mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-01 02:40:43 +02:00
#368 GBA use sphere culling instead of box (boxIsVisible)
This commit is contained in:
@@ -63,7 +63,7 @@
|
||||
|
||||
#define USE_FMT (LVL_FMT_PKD)
|
||||
|
||||
#include <tonc.h>
|
||||
#include <tonc.h>
|
||||
#elif defined(__NDS__)
|
||||
#define USE_DIV_TABLE
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
|
||||
#define USE_FMT (LVL_FMT_PSX)
|
||||
|
||||
#include <nds.h>
|
||||
#include <nds.h>
|
||||
#include <fat.h>
|
||||
#include <filesystem.h>
|
||||
#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 <new>
|
||||
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();
|
||||
}
|
||||
|
113
src/fixed/draw.h
113
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
|
||||
|
||||
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));
|
||||
|
||||
// approx. radius (TODO more precise)
|
||||
sr = (sr >> 1) + (sr >> 2);
|
||||
|
||||
// rotate sphere center by quadrant
|
||||
uint16 quadrant = uint16(item->angle.y + ANGLE_45) >> ANGLE_SHIFT_90;
|
||||
|
||||
if (quadrant != 0)
|
||||
{
|
||||
int32 ix = sx;
|
||||
int32 iz = sz;
|
||||
|
||||
switch (quadrant)
|
||||
{
|
||||
case 1:
|
||||
sx = iz;
|
||||
sz = -ix;
|
||||
break;
|
||||
case 2:
|
||||
sx = -ix;
|
||||
sz = -iz;
|
||||
break;
|
||||
case 3:
|
||||
sx = -iz;
|
||||
sz = ix;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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 vis = boxIsVisible(&frameA->box);
|
||||
int32 intensity = item->intensity << 5;
|
||||
|
||||
if (vis)
|
||||
{
|
||||
int32 intensity = item->intensity << 5;
|
||||
if (intensity == 0) {
|
||||
vec3i point = item->getRelative(frameA->box.getCenter());
|
||||
calcLightingDynamic(item->room, point);
|
||||
} else {
|
||||
calcLightingStatic(intensity);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
// 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();
|
||||
}
|
||||
|
@@ -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();
|
||||
|
@@ -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();
|
||||
|
@@ -30,6 +30,8 @@
|
||||
<ClInclude Include="..\..\fixed\common.h" />
|
||||
<ClInclude Include="..\..\fixed\draw.h" />
|
||||
<ClInclude Include="..\..\fixed\enemy.h" />
|
||||
<ClInclude Include="..\..\fixed\fmt\phd.h" />
|
||||
<ClInclude Include="..\..\fixed\fmt\pkd.h" />
|
||||
<ClInclude Include="..\..\fixed\game.h" />
|
||||
<ClInclude Include="..\..\fixed\inventory.h" />
|
||||
<ClInclude Include="..\..\fixed\item.h" />
|
||||
@@ -116,7 +118,7 @@
|
||||
<WarningLevel>Level2</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>__GBA_WIN__;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
@@ -132,7 +134,7 @@
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>__GBA_WIN__;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
@@ -149,7 +151,7 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>__GBA_WIN__;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
@@ -170,7 +172,7 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>__GBA_WIN__;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
|
@@ -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
|
@@ -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)
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user