/*****************************\
*   >>> IMAGEMAKER V1.2 <<<   *
*-----------------------------*
*    (C) 1988 by KICKSTART    *
*  written by Holger Schemel  *
\*****************************/

#include <stdio.h>
#include <exec/types.h>
#include <exec/memory.h>
extern void *AllocMem();

struct BMHD
{
   UWORD Width,Height;
   WORD  LeftEdge,TopEdge;
   UBYTE Depth;
   UBYTE Mask;
   UBYTE Compression;
   UBYTE pad1;
   UWORD transparentColor;
   UBYTE xAspect,yAspect;
   WORD  pageWidth,pageHeight;
} BMHeader;

struct Image
{
   SHORT LeftEdge,TopEdge;
   SHORT Width,Height,Depth;
   SHORT *ImageData;
   UBYTE PlanePick,PlaneOnOff;
   struct Image *NextImage;
} Brush;

BYTE  imagename[40],imagefile[40];
UBYTE *imagedata=0;
UWORD *data;
LONG i,j;
ULONG mem;
FILE  *fp;

main(argc,argv)
SHORT argc;
BYTE *argv[];
{
   SHORT x,y,z;
   BOOL sprite = FALSE;

   if (argc<2 || argc>3 || *argv[1]=='?')
      exit(puts("Usage: ImageMaker <brushname> [-s (for sprite; default: image)]"));

   if (argc>2) for(i=1;i<argc;i++) if (!strcmp(argv[i],"-s")) sprite=TRUE;
   if (!strcmp(argv[1],"-s")) argv[1]=argv[2];

   for(i=strlen(argv[1])-1;i>=0;i--)
      if (*(argv[1]+i)==':' || *(argv[1]+i)=='/') break;
   sprintf(imagename,"%s",argv[1]+i+1);

   printf("Loading Brush %s...",argv[1]);
   LoadBrush(argv[1]);  /* Brush laden */
   Brush.ImageData = (SHORT *)imagedata;
   Brush.Width = BMHeader.Width;
   Brush.Height = BMHeader.Height;
   Brush.Depth = BMHeader.Depth;
   Brush.PlanePick = (1<<BMHeader.Depth)-1;

   data = (UWORD *)imagedata;
   x = Brush.Width/16+(Brush.Width%16 > 0);
   y = Brush.Height;
   z = Brush.Depth;

   if (sprite && (Brush.Depth!=2 || Brush.Width!=16))
   {
      puts("\nNot a sprite-sized brush! (Width<>16 or Depth<>2 !)");
      FreeMem(imagedata,mem);
      exit();
   }

   printf("\nConverting to file %s.c ",&imagename[0]);
   if (sprite) puts("(sprite-structure)");
   else        puts("(image-structure)");


   sprintf(imagefile,"%s.c",argv[1]);
   if(!(fp = fopen(imagefile,"w")))
      exit(printf("Can't open file '%s' for write.\n",argv[2]));

   if (sprite)
   {
      fprintf(fp,"struct SpriteImage *%s_data =\n{\n   0,0,\n",imagename);
      for(j=0;j<y;j++) fprintf(fp,"   0x%04x, 0x%04x,\n",data[j],data[y+j]);
      fprintf(fp,"   0,0\n};\n\n");
      fprintf(fp,"struct SimpleSprite %s =\n{\n",imagename);
      fprintf(fp,"   %s_data,\n   %d,\n   0,0,\n",imagename,y);
      fprintf(fp,"   2\n};\n");
   }
   else
   {
      fprintf(fp,"USHORT %s_data[] =\n{\n",imagename);
      for(j=0;j<z;j++)
      {
         for(i=0;i<x*y;i++)
         {
            fprintf(fp,"   0x%04x,",data[i+j*x*y]);
            if (i+1<x*y) fprintf(fp," 0x%04x,",data[++i+j*x*y]);
            fprintf(fp,"\n");
         }
         if (j+1<z) fprintf(fp,"\n");
      }
      fprintf(fp,"};\n\n");
      fprintf(fp,"struct Image %s =\n{\n",imagename);
      fprintf(fp,"   0,0,\n");
      fprintf(fp,"   %d,%d,%d,\n",Brush.Width,Brush.Height,Brush.Depth);
      fprintf(fp,"   &%s_data[0],\n",imagename);
      fprintf(fp,"   %d,0,\n   NULL\n};\n",Brush.PlanePick);
   }
   fclose(fp);
   FreeMem(imagedata,mem);    /* Freigeben des reservierten Speichers */
}

LoadBrush(name)   /* IFF-Laderoutine */
char *name;
{
   BYTE  c2;
   UBYTE *ptr;
   SHORT c,ct,ct2;
   UWORD BWidth,BHeight,BDepth;

   if (!(fp = fopen(name,"r")))
      exit(printf("Can't read '%s'.\n",name));

   if (!SearchHeader(fp,"ILBMBMHD"))   /* IFF-File? */
      exit(fclose(fp),printf("Not an IFF-File.\n"));

   ptr = (UBYTE *)&BMHeader;
   for(i=0;i<20;i++) *(ptr++)=getc(fp);
   BWidth = ((BMHeader.Width+15)/16)*2;

   if (!(imagedata = AllocMem(mem=(ULONG) /* Speicher reservieren */
      (BWidth*BMHeader.Height*BMHeader.Depth),MEMF_CHIP)))
         exit(fclose(fp),printf("Not enough CHIP-RAM!\n"));

   if (!SearchHeader(fp,"BODY")) /* Grafikdatenbeginn suchen */
      exit(fclose(fp),FreeMem(imagedata,mem),printf("Not an IFF-File.\n"));

   for(BHeight=0;BHeight<BMHeader.Height;BHeight++)  /* Zeilen */
   {
      for(BDepth=0;BDepth<BMHeader.Depth;BDepth++)  /* Bitplanes */
      {
         ptr = imagedata+BDepth*BWidth*BMHeader.Height+BHeight*BWidth;
         ct2=0;
         if (!BMHeader.Compression) /* Brushdaten gepackt? */
            while(ct2++<BWidth) *ptr++=getc(fp);
         else                       /* wenn ja: Entpacken */
         {
            while(ct2<BWidth)
            {
               c=getc(fp);
               if (c<=128)
               {
                  ct=c+1;
                  for(i=0;i<ct;i++) { *ptr++=getc(fp); ct2++; }
               }
               else
               {
                  ct=256-c+1;
                  c2=getc(fp);
                  for(i=0;i<ct;i++) { *ptr++=c2; ct2++; }
               }
            }
         }
      }
   }
   fclose(fp);
}

SearchHeader(fp,iffheader)   /* Nach IFF-Header suchen */
FILE  *fp;
UBYTE *iffheader;
{
   SHORT c;
   UBYTE *cp=iffheader;

   while((c=getc(fp))!=EOF)
   {
      if (c==*cp) { cp++; if (!*cp) break; }
      else cp=iffheader;
   }
   if (c==EOF) return(0);
   else { for(i=0;i<4;i++) getc(fp); return(1); }
}

