Refresh 12

This commit is contained in:
n64
2020-09-20 11:15:47 -04:00
parent 9214dddabc
commit 8b872a71e8
137 changed files with 2102 additions and 1582 deletions

View File

@@ -314,12 +314,12 @@ struct GraphNodeObject *init_graph_node_object(struct AllocOnlyPool *pool,
vec3s_copy(graphNode->angle, angle);
graphNode->sharedChild = sharedChild;
graphNode->throwMatrix = NULL;
graphNode->unk38.animID = 0;
graphNode->unk38.curAnim = NULL;
graphNode->unk38.animFrame = 0;
graphNode->unk38.animFrameAccelAssist = 0;
graphNode->unk38.animAccel = 0x10000;
graphNode->unk38.animTimer = 0;
graphNode->animInfo.animID = 0;
graphNode->animInfo.curAnim = NULL;
graphNode->animInfo.animFrame = 0;
graphNode->animInfo.animFrameAccelAssist = 0;
graphNode->animInfo.animAccel = 0x10000;
graphNode->animInfo.animTimer = 0;
graphNode->node.flags |= GRAPH_RENDER_HAS_ANIMATION;
}
@@ -698,7 +698,7 @@ void geo_obj_init(struct GraphNodeObject *graphNode, void *sharedChild, Vec3f po
graphNode->sharedChild = sharedChild;
graphNode->unk4C = 0;
graphNode->throwMatrix = NULL;
graphNode->unk38.curAnim = NULL;
graphNode->animInfo.curAnim = NULL;
graphNode->node.flags |= GRAPH_RENDER_ACTIVE;
graphNode->node.flags &= ~GRAPH_RENDER_INVISIBLE;
@@ -717,12 +717,12 @@ void geo_obj_init_spawninfo(struct GraphNodeObject *graphNode, struct SpawnInfo
graphNode->pos[1] = (f32) spawn->startPos[1];
graphNode->pos[2] = (f32) spawn->startPos[2];
graphNode->unk18 = spawn->areaIndex;
graphNode->unk19 = spawn->activeAreaIndex;
graphNode->areaIndex = spawn->areaIndex;
graphNode->activeAreaIndex = spawn->activeAreaIndex;
graphNode->sharedChild = spawn->unk18;
graphNode->unk4C = spawn;
graphNode->throwMatrix = NULL;
graphNode->unk38.curAnim = 0;
graphNode->animInfo.curAnim = 0;
graphNode->node.flags |= GRAPH_RENDER_ACTIVE;
graphNode->node.flags &= ~GRAPH_RENDER_INVISIBLE;
@@ -737,11 +737,11 @@ void geo_obj_init_animation(struct GraphNodeObject *graphNode, struct Animation
struct Animation **animSegmented = segmented_to_virtual(animPtrAddr);
struct Animation *anim = segmented_to_virtual(*animSegmented);
if (graphNode->unk38.curAnim != anim) {
graphNode->unk38.curAnim = anim;
graphNode->unk38.animFrame = anim->unk04 + ((anim->flags & ANIM_FLAG_FORWARD) ? 1 : -1);
graphNode->unk38.animAccel = 0;
graphNode->unk38.animYTrans = 0;
if (graphNode->animInfo.curAnim != anim) {
graphNode->animInfo.curAnim = anim;
graphNode->animInfo.animFrame = anim->startFrame + ((anim->flags & ANIM_FLAG_FORWARD) ? 1 : -1);
graphNode->animInfo.animAccel = 0;
graphNode->animInfo.animYTrans = 0;
}
}
@@ -752,15 +752,15 @@ void geo_obj_init_animation_accel(struct GraphNodeObject *graphNode, struct Anim
struct Animation **animSegmented = segmented_to_virtual(animPtrAddr);
struct Animation *anim = segmented_to_virtual(*animSegmented);
if (graphNode->unk38.curAnim != anim) {
graphNode->unk38.curAnim = anim;
graphNode->unk38.animYTrans = 0;
graphNode->unk38.animFrameAccelAssist =
(anim->unk04 << 16) + ((anim->flags & ANIM_FLAG_FORWARD) ? animAccel : -animAccel);
graphNode->unk38.animFrame = graphNode->unk38.animFrameAccelAssist >> 16;
if (graphNode->animInfo.curAnim != anim) {
graphNode->animInfo.curAnim = anim;
graphNode->animInfo.animYTrans = 0;
graphNode->animInfo.animFrameAccelAssist =
(anim->startFrame << 16) + ((anim->flags & ANIM_FLAG_FORWARD) ? animAccel : -animAccel);
graphNode->animInfo.animFrame = graphNode->animInfo.animFrameAccelAssist >> 16;
}
graphNode->unk38.animAccel = animAccel;
graphNode->animInfo.animAccel = animAccel;
}
/**
@@ -789,7 +789,7 @@ s32 retrieve_animation_index(s32 frame, u16 **attributes) {
* whether it plays forwards or backwards, and whether it stops or loops at
* the end etc.
*/
s16 geo_update_animation_frame(struct GraphNodeObject_sub *obj, s32 *accelAssist) {
s16 geo_update_animation_frame(struct AnimInfo *obj, s32 *accelAssist) {
s32 result;
struct Animation *anim;
@@ -810,11 +810,11 @@ s16 geo_update_animation_frame(struct GraphNodeObject_sub *obj, s32 *accelAssist
result = (obj->animFrame - 1) << 16;
}
if (GET_HIGH_S16_OF_32(result) < anim->unk06) {
if (GET_HIGH_S16_OF_32(result) < anim->loopStart) {
if (anim->flags & ANIM_FLAG_NOLOOP) {
SET_HIGH_S16_OF_32(result, anim->unk06);
SET_HIGH_S16_OF_32(result, anim->loopStart);
} else {
SET_HIGH_S16_OF_32(result, anim->unk08 - 1);
SET_HIGH_S16_OF_32(result, anim->loopEnd - 1);
}
}
} else {
@@ -824,11 +824,11 @@ s16 geo_update_animation_frame(struct GraphNodeObject_sub *obj, s32 *accelAssist
result = (obj->animFrame + 1) << 16;
}
if (GET_HIGH_S16_OF_32(result) >= anim->unk08) {
if (GET_HIGH_S16_OF_32(result) >= anim->loopEnd) {
if (anim->flags & ANIM_FLAG_NOLOOP) {
SET_HIGH_S16_OF_32(result, anim->unk08 - 1);
SET_HIGH_S16_OF_32(result, anim->loopEnd - 1);
} else {
SET_HIGH_S16_OF_32(result, anim->unk06);
SET_HIGH_S16_OF_32(result, anim->loopStart);
}
}
}
@@ -849,7 +849,7 @@ s16 geo_update_animation_frame(struct GraphNodeObject_sub *obj, s32 *accelAssist
* animations without lateral translation.
*/
void geo_retreive_animation_translation(struct GraphNodeObject *obj, Vec3f position) {
struct Animation *animation = obj->unk38.curAnim;
struct Animation *animation = obj->animInfo.curAnim;
u16 *attribute;
s16 *values;
s16 frame;
@@ -858,7 +858,7 @@ void geo_retreive_animation_translation(struct GraphNodeObject *obj, Vec3f posit
attribute = segmented_to_virtual((void *) animation->index);
values = segmented_to_virtual((void *) animation->values);
frame = obj->unk38.animFrame;
frame = obj->animInfo.animFrame;
if (frame < 0) {
frame = 0;

View File

@@ -420,7 +420,7 @@ void geo_obj_init_animation_accel(struct GraphNodeObject *graphNode, struct Anim
s32 retrieve_animation_index(s32 frame, u16 **attributes);
s16 geo_update_animation_frame(struct GraphNodeObject_sub *obj, s32 *accelAssist);
s16 geo_update_animation_frame(struct AnimInfo *obj, s32 *accelAssist);
void geo_retreive_animation_translation(struct GraphNodeObject *obj, Vec3f position);
struct GraphNodeRoot *geo_find_root(struct GraphNode *graphNode);

View File

@@ -159,7 +159,8 @@ void mtxf_copy(Mat4 dest, Mat4 src) {
void mtxf_identity(Mat4 mtx) {
register s32 i;
register f32 *dest;
// Note: These loops need to be on one line to match on PAL
// These loops must be one line to match on -O2
// initialize everything except the first and last cells to 0
for (dest = (f32 *) mtx + 1, i = 0; i < 14; dest++, i++) *dest = 0;

View File

@@ -199,8 +199,8 @@ s32 find_wall_collisions(struct WallCollisionData *colData) {
// World (level) consists of a 16x16 grid. Find where the collision is on
// the grid (round toward -inf)
cellX = ((x + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & 0x0F;
cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & 0x0F;
cellX = ((x + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & (NUM_CELLS - 1);
cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & (NUM_CELLS - 1);
// Check for surfaces belonging to objects.
node = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS].next;
@@ -307,8 +307,8 @@ f32 find_ceil(f32 posX, f32 posY, f32 posZ, struct Surface **pceil) {
s16 cellZ, cellX;
struct Surface *ceil, *dynamicCeil;
struct SurfaceNode *surfaceList;
f32 height = 20000.0f;
f32 dynamicHeight = 20000.0f;
f32 height = CELL_HEIGHT_LIMIT;
f32 dynamicHeight = CELL_HEIGHT_LIMIT;
s16 x, y, z;
//! (Parallel Universes) Because position is casted to an s16, reaching higher
@@ -327,8 +327,8 @@ f32 find_ceil(f32 posX, f32 posY, f32 posZ, struct Surface **pceil) {
}
// Each level is split into cells to limit load, find the appropriate cell.
cellX = ((x + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & 0xF;
cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & 0xF;
cellX = ((x + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & (NUM_CELLS - 1);
cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & (NUM_CELLS - 1);
// Check for surfaces belonging to objects.
surfaceList = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS].next;
@@ -486,7 +486,7 @@ f32 find_floor_height(f32 x, f32 y, f32 z) {
f32 unused_find_dynamic_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor) {
struct SurfaceNode *surfaceList;
struct Surface *floor;
f32 floorHeight = -11000.0f;
f32 floorHeight = FLOOR_LOWER_LIMIT;
// Would normally cause PUs, but dynamic floors unload at that range.
s16 x = (s16) xPos;
@@ -494,8 +494,8 @@ f32 unused_find_dynamic_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfl
s16 z = (s16) zPos;
// Each level is split into cells to limit load, find the appropriate cell.
s16 cellX = ((x + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & 0x0F;
s16 cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & 0x0F;
s16 cellX = ((x + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & (NUM_CELLS - 1);
s16 cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & (NUM_CELLS - 1);
surfaceList = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next;
floor = find_floor_from_list(surfaceList, x, y, z, &floorHeight);
@@ -514,8 +514,8 @@ f32 find_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor) {
struct Surface *floor, *dynamicFloor;
struct SurfaceNode *surfaceList;
f32 height = -11000.0f;
f32 dynamicHeight = -11000.0f;
f32 height = FLOOR_LOWER_LIMIT;
f32 dynamicHeight = FLOOR_LOWER_LIMIT;
//! (Parallel Universes) Because position is casted to an s16, reaching higher
// float locations can return floors despite them not existing there.
@@ -534,8 +534,8 @@ f32 find_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor) {
}
// Each level is split into cells to limit load, find the appropriate cell.
cellX = ((x + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & 0xF;
cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & 0xF;
cellX = ((x + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & (NUM_CELLS - 1);
cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & (NUM_CELLS - 1);
// Check for surfaces belonging to objects.
surfaceList = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next;
@@ -591,7 +591,7 @@ f32 find_water_level(f32 x, f32 z) {
s32 numRegions;
s16 val;
f32 loX, hiX, loZ, hiZ;
f32 waterLevel = -11000.0f;
f32 waterLevel = FLOOR_LOWER_LIMIT;
s16 *p = gEnvironmentRegions;
if (p != NULL) {
@@ -627,7 +627,7 @@ f32 find_poison_gas_level(f32 x, f32 z) {
UNUSED s32 unused;
s16 val;
f32 loX, hiX, loZ, hiZ;
f32 gasLevel = -11000.0f;
f32 gasLevel = FLOOR_LOWER_LIMIT;
s16 *p = gEnvironmentRegions;
if (p != NULL) {
@@ -689,25 +689,25 @@ void debug_surface_list_info(f32 xPos, f32 zPos) {
s32 cellX = (xPos + LEVEL_BOUNDARY_MAX) / CELL_SIZE;
s32 cellZ = (zPos + LEVEL_BOUNDARY_MAX) / CELL_SIZE;
list = gStaticSurfacePartition[cellZ & 0x0F][cellX & 0x0F][SPATIAL_PARTITION_FLOORS].next;
list = gStaticSurfacePartition[cellZ & (NUM_CELLS - 1)][cellX & (NUM_CELLS - 1)][SPATIAL_PARTITION_FLOORS].next;
numFloors += surface_list_length(list);
list = gDynamicSurfacePartition[cellZ & 0x0F][cellX & 0x0F][SPATIAL_PARTITION_FLOORS].next;
list = gDynamicSurfacePartition[cellZ & (NUM_CELLS - 1)][cellX & (NUM_CELLS - 1)][SPATIAL_PARTITION_FLOORS].next;
numFloors += surface_list_length(list);
list = gStaticSurfacePartition[cellZ & 0x0F][cellX & 0x0F][SPATIAL_PARTITION_WALLS].next;
list = gStaticSurfacePartition[cellZ & (NUM_CELLS - 1)][cellX & (NUM_CELLS - 1)][SPATIAL_PARTITION_WALLS].next;
numWalls += surface_list_length(list);
list = gDynamicSurfacePartition[cellZ & 0x0F][cellX & 0x0F][SPATIAL_PARTITION_WALLS].next;
list = gDynamicSurfacePartition[cellZ & (NUM_CELLS - 1)][cellX & (NUM_CELLS - 1)][SPATIAL_PARTITION_WALLS].next;
numWalls += surface_list_length(list);
list = gStaticSurfacePartition[cellZ & 0x0F][cellX & 0x0F][SPATIAL_PARTITION_CEILS].next;
list = gStaticSurfacePartition[cellZ & (NUM_CELLS - 1)][cellX & (NUM_CELLS - 1)][SPATIAL_PARTITION_CEILS].next;
numCeils += surface_list_length(list);
list = gDynamicSurfacePartition[cellZ & 0x0F][cellX & 0x0F][SPATIAL_PARTITION_CEILS].next;
list = gDynamicSurfacePartition[cellZ & (NUM_CELLS - 1)][cellX & (NUM_CELLS - 1)][SPATIAL_PARTITION_CEILS].next;
numCeils += surface_list_length(list);
print_debug_top_down_mapinfo("area %x", cellZ * 16 + cellX);
print_debug_top_down_mapinfo("area %x", cellZ * NUM_CELLS + cellX);
// Names represent ground, walls, and roofs as found in SMS.
print_debug_top_down_mapinfo("dg %d", numFloors);

View File

@@ -5,8 +5,11 @@
#include "types.h"
#define LEVEL_BOUNDARY_MAX 0x2000
#define CELL_SIZE 0x400
#define LEVEL_BOUNDARY_MAX 0x2000
#define CELL_SIZE 0x400
#define CELL_HEIGHT_LIMIT 20000.f
#define FLOOR_LOWER_LIMIT -11000.f
struct WallCollisionData
{

View File

@@ -21,8 +21,8 @@ s32 unused8038BE90;
* Partitions for course and object surfaces. The arrays represent
* the 16x16 cells that each level is split into.
*/
SpatialPartitionCell gStaticSurfacePartition[16][16];
SpatialPartitionCell gDynamicSurfacePartition[16][16];
SpatialPartitionCell gStaticSurfacePartition[NUM_CELLS][NUM_CELLS];
SpatialPartitionCell gDynamicSurfacePartition[NUM_CELLS][NUM_CELLS];
/**
* Pools of data to contain either surface nodes or surfaces.
@@ -83,7 +83,7 @@ static struct Surface *alloc_surface(void) {
* Iterates through the entire partition, clearing the surfaces.
*/
static void clear_spatial_partition(SpatialPartitionCell *cells) {
register s32 i = 16 * 16;
register s32 i = NUM_CELLS * NUM_CELLS;
while (i--) {
(*cells)[SPATIAL_PARTITION_FLOORS].next = NULL;
@@ -201,18 +201,18 @@ static s16 lower_cell_index(s16 coord) {
s16 index;
// Move from range [-0x2000, 0x2000) to [0, 0x4000)
coord += 0x2000;
coord += LEVEL_BOUNDARY_MAX;
if (coord < 0) {
coord = 0;
}
// [0, 16)
index = coord / 0x400;
index = coord / CELL_SIZE;
// Include extra cell if close to boundary
//! Some wall checks are larger than the buffer, meaning wall checks can
// miss walls that are near a cell border.
if (coord % 0x400 < 50) {
if (coord % CELL_SIZE < 50) {
index -= 1;
}
@@ -233,23 +233,23 @@ static s16 upper_cell_index(s16 coord) {
s16 index;
// Move from range [-0x2000, 0x2000) to [0, 0x4000)
coord += 0x2000;
coord += LEVEL_BOUNDARY_MAX;
if (coord < 0) {
coord = 0;
}
// [0, 16)
index = coord / 0x400;
index = coord / CELL_SIZE;
// Include extra cell if close to boundary
//! Some wall checks are larger than the buffer, meaning wall checks can
// miss walls that are near a cell border.
if (coord % 0x400 > 0x400 - 50) {
if (coord % CELL_SIZE > CELL_SIZE - 50) {
index += 1;
}
if (index > 15) {
index = 15;
if (index > (NUM_CELLS - 1)) {
index = (NUM_CELLS - 1);
}
// Potentially < 0, but since lower index is >= 0, not exploitable

View File

@@ -5,6 +5,10 @@
#include "types.h"
// NUM_CELLS needs to be a power of 2 so that the bitwise
// in surface_collision.c functions can work properly
#define NUM_CELLS 16
struct SurfaceNode
{
struct SurfaceNode *next;
@@ -23,8 +27,8 @@ typedef struct SurfaceNode SpatialPartitionCell[3];
// Needed for bs bss reordering memes.
extern s32 unused8038BE90;
extern SpatialPartitionCell gStaticSurfacePartition[16][16];
extern SpatialPartitionCell gDynamicSurfacePartition[16][16];
extern SpatialPartitionCell gStaticSurfacePartition[NUM_CELLS][NUM_CELLS];
extern SpatialPartitionCell gDynamicSurfacePartition[NUM_CELLS][NUM_CELLS];
extern struct SurfaceNode *sSurfaceNodePool;
extern struct Surface *sSurfacePool;
extern s16 sSurfacePoolSize;