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

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


#define INTUI_V36_NAMES_ONLY

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


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

#include "ppm2AGA.h"

extern struct IntuitionBase *IntuitionBase;
extern int VGAenable;
extern ULONG SMR;
extern ULONG SMR_DisplayID;
struct Screen *my_screen = NULL;
struct Window *my_window = NULL;
struct RastPort temprp; /* a copy of the screen's RastPort */

void CloseDisplay(void);

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

int InitDisplay(int cols, int rows, ULONG Mode, int NumPlanes)
{
  if(IntuitionBase->LibNode.lib_Version >= 39)
  {
    ULONG Depth, DisplayID;

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

    if(SMR)
    {
      DisplayID = SMR_DisplayID;
    }
    else
    {
      if(VGAenable)
      {
        if(Mode == HAM6 || Mode == HAM8)
        {
          if(cols > 370 || rows > 260)
            DisplayID = VGAPRODUCTHAM_KEY;
          else
            DisplayID = VGALORESHAMDBL_KEY;
        }
        else
        {
          if(cols > 370 || rows >260) 
            DisplayID = VGAPRODUCT_KEY;
          else
            DisplayID = VGALORESDBL_KEY;   
        }
      }
      else
      {  
        if(Mode == 1 || Mode == 2)
          DisplayID = DEFAULT_MONITOR_ID | HAM_KEY;
        else
          DisplayID = DEFAULT_MONITOR_ID;

        if(cols > 370) DisplayID |= HIRES;
        if(rows > 280) DisplayID |= LACE;
      }
    }

    if(Mode == HAM6) Depth = 6;
    else 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)
    {
      /* open a dummy window to allow autoscroll feature      */
      /* if the window fails to open we can continue, but the */
      /* user will not be able to move the screen             */
      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 */
                                       TAG_DONE);

      /* 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)
      {
        CloseDisplay();
        return 0; /* failure */
      }
      return 1; /* success */
    }
  }
  return 0; /* failure */
}


/* 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(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;
  }
}


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

void DisplayRow(char *array, int cols, int row)
{
  if(my_screen)
    /* V37 function */
    WritePixelLine8(&my_screen->RastPort, 0, row, cols, array, &temprp);
}
