From e59bfd1a9cdf977146aa9880586d6ce1025874f2 Mon Sep 17 00:00:00 2001 From: MelonSpeedruns Date: Tue, 28 Apr 2026 15:01:57 -0400 Subject: [PATCH 01/18] potential fix for freecam flashing --- src/d/d_camera.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/d/d_camera.cpp b/src/d/d_camera.cpp index 471c93bb19..ad9ff110ce 100644 --- a/src/d/d_camera.cpp +++ b/src/d/d_camera.cpp @@ -3089,10 +3089,6 @@ bool dCamera_c::bumpCheck(u32 i_flags) { field_0x968 *= mMonitor.field_0xc / 5.0f; } - #if TARGET_PC - if (!dusk::getSettings().game.freeCamera || !mCamParam.mManualMode) { - #endif - f32 tmp = field_0x96c * (mIsWolf == 1 ? 30.0f : 30.0f); center += vec3.norm() * (tmp * globe.V().Sin()); cSGlobe globe2(vec2 - center); @@ -3106,10 +3102,6 @@ bool dCamera_c::bumpCheck(u32 i_flags) { vec = lin_chk1.GetCross(); } - #if TARGET_PC - } - #endif - #if DEBUG if (mCamSetup.CheckFlag(0x8000)) { dDbVw_Report(20, 235, " U"); From 79344edf0d483d34e27bf35810d4c65e276012e6 Mon Sep 17 00:00:00 2001 From: MelonSpeedruns Date: Tue, 28 Apr 2026 15:19:32 -0400 Subject: [PATCH 02/18] maybe fix number 2 --- src/d/d_camera.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/d/d_camera.cpp b/src/d/d_camera.cpp index ad9ff110ce..2386c0e3b5 100644 --- a/src/d/d_camera.cpp +++ b/src/d/d_camera.cpp @@ -7488,7 +7488,9 @@ bool dCamera_c::freeCamera() { mCamParam.freeYAngle += camMovement.y * magnitude * dusk::getSettings().game.freeCameraSensitivity * 4.0f; } - if (!mCamParam.mManualMode) { + fopAc_ac_c* player = dComIfGp_getPlayer(0); + + if (!mCamParam.mManualMode || player == nullptr) { return false; } @@ -7501,7 +7503,7 @@ bool dCamera_c::freeCamera() { f32 currentLerp = (mCamParam.freeYAngle - minYAngle) / (maxAngle - minYAngle); mViewCache.mDirection.mRadius = std::lerp(200.0f, 1000.0f, currentLerp); - cXyz finalCenter = mpPlayerActor->current.pos; + cXyz finalCenter = player->current.pos; finalCenter.y += mIsWolf ? 90.0f : 100.0f; mViewCache.mCenter = finalCenter; From 8e0f0e878e00b4fa2baa8be1181daf7f273dfa79 Mon Sep 17 00:00:00 2001 From: MelonSpeedruns Date: Tue, 28 Apr 2026 16:13:49 -0400 Subject: [PATCH 03/18] optimize some code --- src/d/d_camera.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/d/d_camera.cpp b/src/d/d_camera.cpp index 2386c0e3b5..3aa707b87b 100644 --- a/src/d/d_camera.cpp +++ b/src/d/d_camera.cpp @@ -7476,12 +7476,7 @@ bool dCamera_c::freeCamera() { f32 magnitude = sqrt(mPadInfo.mCStick.mLastPosX * mPadInfo.mCStick.mLastPosX + mPadInfo.mCStick.mLastPosY * mPadInfo.mCStick.mLastPosY); if (mPadInfo.mCStick.mLastPosX != 0 || mPadInfo.mCStick.mLastPosY != 0) { - if (!mCamParam.mManualMode) { - mCamParam.mManualMode = 1; - mCamParam.freeXAngle = mViewCache.mDirection.mAzimuth.Degree(); - mCamParam.freeYAngle = mViewCache.mDirection.mInclination.Degree(); - } - + mCamParam.mManualMode = 1; camMovement = camMovement.normalize(); camMovement.y *= dusk::getSettings().game.invertCameraYAxis ? 1.0f : -1.0f; mCamParam.freeXAngle += camMovement.x * magnitude * dusk::getSettings().game.freeCameraSensitivity * 4.0f; @@ -7489,7 +7484,6 @@ bool dCamera_c::freeCamera() { } fopAc_ac_c* player = dComIfGp_getPlayer(0); - if (!mCamParam.mManualMode || player == nullptr) { return false; } From 9a7b62cbc62659dde0bf540bfdc8e4474e52210e Mon Sep 17 00:00:00 2001 From: MelonSpeedruns Date: Tue, 28 Apr 2026 16:25:42 -0400 Subject: [PATCH 04/18] disable freecam if an event cam happens --- src/d/d_camera.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/d/d_camera.cpp b/src/d/d_camera.cpp index 3aa707b87b..4d6a7b8582 100644 --- a/src/d/d_camera.cpp +++ b/src/d/d_camera.cpp @@ -10049,6 +10049,10 @@ bool dCamera_c::oneSideCamera(s32 param_1) { } bool dCamera_c::eventCamera(s32 param_0) { + #if TARGET_PC + mCamParam.mManualMode = 0; + #endif + char sp90[12]; UNUSED(param_0); From 4462c0ef6919d49cca66bdf1933e7b0b1a6aaa39 Mon Sep 17 00:00:00 2001 From: MelonSpeedruns Date: Wed, 29 Apr 2026 14:28:18 -0400 Subject: [PATCH 05/18] more optimizations to freecam code --- src/d/d_camera.cpp | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/src/d/d_camera.cpp b/src/d/d_camera.cpp index 4d6a7b8582..81cb452dc1 100644 --- a/src/d/d_camera.cpp +++ b/src/d/d_camera.cpp @@ -3512,12 +3512,6 @@ void dCamera_c::checkGroundInfo() { } bool dCamera_c::chaseCamera(s32 param_0) { -#if TARGET_PC - if (freeCamera()) { - return 1; - } -#endif - static f32 JumpCushion = 0.9f; f32 charge_latitude = mCamSetup.ChargeLatitude(); int charge_timer = mCamSetup.ChargeTimer(); @@ -4636,6 +4630,9 @@ bool dCamera_c::chaseCamera(s32 param_0) { if (chase->field_0x1c != 0) { chase->field_0x1c--; } + + freeCamera(); + return true; } @@ -7469,8 +7466,10 @@ bool dCamera_c::freeCamera() { return false; } - mCamParam.freeXAngle = mViewCache.mDirection.mAzimuth.Degree(); - mCamParam.freeYAngle = mViewCache.mDirection.mInclination.Degree(); + if (!mCamParam.mManualMode) { + mCamParam.freeXAngle = mViewCache.mDirection.mAzimuth.Degree(); + mCamParam.freeYAngle = mViewCache.mDirection.mInclination.Degree(); + } cXyz camMovement = {mPadInfo.mCStick.mLastPosX, mPadInfo.mCStick.mLastPosY, 0.0f}; f32 magnitude = sqrt(mPadInfo.mCStick.mLastPosX * mPadInfo.mCStick.mLastPosX + mPadInfo.mCStick.mLastPosY * mPadInfo.mCStick.mLastPosY); @@ -7488,24 +7487,16 @@ bool dCamera_c::freeCamera() { return false; } - f32 minYAngle = -10.0f; + f32 minYAngle = -30.0f; f32 maxAngle = 50.0f; mCamParam.freeYAngle = std::clamp(mCamParam.freeYAngle, minYAngle, maxAngle); mViewCache.mDirection.mAzimuth = cSAngle(mCamParam.freeXAngle); mViewCache.mDirection.mInclination = cSAngle(mCamParam.freeYAngle); - f32 currentLerp = (mCamParam.freeYAngle - minYAngle) / (maxAngle - minYAngle); - mViewCache.mDirection.mRadius = std::lerp(200.0f, 1000.0f, currentLerp); - cXyz finalCenter = player->current.pos; - finalCenter.y += mIsWolf ? 90.0f : 100.0f; - mViewCache.mCenter = finalCenter; - - cXyz finalEye = finalCenter + mViewCache.mDirection.Xyz(); + cXyz finalEye = mViewCache.mCenter + mViewCache.mDirection.Xyz(); mViewCache.mEye = finalEye; - mViewCache.mFovy = 60.0f; - return true; } #endif From b8a83c6f594b715639a76c8d5fb78ecabf6a55d0 Mon Sep 17 00:00:00 2001 From: MelonSpeedruns Date: Wed, 29 Apr 2026 14:37:32 -0400 Subject: [PATCH 06/18] disable freecam if not chasecamera --- src/d/d_camera.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/d/d_camera.cpp b/src/d/d_camera.cpp index 81cb452dc1..7b10f6883d 100644 --- a/src/d/d_camera.cpp +++ b/src/d/d_camera.cpp @@ -1177,6 +1177,12 @@ bool dCamera_c::Run() { } else { sp0F = (this->*engine_tbl[mCamParam.Algorythmn(mCamStyle)])(mCamStyle); + #if TARGET_PC + if (mCamParam.Algorythmn(mCamStyle) != 1) { + mCamParam.mManualMode = 0; + } + #endif + field_0x170++; field_0x160++; mCurCamStyleTimer++; @@ -4631,7 +4637,9 @@ bool dCamera_c::chaseCamera(s32 param_0) { chase->field_0x1c--; } + #if TARGET_PC freeCamera(); + #endif return true; } @@ -7478,8 +7486,8 @@ bool dCamera_c::freeCamera() { mCamParam.mManualMode = 1; camMovement = camMovement.normalize(); camMovement.y *= dusk::getSettings().game.invertCameraYAxis ? 1.0f : -1.0f; - mCamParam.freeXAngle += camMovement.x * magnitude * dusk::getSettings().game.freeCameraSensitivity * 4.0f; - mCamParam.freeYAngle += camMovement.y * magnitude * dusk::getSettings().game.freeCameraSensitivity * 4.0f; + mCamParam.freeXAngle += camMovement.x * magnitude * dusk::getSettings().game.freeCameraSensitivity * 5.0f; + mCamParam.freeYAngle += camMovement.y * magnitude * dusk::getSettings().game.freeCameraSensitivity * 5.0f; } fopAc_ac_c* player = dComIfGp_getPlayer(0); @@ -10040,10 +10048,6 @@ bool dCamera_c::oneSideCamera(s32 param_1) { } bool dCamera_c::eventCamera(s32 param_0) { - #if TARGET_PC - mCamParam.mManualMode = 0; - #endif - char sp90[12]; UNUSED(param_0); From ee4c84f39b1d81aa5c513ae1161376df0e84656a Mon Sep 17 00:00:00 2001 From: MelonSpeedruns Date: Wed, 29 Apr 2026 15:21:48 -0400 Subject: [PATCH 07/18] Fix slight spazz when changing cam type --- src/d/d_camera.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/d/d_camera.cpp b/src/d/d_camera.cpp index 7b10f6883d..a9c54512e3 100644 --- a/src/d/d_camera.cpp +++ b/src/d/d_camera.cpp @@ -4199,6 +4199,11 @@ bool dCamera_c::chaseCamera(s32 param_0) { chase->field_0x8 -= chase->field_0xc; chase->field_0x8c = 0; chase->field_0x90 = false; + + #if TARGET_PC + freeCamera(); + #endif + return true; } From f147dcac0c8da26e137a8319e727c67b369cbcae Mon Sep 17 00:00:00 2001 From: MelonSpeedruns Date: Wed, 29 Apr 2026 15:29:00 -0400 Subject: [PATCH 08/18] Fix camera while crawling & disable freecam properly when not chasecam --- src/d/d_camera.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/d/d_camera.cpp b/src/d/d_camera.cpp index a9c54512e3..09ed30d9f7 100644 --- a/src/d/d_camera.cpp +++ b/src/d/d_camera.cpp @@ -1175,14 +1175,14 @@ bool dCamera_c::Run() { clrFlag(0x200000); } } else { - sp0F = (this->*engine_tbl[mCamParam.Algorythmn(mCamStyle)])(mCamStyle); - #if TARGET_PC if (mCamParam.Algorythmn(mCamStyle) != 1) { mCamParam.mManualMode = 0; } #endif + sp0F = (this->*engine_tbl[mCamParam.Algorythmn(mCamStyle)])(mCamStyle); + field_0x170++; field_0x160++; mCurCamStyleTimer++; @@ -7474,7 +7474,8 @@ bool dCamera_c::test2Camera(s32 param_0) { #if TARGET_PC bool dCamera_c::freeCamera() { - if (!dusk::getSettings().game.freeCamera) { + if (!dusk::getSettings().game.freeCamera || mCamStyle == 70) + { mCamParam.mManualMode = 0; return false; } From 5899b2157a83f0eecf6d8a26bea3c610864e6b99 Mon Sep 17 00:00:00 2001 From: MelonSpeedruns Date: Thu, 30 Apr 2026 09:29:42 -0400 Subject: [PATCH 09/18] fix bow aiming in first person --- src/d/d_camera.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/d/d_camera.cpp b/src/d/d_camera.cpp index 471c93bb19..497d349e46 100644 --- a/src/d/d_camera.cpp +++ b/src/d/d_camera.cpp @@ -7091,10 +7091,12 @@ bool dCamera_c::subjectCamera(s32 param_0) { cXyz sp1E0(val0, val2, val1); #if TARGET_PC - f32 aspect = mDoGph_gInf_c::getAspect(); - f32 baseAspect = FB_WIDTH / FB_HEIGHT; - if (aspect > baseAspect) { - sp1E0.z += (aspect - baseAspect) * 4; + if (sp13) { + f32 aspect = mDoGph_gInf_c::getAspect(); + f32 baseAspect = FB_WIDTH / FB_HEIGHT; + if (aspect > baseAspect) { + sp1E0.z += (aspect - baseAspect) * 4; + } } #endif From b0e9033736529acf445665d99634f8f4ac4597d8 Mon Sep 17 00:00:00 2001 From: MelonSpeedruns Date: Thu, 30 Apr 2026 10:55:53 -0400 Subject: [PATCH 10/18] Widescreen Field Map --- include/d/d_menu_fmap2D.h | 8 ++++++++ src/d/d_menu_fmap2D.cpp | 30 +++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/include/d/d_menu_fmap2D.h b/include/d/d_menu_fmap2D.h index 9b237f2771..d0152f0229 100644 --- a/include/d/d_menu_fmap2D.h +++ b/include/d/d_menu_fmap2D.h @@ -81,6 +81,10 @@ public: void calcDrawPriority(); void setArrowPosAxis(f32, f32); + #if TARGET_PC + void fMapBackWide(); + #endif + virtual void draw(); virtual ~dMenu_Fmap2DBack_c(); @@ -330,6 +334,10 @@ public: void setHIO(bool); bool isWarpAccept(); + #if TARGET_PC + void fMapTopWide(); + #endif + virtual void draw(); virtual ~dMenu_Fmap2DTop_c(); diff --git a/src/d/d_menu_fmap2D.cpp b/src/d/d_menu_fmap2D.cpp index 8692156daf..f01ef2a10d 100644 --- a/src/d/d_menu_fmap2D.cpp +++ b/src/d/d_menu_fmap2D.cpp @@ -20,6 +20,15 @@ #include "dusk/frame_interpolation.h" #include +#if TARGET_PC +void dMenu_Fmap2DBack_c::fMapBackWide() { + mpBaseScreen->scale(mDoGph_gInf_c::hudAspectScaleUp, 1.0f); + mpBaseScreen->translate(mDoGph_gInf_c::getSafeMinXF(), 0.0f); + mpBackScreen->scale(mDoGph_gInf_c::hudAspectScaleUp, 1.0f); + mpBackScreen->translate(mDoGph_gInf_c::getSafeMinXF(), 0.0f); +} +#endif + dMenu_Fmap2DBack_c::dMenu_Fmap2DBack_c() { dMeter2Info_setMapDrugFlag(0); @@ -267,6 +276,10 @@ dMenu_Fmap2DBack_c::~dMenu_Fmap2DBack_c() { } void dMenu_Fmap2DBack_c::draw() { + #if TARGET_PC + fMapBackWide(); + #endif + calcBlink(); J2DGrafContext* grafPort = dComIfGp_getCurrentGrafPort(); @@ -1199,7 +1212,7 @@ f32 dMenu_Fmap2DBack_c::getMapScissorAreaSizeX() { } f32 dMenu_Fmap2DBack_c::getMapScissorAreaSizeRealX() { -#if PLATFORM_GCN && !TARGET_PC +#if PLATFORM_GCN return getMapScissorAreaSizeX(); #else return getMapScissorAreaSizeX() * mDoGph_gInf_c::getScale(); @@ -2179,6 +2192,17 @@ void dMenu_Fmap2DBack_c::setArrowPosAxis(f32 i_posX, f32 i_posZ) { control_ypos = 0.0f; } +#if TARGET_PC +void dMenu_Fmap2DTop_c::fMapTopWide() { + mpTitleScreen->search(MULTI_CHAR('spot0_n'))->scale(mDoGph_gInf_c::hudAspectScaleUp, 1.0f); + mpTitleScreen->search(MULTI_CHAR('spot2_n'))->scale(mDoGph_gInf_c::hudAspectScaleUp, 1.0f); + mpTitleScreen->search(MULTI_CHAR('name_n'))->translate(mDoGph_gInf_c::ScaleHUDXLeft(-243.0f), -169.0f); + mpTitleScreen->search(MULTI_CHAR('sub_n_n'))->translate(mDoGph_gInf_c::ScaleHUDXLeft(-80.0f), -154.0f); + mpTitleScreen->search(MULTI_CHAR('btn_i_n'))->translate(mDoGph_gInf_c::ScaleHUDXLeft(-241.0f), 177.0f); + mpTitleScreen->search(MULTI_CHAR('cont_n'))->translate(mDoGph_gInf_c::ScaleHUDXRight(515.0f), 83.0f); +} +#endif + dMenu_Fmap2DTop_c::dMenu_Fmap2DTop_c(JKRExpHeap* i_heap, STControl* i_stick) { mpHeap = i_heap; mTransX = 0.0f; @@ -2572,6 +2596,10 @@ void dMenu_Fmap2DTop_c::setAllAlphaRate(f32 i_rate, bool i_init) { } void dMenu_Fmap2DTop_c::draw() { + #if TARGET_PC + fMapTopWide(); + #endif + u32 scissor_left, scissor_top, scissor_width, scissor_height; J2DOrthoGraph* ctx = static_cast(dComIfGp_getCurrentGrafPort()); ctx->setup2D(); From e3ce1f01c91b0b23e40258eecdf8be546fc8afd7 Mon Sep 17 00:00:00 2001 From: MelonSpeedruns Date: Thu, 30 Apr 2026 14:38:24 -0400 Subject: [PATCH 11/18] Widescreen Dungeon Map --- include/d/d_menu_dmap.h | 4 ++++ src/d/d_menu_dmap.cpp | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/include/d/d_menu_dmap.h b/include/d/d_menu_dmap.h index e50c533654..81baea1446 100644 --- a/include/d/d_menu_dmap.h +++ b/include/d/d_menu_dmap.h @@ -91,6 +91,10 @@ public: void calcCursor(); void drawCursor(); + #if TARGET_PC + void dMapBgWide(); + #endif + void setDPDFloorSelCurPos(s8 i_pos) { field_0xdd6 = i_pos; } f32 getMapWidth() { return mMapWidth; } diff --git a/src/d/d_menu_dmap.cpp b/src/d/d_menu_dmap.cpp index bb557efdac..8ef7fadd4b 100644 --- a/src/d/d_menu_dmap.cpp +++ b/src/d/d_menu_dmap.cpp @@ -856,7 +856,46 @@ void dMenu_DmapBg_c::decGoldFrameAlphaRate() { setGoldFrameAlphaRate(rate); } +void dMenu_DmapBg_c::dMapBgWide() { + // Scale Base HUD + mBaseScreen->scale(mDoGph_gInf_c::hudAspectScaleUp, 1.0f); + mBaseScreen->translate(mDoGph_gInf_c::getSafeMinXF(), 0.0f); + + // Boss Key, Compass & Map icons + mBaseScreen->search(MULTI_CHAR('key_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mBaseScreen->search(MULTI_CHAR('con_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mBaseScreen->search(MULTI_CHAR('map_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // Text Header + mBaseScreen->search(MULTI_CHAR('t_t00'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mBaseScreen->search(MULTI_CHAR('f_t_00'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // C Button + mBaseScreen->search(MULTI_CHAR('c_btn2'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // Scale Buttons HUD + mButtonScreen->scale(mDoGph_gInf_c::hudAspectScaleUp, 1.0f); + mButtonScreen->translate(mDoGph_gInf_c::getSafeMinXF(), 0.0f); + + // Buttons + mButtonScreen->search(MULTI_CHAR('cont_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // C Button + mButtonScreen->search(MULTI_CHAR('c_btn'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mButtonScreen->search(MULTI_CHAR('c_text_s'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mButtonScreen->search(MULTI_CHAR('c_text'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mButtonScreen->search(MULTI_CHAR('f_text_s'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + mButtonScreen->search(MULTI_CHAR('f_text'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); + + // Decorations + mButtonScreen->search(MULTI_CHAR('kazari_n'))->scale(mDoGph_gInf_c::hudAspectScaleDown, 1.0f); +} + void dMenu_DmapBg_c::draw() { + #if TARGET_PC + dMapBgWide(); + #endif + u32 scissor_left; u32 scissor_top; u32 scissor_width; From a4752154f7c7253eade3a5c0cf1ed95d2e2735e3 Mon Sep 17 00:00:00 2001 From: PJB3005 Date: Fri, 1 May 2026 08:50:42 +0200 Subject: [PATCH 12/18] Nicely plumb OSReport error/warning/etc through Aurora's logger This makes a new implementation in the dusk src folder, and makes the existing file containing these functions not compiled anymore. A ton of dead code is now gone. --- files.cmake | 3 +- src/dusk/OSReport.cpp | 91 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 src/dusk/OSReport.cpp diff --git a/files.cmake b/files.cmake index f91756a9d5..6cec4672fb 100644 --- a/files.cmake +++ b/files.cmake @@ -1,7 +1,7 @@ set(DOLZEL_FILES src/m_Do/m_Do_main.cpp - src/m_Do/m_Do_printf.cpp + #src/m_Do/m_Do_printf.cpp src/m_Do/m_Do_audio.cpp src/m_Do/m_Do_controller_pad.cpp #src/m_Do/m_Re_controller_pad.cpp @@ -1467,6 +1467,7 @@ set(DUSK_FILES src/dusk/livesplit.cpp src/dusk/offset_ptr.cpp src/dusk/OSContext.cpp + src/dusk/OSReport.cpp src/dusk/OSThread.cpp src/dusk/OSMutex.cpp src/dusk/discord_presence.cpp diff --git a/src/dusk/OSReport.cpp b/src/dusk/OSReport.cpp new file mode 100644 index 0000000000..b89a708d78 --- /dev/null +++ b/src/dusk/OSReport.cpp @@ -0,0 +1,91 @@ +#include "aurora/lib/logging.hpp" +#include "os_report.h" + +aurora::Module Log("dusk::osReport"); + +bool dusk::OSReportReallyForceEnable = false; + +u8 __OSReport_disable; + +void OSReportDisable() { + __OSReport_disable = true; +} + +void OSReportEnable() { + __OSReport_disable = false; +} + +static bool checkEnabled() { + return !__OSReport_disable || dusk::OSReportReallyForceEnable; +} + +static std::string FormatToString(const char* msg, va_list list) { + int ret = vsnprintf(nullptr, 0, msg, list); + std::string buf(ret, '\0'); + vsnprintf(buf.data(), buf.size(), msg, list); + buf.pop_back(); + return buf; +} + +void OSReport_Error(const char* fmt, ...) { + if (!checkEnabled()) { + return; + } + + va_list args; + va_start(args, fmt); + const auto str = FormatToString(fmt, args); + va_end(args); + + Log.error("{}", str); +} + +void OSReport_FatalError(const char* fmt, ...) { + if (!checkEnabled()) { + return; + } + + va_list args; + va_start(args, fmt); + const auto str = FormatToString(fmt, args); + va_end(args); + + Log.fatal("{}", str); +} + +void OSReport_Warning(const char* fmt, ...) { + if (!checkEnabled()) { + return; + } + + va_list args; + va_start(args, fmt); + const auto str = FormatToString(fmt, args); + va_end(args); + + Log.warn("{}", str); +} + +void OSReport_System(const char* fmt, ...) { + va_list args; + va_start(args, fmt); + OSVAttention(fmt, args); + va_end(args); +} + +void OSVAttention(const char* fmt, va_list args) { + if (!checkEnabled()) { + return; + } + + const auto str = FormatToString(fmt, args); + + Log.info("{}", str); +} + +void OSAttention(const char* fmt, ...) { + va_list args; + va_start(args, fmt); + OSVAttention(fmt, args); + va_end(args); +} \ No newline at end of file From 48b98a543215e4b8915f4e5073e3ad67dc759620 Mon Sep 17 00:00:00 2001 From: PJB3005 Date: Fri, 1 May 2026 08:50:55 +0200 Subject: [PATCH 13/18] Make JKRExpHeap OOM logging more verbose --- libs/JSystem/src/JKernel/JKRExpHeap.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/libs/JSystem/src/JKernel/JKRExpHeap.cpp b/libs/JSystem/src/JKernel/JKRExpHeap.cpp index 4a6712cb65..dc88090a47 100644 --- a/libs/JSystem/src/JKernel/JKRExpHeap.cpp +++ b/libs/JSystem/src/JKernel/JKRExpHeap.cpp @@ -222,16 +222,11 @@ void* JKRExpHeap::do_alloc(u32 size, int alignment) { OSReport_Error("Free block list as follows:\n"); OSReport_Error("Start | End | Size \n"); - int i = 0; for (const CMemBlock* block = mHeadFreeList; block; block = block->mNext) { if (block->mMagic) { // Allocated, ignore. continue; } - if (i++ > 10) { - OSReport_Error("\n"); - break; - } auto blockStart = (uintptr_t)block - (uintptr_t)mStart; auto blockEnd = (uintptr_t)block + block->size - (uintptr_t)mStart; @@ -239,6 +234,14 @@ void* JKRExpHeap::do_alloc(u32 size, int alignment) { OSReport_Error("%08X | %08X | %08X\n", (u32) blockStart, (u32) blockEnd, (u32) blockSize); } + OSReport_Error("Child heaps as follows:\n"); + OSReport_Error("Start | End | Name \n"); + + const JSUTree& tree = getHeapTree(); + for (JSUTreeIterator iter(tree.getFirstChild()); iter != tree.getEndChild(); ++iter) { + OSReport_Error("%08X | %08X | %s\n", iter->getStartAddr(), iter->getEndAddr(), iter->getName()); + } + CRASH("Aborting due to allocation failure!"); } #else From f2ac4d6f44170ccdbee32f4359656fe0808b74da Mon Sep 17 00:00:00 2001 From: PJB3005 Date: Fri, 1 May 2026 08:52:41 +0200 Subject: [PATCH 14/18] Leave OSReport enabled. --- src/m_Do/m_Do_machine.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/m_Do/m_Do_machine.cpp b/src/m_Do/m_Do_machine.cpp index 6b186a77e6..f4fb0f6286 100644 --- a/src/m_Do/m_Do_machine.cpp +++ b/src/m_Do/m_Do_machine.cpp @@ -753,9 +753,11 @@ void myGXVerifyCallback(GXWarningLevel param_1, u32 param_2, const char* param_3 #endif int mDoMch_Create() { +#if !TARGET_PC // We want crash logs. if (mDoMain::developmentMode == 0 || !(OSGetConsoleType() & 0x10000000)) { OSReportDisable(); } +#endif JKRHeap::setDefaultDebugFill(mDoMch::mDebugFill); #if DEBUG From e4ff38a712a752f116fe79858a90183a4730e334 Mon Sep 17 00:00:00 2001 From: PJB3005 Date: Fri, 1 May 2026 08:54:32 +0200 Subject: [PATCH 15/18] Disable spammy mDoGph_Painter log line What was this even debugging? Who knows. --- src/m_Do/m_Do_graphic.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/m_Do/m_Do_graphic.cpp b/src/m_Do/m_Do_graphic.cpp index 9bd6e5e327..f7866850df 100644 --- a/src/m_Do/m_Do_graphic.cpp +++ b/src/m_Do/m_Do_graphic.cpp @@ -2041,11 +2041,12 @@ static void drawItem3D() { int mDoGph_Painter() { ZoneScoped; + // Diagnostic: log windowNum to track game state machine progress static bool sDiagLoggedWindow = false; if (!sDiagLoggedWindow) { int wn = dComIfGp_getWindowNum(); - DuskLog.debug("mDoGph_Painter: windowNum={}", wn); + // DuskLog.debug("mDoGph_Painter: windowNum={}", wn); if (wn != 0) sDiagLoggedWindow = true; } From 52879f50f000bd89423f8ba50dc2efc9b7d08b97 Mon Sep 17 00:00:00 2001 From: MelonSpeedruns Date: Fri, 1 May 2026 11:47:18 -0400 Subject: [PATCH 16/18] Wide Bulblin count in Hidden Village --- src/d/d_meter_HIO.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/d/d_meter_HIO.cpp b/src/d/d_meter_HIO.cpp index 2df28b2655..584a2852f6 100644 --- a/src/d/d_meter_HIO.cpp +++ b/src/d/d_meter_HIO.cpp @@ -2306,6 +2306,10 @@ void dMeter_drawHIO_c::updateOnWide() { // River Canoe Minigame g_drawHIO.mMiniGame.mCounterPosX[1] = mDoGph_gInf_c::ScaleHUDXRight(g_drawHIO.mMiniGame.mCounterPosX[1]); g_drawHIO.mMiniGame.mIconPosX[1] = mDoGph_gInf_c::ScaleHUDXRight(g_drawHIO.mMiniGame.mIconPosX[1]); + + // Bulblin Count in Hidden Village + g_drawHIO.mMiniGame.mCounterPosX[2] = mDoGph_gInf_c::ScaleHUDXRight(g_drawHIO.mMiniGame.mCounterPosX[2]); + g_drawHIO.mMiniGame.mIconPosX[2] = mDoGph_gInf_c::ScaleHUDXRight(g_drawHIO.mMiniGame.mIconPosX[2]); #endif } From acecba7ff788e09c8460d179ce0035aa37bb960f Mon Sep 17 00:00:00 2001 From: MelonSpeedruns Date: Fri, 1 May 2026 12:54:40 -0400 Subject: [PATCH 17/18] Reset camera zoom to 0 if freecam is enabled mid-game --- src/d/d_camera.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/d/d_camera.cpp b/src/d/d_camera.cpp index 96ffdf97d3..56c44e34f2 100644 --- a/src/d/d_camera.cpp +++ b/src/d/d_camera.cpp @@ -7474,6 +7474,10 @@ bool dCamera_c::test2Camera(s32 param_0) { #if TARGET_PC bool dCamera_c::freeCamera() { + if (dusk::getSettings().game.freeCamera && mGear == 1) { + mGear = 0; + } + if (!dusk::getSettings().game.freeCamera || mCamStyle == 70) { mCamParam.mManualMode = 0; From 93c8bcc2103998c91f48b6336e0a8f3ffbfd8d81 Mon Sep 17 00:00:00 2001 From: madeline Date: Fri, 1 May 2026 13:04:08 -0700 Subject: [PATCH 18/18] hrtf --- include/dusk/settings.h | 1 + .../include/JSystem/JAudio2/JAISeqMgr.h | 3 + libs/JSystem/src/JAudio2/JASChannel.cpp | 10 ++- src/Z2AudioLib/Z2Audience.cpp | 19 ++++- src/dusk/audio/DuskDsp.cpp | 54 +++++++++++++ src/dusk/audio/DuskDsp.hpp | 2 + src/dusk/imgui/ImGuiAudio.cpp | 75 ++++++++++++++++++- src/dusk/imgui/ImGuiMenuGame.cpp | 6 ++ src/dusk/settings.cpp | 2 + src/m_Do/m_Do_main.cpp | 2 + 10 files changed, 171 insertions(+), 3 deletions(-) diff --git a/include/dusk/settings.h b/include/dusk/settings.h index e426e301fa..e6fb0bd32b 100644 --- a/include/dusk/settings.h +++ b/include/dusk/settings.h @@ -55,6 +55,7 @@ struct UserSettings { ConfigVar soundEffectsVolume; ConfigVar fanfareVolume; ConfigVar enableReverb; + ConfigVar enableHrtf; } audio; // Game settings diff --git a/libs/JSystem/include/JSystem/JAudio2/JAISeqMgr.h b/libs/JSystem/include/JSystem/JAudio2/JAISeqMgr.h index 87c85f316f..6f6d29ca98 100644 --- a/libs/JSystem/include/JSystem/JAudio2/JAISeqMgr.h +++ b/libs/JSystem/include/JSystem/JAudio2/JAISeqMgr.h @@ -59,6 +59,9 @@ public: bool isActive() const { return mSeqList.getNumLinks() != 0; } int getNumActiveSeqs() const { return mSeqList.getNumLinks(); } void pause(bool paused) { mActivity.field_0x0.flags.flag2 = paused; } + #if TARGET_PC + JSUList* getSeqList() { return &mSeqList; } + #endif private: /* 0x08 */ JAIAudience* mAudience; diff --git a/libs/JSystem/src/JAudio2/JASChannel.cpp b/libs/JSystem/src/JAudio2/JASChannel.cpp index 61fe80a098..758167cc5c 100644 --- a/libs/JSystem/src/JAudio2/JASChannel.cpp +++ b/libs/JSystem/src/JAudio2/JASChannel.cpp @@ -1,6 +1,9 @@ #include "JSystem/JSystem.h" // IWYU pragma: keep #include "JSystem/JAudio2/JASChannel.h" +#if TARGET_PC +#include "dusk/audio/DuskDsp.hpp" +#endif #include "JSystem/JAudio2/JASAiCtrl.h" #include "JSystem/JAudio2/JASCalc.h" #include "JSystem/JAudio2/JASDriverIF.h" @@ -170,7 +173,12 @@ void JASChannel::updateEffectorParam(JASDsp::TChannel* i_channel, u16* i_mixerVo f32 pan = 0.5f; f32 dolby = 0.0f; - switch (JASDriver::getOutputMode()) { +#if TARGET_PC + u32 effectiveOutputMode = dusk::audio::EnableHrtf ? JAS_OUTPUT_SURROUND : JASDriver::getOutputMode(); +#else + u32 effectiveOutputMode = JASDriver::getOutputMode(); +#endif + switch (effectiveOutputMode) { case JAS_OUTPUT_MONO: break; case JAS_OUTPUT_STEREO: diff --git a/src/Z2AudioLib/Z2Audience.cpp b/src/Z2AudioLib/Z2Audience.cpp index 5bb91eef31..93b3f701c6 100644 --- a/src/Z2AudioLib/Z2Audience.cpp +++ b/src/Z2AudioLib/Z2Audience.cpp @@ -1,5 +1,9 @@ #include "Z2AudioLib/Z2Audience.h" #include "Z2AudioLib/Z2SoundInfo.h" +#if TARGET_PC +#include "dusk/audio/DuskDsp.hpp" +#include +#endif #include "Z2AudioLib/Z2Calc.h" #include "Z2AudioLib/Z2Param.h" #include "JSystem/JAudio2/JAISound.h" @@ -734,9 +738,22 @@ f32 Z2Audience::calcRelPosPan(const Vec& param_0, int camID) { f32 Z2Audience::calcRelPosDolby(const Vec& param_0, int camID) { f32 fVar1 = param_0.z + mAudioCamera[camID].getDolbyCenterZ(); +#if TARGET_PC + if (dusk::audio::EnableHrtf) { + // Normalize the direction so result is purely front/back orientation, + // independent of how far away the sound is + f32 lenSq = param_0.x * param_0.x + param_0.y * param_0.y + param_0.z * param_0.z; + if (lenSq < 0.0001f) { + return 0.5f; + } + f32 zNorm = param_0.z / sqrtf(lenSq); + f32 t = (zNorm + 1.0f) * 0.5f; + return 0.5f - 0.5f * cosf(t * static_cast(M_PI)); + } +#endif if (fVar1 > mSetting.field_0x48) { return 1.0f; - } + } if (fVar1 < mSetting.field_0x44) { return 0.0f; diff --git a/src/dusk/audio/DuskDsp.cpp b/src/dusk/audio/DuskDsp.cpp index f576a5d0f1..697371702f 100644 --- a/src/dusk/audio/DuskDsp.cpp +++ b/src/dusk/audio/DuskDsp.cpp @@ -48,6 +48,20 @@ f32 dusk::audio::MasterVolume = 1.0f; f32 dusk::audio::PrevMasterVolume = 1.0f; bool dusk::audio::EnableReverb = true; bool dusk::audio::DumpAudio = false; +bool dusk::audio::EnableHrtf = false; +f32 dusk::audio::HrtfGain = 0.5f; + + +// 3dB at 5kHz. +static constexpr f32 HRTF_LP_K = 0.75f; +static constexpr f32 HRTF_ALLPASS_G = 0.3f; +// Front never drops below (1 - HRTF_EXTRACT_MAX). +static constexpr f32 HRTF_EXTRACT_MAX = 0.6f; + +static f32 sHrtfLp1 = 0.0f; +static f32 sHrtfLp2 = 0.0f; +static f32 sHrtfApIn1 = 0.0f; +static f32 sHrtfApOut1 = 0.0f; /** * Validate that a DSP channel's format is actually something we know how to play. @@ -283,6 +297,9 @@ void dusk::audio::DspRender(OutputSubframe& subframe) { DspSubframe reverbInputR = {}; bool anyReverbInput = false; + DspSubframe surroundBus = {}; + bool anySurroundInput = false; + for (int i = 0; i < channels.size(); i++) { auto& channel = channels[i]; auto& channelAux = ChannelAux[i]; @@ -324,6 +341,21 @@ void dusk::audio::DspRender(OutputSubframe& subframe) { } } + if (EnableHrtf && channel.mAutoMixerBeenSet) { + f32 dolby = (channel.mAutoMixerPanDolby & 0xFF) / 127.0f; + if (dolby > 0.0f) { + anySurroundInput = true; + f32 extract = dolby * HRTF_EXTRACT_MAX; + f32 frontScale = 1.0f - extract; + for (int j = 0; j < DSP_SUBFRAME_SIZE; j++) { + f32 mono = (channelSubframe.channels[0][j] + channelSubframe.channels[1][j]) * 0.5f; + surroundBus[j] += mono * extract; + channelSubframe.channels[0][j] *= frontScale; + channelSubframe.channels[1][j] *= frontScale; + } + } + } + if (DumpAudio && sChannelDumpFiles[i]) { f32 interleaved[DSP_SUBFRAME_SIZE * 2]; for (int j = 0; j < DSP_SUBFRAME_SIZE; j++) { @@ -349,6 +381,28 @@ void dusk::audio::DspRender(OutputSubframe& subframe) { ReverbHasTail = wetEnergy >= REVERB_ENERGY_EPSILON; } + if (EnableHrtf && anySurroundInput) { + // Two-pole LPF: -12 dB/oct above 3 kHz + for (int j = 0; j < DSP_SUBFRAME_SIZE; j++) { + sHrtfLp1 = (1.0f - HRTF_LP_K) * sHrtfLp1 + HRTF_LP_K * surroundBus[j]; + sHrtfLp2 = (1.0f - HRTF_LP_K) * sHrtfLp2 + HRTF_LP_K * sHrtfLp1; + surroundBus[j] = sHrtfLp2; + } + + // Mix into L and R + // L gets the filtered signal directly; R gets it allpass for mild decorrelation + for (int j = 0; j < DSP_SUBFRAME_SIZE; j++) { + f32 s = surroundBus[j]; + + subframe.channels[0][j] += s * HrtfGain; + + f32 r = -HRTF_ALLPASS_G * s + sHrtfApIn1 + HRTF_ALLPASS_G * sHrtfApOut1; + sHrtfApIn1 = s; + sHrtfApOut1 = r; + subframe.channels[1][j] += r * HrtfGain; + } + } + for (auto& channel : subframe.channels) { ApplyVolume(channel, channel, PrevMasterVolume, MasterVolume); } diff --git a/src/dusk/audio/DuskDsp.hpp b/src/dusk/audio/DuskDsp.hpp index 8000e627a1..cfcbfe3f46 100644 --- a/src/dusk/audio/DuskDsp.hpp +++ b/src/dusk/audio/DuskDsp.hpp @@ -133,4 +133,6 @@ namespace dusk::audio { extern f32 PrevMasterVolume; extern bool EnableReverb; extern bool DumpAudio; + extern bool EnableHrtf; + extern f32 HrtfGain; } diff --git a/src/dusk/imgui/ImGuiAudio.cpp b/src/dusk/imgui/ImGuiAudio.cpp index 9abe4c5261..6bddc6f07c 100644 --- a/src/dusk/imgui/ImGuiAudio.cpp +++ b/src/dusk/imgui/ImGuiAudio.cpp @@ -1,5 +1,7 @@ #include "ImGuiConsole.hpp" #include "ImGuiMenuTools.hpp" +#include +#include "JSystem/JAudio2/JAISeq.h" #include "JSystem/JAudio2/JAISeMgr.h" #include "JSystem/JAudio2/JAISeqMgr.h" #include "JSystem/JAudio2/JAIStreamMgr.h" @@ -15,6 +17,24 @@ static std::array lastResetCounts = {}; static bool sortUpdateCount = true; +static void DrawDirectionGauge(float pan, float dolby) { + constexpr float R = 20.0f; + constexpr float SIZE = R * 2.0f + 4.0f; + + ImVec2 origin = ImGui::GetCursorScreenPos(); + ImGui::Dummy(ImVec2(SIZE, SIZE)); + ImDrawList* dl = ImGui::GetWindowDrawList(); + ImVec2 c = ImVec2(origin.x + SIZE * 0.5f, origin.y + SIZE * 0.5f); + + dl->AddCircle(c, R, IM_COL32(90, 90, 90, 255), 32); + + float dx = (pan - 0.5f) * 2.0f; + float dy = dolby * 2.0f - 1.0f; + float len = sqrtf(dx * dx + dy * dy); + if (len > 1.0f) { dx /= len; dy /= len; } + dl->AddLine(c, ImVec2(c.x + dx * R, c.y + dy * R), IM_COL32(255, 200, 50, 255), 1.5f); +} + static void DisplayDspChannel(int i) { using namespace dusk::audio; @@ -52,8 +72,10 @@ static void DisplayDspChannel(int i) { auto fxMix = (channel.mAutoMixerFxMix >> 8) / 127.5f; auto volume = VolumeFromU16(channel.mAutoMixerVolume); auto pitch = channel.mPitch / 4096.0f; + DrawDirectionGauge(pan, dolby); + ImGui::SameLine(); ImGui::Text( - "Auto mixer active (pan: %f, dolby: %f, fx: %f, volume: %f, pitch %f)", + "pan: %.2f dolby: %.2f\nfx: %.2f vol: %.2f pitch: %.2f", pan, dolby, fxMix, volume, pitch); } else { ImGui::Text( @@ -183,6 +205,10 @@ static void ShowAllJAISes() { if (ImGui::Button("Pause All")) { category->pause(true); } + ImGui::SameLine(); + if (ImGui::Button("Resume All")) { + category->pause(false); + } for (auto seLink = category->getSeList()->getFirst(); seLink != nullptr; seLink = seLink->getNext()) { const auto se = seLink->getObject(); @@ -196,6 +222,33 @@ static void ShowAllJAISes() { } +static void ShowSeqTracks(JAISeq& seq) { + JASTrack& root = seq.inner_.outputTrack; + + for (int group = 0; group < 2; group++) { + JASTrack* groupTrack = root.getChild(group); + if (groupTrack == nullptr) { + continue; + } + + for (int j = 0; j < JASTrack::MAX_CHILDREN; j++) { + JASTrack* track = groupTrack->getChild(j); + if (track == nullptr) { + continue; + } + + int trackIdx = group * 16 + j; + char label[64]; + snprintf(label, sizeof(label), "Track %d (bank %hu, prog %hu)##%p", + trackIdx, track->getBankNumber(), track->getProgNumber(), track); + bool muted = track->mFlags.mute; + if (ImGui::Checkbox(label, &muted)) { + track->mute(muted); + } + } + } +} + static void ShowAllJAISeqs() { auto& mgr = *JAISeqMgr::getInstance(); @@ -206,6 +259,26 @@ static void ShowAllJAISeqs() { if (ImGui::Button("Unpause")) { mgr.pause(false); } + + ImGui::Text("Active sequences: %d", mgr.getNumActiveSeqs()); + + auto* seqList = mgr.getSeqList(); + for (auto* link = seqList->getFirst(); link != nullptr; link = link->getNext()) { + JAISeq* seq = link->getObject(); + if (seq == nullptr) { + continue; + } + + char buf[32]; + snprintf(buf, sizeof(buf), "%p", seq); + + if (ImGui::BeginChild(buf, ImVec2(), ImGuiChildFlags_Border | ImGuiChildFlags_AutoResizeY)) { + ImGui::Text("Seq [%p]", seq); + ShowSeqTracks(*seq); + } + + ImGui::EndChild(); + } } void dusk::ImGuiMenuTools::ShowAudioDebug() { diff --git a/src/dusk/imgui/ImGuiMenuGame.cpp b/src/dusk/imgui/ImGuiMenuGame.cpp index deced34b8e..cf72e17a9a 100644 --- a/src/dusk/imgui/ImGuiMenuGame.cpp +++ b/src/dusk/imgui/ImGuiMenuGame.cpp @@ -397,6 +397,12 @@ namespace dusk { dusk::audio::SetEnableReverb(getSettings().audio.enableReverb); } + if (config::ImGuiCheckbox("Spatial Sound", getSettings().audio.enableHrtf)) { + dusk::audio::EnableHrtf = getSettings().audio.enableHrtf; + } + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("Emulate surround sound via HRTF (for headphone use only)!"); + } ImGui::SeparatorText("Tweaks"); diff --git a/src/dusk/settings.cpp b/src/dusk/settings.cpp index 2eac6d5a19..6198e789d1 100644 --- a/src/dusk/settings.cpp +++ b/src/dusk/settings.cpp @@ -17,6 +17,7 @@ UserSettings g_userSettings = { .soundEffectsVolume {"audio.soundEffectsVolume", 100}, .fanfareVolume {"audio.fanfareVolume", 100}, .enableReverb {"audio.enableReverb", true}, + .enableHrtf {"audio.enableHrtf", false}, }, .game = { @@ -133,6 +134,7 @@ void registerSettings() { Register(g_userSettings.audio.soundEffectsVolume); Register(g_userSettings.audio.fanfareVolume); Register(g_userSettings.audio.enableReverb); + Register(g_userSettings.audio.enableHrtf); // Game Register(g_userSettings.game.language); diff --git a/src/m_Do/m_Do_main.cpp b/src/m_Do/m_Do_main.cpp index d25debb38e..3211fc8873 100644 --- a/src/m_Do/m_Do_main.cpp +++ b/src/m_Do/m_Do_main.cpp @@ -68,6 +68,7 @@ #include "cxxopts.hpp" #include "d/actor/d_a_movie_player.h" #include "dusk/audio/DuskAudioSystem.h" +#include "dusk/audio/DuskDsp.hpp" #include "dusk/config.hpp" #include "dusk/imgui/ImGuiConsole.hpp" #include "dusk/settings.h" @@ -577,6 +578,7 @@ int game_main(int argc, char* argv[]) { dusk::audio::SetMasterVolume(dusk::getSettings().audio.masterVolume / 100.0f); dusk::audio::SetEnableReverb(dusk::getSettings().audio.enableReverb); + dusk::audio::EnableHrtf = dusk::getSettings().audio.enableHrtf; std::string dvd_path; bool dvd_opened = false;