#include <dos.h>
#include <cybergraphics/cybergraphics.h>
#include <exec/memory.h>
#include <exec/types.h>
#include <intuition/intuition.h>
#include <clib/alib_protos.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <proto/exec.h>
#include <rtgmaster/rtgmaster.h>
#include <pragmas/rtgmaster_pragmas.h>
#include <clib/rtgmaster_protos.h>
#include <rtgmaster/rtgsublibs.h>

#define NOPOINTER 0
#define POINTER 1
#define MOVEM 4
#define RTGMASTER 3
#define DOUBLEBUFFER 2
#define BLITTER 1
#define MOVE16 0

#define LSHIFT              0x0001
#define RSHIFT              0x0002
#define CAPSLOCK            0x0004
#define CONTROL             0x0008
#define LALT                0x0010
#define RALT                0x0020
#define LCOMMAND            0x0040
#define RCOMMAND            0x0080
#define NUMERICPAD          0x0100
#define MIDBUTTON           0x1000
#define RBUTTON             0x2000
#define LEFTBUTTON          0x4000
#define IECODE_LBUTTON                  0x68
#define IECODE_RBUTTON                  0x69
#define IECODE_MBUTTON                  0x6A
#define IECODE_UP_PREFIX                0x80
#define SELECTUP        (IECODE_LBUTTON | IECODE_UP_PREFIX)
#define SELECTDOWN      (IECODE_LBUTTON)
#define MENUUP          (IECODE_RBUTTON | IECODE_UP_PREFIX)
#define MENUDOWN        (IECODE_RBUTTON)
#define MIDDLEUP        (IECODE_MBUTTON | IECODE_UP_PREFIX)
#define MIDDLEDOWN      (IECODE_MBUTTON)


typedef struct vrect_s
{
        int                             x,y,width,height;
        struct vrect_s  *pnext;
} vrect_t;


typedef struct
{
        UBYTE                 *buffer;                // invisible buffer
        UBYTE                 *colormap;              // 256 * VID_GRADES size
        unsigned                rowbytes;       // may be > width if displayed in a window
        unsigned                width;
        unsigned                height;
        int                             numpages;
        UBYTE                 *direct;                // direct drawing to framebuffer, if not
                                                                        //  NULL
} viddef_t;

#define LUT8                    1<<PIXFMT_LUT8
#define RGB15                   1<<PIXFMT_RGB15
#define BGR15                   1<<PIXFMT_BGR15
#define RGB15PC         1<<PIXFMT_RGB15PC
#define BGR15PC   1<<PIXFMT_BGR15PC
#define RGB16                   1<<PIXFMT_RGB16
#define BGR16                   1<<PIXFMT_BGR16
#define RGB16PC         1<<PIXFMT_RGB16PC
#define BGR16PC         1<<PIXFMT_BGR16PC
#define RGB24                   1<<PIXFMT_RGB24
#define BGR24                   1<<PIXFMT_BGR24
#define ARGB32          1<<PIXFMT_ARGB32
#define BGRA32          1<<PIXFMT_BGRA32
#define RGBA32          1<<PIXFMT_RGBA32

/*********************************************************************
* mymode =1 => Use Screenmode-Requester. Init-Function returns a     *
* single Screenmode-Structure. Mymode =0 => A list of the Screenmode-*
* requesters in the system is returned, no Requester is called.      *
* support is in rtgmaster format (see below).                        *
*********************************************************************/

/* Support format :

;    ;
;    ;    | Pixels  | Pixel|Color| Pixel
;    ; Bit|represent| size |space| layout
;    ;------------------------------------------------------------------
;    ;  0  TrueColor  LONG   RGB   %00000000 rrrrrrrr gggggggg bbbbbbbb  ARGB32
;    ;  1  TrueColor 3 BYTE  RGB   %rrrrrrrr gggggggg bbbbbbbb           RGB24
;    ;  2  TrueColor  WORD   RGB   %rrrrrggg gggbbbbb                    RGB16
;    ;  3  TrueColor  WORD   RGB   %0rrrrrgg gggbbbbb                    RGB15
;    ;  4  TrueColor  LONG   BGR   %00000000 bbbbbbbb gggggggg rrrrrrrr  ABGR32
;    ;  5  TrueColor 3 BYTE  BGR   %bbbbbbbb gggggggg rrrrrrrr           BGR24
;    ;  6  TrueColor  WORD   BGR   %bbbbbggg gggrrrrr                    BGR16
;    ;  7  TrueColor  WORD   BGR   %0bbbbbgg gggrrrrr                    BGR15
;    ;  8  TrueColor  LONG   RGB   %rrrrrrrr gggggggg bbbbbbbb 00000000  RGBA32
;    ;  9  ColorMap   BYTE   -     -                                     LUT8
;    ; 10  Graffiti   BYTE   -     - (Graffiti style chunky, very special)
;    ; 11  TrueColor  WORD   RGB   %gggbbbbb 0rrrrrgg                    RGB15PC
;    ; 12  TrueColor  WORD   BGR   %gggrrrrr 0bbbbbgg                    BGR15PC
;    ; 13  TrueColor  WORD   RGB   %gggbbbbb rrrrrggg                    RGB16PC
;    ; 14  TrueColor  WORD   BGR   %gggrrrrr bbbbbggg                    BGR16PC
;    ; 15  TrueColor  LONG   BGR   %bbbbbbbb gggggggg rrrrrrrr 00000000  BGRA32
;

NOTE: There is a bit for Graffiti, but the board is not yet supported !!!

*/

struct MyMode {
        ULONG minwidth;
        ULONG minheight;
        ULONG maxwidth;
        ULONG maxheight;
        ULONG support;
       };

