config Refactor | use rfl (Thanks to asesidaa)

This commit is contained in:
ptmaster
2025-01-23 23:43:38 +08:00
parent 7e7a9018db
commit a3631a8659
22 changed files with 1173 additions and 747 deletions
+107 -58
View File
@@ -29,19 +29,6 @@ add_definitions(-DNOMINMAX -DLTC_NO_PROTOTYPES -D_CRT_SECURE_NO_WARNINGS)
# Include FetchContent module
include(FetchContent)
# Fetch tomlc99 (no built-in CMake support)
FetchContent_Declare(
tomlc99
GIT_REPOSITORY https://github.com/cktan/tomlc99.git
GIT_TAG master
)
FetchContent_GetProperties(tomlc99)
if(NOT tomlc99_POPULATED)
FetchContent_MakeAvailable(tomlc99)
add_library(tomlc99 STATIC ${tomlc99_SOURCE_DIR}/toml.c)
target_include_directories(tomlc99 PUBLIC ${tomlc99_SOURCE_DIR})
endif()
# Fetch stb (header-only library, no built-in CMake support)
FetchContent_Declare(
stb
@@ -130,48 +117,93 @@ FetchContent_Declare(
)
FetchContent_MakeAvailable(minhook)
FetchContent_Declare(
tomlplusplus
GIT_REPOSITORY https://github.com/marzer/tomlplusplus.git
GIT_TAG v3.4.0
)
FetchContent_MakeAvailable(tomlplusplus)
export(TARGETS tomlplusplus_tomlplusplus FILE "${CMAKE_BINARY_DIR}/tomlplusplus-config.cmake")
set(tomlplusplus_DIR "${CMAKE_BINARY_DIR}")
FetchContent_Declare(
reflectcpp
URL https://github.com/getml/reflect-cpp/archive/refs/tags/v0.17.0.zip
)
set(REFLECTCPP_TOML ON CACHE BOOL "" FORCE)
set(REFLECTCPP_XML OFF CACHE BOOL "" FORCE)
set(REFLECTCPP_USE_VCPKG OFF CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(reflectcpp)
# Source files
set(SOURCES
src/dllmain.cpp
src/helpers.cpp
src/logger.cpp
src/poll.cpp
src/pollasync.cpp
src/bnusio.cpp
src/Windows/WindowsError.cpp
src/Windows/MinimumLatencyAudioClient.cpp
src/patches/amauth.cpp
# src/patches/dxgi.cpp
# src/patches/fpslimiter.cpp
src/patches/audio.cpp
src/patches/plugins.cpp
src/patches/scanner.cpp
src/patches/layeredfs.cpp
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
src/patches/versions/CHN00.cpp
src/dllmain.cpp
src/helpers.cpp
src/logger.cpp
src/poll.cpp
src/pollasync.cpp
src/bnusio.cpp
src/Windows/WindowsError.cpp
src/Windows/MinimumLatencyAudioClient.cpp
src/patches/amauth.cpp
# src/patches/dxgi.cpp
# src/patches/fpslimiter.cpp
src/patches/audio.cpp
src/patches/plugins.cpp
src/patches/scanner.cpp
src/patches/layeredfs.cpp
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
src/patches/versions/CHN00.cpp
src/config.cpp
)
set(VALIDATOR_SOURCES
src/configValidator.cpp
src/helpers.cpp
src/config.cpp
src/logger.cpp
)
# Create the library
add_library(bnusio SHARED ${SOURCES})
add_executable(validator ${VALIDATOR_SOURCES})
# Remove 'lib' prefix from the library name, make sure the output directory is expected
set_target_properties(bnusio PROPERTIES
PREFIX ""
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/$<CONFIG>"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/$<CONFIG>")
set_target_properties(validator PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/$<CONFIG>"
)
# Remove 'lib' prefix from the library name
set_target_properties(bnusio PROPERTIES PREFIX "")
# Include directories
target_include_directories(bnusio PRIVATE
src
${tomlc99_SOURCE_DIR}
${SDL3_SOURCE_DIR}/include
${xxhash_SOURCE_DIR}
${zlib_SOURCE_DIR}
${libtomcrypt_SOURCE_DIR}/src/headers
${minhook_SOURCE_DIR}/include
src
${SDL3_SOURCE_DIR}/include
${xxhash_SOURCE_DIR}
${zlib_SOURCE_DIR}
${libtomcrypt_SOURCE_DIR}/src/headers
${minhook_SOURCE_DIR}/include
${reflectcpp_SOURCE_DIR}/include
)
target_include_directories(validator PRIVATE
src
${SDL3_SOURCE_DIR}/include
${xxhash_SOURCE_DIR}
${zlib_SOURCE_DIR}
${libtomcrypt_SOURCE_DIR}/src/headers
${minhook_SOURCE_DIR}/include
${reflectcpp_SOURCE_DIR}/include
)
# Compiler definitions
@@ -186,18 +218,35 @@ endif()
# Link libraries
target_link_libraries(bnusio PRIVATE
tomlc99
SDL3-static
xxhash
zlibstatic
libtomcrypt
safetyhook
ZXing::ZXing
pugixml
stb
ws2_32
ntdll
minhook
SDL3-static
xxhash
zlibstatic
libtomcrypt
safetyhook
ZXing::ZXing
pugixml
stb
ws2_32
ntdll
minhook
tomlplusplus::tomlplusplus
reflectcpp
)
target_link_libraries(validator PRIVATE
SDL3-static
xxhash
zlibstatic
libtomcrypt
safetyhook
ZXing::ZXing
pugixml
stb
ws2_32
ntdll
minhook
tomlplusplus::tomlplusplus
reflectcpp
)
# Define log path; used to make the file path relative in the log calls.
@@ -220,7 +269,7 @@ endif()
add_custom_command(
TARGET bnusio POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}/bnusio.dll"
"${CMAKE_BINARY_DIR}/$<CONFIG>/bnusio.dll"
"${CMAKE_SOURCE_DIR}/dist/bnusio.dll"
COMMENT "Copying bnusio.dll to dist directory"
)
+88
View File
@@ -0,0 +1,88 @@
diff --git a/src/config.h b/src/config.h
index be682de..7d3388c 100644
--- a/src/config.h
+++ b/src/config.h
@@ -459,6 +459,11 @@ public:
const loggingConfig& getLoggingConfig() const { return config.logging; }
const keybindingConfig& getKeyBindings() const { return keyBindings; }
+ void setRes(i32 x, i32 y) {
+ config.graphics.res.x = x;
+ config.graphics.res.y = y;
+ }
+
private:
ConfigManager();
diff --git a/src/dllmain.cpp b/src/dllmain.cpp
index 6cb5b49..673663c 100644
--- a/src/dllmain.cpp
+++ b/src/dllmain.cpp
@@ -265,6 +265,7 @@ DllMain (HMODULE module, const DWORD reason, LPVOID reserved) {
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);
}
+ Config::ConfigManager::instance ().setRes (xRes, yRes);
LogMessage (LogLevel::INFO, "Scale Rate: x={} y={}", horizontalScale, verticalScale);
LogMessage (LogLevel::INFO, "Boot with {} mode ({}x{})", windowed ? "window" : "fullscreen", xRes, yRes);
diff --git a/src/patches/versions/CHN00.cpp b/src/patches/versions/CHN00.cpp
index 2d59616..31ca3c1 100644
--- a/src/patches/versions/CHN00.cpp
+++ b/src/patches/versions/CHN00.cpp
@@ -3,8 +3,8 @@
#include "config.h"
static std::string chassisId = Config::ConfigManager::instance ().getAmauthConfig ().chassis_id.value ();
-static i32 xRes = Config::ConfigManager::instance ().getGraphicsConfig ().res.x;
-static i32 yRes = Config::ConfigManager::instance ().getGraphicsConfig ().res.y;
+static const i32& xRes = Config::ConfigManager::instance ().getGraphicsConfig ().res.x;
+static const i32& yRes = Config::ConfigManager::instance ().getGraphicsConfig ().res.y;
static bool vsync = Config::ConfigManager::instance ().getGraphicsConfig ().vsync;
static bool localFiles = Config::ConfigManager::instance ().getPatchesConfig ().local_files;
diff --git a/src/patches/versions/JPN00.cpp b/src/patches/versions/JPN00.cpp
index 1490c8f..c4580c1 100644
--- a/src/patches/versions/JPN00.cpp
+++ b/src/patches/versions/JPN00.cpp
@@ -2,8 +2,8 @@
#include "../patches.h"
#include "config.h"
-static i32 xRes = Config::ConfigManager::instance ().getGraphicsConfig ().res.x;
-static i32 yRes = Config::ConfigManager::instance ().getGraphicsConfig ().res.y;
+static const i32& xRes = Config::ConfigManager::instance ().getGraphicsConfig ().res.x;
+static const i32& yRes = Config::ConfigManager::instance ().getGraphicsConfig ().res.y;
static bool vsync = Config::ConfigManager::instance ().getGraphicsConfig ().vsync;
static bool localFiles = Config::ConfigManager::instance ().getPatchesConfig ().local_files;
namespace patches::JPN00 {
diff --git a/src/patches/versions/JPN08.cpp b/src/patches/versions/JPN08.cpp
index 0dac8f0..bc07616 100644
--- a/src/patches/versions/JPN08.cpp
+++ b/src/patches/versions/JPN08.cpp
@@ -4,8 +4,8 @@
extern u64 song_data_size;
extern void *song_data;
-static i32 xRes = Config::ConfigManager::instance ().getGraphicsConfig ().res.x;
-static i32 yRes = Config::ConfigManager::instance ().getGraphicsConfig ().res.y;
+static const i32& xRes = Config::ConfigManager::instance ().getGraphicsConfig ().res.x;
+static const i32& yRes = Config::ConfigManager::instance ().getGraphicsConfig ().res.y;
static bool vsync = Config::ConfigManager::instance ().getGraphicsConfig ().vsync;
static bool localFiles = Config::ConfigManager::instance ().getPatchesConfig ().local_files;
#define RDX_MOV 0x48, 0xBA
diff --git a/src/patches/versions/JPN39.cpp b/src/patches/versions/JPN39.cpp
index 2b37ac7..e5edbd1 100644
--- a/src/patches/versions/JPN39.cpp
+++ b/src/patches/versions/JPN39.cpp
@@ -4,8 +4,8 @@
#include <map>
#include "config.h"
-static i32 xRes = Config::ConfigManager::instance ().getGraphicsConfig ().res.x;
-static i32 yRes = Config::ConfigManager::instance ().getGraphicsConfig ().res.y;
+static const i32& xRes = Config::ConfigManager::instance ().getGraphicsConfig ().res.x;
+static const i32& yRes = Config::ConfigManager::instance ().getGraphicsConfig ().res.y;
static bool vsync = Config::ConfigManager::instance ().getGraphicsConfig ().vsync;
static bool localFiles = Config::ConfigManager::instance ().getPatchesConfig ().local_files;
+41 -84
View File
@@ -1,9 +1,11 @@
// ReSharper disable CppDFAUnreachableCode
#include <queue>
#include "constants.h"
#include "helpers.h"
#include "patches/patches.h"
#include "bnusio.h"
#include "poll.h"
#include "config.h"
extern GameVersion gameVersion;
extern std::vector<HMODULE> plugins;
@@ -14,29 +16,29 @@ extern char accessCode2[21];
extern char chipId1[33];
extern char chipId2[33];
extern bool emulateUsio;
extern bool acceptInvalidCards;
static bool emulateUsio = Config::ConfigManager::instance ().getEmulationConfig ().usio;
static bool acceptInvalidCards = Config::ConfigManager::instance ().getEmulationConfig ().accept_invalid;
extern HWND hGameWnd;
Keybindings EXIT = {.keycodes = {VK_ESCAPE}};
Keybindings TEST = {.keycodes = {VK_F1}};
Keybindings SERVICE = {.keycodes = {VK_F2}};
Keybindings DEBUG_UP = {.keycodes = {VK_UP}};
Keybindings DEBUG_DOWN = {.keycodes = {VK_DOWN}};
Keybindings DEBUG_ENTER = {.keycodes = {VK_RETURN}};
Keybindings COIN_ADD = {.keycodes = {VK_RETURN}, .buttons = {SDL_GAMEPAD_BUTTON_START}};
Keybindings CARD_INSERT_1 = {.keycodes = {'P'}};
Keybindings CARD_INSERT_2 = {};
Keybindings 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 = {.keycodes = {'Z'}};
Keybindings P2_LEFT_RED = {.keycodes = {'X'}};
Keybindings P2_RIGHT_RED = {.keycodes = {'C'}};
Keybindings P2_RIGHT_BLUE = {.keycodes = {'V'}};
static const Keybindings & EXIT = Config::ConfigManager::instance ().getKeyBindings ().exit();
static const Keybindings & TEST = Config::ConfigManager::instance ().getKeyBindings ().test();
static const Keybindings & SERVICE = Config::ConfigManager::instance ().getKeyBindings ().service();
static const Keybindings & DEBUG_UP = Config::ConfigManager::instance ().getKeyBindings ().debug_up();
static const Keybindings & DEBUG_DOWN = Config::ConfigManager::instance ().getKeyBindings ().debug_down();
static const Keybindings & DEBUG_ENTER = Config::ConfigManager::instance ().getKeyBindings ().debug_enter();
static const Keybindings & COIN_ADD = Config::ConfigManager::instance ().getKeyBindings ().coin_add();
static const Keybindings & CARD_INSERT_1 = Config::ConfigManager::instance ().getKeyBindings ().card_insert_1();
static const Keybindings & CARD_INSERT_2 = Config::ConfigManager::instance ().getKeyBindings ().card_insert_2();
static const Keybindings & QR_DATA_READ = Config::ConfigManager::instance ().getKeyBindings ().qr_data_read();
static const Keybindings & QR_IMAGE_READ = Config::ConfigManager::instance ().getKeyBindings ().qr_image_read();
static const Keybindings & P1_LEFT_BLUE = Config::ConfigManager::instance ().getKeyBindings ().p1_left_blue();
static const Keybindings & P1_LEFT_RED = Config::ConfigManager::instance ().getKeyBindings ().p1_left_red();
static const Keybindings & P1_RIGHT_RED = Config::ConfigManager::instance ().getKeyBindings ().p1_right_red();
static const Keybindings & P1_RIGHT_BLUE = Config::ConfigManager::instance ().getKeyBindings ().p1_right_blue();
static const Keybindings & P2_LEFT_BLUE = Config::ConfigManager::instance ().getKeyBindings ().p2_left_blue();
static const Keybindings & P2_LEFT_RED = Config::ConfigManager::instance ().getKeyBindings ().p2_left_red();
static const Keybindings & P2_RIGHT_RED = Config::ConfigManager::instance ().getKeyBindings ().p2_right_red();
static const Keybindings & P2_RIGHT_BLUE = Config::ConfigManager::instance ().getKeyBindings ().p2_right_blue();
const int exitWait = 100;
int exited = 0;
@@ -50,7 +52,16 @@ bool updateByCoin = false;
HWND windowHandle = nullptr;
float axisThreshold = 0.6f;
u8 inputState = 1 | (1 << 2);
bool globalKeyboard = false;
bool globalKeyboard = Config::ConfigManager::instance ().getControllerConfig ().global_keyboard;
bool waitAll = false;
short drumWaitPeriod = Config::ConfigManager::instance ().getControllerConfig ().wait_period;
bool analogInput = Config::ConfigManager::instance ().getControllerConfig ().analog_input;
u16 buttonWaitPeriod[] = { 0, 0 };
std::queue<u8> buttonQueue[] = { {}, {} };
bool valueStates[] = {false, false, false, false, false, false, false, false};
const 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
};
namespace bnusio {
HMODULE bnusioOriginal = LoadLibrary ("bnusio_original.dll");
@@ -136,10 +147,9 @@ BNUSIO_EXPORT (u16, bnusio_GetService, i32 a1) {
}
}
bool analogInput = false;
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
SDLAxis::SDL_AXIS_LEFT_LEFT, SDLAxis::SDL_AXIS_LEFT_RIGHT, SDLAxis::SDL_AXIS_LEFT_DOWN, SDLAxis::SDL_AXIS_LEFT_UP, // P1: LB, LR, RR, RB
SDLAxis::SDL_AXIS_RIGHT_LEFT, SDLAxis::SDL_AXIS_RIGHT_RIGHT, SDLAxis::SDL_AXIS_RIGHT_DOWN, SDLAxis::SDL_AXIS_RIGHT_UP, // P2: LB, LR, RR, RB
};
u16 __fastcall
AnalogInputAxis (const u8 which) {
@@ -147,14 +157,6 @@ AnalogInputAxis (const u8 which) {
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];
@@ -215,24 +217,8 @@ AnalogInputSimple (const u8 which) {
void
Init () {
SetKeyboardButtons ();
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);
if (config_ptr) {
const toml_table_t *config = config_ptr.get ();
if (const auto controller = openConfigSection (config, "controller")) {
drumWaitPeriod = static_cast<short> (readConfigInt (controller, "wait_period", drumWaitPeriod));
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);
// }
}
updateByCoin = fpsLimit == 0;
// if (updateByCoin) {
// LogMessage (LogLevel::INFO, "fpsLimit is set to 0, bnusio::Update() will invoke in getCoin callback");
@@ -252,39 +238,6 @@ Init () {
analogMethod = AnalogInputSimple;
}
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) {
inputState = 0;
if (analogInput) inputState |= (1 << 2);
const toml_table_t *keyConfig = keyConfig_ptr.get ();
SetConfigValue (keyConfig, "EXIT", &EXIT, &inputState);
SetConfigValue (keyConfig, "TEST", &TEST, &inputState);
SetConfigValue (keyConfig, "SERVICE", &SERVICE, &inputState);
SetConfigValue (keyConfig, "DEBUG_UP", &DEBUG_UP, &inputState);
SetConfigValue (keyConfig, "DEBUG_DOWN", &DEBUG_DOWN, &inputState);
SetConfigValue (keyConfig, "DEBUG_ENTER", &DEBUG_ENTER, &inputState);
SetConfigValue (keyConfig, "COIN_ADD", &COIN_ADD, &inputState);
SetConfigValue (keyConfig, "CARD_INSERT_1", &CARD_INSERT_1, &inputState);
SetConfigValue (keyConfig, "CARD_INSERT_2", &CARD_INSERT_2, &inputState);
SetConfigValue (keyConfig, "QR_DATA_READ", &QR_DATA_READ, &inputState);
SetConfigValue (keyConfig, "QR_IMAGE_READ", &QR_IMAGE_READ, &inputState);
SetConfigValue (keyConfig, "P1_LEFT_BLUE", &P1_LEFT_BLUE, &inputState);
SetConfigValue (keyConfig, "P1_LEFT_RED", &P1_LEFT_RED, &inputState);
SetConfigValue (keyConfig, "P1_RIGHT_RED", &P1_RIGHT_RED, &inputState);
SetConfigValue (keyConfig, "P1_RIGHT_BLUE", &P1_RIGHT_BLUE, &inputState);
SetConfigValue (keyConfig, "P2_LEFT_BLUE", &P2_LEFT_BLUE, &inputState);
SetConfigValue (keyConfig, "P2_LEFT_RED", &P2_LEFT_RED, &inputState);
SetConfigValue (keyConfig, "P2_RIGHT_RED", &P2_RIGHT_RED, &inputState);
SetConfigValue (keyConfig, "P2_RIGHT_BLUE", &P2_RIGHT_BLUE, &inputState);
}
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")) {
emulateUsio = true;
LogMessage (LogLevel::ERROR, "bnusio_original.dll not found! usio emulation enabled");
@@ -307,8 +260,12 @@ Update () {
UpdatePoll (windowHandle);
std::vector<uint8_t> buffer = {};
if (IsButtonTapped (COIN_ADD)) coin_count++;
if (IsButtonTapped (SERVICE)) service_count++;
if (IsButtonTapped (COIN_ADD)) {
coin_count++;
}
if (IsButtonTapped (SERVICE)) {
service_count++;
}
if (IsButtonTapped (TEST)) testEnabled = !testEnabled;
if (exited == 0 && IsButtonTapped (EXIT)) {
LogMessage (LogLevel::INFO, "Exit by Press Exit Button!");
+245
View File
@@ -0,0 +1,245 @@
#include <filesystem>
#include <istream>
#include <iostream>
#include <Windows.h>
#include <rfl/toml.hpp>
#include <map>
#include "config.h"
#include "logger.h"
static bool usingKeyboard = false;
static bool usingMouse = false;
static bool usingController = false;
namespace Config {
bool
ConfigManager::validateConfigfile (std::string path) {
std::filesystem::path configPath = path;
if (!exists (configPath) || !configPath.has_filename ()) {
std::cerr << configPath.string () << ": file does not exist" << std::endl;
return false;
}
std::ifstream stream (configPath);
if (!stream.is_open ()) {
std::cerr << "Could not open " << configPath.string () << std::endl;
return false;
}
auto result = rfl::toml::read<struct globalConfig> (stream);
if (result) {
return true;
}
auto error = result.error ().value ();
std::cerr << "Validate config failed with error: " << error.what () << std::endl;
return false;
}
bool
ConfigManager::loadConfig () {
std::lock_guard lock (mutex);
InitializeLogger (LogLevel::INFO, true, "TaikoArcadeLoader.log");
if (isLoaded) { return true; }
const auto configPath = std::filesystem::current_path () / "config.toml";
if (!exists (configPath) || !configPath.has_filename ()) {
LogMessage (LogLevel::WARN, std::string (configPath.string ()) + ": file does not exist");
return false;
}
std::ifstream stream (configPath);
if (!stream.is_open ()) {
LogMessage (LogLevel::WARN, "Could not open " + std::string (configPath.string ()));
return false;
}
auto result = rfl::toml::read<struct globalConfig, rfl::DefaultIfMissing> (stream);
if (result) {
config = result.value ();
bool success = loadKeyBindings ();
if (!success) {
LogMessage (LogLevel::ERROR, "Failed to load keybindings");
MessageBoxA (nullptr, "Failed to load keybindings, check logs for error", nullptr, MB_OK);
ExitProcess (0);
}
isLoaded = true;
return true;
}
auto error = result.error ().value ();
LogMessage (LogLevel::WARN, "Read config failed with error: " + error.what ());
return false;
}
const qrConfig &
ConfigManager::getQrConfig () {
auto result = updateQrConfig ();
if (!result) {
LogMessage (LogLevel::ERROR, "Failed to update QR config");
MessageBoxA (nullptr, "Failed to update QR config", nullptr, MB_OK);
ExitProcess (0);
}
return config.qr;
}
ConfigManager::ConfigManager () {
auto result = loadConfig ();
if (!result) {
LogMessage (LogLevel::ERROR, "Failed to load config file");
MessageBoxA (nullptr, "Failed to load config", nullptr, MB_OK);
ExitProcess (0);
}
}
bool
ConfigManager::loadKeyBindings () {
LogMessage (LogLevel::INFO, "Layout: {}", config.keyboard.jp_layout ? "JP" : "US");
ConfigKeyboardButtons = config.keyboard.jp_layout ? std::map(ConfigKeyboardButtons_JP) : std::map(ConfigKeyboardButtons_US);
const auto configPath = std::filesystem::current_path () / "keyconfig.toml";
if (!exists (configPath) || !configPath.has_filename ()) {
LogMessage (LogLevel::WARN, std::string (configPath.string ()) + ": file does not exist");
return false;
}
std::ifstream stream (configPath);
if (!stream.is_open ()) {
LogMessage (LogLevel::WARN, "Could not open " + std::string (configPath.string ()));
return false;
}
auto result = rfl::toml::read<struct keybindingConfig> (stream);
if (result) {
keyBindings = result.value ();
keyBindings.usingKeyboard = usingKeyboard;
keyBindings.usingMouse = usingMouse;
keyBindings.usingController = usingController;
LogMessage (LogLevel::INFO, "Finish Loading keyconfig.toml useKeyboard={} useMouse={} useController={}",
usingKeyboard ? "true" : "false", usingMouse ? "true" : "false", usingController ? "true" : "false");
return true;
}
auto error = result.error ().value ();
LogMessage (LogLevel::WARN, "Read keybindings failed with error: " + error.what ());
return false;
}
bool
ConfigManager::updateQrConfig () {
const auto configPath = std::filesystem::current_path () / "config.toml";
if (!exists (configPath) || !configPath.has_filename ()) {
LogMessage (LogLevel::WARN, std::string (configPath.string ()) + ": file does not exist");
return false;
}
std::ifstream stream (configPath);
if (!stream.is_open ()) {
LogMessage (LogLevel::WARN, "Could not open " + std::string (configPath.string ()));
return false;
}
auto result = rfl::toml::read<struct qrConfig, rfl::DefaultIfMissing> (stream);
if (result) {
config.qr = result.value ();
return true;
}
auto error = result.error ().value ();
LogMessage (LogLevel::WARN, "Read config failed with error: " + error.what ());
return false;
}
}
template <>
struct rfl::Reflector<Keybindings> {
using ReflType = std::vector<std::string>;
static ConfigValue StringToConfigEnum(const std::string& value) {
ConfigValue ret = {};
if (Config::ConfigManager::ConfigKeyboardButtons.contains (value)) {
usingKeyboard = true;
ret.type = EnumType::keycode;
ret.keycode = Config::ConfigManager::ConfigKeyboardButtons.at (value);
return ret;
}
if (Config::ConfigManager::ConfigControllerButtons.contains (value)) {
usingController = true;
ret.type = EnumType::button;
ret.button = Config::ConfigManager::ConfigControllerButtons.at (value);
return ret;
}
if (Config::ConfigManager::ConfigControllerAXIS.contains (value)) {
usingController = true;
ret.type = EnumType::axis;
ret.axis = Config::ConfigManager::ConfigControllerAXIS.at (value);
return ret;
}
if (Config::ConfigManager::ConfigMouseScroll.contains (value)) {
usingMouse = true;
ret.type = EnumType::scroll;
ret.scroll = Config::ConfigManager::ConfigMouseScroll.at (value);
return ret;
}
LogMessage(LogLevel::ERROR, "Unknown key config value: {}", value);
throw std::exception(std::format ("Unknown key config value: {}", value).c_str());
}
static Keybindings to(const ReflType& value) {
Keybindings result {};
result.buttons.fill (SDL_GAMEPAD_BUTTON_INVALID);
for (const auto& key : value) {
const auto config = StringToConfigEnum(key);
switch (config.type) {
case EnumType::keycode:
LogMessage (LogLevel::DEBUG, "config {} type=keycode value={}", key, static_cast<int>(config.keycode));
for (auto &keycode : result.keycodes) {
if (keycode == 0) {
keycode = config.keycode;
break;
}
}
break;
case EnumType::button:
LogMessage(LogLevel::DEBUG, "config {} type=button value={}", key, static_cast<int>(config.button));
for (auto &button : result.buttons) {
if (button == SDL_GAMEPAD_BUTTON_INVALID) {
button = config.button;
break;
}
}
break;
case EnumType::axis:
LogMessage (LogLevel::DEBUG, "config {} type=axis value={}", key, static_cast<int>(config.axis));
for (auto &axis : result.axis) {
if (axis == SDLAxis::SDL_AXIS_NULL) {
axis = config.axis;
break;
}
}
break;
case EnumType::scroll:
LogMessage (LogLevel::DEBUG, "config {} type=scroll value={}", key, static_cast<int>(config.scroll));
for (auto &scroll : result.scroll) {
if (scroll == Scroll::MOUSE_SCROLL_INVALID) {
scroll = config.scroll;
break;
}
}
break;
case EnumType::none:
default:
throw std::exception("Invalid keybinding type");
}
}
return result;
}
};
+481
View File
@@ -0,0 +1,481 @@
#pragma once
#include <string>
#include <vector>
#include <mutex>
#include <rfl.hpp>
#include "poll.h"
namespace Config {
using chassisIdLimit = rfl::Validator<std::string, rfl::Size<rfl::Maximum<15>>>;
struct amauthConfig {
std::string server = "127.0.0.1";
std::string port = "54430";
chassisIdLimit chassis_id = "284111080000";
std::string shop_id = "TAIKO ARCADE LOADER";
std::string game_ver = "00.00";
std::string country_code = "JPN";
std::string full_address() const {
auto result = server + (port.empty() ? "" : ":" + port);
if (result.size() > 255) {
result.resize(255);
}
return result;
}
std::string place_id() const {
// Truncate to max 15 characters
auto result = country_code + "0FF0";
if (result.size() > 15) {
result.resize(15);
}
return result;
}
};
using patchVersions = rfl::Literal<"auto", "JPN00", "JPN08", "JPN39", "CHN00">;
struct patchesConfig {
patchVersions version{"auto"};
bool unlock_songs = true;
bool local_files = true;
struct chn00Config {
bool fix_language = false;
bool demo_movie = true;
bool mode_collabo025 = false;
bool mode_collabo026 = false;
};
chn00Config chn00;
};
struct emulationConfig {
bool usio = true;
bool card_reader = true;
bool accept_invalid = false;
bool qr = true;
};
struct graphicsConfig {
bool windowed = false;
bool cursor = true;
struct resConfig {
int x = 1920;
int y = 1080;
};
resConfig res;
bool vsync = false;
float model_res_rate = 1.0f;
};
struct audioConfig {
bool real = true;
bool wasapi_shared = true;
bool asio = false;
std::string asio_driver = "ASIO4ALL v2";
};
struct qrConfig {
std::string image_path = "";
struct qrDataConfig {
std::string serial = "";
int type = 0;
std::vector<int> song_no;
};
qrDataConfig data;
};
struct controllerConfig {
int wait_period = 0;
bool analog_input = false;
bool global_keyboard = false;
};
struct keyboardConfig {
bool auto_ime = true;
bool jp_layout = false;
};
struct layeredfsConfig {
bool enabled = false;
};
using logLevels = rfl::Literal<"NONE", "ERROR", "WARN", "INFO", "DEBUG", "HOOKS">;
struct loggingConfig {
logLevels log_level{ "INFO"};
bool log_to_file = true;
std::string log_path = "TaikoArcadeLoader.log";
};
struct globalConfig {
amauthConfig amauth;
patchesConfig patches;
emulationConfig emulation;
graphicsConfig graphics;
audioConfig audio;
qrConfig qr;
controllerConfig controller;
keyboardConfig keyboard;
layeredfsConfig layeredfs;
loggingConfig logging;
};
struct keybindingConfig {
rfl::Rename<"EXIT", Keybindings> exit = Keybindings{.keycodes = {VK_ESCAPE}};
rfl::Rename<"TEST", Keybindings> test = Keybindings{.keycodes = {VK_F1}};
rfl::Rename<"SERVICE", Keybindings> service = Keybindings{.keycodes = {VK_F2}};
rfl::Rename<"DEBUG_UP", Keybindings> debug_up = Keybindings{.keycodes = {VK_UP}};
rfl::Rename<"DEBUG_DOWN", Keybindings> debug_down = Keybindings{.keycodes = {VK_DOWN}};
rfl::Rename<"DEBUG_ENTER", Keybindings> debug_enter = Keybindings{.keycodes = {VK_RETURN}};
rfl::Rename<"COIN_ADD", Keybindings> coin_add = Keybindings{.keycodes = {VK_RETURN}, .buttons = {SDL_GAMEPAD_BUTTON_START}};
rfl::Rename<"CARD_INSERT_1", Keybindings> card_insert_1 = Keybindings{.keycodes = {'P'}};
rfl::Rename<"CARD_INSERT_2", Keybindings> card_insert_2 = Keybindings{.keycodes = {}};
rfl::Rename<"QR_DATA_READ", Keybindings> qr_data_read = Keybindings{.keycodes = {'Q'}};
rfl::Rename<"QR_IMAGE_READ", Keybindings> qr_image_read = Keybindings{.keycodes = {'W'}};
rfl::Rename<"P1_LEFT_BLUE", Keybindings> p1_left_blue = Keybindings{.keycodes = {'D'}, .axis = {SDLAxis::SDL_AXIS_LEFT_DOWN}};
rfl::Rename<"P1_LEFT_RED", Keybindings> p1_left_red = Keybindings{.keycodes = {'F'}, .axis = {SDLAxis::SDL_AXIS_LEFT_RIGHT}};
rfl::Rename<"P1_RIGHT_RED", Keybindings> p1_right_red = Keybindings{.keycodes = {'J'}, .axis = {SDLAxis::SDL_AXIS_RIGHT_RIGHT}};
rfl::Rename<"P1_RIGHT_BLUE", Keybindings> p1_right_blue = Keybindings{.keycodes = {'K'}, .axis = {SDLAxis::SDL_AXIS_RIGHT_DOWN}};
rfl::Rename<"P2_LEFT_BLUE", Keybindings> p2_left_blue = Keybindings{.keycodes = {'Z'}};
rfl::Rename<"P2_LEFT_RED", Keybindings> p2_left_red = Keybindings{.keycodes = {'X'}};
rfl::Rename<"P2_RIGHT_RED", Keybindings> p2_right_red = Keybindings{.keycodes = {'C'}};
rfl::Rename<"P2_RIGHT_BLUE", Keybindings> p2_right_blue = Keybindings{.keycodes = {'V'}};
rfl::Skip<bool> usingKeyboard;
rfl::Skip<bool> usingMouse;
rfl::Skip<bool> usingController;
};
class ConfigManager {
public:
inline static const std::map<std::string, u8> ConfigKeyboardButtons_US = {
// Reference:https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
// Wayback Machine:https://web.archive.org/web/20231223135232/https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
// Row 1
{"ESCAPE", VK_ESCAPE},
{"F1", VK_F1},
{"F2", VK_F2},
{"F3", VK_F3},
{"F4", VK_F4},
{"F5", VK_F5},
{"F6", VK_F6},
{"F7", VK_F7},
{"F8", VK_F8},
{"F9", VK_F9},
{"F10", VK_F10},
{"F11", VK_F11},
{"F12", VK_F12},
// Row 2
{"`", VK_OEM_3},
{"1", '1'},
{"2", '2'},
{"3", '3'},
{"4", '4'},
{"5", '5'},
{"6", '6'},
{"7", '7'},
{"8", '8'},
{"9", '9'},
{"0", '0'},
{"-", VK_OEM_MINUS},
{"=", VK_OEM_PLUS},
{"BACKSPACE", VK_BACK},
// Row 3
{"TAB", VK_TAB},
{"Q", 'Q'},
{"W", 'W'},
{"E", 'E'},
{"R", 'R'},
{"T", 'T'},
{"Y", 'Y'},
{"U", 'U'},
{"I", 'I'},
{"O", 'O'},
{"P", 'P'},
{"[", VK_OEM_4},
{"]", VK_OEM_6},
{"BACKSLASH", VK_OEM_5},
// Row 4
{"CAPS_LOCK", VK_CAPITAL},
{"A", 'A'},
{"S", 'S'},
{"D", 'D'},
{"F", 'F'},
{"G", 'G'},
{"H", 'H'},
{"J", 'J'},
{"K", 'K'},
{"L", 'L'},
{";", VK_OEM_1},
{"'", VK_OEM_7},
{"ENTER", VK_RETURN},
// Row 5
{"SHIFT", VK_SHIFT},
{"Z", 'Z'},
{"X", 'X'},
{"C", 'C'},
{"V", 'V'},
{"B", 'B'},
{"N", 'N'},
{"M", 'M'},
{",", VK_OEM_COMMA},
{".", VK_OEM_PERIOD},
{"SLASH", VK_OEM_2},
// Row 6
{"CONTROL", VK_CONTROL},
{"L_WIN", VK_LWIN},
{"ALT", VK_MENU},
{"SPACE", VK_SPACE},
{"R_WIN", VK_RWIN},
{"MENU", VK_APPS},
// Other Keys
// PrtSc is more important when making snapshots, therefore comment it as reserved
//{"PRINT_SCREEN", VK_SNAPSHOT},
{"SCROLL_LOCK", VK_SCROLL},
{"PAUSE", VK_PAUSE},
{"INSERT", VK_INSERT},
{"DELETE", VK_DELETE},
{"HOME", VK_HOME},
{"END", VK_END},
{"PAGE_UP", VK_PRIOR},
{"PAGE_DOWN", VK_NEXT},
// Arrow Keys
{"UPARROW", VK_UP},
{"LEFTARROW", VK_LEFT},
{"DOWNARROW", VK_DOWN},
{"RIGHTARROW", VK_RIGHT},
// NUMPAD Keys
{"NUM_LOCK", VK_NUMLOCK},
{"DIVIDE", VK_DIVIDE},
{"MULTIPLY", VK_MULTIPLY},
{"SUBTRACT", VK_SUBTRACT},
{"NUM7", VK_NUMPAD7},
{"NUM8", VK_NUMPAD8},
{"NUM9", VK_NUMPAD9},
{"ADD", VK_ADD},
{"NUM4", VK_NUMPAD4},
{"NUM5", VK_NUMPAD5},
{"NUM6", VK_NUMPAD6},
{"NUM1", VK_NUMPAD1},
{"NUM2", VK_NUMPAD2},
{"NUM3", VK_NUMPAD3},
{"NUM0", VK_NUMPAD0},
{"DECIMAL", VK_DECIMAL},
};
inline static const std::map<std::string, u8> ConfigKeyboardButtons_JP = {
// Reference:https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
// Wayback Machine:https://web.archive.org/web/20231223135232/https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
// Row 1
{"ESCAPE", VK_ESCAPE},
{"F1", VK_F1},
{"F2", VK_F2},
{"F3", VK_F3},
{"F4", VK_F4},
{"F5", VK_F5},
{"F6", VK_F6},
{"F7", VK_F7},
{"F8", VK_F8},
{"F9", VK_F9},
{"F10", VK_F10},
{"F11", VK_F11},
{"F12", VK_F12},
// Row 2
{"1", '1'},
{"2", '2'},
{"3", '3'},
{"4", '4'},
{"5", '5'},
{"6", '6'},
{"7", '7'},
{"8", '8'},
{"9", '9'},
{"0", '0'},
{"-", VK_OEM_MINUS},
{"^", VK_OEM_7},
{"YEN", VK_OEM_5},
{"BACKSPACE", VK_BACK},
// Row 3
{"TAB", VK_TAB},
{"Q", 'Q'},
{"W", 'W'},
{"E", 'E'},
{"R", 'R'},
{"T", 'T'},
{"Y", 'Y'},
{"U", 'U'},
{"I", 'I'},
{"O", 'O'},
{"P", 'P'},
{"@", VK_OEM_3},
{"[", VK_OEM_4},
// Row 4
{"CAPS_LOCK", VK_CAPITAL},
{"A", 'A'},
{"S", 'S'},
{"D", 'D'},
{"F", 'F'},
{"G", 'G'},
{"H", 'H'},
{"J", 'J'},
{"K", 'K'},
{"L", 'L'},
{";", VK_OEM_PLUS},
{":", VK_OEM_1},
{"]", VK_OEM_6},
{"ENTER", VK_RETURN},
// Row 5
{"SHIFT", VK_SHIFT},
{"Z", 'Z'},
{"X", 'X'},
{"C", 'C'},
{"V", 'V'},
{"B", 'B'},
{"N", 'N'},
{"M", 'M'},
{",", VK_OEM_COMMA},
{".", VK_OEM_PERIOD},
{"SLASH", VK_OEM_2},
{"BACKSLASH", VK_OEM_102},
// Row 6
{"CONTROL", VK_CONTROL},
{"L_WIN", VK_LWIN},
{"ALT", VK_MENU},
{"SPACE", VK_SPACE},
{"R_WIN", VK_RWIN},
{"MENU", VK_APPS},
// Other Keys
// PrtSc is more important when making snapshots, therefore comment it as reserved
//{"PRINT_SCREEN", VK_SNAPSHOT},
{"SCROLL_LOCK", VK_SCROLL},
{"PAUSE", VK_PAUSE},
{"INSERT", VK_INSERT},
{"DELETE", VK_DELETE},
{"HOME", VK_HOME},
{"END", VK_END},
{"PAGE_UP", VK_PRIOR},
{"PAGE_DOWN", VK_NEXT},
// Arrow Keys
{"UPARROW", VK_UP},
{"LEFTARROW", VK_LEFT},
{"DOWNARROW", VK_DOWN},
{"RIGHTARROW", VK_RIGHT},
// NUMPAD Keys
{"NUM_LOCK", VK_NUMLOCK},
{"DIVIDE", VK_DIVIDE},
{"MULTIPLY", VK_MULTIPLY},
{"SUBTRACT", VK_SUBTRACT},
{"NUM7", VK_NUMPAD7},
{"NUM8", VK_NUMPAD8},
{"NUM9", VK_NUMPAD9},
{"ADD", VK_ADD},
{"NUM4", VK_NUMPAD4},
{"NUM5", VK_NUMPAD5},
{"NUM6", VK_NUMPAD6},
{"NUM1", VK_NUMPAD1},
{"NUM2", VK_NUMPAD2},
{"NUM3", VK_NUMPAD3},
{"NUM0", VK_NUMPAD0},
{"DECIMAL", VK_DECIMAL},
};
inline static std::map<std::string, u8> ConfigKeyboardButtons{};
inline static const std::map<std::string, SDL_GamepadButton> ConfigControllerButtons = {
{"SDL_A", SDL_GAMEPAD_BUTTON_SOUTH},
{"SDL_B", SDL_GAMEPAD_BUTTON_EAST},
{"SDL_X", SDL_GAMEPAD_BUTTON_WEST},
{"SDL_Y", SDL_GAMEPAD_BUTTON_NORTH},
{"SDL_BACK", SDL_GAMEPAD_BUTTON_BACK},
{"SDL_GUIDE", SDL_GAMEPAD_BUTTON_GUIDE},
{"SDL_START", SDL_GAMEPAD_BUTTON_START},
{"SDL_LSTICK_PRESS", SDL_GAMEPAD_BUTTON_LEFT_STICK},
{"SDL_RSTICK_PRESS", SDL_GAMEPAD_BUTTON_RIGHT_STICK},
{"SDL_LSHOULDER", SDL_GAMEPAD_BUTTON_LEFT_SHOULDER},
{"SDL_RSHOULDER", SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER},
{"SDL_DPAD_UP", SDL_GAMEPAD_BUTTON_DPAD_UP},
{"SDL_DPAD_DOWN", SDL_GAMEPAD_BUTTON_DPAD_DOWN},
{"SDL_DPAD_LEFT", SDL_GAMEPAD_BUTTON_DPAD_LEFT},
{"SDL_DPAD_RIGHT", SDL_GAMEPAD_BUTTON_DPAD_RIGHT},
{"SDL_MISC", SDL_GAMEPAD_BUTTON_MISC1},
{"SDL_PADDLE1", SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1},
{"SDL_PADDLE2", SDL_GAMEPAD_BUTTON_LEFT_PADDLE1},
{"SDL_PADDLE3", SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2},
{"SDL_PADDLE4", SDL_GAMEPAD_BUTTON_LEFT_PADDLE2},
{"SDL_TOUCHPAD", SDL_GAMEPAD_BUTTON_TOUCHPAD},
};
inline static const std::map<std::string, SDLAxis> ConfigControllerAXIS = {
{"SDL_LSTICK_LEFT", SDLAxis::SDL_AXIS_LEFT_LEFT}, {"SDL_LSTICK_UP", SDLAxis::SDL_AXIS_LEFT_UP}, {"SDL_LSTICK_DOWN", SDLAxis::SDL_AXIS_LEFT_DOWN},
{"SDL_LSTICK_RIGHT", SDLAxis::SDL_AXIS_LEFT_RIGHT}, {"SDL_RSTICK_LEFT", SDLAxis::SDL_AXIS_RIGHT_LEFT}, {"SDL_RSTICK_UP", SDLAxis::SDL_AXIS_RIGHT_UP},
{"SDL_RSTICK_DOWN", SDLAxis::SDL_AXIS_RIGHT_DOWN}, {"SDL_RSTICK_RIGHT", SDLAxis::SDL_AXIS_RIGHT_RIGHT}, {"SDL_LTRIGGER", SDLAxis::SDL_AXIS_LTRIGGER_DOWN},
{"SDL_RTRIGGER", SDLAxis::SDL_AXIS_RTRIGGER_DOWN},
};
inline static const std::map<std::string, Scroll> ConfigMouseScroll = {
{"SCROLL_UP", Scroll::MOUSE_SCROLL_UP},
{"SCROLL_DOWN", Scroll::MOUSE_SCROLL_DOWN},
};
// Singleton pattern for global access
static ConfigManager& instance() {
static ConfigManager instance; // Guaranteed to be destroyed, instantiated on first use
return instance;
}
static bool validateConfigfile(std::string path);
// Load configuration from a file (deserialization happens here)
bool loadConfig();
// Accessor methods
const globalConfig& getConfig() const { return config; }
// To access specific parts of the config
const amauthConfig& getAmauthConfig() const { return config.amauth; }
const patchesConfig& getPatchesConfig() const { return config.patches; }
const emulationConfig& getEmulationConfig() const { return config.emulation; }
const graphicsConfig& getGraphicsConfig() const { return config.graphics; }
const audioConfig& getAudioConfig() const { return config.audio; }
const qrConfig& getQrConfig();
const controllerConfig& getControllerConfig() const { return config.controller; }
const keyboardConfig& getKeyboardConfig() const { return config.keyboard; }
const layeredfsConfig& getLayeredFsConfig() const { return config.layeredfs; }
const loggingConfig& getLoggingConfig() const { return config.logging; }
const keybindingConfig& getKeyBindings() const { return keyBindings; }
private:
ConfigManager();
~ConfigManager() = default;
// Prevent copy/move
ConfigManager(const ConfigManager&) = delete;
ConfigManager& operator=(const ConfigManager&) = delete;
bool loadKeyBindings();
bool updateQrConfig();
globalConfig config;
keybindingConfig keyBindings;
bool isLoaded;
// Mutex for thread safety (if needed)
mutable std::mutex mutex;
};
}
+21
View File
@@ -0,0 +1,21 @@
#include <string>
#include <iostream>
#include "config.h"
int main(int argc, char **argv) {
if (argc < 2) {
std::cerr << "Usage: " << argv[0] << " <config file>" << std::endl;
return 1;
}
std::string fullPath = argv[1];
if (!Config::ConfigManager::validateConfigfile(fullPath)) {
std::cerr << "Config file is invalid" << std::endl;
return 1;
}
std::cout << "Config file is valid" << std::endl;
return 0;
}
+28 -25
View File
@@ -4,6 +4,7 @@
#include "patches/patches.h"
#include "poll.h"
#include "logger.h"
#include "config.h"
#include <dbghelp.h>
auto gameVersion = GameVersion::UNKNOWN;
@@ -11,35 +12,36 @@ std::vector<HMODULE> plugins;
u64 song_data_size = 1024 * 1024 * 64;
void *song_data;
std::string server = "127.0.0.1";
/*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] = {};
char placeId[16] = {};
char placeId[16] = {};*/
char accessCode1[21] = "00000000000000000001";
char accessCode2[21] = "00000000000000000002";
char chipId1[33] = "00000000000000000000000000000001";
char chipId2[33] = "00000000000000000000000000000002";
bool windowed = false;
bool autoIme = true;
bool jpLayout = false;
bool cursor = true;
bool emulateUsio = true;
bool emulateCardReader = true;
bool emulateQr = true;
bool acceptInvalidCards = false;
bool localFiles = true;
HKL currentLayout = nullptr;
i32 xRes = 1920;
i32 yRes = 1080;
bool vsync = false;
bool windowed = Config::ConfigManager::instance ().getGraphicsConfig ().windowed;
bool autoIme = Config::ConfigManager::instance ().getKeyboardConfig ().auto_ime;
bool jpLayout = Config::ConfigManager::instance ().getKeyboardConfig ().jp_layout;
bool cursor = Config::ConfigManager::instance ().getGraphicsConfig ().cursor;
bool emulateUsio = Config::ConfigManager::instance ().getEmulationConfig ().usio;
bool emulateCardReader = Config::ConfigManager::instance ().getEmulationConfig ().card_reader;
bool emulateQr = Config::ConfigManager::instance ().getEmulationConfig ().qr;
bool acceptInvalidCards = Config::ConfigManager::instance ().getEmulationConfig ().accept_invalid;
bool localFiles = Config::ConfigManager::instance ().getPatchesConfig ().local_files;
std::string logLevelStr = "INFO";
bool logToFile = true;
std::string logPath = "TaikoArcadeLoader.log";
HKL currentLayout = nullptr;
i32 xRes = Config::ConfigManager::instance ().getGraphicsConfig ().res.x;
i32 yRes = Config::ConfigManager::instance ().getGraphicsConfig ().res.y;
bool vsync = Config::ConfigManager::instance ().getGraphicsConfig ().vsync;
std::string logLevelStr = Config::ConfigManager::instance ().getLoggingConfig ().log_level.name ();
bool logToFile = Config::ConfigManager::instance ().getLoggingConfig ().log_to_file;
std::string logPath = Config::ConfigManager::instance ().getLoggingConfig ().log_path;
HWND hGameWnd;
FAST_HOOK (i32, ShowMouse, PROC_ADDRESS ("user32.dll", "ShowCursor"), bool) { return originalShowMouse.stdcall<i32> (true); }
@@ -64,7 +66,7 @@ FAST_HOOK (HWND, CreateWindow, PROC_ADDRESS ("user32.dll", "CreateWindowExW"), D
i32 X, i32 Y, i32 nWidth, i32 nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam) {
if (lpWindowName != nullptr) {
if (wcscmp (lpWindowName, L"Taiko") == 0) {
if (windowed) dwStyle = WS_TILEDWINDOW ^ WS_MAXIMIZEBOX ^ WS_THICKFRAME;
if (Config::ConfigManager::instance ().getGraphicsConfig ().windowed) dwStyle = WS_TILEDWINDOW ^ WS_MAXIMIZEBOX ^ WS_THICKFRAME;
hGameWnd
= originalCreateWindow.stdcall<HWND> (dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
@@ -99,12 +101,12 @@ FAST_HOOK (i32, ssleay_Shutdown, PROC_ADDRESS ("ssleay32.dll", "SSL_shutdown"))
FAST_HOOK (i64, UsbFinderInitialize, PROC_ADDRESS ("nbamUsbFinder.dll", "nbamUsbFinderInitialize")) { return 0; }
FAST_HOOK (i64, UsbFinderRelease, PROC_ADDRESS ("nbamUsbFinder.dll", "nbamUsbFinderRelease")) { return 0; }
FAST_HOOK (i64, UsbFinderGetSerialNumber, PROC_ADDRESS ("nbamUsbFinder.dll", "nbamUsbFinderGetSerialNumber"), i32 a1, char *a2) {
strcpy (a2, chassisId.c_str ());
strcpy (a2, Config::ConfigManager::instance ().getAmauthConfig ().chassis_id.value ().c_str ());
return 0;
}
FAST_HOOK (i32, ws2_getaddrinfo, PROC_ADDRESS ("ws2_32.dll", "getaddrinfo"), const char *node, char *service, void *hints, void *out) {
return originalws2_getaddrinfo.stdcall<i32> (server.c_str (), service, hints, out);
return originalws2_getaddrinfo.stdcall<i32> (Config::ConfigManager::instance ().getAmauthConfig ().server.c_str (), service, hints, out);
}
void
@@ -176,10 +178,10 @@ DllMain (HMODULE module, const DWORD reason, LPVOID reserved) {
InitializeLogger (GetLogLevel (logLevelStr), logToFile, logPath);
patches::Timer::Init ();
LogMessage (LogLevel::INFO, "Loading config...");
// LogMessage (LogLevel::INFO, "Loading config...");
std::string version = "auto";
const std::filesystem::path configPath = std::filesystem::current_path () / "config.toml";
std::string version = Config::ConfigManager::instance ().getPatchesConfig ().version.name ();
/*const std::filesystem::path configPath = std::filesystem::current_path () / "config.toml";
const std::unique_ptr<toml_table_t, void (*) (toml_table_t *)> config_ptr (openConfig (configPath), toml_free);
if (config_ptr) {
const toml_table_t *config = config_ptr.get ();
@@ -229,7 +231,7 @@ DllMain (HMODULE module, const DWORD reason, LPVOID reserved) {
logToFile = readConfigBool (logging, "log_to_file", logToFile);
logPath = readConfigString (logging, "log_path", logPath);
}
}
}*/
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_UNAWARE);
auto activeWindow = GetActiveWindow();
@@ -263,6 +265,7 @@ DllMain (HMODULE module, const DWORD reason, LPVOID reserved) {
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);
}
Config::ConfigManager::instance ().setRes (xRes, yRes);
LogMessage (LogLevel::INFO, "Scale Rate: x={} y={}", horizontalScale, verticalScale);
LogMessage (LogLevel::INFO, "Boot with {} mode ({}x{})", windowed ? "window" : "fullscreen", xRes, yRes);
+2 -2
View File
@@ -1,7 +1,7 @@
#include <codecvt>
#include "helpers.h"
static void
/*static void
toml_myfree (void *p) {
if (p) free (p);
}
@@ -108,7 +108,7 @@ readConfigIntArray (const toml_table_t *table, const std::string &key, std::vect
}
return ret;
}
}*/
std::wstring
replace (const std::wstring orignStr, const std::wstring &oldStr, const std::wstring &newStr) {
+2 -4
View File
@@ -9,9 +9,7 @@
// ReSharper disable once CppUnusedIncludeDirective
#include <MinHook.h>
#include <string>
#include <toml.h>
#include <windows.h>
#include <map>
#include <functional>
#include "constants.h"
#include "logger.h"
@@ -168,13 +166,13 @@ const HMODULE MODULE_HANDLE = GetModuleHandle (nullptr);
#define round(num) ((num > 0) ? (int)(num + 0.5) : (int)(num - 0.5))
#define timestamp() (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now ().time_since_epoch ()).count ())
toml_table_t *openConfig (const std::filesystem::path &path);
/*toml_table_t *openConfig (const std::filesystem::path &path);
toml_table_t *openConfigSection (const toml_table_t *config, const std::string &sectionName);
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 &notFoundValue);
std::vector<i64> readConfigIntArray (const toml_table_t *table, const std::string &key, std::vector<i64> notFoundValue);
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);
std::string replace (const std::string orignStr, const std::string &oldStr, const std::string &newStr);
const char *GameVersionToString (GameVersion version);
+19 -19
View File
@@ -1,22 +1,22 @@
#include <winsock2.h>
#include "helpers.h"
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <ws2tcpip.h>
#include "config.h"
/*
* Reference: https://gitea.tendokyu.moe/Hay1tsme/bananatools/src/branch/master/amcus/iauth.c
* https://github.com/BroGamer4256/TaikoArcadeLoader/blob/master/plugins/amauth/dllmain.cpp
*/
extern std::string server;
extern std::string chassisId;
extern std::string shopId;
extern std::string gameVerNum;
extern std::string countryCode;
extern char fullAddress[256];
extern char placeId[16];
static std::string server = Config::ConfigManager::instance ().getAmauthConfig ().server;
static std::string chassisId = Config::ConfigManager::instance ().getAmauthConfig ().chassis_id.value ();
static std::string shopId = Config::ConfigManager::instance ().getAmauthConfig ().shop_id;
static std::string gameVerNum = Config::ConfigManager::instance ().getAmauthConfig ().game_ver;
static std::string countryCode = Config::ConfigManager::instance ().getAmauthConfig ().country_code;
static std::string fullAddress = Config::ConfigManager::instance ().getAmauthConfig ().full_address();
static std::string placeId = Config::ConfigManager::instance ().getAmauthConfig ().place_id();
namespace patches::AmAuth {
@@ -379,10 +379,10 @@ public:
strcpy_s (version->game_id, "SBWY");
strcpy_s (version->game_ver, "12.20");
strcpy_s (version->game_cd, "S121");
strcpy_s (version->cacfg_game_ver, gameVerNum.c_str ());
strcpy_s (version->cacfg_game_ver, sizeof(version->cacfg_game_ver), gameVerNum.c_str ());
strcpy_s (version->game_board_type, "0");
strcpy_s (version->game_board_id, "PCB");
strcpy_s (version->auth_url, fullAddress);
strcpy_s (version->auth_url, sizeof(version->auth_url), fullAddress.c_str ());
return 0;
}
@@ -392,11 +392,11 @@ public:
virtual i32 IAuth_GetAuthServerResp (amcus_auth_server_resp_t *resp) {
memset (resp, 0, sizeof (*resp));
strcpy_s (resp->uri, fullAddress);
strcpy_s (resp->host, fullAddress);
strcpy_s (resp->uri, sizeof(resp->uri) , fullAddress.c_str ());
strcpy_s (resp->host, sizeof(resp->host), fullAddress.c_str ());
strcpy_s (resp->shop_name, shopId.c_str ());
strcpy_s (resp->shop_nickname, shopId.c_str ());
strcpy_s (resp->shop_name, sizeof(resp->shop_name), shopId.c_str ());
strcpy_s (resp->shop_nickname, sizeof(resp->shop_nickname), shopId.c_str ());
strcpy_s (resp->region0, "01035");
@@ -404,9 +404,9 @@ public:
strcpy_s (resp->region_name1, "X");
strcpy_s (resp->region_name2, "Y");
strcpy_s (resp->region_name3, "Z");
strcpy_s (resp->place_id, placeId);
strcpy_s (resp->place_id, sizeof(resp->place_id), placeId.c_str ());
strcpy_s (resp->setting, "");
strcpy_s (resp->country, countryCode.c_str ());
strcpy_s (resp->country, sizeof(resp->country), countryCode.c_str ());
strcpy_s (resp->timezone, "+0900");
strcpy_s (resp->res_class, "PowerOnResponseVer3");
return 0;
@@ -424,7 +424,7 @@ public:
strcpy_s (arr->shop_name_en, sizeof (arr->shop_name_en), shopId.c_str ());
strcpy_s (arr->shop_nickname, sizeof (arr->shop_nickname), shopId.c_str ());
strcpy_s (arr->shop_nickname_en, sizeof (arr->shop_nickname_en), shopId.c_str ());
strcpy_s (arr->place_id, sizeof (arr->place_id), placeId);
strcpy_s (arr->place_id, sizeof (arr->place_id), placeId.c_str ());
strcpy_s (arr->country_cd, sizeof (arr->country_cd), countryCode.c_str ());
strcpy_s (arr->area0, sizeof (arr->area0), "008");
@@ -447,8 +447,8 @@ public:
strcpy_s (arr->url_charge, sizeof (arr->url_charge), "http://127.0.0.1/charge/");
strcpy_s (arr->url_file, sizeof (arr->url_file), "http://127.0.0.1/file/");
strcpy_s (arr->url_url1, sizeof (arr->url_url1), fullAddress);
strcpy_s (arr->url_url2, sizeof (arr->url_url2), fullAddress);
strcpy_s (arr->url_url1, sizeof (arr->url_url1), fullAddress.c_str ());
strcpy_s (arr->url_url2, sizeof (arr->url_url2), fullAddress.c_str ());
strcpy_s (arr->url_url3, sizeof (arr->url_url3), "http://127.0.0.1/url3/");
return 0;
}
+8 -8
View File
@@ -1,6 +1,7 @@
#include "constants.h"
#include "helpers.h"
#include "patches.h"
#include "config.h"
#include "../Windows/MinimumLatencyAudioClient.h"
extern GameVersion gameVersion;
@@ -19,10 +20,10 @@ typedef struct nusc_init_config {
void *wasapi_audioSes;
} nusc_init_config_t;
bool real = true;
bool wasapiShared = true;
bool asio = false;
std::string asioDriver;
bool wasapiShared = Config::ConfigManager::instance ().getAudioConfig ().wasapi_shared;
bool asio = Config::ConfigManager::instance ().getAudioConfig ().asio;
std::string asioDriver = Config::ConfigManager::instance ().getAudioConfig ().asio_driver;
bool real = Config::ConfigManager::instance ().getAudioConfig ().real;
float volumeRate = 0.0f;
@@ -54,7 +55,7 @@ FAST_HOOK_DYNAMIC (u64, NuscBusVolume, u64 a1, u64 a2, float a3) {
}
void
SetVolumeRate (float rate) {
SetVolumeRate (const float rate) {
volumeRate = rate;
}
@@ -78,17 +79,16 @@ void
Init () {
LogMessage (LogLevel::INFO, "Init Audio patches");
const auto configPath = std::filesystem::current_path () / "config.toml";
/*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);
if (config_ptr) {
if (const auto audio = openConfigSection (config_ptr.get (), "audio")) {
real = readConfigBool (audio, "real", real);
wasapiShared = readConfigBool (audio, "wasapi_shared", wasapiShared);
asio = readConfigBool (audio, "asio", asio);
asioDriver = readConfigString (audio, "asio_driver", asioDriver);
}
}
}*/
if (real) ReduceAudioLatency ();
+2 -1
View File
@@ -1,7 +1,8 @@
#include "constants.h"
#include "helpers.h"
#include "patches.h"
#include <emmintrin.h>
#include <map>
extern GameVersion gameVersion;
+4 -3
View File
@@ -2,8 +2,9 @@
#include "helpers.h"
#include <tomcrypt.h>
#include <zlib.h>
#include "config.h"
bool useLayeredFs = false;
bool useLayeredFs = Config::ConfigManager::instance ().getLayeredFsConfig ().enabled;
std::string datatableKey = "3530304242323633353537423431384139353134383346433246464231354534";
std::string fumenKey = "4434423946383537303842433443383030333843444132343339373531353830";
@@ -285,12 +286,12 @@ FAST_HOOK (HANDLE, CreateFileAHook, PROC_ADDRESS ("kernel32.dll", "CreateFileA")
void
Init () {
const auto configPath = std::filesystem::current_path () / "config.toml";
/*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);
if (config_ptr) {
if (const auto layeredFs = openConfigSection (config_ptr.get (), "layeredfs"))
useLayeredFs = readConfigBool (layeredFs, "enabled", useLayeredFs);
}
}*/
register_cipher (&aes_desc);
if (useLayeredFs || !beforeHandlers.empty () || !afterHandlers.empty ()) {
LogMessage (LogLevel::INFO, "using LayeredFs! Data_mods={} beforHandlers={} afterHandlers={}",
+10 -27
View File
@@ -12,12 +12,13 @@
#define STB_IMAGE_IMPLEMENTATION
#define STBI_WINDOWS_UTF8
#include "stb_image.h"
#include "config.h"
extern GameVersion gameVersion;
extern std::vector<HMODULE> plugins;
extern bool acceptInvalidCards;
extern bool emulateCardReader;
extern bool emulateQr;
static bool acceptInvalidCards = Config::ConfigManager::instance ().getEmulationConfig ().accept_invalid;
static bool emulateCardReader = Config::ConfigManager::instance ().getEmulationConfig ().card_reader;
static bool emulateQr = Config::ConfigManager::instance ().getEmulationConfig ().qr;
extern char accessCode1[21];
extern char accessCode2[21];
extern char chipId1[33];
@@ -384,24 +385,12 @@ namespace Qr {
std::vector<uint8_t> &
ReadQRData (std::vector<uint8_t> &buffer) {
std::string serial = "";
u16 type = 0;
std::vector<i64> songNoes;
std::string serial = Config::ConfigManager::instance ().getQrConfig ().data.serial;
u16 type = Config::ConfigManager::instance ().getQrConfig ().data.type;
std::vector<int> songNoes = Config::ConfigManager::instance ().getQrConfig ().data.song_no;
buffer.clear ();
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) {
auto qr = openConfigSection (config_ptr.get (), "qr");
if (qr) {
auto data = openConfigSection (qr, "data");
if (data) {
serial = readConfigString (data, "serial", "");
type = (u16) readConfigInt (data, "type", 0);
songNoes = readConfigIntArray (data, "song_no", songNoes);
}
}
}
std::vector<uint8_t> header = { 0x53, 0x31, 0x32, 0x00, 0x00, 0xFF, 0xFF, (uint8_t)serial.size (), 0x01, 0x00 };
for (uint8_t byte_data : header) buffer.push_back (byte_data);
for (char word : serial) buffer.push_back ((uint8_t)word);
@@ -420,18 +409,12 @@ namespace Qr {
std::vector<uint8_t> &
ReadQRImage (std::vector<uint8_t> &buffer) {
std::string imagePath = "";
std::string imagePath = Config::ConfigManager::instance ().getQrConfig ().image_path;
buffer.clear ();
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) {
auto qr = openConfigSection (config_ptr.get (), "qr");
if (qr) imagePath = readConfigString (qr, "image_path", "");
}
std::u8string u8PathStr (imagePath.begin (), imagePath.end ());
std::filesystem::path u8Path (u8PathStr);
if (!std::filesystem::is_regular_file (u8Path)) {
if (!is_regular_file (u8Path)) {
LogMessage (LogLevel::ERROR, "Failed to open image: {} (file not found)", u8Path.string());
return buffer;
}
+2 -1
View File
@@ -4,6 +4,7 @@
#include <exception>
#include <format>
#include <queue>
#include <map>
extern GameVersion gameVersion;
@@ -270,7 +271,7 @@ std::wstring
replaceFileName (std::wstring fullFileName, std::wstring usingLastFileName) {
size_t lastPosition = fullFileName.find_last_of (L"/");
if (lastPosition == -1) return usingLastFileName;
else return fullFileName.substr(0, lastPosition) + usingLastFileName;
else return fullFileName.substr(0, lastPosition + 1) + usingLastFileName;
}
FAST_HOOK_DYNAMIC (void, TestModeSetMenuHook, u64 testModeLibrary, const wchar_t *lFileName) {
+13 -12
View File
@@ -1,11 +1,12 @@
#include "helpers.h"
#include "../patches.h"
#include "config.h"
extern std::string chassisId;
extern i32 xRes;
extern i32 yRes;
extern bool vsync;
extern bool localFiles;
static std::string chassisId = Config::ConfigManager::instance ().getAmauthConfig ().chassis_id.value ();
static const i32& xRes = Config::ConfigManager::instance ().getGraphicsConfig ().res.x;
static const i32& yRes = Config::ConfigManager::instance ().getGraphicsConfig ().res.y;
static bool vsync = Config::ConfigManager::instance ().getGraphicsConfig ().vsync;
static bool localFiles = Config::ConfigManager::instance ().getPatchesConfig ().local_files;
namespace patches::CHN00 {
int language = 0;
@@ -105,11 +106,11 @@ ReplaceLeaBufferAddress (const std::vector<uintptr_t> &bufferAddresses, void *ne
void
Init () {
LogMessage (LogLevel::INFO, "Init CHN00 patches");
bool unlockSongs = true;
bool fixLanguage = false;
bool demoMovie = true;
bool modeCollabo025 = false;
bool modeCollabo026 = false;
bool unlockSongs = Config::ConfigManager::instance ().getPatchesConfig ().unlock_songs;
bool fixLanguage = Config::ConfigManager::instance ().getPatchesConfig ().chn00.fix_language;
bool demoMovie = Config::ConfigManager::instance ().getPatchesConfig ().chn00.demo_movie;
bool modeCollabo025 = Config::ConfigManager::instance ().getPatchesConfig ().chn00.mode_collabo025;
bool modeCollabo026 = Config::ConfigManager::instance ().getPatchesConfig ().chn00.mode_collabo026;
haspBuffer = static_cast<u8 *> (malloc (0xD40));
memset (haspBuffer, 0, 0xD40);
@@ -128,7 +129,7 @@ Init () {
INSTALL_HOOK (HaspGetInfo);
INSTALL_HOOK (HaspRead);
const auto configPath = std::filesystem::current_path () / "config.toml";
/*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);
if (config_ptr) {
if (const auto patches = openConfigSection (config_ptr.get (), "patches")) {
@@ -140,7 +141,7 @@ Init () {
modeCollabo026 = readConfigBool (chn00, "mode_collabo026", modeCollabo026);
}
}
}
}*/
// Apply common config patch
WRITE_MEMORY (ASLR (0x1404A4ED3), i32, xRes);
+8 -8
View File
@@ -1,11 +1,11 @@
#include "helpers.h"
#include "../patches.h"
#include "config.h"
extern i32 xRes;
extern i32 yRes;
extern bool vsync;
extern bool localFiles;
static const i32& xRes = Config::ConfigManager::instance ().getGraphicsConfig ().res.x;
static const i32& yRes = Config::ConfigManager::instance ().getGraphicsConfig ().res.y;
static bool vsync = Config::ConfigManager::instance ().getGraphicsConfig ().vsync;
static bool localFiles = Config::ConfigManager::instance ().getPatchesConfig ().local_files;
namespace patches::JPN00 {
HOOK_DYNAMIC (char, AMFWTerminate, i64) { return 0; }
@@ -42,14 +42,14 @@ ReplaceLeaBufferAddress (const std::vector<uintptr_t> &bufferAddresses, void *ne
void
Init () {
LogMessage (LogLevel::INFO, "Init JNP00 patches");
bool unlockSongs = true;
bool unlockSongs = Config::ConfigManager::instance ().getPatchesConfig ().unlock_songs;
const auto configPath = std::filesystem::current_path () / "config.toml";
/*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);
if (config_ptr) {
if (const auto patches = openConfigSection (config_ptr.get (), "patches"))
unlockSongs = readConfigBool (patches, "unlock_songs", unlockSongs);
}
}*/
// Apply common config patch
WRITE_MEMORY (ASLR (0x140224B2B), i32, xRes);
+8 -8
View File
@@ -1,13 +1,13 @@
#include "helpers.h"
#include "../patches.h"
#include "config.h"
extern u64 song_data_size;
extern void *song_data;
extern i32 xRes;
extern i32 yRes;
extern bool vsync;
extern bool localFiles;
static const i32& xRes = Config::ConfigManager::instance ().getGraphicsConfig ().res.x;
static const i32& yRes = Config::ConfigManager::instance ().getGraphicsConfig ().res.y;
static bool vsync = Config::ConfigManager::instance ().getGraphicsConfig ().vsync;
static bool localFiles = Config::ConfigManager::instance ().getPatchesConfig ().local_files;
#define RDX_MOV 0x48, 0xBA
#define R8_MOV 0x49, 0xB8
#define GENERATE_MOV(instruction, location) \
@@ -52,13 +52,13 @@ ReplaceLeaBufferAddress (const std::vector<uintptr_t> &bufferAddresses, void *ne
void
Init () {
LogMessage (LogLevel::INFO, "Init JPN08 patches");
bool unlockSongs = true;
bool unlockSongs = Config::ConfigManager::instance ().getPatchesConfig ().unlock_songs;
auto configPath = std::filesystem::current_path () / "config.toml";
/*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);
}
}*/
// Apply common config patch
WRITE_MEMORY (ASLR (0x14035FC5B), i32, xRes);
+9 -8
View File
@@ -2,11 +2,12 @@
#include "helpers.h"
#include "../patches.h"
#include <map>
#include "config.h"
extern i32 xRes;
extern i32 yRes;
extern bool vsync;
extern bool localFiles;
static const i32& xRes = Config::ConfigManager::instance ().getGraphicsConfig ().res.x;
static const i32& yRes = Config::ConfigManager::instance ().getGraphicsConfig ().res.y;
static bool vsync = Config::ConfigManager::instance ().getGraphicsConfig ().vsync;
static bool localFiles = Config::ConfigManager::instance ().getPatchesConfig ().local_files;
namespace patches::JPN39 {
int language = 0;
@@ -334,10 +335,10 @@ ReplaceDatatableBufferAddresses () {
void
Init () {
LogMessage (LogLevel::INFO, "Init JPN39 patches");
bool unlockSongs = true;
double modelResRate = 1.0;
bool unlockSongs = Config::ConfigManager::instance ().getPatchesConfig ().unlock_songs;
double modelResRate = Config::ConfigManager::instance ().getGraphicsConfig ().model_res_rate;
auto configPath = std::filesystem::current_path () / "config.toml";
/*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")) {
@@ -346,7 +347,7 @@ Init () {
if (auto graphics = openConfigSection (config_ptr.get (), "graphics")) {
modelResRate = readConfigDouble (graphics, "model_res_rate", modelResRate);
}
}
}*/
// Hook to get AppAccessor and ComponentAccessor
INSTALL_FAST_HOOK (DeviceCheck);
+21 -11
View File
@@ -1,5 +1,6 @@
#pragma once
#include <SDL3/SDL.h>
#include <array>
#include "helpers.h"
#include "bnusio.h"
@@ -9,8 +10,8 @@
// #define ASYNC_IO
enum SDLAxis {
SDL_AXIS_NULL,
enum class SDLAxis {
SDL_AXIS_NULL = 0,
SDL_AXIS_LEFT_LEFT,
SDL_AXIS_LEFT_RIGHT,
SDL_AXIS_LEFT_UP,
@@ -37,16 +38,16 @@ struct SDLAxisState {
float RTriggerDown;
};
enum Scroll { MOUSE_SCROLL_INVALID, MOUSE_SCROLL_UP, MOUSE_SCROLL_DOWN };
enum class Scroll { MOUSE_SCROLL_INVALID = 0, MOUSE_SCROLL_UP, MOUSE_SCROLL_DOWN };
struct Keybindings {
u8 keycodes[255] = { '\0' };
SDL_GamepadButton buttons[255] = { SDL_GAMEPAD_BUTTON_INVALID };
SDLAxis axis[255] = { SDL_AXIS_NULL };
Scroll scroll[2] = { MOUSE_SCROLL_INVALID };
std::array<u8, 255> keycodes = { };
std::array<SDL_GamepadButton, 255> buttons = { SDL_GAMEPAD_BUTTON_INVALID };
std::array<SDLAxis, 255> axis = {SDLAxis::SDL_AXIS_NULL };
std::array<Scroll,2> scroll = {Scroll::MOUSE_SCROLL_INVALID };
};
enum EnumType { none, keycode, button, axis, scroll };
enum class EnumType { none, keycode, button, axis, scroll };
struct ConfigValue {
EnumType type;
@@ -64,11 +65,20 @@ struct InternalButtonState {
bool Tapped;
};
struct KeyCodePair {
std::string string;
u8 keycode;
};
struct MouseState {
POINT Position;
POINT RelativePosition;
bool ScrolledUp;
bool ScrolledDown;
} inline currentMouseState, lastMouseState;
bool InitializePoll (HWND windowHandle);
void DisposePoll ();
void SetKeyboardButtons ();
ConfigValue StringToConfigEnum (const char *value);
void SetConfigValue (const toml_table_t *table, const char *key, Keybindings *keybind, u8 *inputState);
InternalButtonState GetInternalButtonState (const Keybindings &bindings);
void SetRumble (int left, int right, int length);
+54 -162
View File
@@ -1,19 +1,18 @@
#include "poll.h"
#ifdef ASYNC_IO
#include "polldef.h"
#define SDL_MAIN_NOIMPL
#include <SDL3/SDL_main.h>
extern bool jpLayout;
extern int exited;
extern u8 inputState;
#include "config.h"
static bool jpLayout = Config::ConfigManager::instance ().getKeyboardConfig ().jp_layout;
static bool autoIme = Config::ConfigManager::instance ().getKeyboardConfig ().auto_ime;
static bool globalKeyboard = Config::ConfigManager::instance ().getControllerConfig ().global_keyboard;
static bool emulateUsio = Config::ConfigManager::instance ().getEmulationConfig ().usio;
extern float axisThreshold;
extern bool globalKeyboardInput;
extern bool autoIme;
extern HKL currentLayout;
extern bool emulateUsio;
extern bool globalKeyboard;
bool wndForeground = false;
bool usingKeyboard = false;
@@ -32,9 +31,9 @@ char currentMouseWheelDirection = 0;
uint8_t mouseWheelCount[2] = { 0 };
uint8_t mouseWheelDiff[2] = { 0 };
// SDLAxisState currentControllerAxisState;
float currentControllerAxisState[SDL_AXIS_MAX] = { 0.0 };
uint8_t controllerAxisCount[SDL_AXIS_MAX] = { 0 };
uint8_t controllerAxisDiff[SDL_AXIS_MAX] = { 0 };
float currentControllerAxisState[static_cast<size_t>(SDLAxis::SDL_AXIS_MAX)] = { 0.0 };
uint8_t controllerAxisCount[static_cast<size_t>(SDLAxis::SDL_AXIS_MAX)] = { 0 };
uint8_t controllerAxisDiff[static_cast<size_t>(SDLAxis::SDL_AXIS_MAX)] = { 0 };
int maxCount = 1;
@@ -44,81 +43,6 @@ bool flipped[255];
std::thread updatePollThread;
void
SetKeyboardButtons () {
ConfigKeyboardButtonsCount = jpLayout ? std::size (ConfigKeyboardButtons_JP) : std::size (ConfigKeyboardButtons_US);
ConfigKeyboardButtons = static_cast<KeyCodePair *> (malloc (ConfigKeyboardButtonsCount * sizeof (KeyCodePair)));
memcpy (ConfigKeyboardButtons, jpLayout ? ConfigKeyboardButtons_JP : ConfigKeyboardButtons_US, ConfigKeyboardButtonsCount * sizeof (KeyCodePair));
}
void
SetConfigValue (const toml_table_t *table, const char *key, Keybindings *key_bind, u8 *inputState) {
const toml_array_t *array = toml_array_in (table, key);
if (!array) {
LogMessage (LogLevel::WARN, std::string (key) + ": Cannot find array");
return;
}
memset (key_bind, 0, sizeof (*key_bind));
for (size_t i = 0; i < std::size (key_bind->buttons); i++)
key_bind->buttons[i] = SDL_GAMEPAD_BUTTON_INVALID;
for (int idx = 0;; idx++) {
const auto [ok, u] = toml_string_at (array, idx);
if (!ok) break;
const ConfigValue value = StringToConfigEnum (u.s);
free (u.s);
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) {
key_bind->keycodes[i] = value.keycode;
break;
}
}
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) {
key_bind->buttons[i] = value.button;
break;
}
}
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) {
key_bind->axis[i] = value.axis;
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) {
key_bind->scroll[i] = value.scroll;
break;
}
}
break;
}
default: break;
}
}
}
// 钩子句柄
HHOOK keyboardHook;
HHOOK mouseHook;
@@ -208,9 +132,9 @@ InitializePoll (HWND windowHandle) {
wndForeground = windowHandle == GetForegroundWindow ();
if (!emulateUsio) return false;
usingKeyboard = inputState & 1;
usingMouse = inputState & (1 << 1);
usingController = inputState & (1 << 2);
usingKeyboard = Config::ConfigManager::instance ().getKeyBindings ().usingKeyboard();
usingMouse = Config::ConfigManager::instance ().getKeyBindings ().usingMouse();
usingController = Config::ConfigManager::instance ().getKeyBindings ().usingController();
usingSDLEvent = usingMouse || usingController;
atexit ([](){ if (currentLayout != nullptr) ActivateKeyboardLayout (currentLayout, KLF_SETFORPROCESS);});
@@ -324,9 +248,9 @@ CleanPoll () {
if (usingController) {
for (int i=0; i<SDL_GAMEPAD_BUTTON_COUNT; i++) controllerCount[i] -= (bool)controllerDiff[i];
for (int i=1; i<SDL_AXIS_MAX; i++) controllerAxisCount[i] -= (bool)controllerAxisDiff[i];
for (int i=1; i< static_cast<int>(SDLAxis::SDL_AXIS_MAX); i++) controllerAxisCount[i] -= (bool)controllerAxisDiff[i];
memset (controllerDiff, 0, SDL_GAMEPAD_BUTTON_COUNT);
memset (controllerAxisDiff, 0, SDL_AXIS_MAX);
memset (controllerAxisDiff, 0, static_cast<size_t>(SDLAxis::SDL_AXIS_MAX));
}
}
@@ -413,38 +337,6 @@ DisposePoll () {
SDL_Quit ();
}
ConfigValue
StringToConfigEnum (const char *value) {
ConfigValue rval = {};
for (size_t i = 0; i < ConfigKeyboardButtonsCount; ++i)
if (!strcmp (value, ConfigKeyboardButtons[i].string)) {
rval.type = keycode;
rval.keycode = ConfigKeyboardButtons[i].keycode;
return rval;
}
for (const auto &[string, button_] : ConfigControllerButtons)
if (!strcmp (value, string)) {
rval.type = button;
rval.button = button_;
return rval;
}
for (const auto &[string, axis_] : ConfigControllerAXIS)
if (!strcmp (value, string)) {
rval.type = axis;
rval.axis = axis_;
return rval;
}
for (auto &[string, scroll_] : ConfigMouseScroll)
if (!strcmp (value, string)) {
rval.type = scroll;
rval.scroll = scroll_;
return rval;
}
LogMessage (LogLevel::ERROR, std::string (value) + ": Unknown value");
return rval;
}
void
SetRumble (int left, int right, int length) {
for (auto &controller : controllers) {
@@ -482,16 +374,16 @@ GetMouseScrollDown () {
bool
GetMouseScrollIsDown (const Scroll scroll) {
if (scroll == MOUSE_SCROLL_UP) return GetMouseScrollUp ();
if (scroll == Scroll::MOUSE_SCROLL_UP) return GetMouseScrollUp ();
else return GetMouseScrollDown ();
}
int maxWheelCount = 1;
bool
GetMouseScrollIsTapped (const Scroll scroll) {
if (scroll == MOUSE_SCROLL_INVALID) return false;
if (mouseWheelCount[scroll - 1] > 0) {
mouseWheelDiff[scroll - 1] = 1;
if (scroll == Scroll::MOUSE_SCROLL_INVALID) return false;
if (mouseWheelCount[(int)scroll - 1] > 0) {
mouseWheelDiff[(int)scroll - 1] = 1;
return true;
} return false;
}
@@ -512,64 +404,64 @@ ControllerButtonIsTapped (const SDL_GamepadButton button) {
float
ControllerAxisIsDown (const SDLAxis axis) {
return currentControllerAxisState[axis];
return currentControllerAxisState[(int)axis];
}
bool
ControllerAxisIsTapped (const SDLAxis axis) {
if (controllerAxisCount[axis] > 0) {
controllerAxisDiff[axis] = 1;
if (controllerAxisCount[(int)axis] > 0) {
controllerAxisDiff[(int)axis] = 1;
return true;
} return false;
}
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;
}
for (const auto keycode : bindings.keycodes) {
if (keycode == 0) continue;
if (KeyboardIsTapped (keycode)) 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;
}
for (const auto button : bindings.buttons) {
if (button == SDL_GAMEPAD_BUTTON_INVALID) continue;
if (ControllerButtonIsTapped (button)) return true;
}
for (size_t i = 0; i < std::size (ConfigControllerAXIS); i++) {
if (bindings.axis[i] == SDL_AXIS_NULL) continue;
if (ControllerAxisIsTapped (bindings.axis[i])) {
return true;
}
for (const auto axis : bindings.axis) {
if (axis == SDLAxis::SDL_AXIS_NULL) continue;
if (ControllerAxisIsTapped (axis)) return true;
}
for (size_t i = 0; i < std::size (ConfigMouseScroll); i++) {
if (bindings.scroll[i] == MOUSE_SCROLL_INVALID) continue;
if (GetMouseScrollIsTapped (bindings.scroll[i])) {
return true;
}
for (const auto scroll : bindings.scroll) {
if (scroll == Scroll::MOUSE_SCROLL_INVALID) continue;
if (GetMouseScrollIsTapped (scroll)) return true;
}
return false;
}
float
IsButtonDown (const Keybindings &bindings) {
for (size_t i = 0; i < ConfigKeyboardButtonsCount; i++) {
if (bindings.keycodes[i] == 0) continue;
if (KeyboardIsDown (bindings.keycodes[i])) return 1.0f;
for (const auto keycode : bindings.keycodes) {
if (keycode == 0) continue;
if (KeyboardIsDown (keycode)) return 1.0f;
}
for (size_t i = 0; i < std::size (ConfigControllerButtons); i++) {
if (bindings.buttons[i] == SDL_GAMEPAD_BUTTON_INVALID) continue;
if (ControllerButtonIsDown (bindings.buttons[i])) return 1.0f;
for (const auto button : bindings.buttons) {
if (button == SDL_GAMEPAD_BUTTON_INVALID) continue;
if (ControllerButtonIsDown (button)) return 1.0f;
}
for (size_t i = 0; i < std::size (ConfigControllerAXIS); i++) {
if (bindings.axis[i] == 0) continue;
if (float val = ControllerAxisIsDown (bindings.axis[i]); val > 0) return val;
for (const auto axis : bindings.axis) {
if (axis == SDLAxis::SDL_AXIS_NULL) continue;
if (float val = ControllerAxisIsDown (axis); val > 0) return val;
}
for (size_t i = 0; i < std::size (ConfigMouseScroll); i++) {
if (bindings.scroll[i] == 0) continue;
if (GetMouseScrollIsDown (bindings.scroll[i])) return 1.0f;
for (const auto scroll : bindings.scroll) {
if (scroll == Scroll::MOUSE_SCROLL_INVALID) continue;
if (GetMouseScrollIsDown (scroll)) return 1.0f;
}
return 0.0f;
}
#endif
-306
View File
@@ -1,306 +0,0 @@
#pragma once
#include "poll.h"
struct KeyCodePair {
const char *string;
u8 keycode;
};
size_t ConfigKeyboardButtonsCount = 0;
KeyCodePair *ConfigKeyboardButtons = nullptr;
KeyCodePair ConfigKeyboardButtons_US[] = {
// Reference:https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
// Wayback Machine:https://web.archive.org/web/20231223135232/https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
// Row 1
{"ESCAPE", VK_ESCAPE},
{"F1", VK_F1},
{"F2", VK_F2},
{"F3", VK_F3},
{"F4", VK_F4},
{"F5", VK_F5},
{"F6", VK_F6},
{"F7", VK_F7},
{"F8", VK_F8},
{"F9", VK_F9},
{"F10", VK_F10},
{"F11", VK_F11},
{"F12", VK_F12},
// Row 2
{"`", VK_OEM_3},
{"1", '1'},
{"2", '2'},
{"3", '3'},
{"4", '4'},
{"5", '5'},
{"6", '6'},
{"7", '7'},
{"8", '8'},
{"9", '9'},
{"0", '0'},
{"-", VK_OEM_MINUS},
{"=", VK_OEM_PLUS},
{"BACKSPACE", VK_BACK},
// Row 3
{"TAB", VK_TAB},
{"Q", 'Q'},
{"W", 'W'},
{"E", 'E'},
{"R", 'R'},
{"T", 'T'},
{"Y", 'Y'},
{"U", 'U'},
{"I", 'I'},
{"O", 'O'},
{"P", 'P'},
{"[", VK_OEM_4},
{"]", VK_OEM_6},
{"BACKSLASH", VK_OEM_5},
// Row 4
{"CAPS_LOCK", VK_CAPITAL},
{"A", 'A'},
{"S", 'S'},
{"D", 'D'},
{"F", 'F'},
{"G", 'G'},
{"H", 'H'},
{"J", 'J'},
{"K", 'K'},
{"L", 'L'},
{";", VK_OEM_1},
{"'", VK_OEM_7},
{"ENTER", VK_RETURN},
// Row 5
{"SHIFT", VK_SHIFT},
{"Z", 'Z'},
{"X", 'X'},
{"C", 'C'},
{"V", 'V'},
{"B", 'B'},
{"N", 'N'},
{"M", 'M'},
{",", VK_OEM_COMMA},
{".", VK_OEM_PERIOD},
{"SLASH", VK_OEM_2},
// Row 6
{"CONTROL", VK_CONTROL},
{"L_WIN", VK_LWIN},
{"ALT", VK_MENU},
{"SPACE", VK_SPACE},
{"R_WIN", VK_RWIN},
{"MENU", VK_APPS},
// Other Keys
// PrtSc is more important when making snapshots, therefore comment it as reserved
//{"PRINT_SCREEN", VK_SNAPSHOT},
{"SCROLL_LOCK", VK_SCROLL},
{"PAUSE", VK_PAUSE},
{"INSERT", VK_INSERT},
{"DELETE", VK_DELETE},
{"HOME", VK_HOME},
{"END", VK_END},
{"PAGE_UP", VK_PRIOR},
{"PAGE_DOWN", VK_NEXT},
// Arrow Keys
{"UPARROW", VK_UP},
{"LEFTARROW", VK_LEFT},
{"DOWNARROW", VK_DOWN},
{"RIGHTARROW", VK_RIGHT},
// NUMPAD Keys
{"NUM_LOCK", VK_NUMLOCK},
{"DIVIDE", VK_DIVIDE},
{"MULTIPLY", VK_MULTIPLY},
{"SUBTRACT", VK_SUBTRACT},
{"NUM7", VK_NUMPAD7},
{"NUM8", VK_NUMPAD8},
{"NUM9", VK_NUMPAD9},
{"ADD", VK_ADD},
{"NUM4", VK_NUMPAD4},
{"NUM5", VK_NUMPAD5},
{"NUM6", VK_NUMPAD6},
{"NUM1", VK_NUMPAD1},
{"NUM2", VK_NUMPAD2},
{"NUM3", VK_NUMPAD3},
{"NUM0", VK_NUMPAD0},
{"DECIMAL", VK_DECIMAL},
};
KeyCodePair ConfigKeyboardButtons_JP[] = {
// Reference:https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
// Wayback Machine:https://web.archive.org/web/20231223135232/https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
// Row 1
{"ESCAPE", VK_ESCAPE},
{"F1", VK_F1},
{"F2", VK_F2},
{"F3", VK_F3},
{"F4", VK_F4},
{"F5", VK_F5},
{"F6", VK_F6},
{"F7", VK_F7},
{"F8", VK_F8},
{"F9", VK_F9},
{"F10", VK_F10},
{"F11", VK_F11},
{"F12", VK_F12},
// Row 2
{"1", '1'},
{"2", '2'},
{"3", '3'},
{"4", '4'},
{"5", '5'},
{"6", '6'},
{"7", '7'},
{"8", '8'},
{"9", '9'},
{"0", '0'},
{"-", VK_OEM_MINUS},
{"^", VK_OEM_7},
{"YEN", VK_OEM_5},
{"BACKSPACE", VK_BACK},
// Row 3
{"TAB", VK_TAB},
{"Q", 'Q'},
{"W", 'W'},
{"E", 'E'},
{"R", 'R'},
{"T", 'T'},
{"Y", 'Y'},
{"U", 'U'},
{"I", 'I'},
{"O", 'O'},
{"P", 'P'},
{"@", VK_OEM_3},
{"[", VK_OEM_4},
// Row 4
{"CAPS_LOCK", VK_CAPITAL},
{"A", 'A'},
{"S", 'S'},
{"D", 'D'},
{"F", 'F'},
{"G", 'G'},
{"H", 'H'},
{"J", 'J'},
{"K", 'K'},
{"L", 'L'},
{";", VK_OEM_PLUS},
{":", VK_OEM_1},
{"]", VK_OEM_6},
{"ENTER", VK_RETURN},
// Row 5
{"SHIFT", VK_SHIFT},
{"Z", 'Z'},
{"X", 'X'},
{"C", 'C'},
{"V", 'V'},
{"B", 'B'},
{"N", 'N'},
{"M", 'M'},
{",", VK_OEM_COMMA},
{".", VK_OEM_PERIOD},
{"SLASH", VK_OEM_2},
{"BACKSLASH", VK_OEM_102},
// Row 6
{"CONTROL", VK_CONTROL},
{"L_WIN", VK_LWIN},
{"ALT", VK_MENU},
{"SPACE", VK_SPACE},
{"R_WIN", VK_RWIN},
{"MENU", VK_APPS},
// Other Keys
// PrtSc is more important when making snapshots, therefore comment it as reserved
//{"PRINT_SCREEN", VK_SNAPSHOT},
{"SCROLL_LOCK", VK_SCROLL},
{"PAUSE", VK_PAUSE},
{"INSERT", VK_INSERT},
{"DELETE", VK_DELETE},
{"HOME", VK_HOME},
{"END", VK_END},
{"PAGE_UP", VK_PRIOR},
{"PAGE_DOWN", VK_NEXT},
// Arrow Keys
{"UPARROW", VK_UP},
{"LEFTARROW", VK_LEFT},
{"DOWNARROW", VK_DOWN},
{"RIGHTARROW", VK_RIGHT},
// NUMPAD Keys
{"NUM_LOCK", VK_NUMLOCK},
{"DIVIDE", VK_DIVIDE},
{"MULTIPLY", VK_MULTIPLY},
{"SUBTRACT", VK_SUBTRACT},
{"NUM7", VK_NUMPAD7},
{"NUM8", VK_NUMPAD8},
{"NUM9", VK_NUMPAD9},
{"ADD", VK_ADD},
{"NUM4", VK_NUMPAD4},
{"NUM5", VK_NUMPAD5},
{"NUM6", VK_NUMPAD6},
{"NUM1", VK_NUMPAD1},
{"NUM2", VK_NUMPAD2},
{"NUM3", VK_NUMPAD3},
{"NUM0", VK_NUMPAD0},
{"DECIMAL", VK_DECIMAL},
};
struct {
const char *string;
SDL_GamepadButton button;
} ConfigControllerButtons[] = {
{"SDL_A", SDL_GAMEPAD_BUTTON_SOUTH},
{"SDL_B", SDL_GAMEPAD_BUTTON_EAST},
{"SDL_X", SDL_GAMEPAD_BUTTON_WEST},
{"SDL_Y", SDL_GAMEPAD_BUTTON_NORTH},
{"SDL_BACK", SDL_GAMEPAD_BUTTON_BACK},
{"SDL_GUIDE", SDL_GAMEPAD_BUTTON_GUIDE},
{"SDL_START", SDL_GAMEPAD_BUTTON_START},
{"SDL_LSTICK_PRESS", SDL_GAMEPAD_BUTTON_LEFT_STICK},
{"SDL_RSTICK_PRESS", SDL_GAMEPAD_BUTTON_RIGHT_STICK},
{"SDL_LSHOULDER", SDL_GAMEPAD_BUTTON_LEFT_SHOULDER},
{"SDL_RSHOULDER", SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER},
{"SDL_DPAD_UP", SDL_GAMEPAD_BUTTON_DPAD_UP},
{"SDL_DPAD_DOWN", SDL_GAMEPAD_BUTTON_DPAD_DOWN},
{"SDL_DPAD_LEFT", SDL_GAMEPAD_BUTTON_DPAD_LEFT},
{"SDL_DPAD_RIGHT", SDL_GAMEPAD_BUTTON_DPAD_RIGHT},
{"SDL_MISC", SDL_GAMEPAD_BUTTON_MISC1},
{"SDL_PADDLE1", SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1},
{"SDL_PADDLE2", SDL_GAMEPAD_BUTTON_LEFT_PADDLE1},
{"SDL_PADDLE3", SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2},
{"SDL_PADDLE4", SDL_GAMEPAD_BUTTON_LEFT_PADDLE2},
{"SDL_TOUCHPAD", SDL_GAMEPAD_BUTTON_TOUCHPAD},
};
struct {
const char *string;
SDLAxis axis;
} ConfigControllerAXIS[] = {
{"SDL_LSTICK_LEFT", SDL_AXIS_LEFT_LEFT}, {"SDL_LSTICK_UP", SDL_AXIS_LEFT_UP}, {"SDL_LSTICK_DOWN", SDL_AXIS_LEFT_DOWN},
{"SDL_LSTICK_RIGHT", SDL_AXIS_LEFT_RIGHT}, {"SDL_RSTICK_LEFT", SDL_AXIS_RIGHT_LEFT}, {"SDL_RSTICK_UP", SDL_AXIS_RIGHT_UP},
{"SDL_RSTICK_DOWN", SDL_AXIS_RIGHT_DOWN}, {"SDL_RSTICK_RIGHT", SDL_AXIS_RIGHT_RIGHT}, {"SDL_LTRIGGER", SDL_AXIS_LTRIGGER_DOWN},
{"SDL_RTRIGGER", SDL_AXIS_RTRIGGER_DOWN},
};
struct {
const char *string;
Scroll scroll;
} ConfigMouseScroll[] = {
{"SCROLL_UP", MOUSE_SCROLL_UP},
{"SCROLL_DOWN", MOUSE_SCROLL_DOWN},
};
struct MouseState {
POINT Position;
POINT RelativePosition;
bool ScrolledUp;
bool ScrolledDown;
} currentMouseState, lastMouseState;