Change clang-format settings and format all codes

This commit is contained in:
esuo1198
2024-04-26 16:01:00 +09:00
parent 6a4082d511
commit bf2f54df84
15 changed files with 2033 additions and 2017 deletions
+4 -3
View File
@@ -1,10 +1,10 @@
BasedOnStyle: LLVM
BasedOnStyle: GNU
IndentWidth: 4
TabWidth: 4
UseTab: ForIndentation
UseTab: Never
IndentCaseLabels: False
BreakBeforeBraces: Attach
ColumnLimit: 200
ColumnLimit: 150
AlignConsecutiveAssignments: Consecutive
AlignConsecutiveMacros: Consecutive
AllowShortBlocksOnASingleLine: Always
@@ -19,3 +19,4 @@ AlwaysBreakAfterReturnType: TopLevelDefinitions
RemoveBracesLLVM: True
AlignEscapedNewlines: Left
AccessModifierOffset: -4
Cpp11BracedListStyle: True
+217 -212
View File
@@ -45,7 +45,7 @@ Keybindings P2_RIGHT_BLUE = {};
namespace bnusio {
#define RETURN_FALSE(returnType, functionName, ...) \
returnType functionName (__VA_ARGS__) { return 0; }
returnType functionName (__VA_ARGS__) { return 0; }
extern "C" {
RETURN_FALSE (i64, bnusio_ClearSram);
@@ -90,15 +90,16 @@ RETURN_FALSE (i64, bnusio_ResetCoin);
RETURN_FALSE (i64, bnusio_DecCoin, i32 a1, u16 a2);
size_t
bnusio_GetFirmwareVersion () {
return 126;
return 126;
}
u16 drumMin = 15000;
u16 drumMax = 30000;
u16 drumWaitPeriod = 4;
u16 lastHitValue = drumMin;
Keybindings *analogButtons[] = {&P1_LEFT_BLUE, &P1_LEFT_RED, &P1_RIGHT_RED, &P1_RIGHT_BLUE, &P2_LEFT_BLUE, &P2_LEFT_RED, &P2_RIGHT_RED, &P2_RIGHT_BLUE};
u16 lastHitValue = drumMin;
Keybindings *analogButtons[]
= {&P1_LEFT_BLUE, &P1_LEFT_RED, &P1_RIGHT_RED, &P1_RIGHT_BLUE, &P2_LEFT_BLUE, &P2_LEFT_RED, &P2_RIGHT_RED, &P2_RIGHT_BLUE};
u16 buttonWaitPeriodP1 = 0;
u16 buttonWaitPeriodP2 = 0;
@@ -113,53 +114,54 @@ SDLAxis analogBindings[] = {
u16
bnusio_GetAnalogIn (u8 which) {
u16 analogValue;
if (useTaikoController) {
analogValue = (u16)(32768 * ControllerAxisIsDown (analogBindings[which]));
if (analogValue > 100) return analogValue;
return 0;
}
auto button = analogButtons[which];
if (which == 0) {
if (buttonWaitPeriodP1 > 0) buttonWaitPeriodP1--;
if (buttonWaitPeriodP2 > 0) buttonWaitPeriodP2--;
}
bool isP1 = which / 4 == 0;
if ((isP1 && !buttonQueueP1.empty ()) || (!isP1 && !buttonQueueP2.empty ())) {
if ((isP1 && buttonQueueP1.front () == which && buttonWaitPeriodP1 == 0) || (!isP1 && buttonQueueP2.front () == which && buttonWaitPeriodP2 == 0)) {
if (isP1) {
buttonQueueP1.pop ();
buttonWaitPeriodP1 = drumWaitPeriod;
} else {
buttonQueueP2.pop ();
buttonWaitPeriodP2 = drumWaitPeriod;
}
u16 analogValue;
if (useTaikoController) {
analogValue = (u16)(32768 * ControllerAxisIsDown (analogBindings[which]));
if (analogValue > 100) return analogValue;
return 0;
}
auto button = analogButtons[which];
if (which == 0) {
if (buttonWaitPeriodP1 > 0) buttonWaitPeriodP1--;
if (buttonWaitPeriodP2 > 0) buttonWaitPeriodP2--;
}
bool isP1 = which / 4 == 0;
if ((isP1 && !buttonQueueP1.empty ()) || (!isP1 && !buttonQueueP2.empty ())) {
if ((isP1 && buttonQueueP1.front () == which && buttonWaitPeriodP1 == 0)
|| (!isP1 && buttonQueueP2.front () == which && buttonWaitPeriodP2 == 0)) {
if (isP1) {
buttonQueueP1.pop ();
buttonWaitPeriodP1 = drumWaitPeriod;
} else {
buttonQueueP2.pop ();
buttonWaitPeriodP2 = drumWaitPeriod;
}
lastHitValue++;
if (lastHitValue >= drumMax) lastHitValue = drumMin;
return lastHitValue;
}
if (IsButtonTapped (*button)) {
if (isP1) buttonQueueP1.push (which);
else buttonQueueP2.push (which);
}
return 0;
} else if (IsButtonTapped (*button)) {
if (isP1 && buttonWaitPeriodP1 > 0) {
buttonQueueP1.push (which);
return 0;
} else if (!isP1 && buttonWaitPeriodP2 > 0) {
buttonQueueP2.push (which);
return 0;
}
if (isP1) buttonWaitPeriodP1 = drumWaitPeriod;
else buttonWaitPeriodP2 = drumWaitPeriod;
lastHitValue++;
if (lastHitValue >= drumMax) lastHitValue = drumMin;
return lastHitValue;
} else {
return 0;
}
lastHitValue++;
if (lastHitValue >= drumMax) lastHitValue = drumMin;
return lastHitValue;
}
if (IsButtonTapped (*button)) {
if (isP1) buttonQueueP1.push (which);
else buttonQueueP2.push (which);
}
return 0;
} else if (IsButtonTapped (*button)) {
if (isP1 && buttonWaitPeriodP1 > 0) {
buttonQueueP1.push (which);
return 0;
} else if (!isP1 && buttonWaitPeriodP2 > 0) {
buttonQueueP2.push (which);
return 0;
}
if (isP1) buttonWaitPeriodP1 = drumWaitPeriod;
else buttonWaitPeriodP2 = drumWaitPeriod;
lastHitValue++;
if (lastHitValue >= drumMax) lastHitValue = drumMin;
return lastHitValue;
} else {
return 0;
}
}
bool testEnabled = false;
@@ -169,105 +171,107 @@ HWND windowHandle = nullptr;
HKL currentLayout;
u16 __fastcall bnusio_GetCoin (i32 a1) {
if (a1 != 1) return coin_count;
if (a1 != 1) return coin_count;
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);
}
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);
}
for (auto plugin : plugins) {
auto initEvent = GetProcAddress (plugin, "Init");
if (initEvent) initEvent ();
}
for (auto plugin : plugins) {
auto initEvent = GetProcAddress (plugin, "Init");
if (initEvent) initEvent ();
}
inited = true;
}
inited = true;
}
UpdatePoll (windowHandle);
if (IsButtonTapped (COIN_ADD) && !testEnabled) coin_count++;
if (IsButtonTapped (TEST)) testEnabled = !testEnabled;
if (IsButtonTapped (EXIT)) ExitProcess (0);
if (waitingForTouch) {
static u8 cardData[168] = {0x01, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0x2E, 0x58, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7F, 0x5C, 0x97, 0x44, 0xF0, 0x88, 0x04, 0x00, 0x43, 0x26, 0x2C, 0x33, 0x00, 0x04, 0x06, 0x10, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x4E, 0x42, 0x47, 0x49, 0x43, 0x36, 0x00, 0x00, 0xFA, 0xE9, 0x69, 0x00, 0xF6, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
bool hasInserted = false;
if (IsButtonTapped (CARD_INSERT_1)) {
for (auto plugin : plugins) {
FARPROC insertEvent = GetProcAddress (plugin, "BeforeCard1Insert");
if (insertEvent) ((event *)insertEvent) ();
}
for (auto plugin : plugins) {
FARPROC insertEvent = GetProcAddress (plugin, "Card1Insert");
if (insertEvent) {
((event *)insertEvent) ();
hasInserted = true;
}
}
if (!hasInserted) {
memcpy (cardData + 0x2C, chipId1, 33);
memcpy (cardData + 0x50, accessCode1, 21);
touchCallback (0, 0, cardData, touchData);
}
} else if (IsButtonTapped (CARD_INSERT_2)) {
for (auto plugin : plugins) {
FARPROC insertEvent = GetProcAddress (plugin, "BeforeCard2Insert");
if (insertEvent) ((event *)insertEvent) ();
}
for (auto plugin : plugins) {
FARPROC insertEvent = GetProcAddress (plugin, "Card2Insert");
if (insertEvent) {
((event *)insertEvent) ();
hasInserted = true;
}
}
if (!hasInserted) {
memcpy (cardData + 0x2C, chipId2, 33);
memcpy (cardData + 0x50, accessCode2, 21);
touchCallback (0, 0, cardData, touchData);
}
}
}
UpdatePoll (windowHandle);
if (IsButtonTapped (COIN_ADD) && !testEnabled) coin_count++;
if (IsButtonTapped (TEST)) testEnabled = !testEnabled;
if (IsButtonTapped (EXIT)) ExitProcess (0);
if (waitingForTouch) {
static u8 cardData[168]
= {0x01, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0x2E, 0x58, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x5C, 0x97, 0x44, 0xF0, 0x88, 0x04, 0x00, 0x43, 0x26, 0x2C, 0x33, 0x00, 0x04,
0x06, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x42, 0x47, 0x49, 0x43, 0x36,
0x00, 0x00, 0xFA, 0xE9, 0x69, 0x00, 0xF6, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
bool hasInserted = false;
if (IsButtonTapped (CARD_INSERT_1)) {
for (auto plugin : plugins) {
FARPROC insertEvent = GetProcAddress (plugin, "BeforeCard1Insert");
if (insertEvent) ((event *)insertEvent) ();
}
for (auto plugin : plugins) {
FARPROC insertEvent = GetProcAddress (plugin, "Card1Insert");
if (insertEvent) {
((event *)insertEvent) ();
hasInserted = true;
}
}
if (!hasInserted) {
memcpy (cardData + 0x2C, chipId1, 33);
memcpy (cardData + 0x50, accessCode1, 21);
touchCallback (0, 0, cardData, touchData);
}
} else if (IsButtonTapped (CARD_INSERT_2)) {
for (auto plugin : plugins) {
FARPROC insertEvent = GetProcAddress (plugin, "BeforeCard2Insert");
if (insertEvent) ((event *)insertEvent) ();
}
for (auto plugin : plugins) {
FARPROC insertEvent = GetProcAddress (plugin, "Card2Insert");
if (insertEvent) {
((event *)insertEvent) ();
hasInserted = true;
}
}
if (!hasInserted) {
memcpy (cardData + 0x2C, chipId2, 33);
memcpy (cardData + 0x50, accessCode2, 21);
touchCallback (0, 0, cardData, touchData);
}
}
}
for (auto plugin : plugins) {
auto updateEvent = GetProcAddress (plugin, "Update");
if (updateEvent) updateEvent ();
}
for (auto plugin : plugins) {
auto updateEvent = GetProcAddress (plugin, "Update");
if (updateEvent) updateEvent ();
}
patches::Qr::Update ();
patches::Qr::Update ();
if (attachCallback) attachCallback (0, 0, attachData);
return coin_count;
if (attachCallback) attachCallback (0, 0, attachData);
return coin_count;
}
u32
bnusio_GetSwIn () {
u32 sw = 0;
sw |= (u32)testEnabled << 7;
sw |= (u32)IsButtonDown (DEBUG_ENTER) << 9;
sw |= (u32)IsButtonDown (DEBUG_DOWN) << 12;
sw |= (u32)IsButtonDown (DEBUG_UP) << 13;
sw |= (u32)IsButtonDown (SERVICE) << 14;
return sw;
u32 sw = 0;
sw |= (u32)testEnabled << 7;
sw |= (u32)IsButtonDown (DEBUG_ENTER) << 9;
sw |= (u32)IsButtonDown (DEBUG_DOWN) << 12;
sw |= (u32)IsButtonDown (DEBUG_UP) << 13;
sw |= (u32)IsButtonDown (SERVICE) << 14;
return sw;
}
i64
bnusio_Close () {
if (autoIME) ActivateKeyboardLayout (currentLayout, KLF_SETFORPROCESS);
for (auto plugin : plugins) {
FARPROC exitEvent = GetProcAddress (plugin, "Exit");
if (exitEvent) ((event *)exitEvent) ();
}
return 0;
if (autoIME) ActivateKeyboardLayout (currentLayout, KLF_SETFORPROCESS);
for (auto plugin : plugins) {
FARPROC exitEvent = GetProcAddress (plugin, "Exit");
if (exitEvent) ((event *)exitEvent) ();
}
return 0;
}
}
@@ -291,92 +295,93 @@ HOOK (u64, bngrw_ReqSetLedPower, PROC_ADDRESS ("bngrw.dll", "BngRwReqSetLedPower
HOOK (i32, bngrw_reqCancel, PROC_ADDRESS ("bngrw.dll", "BngRwReqCancel")) { return 1; }
HOOK (u64, bngrw_Init, PROC_ADDRESS ("bngrw.dll", "BngRwInit")) { return 0; }
HOOK (u64, bngrw_attach, PROC_ADDRESS ("bngrw.dll", "BngRwAttach"), i32 a1, char *a2, i32 a3, i32 a4, i32 (*callback) (i32, i32, i32 *), i32 *a6) {
// This is way too fucking jank
attachCallback = callback;
attachData = a6;
return 1;
// This is way too fucking jank
attachCallback = callback;
attachData = a6;
return 1;
}
HOOK (u64, bngrw_reqWaitTouch, PROC_ADDRESS ("bngrw.dll", "BngRwReqWaitTouch"), u32 a1, i32 a2, u32 a3, void (*callback) (i32, i32, u8[168], u64), u64 a5) {
waitingForTouch = true;
touchCallback = callback;
touchData = a5;
for (auto plugin : plugins) {
FARPROC touchEvent = GetProcAddress (plugin, "WaitTouch");
if (touchEvent) ((waitTouchEvent *)touchEvent) (callback, a5);
}
return 1;
HOOK (u64, bngrw_reqWaitTouch, PROC_ADDRESS ("bngrw.dll", "BngRwReqWaitTouch"), u32 a1, i32 a2, u32 a3, void (*callback) (i32, i32, u8[168], u64),
u64 a5) {
waitingForTouch = true;
touchCallback = callback;
touchData = a5;
for (auto plugin : plugins) {
FARPROC touchEvent = GetProcAddress (plugin, "WaitTouch");
if (touchEvent) ((waitTouchEvent *)touchEvent) (callback, a5);
}
return 1;
}
void
Init () {
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) {
toml_table_t *config = config_ptr.get ();
auto drum = openConfigSection (config, "drum");
if (drum) drumWaitPeriod = readConfigInt (drum, "wait_period", drumWaitPeriod);
auto taikoController = openConfigSection (config, "controller");
if (taikoController) {
useTaikoController = readConfigBool (taikoController, "analog", useTaikoController);
if (useTaikoController) printf ("Using analog input mode. All the keyboard drum inputs have been disabled.\n");
}
auto card = openConfigSection (config, "card_reader");
if (card) {
bool cardEnabled = readConfigBool (card, "enabled", true);
if (cardEnabled) {
INSTALL_HOOK (bngrw_DevReset);
INSTALL_HOOK (bngrw_ReadMifare);
INSTALL_HOOK (bngrw_fin);
INSTALL_HOOK (bngrw_GetFwVersion);
INSTALL_HOOK (bngrw_GetStationID);
INSTALL_HOOK (bngrw_GetRetryCount);
INSTALL_HOOK (bngrw_IsCmdExec);
INSTALL_HOOK (bngrw_ReqAction);
INSTALL_HOOK (bngrw_ReqAiccAuth);
INSTALL_HOOK (bngrw_ReqBeep);
INSTALL_HOOK (bngrw_ReqFwCleanup);
INSTALL_HOOK (bngrw_ReqFwVersionUp);
INSTALL_HOOK (bngrw_ReqLatchID);
INSTALL_HOOK (bngrw_ReqLed);
INSTALL_HOOK (bngrw_ReqSendMail);
INSTALL_HOOK (bngrw_ReqSendUrl);
INSTALL_HOOK (bngrw_ReqSetLedPower);
INSTALL_HOOK (bngrw_reqCancel);
INSTALL_HOOK (bngrw_Init)
INSTALL_HOOK (bngrw_attach);
INSTALL_HOOK (bngrw_reqWaitTouch);
} else {
std::cout << "[Init] Card reader emulation disabled" << std::endl;
}
}
}
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) {
toml_table_t *config = config_ptr.get ();
auto drum = openConfigSection (config, "drum");
if (drum) drumWaitPeriod = readConfigInt (drum, "wait_period", drumWaitPeriod);
auto taikoController = openConfigSection (config, "controller");
if (taikoController) {
useTaikoController = readConfigBool (taikoController, "analog", useTaikoController);
if (useTaikoController) printf ("Using analog input mode. All the keyboard drum inputs have been disabled.\n");
}
auto card = openConfigSection (config, "card_reader");
if (card) {
bool cardEnabled = readConfigBool (card, "enabled", true);
if (cardEnabled) {
INSTALL_HOOK (bngrw_DevReset);
INSTALL_HOOK (bngrw_ReadMifare);
INSTALL_HOOK (bngrw_fin);
INSTALL_HOOK (bngrw_GetFwVersion);
INSTALL_HOOK (bngrw_GetStationID);
INSTALL_HOOK (bngrw_GetRetryCount);
INSTALL_HOOK (bngrw_IsCmdExec);
INSTALL_HOOK (bngrw_ReqAction);
INSTALL_HOOK (bngrw_ReqAiccAuth);
INSTALL_HOOK (bngrw_ReqBeep);
INSTALL_HOOK (bngrw_ReqFwCleanup);
INSTALL_HOOK (bngrw_ReqFwVersionUp);
INSTALL_HOOK (bngrw_ReqLatchID);
INSTALL_HOOK (bngrw_ReqLed);
INSTALL_HOOK (bngrw_ReqSendMail);
INSTALL_HOOK (bngrw_ReqSendUrl);
INSTALL_HOOK (bngrw_ReqSetLedPower);
INSTALL_HOOK (bngrw_reqCancel);
INSTALL_HOOK (bngrw_Init)
INSTALL_HOOK (bngrw_attach);
INSTALL_HOOK (bngrw_reqWaitTouch);
} else {
std::cout << "[Init] Card reader emulation disabled" << std::endl;
}
}
}
auto keyconfigPath = std::filesystem::current_path () / "keyconfig.toml";
std::unique_ptr<toml_table_t, void (*) (toml_table_t *)> keyconfig_ptr (openConfig (keyconfigPath), toml_free);
if (keyconfig_ptr) {
toml_table_t *keyconfig = keyconfig_ptr.get ();
SetConfigValue (keyconfig, "EXIT", &EXIT);
auto keyconfigPath = std::filesystem::current_path () / "keyconfig.toml";
std::unique_ptr<toml_table_t, void (*) (toml_table_t *)> keyconfig_ptr (openConfig (keyconfigPath), toml_free);
if (keyconfig_ptr) {
toml_table_t *keyconfig = keyconfig_ptr.get ();
SetConfigValue (keyconfig, "EXIT", &EXIT);
SetConfigValue (keyconfig, "TEST", &TEST);
SetConfigValue (keyconfig, "SERVICE", &SERVICE);
SetConfigValue (keyconfig, "DEBUG_UP", &DEBUG_UP);
SetConfigValue (keyconfig, "DEBUG_DOWN", &DEBUG_DOWN);
SetConfigValue (keyconfig, "DEBUG_ENTER", &DEBUG_ENTER);
SetConfigValue (keyconfig, "TEST", &TEST);
SetConfigValue (keyconfig, "SERVICE", &SERVICE);
SetConfigValue (keyconfig, "DEBUG_UP", &DEBUG_UP);
SetConfigValue (keyconfig, "DEBUG_DOWN", &DEBUG_DOWN);
SetConfigValue (keyconfig, "DEBUG_ENTER", &DEBUG_ENTER);
SetConfigValue (keyconfig, "COIN_ADD", &COIN_ADD);
SetConfigValue (keyconfig, "CARD_INSERT_1", &CARD_INSERT_1);
SetConfigValue (keyconfig, "CARD_INSERT_2", &CARD_INSERT_2);
SetConfigValue (keyconfig, "QR_DATA_READ", &QR_DATA_READ);
SetConfigValue (keyconfig, "QR_IMAGE_READ", &QR_IMAGE_READ);
SetConfigValue (keyconfig, "COIN_ADD", &COIN_ADD);
SetConfigValue (keyconfig, "CARD_INSERT_1", &CARD_INSERT_1);
SetConfigValue (keyconfig, "CARD_INSERT_2", &CARD_INSERT_2);
SetConfigValue (keyconfig, "QR_DATA_READ", &QR_DATA_READ);
SetConfigValue (keyconfig, "QR_IMAGE_READ", &QR_IMAGE_READ);
SetConfigValue (keyconfig, "P1_LEFT_BLUE", &P1_LEFT_BLUE);
SetConfigValue (keyconfig, "P1_LEFT_RED", &P1_LEFT_RED);
SetConfigValue (keyconfig, "P1_RIGHT_RED", &P1_RIGHT_RED);
SetConfigValue (keyconfig, "P1_RIGHT_BLUE", &P1_RIGHT_BLUE);
SetConfigValue (keyconfig, "P2_LEFT_BLUE", &P2_LEFT_BLUE);
SetConfigValue (keyconfig, "P2_LEFT_RED", &P2_LEFT_RED);
SetConfigValue (keyconfig, "P2_RIGHT_RED", &P2_RIGHT_RED);
SetConfigValue (keyconfig, "P2_RIGHT_BLUE", &P2_RIGHT_BLUE);
}
SetConfigValue (keyconfig, "P1_LEFT_BLUE", &P1_LEFT_BLUE);
SetConfigValue (keyconfig, "P1_LEFT_RED", &P1_LEFT_RED);
SetConfigValue (keyconfig, "P1_RIGHT_RED", &P1_RIGHT_RED);
SetConfigValue (keyconfig, "P1_RIGHT_BLUE", &P1_RIGHT_BLUE);
SetConfigValue (keyconfig, "P2_LEFT_BLUE", &P2_LEFT_BLUE);
SetConfigValue (keyconfig, "P2_LEFT_RED", &P2_LEFT_RED);
SetConfigValue (keyconfig, "P2_RIGHT_RED", &P2_RIGHT_RED);
SetConfigValue (keyconfig, "P2_RIGHT_BLUE", &P2_RIGHT_BLUE);
}
}
} // namespace bnusio
+5 -5
View File
@@ -2,9 +2,9 @@
#include <xxhash.h>
enum class GameVersion : XXH64_hash_t {
UNKNOWN = 0,
JPN00 = 0x4C07355966D815FB,
JPN08 = 0x67C0F3042746D488,
JPN39 = 0x49F643ADB6B18705,
CHN00 = 0xA7EE39F2CC2C57C8,
UNKNOWN = 0,
JPN00 = 0x4C07355966D815FB,
JPN08 = 0x67C0F3042746D488,
JPN39 = 0x49F643ADB6B18705,
CHN00 = 0xA7EE39F2CC2C57C8,
};
+124 -124
View File
@@ -35,165 +35,165 @@ HOOK (i32, ssleay_Shutdown, PROC_ADDRESS ("ssleay32.dll", "SSL_shutdown")) { ret
HOOK (i64, UsbFinderInitialize, PROC_ADDRESS ("nbamUsbFinder.dll", "nbamUsbFinderInitialize")) { return 0; }
HOOK (i64, UsbFinderRelease, PROC_ADDRESS ("nbamUsbFinder.dll", "nbamUsbFinderRelease")) { return 0; }
HOOK (i64, UsbFinderGetSerialNumber, PROC_ADDRESS ("nbamUsbFinder.dll", "nbamUsbFinderGetSerialNumber"), i32 a1, char *a2) {
strcpy (a2, chassisId.c_str ());
return 0;
strcpy (a2, chassisId.c_str ());
return 0;
}
HOOK (i32, ws2_getaddrinfo, PROC_ADDRESS ("ws2_32.dll", "getaddrinfo"), const char *node, char *service, void *hints, void *out) {
return originalws2_getaddrinfo (server.c_str (), service, hints, out);
return originalws2_getaddrinfo (server.c_str (), service, hints, out);
}
void
GetGameVersion () {
wchar_t w_path[MAX_PATH];
GetModuleFileNameW (nullptr, w_path, MAX_PATH);
std::filesystem::path path (w_path);
wchar_t w_path[MAX_PATH];
GetModuleFileNameW (nullptr, w_path, MAX_PATH);
std::filesystem::path path (w_path);
if (!std::filesystem::exists (path) || !path.has_filename ()) {
MessageBoxA (nullptr, "Failed to find executable", nullptr, MB_OK);
ExitProcess (0);
}
if (!std::filesystem::exists (path) || !path.has_filename ()) {
MessageBoxA (nullptr, "Failed to find executable", nullptr, MB_OK);
ExitProcess (0);
}
std::ifstream stream (path, std::ios::binary);
if (!stream.is_open ()) {
MessageBoxA (nullptr, "Failed to read executable", nullptr, MB_OK);
ExitProcess (0);
}
std::ifstream stream (path, std::ios::binary);
if (!stream.is_open ()) {
MessageBoxA (nullptr, "Failed to read executable", nullptr, MB_OK);
ExitProcess (0);
}
stream.seekg (0, std::ifstream::end);
size_t length = stream.tellg ();
stream.seekg (0, std::ifstream::beg);
stream.seekg (0, std::ifstream::end);
size_t length = stream.tellg ();
stream.seekg (0, std::ifstream::beg);
char *buf = (char *)calloc (length + 1, sizeof (char));
stream.read (buf, length);
char *buf = (char *)calloc (length + 1, sizeof (char));
stream.read (buf, length);
gameVersion = (GameVersion)XXH64 (buf, length, 0);
gameVersion = (GameVersion)XXH64 (buf, length, 0);
stream.close ();
free (buf);
stream.close ();
free (buf);
switch (gameVersion) {
case GameVersion::JPN00:
case GameVersion::JPN08:
case GameVersion::JPN39:
case GameVersion::CHN00: break;
default: MessageBoxA (nullptr, "Unknown game version", nullptr, MB_OK); ExitProcess (0);
}
switch (gameVersion) {
case GameVersion::JPN00:
case GameVersion::JPN08:
case GameVersion::JPN39:
case GameVersion::CHN00: break;
default: MessageBoxA (nullptr, "Unknown game version", nullptr, MB_OK); ExitProcess (0);
}
}
void
createCard () {
const char hexCharacterTable[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
char buf[64] = {0};
srand (time (nullptr));
const char hexCharacterTable[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
char buf[64] = {0};
srand (time (nullptr));
std::generate (buf, buf + 20, [&] () { return hexCharacterTable[rand () % 10]; });
WritePrivateProfileStringA ("card", "accessCode1", buf, ".\\card.ini");
std::generate (buf, buf + 32, [&] () { return hexCharacterTable[rand () % 16]; });
WritePrivateProfileStringA ("card", "chipId1", buf, ".\\card.ini");
std::generate (buf, buf + 20, [&] () { return hexCharacterTable[rand () % 10]; });
WritePrivateProfileStringA ("card", "accessCode2", buf, ".\\card.ini");
std::generate (buf, buf + 32, [&] () { return hexCharacterTable[rand () % 16]; });
WritePrivateProfileStringA ("card", "chipId2", buf, ".\\card.ini");
std::generate (buf, buf + 20, [&] () { return hexCharacterTable[rand () % 10]; });
WritePrivateProfileStringA ("card", "accessCode1", buf, ".\\card.ini");
std::generate (buf, buf + 32, [&] () { return hexCharacterTable[rand () % 16]; });
WritePrivateProfileStringA ("card", "chipId1", buf, ".\\card.ini");
std::generate (buf, buf + 20, [&] () { return hexCharacterTable[rand () % 10]; });
WritePrivateProfileStringA ("card", "accessCode2", buf, ".\\card.ini");
std::generate (buf, buf + 32, [&] () { return hexCharacterTable[rand () % 16]; });
WritePrivateProfileStringA ("card", "chipId2", buf, ".\\card.ini");
}
BOOL
DllMain (HMODULE module, DWORD reason, LPVOID reserved) {
if (reason == DLL_PROCESS_ATTACH) {
// This is bad, dont do this
// I/O in DllMain can easily cause a deadlock
if (reason == DLL_PROCESS_ATTACH) {
// This is bad, dont do this
// I/O in DllMain can easily cause a deadlock
std::string version = "auto";
auto configPath = std::filesystem::current_path () / "config.toml";
std::unique_ptr<toml_table_t, void (*) (toml_table_t *)> config_ptr (openConfig (configPath), toml_free);
if (config_ptr) {
toml_table_t *config = config_ptr.get ();
auto amauth = openConfigSection (config, "amauth");
if (amauth) {
server = readConfigString (amauth, "server", server);
port = readConfigString (amauth, "port", port);
chassisId = readConfigString (amauth, "chassis_id", chassisId);
shopId = readConfigString (amauth, "shop_id", shopId);
gameVerNum = readConfigString (amauth, "game_ver", gameVerNum);
countryCode = readConfigString (amauth, "country_code", countryCode);
std::string version = "auto";
auto configPath = std::filesystem::current_path () / "config.toml";
std::unique_ptr<toml_table_t, void (*) (toml_table_t *)> config_ptr (openConfig (configPath), toml_free);
if (config_ptr) {
toml_table_t *config = config_ptr.get ();
auto amauth = openConfigSection (config, "amauth");
if (amauth) {
server = readConfigString (amauth, "server", server);
port = readConfigString (amauth, "port", port);
chassisId = readConfigString (amauth, "chassis_id", chassisId);
shopId = readConfigString (amauth, "shop_id", shopId);
gameVerNum = readConfigString (amauth, "game_ver", gameVerNum);
countryCode = readConfigString (amauth, "country_code", countryCode);
std::strcat (fullAddress, server.c_str ());
std::strcat (fullAddress, ":");
std::strcat (fullAddress, port.c_str ());
std::strcat (fullAddress, server.c_str ());
std::strcat (fullAddress, ":");
std::strcat (fullAddress, port.c_str ());
std::strcat (placeId, countryCode.c_str ());
std::strcat (placeId, "0FF0");
}
auto patches = openConfigSection (config, "patches");
if (patches) {
version = readConfigString (patches, "version", version);
autoIME = readConfigBool (patches, "auto_ime", autoIME);
}
}
std::strcat (placeId, countryCode.c_str ());
std::strcat (placeId, "0FF0");
}
auto patches = openConfigSection (config, "patches");
if (patches) {
version = readConfigString (patches, "version", version);
autoIME = readConfigBool (patches, "auto_ime", autoIME);
}
}
if (version == "auto") {
GetGameVersion ();
} else if (version == "JPN00") {
gameVersion = GameVersion::JPN00;
} else if (version == "JPN08") {
gameVersion = GameVersion::JPN08;
} else if (version == "JPN39") {
gameVersion = GameVersion::JPN39;
} else if (version == "CHN00") {
gameVersion = GameVersion::CHN00;
} else {
MessageBoxA (nullptr, "Unknown patch version", nullptr, MB_OK);
ExitProcess (0);
}
if (version == "auto") {
GetGameVersion ();
} else if (version == "JPN00") {
gameVersion = GameVersion::JPN00;
} else if (version == "JPN08") {
gameVersion = GameVersion::JPN08;
} else if (version == "JPN39") {
gameVersion = GameVersion::JPN39;
} else if (version == "CHN00") {
gameVersion = GameVersion::CHN00;
} else {
MessageBoxA (nullptr, "Unknown patch version", nullptr, MB_OK);
ExitProcess (0);
}
auto pluginPath = std::filesystem::current_path () / "plugins";
auto pluginPath = std::filesystem::current_path () / "plugins";
if (std::filesystem::exists (pluginPath)) {
for (const auto &entry : std::filesystem::directory_iterator (pluginPath)) {
if (entry.path ().extension () == ".dll") {
auto name = entry.path ().wstring ();
HMODULE hModule = LoadLibraryW (name.c_str ());
if (!hModule) {
wchar_t buf[128];
wsprintfW (buf, L"Failed to load plugin %ls", name.c_str ());
MessageBoxW (0, buf, name.c_str (), MB_ICONERROR);
} else {
plugins.push_back (hModule);
}
}
}
}
if (std::filesystem::exists (pluginPath)) {
for (const auto &entry : std::filesystem::directory_iterator (pluginPath)) {
if (entry.path ().extension () == ".dll") {
auto name = entry.path ().wstring ();
HMODULE hModule = LoadLibraryW (name.c_str ());
if (!hModule) {
wchar_t buf[128];
wsprintfW (buf, L"Failed to load plugin %ls", name.c_str ());
MessageBoxW (0, buf, name.c_str (), MB_ICONERROR);
} else {
plugins.push_back (hModule);
}
}
}
}
if (!std::filesystem::exists (".\\card.ini")) createCard ();
GetPrivateProfileStringA ("card", "accessCode1", accessCode1, accessCode1, 21, ".\\card.ini");
GetPrivateProfileStringA ("card", "chipId1", chipId1, chipId1, 33, ".\\card.ini");
GetPrivateProfileStringA ("card", "accessCode2", accessCode2, accessCode2, 21, ".\\card.ini");
GetPrivateProfileStringA ("card", "chipId2", chipId2, chipId2, 33, ".\\card.ini");
if (!std::filesystem::exists (".\\card.ini")) createCard ();
GetPrivateProfileStringA ("card", "accessCode1", accessCode1, accessCode1, 21, ".\\card.ini");
GetPrivateProfileStringA ("card", "chipId1", chipId1, chipId1, 33, ".\\card.ini");
GetPrivateProfileStringA ("card", "accessCode2", accessCode2, accessCode2, 21, ".\\card.ini");
GetPrivateProfileStringA ("card", "chipId2", chipId2, chipId2, 33, ".\\card.ini");
INSTALL_HOOK (ShowMouse);
INSTALL_HOOK (ExitWindows);
INSTALL_HOOK (ShowMouse);
INSTALL_HOOK (ExitWindows);
INSTALL_HOOK (XinputGetState);
INSTALL_HOOK (XinputSetState);
INSTALL_HOOK (XinputGetCapabilites);
INSTALL_HOOK (XinputGetState);
INSTALL_HOOK (XinputSetState);
INSTALL_HOOK (XinputGetCapabilites);
INSTALL_HOOK (ssleay_Shutdown);
INSTALL_HOOK (ssleay_Shutdown);
INSTALL_HOOK (UsbFinderInitialize);
INSTALL_HOOK (UsbFinderRelease);
INSTALL_HOOK (UsbFinderGetSerialNumber);
INSTALL_HOOK (UsbFinderInitialize);
INSTALL_HOOK (UsbFinderRelease);
INSTALL_HOOK (UsbFinderGetSerialNumber);
INSTALL_HOOK (ws2_getaddrinfo);
INSTALL_HOOK (ws2_getaddrinfo);
bnusio::Init ();
bnusio::Init ();
switch (gameVersion) {
case GameVersion::UNKNOWN: break;
case GameVersion::JPN00: patches::JPN00::Init (); break;
case GameVersion::JPN08: patches::JPN08::Init (); break;
case GameVersion::JPN39: patches::JPN39::Init (); break;
case GameVersion::CHN00: patches::CHN00::Init (); break;
}
}
return true;
switch (gameVersion) {
case GameVersion::UNKNOWN: break;
case GameVersion::JPN00: patches::JPN00::Init (); break;
case GameVersion::JPN08: patches::JPN08::Init (); break;
case GameVersion::JPN39: patches::JPN39::Init (); break;
case GameVersion::CHN00: patches::CHN00::Init (); break;
}
}
return true;
}
+60 -60
View File
@@ -5,107 +5,107 @@ void *consoleHandle = 0;
static void
toml_myfree (void *p) {
if (p) {
char *pp = (char *)p;
delete[] pp;
}
if (p) {
char *pp = (char *)p;
delete[] pp;
}
}
toml_table_t *
openConfig (std::filesystem::path path) {
if (!std::filesystem::exists (path) || !path.has_filename ()) {
printWarning ("%s (%s): file does not exist\n", __func__, path.string ().c_str ());
return 0;
}
if (!std::filesystem::exists (path) || !path.has_filename ()) {
printWarning ("%s (%s): file does not exist\n", __func__, path.string ().c_str ());
return 0;
}
std::ifstream stream (path);
if (!stream.is_open ()) {
printWarning ("%s (%s): could not open\n", __func__, path.string ().c_str ());
return 0;
}
std::ifstream stream (path);
if (!stream.is_open ()) {
printWarning ("%s (%s): could not open\n", __func__, path.string ().c_str ());
return 0;
}
stream.seekg (0, stream.end);
size_t length = stream.tellg ();
stream.seekg (0, stream.beg);
stream.seekg (0, stream.end);
size_t length = stream.tellg ();
stream.seekg (0, stream.beg);
char *buf = (char *)calloc (length + 1, sizeof (char));
stream.read (buf, length);
char *buf = (char *)calloc (length + 1, sizeof (char));
stream.read (buf, length);
char errorbuf[200];
toml_table_t *config = toml_parse (buf, errorbuf, 200);
stream.close ();
free (buf);
char errorbuf[200];
toml_table_t *config = toml_parse (buf, errorbuf, 200);
stream.close ();
free (buf);
if (!config) {
printWarning ("%s (%s): %s\n", __func__, path.string ().c_str (), errorbuf);
return 0;
}
if (!config) {
printWarning ("%s (%s): %s\n", __func__, path.string ().c_str (), errorbuf);
return 0;
}
return config;
return config;
}
toml_table_t *
openConfigSection (toml_table_t *config, const std::string &sectionName) {
toml_table_t *section = toml_table_in (config, sectionName.c_str ());
if (!section) {
printWarning ("%s (%s): cannot find section\n", __func__, sectionName.c_str ());
return 0;
}
toml_table_t *section = toml_table_in (config, sectionName.c_str ());
if (!section) {
printWarning ("%s (%s): cannot find section\n", __func__, sectionName.c_str ());
return 0;
}
return section;
return section;
}
bool
readConfigBool (toml_table_t *table, const std::string &key, bool notFoundValue) {
toml_datum_t data = toml_bool_in (table, key.c_str ());
if (!data.ok) return notFoundValue;
toml_datum_t data = toml_bool_in (table, key.c_str ());
if (!data.ok) return notFoundValue;
return (bool)data.u.b;
return (bool)data.u.b;
}
int64_t
readConfigInt (toml_table_t *table, const std::string &key, int64_t notFoundValue) {
toml_datum_t data = toml_int_in (table, key.c_str ());
if (!data.ok) return notFoundValue;
toml_datum_t data = toml_int_in (table, key.c_str ());
if (!data.ok) return notFoundValue;
return data.u.i;
return data.u.i;
}
const std::string
readConfigString (toml_table_t *table, const std::string &key, const std::string &notFoundValue) {
toml_datum_t data = toml_string_in (table, key.c_str ());
if (!data.ok) return notFoundValue;
std::string str = data.u.s;
toml_myfree (data.u.s);
toml_datum_t data = toml_string_in (table, key.c_str ());
if (!data.ok) return notFoundValue;
std::string str = data.u.s;
toml_myfree (data.u.s);
return str;
return str;
}
std::vector<int64_t>
readConfigIntArray (toml_table_t *table, const std::string &key, std::vector<int64_t> notFoundValue) {
toml_array_t *array = toml_array_in (table, key.c_str ());
if (!array) return notFoundValue;
toml_array_t *array = toml_array_in (table, key.c_str ());
if (!array) return notFoundValue;
std::vector<int64_t> datas;
for (int i = 0;; i++) {
toml_datum_t data = toml_int_at (array, i);
if (!data.ok) break;
datas.push_back (data.u.i);
}
std::vector<int64_t> datas;
for (int i = 0;; i++) {
toml_datum_t data = toml_int_at (array, i);
if (!data.ok) break;
datas.push_back (data.u.i);
}
return datas;
return datas;
}
void
printColour (int colour, const char *format, ...) {
va_list args;
va_start (args, format);
va_list args;
va_start (args, format);
if (consoleHandle == 0) consoleHandle = GetStdHandle (STD_OUTPUT_HANDLE);
if (consoleHandle == 0) consoleHandle = GetStdHandle (STD_OUTPUT_HANDLE);
SetConsoleTextAttribute (consoleHandle, colour);
vprintf (format, args);
SetConsoleTextAttribute (consoleHandle, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED);
SetConsoleTextAttribute (consoleHandle, colour);
vprintf (format, args);
SetConsoleTextAttribute (consoleHandle, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED);
va_end (args);
va_end (args);
}
+52 -52
View File
@@ -32,78 +32,78 @@ const HMODULE MODULE_HANDLE = GetModuleHandle (nullptr);
#endif
#define HOOK(returnType, functionName, location, ...) \
typedef returnType (*functionName) (__VA_ARGS__); \
functionName original##functionName = NULL; \
void *where##functionName = (void *)(location); \
returnType implOf##functionName (__VA_ARGS__)
typedef returnType (*functionName) (__VA_ARGS__); \
functionName original##functionName = NULL; \
void *where##functionName = (void *)(location); \
returnType implOf##functionName (__VA_ARGS__)
#define HOOK_DYNAMIC(returnType, callingConvention, functionName, ...) \
typedef returnType callingConvention (*functionName) (__VA_ARGS__); \
functionName original##functionName = NULL; \
void *where##functionName = NULL; \
returnType callingConvention implOf##functionName (__VA_ARGS__)
typedef returnType callingConvention (*functionName) (__VA_ARGS__); \
functionName original##functionName = NULL; \
void *where##functionName = NULL; \
returnType callingConvention implOf##functionName (__VA_ARGS__)
#define VTABLE_HOOK(returnType, className, functionName, ...) \
typedef returnType (*className##functionName) (className * This, __VA_ARGS__); \
className##functionName original##className##functionName = NULL; \
void *where##className##functionName = NULL; \
returnType implOf##className##functionName (className *This, __VA_ARGS__)
typedef returnType (*className##functionName) (className * This, __VA_ARGS__); \
className##functionName original##className##functionName = NULL; \
void *where##className##functionName = NULL; \
returnType implOf##className##functionName (className *This, __VA_ARGS__)
#define INSTALL_HOOK(functionName) \
{ \
MH_Initialize (); \
MH_CreateHook ((void *)where##functionName, (void *)implOf##functionName, (void **)(&original##functionName)); \
MH_EnableHook ((void *)where##functionName); \
}
{ \
MH_Initialize (); \
MH_CreateHook ((void *)where##functionName, (void *)implOf##functionName, (void **)(&original##functionName)); \
MH_EnableHook ((void *)where##functionName); \
}
#define INSTALL_HOOK_DYNAMIC(functionName, location) \
{ \
where##functionName = (void *)location; \
INSTALL_HOOK (functionName); \
}
{ \
where##functionName = (void *)location; \
INSTALL_HOOK (functionName); \
}
#define INSTALL_VTABLE_HOOK(className, object, functionName, functionIndex) \
{ \
where##className##functionName = (*(className##functionName ***)object)[functionIndex]; \
INSTALL_HOOK (className##functionName); \
}
{ \
where##className##functionName = (*(className##functionName ***)object)[functionIndex]; \
INSTALL_HOOK (className##functionName); \
}
#define READ_MEMORY(location, type) *(type *)location
#define WRITE_MEMORY(location, type, ...) \
{ \
const type data[] = {__VA_ARGS__}; \
DWORD oldProtect; \
VirtualProtect ((void *)(location), sizeof (data), PAGE_EXECUTE_READWRITE, &oldProtect); \
memcpy ((void *)(location), data, sizeof (data)); \
VirtualProtect ((void *)(location), sizeof (data), oldProtect, &oldProtect); \
}
{ \
const type data[] = {__VA_ARGS__}; \
DWORD oldProtect; \
VirtualProtect ((void *)(location), sizeof (data), PAGE_EXECUTE_READWRITE, &oldProtect); \
memcpy ((void *)(location), data, sizeof (data)); \
VirtualProtect ((void *)(location), sizeof (data), oldProtect, &oldProtect); \
}
#define WRITE_MEMORY_STRING(location, data, length) \
{ \
DWORD oldProtect; \
VirtualProtect ((void *)(location), length, PAGE_EXECUTE_READWRITE, &oldProtect); \
memcpy ((void *)(location), data, length); \
VirtualProtect ((void *)(location), length, oldProtect, &oldProtect); \
}
{ \
DWORD oldProtect; \
VirtualProtect ((void *)(location), length, PAGE_EXECUTE_READWRITE, &oldProtect); \
memcpy ((void *)(location), data, length); \
VirtualProtect ((void *)(location), length, oldProtect, &oldProtect); \
}
#define WRITE_NOP(location, count) \
{ \
DWORD oldProtect; \
VirtualProtect ((void *)(location), (size_t)(count), PAGE_EXECUTE_READWRITE, &oldProtect); \
for (size_t i = 0; i < (size_t)(count); i++) \
*((uint8_t *)(location) + i) = 0x90; \
VirtualProtect ((void *)(location), (size_t)(count), oldProtect, &oldProtect); \
}
{ \
DWORD oldProtect; \
VirtualProtect ((void *)(location), (size_t)(count), PAGE_EXECUTE_READWRITE, &oldProtect); \
for (size_t i = 0; i < (size_t)(count); i++) \
*((uint8_t *)(location) + i) = 0x90; \
VirtualProtect ((void *)(location), (size_t)(count), oldProtect, &oldProtect); \
}
#define WRITE_NULL(location, count) \
{ \
DWORD oldProtect; \
VirtualProtect ((void *)(location), (size_t)(count), PAGE_EXECUTE_READWRITE, &oldProtect); \
for (size_t i = 0; i < (size_t)(count); i++) \
*((uint8_t *)(location) + i) = 0x00; \
VirtualProtect ((void *)(location), (size_t)(count), oldProtect, &oldProtect); \
}
{ \
DWORD oldProtect; \
VirtualProtect ((void *)(location), (size_t)(count), PAGE_EXECUTE_READWRITE, &oldProtect); \
for (size_t i = 0; i < (size_t)(count); i++) \
*((uint8_t *)(location) + i) = 0x00; \
VirtualProtect ((void *)(location), (size_t)(count), oldProtect, &oldProtect); \
}
#define COUNTOFARR(arr) sizeof (arr) / sizeof (arr[0])
+496 -494
View File
File diff suppressed because it is too large Load Diff
+54 -54
View File
@@ -7,15 +7,15 @@ extern GameVersion gameVersion;
namespace patches::Audio {
typedef struct nusc_init_config {
uint32_t sample_rate;
uint32_t buffer_size;
uint32_t device_mode;
uint32_t channel_count;
const char *asio_driver_name;
bool wasapi_disable_com;
bool wasapi_exclusive;
uint32_t wasapi_exclusive_buffer_size;
void *wasapi_audioses;
uint32_t sample_rate;
uint32_t buffer_size;
uint32_t device_mode;
uint32_t channel_count;
const char *asio_driver_name;
bool wasapi_disable_com;
bool wasapi_exclusive;
uint32_t wasapi_exclusive_buffer_size;
void *wasapi_audioses;
} nusc_init_config_t;
bool wasapiShared = true;
@@ -23,57 +23,57 @@ bool asio = false;
std::string asioDriver = "";
HOOK_DYNAMIC (i64, __fastcall, NUSCDeviceInit, void *a1, nusc_init_config_t *a2, nusc_init_config_t *a3, void *a4) {
a2->device_mode = asio;
a2->asio_driver_name = asio ? asioDriver.c_str () : "";
a2->wasapi_exclusive = asio ? 1 : wasapiShared ? 0 : 1;
return originalNUSCDeviceInit (a1, a2, a3, a4);
a2->device_mode = asio;
a2->asio_driver_name = asio ? asioDriver.c_str () : "";
a2->wasapi_exclusive = asio ? 1 : wasapiShared ? 0 : 1;
return originalNUSCDeviceInit (a1, a2, a3, a4);
}
HOOK_DYNAMIC (bool, __fastcall, LoadASIODriver, void *a1, const char *a2) {
auto result = originalLoadASIODriver (a1, a2);
if (!result) {
MessageBoxA (nullptr, "Failed to load ASIO driver", nullptr, MB_OK);
ExitProcess (0);
}
return result;
auto result = originalLoadASIODriver (a1, a2);
if (!result) {
MessageBoxA (nullptr, "Failed to load ASIO driver", nullptr, MB_OK);
ExitProcess (0);
}
return result;
}
void
Init () {
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 audio = openConfigSection (config_ptr.get (), "audio");
if (audio) {
wasapiShared = readConfigBool (audio, "wasapi_shared", wasapiShared);
asio = readConfigBool (audio, "asio", asio);
asioDriver = readConfigString (audio, "asio_driver", asioDriver);
}
}
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 audio = openConfigSection (config_ptr.get (), "audio");
if (audio) {
wasapiShared = readConfigBool (audio, "wasapi_shared", wasapiShared);
asio = readConfigBool (audio, "asio", asio);
asioDriver = readConfigString (audio, "asio_driver", asioDriver);
}
}
switch (gameVersion) {
case GameVersion::JPN00: {
INSTALL_HOOK_DYNAMIC (NUSCDeviceInit, ASLR (0x140552160));
INSTALL_HOOK_DYNAMIC (LoadASIODriver, ASLR (0x14055A950));
break;
}
case GameVersion::JPN08: {
INSTALL_HOOK_DYNAMIC (NUSCDeviceInit, ASLR (0x140692E00));
INSTALL_HOOK_DYNAMIC (LoadASIODriver, ASLR (0x14069B750));
break;
}
case GameVersion::JPN39: {
INSTALL_HOOK_DYNAMIC (NUSCDeviceInit, ASLR (0x1407C8620));
INSTALL_HOOK_DYNAMIC (LoadASIODriver, ASLR (0x1407D0F70));
break;
}
case GameVersion::CHN00: {
INSTALL_HOOK_DYNAMIC (NUSCDeviceInit, ASLR (0x140777F70));
INSTALL_HOOK_DYNAMIC (LoadASIODriver, ASLR (0x1407808C0));
break;
}
default: {
break;
}
}
switch (gameVersion) {
case GameVersion::JPN00: {
INSTALL_HOOK_DYNAMIC (NUSCDeviceInit, ASLR (0x140552160));
INSTALL_HOOK_DYNAMIC (LoadASIODriver, ASLR (0x14055A950));
break;
}
case GameVersion::JPN08: {
INSTALL_HOOK_DYNAMIC (NUSCDeviceInit, ASLR (0x140692E00));
INSTALL_HOOK_DYNAMIC (LoadASIODriver, ASLR (0x14069B750));
break;
}
case GameVersion::JPN39: {
INSTALL_HOOK_DYNAMIC (NUSCDeviceInit, ASLR (0x1407C8620));
INSTALL_HOOK_DYNAMIC (LoadASIODriver, ASLR (0x1407D0F70));
break;
}
case GameVersion::CHN00: {
INSTALL_HOOK_DYNAMIC (NUSCDeviceInit, ASLR (0x140777F70));
INSTALL_HOOK_DYNAMIC (LoadASIODriver, ASLR (0x1407808C0));
break;
}
default: {
break;
}
}
}
} // namespace patches::Audio
+242 -241
View File
@@ -41,287 +41,288 @@ bool qrPluginRegistered = false;
HOOK_DYNAMIC (char, __fastcall, qrInit, i64) { return 1; }
HOOK_DYNAMIC (char, __fastcall, qrClose, i64) { return 1; }
HOOK_DYNAMIC (char, __fastcall, qrRead, i64 a1) {
*(DWORD *)(a1 + 40) = 1;
*(DWORD *)(a1 + 16) = 1;
*(BYTE *)(a1 + 112) = 0;
return 1;
*(DWORD *)(a1 + 40) = 1;
*(DWORD *)(a1 + 16) = 1;
*(BYTE *)(a1 + 112) = 0;
return 1;
}
HOOK_DYNAMIC (i64, __fastcall, callQrUnknown, i64) { return 1; }
HOOK_DYNAMIC (bool, __fastcall, Send1, i64 a1) {
*(BYTE *)(a1 + 88) = 1;
*(i64 *)(a1 + 32) = *(i64 *)(a1 + 24);
*(WORD *)(a1 + 89) = 0;
return true;
*(BYTE *)(a1 + 88) = 1;
*(i64 *)(a1 + 32) = *(i64 *)(a1 + 24);
*(WORD *)(a1 + 89) = 0;
return true;
}
HOOK_DYNAMIC (bool, __fastcall, Send2, i64 a1) {
*(WORD *)(a1 + 88) = 0;
*(BYTE *)(a1 + 90) = 0;
return true;
*(WORD *)(a1 + 88) = 0;
*(BYTE *)(a1 + 90) = 0;
return true;
}
HOOK_DYNAMIC (bool, __fastcall, Send3, i64, char) { return true; }
HOOK_DYNAMIC (bool, __fastcall, Send4, i64, const void *, i64) { return true; }
HOOK_DYNAMIC (i64, __fastcall, copy_data, i64, void *dest, int length) {
if (gState == State::CopyWait) {
std::cout << "Copy data, length: " << length << std::endl;
if (gState == State::CopyWait) {
std::cout << "Copy data, length: " << length << std::endl;
auto configPath = std::filesystem::current_path () / "config.toml";
std::unique_ptr<toml_table_t, void (*) (toml_table_t *)> config_ptr (openConfig (configPath), toml_free);
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 (gMode == Mode::Card) {
memcpy (dest, accessCode.c_str (), accessCode.size () + 1);
gState = State::Ready;
return accessCode.size () + 1;
} else if (gMode == Mode::Data) {
std::string serial = "";
u16 type = 0;
std::vector<i64> songNoes;
if (gMode == Mode::Card) {
memcpy (dest, accessCode.c_str (), accessCode.size () + 1);
gState = State::Ready;
return accessCode.size () + 1;
} else if (gMode == Mode::Data) {
std::string serial = "";
u16 type = 0;
std::vector<i64> songNoes;
if (config_ptr) {
auto qr = openConfigSection (config_ptr.get (), "qr");
if (qr) {
auto data = openConfigSection (qr, "data");
if (data) {
serial = readConfigString (data, "serial", "");
type = readConfigInt (data, "type", 0);
songNoes = readConfigIntArray (data, "song_no", songNoes);
}
}
}
if (config_ptr) {
auto qr = openConfigSection (config_ptr.get (), "qr");
if (qr) {
auto data = openConfigSection (qr, "data");
if (data) {
serial = readConfigString (data, "serial", "");
type = readConfigInt (data, "type", 0);
songNoes = readConfigIntArray (data, "song_no", songNoes);
}
}
}
BYTE serial_length = (BYTE)serial.size ();
std::vector<BYTE> byteBuffer = {0x53, 0x31, 0x32, 0x00, 0x00, 0xFF, 0xFF, serial_length, 0x01, 0x00};
BYTE serial_length = (BYTE)serial.size ();
std::vector<BYTE> byteBuffer = {0x53, 0x31, 0x32, 0x00, 0x00, 0xFF, 0xFF, serial_length, 0x01, 0x00};
for (char c : serial)
byteBuffer.push_back ((BYTE)c);
for (char c : serial)
byteBuffer.push_back ((BYTE)c);
if (type == 5) {
std::vector<BYTE> folderData = {0xFF, 0xFF};
if (type == 5) {
std::vector<BYTE> folderData = {0xFF, 0xFF};
folderData.push_back (songNoes.size () * 2);
folderData.push_back (songNoes.size () * 2);
folderData.push_back ((u8)(type & 0xFF));
folderData.push_back ((u8)((type >> 8) & 0xFF));
folderData.push_back ((u8)(type & 0xFF));
folderData.push_back ((u8)((type >> 8) & 0xFF));
for (u16 songNo : songNoes) {
folderData.push_back ((u8)(songNo & 0xFF));
folderData.push_back ((u8)((songNo >> 8) & 0xFF));
}
for (u16 songNo : songNoes) {
folderData.push_back ((u8)(songNo & 0xFF));
folderData.push_back ((u8)((songNo >> 8) & 0xFF));
}
for (auto c : folderData)
byteBuffer.push_back (c);
}
for (auto c : folderData)
byteBuffer.push_back (c);
}
byteBuffer.push_back (0xEE);
byteBuffer.push_back (0xFF);
byteBuffer.push_back (0xEE);
byteBuffer.push_back (0xFF);
for (auto byteData : byteBuffer)
std::cout << std::hex << std::uppercase << std::setfill ('0') << std::setw (2) << static_cast<int> (byteData) << " ";
std::cout << std::endl;
for (auto byteData : byteBuffer)
std::cout << std::hex << std::uppercase << std::setfill ('0') << std::setw (2) << static_cast<int> (byteData) << " ";
std::cout << std::endl;
memcpy (dest, byteBuffer.data (), byteBuffer.size ());
gState = State::Ready;
return byteBuffer.size ();
} else if (gMode == Mode::Image) {
std::string imagePath = "";
memcpy (dest, byteBuffer.data (), byteBuffer.size ());
gState = State::Ready;
return byteBuffer.size ();
} else if (gMode == Mode::Image) {
std::string imagePath = "";
if (config_ptr) {
auto qr = openConfigSection (config_ptr.get (), "qr");
if (qr) imagePath = readConfigString (qr, "image_path", "");
}
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)) {
std::cerr << "Failed to open image: " << u8Path.string () << " (file not found)"
<< "\n";
gState = State::Ready;
return 0;
}
std::u8string u8PathStr (imagePath.begin (), imagePath.end ());
std::filesystem::path u8Path (u8PathStr);
if (!std::filesystem::is_regular_file (u8Path)) {
std::cerr << "Failed to open image: " << u8Path.string () << " (file not found)"
<< "\n";
gState = State::Ready;
return 0;
}
int width, height, channels;
std::unique_ptr<stbi_uc, void (*) (void *)> buffer (stbi_load (u8Path.string ().c_str (), &width, &height, &channels, 3), stbi_image_free);
if (!buffer) {
std::cerr << "Failed to read image: " << u8Path << " (" << stbi_failure_reason () << ")"
<< "\n";
gState = State::Ready;
return 0;
}
int width, height, channels;
std::unique_ptr<stbi_uc, void (*) (void *)> buffer (stbi_load (u8Path.string ().c_str (), &width, &height, &channels, 3),
stbi_image_free);
if (!buffer) {
std::cerr << "Failed to read image: " << u8Path << " (" << stbi_failure_reason () << ")"
<< "\n";
gState = State::Ready;
return 0;
}
ZXing::ImageView image{buffer.get (), width, height, ZXing::ImageFormat::RGB};
auto result = ReadBarcode (image);
if (!result.isValid ()) {
std::cerr << "Failed to read qr: " << imagePath << " (" << ToString (result.error ()) << ")"
<< "\n";
gState = State::Ready;
return 0;
}
ZXing::ImageView image{buffer.get (), width, height, ZXing::ImageFormat::RGB};
auto result = ReadBarcode (image);
if (!result.isValid ()) {
std::cerr << "Failed to read qr: " << imagePath << " (" << ToString (result.error ()) << ")"
<< "\n";
gState = State::Ready;
return 0;
}
std::cout << "Valid" << std::endl;
auto byteData = result.bytes ();
std::cout << ZXing::ToHex (byteData) << std::endl;
auto dataSize = byteData.size ();
std::cout << "Valid" << std::endl;
auto byteData = result.bytes ();
std::cout << ZXing::ToHex (byteData) << std::endl;
auto dataSize = byteData.size ();
memcpy (dest, byteData.data (), dataSize);
gState = State::Ready;
return dataSize;
} else if (gMode == Mode::Plugin) {
FARPROC getEvent = GetProcAddress (gPlugin, "GetQr");
if (getEvent) {
unsigned char plugin_data[length];
int buf_len = ((getQrEvent *)getEvent) (length, plugin_data);
if (0 < buf_len && buf_len <= length) {
for (int i = 0; i < buf_len; i++)
std::cout << std::hex << std::uppercase << std::setfill ('0') << std::setw (2) << static_cast<int> (plugin_data[i]) << " ";
std::cout << std::endl;
memcpy (dest, plugin_data, buf_len);
} else {
std::cerr << "QR discard! Length invalid: " << buf_len << ", valid range: 0~" << length << std::endl;
}
gState = State::Ready;
return buf_len;
} else {
gState = State::Ready;
return 0;
}
}
} else if (qrPluginRegistered) {
for (auto plugin : qrPlugins) {
FARPROC usingQrEvent = GetProcAddress (plugin, "UsingQr");
if (usingQrEvent) ((event *)usingQrEvent) ();
}
}
return 0;
memcpy (dest, byteData.data (), dataSize);
gState = State::Ready;
return dataSize;
} else if (gMode == Mode::Plugin) {
FARPROC getEvent = GetProcAddress (gPlugin, "GetQr");
if (getEvent) {
unsigned char plugin_data[length];
int buf_len = ((getQrEvent *)getEvent) (length, plugin_data);
if (0 < buf_len && buf_len <= length) {
for (int i = 0; i < buf_len; i++)
std::cout << std::hex << std::uppercase << std::setfill ('0') << std::setw (2) << static_cast<int> (plugin_data[i]) << " ";
std::cout << std::endl;
memcpy (dest, plugin_data, buf_len);
} else {
std::cerr << "QR discard! Length invalid: " << buf_len << ", valid range: 0~" << length << std::endl;
}
gState = State::Ready;
return buf_len;
} else {
gState = State::Ready;
return 0;
}
}
} else if (qrPluginRegistered) {
for (auto plugin : qrPlugins) {
FARPROC usingQrEvent = GetProcAddress (plugin, "UsingQr");
if (usingQrEvent) ((event *)usingQrEvent) ();
}
}
return 0;
}
void
Update () {
if (!qrEnabled) return;
if (gState == State::Ready) {
if (IsButtonTapped (CARD_INSERT_1)) {
if (gameVersion != GameVersion::CHN00) return;
if (!qrEnabled) return;
if (gState == State::Ready) {
if (IsButtonTapped (CARD_INSERT_1)) {
if (gameVersion != GameVersion::CHN00) return;
std::cout << "Insert" << std::endl;
accessCode = "BNTTCNID";
accessCode += accessCode1;
gState = State::CopyWait;
gMode = Mode::Card;
} else if (IsButtonTapped (CARD_INSERT_2)) {
if (gameVersion != GameVersion::CHN00) return;
std::cout << "Insert" << std::endl;
accessCode = "BNTTCNID";
accessCode += accessCode1;
gState = State::CopyWait;
gMode = Mode::Card;
} else if (IsButtonTapped (CARD_INSERT_2)) {
if (gameVersion != GameVersion::CHN00) return;
std::cout << "Insert" << std::endl;
accessCode = "BNTTCNID";
accessCode += accessCode2;
gState = State::CopyWait;
gMode = Mode::Card;
} else if (IsButtonTapped (QR_DATA_READ)) {
std::cout << "Insert" << std::endl;
gState = State::CopyWait;
gMode = Mode::Data;
} else if (IsButtonTapped (QR_IMAGE_READ)) {
std::cout << "Insert" << std::endl;
gState = State::CopyWait;
gMode = Mode::Image;
} else if (qrPluginRegistered) {
for (auto plugin : qrPlugins) {
FARPROC checkEvent = GetProcAddress (plugin, "CheckQr");
if (checkEvent && ((checkQrEvent *)checkEvent) ()) {
std::cout << "Insert" << std::endl;
gState = State::CopyWait;
gMode = Mode::Plugin;
gPlugin = plugin;
break;
}
}
}
}
std::cout << "Insert" << std::endl;
accessCode = "BNTTCNID";
accessCode += accessCode2;
gState = State::CopyWait;
gMode = Mode::Card;
} else if (IsButtonTapped (QR_DATA_READ)) {
std::cout << "Insert" << std::endl;
gState = State::CopyWait;
gMode = Mode::Data;
} else if (IsButtonTapped (QR_IMAGE_READ)) {
std::cout << "Insert" << std::endl;
gState = State::CopyWait;
gMode = Mode::Image;
} else if (qrPluginRegistered) {
for (auto plugin : qrPlugins) {
FARPROC checkEvent = GetProcAddress (plugin, "CheckQr");
if (checkEvent && ((checkQrEvent *)checkEvent) ()) {
std::cout << "Insert" << std::endl;
gState = State::CopyWait;
gMode = Mode::Plugin;
gPlugin = plugin;
break;
}
}
}
}
}
void
Init () {
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) {
std::cerr << "[Init] Config file not found" << std::endl;
return;
}
auto qr = openConfigSection (config_ptr.get (), "qr");
if (!qr) {
std::cerr << "[Init] QR config section not found! QR emulation disabled" << std::endl;
qrEnabled = false;
return;
}
qrEnabled = readConfigBool (qr, "enabled", true);
if (!qrEnabled) {
std::cout << "[Init] QR emulation disabled" << std::endl;
return;
}
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) {
std::cerr << "[Init] Config file not found" << std::endl;
return;
}
auto qr = openConfigSection (config_ptr.get (), "qr");
if (!qr) {
std::cerr << "[Init] QR config section not found! QR emulation disabled" << std::endl;
qrEnabled = false;
return;
}
qrEnabled = readConfigBool (qr, "enabled", true);
if (!qrEnabled) {
std::cout << "[Init] QR emulation disabled" << std::endl;
return;
}
for (auto plugin : plugins) {
FARPROC initEvent = GetProcAddress (plugin, "InitQr");
if (initEvent) ((initQrEvent *)initEvent) (gameVersion);
for (auto plugin : plugins) {
FARPROC initEvent = GetProcAddress (plugin, "InitQr");
if (initEvent) ((initQrEvent *)initEvent) (gameVersion);
FARPROC usingQrEvent = GetProcAddress (plugin, "UsingQr");
if (usingQrEvent) qrPlugins.push_back (plugin);
}
if (qrPlugins.size () > 0) {
std::cout << "QR plugin found!" << std::endl;
qrPluginRegistered = true;
}
FARPROC usingQrEvent = GetProcAddress (plugin, "UsingQr");
if (usingQrEvent) qrPlugins.push_back (plugin);
}
if (qrPlugins.size () > 0) {
std::cout << "QR plugin found!" << std::endl;
qrPluginRegistered = true;
}
SetConsoleOutputCP (CP_UTF8);
auto amHandle = (u64)GetModuleHandle ("AMFrameWork.dll");
switch (gameVersion) {
case GameVersion::JPN00: {
INSTALL_HOOK_DYNAMIC (qrInit, (LPVOID)(amHandle + 0x1b3e0));
INSTALL_HOOK_DYNAMIC (qrClose, (LPVOID)(amHandle + 0x1b5b0));
INSTALL_HOOK_DYNAMIC (qrRead, (LPVOID)(amHandle + 0x1b600));
INSTALL_HOOK_DYNAMIC (callQrUnknown, (LPVOID)(amHandle + 0xfd40));
INSTALL_HOOK_DYNAMIC (Send1, (LPVOID)(amHandle + 0x1bbb0));
INSTALL_HOOK_DYNAMIC (Send2, (LPVOID)(amHandle + 0x1bbf0));
INSTALL_HOOK_DYNAMIC (Send3, (LPVOID)(amHandle + 0x1bc60));
// JPN00 has no Send4
INSTALL_HOOK_DYNAMIC (copy_data, (LPVOID)(amHandle + 0x1bc30));
break;
}
case GameVersion::JPN08: {
INSTALL_HOOK_DYNAMIC (qrInit, (LPVOID)(amHandle + 0x1BA00));
INSTALL_HOOK_DYNAMIC (qrClose, (LPVOID)(amHandle + 0x1BBD0));
INSTALL_HOOK_DYNAMIC (qrRead, (LPVOID)(amHandle + 0x1BC20));
INSTALL_HOOK_DYNAMIC (callQrUnknown, (LPVOID)(amHandle + 0xFD40));
INSTALL_HOOK_DYNAMIC (Send1, (LPVOID)(amHandle + 0x1C220));
INSTALL_HOOK_DYNAMIC (Send2, (LPVOID)(amHandle + 0x1C260));
INSTALL_HOOK_DYNAMIC (Send3, (LPVOID)(amHandle + 0x1C2D0));
// JPN08 has no Send4
INSTALL_HOOK_DYNAMIC (copy_data, (LPVOID)(amHandle + 0x1C2A0));
break;
}
case GameVersion::JPN39: {
INSTALL_HOOK_DYNAMIC (qrInit, (LPVOID)(amHandle + 0x1EDC0));
INSTALL_HOOK_DYNAMIC (qrClose, (LPVOID)(amHandle + 0x1EF60));
INSTALL_HOOK_DYNAMIC (qrRead, (LPVOID)(amHandle + 0x1EFB0));
INSTALL_HOOK_DYNAMIC (callQrUnknown, (LPVOID)(amHandle + 0x11A70));
INSTALL_HOOK_DYNAMIC (Send1, (LPVOID)(amHandle + 0x1F5B0));
INSTALL_HOOK_DYNAMIC (Send2, (LPVOID)(amHandle + 0x1F5F0));
INSTALL_HOOK_DYNAMIC (Send3, (LPVOID)(amHandle + 0x1F660));
INSTALL_HOOK_DYNAMIC (Send4, (LPVOID)(amHandle + 0x1F690));
INSTALL_HOOK_DYNAMIC (copy_data, (LPVOID)(amHandle + 0x1F630));
break;
}
case GameVersion::CHN00: {
INSTALL_HOOK_DYNAMIC (qrInit, (LPVOID)(amHandle + 0x161B0));
INSTALL_HOOK_DYNAMIC (qrClose, (LPVOID)(amHandle + 0x16350));
INSTALL_HOOK_DYNAMIC (qrRead, (LPVOID)(amHandle + 0x163A0));
INSTALL_HOOK_DYNAMIC (callQrUnknown, (LPVOID)(amHandle + 0x8F60));
INSTALL_HOOK_DYNAMIC (Send1, (LPVOID)(amHandle + 0x16940));
INSTALL_HOOK_DYNAMIC (Send2, (LPVOID)(amHandle + 0x16990));
INSTALL_HOOK_DYNAMIC (Send3, (LPVOID)(amHandle + 0x16A00));
INSTALL_HOOK_DYNAMIC (Send4, (LPVOID)(amHandle + 0x16A30));
INSTALL_HOOK_DYNAMIC (copy_data, (LPVOID)(amHandle + 0x169D0));
break;
}
default: {
break;
}
}
SetConsoleOutputCP (CP_UTF8);
auto amHandle = (u64)GetModuleHandle ("AMFrameWork.dll");
switch (gameVersion) {
case GameVersion::JPN00: {
INSTALL_HOOK_DYNAMIC (qrInit, (LPVOID)(amHandle + 0x1b3e0));
INSTALL_HOOK_DYNAMIC (qrClose, (LPVOID)(amHandle + 0x1b5b0));
INSTALL_HOOK_DYNAMIC (qrRead, (LPVOID)(amHandle + 0x1b600));
INSTALL_HOOK_DYNAMIC (callQrUnknown, (LPVOID)(amHandle + 0xfd40));
INSTALL_HOOK_DYNAMIC (Send1, (LPVOID)(amHandle + 0x1bbb0));
INSTALL_HOOK_DYNAMIC (Send2, (LPVOID)(amHandle + 0x1bbf0));
INSTALL_HOOK_DYNAMIC (Send3, (LPVOID)(amHandle + 0x1bc60));
// JPN00 has no Send4
INSTALL_HOOK_DYNAMIC (copy_data, (LPVOID)(amHandle + 0x1bc30));
break;
}
case GameVersion::JPN08: {
INSTALL_HOOK_DYNAMIC (qrInit, (LPVOID)(amHandle + 0x1BA00));
INSTALL_HOOK_DYNAMIC (qrClose, (LPVOID)(amHandle + 0x1BBD0));
INSTALL_HOOK_DYNAMIC (qrRead, (LPVOID)(amHandle + 0x1BC20));
INSTALL_HOOK_DYNAMIC (callQrUnknown, (LPVOID)(amHandle + 0xFD40));
INSTALL_HOOK_DYNAMIC (Send1, (LPVOID)(amHandle + 0x1C220));
INSTALL_HOOK_DYNAMIC (Send2, (LPVOID)(amHandle + 0x1C260));
INSTALL_HOOK_DYNAMIC (Send3, (LPVOID)(amHandle + 0x1C2D0));
// JPN08 has no Send4
INSTALL_HOOK_DYNAMIC (copy_data, (LPVOID)(amHandle + 0x1C2A0));
break;
}
case GameVersion::JPN39: {
INSTALL_HOOK_DYNAMIC (qrInit, (LPVOID)(amHandle + 0x1EDC0));
INSTALL_HOOK_DYNAMIC (qrClose, (LPVOID)(amHandle + 0x1EF60));
INSTALL_HOOK_DYNAMIC (qrRead, (LPVOID)(amHandle + 0x1EFB0));
INSTALL_HOOK_DYNAMIC (callQrUnknown, (LPVOID)(amHandle + 0x11A70));
INSTALL_HOOK_DYNAMIC (Send1, (LPVOID)(amHandle + 0x1F5B0));
INSTALL_HOOK_DYNAMIC (Send2, (LPVOID)(amHandle + 0x1F5F0));
INSTALL_HOOK_DYNAMIC (Send3, (LPVOID)(amHandle + 0x1F660));
INSTALL_HOOK_DYNAMIC (Send4, (LPVOID)(amHandle + 0x1F690));
INSTALL_HOOK_DYNAMIC (copy_data, (LPVOID)(amHandle + 0x1F630));
break;
}
case GameVersion::CHN00: {
INSTALL_HOOK_DYNAMIC (qrInit, (LPVOID)(amHandle + 0x161B0));
INSTALL_HOOK_DYNAMIC (qrClose, (LPVOID)(amHandle + 0x16350));
INSTALL_HOOK_DYNAMIC (qrRead, (LPVOID)(amHandle + 0x163A0));
INSTALL_HOOK_DYNAMIC (callQrUnknown, (LPVOID)(amHandle + 0x8F60));
INSTALL_HOOK_DYNAMIC (Send1, (LPVOID)(amHandle + 0x16940));
INSTALL_HOOK_DYNAMIC (Send2, (LPVOID)(amHandle + 0x16990));
INSTALL_HOOK_DYNAMIC (Send3, (LPVOID)(amHandle + 0x16A00));
INSTALL_HOOK_DYNAMIC (Send4, (LPVOID)(amHandle + 0x16A30));
INSTALL_HOOK_DYNAMIC (copy_data, (LPVOID)(amHandle + 0x169D0));
break;
}
default: {
break;
}
}
}
} // namespace patches::Qr
+140 -140
View File
@@ -12,16 +12,16 @@ HOOK (i32, HaspEncrypt, PROC_ADDRESS ("hasp_windows_x64.dll", "hasp_encrypt")) {
HOOK (i32, HaspLogout, PROC_ADDRESS ("hasp_windows_x64.dll", "hasp_logout")) { return 0; }
HOOK (i32, HaspWrite, PROC_ADDRESS ("hasp_windows_x64.dll", "hasp_write")) { return 0; }
HOOK (i32, HaspLogin, PROC_ADDRESS ("hasp_windows_x64.dll", "hasp_login"), i32, char *, i32 *id) {
*id = 1;
return 0;
*id = 1;
return 0;
}
HOOK (i32, HaspGetInfo, PROC_ADDRESS ("hasp_windows_x64.dll", "hasp_get_info"), const char *, const char *, void *, const char **a4) {
*a4 = "type=\"HASP-HL\"";
return 0;
*a4 = "type=\"HASP-HL\"";
return 0;
}
HOOK (i32, HaspRead, PROC_ADDRESS ("hasp_windows_x64.dll", "hasp_read"), i32, i32, i32 offset, i32 length, void *buffer) {
memcpy (buffer, haspBuffer + offset, length);
return 0;
memcpy (buffer, haspBuffer + offset, length);
return 0;
}
i64 (__fastcall *lua_settop) (u64, u64) = (i64 (__fastcall *) (u64, u64))PROC_ADDRESS ("lua51.dll", "lua_settop");
@@ -30,9 +30,9 @@ i64 (__fastcall *lua_pushstring) (u64, u64) = (i64 (__fastcall *) (u64, u64))PR
i64
lua_pushtrue (i64 a1) {
lua_settop (a1, 0);
lua_pushboolean (a1, 1);
return 1;
lua_settop (a1, 0);
lua_pushboolean (a1, 1);
return 1;
}
HOOK (i64, AvailableMode_Dani_AI, ASLR (0x1401AC550), i64 a1) { return lua_pushtrue (a1); }
@@ -42,28 +42,28 @@ HOOK (i64, AvailableMode_Collabo026, ASLR (0x1402BC9B0), i64 a1) { return lua_pu
int language = 0;
const char *
languageStr () {
switch (language) {
case 1: return "en_us";
case 2: return "cn_tw";
case 3: return "kor";
case 4: return "cn_cn";
default: return "jpn";
}
switch (language) {
case 1: return "en_us";
case 2: return "cn_tw";
case 3: return "kor";
case 4: return "cn_cn";
default: return "jpn";
}
}
HOOK (i64, GetLanguage, ASLR (0x140023720), i64 a1) {
auto result = originalGetLanguage (a1);
language = *((u32 *)result);
return result;
auto result = originalGetLanguage (a1);
language = *((u32 *)result);
return result;
}
HOOK (i64, GetRegionLanguage, ASLR (0x1401AC300), i64 a1) {
lua_settop (a1, 0);
lua_pushstring (a1, (u64)languageStr ());
return 1;
lua_settop (a1, 0);
lua_pushstring (a1, (u64)languageStr ());
return 1;
}
HOOK (i64, GetCabinetLanguage, ASLR (0x1401AF270), i64, i64 a2) {
lua_settop (a2, 0);
lua_pushstring (a2, (u64)languageStr ());
return 1;
lua_settop (a2, 0);
lua_pushstring (a2, (u64)languageStr ());
return 1;
}
HOOK_DYNAMIC (char, __fastcall, AMFWTerminate, i64) { return 0; }
@@ -79,145 +79,145 @@ const std::vector<uintptr_t> memsetSizeAddresses = {0x140093416, 0x1400934
void
AllocateStaticBufferNear (void *target_address, size_t size, safetyhook::Allocation *newBuffer) {
auto allocator = safetyhook::Allocator::global ();
std::vector desired_addresses = {(uint8_t *)target_address};
auto allocation_result = allocator->allocate_near (desired_addresses, size);
if (allocation_result.has_value ()) *newBuffer = std::move (*allocation_result);
auto allocator = safetyhook::Allocator::global ();
std::vector desired_addresses = {(uint8_t *)target_address};
auto allocation_result = allocator->allocate_near (desired_addresses, size);
if (allocation_result.has_value ()) *newBuffer = std::move (*allocation_result);
}
void
ReplaceLeaBufferAddress (const std::vector<uintptr_t> &bufferAddresses, void *newBufferAddress) {
for (auto bufferAddress : bufferAddresses) {
uintptr_t lea_instruction_dst = ASLR (bufferAddress) + 3;
uintptr_t lea_instruction_end = ASLR (bufferAddress) + 7;
intptr_t offset = (intptr_t)newBufferAddress - lea_instruction_end;
WRITE_MEMORY (lea_instruction_dst, i32, (i32)offset);
}
for (auto bufferAddress : bufferAddresses) {
uintptr_t lea_instruction_dst = ASLR (bufferAddress) + 3;
uintptr_t lea_instruction_end = ASLR (bufferAddress) + 7;
intptr_t offset = (intptr_t)newBufferAddress - lea_instruction_end;
WRITE_MEMORY (lea_instruction_dst, i32, (i32)offset);
}
}
void
Init () {
i32 xRes = 1920;
i32 yRes = 1080;
bool vsync = false;
bool unlockSongs = true;
bool fixLanguage = false;
bool demoMovie = true;
bool modeCollabo025 = false;
bool modeCollabo026 = false;
i32 xRes = 1920;
i32 yRes = 1080;
bool vsync = false;
bool unlockSongs = true;
bool fixLanguage = false;
bool demoMovie = true;
bool modeCollabo025 = false;
bool modeCollabo026 = false;
haspBuffer = (u8 *)malloc (0xD40);
memset (haspBuffer, 0, 0xD40);
strcpy ((char *)(haspBuffer + 0xD00), chassisId.c_str ());
u8 crc = 0;
for (int i = 0; i < 62; i++)
crc += haspBuffer[0xD00 + i];
haspBuffer[0xD3E] = crc;
haspBuffer[0xD3F] = haspBuffer[0xD3E] ^ 0xFF;
haspBuffer = (u8 *)malloc (0xD40);
memset (haspBuffer, 0, 0xD40);
strcpy ((char *)(haspBuffer + 0xD00), chassisId.c_str ());
u8 crc = 0;
for (int i = 0; i < 62; i++)
crc += haspBuffer[0xD00 + i];
haspBuffer[0xD3E] = crc;
haspBuffer[0xD3F] = haspBuffer[0xD3E] ^ 0xFF;
INSTALL_HOOK (HaspDecrypt);
INSTALL_HOOK (HaspEncrypt);
INSTALL_HOOK (HaspLogout);
INSTALL_HOOK (HaspWrite);
INSTALL_HOOK (HaspLogin);
INSTALL_HOOK (HaspGetInfo);
INSTALL_HOOK (HaspRead);
INSTALL_HOOK (HaspDecrypt);
INSTALL_HOOK (HaspEncrypt);
INSTALL_HOOK (HaspLogout);
INSTALL_HOOK (HaspWrite);
INSTALL_HOOK (HaspLogin);
INSTALL_HOOK (HaspGetInfo);
INSTALL_HOOK (HaspRead);
auto configPath = std::filesystem::current_path () / "config.toml";
std::unique_ptr<toml_table_t, void (*) (toml_table_t *)> config_ptr (openConfig (configPath), toml_free);
if (config_ptr) {
auto patches = openConfigSection (config_ptr.get (), "patches");
if (patches) {
auto res = openConfigSection (patches, "res");
if (res) {
xRes = readConfigInt (res, "x", xRes);
yRes = readConfigInt (res, "y", yRes);
}
vsync = readConfigBool (patches, "vsync", vsync);
unlockSongs = readConfigBool (patches, "unlock_songs", unlockSongs);
auto chn00 = openConfigSection (patches, "chn00");
if (chn00) {
fixLanguage = readConfigBool (chn00, "fix_language", fixLanguage);
demoMovie = readConfigBool (chn00, "demo_movie", demoMovie);
modeCollabo025 = readConfigBool (chn00, "mode_collabo025", modeCollabo025);
modeCollabo026 = readConfigBool (chn00, "mode_collabo026", modeCollabo026);
}
}
}
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 patches = openConfigSection (config_ptr.get (), "patches");
if (patches) {
auto res = openConfigSection (patches, "res");
if (res) {
xRes = readConfigInt (res, "x", xRes);
yRes = readConfigInt (res, "y", yRes);
}
vsync = readConfigBool (patches, "vsync", vsync);
unlockSongs = readConfigBool (patches, "unlock_songs", unlockSongs);
auto chn00 = openConfigSection (patches, "chn00");
if (chn00) {
fixLanguage = readConfigBool (chn00, "fix_language", fixLanguage);
demoMovie = readConfigBool (chn00, "demo_movie", demoMovie);
modeCollabo025 = readConfigBool (chn00, "mode_collabo025", modeCollabo025);
modeCollabo026 = readConfigBool (chn00, "mode_collabo026", modeCollabo026);
}
}
}
// Apply common config patch
WRITE_MEMORY (ASLR (0x1404A4ED3), i32, xRes);
WRITE_MEMORY (ASLR (0x1404A4EDA), i32, yRes);
if (!vsync) WRITE_MEMORY (ASLR (0x1405FC5B9), u8, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x90);
if (unlockSongs) WRITE_MEMORY (ASLR (0x140425BCD), u8, 0xB0, 0x01);
// Apply common config patch
WRITE_MEMORY (ASLR (0x1404A4ED3), i32, xRes);
WRITE_MEMORY (ASLR (0x1404A4EDA), i32, yRes);
if (!vsync) WRITE_MEMORY (ASLR (0x1405FC5B9), u8, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x90);
if (unlockSongs) WRITE_MEMORY (ASLR (0x140425BCD), u8, 0xB0, 0x01);
// Bypass errors
WRITE_MEMORY (ASLR (0x14003F690), u8, 0xC3);
// Bypass errors
WRITE_MEMORY (ASLR (0x14003F690), u8, 0xC3);
// Use TLS v1.2
WRITE_MEMORY (ASLR (0x140369662), u8, 0x10);
// Use TLS v1.2
WRITE_MEMORY (ASLR (0x140369662), u8, 0x10);
// Disable SSLVerify
WRITE_MEMORY (ASLR (0x14034C182), u8, 0x00);
// Disable SSLVerify
WRITE_MEMORY (ASLR (0x14034C182), u8, 0x00);
// Move various files to current directory
WRITE_MEMORY (ASLR (0x140C33C40), char, "./");
WRITE_MEMORY (ASLR (0x140C33C44), char, "./");
WRITE_MEMORY (ASLR (0x140C7B158), char, ".\\SettingChina1.bin");
WRITE_MEMORY (ASLR (0x140C7B2B8), char, ".\\SettingChina1.bin");
WRITE_MEMORY (ASLR (0x140C7B2A0), char, ".\\SettingChina2.bin");
WRITE_MEMORY (ASLR (0x140C3CF58), char, ".\\TournamentData\\PlayData\\TournamentPlayData.dat");
WRITE_MEMORY (ASLR (0x140C3CF90), char, ".\\TournamentData\\InfoData\\TournamentInfoData.dat");
WRITE_MEMORY (ASLR (0x140C3CFC8), char, ".\\TournamentData\\PlayData\\TournamentPlayData.dat");
WRITE_MEMORY (ASLR (0x140C3D000), char, ".\\TournamentData\\InfoData\\TournamentInfoData.dat");
// Move various files to current directory
WRITE_MEMORY (ASLR (0x140C33C40), char, "./");
WRITE_MEMORY (ASLR (0x140C33C44), char, "./");
WRITE_MEMORY (ASLR (0x140C7B158), char, ".\\SettingChina1.bin");
WRITE_MEMORY (ASLR (0x140C7B2B8), char, ".\\SettingChina1.bin");
WRITE_MEMORY (ASLR (0x140C7B2A0), char, ".\\SettingChina2.bin");
WRITE_MEMORY (ASLR (0x140C3CF58), char, ".\\TournamentData\\PlayData\\TournamentPlayData.dat");
WRITE_MEMORY (ASLR (0x140C3CF90), char, ".\\TournamentData\\InfoData\\TournamentInfoData.dat");
WRITE_MEMORY (ASLR (0x140C3CFC8), char, ".\\TournamentData\\PlayData\\TournamentPlayData.dat");
WRITE_MEMORY (ASLR (0x140C3D000), char, ".\\TournamentData\\InfoData\\TournamentInfoData.dat");
// Remove datatable size limit
{
for (auto address : memsetSizeAddresses)
WRITE_MEMORY (ASLR (address) + 2, i32, datatableBufferSize);
// Remove datatable size limit
{
for (auto address : memsetSizeAddresses)
WRITE_MEMORY (ASLR (address) + 2, i32, datatableBufferSize);
auto bufferBase = MODULE_HANDLE - 0x03000000;
AllocateStaticBufferNear ((void *)bufferBase, datatableBufferSize, &datatableBuffer1);
bufferBase += datatableBufferSize;
AllocateStaticBufferNear ((void *)bufferBase, datatableBufferSize, &datatableBuffer2);
bufferBase += datatableBufferSize;
AllocateStaticBufferNear ((void *)bufferBase, datatableBufferSize, &datatableBuffer3);
auto bufferBase = MODULE_HANDLE - 0x03000000;
AllocateStaticBufferNear ((void *)bufferBase, datatableBufferSize, &datatableBuffer1);
bufferBase += datatableBufferSize;
AllocateStaticBufferNear ((void *)bufferBase, datatableBufferSize, &datatableBuffer2);
bufferBase += datatableBufferSize;
AllocateStaticBufferNear ((void *)bufferBase, datatableBufferSize, &datatableBuffer3);
ReplaceLeaBufferAddress (datatableBuffer1Addresses, datatableBuffer1.data ());
ReplaceLeaBufferAddress (datatableBuffer2Addresses, datatableBuffer2.data ());
ReplaceLeaBufferAddress (datatableBuffer3Addresses, datatableBuffer3.data ());
}
ReplaceLeaBufferAddress (datatableBuffer1Addresses, datatableBuffer1.data ());
ReplaceLeaBufferAddress (datatableBuffer2Addresses, datatableBuffer2.data ());
ReplaceLeaBufferAddress (datatableBuffer3Addresses, datatableBuffer3.data ());
}
// Fix language
if (fixLanguage) {
INSTALL_HOOK (GetLanguage);
INSTALL_HOOK (GetRegionLanguage);
INSTALL_HOOK (GetCabinetLanguage);
}
// Fix language
if (fixLanguage) {
INSTALL_HOOK (GetLanguage);
INSTALL_HOOK (GetRegionLanguage);
INSTALL_HOOK (GetCabinetLanguage);
}
// Disable demo movie
if (!demoMovie) WRITE_MEMORY (ASLR (0x14047D387), u8, 0x00);
// Disable demo movie
if (!demoMovie) WRITE_MEMORY (ASLR (0x14047D387), u8, 0x00);
// Enable mode
INSTALL_HOOK (AvailableMode_Dani_AI);
if (modeCollabo025) INSTALL_HOOK (AvailableMode_Collabo025);
if (modeCollabo026) INSTALL_HOOK (AvailableMode_Collabo026);
// Enable mode
INSTALL_HOOK (AvailableMode_Dani_AI);
if (modeCollabo025) INSTALL_HOOK (AvailableMode_Collabo025);
if (modeCollabo026) INSTALL_HOOK (AvailableMode_Collabo026);
// Disable live check
auto amHandle = (u64)GetModuleHandle ("AMFrameWork.dll");
INSTALL_HOOK_DYNAMIC (AMFWTerminate, (void *)(amHandle + 0x25A00));
// Disable live check
auto amHandle = (u64)GetModuleHandle ("AMFrameWork.dll");
INSTALL_HOOK_DYNAMIC (AMFWTerminate, (void *)(amHandle + 0x25A00));
// Move various files to current directory
WRITE_MEMORY (amHandle + 0xC652, u8, 0xEB); // CreditLogPathA
WRITE_MEMORY (amHandle + 0xC819, u8, 0xEB); // CreditLogPathB
WRITE_MEMORY (amHandle + 0x243BA, u8, 0xEB); // ErrorLogPathA
WRITE_MEMORY (amHandle + 0x24539, u8, 0xEB); // ErrorLogPathB
WRITE_MEMORY (amHandle + 0x24901, u8, 0xEB); // CommonLogPathA
WRITE_MEMORY (amHandle + 0x24A85, u8, 0xEB); // CommonLogPathB
WRITE_MEMORY (amHandle + 0x24DD1, u8, 0x90, 0x90, 0x90, 0x90, 0x90); // BackupDataPathA
WRITE_MEMORY (amHandle + 0x24E47, u8, 0x90, 0x90, 0x90, 0x90, 0x90); // BackupDataPathB
// Move various files to current directory
WRITE_MEMORY (amHandle + 0xC652, u8, 0xEB); // CreditLogPathA
WRITE_MEMORY (amHandle + 0xC819, u8, 0xEB); // CreditLogPathB
WRITE_MEMORY (amHandle + 0x243BA, u8, 0xEB); // ErrorLogPathA
WRITE_MEMORY (amHandle + 0x24539, u8, 0xEB); // ErrorLogPathB
WRITE_MEMORY (amHandle + 0x24901, u8, 0xEB); // CommonLogPathA
WRITE_MEMORY (amHandle + 0x24A85, u8, 0xEB); // CommonLogPathB
WRITE_MEMORY (amHandle + 0x24DD1, u8, 0x90, 0x90, 0x90, 0x90, 0x90); // BackupDataPathA
WRITE_MEMORY (amHandle + 0x24E47, u8, 0x90, 0x90, 0x90, 0x90, 0x90); // BackupDataPathB
patches::Audio::Init ();
patches::Qr::Init ();
patches::Audio::Init ();
patches::Qr::Init ();
}
} // namespace patches::CHN00
+76 -74
View File
@@ -7,9 +7,9 @@ extern void *song_data;
#define RDX_MOV 0x48, 0xBA
#define R8_MOV 0x49, 0xB8
#define GENERATE_MOV(instruction, location) \
instruction, (u8)(u64)(location), (u8)((u64)(location) >> 8), (u8)((u64)(location) >> 16), (u8)((u64)(location) >> 24), (u8)((u64)(location) >> 32), (u8)((u64)(location) >> 40), \
(u8)((u64)(location) >> 48), (u8)((u64)(location) >> 56)
#define GENERATE_MOV(instruction, location) \
instruction, (u8)(u64)(location), (u8)((u64)(location) >> 8), (u8)((u64)(location) >> 16), (u8)((u64)(location) >> 24), \
(u8)((u64)(location) >> 32), (u8)((u64)(location) >> 40), (u8)((u64)(location) >> 48), (u8)((u64)(location) >> 56)
namespace patches::JPN00 {
@@ -17,98 +17,100 @@ HOOK_DYNAMIC (char, __fastcall, AMFWTerminate, i64) { return 0; }
const i32 datatableBufferSize = 1024 * 1024 * 12;
safetyhook::Allocation datatableBuffer;
const std::vector<uintptr_t> datatableBufferAddresses = {0x14005A418, 0x14005A445, 0x14005A778, 0x14005A7A5, 0x14005AD58, 0x14005AD85, 0x14005B1F2, 0x14005B221, 0x14005B438,
0x14005B465, 0x14005B7D8, 0x14005B805, 0x14005BA59, 0x14005BA88, 0x14005BD78, 0x14005BDA7, 0x14005C1B3, 0x14005C1E2,
0x14005CC52, 0x14005CC81, 0x14005D348, 0x14005D375, 0x14005D668, 0x14005D695, 0x14005D9D2, 0x14005DA04, 0x14005EA04,
0x14005EA33, 0x14005EC18, 0x14005EC45, 0x14005EEE4, 0x14005EF10, 0x14005F158, 0x14005F185, 0x14005F47C, 0x14005F4A9};
const std::vector<uintptr_t> memsetSizeAddresses = {0x14005A412, 0x14005A772, 0x14005AD52, 0x14005B1EC, 0x14005B432, 0x14005B7D2, 0x14005BA53, 0x14005BD72, 0x14005C1AD,
0x14005CC4C, 0x14005D342, 0x14005D662, 0x14005D9CC, 0x14005E9FE, 0x14005EC12, 0x14005EEDE, 0x14005F152, 0x14005F476};
const std::vector<uintptr_t> datatableBufferAddresses
= {0x14005A418, 0x14005A445, 0x14005A778, 0x14005A7A5, 0x14005AD58, 0x14005AD85, 0x14005B1F2, 0x14005B221, 0x14005B438,
0x14005B465, 0x14005B7D8, 0x14005B805, 0x14005BA59, 0x14005BA88, 0x14005BD78, 0x14005BDA7, 0x14005C1B3, 0x14005C1E2,
0x14005CC52, 0x14005CC81, 0x14005D348, 0x14005D375, 0x14005D668, 0x14005D695, 0x14005D9D2, 0x14005DA04, 0x14005EA04,
0x14005EA33, 0x14005EC18, 0x14005EC45, 0x14005EEE4, 0x14005EF10, 0x14005F158, 0x14005F185, 0x14005F47C, 0x14005F4A9};
const std::vector<uintptr_t> memsetSizeAddresses
= {0x14005A412, 0x14005A772, 0x14005AD52, 0x14005B1EC, 0x14005B432, 0x14005B7D2, 0x14005BA53, 0x14005BD72, 0x14005C1AD,
0x14005CC4C, 0x14005D342, 0x14005D662, 0x14005D9CC, 0x14005E9FE, 0x14005EC12, 0x14005EEDE, 0x14005F152, 0x14005F476};
void
AllocateStaticBufferNear (void *target_address, size_t size, safetyhook::Allocation *newBuffer) {
auto allocator = safetyhook::Allocator::global ();
std::vector desired_addresses = {(uint8_t *)target_address};
auto allocation_result = allocator->allocate_near (desired_addresses, size);
if (allocation_result.has_value ()) *newBuffer = std::move (*allocation_result);
auto allocator = safetyhook::Allocator::global ();
std::vector desired_addresses = {(uint8_t *)target_address};
auto allocation_result = allocator->allocate_near (desired_addresses, size);
if (allocation_result.has_value ()) *newBuffer = std::move (*allocation_result);
}
void
ReplaceLeaBufferAddress (const std::vector<uintptr_t> &bufferAddresses, void *newBufferAddress) {
for (auto bufferAddress : bufferAddresses) {
uintptr_t lea_instruction_dst = ASLR (bufferAddress) + 3;
uintptr_t lea_instruction_end = ASLR (bufferAddress) + 7;
intptr_t offset = (intptr_t)newBufferAddress - lea_instruction_end;
WRITE_MEMORY (lea_instruction_dst, i32, (i32)offset);
}
for (auto bufferAddress : bufferAddresses) {
uintptr_t lea_instruction_dst = ASLR (bufferAddress) + 3;
uintptr_t lea_instruction_end = ASLR (bufferAddress) + 7;
intptr_t offset = (intptr_t)newBufferAddress - lea_instruction_end;
WRITE_MEMORY (lea_instruction_dst, i32, (i32)offset);
}
}
void
Init () {
i32 xRes = 1920;
i32 yRes = 1080;
bool vsync = false;
bool unlockSongs = true;
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) {
auto patches = openConfigSection (config_ptr.get (), "patches");
if (patches) {
auto res = openConfigSection (patches, "res");
if (res) {
xRes = readConfigInt (res, "x", xRes);
yRes = readConfigInt (res, "y", yRes);
}
vsync = readConfigBool (patches, "vsync", vsync);
unlockSongs = readConfigBool (patches, "unlock_songs", unlockSongs);
}
}
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 patches = openConfigSection (config_ptr.get (), "patches");
if (patches) {
auto res = openConfigSection (patches, "res");
if (res) {
xRes = readConfigInt (res, "x", xRes);
yRes = readConfigInt (res, "y", yRes);
}
vsync = readConfigBool (patches, "vsync", vsync);
unlockSongs = readConfigBool (patches, "unlock_songs", unlockSongs);
}
}
// Apply common config patch
WRITE_MEMORY (ASLR (0x140224B2B), i32, xRes);
WRITE_MEMORY (ASLR (0x140224B32), i32, yRes);
if (!vsync) WRITE_MEMORY (ASLR (0x1403D6189), u8, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x90);
if (unlockSongs) WRITE_MEMORY (ASLR (0x1401F6B78), u8, 0xB0, 0x01);
// Apply common config patch
WRITE_MEMORY (ASLR (0x140224B2B), i32, xRes);
WRITE_MEMORY (ASLR (0x140224B32), i32, yRes);
if (!vsync) WRITE_MEMORY (ASLR (0x1403D6189), u8, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x90);
if (unlockSongs) WRITE_MEMORY (ASLR (0x1401F6B78), u8, 0xB0, 0x01);
// Bypass errors
WRITE_MEMORY (ASLR (0x14001F0A0), u8, 0xC3);
// Bypass errors
WRITE_MEMORY (ASLR (0x14001F0A0), u8, 0xC3);
// Use TLS v1.2
WRITE_MEMORY (ASLR (0x140309AC9), u8, 0x10);
// Use TLS v1.2
WRITE_MEMORY (ASLR (0x140309AC9), u8, 0x10);
// Move various files to current dir
WRITE_MEMORY (ASLR (0x140018351), u8, 0x02);
WRITE_MEMORY (ASLR (0x1409A7138), char, "./");
WRITE_MEMORY (ASLR (0x1409D23B8), char, ".\\Setting1.bin");
WRITE_MEMORY (ASLR (0x1409D23C8), char, ".\\Setting2.bin");
// Move various files to current dir
WRITE_MEMORY (ASLR (0x140018351), u8, 0x02);
WRITE_MEMORY (ASLR (0x1409A7138), char, "./");
WRITE_MEMORY (ASLR (0x1409D23B8), char, ".\\Setting1.bin");
WRITE_MEMORY (ASLR (0x1409D23C8), char, ".\\Setting2.bin");
// Remove datatable size limit
{
for (auto address : memsetSizeAddresses)
WRITE_MEMORY (ASLR (address) + 2, i32, datatableBufferSize);
// Remove datatable size limit
{
for (auto address : memsetSizeAddresses)
WRITE_MEMORY (ASLR (address) + 2, i32, datatableBufferSize);
auto bufferBase = MODULE_HANDLE - 0x01000000;
AllocateStaticBufferNear ((void *)bufferBase, datatableBufferSize, &datatableBuffer);
auto bufferBase = MODULE_HANDLE - 0x01000000;
AllocateStaticBufferNear ((void *)bufferBase, datatableBufferSize, &datatableBuffer);
ReplaceLeaBufferAddress (datatableBufferAddresses, datatableBuffer.data ());
}
ReplaceLeaBufferAddress (datatableBufferAddresses, datatableBuffer.data ());
}
// Disable live check
auto amHandle = (u64)GetModuleHandle ("AMFrameWork.dll");
INSTALL_HOOK_DYNAMIC (AMFWTerminate, (void *)(amHandle + 0x24B80));
// Disable live check
auto amHandle = (u64)GetModuleHandle ("AMFrameWork.dll");
INSTALL_HOOK_DYNAMIC (AMFWTerminate, (void *)(amHandle + 0x24B80));
// Move various files to current directory
WRITE_MEMORY (amHandle + 0x1473F, u8, 0xEB); // CreditLogPathA
WRITE_MEMORY (amHandle + 0x148AA, u8, 0xEB); // CreditLogPathB
WRITE_MEMORY (amHandle + 0x321A7, u8, 0xEB); // ErrorLogPathA
WRITE_MEMORY (amHandle + 0x322FA, u8, 0xEB); // ErrorLogPathB
WRITE_MEMORY (amHandle + 0x326D9, u8, 0xEB); // CommonLogPathA
WRITE_MEMORY (amHandle + 0x3282C, u8, 0xEB); // CommonLogPathB
WRITE_MEMORY (amHandle + 0x32C2A, u8, 0xEB); // BackupDataPathA
WRITE_MEMORY (amHandle + 0x32D7D, u8, 0xEB); // BackupDataPathB
// Move various files to current directory
WRITE_MEMORY (amHandle + 0x1473F, u8, 0xEB); // CreditLogPathA
WRITE_MEMORY (amHandle + 0x148AA, u8, 0xEB); // CreditLogPathB
WRITE_MEMORY (amHandle + 0x321A7, u8, 0xEB); // ErrorLogPathA
WRITE_MEMORY (amHandle + 0x322FA, u8, 0xEB); // ErrorLogPathB
WRITE_MEMORY (amHandle + 0x326D9, u8, 0xEB); // CommonLogPathA
WRITE_MEMORY (amHandle + 0x3282C, u8, 0xEB); // CommonLogPathB
WRITE_MEMORY (amHandle + 0x32C2A, u8, 0xEB); // BackupDataPathA
WRITE_MEMORY (amHandle + 0x32D7D, u8, 0xEB); // BackupDataPathB
patches::Audio::Init ();
patches::Qr::Init ();
patches::AmAuth::Init ();
patches::Audio::Init ();
patches::Qr::Init ();
patches::AmAuth::Init ();
}
} // namespace patches::JPN00
+141 -139
View File
@@ -7,9 +7,9 @@ extern void *song_data;
#define RDX_MOV 0x48, 0xBA
#define R8_MOV 0x49, 0xB8
#define GENERATE_MOV(instruction, location) \
instruction, (u8)(u64)(location), (u8)((u64)(location) >> 8), (u8)((u64)(location) >> 16), (u8)((u64)(location) >> 24), (u8)((u64)(location) >> 32), (u8)((u64)(location) >> 40), \
(u8)((u64)(location) >> 48), (u8)((u64)(location) >> 56)
#define GENERATE_MOV(instruction, location) \
instruction, (u8)(u64)(location), (u8)((u64)(location) >> 8), (u8)((u64)(location) >> 16), (u8)((u64)(location) >> 24), \
(u8)((u64)(location) >> 32), (u8)((u64)(location) >> 40), (u8)((u64)(location) >> 48), (u8)((u64)(location) >> 56)
namespace patches::JPN08 {
@@ -17,166 +17,168 @@ HOOK_DYNAMIC (char, __fastcall, AMFWTerminate, i64) { return 0; }
const i32 datatableBufferSize = 1024 * 1024 * 12;
safetyhook::Allocation datatableBuffer;
const std::vector<uintptr_t> datatableBufferAddresses = {0x14006D9A6, 0x14006D9D3, 0x14006E048, 0x14006E075, 0x14006E3A8, 0x14006E3D5, 0x14006E988, 0x14006E9B5, 0x14006EE22, 0x14006EE51, 0x14006F068,
0x14006F095, 0x14006F2F8, 0x14006F325, 0x14006F698, 0x14006F6C5, 0x14006F919, 0x14006F948, 0x14006FC38, 0x14006FC67, 0x14007006C, 0x140070099,
0x1400703E3, 0x140070412, 0x140070EB3, 0x140070EE2, 0x140071748, 0x140071775, 0x140071A68, 0x140071A95, 0x140071DD2, 0x140071E04, 0x140072E44,
0x140072E73, 0x140073058, 0x140073085, 0x140073374, 0x1400733A0, 0x1400735E8, 0x140073615, 0x14007390C, 0x140073939, 0x140073E73, 0x140073EA6,
0x140074A8D, 0x140074ABC, 0x140075082, 0x1400750B1, 0x140075524, 0x140075550, 0x1400758A2, 0x1400758D1, 0x140075D88, 0x140075DB5, 0x1403BA8FD};
const std::vector<uintptr_t> memsetSizeAddresses = {0x14006D9A0, 0x14006E042, 0x14006E3A2, 0x14006E982, 0x14006EE1C, 0x14006F062, 0x14006F2F2, 0x14006F692, 0x14006F913,
0x14006FC32, 0x140070066, 0x1400703DD, 0x140070EAD, 0x140071742, 0x140071A62, 0x140071DCC, 0x140072E3E, 0x140073052,
0x14007336E, 0x1400735E2, 0x140073906, 0x140073E6D, 0x140074A87, 0x14007507C, 0x14007551E, 0x14007589C, 0x140075D82};
const std::vector<uintptr_t> datatableBufferAddresses
= {0x14006D9A6, 0x14006D9D3, 0x14006E048, 0x14006E075, 0x14006E3A8, 0x14006E3D5, 0x14006E988, 0x14006E9B5, 0x14006EE22, 0x14006EE51, 0x14006F068,
0x14006F095, 0x14006F2F8, 0x14006F325, 0x14006F698, 0x14006F6C5, 0x14006F919, 0x14006F948, 0x14006FC38, 0x14006FC67, 0x14007006C, 0x140070099,
0x1400703E3, 0x140070412, 0x140070EB3, 0x140070EE2, 0x140071748, 0x140071775, 0x140071A68, 0x140071A95, 0x140071DD2, 0x140071E04, 0x140072E44,
0x140072E73, 0x140073058, 0x140073085, 0x140073374, 0x1400733A0, 0x1400735E8, 0x140073615, 0x14007390C, 0x140073939, 0x140073E73, 0x140073EA6,
0x140074A8D, 0x140074ABC, 0x140075082, 0x1400750B1, 0x140075524, 0x140075550, 0x1400758A2, 0x1400758D1, 0x140075D88, 0x140075DB5, 0x1403BA8FD};
const std::vector<uintptr_t> memsetSizeAddresses
= {0x14006D9A0, 0x14006E042, 0x14006E3A2, 0x14006E982, 0x14006EE1C, 0x14006F062, 0x14006F2F2, 0x14006F692, 0x14006F913,
0x14006FC32, 0x140070066, 0x1400703DD, 0x140070EAD, 0x140071742, 0x140071A62, 0x140071DCC, 0x140072E3E, 0x140073052,
0x14007336E, 0x1400735E2, 0x140073906, 0x140073E6D, 0x140074A87, 0x14007507C, 0x14007551E, 0x14007589C, 0x140075D82};
void
AllocateStaticBufferNear (void *target_address, size_t size, safetyhook::Allocation *newBuffer) {
auto allocator = safetyhook::Allocator::global ();
std::vector desired_addresses = {(uint8_t *)target_address};
auto allocation_result = allocator->allocate_near (desired_addresses, size);
if (allocation_result.has_value ()) *newBuffer = std::move (*allocation_result);
auto allocator = safetyhook::Allocator::global ();
std::vector desired_addresses = {(uint8_t *)target_address};
auto allocation_result = allocator->allocate_near (desired_addresses, size);
if (allocation_result.has_value ()) *newBuffer = std::move (*allocation_result);
}
void
ReplaceLeaBufferAddress (const std::vector<uintptr_t> &bufferAddresses, void *newBufferAddress) {
for (auto bufferAddress : bufferAddresses) {
uintptr_t lea_instruction_dst = ASLR (bufferAddress) + 3;
uintptr_t lea_instruction_end = ASLR (bufferAddress) + 7;
intptr_t offset = (intptr_t)newBufferAddress - lea_instruction_end;
WRITE_MEMORY (lea_instruction_dst, i32, (i32)offset);
}
for (auto bufferAddress : bufferAddresses) {
uintptr_t lea_instruction_dst = ASLR (bufferAddress) + 3;
uintptr_t lea_instruction_end = ASLR (bufferAddress) + 7;
intptr_t offset = (intptr_t)newBufferAddress - lea_instruction_end;
WRITE_MEMORY (lea_instruction_dst, i32, (i32)offset);
}
}
void
Init () {
i32 xRes = 1920;
i32 yRes = 1080;
bool vsync = false;
bool unlockSongs = true;
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) {
auto patches = openConfigSection (config_ptr.get (), "patches");
if (patches) {
auto res = openConfigSection (patches, "res");
if (res) {
xRes = readConfigInt (res, "x", xRes);
yRes = readConfigInt (res, "y", yRes);
}
vsync = readConfigBool (patches, "vsync", vsync);
unlockSongs = readConfigBool (patches, "unlock_songs", unlockSongs);
}
}
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 patches = openConfigSection (config_ptr.get (), "patches");
if (patches) {
auto res = openConfigSection (patches, "res");
if (res) {
xRes = readConfigInt (res, "x", xRes);
yRes = readConfigInt (res, "y", yRes);
}
vsync = readConfigBool (patches, "vsync", vsync);
unlockSongs = readConfigBool (patches, "unlock_songs", unlockSongs);
}
}
// Apply common config patch
WRITE_MEMORY (ASLR (0x14035FC5B), i32, xRes);
WRITE_MEMORY (ASLR (0x14035FC62), i32, yRes);
if (!vsync) WRITE_MEMORY (ASLR (0x140517339), u8, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x90);
if (unlockSongs) WRITE_MEMORY (ASLR (0x140314E8D), u8, 0xB0, 0x01);
// Apply common config patch
WRITE_MEMORY (ASLR (0x14035FC5B), i32, xRes);
WRITE_MEMORY (ASLR (0x14035FC62), i32, yRes);
if (!vsync) WRITE_MEMORY (ASLR (0x140517339), u8, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x90);
if (unlockSongs) WRITE_MEMORY (ASLR (0x140314E8D), u8, 0xB0, 0x01);
// Bypass errors
WRITE_MEMORY (ASLR (0x1400239C0), u8, 0xC3);
// Bypass errors
WRITE_MEMORY (ASLR (0x1400239C0), u8, 0xC3);
// Use TLS v1.2
WRITE_MEMORY (ASLR (0x14044B1A9), u8, 0x10);
// Use TLS v1.2
WRITE_MEMORY (ASLR (0x14044B1A9), u8, 0x10);
// Move various files to current directory
WRITE_MEMORY (ASLR (0x14001C941), u8, 0x02);
WRITE_MEMORY (ASLR (0x140B1B4B0), char, "./");
WRITE_MEMORY (ASLR (0x140B5C528), char, ".\\Setting1.bin");
WRITE_MEMORY (ASLR (0x140B5C538), char, ".\\Setting2.bin");
// Move various files to current directory
WRITE_MEMORY (ASLR (0x14001C941), u8, 0x02);
WRITE_MEMORY (ASLR (0x140B1B4B0), char, "./");
WRITE_MEMORY (ASLR (0x140B5C528), char, ".\\Setting1.bin");
WRITE_MEMORY (ASLR (0x140B5C538), char, ".\\Setting2.bin");
// Remove datatable size limit
{
for (auto address : memsetSizeAddresses)
WRITE_MEMORY (ASLR (address) + 2, i32, datatableBufferSize);
// Remove datatable size limit
{
for (auto address : memsetSizeAddresses)
WRITE_MEMORY (ASLR (address) + 2, i32, datatableBufferSize);
auto bufferBase = MODULE_HANDLE - 0x01000000;
AllocateStaticBufferNear ((void *)bufferBase, datatableBufferSize, &datatableBuffer);
auto bufferBase = MODULE_HANDLE - 0x01000000;
AllocateStaticBufferNear ((void *)bufferBase, datatableBufferSize, &datatableBuffer);
ReplaceLeaBufferAddress (datatableBufferAddresses, datatableBuffer.data ());
}
ReplaceLeaBufferAddress (datatableBufferAddresses, datatableBuffer.data ());
}
// Remove song limit
{
WRITE_MEMORY (ASLR (0x140313726), i32, 9000);
WRITE_MEMORY (ASLR (0x1402F39E6), i32, 9000);
WRITE_MEMORY (ASLR (0x1402F3AB0), i32, 9000);
WRITE_MEMORY (ASLR (0x1402F3BE4), i32, 9000);
WRITE_MEMORY (ASLR (0x14030643B), i32, 9000);
WRITE_MEMORY (ASLR (0x140306507), i32, 9000);
WRITE_MEMORY (ASLR (0x1403065D3), i32, 9000);
WRITE_MEMORY (ASLR (0x1403066FB), i32, 9000);
WRITE_MEMORY (ASLR (0x1403067C7), i32, 9000);
WRITE_MEMORY (ASLR (0x140306893), i32, 9000);
WRITE_MEMORY (ASLR (0x14030698B), i32, 9000);
WRITE_MEMORY (ASLR (0x140313666), i32, 9000);
WRITE_MEMORY (ASLR (0x1403139F4), i32, 9000);
WRITE_MEMORY (ASLR (0x140313B04), i32, 9000);
WRITE_MEMORY (ASLR (0x140313C24), i32, 9000);
WRITE_MEMORY (ASLR (0x140313CF4), i32, 9000);
WRITE_MEMORY (ASLR (0x1403140C4), i32, 9000);
WRITE_MEMORY (ASLR (0x1403147AA), i32, 9000);
WRITE_MEMORY (ASLR (0x140225FB6), i32, 9000);
WRITE_MEMORY (ASLR (0x140226146), i32, 9000);
WRITE_MEMORY (ASLR (0x140314DCC), i32, 9000);
WRITE_MEMORY (ASLR (0x140314EC9), i32, 9000);
WRITE_MEMORY (ASLR (0x140338E2C), i32, 9000);
WRITE_MEMORY (ASLR (0x1400EE0A4), i32, 9000);
WRITE_MEMORY (ASLR (0x1400EE8B5), i32, 9000);
WRITE_MEMORY (ASLR (0x1400EEDA6), i32, 9000);
WRITE_MEMORY (ASLR (0x140315608), i32, 9000);
WRITE_MEMORY (ASLR (0x14034A7EB), i32, 9000);
WRITE_MEMORY (ASLR (0x1402F3CB3), i32, 9000);
WRITE_MEMORY (ASLR (0x140314059), i32, 9000);
WRITE_MEMORY (ASLR (0x140226063), i32, 9000);
WRITE_MEMORY (ASLR (0x14022609F), i32, 9000);
WRITE_MEMORY (ASLR (0x140226296), i32, 9000);
WRITE_MEMORY (ASLR (0x140306A2E), i32, 9000);
WRITE_MEMORY (ASLR (0x140314F46), i32, 9000);
WRITE_MEMORY (ASLR (0x140314F97), i32, 9000);
// Remove song limit
{
WRITE_MEMORY (ASLR (0x140313726), i32, 9000);
WRITE_MEMORY (ASLR (0x1402F39E6), i32, 9000);
WRITE_MEMORY (ASLR (0x1402F3AB0), i32, 9000);
WRITE_MEMORY (ASLR (0x1402F3BE4), i32, 9000);
WRITE_MEMORY (ASLR (0x14030643B), i32, 9000);
WRITE_MEMORY (ASLR (0x140306507), i32, 9000);
WRITE_MEMORY (ASLR (0x1403065D3), i32, 9000);
WRITE_MEMORY (ASLR (0x1403066FB), i32, 9000);
WRITE_MEMORY (ASLR (0x1403067C7), i32, 9000);
WRITE_MEMORY (ASLR (0x140306893), i32, 9000);
WRITE_MEMORY (ASLR (0x14030698B), i32, 9000);
WRITE_MEMORY (ASLR (0x140313666), i32, 9000);
WRITE_MEMORY (ASLR (0x1403139F4), i32, 9000);
WRITE_MEMORY (ASLR (0x140313B04), i32, 9000);
WRITE_MEMORY (ASLR (0x140313C24), i32, 9000);
WRITE_MEMORY (ASLR (0x140313CF4), i32, 9000);
WRITE_MEMORY (ASLR (0x1403140C4), i32, 9000);
WRITE_MEMORY (ASLR (0x1403147AA), i32, 9000);
WRITE_MEMORY (ASLR (0x140225FB6), i32, 9000);
WRITE_MEMORY (ASLR (0x140226146), i32, 9000);
WRITE_MEMORY (ASLR (0x140314DCC), i32, 9000);
WRITE_MEMORY (ASLR (0x140314EC9), i32, 9000);
WRITE_MEMORY (ASLR (0x140338E2C), i32, 9000);
WRITE_MEMORY (ASLR (0x1400EE0A4), i32, 9000);
WRITE_MEMORY (ASLR (0x1400EE8B5), i32, 9000);
WRITE_MEMORY (ASLR (0x1400EEDA6), i32, 9000);
WRITE_MEMORY (ASLR (0x140315608), i32, 9000);
WRITE_MEMORY (ASLR (0x14034A7EB), i32, 9000);
WRITE_MEMORY (ASLR (0x1402F3CB3), i32, 9000);
WRITE_MEMORY (ASLR (0x140314059), i32, 9000);
WRITE_MEMORY (ASLR (0x140226063), i32, 9000);
WRITE_MEMORY (ASLR (0x14022609F), i32, 9000);
WRITE_MEMORY (ASLR (0x140226296), i32, 9000);
WRITE_MEMORY (ASLR (0x140306A2E), i32, 9000);
WRITE_MEMORY (ASLR (0x140314F46), i32, 9000);
WRITE_MEMORY (ASLR (0x140314F97), i32, 9000);
song_data = malloc (song_data_size);
memset (song_data, 0, song_data_size);
song_data = malloc (song_data_size);
memset (song_data, 0, song_data_size);
// Song data
WRITE_MEMORY (ASLR (0x14031367B), u8, GENERATE_MOV (R8_MOV, song_data));
// Crown data
WRITE_MEMORY (ASLR (0x1402F3AC6), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x1402F39FC), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x1402F3BFA), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x1403140D7), u8, GENERATE_MOV (R8_MOV, song_data));
// Score ranks
WRITE_MEMORY (ASLR (0x1403065EA), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x14030651E), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x140306452), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x1403068AA), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x1403067DE), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x140306712), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x1403069A2), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x1403069AC), u8, 0x90, 0x90, 0x90, 0x90, 0x90);
// Unknown
WRITE_MEMORY (ASLR (0x140313755), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x140313A0B), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x140313B4C), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x140313D38), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x140313C42), u8, GENERATE_MOV (R8_MOV, song_data));
}
// Song data
WRITE_MEMORY (ASLR (0x14031367B), u8, GENERATE_MOV (R8_MOV, song_data));
// Crown data
WRITE_MEMORY (ASLR (0x1402F3AC6), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x1402F39FC), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x1402F3BFA), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x1403140D7), u8, GENERATE_MOV (R8_MOV, song_data));
// Score ranks
WRITE_MEMORY (ASLR (0x1403065EA), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x14030651E), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x140306452), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x1403068AA), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x1403067DE), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x140306712), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x1403069A2), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x1403069AC), u8, 0x90, 0x90, 0x90, 0x90, 0x90);
// Unknown
WRITE_MEMORY (ASLR (0x140313755), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x140313A0B), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x140313B4C), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x140313D38), u8, GENERATE_MOV (RDX_MOV, song_data));
WRITE_MEMORY (ASLR (0x140313C42), u8, GENERATE_MOV (R8_MOV, song_data));
}
// Disable live check
auto amHandle = (u64)GetModuleHandle ("AMFrameWork.dll");
INSTALL_HOOK_DYNAMIC (AMFWTerminate, (void *)(amHandle + 0x35A00));
// Disable live check
auto amHandle = (u64)GetModuleHandle ("AMFrameWork.dll");
INSTALL_HOOK_DYNAMIC (AMFWTerminate, (void *)(amHandle + 0x35A00));
// Move various files to current directory
WRITE_MEMORY (amHandle + 0x148AF, u8, 0xEB); // CreditLogPathA
WRITE_MEMORY (amHandle + 0x14A1A, u8, 0xEB); // CreditLogPathB
WRITE_MEMORY (amHandle + 0x33EF7, u8, 0xEB); // ErrorLogPathA
WRITE_MEMORY (amHandle + 0x3404A, u8, 0xEB); // ErrorLogPathB
WRITE_MEMORY (amHandle + 0x34429, u8, 0xEB); // CommonLogPathA
WRITE_MEMORY (amHandle + 0x3457C, u8, 0xEB); // CommonLogPathB
WRITE_MEMORY (amHandle + 0x3497A, u8, 0xEB); // BackupDataPathA
WRITE_MEMORY (amHandle + 0x34ACD, u8, 0xEB); // BackupDataPathB
// Move various files to current directory
WRITE_MEMORY (amHandle + 0x148AF, u8, 0xEB); // CreditLogPathA
WRITE_MEMORY (amHandle + 0x14A1A, u8, 0xEB); // CreditLogPathB
WRITE_MEMORY (amHandle + 0x33EF7, u8, 0xEB); // ErrorLogPathA
WRITE_MEMORY (amHandle + 0x3404A, u8, 0xEB); // ErrorLogPathB
WRITE_MEMORY (amHandle + 0x34429, u8, 0xEB); // CommonLogPathA
WRITE_MEMORY (amHandle + 0x3457C, u8, 0xEB); // CommonLogPathB
WRITE_MEMORY (amHandle + 0x3497A, u8, 0xEB); // BackupDataPathA
WRITE_MEMORY (amHandle + 0x34ACD, u8, 0xEB); // BackupDataPathB
patches::Audio::Init ();
patches::Qr::Init ();
patches::AmAuth::Init ();
patches::Audio::Init ();
patches::Qr::Init ();
patches::AmAuth::Init ();
}
} // namespace patches::JPN08
+96 -96
View File
@@ -7,10 +7,10 @@ namespace patches::JPN39 {
HOOK_DYNAMIC (char, __fastcall, AMFWTerminate, i64) { return 0; }
HOOK_DYNAMIC (i64, __fastcall, curl_easy_setopt, i64 a1, i64 a2, i64 a3, i64 a4, i64 a5) {
// printf ("garmc curl_easy_setopt\n");
originalcurl_easy_setopt (a1, 64, 0, 0, 0);
originalcurl_easy_setopt (a1, 81, 0, 0, 0);
return originalcurl_easy_setopt (a1, a2, a3, a4, a5);
// printf ("garmc curl_easy_setopt\n");
originalcurl_easy_setopt (a1, 64, 0, 0, 0);
originalcurl_easy_setopt (a1, 81, 0, 0, 0);
return originalcurl_easy_setopt (a1, a2, a3, a4, a5);
}
const i32 datatableBufferSize = 1024 * 1024 * 12;
@@ -24,118 +24,118 @@ const std::vector<uintptr_t> memsetSizeAddresses = {0x1400ABE26, 0x1400ABE
void
AllocateStaticBufferNear (void *target_address, size_t size, safetyhook::Allocation *newBuffer) {
auto allocator = safetyhook::Allocator::global ();
std::vector desired_addresses = {(uint8_t *)target_address};
auto allocation_result = allocator->allocate_near (desired_addresses, size);
if (allocation_result.has_value ()) *newBuffer = std::move (*allocation_result);
auto allocator = safetyhook::Allocator::global ();
std::vector desired_addresses = {(uint8_t *)target_address};
auto allocation_result = allocator->allocate_near (desired_addresses, size);
if (allocation_result.has_value ()) *newBuffer = std::move (*allocation_result);
}
void
ReplaceLeaBufferAddress (const std::vector<uintptr_t> &bufferAddresses, void *newBufferAddress) {
for (auto bufferAddress : bufferAddresses) {
uintptr_t lea_instruction_dst = ASLR (bufferAddress) + 3;
uintptr_t lea_instruction_end = ASLR (bufferAddress) + 7;
intptr_t offset = (intptr_t)newBufferAddress - lea_instruction_end;
WRITE_MEMORY (lea_instruction_dst, i32, (i32)offset);
}
for (auto bufferAddress : bufferAddresses) {
uintptr_t lea_instruction_dst = ASLR (bufferAddress) + 3;
uintptr_t lea_instruction_end = ASLR (bufferAddress) + 7;
intptr_t offset = (intptr_t)newBufferAddress - lea_instruction_end;
WRITE_MEMORY (lea_instruction_dst, i32, (i32)offset);
}
}
void
Init () {
i32 xRes = 1920;
i32 yRes = 1080;
bool vsync = false;
bool unlockSongs = true;
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) {
auto patches = openConfigSection (config_ptr.get (), "patches");
if (patches) {
auto res = openConfigSection (patches, "res");
if (res) {
xRes = readConfigInt (res, "x", xRes);
yRes = readConfigInt (res, "y", yRes);
}
vsync = readConfigBool (patches, "vsync", vsync);
unlockSongs = readConfigBool (patches, "unlock_songs", unlockSongs);
}
}
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 patches = openConfigSection (config_ptr.get (), "patches");
if (patches) {
auto res = openConfigSection (patches, "res");
if (res) {
xRes = readConfigInt (res, "x", xRes);
yRes = readConfigInt (res, "y", yRes);
}
vsync = readConfigBool (patches, "vsync", vsync);
unlockSongs = readConfigBool (patches, "unlock_songs", unlockSongs);
}
}
// Apply common config patch
WRITE_MEMORY (ASLR (0x140494533), i32, xRes);
WRITE_MEMORY (ASLR (0x14049453A), i32, yRes);
if (!vsync) WRITE_MEMORY (ASLR (0x14064C7E9), u8, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x90);
if (unlockSongs) WRITE_MEMORY (ASLR (0x1403F45CF), u8, 0xB0, 0x01);
// Apply common config patch
WRITE_MEMORY (ASLR (0x140494533), i32, xRes);
WRITE_MEMORY (ASLR (0x14049453A), i32, yRes);
if (!vsync) WRITE_MEMORY (ASLR (0x14064C7E9), u8, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x90);
if (unlockSongs) WRITE_MEMORY (ASLR (0x1403F45CF), u8, 0xB0, 0x01);
// Bypass errors
WRITE_MEMORY (ASLR (0x140041A00), u8, 0xC3);
// Bypass errors
WRITE_MEMORY (ASLR (0x140041A00), u8, 0xC3);
// Use TLS v1.2
WRITE_MEMORY (ASLR (0x140580459), u8, 0x10);
// Use TLS v1.2
WRITE_MEMORY (ASLR (0x140580459), u8, 0x10);
// Disable F/G check
WRITE_MEMORY (ASLR (0x140CD4858), char, "./");
// Disable F/G check
WRITE_MEMORY (ASLR (0x140CD4858), char, "./");
// Move various files to current directory
WRITE_MEMORY (ASLR (0x140C8AB60), char, "./");
WRITE_MEMORY (ASLR (0x140C8AB5C), char, "./");
WRITE_MEMORY (ASLR (0x140CD4DC0), char, ".\\Setting1.bin");
WRITE_MEMORY (ASLR (0x140CD4DB0), char, ".\\Setting2.bin");
WRITE_MEMORY (ASLR (0x140C95B40), char, ".\\TournamentData\\PlayData\\TournamentPlayData.dat");
WRITE_MEMORY (ASLR (0x140C95BB0), char, ".\\TournamentData\\InfoData\\TournamentInfoData.dat");
WRITE_MEMORY (ASLR (0x140CC0508), char, ".\\Garmc\\BillingData\\GarmcBillingData.dat");
WRITE_MEMORY (ASLR (0x140CC0660), char, ".\\Garmc\\BillingData\\GarmcOBillingData.dat");
WRITE_MEMORY (ASLR (0x140CC05E0), char, ".\\Garmc\\BillingNetIdLocationId\\GarmcBillingNetIdLocationId.dat");
WRITE_MEMORY (ASLR (0x140CC0830), char, ".\\Garmc\\BillingNetIdLocationId\\GarmcOBillingNetIdLocationId.dat");
WRITE_MEMORY (ASLR (0x140CC06C0), char, ".\\Garmc\\ErrorLogData\\GarmcErrorLogData.dat");
WRITE_MEMORY (ASLR (0x140CC0580), char, ".\\Garmc\\ErrorLogData\\GarmcOErrorLogData.dat");
WRITE_MEMORY (ASLR (0x140C95B78), char, ".\\TournamentData\\PlayData\\TournamentPlayData.dat");
WRITE_MEMORY (ASLR (0x140C95BE8), char, ".\\TournamentData\\InfoData\\TournamentInfoData.dat");
WRITE_MEMORY (ASLR (0x140CC0538), char, ".\\Garmc\\BillingData\\GarmcBillingData.dat");
WRITE_MEMORY (ASLR (0x140CC0690), char, ".\\Garmc\\BillingData\\GarmcOBillingData.dat");
WRITE_MEMORY (ASLR (0x140CC0620), char, ".\\Garmc\\BillingNetIdLocationId\\GarmcBillingNetIdLocationId.dat");
WRITE_MEMORY (ASLR (0x140CC0880), char, ".\\Garmc\\BillingNetIdLocationId\\GarmcOBillingNetIdLocationId.dat");
WRITE_MEMORY (ASLR (0x140CC06F0), char, ".\\Garmc\\ErrorLogData\\GarmcErrorLogData.dat");
WRITE_MEMORY (ASLR (0x140CC05B0), char, ".\\Garmc\\ErrorLogData\\GarmcOErrorLogData.dat");
// Move various files to current directory
WRITE_MEMORY (ASLR (0x140C8AB60), char, "./");
WRITE_MEMORY (ASLR (0x140C8AB5C), char, "./");
WRITE_MEMORY (ASLR (0x140CD4DC0), char, ".\\Setting1.bin");
WRITE_MEMORY (ASLR (0x140CD4DB0), char, ".\\Setting2.bin");
WRITE_MEMORY (ASLR (0x140C95B40), char, ".\\TournamentData\\PlayData\\TournamentPlayData.dat");
WRITE_MEMORY (ASLR (0x140C95BB0), char, ".\\TournamentData\\InfoData\\TournamentInfoData.dat");
WRITE_MEMORY (ASLR (0x140CC0508), char, ".\\Garmc\\BillingData\\GarmcBillingData.dat");
WRITE_MEMORY (ASLR (0x140CC0660), char, ".\\Garmc\\BillingData\\GarmcOBillingData.dat");
WRITE_MEMORY (ASLR (0x140CC05E0), char, ".\\Garmc\\BillingNetIdLocationId\\GarmcBillingNetIdLocationId.dat");
WRITE_MEMORY (ASLR (0x140CC0830), char, ".\\Garmc\\BillingNetIdLocationId\\GarmcOBillingNetIdLocationId.dat");
WRITE_MEMORY (ASLR (0x140CC06C0), char, ".\\Garmc\\ErrorLogData\\GarmcErrorLogData.dat");
WRITE_MEMORY (ASLR (0x140CC0580), char, ".\\Garmc\\ErrorLogData\\GarmcOErrorLogData.dat");
WRITE_MEMORY (ASLR (0x140C95B78), char, ".\\TournamentData\\PlayData\\TournamentPlayData.dat");
WRITE_MEMORY (ASLR (0x140C95BE8), char, ".\\TournamentData\\InfoData\\TournamentInfoData.dat");
WRITE_MEMORY (ASLR (0x140CC0538), char, ".\\Garmc\\BillingData\\GarmcBillingData.dat");
WRITE_MEMORY (ASLR (0x140CC0690), char, ".\\Garmc\\BillingData\\GarmcOBillingData.dat");
WRITE_MEMORY (ASLR (0x140CC0620), char, ".\\Garmc\\BillingNetIdLocationId\\GarmcBillingNetIdLocationId.dat");
WRITE_MEMORY (ASLR (0x140CC0880), char, ".\\Garmc\\BillingNetIdLocationId\\GarmcOBillingNetIdLocationId.dat");
WRITE_MEMORY (ASLR (0x140CC06F0), char, ".\\Garmc\\ErrorLogData\\GarmcErrorLogData.dat");
WRITE_MEMORY (ASLR (0x140CC05B0), char, ".\\Garmc\\ErrorLogData\\GarmcOErrorLogData.dat");
// Remove datatable size limit
{
for (auto address : memsetSizeAddresses)
WRITE_MEMORY (ASLR (address) + 2, i32, datatableBufferSize);
// Remove datatable size limit
{
for (auto address : memsetSizeAddresses)
WRITE_MEMORY (ASLR (address) + 2, i32, datatableBufferSize);
auto bufferBase = MODULE_HANDLE - 0x03000000;
AllocateStaticBufferNear ((void *)bufferBase, datatableBufferSize, &datatableBuffer1);
bufferBase += datatableBufferSize;
AllocateStaticBufferNear ((void *)bufferBase, datatableBufferSize, &datatableBuffer2);
bufferBase += datatableBufferSize;
AllocateStaticBufferNear ((void *)bufferBase, datatableBufferSize, &datatableBuffer3);
auto bufferBase = MODULE_HANDLE - 0x03000000;
AllocateStaticBufferNear ((void *)bufferBase, datatableBufferSize, &datatableBuffer1);
bufferBase += datatableBufferSize;
AllocateStaticBufferNear ((void *)bufferBase, datatableBufferSize, &datatableBuffer2);
bufferBase += datatableBufferSize;
AllocateStaticBufferNear ((void *)bufferBase, datatableBufferSize, &datatableBuffer3);
ReplaceLeaBufferAddress (datatableBuffer1Addresses, datatableBuffer1.data ());
ReplaceLeaBufferAddress (datatableBuffer2Addresses, datatableBuffer2.data ());
ReplaceLeaBufferAddress (datatableBuffer3Addresses, datatableBuffer3.data ());
}
ReplaceLeaBufferAddress (datatableBuffer1Addresses, datatableBuffer1.data ());
ReplaceLeaBufferAddress (datatableBuffer2Addresses, datatableBuffer2.data ());
ReplaceLeaBufferAddress (datatableBuffer3Addresses, datatableBuffer3.data ());
}
// Disable live check
auto amHandle = (u64)GetModuleHandle ("AMFrameWork.dll");
INSTALL_HOOK_DYNAMIC (AMFWTerminate, (void *)(amHandle + 0x42DE0));
// Disable live check
auto amHandle = (u64)GetModuleHandle ("AMFrameWork.dll");
INSTALL_HOOK_DYNAMIC (AMFWTerminate, (void *)(amHandle + 0x42DE0));
// Move various files to current directory
WRITE_MEMORY (amHandle + 0x15252, u8, 0xEB); // CreditLogPathA
WRITE_MEMORY (amHandle + 0x15419, u8, 0xEB); // CreditLogPathB
WRITE_MEMORY (amHandle + 0x416DA, u8, 0xEB); // ErrorLogPathA
WRITE_MEMORY (amHandle + 0x41859, u8, 0xEB); // ErrorLogPathB
WRITE_MEMORY (amHandle + 0x41C21, u8, 0xEB); // CommonLogPathA
WRITE_MEMORY (amHandle + 0x41DA5, u8, 0xEB); // CommonLogPathB
WRITE_MEMORY (amHandle + 0x420F1, u8, 0x90, 0x90, 0x90, 0x90, 0x90); // BackupDataPathA
WRITE_MEMORY (amHandle + 0x42167, u8, 0x90, 0x90, 0x90, 0x90, 0x90); // BackupDataPathB
// Move various files to current directory
WRITE_MEMORY (amHandle + 0x15252, u8, 0xEB); // CreditLogPathA
WRITE_MEMORY (amHandle + 0x15419, u8, 0xEB); // CreditLogPathB
WRITE_MEMORY (amHandle + 0x416DA, u8, 0xEB); // ErrorLogPathA
WRITE_MEMORY (amHandle + 0x41859, u8, 0xEB); // ErrorLogPathB
WRITE_MEMORY (amHandle + 0x41C21, u8, 0xEB); // CommonLogPathA
WRITE_MEMORY (amHandle + 0x41DA5, u8, 0xEB); // CommonLogPathB
WRITE_MEMORY (amHandle + 0x420F1, u8, 0x90, 0x90, 0x90, 0x90, 0x90); // BackupDataPathA
WRITE_MEMORY (amHandle + 0x42167, u8, 0x90, 0x90, 0x90, 0x90, 0x90); // BackupDataPathB
// Redirect garmc requests
auto garmcHandle = (u64)GetModuleHandle ("garmc.dll");
INSTALL_HOOK_DYNAMIC (curl_easy_setopt, (void *)(garmcHandle + 0x1FBBB0));
// Redirect garmc requests
auto garmcHandle = (u64)GetModuleHandle ("garmc.dll");
INSTALL_HOOK_DYNAMIC (curl_easy_setopt, (void *)(garmcHandle + 0x1FBBB0));
patches::Audio::Init ();
patches::Qr::Init ();
patches::AmAuth::Init ();
patches::Audio::Init ();
patches::Qr::Init ();
patches::AmAuth::Init ();
}
} // namespace patches::JPN39
+290 -287
View File
@@ -3,8 +3,8 @@
#include <windows.h>
struct {
const char *string;
uint8_t keycode;
const char *string;
uint8_t keycode;
} ConfigKeyboardButtons[] = {
// 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
@@ -130,8 +130,8 @@ struct {
};
struct {
const char *string;
SDL_GameControllerButton button;
const char *string;
SDL_GameControllerButton button;
} ConfigControllerButtons[] = {
{"SDL_A", SDL_CONTROLLER_BUTTON_A},
{"SDL_B", SDL_CONTROLLER_BUTTON_B},
@@ -157,27 +157,28 @@ struct {
};
struct {
const char *string;
SDLAxis axis;
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},
{"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;
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;
POINT Position;
POINT RelativePosition;
bool ScrolledUp;
bool ScrolledDown;
} currentMouseState, lastMouseState;
bool currentKeyboardState[0xFF];
@@ -193,297 +194,299 @@ SDL_GameController *controllers[255];
void
SetConfigValue (toml_table_t *table, const char *key, Keybindings *keybind) {
toml_array_t *array = toml_array_in (table, key);
if (!array) {
printWarning ("%s (%s): Cannot find array\n", __func__, key);
return;
}
toml_array_t *array = toml_array_in (table, key);
if (!array) {
printWarning ("%s (%s): Cannot find array\n", __func__, key);
return;
}
memset (keybind, 0, sizeof (*keybind));
for (size_t i = 0; i < COUNTOFARR (keybind->buttons); i++)
keybind->buttons[i] = SDL_CONTROLLER_BUTTON_INVALID;
memset (keybind, 0, sizeof (*keybind));
for (size_t i = 0; i < COUNTOFARR (keybind->buttons); i++)
keybind->buttons[i] = SDL_CONTROLLER_BUTTON_INVALID;
for (size_t i = 0;; i++) {
toml_datum_t bind = toml_string_at (array, i);
if (!bind.ok) break;
ConfigValue value = StringToConfigEnum (bind.u.s);
free (bind.u.s);
for (size_t i = 0;; i++) {
toml_datum_t bind = toml_string_at (array, i);
if (!bind.ok) break;
ConfigValue value = StringToConfigEnum (bind.u.s);
free (bind.u.s);
switch (value.type) {
case keycode:
for (size_t i = 0; i < COUNTOFARR (keybind->keycodes); i++) {
if (keybind->keycodes[i] == 0) {
keybind->keycodes[i] = value.keycode;
break;
}
}
break;
case button:
for (size_t i = 0; i < COUNTOFARR (keybind->buttons); i++) {
if (keybind->buttons[i] == SDL_CONTROLLER_BUTTON_INVALID) {
keybind->buttons[i] = value.button;
break;
}
}
break;
case axis:
for (size_t i = 0; i < COUNTOFARR (keybind->axis); i++) {
if (keybind->axis[i] == 0) {
keybind->axis[i] = value.axis;
break;
}
}
case scroll:
for (size_t i = 0; i < COUNTOFARR (keybind->scroll); i++) {
if (keybind->scroll[i] == 0) {
keybind->scroll[i] = value.scroll;
break;
}
}
break;
default: break;
}
}
switch (value.type) {
case keycode:
for (size_t i = 0; i < COUNTOFARR (keybind->keycodes); i++) {
if (keybind->keycodes[i] == 0) {
keybind->keycodes[i] = value.keycode;
break;
}
}
break;
case button:
for (size_t i = 0; i < COUNTOFARR (keybind->buttons); i++) {
if (keybind->buttons[i] == SDL_CONTROLLER_BUTTON_INVALID) {
keybind->buttons[i] = value.button;
break;
}
}
break;
case axis:
for (size_t i = 0; i < COUNTOFARR (keybind->axis); i++) {
if (keybind->axis[i] == 0) {
keybind->axis[i] = value.axis;
break;
}
}
case scroll:
for (size_t i = 0; i < COUNTOFARR (keybind->scroll); i++) {
if (keybind->scroll[i] == 0) {
keybind->scroll[i] = value.scroll;
break;
}
}
break;
default: break;
}
}
}
bool
InitializePoll (HWND windowHandle) {
bool hasRumble = true;
SDL_SetMainReady ();
bool hasRumble = true;
SDL_SetMainReady ();
SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_PS4, "1");
SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, "1");
SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_PS5, "1");
SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1");
SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_PS4, "1");
SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, "1");
SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_PS5, "1");
SDL_SetHint (SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1");
if (SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS | SDL_INIT_VIDEO) != 0) {
if (SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS | SDL_INIT_VIDEO) == 0) {
hasRumble = false;
} else {
printError ("SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS | SDL_INIT_VIDEO): "
"%s\n",
SDL_GetError ());
return false;
}
}
if (SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS | SDL_INIT_VIDEO) != 0) {
if (SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS | SDL_INIT_VIDEO) == 0) {
hasRumble = false;
} else {
printError ("SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS | SDL_INIT_VIDEO): "
"%s\n",
SDL_GetError ());
return false;
}
}
auto configPath = std::filesystem::current_path () / "gamecontrollerdb.txt";
if (SDL_GameControllerAddMappingsFromFile (configPath.string ().c_str ()) == -1) printError ("%s (): Cannot read gamecontrollerdb.txt\n", __func__);
SDL_GameControllerEventState (SDL_ENABLE);
SDL_JoystickEventState (SDL_ENABLE);
auto configPath = std::filesystem::current_path () / "gamecontrollerdb.txt";
if (SDL_GameControllerAddMappingsFromFile (configPath.string ().c_str ()) == -1)
printError ("%s (): Cannot read gamecontrollerdb.txt\n", __func__);
SDL_GameControllerEventState (SDL_ENABLE);
SDL_JoystickEventState (SDL_ENABLE);
for (int i = 0; i < SDL_NumJoysticks (); i++) {
if (!SDL_IsGameController (i)) continue;
for (int i = 0; i < SDL_NumJoysticks (); i++) {
if (!SDL_IsGameController (i)) continue;
SDL_GameController *controller = SDL_GameControllerOpen (i);
if (!controller) {
printWarning ("Could not open gamecontroller %s: %s\n", SDL_GameControllerNameForIndex (i), SDL_GetError ());
continue;
}
controllers[i] = controller;
}
SDL_GameController *controller = SDL_GameControllerOpen (i);
if (!controller) {
printWarning ("Could not open gamecontroller %s: %s\n", SDL_GameControllerNameForIndex (i), SDL_GetError ());
continue;
}
controllers[i] = controller;
}
window = SDL_CreateWindowFrom (windowHandle);
if (window == NULL) printError ("SDL_CreateWindowFrom (windowHandle): %s\n", SDL_GetError ());
window = SDL_CreateWindowFrom (windowHandle);
if (window == NULL) printError ("SDL_CreateWindowFrom (windowHandle): %s\n", SDL_GetError ());
atexit (DisposePoll);
atexit (DisposePoll);
return hasRumble;
return hasRumble;
}
void
UpdatePoll (HWND windowHandle) {
if (windowHandle == NULL || GetForegroundWindow () != windowHandle) return;
if (windowHandle == NULL || GetForegroundWindow () != windowHandle) return;
memcpy (lastKeyboardState, currentKeyboardState, 255);
memcpy (lastControllerButtonsState, currentControllerButtonsState, 21);
lastMouseState = currentMouseState;
lastControllerAxisState = currentControllerAxisState;
memcpy (lastKeyboardState, currentKeyboardState, 255);
memcpy (lastControllerButtonsState, currentControllerButtonsState, 21);
lastMouseState = currentMouseState;
lastControllerAxisState = currentControllerAxisState;
for (uint8_t i = 0; i < 0xFF; i++)
currentKeyboardState[i] = GetAsyncKeyState (i) != 0;
for (uint8_t i = 0; i < 0xFF; i++)
currentKeyboardState[i] = GetAsyncKeyState (i) != 0;
currentMouseState.ScrolledUp = false;
currentMouseState.ScrolledDown = false;
currentMouseState.ScrolledUp = false;
currentMouseState.ScrolledDown = false;
GetCursorPos (&currentMouseState.Position);
ScreenToClient (windowHandle, &currentMouseState.Position);
GetCursorPos (&currentMouseState.Position);
ScreenToClient (windowHandle, &currentMouseState.Position);
SDL_Event event;
SDL_GameController *controller;
while (SDL_PollEvent (&event) != 0) {
switch (event.type) {
case SDL_CONTROLLERDEVICEADDED:
if (!SDL_IsGameController (event.cdevice.which)) break;
SDL_Event event;
SDL_GameController *controller;
while (SDL_PollEvent (&event) != 0) {
switch (event.type) {
case SDL_CONTROLLERDEVICEADDED:
if (!SDL_IsGameController (event.cdevice.which)) break;
controller = SDL_GameControllerOpen (event.cdevice.which);
if (!controller) {
printError ("%s (): Could not open gamecontroller %s: %s\n", __func__, SDL_GameControllerNameForIndex (event.cdevice.which), SDL_GetError ());
continue;
}
controllers[event.cdevice.which] = controller;
break;
case SDL_CONTROLLERDEVICEREMOVED:
if (!SDL_IsGameController (event.cdevice.which)) break;
SDL_GameControllerClose (controllers[event.cdevice.which]);
break;
case SDL_MOUSEWHEEL:
if (event.wheel.y > 0) currentMouseState.ScrolledUp = true;
else if (event.wheel.y < 0) currentMouseState.ScrolledDown = true;
break;
case SDL_CONTROLLERBUTTONUP:
case SDL_CONTROLLERBUTTONDOWN: currentControllerButtonsState[event.cbutton.button] = event.cbutton.state; break;
case SDL_CONTROLLERAXISMOTION:
if (event.caxis.value > 1) {
switch (event.caxis.axis) {
case SDL_CONTROLLER_AXIS_LEFTX: currentControllerAxisState.LeftRight = (float)event.caxis.value / 32767; break;
case SDL_CONTROLLER_AXIS_LEFTY: currentControllerAxisState.LeftDown = (float)event.caxis.value / 32767; break;
case SDL_CONTROLLER_AXIS_RIGHTX: currentControllerAxisState.RightRight = (float)event.caxis.value / 32767; break;
case SDL_CONTROLLER_AXIS_RIGHTY: currentControllerAxisState.RightDown = (float)event.caxis.value / 32767; break;
case SDL_CONTROLLER_AXIS_TRIGGERLEFT: currentControllerAxisState.LTriggerDown = (float)event.caxis.value / 32767; break;
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: currentControllerAxisState.RTriggerDown = (float)event.caxis.value / 32767; break;
}
} else if (event.caxis.value < -1) {
switch (event.caxis.axis) {
case SDL_CONTROLLER_AXIS_LEFTX: currentControllerAxisState.LeftLeft = (float)event.caxis.value / -32768; break;
case SDL_CONTROLLER_AXIS_LEFTY: currentControllerAxisState.LeftUp = (float)event.caxis.value / -32768; break;
case SDL_CONTROLLER_AXIS_RIGHTX: currentControllerAxisState.RightLeft = (float)event.caxis.value / -32768; break;
case SDL_CONTROLLER_AXIS_RIGHTY: currentControllerAxisState.RightUp = (float)event.caxis.value / -32768; break;
}
} else {
switch (event.caxis.axis) {
case SDL_CONTROLLER_AXIS_LEFTX:
currentControllerAxisState.LeftRight = 0;
currentControllerAxisState.LeftLeft = 0;
break;
case SDL_CONTROLLER_AXIS_LEFTY:
currentControllerAxisState.LeftDown = 0;
currentControllerAxisState.LeftUp = 0;
break;
case SDL_CONTROLLER_AXIS_RIGHTX:
currentControllerAxisState.RightRight = 0;
currentControllerAxisState.RightLeft = 0;
break;
case SDL_CONTROLLER_AXIS_RIGHTY:
currentControllerAxisState.RightDown = 0;
currentControllerAxisState.RightUp = 0;
break;
case SDL_CONTROLLER_AXIS_TRIGGERLEFT: currentControllerAxisState.LTriggerDown = 0; break;
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: currentControllerAxisState.RTriggerDown = 0; break;
}
}
break;
}
}
controller = SDL_GameControllerOpen (event.cdevice.which);
if (!controller) {
printError ("%s (): Could not open gamecontroller %s: %s\n", __func__, SDL_GameControllerNameForIndex (event.cdevice.which),
SDL_GetError ());
continue;
}
controllers[event.cdevice.which] = controller;
break;
case SDL_CONTROLLERDEVICEREMOVED:
if (!SDL_IsGameController (event.cdevice.which)) break;
SDL_GameControllerClose (controllers[event.cdevice.which]);
break;
case SDL_MOUSEWHEEL:
if (event.wheel.y > 0) currentMouseState.ScrolledUp = true;
else if (event.wheel.y < 0) currentMouseState.ScrolledDown = true;
break;
case SDL_CONTROLLERBUTTONUP:
case SDL_CONTROLLERBUTTONDOWN: currentControllerButtonsState[event.cbutton.button] = event.cbutton.state; break;
case SDL_CONTROLLERAXISMOTION:
if (event.caxis.value > 1) {
switch (event.caxis.axis) {
case SDL_CONTROLLER_AXIS_LEFTX: currentControllerAxisState.LeftRight = (float)event.caxis.value / 32767; break;
case SDL_CONTROLLER_AXIS_LEFTY: currentControllerAxisState.LeftDown = (float)event.caxis.value / 32767; break;
case SDL_CONTROLLER_AXIS_RIGHTX: currentControllerAxisState.RightRight = (float)event.caxis.value / 32767; break;
case SDL_CONTROLLER_AXIS_RIGHTY: currentControllerAxisState.RightDown = (float)event.caxis.value / 32767; break;
case SDL_CONTROLLER_AXIS_TRIGGERLEFT: currentControllerAxisState.LTriggerDown = (float)event.caxis.value / 32767; break;
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: currentControllerAxisState.RTriggerDown = (float)event.caxis.value / 32767; break;
}
} else if (event.caxis.value < -1) {
switch (event.caxis.axis) {
case SDL_CONTROLLER_AXIS_LEFTX: currentControllerAxisState.LeftLeft = (float)event.caxis.value / -32768; break;
case SDL_CONTROLLER_AXIS_LEFTY: currentControllerAxisState.LeftUp = (float)event.caxis.value / -32768; break;
case SDL_CONTROLLER_AXIS_RIGHTX: currentControllerAxisState.RightLeft = (float)event.caxis.value / -32768; break;
case SDL_CONTROLLER_AXIS_RIGHTY: currentControllerAxisState.RightUp = (float)event.caxis.value / -32768; break;
}
} else {
switch (event.caxis.axis) {
case SDL_CONTROLLER_AXIS_LEFTX:
currentControllerAxisState.LeftRight = 0;
currentControllerAxisState.LeftLeft = 0;
break;
case SDL_CONTROLLER_AXIS_LEFTY:
currentControllerAxisState.LeftDown = 0;
currentControllerAxisState.LeftUp = 0;
break;
case SDL_CONTROLLER_AXIS_RIGHTX:
currentControllerAxisState.RightRight = 0;
currentControllerAxisState.RightLeft = 0;
break;
case SDL_CONTROLLER_AXIS_RIGHTY:
currentControllerAxisState.RightDown = 0;
currentControllerAxisState.RightUp = 0;
break;
case SDL_CONTROLLER_AXIS_TRIGGERLEFT: currentControllerAxisState.LTriggerDown = 0; break;
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: currentControllerAxisState.RTriggerDown = 0; break;
}
}
break;
}
}
}
void
DisposePoll () {
SDL_DestroyWindow (window);
SDL_Quit ();
SDL_DestroyWindow (window);
SDL_Quit ();
}
ConfigValue
StringToConfigEnum (const char *value) {
ConfigValue rval;
for (size_t i = 0; i < COUNTOFARR (ConfigKeyboardButtons); ++i)
if (!strcmp (value, ConfigKeyboardButtons[i].string)) {
rval.type = keycode;
rval.keycode = ConfigKeyboardButtons[i].keycode;
return rval;
}
for (size_t i = 0; i < COUNTOFARR (ConfigControllerButtons); ++i)
if (!strcmp (value, ConfigControllerButtons[i].string)) {
rval.type = button;
rval.button = ConfigControllerButtons[i].button;
return rval;
}
for (size_t i = 0; i < COUNTOFARR (ConfigControllerAXIS); ++i)
if (!strcmp (value, ConfigControllerAXIS[i].string)) {
rval.type = axis;
rval.axis = ConfigControllerAXIS[i].axis;
return rval;
}
for (size_t i = 0; i < COUNTOFARR (ConfigMouseScroll); ++i)
if (!strcmp (value, ConfigMouseScroll[i].string)) {
rval.type = scroll;
rval.scroll = ConfigMouseScroll[i].scroll;
return rval;
}
ConfigValue rval;
for (size_t i = 0; i < COUNTOFARR (ConfigKeyboardButtons); ++i)
if (!strcmp (value, ConfigKeyboardButtons[i].string)) {
rval.type = keycode;
rval.keycode = ConfigKeyboardButtons[i].keycode;
return rval;
}
for (size_t i = 0; i < COUNTOFARR (ConfigControllerButtons); ++i)
if (!strcmp (value, ConfigControllerButtons[i].string)) {
rval.type = button;
rval.button = ConfigControllerButtons[i].button;
return rval;
}
for (size_t i = 0; i < COUNTOFARR (ConfigControllerAXIS); ++i)
if (!strcmp (value, ConfigControllerAXIS[i].string)) {
rval.type = axis;
rval.axis = ConfigControllerAXIS[i].axis;
return rval;
}
for (size_t i = 0; i < COUNTOFARR (ConfigMouseScroll); ++i)
if (!strcmp (value, ConfigMouseScroll[i].string)) {
rval.type = scroll;
rval.scroll = ConfigMouseScroll[i].scroll;
return rval;
}
printError ("%s (%s): Unknown value\n", __func__, value);
return rval;
printError ("%s (%s): Unknown value\n", __func__, value);
return rval;
}
InternalButtonState
GetInternalButtonState (Keybindings bindings) {
InternalButtonState buttons = {0};
InternalButtonState buttons = {0};
for (size_t i = 0; i < COUNTOFARR (ConfigKeyboardButtons); i++) {
if (bindings.keycodes[i] == 0) continue;
if (KeyboardIsReleased (bindings.keycodes[i])) buttons.Released = 1;
if (KeyboardIsDown (bindings.keycodes[i])) buttons.Down = 1;
if (KeyboardIsTapped (bindings.keycodes[i])) buttons.Tapped = 1;
}
for (size_t i = 0; i < COUNTOFARR (ConfigControllerButtons); i++) {
if (bindings.buttons[i] == SDL_CONTROLLER_BUTTON_INVALID) continue;
if (ControllerButtonIsReleased (bindings.buttons[i])) buttons.Released = 1;
if (ControllerButtonIsDown (bindings.buttons[i])) buttons.Down = 1;
if (ControllerButtonIsTapped (bindings.buttons[i])) buttons.Tapped = 1;
}
for (size_t i = 0; i < COUNTOFARR (ConfigControllerAXIS); i++) {
if (bindings.axis[i] == 0) continue;
if (float val = ControllerAxisIsReleased (bindings.axis[i])) buttons.Released = val;
if (float val = ControllerAxisIsDown (bindings.axis[i])) buttons.Down = val;
if (float val = ControllerAxisIsTapped (bindings.axis[i])) buttons.Tapped = val;
}
for (size_t i = 0; i < COUNTOFARR (ConfigMouseScroll); i++) {
if (bindings.scroll[i] == 0) continue;
if (GetMouseScrollIsReleased (bindings.scroll[i])) buttons.Released = 1;
if (GetMouseScrollIsDown (bindings.scroll[i])) buttons.Down = 1;
if (GetMouseScrollIsTapped (bindings.scroll[i])) buttons.Tapped = 1;
}
for (size_t i = 0; i < COUNTOFARR (ConfigKeyboardButtons); i++) {
if (bindings.keycodes[i] == 0) continue;
if (KeyboardIsReleased (bindings.keycodes[i])) buttons.Released = 1;
if (KeyboardIsDown (bindings.keycodes[i])) buttons.Down = 1;
if (KeyboardIsTapped (bindings.keycodes[i])) buttons.Tapped = 1;
}
for (size_t i = 0; i < COUNTOFARR (ConfigControllerButtons); i++) {
if (bindings.buttons[i] == SDL_CONTROLLER_BUTTON_INVALID) continue;
if (ControllerButtonIsReleased (bindings.buttons[i])) buttons.Released = 1;
if (ControllerButtonIsDown (bindings.buttons[i])) buttons.Down = 1;
if (ControllerButtonIsTapped (bindings.buttons[i])) buttons.Tapped = 1;
}
for (size_t i = 0; i < COUNTOFARR (ConfigControllerAXIS); i++) {
if (bindings.axis[i] == 0) continue;
if (float val = ControllerAxisIsReleased (bindings.axis[i])) buttons.Released = val;
if (float val = ControllerAxisIsDown (bindings.axis[i])) buttons.Down = val;
if (float val = ControllerAxisIsTapped (bindings.axis[i])) buttons.Tapped = val;
}
for (size_t i = 0; i < COUNTOFARR (ConfigMouseScroll); i++) {
if (bindings.scroll[i] == 0) continue;
if (GetMouseScrollIsReleased (bindings.scroll[i])) buttons.Released = 1;
if (GetMouseScrollIsDown (bindings.scroll[i])) buttons.Down = 1;
if (GetMouseScrollIsTapped (bindings.scroll[i])) buttons.Tapped = 1;
}
return buttons;
return buttons;
}
void
SetRumble (int left, int right, int length) {
for (size_t i = 0; i < COUNTOFARR (controllers); i++) {
if (!controllers[i] || !SDL_GameControllerHasRumble (controllers[i])) continue;
for (size_t i = 0; i < COUNTOFARR (controllers); i++) {
if (!controllers[i] || !SDL_GameControllerHasRumble (controllers[i])) continue;
SDL_GameControllerRumble (controllers[i], left, right, length);
}
SDL_GameControllerRumble (controllers[i], left, right, length);
}
}
bool
KeyboardIsDown (uint8_t keycode) {
return currentKeyboardState[keycode];
return currentKeyboardState[keycode];
}
bool
KeyboardIsUp (uint8_t keycode) {
return !KeyboardIsDown (keycode);
return !KeyboardIsDown (keycode);
}
bool
KeyboardIsTapped (uint8_t keycode) {
return KeyboardIsDown (keycode) && KeyboardWasUp (keycode);
return KeyboardIsDown (keycode) && KeyboardWasUp (keycode);
}
bool
KeyboardIsReleased (uint8_t keycode) {
return KeyboardIsUp (keycode) && KeyboardWasDown (keycode);
return KeyboardIsUp (keycode) && KeyboardWasDown (keycode);
}
bool
KeyboardWasDown (uint8_t keycode) {
return lastKeyboardState[keycode];
return lastKeyboardState[keycode];
}
bool
KeyboardWasUp (uint8_t keycode) {
return !KeyboardWasDown (keycode);
return !KeyboardWasDown (keycode);
}
POINT
@@ -500,142 +503,142 @@ GetLastMouseRelativePosition () { return lastMouseState.RelativePosition; }
void
SetMousePosition (POINT newPosition) {
currentMouseState.Position = newPosition;
currentMouseState.Position = newPosition;
}
bool
GetMouseScrollUp () {
return currentMouseState.ScrolledUp;
return currentMouseState.ScrolledUp;
}
bool
GetMouseScrollDown () {
return currentMouseState.ScrolledDown;
return currentMouseState.ScrolledDown;
}
bool
GetWasMouseScrollUp () {
return lastMouseState.ScrolledUp;
return lastMouseState.ScrolledUp;
}
bool
GetWasMouseScrollDown () {
return lastMouseState.ScrolledDown;
return lastMouseState.ScrolledDown;
}
bool
GetMouseScrollIsReleased (Scroll scroll) {
if (scroll == MOUSE_SCROLL_UP) return !GetMouseScrollUp () && GetWasMouseScrollUp ();
else return !GetMouseScrollDown () && GetWasMouseScrollDown ();
if (scroll == MOUSE_SCROLL_UP) return !GetMouseScrollUp () && GetWasMouseScrollUp ();
else return !GetMouseScrollDown () && GetWasMouseScrollDown ();
}
bool
GetMouseScrollIsDown (Scroll scroll) {
if (scroll == MOUSE_SCROLL_UP) return GetMouseScrollUp ();
else return GetMouseScrollDown ();
if (scroll == MOUSE_SCROLL_UP) return GetMouseScrollUp ();
else return GetMouseScrollDown ();
}
bool
GetMouseScrollIsTapped (Scroll scroll) {
if (scroll == MOUSE_SCROLL_UP) return GetMouseScrollUp () && !GetWasMouseScrollUp ();
else return GetMouseScrollDown () && !GetWasMouseScrollDown ();
if (scroll == MOUSE_SCROLL_UP) return GetMouseScrollUp () && !GetWasMouseScrollUp ();
else return GetMouseScrollDown () && !GetWasMouseScrollDown ();
}
bool
ControllerButtonIsDown (SDL_GameControllerButton button) {
return currentControllerButtonsState[button];
return currentControllerButtonsState[button];
}
bool
ControllerButtonIsUp (SDL_GameControllerButton button) {
return !ControllerButtonIsDown (button);
return !ControllerButtonIsDown (button);
}
bool
ControllerButtonWasDown (SDL_GameControllerButton button) {
return lastControllerButtonsState[button];
return lastControllerButtonsState[button];
}
bool
ControllerButtonWasUp (SDL_GameControllerButton button) {
return !ControllerButtonWasDown (button);
return !ControllerButtonWasDown (button);
}
bool
ControllerButtonIsTapped (SDL_GameControllerButton button) {
return ControllerButtonIsDown (button) && ControllerButtonWasUp (button);
return ControllerButtonIsDown (button) && ControllerButtonWasUp (button);
}
bool
ControllerButtonIsReleased (SDL_GameControllerButton button) {
return ControllerButtonIsUp (button) && ControllerButtonWasDown (button);
return ControllerButtonIsUp (button) && ControllerButtonWasDown (button);
}
float
ControllerAxisIsDown (SDLAxis axis) {
switch (axis) {
case SDL_AXIS_LEFT_LEFT: return currentControllerAxisState.LeftLeft;
case SDL_AXIS_LEFT_RIGHT: return currentControllerAxisState.LeftRight;
case SDL_AXIS_LEFT_UP: return currentControllerAxisState.LeftUp;
case SDL_AXIS_LEFT_DOWN: return currentControllerAxisState.LeftDown;
case SDL_AXIS_RIGHT_LEFT: return currentControllerAxisState.RightLeft;
case SDL_AXIS_RIGHT_RIGHT: return currentControllerAxisState.RightRight;
case SDL_AXIS_RIGHT_UP: return currentControllerAxisState.RightUp;
case SDL_AXIS_RIGHT_DOWN: return currentControllerAxisState.RightDown;
case SDL_AXIS_LTRIGGER_DOWN: return currentControllerAxisState.LTriggerDown;
case SDL_AXIS_RTRIGGER_DOWN: return currentControllerAxisState.RTriggerDown;
default: return false;
}
switch (axis) {
case SDL_AXIS_LEFT_LEFT: return currentControllerAxisState.LeftLeft;
case SDL_AXIS_LEFT_RIGHT: return currentControllerAxisState.LeftRight;
case SDL_AXIS_LEFT_UP: return currentControllerAxisState.LeftUp;
case SDL_AXIS_LEFT_DOWN: return currentControllerAxisState.LeftDown;
case SDL_AXIS_RIGHT_LEFT: return currentControllerAxisState.RightLeft;
case SDL_AXIS_RIGHT_RIGHT: return currentControllerAxisState.RightRight;
case SDL_AXIS_RIGHT_UP: return currentControllerAxisState.RightUp;
case SDL_AXIS_RIGHT_DOWN: return currentControllerAxisState.RightDown;
case SDL_AXIS_LTRIGGER_DOWN: return currentControllerAxisState.LTriggerDown;
case SDL_AXIS_RTRIGGER_DOWN: return currentControllerAxisState.RTriggerDown;
default: return false;
}
}
bool
ControllerAxisIsUp (SDLAxis axis) {
return !ControllerAxisIsDown (axis);
return !ControllerAxisIsDown (axis);
}
float
ControllerAxisWasDown (SDLAxis axis) {
switch (axis) {
case SDL_AXIS_LEFT_LEFT: return lastControllerAxisState.LeftLeft;
case SDL_AXIS_LEFT_RIGHT: return lastControllerAxisState.LeftRight;
case SDL_AXIS_LEFT_UP: return lastControllerAxisState.LeftUp;
case SDL_AXIS_LEFT_DOWN: return lastControllerAxisState.LeftDown;
case SDL_AXIS_RIGHT_LEFT: return lastControllerAxisState.RightLeft;
case SDL_AXIS_RIGHT_RIGHT: return lastControllerAxisState.RightRight;
case SDL_AXIS_RIGHT_UP: return lastControllerAxisState.RightUp;
case SDL_AXIS_RIGHT_DOWN: return lastControllerAxisState.RightDown;
case SDL_AXIS_LTRIGGER_DOWN: return lastControllerAxisState.LTriggerDown;
case SDL_AXIS_RTRIGGER_DOWN: return lastControllerAxisState.RTriggerDown;
default: return false;
}
switch (axis) {
case SDL_AXIS_LEFT_LEFT: return lastControllerAxisState.LeftLeft;
case SDL_AXIS_LEFT_RIGHT: return lastControllerAxisState.LeftRight;
case SDL_AXIS_LEFT_UP: return lastControllerAxisState.LeftUp;
case SDL_AXIS_LEFT_DOWN: return lastControllerAxisState.LeftDown;
case SDL_AXIS_RIGHT_LEFT: return lastControllerAxisState.RightLeft;
case SDL_AXIS_RIGHT_RIGHT: return lastControllerAxisState.RightRight;
case SDL_AXIS_RIGHT_UP: return lastControllerAxisState.RightUp;
case SDL_AXIS_RIGHT_DOWN: return lastControllerAxisState.RightDown;
case SDL_AXIS_LTRIGGER_DOWN: return lastControllerAxisState.LTriggerDown;
case SDL_AXIS_RTRIGGER_DOWN: return lastControllerAxisState.RTriggerDown;
default: return false;
}
}
bool
ControllerAxisWasUp (SDLAxis axis) {
return !ControllerAxisWasDown (axis);
return !ControllerAxisWasDown (axis);
}
bool
ControllerAxisIsTapped (SDLAxis axis) {
return ControllerAxisIsDown (axis) && ControllerAxisWasUp (axis);
return ControllerAxisIsDown (axis) && ControllerAxisWasUp (axis);
}
bool
ControllerAxisIsReleased (SDLAxis axis) {
return ControllerAxisIsUp (axis) && ControllerAxisWasDown (axis);
return ControllerAxisIsUp (axis) && ControllerAxisWasDown (axis);
}
bool
IsButtonTapped (Keybindings bindings) {
return GetInternalButtonState (bindings).Tapped;
return GetInternalButtonState (bindings).Tapped;
}
bool
IsButtonReleased (Keybindings bindings) {
return GetInternalButtonState (bindings).Released;
return GetInternalButtonState (bindings).Released;
}
float
IsButtonDown (Keybindings bindings) {
return GetInternalButtonState (bindings).Down;
return GetInternalButtonState (bindings).Down;
}
+36 -36
View File
@@ -6,58 +6,58 @@
#include <windows.h>
enum SDLAxis {
SDL_AXIS_NULL,
SDL_AXIS_LEFT_LEFT,
SDL_AXIS_LEFT_RIGHT,
SDL_AXIS_LEFT_UP,
SDL_AXIS_LEFT_DOWN,
SDL_AXIS_RIGHT_LEFT,
SDL_AXIS_RIGHT_RIGHT,
SDL_AXIS_RIGHT_UP,
SDL_AXIS_RIGHT_DOWN,
SDL_AXIS_LTRIGGER_DOWN,
SDL_AXIS_RTRIGGER_DOWN,
SDL_AXIS_MAX
SDL_AXIS_NULL,
SDL_AXIS_LEFT_LEFT,
SDL_AXIS_LEFT_RIGHT,
SDL_AXIS_LEFT_UP,
SDL_AXIS_LEFT_DOWN,
SDL_AXIS_RIGHT_LEFT,
SDL_AXIS_RIGHT_RIGHT,
SDL_AXIS_RIGHT_UP,
SDL_AXIS_RIGHT_DOWN,
SDL_AXIS_LTRIGGER_DOWN,
SDL_AXIS_RTRIGGER_DOWN,
SDL_AXIS_MAX
};
struct SDLAxisState {
float LeftLeft;
float LeftRight;
float LeftUp;
float LeftDown;
float RightLeft;
float RightRight;
float RightUp;
float RightDown;
float LTriggerDown;
float RTriggerDown;
float LeftLeft;
float LeftRight;
float LeftUp;
float LeftDown;
float RightLeft;
float RightRight;
float RightUp;
float RightDown;
float LTriggerDown;
float RTriggerDown;
};
enum Scroll { MOUSE_SCROLL_INVALID, MOUSE_SCROLL_UP, MOUSE_SCROLL_DOWN };
struct Keybindings {
uint8_t keycodes[255];
SDL_GameControllerButton buttons[255];
SDLAxis axis[255];
Scroll scroll[2];
uint8_t keycodes[255];
SDL_GameControllerButton buttons[255];
SDLAxis axis[255];
Scroll scroll[2];
};
enum EnumType { none, keycode, button, axis, scroll };
struct ConfigValue {
EnumType type;
union {
uint8_t keycode;
SDL_GameControllerButton button;
SDLAxis axis;
Scroll scroll;
};
EnumType type;
union {
uint8_t keycode;
SDL_GameControllerButton button;
SDLAxis axis;
Scroll scroll;
};
};
struct InternalButtonState {
float Down;
bool Released;
bool Tapped;
float Down;
bool Released;
bool Tapped;
};
bool InitializePoll (HWND windowHandle);