From: sparky4 Date: Sun, 29 Mar 2015 08:35:47 +0000 (-0500) Subject: extended the palette system~ wwww X-Git-Url: http://4ch.mooo.com/gitweb/?a=commitdiff_plain;h=cc5df35b6ba3d7871eac6734822464c7e176f4b7;p=16.git extended the palette system~ wwww wwww modified: data/MAYU.PCX new file: data/g.pal modified: data/koishi^^.pcx modified: data/koishi~.pcx modified: data/ptmp.pcx modified: pcxtest.exe modified: scroll.exe modified: src/lib/bitmap.h modified: src/lib/mapread.c modified: src/lib/mapread.h modified: src/lib/modex16.c modified: src/lib/modex16.h modified: src/pcxtest.c modified: src/scroll.c modified: test.exe modified: test2.exe --- diff --git a/data/MAYU.PCX b/data/MAYU.PCX index 025e7d4a..c89f0253 100644 Binary files a/data/MAYU.PCX and b/data/MAYU.PCX differ diff --git a/data/g.pal b/data/g.pal new file mode 100644 index 00000000..7ac648dc Binary files /dev/null and b/data/g.pal differ diff --git a/data/koishi^^.pcx b/data/koishi^^.pcx index 0dbbc0da..66523ede 100644 Binary files a/data/koishi^^.pcx and b/data/koishi^^.pcx differ diff --git a/data/koishi~.pcx b/data/koishi~.pcx index 58a03bb4..c6065672 100644 Binary files a/data/koishi~.pcx and b/data/koishi~.pcx differ diff --git a/data/ptmp.pcx b/data/ptmp.pcx index 3b956313..7e212b72 100644 Binary files a/data/ptmp.pcx and b/data/ptmp.pcx differ diff --git a/pcxtest.exe b/pcxtest.exe index 98fa93af..e69de29b 100644 Binary files a/pcxtest.exe and b/pcxtest.exe differ diff --git a/scroll.exe b/scroll.exe index 3417aed0..edbdeeb4 100644 Binary files a/scroll.exe and b/scroll.exe differ diff --git a/src/lib/bitmap.h b/src/lib/bitmap.h index 2eefe41b..e0e93c38 100644 --- a/src/lib/bitmap.h +++ b/src/lib/bitmap.h @@ -8,7 +8,8 @@ typedef struct { byte *data; word width; word height; - byte *palette; + byte *palette; + word offset; } bitmap_t; typedef struct { diff --git a/src/lib/mapread.c b/src/lib/mapread.c index a55f21a0..d1187795 100644 --- a/src/lib/mapread.c +++ b/src/lib/mapread.c @@ -9,7 +9,7 @@ static int jsoneq(const char *json, jsmntok_t *tok, const char *s) { } //this function is quite messy ^^; sorry! it is a quick and dirty fix~ -static int dump(const char *js, jsmntok_t *t, size_t count, int indent, /*char *js_sv,*/ map_t *map, int q/*, int *w*/) { +static int dump(const char *js, jsmntok_t *t, size_t count, int indent, /*char *js_sv,*/ map_t *map, int q) { int i, j, k; bitmap_t bp; if (count == 0) { @@ -75,9 +75,9 @@ static int dump(const char *js, jsmntok_t *t, size_t count, int indent, /*char * j = 0; for (i = 0; i < t->size; i++) { //for (k = 0; k < indent; k++) printf("\t"); - j += dump(js, t+1+j, count-j, indent+1, map, i/*, w*/); + j += dump(js, t+1+j, count-j, indent+1, map, i); //printf(": "); - j += dump(js, t+1+j, count-j, indent+1, map, i/*, w*/); + j += dump(js, t+1+j, count-j, indent+1, map, i); //printf("\n"); } return j+1; @@ -87,7 +87,7 @@ static int dump(const char *js, jsmntok_t *t, size_t count, int indent, /*char * for (i = 0; i < t->size; i++) { //for (k = 0; k < indent-1; k++) printf("\t"); //printf("\t-"); - j += dump(js, t+1+j, count-j, indent+1, map, i/*, &t->size*/); + j += dump(js, t+1+j, count-j, indent+1, map, i); //printf("==\n"); } return j+1; @@ -95,7 +95,7 @@ static int dump(const char *js, jsmntok_t *t, size_t count, int indent, /*char * return 0; } -static int loadmap(char *mn, map_t *map/*, word w*/) +static int loadmap(char *mn, map_t *map) { int r; int eof_expected = 0; diff --git a/src/lib/mapread.h b/src/lib/mapread.h index 623bf545..b82369a3 100644 --- a/src/lib/mapread.h +++ b/src/lib/mapread.h @@ -26,6 +26,6 @@ typedef struct { static int jsoneq(const char *json, jsmntok_t *tok, const char *s); static int dump(const char *js, jsmntok_t *t, size_t count, int indent, map_t *map, int q); -static int loadmap(char *mn, map_t *map/*, word w*/); +static int loadmap(char *mn, map_t *map); #endif/*_LIBMAPREAD_H_*/ diff --git a/src/lib/modex16.c b/src/lib/modex16.c index d0707ffd..83c22788 100644 --- a/src/lib/modex16.c +++ b/src/lib/modex16.c @@ -1,617 +1,671 @@ -#include -#include -#include -#include -#include -#include -#include "src\lib\modex16.h" - - -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]; - -static void -vgaSetMode(byte mode) -{ - union REGS regs; - - regs.h.ah = SET_MODE; - regs.h.al = mode; - int86(VIDEO_INT, ®s, ®s); -} - - -/* -========================= 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; idata + (p->width/4)*p->height; /* compute the offset */ - result.dx = 0; - result.dy = 0; - result.width = p->width; - result.height = p->height; - - return result; -} - - -void -modexShowPage(page_t *page) { - word high_address; - word low_address; - word offset; - byte crtcOffset; - - /* calculate offset */ - offset = (word) page->data; - offset += page->dy * (page->width >> 2 ); - offset += page->dx >> 2; - - /* calculate crtcOffset according to virtual width */ - crtcOffset = page->width >> 3; - - high_address = HIGH_ADDRESS | (offset & 0xff00); - low_address = LOW_ADDRESS | (offset << 8); - - /* wait for appropriate timing and then program CRTC */ - while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE)); - outpw(CRTC_INDEX, high_address); - outpw(CRTC_INDEX, low_address); - outp(CRTC_INDEX, 0x13); - outp(CRTC_DATA, crtcOffset); - - /* wait for one retrace */ - while (!(inp(INPUT_STATUS_1) & VRETRACE)); - - /* do PEL panning here */ - outp(AC_INDEX, 0x33); - outp(AC_INDEX, (page->dx & 0x03) << 1); -} - - -void -modexPanPage(page_t *page, int dx, int dy) { - page->dx = dx; - page->dy = dy; -} - - -void -modexSelectPlane(byte plane) { - outp(SC_INDEX, MAP_MASK); /* select plane */ - outp(SC_DATA, plane); -} - - -void -modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) { - word pageOff = (word) page->data; - word xoff=x/4; /* xoffset that begins each row */ - word scanCount=w/4; /* number of iterations per row (excluding right clip)*/ - word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */ - word nextRow = page->width/4-scanCount-1; /* loc of next row */ - byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */ - byte rclip[] = {0x00, 0x01, 0x03, 0x07}; - byte left = lclip[x&0x03]; - byte right = rclip[(x+w)&0x03]; - - /* handle the case which requires an extra group */ - if((x & 0x03) && !((x+w) & 0x03)) { - right=0x0f; - } - - __asm { - MOV AX, SCREEN_SEG ; go to the VGA memory - MOV ES, AX - MOV DI, poffset ; go to the first pixel - MOV DX, SC_INDEX ; point to the map mask - MOV AL, MAP_MASK - OUT DX, AL - INC DX - MOV AL, color ; get ready to write colors - SCAN_START: - MOV CX, scanCount ; count the line - MOV BL, AL ; remember color - MOV AL, left ; do the left clip - OUT DX, AL ; set the left clip - MOV AL, BL ; restore color - STOSB ; write the color - DEC CX - JZ SCAN_DONE ; handle 1 group stuff - - ;-- write the main body of the scanline - MOV BL, AL ; remember color - MOV AL, 0x0f ; write to all pixels - OUT DX, AL - MOV AL, BL ; restore color - REP STOSB ; write the color - SCAN_DONE: - MOV BL, AL ; remeber color - MOV AL, right - OUT DX, AL ; do the right clip - MOV AL, BL ; restore color - STOSB ; write pixel - ADD DI, nextRow ; go to the next row - DEC h - JNZ SCAN_START - } -} - - -void -modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) { - /* draw the region (the entire freakin bitmap) */ - 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; - 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; - - //code is a bit slow here - __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: - MOVSB ; copy the 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 - } -} - - -void -modexDrawPlanarBuf(page_t *page, int x, int y, planar_buf_t *bmp) { +#include +#include +#include +#include +#include +#include +#include "src\lib\modex16.h" + + +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]; + +static void +vgaSetMode(byte mode) +{ + union REGS regs; + + regs.h.ah = SET_MODE; + regs.h.al = mode; + int86(VIDEO_INT, ®s, ®s); +} + + +/* -========================= 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; idata + (p->width/4)*p->height; /* compute the offset */ + result.dx = 0; + result.dy = 0; + result.width = p->width; + result.height = p->height; + + return result; +} + + +void +modexShowPage(page_t *page) { + word high_address; + word low_address; + word offset; + byte crtcOffset; + + /* calculate offset */ + offset = (word) page->data; + offset += page->dy * (page->width >> 2 ); + offset += page->dx >> 2; + + /* calculate crtcOffset according to virtual width */ + crtcOffset = page->width >> 3; + + high_address = HIGH_ADDRESS | (offset & 0xff00); + low_address = LOW_ADDRESS | (offset << 8); + + /* wait for appropriate timing and then program CRTC */ + while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE)); + outpw(CRTC_INDEX, high_address); + outpw(CRTC_INDEX, low_address); + outp(CRTC_INDEX, 0x13); + outp(CRTC_DATA, crtcOffset); + + /* wait for one retrace */ + while (!(inp(INPUT_STATUS_1) & VRETRACE)); + + /* do PEL panning here */ + outp(AC_INDEX, 0x33); + outp(AC_INDEX, (page->dx & 0x03) << 1); +} + + +void +modexPanPage(page_t *page, int dx, int dy) { + page->dx = dx; + page->dy = dy; +} + + +void +modexSelectPlane(byte plane) { + outp(SC_INDEX, MAP_MASK); /* select plane */ + outp(SC_DATA, plane); +} + + +void +modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) { + word pageOff = (word) page->data; + word xoff=x/4; /* xoffset that begins each row */ + word scanCount=w/4; /* number of iterations per row (excluding right clip)*/ + word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */ + word nextRow = page->width/4-scanCount-1; /* loc of next row */ + byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */ + byte rclip[] = {0x00, 0x01, 0x03, 0x07}; + byte left = lclip[x&0x03]; + byte right = rclip[(x+w)&0x03]; + + /* handle the case which requires an extra group */ + if((x & 0x03) && !((x+w) & 0x03)) { + right=0x0f; + } + + __asm { + MOV AX, SCREEN_SEG ; go to the VGA memory + MOV ES, AX + MOV DI, poffset ; go to the first pixel + MOV DX, SC_INDEX ; point to the map mask + MOV AL, MAP_MASK + OUT DX, AL + INC DX + MOV AL, color ; get ready to write colors + SCAN_START: + MOV CX, scanCount ; count the line + MOV BL, AL ; remember color + MOV AL, left ; do the left clip + OUT DX, AL ; set the left clip + MOV AL, BL ; restore color + STOSB ; write the color + DEC CX + JZ SCAN_DONE ; handle 1 group stuff + + ;-- write the main body of the scanline + MOV BL, AL ; remember color + MOV AL, 0x0f ; write to all pixels + OUT DX, AL + MOV AL, BL ; restore color + REP STOSB ; write the color + SCAN_DONE: + MOV BL, AL ; remeber color + MOV AL, right + OUT DX, AL ; do the right clip + MOV AL, BL ; restore color + STOSB ; write pixel + ADD DI, nextRow ; go to the next row + DEC h + JNZ SCAN_START + } +} + + +void +modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) { + /* draw the region (the entire freakin bitmap) */ + 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; + 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; + + //code is a bit slow here + __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: + MOVSB ; copy the 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 + } +} + + +void +modexDrawPlanarBuf(page_t *page, int x, int y, planar_buf_t *bmp) { /* TODO - adapt from test code */ int plane; for(plane=0; plane < 4; plane++) { //fack - } -} - - -void -modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) { - /* draw the whole sprite */ - 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; - 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 - } -} - - -/* 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. - */ -void -modexCopyPageRegion(page_t *dest, page_t *src, - word sx, word sy, - word dx, word dy, - word width, word height) -{ - word doffset = (word)dest->data + dy*(dest->width/4) + dx/4; - word soffset = (word)src->data + sy*(src->width/4) + sx/4; - word scans = width/4; - word nextSrcRow = src->width/4 - scans - 1; - word nextDestRow = dest->width/4 - scans - 1; - byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */ - byte rclip[] = {0x0f, 0x01, 0x03, 0x07}; - byte left = lclip[sx&0x03]; - byte right = rclip[(sx+width)&0x03]; - - __asm { - MOV AX, SCREEN_SEG ; work in the vga space - MOV ES, AX ; - MOV DI, doffset ; - MOV SI, soffset ; - - MOV DX, GC_INDEX ; turn off cpu bits - MOV AX, 0008h ; - OUT DX, AX - - MOV AX, SC_INDEX ; point to the mask register - MOV DX, AX ; - MOV AL, MAP_MASK ; - OUT DX, AL ; - INC DX ; - - ROW_START: - PUSH DS - MOV AX, ES - MOV DS, AX - MOV CX, scans ; the number of latches - - MOV AL, left ; do the left column - OUT DX, AL ; - MOVSB ; - DEC CX ; - - MOV AL, 0fh ; do the inner columns - OUT DX, AL - REP MOVSB ; copy the pixels - - MOV AL, right ; do the right column - OUT DX, AL - MOVSB - POP DS - - MOV AX, SI ; go the start of the next row - ADD AX, nextSrcRow ; - MOV SI, AX ; - MOV AX, DI ; - ADD AX, nextDestRow ; - MOV DI, AX ; - - DEC height ; do the rest of the actions - JNZ ROW_START ; - - MOV DX, GC_INDEX+1 ; go back to CPU data - MOV AL, 0ffh ; none from latches - OUT DX, AL ; - } -} - - -/* fade and flash */ -void -modexFadeOn(word fade, byte *palette) { - fadePalette(-fade, 64, 64/fade+1, palette); -} - - -void -modexFadeOff(word fade, byte *palette) { - fadePalette(fade, 0, 64/fade+1, palette); -} - - -void -modexFlashOn(word fade, byte *palette) { - fadePalette(fade, -64, 64/fade+1, palette); -} - - -void -modexFlashOff(word fade, byte *palette) { - fadePalette(-fade, 0, 64/fade+1, palette); -} - - -static void -fadePalette(sbyte fade, sbyte start, word iter, byte *palette) { - word i; - byte dim = start; - - /* handle the case where we just update */ - if(iter == 0) { - modexPalUpdate(palette); - return; - } - - while(iter > 0) { /* FadeLoop */ - for(i=0; i 127) { - tmppal[i] = 0; - } else if(tmppal[i] > 63) { - tmppal[i] = 63; - } - } - modexPalUpdate(tmppal); - iter--; - dim += fade; - } -} - - -/* save and load */ -void -modexPalSave(byte *palette) { - int i; - - outp(PAL_READ_REG, 0); /* start at palette entry 0 */ - for(i=0; iwidth, 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 + } +} + + +/* 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. + */ +void +modexCopyPageRegion(page_t *dest, page_t *src, + word sx, word sy, + word dx, word dy, + word width, word height) +{ + word doffset = (word)dest->data + dy*(dest->width/4) + dx/4; + word soffset = (word)src->data + sy*(src->width/4) + sx/4; + word scans = width/4; + word nextSrcRow = src->width/4 - scans - 1; + word nextDestRow = dest->width/4 - scans - 1; + byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */ + byte rclip[] = {0x0f, 0x01, 0x03, 0x07}; + byte left = lclip[sx&0x03]; + byte right = rclip[(sx+width)&0x03]; + + __asm { + MOV AX, SCREEN_SEG ; work in the vga space + MOV ES, AX ; + MOV DI, doffset ; + MOV SI, soffset ; + + MOV DX, GC_INDEX ; turn off cpu bits + MOV AX, 0008h ; + OUT DX, AX + + MOV AX, SC_INDEX ; point to the mask register + MOV DX, AX ; + MOV AL, MAP_MASK ; + OUT DX, AL ; + INC DX ; + + ROW_START: + PUSH DS + MOV AX, ES + MOV DS, AX + MOV CX, scans ; the number of latches + + MOV AL, left ; do the left column + OUT DX, AL ; + MOVSB ; + DEC CX ; + + MOV AL, 0fh ; do the inner columns + OUT DX, AL + REP MOVSB ; copy the pixels + + MOV AL, right ; do the right column + OUT DX, AL + MOVSB + POP DS + + MOV AX, SI ; go the start of the next row + ADD AX, nextSrcRow ; + MOV SI, AX ; + MOV AX, DI ; + ADD AX, nextDestRow ; + MOV DI, AX ; + + DEC height ; do the rest of the actions + JNZ ROW_START ; + + MOV DX, GC_INDEX+1 ; go back to CPU data + MOV AL, 0ffh ; none from latches + OUT DX, AL ; + } +} + + +/* fade and flash */ +void +modexFadeOn(word fade, byte *palette) { + fadePalette(-fade, 64, 64/fade+1, palette); +} + + +void +modexFadeOff(word fade, byte *palette) { + fadePalette(fade, 0, 64/fade+1, palette); +} + + +void +modexFlashOn(word fade, byte *palette) { + fadePalette(fade, -64, 64/fade+1, palette); +} + + +void +modexFlashOff(word fade, byte *palette) { + fadePalette(-fade, 0, 64/fade+1, palette); +} + + +static void +fadePalette(sbyte fade, sbyte start, word iter, byte *palette) { + word i; + byte dim = start; + + /* handle the case where we just update */ + if(iter == 0) { + modexPalUpdate2(palette); + return; + } + + while(iter > 0) { /* FadeLoop */ + for(i=0; i 127) { + tmppal[i] = 0; + } else if(tmppal[i] > 63) { + tmppal[i] = 63; + } + } + modexPalUpdate2(tmppal); + iter--; + dim += fade; + } +} + + +/* save and load */ +void +modexPalSave(byte *palette) { + int i; + + outp(PAL_READ_REG, 0); /* start at palette entry 0 */ + for(i=0; i(88*3)) printf(" %d %d\n", (*i), p[(*i)]); + } + } + } + modexWaitBorder(); /* waits one retrace -- less flicker */ + if((*i)>=PAL_SIZE/2 && w==0) + { + //printf(" 2nd half\n"); + for(; (*i)(88*3)) printf(" %d %d\n", (*i), p[(*i)]); + } + } + } +} + +void +modexPalUpdate2(byte *p) +{ + int i; + modexWaitBorder(); + outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */ + for(i=0; i -#include "src\lib\types.h" -#include "src\lib\bitmap.h" -#include "src\lib\planar.h" - -/* -========================== Types & Macros ==========================- */ -#define PAGE_OFFSET(x,y) (((y)<<6)+((y)<<4)+((x)>>2)) -#define PLANE(x) (1<< (x&3)) -#define SELECT_ALL_PLANES() outpw(0x03c4, 0xff02) - -typedef struct { - byte far* data; /* the data for the page */ - word dx; /* col we are viewing on the virtual screen */ - word dy; /* row we are viewing on the virtual screen */ - word width; /* virtual width of the page */ - word height; /* virtual height of the page */ -} page_t; - -/* -============================ Functions =============================- */ -/* mode switching, page, and plane functions */ -void modexEnter(); -void modexLeave(); -page_t modexDefaultPage(); -page_t modexNextPage(page_t *p); -void modexShowPage(page_t *page); -void modexPanPage(page_t *page, int dx, int dy); -void modexSelectPlane(byte plane); -void modexClearRegion(page_t *page, int x, int y, int w, int h, byte color); -void modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp); -void modexDrawBmpRegion(page_t *page, int x, int y, int rx, int ry, int rw, int rh, bitmap_t *bmp); -void modexDrawPlanarBuf(page_t *page, int x, int y, planar_buf_t *bmp); -void modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp); -void modexDrawSpriteRegion(page_t *page, int x, int y, int rx, int ry, int rw, int rh, bitmap_t *bmp); -void modexCopyPageRegion(page_t *dest, page_t *src, word sx, word sy, word dx, word dy, word width, word height); - -/* Palette fade and flash effects */ -void modexFadeOn(word fade, byte *palette); -void modexFadeOff(word fade, byte *palette); -void modexFlashOn(word fade, byte *palette); -void modexFlashOff(word fade, byte *palette); - -/* palette loading and saving */ -void modexPalSave(byte *palette); -byte *modexNewPal(); -void modexLoadPalFile(char *filename, byte **palette); -void modexSavePalFile(char *filename, byte *palette); - -/* fixed palette functions */ -void modexPalBlack(); -void modexPalWhite(); - -/* utility functions */ -void modexPalUpdate(byte *p); -void modexWaitBorder(); - -/* -======================= Constants & Vars ==========================- */ -extern byte far* VGA; /* The VGA Memory */ -#define SCREEN_SEG 0xa000 -#define VIDEO_INT 0x10 -#define SET_MODE 0x00 -#define VGA_256_COLOR_MODE 0x13 -#define TEXT_MODE 0x03 -#define SCREEN_WIDTH 320 -#define SCREEN_HEIGHT 240 -#define PAGE_SIZE (word)(SCREEN_WIDTH/4 * SCREEN_HEIGHT) - -#define AC_INDEX 0x03c0 -#define SC_INDEX 0x03c4 -#define SC_DATA 0x03c5 -#define CRTC_INDEX 0x03d4 -#define CRTC_DATA 0x03d5 -#define GC_INDEX 0x03ce -#define MISC_OUTPUT 0x03c2 -#define HIGH_ADDRESS 0x0C -#define LOW_ADDRESS 0x0D -#define VRETRACE 0x08 -#define INPUT_STATUS_1 0x03da -#define DISPLAY_ENABLE 0x01 -#define MAP_MASK 0x02 -#define PAL_READ_REG 0x03C7 /* Color register, read address */ -#define PAL_WRITE_REG 0x03C8 /* Color register, write address */ -#define PAL_DATA_REG 0x03C9 /* Color register, data port */ -#define PAL_SIZE (256 * 3) -#endif +/* + * Functions for handling modex and doing other basic graphics stuff. + */ +#ifndef MODEX16_H +#define MODEX16_H +#include +#include "src\lib\types.h" +#include "src\lib\bitmap.h" +#include "src\lib\planar.h" + +/* -========================== Types & Macros ==========================- */ +#define PAGE_OFFSET(x,y) (((y)<<6)+((y)<<4)+((x)>>2)) +#define PLANE(x) (1<< (x&3)) +#define SELECT_ALL_PLANES() outpw(0x03c4, 0xff02) + +typedef struct { + byte far* data; /* the data for the page */ + word dx; /* col we are viewing on the virtual screen */ + word dy; /* row we are viewing on the virtual screen */ + word width; /* virtual width of the page */ + word height; /* virtual height of the page */ +} page_t; + +/* -============================ Functions =============================- */ +/* mode switching, page, and plane functions */ +void modexEnter(); +void modexLeave(); +page_t modexDefaultPage(); +page_t modexNextPage(page_t *p); +void modexShowPage(page_t *page); +void modexPanPage(page_t *page, int dx, int dy); +void modexSelectPlane(byte plane); +void modexClearRegion(page_t *page, int x, int y, int w, int h, byte color); +void modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp); +void modexDrawBmpRegion(page_t *page, int x, int y, int rx, int ry, int rw, int rh, bitmap_t *bmp); +void modexDrawPlanarBuf(page_t *page, int x, int y, planar_buf_t *bmp); +void modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp); +void modexDrawSpriteRegion(page_t *page, int x, int y, int rx, int ry, int rw, int rh, bitmap_t *bmp); +void modexCopyPageRegion(page_t *dest, page_t *src, word sx, word sy, word dx, word dy, word width, word height); + +/* Palette fade and flash effects */ +void modexFadeOn(word fade, byte *palette); +void modexFadeOff(word fade, byte *palette); +void modexFlashOn(word fade, byte *palette); +void modexFlashOff(word fade, byte *palette); + +/* palette loading and saving */ +void modexPalSave(byte *palette); +byte *modexNewPal(); +void modexLoadPalFile(char *filename, byte **palette); +void modexSavePalFile(char *filename, byte *palette); + +/* fixed palette functions */ +void modexPalBlack(); +void modexPalWhite(); + +/* utility functions */ +void modexPalUpdate(byte *p, word *i); +void modexPalUpdate2(byte *p); +void modexWaitBorder(); + +/* -======================= Constants & Vars ==========================- */ +extern byte far* VGA; /* The VGA Memory */ +#define SCREEN_SEG 0xa000 +#define VIDEO_INT 0x10 +#define SET_MODE 0x00 +#define VGA_256_COLOR_MODE 0x13 +#define TEXT_MODE 0x03 +#define SCREEN_WIDTH 320 +#define SCREEN_HEIGHT 240 +#define PAGE_SIZE (word)(SCREEN_WIDTH/4 * SCREEN_HEIGHT) + +#define AC_INDEX 0x03c0 +#define SC_INDEX 0x03c4 +#define SC_DATA 0x03c5 +#define CRTC_INDEX 0x03d4 +#define CRTC_DATA 0x03d5 +#define GC_INDEX 0x03ce +#define MISC_OUTPUT 0x03c2 +#define HIGH_ADDRESS 0x0C +#define LOW_ADDRESS 0x0D +#define VRETRACE 0x08 +#define INPUT_STATUS_1 0x03da +#define DISPLAY_ENABLE 0x01 +#define MAP_MASK 0x02 +#define PAL_READ_REG 0x03C7 /* Color register, read address */ +#define PAL_WRITE_REG 0x03C8 /* Color register, write address */ +#define PAL_DATA_REG 0x03C9 /* Color register, data port */ +#define PAL_SIZE (256 * 3) +#endif diff --git a/src/pcxtest.c b/src/pcxtest.c index 3c406286..75847e56 100644 --- a/src/pcxtest.c +++ b/src/pcxtest.c @@ -68,7 +68,7 @@ void main() { modexEnter(); /* fix up the palette and everything */ - modexPalUpdate(bmp.palette); + modexPalUpdate(bmp.palette, 0); /* clear and draw one sprite and one bitmap */ modexClearRegion(&page, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 1); diff --git a/src/scroll.c b/src/scroll.c index a6ee75cc..17f0aa6e 100644 --- a/src/scroll.c +++ b/src/scroll.c @@ -58,11 +58,12 @@ void mapGoTo(map_view_t *mv, int tx, int ty); void mapDrawTile(tiles_t *t, word i, page_t *page, word x, word y); void mapDrawRow(map_view_t *mv, int tx, int ty, word y); void mapDrawCol(map_view_t *mv, int tx, int ty, word x); -void qclean(); +void qclean(); +void pdump(map_view_t *pee); void animatePlayer(map_view_t *src, map_view_t *dest, /*map_view_t *top, */sword d, short scrolloffsetswitch, int x, int y, int ls, int lp, bitmap_t *bmp); -#define TILEWH 16 -#define QUADWH (TILEWH/4) +#define TILEWH 16 +#define QUADWH TILEWH/2 #define SPEED 4 //#define LOOPMAX (TILEWH/SPEED) @@ -76,7 +77,8 @@ void main() { long emmhandle; long emsavail; char teststr[80]; - int i; + int i; + static word paloffset=0; bitmap_t ptmp;//, npctmp; // player sprite planar_buf_t *p; const char *cpus; @@ -85,8 +87,8 @@ void main() { map_t map; map_view_t mv, mv2, mv3; map_view_t *bg, *spri, *mask;//, *tmp; - byte *pal; - byte *ptr; + byte *dpal, *gpal; + byte *ptr, *mappalptr; actor_t player; //actor_t npc0; @@ -116,24 +118,25 @@ void main() { printf("Insufficient pages available\n"); exit(0); }*/ - + /* create the map */ - loadmap("data/test.map", &map/*, 0*/); + loadmap("data/test.map", &map); //---- map = allocMap(map.width,map.height); //20x15 is the resolution of the screen you can make maps smaller than 20x15 but the null space needs to be drawn properly - //if(isEMS()) printf("%d tesuto\n", coretotalEMS()); -//---- initMap(&map); - mv.map = ↦ - mv2.map = ↦ - mv3.map = ↦ - - /* draw the tiles */ - ptr = map.data; - /* data */ - ptmp = bitmapLoadPcx("data/ptmp.pcx"); // load sprite - //npctmp = bitmapLoadPcx("ptmp1.pcx"); // load sprite - /* create the planar buffer */ + //if(isEMS()) printf("%d tesuto\n", coretotalEMS()); +//---- initMap(&map); + mv.map = ↦ + mv2.map = ↦ + mv3.map = ↦ + + /* draw the tiles */ + ptr = map.data; + mappalptr = map.tiles->data->palette; + /* data */ + ptmp = bitmapLoadPcx("data/ptmp.pcx"); // load sprite + //npctmp = bitmapLoadPcx("ptmp1.pcx"); // load sprite + /* create the planar buffer */ p = planar_buf_from_bitmap(&ptmp); - + /*if(isEMS()) { XMOVE mm; @@ -164,18 +167,32 @@ void main() { //printf("%d\n", emmhandle); } */ - /* save the palette */ - pal = modexNewPal(); - modexPalSave(pal); - modexFadeOff(4, pal); - modexPalBlack(); - - setkb(1); - modexEnter(); - modexPalBlack(); - modexPalUpdate(ptmp.palette); - modexFadeOn(4, ptmp.palette); - screen = modexDefaultPage(); + + /* save the palette */ + dpal = modexNewPal(); + modexPalSave(dpal); + modexFadeOff(4, dpal); + modexPalBlack(); + + setkb(1); + modexEnter(); + modexPalBlack(); + //ptmp.offset=(paloffset/3); + ptmp.offset=paloffset; + modexPalUpdate(ptmp.palette, &paloffset); +// printf(" %x\n", ptmp.data); + //printf("1: %d\n", paloffset); + map.tiles->data->offset=paloffset; + modexPalUpdate(map.tiles->data->palette, &paloffset); + //printf("2: %d\n", paloffset); +// printf(" %x\n", map.tiles->data->data); + gpal = modexNewPal(); + modexPalSave(gpal); + modexSavePalFile("data/g.pal", gpal); + modexFadeOn(4, gpal); + + /* setup camera and screen~ */ + screen = modexDefaultPage(); screen.width += (TILEWH*2); screen.height += (TILEWH*2)+QUADWH; mv.page = &screen; @@ -217,11 +234,11 @@ void main() { modexDrawSpriteRegion(spri->page, npc0.x-4, npc0.y-TILEWH, 24, 64, 24, 32, &npctmp);*/ modexDrawSpriteRegion(spri->page, player.x-4, player.y-TILEWH, 24, 64, 24, 32, &ptmp); - modexClearRegion(spri->page, player.triggerx*16, player.triggery*16, 16, 16, 1); - modexClearRegion(bg->page, player.triggerx*16, player.triggery*16, 16, 16, 1); + //----modexClearRegion(spri->page, player.triggerx*16, player.triggery*16, 16, 16, 1); + //----modexClearRegion(bg->page, player.triggerx*16, player.triggery*16, 16, 16, 1); - modexClearRegion(spri->page, 5*16, 5*16, 16, 16, 255); - modexClearRegion(bg->page, 5*16, 5*16, 16, 16, 255); + //----modexClearRegion(spri->page, 5*16, 5*16, 16, 16, 255); + //----modexClearRegion(bg->page, 5*16, 5*16, 16, 16, 255); modexShowPage(spri->page); while(!keyp(1) && player.hp>0) @@ -521,8 +538,8 @@ void main() { } if(player.q == (TILEWH/SPEED)+1 && player.d > 0 && (player.triggerx == 5 && player.triggery == 5)){ player.hp--; } //if(keyp(0x0E)) while(1){ if(xmsmalloc(24)) break; } -// modexDrawBmp(bg->page, 0, 0, map.tiles->data); -// modexDrawBmp(spri->page, 0, 0, map.tiles->data); + if(keyp(25)){ pdump(bg); pdump(spri); } + if(keyp(87)) { modexLeave(); @@ -535,8 +552,8 @@ void main() { } } - /* fade back to text mode */ - modexFadeOff(4, ptmp.palette); + /* fade back to text mode */ + modexFadeOff(4, gpal); modexPalBlack(); modexLeave(); setkb(0); @@ -554,7 +571,7 @@ void main() { printf("player.hp: %d\n", player.hp); printf("player.q: %d\n", player.q); printf("player.d: %d\n", player.d); - printf("%d\n", map.data[0]); + printf("palette offset: %d\n", paloffset); printf("temporary player sprite 0: http://www.pixiv.net/member_illust.php?mode=medium&illust_id=45556867\n"); printf("temporary player sprite 1: http://www.pixiv.net/member_illust.php?mode=medium&illust_id=44606385\n"); printf("\n"); @@ -571,9 +588,9 @@ void main() { case 2: cpus = "386 or newer"; break; default: cpus = "internal error"; break; } - printf("detected CPU type: %s\n", cpus); + printf("detected CPU type: %s\n", cpus); modexPalBlack(); - modexFadeOn(4, pal); + modexFadeOn(4, dpal); } @@ -833,6 +850,20 @@ void qclean() { modexLeave(); setkb(0); +} + +void pdump(map_view_t *pee) +{ + int mult=(QUADWH); + int palq=(mult)*TILEWH; + int palcol=0; + int palx, paly; + for(paly=0; palypage, palx+TILEWH, paly+TILEWH, mult, mult, palcol); + palcol++; + } + } } void diff --git a/test.exe b/test.exe index c84415ec..9df6003d 100644 Binary files a/test.exe and b/test.exe differ diff --git a/test2.exe b/test2.exe index 5d1c1bd9..9d517a5f 100644 Binary files a/test2.exe and b/test2.exe differ