/* Screen display routines              */
/* written by Günther Röhrich           */
/* this source is Public Domain         */

/* this works only with OS 3.0 or higher */


/* last change: 16-Nov-1994 */
/* (small changes for PhotoCDAGA) */

#define INTUI_V36_NAMES_ONLY

#include <exec/types.h>
#include <intuition/intuition.h>
#include <intuition/screens.h>
#include <graphics/modeid.h>


#ifndef __GNUC__
#include <pragmas/intuition_pragmas.h>
#include <pragmas/graphics_pragmas.h>
#include <pragmas/exec_pragmas.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <clib/exec_protos.h>
#else
#include <inline/graphics.h>  
#include <inline/intuition.h> 
#include <inline/exec.h>
#endif

#define HAM8 1


struct IntuitionBase *IntuitionBase = NULL;
struct GfxBase *GfxBase = NULL;
extern int VGAenable; /* indicates if user wants to have VGA mode */
extern int SUPER72enable; /* indicates if user wants to have SUPER72 mode */
static void error_exit(const char *msgtext);
struct Screen *my_screen = NULL;
struct Window *my_window = NULL;
struct RastPort temprp; /* a copy of the screen's RastPort */
int Drow = 0; 



void CloseDisplay(void);

/* Initialize the display, colors will be set later */

int InitDisplay(int cols, int rows, ULONG Mode, int NumPlanes)
{
  ULONG Depth, DisplayID;
  ULONG NoSUPER72;

  if(!(IntuitionBase = OpenLibrary((UBYTE *)"intuition.library", 39)))
   error_exit("Can't open intuition.library V39 or higher");

  if(!(GfxBase = OpenLibrary((UBYTE *)"graphics.library",39)))
   error_exit("Can't open graphics.library V39 or higher");

  
  /* Calculate a DisplayID */
  /* this should be done better... */

  /* check if SUPER72 mode is available */

  NoSUPER72 = ModeNotAvailable(SUPER72_MONITOR_ID | SUPERHAMLACE_KEY);


  if(VGAenable)
  {
    if(Mode == HAM8)
    {
      if(cols > 780 && !NoSUPER72 && SUPER72enable) DisplayID = SUPER72_MONITOR_ID | SUPERHAMLACE_KEY;
      else
      if(cols > 384 || rows > 384)
        DisplayID = VGAPRODUCTHAM_KEY;
      else
        DisplayID = VGALORESHAMDBL_KEY;
    }
    else
    {
      if(cols > 780 && !NoSUPER72 && SUPER72enable) DisplayID = SUPER72_MONITOR_ID | SUPERLACE_KEY;
      else
      if(cols > 384 || rows >384) 
        DisplayID = VGAPRODUCT_KEY;
      else
        DisplayID = VGALORESDBL_KEY;        
    }
  }
  else
  {  
    if(Mode == HAM8)
    {
      if(cols > 384 || rows > 384)
        DisplayID = HIRESHAMLACE_KEY;
      else
        DisplayID = HAM_KEY;
    }
    else
    {
      if(cols > 384 || rows >384) 
        DisplayID = HIRESLACE_KEY;
      else
        DisplayID = LORES_KEY; 
    }   
  }

  if(Mode == HAM8) Depth = 8;
    else Depth = NumPlanes;

  my_screen = OpenScreenTags(NULL, SA_Width,     (ULONG)cols,
                                   SA_Height,    (ULONG)rows,
                                   SA_Depth,     (ULONG)Depth,
                                   SA_DisplayID, (ULONG)DisplayID,
                                   SA_Type,      (ULONG)CUSTOMSCREEN,
                                   SA_Quiet,     (ULONG)TRUE,
                                   SA_AutoScroll,(ULONG)TRUE,
                                   SA_Overscan,  (ULONG)OSCAN_STANDARD,
                                   TAG_DONE);

  if(my_screen == NULL)  return 0;
    
  /* open a dummy window to allow autoscroll feature      */
  
  my_window = OpenWindowTags(NULL, WA_Left,         (ULONG)0,
                                   WA_Top,          (ULONG)0,
                                   WA_Width,        (ULONG)cols,
                                   WA_Height,       (ULONG)rows,
                                   WA_CustomScreen, my_screen,
                                   WA_NoCareRefresh,(ULONG)TRUE,
                                   WA_Borderless,   (ULONG)TRUE,
                                   WA_Backdrop,     (ULONG)TRUE,
                                   WA_RMBTrap,      (ULONG)TRUE, /* disable screen menu drawing */
                                   WA_IDCMP,        (ULONG)IDCMP_MOUSEBUTTONS,
                                   WA_Activate,     (ULONG)TRUE,
                                   WA_BusyPointer,  (ULONG)TRUE, /* V39 only! */
                                   TAG_DONE);

  if(my_window == NULL) return 0;

  /* initialize temprp for use with WritePixelLine8() */

  CopyMem(&my_screen->RastPort, &temprp, sizeof(struct RastPort));
  temprp.Layer = NULL;
  /* V39 function */
  temprp.BitMap = AllocBitMap(cols, 1, my_screen->RastPort.BitMap->Depth, 0, my_screen->RastPort.BitMap);

  if(temprp.BitMap == NULL) return 0;

  return 1; /* success */  
}


