Moved to system malloc removed model id limit

This commit is contained in:
KiritoDv 2021-05-31 18:27:07 +00:00
parent fc3890c688
commit f02de40a1d
34 changed files with 413 additions and 892 deletions

View File

@ -293,6 +293,9 @@ SRC_DIRS += src/moon/mod-engine/hooks
# Moon64 SRC [Mod-Engine - Shaders Module]
SRC_DIRS += src/moon/mod-engine/shaders
# Moon64 SRC [Mod-Engine - Models Module]
SRC_DIRS += src/moon/mod-engine/models
# Moon64 SRC [Achievements]
SRC_DIRS += src/moon/achievements

View File

@ -161,8 +161,9 @@
CMD_BBH(0x20, 0x04, 0x0000)
#define LOAD_MODEL_FROM_DL(model, dl, layer) \
CMD_BBH(0x21, 0x08, ((layer << 12) | model)), \
CMD_PTR(dl)
CMD_BBH(0x21, 0x0C, 0), \
CMD_PTR(dl), \
CMD_HH(layer, model)
#define LOAD_MODEL_FROM_GEO(model, geo) \
CMD_BBH(0x22, 0x08, model), \
@ -175,18 +176,20 @@
CMD_W(unk8)
#define OBJECT_WITH_ACTS(model, posX, posY, posZ, angleX, angleY, angleZ, behParam, beh, acts) \
CMD_BBBB(0x24, 0x18, acts, model), \
CMD_BBBB(0x24, 0x1C, acts, 0x00), \
CMD_HHHHHH(posX, posY, posZ, angleX, angleY, angleZ), \
CMD_W(behParam), \
CMD_PTR(beh)
CMD_PTR(beh), \
CMD_HH(0, model)
#define OBJECT(model, posX, posY, posZ, angleX, angleY, angleZ, behParam, beh) \
OBJECT_WITH_ACTS(model, posX, posY, posZ, angleX, angleY, angleZ, behParam, beh, 0x1F)
#define MARIO(unk3, behArg, beh) \
CMD_BBBB(0x25, 0x0C, 0x00, unk3), \
#define MARIO(model, behArg, beh) \
CMD_BBH(0x25, 0x10, 0), \
CMD_W(behArg), \
CMD_PTR(beh)
CMD_PTR(beh), \
CMD_HH(0, model)
#define WARP_NODE(id, destLevel, destArea, destNode, flags) \
CMD_BBBB(0x26, 0x08, id, destLevel), \
@ -277,7 +280,7 @@
#define ADV_DEMO() \
CMD_BBH(0x3D, 0x04, 0x0000)
#define CLEAR_DEMO_PTR() \
CMD_BBH(0x3E, 0x04, 0x0000)

View File

