Compare commits

..

5 Commits

Author SHA1 Message Date
sp2xdev c96f4330d2 Merge branch 'main' of https://github.com/spice2x/spice2x.github.io 2025-08-21 08:29:33 -07:00
sp2xdev 26a2a0f481 update changelog 2025-08-21 08:29:27 -07:00
bicarus-dev 11b9790e6c cfg: rearrange options (#357)
## Link to GitHub Issue, if one exists
n/a

## Description of change
In an attempt to make the Options tab smaller, move out more options to
advanced / development tabs.

## Testing
n/a
2025-08-19 02:41:56 -07:00
bicarus-dev 1dfcf8c087 ddr: check for common DLL errors (#355)
## Link to GitHub Issue, if one exists
#345 

## Description of change
Check if the path to codecs directory contains non-ASCII characters, and
display a giant warning. This is to help with troubleshooting, since
registration of xactengine silently fails (creates a bad registry entry)
if the path contains non-ASCII chars.

Log the size of codec DLLs, and log any failures from `regsvr32`.

Detect the case where user specified `-exec gamemdx.dll` for DDR which
seems to be a common pitfall. This doesn't work because gamemdx.dll does
not have a DLL entry, but for some reason people are really tempted to
do this.

## Testing
Validated the error cases.
2025-08-18 00:00:38 -07:00
bicarus-dev 5c7ad0d51e ea3: supply default pcbid if not present (#356)
## Link to GitHub Issue, if one exists
#345 

## Description of change
If ea3 xml is missing pcbid node, AND there is no pcbid override, supply
a default value. Useful for quickly getting offline clients up &
running.

## Testing
Tested with/without pcbid override, with/without pcbid node in xml.
2025-08-17 23:52:15 -07:00
5 changed files with 93 additions and 32 deletions
+7 -1
View File
@@ -356,6 +356,12 @@ namespace avs {
} }
} }
// fall back to default PCBID if node is not found
if (!EA3_PCBID[0] && PCBID_CUSTOM.empty()) {
log_warning("avs-ea3", "no PCBID set, falling back to default PCBID value (04040000000000000000)");
PCBID_CUSTOM = "04040000000000000000";
}
// custom PCBID // custom PCBID
if (!PCBID_CUSTOM.empty()) { if (!PCBID_CUSTOM.empty()) {
@@ -399,7 +405,7 @@ namespace avs {
avs::core::NODE_TYPE_str, "/ea3/id/accountid", &EA3_ACCOUNTID); avs::core::NODE_TYPE_str, "/ea3/id/accountid", &EA3_ACCOUNTID);
} }
// check if PCBID is defined // check if PCBID is defined - should never hit, left for sanity check only
if (avs::core::property_search(ea3_config, nullptr, "/ea3/id/pcbid") == nullptr) { if (avs::core::property_search(ea3_config, nullptr, "/ea3/id/pcbid") == nullptr) {
log_fatal("avs-ea3", "node not found: /ea3/id/pcbid (try using -p to specify PCBID)"); log_fatal("avs-ea3", "node not found: /ea3/id/pcbid (try using -p to specify PCBID)");
} else if (strlen(EA3_PCBID) == 0) { } else if (strlen(EA3_PCBID) == 0) {
+18 -2
View File
@@ -80,7 +80,7 @@ namespace avs {
if (130 <= dll_path_s.length()) { if (130 <= dll_path_s.length()) {
log_warning( log_warning(
"avs-game", "avs-game",
"PATH TOO LONG WARNING\n\n\n" "PATH TOO LONG WARNING\n\n"
"-------------------------------------------------------------------\n" "-------------------------------------------------------------------\n"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
"WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING\n" "WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING\n"
@@ -95,10 +95,26 @@ namespace avs {
"-------------------------------------------------------------------\n\n", "-------------------------------------------------------------------\n\n",
dll_path_s, dll_path_s.length()); dll_path_s, dll_path_s.length());
} }
// ddr gamemdx.dll user error
if (avs::game::is_model("MDX") && DLL_NAME == "gamemdx.dll") {
log_fatal(
"ddr",
"BAD GAME DLL ERROR\n\n"
"!!! !!!\n"
"!!! -exec gamemdx.dll was specified !!!\n"
"!!! this is the wrong DLL; the game will not load !!!\n"
"!!! remove -exec argument and try again. !!!\n"
"!!! !!!\n"
);
}
// file not found on disk
if (!fileutils::file_exists(dll_path)) { if (!fileutils::file_exists(dll_path)) {
log_warning("avs-game", "game DLL could not be found on disk: {}", dll_path.string().c_str()); log_warning("avs-game", "game DLL could not be found on disk: {}", dll_path.string().c_str());
log_warning("avs-game", "double check -exec and -modules parameters; unless you know what you're doing, leave them blank"); log_warning("avs-game", "double check -exec and -modules parameters; unless you know what you're doing, leave them blank");
} }
if (fileutils::verify_header_pe(dll_path)) { if (fileutils::verify_header_pe(dll_path)) {
DLL_INSTANCE = libutils::load_library(dll_path); DLL_INSTANCE = libutils::load_library(dll_path);
} }
@@ -106,7 +122,7 @@ namespace avs {
// load entry points // load entry points
dll_entry_init = (ENTRY_INIT_T) libutils::get_proc(DLL_INSTANCE, ENTRY_INIT_NAME); dll_entry_init = (ENTRY_INIT_T) libutils::get_proc(DLL_INSTANCE, ENTRY_INIT_NAME);
dll_entry_main = (ENTRY_MAIN_T) libutils::get_proc(DLL_INSTANCE, ENTRY_MAIN_NAME); dll_entry_main = (ENTRY_MAIN_T) libutils::get_proc(DLL_INSTANCE, ENTRY_MAIN_NAME);
log_info("avs-game", "loaded successfully ({})", fmt::ptr(DLL_INSTANCE)); log_info("avs-game", "loaded {} successfully ({})", DLL_NAME, fmt::ptr(DLL_INSTANCE));
} }
bool entry_init(char *sid_code, void *app_param) { bool entry_init(char *sid_code, void *app_param) {
+5
View File
@@ -1,3 +1,8 @@
08/21/2025 [spice2x]
DDR: check for common DLL errors
Supply default PCBID if absent
Rearrange options
08/17/2025 [spice2x] 08/17/2025 [spice2x]
DDR: fix codec registration failure when path contains spaces DDR: fix codec registration failure when path contains spaces
+36 -4
View File
@@ -50,6 +50,15 @@ namespace games::ddr {
return SendMessage_real(hWnd, Msg, wParam, lParam); return SendMessage_real(hWnd, Msg, wParam, lParam);
} }
bool contains_only_ascii(const std::string& str) {
for (auto c: str) {
if (static_cast<unsigned char>(c) > 127) {
return false;
}
}
return true;
}
DDRGame::DDRGame() : Game("Dance Dance Revolution") { DDRGame::DDRGame() : Game("Dance Dance Revolution") {
} }
@@ -82,7 +91,7 @@ namespace games::ddr {
continue; continue;
} }
log_info("ddr", "found DLL: {}", filename.string()); log_info("ddr", "found DLL: {}, size: {} bytes", filename.string(), file.file_size());
if (filename == "k-clvsd.dll" || filename.string().find("xactengine") == 0) { if (filename == "k-clvsd.dll" || filename.string().find("xactengine") == 0) {
const std::wstring wcmd = L"regsvr32.exe /s \"" + file.path().wstring() + L"\""; const std::wstring wcmd = L"regsvr32.exe /s \"" + file.path().wstring() + L"\"";
const std::string cmd = "regsvr32.exe /s \"" + file.path().string() + "\""; const std::string cmd = "regsvr32.exe /s \"" + file.path().string() + "\"";
@@ -92,7 +101,23 @@ namespace games::ddr {
result = _wsystem(wcmd.c_str()); result = _wsystem(wcmd.c_str());
}); });
t.join(); t.join();
log_info("ddr", "`{}` returned {}", cmd, result);
if (result == 0) {
log_info("ddr", "`{}` returned {}", cmd, result);
} else {
log_warning("ddr", "`{}` failed, returned {}", cmd, result);
}
if (!contains_only_ascii(file.path().string())) {
log_warning(
"ddr",
"BAD PATH ERROR\n\n\n"
"!!! !!!\n"
"!!! filesystem path to codec contains non-ASCII characters! !!!\n"
"!!! this may cause the game to crash! !!!\n"
"!!! !!!\n"
);
}
} }
} }
} }
@@ -134,8 +159,15 @@ namespace games::ddr {
); );
} }
if (!cfg::CONFIGURATOR_STANDALONE && !NO_CODEC_REGISTRATION) { if (!cfg::CONFIGURATOR_STANDALONE) {
this->register_codecs(); if (!NO_CODEC_REGISTRATION) {
this->register_codecs();
} else {
log_warning(
"ddr",
"skipping codec registration (-ddrnocodec), "
"game may crash if you didn't register codecs before launching the game");
}
} }
} }
+27 -25
View File
@@ -17,7 +17,6 @@ static const std::vector<std::string> CATEGORY_ORDER_BASIC = {
"Game Options", "Game Options",
"Common", "Common",
"Network", "Network",
"Overlay",
"Graphics (Common)", "Graphics (Common)",
"Graphics (Full Screen)", "Graphics (Full Screen)",
"Graphics (Windowed)", "Graphics (Windowed)",
@@ -26,18 +25,21 @@ static const std::vector<std::string> CATEGORY_ORDER_BASIC = {
static const std::vector<std::string> CATEGORY_ORDER_ADVANCED = { static const std::vector<std::string> CATEGORY_ORDER_ADVANCED = {
"Game Options (Advanced)", "Game Options (Advanced)",
"Overlay",
"Network (Advanced)", "Network (Advanced)",
"Performance", "Performance",
"Miscellaneous", "Miscellaneous",
"Paths",
"Touch Parameters", "Touch Parameters",
"I/O Options", "I/O Options",
"NFC Card Readers", "NFC Card Readers",
}; };
static const std::vector<std::string> CATEGORY_ORDER_DEV = { static const std::vector<std::string> CATEGORY_ORDER_DEV = {
"Network Adapters", "Paths",
"Network (Development)",
"Audio (Hacks)",
"I/O Modules", "I/O Modules",
"Development", "Development",
"Debug Log",
}; };
static const std::vector<std::string> CATEGORY_ORDER_NONE = { static const std::vector<std::string> CATEGORY_ORDER_NONE = {
"" ""
@@ -268,7 +270,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
.name = "nolegacy", .name = "nolegacy",
.desc = "Disables legacy key activation in-game.", .desc = "Disables legacy key activation in-game.",
.type = OptionType::Bool, .type = OptionType::Bool,
.category = "Miscellaneous", .category = "I/O Options",
}, },
{ {
.title = "Discord Rich Presence", .title = "Discord Rich Presence",
@@ -310,7 +312,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
.desc = "This is NOT the EA service URL; use -url for that. " .desc = "This is NOT the EA service URL; use -url for that. "
"Force the use of an adapter with the specified network. Must also provide -subnet", "Force the use of an adapter with the specified network. Must also provide -subnet",
.type = OptionType::Text, .type = OptionType::Text,
.category = "Network Adapters", .category = "Network (Development)",
.sensitive = true, .sensitive = true,
}, },
{ {
@@ -318,21 +320,21 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
.name = "subnet", .name = "subnet",
.desc = "Force the use of an adapter with the specified subnet. Must also provide -network", .desc = "Force the use of an adapter with the specified subnet. Must also provide -network",
.type = OptionType::Text, .type = OptionType::Text,
.category = "Network Adapters", .category = "Network (Development)",
}, },
{ {
.title = "Disable Network Fixes", .title = "Disable Network Fixes",
.name = "netfixdisable", .name = "netfixdisable",
.desc = "Force disables network fixes", .desc = "Force disables network fixes",
.type = OptionType::Bool, .type = OptionType::Bool,
.category = "Network Adapters", .category = "Network (Development)",
}, },
{ {
.title = "HTTP/1.1", .title = "HTTP/1.1",
.name = "http11", .name = "http11",
.desc = "Sets EA3 http11 value", .desc = "Sets EA3 http11 value",
.type = OptionType::Enum, .type = OptionType::Enum,
.category = "Network (Advanced)", .category = "Network (Development)",
.elements = {{"0", "Off"}, {"1", "On"}}, .elements = {{"0", "Off"}, {"1", "On"}},
}, },
{ {
@@ -340,7 +342,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
.name = "ssldisable", .name = "ssldisable",
.desc = "Prevents the SSL protocol from being registered", .desc = "Prevents the SSL protocol from being registered",
.type = OptionType::Bool, .type = OptionType::Bool,
.category = "Network (Advanced)", .category = "Network (Development)",
}, },
{ {
.title = "URL Slash", .title = "URL Slash",
@@ -355,7 +357,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
.name = "r", .name = "r",
.desc = "Set custom SOFTID override", .desc = "Set custom SOFTID override",
.type = OptionType::Text, .type = OptionType::Text,
.category = "Network (Advanced)", .category = "Network (Development)",
.sensitive = true, .sensitive = true,
}, },
{ {
@@ -1412,7 +1414,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
.name = "sextet", .name = "sextet",
.desc = "Use a SextetStream device on a given COM port", .desc = "Use a SextetStream device on a given COM port",
.type = OptionType::Text, .type = OptionType::Text,
.category = "Miscellaneous", .category = "I/O Options",
}, },
{ {
.title = "Enable BemaniTools 5 API", .title = "Enable BemaniTools 5 API",
@@ -1513,7 +1515,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
"you use a different backend instead of exclusive WASAPI).\n\n" "you use a different backend instead of exclusive WASAPI).\n\n"
"Check this if you want games to natively access your audio device", "Check this if you want games to natively access your audio device",
.type = OptionType::Bool, .type = OptionType::Bool,
.category = "Audio", .category = "Audio (Hacks)",
}, },
{ {
// spice2x_DisableVolumeHook // spice2x_DisableVolumeHook
@@ -1525,7 +1527,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
"Default: off (prevent games from changing audio volume by hooking IAudioEndpointVolume).\n\n" "Default: off (prevent games from changing audio volume by hooking IAudioEndpointVolume).\n\n"
"Check this if you want games to freely change your volume", "Check this if you want games to freely change your volume",
.type = OptionType::Bool, .type = OptionType::Bool,
.category = "Audio", .category = "Audio (Hacks)",
}, },
{ {
.title = "Spice Audio Hook Backend", .title = "Spice Audio Hook Backend",
@@ -1550,7 +1552,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
"This is automatically enabled when required and not normally needed", "This is automatically enabled when required and not normally needed",
.type = OptionType::Bool, .type = OptionType::Bool,
.hidden = true, .hidden = true,
.category = "Audio", .category = "Audio (Hacks)",
}, },
{ {
// DelayBy5Seconds // DelayBy5Seconds
@@ -1607,7 +1609,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
.name = "loglevel", .name = "loglevel",
.desc = "Set the level of detail for AVS log messages written to the log. Does not affect logging from spice", .desc = "Set the level of detail for AVS log messages written to the log. Does not affect logging from spice",
.type = OptionType::Enum, .type = OptionType::Enum,
.category = "Performance", .category = "Debug Log",
.elements = {{"fatal", ""}, {"warning", ""}, {"info", ""}, {"misc", ""}, {"all", ""}, {"disable", ""}}, .elements = {{"fatal", ""}, {"warning", ""}, {"info", ""}, {"misc", ""}, {"all", ""}, {"disable", ""}},
}, },
{ {
@@ -1615,14 +1617,14 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
.name = "automap", .name = "automap",
.desc = "Enable automap in patch configuration", .desc = "Enable automap in patch configuration",
.type = OptionType::Bool, .type = OptionType::Bool,
.category = "Development", .category = "Network (Development)",
}, },
{ {
.title = "EA Netdump", .title = "EA Netdump",
.name = "netdump", .name = "netdump",
.desc = "Enable automap in network dumping configuration", .desc = "Enable automap in network dumping configuration",
.type = OptionType::Bool, .type = OptionType::Bool,
.category = "Development", .category = "Network (Development)",
}, },
{ {
.title = "Discord RPC AppID Override", .title = "Discord RPC AppID Override",
@@ -1636,35 +1638,35 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
.name = "logblock", .name = "logblock",
.desc = "Slower but safer logging used for debugging", .desc = "Slower but safer logging used for debugging",
.type = OptionType::Bool, .type = OptionType::Bool,
.category = "Development", .category = "Debug Log",
}, },
{ {
.title = "Debug CreateFile", .title = "Debug CreateFile",
.name = "createfiledebug", .name = "createfiledebug",
.desc = "Outputs CreateFile debug prints", .desc = "Outputs CreateFile debug prints",
.type = OptionType::Bool, .type = OptionType::Bool,
.category = "Development", .category = "Debug Log",
}, },
{ {
.title = "Verbose Graphics Logging", .title = "Verbose Graphics Logging",
.name = "graphicsverbose", .name = "graphicsverbose",
.desc = "Enable the verbose logging of graphics hook code", .desc = "Enable the verbose logging of graphics hook code",
.type = OptionType::Bool, .type = OptionType::Bool,
.category = "Development", .category = "Debug Log",
}, },
{ {
.title = "Verbose AVS Logging", .title = "Verbose AVS Logging",
.name = "avsverbose", .name = "avsverbose",
.desc = "Enable the verbose logging of AVS filesystem functions", .desc = "Enable the verbose logging of AVS filesystem functions",
.type = OptionType::Bool, .type = OptionType::Bool,
.category = "Development", .category = "Debug Log",
}, },
{ {
.title = "Disable Colored Output", .title = "Disable Colored Output",
.name = "nocolor", .name = "nocolor",
.desc = "Disable terminal colors for log outputs to console", .desc = "Disable terminal colors for log outputs to console",
.type = OptionType::Bool, .type = OptionType::Bool,
.category = "Development", .category = "Debug Log",
}, },
{ {
.title = "Disable ACP Hook", .title = "Disable ACP Hook",
@@ -1699,7 +1701,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
.name = "pebprint", .name = "pebprint",
.desc = "Prints PEB on startup to console", .desc = "Prints PEB on startup to console",
.type = OptionType::Bool, .type = OptionType::Bool,
.category = "Development", .category = "Debug Log",
}, },
{ {
// DumpSystemInfo // DumpSystemInfo
@@ -1707,7 +1709,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
.name = "sysdump", .name = "sysdump",
.desc = "Print system information to the log on startup. Default: basic", .desc = "Print system information to the log on startup. Default: basic",
.type = OptionType::Enum, .type = OptionType::Enum,
.category = "Development", .category = "Debug Log",
.elements = { .elements = {
{"none", "Nothing"}, {"none", "Nothing"},
{"basic", "OS, CPU, SMBIOS, GPU"}, {"basic", "OS, CPU, SMBIOS, GPU"},
@@ -1937,7 +1939,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
.desc = "For certain buggy ASIO drivers, force unload of ASIO driver when audio stream stops. " .desc = "For certain buggy ASIO drivers, force unload of ASIO driver when audio stream stops. "
"Used for working around ASIO drivers that lock up after force quitting games", "Used for working around ASIO drivers that lock up after force quitting games",
.type = OptionType::Bool, .type = OptionType::Bool,
.category = "Audio", .category = "Audio (Hacks)",
}, },
{ {
// spice2x_IIDXNoESpec // spice2x_IIDXNoESpec