/* Set a color... */

void SetDisplayColor(int ColorNumber, UBYTE r, UBYTE g, UBYTE b)
{
  if(my_screen)
    /* V39 function */
    SetRGB32(&my_screen->ViewPort, (ULONG)ColorNumber, (ULONG)r << 24,
                                                       (ULONG)g << 24,
                                                       (ULONG)b << 24);
}


/* Close the display */

void CloseDisplay(void)
{
  if(my_screen) ScreenToBack(my_screen);

  if(temprp.BitMap)
  {
    /* V39 function */
    FreeBitMap(temprp.BitMap);
    temprp.BitMap = NULL;
  }
  if(my_window)
  {
    CloseWindow(my_window);
    my_window = NULL;
  }
  if(my_screen)
  {
    CloseScreen(my_screen);
    my_screen = NULL;
  }
  if(IntuitionBase)
  {
   CloseLibrary(IntuitionBase);
   IntuitionBase = NULL;
  }
  if(GfxBase)
  {
    CloseLibrary(GfxBase);
    GfxBase = NULL;
  }
}


/* display a line of chunky pixel graphics... */


void DisplayRow(char *array, int cols)
{
  if(my_screen)
    WritePixelLine8(&my_screen->RastPort, 0, Drow++, cols, array, &temprp);
}


/* check for a right mouse button press */

int CheckButton(void)
{
  struct IntuiMessage *msg;
  int Button = 0;

  if(my_window)
  {
    while(msg = (struct IntuiMessage *)GetMsg(my_window->UserPort))
    {
      if(msg->Class == IDCMP_MOUSEBUTTONS)
        if(msg->Code == MENUDOWN)
          Button = 1; 
      ReplyMsg((struct Message *)msg);
      if(Button) break;
    }
  }
  return Button;
}
       
/* final wait after the picture is finished */

void FinalWait(void)
{
  struct IntuiMessage *msg;
  int Button = 0;
  struct TagItem WinPointerSet[] = { {WA_Pointer, NULL}, {TAG_DONE, NULL} };

  /* set the normal pointer */
  /* V39 function */

  /* SetWindowPointer(my_window, WA_Pointer, NULL, TAG_DONE); */
  SetWindowPointerA(my_window, WinPointerSet);
  
  if(my_window)
  {
    while(!Button)
    {
      Wait(1L<<my_window->UserPort->mp_SigBit);
      while(msg = (struct IntuiMessage *)GetMsg(my_window->UserPort))
      {
        if(msg->Class == IDCMP_MOUSEBUTTONS)
          if(msg->Code == MENUDOWN) Button = 1; 
        ReplyMsg((struct Message *)msg);
        if(Button) break;
      }
    }
  }
}
      
static void error_exit(const char *msgtext)
{
 printf("%s", msgtext);
 CloseDisplay();
 exit(10);
}
