Memory management improvements

Log errors on allocation failure
NULL check all display list allocations
Fix reading a freed string
This commit is contained in:
MysterD 2022-04-06 18:10:22 -07:00
parent a58130b9f6
commit b5b9d509e8
17 changed files with 73 additions and 8 deletions

View file

@ -49,10 +49,10 @@ int dynos_packs_get_count(void) {
}
const char* dynos_packs_get(s32 index) {
std::string path = DynOS_Gfx_GetPacks()[index]->mPath;
const char* path = DynOS_Gfx_GetPacks()[index]->mPath.c_str();
// extract basename
const char* cpath = path.c_str();
const char* cpath = path;
const char* ctoken = cpath;
while (*ctoken != '\0') {
if (*ctoken == '/' || *ctoken == '\\') {

View file

@ -523,6 +523,7 @@ static void load_environmental_regions(s16 **data) {
numRegions = *(*data)++;
if (numRegions > 20) {
numRegions = 20;
}
for (i = 0; i < numRegions; i++) {

View file

@ -1523,6 +1523,7 @@ Gfx *geo_bits_bowser_coloring(s32 run, struct GraphNode *node, UNUSED s32 a2) {
else
sp20->fnNode.node.flags = (sp20->fnNode.node.flags & 0xFF) | (GRAPH_NODE_TYPE_FUNCTIONAL | GRAPH_NODE_TYPE_400);
sp28 = sp2C = alloc_display_list(2 * sizeof(Gfx));
if (sp28 == NULL) { return NULL; }
if (sp24->oBowserUnk1B2 != 0) {
gSPClearGeometryMode(sp28++, G_LIGHTING);

View file

@ -524,6 +524,7 @@ Gfx *envfx_update_bubble_particles(s32 mode, UNUSED Vec3s marioPos, Vec3s camFro
for (i = 0; i < sBubbleParticleMaxCount; i += 5) {
Vtx *interpolatedVertBuf = alloc_display_list(15 * sizeof(Vtx));
if (interpolatedVertBuf == NULL) { continue; }
s32 j, k;
gDPPipeSync(sGfxCursor++);
envfx_set_bubble_texture(mode, i);

View file

@ -370,7 +370,7 @@ void append_snowflake_vertex_buffer(Gfx *gfx, s32 index, Vec3s vertex1, Vec3s ve
Vtx *vertBufInterpolated = (Vtx *) alloc_display_list(15 * sizeof(Vtx));
Vtx *v;
if (vertBuf == NULL) {
if (vertBuf == NULL || vertBufInterpolated == NULL) {
return;
}

View file

@ -196,6 +196,7 @@ Gfx *geo_exec_cake_end_screen(s32 callContext, struct GraphNode *node, UNUSED f3
if (callContext == GEO_CONTEXT_RENDER) {
displayList = alloc_display_list(3 * sizeof(*displayList));
if (displayList == NULL) { return NULL; }
displayListHead = displayList;
generatedNode->fnNode.node.flags = (generatedNode->fnNode.node.flags & 0xFF) | 0x100;

View file

@ -71,6 +71,7 @@ static Gfx *sPowerMeterDisplayListPos;
void patch_interpolated_hud(void) {
if (sPowerMeterDisplayListPos != NULL) {
Mtx *mtx = alloc_display_list(sizeof(Mtx));
if (mtx == NULL) { return; }
guTranslate(mtx, (f32) sPowerMeterHUD.x, (f32) sPowerMeterHUD.y, 0);
gSPMatrix(sPowerMeterDisplayListPos, VIRTUAL_TO_PHYSICAL(mtx),
G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_PUSH);

View file

@ -142,24 +142,29 @@ void patch_interpolated_dialog(void) {
if (sInterpolatedDialogOffsetPos != NULL) {
matrix = (Mtx *) alloc_display_list(sizeof(Mtx));
if (matrix == NULL) { return; }
guTranslate(matrix, 0, sInterpolatedDialogOffset, 0);
gSPMatrix(sInterpolatedDialogOffsetPos, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH);
sInterpolatedDialogOffsetPos = NULL;
}
if (sInterpolatedDialogRotationPos != NULL) {
matrix = (Mtx *) alloc_display_list(sizeof(Mtx));
if (matrix == NULL) { return; }
guScale(matrix, 1.0 / sInterpolatedDialogScale, 1.0 / sInterpolatedDialogScale, 1.0f);
gSPMatrix(sInterpolatedDialogRotationPos++, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH);
matrix = (Mtx *) alloc_display_list(sizeof(Mtx));
if (matrix == NULL) { return; }
guRotate(matrix, sInterpolatedDialogRotation * 4.0f, 0, 0, 1.0f);
gSPMatrix(sInterpolatedDialogRotationPos, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH);
sInterpolatedDialogRotationPos = NULL;
}
if (sInterpolatedDialogZoomPos != NULL) {
matrix = (Mtx *) alloc_display_list(sizeof(Mtx));
if (matrix == NULL) { return; }
guTranslate(matrix, 65.0 - (65.0 / sInterpolatedDialogScale), (40.0 / sInterpolatedDialogScale) - 40, 0);
gSPMatrix(sInterpolatedDialogZoomPos++, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH);
matrix = (Mtx *) alloc_display_list(sizeof(Mtx));
if (matrix == NULL) { return; }
guScale(matrix, 1.0 / sInterpolatedDialogScale, 1.0 / sInterpolatedDialogScale, 1.0f);
gSPMatrix(sInterpolatedDialogZoomPos, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH);
sInterpolatedDialogZoomPos = NULL;

View file

@ -391,10 +391,12 @@ static Gfx *make_gfx_mario_alpha(struct GraphNodeGenerated *node, s16 alpha) {
if (alpha == 255) {
node->fnNode.node.flags = (node->fnNode.node.flags & 0xFF) | (LAYER_OPAQUE << 8);
gfxHead = alloc_display_list(2 * sizeof(*gfxHead));
if (gfxHead == NULL) { return NULL; }
gfx = gfxHead;
} else {
node->fnNode.node.flags = (node->fnNode.node.flags & 0xFF) | (LAYER_TRANSPARENT << 8);
gfxHead = alloc_display_list(3 * sizeof(*gfxHead));
if (gfxHead == NULL) { return NULL; }
gfx = gfxHead;
gDPSetAlphaCompare(gfx++, G_AC_DITHER);
}
@ -792,6 +794,7 @@ Gfx* geo_mirror_mario_backface_culling(s32 callContext, struct GraphNode* node,
if (callContext == GEO_CONTEXT_RENDER && isMirrorMario) {
gfx = alloc_display_list(3 * sizeof(*gfx));
if (gfx == NULL) { return NULL; }
if ((asGenerated->parameter & 0x01) == 0) {
gSPClearGeometryMode(&gfx[0], G_CULL_BACK);
@ -822,6 +825,7 @@ Gfx* geo_mario_set_player_colors(s32 callContext, struct GraphNode* node, UNUSED
// extra players get last color
if (colorIndex >= gNumPlayerColors) colorIndex = gNumPlayerColors - 1;
gfx = alloc_display_list(5 * sizeof(*gfx));
if (gfx == NULL) { return NULL; }
// put the player colors into lights 3, 4, 5, 6
// they will be later copied to lights 1, 2 with gsSPCopyLightEXT
gSPLight(gfx + 0, &gPlayerColors[colorIndex].pants.l, 3);
@ -855,6 +859,7 @@ Gfx* geo_mario_cap_display_list(s32 callContext, struct GraphNode* node, UNUSED
if (character->capEnemyGfx != NULL) { dpLength++; }
if (character->capEnemyDecalGfx != NULL) { dpLength++; }
Gfx* gfx = alloc_display_list(dpLength * sizeof(*gfx));
if (gfx == NULL) { return NULL; }
Gfx* onGfx = gfx;
// put the player colors into lights 3, 4, 5, 6

View file

@ -12,6 +12,7 @@
#include "memory.h"
#include "segment_symbols.h"
#include "segments.h"
#include "pc/debuglog.h"
// round up to the next multiple
#define ALIGN4(val) (((val) + 0x3) & ~0x3)
@ -132,6 +133,9 @@ void *main_pool_alloc(u32 size, u32 side) {
addr = (u8 *) sPoolListHeadR + 16;
}
}
if (addr == NULL) {
LOG_ERROR("Main pool alloc failed!");
}
return addr;
}
@ -177,6 +181,9 @@ void *main_pool_realloc(void *addr, u32 size) {
main_pool_free(addr);
newAddr = main_pool_alloc(size, MEMORY_POOL_LEFT);
}
if (addr == NULL) {
LOG_ERROR("Main pool realloc failed!");
}
return newAddr;
}
@ -259,6 +266,9 @@ struct AllocOnlyPool *alloc_only_pool_init(u32 size, u32 side) {
subPool->startPtr = (u8 *) addr + sizeof(struct AllocOnlyPool);
subPool->freePtr = (u8 *) addr + sizeof(struct AllocOnlyPool);
}
if (addr == NULL) {
LOG_ERROR("Alloc only pool init failed!");
}
return subPool;
}
@ -275,6 +285,9 @@ void *alloc_only_pool_alloc(struct AllocOnlyPool *pool, s32 size) {
pool->freePtr += size;
pool->usedSpace += size;
}
if (addr == NULL) {
LOG_ERROR("Alloc only pool alloc failed!");
}
return addr;
}
@ -292,6 +305,9 @@ struct AllocOnlyPool *alloc_only_pool_resize(struct AllocOnlyPool *pool, u32 siz
if (newPool != NULL) {
pool->totalSpace = size;
}
if (newPool == NULL) {
LOG_ERROR("Alloc only pool realloc failed!");
}
return newPool;
}
@ -318,6 +334,9 @@ struct MemoryPool *mem_pool_init(u32 size, u32 side) {
block->next = NULL;
block->size = pool->totalSpace;
}
if (addr == NULL) {
LOG_ERROR("Mem pool init failed!");
}
return pool;
}
@ -345,6 +364,9 @@ void *mem_pool_alloc(struct MemoryPool *pool, u32 size) {
}
freeBlock = freeBlock->next;
}
if (addr == NULL) {
LOG_ERROR("Mem pool alloc failed!");
}
return addr;
}
@ -398,6 +420,7 @@ void *alloc_display_list(u32 size) {
gGfxPoolEnd -= size;
ptr = gGfxPoolEnd;
} else {
LOG_ERROR("Failed to alloc display list!");
}
return ptr;
}

View file

@ -111,6 +111,7 @@ Gfx UNUSED *geo_obj_transparency_something(s32 callContext, struct GraphNode *no
}
gfxHead = alloc_display_list(3 * sizeof(Gfx));
if (gfxHead == NULL) { return NULL; }
gfx = gfxHead;
obj->header.gfx.node.flags =
(obj->header.gfx.node.flags & 0xFF) | (GRAPH_NODE_TYPE_FUNCTIONAL | GRAPH_NODE_TYPE_400);

View file

@ -81,6 +81,7 @@ Gfx *geo_update_layer_transparency(s32 callContext, struct GraphNode *node, UNUS
objectOpacity = objectGraphNode->oOpacity;
dlStart = alloc_display_list(sizeof(Gfx) * 3);
if (dlStart == NULL) { return NULL; }
dlHead = dlStart;

View file

@ -961,7 +961,7 @@ Gfx *painting_model_view_transform(struct Painting *painting) {
Gfx *dlist = alloc_display_list(5 * sizeof(Gfx));
Gfx *gfx = dlist;
if (rotX == NULL || rotY == NULL || translate == NULL || dlist == NULL) {
if (rotX == NULL || rotY == NULL || translate == NULL || scale == NULL || dlist == NULL) {
return NULL;
}

View file

@ -278,6 +278,7 @@ static void geo_process_master_list(struct GraphNodeMasterList *node) {
static void geo_process_ortho_projection(struct GraphNodeOrthoProjection *node) {
if (node->node.children != NULL) {
Mtx *mtx = alloc_display_list(sizeof(*mtx));
if (mtx == NULL) { return; }
f32 left = (gCurGraphNodeRoot->x - gCurGraphNodeRoot->width) / 2.0f * node->scale;
f32 right = (gCurGraphNodeRoot->x + gCurGraphNodeRoot->width) / 2.0f * node->scale;
f32 top = (gCurGraphNodeRoot->y - gCurGraphNodeRoot->height) / 2.0f * node->scale;
@ -302,6 +303,7 @@ static void geo_process_perspective(struct GraphNodePerspective *node) {
u16 perspNorm;
Mtx *mtxInterpolated = alloc_display_list(sizeof(*mtxInterpolated));
Mtx *mtx = alloc_display_list(sizeof(*mtx));
if (mtx == NULL || mtxInterpolated == NULL) { return; }
f32 fovInterpolated;
#ifdef VERSION_EU
@ -413,6 +415,7 @@ static void geo_process_camera(struct GraphNodeCamera *node) {
Mtx *rollMtx = alloc_display_list(sizeof(*rollMtx));
Mtx *mtx = alloc_display_list(sizeof(*mtx));
Mtx *mtxInterpolated = alloc_display_list(sizeof(*mtxInterpolated));
if (rollMtx == NULL || mtx == NULL || mtxInterpolated == NULL) { return; }
Vec3f posInterpolated;
Vec3f focusInterpolated;
@ -476,6 +479,7 @@ static void geo_process_translation_rotation(struct GraphNodeTranslationRotation
Vec3f translation;
Mtx *mtx = alloc_display_list(sizeof(*mtx));
Mtx *mtxInterpolated = alloc_display_list(sizeof(*mtxInterpolated));
if (mtx == NULL || mtxInterpolated == NULL) { return; }
vec3s_to_vec3f(translation, node->translation);
mtxf_rotate_zxy_and_translate(mtxf, translation, node->rotation);
@ -505,6 +509,7 @@ static void geo_process_translation(struct GraphNodeTranslation *node) {
Vec3f translation;
Mtx *mtx = alloc_display_list(sizeof(*mtx));
Mtx *mtxInterpolated = alloc_display_list(sizeof(*mtxInterpolated));
if (mtx == NULL || mtxInterpolated == NULL) { return; }
vec3s_to_vec3f(translation, node->translation);
mtxf_rotate_zxy_and_translate(mtxf, translation, gVec3sZero);
@ -533,6 +538,7 @@ static void geo_process_rotation(struct GraphNodeRotation *node) {
Mat4 mtxf;
Mtx *mtx = alloc_display_list(sizeof(*mtx));
Mtx *mtxInterpolated = alloc_display_list(sizeof(*mtxInterpolated));
if (mtx == NULL || mtxInterpolated == NULL) { return; }
Vec3s rotationInterpolated;
mtxf_rotate_zxy_and_translate(mtxf, gVec3fZero, node->rotation);
@ -568,6 +574,7 @@ static void geo_process_scale(struct GraphNodeScale *node) {
Vec3f scaleVec;
Mtx *mtx = alloc_display_list(sizeof(*mtx));
Mtx *mtxInterpolated = alloc_display_list(sizeof(*mtxInterpolated));
if (mtx == NULL || mtxInterpolated == NULL) { return; }
vec3f_set(scaleVec, node->scale, node->scale, node->scale);
mtxf_scale_vec3f(gMatStack[gMatStackIndex + 1], gMatStack[gMatStackIndex], scaleVec);
@ -596,6 +603,7 @@ static void geo_process_billboard(struct GraphNodeBillboard *node) {
Vec3f translation;
Mtx *mtx = alloc_display_list(sizeof(*mtx));
Mtx *mtxInterpolated = alloc_display_list(sizeof(*mtxInterpolated));
if (mtx == NULL || mtxInterpolated == NULL) { return; }
gMatStackIndex++;
vec3s_to_vec3f(translation, node->translation);
@ -706,6 +714,7 @@ static void geo_process_background(struct GraphNodeBackground *node) {
Gfx *gfxStart = alloc_display_list(sizeof(Gfx) * 8);
#endif
Gfx *gfx = gfxStart;
if (gfx == NULL) { return; }
gDPPipeSync(gfx++);
gDPSetCycleType(gfx++, G_CYC_FILL);
@ -776,6 +785,7 @@ static void geo_process_animated_part(struct GraphNodeAnimatedPart *node) {
Vec3f translationInterpolated;
Mtx *matrixPtr = alloc_display_list(sizeof(*matrixPtr));
Mtx *mtxInterpolated = alloc_display_list(sizeof(*mtxInterpolated));
if (matrixPtr == NULL || mtxInterpolated == NULL) { return; }
u16 *animAttribute = gCurrAnimAttribute;
u8 animType = gCurAnimType;
@ -945,6 +955,7 @@ static void geo_process_shadow(struct GraphNodeShadow *node) {
if (shadowListInterpolated != NULL && shadowList != NULL) {
mtx = alloc_display_list(sizeof(*mtx));
mtxInterpolated = alloc_display_list(sizeof(*mtxInterpolated));
if (mtx == NULL || mtxInterpolated == NULL) { return; }
gMatStackIndex++;
mtxf_translate(mtxf, shadowPos);
@ -1190,6 +1201,7 @@ static void geo_process_object(struct Object *node) {
if (obj_is_in_view(&node->header.gfx, gMatStack[gMatStackIndex])) {
Mtx *mtx = alloc_display_list(sizeof(*mtx));
Mtx *mtxInterpolated = alloc_display_list(sizeof(*mtxInterpolated));
if (mtx == NULL || mtxInterpolated == NULL) { return; }
mtxf_to_mtx(mtx, gMatStack[gMatStackIndex]);
gMatStackFixed[gMatStackIndex] = mtx;
@ -1244,6 +1256,7 @@ void geo_process_held_object(struct GraphNodeHeldObject *node) {
Vec3f translation;
Mtx *mtx = alloc_display_list(sizeof(*mtx));
Mtx *mtxInterpolated = alloc_display_list(sizeof(*mtxInterpolated));
if (mtx == NULL || mtxInterpolated == NULL) { return; }
Vec3f scaleInterpolated;
#ifdef F3DEX_GBI_2
@ -1442,11 +1455,13 @@ void geo_process_root(struct GraphNodeRoot *node, Vp *b, Vp *c, s32 clearColor)
if (node->node.flags & GRAPH_RENDER_ACTIVE) {
Mtx *initialMatrix;
Vp *viewport = alloc_display_list(sizeof(*viewport));
if (viewport == NULL) { return; }
Vp *viewportInterpolated = viewport;
gDisplayListHeap = alloc_only_pool_init(main_pool_available() - sizeof(struct AllocOnlyPool),
MEMORY_POOL_LEFT);
initialMatrix = alloc_display_list(sizeof(*initialMatrix));
if (initialMatrix == NULL) { return; }
gMatStackIndex = 0;
gCurAnimType = 0;
vec3s_set(viewport->vp.vtrans, node->x * 4, node->y * 4, 511);
@ -1454,6 +1469,7 @@ void geo_process_root(struct GraphNodeRoot *node, Vp *b, Vp *c, s32 clearColor)
if (b != NULL) {
clear_frame_buffer(clearColor);
viewportInterpolated = alloc_display_list(sizeof(*viewportInterpolated));
if (viewportInterpolated == NULL) { return; }
interpolate_vectors_s16(viewportInterpolated->vp.vtrans, sPrevViewport.vp.vtrans, b->vp.vtrans);
interpolate_vectors_s16(viewportInterpolated->vp.vscale, sPrevViewport.vp.vscale, b->vp.vscale);

View file

@ -64,6 +64,7 @@ static Vec3f sIntroScale;
void patch_title_screen_scales(void) {
if (sIntroScalePos != NULL) {
Mtx *scaleMat = alloc_display_list(sizeof(*scaleMat));
if (scaleMat == NULL) { return; }
guScale(scaleMat, sIntroScale[0], sIntroScale[1], sIntroScale[2]);
gSPMatrix(sIntroScalePos, scaleMat, G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_PUSH);
sIntroScalePos = NULL;
@ -94,6 +95,7 @@ Gfx *geo_title_screen(s32 state, struct GraphNode *sp54, UNUSED void *context) {
scaleMat = alloc_display_list(sizeof(*scaleMat));
dl = alloc_display_list(4 * sizeof(*dl));
dlIter = dl;
if (scaleMat == NULL || dl == NULL) { return NULL; }
// determine scale based on the frame counter
if (sIntroFrameCounter >= 0 && sIntroFrameCounter < INTRO_STEPS_ZOOM_IN) {
@ -152,6 +154,7 @@ Gfx *geo_intro_super_mario_64_logo(s32 state, struct GraphNode *node, UNUSED voi
graphNode->flags = (graphNode->flags & 0xFF) | (LAYER_OPAQUE << 8);
scaleMat = alloc_display_list(sizeof(*scaleMat));
dl = alloc_display_list(4 * sizeof(*dl));
if (scaleMat == NULL || dl == NULL) { return NULL; }
dlIter = dl;
// determine scale based on the frame counter
@ -200,6 +203,7 @@ Gfx *geo_intro_tm_copyright(s32 state, struct GraphNode *node, UNUSED void *cont
sTmCopyrightAlpha = 0;
} else if (state == 1) { // draw
dl = alloc_display_list(5 * sizeof(*dl));
if (dl == NULL) { return NULL; }
dlIter = dl;
gSPDisplayList(dlIter++, dl_proj_mtx_fullscreen);
gDPSetEnvColor(dlIter++, 255, 255, 255, sTmCopyrightAlpha);
@ -257,6 +261,7 @@ static Gfx *intro_backdrop_one_image(s32 index, s8 *backgroundTable) {
Mtx *mtx = alloc_display_list(sizeof(*mtx));
Gfx *displayList = alloc_display_list(36 * sizeof(*displayList));
if (mtx == NULL || displayList == NULL) { return NULL; }
Gfx *displayListIter = displayList;
const u8 *const *vIntroBgTable = segmented_to_virtual(textureTables[backgroundTable[index]]);
s32 i;
@ -299,6 +304,7 @@ Gfx *geo_intro_regular_backdrop(s32 state, struct GraphNode *node, UNUSED void *
if (state == 1) { // draw
dl = alloc_display_list(((num_tiles_h*3)+4) * sizeof(*dl));
if (dl == NULL) { return NULL; }
dlIter = dl;
graphNode->node.flags = (graphNode->node.flags & 0xFF) | (LAYER_OPAQUE << 8);
gSPDisplayList(dlIter++, &dl_proj_mtx_fullscreen);
@ -338,6 +344,7 @@ Gfx *geo_intro_gameover_backdrop(s32 state, struct GraphNode *node, UNUSED void
gameOverBackgroundTable[i] = INTRO_BACKGROUND_GAME_OVER;
} else { // draw
dl = alloc_display_list(((num_tiles_h*3)+4) * sizeof(*dl));
if (dl == NULL) { return NULL; }
dlIter = dl;
if (sGameOverTableIndex == -2) {
if (sGameOverFrameCounter == 180) {

View file

@ -378,12 +378,14 @@ s64 smlua_get_mod_variable(u16 modIndex, char* variable) {
return 0;
}
int prevTop = lua_gettop(L);
lua_getglobal(L, "_G"); // get global table
lua_getfield(L, LUA_REGISTRYINDEX, mod->relativePath); // get the file's "global" table
lua_remove(L, -2); // remove global table
s64 value = smlua_get_integer_field(-1, variable);
lua_settop(L, prevTop);
// push variable
return smlua_get_integer_field(-1, variable);
// return variable
return value;
}
///////////////////////////////////////////////////////////////////////////////////////////

View file

@ -156,7 +156,7 @@ static bool ns_discord_initialize(enum NetworkType networkType) {
if (!gDiscordInitialized) {
// set up discord params
struct DiscordCreateParams params;
struct DiscordCreateParams params = { 0 };
DiscordCreateParamsSetDefault(&params);
params.client_id = applicationId;
params.flags = DiscordCreateFlags_NoRequireDiscord;