]> 4ch.mooo.com Git - 16.git/blobdiff - src/lib/modex16.c
wwww
[16.git] / src / lib / modex16.c
index 2246595c58dbb7d73e5f974a2f6d1a975544f3bc..2e6d148934df1e2d2540c4e307015d203e1f815e 100755 (executable)
@@ -85,6 +85,9 @@ void modexEnter(sword vq, boolean cmem, global_game_variables_t *gv)
 \r
        vgaSetMode(VGA_256_COLOR_MODE);\r
        vga_enable_256color_modex();\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
        update_state_from_vga();\r
        vga_read_crtc_mode(&cm);\r
 \r
@@ -92,9 +95,15 @@ void modexEnter(sword vq, boolean cmem, global_game_variables_t *gv)
        {\r
                case 1:\r
                        //CRTParmCount = sizeof(ModeX_320x240regs) / sizeof(ModeX_320x240regs[0]);\r
+                       /*for(i=0; i<CRTParmCount; i++) {\r
+                               outpw(CRTC_INDEX, ModeX_320x240regs[i]);\r
+                       }*/\r
                        /* width and height */\r
                        gv->video.page[0].sw = vga_state.vga_width = 320; // VGA lib currently does not update this\r
                        gv->video.page[0].sh = vga_state.vga_height = 240; // VGA lib currently does not update this\r
+                       /* virtual width and height. match screen, at first */\r
+                       gv->video.page[0].height = gv->video.page[0].sh;\r
+                       gv->video.page[0].width = gv->video.page[0].sw;\r
 \r
                        // mode X BYTE mode\r
                        cm.word_mode = 0;\r
@@ -114,7 +123,7 @@ void modexEnter(sword vq, boolean cmem, global_game_variables_t *gv)
                        cm.vertical_display_end = 480;\r
                        cm.vertical_blank_start = 0x1E7 + 1;\r
                        cm.vertical_blank_end = 0x206 + 1;\r
-                       cm.clock_select = 0; /* misc register = 0xE3  25MHz */\r
+                       cm.clock_select = 1; /* misc register = 0xE3  25MHz */\r
                        cm.vsync_neg = 1;\r
                        cm.hsync_neg = 1;\r
                        cm.offset = (vga_state.vga_width / (4 * 2)); // 320 wide (40 x 4 pixel groups x 2)\r
@@ -145,17 +154,18 @@ void modexEnter(sword vq, boolean cmem, global_game_variables_t *gv)
                }\r
                break;\r
        }\r
-       gv->video.page[0].tilesw = gv->video.page[0].sw/TILEWH;\r
-       gv->video.page[0].tilesh = gv->video.page[0].sh/TILEWH;\r
+\r
+//     gv->video.page[0].tw = gv->video.page[0].sw/TILEWH;\r
+//     gv->video.page[0].th = gv->video.page[0].sh/TILEWH;\r
+\r
        //TODO MAKE FLEXIBLE~\r
-       gv->video.page[0].tilemidposscreenx = gv->video.page[0].tilesw;\r
-       gv->video.page[0].tilemidposscreeny = (gv->video.page[0].tilesh/2)+1;\r
-       #define PAGE_SIZE               (word)(gv->video.page[0].sw/4 * gv->video.page[0].sh)\r
+//     gv->video.page[0].tilemidposscreenx = gv->video.page[0].tilesw;\r
+//     gv->video.page[0].tilemidposscreeny = (gv->video.page[0].tilesh/2)+1;\r
 }\r
 \r
 void\r
 modexLeave() {\r
-       /* TODO restore original mode and palette */\r
+       /* VGAmodeX restores original mode and palette */\r
        vgaSetMode(TEXT_MODE);\r
 }\r
 \r
@@ -165,20 +175,23 @@ modexDefaultPage(page_t *p)
     page_t page;\r
 \r
     /* default page values */\r
-    page.data = vga_state.vga_graphics_ram;//VGA;\r
+       //page.data = VGA;\r
+       //page.data = (byte far *)(vga_state.vga_graphics_ram);\r
+       page.data = (vga_state.vga_graphics_ram);\r
     page.dx = 0;\r
     page.dy = 0;\r
        page.sw = p->sw;\r
        page.sh = p->sh;\r
