diff --git a/src/platform/32x/asm/rasterize.i b/src/platform/32x/asm/rasterize.i index f9adc3f..c92a552 100644 --- a/src/platform/32x/asm/rasterize.i +++ b/src/platform/32x/asm/rasterize.i @@ -11,7 +11,7 @@ .align 4 .global _rasterize_asm _rasterize_asm: - mov tile, r7 + mov tile, r7 // set 4th arg for proc mov flags, type shll2 type shlr16 type @@ -19,7 +19,7 @@ _rasterize_asm: cmp/eq #FACE_TYPE_F, type // cmp/eq #imm is 8-bit bf/s .getProc - mov L, R + mov L, R // [delay slot] extu.b flags, R .getProc: // proc = table[type] @@ -29,13 +29,14 @@ _rasterize_asm: // pixel = fb + y * 320 = fb + y * 256 + y * 64 mov.w @(VERTEX_Y, L), y + // FRAME_WIDTH = 320 = 256 + 64 mov.l var_fb, pixel shll8 y add y, pixel // pixel += y * 256 shar y shar y jmp @proc - add y, pixel // pixel += y * 64 + add y, pixel // [delay slot] pixel += y * 64 .align 2 var_fb: @@ -49,7 +50,7 @@ var_table: .long 0xC0000000 + _rasterizeFT_asm - _block_render_start .long 0xC0000000 + _rasterizeFT_asm - _block_render_start .long 0xC0000000 + _rasterizeGT_asm - _block_render_start - .long 0xC0000000 + _rasterizeGT_asm - _block_render_start + .long 0xC0000000 + _rasterizeGT_asm - _block_render_start #else .long _rasterizeS_asm .long _rasterizeF_asm diff --git a/src/platform/32x/main.cpp b/src/platform/32x/main.cpp index 47b3d2d..10d6301 100644 --- a/src/platform/32x/main.cpp +++ b/src/platform/32x/main.cpp @@ -84,9 +84,14 @@ void updateInput() if (mask & SEGA_CTRL_MODE) keys |= IK_SELECT; } -void* osLoadLevel(const char* name) +const void* osLoadScreen(LevelID id) { - return (void*)LEVEL1_PKD; + return TITLE_SCR; +} + +const void* osLoadLevel(LevelID id) +{ + return (void*)LEVEL1_PKD; // TODO } uint16 pageIndex = 0; @@ -190,7 +195,7 @@ int main() MARS_SYS_COMM4 = 0; - gameInit(gLevelInfo[gLevelID].name); + gameInit(); int32 lastFrame = (gFrameIndex >> 1) - 1; int32 fpsCounter = 0; diff --git a/src/platform/32x/render.cpp b/src/platform/32x/render.cpp index 186f4bd..254f008 100644 --- a/src/platform/32x/render.cpp +++ b/src/platform/32x/render.cpp @@ -116,8 +116,8 @@ X_INLINE Face* faceAdd(int32 depth) extern "C" { X_NOINLINE void drawPoly(uint32 flags, VertexLink* v, const ColorIndex* tile); - X_NOINLINE void drawTriangle(uint32 flags, VertexLink* v, const ColorIndex* tile); - X_NOINLINE void drawQuad(uint32 flags, VertexLink* v, const ColorIndex* tile); + X_INLINE void drawTriangle(uint32 flags, VertexLink* v, const ColorIndex* tile); + X_INLINE void drawQuad(uint32 flags, VertexLink* v, const ColorIndex* tile); } extern "C" { @@ -598,6 +598,26 @@ int32 sphereIsVisible_c(int32 sx, int32 sy, int32 sz, int32 r) void flush_ot(int32 bit) { + VertexLink v[4 + 3]; + VertexLink* q = v; + VertexLink* t = v + 4; + // quad + q[0].prev = 3; + q[0].next = 1; + q[1].prev = -1; + q[1].next = 1; + q[2].prev = -1; + q[2].next = 1; + q[3].prev = -1; + q[3].next = -3; + // triangle + t[0].prev = 2; + t[0].next = 1; + t[1].prev = -1; + t[1].next = 1; + t[2].prev = -1; + t[2].next = -2; + int32 index = 0; const ColorIndex* tile = NULL; @@ -617,37 +637,37 @@ void flush_ot(int32 bit) uint32 flags = face->flags; - VertexLink v[16]; - uint32 type = (flags >> FACE_TYPE_SHIFT) & FACE_TYPE_MASK; if (type <= FACE_TYPE_GTA) { + VertexLink* ptr = (flags & FACE_TRIANGLE) ? t : q; + if (type > FACE_TYPE_F) { const Texture &tex = level.textures[flags & FACE_TEXTURE]; tile = (ColorIndex*)tex.tile; - v[0].t.t = 0xFF00FF00 & (tex.uv01); - v[1].t.t = 0xFF00FF00 & (tex.uv01 << 8); - v[2].t.t = 0xFF00FF00 & (tex.uv23); - v[3].t.t = 0xFF00FF00 & (tex.uv23 << 8); + ptr[0].t.t = 0xFF00FF00 & (tex.uv01); + ptr[1].t.t = 0xFF00FF00 & (tex.uv01 << 8); + ptr[2].t.t = 0xFF00FF00 & (tex.uv23); + ptr[3].t.t = 0xFF00FF00 & (tex.uv23 << 8); } - v[0].v = gVertices[face->indices[0]]; - v[1].v = gVertices[face->indices[1]]; - v[2].v = gVertices[face->indices[2]]; + ptr[0].v = gVertices[face->indices[0]]; + ptr[1].v = gVertices[face->indices[1]]; + ptr[2].v = gVertices[face->indices[2]]; if (!(flags & FACE_TRIANGLE)) { - v[3].v = gVertices[face->indices[3]]; + ptr[3].v = gVertices[face->indices[3]]; } if (flags & FACE_CLIPPED) { - drawPoly(flags, v, tile); + drawPoly(flags, ptr, tile); } else { if (flags & FACE_TRIANGLE) { - drawTriangle(flags, v, tile); + drawTriangle(flags, ptr, tile); } else { - drawQuad(flags, v, tile); + drawQuad(flags, ptr, tile); } } } @@ -716,7 +736,7 @@ void flush_c() PROFILE(CNT_FLUSH); MARS_WAIT(); - CacheClear(); + CacheClear(); MARS_SYS_COMM2 = OT_SIZE; MARS_SYS_COMM6 = OT_SIZE; @@ -734,67 +754,6 @@ void flush_c() #endif } -VertexLink* clipPoly(VertexLink* poly, VertexLink* tmp, int32 &pCount) -{ - #define LERP_SHIFT 6 - #define LERP(a,b,t) (b + ((a - b) * t >> LERP_SHIFT)) - //#define LERP2(a,b,ta,tb) LERP(a,b,t) - #define LERP2(a,b,ta,tb) (b + (((a - b) * ta / tb) >> LERP_SHIFT) ) // less gaps between clipped polys, but slow - - #define CLIP_AXIS(X, Y, edge, output) {\ - int32 ta = (edge - b->v.X) << LERP_SHIFT;\ - int32 tb = (a->v.X - b->v.X);\ - ASSERT(tb != 0);\ - int32 t = ta / tb;\ - VertexLink* v = output + count++;\ - v->v.X = edge;\ - v->v.Y = LERP2(a->v.Y, b->v.Y, ta, tb);\ - v->v.g = LERP(a->v.g, b->v.g, t);\ - v->t.uv.u = LERP(a->t.uv.u, b->t.uv.u, t);\ - v->t.uv.v = LERP(a->t.uv.v, b->t.uv.v, t);\ - } - - #define CLIP_XY(X, Y, X0, X1, input, output) {\ - const VertexLink *a, *b = input + pCount - 1;\ - for (int32 i = 0; i < pCount; i++) {\ - a = b;\ - b = input + i;\ - if (a->v.X < X0) {\ - if (b->v.X < X0) continue;\ - CLIP_AXIS(X, Y, X0, output);\ - } else if (a->v.X > X1) {\ - if (b->v.X > X1) continue;\ - CLIP_AXIS(X, Y, X1, output);\ - }\ - if (b->v.X < X0) {\ - CLIP_AXIS(X, Y, X0, output);\ - } else if (b->v.X > X1) {\ - CLIP_AXIS(X, Y, X1, output);\ - } else {\ - output[count++] = *b;\ - }\ - }\ - if (count < 3) return NULL;\ - } - - int32 count = 0; - - VertexLink *in = poly; - VertexLink *out = tmp; - - // clip x - CLIP_XY(x, y, 0, FRAME_WIDTH, in, out); - - pCount = count; - count = 0; - - // clip y - CLIP_XY(y, x, 0, FRAME_HEIGHT, out, in); - pCount = count; - - return in; -} - void renderInit() { gVerticesBase = gVertices; @@ -813,142 +772,113 @@ void renderLevelFree() { } -extern "C" X_NOINLINE void drawTriangle(uint32 flags, VertexLink* v, const ColorIndex* tile) +extern "C" X_INLINE void drawTriangle(uint32 flags, VertexLink* v, const ColorIndex* tile) { - VertexLink* v0 = v + 0; - VertexLink* v1 = v + 1; - VertexLink* v2 = v + 2; - - v0->next = v1 - v0; - v1->next = v2 - v1; - v2->next = v0 - v2; - v0->prev = v2 - v0; - v1->prev = v0 - v1; - v2->prev = v1 - v2; - - VertexLink* top; - - if (v0->v.y < v1->v.y) { - if (v0->v.y < v2->v.y) { - top = v0; - } else { - top = v2; - } - } else { - if (v1->v.y < v2->v.y) { - top = v1; - } else { - top = v2; - } - } - + VertexLink* top = v; + if (top->v.y > v[1].v.y) top = v + 1; + if (top->v.y > v[2].v.y) top = v + 2; rasterize(flags, top, tile); } -extern "C" X_NOINLINE void drawQuad(uint32 flags, VertexLink* v, const ColorIndex* tile) +extern "C" X_INLINE void drawQuad(uint32 flags, VertexLink* v, const ColorIndex* tile) { - VertexLink* v0 = v + 0; - VertexLink* v1 = v + 1; - VertexLink* v2 = v + 2; - VertexLink* v3 = v + 3; - - v0->next = v1 - v0; - v1->next = v2 - v1; - v2->next = v3 - v2; - v3->next = v0 - v3; - v0->prev = v3 - v0; - v1->prev = v0 - v1; - v2->prev = v1 - v2; - v3->prev = v2 - v3; - - VertexLink* top; - - if (v0->v.y < v1->v.y) { - if (v0->v.y < v2->v.y) { - top = (v0->v.y < v3->v.y) ? v0 : v3; - } else { - top = (v2->v.y < v3->v.y) ? v2 : v3; - } - } else { - if (v1->v.y < v2->v.y) { - top = (v1->v.y < v3->v.y) ? v1 : v3; - } else { - top = (v2->v.y < v3->v.y) ? v2 : v3; - } - } - + VertexLink* top = v; + if (top->v.y > v[1].v.y) top = v + 1; + if (top->v.y > v[2].v.y) top = v + 2; + if (top->v.y > v[3].v.y) top = v + 3; rasterize(flags, top, tile); } extern "C" X_NOINLINE void drawPoly(uint32 flags, VertexLink* v, const ColorIndex* tile) { - VertexLink tmp[16]; + #define LERP_SHIFT 6 + #define LERP(a,b,t) (b + ((a - b) * t >> LERP_SHIFT)) + //#define LERP2(a,b,ta,tb) LERP(a,b,t) + #define LERP2(a,b,ta,tb) (b + (((a - b) * ta / tb) >> LERP_SHIFT) ) // less gaps between clipped polys, but slow - int32 count = (flags & FACE_TRIANGLE) ? 3 : 4; - - v = clipPoly(v, tmp, count); - - if (!v) return; - - if (count <= 4) - { - if (count == 3) { - - if (v[0].v.y == v[1].v.y && - v[0].v.y == v[2].v.y) - return; - - drawTriangle(flags, v, tile); - } else { - - if (v[0].v.y == v[1].v.y && - v[0].v.y == v[2].v.y && - v[0].v.y == v[3].v.y) - return; - - drawQuad(flags, v, tile); - } - return; + #define CLIP_AXIS(X, Y, edge, output) {\ + int32 ta = (edge - b->v.X) << LERP_SHIFT;\ + int32 tb = (a->v.X - b->v.X);\ + ASSERT(tb != 0);\ + int32 t = ta / tb;\ + ASSERT(count < 8);\ + VertexLink* p = output + count++;\ + p->v.X = edge;\ + p->v.Y = LERP2(a->v.Y, b->v.Y, ta, tb);\ + p->v.g = LERP(a->v.g, b->v.g, t);\ + p->t.uv.u = LERP(a->t.uv.u, b->t.uv.u, t);\ + p->t.uv.v = LERP(a->t.uv.v, b->t.uv.v, t);\ } - VertexLink* top = v; - top->next = (v + 1) - top; - top->prev = (v + count - 1) - top; + #define CLIP_XY(X, Y, X0, X1, input, output) {\ + const VertexLink *a, *b = input + pCount - 1;\ + for (int32 i = 0; i < pCount; i++) {\ + a = b;\ + b = input + i;\ + if (a->v.X < X0) {\ + if (b->v.X < X0) continue;\ + CLIP_AXIS(X, Y, X0, output);\ + } else if (a->v.X > X1) {\ + if (b->v.X > X1) continue;\ + CLIP_AXIS(X, Y, X1, output);\ + }\ + if (b->v.X < X0) {\ + CLIP_AXIS(X, Y, X0, output);\ + } else if (b->v.X > X1) {\ + CLIP_AXIS(X, Y, X1, output);\ + } else {\ + ASSERT(count < 8);\ + output[count++] = *b;\ + }\ + }\ + if (count < 3) return;\ + } - bool skip = true; + VertexLink tmp[8]; + VertexLink out[8]; - for (int32 i = 1; i < count; i++) + int32 pCount = (flags & FACE_TRIANGLE) ? 3 : 4; + int32 count = 0; + + // clip x + CLIP_XY(x, y, 0, FRAME_WIDTH, v, tmp); + + pCount = count; + count = 0; + + // clip y + CLIP_XY(y, x, 0, FRAME_HEIGHT, tmp, out); + + VertexLink* first = out; + VertexLink* last = out + count - 1; + + bool skip = (first->v.y == last->v.y); + + VertexLink* top = (first->v.y < last->v.y) ? first : last; + first->prev = count - 1; + first->next = 1; + last->prev = -1; + last->next = 1 - count; + + for (int32 i = 1; i < count - 1; i++) { - int8 next = i + 1; - int8 prev = i - 1; - - if (next >= count) { - next -= count; - } - - if (prev < 0) { - prev += count; - } - - next -= i; - prev -= i; - - VertexLink *p = v + i; - p->next = next; - p->prev = prev; + VertexLink* p = out + i; if (p->v.y != top->v.y) { - if (p->v.y < top->v.y) { + if (p->v.y < top->v.y) + { top = p; } skip = false; } + + p->prev = -1; + p->next = 1; } - if (skip) { - return; // zero height poly - } + if (skip) + return; rasterize(flags, top, tile); }