From 28bd3fa97aded3a948ed8b55e7c5d06d6265ebc5 Mon Sep 17 00:00:00 2001 From: nastys <> Date: Thu, 12 Mar 2020 20:56:45 +0100 Subject: [PATCH] Add Force TEST_MODE --- m39ol.files | 2 ++ source/constants.h | 8 ++---- source/main.cpp | 67 +++++++++++++++++++++++++++++--------------- source/mini-tlac.cpp | 26 +++++++++++++++++ source/mini-tlac.h | 15 ++++++++++ 5 files changed, 90 insertions(+), 28 deletions(-) create mode 100644 source/mini-tlac.cpp create mode 100644 source/mini-tlac.h diff --git a/m39ol.files b/m39ol.files index 4eb846e..a0f6f45 100644 --- a/m39ol.files +++ b/m39ol.files @@ -331,4 +331,6 @@ libs/libtesla/resources/ovl_cheats.jpg libs/libtesla/resources/ovl_stats.jpg source/constants.h source/main.cpp +source/mini-tlac.cpp +source/mini-tlac.h source/structs.h diff --git a/source/constants.h b/source/constants.h index 161074f..354ccd8 100644 --- a/source/constants.h +++ b/source/constants.h @@ -3,6 +3,8 @@ #include #include "structs.h" +#define GAME_TITLE_ID 0x100F3100DA46000 + // Disable NPR #define ADD_PARAM_OFFSET 0x99BA41 const std::string add_param_redirect="adp_force"; @@ -49,10 +51,4 @@ const unsigned char mouse_map_disabled[]={0x04, 0x00, 0x00, 0x14};*/ const unsigned char recording_enabled[]={0x1F, 0x20, 0x03, 0xD5}; const unsigned char recording_disabled[]={0x41, 0x00, 0x00, 0x36}; -#define FN_DONOR_OFFSET 0x1CB830 -const unsigned char fn_donor_original[]={0x3F, 0x44, 0x00, 0x71, 0x88, 0x00, 0x00, 0x54}; -#define FN_CHANGE_SUB_MODE_ADDRESS 0x71001E3980 -#define FN_CHANGE_SUB_MODE_OFFSET 0x1E3980 -const unsigned char fn_donor_b_change_sub_mode[]={0x54, 0x60, 0x00, 0x14, 0xC0, 0x03, 0x5F, 0xD6}; // b? bl? - #endif // CONSTANTS_H diff --git a/source/main.cpp b/source/main.cpp index e42d295..befaf95 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -3,6 +3,7 @@ #include #include #include "constants.h" +#include "mini-tlac.h" static DmntCheatProcessMetadata metadata; static bool initialized=false; @@ -14,6 +15,12 @@ static bool debug_mode_enabled=false; static bool dpad_cursor=false; static float opacity=1.0f; +void force_test_mode(bool state) +{ + if(state) MINITLAC_injectGameSubState(metadata.main_nso_extents.base, 4, 29); + else MINITLAC_restoreGameSubState(metadata.main_nso_extents.base); +} + bool VPincrease(u64 button) { if(button==KEY_A||button==KEY_DRIGHT||button==KEY_LSTICK_RIGHT||button==KEY_RSTICK_RIGHT||button==KEY_X||button==KEY_DLEFT||button==KEY_LSTICK_LEFT||button==KEY_RSTICK_LEFT||button==KEY_MINUS||button==KEY_PLUS) @@ -227,9 +234,9 @@ class M39OLGUI : public tsl::Gui { // Called when this Gui gets loaded to create the UI // Allocate all your elements on the heap. libtesla will make sure to clean them up when not needed anymore virtual tsl::elm::Element* createUI() override { - auto rootFrame = new tsl::elm::OverlayFrame("MEGAHAKUS 2.2.0", "For MEGA39's 1.0.3"); + auto rootFrame = new tsl::elm::OverlayFrame("MEGAHAKUS 2.3.0", "For MEGA39's 1.0.3"); auto list = new tsl::elm::List(); - if (initialized&&debugService_isRunning()&&metadata.title_id==0x100F3100DA46000&&bid_match()) + if (initialized&&debugService_isRunning()&&metadata.title_id==GAME_TITLE_ID&&bid_match()) { // "Disable NPR" // Get current state @@ -273,7 +280,6 @@ class M39OLGUI : public tsl::Gui { // Add item list->addItem(debug_mode); - // "Cursor to touchscreen" // Get current state /*unsigned char cursorbuffer; @@ -329,6 +335,20 @@ class M39OLGUI : public tsl::Gui { cur_dpad_itm->setStateChangedListener(dpad_cursor_toggle); list->addItem(cur_dpad_itm); + // "Force TEST_MODE" + // Get current state + unsigned char tmbuffer[1]; + if(dmntchtReadCheatProcessMemory(metadata.main_nso_extents.base + STATE_SWITCH_OFFSET+2, tmbuffer, 1)) tmbuffer[0]=0x00; + + // Create item + auto *force_test_mode_itm = new tsl::elm::ToggleListItem("Force TEST_MODE", tmbuffer[0]==0x80); + + // Set listener function + force_test_mode_itm->setStateChangedListener(force_test_mode); + + // Add item + list->addItem(force_test_mode_itm); + // "Enable recording" // Get current state unsigned char recbuffer[1]; @@ -357,31 +377,34 @@ class M39OLGUI : public tsl::Gui { // Called once every frame to update values virtual void update() override { - // "Resolution scale" - // Get current value - float resbuf; - if(!dmntchtReadCheatProcessMemory(metadata.main_nso_extents.base + RES_SCALE_OFFSET, &resbuf, sizeof(resbuf))) + if (initialized&&debugService_isRunning()&&metadata.title_id==GAME_TITLE_ID&&bid_match()) { - int resp=static_cast(resbuf*1000); - std::string resstr=std::to_string(resp); - resstr.insert(resstr.end()-1, '.'); - if(resstr.at(0)=='.') resstr.insert(resstr.begin(), '0'); - std::string itmstr="Resolution: "+resstr+'%'; - if(resp<20) itmstr.append(" FLICKER"); - ress_itm->setText(itmstr); - } - // "VP" - // Get current amount - unsigned int vpnum; - if(!dmntchtReadCheatProcessMemory(metadata.main_nso_extents.base + VP_AMOUNT_OFFSET_MAIN, &vpnum, sizeof(vpnum))) - vp_itm->setText("VP: "+std::to_string(vpnum)); + // "Resolution scale" + // Get current value + float resbuf; + if(!dmntchtReadCheatProcessMemory(metadata.main_nso_extents.base + RES_SCALE_OFFSET, &resbuf, sizeof(resbuf))) + { + int resp=static_cast(resbuf*1000); + std::string resstr=std::to_string(resp); + resstr.insert(resstr.end()-1, '.'); + if(resstr.at(0)=='.') resstr.insert(resstr.begin(), '0'); + std::string itmstr="Resolution: "+resstr+'%'; + if(resp<20) itmstr.append(" FLICKER"); + ress_itm->setText(itmstr); + } + // "VP" + // Get current amount + unsigned int vpnum; + if(!dmntchtReadCheatProcessMemory(metadata.main_nso_extents.base + VP_AMOUNT_OFFSET_MAIN, &vpnum, sizeof(vpnum))) + vp_itm->setText("VP: "+std::to_string(vpnum)); - tsl::gfx::Renderer::setOpacity(opacity); + tsl::gfx::Renderer::setOpacity(opacity); + } } // Called once every frame to handle inputs not handled by other UI elements virtual bool handleInput(u64 keysDown, u64 keysHeld, touchPosition touchInput, JoystickPosition leftJoyStick, JoystickPosition rightJoyStick) override { - if(debug_mode_enabled&&((!dpad_cursor&&(leftJoyStick.dx!=0||leftJoyStick.dy!=0||rightJoyStick.dx!=0||rightJoyStick.dy!=0))||(dpad_cursor&&(keysHeld&KEY_DUP||keysHeld&KEY_DDOWN||keysHeld&KEY_DLEFT||keysHeld&KEY_DRIGHT))||keysHeld&KEY_ZR||keysHeld&KEY_ZL||(keysHeld&KEY_L||keysHeld&KEY_R))) + if((initialized&&debugService_isRunning()&&metadata.title_id==GAME_TITLE_ID&&bid_match())&&debug_mode_enabled&&((!dpad_cursor&&(leftJoyStick.dx!=0||leftJoyStick.dy!=0||rightJoyStick.dx!=0||rightJoyStick.dy!=0))||(dpad_cursor&&(keysHeld&KEY_DUP||keysHeld&KEY_DDOWN||keysHeld&KEY_DLEFT||keysHeld&KEY_DRIGHT))||keysHeld&KEY_ZR||keysHeld&KEY_ZL||(keysHeld&KEY_L||keysHeld&KEY_R))) { DivaInputState dis; if(!dmntchtReadCheatProcessMemory(metadata.main_nso_extents.base + INPUTSTATE_P0_OFFSET, &dis, sizeof(dis))) diff --git a/source/mini-tlac.cpp b/source/mini-tlac.cpp new file mode 100644 index 0000000..4d9d610 --- /dev/null +++ b/source/mini-tlac.cpp @@ -0,0 +1,26 @@ +#include +#include "mini-tlac.h" + +bool MINITLAC_injectGameSubState(unsigned long baseaddr, unsigned int state, unsigned int substate) +{ + const unsigned int multiplier=0x20; + + unsigned short submov=static_cast(multiplier*substate); + unsigned char submovlt=(submov & 0xFF)+0x13; + unsigned char submovlb=(submov & 0xFF)+0x1; + unsigned char submovr=(submov >> 8) & 0xFF; + + unsigned short gmmov=static_cast(multiplier*state); + unsigned char gmmovl=(gmmov & 0xFF); + unsigned char gmmovr=(gmmov >> 8) & 0xFF; + + + const unsigned char buffer[]=STATE_SWITCH_PATCHED; + return dmntchtWriteCheatProcessMemory(baseaddr+STATE_SWITCH_OFFSET, &buffer, sizeof(buffer)); +} + +bool MINITLAC_restoreGameSubState(unsigned long baseaddr) +{ + const unsigned char buffer[]=STATE_SWITCH_ORIGINAL; + return dmntchtWriteCheatProcessMemory(baseaddr+STATE_SWITCH_OFFSET, &buffer, sizeof(buffer)); +} diff --git a/source/mini-tlac.h b/source/mini-tlac.h new file mode 100644 index 0000000..74b05b8 --- /dev/null +++ b/source/mini-tlac.h @@ -0,0 +1,15 @@ +#ifndef MINITLAC_H +#define MINITLAC_H + +#define STATE_SWITCH_OFFSET 0x1E3994 +#define STATE_SWITCH_ORIGINAL {0xF3, 0x03, 0x01, 0x2A, 0x1F, 0x30, 0x00, 0x71, 0x40, 0x08, 0x00, 0x54} +#define STATE_SWITCH_PATCHED {submovlt, submovr, 0x80, 0x52, gmmovl, gmmovr, 0x80, 0x52, submovlb, submovr, 0x80, 0x52} + +/*#define CURRENT_STATE_OFFSET 0xB2A2C640 +#define CURRENT_STATE2_OFFSET 0xB2A2C65C*/ + +bool MINITLAC_injectGameSubState(unsigned long baseaddr, unsigned int state, unsigned int substate); + +bool MINITLAC_restoreGameSubState(unsigned long baseaddr); + +#endif // MINITLAC_H