@ -13,6 +13,7 @@
#include "game/object_list_processor.h"
#include "graph_node.h"
#include "surface_collision.h"
#include "moon/mod-engine/models/mod-model.h"
// Macros for retrieving arguments from behavior scripts.
#define BHV_CMD_GET_1ST_U8(index) (u8)((gCurBhvCommand[index] >> 24) & 0xFF) // unused
@ -151,9 +152,9 @@ static s32 bhv_cmd_cylboard(void) {
// Command 0x1B: Sets the current model ID of the object.
// Usage: SET_MODEL(modelID)
static s32 bhv_cmd_set_model(void) {
s32 modelID = BHV_CMD_GET_2ND_S16(0);
gCurrentObject->header.gfx.sharedChild = gLoadedGraphNodes[modelID];
u32 modelID = BHV_CMD_GET_U32(0);
gCurrentObject->header.gfx.sharedChild = get_graph_node(modelID);
printf("bhv_cmd_set_model %d\n", modelID);
gCurBhvCommand++;
return BHV_PROC_CONTINUE;

View File

@ -312,6 +312,8 @@ struct GraphNodeObject *init_graph_node_object(struct AllocOnlyPool *pool,
vec3f_copy(graphNode->pos, pos);
vec3f_copy(graphNode->scale, scale);
vec3s_copy(graphNode->angle, angle);
// To avoid uninitialised memory usage in audio code
vec3f_copy(graphNode->cameraToObject, gVec3fZero);
graphNode->sharedChild = sharedChild;
graphNode->throwMatrix = NULL;
graphNode->unk38.animID = 0;

View File

@ -23,6 +23,7 @@
#include "surface_collision.h"
#include "surface_load.h"
#include "level_table.h"
#include "moon/mod-engine/models/mod-model.h"
#define CMD_GET(type, offset) (*(type *) (CMD_PROCESS_OFFSET(offset) + (u8 *) sCurrentCmd))
@ -54,6 +55,8 @@ static s16 sScriptStatus;
static s32 sRegister;
static struct LevelCommand *sCurrentCmd;
static struct MemoryPool *sMemPoolForGoddard;
static s32 eval_script_op(s8 op, s32 arg) {
s32 result = 0;
@ -279,17 +282,19 @@ static void level_cmd_load_mio0(void) {
sCurrentCmd = CMD_NEXT;
}
static void *alloc_for_goddard(u32 size) {
return mem_pool_alloc(sMemPoolForGoddard, size);
}
static void free_for_goddard(void *ptr) {
mem_pool_free(sMemPoolForGoddard, ptr);
}
static void level_cmd_load_mario_head(void) {
// TODO: Fix these hardcoded sizes
void *addr = main_pool_alloc(DOUBLE_SIZE_ON_64_BIT(0xE1000), MEMORY_POOL_LEFT);
if (addr != NULL) {
gdm_init(addr, DOUBLE_SIZE_ON_64_BIT(0xE1000));
gd_add_to_heap(gZBuffer, sizeof(gZBuffer)); // 0x25800
gd_add_to_heap(gFrameBuffer0, 3 * sizeof(gFrameBuffer0)); // 0x70800
gdm_setup();
gdm_maketestdl(CMD_GET(s16, 2));
} else {
}
sMemPoolForGoddard = mem_pool_init(0, 0);
gdm_init(alloc_for_goddard, free_for_goddard);
gdm_setup();
gdm_maketestdl(CMD_GET(s16, 2));
sCurrentCmd = CMD_NEXT;
}
@ -319,17 +324,17 @@ static void level_cmd_clear_level(void) {
static void level_cmd_alloc_level_pool(void) {
if (sLevelPool == NULL) {
sLevelPool = alloc_only_pool_init(main_pool_available() - sizeof(struct AllocOnlyPool),
MEMORY_POOL_LEFT);
sLevelPool = alloc_only_pool_init();
}
printf("Called alloc level pool\n");
sCurrentCmd = CMD_NEXT;
}
static void level_cmd_free_level_pool(void) {
s32 i;
alloc_only_pool_resize(sLevelPool, sLevelPool->usedSpace);
sLevelPool = NULL;
for (i = 0; i < 8; i++) {
@ -371,29 +376,19 @@ static void level_cmd_end_area(void) {
}
static void level_cmd_load_model_from_dl(void) {
s16 val1 = CMD_GET(s16, 2) & 0x0FFF;
#ifdef VERSION_EU
s16 val2 = (CMD_GET(s16, 2) & 0xFFFF) >> 12;
#else
s16 val2 = CMD_GET(u16, 2) >> 12;
#endif
void *val3 = CMD_GET(void *, 4);
if (val1 < 256) {
gLoadedGraphNodes[val1] =
(struct GraphNode *) init_graph_node_display_list(sLevelPool, 0, val2, val3);
}
u32 model = CMD_GET(u32, 0xA);
s64 layer = CMD_GET(u16, 0x8);
void *dl_ptr = CMD_GET(void *, 4);
bind_graph_node(model, (struct GraphNode *) init_graph_node_display_list(sLevelPool, 0, layer, dl_ptr));
sCurrentCmd = CMD_NEXT;
}
static void level_cmd_load_model_from_geo(void) {
s16 arg0 = CMD_GET(s16, 2);
u32 arg0 = CMD_GET(u32, 2);
void *arg1 = CMD_GET(void *, 4);
if (arg0 < 256) {
gLoadedGraphNodes[arg0] = process_geo_layout(sLevelPool, arg1);
}
bind_graph_node(arg0, process_geo_layout(sLevelPool, arg1));
sCurrentCmd = CMD_NEXT;
}
@ -404,27 +399,20 @@ static void level_cmd_23(void) {
f32 f;
} arg2;
s16 model = CMD_GET(s16, 2) & 0x0FFF;
#ifdef VERSION_EU
s16 arg0H = (CMD_GET(s16, 2) & 0xFFFF) >> 12;
#else
u32 model = CMD_GET(u32, 2) & 0x0FFF;
s16 arg0H = CMD_GET(u16, 2) >> 12;
#endif
void *arg1 = CMD_GET(void *, 4);
// load an f32, but using an integer load instruction for some reason (hence the union)
arg2.i = CMD_GET(s32, 8);
if (model < 256) {
// GraphNodeScale has a GraphNode at the top. This
// is being stored to the array, so cast the pointer.
gLoadedGraphNodes[model] =
(struct GraphNode *) init_graph_node_scale(sLevelPool, 0, arg0H, arg1, arg2.f);
}
bind_graph_node(model, (struct GraphNode *) init_graph_node_scale(sLevelPool, 0, arg0H, arg1, arg2.f));
sCurrentCmd = CMD_NEXT;
}
static void level_cmd_init_mario(void) {
u32 model = CMD_GET(u32, 0xE);
vec3s_set(gMarioSpawnInfo->startPos, 0, 0, 0);
vec3s_set(gMarioSpawnInfo->startAngle, 0, 0, 0);
@ -432,7 +420,8 @@ static void level_cmd_init_mario(void) {
gMarioSpawnInfo->areaIndex = 0;
gMarioSpawnInfo->behaviorArg = CMD_GET(u32, 4);
gMarioSpawnInfo->behaviorScript = CMD_GET(void *, 8);
gMarioSpawnInfo->unk18 = gLoadedGraphNodes[CMD_GET(u8, 3)];
gMarioSpawnInfo->unk18 = get_graph_node(model);
printf("level_cmd_init_mario %d\n", model);
gMarioSpawnInfo->next = NULL;
sCurrentCmd = CMD_NEXT;
@ -440,11 +429,10 @@ static void level_cmd_init_mario(void) {
static void level_cmd_place_object(void) {
u8 val7 = 1 << (gCurrActNum - 1);
u16 model;
u32 model = CMD_GET(u32, 0x1A);
struct SpawnInfo *spawnInfo;
printf("level_cmd_place_object %d\n", model);
if (sCurrAreaIndex != -1 && ((CMD_GET(u8, 2) & val7) || CMD_GET(u8, 2) == 0x1F)) {
model = CMD_GET(u8, 3);
spawnInfo = alloc_only_pool_alloc(sLevelPool, sizeof(struct SpawnInfo));
spawnInfo->startPos[0] = CMD_GET(s16, 4);
@ -460,7 +448,7 @@ static void level_cmd_place_object(void) {
spawnInfo->behaviorArg = CMD_GET(u32, 16);
spawnInfo->behaviorScript = CMD_GET(void *, 20);
spawnInfo->unk18 = gLoadedGraphNodes[model];
spawnInfo->unk18 = get_graph_node(model);
spawnInfo->next = gAreas[sCurrAreaIndex].objectSpawnInfos;
gAreas[sCurrAreaIndex].objectSpawnInfos = spawnInfo;

View File

@ -27,8 +27,11 @@ SpatialPartitionCell gDynamicSurfacePartition[16][16];
/**
* Pools of data to contain either surface nodes or surfaces.
*/
struct SurfaceNode *sSurfaceNodePool;
struct Surface *sSurfacePool;
static struct AllocOnlyPool *sStaticSurfaceNodePool;
static struct AllocOnlyPool *sStaticSurfacePool;
static struct AllocOnlyPool *sDynamicSurfaceNodePool;
static struct AllocOnlyPool *sDynamicSurfacePool;
static u8 sStaticSurfaceLoadComplete;
/**
* The size of the surface pool (2300).
@ -41,17 +44,14 @@ u8 unused8038EEA8[0x30];
* Allocate the part of the surface node pool to contain a surface node.
*/
static struct SurfaceNode *alloc_surface_node(void) {
struct SurfaceNode *node = &sSurfaceNodePool[gSurfaceNodesAllocated];
struct AllocOnlyPool *pool = !sStaticSurfaceLoadComplete ?
sStaticSurfaceNodePool : sDynamicSurfaceNodePool;
struct SurfaceNode *node = alloc_only_pool_alloc(pool, sizeof(struct SurfaceNode));
gSurfaceNodesAllocated++;
node->next = NULL;
//! A bounds check! If there's more surface nodes than 7000 allowed,
// we, um...
// Perhaps originally just debug feedback?
if (gSurfaceNodesAllocated >= 7000) {
}
return node;
}
@ -61,15 +61,10 @@ static struct SurfaceNode *alloc_surface_node(void) {
*/
static struct Surface *alloc_surface(void) {
struct Surface *surface = &sSurfacePool[gSurfacesAllocated];
struct AllocOnlyPool *pool = !sStaticSurfaceLoadComplete ? sStaticSurfacePool : sDynamicSurfacePool;
struct Surface *surface = alloc_only_pool_alloc(pool, sizeof(struct Surface));
gSurfacesAllocated++;
//! A bounds check! If there's more surfaces than the 2300 allowed,
// we, um...
// Perhaps originally just debug feedback?
if (gSurfacesAllocated >= sSurfacePoolSize) {
}
surface->type = 0;
surface->force = 0;
surface->flags = 0;
@ -524,9 +519,10 @@ 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);
sSurfacePool = main_pool_alloc(sSurfacePoolSize * sizeof(struct Surface), MEMORY_POOL_LEFT);
sStaticSurfaceNodePool = alloc_only_pool_init();
sStaticSurfacePool = alloc_only_pool_init();
sDynamicSurfaceNodePool = alloc_only_pool_init();
sDynamicSurfacePool = alloc_only_pool_init();
gCCMEnteredSlide = 0;
reset_red_coins_collected();
@ -580,7 +576,6 @@ u32 get_area_terrain_size(s16 *data) {
return data - startPos;
}
/**
* Process the level file, loading in vertices, surfaces, some objects, and environmental
* boxes (water, gas, JRB fog).
@ -596,6 +591,15 @@ void load_area_terrain(s16 index, s16 *data, s8 *surfaceRooms, s16 *macroObjects
gSurfaceNodesAllocated = 0;
gSurfacesAllocated = 0;
alloc_only_pool_clear(sStaticSurfaceNodePool);
alloc_only_pool_clear(sStaticSurfacePool);
alloc_only_pool_clear(sDynamicSurfaceNodePool);
alloc_only_pool_clear(sDynamicSurfacePool);
sStaticSurfaceLoadComplete = FALSE;
// Originally they forgot to clear this matrix,
// results in segfaults if this is not done.
clear_dynamic_surfaces();
clear_static_surfaces();
// A while loop iterating through each section of the level data. Sections of data
@ -637,6 +641,7 @@ void load_area_terrain(s16 index, s16 *data, s8 *surfaceRooms, s16 *macroObjects
gNumStaticSurfaceNodes = gSurfaceNodesAllocated;
gNumStaticSurfaces = gSurfacesAllocated;
sStaticSurfaceLoadComplete = TRUE;
}
/**
@ -644,6 +649,12 @@ void load_area_terrain(s16 index, s16 *data, s8 *surfaceRooms, s16 *macroObjects
*/
void clear_dynamic_surfaces(void) {
if (!(gTimeStopState & TIME_STOP_ACTIVE)) {
if (gSurfacesAllocated > gNumStaticSurfaces) {
alloc_only_pool_clear(sDynamicSurfacePool);
}
if (gSurfaceNodesAllocated > gNumStaticSurfaceNodes) {
alloc_only_pool_clear(sDynamicSurfaceNodePool);
}
gSurfacesAllocated = gNumStaticSurfaces;
gSurfaceNodesAllocated = gNumStaticSurfaceNodes;
@ -651,9 +662,6 @@ void clear_dynamic_surfaces(void) {
}
}
static void unused_80383604(void) {
}
/**
* Applies an object's transformation to the object's vertices.
*/

View File

@ -25,7 +25,6 @@
#include "gfx_dimensions.h"
struct SpawnInfo gPlayerSpawnInfos[1];
struct GraphNode *D_8033A160[0x100];
struct Area gAreaData[8];
struct WarpTransition gWarpTransition;
@ -38,7 +37,6 @@ s16 gPauseScreenMode;
s16 gSaveOptSelectIndex;
struct SpawnInfo *gMarioSpawnInfo = &gPlayerSpawnInfos[0];
struct GraphNode **gLoadedGraphNodes = D_8033A160;
struct Area *gAreas = gAreaData;
struct Area *gCurrentArea = NULL;
struct CreditsEntry *gCurrCreditsEntry = NULL;
@ -168,6 +166,10 @@ void load_obj_warp_nodes(void) {
struct ObjectWarpNode *sp24;
struct Object *sp20 = (struct Object *) gObjParentGraphNode.children;
if (sp20 == NULL) {
return;
}
do {
struct Object *sp1C = sp20;

View File

@ -118,9 +118,8 @@ struct WarpTransition
/*0x04*/ struct WarpTransitionData data;
};
extern struct GraphNode **gLoadedGraphNodes;
extern struct SpawnInfo gPlayerSpawnInfos[];
extern struct GraphNode *D_8033A160[];
extern struct GraphNode *gLoadedModelsPool[];
extern struct Area gAreaData[];
extern struct WarpTransition gWarpTransition;
extern s16 gCurrCourseNum;

View File

@ -43,6 +43,7 @@
#include "spawn_object.h"
#include "spawn_sound.h"
#include "thread6.h"
#include "moon/mod-engine/models/mod-model.h"
#define o gCurrentObject
@ -76,7 +77,7 @@ struct Struct802C0DF0 {
u8 unk0;
u8 unk1;
u8 unk2;
u8 model;
u32 model;
const BehaviorScript *behavior;
};

View File

@ -42,7 +42,7 @@ static s8 sPieceActions14[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1 };
struct BowserPuzzlePiece {
u8 model;
u32 model;
s8 xOffset;
s8 zOffset;
s8 initialAction;

View File

@ -12,12 +12,10 @@ void bhv_object_bubble_loop(void) {
f32 bubbleY = o->oPosY;
if (bubbleY > waterY) {
if (gFreeObjectList.next) {
bubbleSplash = spawn_object_at_origin(o, 0, MODEL_SMALL_WATER_SPLASH, bhvBubbleSplash);
bubbleSplash->oPosX = o->oPosX;
bubbleSplash->oPosY = bubbleY + 5.0f;
bubbleSplash->oPosZ = o->oPosZ;
}
bubbleSplash = spawn_object_at_origin(o, 0, MODEL_SMALL_WATER_SPLASH, bhvBubbleSplash);
bubbleSplash->oPosX = o->oPosX;
bubbleSplash->oPosY = bubbleY + 5.0f;
bubbleSplash->oPosZ = o->oPosZ;
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
}

View File

@ -8,20 +8,20 @@ void bhv_celebration_star_init(void) {
o->oCelebStarDiameterOfRotation = 100;
#if BUGFIX_STAR_BOWSER_KEY
if (gCurrLevelNum == LEVEL_BOWSER_1 || gCurrLevelNum == LEVEL_BOWSER_2) {
o->header.gfx.sharedChild = gLoadedGraphNodes[MODEL_BOWSER_KEY];
o->header.gfx.sharedChild = get_graph_node(MODEL_BOWSER_KEY);
o->oFaceAnglePitch = 0;
o->oFaceAngleRoll = 49152;
cur_obj_scale(0.1f);
o->oCelebStarUnkF4 = 1;
} else {
o->header.gfx.sharedChild = gLoadedGraphNodes[MODEL_STAR];
o->header.gfx.sharedChild = get_graph_node(MODEL_STAR);
o->oFaceAnglePitch = 0;
o->oFaceAngleRoll = 0;
cur_obj_scale(0.4f);
o->oCelebStarUnkF4 = 0;
}
#else
o->header.gfx.sharedChild = gLoadedGraphNodes[MODEL_STAR];
o->header.gfx.sharedChild = get_graph_node(MODEL_STAR);
cur_obj_scale(0.4f);
o->oFaceAnglePitch = 0;
o->oFaceAngleRoll = 0;

View File

@ -19,9 +19,9 @@ void bhv_collect_star_init(void) {
starId = (o->oBehParams >> 24) & 0xFF;
currentLevelStarFlags = save_file_get_star_flags(gCurrSaveFileNum - 1, gCurrCourseNum - 1);
if (currentLevelStarFlags & (1 << starId)) {
o->header.gfx.sharedChild = gLoadedGraphNodes[MODEL_TRANSPARENT_STAR];
o->header.gfx.sharedChild = get_graph_node(MODEL_TRANSPARENT_STAR);
} else {
o->header.gfx.sharedChild = gLoadedGraphNodes[MODEL_STAR];
o->header.gfx.sharedChild = get_graph_node(MODEL_STAR);
}
obj_set_hitbox(o, &sCollectStarHitbox);

View File

@ -63,8 +63,7 @@ void bhv_small_water_wave_loop(void) {
if (o->oPosY > sp1C) {
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
o->oPosY += 5.0f;
if (gFreeObjectList.next != NULL)
spawn_object(o, MODEL_SMALL_WATER_SPLASH, bhvObjectWaterSplash);
spawn_object(o, MODEL_SMALL_WATER_SPLASH, bhvObjectWaterSplash);
}
if (o->oInteractStatus & INT_STATUS_INTERACTED)
obj_mark_for_deletion(o);

View File

@ -29,8 +29,11 @@
// know of a good way to split them
struct Controller gControllers[3];
struct SPTask *gGfxSPTask;
Gfx *gDisplayListHead;
u8 *gGfxPoolEnd;
struct AllocOnlyPool *gGfxAllocOnlyPool;
Gfx *gDisplayListHeadInChunk;
Gfx *gDisplayListEndInChunk;
struct GfxPool *gGfxPool;
OSContStatus gControllerStatuses[4];
OSContPad gControllerPads[4];
@ -259,31 +262,22 @@ void end_master_display_list(void) {
create_task_structure();
}
//void draw_reset_bars(void) { // TARGET_64 only
// Stubbed. Only N64 target uses this
// }
void rendering_init(void) {
gGfxPool = &gGfxPools[0];
set_segment_base_addr(1, gGfxPool->buffer);
gGfxSPTask = &gGfxPool->spTask;
gDisplayListHead = gGfxPool->buffer;
gGfxPoolEnd = (u8 *) (gGfxPool->buffer + GFX_POOL_SIZE);
init_render_image();
clear_frame_buffer(0);
end_master_display_list();
send_display_list(&gGfxPool->spTask);
frameBufferIndex++;
gGlobalTimer++;
Gfx **alloc_next_dl(void) {
u32 size = 1000;
Gfx *new_chunk = alloc_only_pool_alloc(gGfxAllocOnlyPool, size * sizeof(Gfx));
gSPBranchList(gDisplayListHeadInChunk++, new_chunk);
gDisplayListHeadInChunk = new_chunk;
gDisplayListEndInChunk = new_chunk + size;
return &gDisplayListHeadInChunk;
}
void config_gfx_pool(void) {
gGfxPool = &gGfxPools[gGlobalTimer % GFX_NUM_POOLS];
set_segment_base_addr(1, gGfxPool->buffer);
gGfxSPTask = &gGfxPool->spTask;
gDisplayListHead = gGfxPool->buffer;
gGfxPoolEnd = (u8 *) (gGfxPool->buffer + GFX_POOL_SIZE);
gDisplayListHeadInChunk = gGfxPool->buffer;
gDisplayListEndInChunk = gDisplayListHeadInChunk + 1;
alloc_only_pool_clear(gGfxAllocOnlyPool);
}
/** Handles vsync. */
@ -596,11 +590,4 @@ void game_loop_one_iteration(void) {
read_controller_inputs();
levelCommandAddr = level_script_execute(levelCommandAddr);
display_and_vsync();
// when debug info is enabled, print the "BUF %d" information.
if (gShowDebugText) {
// subtract the end of the gfx pool with the display list to obtain the
// amount of free space remaining.
print_text_fmt_int(180, 20, "BUF %d", gGfxPoolEnd - (u8 *) gDisplayListHead);
}
}

View File

@ -9,6 +9,8 @@
#include "types.h"
#include "memory.h"
#define GFX_POOL_SIZE 6400
struct GfxPool {
Gfx buffer[GFX_POOL_SIZE];
struct SPTask spTask;
@ -35,8 +37,9 @@ extern uintptr_t gPhysicalZBuffer;
extern void *D_80339CF0;
extern void *D_80339CF4;
extern struct SPTask *gGfxSPTask;
extern Gfx *gDisplayListHead;
extern u8 *gGfxPoolEnd;
extern struct AllocOnlyPool *gGfxAllocOnlyPool;
extern Gfx *gDisplayListHeadInChunk;
extern Gfx *gDisplayListEndInChunk;
extern struct GfxPool *gGfxPool;
extern u8 gControllerBits;
extern s8 gEepromProbe;
@ -71,4 +74,7 @@ void rendering_init(void);
void config_gfx_pool(void);
void display_and_vsync(void);
Gfx **alloc_next_dl(void);
#define gDisplayListHead (*(gDisplayListEndInChunk - gDisplayListHeadInChunk >= 2 ? &gDisplayListHeadInChunk : alloc_next_dl()))
#endif // GAME_INIT_H

View File

@ -245,11 +245,7 @@ void spawn_special_objects(s16 areaIndex, s16 **specialObjList) {
s16 y;
s16 z;
s16 extraParams[4];
#ifdef VERSION_EU
s16 model;
#else
u8 model;
#endif
u32 model;
u8 type;
u8 presetID;
u8 defaultParam;

View File

@ -1,6 +1,8 @@
#include <PR/ultratypes.h>
#include <string.h>
#include <stdlib.h>
#include "sm64.h"
#define INCLUDED_FROM_MEMORY_C
@ -19,26 +21,40 @@
#define ALIGN16(val) (((val) + 0xF) & ~0xF)
struct MainPoolState {
u32 freeSpace;
struct MainPoolBlock *listHeadL;
struct MainPoolBlock *listHeadR;
void *prev;
};
struct MainPoolBlock {
struct MainPoolBlock *prev;
struct MainPoolBlock *next;
void (*releaseHandler)(void *addr);
};
struct AllocOnlyPoolBlock {
struct AllocOnlyPoolBlock *prev;
#if !IS_64_BIT
void *pad; // require 8 bytes alignment
#endif
};
struct AllocOnlyPool {
struct AllocOnlyPoolBlock *lastBlock;
u32 lastBlockSize;
u32 lastBlockNextPos;
};
struct FreeListNode {
struct FreeListNode *next;
};
struct AllocatedNode {
s32 bin;
s32 pad;
};
struct MemoryPool {
u32 totalSpace;
struct MemoryBlock *firstBlock;
struct MemoryBlock *freeList;
};
struct MemoryBlock {
struct MemoryBlock *next;
u32 size;
struct AllocOnlyPool *allocOnlyPool;
struct FreeListNode *bins[27];
};
extern uintptr_t sSegmentTable[32];
@ -85,23 +101,14 @@ void *virtual_to_segmented(UNUSED u32 segment, const void *addr) {
void move_segment_table_to_dmem(void) {
}
static void main_pool_free_all(void) {
while (sPoolListHeadL != NULL) {
main_pool_free(sPoolListHeadL + 1);
}
}
/**
* Initialize the main memory pool. This pool is conceptually a pair of stacks
* that grow inward from the left and right. It therefore only supports
* freeing the object that was most recently allocated from a side.
*/
void main_pool_init(void *start, void *end) {
sPoolStart = (u8 *) ALIGN16((uintptr_t) start) + 16;
sPoolEnd = (u8 *) ALIGN16((uintptr_t) end - 15) - 16;
sPoolFreeSpace = sPoolEnd - sPoolStart;
sPoolListHeadL = (struct MainPoolBlock *) (sPoolStart - 16);
sPoolListHeadR = (struct MainPoolBlock *) sPoolEnd;
sPoolListHeadL->prev = NULL;
sPoolListHeadL->next = NULL;
sPoolListHeadR->prev = NULL;
sPoolListHeadR->next = NULL;
void main_pool_init(void) {
atexit(main_pool_free_all);
}
/**
@ -109,100 +116,46 @@ void main_pool_init(void *start, void *end) {
* specified side of the pool (MEMORY_POOL_LEFT or MEMORY_POOL_RIGHT).
* If there is not enough space, return NULL.
*/
void *main_pool_alloc(u32 size, u32 side) {
struct MainPoolBlock *newListHead;
void *addr = NULL;
size = ALIGN16(size) + 16;
if (size != 0 && sPoolFreeSpace >= size) {
sPoolFreeSpace -= size;
if (side == MEMORY_POOL_LEFT) {
newListHead = (struct MainPoolBlock *) ((u8 *) sPoolListHeadL + size);
sPoolListHeadL->next = newListHead;
newListHead->prev = sPoolListHeadL;
newListHead->next = NULL;
addr = (u8 *) sPoolListHeadL + 16;
sPoolListHeadL = newListHead;
} else {
newListHead = (struct MainPoolBlock *) ((u8 *) sPoolListHeadR - size);
sPoolListHeadR->prev = newListHead;
newListHead->next = sPoolListHeadR;
newListHead->prev = NULL;
sPoolListHeadR = newListHead;
addr = (u8 *) sPoolListHeadR + 16;
}
void *main_pool_alloc(u32 size, void (*releaseHandler)(void *addr)) {
struct MainPoolBlock *newListHead = (struct MainPoolBlock *) malloc(sizeof(struct MainPoolBlock) + size);
if (newListHead == NULL) {
abort();
}
return addr;
if (sPoolListHeadL != NULL) {
sPoolListHeadL->next = newListHead;
}
newListHead->prev = sPoolListHeadL;
newListHead->next = NULL;
newListHead->releaseHandler = releaseHandler;
sPoolListHeadL = newListHead;
return newListHead + 1;
}
/**
* Free a block of memory that was allocated from the pool. The block must be
* the most recently allocated block from its end of the pool.
* Return the amount of free space left in the pool.
*/
u32 main_pool_free(void *addr) {
struct MainPoolBlock *block = (struct MainPoolBlock *) ((u8 *) addr - 16);
struct MainPoolBlock *oldListHead = (struct MainPoolBlock *) ((u8 *) addr - 16);
if (oldListHead < sPoolListHeadL) {
while (oldListHead->next != NULL) {
oldListHead = oldListHead->next;
struct MainPoolBlock *block = ((struct MainPoolBlock *) addr) - 1;
void *toFree;
do {
if (sPoolListHeadL == NULL) {
abort();
}
sPoolListHeadL = block;
sPoolListHeadL->next = NULL;
sPoolFreeSpace += (uintptr_t) oldListHead - (uintptr_t) sPoolListHeadL;
} else {
while (oldListHead->prev != NULL) {
oldListHead = oldListHead->prev;
if (sPoolListHeadL->releaseHandler != NULL) {
sPoolListHeadL->releaseHandler(sPoolListHeadL + 1);
}
sPoolListHeadR = block->next;
sPoolListHeadR->prev = NULL;
sPoolFreeSpace += (uintptr_t) sPoolListHeadR - (uintptr_t) oldListHead;
}
return sPoolFreeSpace;
toFree = sPoolListHeadL;
sPoolListHeadL = sPoolListHeadL->prev;
if (sPoolListHeadL != NULL) {
sPoolListHeadL->next = NULL;
}
free(toFree);
} while (toFree != block);
return 0;
}
/**
* Resize a block of memory that was allocated from the left side of the pool.
* If the block is increasing in size, it must be the most recently allocated
* block from the left side.
* The block does not move.
*/
void *main_pool_realloc(void *addr, u32 size) {
void *newAddr = NULL;
struct MainPoolBlock *block = (struct MainPoolBlock *) ((u8 *) addr - 16);
if (block->next == sPoolListHeadL) {
main_pool_free(addr);
newAddr = main_pool_alloc(size, MEMORY_POOL_LEFT);
}
return newAddr;
}
/**
* Return the size of the largest block that can currently be allocated from the
* pool.
*/
u32 main_pool_available(void) {
return sPoolFreeSpace - 16;
}
/**
* Push pool state, to be restored later. Return the amount of free space left
* in the pool.
*/
u32 main_pool_push_state(void) {
void *prevState = gMainPoolState;
u32 freeSpace = sPoolFreeSpace;
struct MainPoolBlock *lhead = sPoolListHeadL;
struct MainPoolBlock *rhead = sPoolListHeadR;
gMainPoolState = main_pool_alloc(sizeof(*gMainPoolState), MEMORY_POOL_LEFT);
gMainPoolState->freeSpace = freeSpace;
gMainPoolState->listHeadL = lhead;
gMainPoolState->listHeadR = rhead;
struct MainPoolState *prevState = gMainPoolState;
gMainPoolState = main_pool_alloc(sizeof(*gMainPoolState), NULL);
gMainPoolState->prev = prevState;
return sPoolFreeSpace;
return 0;
}
/**
@ -210,11 +163,9 @@ u32 main_pool_push_state(void) {
* amount of free space left in the pool.
*/
u32 main_pool_pop_state(void) {
sPoolFreeSpace = gMainPoolState->freeSpace;
sPoolListHeadL = gMainPoolState->listHeadL;
sPoolListHeadR = gMainPoolState->listHeadR;
gMainPoolState = gMainPoolState->prev;
return sPoolFreeSpace;
struct MainPoolState *prevState = gMainPoolState->prev;
main_pool_free(gMainPoolState);
gMainPoolState = prevState;
}
/**
@ -235,7 +186,7 @@ static void *dynamic_dma_read(u8 *srcStart, u8 *srcEnd, u32 side) {
void *dest;
u32 size = ALIGN16(srcEnd - srcStart);
dest = main_pool_alloc(size, side);
dest = main_pool_alloc(size, NULL);
if (dest != NULL) {
dma_read(dest, srcStart, srcEnd);
}
@ -247,160 +198,115 @@ static void *dynamic_dma_read(u8 *srcStart, u8 *srcEnd, u32 side) {
* support freeing allocated memory.
* Return NULL if there is not enough space in the main pool.
*/
struct AllocOnlyPool *alloc_only_pool_init(u32 size, u32 side) {
void *addr;
struct AllocOnlyPool *subPool = NULL;
size = ALIGN4(size);
addr = main_pool_alloc(size + sizeof(struct AllocOnlyPool), side);
if (addr != NULL) {
subPool = (struct AllocOnlyPool *) addr;
subPool->totalSpace = size;
subPool->usedSpace = 0;
subPool->startPtr = (u8 *) addr + sizeof(struct AllocOnlyPool);
subPool->freePtr = (u8 *) addr + sizeof(struct AllocOnlyPool);
static void alloc_only_pool_release_handler(void *addr) {
struct AllocOnlyPool *pool = (struct AllocOnlyPool *) addr;
struct AllocOnlyPoolBlock *block = pool->lastBlock;
while (block != NULL) {
struct AllocOnlyPoolBlock *prev = block->prev;
free(block);
block = prev;
}
return subPool;
}
/**
* Allocate from an allocation-only pool.
* Return NULL if there is not enough space.
*/
void *alloc_only_pool_alloc(struct AllocOnlyPool *pool, s32 size) {
void *addr = NULL;
struct AllocOnlyPool *alloc_only_pool_init(void) {
struct AllocOnlyPool *pool;
void *addr = main_pool_alloc(sizeof(struct AllocOnlyPool), alloc_only_pool_release_handler);
size = ALIGN4(size);
if (size > 0 && pool->usedSpace + size <= pool->totalSpace) {
addr = pool->freePtr;
pool->freePtr += size;
pool->usedSpace += size;
}
return addr;
}
pool = (struct AllocOnlyPool *) addr;
pool->lastBlock = NULL;
pool->lastBlockSize = 0;
pool->lastBlockNextPos = 0;
/**
* Resize an allocation-only pool.
* If the pool is increasing in size, the pool must be the last thing allocated
* from the left end of the main pool.
* The pool does not move.
*/
struct AllocOnlyPool *alloc_only_pool_resize(struct AllocOnlyPool *pool, u32 size) {
struct AllocOnlyPool *newPool;
size = ALIGN4(size);
newPool = main_pool_realloc(pool, size + sizeof(struct AllocOnlyPool));
if (newPool != NULL) {
pool->totalSpace = size;
}
return newPool;
}
/**
* 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 + ALIGN16(sizeof(struct MemoryPool)), side);
if (addr != NULL) {
pool = (struct MemoryPool *) addr;
pool->totalSpace = size;
pool->firstBlock = (struct MemoryBlock *) ((u8 *) addr + ALIGN16(sizeof(struct MemoryPool)));
pool->freeList = (struct MemoryBlock *) ((u8 *) addr + ALIGN16(sizeof(struct MemoryPool)));
block = pool->firstBlock;
block->next = NULL;
block->size = pool->totalSpace;
}
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 = (struct MemoryBlock *) &pool->freeList;
void *addr = NULL;
void alloc_only_pool_clear(struct AllocOnlyPool *pool) {
alloc_only_pool_release_handler(pool);
pool->lastBlock = NULL;
pool->lastBlockSize = 0;
pool->lastBlockNextPos = 0;
}
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;
void *alloc_only_pool_alloc(struct AllocOnlyPool *pool, s32 size) {
u8 *addr;
u32 s = size;
if (pool->lastBlockSize - pool->lastBlockNextPos < s) {
struct AllocOnlyPoolBlock *block;
u32 nextSize = pool->lastBlockSize * 2;
if (nextSize < 100) {
nextSize = 100;
}
freeBlock = freeBlock->next;
if (nextSize < s) {
nextSize = s;
}
block = (struct AllocOnlyPoolBlock *) malloc(sizeof(struct AllocOnlyPoolBlock) + nextSize);
if (block == NULL) {
abort();
}
block->prev = pool->lastBlock;
pool->lastBlock = block;
pool->lastBlockSize = nextSize;
pool->lastBlockNextPos = 0;
}
addr = (u8 *) (pool->lastBlock + 1) + pool->lastBlockNextPos;
pool->lastBlockNextPos += s;
return addr;
}
/**
* Free a block that was allocated using mem_pool_alloc.
*/
void mem_pool_free(struct MemoryPool *pool, void *addr) {
struct MemoryBlock *block = (struct MemoryBlock *) ((u8 *) addr - sizeof(struct MemoryBlock));
struct MemoryBlock *freeList = pool->freeList;
struct MemoryPool *mem_pool_init(UNUSED u32 size, UNUSED u32 side) {
struct MemoryPool *pool;
void *addr = main_pool_alloc(sizeof(struct MemoryPool), NULL);
u32 i;
if (pool->freeList == NULL) {
pool->freeList = block;
block->next = NULL;
} else {
if (block < pool->freeList) {
if ((u8 *) pool->freeList == (u8 *) block + block->size) {
block->size += freeList->size;
block->next = freeList->next;
pool->freeList = block;
} else {
block->next = pool->freeList;
pool->freeList = 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;
}
pool = (struct MemoryPool *) addr;
pool->allocOnlyPool = alloc_only_pool_init();
for (i = 0; i < ARRAY_COUNT(pool->bins); i++) {
pool->bins[i] = NULL;
}
return pool;
}
void *mem_pool_alloc(struct MemoryPool *pool, u32 size) {
struct FreeListNode *node;
struct AllocatedNode *an;
s32 bin = -1;
u32 itemSize;
u32 i;
for (i = 3; i < 30; i++) {
if (size <= (1U << i)) {
bin = i;
break;
}
}
if (bin == -1) {
abort();
}
itemSize = 1 << bin;
node = pool->bins[bin - 3];
if (node == NULL) {
node = alloc_only_pool_alloc(pool->allocOnlyPool, sizeof(struct AllocatedNode) + itemSize);
node->next = NULL;
pool->bins[bin - 3] = node;
}
an = (struct AllocatedNode *) node;
pool->bins[bin - 3] = node->next;
an->bin = bin;
return an + 1;
}
void mem_pool_free(struct MemoryPool *pool, void *addr) {
struct AllocatedNode *an = ((struct AllocatedNode *) addr) - 1;
struct FreeListNode *node = (struct FreeListNode *) an;
s32 bin = an->bin;
node->next = pool->bins[bin - 3];
pool->bins[bin - 3] = node;
}
void *alloc_display_list(u32 size) {
void *ptr = NULL;
size = ALIGN8(size);
if (gGfxPoolEnd - size >= (u8 *) gDisplayListHead) {
gGfxPoolEnd -= size;
ptr = gGfxPoolEnd;
} else {
}
return ptr;
return alloc_only_pool_alloc(gGfxAllocOnlyPool, size);
}
static struct MarioAnimDmaRelatedThing *func_802789F0(u8 *srcAddr) {

View File

@ -8,16 +8,7 @@
#define MEMORY_POOL_LEFT 0
#define MEMORY_POOL_RIGHT 1
#define GFX_POOL_SIZE (512 * 1024)
struct AllocOnlyPool
{
s32 totalSpace;
s32 usedSpace;
u8 *startPtr;
u8 *freePtr;
};
struct AllocOnlyPool;
struct MemoryPool;
struct MarioAnimation;
struct Animation;
@ -35,8 +26,8 @@ void *segmented_to_virtual(const void *addr);
void *virtual_to_segmented(u32 segment, const void *addr);
void move_segment_table_to_dmem(void);
void main_pool_init(void *start, void *end);
void *main_pool_alloc(u32 size, u32 side);
void main_pool_init(void);
void *main_pool_alloc(u32 size, void (*releaseHandler)(void *addr));
u32 main_pool_free(void *addr);
void *main_pool_realloc(void *addr, u32 size);
u32 main_pool_available(void);
@ -49,9 +40,9 @@ u32 main_pool_pop_state(void);
#define load_segment_decompress_heap(...)
#define load_engine_code_segment(...)
struct AllocOnlyPool *alloc_only_pool_init(u32 size, u32 side);
struct AllocOnlyPool *alloc_only_pool_init(void);
void alloc_only_pool_clear(struct AllocOnlyPool *pool);
void *alloc_only_pool_alloc(struct AllocOnlyPool *pool, s32 size);
struct AllocOnlyPool *alloc_only_pool_resize(struct AllocOnlyPool *pool, u32 size);
struct MemoryPool *mem_pool_init(u32 size, u32 side);
void *mem_pool_alloc(struct MemoryPool *pool, u32 size);

View File

@ -31,6 +31,7 @@
#include "save_file.h"
#include "spawn_object.h"
#include "spawn_sound.h"
#include "moon/mod-engine/models/mod-model.h"
/**
* @file obj_behaviors.c

View File

@ -44,6 +44,7 @@
#include "save_file.h"
#include "seq_ids.h"
#include "spawn_sound.h"
#include "moon/mod-engine/models/mod-model.h"
#define POS_OP_SAVE_POSITION 0
#define POS_OP_COMPUTE_VELOCITY 1

View File

@ -26,6 +26,7 @@
#include "rendering_graph_node.h"
#include "spawn_object.h"
#include "spawn_sound.h"
#include "moon/mod-engine/models/mod-model.h"
s8 D_8032F0A0[] = { 0xF8, 0x08, 0xFC, 0x04 };
s16 D_8032F0A4[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
@ -478,7 +479,7 @@ struct Object *spawn_object_rel_with_rot(struct Object *parent, u32 model, const
return newObj;
}
struct Object *spawn_obj_with_transform_flags(struct Object *sp20, s32 model, const BehaviorScript *sp28) {
struct Object *spawn_obj_with_transform_flags(struct Object *sp20, u32 model, const BehaviorScript *sp28) {
struct Object *sp1C = spawn_object(sp20, model, sp28);
sp1C->oFlags |= OBJ_FLAG_0020 | OBJ_FLAG_SET_THROW_MATRIX_FROM_TRANSFORM;
return sp1C;
@ -534,14 +535,14 @@ struct Object *spawn_object_at_origin(struct Object *parent, UNUSED s32 unusedAr
obj->parentObj = parent;
obj->header.gfx.unk18 = parent->header.gfx.unk18;
obj->header.gfx.unk19 = parent->header.gfx.unk18;
geo_obj_init((struct GraphNodeObject *) &obj->header.gfx, gLoadedGraphNodes[model], gVec3fZero,
printf("spawn_object_at_origin %d\n", model);
geo_obj_init((struct GraphNodeObject *) &obj->header.gfx, get_graph_node(model), gVec3fZero,
gVec3sZero);
return obj;
}
struct Object *spawn_object(struct Object *parent, s32 model, const BehaviorScript *behavior) {
struct Object *spawn_object(struct Object *parent, u32 model, const BehaviorScript *behavior) {
struct Object *obj;
obj = spawn_object_at_origin(parent, 0, model, behavior);
@ -550,21 +551,17 @@ struct Object *spawn_object(struct Object *parent, s32 model, const BehaviorScri
return obj;
}
struct Object *try_to_spawn_object(s16 offsetY, f32 scale, struct Object *parent, s32 model,
struct Object *try_to_spawn_object(s16 offsetY, f32 scale, struct Object *parent, u32 model,
const BehaviorScript *behavior) {
struct Object *obj;
if (gFreeObjectList.next != NULL) {
obj = spawn_object(parent, model, behavior);
obj->oPosY += offsetY;
obj_scale(obj, scale);
return obj;
} else {
return NULL;
}
obj = spawn_object(parent, model, behavior);
obj->oPosY += offsetY;
obj_scale(obj, scale);
return obj;
}
struct Object *spawn_object_with_scale(struct Object *parent, s32 model, const BehaviorScript *behavior, f32 scale) {
struct Object *spawn_object_with_scale(struct Object *parent, u32 model, const BehaviorScript *behavior, f32 scale) {
struct Object *obj;
obj = spawn_object_at_origin(parent, 0, model, behavior);
@ -580,7 +577,7 @@ static void obj_build_relative_transform(struct Object *obj) {
}
struct Object *spawn_object_relative(s16 behaviorParam, s16 relativePosX, s16 relativePosY, s16 relativePosZ,
struct Object *parent, s32 model, const BehaviorScript *behavior) {
struct Object *parent, u32 model, const BehaviorScript *behavior) {
struct Object *obj = spawn_object_at_origin(parent, 0, model, behavior);
obj_copy_pos_and_angle(obj, parent);
@ -595,7 +592,7 @@ struct Object *spawn_object_relative(s16 behaviorParam, s16 relativePosX, s16 re
struct Object *spawn_object_relative_with_scale(s16 behaviorParam, s16 relativePosX, s16 relativePosY,
s16 relativePosZ, f32 scale, struct Object *parent,
s32 model, const BehaviorScript *behavior) {
u32 model, const BehaviorScript *behavior) {
struct Object *obj;
obj = spawn_object_relative(behaviorParam, relativePosX, relativePosY, relativePosZ, parent, model,
@ -1124,8 +1121,9 @@ void cur_obj_get_dropped(void) {
cur_obj_move_after_thrown_or_dropped(0.0f, 0.0f);
}
void cur_obj_set_model(s32 modelID) {
o->header.gfx.sharedChild = gLoadedGraphNodes[modelID];
void cur_obj_set_model(u32 modelID) {
printf("cur_obj_set_model %d\n", modelID);
o->header.gfx.sharedChild = get_graph_node(modelID);
}
void mario_set_flag(s32 flag) {
@ -2740,12 +2738,9 @@ s32 cur_obj_update_dialog_with_cutscene(s32 actionArg, s32 dialogFlags, s32 cuts
return dialogResponse;
}
s32 cur_obj_has_model(u16 modelID) {
if (o->header.gfx.sharedChild == gLoadedGraphNodes[modelID]) {
return TRUE;
} else {
return FALSE;
}
s32 cur_obj_has_model(u32 modelID) {
printf("cur_obj_has_model %d\n", modelID);
return o->header.gfx.sharedChild == get_graph_node(modelID);
}
void cur_obj_align_gfx_with_floor(void) {

View File

@ -55,7 +55,7 @@ struct SpawnParticlesInfo
{
/*0x00*/ s8 behParam;
/*0x01*/ s8 count;
/*0x02*/ u8 model;
/*0x02*/ u32 model;
/*0x03*/ s8 offsetY;
/*0x04*/ s8 forwardVelBase;
/*0x05*/ s8 forwardVelRange;
@ -97,18 +97,18 @@ struct Object *spawn_object_abs_with_rot(struct Object *parent, s16 uselessArg,
s16 x, s16 y, s16 z, s16 rx, s16 ry, s16 rz);
struct Object *spawn_object_rel_with_rot(struct Object *parent, u32 model, const BehaviorScript *behavior,
s16 xOff, s16 yOff, s16 zOff, s16 rx, s16 ry, UNUSED s16 rz);
struct Object *spawn_obj_with_transform_flags(struct Object *sp20, s32 model, const BehaviorScript *sp28);
struct Object *spawn_obj_with_transform_flags(struct Object *sp20, u32 model, const BehaviorScript *sp28);
struct Object *spawn_water_droplet(struct Object *parent, struct WaterDropletParams *params);
struct Object *spawn_object_at_origin(struct Object *, s32, u32, const BehaviorScript *);
struct Object *spawn_object_at_origin(struct Object *parent, UNUSED s32 unusedArg, u32 model, const BehaviorScript *behavior);
struct Object *spawn_object(struct Object *parent, s32 model, const BehaviorScript *behavior);
struct Object *try_to_spawn_object(s16 offsetY, f32 scale, struct Object *parent, s32 model, const BehaviorScript *behavior);
struct Object *spawn_object_with_scale(struct Object *parent, s32 model, const BehaviorScript *behavior, f32 scale);
struct Object *spawn_object(struct Object *parent, u32 model, const BehaviorScript *behavior);
struct Object *try_to_spawn_object(s16 offsetY, f32 scale, struct Object *parent, u32 model, const BehaviorScript *behavior);
struct Object *spawn_object_with_scale(struct Object *parent, u32 model, const BehaviorScript *behavior, f32 scale);
struct Object *spawn_object_relative(s16 behaviorParam, s16 relativePosX, s16 relativePosY, s16 relativePosZ,
struct Object *parent, s32 model, const BehaviorScript *behavior);
struct Object *parent, u32 model, const BehaviorScript *behavior);
struct Object *spawn_object_relative_with_scale(s16 behaviorParam, s16 relativePosX, s16 relativePosY,
s16 relativePosZ, f32 scale, struct Object *parent,
s32 model, const BehaviorScript *behavior);
u32 model, const BehaviorScript *behavior);
void cur_obj_move_using_vel(void);
void obj_copy_graph_y_offset(struct Object *dst, struct Object *src);
void obj_copy_pos_and_angle(struct Object *dst, struct Object *src);
@ -157,7 +157,7 @@ void cur_obj_set_y_vel_and_animation(f32 sp18, s32 sp1C);
void cur_obj_unrender_and_reset_state(s32 sp18, s32 sp1C);
void cur_obj_get_thrown_or_placed(f32 forwardVel, f32 velY, s32 thrownAction);
void cur_obj_get_dropped(void);
void cur_obj_set_model(s32 modelID);
void cur_obj_set_model(u32 modelID);
void mario_set_flag(s32 flag);
s32 cur_obj_clear_interact_status_flag(s32 flag);
void obj_mark_for_deletion(struct Object *obj);
@ -276,7 +276,7 @@ s32 cur_obj_can_mario_activate_textbox(f32 radius, f32 height, UNUSED s32 unused
s32 cur_obj_can_mario_activate_textbox_2(f32 radius, f32 height);
s32 cur_obj_update_dialog(s32 actionArg, s32 dialogFlags, s32 dialogID, UNUSED s32 unused);
s32 cur_obj_update_dialog_with_cutscene(s32 actionArg, s32 dialogFlags, s32 cutsceneTable, s32 dialogID);
s32 cur_obj_has_model(u16 modelID);
s32 cur_obj_has_model(u32 modelID);
void cur_obj_align_gfx_with_floor(void);
s32 mario_is_within_rectangle(s16 minX, s16 maxX, s16 minZ, s16 maxZ);
void cur_obj_shake_screen(s32 shake);

View File

@ -63,11 +63,6 @@ s16 gDebugInfoOverwrite[16][8];
*/
u32 gTimeStopState;
/**
* The pool that objects are allocated from.
*/
struct Object gObjectPool[OBJECT_POOL_CAPACITY];
/**
* A special object whose purpose is to act as a parent for macro objects.
*/
@ -188,7 +183,7 @@ s8 sObjectListUpdateOrder[] = { OBJ_LIST_SPAWNER,
struct ParticleProperties {
u32 particleFlag;
u32 activeParticleFlag;
u8 model;
u32 model;
const BehaviorScript *behavior;
};
@ -540,17 +535,11 @@ void clear_objects(void) {
debug_unknown_level_select_check();
init_free_object_list();
clear_object_lists(gObjectListArray);
stub_behavior_script_2();
stub_obj_list_processor_1();
for (i = 0; i < OBJECT_POOL_CAPACITY; i++) {
gObjectPool[i].activeFlags = ACTIVE_FLAG_DEACTIVATED;
geo_reset_object_node(&gObjectPool[i].header.gfx);
}
gObjectMemoryPool = mem_pool_init(0x800, MEMORY_POOL_LEFT);
gObjectLists = gObjectListArray;

View File

@ -1048,8 +1048,7 @@ void geo_process_root(struct GraphNodeRoot *node, Vp *b, Vp *c, s32 clearColor)
Mtx *initialMatrix;
Vp *viewport = alloc_display_list(sizeof(*viewport));
gDisplayListHeap = alloc_only_pool_init(main_pool_available() - sizeof(struct AllocOnlyPool),
MEMORY_POOL_LEFT);
gDisplayListHeap = alloc_only_pool_init();
initialMatrix = alloc_display_list(sizeof(*initialMatrix));
gMatStackIndex = 0;
gCurAnimType = 0;
@ -1077,10 +1076,6 @@ void geo_process_root(struct GraphNodeRoot *node, Vp *b, Vp *c, s32 clearColor)
geo_process_node_and_siblings(node->node.children);
}
gCurGraphNodeRoot = NULL;
if (gShowDebugText) {
print_text_fmt_int(180, 36, "MEM %d",
gDisplayListHeap->totalSpace - gDisplayListHeap->usedSpace);
}
main_pool_free(gDisplayListHeap);
}
}

View File

@ -230,7 +230,6 @@ void *create_skybox_ortho_matrix(s8 player) {
f32 bottom = sSkyBoxInfo[player].scaledY - SCREEN_HEIGHT;
f32 top = sSkyBoxInfo[player].scaledY;
Mtx *mtx = alloc_display_list(sizeof(*mtx));
f32 half_width = (4.0f / 3.0f) / GFX_DIMENSIONS_ASPECT_RATIO * SCREEN_WIDTH / 2;
f32 center = (sSkyBoxInfo[player].scaledX + SCREEN_WIDTH / 2);
if (half_width < SCREEN_WIDTH / 2) {
@ -241,7 +240,6 @@ void *create_skybox_ortho_matrix(s8 player) {
if (mtx != NULL) {
guOrtho(mtx, left, right, bottom, top, 0.0f, 3.0f, 1.0f);
} else {
}
return mtx;
@ -251,7 +249,7 @@ void *create_skybox_ortho_matrix(s8 player) {
* Creates the skybox's display list, then draws the 3x3 grid of tiles.
*/
Gfx *init_skybox_display_list(s8 player, s8 background, s8 colorIndex) {
s32 dlCommandCount = 7 + (3 * 3) * 7; // 5 for the start and end, plus 9 skybox tiles
s32 dlCommandCount = 124;
void *skybox = alloc_display_list(dlCommandCount * sizeof(Gfx));
Gfx *dlist = skybox;

View File

@ -1,5 +1,5 @@
#include <stdlib.h>
#include <PR/ultratypes.h>
#include "audio/external.h"
#include "engine/geo_layout.h"
#include "engine/graph_node.h"
@ -89,10 +89,18 @@ struct Object *try_allocate_object(struct ObjectNode *destList, struct ObjectNod
destList->prev->next = nextObj;
destList->prev = nextObj;
} else {
return NULL;
nextObj = (struct ObjectNode *) malloc(sizeof(struct Object));
if (nextObj == NULL) {
abort();
}
// Insert at end of destination list
nextObj->prev = destList->prev;
nextObj->next = destList;
destList->prev->next = nextObj;
destList->prev = nextObj;
}
geo_remove_child(&nextObj->gfx.node);
init_graph_node_object(NULL, &nextObj->gfx, 0, gVec3fZero, gVec3sZero, gVec3fOne);
geo_add_child(&gObjParentGraphNode, &nextObj->gfx.node);
return (struct Object *) nextObj;
@ -126,27 +134,6 @@ static void deallocate_object(struct ObjectNode *freeList, struct ObjectNode *ob
freeList->next = obj;
}
/**
* Add every object in the pool to the free object list.
*/
void init_free_object_list(void) {
s32 i;
s32 poolLength = OBJECT_POOL_CAPACITY;
// Add the first object in the pool to the free list
struct Object *obj = &gObjectPool[0];
gFreeObjectList.next = (struct ObjectNode *) obj;
// Link each object in the pool to the following object
for (i = 0; i < poolLength - 1; i++) {
obj->header.next = &(obj + 1)->header;
obj++;
}
// End the list
obj->header.next = NULL;
}
/**
* Clear each object list, without adding the objects back to the free list.
*/
@ -154,6 +141,15 @@ void clear_object_lists(struct ObjectNode *objLists) {
s32 i;
for (i = 0; i < NUM_OBJ_LISTS; i++) {
struct ObjectNode *list = objLists + i;
struct ObjectNode *node = list->next;
while (node != NULL && node != list) {
struct Object *obj = (struct Object *) node;
node = node->next;
unload_object(obj);
}
objLists[i].next = &objLists[i];
objLists[i].prev = &objLists[i];
}
@ -190,7 +186,6 @@ void unload_object(struct Object *obj) {
obj->header.gfx.throwMatrix = NULL;
stop_sounds_from_source(obj->header.gfx.cameraToObject);
geo_remove_child(&obj->header.gfx.node);
geo_add_child(&gObjParentGraphNode, &obj->header.gfx.node);
obj->header.gfx.node.flags &= ~GRAPH_RENDER_BILLBOARD;
obj->header.gfx.node.flags &= ~GRAPH_RENDER_CYLBOARD;
@ -208,31 +203,6 @@ struct Object *allocate_object(struct ObjectNode *objList) {
s32 i;
struct Object *obj = try_allocate_object(objList, &gFreeObjectList);
// The object list is full if the newly created pointer is NULL.
// If this happens, we first attempt to unload unimportant objects
// in order to finish allocating the object.
if (obj == NULL) {
// Look for an unimportant object to kick out.
struct Object *unimportantObj = find_unimportant_object();
// If no unimportant object exists, then the object pool is exhausted.
if (unimportantObj == NULL) {
// We've met with a terrible fate.
while (TRUE) {
}
} else {
// If an unimportant object does exist, unload it and take its slot.
unload_object(unimportantObj);
obj = try_allocate_object(objList, &gFreeObjectList);
if (gCurrentObject == obj) {
//! Uh oh, the unimportant object was in the middle of
// updating! This could cause some interesting logic errors,
// but I don't know of any unimportant objects that spawn
// other objects.
}
}
}
// Initialize object fields
obj->activeFlags = ACTIVE_FLAG_ACTIVE | ACTIVE_FLAG_UNK8;

View File

@ -1,316 +1,4 @@
#include <PR/ultratypes.h>
#include "debug_utils.h"
#include "gd_memory.h"
#include "renderer.h"
/**
* @file gd_memory.c
*
* This file contains the functions need to manage allocation in
* goddard's heap. However, the actual, useable allocation functions
* are `gd_malloc()`, `gd_malloc_perm()`, and `gd_malloc_temp()`, as
* well as `gd_free()`. This file is for managing the underlying memory
* block lists.
*/
/* bss */
static struct GMemBlock *sFreeBlockListHead;
static struct GMemBlock *sUsedBlockListHead;
static struct GMemBlock *sEmptyBlockListHead;
/* Forward Declarations */
void empty_mem_block(struct GMemBlock *);
struct GMemBlock *into_free_memblock(struct GMemBlock *);
struct GMemBlock *make_mem_block(u32, u8);
u32 print_list_stats(struct GMemBlock *, s32, s32);
/**
* Empty a `GMemBlock` into a default state. This empty block
* doesn't point to any data, nor does it have any size. The
* block is removed from whatever list is was in, and is added
* to the empty block list.
*/
void empty_mem_block(struct GMemBlock *block) {
if (block->next != NULL) {
block->next->prev = block->prev;
}
if (block->prev != NULL) {
block->prev->next = block->next;
}
switch (block->blockType) {
case G_MEM_BLOCK_FREE:
if (block->prev == NULL) {
sFreeBlockListHead = block->next;
}
break;
case G_MEM_BLOCK_USED:
if (block->prev == NULL) {
sUsedBlockListHead = block->next;
}
break;
}
block->next = sEmptyBlockListHead;
if (block->next != NULL) {
sEmptyBlockListHead->prev = block;
}
sEmptyBlockListHead = block;
block->prev = NULL;
block->ptr = NULL;
block->size = 0;
}
/**
* Transform a `GMemBlock` into a free block that points to memory available
* for allocation.
*
* @returns pointer to the free `GMemBlock` */
struct GMemBlock *into_free_memblock(struct GMemBlock *block) {
struct GMemBlock *freeBlock;
void *ptr;
u8 permanence;
u32 space;
ptr = block->ptr;
space = block->size;
permanence = block->permFlag;
empty_mem_block(block);
freeBlock = make_mem_block(G_MEM_BLOCK_FREE, permanence);
freeBlock->ptr = ptr;
freeBlock->size = space;
freeBlock->permFlag = permanence;
return freeBlock;
}
/**
* Allocate a new `GMemBlock` structure of the given type and permanence.
* It does not assign any heap space to the new block.
*
* @param blockType either `G_MEM_BLOCK_FREE` or `G_MEM_BLOCK_USED`
* @param permFlag some sort of permanence value, where setting one the upper
* four bits imply a permanent block, while setting one the lower
* four bits imply a temporary block
* @returns a pointer to the new `GMemBlock`
*/
struct GMemBlock *make_mem_block(u32 blockType, u8 permFlag) {
struct GMemBlock *newMemBlock;
if (sEmptyBlockListHead == NULL) {
sEmptyBlockListHead = (struct GMemBlock *) gd_allocblock(sizeof(struct GMemBlock));
if (sEmptyBlockListHead == NULL) {
fatal_printf("MakeMemBlock() unable to allocate");
}
sEmptyBlockListHead->next = NULL;
sEmptyBlockListHead->prev = NULL;
}
newMemBlock = sEmptyBlockListHead;
if ((sEmptyBlockListHead = newMemBlock->next) != NULL) {
newMemBlock->next->prev = NULL;
}
switch (blockType) {
case G_MEM_BLOCK_FREE:
newMemBlock->next = sFreeBlockListHead;
if (newMemBlock->next != NULL) {
sFreeBlockListHead->prev = newMemBlock;
}
sFreeBlockListHead = newMemBlock;
break;
case G_MEM_BLOCK_USED:
newMemBlock->next = sUsedBlockListHead;
if (newMemBlock->next != NULL) {
sUsedBlockListHead->prev = newMemBlock;
}
sUsedBlockListHead = newMemBlock;
break;
default:
fatal_printf("unkown memblock type");
}
newMemBlock->prev = NULL;
newMemBlock->blockType = (u8) blockType;
newMemBlock->permFlag = permFlag;
return newMemBlock;
}
/**
* Free memory allocated on the goddard heap.
*
* @param ptr pointer to heap allocated memory
* @returns size of memory freed
* @retval 0 `ptr` did not point to a valid memory block
*/
u32 gd_free_mem(void *ptr) {
register struct GMemBlock *curBlock;
u32 bytesFreed;
register u8 *targetBlock = ptr;
for (curBlock = sUsedBlockListHead; curBlock != NULL; curBlock = curBlock->next) {
if (targetBlock == curBlock->ptr) {
bytesFreed = curBlock->size;
into_free_memblock(curBlock);
return bytesFreed;
}
}
fatal_printf("Free() Not a valid memory block");
return 0;
}
/**
* Request a pointer to goddard heap memory of at least `size` and
* of the same `permanence`.
*
* @return pointer to heap
* @retval NULL could not fulfill the request
*/
void *gd_request_mem(u32 size, u8 permanence) {
struct GMemBlock *foundBlock = NULL;
struct GMemBlock *curBlock;
struct GMemBlock *newBlock;
newBlock = make_mem_block(G_MEM_BLOCK_USED, permanence);
curBlock = sFreeBlockListHead;
while (curBlock != NULL) {
if (curBlock->permFlag & permanence) {
if (curBlock->size == size) {
foundBlock = curBlock;
break;
} else {
if (curBlock->size > size) {
if (foundBlock != NULL) { /* find closest sized block */
if (curBlock->size < foundBlock->size) {
foundBlock = curBlock;
}
} else {
foundBlock = curBlock;
}
}
}
}
curBlock = curBlock->next;
}
if (foundBlock == NULL) {
return NULL;
}
if (foundBlock->size > size) { /* split free block */
newBlock->ptr = foundBlock->ptr;
newBlock->size = size;
foundBlock->size -= size;
foundBlock->ptr += size;
} else if (foundBlock->size == size) { /* recycle whole free block */
newBlock->ptr = foundBlock->ptr;
newBlock->size = size;
empty_mem_block(foundBlock);
}
return newBlock->ptr;
}
/**
* Add memory of `size` at `addr` to the goddard heap for later allocation.
*
* @returns `GMemBlock` that contains info about the new heap memory
*/
struct GMemBlock *gd_add_mem_to_heap(u32 size, void *addr, u8 permanence) {
struct GMemBlock *newBlock;
/* eight-byte align the new block's data stats */
size = (size - 8) & ~7;
addr = (void *)(((uintptr_t) addr + 8) & ~7);
newBlock = make_mem_block(G_MEM_BLOCK_FREE, permanence);
newBlock->ptr = addr;
newBlock->size = size;
return newBlock;
}
/**
* NULL the various `GMemBlock` list heads
*/
void init_mem_block_lists(void) {
sFreeBlockListHead = NULL;
sUsedBlockListHead = NULL;
sEmptyBlockListHead = NULL;
}
/**
* Print information (size, entries) about the `GMemBlock` list. It can print
* information for individual blocks as well as summary info for the entry list.
*
* @param block `GMemBlock` to start reading the list
* @param printBlockInfo If `TRUE`, print information about every block
* in the list
* @param permanence Limit info printed to blocks with this permanence
* @returns number of entries
*/
u32 print_list_stats(struct GMemBlock *block, s32 printBlockInfo, s32 permanence) {
u32 entries = 0;
u32 totalSize = 0;
while (block != NULL) {
if (block->permFlag & permanence) {
entries++;
if (printBlockInfo) {
gd_printf(" %6.2fk (%d bytes)\n",
(f32) block->size / 1024.0, //? 1024.0f
block->size);
}
totalSize += block->size;
}
block = block->next;
}
gd_printf("Total %6.2fk (%d bytes) in %d entries\n",
(f32) totalSize / 1024.0, //? 1024.0f
totalSize, entries);
return entries;
}
/**
* Print summary information about all used, free, and empty
* `GMemBlock`s.
*/
void mem_stats(void) {
struct GMemBlock *list;
gd_printf("Perm Used blocks:\n");
list = sUsedBlockListHead;
print_list_stats(list, FALSE, PERM_G_MEM_BLOCK);
gd_printf("\n");
gd_printf("Perm Free blocks:\n");
list = sFreeBlockListHead;
print_list_stats(list, FALSE, PERM_G_MEM_BLOCK);
gd_printf("\n");
gd_printf("Temp Used blocks:\n");
list = sUsedBlockListHead;
print_list_stats(list, FALSE, TEMP_G_MEM_BLOCK);
gd_printf("\n");
gd_printf("Temp Free blocks:\n");
list = sFreeBlockListHead;
print_list_stats(list, FALSE, TEMP_G_MEM_BLOCK);
gd_printf("\n");
gd_printf("Empty blocks:\n");
list = sEmptyBlockListHead;
print_list_stats(list, FALSE, PERM_G_MEM_BLOCK | TEMP_G_MEM_BLOCK);
}
/*

View File

@ -111,8 +111,6 @@ static struct ObjGadget *sTimerGadgets[GD_NUM_TIMERS]; // @ 801BAEA8
static u32 D_801BAF28; // RAM addr offset?
static s16 D_801BAF30[13][8]; // [[s16; 8]; 13]? vert indices?
static u32 unref_801bb000[3];
static u8 *sMemBlockPoolBase; // @ 801BB00C
static u32 sAllocMemory; // @ 801BB010; malloc-ed bytes
static u32 unref_801bb014;
static s32 D_801BB018;
static s32 D_801BB01C;
@ -179,6 +177,9 @@ static OSIoMesg D_801BE980;
static struct ObjView *D_801BE994; // store if View flag 0x40 set
#endif
static void *(*sAllocFn)(u32 size);
static void (*sFreeFn)(void *ptr);
// data
static u32 unref_801a8670 = 0;
static s32 D_801A8674 = 0;
@ -190,8 +191,6 @@ static f32 sDynamicsTime = 0.0f; // @ 801A8688
static f32 sDLGenTime = 0.0f; // @ 801A868C
static f32 sRCPTime = 0.0f; // @ 801A8690
static f32 sTimeScaleFactor = 1.0f; // @ D_801A8694
static u32 sMemBlockPoolSize = 1; // @ 801A8698
static s32 sMemBlockPoolUsed = 0; // @ 801A869C
static s32 D_801A86A0 = 0;
static struct GdTimer *D_801A86A4 = NULL; // timer for dlgen, dynamics, or rcp
static struct GdTimer *D_801A86A8 = NULL; // timer for dlgen, dynamics, or rcp
@ -461,11 +460,11 @@ static Gfx gd_dl_sparkle[] = {
gsSPClearGeometryMode(G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR),
gsDPSetRenderMode(G_RM_AA_ZB_TEX_EDGE, G_RM_NOOP2),
gsSPTexture(0x8000, 0x8000, 0, G_TX_RENDERTILE, G_ON),
gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD,
gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD,
G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD),
gsDPLoadSync(),
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, 32 * 32 - 1, CALC_DXT(32, G_IM_SIZ_16b_BYTES)),
gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 8, 0, G_TX_RENDERTILE, 0, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD,
gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 8, 0, G_TX_RENDERTILE, 0, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD,
G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD),
gsDPSetTileSize(0, 0, 0, (32 - 1) << G_TEXTURE_IMAGE_FRAC, (32 - 1) << G_TEXTURE_IMAGE_FRAC),
gsSPVertex(gd_vertex_sparkle, 4, 0),
@ -642,7 +641,7 @@ static Gfx gd_dl_mario_face_shine[] = {
gsDPSetTexturePersp(G_TP_PERSP),
gsDPSetTextureFilter(G_TF_BILERP),
gsDPSetCombineMode(G_CC_HILITERGBA, G_CC_HILITERGBA),
gsDPLoadTextureBlock(gd_texture_mario_face_shine, G_IM_FMT_IA, G_IM_SIZ_8b, 32, 32, 0,
gsDPLoadTextureBlock(gd_texture_mario_face_shine, G_IM_FMT_IA, G_IM_SIZ_8b, 32, 32, 0,
G_TX_WRAP | G_TX_NOMIRROR, G_TX_WRAP | G_TX_NOMIRROR, 5, 5, G_TX_NOLOD, G_TX_NOLOD),
gsDPPipeSync(),
gsSPEndDisplayList(),
@ -741,7 +740,7 @@ void reset_cur_dl_indices(void);
// TODO: make a gddl_num_t?
u32 get_alloc_mem_amt(void) {
return sAllocMemory;
return 0;
}
s32 gd_get_ostime(void) {
@ -937,45 +936,12 @@ void gd_exit(UNUSED s32 code) {
/* 24A1D4 -> 24A220; orig name: func_8019BA04 */
void gd_free(void *ptr) {
sAllocMemory -= gd_free_mem(ptr);
}
/* 24A220 -> 24A318 */
void *gd_allocblock(u32 size) {
void *block; // 1c
size = ALIGN(size, 8);
if ((sMemBlockPoolUsed + size) > sMemBlockPoolSize) {
gd_printf("gd_allocblock(): Failed request: %dk (%d bytes)\n", size / 1024, size);
gd_printf("gd_allocblock(): Heap usage: %dk (%d bytes) \n", sMemBlockPoolUsed / 1024,
sMemBlockPoolUsed);
print_all_memtrackers();
mem_stats();
fatal_printf("exit");
}
block = sMemBlockPoolBase + sMemBlockPoolUsed;
sMemBlockPoolUsed += size;
return block;
sFreeFn(ptr);
}
/* 24A318 -> 24A3E8 */
void *gd_malloc(u32 size, u8 perm) {
void *ptr; // 1c
size = ALIGN(size, 8);
ptr = gd_request_mem(size, perm);
if (ptr == NULL) {
gd_printf("gd_malloc(): Failed request: %dk (%d bytes)\n", size / 1024, size);
gd_printf("gd_malloc(): Heap usage: %dk (%d bytes) \n", sAllocMemory / 1024, sAllocMemory);
print_all_memtrackers();
mem_stats();
return NULL;
}
sAllocMemory += size;
return ptr;
return sAllocFn(size);
}
/* 24A3E8 -> 24A420; orig name: func_8019BC18 */
@ -1100,26 +1066,10 @@ void Unknown8019C288(s32 stickX, s32 stickY) {
ctrl->stickYf = (f32)(stickY / 2);
}
/* 24AAA8 -> 24AAE0; orig name: func_8019C2D8 */
void gd_add_to_heap(void *addr, u32 size) {
// TODO: is this `1` for permanence special?
gd_add_mem_to_heap(size, addr, 1);
}
/* 24AAE0 -> 24AB7C */
void gdm_init(void *blockpool, u32 size) {
UNUSED u32 pad;
void gdm_init(void *(*allocFn)(u32 size), void (*freeFn)(void *addr)) {
add_to_stacktrace("gdm_init");
// Align downwards?
size = (size - 8) & ~7;
// Align to next double word boundry?
blockpool = (void *) (((uintptr_t) blockpool + 8) & ~7);
sMemBlockPoolBase = blockpool;
sMemBlockPoolSize = size;
sMemBlockPoolUsed = 0;
sAllocMemory = 0;
init_mem_block_lists();
sAllocFn = allocFn;
sFreeFn = freeFn;
gd_reset_sfx();
imout();
}
@ -2301,7 +2251,7 @@ void parse_p1_controller(void) {
u8 *prevGdCtrlBytes; // 28
f32 aspect = GFX_DIMENSIONS_ASPECT_RATIO;
aspect *= 0.75;
gdctrl = &gGdCtrl;
gdCtrlBytes = (u8 *) gdctrl;
prevGdCtrlBytes = (u8 *) gdctrl->prevFrame;
@ -3076,9 +3026,6 @@ void gd_init(void) {
s8 *data; // 2c
add_to_stacktrace("gd_init");
i = (u32)(sMemBlockPoolSize - DOUBLE_SIZE_ON_64_BIT(0x3E800));
data = gd_allocblock(i);
gd_add_mem_to_heap(i, data, 0x10);
D_801BB184 = (u16) 0xff;
D_801A867C = 0;
D_801A8680 = 0;
@ -3400,7 +3347,7 @@ void gd_put_sprite(u16 *sprite, s32 x, s32 y, s32 wx, s32 wy) {
// Must be game screen aspect ratio, not GFX window aspect ratio
f32 aspect = ((float) SCREEN_WIDTH) / ((float) SCREEN_HEIGHT ) * 0.75;
x *= aspect;
gSPDisplayList(next_gfx(), osVirtualToPhysical(gd_dl_sprite_start_tex_block));
for (r = 0; r < wy; r += 32) {
for (c = 0; c < wx; c += 32) {

View File

@ -42,8 +42,7 @@ void *gd_malloc(u32 size, u8 perm);
void *gd_malloc_perm(u32 size);
void *gd_malloc_temp(u32 size);
void func_8019BD0C(s32 dlNum, s32 gfxIdx);
void gd_add_to_heap(void *addr, u32 size);
void gdm_init(void *blockpool, u32 size);
void gdm_init(void *(*allocFn)(u32 size), void (*freeFn)(void *ptr));
void gdm_setup(void);
void gdm_maketestdl(s32 id);
void gd_vblank(void);

View File

@ -23,6 +23,7 @@
#include <string.h>
#include "moon/utils/moon-gfx.h"
#include "gfx_dimensions.h"
#include "moon/mod-engine/models/mod-model.h"
/**
* @file file_select.c
@ -601,10 +602,9 @@ void copy_action_file_button(struct Object *copyButton, s32 copyFileButtonID) {
sFadeOutText = TRUE;
sMainMenuTimer = 0;
save_file_copy(sSelectedFileIndex, copyFileButtonID - MENU_BUTTON_COPY_MIN);
sMainMenuButtons[copyFileButtonID]->header.gfx.sharedChild =
gLoadedGraphNodes[MODEL_MAIN_MENU_MARIO_SAVE_BUTTON_FADE];
sMainMenuButtons[copyFileButtonID - MENU_BUTTON_COPY_MIN]->header.gfx.sharedChild =
gLoadedGraphNodes[MODEL_MAIN_MENU_MARIO_SAVE_BUTTON_FADE];
sMainMenuButtons[copyFileButtonID]->header.gfx.sharedChild = get_graph_node(MODEL_MAIN_MENU_MARIO_SAVE_BUTTON_FADE);
sMainMenuButtons[copyFileButtonID - MENU_BUTTON_COPY_MIN]->header.gfx.sharedChild = get_graph_node(MODEL_MAIN_MENU_MARIO_SAVE_BUTTON_FADE);
} else {
// If clicked in a existing save file, play buzz sound
if (MENU_BUTTON_COPY_FILE_A + sSelectedFileIndex == copyFileButtonID) {
@ -1830,10 +1830,10 @@ void print_erase_menu_prompt(s16 x, s16 y) {
sFadeOutText = TRUE;
sMainMenuTimer = 0;
save_file_erase(sSelectedFileIndex);
sMainMenuButtons[MENU_BUTTON_ERASE_MIN + sSelectedFileIndex]->header.gfx.sharedChild =
gLoadedGraphNodes[MODEL_MAIN_MENU_MARIO_NEW_BUTTON_FADE];
sMainMenuButtons[sSelectedFileIndex]->header.gfx.sharedChild =
gLoadedGraphNodes[MODEL_MAIN_MENU_MARIO_NEW_BUTTON_FADE];
sMainMenuButtons[MENU_BUTTON_ERASE_MIN + sSelectedFileIndex]->header.gfx.sharedChild = get_graph_node(MODEL_MAIN_MENU_MARIO_NEW_BUTTON_FADE);
sMainMenuButtons[sSelectedFileIndex]->header.gfx.sharedChild = get_graph_node(MODEL_MAIN_MENU_MARIO_NEW_BUTTON_FADE);
sEraseYesNoHoverState = MENU_ERASE_HOVER_NONE;
// ..and is hovering "NO", return back to main phase
} else if (sEraseYesNoHoverState == MENU_ERASE_HOVER_NO) {

View File

@ -0,0 +1,25 @@
#include "mod-model.h"
#include "moon/mod-engine/interfaces/file-entry.h"
#include "moon/mod-engine/interfaces/bit-module.h"
#include "types.h"
#include <string>
#include <vector>
#include <iostream>
#include <map>
using namespace std;
map<int, GraphNode*> loadedGraphNodes;
extern "C"{
void bind_graph_node(int modelId, struct GraphNode *graphNode){
loadedGraphNodes[modelId] = graphNode;
// cout << "Binding model with id " << modelId << endl;
}
struct GraphNode * get_graph_node(int modelId){
if(loadedGraphNodes.find(modelId) == loadedGraphNodes.end()) return NULL;
// cout << "Loading model with id " << modelId << endl;
return loadedGraphNodes[modelId];
}
}

View File

@ -0,0 +1,23 @@
#ifndef ModEngineModelModule
#define ModEngineModelModule
#ifdef __cplusplus
#include <string>
namespace Moon {
}
namespace MoonInternal {
void setupModuleEngine( std::string state );
}
#else
#include "types.h"
void bind_graph_node(int modelId, struct GraphNode *graphNode);
struct GraphNode * get_graph_node(int modelId);
#endif
#endif

View File

@ -188,8 +188,8 @@ static void on_anim_frame(double time) {
void main_func(char *argv[]) {
static u64 pool[0x165000/8 / 4 * sizeof(void *)];
main_pool_init(pool, pool + sizeof(pool) / sizeof(pool[0]));
main_pool_init();
gGfxAllocOnlyPool = alloc_only_pool_init();
gEffectsMemoryPool = mem_pool_init(0x4000, MEMORY_POOL_LEFT);
const char *gamedir = gCLIOpts.GameDir[0] ? gCLIOpts.GameDir : FS_BASEDIR;