*\r
*/\r
\r
-#include <dos.h>\r
-#include <string.h>\r
-#include <mem.h>\r
#include <conio.h>\r
#include <stdio.h>\r
#include <stdlib.h>\r
\r
static void fadePalette(sbyte fade, sbyte start, word iter, byte *palette);\r
static byte tmppal[PAL_SIZE];\r
+//int old_mode;\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+// //\r
+// setvideo() - This function Manages the video modes //\r
+// //\r
+/////////////////////////////////////////////////////////////////////////////\r
+void VGAmodeX(sword vq, global_game_variables_t *gv)\r
+{\r
+ union REGS in, out;\r
+\r
+ if(!vq)\r
+ { // deinit the video\r
+ // change to the video mode we were in before we switched to mode 13h\r
+ modexLeave();\r
+ in.h.ah = 0x00;\r
+ in.h.al = gv->old_mode;\r
+ int86(0x10, &in, &out);\r
+\r
+ }\r
+ else if(vq==1)\r
+ { // init the video\r
+ // get old video mode\r
+ in.h.ah = 0xf;\r
+ int86(0x10, &in, &out);\r
+ gv->old_mode = out.h.al;\r
+ // enter mode\r
+ modex__320x240_256__Enter(gv);\r
+ }\r
+}\r
\r
static void\r
vgaSetMode(byte 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
+modex__320x240_256__Enter(global_game_variables_t *gv)\r
+{\r
+ word i;\r
+ dword far*ptr=(dword far*)VGA; /* used for faster screen clearing */\r
+ word CRTParms[] = {\r
+// 0xe300, /* horizontal total */\r
+ 0x4f01, /* horizontal display enable end */\r
+ 0x5002, /* */\r
+ 0x5404, /* */\r
+ 0x8005, /* */\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
+ 0x2813, /* offset/logical width */\r
+ 0x0014, /* turn off dword mode */\r
+ 0xe715, /* v blank start */\r
+ 0x0616, /* v blank end */\r
+ 0xe317 /* turn on byte mode */\r
+ };\r
+\r
+ int CRTParmCount = sizeof(CRTParms) / sizeof(CRTParms[0]);\r
+ /* width and height */\r
+ //TODO WWWW\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
+ /* clear video memory */\r
+ outpw(SC_INDEX, 0x0f02);\r
+ for(i=0; i<0x8000; i++) {\r
+ ptr[i] = 0x0000;\r
+ }\r
}\r
\r
+// setBaseXMode() does the initialization to make the VGA ready to\r
+// accept any combination of configuration register settings. This\r
+// involves enabling writes to index 0 to 7 of the CRT controller (port\r
+// 0x3D4), by clearing the most significant bit (bit 7) of index 0x11.\r
+void\r
+modexsetBaseXMode(void)\r
+{\r
+ int temp;\r
+\r
+ /* TODO save current video mode and palette */\r
+ vgaSetMode(VGA_256_COLOR_MODE);\r
+\r
+ outp(CRTC_INDEX, 0x11);\r
+ temp = inp(CRTC_DATA) & 0x7F;\r
+ outp(CRTC_INDEX, 0x11);\r
+ outp(CRTC_DATA, temp);\r
+}\r
\r
void\r
modexLeave() {\r
page.dy = 0;\r
page.width = SCREEN_WIDTH;\r
page.height = SCREEN_HEIGHT;\r
- page.id = 0;\r
+ page.tw = page.width/TILEWH;\r
+ page.th = page.height/TILEWH;\r
+ page.id = 0;\r
\r
return page;\r
}\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.data = p->data + (p->width/4)*p->height;\r
result.dx = 0;\r
result.dy = 0;\r
result.width = p->width;\r
result.height = p->height;\r
- result.id = p->id+1;\r
+ result.tw = p->width/TILEWH;\r
+ result.th = p->height/TILEWH;\r
+ result.id = p->id+1;\r
\r
- return result;\r
+ return result;\r
+// return modexNextPageFlexibleSize(&p, p->width, p->height);\r
}\r
\r
//next page with defined dimentions~\r
page_t\r
-modexNextPage0(page_t *p, word x, word y)\r
+modexNextPageFlexibleSize(page_t *p, word x, word y)\r
{\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 = x;\r
- result.height = y;\r
- result.id = p->id+1;\r
-\r
- return result;\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 = x;\r
+ result.height = y;\r
+ result.tw = p->width/TILEWH;\r
+ result.th = p->height/TILEWH;\r
+ result.id = p->id+1;\r
+\r
+ return result;\r
}\r
\r
\r
void\r
oldDrawBmp(byte far* page, int x, int y, bitmap_t *bmp, byte sprite)\r
{\r
- byte plane;\r
- word px, py;\r
- word offset;\r
-\r
- /* TODO Make this fast. It's SLOOOOOOW */\r
- for(plane=0; plane < 4; plane++) {\r
- modexSelectPlane(PLANE(plane+x));\r
- for(px = plane; px < bmp->width; px+=4) {\r
- offset=px;\r
- for(py=0; py<bmp->height; py++) {\r
- if(!sprite || bmp->data[offset])\r
- page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];\r
- offset+=bmp->width;\r
- }\r
- }\r
- }\r
+ byte plane;\r
+ word px, py;\r
+ word offset;\r
+\r
+ /* TODO Make this fast. It's SLOOOOOOW */\r
+ for(plane=0; plane < 4; plane++) {\r
+ modexSelectPlane(PLANE(plane+x));\r
+ for(px = plane; px < bmp->width; px+=4) {\r
+ offset=px;\r
+ for(py=0; py<bmp->height; py++) {\r
+ if(!sprite || bmp->data[offset])\r
+ page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];\r
+ offset+=bmp->width;\r
+ }\r
+ }\r
+ }\r
}\r
\r
+void\r
+CDrawBmp(byte far* vgamem, page_t* page, int x, int y, bitmap_t *bmp, byte sprite)\r
+{\r
+ byte plane;\r
+ word px, py;\r
+ word offset=0;\r
+\r
+\r
+ /* TODO Make this fast. It's SLOOOOOOW */\r
+ for(plane=0; plane < 4; plane++) {\r
+ modexSelectPlane(PLANE(plane+x));\r
+ for(px = plane; px < bmp->width; px+=4) {\r
+ offset=px;\r
+ for(py=0; py<bmp->height; py++) {\r
+ if(!sprite || bmp->data[offset])\r
+ //modexputPixel(page, x+px, y+py, bmp->data[offset]);\r
+ vgamem[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset];\r
+ offset+=bmp->width;\r
+ }\r
+ }\r
+ }\r
+}\r
\r
void\r
modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) {\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;//+bmp->offset;\r
+ byte far *data = bmp->data;//+bmp->offset;\r
word bmpOffset = (word) data + ry * bmp->width + rx;\r
word width = rw;\r
word height = rh;\r
word rowCounter;\r
byte planeCounter = 4;\r
\r
+/* printf("bmp->data=%Fp\n",bmp->data);\r
+ printf("*bmp->data=%Fp\n",*(bmp->data));\r
+ printf("&bmp->data=%Fp\n",&(bmp->data));*/\r
+\r
//code is a bit slow here\r
__asm {\r
MOV AX, SCREEN_SEG ; go to the VGA memory\r
}\r
}\r
\r
+void\r
+modex_sparky4_DrawBmpRegion(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 far *data = bmp->data;//+bmp->offset;\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
+/* printf("bmp->data=%Fp\n",bmp->data);\r
+ printf("*bmp->data=%Fp\n",*(bmp->data));\r
+ printf("&bmp->data=%Fp\n",&(bmp->data));*/\r
+\r
+ //code is a bit slow here\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
void\r
modexDrawPlanarBuf(page_t *page, int x, int y, planar_buf_t *bmp) {\r
}\r
\r
void modexputPixel(page_t *page, int x, int y, byte color)\r
-{
+{\r
word pageOff = (word) page->data;\r
/* Each address accesses four neighboring pixels, so set\r
Write Plane Enable according to which pixel we want\r
to modify. The plane is determined by the two least\r
- significant bits of the x-coordinate: */
- //modexSelectPlane(PLANE(x));\r
- outp(SC_INDEX, 0x02);\r
- outp(SC_DATA, 0x01 << (x & 3));\r
+ significant bits of the x-coordinate: */\r
+ modexSelectPlane(PLANE(x));\r
+ //outp(SC_INDEX, 0x02);\r
+ //outp(SC_DATA, 0x01 << (x & 3));\r
\r
/* The offset of the pixel into the video segment is\r
offset = (width * y + x) / 4, and write the given\r
color to the plane we selected above. Heed the active\r
page start selection. */\r
- VGA[(unsigned)((SCREEN_WIDTH/4) * y) + (x / 4) + pageOff] = color;\r
+ VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color;\r
\r
}\r
\r
-byte modexgetPixel(int x, int y)\r
+byte modexgetPixel(page_t *page, int x, int y)\r
{\r
+ word pageOff = (word) page->data;\r
/* Select the plane from which we must read the pixel color: */\r
outpw(GC_INDEX, 0x04);\r
outpw(GC_INDEX+1, x & 3);\r
\r
- return VGA[(unsigned)((SCREEN_WIDTH/4) * y) + (x / 4) + 0];\r
+ return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff];\r
\r
}\r
\r
+void modexhlin(page_t *page, word xl, word xh, word y, word color)\r
+{\r
+ word x;\r
+ word yy=0;\r
+\r
+ for(x=0;x<xh*4;x+=4)\r
+ {\r
+ if(x+4>=SCREEN_WIDTH-1){ x=0; yy+=4; }\r
+ modexClearRegion(page, x+xl, y+yy, 4, 4, color);\r
+ }\r
+ //modexputPixel(page, x+xl, y, color);\r
+}\r
+\r
void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)\r
-{
- word i, s, o, w, j, xp;
+{\r
+ word i, s, o, w, j, xp;\r
byte l[1024];\r
- word addr = (word) l;
- word chw=0;
- byte c;
-
+ word addr = (word) l;\r
+ word chw=0;\r
+ byte c;\r
+\r
switch(t)\r
{\r
- case 0:
+ case 0:\r
w=14;\r
break;\r
- case 1:
+ case 1:\r
w=8;\r
break;\r
- case 2:
+ case 2:\r
w=8;\r
break;\r
- case 3:
+ case 3:\r
w=16;\r
break;\r
- default:
+ default:\r
t=3;\r
w=16;\r
break;\r
- }
+ }\r
\r
s=romFonts[t].seg;\r
- o=romFonts[t].off;
+ o=romFonts[t].off;\r
\r
for(; *str != '\0'; str++)\r
- {
- c = (*str);
- if((c=='\n'/* || c=="\
-"*/) || chw
->=page->width)
- {
- chw=0;
- y+=w;
- continue;
- }
+ {\r
+ c = (*str);\r
+ if((c=='\n'/* || c=="\\r
+"*/) || chw\r
+>=page->width)\r
+ {\r
+ chw=0;\r
+ y+=w;\r
+ continue;\r
+ }\r
//load the letter 'A'\r
__asm {\r
MOV DI, addr\r
INC DI\r
DEC CX\r
JNZ L1\r
- }
+ }\r
\r
- for(i=0; i<w; i++)
+ for(i=0; i<w; i++)\r
{\r
- j=1<<8;
+ j=1<<8;\r
xp=0;\r
- while(j)
- {
- modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
- xp++;
- j>>=1;
- }
+ while(j)\r
+ {\r
+ modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);\r
+ xp++;\r
+ j>>=1;\r
+ }\r
}\r
chw += xp;\r
}\r
-}
-
+}\r
+\r
void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)\r
-{
- word i, s, o, w, j, xp;
+{\r
+ word i, s, o, w, j, xp;\r
byte l[1024];\r
- word addr = (word) l;
- word chw=0;
- byte c;
-
+ word addr = (word) l;\r
+ word chw=0;\r
+ byte c;\r
+\r
switch(t)\r
{\r
- case 0:
+ case 0:\r
w=14;\r
break;\r
- case 1:
+ case 1:\r
w=8;\r
break;\r
- case 2:
+ case 2:\r
w=8;\r
break;\r
- case 3:
+ case 3:\r
w=16;\r
break;\r
- default:
+ default:\r
t=3;\r
w=16;\r
break;\r
- }
+ }\r
\r
s=romFonts[t].seg;\r
- o=romFonts[t].off;
+ o=romFonts[t].off;\r
\r
for(; *str != '\0'; str++)\r
- {
- c = (*str);
- if((c=='\n'/* || c=="\
-"*/)/* || chw>=page->width*/)
- {
- chw=0;
- y+=w;
- continue;
- }
+ {\r
+ c = (*str);\r
+ if((c=='\n'/* || c=="\\r
+"*/)/* || chw>=page->width*/)\r
+ {\r
+ chw=0;\r
+ y+=w;\r
+ continue;\r
+ }\r
//load the letter 'A'\r
__asm {\r
MOV DI, addr\r
INC DI\r
DEC CX\r
JNZ L1\r
- }
+ }\r
\r
- for(i=0; i<w; i++)
+ for(i=0; i<w; i++)\r
{\r
- j=1<<8;
+ j=1<<8;\r
xp=0;\r
- while(j)
- {
- //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);
- modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);
- xp++;
- j>>=1;
- }
+ while(j)\r
+ {\r
+ //modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol);\r
+ modexClearRegion(page, (x+xp+chw)*8, (y+i)*8, 8, 8, l[i] & j ? col:bgcol);\r
+ xp++;\r
+ j>>=1;\r
+ }\r
}\r
chw += xp;\r
}\r
}\r
\r
+/////////////////////////////////////////////////////////////////////////////\r
+// //\r
+// cls() - This clears the screen to the specified color, on the VGA or on //\r
+// the Virtual screen. //\r
+// //\r
+/////////////////////////////////////////////////////////////////////////////\r
+void cls(page_t *page, byte color, byte *Where)\r
+{\r
+ //modexClearRegion(page, 0, 0, page->width, page->height, color);\r
+ /* set map mask to all 4 planes */\r
+ outpw(SC_INDEX, 0xff02);\r
+ //_fmemset(VGA, color, 16000);\r
+ _fmemset(Where, color, page->width*(page->height));\r
+}\r
+\r
void\r
modexWaitBorder() {\r
while(inp(INPUT_STATUS_1) & 8) {\r