From ce426bb7bb438cfd63d3dd4185b947d48af596dc Mon Sep 17 00:00:00 2001 From: VoltZ <47382115+SuperSaiyajinVoltZ@users.noreply.github.com> Date: Tue, 12 Nov 2019 10:24:38 +0100 Subject: [PATCH] Add Credits Screen and a Spritesheet. ;P --- .gitignore | 2 + Makefile | 35 ++++++- assets/gfx/sprites.t3s | 4 + assets/gfx/sprites/credits/discord.png | Bin 0 -> 17190 bytes assets/gfx/sprites/credits/voltZ.png | Bin 0 -> 18611 bytes include/download/download.hpp | 2 +- include/gui.hpp | 5 + include/screens/scriptCreator.hpp | 15 ++- include/screens/settings.hpp | 22 ++++ romfs/lang/en/app.json | 34 +++++-- source/download/download.cpp | 2 +- source/gui.cpp | 8 ++ source/main.cpp | 2 +- source/screens/mainMenu.cpp | 19 ++-- source/screens/scriptCreator.cpp | 64 ++++++++---- source/screens/settings.cpp | 135 +++++++++++++++++++++++-- 16 files changed, 294 insertions(+), 55 deletions(-) create mode 100644 assets/gfx/sprites.t3s create mode 100644 assets/gfx/sprites/credits/discord.png create mode 100644 assets/gfx/sprites/credits/voltZ.png diff --git a/.gitignore b/.gitignore index a2b356a..30e611e 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,5 @@ makerom* *.pfs0 *.nso *.nacp +build/sprites.h +*.t3x diff --git a/Makefile b/Makefile index d88f339..ecfeb32 100644 --- a/Makefile +++ b/Makefile @@ -95,7 +95,7 @@ RSF_FILE := app/build-cia.rsf ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft CFLAGS := -g -Wall -Wno-psabi -O2 -mword-relocations \ - -DVERSION_STRING=\"$(GIT_VER)\" \ + -DV_STRING=\"$(GIT_VER)\" \ -fomit-frame-pointer -ffunction-sections \ $(ARCH) @@ -136,6 +136,7 @@ CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) PICAFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.v.pica))) SHLISTFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.shlist))) +GFXFILES := $(foreach dir,$(GRAPHICS),$(notdir $(wildcard $(dir)/*.t3s))) BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) #--------------------------------------------------------------------------------- @@ -152,6 +153,19 @@ else endif #--------------------------------------------------------------------------------- +#--------------------------------------------------------------------------------- +ifeq ($(GFXBUILD),$(BUILD)) +#--------------------------------------------------------------------------------- +export T3XFILES := $(GFXFILES:.t3s=.t3x) +#--------------------------------------------------------------------------------- +else +#--------------------------------------------------------------------------------- +export ROMFS_T3XFILES := $(patsubst %.t3s, $(GFXBUILD)/%.t3x, $(GFXFILES)) +export T3XHFILES := $(patsubst %.t3s, $(BUILD)/%.h, $(GFXFILES)) +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- + export OFILES_SOURCES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) export OFILES_BIN := $(addsuffix .o,$(BINFILES)) \ @@ -194,7 +208,7 @@ endif .PHONY: all clean #--------------------------------------------------------------------------------- -all: $(BUILD) $(DEPSDIR) +all: $(BUILD) $(GFXBUILD) $(DEPSDIR) $(ROMFS_T3XFILES) $(T3XHFILES) @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile #------------------------------------------------------------------------------ @@ -212,6 +226,12 @@ cia: $(BUILD) 3dsx: $(BUILD) @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile 3dsx +#--------------------------------------------------------------------------------- +$(GFXBUILD)/%.t3x $(BUILD)/%.h : %.t3s +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + $(DEVKITPRO)/tools/bin/tex3ds -i $< -H $(BUILD)/$*.h -d $(DEPSDIR)/$*.d -o $(GFXBUILD)/$*.t3x + #--------------------------------------------------------------------------------- $(BUILD): @[ -d $@ ] || mkdir -p $@ @@ -240,6 +260,10 @@ $(OUTPUT).cia : $(OUTPUT).elf $(OUTPUT).smdh @echo $(notdir $<) @$(bin2o) +#--------------------------------------------------------------------------------- +.PRECIOUS : %.t3x +#--------------------------------------------------------------------------------- +%.t3x.o %_t3x.h : %.t3x #--------------------------------------------------------------------------------- @echo $(notdir $<) @$(bin2o) @@ -271,8 +295,13 @@ endef @$(call shader-as,$(foreach file,$(shell cat $<),$(dir $<)$(file))) #--------------------------------------------------------------------------------- +%.t3x %.h : %.t3s +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + @tex3ds -i $< -H $*.h -d $*.d -o $*.t3x + -include $(DEPSDIR)/*.d #--------------------------------------------------------------------------------------- endif -#--------------------------------------------------------------------------------------- +#--------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/assets/gfx/sprites.t3s b/assets/gfx/sprites.t3s new file mode 100644 index 0000000..c40ca54 --- /dev/null +++ b/assets/gfx/sprites.t3s @@ -0,0 +1,4 @@ +--atlas -f rgba -z auto + +sprites/credits/discord.png +sprites/credits/voltZ.png \ No newline at end of file diff --git a/assets/gfx/sprites/credits/discord.png b/assets/gfx/sprites/credits/discord.png new file mode 100644 index 0000000000000000000000000000000000000000..5935bb8a34737746123fcea07aaca0cbc64b7f80 GIT binary patch literal 17190 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≫rVQHI9;eVb2Q$! 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 KMNUMnLSTZu71?h9 literal 0 HcmV?d00001 diff --git a/include/download/download.hpp b/include/download/download.hpp index c18e7b6..f4b5f14 100644 --- a/include/download/download.hpp +++ b/include/download/download.hpp @@ -29,7 +29,7 @@ #include "utils/common.hpp" #define APP_TITLE "Universal-Updater" -#define V_STRING "1.0.0" +#define VERSION_STRING "2.0.0" enum DownloadError { DL_ERROR_NONE = 0, diff --git a/include/gui.hpp b/include/gui.hpp index 2226f5f..ce1e14c 100644 --- a/include/gui.hpp +++ b/include/gui.hpp @@ -28,6 +28,8 @@ #define GUI_HPP #include "colors.hpp" +#include "sprites.h" + #include "screens/screen.hpp" #include <3ds.h> @@ -55,6 +57,9 @@ namespace Gui // Clear Text. void clearTextBufs(void); + // Draw a Sprite from the sheet. + void sprite(int key, int x, int y, float ScaleX = 1, float ScaleY = 1); + // Misc. bool Draw_Rect(float x, float y, float w, float h, u32 color); diff --git a/include/screens/scriptCreator.hpp b/include/screens/scriptCreator.hpp index abca930..3d17d87 100644 --- a/include/screens/scriptCreator.hpp +++ b/include/screens/scriptCreator.hpp @@ -30,6 +30,9 @@ #include "screens/screenCommon.hpp" #include "utils/json.hpp" +#include "utils/structs.hpp" + +#include class ScriptCreator : public Screen { @@ -39,13 +42,19 @@ public: ScriptCreator(); private: - void openJson(); - void save(); - + int Selection = 0; + void openJson(std::string fileName); + void save(std::string fileName); + void setInfoStuff(void); void setBool(const std::string &object, const std::string &key, bool v); void setInt(const std::string &object, const std::string &key, int v); void setString(const std::string &object, const std::string &key, const std::string &v); + + std::vector mainButtons = { + {90, 40, 140, 35, -1}, // New Script. + {90, 100, 140, 35, -1}, // Existing Script. + }; }; #endif \ No newline at end of file diff --git a/include/screens/settings.hpp b/include/screens/settings.hpp index 60252d8..73d7cd0 100644 --- a/include/screens/settings.hpp +++ b/include/screens/settings.hpp @@ -39,10 +39,29 @@ public: void Draw(void) const override; void Logic(u32 hDown, u32 hHeld, touchPosition touch) override; private: + // Credits stuff. + int DisplayMode = 1; + int delay = 120; + bool discordText = false; + + int colorMode = 0; + int mode = 0; + int Selection = 0; + + void DrawSubMenu(void) const; void DrawLanguageSelection(void) const; void DrawColorChanging(void) const; + void DrawCreditsScreen(void) const; + void SubMenuLogic(u32 hDown, u32 hHeld, touchPosition touch); void LanguageSelection(u32 hDown, touchPosition touch); void colorChanging(u32 hDown, touchPosition touch); + void CreditsLogic(u32 hDown, touchPosition touch); + + std::vector mainButtons = { + {90, 40, 140, 35, -1}, // Language. + {90, 100, 140, 35, -1}, // Colors. + {90, 160, 140, 35, -1}, // Misc. + }; std::vector langBlocks = { {37, 32, 20, 20, -1}, @@ -63,6 +82,9 @@ private: {220, 85, 95, 41, -1}, }; + std::vector barPos = { + {0, 210, 320, 30, -1}, + }; }; #endif \ No newline at end of file diff --git a/romfs/lang/en/app.json b/romfs/lang/en/app.json index e0baeb2..834c650 100644 --- a/romfs/lang/en/app.json +++ b/romfs/lang/en/app.json @@ -1,15 +1,16 @@ { - "DOWNLOAD_FAILED": "Download Failed!", - "NOT_IMPLEMENTED": "Not Implemented Yet.", - "DONE": "Done!", - "CONNECT_WIFI": "Please Connect to WiFi.", - "DOWNLOADING": "Downloading: ", - "CURRENTLY_EXTRACTING": "\nCurrently extracting:\n", - "KB_DOWNLOADED": "KB downloaded.", - "FILE_EXTRACTED": "file extracted.", - "FILES_EXTRACTED": "files extracted.", + "DOWNLOAD_FAILED": "Download Failed!", + "NOT_IMPLEMENTED": "Not Implemented Yet.", + "DONE": "Done!", + "CONNECT_WIFI": "Please Connect to WiFi.", + "DOWNLOADING": "Downloading: ", + "CURRENTLY_EXTRACTING": "\nCurrently extracting:\n", + "KB_DOWNLOADED": "KB downloaded.", + "FILE_EXTRACTED": "file extracted.", + "FILES_EXTRACTED": "files extracted.", "SCRIPTLIST": "Scriptlist", + "SETTINGS": "Settings", "LANGUAGE": "Language", "COLORS": "Colors", @@ -53,5 +54,18 @@ "B_FTP_EXIT": "Press B to exit from FTP.", "WIFI_NOT_ENABLED": "WiFi not enabled.", - "SCRIPTCREATOR": "Script Creator" + "SCRIPTCREATOR": "Script Creator", + + "CREDITS": "Credits", + "DEVELOPED_BY": "Developed by: Universal-Team.", + "MAIN_DEV": "Main Developer: VoltZ", + "CURRENT_VERSION": "Current version: ", + "MANY_THANKS": "Many Thanks to:", + "TRANSLATORS": "All our Translators", + "HELP_TRANSLATE": "- For helping translate Universal-Updater's strings.", + "HELP_OUT": "- For helping out by Universal-Updater.", + "SCRIPTCREATORS": "All Script Creators", + "CREATING_SCRIPTS": "- For creating Scripts for Universal-Updater.", + "SHOW_QR": "Click here to show the QR Code.", + "LINK": "Join our Discord: https://discord.gg/KDJCfGF" } diff --git a/source/download/download.cpp b/source/download/download.cpp index b109997..ed5486e 100644 --- a/source/download/download.cpp +++ b/source/download/download.cpp @@ -45,7 +45,7 @@ extern "C" { #include "utils/cia.h" } -#define USER_AGENT APP_TITLE "-" V_STRING +#define USER_AGENT APP_TITLE "-" VERSION_STRING static char* result_buf = NULL; static size_t result_sz = 0; diff --git a/source/gui.cpp b/source/gui.cpp index ce0ec7e..6451f5f 100644 --- a/source/gui.cpp +++ b/source/gui.cpp @@ -42,6 +42,7 @@ C3D_RenderTarget* bottom; C2D_TextBuf sizeBuf; std::stack> screens; +C2D_SpriteSheet sprites; bool currentScreen = false; extern bool isScriptSelected; @@ -64,6 +65,7 @@ Result Gui::init(void) C2D_Prepare(); top = C2D_CreateScreenTarget(GFX_TOP, GFX_LEFT); bottom = C2D_CreateScreenTarget(GFX_BOTTOM, GFX_LEFT); + sprites = C2D_SpriteSheetLoad("romfs:/gfx/sprites.t3x"); sizeBuf = C2D_TextBufNew(4096); return 0; } @@ -72,6 +74,7 @@ Result Gui::init(void) void Gui::exit(void) { C2D_TextBufDelete(sizeBuf); + C2D_SpriteSheetFree(sprites); C2D_Fini(); C3D_Fini(); } @@ -91,6 +94,11 @@ void DisplayMsg(std::string text) { C3D_FrameEnd(0); } +void Gui::sprite(int key, int x, int y, float ScaleX, float ScaleY) +{ + C2D_DrawImageAt(C2D_SpriteSheetGetImage(sprites, key), x, y, 0.5f, NULL, ScaleX, ScaleY); +} + void Gui::DisplayWarnMsg(std::string Text) { Gui::clearTextBufs(); diff --git a/source/main.cpp b/source/main.cpp index 7b80fab..908c103 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -53,8 +53,8 @@ bool touching(touchPosition touch, Structs::ButtonPos button) { int main() { gfxInitDefault(); - Gui::init(); romfsInit(); + Gui::init(); sdmcInit(); cfguInit(); acInit(); diff --git a/source/screens/mainMenu.cpp b/source/screens/mainMenu.cpp index c9f59fb..e52c02a 100644 --- a/source/screens/mainMenu.cpp +++ b/source/screens/mainMenu.cpp @@ -36,7 +36,6 @@ #include "utils/config.hpp" -extern int mode; extern bool exiting; extern bool touching(touchPosition touch, Structs::ButtonPos button); extern bool checkWifiStatus(void); @@ -47,7 +46,7 @@ bool isTesting = false; void MainMenu::Draw(void) const { Gui::DrawTop(); Gui::DrawStringCentered(0, 2, 0.7f, Config::TxtColor, "Universal-Updater", 400); - Gui::DrawString(397-Gui::GetStringWidth(0.5f, VERSION_STRING), 237-Gui::GetStringHeight(0.5f, VERSION_STRING), 0.5f, Config::TxtColor, VERSION_STRING); + Gui::DrawString(397-Gui::GetStringWidth(0.5f, V_STRING), 237-Gui::GetStringHeight(0.5f, V_STRING), 0.5f, Config::TxtColor, V_STRING); Gui::DrawBottom(); for (int i = 0; i < 6; i++) { @@ -62,8 +61,8 @@ void MainMenu::Draw(void) const { Gui::DrawString((320-Gui::GetStringWidth(0.6f, Lang::get("GET_SCRIPTS")))/2+150-70, mainButtons[1].y+10, 0.6f, Config::TxtColor, Lang::get("GET_SCRIPTS"), 140); Gui::DrawString((320-Gui::GetStringWidth(0.6f, "TinyDB"))/2-150+70, mainButtons[2].y+10, 0.6f, Config::TxtColor, "TinyDB", 140); Gui::DrawString((320-Gui::GetStringWidth(0.6f, Lang::get("SCRIPTCREATOR")))/2+150-70, mainButtons[3].y+10, 0.6f, Config::TxtColor, Lang::get("SCRIPTCREATOR"), 140); - Gui::DrawString((320-Gui::GetStringWidth(0.6f, Lang::get("LANGUAGE")))/2-150+70, mainButtons[4].y+10, 0.6f, Config::TxtColor, Lang::get("LANGUAGE"), 140); - Gui::DrawString((320-Gui::GetStringWidth(0.6f, Lang::get("COLORS")))/2+150-70, mainButtons[5].y+10, 0.6f, Config::TxtColor, Lang::get("COLORS"), 140); + Gui::DrawString((320-Gui::GetStringWidth(0.6f, Lang::get("SETTINGS")))/2-150+70, mainButtons[4].y+10, 0.6f, Config::TxtColor, Lang::get("SETTINGS"), 140); + Gui::DrawString((320-Gui::GetStringWidth(0.6f, "FTP"))/2+150-70, mainButtons[5].y+10, 0.6f, Config::TxtColor, "FTP", 140); } void MainMenu::Logic(u32 hDown, u32 hHeld, touchPosition touch) { @@ -108,12 +107,12 @@ void MainMenu::Logic(u32 hDown, u32 hHeld, touchPosition touch) { } break; case 4: - mode = 0; Gui::setScreen(std::make_unique()); break; case 5: - mode = 1; - Gui::setScreen(std::make_unique()); + if (checkWifiStatus() == true) { + Gui::setScreen(std::make_unique()); + } break; } } @@ -141,11 +140,11 @@ void MainMenu::Logic(u32 hDown, u32 hHeld, touchPosition touch) { Gui::setScreen(std::make_unique()); } } else if (touching(touch, mainButtons[4])) { - mode = 0; Gui::setScreen(std::make_unique()); } else if (touching(touch, mainButtons[5])) { - mode = 1; - Gui::setScreen(std::make_unique()); + if (checkWifiStatus() == true) { + Gui::setScreen(std::make_unique()); + } } } } \ No newline at end of file diff --git a/source/screens/scriptCreator.cpp b/source/screens/scriptCreator.cpp index 0ebeda0..182c193 100644 --- a/source/screens/scriptCreator.cpp +++ b/source/screens/scriptCreator.cpp @@ -33,8 +33,9 @@ // The to editing script. nlohmann::json editScript; -void ScriptCreator::openJson() { - FILE* file = fopen("sdmc:/3ds/Universal-Updater/Test.json", "r"); +void ScriptCreator::openJson(std::string fileName) { + std::string scriptFile = Config::ScriptPath + fileName; + FILE* file = fopen(scriptFile.c_str(), "r"); if(file) editScript = nlohmann::json::parse(file, nullptr, false); fclose(file); } @@ -55,37 +56,66 @@ void ScriptCreator::Draw(void) const { Gui::DrawTop(); Gui::DrawStringCentered(0, 2, 0.7f, Config::TxtColor, Lang::get("SCRIPTCREATOR"), 400); Gui::DrawBottom(); + + for (int i = 0; i < 2; i++) { + if (Selection == i) { + Gui::Draw_Rect(mainButtons[i].x, mainButtons[i].y, mainButtons[i].w, mainButtons[i].h, Config::SelectedColor); + } else { + Gui::Draw_Rect(mainButtons[i].x, mainButtons[i].y, mainButtons[i].w, mainButtons[i].h, Config::UnselectedColor); + } + } + + Gui::DrawString((320-Gui::GetStringWidth(0.6f, Lang::get("NEW_SCRIPT")))/2, mainButtons[0].y+10, 0.6f, Config::TxtColor, Lang::get("NEW_SCRIPT"), 140); + Gui::DrawString((320-Gui::GetStringWidth(0.6f, Lang::get("EXISTING_SCRIPT")))/2, mainButtons[1].y+10, 0.6f, Config::TxtColor, Lang::get("EXISTING_SCRIPT"), 140); } // Testing purpose for now. ScriptCreator::ScriptCreator() { - openJson(); + openJson("Test.json"); } -void ScriptCreator::save() { - FILE* file = fopen("sdmc:/3ds/Universal-Updater/Test.json", "w"); +void ScriptCreator::save(std::string fileName) { + std::string scriptFile = Config::ScriptPath + fileName; + FILE* file = fopen(scriptFile.c_str(), "w"); if(file) fwrite(editScript.dump(1, '\t').c_str(), 1, editScript.dump(1, '\t').size(), file); fclose(file); } +// Importaant to make Scripts valid. +void ScriptCreator::setInfoStuff(void) { + // Get needed things. + const std::string &test = Input::getString("Enter the Title of the script.", 50); + const std::string &test2 = Input::getString("Enter the Author name of the script.", 50); + const std::string &test3 = Input::getString("Enter the short description of the script.", 80); + const std::string &test4 = Input::getString("Enter the long description of the script.", 300); + int scriptRevision = Input::getUint(99, "Enter the script revision."); + // Set the real JSON stuff. + setString("info", "title", test); + setString("info", "author", test2); + setString("info", "shortDesc", test3); + setString("info", "description", test4); + setInt("info", "version", 2); + setInt("info", "revision", scriptRevision); +} + + + void ScriptCreator::Logic(u32 hDown, u32 hHeld, touchPosition touch) { if (hDown & KEY_B) { - save(); + save("Test.json"); Gui::screenBack(); return; } - if (hDown & KEY_X) { - const std::string &test = Input::getString("Enter the Title of the Script.", 50); - const std::string &test2 = Input::getString("Enter the Author name of the Script.", 50); - const std::string &test3 = Input::getString("Enter the short description of the Script.", 80); - const std::string &test4 = Input::getString("Enter the long description of the Script.", 300); + if (hDown & KEY_UP) { + if(Selection == 1) Selection = 0; + } - setString("info", "title", test); - setString("info", "author", test2); - setString("info", "shortDesc", test3); - setString("info", "description", test4); - setInt("info", "version", 2); - setInt("info", "revision", 1); + if (hDown & KEY_DOWN) { + if(Selection == 0) Selection = 1; + } + + if (hDown & KEY_X) { + setInfoStuff(); } } \ No newline at end of file diff --git a/source/screens/settings.cpp b/source/screens/settings.cpp index 7eda1e8..8887f0c 100644 --- a/source/screens/settings.cpp +++ b/source/screens/settings.cpp @@ -32,17 +32,37 @@ extern bool touching(touchPosition touch, Structs::ButtonPos button); -int mode; -int colorMode = 0; - void Settings::Draw(void) const { if (mode == 0) { - DrawLanguageSelection(); + DrawSubMenu(); } else if (mode == 1) { + DrawLanguageSelection(); + } else if (mode == 2) { DrawColorChanging(); + } else if (mode == 3) { + DrawCreditsScreen(); } } + +void Settings::DrawSubMenu(void) const { + Gui::DrawTop(); + Gui::DrawString((400-Gui::GetStringWidth(0.8f, "Universal-Updater"))/2, 2, 0.8f, Config::TxtColor, "Universal-Updater", 400); + Gui::DrawBottom(); + + for (int i = 0; i < 3; i++) { + if (Selection == i) { + Gui::Draw_Rect(mainButtons[i].x, mainButtons[i].y, mainButtons[i].w, mainButtons[i].h, Config::SelectedColor); + } else { + Gui::Draw_Rect(mainButtons[i].x, mainButtons[i].y, mainButtons[i].w, mainButtons[i].h, Config::UnselectedColor); + } + } + + Gui::DrawString((320-Gui::GetStringWidth(0.6f, Lang::get("LANGUAGE")))/2, mainButtons[0].y+10, 0.6f, Config::TxtColor, Lang::get("LANGUAGE"), 140); + Gui::DrawString((320-Gui::GetStringWidth(0.6f, Lang::get("COLORS")))/2, mainButtons[1].y+10, 0.6f, Config::TxtColor, Lang::get("COLORS"), 140); + Gui::DrawString((320-Gui::GetStringWidth(0.6f, Lang::get("CREDITS")))/2, mainButtons[2].y+10, 0.6f, Config::TxtColor, Lang::get("CREDITS"), 140); +} + void Settings::DrawLanguageSelection(void) const { Gui::DrawTop(); Gui::DrawString((400-Gui::GetStringWidth(0.8f, Lang::get("SELECT_LANG")))/2, 2, 0.8f, Config::TxtColor, Lang::get("SELECT_LANG"), 400); @@ -138,6 +158,77 @@ void Settings::DrawColorChanging(void) const { } } +void Settings::DrawCreditsScreen(void) const { + if (DisplayMode == 1) { + Gui::DrawTop(); + std::string title = "Universal-Updater - "; + title += Lang::get("CREDITS"); + + Gui::DrawString((400-Gui::GetStringWidth(0.8f, title.c_str()))/2, 2, 0.8f, Config::TxtColor, title.c_str(), 400); + Gui::DrawString((400-Gui::GetStringWidth(0.8f, Lang::get("DEVELOPED_BY")))/2, 40, 0.8f, Config::TxtColor, Lang::get("DEVELOPED_BY"), 400); + Gui::DrawString((400-Gui::GetStringWidth(0.8f, Lang::get("MAIN_DEV")))/2, 70, 0.8f, Config::TxtColor, Lang::get("MAIN_DEV"), 400); + Gui::sprite(sprites_voltZ_idx, 150, 110); + std::string currentVersion = Lang::get("CURRENT_VERSION"); + currentVersion += V_STRING; + Gui::DrawString(395-Gui::GetStringWidth(0.72f, currentVersion), 215, 0.72f, Config::TxtColor, currentVersion, 400); + Gui::DrawBottom(); + Gui::DrawString((320-Gui::GetStringWidth(0.7f, Lang::get("MANY_THANKS")))/2, 2, 0.8f, Config::TxtColor, Lang::get("MANY_THANKS"), 320); + Gui::DrawString((320-Gui::GetStringWidth(0.7f, Lang::get("TRANSLATORS")))/2, 40, 0.7f, Config::TxtColor, Lang::get("TRANSLATORS"), 320); + Gui::DrawString((320-Gui::GetStringWidth(0.5f, Lang::get("HELP_TRANSLATE")))/2, 70, 0.5f, Config::TxtColor, Lang::get("HELP_TRANSLATE"), 320); + Gui::DrawString((320-Gui::GetStringWidth(0.7f, "Pk11"))/2, 100, 0.7f, Config::TxtColor, "Pk11", 320); + Gui::DrawString((320-Gui::GetStringWidth(0.5f, Lang::get("HELP_OUT")))/2, 130, 0.5f, Config::TxtColor, Lang::get("HELP_OUT"), 320); + Gui::DrawString((320-Gui::GetStringWidth(0.7f, Lang::get("SCRIPTCREATORS")))/2, 160, 0.7f, Config::TxtColor, Lang::get("SCRIPTCREATORS"), 320); + Gui::DrawString((320-Gui::GetStringWidth(0.5f, Lang::get("CREATING_SCRIPTS")))/2, 190, 0.5f, Config::TxtColor, Lang::get("CREATING_SCRIPTS"), 320); + Gui::DrawString((320-Gui::GetStringWidth(0.55, discordText ? Lang::get("SHOW_QR") : Lang::get("LINK")))/2, 217, 0.55, Config::TxtColor, discordText ? Lang::get("SHOW_QR") : Lang::get("LINK"), 320); + } else if (DisplayMode == 2) { + Gui::DrawTop(); + Gui::Draw_Rect(0, 0, 400, 240, C2D_Color32(0, 0, 0, 190)); + Gui::sprite(sprites_discord_idx, 115, 35); + Gui::DrawBottom(); + Gui::Draw_Rect(0, 0, 320, 240, C2D_Color32(0, 0, 0, 190)); + } +} + + +void Settings::SubMenuLogic(u32 hDown, u32 hHeld, touchPosition touch) { + if (hDown & KEY_UP) { + if(Selection > 0) Selection--; + } + + if (hDown & KEY_DOWN) { + if(Selection < 2) Selection++; + } + + if (hDown & KEY_A) { + switch(Selection) { + case 0: + mode = 1; + break; + case 1: + mode = 2; + break; + case 2: + mode = 3; + break; + } + } + + if (hDown & KEY_TOUCH) { + if (touching(touch, mainButtons[0])) { + mode = 1; + } else if (touching(touch, mainButtons[1])) { + mode = 2; + } else if (touching(touch, mainButtons[2])) { + mode = 3; + } + } + + if (hDown & KEY_B) { + Gui::screenBack(); + return; + } +} + void Settings::LanguageSelection(u32 hDown, touchPosition touch) { if (hDown & KEY_TOUCH) { for (int language = 0; language < 10; language++) { @@ -150,11 +241,11 @@ void Settings::LanguageSelection(u32 hDown, touchPosition touch) { } if (hDown & KEY_B) { - Gui::screenBack(); - return; + mode = 0; } } + void Settings::colorChanging(u32 hDown, touchPosition touch) { int red; int green; @@ -162,8 +253,7 @@ void Settings::colorChanging(u32 hDown, touchPosition touch) { if (hDown & KEY_B) { Config::save(); - Gui::screenBack(); - return; + mode = 0; } if (hDown & KEY_L || hDown & KEY_LEFT) { @@ -235,11 +325,38 @@ void Settings::colorChanging(u32 hDown, touchPosition touch) { } } +void Settings::CreditsLogic(u32 hDown, touchPosition touch) { + gspWaitForVBlank(); + if(delay > 0) { + delay--; + } else { + delay = 120; + discordText = !discordText; + } + if (DisplayMode == 1) { + if (hDown & KEY_TOUCH) { + if (touching(touch, barPos[0])) { + DisplayMode = 2; + } + } + if (hDown & KEY_B) { + mode = 0; + } + } else if (DisplayMode == 2) { + if (hDown & KEY_B) { + DisplayMode = 1; + } + } +} void Settings::Logic(u32 hDown, u32 hHeld, touchPosition touch) { if (mode == 0) { - LanguageSelection(hDown, touch); + SubMenuLogic(hDown, hHeld, touch); } else if (mode == 1) { + LanguageSelection(hDown, touch); + } else if (mode == 2) { colorChanging(hDown, touch); + } else if (mode == 3) { + CreditsLogic(hDown, touch); } } \ No newline at end of file