/** 3DGPL *************************************************\
 *  (MSDOS, 8086+, VGA, BCC/LARGE MODEL+)                 *
 *  Header for hardware specific stuff.                   *
 *                                                        *
 *  Defines:                                              *
 *    HW_open_screen         opening output surface;      *
 *    HW_blit                colourmap onto the screen;   *
 *    HW_close_screen        closing output;              *
 *                                                        *
 *    HW_run_event_loop      runiing for events;          *
 *    HW_quit_event_loop     quiting running.             *
 *                                                        *
 *  (6/1995) By Sergei Savhenko. (savs@cs.mcgill.ca).     *
 *  Copyright (c) 1995 Sergei Savchenko.                  *
 *  THIS SOURCE CODE CAN'T BE USED FOR COMERCIAL PURPOSES *
 *  WITHOUT AUTHORISATION                                 *
\**********************************************************/

#include <dos.h>                            /* MK_FP */
#include <conio.h>                          /* kbhit(), getch() */
#include "../hardware/hardware.h"           /* all the defenitions */

unsigned char *HW_colourmap;                /* where drwaings go to */
int HW_running;                             /* event loop running? */

/**********************************************************\
 *  Implementations for fast memory operations:           *
\**********************************************************/

void HW_set_int(int *d,int l,int v) {int i; for(i=0;i<l;i++) *d++=v; }

/**********************************************************\
 *  Opening output surface and setting the palette.       *
 *                                                        *
 *  RETURNS: always 1.                                    *
 *  --------                                              *
\**********************************************************/

int HW_open_screen(char *display_name,
                   char *screen_name,
                   struct HW_colour palette[256],
                   unsigned char *colourmap
                  )
{
 int i;
 unsigned char r,g,b;
 
 HW_colourmap=colourmap;                    /* for later blits */

 asm mov al,13h                             /* %al mode number */
 asm xor ah,ah                              /* function #0 */
 asm int 10h

 for(i=0;i<256;i++)
 {
  r=(unsigned char)palette[i].hw_r;
  g=(unsigned char)palette[i].hw_g;
  b=(unsigned char)palette[i].hw_b;

  asm mov   dh,r                            /* Red */
  asm mov   ch,g                            /* Green */
  asm mov   cl,b                            /* Blue */
  asm mov   bx,i                            /* Colour to set */
  asm mov   ax,1010h                        /* function 0x10 subfun 0x10 */
  asm int   10h
 }
 return(1);
}

/**********************************************************\
 *  Colormap onto the screen.                             *
\**********************************************************/ 

void HW_blit(void)
{
 HW_copy_int((int*)HW_colourmap,(int*)MK_FP(0xa000,0x0000),HW_COLOURMAP_SIZE_INT);
}

/**********************************************************\
 *  Closing output surface.                               *
\**********************************************************/
 
void HW_close_screen(void)
{
}

/**********************************************************\
 *  Running the event loop.                               *
\**********************************************************/

void HW_run_event_loop(void (*application_main)(void),
                       void (*application_key_handler)(int key_code)
                      )
{
 int k;

 HW_running=1;

 while(HW_running==1)                       /* still running? hmm */
 {
  if(kbhit()) if((k=getch())==0x0) application_key_handler(getch());
              else application_key_handler(k);
  application_main();
 }
}

/**********************************************************\
 *  Stoping the event loop.                               *
\**********************************************************/

void HW_quit_event_loop(void)
{
 HW_running=0;                              /* that's it */
}

/**********************************************************/
