diff --git a/Ryujinx.Common/Configuration/ConfigurationFileFormat.cs b/Ryujinx.Common/Configuration/ConfigurationFileFormat.cs index 1a9407cb..a18db16a 100644 --- a/Ryujinx.Common/Configuration/ConfigurationFileFormat.cs +++ b/Ryujinx.Common/Configuration/ConfigurationFileFormat.cs @@ -73,6 +73,11 @@ namespace Ryujinx.Configuration /// public Language SystemLanguage { get; set; } + /// + /// Change System Region + /// + public Region SystemRegion { get; set; } + /// /// Enables or disables Docked Mode /// diff --git a/Ryujinx.Common/Configuration/ConfigurationState.cs b/Ryujinx.Common/Configuration/ConfigurationState.cs index 050b4973..0f7b4084 100644 --- a/Ryujinx.Common/Configuration/ConfigurationState.cs +++ b/Ryujinx.Common/Configuration/ConfigurationState.cs @@ -148,6 +148,11 @@ namespace Ryujinx.Configuration /// public ReactiveObject Language { get; private set; } + /// + /// Change System Region + /// + public ReactiveObject Region { get; private set; } + /// /// Enables or disables Docked Mode /// @@ -176,6 +181,7 @@ namespace Ryujinx.Configuration public SystemSection() { Language = new ReactiveObject(); + Region = new ReactiveObject(); EnableDockedMode = new ReactiveObject(); EnableMulticoreScheduling = new ReactiveObject(); EnableFsIntegrityChecks = new ReactiveObject(); @@ -289,7 +295,7 @@ namespace Ryujinx.Configuration { ConfigurationFileFormat configurationFile = new ConfigurationFileFormat { - Version = 1, + Version = 2, GraphicsShadersDumpPath = Graphics.ShadersDumpPath, LoggingEnableDebug = Logger.EnableDebug, LoggingEnableStub = Logger.EnableStub, @@ -301,6 +307,7 @@ namespace Ryujinx.Configuration LoggingFilteredClasses = Logger.FilteredClasses, EnableFileLog = Logger.EnableFileLog, SystemLanguage = System.Language, + SystemRegion = System.Region, DockedMode = System.EnableDockedMode, EnableDiscordIntegration = EnableDiscordIntegration, EnableVsync = Graphics.EnableVsync, @@ -346,6 +353,7 @@ namespace Ryujinx.Configuration Logger.FilteredClasses.Value = new LogClass[] { }; Logger.EnableFileLog.Value = true; System.Language.Value = Language.AmericanEnglish; + System.Region.Value = Region.USA; System.EnableDockedMode.Value = false; EnableDiscordIntegration.Value = true; Graphics.EnableVsync.Value = true; @@ -440,9 +448,11 @@ namespace Ryujinx.Configuration }; } - public void Load(ConfigurationFileFormat configurationFileFormat) + public void Load(ConfigurationFileFormat configurationFileFormat, string configurationFilePath) { - if (configurationFileFormat.Version != 1 && configurationFileFormat.Version != 0) + bool configurationFileUpdated = false; + + if (configurationFileFormat.Version < 0 || configurationFileFormat.Version > 2) { Common.Logging.Logger.PrintWarning(LogClass.Application, $"Unsupported configuration version {configurationFileFormat.Version}, loading default."); @@ -451,6 +461,15 @@ namespace Ryujinx.Configuration return; } + if (configurationFileFormat.Version < 2) + { + Common.Logging.Logger.PrintWarning(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, needs to be updated."); + + configurationFileFormat.SystemRegion = Region.USA; + + configurationFileUpdated = true; + } + Graphics.ShadersDumpPath.Value = configurationFileFormat.GraphicsShadersDumpPath; Logger.EnableDebug.Value = configurationFileFormat.LoggingEnableDebug; Logger.EnableStub.Value = configurationFileFormat.LoggingEnableStub; @@ -462,6 +481,7 @@ namespace Ryujinx.Configuration Logger.FilteredClasses.Value = configurationFileFormat.LoggingFilteredClasses; Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog; System.Language.Value = configurationFileFormat.SystemLanguage; + System.Region.Value = configurationFileFormat.SystemRegion; System.EnableDockedMode.Value = configurationFileFormat.DockedMode; System.EnableDockedMode.Value = configurationFileFormat.DockedMode; EnableDiscordIntegration.Value = configurationFileFormat.EnableDiscordIntegration; @@ -487,6 +507,13 @@ namespace Ryujinx.Configuration Hid.EnableKeyboard.Value = configurationFileFormat.EnableKeyboard; Hid.KeyboardControls.Value = configurationFileFormat.KeyboardControls; Hid.JoystickControls.Value = configurationFileFormat.JoystickControls; + + if (configurationFileUpdated) + { + ToFileFormat().SaveConfig(configurationFilePath); + + Common.Logging.Logger.PrintWarning(LogClass.Application, "Configuration file is updated!"); + } } public static void Initialize() diff --git a/Ryujinx.Common/Configuration/System/Region.cs b/Ryujinx.Common/Configuration/System/Region.cs new file mode 100644 index 00000000..54b1c36f --- /dev/null +++ b/Ryujinx.Common/Configuration/System/Region.cs @@ -0,0 +1,13 @@ +namespace Ryujinx.Configuration.System +{ + public enum Region + { + Japan, + USA, + Europe, + Australia, + China, + Korea, + Taiwan + } +} diff --git a/Ryujinx.HLE/HOS/Services/Settings/ISettingsServer.cs b/Ryujinx.HLE/HOS/Services/Settings/ISettingsServer.cs index 2d2512df..a8b10297 100644 --- a/Ryujinx.HLE/HOS/Services/Settings/ISettingsServer.cs +++ b/Ryujinx.HLE/HOS/Services/Settings/ISettingsServer.cs @@ -54,6 +54,24 @@ namespace Ryujinx.HLE.HOS.Services.Settings return ResultCode.Success; } + [Command(4)] + // GetRegionCode() -> u32 nn::settings::RegionCode + public ResultCode GetRegionCode(ServiceCtx context) + { + // NOTE: Service mount 0x8000000000000050 savedata and read the region code here. + + SystemRegion regionCode = (SystemRegion)context.Device.System.State.DesiredRegionCode; + + if (regionCode < SystemRegion.Min || regionCode > SystemRegion.Max) + { + regionCode = SystemRegion.USA; + } + + context.ResponseData.Write((uint)regionCode); + + return ResultCode.Success; + } + [Command(5)] // GetAvailableLanguageCodes2() -> (u32, buffer) public ResultCode GetAvailableLanguageCodes2(ServiceCtx context) diff --git a/Ryujinx.HLE/HOS/SystemState/SystemRegion.cs b/Ryujinx.HLE/HOS/SystemState/SystemRegion.cs new file mode 100644 index 00000000..9a07a4a8 --- /dev/null +++ b/Ryujinx.HLE/HOS/SystemState/SystemRegion.cs @@ -0,0 +1,16 @@ +namespace Ryujinx.HLE.HOS.SystemState +{ + public enum SystemRegion + { + Japan, + USA, + Europe, + Australia, + China, + Korea, + Taiwan, + + Min = Japan, + Max = Taiwan + } +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/SystemState/SystemStateMgr.cs b/Ryujinx.HLE/HOS/SystemState/SystemStateMgr.cs index c2e6680d..b65d1030 100644 --- a/Ryujinx.HLE/HOS/SystemState/SystemStateMgr.cs +++ b/Ryujinx.HLE/HOS/SystemState/SystemStateMgr.cs @@ -37,6 +37,8 @@ namespace Ryujinx.HLE.HOS.SystemState internal long DesiredLanguageCode { get; private set; } + internal uint DesiredRegionCode { get; private set; } + public TitleLanguage DesiredTitleLanguage { get; private set; } internal string ActiveAudioOutput { get; private set; } @@ -79,6 +81,11 @@ namespace Ryujinx.HLE.HOS.SystemState } } + public void SetRegion(SystemRegion region) + { + DesiredRegionCode = (uint)region; + } + public void SetAudioOutputAsTv() { ActiveAudioOutput = AudioOutputs[0]; diff --git a/Ryujinx.HLE/Switch.cs b/Ryujinx.HLE/Switch.cs index b7db5c62..3cd290bd 100644 --- a/Ryujinx.HLE/Switch.cs +++ b/Ryujinx.HLE/Switch.cs @@ -69,6 +69,8 @@ namespace Ryujinx.HLE { System.State.SetLanguage((SystemLanguage)ConfigurationState.Instance.System.Language.Value); + System.State.SetRegion((SystemRegion)ConfigurationState.Instance.System.Region.Value); + EnableDeviceVsync = ConfigurationState.Instance.Graphics.EnableVsync; // TODO: Make this reloadable and implement Docking/Undocking logic. diff --git a/Ryujinx/Config.json b/Ryujinx/Config.json index e35a67ac..80430899 100644 --- a/Ryujinx/Config.json +++ b/Ryujinx/Config.json @@ -1,5 +1,5 @@ { - "version": 1, + "version": 2, "graphics_shaders_dump_path": "", "logging_enable_debug": false, "logging_enable_stub": true, @@ -11,6 +11,7 @@ "logging_filtered_classes": [], "enable_file_log": true, "system_language": "AmericanEnglish", + "system_region": "USA", "docked_mode": false, "enable_discord_integration": true, "enable_vsync": true, diff --git a/Ryujinx/Program.cs b/Ryujinx/Program.cs index 7ff2b64f..2f02e003 100644 --- a/Ryujinx/Program.cs +++ b/Ryujinx/Program.cs @@ -53,7 +53,7 @@ namespace Ryujinx ConfigurationFileFormat configurationFileFormat = ConfigurationFileFormat.Load(localConfigurationPath); - ConfigurationState.Instance.Load(configurationFileFormat); + ConfigurationState.Instance.Load(configurationFileFormat, ConfigurationPath); } else if (File.Exists(globalConfigurationPath)) { @@ -61,7 +61,7 @@ namespace Ryujinx ConfigurationFileFormat configurationFileFormat = ConfigurationFileFormat.Load(globalConfigurationPath); - ConfigurationState.Instance.Load(configurationFileFormat); + ConfigurationState.Instance.Load(configurationFileFormat, ConfigurationPath); } else { diff --git a/Ryujinx/Ui/SwitchSettings.cs b/Ryujinx/Ui/SwitchSettings.cs index da2d4a74..6fe490c8 100644 --- a/Ryujinx/Ui/SwitchSettings.cs +++ b/Ryujinx/Ui/SwitchSettings.cs @@ -39,6 +39,7 @@ namespace Ryujinx.Ui [GUI] CheckButton _ignoreToggle; [GUI] CheckButton _directKeyboardAccess; [GUI] ComboBoxText _systemLanguageSelect; + [GUI] ComboBoxText _systemRegionSelect; [GUI] CheckButton _custThemeToggle; [GUI] Entry _custThemePath; [GUI] ToggleButton _browseThemePath; @@ -197,6 +198,7 @@ namespace Ryujinx.Ui } _systemLanguageSelect.SetActiveId(ConfigurationState.Instance.System.Language.Value.ToString()); + _systemRegionSelect .SetActiveId(ConfigurationState.Instance.System.Region.Value.ToString()); _controller1Type .SetActiveId(ConfigurationState.Instance.Hid.ControllerType.Value.ToString()); Controller_Changed(null, null, _controller1Type.ActiveId, _controller1Image); @@ -232,6 +234,7 @@ namespace Ryujinx.Ui _gameDirsBox.AppendColumn("", new CellRendererText(), "text", 0); _gameDirsBoxStore = new ListStore(typeof(string)); _gameDirsBox.Model = _gameDirsBoxStore; + foreach (string gameDir in ConfigurationState.Instance.Ui.GameDirs.Value) { _gameDirsBoxStore.AppendValues(gameDir); @@ -438,6 +441,7 @@ namespace Ryujinx.Ui }; ConfigurationState.Instance.System.Language.Value = (Language)Enum.Parse(typeof(Language), _systemLanguageSelect.ActiveId); + ConfigurationState.Instance.System.Region.Value = (Configuration.System.Region)Enum.Parse(typeof(Configuration.System.Region), _systemRegionSelect.ActiveId); ConfigurationState.Instance.Hid.ControllerType.Value = (ControllerType)Enum.Parse(typeof(ControllerType), _controller1Type.ActiveId); ConfigurationState.Instance.Ui.CustomThemePath.Value = _custThemePath.Buffer.Text; ConfigurationState.Instance.Graphics.ShadersDumpPath.Value = _graphicsShadersDumpPath.Buffer.Text; diff --git a/Ryujinx/Ui/SwitchSettings.glade b/Ryujinx/Ui/SwitchSettings.glade index 6128a3ce..a23bc199 100644 --- a/Ryujinx/Ui/SwitchSettings.glade +++ b/Ryujinx/Ui/SwitchSettings.glade @@ -166,6 +166,43 @@ 1 + + + True + False + Change System Region + end + System Region: + + + False + True + 2 + 5 + + + + + True + False + Change System Region + 5 + + Japan + USA + Europe + Australia + China + Korea + Taiwan + + + + False + True + 3 + + False diff --git a/Ryujinx/_schema.json b/Ryujinx/_schema.json index f0321f84..143716b6 100644 --- a/Ryujinx/_schema.json +++ b/Ryujinx/_schema.json @@ -15,6 +15,7 @@ "logging_filtered_classes", "enable_file_log", "system_language", + "system_region", "docked_mode", "enable_vsync", "enable_multicore_scheduling", @@ -402,6 +403,25 @@ "AmericanEnglish" ] }, + "system_region": { + "$id": "#/properties/system_region", + "type": "string", + "title": "System Region", + "description": "Change System Region", + "default": "USA", + "enum": [ + "Japan", + "USA", + "Europe", + "Australia", + "China", + "Korea", + "Taiwan" + ], + "examples": [ + "USA" + ] + }, "docked_mode": { "$id": "#/properties/docked_mode", "type": "boolean",