home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / ROM_Kernel_Manuals / Devices / apps / 24bitDemo / 24bitDemo.c
Encoding:
C/C++ Source or Header  |  1992-08-20  |  11.0 KB  |  414 lines

  1. /* 24bitDemo.c 05/91  C. Scheppner CBM
  2.  *
  3.  * Example which creates a 24-bit raster, saves it as a 24-bit ILBM,
  4.  *   then loads it as a brush and shows it to you 4 planes at a time
  5.  *   Optionally (if given a filename) just displays 4 planes at a time.
  6.  *
  7.  * requires linkage with several IFF modules
  8.  * see Makefile
  9.  */
  10.  
  11. #include "iffp/ilbmapp.h"
  12.  
  13.  
  14. #ifdef LATTICE
  15. int CXBRK(void) { return(0); }  /* Disable Lattice CTRL/C handling */
  16. int chkabort(void) { return(0); }  /* really */
  17. #endif
  18.  
  19. void cleanup(void);
  20. void bye(UBYTE *s,int error);
  21.  
  22. #define MINARGS 1
  23. char *vers = "\0$VER: 24bitDemo 37.5";
  24. char *Copyright = "24bitDemo v37.5 (Freely Redistributable)";
  25. char *usage = "Usage: 24bitDemo [loadname] (saves/loads if no loadname given)";
  26.  
  27.  
  28. struct Library *IntuitionBase  = NULL;
  29. struct Library *GfxBase        = NULL;
  30. struct Library *IFFParseBase   = NULL;
  31.  
  32. /* Note - these fields are also available in the ILBMInfo structure */
  33. struct   Screen         *scr;         /* for ptr to screen structure */
  34. struct   Window         *win;         /* for ptr to window structure */
  35. struct   RastPort       *wrp;         /* for ptr to RastPort  */
  36. struct   ViewPort       *vp;          /* for ptr to Viewport  */
  37.  
  38.  
  39. struct   NewWindow      mynw = {
  40.    0, 0,                                  /* LeftEdge and TopEdge */
  41.    0, 0,                                /* Width and Height */
  42.    -1, -1,                                /* DetailPen and BlockPen */
  43.    VANILLAKEY|MOUSEBUTTONS,               /* IDCMP Flags with Flags below */
  44.    BACKDROP|BORDERLESS|SMART_REFRESH|NOCAREREFRESH|ACTIVATE|RMBTRAP,
  45.    NULL, NULL,                            /* Gadget and Image pointers */
  46.    NULL,                                  /* Title string */
  47.    NULL,                                  /* Screen ptr null till opened */
  48.    NULL,                                  /* BitMap pointer */
  49.    50, 20,                                /* MinWidth and MinHeight */
  50.    0 , 0,                                 /* MaxWidth and MaxHeight */
  51.    CUSTOMSCREEN                           /* Type of window */
  52.    };
  53.  
  54.  
  55. BOOL   FromWb;
  56.  
  57.  
  58. /* ILBM Property chunks to be grabbed
  59.  * List BMHD, CMAP and CAMG first so we can skip them when we write
  60.  * the file back out (they will be written out with separate code)
  61.  */
  62. LONG    ilbmprops[] = {
  63.         ID_ILBM, ID_BMHD,
  64.         ID_ILBM, ID_CMAP,
  65.         ID_ILBM, ID_CAMG,
  66.         ID_ILBM, ID_CCRT,
  67.         ID_ILBM, ID_AUTH,
  68.         ID_ILBM, ID_Copyright,
  69.         TAG_DONE
  70.         };
  71.  
  72. /* ILBM Collection chunks (more than one in file) to be gathered */
  73. LONG    ilbmcollects[] = {
  74.         ID_ILBM, ID_CRNG,
  75.         TAG_DONE
  76.         };
  77.  
  78. /* ILBM Chunk to stop on */
  79. LONG    ilbmstops[] = {
  80.         ID_ILBM, ID_BODY,
  81.         TAG_DONE
  82.         };
  83.  
  84.  
  85. UBYTE nomem[]  = "Not enough memory\n";
  86. UBYTE noiffh[] = "Can't alloc iff\n";
  87.  
  88.  
  89. /* For our allocated ILBM frames */
  90. struct ILBMInfo  *ilbm[2];
  91.  
  92. #define SCRPLANES 4
  93.  
  94. USHORT colortable[32];
  95. USHORT cstarts[]= { 0x000, 0x800, 0x000, 0x080, 0x000, 0x008 };
  96. USHORT coffs[]    = { 0x100, 0x100, 0x010, 0x010, 0x001, 0x001 };
  97.  
  98. UBYTE *ilbmname = "RAM:24bit.ilbm";
  99. UBYTE *rgbnames[]={"R0","R1","R2","R3","R4","R5","R6","R7",
  100.            "G0","G1","G2","G3","G4","G5","G6","G7",
  101.            "B0","B1","B2","B3","B4","B5","B6","B7" };
  102.  
  103. UBYTE *endtext1 = "Displayed 24 planes, 4 at a time.";
  104. UBYTE *endtext2 = "Press mousebutton or key to exit.";
  105.  
  106. /* 
  107.  * MAIN 
  108.  */
  109. void main(int argc, char **argv)
  110.    {
  111.     struct RastPort *rp = NULL;
  112.     struct BitMap dummy = {0};
  113.     struct BitMap *bm = NULL, *xbm, *sbm;
  114.     LONG    error = 0L;
  115.     USHORT    width, height, depth, pwidth, pheight, pmode, extra, rgb;
  116.     ULONG     plsize;
  117.     UBYTE    *tpp;
  118.     BOOL    DoSave = TRUE;
  119.     int     k, p, s, n;
  120.  
  121.    FromWb = argc ? FALSE : TRUE;
  122.  
  123.    if((argc > 1)&&(argv[argc-1][0]=='?'))
  124.     {
  125.     printf("%s\n%s\n",Copyright,usage);
  126.         bye("",RETURN_OK);
  127.     }
  128.  
  129.    if(argc==2)
  130.     {
  131.     ilbmname = argv[1];
  132.     DoSave = FALSE;
  133.     }
  134.  
  135.    /* Open Libraries */
  136.  
  137.    if(!(IntuitionBase = OpenLibrary("intuition.library", 0)))
  138.       bye("Can't open intuition library.\n",RETURN_WARN);
  139.       
  140.    if(!(GfxBase = OpenLibrary("graphics.library",0)))
  141.       bye("Can't open graphics library.\n",RETURN_WARN);
  142.  
  143.    if(!(IFFParseBase = OpenLibrary("iffparse.library",0)))
  144.       bye("Can't open iffparse library.\n",RETURN_WARN);
  145.  
  146.  
  147. /* 
  148.  * Alloc ILBMInfo structs
  149.  */
  150.     if(!(ilbm[0] = (struct ILBMInfo *)
  151.     AllocMem(sizeof(struct ILBMInfo),MEMF_PUBLIC|MEMF_CLEAR))) 
  152.         bye(nomem,RETURN_FAIL);
  153.     if(!(ilbm[1] = (struct ILBMInfo *)
  154.     AllocMem(sizeof(struct ILBMInfo),MEMF_PUBLIC|MEMF_CLEAR))) 
  155.         bye(nomem,RETURN_FAIL);
  156.  
  157. /*
  158.  * Here we set up our ILBMInfo fields for our
  159.  * application.
  160.  * Above we have defined the propery and collection chunks
  161.  * we are interested in (some required like BMHD)
  162.  */
  163.  
  164.     ilbm[0]->ParseInfo.propchks        = ilbmprops;
  165.     ilbm[0]->ParseInfo.collectchks    = ilbmcollects;
  166.     ilbm[0]->ParseInfo.stopchks        = ilbmstops;
  167.  
  168.     ilbm[0]->windef    = &mynw;
  169.  
  170.     *ilbm[1] = *ilbm[0];
  171.  
  172.  
  173. /* 
  174.  * Alloc IFF handles for frame
  175.  */
  176.     if(!(ilbm[0]->ParseInfo.iff = AllocIFF())) bye(noiffh,RETURN_FAIL);
  177.     if(!(ilbm[1]->ParseInfo.iff = AllocIFF())) bye(noiffh,RETURN_FAIL);
  178.  
  179.  
  180. /* for saving our demo 24-bit ILBM */
  181.  
  182.     width  = 320;
  183.     height = 200;
  184.     depth  = 24;
  185.  
  186.     /* Page width, height, and mode for saved ILBM */
  187.     pwidth  = width  < 320 ? 320 : width;
  188.     pheight = height < 200 ? 200 : height;
  189.     pmode   = pwidth >= 640  ? HIRES : 0L;
  190.     pmode  |= pheight >= 400 ? LACE  : 0L;
  191.  
  192.     plsize = RASSIZE(width,height);
  193.  
  194.     if(!DoSave)    goto nosave;
  195.  
  196.     /*
  197.      * Allocate Bitmap and planes
  198.      */
  199.     extra = depth > 8 ? depth - 8 : 0;
  200.     if(ilbm[0]->brbitmap = AllocMem(sizeof(struct BitMap) + (extra<<2),
  201.                 MEMF_CLEAR))
  202.     {
  203.     bm = ilbm[0]->brbitmap;
  204.         InitBitMap(bm,depth,width,height);
  205.         for(k=0, error=0; k<depth && (!error); k++) 
  206.             {
  207.             if(!(bm->Planes[k] = AllocRaster(width,height)))
  208.             error = IFFERR_NOMEM;
  209.             if(! error)
  210.         {
  211.                 BltClear(bm->Planes[k], RASSIZE(width,height),0);
  212.                 }
  213.         }
  214.  
  215.     if(!error)
  216.         {
  217.         if(!(rp = AllocMem(sizeof(struct RastPort),MEMF_CLEAR)))
  218.         error = IFFERR_NOMEM;
  219.         else
  220.         {
  221.         InitRastPort(rp);
  222.         rp->BitMap = bm;
  223.         rp->Mask = 0x01;    /* we'll render 1 plane at a time */
  224.         SetAPen(rp,1);
  225.         SetDrMd(rp,JAM1);
  226.         }
  227.         }
  228.  
  229.     if(!error)
  230.         {
  231.         /* Put something recognizable in the planes.
  232.          * Our bitmap is not part of a screen or viewport
  233.          * so we can fiddle with the pointers and depth
  234.          */
  235.         tpp = bm->Planes[0];    /* save first plane pointer */
  236.         bm->Depth = 1;
  237.         for(k=0; k<depth; k++)    /* swap in planeptrs 1 at a time */
  238.         {
  239.         bm->Planes[0] = bm->Planes[k];
  240.         Move(rp,k * 10, (k * 8) + 8);    /* render rgb bitname text */
  241.         Text(rp, rgbnames[k], 2);
  242.         }
  243.         bm->Depth = depth;        /* restore depth */
  244.         bm->Planes[0] = tpp;    /* and first pointer */
  245.  
  246.         /* Save the 24-bit ILBM */
  247.         printf("Saving %s\n",ilbmname);
  248.         error = saveilbm(ilbm[0], ilbm[0]->brbitmap, pmode,
  249.                 width,  height, pwidth, pheight,
  250.                 NULL, 0, 0,    /* colortable */
  251.         mskNone, 0,    /* masking, transparent */
  252.         NULL, NULL,     /* chunklists */
  253.         ilbmname);
  254.         }
  255.  
  256.     /* Free our bitmap */
  257.         for(k=0; k<depth; k++) 
  258.             {
  259.             if(ilbm[0]->brbitmap->Planes[k])
  260.             FreeRaster(ilbm[0]->brbitmap->Planes[k],width,height);
  261.         }
  262.     FreeMem(ilbm[0]->brbitmap, sizeof(struct BitMap) + (extra << 2));
  263.     ilbm[0]->brbitmap = NULL;
  264.     if(rp)    FreeMem(rp, sizeof(struct RastPort));
  265.     }
  266.  
  267.     if(error)
  268.     {
  269.     printf("%s\n",IFFerr(error));
  270.     bye(" ", RETURN_FAIL);
  271.     }
  272.  
  273. nosave:
  274.  
  275. /* Normally you would use showilbm() to open an appropriate acreen
  276.  * and display an ILBM in it.  However, this is a 24-bit ILBM
  277.  * so we will load it as a brush (bitmap).
  278.  * Here we are demonstrating
  279.  *  - first querying an ILBM to get its BMHD and CAMG (real or computed)
  280.  *  - then opening our own display
  281.  *  - then loading the 24-bit ILBM as a brush (bitmap) and displaying
  282.  *    it 4 planes at a time in our 4-plane screen.
  283.  */
  284.  
  285.     printf("Attempting to load %s as a bitmap and display 4 planes at a time\n",
  286.         ilbmname);
  287.  
  288.     if(!(error = queryilbm(ilbm[0],ilbmname)))
  289.     {
  290.     D(bug("24bitDemo: after query, this ILBM is %ld x %ld x %ld,modeid=$%lx\n",
  291.           ilbm[0]->Bmhd.w, ilbm[0]->Bmhd.h, ilbm[0]->Bmhd.nPlanes, ilbm[0]->camg));
  292.  
  293.     /* Note - you could use your own routines to open your
  294.      * display, but if so, you must initialize ilbm[0]->scr,
  295.      * ilbm[0]->win, ilbm[0]->wrp, ilbm[0]->srp, and ilbm[0]->vp for your
  296.          * display.  Here we will use opendisplay() which will initialize
  297.      * those fields.
  298.      */
  299.  
  300.     if(!(opendisplay(ilbm[0],
  301.             MAX(ilbm[0]->Bmhd.pageWidth, ilbm[0]->Bmhd.w),
  302.             MAX(ilbm[0]->Bmhd.pageHeight,ilbm[0]->Bmhd.h),
  303.             MIN(ilbm[0]->Bmhd.nPlanes, SCRPLANES),
  304.             ilbm[0]->camg)))
  305.         {
  306.         printf("Failed to open display\n");
  307.         }
  308.     else
  309.         {
  310.         D(bug("24bitDemo: opendisplay (%ld planes) successful\n",SCRPLANES));
  311.  
  312.         scr = ilbm[0]->scr;
  313.         win = ilbm[0]->win;
  314.         wrp = ilbm[0]->wrp;
  315.         vp  = ilbm[0]->vp;
  316.  
  317.         if(!(error = loadbrush(ilbm[1], ilbmname)))
  318.         {
  319.             D(bug("24bitDemo: loadbrush successful\n"));
  320.  
  321.         /* Note - we don't need to examine or copy any
  322.          * chunks from the file, so we will close file now
  323.          */
  324.         closeifile(ilbm[0]);
  325.         ScreenToFront(ilbm[0]->scr);
  326.  
  327.         xbm = &dummy;        /* spare bitmap */
  328.         sbm = &scr->BitMap;    /* screen's bitmap */
  329.         bm = ilbm[1]->brbitmap;    /* the 24-plane bitmap */
  330.         depth = bm->Depth;
  331.  
  332.             InitBitMap(xbm,SCRPLANES,scr->Width,scr->Height);
  333.  
  334.         /* Show the 24 planes */
  335.         for(p=0; p<depth; p+=SCRPLANES)    /* 4 at a time */
  336.             {
  337.             SetRast(&scr->RastPort, 0);
  338.             for(s=0; s<SCRPLANES; s++)
  339.             {
  340.             if((p+s) < depth) xbm->Planes[s] = bm->Planes[p+s];
  341.             else            xbm->Planes[s] = NULL, xbm->Depth--;
  342.             }
  343.             /* Blit planes to the screen */
  344.             BltBitMap(xbm, 0, 0,
  345.                   sbm, 0, 0,
  346.                   scr->Width, scr->Height,
  347.                   0xC0, 0x0F, NULL);
  348.  
  349.             /* Emulate 8-bit color with 4-bit per gun colors
  350.              * by using each rgb value twice
  351.              */
  352.             for(n=0, rgb=cstarts[p /SCRPLANES]; n < 16; n++)
  353.             {
  354.             if(!n)    colortable[n] = 0xFFF;
  355.             else    colortable[n] = rgb;
  356.             /* bump gun for every 2 planes since
  357.              * we only have 8 bits per gun
  358.              */
  359.             if(n & 1)  rgb += coffs[ p / SCRPLANES];
  360.             }
  361.             LoadRGB4(vp, colortable, 16);
  362.             Delay(50);
  363.             }
  364.  
  365.         SetRast(&scr->RastPort, 0);
  366.  
  367.         SetAPen(wrp, 1);
  368.         Move(wrp, 24, 80);
  369.         Text(wrp, endtext1, strlen(endtext1));
  370.         Move(wrp, 24, 120);
  371.         Text(wrp, endtext2, strlen(endtext2));
  372.  
  373.         Wait(1<<win->UserPort->mp_SigBit);
  374.         unloadbrush(ilbm[1]);    /* deallocs colors, closeifile if needed */
  375.         }
  376.         closedisplay(ilbm[0]);
  377.         printf("Done\n");
  378.          }
  379.           }
  380.  
  381.     if(error)    printf("%s\n",IFFerr(error));
  382.  
  383.     cleanup();
  384.     exit(RETURN_OK);
  385.     }
  386.  
  387.  
  388.  
  389. void bye(UBYTE *s,int error)
  390.    {
  391.    if((*s)&&(!FromWb)) printf("%s\n",s);
  392.    cleanup();
  393.    exit(error);
  394.    }
  395.  
  396.  
  397. void cleanup()
  398.    {
  399.    if(ilbm[0])
  400.     {
  401.     if(ilbm[0]->ParseInfo.iff)     FreeIFF(ilbm[0]->ParseInfo.iff);
  402.     FreeMem(ilbm[0],sizeof(struct ILBMInfo));
  403.     }
  404.    if(ilbm[1])
  405.     {
  406.     if(ilbm[1]->ParseInfo.iff)     FreeIFF(ilbm[1]->ParseInfo.iff);
  407.     FreeMem(ilbm[1],sizeof(struct ILBMInfo));
  408.     }
  409.  
  410.    if(GfxBase)              CloseLibrary(GfxBase);
  411.    if(IntuitionBase)     CloseLibrary(IntuitionBase);
  412.    if(IFFParseBase)      CloseLibrary(IFFParseBase);
  413.    }
  414.