diff --git a/src/engine/surface_load.c b/src/engine/surface_load.c index 9da3b661..b1201c14 100644 --- a/src/engine/surface_load.c +++ b/src/engine/surface_load.c @@ -23,6 +23,14 @@ */ SpatialPartitionCell gStaticSurfacePartition[NUM_CELLS][NUM_CELLS]; SpatialPartitionCell gDynamicSurfacePartition[NUM_CELLS][NUM_CELLS]; +struct CellCoords { + u8 z; + u8 x; + u8 partition; +}; +struct CellCoords sCellsUsed[NUM_CELLS]; +u16 sNumCellsUsed; +u8 sClearAllCells; /** * Pools of data that can contain either surface nodes or surfaces. @@ -134,6 +142,16 @@ static void add_surface_to_cell(s32 dynamic, s32 cellX, s32 cellZ, struct Surfac if (dynamic) { list = &gDynamicSurfacePartition[cellZ][cellX][listIndex]; + if (sNumCellsUsed >= sizeof(sCellsUsed) / sizeof(struct CellCoords)) { + sClearAllCells = TRUE; + } else { + if (list->next == NULL) { + sCellsUsed[sNumCellsUsed].z = cellZ; + sCellsUsed[sNumCellsUsed].x = cellX; + sCellsUsed[sNumCellsUsed].partition = listIndex; + sNumCellsUsed++; + } + } } else { list = &gStaticSurfacePartition[cellZ][cellX][listIndex]; } @@ -478,6 +496,9 @@ void load_area_terrain(s32 index, TerrainData *data, RoomData *surfaceRooms, s16 gEnvironmentRegions = NULL; gSurfaceNodesAllocated = 0; gSurfacesAllocated = 0; + bzero(&sCellsUsed, sizeof(sCellsUsed)); + sNumCellsUsed = 0; + sClearAllCells = TRUE; clear_static_surfaces(); @@ -536,10 +557,16 @@ void clear_dynamic_surfaces(void) { if (!(gTimeStopState & TIME_STOP_ACTIVE)) { gSurfacesAllocated = gNumStaticSurfaces; gSurfaceNodesAllocated = gNumStaticSurfaceNodes; - gDynamicSurfacePoolEnd = gDynamicSurfacePool; - - clear_spatial_partition(&gDynamicSurfacePartition[0][0]); + if (sClearAllCells) { + 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; + } + } + sNumCellsUsed = 0; + sClearAllCells = FALSE; } }