X-Git-Url: http://4ch.mooo.com/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fmodex16.c;h=ea059d82d2c58837413e8dba0e2adc643c697cdb;hb=ddf0f7c950011c570d0c0a35ad9b2dea8d5d1160;hp=10c5e9c8a1ea165958f1926037e29383089ad935;hpb=9ffe77d9a59bd77df9ab71eb98e82c97a1fa6076;p=16.git diff --git a/src/lib/modex16.c b/src/lib/modex16.c old mode 100644 new mode 100755 index 10c5e9c8..ea059d82 --- a/src/lib/modex16.c +++ b/src/lib/modex16.c @@ -20,9 +20,6 @@ * */ -#include -#include -#include #include #include #include @@ -33,6 +30,35 @@ byte far* VGA=(byte far*) 0xA0000000; /* this points to video memory. */ static void fadePalette(sbyte fade, sbyte start, word iter, byte *palette); static byte tmppal[PAL_SIZE]; +///////////////////////////////////////////////////////////////////////////// +// // +// setvideo() - This function Manages the video modes // +// // +///////////////////////////////////////////////////////////////////////////// +void VGAmodeX(sword vq, global_game_variables_t *gv) +{ + union REGS in, out; + + switch (vq) + { + case 0: // deinit the video + // change to the video mode we were in before we switched to mode 13h + modexLeave(); + in.h.ah = 0x00; + in.h.al = gv->video.old_mode; + int86(0x10, &in, &out); + break; + default: // init the video + // get old video mode + //in.h.ah = 0xf; + //int86(0x10, &in, &out); + gv->video.old_mode = vgaGetMode();//out.h.al; + // enter mode + modexEnter(vq, gv); + break; + } +} + static void vgaSetMode(byte mode) { @@ -43,76 +69,169 @@ vgaSetMode(byte mode) int86(VIDEO_INT, ®s, ®s); } +//--------------------------------------------------- +// +// Use the bios to get the current video mode +// + +long +vgaGetMode() +{ + union REGS rg; + + rg.h.ah = 0x0f; + int86(VIDEO_INT, &rg, &rg); + + return rg.h.al; +} /* -========================= Entry Points ==========================- */ void -modexEnter() { - word i; - dword far*ptr=(dword far*)VGA; /* used for faster screen clearing */ - word CRTParms[] = { - 0x0d06, /* vertical total */ - 0x3e07, /* overflow (bit 8 of vertical counts) */ - 0x4109, /* cell height (2 to double-scan */ - 0xea10, /* v sync start */ - 0xac11, /* v sync end and protect cr0-cr7 */ - 0xdf12, /* vertical displayed */ - 0x0014, /* turn off dword mode */ - 0xe715, /* v blank start */ - 0x0616, /* v blank end */ - 0xe317 /* turn on byte mode */ - }; - int CRTParmCount = sizeof(CRTParms) / sizeof(CRTParms[0]); - - /* TODO save current video mode and palette */ - vgaSetMode(VGA_256_COLOR_MODE); - - /* disable chain4 mode */ - outpw(SC_INDEX, 0x0604); - - /* synchronous reset while setting Misc Output */ - outpw(SC_INDEX, 0x0100); - - /* select 25 MHz dot clock & 60 Hz scanning rate */ - outp(MISC_OUTPUT, 0xe3); - - /* undo reset (restart sequencer) */ - outpw(SC_INDEX, 0x0300); - - /* reprogram the CRT controller */ - outp(CRTC_INDEX, 0x11); /* VSync End reg contains register write prot */ - outp(CRTC_DATA, 0x7f); /* get current write protect on varios regs */ - - /* send the CRTParms */ - for(i=0; ivideo.page); - /* clear video memory */ - outpw(SC_INDEX, 0x0f02); - for(i=0; i<0x8000; i++) { - ptr[i] = 0x0000; - } + switch(vq) + { + case 1: + CRTParmCount = sizeof(ModeX_320x240regs) / sizeof(ModeX_320x240regs[0]); + /* width and height */ + gv->video.page[0].sw=320; + gv->video.page[0].sh=240; + + /* send the CRTParms */ + for(i=0; ivideo.page[0].sw=192; + gv->video.page[0].sh=144; + + /* send the CRTParms */ + for(i=0; ivideo.page[0].sw=320; + gv->video.page[0].sh=200; + + /* send the CRTParms */ + for(i=0; ivideo.page[0].sw=256; + gv->video.page[0].sh=192; + + /* send the CRTParms */ + for(i=0; ivideo.page[0].tilesw = gv->video.page[0].sw/TILEWH; + gv->video.page[0].tilesh = gv->video.page[0].sh/TILEWH; + //TODO MAKE FLEXIBLE~ + gv->video.page[0].tilemidposscreenx = gv->video.page[0].tilesw; + gv->video.page[0].tilemidposscreeny = (gv->video.page[0].tilesh/2)+1; + #define PAGE_SIZE (word)(gv->video.page[0].sw/4 * gv->video.page[0].sh) } - void modexLeave() { /* TODO restore original mode and palette */ vgaSetMode(TEXT_MODE); } +// setBaseXMode() does the initialization to make the VGA ready to +// accept any combination of configuration register settings. This +// involves enabling writes to index 0 to 7 of the CRT controller (port +// 0x3D4), by clearing the most significant bit (bit 7) of index 0x11. +void +modexsetBaseXMode(page_t *page) +{ + word temp; + /* TODO save current video mode and palette */ + vgaSetMode(VGA_256_COLOR_MODE); + + /* disable chain4 mode */ + outpw(SC_INDEX, 0x0604); + + /* synchronous reset while setting Misc Output */ + outpw(SC_INDEX, 0x0100); + + /* select 25 MHz dot clock & 60 Hz scanning rate */ + outp(MISC_OUTPUT, 0xe3); + + /* undo reset (restart sequencer) */ + outpw(SC_INDEX, 0x0300); + + /* reprogram the CRT controller */ + outp(CRTC_INDEX, 0x11); /* VSync End reg contains register write prot */ +// temp = inp(CRTC_DATA) & 0x7F; +// outp(CRTC_INDEX, 0x11); + outp(CRTC_DATA, 0x7f); /* get current write protect on varios regs */ +// outp(CRTC_DATA, temp); /* get current write protect on varios regs */ +} page_t -modexDefaultPage() { +modexDefaultPage(page_t *p) +{ page_t page; /* default page values */ page.data = VGA; page.dx = 0; page.dy = 0; - page.width = SCREEN_WIDTH; - page.height = SCREEN_HEIGHT; - page.id = 0; + page.sw = p->sw; + page.sh = p->sh; + page.width = p->sw; + page.height = p->sh; + page.tw = page.sw/TILEWH; + page.th = page.sh/TILEWH; + page.tilemidposscreenx = page.tw/2; + page.tilemidposscreeny = (page.th/2)+1; + page.tilesw=p->tilesw; + page.tilesh=p->tilesh; + //pageSize = p->sw*p->sh; + page.id = 0; return page; } @@ -124,30 +243,35 @@ page_t modexNextPage(page_t *p) { page_t result; - result.data = p->data + (p->width/4)*p->height; /* compute the offset */ + result.data = p->data + (p->width/4)*p->height; result.dx = 0; result.dy = 0; result.width = p->width; result.height = p->height; - result.id = p->id+1; + result.tw = p->width/TILEWH; + result.th = p->height/TILEWH; + result.id = p->id+1; - return result; + return result; +// return modexNextPageFlexibleSize(&p, p->width, p->height); } //next page with defined dimentions~ page_t -modexNextPage0(page_t *p, word x, word y) +modexNextPageFlexibleSize(page_t *p, word x, word y) { - page_t result; - - result.data = p->data + (p->width/4)*p->height; /* compute the offset */ - result.dx = 0; - result.dy = 0; - result.width = x; - result.height = y; - result.id = p->id+1; - - return result; + page_t result; + + result.data = p->data + (p->width/4)*p->height; /* compute the offset */ + result.dx = 0; + result.dy = 0; + result.width = x; + result.height = y; + result.tw = p->width/TILEWH; + result.th = p->height/TILEWH; + result.id = p->id+1; + + return result; } @@ -257,24 +381,46 @@ modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) { void oldDrawBmp(byte far* page, int x, int y, bitmap_t *bmp, byte sprite) { - byte plane; - word px, py; - word offset; - - /* TODO Make this fast. It's SLOOOOOOW */ - for(plane=0; plane < 4; plane++) { - modexSelectPlane(PLANE(plane+x)); - for(px = plane; px < bmp->width; px+=4) { - offset=px; - for(py=0; pyheight; py++) { - if(!sprite || bmp->data[offset]) - page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset]; - offset+=bmp->width; - } - } - } + byte plane; + word px, py; + word offset; + + /* TODO Make this fast. It's SLOOOOOOW */ + for(plane=0; plane < 4; plane++) { + modexSelectPlane(PLANE(plane+x)); + for(px = plane; px < bmp->width; px+=4) { + offset=px; + for(py=0; pyheight; py++) { + if(!sprite || bmp->data[offset]) + page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset]; + offset+=bmp->width; + } + } + } } +void +CDrawBmp(byte far* vgamem, page_t* page, int x, int y, bitmap_t *bmp, byte sprite) +{ + byte plane; + word px, py; + word offset=0; + + + /* TODO Make this fast. It's SLOOOOOOW */ + for(plane=0; plane < 4; plane++) { + modexSelectPlane(PLANE(plane+x)); + for(px = plane; px < bmp->width; px+=4) { + offset=px; + for(py=0; pyheight; py++) { + if(!sprite || bmp->data[offset]) + //modexputPixel(page, x+px, y+py, bmp->data[offset]); + vgamem[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset]; + offset+=bmp->width; + } + } + } +} void modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) { @@ -282,12 +428,11 @@ modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) { modexDrawBmpRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp); } - void modexDrawBmpRegion(page_t *page, int x, int y, int rx, int ry, int rw, int rh, bitmap_t *bmp) { word poffset = (word) page->data + y*(page->width/4) + x/4; - byte *data = bmp->data;//+bmp->offset; + byte far *data = bmp->data;//+bmp->offset; word bmpOffset = (word) data + ry * bmp->width + rx; word width = rw; word height = rh; @@ -298,6 +443,10 @@ modexDrawBmpRegion(page_t *page, int x, int y, word rowCounter; byte planeCounter = 4; +/* printf("bmp->data=%Fp\n",bmp->data); + printf("*bmp->data=%Fp\n",*(bmp->data)); + printf("&bmp->data=%Fp\n",&(bmp->data));*/ + //code is a bit slow here __asm { MOV AX, SCREEN_SEG ; go to the VGA memory @@ -346,7 +495,6 @@ modexDrawBmpRegion(page_t *page, int x, int y, } } - void modexDrawPlanarBuf(page_t *page, int x, int y, planar_buf_t *bmp) { /* TODO - adapt from test code */ @@ -364,6 +512,78 @@ modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) { modexDrawSpriteRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp); } +/*void +modexDrawSpriteRegion(page_t *page, int x, int y, + int rx, int ry, int rw, int rh, bitmap_t *bmp) { + word poffset = (word)page->data + y*(page->width/4) + x/4; + byte *data = bmp->data;//+bmp->offset; + word bmpOffset = (word) data + ry * bmp->width + rx; + word width = rw; + word height = rh; + byte plane = 1 << ((byte) x & 0x03); + word scanCount = width/4 + (width%4 ? 1 :0); + word nextPageRow = page->width/4 - scanCount; + word nextBmpRow = (word) bmp->width - width; + word rowCounter; + byte planeCounter = 4; + + __asm { + MOV AX, SCREEN_SEG ; go to the VGA memory + MOV ES, AX + + MOV DX, SC_INDEX ; point at the map mask register + MOV AL, MAP_MASK ; + OUT DX, AL ; + + PLANE_LOOP: + MOV DX, SC_DATA ; select the current plane + MOV AL, plane ; + OUT DX, AL ; + + ;-- begin plane painting + MOV AX, height ; start the row counter + MOV rowCounter, AX ; + MOV DI, poffset ; go to the first pixel + MOV SI, bmpOffset ; go to the bmp pixel + ROW_LOOP: + MOV CX, width ; count the columns + SCAN_LOOP: + LODSB + DEC SI + CMP AL, 0 + JNE DRAW_PIXEL ; draw non-zero pixels + + INC DI ; skip the transparent pixel + ADD SI, 1 + JMP NEXT_PIXEL + DRAW_PIXEL: + MOVSB ; copy the pixel + NEXT_PIXEL: + SUB CX, 3 ; we skip the next 3 + ADD SI, 3 ; skip the bmp pixels + LOOP SCAN_LOOP ; finish the scan + + MOV AX, nextPageRow + ADD DI, AX ; go to the next row on screen + MOV AX, nextBmpRow + ADD SI, AX ; go to the next row on bmp + + DEC rowCounter + JNZ ROW_LOOP ; do all the rows + ;-- end plane painting + + MOV AL, plane ; advance to the next plane + SHL AL, 1 ; + AND AL, 0x0f ; mask the plane properly + MOV plane, AL ; store the plane + + INC bmpOffset ; start bmp at the right spot + + DEC planeCounter + JNZ PLANE_LOOP ; do all 4 planes + } +}//backup!*/ + void modexDrawSpriteRegion(page_t *page, int x, int y, int rx, int ry, int rw, int rh, bitmap_t *bmp) { @@ -436,7 +656,6 @@ modexDrawSpriteRegion(page_t *page, int x, int y, } } - /* copy a region of video memory from one page to another. * It assumes that the left edge of the tile is the same on both * regions and the memory areas do not overlap. @@ -943,85 +1162,90 @@ no... wait.... no wwww } void modexputPixel(page_t *page, int x, int y, byte color) -{ +{ word pageOff = (word) page->data; /* Each address accesses four neighboring pixels, so set Write Plane Enable according to which pixel we want to modify. The plane is determined by the two least - significant bits of the x-coordinate: */ - //modexSelectPlane(PLANE(x)); - outp(SC_INDEX, 0x02); - outp(SC_DATA, 0x01 << (x & 3)); + significant bits of the x-coordinate: */ + modexSelectPlane(PLANE(x)); + //outp(SC_INDEX, 0x02); + //outp(SC_DATA, 0x01 << (x & 3)); /* The offset of the pixel into the video segment is offset = (width * y + x) / 4, and write the given color to the plane we selected above. Heed the active page start selection. */ - VGA[(unsigned)((SCREEN_WIDTH/4) * y) + (x / 4) + pageOff] = color; + VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff] = color; } byte modexgetPixel(page_t *page, int x, int y) -{ +{ word pageOff = (word) page->data; /* Select the plane from which we must read the pixel color: */ outpw(GC_INDEX, 0x04); outpw(GC_INDEX+1, x & 3); - return VGA[(unsigned)((SCREEN_WIDTH/4) * y) + (x / 4) + pageOff]; + return VGA[(unsigned)((page->width/4) * y) + (x / 4) + pageOff]; -} - -void modexhlin(page_t *page, word xl, word xh, word y, word color) -{ - word x; - - for(x=0;x=page[0].sw-1){ x=0; yy+=4; } + modexClearRegion(page, x+xl, y+yy, 4, 4, color); + } + //modexputPixel(page, x+xl, y, color); } void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str) -{ - word i, s, o, w, j, xp; +{ + word i, s, o, w, j, xp; byte l[1024]; - word addr = (word) l; - word chw=0; - byte c; - + word addr = (word) l; + word chw=0; + byte c; + switch(t) { - case 0: + case 0: w=14; break; - case 1: + case 1: w=8; break; - case 2: + case 2: w=8; break; - case 3: + case 3: w=16; break; - default: + default: t=3; w=16; break; - } + } s=romFonts[t].seg; - o=romFonts[t].off; + o=romFonts[t].off; for(; *str != '\0'; str++) - { - c = (*str); - if((c=='\n'/* || c=="\ -"*/) || chw ->=page->width) - { - chw=0; - y+=w; - continue; - } + { + c = (*str); + if((c=='\n'/* || c=="\ +"*/) || chw +>=page->width) + { + chw=0; + y+=w; + continue; + } //load the letter 'A' __asm { MOV DI, addr @@ -1038,64 +1262,64 @@ void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, cons INC DI DEC CX JNZ L1 - } + } - for(i=0; i>=1; - } + while(j) + { + modexputPixel(page, x+xp+chw, y+i, l[i] & j ? col:bgcol); + xp++; + j>>=1; + } } chw += xp; } -} - +} + void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str) -{ - word i, s, o, w, j, xp; +{ + word i, s, o, w, j, xp; byte l[1024]; - word addr = (word) l; - word chw=0; - byte c; - + word addr = (word) l; + word chw=0; + byte c; + switch(t) { - case 0: + case 0: w=14; break; - case 1: + case 1: w=8; break; - case 2: + case 2: w=8; break; - case 3: + case 3: w=16; break; - default: + default: t=3; w=16; break; - } + } s=romFonts[t].seg; - o=romFonts[t].off; + o=romFonts[t].off; for(; *str != '\0'; str++) - { - c = (*str); - if((c=='\n'/* || c=="\ -"*/)/* || chw>=page->width*/) - { - chw=0; - y+=w; - continue; - } + { + c = (*str); + if((c=='\n'/* || c=="\ +"*/)/* || chw>=page->width*/) + { + chw=0; + y+=w; + continue; + } //load the letter 'A' __asm { MOV DI, addr @@ -1112,24 +1336,54 @@ void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, c INC DI DEC CX JNZ L1 - } + } - for(i=0; i>=1; - } + 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; + } } chw += xp; } } +/* palette dump on display! */ +void pdump(page_t *pee) +{ + int mult=(QUADWH); + int palq=(mult)*TILEWH; + int palcol=0; + int palx, paly; + for(paly=0; palywidth, page->height, color); + /* set map mask to all 4 planes */ + outpw(SC_INDEX, 0xff02); + //_fmemset(VGA, color, 16000); + _fmemset(Where, color, page->width*(page->height)); +} + void modexWaitBorder() { while(inp(INPUT_STATUS_1) & 8) {