segatools-configurator/option.cpp
2024-04-14 17:37:36 +07:00

1035 lines
34 KiB
C++

//
// Created by beerpsi on 4/13/2024.
//
#include <stdexcept>
#include <memory>
#include <windows.h>
#include <iostream>
#include "option.h"
static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
{
.title = "CHUNITHM: ChuniIO Path",
.section = "chuniio",
.key = "path",
.desc = "Set this option to use a custom CHUNITHM IO DLL.",
.type = OptionType::Text,
.default_value = "",
.max_string_length = MAX_PATH - 1,
.game_name = "CHUNITHM",
.category = "Game Options",
},
{
.title = "CHUNITHM: Separate IR control",
.section = "io3",
.key = "ir",
.desc = "Use separate 'Air X' keybindings instead of the single 'Air' keybind. DO NOT BIND 'AIR' AFTER ENABLING THIS!",
.type = OptionType::Enum,
.default_value = "0x20",
.max_string_length = 16,
.game_name = "CHUNITHM",
.category = "Game Options",
.elements = { { "0x20", "Off" }, { "0", "On" } },
},
{
.title = "CHUNITHM: Enable LED emulation",
.section = "led15093",
.key = "enable",
.desc = "This LED controller handles the air tower RGBs and the rear LED panel (billboard) on the cabinet.",
.type = OptionType::Bool,
.default_value = "1",
.game_name = "CHUNITHM",
.category = "Game Options",
},
{
.title = "CHUNITHM NEW!!: Monitor type",
.section = "gpio",
.key = "dipsw2",
.desc = "Set this to your monitor's refresh rate.",
.type = OptionType::Enum,
.default_value = "1",
.max_string_length = 1,
.game_name = "CHUNITHM NEW!!",
.category = "Game Options",
.elements = { { "0", "120Hz" }, { "1", "60Hz" } },
},
{
.title = "CHUNITHM NEW!!: Cabinet type",
.section = "gpio",
.key = "dipsw3",
.desc = "SP will enable VFD and eMoney. 120Hz and CVT will crash your game.",
.type = OptionType::Enum,
.default_value = "1",
.max_string_length = 1,
.game_name = "CHUNITHM NEW!!",
.category = "Game Options",
.elements = { { "0", "SP" }, { "1", "CVT" } },
},
{
.title = "CHUNITHM NEW!!: ChuniIO Path",
.section = "chuniio",
.key = "path",
.desc = "Set this option if you have a single DLL for your ChuniIO.",
.type = OptionType::Text,
.default_value = "",
.max_string_length = MAX_PATH - 1,
.game_name = "CHUNITHM NEW!!",
.category = "Game Options",
},
{
.title = "CHUNITHM NEW!!: ChuniIO x86 Path",
.section = "chuniio",
.key = "path32",
.desc = "Set this option if you have two DLLs for your CHUNIIO.",
.type = OptionType::Text,
.default_value = "",
.max_string_length = MAX_PATH - 1,
.game_name = "CHUNITHM NEW!!",
.category = "Game Options",
},
{
.title = "CHUNITHM NEW!!: ChuniIO x64 Path",
.section = "chuniio",
.key = "path64",
.desc = "Set this option if you have two DLLs for your CHUNIIO.",
.type = OptionType::Text,
.default_value = "",
.max_string_length = MAX_PATH - 1,
.game_name = "CHUNITHM NEW!!",
.category = "Game Options",
},
{
.title = "CHUNITHM NEW!!: Separate IR control",
.section = "io3",
.key = "ir",
.desc = "Use separate 'Air X' keybindings instead of the single 'Air' keybind. DO NOT BIND 'AIR' AFTER ENABLING THIS!",
.type = OptionType::Enum,
.default_value = "0x20",
.max_string_length = 16,
.game_name = "CHUNITHM NEW!!",
.category = "Game Options",
.elements = { { "0x20", "Off" }, { "0", "On" } },
},
{
.title = "CHUNITHM NEW!!: Enable LED emulation",
.section = "led15093",
.key = "enable",
.desc = "This LED controller handles the air tower RGBs and the rear LED panel (billboard) on the cabinet.",
.type = OptionType::Bool,
.default_value = "1",
.game_name = "CHUNITHM NEW!!",
.category = "Game Options",
},
{
.title = "maimai DX: Mai2IO DLL",
.section = "mai2io",
.key = "path",
.desc = "Set this option to use a custom maimai DX IO DLL.",
.type = OptionType::Text,
.default_value = "",
.max_string_length = MAX_PATH - 1,
.game_name = "maimai DX",
.category = "Game Options",
},
{
.title = "O.N.G.E.K.I.: Mu3IO DLL",
.section = "mu3io",
.key = "path",
.desc = "Set this option to use a custom O.N.G.E.K.I. IO DLL.",
.type = OptionType::Text,
.default_value = "",
.max_string_length = MAX_PATH - 1,
.game_name = "O.N.G.E.K.I.",
.category = "Game Options",
},
{
.title = "O.N.G.E.K.I.: Mouse lever emulation",
.section = "io4",
.key = "mouse",
.desc = "Disable to use XInput",
.type = OptionType::Bool,
.default_value = "1",
.game_name = "O.N.G.E.K.I.",
.category = "Game Options",
},
{
.title = "WACCA: MercuryIO DLL",
.section = "mercuryio",
.key = "path",
.desc = "Set this option to use a custom WACCA IO DLL.",
.type = OptionType::Text,
.default_value = "",
.max_string_length = MAX_PATH - 1,
.game_name = "WACCA",
.category = "Game Options",
},
{
.title = "WACCA: Enable touch hooks",
.section = "touch",
.key = "enable",
.type = OptionType::Bool,
.default_value = "1",
.game_name = "WACCA",
.category = "Game Options",
},
{
.title = "WACCA: Enable LED board hooks",
.section = "elisabeth",
.key = "enable",
.type = OptionType::Bool,
.default_value = "1",
.game_name = "WACCA",
.category = "Game Options",
},
{
.title = "Enable path redirection",
.section = "vfs",
.key = "enable",
.type = OptionType::Bool,
.default_value = "1",
.category = "VFS",
},
{
.title = "SEGA AMFS volume path",
.section = "vfs",
.key = "amfs",
.desc = "Enter the path to the game's AMFS directory (containing ICF1 and ICF2) here. Leaving this empty causes a startup error!",
.type = OptionType::Text,
.default_value = "",
.max_string_length = MAX_PATH - 1,
.category = "VFS",
},
{
.title = "SEGA APPDATA volume path",
.section = "vfs",
.key = "appdata",
.desc = "Create an empty folder somewhere and enter its path here. Nothing to do with Windows' %APPDATA%. Leaving this empty causes a startup error!",
.type = OptionType::Text,
.default_value = "",
.max_string_length = MAX_PATH - 1,
.category = "VFS",
},
{
.title = "Option data path",
.section = "vfs",
.key = "option",
.desc = "Sets the path to the game's Option folder (contains Axxx folders)",
.type = OptionType::Text,
.default_value = "",
.max_string_length = MAX_PATH - 1,
.category = "VFS",
},
{
.title = "Aime reader emulation",
.section = "aime",
.key = "enable",
.desc = "Disable to use a real SEGA Aime reader (COM port number varies by game).",
.type = OptionType::Bool,
.default_value = "1",
.category = "Aime",
},
{
.title = "High baud rate",
.section = "aime",
.key = "highBaud",
.desc = "Enables the high baudrate of the Aime card reader to be 115200 (instead of 38400). This is required for some games (e.g. CHUNTHM) but not others (e.g. WACCA).",
.type = OptionType::Bool,
.default_value = "1",
.category = "Aime",
},
{
.title = "Aime reader generation",
.section = "aime",
.key = "gen",
.desc = "This will also change the LED info provided for the game.",
.type = OptionType::Enum,
.default_value = "1",
.category = "Aime",
.elements = {
{ "1", "TN32MSEC003S H/W Ver3.0 / TN32MSEC003S F/W Ver1.2" },
{ "2", "837-15286 / 94" },
{ "3", "837-15396 / 94" },
},
},
{
.title = "AimeIO Path",
.section = "aimeio",
.key = "path",
.desc = "Path to a third-party card reader driver DLL.",
.type = OptionType::Text,
.default_value = "",
.max_string_length = MAX_PATH - 1,
.setting_name = "*.dll",
.category = "Aime",
},
{
.title = "Service address",
.section = "dns",
.key = "default",
.desc = "Controls address of all of the common network services servers, unless overriden by a specific setting below.",
.type = OptionType::Text,
.default_value = "localhost",
.max_string_length = 128,
.setting_name = "Enter address...",
.category = "Network",
},
{
.title = "Router address",
.section = "dns",
.key = "router",
.desc = "Overrides the target of the tenporouter.loc and bbrouter.loc hostname lookups.",
.type = OptionType::Text,
.default_value = "",
.max_string_length = 128,
.setting_name = "Enter hostname...",
.category = "Network",
},
{
.title = "ALL.Net address",
.section = "dns",
.key = "startup",
.desc = "Overrides the target of the naominet.jp host lookup.",
.type = OptionType::Text,
.default_value = "",
.max_string_length = 128,
.setting_name = "Enter hostname...",
.category = "Network",
},
{
.title = "Billing address",
.section = "dns",
.key = "billing",
.desc = "Overrides the target of the ib.naominet.jp host lookup.",
.type = OptionType::Text,
.default_value = "",
.max_string_length = 128,
.setting_name = "Enter hostname...",
.category = "Network",
},
{
.title = "AimeDB address",
.section = "dns",
.key = "aimedb",
.desc = "Overrides the target of the aime.naominet.jp host lookup.",
.type = OptionType::Text,
.default_value = "",
.max_string_length = 128,
.setting_name = "Enter hostname...",
.category = "Network",
},
{
.title = "Enable GFX hooks",
.section = "gfx",
.key = "enable",
.type = OptionType::Bool,
.default_value = "1",
.category = "Graphics",
},
{
.title = "Windowed mode",
.section = "gfx",
.key = "windowed",
.desc = "Force the game to run in windowed mode.",
.type = OptionType::Bool,
.default_value = "1",
.category = "Graphics",
},
{
.title = "Window frame",
.section = "gfx",
.key = "framed",
.desc = "Add a frame to the window if running in windowed mode.",
.type = OptionType::Bool,
.default_value = "0",
.category = "Graphics",
},
{
.title = "Monitor",
.section = "gfx",
.key = "monitor",
.desc = "Sets the monitor that the game will be opened in, if running in fullscreen mode.",
.type = OptionType::Integer,
.default_value = "0",
.category = "Graphics",
},
{
.title = "Network environment simulation",
.section = "netenv",
.key = "enable",
.desc = "You may need to disable this if you want to do any head-to-head play on your LAN.",
.type = OptionType::Bool,
.default_value = "1",
.category = "Network",
},
{
.title = "Local address suffix",
.section = "netenv",
.key = "addrSuffix",
.desc = "The final part of the local host's IP address on the virtualized subnet.",
.type = OptionType::Integer,
.default_value = "11",
.category = "Network",
},
{
.title = "Router address suffix",
.section = "netenv",
.key = "routerSuffix",
.desc = "The final part of the default gateway's IP address on the virtualized subnet.",
.type = OptionType::Integer,
.default_value = "1",
.category = "Network",
},
{
.title = "Adapter MAC address",
.section = "netenv",
.key = "macAddr",
.desc = "Shouldn't ever matter",
.type = OptionType::Text,
.default_value = "01:02:03:04:05:06",
.max_string_length = 17,
.category = "Network",
},
{
.title = "LAN Install mode",
.section = "gpio",
.key = "dipsw1",
.desc = "If multiple machines are present on the same LAN then set Server on exactly one machine.",
.type = OptionType::Enum,
.default_value = "1",
.max_string_length = 1,
.category = "Network",
.elements = { { "0", "Client" }, { "1", "Server" } },
},
{
.title = "Enable keychip emulation",
.section = "keychip",
.key = "enable",
.desc = "Disable to use a real keychip",
.type = OptionType::Bool,
.default_value = "1",
.category = "Keychip",
},
{
.title = "Keychip serial",
.section = "keychip",
.key = "id",
.type = OptionType::Text,
.default_value = "A69E-01A88888888",
.max_string_length = 16,
.category = "Keychip",
},
{
.title = "Game ID",
.section = "keychip",
.key = "gameId",
.desc = "Changing is usually not needed and will probably just cause a system error.",
.type = OptionType::Text,
.default_value = "",
.max_string_length = 4,
.category = "Keychip",
},
{
.title = "Platform ID",
.section = "keychip",
.key = "platformId",
.desc = "The default varies depending on game",
.type = OptionType::Text,
.default_value = "",
.max_string_length = 4,
.category = "Keychip",
},
{
.title = "Region",
.section = "keychip",
.key = "region",
.desc = "Most games seem to pay attention to the DS EEPROM region code and not the keychip region code.",
.type = OptionType::Enum,
.default_value = "1",
.category = "Keychip",
.elements = {
{ "1", "Japan" },
{ "2", "USA (unused)" },
{ "3", "Export" },
{ "4", "China" },
},
},
{
.title = "Subnet",
.section = "keychip",
.key = "subnet",
.desc = "The LAN IP range that the game will expect.",
.type = OptionType::Text,
.default_value = "192.168.100.0",
.max_string_length = 15,
.category = "Keychip",
},
{
.title = "Force JST timezone",
.section = "clock",
.key = "timezone",
.desc = "Make the system time zone appear to be JST. SEGA games malfunction in strange ways if the system time zone is not JST. There should not be any reason to disable this hook other than possible implementation bugs.",
.type = OptionType::Bool,
.default_value = "1",
.category = "Clock",
},
{
.title = "Time warp",
.section = "clock",
.key = "timewarp",
.desc = "Experimental time-of-day warping hook that skips over the hardcoded server maintenance period. Causes an incorrect in-game time-of-day to be reported. Better solutions for this problem exist and this feature will probably be removed soon.",
.type = OptionType::Bool,
.default_value = "0",
.category = "Clock",
},
{
.title = "Don't block clock updates",
.section = "clock",
.key = "writeable",
.desc = "Allow game to adjust system clock and time zone settings.",
.type = OptionType::Bool,
.default_value = "0",
.category = "Clock",
},
{
.title = "Enable VFD emulation",
.section = "vfd",
.key = "enable",
.desc = "Disable to use a real VFD GP1232A02A FUTABA assembly.",
.type = OptionType::Bool,
.default_value = "1",
.hw_family = games::HW_FAMILY_ALLS,
.category = "Other",
},
{
.title = "Free Play",
.section = "gpio",
.key = "freeplay",
.desc = "Disables the coin slot and sets the game to freeplay mode.",
.type = OptionType::Bool,
.default_value = "0",
.hw_family = games::HW_FAMILY_ALLS,
.category = "Other",
},
{
.title = "CHUNITHM: LED board firmware version",
.section = "led15093",
.key = "fwVer",
.type = OptionType::Integer,
.default_value = "144",
.game_name = "CHUNITHM",
.category = "Game Options (Advanced)",
},
{
.title = "CHUNITHM: LED board firmware checksum",
.section = "led15093",
.key = "fwSum",
.type = OptionType::Integer,
.default_value = "44535",
.game_name = "CHUNITHM",
.category = "Game Options (Advanced)",
},
{
.title = "CHUNITHM: LED board number",
.section = "led15093",
.key = "boardNumber",
.type = OptionType::Text,
.default_value = "15093-06",
.max_string_length = 15,
.game_name = "CHUNITHM",
.category = "Game Options (Advanced)",
},
{
.title = "CHUNITHM: LED chip number",
.section = "led15093",
.key = "chipNumber",
.type = OptionType::Text,
.default_value = "6710 ",
.max_string_length = 15,
.game_name = "CHUNITHM",
.category = "Game Options (Advanced)",
},
{
.title = "CHUNITHM: LED boot chip number",
.section = "led15093",
.key = "bootChipNumber",
.type = OptionType::Text,
.default_value = "6709 ",
.max_string_length = 15,
.game_name = "CHUNITHM",
.category = "Game Options (Advanced)",
},
{
.title = "CHUNITHM: Pipe billboard LED data",
.section = "led",
.key = "cabLedOutputPipe",
.desc = R"(Output billboard LED strip data to a named pipe called "\\.\pipe\chuni_led")",
.type = OptionType::Bool,
.default_value = "1",
.game_name = "CHUNITHM",
.category = "Game Options (Advanced)",
},
{
.title = "CHUNITHM: Serial billboard LED data",
.section = "led",
.key = "cabLedOutputSerial",
.desc = "Output billboard LED strip data to serial",
.type = OptionType::Bool,
.default_value = "0",
.game_name = "CHUNITHM",
.category = "Game Options (Advanced)",
},
{
.title = "CHUNITHM: Pipe slider LED data",
.section = "led",
.key = "controllerLedOutputPipe",
.desc = R"(Output slider LED data to a named pipe called "\\.\pipe\chuni_led")",
.type = OptionType::Bool,
.default_value = "1",
.game_name = "CHUNITHM",
.category = "Game Options (Advanced)",
},
{
.title = "CHUNITHM: Serial slider LED data",
.section = "led",
.key = "controllerLedOutputSerial",
.desc = "Output slider LED data to serial",
.type = OptionType::Bool,
.default_value = "0",
.game_name = "CHUNITHM",
.category = "Game Options (Advanced)",
},
{
.title = "CHUNITHM: Serial LED port",
.section = "led",
.key = "serialPort",
.desc = "Serial port to send data to if using serial output.",
.type = OptionType::Text,
.default_value = "COM5",
.max_string_length = 6, // up to 256 com ports
.game_name = "CHUNITHM",
.category = "Game Options (Advanced)",
},
{
.title = "CHUNITHM: Serial baud rate",
.section = "led",
.key = "serialBaud",
.type = OptionType::Integer,
.default_value = "921600",
.game_name = "CHUNITHM",
.category = "Game Options (Advanced)",
},
{
.title = "CHUNITHM NEW!!: LED board firmware version",
.section = "led15093",
.key = "fwVer",
.type = OptionType::Integer,
.default_value = "144",
.game_name = "CHUNITHM NEW!!",
.category = "Game Options (Advanced)",
},
{
.title = "CHUNITHM NEW!!: LED board firmware checksum",
.section = "led15093",
.key = "fwSum",
.type = OptionType::Integer,
.default_value = "44535",
.game_name = "CHUNITHM NEW!!",
.category = "Game Options (Advanced)",
},
{
.title = "CHUNITHM NEW!!: LED board number",
.section = "led15093",
.key = "boardNumber",
.type = OptionType::Text,
.default_value = "15093-06",
.max_string_length = 15,
.game_name = "CHUNITHM NEW!!",
.category = "Game Options (Advanced)",
},
{
.title = "CHUNITHM NEW!!: LED chip number",
.section = "led15093",
.key = "chipNumber",
.type = OptionType::Text,
.default_value = "6710 ",
.max_string_length = 15,
.game_name = "CHUNITHM NEW!!",
.category = "Game Options (Advanced)",
},
{
.title = "CHUNITHM NEW!!: LED boot chip number",
.section = "led15093",
.key = "bootChipNumber",
.type = OptionType::Text,
.default_value = "6709 ",
.max_string_length = 15,
.game_name = "CHUNITHM NEW!!",
.category = "Game Options (Advanced)",
},
{
.title = "CHUNITHM NEW!!: Pipe billboard LED data",
.section = "led",
.key = "cabLedOutputPipe",
.desc = R"(Output billboard LED strip data to a named pipe called "\\.\pipe\chuni_led")",
.type = OptionType::Bool,
.default_value = "1",
.game_name = "CHUNITHM NEW!!",
.category = "Game Options (Advanced)",
},
{
.title = "CHUNITHM NEW!!: Serial billboard LED data",
.section = "led",
.key = "cabLedOutputSerial",
.desc = "Output billboard LED strip data to serial",
.type = OptionType::Bool,
.default_value = "0",
.game_name = "CHUNITHM NEW!!",
.category = "Game Options (Advanced)",
},
{
.title = "CHUNITHM NEW!!: Pipe slider LED data",
.section = "led",
.key = "controllerLedOutputPipe",
.desc = R"(Output slider LED data to a named pipe called "\\.\pipe\chuni_led")",
.type = OptionType::Bool,
.default_value = "1",
.game_name = "CHUNITHM NEW!!",
.category = "Game Options (Advanced)",
},
{
.title = "CHUNITHM NEW!!: Serial slider LED data",
.section = "led",
.key = "controllerLedOutputSerial",
.desc = "Output slider LED data to serial",
.type = OptionType::Bool,
.default_value = "0",
.game_name = "CHUNITHM NEW!!",
.category = "Game Options (Advanced)",
},
{
.title = "CHUNITHM NEW!!: Serial LED port",
.section = "led",
.key = "serialPort",
.desc = "Serial port to send data to if using serial output.",
.type = OptionType::Text,
.default_value = "COM5",
.max_string_length = 6, // up to 256 com ports
.game_name = "CHUNITHM NEW!!",
.category = "Game Options (Advanced)",
},
{
.title = "CHUNITHM NEW!!: Serial baud rate",
.section = "led",
.key = "serialBaud",
.type = OptionType::Integer,
.default_value = "921600",
.game_name = "CHUNITHM NEW!!",
.category = "Game Options (Advanced)",
},
{
.title = "Enable AMVideo stub",
.section = "amvideo",
.key = "enable",
.desc = "Controls the amvideo.dll stub built into Segatools. This is a DLL that is normally present on the SEGA operating system image which is responsible for changing screen resolution and orientation.",
.type = OptionType::Bool,
.default_value = "1",
.category = "Graphics (Advanced)",
},
{
.title = "Billing type",
.section = "keychip",
.key = "billingType",
.type = OptionType::Enum,
.default_value = "1",
.category = "Keychip (Advanced)",
.elements = {
{ "1", "A" },
{ "2", "B1" },
{ "3", "B2" },
},
},
{
.title = "Billing certificate",
.section = "keychip",
.key = "billingCa",
.type = OptionType::Text,
.default_value = "DEVICE\\ca.crt",
.max_string_length = MAX_PATH - 1,
.category = "Keychip (Advanced)",
},
{
.title = "Billing public key",
.section = "keychip",
.key = "billingPub",
.type = OptionType::Text,
.default_value = "DEVICE\\billing.pub",
.max_string_length = MAX_PATH - 1,
.category = "Keychip (Advanced)",
},
{
.title = "System flag",
.section = "keychip",
.key = "systemFlag",
.type = OptionType::Integer,
.default_value = "100",
.category = "Keychip (Advanced)",
},
{
.title = "Emulate EEPROM",
.section = "eeprom",
.key = "enable",
.desc = "This chip stores status and configuration information on AMEX boards.",
.type = OptionType::Bool,
.default_value = "1",
.hw_family = games::HW_FAMILY_AMEX,
.category = "AMEX (Advanced)",
},
{
.title = "EEPROM path",
.section = "eeprom",
.key = "path",
.type = OptionType::Text,
.default_value = "DEVICE\\eeprom.bin",
.max_string_length = MAX_PATH - 1,
.hw_family = games::HW_FAMILY_AMEX,
.category = "AMEX (Advanced)",
},
{
.title = "Emulate SRAM",
.section = "sram",
.key = "enable",
.desc = "This stores bookkeeping state and settings on AMEX boards.",
.type = OptionType::Bool,
.default_value = "1",
.hw_family = games::HW_FAMILY_AMEX,
.category = "AMEX (Advanced)",
},
{
.title = "SRAM path",
.section = "sram",
.key = "path",
.type = OptionType::Text,
.default_value = "DEVICE\\sram.bin",
.max_string_length = MAX_PATH - 1,
.hw_family = games::HW_FAMILY_AMEX,
.category = "AMEX (Advanced)",
},
{
.title = "Enable DS EEPROM emulation",
.section = "ds",
.key = "enable",
.desc = "Disable to use the DS EEPROM chip on a real AMEX.",
.type = OptionType::Bool,
.default_value = "1",
.hw_family = games::HW_FAMILY_AMEX,
.category = "AMEX (Advanced)",
},
{
.title = "AMEX board region code",
.section = "ds",
.key = "region",
.type = OptionType::Enum,
.default_value = "1",
.hw_family = games::HW_FAMILY_AMEX,
.category = "AMEX (Advanced)",
.elements = { { "1", "Japan" }, { "2", "USA (unused)" }, { "4", "Export" }, { "8", "China" } },
},
{
.title = "\"MAIN ID\" serial number",
.section = "ds",
.key = "serialNo",
.type = OptionType::Text,
.default_value = "AAVE-01A99999999",
.max_string_length = 16,
.hw_family = games::HW_FAMILY_AMEX,
.category = "AMEX (Advanced)",
},
{
.title = "Enable IO4 emulation",
.section = "io4",
.key = "enable",
.desc = "CHUNITHM NEW!! uses IO3 instead for backwards compatibility, even if its board is IO4.",
.type = OptionType::Bool,
.default_value = "1",
.hw_family = games::HW_FAMILY_ALLS,
.category = "ALLS (Advanced)",
},
{
.title = "Enable hostname virtualization",
.section = "pcbid",
.key = "enable",
.desc = "Needed for ALLS games, since they store the PCB serial in the Windows machine name.",
.type = OptionType::Bool,
.default_value = "1",
.hw_family = games::HW_FAMILY_ALLS,
.category = "ALLS (Advanced)"
},
{
.title = "Hostname",
.section = "pcbid",
.key = "serialNo",
.desc = "Should be an ALLS MAIN ID without hyphens",
.type = OptionType::Text,
.default_value = "ACAE01A99999999",
.max_string_length = 15,
.hw_family = games::HW_FAMILY_ALLS,
.category = "ALLS (Advanced)",
},
{
.title = "Enable HWMON emulation",
.section = "hwmon",
.key = "enable",
.type = OptionType::Bool,
.default_value = "1",
.category = "System (Advanced)",
},
{
.title = "Enable JVS emulation",
.section = "jvs",
.key = "enable",
.type = OptionType::Bool,
.default_value = "1",
.category = "System (Advanced)",
},
{
.title = "Enable IO3 emulation",
.section = "io3",
.key = "enable",
.desc = "Used by AMEX (SEGA Nu) games and CHUNITHM NEW.",
.type = OptionType::Bool,
.default_value = "1",
.category = "System (Advanced)",
},
{
.title = "Enable GPIO emulation",
.section = "gpio",
.key = "enable",
.desc = "Needed to emulate DIP switches for some games.",
.type = OptionType::Bool,
.default_value = "1",
.category = "System (Advanced)",
},
};
const std::vector<OptionDefinition> &get_option_definitions() {
return OPTION_DEFINITIONS;
}
std::unique_ptr<std::vector<Option>> parse_options() {
std::vector<OptionDefinition> definitions = get_option_definitions();
auto options = std::make_unique<std::vector<Option>>();
options->reserve(definitions.size());
for (OptionDefinition definition : definitions) {
std::string value = "";
switch (definition.type) {
case OptionType::Bool: {
int val = GetPrivateProfileIntA(
definition.section.c_str(),
definition.key.c_str(),
definition.default_value == "1",
".\\segatools.ini"
);
value = val == 1 ? "1" : "0";
break;
}
case OptionType::Enum:
case OptionType::Text: {
value.resize(definition.max_string_length + 1, 0);
int cnt = GetPrivateProfileStringA(
definition.section.c_str(),
definition.key.c_str(),
definition.default_value.c_str(),
value.data(),
definition.max_string_length + 1,
".\\segatools.ini"
);
value.resize(cnt);
break;
}
case OptionType::Integer: {
char *p;
strtol(definition.default_value.c_str(), &p, 10);
if (*p) {
throw std::runtime_error("Invalid default value");
}
value.resize(512, 0);
int cnt = GetPrivateProfileStringA(
definition.section.c_str(),
definition.key.c_str(),
definition.default_value.c_str(),
value.data(),
512,
".\\segatools.ini"
);
value.resize(cnt);
break;
}
}
options->emplace_back(definition, value);
}
return options;
}
void Option::value_set(std::string new_value) {
this->value = std::move(new_value);
}
bool Option::value_bool() const {
if (this->definition.type != OptionType::Bool) {
throw std::invalid_argument("value_bool() called on non-bool option");
}
return this->value == "1";
}
const std::string &Option::value_text() const {
if (this->definition.type != OptionType::Text && this->definition.type != OptionType::Enum) {
throw std::invalid_argument("value_text() called on non-text option");
}
return this->value;
}
int Option::value_int() const {
if (this->definition.type != OptionType::Integer && this->definition.type != OptionType::Enum) {
throw std::invalid_argument("value_int() called on non-integer option");
}
char *p;
int res = strtol(this->value.c_str(), &p, 10);
if (*p) {
throw std::invalid_argument("tried to convert invalid value to integer");
}
return res;
}
void Option::update_config() const {
WritePrivateProfileStringA(
definition.section.c_str(),
definition.key.c_str(),
this->value.c_str(),
".\\segatools.ini"
);
}