/*
 * This is demo code to show how to call the renderhame.library
 * for both HAME and REG mode rendering. Save of the resulting IFF
 * image is also provided in the library, and demonstrated here.
 *
 * if 'DOHAM' is defined, then this code will generate a HAME mode output.
 * otherwise, it generates REWG mode output. If you search thru the code
 * to find these two variables, you'll see how simple the render options
 * are.
 */

#define DOHAM 1

#include <intuition/intuition.h>
#include <exec/types.h>
#include <exec/execbase.h>
#include <graphics/text.h>

#include <proto/exec.h>
#include <proto/graphics.h>

#include "hame_pragmas.h"
#include "HameStruct.h"
#include "HameProtos.h"
#include "HameRev.h"

#include "rend_pragmas.h"
#include "RendStruct.h"
#include "RendProtos.h"
#include "RendRev.h"

#include <string.h>
#include <exec/memory.h>
#include <exec/tasks.h>

#include <graphics/view.h>
#include <graphics/gfx.h>
#include <graphics/rastport.h>

#include <proto/intuition.h>
#include <stdio.h>

struct Library *HameBase;
struct Library *RenderBase;
struct HamePort *HamePort;
struct rgb_image rgb;

extern struct Screen *OpenScreen();
extern struct Window *OpenWindow();

extern struct ExecBase *SysBase;
struct IntuitionBase *IntuitionBase;
struct GfxBase       *GfxBase;

struct Screen        *screen;
struct Window        *window;

FILE *rf, *gf, *bf;
UBYTE  *rptr, *gptr, *bptr;
long ptsize;

#define WIDTH 640
#define HEIGHT 200

struct NewScreen my_screen =
  {
    0, 0, WIDTH, HEIGHT,
    4,
    0, 1,
    HIRES,
    CUSTOMSCREEN,
    (struct TextAttr *) NULL,
    NULL,
    NULL, NULL
  };

struct NewWindow my_window =
  {
    0, 0, WIDTH, HEIGHT,
    (UBYTE) 0, (UBYTE) 1,
    MOUSEBUTTONS
       | INTUITICKS,
    SMART_REFRESH
       | BORDERLESS
       | BACKDROP
       | ACTIVATE
       | NOCAREREFRESH
       | REPORTMOUSE,
    NULL, NULL,
    NULL,
    NULL, NULL,
    0, 0, 0, 0,
    CUSTOMSCREEN
  };


/*
  Clean up and exit
*/
void CloseStuff()
  {
      if (rf)                 fclose(rf);
      if (gf)                 fclose(gf);
      if (bf)                 fclose(bf);

      if (rptr)               FreeMem(rptr, ptsize);
      if (gptr)               FreeMem(gptr, ptsize);
      if (bptr)               FreeMem(bptr, ptsize);

      if (window)             CloseWindow(window);
      if (screen)             CloseScreen(screen);
      if (HamePort)           HAME_Dispose(HamePort);
      if (RenderBase)         CloseLibrary(RenderBase);
      if (HameBase)           CloseLibrary(HameBase);
      if (GfxBase)            CloseLibrary(GfxBase);
      if (IntuitionBase)      CloseLibrary(IntuitionBase);

      exit(0);
  }


/*
  Draw a vertical column of pixels at the left margin to prevent hame from
  turning off.
*/
void DrawLeftMargin()
  {
  int i;
    HAME_SetAPen(HamePort, 1);
    for ( i=0; i<200; i++ )
      {
        HAME_WritePixel( HamePort, 0, i);
      }
  }

void palette1()
  {
  int i, r;
    HAME_SetRGB8(HamePort, 0, 0, 0, 0);
    HAME_SetRGB8(HamePort, 1, 0, 0, 0);
    for ( i = 2; i < 64; i++ )
      {
        r = i << 2;
        HAME_SetRGB8(HamePort, i, r, r, r);
      }
  }

/*
 * Main routine
 */
