/** 3DGPL *************************************************\
 *  (MSDOS, i386+, VGA, DJGPP)                            *
 *  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 <pc.h>                             /* kbhit() etc. */
#include "../hardware/hardware.h"           /* all the defenitions */

unsigned char *HW_colourmap;                /* where drwaings go to */
int HW_running;                             /* event loop running? */

/**********************************************************\
 *  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("movb  $0x13,%%al":::"%al");           /* %al mode number */
 asm("xorb  %%ah,%%ah":::"%ah");            /* function #0 */
 asm("int   $0x10");

 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("movb  %0,%%dh":: "g" (r):"%dh");     /* Red */
  asm("movb  %0,%%ch":: "g" (g):"%ch");     /* Green */
  asm("movb  %0,%%cl":: "g" (b):"%cl");     /* Blue */
  asm("movw  %0,%%ebx":: "g" (i):"%ebx");   /* Colour to set */
  asm("movw  $0x1010,%%ax":::"%ax");        /* function 0x10 subfun 0x10 */
  asm("int   $0x10");
 }
 return(1);
}

/**********************************************************\
 *  Colormap onto the screen.                             *
\**********************************************************/

void HW_blit(void)
{
 HW_copy_int((int*)HW_colourmap,(int*)0xd0000000,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)
                      )
{
 HW_running=1;

 while(HW_running==1)                       /* still running? hmm */
 {
  if(kbhit()) application_key_handler(getkey());
  application_main();
 }
}

/**********************************************************\
 *  Stoping the event loop.                               *
\**********************************************************/

void HW_quit_event_loop(void)
{
 HW_running=0;                              /* that's it */
}

/**********************************************************/
