From 7d8fb7eb5d03c5d25db9d063d12d8d9e17e8655b Mon Sep 17 00:00:00 2001 From: StackZ <47382115+SuperSaiyajinStackZ@users.noreply.github.com> Date: Tue, 28 Apr 2020 14:35:42 +0200 Subject: [PATCH] Display Percentage on Installing & Extracting. Also add progressbar for Installing & convert `cia.c` to `cia.cpp` for `new`. --- include/animation.hpp | 2 + include/utils/{cia.h => cia.hpp} | 21 ++- source/animation.cpp | 8 + source/download/download.cpp | 93 +++++++---- source/utils/{cia.c => cia.cpp} | 279 ++++++++++++++++--------------- source/utils/extract.cpp | 3 +- source/utils/scriptHelper.cpp | 13 +- 7 files changed, 231 insertions(+), 188 deletions(-) rename include/utils/{cia.h => cia.hpp} (66%) rename source/utils/{cia.c => cia.cpp} (82%) diff --git a/include/animation.hpp b/include/animation.hpp index 58c72aa..01d266d 100644 --- a/include/animation.hpp +++ b/include/animation.hpp @@ -35,6 +35,8 @@ namespace Animation { void DrawProgressBar(float currentProgress, float totalProgress, int mode); // Extracting progressbar. void DrawProgressBarExtract(u64 currentProgress, u64 totalProgress, int mode); + // Installing progressbar. + void DrawProgressBarInstall(u64 currentProgress, u64 totalProgress, int mode); // Draw Button. void Button(int x, int y, float speed = .030); } diff --git a/include/utils/cia.h b/include/utils/cia.hpp similarity index 66% rename from include/utils/cia.h rename to include/utils/cia.hpp index 0ff14a4..8235fb3 100644 --- a/include/utils/cia.h +++ b/include/utils/cia.hpp @@ -1,9 +1,12 @@ -#pragma once - -#include "common.hpp" - -#include <3ds.h> - -Result CIA_LaunchTitle(u64 titleId, FS_MediaType mediaType); -Result deletePrevious(u64 titleid, FS_MediaType media); -Result installCia(const char * ciaPath); \ No newline at end of file +#ifndef CIA_HPP +#define CIA_HPP + +#include "common.hpp" + +#include <3ds.h> + +Result CIA_LaunchTitle(u64 titleId, FS_MediaType mediaType); +Result deletePrevious(u64 titleid, FS_MediaType media); +Result installCia(const char * ciaPath); + +#endif \ No newline at end of file diff --git a/source/animation.cpp b/source/animation.cpp index c7e44b2..958d005 100644 --- a/source/animation.cpp +++ b/source/animation.cpp @@ -41,6 +41,14 @@ void Animation::DrawProgressBar(float currentProgress, float totalProgress, int } } +void Animation::DrawProgressBarInstall(u64 currentProgress, u64 totalProgress, int mode) { + if (mode == 1) { + Gui::Draw_Rect(31, 121, (int)(((float)currentProgress / (float)totalProgress) * 338.0f), 28, progressBar); + } else { + Gui::Draw_Rect(31, 121, (int)(((float)currentProgress / (float)totalProgress) * 338.0f), 28, Config::progressbarColor); + } +} + void Animation::DrawProgressBarExtract(u64 currentProgress, u64 totalProgress, int mode) { if (mode == 1) { Gui::Draw_Rect(31, 141, (int)(((float)currentProgress / (float)totalProgress) * 338.0f), 28, progressBar); diff --git a/source/download/download.cpp b/source/download/download.cpp index 0bea7e0..68979f8 100644 --- a/source/download/download.cpp +++ b/source/download/download.cpp @@ -50,11 +50,12 @@ extern std::string extractingFile; char progressBarMsg[128] = ""; bool showProgressBar = false; -bool progressBarType = 0; // 0 = Download | 1 = Extract +int progressBarType = 0; // 0 = Download | 1 = Extract | 2 = Install // That are our extract Progressbar variables. -extern u64 extractSize; -extern u64 writeOffset; +extern u64 extractSize, writeOffset; +// That are our install Progressbar variables. +extern u64 installSize, installOffset; #define TIME_IN_US 1 #define TIMETYPE curl_off_t @@ -856,52 +857,38 @@ void displayProgressBar() { downloadTotal = downloadNow; } - if (progressBarType) { - snprintf(str, sizeof(str), "%i %s", - filesExtracted, - (filesExtracted == 1 ? (Lang::get("FILE_EXTRACTED")).c_str() :(Lang::get("FILES_EXTRACTED")).c_str()) - ); - } else { + // Downloading. + if (progressBarType == 0){ snprintf(str, sizeof(str), "%s / %s (%.2f%%)", formatBytes(downloadNow).c_str(), formatBytes(downloadTotal).c_str(), - ((float)downloadNow/(float)downloadTotal) * 100.0f - ); - } + ((float)downloadNow/(float)downloadTotal) * 100.0f); + // Extracting. + } else if (progressBarType == 1) { + snprintf(str, sizeof(str), "%s / %s (%.2f%%)", + formatBytes(writeOffset).c_str(), + formatBytes(extractSize).c_str(), + ((float)writeOffset/(float)extractSize) * 100.0f); + // Installing. + } else if (progressBarType == 2){ + snprintf(str, sizeof(str), "%s / %s (%.2f%%)", + formatBytes(installOffset).c_str(), + formatBytes(installSize).c_str(), + ((float)installOffset/(float)installSize) * 100.0f); + }; Gui::clearTextBufs(); C3D_FrameBegin(C3D_FRAME_SYNCDRAW); C2D_TargetClear(Top, BLACK); C2D_TargetClear(Bottom, BLACK); GFX::DrawTop(); + // Display this by all. if (isScriptSelected == true) { Gui::DrawStringCentered(0, 1, 0.7f, TextColor, progressBarMsg, 400); } else { Gui::DrawStringCentered(0, 1, 0.7f, Config::TxtColor, progressBarMsg, 400); } - // Display 'Currently Extracting: '. - if (progressBarType == 1) { - // Text. - if (isScriptSelected == true) { - Gui::DrawStringCentered(0, 100, 0.6f, TextColor, str, 400); - Gui::DrawStringCentered(0, 180, 0.6f, TextColor, formatBytes(writeOffset) + " / " + formatBytes(extractSize), 400); - Gui::DrawStringCentered(0, 40, 0.6f, TextColor, Lang::get("CURRENTLY_EXTRACTING") + "\n" + extractingFile, 400); - } else { - Gui::DrawStringCentered(0, 100, 0.6f, Config::TxtColor, str, 400); - Gui::DrawStringCentered(0, 180, 0.6f, Config::TxtColor, formatBytes(writeOffset) + " / " + formatBytes(extractSize), 400); - Gui::DrawStringCentered(0, 40, 0.6f, Config::TxtColor, Lang::get("CURRENTLY_EXTRACTING") + "\n" + extractingFile, 400); - } - // Outline of progressbar. - Gui::Draw_Rect(30, 140, 340, 30, BLACK); - // Progressbar. - if (isScriptSelected == true) { - Animation::DrawProgressBarExtract(writeOffset, extractSize, 1); - } else { - Animation::DrawProgressBarExtract(writeOffset, extractSize, 2); - } - } - // Only display this by downloading. if (progressBarType == 0) { if (isScriptSelected == true) { @@ -917,6 +904,44 @@ void displayProgressBar() { Animation::DrawProgressBar(downloadNow, downloadTotal, 2); } } + + // Only Display this by extracting. + if (progressBarType == 1) { + // Text. + if (isScriptSelected == true) { + Gui::DrawStringCentered(0, 180, 0.6f, TextColor, str, 400); + Gui::DrawStringCentered(0, 100, 0.6f, TextColor, std::to_string(filesExtracted) + " " + (filesExtracted == 1 ? (Lang::get("FILE_EXTRACTED")).c_str() :(Lang::get("FILES_EXTRACTED"))), 400); + Gui::DrawStringCentered(0, 40, 0.6f, TextColor, Lang::get("CURRENTLY_EXTRACTING") + "\n" + extractingFile, 400); + } else { + Gui::DrawStringCentered(0, 180, 0.6f, Config::TxtColor, str, 400); + Gui::DrawStringCentered(0, 100, 0.6f, Config::TxtColor, std::to_string(filesExtracted) + " " + (filesExtracted == 1 ? (Lang::get("FILE_EXTRACTED")).c_str() :(Lang::get("FILES_EXTRACTED"))), 400); + Gui::DrawStringCentered(0, 40, 0.6f, Config::TxtColor, Lang::get("CURRENTLY_EXTRACTING") + "\n" + extractingFile, 400); + } + // Outline of progressbar. + Gui::Draw_Rect(30, 140, 340, 30, BLACK); + // Progressbar. + if (isScriptSelected == true) { + Animation::DrawProgressBarExtract(writeOffset, extractSize, 1); + } else { + Animation::DrawProgressBarExtract(writeOffset, extractSize, 2); + } + } + + // Only display this by installing. + if (progressBarType == 2) { + if (isScriptSelected == true) { + Gui::DrawStringCentered(0, 80, 0.6f, TextColor, str, 400); + } else { + Gui::DrawStringCentered(0, 80, 0.6f, Config::TxtColor, str, 400); + } + // Outline of progressbar. + Gui::Draw_Rect(30, 120, 340, 30, BLACK); + if (isScriptSelected == true) { + Animation::DrawProgressBarInstall(installOffset, installSize, 1); + } else { + Animation::DrawProgressBarInstall(installOffset, installSize, 2); + } + } GFX::DrawBottom(); C3D_FrameEnd(0); gspWaitForVBlank(); diff --git a/source/utils/cia.c b/source/utils/cia.cpp similarity index 82% rename from source/utils/cia.c rename to source/utils/cia.cpp index 9db7d9d..3be6499 100644 --- a/source/utils/cia.c +++ b/source/utils/cia.cpp @@ -1,138 +1,143 @@ -#include "cia.h" - -bool updatingSelf = false; - -Result CIA_LaunchTitle(u64 titleId, FS_MediaType mediaType) { - Result ret = 0; - u8 param[0x300]; - u8 hmac[0x20]; - - if (R_FAILED(ret = APT_PrepareToDoApplicationJump(0, titleId, mediaType))) { - printf("Error In:\nAPT_PrepareToDoApplicationJump"); - return ret; - } - if (R_FAILED(ret = APT_DoApplicationJump(param, sizeof(param), hmac))) { - printf("Error In:\nAPT_DoApplicationJump"); - return ret; - } - - return 0; -} - -Result deletePrevious(u64 titleid, FS_MediaType media) -{ - Result ret = 0; - - u32 titles_amount = 0; - ret = AM_GetTitleCount(media, &titles_amount); - if (R_FAILED(ret)) { - printf("Error in:\nAM_GetTitleCount\n"); - return ret; - } - - u32 read_titles = 0; - u64 * titleIDs = malloc(titles_amount * sizeof(u64)); - ret = AM_GetTitleList(&read_titles, media, titles_amount, titleIDs); - if (R_FAILED(ret)) { - free(titleIDs); - printf("Error in:\nAM_GetTitleList\n"); - return ret; - } - - for (u32 i = 0; i < read_titles; i++) { - if (titleIDs[i] == titleid) { - ret = AM_DeleteAppTitle(media, titleid); - break; - } - } - - free(titleIDs); - if (R_FAILED(ret)) { - printf("Error in:\nAM_DeleteAppTitle\n"); - return ret; - } - - return 0; -} - -FS_MediaType getTitleDestination(u64 titleId) { - u16 platform = (u16) ((titleId >> 48) & 0xFFFF); - u16 category = (u16) ((titleId >> 32) & 0xFFFF); - u8 variation = (u8) (titleId & 0xFF); - - // DSiWare 3DS DSiWare, System, DLP Application System Title - return platform == 0x0003 || (platform == 0x0004 && ((category & 0x8011) != 0 || (category == 0x0000 && variation == 0x02))) ? MEDIATYPE_NAND : MEDIATYPE_SD; -} - - -Result installCia(const char * ciaPath) -{ - u64 size = 0; - u32 bytes; - Handle ciaHandle; - Handle fileHandle; - AM_TitleEntry info; - Result ret = 0; - - FS_MediaType media = MEDIATYPE_SD; - - ret = openFile(&fileHandle, ciaPath, false); - if (R_FAILED(ret)) { - printf("Error in:\nopenFile\n"); - return ret; - } - - ret = AM_GetCiaFileInfo(media, &info, fileHandle); - if (R_FAILED(ret)) { - printf("Error in:\nAM_GetCiaFileInfo\n"); - return ret; - } - - media = getTitleDestination(info.titleID); - if (info.titleID == 0x0004000004391700) { - updatingSelf = true; - } - - if (!updatingSelf) { - ret = deletePrevious(info.titleID, media); - if (R_FAILED(ret)) - return ret; - } - - ret = FSFILE_GetSize(fileHandle, &size); - if (R_FAILED(ret)) { - printf("Error in:\nFSFILE_GetSize\n"); - return ret; - } - ret = AM_StartCiaInstall(media, &ciaHandle); - if (R_FAILED(ret)) { - printf("Error in:\nAM_StartCiaInstall\n"); - return ret; - } - - u32 toRead = 0x20000; - u8 * cia_buffer = memalign(0x1000, toRead); - for (u64 startSize = size; size != 0; size -= toRead) { - if (size < toRead) toRead = size; - FSFILE_Read(fileHandle, &bytes, startSize-size, cia_buffer, toRead); - FSFILE_Write(ciaHandle, &bytes, startSize-size, cia_buffer, toRead, 0); - } - free(cia_buffer); - - ret = AM_FinishCiaInstall(ciaHandle); - if (R_FAILED(ret)) { - printf("Error in:\nAM_FinishCiaInstall\n"); - return ret; - } - ret = FSFILE_Close(fileHandle); - if (R_FAILED(ret)) { - printf("Error in:\nFSFILE_Close\n"); - return ret; - } - - if (updatingSelf) { - if (R_FAILED(ret = CIA_LaunchTitle(info.titleID, MEDIATYPE_SD))) - return ret; - } - return 0; +#include "cia.hpp" + +bool updatingSelf = false; + +Result CIA_LaunchTitle(u64 titleId, FS_MediaType mediaType) { + Result ret = 0; + u8 param[0x300]; + u8 hmac[0x20]; + + if (R_FAILED(ret = APT_PrepareToDoApplicationJump(0, titleId, mediaType))) { + printf("Error In:\nAPT_PrepareToDoApplicationJump"); + return ret; + } + if (R_FAILED(ret = APT_DoApplicationJump(param, sizeof(param), hmac))) { + printf("Error In:\nAPT_DoApplicationJump"); + return ret; + } + + return 0; +} + +Result deletePrevious(u64 titleid, FS_MediaType media) +{ + Result ret = 0; + + u32 titles_amount = 0; + ret = AM_GetTitleCount(media, &titles_amount); + if (R_FAILED(ret)) { + printf("Error in:\nAM_GetTitleCount\n"); + return ret; + } + + u32 read_titles = 0; + u64 * titleIDs = (u64*)malloc(titles_amount * sizeof(u64)); + ret = AM_GetTitleList(&read_titles, media, titles_amount, titleIDs); + if (R_FAILED(ret)) { + free(titleIDs); + printf("Error in:\nAM_GetTitleList\n"); + return ret; + } + + for (u32 i = 0; i < read_titles; i++) { + if (titleIDs[i] == titleid) { + ret = AM_DeleteAppTitle(media, titleid); + break; + } + } + + free(titleIDs); + if (R_FAILED(ret)) { + printf("Error in:\nAM_DeleteAppTitle\n"); + return ret; + } + + return 0; +} + +FS_MediaType getTitleDestination(u64 titleId) { + u16 platform = (u16) ((titleId >> 48) & 0xFFFF); + u16 category = (u16) ((titleId >> 32) & 0xFFFF); + u8 variation = (u8) (titleId & 0xFF); + + // DSiWare 3DS DSiWare, System, DLP Application System Title + return platform == 0x0003 || (platform == 0x0004 && ((category & 0x8011) != 0 || (category == 0x0000 && variation == 0x02))) ? MEDIATYPE_NAND : MEDIATYPE_SD; +} + +// Variables. +u64 installSize = 0, installOffset = 0; + +Result installCia(const char * ciaPath) +{ + u32 bytes_read = 0, bytes_written; + installSize = 0, installOffset = 0; u64 size = 0; + Handle ciaHandle, fileHandle; + AM_TitleEntry info; + Result ret = 0; + FS_MediaType media = MEDIATYPE_SD; + + ret = openFile(&fileHandle, ciaPath, false); + if (R_FAILED(ret)) { + printf("Error in:\nopenFile\n"); + return ret; + } + + ret = AM_GetCiaFileInfo(media, &info, fileHandle); + if (R_FAILED(ret)) { + printf("Error in:\nAM_GetCiaFileInfo\n"); + return ret; + } + + media = getTitleDestination(info.titleID); + if (info.titleID == 0x0004000004391700) { + updatingSelf = true; + } + + if (!updatingSelf) { + ret = deletePrevious(info.titleID, media); + if (R_FAILED(ret)) + return ret; + } + + ret = FSFILE_GetSize(fileHandle, &size); + if (R_FAILED(ret)) { + printf("Error in:\nFSFILE_GetSize\n"); + return ret; + } + ret = AM_StartCiaInstall(media, &ciaHandle); + if (R_FAILED(ret)) { + printf("Error in:\nAM_StartCiaInstall\n"); + return ret; + } + + u32 toRead = 0x200000; + u8 *buf = new u8[toRead]; + if(buf == nullptr) { + return -1; + } + + installSize = size; + do { + FSFILE_Read(fileHandle, &bytes_read, installOffset, buf, toRead); + FSFILE_Write(ciaHandle, &bytes_written, installOffset, buf, toRead, FS_WRITE_FLUSH); + installOffset += bytes_read; + } while(installOffset < installSize); + delete[] buf; + + ret = AM_FinishCiaInstall(ciaHandle); + if (R_FAILED(ret)) { + printf("Error in:\nAM_FinishCiaInstall\n"); + return ret; + } + ret = FSFILE_Close(fileHandle); + if (R_FAILED(ret)) { + printf("Error in:\nFSFILE_Close\n"); + return ret; + } + + if (updatingSelf) { + if (R_FAILED(ret = CIA_LaunchTitle(info.titleID, MEDIATYPE_SD))) + return ret; + } + return 0; } \ No newline at end of file diff --git a/source/utils/extract.cpp b/source/utils/extract.cpp index 4936f5b..81ea569 100644 --- a/source/utils/extract.cpp +++ b/source/utils/extract.cpp @@ -35,8 +35,7 @@ int filesExtracted = 0; std::string extractingFile = ""; // That are our File Progressbar variable. -u64 extractSize = 0; -u64 writeOffset = 0; +u64 extractSize = 0, writeOffset = 0; Result extractArchive(std::string archivePath, std::string wantedFile, std::string outputPath) { extractSize = 0, writeOffset = 0, filesExtracted = 0; diff --git a/source/utils/scriptHelper.cpp b/source/utils/scriptHelper.cpp index c780e00..ac27758 100644 --- a/source/utils/scriptHelper.cpp +++ b/source/utils/scriptHelper.cpp @@ -24,6 +24,7 @@ * reasonable ways as different from the original version. */ +#include "cia.hpp" #include "download.hpp" #include "extract.hpp" #include "fileBrowse.hpp" @@ -35,12 +36,8 @@ #include #include -extern "C" { - #include "cia.h" -} - extern bool showProgressBar; -extern bool progressBarType; +extern int progressBarType; extern char progressBarMsg[128]; extern int filesExtracted; @@ -110,8 +107,12 @@ Result ScriptHelper::removeFile(std::string file, std::string message) { // Install a file. void ScriptHelper::installFile(std::string file, std::string message) { - Msg::DisplayMsg(message); + snprintf(progressBarMsg, sizeof(progressBarMsg), message.c_str()); + showProgressBar = true; + progressBarType = 2; + Threads::create((ThreadFunc)displayProgressBar); installCia(file.c_str()); + showProgressBar = false; } // Extract Files.