home *** CD-ROM | disk | FTP | other *** search
/ Micro R&D 1 / MicroRD-CD-ROM-Vol1-1994.iso / os30 / gfx / animdemo.lha / iff.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-22  |  5.7 KB  |  188 lines

  1. /*******************************************************************************
  2.  *
  3.  * (c) Copyright 1993 Commodore-Amiga, Inc.  All rights reserved.
  4.  *
  5.  * This software is provided as-is and is subject to change; no warranties
  6.  * are made.  All use is at your own risk.  No liability or responsibility
  7.  * is assumed.
  8.  *
  9.  * iff.c - reads normal IFF ILBM files. Used for the mask and cockpit images.
  10.  *
  11.  ******************************************************************************/
  12.  
  13. #include <intuition/screens.h>
  14. #include <intuition/intuition.h>
  15. #include <intuition/intuitionbase.h>
  16. #include <graphics/gfx.h>
  17. #include <graphics/modeid.h>
  18. #include <libraries/iffparse.h>
  19. #include <proto/iffparse.h>
  20. #include <dos/dos.h>
  21. #include <proto/dos.h>
  22. #include <proto/exec.h>
  23. #include <proto/graphics.h>
  24. #include <proto/intuition.h>
  25. #include <stdio.h>
  26.  
  27. #include "playanim.h"
  28.  
  29. void __asm ShowILBM(register __a0 struct BitMapHeader *bmhd, register __a1 struct BitMap *bm, register __a2 UBYTE *buff);
  30. void Error (char *String);
  31.  
  32. #define ID_ILBM MAKE_ID('I','L','B','M')
  33. #define ID_BODY MAKE_ID('B','O','D','Y')
  34. #define ID_BMHD MAKE_ID('B','M','H','D')
  35. #define ID_CMAP MAKE_ID('C','M','A','P')
  36. #define ID_CAMG MAKE_ID('C','A','M','G')
  37.  
  38. void ReadILBM(STRPTR ILBM, struct Screen *Screen, BOOL CMap)
  39. {
  40.     /* Use the IFFParse.library to parse a normal IFF ILBM file. */
  41.  
  42.     struct IFFHandle *iff = NULL;
  43.     struct StoredProperty *sp;
  44.     struct ContextNode *cn;
  45.     APTR inbuff;
  46.     UBYTE *cmap;
  47.     struct BitMapHeader bmhd;
  48.  
  49.     if (iff = AllocIFF())
  50.     {
  51.     if ((iff->iff_Stream = Open(ILBM, MODE_OLDFILE)) == NULL)
  52.     {
  53.         FreeIFF(iff);
  54.         return;
  55.     }
  56.     InitIFFasDOS(iff);
  57.     if (OpenIFF(iff, IFFF_READ) == NULL)
  58.     {
  59.         if ((PropChunk(iff, ID_ILBM, ID_BMHD) == 0) &&
  60.             (PropChunk(iff, ID_ILBM, ID_CMAP) == 0) &&
  61.             (StopChunk(iff, ID_ILBM, ID_BODY) == 0) &&
  62.             (ParseIFF(iff, IFFPARSE_SCAN) == 0))
  63.         {
  64.             if (sp = FindProp(iff, ID_ILBM, ID_BMHD))
  65.             {
  66.                 bmhd = (*(struct BitMapHeader *)sp->sp_Data);
  67.             }
  68.             if (CMap && (sp = FindProp(iff, ID_ILBM, ID_CMAP)))
  69.             {
  70.                 int i;
  71.                 cmap = (UBYTE *)sp->sp_Data;
  72.                 for (i = 0; i < (1 << bmhd.nplanes); i++)
  73.                 {
  74.                     SetRGB32(&Screen->ViewPort, i, ((*cmap++) << 24), ((*cmap++) << 24), ((*cmap++) << 24));
  75.                 }
  76.             }
  77.             /* we are at the BODY chunk */
  78.             if ((cn = CurrentChunk(iff)) &&
  79.                 (inbuff = AllocVec(cn->cn_Size, 0)))
  80.             {
  81.                 ReadChunkBytes(iff, inbuff, cn->cn_Size);
  82.                 ShowILBM(&bmhd, Screen->RastPort.BitMap, inbuff);
  83.  
  84.                 FreeVec(inbuff);
  85.             }
  86.         }
  87.         CloseIFF(iff);
  88.     }
  89.     Close(iff->iff_Stream);
  90.     FreeIFF(iff);
  91.     }
  92. }
  93.  
  94. struct Screen *OpenCockpit(STRPTR Cockpit, struct Screen *Parent)
  95. {
  96.     /* Use IFFParse.library to parse the cockpit image, which is just
  97.      * a normal IFF ILBM file, and render it into a screen's bitmap.
  98.      * This cockpit screen will be attached to the main animation screen,
  99.      * and so the two separate screens will be treated as one.
  100.      */
  101.  
  102.     struct IFFHandle *iff = NULL;
  103.     struct StoredProperty *sp;
  104.     struct Screen *cockpit = FALSE;
  105.     ULONG camg;
  106.     struct BitMapHeader bmhd;
  107.  
  108.     if (iff = AllocIFF())
  109.     {
  110.     if ((iff->iff_Stream = Open(Cockpit, MODE_OLDFILE)) == NULL)
  111.     {
  112.         FreeIFF(iff);
  113.         return(NULL);
  114.     }
  115.     InitIFFasDOS(iff);
  116.     if (OpenIFF(iff, IFFF_READ) == NULL)
  117.     {
  118.         if ((PropChunk(iff, ID_ILBM, ID_BMHD) == 0) &&
  119.             (PropChunk(iff, ID_ILBM, ID_CAMG) == 0) &&
  120.             (StopChunk(iff, ID_ILBM, ID_BODY) == 0) &&
  121.             (ParseIFF(iff, IFFPARSE_SCAN) == 0))
  122.         {
  123.             ULONG ModeID;
  124.  
  125.             if (sp = FindProp(iff, ID_ILBM, ID_BMHD))
  126.             {
  127.                 bmhd = (*(struct BitMapHeader *)sp->sp_Data);
  128.             }
  129.             if (sp = FindProp(iff, ID_ILBM, ID_CAMG))
  130.             {
  131.                 camg = (*(ULONG *)sp->sp_Data);
  132.             }
  133.             /* make sure we choose a ModeID for the cockpit
  134.              * that is of the same monitor type as the 
  135.              * main animation screen.
  136.              */
  137.             ModeID = BestModeID(BIDTAG_SourceID, camg,
  138.                                 BIDTAG_MonitorID, (GetVPModeID(&Parent->ViewPort) & MONITOR_ID_MASK),
  139.                                 TAG_END);
  140.             printf("Cockpit ModeID = 0x%lx\n", ModeID);
  141.  
  142.             cockpit = OpenScreenTags(NULL,
  143.                       SA_Width, bmhd.w,
  144.                       SA_Height, bmhd.h,
  145.                       SA_Depth, bmhd.nplanes,
  146.                       SA_DisplayID, ModeID,
  147.                       SA_Parent, Parent,
  148.                       SA_Draggable, FALSE,
  149.                       TAG_END);
  150.         }
  151.         CloseIFF(iff);
  152.     }
  153.     Close(iff->iff_Stream);
  154.     FreeIFF(iff);
  155.     }
  156.  
  157.     if (cockpit)
  158.     {
  159.     /* The cockpit screen was opened at the top of the display, but we want
  160.      * it to be below the animation screen, so we use ScreenPosition() to
  161.      * position the screen. Note that we have to use SPOS_FORCEDRAG as the
  162.      * screen was opened as non-draggable.
  163.      *
  164.      * The cockpit screen's first visible line should be positioned at the
  165.      * Parent->Height + the number of lines needed for the inter-screen gap.
  166.      * This would be the perfect place to use graphics' CalcIVG() function,
  167.      * where UWORD ivg = CalcIVG(&IntuitionBase->ViewLord, &Parent->ViewPort).
  168.      * However, when a screen is opened behind the others (which is true in
  169.      * this case), then intuition does not call MakeVPort() on the screen's
  170.      * ViewPort. Therefore, there are no ViewPort->DspIns instructions when
  171.      * CalcIVG() is called, so CalcIVG() returns 0.
  172.      *
  173.      * To work around this, I have hard-coded (Bleuchhh!!) the inter-screen
  174.      * gap to 10 lines here. An alternative would be to open the screens in
  175.      * front, so CalcIVG() could return a correct value. That would mean that
  176.      * all our initialisations would be visible, which is not very pretty.
  177.      * [I guess we could do that with a colour palette of all blacks, so
  178.      *  nothing could be seen. I'll leave that as an exercise for the reader.]
  179.      */
  180.  
  181.     UWORD ivg = 10;
  182.     ReadILBM(Cockpit, cockpit, TRUE);
  183.     ScreenPosition(cockpit, (SPOS_RELATIVE | SPOS_FORCEDRAG), 0, (Parent->Height + ivg), 0, 0);
  184.     }
  185.  
  186.     return(cockpit);
  187. }                
  188.