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 "./util/_util.h"
|
||||
#include "micefs.h"
|
||||
#include "input_config.h"
|
||||
|
||||
#define size2int(x) ((int)((x) & 0x7fffffff))
|
||||
#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 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() {
|
||||
// Placeholders
|
||||
g_ActiveResponse[1] = '@';
|
||||
@ -74,41 +92,29 @@ static void populateActiveResponse() {
|
||||
g_ActiveResponse[9] = '@';
|
||||
g_ActiveResponse[10] = '@';
|
||||
|
||||
if (!GetAsyncKeyState(VK_LBUTTON)) return;
|
||||
|
||||
POINT pCursor;
|
||||
GetCursorPos(&pCursor);
|
||||
if (!mainWindow) return;
|
||||
if (!ScreenToClient(mainWindow, &pCursor)) return;
|
||||
|
||||
RECT winRect;
|
||||
if (!GetWindowRect(mainWindow, &winRect)) return;
|
||||
DWORD dwStyle = GetWindowLongW(mainWindow, GWL_STYLE);
|
||||
UnadjustWindowRect(&winRect, dwStyle, FALSE);
|
||||
|
||||
int w = winRect.right - winRect.left;
|
||||
int h = winRect.bottom - winRect.top;
|
||||
|
||||
float x = (float)pCursor.x / (float)(w);
|
||||
float y = (float)pCursor.y / (float)(h);
|
||||
if (GetAsyncKeyState(VK_LBUTTON)) {
|
||||
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
|
||||
WORD button;
|
||||
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;
|
||||
for (DWORD i = 0; i < nActiveTouches; i++) {
|
||||
handleOneButton(w, h, activeTouches[i].m_X, activeTouches[i].m_Y);
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
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)) {
|
||||
populateActiveResponse();
|
||||
comdev_write(dev, g_ActiveResponse, 14);
|
||||
Sleep(5); // 200Hz should be plenty
|
||||
Sleep(2);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -43,9 +43,9 @@ void set_eeprom_static_config() {
|
||||
.m_Rental = MiceConfig.sysconf.rental,
|
||||
};
|
||||
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;
|
||||
memcpy(Static.m_strSerialId, MiceConfig.sysconf.serial, len);
|
||||
memcpy(Static.m_strSerialId, MiceConfig.sysconf.pcb_serial, len);
|
||||
fix_crc(Static);
|
||||
memcpy(&EEPROM_DATA[AM_SYSDATAwH_STATIC_REG], &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) {
|
||||
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
|
||||
amiCrc32RInit();
|
||||
|
||||
load_mice_config();
|
||||
load_keybind_config();
|
||||
|
||||
// We're in a new context now, so need to reconfigure
|
||||
setup_logging();
|
||||
MiceSetLogBasename(exeNameC);
|
||||
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
|
||||
if (MiceConfig.drivers.mxsuperio) setup_mxsuperio();
|
||||
// MX JVS: Interacting with JVS-based devices
|
||||
if (MiceConfig.drivers.mxjvs) {
|
||||
setup_mxjvs();
|
||||
load_keybind_config();
|
||||
}
|
||||
if (MiceConfig.drivers.mxjvs) setup_mxjvs();
|
||||
// MX HW Reset: Forcibly reboot the machine
|
||||
if (MiceConfig.drivers.mxhwreset) setup_mxhwreset();
|
||||
// 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_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 "../../common.h"
|
||||
#include "jvs.h"
|
||||
|
||||
#define PLAYER_COUNT 2
|
||||
#define COIN_COUNTERS 2
|
||||
@ -24,15 +23,20 @@ static void Ctor(PMICE_JVS this) {
|
||||
this->m_VersionComm = 0x10;
|
||||
|
||||
// Coin + Test + 13 switches per player
|
||||
this->m_ButtonsPerPlayer = PLAYER_SWITCH_COUNT;
|
||||
this->m_Coins = COIN_COUNTERS;
|
||||
this->m_Players = PLAYER_COUNT;
|
||||
if (this->m_ButtonsPerPlayer == 0) this->m_ButtonsPerPlayer = PLAYER_SWITCH_COUNT;
|
||||
if (this->m_Coins == 0) this->m_Coins = COIN_COUNTERS;
|
||||
if (this->m_Players == 0) this->m_Players = PLAYER_COUNT;
|
||||
|
||||
this->m_NumButtons = this->m_Coins + 1 + (this->m_ButtonsPerPlayer * this->m_Players);
|
||||
this->m_ButtonStates = malloc(this->m_NumButtons * sizeof *this->m_ButtonStates);
|
||||
ZeroMemory(this->m_ButtonStates, this->m_NumButtons * sizeof *this->m_ButtonStates);
|
||||
this->m_Bindings = malloc(this->m_NumButtons * sizeof *this->m_Bindings);
|
||||
ZeroMemory(this->m_Bindings, this->m_NumButtons * sizeof *this->m_Bindings);
|
||||
if (this->m_NumButtons == 0)
|
||||
this->m_NumButtons = this->m_Coins + 1 + (this->m_ButtonsPerPlayer * this->m_Players);
|
||||
if (this->m_ButtonStates == NULL) {
|
||||
this->m_ButtonStates = malloc(this->m_NumButtons * sizeof *this->m_ButtonStates);
|
||||
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);
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include <Windows.h>
|
||||
|
||||
#include "../../common.h"
|
||||
#include "jvs.h"
|
||||
|
||||
#define PLAYER_COUNT 1
|
||||
#define COIN_COUNTERS 2
|
||||
@ -88,20 +87,12 @@ static JVS_STATUS Transact(PMICE_JVS this, BYTE command) {
|
||||
unsigned char coin_count;
|
||||
coin_count = MiceJvsRead(this);
|
||||
|
||||
// int coin1 = jvsKeybindings[board->num].buttons[0];
|
||||
// int coin2 = jvsKeybindings[board->num].buttons[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);
|
||||
// }
|
||||
if (MiceInputGetButtonState(&(this->m_Bindings[0]))) this->m_CoinCounts[0]++;
|
||||
if (MiceInputGetButtonState(&(this->m_Bindings[1]))) this->m_CoinCounts[1]++;
|
||||
|
||||
for (unsigned char slot = 0; slot < coin_count; slot++) {
|
||||
MiceJvsWrite(this, 0);
|
||||
MiceJvsWrite(this, 0);
|
||||
MiceJvsWrite(this, this->m_CoinCounts[slot] >> 8);
|
||||
MiceJvsWrite(this, this->m_CoinCounts[slot] & 0xff);
|
||||
}
|
||||
return JVS_STATUS_OK;
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include <Windows.h>
|
||||
|
||||
#include "../../common.h"
|
||||
#include "jvs.h"
|
||||
|
||||
static void Ctor(PMICE_JVS this) {
|
||||
this->vftable = &_MiceJvsBase_vftable;
|
||||
|
@ -4,10 +4,9 @@
|
||||
#include "../common.h"
|
||||
#include "../input.h"
|
||||
#include "../key_config.h"
|
||||
#include "jvs_boards/jvs.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 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 jvsOutUnmasked[MICE_JVS_MAX];
|
||||
BYTE jvsOutMasked[MICE_JVS_MASKED];
|
||||
void mxjvs_handle(unsigned char* lpMaskedIn, short nMaskedCount, unsigned char* outData,
|
||||
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;
|
||||
BOOL wasMark = FALSE;
|
||||
for (int i = 0; i < nMaskedCount; i++) {
|
||||
@ -81,7 +104,7 @@ void mxjvs_handle(unsigned char* lpMaskedIn, short nMaskedCount, unsigned char*
|
||||
return;
|
||||
}
|
||||
|
||||
DWORD nBoardCount = MiceConfig.keys.board_count;
|
||||
DWORD nBoardCount = g_MiceJvsNumBoards;
|
||||
if (nBoardCount > _countof(_MiceJvsBoards)) nBoardCount = _countof(_MiceJvsBoards);
|
||||
|
||||
// Not broadcast, not master-bound, and within bounds
|
||||
|
@ -2,10 +2,12 @@
|
||||
|
||||
#include "../../sysconf.h"
|
||||
|
||||
BYTE parallel_flags = 0x00;
|
||||
BYTE parallel_ctrl = 0x00;
|
||||
BYTE parallel_status = 0x00;
|
||||
BYTE parallel_data = 0x00;
|
||||
static HANDLE parallel_ctrl_changed_event = NULL;
|
||||
|
||||
static BYTE parallel_flags = 0x00;
|
||||
static BYTE parallel_ctrl = 0x00;
|
||||
static BYTE parallel_status = 0x00;
|
||||
static BYTE parallel_data = 0x00;
|
||||
|
||||
BYTE KEYCHIP_ID[16] = KEY_ID;
|
||||
BYTE _MAIN_ID[16] = MAIN_ID;
|
||||
@ -71,6 +73,7 @@ BOOL WINAPI mxparallel_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCod
|
||||
return TRUE;
|
||||
case IOCTL_MXPARALLEL_WRITE_CTRL_PORT:
|
||||
parallel_ctrl = ((LPBYTE)lpInBuffer)[0];
|
||||
SetEvent(parallel_ctrl_changed_event);
|
||||
// log_warning(plfMxParallel, "Write ctrl %08x", parallel_ctrl);
|
||||
outLen(0);
|
||||
return TRUE;
|
||||
@ -101,12 +104,12 @@ BOOL WINAPI mxparallel_DeviceIoControl(file_context_t* ctx, DWORD dwIoControlCod
|
||||
void micexkTransportSend(unsigned char* send_data, int nbytes) {
|
||||
setAck;
|
||||
for (int i = 0; i < nbytes; i++) {
|
||||
while (_Strobe) YieldProcessor();
|
||||
WaitForNotStrobe;
|
||||
setBusy;
|
||||
parallel_data = send_data[i];
|
||||
while (!_Strobe) YieldProcessor();
|
||||
WaitForStrobe;
|
||||
clearBusy;
|
||||
while (_Strobe) YieldProcessor();
|
||||
WaitForNotStrobe;
|
||||
}
|
||||
clearAck;
|
||||
}
|
||||
@ -120,10 +123,10 @@ void micexkSendPacket(unsigned char* send_data) {
|
||||
void micexkTransportRecv(unsigned char* buffer, int nbytes) {
|
||||
for (int i = 0; i < nbytes; i++) {
|
||||
clearBusy;
|
||||
while (!_Strobe) YieldProcessor();
|
||||
WaitForStrobe;
|
||||
buffer[i] = parallel_data;
|
||||
setBusy;
|
||||
while (_Strobe) YieldProcessor();
|
||||
WaitForNotStrobe;
|
||||
clearBusy;
|
||||
}
|
||||
}
|
||||
@ -450,6 +453,8 @@ void setup_mxparallel() {
|
||||
|
||||
init_nv_storage();
|
||||
|
||||
parallel_ctrl_changed_event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
|
||||
file_hook_t* mxparallel = new_file_hook(L"\\\\.\\mxparallel");
|
||||
mxparallel->DeviceIoControl = &mxparallel_DeviceIoControl;
|
||||
hook_file(mxparallel);
|
||||
|
@ -17,7 +17,6 @@ typedef struct {
|
||||
} nvram_data_block_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
void micexkTransportSend(unsigned char* send_data, int nbytes);
|
||||
void micexkSendPacket(unsigned char* send_data);
|
||||
void micexkTransportRecv(unsigned char* buffer, int nbytes);
|
||||
@ -59,3 +58,17 @@ static BYTE parallel_data;
|
||||
#define _Reset getControl(0x04)
|
||||
#define _SelPrint getControl(0x08)
|
||||
#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 "devices/_devices.h"
|
||||
#include "drivers/jvs_boards/jvs.h"
|
||||
#include "input.h"
|
||||
#include "key_config.h"
|
||||
|
||||
@ -110,7 +109,7 @@ void _MiceSetupMaimai() {
|
||||
MiceConfig.sysconf.dipsw = 0b01111000;
|
||||
MiceConfig.window.nosize = true;
|
||||
|
||||
if (MiceConfig.keys.board_count == 0) MiceConfig.keys.board_count = 1;
|
||||
g_MiceJvsNumBoards = 1;
|
||||
|
||||
free(_MiceJvsBoards[0].m_Bindings);
|
||||
_MiceJvsBoards[0].m_Bindings = malloc(sizeof maimaiDefaultBindings);
|
||||
@ -123,6 +122,9 @@ void _MiceSetupMaimai() {
|
||||
_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.
|
||||
make_dirs(MiceIpcRelativePath("dev\\w\\maimai"));
|
||||
make_dirs(MiceIpcRelativePath("dev\\v\\maimai"));
|
||||
@ -139,7 +141,7 @@ void _MiceSetupApm() {
|
||||
|
||||
MiceConfig.sysconf.dipsw = 0b01000000; // 720p
|
||||
|
||||
if (MiceConfig.keys.board_count == 0) MiceConfig.keys.board_count = 1;
|
||||
g_MiceJvsNumBoards = 1;
|
||||
|
||||
free(_MiceJvsBoards[0].m_Bindings);
|
||||
_MiceJvsBoards[0].m_Bindings = malloc(sizeof apmDefaultBindings);
|
||||
@ -151,6 +153,8 @@ void _MiceSetupApm() {
|
||||
free(_MiceJvsBoards[0].m_ButtonStates);
|
||||
_MiceJvsBoards[0].m_ButtonStates =
|
||||
malloc(_countof(apmDefaultBindings) * sizeof *_MiceJvsBoards[0].m_ButtonStates);
|
||||
|
||||
save_keybind_config();
|
||||
}
|
||||
|
||||
void _MiceGotGameId(char game_id[4]) {
|
||||
@ -173,44 +177,7 @@ void _MiceGotGameId(char game_id[4]) {
|
||||
_MiceSetupMaimai();
|
||||
} else if (IS_GAME(SBYG /* APM2 */) || IS_GAME(SDCM /* UNIB */)) {
|
||||
log_info(plfBoot, "Detect game APM2");
|
||||
|
||||
_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 */)) {
|
||||
log_info(plfBoot, "Detect game Sega & Sonic All-Stars Racing Arcade");
|
||||
|
||||
|
@ -2,8 +2,8 @@
|
||||
#ifndef CIMGUI_DEFINE_ENUMS_AND_STRUCTS
|
||||
#define CIMGUI_DEFINE_ENUMS_AND_STRUCTS
|
||||
#endif
|
||||
#include "../common.h"
|
||||
#include "../devices/smb_at24c64an.h"
|
||||
#include "../drivers/jvs_boards/jvs.h"
|
||||
#include "../key_config.h"
|
||||
#include "cimgui.h"
|
||||
#include "imgui/backends/GL/freeglut.h"
|
||||
@ -152,6 +152,7 @@ void hud_card(ImGuiKey open_key) {
|
||||
igEnd();
|
||||
}
|
||||
|
||||
extern float jvsRate;
|
||||
void hud_fps() {
|
||||
if (igBegin("FPS", NULL,
|
||||
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse |
|
||||
@ -167,6 +168,7 @@ void hud_fps() {
|
||||
|
||||
igText("FPS: %.1f", io->Framerate);
|
||||
igText(" dT: %.2fms", 1000 / io->Framerate);
|
||||
igText("JVS Rate: %.2f", jvsRate);
|
||||
}
|
||||
|
||||
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
|
||||
staticChanged |= AddSettingString(
|
||||
"PCB serial number",
|
||||
(MiceConfig.sysconf.serial && MiceConfig.sysconf.serial[0] == 'M' ? SERIAL_HELP : NULL),
|
||||
&MiceConfig.sysconf.serial);
|
||||
(MiceConfig.sysconf.pcb_serial && MiceConfig.sysconf.pcb_serial[0] == 'M' ? SERIAL_HELP
|
||||
: NULL),
|
||||
&MiceConfig.sysconf.pcb_serial);
|
||||
if (staticChanged) {
|
||||
build_eeprom();
|
||||
save_current_config(false);
|
||||
}
|
||||
if (AddSettingString(
|
||||
"Keychip serial number",
|
||||
(MiceConfig.sysconf.keyid && MiceConfig.sysconf.keyid[0] == 'M' ? SERIAL_HELP : NULL),
|
||||
&MiceConfig.sysconf.keyid)) {
|
||||
(MiceConfig.sysconf.keychip_serial && MiceConfig.sysconf.keychip_serial[0] == 'M'
|
||||
? SERIAL_HELP
|
||||
: NULL),
|
||||
&MiceConfig.sysconf.keychip_serial)) {
|
||||
save_current_config(false);
|
||||
}
|
||||
|
||||
@ -789,16 +794,16 @@ void AddSettingButton(PMICE_JVS board, int player, int button) {
|
||||
igSameLine(0, -1);
|
||||
if (igButton(clear, vec0)) {
|
||||
bind->m_Type = MICE_BB_TYPE_UNBOUND;
|
||||
save_current_config(false);
|
||||
save_keybind_config();
|
||||
}
|
||||
}
|
||||
igNextColumn();
|
||||
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();
|
||||
igNextColumn();
|
||||
|
||||
if (igKeyBindPopup_New(name, bind)) save_current_config(false);
|
||||
if (igKeyBindPopup_New(name, bind)) save_keybind_config();
|
||||
}
|
||||
|
||||
void AddButtonsForBoard(PMICE_JVS board) {
|
||||
@ -841,33 +846,34 @@ void tab_jvs_board(int num) {
|
||||
|
||||
igSeparator();
|
||||
|
||||
AddButtonsForBoard(&_MiceJvsBoards[0]);
|
||||
AddButtonsForBoard(&_MiceJvsBoards[num]);
|
||||
|
||||
igSeparator();
|
||||
AddSetting("Test", NULL);
|
||||
char keyName[16];
|
||||
if (jvsKeybindings[num].test == 0) {
|
||||
igTextColored(DISABLED_COL, "None");
|
||||
} else {
|
||||
GetKeyNameTextA(MapVirtualKey(jvsKeybindings[num].test, MAPVK_VK_TO_VSC) << 16, keyName,
|
||||
_countof(keyName));
|
||||
igTextUnformatted(keyName, NULL);
|
||||
}
|
||||
igNextColumn();
|
||||
if (igButton("Bind##JvsTest", vec0)) igOpenPopup_Str("BindJvsTest", ImGuiPopupFlags_None);
|
||||
if (jvsKeybindings[num].test) {
|
||||
igSameLine(0, -1);
|
||||
if (igButton("Clear##ClearJvsTest", vec0)) {
|
||||
jvsKeybindings[num].test = 0;
|
||||
save_current_config(false);
|
||||
}
|
||||
}
|
||||
int boundKey;
|
||||
if (igKeyBindPopup("BindJvsTest", &boundKey))
|
||||
if (boundKey != -1) {
|
||||
jvsKeybindings[num].test = boundKey;
|
||||
save_current_config(false);
|
||||
}
|
||||
// TODO: RESTORE THIS!
|
||||
// igSeparator();
|
||||
// AddSetting("Test", NULL);
|
||||
// char keyName[16];
|
||||
// if (jvsKeybindings[num].test == 0) {
|
||||
// igTextColored(DISABLED_COL, "None");
|
||||
// } else {
|
||||
// GetKeyNameTextA(MapVirtualKey(jvsKeybindings[num].test, MAPVK_VK_TO_VSC) << 16, keyName,
|
||||
// _countof(keyName));
|
||||
// igTextUnformatted(keyName, NULL);
|
||||
// }
|
||||
// igNextColumn();
|
||||
// if (igButton("Bind##JvsTest", vec0)) igOpenPopup_Str("BindJvsTest", ImGuiPopupFlags_None);
|
||||
// if (jvsKeybindings[num].test) {
|
||||
// igSameLine(0, -1);
|
||||
// if (igButton("Clear##ClearJvsTest", vec0)) {
|
||||
// jvsKeybindings[num].test = 0;
|
||||
// save_keybind_config();
|
||||
// }
|
||||
// }
|
||||
// int boundKey;
|
||||
// if (igKeyBindPopup("BindJvsTest", &boundKey))
|
||||
// if (boundKey != -1) {
|
||||
// jvsKeybindings[num].test = boundKey;
|
||||
// save_keybind_config();
|
||||
// }
|
||||
|
||||
igEndColumns();
|
||||
|
||||
@ -940,15 +946,14 @@ void tab_system_buttons() {
|
||||
}
|
||||
|
||||
void tab_main_keybinds() {
|
||||
if (igInputInt("Number of JVS boards", &MiceConfig.keys.board_count, 1, 1,
|
||||
ImGuiInputTextFlags_None)) {
|
||||
if (MiceConfig.keys.board_count < 0) MiceConfig.keys.board_count = 0;
|
||||
if (MiceConfig.keys.board_count > JVS_IO_MAX) MiceConfig.keys.board_count = JVS_IO_MAX;
|
||||
save_current_config(false);
|
||||
if (igInputInt("Number of JVS boards", &g_MiceJvsNumBoards, 1, 1, ImGuiInputTextFlags_None)) {
|
||||
if (g_MiceJvsNumBoards < 1) g_MiceJvsNumBoards = 1;
|
||||
if (g_MiceJvsNumBoards > JVS_IO_MAX) g_MiceJvsNumBoards = JVS_IO_MAX;
|
||||
save_keybind_config();
|
||||
}
|
||||
|
||||
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];
|
||||
snprintf(name, _countof(name), "Board %d", i + 1);
|
||||
if (igBeginTabItem(name, NULL, 0)) {
|
||||
|
@ -4,6 +4,101 @@
|
||||
|
||||
#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);
|
||||
|
||||
HWND mainWindow = NULL;
|
||||
@ -152,10 +247,74 @@ void register_gui_hook(FnEndScene* end_scene) {
|
||||
*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;
|
||||
WNDPROC OriginalWndProc = NULL;
|
||||
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass,
|
||||
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) {
|
||||
while (ShowCursor(TRUE) < 0)
|
||||
@ -167,6 +326,25 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UIN
|
||||
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);
|
||||
}
|
||||
|
||||
@ -186,13 +364,19 @@ void post_win_create(HWND hWnd) {
|
||||
DetourAttach((PVOID*)&TrueEndScene, hkEndScene);
|
||||
DetourTransactionCommit();
|
||||
}
|
||||
|
||||
if (hWnd && !SetWindowSubclass(hWnd, WndProc, (UINT_PTR)&WndProc, (DWORD_PTR)NULL)) {
|
||||
log_error(plfGUI, "failed to SetWindowSubclass(%d)", GetLastError());
|
||||
}
|
||||
// MiceInputInit will be called by our D3D9 hooks instead
|
||||
} else {
|
||||
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 };
|
||||
|
@ -43,6 +43,14 @@ void register_gui_hook(FnEndScene* end_scene);
|
||||
void hook_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);
|
||||
extern HWND mainWindow;
|
||||
extern DWORD changeCursorState;
|
||||
|
@ -36,17 +36,21 @@ DWORD WINAPI FakeGetTempPathW(DWORD nBufferLength, LPWSTR lpBuffer) {
|
||||
}
|
||||
|
||||
HCURSOR WINAPI FakeLoadCursorFromFileA(LPCSTR lpFileName) { return (HANDLE)1; }
|
||||
BOOL FakeSetSystemCursor(HCURSOR hcur, DWORD id) { return TRUE; }
|
||||
BOOL FakeDeleteObject(HGDIOBJ ho) { return TRUE; }
|
||||
BOOL WINAPI FakeSetSystemCursor(HCURSOR hcur, DWORD id) { return TRUE; }
|
||||
BOOL WINAPI FakeDeleteObject(HGDIOBJ ho) { return TRUE; }
|
||||
|
||||
FARPROC FakeGetProcAddress(HMODULE hModule, LPCSTR lpProcName) {
|
||||
log_trace(plfSystem, "GetProcAddress(%s)", lpProcName);
|
||||
FARPROC WINAPI FakeGetProcAddress(HMODULE hModule, LPCSTR lpProcName) {
|
||||
// log_error(plfSystem, "GetProcAddress(%s)", lpProcName);
|
||||
return TrueGetProcAddress(hModule, lpProcName);
|
||||
}
|
||||
HMODULE FakeGetModuleHandleA(LPCSTR lpModuleName) {
|
||||
log_trace(plfSystem, "GetModuleHandleA(%s)", lpModuleName);
|
||||
HMODULE WINAPI FakeGetModuleHandleA(LPCSTR lpModuleName) {
|
||||
// log_game(plfSystem, "GetModuleHandleA(%s)", lpModuleName);
|
||||
return TrueGetModuleHandleA(lpModuleName);
|
||||
}
|
||||
HMODULE WINAPI FakeGetModuleHandleW(LPCWSTR lpModuleName) {
|
||||
// log_game(plfSystem, "GetModuleHandleW(%ls)", lpModuleName);
|
||||
return TrueGetModuleHandleW(lpModuleName);
|
||||
}
|
||||
|
||||
LONG WINAPI FakeRtlGetVersion(PRTL_OSVERSIONINFOW lpVersionInformation) {
|
||||
log_trace(plfSystem, "RtlGetVersion(%p)", lpVersionInformation);
|
||||
@ -89,8 +93,9 @@ void hook_system() {
|
||||
hook("Kernel32.dll", "GetVolumeInformationW", FakeGetVolumeInformationW, NULL);
|
||||
hook("Kernel32.dll", "GetTempPathW", FakeGetTempPathW, NULL);
|
||||
// hook("Kernel32.dll", "GetVersionExA", FakeGetVersionExA, NULL);
|
||||
// hook("Kernel32.dll", "GetProcAddress", FakeGetProcAddress, (void*)&TrueGetProcAddress);
|
||||
// hook("Kernel32.dll", "GetModuleHandleA", FakeGetModuleHandleA, (void*)&TrueGetModuleHandleA);
|
||||
hook("Kernel32.dll", "GetProcAddress", FakeGetProcAddress, (void*)&TrueGetProcAddress);
|
||||
hook("Kernel32.dll", "GetModuleHandleA", FakeGetModuleHandleA, (void*)&TrueGetModuleHandleA);
|
||||
hook("Kernel32.dll", "GetModuleHandleW", FakeGetModuleHandleW, (void*)&TrueGetModuleHandleW);
|
||||
hook("Kernel32.dll", "LoadLibraryA", FakeLoadLibraryA, (void*)&TrueLoadLibraryA);
|
||||
hook("Kernel32.dll", "LoadLibraryW", FakeLoadLibraryW, (void*)&TrueLoadLibraryW);
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
FARPROC(WINAPI* TrueGetProcAddress)(HMODULE hModule, LPCSTR lpProcName);
|
||||
HMODULE(WINAPI* TrueGetModuleHandleA)(LPCSTR lpModuleName);
|
||||
HMODULE(WINAPI* TrueGetModuleHandleW)(LPCWSTR lpModuleName);
|
||||
HMODULE(WINAPI* TrueLoadLibraryA)(LPCSTR 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_BUTTON_PAIR_COUNT 15
|
||||
|
||||
struct {
|
||||
int buttons[JVS_BUTTON_PAIR_COUNT * 2];
|
||||
bool invert[JVS_BUTTON_PAIR_COUNT * 2];
|
||||
int test;
|
||||
int notdefault;
|
||||
} jvsKeybindings[JVS_IO_MAX] = { 0 };
|
||||
// struct {
|
||||
// int buttons[JVS_BUTTON_PAIR_COUNT * 2];
|
||||
// bool invert[JVS_BUTTON_PAIR_COUNT * 2];
|
||||
// int test;
|
||||
// int notdefault;
|
||||
// } jvsKeybindings[JVS_IO_MAX] = { 0 };
|
||||
|
||||
int keySystemTest = 0;
|
||||
|
@ -24,6 +24,7 @@ shared_library(
|
||||
'games.c',
|
||||
'input.c',
|
||||
'micefs.c',
|
||||
'input_config.c',
|
||||
|
||||
'dllmain.c',
|
||||
],
|
||||
|
@ -6,12 +6,9 @@
|
||||
|
||||
#include "../../../../subprojects/inih_dep/ini.h"
|
||||
#include "../../dll/devices/smb_pca9535.h"
|
||||
#include "../../dll/drivers/jvs_boards/jvs.h"
|
||||
#include "../../dll/hooks/files.h"
|
||||
#include "../../dll/key_config.h"
|
||||
|
||||
MICE_JVS _MiceJvsBoards[JVS_IO_MAX];
|
||||
|
||||
config_t MiceConfig = {
|
||||
#define SECTION(s, comment) .s = {
|
||||
#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);
|
||||
}
|
||||
|
||||
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];
|
||||
void save_current_config(bool writeDefault) {
|
||||
CreateDirectoryA("mice", NULL); // TODO: A touch nicer?
|
||||
|
||||
save_keybinds();
|
||||
|
||||
FILE *config_file;
|
||||
fopen_s(&config_file, CONFIG_PATH, "w");
|
||||
if (config_file == NULL) {
|
||||
@ -270,24 +142,30 @@ void load_mice_config() {
|
||||
if (ini_parse(CONFIG_PATH, handler, &MiceConfig) < 0) {
|
||||
printf("Loading config defaults\n");
|
||||
|
||||
if (MiceConfig.sysconf.serial) free(MiceConfig.sysconf.serial);
|
||||
MiceConfig.sysconf.serial = malloc(17);
|
||||
if (MiceConfig.sysconf.keyid) free(MiceConfig.sysconf.keyid);
|
||||
MiceConfig.sysconf.keyid = malloc(17);
|
||||
GetSerialNumbers(MiceConfig.sysconf.serial, MiceConfig.sysconf.keyid);
|
||||
if (MiceConfig.sysconf.pcb_serial) free(MiceConfig.sysconf.pcb_serial);
|
||||
MiceConfig.sysconf.pcb_serial = malloc(17);
|
||||
memset(MiceConfig.sysconf.pcb_serial, 0, 17);
|
||||
if (MiceConfig.sysconf.keychip_serial) free(MiceConfig.sysconf.keychip_serial);
|
||||
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);
|
||||
}
|
||||
|
||||
if (!MiceConfig.sysconf.serial || strlen(MiceConfig.sysconf.serial) == 0) {
|
||||
if (MiceConfig.sysconf.serial) free(MiceConfig.sysconf.serial);
|
||||
MiceConfig.sysconf.serial = malloc(17);
|
||||
GetSerialNumbers(MiceConfig.sysconf.serial, NULL);
|
||||
if (!MiceConfig.sysconf.pcb_serial || strlen(MiceConfig.sysconf.pcb_serial) == 0) {
|
||||
if (MiceConfig.sysconf.pcb_serial) free(MiceConfig.sysconf.pcb_serial);
|
||||
MiceConfig.sysconf.pcb_serial = malloc(17);
|
||||
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.keyid) free(MiceConfig.sysconf.keyid);
|
||||
MiceConfig.sysconf.keyid = malloc(17);
|
||||
GetSerialNumbers(NULL, MiceConfig.sysconf.keyid);
|
||||
if (!MiceConfig.sysconf.keychip_serial || strlen(MiceConfig.sysconf.keychip_serial) == 0) {
|
||||
if (MiceConfig.sysconf.keychip_serial) free(MiceConfig.sysconf.keychip_serial);
|
||||
MiceConfig.sysconf.keychip_serial = malloc(17);
|
||||
memset(MiceConfig.sysconf.keychip_serial, 0, 17);
|
||||
GetSerialNumbers(NULL, MiceConfig.sysconf.keychip_serial);
|
||||
save_current_config(false);
|
||||
}
|
||||
|
||||
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, region, 1, "Board region. 1 = Jpn, 2 = USA, 4 = Exp, 8 = Chn")
|
||||
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
|
||||
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)
|
||||
|
||||
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!")
|
||||
CFG_int(keys, test, 0, "")
|
||||
CFG_int(keys, service, 0, "")
|
||||
CFG_int(keys, board_count, 1, "")
|
||||
ENDSECTION(keys)
|
||||
|
||||
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 load_mice_config();
|
||||
void load_keybind_config();
|
||||
void save_keybind_config();
|
||||
|
@ -67,11 +67,16 @@ cleanup:
|
||||
}
|
||||
|
||||
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)
|
||||
lpAddr[0] = '0' + val;
|
||||
else
|
||||
else if (val < 18)
|
||||
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) {
|
||||
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 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) {
|
||||
pcpaSetSendPacket(stream, BIL_MAINID, MiceConfig.sysconf.serial);
|
||||
pcpaSetSendPacket(stream, BIL_MAINID, MiceConfig.sysconf.pcb_serial);
|
||||
}
|
||||
void mdkPcpPbPlayCount(pcpa_t* stream, void* data) {
|
||||
pcpaSetSendPacket(stream, BIL_PLAYCOUNT, "00000000");
|
||||
|
Loading…
Reference in New Issue
Block a user