Add bounds checking to instant warps, and make object collisions dynamic
in size
This commit is contained in:
parent
488ef1c6d2
commit
b3cae34234
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue