+++ /dev/null
-#include <dos.h>\r
-#include <string.h>\r
-#include <mem.h>\r
-#include <conio.h>\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include "modex16.h"\r
-\r
-\r
-byte far* VGA=(byte far*) 0xA0000000; /* this points to video memory. */\r
-\r
-static void fadePalette(sbyte fade, sbyte start, word iter, byte *palette);\r
-static byte tmppal[PAL_SIZE];\r
-static struct pcxHeader {\r
- byte id;\r
- byte version;\r
- byte encoding;\r
- byte bpp;\r
- word xmin;\r
- word ymin;\r
- word xmax;\r
- word ymax;\r
- word hres;\r
- word vres;\r
- byte pal16[48];\r
- byte res1;\r
- word bpplane;\r
- word palType;\r
- word hScreenSize;\r
- word vScreenSize;\r
- byte padding[54];\r
-};\r
-\r
-\r
-static void\r
-vgaSetMode(byte mode)\r
-{\r
- union REGS regs;\r
-\r
- regs.h.ah = SET_MODE;\r
- regs.h.al = mode;\r
- int86(VIDEO_INT, ®s, ®s);\r
-}\r
-\r
-\r
-/* -========================= Entry Points ==========================- */\r
-void\r
-modexEnter() {\r
- word i;\r
- dword far*ptr=(dword far*)VGA; /* used for faster screen clearing */\r
- word CRTParms[] = {\r
- 0x0d06, /* vertical total */\r
- 0x3e07, /* overflow (bit 8 of vertical counts) */\r
- 0x4109, /* cell height (2 to double-scan */\r
- 0xea10, /* v sync start */\r
- 0xac11, /* v sync end and protect cr0-cr7 */\r
- 0xdf12, /* vertical displayed */\r
- 0x0014, /* turn off dword mode */\r
- 0xe715, /* v blank start */\r
- 0x0616, /* v blank end */\r
- 0xe317 /* turn on byte mode */\r
- };\r
- int CRTParmCount = sizeof(CRTParms) / sizeof(CRTParms[0]);\r
-\r
- /* TODO save current video mode and palette */\r
- vgaSetMode(VGA_256_COLOR_MODE);\r
-\r
- /* disable chain4 mode */\r
- outpw(SC_INDEX, 0x0604);\r
-\r
- /* synchronous reset while setting Misc Output */\r
- outpw(SC_INDEX, 0x0100);\r
-\r
- /* select 25 MHz dot clock & 60 Hz scanning rate */\r
- outp(MISC_OUTPUT, 0xe3);\r
-\r
- /* undo reset (restart sequencer) */\r
- outpw(SC_INDEX, 0x0300);\r
-\r
- /* reprogram the CRT controller */\r
- outp(CRTC_INDEX, 0x11); /* VSync End reg contains register write prot */\r
- outp(CRTC_DATA, 0x7f); /* get current write protect on varios regs */\r
-\r
- /* send the CRTParms */\r
- for(i=0; i<CRTParmCount; i++) {\r
- outpw(CRTC_INDEX, CRTParms[i]);\r
- }\r
-\r
- /* clear video memory */\r
- outpw(SC_INDEX, 0x0f02);\r
- for(i=0; i<0x8000; i++) {\r
- ptr[i] = 0x0000;\r
- }\r
-}\r
-\r
-\r
-void\r
-modexLeave() {\r
- /* TODO restore original mode and palette */\r
- vgaSetMode(TEXT_MODE);\r
-}\r
-\r
-\r
-page_t\r
-modexDefaultPage() {\r
- page_t page;\r
-\r
- /* default page values */\r
- page.data = VGA;\r
- page.dx = 0;\r
- page.dy = 0;\r
- page.width = SCREEN_WIDTH;\r
- page.height = SCREEN_HEIGHT;\r
-\r
- return page;\r
-}\r
-\r
-/* returns the next page in contiguous memory\r
- * the next page will be the same size as p, by default\r
- */\r
-page_t\r
-modexNextPage(page_t *p) {\r
- page_t result;\r
-\r
- result.data = p->data + (p->width/4)*p->height; /* compute the offset */\r
- result.dx = 0;\r
- result.dy = 0;\r
- result.width = p->width;\r
- result.height = p->height;\r
-\r
- return result;\r
-}\r
-\r
-\r
-void\r
-modexShowPage(page_t *page) {\r
- word high_address;\r
- word low_address;\r
- word offset;\r
- byte crtcOffset;\r
-\r
- /* calculate offset */\r
- offset = (word) page->data;\r
- offset += page->dy * (page->width >> 2 );\r
- offset += page->dx >> 2;\r
-\r
- /* calculate crtcOffset according to virtual width */\r
- crtcOffset = page->width >> 3;\r
-\r
- high_address = HIGH_ADDRESS | (offset & 0xff00);\r
- low_address = LOW_ADDRESS | (offset << 8);\r
-\r
- /* wait for appropriate timing and then program CRTC */\r
- while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE));\r
- outpw(CRTC_INDEX, high_address);\r
- outpw(CRTC_INDEX, low_address);\r
- outp(CRTC_INDEX, 0x13);\r
- outp(CRTC_DATA, crtcOffset);\r
-\r
- /* wait for one retrace */\r
- while (!(inp(INPUT_STATUS_1) & VRETRACE)); \r
-\r
- /* do PEL panning here */\r
- outp(AC_INDEX, 0x33);\r
- outp(AC_INDEX, (page->dx & 0x03) << 1);\r
-}\r
-\r
-\r
-void\r
-modexPanPage(page_t *page, int dx, int dy) {\r
- page->dx = dx;\r
- page->dy = dy;\r
-}\r
-\r
-\r
-void\r
-modexSelectPlane(byte plane) {\r
- outp(SC_INDEX, MAP_MASK); /* select plane */\r
- outp(SC_DATA, plane);\r
-}\r
-\r
-\r
-void\r
-modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) {\r
- word pageOff = (word) page->data;\r
- word xoff=x/4; /* xoffset that begins each row */\r
- word scanCount=w/4; /* number of iterations per row (excluding right clip)*/\r
- word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */\r
- word nextRow = page->width/4-scanCount-1; /* loc of next row */\r
- byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */\r
- byte rclip[] = {0x00, 0x01, 0x03, 0x07};\r
- byte left = lclip[x&0x03];\r
- byte right = rclip[(x+w)&0x03];\r
-\r
- /* handle the case which requires an extra group */\r
- if((x & 0x03) && !((x+w) & 0x03)) {\r
- right=0x0f;\r
- }\r
-\r
- __asm {\r
- MOV AX, SCREEN_SEG ; go to the VGA memory\r
- MOV ES, AX\r
- MOV DI, poffset ; go to the first pixel\r
- MOV DX, SC_INDEX ; point to the map mask\r
- MOV AL, MAP_MASK\r
- OUT DX, AL\r
- INC DX\r
- MOV AL, color ; get ready to write colors\r
- SCAN_START:\r
- MOV CX, scanCount ; count the line\r
- MOV BL, AL ; remember color\r
- MOV AL, left ; do the left clip\r
- OUT DX, AL ; set the left clip\r
- MOV AL, BL ; restore color\r
- STOSB ; write the color\r
- DEC CX\r
- JZ SCAN_DONE ; handle 1 group stuff\r
-\r
- ;-- write the main body of the scanline\r
- MOV BL, AL ; remember color\r
- MOV AL, 0x0f ; write to all pixels\r
- OUT DX, AL\r
- MOV AL, BL ; restore color\r
- REP STOSB ; write the color\r
- SCAN_DONE:\r
- MOV BL, AL ; remeber color\r
- MOV AL, right\r
- OUT DX, AL ; do the right clip\r
- MOV AL, BL ; restore color\r
- STOSB ; write pixel\r
- ADD DI, nextRow ; go to the next row\r
- DEC h\r
- JNZ SCAN_START\r
- }\r
-}\r
-\r
-\r
-void\r
-modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) {\r
- /* draw the region (the entire freakin bitmap) */\r
- modexDrawBmpRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);\r
-}\r
-\r
-\r
-void\r
-modexDrawBmpRegion(page_t *page, int x, int y,\r
- int rx, int ry, int rw, int rh, bitmap_t *bmp) {\r
- word poffset = (word) page->data + y*(page->width/4) + x/4;\r
- byte *data = bmp->data;\r
- word bmpOffset = (word) data + ry * bmp->width + rx;\r
- word width = rw;\r
- word height = rh;\r
- byte plane = 1 << ((byte) x & 0x03);\r
- word scanCount = width/4 + (width%4 ? 1 :0);\r
- word nextPageRow = page->width/4 - scanCount;\r
- word nextBmpRow = (word) bmp->width - width;\r
- word rowCounter;\r
- byte planeCounter = 4;\r
-\r
- __asm {\r
- MOV AX, SCREEN_SEG ; go to the VGA memory\r
- MOV ES, AX\r
-\r
- MOV DX, SC_INDEX ; point at the map mask register\r
- MOV AL, MAP_MASK ;\r
- OUT DX, AL ;\r
-\r
- PLANE_LOOP:\r
- MOV DX, SC_DATA ; select the current plane\r
- MOV AL, plane ;\r
- OUT DX, AL ;\r
-\r
- ;-- begin plane painting\r
- MOV AX, height ; start the row counter\r
- MOV rowCounter, AX ; \r
- MOV DI, poffset ; go to the first pixel\r
- MOV SI, bmpOffset ; go to the bmp pixel\r
- ROW_LOOP:\r
- MOV CX, width ; count the columns\r
- SCAN_LOOP:\r
- MOVSB ; copy the pixel\r
- SUB CX, 3 ; we skip the next 3\r
- ADD SI, 3 ; skip the bmp pixels\r
- LOOP SCAN_LOOP ; finish the scan\r
-\r
- MOV AX, nextPageRow\r
- ADD DI, AX ; go to the next row on screen\r
- MOV AX, nextBmpRow\r
- ADD SI, AX ; go to the next row on bmp\r
-\r
- DEC rowCounter\r
- JNZ ROW_LOOP ; do all the rows\r
- ;-- end plane painting\r
-\r
- MOV AL, plane ; advance to the next plane\r
- SHL AL, 1 ;\r
- AND AL, 0x0f ; mask the plane properly\r
- MOV plane, AL ; store the plane\r
-\r
- INC bmpOffset ; start bmp at the right spot\r
-\r
- DEC planeCounter\r
- JNZ PLANE_LOOP ; do all 4 planes\r
- }\r
-}\r
-\r
-\r
-void\r
-modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) {\r
- /* draw the whole sprite */\r
- modexDrawSpriteRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp);\r
-}\r
-\r
-void\r
-modexDrawSpriteRegion(page_t *page, int x, int y,\r
- int rx, int ry, int rw, int rh, bitmap_t *bmp) {\r
- word poffset = (word)page->data + y*(page->width/4) + x/4;\r
- byte *data = bmp->data;\r
- word bmpOffset = (word) data + ry * bmp->width + rx;\r
- word width = rw;\r
- word height = rh;\r
- byte plane = 1 << ((byte) x & 0x03);\r
- word scanCount = width/4 + (width%4 ? 1 :0);\r
- word nextPageRow = page->width/4 - scanCount;\r
- word nextBmpRow = (word) bmp->width - width;\r
- word rowCounter;\r
- byte planeCounter = 4;\r
-\r
- __asm {\r
- MOV AX, SCREEN_SEG ; go to the VGA memory\r
- MOV ES, AX\r
-\r
- MOV DX, SC_INDEX ; point at the map mask register\r
- MOV AL, MAP_MASK ;\r
- OUT DX, AL ;\r
-\r
- PLANE_LOOP:\r
- MOV DX, SC_DATA ; select the current plane\r
- MOV AL, plane ;\r
- OUT DX, AL ;\r
-\r
- ;-- begin plane painting\r
- MOV AX, height ; start the row counter\r
- MOV rowCounter, AX ; \r
- MOV DI, poffset ; go to the first pixel\r
- MOV SI, bmpOffset ; go to the bmp pixel\r
- ROW_LOOP:\r
- MOV CX, width ; count the columns\r
- SCAN_LOOP:\r
- LODSB\r
- DEC SI\r
- CMP AL, 0\r
- JNE DRAW_PIXEL ; draw non-zero pixels\r
-\r
- INC DI ; skip the transparent pixel\r
- ADD SI, 1\r
- JMP NEXT_PIXEL\r
- DRAW_PIXEL:\r
- MOVSB ; copy the pixel\r
- NEXT_PIXEL:\r
- SUB CX, 3 ; we skip the next 3\r
- ADD SI, 3 ; skip the bmp pixels\r
- LOOP SCAN_LOOP ; finish the scan\r
-\r
- MOV AX, nextPageRow\r
- ADD DI, AX ; go to the next row on screen\r
- MOV AX, nextBmpRow\r
- ADD SI, AX ; go to the next row on bmp\r
-\r
- DEC rowCounter\r
- JNZ ROW_LOOP ; do all the rows\r
- ;-- end plane painting\r
-\r
- MOV AL, plane ; advance to the next plane\r
- SHL AL, 1 ;\r
- AND AL, 0x0f ; mask the plane properly\r
- MOV plane, AL ; store the plane\r
-\r
- INC bmpOffset ; start bmp at the right spot\r
-\r
- DEC planeCounter\r
- JNZ PLANE_LOOP ; do all 4 planes\r
- }\r
-}\r
-\r
-\r
-/* copy a region of video memory from one page to another.\r
- * It assumes that the left edge of the tile is the same on both\r
- * regions and the memory areas do not overlap.\r
- */\r
-void\r
-modexCopyPageRegion(page_t *dest, page_t *src,\r
- word sx, word sy,\r
- word dx, word dy,\r
- word width, word height)\r
-{\r
- word doffset = (word)dest->data + dy*(dest->width/4) + dx/4;\r
- word soffset = (word)src->data + sy*(src->width/4) + sx/4;\r
- word scans = width/4;\r
- word nextSrcRow = src->width/4 - scans - 1;\r
- word nextDestRow = dest->width/4 - scans - 1;\r
- byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */\r
- byte rclip[] = {0x0f, 0x01, 0x03, 0x07};\r
- byte left = lclip[sx&0x03];\r
- byte right = rclip[(sx+width)&0x03];\r
-\r
- __asm {\r
- MOV AX, SCREEN_SEG ; work in the vga space\r
- MOV ES, AX ;\r
- MOV DI, doffset ;\r
- MOV SI, soffset ;\r
-\r
- MOV DX, GC_INDEX ; turn off cpu bits\r
- MOV AX, 0008h ;\r
- OUT DX, AX\r
-\r
- MOV AX, SC_INDEX ; point to the mask register\r
- MOV DX, AX ;\r
- MOV AL, MAP_MASK ;\r
- OUT DX, AL ;\r
- INC DX ;\r
-\r
- ROW_START:\r
- PUSH DS\r
- MOV AX, ES\r
- MOV DS, AX\r
- MOV CX, scans ; the number of latches\r
-\r
- MOV AL, left ; do the left column\r
- OUT DX, AL ;\r
- MOVSB ;\r
- DEC CX ;\r
-\r
- MOV AL, 0fh ; do the inner columns\r
- OUT DX, AL\r
- REP MOVSB ; copy the pixels\r
-\r
- MOV AL, right ; do the right column\r
- OUT DX, AL\r
- MOVSB\r
- POP DS\r
-\r
- MOV AX, SI ; go the start of the next row\r
- ADD AX, nextSrcRow ;\r
- MOV SI, AX ;\r
- MOV AX, DI ;\r
- ADD AX, nextDestRow ;\r
- MOV DI, AX ;\r
-\r
- DEC height ; do the rest of the actions\r
- JNZ ROW_START ;\r
-\r
- MOV DX, GC_INDEX+1 ; go back to CPU data\r
- MOV AL, 0ffh ; none from latches\r
- OUT DX, AL ;\r
- }\r
-}\r
-\r
-\r
-/* fade and flash */\r
-void\r
-modexFadeOn(word fade, byte *palette) {\r
- fadePalette(-fade, 64, 64/fade+1, palette);\r
-}\r
-\r
-\r
-void\r
-modexFadeOff(word fade, byte *palette) {\r
- fadePalette(fade, 0, 64/fade+1, palette);\r
-}\r
-\r
-\r
-void\r
-modexFlashOn(word fade, byte *palette) {\r
- fadePalette(fade, -64, 64/fade+1, palette);\r
-}\r
-\r
-\r
-void\r
-modexFlashOff(word fade, byte *palette) {\r
- fadePalette(-fade, 0, 64/fade+1, palette);\r
-}\r
-\r
-\r
-static void\r
-fadePalette(sbyte fade, sbyte start, word iter, byte *palette) {\r
- word i;\r
- byte dim = start;\r
-\r
- /* handle the case where we just update */\r
- if(iter == 0) {\r
- modexPalUpdate(palette);\r
- return;\r
- }\r
-\r
- while(iter > 0) { /* FadeLoop */\r
- for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */\r
- tmppal[i] = palette[i] - dim;\r
- if(tmppal[i] > 127) {\r
- tmppal[i] = 0;\r
- } else if(tmppal[i] > 63) {\r
- tmppal[i] = 63;\r
- }\r
- }\r
- modexPalUpdate(tmppal);\r
- iter--;\r
- dim += fade;\r
- }\r
-}\r
-\r
-\r
-/* save and load */\r
-void\r
-modexPalSave(byte *palette) {\r
- int i;\r
-\r
- outp(PAL_READ_REG, 0); /* start at palette entry 0 */\r
- for(i=0; i<PAL_SIZE; i++) {\r
- palette[i] = inp(PAL_DATA_REG); /* read the palette data */\r
- }\r
-}\r
-\r
-\r
-byte *\r
-modexNewPal() {\r
- byte *ptr;\r
- ptr = malloc(PAL_SIZE);\r
-\r
- /* handle errors */\r
- if(!ptr) {\r
- printf("Could not allocate palette.\n");\r
- exit(-1);\r
- }\r
-\r
- return ptr;\r
-}\r
-\r
-\r
-void\r
-modexLoadPalFile(byte *filename, byte **palette) {\r
- FILE *file;\r
- byte *ptr;\r
-\r
- /* free the palette if it exists */\r
- if(*palette) {\r
- free(*palette);\r
- }\r
-\r
- /* allocate the new palette */\r
- *palette = modexNewPal();\r
-\r
- /* open the file */\r
- file = fopen(filename, "rb");\r
- if(!file) {\r
- printf("Could not open palette file: %s\n", filename);\r
- exit(-2);\r
- }\r
-\r
- /* read the file */\r
- ptr = *palette;\r
- while(!feof(file)) {\r
- *ptr++ = fgetc(file);\r
- }\r
-\r
- fclose(file);\r
-}\r
-\r
-\r
-void\r
-modexSavePalFile(char *filename, byte *pal) {\r
- unsigned int i;\r
- FILE *file;\r
-\r
- /* open the file for writing */\r
- file = fopen(filename, "wb");\r
- if(!file) {\r
- printf("Could not open %s for writing\n", filename);\r
- exit(-2);\r
- }\r
-\r
- /* write the data to the file */\r
- fwrite(pal, 1, PAL_SIZE, file);\r
- fclose(file);\r
-}\r
-\r
-\r
-/* blanking */\r
-void\r
-modexPalBlack() {\r
- fadePalette(-1, 64, 1, tmppal);\r
-}\r
-\r
-\r
-void\r
-modexPalWhite() {\r
- fadePalette(-1, -64, 1, tmppal);\r
-}\r
-\r
-\r
-/* utility */\r
-void\r
-modexPalUpdate(byte *p) {\r
- int i;\r
- modexWaitBorder();\r
- outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */\r
- for(i=0; i<PAL_SIZE/2; i++) {\r
- outp(PAL_DATA_REG, p[i]);\r
- }\r
- modexWaitBorder(); /* waits one retrace -- less flicker */\r
- for(i=PAL_SIZE/2; i<PAL_SIZE; i++) {\r
- outp(PAL_DATA_REG, p[i]);\r
- }\r
-}\r
-\r
-\r
-void\r
-modexWaitBorder() {\r
- while(inp(INPUT_STATUS_1) & 8) {\r
- /* spin */\r
- }\r
-\r
- while(!(inp(INPUT_STATUS_1) & 8)) {\r
- /* spin */\r
- }\r
-}\r
-\r
-\r
-bitmap_t\r
-modexLoadPcx(char *filename) {\r
- FILE *file;\r
- bitmap_t result;\r
- struct pcxHeader head;\r
- long bufSize;\r
- int index;\r
- byte count, val;\r
-\r
- /* open the PCX file for reading */\r
- file = fopen(filename, "rb");\r
- if(!file) {\r
- printf("Could not open %s for reading.\n", filename);\r
- exit(-2);\r
- }\r
-\r
- /* read the header */\r
- fread(&head, sizeof(char), sizeof(struct pcxHeader), file);\r
-\r
- /* make sure this is 8bpp */\r
- if(head.bpp != 8) {\r
- printf("I only know how to handle 8bpp pcx files!\n");\r
- fclose(file);\r
- exit(-2);\r
- }\r
-\r
- /* allocate the buffer */\r
- result.width = head.xmax - head.xmin + 1;\r
- result.height = head.ymax - head.ymin + 1;\r
- bufSize = result.width * result.height;\r
- result.data = malloc(bufSize);\r
- if(!result.data) {\r
- printf("Could not allocate memory for bitmap data.");\r
- fclose(file);\r
- exit(-1);\r
- }\r
-\r
- /* read the buffer in */\r
- index = 0;\r
- do {\r
- /* get the run length and the value */\r
- count = fgetc(file);\r
- if(0xC0 == (count & 0xC0)) { /* this is the run count */\r
- count &= 0x3f;\r
- val = fgetc(file);\r
- } else {\r
- val = count;\r
- count = 1;\r
- }\r
-\r
- /* write the pixel the specified number of times */\r
- for(; count && index < bufSize; count--,index++) {\r
- result.data[index] = val;\r
- }\r
- } while(index < bufSize);\r
-\r
- /* handle the palette */\r
- fseek(file, -769, SEEK_END);\r
- val = fgetc(file);\r
- result.palette = modexNewPal();\r
- if(head.version == 5 && val == 12) {\r
- /* use the vga palette */\r
- for(index=0; !feof(file) && index < PAL_SIZE; index++) {\r
- val = fgetc(file);\r
- result.palette[index] = val >> 2;\r
- }\r
- } else {\r
- /* use the 16 color palette */\r
- for(index=0; index<48; index++) {\r
- result.palette[index] = head.pal16[index];\r
- }\r
- }\r
-\r
- fclose(file);\r
-\r
- return result;\r
-}\r
+++ /dev/null
-/*\r
- * Functions for handling modex and doing other basic graphics stuff.\r
- */\r
-#ifndef MODEX16_H\r
-#define MODEX16_H\r
-#include <conio.h>\r
-#include "types.h"\r
-\r
-/* -========================== Types & Macros ==========================- */\r
-#define PAGE_OFFSET(x,y) (((y)<<6)+((y)<<4)+((x)>>2))\r
-#define PLANE(x) (1<< (x&3))\r
-#define SELECT_ALL_PLANES() outpw(0x03c4, 0xff02)\r
-typedef struct {\r
- byte *data;\r
- word width;\r
- word height;\r
- byte *palette;\r
-} bitmap_t;\r
-\r
-typedef struct {\r
- byte far* data; /* the data for the page */\r
- word dx; /* col we are viewing on the virtual screen */\r
- word dy; /* row we are viewing on the virtual screen */\r
- word width; /* virtual width of the page */\r
- word height; /* virtual height of the page */\r
-} page_t;\r
-\r
-/* -============================ Functions =============================- */\r
-/* mode switching, page, and plane functions */\r
-void modexEnter();\r
-void modexLeave();\r
-page_t modexDefaultPage();\r
-page_t modexNextPage(page_t *p);\r
-void modexShowPage(page_t *page);\r
-void modexPanPage(page_t *page, int dx, int dy);\r
-void modexSelectPlane(byte plane);\r
-void modexClearRegion(page_t *page, int x, int y, int w, int h, byte color);\r
-void modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp);\r
-void modexDrawBmpRegion(page_t *page, int x, int y, int rx, int ry, int rw, int rh, bitmap_t *bmp);\r
-void modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp);\r
-void modexDrawSpriteRegion(page_t *page, int x, int y, int rx, int ry, int rw, int rh, bitmap_t *bmp);\r
-\r
-/* Palette fade and flash effects */\r
-void modexFadeOn(word fade, byte *palette);\r
-void modexFadeOff(word fade, byte *palette);\r
-void modexFlashOn(word fade, byte *palette);\r
-void modexFlashOff(word fade, byte *palette);\r
-\r
-/* palette loading and saving */\r
-void modexPalSave(byte *palette);\r
-byte *modexNewPal();\r
-void modexLoadPalFile(char *filename, byte **palette);\r
-void modexSavePalFile(char *filename, byte *palette);\r
-\r
-/* fixed palette functions */\r
-void modexPalBlack();\r
-void modexPalWhite();\r
-\r
-/* utility functions */\r
-void modexPalUpdate(byte *p);\r
-void modexWaitBorder();\r
-\r
-/* bitmap functions */\r
-bitmap_t modexLoadPcx(char *filename);\r
-\r
-/* -======================= Constants & Vars ==========================- */\r
-extern byte far* VGA; /* The VGA Memory */\r
-#define SCREEN_SEG 0xa000\r
-#define VIDEO_INT 0x10\r
-#define SET_MODE 0x00\r
-#define VGA_256_COLOR_MODE 0x13\r
-#define TEXT_MODE 0x03\r
-#define SCREEN_WIDTH 320\r
-#define SCREEN_HEIGHT 240\r
-#define PAGE_SIZE (word)(SCREEN_WIDTH/4 * SCREEN_HEIGHT)\r
-\r
-#define AC_INDEX 0x03c0\r
-#define SC_INDEX 0x03c4\r
-#define SC_DATA 0x03c5\r
-#define CRTC_INDEX 0x03d4\r
-#define CRTC_DATA 0x03d5\r
-#define GC_INDEX 0x03ce\r
-#define MISC_OUTPUT 0x03c2\r
-#define HIGH_ADDRESS 0x0C\r
-#define LOW_ADDRESS 0x0D\r
-#define VRETRACE 0x08\r
-#define INPUT_STATUS_1 0x03da\r
-#define DISPLAY_ENABLE 0x01\r
-#define MAP_MASK 0x02\r
-#define PAL_READ_REG 0x03C7 /* Color register, read address */\r
-#define PAL_WRITE_REG 0x03C8 /* Color register, write address */\r
-#define PAL_DATA_REG 0x03C9 /* Color register, data port */\r
-#define PAL_SIZE (256 * 3)\r
-#endif\r