From 545eb58102cb0f62e60056634112306809b22599 Mon Sep 17 00:00:00 2001 From: thecozies Date: Wed, 3 Mar 2021 07:02:34 -0600 Subject: [PATCH] Added extended bounds patch --- include/segments.h | 1 + src/engine/extended_bounds.h | 80 ++++++++++++++++++++++++++++++++++ src/engine/surface_collision.h | 4 +- src/engine/surface_load.c | 14 +++--- src/engine/surface_load.h | 2 + src/game/camera.c | 30 ++++++------- src/game/hud.c | 10 +++++ src/game/object_helpers.c | 2 - 8 files changed, 118 insertions(+), 25 deletions(-) create mode 100644 src/engine/extended_bounds.h diff --git a/include/segments.h b/include/segments.h index f4436675..0dbc8873 100644 --- a/include/segments.h +++ b/include/segments.h @@ -14,6 +14,7 @@ * linker script syntax. */ +#define USE_EXT_RAM #ifndef USE_EXT_RAM #define RAM_END 0x80400000 #else diff --git a/src/engine/extended_bounds.h b/src/engine/extended_bounds.h new file mode 100644 index 00000000..e80824e0 --- /dev/null +++ b/src/engine/extended_bounds.h @@ -0,0 +1,80 @@ +#ifndef __EXTENDED_BOUNDS_H__ +#define __EXTENDED_BOUNDS_H__ + +/* + Better Extended Bounds by anonymous_moose + Thanks to someone2639 for the shiftable segments patch + Thanks to Wiseguy for the Surface Pool Full error code and 4x bounds fix + + 0: Regular bounds + Same as vanilla sm64, boundaries are (-8192 to 8191) + 16x16 collision cells. + 1: 2x extended bounds + level boundaries are twice as big (-16384 to 16383) + Collision calculations remain as fast as vanilla, at the cost of using more RAM. + 32x32 collision cells. + 2: Regular bounds (performance) + Same boundaries as vanilla (-8192 to 8191), but with twice the amount of collision cells + Trades more RAM usage for faster collision calculations. + 32x32 collision cells. + 3: 4x extended bounds + level boundaries are 4 times as big (-32768 to 32767) + Collision calculations remain as fast as vanilla, at the cost of using far more RAM (16 times vanilla). + 64x64 collision cells. + + + If you see "SURFACE POOL FULL" or "SURFACE NODE POOL FULL" in game, you should increase + SURFACE_POOL_SIZE or SURFACE_NODE_POOL_SIZE, respectively, or reduce the amount of + collision surfaces in your level. +*/ + +//for the static assert macro +#include "macros.h" + +//set this to the extended bounds mode you want, then do "make clean". +#define EXTENDED_BOUNDS_MODE 1 + +//the maximum amount of collision surfaces (static and dynamic combined) +//8200 should work fine for a 2x extended stage, the vanilla value is 2300 +#define SURFACE_POOL_SIZE 4000 + +//make this approximately (amount of collision cells) + (SURFACE_POOL_SIZE * 3) +//22000 should work fine for a 2x extended stage, the vanilla value is 7000 +#define SURFACE_NODE_POOL_SIZE 12000 + + + + + +//don't touch the stuff past this point unless you know what you're doing! + +//default value to check if the user set a proper extended bounds mode +#define LEVEL_BOUNDARY_MAX 0x0000 + +#if EXTENDED_BOUNDS_MODE == 0 + #undef LEVEL_BOUNDARY_MAX // Undefine the old value to avoid compiler warnings + #define LEVEL_BOUNDARY_MAX 0x2000L + #define CELL_SIZE 0x400 +#elif EXTENDED_BOUNDS_MODE == 1 + #undef LEVEL_BOUNDARY_MAX + #define LEVEL_BOUNDARY_MAX 0x4000L + #define CELL_SIZE 0x400 +#elif EXTENDED_BOUNDS_MODE == 2 + #undef LEVEL_BOUNDARY_MAX + #define LEVEL_BOUNDARY_MAX 0x2000L + #define CELL_SIZE 0x200 +#elif EXTENDED_BOUNDS_MODE == 3 + #undef LEVEL_BOUNDARY_MAX + #define LEVEL_BOUNDARY_MAX 0x8000L + #define CELL_SIZE 0x400 +#endif + +STATIC_ASSERT(LEVEL_BOUNDARY_MAX != 0, "You must set a valid extended bounds mode!"); + +#define NUM_CELLS (2 * LEVEL_BOUNDARY_MAX / CELL_SIZE) + +#define NOT_ENOUGH_ROOM_FOR_SURFACES (1 << 0) +#define NOT_ENOUGH_ROOM_FOR_NODES (1 << 1) + + +#endif // __EXTENDED_BOUNDS_H__ diff --git a/src/engine/surface_collision.h b/src/engine/surface_collision.h index ad5e6406..3b0494f6 100644 --- a/src/engine/surface_collision.h +++ b/src/engine/surface_collision.h @@ -5,10 +5,8 @@ #include "types.h" -// Range level area is 16384x16384 (-8192 to +8192 in x and z) -#define LEVEL_BOUNDARY_MAX 0x2000 // 8192 +#include "engine/extended_bounds.h" -#define CELL_SIZE (1 << 10) // 0x400 #define CELL_HEIGHT_LIMIT 20000 #define FLOOR_LOWER_LIMIT -11000 diff --git a/src/engine/surface_load.c b/src/engine/surface_load.c index b5113901..40f3b55f 100644 --- a/src/engine/surface_load.c +++ b/src/engine/surface_load.c @@ -37,6 +37,8 @@ s16 sSurfacePoolSize; u8 unused8038EEA8[0x30]; +u8 gSurfacePoolError = 0; + /** * Allocate the part of the surface node pool to contain a surface node. */ @@ -49,7 +51,8 @@ static struct SurfaceNode *alloc_surface_node(void) { //! A bounds check! If there's more surface nodes than 7000 allowed, // we, um... // Perhaps originally just debug feedback? - if (gSurfaceNodesAllocated >= 7000) { + if (gSurfaceNodesAllocated >= SURFACE_NODE_POOL_SIZE) { + gSurfacePoolError |= NOT_ENOUGH_ROOM_FOR_NODES; } return node; @@ -68,6 +71,7 @@ static struct Surface *alloc_surface(void) { // we, um... // Perhaps originally just debug feedback? if (gSurfacesAllocated >= sSurfacePoolSize) { + gSurfacePoolError |= NOT_ENOUGH_ROOM_FOR_SURFACES; } surface->type = 0; @@ -197,7 +201,7 @@ static s16 max_3(s16 a0, s16 a1, s16 a2) { * time). This function determines the lower cell for a given x/z position. * @param coord The coordinate to test */ -static s16 lower_cell_index(s16 coord) { +static s16 lower_cell_index(s32 coord) { s16 index; // Move from range [-0x2000, 0x2000) to [0, 0x4000) @@ -229,7 +233,7 @@ static s16 lower_cell_index(s16 coord) { * time). This function determines the upper cell for a given x/z position. * @param coord The coordinate to test */ -static s16 upper_cell_index(s16 coord) { +static s16 upper_cell_index(s32 coord) { s16 index; // Move from range [-0x2000, 0x2000) to [0, 0x4000) @@ -524,8 +528,8 @@ static void load_environmental_regions(s16 **data) { * Allocate some of the main pool for surfaces (2300 surf) and for surface nodes (7000 nodes). */ void alloc_surface_pools(void) { - sSurfacePoolSize = 2300; - sSurfaceNodePool = main_pool_alloc(7000 * sizeof(struct SurfaceNode), MEMORY_POOL_LEFT); + sSurfacePoolSize = SURFACE_POOL_SIZE; + sSurfaceNodePool = main_pool_alloc(SURFACE_NODE_POOL_SIZE * sizeof(struct SurfaceNode), MEMORY_POOL_LEFT); sSurfacePool = main_pool_alloc(sSurfacePoolSize * sizeof(struct Surface), MEMORY_POOL_LEFT); gCCMEnteredSlide = 0; diff --git a/src/engine/surface_load.h b/src/engine/surface_load.h index e41a04a4..27daed26 100644 --- a/src/engine/surface_load.h +++ b/src/engine/surface_load.h @@ -6,6 +6,8 @@ #include "surface_collision.h" #include "types.h" +extern u8 gSurfacePoolError; + #define NUM_CELLS (2 * LEVEL_BOUNDARY_MAX / CELL_SIZE) #define NUM_CELLS_INDEX (NUM_CELLS - 1) diff --git a/src/game/camera.c b/src/game/camera.c index 2ae110ce..3c7649c6 100644 --- a/src/game/camera.c +++ b/src/game/camera.c @@ -874,21 +874,21 @@ void pan_ahead_of_player(struct Camera *c) { vec3f_add(c->focus, pan); } -s16 find_in_bounds_yaw_wdw_bob_thi(Vec3f pos, Vec3f origin, s16 yaw) { - switch (gCurrLevelArea) { - case AREA_WDW_MAIN: - yaw = clamp_positions_and_find_yaw(pos, origin, 4508.f, -3739.f, 4508.f, -3739.f); - break; - case AREA_BOB: - yaw = clamp_positions_and_find_yaw(pos, origin, 8000.f, -8000.f, 7050.f, -8000.f); - break; - case AREA_THI_HUGE: - yaw = clamp_positions_and_find_yaw(pos, origin, 8192.f, -8192.f, 8192.f, -8192.f); - break; - case AREA_THI_TINY: - yaw = clamp_positions_and_find_yaw(pos, origin, 2458.f, -2458.f, 2458.f, -2458.f); - break; - } +s16 find_in_bounds_yaw_wdw_bob_thi(UNUSED Vec3f pos, UNUSED Vec3f origin, s16 yaw) { + // switch (gCurrLevelArea) { + // case AREA_WDW_MAIN: + // yaw = clamp_positions_and_find_yaw(pos, origin, 4508.f, -3739.f, 4508.f, -3739.f); + // break; + // case AREA_BOB: + // yaw = clamp_positions_and_find_yaw(pos, origin, 8000.f, -8000.f, 7050.f, -8000.f); + // break; + // case AREA_THI_HUGE: + // yaw = clamp_positions_and_find_yaw(pos, origin, 8192.f, -8192.f, 8192.f, -8192.f); + // break; + // case AREA_THI_TINY: + // yaw = clamp_positions_and_find_yaw(pos, origin, 2458.f, -2458.f, 2458.f, -2458.f); + // break; + // } return yaw; } diff --git a/src/game/hud.c b/src/game/hud.c index 8d4daa54..a190af08 100644 --- a/src/game/hud.c +++ b/src/game/hud.c @@ -13,6 +13,7 @@ #include "area.h" #include "save_file.h" #include "print.h" +#include "engine/surface_load.h" /* @file hud.c * This file implements HUD rendering and power meter animations. @@ -475,5 +476,14 @@ void render_hud(void) { if (hudDisplayFlags & HUD_DISPLAY_FLAG_TIMER) { render_hud_timer(); } + + if (gSurfacePoolError & NOT_ENOUGH_ROOM_FOR_SURFACES) + { + print_text(10, 40, "SURFACE POOL FULL"); + } + if (gSurfacePoolError & NOT_ENOUGH_ROOM_FOR_NODES) + { + print_text(10, 60, "SURFACE NODE POOL FULL"); + } } } diff --git a/src/game/object_helpers.c b/src/game/object_helpers.c index 0d86000b..d0891f03 100644 --- a/src/game/object_helpers.c +++ b/src/game/object_helpers.c @@ -1840,12 +1840,10 @@ static s32 cur_obj_within_12k_bounds(void) { } void cur_obj_move_using_vel_and_gravity(void) { - if (cur_obj_within_12k_bounds()) { o->oPosX += o->oVelX; o->oPosZ += o->oVelZ; o->oVelY += o->oGravity; //! No terminal velocity o->oPosY += o->oVelY; - } } void cur_obj_move_using_fvel_and_gravity(void) {