diff --git a/include/savemng.h b/include/savemng.h index ccc47a3..9152106 100644 --- a/include/savemng.h +++ b/include/savemng.h @@ -23,11 +23,6 @@ #define M_OFF 1 #define Y_OFF 1 -#define COLOR_WHITE Color(0xffffffff) -#define COLOR_BLACK Color(0, 0, 0, 255) -#define COLOR_BACKGROUND Color(0x00006F00) -#define COLOR_TEXT COLOR_WHITE - struct Title { uint32_t highID; uint32_t lowID; diff --git a/include/utils/Colors.h b/include/utils/Colors.h new file mode 100644 index 0000000..3e24658 --- /dev/null +++ b/include/utils/Colors.h @@ -0,0 +1,6 @@ +#pragma once + +#define COLOR_WHITE Color(0xffffffff) +#define COLOR_BLACK Color(0, 0, 0, 255) +#define COLOR_BACKGROUND Color(0x00006F00) +#define COLOR_TEXT COLOR_WHITE \ No newline at end of file diff --git a/include/utils/DrawUtils.h b/include/utils/DrawUtils.h index b55ec29..725eb76 100644 --- a/include/utils/DrawUtils.h +++ b/include/utils/DrawUtils.h @@ -35,7 +35,9 @@ class DrawUtils { static bool getRedraw() { return redraw; } - static void initBuffers(void *tvBuffer, uint32_t tvSize, void *drcBuffer, uint32_t drcSize); + static BOOL LogConsoleInit(); + + static void LogConsoleFree(); static void beginDraw(); @@ -73,12 +75,21 @@ class DrawUtils { static void drawRGB5A3(int x, int y, float scale, uint8_t *fileContent); + static uint32_t initScreen(); + + static uint32_t deinitScreen(); + + + + private: static bool redraw; static bool isBackBuffer; + static uint8_t *tvBuffer; - static uint32_t tvSize; static uint8_t *drcBuffer; - static uint32_t drcSize; + + static uint32_t sBufferSizeTV, sBufferSizeDRC; + static BOOL sConsoleHasForeground; }; diff --git a/include/utils/StateUtils.h b/include/utils/StateUtils.h index e788778..4c399fa 100644 --- a/include/utils/StateUtils.h +++ b/include/utils/StateUtils.h @@ -1,10 +1,15 @@ #pragma once +#include + class State { public: static void init(); static bool AppRunning(); static void shutdown(); + static void registerProcUICallbacks(); + static uint32_t ConsoleProcCallbackAcquired(void *context); + static uint32_t ConsoleProcCallbackReleased(void *context); private: static bool aroma; diff --git a/include/version.h b/include/version.h index d98fc50..c784e46 100644 --- a/include/version.h +++ b/include/version.h @@ -2,4 +2,4 @@ #define VERSION_MAJOR 1 #define VERSION_MINOR 6 -#define VERSION_MICRO 1 +#define VERSION_MICRO 2 diff --git a/src/main.cpp b/src/main.cpp index 0f54f5b..fd3deed 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,3 @@ -#include -#include -#include #include #include #include @@ -10,11 +7,15 @@ #include #include #include +#include #include #include #include #include #include +#include +#include +#include static int wiiuTitlesCount = 0, vWiiTitlesCount = 0; @@ -91,10 +92,11 @@ static Title *loadWiiUTitles(int run) { path = StringUtils::stringFormat("%s/usr/save/%08x/%s/meta/meta.xml", (i == 0) ? getUSB().c_str() : "storage_mlc01:", highIDs[a], data->d_name); if (checkEntry(path.c_str()) == 1) { - for (int i = 0; i < usable; i++) { - if (contains(highIDs, savesl[i].highID) && - (strtoul(data->d_name, nullptr, 16) == savesl[i].lowID)) { - savesl[i].found = true; + for (int ii = 0; ii < usable; ii++) { + if (contains(highIDs, savesl[ii].highID) && + (strtoul(data->d_name, nullptr, 16) == savesl[ii].lowID) && + savesl[ii].dev == i ) { + savesl[ii].found = true; tNoSave--; break; } @@ -109,7 +111,7 @@ static Title *loadWiiUTitles(int run) { } foundCount += tNoSave; - auto *saves = (Saves *) malloc((foundCount + tNoSave) * sizeof(Saves)); + auto *saves = (Saves *) malloc((foundCount) * sizeof(Saves)); if (saves == nullptr) { promptError(LanguageUtils::gettext("Out of memory.")); return nullptr; @@ -386,24 +388,14 @@ static void unloadTitles(Title *titles, int count) { int main() { AXInit(); AXQuit(); - OSScreenInit(); - - uint32_t tvBufferSize = OSScreenGetBufferSizeEx(SCREEN_TV); - uint32_t drcBufferSize = OSScreenGetBufferSizeEx(SCREEN_DRC); - - auto *screenBuffer = (uint8_t *) memalign(0x100, tvBufferSize + drcBufferSize); - if (!screenBuffer) { - OSFatal("Fail to allocate screenBuffer"); + + State::init(); + + if (DrawUtils::LogConsoleInit()) { + OSFatal("Failed to initialize OSSCreen"); } - memset(screenBuffer, 0, tvBufferSize + drcBufferSize); - - OSScreenSetBufferEx(SCREEN_TV, screenBuffer); - OSScreenSetBufferEx(SCREEN_DRC, screenBuffer + tvBufferSize); - OSScreenEnableEx(SCREEN_TV, TRUE); - OSScreenEnableEx(SCREEN_DRC, TRUE); - - DrawUtils::initBuffers(screenBuffer, tvBufferSize, screenBuffer + tvBufferSize, drcBufferSize); + State::registerProcUICallbacks(); if (!DrawUtils::initFont()) { OSFatal("Failed to init font"); @@ -412,8 +404,8 @@ int main() { WPADInit(); KPADInit(); WPADEnableURCC(1); + loadWiiUTitles(0); - State::init(); int res = romfsInit(); if (res) { @@ -422,20 +414,20 @@ int main() { State::shutdown(); return 0; } - Swkbd_LanguageType systemLanguage = LanguageUtils::getSystemLanguage(); LanguageUtils::loadLanguage(systemLanguage); if (!initFS()) { promptError(LanguageUtils::gettext("initFS failed. Please make sure your MochaPayload is up-to-date")); DrawUtils::endDraw(); - State::shutdown(); + State::shutdown(); return 0; } DrawUtils::beginDraw(); DrawUtils::clear(COLOR_BLACK); DrawUtils::endDraw(); + Title *wiiutitles = loadWiiUTitles(1); Title *wiititles = loadWiiTitles(); getAccountsWiiU(); @@ -445,8 +437,9 @@ int main() { Input input{}; std::unique_ptr state = std::make_unique(wiiutitles, wiititles, wiiuTitlesCount, - vWiiTitlesCount); + vWiiTitlesCount); while (State::AppRunning()) { + input.read(); if (input.get(TRIGGER, PAD_BUTTON_ANY)) @@ -473,12 +466,13 @@ int main() { unloadTitles(wiiutitles, wiiuTitlesCount); unloadTitles(wiititles, vWiiTitlesCount); - shutdownFS(); LanguageUtils::gettextCleanUp(); romfsExit(); DrawUtils::deinitFont(); + DrawUtils::LogConsoleFree(); + State::shutdown(); return 0; } diff --git a/src/menu/WiiUTitleListState.cpp b/src/menu/WiiUTitleListState.cpp index f9d8309..d25e93f 100644 --- a/src/menu/WiiUTitleListState.cpp +++ b/src/menu/WiiUTitleListState.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #define MAX_TITLE_SHOW 14 static int cursorPos = 0; diff --git a/src/menu/vWiiTitleListState.cpp b/src/menu/vWiiTitleListState.cpp index 8aa4b8b..0f336ee 100644 --- a/src/menu/vWiiTitleListState.cpp +++ b/src/menu/vWiiTitleListState.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #define MAX_TITLE_SHOW 14 static int cursorPos = 0; diff --git a/src/savemng.cpp b/src/savemng.cpp index 84090e0..e7bafc7 100644 --- a/src/savemng.cpp +++ b/src/savemng.cpp @@ -8,8 +8,10 @@ #include #include #include +#include #include + #define __FSAShimSend ((FSError(*)(FSAShimBuffer *, uint32_t))(0x101C400 + 0x042d90)) #define IO_MAX_FILE_BUFFER (1024 * 1024) // 1 MB @@ -202,14 +204,18 @@ static bool folderEmpty(const char *fPath) { if (dir == nullptr) return false; - int c = 0; + bool empty = true; struct dirent *data; - while ((data = readdir(dir)) != nullptr) - if (++c > 2) - break; + while ((data = readdir(dir)) != nullptr) { + // rewritten to work wether ./.. are returned or not + if(strcmp(data->d_name,".") == 0 || strcmp(data->d_name,"..") == 0) + continue; + empty = false; + break; + } closedir(dir); - return c < 3; + return empty; } static bool createFolder(const char *path) { @@ -851,16 +857,23 @@ void copySavedata(Title *title, Title *titleb, int8_t allusers, int8_t allusers_ std::string srcPath = StringUtils::stringFormat("%s/%08x/%08x/%s", path.c_str(), highID, lowID, "user"); std::string dstPath = StringUtils::stringFormat("%s/%08x/%08x/%s", pathb.c_str(), highIDb, lowIDb, "user"); createFolderUnlocked(dstPath); - FSAMakeQuotaFromDir(srcPath.c_str(), dstPath.c_str(), titleb->accountSaveSize); - if (allusers > -1) - if (common) + if (allusers > -1) { + if (common) { + FSAMakeQuota(handle, newlibtoFSA(dstPath + "/common").c_str(), 0x666, titleb->accountSaveSize); if (!copyDir(srcPath + "/common", dstPath + "/common")) promptError(LanguageUtils::gettext("Common save not found.")); + } + srcPath.append(StringUtils::stringFormat("/%s", wiiuacc[allusers].persistentID)); + dstPath.append(StringUtils::stringFormat("/%s", wiiuacc[allusers_d].persistentID)); + FSAMakeQuota(handle, newlibtoFSA(dstPath).c_str(), 0x666, titleb->accountSaveSize); + } else { + FSAMakeQuotaFromDir(srcPath.c_str(), dstPath.c_str(), titleb->accountSaveSize); + } - if (!copyDir(srcPath + StringUtils::stringFormat("/%s", wiiuacc[allusers].persistentID), - dstPath + StringUtils::stringFormat("/%s", wiiuacc[allusers_d].persistentID))) + if (!copyDir(srcPath, dstPath)) promptError(LanguageUtils::gettext("Copy failed.")); + if (!titleb->saveInit) { std::string userPath = StringUtils::stringFormat("%s/%08x/%08x/user", pathb.c_str(), highIDb, lowIDb); @@ -1006,19 +1019,24 @@ void restoreSavedata(Title *title, uint8_t slot, int8_t sdusers, int8_t allusers srcPath = getBackupPath(highID, lowID, slot); std::string dstPath = StringUtils::stringFormat("%s/%08x/%08x/%s", path.c_str(), highID, lowID, isWii ? "data" : "user"); createFolderUnlocked(dstPath); - FSAMakeQuotaFromDir(srcPath.c_str(), dstPath.c_str(), title->accountSaveSize); - + if ((sdusers > -1) && !isWii) { if (common) { + FSAMakeQuota(handle, newlibtoFSA(dstPath + "/common").c_str(), 0x666, title->accountSaveSize); if (!copyDir(srcPath + "/common", dstPath + "/common")) promptError(LanguageUtils::gettext("Common save not found.")); } srcPath.append(StringUtils::stringFormat("/%s", sdacc[sdusers].persistentID)); dstPath.append(StringUtils::stringFormat("/%s", wiiuacc[allusers].persistentID)); + FSAMakeQuota(handle, newlibtoFSA(dstPath).c_str(), 0x666, title->accountSaveSize); + } else { + FSAMakeQuotaFromDir(srcPath.c_str(), dstPath.c_str(), title->accountSaveSize); } if (!copyDir(srcPath, dstPath)) promptError(LanguageUtils::gettext("Restore failed.")); + + if (!title->saveInit && !isWii) { std::string userPath = StringUtils::stringFormat("%s/%08x/%08x/user", path.c_str(), highID, lowID); diff --git a/src/utils/DrawUtils.cpp b/src/utils/DrawUtils.cpp index 1b8bdec..471de02 100644 --- a/src/utils/DrawUtils.cpp +++ b/src/utils/DrawUtils.cpp @@ -1,26 +1,101 @@ -#include -#include +#include +#include #include #include #include +#include #include -#include - +#include +#include +#include +#include +#include +#include +#include // buffer width #define TV_WIDTH 0x500 #define DRC_WIDTH 0x380 +#define CONSOLE_FRAME_HEAP_TAG (0x000DECAF) + + bool DrawUtils::isBackBuffer; uint8_t *DrawUtils::tvBuffer = nullptr; -uint32_t DrawUtils::tvSize = 0; uint8_t *DrawUtils::drcBuffer = nullptr; -uint32_t DrawUtils::drcSize = 0; +uint32_t DrawUtils::sBufferSizeTV = 0, DrawUtils::sBufferSizeDRC = 0; +BOOL DrawUtils::sConsoleHasForeground = TRUE; + static SFT pFont = {}; static Color font_col(0xFFFFFFFF); +uint32_t +DrawUtils::initScreen() +{ + MEMHeapHandle heap = MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM1); + MEMRecordStateForFrmHeap(heap, CONSOLE_FRAME_HEAP_TAG); + + if (sBufferSizeTV) { + DrawUtils::tvBuffer = static_cast(MEMAllocFromFrmHeapEx(heap, sBufferSizeTV, 4)); + } + + if (sBufferSizeDRC) { + DrawUtils::drcBuffer = static_cast(MEMAllocFromFrmHeapEx(heap, sBufferSizeDRC, 4)); + } + + + sConsoleHasForeground = TRUE; + + OSScreenSetBufferEx(SCREEN_TV, DrawUtils::tvBuffer); + OSScreenSetBufferEx(SCREEN_DRC, DrawUtils::drcBuffer); + + DrawUtils::endDraw(); // flip buffers + + DrawUtils::setRedraw(true); // force a redraw when reentering + + return 0; + +} + +uint32_t +DrawUtils::deinitScreen() +{ + + MEMHeapHandle heap = MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM1); + MEMFreeByStateToFrmHeap(heap, CONSOLE_FRAME_HEAP_TAG); + sConsoleHasForeground = FALSE; + return 0; + +} + + +BOOL +DrawUtils::LogConsoleInit() +{ + OSScreenInit(); + sBufferSizeTV = OSScreenGetBufferSizeEx(SCREEN_TV); + sBufferSizeDRC = OSScreenGetBufferSizeEx(SCREEN_DRC); + + initScreen(); + + OSScreenEnableEx(SCREEN_TV, 1); + OSScreenEnableEx(SCREEN_DRC, 1); + + return FALSE; +} + +void +DrawUtils::LogConsoleFree() +{ + if (sConsoleHasForeground) { + deinitScreen(); + OSScreenShutdown(); + } +} + + bool DrawUtils::redraw = true; template @@ -32,13 +107,6 @@ void DrawUtils::setRedraw(bool value) { redraw = value; } -void DrawUtils::initBuffers(void *tvBuffer_, uint32_t tvSize_, void *drcBuffer_, uint32_t drcSize_) { - DrawUtils::tvBuffer = (uint8_t *) tvBuffer_; - DrawUtils::tvSize = tvSize_; - DrawUtils::drcBuffer = (uint8_t *) drcBuffer_; - DrawUtils::drcSize = drcSize_; -} - void DrawUtils::beginDraw() { uint32_t pixel = *(uint32_t *) tvBuffer; @@ -55,10 +123,6 @@ void DrawUtils::beginDraw() { } void DrawUtils::endDraw() { - // OSScreenFlipBuffersEx already flushes the cache? - // DCFlushRange(tvBuffer, tvSize); - // DCFlushRange(drcBuffer, drcSize); - OSScreenFlipBuffersEx(SCREEN_DRC); OSScreenFlipBuffersEx(SCREEN_TV); } @@ -73,9 +137,9 @@ void DrawUtils::drawPixel(uint32_t x, uint32_t y, uint8_t r, uint8_t g, uint8_t // put pixel in the drc buffer uint32_t i = (x + y * DRC_WIDTH) * 4; - if (i + 3 < drcSize / 2) { + if (i + 3 < sBufferSizeDRC / 2) { if (isBackBuffer) { - i += drcSize / 2; + i += sBufferSizeDRC / 2; } if (a == 0xFF) { drcBuffer[i] = r; @@ -90,7 +154,7 @@ void DrawUtils::drawPixel(uint32_t x, uint32_t y, uint8_t r, uint8_t g, uint8_t uint32_t USED_TV_WIDTH = TV_WIDTH; float scale = 1.5f; - if (DrawUtils::tvSize == 0x00FD2000) { + if (DrawUtils::sBufferSizeTV == 0x00FD2000) { USED_TV_WIDTH = 1920; scale = 2.25f; } @@ -99,9 +163,9 @@ void DrawUtils::drawPixel(uint32_t x, uint32_t y, uint8_t r, uint8_t g, uint8_t for (uint32_t yy = (y * scale); yy < ((y * scale) + (uint32_t) scale); yy++) { for (uint32_t xx = (x * scale); xx < ((x * scale) + (uint32_t) scale); xx++) { uint32_t i = (xx + yy * USED_TV_WIDTH) * 4; - if (i + 3 < tvSize / 2) { + if (i + 3 < sBufferSizeTV / 2) { if (isBackBuffer) { - i += tvSize / 2; + i += sBufferSizeTV / 2; } if (a == 0xFF) { tvBuffer[i] = r; diff --git a/src/utils/StateUtils.cpp b/src/utils/StateUtils.cpp index 9cf4796..da6b270 100644 --- a/src/utils/StateUtils.cpp +++ b/src/utils/StateUtils.cpp @@ -1,10 +1,14 @@ +#include +#include #include #include #include #include -#include #include +#include + + bool State::aroma = false; void State::init() { @@ -18,6 +22,26 @@ void State::init() { WHBProcInit(); } + +uint32_t +State::ConsoleProcCallbackAcquired(void *context) +{ + return DrawUtils::initScreen(); +} + +uint32_t +State::ConsoleProcCallbackReleased(void *context) +{ + return DrawUtils::deinitScreen(); +} + +void State::registerProcUICallbacks() { + if (aroma) { + ProcUIRegisterCallback(PROCUI_CALLBACK_ACQUIRE, ConsoleProcCallbackAcquired, NULL, 100); + ProcUIRegisterCallback(PROCUI_CALLBACK_RELEASE, ConsoleProcCallbackReleased, NULL, 100); + } +} + bool State::AppRunning() { if (aroma) { bool app = true; @@ -50,4 +74,6 @@ void State::shutdown() { if (!aroma) WHBProcShutdown(); ProcUIShutdown(); -} \ No newline at end of file +} + +