home *** CD-ROM | disk | FTP | other *** search
- /*******************************************************************************
- *
- * (c) Copyright 1993 Commodore-Amiga, Inc. All rights reserved.
- *
- * This software is provided as-is and is subject to change; no warranties
- * are made. All use is at your own risk. No liability or responsibility
- * is assumed.
- *
- * PlayRaw - the main code of the Animation demo. Uses lots of neat AA features
- * and V39 functions.
- *
- ******************************************************************************/
-
- #define LIBVERSION 39
-
- /*******************************************************************/
- /* TO DISABLE CTRL-C HANDLING, SET NO_CTRL_C TO 1 */
- /*******************************************************************/
-
- #define NO_CTRL_C 1
- #if NO_CTRL_C == 1
- int CXBRK (void) { return (0) ; } /* disable ctrl-c */
- #endif
-
- #include <exec/types.h>
- #include <exec/exec.h>
- #include <exec/execbase.h>
- #include <proto/exec.h>
- #include <dos/dos.h>
- #include <dos/rdargs.h>
- #include <proto/dos.h>
- #include <intuition/screens.h>
- #include <intuition/intuition.h>
- #include <intuition/intuitionbase.h>
- #include <proto/intuition.h>
- #include <graphics/gfx.h>
- #include <graphics/gfxbase.h>
- #include <graphics/displayinfo.h>
- #include <graphics/copper.h>
- #include <graphics/gfxmacros.h>
- #include <graphics/videocontrol.h>
- #include <graphics/sprite.h>
- #include <proto/graphics.h>
- #include <libraries/iffparse.h>
- #include <proto/iffparse.h>
- #include <hardware/custom.h>
- #include <devices/input.h>
- #include <devices/inputevent.h>
- #include <devices/audio.h>
-
- #include <stdio.h>
- #include <stdlib.h>
-
- #include "playanim.h"
- #include "asyncio.h"
- #include "sprites.h"
- #include "stick.h"
-
- /*********************************************************************/
- /* GLOBAL VARIABLES */
- /*********************************************************************/
-
- struct IntuitionBase *IntuitionBase = NULL ;
- struct GfxBase *GfxBase = NULL ;
- struct Library *IFFParseBase = NULL;
- extern struct ExecBase *SysBase;
-
- /* This code uses a modified version of Martin Taillefer's AsyncIO routines.
- * Here, we define the DOS functions as macros, so that we can use either normal
- * DOS or AsyncIO routines at the flick of one compiler option.
- *
- * See asyncio.c and AmigaMail Vol. 2 Section 2 P 77 for more details about
- * AsyncIO.
- */
-
- #define ASYNCIO
- #ifdef ASYNCIO
- #define OPEN(f, m, b) OpenAsync((f), (((m) == MODE_READ) ? MODE_READ : MODE_WRITE), (b))
- #define CLOSEFILE(f) CloseAsync((f))
- #define READ(f, b, s) ReadAsync((f), (b), (s))
- #define WRITE(f, b, s) WriteAsync((f), (b), (s))
- #define SEEK(f, s) SeekAsync((f), (b), MODE_START)
- typedef struct AsyncFile *FILETYPE;
- #else
- #define OPEN(f, m, b) Open(f, (((m) == MODE_READ) ? MODE_OLDFILE : MODE_NEWFILE))
- #define CLOSEFILE(f) Close((f))
- #define READ(f, b, s) Read((f), rbuff, (s))
- #define WRITE(f, b, s) Write((f), (b), (s))
- #define SEEK(f, s) Seek((f), (s), OFFSET_BEGINNING)
- typedef BPTR FILETYPE;
- #endif
-
- FILETYPE InFile = NULL;
-
- struct RDArgs *rdargs = NULL;
- struct Screen *screen = NULL;
- struct Screen *cockpitscreen = NULL;
- struct BitMap *bmbuff[] = {NULL, NULL, NULL, NULL}; /* double buffers */
- UWORD *table = NULL;
- UBYTE *inbuff = NULL;
- UBYTE *rbuff;
- APTR XHair = NULL;
- struct UCopList *ucl = NULL;
- struct Window *window = NULL;
- struct Custom *custom = (struct Custom *)0xdff000;
- struct ExtSprite *Sprites[SPRITE_COUNT] = {NULL};
- struct Missile Missiles[MISSILE_COUNT] = {NULL};
-
- /* These are for the inputevent from the joystick */
- struct IOStdReq *InputIO = NULL;
- struct MsgPort *InputMP = NULL;
- struct InputEvent *FakeEvent = NULL;
- struct IEPointerPixel *NewPixel = NULL;
- BOOL InputOpened = FALSE;
- struct JoyStick stick;
-
- /* These are all for the Audio device */
- struct IOAudio *FireAudioIO = NULL;
- struct MsgPort *FireAudioMP = NULL;
- UBYTE *FireAudioBuff = NULL;
- BOOL FireAudioOpened = FALSE;
- struct RawAudio FireRawAudio;
- struct IOAudio *ThrustAudioIO[] = {NULL, NULL};
- struct MsgPort *ThrustAudioMP[] = {NULL, NULL};
- UBYTE *ThrustAudioBuff = NULL;
- BOOL ThrustAudioOpened[] = {FALSE, FALSE};
- struct RawAudio ThrustRawAudio;
-
- /**********************************************************************/
- /* */
- /* void Error (char *String) */
- /* Print string and exit */
- /* */
- /**********************************************************************/
-
- void Error (char *String)
- {
- void CloseAll(void);
-
- printf(String);
-
- CloseAll();
- exit(0);
- }
-
-
- /**********************************************************************/
- /* */
- /* void Init () */
- /* */
- /* Opens all the required libraries */
- /* allocates all memory, etc. */
- /* */
- /**********************************************************************/
-
- APTR InitXHair(void);
- BOOL InitMissiles(struct Missile *Missile, struct ExtSprite *Sprites[]);
- ULONG InitAudio(struct IOAudio *FireAudioIO, struct IOAudio *ThrustAudioIO[]);
-
- void Init (void)
- {
- /* Open the intuition library.... */
- if ((IntuitionBase = (struct IntuitionBase *)OpenLibrary ("intuition.library", LIBVERSION)) == NULL)
- {
- Error ("Could not open the Intuition.library") ;
- }
-
- /* Open the graphics library.... */
- if ((GfxBase = (struct GfxBase *)OpenLibrary ("graphics.library", LIBVERSION)) == NULL)
- {
- Error ("Could not open the Graphics.library") ;
- }
-
- /* open IFFParse library. V37 of IFFParse is sufficient for our needs. */
- if ((IFFParseBase = OpenLibrary("iffparse.library", 37L)) == NULL)
- {
- Error("Could not open the iffparse.library");
- }
-
- if (InitMissiles(&Missiles[0], &Sprites[0]) == NULL)
- {
- Error("Missile allocation error\n");
- }
-
- /* get everything we need for our input event */
- if (!((InputMP = CreateMsgPort()) &&
- (FakeEvent = AllocMem(sizeof(struct InputEvent), MEMF_PUBLIC)) &&
- (NewPixel = AllocMem(sizeof(struct IEPointerPixel), MEMF_PUBLIC)) &&
- (InputIO = CreateIORequest(InputMP, sizeof(struct IOStdReq))) &&
- (InputOpened = ((OpenDevice("input.device", NULL, (struct IORequest *)InputIO, NULL)) == NULL))))
- {
- Error("Error with the input device\n");
- }
-
- /* Get everything we need for the Fire audio */
- if (!((FireAudioMP = CreateMsgPort()) &&
- (FireAudioIO = CreateIORequest(FireAudioMP, sizeof(struct IOAudio))) &&
- (FireAudioOpened = ((OpenDevice("audio.device", NULL, (struct IORequest *)FireAudioIO, NULL)) == NULL))))
- {
- Error("Could not get fire audio\n");
- }
- /* Get everything we need for the Thrust audio */
- if (!((ThrustAudioMP[0] = CreateMsgPort()) &&
- (ThrustAudioIO[0] = CreateIORequest(ThrustAudioMP[0], sizeof(struct IOAudio))) &&
- (ThrustAudioOpened[0] = ((OpenDevice("audio.device", NULL, (struct IORequest *)ThrustAudioIO[0], NULL)) == NULL))))
- {
- Error("Could not get thrust audio 0\n");
- }
- if (!((ThrustAudioMP[1] = CreateMsgPort()) &&
- (ThrustAudioIO[1] = CreateIORequest(ThrustAudioMP[1], sizeof(struct IOAudio))) &&
- (ThrustAudioOpened[1] = ((OpenDevice("audio.device", NULL, (struct IORequest *)ThrustAudioIO[1], NULL)) == NULL))))
- {
- Error("Could not get thrust audio 1\n");
- }
- if (InitAudio(FireAudioIO, ThrustAudioIO))
- {
- Error("Could not allocate the Audio channels\n");
- }
-
- return ;
- }
-
- /**********************************************************************/
- /* */
- /* void CloseAll () */
- /* */
- /* Closes and tidies up everything that was used. */
- /* */
- /**********************************************************************/
-
- void CloseAll ()
- {
- int i;
-
- /* Try to close everything in the reverse order in which they were opened */
-
- if (FireAudioBuff)
- {
- FreeVec(FireAudioBuff);
- }
-
- /* Free the sprite numbers */
-
- for (i = 0; i < MISSILE_COUNT; i++)
- {
- if (Missiles[i].mis_Sprite->es_SimpleSprite.num != -1)
- {
- FreeSprite(Missiles[i].mis_Sprite->es_SimpleSprite.num);
- }
- }
- for (i = 0; i < SPRITE_COUNT; i++)
- {
- if (Sprites[i])
- {
- FreeSpriteData(Sprites[i]);
- }
- }
-
- if (window)
- {
- CloseWindow(window);
- }
-
- if (screen)
- {
- ScreenToBack(screen);
- }
-
- if (bmbuff[1])
- {
- /* This is the copy of the original bitmap from AllocBitMap(). */
- FreeBitMap(bmbuff[1]);
- }
-
- if (table)
- {
- FreeVec(table);
- }
-
- if (inbuff)
- {
- FreeVec(inbuff);
- }
-
- if (cockpitscreen)
- {
- CloseScreen(cockpitscreen);
- }
-
- if (screen)
- {
- CloseScreen(screen);
- }
-
- if (rdargs)
- {
- FreeArgs(rdargs);
- }
-
- if (InFile)
- {
- CLOSEFILE(InFile);
- }
-
- if (XHair)
- {
- DisposeObject(XHair);
- }
-
- if (ThrustAudioOpened[1])
- {
- GetMsg(ThrustAudioIO[1]->ioa_Request.io_Message.mn_ReplyPort);
- CloseDevice((struct IORequest *)ThrustAudioIO[1]);
- }
-
- if (ThrustAudioIO[1])
- {
- DeleteIORequest(ThrustAudioIO[1]);
- }
-
- if (ThrustAudioMP[1])
- {
- DeleteMsgPort(ThrustAudioMP[1]);
- }
-
- if (ThrustAudioOpened[0])
- {
- GetMsg(ThrustAudioIO[0]->ioa_Request.io_Message.mn_ReplyPort);
- CloseDevice((struct IORequest *)ThrustAudioIO[0]);
- }
-
- if (ThrustAudioIO[0])
- {
- DeleteIORequest(ThrustAudioIO[0]);
- }
-
- if (ThrustAudioMP[0])
- {
- DeleteMsgPort(ThrustAudioMP[0]);
- }
-
- if (FireAudioOpened)
- {
- GetMsg(FireAudioIO->ioa_Request.io_Message.mn_ReplyPort);
- CloseDevice((struct IORequest *)FireAudioIO);
- }
-
- if (FireAudioIO)
- {
- DeleteIORequest(FireAudioIO);
- }
-
- if (FireAudioMP)
- {
- DeleteMsgPort(FireAudioMP);
- }
-
- if (InputOpened)
- {
- CloseDevice((struct IORequest *)InputIO);
- }
-
- if (InputIO)
- {
- DeleteIORequest(InputIO);
- }
-
- if (NewPixel)
- {
- FreeMem(NewPixel, sizeof(struct IEPointerPixel));
- }
-
- if (FakeEvent)
- {
- FreeMem(FakeEvent, sizeof(struct InputEvent));
- }
-
- if (InputMP)
- {
- DeleteMsgPort(InputMP);
- }
-
- if (IFFParseBase)
- {
- CloseLibrary(IFFParseBase);
- }
-
- /* Close the Graphics Library */
- if (GfxBase)
- {
- CloseLibrary ((struct Library *) GfxBase) ;
- }
-
- /* Close the Intuition Library */
- if (IntuitionBase)
- {
- CloseLibrary ((struct Library *) IntuitionBase) ;
- }
-
- return ;
- }
-
- /***************************************************************************/
-
- UBYTE *ReadAudio(FILETYPE InFile, struct RawAudio *RawAudio)
- {
- UBYTE *Buff = NULL;
- if (READ(InFile, RawAudio, sizeof(struct RawAudio)) == sizeof(struct RawAudio))
- {
- ULONG padsize;
- UBYTE *pad;
-
- /* The READ() macro always reads into rbuff, so we need to copy
- * the contents into RawAudio.
- */
- CopyMem((APTR)rbuff, (APTR)RawAudio, sizeof(struct RawAudio));
- padsize = ((WHOLE_SECTORS(RawAudio->ra_SizeOfSample + sizeof(struct RawAudio)) * SECTORSIZE) - (RawAudio->ra_SizeOfSample + sizeof(struct RawAudio)));
- if (Buff = AllocVec(RawAudio->ra_SizeOfSample, MEMF_CHIP | MEMF_PUBLIC))
- {
- READ(InFile, Buff, RawAudio->ra_SizeOfSample);
- CopyMem((APTR)rbuff, (APTR)Buff, RawAudio->ra_SizeOfSample);
- }
- if (pad = AllocVec(padsize, 0))
- {
- READ(InFile, pad, padsize);
- FreeVec(pad);
- }
- }
- return(Buff);
- }
-
- /* The actual animation is only 6 bitplanes deep, so it uses 64 pens */
- #define MAXPEN 64
-
- void InitCopLists(struct ViewPort *vp)
- {
- /* The frames were rendered with a purple sky, so use FindColor() to find
- * the purple pen. We will then build a UserCopperList to change the purple
- * to a gradient skyblue.
- *
- * For now, we have to use 12 bits for the gradient. We hope to have a new
- * LVO in the 3.01 graphics.library that will do full 24bit gradual colour
- * changes.
- */
-
- ULONG sky = FindColor(screen->ViewPort.ColorMap, (0xff << 24), 0, (0xff << 24), MAXPEN);
- struct UCopList *ucl;
- ULONG RGB[3] = {FIRSTCOLOUR_RED, FIRSTCOLOUR_GREEN, FIRSTCOLOUR_BLUE};
- LONG Grad[3];
- int i;
-
- if ((ucl = AllocMem(sizeof(struct UCopList), MEMF_PUBLIC | MEMF_CLEAR)) == NULL)
- {
- Error("No RAM for UCopList1\n");
- }
-
- CINIT(ucl, COPINSCNT);
-
- /* calculate the colour gradient. */
- Grad[0] = ((LASTCOLOUR_RED - FIRSTCOLOUR_RED) / COLOURRANGE);
- Grad[1] = ((LASTCOLOUR_GREEN - FIRSTCOLOUR_GREEN) / COLOURRANGE);
- Grad[2] = ((LASTCOLOUR_BLUE - FIRSTCOLOUR_BLUE) / COLOURRANGE);
-
- for (i = 0; i < COLOURRANGE; i++)
- {
- CWAIT(ucl, i, 0);
- /* sky */
- CMOVE(ucl, custom->color[sky & 0x1f], (((RGB[0] & 0xf0000000) >> 20) | ((RGB[1] & 0xf0000000) >> 24) | ((RGB[2] & 0xf0000000) >> 28)));
- RGB[0] += Grad[0];
- RGB[1] += Grad[1];
- RGB[2] += Grad[2];
- }
- CEND(ucl);
- screen->ViewPort.UCopIns = ucl;
-
- /* We can't put the gradient sky in the reflected colour range, because we
- * don't know how to set colours > 32. So in the meanwhilst, just set the
- * reflection to a sky blue.
- * All should be better for 3.01.
- */
- SetRGB32(vp, (sky + MAXPEN), FIRSTCOLOUR_RED, FIRSTCOLOUR_GREEN, FIRSTCOLOUR_BLUE);
-
- RethinkDisplay();
- }
-
- ULONG ScanRate(struct ViewPort *vp)
- {
- /* Calculate the scan rate of the Monitor mode used. */
-
- ULONG ModeID = GetVPModeID(vp);
- ULONG ScanRate = 60;
- struct MonitorInfo minfo;
-
- if (GetDisplayInfoData(NULL, (APTR)&minfo, sizeof(minfo), DTAG_MNTR, ModeID))
- {
- /* The scan rate is the number of nanoseconds in one second (10e9) /
- * the total time for one line in nanoseconds (== colourclocks * ~280ns per
- * colourclock) * the total number of lines.
- */
- ScanRate = (1000000000 / ((ULONG)minfo.TotalColorClocks * 280 * (ULONG)minfo.TotalRows));
- }
-
- return(ScanRate);
- }
-
- /******************************************************************************/
-
- void __asm ShowILBM(register __a0 struct BitMapHeader *bmhd, register __a1 struct BitMap *bm, register __a2 UBYTE *buff);
- void __asm PlayDLTA(register __a2 struct BitMap *bm, register __a1 UBYTE *buff, register __a3 WORD *table, register __d4 UWORD ImageWidth, register __d5 UWORD ImageDepth);
- void HandleInput(struct Input *MyInput);
- void MoveMissile(struct Input *input);
- void FireMissile(struct Input *input);
- void ThrustAudio(struct IOAudio *ThrustAudioIO[], struct RawAudio *RawAudio, UBYTE *ThrustBuffer);
-
- void PlayAnim(FILETYPE InFile, struct Frame1Head *f1h, struct BitMap *bmbuff[], struct ViewPort *vp, UWORD *table, UBYTE *inbuff, ULONG FirstRS, ULONG FirstDS)
- {
- /* This is the main loop that plays the animation.
- *
- * It uses the V39 ChangeVPBitMap() functions, and whilst waiting for the
- * signal to double-buffer, it handles all the input and audio events.
- */
-
- #define WAIT_TO_WRITE while(!GetMsg(ports)) Wait(1l << (ports->mp_SigBit))
-
- struct DBufInfo *dbuf;
- struct MsgPort *ports = NULL;
- struct VistaScript *vista;
- ULONG *secptr, *bytesptr;
- struct Input MyInput;
- ULONG ReadSectors;
- ULONG DLTASize;
- BOOL SafeToWrite = TRUE;
- WORD sbuffno = 1;
- ULONG vbcounter = 0, vbc1, fcount = 0;
- UWORD imagewidth = (((f1h->f1_ImageWidth + 15) >> 4) << 1);
-
- /* Set up the DBuff stuff */
- if ((dbuf = AllocDBufInfo(vp)) == NULL)
- {
- return;
- }
-
- /* Set up the Input structure to pass to HandleInput() */
- MyInput.Stick = &stick;
- MyInput.NewPixel = NewPixel;
- MyInput.InputIO = InputIO;
- MyInput.FakeEvent = FakeEvent;
- MyInput.Screen = screen;
- MyInput.BugOut = &ReadSectors;
- MyInput.Missiles = &Missiles[0];
- MyInput.Sprites = Sprites[0];
- MyInput.FireAudio.RawAudio = &FireRawAudio;
- MyInput.FireAudio.AudioIO = FireAudioIO;
- MyInput.FireAudio.AudioMP = FireAudioMP;
- MyInput.FireAudio.AudioBuffer = FireAudioBuff;
- MyInput.FireAudio.Playing = FALSE;
- MyInput.FireAudio.Period = PERIOD(FireRawAudio.ra_SamplesPerSecond);
- MyInput.FireAudio.Unit = (ULONG)FireAudioIO->ioa_Request.io_Unit;
- MyInput.FireAudio.AllocKey = FireAudioIO->ioa_AllocKey;
-
- if (ports = CreateMsgPort())
- {
- /* A message port for ChangeVPBitMap() */
- dbuf->dbi_SafeMessage.mn_ReplyPort = ports;
-
- ReadSectors = FirstRS;
- DLTASize = FirstDS;
-
- /* GfxBase->VBCounter was added after the 3.0 (V39.106) release.
- * It is just a counter that is incremented every vertical blank.
- */
- vbc1 = GfxBase->VBCounter;
-
- /* Start up the Thrusters */
- ThrustAudio(ThrustAudioIO, &ThrustRawAudio, ThrustAudioBuff);
- WaitBlit(); /* from the BltBitMap() call in main() */
-
- /**************************************/
- /* */
- /* Here is the main animation loop... */
- /* */
- /**************************************/
-
- while (ReadSectors)
- {
- READ(InFile, inbuff, (SECTORSIZE * ReadSectors));
-
- bytesptr = (ULONG *)(rbuff + DLTASize);
- secptr = (bytesptr + 1);
- ReadSectors = *secptr;
- DLTASize = *bytesptr;
- vista = (struct VistaScript *)(secptr + 1);
- MyInput.Vista = vista;
-
- if (!SafeToWrite)
- {
- WAIT_TO_WRITE;
- }
- SafeToWrite = TRUE;
-
- PlayDLTA(bmbuff[sbuffno + 2], rbuff, table, imagewidth, f1h->f1_ImageDepth);
-
- vbcounter += (GfxBase->VBCounter - vbc1);
- ChangeVPBitMap(vp, bmbuff[sbuffno], dbuf);
- vbc1 = GfxBase->VBCounter;
- fcount++;
- SafeToWrite = FALSE;
- sbuffno ^= 1;
-
- HandleInput(&MyInput);
- if (Missiles[0].mis_Active)
- {
- MoveMissile(&MyInput);
- }
- }
-
- /**************************************/
- /* */
- /* That was it!! */
- /* */
- /**************************************/
-
- if (!SafeToWrite)
- {
- WAIT_TO_WRITE;
- }
- DeleteMsgPort(ports);
- }
-
- FreeDBufInfo(dbuf);
-
- if (vbcounter)
- {
- printf("Played %ld frames in %ld frames, or %ld fps\n", fcount, vbcounter, ((ScanRate(vp) * fcount) / vbcounter));
- }
- }
-
-
- ULONG GetModeID(struct Frame1Head *f1h)
- {
- /* Check that the ID in the raw file can handle sprites and doublebuffering.
- * If not, then find the best ModeID that can.
- */
- ULONG ModeID = f1h->f1_ScreenModeID;
- struct DisplayInfo disp;
-
- if (GetDisplayInfoData(NULL, (UBYTE *)&disp, sizeof(struct DisplayInfo), DTAG_DISP, ModeID))
- {
- if ((disp.PropertyFlags & (DIPF_IS_SPRITES | DIPF_IS_DBUFFER)) != (DIPF_IS_SPRITES | DIPF_IS_DBUFFER))
- {
- ModeID = BestModeID(BIDTAG_NominalWidth, f1h->f1_ScreenWidth,
- BIDTAG_NominalHeight, f1h->f1_ScreenHeight,
- BIDTAG_Depth, f1h->f1_ScreenDepth,
- /* Keep the DIPF_ properties of the original
- * ModeID, but ensure we have SPRITES and DBUFFER
- * properties too.
- */
- BIDTAG_SourceID, ModeID,
- BIDTAG_DIPFMustHave, (DIPF_IS_SPRITES | DIPF_IS_DBUFFER),
- TAG_END);
- }
- }
- return(ModeID);
- }
-
-
- /******************************************************************************/
- /******************************************************************************/
- /******************************************************************************/
-
- void ReadILBM(STRPTR Mask, struct Screen *Screen, BOOL CMap);
- struct Screen *OpenCockpit(STRPTR Cockpit, struct Screen *Parent);
-
- void main (int argc, char *argv[])
- {
- #define TEMPLATE "FROM/A,C=COCKPIT,M=MASK"
- #define OPT_FROM 0
- #define OPT_COCKPIT 1
- #define OPT_MASK 2
- #define OPT_COUNT 3
-
- #define SPRITE_BASE 128
-
- LONG result[OPT_COUNT];
- struct TagItem VCTags[] =
- {
- VTAG_SPEVEN_BASE_SET, SPRITE_BASE,
- VTAG_SPODD_BASE_SET, SPRITE_BASE,
- VTAG_USERCLIP_SET, TRUE,
- TAG_END,
- };
- STRPTR from, cockpit = NULL, mask = NULL;
- ULONG *secptr, *bytesptr;
- ULONG ReadSectors;
- ULONG DLTASize;
- struct Frame1Head f1h;
- struct BitMapHeader bmhd;
- struct BitMap bm1, bm2, bm3;
- UWORD XOffs, YOffs;
- int j, r;
- UWORD ncolours;
-
- Init () ;
-
- /* init the result[] */
- result[OPT_FROM] = (LONG)&from;
- result[OPT_COCKPIT] = (LONG)&cockpit;
- result[OPT_MASK] = (LONG)&mask;
-
- if (rdargs = ReadArgs(TEMPLATE, result, NULL))
- {
- from = (STRPTR)result[OPT_FROM];
- cockpit = (STRPTR)result[OPT_COCKPIT];
- mask = (STRPTR)result[OPT_MASK];
- }
- else
- {
- Error("Command line error\n");
- }
-
- if (inbuff = AllocVec(SECTORSIZE, 0))
- {
- if ((InFile = OPEN(from, MODE_READ, SECTORSIZE)) == NULL)
- {
- Error("Could not open the file\n");
- }
-
- rbuff = inbuff;
- if (READ(InFile, inbuff, SECTORSIZE) == SECTORSIZE)
- {
- /* have all the info we need to open the screen and set up
- * the colours.
- */
-
- ULONG ModeID;
- UBYTE *cmap = (rbuff + sizeof(f1h));
- int i;
-
- f1h = (*(struct Frame1Head *)rbuff);
- ncolours = f1h.f1_Colours;
-
- ModeID = GetModeID(&f1h);
- printf("Animation ModeID = 0x%lx\n", ModeID);
-
- /* Open the screen. Notice that we are using SA_FullPalette which
- * informs intuition that we want a palette with the maximum
- * possible number of colours (256 for AA). This lets us use the
- * upper colours that are not part of the animation for the sprite
- * colours. This is a feature of the AA chips, and we handle this
- * on a ViewPort (or Screen) basis with the VideoControl() tags
- * defined in VCTags[]. Under V39, we can pass OpenScreenTags()
- * a taglist of VideoControl() tags to be used when the screen is
- * opened.
- */
- if ((screen = OpenScreenTags(NULL,
- SA_Width, f1h.f1_ScreenWidth,
- SA_Height, f1h.f1_ScreenHeight,
- SA_Depth, f1h.f1_ScreenDepth,
- SA_DisplayID, ModeID,
- SA_FullPalette, TRUE,
- SA_Behind, TRUE,
- SA_VideoControl, VCTags,
- TAG_DONE)) == NULL)
- {
- Error("Could not open screen\n");
- }
-
- /* Display the cockpit as a child screen */
-
- if (cockpit)
- {
- cockpitscreen = OpenCockpit(cockpit, screen);
- }
-
- /* Set up the colours for the sprites */
- SetRGB32(&screen->ViewPort, SPRITE_BASE, 0, 0, 0); /* transparent */
- SetRGB32(&screen->ViewPort, (SPRITE_BASE + 1), -1, -1, -1); /* white */
- SetRGB32(&screen->ViewPort, (SPRITE_BASE + 2), -1, 0, 0); /* red */
- SetRGB32(&screen->ViewPort, (SPRITE_BASE + 3), 0, -1, 0); /* green (unused) */
-
- /* Open a borderless backdrop window in the screen. We use this
- * to change the pointer to our crosshair, and treat any keypress
- * to quit the animation.
- */
- if ((window = OpenWindowTags(NULL,
- WA_CustomScreen, screen,
- WA_Backdrop, TRUE,
- WA_Borderless, TRUE,
- WA_Activate, TRUE,
- WA_RMBTrap, TRUE,
- WA_IDCMP, IDCMP_RAWKEY,
- TAG_DONE)) == NULL)
- {
- Error("Could not open the window\n");
- }
-
- /* If there is a Mask for the animation area, load it in here. */
- ReadILBM(mask, screen, FALSE);
-
- for (i = 0; i < ncolours; i++)
- {
- ULONG red = (*cmap++ << 24);
- ULONG green = (*cmap++ << 24);
- ULONG blue = (*cmap++ << 24);
- ULONG rred;
- ULONG rgreen;
- ULONG rblue;
- /* before creating the reflected colours, check for
- * overflow.
- */
- if ((rred = (red + (red / 5))) < red)
- {
- rred = 0xffffffff;
- }
- if ((rgreen = (green + (green / 5))) < green)
- {
- rgreen = 0xffffffff;
- }
- if ((rblue = (blue + (blue / 5))) < blue)
- {
- rblue = 0xffffffff;
- }
- SetRGB32(&screen->ViewPort, i, rred, rgreen, rblue);
- SetRGB32(&screen->ViewPort, (i + ncolours), red, green, blue);
- }
- CLOSEFILE(InFile);
- InFile = NULL;
- }
- else
- {
- Error("File read error\n");
- }
- FreeVec(inbuff);
- inbuff = NULL;
- }
- else
- {
- Error("not enough memory\n");
- }
-
- /* Now, we have a screen and we know the maximum buffer size we need.
- * So, read in the first frame, and treat it as a raw ILBM, once we skip over
- * all the Frame1Header info.
- */
-
- /* Set up our two buffers */
- bm1 = *(screen->RastPort.BitMap);
- bmbuff[0] = &bm1;
- if ((bmbuff[1] = AllocBitMap(f1h.f1_ScreenWidth, f1h.f1_ScreenHeight, f1h.f1_ScreenDepth, BMF_DISPLAYABLE, bmbuff[0])) == NULL)
- {
- Error("Not enough memory for 2nd bitmap\n");
- }
- /* Because the image may be smaller than the whole screen,
- * we will munge the bitmaps for the Anim code
- * so that the planes point to the correct offset in
- * the bitplanes to center the image. This means
- * we need to keep separate copies of the true bitmaps.
- */
- bm2 = *(bmbuff[0]);
- bm3 = *(bmbuff[1]);
- bmbuff[2] = &bm2;
- bmbuff[3] = &bm3;
-
- /* Center this image in the screen */
- XOffs = ((f1h.f1_ScreenWidth - f1h.f1_ImageWidth) >> 4); /* byte offset */
- YOffs = (((f1h.f1_ScreenHeight - f1h.f1_ImageHeight) >> 1) * bmbuff[0]->BytesPerRow); /* row offset in bytes */
-
- /* Munge the planepointers to the correct offsets to center */
- for (j = 2; j < 4; j++)
- {
- for (r = 0; r < f1h.f1_ImageDepth; r++)
- {
- bmbuff[j]->Planes[r] += (YOffs + XOffs);
- }
- }
-
- /* create the offset table for the DLTA code */
- if (table = AllocVec((f1h.f1_ImageHeight << 1), 0))
- {
- UWORD c = 0;
- UWORD *tmp = table;
- for (r = 0; r < f1h.f1_ImageHeight; r++)
- {
- *tmp++ = c;
- c += screen->RastPort.BitMap->BytesPerRow;
- }
- }
- else
- {
- Error("Not memory for table\n");
- }
-
-
-
- if (inbuff = AllocVec((SECTORSIZE * f1h.f1_MaxSectorSize), MEMF_CLEAR))
- {
- if (InFile = OPEN(from, MODE_READ, (SECTORSIZE * f1h.f1_MaxSectorSize * 2)))
- {
- rbuff = inbuff;
- if (READ(InFile, inbuff, (f1h.f1_Sectors * SECTORSIZE)) == (f1h.f1_Sectors * SECTORSIZE))
- {
- UBYTE *image = (rbuff + DATASIZE);
-
- /* set up the bmhd with the values ShowILBM() needs */
- bmhd.nplanes = f1h.f1_ImageDepth;
- bmhd.w = f1h.f1_ImageWidth;
- bmhd.h = f1h.f1_ImageHeight;
-
- ShowILBM(&bmhd, bmbuff[2], image);
-
- /* Copy the image into the other buffer */
- BltBitMap(bmbuff[0], 0, 0, bmbuff[1], 0, 0, f1h.f1_ScreenWidth, f1h.f1_ScreenHeight, 0xc0, -1, NULL);
- }
- else
- {
- Error("1st frame error\n");
- }
- }
- else
- {
- Error("1st frame did not open\n");
- }
- }
- else
- {
- Error("RAM all gone?\n");
- }
-
- /* get the ReadSectors and DLTASize here, because reading the Audio data trashes the rbuff buffer */
- bytesptr = (ULONG *)(rbuff + DATASIZE + f1h.f1_ByteSize);
- secptr = (bytesptr + 1);
- ReadSectors = *secptr;
- DLTASize = *bytesptr;
-
- /* Read the Audio sectors */
- FireAudioBuff = ReadAudio(InFile, &FireRawAudio);
- ThrustAudioBuff = ReadAudio(InFile, &ThrustRawAudio);
-
- /* final initialisations.... */
- InitCopLists(&screen->ViewPort);
- ScreenToFront(screen);
- if ((XHair = InitXHair()) == NULL)
- {
- Error("No XHair sprite\n");
- }
- SetWindowPointer(window, WA_Pointer, XHair, TAG_DONE);
- /* Put the cursor (intuition's pointer) in the center of the screen */
- FakeEvent->ie_NextEvent = NULL;
- FakeEvent->ie_Class = IECLASS_NEWPOINTERPOS;
- FakeEvent->ie_SubClass = IESUBCLASS_PIXEL;
- FakeEvent->ie_Code = IECODE_NOBUTTON;
- FakeEvent->ie_Qualifier = NULL;
- FakeEvent->ie_EventAddress = (APTR)NewPixel;
- InputIO->io_Data = (APTR)FakeEvent;
- InputIO->io_Length = sizeof(struct InputEvent);
- InputIO->io_Command = IND_WRITEEVENT;
- NewPixel->iepp_Position.X = (screen->Width >> 1);
- NewPixel->iepp_Position.Y = (screen->Height >> 1);
- NewPixel->iepp_Screen = screen;
- DoIO((struct IORequest *)InputIO);
-
- /* Now play the anim until the end! */
- PlayAnim(InFile, &f1h, bmbuff, &screen->ViewPort, table, inbuff, ReadSectors, DLTASize);
-
- CloseAll () ;
- }
-