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

BIN
lib/freeglut.lib Normal file

Binary file not shown.

View File

@ -18,6 +18,10 @@ openssl_lib = meson.get_compiler('c').find_library('libeay32', dirs: [
], required: true)
assert(openssl_lib.found(), 'Please download openssl!')
freeglut_lib = meson.get_compiler('c').find_library('freeglut', dirs: [
join_paths(meson.source_root(), 'lib')
], required: true)
add_project_link_arguments(
'/FIXED:NO',
'/DYNAMICBASE',

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;

View File

@ -0,0 +1,22 @@
#ifndef __FREEGLUT_H__
#define __FREEGLUT_H__
/*
* freeglut.h
*
* The freeglut library include file
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "freeglut_std.h"
#include "freeglut_ext.h"
/*** END OF FILE ***/
#endif /* __FREEGLUT_H__ */

View File

@ -0,0 +1,271 @@
#ifndef __FREEGLUT_EXT_H__
#define __FREEGLUT_EXT_H__
/*
* freeglut_ext.h
*
* The non-GLUT-compatible extensions to the freeglut library include file
*
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
* Creation date: Thu Dec 2 1999
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
* Additional GLUT Key definitions for the Special key function
*/
#define GLUT_KEY_NUM_LOCK 0x006D
#define GLUT_KEY_BEGIN 0x006E
#define GLUT_KEY_DELETE 0x006F
#define GLUT_KEY_SHIFT_L 0x0070
#define GLUT_KEY_SHIFT_R 0x0071
#define GLUT_KEY_CTRL_L 0x0072
#define GLUT_KEY_CTRL_R 0x0073
#define GLUT_KEY_ALT_L 0x0074
#define GLUT_KEY_ALT_R 0x0075
/*
* GLUT API Extension macro definitions -- behaviour when the user clicks on an "x" to close a window
*/
#define GLUT_ACTION_EXIT 0
#define GLUT_ACTION_GLUTMAINLOOP_RETURNS 1
#define GLUT_ACTION_CONTINUE_EXECUTION 2
/*
* Create a new rendering context when the user opens a new window?
*/
#define GLUT_CREATE_NEW_CONTEXT 0
#define GLUT_USE_CURRENT_CONTEXT 1
/*
* Direct/Indirect rendering context options (has meaning only in Unix/X11)
*/
#define GLUT_FORCE_INDIRECT_CONTEXT 0
#define GLUT_ALLOW_DIRECT_CONTEXT 1
#define GLUT_TRY_DIRECT_CONTEXT 2
#define GLUT_FORCE_DIRECT_CONTEXT 3
/*
* GLUT API Extension macro definitions -- the glutGet parameters
*/
#define GLUT_INIT_STATE 0x007C
#define GLUT_ACTION_ON_WINDOW_CLOSE 0x01F9
#define GLUT_WINDOW_BORDER_WIDTH 0x01FA
#define GLUT_WINDOW_BORDER_HEIGHT 0x01FB
#define GLUT_WINDOW_HEADER_HEIGHT 0x01FB /* Docs say it should always have been GLUT_WINDOW_BORDER_HEIGHT, keep this for backward compatibility */
#define GLUT_VERSION 0x01FC
#define GLUT_RENDERING_CONTEXT 0x01FD
#define GLUT_DIRECT_RENDERING 0x01FE
#define GLUT_FULL_SCREEN 0x01FF
#define GLUT_SKIP_STALE_MOTION_EVENTS 0x0204
#define GLUT_GEOMETRY_VISUALIZE_NORMALS 0x0205
#define GLUT_STROKE_FONT_DRAW_JOIN_DOTS 0x0206 /* Draw dots between line segments of stroke fonts? */
/*
* New tokens for glutInitDisplayMode.
* Only one GLUT_AUXn bit may be used at a time.
* Value 0x0400 is defined in OpenGLUT.
*/
#define GLUT_AUX 0x1000
#define GLUT_AUX1 0x1000
#define GLUT_AUX2 0x2000
#define GLUT_AUX3 0x4000
#define GLUT_AUX4 0x8000
/*
* Context-related flags, see fg_state.c
* Set the requested OpenGL version
*/
#define GLUT_INIT_MAJOR_VERSION 0x0200
#define GLUT_INIT_MINOR_VERSION 0x0201
#define GLUT_INIT_FLAGS 0x0202
#define GLUT_INIT_PROFILE 0x0203
/*
* Flags for glutInitContextFlags, see fg_init.c
*/
#define GLUT_DEBUG 0x0001
#define GLUT_FORWARD_COMPATIBLE 0x0002
/*
* Flags for glutInitContextProfile, see fg_init.c
*/
#define GLUT_CORE_PROFILE 0x0001
#define GLUT_COMPATIBILITY_PROFILE 0x0002
/*
* Process loop function, see fg_main.c
*/
FGAPI void FGAPIENTRY glutMainLoopEvent( void );
FGAPI void FGAPIENTRY glutLeaveMainLoop( void );
FGAPI void FGAPIENTRY glutExit ( void );
/*
* Window management functions, see fg_window.c
*/
FGAPI void FGAPIENTRY glutFullScreenToggle( void );
FGAPI void FGAPIENTRY glutLeaveFullScreen( void );
/*
* Menu functions
*/
FGAPI void FGAPIENTRY glutSetMenuFont( int menuID, void* font );
/*
* Window-specific callback functions, see fg_callbacks.c
*/
FGAPI void FGAPIENTRY glutMouseWheelFunc( void (* callback)( int, int, int, int ) );
FGAPI void FGAPIENTRY glutPositionFunc( void (* callback)( int, int ) );
FGAPI void FGAPIENTRY glutCloseFunc( void (* callback)( void ) );
FGAPI void FGAPIENTRY glutWMCloseFunc( void (* callback)( void ) );
/* And also a destruction callback for menus */
FGAPI void FGAPIENTRY glutMenuDestroyFunc( void (* callback)( void ) );
/*
* State setting and retrieval functions, see fg_state.c
*/
FGAPI void FGAPIENTRY glutSetOption ( GLenum option_flag, int value );
FGAPI int * FGAPIENTRY glutGetModeValues(GLenum mode, int * size);
/* A.Donev: User-data manipulation */
FGAPI void* FGAPIENTRY glutGetWindowData( void );
FGAPI void FGAPIENTRY glutSetWindowData(void* data);
FGAPI void* FGAPIENTRY glutGetMenuData( void );
FGAPI void FGAPIENTRY glutSetMenuData(void* data);
/*
* Font stuff, see fg_font.c
*/
FGAPI int FGAPIENTRY glutBitmapHeight( void* font );
FGAPI GLfloat FGAPIENTRY glutStrokeHeight( void* font );
FGAPI void FGAPIENTRY glutBitmapString( void* font, const unsigned char *string );
FGAPI void FGAPIENTRY glutStrokeString( void* font, const unsigned char *string );
/*
* Geometry functions, see fg_geometry.c
*/
FGAPI void FGAPIENTRY glutWireRhombicDodecahedron( void );
FGAPI void FGAPIENTRY glutSolidRhombicDodecahedron( void );
FGAPI void FGAPIENTRY glutWireSierpinskiSponge ( int num_levels, double offset[3], double scale );
FGAPI void FGAPIENTRY glutSolidSierpinskiSponge ( int num_levels, double offset[3], double scale );
FGAPI void FGAPIENTRY glutWireCylinder( double radius, double height, GLint slices, GLint stacks);
FGAPI void FGAPIENTRY glutSolidCylinder( double radius, double height, GLint slices, GLint stacks);
/*
* Rest of functions for rendering Newell's teaset, found in fg_teapot.c
* NB: front facing polygons have clockwise winding, not counter clockwise
*/
FGAPI void FGAPIENTRY glutWireTeacup( double size );
FGAPI void FGAPIENTRY glutSolidTeacup( double size );
FGAPI void FGAPIENTRY glutWireTeaspoon( double size );
FGAPI void FGAPIENTRY glutSolidTeaspoon( double size );
/*
* Extension functions, see fg_ext.c
*/
typedef void (*GLUTproc)();
FGAPI GLUTproc FGAPIENTRY glutGetProcAddress( const char *procName );
/*
* Multi-touch/multi-pointer extensions
*/
#define GLUT_HAS_MULTI 1
/* TODO: add device_id parameter,
cf. http://sourceforge.net/mailarchive/forum.php?thread_name=20120518071314.GA28061%40perso.beuc.net&forum_name=freeglut-developer */
FGAPI void FGAPIENTRY glutMultiEntryFunc( void (* callback)( int, int ) );
FGAPI void FGAPIENTRY glutMultiButtonFunc( void (* callback)( int, int, int, int, int ) );
FGAPI void FGAPIENTRY glutMultiMotionFunc( void (* callback)( int, int, int ) );
FGAPI void FGAPIENTRY glutMultiPassiveFunc( void (* callback)( int, int, int ) );
/*
* Joystick functions, see fg_joystick.c
*/
/* USE OF THESE FUNCTIONS IS DEPRECATED !!!!! */
/* If you have a serious need for these functions in your application, please either
* contact the "freeglut" developer community at freeglut-developer@lists.sourceforge.net,
* switch to the OpenGLUT library, or else port your joystick functionality over to PLIB's
* "js" library.
*/
int glutJoystickGetNumAxes( int ident );
int glutJoystickGetNumButtons( int ident );
int glutJoystickNotWorking( int ident );
float glutJoystickGetDeadBand( int ident, int axis );
void glutJoystickSetDeadBand( int ident, int axis, float db );
float glutJoystickGetSaturation( int ident, int axis );
void glutJoystickSetSaturation( int ident, int axis, float st );
void glutJoystickSetMinRange( int ident, float *axes );
void glutJoystickSetMaxRange( int ident, float *axes );
void glutJoystickSetCenter( int ident, float *axes );
void glutJoystickGetMinRange( int ident, float *axes );
void glutJoystickGetMaxRange( int ident, float *axes );
void glutJoystickGetCenter( int ident, float *axes );
/*
* Initialization functions, see fg_init.c
*/
/* to get the typedef for va_list */
#include <stdarg.h>
FGAPI void FGAPIENTRY glutInitContextVersion( int majorVersion, int minorVersion );
FGAPI void FGAPIENTRY glutInitContextFlags( int flags );
FGAPI void FGAPIENTRY glutInitContextProfile( int profile );
FGAPI void FGAPIENTRY glutInitErrorFunc( void (* callback)( const char *fmt, va_list ap ) );
FGAPI void FGAPIENTRY glutInitWarningFunc( void (* callback)( const char *fmt, va_list ap ) );
/* OpenGL >= 2.0 support */
FGAPI void FGAPIENTRY glutSetVertexAttribCoord3(GLint attrib);
FGAPI void FGAPIENTRY glutSetVertexAttribNormal(GLint attrib);
FGAPI void FGAPIENTRY glutSetVertexAttribTexCoord2(GLint attrib);
/* Mobile platforms lifecycle */
FGAPI void FGAPIENTRY glutInitContextFunc(void (* callback)());
FGAPI void FGAPIENTRY glutAppStatusFunc(void (* callback)(int));
/* state flags that can be passed to callback set by glutAppStatusFunc */
#define GLUT_APPSTATUS_PAUSE 0x0001
#define GLUT_APPSTATUS_RESUME 0x0002
/*
* GLUT API macro definitions -- the display mode definitions
*/
#define GLUT_CAPTIONLESS 0x0400
#define GLUT_BORDERLESS 0x0800
#define GLUT_SRGB 0x1000
#ifdef __cplusplus
}
#endif
/*** END OF FILE ***/
#endif /* __FREEGLUT_EXT_H__ */

