Log Optimization & add Banner

layeredfs add mod_dir option allow uses different folder
add simple input option to allow input direct apply to game
This commit is contained in:
ptmaster
2025-03-16 16:49:07 +08:00
parent ef4564a912
commit 466e6d2e59
19 changed files with 223 additions and 170 deletions
+4
View File
@@ -67,6 +67,7 @@ song_no = [] # Song noes used for custom folder
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)
global_keyboard = false # Accept keyboard input even if Taiko.exe is not foreground
simple_input = false # Simplified input handler, might decrease game laggy
[keyboard]
@@ -79,6 +80,7 @@ enabled = false # Replace assets from the game using a layered file
# | 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.
mod_dir = "Data_mods"
[logging]
@@ -86,4 +88,6 @@ log_level = "INFO" # Log level, Can be either "NONE", "ERROR", "WARN",
# | Keep this as low as possible (Info is usually more than enough) as more logging will slow down your game
log_to_file = false # Log to file, set this to true to save the logs from your last session to TaikoArcadeLoader.log
# |Again, if you do not have a use for this (debugging mods or whatnot), turn it off.
log_method_name = true
log_full_source = true
log_dir = "./logs/" # Log file path (Can be both relative and absolute).
+2 -2
View File
@@ -12,9 +12,9 @@ Version::Version () {
// Print a cool logo with version info
std::cout << R"( )" << std::endl;
std::cout << R"( ______ _ __ ___ __ __ __ )" << std::endl;
std::cout << R"(/_ __/__ _(_) /_____ / _ | ___________ ____/ /__ / / ___ ___ ____/ /__ ____)" << std::endl;
std::cout << R"(/_ __/__ (_) /_____ / _ | ___________ ___/ /__ / / ___ ___ ___/ /__ ____)" << std::endl;
std::cout << R"( / / / _ `/ / '_/ _ \/ __ |/ __/ __/ _ `/ _ / -_) /__/ _ \/ _ `/ _ / -_) __/)" << std::endl;
std::cout << R"(/_/ \_,_/_/_/\_\\___/_/ |_/_/ \__/\_,_/\_,_/\__/____/\___/\_,_/\_,_/\__/_/ )" << std::endl;
std::cout << R"(/_/ \_,_\_/_/\_\\___/_/ |_/_/ \__/\_,_\\_,_/\__/____/\___/\_,_\\_,_/\__/_/ )" << std::endl;
std::cout << std::format("{: >79}", std::format("::v{}::", TAL_VERSION)) << std::endl;
std::cout << R"( )" << std::endl;
}
+9 -7
View File
@@ -225,16 +225,16 @@ Init () {
// }
if (analogInput) {
LogMessage (LogLevel::WARN, "[Analog Type] Axis: All the keyboard drum inputs have been disabled");
LogMessage (LogLevel::WARN, "Using Axis AnalogIn: All the keyboard drum inputs have been disabled");
analogMethod = AnalogInputAxis;
} else if (drumWaitPeriod > 0) {
LogMessage (LogLevel::WARN, "[Analog Type] WaitPeriod: Fast input might be queued");
LogMessage (LogLevel::WARN, "Using WaitPeriod AnalogIn: Fast input might be queued");
analogMethod = AnalogInputWaitPeriod;
} else if (drumWaitPeriod == 0) {
LogMessage (LogLevel::INFO, "[Analog Type] Cooldown: Fastest and original input");
analogMethod = AnalogInputCooldown;
// } else if (drumWaitPeriod == 0) {
// LogMessage (LogLevel::INFO, "Using Cooldown AnalogIn: Fastest and original input");
// analogMethod = AnalogInputCooldown;
} else {
LogMessage (LogLevel::INFO, "[Analog Type] Simple: Fastest and original input");
LogMessage (LogLevel::INFO, "Using Simple AnalogIn: Fastest and original input");
analogMethod = AnalogInputSimple;
}
@@ -244,7 +244,9 @@ Init () {
}
if (!emulateUsio && bnusioOriginal) {
LogMessage (LogLevel::WARN, "USIO emulation disabled");
LogMessage (LogLevel::WARN, "Disable USIO Emulation");
} else {
LogMessage (LogLevel::INFO, "Using USIO Emulation");
}
}
+6 -5
View File
@@ -4,6 +4,7 @@
#include <Windows.h>
#include <rfl/toml.hpp>
#include <map>
#include <stdexcept>
#include "banner.h"
#include "config.h"
@@ -101,7 +102,7 @@ ConfigManager::ConfigManager () {
bool
ConfigManager::loadKeyBindings () {
LogMessage (LogLevel::INFO, "Layout: {}", config.keyboard.jp_layout ? "JP" : "US");
LogMessage (LogLevel::INFO, "Using Keyboard 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";
@@ -122,10 +123,10 @@ ConfigManager::loadKeyBindings () {
keyBindings.usingKeyboard = usingKeyboard;
keyBindings.usingMouse = usingMouse;
keyBindings.usingController = usingController;
LogMessage (LogLevel::INFO, "Finish Loading keyconfig.toml");
if (usingKeyboard) LogMessage (LogLevel::DEBUG, ">>>>> Using Keyboard!");
if (usingMouse) LogMessage (LogLevel::DEBUG, ">>>>> Using Mouse!");
if (usingController) LogMessage (LogLevel::DEBUG, ">>>>> Using Controller!");
LogMessage (LogLevel::DEBUG, "Finish Loading keyconfig.toml");
if (usingKeyboard) LogMessage (LogLevel::INFO, "Using Input Channel: Keyboard");
if (usingMouse) LogMessage (LogLevel::INFO, "Using Input Channel: Mouse Wheel");
if (usingController) LogMessage (LogLevel::INFO, "Using Input Channel: Controller");
return true;
}
+14 -4
View File
@@ -42,6 +42,7 @@ struct patchesConfig {
patchVersions version{"auto"};
bool unlock_songs = true;
bool local_files = true;
// int maximum_song = 1600;
struct chn00Config {
bool fix_language = false;
bool demo_movie = true;
@@ -91,6 +92,7 @@ struct controllerConfig {
int wait_period = 0;
bool analog_input = false;
bool global_keyboard = false;
bool simple_input = false;
};
struct keyboardConfig {
@@ -100,13 +102,16 @@ struct keyboardConfig {
struct layeredfsConfig {
bool enabled = false;
std::string mod_dir = "Data_mods";
};
using logLevels = rfl::Literal<"NONE", "ERROR", "WARN", "INFO", "DEBUG", "HOOKS">;
using logLevels = rfl::Literal<"NONE", "ERROR", "WARN", "INFO", "GAME", "DEBUG", "HOOKS">;
struct loggingConfig {
logLevels log_level{ "INFO"};
logLevels log_level{ "GAME" };
bool log_to_file = false;
bool log_method_name = false;
bool log_full_source = false;
std::string log_dir = "./logs/";
};
@@ -434,8 +439,13 @@ public:
// Singleton pattern for global access
static ConfigManager& instance() {
static ConfigManager instance; // Guaranteed to be destroyed, instantiated on first use
return instance;
try {
static ConfigManager instance; // Guaranteed to be destroyed, instantiated on first use
return instance;
} catch (std::runtime_error &e) {
std::cerr << "[Logger] Failed to parse Default Config: " << e.what () << std::endl;
exit (1);
}
}
static bool validateConfigfile(std::string path);
+6 -5
View File
@@ -206,7 +206,7 @@ DllMain (HMODULE module, const DWORD reason, LPVOID reserved) {
else if (yRes * 16 < xRes * 9) xRes = (int)(yRes * 16.0 / 9.0);
}
Config::ConfigManager::instance ().setRes (xRes, yRes);
LogMessage (LogLevel::INFO, "Boot with {} mode [{}(*{})x{}(*())]", windowed ? "window" : "fullscreen", xRes, hScale, yRes, vScale);
LogMessage (LogLevel::INFO, "Using {} mode [{}(x{}), {}(x{})]", windowed ? "window" : "fullscreen", xRes, hScale, yRes, vScale);
if (autoIme) {
currentLayout = GetKeyboardLayout (0);
@@ -216,7 +216,6 @@ DllMain (HMODULE module, const DWORD reason, LPVOID reserved) {
}
// Update the logger with the level read from config file.
LogMessage (LogLevel::INFO, "Application started.");
if (version == "auto") GetGameVersion ();
else if (version == "JPN00") gameVersion = GameVersion::JPN00;
@@ -228,7 +227,8 @@ DllMain (HMODULE module, const DWORD reason, LPVOID reserved) {
MessageBoxA (nullptr, "Unknown patch version", nullptr, MB_OK);
ExitProcess (0);
}
LogMessage (LogLevel::INFO, "GameVersion is {}", GameVersionToString (gameVersion));
LogMessage (LogLevel::INFO, "Using GameVersion: {}", GameVersionToString (gameVersion));
Logger::InitLoggerHook ();
patches::Plugins::LoadPlugins ();
patches::Plugins::InitVersion (gameVersion);
@@ -239,7 +239,7 @@ DllMain (HMODULE module, const DWORD reason, LPVOID reserved) {
GetPrivateProfileStringA ("card", "accessCode2", accessCode2, accessCode2, 21, ".\\card.ini");
GetPrivateProfileStringA ("card", "chipId2", chipId2, chipId2, 33, ".\\card.ini");
LogMessage (LogLevel::INFO, "==== Loading patches, please wait...");
LogMessage (LogLevel::DEBUG, "=== Loading patches, please wait...");
if (windowed && cursor) INSTALL_FAST_HOOK (ShowMouse);
INSTALL_FAST_HOOK (ExitWindows);
@@ -284,7 +284,8 @@ DllMain (HMODULE module, const DWORD reason, LPVOID reserved) {
// 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);
LogMessage (LogLevel::DEBUG, "=== Finished Loading patches!");
LogMessage (LogLevel::INFO, "Taiko Starts in {:.2f}ms", duration.count () * 1000);
}
return true;
}
+82 -25
View File
@@ -1,4 +1,5 @@
#include "logger.h"
#include "config.h"
#include <iostream>
#include <fstream>
#include <regex>
@@ -9,6 +10,11 @@
#include <cstdarg>
#include <memory>
extern GameVersion gameVersion;
bool s_logMethodName = Config::ConfigManager::instance ().getLoggingConfig ().log_method_name;
bool s_logFullSource = Config::ConfigManager::instance ().getLoggingConfig ().log_full_source;
// Static member definitions
LogLevel Logger::s_logLevel = LogLevel::NONE;
void* Logger::s_consoleHandle = nullptr;
@@ -16,27 +22,54 @@ bool Logger::s_isInitialized = false;
std::fstream* Logger::s_logFile = nullptr;
std::mutex Logger::s_logMutex;
bool loggerInited = false;
// FAST_HOOK_DYNAMIC (int, TaikoPrintf, const char *format, ...) {
// va_list args;
// va_start (args, format);
// int requiredSize = vsnprintf (nullptr, 0, format, args) + 1; // +1 for null terminator
// std::unique_ptr<char[]> buffer (new char[requiredSize]);
// vsnprintf (buffer.get (), requiredSize, format, args);
// Logger::LogMessageHandler ("printf", "Taiko.exe", -1, LogLevel::GAME, buffer.get ());
// va_end (args);
// return requiredSize;
// }
// i64 coutVal = 0;
// FAST_HOOK_DYNAMIC (i64 *, TaikoPrint, i64 *a1, const char *msg) {
// if ((i64) a1 != coutVal) originalTaikoPrint.call<i64 *> (a1, msg);
// Logger::LogMessageHandler ("std::cout", "Taiko.exe", -1, LogLevel::GAME, msg);
// return a1;
// }
void
Logger::InitLoggerHook () {
if (loggerInited) return;
loggerInited = true;
// switch (gameVersion) {
// case GameVersion::JPN00: case GameVersion::JPN08: case GameVersion::CHN00: default: break;
// case GameVersion::JPN39: {
// coutVal = *(i64 *)ASLR (0x1408CCBF8);
// INSTALL_FAST_HOOK_DYNAMIC (TaikoPrintf, ASLR (0x1400D3EE0));
// INSTALL_FAST_HOOK_DYNAMIC (TaikoPrint, ASLR (0x14004B4F0));
// } break;
// }
}
static std::string
ConvertWideToUtf8(const wchar_t* wstr)
{
ConvertWideToUtf8(const wchar_t* wstr) {
if (!wstr) return {};
std::wstring ws (wstr);
return {ws.begin (), ws.end ()};
}
void
Logger::InitializeLogger(const LogLevel level, const bool logToFile, std::string logDir)
{
if (s_isInitialized) {
return;
}
Logger::InitializeLogger(const LogLevel level, const bool logToFile, std::string logDir) {
if (s_isInitialized) return;
s_isInitialized = true;
s_logLevel = level;
if (s_consoleHandle == nullptr) {
s_consoleHandle = GetStdHandle (STD_OUTPUT_HANDLE);
}
if (s_consoleHandle == nullptr) s_consoleHandle = GetStdHandle (STD_OUTPUT_HANDLE);
if (logToFile) {
try {
@@ -60,12 +93,17 @@ Logger::InitializeLogger(const LogLevel level, const bool logToFile, std::string
const std::string fullLogPath = logDir + dateFilename;
s_logFile = new std::fstream (fullLogPath.c_str (), std::ios::out | std::ios::app);
if (!s_logFile->is_open ()) {
std::cerr << "[Logg er] Failed to open " << fullLogPath << " for writing.\n";
std::cerr << "[Logger] Failed to open " << fullLogPath << " for writing.\n";
s_logFile = nullptr;
}
}
}
bool
Logger::GuardianOutput (LogLevel messageLevel) {
return !s_isInitialized || messageLevel > s_logLevel;
}
void
Logger::LogMessageHandler (const char* function, const char* codeFile, int codeLine, LogLevel messageLevel, const char* format, ...) {
// Return if logger uninitialized or messageLevel is more verbose than the set level
@@ -81,6 +119,9 @@ Logger::LogMessageHandler (const char* function, const char* codeFile, int codeL
std::unique_ptr<char[]> buffer (new char[requiredSize]);
vsnprintf (buffer.get (), requiredSize, format, args);
std::string formattedMessage (buffer.get());
while (formattedMessage.ends_with ("\n")) {
formattedMessage = formattedMessage.substr (0, formattedMessage.size () - 1);
}
va_end (args);
std::string logType = Logger::GetLogLevelString(messageLevel);
@@ -89,10 +130,6 @@ Logger::LogMessageHandler (const char* function, const char* codeFile, int codeL
std::regex re (R"(.*? (([\w<>]+::)*[\w]+( [()<>+-]+)?)\(\w+.*?\))");
short_function = std::regex_replace (short_function, re, "$1");
constexpr std::string_view build_dir = XSTRING (SOURCE_ROOT);
std::string_view filename = codeFile;
filename.remove_prefix (build_dir.size ());
SYSTEMTIME systemTime;
GetSystemTime (&systemTime);
time_t rawTime = time (nullptr);
@@ -104,7 +141,19 @@ Logger::LogMessageHandler (const char* function, const char* codeFile, int codeL
// Construct the log message
std::ostringstream descStream;
descStream << short_function << " (" << filename << ":" << codeLine << "): ";
if (s_logMethodName) descStream << short_function << " ";
if (s_logFullSource) {
constexpr std::string_view build_dir = XSTRING (SOURCE_ROOT);
std::string_view filename = codeFile;
filename.remove_prefix (build_dir.size ());
descStream << "(" << filename << ":" << codeLine << "): ";
} else {
std::string filename = std::string (codeFile);
if (size_t begin = filename.find_last_of ("/\\"); begin != std::string::npos) {
filename = filename.substr (begin + 1, filename.length ());
}
descStream << "(" << std::format("{: >20}", std::format("{}:{}", filename, codeLine)) << "): ";
}
std::string descMessage = descStream.str();
// Print to console
@@ -113,9 +162,14 @@ Logger::LogMessageHandler (const char* function, const char* codeFile, int codeL
std::cout << logType;
SetConsoleTextAttribute (s_consoleHandle, FOREGROUND_INTENSITY);
std::cout << descMessage;
// Reset console color
SetConsoleTextAttribute (s_consoleHandle, FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY);
std::cout << formattedMessage << std::endl;
if (messageLevel == LogLevel::WARN || messageLevel == LogLevel::ERROR) {
SetConsoleTextAttribute (s_consoleHandle, Logger::GetLogLevelColor(messageLevel));
std::cout << formattedMessage << std::endl;
SetConsoleTextAttribute (s_consoleHandle, FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY);
} else {
SetConsoleTextAttribute (s_consoleHandle, FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY);
std::cout << formattedMessage << std::endl;
}
std::cout.flush ();
if (s_logFile != nullptr) {
@@ -151,6 +205,7 @@ Logger::GetLogLevel (const std::string& logLevelStr) {
if (logLevelStr == "INFO") return LogLevel::INFO;
if (logLevelStr == "WARN") return LogLevel::WARN;
if (logLevelStr == "ERROR") return LogLevel::ERROR;
if (logLevelStr == "GAME") return LogLevel::GAME;
if (logLevelStr == "HOOKS") return LogLevel::HOOKS;
return LogLevel::NONE;
}
@@ -159,17 +214,17 @@ std::string
Logger::GetLogLevelString (const LogLevel messageLevel) {
switch (messageLevel) {
case LogLevel::DEBUG: return "DEBUG: ";
case LogLevel::INFO: return "INFO: ";
case LogLevel::WARN: return "WARN: ";
case LogLevel::INFO: return "INFO : ";
case LogLevel::WARN: return "WARN : ";
case LogLevel::ERROR: return "ERROR: ";
case LogLevel::HOOKS: return "HOOKS: ";
default: return "NONE: ";
case LogLevel::GAME: return "GAME : ";
default: return "NONE : ";
}
}
int
Logger::GetLogLevelColor(const LogLevel messageLevel)
{
Logger::GetLogLevelColor(const LogLevel messageLevel) {
// Colors: https://i.sstatic.net/ZG625.png
switch (messageLevel) {
case LogLevel::DEBUG:
@@ -182,6 +237,8 @@ Logger::GetLogLevelColor(const LogLevel messageLevel)
return FOREGROUND_RED; // Bright RED
case LogLevel::HOOKS:
return FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY; // Pale Purple
case LogLevel::GAME:
return FOREGROUND_BLUE | FOREGROUND_RED; // Purple
default:
return FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
}
+16 -7
View File
@@ -21,25 +21,30 @@ enum class LogLevel {
ERROR,
WARN,
INFO,
GAME,
DEBUG,
HOOKS
};
class Logger {
public:
static void InitializeLogger(LogLevel level, bool logToFile, std::string logDir);
static void InitLoggerHook ();
static void LogMessageHandler(const char* function, const char* codeFile, int codeLine, LogLevel messageLevel, const char* format, ...);
static void InitializeLogger (LogLevel level, bool logToFile, std::string logDir);
static void LogMessageHandler(const char* function, const char* codeFile, int codeLine, LogLevel messageLevel, const wchar_t* format, ...);
static bool GuardianOutput (LogLevel messageLevel);
static void CleanupLogger();
static void LogMessageHandler (const char* function, const char* codeFile, int codeLine, LogLevel messageLevel, const char* format, ...);
static LogLevel GetLogLevel(const std::string& logLevelStr);
static void LogMessageHandler (const char* function, const char* codeFile, int codeLine, LogLevel messageLevel, const wchar_t* format, ...);
static std::string GetLogLevelString(LogLevel messageLevel);
static void CleanupLogger ();
static int GetLogLevelColor(LogLevel messageLevel);
static LogLevel GetLogLevel (const std::string& logLevelStr);
static std::string GetLogLevelString (LogLevel messageLevel);
static int GetLogLevelColor (LogLevel messageLevel);
private:
// Private constructor to disallow instantiation
@@ -56,6 +61,7 @@ template <typename... Args>
struct LogMessage {
LogMessage (const LogLevel level, const std::string_view format, Args&&... args,
const std::source_location& loc = std::source_location::current()) {
if (Logger::GuardianOutput (level)) return;
std::string formatted_message =
std::vformat(std::string(format), std::make_format_args(args...));
@@ -64,6 +70,7 @@ struct LogMessage {
LogMessage (const LogLevel level, const std::wstring_view format, Args&&... args,
const std::source_location& loc = std::source_location::current()) {
if (Logger::GuardianOutput (level)) return;
std::wstring formatted_message =
std::vformat(std::wstring(format), std::make_wformat_args(args...));
@@ -75,11 +82,13 @@ template <>
struct LogMessage<void> {
LogMessage(const LogLevel level, const std::string_view format,
const std::source_location& loc = std::source_location::current()) {
if (Logger::GuardianOutput (level)) return;
Logger::LogMessageHandler(loc.function_name(), loc.file_name(), loc.line(), level, format.data());
}
LogMessage(const LogLevel level, const std::wstring_view format,
const std::source_location& loc = std::source_location::current()) {
if (Logger::GuardianOutput (level)) return;
Logger::LogMessageHandler(loc.function_name(), loc.file_name(), loc.line(), level, format.data());
}
};
+1 -1
View File
@@ -549,7 +549,7 @@ CoCreateInstanceHook (const IID *const rclsid, const LPUNKNOWN pUnkOuter, const
void
Init () {
LogMessage (LogLevel::INFO, "Init AmAuth patches");
LogMessage (LogLevel::DEBUG, "Init AmAuth patches");
auto whereCoCreateInstance = GetProcAddress (LoadLibraryW (L"ole32.dll"), "CoCreateInstance");
originalCoCreateInstanceHook = safetyhook::create_inline ((void *)whereCoCreateInstance, CoCreateInstanceHook);
+8 -4
View File
@@ -68,16 +68,20 @@ ReduceAudioLatency () {
} else {
auto properties = audioClient->GetProperties ();
auto prop = properties.value();
double currentDelay = prop.minimumBufferSize * 1000.0 / prop.sampleRate;
double defaultDelay = prop.defaultBufferSize * 1000.0 / prop.sampleRate;
LogMessage (LogLevel::INFO, "Audio latency: {:.2f}ms -> {:.2f}ms", defaultDelay, currentDelay);
if (prop.minimumBufferSize < prop.defaultBufferSize) {
double currentDelay = prop.minimumBufferSize * 1000.0 / prop.sampleRate;
double defaultDelay = prop.defaultBufferSize * 1000.0 / prop.sampleRate;
LogMessage (LogLevel::INFO, "Using REAL Audio latency: {:.2f}ms -> {:.2f}ms", defaultDelay, currentDelay);
} else {
LogMessage (LogLevel::WARN, "Using REAL Audio Failed, Please Check Audio Driver!");
}
}
return 0;
}
void
Init () {
LogMessage (LogLevel::INFO, "Init Audio patches");
LogMessage (LogLevel::DEBUG, "Init Audio patches");
if (real) ReduceAudioLatency ();
+4 -4
View File
@@ -111,7 +111,7 @@ Init () {
fontExistAll = false;
}
if (fontExistAll == false) return;
LogMessage (LogLevel::INFO, "Detected cn_xx files, Install Font patches");
LogMessage (LogLevel::INFO, "Using Font patches (Detected cn_xx files)");
languageData = calloc (languages.size () * languages.size () * 0x70 * 0x5, sizeof (u8));
switch (gameVersion) {
@@ -389,14 +389,14 @@ Init () {
demoMovieExistAll = false;
}
if (demoMovieExistAll) {
LogMessage (LogLevel::INFO, "Detected attractdemo_cn files, install attractdemo patches!");
LogMessage (LogLevel::INFO, "Using Attractdemo patches (Detected attractdemo_cn files)");
INSTALL_FAST_HOOK_DYNAMIC (LoadDemoMovie, ASLR (0x1404313F0));
}
bool onpCnExist = false;
if (std::filesystem::exists (std::string ("..\\..\\Data\\x64\\textures\\onpu_cn\\onp_all.nutexb"))) onpCnExist = true;
if (onpCnExist) {
LogMessage (LogLevel::INFO, "Detected onpu_cn files, install onp patches!");
LogMessage (LogLevel::INFO, "Using Onp patches (Detected onpu_cn files)");
INSTALL_MID_HOOK_DYNAMIC (ChangeOnpFile, ASLR (0x140134D16));
}
language_patch.push_back (safetyhook::create_mid (ASLR (0x140134E22), [](SafetyHookContext &ctx){
@@ -638,7 +638,7 @@ Init () {
};
for (std::string voiceFile : voiceFiles) checkVoiceFile (("..\\..\\Data\\x64\\sound\\" + voiceFile).c_str ());
if (enableSwitchVoice) {
LogMessage (LogLevel::INFO, "Detected voice files, install voice patches!");
LogMessage (LogLevel::INFO, "Using Voice patches (Detected voice files)");
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\" "
+9 -7
View File
@@ -4,7 +4,8 @@
#include <zlib.h>
#include "config.h"
bool useLayeredFs = Config::ConfigManager::instance ().getLayeredFsConfig ().enabled;
bool useLayeredFs = Config::ConfigManager::instance ().getLayeredFsConfig ().enabled;
std::string modDir = Config::ConfigManager::instance ().getLayeredFsConfig ().mod_dir;
std::string datatableKey = "3530304242323633353537423431384139353134383346433246464231354534";
std::string fumenKey = "4434423946383537303842433443383030333843444132343339373531353830";
@@ -180,8 +181,8 @@ LayeredFsHandler (const std::string &originalFileName, const std::string &curren
std::filesystem::path path (originalFileName.c_str ());
if (!path.is_absolute ()) path = absolute (path);
auto originalDataFolder = std::filesystem::current_path ().parent_path ().parent_path () / "Data" / "x64";
auto originalLayeredFsFolder = std::filesystem::current_path ().parent_path ().parent_path () / "Data_mods" / "x64";
auto encryptedLayeredFsFolder = std::filesystem::current_path ().parent_path ().parent_path () / "Data_mods" / "x64_enc";
auto originalLayeredFsFolder = std::filesystem::current_path ().parent_path ().parent_path () / modDir / "x64";
auto encryptedLayeredFsFolder = std::filesystem::current_path ().parent_path ().parent_path () / modDir / "x64_enc";
if (path.string ().find (originalDataFolder.string ()) == 0) {
auto newPath = path.string ();
@@ -288,21 +289,22 @@ void
Init () {
register_cipher (&aes_desc);
if (useLayeredFs || !beforeHandlers.empty () || !afterHandlers.empty ()) {
LogMessage (LogLevel::INFO, "using LayeredFs! Data_mods={} beforHandlers={} afterHandlers={}",
useLayeredFs ? "enabled" : "disabled", beforeHandlers.size (), afterHandlers.size ());
if (!beforeHandlers.empty ()) LogMessage (LogLevel::INFO, "Using fileHandler beofre size: {}", beforeHandlers.size ());
if (useLayeredFs) LogMessage (LogLevel::INFO, "Using LayeredFS mods folder: ", modDir);
if (!afterHandlers.empty ()) LogMessage (LogLevel::INFO, "Using fileHandler after size: {}", afterHandlers.size ());
INSTALL_FAST_HOOK (CreateFileAHook);
}
}
void
RegisterBefore (const std::function<std::string (std::string, std::string)> &fileHandler) {
LogMessage (LogLevel::DEBUG, "Registered Before");
LogMessage (LogLevel::DEBUG, "Registered LayeredFS Before Handler");
beforeHandlers.push_back (new RegisteredHandler (fileHandler));
}
void
RegisterAfter (const std::function<std::string (std::string, std::string)> &fileHandler) {
LogMessage (LogLevel::DEBUG, "Registered After");
LogMessage (LogLevel::DEBUG, "Registered LayeredFS After Handler");
afterHandlers.push_back (new RegisteredHandler (fileHandler));
}
-5
View File
@@ -89,11 +89,6 @@ void Update ();
void Exit ();
// Lowlevel Card API
void WaitTouch (CallBackTouchCard callback, uint64_t touchData);
// Lowlevel QR API
void InitQr (GameVersion gameVersion);
void UsingQr ();
void * CheckQr ();
size_t GetQr (void *plugin, size_t size, uint8_t *buffer);
// New API
void InitVersion (GameVersion gameVersion);
void InitCardReader (CommitCardCallback touch);
+3 -36
View File
@@ -39,7 +39,7 @@ namespace patches::Plugins {
if (event) ((BasicEvent)event) ();
}
}
// Card API
// Low Level Card API
void
WaitTouch (CallBackTouchCard callback, uint64_t touchData) {
for (auto plugin : plugins) {
@@ -47,35 +47,6 @@ namespace patches::Plugins {
if (event) ((WaitTouchEvent)event) (callback, touchData);
}
}
// QR API (deprecated)
void
InitQr (GameVersion gameVersion) {
for (auto plugin : plugins) {
auto event = GetProcAddress (plugin, "InitQr");
if (event) ((SendVersionEvent)event) (gameVersion);
}
}
void
UsingQr () {
for (auto plugin : plugins) {
auto event = GetProcAddress (plugin, "UsingQr");
if (event) ((BasicEvent)event) ();
}
}
void *
CheckQr () {
for (auto plugin : plugins) {
auto event = GetProcAddress (plugin, "UsingQr");
if (event && ((CheckEvent)event) ()) return plugin;
}
return nullptr;
}
size_t
GetQr (void *plugin, size_t size, uint8_t *buffer) {
auto event = GetProcAddress (*(HMODULE *)plugin, "GetQr");
if (event) return ((CopyDataEvent)event) (size, buffer);
else return 0;
}
// New API
void
InitVersion (GameVersion gameVersion) {
@@ -124,10 +95,10 @@ namespace patches::Plugins {
auto name = entry.path ().wstring ();
auto shortName = entry.path ().filename ().wstring ();
if (HMODULE hModule = LoadLibraryW (name.c_str ()); !hModule) {
LogMessage (LogLevel::ERROR, L"Failed to load plugin " + shortName);
LogMessage (LogLevel::ERROR, L"Failed to load plugin: {}", shortName);
} else {
plugins.push_back (hModule);
LogMessage (LogLevel::INFO, L"Loaded plugin " + shortName);
LogMessage (LogLevel::INFO, L"Using plugin: {}", shortName);
}
}
}
@@ -146,8 +117,4 @@ namespace patches::Plugins {
}
}).detach ();
}
}
+8 -18
View File
@@ -234,15 +234,16 @@ namespace Card {
void
Init() {
LogMessage (LogLevel::INFO, "Init Card patches");
LogMessage (LogLevel::DEBUG, "Init Card patches");
if (!emulateCardReader) {
LogMessage (LogLevel::WARN, "[Card] Card reader emulation disabled!");
LogMessage (LogLevel::WARN, "Disable Card Reader Emulation");
INSTALL_FAST_HOOK (bngrw_ReqCancelOfficial);
INSTALL_FAST_HOOK (bngrw_ReqWaitTouchOfficial);
// patches::Plugins::InitCardReader (patches::Scanner::Card::Commit);
return;
}
LogMessage (LogLevel::INFO, "Using Card Reader Emulation");
INSTALL_FAST_HOOK (bngrw_Init)
INSTALL_FAST_HOOK (bngrw_Fin);
INSTALL_FAST_HOOK (bngrw_IsCmdExec);
@@ -295,7 +296,6 @@ namespace Qr {
FAST_HOOK_DYNAMIC (bool, Send3, i64, char) { return true; }
FAST_HOOK_DYNAMIC (bool, Send4, i64, const void *, i64) { return true; }
FAST_HOOK_DYNAMIC (i64, CopyData, i64, void *dest, int length) {
patches::Plugins::UsingQr ();
lastScan = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now ().time_since_epoch ()).count ();
if (state == State::CopyWait && scanQueue.size () > 0) {
std::vector<uint8_t> *data = scanQueue.front ();
@@ -368,17 +368,6 @@ namespace Qr {
if ((lastScan + 200) < std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now ().time_since_epoch ()).count ()) {
state = State::Disable;
patches::Plugins::UpdateStatus (StatusType::QrStatus, false);
} else {
void *plugin = patches::Plugins::CheckQr ();
if (plugin) {
uint8_t *space = (uint8_t *)calloc (600, sizeof (uint8_t));
size_t size = patches::Plugins::GetQr (plugin, 600, space);
if (size > 0) {
std::vector<uint8_t> data = {};
for (size_t i = 0; i < size; i ++) data.push_back (space[i]);
patches::Scanner::Qr::Commit (data);
}
}
}
}
}
@@ -436,13 +425,14 @@ namespace Qr {
void
Init () {
LogMessage (LogLevel::INFO, "Init Qr patches");
LogMessage (LogLevel::DEBUG, "Init Qr patches");
if (!emulateQr) {
LogMessage (LogLevel::WARN, "[QR] QR emulation disabled!");
LogMessage (LogLevel::WARN, "Disable QR Scanner Emulation");
return;
}
patches::Plugins::InitQr (gameVersion);
LogMessage (LogLevel::INFO, "Using QR Scanner Emulation");
SetConsoleOutputCP (CP_UTF8);
auto amHandle = reinterpret_cast<u64> (GetModuleHandle ("AMFrameWork.dll"));
switch (gameVersion) {
@@ -511,7 +501,7 @@ Update() {
void
Init() {
LogMessage (LogLevel::INFO, "Init Scanner patches");
LogMessage (LogLevel::DEBUG, "Init Scanner patches");
patches::Scanner::Card::Init ();
patches::Scanner::Qr::Init ();
}
+24 -21
View File
@@ -61,6 +61,8 @@ public:
if (!success) {
LogMessage (LogLevel::ERROR, L"Failed to parse item: {}\n", this->selectItem);
itemDoc.load_string (L"<root><text-item label=\"@Color/Red;!!!ERROR APPLYING ITEM!!!@Color/Default;\"/></root>");
} else {
LogMessage (LogLevel::DEBUG, L"[TestMode] Add Item: {}", itemDoc.attribute(L"label").as_string ());
}
// if (success) AddHookInLoop (this->registerInit);
std::wstring layoutName = L"layout";
@@ -94,7 +96,7 @@ public:
size_t size = items.size ();
if (size == 0) return node;
size_t maxPage = size <= 14 ? 1 : (size / 13 + (size % 13 > 0));
LogMessage (LogLevel::DEBUG, "Render testmode menu with items(size={}, page={})", size, maxPage);
LogMessage (LogLevel::DEBUG, L"[TestMode] Add Menu {} (items={}, page={})", menuName, size, maxPage);
std::wstring menuName = L"menu";
pugi::xml_node parentNode = node->parent ();
while (parentNode.name() != menuName) parentNode = parentNode.parent ();
@@ -124,12 +126,11 @@ public:
std::vector<pugi::xml_node> refs = {};
for (size_t page = 0; page < maxPage; page ++) {
LogMessage (LogLevel::DEBUG, "Render testmode menu page ({}/{})", page + 1, maxPage);
// LogMessage (LogLevel::DEBUG, L"[TestMenu] menu page ({}/{})", page + 1, maxPage);
pugi::xml_node ref = passing;
size_t maxIndex = MIN(size - page * 13, 13);
for (size_t index = 0; index < maxIndex; index ++) {
LogMessage (LogLevel::DEBUG, "Render testmode menu page ({}/{}) item ({}/{})", page + 1, maxPage, index + 1, maxIndex);
// LogMessage (LogLevel::DEBUG, "Render testmode menu page ({}/{}) item ({}/{})", page + 1, maxPage, index + 1, maxIndex);
if (index >= refs.size ()) {
passing = *(items[page * 13 + index]->Apply (doc, &passing));
if (size > 14) {
@@ -149,7 +150,7 @@ public:
if (size == 14) passing = *(items[13]->Apply (doc, &passing));
}
passing = passing.parent ().last_child ();
LogMessage (LogLevel::DEBUG, "Begin render testmode footer");
// LogMessage (LogLevel::DEBUG, "Begin render testmode footer");
size_t maxIndex = size == 14 ? 14 : MIN(size, 13);
for (size_t i = 0; i < 15 - maxIndex; i++) passing = passing.parent ().insert_child_after (L"break-item", passing);
if (maxPage > 1) {
@@ -163,7 +164,7 @@ public:
exit.load_string (std::format (L"<root><menu-item label=\"EXIT\" menu=\"{}\"/></root>", parentId).c_str ());
passing = passing.parent ().insert_copy_after (exit.first_child ().first_child (), passing);
LogMessage (LogLevel::DEBUG, L"Insert testmode menu menuId: {}, fromId: {}", this->menuId, parentId);
// LogMessage (LogLevel::DEBUG, L"Insert testmode menu menuId: {}, fromId: {}", this->menuId, parentId);
pugi::xml_node root = doc->first_child ();
root.insert_copy_after (menu.first_child ().first_child (), root.first_child ());
return &temp;
@@ -451,7 +452,7 @@ LocalizationCHS () {
void
Init () {
LogMessage (LogLevel::INFO, "Init TestMode patches");
LogMessage (LogLevel::DEBUG, "Init TestMode patches");
const u64 testModeLibrary = (u64)GetModuleHandle ("TestModeLibrary.dll");
const u64 testModeSetMenu = testModeLibrary + 0x99D0;
@@ -467,6 +468,7 @@ Init () {
INSTALL_FAST_HOOK_DYNAMIC (SceneTestModeFinalize, ASLR (0x140479600));
INSTALL_FAST_HOOK_DYNAMIC (SceneFirstInitialize, ASLR (0x1404574B0));
if (Language::CnFontPatches () && std::filesystem::exists ("..\\..\\Data\\x64\\testmode\\DeviceInitialize_china.xml")) {
LogMessage (LogLevel::INFO, L"Using DeviceInitialize: DeviceInitialize_china.xml");
usingDeviceInitialize = L"DeviceInitialize_china.xml";
patches.push_back (safetyhook::create_mid (ASLR (0x140465549), [](SafetyHookContext &ctx)
{ ctx.r8 = 2; ctx.rdx = (uintptr_t)"cn"; ctx.rip = ASLR (0x140465556); })); // DeviceCheck = Loading Font
@@ -478,6 +480,7 @@ Init () {
WRITE_MEMORY (ASLR (0x140CD1E50), wchar_t, L"加载中...\0");
}
if (Language::CnFontPatches () && std::filesystem::exists ("..\\..\\Data\\x64\\testmode\\TestMode_china.xml")) {
LogMessage (LogLevel::INFO, L"Using TestMode: TestMode_china.xml");
usingTestMode = L"TestMode_china.xml";
patches.push_back (safetyhook::create_mid (ASLR (0x14047C603), [](SafetyHookContext &ctx)
{ ctx.r8 = 2; ctx.rdx = (uintptr_t)"cn"; ctx.rip = ASLR (0x14047C610); })); // TestMode = DeviceInitialize
@@ -529,13 +532,13 @@ SetTestModeValue (const wchar_t *itemId, int value) {
Menu *
CreateMenu (const std::wstring &menuName, const std::wstring &menuId) {
LogMessage (LogLevel::DEBUG, L"Create MenuName: {} MenuId: {}", menuName, menuId);
// LogMessage (LogLevel::DEBUG, L"Create MenuName: {} MenuId: {}", menuName, menuId);
return new RegisteredMenu (menuName, menuId);
}
Value *
CreateValue (const std::wstring &key) {
LogMessage (LogLevel::DEBUG, L"Create TestMode Value key: {}", 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);
@@ -545,77 +548,77 @@ CreateValue (const std::wstring &key) {
void
RegisterItem (const std::wstring &item, const std::function<void ()> &initMethod, Menu *menu) {
LogMessage (LogLevel::DEBUG, L"Register \nItem: {}", item);
// LogMessage (LogLevel::DEBUG, L"Register Item: {}", item);
hooks.push_back (initMethod);
menu->RegisterItem (new RegisteredItem (item, [](){}));
}
void
RegisterItem (const std::wstring &item, const std::function<void ()> &initMethod) {
LogMessage (LogLevel::DEBUG, L"Register \nItem: {}", item);
// LogMessage (LogLevel::DEBUG, L"Register Item: {}", item);
hooks.push_back (initMethod);
modManager->RegisterItem (new RegisteredItem (item, [](){}));
}
void
RegisterItem (const std::wstring &item, Menu *menu) {
LogMessage (LogLevel::DEBUG, L"Register \nItem: {}", item);
// LogMessage (LogLevel::DEBUG, L"Register Item: {}", item);
menu->RegisterItem (new RegisteredItem (item, [](){}));
}
void
RegisterItem (const std::wstring &item) {
LogMessage (LogLevel::DEBUG, L"Register \nItem: {}", item);
// LogMessage (LogLevel::DEBUG, L"Register Item: {}", item);
modManager->RegisterItem (new RegisteredItem (item, [](){}));
}
void
RegisterItem (Applicable *item, Menu *menu) {
LogMessage (LogLevel::DEBUG, L"Register Item");
// LogMessage (LogLevel::DEBUG, L"Register Item");
menu->RegisterItem (item);
}
void
RegisterItem (Applicable *item) {
LogMessage (LogLevel::DEBUG, L"Register Item");
// LogMessage (LogLevel::DEBUG, L"Register Item");
modManager->RegisterItem (item);
}
void
RegisterItemAfter (const std::wstring &query, const std::wstring &item, const std::function<void()> &initMethod) {
LogMessage (LogLevel::DEBUG, L"Register \nQuery: {} \nItem: {}", query, item);
// LogMessage (LogLevel::DEBUG, L"Register Query: {} Item: {}", query, item);
hooks.push_back (initMethod);
registeredSingleItems.push_back (new RegisteredSingleItem (query, new RegisteredItem (item, [](){})));
}
void
RegisterItemAfter (const std::wstring &query, const std::wstring &item) {
LogMessage (LogLevel::DEBUG, L"Register \nQuery: {} \nItem: {}", query, item);
// LogMessage (LogLevel::DEBUG, L"Register Query: {} Item: {}", query, item);
registeredSingleItems.push_back (new RegisteredSingleItem (query, new RegisteredItem (item, [](){})));
}
void
RegisterItemAfter (const std::wstring &query, Applicable *item) {
LogMessage (LogLevel::DEBUG, L"Register \nQuery: {} \nItem: ptr", query);
// LogMessage (LogLevel::DEBUG, L"Register Query: {} Item: ptr", query);
registeredSingleItems.push_back (new RegisteredSingleItem (query, item));
}
void
RegisterModify (const std::wstring &query, const std::function<void (pugi::xml_node &)> &nodeModify, const std::function<void ()> &initMethod) {
LogMessage (LogLevel::DEBUG, L"Register \nModify: {}", query);
// LogMessage (LogLevel::DEBUG, L"Register Modify: {}", query);
hooks.push_back (initMethod);
registeredModifies.push_back (new RegisteredModify (query, nodeModify, [](){}));
}
void
RegisterModify (const std::wstring &query, const std::function<void (pugi::xml_node &)> &nodeModify) {
LogMessage (LogLevel::DEBUG, L"Register \nModify: {}", query);
// LogMessage (LogLevel::DEBUG, L"Register Modify: {}", query);
registeredModifies.push_back (new RegisteredModify (query, nodeModify, [](){}));
}
void
RegisterHook (const std::function<void()> &initMethod) {
LogMessage (LogLevel::DEBUG, L"Register Hook");
// LogMessage (LogLevel::DEBUG, L"Register Hook");
hooks.push_back (initMethod);
}
+3 -2
View File
@@ -31,9 +31,10 @@ namespace patches::Timer {
bool setHighResolutionTimer = currentResolution > maximumResolution;
if (setHighResolutionTimer) {
NTSTATUS status = NtSetTimerResolution(maximumResolution, TRUE, &currentResolution);
ULONG targetResolution = currentResolution;
NTSTATUS status = NtSetTimerResolution(maximumResolution, TRUE, &targetResolution);
if (status == 0) {
LogMessage (LogLevel::INFO, "Timer resolution: {}ms -> {}ms", currentResolution / 10000.0, maximumResolution / 10000.0);
LogMessage (LogLevel::INFO, "Using HiRes Timer: {}ms -> {}ms", currentResolution / 10000.0, targetResolution / 10000.0);
} else {
LogMessage (LogLevel::WARN, "Failed to change Timer resolution, status={}", status);
}
+3 -3
View File
@@ -315,7 +315,7 @@ std::vector<SafetyHookMid> datatable_patch = {};
#define DATATABLE_PATCH_REGISTER(location, reg, value, skip) { datatable_patch.push_back(safetyhook::create_mid(location, [](SafetyHookContext &ctx) {ctx.reg = (uintptr_t)(value); ctx.rip = location + skip;})); }
void
PatchDatatable () {
LogMessage (LogLevel::INFO, "Set Datatable Size to 12MB");
LogMessage (LogLevel::INFO, "Using Datatable patch size: 12MB");
for (int i = 0; i < 3; i ++) datatableBuffer[i] = (uint8_t *)malloc (datatableBufferSize);
DATATABLE_PATCH_REGISTER (ASLR (0x1400ABE26), r8, datatableBufferSize, 6);
DATATABLE_PATCH_REGISTER (ASLR (0x1400ABE3A), r8, datatableBufferSize, 6);
@@ -334,7 +334,7 @@ PatchDatatable () {
void
Init () {
LogMessage (LogLevel::INFO, "Init JPN39 patches");
LogMessage (LogLevel::DEBUG, "Init JPN39 patches");
bool unlockSongs = Config::ConfigManager::instance ().getPatchesConfig ().unlock_songs;
double modelResRate = Config::ConfigManager::instance ().getGraphicsConfig ().model_res_rate;
@@ -350,7 +350,7 @@ Init () {
if (modelResRate > 0) {
i32 donModelX = (i32)(xRes * modelResRate);
i32 donModelY = (i32)(yRes * modelResRate);
LogMessage (LogLevel::INFO, "Patch DonModel use resolution {}x{}", donModelX, donModelY);
LogMessage (LogLevel::INFO, "Using DonModel Resolutin: {}x{}", donModelX, donModelY);
WRITE_MEMORY (ASLR (0x1404F3D5B), i32, donModelX);
WRITE_MEMORY (ASLR (0x1404F3D62), i32, donModelY);
}
+21 -14
View File
@@ -9,6 +9,7 @@
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 simpleInput = Config::ConfigManager::instance ().getControllerConfig ().simple_input;
static bool emulateUsio = Config::ConfigManager::instance ().getEmulationConfig ().usio;
extern float axisThreshold;
@@ -35,7 +36,7 @@ float currentControllerAxisState[static_cast<size_t>(SDLAxis::SDL_AXIS_MAX)] = {
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;
int maxCount = 10;
SDL_Window *window;
SDL_Gamepad *controllers[255];
@@ -101,10 +102,10 @@ void KeyboardMainLoop() {
if (usingKeyboard) {
keyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, InputProc, nullptr, 0);
if (keyboardHook == nullptr) LogMessage (LogLevel::ERROR, "Failed to install keyboard hook!\n");
else LogMessage (LogLevel::INFO, "KeyboardLL hook installed!");
else LogMessage (LogLevel::DEBUG, "KeyboardLL hook installed!");
}
if (maxCount > 2) LogMessage (LogLevel::ERROR, "CHEATING MODE! max count is set to {}", maxCount);
LogMessage (LogLevel::WARN, "(experimental) Using Async IO!");
if (maxCount > 2) LogMessage (LogLevel::WARN, "Using Cache count max={}", maxCount);
LogMessage (LogLevel::INFO, "Using Async Keyboard");
MSG msg;
while (GetMessage(&msg, hwnd, 0, 0) > 0) {
TranslateMessage(&msg);
@@ -115,9 +116,7 @@ void KeyboardMainLoop() {
void
InitializeKeyboard () {
if (usingKeyboard) {
std::thread (KeyboardMainLoop).detach ();
}
std::thread (KeyboardMainLoop).detach ();
}
void
@@ -137,8 +136,10 @@ InitializePoll (HWND windowHandle) {
usingController = Config::ConfigManager::instance ().getKeyBindings ().usingController();
usingSDLEvent = usingMouse || usingController;
if (simpleInput) LogMessage (LogLevel::INFO, "Using Simple Input (1-1 bind)");
atexit ([](){ if (currentLayout != nullptr) ActivateKeyboardLayout (currentLayout, KLF_SETFORPROCESS);});
InitializeKeyboard ();
if (usingKeyboard) InitializeKeyboard ();
if (usingSDLEvent) {
LogMessage (LogLevel::DEBUG, "InitializePoll");
bool hasRumble = true;
@@ -258,7 +259,7 @@ void
UpdatePoll (HWND windowHandle) {
if (!CheckForegroundWindow (windowHandle)) return;
if (!emulateUsio) return;
CleanPoll ();
if (!simpleInput) CleanPoll ();
if (usingSDLEvent) {
SDL_Event event;
SDL_Gamepad *controller;
@@ -356,8 +357,11 @@ int maxKeyboardCount = 1;
bool
KeyboardIsTapped (const uint8_t keycode) {
if (keyboardCount[keycode] > 0) {
keyboardDiff[keycode] = 1;
keyboardClean = true;
if (simpleInput) keyboardCount[keycode] --;
else {
keyboardDiff[keycode] = 1;
keyboardClean = true;
}
return true;
} return false;
}
@@ -383,7 +387,8 @@ bool
GetMouseScrollIsTapped (const Scroll scroll) {
if (scroll == Scroll::MOUSE_SCROLL_INVALID) return false;
if (mouseWheelCount[(int)scroll - 1] > 0) {
mouseWheelDiff[(int)scroll - 1] = 1;
if (simpleInput) mouseWheelCount[(int)scroll - 1] --;
else mouseWheelDiff[(int)scroll - 1] = 1;
return true;
} return false;
}
@@ -397,7 +402,8 @@ int maxButtonCount = 1;
bool
ControllerButtonIsTapped (const SDL_GamepadButton button) {
if (controllerCount[button] > 0) {
controllerDiff[button] = 1;
if (simpleInput) controllerCount[button] --;
else controllerDiff[button] = 1;
return true;
} return false;
}
@@ -410,7 +416,8 @@ ControllerAxisIsDown (const SDLAxis axis) {
bool
ControllerAxisIsTapped (const SDLAxis axis) {
if (controllerAxisCount[(int)axis] > 0) {
controllerAxisDiff[(int)axis] = 1;
if (simpleInput) controllerAxisCount[(int)axis] --;
else controllerAxisDiff[(int)axis] = 1;
return true;
} return false;
}