Save up to 130KB of RAM at literally zero cost (#786)

This commit is contained in:
arthurtilly
2024-04-22 12:40:47 +12:00
committed by GitHub
parent e494069b0a
commit 0005bbbd6a
5 changed files with 58 additions and 51 deletions

View File

@@ -921,20 +921,20 @@ void find_surface_on_ray_cell(s32 cellX, s32 cellZ, Vec3f orig, Vec3f normalized
if ((cellX >= 0) && (cellX <= (NUM_CELLS - 1)) && (cellZ >= 0) && (cellZ <= (NUM_CELLS - 1))) {
// Iterate through each surface in this partition
if ((normalized_dir[1] > -NEAR_ONE) && (flags & RAYCAST_FIND_CEIL)) {
find_surface_on_ray_list( gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS ].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
find_surface_on_ray_list(gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS ].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
find_surface_on_ray_list( gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS ], orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
find_surface_on_ray_list(gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS ], orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
}
if ((normalized_dir[1] < NEAR_ONE) && (flags & RAYCAST_FIND_FLOOR)) {
find_surface_on_ray_list( gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
find_surface_on_ray_list(gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
find_surface_on_ray_list( gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS], orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
find_surface_on_ray_list(gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS], orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
}
if (flags & RAYCAST_FIND_WALL) {
find_surface_on_ray_list( gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS ].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
find_surface_on_ray_list(gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS ].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
find_surface_on_ray_list( gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS ], orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
find_surface_on_ray_list(gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS ], orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
}
if (flags & RAYCAST_FIND_WATER) {
find_surface_on_ray_list( gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WATER ].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
find_surface_on_ray_list(gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WATER ].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
find_surface_on_ray_list( gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WATER ], orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
find_surface_on_ray_list(gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WATER ], orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
}
}
}

View File

@@ -220,12 +220,12 @@ s32 find_wall_collisions(struct WallCollisionData *colData) {
for (s32 cellZ = minCellZ; cellZ <= maxCellZ; cellZ++) {
if (!(gCollisionFlags & COLLISION_FLAG_EXCLUDE_DYNAMIC)) {
// Check for surfaces belonging to objects.
node = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS].next;
node = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS];
numCollisions += find_wall_collisions_from_list(node, colData);
}
// Check for surfaces that are a part of level geometry.
node = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS].next;
node = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS];
numCollisions += find_wall_collisions_from_list(node, colData);
}
}
@@ -376,7 +376,7 @@ f32 find_ceil(f32 posX, f32 posY, f32 posZ, struct Surface **pceil) {
if (includeDynamic) {
// Check for surfaces belonging to objects.
surfaceList = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS].next;
surfaceList = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS];
dynamicCeil = find_ceil_from_list(surfaceList, x, y, z, &dynamicHeight);
// In the next check, only check for ceilings lower than the previous check.
@@ -384,7 +384,7 @@ f32 find_ceil(f32 posX, f32 posY, f32 posZ, struct Surface **pceil) {
}
// Check for surfaces that are a part of level geometry.
surfaceList = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS].next;
surfaceList = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS];
ceil = find_ceil_from_list(surfaceList, x, y, z, &height);
// Use the lower ceiling.
@@ -573,7 +573,7 @@ f32 unused_find_dynamic_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfl
s32 cellX = GET_CELL_COORD(x);
s32 cellZ = GET_CELL_COORD(z);
struct SurfaceNode *surfaceList = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next;
struct SurfaceNode *surfaceList = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS];
*pfloor = find_floor_from_list(surfaceList, x, y, z, &floorHeight);
@@ -615,7 +615,7 @@ f32 find_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor) {
if (includeDynamic) {
// Check for surfaces belonging to objects.
surfaceList = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next;
surfaceList = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS];
dynamicFloor = find_floor_from_list(surfaceList, x, y, z, &dynamicHeight);
// In the next check, only check for floors higher than the previous check.
@@ -623,7 +623,7 @@ f32 find_floor(f32 xPos, f32 yPos, f32 zPos, struct Surface **pfloor) {
}
// Check for surfaces that are a part of level geometry.
surfaceList = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next;
surfaceList = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS];
floor = find_floor_from_list(surfaceList, x, y, z, &height);
// Use the higher floor.
@@ -690,7 +690,7 @@ f32 find_water_floor(s32 xPos, s32 yPos, s32 zPos, struct Surface **pfloor) {
s32 cellZ = GET_CELL_COORD(z);
// Check for surfaces that are a part of level geometry.
struct SurfaceNode *surfaceList = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WATER].next;
struct SurfaceNode *surfaceList = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WATER];
struct Surface *floor = find_water_floor_from_list(surfaceList, x, y, z, &height);
if (floor == NULL) {
@@ -856,22 +856,22 @@ void debug_surface_list_info(f32 xPos, f32 zPos) {
s32 cellX = GET_CELL_COORD(xPos);
s32 cellZ = GET_CELL_COORD(zPos);
list = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next;
list = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS];
numFloors += surface_list_length(list);
list = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next;
list = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS];
numFloors += surface_list_length(list);
list = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS].next;
list = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS];
numWalls += surface_list_length(list);
list = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS].next;
list = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS];
numWalls += surface_list_length(list);
list = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS].next;
list = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS];
numCeils += surface_list_length(list);
list = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS].next;
list = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS];
numCeils += surface_list_length(list);
print_debug_top_down_mapinfo("area %x", cellZ * NUM_CELLS + cellX);

