From 4ee0d8ed4b91eb7469c9311644ea441105096544 Mon Sep 17 00:00:00 2001 From: qwertyquerty Date: Wed, 13 May 2026 07:56:16 -0700 Subject: [PATCH] 1.1.1 fixes (#1168) * fix keyboard npe * fix autosave NPE * hintTalkEvCamera UB * fix UB in f_pc_base logging * fix NPE in karg carry logic * fix link model dangling pointers * exponential audio slider and better audio default * fix speedrun mode defaullt layer restore issue --- include/dusk/audio/DuskAudioSystem.h | 11 +++++++++++ include/dusk/config_var.hpp | 7 +++++-- src/d/actor/d_a_alink_swindow.inc | 7 ++++++- src/d/actor/d_a_alink_wolf.inc | 6 ++++++ src/d/d_ev_camera.cpp | 4 ++++ src/dusk/autosave.cpp | 14 ++++++++++---- src/dusk/settings.cpp | 2 +- src/dusk/ui/overlay.cpp | 3 ++- src/dusk/ui/settings.cpp | 2 +- src/f_pc/f_pc_base.cpp | 11 ++++++++++- src/m_Do/m_Do_main.cpp | 2 +- 11 files changed, 57 insertions(+), 12 deletions(-) diff --git a/include/dusk/audio/DuskAudioSystem.h b/include/dusk/audio/DuskAudioSystem.h index 8cdd757c82..780187f9d2 100644 --- a/include/dusk/audio/DuskAudioSystem.h +++ b/include/dusk/audio/DuskAudioSystem.h @@ -1,8 +1,19 @@ #pragma once +#include #include namespace dusk::audio { + + // Converts a 0-1 volume to a linear amplitude multiplier. + // The curve is -4 dB per 10% step: 100% = 0 dB, 90% = -4 dB, ..., 0% = -inf dB + inline f32 MasterVolumeToLinear(f32 v) { + if (v <= 0.0f) { + return 0.0f; + } + return std::pow(10.0f, (v - 1.0f) * 2.0f); + } + /** * Initialize the audio system and start playing audio. */ diff --git a/include/dusk/config_var.hpp b/include/dusk/config_var.hpp index 59eed2199e..0bae27bfd3 100644 --- a/include/dusk/config_var.hpp +++ b/include/dusk/config_var.hpp @@ -175,6 +175,7 @@ class ConfigVar : public ConfigVarBase { T defaultValue; T value; T overrideValue; + ConfigVarLayer priorLayer = ConfigVarLayer::Default; public: /** @@ -265,6 +266,7 @@ public: void setSpeedrunValue(T newValue) { checkRegistered(); if (layer != ConfigVarLayer::Override) { + priorLayer = layer; overrideValue = std::move(newValue); layer = ConfigVarLayer::Speedrun; } @@ -282,7 +284,7 @@ public: checkRegistered(); if (layer == ConfigVarLayer::Speedrun) { overrideValue = {}; - layer = ConfigVarLayer::Value; + layer = priorLayer; } } @@ -293,7 +295,8 @@ public: */ [[nodiscard]] constexpr const T& getValueForSave() const noexcept { checkRegistered(); - return layer == ConfigVarLayer::Default ? defaultValue : value; + const ConfigVarLayer effectiveLayer = (layer == ConfigVarLayer::Speedrun) ? priorLayer : layer; + return effectiveLayer == ConfigVarLayer::Default ? defaultValue : value; } }; diff --git a/src/d/actor/d_a_alink_swindow.inc b/src/d/actor/d_a_alink_swindow.inc index 9016f14205..33f1fee37b 100644 --- a/src/d/actor/d_a_alink_swindow.inc +++ b/src/d/actor/d_a_alink_swindow.inc @@ -77,7 +77,12 @@ int daAlink_c::loadModelDVD() { mpWlMidnaHairModel = NULL; if (!checkNoResetFlg2(FLG2_UNK_280000)) { - dComIfG_resDelete(&mPhaseReq, mArcName); + if (!dComIfG_resDelete(&mPhaseReq, mArcName)) { +#if TARGET_PC + // resDelete no-ops if load was in-progress; force-unregister before freeAll + dComIfG_deleteObjectResMain(mArcName); +#endif + } cPhs_Reset(&mPhaseReq); mpArcHeap->freeAll(); diff --git a/src/d/actor/d_a_alink_wolf.inc b/src/d/actor/d_a_alink_wolf.inc index b2e60aea01..67fde3a7a7 100644 --- a/src/d/actor/d_a_alink_wolf.inc +++ b/src/d/actor/d_a_alink_wolf.inc @@ -8723,6 +8723,12 @@ int daAlink_c::procWolfCargoCarry() { return checkNextActionWolf(0); } +#if TARGET_PC + if (field_0x280c.getActor() == NULL) { + return checkNextActionWolf(0); + } +#endif + mDoMtx_stack_c::copy(((e_yc_class*)field_0x280c.getActor())->getLegR3Mtx()); mDoMtx_stack_c::transM(-9.0f, -7.0f, -30.0f); mDoMtx_stack_c::multVecZero(¤t.pos); diff --git a/src/d/d_ev_camera.cpp b/src/d/d_ev_camera.cpp index 442c8cc4af..736f9f7a82 100644 --- a/src/d/d_ev_camera.cpp +++ b/src/d/d_ev_camera.cpp @@ -3882,7 +3882,11 @@ bool dCamera_c::hintTalkEvCamera() { cSAngle acStack_1fc(20.0f); for (i = 0; i < 2; i++) { +#if AVOID_UB + for (j = 0; j < 10; j++) { +#else for (j = 0; j < 12; j++) { +#endif cSAngle acStack_200(local_b0[j] * fVar22); hintTalk->mDirection.U(acStack_1f8 + acStack_200); hintTalk->mDirection.V(((hintTalk->field_0x28.V() * acStack_200.Cos()) * 0.2f) + acStack_1fc); diff --git a/src/dusk/autosave.cpp b/src/dusk/autosave.cpp index 6fce913910..13fc2929eb 100644 --- a/src/dusk/autosave.cpp +++ b/src/dusk/autosave.cpp @@ -26,8 +26,12 @@ void updateAutoSave() { (AutoSaveFuncsProc[mAutoSaveProc])(); } -void writeAutoSave() { - int stageNo = dStage_stagInfo_GetSaveTbl(dComIfGp_getStageStagInfo()); +bool writeAutoSave() { + stage_stag_info_class* stagInfo = dComIfGp_getStageStagInfo(); + if (stagInfo == nullptr) { + return false; + } + int stageNo = dStage_stagInfo_GetSaveTbl(stagInfo); dComIfGs_putSave(stageNo); dComIfGs_setMemoryToCard(mSaveBuffer, dComIfGs_getDataNum()); @@ -40,6 +44,7 @@ void writeAutoSave() { } g_mDoMemCd_control.save(mSaveBuffer, sizeof(mSaveBuffer), 0); + return true; } void autoSaving() { @@ -48,8 +53,9 @@ void autoSaving() { if (cardState == 2) { mAutoSaveProc = 1; } else if (cardState == 1) { - writeAutoSave(); - mAutoSaveProc = 3; + if (writeAutoSave()) { + mAutoSaveProc = 3; + } } } } diff --git a/src/dusk/settings.cpp b/src/dusk/settings.cpp index 5e3f73a366..dbe27db8aa 100644 --- a/src/dusk/settings.cpp +++ b/src/dusk/settings.cpp @@ -13,7 +13,7 @@ UserSettings g_userSettings = { }, .audio = { - .masterVolume {"audio.masterVolume", 80}, + .masterVolume {"audio.masterVolume", 60}, .mainMusicVolume {"audio.mainMusicVolume", 100}, .subMusicVolume {"audio.subMusicVolume", 100}, .soundEffectsVolume {"audio.soundEffectsVolume", 100}, diff --git a/src/dusk/ui/overlay.cpp b/src/dusk/ui/overlay.cpp index 5bcd21c401..c9b2b8614d 100644 --- a/src/dusk/ui/overlay.cpp +++ b/src/dusk/ui/overlay.cpp @@ -354,8 +354,9 @@ void Overlay::update() { } } + u32 count = 0; const bool showControllerWarning = PADGetIndexForPort(PAD_CHAN0) < 0 && - PADGetKeyButtonBindings(PAD_CHAN0, nullptr) == nullptr && + PADGetKeyButtonBindings(PAD_CHAN0, &count) == nullptr && dynamic_cast(top_document()) == nullptr && dynamic_cast(top_document()) == nullptr; if (showControllerWarning && mControllerWarning == nullptr) { diff --git a/src/dusk/ui/settings.cpp b/src/dusk/ui/settings.cpp index 2a26d5113a..c54b3784be 100644 --- a/src/dusk/ui/settings.cpp +++ b/src/dusk/ui/settings.cpp @@ -953,7 +953,7 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) { [](int value) { getSettings().audio.masterVolume.setValue(value); config::Save(); - audio::SetMasterVolume(value / 100.f); + audio::SetMasterVolume(audio::MasterVolumeToLinear(value / 100.0f)); }, .isModified = [] { diff --git a/src/f_pc/f_pc_base.cpp b/src/f_pc/f_pc_base.cpp index 848153b836..7bb53ae634 100644 --- a/src/f_pc/f_pc_base.cpp +++ b/src/f_pc/f_pc_base.cpp @@ -136,8 +136,17 @@ base_process_class* fpcBs_Create(s16 i_profname, fpc_ProcID i_procID, void* i_ap u32 size; pprofile = (process_profile_definition*)fpcPf_Get(i_profname); + if (pprofile == NULL) { +#if TARGET_PC + DuskLog.debug("fpcBs_Create: profile not found for profname={}", i_profname); +#endif + return NULL; + } +#if TARGET_PC + const char* procName = getProcName(i_profname); DuskLog.debug("fpcBs_Create: pid={} profname={} ({}) profile={} procSize={} unkSize={}", - i_procID, getProcName(i_profname), i_profname, (void*)pprofile, pprofile->process_size, pprofile->unk_size); + i_procID, procName ? procName : "(unknown)", i_profname, (void*)pprofile, pprofile->process_size, pprofile->unk_size); +#endif size = pprofile->process_size + pprofile->unk_size; pprocess = (base_process_class*)cMl::memalignB(-4, size); diff --git a/src/m_Do/m_Do_main.cpp b/src/m_Do/m_Do_main.cpp index 8cfd235344..b892a1f706 100644 --- a/src/m_Do/m_Do_main.cpp +++ b/src/m_Do/m_Do_main.cpp @@ -585,7 +585,7 @@ int game_main(int argc, char* argv[]) { } VISetFrameBufferScale(dusk::getSettings().game.internalResolutionScale.getValue()); - dusk::audio::SetMasterVolume(dusk::getSettings().audio.masterVolume / 100.0f); + dusk::audio::SetMasterVolume(dusk::audio::MasterVolumeToLinear(dusk::getSettings().audio.masterVolume / 100.0f)); dusk::audio::SetEnableReverb(dusk::getSettings().audio.enableReverb); dusk::audio::EnableHrtf = dusk::getSettings().audio.enableHrtf;