struct MyEvent {
        UWORD rawkey;
        UWORD mouse;
        UWORD qualifier;
        UWORD x;
        UWORD y;
        };

struct triplet {
        ULONG red;
        ULONG green;
        ULONG blue;
};
struct ColTable {
        UWORD   num_colors;
        UWORD start_color;
        struct triplet  color[256];
        LONG pad1;
        LONG pad2;
        LONG pad3;
};

typedef struct vmode_s {
        struct vmode_s  *pnext;
        ULONG   ID;
        char            *header;
        unsigned        width;
        unsigned        height;
        unsigned        rowbytes;
        int numpages;
        int     type;
        int direct;
        struct RDCMPData *(__asm *setmode)(register __a0 viddef_t *vid, register __a1 struct vmode_s *pcurrentmode);
        void            (__asm *closemode)(register __a0 viddef_t *lvid, register __a1 struct vmode_s *pcurrentmode);
        void            (__asm *swapbuffers)(register __a0 viddef_t *vid, register __a1 struct vmode_s *pcurrentmode,register __a2 vrect_t *rects,register __d0 int wait);
        void            (__asm *setpalette)(register __a0 viddef_t *vid, register __a1 struct vmode_s *pcurrentmode,register __a2 unsigned char *palette);
        void            (__asm *begindirectrect)(register __a0 viddef_t *vid, register __a1 struct vmode_s *pcurrentmode,register __d0 int x, register __d1 int y, register __a2 byte *pbitmap, register __d2 int width,register __d3 int height);
        void            (__asm *enddirectrect)(register __a0 viddef_t *vid, register __a1 struct vmode_s *pcurrentmode,register __d0 int x, register __d1 int y, register __d2 int width, register __d3 int height);
        struct MyEvent             *(__asm *sendkeyevents)(void);
        char            name[DISPLAYNAMELEN+1];
} vmode_t;

// vid_wait settings
#define VID_WAIT_NONE                   0
#define VID_WAIT_VSYNC                  1
#define VID_WAIT_DISPLAY_ENABLE 2

extern int              numvidmodes;
extern vmode_t  *pvidmodes;
extern vmode_t  *vidmodes;

extern unsigned char colormap256[32][256];

extern void     *vid_surfcache;
extern int      vid_surfcachesize;

 vmode_t __asm *RTGM_Init(register __d0 int pixformats,register __d1 int type,register __d2 int pointer,register __d3 int extra,register __a0 struct MyMode *mymode);
void __asm RTGM_SetPalette(register __a0 viddef_t *lvid, register __a1 vmode_t *pcurrentmode, register __a2 unsigned char *palette);
struct RDCMPData __asm *RTGM_SetMode (register __a0 viddef_t *lvid, register __a1 vmode_t *pcurrentmode);
void __asm RTGM_CloseMode (register __a0 viddef_t *lvid, register __a1 vmode_t *pcurrentmode);
void __asm RTGM8_BeginDirectRect (register __a0 viddef_t *lvid, register __a1 struct vmode_s *pcurrentmode, register __d0 int x,register __d1 int y, register __a2 byte *pbitmap, register __d2 int width, register __d3 int height);
void __asm RTGM8_EndDirectRect (register __a0 viddef_t *lvid, register __a1 struct vmode_s *pcurrentmode, register __d0 int x, register __d1 int y, register __d2 int width, register __d3 int height);
void __asm RTGM8_SwapBuffers (register __a0 viddef_t *lvid, register __a1 vmode_t *pcurrentmode, register __a2 vrect_t *rects,register __d0 int wait);
void __asm RTGM16_BeginDirectRect (register __a0 viddef_t *lvid, register __a1 struct vmode_s *pcurrentmode, register __d0 int x,register __d1 int y, register __a2 byte *pbitmap, register __d2 int width, register __d3 int height);
void __asm RTGM16_EndDirectRect (register __a0 viddef_t *lvid, register __a1 struct vmode_s *pcurrentmode, register __d0 int x, register __d1 int y, register __d2 int width, register __d3 int height);
void __asm RTGM16_SwapBuffers (register __a0 viddef_t *lvid, register __a1 vmode_t *pcurrentmode, register __a2 vrect_t *rects,register __d0 int wait);
void __asm RTGM24_BeginDirectRect (register __a0 viddef_t *lvid, register __a1 struct vmode_s *pcurrentmode, register __d0 int x,register __d1 int y, register __a2 byte *pbitmap, register __d2 int width, register __d3 int height);
void __asm RTGM24_EndDirectRect (register __a0 viddef_t *lvid, register __a1 struct vmode_s *pcurrentmode, register __d0 int x, register __d1 int y, register __d2 int width, register __d3 int height);
void __asm RTGM24_SwapBuffers (register __a0 viddef_t *lvid, register __a1 vmode_t *pcurrentmode, register __a2 vrect_t *rects,register __d0 int wait);
void __asm RTGM32_BeginDirectRect (register __a0 viddef_t *lvid, register __a1 struct vmode_s *pcurrentmode, register __d0 int x,register __d1 int y, register __a2 byte *pbitmap, register __d2 int width, register __d3 int height);
void __asm RTGM32_EndDirectRect (register __a0 viddef_t *lvid, register __a1 struct vmode_s *pcurrentmode, register __d0 int x, register __d1 int y, register __d2 int width, register __d3 int height);
void __asm RTGM32_SwapBuffers (register __a0 viddef_t *lvid, register __a1 vmode_t *pcurrentmode, register __a2 vrect_t *rects,register __d0 int wait);
struct MyEvent __asm *Sys_SendKeyEvents(void);

