Add bounds checking to instant warps, and make object collisions dynamic

in size
This commit is contained in:
MysterD 2023-06-15 20:50:05 -07:00
parent 5875a007f9
commit b8b7b568f1
4 changed files with 42 additions and 13 deletions

View File

@ -574,27 +574,40 @@ static void level_cmd_create_warp_node(void) {
} }
static void level_cmd_create_instant_warp(void) { static void level_cmd_create_instant_warp(void) {
s32 i; struct InstantWarp *warp = NULL;
struct InstantWarp *warp;
if (sCurrAreaIndex != -1) { if (sCurrAreaIndex != -1) {
if (gAreas[sCurrAreaIndex].instantWarps == NULL) { if (gAreas[sCurrAreaIndex].instantWarps == NULL) {
gAreas[sCurrAreaIndex].instantWarps = gAreas[sCurrAreaIndex].instantWarps =
dynamic_pool_alloc(gLevelPool, 4 * sizeof(struct InstantWarp)); dynamic_pool_alloc(gLevelPool, 4 * sizeof(struct InstantWarp));
for (i = INSTANT_WARP_INDEX_START; i < INSTANT_WARP_INDEX_STOP; i++) { for (s32 i = INSTANT_WARP_INDEX_START; i < INSTANT_WARP_INDEX_STOP; i++) {
gAreas[sCurrAreaIndex].instantWarps[i].id = 0; gAreas[sCurrAreaIndex].instantWarps[i].id = 0;
} }
} }
warp = gAreas[sCurrAreaIndex].instantWarps + CMD_GET(u8, 2); u8 warpIndex = CMD_GET(u8, 2);
if (warpIndex >= INSTANT_WARP_INDEX_STOP) {
LOG_ERROR("Instant warp index out of bounds: %u", warpIndex);
sCurrentCmd = CMD_NEXT;
return;
}
warp[0].id = 1; u8 areaIndex = CMD_GET(u8, 3);
warp[0].area = CMD_GET(u8, 3); if (areaIndex >= MAX_AREAS) {
LOG_ERROR("Instant warp area index out of bounds: %u", areaIndex);
sCurrentCmd = CMD_NEXT;
return;
}
warp[0].displacement[0] = CMD_GET(s16, 4); warp = &gAreas[sCurrAreaIndex].instantWarps[warpIndex];
warp[0].displacement[1] = CMD_GET(s16, 6);
warp[0].displacement[2] = CMD_GET(s16, 8); warp->id = 1;
warp->area = areaIndex;
warp->displacement[0] = CMD_GET(s16, 4);
warp->displacement[1] = CMD_GET(s16, 6);
warp->displacement[2] = CMD_GET(s16, 8);
} }
sCurrentCmd = CMD_NEXT; sCurrentCmd = CMD_NEXT;

View File

@ -756,7 +756,21 @@ void load_object_collision_model(void) {
if (!gCurrentObject) { return; } if (!gCurrentObject) { return; }
if (gCurrentObject->collisionData == NULL) { return; } if (gCurrentObject->collisionData == NULL) { return; }
s16 vertexData[600]; s32 numVertices = *gCurrentObject->collisionData;
if (numVertices <= 0) {
LOG_ERROR("Object collisions had invalid vertex count");
return;
}
static s32 sVertexDataCount = 0;
static s16* sVertexData = NULL;
// allocate vertex data
if (numVertices > sVertexDataCount || sVertexData == NULL) {
if (sVertexData) { free(sVertexData); }
sVertexDataCount = numVertices;
sVertexData = malloc(sizeof(s16) * sVertexDataCount);
}
s16* collisionData = gCurrentObject->collisionData; s16* collisionData = gCurrentObject->collisionData;
f32 tangibleDist = gCurrentObject->oCollisionDistance; f32 tangibleDist = gCurrentObject->oCollisionDistance;
@ -778,11 +792,11 @@ void load_object_collision_model(void) {
&& (anyPlayerInTangibleRange) && (anyPlayerInTangibleRange)
&& !(gCurrentObject->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM)) { && !(gCurrentObject->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM)) {
collisionData++; collisionData++;
transform_object_vertices(&collisionData, vertexData); transform_object_vertices(&collisionData, sVertexData);
// TERRAIN_LOAD_CONTINUE acts as an "end" to the terrain data. // TERRAIN_LOAD_CONTINUE acts as an "end" to the terrain data.
while (*collisionData != TERRAIN_LOAD_CONTINUE) { while (*collisionData != TERRAIN_LOAD_CONTINUE) {
load_object_surfaces(&collisionData, vertexData); load_object_surfaces(&collisionData, sVertexData);
} }
} }

View File

@ -29,7 +29,7 @@
#include "pc/djui/djui_panel_pause.h" #include "pc/djui/djui_panel_pause.h"
struct SpawnInfo gPlayerSpawnInfos[MAX_PLAYERS]; struct SpawnInfo gPlayerSpawnInfos[MAX_PLAYERS];
struct Area gAreaData[8]; struct Area gAreaData[MAX_AREAS];
struct WarpTransition gWarpTransition; struct WarpTransition gWarpTransition;

View File

@ -26,6 +26,8 @@ struct ObjectWarpNode
#define INSTANT_WARP_INDEX_START 0x00 // Equal and greater than Surface 0x1B #define INSTANT_WARP_INDEX_START 0x00 // Equal and greater than Surface 0x1B
#define INSTANT_WARP_INDEX_STOP 0x04 // Less than Surface 0x1F #define INSTANT_WARP_INDEX_STOP 0x04 // Less than Surface 0x1F
#define MAX_AREAS 8
struct InstantWarp struct InstantWarp
{ {
/*0x00*/ u8 id; // 0 = 0x1B / 1 = 0x1C / 2 = 0x1D / 3 = 0x1E /*0x00*/ u8 id; // 0 = 0x1B / 1 = 0x1C / 2 = 0x1D / 3 = 0x1E