mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-09-06 09:55:11 -04:00
Merge branch 'better-tools' of https://github.com/TakaRikka/dusk into better-tools
This commit is contained in:
+17
-6
@@ -76,15 +76,12 @@ template<ConfigValue T>
|
||||
void ConfigImpl<T>::loadFromJson(ConfigVar<T>& cVar, const json& jsonValue) {
|
||||
if constexpr (std::is_enum_v<T>) {
|
||||
if (jsonValue.is_boolean()) {
|
||||
DuskConfigLog.error("Doing default migration of CVar {} from bool, enum values may not be what is expected!", cVar.getName());
|
||||
|
||||
using Underlying = std::underlying_type_t<T>;
|
||||
const bool b = jsonValue.get<bool>();
|
||||
|
||||
Underlying raw;
|
||||
if constexpr (std::is_same_v<T, dusk::FrameInterpMode>) {
|
||||
raw = b ? static_cast<Underlying>(2) : static_cast<Underlying>(0);
|
||||
} else {
|
||||
raw = b ? static_cast<Underlying>(1) : static_cast<Underlying>(0);
|
||||
}
|
||||
const Underlying raw = b ? static_cast<Underlying>(1) : static_cast<Underlying>(0);
|
||||
|
||||
cVar.setValue(sanitizeEnumValue(cVar, static_cast<T>(raw)), false);
|
||||
return;
|
||||
@@ -194,9 +191,23 @@ namespace dusk::config {
|
||||
template class ConfigImpl<dusk::DiscVerificationState>;
|
||||
template class ConfigImpl<dusk::GameLanguage>;
|
||||
template class ConfigImpl<dusk::GyroMode>;
|
||||
|
||||
template<> void ConfigImpl<FrameInterpMode>::loadFromJson(ConfigVar<FrameInterpMode>& cVar, const json& jsonValue) {
|
||||
if (jsonValue.is_boolean()) {
|
||||
const bool b = jsonValue.get<bool>();
|
||||
|
||||
const FrameInterpMode mode = b ? FrameInterpMode::Unlimited : FrameInterpMode::Off;
|
||||
|
||||
cVar.setValue(sanitizeEnumValue(cVar, mode), false);
|
||||
return;
|
||||
}
|
||||
|
||||
cVar.setValue(sanitizeEnumValue(cVar, jsonValue.get<FrameInterpMode>()), false);
|
||||
}
|
||||
template class ConfigImpl<dusk::FrameInterpMode>;
|
||||
template class ConfigImpl<dusk::MenuScaling>;
|
||||
template class ConfigImpl<dusk::Resampler>;
|
||||
template class ConfigImpl<dusk::MagicArmorMode>;
|
||||
}
|
||||
|
||||
void dusk::config::Register(ConfigVarBase& configVar) {
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#if defined(__APPLE__)
|
||||
#include <mach-o/dyld.h>
|
||||
#include <mach-o/loader.h>
|
||||
#include <TargetConditionals.h>
|
||||
#else
|
||||
#include <elf.h>
|
||||
#include <link.h>
|
||||
@@ -929,7 +930,7 @@ void install() {
|
||||
SymInitialize(GetCurrentProcess(), nullptr, TRUE);
|
||||
#endif
|
||||
g_prevFilter = SetUnhandledExceptionFilter(&windowsHandler);
|
||||
#else
|
||||
#elif !defined(__APPLE__) || !TARGET_OS_TV
|
||||
Dl_info moduleInfo;
|
||||
if (dladdr(reinterpret_cast<void*>(&install), &moduleInfo) != 0) {
|
||||
g_ctx.moduleBase = reinterpret_cast<uintptr_t>(moduleInfo.dli_fbase);
|
||||
|
||||
+2
-101
@@ -16,7 +16,6 @@
|
||||
#include <vector>
|
||||
|
||||
#include <SDL3/SDL_filesystem.h>
|
||||
#include <SDL3/SDL_iostream.h>
|
||||
#include <SDL3/SDL_misc.h>
|
||||
#include <SDL3/SDL_stdinc.h>
|
||||
|
||||
@@ -28,8 +27,6 @@ namespace {
|
||||
aurora::Module Log{"dusk::data"};
|
||||
|
||||
constexpr auto kLocationDescriptorName = "data_location.json";
|
||||
constexpr auto kPipelineCacheName = "pipeline_cache.db";
|
||||
constexpr auto kInitialPipelineCacheName = "initial_pipeline_cache.db";
|
||||
|
||||
constexpr std::array<std::string_view, 4> kUserDataDirectories = {
|
||||
"texture_replacements",
|
||||
@@ -37,10 +34,11 @@ constexpr std::array<std::string_view, 4> kUserDataDirectories = {
|
||||
"EUR",
|
||||
"JAP",
|
||||
};
|
||||
constexpr std::array<std::string_view, 6> kUserDataFiles = {
|
||||
constexpr std::array<std::string_view, 7> kUserDataFiles = {
|
||||
"achievements.json",
|
||||
"config.json",
|
||||
"controller_ports.dat",
|
||||
"gamecontrollerdb.txt",
|
||||
"imgui.ini",
|
||||
"keyboard_bindings.dat",
|
||||
"states.json",
|
||||
@@ -888,102 +886,6 @@ void ensure_data_directory(const std::filesystem::path& dataPath) {
|
||||
}
|
||||
}
|
||||
|
||||
SDL_IOStream* open_initial_pipeline_cache_source(std::string& sourcePathString) {
|
||||
const auto basePath = base_path_relative(kInitialPipelineCacheName);
|
||||
sourcePathString = io::fs_path_to_string(basePath);
|
||||
auto* source = SDL_IOFromFile(sourcePathString.c_str(), "rb");
|
||||
if (source != nullptr) {
|
||||
return source;
|
||||
}
|
||||
|
||||
sourcePathString = std::string{kInitialPipelineCacheName};
|
||||
return SDL_IOFromFile(sourcePathString.c_str(), "rb");
|
||||
}
|
||||
|
||||
void ensure_initial_pipeline_cache(const std::filesystem::path& configDir) {
|
||||
if (configDir.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::error_code ec;
|
||||
std::filesystem::create_directories(configDir, ec);
|
||||
if (ec) {
|
||||
Log.warn("Failed to create config directory '{}' for pipeline cache: {}",
|
||||
io::fs_path_to_string(configDir), ec.message());
|
||||
return;
|
||||
}
|
||||
|
||||
const auto pipelineCachePath = configDir / kPipelineCacheName;
|
||||
if (std::filesystem::exists(pipelineCachePath, ec)) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string sourcePathString;
|
||||
SDL_IOStream* source = open_initial_pipeline_cache_source(sourcePathString);
|
||||
if (source == nullptr) {
|
||||
Log.info("No bundled initial pipeline cache found");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto pipelineCacheString = io::fs_path_to_string(pipelineCachePath);
|
||||
SDL_IOStream* destination = SDL_IOFromFile(pipelineCacheString.c_str(), "wb");
|
||||
if (destination == nullptr) {
|
||||
Log.warn("Failed to open '{}' for seeded pipeline cache: {}", pipelineCacheString,
|
||||
SDL_GetError());
|
||||
SDL_CloseIO(source);
|
||||
return;
|
||||
}
|
||||
|
||||
bool copied = true;
|
||||
std::array<char, 64 * 1024> buffer{};
|
||||
while (true) {
|
||||
const size_t bytesRead = SDL_ReadIO(source, buffer.data(), buffer.size());
|
||||
if (bytesRead > 0) {
|
||||
size_t bytesWritten = 0;
|
||||
while (bytesWritten < bytesRead) {
|
||||
const size_t written = SDL_WriteIO(
|
||||
destination, buffer.data() + bytesWritten, bytesRead - bytesWritten);
|
||||
if (written == 0) {
|
||||
Log.warn("Failed to write seeded pipeline cache '{}': {}", pipelineCacheString,
|
||||
SDL_GetError());
|
||||
copied = false;
|
||||
break;
|
||||
}
|
||||
bytesWritten += written;
|
||||
}
|
||||
}
|
||||
|
||||
if (!copied) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (bytesRead < buffer.size()) {
|
||||
if (SDL_GetIOStatus(source) == SDL_IO_STATUS_EOF) {
|
||||
break;
|
||||
}
|
||||
|
||||
Log.warn(
|
||||
"Failed to read bundled pipeline cache '{}': {}", sourcePathString, SDL_GetError());
|
||||
copied = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!SDL_CloseIO(destination)) {
|
||||
Log.warn(
|
||||
"Failed to close seeded pipeline cache '{}': {}", pipelineCacheString, SDL_GetError());
|
||||
copied = false;
|
||||
}
|
||||
SDL_CloseIO(source);
|
||||
|
||||
if (!copied) {
|
||||
std::filesystem::remove(pipelineCachePath, ec);
|
||||
return;
|
||||
}
|
||||
|
||||
Log.info("Seeded pipeline cache from '{}'", sourcePathString);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool open_data_path() {
|
||||
@@ -1096,7 +998,6 @@ Paths initialize_data() {
|
||||
migrate_data(prefPath, dataPath, descriptor ? &descriptor->descriptor : nullptr);
|
||||
ensure_data_directory(dataPath);
|
||||
ensure_data_directory(prefPath);
|
||||
ensure_initial_pipeline_cache(prefPath);
|
||||
|
||||
return Paths{
|
||||
.userPath = dataPath,
|
||||
|
||||
@@ -49,7 +49,9 @@ namespace dusk {
|
||||
dCam->Reset(center, eye);
|
||||
}
|
||||
|
||||
ImGui::InputFloat("Camera FOV", &dCam->mFovy);
|
||||
if (ImGui::InputFloat("Camera FOV", &dCam->mFovy)) {
|
||||
dCam->mFovy = std::clamp(dCam->mFovy, 0.1f, 179.9f);
|
||||
}
|
||||
|
||||
ImGui::SeparatorText("Options");
|
||||
|
||||
@@ -75,12 +77,12 @@ namespace dusk {
|
||||
if (!getSettings().game.debugFlyCam) {
|
||||
ImGui::BeginDisabled();
|
||||
}
|
||||
config::ImGuiCheckbox("Lock Events", getSettings().game.debugFlyCamLockEvents);
|
||||
config::ImGuiCheckbox("Freeze Time", getSettings().game.debugFlyCamLockEvents);
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
|
||||
if (!getSettings().game.debugFlyCam) {
|
||||
ImGui::SetTooltip("Enable Fly Mode first.");
|
||||
} else {
|
||||
ImGui::SetTooltip("Freeze game events while flying.");
|
||||
ImGui::SetTooltip("Freezes the game while flying.");
|
||||
}
|
||||
}
|
||||
if (!getSettings().game.debugFlyCam) {
|
||||
|
||||
@@ -41,6 +41,7 @@ UserSettings g_userSettings = {
|
||||
.noMissClimbing {"game.noMissClimbing", false},
|
||||
.fastTears {"game.fastTears", false},
|
||||
.no2ndFishForCat {"game.no2ndFishForCat", false},
|
||||
.buttonFishing {"game.buttonFishing", false},
|
||||
.instantSaves {"game.instantSaves", false},
|
||||
.instantText {"game.instantText", false},
|
||||
.sunsSong {"game.sunsSong", false},
|
||||
@@ -50,6 +51,7 @@ UserSettings g_userSettings = {
|
||||
// Preferences
|
||||
.enableMirrorMode {"game.enableMirrorMode", false},
|
||||
.minimalHUD {"game.minimalHUD", false},
|
||||
.hudScale {"game.hudScale", 1.0f},
|
||||
.pauseOnFocusLost {"game.pauseOnFocusLost", false},
|
||||
.enableLinkDollRotation {"game.enableLinkDollRotation", false},
|
||||
.enableAchievementToasts {"game.enableAchievementToasts", true},
|
||||
@@ -125,7 +127,7 @@ UserSettings g_userSettings = {
|
||||
.canTransformAnywhere {"game.canTransformAnywhere", false},
|
||||
.fastRoll {"game.fastRoll", false},
|
||||
.fastSpinner {"game.fastSpinner", false},
|
||||
.freeMagicArmor {"game.freeMagicArmor", false},
|
||||
.armorRupeeDrain {"game.armorRupeeDrain", MagicArmorMode::NORMAL},
|
||||
.invincibleEnemies {"game.invincibleEnemies", false},
|
||||
|
||||
// Technical
|
||||
@@ -225,6 +227,7 @@ void registerSettings() {
|
||||
Register(g_userSettings.game.fastClimbing);
|
||||
Register(g_userSettings.game.fastTears);
|
||||
Register(g_userSettings.game.no2ndFishForCat);
|
||||
Register(g_userSettings.game.buttonFishing);
|
||||
Register(g_userSettings.game.instantSaves);
|
||||
Register(g_userSettings.game.instantText);
|
||||
Register(g_userSettings.game.sunsSong);
|
||||
@@ -240,6 +243,7 @@ void registerSettings() {
|
||||
Register(g_userSettings.game.freeCameraXSensitivity);
|
||||
Register(g_userSettings.game.freeCameraYSensitivity);
|
||||
Register(g_userSettings.game.minimalHUD);
|
||||
Register(g_userSettings.game.hudScale);
|
||||
Register(g_userSettings.game.pauseOnFocusLost);
|
||||
Register(g_userSettings.game.enableDiscordPresence);
|
||||
Register(g_userSettings.game.bloomMode);
|
||||
@@ -255,7 +259,7 @@ void registerSettings() {
|
||||
Register(g_userSettings.game.enableFastIronBoots);
|
||||
Register(g_userSettings.game.canTransformAnywhere);
|
||||
Register(g_userSettings.game.fastRoll);
|
||||
Register(g_userSettings.game.freeMagicArmor);
|
||||
Register(g_userSettings.game.armorRupeeDrain);
|
||||
Register(g_userSettings.game.restoreWiiGlitches);
|
||||
Register(g_userSettings.game.enableLinkDollRotation);
|
||||
Register(g_userSettings.game.enableAchievementToasts);
|
||||
|
||||
@@ -33,7 +33,7 @@ void resetForSpeedrunMode() {
|
||||
getSettings().game.canTransformAnywhere.setSpeedrunValue(false);
|
||||
getSettings().game.fastRoll.setSpeedrunValue(false);
|
||||
getSettings().game.fastSpinner.setSpeedrunValue(false);
|
||||
getSettings().game.freeMagicArmor.setSpeedrunValue(false);
|
||||
getSettings().game.armorRupeeDrain.setSpeedrunValue(MagicArmorMode::NORMAL);
|
||||
|
||||
getSettings().game.pauseOnFocusLost.setSpeedrunValue(false);
|
||||
aurora_set_pause_on_focus_lost(false);
|
||||
|
||||
@@ -217,7 +217,7 @@ void AchievementsWindow::updateTotal() {
|
||||
return;
|
||||
}
|
||||
const auto all = AchievementSystem::get().getAchievements();
|
||||
int total = static_cast<int>(all.size());
|
||||
const int total = std::count_if(all.begin(), all.end(), [](const Achievement& achievement){ return achievement.category != AchievementCategory::Glitched;});
|
||||
int unlocked = 0;
|
||||
for (const auto& a : all) {
|
||||
if (a.unlocked) {
|
||||
|
||||
@@ -37,6 +37,7 @@ void applyPresetDusk() {
|
||||
s.game.invertCameraXAxis.setValue(true);
|
||||
s.game.invertFirstPersonYAxis.setValue(true);
|
||||
s.game.no2ndFishForCat.setValue(true);
|
||||
s.game.buttonFishing.setValue(true);
|
||||
s.game.enableAchievementToasts.setValue(true);
|
||||
s.game.enableControllerToasts.setValue(true);
|
||||
s.game.enableQuickTransform.setValue(true);
|
||||
|
||||
@@ -75,6 +75,14 @@ constexpr std::array kMenuScalingModeLabels = {
|
||||
"Dusklight",
|
||||
};
|
||||
|
||||
constexpr std::array kMagicArmorModes = {
|
||||
"Normal",
|
||||
"On Damage",
|
||||
"Double Defense",
|
||||
"Invincible",
|
||||
"Cosmetic",
|
||||
};
|
||||
|
||||
bool try_parse_backend(std::string_view backend, AuroraBackend& outBackend) {
|
||||
if (backend == "auto") {
|
||||
outBackend = BACKEND_AUTO;
|
||||
@@ -211,7 +219,7 @@ void reset_for_speedrun_mode() {
|
||||
getSettings().game.canTransformAnywhere.setSpeedrunValue(false);
|
||||
getSettings().game.fastRoll.setSpeedrunValue(false);
|
||||
getSettings().game.fastSpinner.setSpeedrunValue(false);
|
||||
getSettings().game.freeMagicArmor.setSpeedrunValue(false);
|
||||
getSettings().game.armorRupeeDrain.setSpeedrunValue(MagicArmorMode::NORMAL);
|
||||
getSettings().game.invincibleEnemies.setSpeedrunValue(false);
|
||||
|
||||
getSettings().game.pauseOnFocusLost.setSpeedrunValue(false);
|
||||
@@ -1113,6 +1121,11 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
|
||||
addOption("Minimal HUD", getSettings().game.minimalHUD,
|
||||
"Disables the elements of the main HUD of the game.<br/>Useful for a more immersive "
|
||||
"experience.");
|
||||
config_percent_select(leftPane, rightPane, getSettings().game.hudScale,
|
||||
"HUD Scale",
|
||||
"Scales the size of the gameplay HUD (hearts, buttons, mini-map, etc.). Does not affect dialog boxes or menus.",
|
||||
50, 200, 5,
|
||||
[] { return getSettings().game.minimalHUD.getValue(); });
|
||||
addOption("Restore Wii 1.0 Glitches", getSettings().game.restoreWiiGlitches,
|
||||
"Restores patched glitches from Wii USA 1.0, the first released version.");
|
||||
addOption("Enable Rotating Link Doll", getSettings().game.enableLinkDollRotation,
|
||||
@@ -1173,6 +1186,8 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
|
||||
"Link will not recoil when his sword hits walls.");
|
||||
addOption("No 2nd Fish for Cat", getSettings().game.no2ndFishForCat,
|
||||
"Skip needing to catch a second fish for Sera's cat.");
|
||||
addOption("Button Fishing", getSettings().game.buttonFishing,
|
||||
"Allow fishing with the Fishing Rod using the button the item is assigned to.");
|
||||
addOption("Show Poe Count on Map", getSettings().game.enhancedMapMenus,
|
||||
"Displays collected/total number of Poe Souls for a region on the map.");
|
||||
addSpeedrunDisabledOption("Sun's Song (R+X)", getSettings().game.sunsSong,
|
||||
@@ -1265,8 +1280,38 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
|
||||
"Makes Link's roll animation and movement twice as fast.");
|
||||
addCheat("Fast Spinner", getSettings().game.fastSpinner,
|
||||
"Speeds up Spinner movement while holding R.");
|
||||
addCheat("Free Magic Armor", getSettings().game.freeMagicArmor,
|
||||
"Lets the magic armor work without consuming rupees.");
|
||||
leftPane.register_control(
|
||||
leftPane.add_select_button({
|
||||
.key = "Magic Armor Behavior",
|
||||
.getValue =
|
||||
[] {
|
||||
return kMagicArmorModes[static_cast<u8>(getSettings().game.armorRupeeDrain.getValue())];
|
||||
},
|
||||
.isDisabled = [] { return getSettings().game.speedrunMode; },
|
||||
.isModified =
|
||||
[] {
|
||||
return getSettings().game.armorRupeeDrain.getValue() !=
|
||||
getSettings().game.armorRupeeDrain.getDefaultValue();
|
||||
},
|
||||
}),
|
||||
rightPane, [](Pane& pane) {
|
||||
for (int i = 0; i < kMagicArmorModes.size(); i++) {
|
||||
pane.add_button({
|
||||
.text = kMagicArmorModes[i],
|
||||
.isSelected =
|
||||
[i] {
|
||||
return getSettings().game.armorRupeeDrain.getValue() == static_cast<MagicArmorMode>(i);
|
||||
},
|
||||
})
|
||||
.on_pressed([i] {
|
||||
mDoAud_seStartMenu(kSoundItemChange);
|
||||
getSettings().game.armorRupeeDrain.setValue(static_cast<MagicArmorMode>(i));
|
||||
config::Save();
|
||||
});
|
||||
}
|
||||
pane.add_rml(
|
||||
"<br/>Control the behavior of the Magic Armor.");
|
||||
});
|
||||
addCheat("Invincible Enemies", getSettings().game.invincibleEnemies,
|
||||
"Prevents enemies from taking damage.");
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user