diff --git a/client/src/Pages/MainMenu/MainMenu.cpp b/client/src/Pages/MainMenu/MainMenu.cpp index 70cc067..34fbab1 100644 --- a/client/src/Pages/MainMenu/MainMenu.cpp +++ b/client/src/Pages/MainMenu/MainMenu.cpp @@ -4,6 +4,7 @@ #include #include "Rendering/RenderWindow/RenderWindow.hpp" +#include "Rendering/Graphics/Graphics.hpp" #include "Utilities/Sound/Sound.h" #include "Utilities/Helpers/Helpers.hpp" @@ -15,13 +16,16 @@ const std::string clockFormat = "%X"; MainMenuPage::MainMenuPage(RenderWindow *p_window, Server *p_api) : window(p_window), api(p_api) { SDL_Texture *wallpaper = window->loadTexture("res/images/wallpaper.jpg"); wallpaperEntity = Entity( - MultiSize(Size(0, SIZE_WIDTH), Size(0, SIZE_HEIGHT), Size(100, SIZE_WIDTH), Size(100, SIZE_HEIGHT)), + MultiSize(Size(0, WW), Size(0, WH), Size(100, WW), Size(100, WH)), wallpaper); gameBorder = window->loadTexture("res/images/game.png"); scrollSound = createAudio("res/sounds/scroll.wav", 0, SDL_MIX_MAXVOLUME); enterSound = createAudio("res/sounds/enter.wav", 0, SDL_MIX_MAXVOLUME); + roundedRect = Graphics::RoundedRectangle{MultiSize(Size(10, WW), Size(10, WW), Size(10, WW), Size(10, WW)), + Size(.5, WW)}; + this->readGameStyles(); this->requestSteamGamesFromServer(); this->setGameTitleFont(); @@ -43,14 +47,15 @@ void MainMenuPage::render(double deltaTime) { window->render(gameTitle); window->render(clockText); + window->render(roundedRect); + for (Entity &game: gameEntities) { game.animate(deltaTime); window->render(game); } } -void MainMenuPage::cleanUp() { - +MainMenuPage::~MainMenuPage() { freeAudio(scrollSound); TTF_CloseFont(gameTitleFont); @@ -146,14 +151,14 @@ void MainMenuPage::setGameTitleFont() { } gameTitle.setFontScale(gameTitleFontScale); gameTitle.setRenderMethod(Text::RenderMethod::Blended); - gameTitle.setPosition(Size(gameTitleX, SIZE_WIDTH), Size(gameTitleY, SIZE_HEIGHT)); + gameTitle.setPosition(Size(gameTitleX, WW), Size(gameTitleY, WH)); clockText.setFont(clockTextFont); clockText.setColor(SDL_Color{255, 255, 255, 255}); clockText.setText(utils::currentDateTime(clockFormat)); clockText.setFontScale(clockTextFontScale); clockText.setRenderMethod(Text::RenderMethod::Blended); - clockText.setPosition(Size(clockTextX, SIZE_WIDTH), Size(clockTextY, SIZE_HEIGHT)); + clockText.setPosition(Size(clockTextX, WW), Size(clockTextY, WH)); }; @@ -177,17 +182,17 @@ void MainMenuPage::animateGames() { } gameEntities[i].setAnimation( - MultiSize(Size(newX, SIZE_HEIGHT), Size(newY, SIZE_HEIGHT), Size(newW, SIZE_HEIGHT), - Size(newH, SIZE_HEIGHT)), isSpamming ? spamTransitionTime : normalTransitionTime); + MultiSize(Size(newX, WH), Size(newY, WH), Size(newW, WH), + Size(newH, WH)), isSpamming ? spamTransitionTime : normalTransitionTime); } }; void MainMenuPage::createGameEntity(int i) { const MultiSize normalGameDims( - Size(i * (gameSizeNormal + (marginBetweenGames * 2) + selectedGameOffset) + gameOffset, SIZE_HEIGHT), - Size(normalY, SIZE_HEIGHT), Size(gameSizeNormal, SIZE_HEIGHT), Size(gameSizeNormal, SIZE_HEIGHT)); - const MultiSize selectedGameDims(Size(gameOffset - selectedGameOffset, SIZE_HEIGHT), Size(normalY, SIZE_HEIGHT), - Size(gameSizeSelected, SIZE_HEIGHT), Size(gameSizeSelected, SIZE_HEIGHT)); + Size(i * (gameSizeNormal + (marginBetweenGames * 2) + selectedGameOffset) + gameOffset, WH), + Size(normalY, WH), Size(gameSizeNormal, WH), Size(gameSizeNormal, WH)); + const MultiSize selectedGameDims(Size(gameOffset - selectedGameOffset, WH), Size(normalY, WH), + Size(gameSizeSelected, WH), Size(gameSizeSelected, WH)); Entity anotherGame(i == 0 ? selectedGameDims : normalGameDims, gameBorder); diff --git a/client/src/Pages/MainMenu/MainMenu.hpp b/client/src/Pages/MainMenu/MainMenu.hpp index 6cee828..f70e015 100644 --- a/client/src/Pages/MainMenu/MainMenu.hpp +++ b/client/src/Pages/MainMenu/MainMenu.hpp @@ -23,6 +23,8 @@ class MainMenuPage { public: MainMenuPage(RenderWindow *p_window, Server *p_api); + ~MainMenuPage(); + void render(double deltaTime); void executeKeyboardEvent(KeyboardController *keyboard_controller); @@ -74,6 +76,7 @@ class MainMenuPage { Audio *scrollSound = NULL, *enterSound = NULL; std::string clockFontFamilyName; float clockTextFontSize, clockTextFontScale, clockTextX, clockTextY; + Graphics::RoundedRectangle roundedRect; struct game { std::string name; diff --git a/client/src/Rendering/Graphics/Graphics.cpp b/client/src/Rendering/Graphics/Graphics.cpp new file mode 100644 index 0000000..fd1a537 --- /dev/null +++ b/client/src/Rendering/Graphics/Graphics.cpp @@ -0,0 +1,84 @@ +// +// Created by Ted on 11/26/2021. +// + +#include +#include "Graphics.hpp" + +#include "Utilities/Math/Math.hpp" + +// TY Kind stranger! (https://stackoverflow.com/questions/38334081/howto-draw-circles-arcs-and-vector-graphics-in-sdl) +// +// draw one quadrant arc, and mirror the other 4 quadrants +void Graphics::drawEllipse(SDL_Renderer *r, int x0, int y0, int radiusX, int radiusY, + Graphics::corner type) { + float pi = 3.14159265358979323846264338327950288419716939937510; + float pih = pi / 2.0; //half of pi + + //drew 28 lines with 4x4 circle with precision of 150 0ms + //drew 132 lines with 25x14 circle with precision of 150 0ms + //drew 152 lines with 100x50 circle with precision of 150 3ms + const int prec = 42; // precision value; value of 1 will draw a diamond, 27 makes pretty smooth circles. + float theta = 0; // angle that will be increased each loop + + //starting point + int x = (float) radiusX * cos(theta);//start point + int y = (float) radiusY * sin(theta);//start point + int x1 = x; + int y1 = y; + + //repeat until theta >= 90; + float step = pih / (float) prec; // amount to add to theta each time (degrees) + for (theta = step; theta <= pih; theta += step)//step through only a 90 arc (1 quadrant) + { + //get new point location + x1 = (float) radiusX * cosf(theta) + 0.5; //new point (+.5 is a quick rounding method) + y1 = (float) radiusY * sinf(theta) + 0.5; //new point (+.5 is a quick rounding method) + + //draw line from previous point to new point, ONLY if point incremented + if ((x != x1) || (y != y1))//only draw if coordinate changed + { + switch (type) { + case Graphics::all: + SDL_RenderDrawLine(r, x0 + x, y0 - y, x0 + x1, y0 - y1);//quadrant TR + SDL_RenderDrawLine(r, x0 - x, y0 - y, x0 - x1, y0 - y1);//quadrant TL + SDL_RenderDrawLine(r, x0 - x, y0 + y, x0 - x1, y0 + y1);//quadrant BL + SDL_RenderDrawLine(r, x0 + x, y0 + y, x0 + x1, y0 + y1);//quadrant BR + break; + case Graphics::topLeft: + SDL_RenderDrawLine(r, x0 - x, y0 - y, x0 - x1, y0 - y1);//quadrant TL + break; + case Graphics::topRight: + SDL_RenderDrawLine(r, x0 + x, y0 - y, x0 + x1, y0 - y1);//quadrant TR + break; + case Graphics::bottomLeft: + SDL_RenderDrawLine(r, x0 - x, y0 + y, x0 - x1, y0 + y1);//quadrant BL + break; + case Graphics::bottomRight: + SDL_RenderDrawLine(r, x0 + x, y0 + y, x0 + x1, y0 + y1);//quadrant BR + break; + + } + + } + //save previous points + x = x1;//save new previous point + y = y1;//save new previous point + } + //arc did not finish because of rounding, so finish the arc + if (x != 0) { + x = 0; + SDL_RenderDrawLine(r, x0 + x, y0 - y, x0 + x1, y0 - y1);//quadrant TR + SDL_RenderDrawLine(r, x0 - x, y0 - y, x0 - x1, y0 - y1);//quadrant TL + SDL_RenderDrawLine(r, x0 - x, y0 + y, x0 - x1, y0 + y1);//quadrant BL + SDL_RenderDrawLine(r, x0 + x, y0 + y, x0 + x1, y0 + y1);//quadrant BR + } +} + +void Graphics::drawLine(SDL_Renderer *r, int x1, int y1, int x2, int y2) { + SDL_RenderDrawLine(r, x1, y1, x2, y2); +} + +void Graphics::setColor(SDL_Renderer *renderer, Uint8 r, Uint8 g, Uint8 b, Uint8 a) { + SDL_SetRenderDrawColor(renderer, r, g, b, a); +} diff --git a/client/src/Rendering/Graphics/Graphics.hpp b/client/src/Rendering/Graphics/Graphics.hpp new file mode 100644 index 0000000..3c7bd32 --- /dev/null +++ b/client/src/Rendering/Graphics/Graphics.hpp @@ -0,0 +1,33 @@ +// +// Created by Ted on 11/26/2021. +// +#include "Utilities/Math/Math.hpp" + +#ifndef AURORA_GRAPHICS_HPP +#define AURORA_GRAPHICS_HPP + + +namespace Graphics { + // Enums + enum corner { + topLeft, topRight, bottomLeft, bottomRight, all + }; + + // Shapes + struct RoundedRectangle { + MultiSize rect; + Size borderRadius{}; + }; + + // Utilities: + void setColor(SDL_Renderer *renderer, Uint8 r, Uint8 g, Uint8 b, Uint8 a); + + // Drawing: + + void drawEllipse(SDL_Renderer *r, int x0, int y0, int radiusX, int radiusY, corner type = all); + + void drawLine(SDL_Renderer *r, int x1, int y1, int x2, int y2); +}; + + +#endif //AURORA_GRAPHICS_HPP \ No newline at end of file diff --git a/client/src/Rendering/RenderWindow/RenderWindow.cpp b/client/src/Rendering/RenderWindow/RenderWindow.cpp index c585613..7f99147 100644 --- a/client/src/Rendering/RenderWindow/RenderWindow.cpp +++ b/client/src/Rendering/RenderWindow/RenderWindow.cpp @@ -3,6 +3,8 @@ #include #include "Rendering/RenderWindow/RenderWindow.hpp" +#include "Rendering/Graphics/Graphics.hpp" + #include "Utilities/Sound/Sound.h" #ifdef __APPLE__ @@ -13,9 +15,10 @@ float calculateSize(Size value, Vector2f windowDimensions) { - return (value.val / 100) * (value.type == SIZE_HEIGHT ? windowDimensions.y : windowDimensions.x); + return (value.val / 100) * (value.type == WH ? windowDimensions.y : windowDimensions.x); } + RenderWindow::RenderWindow(const char *p_title, int p_width, int p_height) : window(NULL), renderer(NULL), windowDims(Vector2f(p_width, p_height)) { // Fix for audio @@ -59,7 +62,7 @@ RenderWindow::RenderWindow(const char *p_title, int p_width, int p_height) : win // SDL_ShowCursor(false); // Hides the cursor; }; -void RenderWindow::cleanUp() { +RenderWindow::~RenderWindow() { endAudio(); SDL_DestroyWindow(window); } @@ -79,6 +82,39 @@ void RenderWindow::clear() { SDL_RenderClear(renderer); } +void RenderWindow::render(Graphics::RoundedRectangle &p_roundedRect) { + int br = calculateSize(p_roundedRect.borderRadius, windowDims); + + int roundedRectX = calculateSize(p_roundedRect.rect.x, windowDims); + int roundedRectY = calculateSize(p_roundedRect.rect.y, windowDims); + int roundedRectW = calculateSize(p_roundedRect.rect.w, windowDims); + int roundedRectH = calculateSize(p_roundedRect.rect.h, windowDims); + int topLeftCornerX = roundedRectX; + int topLeftCornerY = roundedRectY; + int topRightCornerX = roundedRectX + roundedRectW; + int topRightCornerY = roundedRectY; + int bottomLeftCornerX = roundedRectX; + int bottomLeftCornerY = roundedRectY + roundedRectH; + int bottomRightCornerX = roundedRectX + roundedRectW; + int bottomRightCornerY = roundedRectY + roundedRectH; + + Graphics::setColor(renderer, 255, 255, 255, 255); + + // Draw the 4 corners + Graphics::drawEllipse(renderer, topLeftCornerX + br, topLeftCornerY + br, br, br, Graphics::topLeft); + Graphics::drawEllipse(renderer, topRightCornerX - br, topRightCornerY + br, br, br, Graphics::topRight); + Graphics::drawEllipse(renderer, bottomLeftCornerX + br, bottomLeftCornerY - br, br, br, Graphics::bottomLeft); + Graphics::drawEllipse(renderer, bottomRightCornerX - br, bottomRightCornerY - br, br, br, Graphics::bottomRight); + + // Draw the 4 lines + Graphics::drawLine(renderer, topLeftCornerX, topLeftCornerY + br, bottomLeftCornerX, bottomLeftCornerY - br); + Graphics::drawLine(renderer, topRightCornerX, topRightCornerY + br, bottomRightCornerX, bottomRightCornerY - br); + Graphics::drawLine(renderer, bottomLeftCornerX + br, bottomLeftCornerY, bottomRightCornerX - br, + bottomRightCornerY); + Graphics::drawLine(renderer, topLeftCornerX + br, topLeftCornerY, topRightCornerX - br, topRightCornerY); + +} + void RenderWindow::render(Entity &p_entity) { SDL_Rect src, dest; diff --git a/client/src/Rendering/RenderWindow/RenderWindow.hpp b/client/src/Rendering/RenderWindow/RenderWindow.hpp index 674c3f9..b912bed 100644 --- a/client/src/Rendering/RenderWindow/RenderWindow.hpp +++ b/client/src/Rendering/RenderWindow/RenderWindow.hpp @@ -1,32 +1,47 @@ #pragma once + #include #include #include "Rendering/Entity/Entity.hpp" #include "Rendering/Text/Text.hpp" +#include "Rendering/Graphics/Graphics.hpp" + #include "Utilities/Math/Math.hpp" class RenderWindow { public: - RenderWindow(const char* p_title, int p_width, int p_height); - SDL_Texture* loadTexture(const char* p_filepath); + RenderWindow(const char *p_title, int p_width, int p_height); + + ~RenderWindow(); + + SDL_Texture *loadTexture(const char *p_filepath); + + int getRefreshRate(); + + int getDisplayWidth(); + + int getDisplayHeight(); + + Vector2f getWindowDimensions(); + + void setFullScreen(bool isFullScreen); + + void cleanUp(); + + void clear(); + + void render(Entity &p_entity); - int getRefreshRate(); - int getDisplayWidth(); - int getDisplayHeight(); + void render(Graphics::RoundedRectangle &p_roundedRect); - Vector2f getWindowDimensions(); + void render(Text &p_text); - void setFullScreen(bool isFullScreen); - void cleanUp(); - void clear(); - void render(Entity& p_entity); - void render(Text& p_text); - void display(); + void display(); private: - SDL_Window* window; - SDL_Renderer* renderer; - Vector2f windowDims; + SDL_Window *window; + SDL_Renderer *renderer; + Vector2f windowDims; }; \ No newline at end of file diff --git a/client/src/Utilities/Math/Math.hpp b/client/src/Utilities/Math/Math.hpp index cf4b0cd..22ab62d 100644 --- a/client/src/Utilities/Math/Math.hpp +++ b/client/src/Utilities/Math/Math.hpp @@ -2,67 +2,71 @@ #include -#ifndef SIZE_HEIGHT - #define SIZE_HEIGHT false +#ifndef WH +#define WH false #endif -#ifndef SIZE_WIDTH - #define SIZE_WIDTH true +#ifndef WW +#define WW true #endif struct Vector2f { - Vector2f() :x(0.0f), y(0.0f) {}; - Vector2f(float p_x, float p_y) :x(p_x), y(p_y) {}; + Vector2f() : x(0.0f), y(0.0f) {}; - void print() { - std::cout << "Vector2f(x,y): " << x << ", " << y << std::endl; - }; + Vector2f(float p_x, float p_y) : x(p_x), y(p_y) {}; - float x,y; + void print() { + std::cout << "Vector2f(x,y): " << x << ", " << y << std::endl; + }; + + float x, y; }; struct Vector4f { - Vector4f() :x(0.0f), y(0.0f), w(0.0f), h(0.0f) {}; - Vector4f(float p_x, float p_y, float p_w, float p_h) :x(p_x), y(p_y), w(p_w), h(p_h) {}; + Vector4f() : x(0.0f), y(0.0f), w(0.0f), h(0.0f) {}; + + Vector4f(float p_x, float p_y, float p_w, float p_h) : x(p_x), y(p_y), w(p_w), h(p_h) {}; - void print() { - std::cout << "Vector4f(x,y,w,h): " << x << ", " << y << ", " << w << ", " << h << std::endl; - }; + void print() { + std::cout << "Vector4f(x,y,w,h): " << x << ", " << y << ", " << w << ", " << h << std::endl; + }; - float x,y,w,h; + float x, y, w, h; }; struct Size { - Size() :val(0.0f), type(SIZE_WIDTH) {}; - Size(float p_val, bool p_type) :val(p_val), type(p_type) {}; + Size() : val(0.0f), type(WW) {}; - void print() { - std::cout << "Size(val, type): " << val << ", " << (type == true ? "SIZE_WIDTH" : "SIZE_HEIGHT") << std::endl; - }; + Size(float p_val, bool p_type) : val(p_val), type(p_type) {}; - float val; // Percentage - bool type; // Width, Height + void print() { + std::cout << "Size(val, type): " << val << ", " << (type == true ? "WW" : "WH") << std::endl; + }; + + float val; // Percentage + bool type; // Width, Height }; struct MultiSize { - MultiSize() :x(Size()), y(Size()), w(Size()), h(Size()) {}; - MultiSize(Size p_x, Size p_y, Size p_w, Size p_h) :x(p_x), y(p_y), w(p_w), h(p_h) {}; + MultiSize() : x(Size()), y(Size()), w(Size()), h(Size()) {}; + + MultiSize(Size p_x, Size p_y, Size p_w, Size p_h) : x(p_x), y(p_y), w(p_w), h(p_h) {}; - void setX(float p_val) { - x.val = p_val; - } + void setX(float p_val) { + x.val = p_val; + } - void setY(float p_val) { - y.val = p_val; - } + void setY(float p_val) { + y.val = p_val; + } - void setW(float p_val) { - w.val = p_val; - } + void setW(float p_val) { + w.val = p_val; + } - void setH(float p_val) { - h.val = p_val; - } + void setH(float p_val) { + h.val = p_val; + } - Size x,y,w,h; + Size x, y, w, h; }; \ No newline at end of file diff --git a/client/src/main.cpp b/client/src/main.cpp index c9ac8ef..875e72e 100644 --- a/client/src/main.cpp +++ b/client/src/main.cpp @@ -106,9 +106,6 @@ int main(int argc, char *args[]) { } - // Cleanup: - mainMenu.cleanUp(); - window.cleanUp(); SDL_Quit(); return 0;