You've already forked Microtransactions64
mirror of
https://github.com/Print-and-Panic/Microtransactions64.git
synced 2026-01-21 10:17:19 -08:00
Automatically calculate SURFACE_POOL_SIZE and SURFACE_NODE_POOL_SIZE
This commit is contained in:
@@ -22,59 +22,49 @@
|
||||
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
|
||||
// For the static assert macro
|
||||
#include "macros.h"
|
||||
|
||||
//set this to the extended bounds mode you want, then do "make clean".
|
||||
// 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
|
||||
// Don't touch the stuff past this point unless you know what you're doing!
|
||||
|
||||
//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
|
||||
#if EXTENDED_BOUNDS_MODE == 0 // 1x, normal cell size
|
||||
#define LEVEL_BOUNDARY_MAX 0x2000L // 8192
|
||||
#define CELL_SIZE 0x400 // 1024, NUM_CELLS = 16
|
||||
#elif EXTENDED_BOUNDS_MODE == 1 // 2x, normal cell size
|
||||
#define LEVEL_BOUNDARY_MAX 0x4000L // 16384
|
||||
#define CELL_SIZE 0x400 // 1024, NUM_CELLS = 32
|
||||
#elif EXTENDED_BOUNDS_MODE == 2 // 1x, smaller cell size
|
||||
#define LEVEL_BOUNDARY_MAX 0x2000L // 8192
|
||||
#define CELL_SIZE 0x200 // 512, NUM_CELLS = 32
|
||||
#elif EXTENDED_BOUNDS_MODE == 3 // 4x, normal cell size
|
||||
#define LEVEL_BOUNDARY_MAX 0x8000L // 32768
|
||||
#define CELL_SIZE 0x400 // 1024, NUM_CELLS = 64
|
||||
#endif
|
||||
|
||||
STATIC_ASSERT(LEVEL_BOUNDARY_MAX != 0, "You must set a valid extended bounds mode!");
|
||||
STATIC_ASSERT((EXTENDED_BOUNDS_MODE >= 0 && EXTENDED_BOUNDS_MODE <= 3), "You must set a valid extended bounds mode!");
|
||||
|
||||
#define NUM_CELLS (2 * LEVEL_BOUNDARY_MAX / CELL_SIZE)
|
||||
// The amount of cells in each axis in an area.
|
||||
#define NUM_CELLS (2 * LEVEL_BOUNDARY_MAX / CELL_SIZE)
|
||||
// The maximum amount of collision surfaces (static and dynamic combined)
|
||||
#define SURFACE_POOL_SIZE (LEVEL_BOUNDARY_MAX / 2) // Vanilla: 2300. Modes: 0: 4096, 1: 8192, 2: 8192, 3: 16384
|
||||
// How many SurfaceNodes can fit in Surface. This is done so that the maximum sizes for both can contain the same amount.
|
||||
#define SURFACE_NODE_STRUCT_DIFF 3.5 // = (56 / 16) = (sizeof(struct Surface) / sizeof(struct SurfaceNode))
|
||||
// The maximum amount of SurfaceNodes (static and dynamic combined)
|
||||
#define SURFACE_NODE_POOL_SIZE (s32)(SURFACE_POOL_SIZE * SURFACE_NODE_STRUCT_DIFF) // Vanilla: 7000. Modes: 0: 14336, 1: 28672, 2: 28672, 3: 57344
|
||||
|
||||
// Flags for error messages
|
||||
#define NOT_ENOUGH_ROOM_FOR_SURFACES (1 << 0)
|
||||
#define NOT_ENOUGH_ROOM_FOR_NODES (1 << 1)
|
||||
|
||||
// Use this to convert game units to cell coordinates
|
||||
#define GET_CELL_COORD(p) ((((p) + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & (NUM_CELLS - 1));
|
||||
|
||||
#endif // __EXTENDED_BOUNDS_H__
|
||||
|
||||
@@ -158,10 +158,9 @@ s32 find_wall_collisions(struct WallCollisionData *colData) {
|
||||
return numCollisions;
|
||||
}
|
||||
|
||||
// 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) & NUM_CELLS_INDEX;
|
||||
cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & NUM_CELLS_INDEX;
|
||||
// World (level) consists of a 16x16 grid. Find where the collision is on the grid (round toward -inf)
|
||||
cellX = GET_CELL_COORD(x);
|
||||
cellZ = GET_CELL_COORD(z);
|
||||
|
||||
// Check for surfaces belonging to objects.
|
||||
node = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS].next;
|
||||
@@ -285,8 +284,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) & NUM_CELLS_INDEX;
|
||||
cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & NUM_CELLS_INDEX;
|
||||
cellX = GET_CELL_COORD(x);
|
||||
cellZ = GET_CELL_COORD(z);
|
||||
|
||||
// Check for surfaces belonging to objects.
|
||||
surfaceList = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS].next;
|
||||
@@ -458,8 +457,8 @@ f32 unused_find_dynamic_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfl
|
||||
s32 z = zPos;
|
||||
|
||||
// Each level is split into cells to limit load, find the appropriate cell.
|
||||
s32 cellX = ((x + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & NUM_CELLS_INDEX;
|
||||
s32 cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & NUM_CELLS_INDEX;
|
||||
s32 cellX = GET_CELL_COORD(x);
|
||||
s32 cellZ = GET_CELL_COORD(z);
|
||||
|
||||
surfaceList = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next;
|
||||
floor = find_floor_from_list(surfaceList, x, y, z, &floorHeight);
|
||||
@@ -500,8 +499,8 @@ f32 find_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor) {
|
||||
return height;
|
||||
}
|
||||
// Each level is split into cells to limit load, find the appropriate cell.
|
||||
cellX = ((x + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & NUM_CELLS_INDEX;
|
||||
cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & NUM_CELLS_INDEX;
|
||||
cellX = GET_CELL_COORD(x);
|
||||
cellZ = GET_CELL_COORD(z);
|
||||
// Check for surfaces that are a part of level geometry.
|
||||
surfaceList = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next;
|
||||
floor = find_floor_from_list(surfaceList, x, y, z, &height);
|
||||
@@ -556,8 +555,8 @@ f32 find_water_floor(s32 xPos, s32 yPos, s32 zPos, struct Surface **pfloor) {
|
||||
if (is_outside_level_bounds(x, z)) return height;
|
||||
|
||||
// Each level is split into cells to limit load, find the appropriate cell.
|
||||
cellX = ((x + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & NUM_CELLS_INDEX;
|
||||
cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & NUM_CELLS_INDEX;
|
||||
cellX = GET_CELL_COORD(x);
|
||||
cellZ = GET_CELL_COORD(z);
|
||||
|
||||
// Check for surfaces that are a part of level geometry.
|
||||
surfaceList = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WATER].next;
|
||||
@@ -741,26 +740,28 @@ void debug_surface_list_info(f32 xPos, f32 zPos) {
|
||||
s32 numFloors = 0;
|
||||
s32 numWalls = 0;
|
||||
s32 numCeils = 0;
|
||||
s32 x = xPos;
|
||||
s32 z = zPos;
|
||||
|
||||
s32 cellX = (xPos + LEVEL_BOUNDARY_MAX) / CELL_SIZE;
|
||||
s32 cellZ = (zPos + LEVEL_BOUNDARY_MAX) / CELL_SIZE;
|
||||
s32 cellX = GET_CELL_COORD(x);
|
||||
s32 cellZ = GET_CELL_COORD(z);
|
||||
|
||||
list = gStaticSurfacePartition[cellZ & NUM_CELLS_INDEX][cellX & NUM_CELLS_INDEX][SPATIAL_PARTITION_FLOORS].next;
|
||||
list = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next;
|
||||
numFloors += surface_list_length(list);
|
||||
|
||||
list = gDynamicSurfacePartition[cellZ & NUM_CELLS_INDEX][cellX & NUM_CELLS_INDEX][SPATIAL_PARTITION_FLOORS].next;
|
||||
list = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next;
|
||||
numFloors += surface_list_length(list);
|
||||
|
||||
list = gStaticSurfacePartition[cellZ & NUM_CELLS_INDEX][cellX & NUM_CELLS_INDEX][SPATIAL_PARTITION_WALLS].next;
|
||||
list = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS].next;
|
||||
numWalls += surface_list_length(list);
|
||||
|
||||
list = gDynamicSurfacePartition[cellZ & NUM_CELLS_INDEX][cellX & NUM_CELLS_INDEX][SPATIAL_PARTITION_WALLS].next;
|
||||
list = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS].next;
|
||||
numWalls += surface_list_length(list);
|
||||
|
||||
list = gStaticSurfacePartition[cellZ & NUM_CELLS_INDEX][cellX & NUM_CELLS_INDEX][SPATIAL_PARTITION_CEILS].next;
|
||||
list = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS].next;
|
||||
numCeils += surface_list_length(list);
|
||||
|
||||
list = gDynamicSurfacePartition[cellZ & NUM_CELLS_INDEX][cellX & NUM_CELLS_INDEX][SPATIAL_PARTITION_CEILS].next;
|
||||
list = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS].next;
|
||||
numCeils += surface_list_length(list);
|
||||
|
||||
print_debug_top_down_mapinfo("area %x", cellZ * NUM_CELLS + cellX);
|
||||
|
||||
@@ -153,7 +153,7 @@ static void add_surface_to_cell(s32 dynamic, s32 cellX, s32 cellZ, struct Surfac
|
||||
}
|
||||
|
||||
/**
|
||||
* Every level is split into 16 * 16 cells of surfaces (to limit computing
|
||||
* Every level is split into CELL_SIZE * CELL_SIZE cells of surfaces (to limit computing
|
||||
* time). This function determines the lower cell for a given x/z position.
|
||||
* @param coord The coordinate to test
|
||||
*/
|
||||
@@ -185,7 +185,7 @@ static s32 lower_cell_index(s32 coord) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Every level is split into 16 * 16 cells of surfaces (to limit computing
|
||||
* Every level is split into CELL_SIZE * CELL_SIZE cells of surfaces (to limit computing
|
||||
* time). This function determines the upper cell for a given x/z position.
|
||||
* @param coord The coordinate to test
|
||||
*/
|
||||
@@ -208,8 +208,8 @@ static s32 upper_cell_index(s32 coord) {
|
||||
index++;
|
||||
}
|
||||
|
||||
if (index > NUM_CELLS_INDEX) {
|
||||
index = NUM_CELLS_INDEX;
|
||||
if (index > (NUM_CELLS - 1)) {
|
||||
index = (NUM_CELLS - 1);
|
||||
}
|
||||
|
||||
// Potentially < 0, but since lower index is >= 0, not exploitable
|
||||
@@ -430,11 +430,10 @@ static TerrainData *read_vertex_data(TerrainData **data) {
|
||||
* Loads in special environmental regions, such as water, poison gas, and JRB fog.
|
||||
*/
|
||||
static void load_environmental_regions(TerrainData **data) {
|
||||
s32 numRegions;
|
||||
s32 i;
|
||||
|
||||
gEnvironmentRegions = *data;
|
||||
numRegions = *(*data)++;
|
||||
s32 numRegions = *(*data)++;
|
||||
|
||||
for (i = 0; i < numRegions; i++) {
|
||||
*data += 5;
|
||||
@@ -518,9 +517,9 @@ u32 get_area_terrain_size(TerrainData *data) {
|
||||
void load_area_terrain(s32 index, TerrainData *data, RoomData *surfaceRooms, s16 *macroObjects) {
|
||||
s32 terrainLoadType;
|
||||
TerrainData *vertexData = NULL;
|
||||
#if PUPPYPRINT_DEBUG
|
||||
#if PUPPYPRINT_DEBUG
|
||||
OSTime first = osGetTime();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Initialize the data for this.
|
||||
gEnvironmentRegions = NULL;
|
||||
@@ -568,9 +567,9 @@ void load_area_terrain(s32 index, TerrainData *data, RoomData *surfaceRooms, s16
|
||||
|
||||
gNumStaticSurfaceNodes = gSurfaceNodesAllocated;
|
||||
gNumStaticSurfaces = gSurfacesAllocated;
|
||||
#if PUPPYPRINT_DEBUG
|
||||
collisionTime[perfIteration] += osGetTime()-first;
|
||||
#endif
|
||||
#if PUPPYPRINT_DEBUG
|
||||
collisionTime[perfIteration] += osGetTime() - first;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
|
||||
extern u8 gSurfacePoolError;
|
||||
|
||||
#define NUM_CELLS_INDEX (NUM_CELLS - 1)
|
||||
|
||||
struct SurfaceNode
|
||||
{
|
||||
struct SurfaceNode *next;
|
||||
|
||||
@@ -221,8 +221,8 @@ void iterate_surfaces_visual(s32 x, s32 z, Vtx *verts) {
|
||||
return;
|
||||
}
|
||||
|
||||
cellX = ((x + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & NUM_CELLS_INDEX;
|
||||
cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & NUM_CELLS_INDEX;
|
||||
s32 cellX = GET_CELL_COORD(x);
|
||||
s32 cellZ = GET_CELL_COORD(z);
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
switch (i) {
|
||||
@@ -350,8 +350,8 @@ s32 iterate_surface_count(s32 x, s32 z)
|
||||
return 0;
|
||||
}
|
||||
|
||||
cellX = ((x + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & NUM_CELLS_INDEX;
|
||||
cellZ = ((z + LEVEL_BOUNDARY_MAX) / CELL_SIZE) & NUM_CELLS_INDEX;
|
||||
cellX = GET_CELL_COORD(x);
|
||||
cellZ = GET_CELL_COORD(z);
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user