mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-08-01 22:30:42 -07:00
io: fix bi2x_hook implementation in various games (#522)
## Link to GitHub Issue, if one exists similar issue as #499 ## Description of change Fix broken bi2x_hook implementations that did not properly allocate I/O buffers with correct sizes. People keep copy-pasting other implementation that allocate 0 bytes of memory, but we run the risk of memory corruption or/or game crashes if we keep doing this. We've seen some mystery crashes with CCJ for example, maybe this will fix that. While I'm here, implement SOCD cleaner for Polaris Chord. ## Testing Tested I/O menu with CCJ, play through tutorial (didn't test matches) Tested GWDelta (test menu and a few songs in guitar) Tested PC (played a credit) Tested QKS (still can't get past the title screen)
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
#include "bi2x_hook.h"
|
#include "bi2x_hook.h"
|
||||||
|
|
||||||
|
#if SPICE64
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include "util/detour.h"
|
#include "util/detour.h"
|
||||||
#include "util/logging.h"
|
#include "util/logging.h"
|
||||||
@@ -16,15 +18,19 @@ namespace games::ccj {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
struct AIO_SCI_COMM {
|
struct AIO_SCI_COMM {
|
||||||
|
uint8_t data[0xf8];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AIO_NMGR_IOB2 {
|
struct AIO_NMGR_IOB2 {
|
||||||
|
uint8_t data[0xe30];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AIO_IOB2_BI2X_TBS {
|
struct AIO_IOB2_BI2X_TBS {
|
||||||
|
uint8_t data[0x4680];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AIO_IOB2_BI2X_WRFIRM {
|
struct AIO_IOB2_BI2X_WRFIRM {
|
||||||
|
uint8_t data[0x20f48];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AIO_NMGR_IOB__NODEINFO {
|
struct AIO_NMGR_IOB__NODEINFO {
|
||||||
@@ -72,6 +78,12 @@ namespace games::ccj {
|
|||||||
AIO_IOB2_BI2X_AC1__OUTPUTDATA OutputData;
|
AIO_IOB2_BI2X_AC1__OUTPUTDATA OutputData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// checked with UJK-001-2024060400
|
||||||
|
static_assert(sizeof(AIO_SCI_COMM) == 0xf8);
|
||||||
|
static_assert(sizeof(AIO_NMGR_IOB2) == 0xe30);
|
||||||
|
static_assert(sizeof(AIO_IOB2_BI2X_TBS) == 0x4680);
|
||||||
|
static_assert(sizeof(AIO_IOB2_BI2X_WRFIRM) == 0x20f48);
|
||||||
|
|
||||||
static void write_iccr_led(Lights::ccj_lights_t light, uint8_t value);
|
static void write_iccr_led(Lights::ccj_lights_t light, uint8_t value);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -621,4 +633,6 @@ namespace games::ccj {
|
|||||||
detour::trampoline_try(libaioDll, "aioNodeCtl_IsError",
|
detour::trampoline_try(libaioDll, "aioNodeCtl_IsError",
|
||||||
aioNodeCtl_IsError, &aioNodeCtl_IsError_orig);
|
aioNodeCtl_IsError, &aioNodeCtl_IsError_orig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#if SPICE64
|
||||||
|
|
||||||
namespace games::ccj {
|
namespace games::ccj {
|
||||||
void bi2x_hook_init();
|
void bi2x_hook_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -68,9 +68,13 @@ namespace games::ccj {
|
|||||||
detour::trampoline_try("execexe.dll", MAKEINTRESOURCE(11),
|
detour::trampoline_try("execexe.dll", MAKEINTRESOURCE(11),
|
||||||
(void*)execexe_CreateFileW_hook,(void**)&execexe_CreateFileW_orig);
|
(void*)execexe_CreateFileW_hook,(void**)&execexe_CreateFileW_orig);
|
||||||
|
|
||||||
|
#if SPICE64
|
||||||
|
|
||||||
// insert BI2X hooks
|
// insert BI2X hooks
|
||||||
bi2x_hook_init();
|
bi2x_hook_init();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
// insert trackball hooks
|
// insert trackball hooks
|
||||||
trackball_hook_init();
|
trackball_hook_init();
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#include "bi2x_hook.h"
|
#include "bi2x_hook.h"
|
||||||
|
|
||||||
|
#if SPICE64
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include "util/detour.h"
|
#include "util/detour.h"
|
||||||
@@ -18,24 +20,29 @@ namespace games::gitadora {
|
|||||||
// */
|
// */
|
||||||
|
|
||||||
struct AIO_NMGR_IOB2 {
|
struct AIO_NMGR_IOB2 {
|
||||||
|
uint8_t data[0xe18];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AIO_IOB2_BI2X_AC1__SETTING {
|
struct AIO_IOB2_BI2X_AC1__SETTING {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AIO_NMGR_IOB5 {
|
struct AIO_NMGR_IOB5 {
|
||||||
|
uint8_t data[0xb10];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AIO_SCI_COMM {
|
struct AIO_SCI_COMM {
|
||||||
|
uint8_t data[0x100];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AIO_IOB5_Y32D {
|
struct AIO_IOB5_Y32D {
|
||||||
|
uint8_t data[0x2e8];
|
||||||
};
|
};
|
||||||
|
|
||||||
// struct AIO_IOB5_Y33I {
|
// struct AIO_IOB5_Y33I {
|
||||||
// };
|
// };
|
||||||
|
|
||||||
struct AIO_IOB2_BI2X_AC1 {
|
struct AIO_IOB2_BI2X_AC1 {
|
||||||
|
uint8_t data[0x4570];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AIO_NMGR_IOB__NODEINFO {
|
struct AIO_NMGR_IOB__NODEINFO {
|
||||||
@@ -43,6 +50,7 @@ namespace games::gitadora {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct AIO_IOB2_BI2X_WRFIRM {
|
struct AIO_IOB2_BI2X_WRFIRM {
|
||||||
|
uint8_t data[0x20f48];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AIO_SCI_COMM_T {
|
struct AIO_SCI_COMM_T {
|
||||||
@@ -159,6 +167,14 @@ namespace games::gitadora {
|
|||||||
uint8_t unk[0xB1];
|
uint8_t unk[0xB1];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// verified with M32-007-2025092400
|
||||||
|
static_assert(sizeof(AIO_NMGR_IOB2) == 0xe18);
|
||||||
|
static_assert(sizeof(AIO_NMGR_IOB5) == 0xb10);
|
||||||
|
static_assert(sizeof(AIO_SCI_COMM) == 0x100);
|
||||||
|
static_assert(sizeof(AIO_IOB5_Y32D) == 0x2e8);
|
||||||
|
static_assert(sizeof(AIO_IOB2_BI2X_AC1) == 0x4570);
|
||||||
|
static_assert(sizeof(AIO_IOB2_BI2X_WRFIRM) == 0x20f48);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* typedefs
|
* typedefs
|
||||||
*/
|
*/
|
||||||
@@ -701,4 +717,6 @@ namespace games::gitadora {
|
|||||||
detour::trampoline_try(libaioDll, "aioNodeCtl_UpdateDevicesStatus",
|
detour::trampoline_try(libaioDll, "aioNodeCtl_UpdateDevicesStatus",
|
||||||
aioNodeCtl_UpdateDevicesStatus, &aioNodeCtl_UpdateDevicesStatus_orig);
|
aioNodeCtl_UpdateDevicesStatus, &aioNodeCtl_UpdateDevicesStatus_orig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#if SPICE64
|
||||||
|
|
||||||
namespace games::gitadora {
|
namespace games::gitadora {
|
||||||
void bi2x_hook_init();
|
void bi2x_hook_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#include "bi2x_hook.h"
|
#include "bi2x_hook.h"
|
||||||
|
|
||||||
|
#if SPICE64
|
||||||
|
|
||||||
#include "util/execexe.h"
|
#include "util/execexe.h"
|
||||||
#include "util/logging.h"
|
#include "util/logging.h"
|
||||||
#include "rawinput/rawinput.h"
|
#include "rawinput/rawinput.h"
|
||||||
@@ -9,9 +11,10 @@
|
|||||||
#include "util/tapeled.h"
|
#include "util/tapeled.h"
|
||||||
#include "pc.h"
|
#include "pc.h"
|
||||||
#include "util/utils.h"
|
#include "util/utils.h"
|
||||||
|
#include "util/time.h"
|
||||||
|
#include "util/socd_cleaner.h"
|
||||||
|
|
||||||
namespace games::pc {
|
namespace games::pc {
|
||||||
bool PC_KNOB_MODE = false;
|
|
||||||
|
|
||||||
constexpr float RELATIVE_DECAY = 0.02f;
|
constexpr float RELATIVE_DECAY = 0.02f;
|
||||||
struct FADER_RELATIVE {
|
struct FADER_RELATIVE {
|
||||||
@@ -75,18 +78,22 @@ namespace games::pc {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
struct AIO_SCI_COMM {
|
struct AIO_SCI_COMM {
|
||||||
|
uint8_t data[0xf8];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AIO_NMGR_IOB2 {
|
struct AIO_NMGR_IOB2 {
|
||||||
|
uint8_t data[0xe30];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AIO_IOB2_BI2X_AC1 {
|
struct AIO_IOB2_BI2X_AC1 {
|
||||||
|
uint8_t data[0x4538];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AIO_IOB2_BI2X_AC1__SETTING {
|
struct AIO_IOB2_BI2X_AC1__SETTING {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AIO_IOB2_BI2X_WRFIRM {
|
struct AIO_IOB2_BI2X_WRFIRM {
|
||||||
|
uint8_t data[0x20f48];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AIO_IOB2_BI2X_AC1__INPUT
|
struct AIO_IOB2_BI2X_AC1__INPUT
|
||||||
@@ -191,6 +198,12 @@ namespace games::pc {
|
|||||||
AIO_IOB2_BI2X_AC1__ICNPIN ICnPinHist[20];
|
AIO_IOB2_BI2X_AC1__ICNPIN ICnPinHist[20];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// verified with XIF-2024122300
|
||||||
|
static_assert(sizeof(AIO_SCI_COMM) == 0xf8);
|
||||||
|
static_assert(sizeof(AIO_NMGR_IOB2) == 0xe30);
|
||||||
|
static_assert(sizeof(AIO_IOB2_BI2X_AC1) == 0x4538);
|
||||||
|
static_assert(sizeof(AIO_IOB2_BI2X_WRFIRM) == 0x20f48);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* typedefs
|
* typedefs
|
||||||
*/
|
*/
|
||||||
@@ -338,14 +351,21 @@ namespace games::pc {
|
|||||||
val = (GameAPI::Analogs::getState(RI_MGR, analogs[Analogs::FaderL]) - 0.5f) * 2;
|
val = (GameAPI::Analogs::getState(RI_MGR, analogs[Analogs::FaderL]) - 0.5f) * 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::FaderL_Left]) &&
|
|
||||||
GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::FaderL_Right])) {
|
const auto now = get_performance_milliseconds();
|
||||||
val = 0.f;
|
|
||||||
} else if (GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::FaderL_Left])) {
|
const auto fader_l_socd = socd::socd_clean(
|
||||||
|
0, // Fader-L
|
||||||
|
GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::FaderL_Left]),
|
||||||
|
GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::FaderL_Right]),
|
||||||
|
now);
|
||||||
|
|
||||||
|
if (fader_l_socd == socd::SocdCCW) {
|
||||||
val = -1.0f;
|
val = -1.0f;
|
||||||
} else if (GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::FaderL_Right])) {
|
} else if (fader_l_socd == socd::SocdCW) {
|
||||||
val = +1.0f;
|
val = +1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
o_DevStatus->Input.CN15_7 = (val < 0.2f) ? 0xFF : 0;
|
o_DevStatus->Input.CN15_7 = (val < 0.2f) ? 0xFF : 0;
|
||||||
o_DevStatus->Input.CN15_6 = (val > -0.85f && val < 0.35f) ? 0xFF : 0;
|
o_DevStatus->Input.CN15_6 = (val > -0.85f && val < 0.35f) ? 0xFF : 0;
|
||||||
o_DevStatus->Input.CN15_5 = (val > -0.6f && val < 0.6f) ? 0xFF : 0;
|
o_DevStatus->Input.CN15_5 = (val > -0.6f && val < 0.6f) ? 0xFF : 0;
|
||||||
@@ -363,14 +383,19 @@ namespace games::pc {
|
|||||||
val = (GameAPI::Analogs::getState(RI_MGR, analogs[Analogs::FaderR]) - 0.5f) * 2;
|
val = (GameAPI::Analogs::getState(RI_MGR, analogs[Analogs::FaderR]) - 0.5f) * 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::FaderR_Left]) &&
|
|
||||||
GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::FaderR_Right])) {
|
const auto fader_r_socd = socd::socd_clean(
|
||||||
val = 0.f;
|
1, // Fader-R
|
||||||
} else if (GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::FaderR_Left])) {
|
GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::FaderR_Left]),
|
||||||
|
GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::FaderR_Right]),
|
||||||
|
now);
|
||||||
|
|
||||||
|
if (fader_r_socd == socd::SocdCCW) {
|
||||||
val = -1.0f;
|
val = -1.0f;
|
||||||
} else if (GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::FaderR_Right])) {
|
} else if (fader_r_socd == socd::SocdCW) {
|
||||||
val = +1.0f;
|
val = +1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
o_DevStatus->Input.CN11_20 = (val < 0.2f) ? 0xFF : 0;
|
o_DevStatus->Input.CN11_20 = (val < 0.2f) ? 0xFF : 0;
|
||||||
o_DevStatus->Input.CN11_19 = (val > -0.85f && val < 0.35f) ? 0xFF : 0;
|
o_DevStatus->Input.CN11_19 = (val > -0.85f && val < 0.35f) ? 0xFF : 0;
|
||||||
o_DevStatus->Input.CN9_10 = (val > -0.6f && val < 0.6f) ? 0xFF : 0;
|
o_DevStatus->Input.CN9_10 = (val > -0.6f && val < 0.6f) ? 0xFF : 0;
|
||||||
@@ -737,3 +762,5 @@ namespace games::pc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,5 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#if SPICE64
|
||||||
|
|
||||||
namespace games::pc {
|
namespace games::pc {
|
||||||
void bi2x_hook_init();
|
void bi2x_hook_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -12,10 +12,12 @@
|
|||||||
#include "misc/wintouchemu.h"
|
#include "misc/wintouchemu.h"
|
||||||
#include "hooks/graphics/graphics.h"
|
#include "hooks/graphics/graphics.h"
|
||||||
#include "rawinput/rawinput.h"
|
#include "rawinput/rawinput.h"
|
||||||
|
#include "util/socd_cleaner.h"
|
||||||
|
|
||||||
namespace games::pc {
|
namespace games::pc {
|
||||||
std::string PC_INJECT_ARGS = "";
|
std::string PC_INJECT_ARGS = "";
|
||||||
bool PC_NO_IO = false;
|
bool PC_NO_IO = false;
|
||||||
|
bool PC_KNOB_MODE = false;
|
||||||
|
|
||||||
static acioemu::ACIOHandle *acioHandle = nullptr;
|
static acioemu::ACIOHandle *acioHandle = nullptr;
|
||||||
static std::wstring portName = L"COM1";
|
static std::wstring portName = L"COM1";
|
||||||
@@ -61,6 +63,11 @@ namespace games::pc {
|
|||||||
return ERROR_NOT_SUPPORTED;
|
return ERROR_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PCGame::pre_attach() {
|
||||||
|
// SOCD
|
||||||
|
socd::ALGORITHM = socd::SocdAlgorithm::PreferRecent;
|
||||||
|
}
|
||||||
|
|
||||||
void PCGame::attach() {
|
void PCGame::attach() {
|
||||||
Game::attach();
|
Game::attach();
|
||||||
|
|
||||||
@@ -78,9 +85,14 @@ namespace games::pc {
|
|||||||
execexe::load_library("libaio-iob2_video.dll");
|
execexe::load_library("libaio-iob2_video.dll");
|
||||||
execexe::load_library("win10actlog.dll");
|
execexe::load_library("win10actlog.dll");
|
||||||
|
|
||||||
|
#if SPICE64
|
||||||
|
|
||||||
if (!PC_NO_IO) {
|
if (!PC_NO_IO) {
|
||||||
bi2x_hook_init();
|
bi2x_hook_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const auto user32Dll = "user32.dll";
|
const auto user32Dll = "user32.dll";
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ namespace games::pc {
|
|||||||
public:
|
public:
|
||||||
PCGame() : Game("Polaris Chord") {}
|
PCGame() : Game("Polaris Chord") {}
|
||||||
|
|
||||||
|
virtual void pre_attach() override;
|
||||||
virtual void attach() override;
|
virtual void attach() override;
|
||||||
virtual void detach() override;
|
virtual void detach() override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#include "bi2x_hook.h"
|
#include "bi2x_hook.h"
|
||||||
|
|
||||||
|
#if SPICE64
|
||||||
|
|
||||||
#include "util/detour.h"
|
#include "util/detour.h"
|
||||||
#include "util/logging.h"
|
#include "util/logging.h"
|
||||||
#include "rawinput/rawinput.h"
|
#include "rawinput/rawinput.h"
|
||||||
@@ -15,15 +17,19 @@ namespace games::qks {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
struct AIO_SCI_COMM {
|
struct AIO_SCI_COMM {
|
||||||
|
uint8_t data[0xf8];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AIO_NMGR_IOB {
|
struct AIO_NMGR_IOB {
|
||||||
|
uint8_t data[0xa00];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AIO_IOB2_BI2X_AC1 {
|
struct AIO_IOB2_BI2X_AC1 {
|
||||||
|
uint8_t data[0x3908];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AIO_IOB2_BI2X_WRFIRM {
|
struct AIO_IOB2_BI2X_WRFIRM {
|
||||||
|
uint8_t data[0x20f48];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AIO_NMGR_IOB__NODEINFO {
|
struct AIO_NMGR_IOB__NODEINFO {
|
||||||
@@ -174,6 +180,12 @@ namespace games::qks {
|
|||||||
AIO_IOB2_BI2X_AC1__SETTING Setting;
|
AIO_IOB2_BI2X_AC1__SETTING Setting;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// verified with UKS-001-2024030600
|
||||||
|
static_assert(sizeof(AIO_IOB2_BI2X_AC1) == 0x3908);
|
||||||
|
static_assert(sizeof(AIO_SCI_COMM) == 0xf8);
|
||||||
|
static_assert(sizeof(AIO_NMGR_IOB) == 0xa00);
|
||||||
|
static_assert(sizeof(AIO_IOB2_BI2X_WRFIRM) == 0x20f48);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* typedefs
|
* typedefs
|
||||||
*/
|
*/
|
||||||
@@ -602,4 +614,6 @@ namespace games::qks {
|
|||||||
detour::trampoline_try(libaioDll, "aioNodeCtl_IsError",
|
detour::trampoline_try(libaioDll, "aioNodeCtl_IsError",
|
||||||
aioNodeCtl_IsError, &aioNodeCtl_IsError_orig);
|
aioNodeCtl_IsError, &aioNodeCtl_IsError_orig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#if SPICE64
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
namespace games::qks {
|
namespace games::qks {
|
||||||
void bi2x_hook_init();
|
void bi2x_hook_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -86,9 +86,13 @@ namespace games::qks {
|
|||||||
detour::trampoline_try("execexe.dll", MAKEINTRESOURCE(9),
|
detour::trampoline_try("execexe.dll", MAKEINTRESOURCE(9),
|
||||||
execexe_CreateFileA_hook,&execexe_CreateFileA_orig);
|
execexe_CreateFileA_hook,&execexe_CreateFileA_orig);
|
||||||
|
|
||||||
|
#if SPICE64
|
||||||
|
|
||||||
// insert BI2X hooks
|
// insert BI2X hooks
|
||||||
bi2x_hook_init();
|
bi2x_hook_init();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
// add card reader
|
// add card reader
|
||||||
acioHandle = new acioemu::ACIOHandle(portName.c_str());
|
acioHandle = new acioemu::ACIOHandle(portName.c_str());
|
||||||
devicehook_init_trampoline();
|
devicehook_init_trampoline();
|
||||||
|
|||||||
Reference in New Issue
Block a user