View File

@ -0,0 +1,638 @@
#ifndef __FREEGLUT_STD_H__
#define __FREEGLUT_STD_H__
/*
* freeglut_std.h
*
* The GLUT-compatible part of the freeglut library include file
*
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
* Creation date: Thu Dec 2 1999
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
* Under windows, we have to differentiate between static and dynamic libraries
*/
#ifdef _WIN32
/* #pragma may not be supported by some compilers.
* Discussion by FreeGLUT developers suggests that
* Visual C++ specific code involving pragmas may
* need to move to a separate header. 24th Dec 2003
*/
/* Define FREEGLUT_LIB_PRAGMAS to 1 to include library
* pragmas or to 0 to exclude library pragmas.
* The default behavior depends on the compiler/platform.
*/
# ifndef FREEGLUT_LIB_PRAGMAS
# if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(_WIN32_WCE)
# define FREEGLUT_LIB_PRAGMAS 1
# else
# define FREEGLUT_LIB_PRAGMAS 0
# endif
# endif
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN 1
# endif
# ifndef NOMINMAX
# define NOMINMAX
# endif
# include <windows.h>
/* Windows static library */
# ifdef FREEGLUT_STATIC
#error Static linking is not supported with this build. Please remove the FREEGLUT_STATIC preprocessor directive, or download the source code from http://freeglut.sf.net/ and build against that.
/* Windows shared library (DLL) */
# else
# define FGAPIENTRY __stdcall
# if defined(FREEGLUT_EXPORTS)
# define FGAPI __declspec(dllexport)
# else
# define FGAPI __declspec(dllimport)
/* Link with Win32 shared freeglut lib */
# if FREEGLUT_LIB_PRAGMAS
# pragma comment (lib, "freeglut.lib")
# endif
# endif
# endif
/* Drag in other Windows libraries as required by FreeGLUT */
# if FREEGLUT_LIB_PRAGMAS
# pragma comment (lib, "glu32.lib") /* link OpenGL Utility lib */
# pragma comment (lib, "opengl32.lib") /* link Microsoft OpenGL lib */
# pragma comment (lib, "gdi32.lib") /* link Windows GDI lib */
# pragma comment (lib, "winmm.lib") /* link Windows MultiMedia lib */
# pragma comment (lib, "user32.lib") /* link Windows user lib */
# endif
#else
/* Non-Windows definition of FGAPI and FGAPIENTRY */
# define FGAPI
# define FGAPIENTRY
#endif
/*
* The freeglut and GLUT API versions
*/
#define FREEGLUT 1
#define GLUT_API_VERSION 4
#define GLUT_XLIB_IMPLEMENTATION 13
/* Deprecated:
cf. http://sourceforge.net/mailarchive/forum.php?thread_name=CABcAi1hw7cr4xtigckaGXB5X8wddLfMcbA_rZ3NAuwMrX_zmsw%40mail.gmail.com&forum_name=freeglut-developer */
#define FREEGLUT_VERSION_2_0 1
/*
* Always include OpenGL and GLU headers
*/
/* Note: FREEGLUT_GLES is only used to cleanly bootstrap headers
inclusion here; use GLES constants directly
(e.g. GL_ES_VERSION_2_0) for all other needs */
#ifdef FREEGLUT_GLES
# include <EGL/egl.h>
# include <GLES/gl.h>
# include <GLES2/gl2.h>
#elif __APPLE__
# include <OpenGL/gl.h>
# include <OpenGL/glu.h>
#else
# include <GL/gl.h>
# include <GL/glu.h>
#endif
/*
* GLUT API macro definitions -- the special key codes:
*/
#define GLUT_KEY_F1 0x0001
#define GLUT_KEY_F2 0x0002
#define GLUT_KEY_F3 0x0003
#define GLUT_KEY_F4 0x0004
#define GLUT_KEY_F5 0x0005
#define GLUT_KEY_F6 0x0006
#define GLUT_KEY_F7 0x0007
#define GLUT_KEY_F8 0x0008
#define GLUT_KEY_F9 0x0009
#define GLUT_KEY_F10 0x000A
#define GLUT_KEY_F11 0x000B
#define GLUT_KEY_F12 0x000C
#define GLUT_KEY_LEFT 0x0064
#define GLUT_KEY_UP 0x0065
#define GLUT_KEY_RIGHT 0x0066
#define GLUT_KEY_DOWN 0x0067
#define GLUT_KEY_PAGE_UP 0x0068
#define GLUT_KEY_PAGE_DOWN 0x0069
#define GLUT_KEY_HOME 0x006A
#define GLUT_KEY_END 0x006B
#define GLUT_KEY_INSERT 0x006C
/*
* GLUT API macro definitions -- mouse state definitions
*/
#define GLUT_LEFT_BUTTON 0x0000
#define GLUT_MIDDLE_BUTTON 0x0001
#define GLUT_RIGHT_BUTTON 0x0002
#define GLUT_DOWN 0x0000
#define GLUT_UP 0x0001
#define GLUT_LEFT 0x0000
#define GLUT_ENTERED 0x0001
/*
* GLUT API macro definitions -- the display mode definitions
*/
#define GLUT_RGB 0x0000
#define GLUT_RGBA 0x0000
#define GLUT_INDEX 0x0001
#define GLUT_SINGLE 0x0000
#define GLUT_DOUBLE 0x0002
#define GLUT_ACCUM 0x0004
#define GLUT_ALPHA 0x0008
#define GLUT_DEPTH 0x0010
#define GLUT_STENCIL 0x0020
#define GLUT_MULTISAMPLE 0x0080
#define GLUT_STEREO 0x0100
#define GLUT_LUMINANCE 0x0200
/*
* GLUT API macro definitions -- windows and menu related definitions
*/
#define GLUT_MENU_NOT_IN_USE 0x0000
#define GLUT_MENU_IN_USE 0x0001
#define GLUT_NOT_VISIBLE 0x0000
#define GLUT_VISIBLE 0x0001
#define GLUT_HIDDEN 0x0000
#define GLUT_FULLY_RETAINED 0x0001
#define GLUT_PARTIALLY_RETAINED 0x0002
#define GLUT_FULLY_COVERED 0x0003
/*
* GLUT API macro definitions -- fonts definitions
*
* Steve Baker suggested to make it binary compatible with GLUT:
*/
#if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__WATCOMC__)
# define GLUT_STROKE_ROMAN ((void *)0x0000)
# define GLUT_STROKE_MONO_ROMAN ((void *)0x0001)
# define GLUT_BITMAP_9_BY_15 ((void *)0x0002)
# define GLUT_BITMAP_8_BY_13 ((void *)0x0003)
# define GLUT_BITMAP_TIMES_ROMAN_10 ((void *)0x0004)
# define GLUT_BITMAP_TIMES_ROMAN_24 ((void *)0x0005)
# define GLUT_BITMAP_HELVETICA_10 ((void *)0x0006)
# define GLUT_BITMAP_HELVETICA_12 ((void *)0x0007)
# define GLUT_BITMAP_HELVETICA_18 ((void *)0x0008)
#else
/*
* I don't really know if it's a good idea... But here it goes:
*/
extern void* glutStrokeRoman;
extern void* glutStrokeMonoRoman;
extern void* glutBitmap9By15;
extern void* glutBitmap8By13;
extern void* glutBitmapTimesRoman10;
extern void* glutBitmapTimesRoman24;
extern void* glutBitmapHelvetica10;
extern void* glutBitmapHelvetica12;
extern void* glutBitmapHelvetica18;
/*
* Those pointers will be used by following definitions:
*/
# define GLUT_STROKE_ROMAN ((void *) &glutStrokeRoman)
# define GLUT_STROKE_MONO_ROMAN ((void *) &glutStrokeMonoRoman)
# define GLUT_BITMAP_9_BY_15 ((void *) &glutBitmap9By15)
# define GLUT_BITMAP_8_BY_13 ((void *) &glutBitmap8By13)
# define GLUT_BITMAP_TIMES_ROMAN_10 ((void *) &glutBitmapTimesRoman10)
# define GLUT_BITMAP_TIMES_ROMAN_24 ((void *) &glutBitmapTimesRoman24)
# define GLUT_BITMAP_HELVETICA_10 ((void *) &glutBitmapHelvetica10)
# define GLUT_BITMAP_HELVETICA_12 ((void *) &glutBitmapHelvetica12)
# define GLUT_BITMAP_HELVETICA_18 ((void *) &glutBitmapHelvetica18)
#endif
/*
* GLUT API macro definitions -- the glutGet parameters
*/
#define GLUT_WINDOW_X 0x0064
#define GLUT_WINDOW_Y 0x0065
#define GLUT_WINDOW_WIDTH 0x0066
#define GLUT_WINDOW_HEIGHT 0x0067
#define GLUT_WINDOW_BUFFER_SIZE 0x0068
#define GLUT_WINDOW_STENCIL_SIZE 0x0069
#define GLUT_WINDOW_DEPTH_SIZE 0x006A
#define GLUT_WINDOW_RED_SIZE 0x006B
#define GLUT_WINDOW_GREEN_SIZE 0x006C
#define GLUT_WINDOW_BLUE_SIZE 0x006D
#define GLUT_WINDOW_ALPHA_SIZE 0x006E
#define GLUT_WINDOW_ACCUM_RED_SIZE 0x006F
#define GLUT_WINDOW_ACCUM_GREEN_SIZE 0x0070
#define GLUT_WINDOW_ACCUM_BLUE_SIZE 0x0071
#define GLUT_WINDOW_ACCUM_ALPHA_SIZE 0x0072
#define GLUT_WINDOW_DOUBLEBUFFER 0x0073
#define GLUT_WINDOW_RGBA 0x0074
#define GLUT_WINDOW_PARENT 0x0075
#define GLUT_WINDOW_NUM_CHILDREN 0x0076
#define GLUT_WINDOW_COLORMAP_SIZE 0x0077
#define GLUT_WINDOW_NUM_SAMPLES 0x0078
#define GLUT_WINDOW_STEREO 0x0079
#define GLUT_WINDOW_CURSOR 0x007A
#define GLUT_SCREEN_WIDTH 0x00C8
#define GLUT_SCREEN_HEIGHT 0x00C9
#define GLUT_SCREEN_WIDTH_MM 0x00CA
#define GLUT_SCREEN_HEIGHT_MM 0x00CB
#define GLUT_MENU_NUM_ITEMS 0x012C
#define GLUT_DISPLAY_MODE_POSSIBLE 0x0190
#define GLUT_INIT_WINDOW_X 0x01F4
#define GLUT_INIT_WINDOW_Y 0x01F5
#define GLUT_INIT_WINDOW_WIDTH 0x01F6
#define GLUT_INIT_WINDOW_HEIGHT 0x01F7
#define GLUT_INIT_DISPLAY_MODE 0x01F8
#define GLUT_ELAPSED_TIME 0x02BC
#define GLUT_WINDOW_FORMAT_ID 0x007B
/*
* GLUT API macro definitions -- the glutDeviceGet parameters
*/
#define GLUT_HAS_KEYBOARD 0x0258
#define GLUT_HAS_MOUSE 0x0259
#define GLUT_HAS_SPACEBALL 0x025A
#define GLUT_HAS_DIAL_AND_BUTTON_BOX 0x025B
#define GLUT_HAS_TABLET 0x025C
#define GLUT_NUM_MOUSE_BUTTONS 0x025D
#define GLUT_NUM_SPACEBALL_BUTTONS 0x025E
#define GLUT_NUM_BUTTON_BOX_BUTTONS 0x025F
#define GLUT_NUM_DIALS 0x0260
#define GLUT_NUM_TABLET_BUTTONS 0x0261
#define GLUT_DEVICE_IGNORE_KEY_REPEAT 0x0262
#define GLUT_DEVICE_KEY_REPEAT 0x0263
#define GLUT_HAS_JOYSTICK 0x0264
#define GLUT_OWNS_JOYSTICK 0x0265
#define GLUT_JOYSTICK_BUTTONS 0x0266
#define GLUT_JOYSTICK_AXES 0x0267
#define GLUT_JOYSTICK_POLL_RATE 0x0268
/*
* GLUT API macro definitions -- the glutLayerGet parameters
*/
#define GLUT_OVERLAY_POSSIBLE 0x0320
#define GLUT_LAYER_IN_USE 0x0321
#define GLUT_HAS_OVERLAY 0x0322
#define GLUT_TRANSPARENT_INDEX 0x0323
#define GLUT_NORMAL_DAMAGED 0x0324
#define GLUT_OVERLAY_DAMAGED 0x0325
/*
* GLUT API macro definitions -- the glutVideoResizeGet parameters
*/
#define GLUT_VIDEO_RESIZE_POSSIBLE 0x0384
#define GLUT_VIDEO_RESIZE_IN_USE 0x0385
#define GLUT_VIDEO_RESIZE_X_DELTA 0x0386
#define GLUT_VIDEO_RESIZE_Y_DELTA 0x0387
#define GLUT_VIDEO_RESIZE_WIDTH_DELTA 0x0388
#define GLUT_VIDEO_RESIZE_HEIGHT_DELTA 0x0389
#define GLUT_VIDEO_RESIZE_X 0x038A
#define GLUT_VIDEO_RESIZE_Y 0x038B
#define GLUT_VIDEO_RESIZE_WIDTH 0x038C
#define GLUT_VIDEO_RESIZE_HEIGHT 0x038D
/*
* GLUT API macro definitions -- the glutUseLayer parameters
*/
#define GLUT_NORMAL 0x0000
#define GLUT_OVERLAY 0x0001
/*
* GLUT API macro definitions -- the glutGetModifiers parameters
*/
#define GLUT_ACTIVE_SHIFT 0x0001
#define GLUT_ACTIVE_CTRL 0x0002
#define GLUT_ACTIVE_ALT 0x0004
/*
* GLUT API macro definitions -- the glutSetCursor parameters
*/
#define GLUT_CURSOR_RIGHT_ARROW 0x0000
#define GLUT_CURSOR_LEFT_ARROW 0x0001
#define GLUT_CURSOR_INFO 0x0002
#define GLUT_CURSOR_DESTROY 0x0003
#define GLUT_CURSOR_HELP 0x0004
#define GLUT_CURSOR_CYCLE 0x0005
#define GLUT_CURSOR_SPRAY 0x0006
#define GLUT_CURSOR_WAIT 0x0007
#define GLUT_CURSOR_TEXT 0x0008
#define GLUT_CURSOR_CROSSHAIR 0x0009
#define GLUT_CURSOR_UP_DOWN 0x000A
#define GLUT_CURSOR_LEFT_RIGHT 0x000B
#define GLUT_CURSOR_TOP_SIDE 0x000C
#define GLUT_CURSOR_BOTTOM_SIDE 0x000D
#define GLUT_CURSOR_LEFT_SIDE 0x000E
#define GLUT_CURSOR_RIGHT_SIDE 0x000F
#define GLUT_CURSOR_TOP_LEFT_CORNER 0x0010
#define GLUT_CURSOR_TOP_RIGHT_CORNER 0x0011
#define GLUT_CURSOR_BOTTOM_RIGHT_CORNER 0x0012
#define GLUT_CURSOR_BOTTOM_LEFT_CORNER 0x0013
#define GLUT_CURSOR_INHERIT 0x0064
#define GLUT_CURSOR_NONE 0x0065
#define GLUT_CURSOR_FULL_CROSSHAIR 0x0066
/*
* GLUT API macro definitions -- RGB color component specification definitions
*/
#define GLUT_RED 0x0000
#define GLUT_GREEN 0x0001
#define GLUT_BLUE 0x0002
/*
* GLUT API macro definitions -- additional keyboard and joystick definitions
*/
#define GLUT_KEY_REPEAT_OFF 0x0000
#define GLUT_KEY_REPEAT_ON 0x0001
#define GLUT_KEY_REPEAT_DEFAULT 0x0002
#define GLUT_JOYSTICK_BUTTON_A 0x0001
#define GLUT_JOYSTICK_BUTTON_B 0x0002
#define GLUT_JOYSTICK_BUTTON_C 0x0004
#define GLUT_JOYSTICK_BUTTON_D 0x0008
/*
* GLUT API macro definitions -- game mode definitions
*/
#define GLUT_GAME_MODE_ACTIVE 0x0000
#define GLUT_GAME_MODE_POSSIBLE 0x0001
#define GLUT_GAME_MODE_WIDTH 0x0002
#define GLUT_GAME_MODE_HEIGHT 0x0003
#define GLUT_GAME_MODE_PIXEL_DEPTH 0x0004
#define GLUT_GAME_MODE_REFRESH_RATE 0x0005
#define GLUT_GAME_MODE_DISPLAY_CHANGED 0x0006
/*
* Initialization functions, see fglut_init.c
*/
FGAPI void FGAPIENTRY glutInit( int* pargc, char** argv );
FGAPI void FGAPIENTRY glutInitWindowPosition( int x, int y );
FGAPI void FGAPIENTRY glutInitWindowSize( int width, int height );
FGAPI void FGAPIENTRY glutInitDisplayMode( unsigned int displayMode );
FGAPI void FGAPIENTRY glutInitDisplayString( const char* displayMode );
/*
* Process loop function, see fg_main.c
*/
FGAPI void FGAPIENTRY glutMainLoop( void );
/*
* Window management functions, see fg_window.c
*/
FGAPI int FGAPIENTRY glutCreateWindow( const char* title );
FGAPI int FGAPIENTRY glutCreateSubWindow( int window, int x, int y, int width, int height );
FGAPI void FGAPIENTRY glutDestroyWindow( int window );
FGAPI void FGAPIENTRY glutSetWindow( int window );
FGAPI int FGAPIENTRY glutGetWindow( void );
FGAPI void FGAPIENTRY glutSetWindowTitle( const char* title );
FGAPI void FGAPIENTRY glutSetIconTitle( const char* title );
FGAPI void FGAPIENTRY glutReshapeWindow( int width, int height );
FGAPI void FGAPIENTRY glutPositionWindow( int x, int y );
FGAPI void FGAPIENTRY glutShowWindow( void );
FGAPI void FGAPIENTRY glutHideWindow( void );
FGAPI void FGAPIENTRY glutIconifyWindow( void );
FGAPI void FGAPIENTRY glutPushWindow( void );
FGAPI void FGAPIENTRY glutPopWindow( void );
FGAPI void FGAPIENTRY glutFullScreen( void );
/*
* Display-related functions, see fg_display.c
*/
FGAPI void FGAPIENTRY glutPostWindowRedisplay( int window );
FGAPI void FGAPIENTRY glutPostRedisplay( void );
FGAPI void FGAPIENTRY glutSwapBuffers( void );
/*
* Mouse cursor functions, see fg_cursor.c
*/
FGAPI void FGAPIENTRY glutWarpPointer( int x, int y );
FGAPI void FGAPIENTRY glutSetCursor( int cursor );
/*
* Overlay stuff, see fg_overlay.c
*/
FGAPI void FGAPIENTRY glutEstablishOverlay( void );
FGAPI void FGAPIENTRY glutRemoveOverlay( void );
FGAPI void FGAPIENTRY glutUseLayer( GLenum layer );
FGAPI void FGAPIENTRY glutPostOverlayRedisplay( void );
FGAPI void FGAPIENTRY glutPostWindowOverlayRedisplay( int window );
FGAPI void FGAPIENTRY glutShowOverlay( void );
FGAPI void FGAPIENTRY glutHideOverlay( void );
/*
* Menu stuff, see fg_menu.c
*/
FGAPI int FGAPIENTRY glutCreateMenu( void (* callback)( int menu ) );
FGAPI void FGAPIENTRY glutDestroyMenu( int menu );
FGAPI int FGAPIENTRY glutGetMenu( void );
FGAPI void FGAPIENTRY glutSetMenu( int menu );
FGAPI void FGAPIENTRY glutAddMenuEntry( const char* label, int value );
FGAPI void FGAPIENTRY glutAddSubMenu( const char* label, int subMenu );
FGAPI void FGAPIENTRY glutChangeToMenuEntry( int item, const char* label, int value );
FGAPI void FGAPIENTRY glutChangeToSubMenu( int item, const char* label, int value );
FGAPI void FGAPIENTRY glutRemoveMenuItem( int item );
FGAPI void FGAPIENTRY glutAttachMenu( int button );
FGAPI void FGAPIENTRY glutDetachMenu( int button );
/*
* Global callback functions, see fg_callbacks.c
*/
FGAPI void FGAPIENTRY glutTimerFunc( unsigned int time, void (* callback)( int ), int value );
FGAPI void FGAPIENTRY glutIdleFunc( void (* callback)( void ) );
/*
* Window-specific callback functions, see fg_callbacks.c
*/
FGAPI void FGAPIENTRY glutKeyboardFunc( void (* callback)( unsigned char, int, int ) );
FGAPI void FGAPIENTRY glutSpecialFunc( void (* callback)( int, int, int ) );
FGAPI void FGAPIENTRY glutReshapeFunc( void (* callback)( int, int ) );
FGAPI void FGAPIENTRY glutVisibilityFunc( void (* callback)( int ) );
FGAPI void FGAPIENTRY glutDisplayFunc( void (* callback)( void ) );
FGAPI void FGAPIENTRY glutMouseFunc( void (* callback)( int, int, int, int ) );
FGAPI void FGAPIENTRY glutMotionFunc( void (* callback)( int, int ) );
FGAPI void FGAPIENTRY glutPassiveMotionFunc( void (* callback)( int, int ) );
FGAPI void FGAPIENTRY glutEntryFunc( void (* callback)( int ) );
FGAPI void FGAPIENTRY glutKeyboardUpFunc( void (* callback)( unsigned char, int, int ) );
FGAPI void FGAPIENTRY glutSpecialUpFunc( void (* callback)( int, int, int ) );
FGAPI void FGAPIENTRY glutJoystickFunc( void (* callback)( unsigned int, int, int, int ), int pollInterval );
FGAPI void FGAPIENTRY glutMenuStateFunc( void (* callback)( int ) );
FGAPI void FGAPIENTRY glutMenuStatusFunc( void (* callback)( int, int, int ) );
FGAPI void FGAPIENTRY glutOverlayDisplayFunc( void (* callback)( void ) );
FGAPI void FGAPIENTRY glutWindowStatusFunc( void (* callback)( int ) );
FGAPI void FGAPIENTRY glutSpaceballMotionFunc( void (* callback)( int, int, int ) );
FGAPI void FGAPIENTRY glutSpaceballRotateFunc( void (* callback)( int, int, int ) );
FGAPI void FGAPIENTRY glutSpaceballButtonFunc( void (* callback)( int, int ) );
FGAPI void FGAPIENTRY glutButtonBoxFunc( void (* callback)( int, int ) );
FGAPI void FGAPIENTRY glutDialsFunc( void (* callback)( int, int ) );
FGAPI void FGAPIENTRY glutTabletMotionFunc( void (* callback)( int, int ) );
FGAPI void FGAPIENTRY glutTabletButtonFunc( void (* callback)( int, int, int, int ) );
/*
* State setting and retrieval functions, see fg_state.c
*/
FGAPI int FGAPIENTRY glutGet( GLenum query );
FGAPI int FGAPIENTRY glutDeviceGet( GLenum query );
FGAPI int FGAPIENTRY glutGetModifiers( void );
FGAPI int FGAPIENTRY glutLayerGet( GLenum query );
/*
* Font stuff, see fg_font.c
*/
FGAPI void FGAPIENTRY glutBitmapCharacter( void* font, int character );
FGAPI int FGAPIENTRY glutBitmapWidth( void* font, int character );
FGAPI void FGAPIENTRY glutStrokeCharacter( void* font, int character );
FGAPI int FGAPIENTRY glutStrokeWidth( void* font, int character );
FGAPI GLfloat FGAPIENTRY glutStrokeWidthf( void* font, int character ); /* GLUT 3.8 */
FGAPI int FGAPIENTRY glutBitmapLength( void* font, const unsigned char* string );
FGAPI int FGAPIENTRY glutStrokeLength( void* font, const unsigned char* string );
FGAPI GLfloat FGAPIENTRY glutStrokeLengthf( void* font, const unsigned char *string ); /* GLUT 3.8 */
/*
* Geometry functions, see fg_geometry.c
*/
FGAPI void FGAPIENTRY glutWireCube( double size );
FGAPI void FGAPIENTRY glutSolidCube( double size );
FGAPI void FGAPIENTRY glutWireSphere( double radius, GLint slices, GLint stacks );
FGAPI void FGAPIENTRY glutSolidSphere( double radius, GLint slices, GLint stacks );
FGAPI void FGAPIENTRY glutWireCone( double base, double height, GLint slices, GLint stacks );
FGAPI void FGAPIENTRY glutSolidCone( double base, double height, GLint slices, GLint stacks );
FGAPI void FGAPIENTRY glutWireTorus( double innerRadius, double outerRadius, GLint sides, GLint rings );
FGAPI void FGAPIENTRY glutSolidTorus( double innerRadius, double outerRadius, GLint sides, GLint rings );
FGAPI void FGAPIENTRY glutWireDodecahedron( void );
FGAPI void FGAPIENTRY glutSolidDodecahedron( void );
FGAPI void FGAPIENTRY glutWireOctahedron( void );
FGAPI void FGAPIENTRY glutSolidOctahedron( void );
FGAPI void FGAPIENTRY glutWireTetrahedron( void );
FGAPI void FGAPIENTRY glutSolidTetrahedron( void );
FGAPI void FGAPIENTRY glutWireIcosahedron( void );
FGAPI void FGAPIENTRY glutSolidIcosahedron( void );
/*
* Teapot rendering functions, found in fg_teapot.c
* NB: front facing polygons have clockwise winding, not counter clockwise
*/
FGAPI void FGAPIENTRY glutWireTeapot( double size );
FGAPI void FGAPIENTRY glutSolidTeapot( double size );
/*
* Game mode functions, see fg_gamemode.c
*/
FGAPI void FGAPIENTRY glutGameModeString( const char* string );
FGAPI int FGAPIENTRY glutEnterGameMode( void );
FGAPI void FGAPIENTRY glutLeaveGameMode( void );
FGAPI int FGAPIENTRY glutGameModeGet( GLenum query );
/*
* Video resize functions, see fg_videoresize.c
*/
FGAPI int FGAPIENTRY glutVideoResizeGet( GLenum query );
FGAPI void FGAPIENTRY glutSetupVideoResizing( void );
FGAPI void FGAPIENTRY glutStopVideoResizing( void );
FGAPI void FGAPIENTRY glutVideoResize( int x, int y, int width, int height );
FGAPI void FGAPIENTRY glutVideoPan( int x, int y, int width, int height );
/*
* Colormap functions, see fg_misc.c
*/
FGAPI void FGAPIENTRY glutSetColor( int color, GLfloat red, GLfloat green, GLfloat blue );
FGAPI GLfloat FGAPIENTRY glutGetColor( int color, int component );
FGAPI void FGAPIENTRY glutCopyColormap( int window );
/*
* Misc keyboard and joystick functions, see fg_misc.c
*/
FGAPI void FGAPIENTRY glutIgnoreKeyRepeat( int ignore );
FGAPI void FGAPIENTRY glutSetKeyRepeat( int repeatMode );
FGAPI void FGAPIENTRY glutForceJoystickFunc( void );
/*
* Misc functions, see fg_misc.c
*/
FGAPI int FGAPIENTRY glutExtensionSupported( const char* extension );
FGAPI void FGAPIENTRY glutReportErrors( void );
/* Comment from glut.h of classic GLUT:
Win32 has an annoying issue where there are multiple C run-time
libraries (CRTs). If the executable is linked with a different CRT
from the GLUT DLL, the GLUT DLL will not share the same CRT static
data seen by the executable. In particular, atexit callbacks registered
in the executable will not be called if GLUT calls its (different)
exit routine). GLUT is typically built with the
"/MD" option (the CRT with multithreading DLL support), but the Visual
C++ linker default is "/ML" (the single threaded CRT).
One workaround to this issue is requiring users to always link with
the same CRT as GLUT is compiled with. That requires users supply a
non-standard option. GLUT 3.7 has its own built-in workaround where
the executable's "exit" function pointer is covertly passed to GLUT.
GLUT then calls the executable's exit function pointer to ensure that
any "atexit" calls registered by the application are called if GLUT
needs to exit.
Note that the __glut*WithExit routines should NEVER be called directly.
To avoid the atexit workaround, #define GLUT_DISABLE_ATEXIT_HACK. */
/* to get the prototype for exit() */
#include <stdlib.h>
#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) && !defined(__WATCOMC__)
FGAPI void FGAPIENTRY __glutInitWithExit(int *argcp, char **argv, void (__cdecl *exitfunc)(int));
FGAPI int FGAPIENTRY __glutCreateWindowWithExit(const char *title, void (__cdecl *exitfunc)(int));
FGAPI int FGAPIENTRY __glutCreateMenuWithExit(void (* func)(int), void (__cdecl *exitfunc)(int));
#ifndef FREEGLUT_BUILDING_LIB
#if defined(__GNUC__)
#define FGUNUSED __attribute__((unused))
#else
#define FGUNUSED
#endif
static void FGAPIENTRY FGUNUSED glutInit_ATEXIT_HACK(int *argcp, char **argv) { __glutInitWithExit(argcp, argv, exit); }
#define glutInit glutInit_ATEXIT_HACK
static int FGAPIENTRY FGUNUSED glutCreateWindow_ATEXIT_HACK(const char *title) { return __glutCreateWindowWithExit(title, exit); }
#define glutCreateWindow glutCreateWindow_ATEXIT_HACK
static int FGAPIENTRY FGUNUSED glutCreateMenu_ATEXIT_HACK(void (* func)(int)) { return __glutCreateMenuWithExit(func, exit); }
#define glutCreateMenu glutCreateMenu_ATEXIT_HACK
#endif
#endif
#ifdef __cplusplus
}
#endif
/*** END OF FILE ***/
#endif /* __FREEGLUT_STD_H__ */

