From dba6a547398a7e05e117d1f4fbeb1a22ff3890e1 Mon Sep 17 00:00:00 2001 From: XProger Date: Sat, 30 Apr 2022 03:57:33 +0300 Subject: [PATCH] #368 GBA use sphere culling instead of box (boxIsVisible) --- src/fixed/common.h | 37 +++-- src/fixed/draw.h | 113 ++++++++++----- src/platform/32x/render.cpp | 73 ---------- src/platform/3do/render_cel.cpp | 128 ----------------- src/platform/gba/OpenLara.vcxproj | 10 +- src/platform/gba/asm/boxIsVisible.s | 209 ---------------------------- src/platform/gba/asm/common_asm.inc | 4 +- src/platform/gba/main.cpp | 2 +- src/platform/gba/render.iwram.cpp | 87 ++---------- 9 files changed, 116 insertions(+), 547 deletions(-) delete mode 100644 src/platform/gba/asm/boxIsVisible.s diff --git a/src/fixed/common.h b/src/fixed/common.h index cb4bab7d..faff2261 100644 --- a/src/fixed/common.h +++ b/src/fixed/common.h @@ -63,7 +63,7 @@ #define USE_FMT (LVL_FMT_PKD) -#include + #include #elif defined(__NDS__) #define USE_DIV_TABLE @@ -73,7 +73,7 @@ #define USE_FMT (LVL_FMT_PSX) -#include + #include #include #include #elif defined(__TNS__) @@ -279,6 +279,8 @@ typedef uint16 divTableInt; typedef uint8 ColorIndex; #endif +#define ADDR_ALIGN4(x) ((uint8*)x += ((intptr_t(x) + 3) & ~3) - intptr_t(x)) + //#include inline void* operator new(size_t, void *ptr) { @@ -319,15 +321,7 @@ X_INLINE int32 abs(int32 x) { #define ASSERT(x) #endif -#if defined(__GBA__) - #define IME_DISABLE() u16 origIME = REG_IME; REG_IME = 0 - #define IME_ENABLE() REG_IME = origIME; -#else - #define IME_DISABLE() - #define IME_ENABLE() -#endif - -#if defined(__GBA__WIN__) +#if defined(__GBA_WIN__) extern uint16 fb[VRAM_WIDTH * FRAME_HEIGHT]; #elif defined(__GBA__) extern uint32 fb; @@ -895,11 +889,10 @@ struct RoomVertex { #if defined(__3DO__) uint16 xyz565; -#elif defined(__GBA__) || defined(__32X__) +#elif defined(__GBA__) || defined(__GBA_WIN__) || defined(__32X__) uint8 x, y, z, g; #else - uint8 x, y, z; - uint8 cR, cG, cB; + uint8 x, y, z, g; #endif }; @@ -2653,6 +2646,15 @@ X_INLINE void swap(T &a, T &b) { b = tmp; } +X_INLINE uint16 swap16(uint16 x) { + return ((x & 0x00FF) << 8) | ((x & 0xFF00) >> 8); +} + +X_INLINE uint32 swap32(uint32 x) { + return ((x & 0x000000FF) << 24) | ((x & 0x0000FF00) << 8) | ((x & 0x00FF0000) >> 8) | ((x & 0xFF000000) >> 24); +} + + extern int32 gRandSeedLogic; extern int32 gRandSeedDraw; @@ -2731,7 +2733,6 @@ vec3i boxPushOut(const AABBi &a, const AABBi &b); void matrixRotateYXZ_asm(int32 angleX, int32 angleY, int32 angleZ); void boxTranslate_asm(AABBi &box, int32 x, int32 y, int32 z); void boxRotateYQ_asm(AABBi &box, int32 quadrant); - int32 boxIsVisible_asm(const AABBs* box); int32 sphereIsVisible_asm(int32 x, int32 y, int32 z, int32 r); void flush_asm(); } @@ -2750,7 +2751,6 @@ vec3i boxPushOut(const AABBi &a, const AABBi &b); #define matrixRotateYQ matrixRotateYQ_asm #define boxTranslate boxTranslate_asm #define boxRotateYQ boxRotateYQ_asm - #define boxIsVisible boxIsVisible_asm #define sphereIsVisible sphereIsVisible_asm #define flush flush_asm #else @@ -2768,7 +2768,6 @@ vec3i boxPushOut(const AABBi &a, const AABBi &b); #define matrixRotateYQ matrixRotateYQ_c #define boxTranslate boxTranslate_c #define boxRotateYQ boxRotateYQ_c - #define boxIsVisible boxIsVisible_c #define sphereIsVisible sphereIsVisible_c #define flush flush_c @@ -2787,7 +2786,6 @@ vec3i boxPushOut(const AABBi &a, const AABBi &b); void boxTranslate_c(AABBi &box, int32 x, int32 y, int32 z); void boxRotateYQ_c(AABBi &box, int32 quadrant); - int32 boxIsVisible_c(const AABBs* box); int32 sphereIsVisible_c(int32 x, int32 y, int32 z, int32 r); void flush_c(); #endif @@ -2807,7 +2805,6 @@ vec3i boxPushOut(const AABBi &a, const AABBi &b); #undef matrixRotateYQ //#undef boxTranslate //#undef boxRotateYQ - //#undef boxIsVisible //#undef sphereIsVisible //#undef flush @@ -2825,7 +2822,6 @@ vec3i boxPushOut(const AABBi &a, const AABBi &b); #define matrixRotateYQ matrixRotateYQ_asm //#define boxTranslate boxTranslate_asm //#define boxRotateYQ boxRotateYQ_asm - //#define boxIsVisible boxIsVisible_asm //#define sphereIsVisible sphereIsVisible_asm //#define flush flush_asm @@ -2845,7 +2841,6 @@ vec3i boxPushOut(const AABBi &a, const AABBi &b); void matrixRotateYXZ_asm(int32 angleX, int32 angleY, int32 angleZ); void boxTranslate_asm(AABBi &box, int32 x, int32 y, int32 z); void boxRotateYQ_asm(AABBi &box, int32 quadrant); - int32 boxIsVisible_asm(const AABBs* box); int32 sphereIsVisible_asm(int32 x, int32 y, int32 z, int32 r); void flush_asm(); } diff --git a/src/fixed/draw.h b/src/fixed/draw.h index 93d233bb..bf665d20 100644 --- a/src/fixed/draw.h +++ b/src/fixed/draw.h @@ -8,8 +8,8 @@ #ifdef TEST_ROOM_CACHE RoomVertex roomVert[512]; -RoomQuad roomQuads[512]; -RoomTriangle roomTri[64]; +EWRAM_DATA RoomQuad roomQuads[512]; +EWRAM_DATA RoomTriangle roomTri[64]; #endif void drawInit() @@ -26,6 +26,16 @@ void drawInit() int16 rot = i * (ANGLE_90 * 4) / MAX_CAUSTICS; gCaustics[i] = sin(rot) * 768 >> FIXED_SHIFT; } +} + +void drawFree() +{ + renderFree(); +} + +void drawLevelInit() +{ + renderLevelInit(); #ifdef TEST_ROOM_CACHE Room &room = rooms[14]; @@ -40,16 +50,6 @@ void drawInit() #endif } -void drawFree() -{ - renderFree(); -} - -void drawLevelInit() -{ - renderLevelInit(); -} - void drawLevelFree() { renderLevelFree(); @@ -622,35 +622,81 @@ void drawModel(const ItemObj* item) frameDelta = 0; #endif - matrixPush(); - matrixTranslateAbs(item->pos.x, item->pos.y, item->pos.z); - matrixRotateYXZ(item->angle.x, item->angle.y, item->angle.z); + int32 sx, sy, sz, sr, smin, smax; + smin = frameA->box.minX; + smax = frameA->box.maxX; + sx = (smax + smin) >> 1; + sr = (smax - smin); + + smin = frameA->box.minY; + smax = frameA->box.maxY; + sy = (smax + smin) >> 1; + sr = X_MAX(sr, (smax - smin)); + + smin = frameA->box.minZ; + smax = frameA->box.maxZ; + sz = (smax + smin) >> 1; + sr = X_MAX(sr, (smax - smin)); - int32 vis = boxIsVisible(&frameA->box); + // approx. radius (TODO more precise) + sr = (sr >> 1) + (sr >> 2); - if (vis) + // rotate sphere center by quadrant + uint16 quadrant = uint16(item->angle.y + ANGLE_45) >> ANGLE_SHIFT_90; + + if (quadrant != 0) { - int32 intensity = item->intensity << 5; + int32 ix = sx; + int32 iz = sz; - if (intensity == 0) { - vec3i point = item->getRelative(frameA->box.getCenter()); - calcLightingDynamic(item->room, point); - } else { - calcLightingStatic(intensity); + switch (quadrant) + { + case 1: + sx = iz; + sz = -ix; + break; + case 2: + sx = -ix; + sz = -iz; + break; + case 3: + sx = -iz; + sz = ix; + break; } + } - // skip rooms portal clipping for objects - if (item->type == ITEM_LARA) { - drawLaraNodesLerp(item, frameA, frameB, frameDelta, frameRate); - } else { - drawNodesLerp(item, frameA, frameB, frameDelta, frameRate); - } + sx += item->pos.x - gCameraViewPos.x; + sy += item->pos.y - gCameraViewPos.y; + sz += item->pos.z - gCameraViewPos.z; + + if (!sphereIsVisible(sx, sy, sz, sr)) + return; + + matrixPush(); + matrixTranslateAbs(item->pos.x, item->pos.y, item->pos.z); + matrixRotateYXZ(item->angle.x, item->angle.y, item->angle.z); + + int32 intensity = item->intensity << 5; + + if (intensity == 0) { + vec3i point = item->getRelative(frameA->box.getCenter()); + calcLightingDynamic(item->room, point); + } else { + calcLightingStatic(intensity); + } + + // skip rooms portal clipping for objects + if (item->type == ITEM_LARA) { + drawLaraNodesLerp(item, frameA, frameB, frameDelta, frameRate); + } else { + drawNodesLerp(item, frameA, frameB, frameDelta, frameRate); } matrixPop(); // shadow - if (vis && (item->flags & ITEM_FLAG_SHADOW)) { + if (item->flags & ITEM_FLAG_SHADOW) { drawShadow(item, 160); // TODO per item shadow size } } @@ -741,11 +787,8 @@ void drawRoom(const Room* room) matrixTranslateSet(px, py, pz); matrixRotateYQ(q); - int32 vis = boxIsVisible(&staticMesh->vbox); - if (vis) { - calcLightingStatic(STATIC_MESH_INTENSITY(mesh->zf)); - drawMesh(staticMesh->meshIndex); - } + calcLightingStatic(STATIC_MESH_INTENSITY(mesh->zf)); + drawMesh(staticMesh->meshIndex); matrixPop(); } diff --git a/src/platform/32x/render.cpp b/src/platform/32x/render.cpp index 767808ff..d22c39cf 100644 --- a/src/platform/32x/render.cpp +++ b/src/platform/32x/render.cpp @@ -529,79 +529,6 @@ void faceAddMeshTriangles_c(const MeshTriangle* polys, int32 count) } } -bool transformBoxRect(const AABBs* box, RectMinMax* rect) -{ - const Matrix &m = matrixGet(); - - if ((m.e23 < (VIEW_MIN_F >> MATRIX_FIXED_SHIFT)) || (m.e23 >= (VIEW_MAX_F >> MATRIX_FIXED_SHIFT))) - return false; - - vec3i v[8]; - v[0] = _vec3i( box->minX, box->minY, box->minZ ), - v[1] = _vec3i( box->maxX, box->minY, box->minZ ), - v[2] = _vec3i( box->minX, box->maxY, box->minZ ), - v[3] = _vec3i( box->maxX, box->maxY, box->minZ ), - v[4] = _vec3i( box->minX, box->minY, box->maxZ ), - v[5] = _vec3i( box->maxX, box->minY, box->maxZ ), - v[6] = _vec3i( box->minX, box->maxY, box->maxZ ), - v[7] = _vec3i( box->maxX, box->maxY, box->maxZ ); - - *rect = RectMinMax( INT_MAX, INT_MAX, INT_MIN, INT_MIN ); - - for (int32 i = 0; i < 8; i++) - { - int32 z = DP43(m.e20, m.e21, m.e22, m.e23, v[i].x, v[i].y, v[i].z); - - if (z < VIEW_MIN_F || z >= VIEW_MAX_F) - continue; - - int32 x = DP43(m.e00, m.e01, m.e02, m.e03, v[i].x, v[i].y, v[i].z); - int32 y = DP43(m.e10, m.e11, m.e12, m.e13, v[i].x, v[i].y, v[i].z); - - x >>= FIXED_SHIFT; - y >>= FIXED_SHIFT; - z >>= FIXED_SHIFT; - - PERSPECTIVE(x, y, z); - - if (x < rect->x0) rect->x0 = x; - if (x > rect->x1) rect->x1 = x; - if (y < rect->y0) rect->y0 = y; - if (y > rect->y1) rect->y1 = y; - } - - rect->x0 += (FRAME_WIDTH / 2); - rect->y0 += (FRAME_HEIGHT / 2); - rect->x1 += (FRAME_WIDTH / 2); - rect->y1 += (FRAME_HEIGHT / 2); - - return true; -} - -int32 rectIsVisible(const RectMinMax* rect) -{ - if (rect->x0 > rect->x1 || - rect->x0 > viewport.x1 || - rect->x1 < viewport.x0 || - rect->y0 > viewport.y1 || - rect->y1 < viewport.y0) return 0; // not visible - - if (rect->x0 < viewport.x0 || - rect->x1 > viewport.x1 || - rect->y0 < viewport.y0 || - rect->y1 > viewport.y1) return -1; // clipped - - return 1; // fully visible -} - -int32 boxIsVisible_c(const AABBs* box) -{ - RectMinMax rect; - if (!transformBoxRect(box, &rect)) - return 0; // not visible - return rectIsVisible(&rect); -} - int32 sphereIsVisible_c(int32 sx, int32 sy, int32 sz, int32 r) { Matrix &m = matrixGet(); diff --git a/src/platform/3do/render_cel.cpp b/src/platform/3do/render_cel.cpp index bc63d518..1ea7cd32 100644 --- a/src/platform/3do/render_cel.cpp +++ b/src/platform/3do/render_cel.cpp @@ -43,9 +43,6 @@ extern Item screenItem; #define FACE_MIP_SHIFT 11 #define FACE_TEXTURE 0x07FF - -#define F16_SHIFT 2 // special f14 to f16 shift for the math co-processor - #define DUP16(value) value | (value << 16) enum ShadeValue @@ -693,131 +690,6 @@ void faceAddMeshTrianglesFlat_c(const MeshTriangle* polys, int32 count, uint32 s } } -int32 boxIsVisible_c(const AABBs* box) -{ - Matrix &m = matrixGet(); - - if ((m.e23 < VIEW_MIN_F) || (m.e23 >= VIEW_MAX_F)) { - return 0; - } - - const int32* ptr = (int32*)box; - - enum { - MAX_X, - MIN_X, - MAX_Y, - MIN_Y, - MAX_Z, - MIN_Z, - MIN_MAX_SIZE - }; - - int32 mm[MIN_MAX_SIZE][3]; - int32 min, max, minX, minY, minZ, maxX, maxY, maxZ; - - #define PROJECT(dx,dy,dz){\ - int32 x, y, z;\ - x = mm[dx][0] + mm[dy][0] + mm[dz][0];\ - y = mm[dx][1] + mm[dy][1] + mm[dz][1];\ - z = mm[dx][2] + mm[dy][2] + mm[dz][2];\ - if (z >= VIEW_MIN_F && z <= VIEW_MAX_F) {\ - z = gDivTable[z >> (FIXED_SHIFT + PROJ_SHIFT)];\ - x = x * z;\ - y = y * z;\ - if (x < rMinX) rMinX = x;\ - if (y < rMinY) rMinY = y;\ - if (x > rMaxX) rMaxX = x;\ - if (y > rMaxY) rMaxY = y;\ - }\ - } - - int32 xx = ptr[0]; - int32 yy = ptr[1]; - int32 zz = ptr[2]; - - // pre-transform min/max Z - min = zz >> 16; - minX = m.e02 * min + m.e03; - minY = m.e12 * min + m.e13; - minZ = m.e22 * min + m.e23; - max = zz << 16 >> 16; - maxX = m.e02 * max + m.e03; - maxY = m.e12 * max + m.e13; - maxZ = m.e22 * max + m.e23; - mm[MAX_Z][0] = maxX >> FIXED_SHIFT; - mm[MAX_Z][1] = maxY >> FIXED_SHIFT; - mm[MAX_Z][2] = maxZ; - mm[MIN_Z][0] = minX >> FIXED_SHIFT; - mm[MIN_Z][1] = minY >> FIXED_SHIFT; - mm[MIN_Z][2] = minZ; - - // pre-transform min/max Y - min = yy >> 16; - minX = m.e01 * min; - minY = m.e11 * min; - minZ = m.e21 * min; - max = yy << 16 >> 16; - maxX = m.e01 * max; - maxY = m.e11 * max; - maxZ = m.e21 * max; - mm[MAX_Y][0] = maxX >> FIXED_SHIFT; - mm[MAX_Y][1] = maxY >> FIXED_SHIFT; - mm[MAX_Y][2] = maxZ; - mm[MIN_Y][0] = minX >> FIXED_SHIFT; - mm[MIN_Y][1] = minY >> FIXED_SHIFT; - mm[MIN_Y][2] = minZ; - - // pre-transform min/max X - min = xx >> 16; - minX = m.e00 * min; - minY = m.e10 * min; - minZ = m.e20 * min; - max = xx << 16 >> 16; - maxX = m.e00 * max; - maxY = m.e10 * max; - maxZ = m.e20 * max; - mm[MAX_X][0] = maxX >> FIXED_SHIFT; - mm[MAX_X][1] = maxY >> FIXED_SHIFT; - mm[MAX_X][2] = maxZ; - mm[MIN_X][0] = minX >> FIXED_SHIFT; - mm[MIN_X][1] = minY >> FIXED_SHIFT; - mm[MIN_X][2] = minZ; - - int32 rMinX = INT_MAX; - int32 rMinY = INT_MAX; - int32 rMaxX = INT_MIN; - int32 rMaxY = INT_MIN; - - PROJECT(MIN_X, MIN_Y, MIN_Z); - PROJECT(MAX_X, MIN_Y, MIN_Z); - PROJECT(MIN_X, MAX_Y, MIN_Z); - PROJECT(MAX_X, MAX_Y, MIN_Z); - PROJECT(MIN_X, MIN_Y, MAX_Z); - PROJECT(MAX_X, MIN_Y, MAX_Z); - PROJECT(MIN_X, MAX_Y, MAX_Z); - PROJECT(MAX_X, MAX_Y, MAX_Z); - - rMinX >>= (16 - PROJ_SHIFT); - rMaxX >>= (16 - PROJ_SHIFT); - - if (rMinX > rMaxX) return 0; - - // rect Y is shifted left by 16 - rMinY <<= PROJ_SHIFT; - rMaxY <<= PROJ_SHIFT; - - int32 vMinXY = viewportRel.minXY; - int32 vMaxXY = viewportRel.maxXY; - - if (rMaxX < (vMinXY >> 16) || - rMaxY < (vMinXY << 16) || - rMinX > (vMaxXY >> 16) || - rMinY > (vMaxXY << 16)) return 0; - - return 1; -} - int32 sphereIsVisible_c(int32 x, int32 y, int32 z, int32 r) { Matrix &m = matrixGet(); diff --git a/src/platform/gba/OpenLara.vcxproj b/src/platform/gba/OpenLara.vcxproj index f90452d4..b7e2282b 100644 --- a/src/platform/gba/OpenLara.vcxproj +++ b/src/platform/gba/OpenLara.vcxproj @@ -30,6 +30,8 @@ + + @@ -116,7 +118,7 @@ Level2 Disabled true - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + __GBA_WIN__;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true @@ -132,7 +134,7 @@ Level3 Disabled true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + __GBA_WIN__;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true @@ -149,7 +151,7 @@ true true true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + __GBA_WIN__;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreaded @@ -170,7 +172,7 @@ true true true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + __GBA_WIN__;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreaded diff --git a/src/platform/gba/asm/boxIsVisible.s b/src/platform/gba/asm/boxIsVisible.s deleted file mode 100644 index d78aa8a4..00000000 --- a/src/platform/gba/asm/boxIsVisible.s +++ /dev/null @@ -1,209 +0,0 @@ -#include "common_asm.inc" - -mx .req r0 -my .req r1 -mz .req r2 -m .req r3 -vx .req r4 -vy .req r5 -vz .req r6 -x .req r7 -y .req r8 -z .req r9 -rMinX .req r10 -rMinY .req r11 -rMaxX .req r12 -rMaxY .req lr - -boxArg .req mx -tmp .req mz - -bz .req mz -offset .req m -dz .req offset -xx .req rMinX -yy .req rMinY -zz .req rMaxX -min .req rMaxY -max .req rMaxY -vMinXY .req x -vMaxXY .req y -vp .req x - -minX .req x -minY .req y -minZ .req z -maxX .req mx -maxY .req my -maxZ .req mz - -MAX_X = (0 * 3 * 4) -MIN_X = (1 * 3 * 4) -MAX_Y = (2 * 3 * 4) -MIN_Y = (3 * 3 * 4) -MAX_Z = (4 * 3 * 4) -MIN_Z = (5 * 3 * 4) -SIZE = (6 * 3 * 4) - -.macro project dx, dy, dz - add offset, sp, \dz - ldmia offset, {x, y, z} - - add offset, sp, \dy - ldmia offset, {vx, vy, vz} - add x, x, vx - add y, y, vy - add z, z, vz - - add offset, sp, \dx - ldmia offset, {vx, vy, vz} - add z, z, vz - - // check z clipping - sub offset, z, #VIEW_MIN_F - cmp offset, #(VIEW_MAX_F - VIEW_MIN_F) - bhi 1f - - add x, x, vx - add y, y, vy - - mov dz, z, lsr #(FIXED_SHIFT + 6) - add dz, dz, z, lsr #(FIXED_SHIFT + 4) - divLUT tmp, dz - mul x, tmp, x - mul y, tmp, y - - cmp x, rMinX - movlt rMinX, x - cmp y, rMinY - movlt rMinY, y - cmp x, rMaxX - movgt rMaxX, x - cmp y, rMaxY - movgt rMaxY, y -1: -.endm - -.global boxIsVisible_asm -boxIsVisible_asm: - ldr m, =gMatrixPtr - ldr m, [m] - ldr bz, [m, #(11 * 4)] - add bz, bz, #VIEW_OFF_F - cmp bz, #(VIEW_OFF_F + VIEW_MAX_F) - movhi r0, #0 - bxhi lr - - stmfd sp!, {r4-r11, lr} - - ldmia boxArg, {xx, yy, zz} - - // pre-transform min/max Z - ldr mx, [m, #8] - ldr vx, [m, #12] - ldr my, [m, #24] - ldr vy, [m, #28] - ldr mz, [m, #40] - ldr vz, [m, #44] - - mov min, zz, asr #16 - mla minX, min, mx, vx - mla minY, min, my, vy - mla minZ, min, mz, vz - mov minX, minX, asr #FIXED_SHIFT - mov minY, minY, asr #FIXED_SHIFT - - mov max, zz, lsl #16 - mov max, max, asr #16 - mla maxX, max, mx, vx - mla maxY, max, my, vy - mla maxZ, max, mz, vz - mov maxX, maxX, asr #FIXED_SHIFT - mov maxY, maxY, asr #FIXED_SHIFT - stmdb sp!, {maxX, maxY, maxZ, minX, minY, minZ} - - // pre-transform min/max Y - ldr mx, [m, #4] - ldr my, [m, #20] - ldr mz, [m, #36] - - mov min, yy, asr #16 - mul minX, mx, min - mul minY, my, min - mul minZ, mz, min - mov minX, minX, asr #FIXED_SHIFT - mov minY, minY, asr #FIXED_SHIFT - - mov max, yy, lsl #16 - mov max, max, asr #16 - mul maxX, max, mx - mul maxY, max, my - mul maxZ, max, mz - mov maxX, maxX, asr #FIXED_SHIFT - mov maxY, maxY, asr #FIXED_SHIFT - stmdb sp!, {maxX, maxY, maxZ, minX, minY, minZ} - - // pre-transform min/max X - ldr mx, [m, #0] - ldr my, [m, #16] - ldr mz, [m, #32] - - mov min, xx, asr #16 - mul minX, mx, min - mul minY, my, min - mul minZ, mz, min - mov minX, minX, asr #FIXED_SHIFT - mov minY, minY, asr #FIXED_SHIFT - - mov max, xx, lsl #16 - mov max, max, asr #16 - mul maxX, max, mx - mul maxY, max, my - mul maxZ, max, mz - mov maxX, maxX, asr #FIXED_SHIFT - mov maxY, maxY, asr #FIXED_SHIFT - stmdb sp!, {maxX, maxY, maxZ, minX, minY, minZ} - - mov rMinX, #MAX_INT32 - mov rMinY, #MAX_INT32 - mov rMaxX, #MIN_INT32 - mov rMaxY, #MIN_INT32 - - project #MIN_X, #MIN_Y, #MIN_Z - project #MAX_X, #MIN_Y, #MIN_Z - project #MIN_X, #MAX_Y, #MIN_Z - project #MAX_X, #MAX_Y, #MIN_Z - project #MIN_X, #MIN_Y, #MAX_Z - project #MAX_X, #MIN_Y, #MAX_Z - project #MIN_X, #MAX_Y, #MAX_Z - project #MAX_X, #MAX_Y, #MAX_Z - mov r0, #0 - - mov rMinX, rMinX, asr #(16 - PROJ_SHIFT) - mov rMaxX, rMaxX, asr #(16 - PROJ_SHIFT) - - cmp rMinX, rMaxX - beq .done - - // rect Y must remain shifted up by 16 - mov rMinY, rMinY, lsl #PROJ_SHIFT - mov rMaxY, rMaxY, lsl #PROJ_SHIFT - - // check xy clipping - ldr vp, =viewportRel - ldmia vp, {vMinXY, vMaxXY} - - cmp rMaxX, vMinXY, asr #16 - blt .done - cmp rMaxY, vMinXY, lsl #16 - blt .done - cmp rMinX, vMaxXY, asr #16 - bgt .done - cmp rMinY, vMaxXY, lsl #16 - bgt .done - - mov r0, #1 -.done: - add sp, sp, #SIZE - ldmfd sp!, {r4-r11, lr} - bx lr \ No newline at end of file diff --git a/src/platform/gba/asm/common_asm.inc b/src/platform/gba/asm/common_asm.inc index 67077182..1095691e 100644 --- a/src/platform/gba/asm/common_asm.inc +++ b/src/platform/gba/asm/common_asm.inc @@ -72,7 +72,7 @@ .equ PROJ_SHIFT, 4 .equ OT_SHIFT, 4 -.equ VIEW_DIST, (1024 * 10) // max = DIV_TABLE_END << PROJ_SHIFT +.equ VIEW_DIST, (1024 * 10) .equ FOG_SHIFT, 1 .equ FOG_MAX, VIEW_DIST .equ FOG_MIN, (FOG_MAX - (8192 >> FOG_SHIFT)) @@ -124,7 +124,7 @@ asr \tmp, \uv, #16 mul \tmp, \f // u = f * int16(uv >> 16) - lsl \uv, \uv, #16 + lsl \uv, #16 asr \uv, #16 mul \uv, \f // v = f * int16(uv) diff --git a/src/platform/gba/main.cpp b/src/platform/gba/main.cpp index 1e6d63b9..8b224d80 100644 --- a/src/platform/gba/main.cpp +++ b/src/platform/gba/main.cpp @@ -5,7 +5,7 @@ EWRAM_DATA int32 frameIndex = 0; EWRAM_DATA int32 fpsCounter = 0; EWRAM_DATA uint32 curSoundBuffer = 0; -#ifdef _WIN32 +#ifdef __GBA_WIN__ const void* TRACKS_IMA; const void* TITLE_SCR; const void* levelData; diff --git a/src/platform/gba/render.iwram.cpp b/src/platform/gba/render.iwram.cpp index 80528308..a22ed8e0 100644 --- a/src/platform/gba/render.iwram.cpp +++ b/src/platform/gba/render.iwram.cpp @@ -25,7 +25,7 @@ struct ViewportRel { ViewportRel viewportRel; -#if defined(_WIN32) +#if defined(__GBA_WIN__) uint16 fb[VRAM_WIDTH * FRAME_HEIGHT]; #elif defined(__GBA__) uint32 fb = MEM_VRAM; @@ -508,79 +508,6 @@ void faceAddMeshTriangles_c(const MeshTriangle* polys, int32 count) } } -bool transformBoxRect(const AABBs* box, RectMinMax* rect) -{ - const Matrix &m = matrixGet(); - - if ((m.e23 < (VIEW_MIN_F >> MATRIX_FIXED_SHIFT)) || (m.e23 >= (VIEW_MAX_F >> MATRIX_FIXED_SHIFT))) - return false; - - vec3i v[8]; - v[0] = _vec3i( box->minX, box->minY, box->minZ ), - v[1] = _vec3i( box->maxX, box->minY, box->minZ ), - v[2] = _vec3i( box->minX, box->maxY, box->minZ ), - v[3] = _vec3i( box->maxX, box->maxY, box->minZ ), - v[4] = _vec3i( box->minX, box->minY, box->maxZ ), - v[5] = _vec3i( box->maxX, box->minY, box->maxZ ), - v[6] = _vec3i( box->minX, box->maxY, box->maxZ ), - v[7] = _vec3i( box->maxX, box->maxY, box->maxZ ); - - *rect = RectMinMax( INT_MAX, INT_MAX, INT_MIN, INT_MIN ); - - for (int32 i = 0; i < 8; i++) - { - int32 z = DP43(m.e20, m.e21, m.e22, m.e23, v[i].x, v[i].y, v[i].z); - - if (z < VIEW_MIN_F || z >= VIEW_MAX_F) - continue; - - int32 x = DP43(m.e00, m.e01, m.e02, m.e03, v[i].x, v[i].y, v[i].z); - int32 y = DP43(m.e10, m.e11, m.e12, m.e13, v[i].x, v[i].y, v[i].z); - - x >>= FIXED_SHIFT; - y >>= FIXED_SHIFT; - z >>= FIXED_SHIFT; - - PERSPECTIVE(x, y, z); - - if (x < rect->x0) rect->x0 = x; - if (x > rect->x1) rect->x1 = x; - if (y < rect->y0) rect->y0 = y; - if (y > rect->y1) rect->y1 = y; - } - - rect->x0 += (FRAME_WIDTH / 2); - rect->y0 += (FRAME_HEIGHT / 2); - rect->x1 += (FRAME_WIDTH / 2); - rect->y1 += (FRAME_HEIGHT / 2); - - return true; -} - -int32 rectIsVisible(const RectMinMax* rect) -{ - if (rect->x0 > rect->x1 || - rect->x0 > viewport.x1 || - rect->x1 < viewport.x0 || - rect->y0 > viewport.y1 || - rect->y1 < viewport.y0) return 0; // not visible - - if (rect->x0 < viewport.x0 || - rect->x1 > viewport.x1 || - rect->y0 < viewport.y0 || - rect->y1 > viewport.y1) return -1; // clipped - - return 1; // fully visible -} - -int32 boxIsVisible_c(const AABBs* box) -{ - RectMinMax rect; - if (!transformBoxRect(box, &rect)) - return 0; // not visible - return rectIsVisible(&rect); -} - int32 sphereIsVisible_c(int32 sx, int32 sy, int32 sz, int32 r) { Matrix &m = matrixGet(); @@ -802,6 +729,18 @@ void renderInit() gFacesBase = gFaces; } +void renderFree() +{ +} + +void renderLevelInit() +{ +} + +void renderLevelFree() +{ +} + extern "C" X_NOINLINE void drawTriangle(uint32 flags, VertexLink* v) { VertexLink* v0 = v + 0;