Refactor to make surface iteration easier to make safer
This commit is contained in:
@@ -13,10 +13,11 @@ static struct Surface *find_ceil_from_list( s32 x, s32 y, s32 z, f32 *pheight) {
|
|||||||
|
|
||||||
ceil = NULL;
|
ceil = NULL;
|
||||||
|
|
||||||
// Stay in this loop until out of ceilings.
|
uint32_t groupCount = loaded_surface_iter_group_count();
|
||||||
int count = loaded_surface_get_count();
|
for( int i = 0; i < groupCount; ++i ) {
|
||||||
for( int i = 0; i < count; ++i ) {
|
uint32_t surfCount = loaded_surface_iter_group_size( i );
|
||||||
surf = loaded_surface_get_at_index(i);
|
for( int j = 0; j < surfCount; ++j ) {
|
||||||
|
surf = loaded_surface_iter_get_at_index( i, j );
|
||||||
|
|
||||||
// Do the check normally done in add_surface_to_cell
|
// Do the check normally done in add_surface_to_cell
|
||||||
if( surf->normal.y >= -0.01f ) continue;
|
if( surf->normal.y >= -0.01f ) continue;
|
||||||
@@ -71,7 +72,7 @@ static struct Surface *find_ceil_from_list( s32 x, s32 y, s32 z, f32 *pheight) {
|
|||||||
ceil = surf;
|
ceil = surf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}}
|
||||||
return ceil;
|
return ceil;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,10 +87,11 @@ static struct Surface *find_floor_from_list( s32 x, s32 y, s32 z, f32 *pheight)
|
|||||||
f32 height;
|
f32 height;
|
||||||
struct Surface *floor = NULL;
|
struct Surface *floor = NULL;
|
||||||
|
|
||||||
// Iterate through the list of floors until there are no more floors.
|
uint32_t groupCount = loaded_surface_iter_group_count();
|
||||||
int count = loaded_surface_get_count();
|
for( int i = 0; i < groupCount; ++i ) {
|
||||||
for( int i = 0; i < count; ++i ) {
|
uint32_t surfCount = loaded_surface_iter_group_size( i );
|
||||||
surf = loaded_surface_get_at_index(i);
|
for( int j = 0; j < surfCount; ++j ) {
|
||||||
|
surf = loaded_surface_iter_get_at_index( i, j );
|
||||||
|
|
||||||
// Do the check normally done in add_surface_to_cell
|
// Do the check normally done in add_surface_to_cell
|
||||||
if( surf->normal.y <= 0.01f ) continue;
|
if( surf->normal.y <= 0.01f ) continue;
|
||||||
@@ -137,7 +139,7 @@ static struct Surface *find_floor_from_list( s32 x, s32 y, s32 z, f32 *pheight)
|
|||||||
*pheight = height;
|
*pheight = height;
|
||||||
floor = surf;
|
floor = surf;
|
||||||
}
|
}
|
||||||
}
|
}}
|
||||||
return floor;
|
return floor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,10 +160,11 @@ static s32 find_wall_collisions_from_list( struct WallCollisionData *data) {
|
|||||||
radius = 200.0f;
|
radius = 200.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stay in this loop until out of walls.
|
uint32_t groupCount = loaded_surface_iter_group_count();
|
||||||
int count = loaded_surface_get_count();
|
for( int i = 0; i < groupCount; ++i ) {
|
||||||
for( int i = 0; i < count; ++i ) {
|
uint32_t surfCount = loaded_surface_iter_group_size( i );
|
||||||
surf = loaded_surface_get_at_index(i);
|
for( int j = 0; j < surfCount; ++j ) {
|
||||||
|
surf = loaded_surface_iter_get_at_index( i, j );
|
||||||
|
|
||||||
// Do the check normally done in add_surface_to_cell
|
// Do the check normally done in add_surface_to_cell
|
||||||
if( surf->normal.y < -0.01f || surf->normal.y > 0.01f ) continue;
|
if( surf->normal.y < -0.01f || surf->normal.y > 0.01f ) continue;
|
||||||
@@ -251,7 +254,7 @@ static s32 find_wall_collisions_from_list( struct WallCollisionData *data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
numCols++;
|
numCols++;
|
||||||
}
|
}}
|
||||||
|
|
||||||
return numCols;
|
return numCols;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,16 +47,13 @@ void update_mario_platform(void) {
|
|||||||
|
|
||||||
switch (awayFromFloor) {
|
switch (awayFromFloor) {
|
||||||
case 1:
|
case 1:
|
||||||
g_state->mgMarioPlatform = NULL;
|
|
||||||
gMarioObject->platform = NULL;
|
gMarioObject->platform = NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
if (floor != NULL && floor->object != NULL) {
|
if (floor != NULL && floor->transform != NULL) {
|
||||||
g_state->mgMarioPlatform = floor->object;
|
gMarioObject->platform = floor->transform;
|
||||||
gMarioObject->platform = floor->object;
|
|
||||||
} else {
|
} else {
|
||||||
g_state->mgMarioPlatform = NULL;
|
|
||||||
gMarioObject->platform = NULL;
|
gMarioObject->platform = NULL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -166,16 +163,7 @@ void apply_platform_displacement(u32 isMario, struct SurfaceObjectTransform *pla
|
|||||||
* If Mario's platform is not null, apply platform displacement.
|
* If Mario's platform is not null, apply platform displacement.
|
||||||
*/
|
*/
|
||||||
void apply_mario_platform_displacement(void) {
|
void apply_mario_platform_displacement(void) {
|
||||||
struct SurfaceObjectTransform *platform = g_state->mgMarioPlatform;
|
if (gMarioObject != NULL && gMarioObject->platform != NULL) {
|
||||||
|
apply_platform_displacement(TRUE, gMarioObject->platform);
|
||||||
if (gMarioObject != NULL && platform != NULL) {
|
|
||||||
apply_platform_displacement(TRUE, platform);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set Mario's platform to NULL.
|
|
||||||
*/
|
|
||||||
void clear_mario_platform(void) {
|
|
||||||
g_state->mgMarioPlatform = NULL;
|
|
||||||
}
|
}
|
||||||
@@ -6,6 +6,5 @@
|
|||||||
|
|
||||||
void update_mario_platform(void);
|
void update_mario_platform(void);
|
||||||
void apply_mario_platform_displacement(void);
|
void apply_mario_platform_displacement(void);
|
||||||
void clear_mario_platform(void);
|
|
||||||
|
|
||||||
#endif // PLATFORM_DISPLACEMENT_H
|
#endif // PLATFORM_DISPLACEMENT_H
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
#include "PR/ultratypes.h"
|
#include "PR/ultratypes.h"
|
||||||
|
|
||||||
|
|
||||||
// Certain functions are marked as having return values, but do not
|
// Certain functions are marked as having return values, but do not
|
||||||
// actually return a value. This causes undefined behavior, which we'd rather
|
// actually return a value. This causes undefined behavior, which we'd rather
|
||||||
// avoid on modern GCC. This only impacts -O2 and can matter for both the function
|
// avoid on modern GCC. This only impacts -O2 and can matter for both the function
|
||||||
@@ -84,13 +85,27 @@ enum SpTaskState {
|
|||||||
#define ANIM_FLAG_6 (1 << 6) // 0x40
|
#define ANIM_FLAG_6 (1 << 6) // 0x40
|
||||||
#define ANIM_FLAG_7 (1 << 7) // 0x80
|
#define ANIM_FLAG_7 (1 << 7) // 0x80
|
||||||
|
|
||||||
|
// Added by libsm64
|
||||||
|
struct SurfaceObjectTransform
|
||||||
|
{
|
||||||
|
float aPosX, aPosY, aPosZ;
|
||||||
|
float aVelX, aVelY, aVelZ;
|
||||||
|
|
||||||
|
s16 aFaceAnglePitch;
|
||||||
|
s16 aFaceAngleYaw;
|
||||||
|
s16 aFaceAngleRoll;
|
||||||
|
|
||||||
|
s16 aAngleVelPitch;
|
||||||
|
s16 aAngleVelYaw;
|
||||||
|
s16 aAngleVelRoll;
|
||||||
|
};
|
||||||
|
|
||||||
struct Animation {
|
struct Animation {
|
||||||
/*0x00*/ s16 flags;
|
/*0x00*/ s16 flags;
|
||||||
/*0x02*/ s16 animYTransDivisor;
|
/*0x02*/ s16 animYTransDivisor;
|
||||||
/*0x04*/ s16 startFrame;
|
/*0x04*/ s16 startFrame;
|
||||||
/*0x06*/ s16 loopStart;
|
/*0x06*/ s16 loopStart;
|
||||||
/*0x08*/ s16 loopEnd;
|
/*0x08*/ s16 loopEnd; /*0x0A*/ s16 unusedBoneCount;
|
||||||
/*0x0A*/ s16 unusedBoneCount;
|
|
||||||
/*0x0C*/ s16 *values;
|
/*0x0C*/ s16 *values;
|
||||||
/*0x10*/ u16 *index;
|
/*0x10*/ u16 *index;
|
||||||
/*0x14*/ u32 length; // only used with Mario animations to determine how much to load. 0 otherwise.
|
/*0x14*/ u32 length; // only used with Mario animations to determine how much to load. 0 otherwise.
|
||||||
@@ -199,7 +214,7 @@ struct Object
|
|||||||
/*0x208*/ f32 hitboxDownOffset;
|
/*0x208*/ f32 hitboxDownOffset;
|
||||||
/*0x20C*/ const BehaviorScript *behavior;
|
/*0x20C*/ const BehaviorScript *behavior;
|
||||||
/*0x210*/ u32 unused2;
|
/*0x210*/ u32 unused2;
|
||||||
/*0x214*/ struct Object *platform;
|
/*0x214*/ struct SurfaceObjectTransform *platform; // libsm64: type change from Object*
|
||||||
/*0x218*/ void *collisionData;
|
/*0x218*/ void *collisionData;
|
||||||
/*0x21C*/ Mat4 transform;
|
/*0x21C*/ Mat4 transform;
|
||||||
/*0x25C*/ void *respawnInfo;
|
/*0x25C*/ void *respawnInfo;
|
||||||
@@ -241,9 +256,10 @@ struct Surface
|
|||||||
f32 z;
|
f32 z;
|
||||||
} normal;
|
} normal;
|
||||||
/*0x28*/ f32 originOffset;
|
/*0x28*/ f32 originOffset;
|
||||||
/*0x2C*/ struct Object *object;
|
// /*0x2C*/ struct Object *object;
|
||||||
|
|
||||||
u16 terrain;
|
struct SurfaceObjectTransform *transform; // libsm64: added field
|
||||||
|
u16 terrain; // libsm64: added field
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MarioBodyState
|
struct MarioBodyState
|
||||||
@@ -346,7 +362,7 @@ struct MarioState
|
|||||||
/*0xC0*/ f32 quicksandDepth;
|
/*0xC0*/ f32 quicksandDepth;
|
||||||
/*0xC4*/ f32 unkC4;
|
/*0xC4*/ f32 unkC4;
|
||||||
|
|
||||||
u16 curTerrain;
|
u16 curTerrain; // libsm64: added field
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TYPES_H
|
#endif // TYPES_H
|
||||||
|
|||||||
+23
-21
@@ -14,7 +14,8 @@ struct LoadedSurfaceObject
|
|||||||
{
|
{
|
||||||
struct SurfaceObjectTransform transform;
|
struct SurfaceObjectTransform transform;
|
||||||
uint32_t surfaceCount;
|
uint32_t surfaceCount;
|
||||||
struct SM64Surface *surfaces;
|
struct SM64Surface *libSurfaces;
|
||||||
|
struct Surface *engineSurfaces;
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint32_t s_static_surface_count = 0;
|
static uint32_t s_static_surface_count = 0;
|
||||||
@@ -127,11 +128,11 @@ static void engine_surface_from_lib_surface( struct Surface *surface, const stru
|
|||||||
x2 = v2[0]; y2 = v2[1]; z2 = v2[2];
|
x2 = v2[0]; y2 = v2[1]; z2 = v2[2];
|
||||||
x3 = v3[0]; y3 = v3[1]; z3 = v3[2];
|
x3 = v3[0]; y3 = v3[1]; z3 = v3[2];
|
||||||
|
|
||||||
surface->object = (struct Object *)(transform);
|
surface->transform = transform;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
surface->object = NULL;
|
surface->transform = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// (v2 - v1) x (v3 - v2)
|
// (v2 - v1) x (v3 - v2)
|
||||||
@@ -201,6 +202,21 @@ static void engine_surface_from_lib_surface( struct Surface *surface, const stru
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t loaded_surface_iter_group_count( void )
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t loaded_surface_iter_group_size( uint32_t groupIndex )
|
||||||
|
{
|
||||||
|
return groupIndex == 0 ? s_static_surface_count : s_dynamic_surface_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Surface *loaded_surface_iter_get_at_index( uint32_t groupIndex, uint32_t surfaceIndex )
|
||||||
|
{
|
||||||
|
return groupIndex == 0 ? &s_static_surface_list[ surfaceIndex ] : &s_dynamic_surface_list[ surfaceIndex ];
|
||||||
|
}
|
||||||
|
|
||||||
void update_dynamic_surface_list( void )
|
void update_dynamic_surface_list( void )
|
||||||
{
|
{
|
||||||
// TODO, this is way more expensive than it needs to be.
|
// TODO, this is way more expensive than it needs to be.
|
||||||
@@ -215,25 +231,11 @@ void update_dynamic_surface_list( void )
|
|||||||
{
|
{
|
||||||
s_dynamic_surface_count++;
|
s_dynamic_surface_count++;
|
||||||
s_dynamic_surface_list = realloc( s_dynamic_surface_list, s_dynamic_surface_count * sizeof( struct Surface ));
|
s_dynamic_surface_list = realloc( s_dynamic_surface_list, s_dynamic_surface_count * sizeof( struct Surface ));
|
||||||
engine_surface_from_lib_surface( &s_dynamic_surface_list[s_dynamic_surface_count - 1], &s_surface_object_list[i].surfaces[j], &s_surface_object_list[i].transform );
|
engine_surface_from_lib_surface( &s_dynamic_surface_list[s_dynamic_surface_count - 1], &s_surface_object_list[i].libSurfaces[j], &s_surface_object_list[i].transform );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct Surface *loaded_surface_get_at_index( uint32_t index )
|
|
||||||
{
|
|
||||||
if( index < s_static_surface_count )
|
|
||||||
return &s_static_surface_list[ index ];
|
|
||||||
|
|
||||||
return &s_dynamic_surface_list[ index - s_static_surface_count ];
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t loaded_surface_get_count()
|
|
||||||
{
|
|
||||||
return s_static_surface_count + s_dynamic_surface_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
void surfaces_load_static_libsm64( const struct SM64Surface *surfaceArray, uint32_t numSurfaces )
|
void surfaces_load_static_libsm64( const struct SM64Surface *surfaceArray, uint32_t numSurfaces )
|
||||||
{
|
{
|
||||||
s_static_surface_count = numSurfaces;
|
s_static_surface_count = numSurfaces;
|
||||||
@@ -252,8 +254,8 @@ uint32_t surfaces_load_object( const struct SM64SurfaceObject *surfaceObject )
|
|||||||
struct LoadedSurfaceObject *obj = &s_surface_object_list[idx];
|
struct LoadedSurfaceObject *obj = &s_surface_object_list[idx];
|
||||||
init_transform( &obj->transform, &surfaceObject->transform );
|
init_transform( &obj->transform, &surfaceObject->transform );
|
||||||
obj->surfaceCount = surfaceObject->surfaceCount;
|
obj->surfaceCount = surfaceObject->surfaceCount;
|
||||||
obj->surfaces = malloc( obj->surfaceCount * sizeof( struct SM64Surface ));
|
obj->libSurfaces = malloc( obj->surfaceCount * sizeof( struct SM64Surface ));
|
||||||
memcpy( obj->surfaces, surfaceObject->surfaces, obj->surfaceCount * sizeof( struct SM64Surface ));
|
memcpy( obj->libSurfaces, surfaceObject->surfaces, obj->surfaceCount * sizeof( struct SM64Surface ));
|
||||||
|
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
@@ -275,7 +277,7 @@ void surfaces_unload_all( void )
|
|||||||
s_static_surface_list = NULL;
|
s_static_surface_list = NULL;
|
||||||
|
|
||||||
for( int i = 0; i < s_surface_object_count; ++i )
|
for( int i = 0; i < s_surface_object_count; ++i )
|
||||||
free( s_surface_object_list[i].surfaces );
|
free( s_surface_object_list[i].libSurfaces );
|
||||||
free( s_surface_object_list );
|
free( s_surface_object_list );
|
||||||
s_surface_object_count = 0;
|
s_surface_object_count = 0;
|
||||||
s_surface_object_list = NULL;
|
s_surface_object_list = NULL;
|
||||||
|
|||||||
+4
-17
@@ -1,24 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "decomp/include/PR/ultratypes.h"
|
#include "decomp/include/types.h"
|
||||||
#include "libsm64.h"
|
#include "libsm64.h"
|
||||||
|
|
||||||
struct SurfaceObjectTransform
|
extern uint32_t loaded_surface_iter_group_count( void );
|
||||||
{
|
extern uint32_t loaded_surface_iter_group_size( uint32_t groupIndex );
|
||||||
float aPosX, aPosY, aPosZ;
|
extern struct Surface *loaded_surface_iter_get_at_index( uint32_t groupIndex, uint32_t surfaceIndex );
|
||||||
float aVelX, aVelY, aVelZ;
|
|
||||||
|
|
||||||
s16 aFaceAnglePitch;
|
|
||||||
s16 aFaceAngleYaw;
|
|
||||||
s16 aFaceAngleRoll;
|
|
||||||
|
|
||||||
s16 aAngleVelPitch;
|
|
||||||
s16 aAngleVelYaw;
|
|
||||||
s16 aAngleVelRoll;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern struct Surface *loaded_surface_get_at_index( uint32_t index );
|
|
||||||
extern uint32_t loaded_surface_get_count();
|
|
||||||
|
|
||||||
extern void update_dynamic_surface_list( void );
|
extern void update_dynamic_surface_list( void );
|
||||||
extern void surfaces_load_static_libsm64( const struct SM64Surface *surfaceArray, uint32_t numSurfaces );
|
extern void surfaces_load_static_libsm64( const struct SM64Surface *surfaceArray, uint32_t numSurfaces );
|
||||||
|
|||||||
Reference in New Issue
Block a user