Fixed stutter caused by saving by adding a sleep in the saving loop, fixed bug with timers not resuming due to a negative remaining duration

This commit is contained in:
Mr-Wiseguy 2024-04-02 22:16:31 -04:00
parent fcc4eb6351
commit 407b6e547c
4 changed files with 95 additions and 2 deletions

View File

@ -6,8 +6,12 @@
#define osRecvMesg osRecvMesg_recomp
#define osSendMesg osSendMesg_recomp
#define osViGetCurrentFramebuffer osViGetCurrentFramebuffer_recomp
#define osFlashWriteArray osFlashWriteArray_recomp
#define osFlashWriteBuffer osFlashWriteBuffer_recomp
#define osWritebackDCache osWritebackDCache_recomp
#define sinf __sinf_recomp
#define cosf __cosf_recomp
#define bzero bzero_recomp
#define gRandFloat sRandFloat
#include "global.h"
#include "rt64_extended_gbi.h"

86
patches/save_patches.c Normal file
View File

@ -0,0 +1,86 @@
#include "patches.h"
#include "sys_flashrom.h"
#include "PR/os_internal_flash.h"
#include "fault.h"
extern OSMesgQueue sFlashromMesgQueue;
s32 SysFlashrom_IsInit(void);
void Sleep_Msec(u32 ms);
// @recomp Patched to not wait a hardcoded amount of time for the save to complete.
void Sram_UpdateWriteToFlashDefault(SramContext* sramCtx) {
if (sramCtx->status == 2) {
if (SysFlashrom_IsBusy() != 0) { // if task running
if (SysFlashrom_AwaitResult() == 0) { // wait for task done
// task success
sramCtx->status = 4;
} else {
// task failure
sramCtx->status = 4;
}
}
} else if (sramCtx->status == 4) {
// @recomp Patched to check status instead of using a hardcoded wait.
recomp_printf("Status 4\n");
sramCtx->status = 0;
}
}
// @recomp Patched to not wait a hardcoded amount of time for the save to complete.
void Sram_UpdateWriteToFlashOwlSave(SramContext* sramCtx) {
if (sramCtx->status == 7) {
if (SysFlashrom_IsBusy() != 0) { // Is task running
if (SysFlashrom_AwaitResult() == 0) { // Wait for task done
SysFlashrom_WriteDataAsync(sramCtx->saveBuf, sramCtx->curPage + 0x80, sramCtx->numPages);
sramCtx->status = 8;
} else {
SysFlashrom_WriteDataAsync(sramCtx->saveBuf, sramCtx->curPage + 0x80, sramCtx->numPages);
sramCtx->status = 8;
}
}
} else if (sramCtx->status == 8) {
if (SysFlashrom_IsBusy() != 0) { // Is task running
if (SysFlashrom_AwaitResult() == 0) { // Wait for task done
sramCtx->status = 4;
} else {
sramCtx->status = 4;
}
}
} else if (sramCtx->status == 4) {
// @recomp Patched to check status instead of using a hardcoded wait.
sramCtx->status = 0;
bzero(sramCtx->saveBuf, SAVE_BUFFER_SIZE);
gSaveContext.save.isOwlSave = false;
gSaveContext.save.saveInfo.checksum = 0;
// flash read to buffer then copy to save context
SysFlashrom_ReadData(sramCtx->saveBuf, sramCtx->curPage, sramCtx->numPages);
Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, offsetof(SaveContext, fileNum));
}
}
// @recomp Patched to add a pause so that other threads can execute in the meantime.
s32 SysFlashrom_ExecWrite(void* addr, u32 pageNum, u32 pageCount) {
OSIoMesg msg;
s32 result;
u32 i;
if (!SysFlashrom_IsInit()) {
return -1;
}
// Ensure the page is always aligned to a sector boundary.
if ((pageNum % FLASH_BLOCK_SIZE) != 0) {
Fault_AddHungupAndCrash("../sys_flashrom.c", 275);
}
osWritebackDCache(addr, pageCount * FLASH_BLOCK_SIZE);
for (i = 0; i < pageCount; i++) {
// @recomp Pause shortly to allow other threads to work.
Sleep_Msec(5);
osFlashWriteBuffer(&msg, OS_MESG_PRI_NORMAL, (u8*)addr + i * FLASH_BLOCK_SIZE, &sFlashromMesgQueue);
osRecvMesg(&sFlashromMesgQueue, NULL, OS_MESG_BLOCK);
result = osFlashWriteArray(i + pageNum);
if (result != 0) {
return result;
}
}
return 0;
}

View File

@ -27,3 +27,7 @@ recomp_set_current_frame_poll_id = 0x8F00004C;
recomp_time_us = 0x8F000050;
recomp_measure_latency = 0x8F000054;
osViGetCurrentFramebuffer_recomp = 0x8F000058;
bzero_recomp = 0x8F00005C;
osFlashWriteArray_recomp = 0x8F000060;
osFlashWriteBuffer_recomp = 0x8F000064;
osWritebackDCache_recomp = 0x8F000068;

View File

@ -112,10 +112,9 @@ void timer_thread(RDRAM_ARG1) {
// Determine how long to wait to reach the timer's timestamp
auto wait_duration = ticks_to_timepoint(cur_timer->timestamp) - std::chrono::system_clock::now();
auto wait_us = std::chrono::duration_cast<std::chrono::microseconds>(wait_duration);
// Wait for either the duration to complete or a new action to come through
if (timer_context.action_queue.wait_dequeue_timed(cur_action, wait_duration)) {
if (wait_duration.count() >= 0 && timer_context.action_queue.wait_dequeue_timed(cur_action, wait_duration)) {
// Timer was interrupted by a new action
// Add the current timer back to the queue (done first in case the action is to remove this timer)
active_timers.insert(cur_timer_);