/*
	Show3.c: display three IFF files in rapid succession continuously.
	Based on showiff.c by Christian A. Weber.
	Modified by Kriton Kyrimis.
*/

#include <stdio.h>
#include <string.h>
#include <exec/types.h>
#include <graphics/gfxbase.h>
#include <intuition/intuition.h>
#ifdef __SASC
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#endif
#ifdef __GNUC__
#include <inline/exec.h>
#include <inline/intuition.h>
#include <inline/graphics.h>
#endif
#include <iff.h>

struct IntuitionBase *IntuitionBase = NULL;
struct Library *IFFBase = NULL;
struct GfxBase *GfxBase = NULL;

struct NewScreen ns =
{
  0,0,0,0,0,0,0, NULL, AUTOSCROLL | CUSTOMSCREEN | SCREENQUIET, NULL,
  (STRPTR)"Show3", NULL, NULL
};

static struct TagItem ScreenTags[] = {
#define DISPIDTAG 0
  {SA_DisplayID, NULL},
  {SA_Overscan, OSCAN_VIDEO},
  {TAG_DONE, NULL}
};

struct Screen *screen[3] = {NULL, NULL, NULL};
IFFL_HANDLE ifffile = NULL;
char *fname[3] = {NULL, NULL, NULL};
int fsiz = 0;

extern int IsPAL(void);

void
Fail(char *text, int status)
{
	int i;

	if(ifffile) IFFL_CloseIFF(ifffile);
	if(screen[0]) CloseScreen(screen[0]);
	if(screen[1]) CloseScreen(screen[1]);
	if(screen[2]) CloseScreen(screen[2]);
	if (fsiz) {
	  for (i=0; i<3; i++) {
	    if (fname[i]) FreeMem(fname[i], fsiz);
	  }
	}
	if (*text) {
	  printf("%s\n",text);
	}
	if(IFFBase) {
	  if (i = IFFL_IFFError()) {
	    printf("IffError = %ld\n", i);
	  }
          CloseLibrary(IFFBase);	/* MUST ALWAYS BE CLOSED !! */
        }
	if(IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
	if(GfxBase) CloseLibrary((struct Library *)GfxBase);
	exit(status);
}

int
main(int argc, char *argv[])
{
  long count,i;
  WORD colortable[128];
  struct IFFL_BMHD *bmhd;
  long oldpri;

  if(!strcmp(argv[1],"?") || ((argc !=4) && (argc != 2))) {
    printf("Usage: %s redfile greenfile bluefile\n"
	   "       %s filename (.[rgb] will be appended)\n",
	   argv[0], argv[0]);
    exit(1);
  }
  if (argc == 4) {
    for (i=0; i<3; i++) {
      fname[i] = argv[i+1];
    }
  }else{
    fsiz = strlen(argv[1]) + 3;
    for (i=0; i<3; i++) {
      fname[i] = AllocMem(fsiz, 0L);
      if (!fname[i]) {
        Fail("Can't allocate memory", 1);
      }
      strcpy(fname[i], argv[1]);
      strcat(fname[i], ((i == 0) ? ".r" : ((i == 1) ? ".g" : ".b")));
    }
  }
  GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0L);
  if (!GfxBase) {
    Fail("Can't open graphics.library", 1);
  }
  IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0L);
  if (!IntuitionBase) {
    Fail("Can't open intuition.library", 1);
  }
  if(!(IFFBase = OpenLibrary(IFFNAME,IFFVERSION))) {
    Fail("Copy the iff.library to your LIBS: directory!", 1);
  }

  for (i=0; i<3; i++) {
    if(!(ifffile = IFFL_OpenIFF(fname[i], IFFL_MODE_READ))){
      Fail("Error opening file", 1);
    }
    if(!(bmhd = IFFL_GetBMHD(ifffile))) {
      Fail("BitMapHeader not found", 1);
    }
    ns.Width      = bmhd->w;
    ns.Height     = bmhd->h;
    ns.Depth      = bmhd->nPlanes;
    ns.ViewModes  = IFFL_GetViewModes(ifffile);

    ScreenTags[DISPIDTAG].ti_Data = ns.ViewModes;
    if (IsPAL()) {
      ScreenTags[DISPIDTAG].ti_Data |= PAL_MONITOR_ID;
    }else{
      ScreenTags[DISPIDTAG].ti_Data |= NTSC_MONITOR_ID;
    }

    if(!(screen[i] = OpenScreenTagList(&ns, ScreenTags))) {
      Fail("Can't open screen!", 1);
    }

    count = IFFL_GetColorTab(ifffile,colortable);
    if(count > 32L) count = 32L; /* Some HAM pictures have 64 colors ?! */
    LoadRGB4(&(screen[i]->ViewPort), colortable, count);

    if(!IFFL_DecodePic(ifffile, &screen[i]->BitMap)) {
      Fail("Can't decode picture", 1);
    }
    IFFL_CloseIFF(ifffile);
    ifffile = NULL;
  }
  oldpri = SetTaskPri(FindTask(0L), 19L); /* Run at high priority to reduce */
  for(;;) {				  /* flicker! */
    volatile UBYTE *click = (UBYTE *)0xbfe001;
    if (!(*click & 64)) break;	/* I know it's a hack */
    ScreenToFront(screen[0]);
    if (!(*click & 64)) break;	/* I know it's a hack */
    ScreenToFront(screen[1]);
    if (!(*click & 64)) break;	/* I know it's a hack */
    ScreenToFront(screen[2]);
  }
  SetTaskPri(FindTask(0L), oldpri);
  Fail("", 0); /* Close the whole stuff */
#ifdef __SASC
  return 0;
#endif
}