int main(argc, argv)
  int argc;
  char *argv[];
  {
  ULONG  msg_class;
  USHORT msg_code;
  int    finished=0;
  struct IntuiMessage *message;
  struct Gadget *gadget;


    if (argc < 2)
      {
        printf("USAGE:\n  %s outfile\n", argv[0] );
        exit(0);
      }

    if ((IntuitionBase = (struct IntuitionBase *)
         OpenLibrary("intuition.library",33L))==NULL)
      {
        printf("No intuition.library!  GET SOME ROMS!\n");
        CloseStuff();
      }
  
    if ((GfxBase = (struct GfxBase *)
         OpenLibrary("graphics.library" , 0L))==NULL)
      {
        printf("No graphics.library!  GET SOME ROMS!\n");
        CloseStuff();
      }
  
    /* Open the hame library */
    if ((HameBase = (struct Library *) 
         OpenLibrary("hame.library", HAMELIB_VERSION)) == NULL)
      {
        printf("No hame.library!\n");
        CloseStuff();
      }
  
    /* Open the hame library */
    if ((RenderBase = (struct Library *) 
         OpenLibrary(RENDER_LIBNAME, RENDER_LIBVERSION)) == NULL)
      {
        printf("No %s!\n", RENDER_LIBNAME);
        CloseStuff();
      }
  
    /* Get a screen to play with */
    if ((screen = OpenScreen(&my_screen))     ==NULL)
      {
        printf("Couldn't open Screen!\n");
        CloseStuff();
      }
  
    my_window.Screen = screen;
  
    /* Get a window to play with */
    if ((window = OpenWindow(&my_window)) == NULL)
      {
        printf("Couldn't open Window!\n");
        CloseStuff();
      }
  
    /* turn off the title bar */
    ShowTitle(screen, 0L);
  
    /* Tell the library where to put pixels */
#ifdef DOHAM
    /* This is hame mode */
    if ((HamePort = HAME_Init(screen, 320, 200, 10, 1, 0, 1, 199)) == NULL)
      {
        printf("Couldn't get HamePort!\n");
        CloseStuff();
      }
#else
    /* this is spectral mode (256 REG) */
    if ((HamePort = HAME_Init(screen, 320, 200, 10, 0, 0, 4, 196)) == NULL)
      {
        printf("Couldn't get HamePort!\n");
        CloseStuff();
      }
#endif

    /* Set the pallette */
    palette1();
  
    /* Keep hame from turning off because of screen wide color 0 */
    DrawLeftMargin();
  
    /* 8 bit buffer is 160 x 100 */
    ptsize = 160 * 100;
  
    /* Get fast memory */
    rptr = AllocMem(ptsize, 0);
    gptr = AllocMem(ptsize, 0);
    bptr = AllocMem(ptsize, 0);
  
    if ( !rptr || ! gptr || !bptr )
      {
        printf("Can't get enough memory for RGB buffers\n");
        CloseStuff();
      }
  
    /* load the buffers */
    rf = fopen( "pic160x100.red", "r" );
    gf = fopen( "pic160x100.grn", "r" );
    bf = fopen( "pic160x100.blu", "r" );
  
    if ( !rf || ! gf || !bf )
      {
        printf("RAW RGB files missing..\n   pic160x100.red, pic160x100.grn, pic160x100.blu\n");
        CloseStuff();
      }
  
    if (fread(rptr, ptsize, 1, rf) != 1 )
      {
        printf("pic160x100.red truncated!  Aborting\n");
        CloseStuff();
      }
    if (fread(gptr, ptsize, 1, gf) != 1 )
      {
        printf("pic160x100.grn truncated!  Aborting\n");
        CloseStuff();
      }
    if (fread(bptr, ptsize, 1, bf) != 1 )
      {
        printf("pic160x100.blu truncated!  Aborting\n");
        CloseStuff();
      }
  
    rgb.rbu = rptr;
    rgb.gbu = gptr;
    rgb.bbu = bptr;
  
    rgb.xsize = 160;
    rgb.ysize = 100;
  
#ifdef DOHAM
    /* HAM mode */
    HAME_RenderHam(HamePort, &rgb, 0, 0, 160, 100, 1);
#else
    /* REG mode */
    HAME_RenderReg(HamePort, &rgb, 0, 0, 160, 100, 1, 250);
#endif

    if (!HAME_SaveIFF( HamePort, argv[1] ))
      {
        printf("IFF save unsuccessful!\n");
      }
  
    /* Wait for mouse press */
    while(!finished)
      {
        /* flush all msgs in the port */
        
        /* now wait for a NEW message. */
        message       = (struct IntuiMessage *) WaitPort(window->UserPort);
        while(message = (struct IntuiMessage *) GetMsg(window->UserPort))
          {
            msg_class = message->Class;
            msg_code = message->Code;
            gadget = (struct Gadget *) message->IAddress;
            ReplyMsg((struct Message *)message);
  
            switch( msg_class )
              {
                case MOUSEBUTTONS:
                  {
                    finished = 1;
                    break;
                  }
  
                case INTUITICKS:
                  {
                    break;
                  }
                case CLOSEWINDOW:
                  {
                    finished = 1;
                    break;
                  }
                default:
                  {
                    printf("?");
                    break;
                  }
              }
          }
      }
    while ((message = (struct IntuiMessage *)
            GetMsg( window->UserPort )) != NULL)
      {
        ReplyMsg((struct Message *)message);
      }
    CloseStuff();
  }
