From 63306443714d4fef1c8eb67beb5370c59ddbf1c1 Mon Sep 17 00:00:00 2001 From: n64 Date: Sat, 4 Jul 2020 11:18:55 -0400 Subject: [PATCH] Refresh 11 --- CHANGES | 11 + Makefile | 6 +- include/object_constants.h | 26 +- include/object_fields.h | 6 +- include/types.h | 2 +- src/audio/external.c | 2 +- src/audio/synthesis.c | 84 +++--- src/audio/synthesis.h | 3 +- src/engine/graph_node.h | 4 +- src/game/behavior_actions.c | 3 +- src/game/behaviors/boo.inc.c | 2 +- src/game/behaviors/bouncing_fireball.inc.c | 4 +- src/game/behaviors/bowling_ball.inc.c | 47 ++-- src/game/behaviors/bowser.inc.c | 20 +- src/game/behaviors/bubba.inc.c | 6 +- src/game/behaviors/bullet_bill.inc.c | 2 +- src/game/behaviors/chuckya.inc.c | 2 +- src/game/behaviors/coin.inc.c | 6 +- src/game/behaviors/donut_platform.inc.c | 2 +- src/game/behaviors/eyerok.inc.c | 16 +- src/game/behaviors/fire_spitter.inc.c | 2 +- src/game/behaviors/flame.inc.c | 2 +- .../behaviors/flying_bookend_switch.inc.c | 2 +- src/game/behaviors/haunted_chair.inc.c | 2 +- src/game/behaviors/heave_ho.inc.c | 4 +- src/game/behaviors/horizontal_grindel.inc.c | 2 +- src/game/behaviors/jumping_box.inc.c | 4 +- src/game/behaviors/king_bobomb.inc.c | 8 +- src/game/behaviors/lll_volcano_flames.inc.c | 4 +- src/game/behaviors/manta_ray.inc.c | 18 +- src/game/behaviors/mr_blizzard.inc.c | 251 +++++++++++++----- src/game/behaviors/mr_i.inc.c | 2 +- src/game/behaviors/racing_penguin.inc.c | 4 +- src/game/behaviors/scuttlebug.inc.c | 8 +- src/game/behaviors/skeeter.inc.c | 10 +- src/game/behaviors/triplet_butterfly.inc.c | 2 +- src/game/behaviors/ukiki.inc.c | 39 ++- src/game/behaviors/whomp.inc.c | 4 +- src/game/debug.c | 2 +- src/game/mario.c | 3 +- src/game/mario_actions_moving.c | 6 +- src/game/mario_misc.c | 2 +- src/game/obj_behaviors.c | 3 +- src/game/object_helpers.c | 35 +-- src/game/rendering_graph_node.c | 21 +- tools/textconv.c | 79 ++++-- 46 files changed, 486 insertions(+), 287 deletions(-) diff --git a/CHANGES b/CHANGES index daadf638..0a561b62 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,14 @@ +Refresh 11 +1.) (HEAD -> master, origin/master, origin/HEAD) Make geo_process_level_of_detail endian-independent (#1049) +2.) Label oMoveFlags and slight cleanup. (#1046) +3.) Avoid UB in synthesis_resample_and_mix_reverb (#1048) +4.) Change some void * to correct type (#1047) +5.) Remove oPathedWaypointsS16 and convert all paths to Trajectory struct. (#1045) +6.) Mr Blizzard documentation, Tox Box Unks (#1042) +7.) Pipe input to textconv. (#1041) +8.) Remove erroneous long double casts from audiofile.cpp (#1039) +9.) Replace fixed dialogID in play_dialog_sound to DIALOG_COUNT (#1040) + Refresh #10.1 1.) Diff update (#1033) 2.) Fix texture dimensions for exclamation boxes (#1034) diff --git a/Makefile b/Makefile index db3f8d87..09bbba36 100644 --- a/Makefile +++ b/Makefile @@ -766,12 +766,10 @@ endif endif $(BUILD_DIR)/text/%/define_courses.inc.c: text/define_courses.inc.c text/%/courses.h - $(CPP) $(VERSION_CFLAGS) $< -o $@ -I text/$*/ - $(TEXTCONV) charmap.txt $@ $@ + $(CPP) $(VERSION_CFLAGS) $< -o - -I text/$*/ | $(TEXTCONV) charmap.txt - $@ $(BUILD_DIR)/text/%/define_text.inc.c: text/define_text.inc.c text/%/courses.h text/%/dialogs.h - $(CPP) $(VERSION_CFLAGS) $< -o $@ -I text/$*/ - $(TEXTCONV) charmap.txt $@ $@ + $(CPP) $(VERSION_CFLAGS) $< -o - -I text/$*/ | $(TEXTCONV) charmap.txt - $@ RSP_DIRS := $(BUILD_DIR)/rsp ALL_DIRS := $(BUILD_DIR) $(addprefix $(BUILD_DIR)/,$(SRC_DIRS) $(ASM_DIRS) $(GODDARD_SRC_DIRS) $(ULTRA_SRC_DIRS) $(ULTRA_ASM_DIRS) $(ULTRA_BIN_DIRS) $(BIN_DIRS) $(TEXTURE_DIRS) $(TEXT_DIRS) $(SOUND_SAMPLE_DIRS) $(addprefix levels/,$(LEVEL_DIRS)) include) $(MIO0_DIR) $(addprefix $(MIO0_DIR)/,$(VERSION)) $(SOUND_BIN_DIR) $(SOUND_BIN_DIR)/sequences/$(VERSION) $(RSP_DIRS) diff --git a/include/object_constants.h b/include/object_constants.h index 4dcbb4c2..82a16769 100644 --- a/include/object_constants.h +++ b/include/object_constants.h @@ -80,30 +80,22 @@ #define OBJ_MOVE_UNDERWATER_OFF_GROUND (1 << 5) // 0x0020 #define OBJ_MOVE_UNDERWATER_ON_GROUND (1 << 6) // 0x0040 #define OBJ_MOVE_IN_AIR (1 << 7) // 0x0080 -#define OBJ_MOVE_8 (1 << 8) // 0x0100 +#define OBJ_MOVE_OUT_SCOPE (1 << 8) // 0x0100 #define OBJ_MOVE_HIT_WALL (1 << 9) // 0x0200 #define OBJ_MOVE_HIT_EDGE (1 << 10) // 0x0400 #define OBJ_MOVE_ABOVE_LAVA (1 << 11) // 0x0800 #define OBJ_MOVE_LEAVING_WATER (1 << 12) // 0x1000 -#define OBJ_MOVE_13 (1 << 13) // 0x2000 +#define OBJ_MOVE_BOUNCE (1 << 13) // 0x2000 #ifndef VERSION_JP #define OBJ_MOVE_ABOVE_DEATH_BARRIER (1 << 14) // 0x4000 #endif #define OBJ_MOVE_MASK_ON_GROUND (OBJ_MOVE_LANDED | OBJ_MOVE_ON_GROUND) -#define OBJ_MOVE_MASK_33 0x33 #define OBJ_MOVE_MASK_IN_WATER (\ OBJ_MOVE_ENTERED_WATER |\ OBJ_MOVE_AT_WATER_SURFACE |\ OBJ_MOVE_UNDERWATER_OFF_GROUND |\ OBJ_MOVE_UNDERWATER_ON_GROUND) -#define OBJ_MOVE_MASK_HIT_WALL_OR_IN_WATER \ - (OBJ_MOVE_HIT_WALL | OBJ_MOVE_MASK_IN_WATER) -#define OBJ_MOVE_MASK_NOT_AIR (\ - OBJ_MOVE_LANDED |\ - OBJ_MOVE_ON_GROUND |\ - OBJ_MOVE_AT_WATER_SURFACE |\ - OBJ_MOVE_UNDERWATER_ON_GROUND) /* oActiveParticleFlags */ #define ACTIVE_PARTICLE_DUST (1 << 0) // 0x00000001 @@ -971,4 +963,18 @@ #define BOWSER_PUZZLE_ACT_WAIT_FOR_COMPLETE 1 #define BOWSER_PUZZLE_ACT_DONE 2 +/* Mr Blizzard */ + /* oAction */ + #define MR_BLIZZARD_ACT_SPAWN_SNOWBALL 0 + #define MR_BLIZZARD_ACT_HIDE_UNHIDE 1 + #define MR_BLIZZARD_ACT_RISE_FROM_GROUND 2 + #define MR_BLIZZARD_ACT_ROTATE 3 + #define MR_BLIZZARD_ACT_THROW_SNOWBALL 4 + #define MR_BLIZZARD_ACT_BURROW 5 + #define MR_BLIZZARD_ACT_DEATH 6 + #define MR_BLIZZARD_ACT_JUMP 7 + /* oBehParams2ndByte */ + #define MR_BLIZZARD_STYPE_NO_CAP 0 + #define MR_BLIZZARD_STYPE_JUMPING 1 + #endif // OBJECT_CONSTANTS_H diff --git a/include/object_fields.h b/include/object_fields.h index 39a41524..9f2661ce 100644 --- a/include/object_fields.h +++ b/include/object_fields.h @@ -136,8 +136,6 @@ #define /*0x1C4*/ oDeathSound OBJECT_FIELD_S32(0x4F) /* Pathed (see obj_follow_path) */ -// TODO: These two 0x0FC fields need merged, one is data and one is a C struct. -#define /*0x0FC*/ oPathedWaypointsS16 OBJECT_FIELD_VPTR(0x1D) #define /*0x0FC*/ oPathedStartWaypoint OBJECT_FIELD_WAYPOINT(0x1D) #define /*0x100*/ oPathedPrevWaypoint OBJECT_FIELD_WAYPOINT(0x1E) #define /*0x104*/ oPathedPrevWaypointFlags OBJECT_FIELD_S32(0x1F) @@ -966,8 +964,8 @@ #define /*0x110*/ oToadMessageState OBJECT_FIELD_S32(0x22) /* Tox Box */ -#define /*0x1AC*/ oToxBoxUnk1AC OBJECT_FIELD_VPTR(0x49) -#define /*0x1B0*/ oToxBoxUnk1B0 OBJECT_FIELD_S32(0x4A) +#define /*0x1AC*/ oToxBoxMovementPattern OBJECT_FIELD_VPTR(0x49) +#define /*0x1B0*/ oToxBoxMovementStep OBJECT_FIELD_S32(0x4A) /* TTC Rotating Solid */ #define /*0x0F4*/ oTTCRotatingSolidNumTurns OBJECT_FIELD_S32(0x1B) diff --git a/include/types.h b/include/types.h index 19256d74..b3dc27e2 100644 --- a/include/types.h +++ b/include/types.h @@ -131,7 +131,7 @@ struct GraphNodeObject /*0x2C*/ Vec3f scale; /*0x38*/ struct GraphNodeObject_sub unk38; /*0x4C*/ struct SpawnInfo *unk4C; - /*0x50*/ void *throwMatrix; // matrix ptr + /*0x50*/ Mat4 *throwMatrix; // matrix ptr /*0x54*/ Vec3f cameraToObject; }; diff --git a/src/audio/external.c b/src/audio/external.c index 934510b0..d8a26b35 100644 --- a/src/audio/external.c +++ b/src/audio/external.c @@ -2035,7 +2035,7 @@ void func_80320A4C(u8 bankIndex, u8 arg1) { void play_dialog_sound(u8 dialogID) { u8 speaker; - if (dialogID >= 170) { + if (dialogID >= DIALOG_COUNT) { dialogID = 0; } diff --git a/src/audio/synthesis.c b/src/audio/synthesis.c index 8a907c81..1fdd8510 100644 --- a/src/audio/synthesis.c +++ b/src/audio/synthesis.c @@ -11,8 +11,8 @@ #define DMEM_ADDR_TEMP 0x0 #define DMEM_ADDR_UNCOMPRESSED_NOTE 0x180 -#define DMEM_ADDR_ADPCM_RESAMPLED 0x20 -#define DMEM_ADDR_ADPCM_RESAMPLED2 0x160 +#define DMEM_ADDR_RESAMPLED 0x20 +#define DMEM_ADDR_RESAMPLED2 0x160 #define DMEM_ADDR_NOTE_PAN_TEMP 0x200 #define DMEM_ADDR_STEREO_STRONG_TEMP_DRY 0x200 #define DMEM_ADDR_STEREO_STRONG_TEMP_WET 0x340 @@ -100,14 +100,14 @@ void prepare_reverb_ring_buffer(s32 chunkLen, u32 updateIndex, s32 reverbIndex) // Touches both left and right since they are adjacent in memory osInvalDCache(item->toDownsampleLeft, DEFAULT_LEN_2CH); - for (srcPos = 0, dstPos = 0; dstPos < item->lengths[0] / 2; + for (srcPos = 0, dstPos = 0; dstPos < item->lengthA / 2; srcPos += reverb->downsampleRate, dstPos++) { reverb->ringBuffer.left[item->startPos + dstPos] = item->toDownsampleLeft[srcPos]; reverb->ringBuffer.right[item->startPos + dstPos] = item->toDownsampleRight[srcPos]; } - for (dstPos = 0; dstPos < item->lengths[1] / 2; srcPos += reverb->downsampleRate, dstPos++) { + for (dstPos = 0; dstPos < item->lengthB / 2; srcPos += reverb->downsampleRate, dstPos++) { reverb->ringBuffer.left[dstPos] = item->toDownsampleLeft[srcPos]; reverb->ringBuffer.right[dstPos] = item->toDownsampleRight[srcPos]; } @@ -119,14 +119,14 @@ void prepare_reverb_ring_buffer(s32 chunkLen, u32 updateIndex, s32 reverbIndex) excessiveSamples = (nSamples + reverb->nextRingBufferPos) - reverb->bufSizePerChannel; if (excessiveSamples < 0) { // There is space in the ring buffer before it wraps around - item->lengths[0] = nSamples * 2; - item->lengths[1] = 0; + item->lengthA = nSamples * 2; + item->lengthB = 0; item->startPos = (s32) reverb->nextRingBufferPos; reverb->nextRingBufferPos += nSamples; } else { // Ring buffer wrapped around - item->lengths[0] = (nSamples - excessiveSamples) * 2; - item->lengths[1] = excessiveSamples * 2; + item->lengthA = (nSamples - excessiveSamples) * 2; + item->lengthB = excessiveSamples * 2; item->startPos = reverb->nextRingBufferPos; reverb->nextRingBufferPos = excessiveSamples; } @@ -151,14 +151,14 @@ void prepare_reverb_ring_buffer(s32 chunkLen, u32 updateIndex) { // Touches both left and right since they are adjacent in memory osInvalDCache(item->toDownsampleLeft, DEFAULT_LEN_2CH); - for (srcPos = 0, dstPos = 0; dstPos < item->lengths[0] / 2; + for (srcPos = 0, dstPos = 0; dstPos < item->lengthA / 2; srcPos += gReverbDownsampleRate, dstPos++) { gSynthesisReverb.ringBuffer.left[dstPos + item->startPos] = item->toDownsampleLeft[srcPos]; gSynthesisReverb.ringBuffer.right[dstPos + item->startPos] = item->toDownsampleRight[srcPos]; } - for (dstPos = 0; dstPos < item->lengths[1] / 2; srcPos += gReverbDownsampleRate, dstPos++) { + for (dstPos = 0; dstPos < item->lengthB / 2; srcPos += gReverbDownsampleRate, dstPos++) { gSynthesisReverb.ringBuffer.left[dstPos] = item->toDownsampleLeft[srcPos]; gSynthesisReverb.ringBuffer.right[dstPos] = item->toDownsampleRight[srcPos]; } @@ -169,8 +169,8 @@ void prepare_reverb_ring_buffer(s32 chunkLen, u32 updateIndex) { numSamplesAfterDownsampling = chunkLen / gReverbDownsampleRate; if (((numSamplesAfterDownsampling + gSynthesisReverb.nextRingBufferPos) - gSynthesisReverb.bufSizePerChannel) < 0) { // There is space in the ring buffer before it wraps around - item->lengths[0] = numSamplesAfterDownsampling * 2; - item->lengths[1] = 0; + item->lengthA = numSamplesAfterDownsampling * 2; + item->lengthB = 0; item->startPos = (s32) gSynthesisReverb.nextRingBufferPos; gSynthesisReverb.nextRingBufferPos += numSamplesAfterDownsampling; } else { @@ -178,8 +178,8 @@ void prepare_reverb_ring_buffer(s32 chunkLen, u32 updateIndex) { excessiveSamples = (numSamplesAfterDownsampling + gSynthesisReverb.nextRingBufferPos) - gSynthesisReverb.bufSizePerChannel; nSamples = numSamplesAfterDownsampling - excessiveSamples; - item->lengths[0] = nSamples * 2; - item->lengths[1] = excessiveSamples * 2; + item->lengthA = nSamples * 2; + item->lengthB = excessiveSamples * 2; item->startPos = gSynthesisReverb.nextRingBufferPos; gSynthesisReverb.nextRingBufferPos = excessiveSamples; } @@ -349,33 +349,33 @@ u64 *synthesis_execute(u64 *cmdBuf, s32 *writtenCmds, s16 *aiBuf, s32 bufLen) { #ifdef VERSION_EU u64 *synthesis_resample_and_mix_reverb(u64 *cmd, s32 bufLen, s16 reverbIndex, s16 updateIndex) { struct ReverbRingBufferItem *item; - s16 temp_t9; // sp5a - s16 sp58; // sp58 + s16 startPad; + s16 paddedLengthA; item = &gSynthesisReverbs[reverbIndex].items[gSynthesisReverbs[reverbIndex].curFrame][updateIndex]; aClearBuffer(cmd++, DMEM_ADDR_WET_LEFT_CH, DEFAULT_LEN_2CH); if (gSynthesisReverbs[reverbIndex].downsampleRate == 1) { - cmd = synthesis_load_reverb_ring_buffer(cmd, DMEM_ADDR_WET_LEFT_CH, item->startPos, item->lengths[0], reverbIndex); - if (item->lengths[1] != 0) { - cmd = synthesis_load_reverb_ring_buffer(cmd, DMEM_ADDR_WET_LEFT_CH + item->lengths[0], 0, item->lengths[1], reverbIndex); + cmd = synthesis_load_reverb_ring_buffer(cmd, DMEM_ADDR_WET_LEFT_CH, item->startPos, item->lengthA, reverbIndex); + if (item->lengthB != 0) { + cmd = synthesis_load_reverb_ring_buffer(cmd, DMEM_ADDR_WET_LEFT_CH + item->lengthA, 0, item->lengthB, reverbIndex); } aSetBuffer(cmd++, 0, 0, 0, DEFAULT_LEN_2CH); aMix(cmd++, 0, 0x7fff, DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_LEFT_CH); aMix(cmd++, 0, 0x8000 + gSynthesisReverbs[reverbIndex].reverbGain, DMEM_ADDR_WET_LEFT_CH, DMEM_ADDR_WET_LEFT_CH); } else { - temp_t9 = (item->startPos % 8u) * 2; - sp58 = ALIGN(item->lengths[0] + (sp58=temp_t9), 4); + startPad = (item->startPos % 8u) * 2; + paddedLengthA = ALIGN(startPad + item->lengthA, 4); - cmd = synthesis_load_reverb_ring_buffer(cmd, 0x20, (item->startPos - temp_t9 / 2), DEFAULT_LEN_1CH, reverbIndex); - if (item->lengths[1] != 0) { - cmd = synthesis_load_reverb_ring_buffer(cmd, 0x20 + sp58, 0, DEFAULT_LEN_1CH - sp58, reverbIndex); + cmd = synthesis_load_reverb_ring_buffer(cmd, DMEM_ADDR_RESAMPLED, (item->startPos - startPad / 2), DEFAULT_LEN_1CH, reverbIndex); + if (item->lengthB != 0) { + cmd = synthesis_load_reverb_ring_buffer(cmd, DMEM_ADDR_RESAMPLED + paddedLengthA, 0, DEFAULT_LEN_1CH - paddedLengthA, reverbIndex); } - aSetBuffer(cmd++, 0, temp_t9 + DMEM_ADDR_ADPCM_RESAMPLED, DMEM_ADDR_WET_LEFT_CH, bufLen * 2); + aSetBuffer(cmd++, 0, DMEM_ADDR_RESAMPLED + startPad, DMEM_ADDR_WET_LEFT_CH, bufLen * 2); aResample(cmd++, gSynthesisReverbs[reverbIndex].resampleFlags, gSynthesisReverbs[reverbIndex].resampleRate, VIRTUAL_TO_PHYSICAL2(gSynthesisReverbs[reverbIndex].resampleStateLeft)); - aSetBuffer(cmd++, 0, temp_t9 + DMEM_ADDR_ADPCM_RESAMPLED2, DMEM_ADDR_WET_RIGHT_CH, bufLen * 2); + aSetBuffer(cmd++, 0, DMEM_ADDR_RESAMPLED2 + startPad, DMEM_ADDR_WET_RIGHT_CH, bufLen * 2); aResample(cmd++, gSynthesisReverbs[reverbIndex].resampleFlags, gSynthesisReverbs[reverbIndex].resampleRate, VIRTUAL_TO_PHYSICAL2(gSynthesisReverbs[reverbIndex].resampleStateRight)); aSetBuffer(cmd++, 0, 0, 0, DEFAULT_LEN_2CH); @@ -397,10 +397,10 @@ u64 *synthesis_save_reverb_samples(u64 *cmdBuf, s16 reverbIndex, s16 updateIndex } if (reverb->downsampleRate == 1) { // Put the oldest samples in the ring buffer into the wet channels - cmd = cmdBuf = synthesis_save_reverb_ring_buffer(cmd, DMEM_ADDR_WET_LEFT_CH, item->startPos, item->lengths[0], reverbIndex); - if (item->lengths[1] != 0) { + cmd = cmdBuf = synthesis_save_reverb_ring_buffer(cmd, DMEM_ADDR_WET_LEFT_CH, item->startPos, item->lengthA, reverbIndex); + if (item->lengthB != 0) { // Ring buffer wrapped - cmd = synthesis_save_reverb_ring_buffer(cmd, DMEM_ADDR_WET_LEFT_CH + item->lengths[0], 0, item->lengths[1], reverbIndex); + cmd = synthesis_save_reverb_ring_buffer(cmd, DMEM_ADDR_WET_LEFT_CH + item->lengthA, 0, item->lengthB, reverbIndex); cmdBuf = cmd; } } else { @@ -513,9 +513,9 @@ u64 *synthesis_do_one_audio_update(s16 *aiBuf, s32 bufLen, u64 *cmd, u32 updateI if (gReverbDownsampleRate == 1) { // Put the oldest samples in the ring buffer into the wet channels aSetLoadBufferPair(cmd++, 0, v1->startPos); - if (v1->lengths[1] != 0) { + if (v1->lengthB != 0) { // Ring buffer wrapped - aSetLoadBufferPair(cmd++, v1->lengths[0], 0); + aSetLoadBufferPair(cmd++, v1->lengthA, 0); temp = 0; } @@ -532,9 +532,9 @@ u64 *synthesis_do_one_audio_update(s16 *aiBuf, s32 bufLen, u64 *cmd, u32 updateI // Same as above but upsample the previously downsampled samples used for reverb first temp = 0; //! jesus christ t4 = (v1->startPos & 7) * 2; - ra = ALIGN(v1->lengths[0] + t4, 4); + ra = ALIGN(v1->lengthA + t4, 4); aSetLoadBufferPair(cmd++, 0, v1->startPos - t4 / 2); - if (v1->lengths[1] != 0) { + if (v1->lengthB != 0) { // Ring buffer wrapped aSetLoadBufferPair(cmd++, ra, 0); //! We need an empty statement (even an empty ';') here to make the function match (because IDO). @@ -553,10 +553,10 @@ u64 *synthesis_do_one_audio_update(s16 *aiBuf, s32 bufLen, u64 *cmd, u32 updateI } cmd = synthesis_process_notes(aiBuf, bufLen, cmd); if (gReverbDownsampleRate == 1) { - aSetSaveBufferPair(cmd++, 0, v1->lengths[0], v1->startPos); - if (v1->lengths[1] != 0) { + aSetSaveBufferPair(cmd++, 0, v1->lengthA, v1->startPos); + if (v1->lengthB != 0) { // Ring buffer wrapped - aSetSaveBufferPair(cmd++, v1->lengths[0], v1->lengths[1], 0); + aSetSaveBufferPair(cmd++, v1->lengthA, v1->lengthB, 0); } } else { // Downsampling is done later by CPU when RSP is done, therefore we need to have double @@ -967,26 +967,26 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { case 2: switch (curPart) { case 0: - aSetBuffer(cmd++, 0, DMEM_ADDR_UNCOMPRESSED_NOTE + sp130, DMEM_ADDR_ADPCM_RESAMPLED, samplesLenAdjusted + 4); + aSetBuffer(cmd++, 0, DMEM_ADDR_UNCOMPRESSED_NOTE + sp130, DMEM_ADDR_RESAMPLED, samplesLenAdjusted + 4); #ifdef VERSION_EU aResample(cmd++, A_INIT, 0xff60, VIRTUAL_TO_PHYSICAL2(synthesisState->synthesisBuffers->dummyResampleState)); #else aResample(cmd++, A_INIT, 0xff60, VIRTUAL_TO_PHYSICAL2(note->synthesisBuffers->dummyResampleState)); #endif resampledTempLen = samplesLenAdjusted + 4; - noteSamplesDmemAddrBeforeResampling = DMEM_ADDR_ADPCM_RESAMPLED + 4; + noteSamplesDmemAddrBeforeResampling = DMEM_ADDR_RESAMPLED + 4; #ifdef VERSION_EU if (noteSubEu->finished != FALSE) { #else if (note->finished != FALSE) { #endif - aClearBuffer(cmd++, DMEM_ADDR_ADPCM_RESAMPLED + resampledTempLen, samplesLenAdjusted + 0x10); + aClearBuffer(cmd++, DMEM_ADDR_RESAMPLED + resampledTempLen, samplesLenAdjusted + 0x10); } break; case 1: aSetBuffer(cmd++, 0, DMEM_ADDR_UNCOMPRESSED_NOTE + sp130, - DMEM_ADDR_ADPCM_RESAMPLED2, + DMEM_ADDR_RESAMPLED2, samplesLenAdjusted + 8); #ifdef VERSION_EU aResample(cmd++, A_INIT, 0xff60, @@ -997,8 +997,8 @@ u64 *synthesis_process_notes(s16 *aiBuf, s32 bufLen, u64 *cmd) { VIRTUAL_TO_PHYSICAL2( note->synthesisBuffers->dummyResampleState)); #endif - aDMEMMove(cmd++, DMEM_ADDR_ADPCM_RESAMPLED2 + 4, - DMEM_ADDR_ADPCM_RESAMPLED + resampledTempLen, + aDMEMMove(cmd++, DMEM_ADDR_RESAMPLED2 + 4, + DMEM_ADDR_RESAMPLED + resampledTempLen, samplesLenAdjusted + 4); break; } diff --git a/src/audio/synthesis.h b/src/audio/synthesis.h index 698358c8..a82363b1 100644 --- a/src/audio/synthesis.h +++ b/src/audio/synthesis.h @@ -19,7 +19,8 @@ struct ReverbRingBufferItem s16 *toDownsampleLeft; s16 *toDownsampleRight; // data pointed to by left and right are adjacent in memory s32 startPos; // start pos in ring buffer - s16 lengths[2]; // first length in ring buffer (max until end) and second length in ring buffer (from pos 0) + s16 lengthA; // first length in ring buffer (from startPos, at most until end) + s16 lengthB; // second length in ring buffer (from pos 0) }; // size = 0x14 struct SynthesisReverb diff --git a/src/engine/graph_node.h b/src/engine/graph_node.h index 332522d5..802d97a8 100644 --- a/src/engine/graph_node.h +++ b/src/engine/graph_node.h @@ -117,7 +117,7 @@ struct GraphNodePerspective */ struct DisplayListNode { - void *transform; + Mtx *transform; void *displayList; struct DisplayListNode *next; }; @@ -185,7 +185,7 @@ struct GraphNodeCamera } config; /*0x1C*/ Vec3f pos; /*0x28*/ Vec3f focus; - /*0x34*/ void *matrixPtr; // pointer to look-at matrix of this camera as a Mat4 + /*0x34*/ Mat4 *matrixPtr; // pointer to look-at matrix of this camera as a Mat4 /*0x38*/ s16 roll; // roll in look at matrix. Doesn't account for light direction unlike rollScreen. /*0x3A*/ s16 rollScreen; // rolls screen while keeping the light direction consistent }; diff --git a/src/game/behavior_actions.c b/src/game/behavior_actions.c index 246d2334..b40408b3 100644 --- a/src/game/behavior_actions.c +++ b/src/game/behavior_actions.c @@ -19,6 +19,7 @@ #include "game_init.h" #include "ingame_menu.h" #include "interaction.h" +#include "level_misc_macros.h" #include "level_table.h" #include "level_update.h" #include "levels/bob/header.h" @@ -173,7 +174,7 @@ Gfx *geo_move_mario_part_from_parent(s32 run, UNUSED struct GraphNode *node, Mat if (run == TRUE) { sp1C = (struct Object *) gCurGraphNodeObject; if (sp1C == gMarioObject && sp1C->prevObj != NULL) { - create_transformation_from_matrices(sp20, mtx, gCurGraphNodeCamera->matrixPtr); + create_transformation_from_matrices(sp20, mtx, *gCurGraphNodeCamera->matrixPtr); obj_update_pos_from_parent_transformation(sp20, sp1C->prevObj); obj_set_gfx_pos_from_pos(sp1C->prevObj); } diff --git a/src/game/behaviors/boo.inc.c b/src/game/behaviors/boo.inc.c index 8525e28f..abfaba86 100644 --- a/src/game/behaviors/boo.inc.c +++ b/src/game/behaviors/boo.inc.c @@ -273,7 +273,7 @@ static s32 boo_update_during_death(void) { o->oBooTargetOpacity = 0; } - if (o->oTimer > 30 || o->oMoveFlags & 0x200) { + if (o->oTimer > 30 || o->oMoveFlags & OBJ_MOVE_HIT_WALL) { spawn_mist_particles(); o->oBooDeathStatus = BOO_DEATH_STATUS_DEAD; diff --git a/src/game/behaviors/bouncing_fireball.inc.c b/src/game/behaviors/bouncing_fireball.inc.c index 8cf6b99c..89dcfd18 100644 --- a/src/game/behaviors/bouncing_fireball.inc.c +++ b/src/game/behaviors/bouncing_fireball.inc.c @@ -9,7 +9,7 @@ void bhv_bouncing_fireball_flame_loop(void) { o->oAnimState = random_float() * 10.0f; o->oVelY = 30.0f; } - if (o->oMoveFlags & 1) + if (o->oMoveFlags & OBJ_MOVE_LANDED) o->oAction++; break; case 1: @@ -17,7 +17,7 @@ void bhv_bouncing_fireball_flame_loop(void) { o->oVelY = 50.0f; o->oForwardVel = 30.0f; } - if (o->oMoveFlags & (0x40 | 0x10 | 0x2) && o->oTimer > 100) + if (o->oMoveFlags & (OBJ_MOVE_UNDERWATER_ON_GROUND | OBJ_MOVE_AT_WATER_SURFACE | OBJ_MOVE_ON_GROUND) && o->oTimer > 100) obj_mark_for_deletion(o); break; } diff --git a/src/game/behaviors/bowling_ball.inc.c b/src/game/behaviors/bowling_ball.inc.c index d9d58ced..f1e16cb1 100644 --- a/src/game/behaviors/bowling_ball.inc.c +++ b/src/game/behaviors/bowling_ball.inc.c @@ -12,19 +12,32 @@ static struct ObjectHitbox sBowlingBallHitbox = { /* hurtboxHeight: */ 0, }; -// TODO: these are likely Waypoint structs -static s16 D_803315B4[] = { 0x0000, 0xED4E, 0x0065, 0xF78A, 0x0001, 0xEC78, 0x0051, 0xF53F, 0x0002, - 0xEC50, 0x0021, 0xF0FA, 0x0003, 0xEC9A, 0x0026, 0xEC9A, 0x0004, 0xF053, - 0xFEFD, 0xECE3, 0x0005, 0xF5F3, 0xFC05, 0xED54, 0x0006, 0xFBE3, 0xFA89, - 0xED3A, 0x0007, 0x02F8, 0xF99B, 0xED1F, 0x0008, 0x0B32, 0xF801, 0xECEA, - 0x0009, 0x0D3A, 0xE66E, 0xED1F, 0xFFFF, 0x0000 }; +static Trajectory sThiHugeMetalBallTraj[] = { + TRAJECTORY_POS(0, /*pos*/ -4786, 101, -2166), + TRAJECTORY_POS(1, /*pos*/ -5000, 81, -2753), + TRAJECTORY_POS(2, /*pos*/ -5040, 33, -3846), + TRAJECTORY_POS(3, /*pos*/ -4966, 38, -4966), + TRAJECTORY_POS(4, /*pos*/ -4013, -259, -4893), + TRAJECTORY_POS(5, /*pos*/ -2573, -1019, -4780), + TRAJECTORY_POS(6, /*pos*/ -1053, -1399, -4806), + TRAJECTORY_POS(7, /*pos*/ 760, -1637, -4833), + TRAJECTORY_POS(8, /*pos*/ 2866, -2047, -4886), + TRAJECTORY_POS(9, /*pos*/ 3386, -6546, -4833), + TRAJECTORY_END(), +}; -// TODO: these are likely Waypoint structs -static s16 D_80331608[] = { 0x0000, 0xFA3C, 0x001D, 0xFD58, 0x0001, 0xFA2C, 0x000E, 0xFBD0, - 0x0002, 0xFA24, 0x0003, 0xFACD, 0x0003, 0xFAA2, 0xFFEF, 0xFA09, - 0x0004, 0xFB66, 0xFFAD, 0xFA28, 0x0005, 0xFEDC, 0xFE58, 0xFA6F, - 0x0006, 0x00FA, 0xFE15, 0xFA67, 0x0007, 0x035E, 0xFD9B, 0xFA57, - 0x0008, 0x0422, 0xF858, 0xFA57, 0xFFFF, 0x0000 }; +static Trajectory sThiTinyMetalBallTraj[] = { + TRAJECTORY_POS(0, /*pos*/ -1476, 29, -680), + TRAJECTORY_POS(1, /*pos*/ -1492, 14, -1072), + TRAJECTORY_POS(2, /*pos*/ -1500, 3, -1331), + TRAJECTORY_POS(3, /*pos*/ -1374, -17, -1527), + TRAJECTORY_POS(4, /*pos*/ -1178, -83, -1496), + TRAJECTORY_POS(5, /*pos*/ -292, -424, -1425), + TRAJECTORY_POS(6, /*pos*/ 250, -491, -1433), + TRAJECTORY_POS(7, /*pos*/ 862, -613, -1449), + TRAJECTORY_POS(8, /*pos*/ 1058, -1960, -1449), + TRAJECTORY_END(), +}; void bhv_bowling_ball_init(void) { o->oGravity = 5.5f; @@ -42,23 +55,23 @@ void bowling_ball_set_hitbox(void) { void bowling_ball_set_waypoints(void) { switch (o->oBehParams2ndByte) { case BBALL_BP_STYPE_BOB_UPPER: - o->oPathedWaypointsS16 = segmented_to_virtual(bob_seg7_metal_ball_path0); + o->oPathedStartWaypoint = segmented_to_virtual(bob_seg7_metal_ball_path0); break; case BBALL_BP_STYPE_TTM: - o->oPathedWaypointsS16 = segmented_to_virtual(ttm_seg7_trajectory_070170A0); + o->oPathedStartWaypoint = segmented_to_virtual(ttm_seg7_trajectory_070170A0); break; case BBALL_BP_STYPE_BOB_LOWER: - o->oPathedWaypointsS16 = segmented_to_virtual(bob_seg7_metal_ball_path1); + o->oPathedStartWaypoint = segmented_to_virtual(bob_seg7_metal_ball_path1); break; case BBALL_BP_STYPE_THI_LARGE: - o->oPathedWaypointsS16 = D_803315B4; + o->oPathedStartWaypoint = (struct Waypoint *) sThiHugeMetalBallTraj; break; case BBALL_BP_STYPE_THI_SMALL: - o->oPathedWaypointsS16 = D_80331608; + o->oPathedStartWaypoint = (struct Waypoint *) sThiTinyMetalBallTraj; break; } } diff --git a/src/game/behaviors/bowser.inc.c b/src/game/behaviors/bowser.inc.c index 357505a1..ebc6bf47 100644 --- a/src/game/behaviors/bowser.inc.c +++ b/src/game/behaviors/bowser.inc.c @@ -106,7 +106,7 @@ s32 bowser_spawn_shockwave(void) { } void bowser_bounce(s32 *a) { - if (o->oMoveFlags & 1) { + if (o->oMoveFlags & OBJ_MOVE_LANDED) { a[0]++; if (a[0] < 4) { cur_obj_start_cam_event(o, CAM_EVENT_BOWSER_THROW_BOUNCE); @@ -453,7 +453,7 @@ s32 bowser_set_anim_in_air(void) { } s32 bowser_land(void) { - if (o->oMoveFlags & 1) { + if (o->oMoveFlags & OBJ_MOVE_LANDED) { o->oForwardVel = 0; o->oVelY = 0; spawn_mist_particles_variable(0, 0, 60.0f); @@ -627,7 +627,7 @@ void bowser_act_charge_mario(void) { cur_obj_extend_animation_if_at_end(); break; } - if (o->oMoveFlags & 0x400) + if (o->oMoveFlags & OBJ_MOVE_HIT_EDGE) o->oAction = 10; } @@ -650,7 +650,7 @@ void bowser_act_thrown_dropped(void) if (o->oSubAction == 0) { cur_obj_init_animation_with_sound(2); bowser_bounce(&o->oBowserUnkF8); - if (o->oMoveFlags & 2) { + if (o->oMoveFlags & OBJ_MOVE_ON_GROUND) { o->oForwardVel = 0.0f; o->oSubAction++; } @@ -780,9 +780,9 @@ void bowser_fly_back_dead(void) { void bowser_dead_bounce(void) { o->oBowserEyesShut = 1; bowser_bounce(&o->oBowserUnkF8); - if (o->oMoveFlags & 1) + if (o->oMoveFlags & OBJ_MOVE_LANDED) cur_obj_play_sound_2(SOUND_OBJ_BOWSER_WALK); - if (o->oMoveFlags & 2) { + if (o->oMoveFlags & OBJ_MOVE_ON_GROUND) { o->oForwardVel = 0.0f; o->oSubAction++; } @@ -962,7 +962,7 @@ s32 bowser_check_fallen_off_stage(void) // bowser off stage? if (o->oAction != 2 && o->oAction != 19) { if (o->oPosY < o->oHomeY - 1000.0f) return 1; - if (o->oMoveFlags & 1) { + if (o->oMoveFlags & OBJ_MOVE_LANDED) { if (o->oFloorType == 1) return 1; if (o->oFloorType == 10) @@ -1168,7 +1168,7 @@ Gfx *geo_update_body_rot_from_parent(s32 run, UNUSED struct GraphNode *node, Mat if (run == TRUE) { sp1C = (struct Object *) gCurGraphNodeObject; if (sp1C->prevObj != NULL) { - create_transformation_from_matrices(sp20, mtx, gCurGraphNodeCamera->matrixPtr); + create_transformation_from_matrices(sp20, mtx, *gCurGraphNodeCamera->matrixPtr); obj_update_pos_from_parent_transformation(sp20, sp1C->prevObj); obj_set_gfx_pos_from_pos(sp1C->prevObj); } @@ -1424,7 +1424,7 @@ void bhv_flame_bowser_loop(void) { if (o->oAction == 0) { cur_obj_become_intangible(); bowser_flame_move(); - if (o->oMoveFlags & 1) { + if (o->oMoveFlags & OBJ_MOVE_LANDED) { o->oAction++; if (cur_obj_has_behavior(bhvFlameLargeBurningOut)) o->oFlameUnkF4 = 8.0f; @@ -1494,7 +1494,7 @@ void bhv_flame_floating_landing_loop(void) { obj_mark_for_deletion(o); if (o->oVelY < D_8032F748[o->oBehParams2ndByte]) o->oVelY = D_8032F748[o->oBehParams2ndByte]; - if (o->oMoveFlags & 1) { + if (o->oMoveFlags & OBJ_MOVE_LANDED) { if (o->oBehParams2ndByte == 0) spawn_object(o, MODEL_RED_FLAME, bhvFlameLargeBurningOut); else diff --git a/src/game/behaviors/bubba.inc.c b/src/game/behaviors/bubba.inc.c index 742ec15f..5ce25f59 100644 --- a/src/game/behaviors/bubba.inc.c +++ b/src/game/behaviors/bubba.inc.c @@ -33,7 +33,7 @@ void bubba_act_0(void) { o->oBubbaUnkF8 = random_linear_offset(20, 30); } - if ((o->oBubbaUnkFC = o->oMoveFlags & 0x00000200) != 0) { + if ((o->oBubbaUnkFC = o->oMoveFlags & OBJ_MOVE_HIT_WALL) != 0) { o->oBubbaUnk1AE = cur_obj_reflect_move_angle_off_wall(); } else if (o->oTimer > 30 && o->oDistanceToMario < 2000.0f) { o->oAction = 1; @@ -130,8 +130,8 @@ void bhv_bubba_loop(void) { break; } - if (o->oMoveFlags & 0x00000078) { - if (o->oMoveFlags & 0x00000008) { + if (o->oMoveFlags & OBJ_MOVE_MASK_IN_WATER) { + if (o->oMoveFlags & OBJ_MOVE_ENTERED_WATER) { sp38 = spawn_object(o, MODEL_WATER_SPLASH, bhvWaterSplash); if (sp38 != NULL) { obj_scale(sp38, 3.0f); diff --git a/src/game/behaviors/bullet_bill.inc.c b/src/game/behaviors/bullet_bill.inc.c index 643df723..611bc945 100644 --- a/src/game/behaviors/bullet_bill.inc.c +++ b/src/game/behaviors/bullet_bill.inc.c @@ -45,7 +45,7 @@ void bullet_bill_act_2(void) { cur_obj_play_sound_2(SOUND_OBJ_POUNDING_CANNON); cur_obj_shake_screen(SHAKE_POS_SMALL); } - if (o->oTimer > 150 || o->oMoveFlags & 0x200) { + if (o->oTimer > 150 || o->oMoveFlags & OBJ_MOVE_HIT_WALL) { o->oAction = 3; spawn_mist_particles(); } diff --git a/src/game/behaviors/chuckya.inc.c b/src/game/behaviors/chuckya.inc.c index 2e007093..99a1b5f1 100644 --- a/src/game/behaviors/chuckya.inc.c +++ b/src/game/behaviors/chuckya.inc.c @@ -168,7 +168,7 @@ void chuckya_act_3(void) { } void chuckya_act_2(void) { - if (o->oMoveFlags & (0x200 | 0x40 | 0x20 | 0x10 | 0x8 | 0x1)) { + if (o->oMoveFlags & (OBJ_MOVE_HIT_WALL | OBJ_MOVE_MASK_IN_WATER | OBJ_MOVE_LANDED)) { obj_mark_for_deletion(o); obj_spawn_loot_yellow_coins(o, 5, 20.0f); spawn_mist_particles_with_sound(SOUND_OBJ_CHUCKYA_DEATH); diff --git a/src/game/behaviors/coin.inc.c b/src/game/behaviors/coin.inc.c index 05619b96..9b7099de 100644 --- a/src/game/behaviors/coin.inc.c +++ b/src/game/behaviors/coin.inc.c @@ -93,13 +93,13 @@ void bhv_coin_loop(void) { obj_mark_for_deletion(o); } #ifndef VERSION_JP - if (o->oMoveFlags & OBJ_MOVE_13) { + if (o->oMoveFlags & OBJ_MOVE_BOUNCE) { if (o->oCoinUnk1B0 < 5) cur_obj_play_sound_2(0x30364081); o->oCoinUnk1B0++; } #else - if (o->oMoveFlags & OBJ_MOVE_13) + if (o->oMoveFlags & OBJ_MOVE_BOUNCE) cur_obj_play_sound_2(SOUND_GENERAL_COIN_DROP); #endif if (cur_obj_wait_then_blink(400, 20)) @@ -214,7 +214,7 @@ void bhv_coin_formation_loop(void) { void coin_inside_boo_act_1(void) { cur_obj_update_floor_and_walls(); cur_obj_if_hit_wall_bounce_away(); - if (o->oMoveFlags & OBJ_MOVE_13) + if (o->oMoveFlags & OBJ_MOVE_BOUNCE) cur_obj_play_sound_2(SOUND_GENERAL_COIN_DROP); if (o->oTimer > 90 || (o->oMoveFlags & OBJ_MOVE_LANDED)) { obj_set_hitbox(o, &sYellowCoinHitbox); diff --git a/src/game/behaviors/donut_platform.inc.c b/src/game/behaviors/donut_platform.inc.c index afabb2a1..f1503a0e 100644 --- a/src/game/behaviors/donut_platform.inc.c +++ b/src/game/behaviors/donut_platform.inc.c @@ -41,7 +41,7 @@ void bhv_donut_platform_spawner_update(void) { } void bhv_donut_platform_update(void) { - if (o->oTimer != 0 && ((o->oMoveFlags & 0x00000003) || o->oDistanceToMario > 2500.0f)) { + if (o->oTimer != 0 && ((o->oMoveFlags & OBJ_MOVE_MASK_ON_GROUND) || o->oDistanceToMario > 2500.0f)) { o->parentObj->oDonutPlatformSpawnerSpawnedPlatforms = o->parentObj->oDonutPlatformSpawnerSpawnedPlatforms & ((1 << o->oBehParams2ndByte) ^ 0xFFFFFFFF); diff --git a/src/game/behaviors/eyerok.inc.c b/src/game/behaviors/eyerok.inc.c index ef9e6169..25047fee 100644 --- a/src/game/behaviors/eyerok.inc.c +++ b/src/game/behaviors/eyerok.inc.c @@ -292,7 +292,7 @@ static void eyerok_hand_act_show_eye(void) { if (o->parentObj->oEyerokBossNumHands != 2) { obj_face_yaw_approach(o->oMoveAngleYaw, 0x800); if (o->oTimer > 10 - && (o->oPosZ - gMarioObject->oPosZ > 0.0f || (o->oMoveFlags & 0x00000400))) { + && (o->oPosZ - gMarioObject->oPosZ > 0.0f || (o->oMoveFlags & OBJ_MOVE_HIT_EDGE))) { o->parentObj->oEyerokBossActiveHand = 0; o->oForwardVel = 0.0f; } @@ -321,7 +321,7 @@ static void eyerok_hand_act_attacked(void) { o->collisionData = segmented_to_virtual(ssl_seg7_collision_07028274); } - if (o->oMoveFlags & 0x00000003) { + if (o->oMoveFlags & OBJ_MOVE_MASK_ON_GROUND) { o->oForwardVel = 0.0f; } } @@ -346,7 +346,7 @@ static void eyerok_hand_act_die(void) { create_sound_spawner(SOUND_OBJ2_EYEROK_SOUND_LONG); } - if (o->oMoveFlags & 0x00000003) { + if (o->oMoveFlags & OBJ_MOVE_MASK_ON_GROUND) { cur_obj_play_sound_2(SOUND_OBJ_POUNDING_LOUD); o->oForwardVel = 0.0f; } @@ -378,7 +378,7 @@ static void eyerok_hand_act_retreat(void) { static void eyerok_hand_act_target_mario(void) { if (eyerok_check_mario_relative_z(400) != 0 || o->oPosZ - gMarioObject->oPosZ > 0.0f || o->oPosZ - o->parentObj->oPosZ > 1700.0f || absf(o->oPosX - o->parentObj->oPosX) > 900.0f - || (o->oMoveFlags & 0x00000200)) { + || (o->oMoveFlags & OBJ_MOVE_HIT_WALL)) { o->oForwardVel = 0.0f; if (approach_f32_ptr(&o->oPosY, o->oHomeY + 300.0f, 20.0f)) { o->oAction = EYEROK_HAND_ACT_SMASH; @@ -394,7 +394,7 @@ static void eyerok_hand_act_smash(void) { s16 sp1E; if (o->oTimer > 20) { - if (o->oMoveFlags & 0x00000003) { + if (o->oMoveFlags & OBJ_MOVE_MASK_ON_GROUND) { if (o->oGravity < -4.0f) { eyerok_hand_pound_ground(); o->oGravity = -4.0f; @@ -418,7 +418,7 @@ static void eyerok_hand_act_smash(void) { } static void eyerok_hand_act_fist_push(void) { - if (o->oTimer > 5 && (o->oPosZ - gMarioObject->oPosZ > 0.0f || (o->oMoveFlags & 0x00000400))) { + if (o->oTimer > 5 && (o->oPosZ - gMarioObject->oPosZ > 0.0f || (o->oMoveFlags & OBJ_MOVE_HIT_EDGE))) { o->oAction = EYEROK_HAND_ACT_FIST_SWEEP; o->oForwardVel = 0.0f; @@ -433,7 +433,7 @@ static void eyerok_hand_act_fist_push(void) { } static void eyerok_hand_act_fist_sweep(void) { - if (o->oPosZ - o->parentObj->oPosZ < 1000.0f || (o->oMoveFlags & 0x400)) { + if (o->oPosZ - o->parentObj->oPosZ < 1000.0f || (o->oMoveFlags & OBJ_MOVE_HIT_EDGE)) { o->oAction = EYEROK_HAND_ACT_RETREAT; o->oForwardVel = 0.0f; } else { @@ -470,7 +470,7 @@ static void eyerok_hand_act_double_pound(void) { o->oAction = EYEROK_HAND_ACT_RETREAT; o->parentObj->oEyerokBossUnk1AC = o->oBehParams2ndByte; } else if (o->parentObj->oEyerokBossActiveHand == o->oBehParams2ndByte) { - if (o->oMoveFlags & 0x00000003) { + if (o->oMoveFlags & OBJ_MOVE_MASK_ON_GROUND) { if (o->oGravity < -15.0f) { o->parentObj->oEyerokBossActiveHand = 0; eyerok_hand_pound_ground(); diff --git a/src/game/behaviors/fire_spitter.inc.c b/src/game/behaviors/fire_spitter.inc.c index d64bcf7e..2a59a803 100644 --- a/src/game/behaviors/fire_spitter.inc.c +++ b/src/game/behaviors/fire_spitter.inc.c @@ -1,7 +1,7 @@ static void fire_spitter_act_idle(void) { approach_f32_ptr(&o->header.gfx.scale[0], 0.2f, 0.002f); - if (o->oTimer > 150 && o->oDistanceToMario < 800.0f && !(o->oMoveFlags & 0x00000078)) { + if (o->oTimer > 150 && o->oDistanceToMario < 800.0f && !(o->oMoveFlags & OBJ_MOVE_MASK_IN_WATER)) { o->oAction = FIRE_SPITTER_ACT_SPIT_FIRE; o->oFireSpitterScaleVel = 0.05f; } diff --git a/src/game/behaviors/flame.inc.c b/src/game/behaviors/flame.inc.c index e3668219..873523d8 100644 --- a/src/game/behaviors/flame.inc.c +++ b/src/game/behaviors/flame.inc.c @@ -34,7 +34,7 @@ void bhv_small_piranha_flame_loop(void) { obj_check_attacks(&sPiranhaPlantFireHitbox, o->oAction); o->oSmallPiranhaFlameUnk104 += o->oSmallPiranhaFlameUnkF4; - if (o->oSmallPiranhaFlameUnk104 > 1500.0f || (o->oMoveFlags & 0x00000278)) { + if (o->oSmallPiranhaFlameUnk104 > 1500.0f || (o->oMoveFlags & (OBJ_MOVE_HIT_WALL | OBJ_MOVE_MASK_IN_WATER))) { obj_die_if_health_non_positive(); } } diff --git a/src/game/behaviors/flying_bookend_switch.inc.c b/src/game/behaviors/flying_bookend_switch.inc.c index 1d89c224..d3d937be 100644 --- a/src/game/behaviors/flying_bookend_switch.inc.c +++ b/src/game/behaviors/flying_bookend_switch.inc.c @@ -118,7 +118,7 @@ void bhv_flying_bookend_loop(void) { } obj_check_attacks(&sFlyingBookendHitbox, -1); - if (o->oAction == -1 || (o->oMoveFlags & 0x00000203)) { + if (o->oAction == -1 || (o->oMoveFlags & (OBJ_MOVE_MASK_ON_GROUND | OBJ_MOVE_HIT_WALL))) { o->oNumLootCoins = 0; obj_die_if_health_non_positive(); } diff --git a/src/game/behaviors/haunted_chair.inc.c b/src/game/behaviors/haunted_chair.inc.c index 89e7e83b..26d00de2 100644 --- a/src/game/behaviors/haunted_chair.inc.c +++ b/src/game/behaviors/haunted_chair.inc.c @@ -118,7 +118,7 @@ void haunted_chair_act_1(void) { } o->oFaceAngleYaw += 0x2710; } - } else if (o->oMoveFlags & 0x00000203) { + } else if (o->oMoveFlags & (OBJ_MOVE_MASK_ON_GROUND | OBJ_MOVE_HIT_WALL)) { obj_die_if_health_non_positive(); } } diff --git a/src/game/behaviors/heave_ho.inc.c b/src/game/behaviors/heave_ho.inc.c index 2cbd1f0e..1a247607 100644 --- a/src/game/behaviors/heave_ho.inc.c +++ b/src/game/behaviors/heave_ho.inc.c @@ -93,13 +93,13 @@ void heave_ho_move(void) { cur_obj_update_floor_and_walls(); cur_obj_call_action_function(sHeaveHoActions); cur_obj_move_standard(-78); - if (o->oMoveFlags & (0x40 | 0x20 | 0x10 | 0x8)) + if (o->oMoveFlags & OBJ_MOVE_MASK_IN_WATER) o->oGraphYOffset = -15.0f; else o->oGraphYOffset = 0.0f; if (o->oForwardVel > 3.0f) cur_obj_play_sound_1(SOUND_AIR_HEAVEHO_MOVE); - if (o->oAction != 0 && o->oMoveFlags & (0x40 | 0x20 | 0x10 | 0x8)) + if (o->oAction != 0 && o->oMoveFlags & OBJ_MOVE_MASK_IN_WATER) o->oAction = 0; if (o->oInteractStatus & INT_STATUS_GRABBED_MARIO) { o->oInteractStatus = 0; diff --git a/src/game/behaviors/horizontal_grindel.inc.c b/src/game/behaviors/horizontal_grindel.inc.c index 07733c07..c0b5fe15 100644 --- a/src/game/behaviors/horizontal_grindel.inc.c +++ b/src/game/behaviors/horizontal_grindel.inc.c @@ -4,7 +4,7 @@ void bhv_horizontal_grindel_init(void) { } void bhv_horizontal_grindel_update(void) { - if (o->oMoveFlags & 0x00000003) { + if (o->oMoveFlags & OBJ_MOVE_MASK_ON_GROUND) { if (!o->oHorizontalGrindelOnGround) { cur_obj_play_sound_2(SOUND_OBJ_THWOMP); o->oHorizontalGrindelOnGround = TRUE; diff --git a/src/game/behaviors/jumping_box.inc.c b/src/game/behaviors/jumping_box.inc.c index 3f43ea11..287d7377 100644 --- a/src/game/behaviors/jumping_box.inc.c +++ b/src/game/behaviors/jumping_box.inc.c @@ -20,14 +20,14 @@ void jumping_box_act_0(void) { o->oVelY = random_float() * 5.0f + 15.0f; o->oSubAction++; } - } else if (o->oMoveFlags & 2) { + } else if (o->oMoveFlags & OBJ_MOVE_ON_GROUND) { o->oSubAction = 0; o->oJumpingBoxUnkF8 = random_float() * 60.0f + 30.0f; } } void jumping_box_act_1(void) { - if (o->oMoveFlags & (0x200 | 0x40 | 0x20 | 0x10 | 0x8 | 0x1)) { + if (o->oMoveFlags & (OBJ_MOVE_HIT_WALL | OBJ_MOVE_MASK_IN_WATER | OBJ_MOVE_LANDED)) { obj_mark_for_deletion(o); spawn_mist_particles(); } diff --git a/src/game/behaviors/king_bobomb.inc.c b/src/game/behaviors/king_bobomb.inc.c index ced26d7b..7942b2bb 100644 --- a/src/game/behaviors/king_bobomb.inc.c +++ b/src/game/behaviors/king_bobomb.inc.c @@ -8,7 +8,7 @@ Gfx *geo_update_held_mario_pos(s32 run, UNUSED struct GraphNode *node, Mat4 mtx) if (run == TRUE) { sp1C = (struct Object *) gCurGraphNodeObject; if (sp1C->prevObj != NULL) { - create_transformation_from_matrices(sp20, mtx, gCurGraphNodeCamera->matrixPtr); + create_transformation_from_matrices(sp20, mtx, *gCurGraphNodeCamera->matrixPtr); obj_update_pos_from_parent_transformation(sp20, sp1C->prevObj); obj_set_gfx_pos_from_pos(sp1C->prevObj); } @@ -194,7 +194,7 @@ void king_bobomb_act_8(void) { void king_bobomb_act_4(void) { // bobomb been thrown if (o->oPosY - o->oHomeY > -100.0f) { // not thrown off hill - if (o->oMoveFlags & 1) { + if (o->oMoveFlags & OBJ_MOVE_LANDED) { o->oHealth--; o->oForwardVel = 0; o->oVelY = 0; @@ -206,11 +206,11 @@ void king_bobomb_act_4(void) { // bobomb been thrown } } else { if (o->oSubAction == 0) { - if (o->oMoveFlags & 2) { + if (o->oMoveFlags & OBJ_MOVE_ON_GROUND) { o->oForwardVel = 0; o->oVelY = 0; o->oSubAction++; - } else if (o->oMoveFlags & 1) + } else if (o->oMoveFlags & OBJ_MOVE_LANDED) cur_obj_play_sound_2(SOUND_OBJ_KING_BOBOMB); } else { if (cur_obj_init_animation_and_check_if_near_end(10)) diff --git a/src/game/behaviors/lll_volcano_flames.inc.c b/src/game/behaviors/lll_volcano_flames.inc.c index 32207c84..aa2fbc6f 100644 --- a/src/game/behaviors/lll_volcano_flames.inc.c +++ b/src/game/behaviors/lll_volcano_flames.inc.c @@ -6,6 +6,8 @@ void bhv_volcano_flames_loop(void) { o->oPosX += o->oVelX; o->oPosZ += o->oVelZ; cur_obj_move_y(-4.0f, -0.7f, 2.0f); - if (o->oMoveFlags & 0x33) + + if (o->oMoveFlags & (OBJ_MOVE_MASK_ON_GROUND | OBJ_MOVE_AT_WATER_SURFACE + | OBJ_MOVE_UNDERWATER_OFF_GROUND)) obj_mark_for_deletion(o); } diff --git a/src/game/behaviors/manta_ray.inc.c b/src/game/behaviors/manta_ray.inc.c index 4ffc5bf1..35e5e2e6 100644 --- a/src/game/behaviors/manta_ray.inc.c +++ b/src/game/behaviors/manta_ray.inc.c @@ -1,10 +1,16 @@ // manta_ray.c.inc -// TODO: these are likely Waypoint structs -static s16 D_803316A8[] = { 0x0000, 0xEE6C, 0xFA9C, 0xFFD8, 0x0001, 0xEFE8, 0xF740, 0x02E4, 0x0002, - 0xF330, 0xF3F8, 0x0410, 0x0003, 0xF740, 0xF308, 0x02D0, 0x0004, 0xF8D0, - 0xF3BC, 0xFEE8, 0x0005, 0xF6F0, 0xF650, 0xFBB4, 0x0006, 0xF36C, 0xF9C0, - 0xFAB0, 0x0007, 0xEFAC, 0xFC04, 0xFBF0, 0xFFFF, 0x0000 }; +static Trajectory sMantaRayTraj[] = { + TRAJECTORY_POS(0, /*pos*/ -4500, -1380, -40), + TRAJECTORY_POS(1, /*pos*/ -4120, -2240, 740), + TRAJECTORY_POS(2, /*pos*/ -3280, -3080, 1040), + TRAJECTORY_POS(3, /*pos*/ -2240, -3320, 720), + TRAJECTORY_POS(4, /*pos*/ -1840, -3140, -280), + TRAJECTORY_POS(5, /*pos*/ -2320, -2480, -1100), + TRAJECTORY_POS(6, /*pos*/ -3220, -1600, -1360), + TRAJECTORY_POS(7, /*pos*/ -4180, -1020, -1040), + TRAJECTORY_END(), +}; static struct ObjectHitbox sMantaRayHitbox = { /* interactType: */ INTERACT_DAMAGE, @@ -31,7 +37,7 @@ void manta_ray_move(void) { s32 sp18; sp1E = o->header.gfx.unk38.animFrame; - gCurrentObject->oPathedWaypointsS16 = &D_803316A8; + gCurrentObject->oPathedStartWaypoint = (struct Waypoint *) sMantaRayTraj; sp18 = cur_obj_follow_path(sp18); o->oMantaUnkF8 = o->oPathedTargetYaw; o->oMantaUnkF4 = o->oPathedTargetPitch; diff --git a/src/game/behaviors/mr_blizzard.inc.c b/src/game/behaviors/mr_blizzard.inc.c index 52a93d72..c8630a69 100644 --- a/src/game/behaviors/mr_blizzard.inc.c +++ b/src/game/behaviors/mr_blizzard.inc.c @@ -1,3 +1,4 @@ +// Mr. Blizzard hitbox struct ObjectHitbox sMrBlizzardHitbox = { /* interactType: */ INTERACT_MR_BLIZZARD, /* downOffset: */ 24, @@ -10,7 +11,9 @@ struct ObjectHitbox sMrBlizzardHitbox = { /* hurtboxHeight: */ 170, }; -void mr_blizzard_spawn_white_particles(s8 count, s8 offsetY, s8 forwardVelBase, s8 velYBase, s8 sizeBase) { +// Mr. Blizzard particle spawner. +void mr_blizzard_spawn_white_particles(s8 count, s8 offsetY, s8 forwardVelBase, s8 velYBase, + s8 sizeBase) { static struct SpawnParticlesInfo D_80331A00 = { /* behParam: */ 0, /* count: */ 6, @@ -34,42 +37,66 @@ void mr_blizzard_spawn_white_particles(s8 count, s8 offsetY, s8 forwardVelBase, cur_obj_spawn_particles(&D_80331A00); } +/** + * Mr. Blizzard initialization function. + */ + void bhv_mr_blizzard_init(void) { - if (o->oBehParams2ndByte == 1) { - o->oAction = 7; + if (o->oBehParams2ndByte == MR_BLIZZARD_STYPE_JUMPING) { + // Jumping Mr. Blizzard. + o->oAction = MR_BLIZZARD_ACT_JUMP; o->oMrBlizzardGraphYOffset = 24.0f; o->oMrBlizzardTargetMoveYaw = o->oMoveAngleYaw; } else { - if (o->oBehParams2ndByte != 0) { + if (o->oBehParams2ndByte != MR_BLIZZARD_STYPE_NO_CAP) { + // Cap wearing Mr. Blizzard from SL. if (save_file_get_flags() & SAVE_FLAG_CAP_ON_MR_BLIZZARD) { o->oAnimState = 1; } } + // Mr. Blizzard starts under the floor holding nothing. o->oMrBlizzardGraphYOffset = -200.0f; o->oMrBlizzardHeldObj = NULL; } } -static void mr_blizzard_act_0(void) { +/** + * Handler for spawning Mr. Blizzard's snowball. + */ + +static void mr_blizzard_act_spawn_snowball(void) { + + // If Mr. Blizzard is not holding a snowball, and the animation reaches 5 frames + // spawn the Mr. Blizzard snowball. if (o->oMrBlizzardHeldObj == NULL && cur_obj_init_anim_check_frame(0, 5)) { - o->oMrBlizzardHeldObj = spawn_object_relative(0, -70, (s32)(o->oMrBlizzardGraphYOffset + 153.0f), 0, o, - MODEL_WHITE_PARTICLE, bhvMrBlizzardSnowball); + o->oMrBlizzardHeldObj = + spawn_object_relative(0, -70, (s32)(o->oMrBlizzardGraphYOffset + 153.0f), 0, o, + MODEL_WHITE_PARTICLE, bhvMrBlizzardSnowball); } else if (cur_obj_check_anim_frame(10)) { o->prevObj = o->oMrBlizzardHeldObj; } else if (cur_obj_check_if_near_animation_end()) { + // If Mr. Blizzard's graphical position is below the ground, move to hide and unhide action. + // Otherwise, move to rotate action. if (o->oMrBlizzardGraphYOffset < 0.0f) { - o->oAction = 1; + o->oAction = MR_BLIZZARD_ACT_HIDE_UNHIDE; } else { - o->oAction = 3; + o->oAction = MR_BLIZZARD_ACT_ROTATE; } } } -static void mr_blizzard_act_1(void) { +/** + * Handler for Mario entering or exiting Mr. Blizzard's range. + */ + +static void mr_blizzard_act_hide_unhide(void) { + if (o->oDistanceToMario < 1000.0f) { + // If Mario is in range, move to rising action, make Mr. Blizzard visible, + // make Mr. Blizzard tangible, and initialize GraphYVel. cur_obj_play_sound_2(SOUND_OBJ_SNOW_SAND2); - o->oAction = 2; + o->oAction = MR_BLIZZARD_ACT_RISE_FROM_GROUND; o->oMoveAngleYaw = o->oAngleToMario; o->oMrBlizzardGraphYVel = 42.0f; @@ -77,45 +104,69 @@ static void mr_blizzard_act_1(void) { cur_obj_unhide(); cur_obj_become_tangible(); } else { + // If Mario is not in range, make Mr. Blizzard invisible. cur_obj_hide(); } } -static void mr_blizzard_act_2(void) { +/** + * Handler for Mr. Blizzard popping up out of the ground. + */ + +static void mr_blizzard_act_rise_from_ground(void) { + + // If the timer is not 0, decrement by 1 until it reaches 0. if (o->oMrBlizzardTimer != 0) { o->oMrBlizzardTimer -= 1; } else if ((o->oMrBlizzardGraphYOffset += o->oMrBlizzardGraphYVel) > 24.0f) { + // Increments GraphYOffset by GraphYVel until it is greater than 24, + // moving Mr. Blizzard's graphical position upward each frame. + // Then, Mr. Blizzard's Y-position is increased by the value of + // GraphYOffset minus 24, GraphYOffset is + // set to 24, VelY is set to GraphYVel and action is moved to rotate. o->oPosY += o->oMrBlizzardGraphYOffset - 24.0f; o->oMrBlizzardGraphYOffset = 24.0f; mr_blizzard_spawn_white_particles(8, -20, 20, 15, 10); - o->oAction = 3; + o->oAction = MR_BLIZZARD_ACT_ROTATE; o->oVelY = o->oMrBlizzardGraphYVel; } else if ((o->oMrBlizzardGraphYVel -= 10.0f) < 0.0f) { + // Decrement GraphYOffset until it is less than 0. + // When it is less than 0, set it to 47 and set timer to 5. o->oMrBlizzardGraphYVel = 47.0f; o->oMrBlizzardTimer = 5; } } -static void mr_blizzard_act_3(void) { - s16 val06; - f32 val00; +/** + * Handler for Mr. Blizzard's rotation. + */ - if (o->oMoveFlags & 0x00000003) { +static void mr_blizzard_act_rotate(void) { + + s16 angleDiff; + f32 prevDizziness; + // While Mr. Blizzard is on the ground, rotate toward Mario at + // 8.4375 degrees/frame. + if (o->oMoveFlags & OBJ_MOVE_MASK_ON_GROUND) { cur_obj_rotate_yaw_toward(o->oAngleToMario, 0x600); - val06 = o->oAngleToMario - o->oMoveAngleYaw; - if (val06 != 0) { - if (val06 < 0) { + // Modify the ChangeInDizziness based on Mario's angle to Mr. Blizzard. + angleDiff = o->oAngleToMario - o->oMoveAngleYaw; + if (angleDiff != 0) { + if (angleDiff < 0) { o->oMrBlizzardChangeInDizziness -= 8.0f; } else { o->oMrBlizzardChangeInDizziness += 8.0f; } + // Incremement Dizziness by value of ChangeInDizziness o->oMrBlizzardDizziness += o->oMrBlizzardChangeInDizziness; } else if (o->oMrBlizzardDizziness != 0.0f) { - val00 = o->oMrBlizzardDizziness; + prevDizziness = o->oMrBlizzardDizziness; + // Slowly move Dizziness back to 0 by making ChangeInDizziness positive if Dizziness + // is negative, and making ChangeInDizziness negative if Dizziness is positive. if (o->oMrBlizzardDizziness < 0.0f) { approach_f32_ptr(&o->oMrBlizzardChangeInDizziness, 1000.0f, 80.0f); } else { @@ -123,43 +174,55 @@ static void mr_blizzard_act_3(void) { } o->oMrBlizzardDizziness += o->oMrBlizzardChangeInDizziness; - if (val00 * o->oMrBlizzardDizziness < 0.0f) { + // If prevDizziness has a different sign than Dizziness, + // set Dizziness and ChangeInDizziness to 0. + if (prevDizziness * o->oMrBlizzardDizziness < 0.0f) { o->oMrBlizzardDizziness = o->oMrBlizzardChangeInDizziness = 0.0f; } } - + // If Dizziness is not 0 and Mr. Blizzard's FaceRollAngle has a magnitude greater than + // 67.5 degrees move to death action, delete the snowball, and make Mr. Blizzard intangible. if (o->oMrBlizzardDizziness != 0.0f) { if (absi(o->oFaceAngleRoll) > 0x3000) { - o->oAction = 6; + o->oAction = MR_BLIZZARD_ACT_DEATH; o->prevObj = o->oMrBlizzardHeldObj = NULL; cur_obj_become_intangible(); } + // If Mario gets too far away, move to burrow action and delete the snowball. } else if (o->oDistanceToMario > 1500.0f) { - o->oAction = 5; + o->oAction = MR_BLIZZARD_ACT_BURROW; o->oMrBlizzardChangeInDizziness = 300.0f; o->prevObj = o->oMrBlizzardHeldObj = NULL; + // After 60 frames, if Mario is within 11.25 degrees of Mr. Blizzard, throw snowball action. } else if (o->oTimer > 60 && abs_angle_diff(o->oAngleToMario, o->oMoveAngleYaw) < 0x800) { - o->oAction = 4; + o->oAction = MR_BLIZZARD_ACT_THROW_SNOWBALL; } } } -static void mr_blizzard_act_6(void) { - struct Object *val04; +/** + * Handler for Mr. Blizzard's death. + */ + +static void mr_blizzard_act_death(void) { + + struct Object *cap; if (clamp_f32(&o->oMrBlizzardDizziness, -0x4000, 0x4000)) { if (o->oMrBlizzardChangeInDizziness != 0.0f) { cur_obj_play_sound_2(SOUND_OBJ_SNOW_SAND1); + // If Mr. Blizzard is wearing Mario's cap, clear + // the save flag and spawn Mario's cap. if (o->oAnimState) { save_file_clear_flags(SAVE_FLAG_CAP_ON_MR_BLIZZARD); - val04 = spawn_object_relative(0, 5, 105, 0, o, MODEL_MARIOS_CAP, bhvNormalCap); - if (val04 != NULL) { - val04->oMoveAngleYaw = - o->oFaceAngleYaw + (o->oFaceAngleRoll < 0 ? 0x4000 : -0x4000); - val04->oForwardVel = 10.0f; + cap = spawn_object_relative(0, 5, 105, 0, o, MODEL_MARIOS_CAP, bhvNormalCap); + if (cap != NULL) { + cap->oMoveAngleYaw = o->oFaceAngleYaw + (o->oFaceAngleRoll < 0 ? 0x4000 : -0x4000); + cap->oForwardVel = 10.0f; } + // Mr. Blizzard no longer spawns with Mario's cap on. o->oAnimState = 0; } @@ -175,6 +238,8 @@ static void mr_blizzard_act_6(void) { o->oMrBlizzardDizziness += o->oMrBlizzardChangeInDizziness; } + // After 30 frames, play the defeat sound once and scale Mr. Blizzard down to 0 + // at .03 units per frame. Spawn coins and set the coins to not respawn. if (o->oTimer >= 30) { if (o->oTimer == 30) { cur_obj_play_sound_2(SOUND_OBJ_ENEMY_DEFEAT_SHRINK); @@ -188,10 +253,11 @@ static void mr_blizzard_act_6(void) { set_object_respawn_info_bits(o, 1); } } + // Reset Mr. Blizzard if Mario leaves its radius. } else if (o->oDistanceToMario > 1000.0f) { cur_obj_init_animation_with_sound(1); - o->oAction = 0; + o->oAction = MR_BLIZZARD_ACT_SPAWN_SNOWBALL; o->oMrBlizzardScale = 1.0f; o->oMrBlizzardGraphYOffset = -200.0f; o->oFaceAngleRoll = 0; @@ -200,16 +266,29 @@ static void mr_blizzard_act_6(void) { } } -static void mr_blizzard_act_4(void) { +/** + * Handler for snowball throw. + */ + +static void mr_blizzard_act_throw_snowball(void) { + + // Play a sound and set HeldObj to NULL. Then set action to 0. if (cur_obj_init_anim_check_frame(1, 7)) { cur_obj_play_sound_2(SOUND_OBJ2_SCUTTLEBUG_ALERT); o->prevObj = o->oMrBlizzardHeldObj = NULL; } else if (cur_obj_check_if_near_animation_end()) { - o->oAction = 0; + o->oAction = MR_BLIZZARD_ACT_SPAWN_SNOWBALL; } } -static void mr_blizzard_act_5(void) { +/** + * Mr. Blizzard's going back into the ground function. + */ + +static void mr_blizzard_act_burrow(void) { + + // Reset Dizziness by increasing ChangeInDizziness if + // dizziness is negative and decreasing it if Dizziness o->oMrBlizzardDizziness += o->oMrBlizzardChangeInDizziness; if (o->oMrBlizzardDizziness < 0.0f) { @@ -217,32 +296,45 @@ static void mr_blizzard_act_5(void) { } else { o->oMrBlizzardChangeInDizziness -= 150.0f; } - + // Put Mr. Blizzard's graphical position back below ground + // then move to action 0. if (approach_f32_ptr(&o->oMrBlizzardGraphYOffset, -200.0f, 4.0f)) { - o->oAction = 0; + o->oAction = MR_BLIZZARD_ACT_SPAWN_SNOWBALL; cur_obj_init_animation_with_sound(1); } } -static void mr_blizzard_act_7(void) { +/** + * Jumping Mr. Blizzard handler function. + */ + +static void mr_blizzard_act_jump(void) { + if (o->oMrBlizzardTimer != 0) { cur_obj_rotate_yaw_toward(o->oMrBlizzardTargetMoveYaw, 3400); if (--o->oMrBlizzardTimer == 0) { cur_obj_play_sound_2(SOUND_OBJ_MR_BLIZZARD_ALERT); + // If Mr. Blizzard is more than 700 units from its home, change its target yaw + // by 180 degrees, jump in the air, set distance from home to 0. if (o->oMrBlizzardDistFromHome > 700) { o->oMrBlizzardTargetMoveYaw += 0x8000; o->oVelY = 25.0f; o->oMrBlizzardTimer = 30; o->oMrBlizzardDistFromHome = 0; + // Jump forward. } else { o->oForwardVel = 10.0f; o->oVelY = 50.0f; o->oMoveFlags = 0; } } - } else if (o->oMoveFlags & 0x00000003) { + } else if (o->oMoveFlags & OBJ_MOVE_MASK_ON_GROUND) { + // When Mr. Blizzard lands, play the landing sound, stop Mr. Blizzard, and + // set its timer to 15. If Mr. Blizzard's DistFromHome is not 0, + // set DistFromHome to its current distance from its home. + // Otherwise, set DistFromHome to 700. cur_obj_play_sound_2(SOUND_OBJ_SNOW_SAND1); if (o->oMrBlizzardDistFromHome != 0) { o->oMrBlizzardDistFromHome = (s32) cur_obj_lateral_dist_to_home(); @@ -255,37 +347,45 @@ static void mr_blizzard_act_7(void) { } } +/** + * Mr. Blizzard update function. + */ + void bhv_mr_blizzard_update(void) { cur_obj_update_floor_and_walls(); + // Behavior loop switch (o->oAction) { - case 0: - mr_blizzard_act_0(); + case MR_BLIZZARD_ACT_SPAWN_SNOWBALL: + mr_blizzard_act_spawn_snowball(); break; - case 1: - mr_blizzard_act_1(); + case MR_BLIZZARD_ACT_HIDE_UNHIDE: + mr_blizzard_act_hide_unhide(); break; - case 2: - mr_blizzard_act_2(); + case MR_BLIZZARD_ACT_RISE_FROM_GROUND: + mr_blizzard_act_rise_from_ground(); break; - case 3: - mr_blizzard_act_3(); + case MR_BLIZZARD_ACT_ROTATE: + mr_blizzard_act_rotate(); break; - case 4: - mr_blizzard_act_4(); + case MR_BLIZZARD_ACT_THROW_SNOWBALL: + mr_blizzard_act_throw_snowball(); break; - case 5: - mr_blizzard_act_5(); + case MR_BLIZZARD_ACT_BURROW: + mr_blizzard_act_burrow(); break; - case 6: - mr_blizzard_act_6(); + case MR_BLIZZARD_ACT_DEATH: + mr_blizzard_act_death(); break; - case 7: - mr_blizzard_act_7(); + case MR_BLIZZARD_ACT_JUMP: + mr_blizzard_act_jump(); break; } + // Set roll angle equal to dizziness, making Mr. Blizzard + // slowly fall over. o->oFaceAngleRoll = o->oMrBlizzardDizziness; + // Mr. Blizzard's graphical position changes by changing the Y offset. o->oGraphYOffset = o->oMrBlizzardGraphYOffset + absf(20.0f * sins(o->oFaceAngleRoll)) - 40.0f * (1.0f - o->oMrBlizzardScale); @@ -294,6 +394,10 @@ void bhv_mr_blizzard_update(void) { obj_check_attacks(&sMrBlizzardHitbox, o->oAction); } +/** + * Snowball initial takeoff position handler. + */ + static void mr_blizzard_snowball_act_0(void) { cur_obj_move_using_fvel_and_gravity(); if (o->parentObj->prevObj == o) { @@ -303,26 +407,31 @@ static void mr_blizzard_snowball_act_0(void) { } } +/** + * Snowball launching action. + */ + static void mr_blizzard_snowball_act_1(void) { - f32 val04; + f32 marioDist; if (o->parentObj->prevObj == NULL) { - if (o->parentObj->oAction == 4) { - val04 = o->oDistanceToMario; - if (val04 > 800.0f) { - val04 = 800.0f; + if (o->parentObj->oAction == MR_BLIZZARD_ACT_THROW_SNOWBALL) { + marioDist = o->oDistanceToMario; + if (marioDist > 800.0f) { + marioDist = 800.0f; } - o->oMoveAngleYaw = (s32)(o->parentObj->oMoveAngleYaw + 4000 - val04 * 4.0f); + // Launch the snowball relative to Mario's distance from the snowball. + o->oMoveAngleYaw = (s32)(o->parentObj->oMoveAngleYaw + 4000 - marioDist * 4.0f); o->oForwardVel = 40.0f; - o->oVelY = -20.0f + val04 * 0.075f; + o->oVelY = -20.0f + marioDist * 0.075f; } o->oAction = 2; o->oMoveFlags = 0; } } - +// Snowball hitbox. struct ObjectHitbox sMrBlizzardSnowballHitbox = { /* interactType: */ INTERACT_MR_BLIZZARD, /* downOffset: */ 12, @@ -335,11 +444,17 @@ struct ObjectHitbox sMrBlizzardSnowballHitbox = { /* hurtboxHeight: */ 25, }; +/** + * Snowball collision function. + */ + static void mr_blizzard_snowball_act_2(void) { + // Set snowball to interact with walls, floors, and Mario. cur_obj_update_floor_and_walls(); obj_check_attacks(&sMrBlizzardSnowballHitbox, -1); - if (o->oAction == -1 || o->oMoveFlags & 0x0000000B) { + // If snowball collides with the ground, delete snowball. + if (o->oAction == -1 || o->oMoveFlags & (OBJ_MOVE_MASK_ON_GROUND | OBJ_MOVE_ENTERED_WATER)) { mr_blizzard_spawn_white_particles(6, 0, 5, 10, 3); create_sound_spawner(SOUND_GENERAL_MOVING_IN_SAND); obj_mark_for_deletion(o); @@ -348,6 +463,10 @@ static void mr_blizzard_snowball_act_2(void) { cur_obj_move_standard(78); } +/** + * Snowball behavior loop. + */ + void bhv_mr_blizzard_snowball(void) { switch (o->oAction) { case 0: diff --git a/src/game/behaviors/mr_i.inc.c b/src/game/behaviors/mr_i.inc.c index 57a4a2f1..4d883ddf 100644 --- a/src/game/behaviors/mr_i.inc.c +++ b/src/game/behaviors/mr_i.inc.c @@ -17,7 +17,7 @@ void mr_i_piranha_particle_act_0(void) { cur_obj_update_floor_and_walls(); if (0x8000 & o->oInteractStatus) o->oAction = 1; - else if ((o->oTimer >= 101) || (0x200 & o->oMoveFlags) || o->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM) { + else if ((o->oTimer >= 101) || (o->oMoveFlags & OBJ_MOVE_HIT_WALL) || o->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM) { obj_mark_for_deletion(o); spawn_mist_particles(); } diff --git a/src/game/behaviors/racing_penguin.inc.c b/src/game/behaviors/racing_penguin.inc.c index fea739b8..1703d52e 100644 --- a/src/game/behaviors/racing_penguin.inc.c +++ b/src/game/behaviors/racing_penguin.inc.c @@ -88,7 +88,7 @@ static void racing_penguin_act_race(void) { cur_obj_init_animation_with_sound(1); cur_obj_rotate_yaw_toward(o->oPathedTargetYaw, (s32)(15.0f * o->oForwardVel)); - if (cur_obj_check_if_at_animation_end() && (o->oMoveFlags & 0x00000003)) { + if (cur_obj_check_if_at_animation_end() && (o->oMoveFlags & OBJ_MOVE_MASK_ON_GROUND)) { spawn_object_relative_with_scale(0, 0, -100, 0, 4.0f, o, MODEL_SMOKE, bhvWhitePuffSmoke2); } } @@ -104,7 +104,7 @@ static void racing_penguin_act_race(void) { static void racing_penguin_act_finish_race(void) { if (o->oForwardVel != 0.0f) { - if (o->oTimer > 5 && (o->oMoveFlags & 0x00000200)) { + if (o->oTimer > 5 && (o->oMoveFlags & OBJ_MOVE_HIT_WALL)) { cur_obj_play_sound_2(SOUND_OBJ_POUNDING_LOUD); set_camera_shake_from_point(SHAKE_POS_SMALL, o->oPosX, o->oPosY, o->oPosZ); o->oForwardVel = 0.0f; diff --git a/src/game/behaviors/scuttlebug.inc.c b/src/game/behaviors/scuttlebug.inc.c index 40d45461..16840e1c 100644 --- a/src/game/behaviors/scuttlebug.inc.c +++ b/src/game/behaviors/scuttlebug.inc.c @@ -35,9 +35,9 @@ void bhv_scuttlebug_loop(void) { o->oScuttlebugUnkF8 = 0; switch (o->oSubAction) { case 0: - if (o->oMoveFlags & 1) + if (o->oMoveFlags & OBJ_MOVE_LANDED) cur_obj_play_sound_2(SOUND_OBJ_GOOMBA_ALERT); - if (o->oMoveFlags & 3) { + if (o->oMoveFlags & OBJ_MOVE_MASK_ON_GROUND) { o->oHomeX = o->oPosX; o->oHomeY = o->oPosY; o->oHomeZ = o->oPosZ; @@ -85,7 +85,7 @@ void bhv_scuttlebug_loop(void) { break; case 4: o->oForwardVel = -10.0f; - if (o->oMoveFlags & 1) { + if (o->oMoveFlags & OBJ_MOVE_LANDED) { o->oSubAction++; o->oVelY = 0.0f; o->oScuttlebugUnkFC = 0; @@ -105,7 +105,7 @@ void bhv_scuttlebug_loop(void) { else sp18 = 3.0f; cur_obj_init_animation_with_accel_and_sound(0, sp18); - if (o->oMoveFlags & 3) + if (o->oMoveFlags & OBJ_MOVE_MASK_ON_GROUND) set_obj_anim_with_accel_and_sound(1, 23, SOUND_OBJ2_SCUTTLEBUG_WALK); if (o->parentObj != o) { if (obj_is_hidden(o)) diff --git a/src/game/behaviors/skeeter.inc.c b/src/game/behaviors/skeeter.inc.c index aa118923..a726760f 100644 --- a/src/game/behaviors/skeeter.inc.c +++ b/src/game/behaviors/skeeter.inc.c @@ -32,7 +32,7 @@ static void skeeter_spawn_waves(void) { } static void skeeter_act_idle(void) { - if (o->oMoveFlags & 0x00000003) { + if (o->oMoveFlags & OBJ_MOVE_MASK_ON_GROUND) { cur_obj_init_animation_with_sound(3); o->oForwardVel = 0.0f; @@ -42,7 +42,7 @@ static void skeeter_act_idle(void) { } else { cur_obj_init_animation_with_sound(1); - if (o->oMoveFlags & 0x00000010) { + if (o->oMoveFlags & OBJ_MOVE_AT_WATER_SURFACE) { skeeter_spawn_waves(); if (o->oTimer > 60 && obj_smooth_turn(&o->oSkeeterUnk1AC, &o->oMoveAngleYaw, o->oSkeeterTargetAngle, 0.02f, @@ -61,13 +61,13 @@ static void skeeter_act_idle(void) { } static void skeeter_act_lunge(void) { - if (!(o->oMoveFlags & 0x00000010)) { + if (!(o->oMoveFlags & OBJ_MOVE_AT_WATER_SURFACE)) { o->oAction = SKEETER_ACT_IDLE; } else { skeeter_spawn_waves(); cur_obj_init_animation_with_sound(0); - if (o->oMoveFlags & 0x00000200) { + if (o->oMoveFlags & OBJ_MOVE_HIT_WALL) { o->oMoveAngleYaw = cur_obj_reflect_move_angle_off_wall(); o->oForwardVel *= 0.3f; o->oFlags &= ~0x00000008; @@ -92,7 +92,7 @@ static void skeeter_act_lunge(void) { static void skeeter_act_walk(void) { f32 sp24; - if (!(o->oMoveFlags & 0x00000003)) { + if (!(o->oMoveFlags & OBJ_MOVE_MASK_ON_GROUND)) { o->oAction = SKEETER_ACT_IDLE; } else { obj_forward_vel_approach(o->oSkeeterUnkFC, 0.4f); diff --git a/src/game/behaviors/triplet_butterfly.inc.c b/src/game/behaviors/triplet_butterfly.inc.c index 3d16a9d2..5f971854 100644 --- a/src/game/behaviors/triplet_butterfly.inc.c +++ b/src/game/behaviors/triplet_butterfly.inc.c @@ -124,7 +124,7 @@ static void triplet_butterfly_act_explode(void) { obj_check_attacks(&sTripletButterflyExplodeHitbox, -1); - if (o->oAction == -1 || (o->oMoveFlags & 0x00000200) || o->oTimer >= 158) { + if (o->oAction == -1 || (o->oMoveFlags & OBJ_MOVE_HIT_WALL) || o->oTimer >= 158) { o->oPosY += o->oGraphYOffset; spawn_object(o, MODEL_EXPLOSION, bhvExplosion); obj_mark_for_deletion(o); diff --git a/src/game/behaviors/ukiki.inc.c b/src/game/behaviors/ukiki.inc.c index 401abaa2..e7598253 100644 --- a/src/game/behaviors/ukiki.inc.c +++ b/src/game/behaviors/ukiki.inc.c @@ -48,7 +48,7 @@ Gfx *geo_update_projectile_pos_from_parent_copy(s32 run,UNUSED struct GraphNode obj = (struct Object*)gCurGraphNodeObject; if (obj->prevObj != NULL) { - create_transformation_from_matrices(mtx2, mtx, gCurGraphNodeCamera->matrixPtr); + create_transformation_from_matrices(mtx2, mtx, *gCurGraphNodeCamera->matrixPtr); obj_update_pos_from_parent_transformation(mtx2, obj->prevObj); obj_set_gfx_pos_from_pos(obj->prevObj); } @@ -299,7 +299,8 @@ void ukiki_act_jump(void) { if (o->oSubAction == 0) { if (o->oTimer == 0) { cur_obj_set_y_vel_and_animation(random_float() * 10.0f + 45.0f, UKIKI_ANIM_JUMP); - } else if (o->oMoveFlags & OBJ_MOVE_MASK_NOT_AIR) { + } else if (o->oMoveFlags & (OBJ_MOVE_MASK_ON_GROUND | OBJ_MOVE_AT_WATER_SURFACE + | OBJ_MOVE_UNDERWATER_ON_GROUND)) { o->oSubAction++; o->oVelY = 0.0f; } @@ -316,22 +317,20 @@ void ukiki_act_jump(void) { /** * Waypoints that lead from the top of the mountain to the cage. - * - * TODO: Convert to an array of waypoints, perhaps? -1 is tricky. */ -s16 sCageUkikiPath[] = { - 0, 1011, 2306, -285, - 0, 1151, 2304, -510, - 0, 1723, 1861, -964, - 0, 2082, 1775, -1128, - 0, 2489, 1717, -1141, - 0, 2662, 1694, -1140, - 0, 2902, 1536, -947, - 0, 2946, 1536, -467, - 0, 2924, 1536, 72, - 0, 2908, 1536, 536, - 0, 2886, 1536, 783, - -1, +static Trajectory sCageUkikiPath[] = { + TRAJECTORY_POS(0, /*pos*/ 1011, 2306, -285), + TRAJECTORY_POS(0, /*pos*/ 1151, 2304, -510), + TRAJECTORY_POS(0, /*pos*/ 1723, 1861, -964), + TRAJECTORY_POS(0, /*pos*/ 2082, 1775, -1128), + TRAJECTORY_POS(0, /*pos*/ 2489, 1717, -1141), + TRAJECTORY_POS(0, /*pos*/ 2662, 1694, -1140), + TRAJECTORY_POS(0, /*pos*/ 2902, 1536, -947), + TRAJECTORY_POS(0, /*pos*/ 2946, 1536, -467), + TRAJECTORY_POS(0, /*pos*/ 2924, 1536, 72), + TRAJECTORY_POS(0, /*pos*/ 2908, 1536, 536), + TRAJECTORY_POS(0, /*pos*/ 2886, 1536, 783), + TRAJECTORY_END(), }; /** @@ -358,8 +357,8 @@ void ukiki_act_go_to_cage(void) { switch(o->oSubAction) { case UKIKI_SUB_ACT_CAGE_RUN_TO_CAGE: cur_obj_init_animation_with_sound(UKIKI_ANIM_RUN); - - o->oPathedWaypointsS16 = sCageUkikiPath; + + o->oPathedStartWaypoint = (struct Waypoint *) sCageUkikiPath; if (cur_obj_follow_path(0) != PATH_REACHED_END) { o->oForwardVel = 10.0f; @@ -470,7 +469,7 @@ void (*sUkikiActions[])(void) = { ukiki_act_wait_to_respawn, ukiki_act_unused_turn, ukiki_act_return_home, - }; +}; /** * Called via the main behavior function when Ukiki is either nothing diff --git a/src/game/behaviors/whomp.inc.c b/src/game/behaviors/whomp.inc.c index a10ac656..1f3bcb7f 100644 --- a/src/game/behaviors/whomp.inc.c +++ b/src/game/behaviors/whomp.inc.c @@ -122,13 +122,13 @@ void whomp_act_4(void) { } void whomp_act_5(void) { - if (o->oSubAction == 0 && o->oMoveFlags & 1) { + if (o->oSubAction == 0 && o->oMoveFlags & OBJ_MOVE_LANDED) { cur_obj_play_sound_2(SOUND_OBJ_WHOMP_LOWPRIO); cur_obj_shake_screen(SHAKE_POS_SMALL); o->oVelY = 0.0f; o->oSubAction++; } - if (o->oMoveFlags & 2) + if (o->oMoveFlags & OBJ_MOVE_ON_GROUND) o->oAction = 6; } diff --git a/src/game/debug.c b/src/game/debug.c index e5f8c6ac..66d808ed 100644 --- a/src/game/debug.c +++ b/src/game/debug.c @@ -554,7 +554,7 @@ void debug_print_obj_move_flags(void) { if (gCurrentObject->oMoveFlags & OBJ_MOVE_IN_AIR) { print_debug_top_down_objectinfo("SKY %x", gCurrentObject->oMoveFlags); } - if (gCurrentObject->oMoveFlags & OBJ_MOVE_8) { + if (gCurrentObject->oMoveFlags & OBJ_MOVE_OUT_SCOPE) { print_debug_top_down_objectinfo("OUT SCOPE %x", gCurrentObject->oMoveFlags); } #endif diff --git a/src/game/mario.c b/src/game/mario.c index f409c163..5f8e5114 100644 --- a/src/game/mario.c +++ b/src/game/mario.c @@ -1582,8 +1582,7 @@ void sink_mario_in_quicksand(struct MarioState *m) { struct Object *o = m->marioObj; if (o->header.gfx.throwMatrix) { - // TODO: throwMatrix should probably be an actual matrix pointer - *(f32 *) ((u8 *) o->header.gfx.throwMatrix + 0x34) -= m->quicksandDepth; + (*o->header.gfx.throwMatrix)[3][1] -= m->quicksandDepth; } o->header.gfx.pos[1] -= m->quicksandDepth; diff --git a/src/game/mario_actions_moving.c b/src/game/mario_actions_moving.c index 01eb8148..0ccbccf1 100644 --- a/src/game/mario_actions_moving.c +++ b/src/game/mario_actions_moving.c @@ -61,7 +61,7 @@ struct LandingAction sBackflipLandAction = { 4, 0, ACT_FREEFALL, ACT_BACKFLIP_LAND_STOP, ACT_BACKFLIP, ACT_FREEFALL, ACT_BEGIN_SLIDING, }; -Mat4 D_80339F50[2]; +Mat4 sFloorAlignMatrix[2]; s16 tilt_body_running(struct MarioState *m) { s16 pitch = find_floor_slope(m, 0); @@ -89,8 +89,8 @@ void play_step_sound(struct MarioState *m, s16 frame1, s16 frame2) { void align_with_floor(struct MarioState *m) { m->pos[1] = m->floorHeight; - mtxf_align_terrain_triangle(D_80339F50[m->unk00], m->pos, m->faceAngle[1], 40.0f); - m->marioObj->header.gfx.throwMatrix = &D_80339F50[m->unk00]; + mtxf_align_terrain_triangle(sFloorAlignMatrix[m->unk00], m->pos, m->faceAngle[1], 40.0f); + m->marioObj->header.gfx.throwMatrix = &sFloorAlignMatrix[m->unk00]; } s32 begin_walking_action(struct MarioState *m, f32 forwardVel, u32 action, u32 actionArg) { diff --git a/src/game/mario_misc.c b/src/game/mario_misc.c index 6095b6e5..e6354e89 100644 --- a/src/game/mario_misc.c +++ b/src/game/mario_misc.c @@ -574,7 +574,7 @@ Gfx *geo_switch_mario_hand_grab_pos(s32 callContext, struct GraphNode *b, Mat4 * // This is why it won't update during a pause buffered hitstun or when the camera is very far // away. get_pos_from_transform_mtx(marioState->marioBodyState->heldObjLastPosition, *curTransform, - gCurGraphNodeCamera->matrixPtr); + *gCurGraphNodeCamera->matrixPtr); } return NULL; } diff --git a/src/game/obj_behaviors.c b/src/game/obj_behaviors.c index 58339bd1..601c45f1 100644 --- a/src/game/obj_behaviors.c +++ b/src/game/obj_behaviors.c @@ -15,6 +15,7 @@ #include "game_init.h" #include "ingame_menu.h" #include "interaction.h" +#include "level_misc_macros.h" #include "level_table.h" #include "level_update.h" #include "levels/bob/header.h" @@ -235,7 +236,7 @@ void obj_orient_graph(struct Object *obj, f32 normalX, f32 normalY, f32 normalZ) surfaceNormals[2] = normalZ; mtxf_align_terrain_normal(*throwMatrix, surfaceNormals, objVisualPosition, obj->oFaceAngleYaw); - obj->header.gfx.throwMatrix = (void *) throwMatrix; + obj->header.gfx.throwMatrix = throwMatrix; } /** diff --git a/src/game/object_helpers.c b/src/game/object_helpers.c index cd27f089..22b45b32 100644 --- a/src/game/object_helpers.c +++ b/src/game/object_helpers.c @@ -42,7 +42,7 @@ Gfx *geo_update_projectile_pos_from_parent(s32 callContext, UNUSED struct GraphN if (callContext == GEO_CONTEXT_RENDER) { sp1C = (struct Object *) gCurGraphNodeObject; // TODO: change global type to Object pointer if (sp1C->prevObj) { - create_transformation_from_matrices(sp20, mtx, gCurGraphNodeCamera->matrixPtr); + create_transformation_from_matrices(sp20, mtx, *gCurGraphNodeCamera->matrixPtr); obj_update_pos_from_parent_transformation(sp20, sp1C->prevObj); obj_set_gfx_pos_from_pos(sp1C->prevObj); } @@ -1285,7 +1285,7 @@ static void cur_obj_move_update_underwater_flags(void) { } static void cur_obj_move_update_ground_air_flags(UNUSED f32 gravity, f32 bounciness) { - o->oMoveFlags &= ~OBJ_MOVE_13; + o->oMoveFlags &= ~OBJ_MOVE_BOUNCE; if (o->oPosY < o->oFloorHeight) { // On the first frame that we touch the ground, set OBJ_MOVE_LANDED. @@ -1305,9 +1305,9 @@ static void cur_obj_move_update_ground_air_flags(UNUSED f32 gravity, f32 bouncin } if (o->oVelY > 5.0f) { - //! If OBJ_MOVE_13 tracks bouncing, it overestimates, since velY - // could be > 5 here without bounce (e.g. jump into misa) - o->oMoveFlags |= OBJ_MOVE_13; + //! This overestimates since velY could be > 5 here + //! without bounce (e.g. jump into misa). + o->oMoveFlags |= OBJ_MOVE_BOUNCE; } } else { o->oMoveFlags &= ~OBJ_MOVE_LANDED; @@ -1379,7 +1379,8 @@ void cur_obj_move_y(f32 gravity, f32 bounciness, f32 buoyancy) { } } - if (o->oMoveFlags & OBJ_MOVE_MASK_33) { + if (o->oMoveFlags & (OBJ_MOVE_MASK_ON_GROUND | OBJ_MOVE_AT_WATER_SURFACE + | OBJ_MOVE_UNDERWATER_OFF_GROUND)) { o->oMoveFlags &= ~OBJ_MOVE_IN_AIR; } else { o->oMoveFlags |= OBJ_MOVE_IN_AIR; @@ -1770,7 +1771,7 @@ static void cur_obj_update_floor_and_resolve_wall_collisions(s16 steepSlopeDegre if (o->activeFlags & (ACTIVE_FLAG_FAR_AWAY | ACTIVE_FLAG_IN_DIFFERENT_ROOM)) { cur_obj_update_floor(); - o->oMoveFlags &= ~OBJ_MOVE_MASK_HIT_WALL_OR_IN_WATER; + o->oMoveFlags &= ~(OBJ_MOVE_HIT_WALL | OBJ_MOVE_MASK_IN_WATER); if (o->oPosY > o->oFloorHeight) { o->oMoveFlags |= OBJ_MOVE_IN_AIR; @@ -1939,7 +1940,7 @@ void obj_set_throw_matrix_from_transform(struct Object *obj) { obj_apply_scale_to_transform(obj); } - obj->header.gfx.throwMatrix = obj->transform; + obj->header.gfx.throwMatrix = &obj->transform; //! Sets scale of gCurrentObject instead of obj. Not exploitable since this // function is only called with obj = gCurrentObject @@ -1957,7 +1958,7 @@ void obj_build_transform_relative_to_parent(struct Object *obj) { obj->oPosY = obj->transform[3][1]; obj->oPosZ = obj->transform[3][2]; - obj->header.gfx.throwMatrix = obj->transform; + obj->header.gfx.throwMatrix = &obj->transform; //! Sets scale of gCurrentObject instead of obj. Not exploitable since this // function is only called with obj = gCurrentObject @@ -2250,23 +2251,23 @@ static void stub_obj_helpers_2(void) { } s32 cur_obj_set_direction_table(s8 *a0) { - o->oToxBoxUnk1AC = a0; - o->oToxBoxUnk1B0 = 0; + o->oToxBoxMovementPattern = a0; + o->oToxBoxMovementStep = 0; - return *(s8 *) o->oToxBoxUnk1AC; + return *(s8 *) o->oToxBoxMovementPattern; } s32 cur_obj_progress_direction_table(void) { s8 spF; - s8 *sp8 = o->oToxBoxUnk1AC; - s32 sp4 = o->oToxBoxUnk1B0 + 1; + s8 *sp8 = o->oToxBoxMovementPattern; + s32 sp4 = o->oToxBoxMovementStep + 1; if (sp8[sp4] != -1) { spF = sp8[sp4]; - o->oToxBoxUnk1B0++; + o->oToxBoxMovementStep++; } else { spF = sp8[0]; - o->oToxBoxUnk1B0 = 0; + o->oToxBoxMovementStep = 0; } return spF; @@ -2763,7 +2764,7 @@ void cur_obj_align_gfx_with_floor(void) { floorNormal[2] = floor->normal.z; mtxf_align_terrain_normal(o->transform, floorNormal, position, o->oFaceAngleYaw); - o->header.gfx.throwMatrix = o->transform; + o->header.gfx.throwMatrix = &o->transform; } } diff --git a/src/game/rendering_graph_node.c b/src/game/rendering_graph_node.c index 18e70e4a..bc99adc7 100644 --- a/src/game/rendering_graph_node.c +++ b/src/game/rendering_graph_node.c @@ -267,10 +267,15 @@ static void geo_process_perspective(struct GraphNodePerspective *node) { * range of this node. */ static void geo_process_level_of_detail(struct GraphNodeLevelOfDetail *node) { +#ifdef GBI_FLOATS + Mtx *mtx = gMatStackFixed[gMatStackIndex]; + s16 distanceFromCam = (s32) -mtx->m[3][2]; // z-component of the translation column +#else // The fixed point Mtx type is defined as 16 longs, but it's actually 16 // shorts for the integer parts followed by 16 shorts for the fraction parts - s16 *mtx = (s16 *) gMatStackFixed[gMatStackIndex]; - s16 distanceFromCam = -mtx[14]; // z-component of the translation column + Mtx *mtx = gMatStackFixed[gMatStackIndex]; + s16 distanceFromCam = -GET_HIGH_S16_OF_32(mtx->m[1][3]); // z-component of the translation column +#endif if (node->minDistance <= distanceFromCam && distanceFromCam < node->maxDistance) { if (node->node.children != 0) { @@ -321,7 +326,7 @@ static void geo_process_camera(struct GraphNodeCamera *node) { gMatStackFixed[gMatStackIndex] = mtx; if (node->fnNode.node.children != 0) { gCurGraphNodeCamera = node; - node->matrixPtr = gMatStack[gMatStackIndex]; + node->matrixPtr = &gMatStack[gMatStackIndex]; geo_process_node_and_siblings(node->fnNode.node.children); gCurGraphNodeCamera = NULL; } @@ -646,7 +651,7 @@ static void geo_process_shadow(struct GraphNodeShadow *node) { if (gCurGraphNodeCamera != NULL && gCurGraphNodeObject != NULL) { if (gCurGraphNodeHeldObject != NULL) { get_pos_from_transform_mtx(shadowPos, gMatStack[gMatStackIndex], - gCurGraphNodeCamera->matrixPtr); + *gCurGraphNodeCamera->matrixPtr); shadowScale = node->shadowScale; } else { vec3f_copy(shadowPos, gCurGraphNodeObject->pos); @@ -686,7 +691,7 @@ static void geo_process_shadow(struct GraphNodeShadow *node) { mtx = alloc_display_list(sizeof(*mtx)); gMatStackIndex++; mtxf_translate(mtxf, shadowPos); - mtxf_mul(gMatStack[gMatStackIndex], mtxf, gCurGraphNodeCamera->matrixPtr); + mtxf_mul(gMatStack[gMatStackIndex], mtxf, *gCurGraphNodeCamera->matrixPtr); mtxf_to_mtx(mtx, gMatStack[gMatStackIndex]); gMatStackFixed[gMatStackIndex] = mtx; if (gShadowAboveWaterOrLava == 1) { @@ -800,7 +805,7 @@ static void geo_process_object(struct Object *node) { if (node->header.gfx.unk18 == gCurGraphNodeRoot->areaIndex) { if (node->header.gfx.throwMatrix != NULL) { - mtxf_mul(gMatStack[gMatStackIndex + 1], (void *) node->header.gfx.throwMatrix, + mtxf_mul(gMatStack[gMatStackIndex + 1], *node->header.gfx.throwMatrix, gMatStack[gMatStackIndex]); } else if (node->header.gfx.node.flags & GRAPH_RENDER_CYLBOARD) { mtxf_cylboard(gMatStack[gMatStackIndex + 1], gMatStack[gMatStackIndex], @@ -815,7 +820,7 @@ static void geo_process_object(struct Object *node) { mtxf_scale_vec3f(gMatStack[gMatStackIndex + 1], gMatStack[gMatStackIndex + 1], node->header.gfx.scale); - node->header.gfx.throwMatrix = gMatStack[++gMatStackIndex]; + node->header.gfx.throwMatrix = &gMatStack[++gMatStackIndex]; node->header.gfx.cameraToObject[0] = gMatStack[gMatStackIndex][3][0]; node->header.gfx.cameraToObject[1] = gMatStack[gMatStackIndex][3][1]; node->header.gfx.cameraToObject[2] = gMatStack[gMatStackIndex][3][2]; @@ -886,7 +891,7 @@ void geo_process_held_object(struct GraphNodeHeldObject *node) { translation[2] = node->translation[2] / 4.0f; mtxf_translate(mat, translation); - mtxf_copy(gMatStack[gMatStackIndex + 1], (void *) gCurGraphNodeObject->throwMatrix); + mtxf_copy(gMatStack[gMatStackIndex + 1], *gCurGraphNodeObject->throwMatrix); gMatStack[gMatStackIndex + 1][3][0] = gMatStack[gMatStackIndex][3][0]; gMatStack[gMatStackIndex + 1][3][1] = gMatStack[gMatStackIndex][3][1]; gMatStack[gMatStackIndex + 1][3][2] = gMatStack[gMatStackIndex][3][2]; diff --git a/tools/textconv.c b/tools/textconv.c index 595835ae..867a944a 100644 --- a/tools/textconv.c +++ b/tools/textconv.c @@ -54,31 +54,69 @@ static void parse_error(const char *filename, int lineNum, const char *msgfmt, . // Reads the whole file and returns a null-terminated buffer with its contents void *read_text_file(const char *filename) { - FILE *file = fopen(filename, "rb"); - uint8_t *buffer; - size_t size; + if (strcmp(filename, "-") != 0) + { + FILE *file = fopen(filename, "rb"); + uint8_t *buffer; + size_t size; - if (file == NULL) - fatal_error("failed to open file '%s' for reading: %s", filename, strerror(errno)); + if (file == NULL) + fatal_error("failed to open file '%s' for reading: %s", filename, strerror(errno)); - // get size - fseek(file, 0, SEEK_END); - size = ftell(file); + // get size + fseek(file, 0, SEEK_END); + size = ftell(file); - // allocate buffer - buffer = malloc(size + 1); + // allocate buffer + buffer = malloc(size + 1); + if (buffer == NULL) + fatal_error("could not allocate buffer of size %u", (uint32_t)(size + 1)); - // read file - fseek(file, 0, SEEK_SET); - if (fread(buffer, size, 1, file) != 1) - fatal_error("error reading from file '%s': %s", filename, strerror(errno)); + // read file + fseek(file, 0, SEEK_SET); + if (fread(buffer, size, 1, file) != 1) + fatal_error("error reading from file '%s': %s", filename, strerror(errno)); - // null-terminate the buffer - buffer[size] = 0; + // null-terminate the buffer + buffer[size] = 0; - fclose(file); + fclose(file); - return buffer; + return buffer; + } + else + { + size_t size = 0; + size_t capacity = 1024; + uint8_t *buffer = malloc(capacity + 1); + + if (buffer == NULL) + fatal_error("could not allocate buffer of size %u", (uint32_t)(capacity + 1)); + + for (;;) + { + size += fread(buffer + size, 1, capacity - size, stdin); + if (size == capacity) + { + capacity *= 2; + buffer = realloc(buffer, capacity + 1); + if (buffer == NULL) + fatal_error("could not allocate buffer of size %u", (uint32_t)(capacity + 1)); + } + else if (feof(stdin)) + { + break; + } + else + { + fatal_error("error reading from stdin: %s", strerror(errno)); + } + } + + // null-terminate the buffer + buffer[size] = 0; + return buffer; + } } static char *skip_whitespace(char *str) @@ -351,7 +389,7 @@ static char *convert_string(char *pos, FILE *fout, const char *inputFileName, ch static void convert_file(const char *infilename, const char *outfilename) { char *in = read_text_file(infilename); - FILE *fout = fopen(outfilename, "wb"); + FILE *fout = strcmp(outfilename, "-") != 0 ? fopen(outfilename, "wb") : stdout; if (fout == NULL) fatal_error("failed to open file '%s' for writing: %s", strerror(errno)); @@ -436,7 +474,8 @@ static void convert_file(const char *infilename, const char *outfilename) eof: fwrite(start, pos - start, 1, fout); - fclose(fout); + if (strcmp(outfilename, "-") != 0) + fclose(fout); free(in); }