diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..11d863d --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "Universal-Core"] + path = Universal-Core + url = https://github.com/Universal-Team/Universal-Core.git diff --git a/Makefile b/Makefile index fe718e0..05305d8 100644 --- a/Makefile +++ b/Makefile @@ -71,9 +71,10 @@ endif #--------------------------------------------------------------------------------- TARGET := TWiLight_Menu++_Updater BUILD := build -SOURCES := source source/utils source/utils/json +UNIVCORE := Universal-Core +SOURCES := $(UNIVCORE) source source/screens source/utils DATA := data -INCLUDES := include include/utils source source/utils +INCLUDES := $(UNIVCORE) include include/screens include/utils GRAPHICS := assets/gfx #GFXBUILD := $(BUILD) ROMFS := romfs @@ -97,7 +98,7 @@ CFLAGS := -g -Wall -O2 -mword-relocations \ CFLAGS += $(INCLUDE) -DARM11 -D_3DS -CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -fpermissive -std=c++11 -std=gnu++11 +CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -fpermissive -std=gnu++17 ASFLAGS := -g $(ARCH) LDFLAGS = -specs=3dsx.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) diff --git a/Universal-Core b/Universal-Core new file mode 160000 index 0000000..c82ad8d --- /dev/null +++ b/Universal-Core @@ -0,0 +1 @@ +Subproject commit c82ad8d6e11e4842c6099b53595aa3692f24910b diff --git a/azure-pipelines.yml b/azure-pipelines.yml index c56c73e..f042939 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -21,9 +21,7 @@ steps: sudo apt install p7zip-full haveged sudo dpkg -i pacman.deb sudo dkp-pacman -Sy - sudo dkp-pacman -S 3ds-dev --noconfirm - sudo dkp-pacman -S 3ds-curl 3ds-libarchive 3ds-liblzma 3ds-mbedtls 3ds-bzip2 3ds-zlib --noconfirm - sudo 7z x libctru.7z -o/opt/devkitpro/ -y + sudo dkp-pacman -S 3ds-dev 3ds-curl 3ds-libarchive 3ds-liblzma 3ds-mbedtls 3ds-bzip2 3ds-zlib --noconfirm curl -L https://github.com/Steveice10/bannertool/releases/download/1.1.0/bannertool.zip -o bannertool.zip sudo 7z e bannertool.zip linux-x86_64/bannertool sudo chmod +x bannertool @@ -32,6 +30,7 @@ steps: sudo 7z e makerom_015_ctrtool.zip Linux_x86_64/makerom sudo chmod +x makerom rm makerom_015_ctrtool.zip + git submodule update --init --recursive displayName: 'Setup devkitPro' - script: | diff --git a/include/fileBrowse.h b/include/fileBrowse.hpp similarity index 82% rename from include/fileBrowse.h rename to include/fileBrowse.hpp index 94eb1d3..a2f3242 100644 --- a/include/fileBrowse.h +++ b/include/fileBrowse.hpp @@ -1,7 +1,6 @@ -#ifndef FILE_BROWSE_H -#define FILE_BROWSE_H +#ifndef FILE_BROWSE_HPP +#define FILE_BROWSE_HPP -#include "download.hpp" #include #include #include @@ -24,4 +23,4 @@ void findNdsFiles(vector& dirContents); void getDirectoryContents (vector& dirContents); -#endif //FILE_BROWSE_H +#endif //FILE_BROWSE_HPP diff --git a/include/gfx.hpp b/include/gfx.hpp new file mode 100644 index 0000000..97a0841 --- /dev/null +++ b/include/gfx.hpp @@ -0,0 +1,28 @@ +#ifndef GFX_HPP +#define GFX_HPP + +#include "sprites.h" + +#include <3ds.h> +#include + +// Colors. +#define TRANSPARENT C2D_Color32(0, 0, 0, 0) +#define BLACK C2D_Color32(0, 0, 0, 255) +#define WHITE C2D_Color32(255, 255, 255, 255) +#define GRAY C2D_Color32(127, 127, 127, 255) +#define BLUE C2D_Color32(0, 0, 255, 255) +#define GREEN C2D_Color32(0, 255, 0, 255) +#define RED C2D_Color32(255, 0, 0, 255) +#define TIME C2D_Color32(16, 0, 0, 223) + +typedef u32 Color; + +namespace GFX +{ + void DrawTop(); + void DrawSprite(int img, int x, int y, float ScaleX = 1, float ScaleY = 1); + void DrawSpriteBlend(int img, int x, int y, u32 color, float ScaleX = 1, float ScaleY = 1); +} + +#endif \ No newline at end of file diff --git a/include/gui.hpp b/include/gui.hpp deleted file mode 100644 index 046f649..0000000 --- a/include/gui.hpp +++ /dev/null @@ -1,82 +0,0 @@ -/* -* This file is part of Universal-Manager -* Copyright (C) 2019 VoltZ, Epicpkmn11, Flame, RocketRobz, TotallyNotGuy -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Additional Terms 7.b and 7.c of GPLv3 apply to this file: -* * Requiring preservation of specified reasonable legal notices or -* author attributions in that material or in the Appropriate Legal -* Notices displayed by works containing it. -* * Prohibiting misrepresentation of the origin of that material, -* or requiring that modified versions of such material be marked in -* reasonable ways as different from the original version. -*/ - -#ifndef GUI_HPP -#define GUI_HPP - -#include <3ds.h> -#include -#include -#include -#include -#include -#include -#include -#include "common.hpp" - -// Spritesheets. -#include "sprites.h" - -#include "colors.hpp" - -// emulated -#define sprites_res_null_idx 500 - -#define FONT_SIZE_18 0.72f -#define FONT_SIZE_17 0.7f -#define FONT_SIZE_15 0.6f -#define FONT_SIZE_14 0.56f -#define FONT_SIZE_12 0.50f -#define FONT_SIZE_11 0.46f -#define FONT_SIZE_9 0.37f - -namespace Gui { - Result init(void); - void exit(void); - - C3D_RenderTarget* target(gfxScreen_t t); - - void clearTextBufs(void); - - void sprite(int key, int x, int y); - - void Draw_ImageBlend(int key, int x, int y, u32 color); -} - - void displayMsg(const char* text); - void displayBottomMsg(const char* text); - - void set_screen(C3D_RenderTarget * screen); - - void Draw_EndFrame(void); - void Draw_Text(float x, float y, float size, u32 color, const char *text); - void Draw_Textf(float x, float y, float size, u32 color, const char* text, ...); - void Draw_GetTextSize(float size, float *width, float *height, const char *text); - float Draw_GetTextWidth(float size, const char *text); - float Draw_GetTextHeight(float size, const char *text); - bool Draw_Rect(float x, float y, float w, float h, u32 color); - -#endif diff --git a/include/init.hpp b/include/init.hpp new file mode 100644 index 0000000..1654913 --- /dev/null +++ b/include/init.hpp @@ -0,0 +1,13 @@ +#ifndef INIT_HPP +#define INIT_HPP + +#include <3ds.h> + +namespace Init { + // Init, Mainloop & Exit. + Result Initialize(); + Result MainLoop(); + Result Exit(); +} + +#endif \ No newline at end of file diff --git a/include/msg.hpp b/include/msg.hpp new file mode 100644 index 0000000..7dac55d --- /dev/null +++ b/include/msg.hpp @@ -0,0 +1,12 @@ +#ifndef MSG_HPP +#define MSG_HPP + +#include + +namespace Msg +{ + void DisplayMsg(std::string text); + bool promptMsg(std::string promptMsg); +} + +#endif \ No newline at end of file diff --git a/include/screens/updaterScreen.hpp b/include/screens/updaterScreen.hpp new file mode 100644 index 0000000..dd84d53 --- /dev/null +++ b/include/screens/updaterScreen.hpp @@ -0,0 +1,23 @@ +#ifndef UPDATERSCREEN_HPP +#define UPDATERSCREEN_HPP + +#include "common.hpp" +#include "structs.hpp" + +#include + +class UpdaterScreen : public Screen +{ +public: + void Draw(void) const override; + void Logic(u32 hDown, u32 hHeld, touchPosition touch) override; + UpdaterScreen(); + +private: + bool buttonShading = false; + bool setOption = false; + bool showMessage = false; + int menuSelection = 0; +}; + +#endif \ No newline at end of file diff --git a/include/utils/colors.hpp b/include/utils/colors.hpp deleted file mode 100644 index 09e0b13..0000000 --- a/include/utils/colors.hpp +++ /dev/null @@ -1,78 +0,0 @@ -/* -* This file is part of Universal-Manager -* Copyright (C) 2019 VoltZ, Epicpkmn11, Flame, RocketRobz, TotallyNotGuy -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Additional Terms 7.b and 7.c of GPLv3 apply to this file: -* * Requiring preservation of specified reasonable legal notices or -* author attributions in that material or in the Appropriate Legal -* Notices displayed by works containing it. -* * Prohibiting misrepresentation of the origin of that material, -* or requiring that modified versions of such material be marked in -* reasonable ways as different from the original version. -*/ - -#ifndef COLORS_HPP -#define COLORS_HPP - -#include -#include - -/** - * @brief Creates a 8 byte RGBA color - * @param r red component of the color - * @param g green component of the color - * @param b blue component of the color - * @param a alpha component of the color - */ -#define RGBA8(r, g, b, a) ((((r)&0xFF)<<0) | (((g)&0xFF)<<8) | (((b)&0xFF)<<16) | (((a)&0xFF)<<24)) - -/** - * @brief Creates a 8 byte ABGR color - * @param a alpha component of the color - * @param b blue component of the color - * @param g green component of the color - * @param r red component of the color - */ -#define ABGR8(a, b, g, r) ((((a)&0xFF)<<0) | (((b)&0xFF)<<8) | (((g)&0xFF)<<16) | (((r)&0xFF)<<24)) - -/** - * @brief Converts a RGB565 color to RGBA8 color (adds maximum alpha) - * @param rgb 565 to be converted - * @param a alpha - */ -#define RGB565_TO_RGBA8(rgb, a) \ - (RGBA8(((rgb>>11)&0x1F)*0xFF/0x1F, ((rgb>>5)&0x3F)*0xFF/0x3F, (rgb&0x1F)*0xFF/0x1F, a&0xFF)) - -/** - * @brief Converts a RGB565 color to ABGR8 color (adds maximum alpha) - * @param rgb 565 to be converted - * @param a alpha - */ -#define RGB565_TO_ABGR8(rgb, a) \ - (RGBA8(a&0xFF, (rgb&0x1F)*0xFF/0x1F, ((rgb>>5)&0x3F)*0xFF/0x3F, ((rgb>>11)&0x1F)*0xFF/0x1F)) - -#define TRANSPARENT C2D_Color32(0, 0, 0, 0) -#define BLACK C2D_Color32(0, 0, 0, 255) -#define WHITE C2D_Color32(255, 255, 255, 255) -#define GRAY RGBA8(127, 127, 127, 255) -#define BLUE RGBA8(0, 0, 255, 255) -#define GREEN RGBA8(0, 255, 0, 255) -#define RED RGBA8(255, 0, 0, 255) - -#define TIME RGBA8(16, 0, 0, 223) - -typedef u32 Color; -#endif diff --git a/include/utils/common.hpp b/include/utils/common.hpp index 23a3760..1f5c9bd 100755 --- a/include/utils/common.hpp +++ b/include/utils/common.hpp @@ -23,8 +23,12 @@ extern "C" { #include #include -#include "stringutils.hpp" +#include "gfx.hpp" +#include "gui.hpp" #include "json.hpp" +#include "msg.hpp" +#include "screenCommon.hpp" +#include "stringutils.hpp" using json = nlohmann::json; @@ -32,12 +36,4 @@ using json = nlohmann::json; extern char * arg0; -#define WORKING_DIR "/3ds/" - -#define HBL_FILE_NAME APP_TITLE ".3dsx" -#define HBL_FILE_PATH WORKING_DIR "/" HBL_FILE_NAME - -#define CONFIG_FILE_NAME "config.json" -#define CONFIG_FILE_PATH WORKING_DIR "/" CONFIG_FILE_NAME - -#define CONFIG_FILE_URL "https://raw.githubusercontent.com/LiquidFenrir/MultiUpdater/rewrite/config.json" +#define WORKING_DIR "/3ds/" \ No newline at end of file diff --git a/libctru.7z b/libctru.7z deleted file mode 100644 index 4a79d68..0000000 Binary files a/libctru.7z and /dev/null differ diff --git a/source/download.cpp b/source/download.cpp index adc8615..ab18a58 100755 --- a/source/download.cpp +++ b/source/download.cpp @@ -1,16 +1,16 @@ #include "download.hpp" -#include -#include -#include -#include - #include "extract.hpp" -#include "fileBrowse.h" +#include "fileBrowse.hpp" #include "gui.hpp" #include "inifile.h" #include "keyboard.h" #include "thread.h" +#include +#include +#include +#include + extern "C" { #include "cia.h" } @@ -31,8 +31,8 @@ std::string latestUpdaterReleaseCache = ""; std::string latestUpdaterNightlyCache = ""; std::string usernamePasswordCache = ""; -extern C3D_RenderTarget* top; -extern C3D_RenderTarget* bottom; +extern C3D_RenderTarget* Top; +extern C3D_RenderTarget* Bottom; extern bool downloadNightlies; extern bool updateAvailable[]; @@ -267,21 +267,21 @@ bool checkWifiStatus(void) { } void downloadFailed(void) { - displayBottomMsg("Download failed!"); + Msg::DisplayMsg("Download failed!"); for (int i = 0; i < 60*2; i++) { gspWaitForVBlank(); } } void notConnectedMsg(void) { - displayBottomMsg("Please connect to Wi-Fi"); + Msg::DisplayMsg("Please connect to Wi-Fi"); for (int i = 0; i < 60*2; i++) { gspWaitForVBlank(); } } void doneMsg(void) { - displayBottomMsg("Done!"); + Msg::DisplayMsg("Done!"); for (int i = 0; i < 60*2; i++) { gspWaitForVBlank(); } @@ -640,10 +640,10 @@ void downloadTheme(std::string path) { vector themeContents = getThemeList("DS-Homebrew/twlmenu-extras", path); for(uint i=0;i jsonShasTemp = getRecentCommits(repo, "sha"); std::vector jsonBodyTemp = ((jsonShasTemp[0] == "API") ? jsonShasTemp : getRecentCommitsArray(repo, "commit", "message")); std::vector jsonShas; @@ -761,7 +761,7 @@ std::string chooseCommit(std::string repo, std::string title, bool showExitText) commitsText += "\n"; } commitsText += "B: Back A: Info"; - displayBottomMsg(commitsText.c_str()); + Msg::DisplayMsg(commitsText); } setMessageText(jsonBody[selectedCommit]); @@ -818,7 +818,7 @@ void setMessageText(const std::string &text) { std::string temp; _topText.clear(); for(auto word : words) { - int width = Draw_GetTextWidth(0.5f, (temp + " " + word).c_str()); + int width = Gui::GetStringWidth(0.5f, (temp + " " + word).c_str()); if(word.find('\n') != -1u) { word.erase(std::remove(word.begin(), word.end(), '\n'), word.end()); @@ -843,29 +843,29 @@ void setMessageText(const std::string &text) { void drawMessageText(int position, bool showExitText) { Gui::clearTextBufs(); C3D_FrameBegin(C3D_FRAME_SYNCDRAW); - C2D_TargetClear(bottom, TRANSPARENT); - set_screen(bottom); - Gui::sprite(sprites_BS_loading_background_idx, 0, 0); - Draw_Text(18, 24, .7, BLACK, jsonName.c_str()); + C2D_TargetClear(Bottom, TRANSPARENT); + Gui::ScreenDraw(Bottom); + GFX::DrawSprite(sprites_BS_loading_background_idx, 0, 0); + Gui::DrawString(18, 24, .7, BLACK, jsonName.c_str()); for (int i = 0; i < (int)_topText.size() && i < (showExitText ? 9 : 10); i++) { - Draw_Text(24, ((i * 16) + 48), 0.5f, BLACK, _topText[i+position].c_str()); + Gui::DrawString(24, ((i * 16) + 48), 0.5f, BLACK, _topText[i+position].c_str()); } if(showExitText) - Draw_Text(24, 200, 0.5f, BLACK, "B: Cancel A: Update"); - Draw_EndFrame(); + Gui::DrawString(24, 200, 0.5f, BLACK, "B: Cancel A: Update"); + C3D_FrameEnd(0); } void displayProgressBar() { char str[256]; while(showProgressBar) { snprintf(str, sizeof(str), "%s\n%s%s\n%i %s", progressBarMsg, (!progressBarType ? "" : "\nCurrently extracting:\n"), (!progressBarType ? "" : extractingFile.c_str()), (!progressBarType ? (int)round(result_written/1000) : filesExtracted), (!progressBarType ? "KB downloaded." : (filesExtracted == 1 ? "file extracted." :"files extracted."))); - displayBottomMsg(str); + Msg::DisplayMsg(str); gspWaitForVBlank(); } } bool promtUsernamePassword(void) { - displayBottomMsg("The GitHub API rate limit has been\n" + Msg::DisplayMsg("The GitHub API rate limit has been\n" "exceeded for your IP, you can regain\n" "access by signing in to a GitHub account\n" "or waiting for a bit\n" @@ -873,15 +873,15 @@ bool promtUsernamePassword(void) { "B: Cancel A: Authenticate"); C3D_FrameBegin(C3D_FRAME_SYNCDRAW); - set_screen(bottom); - Draw_Text(20, 100, 0.45f, BLACK, "Username:"); - Draw_Rect(100, 100, 100, 14, GRAY); - Draw_Text(20, 120, 0.45f, BLACK, "Password:"); - Draw_Rect(100, 120, 100, 14, GRAY); + Gui::ScreenDraw(Bottom); + Gui::DrawString(20, 100, 0.45f, BLACK, "Username:"); + Gui::Draw_Rect(100, 100, 100, 14, GRAY); + Gui::DrawString(20, 120, 0.45f, BLACK, "Password:"); + Gui::Draw_Rect(100, 120, 100, 14, GRAY); - Draw_Rect(100, 140, 14, 14, GRAY); - Draw_Text(120, 140, 0.45f, BLACK, "Save login?"); - Draw_EndFrame(); + Gui::Draw_Rect(100, 140, 14, 14, GRAY); + Gui::DrawString(120, 140, 0.45f, BLACK, "Save login?"); + C3D_FrameEnd(0); bool save = false; int hDown; @@ -905,23 +905,23 @@ bool promtUsernamePassword(void) { if(touch.px >= 100 && touch.px <= 200 && touch.py >= 100 && touch.py <= 114) { username = keyboardInput("Username"); C3D_FrameBegin(C3D_FRAME_SYNCDRAW); - set_screen(bottom); - Draw_Rect(100, 100, 100, 14, GRAY); - Draw_Text(100, 100, 0.45f, BLACK, username.c_str()); - Draw_EndFrame(); + Gui::ScreenDraw(Bottom); + Gui::Draw_Rect(100, 100, 100, 14, GRAY); + Gui::DrawString(100, 100, 0.45f, BLACK, username.c_str()); + C3D_FrameEnd(0); } else if(touch.px >= 100 && touch.px <= 200 && touch.py >= 120 && touch.py <= 134) { password = keyboardInput("Password"); C3D_FrameBegin(C3D_FRAME_SYNCDRAW); - set_screen(bottom); - Draw_Rect(100, 120, 100, 14, GRAY); - Draw_Text(100, 120, 0.45f, BLACK, password.c_str()); - Draw_EndFrame(); + Gui::ScreenDraw(Bottom); + Gui::Draw_Rect(100, 120, 100, 14, GRAY); + Gui::DrawString(100, 120, 0.45f, BLACK, password.c_str()); + C3D_FrameEnd(0); } else if(touch.px >= 100 && touch.px <= 114 && touch.py >= 140 && touch.py <= 154) { save = !save; C3D_FrameBegin(C3D_FRAME_SYNCDRAW); - set_screen(bottom); - Draw_Rect(102, 142, 10, 10, save ? GREEN : GRAY); - Draw_EndFrame(); + Gui::ScreenDraw(Bottom); + Gui::Draw_Rect(102, 142, 10, 10, save ? GREEN : GRAY); + C3D_FrameEnd(0); } } } @@ -1072,7 +1072,7 @@ void updateBootstrap(std::string commit) { saveUpdateData(); updateAvailable[3] = false; } else { - displayBottomMsg("Downloading nds-bootstrap...\n(Release)"); + Msg::DisplayMsg("Downloading nds-bootstrap...\n(Release)"); snprintf(progressBarMsg, sizeof(progressBarMsg), "Downloading nds-bootstrap...\n(Release)"); showProgressBar = true; progressBarType = 0; @@ -1117,7 +1117,7 @@ void updateTWiLight(std::string commit) { extractArchive("/TWiLightMenu-nightly.7z", "3DS - CFW users/", "/"); showProgressBar = false; - displayBottomMsg("Installing TWiLight Menu++ CIA...\n" + Msg::DisplayMsg("Installing TWiLight Menu++ CIA...\n" "(Nightly)"); installCia("/TWiLight Menu.cia"); installCia("/TWiLight Menu - Game booter.cia"); @@ -1149,7 +1149,7 @@ void updateTWiLight(std::string commit) { extractArchive("/TWiLightMenu-release.7z", "DSi&3DS - SD card users/", "/"); showProgressBar = false; - displayBottomMsg("Installing TWiLight Menu++ CIA...\n" + Msg::DisplayMsg("Installing TWiLight Menu++ CIA...\n" "(Release)"); installCia("/TWiLight Menu.cia"); installCia("/TWiLight Menu - Game booter.cia"); @@ -1184,7 +1184,7 @@ void updateSelf(std::string commit) { saveUpdateData(); updateAvailable[5] = false; - displayBottomMsg("Installing TWiLight Menu++ Updater CIA...\n" + Msg::DisplayMsg("Installing TWiLight Menu++ Updater CIA...\n" "(Nightly)\n\n\n\n\n\n\n\n\n\n" "The app will reboot when done."); installCia("/TWiLightMenu-Updater-nightly.cia"); @@ -1207,7 +1207,7 @@ void updateSelf(std::string commit) { saveUpdateData(); updateAvailable[4] = false; - displayBottomMsg("Installing TWiLight Menu++ Updater CIA...\n" + Msg::DisplayMsg("Installing TWiLight Menu++ Updater CIA...\n" "(Release)\n\n\n\n\n\n\n\n\n\n" "The app will reboot when done."); installCia("/TWiLightMenu-Updater-release.cia"); @@ -1395,7 +1395,7 @@ void downloadExtras(void) { } extrasText += "\n\n\n\n\n\n\n\n"; extrasText += "B: Back A: Choose"; - displayBottomMsg(extrasText.c_str()); + Msg::DisplayMsg(extrasText.c_str()); } } @@ -1404,7 +1404,7 @@ void downloadBoxart(void) { vector dirContents; std::string scanDir; - displayBottomMsg("Would you like to choose a directory, or scan\nthe full card?\n\n\n\n\n\n\n\n\n\nB: Cancel A: Choose Directory X: Full SD"); + Msg::DisplayMsg("Would you like to choose a directory, or scan\nthe full card?\n\n\n\n\n\n\n\n\n\nB: Cancel A: Choose Directory X: Full SD"); while(1) { gspWaitForVBlank(); @@ -1482,7 +1482,7 @@ void downloadBoxart(void) { dirs += "\n"; } dirs += "B: Back A: Open X: Choose"; - displayBottomMsg(dirs.c_str()); + Msg::DisplayMsg(dirs.c_str()); } } break; @@ -1494,7 +1494,7 @@ void downloadBoxart(void) { } } - displayBottomMsg("Scanning SD card for DS roms...\n\n(Press B to cancel)"); + Msg::DisplayMsg("Scanning SD card for DS roms...\n\n(Press B to cancel)"); chdir(scanDir.c_str()); continueNdsScan = true; @@ -1509,7 +1509,7 @@ void downloadBoxart(void) { if(access(path, F_OK) != 0) { char downloadMessage[50]; snprintf(downloadMessage, sizeof(downloadMessage), "Downloading \"%s.png\"...\n", dirContents[i].tid); - displayBottomMsg(downloadMessage); + Msg::DisplayMsg(downloadMessage); const char *ba_region = getBoxartRegion(dirContents[i].tid[3]); @@ -1525,7 +1525,7 @@ void downloadBoxart(void) { chdir("sdmc:/_nds/TWiLightMenu/boxart/temp/"); getDirectoryContents(dirContents); - displayBottomMsg("Cleaning up..."); + Msg::DisplayMsg("Cleaning up..."); for(int i=0;i<(int)dirContents.size();i++) { if(dirContents[i].size == 0) { char path[256]; @@ -1582,10 +1582,10 @@ void downloadThemes(void) { } themesText += "\n\n\n\n\n"; themesText += "B: Back A: Choose"; - displayBottomMsg(themesText.c_str()); + Msg::DisplayMsg(themesText.c_str()); } - displayBottomMsg("Getting theme list..."); + Msg::DisplayMsg("Getting theme list..."); std::vector themeList; themeList = getThemeList("DS-Homebrew/twlmenu-extras", "_nds/TWiLightMenu/"+themeFolders[selectedTwlTheme]+"/themes"); @@ -1601,7 +1601,7 @@ void downloadThemes(void) { if(keyRepeatDelay) keyRepeatDelay--; if(hDown & KEY_A) { mkdir((themeList[selectedTheme].sdPath).c_str(), 0777); - displayBottomMsg(("Downloading: "+themeList[selectedTheme].name).c_str()); + Msg::DisplayMsg(("Downloading: "+themeList[selectedTheme].name).c_str()); downloadTheme(themeList[selectedTheme].path); } else if(hDown & KEY_B) { selectedTheme = 0; @@ -1641,6 +1641,6 @@ void downloadThemes(void) { themesText += "\n"; } themesText += "B: Back A: Choose"; - displayBottomMsg(themesText.c_str()); + Msg::DisplayMsg(themesText.c_str()); } } diff --git a/source/fileBrowse.cpp b/source/fileBrowse.cpp index 81a0c35..7a4e546 100644 --- a/source/fileBrowse.cpp +++ b/source/fileBrowse.cpp @@ -1,18 +1,15 @@ -#include "fileBrowse.h" -#include +#include "common.hpp" +#include "fileBrowse.hpp" + #include -#include +#include #include - +#include using namespace std; - int file_count = 0; - extern bool continueNdsScan; -extern void displayBottomMsg(const char* text); - /** * Get the title ID. * @param ndsFile DS ROM image. @@ -30,7 +27,7 @@ void findNdsFiles(vector& dirContents) { DIR *pdir = opendir("."); if (pdir == NULL) { - displayBottomMsg("Unable to open the directory."); + Msg::DisplayMsg("Unable to open the directory."); for(int i=0;i<120;i++) gspWaitForVBlank(); } else { @@ -45,7 +42,7 @@ void findNdsFiles(vector& dirContents) { dirEntry.name = pent->d_name; char scanningMessage[512]; snprintf(scanningMessage, sizeof(scanningMessage), "Scanning SD card for DS roms...\n\n(Press B to cancel)\n\n\n\n\n\n\n\n\n%s", dirEntry.name.c_str()); - displayBottomMsg(scanningMessage); + Msg::DisplayMsg(scanningMessage); dirEntry.isDirectory = (st.st_mode & S_IFDIR) ? true : false; if(!(dirEntry.isDirectory) && dirEntry.name.length() >= 3) { if (strcasecmp(dirEntry.name.substr(dirEntry.name.length()-3, 3).c_str(), "nds") == 0) { @@ -101,7 +98,7 @@ void getDirectoryContents (vector& dirContents) { DIR *pdir = opendir ("."); if (pdir == NULL) { - displayBottomMsg("Unable to open the directory."); + Msg::DisplayMsg("Unable to open the directory."); for(int i=0;i<120;i++) gspWaitForVBlank(); } else { diff --git a/source/gfx.cpp b/source/gfx.cpp new file mode 100644 index 0000000..8537b8d --- /dev/null +++ b/source/gfx.cpp @@ -0,0 +1,29 @@ +#include "common.hpp" + +extern C2D_SpriteSheet sprites; + +void GFX::DrawTop(void) { + Gui::ScreenDraw(Top); + DrawSprite(sprites_top_bg_idx, 0, 0); + DrawSprite(sprites_twinkle_3_idx, 133, 61); + DrawSprite(sprites_twinkle_2_idx, 157, 81); + DrawSprite(sprites_twinkle_1_idx, 184, 107); + DrawSprite(sprites_arrow_idx, 41, 25); + DrawSprite(sprites_text_updater_idx, 187, 151); + DrawSprite(sprites_twlm_logo_idx, 127, 100); +} + + +void GFX::DrawSprite(int img, int x, int y, float ScaleX, float ScaleY) +{ + Gui::DrawSprite(sprites, img, x, y, ScaleX, ScaleY); +} + +void GFX::DrawSpriteBlend(int img, int x, int y, u32 color, float ScaleX, float ScaleY) { + C2D_ImageTint tint; + C2D_SetImageTint(&tint, C2D_TopLeft, color, 1); + C2D_SetImageTint(&tint, C2D_TopRight, color, 1); + C2D_SetImageTint(&tint, C2D_BotLeft, color, 1); + C2D_SetImageTint(&tint, C2D_BotRight, color, 1); + C2D_DrawImageAt(C2D_SpriteSheetGetImage(sprites, img), x, y, 0.5f, &tint, ScaleX, ScaleY); +} \ No newline at end of file diff --git a/source/gui.cpp b/source/gui.cpp deleted file mode 100644 index 04c2b4e..0000000 --- a/source/gui.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* -* This file is part of Universal-Manager -* Copyright (C) 2019 VoltZ, Epicpkmn11, Flame, RocketRobz, TotallyNotGuy -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* Additional Terms 7.b and 7.c of GPLv3 apply to this file: -* * Requiring preservation of specified reasonable legal notices or -* author attributions in that material or in the Appropriate Legal -* Notices displayed by works containing it. -* * Prohibiting misrepresentation of the origin of that material, -* or requiring that modified versions of such material be marked in -* reasonable ways as different from the original version. -*/ - -#include "gui.hpp" -#include -#include -#include - - -C3D_RenderTarget* top; -C3D_RenderTarget* bottom; - -static C2D_SpriteSheet sprites; -C2D_TextBuf sizeBuf; -C2D_Font systemFont; - -void Gui::clearTextBufs(void) { - C2D_TextBufClear(sizeBuf); -} - -Result Gui::init(void) { - C3D_Init(C3D_DEFAULT_CMDBUF_SIZE); - C2D_Init(C2D_DEFAULT_MAX_OBJECTS); - C2D_Prepare(); - top = C2D_CreateScreenTarget(GFX_TOP, GFX_LEFT); - bottom = C2D_CreateScreenTarget(GFX_BOTTOM, GFX_LEFT); - sizeBuf = C2D_TextBufNew(4096); - sprites = C2D_SpriteSheetLoad("romfs:/gfx/sprites.t3x"); - systemFont = C2D_FontLoadSystem(CFG_REGION_USA); - return 0; -} - -void Gui::exit(void) { - if (sprites) { - C2D_SpriteSheetFree(sprites); - } - C2D_TextBufDelete(sizeBuf); - C2D_Fini(); - C3D_Fini(); -} - -void set_screen(C3D_RenderTarget * screen) { - C2D_SceneBegin(screen); -} - -void Gui::sprite(int key, int x, int y) { - if (key == sprites_res_null_idx) { - return; - } else { // standard case - C2D_DrawImageAt(C2D_SpriteSheetGetImage(sprites, key), x, y, 0.5f); - } -} - -void Gui::Draw_ImageBlend(int key, int x, int y, u32 color) { - C2D_ImageTint tint; - C2D_SetImageTint(&tint, C2D_TopLeft, color, 1); - C2D_SetImageTint(&tint, C2D_TopRight, color, 1); - C2D_SetImageTint(&tint, C2D_BotLeft, color, 1); - C2D_SetImageTint(&tint, C2D_BotRight, color, 1); - C2D_DrawImageAt(C2D_SpriteSheetGetImage(sprites, key), x, y, 0.5f, &tint); -} - -void displayMsg(const char* text) { - Gui::clearTextBufs(); - C3D_FrameBegin(C3D_FRAME_SYNCDRAW); - C2D_TargetClear(bottom, TRANSPARENT); - set_screen(bottom); - Gui::sprite(sprites_BS_loading_background_idx, 0, 0); - Draw_Text(24, 32, 0.45f, BLACK, text); - Draw_EndFrame(); -} - -void displayBottomMsg(const char* text) { - Gui::clearTextBufs(); - C3D_FrameBegin(C3D_FRAME_SYNCDRAW); - C2D_TargetClear(bottom, TRANSPARENT); - set_screen(bottom); - Gui::sprite(sprites_BS_loading_background_idx, 0, 0); - Draw_Text(24, 32, 0.45f, BLACK, text); - Draw_EndFrame(); -} - -void Draw_EndFrame(void) { - C2D_TextBufClear(sizeBuf); - C3D_FrameEnd(0); -} - -void Draw_Text(float x, float y, float size, u32 color, const char *text) { - C2D_Text c2d_text; - C2D_TextFontParse(&c2d_text, systemFont, sizeBuf, text); - C2D_TextOptimize(&c2d_text); - C2D_DrawText(&c2d_text, C2D_WithColor, x, y, 0.5f, size, size, color); -} - -void Draw_Textf(float x, float y, float size, u32 color, const char* text, ...) { - char buffer[256]; - va_list args; - va_start(args, text); - vsnprintf(buffer, 256, text, args); - Draw_Text(x, y, size, color, buffer); - va_end(args); -} - -void Draw_GetTextSize(float size, float *width, float *height, const char *text) { - C2D_Text c2d_text; - C2D_TextFontParse(&c2d_text, systemFont, sizeBuf, text); - C2D_TextGetDimensions(&c2d_text, size, size, width, height); -} - -float Draw_GetTextWidth(float size, const char *text) { - float width = 0; - Draw_GetTextSize(size, &width, NULL, text); - return width; -} - -float Draw_GetTextHeight(float size, const char *text) { - float height = 0; - Draw_GetTextSize(size, NULL, &height, text); - return height; -} - -bool Draw_Rect(float x, float y, float w, float h, u32 color) { - return C2D_DrawRectSolid(x, y, 0.5f, w, h, color); -} \ No newline at end of file diff --git a/source/init.cpp b/source/init.cpp new file mode 100644 index 0000000..766e957 --- /dev/null +++ b/source/init.cpp @@ -0,0 +1,155 @@ +#include "common.hpp" +#include "download.hpp" +#include "dumpdsp.h" +#include "inifile.h" +#include "init.hpp" +#include "sound.h" +#include "thread.h" +#include "updaterScreen.hpp" + +#include <3ds.h> +#include +#include + +#define CONFIG_3D_SLIDERSTATE (*(float *)0x1FF81080) + +static touchPosition touch; + +int fadealpha = 255; +bool fadein = true; + +bool dspfirmfound = false; +bool updatingSelf = false; +bool updated3dsx = false; +static bool musicPlaying = false; +bool exiting = false; + +// Music and sound effects. +sound *mus_settings = NULL; +sound *sfx_launch = NULL; +sound *sfx_select = NULL; +sound *sfx_stop = NULL; +sound *sfx_switch = NULL; +sound *sfx_wrong = NULL; +sound *sfx_back = NULL; + +C2D_SpriteSheet sprites; + +void Play_Music(void) { + if (!musicPlaying && dspfirmfound) { + mus_settings->play(); + musicPlaying = true; + } +} + +Result Init::Initialize() { + amInit(); + sdmcInit(); + romfsInit(); + acInit(); + cfguInit(); + gfxInitDefault(); + Gui::init(); + Gui::loadSheet("romfs:/gfx/sprites.t3x", sprites); + + osSetSpeedupEnable(true); // Enable speed-up for New 3DS users + + // make folders if they don't exist + mkdir("sdmc:/3ds", 0777); // For DSP dump + mkdir("sdmc:/_nds", 0777); + mkdir("sdmc:/_nds/TWiLightMenu", 0777); + mkdir("sdmc:/_nds/TWiLightMenu/gamesettings", 0777); + mkdir("sdmc:/_nds/TWiLightMenu/emulators", 0777); + mkdir("sdmc:/_nds/TWiLightMenu/extras", 0777); + mkdir("sdmc:/_nds/TWiLightMenu/extras/updater", 0777); + + if (access("sdmc:/3ds/dspfirm.cdc", F_OK ) != -1 ) { + ndspInit(); + dspfirmfound = true; + } else{ + C3D_FrameBegin(C3D_FRAME_SYNCDRAW); + Gui::ScreenDraw(Bottom); + Gui::DrawString(12, 16, 0.5f, WHITE, "Dumping DSP firm..."); + C3D_FrameEnd(0); + dumpDsp(); + if(access("sdmc:/3ds/dspfirm.cdc", F_OK ) != -1 ) { + ndspInit(); + dspfirmfound = true; + } else { + for (int i = 0; i < 90; i++) { + C3D_FrameBegin(C3D_FRAME_SYNCDRAW); + C2D_TargetClear(Bottom, TRANSPARENT); // clear Bottom Screen to avoid Text overdraw. + Gui::ScreenDraw(Bottom); + Gui::DrawString(12, 16, 0.5f, WHITE, "DSP firm dumping failed.\n" + "Running without sound."); + C3D_FrameEnd(0); + } + } + } + // Load the sound effects if DSP is available. + if (dspfirmfound) { + mus_settings = new sound("romfs:/sounds/settings.wav", 1, true); + sfx_launch = new sound("romfs:/sounds/launch.wav", 2, false); + sfx_select = new sound("romfs:/sounds/select.wav", 2, false); + sfx_stop = new sound("romfs:/sounds/stop.wav", 2, false); + sfx_switch = new sound("romfs:/sounds/switch.wav", 2, false); + sfx_wrong = new sound("romfs:/sounds/wrong.wav", 2, false); + sfx_back = new sound("romfs:/sounds/back.wav", 2, false); + } + + loadUsernamePassword(); + Gui::setScreen(std::make_unique()); + return 0; +} + +Result Init::MainLoop() { + // Initialize everything. + Initialize(); + + Play_Music(); + + // Loop as long as the status is not exiting. + while (aptMainLoop() && !exiting) + { + hidScanInput(); + u32 hHeld = hidKeysHeld(); + u32 hDown = hidKeysDown(); + hidTouchRead(&touch); + C3D_FrameBegin(C3D_FRAME_SYNCDRAW); + C2D_TargetClear(Top, BLACK); + C2D_TargetClear(Bottom, BLACK); + Gui::clearTextBufs(); + Gui::mainLoop(hDown, hHeld, touch); + C3D_FrameEnd(0); + + if (fadein == true) { + fadealpha -= 3; + if (fadealpha < 0) { + fadealpha = 0; + fadein = false; + } + } + } + // Exit all services and exit the app. + Exit(); + return 0; +} + +Result Init::Exit() { + delete mus_settings; + delete sfx_launch; + delete sfx_select; + delete sfx_stop; + delete sfx_switch; + delete sfx_wrong; + delete sfx_back; + if (dspfirmfound) { + ndspExit(); + } + Gui::exit(); + Gui::unloadSheet(sprites); + romfsExit(); + sdmcExit(); + cfguExit(); + return 0; +} \ No newline at end of file diff --git a/source/main.cpp b/source/main.cpp index 7adb3c5..1763c0b 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -1,477 +1,5 @@ -#include -#include -#include -#include <3ds.h> -#include -#include -#include - -#include "download.hpp" -#include "dumpdsp.h" -#include "gui.hpp" -#include "inifile.h" -#include "sound.h" -#include "thread.h" - -#define CONFIG_3D_SLIDERSTATE (*(float *)0x1FF81080) - -static touchPosition touch; - -bool dspfirmfound = false; -bool updatingSelf = false; -bool updated3dsx = false; -static bool musicPlaying = false; -extern C3D_RenderTarget* top; -extern C3D_RenderTarget* bottom; - -// Music and sound effects. -sound *mus_settings = NULL; -sound *sfx_launch = NULL; -sound *sfx_select = NULL; -sound *sfx_stop = NULL; -sound *sfx_switch = NULL; -sound *sfx_wrong = NULL; -sound *sfx_back = NULL; - -// 3D offsets. (0 == Left, 1 == Right) -struct _Offset3D { - float topbg; - float twinkle3; - float twinkle2; - float twinkle1; - float updater; - float logo; -} offset3D[2] = {0.0f, 0.0f}; - -struct { - int x; - int y; -} buttons2[] = { { 129, 48}, { 220, 48}, { 129, 88}, { 220, 88}, { 129, 128}, { 220, 128}, { 129, 168}, { 220, 168}, -}; - -size_t button_tex2[] = { - sprites_BS_2page_extra_small_button_idx, - sprites_BS_2page_extra_small_button_idx, - sprites_BS_2page_extra_small_button_idx, - sprites_BS_2page_extra_small_button_idx, - sprites_BS_2page_extra_small_button_idx, - sprites_BS_2page_extra_small_button_idx, - sprites_BS_2page_extra_small_button_idx, - sprites_BS_2page_extra_small_button_idx, -}; - -const char *button_titles2[] = { - "Release", - "Nightly", - "Release", - "Nightly", - "Release", - "Nightly", - "Cheats", - "Extras", -}; - -const int title_spacing[] = { - 6, - 10, - 6, - 10, - 6, - 10, - 10, - 17, -}; - -const char *row_titles2[] = { - "TWL Menu++", - "nds-bootstrap", - "Updater", - "Downloads", -}; - -bool updateAvailable[] = { - false, - false, - false, - false, - false, - false, - false, - false, -}; - -static void Play_Music(void) { - if (!musicPlaying && dspfirmfound) { - mus_settings->play(); - musicPlaying = true; - } -} - -int menuSelection = 0; +#include "init.hpp" int main() { - aptInit(); - amInit(); - sdmcInit(); - romfsInit(); - srvInit(); - hidInit(); - acInit(); - cfguInit(); - gfxInitDefault(); - - osSetSpeedupEnable(true); // Enable speed-up for New 3DS users - - // make folders if they don't exist - mkdir("sdmc:/3ds", 0777); // For DSP dump - mkdir("sdmc:/_nds", 0777); - mkdir("sdmc:/_nds/TWiLightMenu", 0777); - mkdir("sdmc:/_nds/TWiLightMenu/gamesettings", 0777); - mkdir("sdmc:/_nds/TWiLightMenu/emulators", 0777); - mkdir("sdmc:/_nds/TWiLightMenu/extras", 0777); - mkdir("sdmc:/_nds/TWiLightMenu/extras/updater", 0777); - - Gui::init(); - - if( access( "sdmc:/3ds/dspfirm.cdc", F_OK ) != -1 ) { - ndspInit(); - dspfirmfound = true; - }else{ - C3D_FrameBegin(C3D_FRAME_SYNCDRAW); - set_screen(bottom); - Draw_Text(12, 16, 0.5f, WHITE, "Dumping DSP firm..."); - Draw_EndFrame(); - dumpDsp(); - if( access( "sdmc:/3ds/dspfirm.cdc", F_OK ) != -1 ) { - ndspInit(); - dspfirmfound = true; - } else { - for (int i = 0; i < 90; i++) { - C3D_FrameBegin(C3D_FRAME_SYNCDRAW); - set_screen(bottom); - Draw_Text(12, 16, 0.5f, WHITE, "DSP firm dumping failed.\n" - "Running without sound."); - Draw_EndFrame(); - } - } - } - - // Load the sound effects if DSP is available. - if (dspfirmfound) { - mus_settings = new sound("romfs:/sounds/settings.wav", 1, true); - sfx_launch = new sound("romfs:/sounds/launch.wav", 2, false); - sfx_select = new sound("romfs:/sounds/select.wav", 2, false); - sfx_stop = new sound("romfs:/sounds/stop.wav", 2, false); - sfx_switch = new sound("romfs:/sounds/switch.wav", 2, false); - sfx_wrong = new sound("romfs:/sounds/wrong.wav", 2, false); - sfx_back = new sound("romfs:/sounds/back.wav", 2, false); - } - - bool buttonShading = false; - bool setOption = false; - bool showMessage = false; - - int fadealpha = 255; - bool fadein = true; - - loadUsernamePassword(); - if(checkWifiStatus()) { - checkForUpdates(); - } - - // Loop as long as the status is not exit - createThread((ThreadFunc)Play_Music); - while(aptMainLoop()) { - - // Scan hid shared memory for input events - hidScanInput(); - - const u32 hDown = hidKeysDown(); - - hidTouchRead(&touch); - - C3D_FrameBegin(C3D_FRAME_SYNCDRAW); - C2D_TargetClear(top, TRANSPARENT); - C2D_TargetClear(bottom, TRANSPARENT); - Gui::clearTextBufs(); - set_screen(top); - Gui::sprite(sprites_top_bg_idx, 0, 0); - Gui::sprite(sprites_twinkle_3_idx, 133, 61); - Gui::sprite(sprites_twinkle_2_idx, 157, 81); - Gui::sprite(sprites_twinkle_1_idx, 184, 107); - Gui::sprite(sprites_arrow_idx, 41, 25); - Gui::sprite(sprites_text_updater_idx, 187, 151); - Gui::sprite(sprites_twlm_logo_idx, 127, 100); - Draw_Text(336, 222, 0.50, WHITE, VERSION_STRING); - if (fadealpha > 0) Draw_Rect(0, 0, 400, 240, RGBA8(0, 0, 0, fadealpha)); // Fade in/out effect - - set_screen(bottom); - Gui::sprite(sprites_BS_background_idx, 0, 0); - Draw_Text(6, 5, 0.55, WHITE, "Updater menu"); - // Draw buttons - for (int i = (int)(sizeof(buttons2)/sizeof(buttons2[0]))-1; i >= 0; i--) { - if (menuSelection == i) { - // Button is highlighted. - Gui::sprite(button_tex2[i], buttons2[i].x, buttons2[i].y); - } else { - // Button is not highlighted. Darken the texture. - if (buttonShading) { - Gui::Draw_ImageBlend(button_tex2[i], buttons2[i].x, buttons2[i].y, GRAY); - } else { - Gui::sprite(button_tex2[i], buttons2[i].x, buttons2[i].y); - } - } - // Draw a green dot if an update is availible - if(updateAvailable[i]) { - Gui::sprite(sprites_dot_green_idx, buttons2[i].x+75, buttons2[i].y-6); - } - - // Determine the text height. - // NOTE: Button texture size is 132x34. - const int h = 32; - - // Draw the title. - int y = buttons2[i].y + ((40 - h) / 2); - int x_from_width = buttons2[i].x + title_spacing[i]; - Draw_Text(x_from_width, y, 0.75, BLACK, button_titles2[i]); - - if(!(i%2)) { - Draw_Text(0, y, 0.60, WHITE, row_titles2[i/2]); - } - } - //const wchar_t *home_text = TR(STR_RETURN_TO_HOME_MENU); - //const int home_width = pp2d_get_wtext_width(home_text, 0.50, 0.50) + 16; - //const int home_x = (320-home_width)/2; - //pp2d_draw_texture(homeicontex, home_x, 219); // Draw HOME icon - //pp2d_draw_wtext(home_x+20, 220, 0.50, 0.50, WHITE, home_text); - if (fadealpha > 0) Draw_Rect(0, 0, 320, 240, RGBA8(0, 0, 0, fadealpha)); // Fade in/out effect - Draw_EndFrame(); - - if (fadein == true) { - fadealpha -= 15; - if (fadealpha < 0) { - fadealpha = 0; - fadein = false; - } - } - - if (hDown & KEY_UP) { - if (buttonShading) menuSelection -= 2; - } else if (hDown & KEY_DOWN) { - if (buttonShading) menuSelection += 2; - } else if (hDown & KEY_LEFT) { - if (buttonShading && menuSelection%2) menuSelection--; - } else if (hDown & KEY_RIGHT) { - if (buttonShading && !(menuSelection%2)) menuSelection++; - } - if (hDown & (KEY_UP | KEY_DOWN | KEY_LEFT | KEY_RIGHT)) { - buttonShading = true; - if(dspfirmfound) { - sfx_select->stop(); - sfx_select->play(); - } - } - - if (hDown & KEY_TOUCH) { - buttonShading = false; - } - - if (menuSelection > 8) menuSelection = 1; - else if (menuSelection > 7) menuSelection = 0; - else if (menuSelection < -1) menuSelection = 6; - else if (menuSelection < 0) menuSelection = 7; - - if (hDown & KEY_A) { - setOption = true; - } - - if (hDown & KEY_TOUCH) { - for (int i = (int)(sizeof(buttons2)/sizeof(buttons2[0]))-1; i >= 0; i--) { - if(updateAvailable[i]){ - if (touch.py >= (buttons2[i].y-6) && touch.py <= (buttons2[i].y+10) && touch.px >= (buttons2[i].x+75) && touch.px <= (buttons2[i].x+91)) { - menuSelection = i; - showMessage = true; - } - } - } - if(!showMessage) { - for (int i = (int)(sizeof(buttons2)/sizeof(buttons2[0]))-1; i >= 0; i--) { - if (touch.py >= buttons2[i].y && touch.py <= (buttons2[i].y+33) && touch.px >= buttons2[i].x && touch.px <= (buttons2[i].x+87)) { - menuSelection = i; - setOption = true; - } - } - } - } - - if (hDown & KEY_Y || showMessage) { - switch (menuSelection) - { - case 0: - if(dspfirmfound) { - sfx_select->stop(); - sfx_select->play(); - } - showReleaseInfo("DS-Homebrew/TWiLightMenu", false); - break; - case 1: - if(dspfirmfound) { - sfx_select->stop(); - sfx_select->play(); - } - chooseCommit("TWLBot/Builds", "TWiLightMenu |", false); - break; - case 2: - if(dspfirmfound) { - sfx_select->stop(); - sfx_select->play(); - } - showReleaseInfo("ahezard/nds-bootstrap", false); - break; - case 3: - if(dspfirmfound) { - sfx_select->stop(); - sfx_select->play(); - } - chooseCommit("TWLBot/Builds", "nds-bootstrap |", false); - break; - case 4: - if(dspfirmfound) { - sfx_select->stop(); - sfx_select->play(); - } - showReleaseInfo("RocketRobz/TWiLightMenu-Updater", false); - break; - case 5: - if(dspfirmfound) { - sfx_select->stop(); - sfx_select->play(); - } - chooseCommit("TWLBot/Builds", "TWiLightMenu-Updater |", false); - break; - default: - if(dspfirmfound) { - sfx_wrong->stop(); - sfx_wrong->play(); - } - break; - } - showMessage = false; - } - - if (setOption) { - if(checkWifiStatus()) { - std::string commit; - switch (menuSelection) { - case 0: // TWiLight release - if(dspfirmfound) { - sfx_select->stop(); - sfx_select->play(); - } - if(showReleaseInfo("DS-Homebrew/TWiLightMenu", true)) - updateTWiLight(""); - break; - case 1: // TWiLight nightly - if(dspfirmfound) { - sfx_select->stop(); - sfx_select->play(); - } - if((commit = chooseCommit("TWLBot/Builds", "TWiLightMenu |", true)) != "") - updateTWiLight(commit); - break; - case 2: // nds-bootstrap release - if(dspfirmfound) { - sfx_select->stop(); - sfx_select->play(); - } - if(showReleaseInfo("ahezard/nds-bootstrap", true)) - updateBootstrap(""); - break; - case 3: // nds-bootstrap nightly - if(dspfirmfound) { - sfx_select->stop(); - sfx_select->play(); - } - if((commit = chooseCommit("TWLBot/Builds", "nds-bootstrap |", true)) != "") - updateBootstrap(commit); - break; - case 4: // Updater release - if(dspfirmfound) { - sfx_select->stop(); - sfx_select->play(); - } - if(showReleaseInfo("RocketRobz/TWiLightMenu-Updater", true)) { - updatingSelf = true; - updateSelf(""); - updatingSelf = false; - } - break; - case 5: // Updater nightly - if(dspfirmfound) { - sfx_select->stop(); - sfx_select->play(); - } - if((commit = chooseCommit("TWLBot/Builds", "TWiLightMenu-Updater |", true)) != "") { - updatingSelf = true; - updateSelf(commit); - updatingSelf = false; - } - break; - case 6: // Cheats - if(dspfirmfound) { - sfx_select->stop(); - sfx_select->play(); - } - updateCheats(); - break; - case 7: // Extras - if(dspfirmfound) { - sfx_select->stop(); - sfx_select->play(); - } - downloadExtras(); - break; - default: - if(dspfirmfound) { - sfx_wrong->stop(); - sfx_wrong->play(); - } - break; - } - } else { - if(dspfirmfound) { - sfx_wrong->stop(); - sfx_wrong->play(); - } - notConnectedMsg(); - } - setOption = false; - } - if(hDown & KEY_START || updated3dsx) { - break; - } - } - - - delete mus_settings; - delete sfx_launch; - delete sfx_select; - delete sfx_stop; - delete sfx_switch; - delete sfx_wrong; - delete sfx_back; - if (dspfirmfound) { - ndspExit(); - } - - Gui::exit(); - - hidExit(); - srvExit(); - romfsExit(); - sdmcExit(); - cfguExit(); - aptExit(); - - return 0; -} + Init::MainLoop(); +} \ No newline at end of file diff --git a/source/msg.cpp b/source/msg.cpp new file mode 100644 index 0000000..60ed5c5 --- /dev/null +++ b/source/msg.cpp @@ -0,0 +1,38 @@ +#include "common.hpp" + +void Msg::DisplayMsg(std::string text) { + Gui::clearTextBufs(); + C3D_FrameBegin(C3D_FRAME_SYNCDRAW); + C2D_TargetClear(Top, TRANSPARENT); + C2D_TargetClear(Bottom, TRANSPARENT); + GFX::DrawTop(); + Gui::ScreenDraw(Bottom); + GFX::DrawSprite(sprites_BS_loading_background_idx, 0, 0); + Gui::DrawString(24, 32, 0.45f, BLACK, text); + C3D_FrameEnd(0); +} + +// Display a Message, which needs to be confirmed with A/B. +bool Msg::promptMsg(std::string promptMsg) +{ + Gui::clearTextBufs(); + C3D_FrameBegin(C3D_FRAME_SYNCDRAW); + C2D_TargetClear(Top, TRANSPARENT); + C2D_TargetClear(Bottom, TRANSPARENT); + GFX::DrawTop(); + Gui::ScreenDraw(Bottom); + GFX::DrawSprite(sprites_BS_loading_background_idx, 0, 0); + Gui::DrawString(24, 32, 0.5f, BLACK, promptMsg); + Gui::DrawStringCentered(0, 180, 0.6f, BLACK, "Press A to confirm, B to cancel.", 390); + C3D_FrameEnd(0); + while(1) + { + gspWaitForVBlank(); + hidScanInput(); + if(hidKeysDown() & KEY_A) { + return true; + } else if(hidKeysDown() & KEY_B) { + return false; + } + } +} \ No newline at end of file diff --git a/source/screens/updaterScreen.cpp b/source/screens/updaterScreen.cpp new file mode 100644 index 0000000..2163278 --- /dev/null +++ b/source/screens/updaterScreen.cpp @@ -0,0 +1,310 @@ +#include "download.hpp" +#include "sound.h" +#include "updaterScreen.hpp" + +extern bool dspfirmfound; +extern bool updatingSelf; +extern bool updated3dsx; +extern bool exiting; +extern int fadealpha; +extern bool fadein; +extern sound *sfx_select; +extern sound *sfx_wrong; + +struct { + int x; + int y; +} buttons2[] = { { 129, 48}, { 220, 48}, { 129, 88}, { 220, 88}, { 129, 128}, { 220, 128}, { 129, 168}, { 220, 168}, +}; + +UpdaterScreen::UpdaterScreen() { + if(checkWifiStatus()) { + if (Msg::promptMsg("Would you like to scan for updates?")) { + Msg::DisplayMsg("Scanning for updates..."); + checkForUpdates(); + } + } +} + + +bool updateAvailable[] = { + false, + false, + false, + false, + false, + false, + false, + false, +}; + +const char *button_titles2[] = { + "Release", + "Nightly", + "Release", + "Nightly", + "Release", + "Nightly", + "Cheats", + "Extras", +}; + +const int title_spacing[] = { + 6, + 10, + 6, + 10, + 6, + 10, + 10, + 17, +}; + +const char *row_titles2[] = { + "TWL Menu++", + "nds-bootstrap", + "Updater", + "Downloads", +}; + + +void UpdaterScreen::Draw(void) const { + GFX::DrawTop(); + Gui::DrawString(336, 222, 0.50, WHITE, VERSION_STRING); + if (fadealpha > 0) Gui::Draw_Rect(0, 0, 400, 240, C2D_Color32(0, 0, 0, fadealpha)); // Fade in/out effect + + Gui::ScreenDraw(Bottom); + GFX::DrawSprite(sprites_BS_background_idx, 0, 0); + Gui::DrawString(6, 5, 0.55, WHITE, "Updater menu"); + // Draw buttons + for (int i = (int)(sizeof(buttons2)/sizeof(buttons2[0]))-1; i >= 0; i--) { + if (menuSelection == i) { + // Button is highlighted. + GFX::DrawSprite(sprites_BS_2page_extra_small_button_idx, buttons2[i].x, buttons2[i].y); + } else { + // Button is not highlighted. Darken the texture. + if (buttonShading) { + GFX::DrawSpriteBlend(sprites_BS_2page_extra_small_button_idx, buttons2[i].x, buttons2[i].y, GRAY); + } else { + GFX::DrawSprite(sprites_BS_2page_extra_small_button_idx, buttons2[i].x, buttons2[i].y); + } + } + // Draw a green dot if an update is availible + if(updateAvailable[i]) { + GFX::DrawSprite(sprites_dot_green_idx, buttons2[i].x+75, buttons2[i].y-6); + } + + // Determine the text height. + // NOTE: Button texture size is 132x34. + const int h = 32; + + // Draw the title. + int y = buttons2[i].y + ((40 - h) / 2); + int x_from_width = buttons2[i].x + title_spacing[i]; + Gui::DrawString(x_from_width, y, 0.75, BLACK, button_titles2[i]); + + if(!(i%2)) { + Gui::DrawString(0, y, 0.60, WHITE, row_titles2[i/2]); + } + } + if (fadealpha > 0) Gui::Draw_Rect(0, 0, 320, 240, C2D_Color32(0, 0, 0, fadealpha)); // Fade in/out effect +} + + +void UpdaterScreen::Logic(u32 hDown, u32 hHeld, touchPosition touch) { + if (hDown & KEY_UP) { + if (buttonShading) menuSelection -= 2; + } else if (hDown & KEY_DOWN) { + if (buttonShading) menuSelection += 2; + } else if (hDown & KEY_LEFT) { + if (buttonShading && menuSelection%2) menuSelection--; + } else if (hDown & KEY_RIGHT) { + if (buttonShading && !(menuSelection%2)) menuSelection++; + } + if (hDown & (KEY_UP | KEY_DOWN | KEY_LEFT | KEY_RIGHT)) { + buttonShading = true; + if(dspfirmfound) { + sfx_select->stop(); + sfx_select->play(); + } + } + + if (hDown & KEY_TOUCH) { + buttonShading = false; + } + + if (menuSelection > 8) menuSelection = 1; + else if (menuSelection > 7) menuSelection = 0; + else if (menuSelection < -1) menuSelection = 6; + else if (menuSelection < 0) menuSelection = 7; + + if (hDown & KEY_A) { + setOption = true; + } + + if (hDown & KEY_TOUCH) { + for (int i = (int)(sizeof(buttons2)/sizeof(buttons2[0]))-1; i >= 0; i--) { + if(updateAvailable[i]){ + if (touch.py >= (buttons2[i].y-6) && touch.py <= (buttons2[i].y+10) && touch.px >= (buttons2[i].x+75) && touch.px <= (buttons2[i].x+91)) { + menuSelection = i; + showMessage = true; + } + } + } + if(!showMessage) { + for (int i = (int)(sizeof(buttons2)/sizeof(buttons2[0]))-1; i >= 0; i--) { + if (touch.py >= buttons2[i].y && touch.py <= (buttons2[i].y+33) && touch.px >= buttons2[i].x && touch.px <= (buttons2[i].x+87)) { + menuSelection = i; + setOption = true; + } + } + } + } + + if (hDown & KEY_Y || showMessage) { + switch (menuSelection) + { + case 0: + if(dspfirmfound) { + sfx_select->stop(); + sfx_select->play(); + } + showReleaseInfo("DS-Homebrew/TWiLightMenu", false); + break; + case 1: + if(dspfirmfound) { + sfx_select->stop(); + sfx_select->play(); + } + chooseCommit("TWLBot/Builds", "TWiLightMenu |", false); + break; + case 2: + if(dspfirmfound) { + sfx_select->stop(); + sfx_select->play(); + } + showReleaseInfo("ahezard/nds-bootstrap", false); + break; + case 3: + if(dspfirmfound) { + sfx_select->stop(); + sfx_select->play(); + } + chooseCommit("TWLBot/Builds", "nds-bootstrap |", false); + break; + case 4: + if(dspfirmfound) { + sfx_select->stop(); + sfx_select->play(); + } + showReleaseInfo("RocketRobz/TWiLightMenu-Updater", false); + break; + case 5: + if(dspfirmfound) { + sfx_select->stop(); + sfx_select->play(); + } + chooseCommit("TWLBot/Builds", "TWiLightMenu-Updater |", false); + break; + default: + if(dspfirmfound) { + sfx_wrong->stop(); + sfx_wrong->play(); + } + break; + } + showMessage = false; + } + + if (setOption) { + if(checkWifiStatus()) { + std::string commit; + switch (menuSelection) { + case 0: // TWiLight release + if(dspfirmfound) { + sfx_select->stop(); + sfx_select->play(); + } + if(showReleaseInfo("DS-Homebrew/TWiLightMenu", true)) + updateTWiLight(""); + break; + case 1: // TWiLight nightly + if(dspfirmfound) { + sfx_select->stop(); + sfx_select->play(); + } + if((commit = chooseCommit("TWLBot/Builds", "TWiLightMenu |", true)) != "") + updateTWiLight(commit); + break; + case 2: // nds-bootstrap release + if(dspfirmfound) { + sfx_select->stop(); + sfx_select->play(); + } + if(showReleaseInfo("ahezard/nds-bootstrap", true)) + updateBootstrap(""); + break; + case 3: // nds-bootstrap nightly + if(dspfirmfound) { + sfx_select->stop(); + sfx_select->play(); + } + if((commit = chooseCommit("TWLBot/Builds", "nds-bootstrap |", true)) != "") + updateBootstrap(commit); + break; + case 4: // Updater release + if(dspfirmfound) { + sfx_select->stop(); + sfx_select->play(); + } + if(showReleaseInfo("RocketRobz/TWiLightMenu-Updater", true)) { + updatingSelf = true; + updateSelf(""); + updatingSelf = false; + } + break; + case 5: // Updater nightly + if(dspfirmfound) { + sfx_select->stop(); + sfx_select->play(); + } + if((commit = chooseCommit("TWLBot/Builds", "TWiLightMenu-Updater |", true)) != "") { + updatingSelf = true; + updateSelf(commit); + updatingSelf = false; + } + break; + case 6: // Cheats + if(dspfirmfound) { + sfx_select->stop(); + sfx_select->play(); + } + updateCheats(); + break; + case 7: // Extras + if(dspfirmfound) { + sfx_select->stop(); + sfx_select->play(); + } + downloadExtras(); + break; + default: + if(dspfirmfound) { + sfx_wrong->stop(); + sfx_wrong->play(); + } + break; + } + } else { + if(dspfirmfound) { + sfx_wrong->stop(); + sfx_wrong->play(); + } + notConnectedMsg(); + } + setOption = false; + } + if(hDown & KEY_START || updated3dsx) { + exiting = true; + } +} \ No newline at end of file