Renormalize code
This commit is contained in:
parent
1672c2cd2a
commit
0060482146
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
||||
* text eol=crlf
|
30
Makefile
30
Makefile
@ -1,15 +1,15 @@
|
||||
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
|
||||
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
|
||||
|
@ -1,11 +1,11 @@
|
||||
[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'
|
||||
|
||||
[host_machine]
|
||||
system = 'windows'
|
||||
cpu_family = 'x86_64'
|
||||
cpu = 'x86_64'
|
||||
endian = 'little'
|
||||
[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'
|
||||
|
||||
[host_machine]
|
||||
system = 'windows'
|
||||
cpu_family = 'x86_64'
|
||||
cpu = 'x86_64'
|
||||
endian = 'little'
|
||||
|
60
dist/config.toml
vendored
60
dist/config.toml
vendored
@ -1,31 +1,31 @@
|
||||
[amauth]
|
||||
server = "127.0.0.1"
|
||||
port = "54430"
|
||||
chassis_id = "284111080000"
|
||||
shop_id = "TAIKO ARCADE LOADER"
|
||||
game_ver = "00.00"
|
||||
country_code = "JPN"
|
||||
|
||||
[patches]
|
||||
version = "auto"
|
||||
res = { x = 1920, y = 1080 }
|
||||
windowed = false
|
||||
vsync = false
|
||||
shared_audio = true
|
||||
unlock_songs = true
|
||||
|
||||
[patches.cn_jun_2023]
|
||||
fix_language = false
|
||||
demo_movie = true
|
||||
mode_collabo025 = false
|
||||
mode_collabo026 = false
|
||||
|
||||
[qr]
|
||||
data = { serial = "", type = 0, song_no = [] }
|
||||
image_path = ""
|
||||
|
||||
[drum]
|
||||
wait_period = 4
|
||||
|
||||
[controller]
|
||||
[amauth]
|
||||
server = "127.0.0.1"
|
||||
port = "54430"
|
||||
chassis_id = "284111080000"
|
||||
shop_id = "TAIKO ARCADE LOADER"
|
||||
game_ver = "00.00"
|
||||
country_code = "JPN"
|
||||
|
||||
[patches]
|
||||
version = "auto"
|
||||
res = { x = 1920, y = 1080 }
|
||||
windowed = false
|
||||
vsync = false
|
||||
shared_audio = true
|
||||
unlock_songs = true
|
||||
|
||||
[patches.cn_jun_2023]
|
||||
fix_language = false
|
||||
demo_movie = true
|
||||
mode_collabo025 = false
|
||||
mode_collabo026 = false
|
||||
|
||||
[qr]
|
||||
data = { serial = "", type = 0, song_no = [] }
|
||||
image_path = ""
|
||||
|
||||
[drum]
|
||||
wait_period = 4
|
||||
|
||||
[controller]
|
||||
analog = false
|
3832
dist/gamecontrollerdb.txt
vendored
3832
dist/gamecontrollerdb.txt
vendored
File diff suppressed because it is too large
Load Diff
152
meson.build
152
meson.build
@ -1,76 +1,76 @@
|
||||
project('TaikoArcadeLoader', 'c', 'cpp', version: '1.0.0', default_options : ['c_std=c11', 'cpp_std=c++23'])
|
||||
warning_level = 3
|
||||
debug = true
|
||||
optimization = 3
|
||||
b_lto = true
|
||||
b_pgo = 'use'
|
||||
cmake = import('cmake')
|
||||
opt_var = cmake.subproject_options()
|
||||
opt_var.set_override_option('cpp_std', 'c++23')
|
||||
|
||||
cpp = meson.get_compiler('cpp')
|
||||
|
||||
add_project_arguments(
|
||||
cpp.get_supported_arguments(
|
||||
'-D_WIN32_WINNT=_WIN32_WINNT_WIN10',
|
||||
),
|
||||
language: 'cpp',
|
||||
)
|
||||
|
||||
add_project_link_arguments(
|
||||
cpp.get_supported_arguments(
|
||||
'-static',
|
||||
#'-s',
|
||||
'-lws2_32',
|
||||
'-lssp',
|
||||
'-lntdll',
|
||||
),
|
||||
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'])
|
||||
opt_var.add_cmake_defines({'SAFETYHOOK_FETCH_ZYDIS': true})
|
||||
safetyhook_proj = cmake.subproject('safetyhook', options: opt_var)
|
||||
safetyhook_dep = safetyhook_proj.dependency('safetyhook')
|
||||
zydis_dep = safetyhook_proj.dependency('Zydis')
|
||||
stb = subproject('stb')
|
||||
opt_var.add_cmake_defines({'BUILD_EXAMPLES': false})
|
||||
zxing_proj = cmake.subproject('zxing', options: opt_var)
|
||||
zxing_dep = zxing_proj.dependency('ZXing')
|
||||
|
||||
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'),
|
||||
],
|
||||
dependencies: [stb.get_variable('stb_dep'),
|
||||
zxing_dep,
|
||||
safetyhook_dep,
|
||||
zydis_dep,
|
||||
],
|
||||
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',
|
||||
'src/patches/jp_apr_2023.cpp',
|
||||
'src/patches/amauth.cpp',
|
||||
'src/patches/qr.cpp',
|
||||
],
|
||||
name_prefix: ''
|
||||
)
|
||||
project('TaikoArcadeLoader', 'c', 'cpp', version: '1.0.0', default_options : ['c_std=c11', 'cpp_std=c++23'])
|
||||
warning_level = 3
|
||||
debug = true
|
||||
optimization = 3
|
||||
b_lto = true
|
||||
b_pgo = 'use'
|
||||
cmake = import('cmake')
|
||||
opt_var = cmake.subproject_options()
|
||||
opt_var.set_override_option('cpp_std', 'c++23')
|
||||
|
||||
cpp = meson.get_compiler('cpp')
|
||||
|
||||
add_project_arguments(
|
||||
cpp.get_supported_arguments(
|
||||
'-D_WIN32_WINNT=_WIN32_WINNT_WIN10',
|
||||
),
|
||||
language: 'cpp',
|
||||
)
|
||||
|
||||
add_project_link_arguments(
|
||||
cpp.get_supported_arguments(
|
||||
'-static',
|
||||
#'-s',
|
||||
'-lws2_32',
|
||||
'-lssp',
|
||||
'-lntdll',
|
||||
),
|
||||
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'])
|
||||
opt_var.add_cmake_defines({'SAFETYHOOK_FETCH_ZYDIS': true})
|
||||
safetyhook_proj = cmake.subproject('safetyhook', options: opt_var)
|
||||
safetyhook_dep = safetyhook_proj.dependency('safetyhook')
|
||||
zydis_dep = safetyhook_proj.dependency('Zydis')
|
||||
stb = subproject('stb')
|
||||
opt_var.add_cmake_defines({'BUILD_EXAMPLES': false})
|
||||
zxing_proj = cmake.subproject('zxing', options: opt_var)
|
||||
zxing_dep = zxing_proj.dependency('ZXing')
|
||||
|
||||
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'),
|
||||
],
|
||||
dependencies: [stb.get_variable('stb_dep'),
|
||||
zxing_dep,
|
||||
safetyhook_dep,
|
||||
zydis_dep,
|
||||
],
|
||||
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',
|
||||
'src/patches/jp_apr_2023.cpp',
|
||||
'src/patches/amauth.cpp',
|
||||
'src/patches/qr.cpp',
|
||||
],
|
||||
name_prefix: ''
|
||||
)
|
||||
|
730
src/bnusio.cpp
730
src/bnusio.cpp
@ -1,365 +1,365 @@
|
||||
#include "constants.h"
|
||||
#include "helpers.h"
|
||||
#include "patches/patches.h"
|
||||
#include "poll.h"
|
||||
|
||||
extern std::vector<HMODULE> plugins;
|
||||
extern char accessCode1[21];
|
||||
extern char chipId1[33];
|
||||
extern char accessCode2[21];
|
||||
extern char chipId2[33];
|
||||
extern GameVersion version;
|
||||
|
||||
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;
|
||||
|
||||
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_1 = {.keycodes = {'P'}};
|
||||
Keybindings CARD_INSERT_2 = {};
|
||||
Keybindings QR_DATA_READ = {.keycodes = {'Q'}};
|
||||
Keybindings QR_IMAGE_READ = {.keycodes = {'W'}};
|
||||
Keybindings P1_LEFT_BLUE = {.keycodes = {'D'}, .axis = {SDL_AXIS_LEFT_DOWN}};
|
||||
Keybindings P1_LEFT_RED = {.keycodes = {'F'}, .axis = {SDL_AXIS_LEFT_RIGHT}};
|
||||
Keybindings P1_RIGHT_RED = {.keycodes = {'J'}, .axis = {SDL_AXIS_RIGHT_RIGHT}};
|
||||
Keybindings P1_RIGHT_BLUE = {.keycodes = {'K'}, .axis = {SDL_AXIS_RIGHT_DOWN}};
|
||||
Keybindings P2_LEFT_BLUE = {};
|
||||
Keybindings P2_LEFT_RED = {};
|
||||
Keybindings P2_RIGHT_RED = {};
|
||||
Keybindings P2_RIGHT_BLUE = {};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
u16 drumMin = 15000;
|
||||
u16 drumMax = 30000;
|
||||
u16 drumWaitPeriod = 4;
|
||||
|
||||
u16 lastHitValue = drumMin;
|
||||
Keybindings *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 buttonWaitPeriodP1 = 0;
|
||||
u16 buttonWaitPeriodP2 = 0;
|
||||
std::queue<u8> buttonQueueP1;
|
||||
std::queue<u8> buttonQueueP2;
|
||||
|
||||
bool useTaikoController;
|
||||
SDLAxis analogBindings[] = {
|
||||
SDL_AXIS_LEFT_LEFT, SDL_AXIS_LEFT_RIGHT, SDL_AXIS_LEFT_DOWN, SDL_AXIS_LEFT_UP, // P1: LB, LR, RR, RB
|
||||
SDL_AXIS_RIGHT_LEFT, SDL_AXIS_RIGHT_RIGHT, SDL_AXIS_RIGHT_DOWN, SDL_AXIS_RIGHT_UP, // P2: LB, LR, RR, RB
|
||||
};
|
||||
|
||||
u16
|
||||
bnusio_GetAnalogIn (u8 which) {
|
||||
u16 analogValue;
|
||||
if (useTaikoController) {
|
||||
analogValue = (u16)(32768 * ControllerAxisIsDown (analogBindings[which]));
|
||||
if (analogValue > 100) return analogValue;
|
||||
return 0;
|
||||
}
|
||||
auto button = analogButtons[which];
|
||||
if (which == 0) {
|
||||
if (buttonWaitPeriodP1 > 0) buttonWaitPeriodP1--;
|
||||
if (buttonWaitPeriodP2 > 0) buttonWaitPeriodP2--;
|
||||
}
|
||||
bool isP1 = which / 4 == 0;
|
||||
if ((isP1 && !buttonQueueP1.empty ()) || (!isP1 && !buttonQueueP2.empty ())) {
|
||||
if ((isP1 && buttonQueueP1.front () == which && buttonWaitPeriodP1 == 0) || (!isP1 && buttonQueueP2.front () == which && buttonWaitPeriodP2 == 0)) {
|
||||
if (isP1) {
|
||||
buttonQueueP1.pop ();
|
||||
buttonWaitPeriodP1 = drumWaitPeriod;
|
||||
} else {
|
||||
buttonQueueP2.pop ();
|
||||
buttonWaitPeriodP2 = drumWaitPeriod;
|
||||
}
|
||||
|
||||
lastHitValue++;
|
||||
if (lastHitValue >= drumMax) lastHitValue = drumMin;
|
||||
return lastHitValue;
|
||||
}
|
||||
if (IsButtonTapped (*button)) {
|
||||
if (isP1) buttonQueueP1.push (which);
|
||||
else buttonQueueP2.push (which);
|
||||
}
|
||||
return 0;
|
||||
} else if (IsButtonTapped (*button)) {
|
||||
if (isP1 && buttonWaitPeriodP1 > 0) {
|
||||
buttonQueueP1.push (which);
|
||||
return 0;
|
||||
} else if (!isP1 && buttonWaitPeriodP2 > 0) {
|
||||
buttonQueueP2.push (which);
|
||||
return 0;
|
||||
}
|
||||
if (isP1) buttonWaitPeriodP1 = drumWaitPeriod;
|
||||
else buttonWaitPeriodP2 = drumWaitPeriod;
|
||||
lastHitValue++;
|
||||
if (lastHitValue >= drumMax) lastHitValue = drumMin;
|
||||
return lastHitValue;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
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 (auto plugin : plugins) {
|
||||
FARPROC insertEvent = GetProcAddress (plugin, "BeforeCard1Insert");
|
||||
if (insertEvent) ((event *)insertEvent) ();
|
||||
}
|
||||
for (auto plugin : plugins) {
|
||||
FARPROC insertEvent = GetProcAddress (plugin, "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 (auto plugin : plugins) {
|
||||
FARPROC insertEvent = GetProcAddress (plugin, "BeforeCard2Insert");
|
||||
if (insertEvent) ((event *)insertEvent) ();
|
||||
}
|
||||
for (auto plugin : plugins) {
|
||||
FARPROC insertEvent = GetProcAddress (plugin, "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 (auto plugin : plugins) {
|
||||
auto updateEvent = GetProcAddress (plugin, "Update");
|
||||
if (updateEvent) updateEvent ();
|
||||
}
|
||||
|
||||
patches::Qr::Update ();
|
||||
|
||||
if (attachCallback) attachCallback (0, 0, attachData);
|
||||
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;
|
||||
}
|
||||
|
||||
i64
|
||||
bnusio_Close () {
|
||||
for (auto plugin : plugins) {
|
||||
FARPROC exitEvent = GetProcAddress (plugin, "Exit");
|
||||
if (exitEvent) ((event *)exitEvent) ();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
// This is way too fucking jank
|
||||
attachCallback = callback;
|
||||
attachData = 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) {
|
||||
waitingForTouch = true;
|
||||
touchCallback = callback;
|
||||
touchData = a5;
|
||||
for (auto plugin : plugins) {
|
||||
FARPROC touchEvent = GetProcAddress (plugin, "WaitTouch");
|
||||
if (touchEvent) ((waitTouchEvent *)touchEvent) (callback, 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)
|
||||
INSTALL_HOOK (bngrw_attach);
|
||||
INSTALL_HOOK (bngrw_reqWaitTouch);
|
||||
|
||||
auto configPath = std::filesystem::current_path () / "config.toml";
|
||||
std::unique_ptr<toml_table_t, void (*) (toml_table_t *)> config_ptr (openConfig (configPath), toml_free);
|
||||
toml_table_t *config = config_ptr.get ();
|
||||
if (config) {
|
||||
auto drum = openConfigSection (config, "drum");
|
||||
if (drum) drumWaitPeriod = readConfigInt (drum, "wait_period", drumWaitPeriod);
|
||||
auto taikoController = openConfigSection (config, "controller");
|
||||
if (taikoController) {
|
||||
useTaikoController = readConfigBool (taikoController, "analog", useTaikoController);
|
||||
if (useTaikoController) printf ("Using analog input mode. All the keyboard drum inputs have been disabled.\n");
|
||||
}
|
||||
}
|
||||
|
||||
auto keyconfigPath = std::filesystem::current_path () / "keyconfig.toml";
|
||||
std::unique_ptr<toml_table_t, void (*) (toml_table_t *)> keyconfig_ptr (openConfig (keyconfigPath), toml_free);
|
||||
toml_table_t *keyconfig = keyconfig_ptr.get ();
|
||||
if (keyconfig) {
|
||||
SetConfigValue (keyconfig, "EXIT", &EXIT);
|
||||
|
||||
SetConfigValue (keyconfig, "TEST", &TEST);
|
||||
SetConfigValue (keyconfig, "SERVICE", &SERVICE);
|
||||
SetConfigValue (keyconfig, "DEBUG_UP", &DEBUG_UP);
|
||||
SetConfigValue (keyconfig, "DEBUG_DOWN", &DEBUG_DOWN);
|
||||
SetConfigValue (keyconfig, "DEBUG_ENTER", &DEBUG_ENTER);
|
||||
|
||||
SetConfigValue (keyconfig, "COIN_ADD", &COIN_ADD);
|
||||
SetConfigValue (keyconfig, "CARD_INSERT_1", &CARD_INSERT_1);
|
||||
SetConfigValue (keyconfig, "CARD_INSERT_2", &CARD_INSERT_2);
|
||||
SetConfigValue (keyconfig, "QR_DATA_READ", &QR_DATA_READ);
|
||||
SetConfigValue (keyconfig, "QR_IMAGE_READ", &QR_IMAGE_READ);
|
||||
|
||||
SetConfigValue (keyconfig, "P1_LEFT_BLUE", &P1_LEFT_BLUE);
|
||||
SetConfigValue (keyconfig, "P1_LEFT_RED", &P1_LEFT_RED);
|
||||
SetConfigValue (keyconfig, "P1_RIGHT_RED", &P1_RIGHT_RED);
|
||||
SetConfigValue (keyconfig, "P1_RIGHT_BLUE", &P1_RIGHT_BLUE);
|
||||
SetConfigValue (keyconfig, "P2_LEFT_BLUE", &P2_LEFT_BLUE);
|
||||
SetConfigValue (keyconfig, "P2_LEFT_RED", &P2_LEFT_RED);
|
||||
SetConfigValue (keyconfig, "P2_RIGHT_RED", &P2_RIGHT_RED);
|
||||
SetConfigValue (keyconfig, "P2_RIGHT_BLUE", &P2_RIGHT_BLUE);
|
||||
}
|
||||
}
|
||||
} // namespace bnusio
|
||||
#include "constants.h"
|
||||
#include "helpers.h"
|
||||
#include "patches/patches.h"
|
||||
#include "poll.h"
|
||||
|
||||
extern std::vector<HMODULE> plugins;
|
||||
extern char accessCode1[21];
|
||||
extern char chipId1[33];
|
||||
extern char accessCode2[21];
|
||||
extern char chipId2[33];
|
||||
extern GameVersion version;
|
||||
|
||||
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;
|
||||
|
||||
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_1 = {.keycodes = {'P'}};
|
||||
Keybindings CARD_INSERT_2 = {};
|
||||
Keybindings QR_DATA_READ = {.keycodes = {'Q'}};
|
||||
Keybindings QR_IMAGE_READ = {.keycodes = {'W'}};
|
||||
Keybindings P1_LEFT_BLUE = {.keycodes = {'D'}, .axis = {SDL_AXIS_LEFT_DOWN}};
|
||||
Keybindings P1_LEFT_RED = {.keycodes = {'F'}, .axis = {SDL_AXIS_LEFT_RIGHT}};
|
||||
Keybindings P1_RIGHT_RED = {.keycodes = {'J'}, .axis = {SDL_AXIS_RIGHT_RIGHT}};
|
||||
Keybindings P1_RIGHT_BLUE = {.keycodes = {'K'}, .axis = {SDL_AXIS_RIGHT_DOWN}};
|
||||
Keybindings P2_LEFT_BLUE = {};
|
||||
Keybindings P2_LEFT_RED = {};
|
||||
Keybindings P2_RIGHT_RED = {};
|
||||
Keybindings P2_RIGHT_BLUE = {};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
u16 drumMin = 15000;
|
||||
u16 drumMax = 30000;
|
||||
u16 drumWaitPeriod = 4;
|
||||
|
||||
u16 lastHitValue = drumMin;
|
||||
Keybindings *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 buttonWaitPeriodP1 = 0;
|
||||
u16 buttonWaitPeriodP2 = 0;
|
||||
std::queue<u8> buttonQueueP1;
|
||||
std::queue<u8> buttonQueueP2;
|
||||
|
||||
bool useTaikoController;
|
||||
SDLAxis analogBindings[] = {
|
||||
SDL_AXIS_LEFT_LEFT, SDL_AXIS_LEFT_RIGHT, SDL_AXIS_LEFT_DOWN, SDL_AXIS_LEFT_UP, // P1: LB, LR, RR, RB
|
||||
SDL_AXIS_RIGHT_LEFT, SDL_AXIS_RIGHT_RIGHT, SDL_AXIS_RIGHT_DOWN, SDL_AXIS_RIGHT_UP, // P2: LB, LR, RR, RB
|
||||
};
|
||||
|
||||
u16
|
||||
bnusio_GetAnalogIn (u8 which) {
|
||||
u16 analogValue;
|
||||
if (useTaikoController) {
|
||||
analogValue = (u16)(32768 * ControllerAxisIsDown (analogBindings[which]));
|
||||
if (analogValue > 100) return analogValue;
|
||||
return 0;
|
||||
}
|
||||
auto button = analogButtons[which];
|
||||
if (which == 0) {
|
||||
if (buttonWaitPeriodP1 > 0) buttonWaitPeriodP1--;
|
||||
if (buttonWaitPeriodP2 > 0) buttonWaitPeriodP2--;
|
||||
}
|
||||
bool isP1 = which / 4 == 0;
|
||||
if ((isP1 && !buttonQueueP1.empty ()) || (!isP1 && !buttonQueueP2.empty ())) {
|
||||
if ((isP1 && buttonQueueP1.front () == which && buttonWaitPeriodP1 == 0) || (!isP1 && buttonQueueP2.front () == which && buttonWaitPeriodP2 == 0)) {
|
||||
if (isP1) {
|
||||
buttonQueueP1.pop ();
|
||||
buttonWaitPeriodP1 = drumWaitPeriod;
|
||||
} else {
|
||||
buttonQueueP2.pop ();
|
||||
buttonWaitPeriodP2 = drumWaitPeriod;
|
||||
}
|
||||
|
||||
lastHitValue++;
|
||||
if (lastHitValue >= drumMax) lastHitValue = drumMin;
|
||||
return lastHitValue;
|
||||
}
|
||||
if (IsButtonTapped (*button)) {
|
||||
if (isP1) buttonQueueP1.push (which);
|
||||
else buttonQueueP2.push (which);
|
||||
}
|
||||
return 0;
|
||||
} else if (IsButtonTapped (*button)) {
|
||||
if (isP1 && buttonWaitPeriodP1 > 0) {
|
||||
buttonQueueP1.push (which);
|
||||
return 0;
|
||||
} else if (!isP1 && buttonWaitPeriodP2 > 0) {
|
||||
buttonQueueP2.push (which);
|
||||
return 0;
|
||||
}
|
||||
if (isP1) buttonWaitPeriodP1 = drumWaitPeriod;
|
||||
else buttonWaitPeriodP2 = drumWaitPeriod;
|
||||
lastHitValue++;
|
||||
if (lastHitValue >= drumMax) lastHitValue = drumMin;
|
||||
return lastHitValue;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
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 (auto plugin : plugins) {
|
||||
FARPROC insertEvent = GetProcAddress (plugin, "BeforeCard1Insert");
|
||||
if (insertEvent) ((event *)insertEvent) ();
|
||||
}
|
||||
for (auto plugin : plugins) {
|
||||
FARPROC insertEvent = GetProcAddress (plugin, "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 (auto plugin : plugins) {
|
||||
FARPROC insertEvent = GetProcAddress (plugin, "BeforeCard2Insert");
|
||||
if (insertEvent) ((event *)insertEvent) ();
|
||||
}
|
||||
for (auto plugin : plugins) {
|
||||
FARPROC insertEvent = GetProcAddress (plugin, "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 (auto plugin : plugins) {
|
||||
auto updateEvent = GetProcAddress (plugin, "Update");
|
||||
if (updateEvent) updateEvent ();
|
||||
}
|
||||
|
||||
patches::Qr::Update ();
|
||||
|
||||
if (attachCallback) attachCallback (0, 0, attachData);
|
||||
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;
|
||||
}
|
||||
|
||||
i64
|
||||
bnusio_Close () {
|
||||
for (auto plugin : plugins) {
|
||||
FARPROC exitEvent = GetProcAddress (plugin, "Exit");
|
||||
if (exitEvent) ((event *)exitEvent) ();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
// This is way too fucking jank
|
||||
attachCallback = callback;
|
||||
attachData = 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) {
|
||||
waitingForTouch = true;
|
||||
touchCallback = callback;
|
||||
touchData = a5;
|
||||
for (auto plugin : plugins) {
|
||||
FARPROC touchEvent = GetProcAddress (plugin, "WaitTouch");
|
||||
if (touchEvent) ((waitTouchEvent *)touchEvent) (callback, 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)
|
||||
INSTALL_HOOK (bngrw_attach);
|
||||
INSTALL_HOOK (bngrw_reqWaitTouch);
|
||||
|
||||
auto configPath = std::filesystem::current_path () / "config.toml";
|
||||
std::unique_ptr<toml_table_t, void (*) (toml_table_t *)> config_ptr (openConfig (configPath), toml_free);
|
||||
toml_table_t *config = config_ptr.get ();
|
||||
if (config) {
|
||||
auto drum = openConfigSection (config, "drum");
|
||||
if (drum) drumWaitPeriod = readConfigInt (drum, "wait_period", drumWaitPeriod);
|
||||
auto taikoController = openConfigSection (config, "controller");
|
||||
if (taikoController) {
|
||||
useTaikoController = readConfigBool (taikoController, "analog", useTaikoController);
|
||||
if (useTaikoController) printf ("Using analog input mode. All the keyboard drum inputs have been disabled.\n");
|
||||
}
|
||||
}
|
||||
|
||||
auto keyconfigPath = std::filesystem::current_path () / "keyconfig.toml";
|
||||
std::unique_ptr<toml_table_t, void (*) (toml_table_t *)> keyconfig_ptr (openConfig (keyconfigPath), toml_free);
|
||||
toml_table_t *keyconfig = keyconfig_ptr.get ();
|
||||
if (keyconfig) {
|
||||
SetConfigValue (keyconfig, "EXIT", &EXIT);
|
||||
|
||||
SetConfigValue (keyconfig, "TEST", &TEST);
|
||||
SetConfigValue (keyconfig, "SERVICE", &SERVICE);
|
||||
SetConfigValue (keyconfig, "DEBUG_UP", &DEBUG_UP);
|
||||
SetConfigValue (keyconfig, "DEBUG_DOWN", &DEBUG_DOWN);
|
||||
SetConfigValue (keyconfig, "DEBUG_ENTER", &DEBUG_ENTER);
|
||||
|
||||
SetConfigValue (keyconfig, "COIN_ADD", &COIN_ADD);
|
||||
SetConfigValue (keyconfig, "CARD_INSERT_1", &CARD_INSERT_1);
|
||||
SetConfigValue (keyconfig, "CARD_INSERT_2", &CARD_INSERT_2);
|
||||
SetConfigValue (keyconfig, "QR_DATA_READ", &QR_DATA_READ);
|
||||
SetConfigValue (keyconfig, "QR_IMAGE_READ", &QR_IMAGE_READ);
|
||||
|
||||
SetConfigValue (keyconfig, "P1_LEFT_BLUE", &P1_LEFT_BLUE);
|
||||
SetConfigValue (keyconfig, "P1_LEFT_RED", &P1_LEFT_RED);
|
||||
SetConfigValue (keyconfig, "P1_RIGHT_RED", &P1_RIGHT_RED);
|
||||
SetConfigValue (keyconfig, "P1_RIGHT_BLUE", &P1_RIGHT_BLUE);
|
||||
SetConfigValue (keyconfig, "P2_LEFT_BLUE", &P2_LEFT_BLUE);
|
||||
SetConfigValue (keyconfig, "P2_LEFT_RED", &P2_LEFT_RED);
|
||||
SetConfigValue (keyconfig, "P2_RIGHT_RED", &P2_RIGHT_RED);
|
||||
SetConfigValue (keyconfig, "P2_RIGHT_BLUE", &P2_RIGHT_BLUE);
|
||||
}
|
||||
}
|
||||
} // namespace bnusio
|
||||
|
@ -1,3 +1,3 @@
|
||||
namespace bnusio {
|
||||
void Init ();
|
||||
} // namespace bnusio
|
||||
namespace bnusio {
|
||||
void Init ();
|
||||
} // namespace bnusio
|
||||
|
384
src/dllmain.cpp
384
src/dllmain.cpp
@ -1,192 +1,192 @@
|
||||
#include "bnusio.h"
|
||||
#include "constants.h"
|
||||
#include "helpers.h"
|
||||
#include "patches/patches.h"
|
||||
#include "poll.h"
|
||||
|
||||
GameVersion gameVersion = GameVersion::UNKNOWN;
|
||||
std::vector<HMODULE> plugins;
|
||||
|
||||
std::string server = "127.0.0.1";
|
||||
std::string port = "54430";
|
||||
std::string chassisId = "284111080000";
|
||||
std::string shopId = "TAIKO ARCADE LOADER";
|
||||
std::string gameVerNum = "00.00";
|
||||
std::string countryCode = "JPN";
|
||||
char fullAddress[256] = {'\0'};
|
||||
char placeId[16] = {'\0'};
|
||||
char accessCode1[21] = "00000000000000000001";
|
||||
char accessCode2[21] = "00000000000000000002";
|
||||
char chipId1[33] = "00000000000000000000000000000001";
|
||||
char chipId2[33] = "00000000000000000000000000000002";
|
||||
|
||||
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, chassisId.c_str ());
|
||||
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.c_str (), 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);
|
||||
|
||||
gameVersion = (GameVersion)XXH64 (buf, length, 0);
|
||||
|
||||
stream.close ();
|
||||
free (buf);
|
||||
|
||||
switch (gameVersion) {
|
||||
case GameVersion::JP_NOV_2020:
|
||||
case GameVersion::CN_JUN_2023:
|
||||
case GameVersion::JP_APR_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", "accessCode1", buf, ".\\card.ini");
|
||||
std::generate (buf, buf + 32, [&] () { return hexCharacterTable[rand () % 16]; });
|
||||
WritePrivateProfileStringA ("card", "chipId1", buf, ".\\card.ini");
|
||||
std::generate (buf, buf + 20, [&] () { return hexCharacterTable[rand () % 10]; });
|
||||
WritePrivateProfileStringA ("card", "accessCode2", buf, ".\\card.ini");
|
||||
std::generate (buf, buf + 32, [&] () { return hexCharacterTable[rand () % 16]; });
|
||||
WritePrivateProfileStringA ("card", "chipId2", 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
|
||||
|
||||
std::string version = "auto";
|
||||
auto configPath = std::filesystem::current_path () / "config.toml";
|
||||
std::unique_ptr<toml_table_t, void (*) (toml_table_t *)> config_ptr (openConfig (configPath), toml_free);
|
||||
toml_table_t *config = config_ptr.get ();
|
||||
if (config) {
|
||||
auto amauth = openConfigSection (config, "amauth");
|
||||
if (amauth) {
|
||||
server = readConfigString (amauth, "server", server);
|
||||
port = readConfigString (amauth, "port", port);
|
||||
chassisId = readConfigString (amauth, "chassis_id", chassisId);
|
||||
shopId = readConfigString (amauth, "shop_id", shopId);
|
||||
gameVerNum = readConfigString (amauth, "game_ver", gameVerNum);
|
||||
countryCode = readConfigString (amauth, "country_code", countryCode);
|
||||
|
||||
std::strcat (fullAddress, server.c_str ());
|
||||
std::strcat (fullAddress, ":");
|
||||
std::strcat (fullAddress, port.c_str ());
|
||||
|
||||
std::strcat (placeId, countryCode.c_str ());
|
||||
std::strcat (placeId, "0FF0");
|
||||
}
|
||||
auto patches = openConfigSection (config, "patches");
|
||||
if (patches) version = readConfigString (patches, "version", version);
|
||||
}
|
||||
|
||||
if (version == "auto") {
|
||||
GetGameVersion ();
|
||||
} else if (version == "jp_nov_2020") {
|
||||
gameVersion = GameVersion::JP_NOV_2020;
|
||||
} else if (version == "cn_jun_2023") {
|
||||
gameVersion = GameVersion::CN_JUN_2023;
|
||||
} else if (version == "jp_apr_2023") {
|
||||
gameVersion = GameVersion::JP_APR_2023;
|
||||
} else {
|
||||
MessageBoxA (0, "Unknown patch version", 0, MB_OK);
|
||||
ExitProcess (0);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!std::filesystem::exists (".\\card.ini")) createCard ();
|
||||
GetPrivateProfileStringA ("card", "accessCode1", accessCode1, accessCode1, 21, ".\\card.ini");
|
||||
GetPrivateProfileStringA ("card", "chipId1", chipId1, chipId1, 33, ".\\card.ini");
|
||||
GetPrivateProfileStringA ("card", "accessCode2", accessCode2, accessCode2, 21, ".\\card.ini");
|
||||
GetPrivateProfileStringA ("card", "chipId2", chipId2, chipId2, 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 (gameVersion) {
|
||||
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;
|
||||
case GameVersion::JP_APR_2023: patches::JP_APR_2023::Init (); break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#include "bnusio.h"
|
||||
#include "constants.h"
|
||||
#include "helpers.h"
|
||||
#include "patches/patches.h"
|
||||
#include "poll.h"
|
||||
|
||||
GameVersion gameVersion = GameVersion::UNKNOWN;
|
||||
std::vector<HMODULE> plugins;
|
||||
|
||||
std::string server = "127.0.0.1";
|
||||
std::string port = "54430";
|
||||
std::string chassisId = "284111080000";
|
||||
std::string shopId = "TAIKO ARCADE LOADER";
|
||||
std::string gameVerNum = "00.00";
|
||||
std::string countryCode = "JPN";
|
||||
char fullAddress[256] = {'\0'};
|
||||
char placeId[16] = {'\0'};
|
||||
char accessCode1[21] = "00000000000000000001";
|
||||
char accessCode2[21] = "00000000000000000002";
|
||||
char chipId1[33] = "00000000000000000000000000000001";
|
||||
char chipId2[33] = "00000000000000000000000000000002";
|
||||
|
||||
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, chassisId.c_str ());
|
||||
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.c_str (), 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);
|
||||
|
||||
gameVersion = (GameVersion)XXH64 (buf, length, 0);
|
||||
|
||||
stream.close ();
|
||||
free (buf);
|
||||
|
||||
switch (gameVersion) {
|
||||
case GameVersion::JP_NOV_2020:
|
||||
case GameVersion::CN_JUN_2023:
|
||||
case GameVersion::JP_APR_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", "accessCode1", buf, ".\\card.ini");
|
||||
std::generate (buf, buf + 32, [&] () { return hexCharacterTable[rand () % 16]; });
|
||||
WritePrivateProfileStringA ("card", "chipId1", buf, ".\\card.ini");
|
||||
std::generate (buf, buf + 20, [&] () { return hexCharacterTable[rand () % 10]; });
|
||||
WritePrivateProfileStringA ("card", "accessCode2", buf, ".\\card.ini");
|
||||
std::generate (buf, buf + 32, [&] () { return hexCharacterTable[rand () % 16]; });
|
||||
WritePrivateProfileStringA ("card", "chipId2", 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
|
||||
|
||||
std::string version = "auto";
|
||||
auto configPath = std::filesystem::current_path () / "config.toml";
|
||||
std::unique_ptr<toml_table_t, void (*) (toml_table_t *)> config_ptr (openConfig (configPath), toml_free);
|
||||
toml_table_t *config = config_ptr.get ();
|
||||
if (config) {
|
||||
auto amauth = openConfigSection (config, "amauth");
|
||||
if (amauth) {
|
||||
server = readConfigString (amauth, "server", server);
|
||||
port = readConfigString (amauth, "port", port);
|
||||
chassisId = readConfigString (amauth, "chassis_id", chassisId);
|
||||
shopId = readConfigString (amauth, "shop_id", shopId);
|
||||
gameVerNum = readConfigString (amauth, "game_ver", gameVerNum);
|
||||
countryCode = readConfigString (amauth, "country_code", countryCode);
|
||||
|
||||
std::strcat (fullAddress, server.c_str ());
|
||||
std::strcat (fullAddress, ":");
|
||||
std::strcat (fullAddress, port.c_str ());
|
||||
|
||||
std::strcat (placeId, countryCode.c_str ());
|
||||
std::strcat (placeId, "0FF0");
|
||||
}
|
||||
auto patches = openConfigSection (config, "patches");
|
||||
if (patches) version = readConfigString (patches, "version", version);
|
||||
}
|
||||
|
||||
if (version == "auto") {
|
||||
GetGameVersion ();
|
||||
} else if (version == "jp_nov_2020") {
|
||||
gameVersion = GameVersion::JP_NOV_2020;
|
||||
} else if (version == "cn_jun_2023") {
|
||||
gameVersion = GameVersion::CN_JUN_2023;
|
||||
} else if (version == "jp_apr_2023") {
|
||||
gameVersion = GameVersion::JP_APR_2023;
|
||||
} else {
|
||||
MessageBoxA (0, "Unknown patch version", 0, MB_OK);
|
||||
ExitProcess (0);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!std::filesystem::exists (".\\card.ini")) createCard ();
|
||||
GetPrivateProfileStringA ("card", "accessCode1", accessCode1, accessCode1, 21, ".\\card.ini");
|
||||
GetPrivateProfileStringA ("card", "chipId1", chipId1, chipId1, 33, ".\\card.ini");
|
||||
GetPrivateProfileStringA ("card", "accessCode2", accessCode2, accessCode2, 21, ".\\card.ini");
|
||||
GetPrivateProfileStringA ("card", "chipId2", chipId2, chipId2, 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 (gameVersion) {
|
||||
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;
|
||||
case GameVersion::JP_APR_2023: patches::JP_APR_2023::Init (); break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,212 +1,212 @@
|
||||
#include "helpers.h"
|
||||
#include "patches.h"
|
||||
#include <safetyhook.hpp>
|
||||
|
||||
extern std::string chassisId;
|
||||
|
||||
namespace patches::CN_JUN_2023 {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
i64 (__fastcall *lua_settop) (u64, u64) = (i64 (__fastcall *) (u64, u64))PROC_ADDRESS ("lua51.dll", "lua_settop");
|
||||
i64 (__fastcall *lua_pushboolean) (u64, u64) = (i64 (__fastcall *) (u64, u64))PROC_ADDRESS ("lua51.dll", "lua_pushboolean");
|
||||
i64 (__fastcall *lua_pushstring) (u64, u64) = (i64 (__fastcall *) (u64, u64))PROC_ADDRESS ("lua51.dll", "lua_pushstring");
|
||||
|
||||
i64
|
||||
lua_pushtrue (i64 a1) {
|
||||
lua_settop (a1, 0);
|
||||
lua_pushboolean (a1, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
HOOK (i64, AvailableMode_Dani_AI, ASLR (0x1401AC550), i64 a1) { return lua_pushtrue (a1); }
|
||||
HOOK (i64, AvailableMode_Collabo025, ASLR (0x1402BFF70), i64 *, i64 a2) { return lua_pushtrue (a2); }
|
||||
HOOK (i64, AvailableMode_Collabo026, ASLR (0x1402BC9B0), i64 a1) { return lua_pushtrue (a1); }
|
||||
|
||||
int language = 0;
|
||||
const char *
|
||||
languageStr () {
|
||||
switch (language) {
|
||||
case 1: return "en_us";
|
||||
case 2: return "cn_tw";
|
||||
case 3: return "kor";
|
||||
case 4: return "cn_cn";
|
||||
default: return "jpn";
|
||||
}
|
||||
}
|
||||
HOOK (i64, GetLanguage, ASLR (0x140023720), i64 a1) {
|
||||
auto result = originalGetLanguage (a1);
|
||||
language = *((u32 *)result);
|
||||
return result;
|
||||
}
|
||||
HOOK (i64, GetRegionLanguage, ASLR (0x1401AC300), i64 a1) {
|
||||
lua_settop (a1, 0);
|
||||
lua_pushstring (a1, (u64)languageStr ());
|
||||
return 1;
|
||||
}
|
||||
HOOK (i64, GetCabinetLanguage, ASLR (0x1401AF270), i64, i64 a2) {
|
||||
lua_settop (a2, 0);
|
||||
lua_pushstring (a2, (u64)languageStr ());
|
||||
return 1;
|
||||
}
|
||||
|
||||
HOOK_DYNAMIC (char, __fastcall, AMFWTerminate, i64) { return 0; }
|
||||
|
||||
const i32 datatableBufferSize = 1024 * 1024 * 12;
|
||||
safetyhook::Allocation datatableBuffer1;
|
||||
safetyhook::Allocation datatableBuffer2;
|
||||
safetyhook::Allocation datatableBuffer3;
|
||||
const std::vector<uintptr_t> datatableBuffer1Addresses = {0x140093430, 0x1400934A1, 0x1400934CB, 0x14009353C};
|
||||
const std::vector<uintptr_t> datatableBuffer2Addresses = {0x14009341C, 0x14009354B, 0x14009357E};
|
||||
const std::vector<uintptr_t> datatableBuffer3Addresses = {0x14009356F, 0x140093585, 0x1400935AF};
|
||||
const std::vector<uintptr_t> memsetSizeAddresses = {0x140093416, 0x14009342A, 0x140093569};
|
||||
|
||||
void
|
||||
AllocateStaticBufferNear (void *target_address, size_t size, safetyhook::Allocation *newBuffer) {
|
||||
auto allocator = safetyhook::Allocator::global ();
|
||||
std::vector desired_addresses = {(uint8_t *)target_address};
|
||||
auto allocation_result = allocator->allocate_near (desired_addresses, size);
|
||||
if (allocation_result.has_value ()) *newBuffer = std::move (*allocation_result);
|
||||
}
|
||||
|
||||
void
|
||||
ReplaceLeaBufferAddress (const std::vector<uintptr_t> &bufferAddresses, void *newBufferAddress) {
|
||||
for (auto bufferAddress : bufferAddresses) {
|
||||
uintptr_t lea_instruction_dst = ASLR (bufferAddress) + 3;
|
||||
uintptr_t lea_instruction_end = ASLR (bufferAddress) + 7;
|
||||
intptr_t offset = (intptr_t)newBufferAddress - lea_instruction_end;
|
||||
WRITE_MEMORY (lea_instruction_dst, i32, (i32)offset);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Init () {
|
||||
i32 xRes = 1920;
|
||||
i32 yRes = 1080;
|
||||
bool vsync = false;
|
||||
bool sharedAudio = true;
|
||||
bool unlockSongs = true;
|
||||
bool fixLanguage = false;
|
||||
bool demoMovie = true;
|
||||
bool modeCollabo025 = false;
|
||||
bool modeCollabo026 = false;
|
||||
|
||||
haspBuffer = (u8 *)malloc (0xD40);
|
||||
memset (haspBuffer, 0, 0xD40);
|
||||
strcpy ((char *)(haspBuffer + 0xD00), chassisId.c_str ());
|
||||
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";
|
||||
std::unique_ptr<toml_table_t, void (*) (toml_table_t *)> config_ptr (openConfig (configPath), toml_free);
|
||||
toml_table_t *config = config_ptr.get ();
|
||||
if (config) {
|
||||
auto patches = openConfigSection (config, "patches");
|
||||
if (patches) {
|
||||
auto res = openConfigSection (patches, "res");
|
||||
if (res) {
|
||||
xRes = readConfigInt (res, "x", xRes);
|
||||
yRes = readConfigInt (res, "y", yRes);
|
||||
}
|
||||
vsync = readConfigBool (patches, "vsync", vsync);
|
||||
sharedAudio = readConfigBool (patches, "shared_audio", sharedAudio);
|
||||
unlockSongs = readConfigBool (patches, "unlock_songs", unlockSongs);
|
||||
auto cn_jun_2023 = openConfigSection (patches, "cn_jun_2023");
|
||||
if (cn_jun_2023) {
|
||||
fixLanguage = readConfigBool (cn_jun_2023, "fix_language", fixLanguage);
|
||||
demoMovie = readConfigBool (cn_jun_2023, "demo_movie", demoMovie);
|
||||
modeCollabo025 = readConfigBool (cn_jun_2023, "mode_collabo025", modeCollabo025);
|
||||
modeCollabo026 = readConfigBool (cn_jun_2023, "mode_collabo026", modeCollabo026);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Apply common config patch
|
||||
WRITE_MEMORY (ASLR (0x1404A4ED3), i32, xRes);
|
||||
WRITE_MEMORY (ASLR (0x1404A4EDA), i32, yRes);
|
||||
if (!vsync) WRITE_MEMORY (ASLR (0x1405FC5B9), u8, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x90);
|
||||
if (sharedAudio) WRITE_MEMORY (ASLR (0x140777F87), u8, 0xEB);
|
||||
if (unlockSongs) WRITE_MEMORY (ASLR (0x140425BCD), u8, 0xB0, 0x01);
|
||||
|
||||
// Bypass errors
|
||||
WRITE_MEMORY (ASLR (0x14003F690), u8, 0xC3);
|
||||
|
||||
// Use TLS v1.2
|
||||
WRITE_MEMORY (ASLR (0x140369662), u8, 0x10);
|
||||
|
||||
// Disable SSLVerify
|
||||
WRITE_MEMORY (ASLR (0x14034C182), u8, 0x00);
|
||||
|
||||
// Move various files to current dir
|
||||
WRITE_MEMORY (ASLR (0x140C33C40), char, "./");
|
||||
WRITE_MEMORY (ASLR (0x140C33C44), char, "./");
|
||||
WRITE_MEMORY (ASLR (0x140C7B158), char, ".\\SettingChina1.bin");
|
||||
WRITE_MEMORY (ASLR (0x140C7B2B8), char, ".\\SettingChina1.bin");
|
||||
WRITE_MEMORY (ASLR (0x140C7B2A0), char, ".\\SettingChina2.bin");
|
||||
|
||||
// Remove datatable size limit
|
||||
{
|
||||
for (auto address : memsetSizeAddresses)
|
||||
WRITE_MEMORY (ASLR (address) + 2, i32, datatableBufferSize);
|
||||
|
||||
auto bufferBase = MODULE_HANDLE - 0x03000000;
|
||||
AllocateStaticBufferNear ((void *)bufferBase, datatableBufferSize, &datatableBuffer1);
|
||||
bufferBase += datatableBufferSize;
|
||||
AllocateStaticBufferNear ((void *)bufferBase, datatableBufferSize, &datatableBuffer2);
|
||||
bufferBase += datatableBufferSize;
|
||||
AllocateStaticBufferNear ((void *)bufferBase, datatableBufferSize, &datatableBuffer3);
|
||||
|
||||
ReplaceLeaBufferAddress (datatableBuffer1Addresses, datatableBuffer1.data ());
|
||||
ReplaceLeaBufferAddress (datatableBuffer2Addresses, datatableBuffer2.data ());
|
||||
ReplaceLeaBufferAddress (datatableBuffer3Addresses, datatableBuffer3.data ());
|
||||
}
|
||||
|
||||
// Fix language
|
||||
if (fixLanguage) {
|
||||
INSTALL_HOOK (GetLanguage);
|
||||
INSTALL_HOOK (GetRegionLanguage);
|
||||
INSTALL_HOOK (GetCabinetLanguage);
|
||||
}
|
||||
|
||||
// Disable demo movie
|
||||
if (!demoMovie) WRITE_MEMORY (ASLR (0x14047D387), u8, 0x00);
|
||||
|
||||
// Enable mode
|
||||
INSTALL_HOOK (AvailableMode_Dani_AI);
|
||||
if (modeCollabo025) INSTALL_HOOK (AvailableMode_Collabo025);
|
||||
if (modeCollabo026) INSTALL_HOOK (AvailableMode_Collabo026);
|
||||
|
||||
// Disable live check
|
||||
auto amHandle = (u64)GetModuleHandle ("AMFrameWork.dll");
|
||||
INSTALL_HOOK_DYNAMIC (AMFWTerminate, (void *)(amHandle + 0x25A00));
|
||||
|
||||
patches::Qr::Init ();
|
||||
}
|
||||
} // namespace patches::CN_JUN_2023
|
||||
#include "helpers.h"
|
||||
#include "patches.h"
|
||||
#include <safetyhook.hpp>
|
||||
|
||||
extern std::string chassisId;
|
||||
|
||||
namespace patches::CN_JUN_2023 {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
i64 (__fastcall *lua_settop) (u64, u64) = (i64 (__fastcall *) (u64, u64))PROC_ADDRESS ("lua51.dll", "lua_settop");
|
||||
i64 (__fastcall *lua_pushboolean) (u64, u64) = (i64 (__fastcall *) (u64, u64))PROC_ADDRESS ("lua51.dll", "lua_pushboolean");
|
||||
i64 (__fastcall *lua_pushstring) (u64, u64) = (i64 (__fastcall *) (u64, u64))PROC_ADDRESS ("lua51.dll", "lua_pushstring");
|
||||
|
||||
i64
|
||||
lua_pushtrue (i64 a1) {
|
||||
lua_settop (a1, 0);
|
||||
lua_pushboolean (a1, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
HOOK (i64, AvailableMode_Dani_AI, ASLR (0x1401AC550), i64 a1) { return lua_pushtrue (a1); }
|
||||
HOOK (i64, AvailableMode_Collabo025, ASLR (0x1402BFF70), i64 *, i64 a2) { return lua_pushtrue (a2); }
|
||||
HOOK (i64, AvailableMode_Collabo026, ASLR (0x1402BC9B0), i64 a1) { return lua_pushtrue (a1); }
|
||||
|
||||
int language = 0;
|
||||
const char *
|
||||
languageStr () {
|
||||
switch (language) {
|
||||
case 1: return "en_us";
|
||||
case 2: return "cn_tw";
|
||||
case 3: return "kor";
|
||||
case 4: return "cn_cn";
|
||||
default: return "jpn";
|
||||
}
|
||||
}
|
||||
HOOK (i64, GetLanguage, ASLR (0x140023720), i64 a1) {
|
||||
auto result = originalGetLanguage (a1);
|
||||
language = *((u32 *)result);
|
||||
return result;
|
||||
}
|
||||
HOOK (i64, GetRegionLanguage, ASLR (0x1401AC300), i64 a1) {
|
||||
lua_settop (a1, 0);
|
||||
lua_pushstring (a1, (u64)languageStr ());
|
||||
return 1;
|
||||
}
|
||||
HOOK (i64, GetCabinetLanguage, ASLR (0x1401AF270), i64, i64 a2) {
|
||||
lua_settop (a2, 0);
|
||||
lua_pushstring (a2, (u64)languageStr ());
|
||||
return 1;
|
||||
}
|
||||
|
||||
HOOK_DYNAMIC (char, __fastcall, AMFWTerminate, i64) { return 0; }
|
||||
|
||||
const i32 datatableBufferSize = 1024 * 1024 * 12;
|
||||
safetyhook::Allocation datatableBuffer1;
|
||||
safetyhook::Allocation datatableBuffer2;
|
||||
safetyhook::Allocation datatableBuffer3;
|
||||
const std::vector<uintptr_t> datatableBuffer1Addresses = {0x140093430, 0x1400934A1, 0x1400934CB, 0x14009353C};
|
||||
const std::vector<uintptr_t> datatableBuffer2Addresses = {0x14009341C, 0x14009354B, 0x14009357E};
|
||||
const std::vector<uintptr_t> datatableBuffer3Addresses = {0x14009356F, 0x140093585, 0x1400935AF};
|
||||
const std::vector<uintptr_t> memsetSizeAddresses = {0x140093416, 0x14009342A, 0x140093569};
|
||||
|
||||
void
|
||||
AllocateStaticBufferNear (void *target_address, size_t size, safetyhook::Allocation *newBuffer) {
|
||||
auto allocator = safetyhook::Allocator::global ();
|
||||
std::vector desired_addresses = {(uint8_t *)target_address};
|
||||
auto allocation_result = allocator->allocate_near (desired_addresses, size);
|
||||
if (allocation_result.has_value ()) *newBuffer = std::move (*allocation_result);
|
||||
}
|
||||
|
||||
void
|
||||
ReplaceLeaBufferAddress (const std::vector<uintptr_t> &bufferAddresses, void *newBufferAddress) {
|
||||
for (auto bufferAddress : bufferAddresses) {
|
||||
uintptr_t lea_instruction_dst = ASLR (bufferAddress) + 3;
|
||||
uintptr_t lea_instruction_end = ASLR (bufferAddress) + 7;
|
||||
intptr_t offset = (intptr_t)newBufferAddress - lea_instruction_end;
|
||||
WRITE_MEMORY (lea_instruction_dst, i32, (i32)offset);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Init () {
|
||||
i32 xRes = 1920;
|
||||
i32 yRes = 1080;
|
||||
bool vsync = false;
|
||||
bool sharedAudio = true;
|
||||
bool unlockSongs = true;
|
||||
bool fixLanguage = false;
|
||||
bool demoMovie = true;
|
||||
bool modeCollabo025 = false;
|
||||
bool modeCollabo026 = false;
|
||||
|
||||
haspBuffer = (u8 *)malloc (0xD40);
|
||||
memset (haspBuffer, 0, 0xD40);
|
||||
strcpy ((char *)(haspBuffer + 0xD00), chassisId.c_str ());
|
||||
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";
|
||||
std::unique_ptr<toml_table_t, void (*) (toml_table_t *)> config_ptr (openConfig (configPath), toml_free);
|
||||
toml_table_t *config = config_ptr.get ();
|
||||
if (config) {
|
||||
auto patches = openConfigSection (config, "patches");
|
||||
if (patches) {
|
||||
auto res = openConfigSection (patches, "res");
|
||||
if (res) {
|
||||
xRes = readConfigInt (res, "x", xRes);
|
||||
yRes = readConfigInt (res, "y", yRes);
|
||||
}
|
||||
vsync = readConfigBool (patches, "vsync", vsync);
|
||||
sharedAudio = readConfigBool (patches, "shared_audio", sharedAudio);
|
||||
unlockSongs = readConfigBool (patches, "unlock_songs", unlockSongs);
|
||||
auto cn_jun_2023 = openConfigSection (patches, "cn_jun_2023");
|
||||
if (cn_jun_2023) {
|
||||
fixLanguage = readConfigBool (cn_jun_2023, "fix_language", fixLanguage);
|
||||
demoMovie = readConfigBool (cn_jun_2023, "demo_movie", demoMovie);
|
||||
modeCollabo025 = readConfigBool (cn_jun_2023, "mode_collabo025", modeCollabo025);
|
||||
modeCollabo026 = readConfigBool (cn_jun_2023, "mode_collabo026", modeCollabo026);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Apply common config patch
|
||||
WRITE_MEMORY (ASLR (0x1404A4ED3), i32, xRes);
|
||||
WRITE_MEMORY (ASLR (0x1404A4EDA), i32, yRes);
|
||||
if (!vsync) WRITE_MEMORY (ASLR (0x1405FC5B9), u8, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x90);
|
||||
if (sharedAudio) WRITE_MEMORY (ASLR (0x140777F87), u8, 0xEB);
|
||||
if (unlockSongs) WRITE_MEMORY (ASLR (0x140425BCD), u8, 0xB0, 0x01);
|
||||
|
||||
// Bypass errors
|
||||
WRITE_MEMORY (ASLR (0x14003F690), u8, 0xC3);
|
||||
|
||||
// Use TLS v1.2
|
||||
WRITE_MEMORY (ASLR (0x140369662), u8, 0x10);
|
||||
|
||||
// Disable SSLVerify
|
||||
WRITE_MEMORY (ASLR (0x14034C182), u8, 0x00);
|
||||
|
||||
// Move various files to current dir
|
||||
WRITE_MEMORY (ASLR (0x140C33C40), char, "./");
|
||||
WRITE_MEMORY (ASLR (0x140C33C44), char, "./");
|
||||
WRITE_MEMORY (ASLR (0x140C7B158), char, ".\\SettingChina1.bin");
|
||||
WRITE_MEMORY (ASLR (0x140C7B2B8), char, ".\\SettingChina1.bin");
|
||||
WRITE_MEMORY (ASLR (0x140C7B2A0), char, ".\\SettingChina2.bin");
|
||||
|
||||
// Remove datatable size limit
|
||||
{
|
||||
for (auto address : memsetSizeAddresses)
|
||||
WRITE_MEMORY (ASLR (address) + 2, i32, datatableBufferSize);
|
||||
|
||||
auto bufferBase = MODULE_HANDLE - 0x03000000;
|
||||
AllocateStaticBufferNear ((void *)bufferBase, datatableBufferSize, &datatableBuffer1);
|
||||
bufferBase += datatableBufferSize;
|
||||
AllocateStaticBufferNear ((void *)bufferBase, datatableBufferSize, &datatableBuffer2);
|
||||
bufferBase += datatableBufferSize;
|
||||
AllocateStaticBufferNear ((void *)bufferBase, datatableBufferSize, &datatableBuffer3);
|
||||
|
||||
ReplaceLeaBufferAddress (datatableBuffer1Addresses, datatableBuffer1.data ());
|
||||
ReplaceLeaBufferAddress (datatableBuffer2Addresses, datatableBuffer2.data ());
|
||||
ReplaceLeaBufferAddress (datatableBuffer3Addresses, datatableBuffer3.data ());
|
||||
}
|
||||
|
||||
// Fix language
|
||||
if (fixLanguage) {
|
||||
INSTALL_HOOK (GetLanguage);
|
||||
INSTALL_HOOK (GetRegionLanguage);
|
||||
INSTALL_HOOK (GetCabinetLanguage);
|
||||
}
|
||||
|
||||
// Disable demo movie
|
||||
if (!demoMovie) WRITE_MEMORY (ASLR (0x14047D387), u8, 0x00);
|
||||
|
||||
// Enable mode
|
||||
INSTALL_HOOK (AvailableMode_Dani_AI);
|
||||
if (modeCollabo025) INSTALL_HOOK (AvailableMode_Collabo025);
|
||||
if (modeCollabo026) INSTALL_HOOK (AvailableMode_Collabo026);
|
||||
|
||||
// Disable live check
|
||||
auto amHandle = (u64)GetModuleHandle ("AMFrameWork.dll");
|
||||
INSTALL_HOOK_DYNAMIC (AMFWTerminate, (void *)(amHandle + 0x25A00));
|
||||
|
||||
patches::Qr::Init ();
|
||||
}
|
||||
} // namespace patches::CN_JUN_2023
|
||||
|
@ -1,185 +1,185 @@
|
||||
#include "helpers.h"
|
||||
#include "patches.h"
|
||||
#include <safetyhook.hpp>
|
||||
|
||||
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)
|
||||
|
||||
namespace patches::JP_NOV_2020 {
|
||||
|
||||
HOOK_DYNAMIC (char, __fastcall, AMFWTerminate, i64) { return 0; }
|
||||
|
||||
const i32 datatableBufferSize = 1024 * 1024 * 12;
|
||||
safetyhook::Allocation datatableBuffer;
|
||||
const std::vector<uintptr_t> datatableBufferAddresses = {0x14006D9A6, 0x14006D9D3, 0x14006E048, 0x14006E075, 0x14006E3A8, 0x14006E3D5, 0x14006E988, 0x14006E9B5, 0x14006EE22, 0x14006EE51, 0x14006F068,
|
||||
0x14006F095, 0x14006F2F8, 0x14006F325, 0x14006F698, 0x14006F6C5, 0x14006F919, 0x14006F948, 0x14006FC38, 0x14006FC67, 0x14007006C, 0x140070099,
|
||||
0x1400703E3, 0x140070412, 0x140070EB3, 0x140070EE2, 0x140071748, 0x140071775, 0x140071A68, 0x140071A95, 0x140071DD2, 0x140071E04, 0x140072E44,
|
||||
0x140072E73, 0x140073058, 0x140073085, 0x140073374, 0x1400733A0, 0x1400735E8, 0x140073615, 0x14007390C, 0x140073939, 0x140073E73, 0x140073EA6,
|
||||
0x140074A8D, 0x140074ABC, 0x140075082, 0x1400750B1, 0x140075524, 0x140075550, 0x1400758A2, 0x1400758D1, 0x140075D88, 0x140075DB5, 0x1403BA8FD};
|
||||
const std::vector<uintptr_t> memsetSizeAddresses = {0x14006D9A0, 0x14006E042, 0x14006E3A2, 0x14006E982, 0x14006EE1C, 0x14006F062, 0x14006F2F2, 0x14006F692, 0x14006F913,
|
||||
0x14006FC32, 0x140070066, 0x1400703DD, 0x140070EAD, 0x140071742, 0x140071A62, 0x140071DCC, 0x140072E3E, 0x140073052,
|
||||
0x14007336E, 0x1400735E2, 0x140073906, 0x140073E6D, 0x140074A87, 0x14007507C, 0x14007551E, 0x14007589C, 0x140075D82};
|
||||
|
||||
void
|
||||
AllocateStaticBufferNear (void *target_address, size_t size, safetyhook::Allocation *newBuffer) {
|
||||
auto allocator = safetyhook::Allocator::global ();
|
||||
std::vector desired_addresses = {(uint8_t *)target_address};
|
||||
auto allocation_result = allocator->allocate_near (desired_addresses, size);
|
||||
if (allocation_result.has_value ()) *newBuffer = std::move (*allocation_result);
|
||||
}
|
||||
|
||||
void
|
||||
ReplaceLeaBufferAddress (const std::vector<uintptr_t> &bufferAddresses, void *newBufferAddress) {
|
||||
for (auto bufferAddress : bufferAddresses) {
|
||||
uintptr_t lea_instruction_dst = ASLR (bufferAddress) + 3;
|
||||
uintptr_t lea_instruction_end = ASLR (bufferAddress) + 7;
|
||||
intptr_t offset = (intptr_t)newBufferAddress - lea_instruction_end;
|
||||
WRITE_MEMORY (lea_instruction_dst, i32, (i32)offset);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Init () {
|
||||
i32 xRes = 1920;
|
||||
i32 yRes = 1080;
|
||||
bool vsync = false;
|
||||
bool sharedAudio = true;
|
||||
bool unlockSongs = true;
|
||||
|
||||
auto configPath = std::filesystem::current_path () / "config.toml";
|
||||
std::unique_ptr<toml_table_t, void (*) (toml_table_t *)> config_ptr (openConfig (configPath), toml_free);
|
||||
toml_table_t *config = config_ptr.get ();
|
||||
if (config) {
|
||||
auto patches = openConfigSection (config, "patches");
|
||||
if (patches) {
|
||||
auto res = openConfigSection (patches, "res");
|
||||
if (res) {
|
||||
xRes = readConfigInt (res, "x", xRes);
|
||||
yRes = readConfigInt (res, "y", yRes);
|
||||
}
|
||||
vsync = readConfigBool (patches, "vsync", vsync);
|
||||
sharedAudio = readConfigBool (patches, "shared_audio", sharedAudio);
|
||||
unlockSongs = readConfigBool (patches, "unlock_songs", unlockSongs);
|
||||
}
|
||||
}
|
||||
|
||||
// Apply common config patch
|
||||
WRITE_MEMORY (ASLR (0x14035FC5B), i32, xRes);
|
||||
WRITE_MEMORY (ASLR (0x14035FC62), i32, yRes);
|
||||
if (!vsync) WRITE_MEMORY (ASLR (0x140517339), u8, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x90);
|
||||
if (sharedAudio) WRITE_MEMORY (ASLR (0x140692E17), u8, 0xEB);
|
||||
if (unlockSongs) WRITE_MEMORY (ASLR (0x140314E8D), u8, 0xB0, 0x01);
|
||||
|
||||
// Bypass errors
|
||||
WRITE_MEMORY (ASLR (0x1400239C0), u8, 0xC3);
|
||||
|
||||
// Use TLS v1.2
|
||||
WRITE_MEMORY (ASLR (0x14044B1A9), u8, 0x10);
|
||||
|
||||
// Move various files to current dir
|
||||
WRITE_MEMORY (ASLR (0x140B1B4B0), char, "./");
|
||||
WRITE_MEMORY (ASLR (0x140B5C528), char, ".\\Setting1.bin");
|
||||
WRITE_MEMORY (ASLR (0x140B5C538), char, ".\\Setting2.bin");
|
||||
WRITE_MEMORY (ASLR (0x14001C941), u8, 0x02);
|
||||
|
||||
// Remove datatable size limit
|
||||
{
|
||||
for (auto address : memsetSizeAddresses)
|
||||
WRITE_MEMORY (ASLR (address) + 2, i32, datatableBufferSize);
|
||||
|
||||
auto bufferBase = MODULE_HANDLE - 0x01000000;
|
||||
AllocateStaticBufferNear ((void *)bufferBase, datatableBufferSize, &datatableBuffer);
|
||||
|
||||
ReplaceLeaBufferAddress (datatableBufferAddresses, datatableBuffer.data ());
|
||||
}
|
||||
|
||||
// Remove song limit
|
||||
{
|
||||
WRITE_MEMORY (ASLR (0x140313726), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1402F39E6), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1402F3AB0), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1402F3BE4), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x14030643B), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140306507), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1403065D3), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1403066FB), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1403067C7), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140306893), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x14030698B), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140313666), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1403139F4), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140313B04), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140313C24), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140313CF4), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1403140C4), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1403147AA), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140225FB6), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140226146), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140314DCC), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140314EC9), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140338E2C), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1400EE0A4), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1400EE8B5), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1400EEDA6), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140315608), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x14034A7EB), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1402F3CB3), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140314059), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140226063), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x14022609F), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140226296), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140306A2E), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140314F46), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140314F97), i32, 9000);
|
||||
|
||||
song_data = malloc (song_data_size);
|
||||
memset (song_data, 0, song_data_size);
|
||||
|
||||
// Song data
|
||||
WRITE_MEMORY (ASLR (0x14031367B), u8, GENERATE_MOV (R8_MOV, song_data));
|
||||
// Crown data
|
||||
WRITE_MEMORY (ASLR (0x1402F3AC6), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x1402F39FC), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x1402F3BFA), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x1403140D7), u8, GENERATE_MOV (R8_MOV, song_data));
|
||||
// Score ranks
|
||||
WRITE_MEMORY (ASLR (0x1403065EA), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x14030651E), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x140306452), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x1403068AA), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x1403067DE), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x140306712), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x1403069A2), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x1403069AC), u8, 0x90, 0x90, 0x90, 0x90, 0x90);
|
||||
// Unknown
|
||||
WRITE_MEMORY (ASLR (0x140313755), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x140313A0B), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x140313B4C), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x140313D38), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x140313C42), u8, GENERATE_MOV (R8_MOV, song_data));
|
||||
}
|
||||
|
||||
// Disable live check
|
||||
auto amHandle = (u64)GetModuleHandle ("AMFrameWork.dll");
|
||||
INSTALL_HOOK_DYNAMIC (AMFWTerminate, (void *)(amHandle + 0x35A00));
|
||||
|
||||
// Move various files to current directory
|
||||
WRITE_MEMORY (amHandle + 0x148AF, u8, 0xEB);
|
||||
WRITE_MEMORY (amHandle + 0x14A1A, u8, 0xEB);
|
||||
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);
|
||||
|
||||
patches::Qr::Init ();
|
||||
patches::AmAuth::Init ();
|
||||
}
|
||||
} // namespace patches::JP_NOV_2020
|
||||
#include "helpers.h"
|
||||
#include "patches.h"
|
||||
#include <safetyhook.hpp>
|
||||
|
||||
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)
|
||||
|
||||
namespace patches::JP_NOV_2020 {
|
||||
|
||||
HOOK_DYNAMIC (char, __fastcall, AMFWTerminate, i64) { return 0; }
|
||||
|
||||
const i32 datatableBufferSize = 1024 * 1024 * 12;
|
||||
safetyhook::Allocation datatableBuffer;
|
||||
const std::vector<uintptr_t> datatableBufferAddresses = {0x14006D9A6, 0x14006D9D3, 0x14006E048, 0x14006E075, 0x14006E3A8, 0x14006E3D5, 0x14006E988, 0x14006E9B5, 0x14006EE22, 0x14006EE51, 0x14006F068,
|
||||
0x14006F095, 0x14006F2F8, 0x14006F325, 0x14006F698, 0x14006F6C5, 0x14006F919, 0x14006F948, 0x14006FC38, 0x14006FC67, 0x14007006C, 0x140070099,
|
||||
0x1400703E3, 0x140070412, 0x140070EB3, 0x140070EE2, 0x140071748, 0x140071775, 0x140071A68, 0x140071A95, 0x140071DD2, 0x140071E04, 0x140072E44,
|
||||
0x140072E73, 0x140073058, 0x140073085, 0x140073374, 0x1400733A0, 0x1400735E8, 0x140073615, 0x14007390C, 0x140073939, 0x140073E73, 0x140073EA6,
|
||||
0x140074A8D, 0x140074ABC, 0x140075082, 0x1400750B1, 0x140075524, 0x140075550, 0x1400758A2, 0x1400758D1, 0x140075D88, 0x140075DB5, 0x1403BA8FD};
|
||||
const std::vector<uintptr_t> memsetSizeAddresses = {0x14006D9A0, 0x14006E042, 0x14006E3A2, 0x14006E982, 0x14006EE1C, 0x14006F062, 0x14006F2F2, 0x14006F692, 0x14006F913,
|
||||
0x14006FC32, 0x140070066, 0x1400703DD, 0x140070EAD, 0x140071742, 0x140071A62, 0x140071DCC, 0x140072E3E, 0x140073052,
|
||||
0x14007336E, 0x1400735E2, 0x140073906, 0x140073E6D, 0x140074A87, 0x14007507C, 0x14007551E, 0x14007589C, 0x140075D82};
|
||||
|
||||
void
|
||||
AllocateStaticBufferNear (void *target_address, size_t size, safetyhook::Allocation *newBuffer) {
|
||||
auto allocator = safetyhook::Allocator::global ();
|
||||
std::vector desired_addresses = {(uint8_t *)target_address};
|
||||
auto allocation_result = allocator->allocate_near (desired_addresses, size);
|
||||
if (allocation_result.has_value ()) *newBuffer = std::move (*allocation_result);
|
||||
}
|
||||
|
||||
void
|
||||
ReplaceLeaBufferAddress (const std::vector<uintptr_t> &bufferAddresses, void *newBufferAddress) {
|
||||
for (auto bufferAddress : bufferAddresses) {
|
||||
uintptr_t lea_instruction_dst = ASLR (bufferAddress) + 3;
|
||||
uintptr_t lea_instruction_end = ASLR (bufferAddress) + 7;
|
||||
intptr_t offset = (intptr_t)newBufferAddress - lea_instruction_end;
|
||||
WRITE_MEMORY (lea_instruction_dst, i32, (i32)offset);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Init () {
|
||||
i32 xRes = 1920;
|
||||
i32 yRes = 1080;
|
||||
bool vsync = false;
|
||||
bool sharedAudio = true;
|
||||
bool unlockSongs = true;
|
||||
|
||||
auto configPath = std::filesystem::current_path () / "config.toml";
|
||||
std::unique_ptr<toml_table_t, void (*) (toml_table_t *)> config_ptr (openConfig (configPath), toml_free);
|
||||
toml_table_t *config = config_ptr.get ();
|
||||
if (config) {
|
||||
auto patches = openConfigSection (config, "patches");
|
||||
if (patches) {
|
||||
auto res = openConfigSection (patches, "res");
|
||||
if (res) {
|
||||
xRes = readConfigInt (res, "x", xRes);
|
||||
yRes = readConfigInt (res, "y", yRes);
|
||||
}
|
||||
vsync = readConfigBool (patches, "vsync", vsync);
|
||||
sharedAudio = readConfigBool (patches, "shared_audio", sharedAudio);
|
||||
unlockSongs = readConfigBool (patches, "unlock_songs", unlockSongs);
|
||||
}
|
||||
}
|
||||
|
||||
// Apply common config patch
|
||||
WRITE_MEMORY (ASLR (0x14035FC5B), i32, xRes);
|
||||
WRITE_MEMORY (ASLR (0x14035FC62), i32, yRes);
|
||||
if (!vsync) WRITE_MEMORY (ASLR (0x140517339), u8, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x90);
|
||||
if (sharedAudio) WRITE_MEMORY (ASLR (0x140692E17), u8, 0xEB);
|
||||
if (unlockSongs) WRITE_MEMORY (ASLR (0x140314E8D), u8, 0xB0, 0x01);
|
||||
|
||||
// Bypass errors
|
||||
WRITE_MEMORY (ASLR (0x1400239C0), u8, 0xC3);
|
||||
|
||||
// Use TLS v1.2
|
||||
WRITE_MEMORY (ASLR (0x14044B1A9), u8, 0x10);
|
||||
|
||||
// Move various files to current dir
|
||||
WRITE_MEMORY (ASLR (0x140B1B4B0), char, "./");
|
||||
WRITE_MEMORY (ASLR (0x140B5C528), char, ".\\Setting1.bin");
|
||||
WRITE_MEMORY (ASLR (0x140B5C538), char, ".\\Setting2.bin");
|
||||
WRITE_MEMORY (ASLR (0x14001C941), u8, 0x02);
|
||||
|
||||
// Remove datatable size limit
|
||||
{
|
||||
for (auto address : memsetSizeAddresses)
|
||||
WRITE_MEMORY (ASLR (address) + 2, i32, datatableBufferSize);
|
||||
|
||||
auto bufferBase = MODULE_HANDLE - 0x01000000;
|
||||
AllocateStaticBufferNear ((void *)bufferBase, datatableBufferSize, &datatableBuffer);
|
||||
|
||||
ReplaceLeaBufferAddress (datatableBufferAddresses, datatableBuffer.data ());
|
||||
}
|
||||
|
||||
// Remove song limit
|
||||
{
|
||||
WRITE_MEMORY (ASLR (0x140313726), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1402F39E6), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1402F3AB0), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1402F3BE4), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x14030643B), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140306507), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1403065D3), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1403066FB), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1403067C7), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140306893), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x14030698B), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140313666), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1403139F4), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140313B04), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140313C24), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140313CF4), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1403140C4), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1403147AA), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140225FB6), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140226146), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140314DCC), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140314EC9), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140338E2C), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1400EE0A4), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1400EE8B5), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1400EEDA6), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140315608), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x14034A7EB), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x1402F3CB3), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140314059), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140226063), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x14022609F), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140226296), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140306A2E), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140314F46), i32, 9000);
|
||||
WRITE_MEMORY (ASLR (0x140314F97), i32, 9000);
|
||||
|
||||
song_data = malloc (song_data_size);
|
||||
memset (song_data, 0, song_data_size);
|
||||
|
||||
// Song data
|
||||
WRITE_MEMORY (ASLR (0x14031367B), u8, GENERATE_MOV (R8_MOV, song_data));
|
||||
// Crown data
|
||||
WRITE_MEMORY (ASLR (0x1402F3AC6), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x1402F39FC), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x1402F3BFA), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x1403140D7), u8, GENERATE_MOV (R8_MOV, song_data));
|
||||
// Score ranks
|
||||
WRITE_MEMORY (ASLR (0x1403065EA), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x14030651E), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x140306452), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x1403068AA), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x1403067DE), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x140306712), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x1403069A2), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x1403069AC), u8, 0x90, 0x90, 0x90, 0x90, 0x90);
|
||||
// Unknown
|
||||
WRITE_MEMORY (ASLR (0x140313755), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x140313A0B), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x140313B4C), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x140313D38), u8, GENERATE_MOV (RDX_MOV, song_data));
|
||||
WRITE_MEMORY (ASLR (0x140313C42), u8, GENERATE_MOV (R8_MOV, song_data));
|
||||
}
|
||||
|
||||
// Disable live check
|
||||
auto amHandle = (u64)GetModuleHandle ("AMFrameWork.dll");
|
||||
INSTALL_HOOK_DYNAMIC (AMFWTerminate, (void *)(amHandle + 0x35A00));
|
||||
|
||||
// Move various files to current directory
|
||||
WRITE_MEMORY (amHandle + 0x148AF, u8, 0xEB);
|
||||
WRITE_MEMORY (amHandle + 0x14A1A, u8, 0xEB);
|
||||
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);
|
||||
|
||||
patches::Qr::Init ();
|
||||
patches::AmAuth::Init ();
|
||||
}
|
||||
} // namespace patches::JP_NOV_2020
|
||||
|
@ -1,18 +1,18 @@
|
||||
namespace patches {
|
||||
namespace JP_NOV_2020 {
|
||||
void Init ();
|
||||
} // namespace JP_NOV_2020
|
||||
namespace CN_JUN_2023 {
|
||||
void Init ();
|
||||
} // namespace CN_JUN_2023
|
||||
namespace JP_APR_2023 {
|
||||
void Init ();
|
||||
} // namespace JP_APR_2023
|
||||
namespace AmAuth {
|
||||
void Init ();
|
||||
} // namespace AmAuth
|
||||
namespace Qr {
|
||||
void Init ();
|
||||
void Update ();
|
||||
} // namespace Qr
|
||||
} // namespace patches
|
||||
namespace patches {
|
||||
namespace JP_NOV_2020 {
|
||||
void Init ();
|
||||
} // namespace JP_NOV_2020
|
||||
namespace CN_JUN_2023 {
|
||||
void Init ();
|
||||
} // namespace CN_JUN_2023
|
||||
namespace JP_APR_2023 {
|
||||
void Init ();
|
||||
} // namespace JP_APR_2023
|
||||
namespace AmAuth {
|
||||
void Init ();
|
||||
} // namespace AmAuth
|
||||
namespace Qr {
|
||||
void Init ();
|
||||
void Update ();
|
||||
} // namespace Qr
|
||||
} // namespace patches
|
||||
|
1282
src/poll.cpp
1282
src/poll.cpp
File diff suppressed because it is too large
Load Diff
206
src/poll.h
206
src/poll.h
@ -1,103 +1,103 @@
|
||||
#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);
|
||||
#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);
|
||||
|
@ -1,21 +1,21 @@
|
||||
--- minhook/meson.build
|
||||
+++ 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,
|
||||
+)
|
||||
--- minhook/meson.build
|
||||
+++ 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,
|
||||
+)
|
||||
|
@ -1,15 +1,15 @@
|
||||
--- tomlc99/meson.build
|
||||
+++ 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,
|
||||
+)
|
||||
--- tomlc99/meson.build
|
||||
+++ 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,
|
||||
+)
|
||||
|
@ -1,7 +1,7 @@
|
||||
[wrap-git]
|
||||
url = https://github.com/cursey/safetyhook.git
|
||||
revision = v0.4.1
|
||||
method = cmake
|
||||
|
||||
[provide]
|
||||
safetyhook = safetyhook_dep
|
||||
[wrap-git]
|
||||
url = https://github.com/cursey/safetyhook.git
|
||||
revision = v0.4.1
|
||||
method = cmake
|
||||
|
||||
[provide]
|
||||
safetyhook = safetyhook_dep
|
||||
|
@ -1,4 +1,4 @@
|
||||
[wrap-git]
|
||||
url = https://github.com/cktan/tomlc99.git
|
||||
revision = master
|
||||
diff_files = tomlc99.patch
|
||||
[wrap-git]
|
||||
url = https://github.com/cktan/tomlc99.git
|
||||
revision = master
|
||||
diff_files = tomlc99.patch
|
||||
|
Loading…
x
Reference in New Issue
Block a user