-       page.width = p->sw;\r
-       page.height = p->sh;\r
+       page.width = p->sw+TILEWHD;\r
+       page.height = p->sh+TILEWHD;\r
        page.tw = page.sw/TILEWH;\r
        page.th = page.sh/TILEWH;\r
+       page.tilesw=page.width/TILEWH;\r
+       page.tilesh=page.height/TILEWH;\r
        page.tilemidposscreenx = page.tw/2;\r
        page.tilemidposscreeny = (page.th/2)+1;\r
-       page.tilesw=p->tilesw;\r
-       page.tilesh=p->tilesh;\r
-       //pageSize = p->sw*p->sh;\r
+       page.stridew=page.width/4;\r
+       page.pagesize = (word)(page.width/4)*page.height;\r
        page.id = 0;\r
 \r
     return page;\r
@@ -191,17 +204,22 @@ page_t
 modexNextPage(page_t *p) {\r
     page_t result;\r
 \r
-    result.data = p->data + (p->width/4)*p->height;\r
+    result.data = p->data + (p->pagesize);\r
     result.dx = 0;\r
     result.dy = 0;\r
+       result.sw = p->sw;\r
+       result.sh = p->sh;\r
     result.width = p->width;\r
     result.height = p->height;\r
-       result.tw = p->width/TILEWH;\r
-       result.th = p->height/TILEWH;\r
+       result.tw = p->tw;\r
+       result.th = p->th;\r
+       result.tilesw = p->tilesw;\r
+       result.tilesh = p->tilesh;\r
        result.id = p->id+1;\r
+       result.stridew=p->stridew;\r
+       result.pagesize = p->pagesize;\r
 \r
        return result;\r
-//     return modexNextPageFlexibleSize(&p, p->width, p->height);\r
 }\r
 \r
 //next page with defined dimentions~\r
@@ -210,18 +228,50 @@ modexNextPageFlexibleSize(page_t *p, word x, word y)
 {\r
        page_t result;\r
 \r
-       result.data = p->data + (p->width/4)*p->height;  /* compute the offset */\r
+       result.data = p->data + (p->pagesize);  /* compute the offset */\r
        result.dx = 0;\r
        result.dy = 0;\r
+       result.sw = x;\r
+       result.sh = y;\r
        result.width = x;\r
        result.height = y;\r
-       result.tw = p->width/TILEWH;\r
-       result.th = p->height/TILEWH;\r
+       result.tw = result.sw/TILEWH;\r
+       result.th = result.sh/TILEWH;\r
+       result.tilesw=result.width/TILEWH;\r
+       result.tilesh=result.height/TILEWH;\r
        result.id = p->id+1;\r
+       result.stridew=result.width/4;\r
+       result.pagesize = (word)(result.width/4)*result.height;\r
 \r
        return result;\r
 }\r
 \r
