/* GetPointer © 1989 AMIGA Plus
   v1.0 Friday 14-Jul-89 11:17:20
   By Aki Rimpilainen & Arnie Cachelin */

#include <exec/exec.h>
#include <intuition/intuition.h>
#include <intuition/preferences.h>
#include <workbench/startup.h>
#include <workbench/workbench.h>
#include <libraries/dos.h>
#include <functions.h>
#include <stdio.h>

#define DEFAULTFILE  "NewSprite"  /* Default file name for pointer */

struct IntuitionBase *IntuitionBase;
struct Preferences   *PrefBuff;
struct WBStartup     *WBenchMsg=NULL;
struct IconBase      *IconBase;
struct DiskObject    *dob;
struct Image         *image;

UWORD *SpriteData, *ImageStuff;

main(argc,argv)
 int argc;
 char *argv[];
{
  struct WBArg       *arg;
  struct FileHandle  *fh;
  FILE   *fp;
  char   *c,*type,name[52],*StructName;
  BYTE   *ByteSize;
  UWORD  *IconData, *SprDatCopy,R,G,B;
  short  i,j;


  if (argc==0)  /* That means we started from Workbench! */
   {
    j=1;
    strcpy(name,DEFAULTFILE);
    while(Lock(name,ACCESS_READ)!=0); /* While name already exists... */
      {                               /* add x to root name           */
       strcpy(name,DEFAULTFILE);
       for (i=0;i<j;i++) strcat(name,"x"); /* add x 'til name is unique */
       strcat(name,".p");                  /*  end with ".p"      */
       ++j;
      }
    *type='d'; /*  We won't save C structs from WB */
   }
  else if (argc>=2)               /* Check for arguments, */
   {
    puts("\n[33mGetPointer - © 1989 AMIGA [3mPlus[0m");
    type=argv[1];
    if (argc==2) strcpy(name,"DefaultSprite");
    else strcpy(name,argv[2]);
    if (argc==4) StructName=argv[3];
    else StructName="DefSpr";  /* Default name for the */
   }                           /* sprite structure */
  else
   {
    puts("\n[33mGetPointer - © 1989 AMIGA [3mPlus[0m");
    Usage();            /* display help if no args */
   }

/* Open Some libraries...    */
  IntuitionBase = (struct IntuitionBase *)
    OpenLibrary("intuition.library",LIBRARY_VERSION);
  if (IntuitionBase==0) { Closing("Can't open intuition."); exit(0L); }

  IconBase=(struct IconBase *)
    OpenLibrary("icon.library",LIBRARY_VERSION);
  if (IconBase==0) { Closing("Can't open icon.library."); exit(0L); }

/* Allocate some memory ...    */
  PrefBuff=AllocMem((LONG)sizeof(struct Preferences),MEMF_CLEAR | MEMF_CHIP);
  if (PrefBuff==0) { Closing("Can't allocate memory."); exit(0L); }

  ImageStuff=AllocMem(64L,MEMF_CLEAR | MEMF_CHIP);
  if (ImageStuff==0) { Closing("Can't allocate memory."); exit(0L); }

  GetPrefs(PrefBuff,((LONG)sizeof(struct Preferences)));
  SpriteData=(UWORD *)PrefBuff->PointerMatrix; /* Find data for pointer */

  if ((*type=='d') || (*type=='D')) /* Then we're saving the data block...*/
   {
    if (!WBenchMsg)
     {
      AddExtension(name,".p");
      printf("Saving %s as raw data...\n\n",name);
     } /* saving sprite data using dos.library commands rather than C std */
       /* this allows us to write the whole block w/ one command */
    fh=Open(name,MODE_NEWFILE);
    if (fh==0) { Closing("Can't open output file."); exit(0L); }
    Write(fh,SpriteData,80L);
    Close(fh);

    dob=GetDiskObject("DefaultIcon");      /* get Icon "DefaultIcon.info" */
    if(dob==0)
      {
        Closing("Can't find DefaultIcon.info; no icon created.");
        exit(0L);
      }
    image=(struct Image *)dob->do_Gadget.GadgetRender;
    image->ImageData=ImageStuff;

    for (j=2;j<4;j++)
     {
      SprDatCopy=SpriteData+j;         /* convert bitplanes into */
      for (i=0;i<16;i++)               /* image format... */
       {
        *ImageStuff++=*SprDatCopy;
        SprDatCopy+=2;
       }
     }
    ImageStuff=image->ImageData;
    PutDiskObject(name,dob);           /* save icon as name.info */
    if (!WBenchMsg)
      printf("%s Saved.\n",name);
   }
  else if ((*type=='c') || (*type=='C'))
   {
    AddExtension(name,".h");
    printf("Saving a C-language structure %s...\n\n",name);

    if (!(fp=fopen(name,"w")))    /* Saving sprite structure using */
     {                            /* C standard I/O functions this time.*/
      Closing("Can't open output file.");
      exit(0L);
     }
    fputs("/* These SimpleSprite and ColorTable data structures \n",fp);
    fputs("   were produced by AMIGA Plus' GetPointer program. */\n\n",fp);
    fprintf(fp,"UWORD %s[] = \n",StructName);
    fputs("{\n",fp);
    for (i=0;i<35;i++)
     {
      fprintf(fp," 0x%04x,",SpriteData[i]);           /* value           */
      if ((i+1)%2==0) fprintf(fp,"\n");          /* newline         */
     }
    fputs(" 0x0000\n",fp);
    fputs("};\n\n\n",fp);

    fputs("   /* Use the following colortable to define  */\n",fp);
    fputs("   /* your virtual sprite colors.                     */\n\n",fp);
    fprintf(fp,"UWORD %s_Col[] = \n",StructName);
    fputs("{\n",fp);
    fputs(" 0x0000",fp);
    for (i=37;i<40;i++) fprintf(fp,", 0x%04x",SpriteData[i]);
    fputs("\n};\n\n",fp);

    fputs("   /* Use the following array to call SetRGB4 */\n",fp);
    fputs("   /* to change your pointer color.                   */\n\n",fp);
    for (i=0;i<3;i++)
     {
      ByteSize=(BYTE *) &SpriteData[37+i];
      R=(*ByteSize)&0x0f;                        /* get the four red bits */
      ++ByteSize;
      G=((*ByteSize)&0xf0)>>4;                   /* ...green bits */
      B=(*ByteSize)&0x0f;                        /* ...blue bits  */
      fprintf(fp,"LONG %s_RGB%d[] = { %d, %d, %d };\n",StructName,i+17,R,G,B);
     }
    fputs("\n",fp);

    fputs("   /* The 'hotspot' offsets are in the two bytes between the  */\n",fp);
    fputs("   /* image and color data, 72 bytes into the 80 byte block.  */\n\n",fp);
    ByteSize=(BYTE *) &SpriteData[36]; /* use ByteSize to read BYTE not WORD */
    fprintf(fp,"LONG %s_XOff =%dL; \n",StructName,ByteSize[0]);
    fprintf(fp,"LONG %s_YOff =%dL; \n\n",StructName,ByteSize[1]);
    fprintf(fp,"/* Use %s_XOff and %s_YOff in  */\n",StructName,StructName);
    fprintf(fp,"/* SetPointer( ViewPort, &%s[0], 16L, 2L,",StructName);
    fprintf(fp," %s_XOff, %s_YOff); */\n\n",StructName,StructName);
    fclose(fp);
    printf("%s Saved.\n",name);
   }
  else Usage();
  Closing(NULL);
  exit(0L);
}

