ConfigurationState.cs 65 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354
  1. using Ryujinx.Common;
  2. using Ryujinx.Common.Configuration;
  3. using Ryujinx.Common.Configuration.Hid;
  4. using Ryujinx.Common.Configuration.Hid.Controller;
  5. using Ryujinx.Common.Configuration.Hid.Keyboard;
  6. using Ryujinx.Common.Logging;
  7. using Ryujinx.Ui.Common.Configuration.System;
  8. using Ryujinx.Ui.Common.Configuration.Ui;
  9. using Ryujinx.Ui.Common.Helper;
  10. using System;
  11. using System.Collections.Generic;
  12. using System.Text.Json.Nodes;
  13. namespace Ryujinx.Ui.Common.Configuration
  14. {
  15. public class ConfigurationState
  16. {
  17. /// <summary>
  18. /// UI configuration section
  19. /// </summary>
  20. public class UiSection
  21. {
  22. public class Columns
  23. {
  24. public ReactiveObject<bool> FavColumn { get; private set; }
  25. public ReactiveObject<bool> IconColumn { get; private set; }
  26. public ReactiveObject<bool> AppColumn { get; private set; }
  27. public ReactiveObject<bool> DevColumn { get; private set; }
  28. public ReactiveObject<bool> VersionColumn { get; private set; }
  29. public ReactiveObject<bool> TimePlayedColumn { get; private set; }
  30. public ReactiveObject<bool> LastPlayedColumn { get; private set; }
  31. public ReactiveObject<bool> FileExtColumn { get; private set; }
  32. public ReactiveObject<bool> FileSizeColumn { get; private set; }
  33. public ReactiveObject<bool> PathColumn { get; private set; }
  34. public Columns()
  35. {
  36. FavColumn = new ReactiveObject<bool>();
  37. IconColumn = new ReactiveObject<bool>();
  38. AppColumn = new ReactiveObject<bool>();
  39. DevColumn = new ReactiveObject<bool>();
  40. VersionColumn = new ReactiveObject<bool>();
  41. TimePlayedColumn = new ReactiveObject<bool>();
  42. LastPlayedColumn = new ReactiveObject<bool>();
  43. FileExtColumn = new ReactiveObject<bool>();
  44. FileSizeColumn = new ReactiveObject<bool>();
  45. PathColumn = new ReactiveObject<bool>();
  46. }
  47. }
  48. public class ColumnSortSettings
  49. {
  50. public ReactiveObject<int> SortColumnId { get; private set; }
  51. public ReactiveObject<bool> SortAscending { get; private set; }
  52. public ColumnSortSettings()
  53. {
  54. SortColumnId = new ReactiveObject<int>();
  55. SortAscending = new ReactiveObject<bool>();
  56. }
  57. }
  58. /// <summary>
  59. /// Used to toggle columns in the GUI
  60. /// </summary>
  61. public Columns GuiColumns { get; private set; }
  62. /// <summary>
  63. /// Used to configure column sort settings in the GUI
  64. /// </summary>
  65. public ColumnSortSettings ColumnSort { get; private set; }
  66. /// <summary>
  67. /// A list of directories containing games to be used to load games into the games list
  68. /// </summary>
  69. public ReactiveObject<List<string>> GameDirs { get; private set; }
  70. /// <summary>
  71. /// Language Code for the UI
  72. /// </summary>
  73. public ReactiveObject<string> LanguageCode { get; private set; }
  74. /// <summary>
  75. /// Enable or disable custom themes in the GUI
  76. /// </summary>
  77. public ReactiveObject<bool> EnableCustomTheme { get; private set; }
  78. /// <summary>
  79. /// Path to custom GUI theme
  80. /// </summary>
  81. public ReactiveObject<string> CustomThemePath { get; private set; }
  82. /// <summary>
  83. /// Selects the base style
  84. /// </summary>
  85. public ReactiveObject<string> BaseStyle { get; private set; }
  86. /// <summary>
  87. /// Start games in fullscreen mode
  88. /// </summary>
  89. public ReactiveObject<bool> StartFullscreen { get; private set; }
  90. /// <summary>
  91. /// Hide / Show Console Window
  92. /// </summary>
  93. public ReactiveObject<bool> ShowConsole { get; private set; }
  94. /// <summary>
  95. /// View Mode of the Game list
  96. /// </summary>
  97. public ReactiveObject<int> GameListViewMode { get; private set; }
  98. /// <summary>
  99. /// Show application name in Grid Mode
  100. /// </summary>
  101. public ReactiveObject<bool> ShowNames { get; private set; }
  102. /// <summary>
  103. /// Sets App Icon Size in Grid Mode
  104. /// </summary>
  105. public ReactiveObject<int> GridSize { get; private set; }
  106. /// <summary>
  107. /// Sorts Apps in Grid Mode
  108. /// </summary>
  109. public ReactiveObject<int> ApplicationSort { get; private set; }
  110. /// <summary>
  111. /// Sets if Grid is ordered in Ascending Order
  112. /// </summary>
  113. public ReactiveObject<bool> IsAscendingOrder { get; private set; }
  114. public UiSection()
  115. {
  116. GuiColumns = new Columns();
  117. ColumnSort = new ColumnSortSettings();
  118. GameDirs = new ReactiveObject<List<string>>();
  119. EnableCustomTheme = new ReactiveObject<bool>();
  120. CustomThemePath = new ReactiveObject<string>();
  121. BaseStyle = new ReactiveObject<string>();
  122. StartFullscreen = new ReactiveObject<bool>();
  123. GameListViewMode = new ReactiveObject<int>();
  124. ShowNames = new ReactiveObject<bool>();
  125. GridSize = new ReactiveObject<int>();
  126. ApplicationSort = new ReactiveObject<int>();
  127. IsAscendingOrder = new ReactiveObject<bool>();
  128. LanguageCode = new ReactiveObject<string>();
  129. ShowConsole = new ReactiveObject<bool>();
  130. ShowConsole.Event += static (s, e) => { ConsoleHelper.SetConsoleWindowState(e.NewValue); };
  131. }
  132. }
  133. /// <summary>
  134. /// Logger configuration section
  135. /// </summary>
  136. public class LoggerSection
  137. {
  138. /// <summary>
  139. /// Enables printing debug log messages
  140. /// </summary>
  141. public ReactiveObject<bool> EnableDebug { get; private set; }
  142. /// <summary>
  143. /// Enables printing stub log messages
  144. /// </summary>
  145. public ReactiveObject<bool> EnableStub { get; private set; }
  146. /// <summary>
  147. /// Enables printing info log messages
  148. /// </summary>
  149. public ReactiveObject<bool> EnableInfo { get; private set; }
  150. /// <summary>
  151. /// Enables printing warning log messages
  152. /// </summary>
  153. public ReactiveObject<bool> EnableWarn { get; private set; }
  154. /// <summary>
  155. /// Enables printing error log messages
  156. /// </summary>
  157. public ReactiveObject<bool> EnableError { get; private set; }
  158. /// <summary>
  159. /// Enables printing trace log messages
  160. /// </summary>
  161. public ReactiveObject<bool> EnableTrace { get; private set; }
  162. /// <summary>
  163. /// Enables printing guest log messages
  164. /// </summary>
  165. public ReactiveObject<bool> EnableGuest { get; private set; }
  166. /// <summary>
  167. /// Enables printing FS access log messages
  168. /// </summary>
  169. public ReactiveObject<bool> EnableFsAccessLog { get; private set; }
  170. /// <summary>
  171. /// Controls which log messages are written to the log targets
  172. /// </summary>
  173. public ReactiveObject<LogClass[]> FilteredClasses { get; private set; }
  174. /// <summary>
  175. /// Enables or disables logging to a file on disk
  176. /// </summary>
  177. public ReactiveObject<bool> EnableFileLog { get; private set; }
  178. /// <summary>
  179. /// Controls which OpenGL log messages are recorded in the log
  180. /// </summary>
  181. public ReactiveObject<GraphicsDebugLevel> GraphicsDebugLevel { get; private set; }
  182. public LoggerSection()
  183. {
  184. EnableDebug = new ReactiveObject<bool>();
  185. EnableStub = new ReactiveObject<bool>();
  186. EnableInfo = new ReactiveObject<bool>();
  187. EnableWarn = new ReactiveObject<bool>();
  188. EnableError = new ReactiveObject<bool>();
  189. EnableTrace = new ReactiveObject<bool>();
  190. EnableGuest = new ReactiveObject<bool>();
  191. EnableFsAccessLog = new ReactiveObject<bool>();
  192. FilteredClasses = new ReactiveObject<LogClass[]>();
  193. EnableFileLog = new ReactiveObject<bool>();
  194. EnableFileLog.Event += static (sender, e) => LogValueChange(sender, e, nameof(EnableFileLog));
  195. GraphicsDebugLevel = new ReactiveObject<GraphicsDebugLevel>();
  196. }
  197. }
  198. /// <summary>
  199. /// System configuration section
  200. /// </summary>
  201. public class SystemSection
  202. {
  203. /// <summary>
  204. /// Change System Language
  205. /// </summary>
  206. public ReactiveObject<Language> Language { get; private set; }
  207. /// <summary>
  208. /// Change System Region
  209. /// </summary>
  210. public ReactiveObject<Region> Region { get; private set; }
  211. /// <summary>
  212. /// Change System TimeZone
  213. /// </summary>
  214. public ReactiveObject<string> TimeZone { get; private set; }
  215. /// <summary>
  216. /// System Time Offset in Seconds
  217. /// </summary>
  218. public ReactiveObject<long> SystemTimeOffset { get; private set; }
  219. /// <summary>
  220. /// Enables or disables Docked Mode
  221. /// </summary>
  222. public ReactiveObject<bool> EnableDockedMode { get; private set; }
  223. /// <summary>
  224. /// Enables or disables profiled translation cache persistency
  225. /// </summary>
  226. public ReactiveObject<bool> EnablePtc { get; private set; }
  227. /// <summary>
  228. /// Enables or disables guest Internet access
  229. /// </summary>
  230. public ReactiveObject<bool> EnableInternetAccess { get; private set; }
  231. /// <summary>
  232. /// Enables integrity checks on Game content files
  233. /// </summary>
  234. public ReactiveObject<bool> EnableFsIntegrityChecks { get; private set; }
  235. /// <summary>
  236. /// Enables FS access log output to the console. Possible modes are 0-3
  237. /// </summary>
  238. public ReactiveObject<int> FsGlobalAccessLogMode { get; private set; }
  239. /// <summary>
  240. /// The selected audio backend
  241. /// </summary>
  242. public ReactiveObject<AudioBackend> AudioBackend { get; private set; }
  243. /// <summary>
  244. /// The audio backend volume
  245. /// </summary>
  246. public ReactiveObject<float> AudioVolume { get; private set; }
  247. /// <summary>
  248. /// The selected memory manager mode
  249. /// </summary>
  250. public ReactiveObject<MemoryManagerMode> MemoryManagerMode { get; private set; }
  251. /// <summary>
  252. /// Defines the amount of RAM available on the emulated system, and how it is distributed
  253. /// </summary>
  254. public ReactiveObject<bool> ExpandRam { get; private set; }
  255. /// <summary>
  256. /// Enable or disable ignoring missing services
  257. /// </summary>
  258. public ReactiveObject<bool> IgnoreMissingServices { get; private set; }
  259. /// <summary>
  260. /// Uses Hypervisor over JIT if available
  261. /// </summary>
  262. public ReactiveObject<bool> UseHypervisor { get; private set; }
  263. public SystemSection()
  264. {
  265. Language = new ReactiveObject<Language>();
  266. Region = new ReactiveObject<Region>();
  267. TimeZone = new ReactiveObject<string>();
  268. SystemTimeOffset = new ReactiveObject<long>();
  269. EnableDockedMode = new ReactiveObject<bool>();
  270. EnableDockedMode.Event += static (sender, e) => LogValueChange(sender, e, nameof(EnableDockedMode));
  271. EnablePtc = new ReactiveObject<bool>();
  272. EnablePtc.Event += static (sender, e) => LogValueChange(sender, e, nameof(EnablePtc));
  273. EnableInternetAccess = new ReactiveObject<bool>();
  274. EnableInternetAccess.Event += static (sender, e) => LogValueChange(sender, e, nameof(EnableInternetAccess));
  275. EnableFsIntegrityChecks = new ReactiveObject<bool>();
  276. EnableFsIntegrityChecks.Event += static (sender, e) => LogValueChange(sender, e, nameof(EnableFsIntegrityChecks));
  277. FsGlobalAccessLogMode = new ReactiveObject<int>();
  278. FsGlobalAccessLogMode.Event += static (sender, e) => LogValueChange(sender, e, nameof(FsGlobalAccessLogMode));
  279. AudioBackend = new ReactiveObject<AudioBackend>();
  280. AudioBackend.Event += static (sender, e) => LogValueChange(sender, e, nameof(AudioBackend));
  281. MemoryManagerMode = new ReactiveObject<MemoryManagerMode>();
  282. MemoryManagerMode.Event += static (sender, e) => LogValueChange(sender, e, nameof(MemoryManagerMode));
  283. ExpandRam = new ReactiveObject<bool>();
  284. ExpandRam.Event += static (sender, e) => LogValueChange(sender, e, nameof(ExpandRam));
  285. IgnoreMissingServices = new ReactiveObject<bool>();
  286. IgnoreMissingServices.Event += static (sender, e) => LogValueChange(sender, e, nameof(IgnoreMissingServices));
  287. AudioVolume = new ReactiveObject<float>();
  288. AudioVolume.Event += static (sender, e) => LogValueChange(sender, e, nameof(AudioVolume));
  289. UseHypervisor = new ReactiveObject<bool>();
  290. UseHypervisor.Event += static (sender, e) => LogValueChange(sender, e, nameof(UseHypervisor));
  291. }
  292. }
  293. /// <summary>
  294. /// Hid configuration section
  295. /// </summary>
  296. public class HidSection
  297. {
  298. /// <summary>
  299. /// Enable or disable keyboard support (Independent from controllers binding)
  300. /// </summary>
  301. public ReactiveObject<bool> EnableKeyboard { get; private set; }
  302. /// <summary>
  303. /// Enable or disable mouse support (Independent from controllers binding)
  304. /// </summary>
  305. public ReactiveObject<bool> EnableMouse { get; private set; }
  306. /// <summary>
  307. /// Hotkey Keyboard Bindings
  308. /// </summary>
  309. public ReactiveObject<KeyboardHotkeys> Hotkeys { get; private set; }
  310. /// <summary>
  311. /// Input device configuration.
  312. /// NOTE: This ReactiveObject won't issue an event when the List has elements added or removed.
  313. /// TODO: Implement a ReactiveList class.
  314. /// </summary>
  315. public ReactiveObject<List<InputConfig>> InputConfig { get; private set; }
  316. public HidSection()
  317. {
  318. EnableKeyboard = new ReactiveObject<bool>();
  319. EnableMouse = new ReactiveObject<bool>();
  320. Hotkeys = new ReactiveObject<KeyboardHotkeys>();
  321. InputConfig = new ReactiveObject<List<InputConfig>>();
  322. }
  323. }
  324. /// <summary>
  325. /// Graphics configuration section
  326. /// </summary>
  327. public class GraphicsSection
  328. {
  329. /// <summary>
  330. /// Whether or not backend threading is enabled. The "Auto" setting will determine whether threading should be enabled at runtime.
  331. /// </summary>
  332. public ReactiveObject<BackendThreading> BackendThreading { get; private set; }
  333. /// <summary>
  334. /// Max Anisotropy. Values range from 0 - 16. Set to -1 to let the game decide.
  335. /// </summary>
  336. public ReactiveObject<float> MaxAnisotropy { get; private set; }
  337. /// <summary>
  338. /// Aspect Ratio applied to the renderer window.
  339. /// </summary>
  340. public ReactiveObject<AspectRatio> AspectRatio { get; private set; }
  341. /// <summary>
  342. /// Resolution Scale. An integer scale applied to applicable render targets. Values 1-4, or -1 to use a custom floating point scale instead.
  343. /// </summary>
  344. public ReactiveObject<int> ResScale { get; private set; }
  345. /// <summary>
  346. /// Custom Resolution Scale. A custom floating point scale applied to applicable render targets. Only active when Resolution Scale is -1.
  347. /// </summary>
  348. public ReactiveObject<float> ResScaleCustom { get; private set; }
  349. /// <summary>
  350. /// Dumps shaders in this local directory
  351. /// </summary>
  352. public ReactiveObject<string> ShadersDumpPath { get; private set; }
  353. /// <summary>
  354. /// Enables or disables Vertical Sync
  355. /// </summary>
  356. public ReactiveObject<bool> EnableVsync { get; private set; }
  357. /// <summary>
  358. /// Enables or disables Shader cache
  359. /// </summary>
  360. public ReactiveObject<bool> EnableShaderCache { get; private set; }
  361. /// <summary>
  362. /// Enables or disables texture recompression
  363. /// </summary>
  364. public ReactiveObject<bool> EnableTextureRecompression { get; private set; }
  365. /// <summary>
  366. /// Enables or disables Macro high-level emulation
  367. /// </summary>
  368. public ReactiveObject<bool> EnableMacroHLE { get; private set; }
  369. /// <summary>
  370. /// Graphics backend
  371. /// </summary>
  372. public ReactiveObject<GraphicsBackend> GraphicsBackend { get; private set; }
  373. /// <summary>
  374. /// Applies anti-aliasing to the renderer.
  375. /// </summary>
  376. public ReactiveObject<AntiAliasing> AntiAliasing { get; private set; }
  377. /// <summary>
  378. /// Sets the framebuffer upscaling type.
  379. /// </summary>
  380. public ReactiveObject<ScalingFilter> ScalingFilter { get; private set; }
  381. /// <summary>
  382. /// Sets the framebuffer upscaling level.
  383. /// </summary>
  384. public ReactiveObject<int> ScalingFilterLevel { get; private set; }
  385. /// <summary>
  386. /// Preferred GPU
  387. /// </summary>
  388. public ReactiveObject<string> PreferredGpu { get; private set; }
  389. public GraphicsSection()
  390. {
  391. BackendThreading = new ReactiveObject<BackendThreading>();
  392. BackendThreading.Event += static (sender, e) => LogValueChange(sender, e, nameof(BackendThreading));
  393. ResScale = new ReactiveObject<int>();
  394. ResScale.Event += static (sender, e) => LogValueChange(sender, e, nameof(ResScale));
  395. ResScaleCustom = new ReactiveObject<float>();
  396. ResScaleCustom.Event += static (sender, e) => LogValueChange(sender, e, nameof(ResScaleCustom));
  397. MaxAnisotropy = new ReactiveObject<float>();
  398. MaxAnisotropy.Event += static (sender, e) => LogValueChange(sender, e, nameof(MaxAnisotropy));
  399. AspectRatio = new ReactiveObject<AspectRatio>();
  400. AspectRatio.Event += static (sender, e) => LogValueChange(sender, e, nameof(AspectRatio));
  401. ShadersDumpPath = new ReactiveObject<string>();
  402. EnableVsync = new ReactiveObject<bool>();
  403. EnableVsync.Event += static (sender, e) => LogValueChange(sender, e, nameof(EnableVsync));
  404. EnableShaderCache = new ReactiveObject<bool>();
  405. EnableShaderCache.Event += static (sender, e) => LogValueChange(sender, e, nameof(EnableShaderCache));
  406. EnableTextureRecompression = new ReactiveObject<bool>();
  407. EnableTextureRecompression.Event += static (sender, e) => LogValueChange(sender, e, nameof(EnableTextureRecompression));
  408. GraphicsBackend = new ReactiveObject<GraphicsBackend>();
  409. GraphicsBackend.Event += static (sender, e) => LogValueChange(sender, e, nameof(GraphicsBackend));
  410. PreferredGpu = new ReactiveObject<string>();
  411. PreferredGpu.Event += static (sender, e) => LogValueChange(sender, e, nameof(PreferredGpu));
  412. EnableMacroHLE = new ReactiveObject<bool>();
  413. EnableMacroHLE.Event += static (sender, e) => LogValueChange(sender, e, nameof(EnableMacroHLE));
  414. AntiAliasing = new ReactiveObject<AntiAliasing>();
  415. AntiAliasing.Event += static (sender, e) => LogValueChange(sender, e, nameof(AntiAliasing));
  416. ScalingFilter = new ReactiveObject<ScalingFilter>();
  417. ScalingFilter.Event += static (sender, e) => LogValueChange(sender, e, nameof(ScalingFilter));
  418. ScalingFilterLevel = new ReactiveObject<int>();
  419. ScalingFilterLevel.Event += static (sender, e) => LogValueChange(sender, e, nameof(ScalingFilterLevel));
  420. }
  421. }
  422. /// <summary>
  423. /// The default configuration instance
  424. /// </summary>
  425. public static ConfigurationState Instance { get; private set; }
  426. /// <summary>
  427. /// The Ui section
  428. /// </summary>
  429. public UiSection Ui { get; private set; }
  430. /// <summary>
  431. /// The Logger section
  432. /// </summary>
  433. public LoggerSection Logger { get; private set; }
  434. /// <summary>
  435. /// The System section
  436. /// </summary>
  437. public SystemSection System { get; private set; }
  438. /// <summary>
  439. /// The Graphics section
  440. /// </summary>
  441. public GraphicsSection Graphics { get; private set; }
  442. /// <summary>
  443. /// The Hid section
  444. /// </summary>
  445. public HidSection Hid { get; private set; }
  446. /// <summary>
  447. /// Enables or disables Discord Rich Presence
  448. /// </summary>
  449. public ReactiveObject<bool> EnableDiscordIntegration { get; private set; }
  450. /// <summary>
  451. /// Checks for updates when Ryujinx starts when enabled
  452. /// </summary>
  453. public ReactiveObject<bool> CheckUpdatesOnStart { get; private set; }
  454. /// <summary>
  455. /// Show "Confirm Exit" Dialog
  456. /// </summary>
  457. public ReactiveObject<bool> ShowConfirmExit { get; private set; }
  458. /// <summary>
  459. /// Hide Cursor on Idle
  460. /// </summary>
  461. public ReactiveObject<bool> HideCursorOnIdle { get; private set; }
  462. private ConfigurationState()
  463. {
  464. Ui = new UiSection();
  465. Logger = new LoggerSection();
  466. System = new SystemSection();
  467. Graphics = new GraphicsSection();
  468. Hid = new HidSection();
  469. EnableDiscordIntegration = new ReactiveObject<bool>();
  470. CheckUpdatesOnStart = new ReactiveObject<bool>();
  471. ShowConfirmExit = new ReactiveObject<bool>();
  472. HideCursorOnIdle = new ReactiveObject<bool>();
  473. }
  474. public ConfigurationFileFormat ToFileFormat()
  475. {
  476. ConfigurationFileFormat configurationFile = new ConfigurationFileFormat
  477. {
  478. Version = ConfigurationFileFormat.CurrentVersion,
  479. BackendThreading = Graphics.BackendThreading,
  480. EnableFileLog = Logger.EnableFileLog,
  481. ResScale = Graphics.ResScale,
  482. ResScaleCustom = Graphics.ResScaleCustom,
  483. MaxAnisotropy = Graphics.MaxAnisotropy,
  484. AspectRatio = Graphics.AspectRatio,
  485. AntiAliasing = Graphics.AntiAliasing,
  486. ScalingFilter = Graphics.ScalingFilter,
  487. ScalingFilterLevel = Graphics.ScalingFilterLevel,
  488. GraphicsShadersDumpPath = Graphics.ShadersDumpPath,
  489. LoggingEnableDebug = Logger.EnableDebug,
  490. LoggingEnableStub = Logger.EnableStub,
  491. LoggingEnableInfo = Logger.EnableInfo,
  492. LoggingEnableWarn = Logger.EnableWarn,
  493. LoggingEnableError = Logger.EnableError,
  494. LoggingEnableTrace = Logger.EnableTrace,
  495. LoggingEnableGuest = Logger.EnableGuest,
  496. LoggingEnableFsAccessLog = Logger.EnableFsAccessLog,
  497. LoggingFilteredClasses = Logger.FilteredClasses,
  498. LoggingGraphicsDebugLevel = Logger.GraphicsDebugLevel,
  499. SystemLanguage = System.Language,
  500. SystemRegion = System.Region,
  501. SystemTimeZone = System.TimeZone,
  502. SystemTimeOffset = System.SystemTimeOffset,
  503. DockedMode = System.EnableDockedMode,
  504. EnableDiscordIntegration = EnableDiscordIntegration,
  505. CheckUpdatesOnStart = CheckUpdatesOnStart,
  506. ShowConfirmExit = ShowConfirmExit,
  507. HideCursorOnIdle = HideCursorOnIdle,
  508. EnableVsync = Graphics.EnableVsync,
  509. EnableShaderCache = Graphics.EnableShaderCache,
  510. EnableTextureRecompression = Graphics.EnableTextureRecompression,
  511. EnableMacroHLE = Graphics.EnableMacroHLE,
  512. EnablePtc = System.EnablePtc,
  513. EnableInternetAccess = System.EnableInternetAccess,
  514. EnableFsIntegrityChecks = System.EnableFsIntegrityChecks,
  515. FsGlobalAccessLogMode = System.FsGlobalAccessLogMode,
  516. AudioBackend = System.AudioBackend,
  517. AudioVolume = System.AudioVolume,
  518. MemoryManagerMode = System.MemoryManagerMode,
  519. ExpandRam = System.ExpandRam,
  520. IgnoreMissingServices = System.IgnoreMissingServices,
  521. UseHypervisor = System.UseHypervisor,
  522. GuiColumns = new GuiColumns
  523. {
  524. FavColumn = Ui.GuiColumns.FavColumn,
  525. IconColumn = Ui.GuiColumns.IconColumn,
  526. AppColumn = Ui.GuiColumns.AppColumn,
  527. DevColumn = Ui.GuiColumns.DevColumn,
  528. VersionColumn = Ui.GuiColumns.VersionColumn,
  529. TimePlayedColumn = Ui.GuiColumns.TimePlayedColumn,
  530. LastPlayedColumn = Ui.GuiColumns.LastPlayedColumn,
  531. FileExtColumn = Ui.GuiColumns.FileExtColumn,
  532. FileSizeColumn = Ui.GuiColumns.FileSizeColumn,
  533. PathColumn = Ui.GuiColumns.PathColumn
  534. },
  535. ColumnSort = new ColumnSort
  536. {
  537. SortColumnId = Ui.ColumnSort.SortColumnId,
  538. SortAscending = Ui.ColumnSort.SortAscending
  539. },
  540. GameDirs = Ui.GameDirs,
  541. LanguageCode = Ui.LanguageCode,
  542. EnableCustomTheme = Ui.EnableCustomTheme,
  543. CustomThemePath = Ui.CustomThemePath,
  544. BaseStyle = Ui.BaseStyle,
  545. GameListViewMode = Ui.GameListViewMode,
  546. ShowNames = Ui.ShowNames,
  547. GridSize = Ui.GridSize,
  548. ApplicationSort = Ui.ApplicationSort,
  549. IsAscendingOrder = Ui.IsAscendingOrder,
  550. StartFullscreen = Ui.StartFullscreen,
  551. ShowConsole = Ui.ShowConsole,
  552. EnableKeyboard = Hid.EnableKeyboard,
  553. EnableMouse = Hid.EnableMouse,
  554. Hotkeys = Hid.Hotkeys,
  555. KeyboardConfig = new List<JsonObject>(),
  556. ControllerConfig = new List<JsonObject>(),
  557. InputConfig = Hid.InputConfig,
  558. GraphicsBackend = Graphics.GraphicsBackend,
  559. PreferredGpu = Graphics.PreferredGpu
  560. };
  561. return configurationFile;
  562. }
  563. public void LoadDefault()
  564. {
  565. Logger.EnableFileLog.Value = true;
  566. Graphics.BackendThreading.Value = BackendThreading.Auto;
  567. Graphics.ResScale.Value = 1;
  568. Graphics.ResScaleCustom.Value = 1.0f;
  569. Graphics.MaxAnisotropy.Value = -1.0f;
  570. Graphics.AspectRatio.Value = AspectRatio.Fixed16x9;
  571. Graphics.GraphicsBackend.Value = OperatingSystem.IsMacOS() ? GraphicsBackend.Vulkan : GraphicsBackend.OpenGl;
  572. Graphics.PreferredGpu.Value = "";
  573. Graphics.ShadersDumpPath.Value = "";
  574. Logger.EnableDebug.Value = false;
  575. Logger.EnableStub.Value = true;
  576. Logger.EnableInfo.Value = true;
  577. Logger.EnableWarn.Value = true;
  578. Logger.EnableError.Value = true;
  579. Logger.EnableTrace.Value = false;
  580. Logger.EnableGuest.Value = true;
  581. Logger.EnableFsAccessLog.Value = false;
  582. Logger.FilteredClasses.Value = Array.Empty<LogClass>();
  583. Logger.GraphicsDebugLevel.Value = GraphicsDebugLevel.None;
  584. System.Language.Value = Language.AmericanEnglish;
  585. System.Region.Value = Region.USA;
  586. System.TimeZone.Value = "UTC";
  587. System.SystemTimeOffset.Value = 0;
  588. System.EnableDockedMode.Value = true;
  589. EnableDiscordIntegration.Value = true;
  590. CheckUpdatesOnStart.Value = true;
  591. ShowConfirmExit.Value = true;
  592. HideCursorOnIdle.Value = false;
  593. Graphics.EnableVsync.Value = true;
  594. Graphics.EnableShaderCache.Value = true;
  595. Graphics.EnableTextureRecompression.Value = false;
  596. Graphics.EnableMacroHLE.Value = true;
  597. Graphics.AntiAliasing.Value = AntiAliasing.None;
  598. Graphics.ScalingFilter.Value = ScalingFilter.Bilinear;
  599. Graphics.ScalingFilterLevel.Value = 80;
  600. System.EnablePtc.Value = true;
  601. System.EnableInternetAccess.Value = false;
  602. System.EnableFsIntegrityChecks.Value = true;
  603. System.FsGlobalAccessLogMode.Value = 0;
  604. System.AudioBackend.Value = AudioBackend.SDL2;
  605. System.AudioVolume.Value = 1;
  606. System.MemoryManagerMode.Value = MemoryManagerMode.HostMappedUnsafe;
  607. System.ExpandRam.Value = false;
  608. System.IgnoreMissingServices.Value = false;
  609. System.UseHypervisor.Value = true;
  610. Ui.GuiColumns.FavColumn.Value = true;
  611. Ui.GuiColumns.IconColumn.Value = true;
  612. Ui.GuiColumns.AppColumn.Value = true;
  613. Ui.GuiColumns.DevColumn.Value = true;
  614. Ui.GuiColumns.VersionColumn.Value = true;
  615. Ui.GuiColumns.TimePlayedColumn.Value = true;
  616. Ui.GuiColumns.LastPlayedColumn.Value = true;
  617. Ui.GuiColumns.FileExtColumn.Value = true;
  618. Ui.GuiColumns.FileSizeColumn.Value = true;
  619. Ui.GuiColumns.PathColumn.Value = true;
  620. Ui.ColumnSort.SortColumnId.Value = 0;
  621. Ui.ColumnSort.SortAscending.Value = false;
  622. Ui.GameDirs.Value = new List<string>();
  623. Ui.EnableCustomTheme.Value = false;
  624. Ui.LanguageCode.Value = "en_US";
  625. Ui.CustomThemePath.Value = "";
  626. Ui.BaseStyle.Value = "Dark";
  627. Ui.GameListViewMode.Value = 0;
  628. Ui.ShowNames.Value = true;
  629. Ui.GridSize.Value = 2;
  630. Ui.ApplicationSort.Value = 0;
  631. Ui.IsAscendingOrder.Value = true;
  632. Ui.StartFullscreen.Value = false;
  633. Ui.ShowConsole.Value = true;
  634. Hid.EnableKeyboard.Value = false;
  635. Hid.EnableMouse.Value = false;
  636. Hid.Hotkeys.Value = new KeyboardHotkeys
  637. {
  638. ToggleVsync = Key.F1,
  639. ToggleMute = Key.F2,
  640. Screenshot = Key.F8,
  641. ShowUi = Key.F4,
  642. Pause = Key.F5,
  643. ResScaleUp = Key.Unbound,
  644. ResScaleDown = Key.Unbound,
  645. VolumeUp = Key.Unbound,
  646. VolumeDown = Key.Unbound
  647. };
  648. Hid.InputConfig.Value = new List<InputConfig>
  649. {
  650. new StandardKeyboardInputConfig
  651. {
  652. Version = InputConfig.CurrentVersion,
  653. Backend = InputBackendType.WindowKeyboard,
  654. Id = "0",
  655. PlayerIndex = PlayerIndex.Player1,
  656. ControllerType = ControllerType.JoyconPair,
  657. LeftJoycon = new LeftJoyconCommonConfig<Key>
  658. {
  659. DpadUp = Key.Up,
  660. DpadDown = Key.Down,
  661. DpadLeft = Key.Left,
  662. DpadRight = Key.Right,
  663. ButtonMinus = Key.Minus,
  664. ButtonL = Key.E,
  665. ButtonZl = Key.Q,
  666. ButtonSl = Key.Unbound,
  667. ButtonSr = Key.Unbound
  668. },
  669. LeftJoyconStick = new JoyconConfigKeyboardStick<Key>
  670. {
  671. StickUp = Key.W,
  672. StickDown = Key.S,
  673. StickLeft = Key.A,
  674. StickRight = Key.D,
  675. StickButton = Key.F,
  676. },
  677. RightJoycon = new RightJoyconCommonConfig<Key>
  678. {
  679. ButtonA = Key.Z,
  680. ButtonB = Key.X,
  681. ButtonX = Key.C,
  682. ButtonY = Key.V,
  683. ButtonPlus = Key.Plus,
  684. ButtonR = Key.U,
  685. ButtonZr = Key.O,
  686. ButtonSl = Key.Unbound,
  687. ButtonSr = Key.Unbound
  688. },
  689. RightJoyconStick = new JoyconConfigKeyboardStick<Key>
  690. {
  691. StickUp = Key.I,
  692. StickDown = Key.K,
  693. StickLeft = Key.J,
  694. StickRight = Key.L,
  695. StickButton = Key.H,
  696. }
  697. }
  698. };
  699. }
  700. public ConfigurationLoadResult Load(ConfigurationFileFormat configurationFileFormat, string configurationFilePath)
  701. {
  702. bool configurationFileUpdated = false;
  703. if (configurationFileFormat.Version < 0 || configurationFileFormat.Version > ConfigurationFileFormat.CurrentVersion)
  704. {
  705. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Unsupported configuration version {configurationFileFormat.Version}, loading default.");
  706. LoadDefault();
  707. return ConfigurationLoadResult.NotLoaded;
  708. }
  709. ConfigurationLoadResult result = ConfigurationLoadResult.Success;
  710. if (configurationFileFormat.Version < 2)
  711. {
  712. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 2.");
  713. configurationFileFormat.SystemRegion = Region.USA;
  714. configurationFileUpdated = true;
  715. }
  716. if (configurationFileFormat.Version < 3)
  717. {
  718. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 3.");
  719. configurationFileFormat.SystemTimeZone = "UTC";
  720. configurationFileUpdated = true;
  721. }
  722. if (configurationFileFormat.Version < 4)
  723. {
  724. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 4.");
  725. configurationFileFormat.MaxAnisotropy = -1;
  726. configurationFileUpdated = true;
  727. }
  728. if (configurationFileFormat.Version < 5)
  729. {
  730. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 5.");
  731. configurationFileFormat.SystemTimeOffset = 0;
  732. configurationFileUpdated = true;
  733. }
  734. if (configurationFileFormat.Version < 8)
  735. {
  736. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 8.");
  737. configurationFileFormat.EnablePtc = true;
  738. configurationFileUpdated = true;
  739. }
  740. if (configurationFileFormat.Version < 9)
  741. {
  742. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 9.");
  743. configurationFileFormat.ColumnSort = new ColumnSort
  744. {
  745. SortColumnId = 0,
  746. SortAscending = false
  747. };
  748. configurationFileFormat.Hotkeys = new KeyboardHotkeys
  749. {
  750. ToggleVsync = Key.F1
  751. };
  752. configurationFileUpdated = true;
  753. }
  754. if (configurationFileFormat.Version < 10)
  755. {
  756. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 10.");
  757. configurationFileFormat.AudioBackend = AudioBackend.OpenAl;
  758. configurationFileUpdated = true;
  759. }
  760. if (configurationFileFormat.Version < 11)
  761. {
  762. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 11.");
  763. configurationFileFormat.ResScale = 1;
  764. configurationFileFormat.ResScaleCustom = 1.0f;
  765. configurationFileUpdated = true;
  766. }
  767. if (configurationFileFormat.Version < 12)
  768. {
  769. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 12.");
  770. configurationFileFormat.LoggingGraphicsDebugLevel = GraphicsDebugLevel.None;
  771. configurationFileUpdated = true;
  772. }
  773. if (configurationFileFormat.Version < 14)
  774. {
  775. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 14.");
  776. configurationFileFormat.CheckUpdatesOnStart = true;
  777. configurationFileUpdated = true;
  778. }
  779. if (configurationFileFormat.Version < 16)
  780. {
  781. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 16.");
  782. configurationFileFormat.EnableShaderCache = true;
  783. configurationFileUpdated = true;
  784. }
  785. if (configurationFileFormat.Version < 17)
  786. {
  787. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 17.");
  788. configurationFileFormat.StartFullscreen = false;
  789. configurationFileUpdated = true;
  790. }
  791. if (configurationFileFormat.Version < 18)
  792. {
  793. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 18.");
  794. configurationFileFormat.AspectRatio = AspectRatio.Fixed16x9;
  795. configurationFileUpdated = true;
  796. }
  797. if (configurationFileFormat.Version < 20)
  798. {
  799. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 20.");
  800. configurationFileFormat.ShowConfirmExit = true;
  801. configurationFileUpdated = true;
  802. }
  803. if (configurationFileFormat.Version < 22)
  804. {
  805. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 22.");
  806. configurationFileFormat.HideCursorOnIdle = false;
  807. configurationFileUpdated = true;
  808. }
  809. if (configurationFileFormat.Version < 24)
  810. {
  811. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 24.");
  812. configurationFileFormat.InputConfig = new List<InputConfig>
  813. {
  814. new StandardKeyboardInputConfig
  815. {
  816. Version = InputConfig.CurrentVersion,
  817. Backend = InputBackendType.WindowKeyboard,
  818. Id = "0",
  819. PlayerIndex = PlayerIndex.Player1,
  820. ControllerType = ControllerType.JoyconPair,
  821. LeftJoycon = new LeftJoyconCommonConfig<Key>
  822. {
  823. DpadUp = Key.Up,
  824. DpadDown = Key.Down,
  825. DpadLeft = Key.Left,
  826. DpadRight = Key.Right,
  827. ButtonMinus = Key.Minus,
  828. ButtonL = Key.E,
  829. ButtonZl = Key.Q,
  830. ButtonSl = Key.Unbound,
  831. ButtonSr = Key.Unbound
  832. },
  833. LeftJoyconStick = new JoyconConfigKeyboardStick<Key>
  834. {
  835. StickUp = Key.W,
  836. StickDown = Key.S,
  837. StickLeft = Key.A,
  838. StickRight = Key.D,
  839. StickButton = Key.F,
  840. },
  841. RightJoycon = new RightJoyconCommonConfig<Key>
  842. {
  843. ButtonA = Key.Z,
  844. ButtonB = Key.X,
  845. ButtonX = Key.C,
  846. ButtonY = Key.V,
  847. ButtonPlus = Key.Plus,
  848. ButtonR = Key.U,
  849. ButtonZr = Key.O,
  850. ButtonSl = Key.Unbound,
  851. ButtonSr = Key.Unbound
  852. },
  853. RightJoyconStick = new JoyconConfigKeyboardStick<Key>
  854. {
  855. StickUp = Key.I,
  856. StickDown = Key.K,
  857. StickLeft = Key.J,
  858. StickRight = Key.L,
  859. StickButton = Key.H,
  860. }
  861. }
  862. };
  863. configurationFileUpdated = true;
  864. }
  865. if (configurationFileFormat.Version < 25)
  866. {
  867. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 25.");
  868. configurationFileUpdated = true;
  869. }
  870. if (configurationFileFormat.Version < 26)
  871. {
  872. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 26.");
  873. configurationFileFormat.MemoryManagerMode = MemoryManagerMode.HostMappedUnsafe;
  874. configurationFileUpdated = true;
  875. }
  876. if (configurationFileFormat.Version < 27)
  877. {
  878. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 27.");
  879. configurationFileFormat.EnableMouse = false;
  880. configurationFileUpdated = true;
  881. }
  882. if (configurationFileFormat.Version < 28)
  883. {
  884. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 28.");
  885. configurationFileFormat.Hotkeys = new KeyboardHotkeys
  886. {
  887. ToggleVsync = Key.F1,
  888. Screenshot = Key.F8
  889. };
  890. configurationFileUpdated = true;
  891. }
  892. if (configurationFileFormat.Version < 29)
  893. {
  894. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 29.");
  895. configurationFileFormat.Hotkeys = new KeyboardHotkeys
  896. {
  897. ToggleVsync = Key.F1,
  898. Screenshot = Key.F8,
  899. ShowUi = Key.F4
  900. };
  901. configurationFileUpdated = true;
  902. }
  903. if (configurationFileFormat.Version < 30)
  904. {
  905. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 30.");
  906. foreach(InputConfig config in configurationFileFormat.InputConfig)
  907. {
  908. if (config is StandardControllerInputConfig controllerConfig)
  909. {
  910. controllerConfig.Rumble = new RumbleConfigController
  911. {
  912. EnableRumble = false,
  913. StrongRumble = 1f,
  914. WeakRumble = 1f
  915. };
  916. }
  917. }
  918. configurationFileUpdated = true;
  919. }
  920. if (configurationFileFormat.Version < 31)
  921. {
  922. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 31.");
  923. configurationFileFormat.BackendThreading = BackendThreading.Auto;
  924. configurationFileUpdated = true;
  925. }
  926. if (configurationFileFormat.Version < 32)
  927. {
  928. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 32.");
  929. configurationFileFormat.Hotkeys = new KeyboardHotkeys
  930. {
  931. ToggleVsync = configurationFileFormat.Hotkeys.ToggleVsync,
  932. Screenshot = configurationFileFormat.Hotkeys.Screenshot,
  933. ShowUi = configurationFileFormat.Hotkeys.ShowUi,
  934. Pause = Key.F5
  935. };
  936. configurationFileUpdated = true;
  937. }
  938. if (configurationFileFormat.Version < 33)
  939. {
  940. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 33.");
  941. configurationFileFormat.Hotkeys = new KeyboardHotkeys
  942. {
  943. ToggleVsync = configurationFileFormat.Hotkeys.ToggleVsync,
  944. Screenshot = configurationFileFormat.Hotkeys.Screenshot,
  945. ShowUi = configurationFileFormat.Hotkeys.ShowUi,
  946. Pause = configurationFileFormat.Hotkeys.Pause,
  947. ToggleMute = Key.F2
  948. };
  949. configurationFileFormat.AudioVolume = 1;
  950. configurationFileUpdated = true;
  951. }
  952. if (configurationFileFormat.Version < 34)
  953. {
  954. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 34.");
  955. configurationFileFormat.EnableInternetAccess = false;
  956. configurationFileUpdated = true;
  957. }
  958. if (configurationFileFormat.Version < 35)
  959. {
  960. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 35.");
  961. foreach (InputConfig config in configurationFileFormat.InputConfig)
  962. {
  963. if (config is StandardControllerInputConfig controllerConfig)
  964. {
  965. controllerConfig.RangeLeft = 1.0f;
  966. controllerConfig.RangeRight = 1.0f;
  967. }
  968. }
  969. configurationFileUpdated = true;
  970. }
  971. if (configurationFileFormat.Version < 36)
  972. {
  973. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 36.");
  974. configurationFileFormat.LoggingEnableTrace = false;
  975. configurationFileUpdated = true;
  976. }
  977. if (configurationFileFormat.Version < 37)
  978. {
  979. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 37.");
  980. configurationFileFormat.ShowConsole = true;
  981. configurationFileUpdated = true;
  982. }
  983. if (configurationFileFormat.Version < 38)
  984. {
  985. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 38.");
  986. configurationFileFormat.BaseStyle = "Dark";
  987. configurationFileFormat.GameListViewMode = 0;
  988. configurationFileFormat.ShowNames = true;
  989. configurationFileFormat.GridSize = 2;
  990. configurationFileFormat.LanguageCode = "en_US";
  991. configurationFileUpdated = true;
  992. }
  993. if (configurationFileFormat.Version < 39)
  994. {
  995. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 39.");
  996. configurationFileFormat.Hotkeys = new KeyboardHotkeys
  997. {
  998. ToggleVsync = configurationFileFormat.Hotkeys.ToggleVsync,
  999. Screenshot = configurationFileFormat.Hotkeys.Screenshot,
  1000. ShowUi = configurationFileFormat.Hotkeys.ShowUi,
  1001. Pause = configurationFileFormat.Hotkeys.Pause,
  1002. ToggleMute = configurationFileFormat.Hotkeys.ToggleMute,
  1003. ResScaleUp = Key.Unbound,
  1004. ResScaleDown = Key.Unbound
  1005. };
  1006. configurationFileUpdated = true;
  1007. }
  1008. if (configurationFileFormat.Version < 40)
  1009. {
  1010. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 40.");
  1011. configurationFileFormat.GraphicsBackend = GraphicsBackend.OpenGl;
  1012. result |= ConfigurationLoadResult.MigratedFromPreVulkan;
  1013. configurationFileUpdated = true;
  1014. }
  1015. if (configurationFileFormat.Version < 41)
  1016. {
  1017. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 41.");
  1018. configurationFileFormat.Hotkeys = new KeyboardHotkeys
  1019. {
  1020. ToggleVsync = configurationFileFormat.Hotkeys.ToggleVsync,
  1021. Screenshot = configurationFileFormat.Hotkeys.Screenshot,
  1022. ShowUi = configurationFileFormat.Hotkeys.ShowUi,
  1023. Pause = configurationFileFormat.Hotkeys.Pause,
  1024. ToggleMute = configurationFileFormat.Hotkeys.ToggleMute,
  1025. ResScaleUp = configurationFileFormat.Hotkeys.ResScaleUp,
  1026. ResScaleDown = configurationFileFormat.Hotkeys.ResScaleDown,
  1027. VolumeUp = Key.Unbound,
  1028. VolumeDown = Key.Unbound
  1029. };
  1030. }
  1031. if (configurationFileFormat.Version < 42)
  1032. {
  1033. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 42.");
  1034. configurationFileFormat.EnableMacroHLE = true;
  1035. }
  1036. if (configurationFileFormat.Version < 43)
  1037. {
  1038. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 43.");
  1039. configurationFileFormat.UseHypervisor = true;
  1040. }
  1041. if (configurationFileFormat.Version < 44)
  1042. {
  1043. Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 42.");
  1044. configurationFileFormat.AntiAliasing = AntiAliasing.None;
  1045. configurationFileFormat.ScalingFilter = ScalingFilter.Bilinear;
  1046. configurationFileFormat.ScalingFilterLevel = 80;
  1047. configurationFileUpdated = true;
  1048. }
  1049. Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog;
  1050. Graphics.ResScale.Value = configurationFileFormat.ResScale;
  1051. Graphics.ResScaleCustom.Value = configurationFileFormat.ResScaleCustom;
  1052. Graphics.MaxAnisotropy.Value = configurationFileFormat.MaxAnisotropy;
  1053. Graphics.AspectRatio.Value = configurationFileFormat.AspectRatio;
  1054. Graphics.ShadersDumpPath.Value = configurationFileFormat.GraphicsShadersDumpPath;
  1055. Graphics.BackendThreading.Value = configurationFileFormat.BackendThreading;
  1056. Graphics.GraphicsBackend.Value = configurationFileFormat.GraphicsBackend;
  1057. Graphics.PreferredGpu.Value = configurationFileFormat.PreferredGpu;
  1058. Graphics.AntiAliasing.Value = configurationFileFormat.AntiAliasing;
  1059. Graphics.ScalingFilter.Value = configurationFileFormat.ScalingFilter;
  1060. Graphics.ScalingFilterLevel.Value = configurationFileFormat.ScalingFilterLevel;
  1061. Logger.EnableDebug.Value = configurationFileFormat.LoggingEnableDebug;
  1062. Logger.EnableStub.Value = configurationFileFormat.LoggingEnableStub;
  1063. Logger.EnableInfo.Value = configurationFileFormat.LoggingEnableInfo;
  1064. Logger.EnableWarn.Value = configurationFileFormat.LoggingEnableWarn;
  1065. Logger.EnableError.Value = configurationFileFormat.LoggingEnableError;
  1066. Logger.EnableTrace.Value = configurationFileFormat.LoggingEnableTrace;
  1067. Logger.EnableGuest.Value = configurationFileFormat.LoggingEnableGuest;
  1068. Logger.EnableFsAccessLog.Value = configurationFileFormat.LoggingEnableFsAccessLog;
  1069. Logger.FilteredClasses.Value = configurationFileFormat.LoggingFilteredClasses;
  1070. Logger.GraphicsDebugLevel.Value = configurationFileFormat.LoggingGraphicsDebugLevel;
  1071. System.Language.Value = configurationFileFormat.SystemLanguage;
  1072. System.Region.Value = configurationFileFormat.SystemRegion;
  1073. System.TimeZone.Value = configurationFileFormat.SystemTimeZone;
  1074. System.SystemTimeOffset.Value = configurationFileFormat.SystemTimeOffset;
  1075. System.EnableDockedMode.Value = configurationFileFormat.DockedMode;
  1076. EnableDiscordIntegration.Value = configurationFileFormat.EnableDiscordIntegration;
  1077. CheckUpdatesOnStart.Value = configurationFileFormat.CheckUpdatesOnStart;
  1078. ShowConfirmExit.Value = configurationFileFormat.ShowConfirmExit;
  1079. HideCursorOnIdle.Value = configurationFileFormat.HideCursorOnIdle;
  1080. Graphics.EnableVsync.Value = configurationFileFormat.EnableVsync;
  1081. Graphics.EnableShaderCache.Value = configurationFileFormat.EnableShaderCache;
  1082. Graphics.EnableTextureRecompression.Value = configurationFileFormat.EnableTextureRecompression;
  1083. Graphics.EnableMacroHLE.Value = configurationFileFormat.EnableMacroHLE;
  1084. System.EnablePtc.Value = configurationFileFormat.EnablePtc;
  1085. System.EnableInternetAccess.Value = configurationFileFormat.EnableInternetAccess;
  1086. System.EnableFsIntegrityChecks.Value = configurationFileFormat.EnableFsIntegrityChecks;
  1087. System.FsGlobalAccessLogMode.Value = configurationFileFormat.FsGlobalAccessLogMode;
  1088. System.AudioBackend.Value = configurationFileFormat.AudioBackend;
  1089. System.AudioVolume.Value = configurationFileFormat.AudioVolume;
  1090. System.MemoryManagerMode.Value = configurationFileFormat.MemoryManagerMode;
  1091. System.ExpandRam.Value = configurationFileFormat.ExpandRam;
  1092. System.IgnoreMissingServices.Value = configurationFileFormat.IgnoreMissingServices;
  1093. System.UseHypervisor.Value = configurationFileFormat.UseHypervisor;
  1094. Ui.GuiColumns.FavColumn.Value = configurationFileFormat.GuiColumns.FavColumn;
  1095. Ui.GuiColumns.IconColumn.Value = configurationFileFormat.GuiColumns.IconColumn;
  1096. Ui.GuiColumns.AppColumn.Value = configurationFileFormat.GuiColumns.AppColumn;
  1097. Ui.GuiColumns.DevColumn.Value = configurationFileFormat.GuiColumns.DevColumn;
  1098. Ui.GuiColumns.VersionColumn.Value = configurationFileFormat.GuiColumns.VersionColumn;
  1099. Ui.GuiColumns.TimePlayedColumn.Value = configurationFileFormat.GuiColumns.TimePlayedColumn;
  1100. Ui.GuiColumns.LastPlayedColumn.Value = configurationFileFormat.GuiColumns.LastPlayedColumn;
  1101. Ui.GuiColumns.FileExtColumn.Value = configurationFileFormat.GuiColumns.FileExtColumn;
  1102. Ui.GuiColumns.FileSizeColumn.Value = configurationFileFormat.GuiColumns.FileSizeColumn;
  1103. Ui.GuiColumns.PathColumn.Value = configurationFileFormat.GuiColumns.PathColumn;
  1104. Ui.ColumnSort.SortColumnId.Value = configurationFileFormat.ColumnSort.SortColumnId;
  1105. Ui.ColumnSort.SortAscending.Value = configurationFileFormat.ColumnSort.SortAscending;
  1106. Ui.GameDirs.Value = configurationFileFormat.GameDirs;
  1107. Ui.EnableCustomTheme.Value = configurationFileFormat.EnableCustomTheme;
  1108. Ui.LanguageCode.Value = configurationFileFormat.LanguageCode;
  1109. Ui.CustomThemePath.Value = configurationFileFormat.CustomThemePath;
  1110. Ui.BaseStyle.Value = configurationFileFormat.BaseStyle;
  1111. Ui.GameListViewMode.Value = configurationFileFormat.GameListViewMode;
  1112. Ui.ShowNames.Value = configurationFileFormat.ShowNames;
  1113. Ui.IsAscendingOrder.Value = configurationFileFormat.IsAscendingOrder;
  1114. Ui.GridSize.Value = configurationFileFormat.GridSize;
  1115. Ui.ApplicationSort.Value = configurationFileFormat.ApplicationSort;
  1116. Ui.StartFullscreen.Value = configurationFileFormat.StartFullscreen;
  1117. Ui.ShowConsole.Value = configurationFileFormat.ShowConsole;
  1118. Hid.EnableKeyboard.Value = configurationFileFormat.EnableKeyboard;
  1119. Hid.EnableMouse.Value = configurationFileFormat.EnableMouse;
  1120. Hid.Hotkeys.Value = configurationFileFormat.Hotkeys;
  1121. Hid.InputConfig.Value = configurationFileFormat.InputConfig;
  1122. if (Hid.InputConfig.Value == null)
  1123. {
  1124. Hid.InputConfig.Value = new List<InputConfig>();
  1125. }
  1126. if (configurationFileUpdated)
  1127. {
  1128. ToFileFormat().SaveConfig(configurationFilePath);
  1129. Ryujinx.Common.Logging.Logger.Notice.Print(LogClass.Application, $"Configuration file updated to version {ConfigurationFileFormat.CurrentVersion}");
  1130. }
  1131. return result;
  1132. }
  1133. private static void LogValueChange<T>(object sender, ReactiveEventArgs<T> eventArgs, string valueName)
  1134. {
  1135. Ryujinx.Common.Logging.Logger.Info?.Print(LogClass.Configuration, $"{valueName} set to: {eventArgs.NewValue}");
  1136. }
  1137. public static void Initialize()
  1138. {
  1139. if (Instance != null)
  1140. {
  1141. throw new InvalidOperationException("Configuration is already initialized");
  1142. }
  1143. Instance = new ConfigurationState();
  1144. }
  1145. }
  1146. }