diff --git a/src/platform/32x/asm/matrixPush.s b/src/platform/32x/asm/matrixPush.s index 2d692c3..3642c6d 100644 --- a/src/platform/32x/asm/matrixPush.s +++ b/src/platform/32x/asm/matrixPush.s @@ -1,39 +1,24 @@ - .text + .macro COPY_ROW + mov.l @r0+, r1 + mov.l @r0+, r2 + mov.l @r0+, r3 + mov.l @r0+, r4 + mov.l r1, @(32, r0) + mov.l r2, @(36, r0) + mov.l r3, @(40, r0) + mov.l r4, @(44, r0) + .endm + + .align 4 .global _matrixPush_asm _matrixPush_asm: mov.l .var_matrixPtr, r5 mov.l @r5, r0 - /* row[0] */ - mov.l @r0+, r1 - mov.l @r0+, r2 - mov.l @r0+, r3 - mov.l @r0+, r4 - mov.l r1, @(32, r0) - mov.l r2, @(36, r0) - mov.l r3, @(40, r0) - mov.l r4, @(44, r0) - - /* row[1] */ - mov.l @r0+, r1 - mov.l @r0+, r2 - mov.l @r0+, r3 - mov.l @r0+, r4 - mov.l r1, @(32, r0) - mov.l r2, @(36, r0) - mov.l r3, @(40, r0) - mov.l r4, @(44, r0) - - /* row[2] */ - mov.l @r0+, r1 - mov.l @r0+, r2 - mov.l @r0+, r3 - mov.l @r0+, r4 - mov.l r1, @(32, r0) - mov.l r2, @(36, r0) - mov.l r3, @(40, r0) - mov.l r4, @(44, r0) + COPY_ROW /* row[0] */ + COPY_ROW /* row[1] */ + COPY_ROW /* row[2] */ rts mov.l r0, @r5 diff --git a/src/platform/32x/main.cpp b/src/platform/32x/main.cpp index 0bf4ce7..bca96a1 100644 --- a/src/platform/32x/main.cpp +++ b/src/platform/32x/main.cpp @@ -114,12 +114,22 @@ int main() gameInit(gLevelInfo[gLevelID].name); int32 lastFrame = (MARS_SYS_COMM12 >> 1) - 1; + int32 fpsCounter = 0; + int32 fpsFrame = MARS_SYS_COMM12; + int32 vsyncRate = (MARS_VDP_DISPMODE & MARS_NTSC_FORMAT) ? 60 : 50; while (1) { int32 frame = MARS_SYS_COMM12; - if (!(MARS_VDP_DISPMODE & MARS_NTSC_FORMAT)) + if (frame - fpsFrame >= vsyncRate) + { + fpsFrame += vsyncRate; + fps = fpsCounter; + fpsCounter = 0; + } + + if (vsyncRate == 50) { frame = frame * 6 / 5; // PAL fix } @@ -132,16 +142,18 @@ int main() continue; lastFrame = frame; - + updateInput(); gameUpdate(delta); - + pageWait(); - + gameRender(); pageFlip(); + + fpsCounter++; } return 0; diff --git a/src/platform/32x/rasterizer.h b/src/platform/32x/rasterizer.h index f8a4988..9a48612 100644 --- a/src/platform/32x/rasterizer.h +++ b/src/platform/32x/rasterizer.h @@ -788,22 +788,197 @@ void rasterizeGTA_c(uint16* pixel, const VertexLink* L, const VertexLink* R) void rasterizeSprite_c(uint16* pixel, const VertexLink* L, const VertexLink* R) { - // TODO + R++; + const uint8* ft_lightmap = &gLightmap[L->v.g << 8]; + + int32 w = R->v.x - L->v.x; + if (w <= 0 || w >= DIV_TABLE_SIZE) return; + + int32 h = R->v.y - L->v.y; + if (h <= 0 || h >= DIV_TABLE_SIZE) return; + + int32 u = L->t.uv.v; + int32 v = L->t.uv.u; + + int32 iw = FixedInvU(w); + int32 ih = FixedInvU(h); + + int32 du = R->t.uv.v * iw >> 8; + int32 dv = R->t.uv.u * ih >> 8; + + if (L->v.y < 0) + { + pixel -= L->v.y * VRAM_WIDTH; + v -= L->v.y * dv; + h += L->v.y; + } + + if (R->v.y > FRAME_HEIGHT) + { + h -= R->v.y - FRAME_HEIGHT; + } + + uint8* ptr = (uint8*)pixel; + + if (h <= 0) return; + + ptr += L->v.x; + + if (L->v.x < 0) + { + ptr -= L->v.x; + u -= L->v.x * du; + w += L->v.x; + } + + if (R->v.x > FRAME_WIDTH) + { + w -= R->v.x - FRAME_WIDTH; + } + + if (w <= 0) return; + + for (int32 y = 0; y < h; y++) + { + const uint8* xtile = gTile + (v & 0xFF00); + + volatile uint8* xptr = ptr; + + int32 xu = u; + + int32 width = w; + + if (intptr_t(xptr) & 1) + { + uint8 indexB = xtile[xu >> 8]; + if (indexB) { + *xptr = ft_lightmap[indexB]; + } + + xptr++; + + xu += du; + } + + if (width & 1) + { + width--; + uint8 indexA = xtile[xu >> 8]; + if (indexA) { + xptr[width] = ft_lightmap[indexA]; + } + } + + for (int32 x = 0; x < width / 2; x++) + { + uint8 indexA = xtile[xu >> 8]; + xu += du; + uint8 indexB = xtile[xu >> 8]; + xu += du; + + if (indexA | indexB) + { + indexA = (indexA) ? ft_lightmap[indexA] : xptr[0]; + indexB = (indexB) ? ft_lightmap[indexB] : xptr[1]; + #ifdef CPU_BIG_ENDIAN + *(uint16*)xptr = indexB | (indexA << 8); + #else + *(uint16*)xptr = indexA | (indexB << 8); + #endif + } + + xptr += 2; + } + + v += dv; + + ptr += FRAME_WIDTH; + } } void rasterizeLineH_c(uint16* pixel, const VertexLink* L, const VertexLink* R) { - // TODO + R++; + int32 x = L->v.x; + int32 index = L->v.g; + int32 width = R->v.x; + + volatile uint8* ptr = (uint8*)pixel + x; + + if (intptr_t(ptr) & 1) + { + *ptr++ = index; + width--; + } + + if (width & 1) + { + width--; + ptr[width] = index; + } + + index |= (index << 8); + + for (int32 i = 0; i < width / 2; i++) + { + *(uint16*)ptr = index; + ptr += 2; + } } void rasterizeLineV_c(uint16* pixel, const VertexLink* L, const VertexLink* R) { - // TODO + R++; + int32 x = L->v.x; + int32 index = L->v.g; + int32 height = R->v.y; + + volatile uint8* ptr = (uint8*)pixel + x; + + for (int32 i = 0; i < height; i++) + { + *ptr = index; + ptr += FRAME_WIDTH; + } } void rasterizeFillS_c(uint16* pixel, const VertexLink* L, const VertexLink* R) { - // TODO + R++; + int32 x = L->v.x; + int32 shade = L->v.g; + int32 width = R->v.x; + int32 height = R->v.y; + + const uint8* lm = &gLightmap[shade << 8]; + + for (int32 i = 0; i < height; i++) + { + volatile uint8* ptr = (uint8*)pixel + x; + int32 w = width; + + if (intptr_t(ptr) & 1) + { + ptr[0] = lm[ptr[0]]; + ptr++; + w--; + } + + if (w & 1) + { + w--; + ptr[w] = lm[ptr[w]]; + } + + for (int32 i = 0; i < w / 2; i++) + { + uint16 p = *(uint16*)ptr; + *(uint16*)ptr = lm[p & 0xFF] | (lm[p >> 8] << 8); + ptr += 2; + } + + pixel += FRAME_WIDTH / 2; + } } #endif diff --git a/src/platform/32x/render.cpp b/src/platform/32x/render.cpp index 0e71971..d3e34db 100644 --- a/src/platform/32x/render.cpp +++ b/src/platform/32x/render.cpp @@ -960,7 +960,12 @@ void faceAddMesh(const MeshQuad* quads, const MeshTriangle* triangles, int32 qCo void clear() { - dmaFill((void*)fb, 0, FRAME_WIDTH * FRAME_HEIGHT); + MARS_VDP_FILLEN = 0xFF; + for(int32 i = 0x100; i < 0x100 + (FRAME_WIDTH * FRAME_HEIGHT >> 1); i += 0xFF) + { + MARS_VDP_FILADR = i; + MARS_VDP_FILDAT = 0x0000; + } } void renderRoom(const Room* room)