#ifndef _HARDWARE_H_
#define _HARDWARE_H_

/** 3DGPL *************************************************\
 *  (MSDOS, i386+, VGA, DJGPP)                            *
 *  Header for hardware specific stuff.                   *
 *                                                        *
 *  hardware.c               hardware specific stuff.     *
 *                                                        *
 *  (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                                 *
\**********************************************************/

typedef short signed_16_bit;                /* compiler/mashine dependent */
typedef int   signed_32_bit;           
typedef unsigned short unsigned_16_bit;
typedef unsigned int   unsigned_32_bit;

#define HW_set_int(dst,lng,val)   asm("movl  %0,%%eax \n"             \
                                      "movl  %1,%%edi \n"             \
                                      "movl  %2,%%ecx \n"             \
                                      "cld \n"                        \
                                      "rep \n"                        \
                                      "stosl %%eax,(%%edi) \n"        \
                                      ::"g" (val),"g" (dst),"g" (lng) \
                                      :"eax","edi","ecx"              \
                                     ) 

#define HW_set_char(dst,lng,val)  asm("movb  %0,%%al  \n"             \
                                      "movl  %1,%%edi \n"             \
                                      "movl  %2,%%ecx \n"             \
                                      "cld \n"                        \
                                      "rep \n"                        \
                                      "stosb %%al,(%%edi) \n"         \
                                      ::"g" (val),"g" (dst),"g" (lng) \
                                      :"al","edi","ecx"               \
                                     ) 

#define HW_copy_int(src,dst,lng)  asm("movl  %0,%%esi \n"             \
                                      "movl  %1,%%edi \n"             \
                                      "movl  %2,%%ecx \n"             \
                                      "cld \n"                        \
                                      "rep \n"                        \
                                      "movsl (%%esi),(%%edi) \n"      \
                                      ::"g" (src),"g" (dst),"g" (lng) \
                                      :"esi","edi","ecx"              \
                                     ) 

#define HW_copy_char(src,dst,lng) asm("movl  %0,%%esi \n"             \
                                      "movl  %1,%%edi \n"             \
                                      "movl  %2,%%ecx \n"             \
                                      "cld \n"                        \
                                      "rep \n"                        \
                                      "movsb (%%esi),(%%edi) \n"      \
                                      ::"g" (src),"g" (dst),"g" (lng) \
                                      :"esi","edi","ecx"              \
                                     ) 

#define HW_SCREEN_X_SIZE         320             
#define HW_SCREEN_Y_SIZE         200        /* number of pixels total */

#define HW_SCREEN_X_MAX          319
#define HW_SCREEN_Y_MAX          199        /* number of maximum pixel */

#define HW_SCREEN_X_CENTRE       160 
#define HW_SCREEN_Y_CENTRE       100        /* middle of the screen */

#define HW_COLOURMAP_SIZE_CHAR 64000        /* bytes in the colourmap */
#define HW_COLOURMAP_SIZE_INT  16000        /* ints in the colourmap */

struct HW_colour                            /* describes colour */
{
 int hw_r;
 int hw_g;
 int hw_b;                                  /* intensity components */
};

int HW_open_screen(char *display_name,
                   char *screen_name, 
                   struct HW_colour palette[256],
                   unsigned char *colourmap
                  );
void HW_blit(void);
void HW_close_screen(void);

#define HW_KEY_ARROW_LEFT  331
#define HW_KEY_ARROW_RIGHT 333
#define HW_KEY_ARROW_UP    328
#define HW_KEY_ARROW_DOWN  336

#define HW_KEY_PLUS         43
#define HW_KEY_MINUS        45

#define HW_KEY_ENTER        13
#define HW_KEY_SPACE        32
#define HW_KEY_TAB           9              /* all i can think of */ 

void HW_run_event_loop(void (*application_main)(void),
                       void (*application_key_handler)(int key_code)
                      );
void HW_quit_event_loop(void);

/**********************************************************/

#endif
