From 73fc22fa86f9629c0ef2a1ddfe18d33a602ec642 Mon Sep 17 00:00:00 2001 From: XProger Date: Mon, 13 Dec 2021 05:22:34 +0300 Subject: [PATCH] #368 camera vs walls collision, #370 more ARM optims, fix trap floor, fix underwater respawn --- src/fixed/camera.h | 71 +++-- src/fixed/common.cpp | 380 ++++++++++++++++---------- src/fixed/common.h | 160 ++++++----- src/fixed/draw.h | 78 +++--- src/fixed/game.h | 7 +- src/fixed/item.h | 8 +- src/fixed/lara.h | 10 + src/fixed/object.h | 2 +- src/fixed/room.h | 17 +- src/platform/3do/boxRotateYQ.s | 58 ++++ src/platform/3do/boxTranslate.s | 32 +++ src/platform/3do/common_asm.inc | 2 + src/platform/3do/main.cpp | 9 +- src/platform/3do/matrixRotateYQ.s | 66 +++++ src/platform/3do/matrixSetBasis.s | 32 +++ src/platform/3do/matrixSetIdentity.s | 33 +++ src/platform/3do/matrixTranslate.s | 51 ++++ src/platform/3do/matrixTranslateAbs.s | 52 ++++ src/platform/3do/phd_sin.s | 27 ++ src/platform/3do/projectVertices.s | 2 +- src/platform/gba/packer/main.cpp | 4 +- 21 files changed, 795 insertions(+), 306 deletions(-) create mode 100644 src/platform/3do/boxRotateYQ.s create mode 100644 src/platform/3do/boxTranslate.s create mode 100644 src/platform/3do/matrixRotateYQ.s create mode 100644 src/platform/3do/matrixSetBasis.s create mode 100644 src/platform/3do/matrixSetIdentity.s create mode 100644 src/platform/3do/matrixTranslate.s create mode 100644 src/platform/3do/matrixTranslateAbs.s create mode 100644 src/platform/3do/phd_sin.s diff --git a/src/fixed/camera.h b/src/fixed/camera.h index 360f7c74..bc3d0983 100644 --- a/src/fixed/camera.h +++ b/src/fixed/camera.h @@ -8,9 +8,10 @@ #define CAM_DIST_FOLLOW 1536 #define CAM_DIST_LOOK 768 #define CAM_DIST_COMBAT 2048 -#define CAMERA_ANGLE_FOLLOW ANGLE(-10) -#define CAMERA_ANGLE_COMBAT ANGLE(-10) -#define CAMERA_ANGLE_MAX ANGLE(85) +#define CAM_RADIUS 255 +#define CAM_ANGLE_FOLLOW ANGLE(-10) +#define CAM_ANGLE_COMBAT ANGLE(-10) +#define CAM_ANGLE_MAX ANGLE(85) void Camera::init(ItemObj* lara) { @@ -53,21 +54,59 @@ Location Camera::getLocationForAngle(int32 angle, int32 distH, int32 distV) return res; } +bool checkWall(Room* room, int32 x, int32 y, int32 z) +{ + Room* nextRoom = room->getRoom(x, y, z); + + const Sector* sector = nextRoom->getSector(x, z); + int32 floor = sector->getFloor(x, y, z); + int32 ceiling = sector->getCeiling(x, y, z); + return (floor == WALL || ceiling == WALL || ceiling >= floor || y > floor || y < ceiling); +} + +int32 checkHeight(Room* room, int32 x, int32 y, int32 z) +{ + Room* nextRoom = room->getRoom(x, y, z); + const Sector* sector = nextRoom->getSector(x, z); + int32 floor = sector->getFloor(x, y, z); + int32 ceiling = sector->getCeiling(x, y, z); + + if (floor != WALL && ceiling != WALL && ceiling < floor) + { + if (y - CAM_RADIUS < ceiling && y + CAM_RADIUS > floor) + return (floor + ceiling) >> 1; + + if (y + CAM_RADIUS > floor) + return floor - CAM_RADIUS; + + if (y - CAM_RADIUS < ceiling) + return ceiling + CAM_RADIUS; + } + + return y; +} + void Camera::clip(Location &loc) { - const Sector* sector = loc.room->getSector(loc.pos.x, loc.pos.z); - - int32 floor = sector->getFloor(loc.pos.x, loc.pos.y, loc.pos.z); - if (floor != WALL && loc.pos.y > floor - 128) { - loc.pos.y = floor - 128; + loc.pos.y = checkHeight(loc.room, loc.pos.x, loc.pos.y, loc.pos.z); + + if (checkWall(loc.room, loc.pos.x - CAM_RADIUS, loc.pos.y, loc.pos.z)) { + loc.pos.x = (loc.pos.x & (~1023)) + CAM_RADIUS; + } + + if (checkWall(loc.room, loc.pos.x + CAM_RADIUS, loc.pos.y, loc.pos.z)) { + loc.pos.x = (loc.pos.x | 1023) - CAM_RADIUS; + } + + if (checkWall(loc.room, loc.pos.x, loc.pos.y, loc.pos.z - CAM_RADIUS)) { + loc.pos.z = (loc.pos.z & (~1023)) + CAM_RADIUS; } - int32 ceiling = sector->getCeiling(loc.pos.x, loc.pos.y, loc.pos.z); - if (ceiling != WALL && loc.pos.y < ceiling + 128) { - loc.pos.y = ceiling + 128; + if (checkWall(loc.room, loc.pos.x, loc.pos.y, loc.pos.z + CAM_RADIUS)) { + loc.pos.z = (loc.pos.z | 1023) - CAM_RADIUS; } - // TODO clip walls? + loc.room = loc.room->getRoom(loc.pos.x, loc.pos.y, loc.pos.z); } Location Camera::getBestLocation(bool clip) @@ -135,7 +174,7 @@ void Camera::updateFree() if (keys & IK_LEFT) angle.y -= CAM_ROT_SPEED; if (keys & IK_RIGHT) angle.y += CAM_ROT_SPEED; - angle.x = X_CLAMP(angle.x, -CAMERA_ANGLE_MAX, CAMERA_ANGLE_MAX); + angle.x = X_CLAMP(angle.x, -CAM_ANGLE_MAX, CAM_ANGLE_MAX); if (keys & IK_A) { @@ -157,10 +196,10 @@ void Camera::updateFree() void Camera::updateFollow(ItemObj* item) { if (targetAngle.x == 0) { - targetAngle.x = CAMERA_ANGLE_FOLLOW; + targetAngle.x = CAM_ANGLE_FOLLOW; } - targetAngle.x = X_CLAMP(targetAngle.x + item->angle.x, -CAMERA_ANGLE_MAX, CAMERA_ANGLE_MAX); + targetAngle.x = X_CLAMP(targetAngle.x + item->angle.x, -CAM_ANGLE_MAX, CAM_ANGLE_MAX); targetAngle.y += item->angle.y; Location best = getBestLocation(false); @@ -172,7 +211,7 @@ void Camera::updateCombat(ItemObj* item) { ASSERT(item->type == ITEM_LARA); - targetAngle.x = item->angle.x + CAMERA_ANGLE_COMBAT; + targetAngle.x = item->angle.x + CAM_ANGLE_COMBAT; targetAngle.y = item->angle.y; if (item->extraL->armR.target || item->extraL->armL.target) diff --git a/src/fixed/common.cpp b/src/fixed/common.cpp index 91abf8b1..e31efd79 100644 --- a/src/fixed/common.cpp +++ b/src/fixed/common.cpp @@ -3,7 +3,6 @@ uint32 keys; RectMinMax viewport; vec3i cameraViewPos; -vec3i cameraViewOffset; Matrix matrixStack[MAX_MATRICES]; Matrix* matrixPtr = matrixStack; @@ -183,7 +182,7 @@ EWRAM_DATA divTableInt divTable[DIV_TABLE_SIZE] = { // must be at EWRAM start }; #endif -const int16 sinTable[1025] = { // ROM +extern "C" const int16 sinTable[1026] = { // ROM 0x0000, 0x0019, 0x0032, 0x004B, 0x0065, 0x007E, 0x0097, 0x00B0, 0x00C9, 0x00E2, 0x00FB, 0x0114, 0x012E, 0x0147, 0x0160, 0x0179, 0x0192, 0x01AB, 0x01C4, 0x01DD, 0x01F7, 0x0210, 0x0229, 0x0242, @@ -311,7 +310,7 @@ const int16 sinTable[1025] = { // ROM 0x3FEC, 0x3FED, 0x3FEF, 0x3FF0, 0x3FF1, 0x3FF2, 0x3FF3, 0x3FF4, 0x3FF5, 0x3FF6, 0x3FF7, 0x3FF7, 0x3FF8, 0x3FF9, 0x3FFA, 0x3FFA, 0x3FFB, 0x3FFC, 0x3FFC, 0x3FFD, 0x3FFD, 0x3FFE, 0x3FFE, 0x3FFE, - 0x3FFF, 0x3FFF, 0x3FFF, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000 + 0x3FFF, 0x3FFF, 0x3FFF, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000 }; const int16 atanTable[2050] = { // ROM @@ -578,27 +577,6 @@ const int32 atanOctant[] = { 0, -16384, -65535, 49152, -32768, 16384, 32768, -49152 }; - -int32 phd_sin(int32 x) -{ - x &= 0xFFFF; - bool neg = (x > 0x8000); - x &= 0x7FFF; - - if (x >= 0x4000) { - x = 0x8000 - x; - } - - x = sinTable[x >> 4]; - - return neg ? -x : x; -} - -int32 phd_cos(int32 x) -{ - return phd_sin(x + 0x4000); -} - int32 phd_atan(int32 x, int32 y) { if (x == 0 && y == 0) @@ -657,43 +635,21 @@ void anglesFromVector(int32 x, int32 y, int32 z, int16 &angleX, int16 &angleY) } } -AABBs boxRotate(const AABBs &box, int16 angle) -{ - if (angle == ANGLE_90) { - return AABBs( box.minZ, box.maxZ, box.minY, box.maxY, -box.maxX, -box.minX ); - } else if (angle == -ANGLE_90) { - return AABBs( -box.maxZ, -box.minZ, box.minY, box.maxY, box.minX, box.maxX ); - } else if (angle == ANGLE_180) { - return AABBs( -box.maxX, -box.minX, box.minY, box.maxY, -box.maxZ, -box.minZ ); - } - return box; -} - -void boxTranslate(AABBs &box, const vec3i &offset) -{ - box.minX += offset.x; - box.maxX += offset.x; - box.minY += offset.y; - box.maxY += offset.y; - box.minZ += offset.z; - box.maxZ += offset.z; -} - -bool boxIntersect(const AABBs &a, const AABBs &b) +bool boxIntersect(const AABBi &a, const AABBi &b) { return !(a.maxX <= b.minX || a.minX >= b.maxX || a.maxY <= b.minY || a.minY >= b.maxY || a.maxZ <= b.minZ || a.minZ >= b.maxZ); } -bool boxContains(const AABBs &a, const vec3i &p) +bool boxContains(const AABBi &a, const vec3i &p) { return !(a.minX > p.x || a.maxX < p.x || a.minY > p.y || a.maxY < p.y || a.minZ > p.z || a.maxZ < p.z); } -vec3i boxPushOut(const AABBs &a, const AABBs &b) +vec3i boxPushOut(const AABBi &a, const AABBi &b) { int32 ax = b.maxX - a.minX; int32 bx = a.maxX - b.minX; @@ -759,7 +715,125 @@ X_INLINE int16 lerpAngleSlow(int16 a, int16 b, int32 mul, int32 div) return a + d * mul / div; } -void matrixTranslate(int32 x, int32 y, int32 z) +#ifndef USE_ASM +int32 phd_sin_c(int32 x) +{ + x &= 0xFFFF; + bool neg = (x > 0x8000); + x &= 0x7FFF; + + if (x >= 0x4000) { + x = 0x8000 - x; + } + + x = sinTable[x >> 4]; + + return neg ? -x : x; +} + +void matrixPush_c() +{ + ASSERT(matrixPtr - matrixStack < MAX_MATRICES); + memcpy(matrixPtr + 1, matrixPtr, sizeof(Matrix)); + matrixPtr++; +} + +void matrixSetIdentity_c() +{ + Matrix &m = matrixGet(); + + m.e00 = 0x4000; + m.e01 = 0; + m.e02 = 0; + m.e03 = 0; + + m.e10 = 0; + m.e11 = 0x4000; + m.e12 = 0; + m.e13 = 0; + + m.e20 = 0; + m.e21 = 0; + m.e22 = 0x4000; + m.e23 = 0; +} + +void matrixSetBasis_c(Matrix &dst, const Matrix &src) +{ + dst.e00 = src.e00; + dst.e01 = src.e01; + dst.e02 = src.e02; + + dst.e10 = src.e10; + dst.e11 = src.e11; + dst.e12 = src.e12; + + dst.e10 = src.e10; + dst.e11 = src.e11; + dst.e12 = src.e12; +} + +#define LERP_1_2(a, b) a = (b + a) >> 1 +#define LERP_1_3(a, b) a = a + (b - a) / 3 +#define LERP_2_3(a, b) a = b - (b - a) / 3 +#define LERP_1_4(a, b) a = a + ((b - a) >> 2) +#define LERP_3_4(a, b) a = b - ((b - a) >> 2) +#define LERP_1_5(a, b) a = a + (b - a) / 5 +#define LERP_2_5(a, b) a = a + ((b - a) << 1) / 5 +#define LERP_3_5(a, b) a = b - ((b - a) << 1) / 5 +#define LERP_4_5(a, b) a = b - (b - a) / 5 +#define LERP_SLOW(a, b) a = a + ((b - a) * t >> 8) + +#define LERP_ROW(lerp_func, a, b, row) \ + lerp_func(a.e##row##0, b.e##row##0); \ + lerp_func(a.e##row##1, b.e##row##1); \ + lerp_func(a.e##row##2, b.e##row##2); \ + lerp_func(a.e##row##3, b.e##row##3); + +#define LERP_MATRIX(lerp_func) \ + LERP_ROW(lerp_func, m, n, 0); \ + LERP_ROW(lerp_func, m, n, 1); \ + LERP_ROW(lerp_func, m, n, 2); + +void matrixLerp_c(const Matrix &n, int32 pmul, int32 pdiv) +{ + Matrix &m = matrixGet(); + + if ((pdiv == 2) || ((pdiv == 4) && (pmul == 2))) { + LERP_MATRIX(LERP_1_2); + } else if (pdiv == 4) { + + if (pmul == 1) { + LERP_MATRIX(LERP_1_4); + } else { + LERP_MATRIX(LERP_3_4); + } + + } else if (pdiv == 3) { + + if (pmul == 1) { + LERP_MATRIX(LERP_1_3); + } else { + LERP_MATRIX(LERP_2_3); + } + + } else if (pdiv == 5) { + + switch (pmul) + { + case 4 : LERP_MATRIX(LERP_4_5); break; + case 3 : LERP_MATRIX(LERP_3_5); break; + case 2 : LERP_MATRIX(LERP_2_5); break; + case 1 : LERP_MATRIX(LERP_1_5); break; + } + + } else { + int32 t = pmul * FixedInvU(pdiv) >> 8; + LERP_MATRIX(LERP_SLOW); + } +} + +void matrixTranslate_c(int32 x, int32 y, int32 z) { Matrix &m = matrixGet(); @@ -772,22 +846,98 @@ void matrixTranslate(int32 x, int32 y, int32 z) m.e23 += dz; } -void matrixTranslateAbs(int32 x, int32 y, int32 z) +void matrixTranslateAbs_c(int32 x, int32 y, int32 z) { x -= cameraViewPos.x; y -= cameraViewPos.y; z -= cameraViewPos.z; - cameraViewOffset.x = x; - cameraViewOffset.y = y; - cameraViewOffset.z = z; - Matrix &m = matrixGet(); m.e03 = DP33(m.e00, m.e01, m.e02, x, y, z); m.e13 = DP33(m.e10, m.e11, m.e12, x, y, z); m.e23 = DP33(m.e20, m.e21, m.e22, x, y, z); } +void matrixRotateYQ_c(int32 quadrant) +{ + if (quadrant == 2) + return; + + Matrix &m = matrixGet(); + + if (quadrant == 0) { + m.e00 = -m.e00; + m.e10 = -m.e10; + m.e20 = -m.e20; + m.e02 = -m.e02; + m.e12 = -m.e12; + m.e22 = -m.e22; + } else if (quadrant == 1) { + int32 e0 = m.e02; + int32 e1 = m.e12; + int32 e2 = m.e22; + + m.e02 = -m.e00; + m.e12 = -m.e10; + m.e22 = -m.e20; + + m.e00 = e0; + m.e10 = e1; + m.e20 = e2; + } else { + int32 e0 = m.e02; + int32 e1 = m.e12; + int32 e2 = m.e22; + + m.e02 = m.e00; + m.e12 = m.e10; + m.e22 = m.e20; + + m.e00 = -e0; + m.e10 = -e1; + m.e20 = -e2; + } +} + +void boxTranslate_c(AABBi &box, int32 x, int32 y, int32 z) +{ + box.minX += x; + box.maxX += x; + box.minY += y; + box.maxY += y; + box.minZ += z; + box.maxZ += z; +} + +void boxRotateYQ_c(AABBi &box, int32 quadrant) +{ + if (quadrant == 2) + return; + + int32 minX = box.minX; + int32 maxX = box.maxX; + int32 minZ = box.minZ; + int32 maxZ = box.maxZ; + + if (quadrant == 3) { + box.minX = minZ; + box.maxX = maxZ; + box.minZ = -maxX; + box.maxZ = -minX; + } else if (quadrant == 1) { + box.minX = -maxZ; + box.maxX = -minZ; + box.minZ = minX; + box.maxZ = maxX; + } else if (quadrant == 0) { + box.minX = -maxX; + box.maxX = -minX; + box.minZ = -maxZ; + box.maxZ = -minZ; + } +} +#endif + void matrixRotateX(int32 angle) { Matrix &m = matrixGet(); @@ -838,82 +988,51 @@ void matrixRotateZXY(int32 angleX, int32 angleY, int32 angleZ) if (angleY) matrixRotateY(angleY); } -void matrixFrame(const vec3s &pos, const uint32* angles) +void matrixFrame(const void* pos, const void* angles) { int16 aX, aY, aZ; - DECODE_ANGLES(angles, aX, aY, aZ); + DECODE_ANGLES(*(uint32*)angles, aX, aY, aZ); - matrixTranslate(pos.x, pos.y, pos.z); - matrixRotateYXZ(aX, aY, aZ); -} + uint32 xy = ((uint32*)pos)[0]; + uint32 zu = ((uint32*)pos)[1]; -#ifndef USE_MATRIX_ASM -#ifdef IWRAM_MATRIX_LERP -void matrixLerp_c(const Matrix &n, int32 pmul, int32 pdiv); +#ifdef CPU_BIG_ENDIAN + int16 posX = int16(xy >> 16); + int16 posY = int16(xy & 0xFFFF); + int16 posZ = int16(zu >> 16); #else -void matrixLerp_c(const Matrix &n, int32 pmul, int32 pdiv) -{ - Matrix &m = matrixGet(); - - if ((pdiv == 2) || ((pdiv == 4) && (pmul == 2))) { - LERP_MATRIX(LERP_1_2); - } else if (pdiv == 4) { + int16 posX = int16(xy & 0xFFFF); + int16 posY = int16(xy >> 16); + int16 posZ = int16(zu & 0xFFFF); +#endif - if (pmul == 1) { - LERP_MATRIX(LERP_1_4); - } else { - LERP_MATRIX(LERP_3_4); - } + matrixTranslate(posX, posY, posZ); + matrixRotateYXZ(aX, aY, aZ); +} - } else if (pdiv == 3) { - - if (pmul == 1) { - LERP_MATRIX(LERP_1_3); - } else { - LERP_MATRIX(LERP_2_3); - } +void matrixFrameLerp(const void* pos, const void* anglesA, const void* anglesB, int32 delta, int32 rate) +{ + int16 aX, aY, aZ; + int16 bX, bY, bZ; - } else if (pdiv == 5) { + DECODE_ANGLES(*(uint32*)anglesA, aX, aY, aZ); + DECODE_ANGLES(*(uint32*)anglesB, bX, bY, bZ); - switch (pmul) - { - case 4 : LERP_MATRIX(LERP_4_5); break; - case 3 : LERP_MATRIX(LERP_3_5); break; - case 2 : LERP_MATRIX(LERP_2_5); break; - case 1 : LERP_MATRIX(LERP_1_5); break; - } + uint32 xy = ((uint32*)pos)[0]; + uint32 zu = ((uint32*)pos)[1]; - } else { - int32 t = pmul * FixedInvU(pdiv) >> 8; - LERP_MATRIX(LERP_SLOW); - } -} -#endif +#ifdef CPU_BIG_ENDIAN + int16 posX = int16(xy >> 16); + int16 posY = int16(xy & 0xFFFF); + int16 posZ = int16(zu >> 16); +#else + int16 posX = int16(xy & 0xFFFF); + int16 posY = int16(xy >> 16); + int16 posZ = int16(zu & 0xFFFF); #endif -void matrixFrameLerp(const vec3s &pos, const uint32* anglesA, const uint32* anglesB, int32 delta, int32 rate) -{ - int16 aX, aY, aZ; - int16 bX, bY, bZ; + matrixTranslate(posX, posY, posZ); - DECODE_ANGLES(anglesA, aX, aY, aZ); - DECODE_ANGLES(anglesB, bX, bY, bZ); - - matrixTranslate(pos.x, pos.y, pos.z); - -#if defined(ANIM_LERP_ANGLE) // TODO oh, damn Gimbal Lock! - #if 0 - int32 t = (delta << FIXED_SHIFT) / rate; - if (aX != bX) aX = lerpAngle(aX, bX, t); - if (aY != bY) aY = lerpAngle(aY, bY, t); - if (aZ != bZ) aZ = lerpAngle(aZ, bZ, t); - #else - if (aX != bX) aX = lerpAngleSlow(aX, bX, delta, rate); - if (aY != bY) aY = lerpAngleSlow(aY, bY, delta, rate); - if (aZ != bZ) aZ = lerpAngleSlow(aZ, bZ, delta, rate); - #endif - matrixRotateYXZ(aX, aY, aZ); -#elif defined(ANIM_LERP_MATRIX) matrixPush(); matrixRotateYXZ(bX, bY, bZ); Matrix &m = matrixGet(); @@ -922,29 +1041,6 @@ void matrixFrameLerp(const vec3s &pos, const uint32* anglesA, const uint32* angl matrixRotateYXZ(aX, aY, aZ); matrixLerp(m, delta, rate); -#else - #error animation lerp type is undefined -#endif -} - -void matrixSetIdentity() -{ - Matrix &m = matrixGet(); - - m.e00 = 0x4000; - m.e01 = 0; - m.e02 = 0; - m.e03 = 0; - - m.e10 = 0; - m.e11 = 0x4000; - m.e12 = 0; - m.e13 = 0; - - m.e20 = 0; - m.e21 = 0; - m.e22 = 0x4000; - m.e23 = 0; } void matrixSetView(const vec3i &pos, int32 angleX, int32 angleY) @@ -972,7 +1068,6 @@ void matrixSetView(const vec3i &pos, int32 angleX, int32 angleY) m.e23 = 0; cameraViewPos = pos; - cameraViewOffset = _vec3i(0, 0, 0); } void CollisionInfo::setSide(CollisionInfo::SideType st, int32 floor, int32 ceiling) @@ -1003,6 +1098,7 @@ void CollisionInfo::setSide(CollisionInfo::SideType st, int32 floor, int32 ceili s->ceiling = ceiling; } +// TODO osSetGamma void setGamma(int32 value) { if (value == 0) { diff --git a/src/fixed/common.h b/src/fixed/common.h index 21b679a4..27c341cf 100644 --- a/src/fixed/common.h +++ b/src/fixed/common.h @@ -153,10 +153,6 @@ #define MAX_ENEMIES 8 #endif -#ifndef ANIM_LERP_ANGLE - #define ANIM_LERP_MATRIX -#endif - // ============================================================================ #if defined(_MSC_VER) @@ -555,6 +551,9 @@ struct vec3s { #define _vec3s(x,y,z) vec3s::create(x, y, z) +struct vec4s { + int16 x, y, z, w; +}; struct vec3i { int32 x, y, z; @@ -702,6 +701,16 @@ struct AABBi int32 maxY; int32 minZ; int32 maxZ; + + X_INLINE AABBi() {} + X_INLINE AABBi(const AABBs &b) : + minX(b.minX), maxX(b.maxX), minY(b.minY), maxY(b.maxY), minZ(b.minZ), maxZ(b.maxZ) {} + X_INLINE AABBi(int32 minX, int32 maxX, int32 minY, int32 maxY, int32 minZ, int32 maxZ) : + minX(minX), maxX(maxX), minY(minY), maxY(maxY), minZ(minZ), maxZ(maxZ) {} + + X_INLINE vec3i getCenter() const { + return _vec3i((maxX + minX) >> 1, (maxY + minY) >> 1, (maxZ + minZ) >> 1); + } }; struct Sphere @@ -771,8 +780,9 @@ struct Light uint8 intensity; }; -#define STATIC_MESH_ID(flags) ((flags) & 0x3F) -#define STATIC_MESH_ROT(flags) ((((flags) >> 6) - 2) * ANGLE_90) +#define STATIC_MESH_ID(flags) ((flags) & 0x3F) +#define STATIC_MESH_QUADRANT(flags) ((flags) >> 6) +#define STATIC_MESH_ROT(flags) ((STATIC_MESH_QUADRANT(flags) - 2) * ANGLE_90) struct RoomMesh { @@ -865,8 +875,8 @@ enum NodeFlag { }; struct ModelNode { - uint16 flags; vec3s pos; + uint16 flags; }; struct Model { @@ -2031,7 +2041,6 @@ struct IMA_STATE extern uint32 keys; extern RectMinMax viewport; extern vec3i cameraViewPos; -extern vec3i cameraViewOffset; extern Matrix* matrixPtr; extern Matrix matrixStack[MAX_MATRICES]; extern int32 gVerticesCount; @@ -2069,8 +2078,6 @@ int32 rand_draw(); #define RAND_LOGIC(r) (rand_logic() * (r) >> 15) #define RAND_DRAW(r) (rand_draw() * (r) >> 15) -int32 phd_sin(int32 x); -int32 phd_cos(int32 x); int32 phd_atan(int32 x, int32 y); uint32 phd_sqrt(uint32 x); @@ -2098,100 +2105,89 @@ X_INLINE int16 angleLerp(int16 a, int16 b, int32 w) #define angleDec(angle, value) angleLerp(angle, 0, value) -AABBs boxRotate(const AABBs &box, int16 angle); -void boxTranslate(AABBs &box, const vec3i &offset); -bool boxIntersect(const AABBs &a, const AABBs &b); -bool boxContains(const AABBs &a, const vec3i &p); -vec3i boxPushOut(const AABBs &a, const AABBs &b); +bool boxIntersect(const AABBi &i, const AABBi &b); +bool boxContains(const AABBi &a, const vec3i &p); +vec3i boxPushOut(const AABBi &a, const AABBi &b); +#ifdef CPU_BIG_ENDIAN #define DECODE_ANGLES(a,x,y,z)\ - x = (((uint16*)(a))[1] & 0x3FF0) << 2;\ - y = (((uint16*)(a))[1] & 0x000F) << 12 | (((uint16*)(a))[0] & 0xFC00) >> 4;\ - z = (((uint16*)(a))[0] & 0x03FF) << 6; - -#ifdef USE_MATRIX_ASM - extern "C" void matrixLerp_asm(const Matrix &n, int32 pmul, int32 pdiv); - - #define matrixLerp matrixLerp_asm + x = (a & 0x3FF0) << 2;\ + y = (a & 0x000F) << 12 | ((a >> 16) & 0xFC00) >> 4;\ + z = ((a >> 16) & 0x03FF) << 6; #else - #define LERP_1_2(a, b) a = (b + a) >> 1 - #define LERP_1_3(a, b) a = a + (b - a) / 3 - #define LERP_2_3(a, b) a = b - (b - a) / 3 - #define LERP_1_4(a, b) a = a + ((b - a) >> 2) - #define LERP_3_4(a, b) a = b - ((b - a) >> 2) - #define LERP_1_5(a, b) a = a + (b - a) / 5 - #define LERP_2_5(a, b) a = a + ((b - a) << 1) / 5 - #define LERP_3_5(a, b) a = b - ((b - a) << 1) / 5 - #define LERP_4_5(a, b) a = b - (b - a) / 5 - #define LERP_SLOW(a, b) a = a + ((b - a) * t >> 8) - - #define LERP_ROW(lerp_func, a, b, row) \ - lerp_func(a.e##row##0, b.e##row##0); \ - lerp_func(a.e##row##1, b.e##row##1); \ - lerp_func(a.e##row##2, b.e##row##2); \ - lerp_func(a.e##row##3, b.e##row##3); - - #define LERP_MATRIX(lerp_func) \ - LERP_ROW(lerp_func, m, n, 0); \ - LERP_ROW(lerp_func, m, n, 1); \ - LERP_ROW(lerp_func, m, n, 2); - - void matrixLerp_c(const Matrix &n, int32 pmul, int32 pdiv); - - #define matrixLerp matrixLerp_c +#define DECODE_ANGLES(a,x,y,z)\ + x = ((a >> 16) & 0x3FF0) << 2;\ + y = ((a >> 16) & 0x000F) << 12 | (a & 0xFC00) >> 4;\ + z = (a & 0x03FF) << 6; #endif -X_INLINE Matrix& matrixGet() -{ - return *matrixPtr; -} +#define matrixGet() *matrixPtr #ifdef USE_ASM - extern "C" void matrixPush_asm(); - #define matrixPush() matrixPush_asm(); + extern "C" { + int32 phd_sin_asm(int32 x); + void matrixPush_asm(); + void matrixSetIdentity_asm(); + void matrixSetBasis_asm(Matrix &dst, const Matrix &src); + void matrixLerp_asm(const Matrix &n, int32 pmul, int32 pdiv); + void matrixTranslate_asm(int32 x, int32 y, int32 z); + void matrixTranslateAbs_asm(int32 x, int32 y, int32 z); + void matrixRotateYQ_asm(int32 quadrant); + void boxTranslate_asm(AABBi &box, int32 x, int32 y, int32 z); + void boxRotateYQ_asm(AABBi &box, int32 quadrant); + } + + #define phd_sin phd_sin_asm + #define matrixPush matrixPush_asm + #define matrixSetIdentity matrixSetIdentity_asm + #define matrixSetBasis matrixSetBasis_asm + #define matrixLerp matrixLerp_asm + #define matrixTranslate matrixTranslate_asm + #define matrixTranslateAbs matrixTranslateAbs_asm + #define matrixRotateYQ matrixRotateYQ_asm + #define boxTranslate boxTranslate_asm + #define boxRotateYQ boxRotateYQ_asm #else - #define matrixPush() matrixPush_c(); + #define phd_sin phd_sin_c + #define matrixPush matrixPush_c + #define matrixSetIdentity matrixSetIdentity_c + #define matrixSetBasis matrixSetBasis_c + #define matrixLerp matrixLerp_c + #define matrixTranslate matrixTranslate_c + #define matrixTranslateAbs matrixTranslateAbs_c + #define matrixRotateYQ matrixRotateYQ_c + #define boxTranslate boxTranslate_c + #define boxRotateYQ boxRotateYQ_c + + int32 phd_sin_c(int32 x); + + void matrixPush_c(); + void matrixSetIdentity_c(); + void matrixSetBasis_c(Matrix &dst, const Matrix &src); + void matrixLerp_c(const Matrix &n, int32 pmul, int32 pdiv); + void matrixTranslate_c(int32 x, int32 y, int32 z); + void matrixTranslateAbs_c(int32 x, int32 y, int32 z); + void matrixRotateYQ_c(int32 quadrant); -X_INLINE void matrixPush_c() -{ - ASSERT(matrixPtr - matrixStack < MAX_MATRICES); - memcpy(matrixPtr + 1, matrixPtr, sizeof(Matrix)); - matrixPtr++; -} + void boxTranslate_c(AABBi &box, int32 x, int32 y, int32 z); + void boxRotateYQ_c(AABBi &box, int32 quadrant); #endif -#define matrixPop() matrixPtr-- - -X_INLINE void matrixSetBasis(Matrix &dst, const Matrix &src) -{ - dst.e00 = src.e00; - dst.e01 = src.e01; - dst.e02 = src.e02; - - dst.e10 = src.e10; - dst.e11 = src.e11; - dst.e12 = src.e12; - - dst.e10 = src.e10; - dst.e11 = src.e11; - dst.e12 = src.e12; -} +#define phd_cos(x) phd_sin((x) + ANGLE_90) +#define matrixPop() matrixPtr-- X_INLINE vec3i matrixGetDir(const Matrix &m) { return _vec3i(m.e20, m.e21, m.e22); } -void matrixTranslate(int32 x, int32 y, int32 z); -void matrixTranslateAbs(int32 x, int32 y, int32 z); void matrixRotateX(int32 angle); void matrixRotateY(int32 angle); void matrixRotateZ(int32 angle); void matrixRotateYXZ(int32 angleX, int32 angleY, int32 angleZ); void matrixRotateZXY(int32 angleX, int32 angleY, int32 angleZ); -void matrixFrame(const vec3s &pos, const uint32* angles); -void matrixFrameLerp(const vec3s &pos, const uint32* anglesA, const uint32* anglesB, int32 delta, int32 rate); -void matrixSetIdentity(); +void matrixFrame(const void* pos, const void* angles); +void matrixFrameLerp(const void* pos, const void* anglesA, const void* anglesB, int32 delta, int32 rate); void matrixSetView(const vec3i &pos, int32 angleX, int32 angleY); void setGamma(int32 value); diff --git a/src/fixed/draw.h b/src/fixed/draw.h index eb652dd3..8c40c436 100644 --- a/src/fixed/draw.h +++ b/src/fixed/draw.h @@ -322,7 +322,7 @@ void drawNodes(const ItemObj* item, const AnimFrame* frameA) const uint32* angles = (uint32*)(frameA->angles + 1); const int16* extraAngles = (int16*)item->extra; - matrixFrame(frameA->pos, angles); + matrixFrame(&frameA->pos, angles); if (visibleMask & 1) { drawMesh(meshIndex); } @@ -336,7 +336,7 @@ void drawNodes(const ItemObj* item, const AnimFrame* frameA) if (node->flags & NODE_FLAG_POP) matrixPop(); if (node->flags & NODE_FLAG_PUSH) matrixPush(); - matrixFrame(node->pos, angles); + matrixFrame(&node->pos, angles); if (extraAngles) { @@ -374,12 +374,12 @@ void drawNodesLerp(const ItemObj* item, const AnimFrame* frameA, const AnimFrame int32 t = GET_FRAME_T(frameDelta, frameRate); - vec3s posLerp; + vec4s posLerp; posLerp.x = frameA->pos.x + ((frameB->pos.x - frameA->pos.x) * t >> 16); posLerp.y = frameA->pos.y + ((frameB->pos.y - frameA->pos.y) * t >> 16); posLerp.z = frameA->pos.z + ((frameB->pos.z - frameA->pos.z) * t >> 16); - matrixFrameLerp(posLerp, anglesA, anglesB, frameDelta, frameRate); + matrixFrameLerp(&posLerp, anglesA, anglesB, frameDelta, frameRate); if (visibleMask & 1) { drawMesh(meshIndex); } @@ -394,7 +394,7 @@ void drawNodesLerp(const ItemObj* item, const AnimFrame* frameA, const AnimFrame if (node->flags & NODE_FLAG_POP) matrixPop(); if (node->flags & NODE_FLAG_PUSH) matrixPush(); - matrixFrameLerp(node->pos, anglesA, anglesB, frameDelta, frameRate); + matrixFrameLerp(&node->pos, anglesA, anglesB, frameDelta, frameRate); if (extraAngles) { @@ -412,7 +412,11 @@ void drawNodesLerp(const ItemObj* item, const AnimFrame* frameA, const AnimFrame } } -#define DEF_TORSO_ANGLE _vec3s(1216, -832, -192) +#define DEF_TORSO_ANGLE_X 1216 +#define DEF_TORSO_ANGLE_Y -832 +#define DEF_TORSO_ANGLE_Z -192 + +const uint32 ZERO_POS[2] = { 0, 0 }; void drawLaraNodes(const ItemObj* lara, const AnimFrame* frameA) { @@ -441,9 +445,11 @@ void drawLaraNodes(const ItemObj* lara, const AnimFrame* frameA) // additional torso animation for shotgun if (extraL->weapon == WEAPON_SHOTGUN && i == LARA_ARM_R) { - vec3s ang; - DECODE_ANGLES((uint32*)(frame->angles + 1) + JOINT_TORSO, ang.x, ang.y, ang.z); - torsoAngle += ang - DEF_TORSO_ANGLE; + int32 aX, aY, aZ; + DECODE_ANGLES(*((uint32*)(frame->angles + 1) + JOINT_TORSO), aX, aY, aZ); + torsoAngle.x = torsoAngle.x + aX - DEF_TORSO_ANGLE_X; + torsoAngle.y = torsoAngle.y + aY - DEF_TORSO_ANGLE_Y; + torsoAngle.z = torsoAngle.z + aZ - DEF_TORSO_ANGLE_Z; } } } @@ -455,22 +461,22 @@ void drawLaraNodes(const ItemObj* lara, const AnimFrame* frameA) matrixPush(); { // JOINT_HIPS - matrixFrame(frameA->pos, angles++); + matrixFrame(&frameA->pos, angles++); drawMesh(*mesh++); for (int32 i = 0; i < 2; i++) // draw Left & Right legs { matrixPush(); { // JOINT_LEG_1 - matrixFrame((node++)->pos, angles++); + matrixFrame(&(node++)->pos, angles++); drawMesh(*mesh++); { // JOINT_LEG_2 - matrixFrame((node++)->pos, angles++); + matrixFrame(&(node++)->pos, angles++); drawMesh(*mesh++); { // JOINT_LEG_3 - matrixFrame((node++)->pos, angles++); + matrixFrame(&(node++)->pos, angles++); drawMesh(*mesh++); } } @@ -479,7 +485,7 @@ void drawLaraNodes(const ItemObj* lara, const AnimFrame* frameA) } { // JOINT_TORSO - matrixFrame((node++)->pos, angles++); + matrixFrame(&(node++)->pos, angles++); matrixRotateYXZ(torsoAngle.x, torsoAngle.y, torsoAngle.z); drawMesh(*mesh++); @@ -495,15 +501,15 @@ void drawLaraNodes(const ItemObj* lara, const AnimFrame* frameA) matrixSetBasis(matrixGet(), basis); matrixRotateYXZ(arm->angle.x, arm->angle.y, arm->angle.z); } - matrixFrame(_vec3s(0, 0, 0), anglesArm[i]++); + matrixFrame(&ZERO_POS, anglesArm[i]++); drawMesh(*mesh++); { // JOINT_ARM_2 - matrixFrame((node++)->pos, anglesArm[i]++); + matrixFrame(&(node++)->pos, anglesArm[i]++); drawMesh(*mesh++); { // JOINT_ARM_3 - matrixFrame((node++)->pos, anglesArm[i]); + matrixFrame(&(node++)->pos, anglesArm[i]); drawMesh(*mesh++); if (arm->flash.timer) { // muzzle flash @@ -515,7 +521,7 @@ void drawLaraNodes(const ItemObj* lara, const AnimFrame* frameA) } { // JOINT_HEAD - matrixFrame((node++)->pos, angles + 3 * LARA_ARM_MAX); + matrixFrame(&(node++)->pos, angles + 3 * LARA_ARM_MAX); matrixRotateYXZ(extraL->head.angle.x, extraL->head.angle.y, extraL->head.angle.z); drawMesh(*mesh++); } @@ -564,9 +570,11 @@ void drawLaraNodesLerp(const ItemObj* lara, const AnimFrame* frameA, const AnimF // additional torso animation for shotgun if (extraL->weapon == WEAPON_SHOTGUN && i == LARA_ARM_R) { - vec3s ang; - DECODE_ANGLES((uint32*)(frame->angles + 1) + JOINT_TORSO, ang.x, ang.y, ang.z); - torsoAngle += ang - DEF_TORSO_ANGLE; + int32 aX, aY, aZ; + DECODE_ANGLES(*((uint32*)(frame->angles + 1) + JOINT_TORSO), aX, aY, aZ); + torsoAngle.x = torsoAngle.x + aX - DEF_TORSO_ANGLE_X; + torsoAngle.y = torsoAngle.y + aY - DEF_TORSO_ANGLE_Y; + torsoAngle.z = torsoAngle.z + aZ - DEF_TORSO_ANGLE_Z; } } } @@ -582,27 +590,27 @@ void drawLaraNodesLerp(const ItemObj* lara, const AnimFrame* frameA, const AnimF { // JOINT_HIPS int32 t = GET_FRAME_T(frameDelta, frameRate); - vec3s posLerp; + vec4s posLerp; posLerp.x = frameA->pos.x + ((frameB->pos.x - frameA->pos.x) * t >> 16); posLerp.y = frameA->pos.y + ((frameB->pos.y - frameA->pos.y) * t >> 16); posLerp.z = frameA->pos.z + ((frameB->pos.z - frameA->pos.z) * t >> 16); - matrixFrameLerp(posLerp, anglesA++, anglesB++, frameDelta, frameRate); + matrixFrameLerp(&posLerp, anglesA++, anglesB++, frameDelta, frameRate); drawMesh(*mesh++); for (int32 i = 0; i < 2; i++) // draw Left & Right legs { matrixPush(); { // JOINT_LEG_1 - matrixFrameLerp((node++)->pos, anglesA++, anglesB++, frameDelta, frameRate); + matrixFrameLerp(&(node++)->pos, anglesA++, anglesB++, frameDelta, frameRate); drawMesh(*mesh++); { // JOINT_LEG_2 - matrixFrameLerp((node++)->pos, anglesA++, anglesB++, frameDelta, frameRate); + matrixFrameLerp(&(node++)->pos, anglesA++, anglesB++, frameDelta, frameRate); drawMesh(*mesh++); { // JOINT_LEG_3 - matrixFrameLerp((node++)->pos, anglesA++, anglesB++, frameDelta, frameRate); + matrixFrameLerp(&(node++)->pos, anglesA++, anglesB++, frameDelta, frameRate); drawMesh(*mesh++); } } @@ -611,7 +619,7 @@ void drawLaraNodesLerp(const ItemObj* lara, const AnimFrame* frameA, const AnimF } { // JOINT_TORSO - matrixFrameLerp((node++)->pos, anglesA++, anglesB++, frameDelta, frameRate); + matrixFrameLerp(&(node++)->pos, anglesA++, anglesB++, frameDelta, frameRate); matrixRotateYXZ(torsoAngle.x, torsoAngle.y, torsoAngle.z); drawMesh(*mesh++); @@ -631,25 +639,25 @@ void drawLaraNodesLerp(const ItemObj* lara, const AnimFrame* frameA, const AnimF bool useLerp = frameRateArm[i] > 1; // armed hands always use frameRate == 1 (i.e. useLerp == false) if (useLerp) { - matrixFrameLerp(_vec3s(0, 0, 0), anglesArmA[i]++, anglesArmB[i]++, frameDelta, frameRate); + matrixFrameLerp(&ZERO_POS, anglesArmA[i]++, anglesArmB[i]++, frameDelta, frameRate); } else { - matrixFrame(_vec3s(0, 0, 0), anglesArmA[i]++); + matrixFrame(&ZERO_POS, anglesArmA[i]++); } drawMesh(*mesh++); { // JOINT_ARM_2 if (useLerp) { - matrixFrameLerp((node++)->pos, anglesArmA[i]++, anglesArmB[i]++, frameDelta, frameRate); + matrixFrameLerp(&(node++)->pos, anglesArmA[i]++, anglesArmB[i]++, frameDelta, frameRate); } else { - matrixFrame((node++)->pos, anglesArmA[i]++); + matrixFrame(&(node++)->pos, anglesArmA[i]++); } drawMesh(*mesh++); { // JOINT_ARM_3 if (useLerp) { - matrixFrameLerp((node++)->pos, anglesArmA[i], anglesArmB[i], frameDelta, frameRate); + matrixFrameLerp(&(node++)->pos, anglesArmA[i], anglesArmB[i], frameDelta, frameRate); } else { - matrixFrame((node++)->pos, anglesArmA[i]); + matrixFrame(&(node++)->pos, anglesArmA[i]); } drawMesh(*mesh++); @@ -662,7 +670,7 @@ void drawLaraNodesLerp(const ItemObj* lara, const AnimFrame* frameA, const AnimF } { // JOINT_HEAD - matrixFrameLerp((node++)->pos, anglesA + 3 * LARA_ARM_MAX, anglesB + 3 * LARA_ARM_MAX, frameDelta, frameRate); + matrixFrameLerp(&(node++)->pos, anglesA + 3 * LARA_ARM_MAX, anglesB + 3 * LARA_ARM_MAX, frameDelta, frameRate); matrixRotateYXZ(extraL->head.angle.x, extraL->head.angle.y, extraL->head.angle.z); drawMesh(*mesh++); } @@ -831,7 +839,7 @@ void drawRoom(const Room* room, Camera* camera) matrixPush(); matrixTranslateAbs(pos.x, pos.y, pos.z); - matrixRotateY(STATIC_MESH_ROT(mesh->flags)); + matrixRotateYQ(STATIC_MESH_QUADRANT(mesh->flags)); int32 vis = boxIsVisible(&staticMesh->vbox); if (vis != 0) { diff --git a/src/fixed/game.h b/src/fixed/game.h index b2dec1f1..375fb06b 100644 --- a/src/fixed/game.h +++ b/src/fixed/game.h @@ -89,7 +89,9 @@ struct Game } // gym + //resetLara(0, 7, _vec3i(39038, -1280, 51712), ANGLE_90); // start //resetLara(0, 8, _vec3i(55994, 0, 52603), ANGLE_90); // piano + //resetLara(0, 9, _vec3i(47672, 256, 40875), ANGLE_90); // hall //resetLara(0, 13, _vec3i(38953, 3328, 63961), ANGLE_90 + ANGLE_45); // pool // level 1 //resetLara(0, 0, _vec3i(74588, 3072, 19673), ANGLE_0); // first darts @@ -111,11 +113,6 @@ struct Game //resetLara(0, 44, _vec3i(73798, 2304, 9819), ANGLE_90); // uw gears drawInit(); - - #ifdef __3DO__ - //players[0]->angle.y += ANGLE_180; - //players[0]->pos.x += 1024; - #endif } void resetLara(int32 index, int32 roomIndex, const vec3i &pos, int32 angleY) diff --git a/src/fixed/item.h b/src/fixed/item.h index 0ae0791a..351ae2fc 100644 --- a/src/fixed/item.h +++ b/src/fixed/item.h @@ -813,7 +813,7 @@ vec3i ItemObj::getJoint(int32 jointIndex, const vec3i &offset) const const ModelNode* node = level.nodes + model->nodeIndex; - matrixFrame(frame->pos, frameAngles); + matrixFrame(&frame->pos, frameAngles); ASSERT(jointIndex < model->count); @@ -822,7 +822,7 @@ vec3i ItemObj::getJoint(int32 jointIndex, const vec3i &offset) const if (node->flags & 1) matrixPop(); if (node->flags & 2) matrixPush(); - matrixFrame(node->pos, ++frameAngles); + matrixFrame(&node->pos, ++frameAngles); // TODO extra rotations @@ -866,7 +866,7 @@ int32 ItemObj::getSpheres(Sphere* spheres, bool flag) const const ModelNode* node = level.nodes + model->nodeIndex; - matrixFrame(frame->pos, frameAngles); + matrixFrame(&frame->pos, frameAngles); Sphere* sphere = spheres; @@ -889,7 +889,7 @@ int32 ItemObj::getSpheres(Sphere* spheres, bool flag) const if (node->flags & 1) matrixPop(); if (node->flags & 2) matrixPush(); - matrixFrame(node->pos, ++frameAngles); + matrixFrame(&node->pos, ++frameAngles); // TODO extra rotations diff --git a/src/fixed/lara.h b/src/fixed/lara.h index 498183a7..0d45a7b3 100644 --- a/src/fixed/lara.h +++ b/src/fixed/lara.h @@ -412,6 +412,16 @@ struct Lara : ItemObj soundStop(SND_SCREAM); } + void restore() + { + if (health > 0) + return; + + health = LARA_MAX_HEALTH; + oxygen = LARA_MAX_OXYGEN; + animSet(ROOM_FLAG_WATER(room->info->flags) ? Lara::ANIM_UNDERWATER : Lara::ANIM_STAND, true, 0); + } + // common bool alignAngle(int16 &angle, int16 threshold) { diff --git a/src/fixed/object.h b/src/fixed/object.h index 4d9919b9..26ddd669 100644 --- a/src/fixed/object.h +++ b/src/fixed/object.h @@ -713,7 +713,7 @@ struct TrapFloor : Object return; } - if (flags.gravity) { + if (state == STATE_FALL) { updateRoom(); } diff --git a/src/fixed/room.h b/src/fixed/room.h index 8ac7e1ee..2c2e17c4 100644 --- a/src/fixed/room.h +++ b/src/fixed/room.h @@ -286,7 +286,7 @@ bool Room::collideStatic(CollisionInfo &cinfo, const vec3i &p, int32 height) cinfo.staticHit = false; cinfo.offset = _vec3i(0, 0, 0); - AABBs objBox; + AABBi objBox; objBox.minX = -cinfo.radius; objBox.maxX = cinfo.radius; objBox.minZ = -cinfo.radius; @@ -314,17 +314,14 @@ bool Room::collideStatic(CollisionInfo &cinfo, const vec3i &p, int32 height) if (staticMesh->flags & STATIC_MESH_FLAG_NO_COLLISION) continue; - AABBs meshBox = boxRotate(staticMesh->cbox, STATIC_MESH_ROT(mesh->flags)); - // TODO align RoomInfo::Mesh (room relative int16?) - vec3i pos; - pos.x = mesh->pos.x + (room->info->x << 8); - pos.y = mesh->pos.y; - pos.z = mesh->pos.z + (room->info->z << 8); - - pos -= p; + int32 x = mesh->pos.x - p.x + (room->info->x << 8); + int32 y = mesh->pos.y - p.y; + int32 z = mesh->pos.z - p.z + (room->info->z << 8); - boxTranslate(meshBox, pos); + AABBi meshBox(staticMesh->cbox); + boxRotateYQ(meshBox, STATIC_MESH_QUADRANT(mesh->flags)); + boxTranslate(meshBox, x, y, z); if (!boxIntersect(meshBox, objBox)) continue; diff --git a/src/platform/3do/boxRotateYQ.s b/src/platform/3do/boxRotateYQ.s new file mode 100644 index 00000000..1d83b65a --- /dev/null +++ b/src/platform/3do/boxRotateYQ.s @@ -0,0 +1,58 @@ + AREA |C$$code|, CODE, READONLY +|x$codeseg| + + INCLUDE common_asm.inc + + EXPORT boxRotateYQ_asm + +vx RN r0 +q RN r1 +vz RN r2 + +min RN q +max RN r3 + +minX RN r12 +maxX RN lr +minZ RN minX +maxZ RN maxX + +boxRotateYQ_asm + cmp q, #2 + moveq pc, lr + + stmfd sp!, {lr} + + add vz, vx, #(4 * 4) + + cmp q, #1 + beq q_1 + cmp q, #3 + beq q_3 + +q_0 ldmia vx, {minX, maxX} + rsb min, maxX, #0 + rsb max, minX, #0 + stmia vx, {min, max} + ldmia vz, {minZ, maxZ} + rsb min, maxZ, #0 + rsb max, minZ, #0 + stmia vz, {min, max} + ldmfd sp!, {pc} + +q_1 ldmia vz, {minZ, maxZ} + ldmia vx, {min, max} + stmia vz, {min, max} + rsb min, maxZ, #0 + rsb max, minZ, #0 + stmia vx, {min, max} + ldmfd sp!, {pc} + +q_3 ldmia vx, {minX, maxX} + ldmia vz, {min, max} + stmia vx, {min, max} + rsb min, maxX, #0 + rsb max, minX, #0 + stmia vz, {min, max} + ldmfd sp!, {pc} + END diff --git a/src/platform/3do/boxTranslate.s b/src/platform/3do/boxTranslate.s new file mode 100644 index 00000000..9c7cf0ae --- /dev/null +++ b/src/platform/3do/boxTranslate.s @@ -0,0 +1,32 @@ + AREA |C$$code|, CODE, READONLY +|x$codeseg| + + INCLUDE common_asm.inc + + EXPORT boxTranslate_asm + +aabb RN r0 +x RN r1 +y RN r2 +z RN r3 +minX RN r4 +maxX RN r5 +minY RN r6 +maxY RN r7 +minZ RN r12 +maxZ RN lr + +boxTranslate_asm + stmfd sp!, {r4-r7, lr} + + ldmia aabb, {minX, maxX, minY, maxY, minZ, maxZ} + add minX, minX, x + add maxX, maxX, x + add minY, minY, y + add maxY, maxY, y + add minZ, minZ, z + add maxZ, maxZ, z + stmia aabb, {minX, maxX, minY, maxY, minZ, maxZ} + + ldmfd sp!, {r4-r7, pc} + END diff --git a/src/platform/3do/common_asm.inc b/src/platform/3do/common_asm.inc index 63635808..f430591d 100644 --- a/src/platform/3do/common_asm.inc +++ b/src/platform/3do/common_asm.inc @@ -4,8 +4,10 @@ IMPORT gFacesBase IMPORT gOT IMPORT gPalette + IMPORT cameraViewPos IMPORT shadeTable IMPORT divTable + IMPORT sinTable IMPORT level CCB_NOBLK EQU 0x00000010 diff --git a/src/platform/3do/main.cpp b/src/platform/3do/main.cpp index 6dfe4537..a26f0ea4 100644 --- a/src/platform/3do/main.cpp +++ b/src/platform/3do/main.cpp @@ -363,14 +363,7 @@ int main(int argc, char *argv[]) if ((keys & IK_A) && (keys & IK_C)) // respawn { - Lara* lara = players[0]; - if (lara->health <= 0) - { - lara->health = LARA_MAX_HEALTH; - lara->oxygen = LARA_MAX_OXYGEN; - lara->animSet(Lara::ANIM_STAND, true, 0); - //game.resetLara(0, lara->room - rooms, lara->pos, lara->angle.y); - } + players[0]->restore(); } int32 updateTime = osGetSystemTimeMS(); diff --git a/src/platform/3do/matrixRotateYQ.s b/src/platform/3do/matrixRotateYQ.s new file mode 100644 index 00000000..7f80430e --- /dev/null +++ b/src/platform/3do/matrixRotateYQ.s @@ -0,0 +1,66 @@ + AREA |C$$code|, CODE, READONLY +|x$codeseg| + + INCLUDE common_asm.inc + + EXPORT matrixRotateYQ_asm + +q RN r0 +mx RN r1 +my RN r2 + +mx0 RN r3 +mx1 RN r4 +mx2 RN r5 + +my0 RN q +my1 RN r12 +my2 RN lr + +matrixRotateYQ_asm + cmp q, #2 + moveq pc, lr + + stmfd sp!, {r4-r5, lr} + + ldr mx, =matrixPtr + ldr mx, [mx] + add my, mx, #(6 * 4) + + ldmia mx, {mx0, mx1, mx2} + + cmp q, #1 + beq q_1 + cmp q, #3 + beq q_3 + + ; column-major + +q_0 ldmia my, {my0, my1, my2} + rsb mx0, mx0, #0 + rsb mx1, mx1, #0 + rsb mx2, mx2, #0 + rsb my0, my0, #0 + rsb my1, my1, #0 + rsb my2, my2, #0 + stmia mx, {mx0, mx1, mx2} + stmia my, {my0, my1, my2} + ldmfd sp!, {r4-r5, pc} + +q_1 ldmia my, {my0, my1, my2} + stmia mx, {my0, my1, my2} + rsb mx0, mx0, #0 + rsb mx1, mx1, #0 + rsb mx2, mx2, #0 + stmia my, {mx0, mx1, mx2} + ldmfd sp!, {r4-r5, pc} + +q_3 ldmia my, {my0, my1, my2} + stmia my, {mx0, mx1, mx2} + rsb my0, my0, #0 + rsb my1, my1, #0 + rsb my2, my2, #0 + stmia mx, {my0, my1, my2} + ldmfd sp!, {r4-r5, pc} + + END diff --git a/src/platform/3do/matrixSetBasis.s b/src/platform/3do/matrixSetBasis.s new file mode 100644 index 00000000..759190a9 --- /dev/null +++ b/src/platform/3do/matrixSetBasis.s @@ -0,0 +1,32 @@ + AREA |C$$code|, CODE, READONLY +|x$codeseg| + + INCLUDE common_asm.inc + + EXPORT matrixSetBasis_asm + +dst RN r0 +src RN r1 + +e0 RN r2 +e1 RN r3 +e2 RN r12 + +matrixSetBasis_asm + ; column-major + ; e0 e1 e2 + ; e0 e1 e2 + ; e0 e1 e2 + ; x y z + + ldmia src!, {e0, e1, e2} + stmia dst!, {e0, e1, e2} + + ldmia src!, {e0, e1, e2} + stmia dst!, {e0, e1, e2} + + ldmia src!, {e0, e1, e2} + stmia dst!, {e0, e1, e2} + + mov pc, lr + END diff --git a/src/platform/3do/matrixSetIdentity.s b/src/platform/3do/matrixSetIdentity.s new file mode 100644 index 00000000..2f2f130f --- /dev/null +++ b/src/platform/3do/matrixSetIdentity.s @@ -0,0 +1,33 @@ + AREA |C$$code|, CODE, READONLY +|x$codeseg| + + INCLUDE common_asm.inc + + EXPORT matrixSetIdentity_asm + +e0 RN r0 +e1 RN r1 +e2 RN r2 +e3 RN r3 +m RN r12 + +matrixSetIdentity_asm + ldr m, =matrixPtr + ldr m, [m] + mov e0, #0x4000 + mov e1, #0 + mov e2, #0 + mov e3, #0 + + ; column-major + ; e0 e1 e2 + ; e3 e0 e1 + ; e2 e3 e0 + ; e1 e2 e3 + + stmia m!, {e0, e1, e2, e3} + stmia m!, {e0, e1, e2, e3} + stmia m!, {e0, e1, e2, e3} + + mov pc, lr + END diff --git a/src/platform/3do/matrixTranslate.s b/src/platform/3do/matrixTranslate.s new file mode 100644 index 00000000..0986d13c --- /dev/null +++ b/src/platform/3do/matrixTranslate.s @@ -0,0 +1,51 @@ + AREA |C$$code|, CODE, READONLY +|x$codeseg| + + INCLUDE common_asm.inc + + EXPORT matrixTranslate_asm + +x RN r0 +y RN r1 +z RN r2 + +m RN r3 + +e0 RN r4 +e1 RN r5 +e2 RN r6 + +dx RN r7 +dy RN r12 +dz RN lr + +matrixTranslate_asm + stmfd sp!, {r4-r7, lr} + + ldr m, =matrixPtr + ldr m, [m] + + ldmia m!, {e0, e1, e2} + mul dx, e0, x + mul dy, e1, x + mul dz, e2, x + + ldmia m!, {e0, e1, e2} + mla dx, e0, y, dx + mla dy, e1, y, dy + mla dz, e2, y, dz + + ldmia m!, {e0, e1, e2} + mla dx, e0, z, dx + mla dy, e1, z, dy + mla dz, e2, z, dz + + ldmia m, {e0, e1, e2} + add e0, e0, dx + add e1, e1, dy + add e2, e2, dz + + stmia m!, {e0, e1, e2} + + ldmfd sp!, {r4-r7, pc} + END diff --git a/src/platform/3do/matrixTranslateAbs.s b/src/platform/3do/matrixTranslateAbs.s new file mode 100644 index 00000000..07e53c2a --- /dev/null +++ b/src/platform/3do/matrixTranslateAbs.s @@ -0,0 +1,52 @@ + AREA |C$$code|, CODE, READONLY +|x$codeseg| + + INCLUDE common_asm.inc + + EXPORT matrixTranslateAbs_asm + +x RN r0 +y RN r1 +z RN r2 + +m RN r3 + +e0 RN r4 +e1 RN r5 +e2 RN r6 + +dx RN r7 +dy RN r12 +dz RN lr + +matrixTranslateAbs_asm + stmfd sp!, {r4-r7, lr} + + ldr m, =cameraViewPos + ldmia m, {e0, e1, e2} + sub x, x, e0 + sub y, y, e1 + sub z, z, e2 + + ldr m, =matrixPtr + ldr m, [m] + + ldmia m!, {e0, e1, e2} + mul dx, e0, x + mul dy, e1, x + mul dz, e2, x + + ldmia m!, {e0, e1, e2} + mla dx, e0, y, dx + mla dy, e1, y, dy + mla dz, e2, y, dz + + ldmia m!, {e0, e1, e2} + mla dx, e0, z, dx + mla dy, e1, z, dy + mla dz, e2, z, dz + + stmia m!, {dx, dy, dz} + + ldmfd sp!, {r4-r7, pc} + END diff --git a/src/platform/3do/phd_sin.s b/src/platform/3do/phd_sin.s new file mode 100644 index 00000000..000b4999 --- /dev/null +++ b/src/platform/3do/phd_sin.s @@ -0,0 +1,27 @@ + AREA |C$$code|, CODE, READONLY +|x$codeseg| + + INCLUDE common_asm.inc + + EXPORT phd_sin_asm + +x RN r0 +y RN r1 +lut RN r2 + +phd_sin_asm + tst x, #0x4000 + mov y, x, lsl #16 + mov y, y, lsr #16 + bic x, y, #0x8000 + rsbne x, x, #0x8000 + tst x, #16 + mov x, x, lsr #5 + ldr lut, =sinTable + ldr x, [lut, x, lsl #2] + movne x, x, lsl #16 + mov x, x, lsr #16 + cmp y, #0x8000 + rsbgt x, x, #0 + mov pc, lr + END diff --git a/src/platform/3do/projectVertices.s b/src/platform/3do/projectVertices.s index c632bacc..6d7c05d2 100644 --- a/src/platform/3do/projectVertices.s +++ b/src/platform/3do/projectVertices.s @@ -53,7 +53,7 @@ projectVertices_asm mov mz, mz, asr #FIXED_SHIFT mov mz, mz, lsl #CLIP_SHIFT -loop ldmia vertex, {x, y, z} ; read unpacked vertex +loop ldmia vertex, {x, y, z} ; read transformed vertex add x, x, mx, asr #FIXED_SHIFT add y, my, y, lsl #PROJ_SHIFT ; extra shift for min/max cmp with hi half-word diff --git a/src/platform/gba/packer/main.cpp b/src/platform/gba/packer/main.cpp index ebadced0..c0162e79 100644 --- a/src/platform/gba/packer/main.cpp +++ b/src/platform/gba/packer/main.cpp @@ -1630,15 +1630,15 @@ struct LevelPC struct NodeComp { - uint16 flags; vec3s pos; + uint16 flags; void write(FileStream &f) { - f.write(flags); f.write(pos.x); f.write(pos.y); f.write(pos.z); + f.write(flags); } };