#ifndef VESA_H
# define VESA_H

# ifdef __cplusplus
 extern "C" {
# endif

#include "standard.h"
#include "palette.h"

/*********************/
/* kind of VESA mode */
/*********************/
#define FB_NONE 0
#define FB_LINEAR 1
#define FB_BANKED 2

#define SVGA640X480        0
#define SVGA800X600        1
#define SVGA1024X768       2
#define SVGA1280X1024      3
#define SVGA1600X1200      4
#define SVGA320X200        5

/* Print Modi */
# define PIC_ON_BACK 1
# define PIC_FILLED 2
# define MULTI_COLOR 1
# define SINGLE_COLOR 2

# define MAX_ZEILEN_LEN 2048

typedef struct
{
 T_PBYTE          zeiger;
 T_WORD           breite;
 T_WORD           hoehe;
 T_WORD           null;
} EIN_ZEICHEN;

typedef struct
{
 EIN_ZEICHEN    zeichen[256];
 T_WORD         hintergrundfarbe;
} T_FONT;

typedef struct
{
 T_BYTE signatur[4];
 T_BYTE vesa_versionsnummer_lo;
 T_BYTE vesa_versionsnummer_hi;
 T_PCHAR herstellername;
 T_DWORD leistungsflag;
 T_PWORD modi_liste;
 T_BYTE fuellen[256-18];
} VESA_DATEN;

typedef struct
{
 T_INT  modus_flag;
 T_BYTE flag_fenster_1;
 T_BYTE flag_fenster_2;
 T_INT  granularitaet;
 T_WORD fenster_groesse;
 T_WORD seg_adresse_fenster_1;
 T_WORD seg_adresse_fenster_2;
 T_PVOID fenster_anzeige_routine;
 T_INT  bytes_pro_zeile;
 T_INT  x_aufloesung;
 T_INT  y_aufloesung;
 T_BYTE breite_zeichenmatrix;
 T_BYTE hoehe_zeichenmatrix;
 T_BYTE anzahl_bitplanes;
 T_BYTE anzahl_bits_pro_punkt;
 T_BYTE anzahl_speicherbloecke;
 T_BYTE speichermodell;
 T_BYTE groesse_speicherbloecke;
 T_BYTE fuellen[256-29];
} VESA_MODUS_DATEN;

/***********************************/
/* SuperVGA mode information block */
/***********************************/
typedef struct {
 T_WORD ModeAttributes;         /* Mode attributes                  */
 T_CHAR  WinAAttributes;         /* Window A attributes              */
 T_CHAR  WinBAttributes;         /* Window B attributes              */
 T_WORD WinGranularity;         /* Window granularity in k          */
 T_WORD WinSize;                /* Window size in k                 */
 T_WORD WinASegment;            /* Window A segment                 */
 T_WORD WinBSegment;            /* Window B segment                 */
 T_WORD WinFuncOffset;          /* Pointer to window function       */
 T_WORD WinFuncSegment;         /* Pointer to window function       */
 T_WORD BytesPerScanLine;       /* Bytes per scanline               */
 T_WORD XResolution;            /* Horizontal resolution            */
 T_WORD YResolution;            /* Vertical resolution              */
 T_CHAR  XCharSize;              /* Character cell width             */
 T_CHAR  YCharSize;              /* Character cell height            */
 T_CHAR  NumberOfPlanes;         /* Number of memory planes          */
 T_CHAR  BitsPerPixel;           /* Bits per pixel                   */
 T_CHAR  NumberOfBanks;          /* Number of CGA style banks        */
 T_CHAR  MemoryModel;            /* Memory model type                */
 T_CHAR  BankSize;               /* Size of CGA style banks          */
 T_CHAR  NumberOfImagePages;     /* Number of images pages           */
 T_CHAR  res1;                   /* Reserved                         */
 T_CHAR  RedMaskSize;            /* Size of direct color red mask    */
 T_CHAR  RedFieldPosition;       /* Bit posn of lsb of red mask      */
 T_CHAR  GreenMaskSize;          /* Size of direct color green mask  */
 T_CHAR  GreenFieldPosition;     /* Bit posn of lsb of green mask    */
 T_CHAR  BlueMaskSize;           /* Size of direct color blue mask   */
 T_CHAR  BlueFieldPosition;      /* Bit posn of lsb of blue mask     */
 T_CHAR  RsvdMaskSize;           /* Size of direct color res mask    */
 T_CHAR  RsvdFieldPosition;      /* Bit posn of lsb of res mask      */
 T_CHAR  DirectColorModeInfo;    /* Direct color mode attributes     */
 /* VBE 2.0 extensions information */

 T_ULONG PhysBasePtr;                    /* Physical address for linear buf      */
 T_ULONG OffScreenMemOffset;             /* Pointer to start of offscreen mem*/
 T_SHORT OffScreenMemSize;               /* Amount of offscreen mem in 1K's      */
 T_CHAR  res2[206];                      /* Pad to 256 byte block size       */
} ModeInfoBlock;

typedef struct
{
 T_INT   groesse_x;
 T_INT   groesse_y;
 T_PBYTE maus_zeiger;
 T_BYTE  outline;
 T_BYTE  fill;
 T_BYTE  back;
} MOUSE_POINTER;

#define MAUS_GROESSE_X_DEFAULT 14
#define MAUS_GROESSE_Y_DEFAULT 16

typedef struct
{
 T_INT   x;
 T_INT   y;
 T_INT   len_x;
 T_INT   len_y;
 T_PBYTE buffer;
}RECTANGLE_SAVE;

#define flongSwap(a,b)                 \
    {static T_SLONG Tmp;               \
    Tmp=*(a);                          \
    *(a)=*(b);                         \
    *(b)=Tmp;}

#define fSwap(a,b)                 \
    {iSWTmp=*(a);                  \
    *(a)=*(b);                     \
    *(b)=iSWTmp;}
#define fSwapWord fSwap


#define vesa_print_char(x,y,z) _ch_vpsm3_(x,y,z)
#define vesa_print_char_max(x,y,len_x,len_y,z) _chm_vpsm3_(x,y,len_xlen_y,z)
#define vesa_print_str(x,y,string) vesa_print_string_max(0,0,x,y,PMAX,PMAX,string)


extern T_INT   (* vesa_print_string_max) (T_INT,T_INT, T_INT, T_INT, T_INT, T_INT, T_PCHAR );
extern T_INT   (* vesa_print_string_max_oc) (T_INT,T_INT, T_INT, T_INT, T_INT, T_INT, T_PCHAR );
extern T_VOID  (* vesa_plot256)  (T_UWORD, T_UWORD, T_UWORD);
extern T_UCHAR (* vesa_get_pixel)(T_UWORD, T_UWORD);
extern T_INT   (* vesa_print_zeile256) (T_INT, T_INT, T_PBYTE , T_WORD);
extern T_VOID  (* vesa_get_zeile) (T_INT, T_INT, T_INT, T_PBYTE );
extern T_VOID  (* vesa_get_zeile_oc) (T_INT, T_INT, T_INT, T_PBYTE );
extern T_VOID  (* vesa_plot256_oc)  (T_UWORD, T_UWORD, T_UWORD);
extern T_UCHAR (* vesa_get_pixel_oc)(T_UWORD, T_UWORD);
extern T_INT   (* vesa_print_zeile256_oc) (T_INT, T_INT, T_PBYTE , T_WORD);
extern T_VOID  (* vesa_print_zeile256_oc_raw) (T_INT, T_INT, T_PBYTE , T_WORD);
extern T_VOID  (* vesa_draw_line) (T_SWORD ,T_SWORD, T_SWORD, T_SWORD, T_SWORD);
extern T_VOID  (* vesa_draw_line_aa) (T_SWORD ,T_SWORD, T_SWORD, T_SWORD, T_SWORD, T_UWORD);

T_VOID vesa_set_palette(T_CHAR palette[256][4]);
T_VOID vesa_save_SVpalette_to_dac(T_CHAR palette[256][4]);
T_VOID vesa_set_dac_register(T_INT color_nummer,T_BYTE r,T_BYTE g,T_BYTE b);
T_INT vesa_get_dac_register(T_INT color_nummer,T_PBYTE r, T_PBYTE g, T_PBYTE b);
T_INT vesa_set_mehrere_dac(T_INT start,T_INT anzahl, T_PBYTE buffer);
T_INT vesa_get_mehrere_dac(T_INT start, T_INT anzahl, T_PBYTE buffer);
T_INT vesa_save_mehrere_dac(T_INT start, T_UWORD anzahl, T_PCHAR dateiname);
T_INT vesa_load_mehrere_dac(T_INT start, T_PCHAR dateiname);

T_INT vesa_karte_da(T_VOID);
T_INT vesa_existiert_modus(T_INT modus);
T_INT vesa_lese_modus_daten(T_INT modus);
T_INT vesa_anzeige_modus_daten(T_INT modus);
T_INT vesa_anzeige_daten(T_VOID);
T_INT vesa_gebe_datenspeicher_zurueck(T_VOID);
T_INT vesa_alten_modus_speichern(T_VOID);
T_INT vesa_alten_modus_setzen(T_VOID);
T_INT vesa_alten_modus_freigeben(T_VOID);
T_INT vesa_setze_modus(T_INT modus);
T_INT _ch_vpsm3_(T_INT x,T_INT y,T_CHAR z);
T_INT _chm_vpsm3_(T_INT x,T_INT y,T_INT len_x,T_INT len_y,T_CHAR z);
T_INT vesa_print_int(T_INT x, T_INT y, T_LONG zahl);
T_INT vesa_load_font(T_PCHAR dateiname, T_FONT *ein_font);
T_INT vesa_free_font(T_FONT *ein_font);
T_INT vesa_get_text_len(T_PCHAR text, T_PINT len_x, T_PINT len_y);

T_VOID vesa_line_h(T_INT x1,T_INT y1,T_INT len, T_BYTE color);
T_VOID vesa_line_v(T_INT x1,T_INT y1,T_INT len, T_BYTE color);
T_VOID vesa_rect(T_INT x1,T_INT y1,T_INT len_x, T_INT len_y, T_BYTE color);
T_VOID vesa_rect_fill(T_INT x1,T_INT y1,T_INT len_x, T_INT len_y,T_BYTE color);
T_VOID vesa_rect_fill_oc(T_INT x1,T_INT y1,T_INT len_x, T_INT len_y,T_BYTE color);
RECTANGLE_SAVE *vesa_rect_save(T_INT x1,T_INT y1,T_INT len_x, T_INT len_y,T_BYTE color);
T_INT vesa_remove_rectangle(RECTANGLE_SAVE *rectangle);

T_INT vesa_mouse_init(T_VOID);
T_INT vesa_mouse_deinit(T_VOID);
T_INT vesa_mouse_setze_cursor(T_INT x, T_INT y);
T_VOID vesa_mouse_save_pos(T_VOID);
T_VOID vesa_mouse_load_pos(T_VOID);
T_INT vesa_mouse_setze_rect(T_INT x_min, T_INT y_min,T_INT x_max, T_INT y_max);
T_VOID vesa_mouse_verstecke_cursor(T_INT x1, T_INT y1, T_INT x2, T_INT y2);
T_VOID vesa_mouse_zeige_cursor(T_INT x1, T_INT y1, T_INT x2, T_INT y2);
T_VOID vesa_mouse_verstecke_cursor_all(T_VOID);
T_VOID vesa_mouse_zeige_cursor_all(T_VOID);
T_VOID vesa_mouse_mickey_pro_8punkte(T_INT mickey_x, T_INT mickey_y);

//#define VESA_MOUSE_VERSTECKE vesa_mouse_verstecke_cursor(0,0,vesa_x,vesa_y);
//#define VESA_MOUSE_ZEIGE vesa_mouse_zeige_cursor(0,0,vesa_x,vesa_y);

T_VOID vesa_mouse_update(T_VOID);
T_VOID vesa_mouse_force_update(T_VOID);

T_INT vesa_set_default_mouse_color(T_BYTE outline,T_BYTE fill);
T_VOID vesa_line_h(T_INT x1,T_INT y1,T_INT len, T_BYTE color);
T_VOID vesa_line_v(T_INT x1,T_INT y1,T_INT len, T_BYTE color);
T_VOID vesa_rect(T_INT x1,T_INT y1,T_INT len_x, T_INT len_y, T_BYTE color);
RECTANGLE_SAVE *vesa_rect_save(T_INT x1,T_INT y1,T_INT len_x, T_INT len_y,T_BYTE color);
T_INT vesa_remove_rectangle(RECTANGLE_SAVE *rectangle);

T_INT vesa_get_dot_col256(T_INT x,T_INT y);
T_VOID vesa_draw_shaded_rectangle(T_INT x, T_INT y, T_INT len_x, T_INT len_y,T_BYTE col1, T_BYTE col2, T_INT thick);
T_VOID sync_display(T_VOID);
T_VOID clear_screen(T_VOID);
T_INT vesa_mouse_get_irq(T_VOID);
T_UCHAR vesa_get_nearest_used_color(T_INT r, T_INT g, T_INT b);

extern T_INT framebuffer;
extern T_UWORD vesa_offset_compare;
extern T_UWORD vesa_segment_of_window[2];
extern T_UWORD vesa_address_of_window[2];
extern T_UWORD vesa_granularity;
extern T_UWORD vesa_granularity_potenz;
extern T_UWORD vesa_and_x;
extern T_ULONG vesa_write_seg;
extern T_ULONG vesa_read_seg;
extern T_UWORD vesa_read_window;
extern T_UWORD vesa_write_window;
extern T_UWORD WinFuncSegment,WinFuncOffset;
extern T_UWORD offset_x;
extern T_UWORD new_win_address;
extern T_VOID (*vesa_set_write_window)(T_VOID);
extern T_VOID (*vesa_set_read_window)(T_VOID);
extern T_INT iScreenXres;
extern T_INT iScreenYres;
extern T_INT iScreenZres;
extern T_INT vesa_x;
extern T_INT vesa_y;
extern T_INT vesa_y_m1;
extern T_INT vesa_force_bank;

extern T_FONT default_font;
extern T_FONT *font_now;
extern T_INT vesa_print_modus;
extern T_INT vesa_back_color;
extern T_INT vesa_text;
extern T_INT vesa_text_color;

extern T_UWORD offset_x;
extern T_ULONG offset;

extern VESA_DATEN *vesa_daten;
extern VESA_MODUS_DATEN *vesa_modus_daten;
extern T_WORD vesa_error;
extern T_BYTE zeile[MAX_ZEILEN_LEN];
extern T_BYTE zeile_hilf[MAX_ZEILEN_LEN];
extern volatile T_INT vesa_mouse_x;
extern volatile T_INT vesa_mouse_y;
extern volatile T_INT vesa_mouse_button;
extern T_INT vesa_da;
extern T_INT vesa_modus_active;
extern T_INT vesa_mouse_initialisiert;
extern volatile T_INT vesa_mouse_interrupt;
extern vesa_mouse_verstecke;
extern T_SWORD iSWTmp;
extern T_INT vesa_bytes_per_scanline;

extern T_BYTE vesa_mauszeiger_default[MAUS_GROESSE_X_DEFAULT*MAUS_GROESSE_Y_DEFAULT];
extern MOUSE_POINTER vesa_mouse_zeiger_default;
extern MOUSE_POINTER *vesa_mouse_zeiger;
extern T_INT vesa_circle( T_INT x, T_INT y, T_INT r, T_UWORD color );
void deinit_mouse_error(void);


#define  MOUSE_VERSTECKE               \
 if (vesa_mouse_verstecke==0)          \
  vesa_mouse_verstecke_cursor_all();   \
 else                                  \
  vesa_mouse_verstecke++;

#define  MOUSE_ZEIGE                   \
 if (vesa_mouse_verstecke==1)          \
  vesa_mouse_zeige_cursor_all();       \
 else                                  \
  vesa_mouse_verstecke--;

extern T_PUCHAR  clip_memory;
extern T_INT use_clip;

#ifdef VECTREX
extern T_INT use_vectrex_mouse;
extern volatile T_ULONG vmouse_y;
extern volatile T_ULONG vmouse_x;

extern T_UWORD dividerx;
extern T_UWORD dividery;

extern T_INT mausxmin;
extern T_INT mausxmax;
extern T_INT mausymin;
extern T_INT mausymax;

#endif

# ifdef __cplusplus
}
# endif

#endif
