/* Display an IFF picture as the boot screen */

#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <intuition/screens.h>
#include <dos/dostags.h>
#include <dos/RDArgs.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/exec.h>
#include <proto/dos.h>

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "SC:Extras/IFFLib/iff.h"

/* Globals */
struct IntuitionBase *IntuitionBase = NULL;
struct GfxBase *GfxBase = NULL;
struct Library *IFFBase = NULL;
IFFL_HANDLE iff = NULL;
struct {
   ULONG blksize;
   ULONG *ctable;
} RememberColors;
BOOL OptsForceNTSC;


UBYTE *qqq_VersionString = "$VER: BootScreen 1.00 by Joseph Luk (24.12.93)";


/* Protos */
VOID OpenAll (VOID);
VOID CloseAll (int);
VOID SetupScrColors (VOID);
ULONG ExtendFrac (UBYTE);


VOID main (VOID)
{
   struct NewScreen newscr;
   struct Screen *scr;
   struct IFFL_BMHD *bmhd;
   
   SetTaskPri(FindTask(NULL),2);

   OpenAll();
   
   bmhd = IFFL_GetBMHD(iff);
   if (bmhd == NULL)
   {
      puts ("Not an IFF ILBM file.");
      CloseAll(10);
   }

   /* Set up screen parameters */
   memset(&newscr,0,sizeof(struct NewScreen));
   newscr.Type = CUSTOMSCREEN | SCREENQUIET;
   newscr.Width = bmhd->w;
   newscr.Height = bmhd->h;
   newscr.Depth = bmhd->nPlanes;
   newscr.ViewModes = IFFL_GetViewModes(iff);
   
   SetupScrColors();
   
   scr = OpenScreenTags (&newscr,
                         SA_DisplayID, (OptsForceNTSC ? NTSC_MONITOR_ID : 0)| newscr.ViewModes,
                         SA_Colors32, RememberColors.ctable,
                         TAG_DONE);
   if (scr == NULL) {
      puts ("Can't open screen!");
      CloseAll(10); }

   
   /* And display the picture!! */
   if ( !IFFL_DecodePic (iff, &scr->BitMap) )
   {
      puts ("Error displaying picture.");
      CloseAll(5);
   }
   

   /* Go into a loop waiting for our screen to be shoved to the back */
   SetTaskPri(FindTask(NULL),-1);
   while (IntuitionBase->FirstScreen == scr) { Delay(50); }
   
   CloseScreen (scr);
   
   CloseAll(0);
}


VOID OpenAll (VOID)
{
   UBYTE *ArgTemplate = "IFFPICTURE/A,FORCENTSC/S";
   struct RDArgs *ArgsStruct;
   LONG Args[2];

   IntuitionBase = (struct IntuitionBase *)OpenLibrary ("intuition.library",39L);
   if (IntuitionBase == NULL)
   {
      puts ("You must have OS Version 39 or better (Release 3.0) to use this program.");
      CloseAll(20);
   }
   GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",39L);
   
   IFFBase = OpenLibrary (IFFNAME,IFFVERSION);
   if (IFFBase == NULL)
   {
      printf ("You must have Christian A. Weber's iff.library version %ld or better to use\nthis program.\n",IFFVERSION);
      CloseAll(20);
   }
   
   /* Get arguments, open file */
   Args[0] = NULL;
   Args[1] = FALSE;
   ArgsStruct = ReadArgs(ArgTemplate,&Args[0],NULL);
   if (Args[0] == NULL)
   {
      puts ("Required argument missing.");
      FreeArgs(ArgsStruct);
      CloseAll(20);
   }
   
   iff = IFFL_OpenIFF ((UBYTE *)Args[0], IFFL_MODE_READ);
   if (iff == NULL)
   {
      puts ("Can't open IFF file.");
      FreeArgs(ArgsStruct);
      CloseAll(10);
   }
   
   OptsForceNTSC = Args[1];
   
   FreeArgs(ArgsStruct);
   
   
   /* Misc stuff */
   RememberColors.ctable = NULL;
   
}

VOID CloseAll (rc)
int rc;
{
   if (RememberColors.ctable) FreeMem(RememberColors.ctable,RememberColors.blksize);
   
   if (iff) IFFL_CloseIFF(iff);

   if (IFFBase) CloseLibrary (IFFBase);
   if (GfxBase) CloseLibrary ((struct Library *)GfxBase);
   if (IntuitionBase) CloseLibrary ((struct Library *)IntuitionBase);
   
   exit(rc);
}

VOID SetupScrColors (VOID)
{
   APTR CMAPPtr;
   ULONG numregs;
   UWORD c;
   
   CMAPPtr = IFFL_FindChunk(iff, ID_CMAP);
   if (CMAPPtr == NULL) return;   

   numregs = *( ((ULONG *)CMAPPtr) + 1 );
      /* Number of color registers defined in CMAP chunk, (numcolors * 3) */
   
   /* Block size = (array of ULONGs) number of registers + first control entry + terminating entry */
   RememberColors.blksize = sizeof(ULONG) * (numregs + 2);
   RememberColors.ctable = AllocMem(RememberColors.blksize,MEMF_CLEAR);

   (RememberColors.ctable)[0] = (numregs/3)<<16;

   /* Fill in the color values! */   
   for (c=1; c<=numregs; c++)
      (RememberColors.ctable)[c] = ExtendFrac ( *( ((UBYTE *)CMAPPtr)+7+c ) );
      
}

ULONG ExtendFrac (input)
UBYTE input;
{
   ULONG retval;
   UBYTE *trickptr = (UBYTE *)&retval;
   
   trickptr[0] = input;
   trickptr[1] = input;
   trickptr[2] = input;
   trickptr[3] = input;
   
   return (retval);
}
