Merge branch 'main' of https://github.com/TwilitRealm/dusk into randomizer

This commit is contained in:
gymnast86
2026-05-13 17:04:13 -07:00
13 changed files with 101 additions and 36 deletions
+11
View File
@@ -1,8 +1,19 @@
#pragma once
#include <cmath>
#include <dolphin/types.h>
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.
*/
+5 -2
View File
@@ -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;
}
};
+6 -1
View File
@@ -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();
+6
View File
@@ -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(&current.pos);
+4
View File
@@ -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);
+10 -4
View File
@@ -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;
}
}
}
}
+43 -23
View File
@@ -78,6 +78,7 @@ struct MigrationStats {
std::optional<std::filesystem::path> sConfiguredDataPath;
std::optional<std::filesystem::path> sActiveDescriptorPath;
std::optional<std::filesystem::path> sActivePrefPath;
std::filesystem::path path_from_utf8(std::string_view value) {
return std::filesystem::path{
@@ -86,19 +87,22 @@ std::filesystem::path path_from_utf8(std::string_view value) {
};
}
std::filesystem::path get_legacy_path() {
if (std::string_view{LegacyAppName}.empty()) {
std::filesystem::path legacy_path_for_pref_path(const std::filesystem::path& prefPath) {
if (std::string_view{LegacyAppName}.empty() || prefPath.empty()) {
return {};
}
char* prefPath = SDL_GetPrefPath(OrgName, LegacyAppName);
if (!prefPath) {
Log.fatal("Unable to get PrefPath: {}", SDL_GetError());
auto normalizedPrefPath = prefPath;
if (normalizedPrefPath.filename().empty()) {
normalizedPrefPath = normalizedPrefPath.parent_path();
}
std::filesystem::path result{reinterpret_cast<const char8_t*>(prefPath)};
SDL_free(prefPath);
return result;
const auto parentPath = normalizedPrefPath.parent_path();
if (parentPath.empty()) {
return {};
}
return parentPath / LegacyAppName;
}
std::filesystem::path get_pref_path() {
@@ -112,6 +116,13 @@ std::filesystem::path get_pref_path() {
return result;
}
std::filesystem::path active_pref_path() {
if (sActivePrefPath) {
return *sActivePrefPath;
}
return get_pref_path();
}
std::filesystem::path base_path_relative(const std::filesystem::path& path) {
const auto* basePath = SDL_GetBasePath();
if (!basePath) {
@@ -265,12 +276,12 @@ std::filesystem::path absolute_path(const std::filesystem::path& path) {
return absolute.lexically_normal();
}
void rename_legacy_pref_path(
std::filesystem::path rename_legacy_pref_path(
const std::filesystem::path& legacyPath, const std::filesystem::path& prefPath) {
if (legacyPath.empty() || prefPath.empty() ||
normalized_path(legacyPath) == normalized_path(prefPath))
{
return;
return prefPath;
}
std::error_code ec;
@@ -279,14 +290,14 @@ void rename_legacy_pref_path(
Log.warn("Failed to inspect legacy data directory '{}': {}",
io::fs_path_to_string(legacyPath), ec.message());
}
return;
return prefPath;
}
const bool prefExists = std::filesystem::exists(prefPath, ec);
if (ec) {
Log.warn("Failed to inspect data directory '{}': {}", io::fs_path_to_string(prefPath),
ec.message());
return;
return prefPath;
}
if (prefExists) {
if (!std::filesystem::is_directory(prefPath, ec) ||
@@ -299,14 +310,14 @@ void rename_legacy_pref_path(
Log.info("Skipping legacy data directory rename because '{}' is not empty",
io::fs_path_to_string(prefPath));
}
return;
return prefPath;
}
std::filesystem::remove(prefPath, ec);
if (ec) {
Log.warn("Failed to remove empty data directory '{}' before legacy rename: {}",
io::fs_path_to_string(prefPath), ec.message());
return;
return prefPath;
}
}
@@ -314,11 +325,18 @@ void rename_legacy_pref_path(
if (ec) {
Log.warn("Failed to rename legacy data directory '{}' to '{}': {}",
io::fs_path_to_string(legacyPath), io::fs_path_to_string(prefPath), ec.message());
return;
ec.clear();
if (!std::filesystem::exists(prefPath, ec) && !ec) {
Log.info("Using legacy data directory '{}' because the new data directory is absent",
io::fs_path_to_string(legacyPath));
return legacyPath;
}
return prefPath;
}
Log.info("Renamed legacy data directory '{}' to '{}'", io::fs_path_to_string(legacyPath),
io::fs_path_to_string(prefPath));
return prefPath;
}
bool is_same_or_inside(const std::filesystem::path& root, const std::filesystem::path& path) {
@@ -394,7 +412,7 @@ std::filesystem::path current_data_path() {
if (!ConfigPath.empty()) {
return ConfigPath;
}
const auto prefPath = get_pref_path();
const auto prefPath = active_pref_path();
const auto descriptor = read_location_descriptor(prefPath);
if (descriptor) {
sActiveDescriptorPath = descriptor->path;
@@ -460,7 +478,7 @@ bool write_location_descriptor(LocationMode mode, const std::filesystem::path& t
json["previousPath"] = io::fs_path_to_string(descriptor.previousPath);
}
const auto prefPath = get_pref_path();
const auto prefPath = active_pref_path();
for (const auto& path : descriptor_write_paths(prefPath)) {
if (write_descriptor_json(path, json)) {
sActiveDescriptorPath = path;
@@ -1013,12 +1031,12 @@ bool set_portable_data_path() {
}
bool reset_data_path() {
const auto prefPath = get_pref_path();
const auto prefPath = active_pref_path();
return write_location_descriptor(LocationMode::Default, default_data_path(prefPath));
}
bool is_default_data_path() {
const auto prefPath = get_pref_path();
const auto prefPath = active_pref_path();
return normalized_path(configured_data_path()) == normalized_path(default_data_path(prefPath));
}
@@ -1027,7 +1045,7 @@ std::filesystem::path configured_data_path() {
return *sConfiguredDataPath;
}
const auto prefPath = get_pref_path();
const auto prefPath = active_pref_path();
const auto descriptor = read_location_descriptor(prefPath);
if (descriptor) {
sActiveDescriptorPath = descriptor->path;
@@ -1041,7 +1059,7 @@ std::filesystem::path cache_path() {
if (!CachePath.empty()) {
return CachePath;
}
return get_pref_path();
return active_pref_path();
}
bool is_data_path_restart_pending() {
@@ -1053,8 +1071,10 @@ bool is_data_path_restart_pending() {
}
Paths initialize_data() {
const auto prefPath = get_pref_path();
rename_legacy_pref_path(get_legacy_path(), prefPath);
const auto preferredPrefPath = get_pref_path();
const auto prefPath =
rename_legacy_pref_path(legacy_path_for_pref_path(preferredPrefPath), preferredPrefPath);
sActivePrefPath = prefPath;
const auto descriptor = read_location_descriptor(prefPath);
if (descriptor) {
+1 -1
View File
@@ -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},
+1 -1
View File
@@ -184,7 +184,7 @@ Rml::String format_graphics_setting_value(GraphicsOption option, int value) {
case BloomMode::Classic:
return "Classic";
case BloomMode::Dusk:
return "Dusk";
return "Dusklight";
}
break;
case GraphicsOption::BloomMultiplier:
+2 -1
View File
@@ -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<Window*>(top_document()) == nullptr &&
dynamic_cast<WindowSmall*>(top_document()) == nullptr;
if (showControllerWarning && mControllerWarning == nullptr) {
+1 -1
View File
@@ -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 =
[] {
+10 -1
View File
@@ -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);
+1 -1
View File
@@ -601,7 +601,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;