From 1dfcf8c0874ebb55e9cc3778875fd2b18d14c4d5 Mon Sep 17 00:00:00 2001 From: bicarus-dev <202771338+bicarus-dev@users.noreply.github.com> Date: Mon, 18 Aug 2025 00:00:38 -0700 Subject: [PATCH] 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. --- src/spice2x/avs/game.cpp | 20 ++++++++++++++++-- src/spice2x/games/ddr/ddr.cpp | 40 +++++++++++++++++++++++++++++++---- 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/src/spice2x/avs/game.cpp b/src/spice2x/avs/game.cpp index ca5c1a2..adefa8f 100644 --- a/src/spice2x/avs/game.cpp +++ b/src/spice2x/avs/game.cpp @@ -80,7 +80,7 @@ namespace avs { if (130 <= dll_path_s.length()) { log_warning( "avs-game", - "PATH TOO LONG WARNING\n\n\n" + "PATH TOO LONG WARNING\n\n" "-------------------------------------------------------------------\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" "WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING\n" @@ -95,10 +95,26 @@ namespace avs { "-------------------------------------------------------------------\n\n", 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)) { 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"); } + if (fileutils::verify_header_pe(dll_path)) { DLL_INSTANCE = libutils::load_library(dll_path); } @@ -106,7 +122,7 @@ namespace avs { // load entry points 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); - 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) { diff --git a/src/spice2x/games/ddr/ddr.cpp b/src/spice2x/games/ddr/ddr.cpp index 2d5f17c..6018c71 100644 --- a/src/spice2x/games/ddr/ddr.cpp +++ b/src/spice2x/games/ddr/ddr.cpp @@ -50,6 +50,15 @@ namespace games::ddr { return SendMessage_real(hWnd, Msg, wParam, lParam); } + bool contains_only_ascii(const std::string& str) { + for (auto c: str) { + if (static_cast(c) > 127) { + return false; + } + } + return true; + } + DDRGame::DDRGame() : Game("Dance Dance Revolution") { } @@ -82,7 +91,7 @@ namespace games::ddr { 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) { const std::wstring wcmd = L"regsvr32.exe /s \"" + file.path().wstring() + L"\""; const std::string cmd = "regsvr32.exe /s \"" + file.path().string() + "\""; @@ -92,7 +101,23 @@ namespace games::ddr { result = _wsystem(wcmd.c_str()); }); 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) { - this->register_codecs(); + if (!cfg::CONFIGURATOR_STANDALONE) { + 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"); + } } }