From 4ad2ee55175a6b25d3baf5279ae52871584be197 Mon Sep 17 00:00:00 2001 From: StackZ <47382115+SuperSaiyajinStackZ@users.noreply.github.com> Date: Wed, 5 Feb 2020 13:32:47 +0100 Subject: [PATCH] Add Initial GUI core. --- README.md | 7 +- gui.cpp | 228 +++++++++++++++++++++++++++++++++++++++++++++++ gui.hpp | 100 +++++++++++++++++++++ screen.hpp | 42 +++++++++ screenCommon.hpp | 35 ++++++++ 5 files changed, 410 insertions(+), 2 deletions(-) create mode 100644 gui.cpp create mode 100644 gui.hpp create mode 100644 screen.hpp create mode 100644 screenCommon.hpp diff --git a/README.md b/README.md index fe86fe4..ef9e08e 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,5 @@ -# Universal-Core -GUI and Core part from Universal-Team. +# Universal-Core by Universal-Team +This contains the GUI & Core part for our 3DS Applications. + +Licensing: +This software is licensed under the terms of the GPLv3. You can find a copy of the license in the LICENSE file. \ No newline at end of file diff --git a/gui.cpp b/gui.cpp new file mode 100644 index 0000000..8633275 --- /dev/null +++ b/gui.cpp @@ -0,0 +1,228 @@ +/* +* This file is part of Universal-Core +* Copyright (C) 2020 DeadPhoenix8091, Epicpkmn11, Flame, RocketRobz, StackZ, 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 "screenCommon.hpp" + +#include <3ds.h> + +C3D_RenderTarget* Top; +C3D_RenderTarget* Bottom; + +C2D_TextBuf TextBuf; +C2D_Font Font; +std::stack> screens; +bool currentScreen = false; + +// Clear Text. +void Gui::clearTextBufs(void) +{ + C2D_TextBufClear(TextBuf); +} + +// Draw a sprite from the sheet. +void Gui::DrawSprite(C2D_SpriteSheet sheet, size_t imgindex, int x, int y, float ScaleX, float ScaleY) +{ + C2D_Image img = C2D_SpriteSheetGetImage(sheet, imgindex); + C2D_DrawImageAt(img, x, y, 0.5f, NULL, ScaleX, ScaleY); +} + +// Initialize GUI. +Result Gui::init(void) +{ + C3D_Init(C3D_DEFAULT_CMDBUF_SIZE); + C2D_Init(C2D_DEFAULT_MAX_OBJECTS); + C2D_Prepare(); + // Create Screen Targets. + Top = C2D_CreateScreenTarget(GFX_TOP, GFX_LEFT); + Bottom = C2D_CreateScreenTarget(GFX_BOTTOM, GFX_LEFT); + // Load Textbuffer. + TextBuf = C2D_TextBufNew(4096); + return 0; +} + +// Load a Font. +Result Gui::loadFont(bool sysFont, const char* Path) { + if (sysFont) Font = C2D_FontLoadSystem(CFG_REGION_USA); + else Font = C2D_FontLoad(Path); + return 0; +} + +// Unload a Font. +Result Gui::unloadFont() { + C2D_FontFree(Font); + return 0; +} + +// Load a Sheet. +Result Gui::loadSheet(const char* Path, C2D_SpriteSheet &sheet) { + sheet = C2D_SpriteSheetLoad(Path); + return 0; +} + +// Unload a Sheet. +Result Gui::unloadSheet(C2D_SpriteSheet &sheet) { + C2D_SpriteSheetFree(sheet); + return 0; +} + +// Exit the GUI. +void Gui::exit(void) +{ + C2D_TextBufDelete(TextBuf); + C2D_Fini(); + C3D_Fini(); +} + +void Gui::DrawStringCentered(float x, float y, float size, u32 color, std::string Text, int maxWidth, int maxHeight) { + float lineHeight, widthScale; + lineHeight = Gui::GetStringHeight(size, " "); + int line = 0; + while(Text.find('\n') != Text.npos) { + if(maxWidth == 0) { + widthScale = Gui::GetStringWidth(size, Text.substr(0, Text.find('\n'))); + } else { + widthScale = std::min((float)maxWidth, Gui::GetStringWidth(size, Text.substr(0, Text.find('\n')))); + } + Gui::DrawString((currentScreen ? 200 : 160)+x-(widthScale/2), y+(lineHeight*line), size, color, Text.substr(0, Text.find('\n')), maxWidth, maxHeight); + Text = Text.substr(Text.find('\n')+1); + line++; + } + if(maxWidth == 0) { + widthScale = Gui::GetStringWidth(size, Text.substr(0, Text.find('\n'))); + } else { + widthScale = std::min((float)maxWidth, Gui::GetStringWidth(size, Text.substr(0, Text.find('\n')))); + } + Gui::DrawString((currentScreen ? 200 : 160)+x-(widthScale/2), y+(lineHeight*line), size, color, Text.substr(0, Text.find('\n')), maxWidth, maxHeight); +} + +// Draw String or Text. +void Gui::DrawString(float x, float y, float size, u32 color, std::string Text, int maxWidth, int maxHeight) { + C2D_Text c2d_text; + C2D_TextFontParse(&c2d_text, Font, TextBuf, Text.c_str()); + C2D_TextOptimize(&c2d_text); + + float heightScale; + if(maxHeight == 0) { + heightScale = size; + } else { + heightScale = std::min(size, size*(maxHeight/Gui::GetStringHeight(size, Text))); + } + + if(maxWidth == 0) { + C2D_DrawText(&c2d_text, C2D_WithColor, x, y, 0.5f, size, heightScale, color); + } else { + C2D_DrawText(&c2d_text, C2D_WithColor, x, y, 0.5f, std::min(size, size*(maxWidth/Gui::GetStringWidth(size, Text))), heightScale, color); + } +} + + +// Get String or Text Width. +float Gui::GetStringWidth(float size, std::string Text) { + float width = 0; + GetStringSize(size, &width, NULL, Text); + return width; +} + +// Get String or Text Size. +void Gui::GetStringSize(float size, float *width, float *height, std::string Text) { + C2D_Text c2d_text; + C2D_TextFontParse(&c2d_text, Font, TextBuf, Text.c_str()); + C2D_TextGetDimensions(&c2d_text, size, size, width, height); +} + + +// Get String or Text Height. +float Gui::GetStringHeight(float size, std::string Text) { + float height = 0; + GetStringSize(size, NULL, &height, Text.c_str()); + return height; +} + +// Draw a Rectangle. +bool Gui::Draw_Rect(float x, float y, float w, float h, u32 color) { + return C2D_DrawRectSolid(x, y, 0.5f, w, h, color); +} + +// Mainloop the GUI. +void Gui::mainLoop(u32 hDown, u32 hHeld, touchPosition touch) { + screens.top()->Draw(); + screens.top()->Logic(hDown, hHeld, touch); +} + +// Set the current Screen. +void Gui::setScreen(std::unique_ptr screen) +{ + screens.push(std::move(screen)); +} + +// Go a Screen back. +void Gui::screenBack() +{ + screens.pop(); +} + +// Select, on which Screen should be drawn. +void Gui::ScreenDraw(C3D_RenderTarget * screen) +{ + C2D_SceneBegin(screen); + currentScreen = screen == Top ? 1 : 0; +} + +void Gui::drawGrid(float xPos, float yPos, float Width, float Height, u32 color) +{ + static constexpr int w = 1; + // BG Color for the Grid. (Transparent.) + C2D_DrawRectSolid(xPos, yPos, 0.5, Width, Height, C2D_Color32(0, 0, 0, 0)); + + // Grid part. + C2D_DrawRectSolid(xPos, yPos, 0.5, Width, w, color); // top + C2D_DrawRectSolid(xPos, yPos + w, 0.5, w, Height - 2 * w, color); // left + C2D_DrawRectSolid(xPos + Width - w, yPos + w, 0.5, w, Height - 2 * w, color); // right + C2D_DrawRectSolid(xPos, yPos + Height - w, 0.5, Width, w, color); // bottom +} + +void Gui::drawAnimatedSelector(float xPos, float yPos, float Width, float Height, float speed, u32 SelectorColor, u32 colour) +{ + static constexpr int w = 2; + static float timer = 0.0f; + float highlight_multiplier = fmax(0.0, fabs(fmod(timer, 1.0) - 0.5) / 0.5); + u8 r = SelectorColor & 0xFF; + u8 g = (SelectorColor >> 8) & 0xFF; + u8 b = (SelectorColor >> 16) & 0xFF; + u32 color = C2D_Color32(r + (255 - r) * highlight_multiplier, g + (255 - g) * highlight_multiplier, b + (255 - b) * highlight_multiplier, 255); + + // BG Color for the Selector. + C2D_DrawRectSolid(xPos, yPos, 0.5, Width, Height, colour); + + // Animated Selector part. + C2D_DrawRectSolid(xPos, yPos, 0.5, Width, w, color); // top + C2D_DrawRectSolid(xPos, yPos + w, 0.5, w, Height - 2 * w, color); // left + C2D_DrawRectSolid(xPos + Width - w, yPos + w, 0.5, w, Height - 2 * w, color); // right + C2D_DrawRectSolid(xPos, yPos + Height - w, 0.5, Width, w, color); // bottom + + timer += speed; // Speed of the animation. Example : .030f / .030 +} \ No newline at end of file diff --git a/gui.hpp b/gui.hpp new file mode 100644 index 0000000..866b381 --- /dev/null +++ b/gui.hpp @@ -0,0 +1,100 @@ +/* +* This file is part of Universal-Core +* Copyright (C) 2020 DeadPhoenix8091, Epicpkmn11, Flame, RocketRobz, StackZ, 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 "screen.hpp" + +#include <3ds.h> +#include +#include +#include + +namespace Gui +{ + // Clear Text Buffer. + void clearTextBufs(void); + + // Draw a sprite from a sheet. + void DrawSprite(C2D_SpriteSheet sheet, size_t imgindex, int x, int y, float ScaleX = 1, float ScaleY = 1); + + // Initialize the GUI with Citro2D & Citro3D and initialize the Textbuffer. + Result init(void); + + // Load a Font. (bcfnt) + Result loadFont(bool sysFont = true, const char * Path = ""); + + // Unload a Font. (bcfnt) + Result unloadFont(); + + // Load a spritesheet. + Result loadSheet(const char* Path, C2D_SpriteSheet &sheet); + + // Unload a spritesheet. + Result unloadSheet(C2D_SpriteSheet &sheet); + + // Exit the GUI. + void exit(void); + + // Draw a centered String. + void DrawStringCentered(float x, float y, float size, u32 color, std::string Text, int maxWidth = 0, int maxHeight = 0); + + // Draw a String. + void DrawString(float x, float y, float size, u32 color, std::string Text, int maxWidth = 0, int maxHeight = 0); + + // Get the width of a String. + float GetStringWidth(float size, std::string Text); + + // Get the size of a String. + void GetStringSize(float size, float *width, float *height, std::string Text); + + // Get the height of a String. + float GetStringHeight(float size, std::string Text); + + // Draw a Rectangle. + bool Draw_Rect(float x, float y, float w, float h, u32 color); + + // Mainloop the GUI / Screen part. + void mainLoop(u32 hDown, u32 hHeld, touchPosition touch); + + // Set a specific Screen. + void setScreen(std::unique_ptr screen); + + // Go a Screen back. + void screenBack(); + + // Set on which screen to draw. + void ScreenDraw(C3D_RenderTarget * screen); + + // Draw a grid. + void drawGrid(float xPos, float yPos, float Width, float Height, u32 color); + + // Draw an animated selector. + void drawAnimatedSelector(float xPos, float yPos, float Width, float Height, float speed, u32 SelectorColor, u32 colour); +} + +#endif \ No newline at end of file diff --git a/screen.hpp b/screen.hpp new file mode 100644 index 0000000..f035c83 --- /dev/null +++ b/screen.hpp @@ -0,0 +1,42 @@ +/* +* This file is part of Universal-Core +* Copyright (C) 2020 DeadPhoenix8091, Epicpkmn11, Flame, RocketRobz, StackZ, 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 SCREEN_HPP +#define SCREEN_HPP + +#include <3ds.h> +#include + +class Screen +{ +public: + virtual ~Screen() {} + virtual void Logic(u32 hDown, u32 hHeld, touchPosition touch) = 0; + virtual void Draw() const = 0; +private: +}; + +#endif \ No newline at end of file diff --git a/screenCommon.hpp b/screenCommon.hpp new file mode 100644 index 0000000..b05954e --- /dev/null +++ b/screenCommon.hpp @@ -0,0 +1,35 @@ +/* +* This file is part of Universal-Core +* Copyright (C) 2020 DeadPhoenix8091, Epicpkmn11, Flame, RocketRobz, StackZ, 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 SCREENCOMMON_HPP +#define SCREENCOMMON_HPP + +#include "gui.hpp" + +extern C3D_RenderTarget* Top; +extern C3D_RenderTarget* Bottom; + +#endif \ No newline at end of file