+void modexCalcVmemRemain(video_t *video)\r
+{\r
+       byte i;\r
+       //printf("\n\n  1st vmem_remain=%u\n", video->vmem_remain);\r
+       for(i=0; i<video->num_of_pages; i++)\r
+       {\r
+               video->vmem_remain-=video->page[i].pagesize;\r
+               //printf("              [%u], video->page[%u].pagesize=%u\n", i, i, video->page[i].pagesize);\r
+               //printf("              [%u], vmem_remain=%u\n", i, video->vmem_remain);\r
+       }\r
+}\r
+\r
+void modexHiganbanaPageSetup(video_t *video)\r
+{\r
+       video->vmem_remain=65535U;\r
+       video->num_of_pages=0;\r
+       (video->page[0]) = modexDefaultPage(&(video->page[0])); video->num_of_pages++;  //video->page[0].width += (TILEWHD); video->page[0].height += (TILEWHD);\r
+       (video->page[1]) = modexNextPage(&(video->page[0]));    video->num_of_pages++;\r
+       (video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), TILEWH*4, TILEWH*4);            video->num_of_pages++;\r
+       (video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), video->page[0].sw, 208);        video->num_of_pages++;\r
+//     (video->page[2]) = modexNextPageFlexibleSize(&(video->page[1]), video->page[0].width, 172);     video->num_of_pages++;\r
+//     (video->page[3]) = modexNextPageFlexibleSize(&(video->page[2]), 72, 128);               video->num_of_pages++;\r
+       modexCalcVmemRemain(video);\r
+       video->p=0;\r
+       video->r=1;\r
+}\r
 \r
 void\r
 modexShowPage(page_t *page) {\r
@@ -256,28 +306,25 @@ modexShowPage(page_t *page) {
     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
+    word poffset = pageOff + y*(page->stridew) + xoff; /* starting offset */\r
+    word nextRow = page->stridew-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
@@ -289,6 +336,14 @@ modexClearRegion(page_t *page, int x, int y, int w, int h, byte  color) {
     }\r
 \r
     __asm {\r
+           PUSHF\r
+           PUSH ES\r
+           PUSH AX\r
+           PUSH BX\r
+           PUSH CX\r
+           PUSH DX\r
+           PUSH SI\r
+           PUSH DI\r
                MOV AX, SCREEN_SEG      ; go to the VGA memory\r
                MOV ES, AX\r
                MOV DI, poffset  ; go to the first pixel\r
@@ -322,6 +377,14 @@ modexClearRegion(page_t *page, int x, int y, int w, int h, byte  color) {
                ADD DI, nextRow  ; go to the next row\r
                DEC h\r
                JNZ SCAN_START\r
+           POP DI\r
+           POP SI\r
+           POP DX\r
+           POP CX\r
+           POP BX\r
+           POP AX\r
+           POP ES\r
+           POPF\r
     }\r
 }\r
 \r
@@ -337,17 +400,26 @@ modexCopyPageRegion(page_t *dest, page_t *src,
                    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
+    word doffset = (word)dest->data + dy*(dest->stridew) + dx/4;\r
+    word soffset = (word)src->data + sy*(src->stridew) + sx/4;\r
+    word scans   = vga_state.vga_stride;\r
+    word nextSrcRow = src->stridew - scans - 1;\r
+    word nextDestRow = dest->stridew - 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
+           PUSHF\r
+           PUSH ES\r
+           PUSH AX\r
+           PUSH BX\r
+           PUSH CX\r
+           PUSH DX\r
+           PUSH SI\r
+           PUSH DI\r
+\r
                MOV AX, SCREEN_SEG      ; work in the vga space\r
                MOV ES, AX            ;\r
                MOV DI, doffset  ;\r
@@ -396,6 +468,15 @@ modexCopyPageRegion(page_t *dest, page_t *src,
                MOV DX, GC_INDEX+1      ; go back to CPU data\r
                MOV AL, 0ffh        ; none from latches\r
                OUT DX, AL            ;\r
+\r
+           POP DI\r
+           POP SI\r
+           POP DX\r
+           POP CX\r
+           POP BX\r
+           POP AX\r
+           POP ES\r
+           POPF\r
     }\r
 }\r
 \r
@@ -880,8 +961,10 @@ byte modexgetPixel(page_t *page, int x, int y)
 void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, const byte *str)\r
 {\r
        word s, o, w;\r
+       word x_draw = x;\r
        word addr = (word) romFontsData.l;\r
        word addrq = (page->width/4) * y + (x / 4) + ((word)page->data);\r
+       word addrr = addrq;\r
        byte c;\r
 \r
        s=romFonts[t].seg;\r
@@ -892,36 +975,23 @@ void modexprint(page_t *page, word x, word y, word t, word col, word bgcol, cons
        for(; *str != '\0'; str++)\r
        {\r
        c = (*str);\r
-       if((c=='\n'/* || c=="\\r
-"*/) || romFontsData.chw\r
->=page->width)\r
+       if(c=='\n')\r
        {\r
-               romFontsData.chw=0;\r
-               y+=romFonts[t].charSize;\r
+               x = x_draw;\r
+               romFontsData.chw = 0;\r
+               addrq += (page->width / 4) * 8;\r
+               addrr = addrq;\r
+               y += 8;\r
                continue;\r
        }\r
-       //load the letter 'A'\r
-       __asm {\r
-               MOV DI, addr\r
-               MOV SI, o\r
-               MOV ES, s\r
-               SUB AH, AH\r
-               MOV AL, c       ; the letter\r
-               MOV CX, w\r
-               MUL CX\r
-               ADD SI, AX      ;the address of charcter\r
-       L1:     MOV AX, ES:SI\r
-               MOV DS:DI, AX\r
-               INC SI\r
-               INC DI\r
-               DEC CX\r
-               JNZ L1\r
-       }\r
-//TODO: OPTIMIZE THIS!!!!\r
-               modexDrawChar(page, x/*for mode X planar use*/, t, col, bgcol, addrq);\r
-               addrq += 2; /* move 8 pixels over (2 x 4 planar pixels per byte) */\r
 \r
-               //if(!q) getch();\r
+       // load the character into romFontsData.l\r
+       // no need for inline assembly!\r
+       // NTS: It might even be faster to just let the modexDrawChar point directly at ROM font than to copy per char! --J.C.\r
+               _fmemcpy(romFontsData.l,MK_FP(s,o+(w*c))/*ROM font location*/,w/*char size*/);\r
+               modexDrawChar(page, x_draw/*for mode X planar use*/, t, col, bgcol, addrr);\r
+               x_draw += 8; /* track X for edge of screen */\r
+               addrr += 2; /* move 8 pixels over (2 x 4 planar pixels per byte) */\r
        }\r
 }\r
 \r
@@ -968,6 +1038,15 @@ void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, c
        }\r
        //load the letter 'A'\r
        __asm {\r
+           PUSHF\r
+           PUSH ES\r
+           PUSH AX\r
+           PUSH BX\r
+           PUSH CX\r
+           PUSH DX\r
+           PUSH SI\r
+           PUSH DI\r
+\r
                MOV DI, addr\r
                MOV SI, o\r
                MOV ES, s\r
@@ -982,6 +1061,15 @@ void modexprintbig(page_t *page, word x, word y, word t, word col, word bgcol, c
                INC DI\r
                DEC CX\r
                JNZ L1\r
+\r
+           POP DI\r
+           POP SI\r
+           POP DX\r
+           POP CX\r
+           POP BX\r
+           POP AX\r
+           POP ES\r
+           POPF\r
        }\r
 \r
                for(i=0; i<w; i++)\r
@@ -1030,16 +1118,16 @@ void modexcls(page_t *page, byte color, byte *Where)
        _fmemset(Where, color, page->width*(page->height)/4);\r
 }\r
 \r
-/*void\r
+void\r
 modexWaitBorder() {\r
-    while(inp(INPUT_STATUS_1)  & 8)  {\r
+       while(inp(INPUT_STATUS_1)  & 8)  {\r
        // spin\r
-    }\r
+       }\r
 \r
-    while(!(inp(INPUT_STATUS_1)  & 8))  {\r
-       // spin\r
-    }\r
-}*/\r
+       while(!(inp(INPUT_STATUS_1)  & 8))  {\r
+       //spin\r
+       }\r
+}\r
 \r
 void bios_cls() {\r
        VGA_ALPHA_PTR ap;\r
@@ -1067,3 +1155,19 @@ void bios_cls() {
                printf("WARNING: bios cls no ptr\n");\r
        }\r
 }\r
+\r
+void modexprintmeminfo(video_t *v)\r
+{\r
+       byte i;\r
+       printf("video memory remaining: %u\n", v->vmem_remain);\r
+       printf("page ");\r
+       for(i=0; i<v->num_of_pages;i++)\r
+       {\r
+               printf("        [%u]=", i);\r
+               printf("(%Fp)", (v->page[i].data));\r
+               printf(" size=%u", v->page[i].pagesize);\r
+               printf(" sw=%lu  sh=%lu ", (unsigned long)v->page[i].sw, (unsigned long)v->page[i].sh);\r
+               printf(" width=%lu  height=%lu", (unsigned long)v->page[i].width, (unsigned long)v->page[i].height);\r
+               printf("\n");\r
+       }\r
+}\r