Huge UI overhaul and OpenGL support

This commit is contained in:
Bottersnike
2023-02-14 07:09:08 +00:00
parent c418e30d12
commit dd4f7f97a5
46 changed files with 2768 additions and 571 deletions

View File

@@ -1,5 +1,10 @@
inih = subproject('inih_dep')
cimgui = subproject('cimgui_dep', default_options: ['win32=enabled', 'dx9=enabled'])
cimgui = subproject('cimgui_dep', default_options: [
'win32=enabled',
'dx9=enabled',
'glut=enabled',
'opengl3=enabled',
])
libs_dir = meson.current_source_dir()

View File

@@ -186,7 +186,10 @@ static DWORD WINAPI led_null_thread(com_device_t* dev) {
while (1) Sleep(10000000);
}
void led_overlay(IDirect3DDevice9* dev) {
void __stdcall led_overlay(unsigned int hookType, IDirect3DDevice9* dev) {
// maimai is DX9, so no point handling anything else anyway
if (hookType != UI_HOOK_DX9) return;
ShowCursor(true);
D3DDEVICE_CREATION_PARAMETERS cparams;
RECT rect;

View File

@@ -36,11 +36,6 @@ void eeprom_restore() {
_CloseHandle(dump);
}
#define SET_IP(val, a, b, c, d) \
do { \
*(uint32_t*)&val = (uint32_t)((a << 24) | (b << 16) | (c << 8) | d); \
} while (0)
#define fix_crc(block) \
do { \
(block).m_Crc = amiCrc32RCalc(sizeof(block) - 4, (BYTE*)(&(block)) + 4, 0); \
@@ -48,38 +43,24 @@ void eeprom_restore() {
void set_eeprom_network_config() {
AM_SYSDATAwH_NETWORK_ETH0 NetEth0 = { 0 };
NetEth0.m_Eth.m_Flag = 0;
NetEth0.m_Eth.m_IpAddress = MiceConfig.network.ip_address;
NetEth0.m_Eth.m_SubnetMask = MiceConfig.network.subnet_mask;
NetEth0.m_Eth.m_Gateway = MiceConfig.network.gateway;
NetEth0.m_Eth.m_PrimaryDns = MiceConfig.network.primary_dns;
NetEth0.m_Eth.m_SecondaryDns = MiceConfig.network.secondary_dns;
NetEth0.m_Eth.m_Flag = 0; // TODO: Allow DHCP
NetEth0.m_Eth.m_IpAddress = _byteswap_ulong(MiceConfig.network.ip_address);
NetEth0.m_Eth.m_SubnetMask = _byteswap_ulong(MiceConfig.network.subnet_mask);
NetEth0.m_Eth.m_Gateway = _byteswap_ulong(MiceConfig.network.gateway);
NetEth0.m_Eth.m_PrimaryDns = _byteswap_ulong(MiceConfig.network.primary_dns);
NetEth0.m_Eth.m_SecondaryDns = _byteswap_ulong(MiceConfig.network.secondary_dns);
fix_crc(NetEth0);
memcpy(&EEPROM_DATA[AM_SYSDATAwH_NETWORK_ETH0_REG], &NetEth0, sizeof NetEth0);
memcpy(&EEPROM_DATA[AM_SYSDATAwH_NETWORK_ETH0_DUP], &NetEth0, sizeof NetEth0);
// TODO: Does anything ever use ETH1?
AM_SYSDATAwH_NETWORK_ETH1 NetEth1 = { 0 };
fix_crc(NetEth1);
memcpy(&EEPROM_DATA[AM_SYSDATAwH_NETWORK_ETH1_REG], &NetEth1, sizeof NetEth1);
memcpy(&EEPROM_DATA[AM_SYSDATAwH_NETWORK_ETH1_DUP], &NetEth1, sizeof NetEth1);
}
int build_eeprom() {
static BOOL built = false;
if (built) return 0;
built = true;
if (FileExists(EEPROM_DUMP)) {
eeprom_restore();
// Our network config always gets priority
set_eeprom_network_config();
return 0;
}
log_info("eeprom", "Building default EEPROM file");
memset(EEPROM_DATA, 0xff, sizeof EEPROM_DATA);
void set_eeprom_static_config() {
AM_SYSDATAwH_STATIC Static = {
.m_Region = MiceConfig.sysconf.region & (1 | 2 | 4 | 8),
.m_Rental = MiceConfig.sysconf.rental,
@@ -88,6 +69,24 @@ int build_eeprom() {
fix_crc(Static);
memcpy(&EEPROM_DATA[AM_SYSDATAwH_STATIC_REG], &Static, sizeof Static);
memcpy(&EEPROM_DATA[AM_SYSDATAwH_STATIC_DUP], &Static, sizeof Static);
}
void build_eeprom() {
if (FileExists(EEPROM_DUMP)) {
eeprom_restore();
// Our network and static config always gets priority
set_eeprom_static_config();
set_eeprom_network_config();
eeprom_dump();
return;
}
log_info("eeprom", "Building default EEPROM file");
memset(EEPROM_DATA, 0xff, sizeof EEPROM_DATA);
set_eeprom_static_config();
AM_SYSDATAwH_CREDIT Credit = {
.m_Config = {
@@ -105,10 +104,10 @@ int build_eeprom() {
AM_SYSDATAwH_HISTORY History = { 0 };
// TODO: Game ID here should be configurable.
History.m_GameId[0] = GAME_ID_0;
History.m_GameId[1] = GAME_ID_1;
History.m_GameId[2] = GAME_ID_2;
History.m_GameId[3] = GAME_ID_3;
History.m_GameId[0] = '-';
History.m_GameId[1] = '-';
History.m_GameId[2] = '-';
History.m_GameId[3] = '-';
History.m_Region = MiceConfig.sysconf.region & (1 | 2 | 4 | 8);
fix_crc(History);
memcpy(&EEPROM_DATA[AM_SYSDATAwH_HISTORY_REG], &History, sizeof History);
@@ -131,11 +130,21 @@ int build_eeprom() {
memcpy(&EEPROM_DATA[AM_SYSDATAwH_ALPB_DEV_CONFIG_DUP], &DevConfig, sizeof DevConfig);
eeprom_dump();
return 1;
}
void ensure_valid_eeprom() {
static BOOL built = false;
if (built) {
eeprom_restore();
return;
}
build_eeprom();
built = true;
}
void eeprom_read(WORD addr, BYTE* data, BYTE length) {
if (!build_eeprom()) eeprom_restore();
ensure_valid_eeprom();
if (addr >= sizeof EEPROM_DATA) return;
if (length + addr > sizeof EEPROM_DATA) length = (sizeof EEPROM_DATA - addr) & 0xff;
@@ -143,7 +152,7 @@ void eeprom_read(WORD addr, BYTE* data, BYTE length) {
memcpy(data, &EEPROM_DATA[addr], length);
}
void eeprom_write(WORD addr, BYTE* data, BYTE length) {
if (!build_eeprom()) eeprom_restore();
ensure_valid_eeprom();
if (addr >= sizeof EEPROM_DATA) return;
if (length + addr > sizeof EEPROM_DATA) length = (sizeof EEPROM_DATA - addr) & 0xff;

View File

@@ -13,3 +13,5 @@ smbus_callback_t smbus_AT24C64AN_read;
#define AT24C64AN_ADDRESS \
(0b1010'000 | (AT24C64AN_PIN_A2 << 2) | (AT24C64AN_PIN_A1 << 1) | AT24C64AN_PIN_A0)
void build_eeprom(void);

View File

@@ -1,36 +1,47 @@
#include "_devices.h"
#include "smb_pca9535.h"
uint16_t pca9535_config = 0xffff;
#include "../key_config.h"
static uint16_t pca9535_config = 0xffff;
static uint8_t out[2] = { 0xFF, 0xFF };
static uint8_t inv[2] = { 0x00, 0x00 };
/**
* RingEdge config (will be set by amlib):
* config = { 0xFF, 0xFC }
*
* LEDs are on IO1_0 and IO1_1
*/
static uint8_t config[2] = { 0xFF, 0xFF };
BOOL smbus_PCA9535_write(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
switch (cmd) {
case ICH9_CMD_BYTE_DATA:
switch (code) {
case PCA9535_IN0:
log_error("pca9535", "Write PCA9535_IN0 unimplemented!");
case PCA9535_REG_IN0:
return FALSE;
case PCA9535_IN1:
log_error("pca9535", "Write PCA9535_IN1 unimplemented!");
case PCA9535_REG_IN1:
return FALSE;
case PCA9535_OUT0:
log_info("pca9535", "Out 0: %02x", data[0]);
case PCA9535_REG_OUT0:
out[0] = data[0];
return TRUE;
case PCA9535_OUT1:
log_info("pca9535", "Out 1: %02x", data[0]);
case PCA9535_REG_OUT1:
out[1] = data[0];
return TRUE;
case PCA9535_INV0:
log_info("pca9535", "Inv 0: %02x", data[0]);
case PCA9535_REG_INV0:
inv[0] = data[0];
return TRUE;
case PCA9535_INV1:
log_info("pca9535", "Inv 1: %02x", data[0]);
case PCA9535_REG_INV1:
inv[1] = data[0];
return TRUE;
case PCA9535_CONF0:
log_info("pca9535", "Conf 0: %02x", data[0]);
pca9535_config = (data[0] << 8) | (pca9535_config & 0xff);
case PCA9535_REG_CONF0:
config[0] = data[0];
return TRUE;
case PCA9535_CONF1:
log_info("pca9535", "Conf 1: %02x", data[0]);
pca9535_config = data[0] | (pca9535_config & 0xff00);
case PCA9535_REG_CONF1:
config[1] = data[0];
return TRUE;
default:
log_error("pca9535", "Unknown write command: %02x", code);
@@ -42,23 +53,51 @@ BOOL smbus_PCA9535_write(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
}
}
#define DIPSW_PORTRAIT 0b0000'0'000
#define DIPSW_LANDSCAPE 0b0000'1'000
/**
* Supported resolutions by amPlatform:
* 640x480: VGA
* 1024x600: WSVGA
* 1024x768: XGA
* 1280x720: 720P
* 1280x1024: WUXGA
* 1360x768: WVGA
* 1920x1080: 1080P
* 1440x900: WXGAPlus
* 1680x1050: WSXGAPlus
* 1600x1200: UXGA
* 1920x1200: WYXGA
* 1280x768: WXGA1280
* 800x600: SVGA
* 800x480: WVGA
*
* DIPSW Resolutions:
* [0]: 640x480
* [1]: 640x480
* [2]: 1024x600
* [3]: 1024x768
* [4]: 1280x720
* [5]: 1280x1024
* [6]: 1360x768
* [7]: 1920x1080
*/
#define DIPSW_RES_1920x1080 0b0'111'0000
#define DIPSW_RES_1360x768 0b0'110'0000
#define DIPSW_RES_1280x1024 0b0'101'0000
#define DIPSW_RES_1280x720 0b0'100'0000
#define DIPSW_RES_1024x768 0b0'011'0000
#define DIPSW_RES_1024x600 0b0'010'0000
#define DIPSW_LANDSCAPE 0b0000'0'000
#define DIPSW_PORTRAIT 0b0000'1'000
#define DIPSW_RES_DEFAULT 0b0'000'0000 // = 640x480
#define DIPSW_RES_640x480 0b0'001'0000
#define DIPSW_RES_DEFAULT 0b0'000'0000
#define DIPSW_RES_1024x600 0b0'010'0000
#define DIPSW_RES_1024x768 0b0'011'0000
#define DIPSW_RES_1280x720 0b0'100'0000
#define DIPSW_RES_1280x1024 0b0'101'0000
#define DIPSW_RES_1360x768 0b0'110'0000
#define DIPSW_RES_1920x1080 0b0'111'0000
BOOL smbus_PCA9535_read(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
switch (cmd) {
case ICH9_CMD_BYTE_DATA:
switch (code) {
case PCA9535_IN0: // DIPSW
case PCA9535_REG_IN0: // DIPSW
/*
0: ?
1: ?
@@ -74,10 +113,9 @@ BOOL smbus_PCA9535_read(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
// data[0] = 0b00001000;
// data[0] = 0b0'111'0'000;
data[0] = DIPSW_LANDSCAPE | DIPSW_RES_1920x1080;
data[0] = ((~MiceConfig.sysconf.dipsw) ^ inv[0]) & config[0];
return TRUE;
case PCA9535_IN1: // SW1/2 + extras
case PCA9535_REG_IN1: // SW1/2 + extras
/*
0: unk
1: unk
@@ -88,33 +126,46 @@ BOOL smbus_PCA9535_read(ich9_cmd_t cmd, WORD code, BYTE dlen, BYTE* data) {
6: unk
7: unk
*/
byte dip = 0x00;
if (GetAsyncKeyState('T') >= 0) {
dip |= 0x04;
}
if (GetAsyncKeyState('S') >= 0) {
dip |= 0x08;
}
data[0] = dip;
byte dip = 0x04 | 0x08;
static bool lastTest = false;
static bool lastSystem = false;
if (keySystemTest && GetAsyncKeyState(keySystemTest) < 0) {
// if (!lastSystem)
dip &= ~0x04;
// lastSystem = true;
} else
lastSystem = false;
if (keySystemService && GetAsyncKeyState(keySystemService) < 0) {
// if (!lastTest)
dip &= ~0x08;
// lastTest = true;
} else
lastTest = false;
data[0] = (dip ^ inv[1]) & config[1];
return TRUE;
case PCA9535_OUT0:
log_error("pca9535", "Read PCA9535_OUT0 unimplemented!");
case PCA9535_REG_OUT0:
data[0] = out[0] & ~config[0];
return FALSE;
case PCA9535_OUT1:
data[0] = 0x00;
case PCA9535_REG_OUT1:
data[0] = out[1] & ~config[1];
return TRUE;
case PCA9535_INV0:
data[0] = 0x00;
case PCA9535_REG_INV0:
data[0] = inv[0];
return TRUE;
case PCA9535_INV1:
data[0] = 0x00;
case PCA9535_REG_INV1:
data[0] = inv[1];
return TRUE;
case PCA9535_CONF0:
data[0] = pca9535_config >> 8;
case PCA9535_REG_CONF0:
data[0] = config[0];
return TRUE;
case PCA9535_CONF1:
data[0] = pca9535_config & 0xff;
case PCA9535_REG_CONF1:
data[0] = config[1];
return TRUE;
default:
log_error("pca9535", "Unknown read command: %02x", code);
return FALSE;

View File

@@ -1,8 +1,29 @@
#include "smbus.h"
#include "../smbus.h"
smbus_callback_t smbus_PCA9535_write;
smbus_callback_t smbus_PCA9535_read;
#define DIPSW_LANDSCAPE 0b0000'0'000
#define DIPSW_PORTRAIT 0b0000'1'000
#define DIPSW_RES_DEFAULT 0b0'000'0000 // = 640x480
#define DIPSW_RES_640x480 0b0'001'0000
#define DIPSW_RES_1024x600 0b0'010'0000
#define DIPSW_RES_1024x768 0b0'011'0000
#define DIPSW_RES_1280x720 0b0'100'0000
#define DIPSW_RES_1280x1024 0b0'101'0000
#define DIPSW_RES_1360x768 0b0'110'0000
#define DIPSW_RES_1920x1080 0b0'111'0000
#define PCA9535_REG_IN0 0x00
#define PCA9535_REG_IN1 0x01
#define PCA9535_REG_OUT0 0x02
#define PCA9535_REG_OUT1 0x03
#define PCA9535_REG_INV0 0x04
#define PCA9535_REG_INV1 0x05
#define PCA9535_REG_CONF0 0x06
#define PCA9535_REG_CONF1 0x07
#define PCA9535_GND 0
#define PCA9535_VCC 1

View File

@@ -148,6 +148,10 @@ void tea_hook_test(char* fmt, ...) {
va_end(argp);
}
int mxkMain();
DWORD WINAPI MxkThreadProc(LPVOID lpParameter) { mxkMain(); };
void spawn_pcp_processes(void) { CreateThread(NULL, 0, &MxkThreadProc, NULL, 0, NULL); }
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
if (ul_reason_for_call != DLL_PROCESS_ATTACH) return TRUE;
@@ -162,10 +166,12 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
// *((DWORD*)(0x00407850)) = (DWORD)(&logcb);
}
if (wcscmp(exeName, L"RingGame.exe") == 0) {
log_warning(BOOT_LOGGER, "Bodge hook goo!");
CreateHook32((void*)(0x005f2580), &tea_hook_test);
}
spawn_pcp_processes();
// if (wcscmp(exeName, L"RingGame.exe") == 0) {
// log_warning(BOOT_LOGGER, "Bodge hook goo!");
// CreateHook32((void*)(0x005f2580), &tea_hook_test);
// }
return TRUE;
}

View File

@@ -4,6 +4,8 @@
#include "jvs.h"
#include "mx.h"
#include "../key_config.h"
BOOL JVS_SENSE = false;
BOOL coin_solenoid = false;
BOOL test_btn = false;
@@ -16,12 +18,7 @@ BOOL test_btn = false;
const char JVS_837_14572_ID[] = "SEGA ENTERPRISES,LTD.;I/O BD JVS;837-13551 ;Ver1.00;98/10";
typedef struct _jvs_board {
char test_keybind;
char coin_keybinds[COIN_COUNTERS];
char keybinds[PLAYER_COUNT][16];
unsigned char flags[PLAYER_COUNT][16];
int num;
unsigned short coin_counts[COIN_COUNTERS];
unsigned char (*handler)(struct _jvs_board* board, unsigned char* inData, short inCount,
@@ -35,8 +32,7 @@ typedef struct _jvs_board {
#define JVS_FLAG_NC 1
#define JVS_FLAG_INVERT 2
jvs_board_t (*jvs_config)[];
size_t jvs_num_boards;
jvs_board_t jvs_boards[JVS_IO_MAX] = { 0 };
short jvs_unpad(unsigned char* paddedData, short length, unsigned char* unpaddedData) {
short index = 0;
@@ -71,20 +67,29 @@ short jvs_pad(unsigned char* unpaddedData, short length, unsigned char* paddedDa
void update_jvs_buttons(jvs_board_t* board) {
unsigned char sysButtons = 0x00;
if (GetAsyncKeyState(board->test_keybind) < 0) sysButtons |= 0x80;
if (GetAsyncKeyState(jvsKeybindings[board->num].test) < 0) sysButtons |= 0x80;
board->last_sysbuttons = sysButtons;
for (int player = 0; player < PLAYER_COUNT; player++) {
unsigned short buttons = 0x0000;
for (int i = 0; i < SWITCH_BYTES * 8; i++) {
int scancode = board->keybinds[player][i];
unsigned char flags = board->flags[player][i];
buttons <<= 1;
if (i < 14) {
int scancode = jvsKeybindings[board->num].buttons[(i + 1) * 2 + player];
bool invert = jvsKeybindings[board->num].invert[(i + 1) * 2 + player];
if (flags & JVS_FLAG_NC) continue;
if (flags & JVS_FLAG_INVERT)
buttons |= (GetAsyncKeyState(scancode) >= 0) << i;
else
buttons |= (GetAsyncKeyState(scancode) < 0) << i;
if (scancode == 0) continue;
if (invert)
buttons |= (GetAsyncKeyState(scancode) >= 0);// << i;
else
buttons |= (GetAsyncKeyState(scancode) < 0);// << i;
}
// 0x80 == push 3
// buttons |= 1;
// buttons |= 0x80;
}
board->last_buttons[player] = buttons;
}
@@ -206,9 +211,12 @@ unsigned char jvs_exchange(jvs_board_t* board, unsigned char* inData, short inCo
unsigned char coin_count;
jvs_read(coin_count);
if (board->coin_keybinds[0] && GetAsyncKeyState(board->coin_keybinds[0]) & 1)
int coin1 = jvsKeybindings[board->num].buttons[0];
int coin2 = jvsKeybindings[board->num].buttons[1];
if (coin1 && GetAsyncKeyState(coin1) & 1)
board->coin_counts[0]++;
if (board->coin_keybinds[1] && GetAsyncKeyState(board->coin_keybinds[1]) & 1)
if (coin2 && GetAsyncKeyState(coin2) & 1)
board->coin_counts[1]++;
for (unsigned char slot = 0; slot < coin_count; slot++) {
@@ -325,19 +333,19 @@ void mxjvs_handle(unsigned char* paddedIn, short inCount, unsigned char* outData
unsigned char destination = inData[1];
// Not broadcast, not master-bound, and within bounds
if (destination != 0xff && (destination == 0 || destination > jvs_num_boards)) return;
if (destination != 0xff && (destination == 0 || destination > numJvsBoards)) return;
unsigned char* response = malloc(maxOut);
unsigned char packetSize;
unsigned char status;
if (destination == 0xff) {
for (int i = 0; i < jvs_num_boards; i++) {
jvs_board_t* board = &(*jvs_config)[i];
for (int i = 0; i < numJvsBoards; i++) {
jvs_board_t *board = &jvs_boards[i];
status = board->handler(board, inData + 3, inData[2] - 1, response + 4, &packetSize);
if (packetSize != 0) break;
}
} else {
jvs_board_t* board = &(*jvs_config)[jvs_num_boards - destination];
jvs_board_t* board = &jvs_boards[numJvsBoards - destination];
status = board->handler(board, inData + 3, inData[2] - 1, response + 4, &packetSize);
}
free(inData);
@@ -405,252 +413,257 @@ BOOL mxjvs_SetCommState(void* com, LPDCB lpDCB) {
return TRUE;
}
jvs_board_t maimai_jvs_config[1] = { {
.test_keybind = VK_OEM_4, // [{
.coin_keybinds = {'1', '2'},
.keybinds = {
{
0,
0,
0,
'W', // *1P8
'Q', // *1P7
'A', // *1P6
'Z', // *1P5
'X', // *1P4
'C', // *1P3
0,
'E', // *1P1
'D', // *1P2
0,
0,
'1', // *1P Service
0,
// jvs_board_t maimai_jvs_config[1] = { {
// .test_keybind = VK_OEM_4, // [{
// .coin_keybinds = {'1', '2'},
// .keybinds = {
// {
// 0,
// 0,
// 0,
// 'W', // *1P8
// 'Q', // *1P7
// 'A', // *1P6
// 'Z', // *1P5
// 'X', // *1P4
// 'C', // *1P3
// 0,
// 'E', // *1P1
// 'D', // *1P2
// 0,
// 0,
// '1', // *1P Service
// 0,
},
{
0,
0,
0,
'I', // *2P8
'U', // *2P7
'J', // *2P6
'M', // *2P5
VK_OEM_COMMA, // *2P4
VK_OEM_PERIOD, // *2P3
0,
'O', // *2P1
'L', // *2P2
0,
0,
'2', // *2P Service
0,
// },
// {
// 0,
// 0,
// 0,
// 'I', // *2P8
// 'U', // *2P7
// 'J', // *2P6
// 'M', // *2P5
// VK_OEM_COMMA, // *2P4
// VK_OEM_PERIOD, // *2P3
// 0,
// 'O', // *2P1
// 'L', // *2P2
// 0,
// 0,
// '2', // *2P Service
// 0,
},
},
.flags = {
{
JVS_FLAG_NC,
JVS_FLAG_NC,
JVS_FLAG_NC,
JVS_FLAG_INVERT,
JVS_FLAG_INVERT,
JVS_FLAG_INVERT,
JVS_FLAG_INVERT,
JVS_FLAG_INVERT,
JVS_FLAG_INVERT,
JVS_FLAG_NC,
JVS_FLAG_INVERT,
JVS_FLAG_INVERT,
JVS_FLAG_NC,
JVS_FLAG_NC,
JVS_FLAG_NONE,
JVS_FLAG_NC,
},
{
// },
// },
// .flags = {
// {
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_INVERT,
// JVS_FLAG_INVERT,
// JVS_FLAG_INVERT,
// JVS_FLAG_INVERT,
// JVS_FLAG_INVERT,
// JVS_FLAG_INVERT,
// JVS_FLAG_NC,
// JVS_FLAG_INVERT,
// JVS_FLAG_INVERT,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NONE,
// JVS_FLAG_NC,
// },
// {
JVS_FLAG_NC,
JVS_FLAG_NC,
JVS_FLAG_NC,
JVS_FLAG_INVERT,
JVS_FLAG_INVERT,
JVS_FLAG_INVERT,
JVS_FLAG_INVERT,
JVS_FLAG_INVERT,
JVS_FLAG_INVERT,
JVS_FLAG_NC,
JVS_FLAG_INVERT,
JVS_FLAG_INVERT,
JVS_FLAG_NC,
JVS_FLAG_NC,
JVS_FLAG_NONE,
JVS_FLAG_NC,
},
},
.coin_counts = {0, 0},
.handler = &jvs_exchange,
.id = JVS_837_14572_ID,
} };
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_INVERT,
// JVS_FLAG_INVERT,
// JVS_FLAG_INVERT,
// JVS_FLAG_INVERT,
// JVS_FLAG_INVERT,
// JVS_FLAG_INVERT,
// JVS_FLAG_NC,
// JVS_FLAG_INVERT,
// JVS_FLAG_INVERT,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NONE,
// JVS_FLAG_NC,
// },
// },
// .coin_counts = {0, 0},
// .handler = &jvs_exchange,
// .id = JVS_837_14572_ID,
// } };
jvs_board_t under_night_jvs_config[1] = {
{
.test_keybind = VK_OEM_4, // [{
.coin_keybinds = {'1', '2'},
.keybinds = {
{
0, 0, 0, 0, 0, 0,
'A', // D (EXCs)
'R', // C (Heavy)
'E', // B (Middle)
'W', // A (Light)
VK_RIGHT, // Right
VK_LEFT, // Left
VK_DOWN, // Down
VK_UP, // Up
VK_BACK, // Service
VK_RETURN, // Start
},
{
0, 0, 0, 0, 0, 0,
'J', // D (EXCs)
'P', // C (Heavy)
'O', // B (Middle)
'I', // A (Light)
VK_NUMPAD6, // Right
VK_NUMPAD4, // Left
VK_NUMPAD2, // Down
VK_NUMPAD8, // Up
VK_BACK, // Service
VK_RETURN, // Start
},
},
.flags = {
{
JVS_FLAG_NC,
JVS_FLAG_NC,
JVS_FLAG_NC,
JVS_FLAG_NC,
JVS_FLAG_NC,
JVS_FLAG_NC,
JVS_FLAG_NONE,
JVS_FLAG_NONE,
JVS_FLAG_NONE,
JVS_FLAG_NONE,
JVS_FLAG_NONE,
JVS_FLAG_NONE,
JVS_FLAG_NONE,
JVS_FLAG_NONE,
JVS_FLAG_NONE,
JVS_FLAG_NONE,
},
{
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
JVS_FLAG_NC,
JVS_FLAG_NC,
JVS_FLAG_NC,
JVS_FLAG_NC,
JVS_FLAG_NC,
JVS_FLAG_NC,
JVS_FLAG_NONE,
JVS_FLAG_NONE,
JVS_FLAG_NONE,
JVS_FLAG_NONE,
JVS_FLAG_NONE,
JVS_FLAG_NONE,
JVS_FLAG_NONE,
JVS_FLAG_NONE,
JVS_FLAG_NONE,
JVS_FLAG_NONE,
},
},
.coin_counts = {0, 0},
.handler = &jvs_exchange,
.id = JVS_837_14572_ID,
},
// {
// .test_keybind = VK_OEM_4, // [{
// .coin_keybinds = {0, 0},
// .keybinds = {
// {
// 0, 0, 0, 0, 0, 0,
// 'J', // D (EXCs)
// 'P', // C (Heavy)
// 'O', // B (Middle)
// 'I', // A (Light)
// VK_NUMPAD6, // Right
// VK_NUMPAD4, // Left
// VK_NUMPAD2, // Down
// VK_NUMPAD8, // Up
// VK_BACK, // Service
// VK_RETURN, // Start
// },
// {0},
// },
// .flags = {
// {
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NONE,
// JVS_FLAG_NONE,
// JVS_FLAG_NONE,
// JVS_FLAG_NONE,
// JVS_FLAG_NONE,
// JVS_FLAG_NONE,
// JVS_FLAG_NONE,
// JVS_FLAG_NONE,
// JVS_FLAG_NONE,
// JVS_FLAG_NONE,
// },
// {
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// },
// },
// .coin_counts = {0, 0},
// .handler = &jvs_exchange,
// .id = JVS_837_14572_ID,
// },
};
// jvs_board_t under_night_jvs_config[1] = {
// {
// .test_keybind = VK_OEM_4, // [{
// .coin_keybinds = {'1', '2'},
// .keybinds = {
// {
// 0, 0, 0, 0, 0, 0,
// 'A', // D (EXCs)
// 'R', // C (Heavy)
// 'E', // B (Middle)
// 'W', // A (Light)
// VK_RIGHT, // Right
// VK_LEFT, // Left
// VK_DOWN, // Down
// VK_UP, // Up
// VK_BACK, // Service
// VK_RETURN, // Start
// },
// {
// 0, 0, 0, 0, 0, 0,
// 'J', // D (EXCs)
// 'P', // C (Heavy)
// 'O', // B (Middle)
// 'I', // A (Light)
// VK_NUMPAD6, // Right
// VK_NUMPAD4, // Left
// VK_NUMPAD2, // Down
// VK_NUMPAD8, // Up
// VK_BACK, // Service
// VK_RETURN, // Start
// },
// },
// .flags = {
// {
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NONE,
// JVS_FLAG_NONE,
// JVS_FLAG_NONE,
// JVS_FLAG_NONE,
// JVS_FLAG_NONE,
// JVS_FLAG_NONE,
// JVS_FLAG_NONE,
// JVS_FLAG_NONE,
// JVS_FLAG_NONE,
// JVS_FLAG_NONE,
// },
// {
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NC,
// JVS_FLAG_NONE,
// JVS_FLAG_NONE,
// JVS_FLAG_NONE,
// JVS_FLAG_NONE,
// JVS_FLAG_NONE,
// JVS_FLAG_NONE,
// JVS_FLAG_NONE,
// JVS_FLAG_NONE,
// JVS_FLAG_NONE,
// JVS_FLAG_NONE,
// },
// },
// .coin_counts = {0, 0},
// .handler = &jvs_exchange,
// .id = JVS_837_14572_ID,
// },
// // {
// // .test_keybind = VK_OEM_4, // [{
// // .coin_keybinds = {0, 0},
// // .keybinds = {
// // {
// // 0, 0, 0, 0, 0, 0,
// // 'J', // D (EXCs)
// // 'P', // C (Heavy)
// // 'O', // B (Middle)
// // 'I', // A (Light)
// // VK_NUMPAD6, // Right
// // VK_NUMPAD4, // Left
// // VK_NUMPAD2, // Down
// // VK_NUMPAD8, // Up
// // VK_BACK, // Service
// // VK_RETURN, // Start
// // },
// // {0},
// // },
// // .flags = {
// // {
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NONE,
// // JVS_FLAG_NONE,
// // JVS_FLAG_NONE,
// // JVS_FLAG_NONE,
// // JVS_FLAG_NONE,
// // JVS_FLAG_NONE,
// // JVS_FLAG_NONE,
// // JVS_FLAG_NONE,
// // JVS_FLAG_NONE,
// // JVS_FLAG_NONE,
// // },
// // {
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // JVS_FLAG_NC,
// // },
// // },
// // .coin_counts = {0, 0},
// // .handler = &jvs_exchange,
// // .id = JVS_837_14572_ID,
// // },
// };
jvs_board_t (*jvs_config)[] = &maimai_jvs_config;
size_t jvs_num_boards = sizeof maimai_jvs_config / sizeof maimai_jvs_config[0];
// jvs_board_t (*jvs_config)[] = &under_night_jvs_config;
// size_t jvs_num_boards = sizeof under_night_jvs_config / sizeof under_night_jvs_config[0];
void init_jvs_boards() {
for (int i = 0; i < _countof(jvs_boards); i++) {
jvs_boards[i].num = i;
jvs_boards[i].id = JVS_837_14572_ID;
jvs_boards[i].handler = &jvs_exchange;
}
}
void setup_mxjvs() {
init_jvs_boards();
file_hook_t* mxjvs = new_file_hook(L"\\\\.\\mxjvs");
mxjvs->DeviceIoControl = &mxjvs_DeviceIoControl;
hook_file(mxjvs);
@@ -668,6 +681,6 @@ void setup_mxjvs() {
mxjvs->com_hook = jvscom;
// TODO: Looks like some things might use JVS on COM4. We should setup a comdevice for this!
// file_hook_t* jvscom_file = new_file_hook(jvscom->wName);
// hook_file(jvscom_file);
file_hook_t* jvscom_file = new_file_hook(jvscom->wName);
hook_file(jvscom_file);
}

View File

@@ -2,12 +2,43 @@
#ifndef CIMGUI_DEFINE_ENUMS_AND_STRUCTS
#define CIMGUI_DEFINE_ENUMS_AND_STRUCTS
#endif
#include "../devices/smb_at24c64an.h"
#include "../key_config.h"
#include "cimgui.h"
#include "imgui/backends/GL/freeglut.h"
#include "imgui_memory_editor.h"
static HWND window;
/* UI Constants */
const ImVec4 DISABLED_COL = { .7f, .7f, .7f, 1.0f };
const ImVec4 WARN_COL = { 1.0f, 1.0f, .1f, 1.0f };
const ImVec4 DANGER_COL = { 1.0f, .1f, .1f, 1.0f };
struct {
const char* name;
int index;
int pinNum;
} JVS_BUTTON_NAMES[JVS_BUTTON_PAIR_COUNT] = {
{ "Coin", 45 }, { "Start", 17 }, { "Service", 41 }, { "UP", 23 }, { "DOWN", 25 },
{ "LEFT", 21 }, { "RIGHT", 19 }, { "Push 1", 27 }, { "Push 2", 29 }, { "Push 3", 31 },
{ "Push 4", 33 }, { "Push 5", 35 }, { "Push 6", 37 }, { "Push 7", 39 }, { "Push 8", 47 },
};
const char* RESOLUTION_NAMES[] = {
"Unspecified", "640x480", "1024x600", "1024x768",
"1280x720", "1280x1024", "1360x768", "1920x1080",
};
const char* ORIENTATION_NAMES[] = {
"Landscape",
"Portrait",
};
/* ImGui useful globals */
static ImVec2 vec0 = { 0 };
static ImVec2 vec10 = { 1, 0 };
/* ImGui externs */
extern bool ImGui_ImplWin32_Init(void* hwnd);
extern void ImGui_ImplWin32_Shutdown();
extern void ImGui_ImplWin32_NewFrame();
@@ -18,63 +49,66 @@ extern void ImGui_ImplDX9_NewFrame();
extern void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data);
extern bool ImGui_ImplDX9_GetCP(IDirect3DDevice9* pDevice, D3DDEVICE_CREATION_PARAMETERS* CP);
extern bool ImGui_ImplGLUT_Init();
extern void ImGui_ImplGLUT_InstallFuncs();
extern void ImGui_ImplGLUT_Shutdown();
extern void ImGui_ImplGLUT_NewFrame();
extern void ImGui_ImplGLUT_ReshapeFunc(int w, int h);
extern void ImGui_ImplGLUT_MotionFunc(int x, int y);
extern void ImGui_ImplGLUT_MouseFunc(int button, int state, int x, int y);
extern void ImGui_ImplGLUT_MouseWheelFunc(int button, int dir, int x, int y);
extern void ImGui_ImplGLUT_KeyboardFunc(unsigned char c, int x, int y);
extern void ImGui_ImplGLUT_KeyboardUpFunc(unsigned char c, int x, int y);
extern void ImGui_ImplGLUT_SpecialFunc(int key, int x, int y);
extern void ImGui_ImplGLUT_SpecialUpFunc(int key, int x, int y);
extern bool ImGui_ImplOpenGL3_Init(const char* glsl_version);
extern void ImGui_ImplOpenGL3_Shutdown();
extern void ImGui_ImplOpenGL3_NewFrame();
extern void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data);
// TODO: Implement log viewing
extern CRITICAL_SECTION logger_lock;
void InitImGui(IDirect3DDevice9* pDevice) {
D3DDEVICE_CREATION_PARAMETERS CP;
ImGui_ImplDX9_GetCP(pDevice, &CP);
window = CP.hFocusWindow;
void InitImGui(unsigned int hookType, IDirect3DDevice9* pDevice) {
if (hookType == UI_HOOK_DX9) {
D3DDEVICE_CREATION_PARAMETERS CP;
ImGui_ImplDX9_GetCP(pDevice, &CP);
window = CP.hFocusWindow;
} else if (hookType == UI_HOOK_GLUT) {
window = GetActiveWindow();
}
igCreateContext(NULL);
ImGuiIO* io = igGetIO();
io->IniFilename = NULL;
io->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
ImFontAtlas_AddFontDefault(io->Fonts, NULL);
// ImFontAtlas_Build(io->Fonts);
ImGui_ImplWin32_Init(window);
ImGui_ImplDX9_Init(pDevice);
}
if (hookType == UI_HOOK_DX9) {
ImGui_ImplWin32_Init(window);
ImGui_ImplDX9_Init(pDevice);
} else if (hookType == UI_HOOK_GLUT) {
ImGui_ImplGLUT_Init();
ImGui_ImplOpenGL3_Init(NULL); // TODO: This
extern BOOL JVS_SENSE;
void jvs_tab() {
int coin_count_1 = 0;
int coin_count_2 = 0;
igText("Player 1 Coins: %d", coin_count_1);
igText("Player 2 Coins: %d", coin_count_2);
igSeparator();
igText("Sense: %d", JVS_SENSE);
igSeparator();
ImVec4 white = { 1.0, 1.0, 1.0, 1.0 };
ImVec4 red = { 1.0, 0.0, 0.0, 1.0 };
igColumns(5, NULL, true);
// for (auto s : scancodes) {
// igTextColored((GetKeyState(s.second) < 0) ? red : white, "%s: %x", s.first, s.second);
// igNextColumn();
// }
igColumns(1, NULL, true);
igColumns(8, NULL, true);
for (int player = 0; player < 2; player++) {
for (int button = 0; button < 16; button++) {
// int scan = jvs_buttons[player][button];
// igTextColored((GetKeyState(scan) < 0) ? red : white, "p%d_%02d: %02x", player, button,
// scan);
igNextColumn();
}
/**
* ! Important we can't use InstallFuncs, because it replaces the
* ! reshape func, which games use. We handle this manuall ourself.
*
* // ImGui_ImplGLUT_InstallFuncs();
* // glutReshapeFunc(ImGui_ImplGLUT_ReshapeFunc);
*/
glutMotionFunc(ImGui_ImplGLUT_MotionFunc);
glutPassiveMotionFunc(ImGui_ImplGLUT_MotionFunc);
glutMouseFunc(ImGui_ImplGLUT_MouseFunc);
glutKeyboardFunc(ImGui_ImplGLUT_KeyboardFunc);
glutKeyboardUpFunc(ImGui_ImplGLUT_KeyboardUpFunc);
glutSpecialFunc(ImGui_ImplGLUT_SpecialFunc);
glutSpecialUpFunc(ImGui_ImplGLUT_SpecialUpFunc);
}
igColumns(1, NULL, true);
igSeparator();
igText("JVS Count");
// for (auto c : jvsCount) {
// igText("%x: %d", c.first, c.second);
// }
igSeparator();
igText("Comio Count");
// for (auto c : comioCount) {
// igText("%x: %d", c.first, c.second);
// }
}
void hud_fps() {
@@ -124,15 +158,732 @@ void hud_sram(ImGuiKey open_key) {
// TODO: Less hacky :)
extern LPBYTE SRAM;
if (editor.Open)
MemoryEditor_DrawWindow(&editor, "SRAM Editor", SRAM, 1024 * 1024, 0x0000);
if (editor.Open) MemoryEditor_DrawWindow(&editor, "SRAM Editor", SRAM, 1024 * 1024, 0x0000);
}
void hud_control() {
igBegin("maimai control", NULL, 0);
void igHelpMarker(const char* text) {
igTextDisabled("(?)");
if (igIsItemHovered(0)) {
igBeginTooltip();
igPushTextWrapPos(igGetFontSize() * 35.0f);
igTextUnformatted(text, NULL);
igPopTextWrapPos();
igEndTooltip();
}
}
void AddSetting(const char* name, const char* help) {
if (help) {
igHelpMarker(help);
igSameLine(0.0, -1.0);
}
igTextUnformatted(name, NULL);
igNextColumn();
}
bool AddSettingInt(const char* name, const char* help, int* value) {
igPushID_Int((int)value);
AddSetting(name, help);
bool changed = igInputInt("", value, 1, 1, ImGuiInputTextFlags_None);
igNextColumn();
igPopID();
return changed;
}
bool AddSettingBool(const char* name, const char* help, bool* value) {
igPushID_Int((int)value);
AddSetting(name, help);
bool changed = igCheckbox("", value);
igNextColumn();
igPopID();
if (changed) save_current_config();
return changed;
}
bool AddSettingString(const char* name, const char* help, char** value) {
igPushID_Int((int)value);
AddSetting(name, help);
char buffer[512];
snprintf(buffer, _countof(buffer), "%s", *value);
buffer[_countof(buffer) - 1] = '\0';
bool changed = igInputText("", buffer, _countof(buffer) - 1, ImGuiInputFlags_None, NULL, NULL);
if (changed) {
int newLen = strlen(buffer) + 1;
*value = realloc(*value, newLen);
memcpy(*value, buffer, newLen);
save_current_config();
}
igNextColumn();
igPopID();
return changed;
}
bool AddSettingIPv4(const char* name, const char* help, unsigned int* value) {
igPushID_Int((int)value);
AddSetting(name, help);
char buffer[17];
snprintf(buffer, _countof(buffer), "%hhu.%hhu.%hhu.%hhu", (*value >> 24) & 0xff,
(*value >> 16) & 0xff, (*value >> 8) & 0xff, (*value) & 0xff);
buffer[_countof(buffer) - 1] = '\0';
bool changed = igInputText("", buffer, _countof(buffer) - 1, ImGuiInputFlags_None, NULL, NULL);
if (changed) {
unsigned char a, b, c, d;
size_t n = 0;
if (sscanf(buffer, "%hhu.%hhu.%hhu.%hhu%n", &a, &b, &c, &d, &n) == 4 &&
n == strlen(buffer)) {
*value = (a << 24) | (b << 16) | (c << 8) | d;
save_current_config();
} else {
changed = false;
}
}
igNextColumn();
igPopID();
return changed;
}
bool igDipsw(const char* label, bool* value) {
if (igGetCurrentWindow()->SkipItems) return false;
const ImGuiID id = igGetID_Str(label);
const float square_sz = igGetFrameHeight();
ImVec2 tl;
igGetCursorScreenPos(&tl);
ImVec2 br;
br.x = tl.x + square_sz / 1.5f;
br.y = tl.y + square_sz;
bool hovered, held;
ImRect rect;
rect.Min = tl;
rect.Max = br;
igItemSize_Rect(rect, igGetCurrentContext()->Style.FramePadding.y);
if (!igItemAdd(rect, id, NULL, ImGuiItemFlags_None)) return false;
bool pressed = igButtonBehavior(rect, id, &hovered, &held, ImGuiButtonFlags_None);
if (pressed) {
*value = !(*value);
igMarkItemEdited(id);
}
ImDrawList* draw_list = igGetWindowDrawList();
ImDrawList_AddRectFilled(draw_list, tl, br,
igGetColorU32_Col((held && hovered) ? ImGuiCol_FrameBgActive
: hovered ? ImGuiCol_FrameBgHovered
: ImGuiCol_FrameBg,
1),
0, ImDrawFlags_None);
int pad = (int)(square_sz / 8.0f);
tl.x += pad;
tl.y += pad;
br.x -= pad;
br.y -= pad;
if (*value) {
ImDrawList_AddRectFilled(draw_list, tl, br, igGetColorU32_Col(ImGuiCol_CheckMark, 0.3f), 0,
ImDrawFlags_None);
tl.y += square_sz / 2.0f;
ImDrawList_AddRectFilled(draw_list, tl, br, igGetColorU32_Col(ImGuiCol_CheckMark, 1), 0,
ImDrawFlags_None);
} else {
br.y -= square_sz / 2.0f;
ImDrawList_AddRectFilled(draw_list, tl, br, igGetColorU32_Col(ImGuiCol_CheckMark, 1), 0,
ImDrawFlags_None);
}
return pressed;
}
void tab_settings_system() {
igColumns(2, "SettingsSystem", true);
igTextUnformatted("Name", NULL);
igNextColumn();
igTextUnformatted("Setting", NULL);
igNextColumn();
igSeparator();
bool staticChanged = false;
{
igPushID_Int((int)&MiceConfig.sysconf.region);
AddSetting("Region", NULL);
bool jpn = !!(MiceConfig.sysconf.region & 1);
bool usa = !!(MiceConfig.sysconf.region & 2);
bool exp = !!(MiceConfig.sysconf.region & 4);
bool chn = !!(MiceConfig.sysconf.region & 8);
igTextUnformatted("JPN", NULL);
igSameLine(0.0, -1.0);
if (igRadioButton_Bool("##JPN", MiceConfig.sysconf.region == 1)) {
MiceConfig.sysconf.region = 1;
staticChanged = true;
save_current_config();
}
igSameLine(0.0, -1.0);
igSeparatorEx(ImGuiSeparatorFlags_Vertical);
igSameLine(0.0, -1.0);
igTextUnformatted("USA", NULL);
igSameLine(0.0, -1.0);
if (igRadioButton_Bool("##USA", MiceConfig.sysconf.region == 2)) {
MiceConfig.sysconf.region = 2;
staticChanged = true;
save_current_config();
}
igSameLine(0.0, -1.0);
igSeparatorEx(ImGuiSeparatorFlags_Vertical);
igSameLine(0.0, -1.0);
igTextUnformatted("EXP", NULL);
igSameLine(0.0, -1.0);
if (igRadioButton_Bool("##EXP", MiceConfig.sysconf.region == 4)) {
MiceConfig.sysconf.region = 4;
staticChanged = true;
save_current_config();
}
igSameLine(0.0, -1.0);
igSeparatorEx(ImGuiSeparatorFlags_Vertical);
igSameLine(0.0, -1.0);
igTextUnformatted("CHN", NULL);
igSameLine(0.0, -1.0);
if (igRadioButton_Bool("##", MiceConfig.sysconf.region == 8)) {
MiceConfig.sysconf.region = 8;
staticChanged = true;
save_current_config();
}
igNextColumn();
igPopID();
}
staticChanged |= AddSettingBool("Rental", NULL, &MiceConfig.sysconf.rental);
staticChanged |=
AddSettingString("Serial", "Main board serial number", &MiceConfig.sysconf.serial);
if (staticChanged) build_eeprom();
igSeparator();
AddSetting("Resolution", NULL);
const char* current_item;
current_item = RESOLUTION_NAMES[(MiceConfig.sysconf.dipsw >> 4) & 0b111];
if (igBeginCombo("##Resolution", current_item, ImGuiComboFlags_None)) {
for (int i = 0; i < _countof(RESOLUTION_NAMES); i++) {
bool is_selected = (current_item == RESOLUTION_NAMES[i]);
if (igSelectable_Bool(RESOLUTION_NAMES[i], is_selected, ImGuiSelectableFlags_None,
vec0)) {
MiceConfig.sysconf.dipsw =
((MiceConfig.sysconf.dipsw & 0b1'000'1111) | (i << 4)) & 0xff;
save_current_config();
}
if (is_selected) igSetItemDefaultFocus();
}
igEndCombo();
}
igNextColumn();
AddSetting("Orientation", NULL);
current_item = ORIENTATION_NAMES[(MiceConfig.sysconf.dipsw >> 3) & 0b1];
if (igBeginCombo("##Orientation", current_item, ImGuiComboFlags_None)) {
for (int i = 0; i < _countof(ORIENTATION_NAMES); i++) {
bool is_selected = (current_item == ORIENTATION_NAMES[i]);
if (igSelectable_Bool(ORIENTATION_NAMES[i], is_selected, ImGuiSelectableFlags_None,
vec0)) {
MiceConfig.sysconf.dipsw =
((MiceConfig.sysconf.dipsw & 0b1111'0'111) | (i << 3)) & 0xff;
save_current_config();
}
if (is_selected) igSetItemDefaultFocus();
}
igEndCombo();
}
igNextColumn();
AddSetting("DIP Switches", "Linked with the above two settings");
for (int i = 0; i < 8; i++) {
bool val = MiceConfig.sysconf.dipsw & (1 << i);
igPushID_Int(i);
if (i != 0) igSameLine(0.0, 2);
if (igDipsw("", &val)) {
MiceConfig.sysconf.dipsw = (MiceConfig.sysconf.dipsw & ~(1 << i)) | (val << i);
save_current_config();
}
igPopID();
}
igNextColumn();
igEndColumns();
}
void tab_settings_window() {
igColumns(2, "SettingsWindow", true);
igTextUnformatted("Name", NULL);
igNextColumn();
igTextUnformatted("Setting", NULL);
igNextColumn();
igSeparator();
bool changed = false;
changed |=
AddSettingBool("Windowed", "Forces games into windowed mode", &MiceConfig.window.windowed);
changed |= AddSettingBool("Borderless", "Should windowed games run borderless",
&MiceConfig.window.borderless);
changed |= AddSettingInt("Adaptor", "Display adaptor to use", &MiceConfig.window.adaptor);
changed |= AddSettingBool("Centre", "Centre the window. X and Y are used otherwise",
&MiceConfig.window.centre);
igBeginDisabled(MiceConfig.window.centre);
changed |= AddSettingInt("X", "Window position X", &MiceConfig.window.x);
changed |= AddSettingInt("Y", "Window position Y", &MiceConfig.window.y);
igEndDisabled();
changed |=
AddSettingBool("No sizing", "Don't change window resolution", &MiceConfig.window.nosize);
igBeginDisabled(MiceConfig.window.nosize);
changed |= AddSettingBool("Use DIPSW", "Use the DIP switches for resolution",
&MiceConfig.window.dipsw);
igBeginDisabled(MiceConfig.window.dipsw);
changed |= AddSettingInt("W", "Window width (0 to unset)", &MiceConfig.window.w);
changed |= AddSettingInt("H", "Window height (0 to unset)", &MiceConfig.window.h);
igEndDisabled();
igEndDisabled();
if (changed) save_current_config();
igEndColumns();
}
void tab_settings_network() {
igColumns(2, "SettingsNetwork", true);
igTextUnformatted("Name", NULL);
igNextColumn();
igTextUnformatted("Setting", NULL);
igNextColumn();
igSeparator();
bool networkChanged = false;
networkChanged |= AddSettingIPv4("IP Address", NULL, &MiceConfig.network.ip_address);
networkChanged |= AddSettingIPv4("Subnet Mask", NULL, &MiceConfig.network.subnet_mask);
networkChanged |= AddSettingIPv4("Gateway", NULL, &MiceConfig.network.gateway);
networkChanged |= AddSettingIPv4("Primary DNS", NULL, &MiceConfig.network.primary_dns);
networkChanged |= AddSettingIPv4("Secondary DNS", NULL, &MiceConfig.network.secondary_dns);
if (networkChanged) build_eeprom();
igSeparator();
igPushColumnsBackground();
igTextUnformatted("Emulated DNS records. Routers must be pingable", NULL);
igPopColumnsBackground();
igSeparator();
bool changed = false;
changed |= AddSettingIPv4("naominet.jp", NULL, &MiceConfig.network.naominet_jp);
changed |= AddSettingIPv4("ib.naominet.jp", NULL, &MiceConfig.network.ib_naominet_jp);
changed |= AddSettingIPv4("aime.naominet.jp", NULL, &MiceConfig.network.aime_naominet_jp);
changed |= AddSettingIPv4("tenporouter.loc", NULL, &MiceConfig.network.tenporouter_loc);
changed |= AddSettingIPv4("bbrouter.loc", NULL, &MiceConfig.network.bbrouter_loc);
changed |= AddSettingIPv4("mobirouter.loc", NULL, &MiceConfig.network.mobirouter_loc);
changed |= AddSettingIPv4("dslrouter.loc", NULL, &MiceConfig.network.dslrouter_loc);
if (changed) save_current_config();
igSeparator();
{
AddSetting("MAC Address", "The first half of the MAC address is locked to SEGA's prefix");
igTextUnformatted("D8:BB:C1:", NULL);
unsigned int scan;
char buffer[3] = { 0 };
igPushStyleVar_Vec2(ImGuiStyleVar_FramePadding, vec10);
snprintf(buffer, _countof(buffer), "%02X", (MiceConfig.network.mac >> 16) & 0xff);
igSameLine(0.0, 0);
igPushItemWidth(16);
if (igInputText("##mac0", buffer, _countof(buffer), ImGuiInputTextFlags_CharsHexadecimal,
NULL, NULL)) {
_snscanf_s(buffer, _countof(buffer), "%02x", &scan);
MiceConfig.network.mac = (MiceConfig.network.mac & 0x00FFFF) | ((scan & 0xff) << 16);
save_current_config();
}
igSameLine(0.0, 0);
igTextUnformatted(":", NULL);
snprintf(buffer, _countof(buffer), "%02X", (MiceConfig.network.mac >> 8) & 0xff);
igSameLine(0.0, 0);
igPushItemWidth(16);
if (igInputText("##mac1", buffer, _countof(buffer), ImGuiInputTextFlags_CharsHexadecimal,
NULL, NULL)) {
_snscanf_s(buffer, _countof(buffer), "%02x", &scan);
MiceConfig.network.mac = (MiceConfig.network.mac & 0xFF00FF) | ((scan & 0xff) << 8);
save_current_config();
}
igSameLine(0.0, 0);
igTextUnformatted(":", NULL);
snprintf(buffer, _countof(buffer), "%02X", MiceConfig.network.mac & 0xff);
igSameLine(0.0, 0);
igPushItemWidth(16);
if (igInputText("##mac2", buffer, _countof(buffer), ImGuiInputTextFlags_CharsHexadecimal,
NULL, NULL)) {
_snscanf_s(buffer, _countof(buffer), "%02x", &scan);
MiceConfig.network.mac = (MiceConfig.network.mac & 0xFFFF00) | (scan & 0xff);
save_current_config();
}
igPopStyleVar(1);
igNextColumn();
}
igEndColumns();
}
void tab_settings_adavanced() {
igColumns(2, "SettingsNetwork", true);
igTextUnformatted("Name", NULL);
igNextColumn();
igTextUnformatted("Setting", NULL);
igNextColumn();
igSeparator();
igPushColumnsBackground();
igTextColored(DANGER_COL, "Enable or disable drivers. Disabling any is not recommended.");
igPopColumnsBackground();
igSeparator();
bool changed;
changed |= AddSettingBool("\\\\.\\columba", NULL, &MiceConfig.drivers.columba);
changed |= AddSettingBool("\\\\.\\mxsram", NULL, &MiceConfig.drivers.mxsram);
changed |= AddSettingBool("\\\\.\\mxsuperio", NULL, &MiceConfig.drivers.mxsuperio);
changed |= AddSettingBool("\\\\.\\mxjvs", NULL, &MiceConfig.drivers.mxjvs);
changed |= AddSettingBool("\\\\.\\mxhwreset", NULL, &MiceConfig.drivers.mxhwreset);
changed |= AddSettingBool("\\\\.\\mxsmbus", NULL, &MiceConfig.drivers.mxsmbus);
changed |= AddSettingBool("\\\\.\\mxparallel", NULL, &MiceConfig.drivers.mxparallel);
changed |= AddSettingBool("\\\\.\\platform", NULL, &MiceConfig.drivers.platform);
igSeparator();
igPushColumnsBackground();
igTextColored(DANGER_COL, "Enable or disable hooks. Disabling any is not recommended.");
igPopColumnsBackground();
igSeparator();
changed |=
AddSettingBool("logging", "Hooks logging functions and the eventlog to capture game logs",
&MiceConfig.hooks.logging);
changed |= AddSettingBool("gui", "Required for overlays to work", &MiceConfig.hooks.gui);
changed |= AddSettingBool("setupapi", "Required for SRAM", &MiceConfig.hooks.setupapi);
changed |= AddSettingBool("commio", "Emulates COM devices", &MiceConfig.hooks.commio);
changed |= AddSettingBool("io", "Hooks all file IO operations, including driver communication",
&MiceConfig.hooks.io);
changed |= AddSettingBool("processes", "Controls process spawning to re-hook children",
&MiceConfig.hooks.processes);
changed |= AddSettingBool("network", "Provides a virtual network environment for the game",
&MiceConfig.hooks.network);
changed |=
AddSettingBool("time", "Some binaries try to change the system time; this handles that",
&MiceConfig.hooks.time);
changed |= AddSettingBool("registry", NULL, &MiceConfig.hooks.registry);
changed |= AddSettingBool("drives", "Provides an emulation layer for the physical game SSD",
&MiceConfig.hooks.drives);
igEndColumns();
if (changed) save_current_config();
}
void tab_main_settings() {
if (igBeginTabBar("SettingsTabs", 0)) {
if (igBeginTabItem("System", NULL, 0)) {
tab_settings_system();
igEndTabItem();
}
if (igBeginTabItem("Window", NULL, 0)) {
tab_settings_window();
igEndTabItem();
}
if (igBeginTabItem("Network", NULL, 0)) {
tab_settings_network();
igEndTabItem();
}
if (igBeginTabItem("Advanced", NULL, 0)) {
tab_settings_adavanced();
igEndTabItem();
}
igEndTabBar();
}
}
bool igKeyBindPopup(const char* name, int* boundKey) {
if (igBeginPopupModal(name, NULL, ImGuiWindowFlags_AlwaysAutoResize)) {
igText("Press any button");
if (igButton("Cancel", vec0)) {
igCloseCurrentPopup();
*boundKey = -1;
igEndPopup();
return true;
}
// Skip the mouse buttons
for (int i = 8; i < 0xff; i++) {
if (GetAsyncKeyState(i) < 0) {
*boundKey = i;
igCloseCurrentPopup();
igEndPopup();
return true;
}
}
igEndPopup();
}
return false;
}
void AddSettingButton(int board, int id) {
char keyName[32];
static int currentlyBinding;
char pinInfo[32];
snprintf(pinInfo, _countof(pinInfo), "CN3, Pins %d/%d", JVS_BUTTON_NAMES[id].pinNum,
JVS_BUTTON_NAMES[id].pinNum + 1);
AddSetting(JVS_BUTTON_NAMES[id].name, pinInfo);
if (jvsKeybindings[board].buttons[id * 2] == 0) {
igTextColored(DISABLED_COL, "None");
} else {
GetKeyNameTextA(MapVirtualKey(jvsKeybindings[board].buttons[id * 2], MAPVK_VK_TO_VSC) << 16,
keyName, _countof(keyName));
igTextUnformatted(keyName, NULL);
}
igNextColumn();
char name[16];
char name2[16];
char clear[16];
char clear2[16];
char invertName[16];
char invertName2[16];
snprintf(name, _countof(name), "Bind##Bind%d", id);
snprintf(name2, _countof(name2), "Bind##Bind2p%d", id);
snprintf(clear, _countof(clear), "Clear##Bind%d", id);
snprintf(clear2, _countof(clear2), "Clear##Bind2p%d", id);
snprintf(invertName, _countof(invertName), "##Invert%d", id);
snprintf(invertName2, _countof(invertName2), "##Invert2p%d", id);
if (igButton(name, vec0)) {
currentlyBinding = 1;
igOpenPopup_Str(name, ImGuiPopupFlags_None);
}
if (jvsKeybindings[board].buttons[id * 2]) {
igSameLine(0, -1);
if (igButton(clear, vec0)) jvsKeybindings[board].buttons[id * 2] = 0;
}
igNextColumn();
igBeginDisabled(!jvsKeybindings[board].buttons[id * 2]);
igCheckbox(invertName, &jvsKeybindings[board].invert[id * 2]);
igEndDisabled();
igNextColumn();
if (jvsKeybindings[board].buttons[id * 2 + 1] == 0) {
igTextColored(DISABLED_COL, "None");
} else {
GetKeyNameTextA(MapVirtualKey(jvsKeybindings[board].buttons[id * 2 + 1], MAPVK_VK_TO_VSC)
<< 16,
keyName, _countof(keyName));
igTextUnformatted(keyName, NULL);
}
igNextColumn();
if (igButton(name2, vec0)) {
currentlyBinding = 2;
igOpenPopup_Str(name, ImGuiPopupFlags_None);
}
if (jvsKeybindings[board].buttons[id * 2 + 1]) {
igSameLine(0, -1);
if (igButton(clear2, vec0)) {
jvsKeybindings[board].buttons[id * 2 + 1] = 0;
}
}
igNextColumn();
igBeginDisabled(!jvsKeybindings[board].buttons[id * 2 + 1]);
igCheckbox(invertName2, &jvsKeybindings[board].invert[id * 2 + 1]);
igEndDisabled();
igNextColumn();
int boundKey;
if (igKeyBindPopup(name, &boundKey)) {
if (boundKey != -1) {
jvsKeybindings[board].buttons[id * 2 + (currentlyBinding - 1)] = boundKey;
}
currentlyBinding = 0;
}
}
void tab_jvs_board(int num) {
igPushID_Int(num);
igColumns(7, "LogicalButtons", true);
igSetColumnWidth(0, 100);
igSetColumnWidth(1, 70);
igSetColumnWidth(2, 100);
igSetColumnWidth(3, 60);
igSetColumnWidth(4, 70);
igSetColumnWidth(5, 100);
igSetColumnWidth(6, 60);
igTextUnformatted("Button", NULL);
igNextColumn();
igTextUnformatted("Player 1", NULL);
igNextColumn();
igNextColumn();
igTextUnformatted("Invert", NULL);
igNextColumn();
igTextUnformatted("Player 2", NULL);
igNextColumn();
igNextColumn();
igTextUnformatted("Invert", NULL);
igNextColumn();
igSeparator();
for (int i = 0; i < _countof(JVS_BUTTON_NAMES); i++) AddSettingButton(num, i);
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;
}
int boundKey;
if (igKeyBindPopup("BindJvsTest", &boundKey))
if (boundKey != -1) jvsKeybindings[num].test = boundKey;
igEndColumns();
igPopID();
}
void tab_system_buttons() {
char keyName[32];
int boundKey;
igColumns(3, "SystemButtons", true);
igTextUnformatted("Button", NULL);
igNextColumn();
igTextUnformatted("Key", NULL);
igNextColumn();
igNextColumn();
igSeparator();
igTextUnformatted("System Test", NULL);
igNextColumn();
if (keySystemTest == 0) {
igTextColored(DISABLED_COL, "None");
} else {
GetKeyNameTextA(MapVirtualKey(keySystemTest, MAPVK_VK_TO_VSC) << 16, keyName,
_countof(keyName));
igTextUnformatted(keyName, NULL);
}
igNextColumn();
if (igButton("Bind##BindTest", vec0)) igOpenPopup_Str("BindSysTest", ImGuiPopupFlags_None);
if (keySystemTest) {
igSameLine(0, -1);
if (igButton("Clear##ClearTest", vec0)) keySystemTest = 0;
}
igNextColumn();
if (igKeyBindPopup("BindSysTest", &boundKey))
if (boundKey != -1) keySystemTest = boundKey;
igTextUnformatted("System Service", NULL);
igNextColumn();
if (keySystemService == 0) {
igTextColored(DISABLED_COL, "None");
} else {
GetKeyNameTextA(MapVirtualKey(keySystemService, MAPVK_VK_TO_VSC) << 16, keyName,
_countof(keyName));
igTextUnformatted(keyName, NULL);
}
igNextColumn();
if (igButton("Bind##BindService", vec0))
igOpenPopup_Str("BindSysService", ImGuiPopupFlags_None);
if (keySystemService) {
igSameLine(0, -1);
if (igButton("Clear##ClearService", vec0)) keySystemService = 0;
}
igNextColumn();
if (igKeyBindPopup("BindSysService", &boundKey))
if (boundKey != -1) keySystemService = boundKey;
}
void tab_main_keybinds() {
igInputInt("Number of JVS boards", &numJvsBoards, 1, 1, ImGuiInputTextFlags_None);
if (numJvsBoards < 0) numJvsBoards = 0;
if (numJvsBoards > JVS_IO_MAX) numJvsBoards = JVS_IO_MAX;
if (igBeginTabBar("JVSBoards", 0)) {
for (int i = 0; i < numJvsBoards; i++) {
char name[32];
snprintf(name, _countof(name), "Board %d", i + 1);
if (igBeginTabItem(name, NULL, 0)) {
tab_jvs_board(i);
igEndTabItem();
}
}
if (igBeginTabItem("System", NULL, 0)) {
tab_system_buttons();
igEndTabItem();
}
igEndTabBar();
}
}
void hud_control(ImGuiKey open_key) {
static bool isOpen = true;
static bool oldCursor;
if (igIsKeyPressed_Bool(open_key, false)) {
isOpen = !isOpen;
if (isOpen) {
CURSORINFO ci;
GetCursorInfo(&ci);
oldCursor = !!(ci.flags & CURSOR_SHOWING);
ShowCursor(TRUE);
} else {
ShowCursor(oldCursor);
}
}
if (!isOpen) return;
igBegin("Micetools", NULL, 0);
static bool haveFirstFrame = false;
if (!haveFirstFrame) {
ImVec2 size = { 600, 700 };
ImVec2 size = { 600, 450 };
igSetWindowSize_Vec2(size, 0);
haveFirstFrame = true;
}
@@ -140,12 +891,16 @@ void hud_control() {
EnterCriticalSection(&logger_lock);
if (igBeginTabBar("MainTabs", 0)) {
if (igBeginTabItem("Logs", NULL, 0)) {
// log_tab();
if (igBeginTabItem("Keybinds", NULL, 0)) {
igBeginChild_Str("Keybinds", vec0, FALSE, 0);
tab_main_keybinds();
igEndChild();
igEndTabItem();
}
if (igBeginTabItem("JVS", NULL, 0)) {
jvs_tab();
if (igBeginTabItem("Settings", NULL, 0)) {
igBeginChild_Str("Settings", vec0, FALSE, 0);
tab_main_settings();
igEndChild();
igEndTabItem();
}
igEndTabBar();
@@ -156,24 +911,25 @@ void hud_control() {
igEnd();
}
void hud_gui(IDirect3DDevice9* dev) {
void __stdcall hud_gui(unsigned int hookType, IDirect3DDevice9* dev) {
static bool showMenu = false;
// if (GetAsyncKeyState(scancodes["openMenu"]) & 1) {
// showMenu = !showMenu;
// }
ShowCursor(1);
static bool initialized = false;
if (!initialized) {
InitImGui(dev);
InitImGui(hookType, dev);
initialized = true;
}
// if (!showMenu) return;
ImGui_ImplDX9_NewFrame();
ImGui_ImplWin32_NewFrame();
igNewFrame();
if (hookType == UI_HOOK_DX9) {
ImGui_ImplDX9_NewFrame();
ImGui_ImplWin32_NewFrame();
igNewFrame();
} else if (hookType == UI_HOOK_GLUT) {
ImGui_ImplGLUT_ReshapeFunc(glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT));
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGLUT_NewFrame();
}
static bool showFps = false;
if (igIsKeyPressed_Bool(ImGuiKey_F12, false)) showFps = !showFps;
@@ -181,11 +937,16 @@ void hud_gui(IDirect3DDevice9* dev) {
hud_eeprom(ImGuiKey_F11);
hud_sram(ImGuiKey_F10);
// hud_control();
hud_control(ImGuiKey_F4);
igEndFrame();
igRender();
ImGui_ImplDX9_RenderDrawData(igGetDrawData());
if (hookType == UI_HOOK_DX9) {
igEndFrame();
igRender();
ImGui_ImplDX9_RenderDrawData(igGetDrawData());
} else if (hookType == UI_HOOK_GLUT) {
igRender();
ImGui_ImplOpenGL3_RenderDrawData(igGetDrawData());
}
}
void setup_hud_gui() { register_gui_hook(&hud_gui); }

View File

@@ -23,8 +23,8 @@ physical_disk_t SSD = {
},
},
.m_Extended = {
{ 0x102d83, MBR_FS_FAT16, SPD_OS, .m_ReadFunc = &ReadFunc_OSLogFiles }, // 512MB OS update
{ 0x403947, MBR_FS_FAT16, SPD_Patch0, .m_ReadFunc = NULL }, // 2GB patch0
{ 0x102d83, MBR_FS_FAT16, SPD_OS, .m_ReadFunc = &ReadFunc_OSLogFiles, .m_WriteFunc = &WriteFunc_OS }, // 512MB OS update
{ 0x403947, MBR_FS_FAT16, SPD_Patch0, .m_ReadFunc = &ReadFunc_Patch0, .m_WriteFunc = &WriteFunc_Patch0 }, // 2GB patch0
{ 0x403947, MBR_FS_FAT16, SPD_Patch1, .m_ReadFunc = NULL }, // 2GB patch1
{ 0x48ed459, MBR_FS_NTFS, SPD_AppData, .m_ReadFunc = NULL }, // 40GB something
{
@@ -102,9 +102,32 @@ physical_disk_t ALPHA_DVD = {
} },
};
physical_disk_t APM_HDD = {
.m_BusType = BusTypeUsb,
.m_HasSegaboot = false,
.m_BlockSize = BLOCK_SIZE_HDD,
.m_TotalSize = 64 * 1024 * 1024 * (1024 / BLOCK_SIZE_HDD),
.m_DiskType = DiskType_HardDisk,
.m_IsFormatted = true,
.m_Partitions = {
// ~64GB big block
{
.m_Size = 0x801eb80,
.m_Filesystem = MBR_FS_NTFS,
.m_Volume = {
.m_Name = "APM",
.m_MountPoint = 'I', // the APM loader mounts this for us
}
},
},
.m_Extended = {{ 0 }},
};
physical_disk_t* PHYSICAL_DISKS[] = {
&SSD,
&UPDATE_USB,
&APM_HDD,
// &LOG_USB,
// &ALPHA_DVD,
&ALPHA_DVD,
};

View File

@@ -86,6 +86,53 @@ BOOL WriteFunc_Original0(DWORD nOffset, LPCVOID lpBuffer, DWORD nNumberOfBytesTo
return ret;
}
BOOL ReadFunc_Patch0(DWORD nOffset, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead) {
*lpNumberOfBytesRead = 0;
if (!_PathFileExistsA(PATCH0_PATH)) {
log_error("drive", "Failed to open %s (does not exist)", PATCH0_PATH);
return FALSE;
}
HANDLE hFile =
_CreateFileA(PATCH0_PATH, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
log_error("drive", "Failed to open %s", PATCH0_PATH);
return FALSE;
}
LARGE_INTEGER seekTo;
seekTo.QuadPart = (LONGLONG)nOffset * (LONGLONG)SSD.m_BlockSize;
_SetFilePointerEx(hFile, seekTo, NULL, FILE_BEGIN);
BOOL ret = _ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, NULL);
if (!ret) log_error("drive", "Failed to read to %s: %03x", PATCH0_PATH, GetLastError());
_CloseHandle(hFile);
return ret;
}
BOOL WriteFunc_Patch0(DWORD nOffset, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten) {
*lpNumberOfBytesWritten = 0;
HANDLE hFile =
_CreateFileA(PATCH0_PATH, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
log_error("drive", "Failed to open %s", PATCH0_PATH);
return FALSE;
}
LARGE_INTEGER seekTo;
seekTo.QuadPart = (LONGLONG)nOffset * (LONGLONG)SSD.m_BlockSize;
_SetFilePointerEx(hFile, seekTo, NULL, FILE_BEGIN);
BOOL ret = _WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, NULL);
if (!ret) log_error("drive", "Failed to write to %s: %03x", PATCH0_PATH, GetLastError());
_CloseHandle(hFile);
return ret;
}
BOOL WriteFunc_OS(DWORD nOffset, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten) {
*lpNumberOfBytesWritten = nNumberOfBytesToWrite;
log_warning("drive", "%d bytes write in OS at %08x", nNumberOfBytesToWrite, nOffset);
return TRUE;
}
BOOL ReadFunc_OSLogFiles(DWORD nOffset, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead) {
if (nOffset == 2047 && nNumberOfBytesToRead == sizeof(AM_EVENT_LOG_HEADER)) {
@@ -613,7 +660,7 @@ void init_all_pd() {
BOOL q_drive_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped) {
log_misc("q", "CDROM read 0x%04x bytes at 0x%08x", nNumberOfBytesToRead,
log_game("q", "CDROM read 0x%04x bytes at 0x%08x", nNumberOfBytesToRead,
ctx->m_Pointer.QuadPart);
/**
@@ -628,7 +675,9 @@ BOOL q_drive_ReadFile(file_context_t* ctx, LPVOID lpBuffer, DWORD nNumberOfBytes
* +512: Boot ID (128 sectors) [keychip.decrypt]
*/
HANDLE hFile = _CreateFileA("\\\\.\\E:", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
// HANDLE hFile = _CreateFileA("\\\\.\\E:", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
// OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
HANDLE hFile = _CreateFileA("H:\\Arcades\\Images\\ALLNet_Pras_Multi_Ver2\\DVR-0069A.iso", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
log_error("q", "READ FAILED. FILE FALLBACK FAILED. %d", GetLastError());

View File

@@ -20,6 +20,7 @@
#define SBR0_PATH (DISK_PATH "sbr0.bin")
#define SBR1_PATH (DISK_PATH "sbr1.bin")
#define ORIGINAL0_PATH (DISK_PATH "original0.bin")
#define PATCH0_PATH (DISK_PATH "patch0.bin")
extern physical_disk_t SSD;
extern physical_disk_t UPDATE_USB;
@@ -37,7 +38,10 @@ void init_all_pd();
mice_partition_read_function_t ReadFunc_Original0;
mice_partition_write_function_t WriteFunc_Original0;
mice_partition_read_function_t ReadFunc_Patch0;
mice_partition_write_function_t WriteFunc_Patch0;
mice_partition_read_function_t ReadFunc_OSLogFiles;
mice_partition_write_function_t WriteFunc_OS;
FnDeviceIoControl c_drive_DeviceIoControl;
FnDeviceIoControl x_drive_DeviceIoControl;

View File

@@ -132,7 +132,7 @@ inline char char_lower(char value) {
BOOL redirect_path(LPCSTR path, LPCSTR* redirected) {
for (int i = 0; i < sizeof DRIVE_REDIRECT_TABLE / sizeof DRIVE_REDIRECT_TABLE[0]; i++) {
drive_redirect_t row = DRIVE_REDIRECT_TABLE[i];
if (strncmp(path, row.drive, strlen(row.drive)) == 0) {
if (PathPrefix(path, row.drive)) {
log_trace(HOOKS_LOGGER, "Redirecting '%s' to '%s'", path, row.path);
size_t new_len = strlen(path) - strlen(row.drive) + strlen(row.path);
@@ -154,7 +154,7 @@ BOOL redirect_path(LPCSTR path, LPCSTR* redirected) {
// Don't redirect local paths
GetCurrentDirectoryA(sizeof WORKING_DIR, WORKING_DIR);
if (strstr(path, WORKING_DIR) == path) return FALSE;
if (PathPrefix(path, WORKING_DIR)) return FALSE;
if ((('a' <= path[0] && path[0] <= 'z') || ('A' <= path[0] && path[0] <= 'Z')) &&
path[1] == ':' && (path[2] == '/' || path[2] == '\\')) {
@@ -259,8 +259,8 @@ BOOL WINAPI FakeDeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lp
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
open_hook_t* pHData = GetDataForHandle(hDevice, HDATA_FILE);
if (pHData == NULL) {
log_trace(HOOKS_LOGGER, "DeviceIoControl(0x%p, 0x%08x, 0x%p, 0x%x, -, 0x%x, 0, 0)", hDevice,
dwIoControlCode, lpInBuffer, nInBufferSize, nOutBufferSize);
// log_trace(HOOKS_LOGGER, "DeviceIoControl(0x%p, 0x%08x, 0x%p, 0x%x, -, 0x%x, 0, 0)", hDevice,
// dwIoControlCode, lpInBuffer, nInBufferSize, nOutBufferSize);
return TrueDeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer,
nOutBufferSize, lpBytesReturned, lpOverlapped);
@@ -402,9 +402,10 @@ int WINAPIV Fake_stat64i32(const char* path, struct _stat64i32* buffer) {
DWORD WINAPI FakeGetFileAttributesA(LPCSTR lpFileName) {
// The game quits out if MiniDump is present!
if (strcmp(lpFileName, "Y:\\MiniDump\\") == 0) {
if (PathEqual(lpFileName, "Y:\\MiniDump\\") == 0) {
return 0;
}
return (DWORD)-1;
LPCSTR redirected;
if (redirect_path(lpFileName, &redirected)) {

View File

@@ -4,6 +4,8 @@ extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam
HWND mainWindow;
static unsigned int hookType;
static HWND window;
BOOL CALLBACK EnumWindowsCallback(HWND handle, LPARAM lParam) {
DWORD wndProcId;
@@ -105,10 +107,11 @@ void draw_rect(IDirect3DDevice9* dev, int x, int y, int w, int h, unsigned char
HRESULT __stdcall hkEndScene(IDirect3DDevice9* pDevice) {
static bool showMenu = false;
hookType = UI_HOOK_DX9;
end_scene_hook_t* head = end_scene_hook_list;
while (head != NULL) {
head->hook(pDevice);
head->hook(hookType, pDevice);
head = head->next;
}
return TrueEndScene(pDevice);
@@ -138,13 +141,15 @@ void post_win_create(HWND hWnd) {
mainWindow = hWnd;
void* d3d9Device[119];
if (GetD3D9Device(d3d9Device, sizeof(d3d9Device))) {
*((PVOID*)&TrueEndScene) = CreateHook32((PVOID)d3d9Device[42], (PVOID)hkEndScene);
}
if (hookType == UI_HOOK_DX9) {
void* d3d9Device[119];
if (GetD3D9Device(d3d9Device, sizeof(d3d9Device))) {
*((PVOID*)&TrueEndScene) = CreateHook32((PVOID)d3d9Device[42], (PVOID)hkEndScene);
}
if (hWnd && !SetWindowSubclass(hWnd, WndProc, (int)&WndProc, (DWORD_PTR)NULL)) {
log_error("gui", "failed to SetWindowSubclass(%d)", GetLastError());
if (hWnd && !SetWindowSubclass(hWnd, WndProc, (int)&WndProc, (DWORD_PTR)NULL)) {
log_error("gui", "failed to SetWindowSubclass(%d)", GetLastError());
}
}
}
@@ -158,22 +163,36 @@ BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMoni
return TRUE;
}
void SetupWindowPosition(int* X, int* Y, int* nWidth, int* nHeight) {
void SetupWindowPosition(LPRECT lpRect, DWORD dwStyle) {
int x = lpRect->left;
int y = lpRect->top;
int w = lpRect->right - x;
int h = lpRect->bottom - y;
monitorIndex = 0;
EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, (LPARAM)NULL);
if (MiceConfig.window.w) *nWidth = MiceConfig.window.w;
if (MiceConfig.window.h) *nHeight = MiceConfig.window.h;
if (!MiceConfig.window.nosize) {
if (MiceConfig.window.w) w = MiceConfig.window.w;
if (MiceConfig.window.h) h = MiceConfig.window.h;
}
if (MiceConfig.window.centre) {
*X = ((monitorRect.right - monitorRect.left) - *nWidth) / 2;
*Y = ((monitorRect.bottom - monitorRect.top) - *nHeight) / 2;
x = ((monitorRect.right - monitorRect.left) - w) / 2;
y = ((monitorRect.bottom - monitorRect.top) - h) / 2;
} else {
*X = MiceConfig.window.x;
*Y = MiceConfig.window.y;
x = MiceConfig.window.x;
y = MiceConfig.window.y;
}
*X += monitorRect.left;
*Y += monitorRect.top;
x += monitorRect.left;
y += monitorRect.top;
lpRect->left = x;
lpRect->right = x + w;
lpRect->top = y;
lpRect->bottom = y + h;
AdjustWindowRect(lpRect, dwStyle, FALSE);
}
HWND WINAPI FakeCreateWindowExA(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName,
@@ -186,9 +205,16 @@ HWND WINAPI FakeCreateWindowExA(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWi
nHeight, hWndParent, hMenu, hInstance, lpParam);
}
SetupWindowPosition(&X, &Y, &nWidth, &nHeight);
HWND hWnd = TrueCreateWindowExA(dwExStyle, lpClassName, "Micetools", dwStyle, X, Y, nWidth,
nHeight, hWndParent, hMenu, hInstance, lpParam);
RECT winRect;
winRect.left = X;
winRect.right = X + nWidth;
winRect.top = Y;
winRect.bottom = Y + nHeight;
SetupWindowPosition(&winRect, dwStyle);
HWND hWnd =
TrueCreateWindowExA(dwExStyle, lpClassName, "Micetools", dwStyle, winRect.left, winRect.top,
winRect.right - winRect.left, winRect.bottom - winRect.top, hWndParent,
hMenu, hInstance, lpParam);
post_win_create(hWnd);
return hWnd;
}
@@ -202,9 +228,16 @@ HWND WINAPI FakeCreateWindowExW(DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lp
nHeight, hWndParent, hMenu, hInstance, lpParam);
}
SetupWindowPosition(&X, &Y, &nWidth, &nHeight);
HWND hWnd = TrueCreateWindowExW(dwExStyle, lpClassName, L"Micetools", dwStyle, X, Y, nWidth,
nHeight, hWndParent, hMenu, hInstance, lpParam);
RECT winRect;
winRect.left = X;
winRect.right = X + nWidth;
winRect.top = Y;
winRect.bottom = Y + nHeight;
SetupWindowPosition(&winRect, dwStyle);
HWND hWnd =
TrueCreateWindowExW(dwExStyle, lpClassName, L"Micetools", dwStyle, winRect.left,
winRect.top, winRect.right - winRect.left, winRect.bottom - winRect.top,
hWndParent, hMenu, hInstance, lpParam);
post_win_create(hWnd);
return hWnd;
}
@@ -238,26 +271,39 @@ HRESULT STDMETHODCALLTYPE FakeCreateDevice(IDirect3D9* this, UINT Adapter, D3DDE
RECT winRect;
GetWindowRect(hFocusWindow, &winRect);
int w = MiceConfig.window.w ? MiceConfig.window.w : (winRect.right - winRect.left);
int h = MiceConfig.window.h ? MiceConfig.window.h : (winRect.bottom - winRect.top);
int x = MiceConfig.window.x;
int y = MiceConfig.window.y;
if (MiceConfig.window.centre) {
x = ((monitorRect.right - monitorRect.left) - w) / 2;
y = ((monitorRect.bottom - monitorRect.top) - h) / 2;
DWORD dwStyle = GetWindowLongW(hFocusWindow, GWL_STYLE);
SetupWindowPosition(&winRect, dwStyle);
SetWindowPos(hFocusWindow, HWND_TOP, winRect.left, winRect.top, winRect.right - winRect.left,
winRect.bottom - winRect.top, 0);
HRESULT res = TrueCreateDevice(this, Adapter, DeviceType, hFocusWindow, BehaviorFlags,
pPresentationParameters, ppReturnedDeviceInterface);
if (res != S_OK) {
switch (res) {
case D3DERR_DEVICELOST:
log_error("D3D9", "CreateDevice failed: Device lost");
break;
case D3DERR_INVALIDCALL:
log_error("D3D9", "CreateDevice failed: Invalid call");
break;
case D3DERR_NOTAVAILABLE:
log_error("D3D9", "CreateDevice failed: Requested configuration not available");
break;
case D3DERR_OUTOFVIDEOMEMORY:
log_error("D3D9", "CreateDevice failed: VMem exhausted");
break;
default:
log_error("D3D9", "CreateDevice failed: %08x", res);
break;
}
}
x += monitorRect.left;
y += monitorRect.top;
SetWindowPos(hFocusWindow, HWND_TOP, x, y, w, h, 0);
return TrueCreateDevice(this, Adapter, DeviceType, hFocusWindow, BehaviorFlags,
pPresentationParameters, ppReturnedDeviceInterface);
return res;
}
IDirect3D9* WINAPI FakeDirect3DCreate9(UINT SDKVersion) {
IDirect3D9* pD3D = TrueDirect3DCreate9(D3D_SDK_VERSION);
hookType = UI_HOOK_DX9;
TrueCreateDevice = pD3D->lpVtbl->CreateDevice;
DWORD patch = (DWORD)&FakeCreateDevice;
@@ -267,15 +313,50 @@ IDirect3D9* WINAPI FakeDirect3DCreate9(UINT SDKVersion) {
};
int WINAPI FakeGetSystemMetrics(int nIndex) {
int real = TrueGetSystemMetrics(nIndex);
if (nIndex == SM_CXSCREEN && MiceConfig.window.w) return MiceConfig.window.w;
if (nIndex == SM_CYSCREEN && MiceConfig.window.h) return MiceConfig.window.h;
return nIndex;
if (nIndex == SM_CXSCREEN && MiceConfig.window.w)
return MiceConfig.window.w;
else if (nIndex == SM_CYSCREEN && MiceConfig.window.h)
return MiceConfig.window.h;
return TrueGetSystemMetrics(nIndex);
}
void __cdecl Fake_glutFullScreen(void) {
hookType = UI_HOOK_GLUT;
if (!MiceConfig.window.windowed) True_glutFullScreen();
}
void __cdecl Fake_glutSwapBuffers(void) {
hookType = UI_HOOK_GLUT;
end_scene_hook_t* head = end_scene_hook_list;
while (head != NULL) {
head->hook(hookType, NULL);
head = head->next;
}
True_glutSwapBuffers();
}
LONG WINAPI FakeChangeDisplaySettingsExW(LPCWSTR lpszDeviceName, DEVMODEW* lpDevMode, HWND hwnd,
DWORD dwflags, LPVOID lParam) {
if (MiceConfig.window.windowed) return DISP_CHANGE_SUCCESSFUL;
return TrueChangeDisplaySettingsExW(lpszDeviceName, lpDevMode, hwnd, dwflags, lParam);
}
void __cdecl Fake_glutInitDisplayMode(unsigned int mode) {
hookType = UI_HOOK_GLUT;
True_glutInitDisplayMode(mode);
}
void hook_gui() {
hook("User32.dll", "CreateWindowExA", FakeCreateWindowExA, (void**)&TrueCreateWindowExA);
hook("User32.dll", "CreateWindowExW", FakeCreateWindowExW, (void**)&TrueCreateWindowExW);
hook("User32.dll", "GetSystemMetrics", FakeGetSystemMetrics, (void**)&TrueGetSystemMetrics);
hook("User32.dll", "ChangeDisplaySettingsExW", FakeChangeDisplaySettingsExW,
(void**)&TrueChangeDisplaySettingsExW);
hook("D3d9.dll", "Direct3DCreate9", FakeDirect3DCreate9, (void**)&TrueDirect3DCreate9);
// Hooked as a way to identify use of GLUT
hook("FREEGLUT.DLL", "glutInitDisplayMode", Fake_glutInitDisplayMode,
(void**)&True_glutInitDisplayMode);
hook("FREEGLUT.DLL", "glutFullScreen", Fake_glutFullScreen, (void**)&True_glutFullScreen);
hook("FREEGLUT.DLL", "glutSwapBuffers", Fake_glutSwapBuffers, (void**)&True_glutSwapBuffers);
}

View File

@@ -13,12 +13,18 @@ static BOOL(WINAPI* TrueSetSystemCursor)(HCURSOR hcur, DWORD id);
static IDirect3D9*(WINAPI* TrueDirect3DCreate9)(UINT SDKVersion);
static int(WINAPI* TrueGetSystemMetrics)(int nIndex);
static void (*__cdecl True_glutFullScreen)(void);
static void (*__cdecl True_glutSwapBuffers)(void);
static void (*__cdecl True_glutInitDisplayMode)(unsigned int mode);
static LONG (*WINAPI TrueChangeDisplaySettingsExW)(LPCWSTR lpszDeviceName, DEVMODEW* lpDevMode,
HWND hwnd, DWORD dwflags, LPVOID lParam);
#define _GetSystemMetrics (TrueGetSystemMetrics ? TrueGetSystemMetrics : GetSystemMetrics)
void draw_rect(IDirect3DDevice9* dev, int x, int y, int w, int h, unsigned char r, unsigned char g,
unsigned char b);
typedef VOID(FnEndScene)(IDirect3DDevice9* dev);
typedef VOID(__stdcall FnEndScene)(unsigned int hookType, IDirect3DDevice9* dev);
typedef struct end_scene_hook {
FnEndScene* hook;
@@ -26,6 +32,9 @@ typedef struct end_scene_hook {
} end_scene_hook_t;
end_scene_hook_t* end_scene_hook_list;
#define UI_HOOK_DX9 0
#define UI_HOOK_GLUT 1
void register_gui_hook(FnEndScene* end_scene);
void hook_gui();
void setup_hud_gui();

View File

@@ -101,10 +101,10 @@ BOOL WINAPI FakeDeregisterEventSource(HANDLE hEventLog) { return TRUE; }
// lpOutputString); }
void hook_logging() {
hook("MSVCR90.DLL", "printf", Fakeprintf, (void**)&Trueprintf);
hook("MSVCR90.DLL", "fprintf", Fakefprintf, (void**)&Truefprintf);
hook("MSVCR90.DLL", "fprintf_s", Fakefprintf_s, (void**)&Truefprintf_s);
hook("MSVCR90.DLL", "vfprintf_s", Fakevfprintf_s, (void**)&Truevfprintf_s);
// hook("MSVCR90.DLL", "printf", Fakeprintf, (void**)&Trueprintf);
// hook("MSVCR90.DLL", "fprintf", Fakefprintf, (void**)&Truefprintf);
// hook("MSVCR90.DLL", "fprintf_s", Fakefprintf_s, (void**)&Truefprintf_s);
// hook("MSVCR90.DLL", "vfprintf_s", Fakevfprintf_s, (void**)&Truevfprintf_s);
hook("Advapi32.dll", "RegisterEventSourceA", FakeRegisterEventSourceA,
(void**)&TrueRegisterEventSourceA);

View File

@@ -5,12 +5,20 @@ int WINAPI Fake_connect(SOCKET s, const SOCKADDR* name, int namelen) {
USHORT port = _byteswap_ushort(((SOCKADDR_IN*)name)->sin_port);
// Poorly exclude pcps. TODO: better
// if (port < 40100 || port > 40120) {
log_misc("connect", "%hhu.%hhu.%hhu.%hhu:%hu", (addr >> 24) & 0xff, (addr >> 16) & 0xff,
log_info("connect", "%hhu.%hhu.%hhu.%hhu:%hu", (addr >> 24) & 0xff, (addr >> 16) & 0xff,
(addr >> 8) & 0xff, addr & 0xff, port);
// }
return True_connect(s, name, namelen);
}
int WINAPI Fake_bind(SOCKET s, const SOCKADDR* name, int namelen) {
ULONG addr = _byteswap_ulong(((SOCKADDR_IN*)name)->sin_addr.S_un.S_addr);
USHORT port = _byteswap_ushort(((SOCKADDR_IN*)name)->sin_port);
log_info("bind", "%hhu.%hhu.%hhu.%hhu:%hu", (addr >> 24) & 0xff, (addr >> 16) & 0xff,
(addr >> 8) & 0xff, addr & 0xff, port);
return True_bind(s, name, namelen);
}
#define IF_INDEX 1
// Sega prefix
#define MAC_PREFIX_0 0xD8
@@ -132,6 +140,7 @@ INT WSAAPI FakeWSAStringToAddressA(LPSTR AddressString, INT AddressFamily,
void hook_network() {
hook("Ws2_32.dll", "connect", Fake_connect, (void**)&True_connect);
hook("Ws2_32.dll", "bind", Fake_bind, (void**)&True_bind);
hook("Ws2_32.dll", "WSAStringToAddressA", FakeWSAStringToAddressA,
(void**)&TrueWSAStringToAddressA);
hook("Iphlpapi.dll", "GetIfTable", FakeGetIfTable, (void**)&TrueGetIfTable);

View File

@@ -2,6 +2,7 @@
#include "../common.h"
static int(WINAPI* True_connect)(SOCKET s, const SOCKADDR* name, int namelen);
static int(WINAPI* True_bind)(SOCKET s, const SOCKADDR* addr, int namelen);
static DWORD(WINAPI* TrueGetIfTable)(PMIB_IFTABLE pIfTable, PULONG pdwSize, BOOL bOrder);

View File

@@ -16,13 +16,17 @@ BOOL WINAPI FakeCreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine,
LPPROCESS_INFORMATION lpProcessInformation) {
log_info("spawn", "CreateProcessA %s %s", lpApplicationName, lpCommandLine);
return TrueCreateProcessA("mxAuthDisc.bat", "", lpProcessAttributes,
lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
lpCurrentDirectory, lpStartupInfo, lpProcessInformation);
HANDLE fake_evt = CreateEvent(NULL, TRUE, FALSE, NULL);
SetEvent(fake_evt);
if (lpProcessInformation) {
lpProcessInformation->hProcess = fake_evt;
}
return FALSE;
return TRUE;
}
BOOL WINAPI FakeCreateProcessW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
@@ -95,5 +99,5 @@ BOOL WINAPI FakeGetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode) {
void hook_processes() {
hook("Kernel32.dll", "CreateProcessW", FakeCreateProcessW, (void**)&TrueCreateProcessW);
hook("Kernel32.dll", "CreateProcessA", FakeCreateProcessA, (void**)&TrueCreateProcessA);
hook("Kernel32.dll", "GetExitCodeProcess", FakeGetExitCodeProcess, NULL);
// hook("Kernel32.dll", "GetExitCodeProcess", FakeGetExitCodeProcess, NULL);
}

View File

@@ -2,8 +2,6 @@
#include "./files.h"
// const char OS_VERSION[] = "Service Pack 3";
OSVERSIONINFOA OS_VERSION = {
.dwOSVersionInfoSize = 148,
.dwMajorVersion = 5,
@@ -47,15 +45,44 @@ LONG WINAPI FakeChangeDisplaySettingsExA(LPCSTR lpszDeviceName, DEVMODEA* lpDevM
return 0;
}
FARPROC FakeGetProcAddress(HMODULE hModule, LPCSTR lpProcName) {
log_trace("system", "GetProcAddress(%s)", lpProcName);
return TrueGetProcAddress(hModule, lpProcName);
}
HMODULE FakeGetModuleHandleA(LPCSTR lpModuleName) {
log_trace("system", "GetModuleHandleA(%s)", lpModuleName);
return TrueGetModuleHandleA(lpModuleName);
}
LONG WINAPI FakeRtlGetVersion(PRTL_OSVERSIONINFOW lpVersionInformation) {
log_trace("system", "RtlGetVersion(%p)", lpVersionInformation);
if (lpVersionInformation->dwOSVersionInfoSize >= sizeof (OSVERSIONINFOW)) {
lpVersionInformation->dwMajorVersion = OS_VERSION.dwMajorVersion;
lpVersionInformation->dwMinorVersion = OS_VERSION.dwMinorVersion;
lpVersionInformation->dwBuildNumber = OS_VERSION.dwBuildNumber;
}
if (lpVersionInformation->dwOSVersionInfoSize >= sizeof (OSVERSIONINFOEXW)) {
PRTL_OSVERSIONINFOEXW lpVersionInformationEx = (PRTL_OSVERSIONINFOEXW)lpVersionInformation;
lpVersionInformationEx->wServicePackMajor = 3;
lpVersionInformationEx->wServicePackMinor = 0;
}
return 0;
}
void hook_system() {
// TODO: This should be part of drives/hooks.c
hook("Kernel32.dll", "GetVolumeInformationW", FakeGetVolumeInformationW, 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", "GetModuleHandleA", FakeGetModuleHandleA, (void*)&TrueGetModuleHandleA);
hook("User32.dll", "ChangeDisplaySettingsA", FakeChangeDisplaySettingsA, NULL);
hook("User32.dll", "ChangeDisplaySettingsExA", FakeChangeDisplaySettingsExA, NULL);
// hook("ntdll.dll", "RtlGetVersion", FakeRtlGetVersion, NULL);
// hook("User32.dll", "LoadCursorFromFileA", FakeLoadCursorFromFileA, NULL);
// hook("User32.dll", "SetSystemCursor", FakeSetSystemCursor, NULL);
// hook("User32.dll", "DeleteObject", FakeDeleteObject, NULL);

View File

@@ -2,4 +2,7 @@
#include "../common.h"
FARPROC (*TrueGetProcAddress)(HMODULE hModule, LPCSTR lpProcName);
HMODULE (*TrueGetModuleHandleA)(LPCSTR lpModuleName);
void hook_system();

View File

@@ -31,18 +31,40 @@ BOOL WINAPI Fake_SetTimeZoneInformation(const TIME_ZONE_INFORMATION* lpTimeZoneI
// TODO: Store deltas instead
BOOL WINAPI Fake_GetLocalTime(SYSTEMTIME* lpSystemTime) {
log_trace("time", "GetLocalTime");
if (ltCache) {
memcpy(lpSystemTime, &localTime, sizeof localTime);
return TRUE;
}
// lpSystemTime->wYear = 2023;
// lpSystemTime->wMonth = 2;
// lpSystemTime->wDayOfWeek = 0;
// lpSystemTime->wDay = 12;
// lpSystemTime->wHour = 17;
// lpSystemTime->wMinute = 29;
// lpSystemTime->wSecond = 12;
// lpSystemTime->wMilliseconds = 764;
// return TRUE;
return TrueGetLocalTime(lpSystemTime);
}
BOOL WINAPI Fake_GetSystemTime(SYSTEMTIME* lpSystemTime) {
log_trace("time", "GetSystemTime");
if (stCache) {
memcpy(lpSystemTime, &systemTime, sizeof systemTime);
return TRUE;
}
return TrueGetSystemTime(lpSystemTime);
// lpSystemTime->wYear = 2023;
// lpSystemTime->wMonth = 2;
// lpSystemTime->wDayOfWeek = 0;
// lpSystemTime->wDay = 12;
// lpSystemTime->wHour = 17;
// lpSystemTime->wMinute = 29;
// lpSystemTime->wSecond = 12;
// lpSystemTime->wMilliseconds = 764;
// return TRUE;
}
void hook_time() {

View File

@@ -0,0 +1,17 @@
#pragma once
#include <stdbool.h>
#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;
} jvsKeybindings[JVS_IO_MAX];
int keySystemTest = 0;
int keySystemService = 0;
int numJvsBoards = 1;

View File

@@ -11,6 +11,7 @@ shared_library(
'util/misc.c',
'util/log.c',
'util/hook.c',
'util/path.c',
drivers_files,
devices_files,
@@ -26,10 +27,11 @@ shared_library(
mice_lib,
amiTimer,
amiMd5,
mxk,
mxklib,
],
include_directories: [
openssl_inc,
],
dependencies: [cimgui.get_variable('cimgui_dep')]
dependencies: [cimgui.get_variable('cimgui_dep'), freeglut_lib]
)

View File

@@ -1,16 +1,6 @@
#pragma once
#include "common.h"
// PCA9535 (DIPSW)
#define PCA9535_IN0 0x00
#define PCA9535_IN1 0x01
#define PCA9535_OUT0 0x02
#define PCA9535_OUT1 0x03
#define PCA9535_INV0 0x04
#define PCA9535_INV1 0x05
#define PCA9535_CONF0 0x06
#define PCA9535_CONF1 0x07
/*
W83627UHG:
Configuration is based on HEFRAS

View File

@@ -15,4 +15,7 @@ HANDLE GetDummyHandle();
void BytesToHex(char* hex_buffer, BYTE* bytes, DWORD nbytes);
void PrintStack(void);
BOOL PathEqual(LPCSTR path1, LPCSTR path2);
BOOL PathPrefix(LPCSTR path, LPCSTR prefix);
void make_dirs(const char* path);

View File

@@ -103,6 +103,18 @@ void* CreateHook32(PVOID src, PVOID dst) {
} else if (bSrc[0] == 0x68) {
// push 0x... (dword)
len = 5;
} else if (bSrc[0] == 0x55 && bSrc[1] == 0x8B && bSrc[2] == 0xEC && bSrc[3] == 0x83 &&
bSrc[4] == 0xE4) {
// pusb ebp
// mov ebp,esp
// and esp,ffffff**
len = 6;
} else if (bSrc[0] == 0x55 && bSrc[1] == 0x8B && bSrc[2] == 0xEC && bSrc[3] == 0x8b &&
bSrc[4] == 0x45) {
// pusb ebp
// mov ebp,esp
// mov eax,DWORD PTR [...]
len = 6;
} else {
log_error(HOOKS_LOGGER, "Unable to identify gateway length! Function peek:");
for (int i = 0; i < 16; i++) {
@@ -126,6 +138,8 @@ void* CreateHook32(PVOID src, PVOID dst) {
return gateway;
}
extern FARPROC (*TrueGetProcAddress)(HMODULE hModule, LPCSTR lpProcName);
void setup_hooks() {
log_info(HOOKS_LOGGER, "attaching");
@@ -145,6 +159,8 @@ void setup_hooks() {
continue;
}
// void* original =
// (TrueGetProcAddress ? TrueGetProcAddress : GetProcAddress)(dll, hook->name);
void* original = GetProcAddress(dll, hook->name);
if (original == NULL) {
log_warning(HOOKS_LOGGER, "failed to get original %s (%03x)", hook->name,

View File

@@ -8,6 +8,7 @@
#pragma comment(lib, "DbgHelp.lib")
#include "../../lib/mice/config.h"
#include "../hooks/files.h"
#include "../hooks/logging.h"
extern WCHAR exeName[MAX_PATH + 1];
@@ -30,11 +31,11 @@ char* log_prelude() {
return _log_prelude;
}
HANDLE log_file = NULL;
static HANDLE log_file = NULL;
VOID trace_hook(char* output);
CRITICAL_SECTION logger_lock;
char* log_colours[] = {
static char* log_colours[] = {
"", // Always
"\033[96m", // Game
"\033[91m", // Error
@@ -43,27 +44,9 @@ char* log_colours[] = {
"\033[90m", // Misc
"\033[90m", // Trace
};
static const char* COLOR_RESET = "\033[0m";
#define LOG_PREFIXES "!GEWIMT"
void force_console_bind() {
// AttachConsole(ATTACH_PARENT_PROCESS);
if (GetStdHandle(STD_ERROR_HANDLE) > (HANDLE)0x10) {
FILE* newstream;
if (GetStdHandle(STD_INPUT_HANDLE)) {
freopen_s(&newstream, "CONIN$", "r", stdin);
setvbuf(stdin, NULL, _IONBF, 0);
}
if (GetStdHandle(STD_OUTPUT_HANDLE)) {
freopen_s(&newstream, "CONOUT$", "w", stdout);
setvbuf(stdout, NULL, _IONBF, 0);
}
if (GetStdHandle(STD_ERROR_HANDLE)) {
freopen_s(&newstream, "CONOUT$", "w", stderr);
setvbuf(stderr, NULL, _IONBF, 0);
}
}
}
void logcb(LPCSTR param_1) { log_game("amLog", param_1); }
void __stdcall amLogCallback(DWORD level, char* format) {
if (level == 0)
@@ -77,6 +60,7 @@ void __stdcall amLogCallback(DWORD level, char* format) {
DWORD pLogcb;
DWORD* ppLogcb;
static char log_buf[1024];
int _do_log(BYTE log_level, const char* caller, const char* format, va_list args) {
// TODO: These are all horrible bodges
if (wcscmp(exeName, L"mxnetwork.exe") == 0) {
@@ -91,45 +75,35 @@ int _do_log(BYTE log_level, const char* caller, const char* format, va_list args
// *((DWORD*)(imageOffset + 0x004438e8)) = (DWORD)(&logcb);
}
force_console_bind();
char prefix = LOG_PREFIXES[log_level];
EnterCriticalSection(&logger_lock);
int len = snprintf(NULL, 0, "%s%c:%s:", log_prelude(), prefix, caller) +
vsnprintf(NULL, 0, format, args);
char* buf = (char*)malloc(len + 2);
if (!buf) {
LeaveCriticalSection(&logger_lock);
return 0;
}
int wrote_a = snprintf(buf, len, "%s%c:%s:", log_prelude(), prefix, caller);
int wrote_b = vsnprintf(buf + wrote_a, len - wrote_a + 1, format, args);
buf[len] = '\n';
buf[len + 1] = '\0';
int col_len = strlen(log_colours[log_level]);
int log_len = snprintf(log_buf, _countof(log_buf), "%s%s%c:%s:", log_colours[log_level],
log_prelude(), prefix, caller);
log_len += vsnprintf(log_buf + log_len, _countof(log_buf) - log_len, format, args);
log_len += snprintf(log_buf + log_len, _countof(log_buf) - log_len, "%s\n", COLOR_RESET);
log_buf[_countof(log_buf) - 1] = '\0';
// No +1 here to not get the \n
if (MiceConfig.mice.log_level >= log_level) {
HANDLE sout = GetStdHandle(STD_OUTPUT_HANDLE);
if (HAS_COLOUR)
(TrueWriteFile ? *TrueWriteFile : WriteFile)(
sout, log_colours[log_level], strlen(log_colours[log_level]), NULL, NULL);
if (sout != INVALID_HANDLE_VALUE)
(TrueWriteFile ? TrueWriteFile : WriteFile)(sout, buf, len, NULL, NULL);
puts(HAS_COLOUR ? "\033[0m" : "");
FlushFileBuffers(sout);
_WriteFile(sout, log_buf, log_len, NULL, NULL);
// FlushFileBuffers(sout);
}
if (MiceConfig.mice.log_to_file) {
if (log_file && log_file != INVALID_HANDLE_VALUE)
(TrueWriteFile ? TrueWriteFile : WriteFile)(log_file, buf, len + 1, NULL, NULL);
if (log_file && log_file != INVALID_HANDLE_VALUE) {
// Replace the colour reset with a newline, then skip the prefix when writing
log_buf[log_len - col_len] = '\n';
log_buf[log_len - col_len + 1] = '\0';
_WriteFile(log_file, log_buf + col_len, log_len - col_len - sizeof(COLOR_RESET), NULL, NULL);
}
}
free(buf);
LeaveCriticalSection(&logger_lock);
return wrote_b;
return log_len;
}
int vlog_trace(const char* caller, const char* format, va_list args) {
return _do_log(LOG_TRACE, caller, format, args);
@@ -199,10 +173,7 @@ VOID trace_hook(char* output) {
void setup_logging() {
// Force stdio even for GUI applications
// TODO: Is there a more robust way to check if we have a proper stdio?
if (false) {
force_console_bind();
}
// AttachConsole(ATTACH_PARENT_PROCESS);
// Enable colour in CMD
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

View File

@@ -133,6 +133,10 @@ void make_dirs(const char* path) {
for (i = 0; i < len; i++) {
if (temp[i] == '/' || temp[i] == '\\') count++;
}
// Don't create directories for trailing slashes
if (count && i && (temp[i - 1] == '/' || temp[i - 1] == '\\')) {
count--;
}
if (count == 0) {
free(temp);
return;

View File

@@ -0,0 +1,23 @@
#include <Windows.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
BOOL PathEqual(LPCSTR path1, LPCSTR path2) {
char buffer1[MAX_PATH];
char buffer2[MAX_PATH];
GetFullPathNameA(path1, _countof(buffer1), buffer1, NULL);
GetFullPathNameA(path2, _countof(buffer2), buffer2, NULL);
return strcmp(path1, path2) == 0;
}
BOOL PathPrefix(LPCSTR path, LPCSTR prefix) {
char buffer1[MAX_PATH];
char buffer2[MAX_PATH];
GetFullPathNameA(path, _countof(buffer1), buffer1, NULL);
GetFullPathNameA(prefix, _countof(buffer2), buffer2, NULL);
return strstr(buffer1, buffer2) == buffer1;
}

View File

@@ -5,6 +5,7 @@
#include <string.h>
#include "../../../../subprojects/inih_dep/ini.h"
#include "../../dll/devices/smb_pca9535.h"
config_t MiceConfig = {
#define SECTION(s, comment) .s = {
@@ -78,7 +79,53 @@ void make_default_config() {
fclose(config_file);
}
int handler(void *user, const char *section, const char *name, const char *value) {
void save_current_config() {
FILE *config_file;
fopen_s(&config_file, CONFIG_PATH, "w");
if (config_file == NULL) {
puts("Failed to create config file!");
return;
};
int first_section = true;
#define CFG_str(s, n, default, comment) \
if (strlen(comment) != 0) fprintf_prefix(config_file, "; ", comment); \
fprintf(config_file, "%s = %s ;(string)\n", #n, MiceConfig.s.n);
#define CFG_bool(s, n, default, comment) \
if (strlen(comment) != 0) fprintf_prefix(config_file, "; ", comment); \
fprintf(config_file, "%s = %s ;(bool)\n", #n, MiceConfig.s.n ? "true" : "false");
#define CFG_int(s, n, default, comment) \
if (strlen(comment) != 0) fprintf_prefix(config_file, "; ", comment); \
fprintf(config_file, "%s = %d ;(int)\n", #n, MiceConfig.s.n);
#define CFG_hex(s, n, precision, default, comment) \
if (strlen(comment) != 0) fprintf_prefix(config_file, "; ", comment); \
fprintf(config_file, "%s = %.*X ;(hex, %d byte%s)\n", #n, precision, MiceConfig.s.n, \
precision, precision == 1 ? "" : "s");
#define CFG_ipv4(s, n, a, b, c, d, comment) \
if (strlen(comment) != 0) fprintf_prefix(config_file, "; ", comment); \
fprintf(config_file, "%s = %hhu.%hhu.%hhu.%hhu ;(ipv4)\n", #n, (MiceConfig.s.n >> 24), \
((MiceConfig.s.n >> 16) & 0xff), ((MiceConfig.s.n >> 8) & 0xff), \
(MiceConfig.s.n & 0xff));
#define SECTION(s, comment) \
if (!first_section) fprintf(config_file, "\n"); \
first_section = false; \
if (strlen(comment) != 0) fprintf_prefix(config_file, "; ", comment); \
fprintf(config_file, "[%s]\n", #s);
#define COMMENT(comment) \
if (strlen(comment) != 0) fprintf_prefix(config_file, "; ", comment);
#include "config.def"
fclose(config_file);
}
static int handler(void *user, const char *section, const char *name, const char *value) {
config_t *cfg = (config_t *)user;
char *end;
@@ -115,9 +162,33 @@ int handler(void *user, const char *section, const char *name, const char *value
return 1;
}
const unsigned int RES_W[8] = {640, 640, 1024, 1024, 1280, 1280, 1360, 1920};
const unsigned int RES_H[8] = {480, 480, 600, 768, 720, 1024, 768, 1080};
void load_mice_config() {
if (ini_parse(CONFIG_PATH, handler, &MiceConfig) < 0) {
make_default_config();
printf("Can't load '%s', using defaults\n", CONFIG_PATH);
}
if (MiceConfig.window.dipsw) {
MiceConfig.window.w = RES_W[(MiceConfig.sysconf.dipsw >> 4) & 0b111];
MiceConfig.window.h = RES_H[(MiceConfig.sysconf.dipsw >> 4) & 0b111];
} else {
MiceConfig.sysconf.dipsw &= 0b1'000'1111;
if (MiceConfig.window.w == 1920 && MiceConfig.window.h == 1080)
MiceConfig.sysconf.dipsw |= DIPSW_RES_1920x1080;
else if (MiceConfig.window.w == 1360 && MiceConfig.window.h == 768)
MiceConfig.sysconf.dipsw |= DIPSW_RES_1360x768;
else if (MiceConfig.window.w == 1280 && MiceConfig.window.h == 1024)
MiceConfig.sysconf.dipsw |= DIPSW_RES_1280x1024;
else if (MiceConfig.window.w == 1280 && MiceConfig.window.h == 720)
MiceConfig.sysconf.dipsw |= DIPSW_RES_1280x720;
else if (MiceConfig.window.w == 1024 && MiceConfig.window.h == 768)
MiceConfig.sysconf.dipsw |= DIPSW_RES_1024x768;
else if (MiceConfig.window.w == 1024 && MiceConfig.window.h == 600)
MiceConfig.sysconf.dipsw |= DIPSW_RES_1024x600;
else if (MiceConfig.window.w == 640 && MiceConfig.window.h == 480)
MiceConfig.sysconf.dipsw |= DIPSW_RES_640x480;
}
}

View File

@@ -31,6 +31,7 @@ SECTION(sysconf, "System configuration settings")
CFG_int(sysconf, region, 1, "Board region. 1 = Jpn, 2 = USA, 4 = Exp, 8 = Chn")
CFG_bool(sysconf, rental, false, "")
CFG_str(sysconf, serial, "AASE-01A65646203", "")
CFG_hex(sysconf, dipsw, 2, 70, "DIP Switch values")
ENDSECTION(sysconf)
SECTION(window, "Game window positioning settings")
@@ -40,6 +41,8 @@ CFG_int(window, adaptor, 0, "Display adaptor to use")
CFG_bool(window, centre, true, "Centre the window. X and Y are used otherwise")
CFG_int(window, x, 0, "Window position X")
CFG_int(window, y, 0, "Window position Y")
CFG_bool(window, nosize, true, "Don't change window resolution")
CFG_bool(window, dipsw, true, "Use DIPSW for resolution")
CFG_int(window, w, 0, "Window width (0 to unset)")
CFG_int(window, h, 0, "Window height (0 to unset)")
ENDSECTION(window)

View File

@@ -1,3 +1,6 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
#define CONFIG_PATH "mice.ini"
@@ -17,4 +20,5 @@ typedef struct config {
extern config_t MiceConfig;
void make_default_config();
void save_current_config();
void load_mice_config();

View File

@@ -8,7 +8,7 @@ config_t Config = {
#include "config.def"
._keep_linter_happy = true};
void make_default_config() {
static void make_default_config() {
FILE *config_file;
fopen_s(&config_file, CONFIG_PATH, "w");
if (config_file == NULL) {
@@ -52,7 +52,7 @@ void make_default_config() {
fclose(config_file);
}
int handler(void *user, const char *section, const char *name, const char *value) {
static int handler(void *user, const char *section, const char *name, const char *value) {
config_t *cfg = (config_t *)user;
char *end;
@@ -83,7 +83,7 @@ void load_config() {
if (ini_parse(CONFIG_PATH, handler, &Config) < 0) printf("Can't load '%s', using defaults\n", CONFIG_PATH);
}
int main() {
int mxkMain() {
DWORD dwAttrib = GetFileAttributes(CONFIG_PATH);
if (dwAttrib == INVALID_FILE_ATTRIBUTES || (dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) make_default_config();
@@ -100,3 +100,7 @@ int main() {
if (err != e_pcpp_ok) PCP_LOG("Server tick: %d\n", err);
}
}
int main() {
return mxkMain();
}

View File

@@ -3,20 +3,26 @@ link_with = [inih.get_variable('lib_inih'), libpcp]
rc = import('windows').compile_resources('micekeychip.rc', depend_files: micekeychip_ico)
sources = [
'main.c',
'mxk.c',
'callbacks/appboot.c',
'callbacks/billing.c',
'callbacks/crypto.c',
'callbacks/misc.c',
'callbacks/tracedata.c',
'callbacks/storage.c',
rc,
]
mxk = static_library(
'mxk',
sources: sources,
link_with: link_with,
)
executable(
'micekeychip',
win_subsystem: subsystem,
sources: [
'main.c',
'mxk.c',
'callbacks/appboot.c',
'callbacks/billing.c',
'callbacks/crypto.c',
'callbacks/misc.c',
'callbacks/tracedata.c',
'callbacks/storage.c',
rc,
],
sources: sources,
link_with: link_with,
dependencies: dependencies,
)

View File

@@ -34,7 +34,7 @@ void fprintf_prefix(FILE *file, const char *prefix, const char *text) {
free(copy);
}
void make_default_config() {
static void make_default_config() {
FILE *config_file;
fopen_s(&config_file, CONFIG_PATH, "w");
if (config_file == NULL) {
@@ -78,7 +78,7 @@ void make_default_config() {
fclose(config_file);
}
int handler(void *user, const char *section, const char *name, const char *value) {
static int handler(void *user, const char *section, const char *name, const char *value) {
config_t *cfg = (config_t *)user;
char *end;