home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
No Fragments Archive 10: Diskmags
/
nf_archive_10.iso
/
MAGS
/
ST_USER
/
1990
/
USERAU90.MSA
/
TEXT_CLINIC.DOC
< prev
next >
Wrap
Text File
|
1990-06-24
|
12KB
|
308 lines
PROGRAMMER'S CLINIC
Mathew Lodge chairs the popular
programming problem solving clinic
A quiet month at the clinic, but some interesting and useful letters were sent
in. In the April clinic (in ST World!) I asked what the difference was between
TOS 1.6 and TOS 1.4. Shortly after I'd written that my question was answered in
a message on the USENET Atari ST newsgroup by staff from Atari USA. The
differences are minimal - TOS 1.6 is just TOS 1.4 modified to work with the
STE's extra hardware.
This month also sees the first MINIX question to grace the pages of this
column. MINIX is a remarkable piece of software, being a complete UNIX clone
for the ST written by Dr Andrew Tanenbaum. If you're at all interested in
operating systems design, or if you just want to turn your ST into a UNIX
machine, then MINIX is the way to do it.
I was recently told that a 1040ST with a large hard drive running MINIX is
more powerful than some DEC mainframes were five years ago! Enough operating
systems talk, let's get on with the clinic.
A WORD IN YOUR SHELL-LIKE
--------------------------
Mark T. White of Toronto, Canada, gave the solution to Ian McCall's shel_write
problem detailed in the June (ST World) clinic, but he also suggested another
method not given.
"The solution to his problem is to use a command line processor, and
several PD and commercial ones are available. If he installs one using 'Install
application' for the extension .BAT, then creates the following file with a
.BAT extension, double-clicking on the file will accomplish the desired
results:
\AUTO\INSTALL.PRG
SIGNUM2.PRG
EXIT
EXIT may need to be changed to BYE for some CLIs.
RAGING Cs
----------
The Atari ST is a computer designed to be programmed in C, and this is
reflected in the fact that most of the code that is sent to the clinic is in
this language. This month I've had a few queries about C, the first of which is
from Ian McCall in Sheffield, Yorkshire and concerns the switch from K&R (UNIX)
C to ANSI standard C, and dialog buttons.
"Since all a compiler/linker does is convert routines into object code and
then link them together, is it possible to switch from K&R to ANSI simply by
changing which library you use? And if so, where can I obtain a copy of the
ANSI libraries without buying a new compiler (I'm using Laser C).
"Secondly, how can you change the text inside an object of type G_BUTTON
from Laser C? The manual states that the ob_spec field of the object structure
for this type is a pointer to text to be output, but if I set this to point to
anything, I get the familiar two bombs. Incidentally, the object structure of
Laser C is different to the object structure listed in issue 46. In Laser C,
ob_spec is defined as char *ob_spec. Is it this that's causing me problems?"
* * *
The next C query comes from Waikei Chung, who has been experimenting with
Lattice C 3.04.
"I have had a copy of Lattice C for some time now, but I have not used it
until now, and I found that Metacomco has apparently left the ST market. I'm
beginning the long and difficult path of learning C, and I'm interested by a
section in the Lattice manual stating that we may 'write assembly language
modules for inclusion in C programs.'
"Unfortunately, I am rather confused by the sparse details, so I wonder if
anyone can elaborate. How does you include assembler code into the final
program, and, above all, do I require a separate assembler package?"
* * *
The final C query is about compiling a C program under MINIX, and is from
David Hoggan.
"Does anyone have a working source copy of AWK, BAWK or any incarnation of
this utility? The versions I've downloaded and tried to compile won't, causing
a file system panic in the process. What I have managed to download and compile
(nearly everything works, as the source was for PCs) has brought MINIX in line
with V1.5.0 for the PC. Also, has anyone figured out how to get MINIX to read a
real time, battery backed clock? I know it can read the clocks in the Megas,
but does anyone know how to do it on an ST(E)?"
IMG decompression
In a clinic special last year (in ST World again), Dimitri Koveos described and
explained the IMG file format. However, he did not include any code for reading
and writing IMG files, which is what the redoubtable Lloyd Patton has provided
for the clinic this month. The IMG reading routine is written in C.
"The code is contained in the file IMGREAD. The function decompress() does
the actual work and is fairly self-explanatory. All the complications are in
the interface function read_image_file(). Which is simply concerned with error
checking and initialising the data structures. Images that are less than a
screen width or height size are placed in a memory form block that is at least
a 640 pixels wide and 400 pixels high as this will allow easier manipulation of
the picture area at a later date
------------------------------------------------------------------------------
/* IMG file decompression */
/* Author : Lloyd Patton */
#include <local.h>
#include <gemdefs.h>
#include <obdefs.h>
typedef struct {
WORD version, header_length, number_of_planes
WORD pattern_length, micron_width, micron_height,
WORD line_length, number_of_lines;
WORD flag, palette[16];
} XIMGHDR; /* this typedef should be in a header file */
#define NoFile 2
#define NoLoadMemory 4
static BYTE
MONOonly[] = "[3][Only monochrome IMG|files supported!][Sorry ]",
BadFile[] = "[3][IMG file format error|encountered!][ Sorry ]";
/* decompress an image file - returns 0 if error occurs */
static decompress_image_file(fp, lines, pixels, llength,picture)
register FILE *fp; /* inout file pointer /*
UWORD lines, pixels; /* no. scan lines && pixels */
LONG llength;
BYTE *picture;
{
WORD repcnt, this;
register WORD first, second, dtype, count;
register BYTE *buffer, *pptr, *bptr;
if ((buffer = lcalloc(llength, 1L)) == NULL)
{
form_error(NoLoadMemory);
return (0);
}
wind_update(BEG_MCTRL);
graf_mouse(HOURGLASS, NULL);
for (this = dtype = 0; this < lines && dtype != EOF; this += repcnt)
{
repcnt = 1;
bptr = buffer;
while (((bptr - buffer) << 3) < pixels && (dtype = getc(fp)) != EOF)
{
switch (dtype)
{
case 0x80: /* BIT STRING */
count = getc(fp); /* copy count no. of bytes */
while (count--)
*bptr++ = getc(fp);
break;
case 0: /* either VERT REPL count || PATTERN RUN */
count = getc(fp);
first = getc(fp);
second = getc(fp);
if (count == 0) /* VERTICAL REPLICATION */
{
if (first == 255 && bptr == buffer)
repcnt = second;
else
lines = this; /* error reading file */
continue;
}
else { /* PATTERN RUN */
while (count--)
{
*bptr++ = first;
*bptr++ = second;
}
}
break;
default: /* SOLID RUN */
first = (dtype & 0x80) ? -1: 0;
count = dtype & 0x7F;
while (count--)
*bptr++ = first;
break;
}
}
for (first = 0; first < repcnt; ++first)
{ /* copy scan line to picture buffer */
pptr = picture + (this + first) * llength;
bcopy(buffer, pptr, (WORD)llength);
}
}
graf_mouse(ARROW, NULL);
wind_update(END_MCTRL);
return (lines == this && dtype != EOF);
}
/* read an image file - returns pointer to picture data or
* NULL if error.
* Your program should not be within a BEG_MCTRL loop
* when this function is called.
*/
BYTE *read_image_file(vdi, img, mform, path)
WORD vdi; /* vdi handle */
register MFDB *mform; /* memory form descriptor for pic*/
register XIMGHDR *img; /* IMG file header */
BYTE *path; /* full pathname for file to read */
{
register FILE *fp;
register LONG psize;
register UWORD lines, pwidth, wwidth;
register WORD pxy[8];
MFDB tform;
if ((fp = fopen(path, "br")) != NULL)
{
fread(img, sizeof(XIMGHDR), 1, fp);
fseek(fp, (LONG)(img -> header_length * 2), 0);
if (img -> number_of_planes != 1)
{
form_alert(1, MONOonly);
return (NULL);
}
mform -> fd_nplanes = 1;
mform -> fd_stand = 0;
psize = (pwidth = mform -> fd_w = img -> line_length) / 16;
mform -> fd_wdwidth = wwidth = psize += (img ->line_length % 16) ? 1: 0;
psize *= lines = mform -> fd_h = img -> number_of_lines;
tform.fd_addr = mform -> fd_addr;
if (mform -> fd_addr)
mform -> fd_addr = (LONG)lrealloc(mform -> fd_addr, psize * 2L);
else
mform -> fd_addr = (LONG)lcalloc(mform -> fd_addr, psize * 2L, 1L);
if (mform -> fd_addr == NULL)
{
fclose(fp);
form_error(NoLoadMemory);
return ((BYTE *)(mform -> fd_addr = tform.fd_addr));
}
if (decompress_image_file(fp, lines, pwidth, (ULONG)wwidth*2L,
mform -> fd_addr))
{
fclose(fp);
if (pwidth < 640 || lines < 400)
{ /* ensure a minimum screen size form */
tform = *mform;
tform.fd_w = img -> line_length = max(img -> line_length, 640);
tform.fd_h=img -> number_of_lines=max(img -> number_of_lines, 400);
tform.fd_wdwidth = max(mform -> fd_wdwidth, 40);
if (tform.fd_addr=(LONG)lcalloc(tform.fd_wdwidth*2L,(LONG)tform.fd_h))
{
pxy[0] = pxy[1] = pxy[4] = pxy[5] = 0;
pxy[2] = pxy[6] = mform -> fd_w - 1;
pxy[3] = pxy[7] = mform -> fd_h - 1;
vro_cpyfm(vdi, S_ONLY, pxy, mform, &tform);
free(mform -> fd_addr);
*mform = tform;
}
else {
form_error(NoLoadMemory);
free(mform);
return (NULL);
}
}
return ((BYTE *)mform -> fd_addr);
}
else {
fclose(fp);
form_alert(1, BadFile);
free(mform -> fd_addr);
}
}
else
form_error(NoFile);
return (NULL);
}
."
------------------------------------------------------------------------------
WINDING DOWN
-------------
Clinic is more yours than it is mine, so if you know the answer to a problem
then write in. Keep the letters coming - especially the solutions and comments
on other people's problems and ideas, but don't forget that the clinic depends
on your problems too! Remember to include your full name and give your phone
number if possible.
If you have a listing longer than about 25 lines then please include it on
a disk. Putting the text of your letter on disk is helpful, too, 1st Word
format if possible, but straight ASCII is fine.
If you are sending a complete program then I also like to see it running
before putting it into the column, so please include a double-clickable version
of your program if at all possible. If you want the disk returning include a
stamped addressed envelope.
Mathew Lodge
"Programmer's Clinic"
"Maen Melin"
Holmes Chapel Road
Lach Dennis
Northwich
Cheshire
CW9 7SZ
JANET : SOCS18 @ uk.ac.york.vaxa