diff options
Diffstat (limited to 'src/main.c')
| -rw-r--r-- | src/main.c | 475 |
1 files changed, 226 insertions, 249 deletions
diff --git a/src/main.c b/src/main.c index f2a2a21ff..1435944b0 100644 --- a/src/main.c +++ b/src/main.c @@ -117,7 +117,9 @@ u8 gControllerBits; CollisionGrid gCollisionGrid[1024]; u16 gNumActors; u16 gMatrixObjectCount; -s32 gTickSpeed; +s32 gTickLogic; // Tick game physics at 60fps +s32 gTickVisuals; // Tick animations at 30fps +s32 gTickGame; f32 D_80150118; u16 wasSoftReset; @@ -146,7 +148,7 @@ u16* gPhysicalFramebuffers[3]; uintptr_t gPhysicalZBuffer; UNUSED u32 D_801502B8; UNUSED u32 D_801502BC; -Mat4 D_801502C0; +Mat4 sBillBoardMtx; // Faces 2D actors at the camera s32 padding[2048]; @@ -483,7 +485,7 @@ void* clear_framebuffer(s32 color) { void rendering_init(void) { gGfxPool = &gGfxPools[0]; - set_segment_base_addr(1, gGfxPool); + set_segment_base_addr_x64(1, gGfxPool); gGfxSPTask = &gGfxPool->spTask; gDisplayListHead = gGfxPool->gfxPool; init_rcp(); @@ -496,7 +498,7 @@ void rendering_init(void) { void config_gfx_pool(void) { gGfxPool = &gGfxPools[gGlobalTimer & 1]; - set_segment_base_addr(1, gGfxPool); + set_segment_base_addr_x64(1, gGfxPool); gDisplayListHead = gGfxPool->gfxPool; gGfxSPTask = &gGfxPool->spTask; } @@ -526,7 +528,9 @@ void display_and_vsync(void) { if (++sRenderingFramebuffer == 3) { sRenderingFramebuffer = 0; } - gGlobalTimer++; + if (gTickVisuals) { + gGlobalTimer++; + } } void init_segment_ending_sequences(void) { @@ -625,12 +629,166 @@ void game_init_clear_framebuffer(void) { clear_framebuffer(0); } -void race_logic_loop(void) { - s16 i; +void calculate_updaterate(void) { + static u32 prevtime = 0; + static u32 remainder = 0; + static u32 logicAccumulator = 0; + static u32 visualsAccumulator = 0; + static u32 frameCounter = 0; // For tracking frames for logic updates + u32 now = SDL_GetTicks(); // Replaces osGetTime() + u32 frameRate = 0; + s32 total; + + // Get target FPS from configuration variable + s32 targetFPS = CVarGetInteger("gInterpolationFPS", 30); + + if (targetFPS < 60) { + targetFPS = 30; + } + + // Detect frame rate based on time passed + if (now > prevtime) { + total = (now - prevtime) + remainder; + } else { + // Handle counter reset (shouldn't happen with SDL_GetTicks, but kept for logic parity) + total = (0xffffffff - prevtime) + 1 + now + remainder; + } + + prevtime = now; + + // Avoid division by zero + if (total > 0) { + // Calculate approximate frame rate (milliseconds per frame) + frameRate = 1000 / total; // Frame rate in frames per second + } else { + frameRate = targetFPS; // Fallback to target FPS + } + + // Default both to no updates + gTickLogic = 0; + gTickVisuals = 0; + + // Calculate the update rates based on target FPS + s32 logicUpdateInterval = 1000 / 60; // Time in ms between logic updates + s32 visualsUpdateInterval = 1000 / 30; // 30 FPS for visuals + + // Accumulate time for logic updates + logicAccumulator += total; + if (logicAccumulator >= logicUpdateInterval) { + logicAccumulator -= logicUpdateInterval; // Subtract full interval + if (targetFPS < 60) { + gTickLogic = 2; + } else { + gTickLogic = 1; // Perform logic update + } + } + + // Visual updates (based on 30 FPS equivalent) + visualsAccumulator += total; // Increment for each frame + if (visualsAccumulator >= visualsUpdateInterval) { // Check if it's time to update visuals + visualsAccumulator -= visualsUpdateInterval; + gTickVisuals = 1; // Perform visual update + } +} + + + + + +void display_debug_info(void) { u16 rotY; + if (!gEnableDebugMode) { + D_800DC514 = false; + } else if (D_800DC514) { + if ((gControllerOne->buttonPressed & R_TRIG) && + (gControllerOne->button & A_BUTTON) && + (gControllerOne->button & B_BUTTON)) { + D_800DC514 = false; + } + rotY = camera1->rot[1]; + gDebugPathCount = D_800DC5EC->pathCounter; + + if (rotY < 0x2000) { + func_80057A50(40, 100, "SOUTH ", gDebugPathCount); + } else if (rotY < 0x6000) { + func_80057A50(40, 100, "EAST ", gDebugPathCount); + } else if (rotY < 0xA000) { + func_80057A50(40, 100, "NORTH ", gDebugPathCount); + } else if (rotY < 0xE000) { + func_80057A50(40, 100, "WEST ", gDebugPathCount); + } else { + func_80057A50(40, 100, "SOUTH ", gDebugPathCount); + } + } else if ((gControllerOne->buttonPressed & L_TRIG) && + (gControllerOne->button & A_BUTTON) && + (gControllerOne->button & B_BUTTON)) { + D_800DC514 = true; + } + + if (!gEnableDebugMode) { + gEnableResourceMeters = 0; + } else { + if (gEnableResourceMeters) { + resource_display(); + if (!(gControllerOne->button & L_TRIG) && + (gControllerOne->button & R_TRIG) && + (gControllerOne->buttonPressed & B_BUTTON)) { + gEnableResourceMeters = 0; + } + } else if (!(gControllerOne->button & L_TRIG) && + (gControllerOne->button & R_TRIG) && + (gControllerOne->buttonPressed & B_BUTTON)) { + gEnableResourceMeters = 1; + } + } +} + +void process_game_tick(void) { + if (D_8015011E) { + gCourseTimer += COURSE_TIMER_ITER; + } + func_802909F0(); + evaluate_collision_for_players_and_actors(); + func_800382DC(); + func_8001EE98(gPlayerOneCopy, camera1, 0); + + switch(gActiveScreenMode) { + case SCREEN_MODE_1P: + func_80028F70(); + break; + case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: + case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: + func_80029060(); + func_8001EE98(gPlayerTwoCopy, camera2, 1); + func_80029150(); + break; + case SCREEN_MODE_3P_4P_SPLITSCREEN: + func_80029158(); + func_8001EE98(gPlayerTwo, camera2, 1); + func_800291E8(); + func_8001EE98(gPlayerThree, camera3, 2); + func_800291F0(); + func_8001EE98(gPlayerFour, camera4, 3); + func_800291F8(); + break; + } + + func_8028F474(); + func_80059AC8(); + update_course_actors(); + CourseManager_TickActors(); + func_802966A0(); + func_8028FCBC(); +} + +void race_logic_loop(void) { + ClearMatrixPools(); + ClearObjectsMatrixPool(); + ClearEffectsMatrixPool(); gMatrixObjectCount = 0; gMatrixEffectCount = 0; + if (gIsGamePaused != 0) { func_80290B14(); } @@ -645,276 +803,94 @@ void race_logic_loop(void) { if (sNumVBlanks < 0) { sNumVBlanks = 1; } - func_802A4EF4(); - - switch (gActiveScreenMode) { - case SCREEN_MODE_1P: - gTickSpeed = 2; - staff_ghosts_loop(); - // Wait for all racers to load - if (gNetwork.enabled) { - network_all_players_loaded(); - } + func_802A4EF4(); - if (gIsGamePaused == 0) { - for (i = 0; i < gTickSpeed; i++) { - if (D_8015011E) { - gCourseTimer += COURSE_TIMER_ITER; - } - func_802909F0(); - evaluate_collision_for_players_and_actors(); - func_800382DC(); - func_8001EE98(gPlayerOneCopy, camera1, 0); - func_80028F70(); - func_8028F474(); - func_80059AC8(); - update_course_actors(); - CourseManager_TickActors(); - func_802966A0(); - func_8028FCBC(); - } - func_80022744(); - } - func_8005A070(); - sNumVBlanks = 0; - profiler_log_thread5_time(LEVEL_SCRIPT_EXECUTE); - D_8015F788 = 0; - render_player_one_1p_screen(); - if (!gEnableDebugMode) { - D_800DC514 = false; - } else { - if (D_800DC514) { + if (gModeSelection == TIME_TRIALS) { + staff_ghosts_loop(); + } - if ((gControllerOne->buttonPressed & R_TRIG) && (gControllerOne->button & A_BUTTON) && - (gControllerOne->button & B_BUTTON)) { - D_800DC514 = false; - } + // Wait for all racers to load + if (gNetwork.enabled) { + network_all_players_loaded(); + } - rotY = camera1->rot[1]; - gDebugPathCount = D_800DC5EC->pathCounter; - if (rotY < 0x2000) { - func_80057A50(40, 100, "SOUTH ", gDebugPathCount); - } else if (rotY < 0x6000) { - func_80057A50(40, 100, "EAST ", gDebugPathCount); - } else if (rotY < 0xA000) { - func_80057A50(40, 100, "NORTH ", gDebugPathCount); - } else if (rotY < 0xE000) { - func_80057A50(40, 100, "WEST ", gDebugPathCount); - } else { - func_80057A50(40, 100, "SOUTH ", gDebugPathCount); - } + if (gIsGamePaused == 0) { + for (size_t i = 0; i < gTickLogic; i++) { + process_game_tick(); + } + func_80022744(); + } + func_8005A070(); + profiler_log_thread5_time(LEVEL_SCRIPT_EXECUTE); + sNumVBlanks = 0; + gNumScreens = 0; + move_segment_table_to_dmem(); + init_rdp(); + if (D_800DC5B0 != 0) { + select_framebuffer(); + } - } else { - if ((gControllerOne->buttonPressed & L_TRIG) && (gControllerOne->button & A_BUTTON) && - (gControllerOne->button & B_BUTTON)) { - D_800DC514 = true; - } - } - } + switch(gActiveScreenMode) { + case SCREEN_MODE_1P: + render_screens(RENDER_SCREEN_MODE_1P_PLAYER_ONE, 0, 0); break; - - case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: - if (GetCourse() == GetDkJungle()) { - gTickSpeed = 3; - } else { - gTickSpeed = 2; - } - if (gIsGamePaused == 0) { - for (i = 0; i < gTickSpeed; i++) { - if (D_8015011E != 0) { - gCourseTimer += COURSE_TIMER_ITER; - } - func_802909F0(); - evaluate_collision_for_players_and_actors(); - func_800382DC(); - func_8001EE98(gPlayerOneCopy, camera1, 0); - func_80029060(); - func_8001EE98(gPlayerTwoCopy, camera2, 1); - func_80029150(); - func_8028F474(); - func_80059AC8(); - update_course_actors(); - func_802966A0(); - func_8028FCBC(); - } - func_80022744(); - } - func_8005A070(); - profiler_log_thread5_time(LEVEL_SCRIPT_EXECUTE); - sNumVBlanks = 0; - move_segment_table_to_dmem(); - init_rdp(); - if (D_800DC5B0 != 0) { - select_framebuffer(); - } - D_8015F788 = 0; + case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: if (gPlayerWinningIndex == 0) { - render_player_two_2p_screen_vertical(); - render_player_one_2p_screen_vertical(); + // In VS Mode the winning player's viewport takes over the whole screen. + // Rendering the winning player last places their screen above the other screens + render_screens(RENDER_SCREEN_MODE_2P_HORIZONTAL_PLAYER_TWO, 1, 1); + render_screens(RENDER_SCREEN_MODE_2P_HORIZONTAL_PLAYER_ONE, 0, 0); } else { - render_player_one_2p_screen_vertical(); - render_player_two_2p_screen_vertical(); + render_screens(RENDER_SCREEN_MODE_2P_HORIZONTAL_PLAYER_ONE, 0, 0); + render_screens(RENDER_SCREEN_MODE_2P_HORIZONTAL_PLAYER_TWO, 1, 1); } break; - - case SCREEN_MODE_2P_SPLITSCREEN_HORIZONTAL: - - if (GetCourse() == GetDkJungle()) { - gTickSpeed = 3; - } else { - gTickSpeed = 2; - } - - if (gIsGamePaused == 0) { - for (i = 0; i < gTickSpeed; i++) { - if (D_8015011E != 0) { - gCourseTimer += COURSE_TIMER_ITER; - } - func_802909F0(); - evaluate_collision_for_players_and_actors(); - func_800382DC(); - func_8001EE98(gPlayerOneCopy, camera1, 0); - func_80029060(); - func_8001EE98(gPlayerTwoCopy, camera2, 1); - func_80029150(); - func_8028F474(); - func_80059AC8(); - update_course_actors(); - func_802966A0(); - func_8028FCBC(); - } - func_80022744(); - } - profiler_log_thread5_time(LEVEL_SCRIPT_EXECUTE); - sNumVBlanks = (u16) 0; - func_8005A070(); - move_segment_table_to_dmem(); - init_rdp(); - if (D_800DC5B0 != 0) { - select_framebuffer(); - } - D_8015F788 = 0; + case SCREEN_MODE_2P_SPLITSCREEN_VERTICAL: if (gPlayerWinningIndex == 0) { - render_player_two_2p_screen_horizontal(); - render_player_one_2p_screen_horizontal(); + render_screens(RENDER_SCREEN_MODE_2P_VERTICAL_PLAYER_TWO, 1, 1); + render_screens(RENDER_SCREEN_MODE_2P_VERTICAL_PLAYER_ONE, 0, 0); } else { - render_player_one_2p_screen_horizontal(); - render_player_two_2p_screen_horizontal(); + render_screens(RENDER_SCREEN_MODE_2P_VERTICAL_PLAYER_ONE, 0, 0); + render_screens(RENDER_SCREEN_MODE_2P_VERTICAL_PLAYER_TWO, 1, 1); } - break; - case SCREEN_MODE_3P_4P_SPLITSCREEN: - if (gPlayerCountSelection1 == 3) { - switch (gCurrentCourseId) { - case COURSE_BOWSER_CASTLE: - case COURSE_MOO_MOO_FARM: - case COURSE_SKYSCRAPER: - case COURSE_DK_JUNGLE: - gTickSpeed = 3; - break; - default: - gTickSpeed = 2; - break; - } - } else { - // Four players - switch (gCurrentCourseId) { - case COURSE_BLOCK_FORT: - case COURSE_DOUBLE_DECK: - case COURSE_BIG_DONUT: - gTickSpeed = 2; - break; - case COURSE_DK_JUNGLE: - gTickSpeed = 4; - break; - default: - gTickSpeed = 3; - break; - } - } - if (gIsGamePaused == 0) { - for (i = 0; i < gTickSpeed; i++) { - if (D_8015011E != 0) { - gCourseTimer += COURSE_TIMER_ITER; - } - func_802909F0(); - evaluate_collision_for_players_and_actors(); - func_800382DC(); - func_8001EE98(gPlayerOneCopy, camera1, 0); - func_80029158(); - func_8001EE98(gPlayerTwo, camera2, 1); - func_800291E8(); - func_8001EE98(gPlayerThree, camera3, 2); - func_800291F0(); - func_8001EE98(gPlayerFour, camera4, 3); - func_800291F8(); - func_8028F474(); - func_80059AC8(); - update_course_actors(); - func_802966A0(); - func_8028FCBC(); - } - func_80022744(); - } - func_8005A070(); - sNumVBlanks = 0; - profiler_log_thread5_time(LEVEL_SCRIPT_EXECUTE); - move_segment_table_to_dmem(); - init_rdp(); - if (D_800DC5B0 != 0) { - select_framebuffer(); - } - D_8015F788 = 0; if (gPlayerWinningIndex == 0) { - render_player_two_3p_4p_screen(); - render_player_three_3p_4p_screen(); - render_player_four_3p_4p_screen(); - render_player_one_3p_4p_screen(); + render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_TWO, 1, 1); + render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_THREE, 2, 2); + render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_FOUR, 3, 3); + render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_ONE, 0, 0); } else if (gPlayerWinningIndex == 1) { - render_player_one_3p_4p_screen(); - render_player_three_3p_4p_screen(); - render_player_four_3p_4p_screen(); - render_player_two_3p_4p_screen(); + render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_ONE, 0, 0); + render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_THREE, 2, 2); + render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_FOUR, 3, 3); + render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_TWO, 1, 1); } else if (gPlayerWinningIndex == 2) { - render_player_one_3p_4p_screen(); - render_player_two_3p_4p_screen(); - render_player_four_3p_4p_screen(); - render_player_three_3p_4p_screen(); + + render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_ONE, 0, 0); + render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_TWO, 1, 1); + render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_FOUR, 3, 3); + render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_THREE, 2, 2); } else { - render_player_one_3p_4p_screen(); - render_player_two_3p_4p_screen(); - render_player_three_3p_4p_screen(); - render_player_four_3p_4p_screen(); + render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_ONE, 0, 0); + render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_TWO, 1, 1); + render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_THREE, 2, 2); + render_screens(RENDER_SCREEN_MODE_3P_4P_PLAYER_FOUR, 3, 3); } break; } - if (!gEnableDebugMode) { - gEnableResourceMeters = 0; - } else { - if (gEnableResourceMeters) { - resource_display(); - if ((!(gControllerOne->button & L_TRIG)) && (gControllerOne->button & R_TRIG) && - (gControllerOne->buttonPressed & B_BUTTON)) { - gEnableResourceMeters = 0; - } - } else { - if ((!(gControllerOne->button & L_TRIG)) && (gControllerOne->button & R_TRIG) && - (gControllerOne->buttonPressed & B_BUTTON)) { - gEnableResourceMeters = 1; - } - } - } + display_debug_info(); + func_802A4300(); func_800591B4(); func_80093E20(); #if DVDL display_dvdl(); #endif - // gDPFullSync(gDisplayListHead++); - // gSPEndDisplayList(gDisplayListHead++); + gDPFullSync(gDisplayListHead++); + gSPEndDisplayList(gDisplayListHead++); } /** @@ -1265,6 +1241,7 @@ void thread5_iteration(void) { } #endif + calculate_updaterate(); if (GfxDebuggerIsDebugging()) { Graphics_PushFrame(gGfxPool->gfxPool); return; @@ -1280,7 +1257,7 @@ void thread5_iteration(void) { read_controllers(); game_state_handler(); - call_render_hook(); + //call_render_hook(); end_master_display_list(); display_and_vsync(); |