View File

@ -0,0 +1,21 @@
#ifndef __GLUT_H__
#define __GLUT_H__
/*
* glut.h
*
* The freeglut library include file
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "freeglut_std.h"
/*** END OF FILE ***/
#endif /* __GLUT_H__ */

View File

@ -20,6 +20,9 @@
#pragma once
#include "imgui.h" // IMGUI_IMPL_API
#ifdef __cplusplus
extern "C" {
#endif
IMGUI_IMPL_API bool ImGui_ImplGLUT_Init();
IMGUI_IMPL_API void ImGui_ImplGLUT_InstallFuncs();
@ -37,3 +40,7 @@ IMGUI_IMPL_API void ImGui_ImplGLUT_KeyboardFunc(unsigned char c, int x, int
IMGUI_IMPL_API void ImGui_ImplGLUT_KeyboardUpFunc(unsigned char c, int x, int y); // ~ CharReleasedFunc
IMGUI_IMPL_API void ImGui_ImplGLUT_SpecialFunc(int key, int x, int y); // ~ KeyPressedFunc
IMGUI_IMPL_API void ImGui_ImplGLUT_SpecialUpFunc(int key, int x, int y); // ~ KeyReleasedFunc
#ifdef __cplusplus
}
#endif

View File

@ -5,7 +5,7 @@
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Read online: https://github.com/ocornut/imgui/tree/master/docs
@ -21,6 +21,10 @@
#pragma once
#include "imgui.h" // IMGUI_IMPL_API
#ifdef __cplusplus
extern "C" {
#endif
IMGUI_IMPL_API bool ImGui_ImplOpenGL2_Init();
IMGUI_IMPL_API void ImGui_ImplOpenGL2_Shutdown();
IMGUI_IMPL_API void ImGui_ImplOpenGL2_NewFrame();
@ -31,3 +35,7 @@ IMGUI_IMPL_API bool ImGui_ImplOpenGL2_CreateFontsTexture();
IMGUI_IMPL_API void ImGui_ImplOpenGL2_DestroyFontsTexture();
IMGUI_IMPL_API bool ImGui_ImplOpenGL2_CreateDeviceObjects();
IMGUI_IMPL_API void ImGui_ImplOpenGL2_DestroyDeviceObjects();
#ifdef __cplusplus
}
#endif

View File

@ -21,6 +21,10 @@
#pragma once
#include "imgui.h" // IMGUI_IMPL_API
#ifdef __cplusplus
extern "C" {
#endif
// Backend API
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_Init(const char* glsl_version = nullptr);
IMGUI_IMPL_API void ImGui_ImplOpenGL3_Shutdown();
@ -54,3 +58,7 @@ IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects();
#endif
#endif
#ifdef __cplusplus
}
#endif

View File

@ -54,7 +54,7 @@ imgui = static_library('imgui',
dependency('vulkan', required: get_option('vulkan')),
dependency('glfw3', required: get_option('glfw')),
dependency('sdl', required: get_option('sdl')),
dependency('glut', required: get_option('glut')),
# dependency('glut', required: get_option('glut')),
],
include_directories: include_dirs,
)