View File

@@ -94,10 +94,10 @@ static void clear_spatial_partition(SpatialPartitionCell *cells) {
register s32 i = sqr(NUM_CELLS);
while (i--) {
(*cells)[SPATIAL_PARTITION_FLOORS].next = NULL;
(*cells)[SPATIAL_PARTITION_CEILS].next = NULL;
(*cells)[SPATIAL_PARTITION_WALLS].next = NULL;
(*cells)[SPATIAL_PARTITION_WATER].next = NULL;
(*cells)[SPATIAL_PARTITION_FLOORS] = NULL;
(*cells)[SPATIAL_PARTITION_CEILS] = NULL;
(*cells)[SPATIAL_PARTITION_WALLS] = NULL;
(*cells)[SPATIAL_PARTITION_WATER] = NULL;
cells++;
}
@@ -119,7 +119,7 @@ static void clear_static_surfaces(void) {
* @param surface The surface to add
*/
static void add_surface_to_cell(s32 dynamic, s32 cellX, s32 cellZ, struct Surface *surface) {
struct SurfaceNode *list;
struct SurfaceNode **list;
s32 priority;
s32 sortDir = 1; // highest to lowest, then insertion order (water and floors)
s32 listIndex;
@@ -146,7 +146,7 @@ static void add_surface_to_cell(s32 dynamic, s32 cellX, s32 cellZ, struct Surfac
if (sNumCellsUsed >= sizeof(sCellsUsed) / sizeof(struct CellCoords)) {
sClearAllCells = TRUE;
} else {
if (list->next == NULL) {
if (*list == NULL) {
sCellsUsed[sNumCellsUsed].z = cellZ;
sCellsUsed[sNumCellsUsed].x = cellX;
sCellsUsed[sNumCellsUsed].partition = listIndex;
@@ -157,19 +157,26 @@ static void add_surface_to_cell(s32 dynamic, s32 cellX, s32 cellZ, struct Surfac
list = &gStaticSurfacePartition[cellZ][cellX][listIndex];
}
if (*list == NULL) {
*list = newNode;
return;
}
struct SurfaceNode *curNode = *list;
// Loop until we find the appropriate place for the surface in the list.
while (list->next != NULL) {
priority = list->next->surface->upperY * sortDir;
while (curNode->next != NULL) {
priority = curNode->next->surface->upperY * sortDir;
if (surfacePriority > priority) {
break;
}
list = list->next;
curNode = curNode->next;
}
newNode->next = list->next;
list->next = newNode;
newNode->next = curNode->next;
curNode->next = newNode;
}
/**
@@ -563,7 +570,7 @@ void clear_dynamic_surfaces(void) {
clear_spatial_partition(&gDynamicSurfacePartition[0][0]);
} else {
for (u32 i = 0; i < sNumCellsUsed; i++) {
gDynamicSurfacePartition[sCellsUsed[i].z][sCellsUsed[i].x][sCellsUsed[i].partition].next = NULL;
gDynamicSurfacePartition[sCellsUsed[i].z][sCellsUsed[i].x][sCellsUsed[i].partition] = NULL;
}
}
sNumCellsUsed = 0;

View File

@@ -29,7 +29,7 @@ enum SpatialPartitions {
NUM_SPATIAL_PARTITIONS
};
typedef struct SurfaceNode SpatialPartitionCell[NUM_SPATIAL_PARTITIONS];
typedef struct SurfaceNode *SpatialPartitionCell[NUM_SPATIAL_PARTITIONS];
extern SpatialPartitionCell gStaticSurfacePartition[NUM_CELLS][NUM_CELLS];
extern SpatialPartitionCell gDynamicSurfacePartition[NUM_CELLS][NUM_CELLS];

View File

@@ -210,14 +210,14 @@ void iterate_surfaces_visual(s32 x, s32 z, Vtx *verts) {
for (i = 0; i < (2 * NUM_SPATIAL_PARTITIONS); i++) {
switch (i) {
case 0: node = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS ].next; colorRGB_copy(col, (ColorRGB)COLOR_RGB_GREEN ); break;
case 1: node = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS ].next; colorRGB_copy(col, (ColorRGB)COLOR_RGB_GREEN ); break;
case 2: node = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next; colorRGB_copy(col, (ColorRGB)COLOR_RGB_BLUE ); break;
case 3: node = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next; colorRGB_copy(col, (ColorRGB)COLOR_RGB_BLUE ); break;
case 4: node = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS ].next; colorRGB_copy(col, (ColorRGB)COLOR_RGB_RED ); break;
case 5: node = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS ].next; colorRGB_copy(col, (ColorRGB)COLOR_RGB_RED ); break;
case 6: node = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WATER ].next; colorRGB_copy(col, (ColorRGB)COLOR_RGB_YELLOW); break;
case 7: node = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WATER ].next; colorRGB_copy(col, (ColorRGB)COLOR_RGB_YELLOW); break;
case 0: node = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS ]; colorRGB_copy(col, (ColorRGB)COLOR_RGB_GREEN ); break;
case 1: node = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS ]; colorRGB_copy(col, (ColorRGB)COLOR_RGB_GREEN ); break;
case 2: node = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS]; colorRGB_copy(col, (ColorRGB)COLOR_RGB_BLUE ); break;
case 3: node = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS]; colorRGB_copy(col, (ColorRGB)COLOR_RGB_BLUE ); break;
case 4: node = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS ]; colorRGB_copy(col, (ColorRGB)COLOR_RGB_RED ); break;
case 5: node = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS ]; colorRGB_copy(col, (ColorRGB)COLOR_RGB_RED ); break;
case 6: node = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WATER ]; colorRGB_copy(col, (ColorRGB)COLOR_RGB_YELLOW); break;
case 7: node = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WATER ]; colorRGB_copy(col, (ColorRGB)COLOR_RGB_YELLOW); break;
}
while (node != NULL) {
@@ -318,14 +318,14 @@ s32 iterate_surface_count(s32 x, s32 z) {
for (i = 0; i < (2 * NUM_SPATIAL_PARTITIONS); i++) {
switch (i) {
case 0: node = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS ].next; break;
case 1: node = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS ].next; break;
case 2: node = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next; break;
case 3: node = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next; break;
case 4: node = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS ].next; break;
case 5: node = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS ].next; break;
case 6: node = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WATER ].next; break;
case 7: node = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WATER ].next; break;
case 0: node = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS ]; break;
case 1: node = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS ]; break;
case 2: node = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS]; break;
case 3: node = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS]; break;
case 4: node = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS ]; break;
case 5: node = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS ]; break;
case 6: node = gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WATER ]; break;
case 7: node = gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WATER ]; break;
}
while (node != NULL) {