home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
-
- Flick FLI-format Animation Viewer v1.4 5 Jan 1994
- --------------------------------------
-
-
- This program plays FLI/FLC-format bitmapped animation files on any ECS,
- AGA or EGS Amiga running OS2.04 or higher. FLI/FLC-format files are
- produced by Autodesk Animator and Autodesk 3D Studio on a PC, as well
- as by other programs.
-
- The files in this archive may be distributed anywhere provided they are
- unmodified and are not sold for profit.
-
- Ownership and copyright of all files remains with the author:
-
- Peter McGavin, 86 Totara Crescent, Lower Hutt, New Zealand.
- e-mail: peterm@maths.grace.cri.nz
-
- *****************************************************************************/
-
- #include "includes.h"
-
- const char version[] = "$VER: Flick 1.4 " __AMIGADATE__ ;
-
- long __oslibversion = 37; /* we require at least OS2.0 */
-
- char __stdiowin[] = "CON:20/50/500/130/Flick";
- char __stdiov37[] = "/AUTO/CLOSE";
-
- #define FLI_256_COLOR 4
- #define FLI_SS2 7
- #define FLI_COLOR 11
- #define FLI_LC 12
- #define FLI_BLACK 13
- #define FLI_BRUN 15
- #define FLI_COPY 16
- #define FLI_PSTAMP 18
-
- struct header {
- ULONG size;
- UWORD magic;
- UWORD frames;
- UWORD width;
- UWORD height;
- UWORD depth;
- UWORD flags;
- ULONG speed;
- UWORD reserved1;
- ULONG created;
- ULONG creator;
- ULONG updated;
- ULONG updater;
- UWORD aspectx;
- UWORD aspecty;
- UBYTE reserved2[38];
- ULONG oframe1;
- ULONG oframe2;
- UBYTE reserved3[40];
- };
-
- struct frameheader {
- ULONG size;
- UWORD magic;
- UWORD chunks;
- UBYTE expand[8];
- };
-
- struct chunkheader {
- ULONG size;
- UWORD type;
- };
-
- struct options {
- BOOL ram;
- enum mode_type mode;
- BOOL once;
- BOOL rom;
- BOOL dbuf;
- BOOL warp;
- BOOL akiko;
- };
-
- struct Library *EGSBase = NULL;
- struct Library *EGSGfxBase = NULL;
- struct Library *EGSBlitBase = NULL;
- struct Library *EGSIntuiBase = NULL;
-
- PLANEPTR raster[2] = {NULL, NULL}; /* 8 contiguous bitplanes */
- struct BitMap screen_bm[2]; /* The displayed bitmap */
- struct RastPort rp[2];
-
- UWORD __chip emptypointer[] = {
- 0x0000, 0x0000, /* reserved, must be NULL */
- 0x0000, 0x0000, /* 1 row of image data */
- 0x0000, 0x0000}; /* reserved, must be NULL */
-
- struct NewScreen ns = {
- 0,0,0,0,0,
- 2,1,
- 0 /* HIRES | LACE */,
- CUSTOMSCREEN | CUSTOMBITMAP,
- NULL,
- NULL,
- NULL,
- &screen_bm[0]
- };
-
- struct NewWindow nw = {
- 0,0, /* Starting corner */
- 0,0, /* Width, height */
- 2,1, /* detail, block pens */
- IDCMP_VANILLAKEY | IDCMP_RAWKEY | IDCMP_MOUSEBUTTONS, /* IDCMP flags */
- WFLG_ACTIVATE | WFLG_BORDERLESS | WFLG_RMBTRAP, /* Window flags */
- NULL, /* Pointer to first gadget */
- NULL, /* Pointer to checkmark */
- NULL, /* title */
- NULL, /* screen pointer */
- NULL, /* bitmap pointer */
- 0,0,0,0, /* window not sized */
- CUSTOMSCREEN /* type of screen */
- };
-
- struct Screen *s = NULL;
- struct Window *w = NULL;
-
- static struct EI_NewScreen ei_ns = {
- NULL, /* screenmode name is put here later... */
- 8, 0, &version[6], /* depth, pad, title */
- NULL, /* CLUPtr */
- { 3, 1, 0, 2, 1, 3, 1 }, /* WinColors */
- 0, /* backPen */
- NULL, /* backPattern */
- NULL, /* Maus */
- NULL /* TextAttr */
- };
-
- static struct EI_NewWindow ei_nw =
- {
- 0, 0, 320, 200, /* LeftEdge, TopEdge, Width, Height */
- 0, 0, 320, 200, /* MinWidth,MinHeight, MaxWidth, MaxHeight */
- NULL, /* Screen - might be set to some screen later */
- EI_WINDOWCLOSE | EI_WINDOWBACK | EI_WINDOWDRAG, /* SysGadgets */
- NULL, /* FirstGadgets */
- &version[6], /* Title */
- EI_SMART_REFRESH | EI_GIMMEZEROZERO | EI_WINDOWACTIVE | EI_RMBTRAP, /* Flags */
- EI_iCLOSEWINDOW | EI_iVANILLAKEY | EI_iRAWKEY | EI_iMOUSEBUTTONS |
- EI_iACTIVEWINDOW | EI_iINACTIVEWINDOW, /*EI_IDCMPFlags */
- NULL, /*Port */
- {0,0,0,0,0,0,0}, /* Colors */
- NULL, /* Menu */
- NULL /* Render */
- };
-
- EI_ScreenPtr ei_s = NULL;
- EI_WindowPtr ei_w = NULL;
- E_EBitMapPtr e_bm = NULL;
- E_CLU *e_oldscreencolours = NULL;
- E_CLU *e_screencolours = NULL;
- EG_RastPortPtr eg_rp;
-
- UWORD screen_width;
- UWORD screen_depth;
- UWORD screen_width32; /* screen_width/32 */
-
- struct ScreenBuffer *sb[2] = {NULL, NULL};
- struct MsgPort *safeport = NULL;
- struct MsgPort *dispport = NULL;
- BOOL safe = TRUE;
- BOOL disp = TRUE;
-
- struct RastPort temprp; /* for WritePixelArray8() */
- struct BitMap tmp_bm; /* for WritePixelArray8(), Height=1, Depth=? */
- PLANEPTR tmpras = NULL; /* for WritePixelArray8() */
-
- UBYTE *chunky = NULL; /* screen_width*h.height chunky pixels */
-
- struct header h;
-
- struct Library *TimerBase = NULL;
- struct MsgPort *timermp = NULL;
- struct timerequest *timerio = NULL;
- ULONG timerclosed = TRUE;
- struct EClockVal *time = NULL;
- struct EClockVal *time0 = NULL;
- struct EClockVal *time1 = NULL;
- double micros_per_eclock; /* Length of EClock tick in microseconds */
-
- struct Task *thistask = NULL;
- BOOL v39 = FALSE;
- BOOL v40 = FALSE;
- ULONG cpu_type; /* 68000, 68010, 68020, 68030, 68040, 68060 */
-
- char programname[20];
- BPTR olddir = NULL;
- struct RDArgs *rdargs = NULL;
-
- struct Library *AslBase = NULL;
- struct FileRequester *fr = NULL;
-
-
- /****************************************************************************/
-
- void swapw (UWORD *w)
- /* Swap the bytes around in a word which may be on an odd byte-boundary */
- {
- UBYTE t;
-
- t = ((UBYTE *)w)[0];
- ((UBYTE *)w)[0] = ((UBYTE *)w)[1];
- ((UBYTE *)w)[1] = t;
- }
-
- void swapl (ULONG *l)
- /* Swap the bytes around in a longword which may be on an odd byte-boundary */
- {
- UBYTE t;
-
- t = ((UBYTE *)l)[0];
- ((UBYTE *)l)[0] = ((UBYTE *)l)[3];
- ((UBYTE *)l)[3] = t;
- t = ((UBYTE *)l)[1];
- ((UBYTE *)l)[1] = ((UBYTE *)l)[2];
- ((UBYTE *)l)[2] = t;
- }
-
- UWORD extractw (UWORD *w)
- /* Get a word which may be on an odd byte-boundary */
- {
- UBYTE t[2];
-
- t[0] = ((UBYTE *)w)[0];
- t[1] = ((UBYTE *)w)[1];
- return *(UWORD *)t;
- }
-
- ULONG extractl (ULONG *l)
- /* Get a longword which may be on an odd byte-boundary */
- {
- UBYTE t[4];
-
- t[0] = ((UBYTE *)l)[0];
- t[1] = ((UBYTE *)l)[1];
- t[2] = ((UBYTE *)l)[2];
- t[3] = ((UBYTE *)l)[3];
- return *(ULONG *)t;
- }
-
- /****************************************************************************/
-
- void close_screen (void)
- {
- int which;
-
- if (chunky != NULL) {
- if (e_bm == NULL || chunky != e_bm->Plane)
- free (chunky);
- chunky = NULL;
- };
- if (e_bm != NULL) {
- e_bm->Lock--;
- E_DisposeBitMap(e_bm);
- e_bm = NULL;
- }
- if (e_oldscreencolours != NULL) {
- E_SetRGB8CM (ei_w->WScreen->EScreen, e_oldscreencolours, 0, 256);
- free (e_oldscreencolours);
- e_oldscreencolours = NULL;
- }
- if (e_screencolours != NULL) {
- free (e_screencolours);
- e_screencolours = NULL;
- }
- if (ei_w != NULL) {
- EI_CloseWindow (ei_w);
- ei_w = NULL;
- }
- if (ei_s != NULL) {
- EI_CloseScreen (ei_s);
- ei_s = NULL;
- }
- if (w != NULL) {
- ClearPointer (w);
- CloseWindow (w);
- w = NULL;
- }
- if (sb[1] != NULL) {
- FreeScreenBuffer (s, sb[1]);
- sb[1] = NULL;
- }
- if (sb[0] != NULL) {
- FreeScreenBuffer (s, sb[0]);
- sb[0] = NULL;
- }
- if (s != NULL) {
- CloseScreen (s);
- s = NULL;
- }
- if (dispport != NULL) {
- DeletePort (dispport);
- dispport = NULL;
- }
- if (safeport != NULL) {
- DeletePort (safeport);
- safeport = NULL;
- }
- for (which = 0; which < 2; which++) {
- if (raster[which] != NULL) {
- FreeRaster (raster[which], screen_width, screen_depth * h.height);
- raster[which] = NULL;
- }
- }
- }
-
- /****************************************************************************/
-
- void _STDcleanup (void)
- /* This get called automatically by SAS/C 6.3 on any sort of exit condition */
- {
- if (!safe) {
- Wait (1 << safeport->mp_SigBit);
- while (GetMsg (safeport) != NULL) /* clear message queue */
- /* nothing */ ;
- safe = TRUE;
- }
- if (!disp) {
- Wait (1 << dispport->mp_SigBit);
- while (GetMsg (dispport) != NULL) /* clear message queue */
- /* nothing */ ;
- disp = TRUE;
- }
- close_screen ();
- if (tmpras != NULL) {
- FreeRaster (tmpras, screen_width, screen_depth);
- tmpras = NULL;
- }
- if (fr != NULL) {
- FreeAslRequest (fr);
- fr = NULL;
- }
- if (AslBase != NULL) {
- CloseLibrary (AslBase);
- AslBase = NULL;
- }
- if (time1 != NULL) {
- FreeMem (time1, sizeof(struct EClockVal));
- time1 = NULL;
- }
- if (time0 != NULL) {
- FreeMem (time0, sizeof(struct EClockVal));
- time0 = NULL;
- }
- if (time != NULL) {
- FreeMem (time, sizeof(struct EClockVal));
- time = NULL;
- }
- if (olddir != NULL) {
- CurrentDir (olddir);
- olddir = NULL;
- }
- if (rdargs != NULL) {
- FreeArgs (rdargs);
- rdargs = NULL;
- }
- if (!timerclosed) {
- CloseDevice ((struct IORequest *)timerio);
- timerclosed = TRUE;
- TimerBase = NULL;
- }
- if (timerio != NULL) {
- DeleteExtIO ((struct IORequest *)timerio);
- timerio = NULL;
- }
- if (timermp != NULL) {
- DeletePort (timermp);
- timermp = NULL;
- }
- if (EGSIntuiBase != NULL) {
- CloseLibrary (EGSIntuiBase);
- EGSIntuiBase = NULL;
- }
- if (EGSBlitBase != NULL) {
- CloseLibrary (EGSBlitBase);
- EGSBlitBase = NULL;
- }
- if (EGSGfxBase != NULL) {
- CloseLibrary (EGSGfxBase);
- EGSGfxBase = NULL;
- }
- if (EGSBase != NULL) {
- CloseLibrary (EGSBase);
- EGSBase = NULL;
- }
- /* standard libraries are auto-closed here by SAS/C */
- }
-
- /****************************************************************************/
-
- static char bodystring[64];
-
- static struct TextAttr topaz80 = {
- "topaz.font", 8, 0, 0
- };
-
- static struct IntuiText bodytext[] = {
- {0, 1, JAM2, 10, 8, &topaz80, programname, &bodytext[1]},
- {0, 1, JAM2, 10, 20, &topaz80, bodystring, NULL},
- };
-
- static struct IntuiText negtext = {0, 1, JAM2, 6, 3, &topaz80, "Ok", NULL};
-
- void die (char *msg, ...)
- /* Exit program with message, return code 10 */
- {
- va_list arglist;
-
- va_start (arglist, msg);
- vsprintf (bodystring, msg, arglist);
- va_end (arglist);
- AutoRequest (w, &bodytext[0], NULL, &negtext, 0, 0, 320, 60);
- exit (10);
- /* SAS/C executes _STDcleanup() automatically on exit */
- }
-
- /****************************************************************************/
-
- void *malloc_check (size_t size)
- {
- void *p;
-
- if ((p = malloc (size)) == NULL)
- die ("%s: Out of memory trying to allocate %ld bytes!", programname,
- size);
- return (p);
- }
-
- /****************************************************************************/
-
- void c2p_rom (UBYTE *chunky,
- UBYTE *copy_of_chunky,
- struct RastPort *rp,
- struct RastPort *temprp,
- UBYTE *dirty_list)
- {
- ULONG h32, *p1, *p2;
- UWORD x, y0, y1, w32, i;
- UBYTE *p;
-
- w32 = screen_width >> 5;
- h32 = w32 * (h.height - 1);
- for (x = 0; x < screen_width; x += 32) {
- p = dirty_list;
- y0 = 0;
- while (y0++ < h.height && !*p)
- p += w32;
- if (y0 < h.height) {
- y0--;
- p = dirty_list + h32;
- y1 = h.height - 1;
- while (!*p) {
- p -= w32;
- y1--;
- }
- p2 = (ULONG *)copy_of_chunky;
- p1 = (ULONG *)(&chunky[y0 * (rp->BitMap->BytesPerRow << 3) + x]);
- for (i = y1 - y0 + 1; i > 0; i--) {
- *p2++ = *p1++;
- *p2++ = *p1++;
- *p2++ = *p1++;
- *p2++ = *p1++;
- *p2++ = *p1++;
- *p2++ = *p1++;
- *p2++ = *p1++;
- *p2++ = *p1;
- p1 += (screen_width >> 2) - 7;
- }
- WritePixelArray8 (rp, x, y0, x + 31, y1, copy_of_chunky, temprp);
- }
- dirty_list++;
- }
- }
-
- /****************************************************************************/
-
- void c2p_egs (E_EBitMapPtr e_bm,
- EG_RastPortPtr eg_rp,
- UBYTE *dirty_list,
- ULONG plsiz)
- {
- ULONG h32;
- UWORD x, y0, y1, w32;
- UBYTE *p;
-
- w32 = e_bm->Width >> 5;
- h32 = w32 * (e_bm->Height - 1);
- for (x = 0; x < e_bm->Width; x += 32) {
- p = dirty_list;
- y0 = 0;
- while (y0++ < e_bm->Height && !*p)
- p += w32;
- if (y0 < e_bm->Height) {
- y0--;
- p = dirty_list + h32;
- y1 = e_bm->Height - 1;
- while (!*p) {
- p -= w32;
- y1--;
- }
- EG_CopyBitMapRastPort (e_bm, eg_rp, x, y0, 32, y1 - y0 + 1, x, y0);
- }
- dirty_list++;
- }
-
- /*
- UWORD d, x, y;
-
- x = 0;
- y = 0;
- for (d = plsiz >> 2; d > 0; d--) {
- if (*dirty_list++ != 0)
- EG_CopyBitMapRastPort (e_bm, eg_rp, x, y, 32, 1, x, y);
- if ((x += 32) >= screen_width) {
- x = 0;
- y++;
- }
- }
- */
-
- /*
- EG_CopyBitMapRastPort (e_bm, eg_rp, 0, 0, e_bm->Width, e_bm->Height, 0, 0);
- */
- }
-
- /****************************************************************************/
-
- void decode_ss2 (UBYTE *chunkbuf, UBYTE *chunky, struct header *h,
- UBYTE *dirty_list)
- {
- UWORD lines, packets, bsize, start;
- ULONG tmp;
- UBYTE *chunky2;
-
- lines = *chunkbuf++;
- lines |= (*chunkbuf++ << 8);
- for ( ; lines > 0; lines--) {
- do {
- packets = *chunkbuf++;
- packets |= (*chunkbuf++ << 8);
- if (packets > 32767)
- if (packets > 49151) {
- tmp = (65536 - packets) * (ULONG)screen_width;
- chunky += tmp;
- dirty_list += (tmp >> 5);
- } else {
- *(chunky + h->width - 1) = (packets & 0xff);
- dirty_list[(h->width - 1) >> 5] = TRUE;
- }
- } while (packets >= 32768);
- chunky2 = chunky;
- for ( ; packets > 0; packets--) {
- chunky2 += *chunkbuf++;
- bsize = *chunkbuf++;
- start = (chunky2 - chunky) >> 5;
- if (bsize > 127) {
- bsize = 256 - bsize;
- /*
- repmem (chunky2, chunkbuf, 2, bsize);
- chunky2 += (bsize << 1);
- */
- for ( ; bsize > 0; bsize--) {
- *chunky2++ = *chunkbuf;
- *chunky2++ = *(chunkbuf + 1);
- }
- chunkbuf += 2;
- } else {
- bsize <<= 1;
- memcpy (chunky2, chunkbuf, bsize);
- /*
- CopyMem (chunkbuf, chunky2, bsize);
- */
- chunkbuf += bsize;
- chunky2 += bsize;
- }
- memset (&dirty_list[start], TRUE, ((chunky2-1 - chunky) >> 5) - start + 1);
- }
- chunky += screen_width;
- dirty_list += screen_width32;
- }
- }
-
-
- void decode_ss2_xlate (UBYTE *chunkbuf, UBYTE *chunky, struct header *h,
- UBYTE *xlate, UBYTE *dirty_list)
- {
- UWORD lines, packets, bsize, start;
- ULONG tmp;
- UBYTE *chunky2, pattern[2];
-
- lines = *chunkbuf++;
- lines |= (*chunkbuf++ << 8);
- for ( ; lines > 0; lines--) {
- do {
- packets = *chunkbuf++;
- packets |= (*chunkbuf++ << 8);
- if (packets > 32767)
- if (packets > 49151) {
- tmp = (65536 - packets) * (ULONG)screen_width;
- chunky += tmp;
- dirty_list += (tmp >> 5);
- } else {
- *(chunky + h->width - 1) = xlate[packets & 0xff];
- dirty_list[(h->width - 1) >> 5] = TRUE;
- }
- } while (packets >= 32768);
- chunky2 = chunky;
- for ( ; packets > 0; packets--) {
- chunky2 += *chunkbuf++;
- bsize = *chunkbuf++;
- start = (chunky2 - chunky) >> 5;
- if (bsize > 127) {
- bsize = 256 - bsize;
- pattern[0] = xlate[*chunkbuf++];
- pattern[1] = xlate[*chunkbuf++];
- /*
- repmem (chunky2, pattern, 2, bsize);
- chunky2 += (bsize << 1);
- */
- for ( ; bsize > 0; bsize--) {
- *chunky2++ = pattern[0];
- *chunky2++ = pattern[1];
- }
- } else {
- bsize <<= 1;
- for ( ; bsize > 0; bsize--)
- *chunky2++ = xlate[*chunkbuf++];
- }
- memset (&dirty_list[start], TRUE, ((chunky2-1 - chunky) >> 5) - start + 1);
- }
- chunky += screen_width;
- dirty_list += screen_width32;
- }
- }
-
-
- #if 0
- void decode_lc (UBYTE *chunkbuf, UBYTE *chunky,
- UBYTE *xlate, enum mode_type mode, UBYTE *dirty_list)
- {
- UBYTE *chunky2;
- UWORD lines, packets, bsize, start;
-
- start = *chunkbuf++;
- start |= (*chunkbuf++ << 8);
- chunky = &chunky[start * screen_width];
- dirty_list = &dirty_list[start * screen_width32];
- lines = *chunkbuf++;
- lines |= (*chunkbuf++ << 8);
- for ( ; lines > 0; lines--) {
- chunky2 = chunky;
- for (packets = *chunkbuf++; packets > 0; packets--) {
- chunky2 += *chunkbuf++;
- bsize = *chunkbuf++;
- start = (chunky2 - chunky) >> 5;
- if (bsize > 127) {
- bsize = 256 - bsize;
- memset (chunky2, xlate[*chunkbuf++], bsize);
- chunky2 += bsize;
- } else {
- if (mode == MODE_COLOUR) {
- memcpy (chunky2, chunkbuf, bsize);
- /*
- CopyMem (chunkbuf, chunky2, bsize);
- */
- chunkbuf += bsize;
- chunky2 += bsize;
- } else
- for ( ; bsize > 0; bsize--)
- *chunky2++ = xlate[*chunkbuf++];
- }
- memset (&dirty_list[start], TRUE, ((chunky2-1 - chunky) >> 5) - start + 1);
- }
- chunky += screen_width;
- dirty_list += screen_width32;
- }
- }
- #endif
-
- void decode_brun (UBYTE *chunkbuf, UBYTE *chunky, struct header *h,
- UBYTE *xlate, enum mode_type mode, UBYTE *dirty_list)
- {
- UBYTE *chunky2;
- UWORD lines, bsize;
-
- for (lines = h->height; lines > 0; lines--) {
- chunky2 = chunky + h->width;
- chunkbuf++; /* skip packet count */
- while (chunky < chunky2) {
- bsize = *chunkbuf++;
- if (bsize <= 127) {
- memset (chunky, xlate[*chunkbuf++], bsize);
- chunky += bsize;
- } else {
- bsize = 256 - bsize;
- if (mode == MODE_COLOUR) {
- memcpy (chunky, chunkbuf, bsize);
- /*
- CopyMem (chunkbuf, chunky, bsize);
- */
- chunkbuf += bsize;
- chunky += bsize;
- } else
- for ( ; bsize > 0; bsize--)
- *chunky++ = xlate[*chunkbuf++];
- }
- }
- chunky += (screen_width - h->width);
- memset (dirty_list, TRUE, ((h->width - 1) >> 5) + 1);
- dirty_list += screen_width32;
- }
- }
-
-
- /****************************************************************************/
-
- int open_screen (char *fname, struct options *opt)
- {
- int which, depth;
-
- if (opt->mode == MODE_EGS) {
-
- if (EGSBase == NULL ||
- EGSGfxBase == NULL ||
- EGSBlitBase == NULL ||
- EGSIntuiBase == NULL)
- return (FALSE);
-
- if ((ei_ns.Mode = getenv ("FLICK")) != NULL) {
- if ((ei_s = EI_OpenScreen (&ei_ns)) == NULL) {
- fprintf (stderr, "Can't open \"%s\" EGS screen!\n", ei_ns.Mode);
- return (FALSE);
- }
- ei_nw.Screen = ei_s;
- ei_nw.LeftEdge = (ei_s->Width - screen_width) >> 1;
- ei_nw.TopEdge = (ei_s->Height - h.height) >> 1;
- }
-
- ei_nw.Width = screen_width;
- ei_nw.Height = h.height;
- ei_nw.Title = fname;
- if ((ei_w = EI_OpenWindow (&ei_nw)) == NULL) {
- close_screen ();
- return (FALSE);
- }
- eg_rp = ei_w->RPort;
-
- if (ei_w->WScreen->EScreen->Map->Depth != 8) {
- fprintf (stderr, "Default EGS screen is not depth 8!\n");
- fprintf (stderr, "Use 'setenv FLICK \"egs-mode-name\"' to select another EGS mode\n");
- close_screen ();
- return (FALSE);
- }
-
- if ((e_bm = E_AllocBitMap (screen_width, h.height, 8, E_PIXELMAP, 0, 0))
- == NULL) {
- close_screen ();
- return (FALSE);
- }
- e_bm->Lock++; /* ensure EGS system doesn't move bitmap memory */
- chunky = e_bm->Plane;
-
- } else {
- switch (opt->mode) {
- case MODE_COLOUR:
- if (!v39)
- return (FALSE);
- screen_depth = 8;
- break;
- case MODE_EHB:
- ns.ViewModes |= EXTRA_HALFBRITE;
- screen_depth = 6;
- break;
- case MODE_COLOUR4:
- case MODE_GREY:
- screen_depth = 4;
- default:
- break;
- }
- ns.Width = screen_width;
- ns.Height = h.height;
- ns.Depth = screen_depth;
- if (screen_width > 384)
- ns.ViewModes |= HIRES;
- else
- ns.ViewModes &= ~HIRES;
- if (h.height > 283)
- ns.ViewModes |= LACE;
- else
- ns.ViewModes &= ~LACE;
-
- /* allocate 2 rasters (for double-buffering) and initialise rp[] */
- if (v39 && opt->rom) {
- ns.Type &= ~CUSTOMBITMAP; /* allow for mode promotion with ROM option */
- ns.CustomBitMap = NULL; /* i.e, no custom bitmap */
- } else {
- ns.Type |= CUSTOMBITMAP;
- ns.CustomBitMap = &screen_bm[0];
- for (which = 0; which < (opt->dbuf ? 2 : 1); which++) {
- InitBitMap (&screen_bm[which], screen_depth, screen_width, h.height); /* Displayed bm */
- /* Allocate 1 contiguous raster for all screen_depth planes */
- if ((raster[which] = (PLANEPTR)AllocRaster (screen_width,
- screen_depth * h.height)) == NULL) {
- close_screen ();
- return (FALSE);
- }
- for (depth = 0; depth < screen_depth; depth++)
- screen_bm[which].Planes[depth] = raster[which] +
- depth * RASSIZE (screen_width, h.height);
- InitRastPort (&rp[which]);
- rp[which].BitMap = &screen_bm[which];
- SetRast (&rp[which], 0);
- }
- }
-
- if ((s = OpenScreen(&ns)) == NULL) {
- close_screen ();
- return (FALSE);
- }
-
- /* allocate structures for double-buffering (if v39) */
- if (v39 && opt->dbuf) {
- if ((safeport = CreatePort (NULL, 0)) == NULL ||
- (dispport = CreatePort (NULL, 0)) == NULL)
- die ("%s: Can't create port!", programname);
- if (opt->rom) {
- if ((sb[0] = AllocScreenBuffer (s, NULL, SB_SCREEN_BITMAP)) == NULL ||
- (sb[1] = AllocScreenBuffer (s, NULL, 0)) == NULL) {
- fprintf (stderr, "Can't allocate structure for double buffering\n");
- close_screen ();
- return (FALSE);
- }
- } else {
- if ((sb[0] = AllocScreenBuffer (s, &screen_bm[0], 0)) == NULL ||
- (sb[1] = AllocScreenBuffer (s, &screen_bm[1], 0)) == NULL) {
- fprintf (stderr, "Can't allocate structure for double buffering\n");
- close_screen ();
- return (FALSE);
- }
- }
- sb[0]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort = safeport;
- sb[0]->sb_DBufInfo->dbi_DispMessage.mn_ReplyPort = dispport;
- sb[1]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort = safeport;
- sb[1]->sb_DBufInfo->dbi_DispMessage.mn_ReplyPort = dispport;
- }
-
- /* initialise rp[] for ROM option */
- if (v39 && opt->rom) {
- InitRastPort (&rp[0]);
- rp[0].BitMap = s->RastPort.BitMap;
- SetRast (&rp[0], 0);
- if (opt->dbuf) {
- InitRastPort (&rp[1]);
- rp[1].BitMap = sb[1]->sb_BitMap;
- SetRast (&rp[1], 0);
- }
- }
-
- /* open a backdrop window (for intuition events) */
- nw.Width = screen_width;
- nw.Height = h.height;
- nw.Screen = s;
- nw.MinWidth = screen_width;
- nw.MinHeight = h.height;
- nw.MaxWidth = screen_width;
- nw.MaxHeight = h.height;
- if ((w = OpenWindow(&nw)) == NULL) {
- close_screen ();
- return (FALSE);
- }
-
- /* allocate chunky pixels */
- if ((chunky = (UBYTE *)malloc (screen_width * (ULONG)h.height)) == NULL) {
- close_screen ();
- return (FALSE);
- }
-
- }
- memset (chunky, 0, screen_width * (ULONG)h.height);
- return (TRUE);
- }
-
- /****************************************************************************/
-
- void parse_tooltypes (char *fname, struct options *opt)
- {
- struct DiskObject *obj;
- char **toolarray;
-
- if ((obj = GetDiskObject (fname)) != NULL) {
- toolarray = obj->do_ToolTypes;
- if (FindToolType (toolarray, "DISK") != NULL)
- opt->ram = FALSE;
- if (FindToolType (toolarray, "RAM") != NULL)
- opt->ram = FALSE;
- if (FindToolType (toolarray, "ONCE") != NULL)
- opt->once = TRUE;
- if (FindToolType (toolarray, "COLOUR") != NULL ||
- FindToolType (toolarray, "COLOR") != NULL)
- opt->mode = MODE_COLOUR;
- if (FindToolType (toolarray, "EHB") != NULL)
- opt->mode = MODE_EHB;
- if (FindToolType (toolarray, "COLOUR4") != NULL ||
- FindToolType (toolarray, "COLOR4") != NULL)
- opt->mode = MODE_COLOUR4;
- if (FindToolType (toolarray, "GREY") != NULL ||
- FindToolType (toolarray, "GRAY") != NULL)
- opt->mode = MODE_GREY;
- if (FindToolType (toolarray, "EGS") != NULL)
- opt->mode = MODE_EGS;
- if (FindToolType (toolarray, "ROM") != NULL)
- opt->rom = TRUE;
- if (FindToolType (toolarray, "DBUF") != NULL)
- opt->dbuf = TRUE;
- if (FindToolType (toolarray, "WARP") != NULL)
- opt->warp = TRUE;
- if (FindToolType (toolarray, "NOAKIKO") != NULL)
- opt->akiko = FALSE;
- FreeDiskObject (obj);
- }
- }
-
- /****************************************************************************/
-
- void animate_file (char *fname, struct options opt)
- {
- FILE *f;
- ULONG size, class, ei_class, totalframes, restartpos, l, *lp, *lp0, *lp1;
- UWORD i, frame, chunk, code, ei_code;
- UWORD packets, n, m, c, lines, depth, which;
- UWORD *viewcolourtable;
- UBYTE (*colourtable)[256][3];
- struct IntuiMessage *msg;
- struct EI_EIntuiMsg *ei_msg;
- UBYTE *filebuf, *buf, *framebuf, *chunkbuf, *p, *p2;
- UBYTE *dirty_list[2], *combined_dirty_list, *copy_of_chunky;
- UBYTE *restartptr, *xlate;
- BOOL going, firstloop;
- struct frameheader *fh;
- struct chunkheader *ch;
- ULONG fh_size;
- UWORD fh_magic, fh_chunks, ch_type;
- BOOL palette_changed;
- int oldpri;
- struct EClockVal eclocks, next_time;
- void __asm (*c2p)(register __a0 UBYTE *chunky_data,
- register __a1 PLANEPTR raster,
- register __a2 UBYTE *dirty_list,
- register __d1 ULONG plsiz,
- register __a5 UBYTE *tmp_buffer);
-
-
- /* initialise resources */
- f = NULL;
- viewcolourtable = NULL;
- filebuf = NULL;
- framebuf = NULL;
- dirty_list[0] = NULL;
- dirty_list[1] = NULL;
- combined_dirty_list = NULL;
- copy_of_chunky = NULL;
- xlate = NULL;
- colourtable = NULL;
- fh = NULL;
-
- parse_tooltypes (fname, &opt);
-
- if (opt.mode == MODE_EGS) {
- opt.dbuf = FALSE;
- opt.rom = FALSE;
- }
-
- /* open file and read header struct */
- if ((f = fopen (fname, "rb")) == NULL)
- die ("%s: Can't open %s", programname, fname);
- if ((fread (&h, sizeof(struct header), 1, f)) != 1)
- die ("%s: Error reading file", programname);
- swapl (&h.size);
- swapw (&h.magic);
- swapw (&h.frames);
- swapw (&h.width);
- swapw (&h.height);
- swapw (&h.depth);
- swapw (&h.flags);
- swapl (&h.speed);
- swapl (&h.creator);
- swapl (&h.updater);
- swapw (&h.aspectx);
- swapw (&h.aspecty);
- swapl (&h.oframe1);
- swapl (&h.oframe2);
-
- printf ("File = %s\n", fname);
- printf ("%lu bytes, %u frames, %ux%ux%u, speed = %u\n", h.size, h.frames,
- h.width, h.height, h.depth, h.speed);
-
- eclocks.ev_hi = 0;
- if (h.magic == 0xaf11) {
- eclocks.ev_lo = (ULONG)((1000000.0 / 70.0) * h.speed / micros_per_eclock + 0.5);
- if (h.speed != 0)
- printf ("Defined frames per second = %4.1lf", 70.0 / h.speed);
- putchar ('\n');
- } else if (h.magic == 0xaf12) {
- eclocks.ev_lo = (ULONG)((1000000.0 / 1000.0) * h.speed / micros_per_eclock + 0.5);
- if (h.speed != 0)
- printf ("Defined frames per second = %4.1lf", 1000.0 / h.speed);
- putchar ('\n');
- } else
- die ("%s: Unrecognised magic number %04x", programname, h.magic);
- if (opt.warp)
- eclocks.ev_lo = 0;
-
- /* allow for AGA modes */
- screen_width = (h.width + 63) & ~63;
- screen_width32 = (screen_width >> 5);
-
- /* allocate dirty lists */
- for (which = 0; which < (opt.dbuf ? 2 : 1); which++) {
- dirty_list[which] = malloc_check (screen_width32 * (ULONG)h.height + 8);
- memset (dirty_list[which], FALSE, screen_width32 * (ULONG)h.height + 8);
- }
-
- if (opt.dbuf) {
- combined_dirty_list = malloc_check (screen_width32 * (ULONG)h.height + 8);
- memset (combined_dirty_list, FALSE, screen_width32 * (ULONG)h.height + 8);
- } else
- combined_dirty_list = dirty_list[0];
-
- /* if using ram then read in the entire file else allocate header buffers */
- if (opt.ram)
- if ((filebuf = malloc (h.size - sizeof(struct header))) == NULL) {
- printf ("%s: Not enough free contiguous memory to load into RAM\n", programname);
- printf (" Playing from disk instead\n");
- opt.ram = FALSE;
- } else {
- if ((fread (filebuf, h.size - sizeof(struct header), 1, f)) != 1)
- die ("%s: Error reading file", programname);
- buf = filebuf;
- }
- if (!opt.ram) {
- fh = malloc_check (sizeof(struct frameheader));
- }
-
- /* open screen with custom bitmap */
- while (!open_screen (fname, &opt)) {
- switch (opt.mode) {
- case MODE_COLOUR:
- printf ("%s: Can't open 8 bitplane COLOUR screen\n", programname);
- if (ns.ViewModes & HIRES) {
- printf (" Trying 4 bitplane COLOUR4 instead\n");
- opt.mode = MODE_COLOUR4;
- } else {
- printf (" Trying 6 bitplane EHB instead\n");
- opt.mode = MODE_EHB;
- }
- break;
- case MODE_EHB:
- printf ("%s: Can't open 6 bitplane EHB screen\n", programname);
- printf (" Trying 4 bitplane COLOUR4 instead\n");
- opt.mode = MODE_COLOUR4;
- break;
- case MODE_EGS:
- printf ("%s: Can't open 8 bitplane EGS screen\n", programname);
- printf (" Trying 8 bitplane COLOUR instead\n");
- opt.mode = MODE_COLOUR;
- break;
- case MODE_COLOUR4:
- case MODE_GREY:
- default:
- die ("%s: Can't open screen!", programname);
- }
- Delay (100);
- }
-
- /* initialise tmp stuff for WritePixelArray8() */
- if (opt.rom) {
- if ((tmpras = (PLANEPTR)AllocRaster (screen_width, screen_depth)) == NULL)
- die ("%s: Out of memory", programname);
- InitBitMap (&tmp_bm, screen_depth, screen_width, 1);
- for (depth = 0; depth < screen_depth; depth++)
- tmp_bm.Planes[depth] = tmpras + depth * RASSIZE (screen_width, 1);
- temprp = rp[0];
- temprp.Layer = NULL;
- temprp.BitMap = &tmp_bm;
- }
-
- /* turn the mouse pointer off for this window */
- if (opt.mode != MODE_EGS)
- SetPointer (w, emptypointer, 1, 16, 0, 0);
-
- /* allocate and initialise colour tables and pixel xlate table */
- colourtable = (UBYTE (*)[256][3])malloc_check (sizeof(*colourtable));
- memset (colourtable, 0, sizeof(*colourtable));
- xlate = malloc_check (256);
-
- switch (opt.mode) {
- case MODE_COLOUR4:
- case MODE_EHB:
- viewcolourtable = (UWORD *)malloc_check ((1 << screen_depth) * sizeof(UWORD));
- memset (viewcolourtable, 0, (1 << screen_depth) * sizeof(UWORD));
- break;
- case MODE_GREY:
- viewcolourtable = (UWORD *)malloc_check ((1 << screen_depth) * sizeof(UWORD));
- memset (viewcolourtable, 0, (1 << screen_depth) * sizeof(UWORD));
- for (c = 0; c < 16; c++)
- viewcolourtable[c] = c * 0x0111;
- LoadRGB4 (&s->ViewPort, viewcolourtable, 1 << screen_depth);
- break;
- case MODE_COLOUR:
- viewcolourtable = (UWORD *)malloc_check (2 * sizeof(UWORD) +
- (1 << screen_depth) * 3 * sizeof(ULONG) + sizeof(UWORD));
- memset (viewcolourtable, 0, 2 * sizeof(UWORD) +
- (1 << screen_depth) * 3 * sizeof(ULONG) + sizeof(UWORD));
- viewcolourtable[0] = 1 << screen_depth;
- for (i = 0; i < 256; i++)
- xlate[i] = i;
- break;
- case MODE_EGS:
- e_screencolours = (E_CLU *)malloc_check (256 * sizeof(E_CLU));
- e_oldscreencolours = (E_CLU *)malloc_check (256 * sizeof(E_CLU));
- E_GetRGB8CM (ei_w->WScreen->EScreen, e_oldscreencolours, 0, 256);
- E_GetRGB8CM (ei_w->WScreen->EScreen, e_screencolours, 0, 256);
- for (i = 0; i < 256; i++)
- xlate[i] = i;
- break;
- }
-
- /* select a chunky to planar (c2p) routine */
- if (opt.mode != MODE_EGS) {
- if (opt.rom) {
- copy_of_chunky = malloc_check (screen_width * (ULONG)h.height);
- } else if (v40 && opt.akiko && (GfxBase->ChunkyToPlanarPtr != NULL)) {
- copy_of_chunky = (UBYTE *)GfxBase->ChunkyToPlanarPtr;
- switch (screen_depth) {
- case 4:
- c2p = c2p_4_akiko;
- break;
- case 6:
- c2p = c2p_6_akiko;
- break;
- case 8:
- c2p = c2p_8_akiko;
- break;
- default:
- die ("%s: Unsupported resolution", programname);
- break;
- }
- } else {
- switch (cpu_type) {
- case 68000:
- case 68010:
- switch (screen_depth) {
- case 4:
- c2p = c2p_4_000;
- break;
- case 6:
- c2p = c2p_6_000;
- break;
- case 8:
- c2p = c2p_8_000;
- break;
- default:
- die ("%s: Unsupported resolution", programname);
- break;
- }
- break;
- case 68020:
- case 68030:
- copy_of_chunky = malloc_check (screen_width * (ULONG)h.height);
- switch (screen_depth) {
- case 4:
- c2p = c2p_4_020;
- break;
- case 6:
- c2p = c2p_6_020;
- break;
- case 8:
- c2p = c2p_8_020;
- break;
- default:
- die ("%s: Unsupported resolution", programname);
- break;
- }
- break;
- case 68040:
- case 68060:
- switch (screen_depth) {
- case 4:
- c2p = c2p_4_040;
- break;
- case 6:
- c2p = c2p_6_040;
- break;
- case 8:
- c2p = c2p_8_040;
- break;
- default:
- die ("%s: Unsupported resolution", programname);
- break;
- }
- break;
- default:
- die ("%s: Unsupported CPU type %d", programname, cpu_type);
- }
- }
- }
-
- /* initialise loop variables */
- which = 0; /* bitmap index --- flips between 0 and 1 with each frame */
- palette_changed = FALSE;
- frame = 0;
- totalframes = 0;
- firstloop = TRUE;
- going = TRUE;
-
- /* read the start time */
- ReadEClock (time0);
- next_time = *time0;
- add64 (&next_time, &eclocks);
-
- /* loop for each frame */
- while (going) {
-
- /* if this is the 2nd frame, save the current file-position for loop */
- if (totalframes == 1)
- if (opt.ram)
- restartptr = buf;
- else
- if ((restartpos = ftell (f)) == -1)
- die ("%s: Error ftelling file", programname);
-
- /* read the frame header */
- if (opt.ram) {
- fh = (struct frameheader *)buf;
- buf += sizeof(struct frameheader);
- } else
- if ((fread (fh, sizeof(struct frameheader), 1, f)) != 1)
- die ("%s: Error reading file", programname);
- if (firstloop || !opt.ram) {
- swapl (&fh->size);
- swapw (&fh->magic);
- swapw (&fh->chunks);
- }
- fh_size = extractl (&fh->size);
- fh_magic = extractw (&fh->magic);
- fh_chunks = extractw (&fh->chunks);
-
- /* allocate memory for and read the rest of the frame */
- if (opt.ram) {
- framebuf = buf;
- } else {
- size = fh_size - sizeof(struct frameheader);
- if (size == 0)
- framebuf = NULL;
- else {
- framebuf = malloc_check (size);
- if ((fread (framebuf, size, 1, f)) != 1)
- die ("%s: Error reading file", programname);
- buf = framebuf;
- }
- }
-
- /* check for and ignore 0xf100 frames */
- if (fh_magic == 0xf100) {
-
- totalframes--; /* don't count this frame */
- frame--;
-
- } else {
-
- /* consistency check */
- if (fh_magic != 0xf1fa)
- die ("%s: Unrecognised magic number in frame %04x %lu",
- programname, fh_magic, fh_size);
-
- /* render into the non-displayed raster (if double-buffering) */
- if (opt.dbuf)
- which = 1 - which;
-
- /* clear the dirty list for this frame */
- memset (dirty_list[which], FALSE, screen_width32 * (ULONG)h.height);
-
- /* loop for each chunk */
- for (chunk = 0; chunk < fh_chunks; chunk++) {
-
- /* examine the chunk header */
- ch = (struct chunkheader *)buf;
- if (firstloop || !opt.ram) {
- swapl (&ch->size);
- swapw (&ch->type);
- }
- chunkbuf = buf + sizeof(struct chunkheader);
- buf += (extractl (&ch->size) + 1) & ~1;
- ch_type = extractw (&ch->type);
-
- /* uncompress chunk into chunky pixels */
- switch (ch_type) {
-
- case FLI_SS2:
- if (opt.mode == MODE_COLOUR || opt.mode == MODE_EGS)
- decode_ss2 (chunkbuf, chunky, &h, dirty_list[which]);
- else
- decode_ss2_xlate (chunkbuf, chunky, &h, xlate, dirty_list[which]);
- break;
-
- case FLI_256_COLOR:
- case FLI_COLOR:
- p = chunkbuf;
- packets = *p++;
- packets |= (*p++ << 8);
- c = 0;
- for ( ; packets > 0; packets--) {
- c += *p++;
- n = *p++;
- if (n == 0)
- n = 256;
- for (m = 0; m < n; m++) {
- if (ch_type == FLI_256_COLOR) {
- (*colourtable)[c][0] = *p++; /* R */
- (*colourtable)[c][1] = *p++; /* G */
- (*colourtable)[c][2] = *p++; /* B */
- } else {
- (*colourtable)[c][0] = *p++ << 2; /* R */
- (*colourtable)[c][1] = *p++ << 2; /* G */
- (*colourtable)[c][2] = *p++ << 2; /* B */
- }
- c++;
- }
- }
- switch (opt.mode) {
- case MODE_COLOUR4:
- case MODE_EHB:
- median_cut (*colourtable, viewcolourtable, xlate, opt.mode);
- break;
- case MODE_GREY:
- for (c = 0; c < 256; c++)
- xlate[c] = ((((UWORD)(*colourtable)[c][0]) +
- ((UWORD)(*colourtable)[c][1]) +
- ((UWORD)(*colourtable)[c][2])) / 3) >> 4;
- break;
- case MODE_COLOUR:
- break;
- case MODE_EGS:
- for (c = 0; c < 256; c++) {
- e_screencolours[c].Red = (*colourtable)[c][0];
- e_screencolours[c].Green = (*colourtable)[c][1];
- e_screencolours[c].Blue = (*colourtable)[c][2];
- }
- break;
- }
- palette_changed = TRUE;
- break;
-
- case FLI_LC:
- if (opt.mode == MODE_COLOUR || opt.mode == MODE_EGS)
- decode_lc (chunkbuf, chunky, dirty_list[which]);
- else
- decode_lc_xlate (chunkbuf, chunky, xlate, dirty_list[which]);
- break;
-
- case FLI_BLACK:
- memset (chunky, xlate[0], screen_width * (ULONG)h.height);
- memset (dirty_list[which], TRUE, screen_width32 * (ULONG)h.height);
- break;
-
- case FLI_BRUN:
- decode_brun (chunkbuf, chunky, &h, xlate, opt.mode,
- dirty_list[which]);
- break;
-
- case FLI_COPY:
- if (opt.mode == MODE_COLOUR || opt.mode == MODE_EGS)
- if (h.width == screen_width) {
- /*
- memcpy (chunky, chunkbuf, h.width * (ULONG)h.height);
- */
- CopyMemQuick (chunkbuf, chunky, screen_width * (ULONG)h.height);
- } else {
- p = chunkbuf;
- p2 = chunky;
- for (lines = h.height; lines > 0; lines--) {
- CopyMemQuick (p, p2, h.width);
- p += h.width;
- p2 += screen_width;
- }
- }
- else {
- if (h.width == screen_width) {
- p2 = chunky;
- for (l = h.width * (ULONG)h.height; l > 0; l--)
- *p2++ = xlate[*p++];
- } else {
- p = chunkbuf;
- p2 = chunky;
- for (lines = h.height; lines > 0; lines--) {
- for (i = h.width; i > 0; i--)
- *p2++ = xlate[*p++];
- p2 += (screen_width - h.width);
- }
- }
- }
- memset (dirty_list[which], TRUE, screen_width32 * (ULONG)h.height);
- break;
-
- case FLI_PSTAMP:
- break;
-
- default:
- die ("%s: Unrecognised chunk type %04x", programname, ch_type);
- break;
- } /* end of switch for each chunk type */
-
- } /* end of loop for each chunk within frame */
-
- /* if double-buffering, combine the dirty lists */
- if (opt.dbuf) {
- lp0 = (ULONG *)dirty_list[which];
- lp1 = (ULONG *)dirty_list[1 - which];
- lp = (ULONG *)combined_dirty_list;
- for (l = ((screen_width32 * (ULONG)h.height) >> 2) + 1; l > 0; l--)
- *lp++ = *lp0++ | *lp1++;
- }
-
- /* update amiga's colourtable if palette has changed in this frame */
- if (palette_changed) {
- switch (opt.mode) {
- case MODE_COLOUR4:
- LoadRGB4 (&s->ViewPort, viewcolourtable, 16);
- break;
- case MODE_EHB:
- LoadRGB4 (&s->ViewPort, viewcolourtable, 32);
- break;
- case MODE_GREY:
- break;
- case MODE_COLOUR:
- for (c = 0; c < (1 << screen_depth); c++) {
- ((ULONG *)viewcolourtable)[3*c+1] = (*colourtable)[c][0] << 24;
- ((ULONG *)viewcolourtable)[3*c+2] = (*colourtable)[c][1] << 24;
- ((ULONG *)viewcolourtable)[3*c+3] = (*colourtable)[c][2] << 24;
- }
- LoadRGB32 (&s->ViewPort, (ULONG *)viewcolourtable);
- break;
- case MODE_EGS:
- E_SetRGB8CM (ei_w->WScreen->EScreen, e_screencolours, 0, 256);
- break;
- }
- palette_changed = FALSE;
- }
-
- /* Wait until it is safe to modify bitmap without flicker (if v39) */
- if (v39 && opt.dbuf) {
- if (!safe) {
- Wait (1 << safeport->mp_SigBit);
- while (GetMsg (safeport) != NULL) /* clear message queue */
- /* nothing */ ;
- safe = TRUE;
- }
- }
-
- /* convert from chunky pixels to (hidden) planar raster[which] */
- if (opt.mode == MODE_EGS)
- c2p_egs (e_bm, eg_rp, combined_dirty_list,
- (screen_width * (ULONG)h.height) >> 3);
- /*
- EG_CopyBitMapRastPort (e_bm, eg_rp, 0, 0, screen_width, h.height, 0, 0);
- */
- else if (opt.rom) {
- /* WritePixelArray8() destroys original chunky, so make a copy */
- /*
- CopyMemQuick (chunky, copy_of_chunky, screen_width * (ULONG)h.height);
- WritePixelArray8 (&rp[which], 0, 0, screen_width-1, h.height-1,
- copy_of_chunky, &temprp);
- */
- c2p_rom (chunky, copy_of_chunky, &rp[which], &temprp,
- combined_dirty_list);
- } else
- c2p (chunky, raster[which], combined_dirty_list,
- (screen_width * (ULONG)h.height) >> 3, copy_of_chunky);
-
- /* wait for time between frames */
- ReadEClock (time);
- if (cmp64 (time, &next_time) > 0) {
- timerio->tr_node.io_Command = TR_ADDREQUEST;
- *(struct EClockVal *)&timerio->tr_time = next_time;
- sub64 ((struct EClockVal *)&timerio->tr_time, time); /* timerio->tr_time -= time */
- /* oldpri = SetTaskPri (thistask, 20); */ /* don't flicker when mouse moves */
- DoIO ((struct IORequest *)timerio); /* delay */
- /* SetTaskPri (thistask, oldpri); */ /* restore task priority */
- }
- while (cmp64 (time, &next_time) > 0) {
- ReadEClock (time);
- }
- next_time = *time;
- add64 (&next_time, &eclocks);
-
- /* make the new raster visible (if double-buffering) */
- if (opt.dbuf) {
- if (v39) {
- oldpri = SetTaskPri (thistask, 20); /* don't flicker when mouse moves */
- /* Wait until it is safe to swap bitmaps without flicker */
- if (!disp) {
- Wait (1 << dispport->mp_SigBit);
- while (GetMsg (dispport) != NULL) /* clear message queue */
- /* nothing */ ;
- disp = TRUE;
- }
- if (ChangeScreenBuffer (s, sb[which])) {
- disp = FALSE;
- safe = FALSE;
- }
- SetTaskPri (thistask, oldpri); /* restore task priority */
- } else {
- s->ViewPort.RasInfo->BitMap = &screen_bm[which];
- MakeScreen (s);
- RethinkDisplay ();
- }
- }
-
- /* check for CTRL/C or BREAK */
- if (SetSignal (0, 0) & SIGBREAKF_CTRL_C) {
- SetSignal (0, SIGBREAKF_CTRL_C);
- printf ("***Break\n");
- exit (0);
- }
-
- /* check for intuition messages */
- if (opt.mode == MODE_EGS) {
- while ((ei_msg = (struct EI_EIntuiMsg *)GetMsg (ei_w->UserPort)) != NULL) {
- ei_class = ei_msg->Class;
- ei_code = ei_msg->Code;
- ReplyMsg ((struct Message *)ei_msg);
- switch (ei_class) {
- case EI_iRAWKEY:
- switch (ei_code) {
- case 0x45: /* ESC */
- going = FALSE;
- break;
- case 0x50: /* F1 */
- eclocks.ev_lo = 0;
- break;
- case 0x51: /* F2 */
- eclocks.ev_lo = (ULONG)((1000000.0 / 60.0) / micros_per_eclock + 0.5);
- break;
- case 0x52: /* F3 */
- eclocks.ev_lo = (ULONG)((1000000.0 / 30.0) / micros_per_eclock + 0.5);
- break;
- case 0x53: /* F4 */
- eclocks.ev_lo = (ULONG)((1000000.0 / 24.0) / micros_per_eclock + 0.5);
- break;
- case 0x54: /* F5 */
- eclocks.ev_lo = (ULONG)((1000000.0 / 15.0) / micros_per_eclock + 0.5);
- break;
- case 0x55: /* F6 */
- eclocks.ev_lo = (ULONG)((1000000.0 / 12.0) / micros_per_eclock + 0.5);
- break;
- case 0x56: /* F7 */
- eclocks.ev_lo = (ULONG)((1000000.0 / 10.0) / micros_per_eclock + 0.5);
- break;
- case 0x57: /* F8 */
- eclocks.ev_lo = (ULONG)((1000000.0 / 5.0) / micros_per_eclock + 0.5);
- break;
- case 0x58: /* F9 */
- eclocks.ev_lo = (ULONG)(1000000.0 / micros_per_eclock + 0.5);
- break;
- case 0x59: /* F10 */
- if (h.magic == 0xaf11)
- eclocks.ev_lo = (ULONG)((1000000.0 / 70.0) * h.speed /
- micros_per_eclock + 0.5);
- else if (h.magic == 0xaf12)
- eclocks.ev_lo = (ULONG)((1000000.0 / 1000.0) * h.speed /
- micros_per_eclock + 0.5);
- break;
- default:
- break;
- }
- break;
- case EI_iVANILLAKEY:
- switch (ei_code) {
- case 0x03: /* CTRL/C */
- printf ("***Break\n");
- exit (0);
- case 0x1b: /* ESC */
- case 0x51: /* q */
- case 0x71: /* Q */
- going = FALSE;
- break;
- case '+':
- if (eclocks.ev_lo == 1)
- eclocks.ev_lo = 0;
- else
- eclocks.ev_lo >>= 1;
- break;
- case '-':
- if (eclocks.ev_lo == 0)
- eclocks.ev_lo = 1;
- else if (eclocks.ev_lo < 500000)
- eclocks.ev_lo <<= 1;
- break;
- default:
- break;
- }
- break;
- case EI_iCLOSEWINDOW:
- going = FALSE;
- break;
- case EI_iMOUSEBUTTONS:
- if (ei_code == MENUDOWN)
- going = FALSE;
- break;
- case EI_iACTIVEWINDOW:
- E_SetRGB8CM (ei_w->WScreen->EScreen, e_screencolours, 0, 256);
- break;
- case EI_iINACTIVEWINDOW:
- E_SetRGB8CM (ei_w->WScreen->EScreen, e_oldscreencolours, 0, 256);
- break;
- default:
- break;
- }
- }
- } else {
- while ((msg = (struct IntuiMessage *)GetMsg (w->UserPort)) != NULL) {
- class = msg->Class;
- code = msg->Code;
- ReplyMsg ((struct Message *)msg);
- switch (class) {
- case IDCMP_RAWKEY:
- switch (code) {
- case 0x45: /* ESC */
- going = FALSE;
- break;
- case 0x50: /* F1 */
- eclocks.ev_lo = 0;
- break;
- case 0x51: /* F2 */
- eclocks.ev_lo = (ULONG)((1000000.0 / 60.0) / micros_per_eclock + 0.5);
- break;
- case 0x52: /* F3 */
- eclocks.ev_lo = (ULONG)((1000000.0 / 30.0) / micros_per_eclock + 0.5);
- break;
- case 0x53: /* F4 */
- eclocks.ev_lo = (ULONG)((1000000.0 / 24.0) / micros_per_eclock + 0.5);
- break;
- case 0x54: /* F5 */
- eclocks.ev_lo = (ULONG)((1000000.0 / 15.0) / micros_per_eclock + 0.5);
- break;
- case 0x55: /* F6 */
- eclocks.ev_lo = (ULONG)((1000000.0 / 12.0) / micros_per_eclock + 0.5);
- break;
- case 0x56: /* F7 */
- eclocks.ev_lo = (ULONG)((1000000.0 / 10.0) / micros_per_eclock + 0.5);
- break;
- case 0x57: /* F8 */
- eclocks.ev_lo = (ULONG)((1000000.0 / 5.0) / micros_per_eclock + 0.5);
- break;
- case 0x58: /* F9 */
- eclocks.ev_lo = (ULONG)(1000000.0 / micros_per_eclock + 0.5);
- break;
- case 0x59: /* F10 */
- if (h.magic == 0xaf11)
- eclocks.ev_lo = (ULONG)((1000000.0 / 70.0) * h.speed /
- micros_per_eclock + 0.5);
- else if (h.magic == 0xaf12)
- eclocks.ev_lo = (ULONG)((1000000.0 / 1000.0) * h.speed /
- micros_per_eclock + 0.5);
- break;
- default:
- break;
- }
- break;
- case IDCMP_VANILLAKEY:
- switch (code) {
- case 0x03: /* CTRL/C */
- printf ("***Break\n");
- exit (0);
- case 0x1b: /* ESC */
- case 0x51: /* q */
- case 0x71: /* Q */
- going = FALSE;
- break;
- case '+':
- if (eclocks.ev_lo == 1)
- eclocks.ev_lo = 0;
- else
- eclocks.ev_lo >>= 1;
- break;
- case '-':
- if (eclocks.ev_lo == 0)
- eclocks.ev_lo = 1;
- else if (eclocks.ev_lo < 500000)
- eclocks.ev_lo <<= 1;
- break;
- default:
- break;
- }
- case IDCMP_MOUSEBUTTONS:
- if (code == MENUDOWN)
- going = FALSE;
- break;
- default:
- break;
- }
- }
- }
-
- } /* end of if frame magic != 0xf100 */
-
- /* seek to the beginning of the next frame or deallocate frame ram */
- if (opt.ram)
- buf = framebuf + fh_size - sizeof(struct frameheader);
- else
- if (framebuf != NULL)
- free (framebuf);
- framebuf = NULL;
-
- /* seek back to frame 1 (the 2nd frame) when we get to the last frame */
- if (frame++ == h.frames)
- if (opt.once)
- going = FALSE;
- else {
- firstloop = FALSE;
- frame = 1;
- if (opt.ram)
- buf = restartptr;
- else
- if (fseek (f, restartpos, SEEK_SET) == -1)
- die ("%s: Error seeking file", programname);
- }
-
- totalframes++;
-
- } /* end of loop for each frame */
-
- if (!safe) {
- Wait (1 << safeport->mp_SigBit);
- while (GetMsg (safeport) != NULL) /* clear message queue */
- /* nothing */ ;
- safe = TRUE;
- }
- if (!disp) {
- Wait (1 << dispport->mp_SigBit);
- while (GetMsg (dispport) != NULL) /* clear message queue */
- /* nothing */ ;
- disp = TRUE;
- }
-
- /* find out and display how long it took */
- ReadEClock (time1);
- sub64 (time1, time0);
- printf ("%s: Achieved frames per second = %4.1lf\n", programname,
- 1000000.0 * totalframes /
- ((time1->ev_hi * 4294967296.0 + time1->ev_lo) * micros_per_eclock));
-
- /* close files and free memory */
- if (f != NULL) {
- fclose (f);
- f = NULL;
- }
- close_screen ();
- if (colourtable != NULL) {
- free (colourtable);
- colourtable = NULL;
- }
- if (viewcolourtable != NULL) {
- free (viewcolourtable);
- viewcolourtable = NULL;
- }
- if (xlate != NULL) {
- free (xlate);
- xlate = NULL;
- }
- if (filebuf != NULL) {
- free (filebuf);
- filebuf = NULL;
- }
- if (!opt.ram) {
- if (fh != NULL) {
- free (fh);
- fh = NULL;
- }
- }
- if (opt.dbuf)
- if (combined_dirty_list != NULL) {
- free (combined_dirty_list);
- combined_dirty_list = NULL;
- }
- if (dirty_list[1] != NULL) {
- free (dirty_list[1]);
- dirty_list[1] = NULL;
- }
- if (dirty_list[0] != NULL) {
- free (dirty_list[0]);
- dirty_list[0] = NULL;
- }
- if (copy_of_chunky != NULL) {
- if (copy_of_chunky != (UBYTE *)GfxBase->ChunkyToPlanarPtr)
- free (copy_of_chunky);
- copy_of_chunky = NULL;
- }
- if (tmpras != NULL) {
- FreeRaster (tmpras, screen_width, screen_depth);
- tmpras = NULL;
- }
- }
-
- /****************************************************************************/
-
- struct TagItem frtags[] = {
- {ASL_Hail, 0},
- {ASL_Pattern, (ULONG)"#?.fl[ic]"},
- {ASL_OKText, (ULONG)"Play"},
- {ASL_CancelText, (ULONG)"Cancel"},
- {ASL_FuncFlags, FILF_PATGAD},
- {TAG_DONE, 0}
- };
-
- char resultstring[128];
-
- void filerequestloop (struct options *opt)
- {
- if ((AslBase = OpenLibrary ("asl.library", 37L)) != NULL) {
- frtags[0].ti_Data = (ULONG)programname;
- if (AslBase->lib_Version < 39)
- frtags[1].ti_Data = (ULONG)"#?.fl?";
- if ((fr = (struct FileRequester *)AllocAslRequest
- (ASL_FileRequest, frtags)) != NULL) {
- while (AslRequest (fr, NULL)) {
- strcpy (resultstring, fr->rf_Dir);
- AddPart (resultstring, fr->rf_File, 128);
- animate_file (resultstring, *opt);
- }
- FreeAslRequest (fr);
- fr = NULL;
- }
- CloseLibrary (AslBase);
- AslBase = NULL;
- }
- }
-
- /****************************************************************************/
-
- LONG argarray[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
-
- int main (int argc, char *argv[])
- {
- struct WBStartup *argmsg;
- struct WBArg *wb_arg;
- char **fnames;
- UWORD ktr;
- struct options opt;
-
-
- /* standard libraries are auto-opened here by SAS/C */
-
- /* find out about ourself */
- thistask = FindTask (NULL);
- GetProgramName (programname, 19);
- v39 = (GfxBase->LibNode.lib_Version >= 39);
- v40 = (GfxBase->LibNode.lib_Version >= 40);
- if ((SysBase->AttnFlags & AFF_68040) != 0)
- cpu_type = 68040;
- else if ((SysBase->AttnFlags & AFF_68030) != 0)
- cpu_type = 68030;
- else if ((SysBase->AttnFlags & AFF_68020) != 0)
- cpu_type = 68020;
- else if ((SysBase->AttnFlags & AFF_68010) != 0)
- cpu_type = 68010;
- else
- cpu_type = 68000;
-
- /* timer stuff */
- if ((timermp = CreatePort (0, 0)) == NULL)
- die ("%s: Can't create messageport!", programname);
- if ((timerio = (struct timerequest *)CreateExtIO (timermp,
- sizeof(struct timerequest))) == NULL)
- die ("%s: Can't create External IO!", programname);
- if (timerclosed = OpenDevice (TIMERNAME, UNIT_MICROHZ,
- (struct IORequest *)timerio, 0))
- die ("%s: Can't open timer.device!", programname);
- TimerBase = (struct Library *)timerio->tr_node.io_Device;
- if ((time = (struct EClockVal *)AllocMem (sizeof(struct EClockVal),
- MEMF_CLEAR | MEMF_PUBLIC)) == NULL ||
- (time0 = (struct EClockVal *)AllocMem (sizeof(struct EClockVal),
- MEMF_CLEAR | MEMF_PUBLIC)) == NULL ||
- (time1 = (struct EClockVal *)AllocMem (sizeof(struct EClockVal),
- MEMF_CLEAR | MEMF_PUBLIC)) == NULL)
- die ("%s: Out of memory", programname);
- micros_per_eclock = 1000000.0 / (double)ReadEClock (time);
-
- /* set default switches */
- opt.ram = TRUE;
- opt.mode = MODE_COLOUR;
- opt.once = FALSE;
- opt.rom = FALSE;
- opt.dbuf = FALSE;
- opt.warp = FALSE;
- opt.akiko = TRUE;
-
- /* try opening EGS libraries */
- if ((EGSBase = OpenLibrary ("egs.library", 0)) != NULL &&
- (EGSGfxBase = OpenLibrary ("egsgfx.library", 0)) != NULL &&
- (EGSBlitBase = OpenLibrary ("egsblit.library", 0)) != NULL &&
- (EGSIntuiBase = OpenLibrary ("egsintui.library", 0)) != NULL) {
- opt.mode = MODE_EGS;
- }
-
- /* parse workbench message or commandline */
- if (argc == 0) {
- argmsg = (struct WBStartup *)argv;
- wb_arg = argmsg->sm_ArgList;
- strcpy (programname, wb_arg->wa_Name);
- parse_tooltypes (wb_arg->wa_Name, &opt);
- if (argmsg->sm_NumArgs <= 1)
- filerequestloop (&opt);
- else {
- wb_arg++;
- for (ktr = 1; ktr < argmsg->sm_NumArgs; ktr++, wb_arg++)
- if (wb_arg->wa_Lock != NULL) {
- olddir = CurrentDir (wb_arg->wa_Lock);
- animate_file (wb_arg->wa_Name, opt);
- CurrentDir (olddir);
- olddir = NULL;
- } else
- animate_file (wb_arg->wa_Name, opt);
- }
- } else {
- if ((rdargs = ReadArgs
- ("FILE/M,DISK/S,RAM/S,ONCE/S,COLOUR/S,COLOR/S,EHB/S,COLOUR4/S,COLOR4/S,GREY/S,GRAY/S,EGS/S,ROM/S,DBUF/S,WARP/S,NOAKIKO/S",
- argarray, NULL)) != NULL) {
- if (argarray[1])
- opt.ram = FALSE;
- if (argarray[2])
- opt.ram = TRUE;
- if (argarray[3])
- opt.once = TRUE;
- if (argarray[4] || argarray[5])
- opt.mode = MODE_COLOUR;
- if (argarray[6])
- opt.mode = MODE_EHB;
- if (argarray[7] || argarray[8])
- opt.mode = MODE_COLOUR4;
- if (argarray[9] || argarray[10])
- opt.mode = MODE_GREY;
- if (argarray[11])
- opt.mode = MODE_EGS;
- if (argarray[12])
- opt.rom = TRUE;
- if (argarray[13])
- opt.dbuf = TRUE;
- if (argarray[14])
- opt.warp = TRUE;
- if (argarray[15])
- opt.akiko = FALSE;
- fnames = (char **)argarray[0];
- if (fnames == NULL || *fnames == NULL)
- filerequestloop (&opt);
- else
- while (*fnames != NULL)
- animate_file (*fnames++, opt);
- FreeArgs (rdargs);
- rdargs = NULL;
- }
- }
-
- /* Let the user see how fast it went before the window closes */
- if (argc == 0)
- Delay (200);
-
- /* exit program with success code */
- return (0);
-
- /* SAS/C executes _STDcleanup() automatically on exit or break */
-
- }
-
- /****************************************************************************/
-