From 5dfa2678c4cb341610d059b1dc04816ff841379a Mon Sep 17 00:00:00 2001 From: jaburns Date: Thu, 29 Oct 2020 16:25:10 -0600 Subject: [PATCH] Refactor to make surface iteration easier to make safer --- src/decomp/engine/surface_collision.c | 33 ++++++++++--------- src/decomp/game/platform_displacement.c | 20 +++-------- src/decomp/game/platform_displacement.h | 1 - src/decomp/include/types.h | 30 +++++++++++++---- src/load_surfaces.c | 44 +++++++++++++------------ src/load_surfaces.h | 21 +++--------- 6 files changed, 72 insertions(+), 77 deletions(-) diff --git a/src/decomp/engine/surface_collision.c b/src/decomp/engine/surface_collision.c index 94d6fc1..d788c60 100644 --- a/src/decomp/engine/surface_collision.c +++ b/src/decomp/engine/surface_collision.c @@ -13,10 +13,11 @@ static struct Surface *find_ceil_from_list( s32 x, s32 y, s32 z, f32 *pheight) { ceil = NULL; - // Stay in this loop until out of ceilings. - int count = loaded_surface_get_count(); - for( int i = 0; i < count; ++i ) { - surf = loaded_surface_get_at_index(i); + uint32_t groupCount = loaded_surface_iter_group_count(); + for( int i = 0; i < groupCount; ++i ) { + uint32_t surfCount = loaded_surface_iter_group_size( 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 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; } } - } + }} return ceil; } @@ -86,10 +87,11 @@ static struct Surface *find_floor_from_list( s32 x, s32 y, s32 z, f32 *pheight) f32 height; struct Surface *floor = NULL; - // Iterate through the list of floors until there are no more floors. - int count = loaded_surface_get_count(); - for( int i = 0; i < count; ++i ) { - surf = loaded_surface_get_at_index(i); + uint32_t groupCount = loaded_surface_iter_group_count(); + for( int i = 0; i < groupCount; ++i ) { + uint32_t surfCount = loaded_surface_iter_group_size( 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 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; floor = surf; } - } + }} return floor; } @@ -158,10 +160,11 @@ static s32 find_wall_collisions_from_list( struct WallCollisionData *data) { radius = 200.0f; } - // Stay in this loop until out of walls. - int count = loaded_surface_get_count(); - for( int i = 0; i < count; ++i ) { - surf = loaded_surface_get_at_index(i); + uint32_t groupCount = loaded_surface_iter_group_count(); + for( int i = 0; i < groupCount; ++i ) { + uint32_t surfCount = loaded_surface_iter_group_size( 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 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++; - } + }} return numCols; } diff --git a/src/decomp/game/platform_displacement.c b/src/decomp/game/platform_displacement.c index 58447e4..c154317 100644 --- a/src/decomp/game/platform_displacement.c +++ b/src/decomp/game/platform_displacement.c @@ -47,16 +47,13 @@ void update_mario_platform(void) { switch (awayFromFloor) { case 1: - g_state->mgMarioPlatform = NULL; gMarioObject->platform = NULL; break; case 0: - if (floor != NULL && floor->object != NULL) { - g_state->mgMarioPlatform = floor->object; - gMarioObject->platform = floor->object; + if (floor != NULL && floor->transform != NULL) { + gMarioObject->platform = floor->transform; } else { - g_state->mgMarioPlatform = NULL; gMarioObject->platform = NULL; } break; @@ -166,16 +163,7 @@ void apply_platform_displacement(u32 isMario, struct SurfaceObjectTransform *pla * If Mario's platform is not null, apply platform displacement. */ void apply_mario_platform_displacement(void) { - struct SurfaceObjectTransform *platform = g_state->mgMarioPlatform; - - if (gMarioObject != NULL && platform != NULL) { - apply_platform_displacement(TRUE, platform); + if (gMarioObject != NULL && gMarioObject->platform != NULL) { + apply_platform_displacement(TRUE, gMarioObject->platform); } -} - -/** - * Set Mario's platform to NULL. - */ -void clear_mario_platform(void) { - g_state->mgMarioPlatform = NULL; } \ No newline at end of file diff --git a/src/decomp/game/platform_displacement.h b/src/decomp/game/platform_displacement.h index 8a8d0fa..3eb182d 100644 --- a/src/decomp/game/platform_displacement.h +++ b/src/decomp/game/platform_displacement.h @@ -6,6 +6,5 @@ void update_mario_platform(void); void apply_mario_platform_displacement(void); -void clear_mario_platform(void); #endif // PLATFORM_DISPLACEMENT_H diff --git a/src/decomp/include/types.h b/src/decomp/include/types.h index ba742bc..07e827b 100644 --- a/src/decomp/include/types.h +++ b/src/decomp/include/types.h @@ -8,6 +8,7 @@ #include "macros.h" #include "PR/ultratypes.h" + // Certain functions are marked as having return values, but do not // 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 @@ -84,13 +85,27 @@ enum SpTaskState { #define ANIM_FLAG_6 (1 << 6) // 0x40 #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 { /*0x00*/ s16 flags; /*0x02*/ s16 animYTransDivisor; /*0x04*/ s16 startFrame; /*0x06*/ s16 loopStart; - /*0x08*/ s16 loopEnd; - /*0x0A*/ s16 unusedBoneCount; + /*0x08*/ s16 loopEnd; /*0x0A*/ s16 unusedBoneCount; /*0x0C*/ s16 *values; /*0x10*/ u16 *index; /*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; /*0x20C*/ const BehaviorScript *behavior; /*0x210*/ u32 unused2; - /*0x214*/ struct Object *platform; + /*0x214*/ struct SurfaceObjectTransform *platform; // libsm64: type change from Object* /*0x218*/ void *collisionData; /*0x21C*/ Mat4 transform; /*0x25C*/ void *respawnInfo; @@ -241,9 +256,10 @@ struct Surface f32 z; } normal; /*0x28*/ f32 originOffset; - /*0x2C*/ struct Object *object; - - u16 terrain; +// /*0x2C*/ struct Object *object; + + struct SurfaceObjectTransform *transform; // libsm64: added field + u16 terrain; // libsm64: added field }; struct MarioBodyState @@ -346,7 +362,7 @@ struct MarioState /*0xC0*/ f32 quicksandDepth; /*0xC4*/ f32 unkC4; - u16 curTerrain; + u16 curTerrain; // libsm64: added field }; #endif // TYPES_H diff --git a/src/load_surfaces.c b/src/load_surfaces.c index bbdb318..ee72c37 100644 --- a/src/load_surfaces.c +++ b/src/load_surfaces.c @@ -14,7 +14,8 @@ struct LoadedSurfaceObject { struct SurfaceObjectTransform transform; uint32_t surfaceCount; - struct SM64Surface *surfaces; + struct SM64Surface *libSurfaces; + struct Surface *engineSurfaces; }; 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]; x3 = v3[0]; y3 = v3[1]; z3 = v3[2]; - surface->object = (struct Object *)(transform); + surface->transform = transform; } else { - surface->object = NULL; + surface->transform = NULL; } // (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 ) { // 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_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 ) { 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]; init_transform( &obj->transform, &surfaceObject->transform ); obj->surfaceCount = surfaceObject->surfaceCount; - obj->surfaces = malloc( obj->surfaceCount * sizeof( struct SM64Surface )); - memcpy( obj->surfaces, surfaceObject->surfaces, obj->surfaceCount * sizeof( struct SM64Surface )); + obj->libSurfaces = malloc( obj->surfaceCount * sizeof( struct SM64Surface )); + memcpy( obj->libSurfaces, surfaceObject->surfaces, obj->surfaceCount * sizeof( struct SM64Surface )); return idx; } @@ -275,7 +277,7 @@ void surfaces_unload_all( void ) s_static_surface_list = NULL; 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 ); s_surface_object_count = 0; s_surface_object_list = NULL; diff --git a/src/load_surfaces.h b/src/load_surfaces.h index 8633d97..57fa2e6 100644 --- a/src/load_surfaces.h +++ b/src/load_surfaces.h @@ -1,24 +1,11 @@ #pragma once -#include "decomp/include/PR/ultratypes.h" +#include "decomp/include/types.h" #include "libsm64.h" -struct SurfaceObjectTransform -{ - float aPosX, aPosY, aPosZ; - 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 uint32_t loaded_surface_iter_group_count( void ); +extern uint32_t loaded_surface_iter_group_size( uint32_t groupIndex ); +extern struct Surface *loaded_surface_iter_get_at_index( uint32_t groupIndex, uint32_t surfaceIndex ); extern void update_dynamic_surface_list( void ); extern void surfaces_load_static_libsm64( const struct SM64Surface *surfaceArray, uint32_t numSurfaces );