mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-28 23:13:02 +00:00
Make envfx use dynamic memory
This commit is contained in:
parent
1e67809cd8
commit
4aa4386319
7 changed files with 152 additions and 117 deletions
|
@ -31,6 +31,7 @@
|
|||
#include "pc/debug_context.h"
|
||||
#include "game/hardcoded.h"
|
||||
#include "menu/intro_geo.h"
|
||||
#include "game/envfx_snow.h"
|
||||
|
||||
#define CMD_GET(type, offset) (*(type *) (CMD_PROCESS_OFFSET(offset) + (u8 *) sCurrentCmd))
|
||||
|
||||
|
@ -51,7 +52,7 @@ LevelScript* gLevelScriptActive = NULL;
|
|||
|
||||
static uintptr_t sStack[32];
|
||||
|
||||
static struct DynamicPool *sLevelPool = NULL;
|
||||
struct DynamicPool *gLevelPool = NULL;
|
||||
|
||||
static u16 sDelayFrames = 0;
|
||||
static u16 sDelayFrames2 = 0;
|
||||
|
@ -107,7 +108,7 @@ static s32 eval_script_op(s8 op, s32 arg) {
|
|||
|
||||
struct ObjectWarpNode *area_create_warp_node(u8 id, u8 destLevel, u8 destArea, u8 destNode, u8 checkpoint, struct Object *o) {
|
||||
if (sCurrAreaIndex != -1) {
|
||||
struct ObjectWarpNode *warpNode = dynamic_pool_alloc(sLevelPool, sizeof(struct ObjectWarpNode));
|
||||
struct ObjectWarpNode *warpNode = dynamic_pool_alloc(gLevelPool, sizeof(struct ObjectWarpNode));
|
||||
|
||||
warpNode->node.id = id;
|
||||
warpNode->node.destLevel = destLevel + checkpoint;
|
||||
|
@ -384,6 +385,21 @@ static void level_cmd_clear_level(void) {
|
|||
sCurrentCmd = CMD_NEXT;
|
||||
}
|
||||
|
||||
static void level_reset_globals(void) {
|
||||
// free previous level pool
|
||||
if (gLevelPool != NULL) {
|
||||
dynamic_pool_free_pool(gLevelPool);
|
||||
gLevelPool = NULL;
|
||||
}
|
||||
|
||||
// reset envfx
|
||||
gEnvFxBuffer = NULL;
|
||||
gEnvFxMode = ENVFX_MODE_NONE;
|
||||
|
||||
// free models stored in dynos
|
||||
dynos_model_clear_pool(MODEL_POOL_LEVEL);
|
||||
}
|
||||
|
||||
static void level_cmd_alloc_level_pool(void) {
|
||||
|
||||
// reset level graph node ownership
|
||||
|
@ -394,16 +410,12 @@ static void level_cmd_alloc_level_pool(void) {
|
|||
}
|
||||
}
|
||||
|
||||
// free previous level pool
|
||||
if (sLevelPool != NULL) {
|
||||
dynamic_pool_free_pool(sLevelPool);
|
||||
sLevelPool = NULL;
|
||||
}
|
||||
dynos_model_clear_pool(MODEL_POOL_LEVEL);
|
||||
// reset all globals
|
||||
level_reset_globals();
|
||||
|
||||
// allocate new level pool
|
||||
if (sLevelPool == NULL) {
|
||||
sLevelPool = dynamic_pool_init();
|
||||
if (gLevelPool == NULL) {
|
||||
gLevelPool = dynamic_pool_init();
|
||||
}
|
||||
|
||||
sCurrentCmd = CMD_NEXT;
|
||||
|
@ -415,7 +427,7 @@ static void level_cmd_free_level_pool(void) {
|
|||
if (!sFinishedLoadingPerm) {
|
||||
sFinishedLoadingPerm = true;
|
||||
// make sure we don't free the pool with the permanent models
|
||||
sLevelPool = NULL;
|
||||
gLevelPool = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
|
@ -500,7 +512,7 @@ static void level_cmd_23(void) {
|
|||
if (model < MAX_LOADED_GRAPH_NODES) {
|
||||
// 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);
|
||||
gLoadedGraphNodes[model] = (struct GraphNode *) init_graph_node_scale(gLevelPool, 0, arg0H, arg1, arg2.f);
|
||||
if (sFinishedLoadingPerm) { sLevelOwnedGraphNodes[model] = true; }
|
||||
smlua_model_util_remember(model, arg0H, arg1, 1);
|
||||
}
|
||||
|
@ -547,7 +559,7 @@ static void level_cmd_place_object(void) {
|
|||
if (sCurrAreaIndex != -1 && (gLevelValues.disableActs || (CMD_GET(u8, 2) & val7) || CMD_GET(u8, 2) == 0x1F)) {
|
||||
model = CMD_GET(u8, 3);
|
||||
if (model >= MAX_LOADED_GRAPH_NODES) { model = MODEL_NONE; }
|
||||
spawnInfo = dynamic_pool_alloc(sLevelPool, sizeof(struct SpawnInfo));
|
||||
spawnInfo = dynamic_pool_alloc(gLevelPool, sizeof(struct SpawnInfo));
|
||||
|
||||
spawnInfo->startPos[0] = CMD_GET(s16, 4);
|
||||
spawnInfo->startPos[1] = CMD_GET(s16, 6);
|
||||
|
@ -578,7 +590,7 @@ static void level_cmd_place_object(void) {
|
|||
static void level_cmd_create_warp_node(void) {
|
||||
if (sCurrAreaIndex != -1) {
|
||||
struct ObjectWarpNode *warpNode =
|
||||
dynamic_pool_alloc(sLevelPool, sizeof(struct ObjectWarpNode));
|
||||
dynamic_pool_alloc(gLevelPool, sizeof(struct ObjectWarpNode));
|
||||
|
||||
warpNode->node.id = CMD_GET(u8, 2);
|
||||
warpNode->node.destLevel = CMD_GET(u8, 3) + CMD_GET(u8, 6);
|
||||
|
@ -601,7 +613,7 @@ static void level_cmd_create_instant_warp(void) {
|
|||
if (sCurrAreaIndex != -1) {
|
||||
if (gAreas[sCurrAreaIndex].instantWarps == NULL) {
|
||||
gAreas[sCurrAreaIndex].instantWarps =
|
||||
dynamic_pool_alloc(sLevelPool, 4 * sizeof(struct InstantWarp));
|
||||
dynamic_pool_alloc(gLevelPool, 4 * sizeof(struct InstantWarp));
|
||||
|
||||
for (i = INSTANT_WARP_INDEX_START; i < INSTANT_WARP_INDEX_STOP; i++) {
|
||||
gAreas[sCurrAreaIndex].instantWarps[i].id = 0;
|
||||
|
@ -636,7 +648,7 @@ static void level_cmd_create_painting_warp_node(void) {
|
|||
if (sCurrAreaIndex != -1) {
|
||||
if (gAreas[sCurrAreaIndex].paintingWarpNodes == NULL) {
|
||||
gAreas[sCurrAreaIndex].paintingWarpNodes =
|
||||
dynamic_pool_alloc(sLevelPool, MAX_PAINTING_WARP_NODES * sizeof(struct WarpNode));
|
||||
dynamic_pool_alloc(gLevelPool, MAX_PAINTING_WARP_NODES * sizeof(struct WarpNode));
|
||||
|
||||
for (i = 0; i < MAX_PAINTING_WARP_NODES; i++) {
|
||||
gAreas[sCurrAreaIndex].paintingWarpNodes[i].id = 0;
|
||||
|
@ -660,7 +672,7 @@ static void level_cmd_3A(void) {
|
|||
if (sCurrAreaIndex != -1) {
|
||||
if ((val4 = gAreas[sCurrAreaIndex].unused28) == NULL) {
|
||||
val4 = gAreas[sCurrAreaIndex].unused28 =
|
||||
dynamic_pool_alloc(sLevelPool, sizeof(struct UnusedArea28));
|
||||
dynamic_pool_alloc(gLevelPool, sizeof(struct UnusedArea28));
|
||||
}
|
||||
|
||||
val4->unk00 = CMD_GET(s16, 2);
|
||||
|
@ -683,7 +695,7 @@ static void level_cmd_create_whirlpool(void) {
|
|||
|| (CMD_GET(u8, 3) == 2 && beatBowser2) || (CMD_GET(u8, 3) == 3 && gCurrActNum >= 2)) {
|
||||
if (sCurrAreaIndex != -1 && index < 2) {
|
||||
if ((whirlpool = gAreas[sCurrAreaIndex].whirlpools[index]) == NULL) {
|
||||
whirlpool = dynamic_pool_alloc(sLevelPool, sizeof(struct Whirlpool));
|
||||
whirlpool = dynamic_pool_alloc(gLevelPool, sizeof(struct Whirlpool));
|
||||
gAreas[sCurrAreaIndex].whirlpools[index] = whirlpool;
|
||||
}
|
||||
|
||||
|
@ -713,7 +725,7 @@ static void level_cmd_set_terrain_data(void) {
|
|||
// The game modifies the terrain data and must be reset upon level reload.
|
||||
data = segmented_to_virtual(CMD_GET(void *, 4));
|
||||
size = get_area_terrain_size(data) * sizeof(Collision);
|
||||
gAreas[sCurrAreaIndex].terrainData = dynamic_pool_alloc(sLevelPool, size);
|
||||
gAreas[sCurrAreaIndex].terrainData = dynamic_pool_alloc(gLevelPool, size);
|
||||
memcpy(gAreas[sCurrAreaIndex].terrainData, data, size);
|
||||
}
|
||||
sCurrentCmd = CMD_NEXT;
|
||||
|
@ -736,10 +748,10 @@ static void level_cmd_set_macro_objects(void) {
|
|||
area_check_red_coin_or_secret(&data[len - 1], true);
|
||||
len += 4;
|
||||
}
|
||||
gAreas[sCurrAreaIndex].macroObjects = dynamic_pool_alloc(sLevelPool, len * sizeof(MacroObject));
|
||||
gAreas[sCurrAreaIndex].macroObjects = dynamic_pool_alloc(gLevelPool, len * sizeof(MacroObject));
|
||||
memcpy(gAreas[sCurrAreaIndex].macroObjects, data, len * sizeof(MacroObject));
|
||||
|
||||
gAreas[sCurrAreaIndex].macroObjectsAltered = dynamic_pool_alloc(sLevelPool, len * sizeof(u8));
|
||||
gAreas[sCurrAreaIndex].macroObjectsAltered = dynamic_pool_alloc(gLevelPool, len * sizeof(u8));
|
||||
memset(gAreas[sCurrAreaIndex].macroObjectsAltered, 0, len);
|
||||
}
|
||||
sCurrentCmd = CMD_NEXT;
|
||||
|
@ -946,7 +958,7 @@ static void level_cmd_place_object_ext(void) {
|
|||
if (sCurrAreaIndex != -1 && (gLevelValues.disableActs || (CMD_GET(u8, 2) & val7) || CMD_GET(u8, 2) == 0x1F)) {
|
||||
u16 model = CMD_GET(u8, 3);
|
||||
if (model >= MAX_LOADED_GRAPH_NODES) { model = MODEL_NONE; }
|
||||
spawnInfo = dynamic_pool_alloc(sLevelPool, sizeof(struct SpawnInfo));
|
||||
spawnInfo = dynamic_pool_alloc(gLevelPool, sizeof(struct SpawnInfo));
|
||||
|
||||
spawnInfo->startPos[0] = CMD_GET(s16, 4);
|
||||
spawnInfo->startPos[1] = CMD_GET(s16, 6);
|
||||
|
@ -1016,7 +1028,7 @@ static void level_cmd_place_object_ext2(void) {
|
|||
}
|
||||
|
||||
if (sCurrAreaIndex != -1 && (gLevelValues.disableActs || (CMD_GET(u8, 2) & val7) || CMD_GET(u8, 2) == 0x1F)) {
|
||||
spawnInfo = dynamic_pool_alloc(sLevelPool, sizeof(struct SpawnInfo));
|
||||
spawnInfo = dynamic_pool_alloc(gLevelPool, sizeof(struct SpawnInfo));
|
||||
|
||||
spawnInfo->startPos[0] = CMD_GET(s16, 4);
|
||||
spawnInfo->startPos[1] = CMD_GET(s16, 6);
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
struct LevelCommand;
|
||||
|
||||
extern struct DynamicPool *gLevelPool;
|
||||
|
||||
extern s32 gLevelScriptModIndex;
|
||||
extern LevelScript* gLevelScriptActive;
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "game/rendering_graph_node.h"
|
||||
#include "pc/utils/misc.h"
|
||||
#include "game/hardcoded.h"
|
||||
#include "engine/level_script.h"
|
||||
|
||||
/**
|
||||
* This file implements environment effects that are not snow:
|
||||
|
@ -49,7 +50,7 @@ static Vec3s sBubbleGfxCamTo;
|
|||
void patch_bubble_particles_before(void) {
|
||||
if (sBubbleGfxPos) {
|
||||
for (s32 i = 0; i < sBubbleParticleMaxCount; i++) {
|
||||
vec3s_set((gEnvFxBuffer + i)->prevPos, (gEnvFxBuffer + i)->xPos, (gEnvFxBuffer + i)->yPos, (gEnvFxBuffer + i)->zPos);
|
||||
vec3s_set(gEnvFxBuffer[i].prevPos, gEnvFxBuffer[i].xPos, gEnvFxBuffer[i].yPos, gEnvFxBuffer[i].zPos);
|
||||
}
|
||||
sBubbleGfxPos = NULL;
|
||||
}
|
||||
|
@ -67,8 +68,8 @@ void patch_bubble_particles_interpolated(UNUSED f32 delta) {
|
|||
* kill flower and bubble particles.
|
||||
*/
|
||||
s32 particle_is_laterally_close(s32 index, s32 x, s32 z, s32 distance) {
|
||||
s32 xPos = (gEnvFxBuffer + index)->xPos;
|
||||
s32 zPos = (gEnvFxBuffer + index)->zPos;
|
||||
s32 xPos = gEnvFxBuffer[index].xPos;
|
||||
s32 zPos = gEnvFxBuffer[index].zPos;
|
||||
|
||||
if (sqr(xPos - x) + sqr(zPos - z) > sqr(distance)) {
|
||||
return 0;
|
||||
|
@ -106,19 +107,19 @@ void envfx_update_flower(Vec3s centerPos) {
|
|||
s16 centerZ = centerPos[2];
|
||||
|
||||
for (i = 0; i < sBubbleParticleMaxCount; i++) {
|
||||
(gEnvFxBuffer + i)->isAlive = particle_is_laterally_close(i, centerX, centerZ, 3000);
|
||||
if ((gEnvFxBuffer + i)->isAlive == 0) {
|
||||
(gEnvFxBuffer + i)->xPos = random_flower_offset() + centerX;
|
||||
(gEnvFxBuffer + i)->zPos = random_flower_offset() + centerZ;
|
||||
(gEnvFxBuffer + i)->yPos = find_floor_height_and_data((gEnvFxBuffer + i)->xPos, 10000.0f,
|
||||
(gEnvFxBuffer + i)->zPos, &floorGeo);
|
||||
(gEnvFxBuffer + i)->isAlive = 1;
|
||||
(gEnvFxBuffer + i)->animFrame = random_float() * 5.0f;
|
||||
vec3s_set((gEnvFxBuffer + i)->prevPos, (gEnvFxBuffer + i)->xPos, (gEnvFxBuffer + i)->yPos, (gEnvFxBuffer + i)->zPos);
|
||||
gEnvFxBuffer[i].isAlive = particle_is_laterally_close(i, centerX, centerZ, 3000);
|
||||
if (gEnvFxBuffer[i].isAlive == 0) {
|
||||
gEnvFxBuffer[i].xPos = random_flower_offset() + centerX;
|
||||
gEnvFxBuffer[i].zPos = random_flower_offset() + centerZ;
|
||||
gEnvFxBuffer[i].yPos = find_floor_height_and_data(gEnvFxBuffer[i].xPos, 10000.0f,
|
||||
gEnvFxBuffer[i].zPos, &floorGeo);
|
||||
gEnvFxBuffer[i].isAlive = 1;
|
||||
gEnvFxBuffer[i].animFrame = random_float() * 5.0f;
|
||||
vec3s_set(gEnvFxBuffer[i].prevPos, gEnvFxBuffer[i].xPos, gEnvFxBuffer[i].yPos, gEnvFxBuffer[i].zPos);
|
||||
} else if ((timer & 0x03) == 0) {
|
||||
(gEnvFxBuffer + i)->animFrame += 1;
|
||||
if ((gEnvFxBuffer + i)->animFrame > 5) {
|
||||
(gEnvFxBuffer + i)->animFrame = 0;
|
||||
gEnvFxBuffer[i].animFrame += 1;
|
||||
if (gEnvFxBuffer[i].animFrame > 5) {
|
||||
gEnvFxBuffer[i].animFrame = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -142,33 +143,33 @@ void envfx_set_lava_bubble_position(s32 index, Vec3s centerPos) {
|
|||
centerY = centerPos[1];
|
||||
centerZ = centerPos[2];
|
||||
|
||||
(gEnvFxBuffer + index)->xPos = random_float() * 6000.0f - 3000.0f + centerX;
|
||||
(gEnvFxBuffer + index)->zPos = random_float() * 6000.0f - 3000.0f + centerZ;
|
||||
gEnvFxBuffer[index].xPos = random_float() * 6000.0f - 3000.0f + centerX;
|
||||
gEnvFxBuffer[index].zPos = random_float() * 6000.0f - 3000.0f + centerZ;
|
||||
|
||||
if ((gEnvFxBuffer + index)->xPos > 8000) {
|
||||
(gEnvFxBuffer + index)->xPos = 16000 - (gEnvFxBuffer + index)->xPos;
|
||||
if (gEnvFxBuffer[index].xPos > 8000) {
|
||||
gEnvFxBuffer[index].xPos = 16000 - gEnvFxBuffer[index].xPos;
|
||||
}
|
||||
if ((gEnvFxBuffer + index)->xPos < -8000) {
|
||||
(gEnvFxBuffer + index)->xPos = -16000 - (gEnvFxBuffer + index)->xPos;
|
||||
if (gEnvFxBuffer[index].xPos < -8000) {
|
||||
gEnvFxBuffer[index].xPos = -16000 - gEnvFxBuffer[index].xPos;
|
||||
}
|
||||
|
||||
if ((gEnvFxBuffer + index)->zPos > 8000) {
|
||||
(gEnvFxBuffer + index)->zPos = 16000 - (gEnvFxBuffer + index)->zPos;
|
||||
if (gEnvFxBuffer[index].zPos > 8000) {
|
||||
gEnvFxBuffer[index].zPos = 16000 - gEnvFxBuffer[index].zPos;
|
||||
}
|
||||
if ((gEnvFxBuffer + index)->zPos < -8000) {
|
||||
(gEnvFxBuffer + index)->zPos = -16000 - (gEnvFxBuffer + index)->zPos;
|
||||
if (gEnvFxBuffer[index].zPos < -8000) {
|
||||
gEnvFxBuffer[index].zPos = -16000 - gEnvFxBuffer[index].zPos;
|
||||
}
|
||||
|
||||
floorY = find_floor((gEnvFxBuffer + index)->xPos, centerY + 500, (gEnvFxBuffer + index)->zPos, &surface);
|
||||
floorY = find_floor(gEnvFxBuffer[index].xPos, centerY + 500, gEnvFxBuffer[index].zPos, &surface);
|
||||
if (surface == NULL) {
|
||||
(gEnvFxBuffer + index)->yPos = gLevelValues.floorLowerLimitMisc;
|
||||
gEnvFxBuffer[index].yPos = gLevelValues.floorLowerLimitMisc;
|
||||
return;
|
||||
}
|
||||
|
||||
if (surface->type == SURFACE_BURNING) {
|
||||
(gEnvFxBuffer + index)->yPos = floorY;
|
||||
gEnvFxBuffer[index].yPos = floorY;
|
||||
} else {
|
||||
(gEnvFxBuffer + index)->yPos = gLevelValues.floorLowerLimitMisc;
|
||||
gEnvFxBuffer[index].yPos = gLevelValues.floorLowerLimitMisc;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,15 +188,15 @@ void envfx_update_lava(Vec3s centerPos) {
|
|||
centerZ = centerPos[2];
|
||||
|
||||
for (i = 0; i < sBubbleParticleMaxCount; i++) {
|
||||
if ((gEnvFxBuffer + i)->isAlive == 0) {
|
||||
if (gEnvFxBuffer[i].isAlive == 0) {
|
||||
envfx_set_lava_bubble_position(i, centerPos);
|
||||
vec3s_set((gEnvFxBuffer + i)->prevPos, (gEnvFxBuffer + i)->xPos, (gEnvFxBuffer + i)->yPos, (gEnvFxBuffer + i)->zPos);
|
||||
(gEnvFxBuffer + i)->isAlive = 1;
|
||||
vec3s_set(gEnvFxBuffer[i].prevPos, gEnvFxBuffer[i].xPos, gEnvFxBuffer[i].yPos, gEnvFxBuffer[i].zPos);
|
||||
gEnvFxBuffer[i].isAlive = 1;
|
||||
} else if ((timer & 0x01) == 0) {
|
||||
(gEnvFxBuffer + i)->animFrame += 1;
|
||||
if ((gEnvFxBuffer + i)->animFrame > 8) {
|
||||
(gEnvFxBuffer + i)->isAlive = 0;
|
||||
(gEnvFxBuffer + i)->animFrame = 0;
|
||||
gEnvFxBuffer[i].animFrame += 1;
|
||||
if (gEnvFxBuffer[i].animFrame > 8) {
|
||||
gEnvFxBuffer[i].isAlive = 0;
|
||||
gEnvFxBuffer[i].animFrame = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -234,11 +235,11 @@ void envfx_rotate_around_whirlpool(s32 *x, s32 *y, s32 *z) {
|
|||
s32 envfx_is_whirlpool_bubble_alive(s32 index) {
|
||||
s32 UNUSED sp4;
|
||||
|
||||
if ((gEnvFxBuffer + index)->bubbleY < gEnvFxBubbleConfig[ENVFX_STATE_DEST_Y] - 100) {
|
||||
if (gEnvFxBuffer[index].bubbleY < gEnvFxBubbleConfig[ENVFX_STATE_DEST_Y] - 100) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((gEnvFxBuffer + index)->angleAndDist[1] < 10) {
|
||||
if (gEnvFxBuffer[index].angleAndDist[1] < 10) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -253,43 +254,43 @@ void envfx_update_whirlpool(void) {
|
|||
s32 i;
|
||||
|
||||
for (i = 0; i < sBubbleParticleMaxCount; i++) {
|
||||
(gEnvFxBuffer + i)->isAlive = envfx_is_whirlpool_bubble_alive(i);
|
||||
if ((gEnvFxBuffer + i)->isAlive == 0) {
|
||||
(gEnvFxBuffer + i)->angleAndDist[1] = random_float() * 1000.0f;
|
||||
(gEnvFxBuffer + i)->angleAndDist[0] = random_float() * 65536.0f;
|
||||
(gEnvFxBuffer + i)->xPos =
|
||||
gEnvFxBuffer[i].isAlive = envfx_is_whirlpool_bubble_alive(i);
|
||||
if (gEnvFxBuffer[i].isAlive == 0) {
|
||||
gEnvFxBuffer[i].angleAndDist[1] = random_float() * 1000.0f;
|
||||
gEnvFxBuffer[i].angleAndDist[0] = random_float() * 65536.0f;
|
||||
gEnvFxBuffer[i].xPos =
|
||||
gEnvFxBubbleConfig[ENVFX_STATE_SRC_X]
|
||||
+ sins((gEnvFxBuffer + i)->angleAndDist[0]) * (gEnvFxBuffer + i)->angleAndDist[1];
|
||||
(gEnvFxBuffer + i)->zPos =
|
||||
+ sins(gEnvFxBuffer[i].angleAndDist[0]) * gEnvFxBuffer[i].angleAndDist[1];
|
||||
gEnvFxBuffer[i].zPos =
|
||||
gEnvFxBubbleConfig[ENVFX_STATE_SRC_Z]
|
||||
+ coss((gEnvFxBuffer + i)->angleAndDist[0]) * (gEnvFxBuffer + i)->angleAndDist[1];
|
||||
(gEnvFxBuffer + i)->bubbleY =
|
||||
+ coss(gEnvFxBuffer[i].angleAndDist[0]) * gEnvFxBuffer[i].angleAndDist[1];
|
||||
gEnvFxBuffer[i].bubbleY =
|
||||
gEnvFxBubbleConfig[ENVFX_STATE_SRC_Y] + (random_float() * 100.0f - 50.0f);
|
||||
(gEnvFxBuffer + i)->yPos = (i + gEnvFxBuffer)->bubbleY;
|
||||
(gEnvFxBuffer + i)->unusedBubbleVar = 0;
|
||||
(gEnvFxBuffer + i)->isAlive = 1;
|
||||
(gEnvFxBuffer + i)->spawnTimestamp = gGlobalTimer;
|
||||
vec3s_set((gEnvFxBuffer + i)->prevPos, (gEnvFxBuffer + i)->xPos, (gEnvFxBuffer + i)->yPos, (gEnvFxBuffer + i)->zPos);
|
||||
gEnvFxBuffer[i].yPos = (i + gEnvFxBuffer)->bubbleY;
|
||||
gEnvFxBuffer[i].unusedBubbleVar = 0;
|
||||
gEnvFxBuffer[i].isAlive = 1;
|
||||
gEnvFxBuffer[i].spawnTimestamp = gGlobalTimer;
|
||||
vec3s_set(gEnvFxBuffer[i].prevPos, gEnvFxBuffer[i].xPos, gEnvFxBuffer[i].yPos, gEnvFxBuffer[i].zPos);
|
||||
|
||||
envfx_rotate_around_whirlpool(&(gEnvFxBuffer + i)->xPos, &(gEnvFxBuffer + i)->yPos,
|
||||
&(gEnvFxBuffer + i)->zPos);
|
||||
envfx_rotate_around_whirlpool(&gEnvFxBuffer[i].xPos, &gEnvFxBuffer[i].yPos,
|
||||
&gEnvFxBuffer[i].zPos);
|
||||
}
|
||||
|
||||
if ((gEnvFxBuffer + i)->isAlive != 0) {
|
||||
(gEnvFxBuffer + i)->angleAndDist[1] -= 40;
|
||||
(gEnvFxBuffer + i)->angleAndDist[0] +=
|
||||
(s16)(3000 - (gEnvFxBuffer + i)->angleAndDist[1] * 2) + 0x400;
|
||||
(gEnvFxBuffer + i)->xPos =
|
||||
if (gEnvFxBuffer[i].isAlive != 0) {
|
||||
gEnvFxBuffer[i].angleAndDist[1] -= 40;
|
||||
gEnvFxBuffer[i].angleAndDist[0] +=
|
||||
(s16)(3000 - gEnvFxBuffer[i].angleAndDist[1] * 2) + 0x400;
|
||||
gEnvFxBuffer[i].xPos =
|
||||
gEnvFxBubbleConfig[ENVFX_STATE_SRC_X]
|
||||
+ sins((gEnvFxBuffer + i)->angleAndDist[0]) * (gEnvFxBuffer + i)->angleAndDist[1];
|
||||
(gEnvFxBuffer + i)->zPos =
|
||||
+ sins(gEnvFxBuffer[i].angleAndDist[0]) * gEnvFxBuffer[i].angleAndDist[1];
|
||||
gEnvFxBuffer[i].zPos =
|
||||
gEnvFxBubbleConfig[ENVFX_STATE_SRC_Z]
|
||||
+ coss((gEnvFxBuffer + i)->angleAndDist[0]) * (gEnvFxBuffer + i)->angleAndDist[1];
|
||||
(gEnvFxBuffer + i)->bubbleY -= 40 - ((s16)(gEnvFxBuffer + i)->angleAndDist[1] / 100);
|
||||
(gEnvFxBuffer + i)->yPos = (i + gEnvFxBuffer)->bubbleY;
|
||||
+ coss(gEnvFxBuffer[i].angleAndDist[0]) * gEnvFxBuffer[i].angleAndDist[1];
|
||||
gEnvFxBuffer[i].bubbleY -= 40 - ((s16)gEnvFxBuffer[i].angleAndDist[1] / 100);
|
||||
gEnvFxBuffer[i].yPos = (i + gEnvFxBuffer)->bubbleY;
|
||||
|
||||
envfx_rotate_around_whirlpool(&(gEnvFxBuffer + i)->xPos, &(gEnvFxBuffer + i)->yPos,
|
||||
&(gEnvFxBuffer + i)->zPos);
|
||||
envfx_rotate_around_whirlpool(&gEnvFxBuffer[i].xPos, &gEnvFxBuffer[i].yPos,
|
||||
&gEnvFxBuffer[i].zPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -303,7 +304,7 @@ s32 envfx_is_jestream_bubble_alive(s32 index) {
|
|||
|
||||
if (!particle_is_laterally_close(index, gEnvFxBubbleConfig[ENVFX_STATE_SRC_X],
|
||||
gEnvFxBubbleConfig[ENVFX_STATE_SRC_Z], 1000)
|
||||
|| gEnvFxBubbleConfig[ENVFX_STATE_SRC_Y] + 1500 < (gEnvFxBuffer + index)->yPos) {
|
||||
|| gEnvFxBubbleConfig[ENVFX_STATE_SRC_Y] + 1500 < gEnvFxBuffer[index].yPos) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -318,20 +319,20 @@ void envfx_update_jetstream(void) {
|
|||
s32 i;
|
||||
|
||||
for (i = 0; i < sBubbleParticleMaxCount; i++) {
|
||||
(gEnvFxBuffer + i)->isAlive = envfx_is_jestream_bubble_alive(i);
|
||||
if ((gEnvFxBuffer + i)->isAlive == 0) {
|
||||
(gEnvFxBuffer + i)->angleAndDist[1] = random_float() * 300.0f;
|
||||
(gEnvFxBuffer + i)->angleAndDist[0] = random_u16();
|
||||
(gEnvFxBuffer + i)->xPos = gEnvFxBubbleConfig[ENVFX_STATE_SRC_X] + sins((gEnvFxBuffer + i)->angleAndDist[0]) * (gEnvFxBuffer + i)->angleAndDist[1];
|
||||
(gEnvFxBuffer + i)->zPos = gEnvFxBubbleConfig[ENVFX_STATE_SRC_Z] + coss((gEnvFxBuffer + i)->angleAndDist[0]) * (gEnvFxBuffer + i)->angleAndDist[1];
|
||||
(gEnvFxBuffer + i)->yPos = gEnvFxBubbleConfig[ENVFX_STATE_SRC_Y] + (random_float() * 400.0f - 200.0f);
|
||||
(gEnvFxBuffer + i)->spawnTimestamp = gGlobalTimer;
|
||||
vec3s_set((gEnvFxBuffer + i)->prevPos, (gEnvFxBuffer + i)->xPos, (gEnvFxBuffer + i)->yPos, (gEnvFxBuffer + i)->zPos);
|
||||
gEnvFxBuffer[i].isAlive = envfx_is_jestream_bubble_alive(i);
|
||||
if (gEnvFxBuffer[i].isAlive == 0) {
|
||||
gEnvFxBuffer[i].angleAndDist[1] = random_float() * 300.0f;
|
||||
gEnvFxBuffer[i].angleAndDist[0] = random_u16();
|
||||
gEnvFxBuffer[i].xPos = gEnvFxBubbleConfig[ENVFX_STATE_SRC_X] + sins(gEnvFxBuffer[i].angleAndDist[0]) * gEnvFxBuffer[i].angleAndDist[1];
|
||||
gEnvFxBuffer[i].zPos = gEnvFxBubbleConfig[ENVFX_STATE_SRC_Z] + coss(gEnvFxBuffer[i].angleAndDist[0]) * gEnvFxBuffer[i].angleAndDist[1];
|
||||
gEnvFxBuffer[i].yPos = gEnvFxBubbleConfig[ENVFX_STATE_SRC_Y] + (random_float() * 400.0f - 200.0f);
|
||||
gEnvFxBuffer[i].spawnTimestamp = gGlobalTimer;
|
||||
vec3s_set(gEnvFxBuffer[i].prevPos, gEnvFxBuffer[i].xPos, gEnvFxBuffer[i].yPos, gEnvFxBuffer[i].zPos);
|
||||
} else {
|
||||
(gEnvFxBuffer + i)->angleAndDist[1] += 10;
|
||||
(gEnvFxBuffer + i)->xPos += sins((gEnvFxBuffer + i)->angleAndDist[0]) * 10.0f;
|
||||
(gEnvFxBuffer + i)->zPos += coss((gEnvFxBuffer + i)->angleAndDist[0]) * 10.0f;
|
||||
(gEnvFxBuffer + i)->yPos -= ((gEnvFxBuffer + i)->angleAndDist[1] / 30) - 50;
|
||||
gEnvFxBuffer[i].angleAndDist[1] += 10;
|
||||
gEnvFxBuffer[i].xPos += sins(gEnvFxBuffer[i].angleAndDist[0]) * 10.0f;
|
||||
gEnvFxBuffer[i].zPos += coss(gEnvFxBuffer[i].angleAndDist[0]) * 10.0f;
|
||||
gEnvFxBuffer[i].yPos -= (gEnvFxBuffer[i].angleAndDist[1] / 30) - 50;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -367,10 +368,8 @@ s32 envfx_init_bubble(s32 mode) {
|
|||
break;
|
||||
}
|
||||
|
||||
gEnvFxBuffer = mem_pool_alloc(gEffectsMemoryPool, sBubbleParticleCount * sizeof(struct EnvFxParticle));
|
||||
if (!gEnvFxBuffer) {
|
||||
return 0;
|
||||
}
|
||||
gEnvFxBuffer = dynamic_pool_alloc(gLevelPool, sBubbleParticleCount * sizeof(struct EnvFxParticle));
|
||||
if (!gEnvFxBuffer) { return 0; }
|
||||
|
||||
bzero(gEnvFxBuffer, sBubbleParticleCount * sizeof(struct EnvFxParticle));
|
||||
bzero(gEnvFxBubbleConfig, sizeof(gEnvFxBubbleConfig));
|
||||
|
@ -378,7 +377,7 @@ s32 envfx_init_bubble(s32 mode) {
|
|||
switch (mode) {
|
||||
case ENVFX_LAVA_BUBBLES:
|
||||
for (i = 0; i < sBubbleParticleCount; i++) {
|
||||
(gEnvFxBuffer + i)->animFrame = random_float() * 7.0f;
|
||||
gEnvFxBuffer[i].animFrame = random_float() * 7.0f;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -489,17 +488,17 @@ void append_bubble_vertex_buffer(Gfx *gfx, s32 index, Vec3s vertex1, Vec3s verte
|
|||
*/
|
||||
void envfx_set_bubble_texture(s32 mode, s16 index) {
|
||||
void **imageArr;
|
||||
s16 frame = (gEnvFxBuffer + index)->animFrame;
|
||||
s16 frame = gEnvFxBuffer[index].animFrame;
|
||||
|
||||
switch (mode) {
|
||||
case ENVFX_FLOWERS:
|
||||
imageArr = segmented_to_virtual(&flower_bubbles_textures_ptr_0B002008);
|
||||
frame = (gEnvFxBuffer + index)->animFrame;
|
||||
frame = gEnvFxBuffer[index].animFrame;
|
||||
break;
|
||||
|
||||
case ENVFX_LAVA_BUBBLES:
|
||||
imageArr = segmented_to_virtual(&lava_bubble_ptr_0B006020);
|
||||
frame = (gEnvFxBuffer + index)->animFrame;
|
||||
frame = gEnvFxBuffer[index].animFrame;
|
||||
break;
|
||||
|
||||
case ENVFX_WHIRLPOOL_BUBBLES:
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "engine/surface_collision.h"
|
||||
#include "engine/math_util.h"
|
||||
#include "engine/behavior_script.h"
|
||||
#include "engine/level_script.h"
|
||||
#include "audio/external.h"
|
||||
#include "obj_behaviors.h"
|
||||
#include "pc/utils/misc.h"
|
||||
|
@ -104,10 +105,8 @@ s32 envfx_init_snow(s32 mode) {
|
|||
break;
|
||||
}
|
||||
|
||||
gEnvFxBuffer = mem_pool_alloc(gEffectsMemoryPool, gSnowParticleMaxCount * sizeof(struct EnvFxParticle));
|
||||
if (!gEnvFxBuffer) {
|
||||
return 0;
|
||||
}
|
||||
gEnvFxBuffer = dynamic_pool_alloc(gLevelPool, gSnowParticleMaxCount * sizeof(struct EnvFxParticle));
|
||||
if (!gEnvFxBuffer) { return 0; }
|
||||
|
||||
bzero(gEnvFxBuffer, gSnowParticleMaxCount * sizeof(struct EnvFxParticle));
|
||||
|
||||
|
@ -161,7 +160,7 @@ void envfx_update_snowflake_count(s32 mode, Vec3s marioPos) {
|
|||
void envfx_cleanup_snow(void *snowParticleArray) {
|
||||
if (gEnvFxMode) {
|
||||
if (snowParticleArray) {
|
||||
mem_pool_free(gEffectsMemoryPool, snowParticleArray);
|
||||
dynamic_pool_free(gLevelPool, snowParticleArray);
|
||||
}
|
||||
gEnvFxMode = ENVFX_MODE_NONE;
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ extern struct MainPoolBlock *sPoolListHeadR;
|
|||
* Memory pool for small graphical effects that aren't connected to Objects.
|
||||
* Used for colored text, paintings, and environmental snow and bubbles.
|
||||
*/
|
||||
struct MemoryPool *gEffectsMemoryPool;
|
||||
struct MemoryPool *gEffectsMemoryPool = NULL;
|
||||
|
||||
uintptr_t sSegmentTable[32];
|
||||
u32 sPoolFreeSpace;
|
||||
|
|
|
@ -70,6 +70,7 @@ u32 main_pool_pop_state(void);
|
|||
|
||||
struct DynamicPool* dynamic_pool_init(void);
|
||||
void* dynamic_pool_alloc(struct DynamicPool *pool, u32 size);
|
||||
void dynamic_pool_free(struct DynamicPool *pool, void* ptr);
|
||||
void dynamic_pool_free_pool(struct DynamicPool *pool);
|
||||
|
||||
struct GrowingPool* growing_pool_init(struct GrowingPool* pool, u32 nodeSize);
|
||||
|
|
|
@ -28,6 +28,28 @@ void* dynamic_pool_alloc(struct DynamicPool *pool, u32 size) {
|
|||
return node->ptr;
|
||||
}
|
||||
|
||||
void dynamic_pool_free(struct DynamicPool *pool, void* ptr) {
|
||||
if (!pool || !ptr) { return; }
|
||||
|
||||
struct DynamicPoolNode* node = pool->tail;
|
||||
struct DynamicPoolNode* next = node;
|
||||
|
||||
while (node) {
|
||||
struct DynamicPoolNode* prev = node->prev;
|
||||
if (node->ptr == ptr) {
|
||||
if (pool->tail == node) {
|
||||
pool->tail = prev;
|
||||
} else {
|
||||
next->prev = prev;
|
||||
}
|
||||
free(node->ptr);
|
||||
free(node);
|
||||
}
|
||||
next = node;
|
||||
node = prev;
|
||||
}
|
||||
}
|
||||
|
||||
void dynamic_pool_free_pool(struct DynamicPool *pool) {
|
||||
if (!pool) { return; }
|
||||
struct DynamicPoolNode* node = pool->tail;
|
||||
|
|
Loading…
Reference in a new issue