X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Fscr%2Fraytrace.c;h=1593d9f7d856386325b47202981fc13ea45fa11c;hb=280b3d2a948e965d7af7f017809c27a2b2ee2ce2;hp=ef6760acf849f4dddd7607c7e13c86fcb351bbaf;hpb=fd64dc3d1930a40d3f173c70206d77b554b92a21;p=dosdemo diff --git a/src/scr/raytrace.c b/src/scr/raytrace.c index ef6760a..1593d9f 100644 --- a/src/scr/raytrace.c +++ b/src/scr/raytrace.c @@ -21,16 +21,12 @@ static struct screen scr = { draw }; -enum {LASTX = 1, LASTY = 2}; - struct tile { - int sz; - unsigned int flags; - struct { int x, y; } cpos[4]; /* corner coordinates */ - uint16_t *cptr[4]; /* corner pixels */ + int x, y; + uint16_t *fbptr; }; -#define TILESZ 8 +#define TILESZ 16 #define NUM_TILES ((320 / TILESZ) * (240 / TILESZ)) static cgm_vec3 raydir[240][320]; @@ -58,23 +54,9 @@ static int init(void) vptr++; if(((j & (TILESZ-1)) | (i & (TILESZ-1))) == 0) { - tptr->sz = TILESZ; - tptr->flags = 0; - if(j + TILESZ >= 320) tptr->flags |= LASTX; - if(i + TILESZ >= 240) tptr->flags |= LASTY; - - tptr->cpos[0].x = j; - tptr->cpos[0].y = i; - tptr->cpos[1].x = j + (tptr->flags & LASTX ? TILESZ - 1 : TILESZ); - tptr->cpos[1].y = i; - tptr->cpos[2].x = j; - tptr->cpos[2].y = i + (tptr->flags & LASTY ? TILESZ - 1 : TILESZ); - tptr->cpos[3].x = tptr->cpos[1].x; - tptr->cpos[3].y = tptr->cpos[2].y; - - for(k=0; k<4; k++) { - tptr->cptr[k] = fb_pixels + tptr->cpos[k].y * 320 + tptr->cpos[k].x; - } + tptr->x = j; + tptr->y = i; + tptr->fbptr = fb_pixels + i * 320 + j; tptr++; } } @@ -127,27 +109,130 @@ static uint16_t INLINE rend_pixel(int x, int y) return 0; } -#define FBPTR(x, y) (fb_pixels + ((y) << 8) + ((y) << 6) + (x)) +#define CMPMASK 0xe79c +static void rend_tile(uint16_t *fbptr, int x0, int y0, int tsz, int valid) +{ + uint16_t *cptr[4]; + uint16_t cpix[4], tmp; + uint32_t pp0, pp1, pp2, pp3, *fb32; + int i, x1, y1, offs; + + fb32 = (uint32_t*)fbptr; + + if(tsz <= 2) { + switch(valid) { + case 0: + fbptr[1] = fbptr[320] = fbptr[321] = *fbptr; + break; + case 1: + fbptr[0] = fbptr[320] = fbptr[321] = fbptr[1]; + break; + case 2: + fbptr[0] = fbptr[1] = fbptr[321] = fbptr[320]; + break; + case 3: + fbptr[0] = fbptr[1] = fbptr[320] = fbptr[321]; + break; + default: + printf("valid = %d\n", valid); + fbptr[0] = fbptr[1] = fbptr[320] = fbptr[321] = 0xff00; + } + return; + } + + offs = tsz - 1; + x1 = x0 + offs; + y1 = y0 + offs; + + cptr[0] = fbptr; + cptr[1] = fbptr + tsz - 1; + cptr[2] = fbptr + (offs << 8) + (offs << 6); + cptr[3] = cptr[2] + tsz - 1; + + cpix[0] = valid == 0 ? *cptr[0] : rend_pixel(x0, y0); + cpix[1] = valid == 1 ? *cptr[1] : rend_pixel(x1, y0); + cpix[2] = valid == 2 ? *cptr[2] : rend_pixel(x0, y1); + cpix[3] = valid == 3 ? *cptr[3] : rend_pixel(x1, y1); + + tmp = cpix[0] & CMPMASK; + if((cpix[1] & CMPMASK) != tmp) goto subdiv; + if((cpix[2] & CMPMASK) != tmp) goto subdiv; + if((cpix[3] & CMPMASK) != tmp) goto subdiv; + + pp0 = cpix[0] | ((uint32_t)cpix[0] << 16); + pp1 = cpix[1] | ((uint32_t)cpix[1] << 16); + pp2 = cpix[2] | ((uint32_t)cpix[2] << 16); + pp3 = cpix[3] | ((uint32_t)cpix[3] << 16); + + switch(tsz) { + case 2: +#ifdef SUBDBG + pp0 = 0x18ff; +#endif + fb32[0] = fb32[160] = pp0; + break; + case 4: +#ifdef SUBDBG + pp0 = pp1 = pp2 = pp3 = 0x03800380; +#endif + fb32[0] = fb32[160] = pp0; + fb32[1] = fb32[161] = pp1; + fb32[320] = fb32[480] = pp2; + fb32[321] = fb32[481] = pp3; + break; + case 8: +#ifdef SUBDBG + pp1 = pp0 = pp2 = pp3 = 0xe00fe00f; +#endif + fb32[0] = fb32[1] = pp0; fb32[2] = fb32[3] = pp1; + fb32[160] = fb32[161] = pp0; fb32[162] = fb32[163] = pp1; + fb32[320] = fb32[321] = pp0; fb32[322] = fb32[323] = pp1; + fb32[480] = fb32[481] = pp0; fb32[482] = fb32[483] = pp1; + fb32[640] = fb32[641] = pp2; fb32[642] = fb32[643] = pp3; + fb32[800] = fb32[801] = pp2; fb32[802] = fb32[803] = pp3; + fb32[960] = fb32[961] = pp2; fb32[962] = fb32[963] = pp3; + fb32[1120] = fb32[1121] = pp2; fb32[1122] = fb32[1123] = pp3; + break; + + case 16: +#ifdef SUBDBG + pp0 = 0xff00ff00; +#endif + for(i=0; i<4; i++) { + memset16(fbptr, pp0, 16); fbptr += 320; + memset16(fbptr, pp0, 16); fbptr += 320; + memset16(fbptr, pp0, 16); fbptr += 320; + memset16(fbptr, pp0, 16); fbptr += 320; + } + break; + } + return; + +subdiv: + *cptr[0] = cpix[0]; + *cptr[1] = cpix[1]; + *cptr[2] = cpix[2]; + *cptr[3] = cpix[3]; + + tsz >>= 1; + rend_tile(fbptr, x0, y0, tsz, 0); + rend_tile(fbptr + tsz, x0 + tsz, y0, tsz, 1); + fbptr += (tsz << 8) + (tsz << 6); + y0 += tsz; + rend_tile(fbptr, x0, y0, tsz, 2); + rend_tile(fbptr + tsz, x0 + tsz, y0, tsz, 3); +} static void draw(void) { int i, j, xbound, ybound; uint16_t *fbptr; - struct tile *tptr; + struct tile *tile; - tptr = tiles; + tile = tiles; for(i=0; icptr[0] = rend_pixel(tptr->cpos[0].x, tptr->cpos[0].y); - if(tptr->flags & LASTX) { - *tptr->cptr[1] = rend_pixel(tptr->cpos[1].x, tptr->cpos[1].y); - if(tptr->flags & LASTY) { - *tptr->cptr[3] = rend_pixel(tptr->cpos[3].x, tptr->cpos[3].y); - } - } - if(tptr->flags & LASTY) { - *tptr->cptr[2] = rend_pixel(tptr->cpos[2].x, tptr->cpos[2].y); - } - tptr++; + rend_tile(tile->fbptr, tile->x, tile->y, TILESZ, -1); + tile++; } swap_buffers(0);