mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-06 21:26:56 +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)
|
#define USE_FMT (LVL_FMT_PKD)
|
||||||
|
|
||||||
#include <tonc.h>
|
#include <tonc.h>
|
||||||
#elif defined(__NDS__)
|
#elif defined(__NDS__)
|
||||||
#define USE_DIV_TABLE
|
#define USE_DIV_TABLE
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@
|
|||||||
|
|
||||||
#define USE_FMT (LVL_FMT_PSX)
|
#define USE_FMT (LVL_FMT_PSX)
|
||||||
|
|
||||||
#include <nds.h>
|
#include <nds.h>
|
||||||
#include <fat.h>
|
#include <fat.h>
|
||||||
#include <filesystem.h>
|
#include <filesystem.h>
|
||||||
#elif defined(__TNS__)
|
#elif defined(__TNS__)
|
||||||
@@ -279,6 +279,8 @@ typedef uint16 divTableInt;
|
|||||||
typedef uint8 ColorIndex;
|
typedef uint8 ColorIndex;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define ADDR_ALIGN4(x) ((uint8*)x += ((intptr_t(x) + 3) & ~3) - intptr_t(x))
|
||||||
|
|
||||||
//#include <new>
|
//#include <new>
|
||||||
inline void* operator new(size_t, void *ptr)
|
inline void* operator new(size_t, void *ptr)
|
||||||
{
|
{
|
||||||
@@ -319,15 +321,7 @@ X_INLINE int32 abs(int32 x) {
|
|||||||
#define ASSERT(x)
|
#define ASSERT(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__GBA__)
|
#if defined(__GBA_WIN__)
|
||||||
#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__)
|
|
||||||
extern uint16 fb[VRAM_WIDTH * FRAME_HEIGHT];
|
extern uint16 fb[VRAM_WIDTH * FRAME_HEIGHT];
|
||||||
#elif defined(__GBA__)
|
#elif defined(__GBA__)
|
||||||
extern uint32 fb;
|
extern uint32 fb;
|
||||||
@@ -895,11 +889,10 @@ struct RoomVertex
|
|||||||
{
|
{
|
||||||
#if defined(__3DO__)
|
#if defined(__3DO__)
|
||||||
uint16 xyz565;
|
uint16 xyz565;
|
||||||
#elif defined(__GBA__) || defined(__32X__)
|
#elif defined(__GBA__) || defined(__GBA_WIN__) || defined(__32X__)
|
||||||
uint8 x, y, z, g;
|
uint8 x, y, z, g;
|
||||||
#else
|
#else
|
||||||
uint8 x, y, z;
|
uint8 x, y, z, g;
|
||||||
uint8 cR, cG, cB;
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2653,6 +2646,15 @@ X_INLINE void swap(T &a, T &b) {
|
|||||||
b = tmp;
|
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 gRandSeedLogic;
|
||||||
extern int32 gRandSeedDraw;
|
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 matrixRotateYXZ_asm(int32 angleX, int32 angleY, int32 angleZ);
|
||||||
void boxTranslate_asm(AABBi &box, int32 x, int32 y, int32 z);
|
void boxTranslate_asm(AABBi &box, int32 x, int32 y, int32 z);
|
||||||
void boxRotateYQ_asm(AABBi &box, int32 quadrant);
|
void boxRotateYQ_asm(AABBi &box, int32 quadrant);
|
||||||
int32 boxIsVisible_asm(const AABBs* box);
|
|
||||||
int32 sphereIsVisible_asm(int32 x, int32 y, int32 z, int32 r);
|
int32 sphereIsVisible_asm(int32 x, int32 y, int32 z, int32 r);
|
||||||
void flush_asm();
|
void flush_asm();
|
||||||
}
|
}
|
||||||
@@ -2750,7 +2751,6 @@ vec3i boxPushOut(const AABBi &a, const AABBi &b);
|
|||||||
#define matrixRotateYQ matrixRotateYQ_asm
|
#define matrixRotateYQ matrixRotateYQ_asm
|
||||||
#define boxTranslate boxTranslate_asm
|
#define boxTranslate boxTranslate_asm
|
||||||
#define boxRotateYQ boxRotateYQ_asm
|
#define boxRotateYQ boxRotateYQ_asm
|
||||||
#define boxIsVisible boxIsVisible_asm
|
|
||||||
#define sphereIsVisible sphereIsVisible_asm
|
#define sphereIsVisible sphereIsVisible_asm
|
||||||
#define flush flush_asm
|
#define flush flush_asm
|
||||||
#else
|
#else
|
||||||
@@ -2768,7 +2768,6 @@ vec3i boxPushOut(const AABBi &a, const AABBi &b);
|
|||||||
#define matrixRotateYQ matrixRotateYQ_c
|
#define matrixRotateYQ matrixRotateYQ_c
|
||||||
#define boxTranslate boxTranslate_c
|
#define boxTranslate boxTranslate_c
|
||||||
#define boxRotateYQ boxRotateYQ_c
|
#define boxRotateYQ boxRotateYQ_c
|
||||||
#define boxIsVisible boxIsVisible_c
|
|
||||||
#define sphereIsVisible sphereIsVisible_c
|
#define sphereIsVisible sphereIsVisible_c
|
||||||
#define flush flush_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 boxTranslate_c(AABBi &box, int32 x, int32 y, int32 z);
|
||||||
void boxRotateYQ_c(AABBi &box, int32 quadrant);
|
void boxRotateYQ_c(AABBi &box, int32 quadrant);
|
||||||
int32 boxIsVisible_c(const AABBs* box);
|
|
||||||
int32 sphereIsVisible_c(int32 x, int32 y, int32 z, int32 r);
|
int32 sphereIsVisible_c(int32 x, int32 y, int32 z, int32 r);
|
||||||
void flush_c();
|
void flush_c();
|
||||||
#endif
|
#endif
|
||||||
@@ -2807,7 +2805,6 @@ vec3i boxPushOut(const AABBi &a, const AABBi &b);
|
|||||||
#undef matrixRotateYQ
|
#undef matrixRotateYQ
|
||||||
//#undef boxTranslate
|
//#undef boxTranslate
|
||||||
//#undef boxRotateYQ
|
//#undef boxRotateYQ
|
||||||
//#undef boxIsVisible
|
|
||||||
//#undef sphereIsVisible
|
//#undef sphereIsVisible
|
||||||
//#undef flush
|
//#undef flush
|
||||||
|
|
||||||
@@ -2825,7 +2822,6 @@ vec3i boxPushOut(const AABBi &a, const AABBi &b);
|
|||||||
#define matrixRotateYQ matrixRotateYQ_asm
|
#define matrixRotateYQ matrixRotateYQ_asm
|
||||||
//#define boxTranslate boxTranslate_asm
|
//#define boxTranslate boxTranslate_asm
|
||||||
//#define boxRotateYQ boxRotateYQ_asm
|
//#define boxRotateYQ boxRotateYQ_asm
|
||||||
//#define boxIsVisible boxIsVisible_asm
|
|
||||||
//#define sphereIsVisible sphereIsVisible_asm
|
//#define sphereIsVisible sphereIsVisible_asm
|
||||||
//#define flush flush_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 matrixRotateYXZ_asm(int32 angleX, int32 angleY, int32 angleZ);
|
||||||
void boxTranslate_asm(AABBi &box, int32 x, int32 y, int32 z);
|
void boxTranslate_asm(AABBi &box, int32 x, int32 y, int32 z);
|
||||||
void boxRotateYQ_asm(AABBi &box, int32 quadrant);
|
void boxRotateYQ_asm(AABBi &box, int32 quadrant);
|
||||||
int32 boxIsVisible_asm(const AABBs* box);
|
|
||||||
int32 sphereIsVisible_asm(int32 x, int32 y, int32 z, int32 r);
|
int32 sphereIsVisible_asm(int32 x, int32 y, int32 z, int32 r);
|
||||||
void flush_asm();
|
void flush_asm();
|
||||||
}
|
}
|
||||||
|
113
src/fixed/draw.h
113
src/fixed/draw.h
@@ -8,8 +8,8 @@
|
|||||||
|
|
||||||
#ifdef TEST_ROOM_CACHE
|
#ifdef TEST_ROOM_CACHE
|
||||||
RoomVertex roomVert[512];
|
RoomVertex roomVert[512];
|
||||||
RoomQuad roomQuads[512];
|
EWRAM_DATA RoomQuad roomQuads[512];
|
||||||
RoomTriangle roomTri[64];
|
EWRAM_DATA RoomTriangle roomTri[64];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void drawInit()
|
void drawInit()
|
||||||
@@ -26,6 +26,16 @@ void drawInit()
|
|||||||
int16 rot = i * (ANGLE_90 * 4) / MAX_CAUSTICS;
|
int16 rot = i * (ANGLE_90 * 4) / MAX_CAUSTICS;
|
||||||
gCaustics[i] = sin(rot) * 768 >> FIXED_SHIFT;
|
gCaustics[i] = sin(rot) * 768 >> FIXED_SHIFT;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawFree()
|
||||||
|
{
|
||||||
|
renderFree();
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawLevelInit()
|
||||||
|
{
|
||||||
|
renderLevelInit();
|
||||||
|
|
||||||
#ifdef TEST_ROOM_CACHE
|
#ifdef TEST_ROOM_CACHE
|
||||||
Room &room = rooms[14];
|
Room &room = rooms[14];
|
||||||
@@ -40,16 +50,6 @@ void drawInit()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawFree()
|
|
||||||
{
|
|
||||||
renderFree();
|
|
||||||
}
|
|
||||||
|
|
||||||
void drawLevelInit()
|
|
||||||
{
|
|
||||||
renderLevelInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void drawLevelFree()
|
void drawLevelFree()
|
||||||
{
|
{
|
||||||
renderLevelFree();
|
renderLevelFree();
|
||||||
@@ -622,35 +622,81 @@ void drawModel(const ItemObj* item)
|
|||||||
frameDelta = 0;
|
frameDelta = 0;
|
||||||
#endif
|
#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();
|
matrixPush();
|
||||||
matrixTranslateAbs(item->pos.x, item->pos.y, item->pos.z);
|
matrixTranslateAbs(item->pos.x, item->pos.y, item->pos.z);
|
||||||
matrixRotateYXZ(item->angle.x, item->angle.y, item->angle.z);
|
matrixRotateYXZ(item->angle.x, item->angle.y, item->angle.z);
|
||||||
|
|
||||||
int32 vis = boxIsVisible(&frameA->box);
|
int32 intensity = item->intensity << 5;
|
||||||
|
|
||||||
if (vis)
|
if (intensity == 0) {
|
||||||
{
|
vec3i point = item->getRelative(frameA->box.getCenter());
|
||||||
int32 intensity = item->intensity << 5;
|
calcLightingDynamic(item->room, point);
|
||||||
|
} else {
|
||||||
|
calcLightingStatic(intensity);
|
||||||
|
}
|
||||||
|
|
||||||
if (intensity == 0) {
|
// skip rooms portal clipping for objects
|
||||||
vec3i point = item->getRelative(frameA->box.getCenter());
|
if (item->type == ITEM_LARA) {
|
||||||
calcLightingDynamic(item->room, point);
|
drawLaraNodesLerp(item, frameA, frameB, frameDelta, frameRate);
|
||||||
} else {
|
} else {
|
||||||
calcLightingStatic(intensity);
|
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();
|
matrixPop();
|
||||||
|
|
||||||
// shadow
|
// shadow
|
||||||
if (vis && (item->flags & ITEM_FLAG_SHADOW)) {
|
if (item->flags & ITEM_FLAG_SHADOW) {
|
||||||
drawShadow(item, 160); // TODO per item shadow size
|
drawShadow(item, 160); // TODO per item shadow size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -741,11 +787,8 @@ void drawRoom(const Room* room)
|
|||||||
matrixTranslateSet(px, py, pz);
|
matrixTranslateSet(px, py, pz);
|
||||||
matrixRotateYQ(q);
|
matrixRotateYQ(q);
|
||||||
|
|
||||||
int32 vis = boxIsVisible(&staticMesh->vbox);
|
calcLightingStatic(STATIC_MESH_INTENSITY(mesh->zf));
|
||||||
if (vis) {
|
drawMesh(staticMesh->meshIndex);
|
||||||
calcLightingStatic(STATIC_MESH_INTENSITY(mesh->zf));
|
|
||||||
drawMesh(staticMesh->meshIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
matrixPop();
|
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)
|
int32 sphereIsVisible_c(int32 sx, int32 sy, int32 sz, int32 r)
|
||||||
{
|
{
|
||||||
Matrix &m = matrixGet();
|
Matrix &m = matrixGet();
|
||||||
|
@@ -43,9 +43,6 @@ extern Item screenItem;
|
|||||||
#define FACE_MIP_SHIFT 11
|
#define FACE_MIP_SHIFT 11
|
||||||
#define FACE_TEXTURE 0x07FF
|
#define FACE_TEXTURE 0x07FF
|
||||||
|
|
||||||
|
|
||||||
#define F16_SHIFT 2 // special f14 to f16 shift for the math co-processor
|
|
||||||
|
|
||||||
#define DUP16(value) value | (value << 16)
|
#define DUP16(value) value | (value << 16)
|
||||||
|
|
||||||
enum ShadeValue
|
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)
|
int32 sphereIsVisible_c(int32 x, int32 y, int32 z, int32 r)
|
||||||
{
|
{
|
||||||
Matrix &m = matrixGet();
|
Matrix &m = matrixGet();
|
||||||
|
@@ -30,6 +30,8 @@
|
|||||||
<ClInclude Include="..\..\fixed\common.h" />
|
<ClInclude Include="..\..\fixed\common.h" />
|
||||||
<ClInclude Include="..\..\fixed\draw.h" />
|
<ClInclude Include="..\..\fixed\draw.h" />
|
||||||
<ClInclude Include="..\..\fixed\enemy.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\game.h" />
|
||||||
<ClInclude Include="..\..\fixed\inventory.h" />
|
<ClInclude Include="..\..\fixed\inventory.h" />
|
||||||
<ClInclude Include="..\..\fixed\item.h" />
|
<ClInclude Include="..\..\fixed\item.h" />
|
||||||
@@ -116,7 +118,7 @@
|
|||||||
<WarningLevel>Level2</WarningLevel>
|
<WarningLevel>Level2</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>__GBA_WIN__;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
@@ -132,7 +134,7 @@
|
|||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>__GBA_WIN__;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
@@ -149,7 +151,7 @@
|
|||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>__GBA_WIN__;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@@ -170,7 +172,7 @@
|
|||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>__GBA_WIN__;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
</ClCompile>
|
</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 PROJ_SHIFT, 4
|
||||||
.equ OT_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_SHIFT, 1
|
||||||
.equ FOG_MAX, VIEW_DIST
|
.equ FOG_MAX, VIEW_DIST
|
||||||
.equ FOG_MIN, (FOG_MAX - (8192 >> FOG_SHIFT))
|
.equ FOG_MIN, (FOG_MAX - (8192 >> FOG_SHIFT))
|
||||||
@@ -124,7 +124,7 @@
|
|||||||
asr \tmp, \uv, #16
|
asr \tmp, \uv, #16
|
||||||
mul \tmp, \f // u = f * int16(uv >> 16)
|
mul \tmp, \f // u = f * int16(uv >> 16)
|
||||||
|
|
||||||
lsl \uv, \uv, #16
|
lsl \uv, #16
|
||||||
asr \uv, #16
|
asr \uv, #16
|
||||||
mul \uv, \f // v = f * int16(uv)
|
mul \uv, \f // v = f * int16(uv)
|
||||||
|
|
||||||
|
@@ -5,7 +5,7 @@ EWRAM_DATA int32 frameIndex = 0;
|
|||||||
EWRAM_DATA int32 fpsCounter = 0;
|
EWRAM_DATA int32 fpsCounter = 0;
|
||||||
EWRAM_DATA uint32 curSoundBuffer = 0;
|
EWRAM_DATA uint32 curSoundBuffer = 0;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef __GBA_WIN__
|
||||||
const void* TRACKS_IMA;
|
const void* TRACKS_IMA;
|
||||||
const void* TITLE_SCR;
|
const void* TITLE_SCR;
|
||||||
const void* levelData;
|
const void* levelData;
|
||||||
|
@@ -25,7 +25,7 @@ struct ViewportRel {
|
|||||||
|
|
||||||
ViewportRel viewportRel;
|
ViewportRel viewportRel;
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(__GBA_WIN__)
|
||||||
uint16 fb[VRAM_WIDTH * FRAME_HEIGHT];
|
uint16 fb[VRAM_WIDTH * FRAME_HEIGHT];
|
||||||
#elif defined(__GBA__)
|
#elif defined(__GBA__)
|
||||||
uint32 fb = MEM_VRAM;
|
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)
|
int32 sphereIsVisible_c(int32 sx, int32 sy, int32 sz, int32 r)
|
||||||
{
|
{
|
||||||
Matrix &m = matrixGet();
|
Matrix &m = matrixGet();
|
||||||
@@ -802,6 +729,18 @@ void renderInit()
|
|||||||
gFacesBase = gFaces;
|
gFacesBase = gFaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void renderFree()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderLevelInit()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderLevelFree()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" X_NOINLINE void drawTriangle(uint32 flags, VertexLink* v)
|
extern "C" X_NOINLINE void drawTriangle(uint32 flags, VertexLink* v)
|
||||||
{
|
{
|
||||||
VertexLink* v0 = v + 0;
|
VertexLink* v0 = v + 0;
|
||||||
|
Reference in New Issue
Block a user