fullscreen & enhance auto_ime & language & several clean up & remove dxgi (seems will cause strange behavior only if you included it)

This commit is contained in:
ptmaster
2024-12-30 23:21:12 +08:00
parent 899445a09c
commit 6a4814b931
11 changed files with 137 additions and 101 deletions
+8 -2
View File
@@ -2,6 +2,11 @@ cmake_minimum_required(VERSION 3.25)
project(TaikoArcadeLoader VERSION 1.0.0 LANGUAGES C CXX)
# Set runtime library to static
if(MSVC)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>" CACHE INTERNAL "")
endif()
# Set C and C++ standards
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 23)
@@ -134,8 +139,8 @@ set(SOURCES
src/pollasync.cpp
src/bnusio.cpp
src/patches/amauth.cpp
src/patches/dxgi.cpp
src/patches/fpslimiter.cpp
# src/patches/dxgi.cpp
# src/patches/fpslimiter.cpp
src/patches/audio.cpp
src/patches/plugins.cpp
src/patches/scanner.cpp
@@ -143,6 +148,7 @@ set(SOURCES
src/patches/testmode.cpp
src/patches/timer.cpp
src/patches/language.cpp
# src/patches/unlimitsong.cpp
src/patches/versions/JPN00.cpp
src/patches/versions/JPN08.cpp
src/patches/versions/JPN39.cpp
+6 -7
View File
@@ -15,7 +15,6 @@ version = "auto" # Patch version
# | - JPN39: For use with Taiko JPN 39.06
# | - CHN00: For use with Taiko CHN 00.32
unlock_songs = true
high_res_timer = true # (experimental) Enable High Resolution Timer, which might improve judgement timing
[patches.chn00] # These patches are only available for version CHN00
fix_language = false # Sync test mode language to attract etc
@@ -33,14 +32,14 @@ qr = true # Disable this if you want to use an original Namco
[graphics]
res = { x = 1920, y = 1080 }
windowed = false
windowed = false # not windowed will automatically fullscreen
cursor = true
vsync = false
fpslimit = 120
vsync = false # enable this if you are using a 120fps screen (and use "Let Application Decide" in Nvidia panel)
# fpslimit = 0 # temporoly remove it, limit it to 120 in Nvidia panel instead!
[audio]
wasapi_shared = true # Wasapi shared mode, allows you to have multiple audio sources at once at a cost of having higher latency.
wasapi_shared = false # Wasapi shared mode, allows you to have multiple audio sources at once at a cost of having higher latency.
asio = false # Use asio audio mode
asio_driver = "ASIO4ALL v2" # Asio driver name
# | If you're not using asio4all, open up regedit then navigate to HKEY_LOCAL_MACHINE\SOFTWARE\ASIO for your driver's name.
@@ -60,12 +59,12 @@ song_no = [] # Song noes used for custom folder
[controller]
wait_period = 4 # Input interval (if using taiko drum controller, should be set to 0)
wait_period = 0 # Input interval (if using taiko drum controller, should be set to 0)
analog_input = false # Use analog input (you need a compatible controller, this allows playing small and big notes like on arcade cabinets)
[keyboard]
auto_ime = false # Automatically change to english ime mode upon game startup
auto_ime = true # Automatically change to english ime mode upon game startup
jp_layout = false # Use jp layout scan code (if using jp layout keyboard, must be set to true)
+3 -21
View File
@@ -13,22 +13,11 @@ extern char accessCode1[21];
extern char accessCode2[21];
extern char chipId1[33];
extern char chipId2[33];
extern bool autoIme;
extern bool emulateUsio;
extern bool emulateCardReader;
extern bool acceptInvalidCards;
extern HWND hGameWnd;
typedef i32 (*callbackAttach) (i32, i32, i32 *);
typedef void (*callbackTouch) (i32, i32, u8[168], u64);
typedef void event ();
typedef void waitTouchEvent (callbackTouch, u64);
bool waitingForTouch = false;
callbackTouch touchCallback;
u64 touchData;
callbackAttach attachCallback;
i32 *attachData;
Keybindings EXIT = {.keycodes = {VK_ESCAPE}};
Keybindings TEST = {.keycodes = {VK_F1}};
Keybindings SERVICE = {.keycodes = {VK_F2}};
@@ -64,8 +53,7 @@ bool updateByCoin = false;
HWND windowHandle = nullptr;
float axisThreshold = 0.6f;
u8 inputState = 1 | (1 << 2);
bool globalKeyboard = false;;
HKL currentLayout;
bool globalKeyboard = false;
namespace bnusio {
#define RETURN_FALSE(returnType, functionName, ...) \
@@ -132,7 +120,7 @@ bnusio_GetSwIn () {
}
bool waitAll = false;
short drumWaitPeriod = 4;
short drumWaitPeriod = 0;
bool analogInput = false;
bool valueStates[] = {false, false, false, false, false, false, false, false};
@@ -405,11 +393,6 @@ Update () {
if (!inited) {
windowHandle = FindWindowA ("nuFoundation.Window", nullptr);
InitializePoll (windowHandle);
if (autoIme) {
currentLayout = GetKeyboardLayout (0);
auto engLayout = LoadKeyboardLayout (TEXT ("00000409"), KLF_ACTIVATE);
ActivateKeyboardLayout (engLayout, KLF_SETFORPROCESS);
}
patches::Plugins::Init ();
inited = true;
}
@@ -439,7 +422,6 @@ Update () {
void
Close () {
if (autoIme) ActivateKeyboardLayout (currentLayout, KLF_SETFORPROCESS);
// patches::Plugins::Exit ();
CleanupLogger ();
}
+49 -2
View File
@@ -24,13 +24,17 @@ char accessCode2[21] = "00000000000000000002";
char chipId1[33] = "00000000000000000000000000000001";
char chipId2[33] = "00000000000000000000000000000002";
bool windowed = false;
bool autoIme = false;
bool autoIme = true;
bool jpLayout = false;
bool cursor = true;
bool emulateUsio = true;
bool emulateCardReader = true;
bool emulateQr = true;
bool acceptInvalidCards = false;
HKL currentLayout = nullptr;
i32 xRes = 1920;
i32 yRes = 1080;
bool vsync = false;
std::string logLevelStr = "INFO";
bool logToFile = true;
@@ -189,6 +193,11 @@ DllMain (HMODULE module, const DWORD reason, LPVOID reserved) {
if (const auto graphics = openConfigSection (config, "graphics")) {
windowed = readConfigBool (graphics, "windowed", windowed);
cursor = readConfigBool (graphics, "cursor", cursor);
if (auto res = openConfigSection (graphics, "res")) {
xRes = static_cast<i32> (readConfigInt (res, "x", xRes));
yRes = static_cast<i32> (readConfigInt (res, "y", yRes));
}
vsync = readConfigBool (graphics, "vsync", vsync);
}
if (const auto keyboard = openConfigSection (config, "keyboard")) {
autoIme = readConfigBool (keyboard, "auto_ime", autoIme);
@@ -201,6 +210,43 @@ DllMain (HMODULE module, const DWORD reason, LPVOID reserved) {
}
}
auto activeWindow = GetActiveWindow();
HMONITOR monitor = MonitorFromWindow(activeWindow, MONITOR_DEFAULTTONEAREST);
// Get the logical width and height of the monitor
MONITORINFOEX monitorInfoEx;
monitorInfoEx.cbSize = sizeof(monitorInfoEx);
GetMonitorInfo(monitor, &monitorInfoEx);
auto cxLogical = monitorInfoEx.rcMonitor.right - monitorInfoEx.rcMonitor.left;
auto cyLogical = monitorInfoEx.rcMonitor.bottom - monitorInfoEx.rcMonitor.top;
// Get the physical width and height of the monitor
DEVMODE devMode;
devMode.dmSize = sizeof(devMode);
devMode.dmDriverExtra = 0;
EnumDisplaySettings(monitorInfoEx.szDevice, ENUM_CURRENT_SETTINGS, &devMode);
auto cxPhysical = devMode.dmPelsWidth;
auto cyPhysical = devMode.dmPelsHeight;
// Calculate the scaling factor
auto horizontalScale = (static_cast<double> (cxPhysical) / static_cast<double> (cxLogical));
auto verticalScale = (static_cast<double> (cyPhysical) / static_cast<double> (cyLogical));
if (windowed) {
xRes = (int)(xRes / horizontalScale);
yRes = (int)(yRes / verticalScale);
} else {
xRes = cxLogical;
yRes = cyLogical;
}
LogMessage (LogLevel::INFO, "Boot with {} mode ({}x{})", windowed ? "window" : "fullscreen", xRes, yRes);
if (autoIme) {
currentLayout = GetKeyboardLayout (0);
auto engLayout = LoadKeyboardLayout (TEXT ("00000409"), KLF_ACTIVATE);
ActivateKeyboardLayout (engLayout, KLF_SETFORPROCESS);
LogMessage (LogLevel::DEBUG, "Initial change KeyboardLayout {}", LOWORD(engLayout));
}
// Update the logger with the level read from config file.
InitializeLogger (GetLogLevel (logLevelStr), logToFile);
LogMessage (LogLevel::INFO, "Application started.");
@@ -264,11 +310,12 @@ DllMain (HMODULE module, const DWORD reason, LPVOID reserved) {
patches::Scanner::Init ();
patches::Audio::Init ();
patches::Dxgi::Init ();
// patches::Dxgi::Init ();
patches::AmAuth::Init ();
patches::Language::Init ();
patches::TestMode::Init ();
patches::LayeredFs::Init ();
// patches::UnlimitSong::Init ();
std::chrono::duration<double> duration = std::chrono::high_resolution_clock::now() - start;
LogMessage (LogLevel::INFO, "==== Finished Loading patches! using: {:.2f}ms", duration.count () * 1000);
+40 -23
View File
@@ -375,8 +375,11 @@ FAST_HOOK_DYNAMIC (u64, GraphicBaseGetLanguageType, u64 a1, void *a2) {
return (u64)GetLanguageType (taiko_assign, language, a2);
}
std::string *season_nulm = nullptr;
std::string *season_nutexb = nullptr;
bool titleExistSeason = true, titleExistMaid = true, titleExistMaidCn = true;
std::string seasonNulm = "title_season.nulm", seasonNutexb = "title_" + season () + ".nutexb";
std::string maidNulmCn = "title_maid.nulm", maidNutexbCn = "title_maid.nutexb";
std::string maidNulm = "title_maid.nulm", maidNutexb = "title_maid.nutexb";
TestMode::Value *titleScreen = TestMode::CreateValue (L"ModTitleScreen");
void
Init () {
switch (gameVersion) {
@@ -419,35 +422,49 @@ Init () {
language_patch.push_back (safetyhook::create_mid (ASLR (0x14012B8C8), [](SafetyHookContext &ctx)
{ InjectLanguageType (ctx.rbp + 0x180 + ctx.rax * 8, ctx.rdx); ctx.rip = ASLR (0x14012B8D0); })); // ScoreGetLanguageType
LayeredFs::RegisterBefore ([&] (const std::string &originalFileName, const std::string &currentFileName) -> std::string {
if (language != 4 || currentFileName.starts_with ("F:\\") || currentFileName.find ("\\lumen\\") == std::string::npos) return "";
if (language != 4 || currentFileName.starts_with ("F:\\lumen\\") || currentFileName.find ("\\lumen\\") == std::string::npos) return "";
std::string fileName = std::string (currentFileName);
fileName = replace (fileName, "\\lumen\\", "\\lumen_cn\\");
if (std::filesystem::exists (fileName)) return fileName;
return "";
});
LayeredFs::RegisterBefore ([&] (const std::string &originalFileName, const std::string &currentFileName) -> std::string {
if (language != 4 || currentFileName.starts_with ("F:\\")) return "";
if (currentFileName.ends_with ("title.nulm")) {
std::string fileName = std::string (currentFileName);
if (season_nulm == nullptr) {
fileName = replace (fileName, "title.nulm", "title_season.nulm");
if (std::filesystem::exists (fileName)) {
std::string nutexb = std::string (currentFileName);
nutexb = replace (nutexb, "title.nulm", "title_" + season () + ".nutexb");
if (std::filesystem::exists (nutexb)) {
season_nulm = new std::string (fileName), season_nutexb = new std::string (nutexb);
return *season_nulm;
}
TestMode::RegisterItem (
L"<select-item label=\"TITLE SCREEN(NEED FILES)\" param-offset-x=\"35\" replace-text=\"0:DEFAULT, 1:SEASON(CHN), "
L"2:MAID\" group=\"Setting\" id=\"ModTitleScreen\" max=\"2\" min=\"0\" default=\"0\"/>",
[&](){
std::string base[] = {"..\\..\\Data\\x64\\lumen\\000_default\\attract\\", "..\\..\\Data_mods\\x64\\lumen\\000_default\\attract\\"};
std::string baseCn[] = {"..\\..\\Data\\x64\\lumen_cn\\000_default\\attract\\", "..\\..\\Data_mods\\x64\\lumen_cn\\000_default\\attract\\"};
for (std::string prefix : baseCn) {
if (!seasonNulm.starts_with ("..\\") && std::filesystem::exists (prefix + seasonNulm)) seasonNulm = prefix + seasonNulm;
if (!seasonNutexb.starts_with ("..\\") && std::filesystem::exists (prefix + seasonNutexb)) seasonNutexb = prefix + seasonNutexb;
}
if (!seasonNulm.starts_with ("..\\") || !seasonNutexb.starts_with ("..\\")) titleExistSeason = false;
for (std::string prefix : baseCn) {
if (!maidNulmCn.starts_with ("..\\") && std::filesystem::exists (prefix + maidNulmCn)) maidNulmCn = prefix + maidNulmCn;
if (!maidNutexbCn.starts_with ("..\\") && std::filesystem::exists (prefix + maidNutexbCn)) maidNutexbCn = prefix + maidNutexbCn;
}
if (!maidNulmCn.starts_with ("..\\") || !maidNutexbCn.starts_with ("..\\")) titleExistMaidCn = false;
for (std::string prefix : base) {
if (!maidNulm.starts_with ("..\\") && std::filesystem::exists (prefix + maidNulm)) maidNulm = prefix + maidNulm;
if (!maidNutexb.starts_with ("..\\") && std::filesystem::exists (prefix + maidNutexb)) maidNutexb = prefix + maidNutexb;
}
if (!maidNulm.starts_with ("..\\") || !maidNutexb.starts_with ("..\\")) titleExistMaid = false;
LayeredFs::RegisterBefore ([&] (const std::string &originalFileName, const std::string &currentFileName) -> std::string {
if (currentFileName.starts_with ("F:\\lumen\\") || currentFileName.find ("title") == std::string::npos) return "";
if (currentFileName.ends_with ("title.nulm")) {
if (language == 4 && titleScreen->Read () == 1 && titleExistSeason) return seasonNulm;
if (language == 4 && titleScreen->Read () == 2 && titleExistMaidCn) return maidNulmCn;
if (titleScreen->Read () == 2 && titleExistMaid) return maidNulm;
} else if (currentFileName.ends_with ("title.nutexb")) {
LogMessage (LogLevel::DEBUG, "nutexb");
if (language == 4 && titleScreen->Read () == 1 && titleExistSeason) return seasonNutexb;
if (language == 4 && titleScreen->Read () == 2 && titleExistMaidCn) return maidNutexbCn;
if (titleScreen->Read () == 2 && titleExistMaid) return maidNutexb;
}
season_nulm = new std::string (""), season_nutexb = new std::string ("");
return "";
} else return *season_nulm;
} else if (currentFileName.ends_with ("title.nutexb") && season_nutexb != nullptr) {
return *season_nutexb;
} else return "";
});
});
});
} break;
}
}
+4 -1
View File
@@ -129,5 +129,8 @@ void Init ();
namespace Language {
boolean CnFontPatches ();
void Init ();
}
} // namespace Language
namespace UnlimitSong {
void Init ();
} // namespace UnlimitSong
} // namespace patches
+3 -11
View File
@@ -2,6 +2,9 @@
#include "../patches.h"
extern std::string chassisId;
extern i32 xRes;
extern i32 yRes;
extern bool vsync;
namespace patches::CHN00 {
int language = 0;
@@ -101,9 +104,6 @@ ReplaceLeaBufferAddress (const std::vector<uintptr_t> &bufferAddresses, void *ne
void
Init () {
LogMessage (LogLevel::INFO, "Init CHN00 patches");
i32 xRes = 1920;
i32 yRes = 1080;
bool vsync = false;
bool unlockSongs = true;
bool fixLanguage = false;
bool demoMovie = true;
@@ -139,14 +139,6 @@ Init () {
modeCollabo026 = readConfigBool (chn00, "mode_collabo026", modeCollabo026);
}
}
if (const auto graphics = openConfigSection (config_ptr.get (), "graphics")) {
if (const auto res = openConfigSection (graphics, "res")) {
xRes = static_cast<i32> (readConfigInt (res, "x", xRes));
yRes = static_cast<i32> (readConfigInt (res, "y", yRes));
}
vsync = readConfigBool (graphics, "vsync", vsync);
}
}
// Apply common config patch
+4 -11
View File
@@ -1,6 +1,10 @@
#include "helpers.h"
#include "../patches.h"
extern i32 xRes;
extern i32 yRes;
extern bool vsync;
namespace patches::JPN00 {
HOOK_DYNAMIC (char, AMFWTerminate, i64) { return 0; }
@@ -37,9 +41,6 @@ ReplaceLeaBufferAddress (const std::vector<uintptr_t> &bufferAddresses, void *ne
void
Init () {
LogMessage (LogLevel::INFO, "Init JNP00 patches");
i32 xRes = 1920;
i32 yRes = 1080;
bool vsync = false;
bool unlockSongs = true;
const auto configPath = std::filesystem::current_path () / "config.toml";
@@ -47,14 +48,6 @@ Init () {
if (config_ptr) {
if (const auto patches = openConfigSection (config_ptr.get (), "patches"))
unlockSongs = readConfigBool (patches, "unlock_songs", unlockSongs);
if (const auto graphics = openConfigSection (config_ptr.get (), "graphics")) {
if (const auto res = openConfigSection (graphics, "res")) {
xRes = static_cast<i32> (readConfigInt (res, "x", xRes));
yRes = static_cast<i32> (readConfigInt (res, "y", yRes));
}
vsync = readConfigBool (graphics, "vsync", vsync);
}
}
// Apply common config patch
+3 -11
View File
@@ -3,6 +3,9 @@
extern u64 song_data_size;
extern void *song_data;
extern i32 xRes;
extern i32 yRes;
extern bool vsync;
#define RDX_MOV 0x48, 0xBA
#define R8_MOV 0x49, 0xB8
@@ -48,23 +51,12 @@ ReplaceLeaBufferAddress (const std::vector<uintptr_t> &bufferAddresses, void *ne
void
Init () {
LogMessage (LogLevel::INFO, "Init JPN08 patches");
i32 xRes = 1920;
i32 yRes = 1080;
bool vsync = false;
bool unlockSongs = true;
auto configPath = std::filesystem::current_path () / "config.toml";
std::unique_ptr<toml_table_t, void (*) (toml_table_t *)> config_ptr (openConfig (configPath), toml_free);
if (config_ptr) {
if (auto patches = openConfigSection (config_ptr.get (), "patches")) unlockSongs = readConfigBool (patches, "unlock_songs", unlockSongs);
if (auto graphics = openConfigSection (config_ptr.get (), "graphics")) {
if (auto res = openConfigSection (graphics, "res")) {
xRes = static_cast<i32> (readConfigInt (res, "x", xRes));
yRes = static_cast<i32> (readConfigInt (res, "y", yRes));
}
vsync = readConfigBool (graphics, "vsync", vsync);
}
}
// Apply common config patch
+4 -11
View File
@@ -3,6 +3,10 @@
#include "../patches.h"
#include <map>
extern i32 xRes;
extern i32 yRes;
extern bool vsync;
namespace patches::JPN39 {
int language = 0;
FAST_HOOK_DYNAMIC (char, AMFWTerminate, i64) {
@@ -281,9 +285,6 @@ ReplaceDatatableBufferAddresses () {
void
Init () {
LogMessage (LogLevel::INFO, "Init JPN39 patches");
i32 xRes = 1920;
i32 yRes = 1080;
bool vsync = false;
bool unlockSongs = true;
auto configPath = std::filesystem::current_path () / "config.toml";
@@ -292,14 +293,6 @@ Init () {
if (auto patches = openConfigSection (config_ptr.get (), "patches")) {
unlockSongs = readConfigBool (patches, "unlock_songs", unlockSongs);
}
if (auto graphics = openConfigSection (config_ptr.get (), "graphics")) {
if (auto res = openConfigSection (graphics, "res")) {
xRes = static_cast<i32> (readConfigInt (res, "x", xRes));
yRes = static_cast<i32> (readConfigInt (res, "y", yRes));
}
vsync = readConfigBool (graphics, "vsync", vsync);
}
}
// Hook to get AppAccessor and ComponentAccessor
+13 -1
View File
@@ -10,6 +10,8 @@ extern int exited;
extern u8 inputState;
extern float axisThreshold;
extern bool globalKeyboardInput;
extern bool autoIme;
extern HKL currentLayout;
bool wndForeground = false;
bool usingKeyboard = false;
@@ -201,6 +203,7 @@ InitializePoll (HWND windowHandle) {
usingController = inputState & (1 << 2);
usingSDLEvent = usingMouse || usingController;
atexit ([](){ if (currentLayout != nullptr) ActivateKeyboardLayout (currentLayout, KLF_SETFORPROCESS);});
InitializeKeyboard ();
if (usingSDLEvent) {
LogMessage (LogLevel::DEBUG, "InitializePoll");
@@ -267,9 +270,18 @@ InitializePoll (HWND windowHandle) {
bool
CheckForegroundWindow (HWND processWindow) {
if (processWindow == nullptr) return false;
if (wndForeground ^ (processWindow == GetForegroundWindow ())) {
HWND foregroundWnd = GetForegroundWindow ();
if (wndForeground ^ (processWindow == foregroundWnd)) {
wndForeground = !wndForeground;
LogMessage (LogLevel::DEBUG, "window focus={}", wndForeground);
if (autoIme) {
if (wndForeground) {
currentLayout = GetKeyboardLayout (0);
auto engLayout = LoadKeyboardLayout (TEXT ("00000409"), KLF_ACTIVATE);
ActivateKeyboardLayout (engLayout, KLF_SETFORPROCESS);
LogMessage (LogLevel::DEBUG, "(experimental) auto change KeyboardLayout {}", LOWORD(engLayout));
}
}
}
return wndForeground;
}