mirror of
https://github.com/esuo1198/TaikoArcadeLoader.git
synced 2026-10-05 21:27:55 +03:00
Change clang-format settings and format all codes
This commit is contained in:
+4
-3
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 §ionName) {
|
||||
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 ¬FoundValue) {
|
||||
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
@@ -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
File diff suppressed because it is too large
Load Diff
+54
-54
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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 (¤tMouseState.Position);
|
||||
ScreenToClient (windowHandle, ¤tMouseState.Position);
|
||||
GetCursorPos (¤tMouseState.Position);
|
||||
ScreenToClient (windowHandle, ¤tMouseState.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
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user