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) {
s32 i;
struct InstantWarp *warp;
struct InstantWarp *warp = NULL;
if (sCurrAreaIndex != -1) {
if (gAreas[sCurrAreaIndex].instantWarps == NULL) {
gAreas[sCurrAreaIndex].instantWarps =
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;
}
}
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;
warp[0].area = CMD_GET(u8, 3);
u8 areaIndex = 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[0].displacement[1] = CMD_GET(s16, 6);
warp[0].displacement[2] = CMD_GET(s16, 8);
warp = &gAreas[sCurrAreaIndex].instantWarps[warpIndex];
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;

View File

@ -756,7 +756,21 @@ void load_object_collision_model(void) {
if (!gCurrentObject) { 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;
f32 tangibleDist = gCurrentObject->oCollisionDistance;
@ -778,11 +792,11 @@ void load_object_collision_model(void) {
&& (anyPlayerInTangibleRange)
&& !(gCurrentObject->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM)) {
collisionData++;
transform_object_vertices(&collisionData, vertexData);
transform_object_vertices(&collisionData, sVertexData);
// TERRAIN_LOAD_CONTINUE acts as an "end" to the terrain data.
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"
struct SpawnInfo gPlayerSpawnInfos[MAX_PLAYERS];
struct Area gAreaData[8];
struct Area gAreaData[MAX_AREAS];
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_STOP 0x04 // Less than Surface 0x1F
#define MAX_AREAS 8
struct InstantWarp
{
/*0x00*/ u8 id; // 0 = 0x1B / 1 = 0x1C / 2 = 0x1D / 3 = 0x1E