using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Hid.Keyboard;
using Ryujinx.Common.Logging;
using Ryujinx.Configuration.System;
using Ryujinx.Configuration.Ui;
using System;
using System.Collections.Generic;
namespace Ryujinx.Configuration
{
public class ConfigurationState
{
///
/// UI configuration section
///
public class UiSection
{
public class Columns
{
public ReactiveObject FavColumn { get; private set; }
public ReactiveObject IconColumn { get; private set; }
public ReactiveObject AppColumn { get; private set; }
public ReactiveObject DevColumn { get; private set; }
public ReactiveObject VersionColumn { get; private set; }
public ReactiveObject TimePlayedColumn { get; private set; }
public ReactiveObject LastPlayedColumn { get; private set; }
public ReactiveObject FileExtColumn { get; private set; }
public ReactiveObject FileSizeColumn { get; private set; }
public ReactiveObject PathColumn { get; private set; }
public Columns()
{
FavColumn = new ReactiveObject();
IconColumn = new ReactiveObject();
AppColumn = new ReactiveObject();
DevColumn = new ReactiveObject();
VersionColumn = new ReactiveObject();
TimePlayedColumn = new ReactiveObject();
LastPlayedColumn = new ReactiveObject();
FileExtColumn = new ReactiveObject();
FileSizeColumn = new ReactiveObject();
PathColumn = new ReactiveObject();
}
}
public class ColumnSortSettings
{
public ReactiveObject SortColumnId { get; private set; }
public ReactiveObject SortAscending { get; private set; }
public ColumnSortSettings()
{
SortColumnId = new ReactiveObject();
SortAscending = new ReactiveObject();
}
}
///
/// Used to toggle columns in the GUI
///
public Columns GuiColumns { get; private set; }
///
/// Used to configure column sort settings in the GUI
///
public ColumnSortSettings ColumnSort { get; private set; }
///
/// A list of directories containing games to be used to load games into the games list
///
public ReactiveObject> GameDirs { get; private set; }
///
/// Enable or disable custom themes in the GUI
///
public ReactiveObject EnableCustomTheme { get; private set; }
///
/// Path to custom GUI theme
///
public ReactiveObject CustomThemePath { get; private set; }
///
/// Start games in fullscreen mode
///
public ReactiveObject StartFullscreen { get; private set; }
public UiSection()
{
GuiColumns = new Columns();
ColumnSort = new ColumnSortSettings();
GameDirs = new ReactiveObject>();
EnableCustomTheme = new ReactiveObject();
CustomThemePath = new ReactiveObject();
StartFullscreen = new ReactiveObject();
}
}
///
/// Logger configuration section
///
public class LoggerSection
{
///
/// Enables printing debug log messages
///
public ReactiveObject EnableDebug { get; private set; }
///
/// Enables printing stub log messages
///
public ReactiveObject EnableStub { get; private set; }
///
/// Enables printing info log messages
///
public ReactiveObject EnableInfo { get; private set; }
///
/// Enables printing warning log messages
///
public ReactiveObject EnableWarn { get; private set; }
///
/// Enables printing error log messages
///
public ReactiveObject EnableError { get; private set; }
///
/// Enables printing guest log messages
///
public ReactiveObject EnableGuest { get; private set; }
///
/// Enables printing FS access log messages
///
public ReactiveObject EnableFsAccessLog { get; private set; }
///
/// Controls which log messages are written to the log targets
///
public ReactiveObject FilteredClasses { get; private set; }
///
/// Enables or disables logging to a file on disk
///
public ReactiveObject EnableFileLog { get; private set; }
///
/// Controls which OpenGL log messages are recorded in the log
///
public ReactiveObject GraphicsDebugLevel { get; private set; }
public LoggerSection()
{
EnableDebug = new ReactiveObject();
EnableStub = new ReactiveObject();
EnableInfo = new ReactiveObject();
EnableWarn = new ReactiveObject();
EnableError = new ReactiveObject();
EnableGuest = new ReactiveObject();
EnableFsAccessLog = new ReactiveObject();
FilteredClasses = new ReactiveObject();
EnableFileLog = new ReactiveObject();
EnableFileLog.Event += static (sender, e) => LogValueChange(sender, e, nameof(EnableFileLog));
GraphicsDebugLevel = new ReactiveObject();
}
}
///
/// System configuration section
///
public class SystemSection
{
///
/// Change System Language
///
public ReactiveObject Language { get; private set; }
///
/// Change System Region
///
public ReactiveObject Region { get; private set; }
///
/// Change System TimeZone
///
public ReactiveObject TimeZone { get; private set; }
///
/// System Time Offset in Seconds
///
public ReactiveObject SystemTimeOffset { get; private set; }
///
/// Enables or disables Docked Mode
///
public ReactiveObject EnableDockedMode { get; private set; }
///
/// Enables or disables profiled translation cache persistency
///
public ReactiveObject EnablePtc { get; private set; }
///
/// Enables integrity checks on Game content files
///
public ReactiveObject EnableFsIntegrityChecks { get; private set; }
///
/// Enables FS access log output to the console. Possible modes are 0-3
///
public ReactiveObject FsGlobalAccessLogMode { get; private set; }
///
/// The selected audio backend
///
public ReactiveObject AudioBackend { get; private set; }
///
/// Defines the amount of RAM available on the emulated system, and how it is distributed
///
public ReactiveObject ExpandRam { get; private set; }
///
/// Enable or disable ignoring missing services
///
public ReactiveObject IgnoreMissingServices { get; private set; }
public SystemSection()
{
Language = new ReactiveObject();
Region = new ReactiveObject();
TimeZone = new ReactiveObject();
SystemTimeOffset = new ReactiveObject();
EnableDockedMode = new ReactiveObject();
EnableDockedMode.Event += static (sender, e) => LogValueChange(sender, e, nameof(EnableDockedMode));
EnablePtc = new ReactiveObject();
EnablePtc.Event += static (sender, e) => LogValueChange(sender, e, nameof(EnablePtc));
EnableFsIntegrityChecks = new ReactiveObject();
EnableFsIntegrityChecks.Event += static (sender, e) => LogValueChange(sender, e, nameof(EnableFsIntegrityChecks));
FsGlobalAccessLogMode = new ReactiveObject();
FsGlobalAccessLogMode.Event += static (sender, e) => LogValueChange(sender, e, nameof(FsGlobalAccessLogMode));
AudioBackend = new ReactiveObject();
AudioBackend.Event += static (sender, e) => LogValueChange(sender, e, nameof(AudioBackend));
ExpandRam = new ReactiveObject();
ExpandRam.Event += static (sender, e) => LogValueChange(sender, e, nameof(ExpandRam));
IgnoreMissingServices = new ReactiveObject();
IgnoreMissingServices.Event += static (sender, e) => LogValueChange(sender, e, nameof(IgnoreMissingServices));
}
}
///
/// Hid configuration section
///
public class HidSection
{
///
/// Enable or disable keyboard support (Independent from controllers binding)
///
public ReactiveObject EnableKeyboard { get; private set; }
///
/// Hotkey Keyboard Bindings
///
public ReactiveObject Hotkeys { get; private set; }
///
/// Input device configuration.
/// NOTE: This ReactiveObject won't issue an event when the List has elements added or removed.
/// TODO: Implement a ReactiveList class.
///
public ReactiveObject> InputConfig { get; private set; }
public HidSection()
{
EnableKeyboard = new ReactiveObject();
Hotkeys = new ReactiveObject();
InputConfig = new ReactiveObject>();
}
}
///
/// Graphics configuration section
///
public class GraphicsSection
{
///
/// Max Anisotropy. Values range from 0 - 16. Set to -1 to let the game decide.
///
public ReactiveObject MaxAnisotropy { get; private set; }
///
/// Aspect Ratio applied to the renderer window.
///
public ReactiveObject AspectRatio { get; private set; }
///
/// Resolution Scale. An integer scale applied to applicable render targets. Values 1-4, or -1 to use a custom floating point scale instead.
///
public ReactiveObject ResScale { get; private set; }
///
/// Custom Resolution Scale. A custom floating point scale applied to applicable render targets. Only active when Resolution Scale is -1.
///
public ReactiveObject ResScaleCustom { get; private set; }
///
/// Dumps shaders in this local directory
///
public ReactiveObject ShadersDumpPath { get; private set; }
///
/// Enables or disables Vertical Sync
///
public ReactiveObject EnableVsync { get; private set; }
///
/// Enables or disables Shader cache
///
public ReactiveObject EnableShaderCache { get; private set; }
public GraphicsSection()
{
ResScale = new ReactiveObject();
ResScale.Event += static (sender, e) => LogValueChange(sender, e, nameof(ResScale));
ResScaleCustom = new ReactiveObject();
ResScaleCustom.Event += static (sender, e) => LogValueChange(sender, e, nameof(ResScaleCustom));
MaxAnisotropy = new ReactiveObject();
MaxAnisotropy.Event += static (sender, e) => LogValueChange(sender, e, nameof(MaxAnisotropy));
AspectRatio = new ReactiveObject();
AspectRatio.Event += static (sender, e) => LogValueChange(sender, e, nameof(AspectRatio));
ShadersDumpPath = new ReactiveObject();
EnableVsync = new ReactiveObject();
EnableVsync.Event += static (sender, e) => LogValueChange(sender, e, nameof(EnableVsync));
EnableShaderCache = new ReactiveObject();
EnableShaderCache.Event += static (sender, e) => LogValueChange(sender, e, nameof(EnableShaderCache));
}
}
///
/// The default configuration instance
///
public static ConfigurationState Instance { get; private set; }
///
/// The Ui section
///
public UiSection Ui { get; private set; }
///
/// The Logger section
///
public LoggerSection Logger { get; private set; }
///
/// The System section
///
public SystemSection System { get; private set; }
///
/// The Graphics section
///
public GraphicsSection Graphics { get; private set; }
///
/// The Hid section
///
public HidSection Hid { get; private set; }
///
/// Enables or disables Discord Rich Presence
///
public ReactiveObject EnableDiscordIntegration { get; private set; }
///
/// Checks for updates when Ryujinx starts when enabled
///
public ReactiveObject CheckUpdatesOnStart { get; private set; }
///
/// Show "Confirm Exit" Dialog
///
public ReactiveObject ShowConfirmExit { get; private set; }
///
/// Hide Cursor on Idle
///
public ReactiveObject HideCursorOnIdle { get; private set; }
private ConfigurationState()
{
Ui = new UiSection();
Logger = new LoggerSection();
System = new SystemSection();
Graphics = new GraphicsSection();
Hid = new HidSection();
EnableDiscordIntegration = new ReactiveObject();
CheckUpdatesOnStart = new ReactiveObject();
ShowConfirmExit = new ReactiveObject();
HideCursorOnIdle = new ReactiveObject();
}
public ConfigurationFileFormat ToFileFormat()
{
ConfigurationFileFormat configurationFile = new ConfigurationFileFormat
{
Version = ConfigurationFileFormat.CurrentVersion,
EnableFileLog = Logger.EnableFileLog,
ResScale = Graphics.ResScale,
ResScaleCustom = Graphics.ResScaleCustom,
MaxAnisotropy = Graphics.MaxAnisotropy,
AspectRatio = Graphics.AspectRatio,
GraphicsShadersDumpPath = Graphics.ShadersDumpPath,
LoggingEnableDebug = Logger.EnableDebug,
LoggingEnableStub = Logger.EnableStub,
LoggingEnableInfo = Logger.EnableInfo,
LoggingEnableWarn = Logger.EnableWarn,
LoggingEnableError = Logger.EnableError,
LoggingEnableGuest = Logger.EnableGuest,
LoggingEnableFsAccessLog = Logger.EnableFsAccessLog,
LoggingFilteredClasses = Logger.FilteredClasses,
LoggingGraphicsDebugLevel = Logger.GraphicsDebugLevel,
SystemLanguage = System.Language,
SystemRegion = System.Region,
SystemTimeZone = System.TimeZone,
SystemTimeOffset = System.SystemTimeOffset,
DockedMode = System.EnableDockedMode,
EnableDiscordIntegration = EnableDiscordIntegration,
CheckUpdatesOnStart = CheckUpdatesOnStart,
ShowConfirmExit = ShowConfirmExit,
HideCursorOnIdle = HideCursorOnIdle,
EnableVsync = Graphics.EnableVsync,
EnableShaderCache = Graphics.EnableShaderCache,
EnablePtc = System.EnablePtc,
EnableFsIntegrityChecks = System.EnableFsIntegrityChecks,
FsGlobalAccessLogMode = System.FsGlobalAccessLogMode,
AudioBackend = System.AudioBackend,
ExpandRam = System.ExpandRam,
IgnoreMissingServices = System.IgnoreMissingServices,
GuiColumns = new GuiColumns
{
FavColumn = Ui.GuiColumns.FavColumn,
IconColumn = Ui.GuiColumns.IconColumn,
AppColumn = Ui.GuiColumns.AppColumn,
DevColumn = Ui.GuiColumns.DevColumn,
VersionColumn = Ui.GuiColumns.VersionColumn,
TimePlayedColumn = Ui.GuiColumns.TimePlayedColumn,
LastPlayedColumn = Ui.GuiColumns.LastPlayedColumn,
FileExtColumn = Ui.GuiColumns.FileExtColumn,
FileSizeColumn = Ui.GuiColumns.FileSizeColumn,
PathColumn = Ui.GuiColumns.PathColumn,
},
ColumnSort = new ColumnSort
{
SortColumnId = Ui.ColumnSort.SortColumnId,
SortAscending = Ui.ColumnSort.SortAscending
},
GameDirs = Ui.GameDirs,
EnableCustomTheme = Ui.EnableCustomTheme,
CustomThemePath = Ui.CustomThemePath,
StartFullscreen = Ui.StartFullscreen,
EnableKeyboard = Hid.EnableKeyboard,
Hotkeys = Hid.Hotkeys,
KeyboardConfig = new List