Merge branch 'main' into nac-spice22x

Merge official spice2x 'main', up to b53447b
Notes: dc82c98  is where the nixac fork starts.

- Upstream's OBJECT-library + forbidden-static-DLL-import build refactor
  merged with nixAC's blob/dsdmo resources
- SPICE_XP / runtime large-address-aware detection builds have been
  integrated from upstream
- README.md grabs from upstream; .gitignore keeps nixAC's fork-specific
  entries
This commit is contained in:
2026-08-07 00:21:58 +02:00
359 changed files with 71032 additions and 27946 deletions
+60 -16
View File
@@ -8,6 +8,9 @@
#include "hooks/graphics/graphics.h"
#include "hooks/devicehook.h"
#include "hooks/libraryhook.h"
#ifdef SPICE64
#include "hooks/graphics/nvapi_impl.h"
#endif
#include "hooks/graphics/nvapi_hook.h"
#include "hooks/powrprof.h"
#include "hooks/sleephook.h"
@@ -21,8 +24,10 @@
#include "util/socd_cleaner.h"
#include "util/time.h"
#include "util/libutils.h"
#include "misc/wintouchemu.h"
#include "util/sysutils.h"
#include "misc/eamuse.h"
#include "misc/wintouchemu.h"
#include "touch/native/nativetouchhook.h"
#include "bi2x_hook.h"
#include "camera.h"
#include "io.h"
@@ -44,7 +49,6 @@ namespace games::sdvx {
const char *ORIGINAL_ASIO_DEVICE_NAME = "XONAR SOUND CARD(64)";
// settings
bool NATIVETOUCH = false;
uint8_t DIGITAL_KNOB_SENS = 16;
SdvxOverlayPosition OVERLAY_POS = SDVX_OVERLAY_BOTTOM;
bool ENABLE_COM_PORT_SCAN_HOOK = false;
@@ -233,6 +237,27 @@ namespace games::sdvx {
});
return false;
}
static bool logged_missing_layer_error = false;
// this is raw SHIFT-JIS text for
// W:BM2D: CreateLayer() 指定したレイヤーは存在しません
if (!logged_missing_layer_error &&
data.find(
"\x57\x3A\x42\x4D\x32\x44\x3A\x20\x43\x72\x65\x61\x74\x65\x4C\x61\x79\x65\x72\x28\x29\x20"
"\x8E\x77\x92\xE8\x82\xB5\x82\xBD\x83\x8C\x83\x43\x83\x84\x81\x5B\x82\xCD\x91\xB6\x8D\xDD"
"\x82\xB5\x82\xDC\x82\xB9\x82\xF1") != std::string::npos) {
logged_missing_layer_error = true;
deferredlogs::defer_error_messages({
"sdvx game engine detected missing or corrupt file(s); raw SHIFT-JIS error was:",
std::string(" ") + data,
" this will almost certainly cause your game to crash",
" this is often caused by mismatched game DLLs or missing resources from game updates",
" double check the integrity of your game data and try again"
});
return false;
}
return false;
}
@@ -333,23 +358,23 @@ namespace games::sdvx {
SHOW_VM_MONITOR_WARNING = true;
log_warning(
"sdvx",
"\n\n!!! using -monitor option with VM mode is NOT recommended due to !!!\n"
"!!! known compatibility issues with the game !!!\n"
"\n\n"
"!!! using -dxmainadapter option with Valkyrie mode is NOT !!!\n"
"!!! recommended due to known compatibility issues with the game !!!\n"
"!!! !!!\n"
"!!! * game may launch in wrong resolution or refresh rate !!!\n"
"!!! * touch / mouse input may stop working in subscreen / overlay !!!\n"
"!!! !!!\n"
"!!! recommendation is to NOT use -monitor and instead set the !!!\n"
"!!! primary monitor in Windows settings before launching the game !!!\n\n"
"!!! recommendation is to use the Change Main Monitor (-mainmonitor) !!!\n"
"!!! option instead of -dxmainadapter !!!\n\n"
);
deferredlogs::defer_error_messages({
"-monitor option is NOT recommended when running with Valkyrie mode",
"-dxmainadapter option is NOT recommended when running with Valkyrie mode",
" due to known compatibility issues with the game:",
" * game may launch in wrong resolution or refresh rate",
" * touch / mouse input may stop working in subscreen / overlay",
" recommended fix is to NOT use -monitor and instead set the primary",
" monitor in Windows settings before launching the game"
" use Change Main Monitor (-mainmonitor) option instead"
});
}
#endif
@@ -369,7 +394,7 @@ namespace games::sdvx {
}
}
}
void SDVXGame::attach() {
Game::attach();
@@ -405,26 +430,41 @@ namespace games::sdvx {
if (aio != nullptr) {
// enable 9on12 for AMD
if (!libutils::try_library("nvapi64.dll")) {
const auto nvapi = libutils::try_library("nvapi64.dll");
if (nvapi == nullptr) {
log_info(
"sdvx",
"nvapi64.dll not found; for non-NVIDIA GPUs, requesting 9on12 to be enabled");
GRAPHICS_9_ON_12_REQUESTED_BY_GAME = true;
}
if (nvapi_hook::BYPASS_NVAPI || nvapi == nullptr) {
const uint32_t main_refresh_hz = GRAPHICS_FORCE_REFRESH > 0 ?
GRAPHICS_FORCE_REFRESH : (is_valkyrie_model() ? 120 : 60);
const uint32_t sub_refresh_hz = GRAPHICS_FORCE_REFRESH_SUB.value_or(60);
if (!nvapi_impl::initialize(
avs::game::DLL_INSTANCE,
main_refresh_hz,
sub_refresh_hz)) {
log_warning("sdvx", "failed to initialize synthetic NVAPI");
}
} else {
// don't let nvapi mess with display settings
nvapi_hook::initialize(avs::game::DLL_INSTANCE);
}
if (is_valkyrie_model()) {
// hook touch window
// in windowed mode, game can accept mouse input on the second screen
if (!NATIVETOUCH && !GRAPHICS_WINDOWED) {
const auto native_touch_ready = !wintouchemu::FORCE &&
nativetouch::hook(avs::game::DLL_INSTANCE);
if (!native_touch_ready) {
wintouchemu::FORCE = true;
wintouchemu::INJECT_MOUSE_AS_WM_TOUCH = true;
wintouchemu::hook_title_ends(
if (!GRAPHICS_WINDOWED) {
wintouchemu::INJECT_MOUSE_AS_WM_TOUCH = true;
wintouchemu::hook_title_ends(
"SOUND VOLTEX",
"Main Screen",
avs::game::DLL_INSTANCE);
}
}
// insert BI2X hooks
@@ -442,6 +482,7 @@ namespace games::sdvx {
ENABLE_COM_PORT_SCAN_HOOK = true;
}
}
#endif
// ASIO device hook
@@ -477,6 +518,9 @@ namespace games::sdvx {
// remove log spam
logger::hook_add(sdvx64_spam_remover, nullptr);
if (is_valkyrie_model()) {
sysutils::hook_EnumDisplayDevicesA();
}
#endif
}