home *** CD-ROM | disk | FTP | other *** search
- /* :ts=8 bk=0
- *
- * looki.c: Yet Another ILBM Viewer, except this one uses the new
- * iffparse.library.
- *
- * Written for Lattice 5.05. This program is constructed by saying:
- * 1> lc -cq -v -L looki.c
- *
- * Note: This program isn't as fully featured as I'd like (I started late).
- * In particular, I'd have liked it to have color cycling capability (toggled
- * on and off by hitting TAB), and the ability to turn the title bar on and
- * off with F10.
- *
- * Another thing to note is that, because many pictures were/are written
- * incorrectly, this program determines whether HIRES and/or LACE should be
- * set based on the CAMG chunk, which is incorrect (this information should
- * be derived from the XAspect/YAspect fields). However, the program will
- * note an inconsistency and flame about it.
- *
- * Even with this capability, there are still some images that it won't
- * display "correctly". In particular, I have encountered some 640 x 200
- * images saved with no CAMG chunk and with an X/Y aspect ratio of 10/11.
- * Thus, these images will be displayed in hi-res *interlace*, because that's
- * what the BMHD specifies: nearly-square pixels. I refuse to install a
- * special case hack to compensate for this (because I'm a self-righteously
- * indignant kinda guy. So there :-) ). I contend I am doing The Right
- * Thing. If the files were written wrong, then they should look wrong.
- *
- * This code is provided AS IS. No warranties, either expressed or implied,
- * of any kind are made. Damages or misfortune arising from the use or
- * misuse of this code are the sole responsibility of the individual using
- * or misusing it.
- *
- * Leo L. Schwab (original Manx 3.4b version) 8906.02
- * Took floating point math out, fixed bugs. 8907.08
- * Updated for 1.4 Beta. 8912.06
- * Converted to Lattice 5.05. 9005.23
- */
- #include <exec/types.h>
- #include <utility/hooks.h>
- #include <intuition/intuition.h>
- #include <libraries/iffparse.h>
- #include <clib/exec_protos.h>
- #include <clib/intuition_protos.h>
- #include <clib/graphics_protos.h>
- #include <stdio.h>
- #include "iffparse_protos.h"
- #include "iffparse.p"
- #include "myilbm.h"
-
- #define MAX(a,b) ((a) > (b) ? (a) : (b))
- #define MIN(a,b) ((a) < (b) ? (a) : (b))
- #define ABS(x) ((x) < 0 ? -(x) : (x))
- #define BPR(w) ((w) + 15 >> 4 << 1)
-
- /* Note: These are arbitrary numbers I pulled out of thin air. */
- #define MAXLORES 512
- #define MAXNONLACE 320
- #define IDEALRATIO (10L * 1000 / 11)
-
-
- /*
- * Forward function declarations. (I hate ANSI.)
- */
- LONG handlefile (struct IFFHandle *, char *);
- LONG displayfile (struct IFFHandle *, char *);
- LONG displayimage (struct IFFHandle *, char *);
- LONG loadbody (struct IFFHandle *);
- LONG createscreen (struct IFFHandle *, struct BitMapHeader *);
- LONG loadbitmap (struct IFFHandle *, struct BitMapHeader *, struct BitMap *);
- LONG loadline (struct IFFHandle *, UBYTE *, int, int, int);
- LONG printIFFerr (LONG);
- void deletescreen (void);
- void setcolors (struct IFFHandle *, struct BitMapHeader *);
- void initiffasstdio (struct IFFHandle *);
- void openstuff (void);
- void closestuff (void);
- void die (char *);
-
-
- struct Screen *scr, sensor;
- struct Window *win;
- struct IFFHandle *iff;
-
- struct IntuitionBase *IntuitionBase;
- struct GfxBase *GfxBase;
- struct Library *IFFParseBase;
-
-
- main (ac, av)
- int ac;
- char **av;
- {
- static char usage[] =
- "Usage: %s file [file ... ] ; For viewing files.\n\
- or %s -c ; For viewing the clipboard.\n\
- Click mouse button anywhere when finished looking.\n";
-
- /*
- * Check for arguments. WorkBench startup not currently supported.
- */
- if (ac < 2)
- if (ac == 1) {
- printf (usage, *av, *av);
- exit (20);
- }
-
- openstuff ();
-
- ac--;
- while (ac--)
- handlefile (iff, *++av);
-
- closestuff ();
-
- return (0);
- }
-
- LONG
- handlefile (iff, filename)
- struct IFFHandle *iff;
- register char *filename;
- {
- LONG error;
- char cboard;
-
- cboard = (*filename == '-' && filename[1] == 'c');
-
- if (cboard) {
- /*
- * Set up IFFHandle for Clipboard I/O.
- */
- if (!(iff->iff_Stream =
- (ULONG) OpenClipboard (PRIMARY_CLIP)))
- {
- puts ("Clipboard open failed.");
- return (FALSE);
- }
- InitIFFasClip (iff);
- } else {
- /*
- * Set up IFFHandle for buffered stdio I/O.
- */
- if (!(iff->iff_Stream = (ULONG) fopen (filename, "r"))) {
- printf ("%s: File open failed.\n", filename);
- return (FALSE);
- }
- initiffasstdio (iff);
- }
-
- printf ("%s: ", cboard ? "[Clipboard]" : filename);
- fflush (stdout);
- OpenIFF (iff, IFFF_READ);
-
- error = printIFFerr (displayfile (iff, filename));
-
- CloseIFF (iff);
- deletescreen ();
- fputs ("\r\233K", stdout);
- if (cboard)
- CloseClipboard ((struct ClipboardHandle *) iff->iff_Stream);
- else
- fclose ((FILE *) iff->iff_Stream);
-
- return (error);
- }
-
- LONG
- displayfile (iff, filename)
- register struct IFFHandle *iff;
- char *filename;
- {
- /*
- * Properties that will be collected automatically.
- */
- static LONG ilbmprops[] = {
- ID_ILBM, ID_BMHD,
- ID_ILBM, ID_CMAP,
- ID_ILBM, ID_CAMG
- };
- register struct ContextNode *cn;
- register LONG error;
- char foundbody = 0, hunt = 0;
-
- /*
- * Declare property, collection and stop chunks.
- */
- if (error = PropChunks (iff, ilbmprops, 3L))
- return (error);
- if (error = CollectionChunk (iff, ID_ILBM, ID_CRNG))
- return (error);
- if (error = StopChunk (iff, ID_ILBM, ID_BODY))
- return (error);
-
- /*
- * We want to stop at the end of an ILBM context.
- */
- if (error = StopOnExit (iff, ID_ILBM, ID_FORM))
- return (error);
-
- /*
- * Take first parse step to enter main chunk.
- */
- if (error = ParseIFF (iff, IFFPARSE_STEP))
- return (error);
-
- /*
- * Test the chunk info to see if this is a simple ILBM.
- */
- if (!(cn = CurrentChunk (iff))) {
- /*
- * This really should never happen. If it does, it means
- * our parser is broken.
- */
- puts ("Weird parsing error; no top chunk!");
- return (1);
- }
- if (cn->cn_ID != ID_FORM || cn->cn_Type != ID_ILBM) {
- printf
- ("This is a(n) %.4s.%.4s. Looking for embedded ILBMs...",
- &cn->cn_Type, &cn->cn_ID);
- fflush (stdout);
- hunt = TRUE;
- }
-
- /*
- * Start scanning the file looking for interesting things.
- * The parser will do all the yucky IFF work for us.
- */
- while (!error) {
- /*
- * ParseIFF() will return on BODY chunk or end of
- * context for an ILBM FORM.
- */
- error = ParseIFF (iff, IFFPARSE_SCAN);
-
- /*
- * If we've left the ILBM FORM context, then we now have
- * collected all possible information. We are now ready
- * to display the image.
- */
- if (error == IFFERR_EOC) {
- error = displayimage (iff, filename);
- deletescreen ();
- if (error)
- break;
- continue;
- }
-
- /*
- * Other values for error are real errors.
- */
- if (error)
- break;
-
- /*
- * NULL error means that we've stopped on an ILBM.BODY.
- */
- if (error = loadbody (iff))
- return (error);
- foundbody = TRUE;
- }
-
- if (error == IFFERR_EOF)
- if (!foundbody) {
- if (hunt)
- puts ("None found.");
- else
- puts ("No imagery to display.");
- return (1);
- } else {
- if (hunt)
- putchar ('\n');
- return (0);
- }
- else
- return (error);
- }
-
- LONG
- displayimage (iff, filename)
- struct IFFHandle *iff;
- char *filename;
- {
- if (scr) {
- /* Well, we must have found *something*... */
- register struct View *view;
- register int sw, sh, oldx, oldy;
-
- oldx = oldy = 0;
-
- sw = scr->Width;
- if (scr->ViewPort.Modes & HIRES)
- sw >>= 1;
- sh = scr->Height;
- if (scr->ViewPort.Modes & LACE)
- sh >>= 1;
-
- if (sw > sensor.Width && sh > sensor.Height) {
- /*
- * Overscan; center view.
- * Note: Jim Mackraz says that it is more correct
- * to shift the whole world to center an overscan
- * screen. Personally, I disagree, as I see no
- * reason to shift all screens to center just one.
- * But he's God, so what can I say?
- */
- view = ViewAddress ();
-
- oldx = view->DxOffset;
- oldy = view->DyOffset;
-
- view->DxOffset += sensor.Width - sw >> 1;
- view->DyOffset += sensor.Height - sh >> 1;
- RemakeDisplay ();
- }
- SetWindowTitles (win, (char *) -1L, filename);
- ScreenToFront (scr);
- ActivateWindow (win);
-
- /* Wait for a mouse click. */
- WaitPort (win->UserPort);
-
- if (oldx || oldy) {
- /* Unshift the world. */
- view->DxOffset = oldx;
- view->DyOffset = oldy;
- RemakeDisplay ();
- }
- }
- return (0);
- }
-
- LONG
- loadbody (iff)
- struct IFFHandle *iff;
- {
- register struct StoredProperty *sp;
- register struct BitMapHeader *bmhd;
- LONG error;
-
- if (!(sp = FindProp (iff, ID_ILBM, ID_BMHD))) {
- puts ("No ILBM.BMHD chunk!");
- return (1);
- }
- bmhd = (struct BitMapHeader *) sp->sp_Data;
-
- if (error = createscreen (iff, bmhd))
- return (error);
-
- setcolors (iff, bmhd);
-
- return (loadbitmap (iff, bmhd, &scr->BitMap));
- }
-
- LONG
- createscreen (iff, bmhd)
- struct IFFHandle *iff;
- register struct BitMapHeader *bmhd;
- {
- static struct NewScreen scrdef = {
- 0, 0, 0, 0, 0,
- 0, 1,
- NULL, /* Modes */
- CUSTOMSCREEN, /* | SCREENBEHIND, */
- NULL,
- NULL,
- NULL, NULL,
- };
- static struct NewWindow windef = {
- 0, 0, 0, 0,
- -1, -1,
- MOUSEBUTTONS,
- BORDERLESS | BACKDROP,
- NULL, NULL, NULL,
- NULL, /* Screen filled in later. */
- NULL,
- 0, 0, 0, 0,
- CUSTOMSCREEN
- };
- register struct StoredProperty *sp;
- long ratio;
- ULONG camg;
- UWORD wide, high, modes;
-
- wide = MAX (bmhd->w, bmhd->PageWidth);
- high = MAX (bmhd->h, bmhd->PageHeight);
-
- if (bmhd->YAspect)
- ratio = bmhd->XAspect * 1000 / bmhd->YAspect;
- else
- ratio = 0;
-
- /*
- * Compute what HIRES/LACE *should* be set to. Allow 15% leeway.
- * (See note in opening comment.)
- * Note: This does not yet handle superhires.
- */
- if (ABS (ratio - IDEALRATIO) < 150)
- /* Nearly square pixels. */
- if (wide >= MAXLORES)
- modes = HIRES | LACE;
- else
- modes = 0;
- else if (ABS (ratio - IDEALRATIO * 2) < 150)
- /* Short, wide pixels. */
- modes = LACE;
- else if (ABS (ratio - IDEALRATIO / 2) < 150)
- /* Tall, narrow pixels. */
- modes = HIRES;
- else {
- /* Weird aspect ratio; we'll have to guess... */
- modes = 0;
- if (wide >= MAXLORES)
- modes |= HIRES;
- if (high >= MAXNONLACE)
- modes |= LACE;
- }
-
- /*
- * Grab CAMG's idea of the viewmodes.
- */
- if (sp = FindProp (iff, ID_ILBM, ID_CAMG)) {
- camg = * (ULONG *) sp->sp_Data;
- scrdef.ViewModes =
- (camg & (HIRES | LACE | DUALPF | HAM | EXTRA_HALFBRITE));
- if (modes ^ (camg & (HIRES | LACE)))
- /*- - - - - - - - - - -*/
- printf ("XAspect/YAspect (%d/%d) inconsistent with CAMG.\n",
- bmhd->XAspect, bmhd->YAspect);
- /*- - - - - - - - - - -*/
- } else {
- /*
- * No CAMG present; use computed modes.
- */
- scrdef.ViewModes = modes;
- if (bmhd->nplanes == 6)
- /*
- * With 6 planes and the absence of a CAMG, we have
- * to make an assumption. I assume HAM.
- */
- scrdef.ViewModes |= HAM;
- }
-
- /*
- * Open the screen and window.
- */
- deletescreen ();
- scrdef.Width = wide;
- scrdef.Height = high;
- scrdef.Depth = bmhd->nplanes;
- if (!(scr = OpenScreen (&scrdef))) {
- puts ("Failed to open display screen.");
- return (1);
- }
-
- windef.Screen = scr;
- windef.Width = wide;
- windef.Height = high;
- if (!(win = OpenWindow (&windef))) {
- puts ("Failed to open window.");
- return (1);
- }
- ShowTitle (scr, FALSE);
- return (0);
- }
-
- void
- deletescreen ()
- {
- if (win) CloseWindow (win), win = NULL;
- if (scr) CloseScreen (scr), scr = NULL;
- }
-
- void
- setcolors (iff, bmhd)
- struct IFFHandle *iff;
- register struct BitMapHeader *bmhd;
- {
- register struct StoredProperty *sp;
- register LONG idx;
- register int ncolors;
- register UBYTE *rgb;
- struct ViewPort *vp = &scr->ViewPort;
- LONG r, g, b;
- int nc, ns;
-
- if (sp = FindProp (iff, ID_ILBM, ID_CMAP)) {
- /*
- * Compute the actual number of colors we need to convert.
- */
- nc = sp->sp_Size / 3;
- ns = 1 << bmhd->nplanes;
- ncolors = MIN (ns, nc);
-
- rgb = sp->sp_Data;
- idx = 0;
- while (ncolors--) {
- r = *rgb++ >> 4;
- g = *rgb++ >> 4;
- b = *rgb++ >> 4;
- SetRGB4 (vp, idx++, r, g, b);
- }
- }
- }
-
- LONG
- loadbitmap (iff, bmhd, destmap)
- register struct IFFHandle *iff;
- register struct BitMapHeader *bmhd;
- struct BitMap *destmap;
- {
- register int i, n, p;
- register UWORD *srcline, *destline;
- struct BitMap mapcopy;
- UWORD *linebuf;
- LONG error;
- int bodyw, bodyh, bodydepth, destw, desth,
- rows, mod;
-
- /*
- * Check compression type.
- */
- if (bmhd->Compression != cmpNone &&
- bmhd->Compression != cmpByteRun1) {
- printf ("Unknown compression format type %d.\n",
- bmhd->Compression);
- return (1);
- }
-
- CopyMem ((char *) destmap,
- (char *) &mapcopy,
- (LONG) sizeof (mapcopy));
-
- bodyw = BPR (bmhd->w);
- bodyh = bmhd->h;
- destw = mapcopy.BytesPerRow;
- desth = mapcopy.Rows;
- rows = MIN (bodyh, desth);
- mod = destw - bodyw;
- if (mod < 0)
- mod = -mod;
-
- bodydepth = bmhd->nplanes;
- if (bmhd->Masking == mskHasMask)
- bodydepth++;
-
- /*
- * Allocate a one-line buffer to load imagery in. The line is
- * then copied into the destination bitmap. This seeming
- * duplicity makes clipping loaded images easier.
- */
- if (!(linebuf = AllocMem ((LONG) bodyw * bodydepth, 0L))) {
- puts ("Failed to allocate unpacking buffer");
- return (1);
- }
-
- /*
- * Load the BODY into the allocated line buffer, then copy into
- * the destination bitmap.
- */
- for (i = rows; i--; ) {
- if (error = loadline (iff,
- (UBYTE *) linebuf,
- bodyw,
- bodydepth,
- bmhd->Compression))
- break;
-
- srcline = linebuf;
- for (p = 0; p < bmhd->nplanes; p++) {
- destline = (UWORD *) mapcopy.Planes[p];
- n = (MIN (bodyw, destw)) >> 1;
- while (n--)
- *destline++ = *srcline++;
- if (bodyw > destw)
- srcline += mod >> 1;
- mapcopy.Planes[p] += destw;
- }
- }
-
- FreeMem (linebuf, (LONG) bodyw * bodydepth);
- return (error);
- }
-
- /*
- * This function reads a BODY in piecemeal i.e. it does lots of little short
- * reads. This is relatively slow, but saves on memory.
- */
- LONG
- loadline (iff, buf, bpr, deep, cmptype)
- struct IFFHandle *iff;
- register UBYTE *buf;
- register int bpr; /* Bytes per row */
- int deep, cmptype;
- {
- if (cmptype == cmpNone) { /* No compression */
- register LONG big = bpr * deep;
-
- if (ReadChunkBytes (iff, (APTR) buf, big) != big)
- return (IFFERR_READ);
- } else {
- register int i, remaining;
- register UBYTE *dest = buf;
- BYTE len;
-
- for (i = deep; i--; ) {
- remaining = bpr;
- while (remaining > 0) {
- if (ReadChunkBytes
- (iff, (APTR) &len, 1L) != 1)
- return (IFFERR_READ);
-
- if (len >= 0) {
- /* Literal byte copy */
- if ((remaining -= ++len) < 0)
- break;
- if (ReadChunkBytes
- (iff, (APTR) dest, (LONG) len)
- != len)
- return (IFFERR_READ);
- dest += len;
-
- } else if (len != -128) {
- /* Replication count */
- register int n;
- UBYTE byte;
-
- n = -len + 1;
- if ((remaining -= n) < 0)
- break;
- if (ReadChunkBytes
- (iff, (APTR) &byte, 1L) != 1)
- return (IFFERR_READ);
- while (--n >= 0)
- *dest++ = byte;
- }
- }
- if (remaining) {
- puts ("Image didn't decompress right.");
- return (1);
- }
- }
- buf += bpr;
- }
- return (0);
- }
-
-
- /*
- * File I/O functions which IFFParse will call.
- *
- * IFFParse uses 2.0 hook structures to implement custom streams. In this
- * case, we are creating a stdio stream, since unbuffered DOS I/O would be
- * terribly slow. See utility/hooks.h for more details on Hook mechanics.
- *
- * Upon entry, A0 contains a pointer to the hook, A2 is a pointer to your
- * IFFHandle, and A1 is a pointer to a command packet, which tells you
- * what to do. A6 contains a pointer to IFFParseBase. You may trash A0,
- * A1, D0, and D1. All other registers *MUST* be preserved.
- *
- * You return your error code in D0. A return of 0 indicates success. A
- * non-zero return indicates an error.
- *
- * For this example, we are using Lattice's registerized parameter feature.
- */
- static LONG __saveds __asm
- stdio_stream (
- register __a0 struct Hook *hook,
- register __a2 struct IFFHandle *iff,
- register __a1 struct IFFStreamCmd *actionpkt
- )
- {
- extern LONG __builtin_getreg();
-
- register FILE *stream;
- register LONG nbytes, error;
- register UBYTE *buf;
- LONG A6save;
-
- /*
- * There is a bug somewhere in the Lattice stdio libraries. Calling
- * fread() trashes A6. IFFParse demands that A6 be preserved during
- * the call-back. So I am using Lattice's builtin register
- * manipulators to save and restore A6.
- */
- A6save = __builtin_getreg (14);
-
- stream = (FILE *) iff->iff_Stream;
- nbytes = actionpkt->sc_NBytes;
- buf = (UBYTE *) actionpkt->sc_Buf;
-
- switch (actionpkt->sc_Command) {
- case IFFCMD_READ:
- /*
- * IFFCMD_READ means read sc_NBytes from the stream and place
- * it in the memory pointed to by sc_Buf. Be aware that
- * sc_NBytes may be larger than can be contained in an int.
- * This is important if you plan on recompiling this for
- * 16-bit ints, since fread() takes int arguments.
- *
- * Any error code returned will be remapped by IFFParse into
- * IFFERR_READ.
- */
- error = fread (buf, 1, nbytes, stream) != nbytes;
- break;
-
- case IFFCMD_WRITE:
- /*
- * IFFCMD_WRITE is analogous to IFFCMD_READ.
- *
- * Any error code returned will be remapped by IFFParse into
- * IFFERR_WRITE.
- */
- error = fwrite (buf, 1, nbytes, stream) != nbytes;
- break;
-
- case IFFCMD_SEEK:
- /*
- * IFFCMD_SEEK asks that you performs a seek relative to the
- * current position. sc_NBytes is a signed number,
- * indicating seek direction (positive for forward, negative
- * for backward). sc_Buf has no meaning here.
- *
- * Any error code returned will be remapped by IFFParse into
- * IFFERR_SEEK.
- */
- error = fseek (stream, nbytes, 1) == -1;
- break;
-
- case IFFCMD_INIT:
- /*
- * IFFCMD_INIT means to prepare your stream for reading.
- * This is used for certain streams that can't be read
- * immediately upon opening, and need further preparation.
- * This operation is allowed to fail; the error code placed
- * in D0 will be returned directly to the client.
- *
- * An example of such a stream is the clipboard. The
- * clipboard.device requires you to set the io_ClipID and
- * io_Offset to zero before starting a read. You would
- * perform such a sequence here. (Stdio files need no such
- * preparation, so we simply return zero for success.)
- */
-
- case IFFCMD_CLEANUP:
- /*
- * IFFCMD_CLEANUP means to terminate the transaction with
- * the associated stream. This is used for streams that
- * can't simply be closed. This operation is not allowed to
- * fail; any error returned will be ignored.
- *
- * An example of such a stream is (surprise!) the clipboard.
- * It requires you to explicity end reads by CMD_READing
- * past the end of a clip, and end writes by sending a
- * CMD_UPDATE. You would perform such a sequence here.
- * (Again, stdio needs no such sequence.)
- */
- error = 0;
- break;
- }
- /* Fix A6 */
- __builtin_putreg (14, A6save);
- return (error);
- }
-
- void
- initiffasstdio (iff)
- register struct IFFHandle *iff;
- {
- static struct Hook stdiohook = {
- { NULL },
- (ULONG (*)()) stdio_stream,
- NULL,
- NULL
- };
-
- /*
- * Initialize the IFF structure to point to the buffered I/O
- * routines. Unbuffered I/O is terribly slow.
- */
- InitIFF (iff, IFFF_FSEEK | IFFF_RSEEK, &stdiohook);
- }
-
-
- /*
- * IFF error printing function.
- */
- LONG
- printIFFerr (error)
- LONG error;
- {
- /*
- * English error messages for possible IFFERR_#? returns from various
- * IFF routines. To get the index into this array, take your IFFERR
- * code, negate it, and subtract one.
- * idx = -error - 1;
- */
- static char *errormsgs[] = {
- "End of file (not an error).",
- "End of context (not an error).",
- "No lexical scope.",
- "Insufficient memory.",
- "Stream read error.",
- "Stream write error.",
- "Stream seek error.",
- "File is corrupt.",
- "IFF syntax error.",
- "Not an IFF file.",
- "Required hook vector missing.",
- "Return to client. You should never see this."
- };
-
- if (error < 0)
- printf ("IFF error: %s\n", errormsgs[(-error) - 1]);
- return (error);
- }
-
- /*
- * Housekeeping.
- */
- void
- openstuff ()
- {
- if (!(IntuitionBase = OpenLibrary ("intuition.library", 33L)))
- die ("Intuition won't open. This is not good.");
-
- if (!(GfxBase = OpenLibrary ("graphics.library", 33L)))
- die ("Graphics won't open.");
-
- if (!(IFFParseBase = OpenLibrary ("iffparse.library", 0L)))
- die ("IFF parser library won't open.");
-
- if (!(iff = AllocIFF ()))
- die ("Failed to create IFF control structure.");
-
- GetScreenData ((char *) &sensor,
- (LONG) sizeof (sensor),
- WBENCHSCREEN, NULL);
-
- /* Convert to lo-res pixels. */
- if (sensor.ViewPort.Modes & HIRES)
- sensor.Width >>= 1;
- if (sensor.ViewPort.Modes & LACE)
- sensor.Height >>= 1;
- }
-
- void
- closestuff ()
- {
- deletescreen ();
- if (iff) FreeIFF (iff);
- if (IFFParseBase) CloseLibrary (IFFParseBase);
- if (GfxBase) CloseLibrary (GfxBase);
- if (IntuitionBase) CloseLibrary (IntuitionBase);
- }
-
- void
- die (str)
- char *str;
- {
- puts (str);
- closestuff ();
- exit (20);
- }
-
- /*
- * Disable Lattice's default ^C trap.
- */
- chkabort ()
- {
- return (0);
- }
-
- CXBRK ()
- {
- return (0);
- }
-