diff --git a/config/RSBE01_02/symbols.txt b/config/RSBE01_02/symbols.txt index 85281ca64a..98a777db96 100644 --- a/config/RSBE01_02/symbols.txt +++ b/config/RSBE01_02/symbols.txt @@ -2282,7 +2282,7 @@ fn_80017C38 = .text:0x80017C38; // type:function size:0x648 fn_80018280 = .text:0x80018280; // type:function size:0x24 fn_800182A4 = .text:0x800182A4; // type:function size:0x36C fn_80018610 = .text:0x80018610; // type:function size:0x168 -fn_80018778 = .text:0x80018778; // type:function size:0x66C +calc__8gfCameraFv = .text:0x80018778; // type:function size:0x66C setGX__8gfCameraFv = .text:0x80018DE4; // type:function size:0xE0 fn_80018EC4 = .text:0x80018EC4; // type:function size:0x5E8 fn_800194AC = .text:0x800194AC; // type:function size:0x26C @@ -4281,7 +4281,7 @@ fn_800A6668 = .text:0x800A6668; // type:function size:0x258 __ct__21cmMenuFixedControllerFv = .text:0x800A68C0; // type:function size:0x44 storeDefault__21cmMenuFixedControllerFv = .text:0x800A6904; // type:function size:0x3C init__21cmMenuFixedControllerFv = .text:0x800A6940; // type:function size:0x6C -fn_800A69AC = .text:0x800A69AC; // type:function size:0xCC +update__21cmMenuFixedControllerFf = .text:0x800A69AC; // type:function size:0xCC fn_800A6A78 = .text:0x800A6A78; // type:function size:0x1C fn_800A6A94 = .text:0x800A6A94; // type:function size:0x40 fn_800A6AD4 = .text:0x800A6AD4; // type:function size:0xA4 diff --git a/configure.py b/configure.py index ee8d66a9a2..790572a7aa 100755 --- a/configure.py +++ b/configure.py @@ -314,14 +314,14 @@ def MatchingFor(*versions): Object(NonMatching, "sora/gf/gf_task_scheduler.cpp"), Object(Matching, "sora/gf/gf_thread.cpp"), Object(Matching, "sora/gf/gf_shutdown_manager.cpp"), - Object(NonMatching, "sora/gf/gf_slow_manager.cpp"), + Object(Matching, "sora/gf/gf_slow_manager.cpp"), Object(Matching, "sora/gf/gf_system_callback.cpp"), Object(Matching, "sora/gf/gf_capture_util.cpp"), Object(Matching, "sora/gf/gf_monitor.cpp"), Object(Matching, "sora/gf/gf_resource_loader.cpp"), Object(NonMatching, "sora/mt/mt_vector_old.cpp"), Object(Matching, "sora/mt/mt_prng.cpp", extra_cflags=["-RTTI off"]), - Object(NonMatching, "sora/mt/mt_trig.cpp"), + Object(Matching, "sora/mt/mt_trig.cpp"), Object(Matching, "sora/mt/mt_prng_log.cpp"), Object(Matching, "sora/st/module.cpp"), Object(Matching, "sora/ut/ut_nw.cpp"), @@ -335,7 +335,7 @@ def MatchingFor(*versions): Object(Matching, "sora/mv/mv_THPAudioDecode.cpp"), Object(Matching, "sora/mv/mv_THPRead.cpp"), Object(Matching, "sora/cm/cm_controller_default.cpp", extra_cflags=["-RTTI off"]), - Object(NonMatching, "sora/cm/cm_controller_menu_fixed.cpp"), + Object(Matching, "sora/cm/cm_controller_menu_fixed.cpp"), Object(Matching, "sora/cm/cm_controller_melee_fixed.cpp"), Object(Matching, "sora/cm/cm_stage_param.cpp"), Object(NonMatching, "sora/ty/ty_fig_listmng.cpp"), diff --git a/include/lib/BrawlHeaders b/include/lib/BrawlHeaders index fd97ee40a4..29c4ff16ce 160000 --- a/include/lib/BrawlHeaders +++ b/include/lib/BrawlHeaders @@ -1 +1 @@ -Subproject commit fd97ee40a414ceb1322bbc1f9831cb6d2224a76a +Subproject commit 29c4ff16ce06241ea672ffd54e6415fbd02c0743 diff --git a/src/sora/cm/cm_controller_menu_fixed.cpp b/src/sora/cm/cm_controller_menu_fixed.cpp index e2d3f9c933..e847d55c39 100644 --- a/src/sora/cm/cm_controller_menu_fixed.cpp +++ b/src/sora/cm/cm_controller_menu_fixed.cpp @@ -34,19 +34,24 @@ void cmMenuFixedController::storeDefault() { unk8 = true; } -// NONMATCHING void cmMenuFixedController::init() { - m_cameraManager->m_cameras[0].unkCC = unkC; - m_cameraManager->m_cameras[0].unkFA.m_flag7 = true; - m_cameraManager->m_cameras[0].m_targetPos.m_x = unk10.m_x; - m_cameraManager->m_cameras[0].m_targetPos.m_y = unk10.m_y; - m_cameraManager->m_cameras[0].m_targetPos.m_z = unk10.m_z; - m_cameraManager->m_cameras[0].unkFA.m_flag1 = true; - m_cameraManager->m_cameras[0].unkD0 = unk1C; - m_cameraManager->m_cameras[0].m_rot.m_x = 0.0f; - m_cameraManager->m_cameras[0].m_rot.m_y = 0.0f; - m_cameraManager->m_cameras[0].m_rot.m_z = 0.0f; - m_cameraManager->m_cameras[0].unkFA.m_flag2 = true; + gfCamera* camera = &m_cameraManager->m_cameras[0]; + camera->unkCC = unkC; + camera->unkFA.m_mask |= 0x80; + camera->m_targetPos = unk10; + camera->unkFA.m_mask |= 0x2; + camera->unkD0 = unk1C; + *camera->m_rot.xy() = Vec2f(0.0f, 0.0f); + camera->m_rot.m_z = 0.0f; + camera->unkFA.m_mask |= 0x40; } -// TODO: cmMenuFixedController::update +void cmMenuFixedController::update(float) { + gfCamera* camera = &m_cameraManager->m_cameras[0]; + if (!unk8) { + storeDefault(); + } + init(); + camera->m_transformFlag.m_mask = 0xe1; + camera->calc(); +} diff --git a/src/sora/gf/gf_slow_manager.cpp b/src/sora/gf/gf_slow_manager.cpp index d9ada4f869..9344994e11 100644 --- a/src/sora/gf/gf_slow_manager.cpp +++ b/src/sora/gf/gf_slow_manager.cpp @@ -32,22 +32,22 @@ void gfSlowManager::update() { g_GameGlobal->updateGameFrame(); } -// NONMATCHING regswap -u32 gfSlowManager::requestSlow(u8 rate) { - u8 res = 0xFF; +gfSlowRequestId gfSlowManager::requestSlow(u8 rate) { + gfSlowRequestId res; + res.m_id = 0xFF; SlowRequest* reqs = s_gfSlowManager.m_reqs; SlowRequest* curr; for (u8 i = 0; i < NRequests; i++) { curr = &reqs[i]; if (curr->m_state == StateInactive) { - res = i; + res.m_id = i; s_needsUpdate = true; curr->m_state = StateActive; curr->m_slowRate = rate; break; } } - return static_cast(res) << 24; + return res; } bool gfSlowManager::removeRequest(const u8& idx) { diff --git a/src/sora/gf/gf_task_scheduler.cpp b/src/sora/gf/gf_task_scheduler.cpp index e91313b536..d8171e3d04 100644 --- a/src/sora/gf/gf_task_scheduler.cpp +++ b/src/sora/gf/gf_task_scheduler.cpp @@ -52,6 +52,19 @@ gfTaskScheduler* g_taskScheduler; } \ } while (false) +// Inline list accessors (needed for register allocation to match) +static inline gfTask* getProcessPrev(gfTask* task) { + return task->m_prev; +} + +static inline gfTask* getProcessNext(gfTask* task) { + return task->m_next; +} + +static inline gfTask* getRenderNext(gfTask* task) { + return task->m_0x18; +} + gfTaskScheduler* gfTaskScheduler::create() { return (g_taskScheduler = new (Heaps::SystemFW) gfTaskScheduler); } @@ -90,15 +103,13 @@ void gfTaskScheduler::updateStatusPre() { } } -// NONMATCHING regswaps +// NONMATCHING regswap: request loop counter should be r27, not r29 void gfTaskScheduler::process(bool p1) { + UnkTaskRequest* req; u32 count; - gfTask* r26; - gfTask* curr; - gfTask* r24; - UnkTaskRequest* r31; - gfTask** r30; + s32 k; s32 i; + gfTask* task; updateStatusPre(); unk0_1 = 1; // loop over ProcessTypes? @@ -106,14 +117,14 @@ void gfTaskScheduler::process(bool p1) { unk0_2 = i; // UBFIX: logic depends on shift overflow? if (!unk8 || !(1 << i)) { - r30 = unk14; // loop over task priority levels? - for (s32 j = 0; j < unk14Size; j++, r30++) { - curr = *r30; + gfTask** list = unk14; + for (s32 j = 0; j < unk14Size; j++, list++) { + gfTask* curr = *list; unk6 = j; while (curr) { - r24 = curr->m_prev; - gfTask* next = curr->m_next; + gfTask* prev = getProcessPrev(curr); + gfTask* next = getProcessNext(curr); unkC = curr; unk10 = next; if (p1) { @@ -122,12 +133,12 @@ void gfTaskScheduler::process(bool p1) { } } else { if (curr->m_alive && !curr->getFlag1()) { - curr->process(static_cast(i)); + curr->process(static_cast(i)); } } if (!curr->unk2C_b0) { - if (!r24) { - curr = *r30; + if (!prev) { + curr = *list; } else { curr = unk10; } @@ -145,16 +156,16 @@ void gfTaskScheduler::process(bool p1) { // Process priority change requests? count = m_numPendingPrioUpdates; if (count) { - r31 = m_pendingPrioUpdates; - for (i = 0; i < count; r31++, i++) { - r26 = getTaskById(r31->m_category, r31->m_taskId); - if (r26) { - if (!r26->unk2C_b0) { - r31->m_task->unk30 = r31->m_priority; + req = m_pendingPrioUpdates; + for (k = 0; k < count; req++, k++) { + task = getTaskById(req->m_category, req->m_taskId); + if (task) { + if (!task->unk2C_b0) { + req->m_task->unk30 = req->m_priority; } else { - unlinkProcessList(r26); - r26->unk30 = r31->m_priority; - TASKLIST_APPEND(unk14[r26->unk30], r26, m_prev, m_next); + unlinkProcessList(task); + task->unk30 = req->m_priority; + TASKLIST_APPEND(unk14[task->unk30], task, m_prev, m_next); } } } @@ -163,16 +174,14 @@ void gfTaskScheduler::process(bool p1) { unk0_1 = 0; } -// NONMATCHING regswaps void gfTaskScheduler::renderPre() { gfTask* next; - gfTask* r3; unk0_1 = 2; for (s32 i = 0; i < unkF8Size; i++) { - r3 = unkF8[i]; + gfTask* head = unkF8[i]; unk6 = i; - for (gfTask* task = r3; task; task = next) { - next = task->m_0x18; + for (gfTask* task = head; task; task = next) { + next = getRenderNext(task); if (task->m_alive && task->unk2C_b2) { task->renderPre(); } @@ -180,26 +189,24 @@ void gfTaskScheduler::renderPre() { } } -// NONMATCHING regswaps void gfTaskScheduler::render() { + gfTask* next; unk0_1 = 2; - gfTask* r31; - gfTask* r3; for (s32 i = 0; i < unkF8Size; i++) { - r3 = unkF8[i]; + gfTask* head = unkF8[i]; unk6 = i; - for (gfTask* task = r3; task; task = r31) { - r31 = task->m_0x18; + for (gfTask* task = head; task; task = next) { + next = getRenderNext(task); if (task->m_alive && task->unk2C_b2) { task->render(gfTask::Render_Opa); } } } for (s32 i = 0; i < unkF8Size; i++) { - r3 = unkF8[i]; + gfTask* head = unkF8[i]; unk6 = i; - for (gfTask* task = r3; task; task = r31) { - r31 = task->m_0x18; + for (gfTask* task = head; task; task = next) { + next = getRenderNext(task); if (task->m_alive && task->unk2C_b2) { task->render(gfTask::Render_Xlu); } @@ -208,7 +215,6 @@ void gfTaskScheduler::render() { unk0_1 = 0; } -// NONMATCHING regswaps void gfTaskScheduler::updateStatus() { unk0_1 = 4; do { @@ -216,7 +222,7 @@ void gfTaskScheduler::updateStatus() { unk2_b7 = false; for (s32 i = 0; i < unk14Size; i++) { for (gfTask* curr = unk14[i]; curr; curr = next) { - next = curr->m_next; + next = getProcessNext(curr); if (curr->m_alive && curr->getStatus() == 2) { curr->setStatus(1); } @@ -363,13 +369,12 @@ void gfTaskScheduler::setPauseCategory(gfTask::Category ctgry, bool isPaused) { } } -// NONMATCHING regswaps, instruction order, dead store void gfTaskScheduler::changeTaskPriorityRequest(u32 id, u8 priority) { gfTask* task = getTask(id); if (task) { UnkTaskRequest x(false); - x.m_category = task->m_taskCategory; x.m_taskId = task->m_taskId; + x.m_category = task->m_taskCategory; x.m_priority = priority; m_pendingPrioUpdates[m_numPendingPrioUpdates] = x; m_numPendingPrioUpdates++; diff --git a/src/sora/mt/mt_trig.cpp b/src/sora/mt/mt_trig.cpp index fc89211193..4fe2af1ef8 100644 --- a/src/sora/mt/mt_trig.cpp +++ b/src/sora/mt/mt_trig.cpp @@ -39,26 +39,37 @@ float mtCosf(float angle) { return mtSinf(angle + HALF_PI); } -// NONMATCHING regswaps - should simply interleave calls to mtCosf and mtSinf -void mtSinCosf(float rad, float* sinOut, float* cosOut) { - s32 s0 = RAD_TO_FIXED_PT * rad; - s32 c0 = RAD_TO_FIXED_PT * (rad + HALF_PI); +// Same as taylor(), but with x^2 precomputed by the caller +static inline float taylorSq(float x, float xSq) { + const float C1 = 1.0f; // 1 + const float C2 = -0.16666657f; // -1/3! + const float C3 = 0.0083330255f; // 1/5! + const float C4 = -0.00019807414f; // -1/7! + const float C5 = 0.000002601887f; // 1/9! + return x * (C1 + (xSq * (C2 + (xSq * (C3 + (xSq * (C4 + (C5 * xSq)))))))); +} - s32 s1 = reduceRange(s0); - s32 c1 = reduceRange(c0); +void mtSinCosf(float rad, float* sinOut, float* cosOut) { + float cosX, sinXSq, cosXSq, sinX; // Weird ordering but only thing that led to byte-match - s32 c2 = fitToRange(s1); - s32 s2 = fitToRange(c1); + s32 sinFixed = RAD_TO_FIXED_PT * rad; + s32 cosFixed = RAD_TO_FIXED_PT * (rad + HALF_PI); - float s3 = s2; - float c3 = c2; + s32 sinTheta = sinFixed + 0x400000; + sinTheta &= 0x00FFFFFF; + s32 cosTheta = cosFixed + 0x400000; + cosTheta &= 0x00FFFFFF; - float c4 = FIXED_PT_TO_RAD * c3; - float s4 = FIXED_PT_TO_RAD * s3; + if (sinTheta > 0x800000) + sinTheta = 0x1000000 - sinTheta; + if (cosTheta > 0x800000) + cosTheta = 0x1000000 - cosTheta; - float s5 = taylor(s4); - float c5 = taylor(c4); + sinX = FIXED_PT_TO_RAD * (sinTheta - 0x400000); + cosX = FIXED_PT_TO_RAD * (cosTheta - 0x400000); + sinXSq = sinX * sinX; + cosXSq = cosX * cosX; - *sinOut = s5; - *cosOut = c5; + *sinOut = taylorSq(sinX, sinXSq); + *cosOut = taylorSq(cosX, cosXSq); }