From f6b63473a033bcf1571a661e529931b3fe5e1b64 Mon Sep 17 00:00:00 2001 From: bicarus-dev <202771338+bicarus-dev@users.noreply.github.com> Date: Sat, 9 Aug 2025 20:53:09 -0700 Subject: [PATCH] ddr: automatically register codecs on launch (#351) ## Link to GitHub Issue, if one exists #345 ## Description of change On launch of spice.exe / spice64.exe, call `regsvr32` on known codecs in the `com` directory. Add an option to skip this (`-ddrnocodec`) as a chicken bit. ## Testing Tested 32 and 64 bit DDR. --- src/spice2x/games/ddr/ddr.cpp | 49 +++++++++++++++++++++++++++++++ src/spice2x/games/ddr/ddr.h | 4 +++ src/spice2x/launcher/launcher.cpp | 3 ++ src/spice2x/launcher/options.cpp | 9 ++++++ src/spice2x/launcher/options.h | 1 + 5 files changed, 66 insertions(+) diff --git a/src/spice2x/games/ddr/ddr.cpp b/src/spice2x/games/ddr/ddr.cpp index cc32fe0..efb1a6c 100644 --- a/src/spice2x/games/ddr/ddr.cpp +++ b/src/spice2x/games/ddr/ddr.cpp @@ -27,6 +27,7 @@ namespace games::ddr { // settings bool SDMODE = false; + bool NO_CODEC_REGISTRATION = false; uint8_t DDR_TAPELEDS[TAPELED_DEVICE_COUNT][50][3] {}; @@ -52,6 +53,50 @@ namespace games::ddr { DDRGame::DDRGame() : Game("Dance Dance Revolution") { } + void DDRGame::register_codecs() { + // find where spice.exe / spice64.exe is located + const auto &spice_bin_path = libutils::module_file_name(nullptr).parent_path(); + + // find the com directory + std::filesystem::path dir = ""; + if (MODULE_PATH == spice_bin_path) { + // try: \com + dir = spice_bin_path / "com"; + } else { + // try: modules\..\com + dir = MODULE_PATH / ".." / "com"; + } + + if (fileutils::dir_exists(dir)) { + log_info("ddr", "looking for codecs in this directory: {}", dir.string()); + } else { + log_info("ddr", "codecs directory not found: {}", dir.string()); + return; + } + + for (const auto &file : std::filesystem::directory_iterator(dir)) { + const auto &filename = file.path().filename(); + const auto extension = strtolower(filename.extension().string()); + + if (extension != ".dll") { + continue; + } + + log_info("ddr", "found DLL: {}", filename.string()); + if (filename == "k-clvsd.dll" || filename.string().find("xactengine") == 0) { + const std::string cmd = "regsvr32.exe /s " + file.path().string(); + + int result = 0; + std::thread t([cmd, &result]() { + result = system(cmd.c_str()); + }); + t.join(); + log_info("ddr", "`{}` returned {}", cmd, result); + } + } + } + + void DDRGame::pre_attach() { if (!cfg::CONFIGURATOR_STANDALONE && avs::game::is_model("TDX")) { log_fatal( @@ -87,6 +132,10 @@ namespace games::ddr { "!!! !!!\n\n\n" ); } + + if (!cfg::CONFIGURATOR_STANDALONE && !NO_CODEC_REGISTRATION) { + this->register_codecs(); + } } void DDRGame::attach() { diff --git a/src/spice2x/games/ddr/ddr.h b/src/spice2x/games/ddr/ddr.h index 0bb9320..7e685f4 100644 --- a/src/spice2x/games/ddr/ddr.h +++ b/src/spice2x/games/ddr/ddr.h @@ -7,6 +7,7 @@ namespace games::ddr { // settings extern bool SDMODE; + extern bool NO_CODEC_REGISTRATION; // Buffers to store RGB data for tape LEDs on gold cabinets const size_t TAPELED_DEVICE_COUNT = 11; @@ -18,5 +19,8 @@ namespace games::ddr { virtual void pre_attach() override; virtual void attach() override; virtual void detach() override; + + private: + void register_codecs(); }; } diff --git a/src/spice2x/launcher/launcher.cpp b/src/spice2x/launcher/launcher.cpp index ebedc9c..233755c 100644 --- a/src/spice2x/launcher/launcher.cpp +++ b/src/spice2x/launcher/launcher.cpp @@ -629,6 +629,9 @@ int main_implementation(int argc, char *argv[]) { if (options[launcher::Options::DDR43Mode].value_bool()) { games::ddr::SDMODE = true; } + if (options[launcher::Options::DDRSkipCodecRegisteration].value_bool()) { + games::ddr::NO_CODEC_REGISTRATION = true; + } if (options[launcher::Options::LoadSteelChronicleModule].value_bool()) { attach_sc = true; } diff --git a/src/spice2x/launcher/options.cpp b/src/spice2x/launcher/options.cpp index 8a6f9ad..82b74e3 100644 --- a/src/spice2x/launcher/options.cpp +++ b/src/spice2x/launcher/options.cpp @@ -809,6 +809,15 @@ static const std::vector OPTION_DEFINITIONS = { .game_name = "Dance Dance Revolution", .category = "Game Options", }, + { + // DDRSkipCodecRegisteration + .title = "DDR Skip Codec Registration", + .name = "ddrnocodec", + .desc = "Prevent automatic registration of codecs in the com folder", + .type = OptionType::Bool, + .game_name = "Dance Dance Revolution", + .category = "Game Options (Advanced)", + }, { .title = "Force Load Pop'n Music Module", .name = "pnm", diff --git a/src/spice2x/launcher/options.h b/src/spice2x/launcher/options.h index 41173de..b5252ea 100644 --- a/src/spice2x/launcher/options.h +++ b/src/spice2x/launcher/options.h @@ -86,6 +86,7 @@ namespace launcher { spice2x_SDVXSubRedraw, LoadDDRModule, DDR43Mode, + DDRSkipCodecRegisteration, LoadPopnMusicModule, PopnMusicForceHDMode, PopnMusicForceSDMode,