[options] Refactor INI options
This change introduces a new class to handle all of the INI options data, VbamOption. A VbamOption represents a single option in the INI file. It is not constructible outside of its implementation, which prevents the initialization of incorrectly formatted options. Internally, a VbamOption points to a global variable in memory, which holds the value used at runtime. This is because various parts of the codebase edit the global variable rather than going through a central registry. This also means we need to separately update the INI values. In the future, we may be able to convert all existing reads and writes to the global variable to go through VbamOption. Individual UX elements could link directly to getters/setters for a specific VbamOption rather than have duplicate data. VbamOption replaces the opt_desc struct and the global opts array. All users of opt_desc and the global opts array have been updated. This is a necessary preliminary change to better support a refactor of accelerators, through wxUserInput. Issue: #745, #158
This commit is contained in:
parent
dd6071e5cb
commit
c4d46a713f
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2022-09-21 17:52+0000\n"
|
||||
"POT-Creation-Date: 2022-09-06 21:07-0700\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
@ -17,55 +17,55 @@ msgstr ""
|
|||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: wxvbam.cpp:225
|
||||
#: wxvbam.cpp:227
|
||||
msgid "visualboyadvance-m"
|
||||
msgstr ""
|
||||
|
||||
#: wxvbam.cpp:446
|
||||
#: wxvbam.cpp:448
|
||||
msgid "Could not create main window"
|
||||
msgstr ""
|
||||
|
||||
#: wxvbam.cpp:517
|
||||
#: wxvbam.cpp:519
|
||||
msgid "Save built-in XRC file and exit"
|
||||
msgstr ""
|
||||
|
||||
#: wxvbam.cpp:520
|
||||
#: wxvbam.cpp:522
|
||||
msgid "Save built-in vba-over.ini and exit"
|
||||
msgstr ""
|
||||
|
||||
#: wxvbam.cpp:523
|
||||
#: wxvbam.cpp:525
|
||||
msgid "Print configuration path and exit"
|
||||
msgstr ""
|
||||
|
||||
#: wxvbam.cpp:526
|
||||
#: wxvbam.cpp:528
|
||||
msgid "Start in full-screen mode"
|
||||
msgstr ""
|
||||
|
||||
#: wxvbam.cpp:529
|
||||
#: wxvbam.cpp:531
|
||||
msgid "Set a configuration file"
|
||||
msgstr ""
|
||||
|
||||
#: wxvbam.cpp:533
|
||||
#: wxvbam.cpp:535
|
||||
msgid "Delete shared link state first, if it exists"
|
||||
msgstr ""
|
||||
|
||||
#: wxvbam.cpp:540
|
||||
#: wxvbam.cpp:542
|
||||
msgid "List all settable options and exit"
|
||||
msgstr ""
|
||||
|
||||
#: wxvbam.cpp:543
|
||||
#: wxvbam.cpp:545
|
||||
msgid "ROM file"
|
||||
msgstr ""
|
||||
|
||||
#: wxvbam.cpp:545
|
||||
#: wxvbam.cpp:547
|
||||
msgid "<config>=<value>"
|
||||
msgstr ""
|
||||
|
||||
#: wxvbam.cpp:576
|
||||
#: wxvbam.cpp:578
|
||||
msgid "Configuration/build error: can't find built-in xrc"
|
||||
msgstr ""
|
||||
|
||||
#: wxvbam.cpp:584
|
||||
#: wxvbam.cpp:586
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Wrote built-in configuration to %s.\n"
|
||||
|
@ -74,11 +74,11 @@ msgid ""
|
|||
"built-in:"
|
||||
msgstr ""
|
||||
|
||||
#: wxvbam.cpp:599
|
||||
#: wxvbam.cpp:601
|
||||
msgid "Configuration is read from, in order:"
|
||||
msgstr ""
|
||||
|
||||
#: wxvbam.cpp:613
|
||||
#: wxvbam.cpp:615
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Wrote built-in override file to %s\n"
|
||||
|
@ -86,13 +86,13 @@ msgid ""
|
|||
"from search path:"
|
||||
msgstr ""
|
||||
|
||||
#: wxvbam.cpp:619
|
||||
#: wxvbam.cpp:621
|
||||
msgid ""
|
||||
"\n"
|
||||
"\tbuilt-in"
|
||||
msgstr ""
|
||||
|
||||
#: wxvbam.cpp:630
|
||||
#: wxvbam.cpp:636
|
||||
msgid ""
|
||||
"Options set from the command line are saved if any configuration changes are "
|
||||
"made in the user interface.\n"
|
||||
|
@ -101,255 +101,255 @@ msgid ""
|
|||
"\n"
|
||||
msgstr ""
|
||||
|
||||
#: wxvbam.cpp:651
|
||||
#: wxvbam.cpp:644
|
||||
msgid ""
|
||||
"The commands available for the Keyboard/* option are:\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
|
||||
#: wxvbam.cpp:663
|
||||
#: wxvbam.cpp:655
|
||||
msgid "Configuration file not found."
|
||||
msgstr ""
|
||||
|
||||
#: wxvbam.cpp:696
|
||||
#: wxvbam.cpp:688
|
||||
msgid "Bad configuration option or multiple ROM files given:\n"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:83
|
||||
#: guiinit.cpp:84
|
||||
msgid "Start!"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:102 xrc/NetLink.xrc:99
|
||||
#: guiinit.cpp:103 xrc/NetLink.xrc:99
|
||||
msgid "Connect"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:119
|
||||
#: guiinit.cpp:120
|
||||
msgid "You must enter a valid host name"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:120
|
||||
#: guiinit.cpp:121
|
||||
msgid "Host name invalid"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:138
|
||||
#: guiinit.cpp:139
|
||||
msgid "Waiting for clients..."
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:139
|
||||
#: guiinit.cpp:140
|
||||
#, c-format
|
||||
msgid "Server IP address is: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:141
|
||||
#: guiinit.cpp:142
|
||||
msgid "Waiting for connection..."
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:142
|
||||
#: guiinit.cpp:143
|
||||
#, c-format
|
||||
msgid "Connecting to %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:175
|
||||
#: guiinit.cpp:176
|
||||
msgid ""
|
||||
"Error occurred.\n"
|
||||
"Please try again."
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:242 guiinit.cpp:295
|
||||
#: guiinit.cpp:243 guiinit.cpp:296
|
||||
msgid "Select cheat file"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:243
|
||||
#: guiinit.cpp:244
|
||||
msgid "VBA cheat lists (*.clt)|*.clt|CHT cheat lists (*.cht)|*.cht"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:262 panel.cpp:449
|
||||
#: guiinit.cpp:263 panel.cpp:449
|
||||
msgid "Loaded cheats"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:296
|
||||
#: guiinit.cpp:297
|
||||
msgid "VBA cheat lists (*.clt)|*.clt"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:314
|
||||
#: guiinit.cpp:315
|
||||
msgid "Saved cheats"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:345 guiinit.cpp:364
|
||||
#: guiinit.cpp:346 guiinit.cpp:365
|
||||
msgid "Restore old values?"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:346 guiinit.cpp:365
|
||||
#: guiinit.cpp:347 guiinit.cpp:366
|
||||
msgid "Removing cheats"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:756 xrc/JoyPanel.xrc:364
|
||||
#: guiinit.cpp:757 xrc/JoyPanel.xrc:364
|
||||
msgid "GameShark"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:757 cmdevents.cpp:678
|
||||
#: guiinit.cpp:758 cmdevents.cpp:675
|
||||
msgid "GameGenie"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:759
|
||||
#: guiinit.cpp:760
|
||||
msgid "Generic Code"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:760
|
||||
#: guiinit.cpp:761
|
||||
msgid "GameShark Advance"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:761
|
||||
#: guiinit.cpp:762
|
||||
msgid "CodeBreaker Advance"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:762
|
||||
#: guiinit.cpp:763
|
||||
msgid "Flashcart CHT"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:830 guiinit.cpp:1085
|
||||
#: guiinit.cpp:831 guiinit.cpp:1086
|
||||
msgid "Number cannot be empty"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:868
|
||||
#: guiinit.cpp:869
|
||||
#, c-format
|
||||
msgid "Search produced %d results. Please refine better"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:880
|
||||
#: guiinit.cpp:881
|
||||
msgid "Search produced no results"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:1043
|
||||
#: guiinit.cpp:1044
|
||||
msgid "8-bit "
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:1047
|
||||
#: guiinit.cpp:1048
|
||||
msgid "16-bit "
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:1051
|
||||
#: guiinit.cpp:1052
|
||||
msgid "32-bit "
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:1057
|
||||
#: guiinit.cpp:1058
|
||||
msgid "signed decimal"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:1061
|
||||
#: guiinit.cpp:1062
|
||||
msgid "unsigned decimal"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:1065
|
||||
#: guiinit.cpp:1066
|
||||
msgid "unsigned hexadecimal"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:1543
|
||||
#: guiinit.cpp:1544
|
||||
#, c-format
|
||||
msgid "%d frames = %.2f ms"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:1555
|
||||
#: guiinit.cpp:1556
|
||||
msgid "Default device"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:1726
|
||||
#: guiinit.cpp:1727
|
||||
msgid "Desktop mode"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:1733
|
||||
#: guiinit.cpp:1734
|
||||
#, c-format
|
||||
msgid "%d x %d - %dbpp @ %dHz"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:1846 cmdevents.cpp:748 xrc/DisplayConfig.xrc:85
|
||||
#: guiinit.cpp:1847 cmdevents.cpp:745 xrc/DisplayConfig.xrc:85
|
||||
#: xrc/DisplayConfig.xrc:135 xrc/DisplayConfig.xrc:221
|
||||
#: xrc/GameBoyAdvanceConfig.xrc:32 xrc/GameBoyAdvanceConfig.xrc:204
|
||||
#: xrc/SoundConfig.xrc:219 xrc/SoundConfig.xrc:309
|
||||
msgid "None"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:1887
|
||||
#: guiinit.cpp:1888
|
||||
#, c-format
|
||||
msgid "No usable rpi plugins found in %s"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:1907 xrc/DisplayConfig.xrc:107
|
||||
#: guiinit.cpp:1908 xrc/DisplayConfig.xrc:107
|
||||
msgid "Plugin"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:1935
|
||||
#: guiinit.cpp:1936
|
||||
msgid "Please select a plugin or a different filter"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:1936
|
||||
#: guiinit.cpp:1937
|
||||
msgid "Plugin selection error"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:2149
|
||||
#: guiinit.cpp:2150
|
||||
msgid "This will clear all user-defined accelerators. Are you sure?"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:2149
|
||||
#: guiinit.cpp:2150
|
||||
msgid "Confirm"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:2740
|
||||
#: guiinit.cpp:2741
|
||||
msgid "Main icon not found"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:2750
|
||||
#: guiinit.cpp:2751
|
||||
msgid "Browse"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:2764
|
||||
#: guiinit.cpp:2765
|
||||
msgid "Main display panel not found"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:2941
|
||||
#: guiinit.cpp:2942
|
||||
#, c-format
|
||||
msgid "Duplicate menu accelerator: %s for %s and %s; keeping first"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:2955
|
||||
#: guiinit.cpp:2956
|
||||
#, c-format
|
||||
msgid "Menu accelerator %s for %s overrides default for %s ; keeping menu"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:3094
|
||||
#: guiinit.cpp:3097
|
||||
#, c-format
|
||||
msgid "Invalid menu item %s; removing"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:3302
|
||||
#: guiinit.cpp:3305
|
||||
msgid "Code"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:3311
|
||||
#: guiinit.cpp:3314
|
||||
msgid "Description"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:3385 xrc/CheatAdd.xrc:31
|
||||
#: guiinit.cpp:3388 xrc/CheatAdd.xrc:31
|
||||
msgid "Address"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:3386
|
||||
#: guiinit.cpp:3389
|
||||
msgid "Old Value"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:3387
|
||||
#: guiinit.cpp:3390
|
||||
msgid "New Value"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:3918
|
||||
#: guiinit.cpp:3917
|
||||
msgid "Menu commands"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:3941
|
||||
#: guiinit.cpp:3940
|
||||
msgid "Other commands"
|
||||
msgstr ""
|
||||
|
||||
#: guiinit.cpp:4052
|
||||
#: guiinit.cpp:4051
|
||||
msgid "JoyBus host invalid; disabling"
|
||||
msgstr ""
|
||||
|
||||
|
@ -851,29 +851,19 @@ msgstr ""
|
|||
msgid "Network is not supported in local mode."
|
||||
msgstr ""
|
||||
|
||||
#: opts.cpp:649 opts.cpp:951
|
||||
#, c-format
|
||||
msgid "Invalid value %s for option %s; valid values are %s%s%s"
|
||||
msgstr ""
|
||||
|
||||
#: opts.cpp:666 opts.cpp:963
|
||||
#, c-format
|
||||
msgid "Invalid value %d for option %s; valid values are %d - %d"
|
||||
msgstr ""
|
||||
|
||||
#: opts.cpp:673 opts.cpp:682 opts.cpp:971 opts.cpp:979
|
||||
#, c-format
|
||||
msgid "Invalid value %f for option %s; valid values are %f - %f"
|
||||
msgstr ""
|
||||
|
||||
#: opts.cpp:739 opts.cpp:760 opts.cpp:1047
|
||||
#: opts.cpp:492 opts.cpp:513 opts.cpp:745
|
||||
#, c-format
|
||||
msgid "Invalid key binding %s for %s"
|
||||
msgstr ""
|
||||
|
||||
#: opts.cpp:934
|
||||
#: opts.cpp:668 opts.cpp:677 opts.cpp:686 opts.cpp:695 vbam-options.cpp:313
|
||||
#, c-format
|
||||
msgid "Invalid flag option %s - %s ignored"
|
||||
msgid "Invalid value %s for option %s"
|
||||
msgstr ""
|
||||
|
||||
#: opts.cpp:767
|
||||
#, c-format
|
||||
msgid "Unknown option %s with value %s"
|
||||
msgstr ""
|
||||
|
||||
#: sys.cpp:195 sys.cpp:256
|
||||
|
@ -1110,6 +1100,456 @@ msgstr ""
|
|||
msgid "Error in video recording (%s); aborting"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options.cpp:218
|
||||
#, c-format
|
||||
msgid "Invalid value %f for option %s; valid values are %f - %f"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options.cpp:232 vbam-options.cpp:246
|
||||
#, c-format
|
||||
msgid "Invalid value %d for option %s; valid values are %d - %d"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options.cpp:297
|
||||
#, c-format
|
||||
msgid "Invalid value %d for option %s; valid values are %s"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:342
|
||||
msgid "Use bilinear filter with 3d renderer"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:343
|
||||
msgid "Full-screen filter to apply"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:344
|
||||
msgid "Filter plugin library"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:345
|
||||
msgid "Interframe blending function"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:346
|
||||
msgid "Keep window on top"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:347
|
||||
msgid "Maximum number of threads to run filters in"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:348
|
||||
msgid "Render method; if unsupported, simple method will be used"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:349
|
||||
msgid "Default scale factor"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:350
|
||||
msgid "Retain aspect ratio when resizing"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:353
|
||||
msgid "BIOS file to use for GB, if enabled"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:354
|
||||
msgid "GB color enhancement, if enabled"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:355
|
||||
msgid "Enable DX Colorization Hacks"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:356 vbam-options-static.cpp:368
|
||||
msgid "Apply LCD filter, if enabled"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:357
|
||||
msgid "BIOS file to use for GBC, if enabled"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:358
|
||||
msgid ""
|
||||
"The default palette, as 8 comma-separated 4-digit hex integers (rgb555)."
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:359
|
||||
msgid ""
|
||||
"The first user palette, as 8 comma-separated 4-digit hex integers (rgb555)."
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:360
|
||||
msgid ""
|
||||
"The second user palette, as 8 comma-separated 4-digit hex integers (rgb555)."
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:361
|
||||
msgid "Automatically gather a full page before printing"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:362
|
||||
msgid "Automatically save printouts as screen captures with -print suffix"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:363 vbam-options-static.cpp:379
|
||||
msgid "Directory to look for ROM files"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:364
|
||||
msgid "Directory to look for GBC ROM files"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:367
|
||||
msgid "BIOS file to use, if enabled"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:370
|
||||
msgid "Enable link at boot"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:371
|
||||
msgid "Enable faster network protocol by default"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:372
|
||||
msgid "Default network link client host"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:373
|
||||
msgid "Default network link server IP to bind"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:374
|
||||
msgid "Default network link port (server and client)"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:375
|
||||
msgid "Default network protocol"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:376
|
||||
msgid "Link timeout (ms)"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:377
|
||||
msgid "Link cable type"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:382
|
||||
msgid "Automatically load last saved state"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:383
|
||||
msgid ""
|
||||
"Directory to store game save files (relative paths are relative to ROM; "
|
||||
"blank is config dir)"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:384
|
||||
msgid "Freeze recent load list"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:385
|
||||
msgid ""
|
||||
"Directory to store A/V and game recordings (relative paths are relative to "
|
||||
"ROM)"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:386
|
||||
msgid "Number of seconds between rewind snapshots (0 to disable)"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:387
|
||||
msgid "Directory to store screenshots (relative paths are relative to ROM)"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:388
|
||||
msgid ""
|
||||
"Directory to store saved state files (relative paths are relative to "
|
||||
"BatteryDir)"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:389
|
||||
msgid "Enable status bar"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:392
|
||||
msgid ""
|
||||
"The parameter Joypad/<n>/<button> contains a comma-separated list of key "
|
||||
"names which map to joypad #<n> button <button>. Button is one of Up, Down, "
|
||||
"Left, Right, A, B, L, R, Select, Start, MotionUp, MotionDown, MotionLeft, "
|
||||
"MotionRight, AutoA, AutoB, Speed, Capture, GS"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:393
|
||||
msgid "The autofire toggle period, in frames (1/60 s)"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:394
|
||||
msgid "The number of the stick to use in single-player mode"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:397
|
||||
msgid ""
|
||||
"The parameter Keyboard/<cmd> contains a comma-separated list of key names (e."
|
||||
"g. Alt-Shift-F1). When the named key is pressed, the command <cmd> is "
|
||||
"executed."
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:400
|
||||
msgid "Enable AGB debug print"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:401
|
||||
msgid "Auto skip frames."
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:402
|
||||
msgid "Apply IPS/UPS/IPF patches if found"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:403
|
||||
msgid "Automatically save and load cheat list"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:404
|
||||
msgid "Automatically enable border for Super GameBoy games"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:405
|
||||
msgid "Always enable border"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:406
|
||||
msgid "Screen capture file format"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:407
|
||||
msgid "Enable cheats"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:409 xrc/MainMenu.xrc:355
|
||||
msgid "Enable MMX"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:411
|
||||
msgid "Disable on-screen status messages"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:412
|
||||
msgid "Type of system to emulate"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:413
|
||||
msgid "Flash size 0 = 64KB 1 = 128KB"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:414
|
||||
msgid "Skip frames. Values are 0-9 or -1 to skip automatically based on time."
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:415
|
||||
msgid "Fullscreen mode color depth (0 = any)"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:416
|
||||
msgid "Fullscreen mode frequency (0 = any)"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:417
|
||||
msgid "Fullscreen mode height (0 = desktop)"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:418
|
||||
msgid "Fullscreen mode width (0 = desktop)"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:419
|
||||
msgid "The palette to use"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:420
|
||||
msgid "Enable printer emulation"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:421
|
||||
msgid "Break into GDB after loading the game."
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:422
|
||||
msgid "Port to connect GDB to."
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:424
|
||||
msgid "Number of players in network"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:426
|
||||
msgid "Maximum scale factor (0 = no limit)"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:427
|
||||
msgid "Pause game when main window loses focus"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:428
|
||||
msgid "Enable RTC (vba-over.ini override is rtcEnabled"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:429
|
||||
msgid "Native save (\"battery\") hardware type"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:430
|
||||
msgid "Show speed indicator"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:431
|
||||
msgid "Draw on-screen messages transparently"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:432
|
||||
msgid "Skip BIOS initialization"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:433
|
||||
msgid "Do not overwrite cheat list when loading state"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:434
|
||||
msgid "Do not overwrite native (battery) save when loading state"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:435
|
||||
msgid "Throttle game speed, even when accelerated (0-450%, 0 = no throttle)"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:436
|
||||
msgid "Set throttle for speedup key (0-3000%, 0 = no throttle)"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:437
|
||||
msgid "Number of frames to skip with speedup (instead of speedup throttle)"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:438
|
||||
msgid "Use frame skip for speedup throttle"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:439
|
||||
msgid "Use the specified BIOS file for GB"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:440
|
||||
msgid "Use the specified BIOS file"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:441
|
||||
msgid "Use the specified BIOS file for GBC"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:442
|
||||
msgid "Wait for vertical sync"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:445
|
||||
msgid "Enter fullscreen mode at startup"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:446
|
||||
msgid "Window maximized"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:447
|
||||
msgid "Window height at startup"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:448
|
||||
msgid "Window width at startup"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:449
|
||||
msgid "Window axis X position at startup"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:450
|
||||
msgid "Window axis Y position at startup"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:453
|
||||
msgid "Capture key events while on background"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:454
|
||||
msgid "Capture joy events while on background"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:455
|
||||
msgid "Hide menu bar when mouse is inactive"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:458
|
||||
msgid "Sound API; if unsupported, default API will be used"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:459
|
||||
msgid "Device ID of chosen audio device for chosen driver"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:460
|
||||
msgid "Number of sound buffers"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:461
|
||||
msgid "Bit mask of sound channels to enable"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:462
|
||||
msgid "GBA sound filtering (%)"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:463
|
||||
msgid "GBA sound interpolation"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:464
|
||||
msgid "GB sound declicking"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:465
|
||||
msgid "GB echo effect (%)"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:466
|
||||
msgid "Enable GB sound effects"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:467
|
||||
msgid "GB stereo effect (%)"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:468
|
||||
msgid "GB surround sound effect (%)"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:469
|
||||
msgid "Sound sample rate (kHz)"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:470
|
||||
msgid "Sound volume (%)"
|
||||
msgstr ""
|
||||
|
||||
#: vbam-options-static.cpp:669 vbam-options-static.cpp:688
|
||||
#: vbam-options-static.cpp:711 vbam-options-static.cpp:732
|
||||
#: vbam-options-static.cpp:752
|
||||
#, c-format
|
||||
msgid "Invalid value %s for option %s; valid values are %s"
|
||||
msgstr ""
|
||||
|
||||
#: viewsupt.cpp:776
|
||||
msgid "R:"
|
||||
msgstr ""
|
||||
|
@ -3024,10 +3464,6 @@ msgstr ""
|
|||
msgid "&Retain aspect ratio"
|
||||
msgstr ""
|
||||
|
||||
#: xrc/MainMenu.xrc:355
|
||||
msgid "Enable MMX"
|
||||
msgstr ""
|
||||
|
||||
#: xrc/MainMenu.xrc:360
|
||||
msgid "&Bilinear filter"
|
||||
msgstr ""
|
||||
|
|
|
@ -733,6 +733,8 @@ set(
|
|||
opts.cpp
|
||||
sys.cpp
|
||||
panel.cpp
|
||||
vbam-options.cpp
|
||||
vbam-options-static.cpp
|
||||
viewsupt.cpp
|
||||
wayland.cpp
|
||||
strutils.cpp
|
||||
|
@ -767,6 +769,8 @@ set(
|
|||
filters.h
|
||||
ioregs.h
|
||||
opts.h
|
||||
vbam-options.h
|
||||
vbam-options-internal.h
|
||||
viewsupt.h
|
||||
wxhead.h
|
||||
wayland.h
|
||||
|
|
|
@ -31,10 +31,10 @@ bool cmditem_lt(const struct cmditem& cmd1, const struct cmditem& cmd2)
|
|||
return wxStrcmp(cmd1.cmd, cmd2.cmd) < 0;
|
||||
}
|
||||
|
||||
void MainFrame::GetMenuOptionBool(const char* menuName, bool& field)
|
||||
void MainFrame::GetMenuOptionBool(const wxString& menuName, bool field)
|
||||
{
|
||||
field = !field;
|
||||
int id = wxXmlResource::GetXRCID(wxString(menuName, wxConvUTF8));
|
||||
int id = wxXmlResource::GetXRCID(menuName);
|
||||
|
||||
for (size_t i = 0; i < checkable_mi.size(); i++) {
|
||||
if (checkable_mi[i].cmd != id)
|
||||
|
@ -45,11 +45,11 @@ void MainFrame::GetMenuOptionBool(const char* menuName, bool& field)
|
|||
}
|
||||
}
|
||||
|
||||
void MainFrame::GetMenuOptionInt(const char* menuName, int& field, int mask)
|
||||
void MainFrame::GetMenuOptionInt(const wxString& menuName, int field, int mask)
|
||||
{
|
||||
int value = mask;
|
||||
bool is_checked = ((field) & (mask)) != (value);
|
||||
int id = wxXmlResource::GetXRCID(wxString(menuName, wxConvUTF8));
|
||||
int id = wxXmlResource::GetXRCID(menuName);
|
||||
|
||||
for (size_t i = 0; i < checkable_mi.size(); i++) {
|
||||
if (checkable_mi[i].cmd != id)
|
||||
|
@ -62,9 +62,9 @@ void MainFrame::GetMenuOptionInt(const char* menuName, int& field, int mask)
|
|||
field = ((field) & ~(mask)) | (is_checked ? (value) : 0);
|
||||
}
|
||||
|
||||
void MainFrame::SetMenuOption(const char* menuName, int value)
|
||||
void MainFrame::SetMenuOption(const wxString& menuName, int value)
|
||||
{
|
||||
int id = wxXmlResource::GetXRCID(wxString(menuName, wxConvUTF8));
|
||||
int id = wxXmlResource::GetXRCID(menuName);
|
||||
|
||||
for (size_t i = 0; i < checkable_mi.size(); i++) {
|
||||
if (checkable_mi[i].cmd != id)
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <wx/wfstream.h>
|
||||
|
||||
#include "opts.h"
|
||||
#include "vbam-options.h"
|
||||
#include "wx/gamecontrol.h"
|
||||
#include "wx/userinput.h"
|
||||
#include "../gba/CheatSearch.h"
|
||||
|
@ -2651,30 +2652,30 @@ void MainFrame::set_global_accels()
|
|||
SetRecentAccels();
|
||||
}
|
||||
|
||||
void MainFrame::MenuOptionBool(const char* menuName, bool& field)
|
||||
void MainFrame::MenuOptionBool(const wxString& menuName, bool field)
|
||||
{
|
||||
int id = wxXmlResource::GetXRCID(wxString(menuName, wxConvUTF8));
|
||||
int id = wxXmlResource::GetXRCID(menuName);
|
||||
|
||||
for (size_t i = 0; i < checkable_mi.size(); i++) {
|
||||
if (checkable_mi[i].cmd != id)
|
||||
continue;
|
||||
|
||||
checkable_mi[i].boolopt = &field;
|
||||
checkable_mi[i].initialized = true;
|
||||
checkable_mi[i].mi->Check(field);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MainFrame::MenuOptionIntMask(const char* menuName, int& field, int mask)
|
||||
void MainFrame::MenuOptionIntMask(const wxString& menuName, int field, int mask)
|
||||
{
|
||||
int id = wxXmlResource::GetXRCID(wxString(menuName, wxConvUTF8));
|
||||
int id = wxXmlResource::GetXRCID(menuName);
|
||||
int value = mask;
|
||||
|
||||
for (size_t i = 0; i < checkable_mi.size(); i++) {
|
||||
if (checkable_mi[i].cmd != id)
|
||||
continue;
|
||||
|
||||
checkable_mi[i].intopt = &field;
|
||||
checkable_mi[i].initialized = true;
|
||||
checkable_mi[i].mask = mask;
|
||||
checkable_mi[i].val = value;
|
||||
checkable_mi[i].mi->Check((field & mask) == value);
|
||||
|
@ -2682,15 +2683,15 @@ void MainFrame::MenuOptionIntMask(const char* menuName, int& field, int mask)
|
|||
}
|
||||
}
|
||||
|
||||
void MainFrame::MenuOptionIntRadioValue(const char* menuName, int& field, int value)
|
||||
void MainFrame::MenuOptionIntRadioValue(const wxString& menuName, int field, int value)
|
||||
{
|
||||
int id = wxXmlResource::GetXRCID(wxString(menuName, wxConvUTF8));
|
||||
int id = wxXmlResource::GetXRCID(menuName);
|
||||
|
||||
for (size_t i = 0; i < checkable_mi.size(); i++) {
|
||||
if (checkable_mi[i].cmd != id)
|
||||
continue;
|
||||
|
||||
checkable_mi[i].intopt = &field;
|
||||
checkable_mi[i].initialized = true;
|
||||
checkable_mi[i].val = field;
|
||||
checkable_mi[i].mi->Check(field == value);
|
||||
break;
|
||||
|
@ -2973,17 +2974,14 @@ bool MainFrame::BindControls()
|
|||
|
||||
// store checkable items
|
||||
if (mi->IsCheckable()) {
|
||||
checkable_mi_t cmi = { cmdtab[i].cmd_id, mi, NULL, NULL, 0, 0 };
|
||||
checkable_mi_t cmi = { cmdtab[i].cmd_id, mi, 0, 0 };
|
||||
checkable_mi.push_back(cmi);
|
||||
|
||||
for (int j = 0; j < num_opts; j++) {
|
||||
wxString menuName = wxString(opts[j].cmd, wxConvUTF8);
|
||||
|
||||
if (menuName == cmdtab[i].cmd) {
|
||||
if (opts[j].intopt)
|
||||
MenuOptionIntMask(opts[j].cmd, *opts[j].intopt, (1 << 0));
|
||||
else if (opts[j].boolopt)
|
||||
MenuOptionBool(opts[j].cmd, *opts[j].boolopt);
|
||||
for (const VbamOption& option : VbamOption::AllOptions()) {
|
||||
if (option.is_int()) {
|
||||
MenuOptionIntMask(option.command(), option.GetInt(), (1 << 0));
|
||||
} else if (option.is_bool()) {
|
||||
MenuOptionBool(option.command(), option.GetBool());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3090,7 +3088,7 @@ bool MainFrame::BindControls()
|
|||
}
|
||||
|
||||
for (size_t i = 0; i < checkable_mi.size(); i++)
|
||||
if (!checkable_mi[i].boolopt && !checkable_mi[i].intopt) {
|
||||
if (!checkable_mi[i].initialized) {
|
||||
wxLogError(_("Invalid menu item %s; removing"),
|
||||
checkable_mi[i].mi->GetItemLabelText().c_str());
|
||||
checkable_mi[i].mi->GetMenu()->Remove(checkable_mi[i].mi);
|
||||
|
|
677
src/wx/opts.cpp
677
src/wx/opts.cpp
|
@ -1,10 +1,11 @@
|
|||
#include "opts.h"
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <wx/log.h>
|
||||
#include <wx/display.h>
|
||||
|
||||
#include "wx/gamecontrol.h"
|
||||
#include "wx/userinput.h"
|
||||
#include "vbam-options.h"
|
||||
#include "wxvbam.h"
|
||||
#include "strutils.h"
|
||||
|
||||
|
@ -19,29 +20,6 @@
|
|||
|
||||
#define WJKB wxUserInput::FromLegacyKeyModJoy
|
||||
|
||||
/* not sure how well other compilers support field-init syntax */
|
||||
#define STROPT(c, n, d, v) \
|
||||
new_opt_desc(wxT(c), (n), d, &v)
|
||||
|
||||
#define INTOPT(c, n, d, v, min, max) \
|
||||
new_opt_desc(wxT(c), (n), d, NULL, &v, wxT(""), min, max)
|
||||
|
||||
#define DOUBLEOPT(c, n, d, v, min, max) \
|
||||
new_opt_desc(wxT(c), (n), d, NULL, NULL, wxT(""), min, max, NULL, &v)
|
||||
|
||||
#define UINTOPT(c, n, d, v, min, max) \
|
||||
new_opt_desc(wxT(c), (n), d, NULL, NULL, wxT(""), min, max, NULL, NULL, &v)
|
||||
|
||||
#define BOOLOPT(c, n, d, v) \
|
||||
new_opt_desc(wxT(c), (n), d, NULL, NULL, wxT(""), 0, 0, &v)
|
||||
|
||||
#define ENUMOPT(c, n, d, v, e) \
|
||||
new_opt_desc(wxT(c), (n), d, NULL, &v, e)
|
||||
|
||||
#define NOOPT(c, n, d) \
|
||||
new_opt_desc(c, (n), d)
|
||||
|
||||
|
||||
opts_t gopts;
|
||||
|
||||
// having the standard menu accels here means they will work even without menus
|
||||
|
@ -272,167 +250,6 @@ const std::map<wxGameControl, std::set<wxUserInput>> kDefaultBindings = {
|
|||
|
||||
wxAcceleratorEntry_v sys_accels;
|
||||
|
||||
// Initializer for struct opt_desc
|
||||
opt_desc new_opt_desc(wxString opt, const char* cmd, wxString desc,
|
||||
wxString* stropt, int* intopt, wxString enumvals,
|
||||
double min, double max, bool* boolopt,
|
||||
double* doubleopt, uint32_t* uintopt, wxString curstr,
|
||||
int curint, double curdouble, uint32_t curuint)
|
||||
{
|
||||
struct opt_desc new_opt = {opt, cmd, desc, stropt, intopt, enumvals,
|
||||
min, max, boolopt, doubleopt, uintopt,
|
||||
curstr, curint, curdouble, curuint};
|
||||
return new_opt;
|
||||
}
|
||||
|
||||
// Note: this table must be sorted in option name order
|
||||
// Both for better user display and for (fast) searching by name
|
||||
opt_desc opts[] = {
|
||||
/// Display
|
||||
BOOLOPT("Display/Bilinear", "Bilinear", wxTRANSLATE("Use bilinear filter with 3d renderer"), gopts.bilinear),
|
||||
ENUMOPT("Display/Filter", "", wxTRANSLATE("Full-screen filter to apply"), gopts.filter,
|
||||
wxTRANSLATE("none|2xsai|super2xsai|supereagle|pixelate|advmame|"
|
||||
L"bilinear|bilinearplus|scanlines|tvmode|hq2x|lq2x|"
|
||||
L"simple2x|simple3x|hq3x|simple4x|hq4x|xbrz2x|xbrz3x|xbrz4x|xbrz5x|xbrz6x|plugin")),
|
||||
STROPT("Display/FilterPlugin", "", wxTRANSLATE("Filter plugin library"), gopts.filter_plugin),
|
||||
ENUMOPT("Display/IFB", "", wxTRANSLATE("Interframe blending function"), gopts.ifb, wxTRANSLATE("none|smart|motionblur")),
|
||||
BOOLOPT("Display/KeepOnTop", "KeepOnTop", wxTRANSLATE("Keep window on top"), gopts.keep_on_top),
|
||||
INTOPT("Display/MaxThreads", "Multithread", wxTRANSLATE("Maximum number of threads to run filters in"), gopts.max_threads, 1, 256),
|
||||
#ifdef __WXMSW__
|
||||
ENUMOPT("Display/RenderMethod", "", wxTRANSLATE("Render method; if unsupported, simple method will be used"), gopts.render_method, wxTRANSLATE("simple|opengl|direct3d")),
|
||||
#elif defined(__WXMAC__)
|
||||
ENUMOPT("Display/RenderMethod", "", wxTRANSLATE("Render method; if unsupported, simple method will be used"), gopts.render_method, wxTRANSLATE("simple|opengl|quartz2d")),
|
||||
#else
|
||||
ENUMOPT("Display/RenderMethod", "", wxTRANSLATE("Render method; if unsupported, simple method will be used"), gopts.render_method, wxTRANSLATE("simple|opengl")),
|
||||
#endif
|
||||
DOUBLEOPT("Display/Scale", "", wxTRANSLATE("Default scale factor"), gopts.video_scale, 1, 6),
|
||||
BOOLOPT("Display/Stretch", "RetainAspect", wxTRANSLATE("Retain aspect ratio when resizing"), gopts.retain_aspect),
|
||||
|
||||
/// GB
|
||||
STROPT("GB/BiosFile", "", wxTRANSLATE("BIOS file to use for GB, if enabled"), gopts.gb_bios),
|
||||
INTOPT("GB/ColorOption", "GBColorOption", wxTRANSLATE("GB color enhancement, if enabled"), gbColorOption, 0, 1),
|
||||
INTOPT("GB/ColorizerHack", "ColorizerHack", wxTRANSLATE("Enable DX Colorization Hacks"), colorizerHack, 0, 1),
|
||||
BOOLOPT("GB/LCDFilter", "GBLcdFilter", wxTRANSLATE("Apply LCD filter, if enabled"), gbLcdFilter),
|
||||
STROPT("GB/GBCBiosFile", "", wxTRANSLATE("BIOS file to use for GBC, if enabled"), gopts.gbc_bios),
|
||||
NOOPT(wxT("GB/Palette0"), "", wxTRANSLATE("The default palette, as 8 comma-separated 4-digit hex integers (rgb555).")),
|
||||
NOOPT(wxT("GB/Palette1"), "", wxTRANSLATE("The first user palette, as 8 comma-separated 4-digit hex integers (rgb555).")),
|
||||
NOOPT(wxT("GB/Palette2"), "", wxTRANSLATE("The second user palette, as 8 comma-separated 4-digit hex integers (rgb555).")),
|
||||
BOOLOPT("GB/PrintAutoPage", "PrintGather", wxTRANSLATE("Automatically gather a full page before printing"), gopts.print_auto_page),
|
||||
BOOLOPT("GB/PrintScreenCap", "PrintSnap", wxTRANSLATE("Automatically save printouts as screen captures with -print suffix"), gopts.print_screen_cap),
|
||||
STROPT("GB/ROMDir", "", wxTRANSLATE("Directory to look for ROM files"), gopts.gb_rom_dir),
|
||||
STROPT("GB/GBCROMDir", "", wxTRANSLATE("Directory to look for GBC ROM files"), gopts.gbc_rom_dir),
|
||||
|
||||
/// GBA
|
||||
STROPT("GBA/BiosFile", "", wxTRANSLATE("BIOS file to use, if enabled"), gopts.gba_bios),
|
||||
BOOLOPT("GBA/LCDFilter", "GBALcdFilter", wxTRANSLATE("Apply LCD filter, if enabled"), gbaLcdFilter),
|
||||
#ifndef NO_LINK
|
||||
BOOLOPT("GBA/LinkAuto", "LinkAuto", wxTRANSLATE("Enable link at boot"), gopts.link_auto),
|
||||
INTOPT("GBA/LinkFast", "SpeedOn", wxTRANSLATE("Enable faster network protocol by default"), linkHacks, 0, 1),
|
||||
STROPT("GBA/LinkHost", "", wxTRANSLATE("Default network link client host"), gopts.link_host),
|
||||
STROPT("GBA/ServerIP", "", wxTRANSLATE("Default network link server IP to bind"), gopts.server_ip),
|
||||
UINTOPT("GBA/LinkPort", "", wxTRANSLATE("Default network link port (server and client)"), gopts.link_port, 0, 65535),
|
||||
INTOPT("GBA/LinkProto", "LinkProto", wxTRANSLATE("Default network protocol"), gopts.link_proto, 0, 1),
|
||||
INTOPT("GBA/LinkTimeout", "LinkTimeout", wxTRANSLATE("Link timeout (ms)"), linkTimeout, 0, 9999999),
|
||||
INTOPT("GBA/LinkType", "LinkType", wxTRANSLATE("Link cable type"), gopts.gba_link_type, 0, 5),
|
||||
#endif
|
||||
STROPT("GBA/ROMDir", "", wxTRANSLATE("Directory to look for ROM files"), gopts.gba_rom_dir),
|
||||
|
||||
/// General
|
||||
BOOLOPT("General/AutoLoadLastState", "", wxTRANSLATE("Automatically load last saved state"), gopts.autoload_state),
|
||||
STROPT("General/BatteryDir", "", wxTRANSLATE("Directory to store game save files (relative paths are relative to ROM; blank is config dir)"), gopts.battery_dir),
|
||||
BOOLOPT("General/FreezeRecent", "", wxTRANSLATE("Freeze recent load list"), gopts.recent_freeze),
|
||||
STROPT("General/RecordingDir", "", wxTRANSLATE("Directory to store A/V and game recordings (relative paths are relative to ROM)"), gopts.recording_dir),
|
||||
INTOPT("General/RewindInterval", "", wxTRANSLATE("Number of seconds between rewind snapshots (0 to disable)"), gopts.rewind_interval, 0, 600),
|
||||
STROPT("General/ScreenshotDir", "", wxTRANSLATE("Directory to store screenshots (relative paths are relative to ROM)"), gopts.scrshot_dir),
|
||||
STROPT("General/StateDir", "", wxTRANSLATE("Directory to store saved state files (relative paths are relative to BatteryDir)"), gopts.state_dir),
|
||||
INTOPT("General/StatusBar", "StatusBar", wxTRANSLATE("Enable status bar"), gopts.statusbar, 0, 1),
|
||||
|
||||
/// Joypad
|
||||
NOOPT(wxT("Joypad/*/*"), "", wxTRANSLATE("The parameter Joypad/<n>/<button> contains a comma-separated list of key names which map to joypad #<n> button <button>. Button is one of Up, Down, Left, Right, A, B, L, R, Select, Start, MotionUp, MotionDown, MotionLeft, MotionRight, AutoA, AutoB, Speed, Capture, GS")),
|
||||
INTOPT("Joypad/AutofireThrottle", "", wxTRANSLATE("The autofire toggle period, in frames (1/60 s)"), gopts.autofire_rate, 1, 1000),
|
||||
|
||||
/// Keyboard
|
||||
INTOPT("Joypad/Default", "", wxTRANSLATE("The number of the stick to use in single-player mode"), gopts.default_stick, 1, 4),
|
||||
|
||||
/// Keyboard
|
||||
NOOPT(wxT("Keyboard/*"), "", wxTRANSLATE("The parameter Keyboard/<cmd> contains a comma-separated list of key names (e.g. Alt-Shift-F1). When the named key is pressed, the command <cmd> is executed.")),
|
||||
|
||||
// Core
|
||||
INTOPT("preferences/agbPrint", "AGBPrinter", wxTRANSLATE("Enable AGB debug print"), agbPrint, 0, 1),
|
||||
INTOPT("preferences/autoFrameSkip", "FrameSkipAuto", wxTRANSLATE("Auto skip frames."), autoFrameSkip, 0, 1),
|
||||
INTOPT("preferences/autoPatch", "ApplyPatches", wxTRANSLATE("Apply IPS/UPS/IPF patches if found"), autoPatch, 0, 1),
|
||||
BOOLOPT("preferences/autoSaveLoadCheatList", "", wxTRANSLATE("Automatically save and load cheat list"), gopts.autoload_cheats),
|
||||
INTOPT("preferences/borderAutomatic", "", wxTRANSLATE("Automatically enable border for Super GameBoy games"), gbBorderAutomatic, 0, 1),
|
||||
INTOPT("preferences/borderOn", "", wxTRANSLATE("Always enable border"), gbBorderOn, 0, 1),
|
||||
INTOPT("preferences/captureFormat", "", wxTRANSLATE("Screen capture file format"), captureFormat, 0, 1),
|
||||
INTOPT("preferences/cheatsEnabled", "", wxTRANSLATE("Enable cheats"), cheatsEnabled, 0, 1),
|
||||
|
||||
#ifdef MMX
|
||||
INTOPT("preferences/enableMMX", "MMX", wxTRANSLATE("Enable MMX"), enableMMX, 0, 1),
|
||||
#endif
|
||||
INTOPT("preferences/disableStatus", "NoStatusMsg", wxTRANSLATE("Disable on-screen status messages"), disableStatusMessages, 0, 1),
|
||||
INTOPT("preferences/emulatorType", "", wxTRANSLATE("Type of system to emulate"), gbEmulatorType, 0, 5),
|
||||
INTOPT("preferences/flashSize", "", wxTRANSLATE("Flash size 0 = 64KB 1 = 128KB"), optFlashSize, 0, 1),
|
||||
INTOPT("preferences/frameSkip", "FrameSkip", wxTRANSLATE("Skip frames. Values are 0-9 or -1 to skip automatically based on time."), frameSkip, -1, 9),
|
||||
INTOPT("preferences/fsColorDepth", "", wxTRANSLATE("Fullscreen mode color depth (0 = any)"), fsColorDepth, 0, 999),
|
||||
INTOPT("preferences/fsFrequency", "", wxTRANSLATE("Fullscreen mode frequency (0 = any)"), fsFrequency, 0, 999),
|
||||
INTOPT("preferences/fsHeight", "", wxTRANSLATE("Fullscreen mode height (0 = desktop)"), fsHeight, 0, 99999),
|
||||
INTOPT("preferences/fsWidth", "", wxTRANSLATE("Fullscreen mode width (0 = desktop)"), fsWidth, 0, 99999),
|
||||
INTOPT("preferences/gbPaletteOption", "", wxTRANSLATE("The palette to use"), gbPaletteOption, 0, 2),
|
||||
INTOPT("preferences/gbPrinter", "Printer", wxTRANSLATE("Enable printer emulation"), winGbPrinterEnabled, 0, 1),
|
||||
INTOPT("preferences/gdbBreakOnLoad", "DebugGDBBreakOnLoad", wxTRANSLATE("Break into GDB after loading the game."), gdbBreakOnLoad, 0, 1),
|
||||
INTOPT("preferences/gdbPort", "DebugGDBPort", wxTRANSLATE("Port to connect GDB to."), gdbPort, 0, 65535),
|
||||
#ifndef NO_LINK
|
||||
INTOPT("preferences/LinkNumPlayers", "", wxTRANSLATE("Number of players in network"), linkNumPlayers, 2, 4),
|
||||
#endif
|
||||
INTOPT("preferences/maxScale", "", wxTRANSLATE("Maximum scale factor (0 = no limit)"), maxScale, 0, 100),
|
||||
INTOPT("preferences/pauseWhenInactive", "PauseWhenInactive", wxTRANSLATE("Pause game when main window loses focus"), pauseWhenInactive, 0, 1),
|
||||
INTOPT("preferences/rtcEnabled", "RTC", wxTRANSLATE("Enable RTC (vba-over.ini override is rtcEnabled"), rtcEnabled, 0, 1),
|
||||
INTOPT("preferences/saveType", "", wxTRANSLATE("Native save (\"battery\") hardware type"), cpuSaveType, 0, 5),
|
||||
INTOPT("preferences/showSpeed", "", wxTRANSLATE("Show speed indicator"), showSpeed, 0, 2),
|
||||
INTOPT("preferences/showSpeedTransparent", "Transparent", wxTRANSLATE("Draw on-screen messages transparently"), showSpeedTransparent, 0, 1),
|
||||
INTOPT("preferences/skipBios", "SkipIntro", wxTRANSLATE("Skip BIOS initialization"), skipBios, 0, 1),
|
||||
INTOPT("preferences/skipSaveGameCheats", "", wxTRANSLATE("Do not overwrite cheat list when loading state"), skipSaveGameCheats, 0, 1),
|
||||
INTOPT("preferences/skipSaveGameBattery", "", wxTRANSLATE("Do not overwrite native (battery) save when loading state"), skipSaveGameBattery, 0, 1),
|
||||
UINTOPT("preferences/throttle", "", wxTRANSLATE("Throttle game speed, even when accelerated (0-450%, 0 = no throttle)"), throttle, 0, 450),
|
||||
UINTOPT("preferences/speedupThrottle", "", wxTRANSLATE("Set throttle for speedup key (0-3000%, 0 = no throttle)"), speedup_throttle, 0, 3000),
|
||||
UINTOPT("preferences/speedupFrameSkip", "", wxTRANSLATE("Number of frames to skip with speedup (instead of speedup throttle)"), speedup_frame_skip, 0, 300),
|
||||
BOOLOPT("preferences/speedupThrottleFrameSkip", "", wxTRANSLATE("Use frame skip for speedup throttle"), speedup_throttle_frame_skip),
|
||||
INTOPT("preferences/useBiosGB", "BootRomGB", wxTRANSLATE("Use the specified BIOS file for GB"), useBiosFileGB, 0, 1),
|
||||
INTOPT("preferences/useBiosGBA", "BootRomEn", wxTRANSLATE("Use the specified BIOS file"), useBiosFileGBA, 0, 1),
|
||||
INTOPT("preferences/useBiosGBC", "BootRomGBC", wxTRANSLATE("Use the specified BIOS file for GBC"), useBiosFileGBC, 0, 1),
|
||||
INTOPT("preferences/vsync", "VSync", wxTRANSLATE("Wait for vertical sync"), vsync, 0, 1),
|
||||
|
||||
/// Geometry
|
||||
INTOPT("geometry/fullScreen", "Fullscreen", wxTRANSLATE("Enter fullscreen mode at startup"), fullScreen, 0, 1),
|
||||
INTOPT("geometry/isMaximized", "Maximized", wxTRANSLATE("Window maximized"), windowMaximized, 0, 1),
|
||||
UINTOPT("geometry/windowHeight", "Height", wxTRANSLATE("Window height at startup"), windowHeight, 0, 99999),
|
||||
UINTOPT("geometry/windowWidth", "Width", wxTRANSLATE("Window width at startup"), windowWidth, 0, 99999),
|
||||
INTOPT("geometry/windowX", "X", wxTRANSLATE("Window axis X position at startup"), windowPositionX, -1, 99999),
|
||||
INTOPT("geometry/windowY", "Y", wxTRANSLATE("Window axis Y position at startup"), windowPositionY, -1, 99999),
|
||||
|
||||
/// UI
|
||||
BOOLOPT("ui/allowKeyboardBackgroundInput", "AllowKeyboardBackgroundInput", wxTRANSLATE("Capture key events while on background"), allowKeyboardBackgroundInput),
|
||||
BOOLOPT("ui/allowJoystickBackgroundInput", "AllowJoystickBackgroundInput", wxTRANSLATE("Capture joy events while on background"), allowJoystickBackgroundInput),
|
||||
BOOLOPT("ui/hideMenuBar", "", wxTRANSLATE("Hide menu bar when mouse is inactive"), gopts.hide_menu_bar),
|
||||
|
||||
/// Sound
|
||||
ENUMOPT("Sound/AudioAPI", "", wxTRANSLATE("Sound API; if unsupported, default API will be used"), gopts.audio_api, wxTRANSLATE("sdl|openal|directsound|xaudio2|faudio")),
|
||||
STROPT("Sound/AudioDevice", "", wxTRANSLATE("Device ID of chosen audio device for chosen driver"), gopts.audio_dev),
|
||||
INTOPT("Sound/Buffers", "", wxTRANSLATE("Number of sound buffers"), gopts.audio_buffers, 2, 10),
|
||||
INTOPT("Sound/Enable", "", wxTRANSLATE("Bit mask of sound channels to enable"), gopts.sound_en, 0, 0x30f),
|
||||
INTOPT("Sound/GBAFiltering", "", wxTRANSLATE("GBA sound filtering (%)"), gopts.gba_sound_filter, 0, 100),
|
||||
BOOLOPT("Sound/GBAInterpolation", "GBASoundInterpolation", wxTRANSLATE("GBA sound interpolation"), soundInterpolation),
|
||||
BOOLOPT("Sound/GBDeclicking", "GBDeclicking", wxTRANSLATE("GB sound declicking"), gopts.gb_declick),
|
||||
INTOPT("Sound/GBEcho", "", wxTRANSLATE("GB echo effect (%)"), gopts.gb_echo, 0, 100),
|
||||
BOOLOPT("Sound/GBEnableEffects", "GBEnhanceSound", wxTRANSLATE("Enable GB sound effects"), gopts.gb_effects_config_enabled),
|
||||
INTOPT("Sound/GBStereo", "", wxTRANSLATE("GB stereo effect (%)"), gopts.gb_stereo, 0, 100),
|
||||
BOOLOPT("Sound/GBSurround", "GBSurround", wxTRANSLATE("GB surround sound effect (%)"), gopts.gb_effects_config_surround),
|
||||
ENUMOPT("Sound/Quality", "", wxTRANSLATE("Sound sample rate (kHz)"), gopts.sound_qual, wxTRANSLATE("48|44|22|11")),
|
||||
INTOPT("Sound/Volume", "", wxTRANSLATE("Sound volume (%)"), gopts.sound_vol, 0, 200)
|
||||
};
|
||||
const int num_opts = sizeof(opts) / sizeof(opts[0]);
|
||||
|
||||
// This constructor only works with globally allocated gopts. It relies on
|
||||
// the default value of every non-object to be 0.
|
||||
opts_t::opts_t()
|
||||
|
@ -482,28 +299,15 @@ opts_t::opts_t()
|
|||
skipSaveGameBattery = true;
|
||||
}
|
||||
|
||||
// for binary_search() and friends
|
||||
bool opt_lt(const opt_desc& opt1, const opt_desc& opt2)
|
||||
{
|
||||
return wxStrcmp(opt1.opt, opt2.opt) < 0;
|
||||
}
|
||||
|
||||
// FIXME: simulate MakeInstanceFilename(vbam.ini) using subkeys (Slave%d/*)
|
||||
void load_opts()
|
||||
{
|
||||
// just for sanity...
|
||||
bool did_init = false;
|
||||
|
||||
if (did_init)
|
||||
return;
|
||||
|
||||
did_init = true;
|
||||
|
||||
// Translations can't be initialized in static structures (before locale
|
||||
// is initialized), so do them now
|
||||
for (int i = 0; i < num_opts; i++)
|
||||
opts[i].desc = wxGetTranslation(opts[i].desc);
|
||||
|
||||
// enumvals should not be translated, since they would cause config file
|
||||
// change after lang change
|
||||
// instead, translate when presented to user
|
||||
|
@ -525,7 +329,6 @@ void load_opts()
|
|||
// Date of last online update check;
|
||||
gopts.last_update = cfg->Read(wxT("General/LastUpdated"), (long)0);
|
||||
cfg->Read(wxT("General/LastUpdatedFileName"), &gopts.last_updated_filename);
|
||||
std::sort(&opts[0], &opts[num_opts], opt_lt);
|
||||
|
||||
for (cont = cfg->GetFirstGroup(s, grp_idx); cont;
|
||||
cont = cfg->GetNextGroup(s, grp_idx)) {
|
||||
|
@ -599,14 +402,10 @@ void load_opts()
|
|||
} else {
|
||||
s.append(wxT('/'));
|
||||
s.append(e);
|
||||
opt_desc dummy = new_opt_desc(s);
|
||||
wxString opt_name(dummy.opt);
|
||||
|
||||
if (!std::binary_search(&opts[0], &opts[num_opts], dummy, opt_lt) && opt_name != wxT("General/LastUpdated") && opt_name != wxT("General/LastUpdatedFileName")) {
|
||||
if (!VbamOption::FindOptionByName(s) && s != wxT("General/LastUpdated") && s != wxT("General/LastUpdatedFileName")) {
|
||||
//wxLogWarning(_("Invalid option %s present; removing if possible"), s.c_str());
|
||||
item_del.push_back(s);
|
||||
}
|
||||
|
||||
s.resize(poff);
|
||||
}
|
||||
}
|
||||
|
@ -624,107 +423,61 @@ void load_opts()
|
|||
// config file will be updated with unset options
|
||||
cfg->SetRecordDefaults();
|
||||
|
||||
for (int i = 0; i < num_opts; i++) {
|
||||
opt_desc& opt = opts[i];
|
||||
|
||||
if (opt.stropt) {
|
||||
//Fix provided by nhdailey
|
||||
cfg->Read(opt.opt, opt.stropt, *opt.stropt);
|
||||
opt.curstr = *opt.stropt;
|
||||
} else if (!opt.enumvals.empty()) {
|
||||
auto enum_opts = strutils::split(opt.enumvals.MakeLower(), wxT("|"));
|
||||
opt.curint = *opt.intopt;
|
||||
bool gotit = cfg->Read(opt.opt, &s); s.MakeLower();
|
||||
|
||||
if (gotit && !s.empty()) {
|
||||
const auto found_pos = enum_opts.Index(s);
|
||||
const bool matched = ((int)found_pos != wxNOT_FOUND);
|
||||
|
||||
if (!matched) {
|
||||
opt.curint = 0;
|
||||
const wxString ev = opt.enumvals;
|
||||
const wxString evx = wxGetTranslation(ev);
|
||||
bool isx = wxStrcmp(ev, evx) != 0;
|
||||
// technically, the translation for this string could incorproate
|
||||
// the equals sign if necessary instead of doing it this way
|
||||
wxLogWarning(_("Invalid value %s for option %s; valid values are %s%s%s"),
|
||||
s.c_str(), opt.opt.c_str(), ev.c_str(),
|
||||
isx ? wxT(" = ") : wxEmptyString,
|
||||
isx ? evx.c_str() : wxEmptyString);
|
||||
// write first option
|
||||
cfg->Write(opt.opt, enum_opts[0]);
|
||||
} else
|
||||
opt.curint = found_pos;
|
||||
|
||||
*opt.intopt = opt.curint;
|
||||
} else {
|
||||
cfg->Write(opt.opt, enum_opts[opt.curint]);
|
||||
// First access here will also initialize translations.
|
||||
for (const VbamOption& opt : VbamOption::AllOptions()) {
|
||||
switch (opt.type()) {
|
||||
case VbamOption::Type::kNone:
|
||||
// Keyboard or Joystick. Handled separately for now.
|
||||
break;
|
||||
case VbamOption::Type::kBool: {
|
||||
bool temp;
|
||||
cfg->Read(opt.config_name(), &temp, opt.GetBool());
|
||||
opt.SetBool(temp);
|
||||
break;
|
||||
}
|
||||
case VbamOption::Type::kDouble: {
|
||||
double temp;
|
||||
cfg->Read(opt.config_name(), &temp, opt.GetDouble());
|
||||
opt.SetDouble(temp);
|
||||
break;
|
||||
}
|
||||
case VbamOption::Type::kInt: {
|
||||
int32_t temp;
|
||||
cfg->Read(opt.config_name(), &temp, opt.GetInt());
|
||||
opt.SetInt(temp);
|
||||
break;
|
||||
}
|
||||
case VbamOption::Type::kUnsigned: {
|
||||
int temp;
|
||||
cfg->Read(opt.config_name(), &temp, opt.GetUnsigned());
|
||||
opt.SetUnsigned(temp);
|
||||
break;
|
||||
}
|
||||
case VbamOption::Type::kString: {
|
||||
wxString temp;
|
||||
cfg->Read(opt.config_name(), &temp, opt.GetString());
|
||||
opt.SetString(temp);
|
||||
break;
|
||||
}
|
||||
case VbamOption::Type::kFilter:
|
||||
case VbamOption::Type::kInterframe:
|
||||
case VbamOption::Type::kRenderMethod:
|
||||
case VbamOption::Type::kAudioApi:
|
||||
case VbamOption::Type::kSoundQuality: {
|
||||
wxString temp;
|
||||
if (cfg->Read(opt.config_name(), &temp) && !temp.empty()) {
|
||||
opt.SetEnumString(temp.MakeLower());
|
||||
}
|
||||
} else if (opt.intopt) {
|
||||
cfg->Read(opt.opt, &opt.curint, *opt.intopt);
|
||||
|
||||
if (opt.curint < opt.min || opt.curint > opt.max) {
|
||||
wxLogWarning(_("Invalid value %d for option %s; valid values are %d - %d"), opt.curint, opt.opt.c_str(), int(opt.min), int(opt.max));
|
||||
} else
|
||||
*opt.intopt = opt.curint;
|
||||
} else if (opt.doubleopt) {
|
||||
cfg->Read(opt.opt, &opt.curdouble, *opt.doubleopt);
|
||||
|
||||
if (opt.curdouble < opt.min || opt.curdouble > opt.max) {
|
||||
wxLogWarning(_("Invalid value %f for option %s; valid values are %f - %f"), opt.curdouble, opt.opt.c_str(), opt.min, opt.max);
|
||||
} else
|
||||
*opt.doubleopt = opt.curdouble;
|
||||
} else if (opt.uintopt) {
|
||||
int val;
|
||||
cfg->Read(opt.opt, &val, *opt.uintopt);
|
||||
opt.curuint = val;
|
||||
|
||||
if (opt.curuint < opt.min || opt.curuint > opt.max) {
|
||||
wxLogWarning(_("Invalid value %f for option %s; valid values are %f - %f"), opt.curuint, opt.opt.c_str(), opt.min, opt.max);
|
||||
} else
|
||||
*opt.uintopt = opt.curuint;
|
||||
} else if (opt.boolopt) {
|
||||
cfg->Read(opt.opt, opt.boolopt, *opt.boolopt);
|
||||
opt.curbool = *opt.boolopt;
|
||||
// This is necessary, in case the option we loaded was invalid.
|
||||
cfg->Write(opt.config_name(), opt.GetEnumString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// GB/Palette[0-2] is special
|
||||
for (int i = 0; i < 3; i++) {
|
||||
wxString optn;
|
||||
optn.Printf(wxT("GB/Palette%d"), i);
|
||||
wxString val;
|
||||
const opt_desc dummy = new_opt_desc(optn);
|
||||
opt_desc* opt = std::lower_bound(&opts[0], &opts[num_opts], dummy, opt_lt);
|
||||
wxString entry;
|
||||
|
||||
for (int j = 0; j < 8; j++) {
|
||||
// stupid wxString.Printf doesn't support printing at offset
|
||||
entry.Printf(wxT("%04X,"), (int)systemGbPalette[i * 8 + j]);
|
||||
val.append(entry);
|
||||
case VbamOption::Type::kGbPalette: {
|
||||
wxString temp;
|
||||
cfg->Read(opt.config_name(), &temp, opt.GetGbPaletteString());
|
||||
opt.SetGbPalette(temp);
|
||||
break;
|
||||
}
|
||||
|
||||
val.resize(val.size() - 1);
|
||||
cfg->Read(optn, &val, val);
|
||||
opt->curstr = val;
|
||||
|
||||
for (int j = 0, cpos = 0; j < 8; j++) {
|
||||
int start = cpos;
|
||||
cpos = val.find(wxT(','), cpos);
|
||||
|
||||
if ((size_t)cpos == wxString::npos)
|
||||
cpos = val.size();
|
||||
|
||||
long ival;
|
||||
// ignoring errors; if the value is bad, palette will be corrupt
|
||||
// -- tough.
|
||||
// stupid wxString.ToLong doesn't support start @ offset
|
||||
entry = val.substr(start, cpos - start);
|
||||
entry.ToLong(&ival, 16);
|
||||
systemGbPalette[i * 8 + j] = ival;
|
||||
|
||||
if ((size_t)cpos != val.size())
|
||||
cpos++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -785,57 +538,36 @@ void update_opts()
|
|||
{
|
||||
wxFileConfig* cfg = wxGetApp().cfg;
|
||||
|
||||
for (int i = 0; i < num_opts; i++) {
|
||||
opt_desc& opt = opts[i];
|
||||
|
||||
if (opt.stropt) {
|
||||
if (opt.curstr != *opt.stropt) {
|
||||
opt.curstr = *opt.stropt;
|
||||
cfg->Write(opt.opt, opt.curstr);
|
||||
}
|
||||
} else if (!opt.enumvals.empty()) {
|
||||
if (*opt.intopt != opt.curint) {
|
||||
opt.curint = *opt.intopt;
|
||||
auto enum_opts = strutils::split(opt.enumvals.MakeLower(), wxT("|"));
|
||||
|
||||
cfg->Write(opt.opt, enum_opts[opt.curint]);
|
||||
}
|
||||
} else if (opt.intopt) {
|
||||
if (*opt.intopt != opt.curint)
|
||||
cfg->Write(opt.opt, (opt.curint = *opt.intopt));
|
||||
} else if (opt.doubleopt) {
|
||||
if (*opt.doubleopt != opt.curdouble)
|
||||
cfg->Write(opt.opt, (opt.curdouble = *opt.doubleopt));
|
||||
} else if (opt.uintopt) {
|
||||
if (*opt.uintopt != opt.curuint)
|
||||
cfg->Write(opt.opt, (long)(opt.curuint = *opt.uintopt));
|
||||
} else if (opt.boolopt) {
|
||||
if (*opt.boolopt != opt.curbool)
|
||||
cfg->Write(opt.opt, (opt.curbool = *opt.boolopt));
|
||||
}
|
||||
}
|
||||
|
||||
// gbpalette requires doing the conversion to string over
|
||||
// it may trigger a write even with no changes if # of digits changes
|
||||
for (int i = 0; i < 3; i++) {
|
||||
wxString optn;
|
||||
optn.Printf(wxT("GB/Palette%d"), i);
|
||||
const opt_desc dummy = new_opt_desc(optn);
|
||||
opt_desc* opt = std::lower_bound(&opts[0], &opts[num_opts], dummy, opt_lt);
|
||||
wxString val;
|
||||
wxString entry;
|
||||
|
||||
for (int j = 0; j < 8; j++) {
|
||||
// stupid wxString.Printf doesn't support printing at offset
|
||||
entry.Printf(wxT("%04X,"), (int)systemGbPalette[i * 8 + j]);
|
||||
val.append(entry);
|
||||
}
|
||||
|
||||
val.resize(val.size() - 1);
|
||||
|
||||
if (val != opt->curstr) {
|
||||
opt->curstr = val;
|
||||
cfg->Write(optn, val);
|
||||
for (const VbamOption& opt : VbamOption::AllOptions()) {
|
||||
switch (opt.type()) {
|
||||
case VbamOption::Type::kNone:
|
||||
// Keyboard and Joypad are handled separately.
|
||||
break;
|
||||
case VbamOption::Type::kBool:
|
||||
cfg->Write(opt.config_name(), opt.GetBool());
|
||||
break;
|
||||
case VbamOption::Type::kDouble:
|
||||
cfg->Write(opt.config_name(), opt.GetDouble());
|
||||
break;
|
||||
case VbamOption::Type::kInt:
|
||||
cfg->Write(opt.config_name(), opt.GetInt());
|
||||
break;
|
||||
case VbamOption::Type::kUnsigned:
|
||||
cfg->Write(opt.config_name(), opt.GetUnsigned());
|
||||
break;
|
||||
case VbamOption::Type::kString:
|
||||
cfg->Write(opt.config_name(), opt.GetString());
|
||||
break;
|
||||
case VbamOption::Type::kFilter:
|
||||
case VbamOption::Type::kInterframe:
|
||||
case VbamOption::Type::kRenderMethod:
|
||||
case VbamOption::Type::kAudioApi:
|
||||
case VbamOption::Type::kSoundQuality:
|
||||
cfg->Write(opt.config_name(), opt.GetEnumString());
|
||||
break;
|
||||
case VbamOption::Type::kGbPalette:
|
||||
cfg->Write(opt.config_name(), opt.GetGbPaletteString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -922,149 +654,116 @@ void update_opts()
|
|||
cfg->Flush();
|
||||
}
|
||||
|
||||
bool opt_set(const wxString& name, const wxString& val)
|
||||
{
|
||||
const opt_desc dummy = new_opt_desc(name);
|
||||
const opt_desc* opt = std::lower_bound(&opts[0], &opts[num_opts], dummy, opt_lt);
|
||||
void opt_set(const wxString& name, const wxString& val) {
|
||||
VbamOption const* opt = VbamOption::FindOptionByName(name);
|
||||
|
||||
if (!wxStrcmp(name, opt->opt)) {
|
||||
if (opt->stropt)
|
||||
*opt->stropt = wxString(val);
|
||||
else if (opt->boolopt) {
|
||||
if (!(val == wxT('0') || val == wxT('1')))
|
||||
wxLogWarning(_("Invalid flag option %s - %s ignored"),
|
||||
// opt->is_none() means it is Keyboard or Joypad.
|
||||
if (opt && !opt->is_none()) {
|
||||
switch (opt->type()) {
|
||||
case VbamOption::Type::kNone:
|
||||
// This should never happen.
|
||||
assert(false);
|
||||
return;
|
||||
case VbamOption::Type::kBool:
|
||||
if (val != '0' && val != '1') {
|
||||
wxLogWarning(_("Invalid value %s for option %s"),
|
||||
name.c_str(), val.c_str());
|
||||
else
|
||||
*opt->boolopt = val == wxT('1');
|
||||
} else if (!opt->enumvals.empty()) {
|
||||
wxString s = val; s.MakeLower();
|
||||
wxString ev = opt->enumvals; ev.MakeLower();
|
||||
auto enum_opts = strutils::split(ev, wxT("|"));
|
||||
|
||||
const std::size_t found_pos = enum_opts.Index(s);
|
||||
const bool matched = ((int)found_pos != wxNOT_FOUND);
|
||||
|
||||
if (!matched) {
|
||||
const wxString evx = wxGetTranslation(opt->enumvals);
|
||||
bool isx = wxStrcmp(opt->enumvals, evx) != 0;
|
||||
// technically, the translation for this string could incorproate
|
||||
// the equals sign if necessary instead of doing it this way
|
||||
wxLogWarning(_("Invalid value %s for option %s; valid values are %s%s%s"),
|
||||
s.c_str(), opt->opt.c_str(), opt->enumvals.c_str(),
|
||||
isx ? wxT(" = ") : wxEmptyString,
|
||||
isx ? evx.c_str() : wxEmptyString);
|
||||
} else {
|
||||
*opt->intopt = found_pos;
|
||||
return;
|
||||
}
|
||||
} else if (opt->intopt) {
|
||||
const wxString s(val);
|
||||
long ival;
|
||||
|
||||
if (!s.ToLong(&ival) || ival < opt->min || ival > opt->max)
|
||||
wxLogWarning(_("Invalid value %d for option %s; valid values are %d - %d"), ival, name.c_str(), opt->min, opt->max);
|
||||
else
|
||||
*opt->intopt = ival;
|
||||
} else if (opt->doubleopt) {
|
||||
const wxString s(val);
|
||||
double dval;
|
||||
|
||||
if (!s.ToDouble(&dval) || dval < opt->min || dval > opt->max)
|
||||
wxLogWarning(_("Invalid value %f for option %s; valid values are %f - %f"), dval, name.c_str(), opt->min, opt->max);
|
||||
else
|
||||
*opt->doubleopt = dval;
|
||||
} else if (opt->uintopt) {
|
||||
const wxString s(val);
|
||||
unsigned long uival;
|
||||
|
||||
if (!s.ToULong(&uival) || uival < opt->min || uival > opt->max)
|
||||
wxLogWarning(_("Invalid value %f for option %s; valid values are %f - %f"), uival, name.c_str(), opt->min, opt->max);
|
||||
else
|
||||
*opt->uintopt = (uint32_t)uival;
|
||||
} else {
|
||||
// GB/Palette[0-2] is virtual
|
||||
for (int i = 0; i < 3; i++) {
|
||||
wxString optn;
|
||||
optn.Printf(wxT("GB/Palette%d"), i);
|
||||
|
||||
if (optn != name)
|
||||
continue;
|
||||
|
||||
wxString vals(val);
|
||||
|
||||
for (size_t j = 0, cpos = 0; j < 8; j++) {
|
||||
int start = cpos;
|
||||
cpos = vals.find(wxT(','), cpos);
|
||||
|
||||
if (cpos == wxString::npos)
|
||||
cpos = vals.size();
|
||||
|
||||
long ival;
|
||||
// ignoring errors; if the value is bad, palette will be corrupt
|
||||
// -- tough.
|
||||
// stupid wxString.ToLong doesn't support start @ offset
|
||||
wxString entry = vals.substr(start, cpos - start);
|
||||
entry.ToLong(&ival, 16);
|
||||
systemGbPalette[i * 8 + j] = ival;
|
||||
|
||||
if (cpos != vals.size())
|
||||
cpos++;
|
||||
}
|
||||
opt->SetBool(val == '1');
|
||||
return;
|
||||
case VbamOption::Type::kDouble: {
|
||||
double value;
|
||||
if (!val.ToDouble(&value)) {
|
||||
wxLogWarning(_("Invalid value %s for option %s"), val, name.c_str());
|
||||
return;
|
||||
}
|
||||
opt->SetDouble(value);
|
||||
return;
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
if (name.Find(wxT('/')) == wxNOT_FOUND)
|
||||
return false;
|
||||
|
||||
auto parts = strutils::split(name, wxT("/"));
|
||||
|
||||
if (parts[0] != wxT("Keyboard")) {
|
||||
cmditem* cmd = std::lower_bound(&cmdtab[0], &cmdtab[ncmds], cmditem{parts[1],wxString(),0,0,NULL}, cmditem_lt);
|
||||
|
||||
if (cmd == &cmdtab[ncmds] || wxStrcmp(parts[1], cmd->cmd))
|
||||
return false;
|
||||
|
||||
for (auto i = gopts.accels.begin(); i < gopts.accels.end(); ++i)
|
||||
if (i->GetCommand() == cmd->cmd_id) {
|
||||
auto j = i;
|
||||
|
||||
for (; j < gopts.accels.end(); ++j)
|
||||
if (j->GetCommand() != cmd->cmd_id)
|
||||
break;
|
||||
|
||||
gopts.accels.erase(i, j);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!val.empty()) {
|
||||
auto aval = wxJoyKeyTextCtrl::ToAccelFromString(val);
|
||||
|
||||
for (size_t i = 0; i < aval.size(); i++)
|
||||
aval[i].Set(aval[i].GetUkey(), aval[i].GetJoystick(), aval[i].GetFlags(), aval[i].GetKeyCode(), cmd->cmd_id);
|
||||
|
||||
if (!aval.size())
|
||||
wxLogWarning(_("Invalid key binding %s for %s"), val.c_str(), name.c_str());
|
||||
else
|
||||
gopts.accels.insert(gopts.accels.end(), aval.begin(), aval.end());
|
||||
case VbamOption::Type::kInt: {
|
||||
long value;
|
||||
if (!val.ToLong(&value)) {
|
||||
wxLogWarning(_("Invalid value %s for option %s"), val, name.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
return true;
|
||||
opt->SetInt(static_cast<int32_t>(value));
|
||||
return;
|
||||
}
|
||||
|
||||
const nonstd::optional<wxGameControl> game_control =
|
||||
wxGameControl::FromString(name);
|
||||
if (game_control) {
|
||||
if (val.empty()) {
|
||||
gopts.game_control_bindings[game_control.value()].clear();
|
||||
} else {
|
||||
gopts.game_control_bindings[game_control.value()] =
|
||||
wxUserInput::FromString(val);
|
||||
case VbamOption::Type::kUnsigned: {
|
||||
unsigned long value;
|
||||
if (!val.ToULong(&value)) {
|
||||
wxLogWarning(_("Invalid value %s for option %s"), val, name.c_str());
|
||||
return;
|
||||
}
|
||||
return true;
|
||||
opt->SetUnsigned(static_cast<uint32_t>(value));
|
||||
return;
|
||||
}
|
||||
case VbamOption::Type::kString:
|
||||
opt->SetString(val);
|
||||
return;
|
||||
case VbamOption::Type::kFilter:
|
||||
case VbamOption::Type::kInterframe:
|
||||
case VbamOption::Type::kRenderMethod:
|
||||
case VbamOption::Type::kAudioApi:
|
||||
case VbamOption::Type::kSoundQuality:
|
||||
opt->SetEnumString(val);
|
||||
return;
|
||||
case VbamOption::Type::kGbPalette:
|
||||
opt->SetGbPalette(val);
|
||||
return;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (name.Find(wxT('/')) == wxNOT_FOUND) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto parts = strutils::split(name, wxT("/"));
|
||||
if (parts[0] == wxT("Keyboard")) {
|
||||
cmditem* cmd = std::lower_bound(&cmdtab[0], &cmdtab[ncmds], cmditem{parts[1],wxString(),0,0,NULL}, cmditem_lt);
|
||||
|
||||
if (cmd == &cmdtab[ncmds] || wxStrcmp(parts[1], cmd->cmd)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto i = gopts.accels.begin(); i < gopts.accels.end(); ++i)
|
||||
if (i->GetCommand() == cmd->cmd_id) {
|
||||
auto j = i;
|
||||
for (; j < gopts.accels.end(); ++j)
|
||||
if (j->GetCommand() != cmd->cmd_id)
|
||||
break;
|
||||
gopts.accels.erase(i, j);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!val.empty()) {
|
||||
auto aval = wxJoyKeyTextCtrl::ToAccelFromString(val);
|
||||
for (size_t i = 0; i < aval.size(); i++) {
|
||||
aval[i].Set(aval[i].GetUkey(), aval[i].GetJoystick(), aval[i].GetFlags(), aval[i].GetKeyCode(), cmd->cmd_id);
|
||||
}
|
||||
if (!aval.size()) {
|
||||
wxLogWarning(_("Invalid key binding %s for %s"), val.c_str(), name.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
gopts.accels.insert(gopts.accels.end(), aval.begin(), aval.end());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const nonstd::optional<wxGameControl> game_control =
|
||||
wxGameControl::FromString(name);
|
||||
if (game_control) {
|
||||
if (val.empty()) {
|
||||
gopts.game_control_bindings[game_control.value()].clear();
|
||||
} else {
|
||||
gopts.game_control_bindings[game_control.value()] =
|
||||
wxUserInput::FromString(val);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
wxLogWarning(_("Unknown option %s with value %s"), name.c_str(), val.c_str());
|
||||
}
|
||||
|
|
|
@ -98,34 +98,6 @@ extern struct opts_t {
|
|||
// wxWidgets-generated options (opaque)
|
||||
} gopts;
|
||||
|
||||
extern struct opt_desc {
|
||||
wxString opt;
|
||||
const char* cmd;
|
||||
wxString desc;
|
||||
wxString* stropt;
|
||||
int* intopt;
|
||||
wxString enumvals;
|
||||
double min, max;
|
||||
bool* boolopt;
|
||||
double* doubleopt;
|
||||
uint32_t* uintopt;
|
||||
// current configured value
|
||||
wxString curstr;
|
||||
int curint;
|
||||
double curdouble;
|
||||
uint32_t curuint;
|
||||
#define curbool curint
|
||||
} opts[];
|
||||
|
||||
// Initializer for struct opt_desc
|
||||
opt_desc new_opt_desc(wxString opt = wxT(""), const char* cmd = NULL, wxString desc = wxT(""),
|
||||
wxString* stropt = NULL, int* intopt = NULL, wxString enumvals = wxT(""),
|
||||
double min = 0, double max = 0, bool* boolopt = NULL,
|
||||
double* doubleopt = NULL, uint32_t* uintopt = NULL, wxString curstr = wxT(""),
|
||||
int curint = 0, double curdouble = 0, uint32_t curuint = 0);
|
||||
|
||||
extern const int num_opts;
|
||||
|
||||
extern const wxAcceleratorEntryUnicode default_accels[];
|
||||
extern const int num_def_accels;
|
||||
|
||||
|
@ -137,6 +109,6 @@ void load_opts();
|
|||
// will detect changes and write config if necessary
|
||||
void update_opts();
|
||||
// returns true if option name correct; prints error if val invalid
|
||||
bool opt_set(const wxString& name, const wxString& val);
|
||||
void opt_set(const wxString& name, const wxString& val);
|
||||
|
||||
#endif /* WX_OPTS_H */
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
#ifndef VBAM_OPTIONS_INTERNAL_INCLUDE
|
||||
#error "Do not include "vbam-options-internal.h" outside of the implementation."
|
||||
#endif
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <wx/string.h>
|
||||
|
||||
#include "nonstd/optional.hpp"
|
||||
#include "vbam-options.h"
|
||||
|
||||
namespace internal {
|
||||
|
||||
struct VbamOptionData {
|
||||
const wxString config_name;
|
||||
const wxString command;
|
||||
const wxString ux_helper;
|
||||
const VbamOption::Type type;
|
||||
};
|
||||
|
||||
// Static data to initialize global values.;
|
||||
extern const std::array<VbamOptionData, kNbOptions + 1> kAllOptionsData;
|
||||
|
||||
// Conversion utilities.
|
||||
nonstd::optional<VbamOptionID> StringToOptionId(const wxString& input);
|
||||
wxString FilterToString(int value);
|
||||
wxString InterframeToString(int value);
|
||||
wxString RenderMethodToString(int value);
|
||||
wxString AudioApiToString(int value);
|
||||
wxString SoundQualityToString(int value);
|
||||
int StringToFilter(const wxString& config_name, const wxString& input);
|
||||
int StringToInterframe(const wxString& config_name, const wxString& input);
|
||||
int StringToRenderMethod(const wxString& config_name, const wxString& input);
|
||||
int StringToAudioApi(const wxString& config_name, const wxString& input);
|
||||
int StringToSoundQuality(const wxString& config_name, const wxString& input);
|
||||
|
||||
wxString AllEnumValuesForType(VbamOption::Type type);
|
||||
|
||||
// Max value for enum types.
|
||||
int MaxForType(VbamOption::Type type);
|
||||
|
||||
} // namespace internal
|
|
@ -0,0 +1,830 @@
|
|||
#include "vbam-options.h"
|
||||
|
||||
// Helper implementation file to define and compile all of these huge constants
|
||||
// separately. These should not be updated very often, so this improves
|
||||
|
||||
#include <algorithm>
|
||||
#include <wx/log.h>
|
||||
|
||||
#include "../common/ConfigManager.h"
|
||||
#include "../gb/gbGlobals.h"
|
||||
#include "opts.h"
|
||||
#include "wx/stringimpl.h"
|
||||
|
||||
#define VBAM_OPTIONS_INTERNAL_INCLUDE
|
||||
#include "vbam-options-internal.h"
|
||||
#undef VBAM_OPTIONS_INTERNAL_INCLUDE
|
||||
|
||||
namespace {
|
||||
|
||||
// This enum must be kept in sync with the one in wxvbam.h
|
||||
enum class FilterFunction {
|
||||
kNone,
|
||||
k2xsai,
|
||||
kSuper2xsai,
|
||||
kSupereagle,
|
||||
kPixelate,
|
||||
kAdvmame,
|
||||
kBilinear,
|
||||
kBilinearplus,
|
||||
kScanlines,
|
||||
kTvmode,
|
||||
kHQ2x,
|
||||
kLQ2x,
|
||||
kSimple2x,
|
||||
kSimple3x,
|
||||
kHQ3x,
|
||||
kSimple4x,
|
||||
kHQ4x,
|
||||
kXbrz2x,
|
||||
kXbrz3x,
|
||||
kXbrz4x,
|
||||
kXbrz5x,
|
||||
kXbrz6x,
|
||||
kPlugin, // This must always be last.
|
||||
|
||||
// Do not add anything under here.
|
||||
kLast,
|
||||
};
|
||||
constexpr size_t kNbFilterFunctions = static_cast<size_t>(FilterFunction::kLast);
|
||||
|
||||
// These MUST follow the same order as the definitions of the enum above.
|
||||
// Adding an option without adding to this array will result in a compiler
|
||||
// error since kNbFilterFunctions is automatically updated.
|
||||
static const std::array<wxString, kNbFilterFunctions> kFilterStrings = {
|
||||
"none",
|
||||
"2xsai",
|
||||
"super2xsai",
|
||||
"supereagle",
|
||||
"pixelate",
|
||||
"advmame",
|
||||
"bilinear",
|
||||
"bilinearplus",
|
||||
"scanlines",
|
||||
"tvmode",
|
||||
"hq2x",
|
||||
"lq2x",
|
||||
"simple2x",
|
||||
"simple3x",
|
||||
"hq3x",
|
||||
"simple4x",
|
||||
"hq4x",
|
||||
"xbrz2x",
|
||||
"xbrz3x",
|
||||
"xbrz4x",
|
||||
"xbrz5x",
|
||||
"xbrz6x",
|
||||
"plugin",
|
||||
};
|
||||
|
||||
// This enum must be kept in sync with the one in wxvbam.h
|
||||
enum class Interframe {
|
||||
kNone = 0,
|
||||
kSmart,
|
||||
kMotionBlur,
|
||||
|
||||
// Do not add anything under here.
|
||||
kLast,
|
||||
};
|
||||
constexpr size_t kNbInterframes = static_cast<size_t>(Interframe::kLast);
|
||||
|
||||
// These MUST follow the same order as the definitions of the enum above.
|
||||
// Adding an option without adding to this array will result in a compiler
|
||||
// error since kNbInterframes is automatically updated.
|
||||
static const std::array<wxString, kNbInterframes> kInterframeStrings = {
|
||||
"none",
|
||||
"smart",
|
||||
"motionblur",
|
||||
};
|
||||
|
||||
// This enum must be kept in sync with the one in wxvbam.h
|
||||
enum class RenderMethod {
|
||||
kSimple = 0,
|
||||
kOpenGL,
|
||||
#ifdef __WXMSW__
|
||||
kDirect3d,
|
||||
#elif defined(__WXMAC__)
|
||||
kQuartz2d,
|
||||
#endif
|
||||
|
||||
// Do not add anything under here.
|
||||
kLast,
|
||||
};
|
||||
constexpr size_t kNbRenderMethods = static_cast<size_t>(RenderMethod::kLast);
|
||||
|
||||
// These MUST follow the same order as the definitions of the enum above.
|
||||
// Adding an option without adding to this array will result in a compiler
|
||||
// error since kNbRenderMethods is automatically updated.
|
||||
static const std::array<wxString, kNbRenderMethods> kRenderMethodStrings = {
|
||||
"simple",
|
||||
"opengl",
|
||||
#ifdef __WXMSW__
|
||||
"direct3d",
|
||||
#elif defined(__WXMAC__)
|
||||
"quartz2d",
|
||||
#endif
|
||||
};
|
||||
|
||||
// This enum must be kept in sync with the one in wxvbam.h
|
||||
enum class AudioApi {
|
||||
kSdl = 0,
|
||||
kOpenAL,
|
||||
kDirectSound,
|
||||
kXAudio2,
|
||||
kFaudio,
|
||||
|
||||
// Do not add anything under here.
|
||||
kLast,
|
||||
};
|
||||
constexpr size_t kNbAudioApis = static_cast<size_t>(AudioApi::kLast);
|
||||
|
||||
// These MUST follow the same order as the definitions of the enum above.
|
||||
// Adding an option without adding to this array will result in a compiler
|
||||
// error since kNbAudioApis is automatically updated.
|
||||
static const std::array<wxString, kNbAudioApis> kAudioApiStrings = {
|
||||
"sdl",
|
||||
"openal",
|
||||
"directsound",
|
||||
"xaudio2",
|
||||
"faudio",
|
||||
};
|
||||
|
||||
enum class SoundQuality {
|
||||
k48kHz = 0,
|
||||
k44kHz,
|
||||
k22kHz,
|
||||
k11kHz,
|
||||
|
||||
// Do not add anything under here.
|
||||
kLast,
|
||||
};
|
||||
constexpr size_t kNbSoundQualities = static_cast<size_t>(SoundQuality::kLast);
|
||||
|
||||
// These MUST follow the same order as the definitions of the enum above.
|
||||
// Adding an option without adding to this array will result in a compiler
|
||||
// error since kNbSoundQualities is automatically updated.
|
||||
static const std::array<wxString, kNbSoundQualities> kSoundQualityStrings = {
|
||||
"48",
|
||||
"44",
|
||||
"22",
|
||||
"11",
|
||||
};
|
||||
|
||||
// Builds the "all enum values" string for a given array defined above.
|
||||
template<std::size_t SIZE>
|
||||
wxString AllEnumValuesForArray(const std::array<wxString, SIZE>& input) {
|
||||
// 15 characters per option is a reasonable higher bound. Probably.
|
||||
static constexpr size_t kMaxOptionLength = 15u;
|
||||
|
||||
wxString all_options;
|
||||
all_options.reserve(kMaxOptionLength * SIZE);
|
||||
|
||||
std::for_each(input.cbegin(), input.cend(), [&all_options](const auto& elt) {
|
||||
all_options.append(elt);
|
||||
all_options.append('|');
|
||||
});
|
||||
// Remove last value
|
||||
all_options.RemoveLast(1u);
|
||||
return all_options;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
std::array<VbamOption, kNbOptions>& VbamOption::AllOptions() {
|
||||
// These MUST follow the same order as the definitions in VbamOptionID.
|
||||
// Adding an option without adding to this array will result in a compiler
|
||||
// error since kNbOptions is automatically updated.
|
||||
// This will be initialized on the first call, in load_opts(), ensuring the
|
||||
// translation initialization has already happened.
|
||||
static std::array<VbamOption, kNbOptions> g_all_opts = {
|
||||
/// Display
|
||||
VbamOption(VbamOptionID::kDisplayBilinear, &gopts.bilinear),
|
||||
VbamOption(VbamOptionID::kDisplayFilter, &gopts.filter),
|
||||
VbamOption(VbamOptionID::kDisplayFilterPlugin, &gopts.filter_plugin),
|
||||
VbamOption(VbamOptionID::kDisplayIFB, &gopts.ifb),
|
||||
VbamOption(VbamOptionID::kDisplayKeepOnTop, &gopts.keep_on_top),
|
||||
VbamOption(VbamOptionID::kDisplayMaxThreads, &gopts.max_threads, 1, 256),
|
||||
VbamOption(VbamOptionID::kDisplayRenderMethod, &gopts.render_method),
|
||||
VbamOption(VbamOptionID::kDisplayScale, &gopts.video_scale, 1, 6),
|
||||
VbamOption(VbamOptionID::kDisplayStretch, &gopts.retain_aspect),
|
||||
|
||||
/// GB
|
||||
VbamOption(VbamOptionID::kGBBiosFile, &gopts.gb_bios),
|
||||
VbamOption(VbamOptionID::kGBColorOption, &gbColorOption, 0, 1),
|
||||
VbamOption(VbamOptionID::kGBColorizerHack, &colorizerHack, 0, 1),
|
||||
VbamOption(VbamOptionID::kGBLCDFilter, &gbLcdFilter),
|
||||
VbamOption(VbamOptionID::kGBGBCBiosFile, &gopts.gbc_bios),
|
||||
VbamOption(VbamOptionID::kGBPalette0, systemGbPalette),
|
||||
VbamOption(VbamOptionID::kGBPalette1, systemGbPalette + 8),
|
||||
VbamOption(VbamOptionID::kGBPalette2, systemGbPalette + 16),
|
||||
VbamOption(VbamOptionID::kGBPrintAutoPage, &gopts.print_auto_page),
|
||||
VbamOption(VbamOptionID::kGBPrintScreenCap, &gopts.print_screen_cap),
|
||||
VbamOption(VbamOptionID::kGBROMDir, &gopts.gb_rom_dir),
|
||||
VbamOption(VbamOptionID::kGBGBCROMDir, &gopts.gbc_rom_dir),
|
||||
|
||||
/// GBA
|
||||
VbamOption(VbamOptionID::kGBABiosFile, &gopts.gba_bios),
|
||||
VbamOption(VbamOptionID::kGBALCDFilter, &gbaLcdFilter),
|
||||
#ifndef NO_LINK
|
||||
VbamOption(VbamOptionID::kGBALinkAuto, &gopts.link_auto),
|
||||
VbamOption(VbamOptionID::kGBALinkFast, &linkHacks, 0, 1),
|
||||
VbamOption(VbamOptionID::kGBALinkHost, &gopts.link_host),
|
||||
VbamOption(VbamOptionID::kGBAServerIP, &gopts.server_ip),
|
||||
VbamOption(VbamOptionID::kGBALinkPort, &gopts.link_port, 0, 65535),
|
||||
VbamOption(VbamOptionID::kGBALinkProto, &gopts.link_proto, 0, 1),
|
||||
VbamOption(VbamOptionID::kGBALinkTimeout, &linkTimeout, 0, 9999999),
|
||||
VbamOption(VbamOptionID::kGBALinkType, &gopts.gba_link_type, 0, 5),
|
||||
#endif
|
||||
VbamOption(VbamOptionID::kGBAROMDir, &gopts.gba_rom_dir),
|
||||
|
||||
/// General
|
||||
VbamOption(VbamOptionID::kGeneralAutoLoadLastState, &gopts.autoload_state),
|
||||
VbamOption(VbamOptionID::kGeneralBatteryDir, &gopts.battery_dir),
|
||||
VbamOption(VbamOptionID::kGeneralFreezeRecent, &gopts.recent_freeze),
|
||||
VbamOption(VbamOptionID::kGeneralRecordingDir, &gopts.recording_dir),
|
||||
VbamOption(VbamOptionID::kGeneralRewindInterval, &gopts.rewind_interval, 0, 600),
|
||||
VbamOption(VbamOptionID::kGeneralScreenshotDir, &gopts.scrshot_dir),
|
||||
VbamOption(VbamOptionID::kGeneralStateDir, &gopts.state_dir),
|
||||
VbamOption(VbamOptionID::kGeneralStatusBar, &gopts.statusbar, 0, 1),
|
||||
|
||||
/// Joypad
|
||||
VbamOption(VbamOptionID::kJoypad),
|
||||
VbamOption(VbamOptionID::kJoypadAutofireThrottle, &gopts.autofire_rate, 1, 1000),
|
||||
VbamOption(VbamOptionID::kJoypadDefault, &gopts.default_stick, 1, 4),
|
||||
|
||||
/// Keyboard
|
||||
VbamOption(VbamOptionID::kKeyboard),
|
||||
|
||||
// Core
|
||||
VbamOption(VbamOptionID::kpreferencesagbPrint, &agbPrint, 0, 1),
|
||||
VbamOption(VbamOptionID::kpreferencesautoFrameSkip, &autoFrameSkip, 0, 1),
|
||||
VbamOption(VbamOptionID::kpreferencesautoPatch, &autoPatch, 0, 1),
|
||||
VbamOption(VbamOptionID::kpreferencesautoSaveLoadCheatList, &gopts.autoload_cheats),
|
||||
VbamOption(VbamOptionID::kpreferencesborderAutomatic, &gbBorderAutomatic, 0, 1),
|
||||
VbamOption(VbamOptionID::kpreferencesborderOn, &gbBorderOn, 0, 1),
|
||||
VbamOption(VbamOptionID::kpreferencescaptureFormat, &captureFormat, 0, 1),
|
||||
VbamOption(VbamOptionID::kpreferencescheatsEnabled, &cheatsEnabled, 0, 1),
|
||||
#ifdef MMX
|
||||
VbamOption(VbamOptionID::kpreferencesenableMMX, &enableMMX, 0, 1),
|
||||
#endif
|
||||
VbamOption(VbamOptionID::kpreferencesdisableStatus, &disableStatusMessages, 0, 1),
|
||||
VbamOption(VbamOptionID::kpreferencesemulatorType, &gbEmulatorType, 0, 5),
|
||||
VbamOption(VbamOptionID::kpreferencesflashSize, &optFlashSize, 0, 1),
|
||||
VbamOption(VbamOptionID::kpreferencesframeSkip, &frameSkip, -1, 9),
|
||||
VbamOption(VbamOptionID::kpreferencesfsColorDepth, &fsColorDepth, 0, 999),
|
||||
VbamOption(VbamOptionID::kpreferencesfsFrequency, &fsFrequency, 0, 999),
|
||||
VbamOption(VbamOptionID::kpreferencesfsHeight, &fsHeight, 0, 99999),
|
||||
VbamOption(VbamOptionID::kpreferencesfsWidth, &fsWidth, 0, 99999),
|
||||
VbamOption(VbamOptionID::kpreferencesgbPaletteOption, &gbPaletteOption, 0, 2),
|
||||
VbamOption(VbamOptionID::kpreferencesgbPrinter, &winGbPrinterEnabled, 0, 1),
|
||||
VbamOption(VbamOptionID::kpreferencesgdbBreakOnLoad, &gdbBreakOnLoad, 0, 1),
|
||||
VbamOption(VbamOptionID::kpreferencesgdbPort, &gdbPort, 0, 65535),
|
||||
#ifndef NO_LINK
|
||||
VbamOption(VbamOptionID::kpreferencesLinkNumPlayers, &linkNumPlayers, 2, 4),
|
||||
#endif
|
||||
VbamOption(VbamOptionID::kpreferencesmaxScale, &maxScale, 0, 100),
|
||||
VbamOption(VbamOptionID::kpreferencespauseWhenInactive, &pauseWhenInactive, 0, 1),
|
||||
VbamOption(VbamOptionID::kpreferencesrtcEnabled, &rtcEnabled, 0, 1),
|
||||
VbamOption(VbamOptionID::kpreferencessaveType, &cpuSaveType, 0, 5),
|
||||
VbamOption(VbamOptionID::kpreferencesshowSpeed, &showSpeed, 0, 2),
|
||||
VbamOption(VbamOptionID::kpreferencesshowSpeedTransparent, &showSpeedTransparent, 0, 1),
|
||||
VbamOption(VbamOptionID::kpreferencesskipBios, &skipBios, 0, 1),
|
||||
VbamOption(VbamOptionID::kpreferencesskipSaveGameCheats, &skipSaveGameCheats, 0, 1),
|
||||
VbamOption(VbamOptionID::kpreferencesskipSaveGameBattery, &skipSaveGameBattery, 0, 1),
|
||||
VbamOption(VbamOptionID::kpreferencesthrottle, &throttle, 0, 450),
|
||||
VbamOption(VbamOptionID::kpreferencesspeedupThrottle, &speedup_throttle, 0, 3000),
|
||||
VbamOption(VbamOptionID::kpreferencesspeedupFrameSkip, &speedup_frame_skip, 0, 300),
|
||||
VbamOption(VbamOptionID::kpreferencesspeedupThrottleFrameSkip, &speedup_throttle_frame_skip),
|
||||
VbamOption(VbamOptionID::kpreferencesuseBiosGB, &useBiosFileGB, 0, 1),
|
||||
VbamOption(VbamOptionID::kpreferencesuseBiosGBA, &useBiosFileGBA, 0, 1),
|
||||
VbamOption(VbamOptionID::kpreferencesuseBiosGBC, &useBiosFileGBC, 0, 1),
|
||||
VbamOption(VbamOptionID::kpreferencesvsync, &vsync, 0, 1),
|
||||
|
||||
/// Geometry
|
||||
VbamOption(VbamOptionID::kgeometryfullScreen, &fullScreen, 0, 1),
|
||||
VbamOption(VbamOptionID::kgeometryisMaximized, &windowMaximized, 0, 1),
|
||||
VbamOption(VbamOptionID::kgeometrywindowHeight, &windowHeight, 0, 99999),
|
||||
VbamOption(VbamOptionID::kgeometrywindowWidth, &windowWidth, 0, 99999),
|
||||
VbamOption(VbamOptionID::kgeometrywindowX, &windowPositionX, -1, 99999),
|
||||
VbamOption(VbamOptionID::kgeometrywindowY, &windowPositionY, -1, 99999),
|
||||
|
||||
/// UI
|
||||
VbamOption(VbamOptionID::kuiallowKeyboardBackgroundInput, &allowKeyboardBackgroundInput),
|
||||
VbamOption(VbamOptionID::kuiallowJoystickBackgroundInput, &allowJoystickBackgroundInput),
|
||||
VbamOption(VbamOptionID::kuihideMenuBar, &gopts.hide_menu_bar),
|
||||
|
||||
/// Sound
|
||||
VbamOption(VbamOptionID::kSoundAudioAPI, &gopts.audio_api),
|
||||
VbamOption(VbamOptionID::kSoundAudioDevice, &gopts.audio_dev),
|
||||
VbamOption(VbamOptionID::kSoundBuffers, &gopts.audio_buffers, 2, 10),
|
||||
VbamOption(VbamOptionID::kSoundEnable, &gopts.sound_en, 0, 0x30f),
|
||||
VbamOption(VbamOptionID::kSoundGBAFiltering, &gopts.gba_sound_filter, 0, 100),
|
||||
VbamOption(VbamOptionID::kSoundGBAInterpolation, &gopts.soundInterpolation),
|
||||
VbamOption(VbamOptionID::kSoundGBDeclicking, &gopts.gb_declick),
|
||||
VbamOption(VbamOptionID::kSoundGBEcho, &gopts.gb_echo, 0, 100),
|
||||
VbamOption(VbamOptionID::kSoundGBEnableEffects, &gopts.gb_effects_config_enabled),
|
||||
VbamOption(VbamOptionID::kSoundGBStereo, &gopts.gb_stereo, 0, 100),
|
||||
VbamOption(VbamOptionID::kSoundGBSurround, &gopts.gb_effects_config_surround),
|
||||
VbamOption(VbamOptionID::kSoundQuality, &gopts.sound_qual),
|
||||
VbamOption(VbamOptionID::kSoundVolume, &gopts.sound_vol, 0, 200),
|
||||
};
|
||||
return g_all_opts;
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
// These MUST follow the same order as the definitions in VbamOptionID.
|
||||
// Adding an option without adding to this array will result in a compiler
|
||||
// error since kNbOptions is automatically updated.
|
||||
const std::array<VbamOptionData, kNbOptions + 1> kAllOptionsData = {
|
||||
/// Display
|
||||
VbamOptionData { "Display/Bilinear", "Bilinear", _("Use bilinear filter with 3d renderer"), VbamOption::Type::kBool },
|
||||
VbamOptionData { "Display/Filter", "", _("Full-screen filter to apply"), VbamOption::Type::kFilter },
|
||||
VbamOptionData { "Display/FilterPlugin", "", _("Filter plugin library"), VbamOption::Type::kString },
|
||||
VbamOptionData { "Display/IFB", "", _("Interframe blending function"), VbamOption::Type::kInterframe },
|
||||
VbamOptionData { "Display/KeepOnTop", "KeepOnTop", _("Keep window on top"), VbamOption::Type::kBool },
|
||||
VbamOptionData { "Display/MaxThreads", "Multithread", _("Maximum number of threads to run filters in"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "Display/RenderMethod", "", _("Render method; if unsupported, simple method will be used"), VbamOption::Type::kRenderMethod },
|
||||
VbamOptionData { "Display/Scale", "", _("Default scale factor"), VbamOption::Type::kDouble },
|
||||
VbamOptionData { "Display/Stretch", "RetainAspect", _("Retain aspect ratio when resizing"), VbamOption::Type::kBool },
|
||||
|
||||
/// GB
|
||||
VbamOptionData { "GB/BiosFile", "", _("BIOS file to use for GB, if enabled"), VbamOption::Type::kString },
|
||||
VbamOptionData { "GB/ColorOption", "GBColorOption", _("GB color enhancement, if enabled"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "GB/ColorizerHack", "ColorizerHack", _("Enable DX Colorization Hacks"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "GB/LCDFilter", "GBLcdFilter", _("Apply LCD filter, if enabled"), VbamOption::Type::kBool },
|
||||
VbamOptionData { "GB/GBCBiosFile", "", _("BIOS file to use for GBC, if enabled"), VbamOption::Type::kString },
|
||||
VbamOptionData { "GB/Palette0", "", _("The default palette, as 8 comma-separated 4-digit hex integers (rgb555)."), VbamOption::Type::kGbPalette },
|
||||
VbamOptionData { "GB/Palette1", "", _("The first user palette, as 8 comma-separated 4-digit hex integers (rgb555)."), VbamOption::Type::kGbPalette },
|
||||
VbamOptionData { "GB/Palette2", "", _("The second user palette, as 8 comma-separated 4-digit hex integers (rgb555)."), VbamOption::Type::kGbPalette },
|
||||
VbamOptionData { "GB/PrintAutoPage", "PrintGather", _("Automatically gather a full page before printing"), VbamOption::Type::kBool },
|
||||
VbamOptionData { "GB/PrintScreenCap", "PrintSnap", _("Automatically save printouts as screen captures with -print suffix"), VbamOption::Type::kBool },
|
||||
VbamOptionData { "GB/ROMDir", "", _("Directory to look for ROM files"), VbamOption::Type::kString },
|
||||
VbamOptionData { "GB/GBCROMDir", "", _("Directory to look for GBC ROM files"), VbamOption::Type::kString },
|
||||
|
||||
/// GBA
|
||||
VbamOptionData { "GBA/BiosFile", "", _("BIOS file to use, if enabled"), VbamOption::Type::kString },
|
||||
VbamOptionData { "GBA/LCDFilter", "GBALcdFilter", _("Apply LCD filter, if enabled"), VbamOption::Type::kBool },
|
||||
#ifndef NO_LINK
|
||||
VbamOptionData { "GBA/LinkAuto", "LinkAuto", _("Enable link at boot"), VbamOption::Type::kBool },
|
||||
VbamOptionData { "GBA/LinkFast", "SpeedOn", _("Enable faster network protocol by default"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "GBA/LinkHost", "", _("Default network link client host"), VbamOption::Type::kString },
|
||||
VbamOptionData { "GBA/ServerIP", "", _("Default network link server IP to bind"), VbamOption::Type::kString },
|
||||
VbamOptionData { "GBA/LinkPort", "", _("Default network link port (server and client)"), VbamOption::Type::kUnsigned },
|
||||
VbamOptionData { "GBA/LinkProto", "LinkProto", _("Default network protocol"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "GBA/LinkTimeout", "LinkTimeout", _("Link timeout (ms)"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "GBA/LinkType", "LinkType", _("Link cable type"), VbamOption::Type::kInt },
|
||||
#endif
|
||||
VbamOptionData { "GBA/ROMDir", "", _("Directory to look for ROM files"), VbamOption::Type::kString },
|
||||
|
||||
/// General
|
||||
VbamOptionData { "General/AutoLoadLastState", "", _("Automatically load last saved state"), VbamOption::Type::kBool },
|
||||
VbamOptionData { "General/BatteryDir", "", _("Directory to store game save files (relative paths are relative to ROM; blank is config dir)"), VbamOption::Type::kString },
|
||||
VbamOptionData { "General/FreezeRecent", "", _("Freeze recent load list"), VbamOption::Type::kBool },
|
||||
VbamOptionData { "General/RecordingDir", "", _("Directory to store A/V and game recordings (relative paths are relative to ROM)"), VbamOption::Type::kString },
|
||||
VbamOptionData { "General/RewindInterval", "", _("Number of seconds between rewind snapshots (0 to disable)"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "General/ScreenshotDir", "", _("Directory to store screenshots (relative paths are relative to ROM)"), VbamOption::Type::kString },
|
||||
VbamOptionData { "General/StateDir", "", _("Directory to store saved state files (relative paths are relative to BatteryDir)"), VbamOption::Type::kString },
|
||||
VbamOptionData { "General/StatusBar", "StatusBar", _("Enable status bar"), VbamOption::Type::kInt },
|
||||
|
||||
/// Joypad
|
||||
VbamOptionData { "Joypad/*/*", "", _("The parameter Joypad/<n>/<button> contains a comma-separated list of key names which map to joypad #<n> button <button>. Button is one of Up, Down, Left, Right, A, B, L, R, Select, Start, MotionUp, MotionDown, MotionLeft, MotionRight, AutoA, AutoB, Speed, Capture, GS"), VbamOption::Type::kNone },
|
||||
VbamOptionData { "Joypad/AutofireThrottle", "", _("The autofire toggle period, in frames (1/60 s)"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "Joypad/Default", "", _("The number of the stick to use in single-player mode"), VbamOption::Type::kInt },
|
||||
|
||||
/// Keyboard
|
||||
VbamOptionData { "Keyboard/*", "", _("The parameter Keyboard/<cmd> contains a comma-separated list of key names (e.g. Alt-Shift-F1). When the named key is pressed, the command <cmd> is executed."), VbamOption::Type::kNone },
|
||||
|
||||
// Core
|
||||
VbamOptionData { "preferences/agbPrint", "AGBPrinter", _("Enable AGB debug print"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "preferences/autoFrameSkip", "FrameSkipAuto", _("Auto skip frames."), VbamOption::Type::kInt },
|
||||
VbamOptionData { "preferences/autoPatch", "ApplyPatches", _("Apply IPS/UPS/IPF patches if found"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "preferences/autoSaveLoadCheatList", "", _("Automatically save and load cheat list"), VbamOption::Type::kBool },
|
||||
VbamOptionData { "preferences/borderAutomatic", "", _("Automatically enable border for Super GameBoy games"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "preferences/borderOn", "", _("Always enable border"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "preferences/captureFormat", "", _("Screen capture file format"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "preferences/cheatsEnabled", "", _("Enable cheats"), VbamOption::Type::kInt },
|
||||
#ifdef MMX
|
||||
VbamOptionData { "preferences/enableMMX", "MMX", _("Enable MMX"), VbamOption::Type::kInt },
|
||||
#endif
|
||||
VbamOptionData { "preferences/disableStatus", "NoStatusMsg", _("Disable on-screen status messages"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "preferences/emulatorType", "", _("Type of system to emulate"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "preferences/flashSize", "", _("Flash size 0 = 64KB 1 = 128KB"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "preferences/frameSkip", "FrameSkip", _("Skip frames. Values are 0-9 or -1 to skip automatically based on time."), VbamOption::Type::kInt },
|
||||
VbamOptionData { "preferences/fsColorDepth", "", _("Fullscreen mode color depth (0 = any)"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "preferences/fsFrequency", "", _("Fullscreen mode frequency (0 = any)"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "preferences/fsHeight", "", _("Fullscreen mode height (0 = desktop)"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "preferences/fsWidth", "", _("Fullscreen mode width (0 = desktop)"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "preferences/gbPaletteOption", "", _("The palette to use"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "preferences/gbPrinter", "Printer", _("Enable printer emulation"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "preferences/gdbBreakOnLoad", "DebugGDBBreakOnLoad", _("Break into GDB after loading the game."), VbamOption::Type::kInt },
|
||||
VbamOptionData { "preferences/gdbPort", "DebugGDBPort", _("Port to connect GDB to."), VbamOption::Type::kInt },
|
||||
#ifndef NO_LINK
|
||||
VbamOptionData { "preferences/LinkNumPlayers", "", _("Number of players in network"), VbamOption::Type::kInt },
|
||||
#endif
|
||||
VbamOptionData { "preferences/maxScale", "", _("Maximum scale factor (0 = no limit)"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "preferences/pauseWhenInactive", "PauseWhenInactive", _("Pause game when main window loses focus"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "preferences/rtcEnabled", "RTC", _("Enable RTC (vba-over.ini override is rtcEnabled"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "preferences/saveType", "", _("Native save (\"battery\") hardware type"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "preferences/showSpeed", "", _("Show speed indicator"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "preferences/showSpeedTransparent", "Transparent", _("Draw on-screen messages transparently"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "preferences/skipBios", "SkipIntro", _("Skip BIOS initialization"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "preferences/skipSaveGameCheats", "", _("Do not overwrite cheat list when loading state"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "preferences/skipSaveGameBattery", "", _("Do not overwrite native (battery) save when loading state"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "preferences/throttle", "", _("Throttle game speed, even when accelerated (0-450%, 0 = no throttle)"), VbamOption::Type::kUnsigned },
|
||||
VbamOptionData { "preferences/speedupThrottle", "", _("Set throttle for speedup key (0-3000%, 0 = no throttle)"), VbamOption::Type::kUnsigned },
|
||||
VbamOptionData { "preferences/speedupFrameSkip", "", _("Number of frames to skip with speedup (instead of speedup throttle)"), VbamOption::Type::kUnsigned },
|
||||
VbamOptionData { "preferences/speedupThrottleFrameSkip", "", _("Use frame skip for speedup throttle"), VbamOption::Type::kBool },
|
||||
VbamOptionData { "preferences/useBiosGB", "BootRomGB", _("Use the specified BIOS file for GB"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "preferences/useBiosGBA", "BootRomEn", _("Use the specified BIOS file"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "preferences/useBiosGBC", "BootRomGBC", _("Use the specified BIOS file for GBC"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "preferences/vsync", "VSync", _("Wait for vertical sync"), VbamOption::Type::kInt },
|
||||
|
||||
/// Geometry
|
||||
VbamOptionData { "geometry/fullScreen", "Fullscreen", _("Enter fullscreen mode at startup"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "geometry/isMaximized", "Maximized", _("Window maximized"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "geometry/windowHeight", "Height", _("Window height at startup"), VbamOption::Type::kUnsigned },
|
||||
VbamOptionData { "geometry/windowWidth", "Width", _("Window width at startup"), VbamOption::Type::kUnsigned },
|
||||
VbamOptionData { "geometry/windowX", "X", _("Window axis X position at startup"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "geometry/windowY", "Y", _("Window axis Y position at startup"), VbamOption::Type::kInt },
|
||||
|
||||
/// UI
|
||||
VbamOptionData { "ui/allowKeyboardBackgroundInput", "AllowKeyboardBackgroundInput", _("Capture key events while on background"), VbamOption::Type::kBool },
|
||||
VbamOptionData { "ui/allowJoystickBackgroundInput", "AllowJoystickBackgroundInput", _("Capture joy events while on background"), VbamOption::Type::kBool },
|
||||
VbamOptionData { "ui/hideMenuBar", "", _("Hide menu bar when mouse is inactive"), VbamOption::Type::kBool },
|
||||
|
||||
/// Sound
|
||||
VbamOptionData { "Sound/AudioAPI", "", _("Sound API; if unsupported, default API will be used"), VbamOption::Type::kAudioApi },
|
||||
VbamOptionData { "Sound/AudioDevice", "", _("Device ID of chosen audio device for chosen driver"), VbamOption::Type::kString },
|
||||
VbamOptionData { "Sound/Buffers", "", _("Number of sound buffers"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "Sound/Enable", "", _("Bit mask of sound channels to enable"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "Sound/GBAFiltering", "", _("GBA sound filtering (%)"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "Sound/GBAInterpolation", "GBASoundInterpolation", _("GBA sound interpolation"), VbamOption::Type::kBool },
|
||||
VbamOptionData { "Sound/GBDeclicking", "GBDeclicking", _("GB sound declicking"), VbamOption::Type::kBool },
|
||||
VbamOptionData { "Sound/GBEcho", "", _("GB echo effect (%)"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "Sound/GBEnableEffects", "GBEnhanceSound", _("Enable GB sound effects"), VbamOption::Type::kBool },
|
||||
VbamOptionData { "Sound/GBStereo", "", _("GB stereo effect (%)"), VbamOption::Type::kInt },
|
||||
VbamOptionData { "Sound/GBSurround", "GBSurround", _("GB surround sound effect (%)"), VbamOption::Type::kBool },
|
||||
VbamOptionData { "Sound/Quality", "", _("Sound sample rate (kHz)"), VbamOption::Type::kSoundQuality },
|
||||
VbamOptionData { "Sound/Volume", "", _("Sound volume (%)"), VbamOption::Type::kInt },
|
||||
|
||||
// Last
|
||||
VbamOptionData { "", "", "", VbamOption::Type::kNone },
|
||||
};
|
||||
|
||||
nonstd::optional<VbamOptionID> StringToOptionId(const wxString& input) {
|
||||
// Note: This map does not include "Joystick" and "Keyboard". This is on
|
||||
// purpose, as these are handled separately.
|
||||
static const std::map<wxString, VbamOptionID> kStringToOptionId = {
|
||||
{ "Display/Bilinear", VbamOptionID::kDisplayBilinear },
|
||||
{ "Display/Filter", VbamOptionID::kDisplayFilter },
|
||||
{ "Display/FilterPlugin", VbamOptionID::kDisplayFilterPlugin },
|
||||
{ "Display/IFB", VbamOptionID::kDisplayIFB },
|
||||
{ "Display/KeepOnTop", VbamOptionID::kDisplayKeepOnTop },
|
||||
{ "Display/MaxThreads", VbamOptionID::kDisplayMaxThreads },
|
||||
{ "Display/RenderMethod", VbamOptionID::kDisplayRenderMethod },
|
||||
{ "Display/Scale", VbamOptionID::kDisplayScale },
|
||||
{ "Display/Stretch", VbamOptionID::kDisplayStretch },
|
||||
|
||||
/// GB
|
||||
{ "GB/BiosFile", VbamOptionID::kGBBiosFile },
|
||||
{ "GB/ColorOption", VbamOptionID::kGBColorOption },
|
||||
{ "GB/ColorizerHack", VbamOptionID::kGBColorizerHack },
|
||||
{ "GB/LCDFilter", VbamOptionID::kGBLCDFilter },
|
||||
{ "GB/GBCBiosFile", VbamOptionID::kGBGBCBiosFile },
|
||||
{ "GB/Palette0", VbamOptionID::kGBPalette0 },
|
||||
{ "GB/Palette1", VbamOptionID::kGBPalette1 },
|
||||
{ "GB/Palette2", VbamOptionID::kGBPalette2 },
|
||||
{ "GB/PrintAutoPage", VbamOptionID::kGBPrintAutoPage },
|
||||
{ "GB/PrintScreenCap", VbamOptionID::kGBPrintScreenCap },
|
||||
{ "GB/ROMDir", VbamOptionID::kGBROMDir },
|
||||
{ "GB/GBCROMDir", VbamOptionID::kGBGBCROMDir },
|
||||
|
||||
/// GBA
|
||||
{ "GBA/BiosFile", VbamOptionID::kGBABiosFile },
|
||||
{ "GBA/LCDFilter", VbamOptionID::kGBALCDFilter },
|
||||
#ifndef NO_LINK
|
||||
{ "GBA/LinkAuto", VbamOptionID::kGBALinkAuto },
|
||||
{ "GBA/LinkFast", VbamOptionID::kGBALinkFast },
|
||||
{ "GBA/LinkHost", VbamOptionID::kGBALinkHost },
|
||||
{ "GBA/ServerIP", VbamOptionID::kGBAServerIP },
|
||||
{ "GBA/LinkPort", VbamOptionID::kGBALinkPort },
|
||||
{ "GBA/LinkProto", VbamOptionID::kGBALinkProto },
|
||||
{ "GBA/LinkTimeout", VbamOptionID::kGBALinkTimeout },
|
||||
{ "GBA/LinkType", VbamOptionID::kGBALinkType },
|
||||
#endif
|
||||
{ "GBA/ROMDir", VbamOptionID::kGBAROMDir },
|
||||
|
||||
/// General
|
||||
{ "General/AutoLoadLastState", VbamOptionID::kGeneralAutoLoadLastState },
|
||||
{ "General/BatteryDir", VbamOptionID::kGeneralBatteryDir },
|
||||
{ "General/FreezeRecent", VbamOptionID::kGeneralFreezeRecent },
|
||||
{ "General/RecordingDir", VbamOptionID::kGeneralRecordingDir },
|
||||
{ "General/RewindInterval", VbamOptionID::kGeneralRewindInterval },
|
||||
{ "General/ScreenshotDir", VbamOptionID::kGeneralScreenshotDir },
|
||||
{ "General/StateDir", VbamOptionID::kGeneralStateDir },
|
||||
{ "General/StatusBar", VbamOptionID::kGeneralStatusBar },
|
||||
|
||||
/// Joypad
|
||||
{ "Joypad/AutofireThrottle", VbamOptionID::kJoypadAutofireThrottle },
|
||||
{ "Joypad/Default", VbamOptionID::kJoypadDefault },
|
||||
|
||||
// Core
|
||||
{ "preferences/agbPrint", VbamOptionID::kpreferencesagbPrint },
|
||||
{ "preferences/autoFrameSkip", VbamOptionID::kpreferencesautoFrameSkip },
|
||||
{ "preferences/autoPatch", VbamOptionID::kpreferencesautoPatch },
|
||||
{ "preferences/autoSaveLoadCheatList", VbamOptionID::kpreferencesautoSaveLoadCheatList },
|
||||
{ "preferences/borderAutomatic", VbamOptionID::kpreferencesborderAutomatic },
|
||||
{ "preferences/borderOn", VbamOptionID::kpreferencesborderOn },
|
||||
{ "preferences/captureFormat", VbamOptionID::kpreferencescaptureFormat },
|
||||
{ "preferences/cheatsEnabled", VbamOptionID::kpreferencescheatsEnabled },
|
||||
#ifdef MMX
|
||||
{ "preferences/enableMMX", VbamOptionID::kpreferencesenableMMX },
|
||||
#endif
|
||||
{ "preferences/disableStatus", VbamOptionID::kpreferencesdisableStatus },
|
||||
{ "preferences/emulatorType", VbamOptionID::kpreferencesemulatorType },
|
||||
{ "preferences/flashSize", VbamOptionID::kpreferencesflashSize },
|
||||
{ "preferences/frameSkip", VbamOptionID::kpreferencesframeSkip },
|
||||
{ "preferences/fsColorDepth", VbamOptionID::kpreferencesfsColorDepth },
|
||||
{ "preferences/fsFrequency", VbamOptionID::kpreferencesfsFrequency },
|
||||
{ "preferences/fsHeight", VbamOptionID::kpreferencesfsHeight },
|
||||
{ "preferences/fsWidth", VbamOptionID::kpreferencesfsWidth },
|
||||
{ "preferences/gbPaletteOption", VbamOptionID::kpreferencesgbPaletteOption },
|
||||
{ "preferences/gbPrinter", VbamOptionID::kpreferencesgbPrinter },
|
||||
{ "preferences/gdbBreakOnLoad", VbamOptionID::kpreferencesgdbBreakOnLoad },
|
||||
{ "preferences/gdbPort", VbamOptionID::kpreferencesgdbPort },
|
||||
#ifndef NO_LINK
|
||||
{ "preferences/LinkNumPlayers", VbamOptionID::kpreferencesLinkNumPlayers },
|
||||
#endif
|
||||
{ "preferences/maxScale", VbamOptionID::kpreferencesmaxScale },
|
||||
{ "preferences/pauseWhenInactive", VbamOptionID::kpreferencespauseWhenInactive },
|
||||
{ "preferences/rtcEnabled", VbamOptionID::kpreferencesrtcEnabled },
|
||||
{ "preferences/saveType", VbamOptionID::kpreferencessaveType },
|
||||
{ "preferences/showSpeed", VbamOptionID::kpreferencesshowSpeed },
|
||||
{ "preferences/showSpeedTransparent", VbamOptionID::kpreferencesshowSpeedTransparent },
|
||||
{ "preferences/skipBios", VbamOptionID::kpreferencesskipBios },
|
||||
{ "preferences/skipSaveGameCheats", VbamOptionID::kpreferencesskipSaveGameCheats },
|
||||
{ "preferences/skipSaveGameBattery", VbamOptionID::kpreferencesskipSaveGameBattery },
|
||||
{ "preferences/throttle", VbamOptionID::kpreferencesthrottle },
|
||||
{ "preferences/speedupThrottle", VbamOptionID::kpreferencesspeedupThrottle },
|
||||
{ "preferences/speedupFrameSkip", VbamOptionID::kpreferencesspeedupFrameSkip },
|
||||
{ "preferences/speedupThrottleFrameSkip", VbamOptionID::kpreferencesspeedupThrottleFrameSkip },
|
||||
{ "preferences/useBiosGB", VbamOptionID::kpreferencesuseBiosGB },
|
||||
{ "preferences/useBiosGBA", VbamOptionID::kpreferencesuseBiosGBA },
|
||||
{ "preferences/useBiosGBC", VbamOptionID::kpreferencesuseBiosGBC },
|
||||
{ "preferences/vsync", VbamOptionID::kpreferencesvsync },
|
||||
|
||||
/// Geometry
|
||||
{ "geometry/fullScreen", VbamOptionID::kgeometryfullScreen },
|
||||
{ "geometry/isMaximized", VbamOptionID::kgeometryisMaximized },
|
||||
{ "geometry/windowHeight", VbamOptionID::kgeometrywindowHeight },
|
||||
{ "geometry/windowWidth", VbamOptionID::kgeometrywindowWidth },
|
||||
{ "geometry/windowX", VbamOptionID::kgeometrywindowX },
|
||||
{ "geometry/windowY", VbamOptionID::kgeometrywindowY },
|
||||
|
||||
/// UI
|
||||
{ "ui/allowKeyboardBackgroundInput", VbamOptionID::kuiallowKeyboardBackgroundInput },
|
||||
{ "ui/allowJoystickBackgroundInput", VbamOptionID::kuiallowJoystickBackgroundInput },
|
||||
{ "ui/hideMenuBar", VbamOptionID::kuihideMenuBar },
|
||||
|
||||
/// Sound
|
||||
{ "Sound/AudioAPI", VbamOptionID::kSoundAudioAPI },
|
||||
{ "Sound/AudioDevice", VbamOptionID::kSoundAudioDevice },
|
||||
{ "Sound/Buffers", VbamOptionID::kSoundBuffers },
|
||||
{ "Sound/Enable", VbamOptionID::kSoundEnable },
|
||||
{ "Sound/GBAFiltering", VbamOptionID::kSoundGBAFiltering },
|
||||
{ "Sound/GBAInterpolation", VbamOptionID::kSoundGBAInterpolation },
|
||||
{ "Sound/GBDeclicking", VbamOptionID::kSoundGBDeclicking },
|
||||
{ "Sound/GBEcho", VbamOptionID::kSoundGBEcho },
|
||||
{ "Sound/GBEnableEffects", VbamOptionID::kSoundGBEnableEffects },
|
||||
{ "Sound/GBStereo", VbamOptionID::kSoundGBStereo },
|
||||
{ "Sound/GBSurround", VbamOptionID::kSoundGBSurround },
|
||||
{ "Sound/Quality", VbamOptionID::kSoundQuality },
|
||||
{ "Sound/Volume", VbamOptionID::kSoundVolume },
|
||||
};
|
||||
|
||||
const auto iter = kStringToOptionId.find(input);
|
||||
if (iter == kStringToOptionId.end()) {
|
||||
return nonstd::nullopt;
|
||||
}
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
wxString FilterToString(int value) {
|
||||
assert(value >= 0 && static_cast<size_t>(value) < kNbFilterFunctions);
|
||||
return kFilterStrings[value];
|
||||
}
|
||||
|
||||
wxString InterframeToString(int value) {
|
||||
assert(value >= 0 && static_cast<size_t>(value) < kNbInterframes);
|
||||
return kInterframeStrings[value];
|
||||
}
|
||||
|
||||
wxString RenderMethodToString(int value) {
|
||||
assert(value >= 0 && static_cast<size_t>(value) < kNbRenderMethods);
|
||||
return kRenderMethodStrings[value];
|
||||
}
|
||||
|
||||
wxString AudioApiToString(int value) {
|
||||
assert(value >= 0 && static_cast<size_t>(value) < kNbAudioApis);
|
||||
return kAudioApiStrings[value];
|
||||
}
|
||||
|
||||
wxString SoundQualityToString(int value) {
|
||||
assert(value >= 0 && static_cast<size_t>(value) < kNbSoundQualities);
|
||||
return kSoundQualityStrings[value];
|
||||
}
|
||||
|
||||
int StringToFilter(const wxString& config_name, const wxString& input) {
|
||||
static const std::map<wxString, FilterFunction> kStringToFilter = {
|
||||
{ kFilterStrings[0], FilterFunction::kNone },
|
||||
{ kFilterStrings[1], FilterFunction::k2xsai },
|
||||
{ kFilterStrings[2], FilterFunction::kSuper2xsai },
|
||||
{ kFilterStrings[3], FilterFunction::kSupereagle },
|
||||
{ kFilterStrings[4], FilterFunction::kPixelate },
|
||||
{ kFilterStrings[5], FilterFunction::kAdvmame },
|
||||
{ kFilterStrings[6], FilterFunction::kBilinear },
|
||||
{ kFilterStrings[7], FilterFunction::kBilinearplus },
|
||||
{ kFilterStrings[8], FilterFunction::kScanlines },
|
||||
{ kFilterStrings[9], FilterFunction::kTvmode },
|
||||
{ kFilterStrings[10], FilterFunction::kHQ2x },
|
||||
{ kFilterStrings[11], FilterFunction::kLQ2x },
|
||||
{ kFilterStrings[12], FilterFunction::kSimple2x },
|
||||
{ kFilterStrings[13], FilterFunction::kSimple3x },
|
||||
{ kFilterStrings[14], FilterFunction::kHQ3x },
|
||||
{ kFilterStrings[15], FilterFunction::kSimple4x },
|
||||
{ kFilterStrings[16], FilterFunction::kHQ4x },
|
||||
{ kFilterStrings[17], FilterFunction::kXbrz2x },
|
||||
{ kFilterStrings[18], FilterFunction::kXbrz3x },
|
||||
{ kFilterStrings[19], FilterFunction::kXbrz4x },
|
||||
{ kFilterStrings[20], FilterFunction::kXbrz5x },
|
||||
{ kFilterStrings[21], FilterFunction::kXbrz6x },
|
||||
{ kFilterStrings[22], FilterFunction::kPlugin },
|
||||
};
|
||||
assert(kFilterStrings.size() == kNbFilterFunctions);
|
||||
|
||||
const auto iter = kStringToFilter.find(input);
|
||||
if (iter == kStringToFilter.end()) {
|
||||
wxLogWarning(_("Invalid value %s for option %s; valid values are %s"),
|
||||
input,
|
||||
config_name,
|
||||
AllEnumValuesForType(VbamOption::Type::kFilter));
|
||||
return 0;
|
||||
}
|
||||
return static_cast<int>(iter->second);
|
||||
}
|
||||
|
||||
int StringToInterframe(const wxString& config_name, const wxString& input) {
|
||||
static const std::map<wxString, Interframe> kStringToInterframe = {
|
||||
{ kInterframeStrings[0], Interframe::kNone },
|
||||
{ kInterframeStrings[1], Interframe::kSmart },
|
||||
{ kInterframeStrings[2], Interframe::kMotionBlur },
|
||||
};
|
||||
assert(kStringToInterframe.size() == kNbInterframes);
|
||||
|
||||
const auto iter = kStringToInterframe.find(input);
|
||||
if (iter == kStringToInterframe.end()) {
|
||||
wxLogWarning(_("Invalid value %s for option %s; valid values are %s"),
|
||||
input,
|
||||
config_name,
|
||||
AllEnumValuesForType(VbamOption::Type::kInterframe));
|
||||
return 0;
|
||||
}
|
||||
return static_cast<int>(iter->second);
|
||||
}
|
||||
|
||||
int StringToRenderMethod(const wxString& config_name, const wxString& input) {
|
||||
static const std::map<wxString, RenderMethod> kStringToRenderMethod = {
|
||||
{ kRenderMethodStrings[0], RenderMethod::kSimple },
|
||||
{ kRenderMethodStrings[1], RenderMethod::kOpenGL },
|
||||
#ifdef __WXMSW__
|
||||
{ kRenderMethodStrings[2], RenderMethod::kDirect3d },
|
||||
#elif defined(__WXMAC__)
|
||||
{ kRenderMethodStrings[2], RenderMethod::kQuartz2d },
|
||||
#endif
|
||||
};
|
||||
assert(kStringToRenderMethod.size() == kNbRenderMethods);
|
||||
|
||||
const auto iter = kStringToRenderMethod.find(input);
|
||||
if (iter == kStringToRenderMethod.end()) {
|
||||
wxLogWarning(_("Invalid value %s for option %s; valid values are %s"),
|
||||
input,
|
||||
config_name,
|
||||
AllEnumValuesForType(VbamOption::Type::kRenderMethod));
|
||||
return 0;
|
||||
}
|
||||
return static_cast<int>(iter->second);
|
||||
}
|
||||
|
||||
int StringToAudioApi(const wxString& config_name, const wxString& input) {
|
||||
static const std::map<wxString, AudioApi> kStringToAudioApi = {
|
||||
{ kAudioApiStrings[0], AudioApi::kSdl },
|
||||
{ kAudioApiStrings[1], AudioApi::kOpenAL },
|
||||
{ kAudioApiStrings[2], AudioApi::kDirectSound },
|
||||
{ kAudioApiStrings[3], AudioApi::kXAudio2 },
|
||||
{ kAudioApiStrings[4], AudioApi::kFaudio },
|
||||
};
|
||||
assert(kStringToAudioApi.size() == kNbAudioApis);
|
||||
|
||||
const auto iter = kStringToAudioApi.find(input);
|
||||
if (iter == kStringToAudioApi.end()) {
|
||||
wxLogWarning(_("Invalid value %s for option %s; valid values are %s"),
|
||||
input,
|
||||
config_name,
|
||||
AllEnumValuesForType(VbamOption::Type::kAudioApi));
|
||||
return 0;
|
||||
}
|
||||
return static_cast<int>(iter->second);
|
||||
}
|
||||
|
||||
int StringToSoundQuality(const wxString& config_name, const wxString& input) {
|
||||
static const std::map<wxString, SoundQuality> kStringToSoundQuality = {
|
||||
{ kSoundQualityStrings[0], SoundQuality::k48kHz },
|
||||
{ kSoundQualityStrings[1], SoundQuality::k44kHz },
|
||||
{ kSoundQualityStrings[2], SoundQuality::k22kHz },
|
||||
{ kSoundQualityStrings[3], SoundQuality::k11kHz },
|
||||
};
|
||||
assert(kStringToSoundQuality.size() == kNbSoundQualities);
|
||||
|
||||
const auto iter = kStringToSoundQuality.find(input);
|
||||
if (iter == kStringToSoundQuality.end()) {
|
||||
wxLogWarning(_("Invalid value %s for option %s; valid values are %s"),
|
||||
input,
|
||||
config_name,
|
||||
AllEnumValuesForType(VbamOption::Type::kSoundQuality));
|
||||
return 0;
|
||||
}
|
||||
return static_cast<int>(iter->second);
|
||||
|
||||
}
|
||||
|
||||
wxString AllEnumValuesForType(VbamOption::Type type) {
|
||||
switch (type) {
|
||||
case VbamOption::Type::kFilter: {
|
||||
static const wxString kAllFilterValues = AllEnumValuesForArray(kFilterStrings);
|
||||
return kAllFilterValues;
|
||||
}
|
||||
case VbamOption::Type::kInterframe: {
|
||||
static const wxString kAllInterframeValues = AllEnumValuesForArray(kInterframeStrings);
|
||||
return kAllInterframeValues;
|
||||
}
|
||||
case VbamOption::Type::kRenderMethod: {
|
||||
static const wxString kAllRenderValues = AllEnumValuesForArray(kRenderMethodStrings);
|
||||
return kAllRenderValues;
|
||||
}
|
||||
case VbamOption::Type::kAudioApi: {
|
||||
static const wxString kAllAudioApiValues = AllEnumValuesForArray(kAudioApiStrings);
|
||||
return kAllAudioApiValues;
|
||||
}
|
||||
case VbamOption::Type::kSoundQuality: {
|
||||
static const wxString kAllSoundQualityValues = AllEnumValuesForArray(kSoundQualityStrings);
|
||||
return kAllSoundQualityValues;
|
||||
}
|
||||
|
||||
// We don't use default here to explicitly trigger a compiler warning when
|
||||
// adding a new value.
|
||||
case VbamOption::Type::kNone:
|
||||
case VbamOption::Type::kBool:
|
||||
case VbamOption::Type::kDouble:
|
||||
case VbamOption::Type::kInt:
|
||||
case VbamOption::Type::kUnsigned:
|
||||
case VbamOption::Type::kString:
|
||||
case VbamOption::Type::kGbPalette:
|
||||
assert(false);
|
||||
return wxEmptyString;
|
||||
}
|
||||
assert(false);
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
int MaxForType(VbamOption::Type type) {
|
||||
switch (type) {
|
||||
case VbamOption::Type::kFilter:
|
||||
return kNbFilterFunctions;
|
||||
case VbamOption::Type::kInterframe:
|
||||
return kNbInterframes;
|
||||
case VbamOption::Type::kRenderMethod:
|
||||
return kNbRenderMethods;
|
||||
case VbamOption::Type::kAudioApi:
|
||||
return kNbAudioApis;
|
||||
case VbamOption::Type::kSoundQuality:
|
||||
return kNbSoundQualities;
|
||||
|
||||
// We don't use default here to explicitly trigger a compiler warning when
|
||||
// adding a new value.
|
||||
case VbamOption::Type::kNone:
|
||||
case VbamOption::Type::kBool:
|
||||
case VbamOption::Type::kDouble:
|
||||
case VbamOption::Type::kInt:
|
||||
case VbamOption::Type::kUnsigned:
|
||||
case VbamOption::Type::kString:
|
||||
case VbamOption::Type::kGbPalette:
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace internal
|
|
@ -0,0 +1,368 @@
|
|||
#include "vbam-options.h"
|
||||
|
||||
#include <variant>
|
||||
#include <wx/log.h>
|
||||
#include <wx/translation.h>
|
||||
|
||||
#define VBAM_OPTIONS_INTERNAL_INCLUDE
|
||||
#include "vbam-options-internal.h"
|
||||
#undef VBAM_OPTIONS_INTERNAL_INCLUDE
|
||||
|
||||
// static
|
||||
VbamOption const* VbamOption::FindOptionByName(const wxString &config_name) {
|
||||
nonstd::optional<VbamOptionID> option_id = internal::StringToOptionId(config_name);
|
||||
if (!option_id) {
|
||||
return nullptr;
|
||||
}
|
||||
return &FindOptionByID(option_id.value());
|
||||
}
|
||||
|
||||
// static
|
||||
VbamOption& VbamOption::FindOptionByID(VbamOptionID id) {
|
||||
assert (id != VbamOptionID::Last);
|
||||
return AllOptions()[static_cast<size_t>(id)];
|
||||
}
|
||||
|
||||
VbamOption::~VbamOption() = default;
|
||||
|
||||
VbamOption::VbamOption(VbamOptionID id) :
|
||||
id_(id),
|
||||
config_name_(internal::kAllOptionsData[static_cast<size_t>(id)].config_name),
|
||||
command_(internal::kAllOptionsData[static_cast<size_t>(id)].command),
|
||||
ux_helper_(wxGetTranslation(internal::kAllOptionsData[static_cast<size_t>(id)].ux_helper)),
|
||||
type_(internal::kAllOptionsData[static_cast<size_t>(id)].type),
|
||||
value_(),
|
||||
min_(),
|
||||
max_() {
|
||||
assert(id != VbamOptionID::Last);
|
||||
assert(is_none());
|
||||
}
|
||||
|
||||
VbamOption::VbamOption(VbamOptionID id, bool* option) :
|
||||
id_(id),
|
||||
config_name_(internal::kAllOptionsData[static_cast<size_t>(id)].config_name),
|
||||
command_(internal::kAllOptionsData[static_cast<size_t>(id)].command),
|
||||
ux_helper_(wxGetTranslation(internal::kAllOptionsData[static_cast<size_t>(id)].ux_helper)),
|
||||
type_(internal::kAllOptionsData[static_cast<size_t>(id)].type),
|
||||
value_(option),
|
||||
min_(),
|
||||
max_() {
|
||||
assert(id != VbamOptionID::Last);
|
||||
assert(is_bool());
|
||||
}
|
||||
|
||||
VbamOption::VbamOption(VbamOptionID id, double* option, double min, double max) :
|
||||
id_(id),
|
||||
config_name_(internal::kAllOptionsData[static_cast<size_t>(id)].config_name),
|
||||
command_(internal::kAllOptionsData[static_cast<size_t>(id)].command),
|
||||
ux_helper_(wxGetTranslation(internal::kAllOptionsData[static_cast<size_t>(id)].ux_helper)),
|
||||
type_(internal::kAllOptionsData[static_cast<size_t>(id)].type),
|
||||
value_(option),
|
||||
min_(min),
|
||||
max_(max) {
|
||||
assert(id != VbamOptionID::Last);
|
||||
assert(is_double());
|
||||
|
||||
// Validate the initial value.
|
||||
SetDouble(*option);
|
||||
}
|
||||
|
||||
VbamOption::VbamOption(VbamOptionID id, int32_t* option, int32_t min, int32_t max) :
|
||||
id_(id),
|
||||
config_name_(internal::kAllOptionsData[static_cast<size_t>(id)].config_name),
|
||||
command_(internal::kAllOptionsData[static_cast<size_t>(id)].command),
|
||||
ux_helper_(wxGetTranslation(internal::kAllOptionsData[static_cast<size_t>(id)].ux_helper)),
|
||||
type_(internal::kAllOptionsData[static_cast<size_t>(id)].type),
|
||||
value_(option),
|
||||
min_(min),
|
||||
max_(max) {
|
||||
assert(id != VbamOptionID::Last);
|
||||
assert(is_int());
|
||||
|
||||
// Validate the initial value.
|
||||
SetInt(*option);
|
||||
}
|
||||
|
||||
VbamOption::VbamOption(VbamOptionID id, uint32_t* option, uint32_t min, uint32_t max) :
|
||||
id_(id),
|
||||
config_name_(internal::kAllOptionsData[static_cast<size_t>(id)].config_name),
|
||||
command_(internal::kAllOptionsData[static_cast<size_t>(id)].command),
|
||||
ux_helper_(wxGetTranslation(internal::kAllOptionsData[static_cast<size_t>(id)].ux_helper)),
|
||||
type_(internal::kAllOptionsData[static_cast<size_t>(id)].type),
|
||||
value_(option),
|
||||
min_(min),
|
||||
max_(max) {
|
||||
assert(id != VbamOptionID::Last);
|
||||
assert(is_unsigned());
|
||||
|
||||
// Validate the initial value.
|
||||
SetUnsigned(*option);
|
||||
}
|
||||
|
||||
VbamOption::VbamOption(VbamOptionID id, wxString* option) :
|
||||
id_(id),
|
||||
config_name_(internal::kAllOptionsData[static_cast<size_t>(id)].config_name),
|
||||
command_(internal::kAllOptionsData[static_cast<size_t>(id)].command),
|
||||
ux_helper_(wxGetTranslation(internal::kAllOptionsData[static_cast<size_t>(id)].ux_helper)),
|
||||
type_(internal::kAllOptionsData[static_cast<size_t>(id)].type),
|
||||
value_(option),
|
||||
min_(),
|
||||
max_() {
|
||||
assert(id != VbamOptionID::Last);
|
||||
assert(is_string());
|
||||
}
|
||||
|
||||
VbamOption::VbamOption(VbamOptionID id, int* option) :
|
||||
id_(id),
|
||||
config_name_(internal::kAllOptionsData[static_cast<size_t>(id)].config_name),
|
||||
command_(internal::kAllOptionsData[static_cast<size_t>(id)].command),
|
||||
ux_helper_(wxGetTranslation(internal::kAllOptionsData[static_cast<size_t>(id)].ux_helper)),
|
||||
type_(internal::kAllOptionsData[static_cast<size_t>(id)].type),
|
||||
value_(option),
|
||||
min_(0),
|
||||
max_(internal::MaxForType(type_)) {
|
||||
assert(id != VbamOptionID::Last);
|
||||
assert(is_filter() || is_interframe() || is_render_method() || is_audio_api() || is_sound_quality());
|
||||
|
||||
// Validate the initial value.
|
||||
SetEnumInt(*option);
|
||||
}
|
||||
|
||||
VbamOption::VbamOption(VbamOptionID id, uint16_t* option) :
|
||||
id_(id),
|
||||
config_name_(internal::kAllOptionsData[static_cast<size_t>(id)].config_name),
|
||||
command_(internal::kAllOptionsData[static_cast<size_t>(id)].command),
|
||||
ux_helper_(wxGetTranslation(internal::kAllOptionsData[static_cast<size_t>(id)].ux_helper)),
|
||||
type_(internal::kAllOptionsData[static_cast<size_t>(id)].type),
|
||||
value_(option),
|
||||
min_(),
|
||||
max_() {
|
||||
assert(id != VbamOptionID::Last);
|
||||
assert(is_gb_palette());
|
||||
}
|
||||
|
||||
bool VbamOption::GetBool() const {
|
||||
assert(is_bool());
|
||||
return *(std::get<bool*>(value_));
|
||||
}
|
||||
|
||||
double VbamOption::GetDouble() const {
|
||||
assert(is_double());
|
||||
return *(std::get<double*>(value_));
|
||||
}
|
||||
|
||||
int32_t VbamOption::GetInt() const {
|
||||
assert(is_int());
|
||||
return *(std::get<int32_t*>(value_));
|
||||
}
|
||||
|
||||
uint32_t VbamOption::GetUnsigned() const {
|
||||
assert(is_unsigned());
|
||||
return *(std::get<uint32_t*>(value_));
|
||||
}
|
||||
|
||||
const wxString VbamOption::GetString() const {
|
||||
assert(is_string());
|
||||
return *(std::get<wxString*>(value_));
|
||||
}
|
||||
|
||||
wxString VbamOption::GetEnumString() const {
|
||||
switch (type_) {
|
||||
case VbamOption::Type::kFilter:
|
||||
return internal::FilterToString(*(std::get<int32_t*>(value_)));
|
||||
case VbamOption::Type::kInterframe:
|
||||
return internal::InterframeToString(*(std::get<int32_t*>(value_)));
|
||||
case VbamOption::Type::kRenderMethod:
|
||||
return internal::RenderMethodToString(*(std::get<int32_t*>(value_)));
|
||||
case VbamOption::Type::kAudioApi:
|
||||
return internal::AudioApiToString(*(std::get<int32_t*>(value_)));
|
||||
case VbamOption::Type::kSoundQuality:
|
||||
return internal::SoundQualityToString(*(std::get<int32_t*>(value_)));
|
||||
|
||||
// We don't use default here to explicitly trigger a compiler warning when
|
||||
// adding a new value.
|
||||
case VbamOption::Type::kNone:
|
||||
case VbamOption::Type::kBool:
|
||||
case VbamOption::Type::kDouble:
|
||||
case VbamOption::Type::kInt:
|
||||
case VbamOption::Type::kUnsigned:
|
||||
case VbamOption::Type::kString:
|
||||
case VbamOption::Type::kGbPalette:
|
||||
assert(false);
|
||||
return wxEmptyString;
|
||||
}
|
||||
assert(false);
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
wxString VbamOption::GetGbPaletteString() const {
|
||||
assert(is_gb_palette());
|
||||
|
||||
wxString palette_string;
|
||||
uint16_t const* value = std::get<uint16_t*>(value_);
|
||||
palette_string.Printf("%04X,%04X,%04X,%04X,%04X,%04X,%04X,%04X",
|
||||
value[0], value[1], value[2], value[3],
|
||||
value[4], value[5], value[6], value[7]);
|
||||
return palette_string;
|
||||
}
|
||||
|
||||
void VbamOption::SetBool(bool value) const {
|
||||
assert(is_bool());
|
||||
*std::get<bool*>(value_) = value;
|
||||
}
|
||||
|
||||
void VbamOption::SetDouble(double value) const {
|
||||
assert(is_double());
|
||||
if (value < std::get<double>(min_) || value > std::get<double>(max_)) {
|
||||
wxLogWarning(
|
||||
_("Invalid value %f for option %s; valid values are %f - %f"),
|
||||
value,
|
||||
config_name_,
|
||||
std::get<double>(min_),
|
||||
std::get<double>(max_));
|
||||
return;
|
||||
}
|
||||
*std::get<double*>(value_) = value;
|
||||
}
|
||||
|
||||
void VbamOption::SetInt(int32_t value) const {
|
||||
assert(is_int());
|
||||
if (value < std::get<int32_t>(min_) || value > std::get<int32_t>(max_)) {
|
||||
wxLogWarning(
|
||||
_("Invalid value %d for option %s; valid values are %d - %d"),
|
||||
value,
|
||||
config_name_,
|
||||
std::get<int32_t>(min_),
|
||||
std::get<int32_t>(max_));
|
||||
return;
|
||||
}
|
||||
*std::get<int32_t*>(value_) = value;
|
||||
}
|
||||
|
||||
void VbamOption::SetUnsigned(uint32_t value) const {
|
||||
assert(is_unsigned());
|
||||
if (value < std::get<uint32_t>(min_) || value > std::get<uint32_t>(max_)) {
|
||||
wxLogWarning(
|
||||
_("Invalid value %d for option %s; valid values are %d - %d"),
|
||||
value,
|
||||
config_name_,
|
||||
std::get<uint32_t>(min_),
|
||||
std::get<uint32_t>(max_));
|
||||
return;
|
||||
}
|
||||
*std::get<uint32_t*>(value_) = value;
|
||||
}
|
||||
|
||||
void VbamOption::SetString(const wxString& value) const {
|
||||
assert(is_string());
|
||||
*std::get<wxString*>(value_) = value;
|
||||
}
|
||||
|
||||
void VbamOption::SetEnumString(const wxString& value) const {
|
||||
switch (type_) {
|
||||
case VbamOption::Type::kFilter:
|
||||
SetEnumInt(internal::StringToFilter(config_name_, value));
|
||||
return;
|
||||
case VbamOption::Type::kInterframe:
|
||||
SetEnumInt(internal::StringToInterframe(config_name_, value));
|
||||
return;
|
||||
case VbamOption::Type::kRenderMethod:
|
||||
SetEnumInt(internal::StringToRenderMethod(config_name_, value));
|
||||
return;
|
||||
case VbamOption::Type::kAudioApi:
|
||||
SetEnumInt(internal::StringToAudioApi(config_name_, value));
|
||||
return;
|
||||
case VbamOption::Type::kSoundQuality:
|
||||
SetEnumInt(internal::StringToSoundQuality(config_name_, value));
|
||||
return;
|
||||
|
||||
// We don't use default here to explicitly trigger a compiler warning when
|
||||
// adding a new value.
|
||||
case VbamOption::Type::kNone:
|
||||
case VbamOption::Type::kBool:
|
||||
case VbamOption::Type::kDouble:
|
||||
case VbamOption::Type::kInt:
|
||||
case VbamOption::Type::kUnsigned:
|
||||
case VbamOption::Type::kString:
|
||||
case VbamOption::Type::kGbPalette:
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void VbamOption::SetEnumInt(int value) const {
|
||||
assert(is_filter() || is_interframe() || is_render_method() || is_audio_api() || is_sound_quality());
|
||||
if (value < std::get<int32_t>(min_) || value > std::get<int32_t>(max_)) {
|
||||
wxLogWarning(
|
||||
_("Invalid value %d for option %s; valid values are %s"),
|
||||
value,
|
||||
config_name_,
|
||||
internal::AllEnumValuesForType(type_));
|
||||
return;
|
||||
}
|
||||
*std::get<int32_t*>(value_) = value;
|
||||
}
|
||||
|
||||
void VbamOption::SetGbPalette(const wxString& value) const {
|
||||
assert(is_gb_palette());
|
||||
|
||||
// 8 values of 4 chars and 7 commas.
|
||||
static constexpr size_t kPaletteStringSize = 8 * 4 + 7;
|
||||
|
||||
if (value.size() != kPaletteStringSize) {
|
||||
wxLogWarning(_("Invalid value %s for option %s"),
|
||||
value,
|
||||
config_name_);
|
||||
return;
|
||||
}
|
||||
uint16_t* dest = std::get<uint16_t*>(value_);
|
||||
|
||||
for (size_t i = 0; i < 8; i++) {
|
||||
wxString number = value.substr(i * 4, 4);
|
||||
long temp = 0;
|
||||
if (number.ToLong(&temp, 16)) {
|
||||
dest[i] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wxString VbamOption::ToHelperString() const {
|
||||
wxString helper_string = config_name_;
|
||||
|
||||
switch (type_) {
|
||||
case VbamOption::Type::kNone:
|
||||
break;
|
||||
case VbamOption::Type::kBool:
|
||||
helper_string.Append(" (flag)");
|
||||
break;
|
||||
case VbamOption::Type::kDouble:
|
||||
helper_string.Append(" (decimal)");
|
||||
break;
|
||||
case VbamOption::Type::kInt:
|
||||
helper_string.Append(" (int)");
|
||||
break;
|
||||
case VbamOption::Type::kUnsigned:
|
||||
helper_string.Append(" (unsigned)");
|
||||
break;
|
||||
case VbamOption::Type::kString:
|
||||
helper_string.Append(" (string)");
|
||||
break;
|
||||
case VbamOption::Type::kFilter:
|
||||
case VbamOption::Type::kInterframe:
|
||||
case VbamOption::Type::kRenderMethod:
|
||||
case VbamOption::Type::kAudioApi:
|
||||
case VbamOption::Type::kSoundQuality:
|
||||
helper_string.Append(" (");
|
||||
helper_string.Append(internal::AllEnumValuesForType(type_));
|
||||
helper_string.Append(")");
|
||||
break;
|
||||
case VbamOption::Type::kGbPalette:
|
||||
helper_string.Append(" (XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX)");
|
||||
break;
|
||||
}
|
||||
helper_string.Append("\n\t");
|
||||
helper_string.Append(ux_helper_);
|
||||
helper_string.Append("\n");
|
||||
|
||||
return helper_string;
|
||||
}
|
|
@ -0,0 +1,272 @@
|
|||
#ifndef VBAM_OPTIONS_H
|
||||
#define VBAM_OPTIONS_H
|
||||
|
||||
#include <array>
|
||||
#include <variant>
|
||||
|
||||
#include <wx/string.h>
|
||||
|
||||
enum class VbamOptionID {
|
||||
// Display
|
||||
kDisplayBilinear = 0,
|
||||
kDisplayFilter,
|
||||
kDisplayFilterPlugin,
|
||||
kDisplayIFB,
|
||||
kDisplayKeepOnTop,
|
||||
kDisplayMaxThreads,
|
||||
kDisplayRenderMethod,
|
||||
kDisplayScale,
|
||||
kDisplayStretch,
|
||||
|
||||
/// GB
|
||||
kGBBiosFile,
|
||||
kGBColorOption,
|
||||
kGBColorizerHack,
|
||||
kGBLCDFilter,
|
||||
kGBGBCBiosFile,
|
||||
kGBPalette0,
|
||||
kGBPalette1,
|
||||
kGBPalette2,
|
||||
kGBPrintAutoPage,
|
||||
kGBPrintScreenCap,
|
||||
kGBROMDir,
|
||||
kGBGBCROMDir,
|
||||
|
||||
/// GBA
|
||||
kGBABiosFile,
|
||||
kGBALCDFilter,
|
||||
#ifndef NO_LINK
|
||||
kGBALinkAuto,
|
||||
kGBALinkFast,
|
||||
kGBALinkHost,
|
||||
kGBAServerIP,
|
||||
kGBALinkPort,
|
||||
kGBALinkProto,
|
||||
kGBALinkTimeout,
|
||||
kGBALinkType,
|
||||
#endif
|
||||
kGBAROMDir,
|
||||
|
||||
/// General
|
||||
kGeneralAutoLoadLastState,
|
||||
kGeneralBatteryDir,
|
||||
kGeneralFreezeRecent,
|
||||
kGeneralRecordingDir,
|
||||
kGeneralRewindInterval,
|
||||
kGeneralScreenshotDir,
|
||||
kGeneralStateDir,
|
||||
kGeneralStatusBar,
|
||||
|
||||
/// Joypad
|
||||
kJoypad,
|
||||
kJoypadAutofireThrottle,
|
||||
|
||||
/// Keyboard
|
||||
kJoypadDefault,
|
||||
|
||||
/// Keyboard
|
||||
kKeyboard,
|
||||
|
||||
// Core
|
||||
kpreferencesagbPrint,
|
||||
kpreferencesautoFrameSkip,
|
||||
kpreferencesautoPatch,
|
||||
kpreferencesautoSaveLoadCheatList,
|
||||
kpreferencesborderAutomatic,
|
||||
kpreferencesborderOn,
|
||||
kpreferencescaptureFormat,
|
||||
kpreferencescheatsEnabled,
|
||||
|
||||
#ifdef MMX
|
||||
kpreferencesenableMMX,
|
||||
#endif
|
||||
kpreferencesdisableStatus,
|
||||
kpreferencesemulatorType,
|
||||
kpreferencesflashSize,
|
||||
kpreferencesframeSkip,
|
||||
kpreferencesfsColorDepth,
|
||||
kpreferencesfsFrequency,
|
||||
kpreferencesfsHeight,
|
||||
kpreferencesfsWidth,
|
||||
kpreferencesgbPaletteOption,
|
||||
kpreferencesgbPrinter,
|
||||
kpreferencesgdbBreakOnLoad,
|
||||
kpreferencesgdbPort,
|
||||
#ifndef NO_LINK
|
||||
kpreferencesLinkNumPlayers,
|
||||
#endif
|
||||
kpreferencesmaxScale,
|
||||
kpreferencespauseWhenInactive,
|
||||
kpreferencesrtcEnabled,
|
||||
kpreferencessaveType,
|
||||
kpreferencesshowSpeed,
|
||||
kpreferencesshowSpeedTransparent,
|
||||
kpreferencesskipBios,
|
||||
kpreferencesskipSaveGameCheats,
|
||||
kpreferencesskipSaveGameBattery,
|
||||
kpreferencesthrottle,
|
||||
kpreferencesspeedupThrottle,
|
||||
kpreferencesspeedupFrameSkip,
|
||||
kpreferencesspeedupThrottleFrameSkip,
|
||||
kpreferencesuseBiosGB,
|
||||
kpreferencesuseBiosGBA,
|
||||
kpreferencesuseBiosGBC,
|
||||
kpreferencesvsync,
|
||||
|
||||
/// Geometry
|
||||
kgeometryfullScreen,
|
||||
kgeometryisMaximized,
|
||||
kgeometrywindowHeight,
|
||||
kgeometrywindowWidth,
|
||||
kgeometrywindowX,
|
||||
kgeometrywindowY,
|
||||
|
||||
/// UI
|
||||
kuiallowKeyboardBackgroundInput,
|
||||
kuiallowJoystickBackgroundInput,
|
||||
kuihideMenuBar,
|
||||
|
||||
/// Sound
|
||||
kSoundAudioAPI,
|
||||
kSoundAudioDevice,
|
||||
kSoundBuffers,
|
||||
kSoundEnable,
|
||||
kSoundGBAFiltering,
|
||||
kSoundGBAInterpolation,
|
||||
kSoundGBDeclicking,
|
||||
kSoundGBEcho,
|
||||
kSoundGBEnableEffects,
|
||||
kSoundGBStereo,
|
||||
kSoundGBSurround,
|
||||
kSoundQuality,
|
||||
kSoundVolume,
|
||||
|
||||
// Do not add anything under here.
|
||||
Last,
|
||||
};
|
||||
|
||||
constexpr size_t kNbOptions = static_cast<size_t>(VbamOptionID::Last);
|
||||
|
||||
// Represents a single option saved in the INI file. VbamOption does not own the
|
||||
// individual option, but keeps a pointer to where the data is actually saved.
|
||||
//
|
||||
// Ideally, options in the UI code should only be accessed and set via this
|
||||
// class, which should also take care of updating the INI file when
|
||||
// VbamOption::Set*() is called. This should also handle keyboard and joystick
|
||||
// configuration so option parsing can be done in a uniform manner. If we ever
|
||||
// get to that point, we would be able to remove most update_opts() calls and
|
||||
// have individual UI elements access the option via
|
||||
// VbamOption::FindOptionByID().
|
||||
//
|
||||
// The implementation for this class is largely inspired by base::Value in
|
||||
// Chromium.
|
||||
// https://source.chromium.org/chromium/chromium/src/+/main:base/values.h
|
||||
class VbamOption {
|
||||
public:
|
||||
enum class Type {
|
||||
kNone = 0,
|
||||
kBool,
|
||||
kDouble,
|
||||
kInt,
|
||||
kUnsigned,
|
||||
kString,
|
||||
kFilter,
|
||||
kInterframe,
|
||||
kRenderMethod,
|
||||
kAudioApi,
|
||||
kSoundQuality,
|
||||
kGbPalette,
|
||||
};
|
||||
|
||||
static std::array<VbamOption, kNbOptions>& AllOptions();
|
||||
|
||||
// O(log(kNbOptions))
|
||||
static VbamOption const* FindOptionByName(const wxString& config_name);
|
||||
|
||||
// O(1)
|
||||
static VbamOption& FindOptionByID(VbamOptionID id);
|
||||
|
||||
~VbamOption();
|
||||
|
||||
// Accessors.
|
||||
const wxString& config_name() const { return config_name_; }
|
||||
const wxString& command() const { return command_; }
|
||||
const wxString& ux_helper() const { return ux_helper_; }
|
||||
|
||||
// Returns the type of the value stored by the current object.
|
||||
Type type() const { return type_; }
|
||||
|
||||
// Returns true if the current object represents a given type.
|
||||
bool is_none() const { return type() == Type::kNone; }
|
||||
bool is_bool() const { return type() == Type::kBool; }
|
||||
bool is_double() const { return type() == Type::kDouble; }
|
||||
bool is_int() const { return type() == Type::kInt; }
|
||||
bool is_unsigned() const { return type() == Type::kUnsigned; }
|
||||
bool is_string() const { return type() == Type::kString; }
|
||||
bool is_filter() const { return type() == Type::kFilter; }
|
||||
bool is_interframe() const { return type() == Type::kInterframe; }
|
||||
bool is_render_method() const { return type() == Type::kRenderMethod; }
|
||||
bool is_audio_api() const { return type() == Type::kAudioApi; }
|
||||
bool is_sound_quality() const { return type() == Type::kSoundQuality; }
|
||||
bool is_gb_palette() const { return type() == Type::kGbPalette; }
|
||||
|
||||
// Returns a reference to the stored data. Will assert on type mismatch.
|
||||
// All enum types go through GetEnumString().
|
||||
bool GetBool() const;
|
||||
double GetDouble() const;
|
||||
int32_t GetInt() const;
|
||||
uint32_t GetUnsigned() const;
|
||||
const wxString GetString() const;
|
||||
wxString GetEnumString() const;
|
||||
wxString GetGbPaletteString() const;
|
||||
|
||||
// Sets the value. Will assert on type mismatch.
|
||||
// All enum types go through SetEnumString() and SetEnumInt().
|
||||
void SetBool(bool value) const;
|
||||
void SetDouble(double value) const;
|
||||
void SetInt(int32_t value) const;
|
||||
void SetUnsigned(uint32_t value) const;
|
||||
void SetString(const wxString& value) const;
|
||||
void SetEnumString(const wxString& value) const;
|
||||
void SetEnumInt(int value) const;
|
||||
void SetGbPalette(const wxString& value) const;
|
||||
|
||||
// Command-line helper string.
|
||||
wxString ToHelperString() const;
|
||||
|
||||
private:
|
||||
// Disable copy and assignment. Every individual option is unique.
|
||||
VbamOption(const VbamOption&) = delete;
|
||||
VbamOption& operator=(const VbamOption&) = delete;
|
||||
|
||||
VbamOption(VbamOptionID id);
|
||||
VbamOption(VbamOptionID id, bool* option);
|
||||
VbamOption(VbamOptionID id, double* option, double min, double max);
|
||||
VbamOption(VbamOptionID id, int32_t* option, int32_t min, int32_t max);
|
||||
VbamOption(VbamOptionID id, uint32_t* option, uint32_t min, uint32_t max);
|
||||
VbamOption(VbamOptionID id, wxString* option);
|
||||
VbamOption(VbamOptionID id, int* option);
|
||||
VbamOption(VbamOptionID id, uint16_t* option);
|
||||
|
||||
const VbamOptionID id_;
|
||||
|
||||
const wxString config_name_;
|
||||
const wxString command_;
|
||||
const wxString ux_helper_;
|
||||
|
||||
const Type type_;
|
||||
const std::variant<
|
||||
std::monostate,
|
||||
bool*,
|
||||
double*,
|
||||
int32_t*,
|
||||
uint32_t*,
|
||||
wxString*,
|
||||
uint16_t*>
|
||||
value_;
|
||||
|
||||
const std::variant<std::monostate, double, int32_t, uint32_t> min_;
|
||||
const std::variant<std::monostate, double, int32_t, uint32_t> max_;
|
||||
};
|
||||
|
||||
#endif /* VBAM_OPTIONS_H */
|
|
@ -4,6 +4,7 @@
|
|||
// create & display main frame
|
||||
|
||||
#include "wxvbam.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <wx/cmdline.h>
|
||||
#include <wx/file.h>
|
||||
|
@ -19,14 +20,15 @@
|
|||
#include <wx/url.h>
|
||||
#include <wx/wfstream.h>
|
||||
#include <wx/zipstrm.h>
|
||||
#include "wayland.h"
|
||||
#include "strutils.h"
|
||||
|
||||
// The built-in xrc file
|
||||
#include "builtin-xrc.h"
|
||||
|
||||
// The built-in vba-over.ini
|
||||
#include "builtin-over.h"
|
||||
#include "strutils.h"
|
||||
#include "vbam-options.h"
|
||||
#include "wayland.h"
|
||||
#include "wx/gamecontrol.h"
|
||||
#include "wx/userinput.h"
|
||||
|
||||
|
@ -627,29 +629,19 @@ bool wxvbamApp::OnCmdLineParsed(wxCmdLineParser& cl)
|
|||
}
|
||||
|
||||
if (cl.Found(wxT("o"))) {
|
||||
// This was most likely done on a command line, so use
|
||||
// stderr instead of gui for messages
|
||||
wxLog::SetActiveTarget(new wxLogStderr);
|
||||
|
||||
wxPrintf(_("Options set from the command line are saved if any"
|
||||
" configuration changes are made in the user interface.\n\n"
|
||||
"For flag options, true and false are specified as 1 and 0, respectively.\n\n"));
|
||||
|
||||
for (int i = 0; i < num_opts; i++) {
|
||||
wxPrintf(wxT("%s (%s"), opts[i].opt.c_str(),
|
||||
opts[i].boolopt ? wxT("flag") : opts[i].stropt ? wxT("string") : !opts[i].enumvals.empty() ? opts[i].enumvals.c_str() : (opts[i].intopt ? wxT("int") : opts[i].doubleopt ? wxT("decimal") : wxT("string")));
|
||||
|
||||
if (!opts[i].enumvals.empty()) {
|
||||
const wxString evx = wxGetTranslation(opts[i].enumvals);
|
||||
|
||||
if (wxStrcmp(evx, opts[i].enumvals))
|
||||
wxPrintf(wxT(" = %s"), evx.c_str());
|
||||
}
|
||||
|
||||
wxPrintf(wxT(")\n\t%s\n\n"), opts[i].desc.c_str());
|
||||
|
||||
if (!opts[i].enumvals.empty())
|
||||
opts[i].enumvals = wxGetTranslation(opts[i].enumvals);
|
||||
for (const VbamOption& opt : VbamOption::AllOptions()) {
|
||||
wxPrintf("%s\n", opt.ToHelperString());
|
||||
}
|
||||
|
||||
wxPrintf(_("The commands available for the Keyboard/* option are:\n\n"));
|
||||
|
||||
for (int i = 0; i < ncmds; i++)
|
||||
wxPrintf(wxT("%s (%s)\n"), cmdtab[i].cmd.c_str(), cmdtab[i].name.c_str());
|
||||
|
||||
|
|
|
@ -194,8 +194,8 @@ enum { CMDEN_GB = (1 << 0), // GB ROM loaded
|
|||
struct checkable_mi_t {
|
||||
int cmd;
|
||||
wxMenuItem* mi;
|
||||
bool* boolopt;
|
||||
int *intopt, mask, val;
|
||||
int mask, val;
|
||||
bool initialized = false;
|
||||
};
|
||||
|
||||
// wxArray is only for small types
|
||||
|
@ -218,12 +218,12 @@ public:
|
|||
~MainFrame();
|
||||
|
||||
bool BindControls();
|
||||
void MenuOptionIntMask(const char* menuName, int& field, int mask);
|
||||
void MenuOptionIntRadioValue(const char* menuName, int& field, int mask);
|
||||
void MenuOptionBool(const char* menuName, bool& field);
|
||||
void GetMenuOptionInt(const char* menuName, int& field, int mask);
|
||||
void GetMenuOptionBool(const char* menuName, bool& field);
|
||||
void SetMenuOption(const char* menuName, int value);
|
||||
void MenuOptionIntMask(const wxString& menuName, int field, int mask);
|
||||
void MenuOptionIntRadioValue(const wxString& menuName, int field, int mask);
|
||||
void MenuOptionBool(const wxString& menuName, bool field);
|
||||
void GetMenuOptionInt(const wxString& menuName, int field, int mask);
|
||||
void GetMenuOptionBool(const wxString& menuName, bool field);
|
||||
void SetMenuOption(const wxString& menuName, int value);
|
||||
|
||||
void SetJoystick();
|
||||
|
||||
|
@ -434,6 +434,7 @@ enum showspeed {
|
|||
SS_DETAILED
|
||||
};
|
||||
|
||||
// This enum must be kept in sync with the one in vbam-options-static.cpp.
|
||||
enum filtfunc {
|
||||
// this order must match order of option enum and selector widget
|
||||
FF_NONE,
|
||||
|
@ -469,14 +470,14 @@ enum filtfunc {
|
|||
? 3 \
|
||||
: x == FF_PLUGIN ? 0 : x == FF_NONE ? 1 : 2)
|
||||
|
||||
// This enum must be kept in sync with the one in vbam-options-static.cpp.
|
||||
enum ifbfunc {
|
||||
// this order must match order of option enum and selector widget
|
||||
IFB_NONE,
|
||||
IFB_SMART,
|
||||
IFB_MOTION_BLUR
|
||||
};
|
||||
|
||||
// make sure and keep this in sync with opts.cpp!
|
||||
// This enum must be kept in sync with the one in vbam-options-static.cpp.
|
||||
enum renderer {
|
||||
RND_SIMPLE,
|
||||
RND_OPENGL,
|
||||
|
@ -484,7 +485,7 @@ enum renderer {
|
|||
RND_QUARTZ2D,
|
||||
};
|
||||
|
||||
// likewise
|
||||
// This enum must be kept in sync with the one in vbam-options-static.cpp.
|
||||
enum audioapi { AUD_SDL,
|
||||
AUD_OPENAL,
|
||||
AUD_DIRECTSOUND,
|
||||
|
|
Loading…
Reference in New Issue