├── libctrpf ├── lib │ ├── libctrpf.a │ └── libctrpfd.a └── include │ ├── CTRPluginFramework │ ├── Sound.hpp │ ├── Graphics.hpp │ ├── System │ │ ├── Sleep.hpp │ │ ├── Touch.hpp │ │ ├── Clock.hpp │ │ ├── Mutex.hpp │ │ ├── Lock.hpp │ │ ├── Thread.hpp │ │ ├── System.hpp │ │ ├── Task.hpp │ │ ├── Controller.hpp │ │ ├── Vector.hpp │ │ ├── Rect.hpp │ │ ├── Time.hpp │ │ ├── Directory.hpp │ │ ├── FwkSettings.hpp │ │ ├── Hook.hpp │ │ └── File.hpp │ ├── Utils.hpp │ ├── Menu.hpp │ ├── Graphics │ │ ├── CustomIcon.hpp │ │ ├── Color.hpp │ │ └── OSD.hpp │ ├── Utils │ │ ├── LineReader.hpp │ │ ├── StringExtensions.hpp │ │ ├── LineWriter.hpp │ │ └── Utils.hpp │ ├── System.hpp │ ├── Menu │ │ ├── MessageBox.hpp │ │ ├── MenuEntryHotkeys.hpp │ │ ├── MenuEntry.hpp │ │ ├── MenuFolder.hpp │ │ ├── PluginMenu.hpp │ │ └── Keyboard.hpp │ └── Sound │ │ ├── SoundEngine.hpp │ │ └── Sound.hpp │ └── CTRPluginFramework.hpp ├── New Installer ├── Miichanic's Tool Box logo.ico ├── Miichanics-Tool-Box-Installer.exe └── README.md ├── Assets └── install.sh ├── Includes ├── MenuPointers.hpp ├── Helpers │ ├── Region.hpp │ ├── Strings.hpp │ ├── AutoRegion.hpp │ ├── Wrappers.hpp │ ├── KeySequence.hpp │ ├── HoldKey.hpp │ ├── OSDManager.hpp │ ├── MenuEntryHelpers.hpp │ ├── QuickMenu.hpp │ └── QRCodeGen.hpp ├── Helpers.hpp ├── Unicode.h ├── types.h ├── cheats.hpp └── csvc.h ├── 0004001000028700.txt ├── CTRPluginFramework.plgInfo ├── 0004001000021700.txt ├── Makefile ├── 3gx.ld ├── Sources ├── QRcheat.cpp ├── KORcheats.cpp ├── TWNcheats.cpp └── main.cpp └── README.md /libctrpf/lib/libctrpf.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FoofooTheGuy/Miichanic_Plugin/HEAD/libctrpf/lib/libctrpf.a -------------------------------------------------------------------------------- /libctrpf/lib/libctrpfd.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FoofooTheGuy/Miichanic_Plugin/HEAD/libctrpf/lib/libctrpfd.a -------------------------------------------------------------------------------- /New Installer/Miichanic's Tool Box logo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FoofooTheGuy/Miichanic_Plugin/HEAD/New Installer/Miichanic's Tool Box logo.ico -------------------------------------------------------------------------------- /New Installer/Miichanics-Tool-Box-Installer.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FoofooTheGuy/Miichanic_Plugin/HEAD/New Installer/Miichanics-Tool-Box-Installer.exe -------------------------------------------------------------------------------- /Assets/install.sh: -------------------------------------------------------------------------------- 1 | 2 | DEVKITPRO=/opt/devkitpro 3 | CTRPFDIR=$DEVKITPRO/libctrpf 4 | 5 | rm -rf $CTRPFDIR 6 | mkdir -p $CTRPFDIR 7 | bzip2 -cd $1 | tar -xf - -C $CTRPFDIR 8 | echo "CTRPF was successfully installed in $CTRPFDIR" 9 | -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/Sound.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_SOUND_HPP 2 | #define CTRPLUGINFRAMEWORK_SOUND_HPP 3 | 4 | #include "CTRPluginFramework/Sound/Sound.hpp" 5 | #include "CTRPluginFramework/Sound/SoundEngine.hpp" 6 | 7 | #endif -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/Graphics.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_GRAPHICS_HPP 2 | #define CTRPLUGINFRAMEWORK_GRAPHICS_HPP 3 | 4 | #include "CTRPluginFramework/Graphics/Color.hpp" 5 | #include "CTRPluginFramework/Graphics/OSD.hpp" 6 | 7 | #endif -------------------------------------------------------------------------------- /Includes/MenuPointers.hpp: -------------------------------------------------------------------------------- 1 | #ifndef MENUPOINTERS_HPP 2 | #define MENUPOINTERS_HPP 3 | 4 | #include 5 | 6 | namespace CTRPluginFramework { 7 | extern MenuFolder *editorEntries; 8 | extern MenuFolder *saveEntries; 9 | } 10 | 11 | #endif -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/System/Sleep.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_SLEEP_HPP 2 | #define CTRPLUGINFRAMEWORK_SLEEP_HPP 3 | 4 | 5 | namespace CTRPluginFramework 6 | { 7 | class Time; 8 | 9 | void Sleep(Time sleepTime); 10 | } 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /0004001000028700.txt: -------------------------------------------------------------------------------- 1 | [editor data] 2 | 0880CC04 00000003 3 | 4 | [mii dsta] 5 | 08831C84 00000003 6 | 7 | [blessed] 8 | 08848E84 00000003 9 | 10 | [selected mii] 11 | 18AF7398 00010009 12 | 13 | [editpr!] 14 | 0803CAEC FFFFFFFF 15 | 16 | [is vieeing miis] 17 | 08AF73A4 00B88C50 18 | 19 | -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_HPP 2 | #define CTRPLUGINFRAMEWORK_HPP 3 | 4 | #include "CTRPluginFramework/Graphics.hpp" 5 | #include "CTRPluginFramework/Menu.hpp" 6 | #include "CTRPluginFramework/Sound.hpp" 7 | #include "CTRPluginFramework/System.hpp" 8 | #include "CTRPluginFramework/Utils.hpp" 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/Utils.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_UTILS_HPP 2 | #define CTRPLUGINFRAMEWORK_UTILS_HPP 3 | 4 | #include "CTRPluginFramework/Utils/LineReader.hpp" 5 | #include "CTRPluginFramework/Utils/LineWriter.hpp" 6 | #include "CTRPluginFramework/Utils/Utils.hpp" 7 | #include "CTRPluginFramework/Utils/StringExtensions.hpp" 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /Includes/Helpers/Region.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REGION_HPP 2 | #define REGION_HPP 3 | 4 | #include 5 | 6 | namespace CTRPluginFramework { 7 | enum CurrRegion { 8 | INVALID, 9 | JUE, 10 | CT, 11 | KOR, 12 | }; 13 | 14 | extern CurrRegion c_Region; 15 | 16 | namespace Region { 17 | u32 AutoRegion(u32 jue, u32 ct, u32 kor); 18 | } 19 | } 20 | #endif -------------------------------------------------------------------------------- /Includes/Helpers.hpp: -------------------------------------------------------------------------------- 1 | #ifndef HELPERS_HPP 2 | #define HELPERS_HPP 3 | 4 | //#include "Helpers/AutoRegion.hpp" 5 | #include "Helpers/HoldKey.hpp" 6 | #include "Helpers/KeySequence.hpp" 7 | #include "Helpers/MenuEntryHelpers.hpp" 8 | #include "Helpers/OSDManager.hpp" 9 | #include "Helpers/QuickMenu.hpp" 10 | #include "Helpers/Strings.hpp" 11 | #include "Helpers/Wrappers.hpp" 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /Includes/Helpers/Strings.hpp: -------------------------------------------------------------------------------- 1 | #ifndef STRINGS_HPP 2 | #define STRINGS_HPP 3 | 4 | #include 5 | 6 | namespace CTRPluginFramework 7 | { 8 | std::string Hex(u8 x); 9 | std::string Hex(u16 x); 10 | std::string Hex(u32 x); 11 | std::string Hex(u64 x); 12 | std::string Hex(float x); 13 | std::string Hex(double x); 14 | } 15 | 16 | #endif -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/System/Touch.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_TOUCH_HPP 2 | #define CTRPLUGINFRAMEWORK_TOUCH_HPP 3 | 4 | #include "Vector.hpp" 5 | 6 | namespace CTRPluginFramework 7 | { 8 | class Touch 9 | { 10 | public: 11 | static bool IsDown(void); 12 | static UIntVector GetPosition(void); 13 | }; 14 | } 15 | 16 | #endif -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/Menu.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_MENU_HPP 2 | #define CTRPLUGINFRAMEWORK_MENU_HPP 3 | 4 | #include "CTRPluginFramework/Menu/Keyboard.hpp" 5 | #include "CTRPluginFramework/Menu/MenuEntry.hpp" 6 | #include "CTRPluginFramework/Menu/MenuEntryHotkeys.hpp" 7 | #include "CTRPluginFramework/Menu/MenuFolder.hpp" 8 | #include "CTRPluginFramework/Menu/PluginMenu.hpp" 9 | #include "CTRPluginFramework/Menu/MessageBox.hpp" 10 | 11 | #endif -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/System/Clock.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMREWORK_CLOCK_HPP 2 | #define CTRPLUGINFRAMREWORK_CLOCK_HPP 3 | 4 | #include "CTRPluginFramework/System/Time.hpp" 5 | 6 | namespace CTRPluginFramework 7 | { 8 | class Clock 9 | { 10 | public: 11 | Clock(void); 12 | Clock(Time time); 13 | 14 | Time GetElapsedTime(void) const; 15 | bool HasTimePassed(Time time) const; 16 | Time Restart(void); 17 | private: 18 | Time _startTime; 19 | }; 20 | } 21 | 22 | #endif -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/System/Mutex.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_SYSTEM_MUTEX_HPP 2 | #define CTRPLUGINFRAMEWORK_SYSTEM_MUTEX_HPP 3 | 4 | #include "3ds.h" 5 | 6 | namespace CTRPluginFramework 7 | { 8 | class Mutex 9 | { 10 | public: 11 | Mutex(void); 12 | ~Mutex(void); 13 | 14 | void Lock(void); 15 | // Return true on failure 16 | bool TryLock(void); 17 | void Unlock(void); 18 | 19 | private: 20 | RecursiveLock _lock; 21 | }; 22 | } 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /Includes/Helpers/AutoRegion.hpp: -------------------------------------------------------------------------------- 1 | #ifndef AUTOREGION_HPP 2 | #define AUTOREGION_HPP 3 | 4 | #include "types.h" 5 | 6 | namespace CTRPluginFramework 7 | { 8 | enum Region 9 | { 10 | USA, 11 | EUR 12 | }; 13 | 14 | class AutoRegion 15 | { 16 | public: 17 | 18 | // Constructor 19 | AutoRegion(u32 usa, u32 eur); 20 | ~AutoRegion(){} 21 | 22 | // Return the value according to the current region 23 | u32 operator()(void) const; 24 | 25 | // Properties 26 | const u32 Usa; 27 | const u32 Eur; 28 | }; 29 | } 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /CTRPluginFramework.plgInfo: -------------------------------------------------------------------------------- 1 | Author: Nanquitas 2 | 3 | Version: # Plugin version 4 | Major: 0 5 | Minor: 7 6 | Revision: 0 7 | 8 | Targets: # Low TitleId of games which are compatibles with this plugin (0 for all) 9 | 10 | Title: CTRPF - Blank Template 11 | 12 | Summary: A CTRPF Plugin, with a lot of tools 13 | 14 | Description: | 15 | This plugin gives you access to a set of tools to edit your games 16 | 17 | Features: 18 | - Memory searcher 19 | - Hex Editor 20 | - Code creator 21 | - Code import from file 22 | - Action Replay engine with extra capabilities 23 | - Super fast screenshot engine 24 | -------------------------------------------------------------------------------- /Includes/Helpers/Wrappers.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WRAPPERS_HPP 2 | #define WRAPPERS_HPP 3 | 4 | #include "CTRPluginFramework.hpp" 5 | 6 | namespace CTRPluginFramework 7 | { 8 | using StringVector = std::vector; 9 | 10 | bool GetInput(u8 &input, const std::string &msg = "", bool useHex = false); 11 | bool GetInput(u16 &input, const std::string &msg = "", bool useHex = false); 12 | bool GetInput(u32 &input, const std::string &msg = "", bool useHex = false); 13 | bool GetInput(float &input, const std::string &msg = ""); 14 | bool GetInput(u16 &input, const StringVector &choices, const std::string &msg = ""); 15 | } 16 | 17 | #endif -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/Graphics/CustomIcon.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_CUSTOMICON_HPP 2 | #define CTRPLUGINFRAMEWORK_CUSTOMICON_HPP 3 | 4 | #include "types.h" 5 | 6 | namespace CTRPluginFramework 7 | { 8 | class CustomIcon { 9 | 10 | public: 11 | struct Pixel 12 | { 13 | u8 a; 14 | u8 b; 15 | u8 g; 16 | u8 r; 17 | }; 18 | 19 | Pixel* pixArray; 20 | int sizeX; 21 | int sizeY; 22 | bool isEnabled; 23 | 24 | CustomIcon(Pixel* pixArray, int sizeX, int sizeY, bool isEnabled); 25 | CustomIcon(); 26 | }; 27 | 28 | } 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/System/Lock.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_SYSTEM_LOCK_HPP 2 | #define CTRPLUGINFRAMEWORK_SYSTEM_LOCK_HPP 3 | 4 | #include "3ds.h" 5 | 6 | namespace CTRPluginFramework 7 | { 8 | class Mutex; 9 | class Lock 10 | { 11 | public: 12 | explicit Lock(LightLock &llock); 13 | explicit Lock(RecursiveLock &rlock); 14 | explicit Lock(Mutex &mutex); 15 | 16 | ~Lock(void); 17 | 18 | private: 19 | int _type; 20 | union 21 | { 22 | LightLock *_llock; 23 | RecursiveLock *_rlock; 24 | Mutex *_mutex; 25 | }; 26 | }; 27 | } 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/Utils/LineReader.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_UTILS_LINEREADER_HPP 2 | #define CTRPLUGINFRAMEWORK_UTILS_LINEREADER_HPP 3 | 4 | #include "types.h" 5 | #include 6 | 7 | namespace CTRPluginFramework 8 | { 9 | class File; 10 | class LineReader 11 | { 12 | public: 13 | LineReader(File &file); 14 | ~LineReader(void); 15 | 16 | // Return true if a line was read 17 | bool operator()(std::string &line); 18 | 19 | private: 20 | File &_file; 21 | u32 _offsetInBuffer; 22 | u32 _dataInBuffer; 23 | char *_buffer; 24 | }; 25 | } 26 | 27 | #endif -------------------------------------------------------------------------------- /New Installer/README.md: -------------------------------------------------------------------------------- 1 | # Miichanic's Tool Box Installer 2.00 2 | 3 | An internet connection is required for the program to download the required files! (Miichanic.3gx and boot.firm) 4 | --- 5 | 6 | - This is an installer for the Miichanic plugin made using WinAPI and Microsoft Visual Studio 2022. 7 | I also took many examples and functions from the internet, so I apologize if I forgot to link something that I found on some website... 8 | - It is nicer than the old batch file version by doing many more things automatically! 9 | - Provided are the most important parts of the program, (main.cpp and dirent.h) instead of uploading the entire project. 10 | 11 | Usage example: 12 | --- 13 | 14 | ![usage](https://user-images.githubusercontent.com/32585652/149185461-83fde09f-c460-48ee-8584-55600c39a433.PNG) 15 | -------------------------------------------------------------------------------- /Includes/Helpers/KeySequence.hpp: -------------------------------------------------------------------------------- 1 | #ifndef HELPERS_KEYSEQUENCE_HPP 2 | #define HELPERS_KEYSEQUENCE_HPP 3 | 4 | #include "types.h" 5 | #include "CTRPluginFramework/System/Controller.hpp" 6 | #include "CTRPluginFramework/System/Clock.hpp" 7 | 8 | #include 9 | 10 | namespace CTRPluginFramework 11 | { 12 | using KeyVector = std::vector; 13 | 14 | class KeySequence 15 | { 16 | public: 17 | 18 | KeySequence(KeyVector sequence); 19 | ~KeySequence(){} 20 | 21 | /** 22 | * \brief Check the sequence 23 | * \return true if the sequence is completed, false otherwise 24 | */ 25 | bool operator()(void); 26 | 27 | private: 28 | 29 | KeyVector _sequence; 30 | Clock _timer; 31 | int _indexInSequence; 32 | 33 | }; 34 | } 35 | 36 | #endif -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/System.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_SYSTEM_HPP 2 | #define CTRPLUGINFRAMEWORK_SYSTEM_HPP 3 | 4 | #include "CTRPluginFramework/System/Clock.hpp" 5 | #include "CTRPluginFramework/System/Controller.hpp" 6 | #include "CTRPluginFramework/System/Directory.hpp" 7 | #include "CTRPluginFramework/System/File.hpp" 8 | #include "CTRPluginFramework/System/FwkSettings.hpp" 9 | #include "CTRPluginFramework/System/Hook.hpp" 10 | #include "CTRPluginFramework/System/Lock.hpp" 11 | #include "CTRPluginFramework/System/Mutex.hpp" 12 | #include "CTRPluginFramework/System/Process.hpp" 13 | #include "CTRPluginFramework/System/System.hpp" 14 | #include "CTRPluginFramework/System/Task.hpp" 15 | #include "CTRPluginFramework/System/Thread.hpp" 16 | #include "CTRPluginFramework/System/Time.hpp" 17 | #include "CTRPluginFramework/System/Touch.hpp" 18 | #include "CTRPluginFramework/System/Sleep.hpp" 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/Utils/StringExtensions.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_UTILS_STRINGEXTENSIONS_HPP 2 | #define CTRPLUGINFRAMEWORK_UTILS_STRINGEXTENSIONS_HPP 3 | 4 | #include "CTRPluginFramework/Graphics/Color.hpp" 5 | #include 6 | #include 7 | 8 | namespace CTRPluginFramework 9 | { 10 | // Return a string with the charcter that reset the color (0x18) 11 | std::string ResetColor(void); 12 | 13 | std::string operator <<(const std::string &left, const char *right); 14 | std::string operator <<(const std::string &left, const std::string &right); 15 | 16 | template ::value 19 | && !std::is_same::value 20 | >::type* = nullptr> 21 | std::string operator <<(const std::string &left, T right) 22 | { 23 | return (left + std::to_string(right)); 24 | } 25 | } 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/System/Thread.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_SYSTEM_THREAD_HPP 2 | #define CTRPLUGINFRAMEWORK_SYSTEM_THREAD_HPP 3 | 4 | #include "types.h" 5 | #include "3ds.h" 6 | 7 | namespace CTRPluginFramework 8 | { 9 | class ThreadEx 10 | { 11 | public: 12 | enum 13 | { 14 | IDLE, 15 | RUNNING, 16 | FINISHED 17 | }; 18 | 19 | ThreadEx(ThreadFunc entrypoint,u32 stackSize, u32 priority, int affinity); 20 | ~ThreadEx(void); 21 | 22 | Result Start(void *arg); 23 | Result Join(bool releaseResources); 24 | Handle GetHandle(void); 25 | u32 GetStatus(void); 26 | 27 | u8 priority{0x3F}; 28 | s8 affinity{-1}; 29 | 30 | static void Yield(void); 31 | 32 | private: 33 | u8 _state{IDLE}; 34 | Thread_tag *_thread{nullptr}; 35 | }; 36 | } 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/Utils/LineWriter.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_LINEWRITER_HPP 2 | #define CTRPLUGINFRAMEWORK_LINEWRITER_HPP 3 | 4 | #include "types.h" 5 | #include 6 | #include "CTRPluginFramework/Utils/StringExtensions.hpp" 7 | 8 | namespace CTRPluginFramework 9 | { 10 | class File; 11 | class LineWriter 12 | { 13 | public: 14 | LineWriter(File &output); 15 | LineWriter(const LineWriter &right) = delete; 16 | LineWriter(LineWriter &&right) = delete; 17 | ~LineWriter(void); 18 | 19 | LineWriter & operator<<(const std::string &input); 20 | LineWriter & operator=(const LineWriter &right) = delete; 21 | LineWriter & operator=(LineWriter &&right) = delete; 22 | 23 | static const std::string &endl(void); 24 | void Flush(void); 25 | void Close(void); 26 | 27 | private: 28 | File &_output; 29 | u32 _offsetInBuffer; 30 | u8 *_buffer; 31 | }; 32 | } 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /Includes/Unicode.h: -------------------------------------------------------------------------------- 1 | #ifndef UNICODE_H 2 | #define UNICODE_H 3 | 4 | // HID Symbols 5 | #define FONT_A "\uE000" // System Font A button 6 | #define FONT_B "\uE001" // System Font B button 7 | #define FONT_X "\uE002" // System Font X button 8 | #define FONT_Y "\uE003" // System Font Y button 9 | #define FONT_L "\uE052" // System Font L button 10 | #define FONT_R "\uE053" // System Font R button 11 | #define FONT_ZL "\uE054" // System Font ZL button 12 | #define FONT_ZR "\uE055" // System Font ZR button 13 | #define FONT_DU "\uE079" // System Font D-Pad Up button 14 | #define FONT_DD "\uE07A" // System Font D-Pad Down button 15 | #define FONT_DL "\uE07B" // System Font D-Pad Left button 16 | #define FONT_DR "\uE07C" // System Font D-Pad Right button 17 | #define FONT_DUD "\uE07D" // System Font D-Pad Up and Down button 18 | #define FONT_DLR "\uE07E" // System Font D-Pad Left and Right button 19 | #define FONT_CP "\uE077" // System Font Circle Pad button 20 | #define FONT_T "\uE058" // System Font Touch button 21 | 22 | #endif -------------------------------------------------------------------------------- /Includes/Helpers/HoldKey.hpp: -------------------------------------------------------------------------------- 1 | #ifndef HOLDKEY_HPP 2 | #define HOLDKEY_HPP 3 | 4 | #include "CTRPluginFramework.hpp" 5 | 6 | namespace CTRPluginFramework 7 | { 8 | class HoldKey 9 | { 10 | public: 11 | /** 12 | * \brief A helping class to check if a key(s) is pressed for a period of time 13 | * \param keys A key or a combo that have to be pressed 14 | * \param holdTime The time the key(s) need to be pressed 15 | */ 16 | HoldKey(u32 keys, Time holdTime); 17 | ~HoldKey(void) {}; 18 | 19 | /** 20 | * \brief Check if the key is pressed 21 | * \return If the key(s) were holded the required amount of time 22 | */ 23 | bool operator()(void); 24 | /** 25 | * \brief Change the keys that needs to be pressed 26 | * \param newKeys The new keys value 27 | */ 28 | void operator = (u32 newKeys); 29 | private: 30 | Clock _timer; 31 | Time _goal; 32 | bool _isHold; 33 | u32 _keys; 34 | }; 35 | }; 36 | 37 | #endif -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/Menu/MessageBox.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_MESSAGEBOX_HPP 2 | #define CTRPLUGINFRAMEWORK_MESSAGEBOX_HPP 3 | 4 | #include 5 | #include 6 | 7 | namespace CTRPluginFramework 8 | { 9 | enum class DialogType 10 | { 11 | DialogOk, 12 | DialogOkCancel, 13 | DialogYesNo 14 | }; 15 | 16 | enum class ClearScreen 17 | { 18 | None = 0, 19 | Top = 1 << 1, 20 | Bottom = 1 << 2, 21 | Both = Top | Bottom 22 | }; 23 | 24 | class MessageBoxImpl; 25 | class MessageBox 26 | { 27 | public: 28 | MessageBox(const std::string &title, const std::string &message, DialogType dialogType = DialogType::DialogOk, ClearScreen clear = ClearScreen::None); 29 | MessageBox(const std::string &message, DialogType dialogType = DialogType::DialogOk, ClearScreen clear = ClearScreen::None); 30 | ~MessageBox(void); 31 | 32 | MessageBox& SetClear(ClearScreen screen); 33 | 34 | // Display the Message Box and wait for the user input 35 | // Return: 36 | // True if user selected Yes / Ok 37 | // False is user selected No / Cancel 38 | bool operator()(void) const; 39 | 40 | private: 41 | std::unique_ptr _messageBox; 42 | }; 43 | } 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /Includes/Helpers/OSDManager.hpp: -------------------------------------------------------------------------------- 1 | #ifndef OSD_MANAGER_HPP 2 | #define OSD_MANAGER_HPP 3 | 4 | #include <3ds.h> 5 | #include "CTRPluginFramework.hpp" 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | namespace CTRPluginFramework 12 | { 13 | #define OSDManager (*_OSDManager::GetInstance()) 14 | 15 | using OSDMITuple = std::tuple; 16 | struct OSDMI 17 | { 18 | OSDMI &operator=(const std::string &str); 19 | OSDMI &operator=(const OSDMITuple &tuple); 20 | OSDMI &SetPos(u32 posX, u32 posY); 21 | OSDMI &SetScreen(bool topScreen); 22 | OSDMI &Enable(void); 23 | OSDMI &Disable(void); 24 | private: 25 | friend class _OSDManager; 26 | explicit OSDMI(OSDMITuple &tuple); 27 | 28 | OSDMITuple &data; 29 | }; 30 | 31 | class _OSDManager 32 | { 33 | public: 34 | ~_OSDManager(void); 35 | 36 | static _OSDManager *GetInstance(void); 37 | 38 | OSDMI operator[](const std::string &key); 39 | void Remove(const std::string &key); 40 | void Lock(void); 41 | void Unlock(void); 42 | private: 43 | 44 | _OSDManager(void); 45 | 46 | static bool OSDCallback(const Screen &screen); 47 | 48 | static _OSDManager *_singleton; 49 | 50 | LightLock _lock; 51 | std::map> _items; 52 | }; 53 | } 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /Includes/Helpers/MenuEntryHelpers.hpp: -------------------------------------------------------------------------------- 1 | #ifndef MENUENTRYHELPERS_HPP 2 | #define MENUENTRYHELPERS_HPP 3 | 4 | #include "CTRPluginFramework/Menu/MenuEntry.hpp" 5 | 6 | namespace CTRPluginFramework 7 | { 8 | /** 9 | * \brief Return the arg of an entry \n 10 | * If the arg doesn't exist (nullptr) a new one is created calling the default type constructor 11 | * \tparam T The type of the arg 12 | * \param entry The entry to get the arg from 13 | * \return A pointer to the arg (like reinterpret_cast(entry->GetArg())) 14 | */ 15 | template 16 | T *GetArg(MenuEntry *entry) 17 | { 18 | T *arg = reinterpret_cast(entry->GetArg()); 19 | 20 | if (arg == nullptr) 21 | { 22 | arg = new T(); 23 | entry->SetArg(arg); 24 | } 25 | 26 | return (arg); 27 | } 28 | 29 | /** 30 | * \brief Return the arg of an entry \n 31 | * If the arg doesn't exist (nullptr) a new one is created calling the default type constructor 32 | * \tparam T The type of the arg 33 | * \param entry The entry to get the arg from 34 | * \param defaultValue The value to set to a newly created arg 35 | * \return A pointer to the arg (like reinterpret_cast(entry->GetArg())) 36 | */ 37 | template 38 | T *GetArg(MenuEntry *entry, T defaultValue) 39 | { 40 | T *arg = reinterpret_cast(entry->GetArg()); 41 | 42 | if (arg == nullptr) 43 | { 44 | arg = new T(defaultValue); 45 | entry->SetArg(arg); 46 | } 47 | 48 | return (arg); 49 | } 50 | } 51 | 52 | #endif -------------------------------------------------------------------------------- /0004001000021700.txt: -------------------------------------------------------------------------------- 1 | [technical editor data] 2 | 08815890 00000003 3 | 4 | [copy dude to editor] 5 | D3000001 089C3B10 6 | D3000000 08815890 7 | DD000000 00000200 8 | FC000000 00000100 9 | D2000000 00000000 10 | 11 | [menu (dumb)] 12 | 088B2B28 FFFFFFFF 13 | 088B2B48 00000000 14 | 15 | [First mii] 16 | 0883A910 00000003 17 | 18 | [Second mii] 19 | 08851B10 00000003 20 | {theres a 17200 from each} 21 | 22 | [selected mii] 23 | 188014D4 FFFF0000 24 | 25 | [freeze brows] 26 | 0895A28C 00000000 27 | 0895A20C 00000000 28 | 0895A30C 00000000 29 | 0895A38C 00000000 30 | 0895A40C 00000000 31 | 0895A48C 00000000 32 | 0895A50C 00000000 33 | 0895A58C 00000000 34 | 0895A60C 00000000 35 | 0895A68C 00000000 36 | 37 | [freeze eye] 38 | 08955C0C 00000000 39 | 08955C8C 00000000 40 | 08955D0C 00000000 41 | 08955D8C 00000000 42 | 08955E0C 00000000 43 | 08955E8C 00000000 44 | 08955F0C 00000000 45 | 08955F8C 00000000 46 | 0895600C 00000000 47 | 0895608C 00000000 48 | 49 | [freeze nose] 50 | 0896078C 00000000 51 | 0896080C 00000000 52 | 0896088C 00000000 53 | 0896090C 00000000 54 | 55 | [freeze mouth] 56 | 0895DD0C 00000000 57 | 0895DD8C 00000000 58 | 0895DE0C 00000000 59 | 0895DE8C 00000000 60 | 0895DF0C 00000000 61 | 0895DF8C 00000000 62 | 63 | [freeze glassesnwot] 64 | 0894720C 00000000 65 | 0894728C 00000000 66 | 0894730C 00000000 67 | 0894738C 00000000 68 | 0894CE8C 00000000 69 | 0894CF0C 00000000 70 | 0894CF8C 00000000 71 | 0894D00C 00000000 72 | 0894A48C 00000000 73 | 0894A50C 00000000 74 | 0894A58C 00000000 75 | 0894A60C 00000000 76 | 0894A68C 00000000 77 | 0894A70C 00000000 78 | 79 | [impotrant?] 80 | 00372528 0000C1D0 81 | 82 | [real in editor address] 83 | 0037259C 00002BEF 84 | 85 | [cfog] 86 | D3000000 10000000 87 | 04895A20 474F4643 88 | 89 | -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/System/System.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_SYSTEM_SYSTEM_HPP 2 | #define CTRPLUGINFRAMEWORK_SYSTEM_SYSTEM_HPP 3 | 4 | #include "types.h" 5 | 6 | namespace CTRPluginFramework 7 | { 8 | enum class LanguageId 9 | { 10 | Japanese = 0, 11 | English, 12 | French, 13 | German, 14 | Italian, 15 | Spanish, 16 | ChineseSimplified, 17 | Korean, 18 | Dutch, 19 | Portugese, 20 | Russian, 21 | ChineseTraditional 22 | }; 23 | 24 | class System 25 | { 26 | public: 27 | 28 | /** 29 | * \brief Check if the current console is a New3DS 30 | * \return true if the current console is a New3DS,\n false otherwise 31 | */ 32 | static bool IsNew3DS(void); 33 | 34 | /** 35 | * \brief Get the system's language (user defined) 36 | * \return The language of the system 37 | */ 38 | static LanguageId GetSystemLanguage(void); 39 | 40 | /** 41 | * \brief Get if the 3DS is connected to Internet 42 | * \return true if connected \n false if not connected 43 | */ 44 | static bool IsConnectedToInternet(void); 45 | 46 | /** 47 | * \brief Check if the cfw is Luma3DS or not\n 48 | * A version number can be passed and if it's the case the function will return whether the version of the cfw is the same or higher (true) or inferior (false) 49 | * \param major An optional version 50 | * \param minor An optional version 51 | * \param revision An optional version 52 | * \return If the cfw is Luma3DS or not 53 | */ 54 | static bool CfwIsLuma3DS(u8 major = 0, u8 minor = 0, u8 revision = 0); 55 | 56 | /** 57 | * \brief A callback that will be called in std::abort if set 58 | */ 59 | static void (*OnAbort)(void); 60 | 61 | /** 62 | * \brief Causes a system hardware reboot. Does not return. 63 | */ 64 | static void Reboot(void) NORETURN; 65 | }; 66 | } 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/Sound/SoundEngine.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_SOUND_SOUNDENGINE_HPP 2 | #define CTRPLUGINFRAMEWORK_SOUND_SOUNDENGINE_HPP 3 | 4 | #include "CTRPluginFramework/Sound/Sound.hpp" 5 | 6 | namespace CTRPluginFramework 7 | { 8 | class SoundEngine 9 | { 10 | public: 11 | 12 | /// Menu sound event types. 13 | enum class Event { 14 | CURSOR = 0, ///< Movement of the cursor. 15 | ACCEPT, ///< Acces menu or entry, pressing OK, etc. 16 | CANCEL, ///< Exit menu or entry, pressing Cancel, etc. 17 | SELECT, ///< Selecing a button or enabling entry. 18 | DESELECT, ///< Deselecting a button or disabling entry. 19 | 20 | NUM_EVENTS ///< Total amount of events. 21 | }; 22 | 23 | /** 24 | * \brief Replaces the sound associated to the event with the new sound. 25 | * \param eventType Event to assign the sound to. 26 | * \param sound Sound to assign to the event. 27 | * \return Whether the operation was successful or not. 28 | */ 29 | static bool RegisterMenuSoundEvent(Event eventType, Sound& sound); 30 | 31 | /** 32 | * \brief Gets a reference to the sound associated with an event. 33 | * \param eventType Event to get the sound from. 34 | * \return Reference to the sound associated with the event. 35 | */ 36 | static Sound& GetMenuSoundEvent(SoundEngine::Event eventType); 37 | 38 | /** 39 | * \brief Plays the sound associated with an event. 40 | * \param eventTypes Event to play its sound. 41 | * \return Whether the operation was successful or not. 42 | */ 43 | static bool PlayMenuSound(Event eventType); 44 | 45 | /** 46 | * \brief Stops the sound associated with an event. 47 | * \param eventTypes Event to stop its sound. 48 | */ 49 | static void StopMenuSound(Event eventType); 50 | 51 | /** 52 | * \brief Removes the sound associated to an event. 53 | * \param eventType Event to remove the sound. 54 | */ 55 | static void DeRegisterMenuSoundEvent(Event eventType); 56 | 57 | }; 58 | } 59 | 60 | #endif -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/System/Task.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_SYSTEM_TASK_HPP 2 | #define CTRPLUGINFRAMEWORK_SYSTEM_TASK_HPP 3 | 4 | #include "types.h" 5 | #include "3ds.h" 6 | #include 7 | #include 8 | 9 | namespace CTRPluginFramework 10 | { 11 | using TaskFunc = s32 (*)(void *); 12 | 13 | struct TaskContext 14 | { 15 | std::atomic flags{0}; 16 | s32 affinity{-1}; 17 | s32 result{0}; 18 | void * arg{nullptr}; 19 | TaskFunc func{nullptr}; 20 | LightEvent event{}; 21 | }; 22 | 23 | using TaskContextPtr = std::shared_ptr; 24 | struct Task 25 | { 26 | enum Status 27 | { 28 | Idle = 0, 29 | Scheduled = 1, 30 | Processing = 2, 31 | Finished = 4 32 | }; 33 | 34 | enum Affinity 35 | { 36 | AppCore = 1 << 0, 37 | NewAppCore = 1 << 2, 38 | NewSysCore = 1 << 3, 39 | 40 | AppCores = AppCore | NewAppCore, 41 | SysCores = NewSysCore, 42 | AllCores = AppCores | SysCores 43 | }; 44 | 45 | TaskContextPtr context; 46 | 47 | explicit Task(TaskFunc func, void *arg = nullptr, s32 affinity = -1); 48 | Task(const Task& task); 49 | Task(Task&& task) noexcept; 50 | ~Task(void) = default; 51 | 52 | Task& operator=(const Task& right); 53 | Task& operator=(Task&& right) noexcept; 54 | 55 | /** 56 | * \brief Schedule a Task and starts it 57 | * \return 0 on operation success, -1 if the task is already running (check Status) 58 | */ 59 | int Start(void) const; 60 | int Start(void *arg) const; 61 | 62 | /** 63 | * \brief Wait for the Task to be completed 64 | * \return The result of the Task (returned by TaskFunc) 65 | */ 66 | s32 Wait(void) const; 67 | 68 | /** 69 | * \brief Get the current status of the Task 70 | * \return Task status (see enum) 71 | */ 72 | u32 Status(void) const; 73 | }; 74 | } 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /Includes/Helpers/QuickMenu.hpp: -------------------------------------------------------------------------------- 1 | #ifndef HELPERS_QUICKMENU_HPP 2 | #define HELPERS_QUICKMENU_HPP 3 | #include "types.h" 4 | #include 5 | #include 6 | #include 7 | #include "HoldKey.hpp" 8 | 9 | namespace CTRPluginFramework 10 | { 11 | using VoidMethod = void(*)(void); 12 | using ArgMethod = void(*)(void *); 13 | using StringVector = std::vector; 14 | struct QuickMenuItem 15 | { 16 | enum class ItemType 17 | { 18 | Entry, SubMenu 19 | }; 20 | 21 | QuickMenuItem(const std::string &name, const ItemType itemType); 22 | 23 | std::string name; 24 | const ItemType itemType; 25 | }; 26 | 27 | struct QuickMenuEntry : QuickMenuItem 28 | { 29 | enum class MethodType 30 | { 31 | VOID, ARG 32 | }; 33 | 34 | QuickMenuEntry(const std::string &name, VoidMethod method); 35 | QuickMenuEntry(const std::string &name, ArgMethod method, void *arg); 36 | ~QuickMenuEntry(); 37 | 38 | MethodType methodType; 39 | union 40 | { 41 | VoidMethod voidMethod; 42 | ArgMethod argMethod; 43 | }; 44 | void *methodArg; 45 | }; 46 | 47 | struct QuickMenuSubMenu : QuickMenuItem 48 | { 49 | QuickMenuSubMenu(const std::string &name); 50 | QuickMenuSubMenu(const std::string &name, const std::vector &items); 51 | ~QuickMenuSubMenu(); 52 | void operator += (QuickMenuItem *item); 53 | void operator -= (QuickMenuItem *item); 54 | 55 | std::vector items; 56 | }; 57 | 58 | class QuickMenu 59 | { 60 | public: 61 | ~QuickMenu(); 62 | static QuickMenu &GetInstance(void); 63 | 64 | void ChangeHotkey(u32 newHotkey); 65 | 66 | void operator += (QuickMenuItem *item); 67 | void operator -= (QuickMenuItem *item); 68 | void operator () (void); 69 | 70 | private: 71 | QuickMenu(u32 hotkey); 72 | 73 | HoldKey _hotkey; 74 | QuickMenuSubMenu *_subMenuOpened; 75 | std::vector _root; 76 | std::stack _submenus; 77 | 78 | static QuickMenu _instance; 79 | }; 80 | } 81 | 82 | #endif -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/System/Controller.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_CONTROLLER_HPP 2 | #define CTRPLUGINFRAMEWORK_CONTROLLER_HPP 3 | 4 | #include "types.h" 5 | 6 | namespace CTRPluginFramework 7 | { 8 | enum Key 9 | { 10 | A = 1, 11 | B = 1 << 1, 12 | Select = 1 << 2, 13 | Start = 1 << 3, 14 | DPadRight = 1 << 4, 15 | DPadLeft = 1 << 5, 16 | DPadUp = 1 << 6, 17 | DPadDown = 1 << 7, 18 | R = 1 << 8, 19 | L = 1 << 9, 20 | X = 1 << 10, 21 | Y = 1 << 11, 22 | ZL = 1 << 14, ///< The ZL button (New 3DS only) 23 | ZR = 1 << 15, ///< The ZR button (New 3DS only) 24 | Touchpad = 1 << 20, 25 | CStickRight = 1 << 24, 26 | CStickLeft = 1 << 25, 27 | CStickUp = 1 << 26, 28 | CStickDown = 1 << 27, 29 | CPadRight = 1 << 28, 30 | CPadLeft = 1 << 29, 31 | CPadUp = 1 << 30, 32 | CPadDown = 1 << 31, 33 | Up = DPadUp | CPadUp, 34 | Down = DPadDown | CPadDown, 35 | Left = DPadLeft | CPadLeft, 36 | Right = DPadRight | CPadRight, 37 | CPad = CPadLeft | CPadRight | CPadUp | CPadDown, 38 | CStick = CStickLeft | CStickRight | CStickUp | CStickDown 39 | }; 40 | class Controller 41 | { 42 | public: 43 | 44 | // Return all the keys currently down 45 | static u32 GetKeysDown(void); 46 | // Return all the keys which were released 47 | static u32 GetKeysReleased(void); 48 | // Return if the key is still being pressed 49 | static bool IsKeyDown(Key key); 50 | // Return if the key just got pressed 51 | static bool IsKeyPressed(Key key); 52 | // Return if the key was released 53 | static bool IsKeyReleased(Key key); 54 | 55 | // Return if keyCombo is still being pressed 56 | static bool IsKeysDown(u32 keys); 57 | // Return is the keys combo just got pressed 58 | static bool IsKeysPressed(u32 keys); 59 | // Return is the keys combo just was released 60 | static bool IsKeysReleased(u32 keys); 61 | // Update Controller status 62 | static void Update(void); 63 | 64 | static void InjectTouch(u16 posX, u16 posY); 65 | static void InjectKey(u32 key); 66 | private: 67 | static u32 _keysDown; 68 | static u32 _keysHeld; 69 | static u32 _keysReleased; 70 | }; 71 | } 72 | 73 | #endif -------------------------------------------------------------------------------- /Includes/types.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file types.h 3 | * @brief Various system types. 4 | */ 5 | #pragma once 6 | #ifndef TYPES_H 7 | #define TYPES_H 8 | 9 | #include 10 | #include 11 | #include 12 | /// The maximum value of a u64. 13 | #define U64_MAX UINT64_MAX 14 | 15 | /// would be nice if newlib had this already 16 | #ifndef SSIZE_MAX 17 | #ifdef SIZE_MAX 18 | #define SSIZE_MAX ((SIZE_MAX) >> 1) 19 | #endif 20 | #endif 21 | 22 | typedef uint8_t u8; ///< 8-bit unsigned integer 23 | typedef uint16_t u16; ///< 16-bit unsigned integer 24 | typedef uint32_t u32; ///< 32-bit unsigned integer 25 | typedef uint64_t u64; ///< 64-bit unsigned integer 26 | 27 | typedef int8_t s8; ///< 8-bit signed integer 28 | typedef int16_t s16; ///< 16-bit signed integer 29 | typedef int32_t s32; ///< 32-bit signed integer 30 | typedef int64_t s64; ///< 64-bit signed integer 31 | 32 | typedef volatile u8 vu8; ///< 8-bit volatile unsigned integer. 33 | typedef volatile u16 vu16; ///< 16-bit volatile unsigned integer. 34 | typedef volatile u32 vu32; ///< 32-bit volatile unsigned integer. 35 | typedef volatile u64 vu64; ///< 64-bit volatile unsigned integer. 36 | 37 | typedef volatile s8 vs8; ///< 8-bit volatile signed integer. 38 | typedef volatile s16 vs16; ///< 16-bit volatile signed integer. 39 | typedef volatile s32 vs32; ///< 32-bit volatile signed integer. 40 | typedef volatile s64 vs64; ///< 64-bit volatile signed integer. 41 | 42 | typedef u32 Handle; ///< Resource handle. 43 | typedef s32 Result; ///< Function result. 44 | typedef void (*ThreadFunc)(void *); ///< Thread entrypoint function. 45 | typedef void (*voidfn)(void); 46 | 47 | /// Creates a bitmask from a bit number. 48 | #define BIT(n) (1U<<(n)) 49 | 50 | // Fix intellisense errors 51 | #ifdef _MSC_VER 52 | 53 | #define ALIGN(m) 54 | #define PACKED 55 | #define USED 56 | #define UNUSED 57 | #define DEPRECATED 58 | #define NAKED 59 | #define NORETURN 60 | 61 | #else 62 | 63 | /// Aligns a struct (and other types?) to m, making sure that the size of the struct is a multiple of m. 64 | #define ALIGN(m) __attribute__((aligned(m))) 65 | /// Packs a struct (and other types?) so it won't include padding bytes. 66 | #define PACKED __attribute__((packed)) 67 | 68 | #define USED __attribute__((used)) 69 | #define UNUSED __attribute__((unused)) 70 | 71 | #ifndef LIBCTRU_NO_DEPRECATION 72 | /// Flags a function as deprecated. 73 | #define DEPRECATED __attribute__ ((deprecated)) 74 | #else 75 | /// Flags a function as deprecated. 76 | #define DEPRECATED 77 | #endif 78 | #define NAKED __attribute__((naked)) 79 | #define NORETURN __attribute__((noreturn)) 80 | 81 | #endif 82 | 83 | #define CUR_THREAD_HANDLE 0xFFFF8000 84 | #define CUR_PROCESS_HANDLE 0xFFFF8001 85 | 86 | /// Structure representing CPU registers 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /Includes/cheats.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CHEATS_H 2 | #define CHEATS_H 3 | 4 | #include 5 | #include "Helpers.hpp" 6 | #include "Helpers/QRCodeGen.hpp" 7 | #include "Unicode.h" 8 | 9 | namespace CTRPluginFramework 10 | { 11 | using StringVector = std::vector; 12 | //HELPERS 13 | #define TID_JPN 0x0004001000020700 14 | #define TID_USA 0x0004001000021700 15 | #define TID_EUR 0x0004001000022700 16 | #define TID_CHN 0x0004001000026700 17 | #define TID_KOR 0x0004001000027700 18 | #define TID_TWN 0x0004001000028700 19 | #define Miired 0xD21E14FF//0 20 | #define Miiorange 0xFF6E19FF//1 21 | #define Miiyellow 0xFFD820FF//2 22 | #define Miilime 0x78D220FF//3 23 | #define Miigreen 0x007830FF//4 24 | #define Miiblue 0x204898FF//5 25 | #define Miicyan 0x3CAADEFF//6 26 | #define Miipink 0xF55A7DFF//7 27 | #define Miipurple 0x7328ADFF//8 28 | #define Miibrown 0x483818FF//9 29 | #define Miiwhite 0xE0E0E0FF//10 30 | #define Miiblack 0x181814FF//11 31 | bool WriteNibble(u32 address, u8 value, bool right_side); 32 | bool ReadNibble(u32 address, u8 &value, bool right_side); 33 | bool IsValidPosition(u32 browpos, u32 browspace, u32 browrot, u32 browsize, u32 browidth, u32 eyepos, u32 eyespace, u32 eyerot, u32 eyesize, u32 eyewidth, u32 nosepos, u32 nosesize, u32 mouthpos, u32 mouthsize, u32 mouthwidth, u32 glasspos, u32 glassize, u32 stachepos, u32 stachesize, u32 molex, u32 moley, u32 molesize, u32 tall, u32 wide, u32 gold, u32 share, u8 nibble, u8 val); 34 | std::vector GetSubstrIndexList(std::string &str, std::string indexOf); 35 | void ReplaceSTR(std::string &str, const std::string &oldSTR, const std::string &newSTR, int substrIndex); 36 | std::string colorcolor(int pick); 37 | void miiEncode(std::vector &buf, int allowCopying, int profanityFlag, int regionLock, int characterSet, int pageIndex, int slotIndex, int version, int isGirl, int month, int day, int favColor, int isFavorite, int sharing, int faceShape, int skinColor, std::vector miiID, std::vector creatorMAC); 38 | bool ConvertString(u32 address, const char* input, size_t size, StringFormat format); 39 | std::size_t strlen(const std::string& str); 40 | //QR HELPERS 41 | typedef u8 DecMii[0x60]; 42 | typedef u8 EncMii[0x70]; 43 | #define MII_ENCSIZE 0x70 44 | #define MII_DECSIZE 0x60 45 | int encryptMii(DecMii *data, const char* outputFile); 46 | Result APT_Wrap(u32 outputSize, u32 inputSize, u32 blockSize, u32 nonceSize, void* input, void* output); 47 | void encrypt(void); 48 | void KORencrypt(void); 49 | void TWNencrypt(void); 50 | //STUFF 51 | void savetheme(MenuEntry *entry); 52 | void namedit(MenuEntry *entry); 53 | void OSD(MenuEntry *entry); 54 | void copymii(MenuEntry *entry); 55 | void dumpsave(MenuEntry *entry); 56 | void restoresave(MenuEntry *entry); 57 | void megamenu(MenuEntry *entry); 58 | void exitgame(MenuEntry *entry); 59 | void callencrypt(MenuEntry *entry); 60 | //CHN/TWN 61 | void TWNnamedit(MenuEntry *entry); 62 | void TWNOSD(MenuEntry *entry); 63 | void TWNcopymii(MenuEntry *entry); 64 | void TWNdumpsave(MenuEntry *entry); 65 | void TWNrestoresave(MenuEntry *entry); 66 | void TWNcallencrypt(MenuEntry *entry); 67 | //KOR 68 | void KORnamedit(MenuEntry *entry); 69 | void KOROSD(MenuEntry *entry); 70 | void KORcopymii(MenuEntry *entry); 71 | void KORdumpsave(MenuEntry *entry); 72 | void KORrestoresave(MenuEntry *entry); 73 | void KORcallencrypt(MenuEntry *entry); 74 | } 75 | #endif -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/Graphics/Color.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_COLOR_HPP 2 | #define CTRPLUGINFRAMEWORK_COLOR_HPP 3 | 4 | #include "types.h" 5 | #include 6 | #include 7 | 8 | namespace CTRPluginFramework 9 | { 10 | class Color 11 | { 12 | public: 13 | 14 | enum class BlendMode 15 | { 16 | Alpha, 17 | Add, 18 | Sub, 19 | Mul, 20 | None 21 | }; 22 | 23 | Color(void) : r(0), g(0), b(0), a(255) {} 24 | Color(u32 color); 25 | Color(u8 red, u8 green, u8 blue, u8 alpha = 255); 26 | 27 | u32 ToU32(void) const; 28 | Color &Fade(float fading); 29 | Color Blend(const Color &color, BlendMode mode) const; 30 | 31 | bool operator == (const Color &right) const; 32 | bool operator != (const Color &right) const; 33 | bool operator < (const Color &right) const; 34 | bool operator <= (const Color &right) const; 35 | bool operator > (const Color &right) const; 36 | bool operator >= (const Color &right) const; 37 | Color operator + (const Color &right) const; 38 | Color operator - (const Color &right) const; 39 | Color operator * (const Color &right) const; 40 | Color &operator += (const Color &right); 41 | Color &operator -= (const Color &right); 42 | Color &operator *= (const Color &right); 43 | 44 | operator std::string() const 45 | { 46 | char strColor[5] = { 0 }; 47 | 48 | strColor[0] = 0x1B; 49 | strColor[1] = std::max((u8)1, r); 50 | strColor[2] = std::max((u8)1, g); 51 | strColor[3] = std::max((u8)1, b); 52 | 53 | return strColor; 54 | } 55 | 56 | union 57 | { 58 | u32 raw; 59 | struct 60 | { 61 | u8 r; 62 | u8 g; 63 | u8 b; 64 | u8 a; 65 | }; 66 | }; 67 | 68 | // All those colors are from https://www.rapidtables.com/web/color/RGB_Color.html 69 | // Some basic colors constants 70 | static const Color Black; 71 | static const Color White; 72 | static const Color Red; 73 | static const Color Lime; 74 | static const Color Blue; 75 | static const Color Yellow; 76 | static const Color Cyan; 77 | static const Color Magenta; 78 | static const Color Silver; 79 | static const Color Gray; 80 | static const Color Maroon; 81 | static const Color Olive; 82 | static const Color Green; 83 | static const Color Purple; 84 | static const Color Teal; 85 | static const Color Navy; 86 | 87 | static const Color BlackGrey; 88 | static const Color Brown; 89 | static const Color DarkGrey; 90 | static const Color DeepSkyBlue; 91 | static const Color DimGrey; 92 | static const Color DodgerBlue; 93 | static const Color Gainsboro; 94 | static const Color ForestGreen; 95 | static const Color LimeGreen; 96 | static const Color Orange; 97 | static const Color SkyBlue; 98 | static const Color Turquoise; 99 | }; 100 | } 101 | 102 | #endif -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/System/Vector.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_VECTOR_HPP 2 | #define CTRPLUGINFRAMEWORK_VECTOR_HPP 3 | 4 | #include "types.h" 5 | 6 | namespace CTRPluginFramework 7 | { 8 | template 9 | class Vector 10 | { 11 | public: 12 | Vector(); 13 | Vector(T x, T y); 14 | template 15 | explicit Vector(const Vector &vector); 16 | 17 | T x; 18 | T y; 19 | }; 20 | 21 | template 22 | Vector::Vector() : x(0), y(0) 23 | { 24 | 25 | } 26 | 27 | template 28 | Vector::Vector(T x, T y) : x(x), y(y) 29 | { 30 | 31 | } 32 | 33 | template 34 | template 35 | Vector::Vector(const Vector &vector) : x(static_cast(vector.x)), y(static_cast(vector.y)) 36 | { 37 | 38 | } 39 | 40 | template 41 | Vector operator - (const Vector &vector) 42 | { 43 | return (Vector(-vector.x, -vector.y)); 44 | } 45 | 46 | template 47 | Vector operator - (const Vector &left, const Vector &right) 48 | { 49 | return (Vector(left.x - right.x, left.y - right.y)); 50 | } 51 | 52 | template 53 | Vector &operator -= (const Vector &left, const Vector &right) 54 | { 55 | left.x -= right.x; 56 | left.y -= right.y; 57 | return (left); 58 | } 59 | 60 | template 61 | Vector operator + (const Vector &left, const Vector &right) 62 | { 63 | return (Vector(left.x + right.x, left.y + right.y)); 64 | } 65 | 66 | template 67 | Vector &operator += (const Vector &left, const Vector &right) 68 | { 69 | left.x += right.x; 70 | left.y += right.y; 71 | return (left); 72 | } 73 | 74 | template 75 | Vector operator * (const Vector &left, T right) 76 | { 77 | return (Vector(left.x * right, left.y * right)); 78 | } 79 | 80 | template 81 | Vector operator * (const T left, const Vector &right) 82 | { 83 | return (Vector(right.x * left, right.y * left)); 84 | } 85 | 86 | template 87 | Vector &operator *= (Vector &left, const T right) 88 | { 89 | left.x *= right; 90 | left.y *= right; 91 | return (left); 92 | } 93 | 94 | template 95 | Vector operator / (const Vector &left, const T right) 96 | { 97 | return (Vector(left.x / right, left.y / right)); 98 | } 99 | 100 | template 101 | Vector &operator /= (Vector &left, const T right) 102 | { 103 | left.x /= right; 104 | left.y /= right; 105 | return (left); 106 | } 107 | 108 | template 109 | bool operator <= (const Vector &left, const Vector &right) 110 | { 111 | return (left.x <= right.x 112 | && left.y <= right.y); 113 | } 114 | 115 | template 116 | bool operator >= (const Vector &left, const Vector &right) 117 | { 118 | return (left.x >= right.x 119 | && left.y >= right.y); 120 | } 121 | 122 | typedef Vector UIntVector; 123 | typedef Vector IntVector; 124 | typedef Vector FloatVector; 125 | } 126 | 127 | #endif -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .SUFFIXES: 2 | 3 | ifeq ($(strip $(DEVKITARM)),) 4 | $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") 5 | endif 6 | 7 | TOPDIR ?= $(CURDIR) 8 | include $(DEVKITARM)/3ds_rules 9 | 10 | CTRPFLIB ?= $(CURDIR)/libctrpf 11 | 12 | TARGET := $(notdir $(CURDIR)) 13 | PLGINFO := CTRPluginFramework.plgInfo 14 | 15 | BUILD := Build 16 | INCLUDES := Includes 17 | SOURCES := Sources \ 18 | Sources/Helpers 19 | 20 | #--------------------------------------------------------------------------------- 21 | # options for code generation 22 | #--------------------------------------------------------------------------------- 23 | ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft 24 | 25 | CFLAGS := $(ARCH) -Os -mword-relocations \ 26 | -fomit-frame-pointer -ffunction-sections -fno-strict-aliasing 27 | 28 | CFLAGS += $(INCLUDE) -DARM11 -D_3DS_ 29 | 30 | CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11 31 | 32 | ASFLAGS := $(ARCH) 33 | LDFLAGS := -T $(TOPDIR)/3gx.ld $(ARCH) -Os -Wl,--gc-sections,--strip-discarded,--strip-debug 34 | 35 | LIBS := -lctrpf -lctru 36 | LIBDIRS := $(CTRPFLIB) $(CTRULIB) $(PORTLIBS) 37 | 38 | #--------------------------------------------------------------------------------- 39 | # no real need to edit anything past this point unless you need to add additional 40 | # rules for different file extensions 41 | #--------------------------------------------------------------------------------- 42 | ifneq ($(BUILD),$(notdir $(CURDIR))) 43 | #--------------------------------------------------------------------------------- 44 | 45 | export OUTPUT := $(CURDIR)/$(TARGET) 46 | export TOPDIR := $(CURDIR) 47 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ 48 | $(foreach dir,$(DATA),$(CURDIR)/$(dir)) 49 | 50 | export DEPSDIR := $(CURDIR)/$(BUILD) 51 | 52 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) 53 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) 54 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) 55 | 56 | export LD := $(CXX) 57 | export OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) 58 | export INCLUDE := $(foreach dir,$(INCLUDES),-I $(CURDIR)/$(dir) ) \ 59 | $(foreach dir,$(LIBDIRS),-I $(dir)/include) \ 60 | -I $(CURDIR)/$(BUILD) 61 | 62 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L $(dir)/lib) 63 | 64 | .PHONY: $(BUILD) clean all 65 | 66 | #--------------------------------------------------------------------------------- 67 | all: $(BUILD) 68 | 69 | $(BUILD): 70 | @[ -d $@ ] || mkdir -p $@ 71 | @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile 72 | 73 | #--------------------------------------------------------------------------------- 74 | clean: 75 | @echo clean ... 76 | @rm -fr $(BUILD) $(OUTPUT).3gx 77 | 78 | re: clean all 79 | 80 | #--------------------------------------------------------------------------------- 81 | 82 | else 83 | 84 | DEPENDS := $(OFILES:.o=.d) 85 | 86 | #--------------------------------------------------------------------------------- 87 | # main targets 88 | #--------------------------------------------------------------------------------- 89 | $(OUTPUT).3gx : $(OFILES) 90 | 91 | #--------------------------------------------------------------------------------- 92 | # you need a rule like this for each extension you use as binary data 93 | #--------------------------------------------------------------------------------- 94 | %.bin.o : %.bin 95 | #--------------------------------------------------------------------------------- 96 | @echo $(notdir $<) 97 | @$(bin2o) 98 | 99 | #--------------------------------------------------------------------------------- 100 | %.3gx: %.elf 101 | #--------------------------------------------------------------------------------- 102 | @echo creating $(notdir $@) 103 | @3gxtool -d $(word 1, $^) $(TOPDIR)/$(PLGINFO) $@ 104 | 105 | -include $(DEPENDS) 106 | 107 | #--------------------------------------------------------------------------------- 108 | endif 109 | -------------------------------------------------------------------------------- /3gx.ld: -------------------------------------------------------------------------------- 1 | 2 | OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") 3 | OUTPUT_ARCH(arm) 4 | ENTRY(_start) 5 | 6 | PHDRS 7 | { 8 | code PT_LOAD FLAGS(5) /* Read | Execute */; 9 | rodata PT_LOAD FLAGS(4) /* Read */; 10 | data PT_LOAD FLAGS(6) /* Read | Write */; 11 | } 12 | 13 | SECTIONS 14 | { 15 | /* =========== CODE section =========== */ 16 | 17 | PROVIDE(__start__ = 0x07000100); 18 | . = __start__; 19 | 20 | .text ALIGN(4) : 21 | { 22 | /* .init */ 23 | KEEP( *(.crt0) ) 24 | KEEP( *(.init) ) 25 | . = ALIGN(4); 26 | 27 | /* .text */ 28 | *(.text) 29 | *(.text.*) 30 | *(.glue_7) 31 | *(.glue_7t) 32 | *(.stub) 33 | *(.gnu.warning) 34 | *(.gnu.linkonce.t*) 35 | . = ALIGN(4); 36 | 37 | /* .fini */ 38 | KEEP( *(.fini) ) 39 | . = ALIGN(4); 40 | } : code 41 | 42 | /* =========== RODATA section =========== */ 43 | 44 | .rodata ALIGN(0x4) : 45 | { 46 | *(.rodata) 47 | *(.roda) 48 | *(.rodata.*) 49 | *all.rodata*(*) 50 | *(.gnu.linkonce.r*) 51 | SORT(CONSTRUCTORS) 52 | . = ALIGN(4); 53 | } : rodata 54 | 55 | .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } : rodata 56 | __exidx_start = .; 57 | ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } : rodata 58 | __exidx_end = .; 59 | 60 | /* =========== DATA section =========== */ 61 | 62 | .data ALIGN(4): 63 | { 64 | *(.data) 65 | *(.data.*) 66 | *(.gnu.linkonce.d*) 67 | CONSTRUCTORS 68 | . = ALIGN(4); 69 | } : data 70 | 71 | .tdata ALIGN(4) : 72 | { 73 | __tdata_lma = .; 74 | *(.tdata) 75 | *(.tdata.*) 76 | *(.gnu.linkonce.td.*) 77 | . = ALIGN(4); 78 | __tdata_lma_end = .; 79 | } : data 80 | 81 | .tbss ALIGN(4) : 82 | { 83 | *(.tbss) 84 | *(.tbss.*) 85 | *(.gnu.linkonce.tb.*) 86 | *(.tcommon) 87 | . = ALIGN(4); 88 | } : data 89 | 90 | .preinit_array ALIGN(4) : 91 | { 92 | PROVIDE (__preinit_array_start = .); 93 | KEEP (*(.preinit_array)) 94 | PROVIDE (__preinit_array_end = .); 95 | } : data 96 | 97 | .init_array ALIGN(4) : 98 | { 99 | PROVIDE (__init_array_start = .); 100 | KEEP (*(SORT(.init_array.*))) 101 | KEEP (*(.init_array)) 102 | PROVIDE (__init_array_end = .); 103 | } : data 104 | 105 | .fini_array ALIGN(4) : 106 | { 107 | PROVIDE (__fini_array_start = .); 108 | KEEP (*(.fini_array)) 109 | KEEP (*(SORT(.fini_array.*))) 110 | PROVIDE (__fini_array_end = .); 111 | } : data 112 | 113 | .ctors ALIGN(4) : 114 | { 115 | KEEP (*crtbegin.o(.ctors)) /* MUST be first -- GCC requires it */ 116 | KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) 117 | KEEP (*(SORT(.ctors.*))) 118 | KEEP (*(.ctors)) 119 | } : data 120 | 121 | .dtors ALIGN(4) : 122 | { 123 | KEEP (*crtbegin.o(.dtors)) 124 | KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) 125 | KEEP (*(SORT(.dtors.*))) 126 | KEEP (*(.dtors)) 127 | } : data 128 | 129 | __bss_start__ = .; 130 | .bss ALIGN(4) : 131 | { 132 | *(.dynbss) 133 | *(.bss) 134 | *(.bss.*) 135 | *(.gnu.linkonce.b*) 136 | *(COMMON) 137 | . = ALIGN(4); 138 | 139 | /* Reserve space for the TLS segment of the main thread */ 140 | __tls_start = .; 141 | . += + SIZEOF(.tdata) + SIZEOF(.tbss); 142 | __tls_end = .; 143 | } : data 144 | __bss_end__ = .; 145 | 146 | __end__ = ABSOLUTE(.) ; 147 | 148 | /* ================== 149 | ==== Metadata ==== 150 | ================== */ 151 | 152 | /* Discard sections that difficult post-processing */ 153 | /DISCARD/ : { *(.group .comment .note) } 154 | 155 | /* Stabs debugging sections. */ 156 | .stab 0 : { *(.stab) } 157 | .stabstr 0 : { *(.stabstr) } 158 | .stab.excl 0 : { *(.stab.excl) } 159 | .stab.exclstr 0 : { *(.stab.exclstr) } 160 | .stab.index 0 : { *(.stab.index) } 161 | .stab.indexstr 0 : { *(.stab.indexstr) } 162 | 163 | /* DWARF debug sections. 164 | Symbols in the DWARF debugging sections are relative to the beginning 165 | of the section so we begin them at 0. */ 166 | 167 | /* DWARF 1 */ 168 | .debug 0 : { *(.debug) } 169 | .line 0 : { *(.line) } 170 | 171 | /* GNU DWARF 1 extensions */ 172 | .debug_srcinfo 0 : { *(.debug_srcinfo) } 173 | .debug_sfnames 0 : { *(.debug_sfnames) } 174 | 175 | /* DWARF 1.1 and DWARF 2 */ 176 | .debug_aranges 0 : { *(.debug_aranges) } 177 | .debug_pubnames 0 : { *(.debug_pubnames) } 178 | 179 | /* DWARF 2 */ 180 | .debug_info 0 : { *(.debug_info) } 181 | .debug_abbrev 0 : { *(.debug_abbrev) } 182 | .debug_line 0 : { *(.debug_line) } 183 | .debug_frame 0 : { *(.debug_frame) } 184 | .debug_str 0 : { *(.debug_str) } 185 | .debug_loc 0 : { *(.debug_loc) } 186 | .debug_macinfo 0 : { *(.debug_macinfo) } 187 | } 188 | -------------------------------------------------------------------------------- /Sources/QRcheat.cpp: -------------------------------------------------------------------------------- 1 | 2 | /******************************************** 3 | * * 4 | * Most of this is from Goombi's CipherMii * 5 | * * 6 | * Also thanks to Redshyguy's Vapecord for * 7 | * the DrawQRCode function and more! * 8 | * * 9 | * haha funny header thing go brrrr * 10 | * * 11 | ********************************************/ 12 | 13 | #include "cheats.hpp"//QR code size: 4 modules, 3 pixels per module, Version 10, else default 14 | #include 15 | 16 | std::vector MiiVec; 17 | 18 | namespace CTRPluginFramework 19 | { 20 | 21 | Handle aptuHandle; 22 | 23 | void DrawQrCode(const Screen& screen, u32 posX, u32 posY, const u8* qrcode) { 24 | const u32 size_qr = qrcodegen_getSize(qrcode); 25 | u32 size_qr_s = size_qr; 26 | u32 size_canvas = size_qr + 8; 27 | 28 | //handle scaling 29 | u32 scale = 1; 30 | for(; size_canvas * (scale + 1) < 240; scale++); 31 | size_qr_s *= scale; 32 | size_canvas *= scale; 33 | 34 | //screen.DrawRect(posX - 5, posY - 5, size_canvas - 15, size_canvas - 15, Color::White); 35 | 36 | for(u32 y = 0; y <= size_qr_s; y++) { 37 | for(u32 x = 0; x <= size_qr_s; x++) { 38 | Color c = qrcodegen_getModule(qrcode, x / scale, y / scale) ? Color::Black : Color::White; 39 | screen.DrawRect(posX + x, posY + y, scale, scale, c); 40 | } 41 | } 42 | } 43 | 44 | Result APT_Wrap(u32 outputSize, u32 inputSize, u32 blockSize, u32 nonceSize, void* input, void* output) { 45 | u32* cmdbuf=getThreadCommandBuffer(); 46 | cmdbuf[0]=IPC_MakeHeader(0x46,4,4); // 0x470104 47 | cmdbuf[1]=outputSize; 48 | cmdbuf[2]=inputSize; 49 | cmdbuf[3]=blockSize; 50 | cmdbuf[4]=nonceSize; 51 | cmdbuf[5]=(inputSize << 4) | 0xA; 52 | cmdbuf[6]=(u32) input; 53 | cmdbuf[7]=(outputSize << 4) | 0xC; 54 | cmdbuf[8]=(u32) output; 55 | 56 | Result ret = 0; 57 | if(R_FAILED(ret=svcSendSyncRequest(aptuHandle))) 58 | return ret; 59 | 60 | return cmdbuf[1]; 61 | } 62 | 63 | int encryptMii(DecMii *data) { 64 | const Screen& BottomScreen = OSD::GetBottomScreen(); 65 | u8* output = new u8(); 66 | 67 | //Call APT_Wrap 68 | if(!R_SUCCEEDED(APT_Wrap(MII_ENCSIZE, MII_DECSIZE, 12, 10, data, output))) { 69 | OSD::Notify("ERROR: Failed to encrypt the input."); 70 | return 1; 71 | } 72 | 73 | //Make QR code 74 | u8 qrcode[qrcodegen_BUFFER_LEN_MAX]; 75 | u8 temp[qrcodegen_BUFFER_LEN_MAX]; 76 | 77 | if(qrcodegen_encodeBinary(output, MII_ENCSIZE, qrcode, qrcodegen_Ecc_LOW, 10, 10, qrcodegen_Mask_AUTO, true)) { 78 | DrawQrCode(BottomScreen, 73, 33, qrcode); 79 | MessageBox("Here is your QR code.\nIt will disappear when you press \"Ok\"")(); 80 | Sleep(Milliseconds(200)); 81 | } 82 | delete[] output; 83 | return 0; 84 | } 85 | 86 | void encrypt(void) { 87 | const Screen& BottomScreen = OSD::GetBottomScreen(); 88 | u8 val; 89 | std::string name; 90 | DecMii *data = nullptr; 91 | 92 | srvGetServiceHandle(&aptuHandle, "APT:U"); 93 | 94 | if(*(u32 *)0x88B2B28 != 0xFFFFFFFF && (*(u16 *)0x88014D5 == 0)) { 95 | if(Process::Read8(0x88014D4, val)) { 96 | data = (DecMii *)((0x5C * val) + 0x14895A28); 97 | Process::ReadString((0x5C * val) + (0x14895A20 + 0x22), name, 20, StringFormat::Utf16); 98 | Sleep(Milliseconds(100)); 99 | encryptMii(data); 100 | } 101 | } 102 | 103 | svcCloseHandle(aptuHandle); 104 | } 105 | void KORencrypt(void) { 106 | const Screen& BottomScreen = OSD::GetBottomScreen(); 107 | u8 val; 108 | std::string name; 109 | DecMii *data = nullptr; 110 | 111 | srvGetServiceHandle(&aptuHandle, "APT:U"); 112 | 113 | if (*(u32 *)0x8032218 != 0xFFFFFFFF && (*(u16 *)0x88014D5 == 0)) { 114 | if(Process::Read8(0x88014D4, val)) { 115 | data = (DecMii *)((0x5C * val) + 0x1488B7A8); 116 | Process::ReadString((0x5C * val) + (0x1488B7A0 + 0x22), name, 20, StringFormat::Utf16); 117 | Sleep(Milliseconds(100)); 118 | encryptMii(data); 119 | } 120 | } 121 | 122 | svcCloseHandle(aptuHandle); 123 | } 124 | void TWNencrypt(void) { 125 | const Screen& BottomScreen = OSD::GetBottomScreen(); 126 | u8 val; 127 | std::string name; 128 | DecMii *data = nullptr; 129 | 130 | srvGetServiceHandle(&aptuHandle, "APT:U"); 131 | 132 | if (*(u32 *)0x8AF73A4 == 0xB88C50 && (*(u16 *)0x88014D5 == 0)) { 133 | if(Process::Read8(0x88014D4, val)) { 134 | data = (DecMii *)((0x5C * val) + 0x1488B928); 135 | Process::ReadString((0x5C * val) + (0x1488B920 + 0x22), name, 20, StringFormat::Utf16); 136 | Sleep(Milliseconds(100)); 137 | encryptMii(data); 138 | } 139 | } 140 | 141 | svcCloseHandle(aptuHandle); 142 | } 143 | } -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/Menu/MenuEntryHotkeys.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_MENUENTRYHOTKEYS_HPP 2 | #define CTRPLUGINFRAMEWORK_MENUENTRYHOTKEYS_HPP 3 | 4 | #include "types.h" 5 | 6 | #include 7 | #include 8 | 9 | namespace CTRPluginFramework 10 | { 11 | class MenuEntry; 12 | class Hotkey 13 | { 14 | public: 15 | 16 | Hotkey(); 17 | 18 | /** 19 | * \brief Create a new Hotkey 20 | * \param keys The default keys of this hotkey 21 | * \param name The name for this hotkey \n 22 | * Appear on the note and on the Hotkey selector when the user want to edit an hotkey 23 | */ 24 | Hotkey(u32 keys, const std::string &name); 25 | ~Hotkey(); 26 | 27 | /** 28 | * \brief Change the keys value of the hotkey 29 | * \param keys the new keys value of the hotkey 30 | */ 31 | void operator=(u32 keys); 32 | 33 | /** 34 | * \brief Change the name of the hotkey 35 | * \param name The new name you want to appear on the note / the HotkeyModifier selector 36 | */ 37 | void operator=(const std::string &name); 38 | 39 | /** 40 | * \brief Check if the keys of this Hotkey are currently down 41 | * \return If the keys are down 42 | */ 43 | bool IsDown(void) const; 44 | 45 | /** 46 | * \brief Check if the keys of this Hotkey are pressed 47 | * \return If the keys were just being pressed 48 | */ 49 | bool IsPressed(void) const; 50 | 51 | /** 52 | * \brief Display a control for the user to select the keys 53 | */ 54 | void AskForKeys(void); 55 | 56 | /** 57 | * \brief Get the keys value of this Hotkey 58 | * \return the keys value 59 | */ 60 | u32 GetKeys(void); 61 | 62 | /** 63 | * \brief Stringify the Hotkey 64 | * \param withName if the name of the Hotkey must be in the result 65 | * \return return a string of this Hotkey\n 66 | * if withName is false then the output will simply be the Key's value: "A + B" 67 | * if withName is true the output will be: "Hotkey's name : A + B" 68 | */ 69 | std::string ToString(bool withName = false) const; 70 | 71 | private: 72 | friend class HotkeyManager; 73 | friend class PluginMenuImpl; 74 | u32 _keys; 75 | std::string _name; 76 | }; 77 | 78 | class MenuEntry; 79 | class HotkeyManager 80 | { 81 | public: 82 | /** 83 | * \brief A callback type, the args are: 84 | * MenuEntry *: the entry that own the Hotkey 85 | * int : the index in the HotkeyManager of the hotkey that changed 86 | */ 87 | using OnHotkeyChangeClbk = void(*)(MenuEntry*, int); 88 | 89 | HotkeyManager(MenuEntry *owner); 90 | ~HotkeyManager(); 91 | 92 | /** 93 | * \brief Add an hotkey to the manager 94 | * \param hotkey The Hotkey to add 95 | */ 96 | void operator+=(const Hotkey &hotkey); 97 | 98 | /** 99 | * \brief Return a reference to the Hotkey from the manager 100 | * \param index The index of the Hotkey you want from the manager 101 | * \return A reference to the desired Hotkey 102 | */ 103 | Hotkey &operator[](u32 index); 104 | 105 | /** 106 | * \brief Return a reference to the Hotkey from the manager 107 | * \param name The name of the Hotkey you want from the manager 108 | * \return A reference to the desired Hotkey 109 | */ 110 | Hotkey &operator[](const std::string& name); 111 | 112 | /** 113 | * \brief Stringify all Hotkeys 114 | * \return a string with all the Hotkey as string 115 | */ 116 | std::string ToString(void); 117 | 118 | /** 119 | * \brief Display a control that allows the user to select which Hotkey he wants to edit 120 | */ 121 | void AskForKeys(void); 122 | 123 | /** 124 | * \brief Add a callback that be called when an Hotkey will change 125 | * \param callback The callback to call 126 | */ 127 | void OnHotkeyChangeCallback(OnHotkeyChangeClbk callback); 128 | 129 | /** 130 | * \brief Get how many Hotkeys the manager currently have 131 | * \return The count of Hotkeys 132 | */ 133 | u32 Count(void); 134 | 135 | private: 136 | friend class PluginMenuHome; 137 | friend class PluginMenuImpl; 138 | 139 | MenuEntry *_owner; 140 | OnHotkeyChangeClbk _callback; 141 | std::vector _hotkeys; 142 | 143 | }; 144 | } 145 | 146 | #endif 147 | -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/System/Rect.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_RECT_HPP 2 | #define CTRPLUGINFRAMEWORK_RECT_HPP 3 | 4 | #include "CTRPluginFramework/System/Vector.hpp" 5 | #include 6 | 7 | namespace CTRPluginFramework 8 | { 9 | template 10 | class Rect 11 | { 12 | public: 13 | Rect(); 14 | Rect(const Vector& leftTop, const Vector& size); 15 | Rect(const Vector& leftTop, T width, T height); 16 | Rect(T left, T top, const Vector& size); 17 | Rect(T left, T top, T width, T height); 18 | template 19 | explicit Rect(const Rect& rect); 20 | 21 | bool Contains(T x, T y) const; 22 | bool Contains(const Vector& point) const; 23 | bool Intersects(const Rect& rect) const; 24 | bool Intersects(const Rect& rect, Rect& intersect) const; 25 | 26 | Vector leftTop; 27 | Vector size; 28 | }; 29 | 30 | template 31 | Rect::Rect() : leftTop(0, 0), size(0, 0) 32 | { 33 | 34 | } 35 | 36 | template 37 | Rect::Rect(const Vector& leftTopCorner, const Vector& size) 38 | { 39 | leftTop = leftTopCorner; 40 | this->size = size; 41 | } 42 | 43 | template 44 | Rect::Rect(const Vector& leftTopCorner, T width, T height) 45 | { 46 | leftTop = leftTopCorner; 47 | size.x = width; 48 | size.y = height; 49 | } 50 | 51 | template 52 | Rect::Rect(T left, T top, const Vector& size) 53 | { 54 | leftTop.x = left; 55 | leftTop.y = top; 56 | this->size = size; 57 | } 58 | 59 | template 60 | Rect::Rect(T left, T top, T width, T height) 61 | { 62 | leftTop.x = left; 63 | leftTop.y = top; 64 | size.x = width; 65 | size.y = height; 66 | } 67 | 68 | template 69 | template 70 | Rect::Rect(const Rect& rect) 71 | { 72 | leftTop = reinterpret_cast(rect.leftTop); 73 | size = reinterpret_cast(rect.size); 74 | } 75 | 76 | template 77 | bool Rect::Contains(T x, T y) const 78 | { 79 | T minX = std::min(leftTop.x, leftTop.x + size.x); 80 | T maxX = std::max(leftTop.x, leftTop.x + size.x); 81 | T minY = std::min(leftTop.y, leftTop.y + size.y); 82 | T maxY = std::max(leftTop.y, leftTop.y + size.y); 83 | 84 | return (x >= minX && x < maxX 85 | && y >= minY && y < maxY); 86 | } 87 | 88 | template 89 | bool Rect::Contains(const Vector& point) const 90 | { 91 | return (Contains(point.x, point.y)); 92 | } 93 | 94 | template 95 | bool Rect::Intersects(const Rect& rect) const 96 | { 97 | Rect intersect; 98 | return (Intersects(rect, intersect)); 99 | } 100 | 101 | template 102 | bool Rect::Intersects(const Rect &rect, Rect &intersect) const 103 | { 104 | T thisMinX = std::min(leftTop.x, leftTop.x + size.x); 105 | T thisMaxX = std::max(leftTop.x, leftTop.x + size.x); 106 | T thisMinY = std::min(leftTop.y, leftTop.y + size.y); 107 | T thisMaxY = std::max(leftTop.y, leftTop.y + size.y); 108 | T rectMinX = std::min(rect.leftTop.x, rect.leftTop.x + rect.size.x); 109 | T rectMaxX = std::max(rect.leftTop.x, rect.leftTop.x + rect.size.x); 110 | T rectMinY = std::min(rect.leftTop.y, rect.leftTop.y + rect.size.y); 111 | T rectMaxY = std::max(rect.leftTop.y, rect.leftTop.y + rect.size.y); 112 | 113 | T intersectLeftX = std::max(thisMinX, rectMinX); 114 | T intersectLeftY = std::max(thisMinY, rectMinY); 115 | T intersectRightX = std::min(thisMaxX, rectMaxX); 116 | T intersectRightY = std::min(thisMaxY, rectMaxY); 117 | 118 | if (intersectLeftX < intersectRightX && intersectLeftY < intersectRightY) 119 | { 120 | intersect = Rect(intersectLeftX, intersectLeftY, intersectRightX - intersectLeftX, 121 | intersectRightY - intersectLeftY); 122 | return (true); 123 | } 124 | intersect = Rect(0, 0, 0, 0); 125 | return (false); 126 | } 127 | 128 | template 129 | bool operator ==(Rect &left, Rect &right) 130 | { 131 | return (left.leftTop == right.leftTop 132 | && left.size == right.size); 133 | } 134 | 135 | template 136 | bool operator !=(Rect &left, Rect &right) 137 | { 138 | return (left.leftTop != right.leftTop 139 | && left.size != right.size); 140 | } 141 | 142 | typedef Rect UIntRect; 143 | typedef Rect IntRect; 144 | typedef Rect FloatRect; 145 | } 146 | 147 | #endif -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > [!caution] 2 | > This plugin is very poorly programmed and will have to be completely rewritten to achieve stability. 3 | > Please read the [issues](https://github.com/FoofooTheGuy/Miichanic_Plugin/issues) to understand the risks in using this unmaintained piece of DOODOO. 4 | > If possible, please do not even attempt to use it. 5 | > There is no estimate on when the rewrite will begin. 6 | 7 | 8 |

9 | 10 |

11 | 12 | # Miichanic's Tool Box 13 | A Luma3DS plugin for the Title Mii Maker that uses CTRPF 0.7.0 and supports every region. 14 | 15 | 16 | # Installation guide: 17 | (You will need to first install Custom Firmware to use this plugin) 18 | 19 | Method 1 (Assisted installation using a Windows PC): 20 | --- 21 | 22 | - If you use a Windows PC, (Windows 7 and above), then you can do this simple method! 23 | 24 | 1. Turn off your console and put your SD card into your computer 25 | 26 | 2. Download and run the [Miichanics-Tool-Box-Installer](https://github.com/FoofooTheGuy/Miichanic_Plugin/releases/latest/download/Miichanics-Tool-Box-Installer.exe) program, and follow the instructions there. Come back here when it is finished. 27 | 3. Put your SD card back into your console and open the rosalina menu (L + D-pad down + select by default) and enable the plugin loader (4th option) 28 | 4. Launch Mii maker, and the screen will flash a light blue color and the message "Plugin ready!" shall appear soon after. 29 | 30 | Method 2 (Manual installation): 31 | --- 32 | 1. Turn off your console and put your SD card into your computer 33 | 2. Download the latest boot.firm file for [Luma3DS](https://github.com/LumaTeam/Luma3DS/releases/latest) and 34 | replace the boot.firm on your SD card root with that one. 35 | 3. Create a folder called "plugins" (without quotes) in the luma folder that is on your SD card root (SD:/luma/plugins/) 36 | 4. Create a folder corresponding to your game title ID in the plugins folder: 37 | 38 | Japan: SD:/luma/plugins/0004001000020700/ 39 | 40 | USA: SD:/luma/plugins/0004001000021700/ 41 | 42 | Europe: SD:/luma/plugins/0004001000022700/ 43 | 44 | China: SD:/luma/plugins/0004001000026700/ 45 | 46 | Korea: SD:/luma/plugins/0004001000027700/ 47 | 48 | Taiwan: SD:/luma/plugins/0004001000028700/ 49 | 50 | 5. Place [Miichanic.3gx](https://github.com/FoofooTheGuy/Miichanic_Plugin/releases/latest/download/Miichanic.3gx) in that folder (E.g. SD:/luma/plugins/0004001000020700/Miichanic.3gx) 51 | 6. Put your SD card back into your console and open the rosalina menu (L + D-pad down + select by default) and enable the plugin loader (4th option) 52 | 7. Launch Mii maker, and the screen will flash a light blue color and the message "Plugin ready!" shall appear soon after. 53 | 54 | Press select to open the menu. 55 | # Features: 56 | 57 | # (Directory for Editor codes) 58 | 59 | Nickname / Creator Modifier 60 | 61 | Copy and paste Mii data 62 | 63 | (End of directory) 64 | 65 | # (Directory for Save file options) 66 | 67 | Dump save file 68 | 69 | Restore save file 70 | 71 | Mega menu 72 | 73 | Create Mii QR code 74 | 75 | # Mega menu contains: 76 | 77 | Change name 78 | 79 | Change creator 80 | 81 | Toggle gender 82 | 83 | Change favorite color 84 | 85 | Change birth day 86 | 87 | Toggle favorite 88 | 89 | Toggle sharing 90 | 91 | Toggle copying 92 | 93 | Toggle gold pants 94 | 95 | Take ownership 96 | 97 | Swap with personal Mii 98 | 99 | Delete Mii 100 | 101 | (End of directory) 102 | 103 | # (Root of menu) 104 | 105 | Useless OSD 106 | 107 | Toggle theme 108 | 109 | Exit to home menu 110 | # Screenshots: 111 | Dark theme (default) and Light theme (ugly) 112 | 113 | ![first](https://user-images.githubusercontent.com/32585652/130987833-675f510d-0dfe-4c21-964e-490167394066.png) 114 | ![second](https://user-images.githubusercontent.com/32585652/130987860-290ce40d-830e-4aac-9eba-a7fd4b618530.png) 115 | 116 | Mega Menu: 117 | 118 | ![megalong](https://user-images.githubusercontent.com/32585652/145294918-89fb4220-dbbb-4a4a-a785-fa4874113009.png) 119 | 120 | Change Favorite color: 121 | 122 | ![ChangeColor](https://user-images.githubusercontent.com/32585652/133910032-470f58b3-5c04-442c-a9d7-04b0fc8f6ea0.png) 123 | 124 | JP/US/EU menu: 125 | 126 | ![JPUSEU](https://user-images.githubusercontent.com/32585652/130695895-75d2d25c-03b3-4963-95b6-aac232aab580.png) 127 | 128 | CHN/TWN menu on the CHN version and on the TWN version: 129 | 130 | ![CHNTWN](https://user-images.githubusercontent.com/32585652/130695992-10242923-a364-45d1-ba59-bce55d4a8a1b.png) 131 | ![TWN](https://user-images.githubusercontent.com/32585652/130696044-32db5ee2-a9b1-4379-95ef-c5b648c34e92.png) 132 | 133 | KOR menu: 134 | 135 | ![KOR](https://user-images.githubusercontent.com/32585652/130696091-d48ac080-61a7-4f96-afb0-2d9fbd8988c6.png) 136 | 137 | # Building 138 | 139 | install [this](https://mega.nz/file/bzRU1BaA#rwaZNp-_iki1dEwz-rAWrlG67TAg5nW5NxmQSBgBUnE) version of devkitpro and then run [build.bat](https://github.com/FoofooTheGuy/Miichanic_Plugin/blob/main/build.bat) 140 | -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/System/Time.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_TIME_HPP 2 | #define CTRPLUGINFRAMEWORK_TIME_HPP 3 | 4 | namespace CTRPluginFramework 5 | { 6 | class Time 7 | { 8 | public : 9 | 10 | constexpr Time(void) : _ticks(0) {} 11 | 12 | 13 | float AsSeconds(void) const; 14 | 15 | int AsMilliseconds(void) const; 16 | 17 | s64 AsMicroseconds(void) const; 18 | 19 | inline s64 AsTicks(void) const { return _ticks; } 20 | 21 | static const Time Zero; ///< Predefined "zero" time value 22 | 23 | static constexpr u32 TicksPerSecond = 268111856U; 24 | 25 | private : 26 | 27 | friend constexpr Time Seconds(float amount); 28 | friend constexpr Time Milliseconds(int amount); 29 | friend constexpr Time Microseconds(s64 amount); 30 | friend constexpr Time Ticks(s64 amount); 31 | 32 | constexpr Time(s64 ticks) : _ticks(ticks) {} 33 | 34 | private : 35 | 36 | 37 | s64 _ticks; 38 | }; 39 | 40 | constexpr Time Seconds(float amount) 41 | { 42 | return (Time(static_cast(amount * Time::TicksPerSecond))); 43 | } 44 | 45 | 46 | constexpr Time Milliseconds(int amount) 47 | { 48 | return (Time(static_cast(amount * (Time::TicksPerSecond / 1000.f)))); 49 | } 50 | 51 | 52 | constexpr Time Microseconds(s64 amount) 53 | { 54 | return (Time(static_cast(amount * (Time::TicksPerSecond / 1000000.f)))); 55 | } 56 | 57 | constexpr Time Ticks(s64 amount) 58 | { 59 | return (Time(amount)); 60 | } 61 | 62 | inline bool operator ==(Time left, Time right) 63 | { 64 | return (left.AsTicks() == right.AsTicks()); 65 | } 66 | 67 | 68 | inline bool operator !=(Time left, Time right) 69 | { 70 | return (left.AsTicks() != right.AsTicks()); 71 | } 72 | 73 | 74 | inline bool operator <(Time left, Time right) 75 | { 76 | return (left.AsTicks() < right.AsTicks()); 77 | } 78 | 79 | 80 | inline bool operator >(Time left, Time right) 81 | { 82 | return (left.AsTicks() > right.AsTicks()); 83 | } 84 | 85 | 86 | inline bool operator <=(Time left, Time right) 87 | { 88 | return (left.AsTicks() <= right.AsTicks()); 89 | } 90 | 91 | inline bool operator >=(Time left, Time right) 92 | { 93 | return (left.AsTicks() >= right.AsTicks()); 94 | } 95 | 96 | inline Time operator -(Time right) 97 | { 98 | return (Ticks(-right.AsTicks())); 99 | } 100 | 101 | 102 | inline Time operator +(Time left, Time right) 103 | { 104 | return (Ticks(left.AsTicks() + right.AsTicks())); 105 | } 106 | 107 | 108 | inline Time& operator +=(Time& left, Time right) 109 | { 110 | return (left = left + right); 111 | } 112 | 113 | 114 | inline Time operator -(Time left, Time right) 115 | { 116 | return (Ticks(left.AsTicks() - right.AsTicks())); 117 | } 118 | 119 | 120 | inline Time& operator -=(Time& left, Time right) 121 | { 122 | return left = left - right; 123 | } 124 | 125 | 126 | inline Time operator *(Time left, float right) 127 | { 128 | return (Seconds(left.AsSeconds() * right)); 129 | } 130 | 131 | 132 | inline Time operator *(Time left, s64 right) 133 | { 134 | return (Microseconds(left.AsMicroseconds() * right)); 135 | } 136 | 137 | 138 | inline Time operator *(float left, Time right) 139 | { 140 | return (right * left); 141 | } 142 | 143 | 144 | inline Time operator *(s64 left, Time right) 145 | { 146 | return (right * left); 147 | } 148 | 149 | 150 | inline Time& operator *=(Time& left, float right) 151 | { 152 | return (left = left * right); 153 | } 154 | 155 | 156 | inline Time& operator *=(Time& left, s64 right) 157 | { 158 | return (left = left * right); 159 | } 160 | 161 | 162 | inline Time operator /(Time left, float right) 163 | { 164 | return Seconds(left.AsSeconds() / right); 165 | } 166 | 167 | 168 | inline Time operator /(Time left, s64 right) 169 | { 170 | return (Microseconds(left.AsMicroseconds() / right)); 171 | } 172 | 173 | 174 | inline Time& operator /=(Time& left, float right) 175 | { 176 | return (left = left / right); 177 | } 178 | 179 | 180 | inline Time& operator /=(Time& left, s64 right) 181 | { 182 | return (left = left / right); 183 | } 184 | 185 | 186 | inline float operator /(Time left, Time right) 187 | { 188 | return (left.AsSeconds() / right.AsSeconds()); 189 | } 190 | 191 | 192 | inline Time operator %(Time left, Time right) 193 | { 194 | return (Ticks(left.AsTicks() % right.AsTicks())); 195 | } 196 | 197 | 198 | inline Time& operator %=(Time& left, Time right) 199 | { 200 | return (left = left % right); 201 | } 202 | 203 | } 204 | 205 | #endif 206 | -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/Menu/MenuEntry.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_MENUENTRY_HPP 2 | #define CTRPLUGINFRAMEWORK_MENUENTRY_HPP 3 | 4 | #include "MenuEntryHotkeys.hpp" 5 | 6 | #include 7 | #include 8 | 9 | namespace CTRPluginFramework 10 | { 11 | #ifndef SEPARATOR_TYPE 12 | #define SEPARATOR_TYPE 13 | enum class Separator 14 | { 15 | None, 16 | Filled, 17 | Stippled 18 | }; 19 | #endif 20 | 21 | class MenuEntryImpl; 22 | class MenuEntry 23 | { 24 | using FuncPointer = void(*)(MenuEntry*); 25 | public: 26 | 27 | explicit MenuEntry(const std::string &name, const std::string ¬e = ""); 28 | MenuEntry(const std::string &name, FuncPointer gameFunc, const std::string ¬e = ""); 29 | MenuEntry(const std::string &name, FuncPointer gameFunc, FuncPointer menuFunc, const std::string ¬e = ""); 30 | MenuEntry(int radioGroup, const std::string &name, FuncPointer gameFunc, const std::string ¬e = ""); 31 | MenuEntry(int radioGroup, const std::string &name, FuncPointer gameFunc, FuncPointer menuFunc, const std::string ¬e = ""); 32 | ~MenuEntry(); 33 | 34 | /** 35 | * \brief Enable the entry (the gamefunction linked to it will be executed) 36 | * \param 37 | */ 38 | void Enable(void) const; 39 | 40 | /** 41 | * \brief Disable the entry 42 | * \param 43 | */ 44 | void Disable(void) const; 45 | 46 | /** 47 | * \brief Hide the entry from the menu. The entry will also be disabled 48 | */ 49 | void Hide(void) const; 50 | 51 | /** 52 | * \brief Unhide an entry previously hidden 53 | */ 54 | void Show(void) const; 55 | /** 56 | * \brief Set the entry as a radio entry and link it to a radio group ID 57 | * \param id The id of the radio group to be linked to 58 | */ 59 | void SetRadio(int id) const; 60 | /** 61 | * \brief Set a value for entry's argument 62 | * \param The value of the argument 63 | */ 64 | void SetArg(void *arg) const; 65 | 66 | /** 67 | * \brief Get the value of this entry's argument 68 | * \return The value of the argument 69 | */ 70 | void *GetArg(void) const; 71 | 72 | /** 73 | * \brief Check if this entry was just activated (first gamefunction execution) 74 | * \return true if the entry was just activated 75 | */ 76 | bool WasJustActivated(void) const; 77 | 78 | /** 79 | * \brief Check if this entry is activated 80 | * \return true if the entry is activated, false otherwise 81 | */ 82 | bool IsActivated(void) const; 83 | 84 | /** 85 | * \brief Check if this entry is visible in the menu 86 | * \return true if the entry is visible, false if the entry is hidden 87 | */ 88 | bool IsVisible(void) const; 89 | 90 | /** 91 | * \brief Set if this entry must display a separator on top of the entry 92 | * \param type Type of separator to display 93 | */ 94 | void UseTopSeparator(Separator type = Separator::Filled) const; 95 | 96 | /** 97 | * \brief Set if this entry must display a separator at the bottom of the entry 98 | * \param type Type of separator to display 99 | */ 100 | void UseBottomSeparator(Separator type = Separator::Filled) const; 101 | 102 | /** 103 | * \brief Set if the entry can be selected in the menu or not.\n 104 | * If the entry is Activated and the state is set to unselectable, the entry will be disabled 105 | * \param canBeSelected 106 | */ 107 | void CanBeSelected(bool canBeSelected) const; 108 | 109 | /** 110 | * \brief Set the gamefunction of this entry 111 | * \param func The new function to be executed on game loop 112 | */ 113 | void SetGameFunc(FuncPointer func) const; 114 | 115 | /** 116 | * \brief Set the menu funuction of this entry 117 | * \param func The new function to be executed on the menu 118 | */ 119 | void SetMenuFunc(FuncPointer func) const; 120 | 121 | /** 122 | * \brief Force the menu to refresh the note 123 | */ 124 | void RefreshNote(void) const; 125 | 126 | /** 127 | * \brief Get the entry's name string 128 | * \return A reference to current name 129 | */ 130 | std::string &Name(void) const; 131 | 132 | /** 133 | * \brief Get the entry's note string 134 | * \return A reference to current note 135 | */ 136 | std::string &Note(void) const; 137 | 138 | /** 139 | * \brief The hotkey manager of this entry. See MenuEntryHotkeys.hpp for more infos 140 | */ 141 | HotkeyManager Hotkeys; 142 | 143 | private: 144 | friend class MenuFolder; 145 | friend class PluginMenu; 146 | std::unique_ptr _item; 147 | }; 148 | } 149 | 150 | #endif 151 | -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/Graphics/OSD.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_OSD_HPP 2 | #define CTRPLUGINFRAMEWORK_OSD_HPP 3 | 4 | #include "CTRPluginFramework/Graphics/Color.hpp" 5 | #include <3ds.h> 6 | #include 7 | 8 | namespace CTRPluginFramework 9 | { 10 | using GSPFormat = GSPGPU_FramebufferFormat; 11 | 12 | class Screen 13 | { 14 | public: 15 | bool IsTop; 16 | bool Is3DEnabled; 17 | u32 LeftFramebuffer; 18 | u32 RightFramebuffer; 19 | u32 Stride; 20 | u32 BytesPerPixel; 21 | GSPFormat Format; 22 | 23 | /** 24 | * \brief Get a pointer to the screen's framebuffer 25 | * \param posX The position on the screen to point to 26 | * \param posY The position on the screen to point to 27 | * \param useRightFb If the function must return a pointer to the right framebuffer 28 | * \return A pointer to the screen's framebuffer at the desired position 29 | */ 30 | u8 * GetFramebuffer(u32 posX, u32 posY, bool useRightFb = false) const; 31 | 32 | /** 33 | * \brief Draw a string using Linux's font 34 | * \param str The string to draw 35 | * \param posX The position on screen to draw the string to 36 | * \param posY The position on screen to draw the string to 37 | * \param foreground The color of the characters 38 | * \param background The color of the background 39 | * \return posY + 10 (line feed) 40 | */ 41 | u32 Draw(const std::string &str, u32 posX, u32 posY, const Color &foreground = Color::White, const Color &background = Color::Black) const; 42 | 43 | /** 44 | * \brief Draw a string using system font (support utf8 strings with special chars & unicode) 45 | * \param str The string to draw 46 | * \param posX The position on screen to draw the string to 47 | * \param posY The position on screen to draw the string to 48 | * \param foreground The color of the characters 49 | * \return posY + 16 (line feed) 50 | */ 51 | u32 DrawSysfont(const std::string &str, u32 posX, u32 posY, const Color &foreground = Color::White) const; 52 | 53 | /** 54 | * \brief Draw a rectangle 55 | * \param posX The position on screen to draw the rectangle 56 | * \param posY The position on screen to draw the rectangle 57 | * \param width The width of the rectangle 58 | * \param height The height of the rectangle 59 | * \param color The color of the rectangle 60 | * \param filled If the rectangle is filled or if the function should only draw the border 61 | */ 62 | void DrawRect(u32 posX, u32 posY, u32 width, u32 height, const Color &color, bool filled = true) const; 63 | /** 64 | * \brief Change the color of a pixel at the desired X, Y position 65 | * \param posX The X position of the pixel to change 66 | * \param posY The Y position of the pixel to change 67 | * \param color The new color of the pixel 68 | */ 69 | void DrawPixel(u32 posX, u32 posY, const Color &color) const; 70 | 71 | /** 72 | * \brief Get the current color of a pixel at X, Y position 73 | * \param posX The X position of the pixel to read 74 | * \param posY The Y position of the pixel to read 75 | * \param pixel The output color of the pixel 76 | * \param fromRightFb If the pixel must be read from the right framebuffer 77 | */ 78 | void ReadPixel(u32 posX, u32 posY, Color &pixel, bool fromRightFb = false) const; 79 | 80 | private: 81 | friend class OSDImpl; 82 | Screen() {}; 83 | }; 84 | 85 | using OSDCallback = bool(*)(const Screen &); 86 | class OSD 87 | { 88 | public: 89 | 90 | /** 91 | * \brief Send a notification on the top screen, a notification duration is 5 seconds\n 92 | * A maximum of 50 notifications can be queued 93 | * \param str Text of the notification 94 | * \param foreground The color of the text (Default: blank) 95 | * \param background The color of the background (Default: black) 96 | * \return 0 if success, -1 if the notification couldn't be added 97 | */ 98 | static int Notify(const std::string &str, const Color &foreground = Color::White, const Color &background = Color::Black); 99 | 100 | /** 101 | * \brief Add a callback to the OSD system which will be called at each game's frame 102 | * \param cb The callback to add 103 | */ 104 | static void Run(OSDCallback cb); 105 | 106 | /** 107 | * \brief Remove a callback from the OSD system 108 | * \param cb The callback to remove 109 | */ 110 | static void Stop(OSDCallback cb); 111 | 112 | /** 113 | * \brief Returns the width in pixels of the specified string 114 | * \param sysfont Which font will be used to compute the width 115 | * \param text 116 | * \return The width in pixels 117 | */ 118 | static float GetTextWidth(bool sysfont, const std::string& text); 119 | 120 | /* Those are to be used only when the process is paused */ 121 | static const Screen& GetTopScreen(void); 122 | static const Screen& GetBottomScreen(void); 123 | static void SwapBuffers(void); 124 | 125 | static void Lock(void); 126 | static bool TryLock(void); //false success, true failure 127 | static void Unlock(void); 128 | }; 129 | } 130 | 131 | #endif 132 | -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/System/Directory.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_DIRECTORY_HPP 2 | #define CTRPLUGINFRAMEWORK_DIRECTORY_HPP 3 | 4 | #include "types.h" 5 | #include "CTRPluginFramework/System/File.hpp" 6 | 7 | #include 8 | #include 9 | 10 | namespace CTRPluginFramework 11 | { 12 | class File; 13 | class Directory 14 | { 15 | public: 16 | 17 | enum OPResult 18 | { 19 | SUCCESS = 0, ///< Operation succeeded 20 | INVALID_PATH = -1, ///< The path is invalid 21 | NOT_OPEN = -2, ///< The File instance is not opened 22 | INVALID_ARG = -3, ///< One of the args passed to the operation is invalid (nullptr, address unreachable, etc) 23 | UNEXPECTED_ERROR = -4 ///< An error occured 24 | }; 25 | 26 | /** 27 | * \brief Change the working directory 28 | * \param path The new path to set as working directory 29 | * \return An \ref OPResult code 30 | */ 31 | static int ChangeWorkingDirectory(const std::string &path); 32 | 33 | /** 34 | * \brief Create a directory 35 | * \param path Path of the directory to create 36 | * \return Either a value from \ref OPResult or a FS return value 37 | */ 38 | static int Create(const std::string &path); 39 | 40 | /** 41 | * \brief Remove the specified directoy 42 | * \param path The directory to remove 43 | * \return Either a value from \ref OPResult or a FS return value 44 | */ 45 | static int Remove(const std::string &path); 46 | 47 | /** 48 | * \brief Rename the specified directory 49 | * \param oldPath The directory to rename 50 | * \param newPath The new name of the directory 51 | * \return Either a value from \ref OPResult or a FS return value 52 | */ 53 | static int Rename(const std::string &oldPath, const std::string &newPath); 54 | 55 | /** 56 | * \brief Check if the specified directory exists 57 | * \param path The directory to check 58 | * \return 59 | * 1: Exists 60 | * 0: Doesn't exists 61 | */ 62 | static int IsExists(const std::string &path); 63 | 64 | /** 65 | * \brief Open a directory 66 | * \param output Reference to the Directory object 67 | * \param path The directory to open 68 | * \param create If the directory must be created 69 | * \return Either a value from \ref OPResult or a FS return value 70 | */ 71 | static int Open(Directory &output, const std::string &path, bool create = false); 72 | 73 | /** 74 | * \brief Close a Directory 75 | * \return Either a value from \ref OPResult or a FS return value 76 | */ 77 | int Close(void) const; 78 | 79 | /** 80 | * \brief Open a file within the current Directory 81 | * \param output The File object 82 | * \param path The file to open 83 | * \param mode The mode to open the file with 84 | * \return Either a value from \ref OPResult or a FS return value 85 | */ 86 | int OpenFile(File &output, const std::string &path, int mode = File::RW) const; 87 | 88 | /** 89 | * \brief List all the files within the current Directory 90 | * \param files The list of files that will be returned \n 91 | * Beware that the container is not emptied and results files are appended 92 | * \param pattern If specified, only the files that contain the pattern will be returned 93 | * \return The count of files found, OPResult::NOT_OPEN if the Directory is not opened 94 | */ 95 | int ListFiles(std::vector &files, const std::string &pattern = "") const; 96 | 97 | /** 98 | * \brief List all the directories within the current Directory 99 | * \param directories The list of directories that will be returned \n 100 | * Beware that the container is not emptied and results directories are appended 101 | * \param pattern If specified, only the directories that contain the pattern will be returned 102 | * \return The count of directories found, OPResult::NOT_OPEN if the Directory is not opened 103 | */ 104 | int ListDirectories(std::vector &directories, const std::string &pattern = "") const; 105 | 106 | /** 107 | * \brief Get the name of the current Directory 108 | * \return An std::string with the name of the current Directory 109 | */ 110 | std::string GetName(void) const; 111 | 112 | /** 113 | * \brief Get the full path of the current Directory 114 | * \return An std::string with the full path of the current Directory 115 | */ 116 | std::string GetFullName(void) const; 117 | 118 | /** 119 | * \brief Check if the current Directory is open 120 | * \return true if the specified path was successfully opened, false otherwise 121 | */ 122 | bool IsOpen(void) const; 123 | 124 | Directory(void); 125 | Directory(const std::string &path, bool create = false); 126 | ~Directory(); 127 | 128 | private: 129 | 130 | int _List(void) const; 131 | 132 | std::string _path; 133 | Handle _handle; 134 | mutable bool _isOpen; 135 | mutable Mutex _mutex; 136 | struct DirectoryEntry 137 | { 138 | DirectoryEntry(u32 attrib, u8 *name); 139 | u32 attributes; 140 | std::string name; 141 | }; 142 | mutable std::vector _list; 143 | }; 144 | } 145 | 146 | #endif -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/Sound/Sound.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_SOUND_SOUND_HPP 2 | #define CTRPLUGINFRAMEWORK_SOUND_SOUND_HPP 3 | 4 | #include "types.h" 5 | #include 6 | 7 | namespace CTRPluginFramework 8 | { 9 | class Sound 10 | { 11 | public: 12 | 13 | enum class LoadStatus { 14 | NOT_ALLOCATED = 0, ///< Data is not allocated and cannot be used. 15 | SUCCESS = 1, ///< Loaded properly and is ready to play. 16 | INVALID_ARGUMENT = 2, ///< An invalid argument was passed to the constructor. 17 | FILE_OPEN_FAILED = 3, ///< Failed to open the specified file. 18 | FILE_TOO_LARGE = 4, ///< The file is too large to fit in the available memory. 19 | UNKNOWN_FILE_FORMAT = 5, ///< The specified file is not a valid CWAV file. 20 | INVAID_INFO_BLOCK = 6, ///< The INFO block in the CWAV file is invalid or not supported. 21 | INVAID_DATA_BLOCK = 7, ///< The DATA block in the CWAV file is invalid or not supported. 22 | UNSUPPORTED_AUDIO_ENCODING = 8 ///< The audio encoding is not supported. 23 | }; 24 | 25 | /** 26 | * \brief Default sound constructor with no audio attached to it. 27 | */ 28 | Sound(); 29 | 30 | /** 31 | * \brief Copy constructor. 32 | * \param sound Object to make copy from. 33 | * WARNING: The copy shares the same audio buffer! 34 | */ 35 | Sound(const Sound& sound); 36 | 37 | /** 38 | * \brief Move constructor 39 | * \param sound Object to move from. 40 | */ 41 | Sound(Sound&& sound) noexcept; 42 | 43 | /** 44 | * \brief Constructs a Sound object from a BCWAV file. 45 | * \param bcwavFile Path to the BCWAV file (must fit in memory). 46 | * \param maxSimultPlays Maximum amount of plays at the same time. 47 | */ 48 | Sound(const std::string& bcwavFile, int maxSimultPlays = 1); 49 | 50 | /** 51 | * \brief Constructs a Sound object from a BCWAV file in memory. 52 | * \param bcwavBuffer Buffer to the BCWAV file. 53 | * \param maxSimultPlays Maximum amount of plays at the same time. 54 | */ 55 | Sound(const u8* bcwavBuffer, int maxSimultPlays = 1); 56 | 57 | /** 58 | * \brief Copy asignation operator. 59 | * \param sound Object to copy asign from. 60 | * WARNING: The copy shares the same audio buffer! 61 | */ 62 | Sound& operator=(const Sound& sound); 63 | 64 | /** 65 | * \brief Move asignation operator. 66 | * \param sound Object to move asign from. 67 | */ 68 | Sound& operator=(Sound&& sound) noexcept; 69 | 70 | /** 71 | * \brief Get the BCWAV load status. The sound will only play if the load status is SUCCESS. 72 | * \return Load status from the LoadStatus enum. 73 | */ 74 | LoadStatus GetLoadStatus(); 75 | 76 | /** 77 | * \brief Sets the sound volume. Changes only apply after the next play. 78 | * \param volume New volume to set, in the range [0, 1]. 79 | */ 80 | void SetVolume(float volume); 81 | 82 | /** 83 | * \brief Gets the sound volume. 84 | * \return Volume value, in the range [0, 1]. 85 | */ 86 | float GetVolume(); 87 | 88 | /** 89 | * \brief Sets the sound pan. Changes only apply after the next play. 90 | * \param pam New pan to set, in the range [-1, 1]. (Left ear: -1, Right ear: 1). 91 | */ 92 | void SetPan(float pan); 93 | 94 | /** 95 | * \brief Gets the pan volume. 96 | * \return Pan value, in the range [-1, 1] (Left ear; -1, Right ear: 1). 97 | */ 98 | float GetPan(); 99 | 100 | /** 101 | * \brief Gets the amount of channels stored in the BCWAV file. 102 | * \return Amount of channels in the BCWAV file. 103 | */ 104 | u32 GetChannelAmount(); 105 | 106 | /** 107 | * \brief Checks if the BCWAV file is looped. 108 | * \return True if the BCWAV file is looped, false otherwise. 109 | */ 110 | bool IsLooped(); 111 | 112 | /** 113 | * \brief Plays the first audio channel in mono from the BCWAV file. 114 | * \return Whether the operation was successful or not. 115 | */ 116 | bool Play(); 117 | 118 | /** 119 | * \brief Plays the specified audio channel in mono from the BCWAV file. 120 | * \param monoChannel Channel to play, in the range [ 0, GetChannelAmount() - 1]. 121 | * \return Whether the operation was successful or not. 122 | */ 123 | bool Play(int monoChannel); 124 | 125 | /** 126 | * \brief Plays the specified audio channels in stereo from the BCWAV file. 127 | * \param leftEarChannel Left ear channel to play, in the range [0, GetChannelAmount() - 1]. 128 | * \param rightEarChannel Right each channel to play, in the range [0, GetChannelAmount() - 1]. 129 | * \return Whether the operation was successful or not. 130 | */ 131 | bool Play(int leftEarChannel, int rightEarChannel); 132 | 133 | /** 134 | * \brief Stops all the playing channels. 135 | */ 136 | void Stop(); 137 | 138 | /** 139 | * \brief Stops the specified mono audio channel. 140 | * \param monoChannel Channel to stop, in the range [ 0, GetChannelAmount() - 1]. 141 | */ 142 | void Stop(int monoChannel); 143 | 144 | /** 145 | * \brief Stops the specified stereo channels. 146 | * \param leftEarChannel Left ear channel to stop, in the range [ 0, GetChannelAmount() - 1]. 147 | * \param rightEarChannel Right ear channel to stop, in the range [ 0, GetChannelAmount() - 1]. 148 | */ 149 | void Stop(int leftEarChannel, int rightEarChannel); 150 | 151 | /// Default destructor. 152 | ~Sound(); 153 | 154 | private: 155 | /// Internal sound data. 156 | void* _soundImpl; 157 | }; 158 | } 159 | 160 | #endif -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/Menu/MenuFolder.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_MENUFOLDER_HPP 2 | #define CTRPLUGINFRAMEWORK_MENUFOLDER_HPP 3 | 4 | #include "types.h" 5 | #include 6 | #include 7 | 8 | namespace CTRPluginFramework 9 | { 10 | #ifndef SEPARATOR_TYPE 11 | #define SEPARATOR_TYPE 12 | enum class Separator 13 | { 14 | None, 15 | Filled, 16 | Stippled 17 | }; 18 | #endif 19 | 20 | enum class ActionType 21 | { 22 | Opening, 23 | Closing 24 | }; 25 | 26 | class MenuFolderImpl; 27 | class MenuFolder 28 | { 29 | 30 | public: 31 | MenuFolder(const std::string &name, const std::string ¬e = ""); 32 | MenuFolder(const std::string &name, const std::vector &entries); 33 | MenuFolder(const std::string &name, const std::string ¬e, const std::vector &entries); 34 | 35 | /** 36 | * \brief Destroy a MenuFolder.\n 37 | * Upon destruction all MenuEntry and MenuFolder objects contained by this folder\n 38 | * will be destroyed too (so all pointers will be invalidated). 39 | */ 40 | ~MenuFolder(); 41 | 42 | /** 43 | * \brief Hide the folder from the menu.\n 44 | * Will disable every MenuEntry objects contained in this folder and subfolders 45 | */ 46 | void Hide(void) const; 47 | 48 | /** 49 | * \brief Display the folder previously hidden in the menu 50 | */ 51 | void Show(void) const; 52 | 53 | /** 54 | * \brief Check if the current folder is visible in the menu 55 | * \return true if the folder is visible, false otherwise 56 | */ 57 | bool IsVisible(void) const; 58 | 59 | /** 60 | * \brief Set if this entry must display a separator on top of the entry 61 | * \param type Type of separator to display 62 | */ 63 | void UseTopSeparator(Separator type = Separator::Filled) const; 64 | 65 | /** 66 | * \brief Set if this entry must display a separator at the bottom of the entry 67 | * \param type Type of separator to display 68 | */ 69 | void UseBottomSeparator(Separator type = Separator::Filled) const; 70 | 71 | /** 72 | * \brief Append a MenuEntry object to this folder 73 | * \param item The entry to append 74 | */ 75 | void Append(MenuEntry *item) const; 76 | 77 | /** 78 | * \brief Append a MenuFolder object to this folder 79 | * \param item The folder to append 80 | */ 81 | void Append(MenuFolder *item) const; 82 | 83 | /** 84 | * \brief Get all entries present in this folder (doesn't contain subfolder's) 85 | * \return A std::vector with pointers to all MenuEntry objects 86 | */ 87 | std::vector GetEntryList(void) const; 88 | 89 | /** 90 | * \brief Get all folders present in this folder (doesn't contain subfolder's) 91 | * \return A std::vector with pointers to all MenuEntry objects 92 | */ 93 | std::vector GetFolderList(void) const; 94 | 95 | /** 96 | * \brief Get a reference of the string that hold the name of this folder 97 | * \return A reference of the std::string 98 | */ 99 | std::string &Name(void) const; 100 | /** 101 | * \brief Get a reference of the string that hold the note of this folder 102 | * \return A reference of the std::string 103 | */ 104 | std::string &Note(void) const; 105 | 106 | /** 107 | * \brief Get the number of items that his folder contains (not counting subfolders's content) 108 | * \return The count of items 109 | */ 110 | u32 ItemsCount(void) const; 111 | 112 | /** 113 | * \brief Remove and destroy all items contained by this folder.\n 114 | * This invalidate all pointers to any contained object. 115 | */ 116 | void Clear(void) const; 117 | 118 | /** 119 | * \brief Remove all objects in the range specified 120 | * \param startIndex The index where the range begin 121 | * \param count The number of elements to remove 122 | * \param destroy If the elements must be destroyed (invalidate pointers and release ressources) 123 | */ 124 | void Remove(u32 startIndex, u32 count, bool destroy) const; 125 | 126 | /** 127 | * \brief Add an entry to this folder 128 | * \param entry The MenuEntry object that must be added 129 | * \return A pointer to this MenuFolder 130 | */ 131 | MenuFolder *operator += (const MenuEntry *entry); 132 | 133 | /** 134 | * \brief Remove an entry from this folder 135 | * \param entry The MenuEntry object that must be removed 136 | * \return A pointer to this MenuFolder 137 | */ 138 | MenuFolder *operator -= (const MenuEntry *entry); 139 | 140 | /** 141 | * \brief Add a (sub)folder to this folder 142 | * \param folder The MenuFolder object that must added 143 | * \return A pointer to this MenuFolder 144 | */ 145 | MenuFolder *operator += (const MenuFolder *folder); 146 | 147 | /** 148 | * \brief Remove a (sub)folder to this folder 149 | * \param folder The MenuFolder object that must be removed 150 | * \return A pointer to this MenuFolder 151 | */ 152 | MenuFolder *operator -= (const MenuFolder *folder); 153 | 154 | /** 155 | * \brief Callback type, receive the object that called the callback \n 156 | * along with the action which triggered the callback 157 | * \return Whether the folder can be opened (on ActionType::Opening only, ignored for ActionType::Closing) 158 | */ 159 | using MenuFolder_OnActionFunc = bool(*)(MenuFolder &, ActionType); 160 | 161 | /** 162 | * \brief This callback is called when the folder is about to be opened or closed 163 | */ 164 | MenuFolder_OnActionFunc OnAction; 165 | 166 | private: 167 | friend class PluginMenu; 168 | std::unique_ptr _item; 169 | }; 170 | } 171 | 172 | #endif 173 | -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/Utils/Utils.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_UTILS_UTILS_HPP 2 | #define CTRPLUGINFRAMEWORK_UTILS_UTILS_HPP 3 | 4 | #include "types.h" 5 | 6 | #include "CTRPluginFramework/System/Process.hpp" 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | namespace CTRPluginFramework 13 | { 14 | enum class HexEditorView 15 | { 16 | Byte = 0, 17 | Integer = 1, 18 | Disassembler = 2 19 | }; 20 | 21 | class Color; 22 | class Utils 23 | { 24 | public: 25 | 26 | /** 27 | * \brief Get a string formatted with format specifier from printf 28 | * \param fmt String to be formatted 29 | * \param ... Additional arguments 30 | * \return The formatted std::string 31 | */ 32 | static std::string Format(const char *fmt, ...); 33 | 34 | /** 35 | * \brief Get the hexadecimal representation of a value 36 | * \param value The value to convert 37 | * \return An std::string with the the hexadecimal representation of value 38 | */ 39 | static std::string ToHex(u32 value); 40 | 41 | /** 42 | * \brief Get the string representation of a float value 43 | * \param fpval The value to convert 44 | * \param precision The number of digit after the . 45 | * \return An std::string with the representation of the value\n 46 | * Values between -999999.f && 999999.f will be a fixed representation \n 47 | * while anything lower / higher will be a scientific representation 48 | */ 49 | static std::string ToString(float fpval, int precision = 2); 50 | 51 | /** 52 | * \brief Get a random number 53 | * \return A random number 54 | */ 55 | static u32 Random(void); 56 | 57 | /** 58 | * \brief Get a random number 59 | * \param min Minimum value for the random number 60 | * \param max Maximum value for the random number 61 | * \return A random number between min & max 62 | */ 63 | static u32 Random(u32 min, u32 max); 64 | 65 | /** 66 | * \brief Get the size of an utf8 std::string (max size 0x100) 67 | * \param str The string to count 68 | * \return The count of utf8 chars in the str 69 | */ 70 | static u32 GetSize(const std::string &str); 71 | 72 | 73 | /** 74 | * \brief Open a menu which allow to browse the SD card to select a file 75 | * \param out The absolute path of the selected file 76 | * \param filter If the files must be filtered (can be an extension or a pattern that must be present in the filename) 77 | * \return -1 if the user aborted the operation, 0 on success 78 | */ 79 | static int FilePicker(std::string &out, const std::string &filter = ""); 80 | 81 | /** 82 | * \brief Open a menu which allow to browse the SD card to select a Directory 83 | * \param out The absolute path of the selected directory 84 | * \return -1 if the user aborted the operation, 0 on success 85 | */ 86 | static int DirectoryPicker(std::string &out); 87 | 88 | /** 89 | * \brief Open the HexEditor menu at a specified address within the specified view 90 | * \param address The address to jump to in the HexEditor 91 | * \param view The type of view (can be changed when open) 92 | * \return The address where the cursor was when the HexEditor is closed 93 | */ 94 | static u32 OpenInHexEditor(u32 address, HexEditorView view = HexEditorView::Byte); 95 | 96 | /** 97 | * \brief Remove the last char of an utf8 string (max size 0x100) 98 | * \param str The string to remove the char from 99 | * \return The codepoint value of the char removed 100 | */ 101 | static u32 RemoveLastChar(std::string &str); 102 | 103 | template 104 | static u32 Search(const u32 start, const u32 size, const std::vector &pattern) 105 | { 106 | if (!start || !size || pattern.empty()) 107 | return (0); 108 | 109 | const u32 patternSize = pattern.size() * sizeof(T); 110 | const u8 *patternc = reinterpret_cast(pattern.data()); 111 | const u8 *startPos = reinterpret_cast(start); 112 | 113 | u32 table[256]; 114 | 115 | for (u32 i = 0; i < 256; i++) 116 | table[i] = patternSize; 117 | 118 | for (u32 i = 0; i < patternSize - 1; i++) 119 | table[patternc[i]] = patternSize - i - 1; 120 | 121 | u32 j = 0; 122 | while (j <= size - patternSize) 123 | { 124 | const u8 c = startPos[j + patternSize - 1]; 125 | if (patternc[patternSize - 1] == c && std::memcmp(patternc, startPos + j, patternSize - 1) == 0) 126 | return (reinterpret_cast(startPos + j)); 127 | j += table[c]; 128 | } 129 | return (0); 130 | } 131 | 132 | template 133 | static u32 Rsearch(const u32 start, const u32 size, const std::vector &pattern) 134 | { 135 | if (!start || !size || pattern.empty()) 136 | return (0); 137 | 138 | const u32 patternSize = pattern.size() * sizeof(T); 139 | const u8 *patternc = reinterpret_cast(pattern.data()); 140 | const u8 *startPos = reinterpret_cast(start); 141 | 142 | u32 table[256]; 143 | 144 | for (u32 i = 0; i < 256; i++) 145 | table[i] = patternSize; 146 | 147 | for (u32 i = 0; i < patternSize - 1; i++) 148 | table[patternc[i]] = patternSize - i - 1; 149 | 150 | u32 j = 0; 151 | u32 last = 0; 152 | while (j <= size - patternSize) 153 | { 154 | const u8 c = startPos[j + patternSize - 1]; 155 | if (patternc[patternSize - 1] == c && std::memcmp(patternc, startPos + j, patternSize - 1) == 0) 156 | last = reinterpret_cast(startPos + j); 157 | j += table[c]; 158 | } 159 | return (last); 160 | } 161 | }; 162 | } 163 | 164 | #endif -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/System/FwkSettings.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_SYSTEM_FWKSETTINGS_HPP 2 | #define CTRPLUGINFRAMEWORK_SYSTEM_FWKSETTINGS_HPP 3 | 4 | #include "types.h" 5 | #include "CTRPluginFramework/System/Time.hpp" 6 | #include "CTRPluginFramework/Graphics/Color.hpp" 7 | #include "CTRPluginFramework/System/Rect.hpp" 8 | 9 | namespace CTRPluginFramework 10 | { 11 | struct PluginHeader ///< Defined by Luma3DS plugin loader 12 | { 13 | u32 magic; 14 | u32 version; 15 | u32 heapVA; 16 | u32 heapSize; 17 | u32 exeSize; // Include sizeof(PluginHeader) + .text + .rodata + .data + .bss (0x1000 aligned too) 18 | u32 isDefaultPlugin; 19 | s32* plgldrEvent; ///< Used for synchronization 20 | s32* plgldrReply; ///< Used for synchronization 21 | u32 reserved[24]; 22 | u32 config[32]; 23 | }; 24 | 25 | struct FwkSettings 26 | { 27 | // Plugin init options 28 | u32 ThreadPriority; ///< Pri ority for the main thread of the plugin must be within 0x3E - 0x18 | Default: 0x30 29 | bool AllowActionReplay; ///< Enable the Action Replay's handler, if this is set to off, even if the menu allows to create codes, they won't be executed 30 | bool AllowSearchEngine; ///< If false then the search engine won't be available | Default: true 31 | Time WaitTimeToBoot; ///< Time to wait for the plugin to starts (from when the game will starts) | Default: 5 seconds 32 | 33 | // Sound engine 34 | bool TryLoadSDSounds; ///< Determines if the plugin should automatically try to load the sound files from the SD card. | Default: true 35 | 36 | // UI colors 37 | Color MainTextColor; ///< The color of all texts within the plugin | Default: Blank 38 | Color WindowTitleColor; ///< The color of all window's titles | Default: Blank 39 | Color MenuSelectedItemColor; ///< The color of the text for the selected item | Default: Blank 40 | Color MenuUnselectedItemColor; ///< The color of the text for the items not selected | Default: Silver 41 | Color BackgroundMainColor; ///< The color of the background | Default: Black 42 | Color BackgroundSecondaryColor; ///< The color of the background 2 | Default: black/grey (RGB: 15, 15, 15) 43 | Color BackgroundBorderColor; ///< The color of the border around the window | Default: Blank 44 | float CursorFadeValue; ///< The value to be used to draw the cursor (Shade: [-1.0f - 0f], Tint: [0.f - 1.f]) | Default: 0.2f 45 | 46 | // Keyboard colors 47 | struct 48 | { 49 | Color Background; ///< Color of the window's background | Default: Black 50 | Color KeyBackground; ///< Color of the key's background | Default: Black 51 | Color KeyBackgroundPressed; ///< Color of the key's background while pressed | Default: Silver 52 | Color KeyText; ///< Color of the key's text | Default: Blank 53 | Color KeyTextPressed; ///< Color of the key's text while pressed | Default: Blank 54 | Color KeyTextDisabled; ///< Color of the key's text when disabled | Default: DimGrey 55 | Color Cursor; ///< Color of the cursor | Default: Blank 56 | Color Input; ///< Color of the input | Default: Blank 57 | } Keyboard; 58 | 59 | // Custom Keyboard colors 60 | struct 61 | { 62 | Color BackgroundMain; ///< The color of the background | Default: Black 63 | Color BackgroundSecondary; ///< The color of the background 2 | Default: black/grey (RGB: 15, 15, 15) 64 | Color BackgroundBorder; ///< The color of the border around the window | Default: Blank 65 | Color KeyBackground; ///< Color of the background of a key | Default: sort of Grey (51, 51, 51) 66 | Color KeyBackgroundPressed; ///< Color of the background of a key when it's being touched | Default: Gainsboro 67 | Color KeyText; ///< Color of the text of a key | Default: Blank 68 | Color KeyTextPressed; ///< Color of the text of a key when being touched | Default: Black 69 | Color ScrollBarBackground; ///< Color of the scrollbar's background | Default: Silver 70 | Color ScrollBarThumb; ///< Color of the scrollbar's thumb | Default: DimGrey 71 | } CustomKeyboard; 72 | 73 | enum Alignment_e 74 | { 75 | Left, 76 | Right, 77 | Center 78 | }; 79 | 80 | enum Screen_e 81 | { 82 | Top, 83 | Bottom 84 | }; 85 | 86 | struct 87 | { 88 | Color DefaultBackground; ///< Default: Color::Black 89 | Color DefaultForeground; ///< Default: Color::White 90 | Screen_e Screen; ///< Screen used to display the notifications | Default: Top 91 | UIntRect Area; ///< Area on the screen to display the notifications | Default: 0, 0, 400, 240 92 | u32 Margin; ///< Space between each notification | Default: 5px 93 | Alignment_e Alignment; ///< Alignment of the notification in the defined area | Default: Right 94 | Time LifeSpan; ///< Duration of a notification | Default: 5s 95 | } Notifications; 96 | 97 | /** 98 | * \brief Returns a reference to the FwkSettings instance used by the framework 99 | * Allows runtime theme edition 100 | * \return The instance of FwkSettings 101 | */ 102 | static FwkSettings& Get(void); 103 | static PluginHeader *Header; 104 | 105 | /** 106 | * \brief Reset all colors to their default values 107 | */ 108 | static void SetThemeDefault(void); 109 | 110 | /** 111 | * \brief Set the top screen background image from a bmp file in memory 112 | * \param bmpData Pointer to the BMP file in memory 113 | * \return 0 if success 114 | */ 115 | static Result SetTopScreenBackground(void *bmpData); 116 | 117 | /** 118 | * \brief Set the bottom screen background image from a bmp file in memory 119 | * \param bmpData Pointer to the BMP file in memory 120 | * \return 0 if success 121 | */ 122 | static Result SetBottomScreenBackground(void *bmpData); 123 | }; 124 | } 125 | 126 | #endif 127 | -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/System/Hook.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_SYSTEM_HOOK_H 2 | #define CTRPLUGINFRAMEWORK_SYSTEM_HOOK_H 3 | 4 | #include "types.h" 5 | #include 6 | 7 | namespace CTRPluginFramework 8 | { 9 | enum 10 | { 11 | USE_LR_TO_RETURN = 1 << 0, ///< Enable the use of bx lr to return from callback. LR will be properly restored after the callback is executed 12 | EXECUTE_OI_BEFORE_CB = 1 << 1, ///< If the instruction overwritten by the hook (target) must be executed before the callback 13 | EXECUTE_OI_AFTER_CB = 1 << 2, ///< If the instruction overwritten by the hook (target) must be executed after the callback 14 | MITM_MODE = 1 << 3, ///< This mode is perfect to intercepts functions calls 15 | WRAP_SUB = 1 << 4, ///< Wraps a subroutine call 16 | 17 | HOOK_DEFAULT_PARAMS = USE_LR_TO_RETURN | EXECUTE_OI_BEFORE_CB, 18 | }; 19 | 20 | enum class HookResult 21 | { 22 | Success, 23 | InvalidContext, ///< The HookContext obj linked to the Hook obj is invalid (Should not happen) 24 | InvalidAddress, ///< The target address was not reachable 25 | AddressAlreadyHooked, ///< A hook is already enabled to the same address 26 | TooManyHooks, ///< You attained the maximum of enabled hooks (current limit: 91) 27 | HookParamsError, ///< The parameters of your hook seems off 28 | TargetInstructionCannotBeHandledAutomatically, ///< The target's instruction is position dependent (PC) hence using ExecuteOverwrittenInstructionBeforeCallback or ExecuteOverwrittenInstructionAfterCallback is impossible. 29 | }; 30 | 31 | struct HookContext 32 | { 33 | s32 refcount; 34 | u32 flags; 35 | u32 targetAddress; 36 | u32 returnAddress; 37 | u32 callbackAddress; 38 | u32 callbackAddress2; 39 | u32 overwrittenInstr; 40 | u32 index; 41 | 42 | // Bunch of functions to be used inside a hook's function body 43 | static HookContext& GetCurrent(void); 44 | 45 | // The functions below are to be used only with MITM_MODE hooks 46 | template 47 | typename std::enable_if::value, TResult>::type 48 | OriginalFunction(Args... args) 49 | { 50 | using FPtr = TResult(*)(Args...); 51 | 52 | FPtr fptr = reinterpret_cast(GetCallCode()); 53 | 54 | if (fptr) 55 | return fptr(args...); 56 | 57 | return (TResult)fptr; 58 | } 59 | 60 | template 61 | typename std::enable_if::value, void>::type 62 | OriginalFunction(Args... args) 63 | { 64 | using FPtr = void(*)(Args...); 65 | 66 | FPtr fptr = reinterpret_cast(GetCallCode()); 67 | 68 | if (fptr) 69 | fptr(args...); 70 | } 71 | 72 | private: 73 | void *GetCallCode(void); 74 | }; 75 | 76 | struct Hook 77 | { 78 | Hook(void); 79 | // Warning: copies share the same HookContext 80 | Hook(const Hook& hook); 81 | Hook(Hook&& hook) noexcept; 82 | Hook& operator=(const Hook& hook); 83 | Hook& operator=(Hook&& hook) noexcept; 84 | ~Hook(void); 85 | 86 | /** 87 | * \brief Initialize hook target and callback. Hook's return address is set to targetAddr + 4 88 | * \param targetAddr The address to hook to 89 | * \param callbackAddr The callback to be called by the hook 90 | * \return A reference to Hook obj 91 | */ 92 | Hook& Initialize(u32 targetAddr, u32 callbackAddr); 93 | 94 | /** 95 | * \brief Initialize a hook for mitm mode (apply the required flags) 96 | * \param targetAddr The address to hook to 97 | * \param callbackAddr The callback to be called by the hook 98 | * \return A reference to Hook obj 99 | */ 100 | Hook& InitializeForMitm(u32 targetAddr, u32 callbackAddr); 101 | 102 | /** 103 | * \brief Initialize a hook for subroutine wrapping (apply the required flags) 104 | * \param targetAddr The address with the subroutine call to wrap (BL only) 105 | * \param beforeCallback The callback to be called before the subroutine (can be null) 106 | * \param afterCallback The callback to be called after the subroutine (can be null) 107 | * \return A reference to Hook obj 108 | */ 109 | Hook& InitializeForSubWrap(u32 targetAddr, u32 beforeCallback, u32 afterCallback); 110 | 111 | /** 112 | * \brief Apply the specified flags to the hook. Must be done before enabling the hook otherwise nothing happens 113 | * \param flags The new hook settings 114 | * \return A reference to the Hook obj 115 | */ 116 | Hook& SetFlags(u32 flags); 117 | 118 | /** 119 | * \brief Set the return address of the hook (default: target + 4) 120 | * \param returnAddr The address for the hook to return to 121 | * \return A reference to the Hook obj 122 | */ 123 | Hook& SetReturnAddress(u32 returnAddr); 124 | 125 | 126 | /** 127 | * \brief Check if the hook is applied or not 128 | * \return true if the hook is applied, false otherwise 129 | */ 130 | bool IsEnabled(void); 131 | 132 | /** 133 | * \brief Apply the hook 134 | * \return Return the result of the operation (see HookResult for more infos) 135 | */ 136 | HookResult Enable(void); 137 | 138 | /** 139 | * \brief Disable the hook 140 | * \return Return the result of the operation (see HookResult for more infos) 141 | */ 142 | HookResult Disable(void); 143 | 144 | const HookContext& GetContext(void) const; 145 | 146 | private: 147 | HookContext *_ctx; 148 | }; 149 | 150 | // Bunch of functions to be used inside a hook's function body (asm) 151 | extern "C" 152 | { 153 | /** 154 | * \brief Get a pointer to the current hook's context (see HookContext) 155 | * \return A pointer to current HookContext 156 | */ 157 | void * ctrpfHook__GetCurrent(void); 158 | 159 | /** 160 | * \brief Execute the original function. Only available for mitm hooks. 161 | * If the function takes some args, just set the registers accordingly 162 | * \return return value of original function 163 | */ 164 | void * ctrpfHook__ExecuteOriginalFunction(void); 165 | } 166 | } 167 | 168 | #endif 169 | -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/System/File.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_FILE_HPP 2 | #define CTRPLUGINFRAMEWORK_FILE_HPP 3 | 4 | #include "types.h" 5 | #include "CTRPluginFramework/System/Mutex.hpp" 6 | 7 | #include 8 | #include 9 | 10 | namespace CTRPluginFramework 11 | { 12 | class File 13 | { 14 | public: 15 | 16 | enum SeekPos 17 | { 18 | CUR, 19 | SET, 20 | END 21 | }; 22 | 23 | enum Mode 24 | { 25 | READ = 1, ///< Gives read permission 26 | WRITE = 1 << 1, ///< Gives write permission 27 | CREATE = 1 << 2, ///< The file will be created if it doesn't exist 28 | APPEND = 1 << 3, ///< You'll be unable to overwrite the file, only append data to it 29 | TRUNCATE = 1 << 4, ///< Will clear the file 30 | SYNC = 1 << 5, ///< Will flush and update time on each write 31 | 32 | RW = READ | WRITE, 33 | RWC = READ | WRITE | CREATE 34 | }; 35 | 36 | enum OPResult 37 | { 38 | SUCCESS = 0, ///< Operation succeeded 39 | INVALID_PATH = -1, ///< The path is invalid 40 | NOT_OPEN = -2, ///< The File instance is not opened 41 | INVALID_MODE = -3, ///< The mode passed when opened the file doesn't allow this operation 42 | INVALID_ARG = -4, ///< One of the args passed to the operation is invalid (nullptr, address unreachable, etc) 43 | UNEXPECTED_ERROR = -5 ///< An error occured 44 | }; 45 | 46 | /** 47 | * \brief Create a file 48 | * \param path The path of the file to create 49 | * \return 50 | * Either a value in \ref OPResult or an error code from FS service 51 | */ 52 | static int Create(const std::string &path); 53 | 54 | /** 55 | * \brief Rename the specified file 56 | * \param path Old name 57 | * \param newpath New name 58 | * \return 59 | * Either a value in \ref OPResult or an error code from FS service 60 | */ 61 | static int Rename(const std::string &path, const std::string &newpath); 62 | 63 | /** 64 | * \brief Remove the specified file 65 | * \param path The file to remove 66 | * \return 67 | * Either a value in \ref OPResult or an error code from FS service 68 | */ 69 | static int Remove(const std::string &path); 70 | 71 | 72 | /** 73 | * \brief Determines whether the specified file exists 74 | * \param path The file to check 75 | * \return 76 | * 0: File doesn't exists \n 77 | * 1: File exists \n 78 | * Either a value in \ref OPResult or an error code from FS service 79 | */ 80 | static int Exists(const std::string &path); 81 | 82 | /** 83 | * \brief Open the specified file 84 | * \param output File object 85 | * \param path The file to open 86 | * \param mode The mode that specifies the acces type (See \ref File::Mode) 87 | * \return 88 | * Either a value in \ref OPResult or an error code from FS service 89 | */ 90 | static int Open(File &output, const std::string &path, int mode = READ | WRITE | SYNC); 91 | 92 | /** 93 | * \brief Close the file 94 | * \return 95 | * Either a value in \ref OPResult or an error code from FS service 96 | */ 97 | int Close(void) const; 98 | 99 | /** 100 | * \brief Read file 101 | * \param buffer Where to read the data to, ensure the buffer is large enough 102 | * \param length Size to read in bytes 103 | * \return 104 | * Either a value in \ref OPResult or an error code from FS service 105 | */ 106 | int Read(void *buffer, u32 length) const; 107 | 108 | /** 109 | * \brief Write to file 110 | * \param data Pointer to the data to write to the file 111 | * \param length Length of the data to write in bytes 112 | * \return 113 | * Either a value in \ref OPResult or an error code from FS service 114 | */ 115 | int Write(const void *data, u32 length); 116 | 117 | 118 | /** 119 | * \brief Write a string to file (auto append '\n') 120 | * \param line Text to write 121 | * \return 122 | * Either a value in \ref OPResult or an error code from FS service 123 | */ 124 | int WriteLine(std::string line); 125 | 126 | /** 127 | * \brief Set the position in the file 128 | * \param offset Value to offset from \param origin 129 | * \param origin Position used as reference for \param offset 130 | * \return 131 | * Either a value in \ref OPResult or an error code from FS service 132 | */ 133 | int Seek(s64 offset, SeekPos origin = CUR) const; 134 | 135 | /** 136 | * \brief Get current position in the file 137 | * \return The current position in file from the beginning 138 | */ 139 | u64 Tell(void) const; 140 | 141 | /** 142 | * \brief Set the position to the beginning of the file 143 | */ 144 | void Rewind(void) const; 145 | 146 | /** 147 | * \brief Flushes a file's content 148 | * \return 149 | * Either a value in \ref OPResult or an error code from FS service 150 | */ 151 | int Flush(void) const; 152 | 153 | /** 154 | * \brief Get the size of the file 155 | * \return 156 | * File size if >= 0 \n 157 | * Either a value in \ref OPResult or an error code from FS service otherwise 158 | */ 159 | u64 GetSize(void) const; 160 | 161 | void SetPriority(u32 priority); 162 | 163 | /** 164 | * \brief Write the content of the memory to the file 165 | * \param address Address to start reading the memory from 166 | * \param length Length in bytes to write to the file 167 | * \return 168 | * Either a value in \ref OPResult or an error code from FS service 169 | */ 170 | int Dump(u32 address, u32 length); 171 | 172 | /** 173 | * \brief Write the content of the file (from current position) to memory 174 | * \param address Address to copy the content to 175 | * \param length Length in bytes to copy 176 | * \return 177 | * Either a value in \ref OPResult or an error code from FS service 178 | */ 179 | int Inject(u32 address, u32 length) const; 180 | 181 | /** 182 | * \brief Check if the file is open or not 183 | * \return true if open, false otherwise 184 | */ 185 | bool IsOpen(void) const; 186 | 187 | /** 188 | * \brief Gets the full path of the file 189 | * \return An std::string with the full path of the file 190 | */ 191 | std::string GetFullName(void) const; 192 | 193 | /** 194 | * \brief Get the file name 195 | * \return An std::string with the name of the file 196 | */ 197 | std::string GetName(void) const; 198 | 199 | /** 200 | * \brief Get the extension of the file 201 | * \return An std::string with the extension part of the file 202 | */ 203 | std::string GetExtension(void) const; 204 | 205 | File(void); 206 | File(const std::string &path, u32 mode = READ | WRITE | SYNC); 207 | ~File() { Close(); } 208 | 209 | private: 210 | mutable std::string _path; 211 | mutable Handle _handle; 212 | mutable u64 _offset; 213 | mutable int _mode; 214 | mutable bool _isOpen; 215 | mutable Mutex _mutex; 216 | }; 217 | } 218 | 219 | #endif -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/Menu/PluginMenu.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_PLUGINMENU_HPP 2 | #define CTRPLUGINFRAMEWORK_PLUGINMENU_HPP 3 | 4 | #include "CTRPluginFramework/Menu/MenuEntry.hpp" 5 | #include "CTRPluginFramework/Menu/MenuFolder.hpp" 6 | #include "CTRPluginFramework/System/Time.hpp" 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | namespace CTRPluginFramework 13 | { 14 | class PluginMenuImpl; 15 | class PluginMenu 16 | { 17 | using CallbackPointer = void (*)(void); 18 | using OnOpeningCallback = bool (*)(void); 19 | using OnScreenshotCallback = bool (*)(void); 20 | using FrameCallback = void (*)(Time); 21 | using DecipherPointer = void(*)(std::string &, void *); 22 | public: 23 | 24 | /* 25 | ** Create a new PluginMenu 26 | ** name = The name of the menu / main folder 27 | ** about = text to display on the bottom screen of Tools section 28 | ******************************/ 29 | explicit PluginMenu(std::string name = "Cheats", std::string about = "", u32 menuType = 0); 30 | 31 | /* 32 | ** Create a new PluginMenu 33 | ** name = The name of the menu / main folder 34 | ** about = pointer to encrypted about's text data 35 | ** func = function to decrypt the about's data 36 | ******************************/ 37 | PluginMenu(std::string name, void *about, DecipherPointer func, u32 menuType = 0); 38 | 39 | /** 40 | * \brief Create a new PluginMenu 41 | * \param name The name of the menu / main folder 42 | * \param major The major version number of the plugin version 43 | * \param minor The minor version number of the plugin version 44 | * \param revision The revision version number of the plugin version 45 | * \param about Text to display in Tools About 46 | */ 47 | PluginMenu(std::string name, u32 major, u32 minor, u32 revision, std::string about = "", u32 menuType = 0); 48 | 49 | /* 50 | ** Destructor 51 | ******************************/ 52 | ~PluginMenu(void); 53 | 54 | /* 55 | ** Append a new entry to the menu (root) 56 | ** item = pointer to a MenuEntry object 57 | ******************************/ 58 | void Append(MenuEntry *item) const; 59 | 60 | /* 61 | ** Append a new folder to the menu (root) 62 | ** item = pointer to a MenuFolder object 63 | ******************************/ 64 | void Append(MenuFolder *item) const; 65 | 66 | void operator += (const MenuEntry *entry) const; 67 | void operator += (const MenuFolder *folder) const; 68 | void operator += (CallbackPointer callback) const; 69 | void operator -= (CallbackPointer callback) const; 70 | 71 | /* 72 | ** Add a callback to the menu 73 | ** A callback is a function which is always executed in the menu's main loop 74 | ** callback = function to add as callback 75 | ******************************/ 76 | void Callback(CallbackPointer callback) const; 77 | 78 | /* 79 | ** Run the menu 80 | ** This call is blocking so be sure to do everyting before calling this function 81 | ******************************/ 82 | int Run(void) const; 83 | 84 | /** 85 | * \brief Get all entries present at the root of the menu 86 | * \return A std::vector with pointers to all MenuEntry objects 87 | */ 88 | std::vector GetEntryList(void) const; 89 | 90 | /** 91 | * \brief Get all folders present at the root of the menu 92 | * \return A std::vector with pointers to all MenuFolder objects 93 | */ 94 | std::vector GetFolderList(void) const; 95 | 96 | /** 97 | * \brief Enable / Disable the HexEditor in Tools 98 | * \param isEnabled If HexEditor must be enabled or not 99 | */ 100 | void SetHexEditorState(bool isEnabled) const; 101 | 102 | /** 103 | * \brief Choose to display or not the "plugin ready" message 104 | * \param showMsg If the message must be displayed or not 105 | */ 106 | void ShowWelcomeMessage(bool showMsg) const; 107 | 108 | /** 109 | * \brief Check if the menu is currently open 110 | * \return true if the menu is open, false otherwise 111 | */ 112 | bool IsOpen(void); 113 | 114 | /** 115 | * \brief Check if the menu was opened since last Func execution 116 | * \return true if the menu was opened, false otherwise 117 | */ 118 | bool WasOpened(void); 119 | 120 | /** 121 | * \brief Get a reference to the PluginMenu currently running 122 | * \return A reference to a PluginMenu that is currently running 123 | */ 124 | static PluginMenu *GetRunningInstance(void); 125 | 126 | /** 127 | * \brief Forces the opening of the menu 128 | */ 129 | static void ForceOpen(void); 130 | 131 | /** 132 | * \brief If set to true, the plugin's loop will only be executed 1 per top screen's frame 133 | * \param useSync Wheter to wait for the top screen's frame or not 134 | */ 135 | void SynchronizeWithFrame(const bool useSync); 136 | 137 | /** 138 | * \brief If a callback is set, the callback will be called - Must be set before calling Run 139 | * when the menu is opened for the first time 140 | */ 141 | CallbackPointer OnFirstOpening; 142 | 143 | /** 144 | * \brief If a callback is set, the callback will be called - Must be set before calling Run 145 | * when the menu is opened. Ideal to put the code that refresh the UI. ;) Return true from the callback 146 | * to proceed with menu opening, return false otherwise. 147 | */ 148 | OnOpeningCallback OnOpening; 149 | 150 | /** 151 | * \brief The callback set will be called at each frame rendered while the menu is open 152 | * Ideal to put some UI effect 153 | * The function will receive the Time elapsed since last frame 154 | * Must be set before calling Run 155 | */ 156 | FrameCallback OnNewFrame; 157 | 158 | /** 159 | * \brief Returns the reference of the PluginMenu title string 160 | * \return the reference of the PluginMenu title string 161 | */ 162 | std::string & Title(); 163 | 164 | /** 165 | * \brief Returns the reference of the screenshot path string 166 | * ScreenshotUpdatePaths needs to be called afterwards. 167 | * \return the reference of the screenshot path string 168 | */ 169 | static std::string & ScreenshotPath(); 170 | 171 | /** 172 | * \brief Returns the reference of the screenshot file prefix string, 173 | * ScreenshotUpdatePaths needs to be called afterwards. 174 | * \return the reference of the screenshot file prefix string 175 | */ 176 | static std::string & ScreenshotFilePrefix(); 177 | 178 | /** 179 | * \brief Updates the paths after modifying the path and prefix strings. 180 | */ 181 | static void ScreenshotUpdatePaths(); 182 | 183 | /** 184 | * \brief Gets the screenshot settings references, can be read or written to. 185 | * \param enabled Screenshot feature enabled reference 186 | * \param hotkey Screenshot feature hotkey reference 187 | */ 188 | static void ScreenshotSettings(bool** enabled, u32** hotkey); 189 | 190 | /** 191 | * \brief Sets the screenshot callback, called whenever an screenshot is taken. 192 | * If the callback function returns false, the screenshot will be aborted. 193 | * \param callback The callback function 194 | */ 195 | static void ScreenshotSetcallback(OnScreenshotCallback callback); 196 | 197 | 198 | private: 199 | std::unique_ptr _menu; 200 | }; 201 | } 202 | 203 | #endif 204 | -------------------------------------------------------------------------------- /Sources/KORcheats.cpp: -------------------------------------------------------------------------------- 1 | #include "cheats.hpp" 2 | 3 | namespace CTRPluginFramework 4 | { 5 | Keyboard *KORoptKb = new Keyboard("Choose option:"); 6 | Keyboard *KORcoloptKb = new Keyboard("Choose option:\n(This clears the birth day because of how confusing that is, deal with it.)"); 7 | Keyboard *KORdeloptKb = new Keyboard("Are you sure you want to delete this Mii?"); 8 | 9 | std::vector KORNameEdit 10 | { 11 | "Nickname", 12 | "Creator", 13 | }; 14 | void KORnamedit(MenuEntry *entry) { 15 | u32 val; 16 | u8 breh; 17 | std::string textvalue; 18 | std::string wrote; 19 | KORoptKb->Populate(KORNameEdit); 20 | switch (KORoptKb->Open()) 21 | { 22 | case 0: 23 | if (Process::Read32(0x8032218, val) && val == 0xFFFFFFFF) { //stupid way of checking if youre in the editor 24 | Keyboard keyboard("Type a new nickname.\n(Characters \u0022%\u0022 and \u0022\u005C\u0022 are unsaveable!"); 25 | keyboard.SetMaxLength(10); 26 | int op = keyboard.Open(textvalue); 27 | if(op == -1) 28 | return; 29 | Process::WriteString(0x880CCB8, textvalue, StringFormat::Utf16); 30 | Process::Write16(0x880CCCC, 0); 31 | OSD::Notify("Nickname changed!"); 32 | Process::ReadString(0x880CCB8, wrote, 0x20, StringFormat::Utf16); 33 | if (strstr(wrote.c_str(), "%")) { 34 | std::string toSearch("%"); 35 | std::vector IndexVec = GetSubstrIndexList(wrote, toSearch); 36 | if (IndexVec.size()) 37 | { 38 | for (size_t i = 0; i < IndexVec.size(); i++) { 39 | ReplaceSTR(wrote, toSearch, "?", IndexVec.at(i)); 40 | } 41 | Process::WriteString(0x880CCB8, wrote, StringFormat::Utf16); 42 | MessageBox("Invalid characters detected (%), fixed.")(); 43 | } 44 | } 45 | if (strstr(wrote.c_str(), "\\")) { 46 | std::string toSearch("\\"); 47 | std::vector IndexVec = GetSubstrIndexList(wrote, toSearch); 48 | if (IndexVec.size()) 49 | { 50 | for (size_t i = 0; i < IndexVec.size(); i++) { 51 | ReplaceSTR(wrote, toSearch, "?", IndexVec.at(i)); 52 | } 53 | Process::WriteString(0x880CCB8, wrote, StringFormat::Utf16); 54 | MessageBox("Invalid characters detected (\\), fixed.")(); 55 | } 56 | } 57 | } 58 | else MessageBox(Color::Red << "You don't seem to be in the editing menu")(); 59 | break; 60 | case 1: 61 | if (Process::Read32(0x8032218, val) && val == 0xFFFFFFFF) { 62 | Keyboard keyboard("Type a new creator name.\n(Characters \u0022%\u0022 and \u0022\u005C\u0022 are unsaveable!"); 63 | keyboard.SetMaxLength(10); 64 | int op = keyboard.Open(textvalue); 65 | if(op == -1) 66 | return; 67 | Process::WriteString(0x880CCCE, textvalue, StringFormat::Utf16); 68 | Process::Write16(0x880CCE2, 0); 69 | OSD::Notify("Creator name changed!"); 70 | Process::ReadString(0x880CCCE, wrote, 0x20, StringFormat::Utf16); 71 | if (strstr(wrote.c_str(), "%")) { 72 | std::string toSearch("%"); 73 | std::vector IndexVec = GetSubstrIndexList(wrote, toSearch); 74 | if (IndexVec.size()) 75 | { 76 | for (size_t i = 0; i < IndexVec.size(); i++) { 77 | ReplaceSTR(wrote, toSearch, "?", IndexVec.at(i)); 78 | } 79 | Process::WriteString(0x880CCCE, wrote, StringFormat::Utf16); 80 | MessageBox("Invalid characters detected (%), fixed.")(); 81 | } 82 | } 83 | if (strstr(wrote.c_str(), "\\")) { 84 | std::string toSearch("\\"); 85 | std::vector IndexVec = GetSubstrIndexList(wrote, toSearch); 86 | if (IndexVec.size()) 87 | { 88 | for (size_t i = 0; i < IndexVec.size(); i++) { 89 | ReplaceSTR(wrote, toSearch, "?", IndexVec.at(i)); 90 | } 91 | Process::WriteString(0x880CCCE, wrote, StringFormat::Utf16); 92 | MessageBox("Invalid characters detected (\\), fixed.")(); 93 | } 94 | } 95 | } 96 | else MessageBox(Color::Red << "You don't seem to be in the editing menu")(); 97 | break; 98 | } 99 | } 100 | 101 | bool KORvalidOSD(const Screen &screen) 102 | { 103 | u32 browpos = 0x880CC58; //0x8C8C difference from regular 104 | u32 browspace = 0x880CC54;/// 105 | u32 browrot = 0x880CC50;/// 106 | u32 browsize = 0x880CC48;/// 107 | u32 browidth = 0x880CC4C;/// 108 | u32 eyepos = 0x880CC3C;/// 109 | u32 eyespace = 0x880CC38;/// 110 | u32 eyerot = 0x880CC34;/// 111 | u32 eyesize = 0x880CC2C;/// 112 | u32 eyewidth = 0x880CC30;/// 113 | u32 nosepos = 0x880CC64;/// 114 | u32 nosesize = 0x880CC60;/// 115 | u32 mouthpos = 0x880CC78;/// 116 | u32 mouthsize = 0x880CC70;/// 117 | u32 mouthwidth = 0x880CC74;/// 118 | u32 glasspos = 0x880CC9C;/// 119 | u32 glassize = 0x880CC98;/// 120 | u32 stachepos = 0x880CC8C;/// 121 | u32 stachesize = 0x880CC88;/// 122 | u32 molex = 0x880CCA8;/// 123 | u32 moley = 0x880CCAC;/// 124 | u32 molesize = 0x880CCA4;/// 125 | u32 tall = 0x880CCB0;/// 126 | u32 wide = 0x880CCB4;/// 127 | u32 share = 0x880CCF7;/// 128 | u32 gold = 0x880CD0C;/// 129 | u8 val; 130 | u8 nibble; 131 | if (screen.IsTop && (*(u32 *)0x8032218 == 0xFFFFFFFF)) 132 | { 133 | if(!IsValidPosition(*(u8 *)browpos, *(u8 *)browspace, *(u8 *)browrot, *(u8 *)browsize, *(u8 *)browidth, *(u8 *)eyepos, *(u8 *)eyespace, *(u8 *)eyerot, *(u8 *)eyesize, *(u8 *)eyewidth, *(u8 *)nosepos, *(u8 *)nosesize, *(u8 *)mouthpos, *(u8 *)mouthsize, *(u8 *)mouthwidth, *(u8 *)glasspos, *(u8 *)glassize, *(u8 *)stachepos, *(u8 *)stachesize, *(u8 *)molex, *(u8 *)moley, *(u8 *)molesize, *(u8 *)tall, *(u8 *)wide, *(u8 *)gold, *(u8 *)share, val, nibble)) { 134 | screen.Draw("Unsavable", 0, 0, Color::Red); 135 | } 136 | else screen.Draw("Savable", 0, 0, Color::Green); 137 | } 138 | return true; 139 | } 140 | bool KORaddressOSD(const Screen &screen) 141 | { 142 | u8 val; 143 | if (screen.IsTop && (*(u32 *)0x8AF73A4 == 0xB88C50) && (*(u16 *)0x88014D5 == 0)) 144 | { 145 | if (Process::Read8(0x88014D4, val)) { 146 | screen.Draw(Utils::Format("Mii Data Address: %X", (0x17200 * val) + 0x8831C84), 0, 0, Color::Cyan); 147 | screen.Draw(Utils::Format("Mii Data Address In Save (RAM): %X", (0x5C * val) + 0x1488B7A8), 0, 10, Color::Cyan); 148 | } 149 | } 150 | return true; 151 | } 152 | 153 | void KOROSD(MenuEntry *entry) 154 | { 155 | if (entry->WasJustActivated()) 156 | { 157 | //OSD::Run(KORvalidOSD); 158 | OSD::Run(KORaddressOSD); 159 | } 160 | else if (!entry->IsActivated()) 161 | { 162 | //OSD::Stop(KORvalidOSD); 163 | OSD::Stop(KORaddressOSD); 164 | } 165 | } 166 | 167 | void KORcopymii(MenuEntry *entry) { 168 | u8 val; 169 | u32 dataline; 170 | u32 numint; 171 | if(Controller::IsKeysPressed(entry->Hotkeys[0].GetKeys())) { 172 | if (*(u32 *)0x8AF73A4 == 0xB88C50 && (*(u16 *)0x88014D5 == 0)) 173 | { 174 | if (Process::Read8(0x88014D4, val)) { 175 | for (int i = 0; i < 256; i+=4) 176 | { 177 | if (Process::Read32((0x17200 * val) + (0x8831C84 + i), dataline)) 178 | { 179 | Process::Write32((0x1E81000 + i), dataline); 180 | } 181 | } 182 | std::string name; 183 | Process::ReadString((0x17200 * val) + 0x8831D38, name, 0x20, StringFormat::Utf16); 184 | OSD::Notify("Copied: " + name); 185 | Process::Write8(0x01E81108, 0x1); 186 | } 187 | } 188 | else OSD::Notify(Color::Red << "No Mii selected!"); 189 | } 190 | if(Controller::IsKeysPressed(entry->Hotkeys[1].GetKeys())) { 191 | if (*(u32 *)0x8032218 == 0xFFFFFFFF && (*(u8 *)0x01E81108 == 0x1)) 192 | { 193 | if (*(u32 *)0x8801164 != 0xFFFFFFFF) 194 | { 195 | Sleep(Milliseconds(100)); 196 | MessageBox("Paste this onto the Mii in the Create New Mii editor to avoid the save file from breaking!")(); 197 | return; 198 | } 199 | if (*(u32 *)0x8801164 == 0xFFFFFFFF) 200 | { 201 | for (int i = 0; i < 256; i+=4) 202 | { 203 | if (Process::Read32(0x1E81000 + i, dataline)) 204 | { 205 | Process::Write32((0x880CC04 + i), dataline); 206 | } 207 | } 208 | std::string name; 209 | Process::ReadString(0x880CCB8, name, 0x20, StringFormat::Utf16); 210 | OSD::Notify("Pasted: " + name); 211 | } 212 | } 213 | else OSD::Notify(Color::Red << "No Mii in clipboard and/or you aren't in the editor!"); 214 | } 215 | } 216 | 217 | void KORdumpsave(MenuEntry *entry) { 218 | Directory SaveDir; 219 | if (Directory::IsExists("/Miichanic") == 0) 220 | Directory::Create("/Miichanic"); 221 | 222 | File SaveFile; 223 | File::Open(SaveFile,"/Miichanic/CFL_DB.dat", File::RWC); 224 | SaveFile.Dump(0x1488B7A0, 0x4BD20); 225 | SaveFile.Close(); 226 | MessageBox("Dump complete!")(); 227 | } 228 | void KORrestoresave(MenuEntry *entry) { 229 | Directory SaveDir; 230 | File SaveFile; 231 | Directory::Open(SaveDir,"/Miichanic", true); 232 | SaveDir.OpenFile(SaveFile,"CFL_DB.dat", File::READ); 233 | SaveFile.Inject(0x1488B7A0, 0x4BD20); 234 | MessageBox("Save restored!")(); 235 | } 236 | 237 | void KORcallencrypt(MenuEntry *entry) { 238 | if(Controller::IsKeysPressed(entry->Hotkeys[0].GetKeys())) { 239 | KORencrypt(); 240 | } 241 | } 242 | } -------------------------------------------------------------------------------- /Sources/TWNcheats.cpp: -------------------------------------------------------------------------------- 1 | #include "cheats.hpp" 2 | 3 | namespace CTRPluginFramework 4 | { 5 | Keyboard *TWNoptKb = new Keyboard("Choose option:"); 6 | Keyboard *TWNcoloptKb = new Keyboard("Choose option:\n(This clears the birth day because of how confusing that is, deal with it.)"); 7 | Keyboard *TWNdeloptKb = new Keyboard("Are you sure you want to delete this Mii?"); 8 | 9 | std::vector TWNNameEdit 10 | { 11 | "Nickname", 12 | "Creator", 13 | }; 14 | void TWNnamedit(MenuEntry *entry) { 15 | u32 val; 16 | u8 breh; 17 | std::string textvalue; 18 | std::string wrote; 19 | TWNoptKb->Populate(TWNNameEdit); 20 | switch (TWNoptKb->Open()) 21 | { 22 | case 0: 23 | if (Process::Read32(0x803CAEC, val) && val == 0xFFFFFFFF) { //stupid way of checking if youre in the editor 24 | Keyboard keyboard("Type a new nickname.\n(Characters \u0022%\u0022 and \u0022\u005C\u0022 are unsaveable!"); 25 | keyboard.SetMaxLength(10); 26 | int op = keyboard.Open(textvalue); 27 | if(op == -1) 28 | return; 29 | Process::WriteString(0x880CCB8, textvalue, StringFormat::Utf16); 30 | Process::Write16(0x880CCCC, 0); 31 | OSD::Notify("Nickname changed!"); 32 | Process::ReadString(0x880CCB8, wrote, 0x20, StringFormat::Utf16); 33 | if (strstr(wrote.c_str(), "%")) { 34 | std::string toSearch("%"); 35 | std::vector IndexVec = GetSubstrIndexList(wrote, toSearch); 36 | if (IndexVec.size()) 37 | { 38 | for (size_t i = 0; i < IndexVec.size(); i++) { 39 | ReplaceSTR(wrote, toSearch, "?", IndexVec.at(i)); 40 | } 41 | Process::WriteString(0x880CCB8, wrote, StringFormat::Utf16); 42 | MessageBox("Invalid characters detected (%), fixed.")(); 43 | } 44 | } 45 | if (strstr(wrote.c_str(), "\\")) { 46 | std::string toSearch("\\"); 47 | std::vector IndexVec = GetSubstrIndexList(wrote, toSearch); 48 | if (IndexVec.size()) 49 | { 50 | for (size_t i = 0; i < IndexVec.size(); i++) { 51 | ReplaceSTR(wrote, toSearch, "?", IndexVec.at(i)); 52 | } 53 | Process::WriteString(0x880CCB8, wrote, StringFormat::Utf16); 54 | MessageBox("Invalid characters detected (\\), fixed.")(); 55 | } 56 | } 57 | } 58 | else MessageBox(Color::Red << "You don't seem to be in the editing menu")(); 59 | break; 60 | case 1: 61 | if (Process::Read32(0x803CAEC, val) && val == 0xFFFFFFFF) { 62 | Keyboard keyboard("Type a new creator name.\n(Characters \u0022%\u0022 and \u0022\u005C\u0022 are unsaveable!"); 63 | keyboard.SetMaxLength(10); 64 | int op = keyboard.Open(textvalue); 65 | if(op == -1) 66 | return; 67 | Process::WriteString(0x880CCCE, textvalue, StringFormat::Utf16); 68 | Process::Write16(0x880CCE2, 0); 69 | OSD::Notify("Creator name changed!"); 70 | Process::ReadString(0x880CCCE, wrote, 0x20, StringFormat::Utf16); 71 | if (strstr(wrote.c_str(), "%")) { 72 | std::string toSearch("%"); 73 | std::vector IndexVec = GetSubstrIndexList(wrote, toSearch); 74 | if (IndexVec.size()) 75 | { 76 | for (size_t i = 0; i < IndexVec.size(); i++) { 77 | ReplaceSTR(wrote, toSearch, "?", IndexVec.at(i)); 78 | } 79 | Process::WriteString(0x880CCCE, wrote, StringFormat::Utf16); 80 | MessageBox("Invalid characters detected (%), fixed.")(); 81 | } 82 | } 83 | if (strstr(wrote.c_str(), "\\")) { 84 | std::string toSearch("\\"); 85 | std::vector IndexVec = GetSubstrIndexList(wrote, toSearch); 86 | if (IndexVec.size()) 87 | { 88 | for (size_t i = 0; i < IndexVec.size(); i++) { 89 | ReplaceSTR(wrote, toSearch, "?", IndexVec.at(i)); 90 | } 91 | Process::WriteString(0x880CCCE, wrote, StringFormat::Utf16); 92 | MessageBox("Invalid characters detected (\\), fixed.")(); 93 | } 94 | } 95 | } 96 | else MessageBox(Color::Red << "You don't seem to be in the editing menu")(); 97 | break; 98 | } 99 | } 100 | 101 | bool TWNvalidOSD(const Screen &screen) 102 | { 103 | u32 browpos = 0x880CC58; //0x8C8C difference from regular 104 | u32 browspace = 0x880CC54;/// 105 | u32 browrot = 0x880CC50;/// 106 | u32 browsize = 0x880CC48;/// 107 | u32 browidth = 0x880CC4C;/// 108 | u32 eyepos = 0x880CC3C;/// 109 | u32 eyespace = 0x880CC38;/// 110 | u32 eyerot = 0x880CC34;/// 111 | u32 eyesize = 0x880CC2C;/// 112 | u32 eyewidth = 0x880CC30;/// 113 | u32 nosepos = 0x880CC64;/// 114 | u32 nosesize = 0x880CC60;/// 115 | u32 mouthpos = 0x880CC78;/// 116 | u32 mouthsize = 0x880CC70;/// 117 | u32 mouthwidth = 0x880CC74;/// 118 | u32 glasspos = 0x880CC9C;/// 119 | u32 glassize = 0x880CC98;/// 120 | u32 stachepos = 0x880CC8C;/// 121 | u32 stachesize = 0x880CC88;/// 122 | u32 molex = 0x880CCA8;/// 123 | u32 moley = 0x880CCAC;/// 124 | u32 molesize = 0x880CCA4;/// 125 | u32 tall = 0x880CCB0;/// 126 | u32 wide = 0x880CCB4;/// 127 | u32 share = 0x880CCF7;/// 128 | u32 gold = 0x880CD0C;/// 129 | u8 val; 130 | u8 nibble; 131 | if (screen.IsTop && (*(u32 *)0x803CAEC == 0xFFFFFFFF)) 132 | { 133 | if(!IsValidPosition(*(u8 *)browpos, *(u8 *)browspace, *(u8 *)browrot, *(u8 *)browsize, *(u8 *)browidth, *(u8 *)eyepos, *(u8 *)eyespace, *(u8 *)eyerot, *(u8 *)eyesize, *(u8 *)eyewidth, *(u8 *)nosepos, *(u8 *)nosesize, *(u8 *)mouthpos, *(u8 *)mouthsize, *(u8 *)mouthwidth, *(u8 *)glasspos, *(u8 *)glassize, *(u8 *)stachepos, *(u8 *)stachesize, *(u8 *)molex, *(u8 *)moley, *(u8 *)molesize, *(u8 *)tall, *(u8 *)wide, *(u8 *)gold, *(u8 *)share, val, nibble)) { 134 | screen.Draw("Unsavable", 0, 0, Color::Red); 135 | } 136 | else screen.Draw("Savable", 0, 0, Color::Green); 137 | } 138 | return true; 139 | } 140 | bool TWNaddressOSD(const Screen &screen) 141 | { 142 | u8 val; 143 | if (screen.IsTop && (*(u32 *)0x8AF73A4 == 0xB88C50) && (*(u16 *)0x88014D5 == 0)) 144 | { 145 | if (Process::Read8(0x88014D4, val)) { 146 | screen.Draw(Utils::Format("Mii Data Address: %X", (0x17200 * val) + 0x8831C84), 0, 0, Color::Cyan); 147 | screen.Draw(Utils::Format("Mii Data Address In Save (RAM): %X", (0x5C * val) + 0x1488B928), 0, 10, Color::Cyan); 148 | } 149 | } 150 | return true; 151 | } 152 | 153 | void TWNOSD(MenuEntry *entry) 154 | { 155 | if (entry->WasJustActivated()) 156 | { 157 | //OSD::Run(TWNvalidOSD); 158 | OSD::Run(TWNaddressOSD); 159 | } 160 | else if (!entry->IsActivated()) 161 | { 162 | //OSD::Stop(TWNvalidOSD); 163 | OSD::Stop(TWNaddressOSD); 164 | } 165 | } 166 | 167 | void TWNcopymii(MenuEntry *entry) { 168 | u8 val; 169 | u32 dataline; 170 | u32 numint; 171 | if(Controller::IsKeysPressed(entry->Hotkeys[0].GetKeys())) { 172 | if (*(u32 *)0x8AF73A4 == 0xB88C50 && (*(u16 *)0x88014D5 == 0)) 173 | { 174 | if (Process::Read8(0x88014D4, val)) { 175 | for (int i = 0; i < 256; i+=4) 176 | { 177 | if (Process::Read32((0x17200 * val) + (0x8831C84 + i), dataline)) 178 | { 179 | Process::Write32((0x1E81000 + i), dataline); 180 | } 181 | } 182 | std::string name; 183 | Process::ReadString((0x17200 * val) + 0x8831D38, name, 0x20, StringFormat::Utf16); 184 | OSD::Notify("Copied: " + name); 185 | Process::Write8(0x01E81108, 0x1); 186 | } 187 | } 188 | else OSD::Notify(Color::Red << "No Mii selected!"); 189 | } 190 | if(Controller::IsKeysPressed(entry->Hotkeys[1].GetKeys())) { 191 | if (*(u32 *)0x803CAEC == 0xFFFFFFFF && (*(u8 *)0x01E81108 == 0x1)) 192 | { 193 | if (*(u32 *)0x8801164 != 0xFFFFFFFF) 194 | { 195 | Sleep(Milliseconds(100)); 196 | MessageBox("Paste this onto the Mii in the Create New Mii editor to avoid the save file from breaking!")(); 197 | return; 198 | } 199 | if (*(u32 *)0x8801164 == 0xFFFFFFFF) 200 | { 201 | for (int i = 0; i < 256; i+=4) 202 | { 203 | if (Process::Read32(0x1E81000 + i, dataline)) 204 | { 205 | Process::Write32((0x880CC04 + i), dataline); 206 | } 207 | } 208 | std::string name; 209 | Process::ReadString(0x880CCB8, name, 0x20, StringFormat::Utf16); 210 | OSD::Notify("Pasted: " + name); 211 | } 212 | } 213 | else OSD::Notify(Color::Red << "No Mii in clipboard and/or you aren't in the editor!"); 214 | } 215 | } 216 | 217 | void TWNdumpsave(MenuEntry *entry) { 218 | Directory SaveDir; 219 | if (Directory::IsExists("/Miichanic") == 0) 220 | Directory::Create("/Miichanic"); 221 | 222 | File SaveFile; 223 | File::Open(SaveFile,"/Miichanic/CFL_DB.dat", File::RWC); 224 | SaveFile.Dump(0x1488B920, 0x4BD20); 225 | SaveFile.Close(); 226 | MessageBox("Dump complete!")(); 227 | } 228 | void TWNrestoresave(MenuEntry *entry) { 229 | Directory SaveDir; 230 | File SaveFile; 231 | Directory::Open(SaveDir,"/Miichanic", true); 232 | SaveDir.OpenFile(SaveFile,"CFL_DB.dat", File::READ); 233 | SaveFile.Inject(0x1488B920, 0x4BD20); 234 | MessageBox("Save restored!")(); 235 | } 236 | 237 | void TWNcallencrypt(MenuEntry *entry) { 238 | if(Controller::IsKeysPressed(entry->Hotkeys[0].GetKeys())) { 239 | TWNencrypt(); 240 | } 241 | } 242 | } -------------------------------------------------------------------------------- /Includes/csvc.h: -------------------------------------------------------------------------------- 1 | /* This paricular file is licensed under the following terms: */ 2 | 3 | /* 4 | * This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable 5 | * for any damages arising from the use of this software. 6 | * 7 | * Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it 8 | * and redistribute it freely, subject to the following restrictions: 9 | * 10 | * The origin of this software must not be misrepresented; you must not claim that you wrote the original software. 11 | * If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 12 | * 13 | * Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 14 | * This notice may not be removed or altered from any source distribution. 15 | */ 16 | 17 | #pragma once 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | #include 24 | 25 | #define PA_RWX(add) (add == 0 ? 0 : (add < 0x30000000 ? (u32)((add) | (1u << 31)) : add)) 26 | #define PA_FROM_VA(addr) PA_RWX(svcConvertVAToPA((void *)addr, false)) 27 | 28 | /// Operations for svcControlService 29 | typedef enum ServiceOp 30 | { 31 | SERVICEOP_STEAL_CLIENT_SESSION = 0, ///< Steal a client session given a service or global port name 32 | SERVICEOP_GET_NAME, ///< Get the name of a service or global port given a client or session handle 33 | } ServiceOp; 34 | 35 | /** 36 | * @brief Executes a function in supervisor mode, using the supervisor-mode stack. 37 | * @param func Function to execute. 38 | * @param ... Function parameters, up to 3 registers. 39 | */ 40 | Result svcCustomBackdoor(void *func, ...); 41 | 42 | ///@name I/O 43 | ///@{ 44 | /** 45 | * @brief Gives the physical address corresponding to a virtual address. 46 | * @param VA Virtual address. 47 | * @param writeCheck whether to check if the VA is writable in supervisor mode 48 | * @return The corresponding physical address, or NULL. 49 | */ 50 | u32 svcConvertVAToPA(const void *VA, bool writeCheck); 51 | 52 | /** 53 | * @brief Flushes a range of the data cache (L2C included). 54 | * @param addr Start address. 55 | * @param len Length of the range. 56 | */ 57 | void svcFlushDataCacheRange(void *addr, u32 len); 58 | 59 | /** 60 | * @brief Flushes the data cache entirely (L2C included). 61 | */ 62 | void svcFlushEntireDataCache(void); 63 | 64 | /** 65 | * @brief Invalidates a range of the instruction cache. 66 | * @param addr Start address. 67 | * @param len Length of the range. 68 | */ 69 | void svcInvalidateInstructionCacheRange(void *addr, u32 len); 70 | 71 | /** 72 | * @brief Invalidates the data cache entirely. 73 | */ 74 | void svcInvalidateEntireInstructionCache(void); 75 | ///@} 76 | 77 | ///@name Memory management 78 | ///@{ 79 | /** 80 | * @brief Maps a block of process memory. 81 | * @param dstProcessHandle Handle of the process to map the memory in (destination) 82 | * @param destAddress Start address of the memory block in the destination process 83 | * @param srcProcessHandle Handle of the process to map the memory from (source) 84 | * @param srcAddress Start address of the memory block in the source process 85 | * @param size Size of the block of the memory to map (truncated to a multiple of 0x1000 bytes) 86 | */ 87 | Result svcMapProcessMemoryEx(Handle dstProcessHandle, u32 destAddress, Handle srcProcessHandle, u32 srcAddress, u32 size); 88 | 89 | /** 90 | * @brief Unmaps a block of process memory. 91 | * @param process Handle of the process to unmap the memory from 92 | * @param destAddress Address of the block of memory to unmap 93 | * @param size Size of the block of memory to unmap (truncated to a multiple of 0x1000 bytes). 94 | * This function should only be used to unmap memory mapped with svcMapProcessMemoryEx 95 | */ 96 | Result svcUnmapProcessMemoryEx(Handle process, u32 destAddress, u32 size); 97 | 98 | /** 99 | * @brief Controls memory mapping, with the choice to use region attributes or not. 100 | * @param[out] addr_out The virtual address resulting from the operation. Usually the same as addr0. 101 | * @param addr0 The virtual address to be used for the operation. 102 | * @param addr1 The virtual address to be (un)mirrored by @p addr0 when using @ref MEMOP_MAP or @ref MEMOP_UNMAP. 103 | * It has to be pointing to a RW memory. 104 | * Use NULL if the operation is @ref MEMOP_FREE or @ref MEMOP_ALLOC. 105 | * @param size The requested size for @ref MEMOP_ALLOC and @ref MEMOP_ALLOC_LINEAR. 106 | * @param op Operation flags. See @ref MemOp. 107 | * @param perm A combination of @ref MEMPERM_READ and @ref MEMPERM_WRITE. Using MEMPERM_EXECUTE will return an error. 108 | * Value 0 is used when unmapping memory. 109 | * @param isLoader Whether to use the region attributes 110 | * If a memory is mapped for two or more addresses, you have to use MEMOP_UNMAP before being able to MEMOP_FREE it. 111 | * MEMOP_MAP will fail if @p addr1 was already mapped to another address. 112 | * 113 | * @sa svcControlMemory 114 | */ 115 | Result svcControlMemoryEx(u32* addr_out, u32 addr0, u32 addr1, u32 size, MemOp op, MemPerm perm, bool isLoader); 116 | 117 | /** 118 | * @brief Controls memory mapping, this version removes all checks which were being done 119 | * The only operations supported are MEMOP_FREE, MEMOP_ALLOC and MEMOP_ALLOC_LINEAR 120 | * All memory allocated with this svc, must be freed with this svc as well 121 | * @param[out] addr_out The virtual address resulting from the operation. Usually the same as addr0. 122 | * @param addr0 The virtual address to be used for the operation. 123 | * @param size The requested size for @ref MEMOP_ALLOC and @ref MEMOP_ALLOC_LINEAR. 124 | * @param op Operation flags. See @ref MemOp. 125 | * @param perm A combination of @ref MEMPERM_READ and @ref MEMPERM_WRITE 126 | * Value 0 is used when unmapping memory. 127 | * @sa svcControlMemory 128 | */ 129 | Result svcControlMemoryUnsafe(u32 *out, u32 addr0, u32 size, MemOp op, MemPerm perm); 130 | ///@} 131 | 132 | ///@name System 133 | ///@{ 134 | /** 135 | * @brief Performs actions related to services or global handles. 136 | * @param op The operation to perform, see @ref ServiceOp. 137 | * 138 | * Examples: 139 | * svcControlService(SERVICEOP_GET_NAME, (char [12])outName, (Handle)clientOrSessionHandle); 140 | * svcControlService(SERVICEOP_STEAL_CLIENT_SESSION, (Handle *)&outHandle, (const char *)name); 141 | */ 142 | Result svcControlService(ServiceOp op, ...); 143 | 144 | /** 145 | * @brief Copy a handle from a process to another one. 146 | * @param[out] out The output handle. 147 | * @param outProcess Handle of the process of the output handle. 148 | * @param in The input handle. Pseudo-handles are not accepted. 149 | * @param inProcess Handle of the process of the input handle. 150 | */ 151 | Result svcCopyHandle(Handle *out, Handle outProcess, Handle in, Handle inProcess); 152 | 153 | /** 154 | * @brief Get the address and class name of the underlying kernel object corresponding to a handle. 155 | * @param[out] outKAddr The output kernel address. 156 | * @param[out] outName Output class name. The buffer should be large enough to contain it. 157 | * @param in The input handle. 158 | */ 159 | Result svcTranslateHandle(u32 *outKAddr, char *outClassName, Handle in); 160 | 161 | /// Operations for svcControlProcess 162 | typedef enum ProcessOp 163 | { 164 | PROCESSOP_GET_ALL_HANDLES, ///< List all handles of the process, varg3 can be either 0 to fetch all handles, or token of the type to fetch 165 | ///< s32 count = svcControlProcess(handle, PROCESSOP_GET_ALL_HANDLES, (u32)&outBuf, 0) 166 | ///< Returns how many handles were found 167 | 168 | PROCESSOP_SET_MMU_TO_RWX, ///< Set the whole memory of the process with rwx access (in the mmu table only) 169 | ///< svcControlProcess(handle, PROCESSOP_SET_MMU_TO_RWX, 0, 0) 170 | 171 | PROCESSOP_GET_ON_MEMORY_CHANGE_EVENT, ///< Get the handle of an event which will be signaled each time the memory layout of this process changes 172 | ///< svcControlProcess(handle, PROCESSOP_GET_ON_MEMORY_CHANGE_EVENT, &eventHandleOut, 0) 173 | 174 | PROCESSOP_SIGNAL_ON_EXIT, ///< Set a flag to be signaled when the process will be exited 175 | ///< svcControlProcess(handle, PROCESSOP_SIGNAL_ON_EXIT, 0, 0) 176 | PROCESSOP_GET_PA_FROM_VA, ///< Get the physical address of the VAddr within the process 177 | ///< svcControlProcess(handle, PROCESSOP_GET_PA_FROM_VA, (u32)&PAOut, VAddr) 178 | 179 | PROCESSOP_SCHEDULE_THREADS, ///< Lock / Unlock the process's threads 180 | ///< svcControlProcess(handle, PROCESSOP_SCHEDULE_THREADS, lock, threadPredicate) 181 | ///< lock: 0 to unlock threads, any other value to lock threads 182 | ///< threadPredicate: can be NULL or a funcptr to a predicate (typedef bool (*ThreadPredicate)(KThread *thread);) 183 | ///< The predicate must return true to operate on the thread 184 | } ProcessOp; 185 | 186 | Result svcControlProcess(Handle process, ProcessOp op, u32 varg2, u32 varg3); 187 | ///@} 188 | 189 | #ifdef __cplusplus 190 | } 191 | #endif 192 | -------------------------------------------------------------------------------- /Sources/main.cpp: -------------------------------------------------------------------------------- 1 | #include "cheats.hpp" 2 | #include 3 | 4 | void abort(void); 5 | 6 | extern "C" void _ZN18CTRPluginFramework10SearchMenu12ProcessEventERSt6vectorINS_5EventESaIS2_EERNS_4TimeE(); 7 | 8 | namespace CTRPluginFramework 9 | { 10 | 11 | // This function is called before main and before the game starts 12 | // Useful to do code edits safely 13 | void PatchProcess(FwkSettings &settings) 14 | { 15 | *(u32*)((u32)(_ZN18CTRPluginFramework10SearchMenu12ProcessEventERSt6vectorINS_5EventESaIS2_EERNS_4TimeE) 16 | + 0xB4) = 0xE1A00000; 17 | 18 | settings.AllowSearchEngine = true; 19 | settings.AllowActionReplay = true; 20 | settings.WaitTimeToBoot = Time(Seconds(5)); 21 | settings.BackgroundMainColor = Color::Black; 22 | settings.BackgroundSecondaryColor = Color::Black; 23 | settings.BackgroundBorderColor = Color::Silver; 24 | settings.MainTextColor = Color::White; 25 | settings.WindowTitleColor = Color::White; 26 | settings.MenuSelectedItemColor = Color::White; 27 | settings.MenuUnselectedItemColor = Color::White; 28 | settings.Keyboard.Background = Color::Black; 29 | settings.Keyboard.KeyBackground = Color::Black; 30 | settings.Keyboard.KeyBackgroundPressed = Color::Silver; 31 | settings.Keyboard.KeyText = Color::White; 32 | settings.Keyboard.KeyTextPressed = Color::White; 33 | settings.Keyboard.Cursor = Color::White; 34 | settings.Keyboard.Input = Color::White; 35 | settings.CustomKeyboard.BackgroundMain = Color::Black; 36 | settings.CustomKeyboard.BackgroundSecondary = Color::Black; 37 | settings.CustomKeyboard.BackgroundBorder = Color::Silver; 38 | settings.CustomKeyboard.KeyBackground = Color::Black; 39 | settings.CustomKeyboard.KeyBackgroundPressed = Color::Gainsboro; 40 | settings.CustomKeyboard.KeyText = Color::White; 41 | settings.CustomKeyboard.KeyTextPressed = Color::Black; 42 | settings.CustomKeyboard.ScrollBarBackground = Color::Silver; 43 | settings.CustomKeyboard.ScrollBarThumb = Color::DimGrey; 44 | } 45 | 46 | static MenuEntry *AddArg(void *arg, MenuEntry *entry) 47 | { 48 | if(entry != nullptr) 49 | entry->SetArg(arg); 50 | return (entry); 51 | } 52 | 53 | static MenuEntry *EntryWithHotkey(MenuEntry *entry, const Hotkey &hotkey) 54 | { 55 | if (entry != nullptr) 56 | { 57 | entry->Hotkeys += hotkey; 58 | entry->SetArg(new std::string(entry->Name())); 59 | entry->Name() += " " + hotkey.ToString(); 60 | entry->Hotkeys.OnHotkeyChangeCallback([](MenuEntry *entry, int index) 61 | { 62 | std::string *name = reinterpret_cast(entry->GetArg()); 63 | 64 | entry->Name() = *name + " " + entry->Hotkeys[0].ToString(); 65 | }); 66 | } 67 | 68 | return (entry); 69 | } 70 | 71 | static MenuEntry *EntryWithHotkey(MenuEntry *entry, const std::vector &hotkeys) 72 | { 73 | if (entry != nullptr) 74 | { 75 | for (const Hotkey &hotkey : hotkeys) 76 | entry->Hotkeys += hotkey; 77 | } 78 | 79 | return (entry); 80 | } 81 | 82 | int main() 83 | { 84 | if (Process::GetTitleID() == TID_JPN || Process::GetTitleID() == TID_USA || Process::GetTitleID() == TID_EUR) 85 | { 86 | PluginMenu *menu = new PluginMenu("Miichanic's Tool Box (JP/US/EU)", 0, 6, 1, "A set of cheats for 3DS Mii Maker made by Foofoo\n\nyoutube.com/c/foofooanimations"); 87 | menu->SynchronizeWithFrame(true); 88 | 89 | const std::vector JPUSEUeditorEntries{ 90 | new MenuEntry("Nickname / Creator Modifier", nullptr, namedit, "Be free from the restrictions!\n(But the length is still capped at 10 because that doesn't actually save.)"), 91 | EntryWithHotkey(new MenuEntry("Copy and paste Mii data", copymii, "Copy any Mii!\nTap on a Mii in the View Mii Characters menu and press the hotkey to copy.\nThen go to the editor and use the paste hotkey.\nYou may have to edit something manually to make the preview update, but it's all there ready for saving."), { Hotkey(Key::DPadUp, "Copy Mii data"), Hotkey(Key::DPadDown, "Paste the Mii into editor")}), 92 | }; 93 | 94 | const std::vector JPUSEUsaveEntries{ 95 | new MenuEntry("Dump save file", nullptr, dumpsave, "Backup your save file!\nDumps are stored in: SD:Miichanic/CFL_DB.dat"), 96 | new MenuEntry("Restore save file", nullptr, restoresave), 97 | EntryWithHotkey(new MenuEntry("Mega menu", megamenu, "Tap on a mii and press the hotkeys, it can't do everything, but it's useful.\nMii parsing is borrowed from kazuki-4ys"), { Hotkey(Key::A | Key::DPadRight, "Open menu")}), 98 | EntryWithHotkey(new MenuEntry("Create Mii QR code (Read Note)", callencrypt, "WARNING: This cheat is unstable and might freeze the game. make sure you save before using it!\n\nThis creates a QR Code of the mii you're selecting.\nMake sure that your screen is bright enough if you are scanning it from your screen!\nThanks to Goombi and Redshyguy for their code"), { Hotkey(Key::A | Key::B, "run it")}), 99 | }; 100 | 101 | // ítems 102 | menu->Append(new MenuFolder("Editor codes", JPUSEUeditorEntries)); 103 | menu->Append(new MenuFolder("Save file options", JPUSEUsaveEntries)); 104 | menu->Append(new MenuEntry("Useless OSD", OSD, "Some useful OSD, just says the address of your current mii selection.\nThis might freeze the game, so only turn it on when you need it.")); 105 | menu->Append(new MenuEntry("Toggle theme", savetheme, "On is Light theme, and off is dark theme.\n(Close the menu for it to change)")); 106 | menu->Append(new MenuEntry("Exit to home menu", nullptr, exitgame, "This is only really useful if the app stops you from closing it.")); 107 | 108 | menu->Run(); 109 | delete menu; 110 | } 111 | else if (Process::GetTitleID() == TID_CHN || Process::GetTitleID() == TID_TWN) 112 | { 113 | PluginMenu *menu = new PluginMenu("Miichanic's Tool Box (CHN/TWN)", 0, 6, 1, "A set of cheats for 3DS Mii Studio made by Foofoo\n\nyoutube.com/c/foofooanimations"); 114 | menu->SynchronizeWithFrame(true); 115 | 116 | const std::vector TWNeditorEntries{ 117 | new MenuEntry("Nickname / Creator Modifier", nullptr, TWNnamedit, "Be free from the restrictions!\n(But the length is still capped at 10 because that doesn't actually save.)"), 118 | EntryWithHotkey(new MenuEntry("Copy and paste Mii data", TWNcopymii, "Copy any Mii!\nTap on a Mii in the View Mii Characters menu and press the hotkey to copy.\nThen go to the editor and use the paste hotkey.\nYou may have to edit something manually to make the preview update, but it's all there ready for saving."), { Hotkey(Key::DPadUp, "Copy Mii data"), Hotkey(Key::DPadDown, "Paste the Mii into editor")}), 119 | }; 120 | 121 | const std::vector TWNsaveEntries{ 122 | new MenuEntry("Dump save file", nullptr, TWNdumpsave, "Backup your save file!\nDumps are stored in: SD:Miichanic/CFL_DB.dat"), 123 | new MenuEntry("Restore save file", nullptr, TWNrestoresave), 124 | EntryWithHotkey(new MenuEntry("mega menu", megamenu, "tap on a mii and press the hotkeys, it can't do everything, but it's useful.\nMii parsing is borrowed from kazuki-4ys"), { Hotkey(Key::A | Key::DPadRight, "Open menu")}), 125 | EntryWithHotkey(new MenuEntry("Create Mii QR code (Read Note)", TWNcallencrypt, "WARNING: This cheat is unstable and might freeze the game. make sure you save before using it!\n\nThis creates a QR Code of the mii you're selecting.\nMake sure that your screen is bright enough if you are scanning it from your screen!\nThanks to Goombi and Redshyguy for their code"), { Hotkey(Key::A | Key::B, "run it")}), 126 | }; 127 | 128 | // ítems 129 | menu->Append(new MenuFolder("Editor codes", TWNeditorEntries)); 130 | menu->Append(new MenuFolder("Save file options", TWNsaveEntries)); 131 | menu->Append(new MenuEntry("Useless OSD", TWNOSD, "Some useful OSD, just says the address of your current mii selection.\nThis might freeze the game, so only turn it on when you need it.")); 132 | menu->Append(new MenuEntry("Toggle Theme", savetheme, "On is Light theme, and off is dark theme.\n(Close the menu for it to change)")); 133 | menu->Append(new MenuEntry("Exit to home menu", nullptr, exitgame, "This is only really useful if the app stops you from closing it.")); 134 | 135 | menu->Run(); 136 | delete menu; 137 | } 138 | else if (Process::GetTitleID() == TID_KOR) 139 | { 140 | PluginMenu *menu = new PluginMenu("Miichanic's Tool Box (KOR)", 0, 6, 1, "A set of cheats for 3DS Mii Studio made by Foofoo\n\nyoutube.com/c/foofooanimations"); 141 | menu->SynchronizeWithFrame(true); 142 | 143 | const std::vector KOReditorEntries{ 144 | new MenuEntry("Nickname / Creator Modifier", nullptr, KORnamedit, "Be free from the restrictions!\n(But the length is still capped at 10 because that doesn't actually save.)"), 145 | EntryWithHotkey(new MenuEntry("Copy and paste Mii data", KORcopymii, "Copy any Mii!\nTap on a Mii in the View Mii Characters menu and press the hotkey to copy.\nThen go to the editor and use the paste hotkey.\nYou may have to edit something manually to make the preview update, but it's all there ready for saving."), { Hotkey(Key::DPadUp, "Copy Mii data"), Hotkey(Key::DPadDown, "Paste the Mii into editor")}), 146 | }; 147 | 148 | const std::vector KORsaveEntries{ 149 | new MenuEntry("Dump save file", nullptr, KORdumpsave, "Backup your save file!\nDumps are stored in: SD:Miichanic/CFL_DB.dat"), 150 | new MenuEntry("Restore save file", nullptr, KORrestoresave), 151 | EntryWithHotkey(new MenuEntry("mega menu", megamenu, "tap on a mii and press the hotkeys, it can't do everything, but it's useful.\nMii parsing is borrowed from kazuki-4ys"), { Hotkey(Key::A | Key::DPadRight, "Open menu")}), 152 | EntryWithHotkey(new MenuEntry("Create Mii QR code (Read Note)", KORcallencrypt, "WARNING: This cheat is unstable and might freeze the game. make sure you save before using it!\n\nThis creates a QR Code of the mii you're selecting.\nMake sure that your screen is bright enough if you are scanning it from your screen!\nThanks to Goombi and Redshyguy for their code"), { Hotkey(Key::A | Key::B, "run it")}), 153 | }; 154 | 155 | // ítems 156 | menu->Append(new MenuFolder("Editor codes", KOReditorEntries)); 157 | menu->Append(new MenuFolder("Save file options", KORsaveEntries)); 158 | menu->Append(new MenuEntry("Useless OSD", KOROSD, "Some useful OSD, just says the address of your current mii selection.\nThis might freeze the game, so only turn it on when you need it.")); 159 | menu->Append(new MenuEntry("Toggle Theme", savetheme, "On is Light theme, and off is dark theme.\n(Close the menu for it to change)")); 160 | menu->Append(new MenuEntry("Exit to home menu", nullptr, exitgame, "This is only really useful if the app stops you from closing it.")); 161 | 162 | menu->Run(); 163 | delete menu; 164 | } 165 | else 166 | MessageBox("Hey, this isn't Mii Maker!")(); 167 | PluginMenu *menu = new PluginMenu("Miichanic's Tool Box (N/A)", 0, 0, 0, "Empty."); 168 | menu->SynchronizeWithFrame(true); 169 | menu->Run(); 170 | delete menu; 171 | return 0; 172 | } 173 | 174 | } -------------------------------------------------------------------------------- /Includes/Helpers/QRCodeGen.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * QR Code generator library (C) 3 | * 4 | * Copyright (c) Project Nayuki. (MIT License) 5 | * https://www.nayuki.io/page/qr-code-generator-library 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | * this software and associated documentation files (the "Software"), to deal in 9 | * the Software without restriction, including without limitation the rights to 10 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 | * the Software, and to permit persons to whom the Software is furnished to do so, 12 | * subject to the following conditions: 13 | * - The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * - The Software is provided "as is", without warranty of any kind, express or 16 | * implied, including but not limited to the warranties of merchantability, 17 | * fitness for a particular purpose and noninfringement. In no event shall the 18 | * authors or copyright holders be liable for any claim, damages or other 19 | * liability, whether in an action of contract, tort or otherwise, arising from, 20 | * out of or in connection with the Software or the use or other dealings in the 21 | * Software. 22 | */ 23 | 24 | #pragma once 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | /*---- Enum and struct types----*/ 31 | 32 | /* 33 | * The error correction level used in a QR Code symbol. 34 | */ 35 | enum qrcodegen_Ecc { 36 | qrcodegen_Ecc_LOW = 0, 37 | qrcodegen_Ecc_MEDIUM, 38 | qrcodegen_Ecc_QUARTILE, 39 | qrcodegen_Ecc_HIGH, 40 | }; 41 | 42 | 43 | /* 44 | * The mask pattern used in a QR Code symbol. 45 | */ 46 | enum qrcodegen_Mask { 47 | // A special value to tell the QR Code encoder to 48 | // automatically select an appropriate mask pattern 49 | qrcodegen_Mask_AUTO = -1, 50 | // The eight actual mask patterns 51 | qrcodegen_Mask_0 = 0, 52 | qrcodegen_Mask_1, 53 | qrcodegen_Mask_2, 54 | qrcodegen_Mask_3, 55 | qrcodegen_Mask_4, 56 | qrcodegen_Mask_5, 57 | qrcodegen_Mask_6, 58 | qrcodegen_Mask_7, 59 | }; 60 | 61 | 62 | /* 63 | * The mode field of a segment. 64 | */ 65 | enum qrcodegen_Mode { 66 | qrcodegen_Mode_NUMERIC, 67 | qrcodegen_Mode_ALPHANUMERIC, 68 | qrcodegen_Mode_BYTE, 69 | qrcodegen_Mode_KANJI, 70 | qrcodegen_Mode_ECI, 71 | }; 72 | 73 | 74 | /* 75 | * A segment of user/application data that a QR Code symbol can convey. 76 | * Each segment has a mode, a character count, and character/general data that is 77 | * already encoded as a sequence of bits. The maximum allowed bit length is 32767, 78 | * because even the largest QR Code (version 40) has only 31329 modules. 79 | */ 80 | struct qrcodegen_Segment { 81 | // The mode indicator for this segment. 82 | enum qrcodegen_Mode mode; 83 | 84 | // The length of this segment's unencoded data. Always in the range [0, 32767]. 85 | // For numeric, alphanumeric, and kanji modes, this measures in Unicode code points. 86 | // For byte mode, this measures in bytes (raw binary data, text in UTF-8, or other encodings). 87 | // For ECI mode, this is always zero. 88 | int numChars; 89 | 90 | // The data bits of this segment, packed in bitwise big endian. 91 | // Can be null if the bit length is zero. 92 | uint8_t *data; 93 | 94 | // The number of valid data bits used in the buffer. Requires 95 | // 0 <= bitLength <= 32767, and bitLength <= (capacity of data array) * 8. 96 | int bitLength; 97 | }; 98 | 99 | 100 | 101 | /*---- Macro constants and functions ----*/ 102 | 103 | // The minimum and maximum defined QR Code version numbers for Model 2. 104 | #define qrcodegen_VERSION_MIN 1 105 | #define qrcodegen_VERSION_MAX 40 106 | 107 | // Calculates the number of bytes needed to store any QR Code up to and including the given version number, 108 | // as a compile-time constant. For example, 'uint8_t buffer[qrcodegen_BUFFER_LEN_FOR_VERSION(25)];' 109 | // can store any single QR Code from version 1 to 25, inclusive. 110 | // Requires qrcodegen_VERSION_MIN <= n <= qrcodegen_VERSION_MAX. 111 | #define qrcodegen_BUFFER_LEN_FOR_VERSION(n) ((((n) * 4 + 17) * ((n) * 4 + 17) + 7) / 8 + 1) 112 | 113 | // The worst-case number of bytes needed to store one QR Code, up to and including 114 | // version 40. This value equals 3918, which is just under 4 kilobytes. 115 | // Use this more convenient value to avoid calculating tighter memory bounds for buffers. 116 | #define qrcodegen_BUFFER_LEN_MAX qrcodegen_BUFFER_LEN_FOR_VERSION(qrcodegen_VERSION_MAX) 117 | 118 | 119 | 120 | /*---- Functions to generate QR Codes ----*/ 121 | 122 | /* 123 | * Encodes the given text string to a QR Code symbol, returning true if encoding succeeded. 124 | * If the data is too long to fit in any version in the given range 125 | * at the given ECC level, then false is returned. 126 | * - The input text must be encoded in UTF-8 and contain no NULs. 127 | * - The variables ecl and mask must correspond to enum constant values. 128 | * - Requires 1 <= minVersion <= maxVersion <= 40. 129 | * - The arrays tempBuffer and qrcode must each have a length 130 | * of at least qrcodegen_BUFFER_LEN_FOR_VERSION(maxVersion). 131 | * - After the function returns, tempBuffer contains no useful data. 132 | * - If successful, the resulting QR Code may use numeric, 133 | * alphanumeric, or byte mode to encode the text. 134 | * - In the most optimistic case, a QR Code at version 40 with low ECC 135 | * can hold any UTF-8 string up to 2953 bytes, or any alphanumeric string 136 | * up to 4296 characters, or any digit string up to 7089 characters. 137 | * These numbers represent the hard upper limit of the QR Code standard. 138 | * - Please consult the QR Code specification for information on 139 | * data capacities per version, ECC level, and text encoding mode. 140 | */ 141 | bool qrcodegen_encodeText(const char *text, uint8_t tempBuffer[], uint8_t qrcode[], 142 | enum qrcodegen_Ecc ecl, int minVersion, int maxVersion, enum qrcodegen_Mask mask, bool boostEcl); 143 | 144 | 145 | /* 146 | * Encodes the given binary data to a QR Code symbol, returning true if encoding succeeded. 147 | * If the data is too long to fit in any version in the given range 148 | * at the given ECC level, then false is returned. 149 | * - The input array range dataAndTemp[0 : dataLen] should normally be 150 | * valid UTF-8 text, but is not required by the QR Code standard. 151 | * - The variables ecl and mask must correspond to enum constant values. 152 | * - Requires 1 <= minVersion <= maxVersion <= 40. 153 | * - The arrays dataAndTemp and qrcode must each have a length 154 | * of at least qrcodegen_BUFFER_LEN_FOR_VERSION(maxVersion). 155 | * - After the function returns, the contents of dataAndTemp may have changed, 156 | * and does not represent useful data anymore. 157 | * - If successful, the resulting QR Code will use byte mode to encode the data. 158 | * - In the most optimistic case, a QR Code at version 40 with low ECC can hold any byte 159 | * sequence up to length 2953. This is the hard upper limit of the QR Code standard. 160 | * - Please consult the QR Code specification for information on 161 | * data capacities per version, ECC level, and text encoding mode. 162 | */ 163 | bool qrcodegen_encodeBinary(uint8_t dataAndTemp[], size_t dataLen, uint8_t qrcode[], 164 | enum qrcodegen_Ecc ecl, int minVersion, int maxVersion, enum qrcodegen_Mask mask, bool boostEcl); 165 | 166 | 167 | /* 168 | * Tests whether the given string can be encoded as a segment in alphanumeric mode. 169 | */ 170 | bool qrcodegen_isAlphanumeric(const char *text); 171 | 172 | 173 | /* 174 | * Tests whether the given string can be encoded as a segment in numeric mode. 175 | */ 176 | bool qrcodegen_isNumeric(const char *text); 177 | 178 | 179 | /* 180 | * Returns the number of bytes (uint8_t) needed for the data buffer of a segment 181 | * containing the given number of characters using the given mode. Notes: 182 | * - Returns SIZE_MAX on failure, i.e. numChars > INT16_MAX or 183 | * the number of needed bits exceeds INT16_MAX (i.e. 32767). 184 | * - Otherwise, all valid results are in the range [0, ceil(INT16_MAX / 8)], i.e. at most 4096. 185 | * - It is okay for the user to allocate more bytes for the buffer than needed. 186 | * - For byte mode, numChars measures the number of bytes, not Unicode code points. 187 | * - For ECI mode, numChars must be 0, and the worst-case number of bytes is returned. 188 | * An actual ECI segment can have shorter data. For non-ECI modes, the result is exact. 189 | */ 190 | size_t qrcodegen_calcSegmentBufferSize(enum qrcodegen_Mode mode, size_t numChars); 191 | 192 | 193 | /* 194 | * Returns a segment representing the given binary data encoded in byte mode. 195 | */ 196 | struct qrcodegen_Segment qrcodegen_makeBytes(const uint8_t data[], size_t len, uint8_t buf[]); 197 | 198 | 199 | /* 200 | * Returns a segment representing the given string of decimal digits encoded in numeric mode. 201 | */ 202 | struct qrcodegen_Segment qrcodegen_makeNumeric(const char *digits, uint8_t buf[]); 203 | 204 | 205 | /* 206 | * Returns a segment representing the given text string encoded in alphanumeric mode. 207 | * The characters allowed are: 0 to 9, A to Z (uppercase only), space, 208 | * dollar, percent, asterisk, plus, hyphen, period, slash, colon. 209 | */ 210 | struct qrcodegen_Segment qrcodegen_makeAlphanumeric(const char *text, uint8_t buf[]); 211 | 212 | 213 | /* 214 | * Returns a segment representing an Extended Channel Interpretation 215 | * (ECI) designator with the given assignment value. 216 | */ 217 | struct qrcodegen_Segment qrcodegen_makeEci(long assignVal, uint8_t buf[]); 218 | 219 | 220 | /* 221 | * Renders a QR Code symbol representing the given data segments at the given error correction 222 | * level or higher. The smallest possible QR Code version is automatically chosen for the output. 223 | * Returns true if QR Code creation succeeded, or false if the data is too long to fit in any version. 224 | * This function allows the user to create a custom sequence of segments that switches 225 | * between modes (such as alphanumeric and binary) to encode text more efficiently. 226 | * This function is considered to be lower level than simply encoding text or binary data. 227 | * To save memory, the segments' data buffers can alias/overlap tempBuffer, and will 228 | * result in them being clobbered, but the QR Code output will still be correct. 229 | * But the qrcode array must not overlap tempBuffer or any segment's data buffer. 230 | */ 231 | bool qrcodegen_encodeSegments(const struct qrcodegen_Segment segs[], size_t len, 232 | enum qrcodegen_Ecc ecl, uint8_t tempBuffer[], uint8_t qrcode[]); 233 | 234 | 235 | /* 236 | * Renders a QR Code symbol representing the given data segments with the given encoding parameters. 237 | * Returns true if QR Code creation succeeded, or false if the data is too long to fit in the range of versions. 238 | * The smallest possible QR Code version within the given range is automatically chosen for the output. 239 | * This function allows the user to create a custom sequence of segments that switches 240 | * between modes (such as alphanumeric and binary) to encode text more efficiently. 241 | * This function is considered to be lower level than simply encoding text or binary data. 242 | * To save memory, the segments' data buffers can alias/overlap tempBuffer, and will 243 | * result in them being clobbered, but the QR Code output will still be correct. 244 | * But the qrcode array must not overlap tempBuffer or any segment's data buffer. 245 | */ 246 | bool qrcodegen_encodeSegmentsAdvanced(const struct qrcodegen_Segment segs[], size_t len, enum qrcodegen_Ecc ecl, 247 | int minVersion, int maxVersion, int mask, bool boostEcl, uint8_t tempBuffer[], uint8_t qrcode[]); 248 | 249 | 250 | /*---- Functions to extract raw data from QR Codes ----*/ 251 | 252 | /* 253 | * Returns the side length of the given QR Code, assuming that encoding succeeded. 254 | * The result is in the range [21, 177]. Note that the length of the array buffer 255 | * is related to the side length - every 'uint8_t qrcode[]' must have length at least 256 | * qrcodegen_BUFFER_LEN_FOR_VERSION(version), which equals ceil(size^2 / 8 + 1). 257 | */ 258 | int qrcodegen_getSize(const uint8_t qrcode[]); 259 | 260 | 261 | /* 262 | * Returns the color of the module (pixel) at the given coordinates, which is either 263 | * false for white or true for black. The top left corner has the coordinates (x=0, y=0). 264 | * If the given coordinates are out of bounds, then false (white) is returned. 265 | */ 266 | bool qrcodegen_getModule(const uint8_t qrcode[], int x, int y); -------------------------------------------------------------------------------- /libctrpf/include/CTRPluginFramework/Menu/Keyboard.hpp: -------------------------------------------------------------------------------- 1 | #ifndef CTRPLUGINFRAMEWORK_KEYBOARD_HPP 2 | #define CTRPLUGINFRAMEWORK_KEYBOARD_HPP 3 | 4 | #include "CTRPluginFramework/Graphics/CustomIcon.hpp" 5 | #include "CTRPluginFramework/System/Controller.hpp" 6 | #include "CTRPluginFramework/Sound.hpp" 7 | #include "types.h" 8 | #include 9 | #include 10 | #include 11 | 12 | namespace CTRPluginFramework 13 | { 14 | class KeyboardEvent 15 | { 16 | public: 17 | enum EventType 18 | { 19 | CharacterAdded, 20 | CharacterRemoved, 21 | InputWasCleared, 22 | SelectionChanged, 23 | KeyPressed, 24 | KeyDown, 25 | KeyReleased 26 | }; 27 | 28 | EventType type{}; ///< Type of the event 29 | u32 codepoint{0}; ///< The codepoint of the character that thrown the event (used for CharacterAdded and CharacterRemoved, 0 otherwise) 30 | u32 selectedIndex{0}; ///< The entry index in a custom keyboard being selected (used for SelectionChanged, 0 otherwise) 31 | Key affectedKey{(Key)0}; //< Button affected not mapped to any keyboard feature (used for ButtonPressed, ButtonHold and ButtonReleased, 0 otherwise) 32 | }; 33 | 34 | class KeyboardImpl; 35 | class Keyboard 36 | { 37 | /** 38 | * \brief The signature of the callback called to check the input 39 | * \param input A void pointer to the input, must be casted to the correct type (as passed to Keyboard::Open) 40 | * \param error A reference to the string that hold the error message. You can edit it according to what you want to display 41 | * \return A boolean \n Return true if the input is valid, false if it's not 42 | */ 43 | using CompareCallback = bool (*)(const void *, std::string&); 44 | 45 | /** 46 | * \brief The signature of the callback called when the input change (user enter / delete a character) 47 | * \param keyboard A reference to the Keyboard object that called the callback 48 | * \event event The event that caused the input to change 49 | */ 50 | using OnEventCallback = void(*)(Keyboard&, KeyboardEvent &event); 51 | public: 52 | 53 | /** 54 | * \brief Keyboard constructor 55 | * \param text The message to display on the top screen if displayed 56 | */ 57 | Keyboard(const std::string &text = ""); 58 | Keyboard(const std::string &text, const std::vector &options); 59 | Keyboard(const std::vector &options); 60 | ~Keyboard(void); 61 | 62 | /** 63 | * \brief Set if the user can abort the keybord by pressing B 64 | * \param canAbort Whether the user can press B to close the keyboard and abort the current operation 65 | */ 66 | void CanAbort(bool canAbort) const; 67 | 68 | /** 69 | * \brief Define if the input must be hexadecimal or not \n 70 | * Have no effect for float, double, string 71 | * \param isHex If the input must be hexadecimal 72 | */ 73 | void IsHexadecimal(bool isHex); 74 | 75 | /** 76 | * \brief Define a maximum input length for qwerty keyboard 77 | * \param maxValue The maximum count of characters that the user can type 78 | */ 79 | void SetMaxLength(u32 maxValue) const; 80 | 81 | /** 82 | * \brief Define a callback to check the input \n 83 | * The callback is called each time the input is changed \n 84 | * See CompareCallback's description for more infos 85 | * \param callback The callback that must be called 86 | */ 87 | void SetCompareCallback(CompareCallback callback) const; 88 | 89 | /** 90 | * \brief Define a callback that will be called when the user change the input \n 91 | * Note that if a CompareCallback is set, CompareCallback is called before OnKeyboardEvent \n 92 | * See OnEventCallback's description for more infos 93 | * \param callback 94 | */ 95 | void OnKeyboardEvent(OnEventCallback callback) const; 96 | 97 | /** 98 | * \brief Set the error flag and an error message \n 99 | * When the error flag is set, the user can't valid the input 100 | * \param error The error message that must be displayed 101 | */ 102 | void SetError(std::string error) const; 103 | 104 | /** 105 | * \brief Selects and scroll to the specified entry, must be called after Populate 106 | * \param entry Entry index to select, -1 to deselect all. 107 | */ 108 | void ChangeSelectedEntry(int entry); 109 | 110 | /** 111 | * \brief Sets the sound event to play when the entry is activated 112 | * \param entry Entry index to change the sound event 113 | * \param soundEvent Event to set for the given entry. 114 | */ 115 | void ChangeEntrySound(int entry, SoundEngine::Event soundEvent); 116 | 117 | /** 118 | * \brief Populate a keyboard with the strings contained in an std::vector 119 | * \param input A std::vector that contain a list of strings 120 | * \param resetScroll Set to true to reset the scroll position if the list is the same size 121 | */ 122 | void Populate(const std::vector &input, bool resetScroll = false); 123 | 124 | /** 125 | * \brief Populate a keyboard with the CustomIcons contained in an std::vector 126 | * \param input A std::vector that contains a list of CustomIcons (icon size must be 30x30 pixels, otherwise a red cross will be displayed) 127 | * \param resetScroll Set to true to reset the scroll position if the list is the same size 128 | */ 129 | void Populate(const std::vector& input, bool resetScroll = false); 130 | 131 | /** 132 | * \brief Open a keyboard which is populated with strings 133 | * \return -1 : user abort / not populated \n 134 | * -2 : closed by event callback \n 135 | * >= 0 : index of the user choice in the vector 136 | */ 137 | int Open(void) const; 138 | 139 | /** 140 | * \brief Open the keyboard and wait for user input 141 | * \param output Where to place the user's input 142 | * \return -1 : user abort / error \n 143 | * -2 : closed by event callback \n 144 | * 0 : Success 145 | */ 146 | int Open(u8 &output) const; 147 | 148 | /** 149 | * \brief Open the keyboard and wait for user input 150 | * \param output Where to place the user's input 151 | * \param start The keyboard will start with this value as input 152 | * \return -1 : user abort / error \n 153 | * -2 : closed by event callback \n 154 | * 0 : Success 155 | */ 156 | int Open(u8 &output, u8 start) const; 157 | 158 | /** 159 | * \brief Open the keyboard and wait for user input 160 | * \param output Where to place the user's input 161 | * \return -1 : user abort / error \n 162 | * -2 : closed by event callback \n 163 | * 0 : Success 164 | */ 165 | int Open(u16 &output) const; 166 | 167 | /** 168 | * \brief Open the keyboard and wait for user input 169 | * \param output Where to place the user's input 170 | * \param start The keyboard will start with this value as input 171 | * \return -1 : user abort / error \n 172 | * -2 : closed by event callback \n 173 | * 0 : Success 174 | */ 175 | int Open(u16 &output, u16 start) const; 176 | 177 | /** 178 | * \brief Open the keyboard and wait for user input 179 | * \param output Where to place the user's input 180 | * \return -1 : user abort / error \n 181 | * -2 : closed by event callback \n 182 | * 0 : Success 183 | */ 184 | int Open(u32 &output) const; 185 | 186 | /** 187 | * \brief Open the keyboard and wait for user input 188 | * \param output Where to place the user's input 189 | * \param start The keyboard will start with this value as input 190 | * \return -1 : user abort / error \n 191 | * -2 : closed by event callback \n 192 | * 0 : Success 193 | */ 194 | int Open(u32 &output, u32 start) const; 195 | 196 | /** 197 | * \brief Open the keyboard and wait for user input 198 | * \param output Where to place the user's input 199 | * \return -1 : user abort / error \n 200 | * -2 : closed by event callback \n 201 | * 0 : Success 202 | */ 203 | int Open(u64 &output) const; 204 | 205 | /** 206 | * \brief Open the keyboard and wait for user input 207 | * \param output Where to place the user's input 208 | * \param start The keyboard will start with this value as input 209 | * \return -1 : user abort / error \n 210 | * -2 : closed by event callback \n 211 | * 0 : Success 212 | */ 213 | int Open(u64 &output, u64 start) const; 214 | 215 | /** 216 | * \brief Open the keyboard and wait for user input 217 | * \param output Where to place the user's input 218 | * \return -1 : user abort / error \n 219 | * -2 : closed by event callback \n 220 | * 0 : Success 221 | */ 222 | int Open(float &output) const; 223 | 224 | /** 225 | * \brief Open the keyboard and wait for user input 226 | * \param output Where to place the user's input 227 | * \param start The keyboard will start with this value as input 228 | * \return -1 : user abort / error \n 229 | * -2 : closed by event callback \n 230 | * 0 : Success 231 | */ 232 | int Open(float &output, float start) const; 233 | 234 | /** 235 | * \brief Open the keyboard and wait for user input 236 | * \param output Where to place the user's input 237 | * \return -1 : user abort / error \n 238 | * -2 : closed by event callback \n 239 | * 0 : Success 240 | */ 241 | int Open(double &output) const; 242 | 243 | /** 244 | * \brief Open the keyboard and wait for user input 245 | * \param output Where to place the user's input 246 | * \param start The keyboard will start with this value as input 247 | * \return -1 : user abort / error \n 248 | * -2 : closed by event callback \n 249 | * 0 : Success 250 | */ 251 | int Open(double &output, double start) const; 252 | 253 | /** 254 | * \brief Open the keyboard and wait for user input 255 | * \param output Where to place the user's input 256 | * \return -1 : user abort / error \n 257 | * -2 : closed by event callback \n 258 | * 0 : Success 259 | */ 260 | int Open(std::string &output) const; 261 | 262 | /** 263 | * \brief Open the keyboard and wait for user input 264 | * \param output Where to place the user's input 265 | * \param start The keyboard will start with this value as input 266 | * \return -1 : user abort / error \n 267 | * -2 : closed by event callback \n 268 | * 0 : Success 269 | */ 270 | int Open(std::string &output, const std::string &start) const; 271 | 272 | /** 273 | * \brief Forcefully close the keyboard without any regard to the error flag \n 274 | * (This can only be called from an OnKeyboardEvent callback) 275 | */ 276 | void Close(void) const; 277 | 278 | /** 279 | * \brief Get a reference to the Keyboard's input string 280 | * \return A reference to the Keyboard's input string 281 | */ 282 | std::string &GetInput(void) const; 283 | 284 | /** 285 | * \brief Get a reference to the top screen's message string 286 | * \return A reference to the top screen's message string 287 | */ 288 | std::string &GetMessage(void) const; 289 | 290 | /** 291 | * \brief This property define if the top screen must be displayed or not \n 292 | * Note that when disabled, errors messages can't be displayed 293 | */ 294 | bool DisplayTopScreen; 295 | 296 | private: 297 | std::unique_ptr _keyboard; 298 | bool _hexadecimal; 299 | mutable bool _isPopulated; 300 | }; 301 | } 302 | 303 | #endif 304 | --------------------------------------------------------------------------------