#include "sdvx_live2d.h" // only the Live2D-capable SDVX versions are 64-bit, so the whole feature is // compiled out of 32-bit builds. #ifdef SPICE64 #include #include "hooks/graphics/graphics.h" #include "launcher/logger.h" #include "util/logging.h" namespace games::sdvx { // Live2D in-game scene detection (for the -sdvxnolive2d "ingame" option). // // the game logs scene transitions as "I:Attach: in " / "I:Detach: in // ". several scenes correspond to in-song gameplay (with the heavy // Live2D rendering); we watch those log lines and keep the shared flag // the d3d9 backend reads up to date. the hook never alters the log output // (always returns false). static bool live2d_scene_log_hook( void *user, const std::string &data, logger::Style style, std::string &out) { // any of these scenes counts as in-song gameplay (different play modes) static const char *const gameplay_scenes[] = { "in ALTERNATIVE_GAME_SCENE", "in MEGAMIX_GAME_SCENE", "in MEGAMIX_BATTLE", "in BATTLE_GAME_SCENE", "in AUTOMATION_GAME_SCENE", "in ARENA_GAME_SCENE", }; bool in_gameplay_scene = false; for (const auto *scene : gameplay_scenes) { if (data.find(scene) != std::string::npos) { in_gameplay_scene = true; break; } } if (!in_gameplay_scene) { return false; } // note: log messages here must NOT contain any matched scene token, else // this hook would re-enter itself when the message is pushed. if (data.find("I:Attach: in ") != std::string::npos) { if (!GRAPHICS_SDVX_LIVE2D_IN_GAMEPLAY.exchange(true, std::memory_order_relaxed)) { log_info("sdvx", "Live2D skip: entering gameplay"); } } else if (data.find("I:Detach: in ") != std::string::npos) { if (GRAPHICS_SDVX_LIVE2D_IN_GAMEPLAY.exchange(false, std::memory_order_relaxed)) { log_info("sdvx", "Live2D skip: leaving gameplay"); } } return false; } void live2d_scene_detection_init() { static bool installed = false; if (installed) { return; } installed = true; // the logger's hook list is a persistent static, so registering here is // safe even though this runs before logger::start(). we intentionally do // NOT log a confirmation now: at this point the log file isn't open yet // and the message would be dropped. the entering/leaving-gameplay lines // above provide runtime confirmation once the logger is running. logger::hook_add(live2d_scene_log_hook, nullptr); } } #endif // SPICE64