Update to spice2x-23-06-08

This commit is contained in:
[ ]
2023-09-20 02:09:17 +09:00
parent 8957d9d446
commit d03cca1fe2
98 changed files with 21957 additions and 4977 deletions
+7 -7
View File
@@ -11,13 +11,13 @@ namespace games::bc {
Game::attach();
setupapihook_init(libutils::load_library("libaio.dll"));
setupapihook_add({
{ 0, 0, 0, 0, },
"",
"USB\\VID_1CCF&PID_8050\\0000",
{},
"COM3",
});
SETUPAPI_SETTINGS settings {};
const char hwid[] = "USB\\VID_1CCF&PID_8050\\0000";
memcpy(settings.property_hardwareid, hwid, sizeof(hwid));
const char comport[] = "COM3";
memcpy(settings.interface_detail, comport, sizeof(comport));
setupapihook_add(settings);
auto iob = new acio2emu::IOBHandle(L"COM3");
iob->register_node(std::make_unique<TBSNode>());
+89 -18
View File
@@ -15,6 +15,7 @@
#include "acioemu/handle.h"
#include "avs/core.h"
#include "avs/game.h"
#include "cfg/configurator.h"
#include "games/io.h"
#include "hooks/avshook.h"
#include "hooks/cfgmgr32hook.h"
@@ -23,6 +24,7 @@
#include "hooks/setupapihook.h"
#include "hooks/sleephook.h"
#include "launcher/options.h"
#include "touch/touch.h"
#include "misc/wintouchemu.h"
#include "misc/eamuse.h"
#include "util/detour.h"
@@ -56,15 +58,19 @@ namespace games::iidx {
bool FLIP_CAMS = false;
bool DISABLE_CAMS = false;
bool TDJ_MODE = false;
bool FORCE_720P = false;
std::optional<std::string> SOUND_OUTPUT_DEVICE = std::nullopt;
std::optional<std::string> ASIO_DRIVER = std::nullopt;
uint8_t DIGITAL_TT_SENS = 4;
std::optional<std::string> SUBSCREEN_OVERLAY_SIZE = std::nullopt;
// states
static HKEY real_asio_reg_handle = nullptr;
static HKEY real_asio_device_reg_handle = nullptr;
static uint16_t IIDXIO_TT_STATE[2]{};
static uint16_t IIDXIO_TT_DIRECTION[2]{};
static int8_t IIDXIO_TT_DIRECTION[2]{1, 1};
static bool IIDXIO_TT_PRESSED[2]{};
static bool IIDXIO_TT_ALT_PRESSED[2]{};
char IIDXIO_LED_TICKER[10] = {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '\x00'};
bool IIDXIO_LED_TICKER_READONLY = false;
std::mutex IIDX_LED_TICKER_LOCK;
@@ -445,8 +451,8 @@ namespace games::iidx {
// need to hook `avs2-core.dll` so AVS win32fs operations go through rom hook
devicehook_init(avs::core::DLL_INSTANCE);
// hook touch window
wintouchemu::FORCE = true;
wintouchemu::INJECT_MOUSE_AS_WM_TOUCH = true;
wintouchemu::hook_title_ends("beatmania IIDX", "main", avs::game::DLL_INSTANCE);
// prevent crash on TDJ mode without correct DLL
@@ -538,8 +544,21 @@ namespace games::iidx {
if (DISABLE_CAMS) {
SetEnvironmentVariable("CONNECT_CAMERA", "0");
}
if (SOUND_OUTPUT_DEVICE.has_value()) {
SetEnvironmentVariable("SOUND_OUTPUT_DEVICE", SOUND_OUTPUT_DEVICE.value().c_str());
this->detect_sound_output_device();
// check bad model name
if (!cfg::CONFIGURATOR_STANDALONE && avs::game::is_model("TDJ")) {
log_fatal(
"iidx",
"BAD MODEL NAME ERROR\n\n\n"
"!!! model name set to TDJ, this is WRONG and will break your game !!!\n"
"If you are trying to boot IIDX with Lightning Model mode, please do the following instead:\n"
" Revert your changes to XML file so it says <model __type=\"str\">LDJ</model>\n"
" In SpiceCfg, enable 'IIDX TDJ Mode' or provide -iidxtdj flag in command line\n"
" Apply any applicable settings / patches / hex edits\n"
"!!! model name set to TDJ, this is WRONG and will break your game !!!\n\n\n"
);
}
}
@@ -549,6 +568,53 @@ namespace games::iidx {
devicehook_dispose();
}
void IIDXGame::detect_sound_output_device() {
// if the user specified a value (other than auto), use it as the environment var
// probably "wasapi" or "asio", but it's not explicitly checked here for forward compat
if (SOUND_OUTPUT_DEVICE.has_value() && SOUND_OUTPUT_DEVICE.value() != "auto") {
log_info(
"iidx",
"using user-supplied \"{}\" for SOUND_OUTPUT_DEVICE",
SOUND_OUTPUT_DEVICE.value());
SetEnvironmentVariable("SOUND_OUTPUT_DEVICE", SOUND_OUTPUT_DEVICE.value().c_str());
return;
}
// automatic detection
bool use_asio = false;
log_misc("iidx", "auto-detect SOUND_OUTPUT_DEVICE...");
if (ASIO_DRIVER.has_value()) {
log_misc(
"iidx",
"-iidxasio is set to \"{}\", use asio for SOUND_OUTPUT_DEVICE",
ASIO_DRIVER.value());
use_asio = true;
} else {
HKEY subkey;
LSTATUS result;
result = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\ASIO\\XONAR SOUND CARD(64)", &subkey);
if (result == ERROR_SUCCESS) {
RegCloseKey(subkey);
use_asio = true;
log_misc(
"iidx",
"found HKLM\\SOFTWARE\\ASIO\\XONAR SOUND CARD(64), using asio for SOUND_OUTPUT_DEVICE");
}
}
const char* device = "wasapi";
if (use_asio) {
device = "asio";
}
log_info("iidx", "SOUND_OUTPUT_DEVICE set to {}", device);
log_info(
"iidx",
"SOUND_OUTPUT_DEVICE only affects IIDX27+ and ignored by older games. "
"If {} is not what you wanted, you can override it with -iidxsounddevice option",
device);
SetEnvironmentVariable("SOUND_OUTPUT_DEVICE", device);
}
uint32_t get_pad() {
uint32_t pad = 0;
@@ -701,7 +767,8 @@ namespace games::iidx {
unsigned char get_tt(int player, bool slow) {
// check change value for high/low precision
uint16_t change = slow ? (uint16_t) 1 : (uint16_t) 4;
uint16_t change =
slow ? (uint16_t) (DIGITAL_TT_SENS / 4) : (uint16_t) DIGITAL_TT_SENS;
// check player number
if (player > 1)
@@ -713,8 +780,11 @@ namespace games::iidx {
player != 0 ? Buttons::P2_TTPlus : Buttons::P1_TTPlus));
bool ttm = GameAPI::Buttons::getState(RI_MGR, buttons.at(
player != 0 ? Buttons::P2_TTMinus : Buttons::P1_TTMinus));
bool ttpm = GameAPI::Buttons::getState(RI_MGR, buttons.at(
player != 0 ? Buttons::P2_TTPlusMinus : Buttons::P1_TTPlusMinus));
bool ttpm_alt = GameAPI::Buttons::getState(RI_MGR, buttons.at(
player != 0 ? Buttons::P2_TTPlusMinusAlt : Buttons::P1_TTPlusMinusAlt));
// TT+
if (ttp)
@@ -725,19 +795,16 @@ namespace games::iidx {
IIDXIO_TT_STATE[player] -= change;
// TT+/-
if (ttpm) {
if (IIDXIO_TT_DIRECTION[player] != 0u) {
if (!IIDXIO_TT_PRESSED[player])
IIDXIO_TT_DIRECTION[player] = 0;
IIDXIO_TT_STATE[player] += change;
} else {
if (!IIDXIO_TT_PRESSED[player])
IIDXIO_TT_DIRECTION[player] = 1;
IIDXIO_TT_STATE[player] -= change;
}
IIDXIO_TT_PRESSED[player] = true;
} else
IIDXIO_TT_PRESSED[player] = false;
bool ttpm_rising_edge = !IIDXIO_TT_PRESSED[player] && ttpm;
bool ttpm_alt_rising_edge = !IIDXIO_TT_ALT_PRESSED[player] && ttpm_alt;
if (ttpm_rising_edge || ttpm_alt_rising_edge) {
IIDXIO_TT_DIRECTION[player] *= -1;
}
if (ttpm || ttpm_alt) {
IIDXIO_TT_STATE[player] += (change * IIDXIO_TT_DIRECTION[player]);
}
IIDXIO_TT_PRESSED[player] = ttpm;
IIDXIO_TT_ALT_PRESSED[player] = ttpm_alt;
// raw input
auto &analogs = get_analogs();
@@ -793,4 +860,8 @@ namespace games::iidx {
const char* get_16seg() {
return IIDXIO_LED_TICKER;
}
bool is_tdj_fhd() {
return TDJ_MODE && avs::game::is_ext(2022101900, MAXINT);
}
}
+7
View File
@@ -11,8 +11,11 @@ namespace games::iidx {
extern bool FLIP_CAMS;
extern bool DISABLE_CAMS;
extern bool TDJ_MODE;
extern bool FORCE_720P;
extern std::optional<std::string> SOUND_OUTPUT_DEVICE;
extern std::optional<std::string> ASIO_DRIVER;
extern uint8_t DIGITAL_TT_SENS;
extern std::optional<std::string> SUBSCREEN_OVERLAY_SIZE;
// state
extern char IIDXIO_LED_TICKER[10];
@@ -27,6 +30,9 @@ namespace games::iidx {
virtual void attach() override;
virtual void pre_attach() override;
virtual void detach() override;
private:
void detect_sound_output_device();
};
// helper methods
@@ -38,4 +44,5 @@ namespace games::iidx {
unsigned char get_tt(int player, bool slow);
unsigned char get_slider(uint8_t slider);
const char* get_16seg();
bool is_tdj_fhd();
}
+2
View File
@@ -21,6 +21,7 @@ std::vector<Button> &games::iidx::get_buttons() {
"P1 TT+",
"P1 TT-",
"P1 TT+/-",
"P1 TT+/- Alternate",
"P1 Start",
"P2 1",
"P2 2",
@@ -32,6 +33,7 @@ std::vector<Button> &games::iidx::get_buttons() {
"P2 TT+",
"P2 TT-",
"P2 TT+/-",
"P2 TT+/- Alternate",
"P2 Start",
"EFFECT",
"VEFX",
+2
View File
@@ -21,6 +21,7 @@ namespace games::iidx {
P1_TTPlus,
P1_TTMinus,
P1_TTPlusMinus,
P1_TTPlusMinusAlt,
P1_Start,
P2_1,
P2_2,
@@ -32,6 +33,7 @@ namespace games::iidx {
P2_TTPlus,
P2_TTMinus,
P2_TTPlusMinus,
P2_TTPlusMinusAlt,
P2_Start,
Effect,
VEFX,
+12 -10
View File
@@ -366,8 +366,14 @@ namespace games {
std::vector<unsigned short> vkey_defaults;
// overlay button definitions
names.emplace_back("Screenshot");
vkey_defaults.push_back(VK_SNAPSHOT);
names.emplace_back("Toggle Sub Screen");
vkey_defaults.push_back(VK_PRIOR);
names.emplace_back("Insert Coin");
vkey_defaults.push_back(VK_F1);
names.emplace_back("Toggle IO Panel");
vkey_defaults.push_back(VK_F2);
names.emplace_back("Toggle Config");
vkey_defaults.push_back(VK_F4);
names.emplace_back("Toggle Virtual Keypad P1");
@@ -382,12 +388,14 @@ namespace games {
vkey_defaults.push_back(VK_F9);
names.emplace_back("Toggle Patch Manager");
vkey_defaults.push_back(VK_F10);
names.emplace_back("Toggle Sub Screen");
vkey_defaults.push_back(VK_PRIOR);
names.emplace_back("Toggle VR Control");
vkey_defaults.push_back(0xFF);
names.emplace_back("Toggle Screen Resize");
vkey_defaults.push_back(VK_F11);
names.emplace_back("Toggle Overlay");
vkey_defaults.push_back(VK_F12);
names.emplace_back("Toggle VR Control");
vkey_defaults.push_back(0xFF);
names.emplace_back("Screen Resize");
vkey_defaults.push_back(0xFF);
names.emplace_back("Navigator Activate");
vkey_defaults.push_back(0xFF);
names.emplace_back("Navigator Cancel");
@@ -400,18 +408,12 @@ namespace games {
vkey_defaults.push_back(0xFF);
names.emplace_back("Navigator Right");
vkey_defaults.push_back(0xFF);
names.emplace_back("Screenshot");
vkey_defaults.push_back(VK_SNAPSHOT);
names.emplace_back("Hotkey Enable 1");
vkey_defaults.push_back(0xFF);
names.emplace_back("Hotkey Enable 2");
vkey_defaults.push_back(0xFF);
names.emplace_back("Hotkey Toggle");
vkey_defaults.push_back(0xFF);
names.emplace_back("Screen Resize");
vkey_defaults.push_back(0xFF);
names.emplace_back("Toggle Screen Resize");
vkey_defaults.push_back(0xFF);
// return sorted buttons
buttons = GameAPI::Buttons::sortButtons(buttons, names, &vkey_defaults);
+6 -5
View File
@@ -7,7 +7,10 @@ namespace games {
namespace OverlayButtons {
enum {
Screenshot,
ToggleSubScreen,
InsertCoin,
ToggleIOPanel,
ToggleConfig,
ToggleVirtualKeypadP1,
ToggleVirtualKeypadP2,
@@ -15,21 +18,19 @@ namespace games {
ToggleLog,
ToggleControl,
TogglePatchManager,
ToggleSubScreen,
ToggleVRControl,
ToggleScreenResize,
ToggleOverlay,
ToggleVRControl,
ScreenResize,
NavigatorActivate,
NavigatorCancel,
NavigatorUp,
NavigatorDown,
NavigatorLeft,
NavigatorRight,
Screenshot,
HotkeyEnable1,
HotkeyEnable2,
HotkeyToggle,
ScreenResize,
ToggleScreenResize,
};
}
+56 -9
View File
@@ -10,9 +10,14 @@
#include "util/detour.h"
#include "util/libutils.h"
#define JB_BUTTON_SIZE 160
#define JB_BUTTON_GAP 37
#define JB_BUTTON_HITBOX (JB_BUTTON_SIZE + JB_BUTTON_GAP)
namespace games::jb {
// touch stuff
bool TOUCH_LEGACY_BOX = false;
static bool TOUCH_ENABLE = false;
static bool TOUCH_ATTACHED = false;
static bool IS_PORTRAIT = true;
@@ -68,19 +73,61 @@ namespace games::jb {
memset(TOUCH_STATE, 0, sizeof(TOUCH_STATE));
// check touch points
// note that the IO code in device.cpp will correctly compensate for orientation, depending on the model.
TOUCH_POINTS.clear();
touch_get_points(TOUCH_POINTS);
auto offset = IS_PORTRAIT ? 580 : 0;
for (auto &tp : TOUCH_POINTS) {
if (TOUCH_LEGACY_BOX) {
auto offset = IS_PORTRAIT ? 580 : 0;
for (auto &tp : TOUCH_POINTS) {
// get grid coordinates
int x = tp.x * 4 / 768;
int y = (tp.y - offset) * 4 / (1360 - 580);
// get grid coordinates
int x = tp.x * 4 / 768;
int y = (tp.y - offset) * 4 / (1360 - 580);
// set the corresponding state
int index = y * 4 + x;
if (index >= 0 && index < 16) {
TOUCH_STATE[index] = true;
// set the corresponding state
int index = y * 4 + x;
if (index >= 0 && index < 16) {
TOUCH_STATE[index] = true;
}
}
} else {
for (auto &tp : TOUCH_POINTS) {
int x_relative = tp.x;
int y_relative = tp.y;
// x_relative and y_relative are relative to the top-left pixel of the first button
if (IS_PORTRAIT) {
// which is at (8, 602) in portrait:
// X: [8...759] (752 pixels wide)
// Y: [602...1353] (752 pixels high)
x_relative -= 8;
y_relative -= 602;
} else {
// and at (8, 8) in landscape
x_relative -= 8;
y_relative -= 8;
}
if (x_relative < 0 || y_relative < 0) {
continue;
}
// x_hitbox and y_hitbox is relative to top-left pixel of each button
int x_index = x_relative / JB_BUTTON_HITBOX;
int x_hitbox = x_relative % JB_BUTTON_HITBOX;
int y_index = y_relative / JB_BUTTON_HITBOX;
int y_hitbox = y_relative % JB_BUTTON_HITBOX;
// check if the gap was touched
if (x_hitbox > JB_BUTTON_SIZE || y_hitbox > JB_BUTTON_SIZE) {
continue;
}
// set the corresponding state
int index = y_index * 4 + x_index;
if (0 <= index && index < 16) {
TOUCH_STATE[index] = true;
}
}
}
}
+1
View File
@@ -5,6 +5,7 @@
namespace games::jb {
// touch stuff
extern bool TOUCH_LEGACY_BOX;
extern bool TOUCH_STATE[16];
void touch_update();
+2
View File
@@ -4,6 +4,8 @@
namespace games::rb {
extern uint16_t TOUCH_SCALING;
class RBGame : public games::Game {
public:
RBGame();
+21 -4
View File
@@ -11,15 +11,20 @@
static std::string WINDOW_TITLE = "REFLEC BEAT";
namespace games::rb {
uint16_t TOUCH_SCALING = 1000;
}
games::rb::ReflecBeatTouchDeviceHandle::ReflecBeatTouchDeviceHandle(bool log_fps) {
this->log_fps = log_fps;
}
void games::rb::ReflecBeatTouchDeviceHandle::grid_insert(unsigned char *data, int cursor_x, int cursor_y) {
// scale to grid position
// scale to grid position - there are 48 columns and 76 rows of IR sensors.
// for whatever reason, the last y row (#75) results in weird input few rows above; just drop it
int grid_x = CLAMP((cursor_x * 48) / window_width, 0, 47);
int grid_y = CLAMP((cursor_y * 76) / window_height, 0, 75);
int grid_y = CLAMP((cursor_y * 76) / window_height, 0, 74);
// get bit positions
int bit_x = 88 + grid_x;
@@ -121,6 +126,8 @@ int games::rb::ReflecBeatTouchDeviceHandle::read(LPVOID lpBuffer, DWORD nNumberO
// data header
data[0] = 0x55;
data[2] = 0x4C;
const auto SCALE_FACTOR = games::rb::TOUCH_SCALING / 1000.f;
// iterate all touch points
auto offset_x = (int) (window_width / 48.0 / 3.0);
@@ -139,9 +146,19 @@ int games::rb::ReflecBeatTouchDeviceHandle::read(LPVOID lpBuffer, DWORD nNumberO
y = window_height - point.x;
}
// apply scaling
x = x - (window_width * (1.f - SCALE_FACTOR) / 2);
x = x / SCALE_FACTOR;
y = y - (window_height * (1.f - SCALE_FACTOR) / 2);
y = y / SCALE_FACTOR;
if (x < 0 || window_width <= x || y < 0 || window_height <= y) {
continue;
}
// point scaling
auto point_x = (int) ((x - window_width / 2.0) * 48.0 / 54.0 + window_width / 2.0);
auto point_y = (int) (y - window_height / 76);
const auto point_x = (int) ((x - window_width / 2.0) * 48.0 / 54.0 + window_width / 2.0);
const auto point_y = (int) (y - window_height / 76);
// insert 9 times with offset to double the precision
grid_insert(data, point_x, point_y);
+7 -5
View File
@@ -9,9 +9,11 @@
#include "games/io.h"
#include "launcher/options.h"
#include "io.h"
#include "games/sdvx/sdvx.h"
namespace games::sdvx {
constexpr bool BI2X_PASSTHROUGH = false;
bool BI2X_INITIALIZED = false;
/*
* class definitions
@@ -104,7 +106,6 @@ namespace games::sdvx {
if (!BI2X_PASSTHROUGH) {
custom_node = new AIO_IOB2_BI2X_UFC;
memset(&custom_node->data, 0, sizeof(custom_node->data));
return custom_node;
} else {
@@ -163,18 +164,18 @@ namespace games::sdvx {
// volume left
if (GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::VOL_L_Left])) {
VOL_L -= 64;
VOL_L -= ((uint16_t)DIGITAL_KNOB_SENS * 4);
}
if (GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::VOL_L_Right])) {
VOL_L += 64;
VOL_L += ((uint16_t)DIGITAL_KNOB_SENS * 4);
}
// volume right
if (GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::VOL_R_Left])) {
VOL_R -= 64;
VOL_R -= ((uint16_t)DIGITAL_KNOB_SENS * 4);
}
if (GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::VOL_R_Right])) {
VOL_R += 64;
VOL_R += ((uint16_t)DIGITAL_KNOB_SENS * 4);
}
// update volumes
@@ -364,6 +365,7 @@ namespace games::sdvx {
aioNmgrIob2->pAIO_NMGR_IOB_BeginManage = AIO_NMGR_IOB_BeginManageStub;
}
log_info("bi2x_hook", "aioNMgrIob2_Create");
BI2X_INITIALIZED = true;
return &aioNmgrIob2;
}
+123
View File
@@ -10,6 +10,7 @@
#include "hooks/libraryhook.h"
#include "hooks/powrprof.h"
#include "hooks/sleephook.h"
#include "touch/touch.h"
#include "util/detour.h"
#include "util/logging.h"
#include "util/sigscan.h"
@@ -21,11 +22,118 @@
#include "io.h"
#include "acioemu/handle.h"
static decltype(RegCloseKey) *RegCloseKey_orig = nullptr;
static decltype(RegEnumKeyA) *RegEnumKeyA_orig = nullptr;
static decltype(RegOpenKeyA) *RegOpenKeyA_orig = nullptr;
static decltype(RegOpenKeyExA) *RegOpenKeyExA_orig = nullptr;
static decltype(RegQueryValueExA) *RegQueryValueExA_orig = nullptr;
namespace games::sdvx {
// constants
const HKEY PARENT_ASIO_REG_HANDLE = reinterpret_cast<HKEY>(0x3001);
const HKEY DEVICE_ASIO_REG_HANDLE = reinterpret_cast<HKEY>(0x3002);
const char *ORIGINAL_ASIO_DEVICE_NAME = "XONAR SOUND CARD(64)";
// settings
bool DISABLECAMS = false;
bool NATIVETOUCH = false;
uint8_t DIGITAL_KNOB_SENS = 16;
SdvxOverlayPosition OVERLAY_POS = SDVX_OVERLAY_BOTTOM;
std::optional<std::string> SOUND_OUTPUT_DEVICE = std::nullopt;
std::optional<std::string> ASIO_DRIVER = std::nullopt;
// states
static HKEY real_asio_reg_handle = nullptr;
static HKEY real_asio_device_reg_handle = nullptr;
static LONG WINAPI RegOpenKeyA_hook(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult) {
if (lpSubKey != nullptr && phkResult != nullptr) {
if (hKey == HKEY_LOCAL_MACHINE &&
ASIO_DRIVER.has_value() &&
_stricmp(lpSubKey, "software\\asio") == 0)
{
*phkResult = PARENT_ASIO_REG_HANDLE;
return RegOpenKeyA_orig(hKey, lpSubKey, &real_asio_reg_handle);
}
}
return RegOpenKeyA_orig(hKey, lpSubKey, phkResult);
}
static LONG WINAPI RegOpenKeyExA_hook(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired,
PHKEY phkResult)
{
if (lpSubKey != nullptr && phkResult != nullptr) {
if (hKey == PARENT_ASIO_REG_HANDLE &&
ASIO_DRIVER.has_value() &&
_stricmp(lpSubKey, ORIGINAL_ASIO_DEVICE_NAME) == 0)
{
*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,
&real_asio_device_reg_handle);
}
}
return RegOpenKeyExA_orig(hKey, lpSubKey, ulOptions, samDesired, phkResult);
}
static LONG WINAPI RegEnumKeyA_hook(HKEY hKey, DWORD dwIndex, LPSTR lpName, DWORD cchName) {
if (hKey == PARENT_ASIO_REG_HANDLE && ASIO_DRIVER.has_value()) {
if (dwIndex == 0) {
auto ret = RegEnumKeyA_orig(real_asio_reg_handle, dwIndex, lpName, cchName);
if (ret == ERROR_SUCCESS && lpName != nullptr) {
log_info("sdvx::asio", "stubbing '{}' with '{}'", lpName, ORIGINAL_ASIO_DEVICE_NAME);
strncpy(lpName, ORIGINAL_ASIO_DEVICE_NAME, cchName);
}
return ret;
} else {
return ERROR_NO_MORE_ITEMS;
}
}
return RegEnumKeyA_orig(hKey, dwIndex, lpName, cchName);
}
static LONG WINAPI RegQueryValueExA_hook(HKEY hKey, LPCTSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType,
LPBYTE lpData, LPDWORD lpcbData)
{
if (lpValueName != nullptr && lpData != nullptr && lpcbData != nullptr) {
if (hKey == DEVICE_ASIO_REG_HANDLE && ASIO_DRIVER.has_value()) {
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)
memcpy(lpData, ORIGINAL_ASIO_DEVICE_NAME, strlen(ORIGINAL_ASIO_DEVICE_NAME) + 1);
return ERROR_SUCCESS;
} else {
hKey = real_asio_device_reg_handle;
}
}
}
// fallback
return RegQueryValueExA_orig(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData);
}
static LONG WINAPI RegCloseKey_hook(HKEY hKey) {
if (hKey == PARENT_ASIO_REG_HANDLE || hKey == DEVICE_ASIO_REG_HANDLE) {
return ERROR_SUCCESS;
}
return RegCloseKey_orig(hKey);
}
SDVXGame::SDVXGame() : Game("Sound Voltex") {
}
@@ -161,6 +269,7 @@ namespace games::sdvx {
// hook touch window
if (!NATIVETOUCH) {
wintouchemu::FORCE = true;
wintouchemu::INJECT_MOUSE_AS_WM_TOUCH = true;
wintouchemu::hook_title_ends(
"SOUND VOLTEX",
"Main Screen",
@@ -179,7 +288,21 @@ namespace games::sdvx {
libraryhook_enable(avs::game::DLL_INSTANCE);
}
}
#endif
// ASIO device hook
RegCloseKey_orig = detour::iat_try(
"RegCloseKey", RegCloseKey_hook, avs::game::DLL_INSTANCE);
RegEnumKeyA_orig = detour::iat_try(
"RegEnumKeyA", RegEnumKeyA_hook, avs::game::DLL_INSTANCE);
RegOpenKeyA_orig = detour::iat_try(
"RegOpenKeyA", RegOpenKeyA_hook, avs::game::DLL_INSTANCE);
RegOpenKeyExA_orig = detour::iat_try(
"RegOpenKeyExA", RegOpenKeyExA_hook, avs::game::DLL_INSTANCE);
RegQueryValueExA_orig = detour::iat_try(
"RegQueryValueExA", RegQueryValueExA_hook, avs::game::DLL_INSTANCE);
#ifdef SPICE64
powrprof_hook_init(avs::game::DLL_INSTANCE);
// hook camera
+13
View File
@@ -1,12 +1,25 @@
#pragma once
#include <optional>
#include "games/game.h"
namespace games::sdvx {
enum SdvxOverlayPosition {
SDVX_OVERLAY_TOP,
SDVX_OVERLAY_MIDDLE,
SDVX_OVERLAY_BOTTOM
};
// settings
extern bool DISABLECAMS;
extern bool NATIVETOUCH;
extern uint8_t DIGITAL_KNOB_SENS;
extern std::optional<std::string> ASIO_DRIVER;
extern bool BI2X_INITIALIZED;
extern SdvxOverlayPosition OVERLAY_POS;
class SDVXGame : public games::Game {
public: