Qt: Add GUI for game-specific settings (#3533)

* Open settings dialog from context menu

* initial version complete

* add context menu item to delete game config if it exists

* Create game config from base value instead of default value

* Require confirmation before deleting game configs with menu item

* fix rebase

* Reset game specific values when creating a new game config

* Add icon for entries with game config

* clang format

* Add submenu for game-specific settings

* Log if game-specific config exists, remove hidden tab from tab selection

* Add other experimental options to game-specific GUI

* clang format

* Add flag to specify if game-specific file needs creation

* refactor: remove additional arguments, reset game-specific status on save instead

* Fix return

* cleanup - remove unneeded load

* Set tab to general if hidden tab is set as default

* Cleanup variable names and strings, default tab fix, volumeslider fix

* cleanup: missed a couple of variables to standardize

* More readable way to reset volume slider
This commit is contained in:
rainmakerv2
2025-09-10 17:18:39 +08:00
committed by GitHub
parent 4abc6b3010
commit 319db3bebe
13 changed files with 893 additions and 625 deletions

View File

@@ -74,6 +74,7 @@ path = [
"src/images/youtube.svg", "src/images/youtube.svg",
"src/images/trophy.wav", "src/images/trophy.wav",
"src/images/hotkey.png", "src/images/hotkey.png",
"src/images/game_settings.png",
"src/shadps4.qrc", "src/shadps4.qrc",
"src/shadps4.rc", "src/shadps4.rc",
"src/qt_gui/translations/update_translation.sh", "src/qt_gui/translations/update_translation.sh",

View File

@@ -94,6 +94,18 @@ public:
base_value = toml::get_optional<T>(v, key).value_or(base_value); base_value = toml::get_optional<T>(v, key).value_or(base_value);
} }
} }
void set(const T value, bool is_game_specific = false) {
is_game_specific ? game_specific_value = value : base_value = value;
}
void setTomlValue(toml::ordered_value& data, const std::string& header, const std::string& key,
bool is_game_specific = false) {
if (is_game_specific) {
data[header][key] = game_specific_value.value_or(base_value);
game_specific_value = std::nullopt;
} else {
data[header][key] = base_value;
}
}
// operator T() { // operator T() {
// return get(); // return get();
// } // }
@@ -242,8 +254,8 @@ std::filesystem::path GetSaveDataPath() {
return save_data_path; return save_data_path;
} }
void setVolumeSlider(int volumeValue) { void setVolumeSlider(int volumeValue, bool is_game_specific) {
volumeSlider.base_value = volumeValue; volumeSlider.set(volumeValue, is_game_specific);
} }
void setLoadGameSizeEnabled(bool enable) { void setLoadGameSizeEnabled(bool enable) {
@@ -426,16 +438,16 @@ bool getVkGuestMarkersEnabled() {
return vkGuestMarkers.get(); return vkGuestMarkers.get();
} }
void setVkCrashDiagnosticEnabled(bool enable) { void setVkCrashDiagnosticEnabled(bool enable, bool is_game_specific) {
vkCrashDiagnostic.base_value = enable; vkCrashDiagnostic.set(enable, is_game_specific);
} }
void setVkHostMarkersEnabled(bool enable) { void setVkHostMarkersEnabled(bool enable, bool is_game_specific) {
vkHostMarkers.base_value = enable; vkHostMarkers.set(enable, is_game_specific);
} }
void setVkGuestMarkersEnabled(bool enable) { void setVkGuestMarkersEnabled(bool enable, bool is_game_specific) {
vkGuestMarkers.base_value = enable; vkGuestMarkers.set(enable, is_game_specific);
} }
bool getCompatibilityEnabled() { bool getCompatibilityEnabled() {
@@ -450,16 +462,20 @@ bool getIsConnectedToNetwork() {
return isConnectedToNetwork.get(); return isConnectedToNetwork.get();
} }
void setGpuId(s32 selectedGpuId) { void setConnectedToNetwork(bool enable, bool is_game_specific) {
gpuId.base_value = selectedGpuId; isConnectedToNetwork.set(enable, is_game_specific);
} }
void setWindowWidth(u32 width) { void setGpuId(s32 selectedGpuId, bool is_game_specific) {
windowWidth.base_value = width; gpuId.set(selectedGpuId, is_game_specific);
} }
void setWindowHeight(u32 height) { void setWindowWidth(u32 width, bool is_game_specific) {
windowHeight.base_value = height; windowWidth.set(width, is_game_specific);
}
void setWindowHeight(u32 height, bool is_game_specific) {
windowHeight.set(height, is_game_specific);
} }
void setInternalScreenWidth(u32 width) { void setInternalScreenWidth(u32 width) {
@@ -470,132 +486,136 @@ void setInternalScreenHeight(u32 height) {
internalScreenHeight.base_value = height; internalScreenHeight.base_value = height;
} }
void setDebugDump(bool enable) { void setDebugDump(bool enable, bool is_game_specific) {
isDebugDump.base_value = enable; isDebugDump.set(enable, is_game_specific);
} }
void setLoggingEnabled(bool enable) { void setLoggingEnabled(bool enable, bool is_game_specific) {
logEnabled.base_value = enable; logEnabled.set(enable, is_game_specific);
} }
void setCollectShaderForDebug(bool enable) { void setCollectShaderForDebug(bool enable, bool is_game_specific) {
isShaderDebug.base_value = enable; isShaderDebug.set(enable, is_game_specific);
} }
void setShowSplash(bool enable) { void setShowSplash(bool enable, bool is_game_specific) {
isShowSplash.base_value = enable; isShowSplash.set(enable, is_game_specific);
} }
void setSideTrophy(string side) { void setSideTrophy(string side, bool is_game_specific) {
isSideTrophy.base_value = side; isSideTrophy.set(side, is_game_specific);
} }
void setNullGpu(bool enable) { void setNullGpu(bool enable, bool is_game_specific) {
isNullGpu.base_value = enable; isNullGpu.set(enable, is_game_specific);
} }
void setAllowHDR(bool enable) { void setAllowHDR(bool enable, bool is_game_specific) {
isHDRAllowed.base_value = enable; isHDRAllowed.set(enable, is_game_specific);
} }
void setCopyGPUCmdBuffers(bool enable) { void setCopyGPUCmdBuffers(bool enable, bool is_game_specific) {
shouldCopyGPUBuffers.base_value = enable; shouldCopyGPUBuffers.set(enable, is_game_specific);
} }
void setReadbacks(bool enable) { void setReadbacks(bool enable, bool is_game_specific) {
readbacksEnabled.base_value = enable; readbacksEnabled.set(enable, is_game_specific);
} }
void setReadbackLinearImages(bool enable) { void setReadbackLinearImages(bool enable, bool is_game_specific) {
readbackLinearImagesEnabled.base_value = enable; readbackLinearImagesEnabled.set(enable, is_game_specific);
} }
void setDirectMemoryAccess(bool enable) { void setDirectMemoryAccess(bool enable, bool is_game_specific) {
directMemoryAccessEnabled.base_value = enable; directMemoryAccessEnabled.set(enable, is_game_specific);
} }
void setDumpShaders(bool enable) { void setDumpShaders(bool enable, bool is_game_specific) {
shouldDumpShaders.base_value = enable; shouldDumpShaders.set(enable, is_game_specific);
} }
void setVkValidation(bool enable) { void setVkValidation(bool enable, bool is_game_specific) {
vkValidation.base_value = enable; vkValidation.set(enable, is_game_specific);
} }
void setVkSyncValidation(bool enable) { void setVkSyncValidation(bool enable, bool is_game_specific) {
vkValidationSync.base_value = enable; vkValidationSync.set(enable, is_game_specific);
} }
void setRdocEnabled(bool enable) { void setRdocEnabled(bool enable, bool is_game_specific) {
rdocEnable.base_value = enable; rdocEnable.set(enable, is_game_specific);
} }
void setVblankFreq(u32 value) { void setVblankFreq(u32 value, bool is_game_specific) {
vblankFrequency.base_value = value; vblankFrequency.set(value, is_game_specific);
} }
void setIsFullscreen(bool enable) { void setIsFullscreen(bool enable, bool is_game_specific) {
isFullscreen.base_value = enable; isFullscreen.set(enable, is_game_specific);
} }
void setFullscreenMode(string mode) { void setFullscreenMode(string mode, bool is_game_specific) {
fullscreenMode.base_value = mode; fullscreenMode.set(mode, is_game_specific);
} }
void setPresentMode(std::string mode) { void setPresentMode(std::string mode, bool is_game_specific) {
presentMode.base_value = mode; presentMode.set(mode, is_game_specific);
} }
void setisTrophyPopupDisabled(bool disable) { void setisTrophyPopupDisabled(bool disable, bool is_game_specific) {
isTrophyPopupDisabled.base_value = disable; isTrophyPopupDisabled.set(disable, is_game_specific);
} }
void setEnableDiscordRPC(bool enable) { void setEnableDiscordRPC(bool enable) {
enableDiscordRPC = enable; enableDiscordRPC = enable;
} }
void setCursorState(s16 newCursorState) { void setCursorState(s16 newCursorState, bool is_game_specific) {
cursorState.base_value = newCursorState; cursorState.set(newCursorState, is_game_specific);
} }
void setCursorHideTimeout(int newcursorHideTimeout) { void setCursorHideTimeout(int newcursorHideTimeout, bool is_game_specific) {
cursorHideTimeout.base_value = newcursorHideTimeout; cursorHideTimeout.set(newcursorHideTimeout, is_game_specific);
} }
void setMicDevice(string device) { void setMicDevice(string device, bool is_game_specific) {
micDevice.base_value = device; micDevice.set(device, is_game_specific);
} }
void setTrophyNotificationDuration(double newTrophyNotificationDuration) { void setTrophyNotificationDuration(double newTrophyNotificationDuration, bool is_game_specific) {
trophyNotificationDuration.base_value = newTrophyNotificationDuration; trophyNotificationDuration.set(newTrophyNotificationDuration, is_game_specific);
} }
void setLanguage(u32 language) { void setLanguage(u32 language, bool is_game_specific) {
m_language.base_value = language; m_language.set(language, is_game_specific);
} }
void setNeoMode(bool enable) { void setNeoMode(bool enable, bool is_game_specific) {
isNeo.base_value = enable; isNeo.set(enable, is_game_specific);
} }
void setLogType(const string& type) { void setDevKitConsole(bool enable, bool is_game_specific) {
logType.base_value = type; isDevKit.set(enable, is_game_specific);
} }
void setLogFilter(const string& type) { void setLogType(const string& type, bool is_game_specific) {
logFilter.base_value = type; logType.set(type, is_game_specific);
} }
void setSeparateLogFilesEnabled(bool enabled) { void setLogFilter(const string& type, bool is_game_specific) {
isSeparateLogFilesEnabled.base_value = enabled; logFilter.set(type, is_game_specific);
} }
void setUserName(const string& type) { void setSeparateLogFilesEnabled(bool enabled, bool is_game_specific) {
userName.base_value = type; isSeparateLogFilesEnabled.set(enabled, is_game_specific);
} }
void setChooseHomeTab(const string& type) { void setUserName(const string& name, bool is_game_specific) {
chooseHomeTab.base_value = type; userName.set(name, is_game_specific);
}
void setChooseHomeTab(const string& type, bool is_game_specific) {
chooseHomeTab.set(type, is_game_specific);
} }
void setUseSpecialPad(bool use) { void setUseSpecialPad(bool use) {
@@ -606,8 +626,8 @@ void setSpecialPadClass(int type) {
specialPadClass.base_value = type; specialPadClass.base_value = type;
} }
void setIsMotionControlsEnabled(bool use) { void setIsMotionControlsEnabled(bool use, bool is_game_specific) {
isMotionControlsEnabled.base_value = use; isMotionControlsEnabled.set(use, is_game_specific);
} }
void setCompatibilityEnabled(bool use) { void setCompatibilityEnabled(bool use) {
@@ -703,8 +723,8 @@ bool getPSNSignedIn() {
return isPSNSignedIn.get(); return isPSNSignedIn.get();
} }
void setPSNSignedIn(bool sign) { void setPSNSignedIn(bool sign, bool is_game_specific) {
isPSNSignedIn.base_value = sign; isPSNSignedIn.set(sign, is_game_specific);
} }
string getDefaultControllerID() { string getDefaultControllerID() {
@@ -719,32 +739,32 @@ bool getBackgroundControllerInput() {
return backgroundControllerInput.get(); return backgroundControllerInput.get();
} }
void setBackgroundControllerInput(bool enable) { void setBackgroundControllerInput(bool enable, bool is_game_specific) {
backgroundControllerInput.base_value = enable; backgroundControllerInput.set(enable, is_game_specific);
} }
bool getFsrEnabled() { bool getFsrEnabled() {
return fsrEnabled.get(); return fsrEnabled.get();
} }
void setFsrEnabled(bool enable) { void setFsrEnabled(bool enable, bool is_game_specific) {
fsrEnabled.base_value = enable; fsrEnabled.set(enable, is_game_specific);
} }
bool getRcasEnabled() { bool getRcasEnabled() {
return rcasEnabled.get(); return rcasEnabled.get();
} }
void setRcasEnabled(bool enable) { void setRcasEnabled(bool enable, bool is_game_specific) {
rcasEnabled.base_value = enable; rcasEnabled.set(enable, is_game_specific);
} }
int getRcasAttenuation() { int getRcasAttenuation() {
return rcasAttenuation.get(); return rcasAttenuation.get();
} }
void setRcasAttenuation(int value) { void setRcasAttenuation(int value, bool is_game_specific) {
rcasAttenuation.base_value = value; rcasAttenuation.set(value, is_game_specific);
} }
void load(const std::filesystem::path& path, bool is_game_specific) { void load(const std::filesystem::path& path, bool is_game_specific) {
@@ -934,7 +954,7 @@ void sortTomlSections(toml::ordered_value& data) {
data = ordered_data; data = ordered_data;
} }
void save(const std::filesystem::path& path) { void save(const std::filesystem::path& path, bool is_game_specific) {
toml::ordered_value data; toml::ordered_value data;
std::error_code error; std::error_code error;
@@ -956,66 +976,65 @@ void save(const std::filesystem::path& path) {
fmt::print("Saving new configuration file {}\n", fmt::UTF(path.u8string())); fmt::print("Saving new configuration file {}\n", fmt::UTF(path.u8string()));
} }
data["General"]["volumeSlider"] = volumeSlider.base_value; // Entries saved by the game-specific settings GUI
data["General"]["isPS4Pro"] = isNeo.base_value; volumeSlider.setTomlValue(data, "General", "volumeSlider", is_game_specific);
data["General"]["isDevKit"] = isDevKit.base_value; isTrophyPopupDisabled.setTomlValue(data, "General", "isTrophyPopupDisabled", is_game_specific);
data["General"]["isPSNSignedIn"] = isPSNSignedIn.base_value; trophyNotificationDuration.setTomlValue(data, "General", "trophyNotificationDuration",
data["General"]["isTrophyPopupDisabled"] = isTrophyPopupDisabled.base_value; is_game_specific);
data["General"]["trophyNotificationDuration"] = trophyNotificationDuration.base_value; logFilter.setTomlValue(data, "General", "logFilter", is_game_specific);
data["General"]["logFilter"] = logFilter.base_value; logType.setTomlValue(data, "General", "logType", is_game_specific);
data["General"]["logType"] = logType.base_value; userName.setTomlValue(data, "General", "userName", is_game_specific);
data["General"]["userName"] = userName.base_value; chooseHomeTab.setTomlValue(data, "General", "chooseHomeTab", is_game_specific);
data["General"]["chooseHomeTab"] = chooseHomeTab.base_value; isShowSplash.setTomlValue(data, "General", "showSplash", is_game_specific);
data["General"]["showSplash"] = isShowSplash.base_value; isSideTrophy.setTomlValue(data, "General", "sideTrophy", is_game_specific);
data["General"]["sideTrophy"] = isSideTrophy.base_value; isNeo.setTomlValue(data, "General", "isPS4Pro", is_game_specific);
data["General"]["isConnectedToNetwork"] = isConnectedToNetwork.base_value; isDevKit.setTomlValue(data, "General", "isDevKit", is_game_specific);
data["General"]["defaultControllerID"] = defaultControllerID.base_value; isPSNSignedIn.setTomlValue(data, "General", "isPSNSignedIn", is_game_specific);
data["General"]["enableDiscordRPC"] = enableDiscordRPC; isConnectedToNetwork.setTomlValue(data, "General", "isConnectedToNetwork", is_game_specific);
data["General"]["compatibilityEnabled"] = compatibilityData;
data["General"]["checkCompatibilityOnStartup"] = checkCompatibilityOnStartup;
data["Input"]["cursorState"] = cursorState.base_value;
data["Input"]["cursorHideTimeout"] = cursorHideTimeout.base_value;
data["Input"]["useSpecialPad"] = useSpecialPad.base_value;
data["Input"]["specialPadClass"] = specialPadClass.base_value;
data["Input"]["isMotionControlsEnabled"] = isMotionControlsEnabled.base_value;
data["Input"]["useUnifiedInputConfig"] = useUnifiedInputConfig.base_value;
data["Input"]["micDevice"] = micDevice.base_value;
data["Input"]["backgroundControllerInput"] = backgroundControllerInput.base_value;
data["GPU"]["screenWidth"] = windowWidth.base_value;
data["GPU"]["screenHeight"] = windowHeight.base_value;
data["GPU"]["internalScreenWidth"] = internalScreenWidth.base_value;
data["GPU"]["internalScreenHeight"] = internalScreenHeight.base_value;
data["GPU"]["nullGpu"] = isNullGpu.base_value;
data["GPU"]["copyGPUBuffers"] = shouldCopyGPUBuffers.base_value;
data["GPU"]["readbacks"] = readbacksEnabled.base_value;
data["GPU"]["readbackLinearImages"] = readbackLinearImagesEnabled.base_value;
data["GPU"]["directMemoryAccess"] = directMemoryAccessEnabled.base_value;
data["GPU"]["dumpShaders"] = shouldDumpShaders.base_value;
data["GPU"]["patchShaders"] = shouldPatchShaders.base_value;
data["GPU"]["vblankFrequency"] = vblankFrequency.base_value;
data["GPU"]["Fullscreen"] = isFullscreen.base_value;
data["GPU"]["FullscreenMode"] = fullscreenMode.base_value;
data["GPU"]["presentMode"] = presentMode.base_value;
data["GPU"]["allowHDR"] = isHDRAllowed.base_value;
data["GPU"]["fsrEnabled"] = fsrEnabled.base_value;
data["GPU"]["rcasEnabled"] = rcasEnabled.base_value;
data["GPU"]["rcasAttenuation"] = rcasAttenuation.base_value;
data["Vulkan"]["gpuId"] = gpuId.base_value;
data["Vulkan"]["validation"] = vkValidation.base_value;
data["Vulkan"]["validation_sync"] = vkValidationSync.base_value;
data["Vulkan"]["validation_gpu"] = vkValidationGpu.base_value;
data["Vulkan"]["crashDiagnostic"] = vkCrashDiagnostic.base_value;
data["Vulkan"]["hostMarkers"] = vkHostMarkers.base_value;
data["Vulkan"]["guestMarkers"] = vkGuestMarkers.base_value;
data["Vulkan"]["rdocEnable"] = rdocEnable.base_value;
data["Debug"]["DebugDump"] = isDebugDump.base_value;
data["Debug"]["CollectShader"] = isShaderDebug.base_value;
data["Debug"]["isSeparateLogFilesEnabled"] = isSeparateLogFilesEnabled.base_value;
data["Debug"]["FPSColor"] = isFpsColor.base_value;
data["Debug"]["logEnabled"] = logEnabled.base_value;
data["Debug"]["ConfigVersion"] = config_version;
data["Keys"]["TrophyKey"] = trophyKey;
cursorState.setTomlValue(data, "Input", "cursorState", is_game_specific);
cursorHideTimeout.setTomlValue(data, "Input", "cursorHideTimeout", is_game_specific);
isMotionControlsEnabled.setTomlValue(data, "Input", "isMotionControlsEnabled",
is_game_specific);
micDevice.setTomlValue(data, "Input", "micDevice", is_game_specific);
backgroundControllerInput.setTomlValue(data, "Input", "backgroundControllerInput",
is_game_specific);
windowWidth.setTomlValue(data, "GPU", "screenWidth", is_game_specific);
windowHeight.setTomlValue(data, "GPU", "screenHeight", is_game_specific);
isNullGpu.setTomlValue(data, "GPU", "nullGpu", is_game_specific);
shouldCopyGPUBuffers.setTomlValue(data, "GPU", "copyGPUBuffers", is_game_specific);
readbacksEnabled.setTomlValue(data, "GPU", "readbacks", is_game_specific);
readbackLinearImagesEnabled.setTomlValue(data, "GPU", "readbackLinearImages", is_game_specific);
shouldDumpShaders.setTomlValue(data, "GPU", "dumpShaders", is_game_specific);
vblankFrequency.setTomlValue(data, "GPU", "vblankFrequency", is_game_specific);
isFullscreen.setTomlValue(data, "GPU", "Fullscreen", is_game_specific);
fullscreenMode.setTomlValue(data, "GPU", "FullscreenMode", is_game_specific);
presentMode.setTomlValue(data, "GPU", "presentMode", is_game_specific);
isHDRAllowed.setTomlValue(data, "GPU", "allowHDR", is_game_specific);
fsrEnabled.setTomlValue(data, "GPU", "fsrEnabled", is_game_specific);
rcasEnabled.setTomlValue(data, "GPU", "rcasEnabled", is_game_specific);
rcasAttenuation.setTomlValue(data, "GPU", "rcasAttenuation", is_game_specific);
directMemoryAccessEnabled.setTomlValue(data, "GPU", "directMemoryAccess", is_game_specific);
gpuId.setTomlValue(data, "Vulkan", "gpuId", is_game_specific);
vkValidation.setTomlValue(data, "Vulkan", "validation", is_game_specific);
vkValidationSync.setTomlValue(data, "Vulkan", "validation_sync", is_game_specific);
vkCrashDiagnostic.setTomlValue(data, "Vulkan", "crashDiagnostic", is_game_specific);
vkHostMarkers.setTomlValue(data, "Vulkan", "hostMarkers", is_game_specific);
vkGuestMarkers.setTomlValue(data, "Vulkan", "guestMarkers", is_game_specific);
rdocEnable.setTomlValue(data, "Vulkan", "rdocEnable", is_game_specific);
isDebugDump.setTomlValue(data, "Debug", "DebugDump", is_game_specific);
isShaderDebug.setTomlValue(data, "Debug", "CollectShader", is_game_specific);
isSeparateLogFilesEnabled.setTomlValue(data, "Debug", "isSeparateLogFilesEnabled",
is_game_specific);
logEnabled.setTomlValue(data, "Debug", "logEnable", is_game_specific);
m_language.setTomlValue(data, "Settings", "consoleLanguage", is_game_specific);
// All other entries
if (!is_game_specific) {
std::vector<string> install_dirs; std::vector<string> install_dirs;
std::vector<bool> install_dirs_enabled; std::vector<bool> install_dirs_enabled;
@@ -1027,14 +1046,17 @@ void save(const std::filesystem::path& path) {
std::vector<DirEntry> sorted_dirs; std::vector<DirEntry> sorted_dirs;
for (const auto& dirInfo : settings_install_dirs) { for (const auto& dirInfo : settings_install_dirs) {
sorted_dirs.push_back({string{fmt::UTF(dirInfo.path.u8string()).data}, dirInfo.enabled}); sorted_dirs.push_back(
{string{fmt::UTF(dirInfo.path.u8string()).data}, dirInfo.enabled});
} }
// Sort directories alphabetically // Sort directories alphabetically
std::sort(sorted_dirs.begin(), sorted_dirs.end(), [](const DirEntry& a, const DirEntry& b) { std::sort(sorted_dirs.begin(), sorted_dirs.end(), [](const DirEntry& a, const DirEntry& b) {
return std::lexicographical_compare( return std::lexicographical_compare(
a.path_str.begin(), a.path_str.end(), b.path_str.begin(), b.path_str.end(), a.path_str.begin(), a.path_str.end(), b.path_str.begin(), b.path_str.end(),
[](char a_char, char b_char) { return std::tolower(a_char) < std::tolower(b_char); }); [](char a_char, char b_char) {
return std::tolower(a_char) < std::tolower(b_char);
});
}); });
for (const auto& entry : sorted_dirs) { for (const auto& entry : sorted_dirs) {
@@ -1042,13 +1064,35 @@ void save(const std::filesystem::path& path) {
install_dirs_enabled.push_back(entry.enabled); install_dirs_enabled.push_back(entry.enabled);
} }
// Non game-specific entries
data["General"]["enableDiscordRPC"] = enableDiscordRPC;
data["General"]["compatibilityEnabled"] = compatibilityData;
data["General"]["checkCompatibilityOnStartup"] = checkCompatibilityOnStartup;
data["GUI"]["installDirs"] = install_dirs; data["GUI"]["installDirs"] = install_dirs;
data["GUI"]["installDirsEnabled"] = install_dirs_enabled; data["GUI"]["installDirsEnabled"] = install_dirs_enabled;
data["GUI"]["saveDataPath"] = string{fmt::UTF(save_data_path.u8string()).data}; data["GUI"]["saveDataPath"] = string{fmt::UTF(save_data_path.u8string()).data};
data["GUI"]["loadGameSizeEnabled"] = load_game_size; data["GUI"]["loadGameSizeEnabled"] = load_game_size;
data["GUI"]["addonInstallDir"] =
string{fmt::UTF(settings_addon_install_dir.u8string()).data};
data["GUI"]["addonInstallDir"] = string{fmt::UTF(settings_addon_install_dir.u8string()).data}; data["Debug"]["ConfigVersion"] = config_version;
data["Settings"]["consoleLanguage"] = m_language.base_value; data["Keys"]["TrophyKey"] = trophyKey;
// Do not save these entries in the game-specific dialog since they are not in the GUI
data["General"]["defaultControllerID"] = defaultControllerID.base_value;
data["Input"]["useSpecialPad"] = useSpecialPad.base_value;
data["Input"]["specialPadClass"] = specialPadClass.base_value;
data["Input"]["useUnifiedInputConfig"] = useUnifiedInputConfig.base_value;
data["GPU"]["internalScreenWidth"] = internalScreenWidth.base_value;
data["GPU"]["internalScreenHeight"] = internalScreenHeight.base_value;
data["GPU"]["patchShaders"] = shouldPatchShaders.base_value;
data["Vulkan"]["validation_gpu"] = vkValidationGpu.base_value;
data["Debug"]["FPSColor"] = isFpsColor.base_value;
}
// Sorting of TOML sections // Sorting of TOML sections
sortTomlSections(data); sortTomlSections(data);
@@ -1058,82 +1102,101 @@ void save(const std::filesystem::path& path) {
file.close(); file.close();
} }
void setDefaultValues() { void setDefaultValues(bool is_game_specific) {
// Entries with game-specific settings that are in the game-specific setings GUI but not in
// the global settings GUI
if (is_game_specific) {
isNeo.set(false, is_game_specific);
isDevKit.set(false, is_game_specific);
isPSNSignedIn.set(false, is_game_specific);
isConnectedToNetwork.set(false, is_game_specific);
directMemoryAccessEnabled.set(false, is_game_specific);
}
// Entries with game-specific settings that are in both the game-specific and global GUI
// GS - General
volumeSlider.set(100, is_game_specific);
isTrophyPopupDisabled.set(false, is_game_specific);
trophyNotificationDuration.set(6.0, is_game_specific);
logFilter.set("", is_game_specific);
logType.set("sync", is_game_specific);
userName.set("shadPS4", is_game_specific);
chooseHomeTab.set("General", is_game_specific);
isShowSplash.set(false, is_game_specific);
isSideTrophy.set("right", is_game_specific);
// GS - Input
cursorState.set(HideCursorState::Idle, is_game_specific);
cursorHideTimeout.set(5, is_game_specific);
isMotionControlsEnabled.set(true, is_game_specific);
micDevice.set("Default Device", is_game_specific);
backgroundControllerInput.set(false, is_game_specific);
// GS - GPU
windowWidth.set(1280, is_game_specific);
windowHeight.set(720, is_game_specific);
isNullGpu.set(false, is_game_specific);
shouldCopyGPUBuffers.set(false, is_game_specific);
readbacksEnabled.set(false, is_game_specific);
readbackLinearImagesEnabled.set(false, is_game_specific);
shouldDumpShaders.set(false, is_game_specific);
vblankFrequency.set(60, is_game_specific);
isFullscreen.set(false, is_game_specific);
fullscreenMode.set("Windowed", is_game_specific);
presentMode.set("Mailbox", is_game_specific);
isHDRAllowed.set(false, is_game_specific);
fsrEnabled.set(true, is_game_specific);
rcasEnabled.set(true, is_game_specific);
rcasAttenuation.set(250, is_game_specific);
// GS - Vulkan
gpuId.set(-1, is_game_specific);
vkValidation.set(false, is_game_specific);
vkValidationSync.set(false, is_game_specific);
vkValidationGpu.set(false, is_game_specific);
vkCrashDiagnostic.set(false, is_game_specific);
vkHostMarkers.set(false, is_game_specific);
vkGuestMarkers.set(false, is_game_specific);
rdocEnable.set(false, is_game_specific);
// GS - Debug
isDebugDump.set(false, is_game_specific);
isShaderDebug.set(false, is_game_specific);
isSeparateLogFilesEnabled.set(false, is_game_specific);
logEnabled.set(true, is_game_specific);
// GS - Settings
m_language.set(1, is_game_specific);
// All other entries
if (!is_game_specific) {
// General // General
volumeSlider = 100;
isNeo = false;
isDevKit = false;
isPSNSignedIn = false;
isTrophyPopupDisabled = false;
trophyNotificationDuration = 6.0;
enableDiscordRPC = false; enableDiscordRPC = false;
logFilter = "";
logType = "sync";
userName = "shadPS4";
chooseHomeTab = "General";
isShowSplash = false;
isSideTrophy = "right";
compatibilityData = false; compatibilityData = false;
checkCompatibilityOnStartup = false; checkCompatibilityOnStartup = false;
isConnectedToNetwork = false;
// Input // Input
cursorState = HideCursorState::Idle; useSpecialPad.base_value = false;
cursorHideTimeout = 5; specialPadClass.base_value = 1;
useSpecialPad = false; useUnifiedInputConfig.base_value = true;
specialPadClass = 1;
isMotionControlsEnabled = true;
useUnifiedInputConfig = true;
overrideControllerColor = false; overrideControllerColor = false;
controllerCustomColorRGB[0] = 0; controllerCustomColorRGB[0] = 0;
controllerCustomColorRGB[1] = 0; controllerCustomColorRGB[1] = 0;
controllerCustomColorRGB[2] = 255; controllerCustomColorRGB[2] = 255;
micDevice = "Default Device";
backgroundControllerInput = false;
// GPU // GPU
windowWidth = 1280; shouldPatchShaders.base_value = false;
windowHeight = 720; internalScreenWidth.base_value = 1280;
internalScreenWidth = 1280; internalScreenHeight.base_value = 720;
internalScreenHeight = 720;
isNullGpu = false;
shouldCopyGPUBuffers = false;
readbacksEnabled = false;
readbackLinearImagesEnabled = false;
directMemoryAccessEnabled = false;
shouldDumpShaders = false;
shouldPatchShaders = false;
vblankFrequency = 60;
isFullscreen = false;
fullscreenMode = "Windowed";
presentMode = "Mailbox";
isHDRAllowed = false;
fsrEnabled = true;
rcasEnabled = true;
rcasAttenuation = 250;
// Vulkan
gpuId = -1;
vkValidation = false;
vkValidationSync = false;
vkValidationGpu = false;
vkCrashDiagnostic = false;
vkHostMarkers = false;
vkGuestMarkers = false;
rdocEnable = false;
// Debug
isDebugDump = false;
isShaderDebug = false;
isSeparateLogFilesEnabled = false;
isFpsColor = true;
logEnabled = true;
// GUI // GUI
load_game_size = true; load_game_size = true;
// Settings // Debug
m_language = 1; isFpsColor.base_value = true;
}
} }
constexpr std::string_view GetDefaultGlobalConfig() { constexpr std::string_view GetDefaultGlobalConfig() {
@@ -1272,4 +1335,10 @@ std::filesystem::path GetFoolproofInputConfigFile(const string& game_id) {
return config_file; return config_file;
} }
void resetGameSpecificValue(std::string entry) {
if (entry == "volumeSlider") {
volumeSlider.game_specific_value = std::nullopt;
}
}
} // namespace Config } // namespace Config

View File

@@ -17,110 +17,118 @@ struct GameInstallDir {
enum HideCursorState : int { Never, Idle, Always }; enum HideCursorState : int { Never, Idle, Always };
void load(const std::filesystem::path& path, bool is_game_specific = false); void load(const std::filesystem::path& path, bool is_game_specific = false);
void save(const std::filesystem::path& path); void save(const std::filesystem::path& path, bool is_game_specific = false);
void resetGameSpecificValue(std::string entry);
int getVolumeSlider(); int getVolumeSlider();
void setVolumeSlider(int volumeValue); void setVolumeSlider(int volumeValue, bool is_game_specific = false);
std::string getTrophyKey(); std::string getTrophyKey();
void setTrophyKey(std::string key); void setTrophyKey(std::string key);
bool getIsFullscreen(); bool getIsFullscreen();
void setIsFullscreen(bool enable); void setIsFullscreen(bool enable, bool is_game_specific = false);
std::string getFullscreenMode(); std::string getFullscreenMode();
void setFullscreenMode(std::string mode); void setFullscreenMode(std::string mode, bool is_game_specific = false);
std::string getPresentMode(); std::string getPresentMode();
void setPresentMode(std::string mode); void setPresentMode(std::string mode, bool is_game_specific = false);
u32 getWindowWidth(); u32 getWindowWidth();
u32 getWindowHeight(); u32 getWindowHeight();
void setWindowWidth(u32 width); void setWindowWidth(u32 width, bool is_game_specific = false);
void setWindowHeight(u32 height); void setWindowHeight(u32 height, bool is_game_specific = false);
u32 getInternalScreenWidth(); u32 getInternalScreenWidth();
u32 getInternalScreenHeight(); u32 getInternalScreenHeight();
void setInternalScreenWidth(u32 width); void setInternalScreenWidth(u32 width);
void setInternalScreenHeight(u32 height); void setInternalScreenHeight(u32 height);
bool debugDump(); bool debugDump();
void setDebugDump(bool enable); void setDebugDump(bool enable, bool is_game_specific = false);
s32 getGpuId(); s32 getGpuId();
void setGpuId(s32 selectedGpuId); void setGpuId(s32 selectedGpuId, bool is_game_specific = false);
bool allowHDR(); bool allowHDR();
void setAllowHDR(bool enable); void setAllowHDR(bool enable, bool is_game_specific = false);
bool collectShadersForDebug(); bool collectShadersForDebug();
void setCollectShaderForDebug(bool enable); void setCollectShaderForDebug(bool enable, bool is_game_specific = false);
bool showSplash(); bool showSplash();
void setShowSplash(bool enable); void setShowSplash(bool enable, bool is_game_specific = false);
std::string sideTrophy(); std::string sideTrophy();
void setSideTrophy(std::string side); void setSideTrophy(std::string side, bool is_game_specific = false);
bool nullGpu(); bool nullGpu();
void setNullGpu(bool enable); void setNullGpu(bool enable, bool is_game_specific = false);
bool copyGPUCmdBuffers(); bool copyGPUCmdBuffers();
void setCopyGPUCmdBuffers(bool enable); void setCopyGPUCmdBuffers(bool enable, bool is_game_specific = false);
bool readbacks(); bool readbacks();
void setReadbacks(bool enable); void setReadbacks(bool enable, bool is_game_specific = false);
bool readbackLinearImages(); bool readbackLinearImages();
void setReadbackLinearImages(bool enable); void setReadbackLinearImages(bool enable, bool is_game_specific = false);
bool directMemoryAccess(); bool directMemoryAccess();
void setDirectMemoryAccess(bool enable); void setDirectMemoryAccess(bool enable, bool is_game_specific = false);
bool dumpShaders(); bool dumpShaders();
void setDumpShaders(bool enable); void setDumpShaders(bool enable, bool is_game_specific = false);
u32 vblankFreq(); u32 vblankFreq();
void setVblankFreq(u32 value); void setVblankFreq(u32 value, bool is_game_specific = false);
bool getisTrophyPopupDisabled(); bool getisTrophyPopupDisabled();
void setisTrophyPopupDisabled(bool disable); void setisTrophyPopupDisabled(bool disable, bool is_game_specific = false);
s16 getCursorState(); s16 getCursorState();
void setCursorState(s16 cursorState); void setCursorState(s16 cursorState, bool is_game_specific = false);
bool vkValidationEnabled(); bool vkValidationEnabled();
void setVkValidation(bool enable); void setVkValidation(bool enable, bool is_game_specific = false);
bool vkValidationSyncEnabled(); bool vkValidationSyncEnabled();
void setVkSyncValidation(bool enable); void setVkSyncValidation(bool enable, bool is_game_specific = false);
bool getVkCrashDiagnosticEnabled(); bool getVkCrashDiagnosticEnabled();
void setVkCrashDiagnosticEnabled(bool enable); void setVkCrashDiagnosticEnabled(bool enable, bool is_game_specific = false);
bool getVkHostMarkersEnabled(); bool getVkHostMarkersEnabled();
void setVkHostMarkersEnabled(bool enable); void setVkHostMarkersEnabled(bool enable, bool is_game_specific = false);
bool getVkGuestMarkersEnabled(); bool getVkGuestMarkersEnabled();
void setVkGuestMarkersEnabled(bool enable); void setVkGuestMarkersEnabled(bool enable, bool is_game_specific = false);
bool getEnableDiscordRPC(); bool getEnableDiscordRPC();
void setEnableDiscordRPC(bool enable); void setEnableDiscordRPC(bool enable);
bool isRdocEnabled(); bool isRdocEnabled();
void setRdocEnabled(bool enable); void setRdocEnabled(bool enable, bool is_game_specific = false);
std::string getLogType(); std::string getLogType();
void setLogType(const std::string& type); void setLogType(const std::string& type, bool is_game_specific = false);
std::string getLogFilter(); std::string getLogFilter();
void setLogFilter(const std::string& type); void setLogFilter(const std::string& type, bool is_game_specific = false);
double getTrophyNotificationDuration(); double getTrophyNotificationDuration();
void setTrophyNotificationDuration(double newTrophyNotificationDuration); void setTrophyNotificationDuration(double newTrophyNotificationDuration,
bool is_game_specific = false);
int getCursorHideTimeout(); int getCursorHideTimeout();
std::string getMicDevice(); std::string getMicDevice();
void setCursorHideTimeout(int newcursorHideTimeout); void setCursorHideTimeout(int newcursorHideTimeout, bool is_game_specific = false);
void setMicDevice(std::string device); void setMicDevice(std::string device, bool is_game_specific = false);
void setSeparateLogFilesEnabled(bool enabled); void setSeparateLogFilesEnabled(bool enabled, bool is_game_specific = false);
bool getSeparateLogFilesEnabled(); bool getSeparateLogFilesEnabled();
u32 GetLanguage(); u32 GetLanguage();
void setLanguage(u32 language); void setLanguage(u32 language, bool is_game_specific = false);
void setUseSpecialPad(bool use); void setUseSpecialPad(bool use);
bool getUseSpecialPad(); bool getUseSpecialPad();
void setSpecialPadClass(int type); void setSpecialPadClass(int type);
int getSpecialPadClass(); int getSpecialPadClass();
bool getPSNSignedIn(); bool getPSNSignedIn();
void setPSNSignedIn(bool sign); // no ui setting void setPSNSignedIn(bool sign, bool is_game_specific = false);
bool patchShaders(); // no set bool patchShaders(); // no set
bool fpsColor(); // no set bool fpsColor(); // no set
bool isNeoModeConsole(); bool isNeoModeConsole();
void setNeoMode(bool enable); // no ui setting void setNeoMode(bool enable, bool is_game_specific = false);
bool isDevKitConsole(); // no set bool isDevKitConsole();
void setDevKitConsole(bool enable, bool is_game_specific = false);
bool vkValidationGpuEnabled(); // no set bool vkValidationGpuEnabled(); // no set
bool getIsMotionControlsEnabled(); bool getIsMotionControlsEnabled();
void setIsMotionControlsEnabled(bool use); void setIsMotionControlsEnabled(bool use, bool is_game_specific = false);
std::string getDefaultControllerID(); std::string getDefaultControllerID();
void setDefaultControllerID(std::string id); void setDefaultControllerID(std::string id);
bool getBackgroundControllerInput(); bool getBackgroundControllerInput();
void setBackgroundControllerInput(bool enable); void setBackgroundControllerInput(bool enable, bool is_game_specific = false);
bool getLoggingEnabled(); bool getLoggingEnabled();
void setLoggingEnabled(bool enable); void setLoggingEnabled(bool enable, bool is_game_specific = false);
bool getFsrEnabled(); bool getFsrEnabled();
void setFsrEnabled(bool enable); void setFsrEnabled(bool enable, bool is_game_specific = false);
bool getRcasEnabled(); bool getRcasEnabled();
void setRcasEnabled(bool enable); void setRcasEnabled(bool enable, bool is_game_specific = false);
int getRcasAttenuation(); int getRcasAttenuation();
void setRcasAttenuation(int value); void setRcasAttenuation(int value, bool is_game_specific = false);
bool getIsConnectedToNetwork();
void setConnectedToNetwork(bool enable, bool is_game_specific = false);
void setUserName(const std::string& name, bool is_game_specific = false);
void setChooseHomeTab(const std::string& type, bool is_game_specific = false);
// TODO // TODO
bool GetLoadGameSizeEnabled(); bool GetLoadGameSizeEnabled();
@@ -128,7 +136,6 @@ std::filesystem::path GetSaveDataPath();
void setLoadGameSizeEnabled(bool enable); void setLoadGameSizeEnabled(bool enable);
bool getCompatibilityEnabled(); bool getCompatibilityEnabled();
bool getCheckCompatibilityOnStartup(); bool getCheckCompatibilityOnStartup();
bool getIsConnectedToNetwork();
std::string getUserName(); std::string getUserName();
std::string getChooseHomeTab(); std::string getChooseHomeTab();
bool GetUseUnifiedInputConfig(); bool GetUseUnifiedInputConfig();
@@ -137,8 +144,6 @@ bool GetOverrideControllerColor();
void SetOverrideControllerColor(bool enable); void SetOverrideControllerColor(bool enable);
int* GetControllerCustomColor(); int* GetControllerCustomColor();
void SetControllerCustomColor(int r, int b, int g); void SetControllerCustomColor(int r, int b, int g);
void setUserName(const std::string& type);
void setChooseHomeTab(const std::string& type);
void setGameInstallDirs(const std::vector<std::filesystem::path>& dirs_config); void setGameInstallDirs(const std::vector<std::filesystem::path>& dirs_config);
void setAllGameInstallDirs(const std::vector<GameInstallDir>& dirs_config); void setAllGameInstallDirs(const std::vector<GameInstallDir>& dirs_config);
void setSaveDataPath(const std::filesystem::path& path); void setSaveDataPath(const std::filesystem::path& path);
@@ -154,7 +159,7 @@ const std::vector<std::filesystem::path> getGameInstallDirs();
const std::vector<bool> getGameInstallDirsEnabled(); const std::vector<bool> getGameInstallDirsEnabled();
std::filesystem::path getAddonInstallDir(); std::filesystem::path getAddonInstallDir();
void setDefaultValues(); void setDefaultValues(bool is_game_specific = false);
constexpr std::string_view GetDefaultGlobalConfig(); constexpr std::string_view GetDefaultGlobalConfig();
std::filesystem::path GetFoolproofInputConfigFile(const std::string& game_id = ""); std::filesystem::path GetFoolproofInputConfigFile(const std::string& game_id = "");

View File

@@ -136,8 +136,13 @@ void Emulator::Run(std::filesystem::path file, const std::vector<std::string> ar
LOG_INFO(Loader, "Description {}", Common::g_scm_desc); LOG_INFO(Loader, "Description {}", Common::g_scm_desc);
LOG_INFO(Loader, "Remote {}", Common::g_scm_remote_url); LOG_INFO(Loader, "Remote {}", Common::g_scm_remote_url);
const bool has_game_config = std::filesystem::exists(
Common::FS::GetUserPath(Common::FS::PathType::CustomConfigs) / (id + ".toml"));
LOG_INFO(Config, "Game-specific config exists: {}", has_game_config);
LOG_INFO(Config, "General LogType: {}", Config::getLogType()); LOG_INFO(Config, "General LogType: {}", Config::getLogType());
LOG_INFO(Config, "General isNeo: {}", Config::isNeoModeConsole()); LOG_INFO(Config, "General isNeo: {}", Config::isNeoModeConsole());
LOG_INFO(Config, "General isDevKit: {}", Config::isDevKitConsole());
LOG_INFO(Config, "General isConnectedToNetwork: {}", Config::getIsConnectedToNetwork()); LOG_INFO(Config, "General isConnectedToNetwork: {}", Config::getIsConnectedToNetwork());
LOG_INFO(Config, "General isPsnSignedIn: {}", Config::getPSNSignedIn()); LOG_INFO(Config, "General isPsnSignedIn: {}", Config::getPSNSignedIn());
LOG_INFO(Config, "GPU isNullGpu: {}", Config::nullGpu()); LOG_INFO(Config, "GPU isNullGpu: {}", Config::nullGpu());

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -126,6 +126,7 @@ void GameGridFrame::PopulateGameGrid(QVector<GameInfo> m_games_search, bool from
image_label->setPixmap(QPixmap::fromImage(icon)); image_label->setPixmap(QPixmap::fromImage(icon));
image_label->move(0, 0); image_label->move(0, 0);
SetFavoriteIcon(image_container, m_games_, gameCounter); SetFavoriteIcon(image_container, m_games_, gameCounter);
SetGameConfigIcon(image_container, m_games_, gameCounter);
QLabel* name_label = new QLabel(QString::fromStdString(m_games_[gameCounter].serial)); QLabel* name_label = new QLabel(QString::fromStdString(m_games_[gameCounter].serial));
name_label->setAlignment(Qt::AlignHCenter); name_label->setAlignment(Qt::AlignHCenter);
@@ -254,6 +255,23 @@ void GameGridFrame::SetFavoriteIcon(QWidget* parentWidget, QVector<GameInfo> m_g
label->setObjectName("favoriteIcon"); label->setObjectName("favoriteIcon");
} }
void GameGridFrame::SetGameConfigIcon(QWidget* parentWidget, QVector<GameInfo> m_games_,
int gameCounter) {
std::string serialStr = m_games_[gameCounter].serial;
bool hasGameConfig = std::filesystem::exists(
Common::FS::GetUserPath(Common::FS::PathType::CustomConfigs) / (serialStr + ".toml"));
QLabel* label = new QLabel(parentWidget);
label->setPixmap(QPixmap(":images/game_settings.png")
.scaled(icon_size / 3.8, icon_size / 3.8, Qt::KeepAspectRatio,
Qt::SmoothTransformation));
label->move(2, 2);
label->raise();
label->setVisible(hasGameConfig);
label->setObjectName("gameConfigIcon");
}
void GameGridFrame::SortByFavorite(QVector<GameInfo>* game_list) { void GameGridFrame::SortByFavorite(QVector<GameInfo>* game_list) {
std::sort(game_list->begin(), game_list->end(), [this](const GameInfo& a, const GameInfo& b) { std::sort(game_list->begin(), game_list->end(), [this](const GameInfo& a, const GameInfo& b) {
return this->CompareWithFavorite(a, b); return this->CompareWithFavorite(a, b);

View File

@@ -40,6 +40,7 @@ private:
std::filesystem::path m_current_game_path; // Track current game path to detect changes std::filesystem::path m_current_game_path; // Track current game path to detect changes
std::shared_ptr<gui_settings> m_gui_settings; std::shared_ptr<gui_settings> m_gui_settings;
void SetFavoriteIcon(QWidget* parentWidget, QVector<GameInfo> m_games_, int gameCounter); void SetFavoriteIcon(QWidget* parentWidget, QVector<GameInfo> m_games_, int gameCounter);
void SetGameConfigIcon(QWidget* parentWidget, QVector<GameInfo> m_games_, int gameCounter);
bool CompareWithFavorite(GameInfo a, GameInfo b); bool CompareWithFavorite(GameInfo a, GameInfo b);
public: public:

View File

@@ -83,10 +83,7 @@ GameListFrame::GameListFrame(std::shared_ptr<gui_settings> gui_settings,
connect(this, &QTableWidget::customContextMenuRequested, this, [=, this](const QPoint& pos) { connect(this, &QTableWidget::customContextMenuRequested, this, [=, this](const QPoint& pos) {
int changedFavorite = m_gui_context_menus.RequestGameMenu( int changedFavorite = m_gui_context_menus.RequestGameMenu(
pos, m_game_info->m_games, m_compat_info, m_gui_settings, this, true); pos, m_game_info->m_games, m_compat_info, m_gui_settings, this, true);
if (changedFavorite) {
last_favorite = m_game_info->m_games[this->currentRow()].serial;
PopulateGameList(false); PopulateGameList(false);
}
}); });
connect(this, &QTableWidget::cellClicked, this, [=, this](int row, int column) { connect(this, &QTableWidget::cellClicked, this, [=, this](int row, int column) {
@@ -146,6 +143,12 @@ void GameListFrame::PopulateGameList(bool isInitialPopulation) {
for (int i = 0; i < m_game_info->m_games.size(); i++) { for (int i = 0; i < m_game_info->m_games.size(); i++) {
SetTableItem(i, 1, QString::fromStdString(m_game_info->m_games[i].name)); SetTableItem(i, 1, QString::fromStdString(m_game_info->m_games[i].name));
if (std::filesystem::exists(Common::FS::GetUserPath(Common::FS::PathType::CustomConfigs) /
(m_game_info->m_games[i].serial + ".toml"))) {
QTableWidgetItem* name_item = item(i, 1);
name_item->setIcon(QIcon(":images/game_settings.png"));
}
SetTableItem(i, 3, QString::fromStdString(m_game_info->m_games[i].serial)); SetTableItem(i, 3, QString::fromStdString(m_game_info->m_games[i].serial));
SetRegionFlag(i, 4, QString::fromStdString(m_game_info->m_games[i].region)); SetRegionFlag(i, 4, QString::fromStdString(m_game_info->m_games[i].region));
SetTableItem(i, 5, QString::fromStdString(m_game_info->m_games[i].fw)); SetTableItem(i, 5, QString::fromStdString(m_game_info->m_games[i].fw));

View File

@@ -17,6 +17,7 @@
#include "compatibility_info.h" #include "compatibility_info.h"
#include "game_info.h" #include "game_info.h"
#include "gui_settings.h" #include "gui_settings.h"
#include "settings_dialog.h"
#include "trophy_viewer.h" #include "trophy_viewer.h"
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
@@ -66,6 +67,24 @@ public:
menu.addMenu(openFolderMenu); menu.addMenu(openFolderMenu);
QMenu* gameConfigMenu = new QMenu(tr("Game-specific Settings..."), widget);
QAction gameConfigConfigure(tr("Configure Game-specific Settings"), widget);
QAction gameConfigCreate(tr("Create Game-specific Settings from Global Settings"), widget);
QAction gameConfigDelete(tr("Delete Game-specific Settings"), widget);
if (std::filesystem::exists(Common::FS::GetUserPath(Common::FS::PathType::CustomConfigs) /
(m_games[itemID].serial + ".toml"))) {
gameConfigMenu->addAction(&gameConfigConfigure);
} else {
gameConfigMenu->addAction(&gameConfigCreate);
}
if (std::filesystem::exists(Common::FS::GetUserPath(Common::FS::PathType::CustomConfigs) /
(m_games[itemID].serial + ".toml")))
gameConfigMenu->addAction(&gameConfigDelete);
menu.addMenu(gameConfigMenu);
QString serialStr = QString::fromStdString(m_games[itemID].serial); QString serialStr = QString::fromStdString(m_games[itemID].serial);
QList<QString> list = gui_settings::Var2List(m_gui_settings->GetValue(gui::favorites_list)); QList<QString> list = gui_settings::Var2List(m_gui_settings->GetValue(gui::favorites_list));
bool isFavorite = list.contains(serialStr); bool isFavorite = list.contains(serialStr);
@@ -76,6 +95,7 @@ public:
} else { } else {
toggleFavorite = new QAction(tr("Add to Favorites"), widget); toggleFavorite = new QAction(tr("Add to Favorites"), widget);
} }
QAction createShortcut(tr("Create Shortcut"), widget); QAction createShortcut(tr("Create Shortcut"), widget);
QAction openCheats(tr("Cheats / Patches"), widget); QAction openCheats(tr("Cheats / Patches"), widget);
QAction openSfoViewer(tr("SFO Viewer"), widget); QAction openSfoViewer(tr("SFO Viewer"), widget);
@@ -123,9 +143,9 @@ public:
// Compatibility submenu. // Compatibility submenu.
QMenu* compatibilityMenu = new QMenu(tr("Compatibility..."), widget); QMenu* compatibilityMenu = new QMenu(tr("Compatibility..."), widget);
QAction* updateCompatibility = new QAction(tr("Update database"), widget); QAction* updateCompatibility = new QAction(tr("Update Database"), widget);
QAction* viewCompatibilityReport = new QAction(tr("View report"), widget); QAction* viewCompatibilityReport = new QAction(tr("View Report"), widget);
QAction* submitCompatibilityReport = new QAction(tr("Submit a report"), widget); QAction* submitCompatibilityReport = new QAction(tr("Submit a Report"), widget);
compatibilityMenu->addAction(updateCompatibility); compatibilityMenu->addAction(updateCompatibility);
compatibilityMenu->addAction(viewCompatibilityReport); compatibilityMenu->addAction(viewCompatibilityReport);
@@ -387,6 +407,22 @@ public:
[trophyViewer]() { trophyViewer->deleteLater(); }); [trophyViewer]() { trophyViewer->deleteLater(); });
} }
if (selected == &gameConfigConfigure || selected == &gameConfigCreate) {
auto settingsWindow = new SettingsDialog(m_gui_settings, m_compat_info, widget, true,
serialStr.toStdString());
settingsWindow->exec();
}
if (selected == &gameConfigDelete) {
if (QMessageBox::Yes == QMessageBox::question(widget, tr("Confirm deletion"),
tr("Delete game-specific settings?"),
QMessageBox::Yes | QMessageBox::No)) {
std::filesystem::remove(
Common::FS::GetUserPath(Common::FS::PathType::CustomConfigs) /
(m_games[itemID].serial + ".toml"));
}
}
if (selected == &createShortcut) { if (selected == &createShortcut) {
QString targetPath; QString targetPath;
Common::FS::PathToQString(targetPath, m_games[itemID].path); Common::FS::PathToQString(targetPath, m_games[itemID].path);

View File

@@ -77,22 +77,48 @@ QMap<QString, QString> micMap;
int backgroundImageOpacitySlider_backup; int backgroundImageOpacitySlider_backup;
int bgm_volume_backup; int bgm_volume_backup;
int volume_slider_backup;
static std::vector<QString> m_physical_devices; static std::vector<QString> m_physical_devices;
SettingsDialog::SettingsDialog(std::shared_ptr<gui_settings> gui_settings, SettingsDialog::SettingsDialog(std::shared_ptr<gui_settings> gui_settings,
std::shared_ptr<CompatibilityInfoClass> m_compat_info, std::shared_ptr<CompatibilityInfoClass> m_compat_info,
QWidget* parent) QWidget* parent, bool is_game_specific, std::string gsc_serial)
: QDialog(parent), ui(new Ui::SettingsDialog), m_gui_settings(std::move(gui_settings)) { : QDialog(parent), ui(new Ui::SettingsDialog), m_gui_settings(std::move(gui_settings)),
game_specific(is_game_specific), gs_serial(gsc_serial) {
ui->setupUi(this); ui->setupUi(this);
ui->tabWidgetSettings->setUsesScrollButtons(false); ui->tabWidgetSettings->setUsesScrollButtons(false);
initialHeight = this->height();
// Add a small clear "x" button inside the Log Filter input // Add a small clear "x" button inside the Log Filter input
ui->logFilterLineEdit->setClearButtonEnabled(true); ui->logFilterLineEdit->setClearButtonEnabled(true);
initialHeight = this->height(); if (game_specific) {
const auto config_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir); ui->tabWidgetSettings->setTabVisible(5, false);
ui->chooseHomeTabComboBox->removeItem(5);
ui->label_Trophy->setVisible(false);
ui->trophyKeyLineEdit->setVisible(false);
ui->CompatgroupBox->setVisible(false);
ui->gameSizeCheckBox->setVisible(false);
ui->GUIBackgroundImageGroupBox->setVisible(false);
ui->GUIMusicGroupBox->setVisible(false);
ui->gameSizeCheckBox->setVisible(false);
ui->updaterGroupBox->setVisible(false);
ui->discordRPCCheckbox->setVisible(false);
ui->emulatorLanguageGroupBox->setVisible(false);
} else {
ui->dmaCheckBox->setVisible(false);
ui->devkitCheckBox->setVisible(false);
ui->neoCheckBox->setVisible(false);
ui->networkConnectedCheckBox->setVisible(false);
ui->psnSignInCheckBox->setVisible(false);
}
std::filesystem::path config_file =
game_specific
? Common::FS::GetUserPath(Common::FS::PathType::CustomConfigs) / (gs_serial + ".toml")
: Common::FS::GetUserPath(Common::FS::PathType::UserDir) / "config.toml";
ui->buttonBox->button(QDialogButtonBox::StandardButton::Close)->setFocus(); ui->buttonBox->button(QDialogButtonBox::StandardButton::Close)->setFocus();
@@ -168,25 +194,23 @@ SettingsDialog::SettingsDialog(std::shared_ptr<gui_settings> gui_settings,
connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QWidget::close); connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QWidget::close);
connect(ui->buttonBox, &QDialogButtonBox::clicked, this, connect(ui->buttonBox, &QDialogButtonBox::clicked, this,
[this, config_dir](QAbstractButton* button) { [this, config_file](QAbstractButton* button) {
if (button == ui->buttonBox->button(QDialogButtonBox::Save)) { if (button == ui->buttonBox->button(QDialogButtonBox::Save)) {
is_saving = true; is_saving = true;
UpdateSettings(); UpdateSettings(game_specific);
Config::save(config_dir / "config.toml"); Config::save(config_file, game_specific);
QWidget::close(); QWidget::close();
} else if (button == ui->buttonBox->button(QDialogButtonBox::Apply)) { } else if (button == ui->buttonBox->button(QDialogButtonBox::Apply)) {
UpdateSettings(); UpdateSettings(game_specific);
Config::save(config_dir / "config.toml"); Config::save(config_file, game_specific);
} else if (button == ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)) { } else if (button == ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)) {
Config::setDefaultValues();
setDefaultValues(); setDefaultValues();
Config::save(config_dir / "config.toml"); Config::setDefaultValues(game_specific);
Config::save(config_file, game_specific);
LoadValuesFromConfig(); LoadValuesFromConfig();
} else if (button == ui->buttonBox->button(QDialogButtonBox::Close)) { } else if (button == ui->buttonBox->button(QDialogButtonBox::Close)) {
ui->backgroundImageOpacitySlider->setValue(backgroundImageOpacitySlider_backup); ui->backgroundImageOpacitySlider->setValue(backgroundImageOpacitySlider_backup);
emit BackgroundOpacityChanged(backgroundImageOpacitySlider_backup); emit BackgroundOpacityChanged(backgroundImageOpacitySlider_backup);
ui->horizontalVolumeSlider->setValue(volume_slider_backup);
Config::setVolumeSlider(volume_slider_backup);
ui->BGMVolumeSlider->setValue(bgm_volume_backup); ui->BGMVolumeSlider->setValue(bgm_volume_backup);
BackgroundMusicPlayer::getInstance().setVolume(bgm_volume_backup); BackgroundMusicPlayer::getInstance().setVolume(bgm_volume_backup);
SyncRealTimeWidgetstoConfig(); SyncRealTimeWidgetstoConfig();
@@ -210,7 +234,7 @@ SettingsDialog::SettingsDialog(std::shared_ptr<gui_settings> gui_settings,
{ {
connect(ui->horizontalVolumeSlider, &QSlider::valueChanged, this, [this](int value) { connect(ui->horizontalVolumeSlider, &QSlider::valueChanged, this, [this](int value) {
VolumeSliderChange(value); VolumeSliderChange(value);
Config::setVolumeSlider(value); Config::setVolumeSlider(value, game_specific);
Libraries::AudioOut::AdjustVol(); Libraries::AudioOut::AdjustVol();
}); });
@@ -278,9 +302,6 @@ SettingsDialog::SettingsDialog(std::shared_ptr<gui_settings> gui_settings,
connect(ui->BGMVolumeSlider, &QSlider::valueChanged, this, connect(ui->BGMVolumeSlider, &QSlider::valueChanged, this,
[](int value) { BackgroundMusicPlayer::getInstance().setVolume(value); }); [](int value) { BackgroundMusicPlayer::getInstance().setVolume(value); });
connect(ui->chooseHomeTabComboBox, &QComboBox::currentTextChanged, this,
[](const QString& hometab) { Config::setChooseHomeTab(hometab.toStdString()); });
#if (QT_VERSION < QT_VERSION_CHECK(6, 7, 0)) #if (QT_VERSION < QT_VERSION_CHECK(6, 7, 0))
connect(ui->showBackgroundImageCheckBox, &QCheckBox::stateChanged, this, [this](int state) { connect(ui->showBackgroundImageCheckBox, &QCheckBox::stateChanged, this, [this](int state) {
#else #else
@@ -508,36 +529,42 @@ void SettingsDialog::closeEvent(QCloseEvent* event) {
if (!is_saving) { if (!is_saving) {
ui->backgroundImageOpacitySlider->setValue(backgroundImageOpacitySlider_backup); ui->backgroundImageOpacitySlider->setValue(backgroundImageOpacitySlider_backup);
emit BackgroundOpacityChanged(backgroundImageOpacitySlider_backup); emit BackgroundOpacityChanged(backgroundImageOpacitySlider_backup);
ui->horizontalVolumeSlider->setValue(volume_slider_backup);
Config::setVolumeSlider(volume_slider_backup);
ui->BGMVolumeSlider->setValue(bgm_volume_backup); ui->BGMVolumeSlider->setValue(bgm_volume_backup);
BackgroundMusicPlayer::getInstance().setVolume(bgm_volume_backup); BackgroundMusicPlayer::getInstance().setVolume(bgm_volume_backup);
SyncRealTimeWidgetstoConfig();
} }
QDialog::closeEvent(event); QDialog::closeEvent(event);
} }
void SettingsDialog::LoadValuesFromConfig() { void SettingsDialog::LoadValuesFromConfig() {
std::filesystem::path config_file;
config_file =
game_specific
? Common::FS::GetUserPath(Common::FS::PathType::CustomConfigs) / (gs_serial + ".toml")
: Common::FS::GetUserPath(Common::FS::PathType::UserDir) / "config.toml";
std::filesystem::path userdir = Common::FS::GetUserPath(Common::FS::PathType::UserDir);
std::error_code error; std::error_code error;
if (!std::filesystem::exists(userdir / "config.toml", error)) { bool is_newly_created = false;
Config::load(userdir / "config.toml"); if (!std::filesystem::exists(config_file, error)) {
return; Config::save(config_file, game_specific);
is_newly_created = true;
} }
try { try {
std::ifstream ifs; std::ifstream ifs;
ifs.exceptions(std::ifstream::failbit | std::ifstream::badbit); ifs.exceptions(std::ifstream::failbit | std::ifstream::badbit);
const toml::value data = toml::parse(userdir / "config.toml"); const toml::value data = toml::parse(config_file);
} catch (std::exception& ex) { } catch (std::exception& ex) {
fmt::print("Got exception trying to load config file. Exception: {}\n", ex.what()); fmt::print("Got exception trying to load config file. Exception: {}\n", ex.what());
return; return;
} }
const toml::value data = toml::parse(userdir / "config.toml"); const toml::value data = toml::parse(config_file);
const QVector<int> languageIndexes = {21, 23, 14, 6, 18, 1, 12, 22, 2, 4, 25, 24, 29, 5, 0, 9, const QVector<int> languageIndexes = {21, 23, 14, 6, 18, 1, 12, 22, 2, 4, 25, 24, 29, 5, 0, 9,
15, 16, 17, 7, 26, 8, 11, 20, 3, 13, 27, 10, 19, 30, 28}; 15, 16, 17, 7, 26, 8, 11, 20, 3, 13, 27, 10, 19, 30, 28};
// Entries with no game-specific settings
if (!game_specific) {
const auto save_data_path = Config::GetSaveDataPath(); const auto save_data_path = Config::GetSaveDataPath();
QString save_data_path_string; QString save_data_path_string;
Common::FS::PathToQString(save_data_path_string, save_data_path); Common::FS::PathToQString(save_data_path_string, save_data_path);
@@ -548,24 +575,79 @@ void SettingsDialog::LoadValuesFromConfig() {
Common::FS::PathToQString(dlc_folder_path_string, dlc_folder_path); Common::FS::PathToQString(dlc_folder_path_string, dlc_folder_path);
ui->currentDLCFolder->setText(dlc_folder_path_string); ui->currentDLCFolder->setText(dlc_folder_path_string);
ui->emulatorLanguageComboBox->setCurrentIndex(
languages[m_gui_settings->GetValue(gui::gen_guiLanguage).toString().toStdString()]);
ui->playBGMCheckBox->setChecked(
m_gui_settings->GetValue(gui::gl_playBackgroundMusic).toBool());
ui->RCASSlider->setValue(toml::find_or<int>(data, "GPU", "rcasAttenuation", 250));
ui->RCASValue->setText(QString::number(ui->RCASSlider->value() / 1000.0, 'f', 3));
ui->BGMVolumeSlider->setValue(
m_gui_settings->GetValue(gui::gl_backgroundMusicVolume).toInt());
ui->discordRPCCheckbox->setChecked(
toml::find_or<bool>(data, "General", "enableDiscordRPC", true));
ui->gameSizeCheckBox->setChecked(
toml::find_or<bool>(data, "GUI", "loadGameSizeEnabled", true));
ui->trophyKeyLineEdit->setText(
QString::fromStdString(toml::find_or<std::string>(data, "Keys", "TrophyKey", "")));
ui->trophyKeyLineEdit->setEchoMode(QLineEdit::Password);
ui->enableCompatibilityCheckBox->setChecked(
toml::find_or<bool>(data, "General", "compatibilityEnabled", false));
ui->checkCompatibilityOnStartupCheckBox->setChecked(
toml::find_or<bool>(data, "General", "checkCompatibilityOnStartup", false));
ui->removeFolderButton->setEnabled(!ui->gameFoldersListWidget->selectedItems().isEmpty());
ui->backgroundImageOpacitySlider->setValue(
m_gui_settings->GetValue(gui::gl_backgroundImageOpacity).toInt());
ui->showBackgroundImageCheckBox->setChecked(
m_gui_settings->GetValue(gui::gl_showBackgroundImage).toBool());
backgroundImageOpacitySlider_backup =
m_gui_settings->GetValue(gui::gl_backgroundImageOpacity).toInt();
bgm_volume_backup = m_gui_settings->GetValue(gui::gl_backgroundMusicVolume).toInt();
#ifdef ENABLE_UPDATER
ui->updateCheckBox->setChecked(m_gui_settings->GetValue(gui::gen_checkForUpdates).toBool());
ui->changelogCheckBox->setChecked(
m_gui_settings->GetValue(gui::gen_showChangeLog).toBool());
QString updateChannel = m_gui_settings->GetValue(gui::gen_updateChannel).toString();
ui->updateComboBox->setCurrentText(
channelMap.key(updateChannel != "Release" && updateChannel != "Nightly"
? (Common::g_is_release ? "Release" : "Nightly")
: updateChannel));
#endif
SyncRealTimeWidgetstoConfig();
}
// Entries with game-specific settings, *load these from toml file, not from Config::get*
ui->consoleLanguageComboBox->setCurrentIndex( ui->consoleLanguageComboBox->setCurrentIndex(
std::distance(languageIndexes.begin(), std::distance(languageIndexes.begin(),
std::find(languageIndexes.begin(), languageIndexes.end(), std::find(languageIndexes.begin(), languageIndexes.end(),
toml::find_or<int>(data, "Settings", "consoleLanguage", 6))) % toml::find_or<int>(data, "Settings", "consoleLanguage", 6))) %
languageIndexes.size()); languageIndexes.size());
ui->emulatorLanguageComboBox->setCurrentIndex(
languages[m_gui_settings->GetValue(gui::gen_guiLanguage).toString().toStdString()]);
ui->hideCursorComboBox->setCurrentIndex(toml::find_or<int>(data, "Input", "cursorState", 1));
OnCursorStateChanged(toml::find_or<int>(data, "Input", "cursorState", 1));
ui->idleTimeoutSpinBox->setValue(toml::find_or<int>(data, "Input", "cursorHideTimeout", 5));
QString micValue = QString::fromStdString(Config::getMicDevice()); std::string micDevice =
toml::find_or<std::string>(data, "Input", "micDevice", "Default Device");
QString micValue = QString::fromStdString(micDevice);
int micIndex = ui->micComboBox->findData(micValue); int micIndex = ui->micComboBox->findData(micValue);
if (micIndex != -1) { if (micIndex != -1) {
ui->micComboBox->setCurrentIndex(micIndex); ui->micComboBox->setCurrentIndex(micIndex);
} else { } else {
ui->micComboBox->setCurrentIndex(0); ui->micComboBox->setCurrentIndex(0);
} }
ui->dmaCheckBox->setChecked(toml::find_or<bool>(data, "GPU", "directMemoryAccess", false));
ui->neoCheckBox->setChecked(toml::find_or<bool>(data, "General", "isPS4Pro", false));
ui->devkitCheckBox->setChecked(toml::find_or<bool>(data, "General", "isDevKit", false));
ui->networkConnectedCheckBox->setChecked(
toml::find_or<bool>(data, "General", "isConnectedToNetwork", false));
ui->psnSignInCheckBox->setChecked(toml::find_or<bool>(data, "General", "isPSNSignedIn", false));
// First options is auto selection -1, so gpuId on the GUI will always have to subtract 1 // First options is auto selection -1, so gpuId on the GUI will always have to subtract 1
// when setting and add 1 when getting to select the correct gpu in Qt // when setting and add 1 when getting to select the correct gpu in Qt
ui->graphicsAdapterBox->setCurrentIndex(toml::find_or<int>(data, "Vulkan", "gpuId", -1) + 1); ui->graphicsAdapterBox->setCurrentIndex(toml::find_or<int>(data, "Vulkan", "gpuId", -1) + 1);
@@ -577,35 +659,43 @@ void SettingsDialog::LoadValuesFromConfig() {
ui->enableHDRCheckBox->setChecked(toml::find_or<bool>(data, "GPU", "allowHDR", false)); ui->enableHDRCheckBox->setChecked(toml::find_or<bool>(data, "GPU", "allowHDR", false));
ui->FSRCheckBox->setChecked(toml::find_or<bool>(data, "GPU", "fsrEnabled", true)); ui->FSRCheckBox->setChecked(toml::find_or<bool>(data, "GPU", "fsrEnabled", true));
ui->RCASCheckBox->setChecked(toml::find_or<bool>(data, "GPU", "rcasEnabled", true)); ui->RCASCheckBox->setChecked(toml::find_or<bool>(data, "GPU", "rcasEnabled", true));
ui->RCASSlider->setValue(toml::find_or<int>(data, "GPU", "rcasAttenuation", 500)); ui->RCASSlider->setValue(toml::find_or<int>(data, "GPU", "rcasAttenuation", 250));
ui->RCASValue->setText(QString::number(ui->RCASSlider->value() / 1000.0, 'f', 3)); ui->RCASValue->setText(QString::number(ui->RCASSlider->value() / 1000.0, 'f', 3));
ui->playBGMCheckBox->setChecked(m_gui_settings->GetValue(gui::gl_playBackgroundMusic).toBool());
ui->disableTrophycheckBox->setChecked( ui->disableTrophycheckBox->setChecked(
toml::find_or<bool>(data, "General", "isTrophyPopupDisabled", false)); toml::find_or<bool>(data, "General", "isTrophyPopupDisabled", false));
ui->popUpDurationSpinBox->setValue(Config::getTrophyNotificationDuration()); ui->popUpDurationSpinBox->setValue(
toml::find_or<double>(data, "General", "trophyNotificationDuration", 6.0));
QString side = QString::fromStdString(Config::sideTrophy()); ui->showSplashCheckBox->setChecked(toml::find_or<bool>(data, "General", "showSplash", false));
ui->hideCursorComboBox->setCurrentIndex(toml::find_or<int>(data, "Input", "cursorState", 1));
OnCursorStateChanged(toml::find_or<int>(data, "Input", "cursorState", 1));
ui->idleTimeoutSpinBox->setValue(toml::find_or<int>(data, "Input", "cursorHideTimeout", 5));
ui->motionControlsCheckBox->setChecked(
toml::find_or<bool>(data, "Input", "isMotionControlsEnabled", true));
ui->backgroundControllerCheckBox->setChecked(
toml::find_or<bool>(data, "Input", "backgroundControllerInput", false));
std::string sideTrophy = toml::find_or<std::string>(data, "General", "sideTrophy", "right");
QString side = QString::fromStdString(sideTrophy);
ui->radioButton_Left->setChecked(side == "left"); ui->radioButton_Left->setChecked(side == "left");
ui->radioButton_Right->setChecked(side == "right"); ui->radioButton_Right->setChecked(side == "right");
ui->radioButton_Top->setChecked(side == "top"); ui->radioButton_Top->setChecked(side == "top");
ui->radioButton_Bottom->setChecked(side == "bottom"); ui->radioButton_Bottom->setChecked(side == "bottom");
ui->BGMVolumeSlider->setValue(m_gui_settings->GetValue(gui::gl_backgroundMusicVolume).toInt()); ui->horizontalVolumeSlider->setValue(toml::find_or<int>(data, "General", "volumeSlider", 100));
ui->horizontalVolumeSlider->setValue(m_gui_settings->GetValue(gui::gl_VolumeSlider).toInt());
ui->volumeText->setText(QString::number(ui->horizontalVolumeSlider->sliderPosition()) + "%"); ui->volumeText->setText(QString::number(ui->horizontalVolumeSlider->sliderPosition()) + "%");
ui->discordRPCCheckbox->setChecked(
toml::find_or<bool>(data, "General", "enableDiscordRPC", true)); std::string fullScreenMode =
toml::find_or<std::string>(data, "General", "FullscreenMode", "Windowed");
QString translatedText_FullscreenMode = QString translatedText_FullscreenMode =
screenModeMap.key(QString::fromStdString(Config::getFullscreenMode())); screenModeMap.key(QString::fromStdString(fullScreenMode));
ui->displayModeComboBox->setCurrentText(translatedText_FullscreenMode); ui->displayModeComboBox->setCurrentText(translatedText_FullscreenMode);
QString translatedText_PresentMode =
presentModeMap.key(QString::fromStdString(Config::getPresentMode())); std::string presentMode = toml::find_or<std::string>(data, "GPU", "presentMode", "Mailbox");
QString translatedText_PresentMode = presentModeMap.key(QString::fromStdString(presentMode));
ui->presentModeComboBox->setCurrentText(translatedText_PresentMode); ui->presentModeComboBox->setCurrentText(translatedText_PresentMode);
ui->gameSizeCheckBox->setChecked(toml::find_or<bool>(data, "GUI", "loadGameSizeEnabled", true));
ui->showSplashCheckBox->setChecked(toml::find_or<bool>(data, "General", "showSplash", false)); std::string logType = toml::find_or<std::string>(data, "General", "logType", "sync");
QString translatedText_logType = logTypeMap.key(QString::fromStdString(Config::getLogType())); QString translatedText_logType = logTypeMap.key(QString::fromStdString(logType));
if (!translatedText_logType.isEmpty()) { if (!translatedText_logType.isEmpty()) {
ui->logTypeComboBox->setCurrentText(translatedText_logType); ui->logTypeComboBox->setCurrentText(translatedText_logType);
} }
@@ -613,9 +703,7 @@ void SettingsDialog::LoadValuesFromConfig() {
QString::fromStdString(toml::find_or<std::string>(data, "General", "logFilter", ""))); QString::fromStdString(toml::find_or<std::string>(data, "General", "logFilter", "")));
ui->userNameLineEdit->setText( ui->userNameLineEdit->setText(
QString::fromStdString(toml::find_or<std::string>(data, "General", "userName", "shadPS4"))); QString::fromStdString(toml::find_or<std::string>(data, "General", "userName", "shadPS4")));
ui->trophyKeyLineEdit->setText(
QString::fromStdString(toml::find_or<std::string>(data, "Keys", "TrophyKey", "")));
ui->trophyKeyLineEdit->setEchoMode(QLineEdit::Password);
ui->debugDump->setChecked(toml::find_or<bool>(data, "Debug", "DebugDump", false)); ui->debugDump->setChecked(toml::find_or<bool>(data, "Debug", "DebugDump", false));
ui->separateLogFilesCheckbox->setChecked( ui->separateLogFilesCheckbox->setChecked(
toml::find_or<bool>(data, "Debug", "isSeparateLogFilesEnabled", false)); toml::find_or<bool>(data, "Debug", "isSeparateLogFilesEnabled", false));
@@ -636,21 +724,6 @@ void SettingsDialog::LoadValuesFromConfig() {
ui->enableLoggingCheckBox->setChecked(toml::find_or<bool>(data, "Debug", "logEnabled", true)); ui->enableLoggingCheckBox->setChecked(toml::find_or<bool>(data, "Debug", "logEnabled", true));
ui->readbackLinearImagesCheckBox->setChecked( ui->readbackLinearImagesCheckBox->setChecked(
toml::find_or<bool>(data, "GPU", "readbackLinearImages", false)); toml::find_or<bool>(data, "GPU", "readbackLinearImages", false));
ui->enableCompatibilityCheckBox->setChecked(
toml::find_or<bool>(data, "General", "compatibilityEnabled", false));
ui->checkCompatibilityOnStartupCheckBox->setChecked(
toml::find_or<bool>(data, "General", "checkCompatibilityOnStartup", false));
#ifdef ENABLE_UPDATER
ui->updateCheckBox->setChecked(m_gui_settings->GetValue(gui::gen_checkForUpdates).toBool());
ui->changelogCheckBox->setChecked(m_gui_settings->GetValue(gui::gen_showChangeLog).toBool());
QString updateChannel = m_gui_settings->GetValue(gui::gen_updateChannel).toString();
ui->updateComboBox->setCurrentText(
channelMap.key(updateChannel != "Release" && updateChannel != "Nightly"
? (Common::g_is_release ? "Release" : "Nightly")
: updateChannel));
#endif
std::string chooseHomeTab = std::string chooseHomeTab =
toml::find_or<std::string>(data, "General", "chooseHomeTab", "General"); toml::find_or<std::string>(data, "General", "chooseHomeTab", "General");
@@ -663,26 +736,9 @@ void SettingsDialog::LoadValuesFromConfig() {
QStringList tabNames = {tr("General"), tr("GUI"), tr("Graphics"), tr("User"), QStringList tabNames = {tr("General"), tr("GUI"), tr("Graphics"), tr("User"),
tr("Input"), tr("Paths"), tr("Log"), tr("Debug")}; tr("Input"), tr("Paths"), tr("Log"), tr("Debug")};
int indexTab = tabNames.indexOf(translatedText); int indexTab = tabNames.indexOf(translatedText);
if (indexTab == -1) if (indexTab == -1 || !ui->tabWidgetSettings->isTabVisible(indexTab) || is_newly_created)
indexTab = 0; indexTab = 0;
ui->tabWidgetSettings->setCurrentIndex(indexTab); ui->tabWidgetSettings->setCurrentIndex(indexTab);
ui->motionControlsCheckBox->setChecked(
toml::find_or<bool>(data, "Input", "isMotionControlsEnabled", true));
ui->backgroundControllerCheckBox->setChecked(
toml::find_or<bool>(data, "Input", "backgroundControllerInput", false));
ui->removeFolderButton->setEnabled(!ui->gameFoldersListWidget->selectedItems().isEmpty());
SyncRealTimeWidgetstoConfig();
ui->backgroundImageOpacitySlider->setValue(
m_gui_settings->GetValue(gui::gl_backgroundImageOpacity).toInt());
ui->showBackgroundImageCheckBox->setChecked(
m_gui_settings->GetValue(gui::gl_showBackgroundImage).toBool());
backgroundImageOpacitySlider_backup =
m_gui_settings->GetValue(gui::gl_backgroundImageOpacity).toInt();
bgm_volume_backup = m_gui_settings->GetValue(gui::gl_backgroundMusicVolume).toInt();
volume_slider_backup = m_gui_settings->GetValue(gui::gl_VolumeSlider).toInt();
} }
void SettingsDialog::InitializeEmulatorLanguages() { void SettingsDialog::InitializeEmulatorLanguages() {
@@ -908,79 +964,79 @@ bool SettingsDialog::eventFilter(QObject* obj, QEvent* event) {
return QDialog::eventFilter(obj, event); return QDialog::eventFilter(obj, event);
} }
void SettingsDialog::UpdateSettings() { void SettingsDialog::UpdateSettings(bool game_specific) {
// Entries that are only in the game-specific gui
Config::setIsFullscreen(screenModeMap.value(ui->displayModeComboBox->currentText()) != if (game_specific) {
"Windowed"); Config::setDirectMemoryAccess(ui->dmaCheckBox->isChecked(), true);
Config::setDevKitConsole(ui->devkitCheckBox->isChecked(), true);
Config::setNeoMode(ui->neoCheckBox->isChecked(), true);
Config::setConnectedToNetwork(ui->networkConnectedCheckBox->isChecked(), true);
Config::setPSNSignedIn(ui->psnSignInCheckBox->isChecked(), true);
}
// Entries with game-specific settings, needs the game-specific arg
Config::setIsFullscreen(
screenModeMap.value(ui->displayModeComboBox->currentText()) != "Windowed", game_specific);
Config::setFullscreenMode( Config::setFullscreenMode(
screenModeMap.value(ui->displayModeComboBox->currentText()).toStdString()); screenModeMap.value(ui->displayModeComboBox->currentText()).toStdString(), game_specific);
Config::setPresentMode( Config::setPresentMode(
presentModeMap.value(ui->presentModeComboBox->currentText()).toStdString()); presentModeMap.value(ui->presentModeComboBox->currentText()).toStdString(), game_specific);
Config::setIsMotionControlsEnabled(ui->motionControlsCheckBox->isChecked()); Config::setIsMotionControlsEnabled(ui->motionControlsCheckBox->isChecked(), game_specific);
Config::setBackgroundControllerInput(ui->backgroundControllerCheckBox->isChecked()); Config::setBackgroundControllerInput(ui->backgroundControllerCheckBox->isChecked(),
Config::setisTrophyPopupDisabled(ui->disableTrophycheckBox->isChecked()); game_specific);
Config::setTrophyNotificationDuration(ui->popUpDurationSpinBox->value()); Config::setisTrophyPopupDisabled(ui->disableTrophycheckBox->isChecked(), game_specific);
Config::setTrophyNotificationDuration(ui->popUpDurationSpinBox->value(), game_specific);
if (ui->radioButton_Top->isChecked()) { if (ui->radioButton_Top->isChecked()) {
Config::setSideTrophy("top"); Config::setSideTrophy("top", game_specific);
} else if (ui->radioButton_Left->isChecked()) { } else if (ui->radioButton_Left->isChecked()) {
Config::setSideTrophy("left"); Config::setSideTrophy("left", game_specific);
} else if (ui->radioButton_Right->isChecked()) { } else if (ui->radioButton_Right->isChecked()) {
Config::setSideTrophy("right"); Config::setSideTrophy("right", game_specific);
} else if (ui->radioButton_Bottom->isChecked()) { } else if (ui->radioButton_Bottom->isChecked()) {
Config::setSideTrophy("bottom"); Config::setSideTrophy("bottom", game_specific);
} }
m_gui_settings->SetValue(gui::gl_playBackgroundMusic, ui->playBGMCheckBox->isChecked());
Config::setLoggingEnabled(ui->enableLoggingCheckBox->isChecked());
Config::setAllowHDR(ui->enableHDRCheckBox->isChecked());
Config::setLogType(logTypeMap.value(ui->logTypeComboBox->currentText()).toStdString());
Config::setMicDevice(ui->micComboBox->currentData().toString().toStdString());
Config::setLogFilter(ui->logFilterLineEdit->text().toStdString());
Config::setUserName(ui->userNameLineEdit->text().toStdString());
Config::setTrophyKey(ui->trophyKeyLineEdit->text().toStdString());
Config::setCursorState(ui->hideCursorComboBox->currentIndex());
Config::setCursorHideTimeout(ui->idleTimeoutSpinBox->value());
Config::setGpuId(ui->graphicsAdapterBox->currentIndex() - 1);
m_gui_settings->SetValue(gui::gl_VolumeSlider, ui->horizontalVolumeSlider->value());
m_gui_settings->SetValue(gui::gl_backgroundMusicVolume, ui->BGMVolumeSlider->value());
Config::setLanguage(languageIndexes[ui->consoleLanguageComboBox->currentIndex()]);
Config::setEnableDiscordRPC(ui->discordRPCCheckbox->isChecked());
Config::setWindowWidth(ui->widthSpinBox->value());
Config::setWindowHeight(ui->heightSpinBox->value());
Config::setVblankFreq(ui->vblankSpinBox->value());
Config::setDumpShaders(ui->dumpShadersCheckBox->isChecked());
Config::setNullGpu(ui->nullGpuCheckBox->isChecked());
Config::setFsrEnabled(ui->FSRCheckBox->isChecked());
Config::setRcasEnabled(ui->RCASCheckBox->isChecked());
Config::setRcasAttenuation(ui->RCASSlider->value());
Config::setLoadGameSizeEnabled(ui->gameSizeCheckBox->isChecked());
Config::setShowSplash(ui->showSplashCheckBox->isChecked());
Config::setDebugDump(ui->debugDump->isChecked());
Config::setSeparateLogFilesEnabled(ui->separateLogFilesCheckbox->isChecked());
Config::setVkValidation(ui->vkValidationCheckBox->isChecked());
Config::setVkSyncValidation(ui->vkSyncValidationCheckBox->isChecked());
Config::setRdocEnabled(ui->rdocCheckBox->isChecked());
Config::setVkHostMarkersEnabled(ui->hostMarkersCheckBox->isChecked());
Config::setVkGuestMarkersEnabled(ui->guestMarkersCheckBox->isChecked());
Config::setVkCrashDiagnosticEnabled(ui->crashDiagnosticsCheckBox->isChecked());
Config::setReadbacks(ui->readbacksCheckBox->isChecked());
Config::setReadbackLinearImages(ui->readbackLinearImagesCheckBox->isChecked());
Config::setCollectShaderForDebug(ui->collectShaderCheckBox->isChecked());
Config::setCopyGPUCmdBuffers(ui->copyGPUBuffersCheckBox->isChecked());
m_gui_settings->SetValue(gui::gen_checkForUpdates, ui->updateCheckBox->isChecked());
m_gui_settings->SetValue(gui::gen_showChangeLog, ui->changelogCheckBox->isChecked());
m_gui_settings->SetValue(gui::gen_updateChannel,
channelMap.value(ui->updateComboBox->currentText()));
Config::setChooseHomeTab(
chooseHomeTabMap.value(ui->chooseHomeTabComboBox->currentText()).toStdString());
Config::setCompatibilityEnabled(ui->enableCompatibilityCheckBox->isChecked());
Config::setCheckCompatibilityOnStartup(ui->checkCompatibilityOnStartupCheckBox->isChecked());
m_gui_settings->SetValue(gui::gl_backgroundImageOpacity,
std::clamp(ui->backgroundImageOpacitySlider->value(), 0, 100));
emit BackgroundOpacityChanged(ui->backgroundImageOpacitySlider->value());
m_gui_settings->SetValue(gui::gl_showBackgroundImage,
ui->showBackgroundImageCheckBox->isChecked());
Config::setLoggingEnabled(ui->enableLoggingCheckBox->isChecked(), game_specific);
Config::setAllowHDR(ui->enableHDRCheckBox->isChecked(), game_specific);
Config::setLogType(logTypeMap.value(ui->logTypeComboBox->currentText()).toStdString(),
game_specific);
Config::setMicDevice(ui->micComboBox->currentData().toString().toStdString(), game_specific);
Config::setLogFilter(ui->logFilterLineEdit->text().toStdString(), game_specific);
Config::setUserName(ui->userNameLineEdit->text().toStdString(), game_specific);
Config::setCursorState(ui->hideCursorComboBox->currentIndex(), game_specific);
Config::setCursorHideTimeout(ui->hideCursorComboBox->currentIndex(), game_specific);
Config::setGpuId(ui->graphicsAdapterBox->currentIndex() - 1, game_specific);
Config::setVolumeSlider(ui->horizontalVolumeSlider->value(), game_specific);
Config::setLanguage(languageIndexes[ui->consoleLanguageComboBox->currentIndex()]);
Config::setWindowWidth(ui->widthSpinBox->value(), game_specific);
Config::setWindowHeight(ui->heightSpinBox->value(), game_specific);
Config::setVblankFreq(ui->vblankSpinBox->value(), game_specific);
Config::setDumpShaders(ui->dumpShadersCheckBox->isChecked(), game_specific);
Config::setNullGpu(ui->nullGpuCheckBox->isChecked(), game_specific);
Config::setFsrEnabled(ui->FSRCheckBox->isChecked(), game_specific);
Config::setRcasEnabled(ui->RCASCheckBox->isChecked(), game_specific);
Config::setRcasAttenuation(ui->RCASSlider->value(), game_specific);
Config::setShowSplash(ui->showSplashCheckBox->isChecked(), game_specific);
Config::setDebugDump(ui->debugDump->isChecked(), game_specific);
Config::setSeparateLogFilesEnabled(ui->separateLogFilesCheckbox->isChecked(), game_specific);
Config::setVkValidation(ui->vkValidationCheckBox->isChecked(), game_specific);
Config::setVkSyncValidation(ui->vkSyncValidationCheckBox->isChecked(), game_specific);
Config::setRdocEnabled(ui->rdocCheckBox->isChecked(), game_specific);
Config::setVkHostMarkersEnabled(ui->hostMarkersCheckBox->isChecked(), game_specific);
Config::setVkGuestMarkersEnabled(ui->guestMarkersCheckBox->isChecked(), game_specific);
Config::setVkCrashDiagnosticEnabled(ui->crashDiagnosticsCheckBox->isChecked(), game_specific);
Config::setReadbacks(ui->readbacksCheckBox->isChecked(), game_specific);
Config::setReadbackLinearImages(ui->readbackLinearImagesCheckBox->isChecked(), game_specific);
Config::setCollectShaderForDebug(ui->collectShaderCheckBox->isChecked(), game_specific);
Config::setCopyGPUCmdBuffers(ui->copyGPUBuffersCheckBox->isChecked(), game_specific);
Config::setChooseHomeTab(
chooseHomeTabMap.value(ui->chooseHomeTabComboBox->currentText()).toStdString(),
game_specific);
// Entries with no game-specific settings
if (!game_specific) {
std::vector<Config::GameInstallDir> dirs_with_states; std::vector<Config::GameInstallDir> dirs_with_states;
for (int i = 0; i < ui->gameFoldersListWidget->count(); i++) { for (int i = 0; i < ui->gameFoldersListWidget->count(); i++) {
QListWidgetItem* item = ui->gameFoldersListWidget->item(i); QListWidgetItem* item = ui->gameFoldersListWidget->item(i);
@@ -992,6 +1048,8 @@ void SettingsDialog::UpdateSettings() {
} }
Config::setAllGameInstallDirs(dirs_with_states); Config::setAllGameInstallDirs(dirs_with_states);
BackgroundMusicPlayer::getInstance().setVolume(ui->BGMVolumeSlider->value());
#ifdef ENABLE_DISCORD_RPC #ifdef ENABLE_DISCORD_RPC
auto* rpc = Common::Singleton<DiscordRPCHandler::RPC>::Instance(); auto* rpc = Common::Singleton<DiscordRPCHandler::RPC>::Instance();
if (Config::getEnableDiscordRPC()) { if (Config::getEnableDiscordRPC()) {
@@ -1002,16 +1060,32 @@ void SettingsDialog::UpdateSettings() {
} }
#endif #endif
BackgroundMusicPlayer::getInstance().setVolume(ui->BGMVolumeSlider->value()); Config::setLoadGameSizeEnabled(ui->gameSizeCheckBox->isChecked());
Config::setVolumeSlider(ui->horizontalVolumeSlider->value()); Config::setTrophyKey(ui->trophyKeyLineEdit->text().toStdString());
Config::setEnableDiscordRPC(ui->discordRPCCheckbox->isChecked());
Config::setCompatibilityEnabled(ui->enableCompatibilityCheckBox->isChecked());
Config::setCheckCompatibilityOnStartup(
ui->checkCompatibilityOnStartupCheckBox->isChecked());
m_gui_settings->SetValue(gui::gl_playBackgroundMusic, ui->playBGMCheckBox->isChecked());
m_gui_settings->SetValue(gui::gl_backgroundMusicVolume, ui->BGMVolumeSlider->value());
m_gui_settings->SetValue(gui::gen_checkForUpdates, ui->updateCheckBox->isChecked());
m_gui_settings->SetValue(gui::gen_showChangeLog, ui->changelogCheckBox->isChecked());
m_gui_settings->SetValue(gui::gen_updateChannel,
channelMap.value(ui->updateComboBox->currentText()));
m_gui_settings->SetValue(gui::gl_showBackgroundImage,
ui->showBackgroundImageCheckBox->isChecked());
m_gui_settings->SetValue(gui::gl_backgroundImageOpacity,
std::clamp(ui->backgroundImageOpacitySlider->value(), 0, 100));
emit BackgroundOpacityChanged(ui->backgroundImageOpacitySlider->value());
}
} }
void SettingsDialog::SyncRealTimeWidgetstoConfig() { void SettingsDialog::SyncRealTimeWidgetstoConfig() {
ui->gameFoldersListWidget->clear();
std::filesystem::path userdir = Common::FS::GetUserPath(Common::FS::PathType::UserDir); std::filesystem::path userdir = Common::FS::GetUserPath(Common::FS::PathType::UserDir);
const toml::value data = toml::parse(userdir / "config.toml"); const toml::value data = toml::parse(userdir / "config.toml");
if (!game_specific) {
ui->gameFoldersListWidget->clear();
if (data.contains("GUI")) { if (data.contains("GUI")) {
const toml::value& gui = data.at("GUI"); const toml::value& gui = data.at("GUI");
const auto install_dir_array = const auto install_dir_array =
@@ -1048,20 +1122,38 @@ void SettingsDialog::SyncRealTimeWidgetstoConfig() {
Config::setAllGameInstallDirs(settings_install_dirs_config); Config::setAllGameInstallDirs(settings_install_dirs_config);
} }
}
toml::value gs_data;
game_specific
? gs_data = toml::parse(Common::FS::GetUserPath(Common::FS::PathType::CustomConfigs) /
(gs_serial + ".toml"))
: gs_data = data;
int sliderValue = toml::find_or<int>(gs_data, "General", "volumeSlider", 100);
ui->horizontalVolumeSlider->setValue(sliderValue);
// Since config::set can be called for volume slider (connected to the widget) outside the save
// function, need to null it out if GS GUI is closed without saving
game_specific ? Config::resetGameSpecificValue("volumeSlider")
: Config::setVolumeSlider(sliderValue);
if (presenter) { if (presenter) {
presenter->GetFsrSettingsRef().enable = Config::getFsrEnabled(); presenter->GetFsrSettingsRef().enable =
presenter->GetFsrSettingsRef().use_rcas = Config::getRcasEnabled(); toml::find_or<bool>(gs_data, "GPU", "fsrEnabled", true);
presenter->GetFsrSettingsRef().use_rcas =
toml::find_or<bool>(gs_data, "GPU", "rcasEnabled", true);
presenter->GetFsrSettingsRef().rcas_attenuation = presenter->GetFsrSettingsRef().rcas_attenuation =
static_cast<float>(Config::getRcasAttenuation() / 1000.f); static_cast<float>(toml::find_or<int>(gs_data, "GPU", "rcasAttenuation", 250) / 1000.f);
} }
} }
void SettingsDialog::setDefaultValues() { void SettingsDialog::setDefaultValues() {
if (!game_specific) {
m_gui_settings->SetValue(gui::gl_showBackgroundImage, true); m_gui_settings->SetValue(gui::gl_showBackgroundImage, true);
m_gui_settings->SetValue(gui::gl_backgroundImageOpacity, 50); m_gui_settings->SetValue(gui::gl_backgroundImageOpacity, 50);
m_gui_settings->SetValue(gui::gl_playBackgroundMusic, false); m_gui_settings->SetValue(gui::gl_playBackgroundMusic, false);
m_gui_settings->SetValue(gui::gl_backgroundMusicVolume, 50); m_gui_settings->SetValue(gui::gl_backgroundMusicVolume, 50);
m_gui_settings->SetValue(gui::gl_VolumeSlider, 100);
m_gui_settings->SetValue(gui::gen_checkForUpdates, false); m_gui_settings->SetValue(gui::gen_checkForUpdates, false);
m_gui_settings->SetValue(gui::gen_showChangeLog, false); m_gui_settings->SetValue(gui::gen_showChangeLog, false);
if (Common::g_is_release) { if (Common::g_is_release) {
@@ -1071,3 +1163,4 @@ void SettingsDialog::setDefaultValues() {
} }
m_gui_settings->SetValue(gui::gen_guiLanguage, "en_US"); m_gui_settings->SetValue(gui::gen_guiLanguage, "en_US");
} }
}

View File

@@ -23,7 +23,8 @@ class SettingsDialog : public QDialog {
public: public:
explicit SettingsDialog(std::shared_ptr<gui_settings> gui_settings, explicit SettingsDialog(std::shared_ptr<gui_settings> gui_settings,
std::shared_ptr<CompatibilityInfoClass> m_compat_info, std::shared_ptr<CompatibilityInfoClass> m_compat_info,
QWidget* parent = nullptr); QWidget* parent = nullptr, bool is_game_specific = false,
std::string gsc_serial = "");
~SettingsDialog(); ~SettingsDialog();
bool eventFilter(QObject* obj, QEvent* event) override; bool eventFilter(QObject* obj, QEvent* event) override;
@@ -38,7 +39,7 @@ signals:
private: private:
void LoadValuesFromConfig(); void LoadValuesFromConfig();
void UpdateSettings(); void UpdateSettings(bool game_specific = false);
void SyncRealTimeWidgetstoConfig(); void SyncRealTimeWidgetstoConfig();
void InitializeEmulatorLanguages(); void InitializeEmulatorLanguages();
void OnLanguageChanged(int index); void OnLanguageChanged(int index);
@@ -55,5 +56,8 @@ private:
int initialHeight; int initialHeight;
bool is_saving = false; bool is_saving = false;
bool game_specific;
std::string gs_serial;
std::shared_ptr<gui_settings> m_gui_settings; std::shared_ptr<gui_settings> m_gui_settings;
}; };

View File

@@ -12,7 +12,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>970</width> <width>970</width>
<height>750</height> <height>765</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
@@ -59,7 +59,7 @@
</size> </size>
</property> </property>
<property name="currentIndex"> <property name="currentIndex">
<number>6</number> <number>7</number>
</property> </property>
<widget class="QScrollArea" name="generalTab"> <widget class="QScrollArea" name="generalTab">
<property name="widgetResizable"> <property name="widgetResizable">
@@ -74,7 +74,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>946</width> <width>946</width>
<height>486</height> <height>501</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="generalTabVLayout" stretch="0"> <layout class="QVBoxLayout" name="generalTabVLayout" stretch="0">
@@ -452,8 +452,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>400</width> <width>402</width>
<height>60</height> <height>68</height>
</rect> </rect>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout_6"> <layout class="QHBoxLayout" name="horizontalLayout_6">
@@ -539,7 +539,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>946</width> <width>946</width>
<height>486</height> <height>501</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
@@ -999,7 +999,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>946</width> <width>946</width>
<height>486</height> <height>501</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="graphicsTabVLayout" stretch="0,0"> <layout class="QVBoxLayout" name="graphicsTabVLayout" stretch="0,0">
@@ -1406,7 +1406,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>946</width> <width>946</width>
<height>486</height> <height>501</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="userTabVLayout" stretch="0,0,1"> <layout class="QVBoxLayout" name="userTabVLayout" stretch="0,0,1">
@@ -1648,7 +1648,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>946</width> <width>946</width>
<height>486</height> <height>501</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="inputTabVLayout" stretch="0,0"> <layout class="QVBoxLayout" name="inputTabVLayout" stretch="0,0">
@@ -1920,7 +1920,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>946</width> <width>946</width>
<height>486</height> <height>501</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="pathsTabLayout"> <layout class="QVBoxLayout" name="pathsTabLayout">
@@ -2235,7 +2235,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>946</width> <width>946</width>
<height>382</height> <height>495</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
@@ -2244,17 +2244,11 @@
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<layout class="QVBoxLayout" name="debugTabVLayout" stretch="0,0"> <layout class="QVBoxLayout" name="debugTabVLayout" stretch="0">
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_5"> <layout class="QVBoxLayout" name="debugVLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<item> <item>
<layout class="QHBoxLayout" name="debugTabHLayout" stretch="0"> <layout class="QHBoxLayout" name="debugHLayout">
<item> <item>
<widget class="QGroupBox" name="debugTabGroupBox"> <widget class="QGroupBox" name="debugTabGroupBox">
<property name="enabled"> <property name="enabled">
@@ -2318,10 +2312,6 @@
</layout> </layout>
</widget> </widget>
</item> </item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item> <item>
<widget class="QGroupBox" name="advancedGroupBox"> <widget class="QGroupBox" name="advancedGroupBox">
<property name="sizePolicy"> <property name="sizePolicy">
@@ -2389,30 +2379,28 @@
</item> </item>
</layout> </layout>
</item> </item>
</layout>
</item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_8"> <layout class="QHBoxLayout" name="experimentalHLayout">
<property name="topMargin">
<number>0</number>
</property>
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item> <item>
<widget class="QGroupBox" name="ExperimentalGroupBox"> <widget class="QGroupBox" name="ExperimentalGroupBox">
<property name="title"> <property name="title">
<string>Experimental Features</string> <string>Experimental Features</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_3"> <layout class="QVBoxLayout" name="verticalLayout_3">
<item> <property name="spacing">
<layout class="QHBoxLayout" name="horizontalLayout_11"> <number>6</number>
<property name="topMargin"> </property>
<number>0</number> <property name="leftMargin">
<number>9</number>
</property> </property>
<item>
<layout class="QVBoxLayout" name="verticalLayout_6">
<property name="topMargin"> <property name="topMargin">
<number>0</number> <number>9</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>9</number>
</property> </property>
<item> <item>
<widget class="QCheckBox" name="readbacksCheckBox"> <widget class="QCheckBox" name="readbacksCheckBox">
@@ -2428,7 +2416,43 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QCheckBox" name="dmaCheckBox">
<property name="text">
<string>Enable Direct Memory Access</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="devkitCheckBox">
<property name="text">
<string>Enable Devkit Console Mode</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="neoCheckBox">
<property name="text">
<string>Enable PS4 Pro Mode</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="psnSignInCheckBox">
<property name="text">
<string>Set &quot;PSN signed-in&quot; to True</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="networkConnectedCheckBox">
<property name="text">
<string>Set &quot;Network Connected&quot; to True</string>
</property>
</widget>
</item>
</layout> </layout>
</widget>
</item> </item>
<item> <item>
<widget class="QLabel" name="ExperimentalLabel"> <widget class="QLabel" name="ExperimentalLabel">
@@ -2457,13 +2481,13 @@
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set> <set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter</set>
</property> </property>
<property name="wordWrap"> <property name="wordWrap">
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="margin"> <property name="margin">
<number>0</number> <number>20</number>
</property> </property>
<property name="indent"> <property name="indent">
<number>-1</number> <number>-1</number>
@@ -2472,10 +2496,18 @@
</item> </item>
</layout> </layout>
</item> </item>
</layout> <item>
</widget> <spacer name="verticalSpacer_10">
</item> <property name="orientation">
</layout> <enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>5</height>
</size>
</property>
</spacer>
</item> </item>
</layout> </layout>
</item> </item>

View File

@@ -38,5 +38,6 @@
<file>images/favorite_icon.png</file> <file>images/favorite_icon.png</file>
<file>images/trophy_icon.png</file> <file>images/trophy_icon.png</file>
<file>images/hotkey.png</file> <file>images/hotkey.png</file>
<file>images/game_settings.png</file>
</qresource> </qresource>
</RCC> </RCC>