Initial refactor
cards.dat has been replaced with cards.ini there are no more plugins though plugin support still exists card reading is not yet implemented 08.18/amauth support is not yet implemented
This commit is contained in:
parent
4ff4324cb1
commit
b119478ce3
@ -1,13 +1,21 @@
|
||||
BasedOnStyle: GNU
|
||||
BasedOnStyle: LLVM
|
||||
IndentWidth: 4
|
||||
TabWidth: 4
|
||||
UseTab: ForIndentation
|
||||
IndentCaseLabels: False
|
||||
BreakBeforeBraces: Attach
|
||||
ColumnLimit: 150
|
||||
ColumnLimit: 200
|
||||
AlignConsecutiveAssignments: Consecutive
|
||||
AlignConsecutiveMacros: Consecutive
|
||||
AllowShortBlocksOnASingleLine: Always
|
||||
AllowShortCaseLabelsOnASingleLine: True
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: AllIfsAndElse
|
||||
AllowShortIfStatementsOnASingleLine: AllIfsAndElse
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
SpaceAfterTemplateKeyword: True
|
||||
SpacesInAngles: Never
|
||||
SpaceBeforeParens: Always
|
||||
AlwaysBreakAfterReturnType: TopLevelDefinitions
|
||||
RemoveBracesLLVM: True
|
||||
AlignEscapedNewlines: Left
|
||||
AccessModifierOffset: -4
|
||||
|
@ -1,5 +1,3 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
indent_size = 4
|
||||
|
6
.github/workflows/build.yml
vendored
6
.github/workflows/build.yml
vendored
@ -4,15 +4,15 @@ on: [ push, pull_request ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Install depends
|
||||
run: sudo apt-get install -y mingw-w64 clang
|
||||
run: sudo apt-get install -y mingw-w64 ninja-build nasm; pip3 install meson
|
||||
- name: Make
|
||||
run: make dist-no-7z
|
||||
run: make setup dist-no-7z
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: dist
|
||||
|
13
.gitignore
vendored
13
.gitignore
vendored
@ -1,6 +1,9 @@
|
||||
x86_64-pc-windows
|
||||
*.o
|
||||
*.dll
|
||||
*.7z
|
||||
.cache
|
||||
build/
|
||||
compile_commands.json
|
||||
.cache
|
||||
subprojects/minhook
|
||||
subprojects/packagecache
|
||||
subprojects/tomlc99
|
||||
subprojects/SDL2-2.26.5
|
||||
subprojects/xxHash-0.8.2
|
||||
dist.7z
|
||||
|
9
.gitmodules
vendored
9
.gitmodules
vendored
@ -1,9 +0,0 @@
|
||||
[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
|
81
Makefile
81
Makefile
@ -1,66 +1,15 @@
|
||||
OUT = TAL
|
||||
CC = x86_64-w64-mingw32-gcc
|
||||
TARGET = x86_64-pc-windows-gnu
|
||||
SRC = src/dllmain.c src/helpers.c src/poll.c src/boilerplate.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/include -ISDL/build/include -Itomlc99 -Wall -Ofast -DWIN32_LEAN_AND_MEAN -D_WIN32_WINNT=_WIN32_WINNT_WIN7
|
||||
LDFLAGS = -shared -static -static-libgcc -s
|
||||
LIBS = SDL/build/libSDL3.a SDL/build/libSDL3_main.a -lmingw32 -luuid -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lsetupapi -lversion
|
||||
DEPS = SDL
|
||||
|
||||
all: options ${OUT} plugins
|
||||
|
||||
.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: SDL
|
||||
SDL:
|
||||
@cd SDL && cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=build-scripts/cmake-toolchain-mingw64-x86_64.cmake && cmake --build build
|
||||
|
||||
.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
|
||||
@cd plugins/8.18 && clang-format -i *.c -style=file
|
||||
@cd plugins/amauth && clang-format -i *.c -style=file
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf ${TARGET}
|
||||
|
||||
.PHONY: plugins
|
||||
plugins:
|
||||
make -C plugins/8.18
|
||||
make -C plugins/amauth
|
||||
strip ${TARGET}/*.dll
|
||||
|
||||
.PHONY: dist-no-7z
|
||||
dist-no-7z: options ${OUT} plugins
|
||||
mkdir -p out/plugins
|
||||
cp ${TARGET}/${OUT}.dll out/
|
||||
mv out/${OUT}.dll out/bnusio.dll
|
||||
cp ${TARGET}/patches.*.dll out/plugins
|
||||
cp ${TARGET}/amauth.dll out/plugins
|
||||
cp -r dist/* out/
|
||||
|
||||
.PHONY: dist
|
||||
dist: dist-no-7z
|
||||
cd out && 7z a -t7z ../${OUT}.7z .
|
||||
rm -rf out
|
||||
all:
|
||||
@meson compile -C build
|
||||
@strip build/bnusio.dll
|
||||
|
||||
setup:
|
||||
@meson setup build --cross cross-mingw-64.txt
|
||||
|
||||
dist-no-7z: all
|
||||
@mkdir -p out/
|
||||
@cp build/bnusio.dll out/
|
||||
@cp -r dist/* out/
|
||||
|
||||
dist: dist-no-7z
|
||||
@cd out && 7z a -t7z ../dist.7z .
|
||||
@rm -rf out
|
||||
|
21
PLUGINS.md
21
PLUGINS.md
@ -2,10 +2,6 @@
|
||||
|
||||
Plugins are just libraries with certain exported functions that go in the plugins folder.
|
||||
|
||||
```
|
||||
void PreInit()
|
||||
```
|
||||
Runs in dllmain, may run into loader locks. You can also just use your own dllmain for this but that involves writing out all the arguments.
|
||||
```
|
||||
void Init()
|
||||
```
|
||||
@ -30,18 +26,7 @@ callback(0, 0, cardData, data);
|
||||
```
|
||||
|
||||
```
|
||||
void Card1Insert()
|
||||
void CardInsert()
|
||||
```
|
||||
Runs when user presses CARD_INSERT_1, causes TAL to not insert a card if any plugins have this present
|
||||
```
|
||||
void Card2Insert()
|
||||
```
|
||||
Runs when user presses CARD_INSERT_2, causes TAL to not insert a card if any plugins have this present
|
||||
```
|
||||
void BeforeCard1Insert()
|
||||
```
|
||||
Runs before CARD_INSERT_1 is handled
|
||||
```
|
||||
void BeforeCard2Insert()
|
||||
```
|
||||
Runs before CARD_INSERT_2 is handled
|
||||
Runs when user presses CARD_INSERT, causes TAL to not insert a card if any plugins have this present
|
||||
void BeforeCardInsert()
|
||||
|
1
SDL
1
SDL
@ -1 +0,0 @@
|
||||
Subproject commit 180afcdf3998e5175b744d3f2d87147802809450
|
12
cross-mingw-64.txt
Normal file
12
cross-mingw-64.txt
Normal file
@ -0,0 +1,12 @@
|
||||
[binaries]
|
||||
c = 'x86_64-w64-mingw32-gcc'
|
||||
cpp = 'x86_64-w64-mingw32-g++'
|
||||
ar = 'x86_64-w64-mingw32-ar'
|
||||
strip = 'x86_64-w64-mingw32-strip'
|
||||
nasm = 'nasm'
|
||||
|
||||
[host_machine]
|
||||
system = 'windows'
|
||||
cpu_family = 'x86_64'
|
||||
cpu = 'x86_64'
|
||||
endian = 'little'
|
11
dist/config.toml
vendored
11
dist/config.toml
vendored
@ -1,6 +1,5 @@
|
||||
# Values for random drum hit amounts
|
||||
drumMax = 20000
|
||||
drumMin = 10000
|
||||
|
||||
server = "127.0.0.1"
|
||||
pcb_id = "TAL0000001"
|
||||
server = "127.0.0.1"
|
||||
res = { x = 1360, y = 768 }
|
||||
unlock_songs = true
|
||||
shared_audio = true
|
||||
vsync = false
|
||||
|
3765
dist/gamecontrollerdb.txt
vendored
3765
dist/gamecontrollerdb.txt
vendored
File diff suppressed because it is too large
Load Diff
3
dist/keyconfig.toml
vendored
3
dist/keyconfig.toml
vendored
@ -7,8 +7,7 @@ DEBUG_DOWN = ["DOWNARROW"]
|
||||
DEBUG_ENTER = ["ENTER"]
|
||||
|
||||
COIN_ADD = ["ENTER", "SDL_START"]
|
||||
CARD_INSERT_1 = ["P"]
|
||||
CARD_INSERT_2 = []
|
||||
CARD_INSERT = ["P"]
|
||||
|
||||
P1_LEFT_BLUE = ["D", "SDL_LTRIGGER"]
|
||||
P1_LEFT_RED = ["F", "SDL_LSTICK_PRESS"]
|
||||
|
4
dist/plugins/patches.toml
vendored
4
dist/plugins/patches.toml
vendored
@ -1,4 +0,0 @@
|
||||
unlock_songs = true
|
||||
shared_audio = true
|
||||
vsync = false
|
||||
windowRes = { x = 1920, y = 1080 }
|
59
meson.build
Normal file
59
meson.build
Normal file
@ -0,0 +1,59 @@
|
||||
project('TaikoArcadeLoader', 'c', 'cpp', 'nasm', version: '1.0.0')
|
||||
warning_level = 3
|
||||
debug = true
|
||||
optimization = 3
|
||||
b_lto = true
|
||||
b_pgo = 'use'
|
||||
cpp_std = 'c++20'
|
||||
|
||||
cpp = meson.get_compiler('cpp')
|
||||
|
||||
add_project_arguments(
|
||||
cpp.get_supported_arguments(
|
||||
'-D_WIN32_WINNT=_WIN32_WINNT_WIN10',
|
||||
'-std=c++20',
|
||||
'-Werror',
|
||||
),
|
||||
language: 'cpp',
|
||||
)
|
||||
|
||||
add_project_link_arguments(
|
||||
cpp.get_supported_arguments(
|
||||
'-static',
|
||||
#'-s',
|
||||
'-lws2_32',
|
||||
'-lssp',
|
||||
),
|
||||
language: 'cpp',
|
||||
)
|
||||
|
||||
minhook = subproject('minhook')
|
||||
tomlc99 = subproject('tomlc99')
|
||||
sdl2 = subproject('sdl2', default_options: ['default_library=static', 'test=false', 'use_render=disabled'])
|
||||
xxhash = subproject('xxhash', default_options: ['default_library=static', 'cli=false'])
|
||||
|
||||
library(
|
||||
'bnusio',
|
||||
link_with: [
|
||||
minhook.get_variable('minhook_lib'),
|
||||
tomlc99.get_variable('tomlc99_lib'),
|
||||
sdl2.get_variable('sdl2'),
|
||||
xxhash.get_variable('xxhash'),
|
||||
],
|
||||
include_directories: [
|
||||
'src',
|
||||
minhook.get_variable('minhook_inc'),
|
||||
tomlc99.get_variable('tomlc99_inc'),
|
||||
sdl2.get_variable('core_inc'),
|
||||
xxhash.get_variable('inc'),
|
||||
],
|
||||
sources : [
|
||||
'src/dllmain.cpp',
|
||||
'src/helpers.cpp',
|
||||
'src/poll.cpp',
|
||||
'src/bnusio.cpp',
|
||||
'src/patches/jp_nov_2020.cpp',
|
||||
'src/patches/cn_jun_2023.cpp',
|
||||
],
|
||||
name_prefix: ''
|
||||
)
|
1
minhook
1
minhook
@ -1 +0,0 @@
|
||||
Subproject commit 426cb6880035ee3cceed05384bb3f2db01a20a15
|
@ -1,31 +0,0 @@
|
||||
OUT = patches.8.18
|
||||
CC = clang
|
||||
TARGET = x86_64-pc-windows-gnu
|
||||
SRC = dllmain.c
|
||||
OBJ = ${addprefix ../../${TARGET}/plugins/8.18/,${SRC:.c=.o}}
|
||||
EXTERN_SRC = src/helpers.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
|
||||
EXTERN_OBJ = ${addprefix ../../${TARGET}/,${EXTERN_SRC:.c=.o}}
|
||||
CFLAGS = -std=c99 -I../../src -I../../minhook/include -I../../tomlc99 -Wall -Ofast -target ${TARGET} -DWIN32_LEAN_AND_MEAN -D_WIN32_WINNT=_WIN32_WINNT_WIN7
|
||||
LDFLAGS = -shared -static -static-libgcc -s
|
||||
LIBS = -lmingw32 -luuid -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lsetupapi -lversion
|
||||
|
||||
all: options ${OUT}
|
||||
|
||||
.PHONY: dirs
|
||||
dirs:
|
||||
@mkdir -p ../../${TARGET}/plugins/8.18
|
||||
|
||||
.PHONY: options
|
||||
options:
|
||||
@echo "CFLAGS = ${CFLAGS}"
|
||||
@echo "LDFLAGS = ${LDFLAGS}"
|
||||
@echo "CC = ${CC}"
|
||||
|
||||
../../${TARGET}/plugins/8.18/%.o: %.c
|
||||
@echo BUILD $@
|
||||
@${CC} -c ${CFLAGS} $< -o $@
|
||||
|
||||
.PHONY: ${OUT}
|
||||
${OUT}: dirs ${OBJ}
|
||||
@echo LINK $@
|
||||
@${CC} ${CFLAGS} -o ../../${TARGET}/$@.dll ${OBJ} ${EXTERN_OBJ} ${LDFLAGS} ${LIBS}
|
@ -1,137 +0,0 @@
|
||||
#define BASE_ADDRESS 0x140000000
|
||||
#include "helpers.h"
|
||||
|
||||
const u64 song_data_size = 1024 * 1024 * 64;
|
||||
void *song_data;
|
||||
|
||||
#define RDX_MOV 0x48, 0xBA
|
||||
#define R8_MOV 0x49, 0xB8
|
||||
#define GENERATE_MOV(instruction, location) \
|
||||
instruction, (u8)(u64)(location), (u8)((u64)(location) >> 8), (u8)((u64)(location) >> 16), (u8)((u64)(location) >> 24), \
|
||||
(u8)((u64)(location) >> 32), (u8)((u64)(location) >> 40), (u8)((u64)(location) >> 48), (u8)((u64)(location) >> 56)
|
||||
|
||||
HOOK_DYNAMIC (u8, __fastcall, qrVtable1, u64 a1) { return 1; }
|
||||
HOOK_DYNAMIC (u8, __fastcall, qrReadFromCOM1, u64 a1) {
|
||||
*(u32 *)(a1 + 40) = 1;
|
||||
*(u32 *)(a1 + 16) = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
PreInit () {
|
||||
toml_table_t *config = openConfig (configPath ("plugins/patches.toml"));
|
||||
if (!config) return;
|
||||
void *handle = GetModuleHandle (0);
|
||||
WRITE_MEMORY (ASLR (0x1400239C0, handle), u8, 0xC3); // Stop error
|
||||
if (readConfigBool (config, "unlock_songs", true)) WRITE_MEMORY (ASLR (0x140314E8D, handle), u8, 0xB0, 0x01); // Unlock songs
|
||||
if (readConfigBool (config, "shared_audio", true)) WRITE_MEMORY (ASLR (0x140692E17, handle), u8, 0xEB); // Shared audio
|
||||
if (!readConfigBool (config, "vsync", false)) WRITE_MEMORY (ASLR (0x140517339, handle), u8, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x90); // Disable VSync
|
||||
// Remove song limit
|
||||
WRITE_MEMORY (ASLR (0x140313726, handle), i32, 9000);
|
||||
// Remove for with server
|
||||
WRITE_MEMORY (ASLR (0x1402F39E6, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1402F3AB0, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1402F3BE4, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x14030643B, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140306507, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1403065D3, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1403066FB, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1403067C7, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140306893, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x14030698B, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140313666, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1403139F4, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140313B04, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140313C24, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140313CF4, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1403140C4, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1403147AA, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140225FB6, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140226146, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140314DCC, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140314EC9, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140338E2C, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1400EE0A4, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1400EE8B5, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1400EEDA6, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140315608, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x14034A7EB, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1402F3CB3, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140314059, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140226063, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x14022609F, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140226296, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140306A2E, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140314F46, handle), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140314F97, handle), i32, 9000);
|
||||
|
||||
song_data = malloc (song_data_size);
|
||||
memset (song_data, 0, song_data_size);
|
||||
|
||||
// Song data
|
||||
WRITE_MEMORY (ASLR (0x14031367B, handle), u8, GENERATE_MOV (R8_MOV, song_data));
|
||||
// Crown data
|
||||
WRITE_MEMORY (ASLR (0x1402F3AC6, handle), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x1402F39FC, handle), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x1402F3BFA, handle), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x1403140D7, handle), u8, GENERATE_MOV (R8_MOV, song_data));
|
||||
// Score ranks
|
||||
WRITE_MEMORY (ASLR (0x1403065EA, handle), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x14030651E, handle), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x140306452, handle), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x1403068AA, handle), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x1403067DE, handle), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x140306712, handle), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x1403069A2, handle), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
// Unknown
|
||||
WRITE_MEMORY (ASLR (0x140313755, handle), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x140313A0B, handle), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x140313B4C, handle), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x140313D38, handle), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x140313C42, handle), u8, GENERATE_MOV (R8_MOV, song_data));
|
||||
|
||||
// Save settings cross session without F:/ and G:/ drive
|
||||
WRITE_MEMORY (ASLR (0x140B5C528, handle), char, "./Setting1.bin");
|
||||
WRITE_MEMORY (ASLR (0x140B5C538, handle), char, "./Setting2.bin");
|
||||
// Move F:/ files to current directory
|
||||
WRITE_MEMORY (ASLR (0x140B1B4B0, handle), char, "./");
|
||||
WRITE_MEMORY (ASLR (0x14001C941, handle), u8, 0x02);
|
||||
// Patch TLS v1.0 to v1.2
|
||||
WRITE_MEMORY (ASLR (0x14044B1A9, handle), u8, 0x10);
|
||||
|
||||
toml_table_t *windowResSection = openConfigSection (config, "windowRes");
|
||||
if (windowResSection) {
|
||||
i32 windowResX = readConfigInt (windowResSection, "x", 0);
|
||||
i32 windowResY = readConfigInt (windowResSection, "y", 0);
|
||||
if (windowResX > 0 && windowResY > 0) {
|
||||
WRITE_MEMORY (ASLR (0x14035FC5B, handle), i32, windowResX);
|
||||
WRITE_MEMORY (ASLR (0x14035FC62, handle), i32, windowResY);
|
||||
}
|
||||
}
|
||||
|
||||
toml_free (config);
|
||||
|
||||
// Move various files to current directory
|
||||
void *amHandle = GetModuleHandle ("AMFrameWork.dll");
|
||||
WRITE_MEMORY (amHandle + 0x33EF7, u8, 0xEB);
|
||||
WRITE_MEMORY (amHandle + 0x3404A, u8, 0xEB);
|
||||
WRITE_MEMORY (amHandle + 0x34429, u8, 0xEB);
|
||||
WRITE_MEMORY (amHandle + 0x3457C, u8, 0xEB);
|
||||
WRITE_MEMORY (amHandle + 0x3497A, u8, 0xEB);
|
||||
WRITE_MEMORY (amHandle + 0x34ACD, u8, 0xEB);
|
||||
WRITE_MEMORY (amHandle + 0x148AF, u8, 0xEB);
|
||||
WRITE_MEMORY (amHandle + 0x14A1A, u8, 0xEB);
|
||||
|
||||
INSTALL_HOOK_DYNAMIC (qrVtable1, amHandle + 0x1BA00);
|
||||
INSTALL_HOOK_DYNAMIC (qrReadFromCOM1, amHandle + 0x1BC20);
|
||||
}
|
||||
|
||||
void
|
||||
BeforeCard1Insert () {
|
||||
memset (song_data, 0, song_data_size);
|
||||
}
|
||||
|
||||
void
|
||||
BeforeCard2Insert () {
|
||||
memset (song_data, 0, song_data_size);
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
OUT = amauth
|
||||
CXX := x86_64-w64-mingw32-g++
|
||||
TARGET := x86_64-pc-windows-gnu
|
||||
SRC = dllmain.cpp
|
||||
OBJ = ${addprefix ../../${TARGET}/plugins/amauth/,${SRC:.cpp=.o}}
|
||||
EXTERN_SRC = src/helpers.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
|
||||
EXTERN_OBJ = ${addprefix ../../${TARGET}/,${EXTERN_SRC:.c=.o}}
|
||||
CXXFLAGS = -std=c++11 -I../../src -I../../minhook/include -I../../tomlc99 -Wall -Ofast -DWIN32_LEAN_AND_MEAN -D_WIN32_WINNT=_WIN32_WINNT_WIN7
|
||||
LDFLAGS := -shared -static -static-libgcc -s
|
||||
LIBS := -lmingw32 -luuid -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lsetupapi -lversion -lws2_32
|
||||
|
||||
all: options ${OUT}
|
||||
|
||||
.PHONY: dirs
|
||||
dirs:
|
||||
@mkdir -p ../../${TARGET}/plugins/amauth
|
||||
|
||||
.PHONY: options
|
||||
options:
|
||||
@echo "CFLAGS = ${CFLAGS}"
|
||||
@echo "LDFLAGS = ${LDFLAGS}"
|
||||
@echo "CXX = ${CXX}"
|
||||
|
||||
../../${TARGET}/plugins/amauth/%.o: %.cpp
|
||||
@echo BUILD $@
|
||||
@${CXX} -c ${CXXFLAGS} $< -o $@
|
||||
|
||||
.PHONY: ${OUT}
|
||||
${OUT}: dirs ${OBJ}
|
||||
@echo LINK $@
|
||||
@${CXX} ${CXXFLAGS} -o ../../${TARGET}/$@.dll ${OBJ} ${EXTERN_OBJ} ${LDFLAGS} ${LIBS}
|
@ -1,363 +0,0 @@
|
||||
// Here be lions
|
||||
// The following code is shit
|
||||
// It attempts to recreate the functionality of AMAuthd
|
||||
// However some of this functionality is needless
|
||||
#include <unknwn.h>
|
||||
#include <ws2tcpip.h>
|
||||
// Needs to be after for DEFINE_GUID
|
||||
#include "helpers.h"
|
||||
|
||||
DWORD reg = 0;
|
||||
char server_ip[0x10];
|
||||
char *server_hostname = (char *)"127.0.0.1";
|
||||
char *pcb_id = (char *)"TAL0000001";
|
||||
|
||||
DEFINE_GUID (IID_CAuthFactory, 0x4603BB03, 0x058D, 0x43D9, 0xB9, 0x6F, 0x63, 0x9B, 0xE9, 0x08, 0xC1, 0xED);
|
||||
DEFINE_GUID (IID_CAuth, 0x045A5150, 0xD2B3, 0x4590, 0xA3, 0x8B, 0xC1, 0x15, 0x86, 0x78, 0xE1, 0xAC);
|
||||
|
||||
class CAuth : public IUnknown {
|
||||
public:
|
||||
STDMETHODIMP
|
||||
QueryInterface (REFIID riid, LPVOID *ppvObj) {
|
||||
wchar_t *iid_str;
|
||||
StringFromCLSID (riid, &iid_str);
|
||||
printf ("QueryInterface %ls\n", iid_str);
|
||||
|
||||
if (riid == IID_IUnknown || riid == IID_CAuth) {
|
||||
*ppvObj = this;
|
||||
this->AddRef ();
|
||||
return 0;
|
||||
} else {
|
||||
*ppvObj = 0;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
}
|
||||
STDMETHODIMP_ (ULONG) AddRef () { return this->refCount++; }
|
||||
STDMETHODIMP_ (ULONG) Release () {
|
||||
this->refCount--;
|
||||
if (this->refCount <= 0) {
|
||||
// delete this;
|
||||
return 0;
|
||||
}
|
||||
return this->refCount;
|
||||
}
|
||||
|
||||
virtual i64
|
||||
Unk3 (u32 a1) {
|
||||
return 1;
|
||||
}
|
||||
virtual i64
|
||||
Unk4 () {
|
||||
return 1;
|
||||
}
|
||||
virtual i32
|
||||
Unk5 () {
|
||||
return 0;
|
||||
}
|
||||
virtual i64
|
||||
Unk6 () {
|
||||
return 1;
|
||||
}
|
||||
virtual i32
|
||||
Unk7 () {
|
||||
return 0;
|
||||
}
|
||||
virtual i32
|
||||
Unk8 () {
|
||||
return 0;
|
||||
}
|
||||
virtual i32
|
||||
Unk9 (i32 *a1) {
|
||||
memset (a1, 0, sizeof (i32) * 0x31);
|
||||
a1[0] = 15;
|
||||
a1[2] = 2;
|
||||
a1[3] = 1;
|
||||
a1[6] = 9;
|
||||
a1[8] = 2;
|
||||
a1[9] = 1;
|
||||
a1[10] = 27;
|
||||
a1[11] = 33;
|
||||
a1[12] = 41;
|
||||
a1[13] = 50;
|
||||
a1[14] = 59;
|
||||
a1[15] = 1179656;
|
||||
a1[30] = 1;
|
||||
a1[46] = 1;
|
||||
a1[47] = 3;
|
||||
a1[48] = 9;
|
||||
return 0;
|
||||
}
|
||||
virtual i32
|
||||
Unk10 (char *a1) {
|
||||
memset (a1, 0, 0xB0);
|
||||
strncpy_s (a1, 0x10, "STANDALONE", 0xF);
|
||||
strncpy_s (a1 + 0x10, 0x10, pcb_id, 0xF); // PCB ID
|
||||
strncpy_s (a1 + 0x20, 0x10, "000000-00000", 0xF); // ignored by game
|
||||
strncpy_s (a1 + 0x30, 0x10, server_ip, 0xF);
|
||||
strncpy_s (a1 + 0x40, 0x10, server_ip, 0xF);
|
||||
strncpy_s (a1 + 0x50, 0x10, server_ip, 0xF);
|
||||
strncpy_s (a1 + 0x60, 0x10, "***.***.***.***", 0xF); // Subnet mask
|
||||
strncpy_s (a1 + 0x70, 0x10, "***.***.***.***", 0xF); // GATEWAY
|
||||
strncpy_s (a1 + 0x80, 0x10, "***.***.***.***", 0xF); // PRIMARY DNS
|
||||
return 0;
|
||||
}
|
||||
virtual i32
|
||||
Unk11 (char *a1) {
|
||||
memset (a1, 0, 0x13C);
|
||||
strncpy_s (a1, 4, "1", 3);
|
||||
strncpy_s (a1 + 4, 0x10, "ALLNET", 0xF);
|
||||
strncpy_s (a1 + 20, 8, "SBWY", 7);
|
||||
strncpy_s (a1 + 28, 8, "12.00", 7);
|
||||
strncpy_s (a1 + 36, 8, "TAL0", 7); // ignored by game
|
||||
strncpy_s (a1 + 44, 8, "08.18", 7); // GAME VERSION
|
||||
strncpy_s (a1 + 52, 4, "0", 3);
|
||||
strncpy_s (a1 + 56, 4, "PCB", 3);
|
||||
return 0;
|
||||
}
|
||||
virtual i32
|
||||
Unk12 () {
|
||||
return 1;
|
||||
}
|
||||
virtual i32
|
||||
Unk13 () {
|
||||
return 1;
|
||||
}
|
||||
virtual i32
|
||||
Unk14 (char *a1) {
|
||||
memset (a1, 0, 0x8A2);
|
||||
strncpy_s (a1, 0x101, server_hostname, 0x100);
|
||||
strncpy_s (a1 + 0x101, 0x101, server_hostname, 0x100);
|
||||
strncpy_s (a1 + 0x202, 0x100, "TAIKO ARCADE LOADER", 0xFF); // ALL.Net SHOP NAME
|
||||
strncpy_s (a1 + 0x302, 0x100, "TAIKO ARCADE LOADER", 0xFF);
|
||||
strncpy_s (a1 + 0x402, 0x10, "1", 0xF);
|
||||
strncpy_s (a1 + 0x412, 0x100, "TAIKO ARCADE LOADER", 0xFF);
|
||||
strncpy_s (a1 + 0x512, 0x100, "X", 0xFF);
|
||||
strncpy_s (a1 + 0x612, 0x100, "Y", 0xFF);
|
||||
strncpy_s (a1 + 0x712, 0x100, "Z", 0xFF);
|
||||
strncpy_s (a1 + 0x812, 0x10, "JPN0123", 0xF);
|
||||
strncpy_s (a1 + 0x832, 0x10, "JPN", 0xF);
|
||||
strncpy_s (a1 + 0x842, 0x10, "002,00", 0xF);
|
||||
strncpy_s (a1 + 0x842, 0x10, "PowerOnResponseVer2", 0xF);
|
||||
return 0;
|
||||
}
|
||||
virtual i32
|
||||
Unk15 () {
|
||||
return 0;
|
||||
}
|
||||
virtual i32
|
||||
Unk16 () {
|
||||
return 0;
|
||||
}
|
||||
virtual i32
|
||||
Unk17 () {
|
||||
return 0;
|
||||
}
|
||||
virtual i32
|
||||
Unk18 (void *a1) {
|
||||
return 0;
|
||||
}
|
||||
virtual i32
|
||||
Unk19 (u8 *a1) {
|
||||
memset (a1, 0, 0x38);
|
||||
a1[0] = 1;
|
||||
return 1;
|
||||
}
|
||||
virtual i32
|
||||
Unk20 () {
|
||||
return 0;
|
||||
}
|
||||
virtual i32
|
||||
Unk21 () {
|
||||
return 1;
|
||||
}
|
||||
virtual i32
|
||||
Unk22 () {
|
||||
return 0;
|
||||
}
|
||||
virtual i32
|
||||
Unk23 () {
|
||||
return 0;
|
||||
}
|
||||
virtual i32
|
||||
Unk24 () {
|
||||
return 0;
|
||||
}
|
||||
virtual i32
|
||||
Unk25 () {
|
||||
return 1;
|
||||
}
|
||||
virtual i32
|
||||
Unk26 () {
|
||||
return 0;
|
||||
}
|
||||
virtual i32
|
||||
Unk27 () {
|
||||
return 1;
|
||||
}
|
||||
virtual i32
|
||||
Unk28 () {
|
||||
return 0;
|
||||
}
|
||||
virtual i32
|
||||
Unk29 () {
|
||||
return 0;
|
||||
}
|
||||
virtual i32
|
||||
Unk30 () {
|
||||
return 0;
|
||||
}
|
||||
virtual i32
|
||||
PrintDebugInfo () {
|
||||
return 0;
|
||||
}
|
||||
virtual i32
|
||||
Unk32 (void *a1) {
|
||||
return 0;
|
||||
}
|
||||
virtual void
|
||||
Unk33 () {}
|
||||
|
||||
public:
|
||||
CAuth () {}
|
||||
virtual ~CAuth () {}
|
||||
|
||||
private:
|
||||
i32 refCount = 0;
|
||||
};
|
||||
|
||||
class CAuthFactory : public IClassFactory {
|
||||
public:
|
||||
STDMETHODIMP
|
||||
QueryInterface (REFIID riid, LPVOID *ppvObj) {
|
||||
wchar_t *iid_str;
|
||||
StringFromCLSID (riid, &iid_str);
|
||||
printf ("QueryInterface %ls\n", iid_str);
|
||||
|
||||
if (riid == IID_IUnknown || riid == IID_IClassFactory || riid == IID_CAuthFactory) {
|
||||
*ppvObj = this;
|
||||
return 0;
|
||||
} else {
|
||||
*ppvObj = 0;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
}
|
||||
STDMETHODIMP_ (ULONG) AddRef () { return 2; }
|
||||
STDMETHODIMP_ (ULONG) Release () { return 1; }
|
||||
virtual HRESULT
|
||||
CreateInstance (IUnknown *outer, REFIID riid, void **object) {
|
||||
if (outer != 0) return CLASS_E_NOAGGREGATION;
|
||||
wchar_t *iid_str;
|
||||
StringFromCLSID (riid, &iid_str);
|
||||
printf ("CreateInstance %ls\n", iid_str);
|
||||
CAuth *auth = new CAuth ();
|
||||
return auth->QueryInterface (riid, object);
|
||||
}
|
||||
virtual HRESULT
|
||||
LockServer (i32 lock) {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
void
|
||||
Init () {
|
||||
CoInitializeEx (0, 0);
|
||||
CoRegisterClassObject (IID_CAuthFactory, (IUnknown *)new CAuthFactory (), CLSCTX_LOCAL_SERVER, 1, ®);
|
||||
toml_table_t *config = openConfig (configPath ((char *)"config.toml"));
|
||||
if (config) {
|
||||
server_hostname = readConfigString (config, (char *)"server", server_hostname);
|
||||
pcb_id = readConfigString (config, (char *)"pcb_id", pcb_id);
|
||||
// Get ipv4 address of server
|
||||
struct addrinfo *res = 0;
|
||||
getaddrinfo (server_hostname, "", 0, &res);
|
||||
for (struct addrinfo *i = res; i != 0; i = i->ai_next) {
|
||||
if (res->ai_addr->sa_family != AF_INET) { continue; }
|
||||
struct sockaddr_in *p = (struct sockaddr_in *)res->ai_addr;
|
||||
inet_ntop (AF_INET, &p->sin_addr, server_ip, 0x10);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Exit () {
|
||||
CoRevokeClassObject (reg);
|
||||
CoUninitialize ();
|
||||
}
|
||||
|
||||
void
|
||||
Test () {
|
||||
i32 res;
|
||||
CoInitializeEx (0, 0);
|
||||
CAuth *auth;
|
||||
res = CoCreateInstance (IID_CAuthFactory, 0, 4, IID_CAuth, (void **)&auth);
|
||||
if (res != S_OK) {
|
||||
printf ("AMAuthd not running %x\n", res);
|
||||
CoUninitialize ();
|
||||
return;
|
||||
}
|
||||
auth->AddRef ();
|
||||
|
||||
i32 *unk9 = (i32 *)malloc (sizeof (i32) * 0x50);
|
||||
memset (unk9, 0, sizeof (i32) * 0x50);
|
||||
res = auth->Unk9 (unk9);
|
||||
printf ("unk9: %d\n", res);
|
||||
for (int i = 0; i < 0x50; i++) {
|
||||
printf ("%d\n", unk9[i]);
|
||||
}
|
||||
free (unk9);
|
||||
|
||||
char *unk14 = (char *)malloc (0x8A2);
|
||||
res = auth->Unk14 (unk14);
|
||||
printf ("unk14: %d\n", res);
|
||||
printf ("unk14 %s\n", unk14);
|
||||
printf ("unk14 + 0x101 %s\n", unk14 + 0x101);
|
||||
printf ("unk14 + 0x202 %s\n", unk14 + 0x202);
|
||||
printf ("unk14 + 0x302 %s\n", unk14 + 0x302);
|
||||
printf ("unk14 + 0x402 %s\n", unk14 + 0x402);
|
||||
printf ("unk14 + 0x412 %s\n", unk14 + 0x412);
|
||||
printf ("unk14 + 0x512 %s\n", unk14 + 0x512);
|
||||
printf ("unk14 + 0x512 %s\n", unk14 + 0x612);
|
||||
printf ("unk14 + 0x712 %s\n", unk14 + 0x712);
|
||||
printf ("unk14 + 0x812 %s\n", unk14 + 0x812);
|
||||
printf ("unk14 + 0x822 %s\n", unk14 + 0x822);
|
||||
printf ("unk14 + 0x832 %s\n", unk14 + 0x832);
|
||||
printf ("unk14 + 0x842 %s\n", unk14 + 0x842);
|
||||
printf ("unk14 + 0x862 %s\n", unk14 + 0x862);
|
||||
free (unk14);
|
||||
|
||||
char *unk11 = (char *)malloc (0x13C);
|
||||
res = auth->Unk11 (unk11);
|
||||
printf ("unk11: %d\n", res);
|
||||
printf ("%s\n", unk11);
|
||||
printf ("%s\n", unk11 + 4);
|
||||
printf ("%s\n", unk11 + 20);
|
||||
printf ("%s\n", unk11 + 28);
|
||||
printf ("%s\n", unk11 + 36);
|
||||
printf ("%s\n", unk11 + 44);
|
||||
printf ("%s\n", unk11 + 52);
|
||||
printf ("%s\n", unk11 + 56);
|
||||
printf ("%s\n", unk11 + 60);
|
||||
free (unk11);
|
||||
|
||||
char *unk10 = (char *)malloc (0xB0);
|
||||
res = auth->Unk10 (unk10);
|
||||
printf ("unk10: %d\n", res);
|
||||
FILE *unk10fp = fopen ("unk10.bin", "w");
|
||||
fwrite (unk10, 0xA8, 1, unk10fp);
|
||||
fclose (unk10fp);
|
||||
free (unk10);
|
||||
|
||||
u8 *unk19 = (u8 *)malloc (0x40);
|
||||
memset (unk19, 0xFF, 0x40);
|
||||
res = auth->Unk19 (unk19);
|
||||
printf ("unk19: %d\n", res);
|
||||
FILE *unk19fp = fopen ("unk19.bin", "w");
|
||||
fwrite (unk19, 0x40, 1, unk19fp);
|
||||
fclose (unk19fp);
|
||||
free (unk19);
|
||||
|
||||
auth->Release ();
|
||||
CoUninitialize ();
|
||||
}
|
||||
}
|
213
src/bnusio.cpp
Normal file
213
src/bnusio.cpp
Normal file
@ -0,0 +1,213 @@
|
||||
#include "helpers.h"
|
||||
#include "poll.h"
|
||||
|
||||
extern std::vector<HMODULE> plugins;
|
||||
extern char accessCode[21];
|
||||
extern char chipId[33];
|
||||
|
||||
namespace bnusio {
|
||||
#define RETURN_FALSE(returnType, functionName, ...) \
|
||||
returnType functionName (__VA_ARGS__) { return 0; }
|
||||
|
||||
extern "C" {
|
||||
RETURN_FALSE (i64, bnusio_ClearSram);
|
||||
RETURN_FALSE (i64, bnusio_Communication, i32 a1);
|
||||
RETURN_FALSE (i64, bnusio_DecService, i32 a1, u16 a2);
|
||||
RETURN_FALSE (void *, bnusio_GetBuffer, u16 a1, i64 a2, i16 a3);
|
||||
RETURN_FALSE (i64, bnusio_GetCDOut, u8 a1);
|
||||
RETURN_FALSE (void *, bnusio_GetCoinError, i32 a1);
|
||||
RETURN_FALSE (i64, bnusio_GetCoinLock, u8 a1);
|
||||
RETURN_FALSE (u64, bnusio_GetEncoder);
|
||||
RETURN_FALSE (void *, bnusio_GetExpansionMode);
|
||||
RETURN_FALSE (u8, bnusio_GetGout, u8 a1);
|
||||
RETURN_FALSE (i64, bnusio_GetHopOut, u8 a1);
|
||||
RETURN_FALSE (char *, bnusio_GetIoBoardName);
|
||||
RETURN_FALSE (u16, bnusio_GetRegisterU16, i16 a1);
|
||||
RETURN_FALSE (u8, bnusio_GetRegisterU8, u16 a1);
|
||||
RETURN_FALSE (void *, bnusio_GetService, i32 a1);
|
||||
RETURN_FALSE (void *, bnusio_GetServiceError, i32 a1);
|
||||
RETURN_FALSE (u16, bnusio_GetStatusU16, u16 a1);
|
||||
RETURN_FALSE (u8, bnusio_GetStatusU8, u16 a1);
|
||||
RETURN_FALSE (u64, bnusio_GetSwIn64);
|
||||
RETURN_FALSE (void *, bnusio_GetSystemError);
|
||||
RETURN_FALSE (u8, bnusio_IsConnected);
|
||||
RETURN_FALSE (u8, bnusio_IsWideUsio);
|
||||
RETURN_FALSE (i64, bnusio_Open);
|
||||
RETURN_FALSE (i32, bnusio_ResetIoBoard);
|
||||
RETURN_FALSE (i64, bnusio_SetBuffer, u16 a1, i32 a2, i16 a3);
|
||||
RETURN_FALSE (i64, bnusio_SetCDOut, u8 a1, u8 a2);
|
||||
RETURN_FALSE (i64, bnusio_SetCoinLock, u8 a1, u8 a2);
|
||||
RETURN_FALSE (i64, bnusio_SetExpansionMode, i16 a1);
|
||||
RETURN_FALSE (i64, bnusio_SetGout, u8 a1, u8 a2);
|
||||
RETURN_FALSE (i64, bnusio_SetHopOut, u8 a1, u8 a2);
|
||||
RETURN_FALSE (i64, bnusio_SetHopperLimit, u16 a1, i16 a2);
|
||||
RETURN_FALSE (i64, bnusio_SetHopperRequest, u16 a1, i16 a2);
|
||||
RETURN_FALSE (void *, bnusio_SetPLCounter, i16 a1);
|
||||
RETURN_FALSE (i64, bnusio_SetRegisterU16, u16 a1, u16 a2);
|
||||
RETURN_FALSE (i64, bnusio_SetRegisterU8, u16 a1, u8 a2);
|
||||
RETURN_FALSE (i64, bnusio_SetSystemError, i16 a1);
|
||||
RETURN_FALSE (i64, bnusio_SramRead, i32 a1, u8 a2, i32 a3, u16 a4);
|
||||
RETURN_FALSE (i64, bnusio_SramWrite, i32 a1, u8 a2, i32 a3, u16 a4);
|
||||
RETURN_FALSE (i64, bnusio_ResetCoin);
|
||||
RETURN_FALSE (i64, bnusio_DecCoin, i32 a1, u16 a2);
|
||||
size_t
|
||||
bnusio_GetFirmwareVersion () {
|
||||
return 126;
|
||||
}
|
||||
|
||||
Keybindings EXIT = {.keycodes = {VK_ESCAPE}};
|
||||
Keybindings TEST = {.keycodes = {VK_F1}};
|
||||
Keybindings SERVICE = {.keycodes = {VK_F2}};
|
||||
Keybindings DEBUG_UP = {.keycodes = {VK_UP}};
|
||||
Keybindings DEBUG_DOWN = {.keycodes = {VK_DOWN}};
|
||||
Keybindings DEBUG_ENTER = {.keycodes = {VK_RETURN}};
|
||||
Keybindings COIN_ADD = {.keycodes = {VK_RETURN}, .buttons = {SDL_CONTROLLER_BUTTON_START}};
|
||||
Keybindings CARD_INSERT = {.keycodes = {'P'}};
|
||||
Keybindings P1_LEFT_BLUE = {.keycodes = {'D'}, .axis = {SDL_AXIS_LTRIGGER_DOWN}};
|
||||
Keybindings P1_LEFT_RED = {.keycodes = {'F'}, .buttons = {SDL_CONTROLLER_BUTTON_LEFTSTICK}};
|
||||
Keybindings P1_RIGHT_RED = {.keycodes = {'J'}, .buttons = {SDL_CONTROLLER_BUTTON_RIGHTSTICK}};
|
||||
Keybindings P1_RIGHT_BLUE = {.keycodes = {'K'}, .axis = {SDL_AXIS_RTRIGGER_DOWN}};
|
||||
Keybindings P2_LEFT_BLUE = {};
|
||||
Keybindings P2_LEFT_RED = {};
|
||||
Keybindings P2_RIGHT_RED = {};
|
||||
Keybindings P2_RIGHT_BLUE = {};
|
||||
|
||||
struct AnalogGameButton {
|
||||
Keybindings *bindings;
|
||||
i32 offset;
|
||||
};
|
||||
|
||||
u16 drumMin = 10000;
|
||||
u16 drumMax = 20000;
|
||||
AnalogGameButton analogButtons[] = {{&P1_LEFT_BLUE}, {&P1_LEFT_RED}, {&P1_RIGHT_RED}, {&P1_RIGHT_BLUE}, {&P2_LEFT_BLUE}, {&P2_LEFT_RED}, {&P2_RIGHT_RED}, {&P2_RIGHT_BLUE}};
|
||||
|
||||
u16
|
||||
bnusio_GetAnalogIn (u8 which) {
|
||||
auto button = &analogButtons[which];
|
||||
if (!IsButtonDown (*button->bindings)) {
|
||||
button->offset = drumMin;
|
||||
return 0;
|
||||
} else if (button->offset == drumMax) {
|
||||
return drumMax;
|
||||
} else {
|
||||
button->offset += 1;
|
||||
return button->offset;
|
||||
}
|
||||
}
|
||||
|
||||
bool testEnabled = false;
|
||||
int coin_count = 0;
|
||||
bool inited = false;
|
||||
HWND windowHandle = 0;
|
||||
|
||||
u16 __fastcall bnusio_GetCoin (i32 a1) {
|
||||
if (a1 != 1) return coin_count;
|
||||
|
||||
if (!inited) {
|
||||
windowHandle = FindWindowA ("nuFoundation.Window", 0);
|
||||
InitializePoll (windowHandle);
|
||||
|
||||
for (auto plugin : plugins) {
|
||||
auto initEvent = GetProcAddress (plugin, "Init");
|
||||
if (initEvent) initEvent ();
|
||||
}
|
||||
|
||||
inited = true;
|
||||
}
|
||||
|
||||
UpdatePoll (windowHandle);
|
||||
if (IsButtonTapped (COIN_ADD) && !testEnabled) coin_count++;
|
||||
if (IsButtonTapped (TEST)) testEnabled = !testEnabled;
|
||||
if (IsButtonTapped (EXIT)) ExitProcess (0);
|
||||
|
||||
for (auto plugin : plugins) {
|
||||
auto updateEvent = GetProcAddress (plugin, "Update");
|
||||
if (updateEvent) updateEvent ();
|
||||
}
|
||||
|
||||
return coin_count;
|
||||
}
|
||||
|
||||
u32
|
||||
bnusio_GetSwIn () {
|
||||
u32 sw = 0;
|
||||
sw |= (u32)testEnabled << 7;
|
||||
sw |= (u32)IsButtonDown (DEBUG_ENTER) << 9;
|
||||
sw |= (u32)IsButtonDown (DEBUG_DOWN) << 12;
|
||||
sw |= (u32)IsButtonDown (DEBUG_UP) << 13;
|
||||
sw |= (u32)IsButtonDown (SERVICE) << 14;
|
||||
return sw;
|
||||
}
|
||||
}
|
||||
|
||||
HOOK (u64, bngrw_DevReset, PROC_ADDRESS ("bngrw.dll", "BngRwDevReset")) { return 1; }
|
||||
HOOK (u64, bngrw_ReadMifare, PROC_ADDRESS ("bngrw.dll", "BngRwExReadMifareAllBlock")) { return 0xFFFFFF9C; }
|
||||
HOOK (void, bngrw_fin, PROC_ADDRESS ("bngrw.dll", "BngRwFin")) { return; }
|
||||
HOOK (u64, bngrw_GetFwVersion, PROC_ADDRESS ("bngrw.dll", "BngRwGetFwVersion")) { return 0; }
|
||||
HOOK (u64, bngrw_GetStationID, PROC_ADDRESS ("bngrw.dll", "BngRwGetStationID")) { return 0; }
|
||||
HOOK (u64, bngrw_GetRetryCount, PROC_ADDRESS ("bngrw.dll", "BngRwGetTotalRetryCount")) { return 0; }
|
||||
HOOK (u64, bngrw_IsCmdExec, PROC_ADDRESS ("bngrw.dll", "BngRwIsCmdExec")) { return 0xFFFFFFFF; }
|
||||
HOOK (u64, bngrw_ReqAction, PROC_ADDRESS ("bngrw.dll", "BngRwReqAction")) { return 1; }
|
||||
HOOK (u64, bngrw_ReqAiccAuth, PROC_ADDRESS ("bngrw.dll", "BngRwReqAiccAuth")) { return 1; }
|
||||
HOOK (u64, bngrw_ReqBeep, PROC_ADDRESS ("bngrw.dll", "BngRwReqBeep")) { return 1; }
|
||||
HOOK (u64, bngrw_ReqFwCleanup, PROC_ADDRESS ("bngrw.dll", "BngRwReqFwCleanup")) { return 1; }
|
||||
HOOK (u64, bngrw_ReqFwVersionUp, PROC_ADDRESS ("bngrw.dll", "BngRwReqFwVersionUp")) { return 1; }
|
||||
HOOK (i32, bngrw_ReqLatchID, PROC_ADDRESS ("bngrw.dll", "BngRwReqLatchID")) { return 1; }
|
||||
HOOK (u64, bngrw_ReqLed, PROC_ADDRESS ("bngrw.dll", "BngRwReqLed")) { return 1; }
|
||||
HOOK (i32, bngrw_ReqSendMail, PROC_ADDRESS ("bngrw.dll", "BngRwReqSendMailTo")) { return 1; }
|
||||
HOOK (i32, bngrw_ReqSendUrl, PROC_ADDRESS ("bngrw.dll", "BngRwReqSendUrlTo")) { return 1; }
|
||||
HOOK (u64, bngrw_ReqSetLedPower, PROC_ADDRESS ("bngrw.dll", "BngRwReqSetLedPower")) { return 0; }
|
||||
HOOK (i32, bngrw_reqCancel, PROC_ADDRESS ("bngrw.dll", "BngRwReqCancel")) { return 1; }
|
||||
HOOK (u64, bngrw_Init, PROC_ADDRESS ("bngrw.dll", "BngRwInit")) { return 0; }
|
||||
HOOK (u64, bngrw_attach, PROC_ADDRESS ("bngrw.dll", "BngRwAttach"), i32 a1, char *a2, i32 a3, i32 a4, i32 (*callback) (i32, i32, i32 *), i32 *a6) { return 1; }
|
||||
HOOK (u64, bngrw_reqWaitTouch, PROC_ADDRESS ("bngrw.dll", "BngRwReqWaitTouch"), u32 a1, i32 a2, u32 a3, void (*callback) (i32, i32, u8[168], u64), u64 a5) { return 1; }
|
||||
|
||||
void
|
||||
Init () {
|
||||
INSTALL_HOOK (bngrw_DevReset);
|
||||
INSTALL_HOOK (bngrw_ReadMifare);
|
||||
INSTALL_HOOK (bngrw_fin);
|
||||
INSTALL_HOOK (bngrw_GetFwVersion);
|
||||
INSTALL_HOOK (bngrw_GetStationID);
|
||||
INSTALL_HOOK (bngrw_GetRetryCount);
|
||||
INSTALL_HOOK (bngrw_IsCmdExec);
|
||||
INSTALL_HOOK (bngrw_ReqAction);
|
||||
INSTALL_HOOK (bngrw_ReqAiccAuth);
|
||||
INSTALL_HOOK (bngrw_ReqBeep);
|
||||
INSTALL_HOOK (bngrw_ReqFwCleanup);
|
||||
INSTALL_HOOK (bngrw_ReqFwVersionUp);
|
||||
INSTALL_HOOK (bngrw_ReqLatchID);
|
||||
INSTALL_HOOK (bngrw_ReqLed);
|
||||
INSTALL_HOOK (bngrw_ReqSendMail);
|
||||
INSTALL_HOOK (bngrw_ReqSendUrl);
|
||||
INSTALL_HOOK (bngrw_ReqSetLedPower);
|
||||
INSTALL_HOOK (bngrw_reqCancel);
|
||||
INSTALL_HOOK (bngrw_Init);
|
||||
|
||||
auto configPath = std::filesystem::current_path () / "keyconfig.toml";
|
||||
toml_table_t *config = openConfig (configPath);
|
||||
if (config) {
|
||||
SetConfigValue (config, "EXIT", &EXIT);
|
||||
|
||||
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);
|
||||
|
||||
SetConfigValue (config, "COIN_ADD", &COIN_ADD);
|
||||
SetConfigValue (config, "CARD_INSERT", &CARD_INSERT);
|
||||
|
||||
SetConfigValue (config, "P1_LEFT_BLUE", &P1_LEFT_BLUE);
|
||||
SetConfigValue (config, "P1_LEFT_RED", &P1_LEFT_RED);
|
||||
SetConfigValue (config, "P1_RIGHT_RED", &P1_RIGHT_RED);
|
||||
SetConfigValue (config, "P1_RIGHT_BLUE", &P1_RIGHT_BLUE);
|
||||
SetConfigValue (config, "P2_LEFT_BLUE", &P2_LEFT_BLUE);
|
||||
SetConfigValue (config, "P2_LEFT_RED", &P2_LEFT_RED);
|
||||
SetConfigValue (config, "P2_RIGHT_RED", &P2_RIGHT_RED);
|
||||
SetConfigValue (config, "P2_RIGHT_BLUE", &P2_RIGHT_BLUE);
|
||||
|
||||
toml_free (config);
|
||||
}
|
||||
}
|
||||
} // namespace bnusio
|
3
src/bnusio.h
Normal file
3
src/bnusio.h
Normal file
@ -0,0 +1,3 @@
|
||||
namespace bnusio {
|
||||
void Init ();
|
||||
} // namespace bnusio
|
@ -1,117 +0,0 @@
|
||||
#include "helpers.h"
|
||||
|
||||
// force show cursor
|
||||
HOOK_DYNAMIC (i32, __stdcall, ShowMouse, i32 show) { return originalShowMouse (true); }
|
||||
HOOK_DYNAMIC (i32, __stdcall, ExitWindows, i32 exitCode, i32 reason) {
|
||||
ExitProcess (0);
|
||||
return true;
|
||||
}
|
||||
|
||||
// xinput stuff
|
||||
HOOK_DYNAMIC (u32, __stdcall, XinputGetState, u32 index, void *state) { return ERROR_DEVICE_NOT_CONNECTED; }
|
||||
HOOK_DYNAMIC (u32, __stdcall, XinputSetState, u32 index, void *state) { return ERROR_DEVICE_NOT_CONNECTED; }
|
||||
HOOK_DYNAMIC (u32, __stdcall, XinputGetCapabilites, u32 index, u32 flags, void *state) { return ERROR_DEVICE_NOT_CONNECTED; }
|
||||
|
||||
// bnusio stuff
|
||||
RETURN_FALSE (i64, __stdcall, bnusio_ClearSram);
|
||||
RETURN_FALSE (i64, __fastcall, bnusio_Communication, i32 a1);
|
||||
RETURN_FALSE (i64, __fastcall, bnusio_DecService, i32 a1, u16 a2);
|
||||
RETURN_FALSE (void *, __fastcall, bnusio_GetBuffer, u16 a1, i64 a2, i16 a3);
|
||||
RETURN_FALSE (i64, __fastcall, bnusio_GetCDOut, u8 a1);
|
||||
RETURN_FALSE (void *, __fastcall, bnusio_GetCoinError, i32 a1);
|
||||
RETURN_FALSE (i64, __fastcall, bnusio_GetCoinLock, u8 a1);
|
||||
RETURN_FALSE (u64, __stdcall, bnusio_GetEncoder);
|
||||
RETURN_FALSE (void *, __stdcall, bnusio_GetExpansionMode);
|
||||
void *__stdcall bnusio_GetFirmwareVersion () { return (void *)(u16)126; }
|
||||
RETURN_FALSE (u8, __stdcall, bnusio_GetGout, u8 a1);
|
||||
RETURN_FALSE (i64, __stdcall, bnusio_GetHopOut, u8 a1);
|
||||
RETURN_FALSE (char *, __stdcall, bnusio_GetIoBoardName);
|
||||
RETURN_FALSE (u16, __fastcall, bnusio_GetRegisterU16, i16 a1);
|
||||
RETURN_FALSE (u8, __fastcall, bnusio_GetRegisterU8, u16 a1);
|
||||
RETURN_FALSE (void *, __fastcall, bnusio_GetService, i32 a1);
|
||||
RETURN_FALSE (void *, __fastcall, bnusio_GetServiceError, i32 a1);
|
||||
RETURN_FALSE (u16, __fastcall, bnusio_GetStatusU16, u16 a1);
|
||||
RETURN_FALSE (u8, __fastcall, bnusio_GetStatusU8, u16 a1);
|
||||
RETURN_FALSE (u64, __stdcall, bnusio_GetSwIn64);
|
||||
RETURN_FALSE (void *, __stdcall, bnusio_GetSystemError);
|
||||
RETURN_FALSE (u8, __stdcall, bnusio_IsConnected);
|
||||
RETURN_FALSE (u8, __stdcall, bnusio_IsWideUsio);
|
||||
RETURN_FALSE (i64, __stdcall, bnusio_Open);
|
||||
RETURN_FALSE (i32, __stdcall, bnusio_ResetIoBoard);
|
||||
RETURN_FALSE (i64, __fastcall, bnusio_SetBuffer, u16 a1, i32 a2, i16 a3);
|
||||
RETURN_FALSE (i64, __fastcall, bnusio_SetCDOut, u8 a1, u8 a2);
|
||||
RETURN_FALSE (i64, __fastcall, bnusio_SetCoinLock, u8 a1, u8 a2);
|
||||
RETURN_FALSE (i64, __fastcall, bnusio_SetExpansionMode, i16 a1);
|
||||
RETURN_FALSE (i64, __fastcall, bnusio_SetGout, u8 a1, u8 a2);
|
||||
RETURN_FALSE (i64, __fastcall, bnusio_SetHopOut, u8 a1, u8 a2);
|
||||
RETURN_FALSE (i64, __fastcall, bnusio_SetHopperLimit, u16 a1, i16 a2);
|
||||
RETURN_FALSE (i64, __fastcall, bnusio_SetHopperRequest, u16 a1, i16 a2);
|
||||
RETURN_FALSE (void *, __fastcall, bnusio_SetPLCounter, i16 a1);
|
||||
RETURN_FALSE (i64, __fastcall, bnusio_SetRegisterU16, u16 a1, u16 a2);
|
||||
RETURN_FALSE (i64, __fastcall, bnusio_SetRegisterU8, u16 a1, u8 a2);
|
||||
RETURN_FALSE (i64, __fastcall, bnusio_SetSystemError, i16 a1);
|
||||
RETURN_FALSE (i64, __fastcall, bnusio_SramRead, i32 a1, u8 a2, i32 a3, u16 a4);
|
||||
RETURN_FALSE (i64, __fastcall, bnusio_SramWrite, i32 a1, u8 a2, i32 a3, u16 a4);
|
||||
RETURN_FALSE (i64, __stdcall, bnusio_ResetCoin);
|
||||
RETURN_FALSE (i64, __fastcall, bnusio_DecCoin, i32 a1, u16 a2);
|
||||
HOOK_DYNAMIC (i64, __stdcall, UsbFinderInitialize) { return 0; }
|
||||
HOOK_DYNAMIC (i64, __stdcall, UsbFinderRelease) { return 0; }
|
||||
HOOK_DYNAMIC (i64, __fastcall, UsbFinderGetSerialNumber, i32 a1, char *a2) {
|
||||
strcpy (a2, "284111080001");
|
||||
return 0;
|
||||
}
|
||||
HOOK_DYNAMIC (u64, __stdcall, bngrw_DevReset) { return 1; }
|
||||
HOOK_DYNAMIC (u64, __stdcall, bngrw_ReadMifare) { return 0xFFFFFF9C; }
|
||||
HOOK_DYNAMIC (void, __stdcall, bngrw_fin) { return; }
|
||||
HOOK_DYNAMIC (u64, __stdcall, bngrw_GetFwVersion) { return 0; }
|
||||
HOOK_DYNAMIC (u64, __stdcall, bngrw_GetStationID) { return 0; }
|
||||
HOOK_DYNAMIC (u64, __stdcall, bngrw_GetRetryCount) { return 0; }
|
||||
HOOK_DYNAMIC (u64, __stdcall, bngrw_IsCmdExec) { return 0xFFFFFFFF; }
|
||||
HOOK_DYNAMIC (u64, __stdcall, bngrw_ReqAction) { return 1; }
|
||||
HOOK_DYNAMIC (u64, __stdcall, bngrw_ReqAiccAuth) { return 1; }
|
||||
HOOK_DYNAMIC (u64, __stdcall, bngrw_ReqBeep) { return 1; }
|
||||
HOOK_DYNAMIC (u64, __stdcall, bngrw_ReqFwCleanup) { return 1; }
|
||||
HOOK_DYNAMIC (u64, __stdcall, bngrw_ReqFwVersionUp) { return 1; }
|
||||
HOOK_DYNAMIC (i32, __stdcall, bngrw_ReqLatchID) { return 1; }
|
||||
HOOK_DYNAMIC (u64, __stdcall, bngrw_ReqLed) { return 1; }
|
||||
HOOK_DYNAMIC (i32, __stdcall, bngrw_ReqSendMail) { return 1; }
|
||||
HOOK_DYNAMIC (i32, __stdcall, bngrw_ReqSendUrl) { return 1; }
|
||||
HOOK_DYNAMIC (u64, __stdcall, bngrw_ReqSetLedPower) { return 0; }
|
||||
HOOK_DYNAMIC (i32, __stdcall, bngrw_reqCancel) { return 1; }
|
||||
|
||||
HOOK_DYNAMIC (i32, __stdcall, ssleay_Shutdown) { return 1; }
|
||||
|
||||
void
|
||||
init_boilerplate () {
|
||||
INSTALL_HOOK_DYNAMIC (ShowMouse, PROC_ADDRESS ("user32.dll", "ShowCursor"));
|
||||
INSTALL_HOOK_DYNAMIC (ExitWindows, PROC_ADDRESS ("user32.dll", "ExitWindowsEx"));
|
||||
|
||||
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 (UsbFinderInitialize, PROC_ADDRESS ("nbamUsbFinder.dll", "nbamUsbFinderInitialize"));
|
||||
INSTALL_HOOK_DYNAMIC (UsbFinderRelease, PROC_ADDRESS ("nbamUsbFinder.dll", "nbamUsbFinderRelease"));
|
||||
INSTALL_HOOK_DYNAMIC (UsbFinderGetSerialNumber, PROC_ADDRESS ("nbamUsbFinder.dll", "nbamUsbFinderGetSerialNumber"));
|
||||
|
||||
INSTALL_HOOK_DYNAMIC (bngrw_DevReset, PROC_ADDRESS ("bngrw.dll", "BngRwDevReset"));
|
||||
INSTALL_HOOK_DYNAMIC (bngrw_ReadMifare, PROC_ADDRESS ("bngrw.dll", "BngRwExReadMifareAllBlock"));
|
||||
INSTALL_HOOK_DYNAMIC (bngrw_fin, PROC_ADDRESS ("bngrw.dll", "BngRwFin"));
|
||||
INSTALL_HOOK_DYNAMIC (bngrw_GetFwVersion, PROC_ADDRESS ("bngrw.dll", "BngRwGetFwVersion"));
|
||||
INSTALL_HOOK_DYNAMIC (bngrw_GetStationID, PROC_ADDRESS ("bngrw.dll", "BngRwGetStationID"));
|
||||
INSTALL_HOOK_DYNAMIC (bngrw_GetRetryCount, PROC_ADDRESS ("bngrw.dll", "BngRwGetTotalRetryCount"));
|
||||
INSTALL_HOOK_DYNAMIC (bngrw_IsCmdExec, PROC_ADDRESS ("bngrw.dll", "BngRwIsCmdExec"));
|
||||
INSTALL_HOOK_DYNAMIC (bngrw_ReqAction, PROC_ADDRESS ("bngrw.dll", "BngRwReqAction"));
|
||||
INSTALL_HOOK_DYNAMIC (bngrw_ReqAiccAuth, PROC_ADDRESS ("bngrw.dll", "BngRwReqAiccAuth"));
|
||||
INSTALL_HOOK_DYNAMIC (bngrw_ReqBeep, PROC_ADDRESS ("bngrw.dll", "BngRwReqBeep"));
|
||||
INSTALL_HOOK_DYNAMIC (bngrw_ReqFwCleanup, PROC_ADDRESS ("bngrw.dll", "BngRwReqFwCleanup"));
|
||||
INSTALL_HOOK_DYNAMIC (bngrw_ReqFwVersionUp, PROC_ADDRESS ("bngrw.dll", "BngRwReqFwVersionUp"));
|
||||
INSTALL_HOOK_DYNAMIC (bngrw_ReqLatchID, PROC_ADDRESS ("bngrw.dll", "BngRwReqLatchID"));
|
||||
INSTALL_HOOK_DYNAMIC (bngrw_ReqLed, PROC_ADDRESS ("bngrw.dll", "BngRwReqLed"));
|
||||
INSTALL_HOOK_DYNAMIC (bngrw_ReqSendMail, PROC_ADDRESS ("bngrw.dll", "BngRwReqSendMailTo"));
|
||||
INSTALL_HOOK_DYNAMIC (bngrw_ReqSendUrl, PROC_ADDRESS ("bngrw.dll", "BngRwReqSendUrlTo"));
|
||||
INSTALL_HOOK_DYNAMIC (bngrw_ReqSetLedPower, PROC_ADDRESS ("bngrw.dll", "BngRwReqSetLedPower"));
|
||||
INSTALL_HOOK_DYNAMIC (bngrw_reqCancel, PROC_ADDRESS ("bngrw.dll", "BngRwReqCancel"));
|
||||
|
||||
INSTALL_HOOK_DYNAMIC (ssleay_Shutdown, PROC_ADDRESS ("ssleay32.dll", "SSL_shutdown"));
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
#pragma once
|
||||
void init_boilerplate ();
|
289
src/dllmain.c
289
src/dllmain.c
@ -1,289 +0,0 @@
|
||||
#include "boilerplate.h"
|
||||
#include "helpers.h"
|
||||
#include "poll.h"
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
bool testEnabled = false;
|
||||
u16 drumMax = 0xFFFF;
|
||||
u16 drumMin = 0xFFFF;
|
||||
char accessCode1[21] = "00000000000000000001";
|
||||
char accessCode2[21] = "00000000000000000002";
|
||||
char chipId1[33] = "00000000000000000000000000000001";
|
||||
char chipId2[33] = "00000000000000000000000000000002";
|
||||
char *server = "127.0.0.1";
|
||||
|
||||
typedef i32 (*callbackAttach) (i32, i32, i32 *);
|
||||
typedef void (*callbackTouch) (i32, i32, u8[168], u64);
|
||||
typedef void event ();
|
||||
typedef void waitTouchEvent (callbackTouch, u64);
|
||||
bool waitingForTouch = false;
|
||||
callbackTouch touchCallback;
|
||||
u64 touchData;
|
||||
callbackAttach attachCallback;
|
||||
i32 *attachData;
|
||||
HMODULE plugins[255] = { 0 };
|
||||
|
||||
#define ON_HIT(bind) IsButtonTapped (bind) ? drumMax == drumMin ? drumMax : (u16)(rand () % drumMax + drumMin) : 0
|
||||
|
||||
Keybindings EXIT = { .keycodes = { VK_ESCAPE } };
|
||||
Keybindings TEST = { .keycodes = { VK_F1 } };
|
||||
Keybindings SERVICE = { .keycodes = { VK_F2 } };
|
||||
Keybindings DEBUG_UP = { .keycodes = { VK_UP } };
|
||||
Keybindings DEBUG_DOWN = { .keycodes = { VK_DOWN } };
|
||||
Keybindings DEBUG_ENTER = { .keycodes = { VK_RETURN } };
|
||||
Keybindings COIN_ADD = { .keycodes = { VK_RETURN }, .buttons = { SDL_GAMEPAD_BUTTON_START } };
|
||||
Keybindings CARD_INSERT_1 = { .keycodes = { 'P' } };
|
||||
Keybindings CARD_INSERT_2 = {};
|
||||
Keybindings P1_LEFT_BLUE = { .keycodes = { 'D' }, .axis = { SDL_AXIS_LTRIGGER_DOWN } };
|
||||
Keybindings P1_LEFT_RED = { .keycodes = { 'F' }, .buttons = { SDL_GAMEPAD_BUTTON_LEFT_STICK } };
|
||||
Keybindings P1_RIGHT_RED = { .keycodes = { 'J' }, .buttons = { SDL_GAMEPAD_BUTTON_RIGHT_STICK } };
|
||||
Keybindings P1_RIGHT_BLUE = { .keycodes = { 'K' }, .axis = { SDL_AXIS_RTRIGGER_DOWN } };
|
||||
Keybindings P2_LEFT_BLUE = {};
|
||||
Keybindings P2_LEFT_RED = {};
|
||||
Keybindings P2_RIGHT_RED = {};
|
||||
Keybindings P2_RIGHT_BLUE = {};
|
||||
|
||||
u16 __fastcall bnusio_GetAnalogIn (u8 which) {
|
||||
switch (which) {
|
||||
case 0: return ON_HIT (P1_LEFT_BLUE); // Player 1 Left Blue
|
||||
case 1: return ON_HIT (P1_LEFT_RED); // Player 1 Left Red
|
||||
case 2: return ON_HIT (P1_RIGHT_RED); // Player 1 Right Red
|
||||
case 3: return ON_HIT (P1_RIGHT_BLUE); // Player 1 Right Blue
|
||||
case 4: return ON_HIT (P2_LEFT_BLUE); // Player 2 Left Blue
|
||||
case 5: return ON_HIT (P2_LEFT_RED); // Player 2 Left Red
|
||||
case 6: return ON_HIT (P2_RIGHT_RED); // Player 2 Right Red
|
||||
case 7: return ON_HIT (P2_RIGHT_BLUE); // Player 2 Right Blue
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
u16 __fastcall bnusio_GetCoin (i32 a1) {
|
||||
static int coin_count = 0;
|
||||
|
||||
if (a1 != 1) return coin_count;
|
||||
static bool inited = false;
|
||||
static HWND windowHandle = 0;
|
||||
|
||||
if (!inited) {
|
||||
windowHandle = FindWindowA ("nuFoundation.Window", 0);
|
||||
|
||||
InitializePoll (windowHandle);
|
||||
|
||||
toml_table_t *config = openConfig (configPath ("keyconfig.toml"));
|
||||
if (config) {
|
||||
SetConfigValue (config, "EXIT", &EXIT);
|
||||
|
||||
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);
|
||||
|
||||
SetConfigValue (config, "COIN_ADD", &COIN_ADD);
|
||||
SetConfigValue (config, "CARD_INSERT_1", &CARD_INSERT_1);
|
||||
SetConfigValue (config, "CARD_INSERT_2", &CARD_INSERT_2);
|
||||
|
||||
SetConfigValue (config, "P1_LEFT_BLUE", &P1_LEFT_BLUE);
|
||||
SetConfigValue (config, "P1_LEFT_RED", &P1_LEFT_RED);
|
||||
SetConfigValue (config, "P1_RIGHT_RED", &P1_RIGHT_RED);
|
||||
SetConfigValue (config, "P1_RIGHT_BLUE", &P1_RIGHT_BLUE);
|
||||
SetConfigValue (config, "P2_LEFT_BLUE", &P2_LEFT_BLUE);
|
||||
SetConfigValue (config, "P2_LEFT_RED", &P2_LEFT_RED);
|
||||
SetConfigValue (config, "P2_RIGHT_RED", &P2_RIGHT_RED);
|
||||
SetConfigValue (config, "P2_RIGHT_BLUE", &P2_RIGHT_BLUE);
|
||||
|
||||
toml_free (config);
|
||||
}
|
||||
|
||||
inited = true;
|
||||
}
|
||||
|
||||
UpdatePoll (windowHandle);
|
||||
if (IsButtonTapped (COIN_ADD) && !testEnabled) coin_count++;
|
||||
if (IsButtonTapped (TEST)) testEnabled = !testEnabled;
|
||||
if (IsButtonTapped (EXIT)) ExitProcess (0);
|
||||
if (waitingForTouch) {
|
||||
static u8 cardData[168]
|
||||
= { 0x01, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0x2E, 0x58, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x5C, 0x97, 0x44, 0xF0, 0x88, 0x04, 0x00, 0x43, 0x26, 0x2C, 0x33, 0x00, 0x04,
|
||||
0x06, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x42, 0x47, 0x49, 0x43, 0x36,
|
||||
0x00, 0x00, 0xFA, 0xE9, 0x69, 0x00, 0xF6, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
bool hasInserted = false;
|
||||
if (IsButtonTapped (CARD_INSERT_1)) {
|
||||
for (int i = 0; plugins[i] != 0; i++) {
|
||||
FARPROC insertEvent = GetProcAddress (plugins[i], "BeforeCard1Insert");
|
||||
if (insertEvent) ((event *)insertEvent) ();
|
||||
}
|
||||
for (int i = 0; plugins[i] != 0; i++) {
|
||||
FARPROC insertEvent = GetProcAddress (plugins[i], "Card1Insert");
|
||||
if (insertEvent) {
|
||||
((event *)insertEvent) ();
|
||||
hasInserted = true;
|
||||
}
|
||||
}
|
||||
if (!hasInserted) {
|
||||
memcpy (cardData + 0x2C, chipId1, 33);
|
||||
memcpy (cardData + 0x50, accessCode1, 21);
|
||||
touchCallback (0, 0, cardData, touchData);
|
||||
}
|
||||
} else if (IsButtonTapped (CARD_INSERT_2)) {
|
||||
for (int i = 0; plugins[i] != 0; i++) {
|
||||
FARPROC insertEvent = GetProcAddress (plugins[i], "BeforeCard2Insert");
|
||||
if (insertEvent) ((event *)insertEvent) ();
|
||||
}
|
||||
for (int i = 0; plugins[i] != 0; i++) {
|
||||
FARPROC insertEvent = GetProcAddress (plugins[i], "Card2Insert");
|
||||
if (insertEvent) {
|
||||
((event *)insertEvent) ();
|
||||
hasInserted = true;
|
||||
}
|
||||
}
|
||||
if (!hasInserted) {
|
||||
memcpy (cardData + 0x2C, chipId2, 33);
|
||||
memcpy (cardData + 0x50, accessCode2, 21);
|
||||
touchCallback (0, 0, cardData, touchData);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; plugins[i] != 0; i++) {
|
||||
FARPROC updateEvent = GetProcAddress (plugins[i], "Update");
|
||||
if (updateEvent) ((event *)updateEvent) ();
|
||||
}
|
||||
if (attachCallback) attachCallback (0, 0, attachData);
|
||||
return coin_count;
|
||||
}
|
||||
|
||||
u32 __stdcall bnusio_GetSwIn () {
|
||||
u32 sw = 0;
|
||||
sw |= (u32)testEnabled << 7;
|
||||
sw |= (u32)IsButtonDown (DEBUG_ENTER) << 9;
|
||||
sw |= (u32)IsButtonDown (DEBUG_DOWN) << 12;
|
||||
sw |= (u32)IsButtonDown (DEBUG_UP) << 13;
|
||||
sw |= (u32)IsButtonDown (SERVICE) << 14;
|
||||
return sw;
|
||||
}
|
||||
|
||||
i64 __stdcall bnusio_Close () {
|
||||
for (int i = 0; plugins[i] != 0; i++) {
|
||||
FARPROC exitEvent = GetProcAddress (plugins[i], "Exit");
|
||||
if (exitEvent) ((event *)exitEvent) ();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
HOOK_DYNAMIC (u64, __stdcall, bngrw_Init) {
|
||||
for (int i = 0; plugins[i] != 0; i++) {
|
||||
FARPROC initEvent = GetProcAddress (plugins[i], "Init");
|
||||
if (initEvent) ((event *)initEvent) ();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
HOOK_DYNAMIC (u64, __stdcall, bngrw_attach, i32 a1, char *a2, i32 a3, i32 a4, callbackAttach callback, i32 *a6) {
|
||||
// This is way too fucking jank
|
||||
attachCallback = callback;
|
||||
attachData = a6;
|
||||
return 1;
|
||||
}
|
||||
|
||||
HOOK_DYNAMIC (i32, __stdcall, bngrw_reqWaitTouch, u32 a1, i32 a2, u32 a3, callbackTouch callback, u64 a5) {
|
||||
waitingForTouch = true;
|
||||
touchCallback = callback;
|
||||
touchData = a5;
|
||||
for (int i = 0; plugins[i] != 0; i++) {
|
||||
FARPROC touchEvent = GetProcAddress (plugins[i], "WaitTouch");
|
||||
if (touchEvent) ((waitTouchEvent *)touchEvent) (callback, a5);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
HOOK_DYNAMIC (i32, __stdcall, ws2_getaddrinfo, char *node, char *service, void *hints, void *out) {
|
||||
return originalws2_getaddrinfo (server, service, hints, out);
|
||||
}
|
||||
|
||||
u32 inline generate_rand () { return rand () + rand () * rand () + rand (); }
|
||||
|
||||
i32 __stdcall DllMain (HMODULE mod, DWORD cause, void *ctx) {
|
||||
if (cause == DLL_PROCESS_DETACH) DisposePoll ();
|
||||
if (cause != DLL_PROCESS_ATTACH) return true;
|
||||
|
||||
init_boilerplate ();
|
||||
|
||||
INSTALL_HOOK_DYNAMIC (bngrw_attach, PROC_ADDRESS ("bngrw.dll", "BngRwAttach"));
|
||||
INSTALL_HOOK_DYNAMIC (bngrw_reqWaitTouch, PROC_ADDRESS ("bngrw.dll", "BngRwReqWaitTouch"));
|
||||
INSTALL_HOOK_DYNAMIC (bngrw_Init, PROC_ADDRESS ("bngrw.dll", "BngRwInit"));
|
||||
|
||||
INSTALL_HOOK_DYNAMIC (ws2_getaddrinfo, PROC_ADDRESS ("ws2_32.dll", "getaddrinfo"));
|
||||
|
||||
// Set current directory to the directory of the executable
|
||||
// Find all files in the plugins directory that end with .dll
|
||||
// Call loadlibraryW on those files
|
||||
// Create a message box if they fail to load
|
||||
wchar_t path[MAX_PATH];
|
||||
GetModuleFileNameW (NULL, path, MAX_PATH);
|
||||
*wcsrchr (path, '\\') = '\0';
|
||||
SetCurrentDirectoryW (path);
|
||||
|
||||
WIN32_FIND_DATAW fd;
|
||||
int i = 0;
|
||||
HANDLE hFind = FindFirstFileW (L"plugins/*.dll", &fd);
|
||||
if (hFind != INVALID_HANDLE_VALUE) {
|
||||
do {
|
||||
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue;
|
||||
wchar_t filePath[MAX_PATH];
|
||||
wcscpy (filePath, path);
|
||||
wcscat (filePath, L"/plugins/");
|
||||
wcscat (filePath, fd.cFileName);
|
||||
HMODULE hModule = LoadLibraryW (filePath);
|
||||
if (!hModule) {
|
||||
wchar_t buf[128];
|
||||
swprintf (buf, 128, L"Failed to load plugin %d", GetLastError ());
|
||||
MessageBoxW (NULL, buf, fd.cFileName, MB_ICONERROR);
|
||||
} else {
|
||||
plugins[i] = hModule;
|
||||
i++;
|
||||
FARPROC preInitEvent = GetProcAddress (hModule, "PreInit");
|
||||
if (preInitEvent) ((event *)preInitEvent) ();
|
||||
}
|
||||
} while (FindNextFileW (hFind, &fd));
|
||||
FindClose (hFind);
|
||||
}
|
||||
|
||||
toml_table_t *config = openConfig (configPath ("config.toml"));
|
||||
if (config) {
|
||||
drumMax = readConfigInt (config, "drumMax", drumMax);
|
||||
drumMin = readConfigInt (config, "drumMin", drumMin);
|
||||
server = readConfigString (config, "server", server);
|
||||
toml_free (config);
|
||||
}
|
||||
|
||||
FILE *cards = fopen (configPath ("cards.dat"), "r");
|
||||
if (cards) {
|
||||
fread (accessCode1, 1, 20, cards);
|
||||
fread (accessCode2, 1, 20, cards);
|
||||
fread (chipId1, 1, 32, cards);
|
||||
fread (chipId2, 1, 32, cards);
|
||||
fclose (cards);
|
||||
} else {
|
||||
FILE *cards_new = fopen (configPath ("cards.dat"), "w");
|
||||
if (cards_new) {
|
||||
srand (time (0));
|
||||
sprintf (accessCode1, "%020d", generate_rand ());
|
||||
fwrite (accessCode1, 1, 20, cards_new);
|
||||
sprintf (accessCode2, "%020d", generate_rand ());
|
||||
fwrite (accessCode2, 1, 20, cards_new);
|
||||
sprintf (chipId1, "%032X", generate_rand ());
|
||||
fwrite (chipId1, 1, 32, cards_new);
|
||||
sprintf (chipId2, "%032X", generate_rand ());
|
||||
fwrite (chipId2, 1, 32, cards_new);
|
||||
fclose (cards_new);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
149
src/dllmain.cpp
Normal file
149
src/dllmain.cpp
Normal file
@ -0,0 +1,149 @@
|
||||
#include "bnusio.h"
|
||||
#include "helpers.h"
|
||||
#include "patches/patches.h"
|
||||
#include "poll.h"
|
||||
#include <xxhash.h>
|
||||
|
||||
enum class GameVersion : XXH64_hash_t {
|
||||
UNKNOWN = 0,
|
||||
JP_NOV_2020 = 0x67C0F3042746D488,
|
||||
CN_JUN_2023 = 0xA7EE39F2CC2C57C8,
|
||||
};
|
||||
GameVersion version = GameVersion::UNKNOWN;
|
||||
std::vector<HMODULE> plugins;
|
||||
|
||||
const char *server = "127.0.0.1";
|
||||
char accessCode[21] = "00000000000000000000";
|
||||
char chipId[33] = "00000000000000000000000000000000";
|
||||
|
||||
HOOK (i32, ShowMouse, PROC_ADDRESS ("user32.dll", "ShowCursor"), bool) { return originalShowMouse (true); }
|
||||
HOOK (i32, ExitWindows, PROC_ADDRESS ("user32.dll", "ExitWindowsEx")) {
|
||||
ExitProcess (0);
|
||||
return true;
|
||||
}
|
||||
|
||||
HOOK (i32, XinputGetState, PROC_ADDRESS ("xinput9_1_0.dll", "XInputGetState")) { return ERROR_DEVICE_NOT_CONNECTED; }
|
||||
HOOK (i32, XinputSetState, PROC_ADDRESS ("xinput9_1_0.dll", "XInputSetState")) { return ERROR_DEVICE_NOT_CONNECTED; }
|
||||
HOOK (i32, XinputGetCapabilites, PROC_ADDRESS ("xinput9_1_0.dll", "XInputGetCapabilities")) { return ERROR_DEVICE_NOT_CONNECTED; }
|
||||
|
||||
HOOK (i32, ssleay_Shutdown, PROC_ADDRESS ("ssleay32.dll", "SSL_shutdown")) { return 1; }
|
||||
|
||||
HOOK (i64, UsbFinderInitialize, PROC_ADDRESS ("nbamUsbFinder.dll", "nbamUsbFinderInitialize")) { return 0; }
|
||||
HOOK (i64, UsbFinderRelease, PROC_ADDRESS ("nbamUsbFinder.dll", "nbamUsbFinderRelease")) { return 0; }
|
||||
HOOK (i64, UsbFinderGetSerialNumber, PROC_ADDRESS ("nbamUsbFinder.dll", "nbamUsbFinderGetSerialNumber"), i32 a1, char *a2) {
|
||||
strcpy (a2, "284111080001");
|
||||
return 0;
|
||||
}
|
||||
|
||||
HOOK (i32, ws2_getaddrinfo, PROC_ADDRESS ("ws2_32.dll", "getaddrinfo"), const char *node, char *service, void *hints, void *out) { return originalws2_getaddrinfo (server, service, hints, out); }
|
||||
|
||||
void
|
||||
GetGameVersion () {
|
||||
wchar_t w_path[MAX_PATH];
|
||||
GetModuleFileNameW (0, w_path, MAX_PATH);
|
||||
std::filesystem::path path (w_path);
|
||||
|
||||
if (!std::filesystem::exists (path) || !path.has_filename ()) {
|
||||
MessageBoxA (0, "Failed to find executable", 0, MB_OK);
|
||||
ExitProcess (0);
|
||||
}
|
||||
|
||||
std::ifstream stream (path, std::ios::binary);
|
||||
if (!stream.is_open ()) {
|
||||
MessageBoxA (0, "Failed to read executable", 0, MB_OK);
|
||||
ExitProcess (0);
|
||||
}
|
||||
|
||||
stream.seekg (0, stream.end);
|
||||
size_t length = stream.tellg ();
|
||||
stream.seekg (0, stream.beg);
|
||||
|
||||
char *buf = (char *)calloc (length + 1, sizeof (char));
|
||||
stream.read (buf, length);
|
||||
|
||||
version = (GameVersion)XXH64 (buf, length, 0);
|
||||
|
||||
stream.close ();
|
||||
free (buf);
|
||||
|
||||
printf ("%llx\n", (u64)version);
|
||||
switch (version) {
|
||||
case GameVersion::JP_NOV_2020:
|
||||
case GameVersion::CN_JUN_2023: break;
|
||||
default: MessageBoxA (0, "Unknown game version", 0, MB_OK); ExitProcess (0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
createCard () {
|
||||
const char hexCharacterTable[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||
char buf[64] = {0};
|
||||
srand (time (0));
|
||||
|
||||
std::generate (buf, buf + 20, [&] () { return hexCharacterTable[rand () % 10]; });
|
||||
WritePrivateProfileStringA ("card", "accessCode", buf, ".\\card.ini");
|
||||
std::generate (buf, buf + 32, [&] () { return hexCharacterTable[rand () % 16]; });
|
||||
WritePrivateProfileStringA ("card", "chipId", buf, ".\\card.ini");
|
||||
}
|
||||
|
||||
BOOL
|
||||
DllMain (HMODULE module, DWORD reason, LPVOID reserved) {
|
||||
if (reason == DLL_PROCESS_ATTACH) {
|
||||
// This is bad, dont do this
|
||||
// I/O in DllMain can easily cause a deadlock
|
||||
GetGameVersion ();
|
||||
|
||||
auto pluginPath = std::filesystem::current_path () / "plugins";
|
||||
|
||||
if (std::filesystem::exists (pluginPath)) {
|
||||
for (auto entry : std::filesystem::directory_iterator (pluginPath)) {
|
||||
if (entry.path ().extension () == ".dll") {
|
||||
auto name = entry.path ().wstring ();
|
||||
HMODULE hModule = LoadLibraryW (name.c_str ());
|
||||
if (!hModule) {
|
||||
wchar_t buf[128];
|
||||
wsprintfW (buf, L"Failed to load plugin %ls", name.c_str ());
|
||||
MessageBoxW (0, buf, name.c_str (), MB_ICONERROR);
|
||||
} else {
|
||||
plugins.push_back (hModule);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto configPath = std::filesystem::current_path () / "config.toml";
|
||||
toml_table_t *config = openConfig (configPath);
|
||||
if (config) {
|
||||
server = readConfigString (config, "server", server);
|
||||
toml_free (config);
|
||||
}
|
||||
|
||||
if (!std::filesystem::exists (".\\card.ini")) createCard ();
|
||||
GetPrivateProfileStringA ("card", "accessCode", accessCode, accessCode, 21, ".\\card.ini");
|
||||
GetPrivateProfileStringA ("card", "chipId", chipId, chipId, 33, ".\\card.ini");
|
||||
|
||||
INSTALL_HOOK (ShowMouse);
|
||||
INSTALL_HOOK (ExitWindows);
|
||||
|
||||
INSTALL_HOOK (XinputGetState);
|
||||
INSTALL_HOOK (XinputSetState);
|
||||
INSTALL_HOOK (XinputGetCapabilites);
|
||||
|
||||
INSTALL_HOOK (ssleay_Shutdown);
|
||||
|
||||
INSTALL_HOOK (UsbFinderInitialize);
|
||||
INSTALL_HOOK (UsbFinderRelease);
|
||||
INSTALL_HOOK (UsbFinderGetSerialNumber);
|
||||
|
||||
INSTALL_HOOK (ws2_getaddrinfo);
|
||||
|
||||
bnusio::Init ();
|
||||
|
||||
switch (version) {
|
||||
case GameVersion::UNKNOWN: break;
|
||||
case GameVersion::JP_NOV_2020: patches::JP_NOV_2020::Init (); break;
|
||||
case GameVersion::CN_JUN_2023: patches::CN_JUN_2023::Init (); break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
@ -3,28 +3,33 @@
|
||||
|
||||
void *consoleHandle = 0;
|
||||
|
||||
char *
|
||||
configPath (char *name) {
|
||||
static char buffer[MAX_PATH];
|
||||
GetModuleFileNameA (NULL, buffer, MAX_PATH);
|
||||
*(strrchr (buffer, '\\') + 1) = 0;
|
||||
strcat_s (buffer, MAX_PATH, 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);
|
||||
openConfig (std::filesystem::path path) {
|
||||
if (!std::filesystem::exists (path) || !path.has_filename ()) {
|
||||
printWarning ("%s (%s): file does not exist\n", __func__, path.string ().c_str ());
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::ifstream stream (path);
|
||||
if (!stream.is_open ()) {
|
||||
printWarning ("%s (%s): could not open\n", __func__, path.string ().c_str ());
|
||||
return 0;
|
||||
}
|
||||
|
||||
stream.seekg (0, stream.end);
|
||||
size_t length = stream.tellg ();
|
||||
stream.seekg (0, stream.beg);
|
||||
|
||||
char *buf = (char *)calloc (length + 1, sizeof (char));
|
||||
stream.read (buf, length);
|
||||
|
||||
char errorbuf[200];
|
||||
toml_table_t *config = toml_parse_file (file, errorbuf, 200);
|
||||
fclose (file);
|
||||
toml_table_t *config = toml_parse (buf, errorbuf, 200);
|
||||
stream.close ();
|
||||
free (buf);
|
||||
|
||||
if (!config) {
|
||||
printWarning ("%s (%s): %s\n", __func__, configFilePath, errorbuf);
|
||||
printWarning ("%s (%s): %s\n", __func__, path.string ().c_str (), errorbuf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -32,7 +37,7 @@ openConfig (char *configFilePath) {
|
||||
}
|
||||
|
||||
toml_table_t *
|
||||
openConfigSection (toml_table_t *config, char *sectionName) {
|
||||
openConfigSection (toml_table_t *config, const char *sectionName) {
|
||||
toml_table_t *section = toml_table_in (config, sectionName);
|
||||
if (!section) {
|
||||
printWarning ("%s (%s): cannot find section\n", __func__, sectionName);
|
||||
@ -43,7 +48,7 @@ openConfigSection (toml_table_t *config, char *sectionName) {
|
||||
}
|
||||
|
||||
bool
|
||||
readConfigBool (toml_table_t *table, char *key, bool notFoundValue) {
|
||||
readConfigBool (toml_table_t *table, const char *key, bool notFoundValue) {
|
||||
toml_datum_t data = toml_bool_in (table, key);
|
||||
if (!data.ok) return notFoundValue;
|
||||
|
||||
@ -51,15 +56,15 @@ readConfigBool (toml_table_t *table, char *key, bool notFoundValue) {
|
||||
}
|
||||
|
||||
int64_t
|
||||
readConfigInt (toml_table_t *table, char *key, int64_t notFoundValue) {
|
||||
readConfigInt (toml_table_t *table, const 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) {
|
||||
const char *
|
||||
readConfigString (toml_table_t *table, const char *key, const char *notFoundValue) {
|
||||
toml_datum_t data = toml_string_in (table, key);
|
||||
if (!data.ok) return notFoundValue;
|
||||
|
140
src/helpers.h
140
src/helpers.h
@ -1,8 +1,11 @@
|
||||
#pragma once
|
||||
#include <MinHook.h>
|
||||
#include <bits/stdc++.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <toml.h>
|
||||
#include <windows.h>
|
||||
|
||||
@ -14,87 +17,83 @@ typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
typedef float f32;
|
||||
typedef double f64;
|
||||
|
||||
#ifdef DEFINE_GUID
|
||||
#undef DEFINE_GUID
|
||||
#endif
|
||||
|
||||
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
|
||||
|
||||
#ifdef BASE_ADDRESS
|
||||
#define ASLR(address, handle) ((u64)handle + (u64)address - (u64)BASE_ADDRESS)
|
||||
#endif
|
||||
|
||||
#define FUNCTION_PTR(returnType, callingConvention, function, location, ...) \
|
||||
returnType (callingConvention *function) (__VA_ARGS__) = (returnType (callingConvention *) (__VA_ARGS__)) (location)
|
||||
#define FUNCTION_PTR(returnType, function, location, ...) returnType (*function) (__VA_ARGS__) = (returnType (*) (__VA_ARGS__)) (location)
|
||||
#define FUNCTION_PTR_H(returnType, function, ...) extern returnType (*function) (__VA_ARGS__)
|
||||
|
||||
#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 BASE_ADDRESS 0x140000000
|
||||
#ifdef BASE_ADDRESS
|
||||
const HMODULE MODULE_HANDLE = GetModuleHandle (nullptr);
|
||||
#define ASLR(address) ((u64)MODULE_HANDLE + (u64)address - (u64)BASE_ADDRESS)
|
||||
#endif
|
||||
|
||||
#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 HOOK(returnType, functionName, location, ...) \
|
||||
typedef returnType (*functionName) (__VA_ARGS__); \
|
||||
functionName original##functionName = NULL; \
|
||||
void *where##functionName = (void *)location; \
|
||||
returnType 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 VTABLE_HOOK(returnType, className, functionName, ...) \
|
||||
typedef returnType (*className##functionName) (className * This, __VA_ARGS__); \
|
||||
className##functionName original##className##functionName = NULL; \
|
||||
void *where##className##functionName = NULL; \
|
||||
returnType implOf##className##functionName (className *This, __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 = (void *)location; \
|
||||
INSTALL_HOOK (functionName); \
|
||||
#define INSTALL_VTABLE_HOOK(className, object, functionName, functionIndex) \
|
||||
{ \
|
||||
where##className##functionName = (*(className##functionName ***)object)[functionIndex]; \
|
||||
INSTALL_HOOK (className##functionName); \
|
||||
}
|
||||
|
||||
#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 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_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_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 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 RETURN_FALSE(returnType, callingConvention, functionName, ...) \
|
||||
returnType callingConvention functionName (__VA_ARGS__) { return 0; }
|
||||
#define RETURN_TRUE(returnType, callingConvention, functionName, ...) \
|
||||
returnType callingConvention functionName (__VA_ARGS__) { return 1; }
|
||||
|
||||
#define INFO_COLOUR FOREGROUND_GREEN
|
||||
#define WARNING_COLOUR (FOREGROUND_RED | FOREGROUND_GREEN)
|
||||
@ -103,16 +102,9 @@ typedef uint64_t u64;
|
||||
#define printWarning(format, ...) printColour (WARNING_COLOUR, format, __VA_ARGS__)
|
||||
#define printError(format, ...) printColour (ERROR_COLOUR, format, __VA_ARGS__)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
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);
|
||||
toml_table_t *openConfig (std::filesystem::path path);
|
||||
toml_table_t *openConfigSection (toml_table_t *config, const char *sectionName);
|
||||
bool readConfigBool (toml_table_t *table, const char *key, bool notFoundValue);
|
||||
int64_t readConfigInt (toml_table_t *table, const char *key, int64_t notFoundValue);
|
||||
const char *readConfigString (toml_table_t *table, const char *key, const char *notFoundValue);
|
||||
void printColour (int colour, const char *format, ...);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
80
src/patches/cn_jun_2023.cpp
Normal file
80
src/patches/cn_jun_2023.cpp
Normal file
@ -0,0 +1,80 @@
|
||||
#include "helpers.h"
|
||||
namespace patches::CN_JUN_2023 {
|
||||
|
||||
i32 xRes = 1360;
|
||||
i32 yRes = 768;
|
||||
bool unlockSongs = true;
|
||||
bool sharedAudio = true;
|
||||
bool vsync = false;
|
||||
|
||||
u8 *haspBuffer;
|
||||
HOOK (i32, HaspDecrypt, PROC_ADDRESS ("hasp_windows_x64.dll", "hasp_decrypt")) { return 0; }
|
||||
HOOK (i32, HaspEncrypt, PROC_ADDRESS ("hasp_windows_x64.dll", "hasp_encrypt")) { return 0; }
|
||||
HOOK (i32, HaspLogout, PROC_ADDRESS ("hasp_windows_x64.dll", "hasp_logout")) { return 0; }
|
||||
HOOK (i32, HaspWrite, PROC_ADDRESS ("hasp_windows_x64.dll", "hasp_write")) { return 0; }
|
||||
HOOK (i32, HaspLogin, PROC_ADDRESS ("hasp_windows_x64.dll", "hasp_login"), i32, char *, i32 *id) {
|
||||
*id = 1;
|
||||
return 0;
|
||||
}
|
||||
HOOK (i32, HaspGetInfo, PROC_ADDRESS ("hasp_windows_x64.dll", "hasp_get_info"), const char *, const char *, void *, const char **a4) {
|
||||
*a4 = "type=\"HASP-HL\"";
|
||||
return 0;
|
||||
}
|
||||
HOOK (i32, HaspRead, PROC_ADDRESS ("hasp_windows_x64.dll", "hasp_read"), i32, i32, i32 offset, i32 length, void *buffer) {
|
||||
memcpy (buffer, haspBuffer + offset, length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Init () {
|
||||
haspBuffer = (u8 *)malloc (0xD40);
|
||||
memset (haspBuffer, 0, 0xD40);
|
||||
strcpy ((char *)(haspBuffer + 0xD00), "284111080001");
|
||||
u8 crc = 0;
|
||||
for (int i = 0; i < 62; i++)
|
||||
crc += haspBuffer[0xD00 + i];
|
||||
haspBuffer[0xD3E] = crc;
|
||||
haspBuffer[0xD3F] = haspBuffer[0xD3E] ^ 0xFF;
|
||||
|
||||
INSTALL_HOOK (HaspDecrypt);
|
||||
INSTALL_HOOK (HaspEncrypt);
|
||||
INSTALL_HOOK (HaspLogout);
|
||||
INSTALL_HOOK (HaspWrite);
|
||||
INSTALL_HOOK (HaspLogin);
|
||||
INSTALL_HOOK (HaspGetInfo);
|
||||
INSTALL_HOOK (HaspRead);
|
||||
|
||||
auto configPath = std::filesystem::current_path () / "config.toml";
|
||||
toml_table_t *config = openConfig (configPath);
|
||||
if (config) {
|
||||
auto res = openConfigSection (config, "res");
|
||||
if (res) {
|
||||
xRes = readConfigInt (res, "x", xRes);
|
||||
yRes = readConfigInt (res, "y", yRes);
|
||||
}
|
||||
unlockSongs = readConfigBool (config, "unlock_songs", unlockSongs);
|
||||
sharedAudio = readConfigBool (config, "shared_audio", sharedAudio);
|
||||
vsync = readConfigBool (config, "vsync", vsync);
|
||||
toml_free (config);
|
||||
}
|
||||
|
||||
WRITE_MEMORY (ASLR (0x14003F690), u8, 0xC3); // Skip errors
|
||||
if (unlockSongs) WRITE_MEMORY (ASLR (0x140425BCD), u8, 0xB0, 0x01);
|
||||
if (sharedAudio) WRITE_MEMORY (ASLR (0x140777F87), u8, 0xEB);
|
||||
if (!vsync) WRITE_MEMORY (ASLR (0x1405FC5B9), u8, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x90);
|
||||
|
||||
// Move various files to current dir
|
||||
WRITE_MEMORY (ASLR (0x140C7B158), char, "./SettingChina1.bin");
|
||||
WRITE_MEMORY (ASLR (0x140C7B2B8), char, "./SettingChina1.bin");
|
||||
WRITE_MEMORY (ASLR (0x140C7B2A0), char, "./SettingChina2.bin");
|
||||
WRITE_MEMORY (ASLR (0x140C33C40), char, "./");
|
||||
WRITE_MEMORY (ASLR (0x140C33C44), char, "./");
|
||||
|
||||
// Res
|
||||
WRITE_MEMORY (ASLR (0x1404A4ED3), i32, xRes);
|
||||
WRITE_MEMORY (ASLR (0x1404A4EDA), i32, yRes);
|
||||
|
||||
// Use TLS v1.2
|
||||
WRITE_MEMORY (ASLR (0x140369662), u8, 0x10);
|
||||
}
|
||||
} // namespace patches::CN_JUN_2023
|
9
src/patches/jp_nov_2020.cpp
Normal file
9
src/patches/jp_nov_2020.cpp
Normal file
@ -0,0 +1,9 @@
|
||||
#include "helpers.h"
|
||||
|
||||
namespace patches::JP_NOV_2020 {
|
||||
void
|
||||
Init () {
|
||||
MessageBoxA (0, "08.18 is currently not supported", 0, 0);
|
||||
ExitProcess (0);
|
||||
}
|
||||
} // namespace patches::JP_NOV_2020
|
8
src/patches/patches.h
Normal file
8
src/patches/patches.h
Normal file
@ -0,0 +1,8 @@
|
||||
namespace patches {
|
||||
namespace JP_NOV_2020 {
|
||||
void Init ();
|
||||
} // namespace JP_NOV_2020
|
||||
namespace CN_JUN_2023 {
|
||||
void Init ();
|
||||
} // namespace CN_JUN_2023
|
||||
} // namespace patches
|
533
src/poll.c
533
src/poll.c
@ -1,533 +0,0 @@
|
||||
#include "poll.h"
|
||||
#include "SDL3/SDL_gamepad.h"
|
||||
#include "SDL3/SDL_joystick.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_GamepadButton button;
|
||||
} ConfigControllerButtons[] = {
|
||||
{ "SDL_A", SDL_GAMEPAD_BUTTON_A },
|
||||
{ "SDL_B", SDL_GAMEPAD_BUTTON_B },
|
||||
{ "SDL_X", SDL_GAMEPAD_BUTTON_X },
|
||||
{ "SDL_Y", SDL_GAMEPAD_BUTTON_Y },
|
||||
{ "SDL_BACK", SDL_GAMEPAD_BUTTON_BACK },
|
||||
{ "SDL_GUIDE", SDL_GAMEPAD_BUTTON_GUIDE },
|
||||
{ "SDL_START", SDL_GAMEPAD_BUTTON_START },
|
||||
{ "SDL_LSTICK_PRESS", SDL_GAMEPAD_BUTTON_LEFT_STICK },
|
||||
{ "SDL_RSTICK_PRESS", SDL_GAMEPAD_BUTTON_RIGHT_STICK },
|
||||
{ "SDL_LSHOULDER", SDL_GAMEPAD_BUTTON_LEFT_SHOULDER },
|
||||
{ "SDL_RSHOULDER", SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER },
|
||||
{ "SDL_DPAD_UP", SDL_GAMEPAD_BUTTON_DPAD_UP },
|
||||
{ "SDL_DPAD_DOWN", SDL_GAMEPAD_BUTTON_DPAD_DOWN },
|
||||
{ "SDL_DPAD_LEFT", SDL_GAMEPAD_BUTTON_DPAD_LEFT },
|
||||
{ "SDL_DPAD_RIGHT", SDL_GAMEPAD_BUTTON_DPAD_RIGHT },
|
||||
{ "SDL_MISC", SDL_GAMEPAD_BUTTON_MISC1 },
|
||||
{ "SDL_PADDLE1", SDL_GAMEPAD_BUTTON_PADDLE1 },
|
||||
{ "SDL_PADDLE2", SDL_GAMEPAD_BUTTON_PADDLE2 },
|
||||
{ "SDL_PADDLE3", SDL_GAMEPAD_BUTTON_PADDLE3 },
|
||||
{ "SDL_PADDLE4", SDL_GAMEPAD_BUTTON_PADDLE4 },
|
||||
{ "SDL_TOUCHPAD", SDL_GAMEPAD_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_GAMEPAD_BUTTON_MAX];
|
||||
bool lastControllerButtonsState[SDL_GAMEPAD_BUTTON_MAX];
|
||||
struct SDLAxisState currentControllerAxisState;
|
||||
struct SDLAxisState lastControllerAxisState;
|
||||
|
||||
SDL_Window *window;
|
||||
SDL_Gamepad *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_GAMEPAD_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_GAMEPAD_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 *windowHandle) {
|
||||
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_GAMEPAD | SDL_INIT_EVENTS | SDL_INIT_VIDEO) != 0) {
|
||||
if (SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD | 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_AddGamepadMappingsFromFile (configPath ("gamecontrollerdb.txt")) == -1)
|
||||
printError ("%s (): Cannot read gamecontrollerdb.txt\n", __func__);
|
||||
|
||||
int count = 0;
|
||||
SDL_JoystickID *joysticks = SDL_GetJoysticks (&count);
|
||||
if (joysticks == 0) { return hasRumble; }
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (!SDL_IsGamepad (joysticks[i])) continue;
|
||||
|
||||
SDL_Gamepad *controller = SDL_OpenGamepad (joysticks[i]);
|
||||
|
||||
if (!controller) { continue; }
|
||||
|
||||
printInfo ("%s: %s\n", SDL_GetGamepadName (controller), SDL_GetGamepadMapping (controller));
|
||||
controllers[i] = controller;
|
||||
}
|
||||
|
||||
window = SDL_CreateWindowFrom (windowHandle);
|
||||
if (window != NULL) SDL_SetWindowResizable (window, true);
|
||||
else printError ("SDL_CreateWindowFrom (windowHandle): %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_GAMEPADADDED:
|
||||
if (!SDL_IsGamepad (event.cdevice.which)) break;
|
||||
|
||||
SDL_Gamepad *controller = SDL_OpenGamepad (event.cdevice.which);
|
||||
|
||||
if (!controller) { continue; }
|
||||
printInfo ("%s: %s\n", SDL_GetGamepadName (controller), SDL_GetGamepadMapping (controller));
|
||||
controllers[event.cdevice.which] = controller;
|
||||
break;
|
||||
case SDL_GAMEPADREMOVED:
|
||||
printInfo ("%s: %s\n", SDL_GetGamepadName (controllers[event.cdevice.which]), SDL_GetGamepadMapping (controllers[event.cdevice.which]));
|
||||
if (!SDL_IsGamepad (event.cdevice.which)) break;
|
||||
SDL_CloseGamepad (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_GAMEPADBUTTONUP:
|
||||
case SDL_GAMEPADBUTTONDOWN:
|
||||
currentControllerButtonsState[event.cbutton.button] = event.cbutton.state;
|
||||
printInfo ("%s\n", SDL_GetGamepadStringForButton (event.cbutton.button));
|
||||
break;
|
||||
case SDL_GAMEPADAXISMOTION:
|
||||
if (event.caxis.value > 8000) {
|
||||
switch (event.caxis.axis) {
|
||||
case SDL_GAMEPAD_AXIS_LEFTX: currentControllerAxisState.LeftRight = 1; break;
|
||||
case SDL_GAMEPAD_AXIS_LEFTY: currentControllerAxisState.LeftDown = 1; break;
|
||||
case SDL_GAMEPAD_AXIS_RIGHTX: currentControllerAxisState.RightRight = 1; break;
|
||||
case SDL_GAMEPAD_AXIS_RIGHTY: currentControllerAxisState.RightDown = 1; break;
|
||||
case SDL_GAMEPAD_AXIS_LEFT_TRIGGER: currentControllerAxisState.LTriggerDown = 1; break;
|
||||
case SDL_GAMEPAD_AXIS_RIGHT_TRIGGER: currentControllerAxisState.RTriggerDown = 1; break;
|
||||
}
|
||||
} else if (event.caxis.value < -8000) {
|
||||
switch (event.caxis.axis) {
|
||||
case SDL_GAMEPAD_AXIS_LEFTX: currentControllerAxisState.LeftLeft = 1; break;
|
||||
case SDL_GAMEPAD_AXIS_LEFTY: currentControllerAxisState.LeftUp = 1; break;
|
||||
case SDL_GAMEPAD_AXIS_RIGHTX: currentControllerAxisState.RightLeft = 1; break;
|
||||
case SDL_GAMEPAD_AXIS_RIGHTY: currentControllerAxisState.RightUp = 1; break;
|
||||
}
|
||||
} else {
|
||||
switch (event.caxis.axis) {
|
||||
case SDL_GAMEPAD_AXIS_LEFTX:
|
||||
currentControllerAxisState.LeftRight = 0;
|
||||
currentControllerAxisState.LeftLeft = 0;
|
||||
break;
|
||||
case SDL_GAMEPAD_AXIS_LEFTY:
|
||||
currentControllerAxisState.LeftDown = 0;
|
||||
currentControllerAxisState.LeftUp = 0;
|
||||
break;
|
||||
case SDL_GAMEPAD_AXIS_RIGHTX:
|
||||
currentControllerAxisState.RightRight = 0;
|
||||
currentControllerAxisState.RightLeft = 0;
|
||||
break;
|
||||
case SDL_GAMEPAD_AXIS_RIGHTY:
|
||||
currentControllerAxisState.RightDown = 0;
|
||||
currentControllerAxisState.RightUp = 0;
|
||||
break;
|
||||
case SDL_GAMEPAD_AXIS_LEFT_TRIGGER: currentControllerAxisState.LTriggerDown = 0; break;
|
||||
case SDL_GAMEPAD_AXIS_RIGHT_TRIGGER: 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_GAMEPAD_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_GamepadHasRumble (controllers[i])) continue;
|
||||
|
||||
SDL_RumbleGamepad (controllers[i], left, right, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
KeyboardIsDown (uint8_t keycode) {
|
||||
return currentKeyboardState[keycode];
|
||||
}
|
||||
|
||||
bool
|
||||
KeyboardIsUp (uint8_t keycode) {
|
||||
return !KeyboardIsDown (keycode);
|
||||
}
|
||||
|
||||
bool
|
||||
KeyboardIsTapped (uint8_t keycode) {
|
||||
return KeyboardIsDown (keycode) && KeyboardWasUp (keycode);
|
||||
}
|
||||
|
||||
bool
|
||||
KeyboardIsReleased (uint8_t keycode) {
|
||||
return KeyboardIsUp (keycode) && KeyboardWasDown (keycode);
|
||||
}
|
||||
|
||||
bool
|
||||
KeyboardWasDown (uint8_t keycode) {
|
||||
return lastKeyboardState[keycode];
|
||||
}
|
||||
|
||||
bool
|
||||
KeyboardWasUp (uint8_t keycode) {
|
||||
return !KeyboardWasDown (keycode);
|
||||
}
|
||||
|
||||
POINT
|
||||
GetMousePosition () { return currentMouseState.Position; }
|
||||
|
||||
POINT
|
||||
GetLastMousePosition () { return lastMouseState.Position; }
|
||||
|
||||
POINT
|
||||
GetMouseRelativePosition () { return currentMouseState.RelativePosition; }
|
||||
|
||||
POINT
|
||||
GetLastMouseRelativePosition () { return lastMouseState.RelativePosition; }
|
||||
|
||||
void
|
||||
SetMousePosition (POINT newPosition) {
|
||||
currentMouseState.Position = newPosition;
|
||||
}
|
||||
|
||||
bool
|
||||
GetMouseScrollUp () {
|
||||
return currentMouseState.ScrolledUp;
|
||||
}
|
||||
|
||||
bool
|
||||
GetMouseScrollDown () {
|
||||
return currentMouseState.ScrolledDown;
|
||||
}
|
||||
|
||||
bool
|
||||
GetWasMouseScrollUp () {
|
||||
return lastMouseState.ScrolledUp;
|
||||
}
|
||||
|
||||
bool
|
||||
GetWasMouseScrollDown () {
|
||||
return lastMouseState.ScrolledDown;
|
||||
}
|
||||
|
||||
bool
|
||||
GetMouseScrollIsReleased (enum Scroll scroll) {
|
||||
if (scroll == MOUSE_SCROLL_UP) return !GetMouseScrollUp () && GetWasMouseScrollUp ();
|
||||
else return !GetMouseScrollDown () && GetWasMouseScrollDown ();
|
||||
}
|
||||
|
||||
bool
|
||||
GetMouseScrollIsDown (enum Scroll scroll) {
|
||||
if (scroll == MOUSE_SCROLL_UP) return GetMouseScrollUp ();
|
||||
else return GetMouseScrollDown ();
|
||||
}
|
||||
|
||||
bool
|
||||
GetMouseScrollIsTapped (enum Scroll scroll) {
|
||||
if (scroll == MOUSE_SCROLL_UP) return GetMouseScrollUp () && !GetWasMouseScrollUp ();
|
||||
else return GetMouseScrollDown () && !GetWasMouseScrollDown ();
|
||||
}
|
||||
|
||||
bool
|
||||
ControllerButtonIsDown (SDL_GamepadButton button) {
|
||||
return currentControllerButtonsState[button];
|
||||
}
|
||||
|
||||
bool
|
||||
ControllerButtonIsUp (SDL_GamepadButton button) {
|
||||
return !ControllerButtonIsDown (button);
|
||||
}
|
||||
|
||||
bool
|
||||
ControllerButtonWasDown (SDL_GamepadButton button) {
|
||||
return lastControllerButtonsState[button];
|
||||
}
|
||||
|
||||
bool
|
||||
ControllerButtonWasUp (SDL_GamepadButton button) {
|
||||
return !ControllerButtonWasDown (button);
|
||||
}
|
||||
|
||||
bool
|
||||
ControllerButtonIsTapped (SDL_GamepadButton button) {
|
||||
return ControllerButtonIsDown (button) && ControllerButtonWasUp (button);
|
||||
}
|
||||
|
||||
bool
|
||||
ControllerButtonIsReleased (SDL_GamepadButton button) {
|
||||
return ControllerButtonIsUp (button) && ControllerButtonWasDown (button);
|
||||
}
|
||||
|
||||
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;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ControllerAxisIsUp (enum SDLAxis axis) {
|
||||
return !ControllerAxisIsDown (axis);
|
||||
}
|
||||
|
||||
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;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ControllerAxisWasUp (enum SDLAxis axis) {
|
||||
return !ControllerAxisWasDown (axis);
|
||||
}
|
||||
|
||||
bool
|
||||
ControllerAxisIsTapped (enum SDLAxis axis) {
|
||||
return ControllerAxisIsDown (axis) && ControllerAxisWasUp (axis);
|
||||
}
|
||||
|
||||
bool
|
||||
ControllerAxisIsReleased (enum SDLAxis axis) {
|
||||
return ControllerAxisIsUp (axis) && ControllerAxisWasDown (axis);
|
||||
}
|
||||
|
||||
bool
|
||||
IsButtonTapped (struct Keybindings bindings) {
|
||||
return GetInternalButtonState (bindings).Tapped;
|
||||
}
|
||||
|
||||
bool
|
||||
IsButtonReleased (struct Keybindings bindings) {
|
||||
return GetInternalButtonState (bindings).Released;
|
||||
}
|
||||
|
||||
bool
|
||||
IsButtonDown (struct Keybindings bindings) {
|
||||
return GetInternalButtonState (bindings).Down;
|
||||
}
|
628
src/poll.cpp
Normal file
628
src/poll.cpp
Normal file
@ -0,0 +1,628 @@
|
||||
#include "poll.h"
|
||||
#include "helpers.h"
|
||||
#include <windows.h>
|
||||
|
||||
struct {
|
||||
const char *string;
|
||||
uint8_t keycode;
|
||||
} ConfigKeyboardButtons[] = {
|
||||
{"F1", VK_F1},
|
||||
{"F2", VK_F2},
|
||||
{"F3", VK_F3},
|
||||
{"F4", VK_F4},
|
||||
{"F5", VK_F5},
|
||||
{"F6", VK_F6},
|
||||
{"F7", VK_F7},
|
||||
{"F8", VK_F8},
|
||||
{"F9", VK_F9},
|
||||
{"F10", VK_F10},
|
||||
{"F11", VK_F11},
|
||||
{"F12", VK_F12},
|
||||
{"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", VK_UP},
|
||||
{"LEFTARROW", VK_LEFT},
|
||||
{"DOWNARROW", VK_DOWN},
|
||||
{"RIGHTARROW", VK_RIGHT},
|
||||
{"ENTER", VK_RETURN},
|
||||
{"SPACE", VK_SPACE},
|
||||
{"CONTROL", VK_CONTROL},
|
||||
{"SHIFT", VK_SHIFT},
|
||||
{"TAB", VK_TAB},
|
||||
{"ESCAPE", VK_ESCAPE},
|
||||
};
|
||||
|
||||
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;
|
||||
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;
|
||||
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];
|
||||
SDLAxisState currentControllerAxisState;
|
||||
SDLAxisState lastControllerAxisState;
|
||||
|
||||
SDL_Window *window;
|
||||
SDL_GameController *controllers[255];
|
||||
|
||||
void
|
||||
SetConfigValue (toml_table_t *table, const char *key, 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 (size_t i = 0; i < COUNTOFARR (keybind->buttons); i++)
|
||||
keybind->buttons[i] = SDL_CONTROLLER_BUTTON_INVALID;
|
||||
|
||||
for (size_t i = 0;; i++) {
|
||||
toml_datum_t bind = toml_string_at (array, i);
|
||||
if (!bind.ok) break;
|
||||
ConfigValue value = StringToConfigEnum (bind.u.s);
|
||||
free (bind.u.s);
|
||||
|
||||
switch (value.type) {
|
||||
case keycode:
|
||||
for (size_t i = 0; i < COUNTOFARR (keybind->keycodes); i++) {
|
||||
if (keybind->keycodes[i] == 0) {
|
||||
keybind->keycodes[i] = value.keycode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case button:
|
||||
for (size_t 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 (size_t i = 0; i < COUNTOFARR (keybind->axis); i++) {
|
||||
if (keybind->axis[i] == 0) {
|
||||
keybind->axis[i] = value.axis;
|
||||
break;
|
||||
}
|
||||
}
|
||||
case scroll:
|
||||
for (size_t i = 0; i < COUNTOFARR (keybind->scroll); i++) {
|
||||
if (keybind->scroll[i] == 0) {
|
||||
keybind->scroll[i] = value.scroll;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
InitializePoll (HWND windowHandle) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
auto configPath = std::filesystem::current_path () / "gamecontrollerdb.txt";
|
||||
if (SDL_GameControllerAddMappingsFromFile (configPath.string ().c_str ()) == -1) printError ("%s (): Cannot read gamecontrollerdb.txt\n", __func__);
|
||||
SDL_GameControllerEventState (SDL_ENABLE);
|
||||
SDL_JoystickEventState (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;
|
||||
}
|
||||
|
||||
window = SDL_CreateWindowFrom (windowHandle);
|
||||
if (window != NULL) SDL_SetWindowResizable (window, SDL_TRUE);
|
||||
else printError ("SDL_CreateWindowFrom (windowHandle): %s\n", SDL_GetError ());
|
||||
|
||||
atexit (DisposePoll);
|
||||
|
||||
return hasRumble;
|
||||
}
|
||||
|
||||
void
|
||||
UpdatePoll (HWND windowHandle) {
|
||||
if (windowHandle == NULL || GetForegroundWindow () != windowHandle) 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;
|
||||
|
||||
GetCursorPos (¤tMouseState.Position);
|
||||
ScreenToClient (windowHandle, ¤tMouseState.Position);
|
||||
|
||||
SDL_Event event;
|
||||
SDL_GameController *controller;
|
||||
while (SDL_PollEvent (&event) != 0) {
|
||||
switch (event.type) {
|
||||
case SDL_CONTROLLERDEVICEADDED:
|
||||
if (!SDL_IsGameController (event.cdevice.which)) break;
|
||||
|
||||
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 > 1) {
|
||||
switch (event.caxis.axis) {
|
||||
case SDL_CONTROLLER_AXIS_LEFTX:
|
||||
currentControllerAxisState.LeftRight = (float)event.caxis.value / 32767;
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_LEFTY:
|
||||
currentControllerAxisState.LeftDown = (float)event.caxis.value / 32767;
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_RIGHTX:
|
||||
currentControllerAxisState.RightRight = (float)event.caxis.value / 32767;
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_RIGHTY:
|
||||
currentControllerAxisState.RightDown = (float)event.caxis.value / 32767;
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
|
||||
currentControllerAxisState.LTriggerDown = (float)event.caxis.value / 32767;
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
|
||||
currentControllerAxisState.RTriggerDown = (float)event.caxis.value / 32767;
|
||||
break;
|
||||
}
|
||||
} else if (event.caxis.value < -1) {
|
||||
switch (event.caxis.axis) {
|
||||
case SDL_CONTROLLER_AXIS_LEFTX:
|
||||
currentControllerAxisState.LeftLeft = (float)event.caxis.value / -32768;
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_LEFTY:
|
||||
currentControllerAxisState.LeftUp = (float)event.caxis.value / -32768;
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_RIGHTX:
|
||||
currentControllerAxisState.RightLeft = (float)event.caxis.value / -32768;
|
||||
break;
|
||||
case SDL_CONTROLLER_AXIS_RIGHTY:
|
||||
currentControllerAxisState.RightUp = (float)event.caxis.value / -32768;
|
||||
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 ();
|
||||
}
|
||||
|
||||
ConfigValue
|
||||
StringToConfigEnum (const char *value) {
|
||||
ConfigValue rval;
|
||||
for (size_t i = 0; i < COUNTOFARR (ConfigKeyboardButtons); ++i)
|
||||
if (!strcmp (value, ConfigKeyboardButtons[i].string)) {
|
||||
rval.type = keycode;
|
||||
rval.keycode = ConfigKeyboardButtons[i].keycode;
|
||||
return rval;
|
||||
}
|
||||
for (size_t i = 0; i < COUNTOFARR (ConfigControllerButtons); ++i)
|
||||
if (!strcmp (value, ConfigControllerButtons[i].string)) {
|
||||
rval.type = button;
|
||||
rval.button = ConfigControllerButtons[i].button;
|
||||
return rval;
|
||||
}
|
||||
for (size_t i = 0; i < COUNTOFARR (ConfigControllerAXIS); ++i)
|
||||
if (!strcmp (value, ConfigControllerAXIS[i].string)) {
|
||||
rval.type = axis;
|
||||
rval.axis = ConfigControllerAXIS[i].axis;
|
||||
return rval;
|
||||
}
|
||||
for (size_t 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;
|
||||
}
|
||||
|
||||
InternalButtonState
|
||||
GetInternalButtonState (Keybindings bindings) {
|
||||
InternalButtonState buttons = {0};
|
||||
|
||||
for (size_t 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 (size_t 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 (size_t i = 0; i < COUNTOFARR (ConfigControllerAXIS); i++) {
|
||||
if (bindings.axis[i] == 0) continue;
|
||||
if (float val = ControllerAxisIsReleased (bindings.axis[i])) buttons.Released = val;
|
||||
if (float val = ControllerAxisIsDown (bindings.axis[i])) buttons.Down = val;
|
||||
if (float val = ControllerAxisIsTapped (bindings.axis[i])) buttons.Tapped = val;
|
||||
}
|
||||
for (size_t 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, int length) {
|
||||
for (size_t i = 0; i < COUNTOFARR (controllers); i++) {
|
||||
if (!controllers[i] || !SDL_GameControllerHasRumble (controllers[i])) continue;
|
||||
|
||||
SDL_GameControllerRumble (controllers[i], left, right, length);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
KeyboardIsDown (uint8_t keycode) {
|
||||
return currentKeyboardState[keycode];
|
||||
}
|
||||
|
||||
bool
|
||||
KeyboardIsUp (uint8_t keycode) {
|
||||
return !KeyboardIsDown (keycode);
|
||||
}
|
||||
|
||||
bool
|
||||
KeyboardIsTapped (uint8_t keycode) {
|
||||
return KeyboardIsDown (keycode) && KeyboardWasUp (keycode);
|
||||
}
|
||||
|
||||
bool
|
||||
KeyboardIsReleased (uint8_t keycode) {
|
||||
return KeyboardIsUp (keycode) && KeyboardWasDown (keycode);
|
||||
}
|
||||
|
||||
bool
|
||||
KeyboardWasDown (uint8_t keycode) {
|
||||
return lastKeyboardState[keycode];
|
||||
}
|
||||
|
||||
bool
|
||||
KeyboardWasUp (uint8_t keycode) {
|
||||
return !KeyboardWasDown (keycode);
|
||||
}
|
||||
|
||||
POINT
|
||||
GetMousePosition () { return currentMouseState.Position; }
|
||||
|
||||
POINT
|
||||
GetLastMousePosition () { return lastMouseState.Position; }
|
||||
|
||||
POINT
|
||||
GetMouseRelativePosition () { return currentMouseState.RelativePosition; }
|
||||
|
||||
POINT
|
||||
GetLastMouseRelativePosition () { return lastMouseState.RelativePosition; }
|
||||
|
||||
void
|
||||
SetMousePosition (POINT newPosition) {
|
||||
currentMouseState.Position = newPosition;
|
||||
}
|
||||
|
||||
bool
|
||||
GetMouseScrollUp () {
|
||||
return currentMouseState.ScrolledUp;
|
||||
}
|
||||
|
||||
bool
|
||||
GetMouseScrollDown () {
|
||||
return currentMouseState.ScrolledDown;
|
||||
}
|
||||
|
||||
bool
|
||||
GetWasMouseScrollUp () {
|
||||
return lastMouseState.ScrolledUp;
|
||||
}
|
||||
|
||||
bool
|
||||
GetWasMouseScrollDown () {
|
||||
return lastMouseState.ScrolledDown;
|
||||
}
|
||||
|
||||
bool
|
||||
GetMouseScrollIsReleased (Scroll scroll) {
|
||||
if (scroll == MOUSE_SCROLL_UP) return !GetMouseScrollUp () && GetWasMouseScrollUp ();
|
||||
else return !GetMouseScrollDown () && GetWasMouseScrollDown ();
|
||||
}
|
||||
|
||||
bool
|
||||
GetMouseScrollIsDown (Scroll scroll) {
|
||||
if (scroll == MOUSE_SCROLL_UP) return GetMouseScrollUp ();
|
||||
else return GetMouseScrollDown ();
|
||||
}
|
||||
|
||||
bool
|
||||
GetMouseScrollIsTapped (Scroll scroll) {
|
||||
if (scroll == MOUSE_SCROLL_UP) return GetMouseScrollUp () && !GetWasMouseScrollUp ();
|
||||
else return GetMouseScrollDown () && !GetWasMouseScrollDown ();
|
||||
}
|
||||
|
||||
bool
|
||||
ControllerButtonIsDown (SDL_GameControllerButton button) {
|
||||
return currentControllerButtonsState[button];
|
||||
}
|
||||
|
||||
bool
|
||||
ControllerButtonIsUp (SDL_GameControllerButton button) {
|
||||
return !ControllerButtonIsDown (button);
|
||||
}
|
||||
|
||||
bool
|
||||
ControllerButtonWasDown (SDL_GameControllerButton button) {
|
||||
return lastControllerButtonsState[button];
|
||||
}
|
||||
|
||||
bool
|
||||
ControllerButtonWasUp (SDL_GameControllerButton button) {
|
||||
return !ControllerButtonWasDown (button);
|
||||
}
|
||||
|
||||
bool
|
||||
ControllerButtonIsTapped (SDL_GameControllerButton button) {
|
||||
return ControllerButtonIsDown (button) && ControllerButtonWasUp (button);
|
||||
}
|
||||
|
||||
bool
|
||||
ControllerButtonIsReleased (SDL_GameControllerButton button) {
|
||||
return ControllerButtonIsUp (button) && ControllerButtonWasDown (button);
|
||||
}
|
||||
|
||||
float
|
||||
ControllerAxisIsDown (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;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ControllerAxisIsUp (SDLAxis axis) {
|
||||
return !ControllerAxisIsDown (axis);
|
||||
}
|
||||
|
||||
float
|
||||
ControllerAxisWasDown (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;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ControllerAxisWasUp (SDLAxis axis) {
|
||||
return !ControllerAxisWasDown (axis);
|
||||
}
|
||||
|
||||
bool
|
||||
ControllerAxisIsTapped (SDLAxis axis) {
|
||||
return ControllerAxisIsDown (axis) && ControllerAxisWasUp (axis);
|
||||
}
|
||||
|
||||
bool
|
||||
ControllerAxisIsReleased (SDLAxis axis) {
|
||||
return ControllerAxisIsUp (axis) && ControllerAxisWasDown (axis);
|
||||
}
|
||||
|
||||
bool
|
||||
IsButtonTapped (Keybindings bindings) {
|
||||
return GetInternalButtonState (bindings).Tapped;
|
||||
}
|
||||
|
||||
bool
|
||||
IsButtonReleased (Keybindings bindings) {
|
||||
return GetInternalButtonState (bindings).Released;
|
||||
}
|
||||
|
||||
float
|
||||
IsButtonDown (Keybindings bindings) {
|
||||
return GetInternalButtonState (bindings).Down;
|
||||
}
|
209
src/poll.h
209
src/poll.h
@ -1,106 +1,103 @@
|
||||
#pragma once
|
||||
#include <SDL3/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_GamepadButton buttons[255];
|
||||
enum SDLAxis axis[255];
|
||||
enum Scroll scroll[2];
|
||||
};
|
||||
|
||||
typedef struct Keybindings Keybindings;
|
||||
|
||||
enum EnumType { none, keycode, button, axis, scroll };
|
||||
|
||||
struct ConfigValue {
|
||||
enum EnumType type;
|
||||
union {
|
||||
uint8_t keycode;
|
||||
SDL_GamepadButton 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 newPosition);
|
||||
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_GamepadButton button);
|
||||
bool ControllerButtonIsUp (SDL_GamepadButton button);
|
||||
bool ControllerButtonWasDown (SDL_GamepadButton button);
|
||||
bool ControllerButtonWasUp (SDL_GamepadButton button);
|
||||
bool ControllerButtonIsTapped (SDL_GamepadButton button);
|
||||
bool ControllerButtonIsReleased (SDL_GamepadButton 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);
|
||||
#pragma once
|
||||
#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 {
|
||||
float LeftLeft;
|
||||
float LeftRight;
|
||||
float LeftUp;
|
||||
float LeftDown;
|
||||
float RightLeft;
|
||||
float RightRight;
|
||||
float RightUp;
|
||||
float RightDown;
|
||||
float LTriggerDown;
|
||||
float RTriggerDown;
|
||||
};
|
||||
|
||||
enum Scroll { MOUSE_SCROLL_INVALID, MOUSE_SCROLL_UP, MOUSE_SCROLL_DOWN };
|
||||
|
||||
struct Keybindings {
|
||||
uint8_t keycodes[255];
|
||||
SDL_GameControllerButton buttons[255];
|
||||
SDLAxis axis[255];
|
||||
Scroll scroll[2];
|
||||
};
|
||||
|
||||
enum EnumType { none, keycode, button, axis, scroll };
|
||||
|
||||
struct ConfigValue {
|
||||
EnumType type;
|
||||
union {
|
||||
uint8_t keycode;
|
||||
SDL_GameControllerButton button;
|
||||
SDLAxis axis;
|
||||
Scroll scroll;
|
||||
};
|
||||
};
|
||||
|
||||
struct InternalButtonState {
|
||||
float Down;
|
||||
bool Released;
|
||||
bool Tapped;
|
||||
};
|
||||
|
||||
bool InitializePoll (HWND windowHandle);
|
||||
void UpdatePoll (HWND windowHandle);
|
||||
void DisposePoll ();
|
||||
ConfigValue StringToConfigEnum (const char *value);
|
||||
void SetConfigValue (toml_table_t *table, const char *key, Keybindings *keybind);
|
||||
InternalButtonState GetInternalButtonState (Keybindings bindings);
|
||||
void SetRumble (int left, int right, int length);
|
||||
|
||||
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 newPosition);
|
||||
bool GetMouseScrollUp ();
|
||||
bool GetMouseScrollDown ();
|
||||
bool GetWasMouseScrollUp ();
|
||||
bool GetWasMouseScrollDown ();
|
||||
bool GetMouseScrollIsReleased (Scroll scroll);
|
||||
bool GetMouseScrollIsDown (Scroll scroll);
|
||||
bool GetMouseScrollIsTapped (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);
|
||||
float ControllerAxisIsDown (SDLAxis axis);
|
||||
bool ControllerAxisIsUp (SDLAxis axis);
|
||||
float ControllerAxisWasDown (SDLAxis axis);
|
||||
bool ControllerAxisWasUp (SDLAxis axis);
|
||||
bool ControllerAxisIsTapped (SDLAxis axis);
|
||||
bool ControllerAxisIsReleased (SDLAxis axis);
|
||||
bool IsButtonTapped (Keybindings bindings);
|
||||
bool IsButtonReleased (Keybindings bindings);
|
||||
float IsButtonDown (Keybindings bindings);
|
||||
|
4
subprojects/minhook.wrap
Executable file
4
subprojects/minhook.wrap
Executable file
@ -0,0 +1,4 @@
|
||||
[wrap-git]
|
||||
url = https://github.com/TsudaKageyu/minhook.git
|
||||
revision = master
|
||||
diff_files = minhook.patch
|
20
subprojects/packagefiles/minhook.patch
Normal file
20
subprojects/packagefiles/minhook.patch
Normal file
@ -0,0 +1,20 @@
|
||||
+++ minhook/meson.build
|
||||
@@ -0,0 +1,18 @@
|
||||
+project('minhook', 'c', version: '1.0.0')
|
||||
+
|
||||
+minhook_inc = include_directories('include')
|
||||
+minhook_lib = static_library(
|
||||
+ 'minhook',
|
||||
+ include_directories: minhook_inc,
|
||||
+ sources: [
|
||||
+ 'src/buffer.c',
|
||||
+ 'src/hook.c',
|
||||
+ 'src/trampoline.c',
|
||||
+ 'src/hde/hde32.c',
|
||||
+ 'src/hde/hde64.c'
|
||||
+ ]
|
||||
+)
|
||||
+minhook_dep = declare_dependency(
|
||||
+ link_with: minhook_lib,
|
||||
+ include_directories: minhook_inc,
|
||||
+)
|
14
subprojects/packagefiles/tomlc99.patch
Normal file
14
subprojects/packagefiles/tomlc99.patch
Normal file
@ -0,0 +1,14 @@
|
||||
+++ tomlc99/meson.build
|
||||
@@ -0,0 +1,12 @@
|
||||
+project('tomlc99', 'c', version: '1.0.0')
|
||||
+
|
||||
+tomlc99_inc = include_directories('.')
|
||||
+tomlc99_lib = static_library(
|
||||
+ 'tomlc99',
|
||||
+ include_directories: tomlc99_inc,
|
||||
+ sources: ['toml.c']
|
||||
+)
|
||||
+tomlc99_dep = declare_dependency(
|
||||
+ link_with: tomlc99_lib,
|
||||
+ include_directories: tomlc99_inc,
|
||||
+)
|
15
subprojects/sdl2.wrap
Normal file
15
subprojects/sdl2.wrap
Normal file
@ -0,0 +1,15 @@
|
||||
[wrap-file]
|
||||
directory = SDL2-2.26.5
|
||||
source_url = https://github.com/libsdl-org/SDL/releases/download/release-2.26.5/SDL2-2.26.5.tar.gz
|
||||
source_filename = SDL2-2.26.5.tar.gz
|
||||
source_hash = ad8fea3da1be64c83c45b1d363a6b4ba8fd60f5bde3b23ec73855709ec5eabf7
|
||||
patch_filename = sdl2_2.26.5-5_patch.zip
|
||||
patch_url = https://wrapdb.mesonbuild.com/v2/sdl2_2.26.5-5/get_patch
|
||||
patch_hash = 4d8d3ae534c326f27b2d97616fdfa7cce41bd0333c7d9683dd8ae39d4ad70e6a
|
||||
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/sdl2_2.26.5-5/SDL2-2.26.5.tar.gz
|
||||
wrapdb_version = 2.26.5-5
|
||||
|
||||
[provide]
|
||||
sdl2 = sdl2_dep
|
||||
sdl2main = sdl2main_dep
|
||||
sdl2_test = sdl2_test_dep
|
4
subprojects/tomlc99.wrap
Normal file
4
subprojects/tomlc99.wrap
Normal file
@ -0,0 +1,4 @@
|
||||
[wrap-git]
|
||||
url = https://github.com/cktan/tomlc99.git
|
||||
revision = master
|
||||
diff_files = tomlc99.patch
|
13
subprojects/xxhash.wrap
Normal file
13
subprojects/xxhash.wrap
Normal file
@ -0,0 +1,13 @@
|
||||
[wrap-file]
|
||||
directory = xxHash-0.8.2
|
||||
source_url = https://github.com/Cyan4973/xxHash/archive/v0.8.2.tar.gz
|
||||
source_filename = xxHash-0.8.2.tar.gz
|
||||
source_hash = baee0c6afd4f03165de7a4e67988d16f0f2b257b51d0e3cb91909302a26a79c4
|
||||
patch_filename = xxhash_0.8.2-1_patch.zip
|
||||
patch_url = https://wrapdb.mesonbuild.com/v2/xxhash_0.8.2-1/get_patch
|
||||
patch_hash = e721ef7a4c4ee0ade8b8440f6f7cb9f935b68e825249d74cb1c2503c53e68d25
|
||||
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/xxhash_0.8.2-1/xxHash-0.8.2.tar.gz
|
||||
wrapdb_version = 0.8.2-1
|
||||
|
||||
[provide]
|
||||
libxxhash = xxhash_dep
|
1
tomlc99
1
tomlc99
@ -1 +0,0 @@
|
||||
Subproject commit 894902820a3ea2f1ec470cd7fe338bde54045cf5
|
Loading…
x
Reference in New Issue
Block a user