mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-08-01 22:30:42 -07:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a554c8f923 | |||
| 6592191624 | |||
| 164592b16d | |||
| 81f879e7ff |
@@ -1,3 +1,6 @@
|
||||
09/17/2025 [spice2x]
|
||||
Polaris Chord I/O fixes, language shim
|
||||
|
||||
09/16/2025 [spice2x]
|
||||
Add Polaris Chord support
|
||||
Tweak ImGUI theme
|
||||
|
||||
@@ -246,52 +246,66 @@ namespace games::pc {
|
||||
memset(o_DevStatus, 0x00, sizeof(AIO_IOB2_BI2X_AC1__DEVSTATUS));
|
||||
|
||||
auto &buttons = get_buttons();
|
||||
o_DevStatus->Input.CN8_8 = !GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::Test]);
|
||||
o_DevStatus->Input.CN8_9 = !GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::Service]);
|
||||
o_DevStatus->Input.CN8_10 = !GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::CoinMech]);
|
||||
o_DevStatus->Input.CN15_10 = !GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::Headphone]);
|
||||
o_DevStatus->Input.CN15_12 = 0xFF; // Recorder off
|
||||
o_DevStatus->Input.CN8_8 = GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::Test]) ? 0 : 0xFF;
|
||||
o_DevStatus->Input.CN8_9 = GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::Service]) ? 0 : 0xFF;
|
||||
o_DevStatus->Input.CN8_10 = GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::CoinMech]) ? 0 : 0xFF;
|
||||
o_DevStatus->Input.CN15_10 = GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::Headphone]) ? 0 : 0xFF;
|
||||
o_DevStatus->Input.CN15_12 = 0xFF; // Recorder off; present in I/O test menu but unused in game
|
||||
|
||||
o_DevStatus->Input.CN12_11 = !GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::Button1]);
|
||||
o_DevStatus->Input.CN12_12 = !GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::Button2]);
|
||||
o_DevStatus->Input.CN12_13 = !GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::Button3]);
|
||||
o_DevStatus->Input.CN12_14 = !GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::Button4]);
|
||||
o_DevStatus->Input.CN12_15 = !GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::Button5]);
|
||||
o_DevStatus->Input.CN12_16 = !GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::Button6]);
|
||||
o_DevStatus->Input.CN12_17 = !GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::Button7]);
|
||||
o_DevStatus->Input.CN12_18 = !GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::Button8]);
|
||||
o_DevStatus->Input.CN12_19 = !GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::Button9]);
|
||||
o_DevStatus->Input.CN12_20 = !GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::Button10]);
|
||||
o_DevStatus->Input.CN12_21 = !GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::Button11]);
|
||||
o_DevStatus->Input.CN12_22 = !GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::Button12]);
|
||||
o_DevStatus->Input.CN12_11 = GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::Button1]) ? 0 : 0xFF;
|
||||
o_DevStatus->Input.CN12_12 = GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::Button2]) ? 0 : 0xFF;
|
||||
o_DevStatus->Input.CN12_13 = GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::Button3]) ? 0 : 0xFF;
|
||||
o_DevStatus->Input.CN12_14 = GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::Button4]) ? 0 : 0xFF;
|
||||
o_DevStatus->Input.CN12_15 = GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::Button5]) ? 0 : 0xFF;
|
||||
o_DevStatus->Input.CN12_16 = GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::Button6]) ? 0 : 0xFF;
|
||||
o_DevStatus->Input.CN12_17 = GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::Button7]) ? 0 : 0xFF;
|
||||
o_DevStatus->Input.CN12_18 = GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::Button8]) ? 0 : 0xFF;
|
||||
o_DevStatus->Input.CN12_19 = GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::Button9]) ? 0 : 0xFF;
|
||||
o_DevStatus->Input.CN12_20 = GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::Button10]) ? 0 : 0xFF;
|
||||
o_DevStatus->Input.CN12_21 = GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::Button11]) ? 0 : 0xFF;
|
||||
o_DevStatus->Input.CN12_22 = GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::Button12]) ? 0 : 0xFF;
|
||||
|
||||
auto &analogs = get_analogs();
|
||||
|
||||
// FADER-L
|
||||
float val = 0.f;
|
||||
if (analogs[Analogs::FaderL].isSet()) {
|
||||
float val = (GameAPI::Analogs::getState(RI_MGR, analogs[Analogs::FaderL]) - 0.5f) * 2;
|
||||
o_DevStatus->Input.CN15_7 = val < 0.2f;
|
||||
o_DevStatus->Input.CN15_6 = val > -0.85f && val < 0.35f;
|
||||
o_DevStatus->Input.CN15_5 = val > -0.6f && val < 0.6f;
|
||||
o_DevStatus->Input.CN15_4 = val > -0.35f && val < 0.85f;
|
||||
o_DevStatus->Input.CN15_3 = val > -0.2f;
|
||||
} else {
|
||||
o_DevStatus->Input.CN15_7 = GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::FaderL_Left]);
|
||||
o_DevStatus->Input.CN15_3 = GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::FaderL_Right]);
|
||||
o_DevStatus->Input.CN15_5 = !o_DevStatus->Input.CN15_7 && !o_DevStatus->Input.CN15_3;
|
||||
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])) {
|
||||
val = 0.f;
|
||||
} else if (GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::FaderL_Left])) {
|
||||
val = -1.0f;
|
||||
} else if (GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::FaderL_Right])) {
|
||||
val = +1.0f;
|
||||
}
|
||||
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_5 = (val > -0.6f && val < 0.6f) ? 0xFF : 0;
|
||||
o_DevStatus->Input.CN15_4 = (val > -0.35f && val < 0.85f) ? 0xFF : 0;
|
||||
o_DevStatus->Input.CN15_3 = (val > -0.2f) ? 0xFF : 0;
|
||||
|
||||
// FADER-R
|
||||
val = 0.f;
|
||||
if (analogs[Analogs::FaderR].isSet()) {
|
||||
float val = (GameAPI::Analogs::getState(RI_MGR, analogs[Analogs::FaderR]) - 0.5f) * 2;
|
||||
o_DevStatus->Input.CN11_20 = val < 0.2f;
|
||||
o_DevStatus->Input.CN11_19 = val > -0.85f && val < 0.35f;
|
||||
o_DevStatus->Input.CN9_10 = val > -0.6f && val < 0.6f;
|
||||
o_DevStatus->Input.CN9_9 = val > -0.35f && val < 0.85f;
|
||||
o_DevStatus->Input.CN9_8 = val > -0.2f;
|
||||
} else {
|
||||
o_DevStatus->Input.CN11_20 = GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::FaderR_Left]);
|
||||
o_DevStatus->Input.CN9_8 = GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::FaderR_Right]);
|
||||
o_DevStatus->Input.CN9_10 = !o_DevStatus->Input.CN11_20 && !o_DevStatus->Input.CN9_8;
|
||||
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])) {
|
||||
val = 0.f;
|
||||
} else if (GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::FaderR_Left])) {
|
||||
val = -1.0f;
|
||||
} else if (GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::FaderR_Right])) {
|
||||
val = +1.0f;
|
||||
}
|
||||
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.CN9_10 = (val > -0.6f && val < 0.6f) ? 0xFF : 0;
|
||||
o_DevStatus->Input.CN9_9 = (val > -0.35f && val < 0.85f) ? 0xFF : 0;
|
||||
o_DevStatus->Input.CN9_8 = (val > -0.2f) ? 0xFF : 0;
|
||||
|
||||
// coin
|
||||
o_DevStatus->Input.Coin1Count = eamuse_coin_get_stock();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,12 +3,15 @@
|
||||
#include <format>
|
||||
|
||||
#include "bi2x_hook.h"
|
||||
#include "util/detour.h"
|
||||
#include "util/logging.h"
|
||||
#include "util/fileutils.h"
|
||||
#include "util/unity_player.h"
|
||||
#include "util/execexe.h"
|
||||
#include "acioemu/handle.h"
|
||||
#include "misc/wintouchemu.h"
|
||||
#include "hooks/graphics/graphics.h"
|
||||
#include "rawinput/rawinput.h"
|
||||
|
||||
namespace games::pc {
|
||||
std::string PC_INJECT_ARGS = "";
|
||||
@@ -17,6 +20,24 @@ namespace games::pc {
|
||||
static acioemu::ACIOHandle *acioHandle = nullptr;
|
||||
static std::wstring portName = L"COM1";
|
||||
|
||||
static decltype(RegisterRawInputDevices) *RegisterRawInputDevices_orig = nullptr;
|
||||
|
||||
static BOOL WINAPI RegisterRawInputDevices_hook(PCRAWINPUTDEVICE pRawInputDevices, UINT uiNumDevices, UINT cbSize) {
|
||||
|
||||
// if the caller is spice itself, then pass through.
|
||||
if (pRawInputDevices &&
|
||||
(uiNumDevices > 0) &&
|
||||
(pRawInputDevices[0].hwndTarget == RI_MGR->input_hwnd)) {
|
||||
|
||||
return RegisterRawInputDevices_orig(pRawInputDevices, uiNumDevices, cbSize);
|
||||
}
|
||||
|
||||
// otherwise, it must be the game; prevent the game from registering for raw input
|
||||
// and hijacking WM_INPUT messages.
|
||||
SetLastError(0xDEADBEEF);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void PCGame::attach() {
|
||||
Game::attach();
|
||||
|
||||
@@ -39,6 +60,10 @@ namespace games::pc {
|
||||
}
|
||||
});
|
||||
|
||||
const auto user32Dll = "user32.dll";
|
||||
detour::trampoline_try(user32Dll, "RegisterRawInputDevices",
|
||||
RegisterRawInputDevices_hook, &RegisterRawInputDevices_orig);
|
||||
|
||||
|
||||
if (GRAPHICS_SHOW_CURSOR) {
|
||||
unity_utils::force_show_cursor(true);
|
||||
|
||||
@@ -18,6 +18,7 @@ constexpr UINT CODEPAGE_SHIFT_JIS = 932;
|
||||
static decltype(GetACP) *GetACP_orig = nullptr;
|
||||
static decltype(GetOEMCP) *GetOEMCP_orig = nullptr;
|
||||
static decltype(MultiByteToWideChar) *MultiByteToWideChar_orig = nullptr;
|
||||
static decltype(GetLocaleInfoEx) *GetLocaleInfoEx_orig = nullptr;
|
||||
|
||||
#ifdef SPICE64
|
||||
static decltype(GetSystemDefaultLCID) *GetSystemDefaultLCID_orig = nullptr;
|
||||
@@ -119,6 +120,48 @@ static int WINAPI MultiByteToWideChar_hook(
|
||||
cchWideChar);
|
||||
}
|
||||
|
||||
static int WINAPI GetLocaleInfoEx_hook (
|
||||
LPCWSTR lpLocaleName,
|
||||
LCTYPE LCType,
|
||||
LPWSTR lpLCData,
|
||||
int cchData)
|
||||
{
|
||||
|
||||
#if 0
|
||||
if (lpLocaleName == LOCALE_NAME_INVARIANT) {
|
||||
log_misc("hooks::lang", "GetLocaleInfoEx_hook hit (LOCALE_NAME_INVARIANT), {}, {}", LCType, cchData);
|
||||
} else if (lpLocaleName == LOCALE_NAME_SYSTEM_DEFAULT) {
|
||||
log_misc("hooks::lang", "GetLocaleInfoEx_hook hit (LOCALE_NAME_SYSTEM_DEFAULT), {}, {}", LCType, cchData);
|
||||
} else if (lpLocaleName == LOCALE_NAME_USER_DEFAULT) {
|
||||
log_misc("hooks::lang", "GetLocaleInfoEx_hook hit (LOCALE_NAME_USER_DEFAULT), {}, {}", LCType, cchData);
|
||||
} else {
|
||||
log_misc("hooks::lang", "GetLocaleInfoEx_hook hit ({}), {}, {}", ws2s(lpLocaleName), LCType, cchData);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (lpLocaleName == LOCALE_NAME_USER_DEFAULT &&
|
||||
LCType == LOCALE_SISO639LANGNAME &&
|
||||
lpLCData != NULL &&
|
||||
cchData >= 3) {
|
||||
log_misc("hooks::lang",
|
||||
"GetLocaleInfoEx_hook hit (LOCALE_NAME_USER_DEFAULT / LOCALE_SISO639LANGNAME), return `ja`");
|
||||
wcscpy(lpLCData, L"ja");
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (lpLocaleName == LOCALE_NAME_USER_DEFAULT &&
|
||||
LCType == LOCALE_SISO3166CTRYNAME &&
|
||||
lpLCData != NULL &&
|
||||
cchData >= 3) {
|
||||
log_misc("hooks::lang",
|
||||
"GetLocaleInfoEx_hook hit (LOCALE_NAME_USER_DEFAULT / LOCALE_SISO3166CTRYNAME), return `JP`");
|
||||
wcscpy(lpLCData, L"JP");
|
||||
return 3;
|
||||
}
|
||||
|
||||
return GetLocaleInfoEx_orig(lpLocaleName, LCType, lpLCData, cchData);
|
||||
}
|
||||
|
||||
void hooks::lang::early_init() {
|
||||
log_info("hooks::lang", "early initialization");
|
||||
|
||||
@@ -138,6 +181,14 @@ void hooks::lang::early_init() {
|
||||
}
|
||||
#endif
|
||||
|
||||
if (avs::game::is_model("XIF")) {
|
||||
log_info("hooks::lang", "hooking GetLocaleInfoEx");
|
||||
detour::trampoline_try(
|
||||
"kernel32.dll",
|
||||
"GetLocaleInfoEx",
|
||||
GetLocaleInfoEx_hook,
|
||||
&GetLocaleInfoEx_orig);
|
||||
}
|
||||
}
|
||||
|
||||
void hooks::lang::init() {
|
||||
|
||||
@@ -54,7 +54,6 @@ namespace rawinput {
|
||||
|
||||
HotplugManager *hotplug;
|
||||
std::vector<Device> devices;
|
||||
HWND input_hwnd = nullptr;
|
||||
WNDCLASSEX input_hwnd_class {};
|
||||
std::thread *input_thread = nullptr;
|
||||
std::thread *flush_thread = nullptr;
|
||||
@@ -91,6 +90,8 @@ namespace rawinput {
|
||||
|
||||
public:
|
||||
|
||||
HWND input_hwnd = nullptr;
|
||||
|
||||
RawInputManager();
|
||||
~RawInputManager();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user