int  AddExtension(base,ext)    /* Adds the extension (like .p) to a string */
     char    *base,*ext;       /* if it is not already there  */
    {
     char    *p,*e;
     int     a,b;
     e=ext;
     a=strlen(base);
     b=strlen(ext);
     if (a<b)          /* is extension is longer than string, */
      {                 /* add it and quit */
       strcat(base,ext);
       return(1);
      }
     else
      for(p=base + a - b; *p!=0; p++)
        if (*p!=*e++)
        {
         strcat(base,ext); /* Add extension as soon as strings don't match */
         return(1);
        }
     return(0);
    }

Usage()
{
  puts("Usage: GetPointer (C|D) [filename] [structurename]");
  puts("Options:\n\tC\tSave as C-structure.");
  puts("\tD\tSave as raw data.");
  Closing(NULL);
  exit(0L);
}

Closing(mes)
char *mes;
{
  if ((!WBenchMsg)&&(mes)) puts(mes);
  if (dob) FreeDiskObject(dob);
  if (PrefBuff) FreeMem(PrefBuff,(LONG)sizeof(struct Preferences));
  if (ImageStuff) FreeMem(ImageStuff,64L);
  if (IconBase) CloseLibrary(IconBase);
  if (IntuitionBase) CloseLibrary(IntuitionBase);
}
