mirror of
https://github.com/esuo1198/TaikoArcadeLoader.git
synced 2026-10-04 12:47:58 +03:00
Merge pull request #24 from ryumiyax/Refactor
[Experimental] auto_ime enhanced | graphic enhanced | build without requirement of msvcp140.dll
This commit is contained in:
+8
-2
@@ -2,6 +2,11 @@ cmake_minimum_required(VERSION 3.25)
|
||||
|
||||
project(TaikoArcadeLoader VERSION 1.0.0 LANGUAGES C CXX)
|
||||
|
||||
# Set runtime library to static
|
||||
if(MSVC)
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>" CACHE INTERNAL "")
|
||||
endif()
|
||||
|
||||
# Set C and C++ standards
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD 23)
|
||||
@@ -134,8 +139,8 @@ set(SOURCES
|
||||
src/pollasync.cpp
|
||||
src/bnusio.cpp
|
||||
src/patches/amauth.cpp
|
||||
src/patches/dxgi.cpp
|
||||
src/patches/fpslimiter.cpp
|
||||
# src/patches/dxgi.cpp
|
||||
# src/patches/fpslimiter.cpp
|
||||
src/patches/audio.cpp
|
||||
src/patches/plugins.cpp
|
||||
src/patches/scanner.cpp
|
||||
@@ -143,6 +148,7 @@ set(SOURCES
|
||||
src/patches/testmode.cpp
|
||||
src/patches/timer.cpp
|
||||
src/patches/language.cpp
|
||||
# src/patches/unlimitsong.cpp
|
||||
src/patches/versions/JPN00.cpp
|
||||
src/patches/versions/JPN08.cpp
|
||||
src/patches/versions/JPN39.cpp
|
||||
|
||||
@@ -34,6 +34,7 @@ version = "auto" # Patch version
|
||||
# | - JPN39: For use with Taiko JPN 39.06
|
||||
# | - CHN00: For use with Taiko CHN 00.32
|
||||
unlock_songs = true # not active for JPN39 (see TestMode)
|
||||
# More options are available in the ModManager, in the TestMode menu (Default key is F1)
|
||||
|
||||
[patches.chn00] # These patches are only available for version CHN00
|
||||
fix_language = false # Sync test mode language to attract etc
|
||||
@@ -41,25 +42,26 @@ demo_movie = true # Show demo movie
|
||||
mode_collabo025 = false # Enable one piece collab mode
|
||||
mode_collabo026 = false # Enable ai soshina mode
|
||||
|
||||
[patches.jpn39] # These patches are only available for version JPN39
|
||||
chs_patch = false # Use Chinese font and Simplified Chinese values from the wordlist
|
||||
# More options are available in the ModManager, in the TestMode menu (Default key is F1)
|
||||
|
||||
[emulation]
|
||||
usio = true # If usio emulation is disabled, you need to place bnusio_original.dll (unmodified bnusio.dll) in the executable folder.
|
||||
card_reader = true # Disable this if you have an original namco card reader
|
||||
accept_invalid = false # Enable this if you want to accept cards incompatible with the original readers
|
||||
accept_invalid = false # Enable this if you want to accept cards incompatible with the original readers
|
||||
qr = true # Disable this if you have an original namco qr code scanner
|
||||
|
||||
|
||||
[graphics]
|
||||
res = { x = 1920, y = 1080 }
|
||||
windowed = false
|
||||
cursor = true
|
||||
vsync = false
|
||||
fpslimit = 120
|
||||
windowed = false # not windowed will automatically fullscreen
|
||||
cursor = true # fullscreen will automatically hide cursor
|
||||
vsync = false # enable this if you are using a 120fps screen (and use "Let Application Decide" in Nvidia panel)
|
||||
# fpslimit = 0 # temporoly remove it, limit it to 120 in Nvidia panel instead!!!
|
||||
model_res_rate = 1.0 # Don-Model resolution rate (currently JPN39 only)
|
||||
# | rate <= 0: default 1280x720
|
||||
# | rate > 0: current resolution * rate
|
||||
|
||||
[audio]
|
||||
wasapi_shared = true # Wasapi shared mode, allows you to have multiple audio sources at once at a cost of having higher latency.
|
||||
wasapi_shared = false # Wasapi shared mode, allows you to have multiple audio sources at once at a cost of having higher latency.
|
||||
asio = false # Use asio audio mode
|
||||
asio_driver = "ASIO4ALL v2" # Asio driver name
|
||||
# | If you're not using asio4all, open up regedit then navigate to HKEY_LOCAL_MACHINE\SOFTWARE\ASIO for your driver's name.
|
||||
@@ -76,7 +78,7 @@ type = 0 # qr type
|
||||
song_no = [] # Song noes used for custom folder
|
||||
|
||||
[controller]
|
||||
wait_period = 4 # Input interval (if using taiko drum controller, should be set to 0)
|
||||
wait_period = 0 # Input interval (if using taiko drum controller, should be set to 0)
|
||||
analog_input = false # Use analog input (you need a compatible controller, this allows playing small and big notes like on arcade cabinets)
|
||||
|
||||
[keyboard]
|
||||
@@ -86,8 +88,8 @@ jp_layout = false # Use jp layout scan code (if using jp layout keyboa
|
||||
[layeredfs]
|
||||
enabled = false # Replace assets from the game using a layered file system.
|
||||
# | For example if you want to edit the wordlist, add your edited version like so:
|
||||
# | .\Data_mods\x64\datatable\wordlist.json
|
||||
# | You can provide both unencrypted and encrypted files.
|
||||
# | .\Data_mods\x64\datatable\wordlist.json
|
||||
# | You can provide both unencrypted and encrypted files.
|
||||
|
||||
[logging]
|
||||
log_level = "INFO" # Log level, Can be either "NONE", "ERROR", "WARN", "INFO", "DEBUG" and "HOOKS"
|
||||
@@ -105,17 +107,22 @@ The follow options are available in "MOD MANAGER" menu:
|
||||
* FIX LANGUAGE (sync test mode language to attract etc)
|
||||
* UNLOCK SONGS (show all of the songs)
|
||||
* FREEZE TIMER (stop timer count down)
|
||||
* KIMETSU MODE (enable collabo024, will show a blank title)
|
||||
* KIMETSU MODE (enable collabo024, will show a blank title and crash when enter)
|
||||
* ONE PIECE MODE (enable collabo025)
|
||||
* AI SOSHINA MODE (enable collabo026)
|
||||
* AOHARU MODE (enable aprilfool001)
|
||||
* INSTANT RESULT (send result per song)
|
||||
* INSTANT RESULT (send result per song, experimental not stable)
|
||||
|
||||
Enhanced original option:
|
||||
|
||||
* Louder volume (Speaker Volume is now up to 300%, **WARNING: May damage your speakers**)
|
||||
* Attract demo (Only available if FIX LANGUAGE is ON)
|
||||
|
||||
With chs-patch (Only unlock while resource correctly settled):
|
||||
|
||||
* Add Language: zh-cn
|
||||
* Add Voice Language (Could switch between JPN and CHN)
|
||||
|
||||
## Building Manually
|
||||
|
||||
To compile TaikoArcadeLoader, you'll need to install [MSVC](https://aka.ms/vs/17/release/vs_BuildTools.exe).
|
||||
|
||||
Vendored
+13
-11
@@ -15,7 +15,6 @@ version = "auto" # Patch version
|
||||
# | - JPN39: For use with Taiko JPN 39.06
|
||||
# | - CHN00: For use with Taiko CHN 00.32
|
||||
unlock_songs = true
|
||||
high_res_timer = true # (experimental) Enable High Resolution Timer, which might improve judgement timing
|
||||
|
||||
[patches.chn00] # These patches are only available for version CHN00
|
||||
fix_language = false # Sync test mode language to attract etc
|
||||
@@ -27,20 +26,23 @@ mode_collabo026 = false # Enable ai soshina mode
|
||||
[emulation]
|
||||
usio = true # Disable this if you want to use an original Namco USIO board. you need to place bnusio_original.dll (unmodified bnusio.dll) in the executable folder.
|
||||
card_reader = true # Disable this if you want to use an original Namco card reader
|
||||
accept_invalid = false # Enable this if you want to accept cards incompatible with the original readers
|
||||
accept_invalid = false # Enable this if you want to accept cards incompatible with the original readers
|
||||
qr = true # Disable this if you want to use an original Namco QR code scanner
|
||||
|
||||
|
||||
[graphics]
|
||||
res = { x = 1920, y = 1080 }
|
||||
windowed = false
|
||||
cursor = true
|
||||
vsync = false
|
||||
fpslimit = 120
|
||||
windowed = false # not windowed will automatically fullscreen
|
||||
cursor = true # fullscreen will automatically hide cursor
|
||||
vsync = false # enable this if you are using a 120fps screen (and use "Let Application Decide" in Nvidia panel)
|
||||
# fpslimit = 0 # temporoly remove it, limit it to 120 in Nvidia panel instead!!!
|
||||
model_res_rate = 1.0 # Don-Model resolution rate (currently JPN39 only)
|
||||
# | rate <= 0: default 1280x720
|
||||
# | rate > 0: current resolution * rate
|
||||
|
||||
|
||||
[audio]
|
||||
wasapi_shared = true # Wasapi shared mode, allows you to have multiple audio sources at once at a cost of having higher latency.
|
||||
wasapi_shared = false # Wasapi shared mode, allows you to have multiple audio sources at once at a cost of having higher latency.
|
||||
asio = false # Use asio audio mode
|
||||
asio_driver = "ASIO4ALL v2" # Asio driver name
|
||||
# | If you're not using asio4all, open up regedit then navigate to HKEY_LOCAL_MACHINE\SOFTWARE\ASIO for your driver's name.
|
||||
@@ -60,20 +62,20 @@ song_no = [] # Song noes used for custom folder
|
||||
|
||||
|
||||
[controller]
|
||||
wait_period = 4 # Input interval (if using taiko drum controller, should be set to 0)
|
||||
wait_period = 0 # Input interval (if using taiko drum controller, should be set to 0)
|
||||
analog_input = false # Use analog input (you need a compatible controller, this allows playing small and big notes like on arcade cabinets)
|
||||
|
||||
|
||||
[keyboard]
|
||||
auto_ime = false # Automatically change to english ime mode upon game startup
|
||||
auto_ime = true # Automatically change to english ime mode upon game startup
|
||||
jp_layout = false # Use jp layout scan code (if using jp layout keyboard, must be set to true)
|
||||
|
||||
|
||||
[layeredfs]
|
||||
enabled = false # Replace assets from the game using a layered file system.
|
||||
# | For example if you want to edit the wordlist, add your edited version like so:
|
||||
# | .\Data_mods\x64\datatable\wordlist.json
|
||||
# | You can provide both unencrypted and encrypted files.
|
||||
# | .\Data_mods\x64\datatable\wordlist.json
|
||||
# | You can provide both unencrypted and encrypted files.
|
||||
|
||||
|
||||
[logging]
|
||||
|
||||
Vendored
+1
-1
@@ -21,7 +21,7 @@ P2_LEFT_RED = ["X"]
|
||||
P2_RIGHT_RED = ["C"]
|
||||
P2_RIGHT_BLUE = ["V"]
|
||||
|
||||
# ESCAPE F1 through F12
|
||||
# ESCAPE F1 through F12
|
||||
# ` 1 through 0 -= BACKSPACE ^ YEN
|
||||
# TAB QWERTYUIOP [ ] BACKSLASH @
|
||||
# CAPS_LOCK ASDFGHJKL ;' ENTER :
|
||||
|
||||
+90
-200
@@ -13,22 +13,11 @@ extern char accessCode1[21];
|
||||
extern char accessCode2[21];
|
||||
extern char chipId1[33];
|
||||
extern char chipId2[33];
|
||||
extern bool autoIme;
|
||||
|
||||
extern bool emulateUsio;
|
||||
extern bool emulateCardReader;
|
||||
extern bool acceptInvalidCards;
|
||||
extern HWND hGameWnd;
|
||||
|
||||
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}};
|
||||
@@ -48,9 +37,6 @@ Keybindings P2_LEFT_BLUE = {.keycodes = {'Z'}};
|
||||
Keybindings P2_LEFT_RED = {.keycodes = {'X'}};
|
||||
Keybindings P2_RIGHT_RED = {.keycodes = {'C'}};
|
||||
Keybindings P2_RIGHT_BLUE = {.keycodes = {'V'}};
|
||||
// Keybindings ALL[] = { EXIT, TEST, SERVICE, DEBUG_UP, DEBUG_DOWN, DEBUG_ENTER, COIN_ADD,
|
||||
// CARD_INSERT_1, CARD_INSERT_2, QR_DATA_READ, QR_IMAGE_READ, P1_LEFT_BLUE, P1_LEFT_RED,
|
||||
// P1_RIGHT_RED, P1_RIGHT_BLUE, P2_LEFT_BLUE, P2_LEFT_RED, P2_RIGHT_RED, P2_RIGHT_BLUE };
|
||||
|
||||
const int exitWait = 100;
|
||||
int exited = 0;
|
||||
@@ -64,64 +50,68 @@ bool updateByCoin = false;
|
||||
HWND windowHandle = nullptr;
|
||||
float axisThreshold = 0.6f;
|
||||
u8 inputState = 1 | (1 << 2);
|
||||
bool globalKeyboard = false;;
|
||||
HKL currentLayout;
|
||||
bool globalKeyboard = false;
|
||||
|
||||
namespace bnusio {
|
||||
#define RETURN_FALSE(returnType, functionName, ...) \
|
||||
returnType functionName (__VA_ARGS__) { return 0; }
|
||||
HMODULE bnusioOriginal = LoadLibrary ("bnusio_original.dll");
|
||||
#define BNUSIO_EXPORT(returnType, functionName, ...) \
|
||||
typedef returnType (*type_##functionName) (__VA_ARGS__); \
|
||||
type_##functionName ori_##functionName = bnusioOriginal == nullptr ? nullptr : (type_##functionName)GetProcAddress (bnusioOriginal, #functionName); \
|
||||
returnType functionName (__VA_ARGS__)
|
||||
|
||||
#define CALL_BNUSIO_FALSE(functionName, ...) \
|
||||
{ if (!emulateUsio && ori_##functionName) return ori_##functionName (__VA_ARGS__); else return 0; }
|
||||
|
||||
typedef u16 (__fastcall *AnalogMethod) (const u8);
|
||||
AnalogMethod analogMethod = nullptr;
|
||||
|
||||
extern "C" {
|
||||
RETURN_FALSE (i64, bnusio_Open);
|
||||
RETURN_FALSE (i64, bnusio_Close);
|
||||
RETURN_FALSE (i64, bnusio_Communication, i32 a1);
|
||||
RETURN_FALSE (u8, bnusio_IsConnected);
|
||||
RETURN_FALSE (i32, bnusio_ResetIoBoard);
|
||||
RETURN_FALSE (u16, bnusio_GetStatusU16, u16 a1);
|
||||
RETURN_FALSE (u8, bnusio_GetStatusU8, u16 a1);
|
||||
RETURN_FALSE (u16, bnusio_GetRegisterU16, i16 a1);
|
||||
RETURN_FALSE (u8, bnusio_GetRegisterU8, u16 a1);
|
||||
RETURN_FALSE (void *, bnusio_GetBuffer, u16 a1, i64 a2, i16 a3);
|
||||
RETURN_FALSE (i64, bnusio_SetRegisterU16, u16 a1, u16 a2);
|
||||
RETURN_FALSE (i64, bnusio_SetRegisterU8, u16 a1, u8 a2);
|
||||
RETURN_FALSE (i64, bnusio_SetBuffer, u16 a1, i32 a2, i16 a3);
|
||||
RETURN_FALSE (void *, bnusio_GetSystemError);
|
||||
RETURN_FALSE (i64, bnusio_SetSystemError, i16 a1);
|
||||
RETURN_FALSE (i64, bnusio_ClearSram);
|
||||
RETURN_FALSE (void *, bnusio_GetExpansionMode);
|
||||
RETURN_FALSE (i64, bnusio_SetExpansionMode, i16 a1);
|
||||
RETURN_FALSE (u8, bnusio_IsWideUsio);
|
||||
RETURN_FALSE (u64, bnusio_GetSwIn64);
|
||||
RETURN_FALSE (u8, bnusio_GetGout, u8 a1);
|
||||
RETURN_FALSE (i64, bnusio_SetGout, u8 a1, u8 a2);
|
||||
RETURN_FALSE (u64, bnusio_GetEncoder);
|
||||
RETURN_FALSE (i64, bnusio_GetCoinLock, u8 a1);
|
||||
RETURN_FALSE (i64, bnusio_SetCoinLock, u8 a1, u8 a2);
|
||||
RETURN_FALSE (i64, bnusio_GetCDOut, u8 a1);
|
||||
RETURN_FALSE (i64, bnusio_SetCDOut, u8 a1, u8 a2);
|
||||
RETURN_FALSE (i64, bnusio_GetHopOut, u8 a1);
|
||||
RETURN_FALSE (i64, bnusio_SetHopOut, u8 a1, u8 a2);
|
||||
RETURN_FALSE (void *, bnusio_SetPLCounter, i16 a1);
|
||||
RETURN_FALSE (char *, bnusio_GetIoBoardName);
|
||||
RETURN_FALSE (i64, bnusio_SetHopperRequest, u16 a1, i16 a2);
|
||||
RETURN_FALSE (i64, bnusio_SetHopperLimit, u16 a1, i16 a2);
|
||||
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 (void *, bnusio_GetCoinError, i32 a1);
|
||||
RETURN_FALSE (void *, bnusio_GetServiceError, i32 a1);
|
||||
RETURN_FALSE (i64, bnusio_DecCoin, i32 a1, u16 a2);
|
||||
RETURN_FALSE (i64, bnusio_DecService, i32 a1, u16 a2);
|
||||
RETURN_FALSE (i64, bnusio_ResetCoin);
|
||||
size_t
|
||||
bnusio_GetFirmwareVersion () {
|
||||
return 126;
|
||||
BNUSIO_EXPORT (i64, bnusio_Open) CALL_BNUSIO_FALSE (bnusio_Open)
|
||||
BNUSIO_EXPORT (i64, bnusio_Close) CALL_BNUSIO_FALSE (bnusio_Close)
|
||||
BNUSIO_EXPORT (i64, bnusio_Communication, i32 a1) CALL_BNUSIO_FALSE (bnusio_Communication, a1)
|
||||
BNUSIO_EXPORT (u8, bnusio_IsConnected) CALL_BNUSIO_FALSE (bnusio_IsConnected)
|
||||
BNUSIO_EXPORT (i32, bnusio_ResetIoBoard) CALL_BNUSIO_FALSE (bnusio_ResetIoBoard)
|
||||
BNUSIO_EXPORT (u16, bnusio_GetStatusU16, u16 a1) CALL_BNUSIO_FALSE (bnusio_GetStatusU16, a1)
|
||||
BNUSIO_EXPORT (u8, bnusio_GetStatusU8, u16 a1) CALL_BNUSIO_FALSE (bnusio_GetStatusU8, a1)
|
||||
BNUSIO_EXPORT (u16, bnusio_GetRegisterU16, i16 a1) CALL_BNUSIO_FALSE (bnusio_GetRegisterU16, a1)
|
||||
BNUSIO_EXPORT (u8, bnusio_GetRegisterU8, u16 a1) CALL_BNUSIO_FALSE (bnusio_GetRegisterU8, a1)
|
||||
BNUSIO_EXPORT (void *, bnusio_GetBuffer, u16 a1, i64 a2, i16 a3) CALL_BNUSIO_FALSE (bnusio_GetBuffer, a1, a2, a3)
|
||||
BNUSIO_EXPORT (i64, bnusio_SetRegisterU16, u16 a1, u16 a2) CALL_BNUSIO_FALSE (bnusio_SetRegisterU16, a1, a2)
|
||||
BNUSIO_EXPORT (i64, bnusio_SetRegisterU8, u16 a1, u8 a2) CALL_BNUSIO_FALSE (bnusio_SetRegisterU8, a1, a2)
|
||||
BNUSIO_EXPORT (i64, bnusio_SetBuffer, u16 a1, i32 a2, i16 a3) CALL_BNUSIO_FALSE (bnusio_SetBuffer, a1, a2, a3)
|
||||
BNUSIO_EXPORT (void *, bnusio_GetSystemError) CALL_BNUSIO_FALSE (bnusio_GetSystemError)
|
||||
BNUSIO_EXPORT (i64, bnusio_SetSystemError, i16 a1) CALL_BNUSIO_FALSE (bnusio_SetSystemError, a1)
|
||||
BNUSIO_EXPORT (i64, bnusio_ClearSram) CALL_BNUSIO_FALSE (bnusio_ClearSram)
|
||||
BNUSIO_EXPORT (void *, bnusio_GetExpansionMode) CALL_BNUSIO_FALSE (bnusio_GetExpansionMode)
|
||||
BNUSIO_EXPORT (i64, bnusio_SetExpansionMode, i16 a1) CALL_BNUSIO_FALSE (bnusio_SetExpansionMode, a1)
|
||||
BNUSIO_EXPORT (u8, bnusio_IsWideUsio) CALL_BNUSIO_FALSE (bnusio_IsWideUsio)
|
||||
BNUSIO_EXPORT (u64, bnusio_GetSwIn64) CALL_BNUSIO_FALSE (bnusio_GetSwIn64)
|
||||
BNUSIO_EXPORT (u8, bnusio_GetGout, u8 a1) CALL_BNUSIO_FALSE (bnusio_GetGout, a1)
|
||||
BNUSIO_EXPORT (i64, bnusio_SetGout, u8 a1, u8 a2) CALL_BNUSIO_FALSE (bnusio_SetGout, a1, a2)
|
||||
BNUSIO_EXPORT (u64, bnusio_GetEncoder) CALL_BNUSIO_FALSE (bnusio_GetEncoder)
|
||||
BNUSIO_EXPORT (i64, bnusio_GetCoinLock, u8 a1) CALL_BNUSIO_FALSE (bnusio_GetCoinLock, a1)
|
||||
BNUSIO_EXPORT (i64, bnusio_SetCoinLock, u8 a1, u8 a2) CALL_BNUSIO_FALSE (bnusio_SetCoinLock, a1, a2)
|
||||
BNUSIO_EXPORT (i64, bnusio_GetCDOut, u8 a1) CALL_BNUSIO_FALSE (bnusio_GetCDOut, a1)
|
||||
BNUSIO_EXPORT (i64, bnusio_SetCDOut, u8 a1, u8 a2) CALL_BNUSIO_FALSE (bnusio_SetCDOut, a1, a2)
|
||||
BNUSIO_EXPORT (i64, bnusio_GetHopOut, u8 a1) CALL_BNUSIO_FALSE (bnusio_GetHopOut, a1)
|
||||
BNUSIO_EXPORT (i64, bnusio_SetHopOut, u8 a1, u8 a2) CALL_BNUSIO_FALSE (bnusio_SetHopOut, a1, a2)
|
||||
BNUSIO_EXPORT (void *, bnusio_SetPLCounter, i16 a1) CALL_BNUSIO_FALSE (bnusio_SetPLCounter, a1)
|
||||
BNUSIO_EXPORT (char *, bnusio_GetIoBoardName) CALL_BNUSIO_FALSE (bnusio_GetIoBoardName)
|
||||
BNUSIO_EXPORT (i64, bnusio_SetHopperRequest, u16 a1, i16 a2) CALL_BNUSIO_FALSE (bnusio_SetHopperRequest, a1, a2)
|
||||
BNUSIO_EXPORT (i64, bnusio_SetHopperLimit, u16 a1, i16 a2) CALL_BNUSIO_FALSE (bnusio_SetHopperLimit, a1, a2)
|
||||
BNUSIO_EXPORT (i64, bnusio_SramRead, i32 a1, u8 a2, i32 a3, u16 a4) CALL_BNUSIO_FALSE (bnusio_SramRead, a1, a2, a3, a4)
|
||||
BNUSIO_EXPORT (i64, bnusio_SramWrite, i32 a1, u8 a2, i32 a3, u16 a4) CALL_BNUSIO_FALSE (bnusio_SramWrite, a1, a2, a3, a4)
|
||||
BNUSIO_EXPORT (void *, bnusio_GetCoinError, i32 a1) CALL_BNUSIO_FALSE (bnusio_GetCoinError, a1)
|
||||
BNUSIO_EXPORT (void *, bnusio_GetServiceError, i32 a1) CALL_BNUSIO_FALSE (bnusio_GetServiceError, a1)
|
||||
BNUSIO_EXPORT (i64, bnusio_DecCoin, i32 a1, u16 a2) CALL_BNUSIO_FALSE (bnusio_DecCoin, a1, a2)
|
||||
BNUSIO_EXPORT (i64, bnusio_DecService, i32 a1, u16 a2) CALL_BNUSIO_FALSE (bnusio_DecService, a1, a2)
|
||||
BNUSIO_EXPORT (i64, bnusio_ResetCoin) CALL_BNUSIO_FALSE (bnusio_ResetCoin)
|
||||
BNUSIO_EXPORT (size_t, bnusio_GetFirmwareVersion) {
|
||||
if (!emulateUsio && ori_bnusio_GetFirmwareVersion) return ori_bnusio_GetFirmwareVersion();
|
||||
else return 126;
|
||||
}
|
||||
|
||||
u32
|
||||
bnusio_GetSwIn () {
|
||||
BNUSIO_EXPORT (u32, bnusio_GetSwIn) {
|
||||
if (!emulateUsio && ori_bnusio_GetSwIn) return ori_bnusio_GetSwIn ();
|
||||
u32 sw = 0;
|
||||
sw |= static_cast<u32> (testEnabled) << 7;
|
||||
sw |= static_cast<u32> (IsButtonDown (DEBUG_ENTER)) << 9;
|
||||
@@ -130,91 +120,41 @@ bnusio_GetSwIn () {
|
||||
sw |= static_cast<u32> (IsButtonDown (SERVICE)) << 14;
|
||||
return sw;
|
||||
}
|
||||
BNUSIO_EXPORT (u16, bnusio_GetAnalogIn, const u8 which) {
|
||||
if (!emulateUsio && ori_bnusio_GetAnalogIn) return ori_bnusio_GetAnalogIn (which);
|
||||
if (analogMethod) return analogMethod (which);
|
||||
else return 0;
|
||||
}
|
||||
BNUSIO_EXPORT (u16, bnusio_GetCoin, i32 a1) {
|
||||
if (updateByCoin && a1 == 1) bnusio::Update ();
|
||||
if (!emulateUsio && ori_bnusio_GetCoin) return ori_bnusio_GetCoin (a1);
|
||||
return coin_count;
|
||||
}
|
||||
BNUSIO_EXPORT (u16, bnusio_GetService, i32 a1) {
|
||||
if (!emulateUsio && ori_bnusio_GetService) return ori_bnusio_GetService (a1);
|
||||
return service_count;
|
||||
}
|
||||
}
|
||||
|
||||
bool waitAll = false;
|
||||
short drumWaitPeriod = 4;
|
||||
bool analogInput = false;
|
||||
bool valueStates[] = {false, false, false, false, false, false, false, false};
|
||||
|
||||
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};
|
||||
|
||||
u8 cooldown[8] = { 0 };
|
||||
u16 buttonWaitPeriod[] = { 0, 0 };
|
||||
std::queue<u8> buttonQueue[] = { {}, {} };
|
||||
|
||||
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 (const u8 which) {
|
||||
// LogMessage (LogLevel::DEBUG, "GetAnalogIn p={}", which);
|
||||
if (analogMethod) return analogMethod (which);
|
||||
else return 0;
|
||||
}
|
||||
|
||||
u16 __fastcall bnusio_GetCoin (i32 a1) {
|
||||
// LogMessage (LogLevel::DEBUG, "GetCoin p={}", a1);
|
||||
if (updateByCoin && a1 == 1) bnusio::Update ();
|
||||
return coin_count;
|
||||
}
|
||||
u16 __fastcall bnusio_GetService (i32 a1) { return service_count; }
|
||||
}
|
||||
|
||||
FUNCTION_PTR (i64, bnusio_Open_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_Open"));
|
||||
FUNCTION_PTR (i64, bnusio_Close_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_Close"));
|
||||
FUNCTION_PTR (u64, bnusio_Communication_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_Communication"), i32);
|
||||
FUNCTION_PTR (u8, bnusio_IsConnected_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_IsConnected"));
|
||||
FUNCTION_PTR (i32, bnusio_ResetIoBoard_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_ResetIoBoard"));
|
||||
FUNCTION_PTR (u16, bnusio_GetStatusU16_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_GetStatusU16"), u16);
|
||||
FUNCTION_PTR (u8, bnusio_GetStatusU8_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_GetStatusU8"), u16);
|
||||
FUNCTION_PTR (u16, bnusio_GetRegisterU16_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_GetRegisterU16"), i16);
|
||||
FUNCTION_PTR (u8, bnusio_GetRegisterU8_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_GetRegisterU8"), i16);
|
||||
FUNCTION_PTR (void *, bnusio_GetBuffer_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_GetBuffer"), u16, i64, i16);
|
||||
FUNCTION_PTR (i64, bnusio_SetRegisterU16_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_SetRegisterU16"), u16, u16);
|
||||
FUNCTION_PTR (i64, bnusio_SetRegisterU8_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_SetRegisterU8"), u16, u8);
|
||||
FUNCTION_PTR (i64, bnusio_SetBuffer_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_SetBuffer"), u16, i32, i16);
|
||||
FUNCTION_PTR (void *, bnusio_GetSystemError_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_GetSystemError"));
|
||||
FUNCTION_PTR (i64, bnusio_SetSystemError_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_SetSystemError"), i16);
|
||||
FUNCTION_PTR (size_t, bnusio_GetFirmwareVersion_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_GetFirmwareVersion"));
|
||||
FUNCTION_PTR (i64, bnusio_ClearSram_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_ClearSram"));
|
||||
FUNCTION_PTR (void *, bnusio_GetExpansionMode_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_GetExpansionMode"));
|
||||
FUNCTION_PTR (i64, bnusio_SetExpansionMode_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_SetExpansionMode"), i16);
|
||||
FUNCTION_PTR (u8, bnusio_IsWideUsio_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_IsWideUsio"));
|
||||
FUNCTION_PTR (u32, bnusio_GetSwIn_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_GetSwIn"));
|
||||
FUNCTION_PTR (u64, bnusio_GetSwIn64_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_GetSwIn64"));
|
||||
FUNCTION_PTR (u16, bnusio_GetAnalogIn_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_GetAnalogIn"), u8);
|
||||
FUNCTION_PTR (u8, bnusio_GetGout_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_GetGout"), u8);
|
||||
FUNCTION_PTR (i64, bnusio_SetGout_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_SetGout"), u8, u8);
|
||||
FUNCTION_PTR (u64, bnusio_GetEncoder_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_GetEncoder"));
|
||||
FUNCTION_PTR (i64, bnusio_GetCoinLock_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_GetCoinLock"), u8);
|
||||
FUNCTION_PTR (i64, bnusio_SetCoinLock_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_SetCoinLock"), u8, u8);
|
||||
FUNCTION_PTR (i64, bnusio_GetCDOut_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_GetCDOut"), u8);
|
||||
FUNCTION_PTR (i64, bnusio_SetCDOut_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_SetCDOut"), u8, u8);
|
||||
FUNCTION_PTR (i64, bnusio_GetHopOut_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_GetHopOut"), u8);
|
||||
FUNCTION_PTR (i64, bnusio_SetHopOut_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_SetHopOut"), u8, u8);
|
||||
FUNCTION_PTR (void *, bnusio_SetPLCounter_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_SetPLCounter"), i16);
|
||||
FUNCTION_PTR (char *, bnusio_GetIoBoardName_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_GetIoBoardName"));
|
||||
FUNCTION_PTR (i64, bnusio_SetHopperRequest_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_SetHopperRequest"), u16, i16);
|
||||
FUNCTION_PTR (i64, bnusio_SetHopperLimit_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_SetHopperLimit"), u16, i16);
|
||||
FUNCTION_PTR (i64, bnusio_SramRead_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_SramRead"), i32, u8, i32, u16);
|
||||
FUNCTION_PTR (i64, bnusio_SramWrite_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_SramWrite"), i32, u8, i32, u16);
|
||||
FUNCTION_PTR (u16, bnusio_GetCoin_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_GetCoin"), i32);
|
||||
FUNCTION_PTR (void *, bnusio_GetCoinError_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_GetCoinError"), i32);
|
||||
FUNCTION_PTR (void *, bnusio_GetService_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_GetService"), i32);
|
||||
FUNCTION_PTR (void *, bnusio_GetServiceError_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_GetServiceError"), i32);
|
||||
FUNCTION_PTR (i64, bnusio_DecCoin_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_DecCoin"), i32, u16);
|
||||
FUNCTION_PTR (u64, bnusio_DecService_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_DecService"), i32, u16);
|
||||
FUNCTION_PTR (i64, bnusio_ResetCoin_Original, PROC_ADDRESS ("bnusio_original.dll", "bnusio_ResetCoin"));
|
||||
|
||||
u16 __fastcall
|
||||
AnalogInputAxis (const u8 which) {
|
||||
u16 analogIn = (u16)(32768 * ControllerAxisIsDown (analogBindings[which])) + 1;
|
||||
return analogIn > 100 ? analogIn : 0;
|
||||
}
|
||||
|
||||
bool waitAll = false;
|
||||
short drumWaitPeriod = 0;
|
||||
u16 buttonWaitPeriod[] = { 0, 0 };
|
||||
std::queue<u8> buttonQueue[] = { {}, {} };
|
||||
bool valueStates[] = {false, false, false, false, false, false, false, false};
|
||||
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 __fastcall
|
||||
AnalogInputWaitPeriod (const u8 which) {
|
||||
const auto button = analogButtons[which];
|
||||
@@ -245,6 +185,7 @@ AnalogInputWaitPeriod (const u8 which) {
|
||||
return analogValue;
|
||||
}
|
||||
|
||||
int cooldown[8] = { 0 };
|
||||
u8 blueCooldown = 1, redCooldown = 1;
|
||||
u16 __fastcall
|
||||
AnalogInputCooldown (const u8 which) {
|
||||
@@ -276,7 +217,7 @@ void
|
||||
Init () {
|
||||
SetKeyboardButtons ();
|
||||
|
||||
int fpsLimit = 120;
|
||||
int fpsLimit = 0;
|
||||
|
||||
const auto configPath = std::filesystem::current_path () / "config.toml";
|
||||
const std::unique_ptr<toml_table_t, void (*) (toml_table_t *)> config_ptr (openConfig (configPath), toml_free);
|
||||
@@ -287,11 +228,15 @@ Init () {
|
||||
analogInput = readConfigBool (controller, "analog_input", analogInput);
|
||||
globalKeyboard = readConfigBool (controller, "global_keyboard", globalKeyboard);
|
||||
}
|
||||
auto graphics = openConfigSection (config, "graphics");
|
||||
if (graphics) {
|
||||
fpsLimit = (int)readConfigInt (graphics, "fpslimit", fpsLimit);
|
||||
}
|
||||
// auto graphics = openConfigSection (config, "graphics");
|
||||
// if (graphics) {
|
||||
// fpsLimit = (int)readConfigInt (graphics, "fpslimit", fpsLimit);
|
||||
// }
|
||||
}
|
||||
updateByCoin = fpsLimit == 0;
|
||||
// if (updateByCoin) {
|
||||
// LogMessage (LogLevel::INFO, "fpsLimit is set to 0, bnusio::Update() will invoke in getCoin callback");
|
||||
// }
|
||||
|
||||
if (analogInput) {
|
||||
LogMessage (LogLevel::WARN, "[Analog Type] Axis: All the keyboard drum inputs have been disabled");
|
||||
@@ -307,10 +252,6 @@ Init () {
|
||||
analogMethod = AnalogInputSimple;
|
||||
}
|
||||
|
||||
updateByCoin = fpsLimit == 0;
|
||||
if (updateByCoin) {
|
||||
LogMessage (LogLevel::INFO, "fpsLimit is set to 0, bnusio::Update() will invoke in getCoin callback");
|
||||
}
|
||||
const auto keyConfigPath = std::filesystem::current_path () / "keyconfig.toml";
|
||||
const std::unique_ptr<toml_table_t, void (*) (toml_table_t *)> keyConfig_ptr (openConfig (keyConfigPath), toml_free);
|
||||
if (keyConfig_ptr) {
|
||||
@@ -341,7 +282,7 @@ Init () {
|
||||
SetConfigValue (keyConfig, "P2_RIGHT_BLUE", &P2_RIGHT_BLUE, &inputState);
|
||||
}
|
||||
|
||||
LogMessage (LogLevel::INFO, "Finish Loading keyconfig.toml useKeyboard={} useMouse={} useController={}",
|
||||
LogMessage (LogLevel::INFO, "Finish Loading keyconfig.toml useKeyboard={} useMouse={} useController={}",
|
||||
(inputState & 1) ? "true" : "false", (inputState & (1 << 1)) ? "true" : "false", (inputState & (1 << 2)) ? "true" : "false");
|
||||
|
||||
if (!emulateUsio && !exists (std::filesystem::current_path () / "bnusio_original.dll")) {
|
||||
@@ -349,52 +290,7 @@ Init () {
|
||||
LogMessage (LogLevel::ERROR, "bnusio_original.dll not found! usio emulation enabled");
|
||||
}
|
||||
|
||||
if (!emulateUsio) {
|
||||
INSTALL_HOOK_DIRECT (bnusio_Open, bnusio_Open_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_Close, bnusio_Close_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_Communication, bnusio_Communication_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_IsConnected, bnusio_IsConnected_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_ResetIoBoard, bnusio_ResetIoBoard_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_GetStatusU16, bnusio_GetStatusU16_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_GetStatusU8, bnusio_GetStatusU8_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_GetRegisterU16, bnusio_GetRegisterU16_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_GetRegisterU8, bnusio_GetRegisterU8_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_GetBuffer, bnusio_GetBuffer_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_SetRegisterU16, bnusio_SetRegisterU16_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_SetRegisterU8, bnusio_SetRegisterU8_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_SetBuffer, bnusio_SetBuffer_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_GetSystemError, bnusio_GetSystemError_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_SetSystemError, bnusio_SetSystemError_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_GetFirmwareVersion, bnusio_GetFirmwareVersion_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_ClearSram, bnusio_ClearSram_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_GetExpansionMode, bnusio_GetExpansionMode_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_SetExpansionMode, bnusio_SetExpansionMode_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_IsWideUsio, bnusio_IsWideUsio_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_GetSwIn, bnusio_GetSwIn_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_GetSwIn64, bnusio_GetSwIn64_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_GetAnalogIn, bnusio_GetAnalogIn_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_GetGout, bnusio_GetGout_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_SetGout, bnusio_SetGout_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_GetEncoder, bnusio_GetEncoder_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_GetCoinLock, bnusio_GetCoinLock_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_SetCoinLock, bnusio_SetCoinLock_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_GetCDOut, bnusio_GetCDOut_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_SetCDOut, bnusio_SetCDOut_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_GetHopOut, bnusio_GetHopOut_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_SetHopOut, bnusio_SetHopOut_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_SetPLCounter, bnusio_SetPLCounter_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_GetIoBoardName, bnusio_GetIoBoardName_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_SetHopperRequest, bnusio_SetHopperRequest_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_SetHopperLimit, bnusio_SetHopperLimit_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_SramRead, bnusio_SramRead_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_SramWrite, bnusio_SramWrite_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_GetCoin, bnusio_GetCoin_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_GetCoinError, bnusio_GetCoinError_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_GetService, bnusio_GetService_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_GetServiceError, bnusio_GetServiceError_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_DecCoin, bnusio_DecCoin_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_DecService, bnusio_DecService_Original);
|
||||
INSTALL_HOOK_DIRECT (bnusio_ResetCoin, bnusio_ResetCoin_Original);
|
||||
if (!emulateUsio && bnusioOriginal) {
|
||||
LogMessage (LogLevel::WARN, "USIO emulation disabled");
|
||||
}
|
||||
}
|
||||
@@ -405,11 +301,6 @@ Update () {
|
||||
if (!inited) {
|
||||
windowHandle = FindWindowA ("nuFoundation.Window", nullptr);
|
||||
InitializePoll (windowHandle);
|
||||
if (autoIme) {
|
||||
currentLayout = GetKeyboardLayout (0);
|
||||
auto engLayout = LoadKeyboardLayout (TEXT ("00000409"), KLF_ACTIVATE);
|
||||
ActivateKeyboardLayout (engLayout, KLF_SETFORPROCESS);
|
||||
}
|
||||
patches::Plugins::Init ();
|
||||
inited = true;
|
||||
}
|
||||
@@ -439,7 +330,6 @@ Update () {
|
||||
|
||||
void
|
||||
Close () {
|
||||
if (autoIme) ActivateKeyboardLayout (currentLayout, KLF_SETFORPROCESS);
|
||||
// patches::Plugins::Exit ();
|
||||
CleanupLogger ();
|
||||
}
|
||||
|
||||
+76
-7
@@ -24,13 +24,17 @@ char accessCode2[21] = "00000000000000000002";
|
||||
char chipId1[33] = "00000000000000000000000000000001";
|
||||
char chipId2[33] = "00000000000000000000000000000002";
|
||||
bool windowed = false;
|
||||
bool autoIme = false;
|
||||
bool autoIme = true;
|
||||
bool jpLayout = false;
|
||||
bool cursor = true;
|
||||
bool emulateUsio = true;
|
||||
bool emulateCardReader = true;
|
||||
bool emulateQr = true;
|
||||
bool acceptInvalidCards = false;
|
||||
HKL currentLayout = nullptr;
|
||||
i32 xRes = 1920;
|
||||
i32 yRes = 1080;
|
||||
bool vsync = false;
|
||||
|
||||
std::string logLevelStr = "INFO";
|
||||
bool logToFile = true;
|
||||
@@ -39,6 +43,22 @@ std::string logPath = "TaikoArcadeLoader.log";
|
||||
HWND hGameWnd;
|
||||
FAST_HOOK (i32, ShowMouse, PROC_ADDRESS ("user32.dll", "ShowCursor"), bool) { return originalShowMouse.stdcall<i32> (true); }
|
||||
FAST_HOOK (i32, ExitWindows, PROC_ADDRESS ("user32.dll", "ExitWindowsEx")) { ExitProcess (0); }
|
||||
// FAST_HOOK (ATOM, HookRegisterClassA, PROC_ADDRESS ("winuser.h", "RegisterClassA"), WNDCLASSA *lpWndClass) {
|
||||
// LogMessage (LogLevel::DEBUG, "RegisterClassA name={}", lpWndClass->lpszClassName);
|
||||
// return originalHookRegisterClassA.call<ATOM> (lpWndClass);
|
||||
// }
|
||||
// FAST_HOOK (ATOM, HookRegisterClassW, PROC_ADDRESS ("winuser.h", "RegisterClassW"), WNDCLASSW *lpWndClass) {
|
||||
// LogMessage (LogLevel::DEBUG, L"RegisterClassW name={}", lpWndClass->lpszClassName);
|
||||
// return originalHookRegisterClassW.call<ATOM> (lpWndClass);
|
||||
// }
|
||||
// FAST_HOOK (ATOM, HookRegisterClassExA, PROC_ADDRESS ("winuser.h", "RegisterClassExA"), WNDCLASSEXA *lpWndClass) {
|
||||
// LogMessage (LogLevel::DEBUG, "RegisterClassExA name={}", lpWndClass->lpszClassName);
|
||||
// return originalHookRegisterClassExA.call<ATOM> (lpWndClass);
|
||||
// }
|
||||
// FAST_HOOK (ATOM, HookRegisterClassExW, PROC_ADDRESS ("winuser.h", "RegisterClassExW"), WNDCLASSEXW *lpWndClass) {
|
||||
// LogMessage (LogLevel::DEBUG, L"RegisterClassExW name={}", lpWndClass->lpszClassName);
|
||||
// return originalHookRegisterClassExW.call<ATOM> (lpWndClass);
|
||||
// }
|
||||
FAST_HOOK (HWND, CreateWindow, PROC_ADDRESS ("user32.dll", "CreateWindowExW"), DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName, DWORD dwStyle,
|
||||
i32 X, i32 Y, i32 nWidth, i32 nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam) {
|
||||
if (lpWindowName != nullptr) {
|
||||
@@ -152,10 +172,6 @@ DllMain (HMODULE module, const DWORD reason, LPVOID reserved) {
|
||||
InitializeLogger (GetLogLevel (logLevelStr), logToFile, logPath);
|
||||
patches::Timer::Init ();
|
||||
|
||||
// #ifdef ASYNC_IO
|
||||
// InitializeKeyboard ();
|
||||
// #endif
|
||||
|
||||
LogMessage (LogLevel::INFO, "Loading config...");
|
||||
|
||||
std::string version = "auto";
|
||||
@@ -190,6 +206,11 @@ DllMain (HMODULE module, const DWORD reason, LPVOID reserved) {
|
||||
if (const auto graphics = openConfigSection (config, "graphics")) {
|
||||
windowed = readConfigBool (graphics, "windowed", windowed);
|
||||
cursor = readConfigBool (graphics, "cursor", cursor);
|
||||
if (auto res = openConfigSection (graphics, "res")) {
|
||||
xRes = static_cast<i32> (readConfigInt (res, "x", xRes));
|
||||
yRes = static_cast<i32> (readConfigInt (res, "y", yRes));
|
||||
}
|
||||
vsync = readConfigBool (graphics, "vsync", vsync);
|
||||
}
|
||||
if (const auto keyboard = openConfigSection (config, "keyboard")) {
|
||||
autoIme = readConfigBool (keyboard, "auto_ime", autoIme);
|
||||
@@ -203,6 +224,49 @@ DllMain (HMODULE module, const DWORD reason, LPVOID reserved) {
|
||||
}
|
||||
}
|
||||
|
||||
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_UNAWARE);
|
||||
auto activeWindow = GetActiveWindow();
|
||||
HMONITOR monitor = MonitorFromWindow(activeWindow, MONITOR_DEFAULTTONEAREST);
|
||||
|
||||
// Get the logical width and height of the monitor
|
||||
MONITORINFOEX monitorInfoEx;
|
||||
monitorInfoEx.cbSize = sizeof(monitorInfoEx);
|
||||
GetMonitorInfo(monitor, &monitorInfoEx);
|
||||
auto cxLogical = monitorInfoEx.rcMonitor.right - monitorInfoEx.rcMonitor.left;
|
||||
auto cyLogical = monitorInfoEx.rcMonitor.bottom - monitorInfoEx.rcMonitor.top;
|
||||
|
||||
// Get the physical width and height of the monitor
|
||||
DEVMODE devMode;
|
||||
devMode.dmSize = sizeof(devMode);
|
||||
devMode.dmDriverExtra = 0;
|
||||
EnumDisplaySettings(monitorInfoEx.szDevice, ENUM_CURRENT_SETTINGS, &devMode);
|
||||
auto cxPhysical = devMode.dmPelsWidth;
|
||||
auto cyPhysical = devMode.dmPelsHeight;
|
||||
|
||||
// Calculate the scaling factor
|
||||
auto horizontalScale = (static_cast<double> (cxPhysical) / static_cast<double> (cxLogical));
|
||||
auto verticalScale = (static_cast<double> (cyPhysical) / static_cast<double> (cyLogical));
|
||||
if (windowed) {
|
||||
// Game will automatically adjust scale
|
||||
xRes = (int)(xRes / horizontalScale);
|
||||
yRes = (int)(yRes / verticalScale);
|
||||
} else {
|
||||
xRes = cxLogical;
|
||||
yRes = cyLogical;
|
||||
if (yRes * 16 > xRes * 9) yRes = (int)(xRes * 9.0 / 16.0);
|
||||
else if (yRes * 16 < xRes * 9) xRes = (int)(yRes * 16.0 / 9.0);
|
||||
}
|
||||
|
||||
LogMessage (LogLevel::INFO, "Scale Rate: x={} y={}", horizontalScale, verticalScale);
|
||||
LogMessage (LogLevel::INFO, "Boot with {} mode ({}x{})", windowed ? "window" : "fullscreen", xRes, yRes);
|
||||
|
||||
if (autoIme) {
|
||||
currentLayout = GetKeyboardLayout (0);
|
||||
auto engLayout = LoadKeyboardLayout (TEXT ("00000409"), KLF_ACTIVATE);
|
||||
ActivateKeyboardLayout (engLayout, KLF_SETFORPROCESS);
|
||||
LogMessage (LogLevel::DEBUG, "Initial change KeyboardLayout {}", LOWORD(engLayout));
|
||||
}
|
||||
|
||||
// Update the logger with the level read from config file.
|
||||
InitializeLogger (GetLogLevel (logLevelStr), logToFile, logPath);
|
||||
LogMessage (LogLevel::INFO, "Application started.");
|
||||
@@ -235,9 +299,13 @@ DllMain (HMODULE module, const DWORD reason, LPVOID reserved) {
|
||||
|
||||
LogMessage (LogLevel::INFO, "==== Loading patches, please wait...");
|
||||
|
||||
if (cursor) INSTALL_FAST_HOOK (ShowMouse);
|
||||
if (windowed && cursor) INSTALL_FAST_HOOK (ShowMouse);
|
||||
INSTALL_FAST_HOOK (ExitWindows);
|
||||
INSTALL_FAST_HOOK (CreateWindow);
|
||||
// INSTALL_FAST_HOOK (HookRegisterClassA);
|
||||
// INSTALL_FAST_HOOK (HookRegisterClassW);
|
||||
// INSTALL_FAST_HOOK (HookRegisterClassExA);
|
||||
// INSTALL_FAST_HOOK (HookRegisterClassExW);
|
||||
INSTALL_FAST_HOOK (SetWindowPosition);
|
||||
|
||||
INSTALL_FAST_HOOK (ExitProcessHook);
|
||||
@@ -266,11 +334,12 @@ DllMain (HMODULE module, const DWORD reason, LPVOID reserved) {
|
||||
|
||||
patches::Scanner::Init ();
|
||||
patches::Audio::Init ();
|
||||
patches::Dxgi::Init ();
|
||||
// patches::Dxgi::Init ();
|
||||
patches::AmAuth::Init ();
|
||||
patches::Language::Init ();
|
||||
patches::TestMode::Init ();
|
||||
patches::LayeredFs::Init ();
|
||||
// patches::UnlimitSong::Init ();
|
||||
|
||||
std::chrono::duration<double> duration = std::chrono::high_resolution_clock::now() - start;
|
||||
LogMessage (LogLevel::INFO, "==== Finished Loading patches! using: {:.2f}ms", duration.count () * 1000);
|
||||
|
||||
+11
-1
@@ -73,6 +73,16 @@ readConfigInt (const toml_table_t *table, const std::string &key, const i64 notF
|
||||
return u.i;
|
||||
}
|
||||
|
||||
double
|
||||
readConfigDouble (const toml_table_t *table, const std::string &key, const double notFoundValue) {
|
||||
const auto [ok, u] = toml_double_in (table, key.c_str ());
|
||||
if (!ok) {
|
||||
LogMessage (LogLevel::WARN, ("Could not find Int named " + key).c_str ());
|
||||
return notFoundValue;
|
||||
}
|
||||
return u.d;
|
||||
}
|
||||
|
||||
std::string
|
||||
readConfigString (const toml_table_t *table, const std::string &key, const std::string ¬FoundValue) {
|
||||
const auto [ok, u] = toml_string_in (table, key.c_str ());
|
||||
@@ -184,7 +194,7 @@ AreAllBytesZero (const u8 *array, const size_t offset, const size_t length) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
withFile (const char *fileName, std::function<void (u8 *)> callback) {
|
||||
FILE *file = fopen (fileName, "rb");
|
||||
if (file == nullptr) return;
|
||||
|
||||
+1
-44
@@ -128,50 +128,6 @@ const HMODULE MODULE_HANDLE = GetModuleHandle (nullptr);
|
||||
original##functionName = safetyhook::create_inline ((void *)location, (void*)implOf##functionName); \
|
||||
}
|
||||
|
||||
inline bool sendFlag = false;
|
||||
#define SCENE_RESULT_HOOK(functionName, location) \
|
||||
FAST_HOOK (void, functionName, location, i64 a1, i64 a2, i64 a3) { \
|
||||
if (TestMode::ReadTestModeValue (L"ModInstantResult") != 1 && TestMode::ReadTestModeValue (L"NumberOfStageItem") <= 4) { \
|
||||
original##functionName.fastcall (a1, a2, a3); \
|
||||
return; \
|
||||
} \
|
||||
sendFlag = true; \
|
||||
original##functionName.fastcall (a1, a2, a3); \
|
||||
ExecuteSendResultData (); \
|
||||
}
|
||||
|
||||
#define SEND_RESULT_HOOK(functionName, location) \
|
||||
FAST_HOOK (void, functionName, location, i64 a1) { \
|
||||
if (TestMode::ReadTestModeValue (L"ModInstantResult") != 1 && TestMode::ReadTestModeValue (L"NumberOfStageItem") <= 4) { \
|
||||
original##functionName.fastcall (a1); \
|
||||
return; \
|
||||
} \
|
||||
if (sendFlag) { \
|
||||
sendFlag = false; \
|
||||
original##functionName.fastcall (a1); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CHANGE_RESULT_SIZE_HOOK(functionName, location, target) \
|
||||
MID_HOOK (functionName, location, SafetyHookContext &ctx) { \
|
||||
if (TestMode::ReadTestModeValue (L"ModInstantResult") != 1 && TestMode::ReadTestModeValue (L"NumberOfStageItem") <= 4) { return; } \
|
||||
i64 instance = RefPlayDataManager (*(i64 *)ctx.r12); \
|
||||
u32 currentStageCount = *(u32 *)(instance + 8); \
|
||||
ctx.target &= 0xFFFFFFFF00000000; \
|
||||
ctx.target |= currentStageCount; \
|
||||
}
|
||||
|
||||
#define CHANGE_RESULT_INDEX_HOOK(functionName, location, target, offset, skip) \
|
||||
MID_HOOK (functionName, location, SafetyHookContext &ctx) { \
|
||||
if (TestMode::ReadTestModeValue (L"ModInstantResult") != 1 && TestMode::ReadTestModeValue (L"NumberOfStageItem") <= 4) { return; } \
|
||||
i64 instance = RefPlayDataManager (*(i64 *)ctx.r12); \
|
||||
u32 currentStageCount = *(u32 *)(instance + 8); \
|
||||
ctx.target &= 0xFFFFFFFF00000000; \
|
||||
ctx.target |= currentStageCount - 1; \
|
||||
*(u32 *)(ctx.rsp + offset) = currentStageCount - 1; \
|
||||
ctx.rip += skip; \
|
||||
}
|
||||
|
||||
#define READ_MEMORY(location, type) *(type *)location
|
||||
|
||||
#define WRITE_MEMORY(location, type, ...) \
|
||||
@@ -216,6 +172,7 @@ toml_table_t *openConfig (const std::filesystem::path &path);
|
||||
toml_table_t *openConfigSection (const toml_table_t *config, const std::string §ionName);
|
||||
bool readConfigBool (const toml_table_t *table, const std::string &key, bool notFoundValue);
|
||||
i64 readConfigInt (const toml_table_t *table, const std::string &key, i64 notFoundValue);
|
||||
double readConfigDouble (const toml_table_t *table, const std::string &key, const double notFoundValue);
|
||||
std::string readConfigString (const toml_table_t *table, const std::string &key, const std::string ¬FoundValue);
|
||||
std::vector<i64> readConfigIntArray (const toml_table_t *table, const std::string &key, std::vector<i64> notFoundValue);
|
||||
std::wstring replace (const std::wstring orignStr, const std::wstring &oldStr, const std::wstring &newStr);
|
||||
|
||||
@@ -121,8 +121,7 @@ typedef struct amcus_state {
|
||||
/* Offset: 8 */ i32 allnet_auth_state;
|
||||
/* Offset: 12 */ i32 allnet_auth_count;
|
||||
/* Offset: 16 */ i32 allnet_last_error;
|
||||
/* Offset: 24 */
|
||||
mucha_state mucha_state;
|
||||
/* Offset: 24 */ mucha_state mucha_state;
|
||||
/* Offset: 176 */ i64 clock_status;
|
||||
/* Offset: 184 */ i64 name_resolution_timeout;
|
||||
/* Offset: 192 */ /* ENUM32 */ u32 auth_type;
|
||||
|
||||
+69
-52
@@ -9,6 +9,7 @@ namespace patches::Language {
|
||||
const std::vector<std::string> languages = { "jpn", "en_us", "cn_tw", "kor", "cn_cn" };
|
||||
std::vector<SafetyHookMid> language_patch = { };
|
||||
boolean cnFontPatches = false;
|
||||
// TestMode::Value *languageItem = TestMode::CreateValue (L"LanguageItem");
|
||||
int language = 0;
|
||||
|
||||
FUNCTION_PTR (void, lua_settop, PROC_ADDRESS ("lua51.dll", "lua_settop"), i64, i32);
|
||||
@@ -40,7 +41,7 @@ typedef struct {
|
||||
void *languageData = nullptr;
|
||||
const size_t languageOffset = languages.size () * 560;
|
||||
// jp_64, jp_30, jp_32, en_64, en_30, en_32, tw_64, tw_30, tw_32, ko_64, ko_30, ko_32, cn_64, cn_30, cn_32
|
||||
const float upA[15] = { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
const float upA[15] = { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
const float upB[15] = { -0.265625f, 0.15f, 0.078125f, -0.21875f, 0.2329999f, 0.140625f, -0.0625f, 0.333f, 0.28125f, -0.109375f, 0.333f, 0.28125f, -0.09375f, 0.30000001f, 0.25f };
|
||||
const float downA[15] = { -0.25f, 0.167f, 0.125f, -0.21875f, 0.233f, 0.140625f, -0.0625f, 0.333f, 0.25f, -0.125f, 0.333f, 0.28125f, -0.09375f, 0.30000001f, 0.25f };
|
||||
const float downB[15] = { 50.5f, 10.0f, 13.0f, 46.0f, 8.0f, 11.5f, 36.0f, 5.0f, 7.0f, 39.0f, 5.0f, 7.0f, 38.0f, 6.0f, 8.0f };
|
||||
@@ -77,7 +78,7 @@ FAST_HOOK_DYNAMIC (int, initial_load_setting) {
|
||||
*(u32 *)(basicOffset + 0x68) = lang == 0 ? 0 : (3 * lang + shapeIndex + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -101,7 +102,7 @@ void
|
||||
Init () {
|
||||
bool fontExistAll = true;
|
||||
const char *fontToCheck[]{
|
||||
"cn_30.nutexb", "cn_30.xml", "cn_32_EB.nutexb", "cn_32_EB.xml", "cn_32_B.nutexb",
|
||||
"cn_30.nutexb", "cn_30.xml", "cn_32_EB.nutexb", "cn_32_EB.xml", "cn_32_B.nutexb",
|
||||
"cn_32_B.xml", "cn_32_DB.nutexb", "cn_32_DB.xml", "cn_64.nutexb", "cn_64.xml"
|
||||
};
|
||||
for (int i = 0; i < 6; i++) {
|
||||
@@ -122,7 +123,7 @@ Init () {
|
||||
node.attribute (L"max").set_value (L"4");
|
||||
node.attribute (L"replace-text").set_value (L"0:JPN, 1:ENG, 2:zh-tw, 3:KOR, 4:zh-cn");
|
||||
}, [&](){
|
||||
// load_setting
|
||||
// load_setting
|
||||
INSTALL_FAST_HOOK_DYNAMIC (initial_load_setting, ASLR (0x14001B010));
|
||||
// SceneBoot::LoadFont
|
||||
language_patch.push_back (safetyhook::create_mid (ASLR (0x140464235), [](SafetyHookContext &ctx){
|
||||
@@ -130,12 +131,12 @@ Init () {
|
||||
ctx.rax = (uintptr_t)languageData;
|
||||
ctx.rip = ASLR (0x140464243);
|
||||
}));
|
||||
language_patch.push_back (safetyhook::create_mid (ASLR (0x14046426C), [](SafetyHookContext &ctx){
|
||||
language_patch.push_back (safetyhook::create_mid (ASLR (0x14046426C), [](SafetyHookContext &ctx){
|
||||
ctx.r15 = ctx.rbp + languageOffset;
|
||||
ctx.rip = ASLR (0x140464273);
|
||||
}));
|
||||
// SceneBoot::SetFontShift
|
||||
language_patch.push_back (safetyhook::create_mid (ASLR (0x1404644AF), [](SafetyHookContext &ctx){
|
||||
language_patch.push_back (safetyhook::create_mid (ASLR (0x1404644AF), [](SafetyHookContext &ctx){
|
||||
ctx.rdi = ctx.rcx * languageOffset;
|
||||
ctx.rax = (uintptr_t)languageData;
|
||||
ctx.rdi += ctx.rax;
|
||||
@@ -202,7 +203,7 @@ MID_HOOK_DYNAMIC (WordlistLanguageType, SafetyHookContext &ctx) {
|
||||
u64 *data = jsonGetMember (json, languageTexts[0].c_str ());
|
||||
if ((*((u16 *)data + 7) & 0x1000) == 0) data = (u64 *)(data[1] & 0xFFFFFFFFFFFF);
|
||||
taiko_assign ((void *)(ctx.rsp + 0x60), (char *)data, strlen ((char *)data));
|
||||
} else taiko_assign ((void *)(ctx.rsp + 0x60), "", 0);
|
||||
} else taiko_assign ((void *)(ctx.rsp + 0x60), "", 0);
|
||||
|
||||
if (fallback != -1) {
|
||||
if (jsonHasMember (json, languageFontTypes[fallback].c_str ())) {
|
||||
@@ -359,24 +360,17 @@ MID_HOOK_DYNAMIC (ChangeOnpFile, SafetyHookContext &ctx) {
|
||||
ctx.rdx = (uintptr_t) onpCn.c_str ();
|
||||
ctx.r8 = 0x1F;
|
||||
}
|
||||
void *
|
||||
GetLanguageType (Taiko_assign assign, int language, void *buf) {
|
||||
int langFix = languageFix (language);
|
||||
return assign (buf, languageStr (langFix), (langFix == 0 || langFix == 3) ? 3 : 5);
|
||||
}
|
||||
void
|
||||
InjectLanguageType (uintptr_t language, uintptr_t ®) {
|
||||
int langFix = languageFix ((int)language);
|
||||
reg = (uintptr_t)languageStr (langFix);
|
||||
}
|
||||
|
||||
FAST_HOOK_DYNAMIC (u64, GraphicBaseGetLanguageType, u64 a1, void *a2) {
|
||||
int language = *(int *)(a1 + 56);
|
||||
return (u64)GetLanguageType (taiko_assign, language, a2);
|
||||
}
|
||||
|
||||
std::string *season_nulm = nullptr;
|
||||
std::string *season_nutexb = nullptr;
|
||||
bool titleExistSeason = true, titleExistMaid = true, titleExistMaidCn = true;
|
||||
std::string seasonNulm = "title_season.nulm", seasonNutexb = "title_" + season () + ".nutexb";
|
||||
std::string maidNulmCn = "title_maid.nulm", maidNutexbCn = "title_maid.nutexb";
|
||||
std::string maidNulm = "title_maid.nulm", maidNutexb = "title_maid.nutexb";
|
||||
TestMode::Value *titleScreen = TestMode::CreateValue (L"ModTitleScreen");
|
||||
void
|
||||
Init () {
|
||||
switch (gameVersion) {
|
||||
@@ -399,55 +393,78 @@ Init () {
|
||||
LogMessage (LogLevel::INFO, "Detected onpu_cn files, install onp patches!");
|
||||
INSTALL_MID_HOOK_DYNAMIC (ChangeOnpFile, ASLR (0x140134D16));
|
||||
}
|
||||
language_patch.push_back (safetyhook::create_mid (ASLR (0x140134E22), [](SafetyHookContext &ctx){
|
||||
language_patch.push_back (safetyhook::create_mid (ASLR (0x140134E22), [](SafetyHookContext &ctx){
|
||||
if (ctx.rcx == 4) *(int *)(ctx.r15 + 0x3100) = 2;
|
||||
else *(int *)(ctx.r15 + 0x3100) = (int)ctx.rcx;
|
||||
ctx.rip = ASLR (0x140134E29);
|
||||
}));
|
||||
|
||||
INSTALL_FAST_HOOK_DYNAMIC (GraphicBaseGetLanguageType, ASLR (0x1400E8740));
|
||||
language_patch.push_back (safetyhook::create_mid (ASLR (0x1400E8791), [](SafetyHookContext &ctx)
|
||||
{ InjectLanguageType (ctx.rsp + 0x58 + ctx.rax * 8, ctx.rdx); ctx.rip = ASLR (0x1400E8796); })); // HitEffectGetLanguageType
|
||||
{ InjectLanguageType (ctx.rax, ctx.rdx); ctx.rip = ASLR (0x1400E8796); })); // HitEffectGetLanguageType
|
||||
language_patch.push_back (safetyhook::create_mid (ASLR (0x14011F8E4), [](SafetyHookContext &ctx)
|
||||
{ InjectLanguageType (ctx.rbp + 0x57 + ctx.rax * 8, ctx.rdx); ctx.rip = ASLR (0x14011F8E9); })); // KusudamaGetLanguageType
|
||||
{ InjectLanguageType (ctx.rax, ctx.rdx); ctx.rip = ASLR (0x14011F8E9); })); // KusudamaGetLanguageType
|
||||
language_patch.push_back (safetyhook::create_mid (ASLR (0x140122404), [](SafetyHookContext &ctx)
|
||||
{ InjectLanguageType (ctx.rbp + 0x140 + ctx.rax * 8, ctx.rdx); ctx.rip = ASLR (0x14012240C); })); // NoteJumpGetLanguageType
|
||||
{ InjectLanguageType (ctx.rax, ctx.rdx); ctx.rip = ASLR (0x14012240C); })); // NoteJumpGetLanguageType
|
||||
language_patch.push_back (safetyhook::create_mid (ASLR (0x14012425E), [](SafetyHookContext &ctx)
|
||||
{ InjectLanguageType (ctx.rbp + 0x57 + ctx.rax * 8, ctx.rdx); ctx.rip = ASLR (0x140124263); })); // RendaEffectGetLanguageType
|
||||
{ InjectLanguageType (ctx.rax, ctx.rdx); ctx.rip = ASLR (0x140124263); })); // RendaEffectGetLanguageType
|
||||
language_patch.push_back (safetyhook::create_mid (ASLR (0x140129450), [](SafetyHookContext &ctx)
|
||||
{ InjectLanguageType (ctx.rbp + 0x57 + ctx.rax * 8, ctx.rdx); ctx.rip = ASLR (0x140129455); })); // RendaEffectGetLanguageType
|
||||
{ InjectLanguageType (ctx.rax, ctx.rdx); ctx.rip = ASLR (0x140129455); })); // RendaEffectGetLanguageType
|
||||
language_patch.push_back (safetyhook::create_mid (ASLR (0x14012B8C8), [](SafetyHookContext &ctx)
|
||||
{ InjectLanguageType (ctx.rbp + 0x180 + ctx.rax * 8, ctx.rdx); ctx.rip = ASLR (0x14012B8D0); })); // ScoreGetLanguageType
|
||||
{ InjectLanguageType (ctx.rax, ctx.rdx); ctx.rip = ASLR (0x14012B8D0); })); // ScoreGetLanguageType
|
||||
LayeredFs::RegisterBefore ([&] (const std::string &originalFileName, const std::string ¤tFileName) -> std::string {
|
||||
if (language != 4 || currentFileName.starts_with ("F:\\") || currentFileName.find ("\\lumen\\") == std::string::npos) return "";
|
||||
if (language != 4 || currentFileName.starts_with ("F:\\lumen\\") || currentFileName.find ("\\lumen\\") == std::string::npos) return "";
|
||||
std::string fileName = std::string (currentFileName);
|
||||
fileName = replace (fileName, "\\lumen\\", "\\lumen_cn\\");
|
||||
if (std::filesystem::exists (fileName)) return fileName;
|
||||
return "";
|
||||
});
|
||||
|
||||
LayeredFs::RegisterBefore ([&] (const std::string &originalFileName, const std::string ¤tFileName) -> std::string {
|
||||
if (language != 4 || currentFileName.starts_with ("F:\\")) return "";
|
||||
if (currentFileName.ends_with ("title.nulm")) {
|
||||
std::string fileName = std::string (currentFileName);
|
||||
if (season_nulm == nullptr) {
|
||||
fileName = replace (fileName, "title.nulm", "title_season.nulm");
|
||||
if (std::filesystem::exists (fileName)) {
|
||||
std::string nutexb = std::string (currentFileName);
|
||||
nutexb = replace (nutexb, "title.nulm", "title_" + season () + ".nutexb");
|
||||
if (std::filesystem::exists (nutexb)) {
|
||||
season_nulm = new std::string (fileName), season_nutexb = new std::string (nutexb);
|
||||
return *season_nulm;
|
||||
}
|
||||
}
|
||||
season_nulm = new std::string (""), season_nutexb = new std::string ("");
|
||||
return "";
|
||||
} else return *season_nulm;
|
||||
} else if (currentFileName.ends_with ("title.nutexb") && season_nutexb != nullptr) {
|
||||
return *season_nutexb;
|
||||
} else return "";
|
||||
});
|
||||
|
||||
std::string base[] = {"..\\..\\Data\\x64\\lumen\\000_default\\attract\\", "..\\..\\Data_mods\\x64\\lumen\\000_default\\attract\\"};
|
||||
std::string baseCn[] = {"..\\..\\Data\\x64\\lumen_cn\\000_default\\attract\\", "..\\..\\Data_mods\\x64\\lumen_cn\\000_default\\attract\\"};
|
||||
for (std::string prefix : baseCn) {
|
||||
if (!seasonNulm.starts_with ("..\\") && std::filesystem::exists (prefix + seasonNulm)) seasonNulm = prefix + seasonNulm;
|
||||
if (!seasonNutexb.starts_with ("..\\") && std::filesystem::exists (prefix + seasonNutexb)) seasonNutexb = prefix + seasonNutexb;
|
||||
}
|
||||
if (!seasonNulm.starts_with ("..\\") || !seasonNutexb.starts_with ("..\\")) titleExistSeason = false;
|
||||
for (std::string prefix : baseCn) {
|
||||
if (!maidNulmCn.starts_with ("..\\") && std::filesystem::exists (prefix + maidNulmCn)) maidNulmCn = prefix + maidNulmCn;
|
||||
if (!maidNutexbCn.starts_with ("..\\") && std::filesystem::exists (prefix + maidNutexbCn)) maidNutexbCn = prefix + maidNutexbCn;
|
||||
}
|
||||
if (!maidNulmCn.starts_with ("..\\") || !maidNutexbCn.starts_with ("..\\")) titleExistMaidCn = false;
|
||||
for (std::string prefix : base) {
|
||||
if (!maidNulm.starts_with ("..\\") && std::filesystem::exists (prefix + maidNulm)) maidNulm = prefix + maidNulm;
|
||||
if (!maidNutexb.starts_with ("..\\") && std::filesystem::exists (prefix + maidNutexb)) maidNutexb = prefix + maidNutexb;
|
||||
}
|
||||
if (!maidNulm.starts_with ("..\\") || !maidNutexb.starts_with ("..\\")) titleExistMaid = false;
|
||||
|
||||
if (titleExistSeason || (titleExistMaid && titleExistMaidCn)) {
|
||||
TestMode::RegisterItem (
|
||||
L"<select-item label=\"TITLE SCREEN(NEED FILES)\" param-offset-x=\"35\" replace-text=\"0:DEFAULT, 1:SEASON(CHN), "
|
||||
L"2:MAID\" group=\"Setting\" id=\"ModTitleScreen\" max=\"2\" min=\"0\" default=\"0\"/>",
|
||||
[&](){
|
||||
LayeredFs::RegisterBefore ([&] (const std::string &originalFileName, const std::string ¤tFileName) -> std::string {
|
||||
if (currentFileName.starts_with ("F:\\lumen\\") || currentFileName.find ("title") == std::string::npos) return "";
|
||||
if (currentFileName.ends_with ("\\title.nulm")) {
|
||||
if (language == 4 && titleScreen->Read () == 1 && titleExistSeason) return seasonNulm;
|
||||
if (language == 4 && titleScreen->Read () == 2 && titleExistMaidCn) return maidNulmCn;
|
||||
if (titleScreen->Read () == 2 && titleExistMaid) return maidNulm;
|
||||
} else if (currentFileName.ends_with ("\\title.nutexb")) {
|
||||
LogMessage (LogLevel::DEBUG, "nutexb");
|
||||
if (language == 4 && titleScreen->Read () == 1 && titleExistSeason) return seasonNutexb;
|
||||
if (language == 4 && titleScreen->Read () == 2 && titleExistMaidCn) return maidNutexbCn;
|
||||
if (titleScreen->Read () == 2 && titleExistMaid) return maidNutexb;
|
||||
}
|
||||
return "";
|
||||
});
|
||||
LayeredFs::RegisterBefore ([&] (const std::string &originalFileName, const std::string ¤tFileName) -> std::string {
|
||||
if (titleScreen->Read () != 2 || currentFileName.starts_with ("F:\\lumen\\") || currentFileName.find ("\\lumen\\") == std::string::npos) return "";
|
||||
std::string fileName = std::string (currentFileName);
|
||||
fileName = replace (fileName, "\\lumen\\", "\\lumen_maid\\");
|
||||
if (std::filesystem::exists (fileName)) return fileName;
|
||||
return "";
|
||||
});
|
||||
});
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
@@ -617,7 +634,7 @@ Init () {
|
||||
LogMessage (LogLevel::INFO, "Detected voice files, install voice patches!");
|
||||
TestMode::RegisterItemAfter(
|
||||
L"/root/menu[@id='OthersMenu']/layout[@type='Center']/select-item[@id='LanguageItem']",
|
||||
L"<select-item label=\"VOICE\" param-offset-x=\"35\" replace-text=\"0:JPN, 1:CHN\" group=\"Setting\" "
|
||||
L"<select-item label=\"VOICE\" param-offset-x=\"35\" replace-text=\"0:JPN, 1:CHN\" group=\"Setting\" "
|
||||
L"id=\"VoiceLanguageItem\" max=\"1\" min=\"0\" default=\"0\"/>",
|
||||
[&](){
|
||||
INSTALL_FAST_HOOK_DYNAMIC (PlaySoundMain, ASLR (0x1404C6DC0));
|
||||
@@ -632,7 +649,7 @@ Init () {
|
||||
}
|
||||
}
|
||||
|
||||
boolean
|
||||
boolean
|
||||
CnFontPatches () {
|
||||
return cnFontPatches;
|
||||
}
|
||||
|
||||
@@ -279,7 +279,7 @@ FAST_HOOK (HANDLE, CreateFileAHook, PROC_ADDRESS ("kernel32.dll", "CreateFileA")
|
||||
|
||||
LPCSTR pFinalFileName = changed ? currentFileName.c_str () : lpFileName;
|
||||
if (changed) LogMessage (LogLevel::HOOKS, "Final Redirect: {}", currentFileName);
|
||||
return originalCreateFileAHook.stdcall<HANDLE> (pFinalFileName, dwDesiredAccess, dwShareMode,
|
||||
return originalCreateFileAHook.stdcall<HANDLE> (pFinalFileName, dwDesiredAccess, dwShareMode,
|
||||
lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
|
||||
}
|
||||
|
||||
@@ -293,7 +293,7 @@ Init () {
|
||||
}
|
||||
register_cipher (&aes_desc);
|
||||
if (useLayeredFs || !beforeHandlers.empty () || !afterHandlers.empty ()) {
|
||||
LogMessage (LogLevel::INFO, "using LayeredFs! Data_mods={} beforHandlers={} afterHandlers={}",
|
||||
LogMessage (LogLevel::INFO, "using LayeredFs! Data_mods={} beforHandlers={} afterHandlers={}",
|
||||
useLayeredFs ? "enabled" : "disabled", beforeHandlers.size (), afterHandlers.size ());
|
||||
INSTALL_FAST_HOOK (CreateFileAHook);
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ public:
|
||||
};
|
||||
class Value {
|
||||
public:
|
||||
virtual int Read() = 0;
|
||||
virtual int Read(int value = -1) = 0;
|
||||
virtual void Write(int value) = 0;
|
||||
virtual void Reset() = 0;
|
||||
};
|
||||
@@ -129,5 +129,8 @@ void Init ();
|
||||
namespace Language {
|
||||
boolean CnFontPatches ();
|
||||
void Init ();
|
||||
}
|
||||
} // namespace Language
|
||||
namespace UnlimitSong {
|
||||
void Init ();
|
||||
} // namespace UnlimitSong
|
||||
} // namespace patches
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace patches::Plugins {
|
||||
}
|
||||
}
|
||||
// Card API
|
||||
void
|
||||
void
|
||||
WaitTouch (CallBackTouchCard callback, uint64_t touchData) {
|
||||
for (auto plugin : plugins) {
|
||||
auto event = GetProcAddress (plugin, "WaitTouch");
|
||||
@@ -48,7 +48,7 @@ namespace patches::Plugins {
|
||||
}
|
||||
}
|
||||
// QR API (deprecated)
|
||||
void
|
||||
void
|
||||
InitQr (GameVersion gameVersion) {
|
||||
for (auto plugin : plugins) {
|
||||
auto event = GetProcAddress (plugin, "InitQr");
|
||||
@@ -62,7 +62,7 @@ namespace patches::Plugins {
|
||||
if (event) ((BasicEvent)event) ();
|
||||
}
|
||||
}
|
||||
void *
|
||||
void *
|
||||
CheckQr () {
|
||||
for (auto plugin : plugins) {
|
||||
auto event = GetProcAddress (plugin, "UsingQr");
|
||||
@@ -70,7 +70,7 @@ namespace patches::Plugins {
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
size_t
|
||||
size_t
|
||||
GetQr (void *plugin, size_t size, uint8_t *buffer) {
|
||||
auto event = GetProcAddress (*(HMODULE *)plugin, "GetQr");
|
||||
if (event) return ((CopyDataEvent)event) (size, buffer);
|
||||
|
||||
@@ -147,7 +147,7 @@ namespace Card {
|
||||
patches::Scanner::Card::Internal::InsertCard (cardData, internalInvoke);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FAST_HOOK (u64, bngrw_Init, PROC_ADDRESS ("bngrw.dll", "BngRwInit")) { return 0; }
|
||||
FAST_HOOK (void, bngrw_Fin, PROC_ADDRESS ("bngrw.dll", "BngRwFin")) { return; }
|
||||
@@ -167,7 +167,7 @@ namespace Card {
|
||||
FAST_HOOK (i32, bngrw_ReqLatchID, PROC_ADDRESS ("bngrw.dll", "BngRwReqLatchID")) { return 1; }
|
||||
FAST_HOOK (u64, bngrw_ReqAiccAuth, PROC_ADDRESS ("bngrw.dll", "BngRwReqAiccAuth")) { return 1; }
|
||||
FAST_HOOK (u64, bngrw_DevReset, PROC_ADDRESS ("bngrw.dll", "BngRwDevReset")) { return 1; } // Invoke when enter testmode
|
||||
FAST_HOOK (i32, bngrw_ReqCancel, PROC_ADDRESS ("bngrw.dll", "BngRwReqCancel")) {
|
||||
FAST_HOOK (i32, bngrw_ReqCancel, PROC_ADDRESS ("bngrw.dll", "BngRwReqCancel")) {
|
||||
if (state != State::Disable) {
|
||||
state = State::Disable;
|
||||
patches::Scanner::Card::Internal::Commit0 (accessCodeTemplate, chipIdTemplate, true);
|
||||
@@ -188,7 +188,7 @@ namespace Card {
|
||||
return 1;
|
||||
}
|
||||
|
||||
HOOK (i64, bngrw_ReqCancelOfficial, PROC_ADDRESS ("bngrw.dll", "BngRwReqCancel"), u32 a1) {
|
||||
HOOK (i64, bngrw_ReqCancelOfficial, PROC_ADDRESS ("bngrw.dll", "BngRwReqCancel"), u32 a1) {
|
||||
if (state != State::Disable) {
|
||||
state = State::Disable;
|
||||
patches::Plugins::UpdateStatus (StatusType::CardStatus, false);
|
||||
@@ -339,7 +339,7 @@ namespace Qr {
|
||||
}
|
||||
if (scanQueue.empty() || *scanQueue.back() != buffer) {
|
||||
std::vector<uint8_t> *scanData = new std::vector<uint8_t> ();
|
||||
for (uint8_t byte_data : buffer)
|
||||
for (uint8_t byte_data : buffer)
|
||||
scanData->push_back (byte_data);
|
||||
scanQueue.push (scanData);
|
||||
}
|
||||
@@ -355,7 +355,7 @@ namespace Qr {
|
||||
}
|
||||
std::vector<uint8_t> buffer = {};
|
||||
std::string accessQRDataBase = "BNTTCNID";
|
||||
if (!accessCode.starts_with (accessQRDataBase))
|
||||
if (!accessCode.starts_with (accessQRDataBase))
|
||||
for (char word : accessQRDataBase) buffer.push_back (word);
|
||||
for (char word : accessCode) buffer.push_back (word);
|
||||
return patches::Scanner::Qr::Commit (buffer);
|
||||
|
||||
+44
-36
@@ -18,6 +18,7 @@ std::mutex hooksMutex;
|
||||
std::condition_variable hooksCV;
|
||||
std::vector<SafetyHookMid> patches = {};
|
||||
std::vector<Value *> values = {};
|
||||
std::map<std::wstring, Value *> valueMap = {};
|
||||
|
||||
std::wstring
|
||||
mergeCondition (std::wstring original, std::wstring addition, std::wstring value) {
|
||||
@@ -214,15 +215,16 @@ public:
|
||||
this->reset = true;
|
||||
}
|
||||
int
|
||||
Read () override {
|
||||
if (reset) {
|
||||
this->value = ReadTestModeValue (key.c_str ());
|
||||
Read (int value) override {
|
||||
if (reset) {
|
||||
this->value = ReadTestModeValue (key.c_str ());
|
||||
if (this->value != -1) {
|
||||
LogMessage (LogLevel::DEBUG, L"TestMode Value({}) got val: {}", this->key, this->value);
|
||||
reset = false;
|
||||
}
|
||||
}
|
||||
return this->value;
|
||||
if (this->value == -1) return value;
|
||||
else return this->value;
|
||||
}
|
||||
void
|
||||
Write (int value) override {
|
||||
@@ -357,58 +359,58 @@ LocalizationCHT () {
|
||||
);
|
||||
TestMode::RegisterModify(
|
||||
L"/root/menu[@id='ModManagerMenu']/layout[@type='Center']/select-item[@id='ModFixLanguage']",
|
||||
[&](pugi::xml_node &node) {
|
||||
node.attribute(L"label").set_value(L"修復語言");
|
||||
node.attribute(L"replace-text").set_value(L"0:關閉, 1:開啓");
|
||||
[&](pugi::xml_node &node) {
|
||||
node.attribute(L"label").set_value(L"修復語言");
|
||||
node.attribute(L"replace-text").set_value(L"0:關閉, 1:開啓");
|
||||
}, [](){}
|
||||
);
|
||||
TestMode::RegisterModify(
|
||||
L"/root/menu[@id='ModManagerMenu']/layout[@type='Center']/select-item[@id='ModUnlockSongs']",
|
||||
[&](pugi::xml_node &node) {
|
||||
node.attribute(L"label").set_value(L"解鎖歌曲");
|
||||
node.attribute(L"replace-text").set_value(L"0:關閉, 1:開啓, 2:強制");
|
||||
[&](pugi::xml_node &node) {
|
||||
node.attribute(L"label").set_value(L"解鎖歌曲");
|
||||
node.attribute(L"replace-text").set_value(L"0:關閉, 1:開啓, 2:強制");
|
||||
}, [](){}
|
||||
);
|
||||
TestMode::RegisterModify(
|
||||
L"/root/menu[@id='ModManagerMenu']/layout[@type='Center']/select-item[@id='ModFreezeTimer']",
|
||||
[&](pugi::xml_node &node) {
|
||||
node.attribute(L"label").set_value(L"凍結計時");
|
||||
node.attribute(L"replace-text").set_value(L"0:關閉, 1:開啓");
|
||||
[&](pugi::xml_node &node) {
|
||||
node.attribute(L"label").set_value(L"凍結計時");
|
||||
node.attribute(L"replace-text").set_value(L"0:關閉, 1:開啓");
|
||||
}, [](){}
|
||||
);
|
||||
TestMode::RegisterModify(
|
||||
L"/root/menu[@id='ModManagerMenu']/layout[@type='Center']/select-item[@id='ModModeCollabo024']",
|
||||
[&](pugi::xml_node &node) {
|
||||
node.attribute(L"label").set_value(L"鬼滅之刃模式");
|
||||
node.attribute(L"replace-text").set_value(L"0:黙認, 1:啓用, 2:僅登入");
|
||||
[&](pugi::xml_node &node) {
|
||||
node.attribute(L"label").set_value(L"鬼滅之刃模式");
|
||||
node.attribute(L"replace-text").set_value(L"0:黙認, 1:啓用, 2:僅登入");
|
||||
}, [](){}
|
||||
);
|
||||
TestMode::RegisterModify(
|
||||
L"/root/menu[@id='ModManagerMenu']/layout[@type='Center']/select-item[@id='ModModeCollabo025']",
|
||||
[&](pugi::xml_node &node) {
|
||||
node.attribute(L"label").set_value(L"航海王模式");
|
||||
node.attribute(L"replace-text").set_value(L"0:黙認, 1:啓用, 2:僅登入");
|
||||
[&](pugi::xml_node &node) {
|
||||
node.attribute(L"label").set_value(L"航海王模式");
|
||||
node.attribute(L"replace-text").set_value(L"0:黙認, 1:啓用, 2:僅登入");
|
||||
}, [](){}
|
||||
);
|
||||
TestMode::RegisterModify(
|
||||
L"/root/menu[@id='ModManagerMenu']/layout[@type='Center']/select-item[@id='ModModeCollabo026']",
|
||||
[&](pugi::xml_node &node) {
|
||||
node.attribute(L"label").set_value(L"AI粗品模式");
|
||||
node.attribute(L"replace-text").set_value(L"0:黙認, 1:啓用, 2:僅登入");
|
||||
[&](pugi::xml_node &node) {
|
||||
node.attribute(L"label").set_value(L"AI粗品模式");
|
||||
node.attribute(L"replace-text").set_value(L"0:黙認, 1:啓用, 2:僅登入");
|
||||
}, [](){}
|
||||
);
|
||||
TestMode::RegisterModify(
|
||||
L"/root/menu[@id='ModManagerMenu']/layout[@type='Center']/select-item[@id='ModModeAprilFool001']",
|
||||
[&](pugi::xml_node &node) {
|
||||
node.attribute(L"label").set_value(L"青春之達人模式");
|
||||
node.attribute(L"replace-text").set_value(L"0:黙認, 1:啓用, 2:僅登入");
|
||||
[&](pugi::xml_node &node) {
|
||||
node.attribute(L"label").set_value(L"青春之達人模式");
|
||||
node.attribute(L"replace-text").set_value(L"0:黙認, 1:啓用, 2:僅登入");
|
||||
}, [](){}
|
||||
);
|
||||
TestMode::RegisterModify(
|
||||
L"/root/menu[@id='ModManagerMenu']/layout[@type='Center']/select-item[@id='ModInstantResult']",
|
||||
[&](pugi::xml_node &node) {
|
||||
node.attribute(L"label").set_value(L"即時保存");
|
||||
node.attribute(L"replace-text").set_value(L"0:關閉, 1:開啓");
|
||||
[&](pugi::xml_node &node) {
|
||||
node.attribute(L"label").set_value(L"即時保存");
|
||||
node.attribute(L"replace-text").set_value(L"0:關閉, 1:開啓");
|
||||
}, [](){}
|
||||
);
|
||||
TestMode::RegisterModify(
|
||||
@@ -417,9 +419,9 @@ LocalizationCHT () {
|
||||
);
|
||||
TestMode::RegisterModify(
|
||||
L"/root/menu[@id='OthersMenu']/layout[@type='Center']/select-item[@id='AttractDemoItem']",
|
||||
[&](pugi::xml_node &node) {
|
||||
node.attribute(L"label").set_value(L"演示遊玩影片");
|
||||
node.attribute(L"replace-text").set_value(L"0:關閉, 1:開啓");
|
||||
[&](pugi::xml_node &node) {
|
||||
node.attribute(L"label").set_value(L"演示遊玩影片");
|
||||
node.attribute(L"replace-text").set_value(L"0:關閉, 1:開啓");
|
||||
}, [](){}
|
||||
);
|
||||
}
|
||||
@@ -521,11 +523,15 @@ SetupAccessor (const u64 appAccessor, const RefTestModeMain refTestMode) {
|
||||
int
|
||||
ReadTestModeValue (const wchar_t *itemId) {
|
||||
if (appAccessor) {
|
||||
if (const u64 testModeMain = refTestMode (appAccessor)) {
|
||||
int value = 0;
|
||||
u64 *reader = *reinterpret_cast<u64 **> (testModeMain + 16);
|
||||
(*reinterpret_cast<void (__fastcall **) (u64 *, const wchar_t *, int *)> (*reader + 256)) (reader, itemId, &value);
|
||||
return value;
|
||||
try {
|
||||
if (const u64 testModeMain = refTestMode (appAccessor)) {
|
||||
int value = 0;
|
||||
u64 *reader = *reinterpret_cast<u64 **> (testModeMain + 16);
|
||||
(*reinterpret_cast<void (__fastcall **) (u64 *, const wchar_t *, int *)> (*reader + 256)) (reader, itemId, &value);
|
||||
return value;
|
||||
}
|
||||
} catch ([[maybe_unused]] std::exception &e) {
|
||||
LogMessage (LogLevel::ERROR, L"Reading Value({}) Error!", itemId);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
@@ -550,8 +556,10 @@ CreateMenu (const std::wstring &menuName, const std::wstring &menuId) {
|
||||
Value *
|
||||
CreateValue (const std::wstring &key) {
|
||||
LogMessage (LogLevel::DEBUG, L"Create TestMode Value key: {}", key);
|
||||
// if (valueMap.count (key)) return valueMap[key];
|
||||
Value *value = (Value *)(new TestModeValue (key));
|
||||
values.push_back ((Value *)value);
|
||||
// valueMap[key] = value;
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
#include "../patches.h"
|
||||
|
||||
extern std::string chassisId;
|
||||
extern i32 xRes;
|
||||
extern i32 yRes;
|
||||
extern bool vsync;
|
||||
|
||||
namespace patches::CHN00 {
|
||||
int language = 0;
|
||||
@@ -101,9 +104,6 @@ ReplaceLeaBufferAddress (const std::vector<uintptr_t> &bufferAddresses, void *ne
|
||||
void
|
||||
Init () {
|
||||
LogMessage (LogLevel::INFO, "Init CHN00 patches");
|
||||
i32 xRes = 1920;
|
||||
i32 yRes = 1080;
|
||||
bool vsync = false;
|
||||
bool unlockSongs = true;
|
||||
bool fixLanguage = false;
|
||||
bool demoMovie = true;
|
||||
@@ -139,14 +139,6 @@ Init () {
|
||||
modeCollabo026 = readConfigBool (chn00, "mode_collabo026", modeCollabo026);
|
||||
}
|
||||
}
|
||||
|
||||
if (const auto graphics = openConfigSection (config_ptr.get (), "graphics")) {
|
||||
if (const auto res = openConfigSection (graphics, "res")) {
|
||||
xRes = static_cast<i32> (readConfigInt (res, "x", xRes));
|
||||
yRes = static_cast<i32> (readConfigInt (res, "y", yRes));
|
||||
}
|
||||
vsync = readConfigBool (graphics, "vsync", vsync);
|
||||
}
|
||||
}
|
||||
|
||||
// Apply common config patch
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
#include "helpers.h"
|
||||
#include "../patches.h"
|
||||
|
||||
extern i32 xRes;
|
||||
extern i32 yRes;
|
||||
extern bool vsync;
|
||||
|
||||
namespace patches::JPN00 {
|
||||
|
||||
HOOK_DYNAMIC (char, AMFWTerminate, i64) { return 0; }
|
||||
@@ -37,9 +41,6 @@ ReplaceLeaBufferAddress (const std::vector<uintptr_t> &bufferAddresses, void *ne
|
||||
void
|
||||
Init () {
|
||||
LogMessage (LogLevel::INFO, "Init JNP00 patches");
|
||||
i32 xRes = 1920;
|
||||
i32 yRes = 1080;
|
||||
bool vsync = false;
|
||||
bool unlockSongs = true;
|
||||
|
||||
const auto configPath = std::filesystem::current_path () / "config.toml";
|
||||
@@ -47,14 +48,6 @@ Init () {
|
||||
if (config_ptr) {
|
||||
if (const auto patches = openConfigSection (config_ptr.get (), "patches"))
|
||||
unlockSongs = readConfigBool (patches, "unlock_songs", unlockSongs);
|
||||
|
||||
if (const auto graphics = openConfigSection (config_ptr.get (), "graphics")) {
|
||||
if (const auto res = openConfigSection (graphics, "res")) {
|
||||
xRes = static_cast<i32> (readConfigInt (res, "x", xRes));
|
||||
yRes = static_cast<i32> (readConfigInt (res, "y", yRes));
|
||||
}
|
||||
vsync = readConfigBool (graphics, "vsync", vsync);
|
||||
}
|
||||
}
|
||||
|
||||
// Apply common config patch
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
|
||||
extern u64 song_data_size;
|
||||
extern void *song_data;
|
||||
extern i32 xRes;
|
||||
extern i32 yRes;
|
||||
extern bool vsync;
|
||||
|
||||
#define RDX_MOV 0x48, 0xBA
|
||||
#define R8_MOV 0x49, 0xB8
|
||||
@@ -48,23 +51,12 @@ ReplaceLeaBufferAddress (const std::vector<uintptr_t> &bufferAddresses, void *ne
|
||||
void
|
||||
Init () {
|
||||
LogMessage (LogLevel::INFO, "Init JPN08 patches");
|
||||
i32 xRes = 1920;
|
||||
i32 yRes = 1080;
|
||||
bool vsync = false;
|
||||
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);
|
||||
if (config_ptr) {
|
||||
if (auto patches = openConfigSection (config_ptr.get (), "patches")) unlockSongs = readConfigBool (patches, "unlock_songs", unlockSongs);
|
||||
|
||||
if (auto graphics = openConfigSection (config_ptr.get (), "graphics")) {
|
||||
if (auto res = openConfigSection (graphics, "res")) {
|
||||
xRes = static_cast<i32> (readConfigInt (res, "x", xRes));
|
||||
yRes = static_cast<i32> (readConfigInt (res, "y", yRes));
|
||||
}
|
||||
vsync = readConfigBool (graphics, "vsync", vsync);
|
||||
}
|
||||
}
|
||||
|
||||
// Apply common config patch
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
#include "../patches.h"
|
||||
#include <map>
|
||||
|
||||
extern i32 xRes;
|
||||
extern i32 yRes;
|
||||
extern bool vsync;
|
||||
|
||||
namespace patches::JPN39 {
|
||||
int language = 0;
|
||||
FAST_HOOK_DYNAMIC (char, AMFWTerminate, i64) {
|
||||
@@ -39,7 +43,7 @@ FUNCTION_PTR (i32, luaL_loadstring, PROC_ADDRESS ("lua51.dll", "luaL_loadstring"
|
||||
|
||||
FUNCTION_PTR (u64, RefTestModeMain, ASLR (0x1400337C0), u64);
|
||||
FUNCTION_PTR (u64, RefPlayDataManager, ASLR (0x140024AC0), u64);
|
||||
FUNCTION_PTR (i64, GetUserCount, ASLR (0x1403F1020), u64);
|
||||
FUNCTION_PTR (i64, GetUserCount, ASLR (0x1403F1080), u64);
|
||||
|
||||
i64
|
||||
lua_pushbool (const i64 a1, const bool val) {
|
||||
@@ -196,6 +200,52 @@ ExecuteSendResultData () {
|
||||
);
|
||||
}
|
||||
|
||||
bool sendFlag = false;
|
||||
TestMode::Value *instantResult = TestMode::CreateValue (L"ModInstantResult");
|
||||
TestMode::Value *stageNumber = TestMode::CreateValue (L"NumberOfStageItem");
|
||||
#define SCENE_RESULT_HOOK(functionName, location) \
|
||||
FAST_HOOK (void, functionName, location, i64 a1, i64 a2, i64 a3) { \
|
||||
if (instantResult->Read () != 1 && stageNumber->Read () <= 4) { \
|
||||
original##functionName.fastcall (a1, a2, a3); \
|
||||
return; \
|
||||
} \
|
||||
sendFlag = true; \
|
||||
original##functionName.fastcall (a1, a2, a3); \
|
||||
ExecuteSendResultData (); \
|
||||
}
|
||||
|
||||
#define SEND_RESULT_HOOK(functionName, location) \
|
||||
FAST_HOOK (void, functionName, location, i64 a1) { \
|
||||
if (instantResult->Read () != 1 && stageNumber->Read () <= 4) { \
|
||||
original##functionName.fastcall (a1); \
|
||||
return; \
|
||||
} \
|
||||
if (sendFlag) { \
|
||||
sendFlag = false; \
|
||||
original##functionName.fastcall (a1); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CHANGE_RESULT_SIZE_HOOK(functionName, location, target) \
|
||||
MID_HOOK (functionName, location, SafetyHookContext &ctx) { \
|
||||
if (instantResult->Read () != 1 && stageNumber->Read () <= 4) { return; } \
|
||||
i64 instance = RefPlayDataManager (*(i64 *)ctx.r12); \
|
||||
u32 currentStageCount = *(u32 *)(instance + 8); \
|
||||
ctx.target &= 0xFFFFFFFF00000000; \
|
||||
ctx.target |= currentStageCount; \
|
||||
}
|
||||
|
||||
#define CHANGE_RESULT_INDEX_HOOK(functionName, location, target, offset, skip) \
|
||||
MID_HOOK (functionName, location, SafetyHookContext &ctx) { \
|
||||
if (instantResult->Read () != 1 && stageNumber->Read () <= 4) { return; } \
|
||||
i64 instance = RefPlayDataManager (*(i64 *)ctx.r12); \
|
||||
u32 currentStageCount = *(u32 *)(instance + 8); \
|
||||
ctx.target &= 0xFFFFFFFF00000000; \
|
||||
ctx.target |= currentStageCount - 1; \
|
||||
*(u32 *)(ctx.rsp + offset) = currentStageCount - 1; \
|
||||
ctx.rip += skip; \
|
||||
}
|
||||
|
||||
SCENE_RESULT_HOOK (SceneResultInitialize_Enso, ASLR (0x140411FD0));
|
||||
SCENE_RESULT_HOOK (SceneResultInitialize_AI, ASLR (0x140411FD0));
|
||||
SCENE_RESULT_HOOK (SceneResultInitialize_Collabo025, ASLR (0x140411FD0));
|
||||
@@ -248,12 +298,13 @@ MID_HOOK (AttractDemo, ASLR (0x14045A720), SafetyHookContext &ctx) {
|
||||
if (attractDemo->Read () == 1) ctx.r14 = 0;
|
||||
}
|
||||
|
||||
// HOOK (DWORD*, AcquireMostCompatibleDisplayMode, ASLR (0x14064C870), i64 a1, DWORD *a2, DWORD *a3) {
|
||||
// LogMessage (LogLevel::DEBUG, "AcquireMostCompatibleDisplayMode {:d} {:d} {:f} {:f}", a3[0], a3[1], (float)(int)a3[2], (float)(int)a3[3]);
|
||||
// a3[2] = (DWORD)(int)120.0f;
|
||||
// LogMessage (LogLevel::DEBUG, "AcquireMostCompatibleDisplayMode {:d} {:d} {:f} {:f}", a3[0], a3[1], (float)(int)a3[2], (float)(int)a3[3]);
|
||||
// return originalAcquireMostCompatibleDisplayMode (a1, a2, a3);
|
||||
// }
|
||||
FAST_HOOK (DWORD*, AcquireMostCompatibleDisplayMode, ASLR (0x14064C870), i64 a1, DWORD *a2, DWORD *a3) {
|
||||
LogMessage (LogLevel::DEBUG, "AcquireMostCompatibleDisplayMode {:d} {:d} {:f} {:f}", a3[0], a3[1], (float)(int)a3[2], (float)(int)a3[3]);
|
||||
// a3[0] = xRes;
|
||||
// a3[1] = yRes;
|
||||
// LogMessage (LogLevel::DEBUG, "AcquireMostCompatibleDisplayMode {:d} {:d} {:f} {:f}", a3[0], a3[1], (float)(int)a3[2], (float)(int)a3[3]);
|
||||
return originalAcquireMostCompatibleDisplayMode.fastcall<DWORD *> (a1, a2, a3);
|
||||
}
|
||||
|
||||
constexpr i32 datatableBufferSize = 1024 * 1024 * 12;
|
||||
uint8_t *datatableBuffer[3] = { nullptr };
|
||||
@@ -281,10 +332,8 @@ ReplaceDatatableBufferAddresses () {
|
||||
void
|
||||
Init () {
|
||||
LogMessage (LogLevel::INFO, "Init JPN39 patches");
|
||||
i32 xRes = 1920;
|
||||
i32 yRes = 1080;
|
||||
bool vsync = false;
|
||||
bool unlockSongs = true;
|
||||
double modelResRate = 1.0;
|
||||
|
||||
auto configPath = std::filesystem::current_path () / "config.toml";
|
||||
std::unique_ptr<toml_table_t, void (*) (toml_table_t *)> config_ptr (openConfig (configPath), toml_free);
|
||||
@@ -292,24 +341,45 @@ Init () {
|
||||
if (auto patches = openConfigSection (config_ptr.get (), "patches")) {
|
||||
unlockSongs = readConfigBool (patches, "unlock_songs", unlockSongs);
|
||||
}
|
||||
|
||||
if (auto graphics = openConfigSection (config_ptr.get (), "graphics")) {
|
||||
if (auto res = openConfigSection (graphics, "res")) {
|
||||
xRes = static_cast<i32> (readConfigInt (res, "x", xRes));
|
||||
yRes = static_cast<i32> (readConfigInt (res, "y", yRes));
|
||||
}
|
||||
vsync = readConfigBool (graphics, "vsync", vsync);
|
||||
modelResRate = readConfigDouble (graphics, "model_res_rate", modelResRate);
|
||||
}
|
||||
}
|
||||
|
||||
// Hook to get AppAccessor and ComponentAccessor
|
||||
INSTALL_FAST_HOOK (DeviceCheck);
|
||||
INSTALL_FAST_HOOK (luaL_newstate);
|
||||
// INSTALL_HOOK (AcquireMostCompatibleDisplayMode);
|
||||
// INSTALL_FAST_HOOK (AcquireMostCompatibleDisplayMode);
|
||||
|
||||
// Apply common config patch
|
||||
// Window Size
|
||||
WRITE_MEMORY (ASLR (0x140494533), i32, xRes);
|
||||
WRITE_MEMORY (ASLR (0x14049453A), i32, yRes);
|
||||
// DonSystem::DonModelRenderer::DonModelRenderer
|
||||
if (modelResRate > 0) {
|
||||
i32 donModelX = (i32)(xRes * modelResRate);
|
||||
i32 donModelY = (i32)(yRes * modelResRate);
|
||||
LogMessage (LogLevel::INFO, "Patch DonModel use resolution {}x{}", donModelX, donModelY);
|
||||
WRITE_MEMORY (ASLR (0x1404F3D5B), i32, donModelX);
|
||||
WRITE_MEMORY (ASLR (0x1404F3D62), i32, donModelY);
|
||||
}
|
||||
// // DonSystem::Renderer::Renderer
|
||||
// WRITE_MEMORY (ASLR (0x1404FBF33), i32, xRes);
|
||||
// WRITE_MEMORY (ASLR (0x1404FBF3A), i32, yRes);
|
||||
// // DonSystem::Renderer::CreateOnpuPass
|
||||
// WRITE_MEMORY (ASLR (0x1404FCF77), i32, xRes);
|
||||
// WRITE_MEMORY (ASLR (0x1404FCF81), i32, yRes / 2);
|
||||
// // nu::LightManager::LightManager
|
||||
// WRITE_MEMORY (ASLR (0x1406BED7A), i32, xRes);
|
||||
// WRITE_MEMORY (ASLR (0x1406BED82), i32, yRes);
|
||||
// WRITE_MEMORY (ASLR (0x1406BEF26), i32, xRes);
|
||||
// WRITE_MEMORY (ASLR (0x1406BEF33), i32, yRes);
|
||||
// // google::protobuf::TextFormat::Parser::ParserImpl::ConsumeField
|
||||
// WRITE_MEMORY (ASLR (0x1406F7E47), i32, xRes);
|
||||
// // google::protobuf::DescriptorBuilder::AddSymbol
|
||||
// WRITE_MEMORY (ASLR (0x140719191), i32, xRes);
|
||||
// nuscDecoderCalcObjectSize
|
||||
// WRITE_MEMORY (ASLR (0x140719191), i32, xRes);
|
||||
|
||||
if (!vsync) WRITE_MEMORY (ASLR (0x14064C7E9), u8, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x90);
|
||||
|
||||
// Bypass errors
|
||||
@@ -350,10 +420,10 @@ Init () {
|
||||
TestMode::RegisterItem (
|
||||
L"<select-item label=\"UNLOCK SONGS\" param-offset-x=\"35\" replace-text=\"0:OFF, 1:ON, "
|
||||
L"2:FORCE\" group=\"Setting\" id=\"ModUnlockSongs\" max=\"2\" min=\"0\" default=\"1\"/>",
|
||||
[&]() {
|
||||
INSTALL_FAST_HOOK (IsSongRelease);
|
||||
INSTALL_FAST_HOOK (IsSongReleasePlayer);
|
||||
INSTALL_MID_HOOK (DifficultyPanelCrown);
|
||||
[&]() {
|
||||
INSTALL_FAST_HOOK (IsSongRelease);
|
||||
INSTALL_FAST_HOOK (IsSongReleasePlayer);
|
||||
INSTALL_MID_HOOK (DifficultyPanelCrown);
|
||||
}
|
||||
);
|
||||
// Freeze Timer
|
||||
|
||||
+4
-4
@@ -40,10 +40,10 @@ struct SDLAxisState {
|
||||
enum Scroll { MOUSE_SCROLL_INVALID, MOUSE_SCROLL_UP, MOUSE_SCROLL_DOWN };
|
||||
|
||||
struct Keybindings {
|
||||
u8 keycodes[255];
|
||||
SDL_GamepadButton buttons[255];
|
||||
SDLAxis axis[255];
|
||||
Scroll scroll[2];
|
||||
u8 keycodes[255] = { '\0' };
|
||||
SDL_GamepadButton buttons[255] = { SDL_GAMEPAD_BUTTON_INVALID };
|
||||
SDLAxis axis[255] = { SDL_AXIS_NULL };
|
||||
Scroll scroll[2] = { MOUSE_SCROLL_INVALID };
|
||||
};
|
||||
|
||||
enum EnumType { none, keycode, button, axis, scroll };
|
||||
|
||||
+44
-15
@@ -10,6 +10,9 @@ extern int exited;
|
||||
extern u8 inputState;
|
||||
extern float axisThreshold;
|
||||
extern bool globalKeyboardInput;
|
||||
extern bool autoIme;
|
||||
extern HKL currentLayout;
|
||||
extern bool emulateUsio;
|
||||
|
||||
bool wndForeground = false;
|
||||
bool usingKeyboard = false;
|
||||
@@ -67,6 +70,7 @@ SetConfigValue (const toml_table_t *table, const char *key, Keybindings *key_bin
|
||||
|
||||
switch (value.type) {
|
||||
case keycode: {
|
||||
LogMessage (LogLevel::DEBUG, "config {} type=keycode value={}", key, (int)value.keycode);
|
||||
*inputState |= 1;
|
||||
for (int i = 0; i < std::size (key_bind->keycodes); i++) {
|
||||
if (key_bind->keycodes[i] == 0) {
|
||||
@@ -77,6 +81,7 @@ SetConfigValue (const toml_table_t *table, const char *key, Keybindings *key_bin
|
||||
break;
|
||||
}
|
||||
case button: {
|
||||
LogMessage (LogLevel::DEBUG, "config {} type=button value={}", key, (int)value.button);
|
||||
*inputState |= (1 << 2);
|
||||
for (int i = 0; i < std::size (key_bind->buttons); i++) {
|
||||
if (key_bind->buttons[i] == SDL_GAMEPAD_BUTTON_INVALID) {
|
||||
@@ -87,6 +92,7 @@ SetConfigValue (const toml_table_t *table, const char *key, Keybindings *key_bin
|
||||
break;
|
||||
}
|
||||
case axis: {
|
||||
LogMessage (LogLevel::DEBUG, "config {} type=axis value={}", key, (int)value.axis);
|
||||
*inputState |= (1 << 2);
|
||||
for (int i = 0; i < std::size (key_bind->axis); i++) {
|
||||
if (key_bind->axis[i] == 0) {
|
||||
@@ -94,8 +100,10 @@ SetConfigValue (const toml_table_t *table, const char *key, Keybindings *key_bin
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case scroll: {
|
||||
LogMessage (LogLevel::DEBUG, "config {} type=scroll value={}", key, (int)value.scroll);
|
||||
*inputState |= (1 << 1);
|
||||
for (int i = 0; i < std::size (key_bind->scroll); i++) {
|
||||
if (key_bind->scroll[i] == 0) {
|
||||
@@ -196,16 +204,19 @@ CheckFlipped (uint32_t which, SDL_Gamepad *gamepad) {
|
||||
|
||||
bool
|
||||
InitializePoll (HWND windowHandle) {
|
||||
wndForeground = windowHandle == GetForegroundWindow ();
|
||||
if (!emulateUsio) return false;
|
||||
|
||||
usingKeyboard = inputState & 1;
|
||||
usingMouse = inputState & (1 << 1);
|
||||
usingController = inputState & (1 << 2);
|
||||
usingSDLEvent = usingMouse || usingController;
|
||||
|
||||
atexit ([](){ if (currentLayout != nullptr) ActivateKeyboardLayout (currentLayout, KLF_SETFORPROCESS);});
|
||||
InitializeKeyboard ();
|
||||
if (usingSDLEvent) {
|
||||
LogMessage (LogLevel::DEBUG, "InitializePoll");
|
||||
bool hasRumble = true;
|
||||
wndForeground = windowHandle == GetForegroundWindow ();
|
||||
SDL_SetMainReady ();
|
||||
|
||||
SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_PS4, "1");
|
||||
@@ -267,9 +278,18 @@ InitializePoll (HWND windowHandle) {
|
||||
bool
|
||||
CheckForegroundWindow (HWND processWindow) {
|
||||
if (processWindow == nullptr) return false;
|
||||
if (wndForeground ^ (processWindow == GetForegroundWindow ())) {
|
||||
HWND foregroundWnd = GetForegroundWindow ();
|
||||
if (wndForeground ^ (processWindow == foregroundWnd)) {
|
||||
wndForeground = !wndForeground;
|
||||
LogMessage (LogLevel::DEBUG, "window focus={}", wndForeground);
|
||||
if (autoIme) {
|
||||
if (wndForeground) {
|
||||
currentLayout = GetKeyboardLayout (0);
|
||||
auto engLayout = LoadKeyboardLayout (TEXT ("00000409"), KLF_ACTIVATE);
|
||||
ActivateKeyboardLayout (engLayout, KLF_SETFORPROCESS);
|
||||
LogMessage (LogLevel::DEBUG, "(experimental) auto change KeyboardLayout {}", LOWORD(engLayout));
|
||||
}
|
||||
}
|
||||
}
|
||||
return wndForeground;
|
||||
}
|
||||
@@ -288,11 +308,11 @@ CorrectButton (uint32_t which, uint8_t button) {
|
||||
|
||||
void
|
||||
CleanPoll () {
|
||||
if (usingKeyboard && keyboardClean) {
|
||||
keyboardClean = false;
|
||||
for (int i=0; i<0xFF; i++) keyboardCount[i] -= (bool)keyboardDiff[i];
|
||||
if (usingKeyboard) {
|
||||
for (int i=0; i<0xFF; i++) keyboardCount[i] -= (bool)keyboardDiff[i];
|
||||
memset (keyboardDiff, 0, 0XFF);
|
||||
}
|
||||
|
||||
if (usingMouse) {
|
||||
currentMouseState.ScrolledUp = false;
|
||||
currentMouseState.ScrolledDown = false;
|
||||
@@ -311,7 +331,8 @@ CleanPoll () {
|
||||
|
||||
void
|
||||
UpdatePoll (HWND windowHandle) {
|
||||
if (!CheckForegroundWindow (windowHandle)) return;
|
||||
if (!CheckForegroundWindow (windowHandle)) return;
|
||||
if (!emulateUsio) return;
|
||||
CleanPoll ();
|
||||
if (usingSDLEvent) {
|
||||
SDL_Event event;
|
||||
@@ -347,7 +368,7 @@ UpdatePoll (HWND windowHandle) {
|
||||
uint8_t button = CorrectButton (event.gbutton.which, event.gbutton.button);
|
||||
currentControllerButtonsState[button] = false;
|
||||
} break;
|
||||
case SDL_EVENT_GAMEPAD_BUTTON_DOWN:
|
||||
case SDL_EVENT_GAMEPAD_BUTTON_DOWN:
|
||||
if (wndForeground) {
|
||||
uint8_t button = CorrectButton (event.gbutton.which, event.gbutton.button);
|
||||
LogMessage (LogLevel::DEBUG, "Controller {}: button {} pressed, remapped to {}", event.gbutton.which, event.gbutton.button, button);
|
||||
@@ -379,7 +400,7 @@ UpdatePoll (HWND windowHandle) {
|
||||
currentControllerAxisState[button] = sensorValue;
|
||||
} break;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -504,20 +525,28 @@ ControllerAxisIsTapped (const SDLAxis axis) {
|
||||
bool
|
||||
IsButtonTapped (const Keybindings &bindings) {
|
||||
for (size_t i = 0; i < ConfigKeyboardButtonsCount; i++) {
|
||||
if (bindings.keycodes[i] == 0) continue;
|
||||
if (KeyboardIsTapped (bindings.keycodes[i])) return true;
|
||||
if (bindings.keycodes[i] == '\0') continue;
|
||||
if (KeyboardIsTapped (bindings.keycodes[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < std::size (ConfigControllerButtons); i++) {
|
||||
if (bindings.buttons[i] == SDL_GAMEPAD_BUTTON_INVALID) continue;
|
||||
if (ControllerButtonIsTapped (bindings.buttons[i])) return true;
|
||||
if (ControllerButtonIsTapped (bindings.buttons[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < std::size (ConfigControllerAXIS); i++) {
|
||||
if (bindings.axis[i] == 0) continue;
|
||||
if (float val = ControllerAxisIsTapped (bindings.axis[i]); val > 0) return true;
|
||||
if (bindings.axis[i] == SDL_AXIS_NULL) continue;
|
||||
if (ControllerAxisIsTapped (bindings.axis[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < std::size (ConfigMouseScroll); i++) {
|
||||
if (bindings.scroll[i] == 0) continue;
|
||||
if (GetMouseScrollIsTapped (bindings.scroll[i])) return true;
|
||||
if (bindings.scroll[i] == MOUSE_SCROLL_INVALID) continue;
|
||||
if (GetMouseScrollIsTapped (bindings.scroll[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user