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.
- *
- * iff.c - reads normal IFF ILBM files. Used for the mask and cockpit images.
- *
- ******************************************************************************/
-
- #include <intuition/screens.h>
- #include <intuition/intuition.h>
- #include <intuition/intuitionbase.h>
- #include <graphics/gfx.h>
- #include <graphics/modeid.h>
- #include <libraries/iffparse.h>
- #include <proto/iffparse.h>
- #include <dos/dos.h>
- #include <proto/dos.h>
- #include <proto/exec.h>
- #include <proto/graphics.h>
- #include <proto/intuition.h>
- #include <stdio.h>
-
- #include "playanim.h"
-
- void __asm ShowILBM(register __a0 struct BitMapHeader *bmhd, register __a1 struct BitMap *bm, register __a2 UBYTE *buff);
- void Error (char *String);
-
- #define ID_ILBM MAKE_ID('I','L','B','M')
- #define ID_BODY MAKE_ID('B','O','D','Y')
- #define ID_BMHD MAKE_ID('B','M','H','D')
- #define ID_CMAP MAKE_ID('C','M','A','P')
- #define ID_CAMG MAKE_ID('C','A','M','G')
-
- void ReadILBM(STRPTR ILBM, struct Screen *Screen, BOOL CMap)
- {
- /* Use the IFFParse.library to parse a normal IFF ILBM file. */
-
- struct IFFHandle *iff = NULL;
- struct StoredProperty *sp;
- struct ContextNode *cn;
- APTR inbuff;
- UBYTE *cmap;
- struct BitMapHeader bmhd;
-
- if (iff = AllocIFF())
- {
- if ((iff->iff_Stream = Open(ILBM, MODE_OLDFILE)) == NULL)
- {
- FreeIFF(iff);
- return;
- }
- InitIFFasDOS(iff);
- if (OpenIFF(iff, IFFF_READ) == NULL)
- {
- if ((PropChunk(iff, ID_ILBM, ID_BMHD) == 0) &&
- (PropChunk(iff, ID_ILBM, ID_CMAP) == 0) &&
- (StopChunk(iff, ID_ILBM, ID_BODY) == 0) &&
- (ParseIFF(iff, IFFPARSE_SCAN) == 0))
- {
- if (sp = FindProp(iff, ID_ILBM, ID_BMHD))
- {
- bmhd = (*(struct BitMapHeader *)sp->sp_Data);
- }
- if (CMap && (sp = FindProp(iff, ID_ILBM, ID_CMAP)))
- {
- int i;
- cmap = (UBYTE *)sp->sp_Data;
- for (i = 0; i < (1 << bmhd.nplanes); i++)
- {
- SetRGB32(&Screen->ViewPort, i, ((*cmap++) << 24), ((*cmap++) << 24), ((*cmap++) << 24));
- }
- }
- /* we are at the BODY chunk */
- if ((cn = CurrentChunk(iff)) &&
- (inbuff = AllocVec(cn->cn_Size, 0)))
- {
- ReadChunkBytes(iff, inbuff, cn->cn_Size);
- ShowILBM(&bmhd, Screen->RastPort.BitMap, inbuff);
-
- FreeVec(inbuff);
- }
- }
- CloseIFF(iff);
- }
- Close(iff->iff_Stream);
- FreeIFF(iff);
- }
- }
-
- struct Screen *OpenCockpit(STRPTR Cockpit, struct Screen *Parent)
- {
- /* Use IFFParse.library to parse the cockpit image, which is just
- * a normal IFF ILBM file, and render it into a screen's bitmap.
- * This cockpit screen will be attached to the main animation screen,
- * and so the two separate screens will be treated as one.
- */
-
- struct IFFHandle *iff = NULL;
- struct StoredProperty *sp;
- struct Screen *cockpit = FALSE;
- ULONG camg;
- struct BitMapHeader bmhd;
-
- if (iff = AllocIFF())
- {
- if ((iff->iff_Stream = Open(Cockpit, MODE_OLDFILE)) == NULL)
- {
- FreeIFF(iff);
- return(NULL);
- }
- InitIFFasDOS(iff);
- if (OpenIFF(iff, IFFF_READ) == NULL)
- {
- if ((PropChunk(iff, ID_ILBM, ID_BMHD) == 0) &&
- (PropChunk(iff, ID_ILBM, ID_CAMG) == 0) &&
- (StopChunk(iff, ID_ILBM, ID_BODY) == 0) &&
- (ParseIFF(iff, IFFPARSE_SCAN) == 0))
- {
- ULONG ModeID;
-
- if (sp = FindProp(iff, ID_ILBM, ID_BMHD))
- {
- bmhd = (*(struct BitMapHeader *)sp->sp_Data);
- }
- if (sp = FindProp(iff, ID_ILBM, ID_CAMG))
- {
- camg = (*(ULONG *)sp->sp_Data);
- }
- /* make sure we choose a ModeID for the cockpit
- * that is of the same monitor type as the
- * main animation screen.
- */
- ModeID = BestModeID(BIDTAG_SourceID, camg,
- BIDTAG_MonitorID, (GetVPModeID(&Parent->ViewPort) & MONITOR_ID_MASK),
- TAG_END);
- printf("Cockpit ModeID = 0x%lx\n", ModeID);
-
- cockpit = OpenScreenTags(NULL,
- SA_Width, bmhd.w,
- SA_Height, bmhd.h,
- SA_Depth, bmhd.nplanes,
- SA_DisplayID, ModeID,
- SA_Parent, Parent,
- SA_Draggable, FALSE,
- TAG_END);
- }
- CloseIFF(iff);
- }
- Close(iff->iff_Stream);
- FreeIFF(iff);
- }
-
- if (cockpit)
- {
- /* The cockpit screen was opened at the top of the display, but we want
- * it to be below the animation screen, so we use ScreenPosition() to
- * position the screen. Note that we have to use SPOS_FORCEDRAG as the
- * screen was opened as non-draggable.
- *
- * The cockpit screen's first visible line should be positioned at the
- * Parent->Height + the number of lines needed for the inter-screen gap.
- * This would be the perfect place to use graphics' CalcIVG() function,
- * where UWORD ivg = CalcIVG(&IntuitionBase->ViewLord, &Parent->ViewPort).
- * However, when a screen is opened behind the others (which is true in
- * this case), then intuition does not call MakeVPort() on the screen's
- * ViewPort. Therefore, there are no ViewPort->DspIns instructions when
- * CalcIVG() is called, so CalcIVG() returns 0.
- *
- * To work around this, I have hard-coded (Bleuchhh!!) the inter-screen
- * gap to 10 lines here. An alternative would be to open the screens in
- * front, so CalcIVG() could return a correct value. That would mean that
- * all our initialisations would be visible, which is not very pretty.
- * [I guess we could do that with a colour palette of all blacks, so
- * nothing could be seen. I'll leave that as an exercise for the reader.]
- */
-
- UWORD ivg = 10;
- ReadILBM(Cockpit, cockpit, TRUE);
- ScreenPosition(cockpit, (SPOS_RELATIVE | SPOS_FORCEDRAG), 0, (Parent->Height + ivg), 0, 0);
- }
-
- return(cockpit);
- }
-