From 6a957757d4cd3e48f32e8cb33177ecc26742aaed Mon Sep 17 00:00:00 2001 From: MysterD Date: Tue, 3 Aug 2021 19:21:50 -0700 Subject: [PATCH] Refactored network area timer system --- include/object_fields.h | 4 - include/types.h | 1 + src/engine/behavior_script.c | 40 +++- src/engine/behavior_script.h | 6 +- src/game/behaviors/bomp.inc.c | 206 ++++++++---------- src/game/behaviors/bowser_puzzle_piece.inc.c | 31 +-- .../behaviors/checkerboard_platform.inc.c | 91 ++++---- src/game/behaviors/ddd_pole.inc.c | 36 ++- src/game/spawn_object.c | 1 + 9 files changed, 190 insertions(+), 226 deletions(-) diff --git a/include/object_fields.h b/include/object_fields.h index 376c3c541..a6d771ce5 100644 --- a/include/object_fields.h +++ b/include/object_fields.h @@ -232,7 +232,6 @@ /* Bomp (Small) */ #define /*0x100*/ oSmallBompInitX OBJECT_FIELD_F32(0x1E) -#define /*?????*/ oBompTimer OBJECT_FIELD_U32(0x1F) /* Boo */ #define /*0x088*/ oBooDeathStatus OBJECT_FIELD_S32(0x00) @@ -311,7 +310,6 @@ #define /*0x108*/ oBowserPuzzlePieceContinuePerformingAction OBJECT_FIELD_S32(0x20) #define /*0x10C*/ oBowserPuzzlePieceActionList OBJECT_FIELD_VPTR(0x21) #define /*0x110*/ oBowserPuzzlePieceNextAction OBJECT_FIELD_VPTR(0x22) -#define /*0x0F4*/ oBowserPuzzlePieceTimer OBJECT_FIELD_U32(0x1B) /* Bubba */ #define /*0x0F4*/ oBubbaUnkF4 OBJECT_FIELD_F32(0x1B) @@ -377,7 +375,6 @@ #define /*0x0F8*/ oCheckerBoardPlatformUnkF8 OBJECT_FIELD_S32(0x1C) // oAction like #define /*0x0FC*/ oCheckerBoardPlatformUnkFC OBJECT_FIELD_S32(0x1D) #define /*0x1AC*/ oCheckerBoardPlatformUnk1AC OBJECT_FIELD_F32(0x49) -#define /*0x1B0*/ oCheckerBoardPlatformTimer OBJECT_FIELD_U32(0x4A) /* Cheep Cheep */ #define /*0x0F4*/ oCheepCheepUnkF4 OBJECT_FIELD_F32(0x1B) @@ -830,7 +827,6 @@ #define /*0x0F4*/ oDDDPoleVel OBJECT_FIELD_F32(0x1B) #define /*0x0F8*/ oDDDPoleMaxOffset OBJECT_FIELD_F32(0x1C) #define /*0x0FC*/ oDDDPoleOffset OBJECT_FIELD_F32(0x1D) -#define /*0x100*/ oDDDPoleTimer OBJECT_FIELD_U32(0x1E) /* Pyramid Top */ #define /*0x0F4*/ oPyramidTopPillarsTouched OBJECT_FIELD_S32(0x1B) diff --git a/include/types.h b/include/types.h index 6ed9cf9cf..96af4531a 100644 --- a/include/types.h +++ b/include/types.h @@ -221,6 +221,7 @@ struct Object /*0x21C*/ Mat4 transform; /*0x25C*/ void *respawnInfo; /*?????*/ u8 createdThroughNetwork; + /*?????*/ u32 areaTimer; }; struct ObjectHitbox diff --git a/src/engine/behavior_script.c b/src/engine/behavior_script.c index aa4bdcc41..d38236400 100644 --- a/src/engine/behavior_script.c +++ b/src/engine/behavior_script.c @@ -109,18 +109,6 @@ s32 random_sign(void) { } } -u16 position_based_random_u16(void) { - u16 value = (u16)(gCurrentObject->oPosX * 2659); - value ^= (u16)(gCurrentObject->oPosY * 1901); - value ^= (u16)(gCurrentObject->oPosZ * 3331); - return value; -} - -f32 position_based_random_float_position(void) { - f32 rnd = position_based_random_u16(); - return rnd / (double)0x10000; -} - // Update an object's graphical position and rotation to match its real position and rotation. void obj_update_gfx_pos_and_angle(struct Object *obj) { obj->header.gfx.pos[0] = obj->oPosX; @@ -1129,3 +1117,31 @@ void cur_obj_fake_update(void) { gCurrentObject->oPrevAction = gCurrentObject->oAction); } } + +u16 position_based_random_u16(void) { + u16 value = (u16)(gCurrentObject->oPosX * 2659); + value ^= (u16)(gCurrentObject->oPosY * 1901); + value ^= (u16)(gCurrentObject->oPosZ * 3331); + return value; +} + +f32 position_based_random_float_position(void) { + f32 rnd = position_based_random_u16(); + return rnd / (double)0x10000; +} + +void cur_obj_area_timer_loop(u32 loopLength, void (*func)(void)) { + if ((gNetworkAreaTimer - gCurrentObject->areaTimer) >= loopLength) { + u32 catchup = (gNetworkAreaTimer - gCurrentObject->areaTimer) / loopLength; + catchup *= loopLength; + gCurrentObject->areaTimer += catchup; + } + + while (gCurrentObject->areaTimer < gNetworkAreaTimer) { + (*func)(); + gCurrentObject->areaTimer++; + if (gCurrentObject->areaTimer < gNetworkAreaTimer) { + cur_obj_fake_update(); + } + } +} diff --git a/src/engine/behavior_script.h b/src/engine/behavior_script.h index 303b5c5cf..04d928a33 100644 --- a/src/engine/behavior_script.h +++ b/src/engine/behavior_script.h @@ -22,12 +22,14 @@ u16 random_u16(void); float random_float(void); s32 random_sign(void); -u16 position_based_random_u16(void); -f32 position_based_random_float_position(void); void stub_behavior_script_2(void); void cur_obj_update(void); void cur_obj_fake_update(void); +u16 position_based_random_u16(void); +f32 position_based_random_float_position(void); +void cur_obj_area_timer_loop(u32 loopLength, void (*func)(void)); + #endif // BEHAVIOR_SCRIPT_H diff --git a/src/game/behaviors/bomp.inc.c b/src/game/behaviors/bomp.inc.c index 90a199ee6..569b71f90 100644 --- a/src/game/behaviors/bomp.inc.c +++ b/src/game/behaviors/bomp.inc.c @@ -1,144 +1,122 @@ // bomp.c.inc void bhv_small_bomp_init(void) { - o->oBompTimer = 0; o->oFaceAngleYaw -= 0x4000; o->oSmallBompInitX = o->oPosX; o->oTimer = position_based_random_float_position() * 100.0f; } -void bhv_small_bomp_loop(void) { - u32 loopLength = 168; - if ((gNetworkAreaTimer - o->oBompTimer) >= loopLength) { - u32 catchup = (gNetworkAreaTimer - o->oBompTimer) / loopLength; - catchup *= loopLength; - o->oBompTimer += catchup; - } +static void bhv_small_bomp_loop_inner(void) { + switch (o->oAction) { + case BOMP_ACT_WAIT: + if (o->oTimer >= 101) { + o->oAction = BOMP_ACT_POKE_OUT; + o->oForwardVel = 30.0f; + } + break; - while (o->oBompTimer < gNetworkAreaTimer) { - switch (o->oAction) { - case BOMP_ACT_WAIT: - if (o->oTimer >= 101) { - o->oAction = BOMP_ACT_POKE_OUT; - o->oForwardVel = 30.0f; - } - break; + case BOMP_ACT_POKE_OUT: + if (o->oPosX > 3450.0f) { + o->oPosX = 3450.0f; + o->oForwardVel = 0; + } - case BOMP_ACT_POKE_OUT: - if (o->oPosX > 3450.0f) { - o->oPosX = 3450.0f; - o->oForwardVel = 0; - } + if (o->oTimer == 15.0) { + o->oAction = BOMP_ACT_EXTEND; + o->oForwardVel = 40.0f; + cur_obj_play_sound_2(SOUND_OBJ_UNKNOWN2); + } + break; - if (o->oTimer == 15.0) { - o->oAction = BOMP_ACT_EXTEND; - o->oForwardVel = 40.0f; - cur_obj_play_sound_2(SOUND_OBJ_UNKNOWN2); - } - break; + case BOMP_ACT_EXTEND: + if (o->oPosX > 3830.0f) { + o->oPosX = 3830.0f; + o->oForwardVel = 0; + } - case BOMP_ACT_EXTEND: - if (o->oPosX > 3830.0f) { - o->oPosX = 3830.0f; - o->oForwardVel = 0; - } + if (o->oTimer == 60) { + o->oAction = BOMP_ACT_RETRACT; + o->oForwardVel = 10.0f; + o->oMoveAngleYaw -= 0x8000; + cur_obj_play_sound_2(SOUND_OBJ_UNKNOWN2); + } + break; - if (o->oTimer == 60) { - o->oAction = BOMP_ACT_RETRACT; - o->oForwardVel = 10.0f; - o->oMoveAngleYaw -= 0x8000; - cur_obj_play_sound_2(SOUND_OBJ_UNKNOWN2); - } - break; + case BOMP_ACT_RETRACT: + if (o->oPosX < 3330.0f) { + o->oPosX = 3330.0f; + o->oForwardVel = 0; + } - case BOMP_ACT_RETRACT: - if (o->oPosX < 3330.0f) { - o->oPosX = 3330.0f; - o->oForwardVel = 0; - } - - if (o->oTimer == 90) { - o->oAction = BOMP_ACT_POKE_OUT; - o->oForwardVel = 25.0f; - o->oMoveAngleYaw -= 0x8000; - } - break; - } - - o->oBompTimer++; - if (o->oBompTimer < gNetworkAreaTimer) { - cur_obj_fake_update(); - } + if (o->oTimer == 90) { + o->oAction = BOMP_ACT_POKE_OUT; + o->oForwardVel = 25.0f; + o->oMoveAngleYaw -= 0x8000; + } + break; } } +void bhv_small_bomp_loop(void) { + cur_obj_area_timer_loop(168, bhv_small_bomp_loop_inner); +} + void bhv_large_bomp_init(void) { - o->oBompTimer = 0; o->oMoveAngleYaw += 0x4000; o->oTimer = position_based_random_float_position() * 100.0f; } -void bhv_large_bomp_loop(void) { - u32 loopLength = 168; - if ((gNetworkAreaTimer - o->oBompTimer) >= loopLength) { - u32 catchup = (gNetworkAreaTimer - o->oBompTimer) / loopLength; - catchup *= loopLength; - o->oBompTimer += catchup; - } +void bhv_large_bomp_loop_inner(void) { + switch (o->oAction) { + case BOMP_ACT_WAIT: + if (o->oTimer >= 101) { + o->oAction = BOMP_ACT_POKE_OUT; + o->oForwardVel = 30.0f; + } + break; - while (o->oBompTimer < gNetworkAreaTimer) { - switch (o->oAction) { - case BOMP_ACT_WAIT: - if (o->oTimer >= 101) { - o->oAction = BOMP_ACT_POKE_OUT; - o->oForwardVel = 30.0f; - } - break; + case BOMP_ACT_POKE_OUT: + if (o->oPosX > 3450.0f) { + o->oPosX = 3450.0f; + o->oForwardVel = 0; + } - case BOMP_ACT_POKE_OUT: - if (o->oPosX > 3450.0f) { - o->oPosX = 3450.0f; - o->oForwardVel = 0; - } + if (o->oTimer == 15.0) { + o->oAction = BOMP_ACT_EXTEND; + o->oForwardVel = 10.0f; + cur_obj_play_sound_2(SOUND_OBJ_UNKNOWN2); + } + break; - if (o->oTimer == 15.0) { - o->oAction = BOMP_ACT_EXTEND; - o->oForwardVel = 10.0f; - cur_obj_play_sound_2(SOUND_OBJ_UNKNOWN2); - } - break; + case BOMP_ACT_EXTEND: + if (o->oPosX > 3830.0f) { + o->oPosX = 3830.0f; + o->oForwardVel = 0; + } - case BOMP_ACT_EXTEND: - if (o->oPosX > 3830.0f) { - o->oPosX = 3830.0f; - o->oForwardVel = 0; - } + if (o->oTimer == 60) { + o->oAction = BOMP_ACT_RETRACT; + o->oForwardVel = 10.0f; + o->oMoveAngleYaw -= 0x8000; + cur_obj_play_sound_2(SOUND_OBJ_UNKNOWN2); + } + break; - if (o->oTimer == 60) { - o->oAction = BOMP_ACT_RETRACT; - o->oForwardVel = 10.0f; - o->oMoveAngleYaw -= 0x8000; - cur_obj_play_sound_2(SOUND_OBJ_UNKNOWN2); - } - break; + case BOMP_ACT_RETRACT: + if (o->oPosX < 3330.0f) { + o->oPosX = 3330.0f; + o->oForwardVel = 0; + } - case BOMP_ACT_RETRACT: - if (o->oPosX < 3330.0f) { - o->oPosX = 3330.0f; - o->oForwardVel = 0; - } - - if (o->oTimer == 90) { - o->oAction = BOMP_ACT_POKE_OUT; - o->oForwardVel = 25.0f; - o->oMoveAngleYaw -= 0x8000; - } - break; - } - - o->oBompTimer++; - if (o->oBompTimer < gNetworkAreaTimer) { - cur_obj_fake_update(); - } + if (o->oTimer == 90) { + o->oAction = BOMP_ACT_POKE_OUT; + o->oForwardVel = 25.0f; + o->oMoveAngleYaw -= 0x8000; + } + break; } } + +void bhv_large_bomp_loop(void) { + cur_obj_area_timer_loop(168, bhv_large_bomp_loop_inner); +} diff --git a/src/game/behaviors/bowser_puzzle_piece.inc.c b/src/game/behaviors/bowser_puzzle_piece.inc.c index cbdccf75f..dc800a5b5 100644 --- a/src/game/behaviors/bowser_puzzle_piece.inc.c +++ b/src/game/behaviors/bowser_puzzle_piece.inc.c @@ -94,7 +94,6 @@ void bhv_lll_bowser_puzzle_spawn_piece(s16 model, const BehaviorScript *behavior puzzlePiece->oAction = initialAction; // This action never gets executed. puzzlePiece->oBowserPuzzlePieceActionList = actionList; puzzlePiece->oBowserPuzzlePieceNextAction = actionList; - puzzlePiece->oBowserPuzzlePieceTimer = 0; puzzlePiece->oTimer = 0; } @@ -258,26 +257,16 @@ void (*sBowserPuzzlePieceActions[])(void) = { bhv_lll_bowser_puzzle_piece_move_down }; -void bhv_lll_bowser_puzzle_piece_loop(void) { - u32 loopLength = 650; - if ((gNetworkAreaTimer - o->oBowserPuzzlePieceTimer) >= loopLength) { - u32 catchup = (gNetworkAreaTimer - o->oBowserPuzzlePieceTimer) / loopLength; - catchup *= loopLength; - o->oBowserPuzzlePieceTimer += catchup; - } +void bhv_lll_bowser_puzzle_piece_loop_inner(void) { + bhv_lll_bowser_puzzle_piece_update(); - while (o->oBowserPuzzlePieceTimer < gNetworkAreaTimer) { - bhv_lll_bowser_puzzle_piece_update(); + cur_obj_call_action_function(sBowserPuzzlePieceActions); - cur_obj_call_action_function(sBowserPuzzlePieceActions); - - o->oPosX = o->oBowserPuzzlePieceOffsetX + o->oHomeX; - o->oPosY = o->oBowserPuzzlePieceOffsetY + o->oHomeY; - o->oPosZ = o->oBowserPuzzlePieceOffsetZ + o->oHomeZ; - - o->oBowserPuzzlePieceTimer++; - if (o->oBowserPuzzlePieceTimer < gNetworkAreaTimer) { - cur_obj_fake_update(); - } - } + o->oPosX = o->oBowserPuzzlePieceOffsetX + o->oHomeX; + o->oPosY = o->oBowserPuzzlePieceOffsetY + o->oHomeY; + o->oPosZ = o->oBowserPuzzlePieceOffsetZ + o->oHomeZ; +} + +void bhv_lll_bowser_puzzle_piece_loop(void) { + cur_obj_area_timer_loop(650, bhv_lll_bowser_puzzle_piece_loop_inner); } diff --git a/src/game/behaviors/checkerboard_platform.inc.c b/src/game/behaviors/checkerboard_platform.inc.c index 832d1ba06..b9ae00c58 100644 --- a/src/game/behaviors/checkerboard_platform.inc.c +++ b/src/game/behaviors/checkerboard_platform.inc.c @@ -24,7 +24,6 @@ void bhv_checkerboard_elevator_group_init(void) { bhvCheckerboardPlatformSub); sp2C->oCheckerBoardPlatformUnk1AC = D_8032F754[sp34].unk2; sp2C->oTimer = 0; - sp2C->oCheckerBoardPlatformTimer = 0; vec3f_copy_2(sp2C->header.gfx.scale, D_8032F754[sp34].unk1); } } @@ -53,60 +52,52 @@ void bhv_checkerboard_platform_init(void) { o->oCheckerBoardPlatformUnkFC = o->parentObj->oBehParams2ndByte; } -void bhv_checkerboard_platform_loop(void) { - u32 loopLength = 132 + o->oCheckerBoardPlatformUnkFC * 2; - if ((gNetworkAreaTimer - o->oCheckerBoardPlatformTimer) >= loopLength) { - u32 catchup = (gNetworkAreaTimer - o->oCheckerBoardPlatformTimer) / loopLength; - catchup *= loopLength; - o->oCheckerBoardPlatformTimer += catchup; +static void bhv_checkerboard_platform_loop_inner(void) { + f32 sp24 = o->oCheckerBoardPlatformUnk1AC; + o->oCheckerBoardPlatformUnkF8 = 0; + switch (o->oAction) { + case 0: + if (o->oBehParams2ndByte == 0) + o->oAction = 1; + else + o->oAction = 3; + break; + case 1: + checkerboard_plat_act_move_y(2, 10.0f, o->oCheckerBoardPlatformUnkFC); + break; + case 2: + checkerboard_plat_act_rotate(3, 512); + break; + case 3: + checkerboard_plat_act_move_y(4, -10.0f, o->oCheckerBoardPlatformUnkFC); + break; + case 4: + checkerboard_plat_act_rotate(1, -512); + break; } + o->oMoveAnglePitch += absi(o->oAngleVelPitch); + o->oFaceAnglePitch += absi(o->oAngleVelPitch); + o->oFaceAngleYaw = o->oMoveAngleYaw; + if (o->oMoveAnglePitch != 0) { + o->oForwardVel = signum_positive(o->oAngleVelPitch) * sins(o->oMoveAnglePitch) * sp24; + o->oVelY = signum_positive(o->oAngleVelPitch) * coss(o->oMoveAnglePitch) * sp24; + } + if (o->oCheckerBoardPlatformUnkF8 == 1) { + o->oAngleVelPitch = 0; + o->oFaceAnglePitch &= ~0x7FFF; + cur_obj_move_using_fvel_and_gravity(); + } + else { + cur_obj_move_using_fvel_and_gravity(); + } +} +void bhv_checkerboard_platform_loop(void) { if (o->oDistanceToMario < 1000.0f) cur_obj_play_sound_1(SOUND_ENV_ELEVATOR4); - while (o->oCheckerBoardPlatformTimer < gNetworkAreaTimer) { - s32 oldAction = o->oAction; - f32 sp24 = o->oCheckerBoardPlatformUnk1AC; - o->oCheckerBoardPlatformUnkF8 = 0; - switch (o->oAction) { - case 0: - if (o->oBehParams2ndByte == 0) - o->oAction = 1; - else - o->oAction = 3; - break; - case 1: - checkerboard_plat_act_move_y(2, 10.0f, o->oCheckerBoardPlatformUnkFC); - break; - case 2: - checkerboard_plat_act_rotate(3, 512); - break; - case 3: - checkerboard_plat_act_move_y(4, -10.0f, o->oCheckerBoardPlatformUnkFC); - break; - case 4: - checkerboard_plat_act_rotate(1, -512); - break; - } - o->oMoveAnglePitch += absi(o->oAngleVelPitch); - o->oFaceAnglePitch += absi(o->oAngleVelPitch); - o->oFaceAngleYaw = o->oMoveAngleYaw; - if (o->oMoveAnglePitch != 0) { - o->oForwardVel = signum_positive(o->oAngleVelPitch) * sins(o->oMoveAnglePitch) * sp24; - o->oVelY = signum_positive(o->oAngleVelPitch) * coss(o->oMoveAnglePitch) * sp24; - } - if (o->oCheckerBoardPlatformUnkF8 == 1) { - o->oAngleVelPitch = 0; - o->oFaceAnglePitch &= ~0x7FFF; - cur_obj_move_using_fvel_and_gravity(); - } else - cur_obj_move_using_fvel_and_gravity(); - - o->oCheckerBoardPlatformTimer++; - if (o->oCheckerBoardPlatformTimer < gNetworkAreaTimer) { - cur_obj_fake_update(); - } - } + u32 loopLength = 132 + o->oCheckerBoardPlatformUnkFC * 2; + cur_obj_area_timer_loop(loopLength, bhv_checkerboard_platform_loop_inner); load_object_collision_model(); } diff --git a/src/game/behaviors/ddd_pole.inc.c b/src/game/behaviors/ddd_pole.inc.c index 0c8693d7d..a38be033b 100644 --- a/src/game/behaviors/ddd_pole.inc.c +++ b/src/game/behaviors/ddd_pole.inc.c @@ -8,30 +8,20 @@ void bhv_ddd_pole_init(void) { } } +static void bhv_ddd_pole_update_inner(void) { + if (o->oTimer > 20) { + o->oDDDPoleOffset += o->oDDDPoleVel; + + if (clamp_f32(&o->oDDDPoleOffset, 0.0f, o->oDDDPoleMaxOffset)) { + o->oDDDPoleVel = -o->oDDDPoleVel; + o->oTimer = 0; + } + } + + obj_set_dist_from_home(o->oDDDPoleOffset); +} void bhv_ddd_pole_update(void) { u32 loopLength = (((u16)o->oDDDPoleMaxOffset / 10) + 20) * 2; - if ((gNetworkAreaTimer - o->oDDDPoleTimer) >= loopLength) { - u32 catchup = (gNetworkAreaTimer - o->oDDDPoleTimer) / loopLength; - catchup *= loopLength; - o->oDDDPoleTimer += catchup; - } - - while (o->oDDDPoleTimer < gNetworkAreaTimer) { - if (o->oTimer > 20) { - o->oDDDPoleOffset += o->oDDDPoleVel; - - if (clamp_f32(&o->oDDDPoleOffset, 0.0f, o->oDDDPoleMaxOffset)) { - o->oDDDPoleVel = -o->oDDDPoleVel; - o->oTimer = 0; - } - } - - obj_set_dist_from_home(o->oDDDPoleOffset); - - o->oDDDPoleTimer++; - if (o->oDDDPoleTimer < gNetworkAreaTimer) { - cur_obj_fake_update(); - } - } + cur_obj_area_timer_loop(loopLength, bhv_ddd_pole_update_inner); } diff --git a/src/game/spawn_object.c b/src/game/spawn_object.c index 055c33acb..09a1094c0 100644 --- a/src/game/spawn_object.c +++ b/src/game/spawn_object.c @@ -364,6 +364,7 @@ struct Object *create_object(const BehaviorScript *bhvScript) { } obj->createdThroughNetwork = false; + obj->areaTimer = 0; return obj; }