Initial Commit
This commit is contained in:
commit
e746464108
6
.clang-format
Normal file
6
.clang-format
Normal file
@ -0,0 +1,6 @@
|
||||
BasedOnStyle: GNU
|
||||
IndentWidth: 4
|
||||
TabWidth: 4
|
||||
UseTab: Always
|
||||
IndentCaseLabels: False
|
||||
BreakBeforeBraces: Attach
|
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
x86_64-pc-windows
|
||||
*.o
|
||||
*.dll
|
||||
original.cpp
|
9
.gitmodules
vendored
Normal file
9
.gitmodules
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
[submodule "minhook"]
|
||||
path = minhook
|
||||
url = https://github.com/TsudaKageyu/minhook
|
||||
[submodule "SDL"]
|
||||
path = SDL
|
||||
url = https://github.com/libsdl-org/SDL
|
||||
[submodule "tomlc99"]
|
||||
path = tomlc99
|
||||
url = https://github.com/cktan/tomlc99
|
47
Makefile
Normal file
47
Makefile
Normal file
@ -0,0 +1,47 @@
|
||||
OUT = TAL
|
||||
CC := clang
|
||||
TARGET := x86_64-pc-windows-gnu
|
||||
SDL_TARGET := x86_64-w64-mingw32
|
||||
SRC = src/dllmain.c src/helpers.c src/poll.c tomlc99/toml.c minhook/src/buffer.c minhook/src/hook.c minhook/src/trampoline.c minhook/src/hde/hde32.c minhook/src/hde/hde64.c
|
||||
OBJ = ${addprefix ${TARGET}/,${SRC:.c=.o}}
|
||||
CFLAGS = -std=c99 -Iminhook/include -ISDL/${SDL_TARGET}/include -ISDL/include -Itomlc99 -Wall -Ofast -target ${TARGET} -DWIN32_LEAN_AND_MEAN -D_WIN32_WINNT=_WIN32_WINNT_WIN7
|
||||
LDFLAGS := -shared -static -static-libgcc -s
|
||||
LIBS := SDL/${SDL_TARGET}/build/.libs/libSDL2.a SDL/${SDL_TARGET}/build/.libs/libSDL2main.a -lmingw32 -luuid -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lsetupapi -lversion
|
||||
DEPS = SDL
|
||||
|
||||
all: options ${OUT}
|
||||
|
||||
.PHONY: dirs
|
||||
dirs:
|
||||
@mkdir -p ${TARGET}/src
|
||||
@mkdir -p ${TARGET}/minhook/src/hde
|
||||
@mkdir -p ${TARGET}/tomlc99
|
||||
|
||||
.PHONY: options
|
||||
options:
|
||||
@echo "CFLAGS = ${CFLAGS}"
|
||||
@echo "LDFLAGS = ${LDFLAGS}"
|
||||
@echo "CC = ${CC}"
|
||||
|
||||
${TARGET}/%.o: %.c
|
||||
@echo BUILD $@
|
||||
@${CC} -c ${CFLAGS} $< -o $@
|
||||
|
||||
.PHONY: ${OUT}
|
||||
${OUT}: dirs ${DEPS} ${OBJ}
|
||||
@echo LINK $@
|
||||
@${CC} ${CFLAGS} -o ${TARGET}/$@.dll ${OBJ} ${LDFLAGS} ${LIBS}
|
||||
|
||||
.PHONY: fmt
|
||||
fmt:
|
||||
@cd src && clang-format -i *.h *.c -style=file
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf ${TARGET}
|
||||
|
||||
.PHONY: SDL
|
||||
SDL:
|
||||
@mkdir -p SDL/${SDL_TARGET}
|
||||
@cd SDL/${SDL_TARGET} && ../configure --build=x86_64-linux-gnu --host=${SDL_TARGET} --disable-sdl2-config --disable-shared --enable-assertions=release --enable-directx --enable-haptic
|
||||
@make -s -C SDL/${SDL_TARGET}
|
1
SDL
Submodule
1
SDL
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 00b95e989b68ca057662263a18a4df576786555a
|
7
dist/keyconfig.toml
vendored
Normal file
7
dist/keyconfig.toml
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
TEST = [ "F1" ]
|
||||
SERVICE = [ "F2" ]
|
||||
DEBUG_UP = [ "UPARROW" ]
|
||||
DEBUG_DOWN = [ "DOWNARROW" ]
|
||||
DEBUG_ENTER = [ "ENTER" ]
|
||||
|
||||
COIN_ADD = [ "ENTER", "SDL_START" ]
|
1
minhook
Submodule
1
minhook
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 4a455528f61b5a375b1f9d44e7d296d47f18bb18
|
348
src/dllmain.c
Normal file
348
src/dllmain.c
Normal file
@ -0,0 +1,348 @@
|
||||
#include "helpers.h"
|
||||
#include "poll.h"
|
||||
#include <math.h>
|
||||
|
||||
u16
|
||||
rand16 (void) {
|
||||
int max_value = 20000; // ~ 90 in I/O test menu
|
||||
int min_value = 10000; // ~ 30 in I/O test menu
|
||||
|
||||
return (u16)(rand () % max_value + min_value);
|
||||
}
|
||||
|
||||
HWND windowHandle = 0;
|
||||
|
||||
int CALLBACK
|
||||
enumWindows (HWND handle, LPARAM param) {
|
||||
char buf[64];
|
||||
GetClassName (handle, buf, 64);
|
||||
printf ("%s\n", buf);
|
||||
if (!strcmp (buf, "nuFoundation.Window")) {
|
||||
windowHandle = handle;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// show cursor
|
||||
HOOK_DYNAMIC (i32, __stdcall, ShowMouse, i32 show) {
|
||||
return originalShowMouse (true);
|
||||
}
|
||||
|
||||
// xinput stuff
|
||||
HOOK_DYNAMIC (u32, __stdcall, XinputGetState, u32 index, void *state) {
|
||||
return 1167;
|
||||
}
|
||||
|
||||
HOOK_DYNAMIC (u32, __stdcall, XinputSetState, u32 index, void *state) {
|
||||
return 1167;
|
||||
}
|
||||
|
||||
HOOK_DYNAMIC (u32, __stdcall, XinputGetCapabilites, u32 index, u32 flags,
|
||||
void *state) {
|
||||
return 1167;
|
||||
}
|
||||
|
||||
struct Keybindings COIN_ADD = { .keycodes = { VK_RETURN },
|
||||
.buttons = { SDL_CONTROLLER_BUTTON_START } };
|
||||
struct Keybindings TEST = { .keycodes = { VK_F1 } };
|
||||
struct Keybindings SERVICE = { .keycodes = { VK_F2 } };
|
||||
struct Keybindings DEBUG_UP = { .keycodes = { VK_UP } };
|
||||
struct Keybindings DEBUG_DOWN = { .keycodes = { VK_DOWN } };
|
||||
struct Keybindings DEBUG_ENTER = { .keycodes = { VK_RETURN } };
|
||||
|
||||
int coin_count = 0;
|
||||
bool testEnabled = false;
|
||||
bool inited = false;
|
||||
|
||||
// bnusio stuff
|
||||
HOOK_DYNAMIC (i64, __stdcall, ClearSram) { return false; }
|
||||
|
||||
HOOK_DYNAMIC (i64, __stdcall, Close) { return false; }
|
||||
|
||||
HOOK_DYNAMIC (i64, __fastcall, Communication, i32 a1) { return false; }
|
||||
|
||||
HOOK_DYNAMIC (i64, __fastcall, DecCoin, i32 a1, u16 a2) {
|
||||
coin_count -= a2;
|
||||
return false;
|
||||
}
|
||||
|
||||
HOOK_DYNAMIC (i64, __fastcall, DecService, i32 a1, u16 a2) { return false; }
|
||||
|
||||
// TODO
|
||||
HOOK_DYNAMIC (u16, __fastcall, GetAnalogIn, u8 which) { return false; }
|
||||
|
||||
HOOK_DYNAMIC (void *, __fastcall, GetBuffer, u16 a1, i64 a2, i16 a3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
HOOK_DYNAMIC (i64, __fastcall, GetCDOut, u8 a1) { return false; }
|
||||
|
||||
HOOK_DYNAMIC (u16, __fastcall, GetCoin, i32 a1) {
|
||||
if (a1 == 1) {
|
||||
if (!inited) {
|
||||
EnumWindows (enumWindows, 0);
|
||||
InitializePoll (windowHandle);
|
||||
|
||||
toml_table_t *config = openConfig (configPath ("keyconfig.toml"));
|
||||
if (config) {
|
||||
SetConfigValue (config, "COIN_ADD", &COIN_ADD);
|
||||
SetConfigValue (config, "TEST", &TEST);
|
||||
SetConfigValue (config, "SERVICE", &SERVICE);
|
||||
SetConfigValue (config, "DEBUG_UP", &DEBUG_UP);
|
||||
SetConfigValue (config, "DEBUG_DOWN", &DEBUG_DOWN);
|
||||
SetConfigValue (config, "DEBUG_ENTER", &DEBUG_ENTER);
|
||||
|
||||
toml_free (config);
|
||||
}
|
||||
|
||||
inited = true;
|
||||
}
|
||||
|
||||
UpdatePoll (windowHandle);
|
||||
if (IsButtonTapped (COIN_ADD)) {
|
||||
printf ("Add coin\n");
|
||||
coin_count++;
|
||||
}
|
||||
if (IsButtonTapped (TEST))
|
||||
testEnabled = !testEnabled;
|
||||
}
|
||||
return coin_count;
|
||||
}
|
||||
|
||||
HOOK_DYNAMIC (void *, __fastcall, GetCoinError, i32 a1) { return false; }
|
||||
|
||||
HOOK_DYNAMIC (i64, __fastcall, GetCoinLock, u8 a1) { return false; }
|
||||
|
||||
HOOK_DYNAMIC (u64, __stdcall, GetEncoder) { return false; }
|
||||
|
||||
HOOK_DYNAMIC (void *, __stdcall, GetExpansionMode) { return false; }
|
||||
|
||||
HOOK_DYNAMIC (void *, __stdcall, GetFirmwareVersion) {
|
||||
return (void *)(u16)126;
|
||||
}
|
||||
|
||||
HOOK_DYNAMIC (u8, __stdcall, GetGout, u8 a1) { return false; }
|
||||
|
||||
HOOK_DYNAMIC (i64, __stdcall, GetHopOut, u8 a1) { return false; }
|
||||
|
||||
HOOK_DYNAMIC (char *, __stdcall, GetIoBoardName) { return false; }
|
||||
|
||||
HOOK_DYNAMIC (u16, __fastcall, GetRegisterU16, i16 a1) { return false; }
|
||||
|
||||
HOOK_DYNAMIC (u8, __fastcall, GetRegisterU8, u16 a1) { return false; }
|
||||
|
||||
HOOK_DYNAMIC (void *, __fastcall, GetService, i32 a1) { return false; }
|
||||
|
||||
HOOK_DYNAMIC (void *, __fastcall, GetServiceError, i32 a1) { return false; }
|
||||
|
||||
HOOK_DYNAMIC (u16, __fastcall, GetStatusU16, u16 a1) { return false; }
|
||||
|
||||
HOOK_DYNAMIC (u8, __fastcall, GetStatusU8, u16 a1) { return false; }
|
||||
|
||||
HOOK_DYNAMIC (u32, __stdcall, GetSwIn) {
|
||||
u32 mask = 0;
|
||||
mask |= (u32)testEnabled << 7;
|
||||
mask |= (u32)IsButtonDown (DEBUG_ENTER) << 9;
|
||||
mask |= (u32)IsButtonDown (DEBUG_DOWN) << 12;
|
||||
mask |= (u32)IsButtonDown (DEBUG_UP) << 13;
|
||||
mask |= (u32)IsButtonDown (SERVICE) << 14;
|
||||
return mask;
|
||||
}
|
||||
|
||||
HOOK_DYNAMIC (u64, __stdcall, GetSwIn64) { return false; }
|
||||
|
||||
HOOK_DYNAMIC (void *, __stdcall, GetSystemError) { return false; }
|
||||
|
||||
HOOK_DYNAMIC (u8, __stdcall, IsConnected) { return false; }
|
||||
|
||||
HOOK_DYNAMIC (u8, __stdcall, IsWideUsio) { return false; }
|
||||
|
||||
HOOK_DYNAMIC (i64, __stdcall, Open) { return false; }
|
||||
|
||||
// TODO
|
||||
HOOK_DYNAMIC (i64, __stdcall, ResetCoin) {
|
||||
coin_count = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
HOOK_DYNAMIC (i32, __stdcall, ResetIoBoard) { return false; }
|
||||
|
||||
HOOK_DYNAMIC (i64, __fastcall, SetBuffer, u16 a1, i32 a2, i16 a3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
HOOK_DYNAMIC (i64, __fastcall, SetCDOut, u8 a1, u8 a2) { return false; }
|
||||
|
||||
// TODO
|
||||
HOOK_DYNAMIC (i64, __fastcall, SetCoinLock, u8 a1, u8 a2) { return false; }
|
||||
|
||||
HOOK_DYNAMIC (i64, __fastcall, SetExpansionMode, i16 a1) { return false; }
|
||||
|
||||
HOOK_DYNAMIC (i64, __fastcall, SetGout, u8 a1, u8 a2) { return false; }
|
||||
|
||||
HOOK_DYNAMIC (i64, __fastcall, SetHopOut, u8 a1, u8 a2) { return false; }
|
||||
|
||||
HOOK_DYNAMIC (i64, __fastcall, SetHopperLimit, u16 a1, i16 a2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
HOOK_DYNAMIC (i64, __fastcall, SetHopperRequest, u16 a1, i16 a2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
HOOK_DYNAMIC (void *, __fastcall, SetPLCounter, i16 a1) { return false; }
|
||||
|
||||
HOOK_DYNAMIC (i64, __fastcall, SetRegisterU16, u16 a1, u16 a2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
HOOK_DYNAMIC (i64, __fastcall, SetRegisterU8, u16 a1, u8 a2) { return false; }
|
||||
|
||||
HOOK_DYNAMIC (i64, __fastcall, SetSystemError, i16 a1) { return false; }
|
||||
|
||||
HOOK_DYNAMIC (i64, __fastcall, SramRead, i32 a1, u8 a2, i32 a3, u16 a4) {
|
||||
return false;
|
||||
}
|
||||
|
||||
HOOK_DYNAMIC (i64, __fastcall, SramWrite, i32 a1, u8 a2, i32 a3, u16 a4) {
|
||||
return false;
|
||||
}
|
||||
|
||||
HOOK_DYNAMIC (i64, __stdcall, UsbFinderInitialize) { return false; }
|
||||
|
||||
HOOK_DYNAMIC (i64, __stdcall, UsbFinderRelease) { return false; }
|
||||
|
||||
HOOK_DYNAMIC (i64, __fastcall, UsbFinderGetSerialNumber, i32 a1, i64 a2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
i32 __stdcall DllMain (HMODULE mod, DWORD cause, void *ctx) {
|
||||
if (cause == DLL_PROCESS_DETACH)
|
||||
DisposePoll ();
|
||||
if (cause != DLL_PROCESS_ATTACH)
|
||||
return 1;
|
||||
|
||||
void *base = GetModuleHandleA (0);
|
||||
|
||||
// Blatantly stolen patches
|
||||
WRITE_MEMORY (base + 0x239C0, u8, 0xC3); // Actually get shit working
|
||||
WRITE_MEMORY (base + 0x314E8D, u8, 0xB0, 0x01); // Unlock songs
|
||||
|
||||
INSTALL_HOOK_DYNAMIC (ShowMouse,
|
||||
PROC_ADDRESS ("user32.dll", "ShowCursor"));
|
||||
|
||||
INSTALL_HOOK_DYNAMIC (XinputGetState,
|
||||
PROC_ADDRESS ("xinput9_1_0.dll", "XInputGetState"));
|
||||
INSTALL_HOOK_DYNAMIC (XinputSetState,
|
||||
PROC_ADDRESS ("xinput9_1_0.dll", "XInputSetState"));
|
||||
INSTALL_HOOK_DYNAMIC (
|
||||
XinputGetCapabilites,
|
||||
PROC_ADDRESS ("xinput9_1_0.dll", "XInputGetCapabilities"));
|
||||
|
||||
INSTALL_HOOK_DYNAMIC (ClearSram,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_ClearSram"));
|
||||
INSTALL_HOOK_DYNAMIC (Close, PROC_ADDRESS ("bnusio.dll", "bnusio_Close"));
|
||||
INSTALL_HOOK_DYNAMIC (Communication,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_Communication"));
|
||||
INSTALL_HOOK_DYNAMIC (DecCoin,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_DecCoin"));
|
||||
INSTALL_HOOK_DYNAMIC (DecService,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_DecService"));
|
||||
INSTALL_HOOK_DYNAMIC (GetAnalogIn,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_GetAnalogIn"));
|
||||
INSTALL_HOOK_DYNAMIC (GetBuffer,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_GetBuffer"));
|
||||
INSTALL_HOOK_DYNAMIC (GetCDOut,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_GetCDOut"));
|
||||
INSTALL_HOOK_DYNAMIC (GetCoin,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_GetCoin"));
|
||||
INSTALL_HOOK_DYNAMIC (GetCoinError,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_GetCoinError"));
|
||||
INSTALL_HOOK_DYNAMIC (GetCoinLock,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_GetCoinLock"));
|
||||
INSTALL_HOOK_DYNAMIC (GetEncoder,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_GetEncoder"));
|
||||
INSTALL_HOOK_DYNAMIC (
|
||||
GetExpansionMode,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_GetExpansionMode"));
|
||||
INSTALL_HOOK_DYNAMIC (
|
||||
GetFirmwareVersion,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_GetFirmwareVersion"));
|
||||
INSTALL_HOOK_DYNAMIC (GetGout,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_GetGout"));
|
||||
INSTALL_HOOK_DYNAMIC (GetHopOut,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_GetHopOut"));
|
||||
INSTALL_HOOK_DYNAMIC (
|
||||
GetIoBoardName, PROC_ADDRESS ("bnusio.dll", "bnusio_GetIoBoardName"));
|
||||
INSTALL_HOOK_DYNAMIC (
|
||||
GetRegisterU16, PROC_ADDRESS ("bnusio.dll", "bnusio_GetRegisterU16"));
|
||||
INSTALL_HOOK_DYNAMIC (GetRegisterU8,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_GetRegisterU8"));
|
||||
INSTALL_HOOK_DYNAMIC (GetService,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_GetService"));
|
||||
INSTALL_HOOK_DYNAMIC (
|
||||
GetServiceError,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_GetServiceError"));
|
||||
INSTALL_HOOK_DYNAMIC (GetStatusU16,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_GetStatusU16"));
|
||||
INSTALL_HOOK_DYNAMIC (GetStatusU8,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_GetStatusU8"));
|
||||
INSTALL_HOOK_DYNAMIC (GetSwIn,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_GetSwIn"));
|
||||
INSTALL_HOOK_DYNAMIC (GetSwIn64,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_GetSwIn64"));
|
||||
INSTALL_HOOK_DYNAMIC (
|
||||
GetSystemError, PROC_ADDRESS ("bnusio.dll", "bnusio_GetSystemError"));
|
||||
INSTALL_HOOK_DYNAMIC (IsConnected,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_IsConnected"));
|
||||
INSTALL_HOOK_DYNAMIC (IsWideUsio,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_IsWideUsio"));
|
||||
INSTALL_HOOK_DYNAMIC (Open, PROC_ADDRESS ("bnusio.dll", "bnusio_Open"));
|
||||
INSTALL_HOOK_DYNAMIC (ResetCoin,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_ResetCoin"));
|
||||
INSTALL_HOOK_DYNAMIC (ResetIoBoard,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_ResetIoBoard"));
|
||||
INSTALL_HOOK_DYNAMIC (SetBuffer,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_SetBuffer"));
|
||||
INSTALL_HOOK_DYNAMIC (SetCDOut,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_SetCDOut"));
|
||||
INSTALL_HOOK_DYNAMIC (SetCoinLock,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_SetCoinLock"));
|
||||
INSTALL_HOOK_DYNAMIC (
|
||||
SetExpansionMode,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_SetExpansionMode"));
|
||||
INSTALL_HOOK_DYNAMIC (SetGout,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_SetGout"));
|
||||
INSTALL_HOOK_DYNAMIC (SetHopOut,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_SetHopOut"));
|
||||
INSTALL_HOOK_DYNAMIC (
|
||||
SetHopperLimit, PROC_ADDRESS ("bnusio.dll", "bnusio_SetHopperLimit"));
|
||||
INSTALL_HOOK_DYNAMIC (
|
||||
SetHopperRequest,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_SetHopperRequest"));
|
||||
INSTALL_HOOK_DYNAMIC (SetPLCounter,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_SetPLCounter"));
|
||||
INSTALL_HOOK_DYNAMIC (
|
||||
SetRegisterU16, PROC_ADDRESS ("bnusio.dll", "bnusio_SetRegisterU16"));
|
||||
INSTALL_HOOK_DYNAMIC (SetRegisterU8,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_SetRegisterU8"));
|
||||
INSTALL_HOOK_DYNAMIC (
|
||||
SetSystemError, PROC_ADDRESS ("bnusio.dll", "bnusio_SetSystemError"));
|
||||
INSTALL_HOOK_DYNAMIC (SramRead,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_SramRead"));
|
||||
INSTALL_HOOK_DYNAMIC (SramWrite,
|
||||
PROC_ADDRESS ("bnusio.dll", "bnusio_SramWrite"));
|
||||
|
||||
INSTALL_HOOK_DYNAMIC (
|
||||
UsbFinderInitialize,
|
||||
PROC_ADDRESS ("nbamUsbFinder.dll", "nbamUsbFinderInitialize"));
|
||||
INSTALL_HOOK_DYNAMIC (
|
||||
UsbFinderRelease,
|
||||
PROC_ADDRESS ("nbamUsbFinder.dll", "nbamUsbFinderRelease"));
|
||||
INSTALL_HOOK_DYNAMIC (UsbFinderGetSerialNumber,
|
||||
PROC_ADDRESS ("nbamUsbFinderGetSerialNumber.dll",
|
||||
"nbamUsbFinderRelease"));
|
||||
|
||||
return true;
|
||||
}
|
89
src/helpers.c
Normal file
89
src/helpers.c
Normal file
@ -0,0 +1,89 @@
|
||||
#include "helpers.h"
|
||||
#include <windows.h>
|
||||
|
||||
void *consoleHandle = 0;
|
||||
|
||||
char *
|
||||
configPath (char *name) {
|
||||
static char buffer[MAX_PATH];
|
||||
GetModuleFileNameA (NULL, buffer, MAX_PATH);
|
||||
*strrchr (buffer, '\\') = 0;
|
||||
strcat (buffer, "\\plugins\\");
|
||||
strcat (buffer, name);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
toml_table_t *
|
||||
openConfig (char *configFilePath) {
|
||||
FILE *file = fopen (configFilePath, "r");
|
||||
if (!file) {
|
||||
printWarning ("%s (%s): cannot open file\n", __func__, configFilePath);
|
||||
return 0;
|
||||
}
|
||||
char errorbuf[200];
|
||||
toml_table_t *config = toml_parse_file (file, errorbuf, 200);
|
||||
fclose (file);
|
||||
|
||||
if (!config) {
|
||||
printWarning ("%s (%s): %s\n", __func__, configFilePath, errorbuf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
toml_table_t *
|
||||
openConfigSection (toml_table_t *config, char *sectionName) {
|
||||
toml_table_t *section = toml_table_in (config, sectionName);
|
||||
if (!section) {
|
||||
printWarning ("%s (%s): cannot find section\n", __func__, sectionName);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return section;
|
||||
}
|
||||
|
||||
bool
|
||||
readConfigBool (toml_table_t *table, char *key, bool notFoundValue) {
|
||||
toml_datum_t data = toml_bool_in (table, key);
|
||||
if (!data.ok)
|
||||
return notFoundValue;
|
||||
|
||||
return (bool)data.u.b;
|
||||
}
|
||||
|
||||
int64_t
|
||||
readConfigInt (toml_table_t *table, char *key, int64_t notFoundValue) {
|
||||
toml_datum_t data = toml_int_in (table, key);
|
||||
if (!data.ok)
|
||||
return notFoundValue;
|
||||
|
||||
return data.u.i;
|
||||
}
|
||||
|
||||
char *
|
||||
readConfigString (toml_table_t *table, char *key, char *notFoundValue) {
|
||||
toml_datum_t data = toml_string_in (table, key);
|
||||
if (!data.ok)
|
||||
return notFoundValue;
|
||||
|
||||
return data.u.s;
|
||||
}
|
||||
|
||||
void
|
||||
printColour (int colour, const char *format, ...) {
|
||||
va_list args;
|
||||
va_start (args, format);
|
||||
|
||||
if (consoleHandle == 0)
|
||||
consoleHandle = GetStdHandle (STD_OUTPUT_HANDLE);
|
||||
|
||||
char buffer[255];
|
||||
vsprintf (buffer, format, args);
|
||||
SetConsoleTextAttribute (consoleHandle, colour);
|
||||
printf (buffer);
|
||||
SetConsoleTextAttribute (consoleHandle, FOREGROUND_BLUE | FOREGROUND_GREEN
|
||||
| FOREGROUND_RED);
|
||||
|
||||
va_end (args);
|
||||
}
|
110
src/helpers.h
Normal file
110
src/helpers.h
Normal file
@ -0,0 +1,110 @@
|
||||
#pragma once
|
||||
#include <MinHook.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <toml.h>
|
||||
#include <windows.h>
|
||||
|
||||
typedef int8_t i8;
|
||||
typedef int16_t i16;
|
||||
typedef int32_t i32;
|
||||
typedef int64_t i64;
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
|
||||
#define FUNCTION_PTR(returnType, callingConvention, function, location, ...) \
|
||||
returnType (callingConvention *function) (__VA_ARGS__) \
|
||||
= (returnType (callingConvention *) (__VA_ARGS__)) (location)
|
||||
|
||||
#define PROC_ADDRESS(libraryName, procName) \
|
||||
GetProcAddress (LoadLibrary (TEXT (libraryName)), procName)
|
||||
|
||||
#define HOOK(returnType, callingConvention, functionName, location, ...) \
|
||||
typedef returnType callingConvention (*functionName) (__VA_ARGS__); \
|
||||
functionName original##functionName = NULL; \
|
||||
void *where##functionName = (void *)location; \
|
||||
returnType callingConvention implOf##functionName (__VA_ARGS__)
|
||||
|
||||
#define HOOK_DYNAMIC(returnType, callingConvention, functionName, ...) \
|
||||
typedef returnType callingConvention (*functionName) (__VA_ARGS__); \
|
||||
functionName original##functionName = NULL; \
|
||||
void *where##functionName = NULL; \
|
||||
returnType callingConvention implOf##functionName (__VA_ARGS__)
|
||||
|
||||
#define INSTALL_HOOK(functionName) \
|
||||
{ \
|
||||
MH_Initialize (); \
|
||||
MH_CreateHook ((void *)where##functionName, \
|
||||
(void *)implOf##functionName, \
|
||||
(void **)(&original##functionName)); \
|
||||
MH_EnableHook ((void *)where##functionName); \
|
||||
}
|
||||
|
||||
#define INSTALL_HOOK_DYNAMIC(functionName, location) \
|
||||
{ \
|
||||
where##functionName = location; \
|
||||
INSTALL_HOOK (functionName); \
|
||||
}
|
||||
|
||||
#define READ_MEMORY(location, type) *(type *)location
|
||||
|
||||
#define WRITE_MEMORY(location, type, ...) \
|
||||
{ \
|
||||
const type data[] = { __VA_ARGS__ }; \
|
||||
DWORD oldProtect; \
|
||||
VirtualProtect ((void *)(location), sizeof (data), \
|
||||
PAGE_EXECUTE_READWRITE, &oldProtect); \
|
||||
memcpy ((void *)(location), data, sizeof (data)); \
|
||||
VirtualProtect ((void *)(location), sizeof (data), oldProtect, \
|
||||
&oldProtect); \
|
||||
}
|
||||
|
||||
#define WRITE_MEMORY_STRING(location, data, length) \
|
||||
{ \
|
||||
DWORD oldProtect; \
|
||||
VirtualProtect ((void *)(location), length, PAGE_EXECUTE_READWRITE, \
|
||||
&oldProtect); \
|
||||
memcpy ((void *)(location), data, length); \
|
||||
VirtualProtect ((void *)(location), length, oldProtect, &oldProtect); \
|
||||
}
|
||||
|
||||
#define WRITE_NOP(location, count) \
|
||||
{ \
|
||||
DWORD oldProtect; \
|
||||
VirtualProtect ((void *)(location), (size_t)(count), \
|
||||
PAGE_EXECUTE_READWRITE, &oldProtect); \
|
||||
for (size_t i = 0; i < (size_t)(count); i++) \
|
||||
*((uint8_t *)(location) + i) = 0x90; \
|
||||
VirtualProtect ((void *)(location), (size_t)(count), oldProtect, \
|
||||
&oldProtect); \
|
||||
}
|
||||
|
||||
#define WRITE_NULL(location, count) \
|
||||
{ \
|
||||
DWORD oldProtect; \
|
||||
VirtualProtect ((void *)(location), (size_t)(count), \
|
||||
PAGE_EXECUTE_READWRITE, &oldProtect); \
|
||||
for (size_t i = 0; i < (size_t)(count); i++) \
|
||||
*((uint8_t *)(location) + i) = 0x00; \
|
||||
VirtualProtect ((void *)(location), (size_t)(count), oldProtect, \
|
||||
&oldProtect); \
|
||||
}
|
||||
|
||||
#define COUNTOFARR(arr) sizeof (arr) / sizeof (arr[0])
|
||||
|
||||
#define WARNING_COLOUR (FOREGROUND_RED | FOREGROUND_GREEN)
|
||||
#define ERROR_COLOUR FOREGROUND_RED
|
||||
#define printWarning(format, ...) \
|
||||
printColour (WARNING_COLOUR, format, __VA_ARGS__)
|
||||
#define printError(format, ...) printColour (ERROR_COLOUR, format, __VA_ARGS__)
|
||||
|
||||
char *configPath (char *name);
|
||||
toml_table_t *openConfig (char *configFilePath);
|
||||
toml_table_t *openConfigSection (toml_table_t *config, char *sectionName);
|
||||
bool readConfigBool (toml_table_t *table, char *key, bool notFoundValue);
|
||||
int64_t readConfigInt (toml_table_t *table, char *key, int64_t notFoundValue);
|
||||
char *readConfigString (toml_table_t *table, char *key, char *notFoundValue);
|
||||
void printColour (int colour, const char *format, ...);
|
659
src/poll.c
Normal file
659
src/poll.c
Normal file
@ -0,0 +1,659 @@
|
||||
#include "poll.h"
|
||||
#include "helpers.h"
|
||||
#include <windows.h>
|
||||
|
||||
struct {
|
||||
const char *string;
|
||||
uint8_t keycode;
|
||||
} ConfigKeyboardButtons[] = {
|
||||
{ "F1", 0x70 }, { "F2", 0x71 }, { "F3", 0x72 },
|
||||
{ "F4", 0x73 }, { "F5", 0x74 }, { "F6", 0x75 },
|
||||
{ "F7", 0x76 }, { "F8", 0x77 }, { "F9", 0x78 },
|
||||
{ "F10", 0x79 }, { "F11", 0x7A }, { "F12", 0x7B },
|
||||
{ "NUM1", '1' }, { "NUM2", '2' }, { "NUM3", '3' },
|
||||
{ "NUM4", '4' }, { "NUM5", '5' }, { "NUM6", '6' },
|
||||
{ "NUM7", '7' }, { "NUM8", '8' }, { "NUM9", '9' },
|
||||
{ "NUM0", '0' }, { "Q", 'Q' }, { "W", 'W' },
|
||||
{ "E", 'E' }, { "R", 'R' }, { "T", 'T' },
|
||||
{ "Y", 'Y' }, { "U", 'U' }, { "I", 'I' },
|
||||
{ "O", 'O' }, { "P", 'P' }, { "A", 'A' },
|
||||
{ "S", 'S' }, { "D", 'D' }, { "F", 'F' },
|
||||
{ "G", 'G' }, { "H", 'H' }, { "J", 'J' },
|
||||
{ "K", 'K' }, { "L", 'L' }, { "Z", 'Z' },
|
||||
{ "X", 'X' }, { "C", 'C' }, { "V", 'V' },
|
||||
{ "B", 'B' }, { "N", 'N' }, { "M", 'M' },
|
||||
{ "UPARROW", 0x26 }, { "LEFTARROW", 0x25 }, { "DOWNARROW", 0x28 },
|
||||
{ "RIGHTARROW", 0x27 }, { "ENTER", 0x0D }, { "SPACE", 0x20 },
|
||||
{ "CONTROL", 0x11 }, { "SHIFT", 0x10 }, { "TAB", 0x09 },
|
||||
{ "ESCAPE", 0x1B },
|
||||
};
|
||||
|
||||
struct {
|
||||
const char *string;
|
||||
SDL_GameControllerButton button;
|
||||
} ConfigControllerButtons[] = {
|
||||
{ "SDL_A", SDL_CONTROLLER_BUTTON_A },
|
||||
{ "SDL_B", SDL_CONTROLLER_BUTTON_B },
|
||||
{ "SDL_X", SDL_CONTROLLER_BUTTON_X },
|
||||
{ "SDL_Y", SDL_CONTROLLER_BUTTON_Y },
|
||||
{ "SDL_BACK", SDL_CONTROLLER_BUTTON_BACK },
|
||||
{ "SDL_GUIDE", SDL_CONTROLLER_BUTTON_GUIDE },
|
||||
{ "SDL_START", SDL_CONTROLLER_BUTTON_START },
|
||||
{ "SDL_LSTICK_PRESS", SDL_CONTROLLER_BUTTON_LEFTSTICK },
|
||||
{ "SDL_RSTICK_PRESS", SDL_CONTROLLER_BUTTON_RIGHTSTICK },
|
||||
{ "SDL_LSHOULDER", SDL_CONTROLLER_BUTTON_LEFTSHOULDER },
|
||||
{ "SDL_RSHOULDER", SDL_CONTROLLER_BUTTON_RIGHTSHOULDER },
|
||||
{ "SDL_DPAD_UP", SDL_CONTROLLER_BUTTON_DPAD_UP },
|
||||
{ "SDL_DPAD_DOWN", SDL_CONTROLLER_BUTTON_DPAD_DOWN },
|
||||
{ "SDL_DPAD_LEFT", SDL_CONTROLLER_BUTTON_DPAD_LEFT },
|
||||
{ "SDL_DPAD_RIGHT", SDL_CONTROLLER_BUTTON_DPAD_RIGHT },
|
||||
{ "SDL_MISC", SDL_CONTROLLER_BUTTON_MISC1 },
|
||||
{ "SDL_PADDLE1", SDL_CONTROLLER_BUTTON_PADDLE1 },
|
||||
{ "SDL_PADDLE2", SDL_CONTROLLER_BUTTON_PADDLE2 },
|
||||
{ "SDL_PADDLE3", SDL_CONTROLLER_BUTTON_PADDLE3 },
|
||||
{ "SDL_PADDLE4", SDL_CONTROLLER_BUTTON_PADDLE4 },
|
||||
{ "SDL_TOUCHPAD", SDL_CONTROLLER_BUTTON_TOUCHPAD },
|
||||
};
|
||||
|
||||
struct {
|
||||
const char *string;
|
||||
enum SDLAxis axis;
|
||||
} ConfigControllerAXIS[] = {
|
||||
{ "SDL_LSTICK_LEFT", SDL_AXIS_LEFT_LEFT },
|
||||
{ "SDL_LSTICK_UP", SDL_AXIS_LEFT_UP },
|
||||
{ "SDL_LSTICK_DOWN", SDL_AXIS_LEFT_DOWN },
|
||||
{ "SDL_LSTICK_RIGHT", SDL_AXIS_LEFT_RIGHT },
|
||||
{ "SDL_RSTICK_LEFT", SDL_AXIS_RIGHT_LEFT },
|
||||
{ "SDL_RSTICK_UP", SDL_AXIS_RIGHT_UP },
|
||||
{ "SDL_RSTICK_DOWN", SDL_AXIS_RIGHT_DOWN },
|
||||
{ "SDL_RSTICK_RIGHT", SDL_AXIS_RIGHT_RIGHT },
|
||||
{ "SDL_LTRIGGER", SDL_AXIS_LTRIGGER_DOWN },
|
||||
{ "SDL_RTRIGGER", SDL_AXIS_RTRIGGER_DOWN },
|
||||
};
|
||||
|
||||
struct {
|
||||
const char *string;
|
||||
enum Scroll scroll;
|
||||
} ConfigMouseScroll[] = {
|
||||
{ "SCROLL_UP", MOUSE_SCROLL_UP },
|
||||
{ "SCROLL_DOWN", MOUSE_SCROLL_DOWN },
|
||||
};
|
||||
|
||||
struct MouseState {
|
||||
POINT Position;
|
||||
POINT RelativePosition;
|
||||
bool ScrolledUp;
|
||||
bool ScrolledDown;
|
||||
} currentMouseState, lastMouseState;
|
||||
|
||||
bool currentKeyboardState[0xFF];
|
||||
bool lastKeyboardState[0xFF];
|
||||
|
||||
bool currentControllerButtonsState[SDL_CONTROLLER_BUTTON_MAX];
|
||||
bool lastControllerButtonsState[SDL_CONTROLLER_BUTTON_MAX];
|
||||
struct SDLAxisState currentControllerAxisState;
|
||||
struct SDLAxisState lastControllerAxisState;
|
||||
|
||||
SDL_Window *window;
|
||||
SDL_GameController *controllers[255];
|
||||
|
||||
void
|
||||
SetConfigValue (toml_table_t *table, char *key, struct Keybindings *keybind) {
|
||||
toml_array_t *array = toml_array_in (table, key);
|
||||
if (!array) {
|
||||
printWarning ("%s (%s): Cannot find array\n", __func__, key);
|
||||
return;
|
||||
}
|
||||
|
||||
memset (keybind, 0, sizeof (*keybind));
|
||||
for (int i = 0; i < COUNTOFARR (keybind->buttons); i++)
|
||||
keybind->buttons[i] = SDL_CONTROLLER_BUTTON_INVALID;
|
||||
|
||||
for (int i = 0;; i++) {
|
||||
toml_datum_t bind = toml_string_at (array, i);
|
||||
if (!bind.ok)
|
||||
break;
|
||||
struct ConfigValue value = StringToConfigEnum (bind.u.s);
|
||||
free (bind.u.s);
|
||||
|
||||
switch (value.type) {
|
||||
case keycode:
|
||||
for (int i = 0; i < COUNTOFARR (keybind->keycodes); i++) {
|
||||
if (keybind->keycodes[i] == 0) {
|
||||
keybind->keycodes[i] = value.keycode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case button:
|
||||
for (int i = 0; i < COUNTOFARR (keybind->buttons); i++) {
|
||||
if (keybind->buttons[i] == SDL_CONTROLLER_BUTTON_INVALID) {
|
||||
keybind->buttons[i] = value.button;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case axis:
|
||||
for (int i = 0; i < COUNTOFARR (keybind->axis); i++) {
|
||||
if (keybind->axis[i] == 0) {
|
||||
keybind->axis[i] = value.axis;
|
||||
break;
|
||||
}
|
||||
}
|
||||
case scroll:
|
||||
for (int i = 0; i < COUNTOFARR (keybind->scroll); i++) {
|
||||
if (keybind->scroll[i] == 0) {
|
||||
keybind->scroll[i] = value.scroll;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
InitializePoll (void *DivaWindowHandle) {
|
||||
bool hasRumble = true;
|
||||
SDL_SetMainReady ();
|
||||
|
||||
SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_PS4, "1");
|
||||
SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, "1");
|
||||
SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_PS5, "1");
|
||||
SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1");
|
||||
|
||||
if (SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER
|
||||
| SDL_INIT_EVENTS | SDL_INIT_VIDEO)
|
||||
!= 0) {
|
||||
if (SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER
|
||||
| SDL_INIT_EVENTS | SDL_INIT_VIDEO)
|
||||
== 0) {
|
||||
hasRumble = false;
|
||||
} else {
|
||||
printError (
|
||||
|
||||
"SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | "
|
||||
"SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS | SDL_INIT_VIDEO): "
|
||||
"%s\n",
|
||||
SDL_GetError ());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (SDL_GameControllerAddMappingsFromFile (
|
||||
configPath ("gamecontrollerdb.txt"))
|
||||
== -1)
|
||||
printError ("%s (): Cannot read "
|
||||
"plugins/gamecontrollerdb.txt\n",
|
||||
__func__);
|
||||
SDL_GameControllerEventState (SDL_ENABLE);
|
||||
|
||||
for (int i = 0; i < SDL_NumJoysticks (); i++) {
|
||||
if (!SDL_IsGameController (i))
|
||||
continue;
|
||||
|
||||
SDL_GameController *controller = SDL_GameControllerOpen (i);
|
||||
|
||||
if (!controller) {
|
||||
printWarning ("Could not open gamecontroller %s: %s\n",
|
||||
SDL_GameControllerNameForIndex (i), SDL_GetError ());
|
||||
continue;
|
||||
}
|
||||
|
||||
controllers[i] = controller;
|
||||
break;
|
||||
}
|
||||
|
||||
window = SDL_CreateWindowFrom (DivaWindowHandle);
|
||||
if (window != NULL)
|
||||
SDL_SetWindowResizable (window, true);
|
||||
else
|
||||
printError ("SDL_CreateWindowFrom (DivaWindowHandle): %s\n",
|
||||
SDL_GetError ());
|
||||
|
||||
return hasRumble;
|
||||
}
|
||||
|
||||
void
|
||||
UpdatePoll (void *DivaWindowHandle) {
|
||||
if (DivaWindowHandle == NULL || GetForegroundWindow () != DivaWindowHandle)
|
||||
return;
|
||||
|
||||
memcpy (lastKeyboardState, currentKeyboardState, 255);
|
||||
memcpy (lastControllerButtonsState, currentControllerButtonsState, 21);
|
||||
lastMouseState = currentMouseState;
|
||||
lastControllerAxisState = currentControllerAxisState;
|
||||
|
||||
for (uint8_t i = 0; i < 0xFF; i++)
|
||||
currentKeyboardState[i] = GetAsyncKeyState (i) != 0;
|
||||
|
||||
currentMouseState.ScrolledUp = false;
|
||||
currentMouseState.ScrolledDown = false;
|
||||
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent (&event) != 0) {
|
||||
switch (event.type) {
|
||||
case SDL_CONTROLLERDEVICEADDED:
|
||||
if (!SDL_IsGameController (event.cdevice.which))
|
||||
break;
|
||||
|
||||
SDL_GameController *controller
|
||||
= SDL_GameControllerOpen (event.cdevice.which);
|
||||
|
||||
if (!controller) {
|
||||
printError (
|
||||
|
||||
"%s (): Could not open "
|
||||
"gamecontroller %s: %s\n",
|
||||
__func__,
|
||||
SDL_GameControllerNameForIndex (event.cdevice.which),
|
||||
SDL_GetError ());
|
||||
continue;
|
||||
}
|
||||
|
||||
controllers[event.cdevice.which] = controller;
|
||||
break;
|
||||
case SDL_CONTROLLERDEVICEREMOVED:
|
||||
if (!SDL_IsGameController (event.cdevice.which))
|
||||
break;
|
||||
SDL_GameControllerClose (controllers[event.cdevice.which]);
|
||||
|
||||
break;
|
||||
case SDL_MOUSEWHEEL:
|
||||
if (event.wheel.y > 0)
|
||||
currentMouseState.ScrolledUp = true;
|
||||
else if (event.wheel.y < 0)
|
||||
currentMouseState.ScrolledDown = true;
|
||||
break;
|
||||
case SDL_CONTROLLERBUTTONUP:
|
||||
case SDL_CONTROLLERBUTTONDOWN:
|
||||
currentControllerButtonsState[event.cbutton.button]
|
||||
= event.cbutton.state;
|
||||
break;
|
||||
case SDL_CONTROLLERAXISMOTION:
|
||||
if (event.caxis.value > 8000) {
|
||||
switch (event.caxis.axis) {
|
||||
case SDL_CONTROLLER_AXIS_LEFTX:
|
||||
currentControllerAxisState.LeftRight = 1;
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_LEFTY:
|
||||
currentControllerAxisState.LeftDown = 1;
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_RIGHTX:
|
||||
currentControllerAxisState.RightRight = 1;
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_RIGHTY:
|
||||
currentControllerAxisState.RightDown = 1;
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
|
||||
currentControllerAxisState.LTriggerDown = 1;
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
|
||||
currentControllerAxisState.RTriggerDown = 1;
|
||||
break;
|
||||
}
|
||||
} else if (event.caxis.value < -8000) {
|
||||
switch (event.caxis.axis) {
|
||||
case SDL_CONTROLLER_AXIS_LEFTX:
|
||||
currentControllerAxisState.LeftLeft = 1;
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_LEFTY:
|
||||
currentControllerAxisState.LeftUp = 1;
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_RIGHTX:
|
||||
currentControllerAxisState.RightLeft = 1;
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_RIGHTY:
|
||||
currentControllerAxisState.RightUp = 1;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (event.caxis.axis) {
|
||||
case SDL_CONTROLLER_AXIS_LEFTX:
|
||||
currentControllerAxisState.LeftRight = 0;
|
||||
currentControllerAxisState.LeftLeft = 0;
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_LEFTY:
|
||||
currentControllerAxisState.LeftDown = 0;
|
||||
currentControllerAxisState.LeftUp = 0;
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_RIGHTX:
|
||||
currentControllerAxisState.RightRight = 0;
|
||||
currentControllerAxisState.RightLeft = 0;
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_RIGHTY:
|
||||
currentControllerAxisState.RightDown = 0;
|
||||
currentControllerAxisState.RightUp = 0;
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
|
||||
currentControllerAxisState.LTriggerDown = 0;
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
|
||||
currentControllerAxisState.RTriggerDown = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DisposePoll () {
|
||||
SDL_DestroyWindow (window);
|
||||
SDL_Quit ();
|
||||
}
|
||||
|
||||
struct ConfigValue
|
||||
StringToConfigEnum (char *value) {
|
||||
struct ConfigValue rval = { 0 };
|
||||
for (int i = 0; i < COUNTOFARR (ConfigKeyboardButtons); ++i)
|
||||
if (!strcmp (value, ConfigKeyboardButtons[i].string)) {
|
||||
rval.type = keycode;
|
||||
rval.keycode = ConfigKeyboardButtons[i].keycode;
|
||||
return rval;
|
||||
}
|
||||
for (int i = 0; i < COUNTOFARR (ConfigControllerButtons); ++i)
|
||||
if (!strcmp (value, ConfigControllerButtons[i].string)) {
|
||||
rval.type = button;
|
||||
rval.button = ConfigControllerButtons[i].button;
|
||||
return rval;
|
||||
}
|
||||
for (int i = 0; i < COUNTOFARR (ConfigControllerAXIS); ++i)
|
||||
if (!strcmp (value, ConfigControllerAXIS[i].string)) {
|
||||
rval.type = axis;
|
||||
rval.axis = ConfigControllerAXIS[i].axis;
|
||||
return rval;
|
||||
}
|
||||
for (int i = 0; i < COUNTOFARR (ConfigMouseScroll); ++i)
|
||||
if (!strcmp (value, ConfigMouseScroll[i].string)) {
|
||||
rval.type = scroll;
|
||||
rval.scroll = ConfigMouseScroll[i].scroll;
|
||||
return rval;
|
||||
}
|
||||
|
||||
printError ("%s (%s): Unknown value\n", __func__, value);
|
||||
return rval;
|
||||
}
|
||||
|
||||
struct InternalButtonState
|
||||
GetInternalButtonState (struct Keybindings bindings) {
|
||||
struct InternalButtonState buttons = { 0 };
|
||||
|
||||
for (int i = 0; i < COUNTOFARR (ConfigKeyboardButtons); i++) {
|
||||
if (bindings.keycodes[i] == 0)
|
||||
continue;
|
||||
if (KeyboardIsReleased (bindings.keycodes[i]))
|
||||
buttons.Released = 1;
|
||||
if (KeyboardIsDown (bindings.keycodes[i]))
|
||||
buttons.Down = 1;
|
||||
if (KeyboardIsTapped (bindings.keycodes[i]))
|
||||
buttons.Tapped = 1;
|
||||
}
|
||||
for (int i = 0; i < COUNTOFARR (ConfigControllerButtons); i++) {
|
||||
if (bindings.buttons[i] == SDL_CONTROLLER_BUTTON_INVALID)
|
||||
continue;
|
||||
if (ControllerButtonIsReleased (bindings.buttons[i]))
|
||||
buttons.Released = 1;
|
||||
if (ControllerButtonIsDown (bindings.buttons[i]))
|
||||
buttons.Down = 1;
|
||||
if (ControllerButtonIsTapped (bindings.buttons[i]))
|
||||
buttons.Tapped = 1;
|
||||
}
|
||||
for (int i = 0; i < COUNTOFARR (ConfigControllerAXIS); i++) {
|
||||
if (bindings.axis[i] == 0)
|
||||
continue;
|
||||
if (ControllerAxisIsReleased (bindings.axis[i]))
|
||||
buttons.Released = 1;
|
||||
if (ControllerAxisIsDown (bindings.axis[i]))
|
||||
buttons.Down = 1;
|
||||
if (ControllerAxisIsTapped (bindings.axis[i]))
|
||||
buttons.Tapped = 1;
|
||||
}
|
||||
for (int i = 0; i < COUNTOFARR (ConfigMouseScroll); i++) {
|
||||
if (bindings.scroll[i] == 0)
|
||||
continue;
|
||||
if (GetMouseScrollIsReleased (bindings.scroll[i]))
|
||||
buttons.Released = 1;
|
||||
if (GetMouseScrollIsDown (bindings.scroll[i]))
|
||||
buttons.Down = 1;
|
||||
if (GetMouseScrollIsTapped (bindings.scroll[i]))
|
||||
buttons.Tapped = 1;
|
||||
}
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
void
|
||||
SetRumble (int left, int right) {
|
||||
for (int i = 0; i < COUNTOFARR (controllers); i++) {
|
||||
if (!controllers[i] || !SDL_GameControllerHasRumble (controllers[i]))
|
||||
continue;
|
||||
|
||||
SDL_GameControllerRumble (controllers[i], left, right, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool
|
||||
KeyboardIsDown (uint8_t keycode) {
|
||||
return currentKeyboardState[keycode];
|
||||
}
|
||||
|
||||
inline bool
|
||||
KeyboardIsUp (uint8_t keycode) {
|
||||
return !KeyboardIsDown (keycode);
|
||||
}
|
||||
|
||||
inline bool
|
||||
KeyboardIsTapped (uint8_t keycode) {
|
||||
return KeyboardIsDown (keycode) && KeyboardWasUp (keycode);
|
||||
}
|
||||
|
||||
inline bool
|
||||
KeyboardIsReleased (uint8_t keycode) {
|
||||
return KeyboardIsUp (keycode) && KeyboardWasDown (keycode);
|
||||
}
|
||||
|
||||
inline bool
|
||||
KeyboardWasDown (uint8_t keycode) {
|
||||
return lastKeyboardState[keycode];
|
||||
}
|
||||
|
||||
inline bool
|
||||
KeyboardWasUp (uint8_t keycode) {
|
||||
return !KeyboardWasDown (keycode);
|
||||
}
|
||||
|
||||
inline POINT
|
||||
GetMousePosition () {
|
||||
return currentMouseState.Position;
|
||||
}
|
||||
|
||||
inline POINT
|
||||
GetLastMousePosition () {
|
||||
return lastMouseState.Position;
|
||||
}
|
||||
|
||||
inline POINT
|
||||
GetMouseRelativePosition () {
|
||||
return currentMouseState.RelativePosition;
|
||||
}
|
||||
|
||||
inline POINT
|
||||
GetLastMouseRelativePosition () {
|
||||
return lastMouseState.RelativePosition;
|
||||
}
|
||||
|
||||
inline void
|
||||
SetMousePosition (POINT new) {
|
||||
currentMouseState.Position = new;
|
||||
}
|
||||
|
||||
inline bool
|
||||
GetMouseScrollUp () {
|
||||
return currentMouseState.ScrolledUp;
|
||||
}
|
||||
|
||||
inline bool
|
||||
GetMouseScrollDown () {
|
||||
return currentMouseState.ScrolledDown;
|
||||
}
|
||||
|
||||
inline bool
|
||||
GetWasMouseScrollUp () {
|
||||
return lastMouseState.ScrolledUp;
|
||||
}
|
||||
|
||||
inline bool
|
||||
GetWasMouseScrollDown () {
|
||||
return lastMouseState.ScrolledDown;
|
||||
}
|
||||
|
||||
inline bool
|
||||
GetMouseScrollIsReleased (enum Scroll scroll) {
|
||||
if (scroll == MOUSE_SCROLL_UP)
|
||||
return !GetMouseScrollUp () && GetWasMouseScrollUp ();
|
||||
else
|
||||
return !GetMouseScrollDown () && GetWasMouseScrollDown ();
|
||||
}
|
||||
|
||||
inline bool
|
||||
GetMouseScrollIsDown (enum Scroll scroll) {
|
||||
if (scroll == MOUSE_SCROLL_UP)
|
||||
return GetMouseScrollUp ();
|
||||
else
|
||||
return GetMouseScrollDown ();
|
||||
}
|
||||
|
||||
inline bool
|
||||
GetMouseScrollIsTapped (enum Scroll scroll) {
|
||||
if (scroll == MOUSE_SCROLL_UP)
|
||||
return GetMouseScrollUp () && !GetWasMouseScrollUp ();
|
||||
else
|
||||
return GetMouseScrollDown () && !GetWasMouseScrollDown ();
|
||||
}
|
||||
|
||||
inline bool
|
||||
ControllerButtonIsDown (SDL_GameControllerButton button) {
|
||||
return currentControllerButtonsState[button];
|
||||
}
|
||||
|
||||
inline bool
|
||||
ControllerButtonIsUp (SDL_GameControllerButton button) {
|
||||
return !ControllerButtonIsDown (button);
|
||||
}
|
||||
|
||||
inline bool
|
||||
ControllerButtonWasDown (SDL_GameControllerButton button) {
|
||||
return lastControllerButtonsState[button];
|
||||
}
|
||||
|
||||
inline bool
|
||||
ControllerButtonWasUp (SDL_GameControllerButton button) {
|
||||
return !ControllerButtonWasDown (button);
|
||||
}
|
||||
|
||||
inline bool
|
||||
ControllerButtonIsTapped (SDL_GameControllerButton button) {
|
||||
return ControllerButtonIsDown (button) && ControllerButtonWasUp (button);
|
||||
}
|
||||
|
||||
inline bool
|
||||
ControllerButtonIsReleased (SDL_GameControllerButton button) {
|
||||
return ControllerButtonIsUp (button) && ControllerButtonWasDown (button);
|
||||
}
|
||||
|
||||
inline bool
|
||||
ControllerAxisIsDown (enum SDLAxis axis) {
|
||||
switch (axis) {
|
||||
case SDL_AXIS_LEFT_LEFT:
|
||||
return currentControllerAxisState.LeftLeft;
|
||||
case SDL_AXIS_LEFT_RIGHT:
|
||||
return currentControllerAxisState.LeftRight;
|
||||
case SDL_AXIS_LEFT_UP:
|
||||
return currentControllerAxisState.LeftUp;
|
||||
case SDL_AXIS_LEFT_DOWN:
|
||||
return currentControllerAxisState.LeftDown;
|
||||
case SDL_AXIS_RIGHT_LEFT:
|
||||
return currentControllerAxisState.RightLeft;
|
||||
case SDL_AXIS_RIGHT_RIGHT:
|
||||
return currentControllerAxisState.RightRight;
|
||||
case SDL_AXIS_RIGHT_UP:
|
||||
return currentControllerAxisState.RightUp;
|
||||
case SDL_AXIS_RIGHT_DOWN:
|
||||
return currentControllerAxisState.RightDown;
|
||||
case SDL_AXIS_LTRIGGER_DOWN:
|
||||
return currentControllerAxisState.LTriggerDown;
|
||||
case SDL_AXIS_RTRIGGER_DOWN:
|
||||
return currentControllerAxisState.RTriggerDown;
|
||||
case SDL_AXIS_NULL:
|
||||
case SDL_AXIS_MAX:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool
|
||||
ControllerAxisIsUp (enum SDLAxis axis) {
|
||||
return !ControllerAxisIsDown (axis);
|
||||
}
|
||||
|
||||
inline bool
|
||||
ControllerAxisWasDown (enum SDLAxis axis) {
|
||||
switch (axis) {
|
||||
case SDL_AXIS_LEFT_LEFT:
|
||||
return lastControllerAxisState.LeftLeft;
|
||||
case SDL_AXIS_LEFT_RIGHT:
|
||||
return lastControllerAxisState.LeftRight;
|
||||
case SDL_AXIS_LEFT_UP:
|
||||
return lastControllerAxisState.LeftUp;
|
||||
case SDL_AXIS_LEFT_DOWN:
|
||||
return lastControllerAxisState.LeftDown;
|
||||
case SDL_AXIS_RIGHT_LEFT:
|
||||
return lastControllerAxisState.RightLeft;
|
||||
case SDL_AXIS_RIGHT_RIGHT:
|
||||
return lastControllerAxisState.RightRight;
|
||||
case SDL_AXIS_RIGHT_UP:
|
||||
return lastControllerAxisState.RightUp;
|
||||
case SDL_AXIS_RIGHT_DOWN:
|
||||
return lastControllerAxisState.RightDown;
|
||||
case SDL_AXIS_LTRIGGER_DOWN:
|
||||
return lastControllerAxisState.LTriggerDown;
|
||||
case SDL_AXIS_RTRIGGER_DOWN:
|
||||
return lastControllerAxisState.RTriggerDown;
|
||||
case SDL_AXIS_NULL:
|
||||
case SDL_AXIS_MAX:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool
|
||||
ControllerAxisWasUp (enum SDLAxis axis) {
|
||||
return !ControllerAxisWasDown (axis);
|
||||
}
|
||||
|
||||
inline bool
|
||||
ControllerAxisIsTapped (enum SDLAxis axis) {
|
||||
return ControllerAxisIsDown (axis) && ControllerAxisWasUp (axis);
|
||||
}
|
||||
|
||||
inline bool
|
||||
ControllerAxisIsReleased (enum SDLAxis axis) {
|
||||
return ControllerAxisIsUp (axis) && ControllerAxisWasDown (axis);
|
||||
}
|
||||
|
||||
inline bool
|
||||
IsButtonTapped (struct Keybindings bindings) {
|
||||
return GetInternalButtonState (bindings).Tapped;
|
||||
}
|
||||
|
||||
inline bool
|
||||
IsButtonReleased (struct Keybindings bindings) {
|
||||
return GetInternalButtonState (bindings).Released;
|
||||
}
|
||||
|
||||
inline bool
|
||||
IsButtonDown (struct Keybindings bindings) {
|
||||
return GetInternalButtonState (bindings).Down;
|
||||
}
|
103
src/poll.h
Normal file
103
src/poll.h
Normal file
@ -0,0 +1,103 @@
|
||||
#include <SDL.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <toml.h>
|
||||
#include <windows.h>
|
||||
|
||||
enum SDLAxis {
|
||||
SDL_AXIS_NULL,
|
||||
SDL_AXIS_LEFT_LEFT,
|
||||
SDL_AXIS_LEFT_RIGHT,
|
||||
SDL_AXIS_LEFT_UP,
|
||||
SDL_AXIS_LEFT_DOWN,
|
||||
SDL_AXIS_RIGHT_LEFT,
|
||||
SDL_AXIS_RIGHT_RIGHT,
|
||||
SDL_AXIS_RIGHT_UP,
|
||||
SDL_AXIS_RIGHT_DOWN,
|
||||
SDL_AXIS_LTRIGGER_DOWN,
|
||||
SDL_AXIS_RTRIGGER_DOWN,
|
||||
SDL_AXIS_MAX
|
||||
};
|
||||
|
||||
struct SDLAxisState {
|
||||
unsigned int LeftLeft : 1;
|
||||
unsigned int LeftRight : 1;
|
||||
unsigned int LeftUp : 1;
|
||||
unsigned int LeftDown : 1;
|
||||
unsigned int RightLeft : 1;
|
||||
unsigned int RightRight : 1;
|
||||
unsigned int RightUp : 1;
|
||||
unsigned int RightDown : 1;
|
||||
unsigned int LTriggerDown : 1;
|
||||
unsigned int RTriggerDown : 1;
|
||||
};
|
||||
|
||||
enum Scroll { MOUSE_SCROLL_INVALID, MOUSE_SCROLL_UP, MOUSE_SCROLL_DOWN };
|
||||
|
||||
struct Keybindings {
|
||||
uint8_t keycodes[255];
|
||||
SDL_GameControllerButton buttons[255];
|
||||
enum SDLAxis axis[255];
|
||||
enum Scroll scroll[2];
|
||||
};
|
||||
|
||||
enum EnumType { none, keycode, button, axis, scroll };
|
||||
|
||||
struct ConfigValue {
|
||||
enum EnumType type;
|
||||
uint8_t keycode;
|
||||
SDL_GameControllerButton button;
|
||||
enum SDLAxis axis;
|
||||
enum Scroll scroll;
|
||||
};
|
||||
|
||||
struct InternalButtonState {
|
||||
unsigned int Released : 1;
|
||||
unsigned int Down : 1;
|
||||
unsigned int Tapped : 1;
|
||||
};
|
||||
|
||||
bool InitializePoll (void *DivaWindowHandle);
|
||||
void UpdatePoll (void *DivaWindowHandle);
|
||||
void DisposePoll ();
|
||||
|
||||
struct ConfigValue StringToConfigEnum (char *value);
|
||||
void SetConfigValue (toml_table_t *table, char *key,
|
||||
struct Keybindings *keybind);
|
||||
struct InternalButtonState
|
||||
GetInternalButtonState (struct Keybindings bindings);
|
||||
void SetRumble (int left, int right);
|
||||
|
||||
bool KeyboardIsDown (uint8_t keycode);
|
||||
bool KeyboardIsUp (uint8_t keycode);
|
||||
bool KeyboardIsTapped (uint8_t keycode);
|
||||
bool KeyboardIsReleased (uint8_t keycode);
|
||||
bool KeyboardWasDown (uint8_t keycode);
|
||||
bool KeyboardWasUp (uint8_t keycode);
|
||||
POINT GetMousePosition ();
|
||||
POINT GetLastMousePosition ();
|
||||
POINT GetMouseRelativePosition ();
|
||||
POINT GetLastMouseRelativePosition ();
|
||||
void SetMousePosition (POINT new);
|
||||
bool GetMouseScrollUp ();
|
||||
bool GetMouseScrollDown ();
|
||||
bool GetWasMouseScrollUp ();
|
||||
bool GetWasMouseScrollDown ();
|
||||
bool GetMouseScrollIsReleased (enum Scroll scroll);
|
||||
bool GetMouseScrollIsDown (enum Scroll scroll);
|
||||
bool GetMouseScrollIsTapped (enum Scroll scroll);
|
||||
bool ControllerButtonIsDown (SDL_GameControllerButton button);
|
||||
bool ControllerButtonIsUp (SDL_GameControllerButton button);
|
||||
bool ControllerButtonWasDown (SDL_GameControllerButton button);
|
||||
bool ControllerButtonWasUp (SDL_GameControllerButton button);
|
||||
bool ControllerButtonIsTapped (SDL_GameControllerButton button);
|
||||
bool ControllerButtonIsReleased (SDL_GameControllerButton button);
|
||||
bool ControllerAxisIsDown (enum SDLAxis axis);
|
||||
bool ControllerAxisIsUp (enum SDLAxis axis);
|
||||
bool ControllerAxisWasDown (enum SDLAxis axis);
|
||||
bool ControllerAxisWasUp (enum SDLAxis axis);
|
||||
bool ControllerAxisIsTapped (enum SDLAxis axis);
|
||||
bool ControllerAxisIsReleased (enum SDLAxis axis);
|
||||
bool IsButtonTapped (struct Keybindings bindings);
|
||||
bool IsButtonReleased (struct Keybindings bindings);
|
||||
bool IsButtonDown (struct Keybindings bindings);
|
1
tomlc99
Submodule
1
tomlc99
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 034b23ed3e4e5ee5345040eabed470f204d7f668
|
Loading…
x
Reference in New Issue
Block a user