From dd4f7f97a5a843aab2e9a335165a88dd76f68420 Mon Sep 17 00:00:00 2001 From: Bottersnike Date: Tue, 14 Feb 2023 07:09:08 +0000 Subject: [PATCH] Huge UI overhaul and OpenGL support --- lib/freeglut.lib | Bin 0 -> 39732 bytes meson.build | 4 + src/meson.build | 7 +- src/micetools/dll/devices/ser_led_bd.c | 5 +- src/micetools/dll/devices/smb_at24c64an.c | 77 +- src/micetools/dll/devices/smb_at24c64an.h | 2 + src/micetools/dll/devices/smb_pca9535.c | 157 ++- src/micetools/dll/devices/smb_pca9535.h | 23 +- src/micetools/dll/dllmain.c | 14 +- src/micetools/dll/drivers/mxjvs.c | 539 ++++++----- src/micetools/dll/gui/gui.c | 903 ++++++++++++++++-- src/micetools/dll/hooks/drive/disks.c | 29 +- src/micetools/dll/hooks/drive/drive.c | 53 +- src/micetools/dll/hooks/drive/drive.h | 4 + src/micetools/dll/hooks/files.c | 11 +- src/micetools/dll/hooks/gui.c | 163 +++- src/micetools/dll/hooks/gui.h | 11 +- src/micetools/dll/hooks/logging.c | 8 +- src/micetools/dll/hooks/network.c | 11 +- src/micetools/dll/hooks/network.h | 1 + src/micetools/dll/hooks/processes.c | 8 +- src/micetools/dll/hooks/system.c | 33 +- src/micetools/dll/hooks/system.h | 3 + src/micetools/dll/hooks/time.c | 22 + src/micetools/dll/key_config.h | 17 + src/micetools/dll/meson.build | 4 +- src/micetools/dll/smbus.h | 10 - src/micetools/dll/util/_util.h | 3 + src/micetools/dll/util/hook.c | 16 + src/micetools/dll/util/log.c | 73 +- src/micetools/dll/util/misc.c | 4 + src/micetools/dll/util/path.c | 23 + src/micetools/lib/mice/config.c | 73 +- src/micetools/lib/mice/config.def | 3 + src/micetools/lib/mice/config.h | 4 + src/micetools/micekeychip/main.c | 10 +- src/micetools/micekeychip/meson.build | 28 +- src/micetools/micemaster/config.c | 4 +- .../cimgui_dep/imgui/backends/GL/freeglut.h | 22 + .../imgui/backends/GL/freeglut_ext.h | 271 ++++++ .../imgui/backends/GL/freeglut_std.h | 638 +++++++++++++ .../cimgui_dep/imgui/backends/GL/glut.h | 21 + .../imgui/backends/imgui_impl_glut.h | 7 + .../imgui/backends/imgui_impl_opengl2.h | 10 +- .../imgui/backends/imgui_impl_opengl3.h | 8 + subprojects/cimgui_dep/imgui/meson.build | 2 +- 46 files changed, 2768 insertions(+), 571 deletions(-) create mode 100644 lib/freeglut.lib create mode 100644 src/micetools/dll/key_config.h create mode 100644 src/micetools/dll/util/path.c create mode 100644 subprojects/cimgui_dep/imgui/backends/GL/freeglut.h create mode 100644 subprojects/cimgui_dep/imgui/backends/GL/freeglut_ext.h create mode 100644 subprojects/cimgui_dep/imgui/backends/GL/freeglut_std.h create mode 100644 subprojects/cimgui_dep/imgui/backends/GL/glut.h diff --git a/lib/freeglut.lib b/lib/freeglut.lib new file mode 100644 index 0000000000000000000000000000000000000000..498a5760c4bfda3a74a2830296c07a82917cef84 GIT binary patch literal 39732 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 ST=&adKE<~Lr`P$i=>Gur>iJy& literal 0 HcmV?d00001 diff --git a/meson.build b/meson.build index eddceee..06c7531 100644 --- a/meson.build +++ b/meson.build @@ -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', diff --git a/src/meson.build b/src/meson.build index baad635..7b62cea 100644 --- a/src/meson.build +++ b/src/meson.build @@ -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() diff --git a/src/micetools/dll/devices/ser_led_bd.c b/src/micetools/dll/devices/ser_led_bd.c index 3848798..d065246 100644 --- a/src/micetools/dll/devices/ser_led_bd.c +++ b/src/micetools/dll/devices/ser_led_bd.c @@ -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; diff --git a/src/micetools/dll/devices/smb_at24c64an.c b/src/micetools/dll/devices/smb_at24c64an.c index fb17c8d..2961629 100644 --- a/src/micetools/dll/devices/smb_at24c64an.c +++ b/src/micetools/dll/devices/smb_at24c64an.c @@ -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; diff --git a/src/micetools/dll/devices/smb_at24c64an.h b/src/micetools/dll/devices/smb_at24c64an.h index c3c34ab..0812246 100644 --- a/src/micetools/dll/devices/smb_at24c64an.h +++ b/src/micetools/dll/devices/smb_at24c64an.h @@ -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); diff --git a/src/micetools/dll/devices/smb_pca9535.c b/src/micetools/dll/devices/smb_pca9535.c index 828d980..773f856 100644 --- a/src/micetools/dll/devices/smb_pca9535.c +++ b/src/micetools/dll/devices/smb_pca9535.c @@ -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; diff --git a/src/micetools/dll/devices/smb_pca9535.h b/src/micetools/dll/devices/smb_pca9535.h index f0996f9..6158423 100644 --- a/src/micetools/dll/devices/smb_pca9535.h +++ b/src/micetools/dll/devices/smb_pca9535.h @@ -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 diff --git a/src/micetools/dll/dllmain.c b/src/micetools/dll/dllmain.c index 1215040..ca7aad1 100644 --- a/src/micetools/dll/dllmain.c +++ b/src/micetools/dll/dllmain.c @@ -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; } diff --git a/src/micetools/dll/drivers/mxjvs.c b/src/micetools/dll/drivers/mxjvs.c index 943aa84..5565478 100644 --- a/src/micetools/dll/drivers/mxjvs.c +++ b/src/micetools/dll/drivers/mxjvs.c @@ -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); } diff --git a/src/micetools/dll/gui/gui.c b/src/micetools/dll/gui/gui.c index 1976857..91ec5dd 100644 --- a/src/micetools/dll/gui/gui.c +++ b/src/micetools/dll/gui/gui.c @@ -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); } diff --git a/src/micetools/dll/hooks/drive/disks.c b/src/micetools/dll/hooks/drive/disks.c index 5067c3d..9d6ed85 100644 --- a/src/micetools/dll/hooks/drive/disks.c +++ b/src/micetools/dll/hooks/drive/disks.c @@ -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, }; diff --git a/src/micetools/dll/hooks/drive/drive.c b/src/micetools/dll/hooks/drive/drive.c index e1d4b76..2cefce3 100644 --- a/src/micetools/dll/hooks/drive/drive.c +++ b/src/micetools/dll/hooks/drive/drive.c @@ -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()); diff --git a/src/micetools/dll/hooks/drive/drive.h b/src/micetools/dll/hooks/drive/drive.h index ece2d52..0e6518c 100644 --- a/src/micetools/dll/hooks/drive/drive.h +++ b/src/micetools/dll/hooks/drive/drive.h @@ -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; diff --git a/src/micetools/dll/hooks/files.c b/src/micetools/dll/hooks/files.c index 0b44326..a032d6f 100644 --- a/src/micetools/dll/hooks/files.c +++ b/src/micetools/dll/hooks/files.c @@ -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)) { diff --git a/src/micetools/dll/hooks/gui.c b/src/micetools/dll/hooks/gui.c index 25ed954..c226940 100644 --- a/src/micetools/dll/hooks/gui.c +++ b/src/micetools/dll/hooks/gui.c @@ -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); } diff --git a/src/micetools/dll/hooks/gui.h b/src/micetools/dll/hooks/gui.h index e2be0f8..29a0dfd 100644 --- a/src/micetools/dll/hooks/gui.h +++ b/src/micetools/dll/hooks/gui.h @@ -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(); diff --git a/src/micetools/dll/hooks/logging.c b/src/micetools/dll/hooks/logging.c index a007e16..6337ebc 100644 --- a/src/micetools/dll/hooks/logging.c +++ b/src/micetools/dll/hooks/logging.c @@ -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); diff --git a/src/micetools/dll/hooks/network.c b/src/micetools/dll/hooks/network.c index ee690fc..64311bf 100644 --- a/src/micetools/dll/hooks/network.c +++ b/src/micetools/dll/hooks/network.c @@ -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); diff --git a/src/micetools/dll/hooks/network.h b/src/micetools/dll/hooks/network.h index 01bcf1e..f13ce00 100644 --- a/src/micetools/dll/hooks/network.h +++ b/src/micetools/dll/hooks/network.h @@ -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); diff --git a/src/micetools/dll/hooks/processes.c b/src/micetools/dll/hooks/processes.c index 97982f4..9931d3f 100644 --- a/src/micetools/dll/hooks/processes.c +++ b/src/micetools/dll/hooks/processes.c @@ -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); } diff --git a/src/micetools/dll/hooks/system.c b/src/micetools/dll/hooks/system.c index 4ba7a8b..17bf4d1 100644 --- a/src/micetools/dll/hooks/system.c +++ b/src/micetools/dll/hooks/system.c @@ -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); diff --git a/src/micetools/dll/hooks/system.h b/src/micetools/dll/hooks/system.h index bed2465..930088d 100644 --- a/src/micetools/dll/hooks/system.h +++ b/src/micetools/dll/hooks/system.h @@ -2,4 +2,7 @@ #include "../common.h" +FARPROC (*TrueGetProcAddress)(HMODULE hModule, LPCSTR lpProcName); +HMODULE (*TrueGetModuleHandleA)(LPCSTR lpModuleName); + void hook_system(); diff --git a/src/micetools/dll/hooks/time.c b/src/micetools/dll/hooks/time.c index 6060772..3baf2f2 100644 --- a/src/micetools/dll/hooks/time.c +++ b/src/micetools/dll/hooks/time.c @@ -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() { diff --git a/src/micetools/dll/key_config.h b/src/micetools/dll/key_config.h new file mode 100644 index 0000000..15b3e31 --- /dev/null +++ b/src/micetools/dll/key_config.h @@ -0,0 +1,17 @@ +#pragma once + +#include + +#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; diff --git a/src/micetools/dll/meson.build b/src/micetools/dll/meson.build index 7a8d8eb..52af9c2 100644 --- a/src/micetools/dll/meson.build +++ b/src/micetools/dll/meson.build @@ -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] ) diff --git a/src/micetools/dll/smbus.h b/src/micetools/dll/smbus.h index d780208..c288cbc 100644 --- a/src/micetools/dll/smbus.h +++ b/src/micetools/dll/smbus.h @@ -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 diff --git a/src/micetools/dll/util/_util.h b/src/micetools/dll/util/_util.h index 25541dc..f1eeef0 100644 --- a/src/micetools/dll/util/_util.h +++ b/src/micetools/dll/util/_util.h @@ -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); diff --git a/src/micetools/dll/util/hook.c b/src/micetools/dll/util/hook.c index c756334..6cd242f 100644 --- a/src/micetools/dll/util/hook.c +++ b/src/micetools/dll/util/hook.c @@ -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, diff --git a/src/micetools/dll/util/log.c b/src/micetools/dll/util/log.c index 13c3f7b..7fd0e00 100644 --- a/src/micetools/dll/util/log.c +++ b/src/micetools/dll/util/log.c @@ -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); diff --git a/src/micetools/dll/util/misc.c b/src/micetools/dll/util/misc.c index f1b9870..c2e513a 100644 --- a/src/micetools/dll/util/misc.c +++ b/src/micetools/dll/util/misc.c @@ -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; diff --git a/src/micetools/dll/util/path.c b/src/micetools/dll/util/path.c new file mode 100644 index 0000000..fffcf3a --- /dev/null +++ b/src/micetools/dll/util/path.c @@ -0,0 +1,23 @@ +#include +#include +#include +#include + +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; +} diff --git a/src/micetools/lib/mice/config.c b/src/micetools/lib/mice/config.c index d6db19e..997d40f 100644 --- a/src/micetools/lib/mice/config.c +++ b/src/micetools/lib/mice/config.c @@ -5,6 +5,7 @@ #include #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; + } } diff --git a/src/micetools/lib/mice/config.def b/src/micetools/lib/mice/config.def index 60abfda..3dabbd9 100644 --- a/src/micetools/lib/mice/config.def +++ b/src/micetools/lib/mice/config.def @@ -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) diff --git a/src/micetools/lib/mice/config.h b/src/micetools/lib/mice/config.h index 6d58d7c..b4b69a3 100644 --- a/src/micetools/lib/mice/config.h +++ b/src/micetools/lib/mice/config.h @@ -1,3 +1,6 @@ +#pragma once + +#include #include #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(); diff --git a/src/micetools/micekeychip/main.c b/src/micetools/micekeychip/main.c index b2ffb25..87558a0 100644 --- a/src/micetools/micekeychip/main.c +++ b/src/micetools/micekeychip/main.c @@ -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(); +} diff --git a/src/micetools/micekeychip/meson.build b/src/micetools/micekeychip/meson.build index b0e7bf8..dcb2e67 100644 --- a/src/micetools/micekeychip/meson.build +++ b/src/micetools/micekeychip/meson.build @@ -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, ) diff --git a/src/micetools/micemaster/config.c b/src/micetools/micemaster/config.c index ed54706..8704c6f 100644 --- a/src/micetools/micemaster/config.c +++ b/src/micetools/micemaster/config.c @@ -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; diff --git a/subprojects/cimgui_dep/imgui/backends/GL/freeglut.h b/subprojects/cimgui_dep/imgui/backends/GL/freeglut.h new file mode 100644 index 0000000..0e6f8c6 --- /dev/null +++ b/subprojects/cimgui_dep/imgui/backends/GL/freeglut.h @@ -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__ */ diff --git a/subprojects/cimgui_dep/imgui/backends/GL/freeglut_ext.h b/subprojects/cimgui_dep/imgui/backends/GL/freeglut_ext.h new file mode 100644 index 0000000..0c22c4f --- /dev/null +++ b/subprojects/cimgui_dep/imgui/backends/GL/freeglut_ext.h @@ -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, + * 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 +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__ */ diff --git a/subprojects/cimgui_dep/imgui/backends/GL/freeglut_std.h b/subprojects/cimgui_dep/imgui/backends/GL/freeglut_std.h new file mode 100644 index 0000000..55539e5 --- /dev/null +++ b/subprojects/cimgui_dep/imgui/backends/GL/freeglut_std.h @@ -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, + * 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 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 +# include +# include +#elif __APPLE__ +# include +# include +#else +# include +# include +#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 + +#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__ */ diff --git a/subprojects/cimgui_dep/imgui/backends/GL/glut.h b/subprojects/cimgui_dep/imgui/backends/GL/glut.h new file mode 100644 index 0000000..6191f77 --- /dev/null +++ b/subprojects/cimgui_dep/imgui/backends/GL/glut.h @@ -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__ */ diff --git a/subprojects/cimgui_dep/imgui/backends/imgui_impl_glut.h b/subprojects/cimgui_dep/imgui/backends/imgui_impl_glut.h index 98d4e59..b85c7ff 100644 --- a/subprojects/cimgui_dep/imgui/backends/imgui_impl_glut.h +++ b/subprojects/cimgui_dep/imgui/backends/imgui_impl_glut.h @@ -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 diff --git a/subprojects/cimgui_dep/imgui/backends/imgui_impl_opengl2.h b/subprojects/cimgui_dep/imgui/backends/imgui_impl_opengl2.h index 91b3b1d..e103c27 100644 --- a/subprojects/cimgui_dep/imgui/backends/imgui_impl_opengl2.h +++ b/subprojects/cimgui_dep/imgui/backends/imgui_impl_opengl2.h @@ -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 diff --git a/subprojects/cimgui_dep/imgui/backends/imgui_impl_opengl3.h b/subprojects/cimgui_dep/imgui/backends/imgui_impl_opengl3.h index e00a88c..2c9b1d9 100644 --- a/subprojects/cimgui_dep/imgui/backends/imgui_impl_opengl3.h +++ b/subprojects/cimgui_dep/imgui/backends/imgui_impl_opengl3.h @@ -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 diff --git a/subprojects/cimgui_dep/imgui/meson.build b/subprojects/cimgui_dep/imgui/meson.build index 10057f9..9696ba9 100644 --- a/subprojects/cimgui_dep/imgui/meson.build +++ b/subprojects/cimgui_dep/imgui/meson.build @@ -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, )