Update to spice2x-25-04-25 (pre-apply)

> broken commit
This commit is contained in:
[ ]
2025-05-07 00:25:31 +09:00
parent 04dee88276
commit c94de456b5
543 changed files with 78491 additions and 91698 deletions
+82 -19
View File
@@ -8,8 +8,10 @@
#include "hooks/graphics/graphics.h"
#include "hooks/devicehook.h"
#include "hooks/libraryhook.h"
#include "hooks/graphics/nvapi_hook.h"
#include "hooks/powrprof.h"
#include "hooks/sleephook.h"
#include "hooks/winuser.h"
#include "touch/touch.h"
#include "util/detour.h"
#include "util/logging.h"
@@ -21,6 +23,7 @@
#include "camera.h"
#include "io.h"
#include "acioemu/handle.h"
#include "cfg/configurator.h"
static decltype(RegCloseKey) *RegCloseKey_orig = nullptr;
static decltype(RegEnumKeyA) *RegEnumKeyA_orig = nullptr;
@@ -40,6 +43,7 @@ namespace games::sdvx {
bool NATIVETOUCH = false;
uint8_t DIGITAL_KNOB_SENS = 16;
SdvxOverlayPosition OVERLAY_POS = SDVX_OVERLAY_BOTTOM;
bool ENABLE_COM_PORT_SCAN_HOOK = false;
std::optional<std::string> SOUND_OUTPUT_DEVICE = std::nullopt;
std::optional<std::string> ASIO_DRIVER = std::nullopt;
@@ -66,6 +70,7 @@ namespace games::sdvx {
static LONG WINAPI RegOpenKeyExA_hook(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired,
PHKEY phkResult)
{
// ASIO hook
if (lpSubKey != nullptr && phkResult != nullptr) {
if (hKey == PARENT_ASIO_REG_HANDLE &&
ASIO_DRIVER.has_value() &&
@@ -74,12 +79,36 @@ namespace games::sdvx {
*phkResult = DEVICE_ASIO_REG_HANDLE;
log_info("sdvx::asio", "replacing '{}' with '{}'", lpSubKey, ASIO_DRIVER.value());
return RegOpenKeyExA_orig(real_asio_reg_handle, ASIO_DRIVER.value().c_str(), ulOptions, samDesired,
const auto result = RegOpenKeyExA_orig(
real_asio_reg_handle,
ASIO_DRIVER.value().c_str(),
ulOptions,
samDesired,
&real_asio_device_reg_handle);
if (result != ERROR_SUCCESS) {
log_warning(
"sdvx::asio",
"failed to open registry subkey '{}', error=0x{:x}",
ASIO_DRIVER.value().c_str(), result);
log_warning(
"sdvx::asio",
"due to improper ASIO setting, game will likely fall back to WASAPI; double check -sdvxasio and the registry",
ASIO_DRIVER.value().c_str(), result);
}
return result;
}
}
// COM hook
if (ENABLE_COM_PORT_SCAN_HOOK &&
lpSubKey != nullptr && phkResult != nullptr &&
_stricmp(lpSubKey, "HARDWARE\\DEVICEMAP\\SERIALCOMM") == 0) {
log_info("sdvx::io", "failing HKLM\\HARDWARE\\DEVICEMAP\\SERIALCOMM to force COM1 ICCA");
return 2; //ERROR_FILE_NOT_FOUND
}
return RegOpenKeyExA_orig(hKey, lpSubKey, ulOptions, samDesired, phkResult);
}
@@ -111,9 +140,9 @@ namespace games::sdvx {
log_info("sdvx::asio", "RegQueryValueExA({}, \"{}\")", fmt::ptr((void *) hKey), lpValueName);
if (_stricmp(lpValueName, "Description") == 0) {
// sdvx does a comparison against "XONAR SOUND CARD(64)"
// otherwise you end up with this error:
// M:BMSoundLib: ASIODriver: No such driver: XONAR SOUND CARD(64)
// sdvx does a comparison against hardcoded string "XONAR SOUND CARD(64)" (same as iidx31)
// so what's in the registry must be overridden with "XONAR SOUND CARD(64)"
// otherwise you end up with this error: M:BMSoundLib: ASIODriver: No such driver
memcpy(lpData, ORIGINAL_ASIO_DEVICE_NAME, strlen(ORIGINAL_ASIO_DEVICE_NAME) + 1);
return ERROR_SUCCESS;
@@ -144,7 +173,7 @@ namespace games::sdvx {
}
#ifdef SPICE64
static bool sdvx5_spam_remover(void *user, const std::string &data, logger::Style style, std::string &out) {
static bool sdvx64_spam_remover(void *user, const std::string &data, logger::Style style, std::string &out) {
if (data.empty() || data[0] != '[') {
return false;
}
@@ -176,6 +205,11 @@ namespace games::sdvx {
out = "";
return true;
}
// M:AppConfig: [env/APPDATA]=C:\Users\username\AppData\Roaming
if (data.find("M:AppConfig: [env/") != std::string::npos) {
out = "";
return true;
}
return false;
}
@@ -223,6 +257,25 @@ namespace games::sdvx {
}
#endif
void SDVXGame::pre_attach() {
// for whatever reason, sdvx latches onto cards for much longer than other games
// needed because the game waits forever on the game over screen until a card is not detected
AUTO_INSERT_CARD_COOLDOWN = 15.f;
// check bad model name
if (!cfg::CONFIGURATOR_STANDALONE && avs::game::is_model("UFC")) {
log_fatal(
"sdvx",
"BAD MODEL NAME ERROR\n\n\n"
"!!! model name set to UFC, this is WRONG and will break your game !!!\n"
"!!! !!!\n"
"!!! If you are trying to boot Valkyrie Model, !!!\n"
"!!! change <spec> from F to G. !!!\n"
"!!! !!!\n"
"!!! model name set to UFC, this is WRONG and will break your game !!!\n\n\n"
);
}
}
void SDVXGame::attach() {
Game::attach();
@@ -260,14 +313,20 @@ namespace games::sdvx {
// enable 9on12 for AMD
if (!libutils::try_library("nvapi64.dll")) {
log_info("sdvx", "nvapi64.dll not found, force enabling 9on12");
GRAPHICS_9_ON_12 = true;
log_info(
"sdvx",
"nvapi64.dll not found; for non-NVIDIA GPUs, requesting 9on12 to be enabled");
GRAPHICS_9_ON_12_REQUESTED_BY_GAME = true;
} else {
// don't let nvapi mess with display settings
nvapi_hook::initialize(avs::game::DLL_INSTANCE);
}
// check for Valkyrie cabinet mode
if (isValkyrieCabinetMode) {
// hook touch window
if (!NATIVETOUCH) {
// in windowed mode, game can accept mouse input on the second screen
if (!NATIVETOUCH && !GRAPHICS_WINDOWED) {
wintouchemu::FORCE = true;
wintouchemu::INJECT_MOUSE_AS_WM_TOUCH = true;
wintouchemu::hook_title_ends(
@@ -282,10 +341,13 @@ namespace games::sdvx {
// add card readers
devicehook_init(aio);
devicehook_add(new acioemu::ACIOHandle(L"COM1"));
} else {
// don't let nvapi mess with display settings (force failure)
libraryhook_hook_proc("nvapi_QueryInterface", static_cast<void *>(nullptr));
libraryhook_enable(avs::game::DLL_INSTANCE);
// this is needed because on some newer versions of SDVX6, soundvoltex.dll will open
// HKLM\HARDWARE\DEVICEMAP\SERIALCOMM, go through some of the keys, and depending on
// what is present, pick a port other than COM1 (seemingly the highest port
// available). We want the game to pick COM1 still, so a workaround is needed to
// fool the game.
ENABLE_COM_PORT_SCAN_HOOK = true;
}
}
#endif
@@ -304,6 +366,7 @@ namespace games::sdvx {
#ifdef SPICE64
powrprof_hook_init(avs::game::DLL_INSTANCE);
winuser_hook_init(avs::game::DLL_INSTANCE);
// hook camera
if (!DISABLECAMS) {
@@ -316,11 +379,11 @@ namespace games::sdvx {
"418D480484C074218D51FD",
"????????????9090??????",
0, 0)) {
log_warning("sdvx", "failed to insert camera error fix");
log_info("sdvx", "did not find matching signature for camera error patch");
}
// remove log spam
logger::hook_add(sdvx5_spam_remover, nullptr);
logger::hook_add(sdvx64_spam_remover, nullptr);
#endif
}
@@ -366,7 +429,7 @@ namespace games::sdvx {
// calculate target RVA
auto volume_set_rva = libutils::offset2rva(MODULE_PATH / avs::game::DLL_NAME, rva);
if (volume_set_rva == -1) {
log_warning("sdvx", "failed to insert set volume hook (convert rva {})", rva);
log_info("sdvx", "could not apply volume hook patch (convert rva {})", rva);
break;
}
@@ -374,7 +437,7 @@ namespace games::sdvx {
auto *volume_set_ptr = reinterpret_cast<uint16_t *>(
reinterpret_cast<intptr_t>(avs::game::DLL_INSTANCE) + volume_set_rva);
if (volume_set_ptr[0] != 0x8B48) {
log_warning("sdvx", "failed to insert set volume hook (invalid target)");
log_info("sdvx", "could not apply volume hook patch (invalid target)", rva);
break;
}
@@ -384,7 +447,7 @@ namespace games::sdvx {
volume_set_hook,
&volume_set_orig))
{
log_warning("sdvx", "failed to insert set volume hook (insert trampoline)");
log_info("sdvx", "could not apply volume hook patch (insert trampoline)", rva);
}
// success
@@ -395,7 +458,7 @@ namespace games::sdvx {
// check if version not found
if (!volume_hook_found) {
log_warning("sdvx", "volume hook unavailable for this game version");
log_info("sdvx", "volume hook unavailable for this game version");
// set volumes to sdvx 4 defaults
auto &lights = games::sdvx::get_lights();