Gonna be real idk whats in this one chief
This commit is contained in:
parent
3423861c3c
commit
1ca4d5dc30
@ -24,6 +24,7 @@
|
|||||||
#include "../lib/mice/mice.h"
|
#include "../lib/mice/mice.h"
|
||||||
#include "./util/_util.h"
|
#include "./util/_util.h"
|
||||||
#include "micefs.h"
|
#include "micefs.h"
|
||||||
|
#include "input_config.h"
|
||||||
|
|
||||||
#define size2int(x) ((int)((x) & 0x7fffffff))
|
#define size2int(x) ((int)((x) & 0x7fffffff))
|
||||||
#define size2uint(x) ((unsigned int)((x) & 0xffffffff))
|
#define size2uint(x) ((unsigned int)((x) & 0xffffffff))
|
||||||
|
@ -62,6 +62,24 @@ WORD getSensorInRegion(float mX, float mY, float rX, float rY, float rW, float r
|
|||||||
}
|
}
|
||||||
|
|
||||||
static BYTE g_ActiveResponse[14];
|
static BYTE g_ActiveResponse[14];
|
||||||
|
static inline void handleOneButton(int iW, int iH, int iX, int iY) {
|
||||||
|
float x = (float)iX / (float)(iW);
|
||||||
|
float y = (float)iY / (float)(iH);
|
||||||
|
|
||||||
|
// If the window is square, assume `1P_ONLY` is set
|
||||||
|
WORD button;
|
||||||
|
if (iW == iH) {
|
||||||
|
button = getSensorInRegion(x, y, 0.0f, 0.0f, 1.0f, 1.0f);
|
||||||
|
if (button) g_ActiveResponse[button >> 8] |= button & 0xff;
|
||||||
|
} else {
|
||||||
|
// 1P
|
||||||
|
button = getSensorInRegion(x, y, 0.0f, 0.4375f, 0.5f, 0.5625f);
|
||||||
|
if (button) g_ActiveResponse[button >> 8] |= button & 0xff;
|
||||||
|
// 2P
|
||||||
|
button = getSensorInRegion(x, y, 0.5f, 0.4375f, 0.5f, 0.5625f);
|
||||||
|
if (button) g_ActiveResponse[(button >> 8) + 6] |= button & 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
static void populateActiveResponse() {
|
static void populateActiveResponse() {
|
||||||
// Placeholders
|
// Placeholders
|
||||||
g_ActiveResponse[1] = '@';
|
g_ActiveResponse[1] = '@';
|
||||||
@ -74,41 +92,29 @@ static void populateActiveResponse() {
|
|||||||
g_ActiveResponse[9] = '@';
|
g_ActiveResponse[9] = '@';
|
||||||
g_ActiveResponse[10] = '@';
|
g_ActiveResponse[10] = '@';
|
||||||
|
|
||||||
if (!GetAsyncKeyState(VK_LBUTTON)) return;
|
|
||||||
|
|
||||||
POINT pCursor;
|
|
||||||
GetCursorPos(&pCursor);
|
|
||||||
if (!mainWindow) return;
|
if (!mainWindow) return;
|
||||||
if (!ScreenToClient(mainWindow, &pCursor)) return;
|
|
||||||
|
|
||||||
RECT winRect;
|
RECT winRect;
|
||||||
if (!GetWindowRect(mainWindow, &winRect)) return;
|
if (!GetWindowRect(mainWindow, &winRect)) return;
|
||||||
DWORD dwStyle = GetWindowLongW(mainWindow, GWL_STYLE);
|
DWORD dwStyle = GetWindowLongW(mainWindow, GWL_STYLE);
|
||||||
UnadjustWindowRect(&winRect, dwStyle, FALSE);
|
UnadjustWindowRect(&winRect, dwStyle, FALSE);
|
||||||
|
|
||||||
int w = winRect.right - winRect.left;
|
int w = winRect.right - winRect.left;
|
||||||
int h = winRect.bottom - winRect.top;
|
int h = winRect.bottom - winRect.top;
|
||||||
|
|
||||||
float x = (float)pCursor.x / (float)(w);
|
if (GetAsyncKeyState(VK_LBUTTON)) {
|
||||||
float y = (float)pCursor.y / (float)(h);
|
POINT pCursor;
|
||||||
|
GetCursorPos(&pCursor);
|
||||||
|
if (ScreenToClient(mainWindow, &pCursor)) {
|
||||||
|
handleOneButton(w, h, pCursor.x, pCursor.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If the window is square, assume `1P_ONLY` is set
|
for (DWORD i = 0; i < nActiveTouches; i++) {
|
||||||
WORD button;
|
handleOneButton(w, h, activeTouches[i].m_X, activeTouches[i].m_Y);
|
||||||
if (w == h) {
|
|
||||||
button = getSensorInRegion(x, y, 0.0f, 0.0f, 1.0f, 1.0f);
|
|
||||||
if (button) g_ActiveResponse[button >> 8] |= button & 0xff;
|
|
||||||
} else {
|
|
||||||
// 1P
|
|
||||||
button = getSensorInRegion(x, y, 0.0f, 0.4375f, 0.5f, 0.5625f);
|
|
||||||
if (button) g_ActiveResponse[button >> 8] |= button & 0xff;
|
|
||||||
// 2P
|
|
||||||
button = getSensorInRegion(x, y, 0.5f, 0.4375f, 0.5f, 0.5625f);
|
|
||||||
if (button) g_ActiveResponse[(button >> 8) + 6] |= button & 0xff;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL touch_is_enabled = TRUE; // Default on is important!
|
BOOL touch_is_enabled = TRUE; // Default on is important!
|
||||||
BYTE thresh = 0x00; // Lazy caching of single value
|
BYTE thresh = 0x00; // Lazy caching of single value
|
||||||
DWORD WINAPI touch_bd_thread(com_device_t* dev) {
|
DWORD WINAPI touch_bd_thread(com_device_t* dev) {
|
||||||
log_info(plfMaiTouch, "%ls woke up", dev->com->wName);
|
log_info(plfMaiTouch, "%ls woke up", dev->com->wName);
|
||||||
|
|
||||||
@ -124,7 +130,7 @@ DWORD WINAPI touch_bd_thread(com_device_t* dev) {
|
|||||||
if (touch_is_enabled && !comdev_available(dev)) {
|
if (touch_is_enabled && !comdev_available(dev)) {
|
||||||
populateActiveResponse();
|
populateActiveResponse();
|
||||||
comdev_write(dev, g_ActiveResponse, 14);
|
comdev_write(dev, g_ActiveResponse, 14);
|
||||||
Sleep(5); // 200Hz should be plenty
|
Sleep(2);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,9 +43,9 @@ void set_eeprom_static_config() {
|
|||||||
.m_Rental = MiceConfig.sysconf.rental,
|
.m_Rental = MiceConfig.sysconf.rental,
|
||||||
};
|
};
|
||||||
ZeroMemory(Static.m_strSerialId, sizeof Static.m_strSerialId);
|
ZeroMemory(Static.m_strSerialId, sizeof Static.m_strSerialId);
|
||||||
DWORD len = strlen(MiceConfig.sysconf.serial);
|
DWORD len = strlen(MiceConfig.sysconf.pcb_serial);
|
||||||
if (len > sizeof Static.m_strSerialId - 1) len = sizeof Static.m_strSerialId - 1;
|
if (len > sizeof Static.m_strSerialId - 1) len = sizeof Static.m_strSerialId - 1;
|
||||||
memcpy(Static.m_strSerialId, MiceConfig.sysconf.serial, len);
|
memcpy(Static.m_strSerialId, MiceConfig.sysconf.pcb_serial, len);
|
||||||
fix_crc(Static);
|
fix_crc(Static);
|
||||||
memcpy(&EEPROM_DATA[AM_SYSDATAwH_STATIC_REG], &Static, sizeof Static);
|
memcpy(&EEPROM_DATA[AM_SYSDATAwH_STATIC_REG], &Static, sizeof Static);
|
||||||
memcpy(&EEPROM_DATA[AM_SYSDATAwH_STATIC_DUP], &Static, sizeof Static);
|
memcpy(&EEPROM_DATA[AM_SYSDATAwH_STATIC_DUP], &Static, sizeof Static);
|
||||||
|
@ -59,13 +59,14 @@ void prebind_hooks() {
|
|||||||
void init_injection(HMODULE hModule) {
|
void init_injection(HMODULE hModule) {
|
||||||
WideCharToMultiByte(CP_ACP, 0, exeName, -1, exeNameC, sizeof exeNameC, NULL, NULL);
|
WideCharToMultiByte(CP_ACP, 0, exeName, -1, exeNameC, sizeof exeNameC, NULL, NULL);
|
||||||
|
|
||||||
|
// We're in a new context now, so need to reconfigure
|
||||||
|
setup_logging();
|
||||||
// Make sure our CRC32 tables are ready for anything that might want to use them
|
// Make sure our CRC32 tables are ready for anything that might want to use them
|
||||||
amiCrc32RInit();
|
amiCrc32RInit();
|
||||||
|
|
||||||
load_mice_config();
|
load_mice_config();
|
||||||
|
load_keybind_config();
|
||||||
|
|
||||||
// We're in a new context now, so need to reconfigure
|
|
||||||
setup_logging();
|
|
||||||
MiceSetLogBasename(exeNameC);
|
MiceSetLogBasename(exeNameC);
|
||||||
log_info(plfBoot, "Handover complete. Now executing within %ls", exeName);
|
log_info(plfBoot, "Handover complete. Now executing within %ls", exeName);
|
||||||
|
|
||||||
@ -126,10 +127,7 @@ void init_injection(HMODULE hModule) {
|
|||||||
// MX SuperIO: Communicate with the HW monitor chip
|
// MX SuperIO: Communicate with the HW monitor chip
|
||||||
if (MiceConfig.drivers.mxsuperio) setup_mxsuperio();
|
if (MiceConfig.drivers.mxsuperio) setup_mxsuperio();
|
||||||
// MX JVS: Interacting with JVS-based devices
|
// MX JVS: Interacting with JVS-based devices
|
||||||
if (MiceConfig.drivers.mxjvs) {
|
if (MiceConfig.drivers.mxjvs) setup_mxjvs();
|
||||||
setup_mxjvs();
|
|
||||||
load_keybind_config();
|
|
||||||
}
|
|
||||||
// MX HW Reset: Forcibly reboot the machine
|
// MX HW Reset: Forcibly reboot the machine
|
||||||
if (MiceConfig.drivers.mxhwreset) setup_mxhwreset();
|
if (MiceConfig.drivers.mxhwreset) setup_mxhwreset();
|
||||||
// MX SMBus: Communicate over the LPC bus. This contains the EEPROM, and PCA9535
|
// MX SMBus: Communicate over the LPC bus. This contains the EEPROM, and PCA9535
|
||||||
|
@ -70,5 +70,3 @@ static inline void MiceJvsWrite(PMICE_JVS this, BYTE data) {
|
|||||||
if (this->m_lpOutData == NULL) return;
|
if (this->m_lpOutData == NULL) return;
|
||||||
if (this->m_nOutIdx < MICE_JVS_MAX) this->m_lpOutData[this->m_nOutIdx++] = data;
|
if (this->m_nOutIdx < MICE_JVS_MAX) this->m_lpOutData[this->m_nOutIdx++] = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern MICE_JVS _MiceJvsBoards[JVS_IO_MAX];
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
|
||||||
#include "../../common.h"
|
#include "../../common.h"
|
||||||
#include "jvs.h"
|
|
||||||
|
|
||||||
#define PLAYER_COUNT 2
|
#define PLAYER_COUNT 2
|
||||||
#define COIN_COUNTERS 2
|
#define COIN_COUNTERS 2
|
||||||
@ -24,15 +23,20 @@ static void Ctor(PMICE_JVS this) {
|
|||||||
this->m_VersionComm = 0x10;
|
this->m_VersionComm = 0x10;
|
||||||
|
|
||||||
// Coin + Test + 13 switches per player
|
// Coin + Test + 13 switches per player
|
||||||
this->m_ButtonsPerPlayer = PLAYER_SWITCH_COUNT;
|
if (this->m_ButtonsPerPlayer == 0) this->m_ButtonsPerPlayer = PLAYER_SWITCH_COUNT;
|
||||||
this->m_Coins = COIN_COUNTERS;
|
if (this->m_Coins == 0) this->m_Coins = COIN_COUNTERS;
|
||||||
this->m_Players = PLAYER_COUNT;
|
if (this->m_Players == 0) this->m_Players = PLAYER_COUNT;
|
||||||
|
|
||||||
this->m_NumButtons = this->m_Coins + 1 + (this->m_ButtonsPerPlayer * this->m_Players);
|
if (this->m_NumButtons == 0)
|
||||||
this->m_ButtonStates = malloc(this->m_NumButtons * sizeof *this->m_ButtonStates);
|
this->m_NumButtons = this->m_Coins + 1 + (this->m_ButtonsPerPlayer * this->m_Players);
|
||||||
ZeroMemory(this->m_ButtonStates, this->m_NumButtons * sizeof *this->m_ButtonStates);
|
if (this->m_ButtonStates == NULL) {
|
||||||
this->m_Bindings = malloc(this->m_NumButtons * sizeof *this->m_Bindings);
|
this->m_ButtonStates = malloc(this->m_NumButtons * sizeof *this->m_ButtonStates);
|
||||||
ZeroMemory(this->m_Bindings, this->m_NumButtons * sizeof *this->m_Bindings);
|
ZeroMemory(this->m_ButtonStates, this->m_NumButtons * sizeof *this->m_ButtonStates);
|
||||||
|
}
|
||||||
|
if (this->m_Bindings == NULL) {
|
||||||
|
this->m_Bindings = malloc(this->m_NumButtons * sizeof *this->m_Bindings);
|
||||||
|
ZeroMemory(this->m_Bindings, this->m_NumButtons * sizeof *this->m_Bindings);
|
||||||
|
}
|
||||||
|
|
||||||
ZeroMemory(this->m_CoinCounts, sizeof this->m_CoinCounts);
|
ZeroMemory(this->m_CoinCounts, sizeof this->m_CoinCounts);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
|
||||||
#include "../../common.h"
|
#include "../../common.h"
|
||||||
#include "jvs.h"
|
|
||||||
|
|
||||||
#define PLAYER_COUNT 1
|
#define PLAYER_COUNT 1
|
||||||
#define COIN_COUNTERS 2
|
#define COIN_COUNTERS 2
|
||||||
@ -88,20 +87,12 @@ static JVS_STATUS Transact(PMICE_JVS this, BYTE command) {
|
|||||||
unsigned char coin_count;
|
unsigned char coin_count;
|
||||||
coin_count = MiceJvsRead(this);
|
coin_count = MiceJvsRead(this);
|
||||||
|
|
||||||
// int coin1 = jvsKeybindings[board->num].buttons[0];
|
if (MiceInputGetButtonState(&(this->m_Bindings[0]))) this->m_CoinCounts[0]++;
|
||||||
// int coin2 = jvsKeybindings[board->num].buttons[1];
|
if (MiceInputGetButtonState(&(this->m_Bindings[1]))) this->m_CoinCounts[1]++;
|
||||||
|
|
||||||
// if (coin1 && GetAsyncKeyState(coin1) & 1) board->coin_counts[0]++;
|
|
||||||
// if (coin2 && GetAsyncKeyState(coin2) & 1) board->coin_counts[1]++;
|
|
||||||
|
|
||||||
// for (unsigned char slot = 0; slot < coin_count; slot++) {
|
|
||||||
// MiceJvsWrite(this, board->coin_counts[slot] >> 8);
|
|
||||||
// MiceJvsWrite(this, board->coin_counts[slot] & 0xff);
|
|
||||||
// }
|
|
||||||
|
|
||||||
for (unsigned char slot = 0; slot < coin_count; slot++) {
|
for (unsigned char slot = 0; slot < coin_count; slot++) {
|
||||||
MiceJvsWrite(this, 0);
|
MiceJvsWrite(this, this->m_CoinCounts[slot] >> 8);
|
||||||
MiceJvsWrite(this, 0);
|
MiceJvsWrite(this, this->m_CoinCounts[slot] & 0xff);
|
||||||
}
|
}
|
||||||
return JVS_STATUS_OK;
|
return JVS_STATUS_OK;
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
|
||||||
#include "../../common.h"
|
#include "../../common.h"
|
||||||
#include "jvs.h"
|
|
||||||
|
|
||||||
static void Ctor(PMICE_JVS this) {
|
static void Ctor(PMICE_JVS this) {
|
||||||
this->vftable = &_MiceJvsBase_vftable;
|
this->vftable = &_MiceJvsBase_vftable;
|
||||||
|
@ -4,10 +4,9 @@
|
|||||||
#include "../common.h"
|
#include "../common.h"
|
||||||
#include "../input.h"
|
#include "../input.h"
|
||||||
#include "../key_config.h"
|
#include "../key_config.h"
|
||||||
#include "jvs_boards/jvs.h"
|
|
||||||
#include "mx.h"
|
#include "mx.h"
|
||||||
|
|
||||||
#define JVS_SENSE (MiceConfig.keys.board_count == 0 ? FALSE : _MiceJvsBoards[0].m_SenseOut)
|
#define JVS_SENSE (g_MiceJvsNumBoards == 0 ? FALSE : _MiceJvsBoards[0].m_SenseOut)
|
||||||
|
|
||||||
JVS_STATUS MiceJvsWrapper(PMICE_JVS this, DWORD nMaxRead) {
|
JVS_STATUS MiceJvsWrapper(PMICE_JVS this, DWORD nMaxRead) {
|
||||||
JVS_STATUS status = JVS_STATUS_OK;
|
JVS_STATUS status = JVS_STATUS_OK;
|
||||||
@ -38,11 +37,35 @@ void jvs_send_status(unsigned char status, unsigned char* outData, LPDWORD outCo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static float jvsRateAccum;
|
||||||
|
static float jvsDTHistory[60];
|
||||||
|
static size_t jvsDTHIndex = 0;
|
||||||
|
static size_t jvsDTHCount = 0;
|
||||||
|
float jvsRate = 0;
|
||||||
|
|
||||||
BYTE jvsInUnmasked[MICE_JVS_MAX];
|
BYTE jvsInUnmasked[MICE_JVS_MAX];
|
||||||
BYTE jvsOutUnmasked[MICE_JVS_MAX];
|
BYTE jvsOutUnmasked[MICE_JVS_MAX];
|
||||||
BYTE jvsOutMasked[MICE_JVS_MASKED];
|
BYTE jvsOutMasked[MICE_JVS_MASKED];
|
||||||
void mxjvs_handle(unsigned char* lpMaskedIn, short nMaskedCount, unsigned char* outData,
|
void mxjvs_handle(unsigned char* lpMaskedIn, short nMaskedCount, unsigned char* outData,
|
||||||
short maxOut, LPDWORD outCount) {
|
short maxOut, LPDWORD outCount) {
|
||||||
|
// Poll rate calculation
|
||||||
|
static amtime_t last_tick = { .seconds = 0, .microseconds = 0 };
|
||||||
|
amtime_t now;
|
||||||
|
amiTimerGet(&now);
|
||||||
|
|
||||||
|
float dt = (float)amiTimerDiffUsec(&last_tick, &now) / (float)1000000;
|
||||||
|
if (last_tick.seconds != 0 || last_tick.microseconds != 0) {
|
||||||
|
jvsRateAccum += dt - jvsDTHistory[jvsDTHIndex];
|
||||||
|
jvsDTHistory[jvsDTHIndex] = dt;
|
||||||
|
if ((++jvsDTHIndex) == _countof(jvsDTHistory)) jvsDTHIndex = 0;
|
||||||
|
if ((++jvsDTHCount) > _countof(jvsDTHistory)) jvsDTHCount = _countof(jvsDTHistory);
|
||||||
|
|
||||||
|
jvsRate = (jvsRateAccum > 0.0f) ? (1.0f / (jvsRateAccum / (float)jvsDTHCount)) : FLT_MAX;
|
||||||
|
}
|
||||||
|
last_tick = now;
|
||||||
|
|
||||||
|
// Actual handler start
|
||||||
|
|
||||||
SHORT nIn = 0;
|
SHORT nIn = 0;
|
||||||
BOOL wasMark = FALSE;
|
BOOL wasMark = FALSE;
|
||||||
for (int i = 0; i < nMaskedCount; i++) {
|
for (int i = 0; i < nMaskedCount; i++) {
|
||||||
@ -81,7 +104,7 @@ void mxjvs_handle(unsigned char* lpMaskedIn, short nMaskedCount, unsigned char*
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD nBoardCount = MiceConfig.keys.board_count;
|
DWORD nBoardCount = g_MiceJvsNumBoards;
|
||||||
if (nBoardCount > _countof(_MiceJvsBoards)) nBoardCount = _countof(_MiceJvsBoards);
|
if (nBoardCount > _countof(_MiceJvsBoards)) nBoardCount = _countof(_MiceJvsBoards);
|
||||||
|
|
||||||
// Not broadcast, not master-bound, and within bounds
|
// Not broadcast, not master-bound, and within bounds
|
||||||
|
@ -2,10 +2,12 @@
|
|||||||
|
|
||||||
#include "../../sysconf.h"
|
#include "../../sysconf.h"
|
||||||
|
|
||||||
BYTE parallel_flags = 0x00;
|
static HANDLE parallel_ctrl_changed_event = NULL;
|
||||||
BYTE parallel_ctrl = 0x00;
|
|
||||||
BYTE parallel_status = 0x00;
|
static BYTE parallel_flags = 0x00;
|
||||||
BYTE parallel_data = 0x00;
|
static BYTE parallel_ctrl = 0x00;
|
||||||
|
static BYTE parallel_status = 0x00;
|
||||||
|
static BYTE parallel_data = 0x00;
|
||||||
|
|
||||||
BYTE KEYCHIP_ID[16] = KEY_ID;
|
BYTE KEYCHIP_ID[16] = KEY_ID;
|
||||||
BYTE _MAIN_ID[16] = MAIN_ID;
|
BYTE _MAIN_ID[16] = MAIN_ID;
|
||||||
@ -71,6 +73,7 @@ BOOL WINAPI mxparallel_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCod
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
case IOCTL_MXPARALLEL_WRITE_CTRL_PORT:
|
case IOCTL_MXPARALLEL_WRITE_CTRL_PORT:
|
||||||
parallel_ctrl = ((LPBYTE)lpInBuffer)[0];
|
parallel_ctrl = ((LPBYTE)lpInBuffer)[0];
|
||||||
|
SetEvent(parallel_ctrl_changed_event);
|
||||||
// log_warning(plfMxParallel, "Write ctrl %08x", parallel_ctrl);
|
// log_warning(plfMxParallel, "Write ctrl %08x", parallel_ctrl);
|
||||||
outLen(0);
|
outLen(0);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -101,12 +104,12 @@ BOOL WINAPI mxparallel_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCod
|
|||||||
void micexkTransportSend(unsigned char* send_data, int nbytes) {
|
void micexkTransportSend(unsigned char* send_data, int nbytes) {
|
||||||
setAck;
|
setAck;
|
||||||
for (int i = 0; i < nbytes; i++) {
|
for (int i = 0; i < nbytes; i++) {
|
||||||
while (_Strobe) YieldProcessor();
|
WaitForNotStrobe;
|
||||||
setBusy;
|
setBusy;
|
||||||
parallel_data = send_data[i];
|
parallel_data = send_data[i];
|
||||||
while (!_Strobe) YieldProcessor();
|
WaitForStrobe;
|
||||||
clearBusy;
|
clearBusy;
|
||||||
while (_Strobe) YieldProcessor();
|
WaitForNotStrobe;
|
||||||
}
|
}
|
||||||
clearAck;
|
clearAck;
|
||||||
}
|
}
|
||||||
@ -120,10 +123,10 @@ void micexkSendPacket(unsigned char* send_data) {
|
|||||||
void micexkTransportRecv(unsigned char* buffer, int nbytes) {
|
void micexkTransportRecv(unsigned char* buffer, int nbytes) {
|
||||||
for (int i = 0; i < nbytes; i++) {
|
for (int i = 0; i < nbytes; i++) {
|
||||||
clearBusy;
|
clearBusy;
|
||||||
while (!_Strobe) YieldProcessor();
|
WaitForStrobe;
|
||||||
buffer[i] = parallel_data;
|
buffer[i] = parallel_data;
|
||||||
setBusy;
|
setBusy;
|
||||||
while (_Strobe) YieldProcessor();
|
WaitForNotStrobe;
|
||||||
clearBusy;
|
clearBusy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -450,6 +453,8 @@ void setup_mxparallel() {
|
|||||||
|
|
||||||
init_nv_storage();
|
init_nv_storage();
|
||||||
|
|
||||||
|
parallel_ctrl_changed_event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||||
|
|
||||||
file_hook_t* mxparallel = new_file_hook(L"\\\\.\\mxparallel");
|
file_hook_t* mxparallel = new_file_hook(L"\\\\.\\mxparallel");
|
||||||
mxparallel->DeviceIoControl = &mxparallel_DeviceIoControl;
|
mxparallel->DeviceIoControl = &mxparallel_DeviceIoControl;
|
||||||
hook_file(mxparallel);
|
hook_file(mxparallel);
|
||||||
|
@ -17,7 +17,6 @@ typedef struct {
|
|||||||
} nvram_data_block_t;
|
} nvram_data_block_t;
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
|
||||||
void micexkTransportSend(unsigned char* send_data, int nbytes);
|
void micexkTransportSend(unsigned char* send_data, int nbytes);
|
||||||
void micexkSendPacket(unsigned char* send_data);
|
void micexkSendPacket(unsigned char* send_data);
|
||||||
void micexkTransportRecv(unsigned char* buffer, int nbytes);
|
void micexkTransportRecv(unsigned char* buffer, int nbytes);
|
||||||
@ -59,3 +58,17 @@ static BYTE parallel_data;
|
|||||||
#define _Reset getControl(0x04)
|
#define _Reset getControl(0x04)
|
||||||
#define _SelPrint getControl(0x08)
|
#define _SelPrint getControl(0x08)
|
||||||
#define _IsDirWrite getControl(0x20)
|
#define _IsDirWrite getControl(0x20)
|
||||||
|
|
||||||
|
#define WaitForStrobe \
|
||||||
|
do { \
|
||||||
|
while (!_Strobe) WaitForSingleObject(parallel_ctrl_changed_event, INFINITE); \
|
||||||
|
/* Awful way to release any other threads too */ \
|
||||||
|
SetEvent(parallel_ctrl_changed_event); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define WaitForNotStrobe \
|
||||||
|
do { \
|
||||||
|
while (_Strobe) WaitForSingleObject(parallel_ctrl_changed_event, INFINITE); \
|
||||||
|
/* Awful way to release any other threads too */ \
|
||||||
|
SetEvent(parallel_ctrl_changed_event); \
|
||||||
|
} while (0)
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "devices/_devices.h"
|
#include "devices/_devices.h"
|
||||||
#include "drivers/jvs_boards/jvs.h"
|
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "key_config.h"
|
#include "key_config.h"
|
||||||
|
|
||||||
@ -110,7 +109,7 @@ void _MiceSetupMaimai() {
|
|||||||
MiceConfig.sysconf.dipsw = 0b01111000;
|
MiceConfig.sysconf.dipsw = 0b01111000;
|
||||||
MiceConfig.window.nosize = true;
|
MiceConfig.window.nosize = true;
|
||||||
|
|
||||||
if (MiceConfig.keys.board_count == 0) MiceConfig.keys.board_count = 1;
|
g_MiceJvsNumBoards = 1;
|
||||||
|
|
||||||
free(_MiceJvsBoards[0].m_Bindings);
|
free(_MiceJvsBoards[0].m_Bindings);
|
||||||
_MiceJvsBoards[0].m_Bindings = malloc(sizeof maimaiDefaultBindings);
|
_MiceJvsBoards[0].m_Bindings = malloc(sizeof maimaiDefaultBindings);
|
||||||
@ -123,6 +122,9 @@ void _MiceSetupMaimai() {
|
|||||||
_MiceJvsBoards[0].m_ButtonStates =
|
_MiceJvsBoards[0].m_ButtonStates =
|
||||||
malloc(_countof(maimaiDefaultBindings) * sizeof *_MiceJvsBoards[0].m_ButtonStates);
|
malloc(_countof(maimaiDefaultBindings) * sizeof *_MiceJvsBoards[0].m_ButtonStates);
|
||||||
|
|
||||||
|
save_keybind_config();
|
||||||
|
load_keybind_config();
|
||||||
|
|
||||||
// Maimai is going to check if these exist. They do, now.
|
// Maimai is going to check if these exist. They do, now.
|
||||||
make_dirs(MiceIpcRelativePath("dev\\w\\maimai"));
|
make_dirs(MiceIpcRelativePath("dev\\w\\maimai"));
|
||||||
make_dirs(MiceIpcRelativePath("dev\\v\\maimai"));
|
make_dirs(MiceIpcRelativePath("dev\\v\\maimai"));
|
||||||
@ -139,7 +141,7 @@ void _MiceSetupApm() {
|
|||||||
|
|
||||||
MiceConfig.sysconf.dipsw = 0b01000000; // 720p
|
MiceConfig.sysconf.dipsw = 0b01000000; // 720p
|
||||||
|
|
||||||
if (MiceConfig.keys.board_count == 0) MiceConfig.keys.board_count = 1;
|
g_MiceJvsNumBoards = 1;
|
||||||
|
|
||||||
free(_MiceJvsBoards[0].m_Bindings);
|
free(_MiceJvsBoards[0].m_Bindings);
|
||||||
_MiceJvsBoards[0].m_Bindings = malloc(sizeof apmDefaultBindings);
|
_MiceJvsBoards[0].m_Bindings = malloc(sizeof apmDefaultBindings);
|
||||||
@ -151,6 +153,8 @@ void _MiceSetupApm() {
|
|||||||
free(_MiceJvsBoards[0].m_ButtonStates);
|
free(_MiceJvsBoards[0].m_ButtonStates);
|
||||||
_MiceJvsBoards[0].m_ButtonStates =
|
_MiceJvsBoards[0].m_ButtonStates =
|
||||||
malloc(_countof(apmDefaultBindings) * sizeof *_MiceJvsBoards[0].m_ButtonStates);
|
malloc(_countof(apmDefaultBindings) * sizeof *_MiceJvsBoards[0].m_ButtonStates);
|
||||||
|
|
||||||
|
save_keybind_config();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _MiceGotGameId(char game_id[4]) {
|
void _MiceGotGameId(char game_id[4]) {
|
||||||
@ -173,44 +177,7 @@ void _MiceGotGameId(char game_id[4]) {
|
|||||||
_MiceSetupMaimai();
|
_MiceSetupMaimai();
|
||||||
} else if (IS_GAME(SBYG /* APM2 */) || IS_GAME(SDCM /* UNIB */)) {
|
} else if (IS_GAME(SBYG /* APM2 */) || IS_GAME(SDCM /* UNIB */)) {
|
||||||
log_info(plfBoot, "Detect game APM2");
|
log_info(plfBoot, "Detect game APM2");
|
||||||
|
|
||||||
_MiceSetupApm();
|
_MiceSetupApm();
|
||||||
|
|
||||||
// MiceConfig.devices.com1 = "";
|
|
||||||
// MiceConfig.devices.com2 = "";
|
|
||||||
// MiceConfig.devices.com3 = "";
|
|
||||||
// MiceConfig.devices.com5 = "";
|
|
||||||
// MiceConfig.devices.com6 = "";
|
|
||||||
// MiceConfig.devices.com7 = "";
|
|
||||||
// MiceConfig.devices.com8 = "";
|
|
||||||
|
|
||||||
// if (MiceConfig.keys.board_count == 0) MiceConfig.keys.board_count = 1;
|
|
||||||
|
|
||||||
// if (!jvsKeybindings[0].notdefault) {
|
|
||||||
// puts("!!");
|
|
||||||
|
|
||||||
// // Zero all buttons
|
|
||||||
// memset(&jvsKeybindings[0].buttons[3 * 2], 0, 12 * 2);
|
|
||||||
// memset(&jvsKeybindings[0].invert[3 * 2], 0, 12 * 2);
|
|
||||||
|
|
||||||
// jvsKeybindings[0].buttons[0 * 2] = VK_BACK;
|
|
||||||
// jvsKeybindings[0].buttons[1 * 2] = VK_RETURN;
|
|
||||||
|
|
||||||
// jvsKeybindings[0].buttons[3 * 2] = VK_UP;
|
|
||||||
// jvsKeybindings[0].buttons[4 * 2] = VK_DOWN;
|
|
||||||
// jvsKeybindings[0].buttons[5 * 2] = VK_LEFT;
|
|
||||||
// jvsKeybindings[0].buttons[6 * 2] = VK_RIGHT;
|
|
||||||
|
|
||||||
// jvsKeybindings[0].buttons[7 * 2] = 'Q';
|
|
||||||
// jvsKeybindings[0].buttons[8 * 2] = 'W';
|
|
||||||
// jvsKeybindings[0].buttons[9 * 2] = 'E';
|
|
||||||
// jvsKeybindings[0].buttons[10 * 2] = 'A';
|
|
||||||
// jvsKeybindings[0].buttons[11 * 2] = 'S';
|
|
||||||
// jvsKeybindings[0].buttons[12 * 2] = 'D';
|
|
||||||
|
|
||||||
// // 2P is unbound by default, as a (nice) keymap with both
|
|
||||||
// // will probably also involve changing 1P too.
|
|
||||||
// }
|
|
||||||
} else if (IS_GAME(SBVH /* Sega & Sonic All-Stars Racing Arcade */)) {
|
} else if (IS_GAME(SBVH /* Sega & Sonic All-Stars Racing Arcade */)) {
|
||||||
log_info(plfBoot, "Detect game Sega & Sonic All-Stars Racing Arcade");
|
log_info(plfBoot, "Detect game Sega & Sonic All-Stars Racing Arcade");
|
||||||
|
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
#ifndef CIMGUI_DEFINE_ENUMS_AND_STRUCTS
|
#ifndef CIMGUI_DEFINE_ENUMS_AND_STRUCTS
|
||||||
#define CIMGUI_DEFINE_ENUMS_AND_STRUCTS
|
#define CIMGUI_DEFINE_ENUMS_AND_STRUCTS
|
||||||
#endif
|
#endif
|
||||||
|
#include "../common.h"
|
||||||
#include "../devices/smb_at24c64an.h"
|
#include "../devices/smb_at24c64an.h"
|
||||||
#include "../drivers/jvs_boards/jvs.h"
|
|
||||||
#include "../key_config.h"
|
#include "../key_config.h"
|
||||||
#include "cimgui.h"
|
#include "cimgui.h"
|
||||||
#include "imgui/backends/GL/freeglut.h"
|
#include "imgui/backends/GL/freeglut.h"
|
||||||
@ -152,6 +152,7 @@ void hud_card(ImGuiKey open_key) {
|
|||||||
igEnd();
|
igEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern float jvsRate;
|
||||||
void hud_fps() {
|
void hud_fps() {
|
||||||
if (igBegin("FPS", NULL,
|
if (igBegin("FPS", NULL,
|
||||||
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse |
|
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse |
|
||||||
@ -167,6 +168,7 @@ void hud_fps() {
|
|||||||
|
|
||||||
igText("FPS: %.1f", io->Framerate);
|
igText("FPS: %.1f", io->Framerate);
|
||||||
igText(" dT: %.2fms", 1000 / io->Framerate);
|
igText(" dT: %.2fms", 1000 / io->Framerate);
|
||||||
|
igText("JVS Rate: %.2f", jvsRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
igEnd();
|
igEnd();
|
||||||
@ -422,16 +424,19 @@ void tab_settings_system() {
|
|||||||
// The 'M' prefix isn't technically foolproof, but it's good enough for a simple help message
|
// The 'M' prefix isn't technically foolproof, but it's good enough for a simple help message
|
||||||
staticChanged |= AddSettingString(
|
staticChanged |= AddSettingString(
|
||||||
"PCB serial number",
|
"PCB serial number",
|
||||||
(MiceConfig.sysconf.serial && MiceConfig.sysconf.serial[0] == 'M' ? SERIAL_HELP : NULL),
|
(MiceConfig.sysconf.pcb_serial && MiceConfig.sysconf.pcb_serial[0] == 'M' ? SERIAL_HELP
|
||||||
&MiceConfig.sysconf.serial);
|
: NULL),
|
||||||
|
&MiceConfig.sysconf.pcb_serial);
|
||||||
if (staticChanged) {
|
if (staticChanged) {
|
||||||
build_eeprom();
|
build_eeprom();
|
||||||
save_current_config(false);
|
save_current_config(false);
|
||||||
}
|
}
|
||||||
if (AddSettingString(
|
if (AddSettingString(
|
||||||
"Keychip serial number",
|
"Keychip serial number",
|
||||||
(MiceConfig.sysconf.keyid && MiceConfig.sysconf.keyid[0] == 'M' ? SERIAL_HELP : NULL),
|
(MiceConfig.sysconf.keychip_serial && MiceConfig.sysconf.keychip_serial[0] == 'M'
|
||||||
&MiceConfig.sysconf.keyid)) {
|
? SERIAL_HELP
|
||||||
|
: NULL),
|
||||||
|
&MiceConfig.sysconf.keychip_serial)) {
|
||||||
save_current_config(false);
|
save_current_config(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -789,16 +794,16 @@ void AddSettingButton(PMICE_JVS board, int player, int button) {
|
|||||||
igSameLine(0, -1);
|
igSameLine(0, -1);
|
||||||
if (igButton(clear, vec0)) {
|
if (igButton(clear, vec0)) {
|
||||||
bind->m_Type = MICE_BB_TYPE_UNBOUND;
|
bind->m_Type = MICE_BB_TYPE_UNBOUND;
|
||||||
save_current_config(false);
|
save_keybind_config();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
igNextColumn();
|
igNextColumn();
|
||||||
igBeginDisabled(bind->m_Type == MICE_BB_TYPE_UNBOUND);
|
igBeginDisabled(bind->m_Type == MICE_BB_TYPE_UNBOUND);
|
||||||
if (igCheckbox(invertName, (bool*)&bind->m_Invert)) save_current_config(false);
|
if (igCheckbox(invertName, (bool*)&bind->m_Invert)) save_keybind_config();
|
||||||
igEndDisabled();
|
igEndDisabled();
|
||||||
igNextColumn();
|
igNextColumn();
|
||||||
|
|
||||||
if (igKeyBindPopup_New(name, bind)) save_current_config(false);
|
if (igKeyBindPopup_New(name, bind)) save_keybind_config();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddButtonsForBoard(PMICE_JVS board) {
|
void AddButtonsForBoard(PMICE_JVS board) {
|
||||||
@ -841,33 +846,34 @@ void tab_jvs_board(int num) {
|
|||||||
|
|
||||||
igSeparator();
|
igSeparator();
|
||||||
|
|
||||||
AddButtonsForBoard(&_MiceJvsBoards[0]);
|
AddButtonsForBoard(&_MiceJvsBoards[num]);
|
||||||
|
|
||||||
igSeparator();
|
// TODO: RESTORE THIS!
|
||||||
AddSetting("Test", NULL);
|
// igSeparator();
|
||||||
char keyName[16];
|
// AddSetting("Test", NULL);
|
||||||
if (jvsKeybindings[num].test == 0) {
|
// char keyName[16];
|
||||||
igTextColored(DISABLED_COL, "None");
|
// if (jvsKeybindings[num].test == 0) {
|
||||||
} else {
|
// igTextColored(DISABLED_COL, "None");
|
||||||
GetKeyNameTextA(MapVirtualKey(jvsKeybindings[num].test, MAPVK_VK_TO_VSC) << 16, keyName,
|
// } else {
|
||||||
_countof(keyName));
|
// GetKeyNameTextA(MapVirtualKey(jvsKeybindings[num].test, MAPVK_VK_TO_VSC) << 16, keyName,
|
||||||
igTextUnformatted(keyName, NULL);
|
// _countof(keyName));
|
||||||
}
|
// igTextUnformatted(keyName, NULL);
|
||||||
igNextColumn();
|
// }
|
||||||
if (igButton("Bind##JvsTest", vec0)) igOpenPopup_Str("BindJvsTest", ImGuiPopupFlags_None);
|
// igNextColumn();
|
||||||
if (jvsKeybindings[num].test) {
|
// if (igButton("Bind##JvsTest", vec0)) igOpenPopup_Str("BindJvsTest", ImGuiPopupFlags_None);
|
||||||
igSameLine(0, -1);
|
// if (jvsKeybindings[num].test) {
|
||||||
if (igButton("Clear##ClearJvsTest", vec0)) {
|
// igSameLine(0, -1);
|
||||||
jvsKeybindings[num].test = 0;
|
// if (igButton("Clear##ClearJvsTest", vec0)) {
|
||||||
save_current_config(false);
|
// jvsKeybindings[num].test = 0;
|
||||||
}
|
// save_keybind_config();
|
||||||
}
|
// }
|
||||||
int boundKey;
|
// }
|
||||||
if (igKeyBindPopup("BindJvsTest", &boundKey))
|
// int boundKey;
|
||||||
if (boundKey != -1) {
|
// if (igKeyBindPopup("BindJvsTest", &boundKey))
|
||||||
jvsKeybindings[num].test = boundKey;
|
// if (boundKey != -1) {
|
||||||
save_current_config(false);
|
// jvsKeybindings[num].test = boundKey;
|
||||||
}
|
// save_keybind_config();
|
||||||
|
// }
|
||||||
|
|
||||||
igEndColumns();
|
igEndColumns();
|
||||||
|
|
||||||
@ -940,15 +946,14 @@ void tab_system_buttons() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void tab_main_keybinds() {
|
void tab_main_keybinds() {
|
||||||
if (igInputInt("Number of JVS boards", &MiceConfig.keys.board_count, 1, 1,
|
if (igInputInt("Number of JVS boards", &g_MiceJvsNumBoards, 1, 1, ImGuiInputTextFlags_None)) {
|
||||||
ImGuiInputTextFlags_None)) {
|
if (g_MiceJvsNumBoards < 1) g_MiceJvsNumBoards = 1;
|
||||||
if (MiceConfig.keys.board_count < 0) MiceConfig.keys.board_count = 0;
|
if (g_MiceJvsNumBoards > JVS_IO_MAX) g_MiceJvsNumBoards = JVS_IO_MAX;
|
||||||
if (MiceConfig.keys.board_count > JVS_IO_MAX) MiceConfig.keys.board_count = JVS_IO_MAX;
|
save_keybind_config();
|
||||||
save_current_config(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (igBeginTabBar("JVSBoards", 0)) {
|
if (igBeginTabBar("JVSBoards", 0)) {
|
||||||
for (int i = 0; i < MiceConfig.keys.board_count; i++) {
|
for (int i = 0; i < g_MiceJvsNumBoards; i++) {
|
||||||
char name[32];
|
char name[32];
|
||||||
snprintf(name, _countof(name), "Board %d", i + 1);
|
snprintf(name, _countof(name), "Board %d", i + 1);
|
||||||
if (igBeginTabItem(name, NULL, 0)) {
|
if (igBeginTabItem(name, NULL, 0)) {
|
||||||
|
@ -4,6 +4,101 @@
|
|||||||
|
|
||||||
#include "../input.h"
|
#include "../input.h"
|
||||||
|
|
||||||
|
// These APIs were added in Windows 8. Because they're events sent to the WndProc, we're safe to
|
||||||
|
// just re-define them ourselves, and get progressive enhancement!
|
||||||
|
#if (WINVER < 0x0602)
|
||||||
|
#define WM_NCPOINTERUPDATE 0x0241
|
||||||
|
#define WM_NCPOINTERDOWN 0x0242
|
||||||
|
#define WM_NCPOINTERUP 0x0243
|
||||||
|
#define WM_POINTERUPDATE 0x0245
|
||||||
|
#define WM_POINTERDOWN 0x0246
|
||||||
|
#define WM_POINTERUP 0x0247
|
||||||
|
#define WM_POINTERENTER 0x0249
|
||||||
|
#define WM_POINTERLEAVE 0x024A
|
||||||
|
#define WM_POINTERACTIVATE 0x024B
|
||||||
|
#define WM_POINTERCAPTURECHANGED 0x024C
|
||||||
|
|
||||||
|
#define POINTER_FLAG_INCONTACT 0x00000004
|
||||||
|
#define POINTER_FLAG_FIRSTBUTTON 0x00000010
|
||||||
|
#define POINTER_FLAG_CANCELED 0x00008000
|
||||||
|
#define POINTER_FLAG_DOWN 0x00010000
|
||||||
|
#define POINTER_FLAG_UP 0x00040000
|
||||||
|
|
||||||
|
#define GET_POINTERID_WPARAM(wParam) (LOWORD(wParam))
|
||||||
|
|
||||||
|
enum tagPOINTER_INPUT_TYPE {
|
||||||
|
PT_POINTER = 1, // Generic pointer
|
||||||
|
PT_TOUCH = 2, // Touch
|
||||||
|
PT_PEN = 3, // Pen
|
||||||
|
PT_MOUSE = 4, // Mouse
|
||||||
|
PT_TOUCHPAD = 5, // Touchpad
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef DWORD POINTER_INPUT_TYPE;
|
||||||
|
typedef UINT32 POINTER_FLAGS;
|
||||||
|
|
||||||
|
typedef enum tagPOINTER_BUTTON_CHANGE_TYPE {
|
||||||
|
POINTER_CHANGE_NONE,
|
||||||
|
POINTER_CHANGE_FIRSTBUTTON_DOWN,
|
||||||
|
POINTER_CHANGE_FIRSTBUTTON_UP,
|
||||||
|
POINTER_CHANGE_SECONDBUTTON_DOWN,
|
||||||
|
POINTER_CHANGE_SECONDBUTTON_UP,
|
||||||
|
POINTER_CHANGE_THIRDBUTTON_DOWN,
|
||||||
|
POINTER_CHANGE_THIRDBUTTON_UP,
|
||||||
|
POINTER_CHANGE_FOURTHBUTTON_DOWN,
|
||||||
|
POINTER_CHANGE_FOURTHBUTTON_UP,
|
||||||
|
POINTER_CHANGE_FIFTHBUTTON_DOWN,
|
||||||
|
POINTER_CHANGE_FIFTHBUTTON_UP,
|
||||||
|
} POINTER_BUTTON_CHANGE_TYPE;
|
||||||
|
|
||||||
|
typedef struct tagPOINTER_INFO {
|
||||||
|
POINTER_INPUT_TYPE pointerType;
|
||||||
|
UINT32 pointerId;
|
||||||
|
UINT32 frameId;
|
||||||
|
POINTER_FLAGS pointerFlags;
|
||||||
|
HANDLE sourceDevice;
|
||||||
|
HWND hwndTarget;
|
||||||
|
POINT ptPixelLocation;
|
||||||
|
POINT ptHimetricLocation;
|
||||||
|
POINT ptPixelLocationRaw;
|
||||||
|
POINT ptHimetricLocationRaw;
|
||||||
|
DWORD dwTime;
|
||||||
|
UINT32 historyCount;
|
||||||
|
INT32 InputData;
|
||||||
|
DWORD dwKeyStates;
|
||||||
|
UINT64 PerformanceCount;
|
||||||
|
POINTER_BUTTON_CHANGE_TYPE ButtonChangeType;
|
||||||
|
} POINTER_INFO;
|
||||||
|
|
||||||
|
// Our target API at compile time didn't support these functions, but these functions are only ever
|
||||||
|
// called if we've already received a touch window event, meaning we're actually running on a newer
|
||||||
|
// version of windows. That means we're safe to load in these functions and use them!
|
||||||
|
static HMODULE hmUser32 = NULL;
|
||||||
|
static BOOL(WINAPI* lpGetPointerType)(UINT32 pointerId, POINTER_INPUT_TYPE* pointerType) = NULL;
|
||||||
|
static BOOL MockGetPointerType(UINT32 pointerId, POINTER_INPUT_TYPE* pointerType) {
|
||||||
|
puts("Loading mock");
|
||||||
|
if (!hmUser32) hmUser32 = LoadLibraryA("User32.dll");
|
||||||
|
if (!hmUser32) return FALSE;
|
||||||
|
puts("Loading function");
|
||||||
|
if (!lpGetPointerType) lpGetPointerType = (void*)GetProcAddress(hmUser32, "GetPointerType");
|
||||||
|
if (!lpGetPointerType) return FALSE;
|
||||||
|
puts("Calling");
|
||||||
|
return lpGetPointerType(pointerId, pointerType);
|
||||||
|
}
|
||||||
|
static BOOL(WINAPI* lpGetPointerInfo)(UINT32 pointerId, POINTER_INFO* pointerInfo) = NULL;
|
||||||
|
static BOOL MockGetPointerInfo(UINT32 pointerId, POINTER_INFO* pointerInfo) {
|
||||||
|
if (!hmUser32) hmUser32 = LoadLibraryA("User32.dll");
|
||||||
|
if (!hmUser32) return FALSE;
|
||||||
|
if (!lpGetPointerInfo) lpGetPointerInfo = (void*)GetProcAddress(hmUser32, "GetPointerInfo");
|
||||||
|
if (!lpGetPointerInfo) return FALSE;
|
||||||
|
return lpGetPointerInfo(pointerId, pointerInfo);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// If our target API supports these, no mocking is needed
|
||||||
|
#define MockGetPointerType GetPointerType
|
||||||
|
#define MockGetPointerInfo GetPointerInfo
|
||||||
|
#endif
|
||||||
|
|
||||||
extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
HWND mainWindow = NULL;
|
HWND mainWindow = NULL;
|
||||||
@ -152,10 +247,74 @@ void register_gui_hook(FnEndScene* end_scene) {
|
|||||||
*head = hook;
|
*head = hook;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DWORD nActiveTouches = 0;
|
||||||
|
ACTIVE_TOUCH* activeTouches = NULL;
|
||||||
|
extern DWORD nActiveTouchesMax = 0;
|
||||||
|
|
||||||
|
void SetTouch(UINT id, INT x, INT y, BOOL state) {
|
||||||
|
if (state) {
|
||||||
|
// If we can just update in place, do
|
||||||
|
for (DWORD i = 0; i < nActiveTouches; i++) {
|
||||||
|
if (activeTouches[i].m_Id == id) {
|
||||||
|
activeTouches[i].m_X = x;
|
||||||
|
activeTouches[i].m_Y = y;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dynamic array re-allocation
|
||||||
|
if (nActiveTouches == nActiveTouchesMax) {
|
||||||
|
DWORD newSize = nActiveTouchesMax * 2 + 1;
|
||||||
|
ACTIVE_TOUCH* newMemory = realloc(activeTouches, sizeof *activeTouches * newSize);
|
||||||
|
if (newMemory != activeTouches) {
|
||||||
|
memcpy(newMemory, activeTouches, sizeof *activeTouches * nActiveTouchesMax);
|
||||||
|
}
|
||||||
|
activeTouches = newMemory;
|
||||||
|
nActiveTouchesMax = newSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store into end of DA
|
||||||
|
activeTouches[nActiveTouches].m_Id = id;
|
||||||
|
activeTouches[nActiveTouches].m_X = x;
|
||||||
|
activeTouches[nActiveTouches].m_Y = y;
|
||||||
|
nActiveTouches++;
|
||||||
|
} else {
|
||||||
|
for (DWORD i = 0; i < nActiveTouches; i++) {
|
||||||
|
if (activeTouches[i].m_Id == id) {
|
||||||
|
// Copy backwards
|
||||||
|
for (DWORD j = i + 1; j < nActiveTouches; j++) {
|
||||||
|
activeTouches[j - 1].m_Id = activeTouches[j].m_Id;
|
||||||
|
activeTouches[j - 1].m_X = activeTouches[j].m_X;
|
||||||
|
activeTouches[j - 1].m_Y = activeTouches[j].m_Y;
|
||||||
|
}
|
||||||
|
nActiveTouches--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TouchHandler(HWND hWnd, WPARAM wParam, LPARAM lParam) {
|
||||||
|
UINT32 pointerId = GET_POINTERID_WPARAM(wParam);
|
||||||
|
POINTER_INFO pointerInfo = { sizeof(POINTER_INFO) };
|
||||||
|
POINTER_INPUT_TYPE pointerType = 0;
|
||||||
|
|
||||||
|
if (MockGetPointerType(pointerId, &pointerType) &&
|
||||||
|
MockGetPointerInfo(pointerId, &pointerInfo)) {
|
||||||
|
POINT point = pointerInfo.ptPixelLocation;
|
||||||
|
if (pointerType == PT_TOUCH && ScreenToClient(hWnd, &point)) {
|
||||||
|
SetTouch(pointerInfo.pointerId, point.x, point.y,
|
||||||
|
!!(pointerInfo.pointerFlags & POINTER_FLAG_INCONTACT)); // |
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DWORD changeCursorState = (DWORD)-1;
|
DWORD changeCursorState = (DWORD)-1;
|
||||||
|
WNDPROC OriginalWndProc = NULL;
|
||||||
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass,
|
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass,
|
||||||
DWORD_PTR dwRefData) {
|
DWORD_PTR dwRefData) {
|
||||||
ImGui_ImplWin32_WndProcHandler(hWnd, uMsg, wParam, lParam);
|
if (hookType == UI_HOOK_DX9) {
|
||||||
|
ImGui_ImplWin32_WndProcHandler(hWnd, uMsg, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
if (changeCursorState == 1) {
|
if (changeCursorState == 1) {
|
||||||
while (ShowCursor(TRUE) < 0)
|
while (ShowCursor(TRUE) < 0)
|
||||||
@ -167,6 +326,25 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UIN
|
|||||||
changeCursorState = (DWORD)-1;
|
changeCursorState = (DWORD)-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (uMsg) {
|
||||||
|
case WM_NCPOINTERUPDATE:
|
||||||
|
case WM_NCPOINTERDOWN:
|
||||||
|
case WM_NCPOINTERUP:
|
||||||
|
case WM_POINTERUPDATE:
|
||||||
|
case WM_POINTERDOWN:
|
||||||
|
case WM_POINTERUP:
|
||||||
|
case WM_POINTERENTER:
|
||||||
|
case WM_POINTERLEAVE:
|
||||||
|
case WM_POINTERACTIVATE:
|
||||||
|
case WM_POINTERCAPTURECHANGED:
|
||||||
|
TouchHandler(hWnd, wParam, lParam);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OriginalWndProc) {
|
||||||
|
return CallWindowProcA(OriginalWndProc, hWnd, uMsg, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
|
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,13 +364,19 @@ void post_win_create(HWND hWnd) {
|
|||||||
DetourAttach((PVOID*)&TrueEndScene, hkEndScene);
|
DetourAttach((PVOID*)&TrueEndScene, hkEndScene);
|
||||||
DetourTransactionCommit();
|
DetourTransactionCommit();
|
||||||
}
|
}
|
||||||
|
// MiceInputInit will be called by our D3D9 hooks instead
|
||||||
if (hWnd && !SetWindowSubclass(hWnd, WndProc, (UINT_PTR)&WndProc, (DWORD_PTR)NULL)) {
|
|
||||||
log_error(plfGUI, "failed to SetWindowSubclass(%d)", GetLastError());
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
MiceInputInit(hWnd);
|
MiceInputInit(hWnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hWnd) {
|
||||||
|
OriginalWndProc = (WNDPROC)GetWindowLongPtr(hWnd, GWLP_WNDPROC);
|
||||||
|
if (OriginalWndProc == NULL) log_warning(plfGUI, "GWLP_WNDPROC NULL");
|
||||||
|
|
||||||
|
if (!SetWindowSubclass(hWnd, WndProc, (UINT_PTR)&WndProc, (DWORD_PTR)NULL)) {
|
||||||
|
log_error(plfGUI, "failed to SetWindowSubclass(%d)", GetLastError());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RECT monitorRect = { 0 };
|
RECT monitorRect = { 0 };
|
||||||
|
@ -43,6 +43,14 @@ void register_gui_hook(FnEndScene* end_scene);
|
|||||||
void hook_gui();
|
void hook_gui();
|
||||||
void setup_hud_gui();
|
void setup_hud_gui();
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
UINT m_Id;
|
||||||
|
INT m_X;
|
||||||
|
INT m_Y;
|
||||||
|
} ACTIVE_TOUCH;
|
||||||
|
extern DWORD nActiveTouches;
|
||||||
|
extern ACTIVE_TOUCH* activeTouches;
|
||||||
|
|
||||||
BOOL UnadjustWindowRect(LPRECT prc, DWORD dwStyle, BOOL fMenu);
|
BOOL UnadjustWindowRect(LPRECT prc, DWORD dwStyle, BOOL fMenu);
|
||||||
extern HWND mainWindow;
|
extern HWND mainWindow;
|
||||||
extern DWORD changeCursorState;
|
extern DWORD changeCursorState;
|
||||||
|
@ -36,17 +36,21 @@ DWORD WINAPI FakeGetTempPathW(DWORD nBufferLength, LPWSTR lpBuffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
HCURSOR WINAPI FakeLoadCursorFromFileA(LPCSTR lpFileName) { return (HANDLE)1; }
|
HCURSOR WINAPI FakeLoadCursorFromFileA(LPCSTR lpFileName) { return (HANDLE)1; }
|
||||||
BOOL FakeSetSystemCursor(HCURSOR hcur, DWORD id) { return TRUE; }
|
BOOL WINAPI FakeSetSystemCursor(HCURSOR hcur, DWORD id) { return TRUE; }
|
||||||
BOOL FakeDeleteObject(HGDIOBJ ho) { return TRUE; }
|
BOOL WINAPI FakeDeleteObject(HGDIOBJ ho) { return TRUE; }
|
||||||
|
|
||||||
FARPROC FakeGetProcAddress(HMODULE hModule, LPCSTR lpProcName) {
|
FARPROC WINAPI FakeGetProcAddress(HMODULE hModule, LPCSTR lpProcName) {
|
||||||
log_trace(plfSystem, "GetProcAddress(%s)", lpProcName);
|
// log_error(plfSystem, "GetProcAddress(%s)", lpProcName);
|
||||||
return TrueGetProcAddress(hModule, lpProcName);
|
return TrueGetProcAddress(hModule, lpProcName);
|
||||||
}
|
}
|
||||||
HMODULE FakeGetModuleHandleA(LPCSTR lpModuleName) {
|
HMODULE WINAPI FakeGetModuleHandleA(LPCSTR lpModuleName) {
|
||||||
log_trace(plfSystem, "GetModuleHandleA(%s)", lpModuleName);
|
// log_game(plfSystem, "GetModuleHandleA(%s)", lpModuleName);
|
||||||
return TrueGetModuleHandleA(lpModuleName);
|
return TrueGetModuleHandleA(lpModuleName);
|
||||||
}
|
}
|
||||||
|
HMODULE WINAPI FakeGetModuleHandleW(LPCWSTR lpModuleName) {
|
||||||
|
// log_game(plfSystem, "GetModuleHandleW(%ls)", lpModuleName);
|
||||||
|
return TrueGetModuleHandleW(lpModuleName);
|
||||||
|
}
|
||||||
|
|
||||||
LONG WINAPI FakeRtlGetVersion(PRTL_OSVERSIONINFOW lpVersionInformation) {
|
LONG WINAPI FakeRtlGetVersion(PRTL_OSVERSIONINFOW lpVersionInformation) {
|
||||||
log_trace(plfSystem, "RtlGetVersion(%p)", lpVersionInformation);
|
log_trace(plfSystem, "RtlGetVersion(%p)", lpVersionInformation);
|
||||||
@ -89,8 +93,9 @@ void hook_system() {
|
|||||||
hook("Kernel32.dll", "GetVolumeInformationW", FakeGetVolumeInformationW, NULL);
|
hook("Kernel32.dll", "GetVolumeInformationW", FakeGetVolumeInformationW, NULL);
|
||||||
hook("Kernel32.dll", "GetTempPathW", FakeGetTempPathW, NULL);
|
hook("Kernel32.dll", "GetTempPathW", FakeGetTempPathW, NULL);
|
||||||
// hook("Kernel32.dll", "GetVersionExA", FakeGetVersionExA, NULL);
|
// hook("Kernel32.dll", "GetVersionExA", FakeGetVersionExA, NULL);
|
||||||
// hook("Kernel32.dll", "GetProcAddress", FakeGetProcAddress, (void*)&TrueGetProcAddress);
|
hook("Kernel32.dll", "GetProcAddress", FakeGetProcAddress, (void*)&TrueGetProcAddress);
|
||||||
// hook("Kernel32.dll", "GetModuleHandleA", FakeGetModuleHandleA, (void*)&TrueGetModuleHandleA);
|
hook("Kernel32.dll", "GetModuleHandleA", FakeGetModuleHandleA, (void*)&TrueGetModuleHandleA);
|
||||||
|
hook("Kernel32.dll", "GetModuleHandleW", FakeGetModuleHandleW, (void*)&TrueGetModuleHandleW);
|
||||||
hook("Kernel32.dll", "LoadLibraryA", FakeLoadLibraryA, (void*)&TrueLoadLibraryA);
|
hook("Kernel32.dll", "LoadLibraryA", FakeLoadLibraryA, (void*)&TrueLoadLibraryA);
|
||||||
hook("Kernel32.dll", "LoadLibraryW", FakeLoadLibraryW, (void*)&TrueLoadLibraryW);
|
hook("Kernel32.dll", "LoadLibraryW", FakeLoadLibraryW, (void*)&TrueLoadLibraryW);
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
FARPROC(WINAPI* TrueGetProcAddress)(HMODULE hModule, LPCSTR lpProcName);
|
FARPROC(WINAPI* TrueGetProcAddress)(HMODULE hModule, LPCSTR lpProcName);
|
||||||
HMODULE(WINAPI* TrueGetModuleHandleA)(LPCSTR lpModuleName);
|
HMODULE(WINAPI* TrueGetModuleHandleA)(LPCSTR lpModuleName);
|
||||||
|
HMODULE(WINAPI* TrueGetModuleHandleW)(LPCWSTR lpModuleName);
|
||||||
HMODULE(WINAPI* TrueLoadLibraryA)(LPCSTR lpLibFileName);
|
HMODULE(WINAPI* TrueLoadLibraryA)(LPCSTR lpLibFileName);
|
||||||
HMODULE(WINAPI* TrueLoadLibraryW)(LPCWSTR lpLibFileName);
|
HMODULE(WINAPI* TrueLoadLibraryW)(LPCWSTR lpLibFileName);
|
||||||
|
|
||||||
|
129
src/micetools/dll/input_config.c
Normal file
129
src/micetools/dll/input_config.c
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
int g_MiceJvsNumBoards = 0;
|
||||||
|
MICE_JVS _MiceJvsBoards[JVS_IO_MAX];
|
||||||
|
|
||||||
|
void save_keybind_config() {
|
||||||
|
HANDLE hFile = CreateFileA(KEYBINDS_PATH, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE, NULL,
|
||||||
|
CREATE_ALWAYS, 0, NULL);
|
||||||
|
if (hFile == INVALID_HANDLE_VALUE) {
|
||||||
|
fprintf(stderr, "Failed to open keybinds file: %d", GetLastError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetFilePointer(hFile, 8, NULL, 0);
|
||||||
|
|
||||||
|
DWORD nWrote;
|
||||||
|
DWORD totalSize = 0;
|
||||||
|
WriteFile(hFile, &g_MiceJvsNumBoards, sizeof g_MiceJvsNumBoards, &nWrote, NULL);
|
||||||
|
totalSize += nWrote;
|
||||||
|
|
||||||
|
for (int board = 0; board < g_MiceJvsNumBoards; board++) {
|
||||||
|
WriteFile(hFile, &_MiceJvsBoards[board].m_Players, sizeof _MiceJvsBoards[board].m_Players,
|
||||||
|
&nWrote, NULL);
|
||||||
|
totalSize += nWrote;
|
||||||
|
WriteFile(hFile, &_MiceJvsBoards[board].m_ButtonsPerPlayer,
|
||||||
|
sizeof _MiceJvsBoards[board].m_ButtonsPerPlayer, &nWrote, NULL);
|
||||||
|
totalSize += nWrote;
|
||||||
|
WriteFile(hFile, &_MiceJvsBoards[board].m_Coins, sizeof _MiceJvsBoards[board].m_Coins,
|
||||||
|
&nWrote, NULL);
|
||||||
|
totalSize += nWrote;
|
||||||
|
WriteFile(hFile, &_MiceJvsBoards[board].m_NumButtons,
|
||||||
|
sizeof _MiceJvsBoards[board].m_NumButtons, &nWrote, NULL);
|
||||||
|
totalSize += nWrote;
|
||||||
|
|
||||||
|
WriteFile(hFile, _MiceJvsBoards[board].m_Bindings,
|
||||||
|
sizeof *_MiceJvsBoards[board].m_Bindings * _MiceJvsBoards[board].m_NumButtons,
|
||||||
|
&nWrote, NULL);
|
||||||
|
totalSize += nWrote;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetFilePointer(hFile, 0, NULL, 0);
|
||||||
|
WriteFile(hFile, &totalSize, sizeof totalSize, &nWrote, NULL);
|
||||||
|
|
||||||
|
amiCrc32RInit();
|
||||||
|
DWORD readLeft = totalSize;
|
||||||
|
DWORD crc32 = 0;
|
||||||
|
SetFilePointer(hFile, 8, NULL, 0);
|
||||||
|
while (readLeft) {
|
||||||
|
BYTE readBuf[0x1000];
|
||||||
|
DWORD toRead = sizeof readBuf;
|
||||||
|
if (readLeft < toRead) toRead = readLeft;
|
||||||
|
DWORD nRead;
|
||||||
|
ReadFile(hFile, readBuf, toRead, &nRead, NULL);
|
||||||
|
|
||||||
|
if (nRead == 0) {
|
||||||
|
fprintf(stderr, "Binding saving failed %d\n", GetLastError());
|
||||||
|
CloseHandle(hFile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
crc32 = amiCrc32RCalc(nRead, readBuf, crc32);
|
||||||
|
readLeft -= nRead;
|
||||||
|
}
|
||||||
|
SetFilePointer(hFile, 4, NULL, 0);
|
||||||
|
WriteFile(hFile, &crc32, sizeof crc32, &nWrote, NULL);
|
||||||
|
|
||||||
|
CloseHandle(hFile);
|
||||||
|
}
|
||||||
|
void load_keybind_config() {
|
||||||
|
HANDLE hFile =
|
||||||
|
CreateFileA(KEYBINDS_PATH, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
if (hFile == INVALID_HANDLE_VALUE) return;
|
||||||
|
|
||||||
|
DWORD nRead;
|
||||||
|
DWORD nSize = 0;
|
||||||
|
ReadFile(hFile, &nSize, sizeof nSize, &nRead, NULL);
|
||||||
|
|
||||||
|
SetFilePointer(hFile, 8, NULL, 0);
|
||||||
|
amiCrc32RInit();
|
||||||
|
DWORD crc32 = 0;
|
||||||
|
while (nSize) {
|
||||||
|
BYTE readBuf[0x1000];
|
||||||
|
DWORD toRead = sizeof readBuf;
|
||||||
|
if (nSize < toRead) toRead = nSize;
|
||||||
|
ReadFile(hFile, readBuf, toRead, &nRead, NULL);
|
||||||
|
|
||||||
|
if (nRead == 0) {
|
||||||
|
log_error(plfBoot, "Binding reading failed\n");
|
||||||
|
CloseHandle(hFile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
crc32 = amiCrc32RCalc(nRead, readBuf, crc32);
|
||||||
|
nSize -= nRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD savedCrc;
|
||||||
|
SetFilePointer(hFile, 4, NULL, 0);
|
||||||
|
ReadFile(hFile, &savedCrc, sizeof savedCrc, &nRead, NULL);
|
||||||
|
if (savedCrc != crc32) {
|
||||||
|
log_error(plfBoot, "Binding file CRC failed (%08x!=%08x)\n", savedCrc, crc32);
|
||||||
|
CloseHandle(hFile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReadFile(hFile, &g_MiceJvsNumBoards, sizeof g_MiceJvsNumBoards, &nRead, NULL);
|
||||||
|
|
||||||
|
for (int board = 0; board < g_MiceJvsNumBoards; board++) {
|
||||||
|
ReadFile(hFile, &_MiceJvsBoards[board].m_Players, sizeof _MiceJvsBoards[board].m_Players,
|
||||||
|
&nRead, NULL);
|
||||||
|
ReadFile(hFile, &_MiceJvsBoards[board].m_ButtonsPerPlayer,
|
||||||
|
sizeof _MiceJvsBoards[board].m_ButtonsPerPlayer, &nRead, NULL);
|
||||||
|
ReadFile(hFile, &_MiceJvsBoards[board].m_Coins, sizeof _MiceJvsBoards[board].m_Coins,
|
||||||
|
&nRead, NULL);
|
||||||
|
ReadFile(hFile, &_MiceJvsBoards[board].m_NumButtons,
|
||||||
|
sizeof _MiceJvsBoards[board].m_NumButtons, &nRead, NULL);
|
||||||
|
|
||||||
|
free(_MiceJvsBoards[board].m_Bindings);
|
||||||
|
_MiceJvsBoards[board].m_Bindings =
|
||||||
|
malloc(sizeof *_MiceJvsBoards[board].m_Bindings * _MiceJvsBoards[board].m_NumButtons);
|
||||||
|
ReadFile(hFile, _MiceJvsBoards[board].m_Bindings,
|
||||||
|
sizeof *_MiceJvsBoards[board].m_Bindings * _MiceJvsBoards[board].m_NumButtons,
|
||||||
|
&nRead, NULL);
|
||||||
|
|
||||||
|
free(_MiceJvsBoards[board].m_ButtonStates);
|
||||||
|
_MiceJvsBoards[board].m_ButtonStates = malloc(sizeof *_MiceJvsBoards[board].m_ButtonStates *
|
||||||
|
_MiceJvsBoards[board].m_NumButtons);
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(hFile);
|
||||||
|
}
|
7
src/micetools/dll/input_config.h
Normal file
7
src/micetools/dll/input_config.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#include "drivers/jvs_boards/jvs.h"
|
||||||
|
|
||||||
|
void save_keybind_config();
|
||||||
|
void load_keybind_config();
|
||||||
|
|
||||||
|
extern MICE_JVS _MiceJvsBoards[JVS_IO_MAX];
|
||||||
|
extern int g_MiceJvsNumBoards;
|
@ -5,11 +5,11 @@
|
|||||||
#define JVS_IO_MAX 31
|
#define JVS_IO_MAX 31
|
||||||
#define JVS_BUTTON_PAIR_COUNT 15
|
#define JVS_BUTTON_PAIR_COUNT 15
|
||||||
|
|
||||||
struct {
|
// struct {
|
||||||
int buttons[JVS_BUTTON_PAIR_COUNT * 2];
|
// int buttons[JVS_BUTTON_PAIR_COUNT * 2];
|
||||||
bool invert[JVS_BUTTON_PAIR_COUNT * 2];
|
// bool invert[JVS_BUTTON_PAIR_COUNT * 2];
|
||||||
int test;
|
// int test;
|
||||||
int notdefault;
|
// int notdefault;
|
||||||
} jvsKeybindings[JVS_IO_MAX] = { 0 };
|
// } jvsKeybindings[JVS_IO_MAX] = { 0 };
|
||||||
|
|
||||||
int keySystemTest = 0;
|
int keySystemTest = 0;
|
||||||
|
@ -24,6 +24,7 @@ shared_library(
|
|||||||
'games.c',
|
'games.c',
|
||||||
'input.c',
|
'input.c',
|
||||||
'micefs.c',
|
'micefs.c',
|
||||||
|
'input_config.c',
|
||||||
|
|
||||||
'dllmain.c',
|
'dllmain.c',
|
||||||
],
|
],
|
||||||
|
@ -6,12 +6,9 @@
|
|||||||
|
|
||||||
#include "../../../../subprojects/inih_dep/ini.h"
|
#include "../../../../subprojects/inih_dep/ini.h"
|
||||||
#include "../../dll/devices/smb_pca9535.h"
|
#include "../../dll/devices/smb_pca9535.h"
|
||||||
#include "../../dll/drivers/jvs_boards/jvs.h"
|
|
||||||
#include "../../dll/hooks/files.h"
|
#include "../../dll/hooks/files.h"
|
||||||
#include "../../dll/key_config.h"
|
#include "../../dll/key_config.h"
|
||||||
|
|
||||||
MICE_JVS _MiceJvsBoards[JVS_IO_MAX];
|
|
||||||
|
|
||||||
config_t MiceConfig = {
|
config_t MiceConfig = {
|
||||||
#define SECTION(s, comment) .s = {
|
#define SECTION(s, comment) .s = {
|
||||||
#define CFG_str(s, n, default, comment) .n = default,
|
#define CFG_str(s, n, default, comment) .n = default,
|
||||||
@ -42,135 +39,10 @@ static void fprintf_prefix(FILE *file, const char *prefix, const char *text) {
|
|||||||
free(copy);
|
free(copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
void save_keybinds() {
|
|
||||||
HANDLE hFile = CreateFileA(KEYBINDS_PATH, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE, NULL,
|
|
||||||
CREATE_ALWAYS, 0, NULL);
|
|
||||||
if (hFile == INVALID_HANDLE_VALUE) {
|
|
||||||
fprintf(stderr, "Failed to open keybinds file: %d", GetLastError());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetFilePointer(hFile, 8, NULL, 0);
|
|
||||||
|
|
||||||
DWORD nWrote;
|
|
||||||
DWORD totalSize = 0;
|
|
||||||
WriteFile(hFile, &MiceConfig.keys.board_count, sizeof MiceConfig.keys.board_count, &nWrote,
|
|
||||||
NULL);
|
|
||||||
totalSize += nWrote;
|
|
||||||
|
|
||||||
for (int board = 0; board < MiceConfig.keys.board_count; board++) {
|
|
||||||
WriteFile(hFile, &_MiceJvsBoards->m_Players, sizeof _MiceJvsBoards->m_Players, &nWrote,
|
|
||||||
NULL);
|
|
||||||
totalSize += nWrote;
|
|
||||||
WriteFile(hFile, &_MiceJvsBoards->m_ButtonsPerPlayer,
|
|
||||||
sizeof _MiceJvsBoards->m_ButtonsPerPlayer, &nWrote, NULL);
|
|
||||||
totalSize += nWrote;
|
|
||||||
WriteFile(hFile, &_MiceJvsBoards->m_Coins, sizeof _MiceJvsBoards->m_Coins, &nWrote, NULL);
|
|
||||||
totalSize += nWrote;
|
|
||||||
WriteFile(hFile, &_MiceJvsBoards->m_NumButtons, sizeof _MiceJvsBoards->m_NumButtons,
|
|
||||||
&nWrote, NULL);
|
|
||||||
totalSize += nWrote;
|
|
||||||
|
|
||||||
WriteFile(hFile, _MiceJvsBoards[board].m_Bindings,
|
|
||||||
sizeof *_MiceJvsBoards[board].m_Bindings * _MiceJvsBoards->m_NumButtons, &nWrote,
|
|
||||||
NULL);
|
|
||||||
totalSize += nWrote;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetFilePointer(hFile, 0, NULL, 0);
|
|
||||||
WriteFile(hFile, &totalSize, sizeof totalSize, &nWrote, NULL);
|
|
||||||
|
|
||||||
amiCrc32RInit();
|
|
||||||
DWORD readLeft = totalSize;
|
|
||||||
DWORD crc32 = 0;
|
|
||||||
SetFilePointer(hFile, 8, NULL, 0);
|
|
||||||
while (readLeft) {
|
|
||||||
BYTE readBuf[0x1000];
|
|
||||||
DWORD toRead = sizeof readBuf;
|
|
||||||
if (readLeft < toRead) toRead = readLeft;
|
|
||||||
DWORD nRead;
|
|
||||||
ReadFile(hFile, readBuf, toRead, &nRead, NULL);
|
|
||||||
|
|
||||||
if (nRead == 0) {
|
|
||||||
fprintf(stderr, "Binding saving failed %d\n", GetLastError());
|
|
||||||
CloseHandle(hFile);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
crc32 = amiCrc32RCalc(nRead, readBuf, crc32);
|
|
||||||
readLeft -= nRead;
|
|
||||||
}
|
|
||||||
SetFilePointer(hFile, 4, NULL, 0);
|
|
||||||
WriteFile(hFile, &crc32, sizeof crc32, &nWrote, NULL);
|
|
||||||
|
|
||||||
CloseHandle(hFile);
|
|
||||||
}
|
|
||||||
void load_keybind_config() {
|
|
||||||
HANDLE hFile =
|
|
||||||
CreateFileA(KEYBINDS_PATH, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
|
||||||
if (hFile == INVALID_HANDLE_VALUE) return;
|
|
||||||
|
|
||||||
DWORD nRead;
|
|
||||||
DWORD nSize = 0;
|
|
||||||
ReadFile(hFile, &nSize, sizeof nSize, &nRead, NULL);
|
|
||||||
|
|
||||||
SetFilePointer(hFile, 8, NULL, 0);
|
|
||||||
amiCrc32RInit();
|
|
||||||
DWORD crc32 = 0;
|
|
||||||
while (nSize) {
|
|
||||||
BYTE readBuf[0x1000];
|
|
||||||
DWORD toRead = sizeof readBuf;
|
|
||||||
if (nSize < toRead) toRead = nSize;
|
|
||||||
ReadFile(hFile, readBuf, toRead, &nRead, NULL);
|
|
||||||
|
|
||||||
if (nRead == 0) {
|
|
||||||
fprintf(stderr, "Binding reading failed\n");
|
|
||||||
CloseHandle(hFile);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
crc32 = amiCrc32RCalc(nRead, readBuf, crc32);
|
|
||||||
nSize -= nRead;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD savedCrc;
|
|
||||||
SetFilePointer(hFile, 4, NULL, 0);
|
|
||||||
ReadFile(hFile, &savedCrc, sizeof savedCrc, &nRead, NULL);
|
|
||||||
if (savedCrc != crc32) {
|
|
||||||
fprintf(stderr, "Binding file CRC failed (%08x!=%08x)\n", savedCrc, crc32);
|
|
||||||
CloseHandle(hFile);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReadFile(hFile, &MiceConfig.keys.board_count, sizeof MiceConfig.keys.board_count, &nRead, NULL);
|
|
||||||
|
|
||||||
for (int board = 0; board < MiceConfig.keys.board_count; board++) {
|
|
||||||
ReadFile(hFile, &_MiceJvsBoards->m_Players, sizeof _MiceJvsBoards->m_Players, &nRead, NULL);
|
|
||||||
ReadFile(hFile, &_MiceJvsBoards->m_ButtonsPerPlayer,
|
|
||||||
sizeof _MiceJvsBoards->m_ButtonsPerPlayer, &nRead, NULL);
|
|
||||||
ReadFile(hFile, &_MiceJvsBoards->m_Coins, sizeof _MiceJvsBoards->m_Coins, &nRead, NULL);
|
|
||||||
ReadFile(hFile, &_MiceJvsBoards->m_NumButtons, sizeof _MiceJvsBoards->m_NumButtons, &nRead,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
free(_MiceJvsBoards[board].m_Bindings);
|
|
||||||
_MiceJvsBoards[board].m_Bindings =
|
|
||||||
malloc(sizeof *_MiceJvsBoards[board].m_Bindings * _MiceJvsBoards->m_NumButtons);
|
|
||||||
ReadFile(hFile, _MiceJvsBoards[board].m_Bindings,
|
|
||||||
sizeof *_MiceJvsBoards[board].m_Bindings * _MiceJvsBoards->m_NumButtons, &nRead,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
free(_MiceJvsBoards[board].m_ButtonStates);
|
|
||||||
_MiceJvsBoards[board].m_ButtonStates =
|
|
||||||
malloc(sizeof *_MiceJvsBoards[board].m_ButtonStates * _MiceJvsBoards->m_NumButtons);
|
|
||||||
}
|
|
||||||
|
|
||||||
CloseHandle(hFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
char keybindBuffer[2 * JVS_IO_MAX * (sizeof _MiceJvsBoards[0].m_Bindings[0]) * 32];
|
char keybindBuffer[2 * JVS_IO_MAX * (sizeof _MiceJvsBoards[0].m_Bindings[0]) * 32];
|
||||||
void save_current_config(bool writeDefault) {
|
void save_current_config(bool writeDefault) {
|
||||||
CreateDirectoryA("mice", NULL); // TODO: A touch nicer?
|
CreateDirectoryA("mice", NULL); // TODO: A touch nicer?
|
||||||
|
|
||||||
save_keybinds();
|
|
||||||
|
|
||||||
FILE *config_file;
|
FILE *config_file;
|
||||||
fopen_s(&config_file, CONFIG_PATH, "w");
|
fopen_s(&config_file, CONFIG_PATH, "w");
|
||||||
if (config_file == NULL) {
|
if (config_file == NULL) {
|
||||||
@ -270,24 +142,30 @@ void load_mice_config() {
|
|||||||
if (ini_parse(CONFIG_PATH, handler, &MiceConfig) < 0) {
|
if (ini_parse(CONFIG_PATH, handler, &MiceConfig) < 0) {
|
||||||
printf("Loading config defaults\n");
|
printf("Loading config defaults\n");
|
||||||
|
|
||||||
if (MiceConfig.sysconf.serial) free(MiceConfig.sysconf.serial);
|
if (MiceConfig.sysconf.pcb_serial) free(MiceConfig.sysconf.pcb_serial);
|
||||||
MiceConfig.sysconf.serial = malloc(17);
|
MiceConfig.sysconf.pcb_serial = malloc(17);
|
||||||
if (MiceConfig.sysconf.keyid) free(MiceConfig.sysconf.keyid);
|
memset(MiceConfig.sysconf.pcb_serial, 0, 17);
|
||||||
MiceConfig.sysconf.keyid = malloc(17);
|
if (MiceConfig.sysconf.keychip_serial) free(MiceConfig.sysconf.keychip_serial);
|
||||||
GetSerialNumbers(MiceConfig.sysconf.serial, MiceConfig.sysconf.keyid);
|
MiceConfig.sysconf.keychip_serial = malloc(17);
|
||||||
|
memset(MiceConfig.sysconf.keychip_serial, 0, 17);
|
||||||
|
GetSerialNumbers(MiceConfig.sysconf.pcb_serial, MiceConfig.sysconf.keychip_serial);
|
||||||
|
|
||||||
save_current_config(true);
|
save_current_config(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!MiceConfig.sysconf.serial || strlen(MiceConfig.sysconf.serial) == 0) {
|
if (!MiceConfig.sysconf.pcb_serial || strlen(MiceConfig.sysconf.pcb_serial) == 0) {
|
||||||
if (MiceConfig.sysconf.serial) free(MiceConfig.sysconf.serial);
|
if (MiceConfig.sysconf.pcb_serial) free(MiceConfig.sysconf.pcb_serial);
|
||||||
MiceConfig.sysconf.serial = malloc(17);
|
MiceConfig.sysconf.pcb_serial = malloc(17);
|
||||||
GetSerialNumbers(MiceConfig.sysconf.serial, NULL);
|
memset(MiceConfig.sysconf.pcb_serial, 0, 17);
|
||||||
|
GetSerialNumbers(MiceConfig.sysconf.pcb_serial, NULL);
|
||||||
|
save_current_config(false);
|
||||||
}
|
}
|
||||||
if (!MiceConfig.sysconf.keyid || strlen(MiceConfig.sysconf.keyid) == 0) {
|
if (!MiceConfig.sysconf.keychip_serial || strlen(MiceConfig.sysconf.keychip_serial) == 0) {
|
||||||
if (MiceConfig.sysconf.keyid) free(MiceConfig.sysconf.keyid);
|
if (MiceConfig.sysconf.keychip_serial) free(MiceConfig.sysconf.keychip_serial);
|
||||||
MiceConfig.sysconf.keyid = malloc(17);
|
MiceConfig.sysconf.keychip_serial = malloc(17);
|
||||||
GetSerialNumbers(NULL, MiceConfig.sysconf.keyid);
|
memset(MiceConfig.sysconf.keychip_serial, 0, 17);
|
||||||
|
GetSerialNumbers(NULL, MiceConfig.sysconf.keychip_serial);
|
||||||
|
save_current_config(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MiceConfig.window.dipsw) {
|
if (MiceConfig.window.dipsw) {
|
||||||
|
@ -40,9 +40,10 @@ SECTION(sysconf, "System configuration settings")
|
|||||||
CFG_int(sysconf, platform, 2, "System platform. 0 = RingWide, 1 = RingEdge, 2 = RingEdge2")
|
CFG_int(sysconf, platform, 2, "System platform. 0 = RingWide, 1 = RingEdge, 2 = RingEdge2")
|
||||||
CFG_int(sysconf, region, 1, "Board region. 1 = Jpn, 2 = USA, 4 = Exp, 8 = Chn")
|
CFG_int(sysconf, region, 1, "Board region. 1 = Jpn, 2 = USA, 4 = Exp, 8 = Chn")
|
||||||
CFG_bool(sysconf, rental, false, "")
|
CFG_bool(sysconf, rental, false, "")
|
||||||
CFG_str(sysconf, serial, "A000-00000000000", "")
|
|
||||||
CFG_str(sysconf, keyid, "A000-00000000000", "")
|
|
||||||
CFG_hex(sysconf, dipsw, 2, 40, "DIP Switch values") // Default 40 = 1280x720
|
CFG_hex(sysconf, dipsw, 2, 40, "DIP Switch values") // Default 40 = 1280x720
|
||||||
|
COMMENT("These serial numbers were automatically generated for you. Please don't change them unless someone has told you to.")
|
||||||
|
CFG_str(sysconf, pcb_serial, "", "")
|
||||||
|
CFG_str(sysconf, keychip_serial, "", "")
|
||||||
ENDSECTION(sysconf)
|
ENDSECTION(sysconf)
|
||||||
|
|
||||||
SECTION(window, "Game window positioning settings")
|
SECTION(window, "Game window positioning settings")
|
||||||
@ -106,7 +107,6 @@ ENDSECTION(hooks)
|
|||||||
SECTION(keys, "Raw keybinding data. Edit this using the built in binding tool!")
|
SECTION(keys, "Raw keybinding data. Edit this using the built in binding tool!")
|
||||||
CFG_int(keys, test, 0, "")
|
CFG_int(keys, test, 0, "")
|
||||||
CFG_int(keys, service, 0, "")
|
CFG_int(keys, service, 0, "")
|
||||||
CFG_int(keys, board_count, 1, "")
|
|
||||||
ENDSECTION(keys)
|
ENDSECTION(keys)
|
||||||
|
|
||||||
SECTION(devices, "Register attached hardware devices. COM4 is reserved for JVS.")
|
SECTION(devices, "Register attached hardware devices. COM4 is reserved for JVS.")
|
||||||
|
@ -27,3 +27,4 @@ extern config_t MiceConfig;
|
|||||||
void save_current_config(bool writeDefault);
|
void save_current_config(bool writeDefault);
|
||||||
void load_mice_config();
|
void load_mice_config();
|
||||||
void load_keybind_config();
|
void load_keybind_config();
|
||||||
|
void save_keybind_config();
|
||||||
|
@ -67,11 +67,16 @@ cleanup:
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline static void alphaNum(CHAR *lpAddr, BYTE val) {
|
inline static void alphaNum(CHAR *lpAddr, BYTE val) {
|
||||||
val %= 26 + 10;
|
// I and O are disallowed, hence the extra logic
|
||||||
|
val %= (26 - 2) + 10;
|
||||||
if (val < 10)
|
if (val < 10)
|
||||||
lpAddr[0] = '0' + val;
|
lpAddr[0] = '0' + val;
|
||||||
else
|
else if (val < 18)
|
||||||
lpAddr[0] = 'A' + (val - 10);
|
lpAddr[0] = 'A' + (val - 10);
|
||||||
|
else if (val < 23)
|
||||||
|
lpAddr[0] = 'J' + (val - 18);
|
||||||
|
else
|
||||||
|
lpAddr[0] = 'P' + (val - 23);
|
||||||
}
|
}
|
||||||
inline static void numeric(CHAR *lpAddr, BYTE val) {
|
inline static void numeric(CHAR *lpAddr, BYTE val) {
|
||||||
val %= 100;
|
val %= 100;
|
||||||
|
@ -40,10 +40,10 @@ void mdkPcpAbNetworkAddress(pcpa_t* stream, void* data) {
|
|||||||
void mdkPcpAbDvd(pcpa_t* stream, void* data) { pcpaSetSendPacket(stream, AB_DVD, "01"); }
|
void mdkPcpAbDvd(pcpa_t* stream, void* data) { pcpaSetSendPacket(stream, AB_DVD, "01"); }
|
||||||
|
|
||||||
void mdkPcpPbKeyId(pcpa_t* stream, void* data) {
|
void mdkPcpPbKeyId(pcpa_t* stream, void* data) {
|
||||||
pcpaSetSendPacket(stream, BIL_KEYID, MiceConfig.sysconf.keyid);
|
pcpaSetSendPacket(stream, BIL_KEYID, MiceConfig.sysconf.keychip_serial);
|
||||||
}
|
}
|
||||||
void mdkPcpPbMainId(pcpa_t* stream, void* data) {
|
void mdkPcpPbMainId(pcpa_t* stream, void* data) {
|
||||||
pcpaSetSendPacket(stream, BIL_MAINID, MiceConfig.sysconf.serial);
|
pcpaSetSendPacket(stream, BIL_MAINID, MiceConfig.sysconf.pcb_serial);
|
||||||
}
|
}
|
||||||
void mdkPcpPbPlayCount(pcpa_t* stream, void* data) {
|
void mdkPcpPbPlayCount(pcpa_t* stream, void* data) {
|
||||||
pcpaSetSendPacket(stream, BIL_PLAYCOUNT, "00000000");
|
pcpaSetSendPacket(stream, BIL_PLAYCOUNT, "00000000");
|
||||||
|
Loading…
Reference in New Issue
Block a user