mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-25 13:35:12 +00:00
Switch all mempools to dynamic memory
This commit is contained in:
parent
4aa4386319
commit
c45e76c870
14 changed files with 17 additions and 148 deletions
|
@ -52,8 +52,6 @@ LevelScript* gLevelScriptActive = NULL;
|
|||
|
||||
static uintptr_t sStack[32];
|
||||
|
||||
struct DynamicPool *gLevelPool = NULL;
|
||||
|
||||
static u16 sDelayFrames = 0;
|
||||
static u16 sDelayFrames2 = 0;
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ void bhv_chain_chomp_chain_part_update(void) {
|
|||
* When mario gets close enough, allocate chain segments and spawn their objects.
|
||||
*/
|
||||
static void chain_chomp_act_uninitialized(void) {
|
||||
struct ChainSegment *segments = mem_pool_alloc(gObjectMemoryPool, 5 * sizeof(struct ChainSegment));
|
||||
struct ChainSegment *segments = dynamic_pool_alloc(gLevelPool, 5 * sizeof(struct ChainSegment));
|
||||
if (segments != NULL) {
|
||||
// Each segment represents the offset of a chain part to the pivot.
|
||||
// Segment 0 connects the pivot to the chain chomp itself. Segment
|
||||
|
@ -450,7 +450,7 @@ static void chain_chomp_act_move(void) {
|
|||
*/
|
||||
static void chain_chomp_act_unload_chain(void) {
|
||||
cur_obj_hide();
|
||||
mem_pool_free(gObjectMemoryPool, o->oChainChompSegments);
|
||||
dynamic_pool_free(gLevelPool, o->oChainChompSegments);
|
||||
|
||||
o->oAction = CHAIN_CHOMP_ACT_UNINITIALIZED;
|
||||
|
||||
|
|
|
@ -126,7 +126,7 @@ void bhv_wiggler_body_part_update(void) {
|
|||
* Initialize the segment data and spawn the body part objects.
|
||||
*/
|
||||
void wiggler_init_segments(void) {
|
||||
struct ChainSegment *segments = mem_pool_alloc(gObjectMemoryPool, 4 * sizeof(struct ChainSegment));
|
||||
struct ChainSegment *segments = dynamic_pool_alloc(gLevelPool, 4 * sizeof(struct ChainSegment));
|
||||
|
||||
// Each segment represents the global position and orientation of each
|
||||
// object. Segment 0 represents the wiggler's head, and segment i>0
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include "game/rendering_graph_node.h"
|
||||
#include "pc/utils/misc.h"
|
||||
#include "game/hardcoded.h"
|
||||
#include "engine/level_script.h"
|
||||
|
||||
/**
|
||||
* This file implements environment effects that are not snow:
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include "engine/surface_collision.h"
|
||||
#include "engine/math_util.h"
|
||||
#include "engine/behavior_script.h"
|
||||
#include "engine/level_script.h"
|
||||
#include "audio/external.h"
|
||||
#include "obj_behaviors.h"
|
||||
#include "pc/utils/misc.h"
|
||||
|
|
|
@ -147,7 +147,6 @@ void alloc_pool(void) {
|
|||
void *end = (void *) (SEG_POOL_START + POOL_SIZE);
|
||||
|
||||
main_pool_init(start, end);
|
||||
gEffectsMemoryPool = mem_pool_init(0x4000, MEMORY_POOL_LEFT);
|
||||
}
|
||||
|
||||
void create_thread(OSThread *thread, OSId id, void (*entry)(void *), void *arg, void *sp, OSPri pri) {
|
||||
|
|
|
@ -49,13 +49,6 @@ extern u8 *sPoolEnd;
|
|||
extern struct MainPoolBlock *sPoolListHeadL;
|
||||
extern struct MainPoolBlock *sPoolListHeadR;
|
||||
|
||||
|
||||
/**
|
||||
* Memory pool for small graphical effects that aren't connected to Objects.
|
||||
* Used for colored text, paintings, and environmental snow and bubbles.
|
||||
*/
|
||||
struct MemoryPool *gEffectsMemoryPool = NULL;
|
||||
|
||||
uintptr_t sSegmentTable[32];
|
||||
u32 sPoolFreeSpace;
|
||||
u8 *sPoolStart;
|
||||
|
@ -249,108 +242,6 @@ static void *dynamic_dma_read(u8 *srcStart, u8 *srcEnd, u32 side) {
|
|||
return dest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate a memory pool from the main pool. This pool supports arbitrary
|
||||
* order for allocation/freeing.
|
||||
* Return NULL if there is not enough space in the main pool.
|
||||
*/
|
||||
struct MemoryPool *mem_pool_init(u32 size, u32 side) {
|
||||
void *addr;
|
||||
struct MemoryBlock *block;
|
||||
struct MemoryPool *pool = NULL;
|
||||
|
||||
size = ALIGN4(size);
|
||||
addr = main_pool_alloc(size + sizeof(struct MemoryPool), side);
|
||||
if (addr != NULL) {
|
||||
pool = (struct MemoryPool *) addr;
|
||||
|
||||
pool->totalSpace = size;
|
||||
pool->firstBlock = (struct MemoryBlock *) ((u8 *) addr + sizeof(struct MemoryPool));
|
||||
pool->freeList.next = (struct MemoryBlock *) ((u8 *) addr + sizeof(struct MemoryPool));
|
||||
|
||||
block = pool->firstBlock;
|
||||
block->next = NULL;
|
||||
block->size = pool->totalSpace;
|
||||
}
|
||||
if (addr == NULL) {
|
||||
LOG_ERROR("Memory pool failed to initalize memory of size 0x%X on side %d.", size, side);
|
||||
}
|
||||
return pool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate from a memory pool. Return NULL if there is not enough space.
|
||||
*/
|
||||
void *mem_pool_alloc(struct MemoryPool *pool, u32 size) {
|
||||
struct MemoryBlock *freeBlock = &pool->freeList;
|
||||
void *addr = NULL;
|
||||
|
||||
size = ALIGN4(size) + sizeof(struct MemoryBlock);
|
||||
while (freeBlock->next != NULL) {
|
||||
if (freeBlock->next->size >= size) {
|
||||
addr = (u8 *) freeBlock->next + sizeof(struct MemoryBlock);
|
||||
if (freeBlock->next->size - size <= sizeof(struct MemoryBlock)) {
|
||||
freeBlock->next = freeBlock->next->next;
|
||||
} else {
|
||||
struct MemoryBlock *newBlock = (struct MemoryBlock *) ((u8 *) freeBlock->next + size);
|
||||
newBlock->size = freeBlock->next->size - size;
|
||||
newBlock->next = freeBlock->next->next;
|
||||
freeBlock->next->size = size;
|
||||
freeBlock->next = newBlock;
|
||||
}
|
||||
break;
|
||||
}
|
||||
freeBlock = freeBlock->next;
|
||||
}
|
||||
if (addr == NULL) {
|
||||
LOG_ERROR("Memory pool failed to allocate memory of size 0x%X on at pool %p.", size, pool);
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free a block that was allocated using mem_pool_alloc.
|
||||
*/
|
||||
void mem_pool_free(struct MemoryPool *pool, void *addr) {
|
||||
if (!addr) { return; }
|
||||
struct MemoryBlock *block = (struct MemoryBlock *) ((u8 *) addr - sizeof(struct MemoryBlock));
|
||||
struct MemoryBlock *freeList = pool->freeList.next;
|
||||
|
||||
if (pool->freeList.next == NULL) {
|
||||
pool->freeList.next = block;
|
||||
block->next = NULL;
|
||||
} else {
|
||||
if (block < pool->freeList.next) {
|
||||
if ((u8 *) pool->freeList.next == (u8 *) block + block->size) {
|
||||
block->size += freeList->size;
|
||||
block->next = freeList->next;
|
||||
pool->freeList.next = block;
|
||||
} else {
|
||||
block->next = pool->freeList.next;
|
||||
pool->freeList.next = block;
|
||||
}
|
||||
} else {
|
||||
while (freeList->next != NULL) {
|
||||
if (freeList < block && block < freeList->next) {
|
||||
break;
|
||||
}
|
||||
freeList = freeList->next;
|
||||
}
|
||||
if ((u8 *) freeList + freeList->size == (u8 *) block) {
|
||||
freeList->size += block->size;
|
||||
block = freeList;
|
||||
} else {
|
||||
block->next = freeList->next;
|
||||
freeList->next = block;
|
||||
}
|
||||
if (block->next != NULL && (u8 *) block->next == (u8 *) block + block->size) {
|
||||
block->size = block->size + block->next->size;
|
||||
block->next = block->next->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static struct MarioAnimDmaRelatedThing *func_802789F0(u8 *srcAddr) {
|
||||
struct MarioAnimDmaRelatedThing *sp1C = dynamic_dma_read(srcAddr, srcAddr + sizeof(u32),
|
||||
MEMORY_POOL_LEFT);
|
||||
|
|
|
@ -41,12 +41,7 @@ struct MemoryPool;
|
|||
struct MarioAnimation;
|
||||
struct Animation;
|
||||
|
||||
#ifndef INCLUDED_FROM_MEMORY_C
|
||||
// Declaring this variable extern puts it in the wrong place in the bss order
|
||||
// when this file is included from memory.c (first instead of last). Hence,
|
||||
// ifdef hack. It was very likely subject to bss reordering originally.
|
||||
extern struct MemoryPool *gEffectsMemoryPool;
|
||||
#endif
|
||||
extern struct DynamicPool *gLevelPool;
|
||||
|
||||
uintptr_t set_segment_base_addr(s32 segment, void *addr);
|
||||
void *get_segment_base_addr(s32 segment);
|
||||
|
@ -77,10 +72,6 @@ struct GrowingPool* growing_pool_init(struct GrowingPool* pool, u32 nodeSize);
|
|||
void* growing_pool_alloc(struct GrowingPool *pool, u32 size);
|
||||
void growing_pool_free_pool(struct GrowingPool *pool);
|
||||
|
||||
struct MemoryPool *mem_pool_init(u32 size, u32 side);
|
||||
void *mem_pool_alloc(struct MemoryPool *pool, u32 size);
|
||||
void mem_pool_free(struct MemoryPool *pool, void *addr);
|
||||
|
||||
void alloc_display_list_reset(void);
|
||||
void *alloc_display_list(u32 size);
|
||||
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
#include <PR/ultratypes.h>
|
||||
#include "memory.h"
|
||||
#include "rendering_graph_node.h"
|
||||
#include "pc/debuglog.h"
|
||||
|
||||
#define ALIGN16(val) (((val) + 0xF) & ~0xF)
|
||||
|
||||
struct DynamicPool *gLevelPool = NULL;
|
||||
|
||||
//////////////////
|
||||
// dynamic pool //
|
||||
//////////////////
|
||||
|
@ -44,10 +47,12 @@ void dynamic_pool_free(struct DynamicPool *pool, void* ptr) {
|
|||
}
|
||||
free(node->ptr);
|
||||
free(node);
|
||||
return;
|
||||
}
|
||||
next = node;
|
||||
node = prev;
|
||||
}
|
||||
LOG_ERROR("Failed to find memory to free in dynamic pool: %p", ptr);
|
||||
}
|
||||
|
||||
void dynamic_pool_free_pool(struct DynamicPool *pool) {
|
||||
|
|
|
@ -142,11 +142,6 @@ s32 gNumStaticSurfaceNodes;
|
|||
*/
|
||||
s32 gNumStaticSurfaces;
|
||||
|
||||
/**
|
||||
* A pool used by chain chomp and wiggler to allocate their body parts.
|
||||
*/
|
||||
struct MemoryPool *gObjectMemoryPool;
|
||||
|
||||
struct Object* gCheckingSurfaceCollisionsForObject = NULL;
|
||||
s16 gCheckingSurfaceCollisionsForCamera;
|
||||
s16 gFindFloorIncludeSurfaceIntangible;
|
||||
|
@ -658,7 +653,6 @@ void clear_objects(void) {
|
|||
geo_reset_object_node(&gObjectPool[i].header.gfx);
|
||||
}
|
||||
|
||||
gObjectMemoryPool = mem_pool_init(0x800, MEMORY_POOL_LEFT);
|
||||
gObjectLists = gObjectListArray;
|
||||
|
||||
clear_dynamic_surfaces();
|
||||
|
|
|
@ -96,8 +96,6 @@ extern s32 gSurfacesAllocated;
|
|||
extern s32 gNumStaticSurfaceNodes;
|
||||
extern s32 gNumStaticSurfaces;
|
||||
|
||||
extern struct MemoryPool *gObjectMemoryPool;
|
||||
|
||||
extern struct Object* gCheckingSurfaceCollisionsForObject;
|
||||
extern s16 gCheckingSurfaceCollisionsForCamera;
|
||||
extern s16 gFindFloorIncludeSurfaceIntangible;
|
||||
|
|
|
@ -1133,7 +1133,7 @@ s16 ripple_if_movable(struct Painting *painting, s16 movable, s16 posX, s16 posY
|
|||
void painting_generate_mesh(struct Painting *painting, s16 *mesh, s16 numTris) {
|
||||
s16 i;
|
||||
|
||||
gPaintingMesh = mem_pool_alloc(gEffectsMemoryPool, numTris * sizeof(struct PaintingMeshVertex));
|
||||
gPaintingMesh = dynamic_pool_alloc(gLevelPool, numTris * sizeof(struct PaintingMeshVertex));
|
||||
painting->ripples.paintingMesh = gPaintingMesh;
|
||||
if (painting->ripples.paintingMesh == NULL) {
|
||||
return;
|
||||
|
@ -1168,7 +1168,7 @@ void painting_generate_mesh(struct Painting *painting, s16 *mesh, s16 numTris) {
|
|||
void painting_calculate_triangle_normals(struct Painting *painting, s16 *mesh, s16 numVtx, s16 numTris) {
|
||||
s16 i;
|
||||
|
||||
gPaintingTriNorms = mem_pool_alloc(gEffectsMemoryPool, numTris * sizeof(Vec3f));
|
||||
gPaintingTriNorms = dynamic_pool_alloc(gLevelPool, numTris * sizeof(Vec3f));
|
||||
painting->ripples.paintingTriNorms = gPaintingTriNorms;
|
||||
if (painting->ripples.paintingTriNorms == NULL) {
|
||||
return;
|
||||
|
@ -1526,8 +1526,8 @@ Gfx *display_painting_rippling(struct Painting *painting) {
|
|||
}
|
||||
|
||||
// The mesh data is freed every frame.
|
||||
mem_pool_free(gEffectsMemoryPool, painting->ripples.paintingMesh);
|
||||
mem_pool_free(gEffectsMemoryPool, painting->ripples.paintingTriNorms);
|
||||
dynamic_pool_free(gLevelPool, painting->ripples.paintingMesh);
|
||||
dynamic_pool_free(gLevelPool, painting->ripples.paintingTriNorms);
|
||||
return dlist;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "memory.h"
|
||||
#include "print.h"
|
||||
#include "segment2.h"
|
||||
#include "game/rendering_graph_node.h"
|
||||
|
||||
/**
|
||||
* This file handles printing and formatting the colorful text that
|
||||
|
@ -177,8 +178,7 @@ void print_text_fmt_int(s32 x, s32 y, const char *str, s32 n) {
|
|||
s32 srcIndex = 0;
|
||||
|
||||
// Don't continue if there is no memory to do so.
|
||||
if ((sTextLabels[sTextLabelsCount] = mem_pool_alloc(gEffectsMemoryPool,
|
||||
sizeof(struct TextLabel))) == NULL) {
|
||||
if ((sTextLabels[sTextLabelsCount] = growing_pool_alloc(gDisplayListHeap, sizeof(struct TextLabel))) == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -228,8 +228,7 @@ void print_text(s32 x, s32 y, const char *str) {
|
|||
s32 srcIndex = 0;
|
||||
|
||||
// Don't continue if there is no memory to do so.
|
||||
if ((sTextLabels[sTextLabelsCount] = mem_pool_alloc(gEffectsMemoryPool,
|
||||
sizeof(struct TextLabel))) == NULL) {
|
||||
if ((sTextLabels[sTextLabelsCount] = growing_pool_alloc(gDisplayListHeap, sizeof(struct TextLabel))) == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -261,8 +260,7 @@ void print_text_centered(s32 x, s32 y, const char *str) {
|
|||
s32 srcIndex = 0;
|
||||
|
||||
// Don't continue if there is no memory to do so.
|
||||
if ((sTextLabels[sTextLabelsCount] = mem_pool_alloc(gEffectsMemoryPool,
|
||||
sizeof(struct TextLabel))) == NULL) {
|
||||
if ((sTextLabels[sTextLabelsCount] = growing_pool_alloc(gDisplayListHeap, sizeof(struct TextLabel))) == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -425,8 +423,6 @@ void render_text_labels(void) {
|
|||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
mem_pool_free(gEffectsMemoryPool, sTextLabels[i]);
|
||||
}
|
||||
|
||||
gSPDisplayList(gDisplayListHead++, dl_hud_img_end);
|
||||
|
|
|
@ -322,7 +322,6 @@ void main_func(void) {
|
|||
u64 *pool = calloc(poolsize, 1);
|
||||
if (!pool) sys_fatal("Could not alloc %u bytes for main pool.\n", poolsize);
|
||||
main_pool_init(pool, pool + poolsize / sizeof(pool[0]));
|
||||
gEffectsMemoryPool = mem_pool_init(0x4000, MEMORY_POOL_LEFT);
|
||||
|
||||
#if defined(WAPI_SDL1) || defined(WAPI_SDL2)
|
||||
wm_api = &gfx_sdl;
|
||||
|
|
Loading…
Reference in a new issue