From 0bf2536bda6f4ebdf2ce08c0f980111d4a4cd334 Mon Sep 17 00:00:00 2001 From: Allan Legemaate Date: Wed, 20 Sep 2023 22:41:17 -0400 Subject: [PATCH] feat: add new input and render utils (#10) * feat: add new render utils and key and mouse buttons * chore: update doxygen * feat: add doxygen * fix: remove sonar action * fix: add token to deploy * fix: remove doxy files * fix: tidy up doxygen docs * fix: do not use ref in render target --- .github/workflows/deploy-docs.yml | 37 +++ .github/workflows/sonar.yml | 36 --- .gitignore | 3 +- .vscode/settings.json | 47 +++- .vscode/tasks.json | 15 ++ Doxyfile | 24 ++ README.md | 25 +- include/asw/asw.h | 2 + include/asw/modules/assets.h | 27 ++- include/asw/modules/core.h | 15 +- include/asw/modules/display.h | 45 +++- include/asw/modules/draw.h | 155 ++++++++++++- include/asw/modules/input.h | 95 +++++++- include/asw/modules/input_keys.h | 270 ++++++++++++++++++++++ include/asw/modules/input_mouse_buttons.h | 28 +++ include/asw/modules/sound.h | 17 ++ include/asw/modules/types.h | 43 ++++ include/asw/modules/util.h | 45 +++- src/modules/display.cpp | 16 ++ src/modules/draw.cpp | 38 ++- 20 files changed, 883 insertions(+), 100 deletions(-) create mode 100644 .github/workflows/deploy-docs.yml delete mode 100644 .github/workflows/sonar.yml create mode 100644 .vscode/tasks.json create mode 100644 Doxyfile create mode 100644 include/asw/modules/input_keys.h create mode 100644 include/asw/modules/input_mouse_buttons.h diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml new file mode 100644 index 0000000..d3e28e6 --- /dev/null +++ b/.github/workflows/deploy-docs.yml @@ -0,0 +1,37 @@ +name: Deploy Docs + +on: + pull_request: + branches: [main] + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + docs: + name: Deploy Docs + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Install graphviz + run: sudo apt install graphviz + + - uses: mattnotmitt/doxygen-action@v1 + with: + doxyfile-path: "./Doxyfile" + + - uses: actions/upload-pages-artifact@v1 + with: + path: ./docs + + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v2 diff --git a/.github/workflows/sonar.yml b/.github/workflows/sonar.yml deleted file mode 100644 index 4bf1e70..0000000 --- a/.github/workflows/sonar.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: SonarCloud -on: - push: - branches: - - main - pull_request: - types: [opened, synchronize, reopened] - -jobs: - sonarcloud: - name: SonarCloud - runs-on: ubuntu-latest - env: - BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - submodules: "recursive" - - - name: Install sonar-scanner and build-wrapper - uses: sonarsource/sonarcloud-github-c-cpp@v1 - - - name: Run build-wrapper - run: | - sudo apt update - sudo apt install libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev libsdl2-mixer-dev - cmake . - build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} make - - - name: Run sonar-scanner - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - run: | - sonar-scanner --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" diff --git a/.gitignore b/.gitignore index 70516c1..66e5c40 100644 --- a/.gitignore +++ b/.gitignore @@ -38,4 +38,5 @@ CMakeCache.txt compile_commands.json .ninja* /lib -Makefile \ No newline at end of file +Makefile +docs/ \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 5fd3ce4..1df1625 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -48,6 +48,51 @@ "stdexcept": "cpp", "streambuf": "cpp", "cinttypes": "cpp", - "typeinfo": "cpp" + "typeinfo": "cpp", + "__bit_reference": "cpp", + "__bits": "cpp", + "__config": "cpp", + "__debug": "cpp", + "__errc": "cpp", + "__functional_base": "cpp", + "__hash_table": "cpp", + "__locale": "cpp", + "__mutex_base": "cpp", + "__node_handle": "cpp", + "__nullptr": "cpp", + "__split_buffer": "cpp", + "__string": "cpp", + "__threading_support": "cpp", + "__tree": "cpp", + "__tuple": "cpp", + "bitset": "cpp", + "charconv": "cpp", + "codecvt": "cpp", + "complex": "cpp", + "condition_variable": "cpp", + "cstring": "cpp", + "forward_list": "cpp", + "fstream": "cpp", + "iomanip": "cpp", + "ios": "cpp", + "list": "cpp", + "locale": "cpp", + "map": "cpp", + "mutex": "cpp", + "optional": "cpp", + "queue": "cpp", + "semaphore": "cpp", + "set": "cpp", + "span": "cpp", + "sstream": "cpp", + "stack": "cpp", + "typeindex": "cpp", + "unordered_set": "cpp", + "valarray": "cpp", + "variant": "cpp", + "format": "cpp", + "shared_mutex": "cpp", + "stop_token": "cpp", + "thread": "cpp" } } diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..20fc547 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,15 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Build", + "type": "shell", + "detail": "Build", + "command": "cmake --build .", + "group": "build", + "problemMatcher": "$gcc" + } + ] +} diff --git a/Doxyfile b/Doxyfile new file mode 100644 index 0000000..3cbfae0 --- /dev/null +++ b/Doxyfile @@ -0,0 +1,24 @@ +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = "ASW Lib" +PROJECT_BRIEF = "A.D.S. Games SDL Wrapper Library. A library targeted at Allegro4 users who want to switch to SDL2 and use modern c++." +TAB_SIZE = 2 +EXTRACT_PRIVATE = YES +EXTRACT_PRIV_VIRTUAL = YES +EXTRACT_PACKAGE = YES +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_ANON_NSPACES = YES +WARN_NO_PARAMDOC = NO +INPUT = src include README.md +FILE_PATTERNS = *.cpp *.h *.md *.hpp +RECURSIVE = YES +EXAMPLE_PATH = examples +EXAMPLE_PATTERNS = *.cpp *.h *.md *.hpp +EXAMPLE_RECURSIVE = YES +USE_MDFILE_AS_MAINPAGE = README.md +SOURCE_BROWSER = YES +GENERATE_LATEX = NO +HTML_OUTPUT = docs +HAVE_DOT = YES +DOT_IMAGE_FORMAT = svg +EXTRACT_ALL = YES \ No newline at end of file diff --git a/README.md b/README.md index 5570243..89e4266 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,18 @@ # asw -A.D.S. Games SDL Wrapper +A.D.S. Games SDL Wrapper. -## Usage (CMAKE) - -### Add submodule +This project started as a way to easily port allegro4 games to SDL2. Now it intends to make it easier to use SDL2 in C++. A primary focus is to allow easy compilation of games using emscripten as well, and has been throughly tested with it. -``` -mkdir lib -git submodule add https://github.com/AdsGames/asw lib/asw -``` - -### Add to CMakeLists.txt +## Usage (CMAKE) -``` -set(ASW_HEADERS lib/asw) +### Fetch Content -target_include_directories( - executable_name PRIVATE - ${ASW_HEADERS} +```sh +FetchContent_Declare( + asw + GIT_REPOSITORY https://github.com/adsgames/asw.git + GIT_TAG ) +FetchContent_MakeAvailable(asw) ``` diff --git a/include/asw/asw.h b/include/asw/asw.h index 7afb84f..b51b3a8 100644 --- a/include/asw/asw.h +++ b/include/asw/asw.h @@ -8,6 +8,8 @@ #include "./modules/display.h" #include "./modules/draw.h" #include "./modules/input.h" +#include "./modules/input_keys.h" +#include "./modules/input_mouse_buttons.h" #include "./modules/sound.h" #include "./modules/types.h" #include "./modules/util.h" diff --git a/include/asw/modules/assets.h b/include/asw/modules/assets.h index ff13612..8ea6ed8 100644 --- a/include/asw/modules/assets.h +++ b/include/asw/modules/assets.h @@ -1,3 +1,12 @@ +/** + * @file assets.h + * @author Allan Legemaate (alegemaate@gmail.com) + * @brief Asset routines for the ASW library + * @date 2023-09-20 + * + * @copyright Copyright (c) 2023 + * + */ #ifndef ASW_ASSETS_H #define ASW_ASSETS_H @@ -12,8 +21,8 @@ namespace asw::assets { * BMP, GIF, JPG, LBM, PCX, PNM, TIF, XCF, XPM, XV, and WEBP. This will abort * if the file is not found. * - * @param filename - The path to the file. - * @return asw::Texture The loaded texture. + * @param filename The path to the file. + * @return The loaded texture. */ asw::Texture loadTexture(const std::string& filename); @@ -21,9 +30,9 @@ namespace asw::assets { * @brief Loads a TTF font from a file. This will abort if the file is not * found. * - * @param filename - The path to the file. - * @param size - * @return asw::Font + * @param filename The path to the file. + * @param size The size of the font. + * @return The loaded font. */ asw::Font loadFont(const std::string& filename, int size); @@ -32,16 +41,16 @@ namespace asw::assets { * OGG and VOC. This will abort if the file is not found. * * @param filename - * @return asw::Sample The loaded sample. + * @return The loaded sample. */ asw::Sample loadSample(const std::string& filename); /** * @brief Create a Texture given the specified dimensions. * - * @param w - The width of the texture. - * @param h - The height of the texture. - * @return asw::Texture The created texture. + * @param w The width of the texture. + * @param h The height of the texture. + * @return The created texture. */ asw::Texture createTexture(int w, int h); } // namespace asw::assets diff --git a/include/asw/modules/core.h b/include/asw/modules/core.h index 4cc69f5..a230289 100644 --- a/include/asw/modules/core.h +++ b/include/asw/modules/core.h @@ -1,3 +1,12 @@ +/** + * @file core.h + * @author Allan Legemaate (alegemaate@gmail.com) + * @brief Core routines including main loop and initialization + * @date 2023-09-20 + * + * @copyright Copyright (c) 2023 + * + */ #ifndef ASW_CORE_H #define ASW_CORE_H @@ -14,9 +23,9 @@ namespace asw::core { /** * @brief Initializes the core module. * - * @param width - The width of the window. - * @param height - The height of the window. - * @param scale - The scale of the window. + * @param width The width of the window. + * @param height The height of the window. + * @param scale The scale of the window. */ void init(int width, int height, int scale = 1); diff --git a/include/asw/modules/display.h b/include/asw/modules/display.h index 72c442d..0009d37 100644 --- a/include/asw/modules/display.h +++ b/include/asw/modules/display.h @@ -1,3 +1,12 @@ +/** + * @file display.h + * @author Allan Legemaate (alegemaate@gmail.com) + * @brief Display and window routines for the ASW library + * @date 2023-09-20 + * + * @copyright Copyright (c) 2023 + * + */ #ifndef ASW_DISPLAY_H #define ASW_DISPLAY_H @@ -14,7 +23,7 @@ namespace asw::display { /** * @brief Set the title of the window. * - * @param title - The title to display at the top of the window. + * @param title The title to display at the top of the window. */ void setTitle(const std::string& title); @@ -22,29 +31,29 @@ namespace asw::display { * @brief Set the icon to display on the window. If it does not exist, this * will silently fail. * - * @param path - A path to the icon to display. + * @param path A path to the icon to display. */ void setIcon(const std::string& path); /** * @brief Set the window to fullscreen or windowed. * - * @param fullscreen - Whether or not to set the window to fullscreen. + * @param fullscreen Whether or not to set the window to fullscreen. */ void setFullscreen(bool fullscreen); /** * @brief Set the resolution of the window. * - * @param w - The width of the window. - * @param h - The height of the window. + * @param w The width of the window. + * @param h The height of the window. */ void setResolution(int w, int h); /** * @brief Get the size of the window. * - * @return SDL_Point - The size of the window. + * @return The size of the window. */ SDL_Point getSize(); @@ -52,7 +61,7 @@ namespace asw::display { * @brief Get the logical size of the window. This may differ from the * actual size if scaling is enabled. * - * @return SDL_Point - The logical size of the window. + * @return The logical size of the window. */ SDL_Point getLogicalSize(); @@ -60,10 +69,30 @@ namespace asw::display { * @brief Get the scale of the window. This is equivalent to the logical * size divided by the actual size. * - * @return SDL_FPoint - The scale of the window. + * @return The scale of the window. */ SDL_FPoint getScale(); + /** + * @brief Set the render target to the window. + */ + void setRenderTarget(asw::Texture texture); + + /** + * @brief Reset the render target to the default. + */ + void resetRenderTarget(); + + /** + * @brief Clear the window. + */ + void clear(); + + /** + * @brief Present the window. + */ + void present(); + } // namespace asw::display #endif // ASW_DISPLAY_H \ No newline at end of file diff --git a/include/asw/modules/draw.h b/include/asw/modules/draw.h index 04d6b25..e848187 100644 --- a/include/asw/modules/draw.h +++ b/include/asw/modules/draw.h @@ -1,3 +1,12 @@ +/** + * @file draw.h + * @author Allan Legemaate (alegemaate@gmail.com) + * @brief Routines for drawing sprites and primitives to the screen + * @date 2023-09-20 + * + * @copyright Copyright (c) 2023 + * + */ #ifndef ASW_DRAW_H #define ASW_DRAW_H @@ -5,18 +14,67 @@ namespace asw::draw { + /** + * @brief Clear the screen to a color. + * + * @param color The color to clear the screen to. + */ void clearColor(asw::Color color); + /** + * @brief Draw a sprite. + * + * @param tex The texture to draw. + * @param x The x position to draw the sprite at. + * @param y The y position to draw the sprite at. + */ void sprite(asw::Texture tex, int x, int y); - void spriteHFlip(asw::Texture tex, int x, int y); - - void spriteVFlip(asw::Texture tex, int x, int y); - - void spriteVHFlip(asw::Texture tex, int x, int y); - + /** + * @brief Draw a sprite with the option to flip it. + * + * @param tex The texture to draw. + * @param x The x position to draw the sprite at. + * @param y The y position to draw the sprite at. + * @param flipX - Whether or not to flip the sprite on the x axis. + * @param flipY - Whether or not to flip the sprite on the y axis. + */ + void spriteFlip(asw::Texture tex, int x, int y, bool flipX, bool flipY); + + /** + * @brief Draw a sprite with the option to stretch it. + * + * @param tex The texture to draw. + * @param x The x position to draw the sprite at. + * @param y The y position to draw the sprite at. + * @param w The width to stretch the sprite to. + * @param h The height to stretch the sprite to. + */ void stretchSprite(asw::Texture tex, int x, int y, int w, int h); + /** + * @brief Draw a sprite with the option to rotate it. + * + * @param tex The texture to draw. + * @param x The x position to draw the sprite at. + * @param y The y position to draw the sprite at. + * @param angleDeg - The angle to rotate the sprite by in degrees. + */ + void rotateSprite(asw::Texture tex, int x, int y, int angleDeg); + + /** + * @brief Draw a sprite with the option to stretch a portion of it. + * + * @param tex The texture to draw. + * @param x1 The x position to draw the sprite at. + * @param y1 The y position to draw the sprite at. + * @param w1 The width to stretch the sprite to. + * @param h1 The height to stretch the sprite to. + * @param x2 The x position of the portion of the sprite to stretch. + * @param y2 The y position of the portion of the sprite to stretch. + * @param w2 The width of the portion of the sprite to stretch. + * @param h2 The height of the portion of the sprite to stretch. + */ void stretchSpriteBlit(asw::Texture tex, int x1, int y1, @@ -27,36 +85,121 @@ namespace asw::draw { int w2, int h2); + /** + * @brief Draw text left aligned. + * + * @param font The font to use. + * @param text The text to draw. + * @param x The x position to draw the text at. + * @param y The y position to draw the text at. + * @param color The color to draw the text. + */ void text(asw::Font font, const std::string& text, int x, int y, asw::Color color); + /** + * @brief Draw text center aligned. + * + * @param font The font to use. + * @param text The text to draw. + * @param x The x position to draw the text at. + * @param y The y position to draw the text at. + * @param color The color to draw the text. + */ void textCenter(asw::Font font, const std::string& text, int x, int y, asw::Color color); + /** + * @brief Draw text right aligned. + * + * @param font The font to use. + * @param text The text to draw. + * @param x The x position to draw the text at. + * @param y The y position to draw the text at. + * @param color The color to draw the text. + */ void textRight(asw::Font font, const std::string& text, int x, int y, asw::Color color); + /** + * @brief Draw a point. + * + * @param x The x position of the point. + * @param y The y position of the point. + * @param color The color of the point. + */ void point(int x, int y, asw::Color color); + /** + * @brief Draw a line. + * + * @param x1 The x position of the start of the line. + * @param y1 The y position of the start of the line. + * @param x2 The x position of the end of the line. + * @param y2 The y position of the end of the line. + * @param color The color of the line. + */ void line(int x1, int y1, int x2, int y2, asw::Color color); + /** + * @brief Draw a rectangle. + * + * @param x The x position of the rectangle. + * @param y The y position of the rectangle. + * @param w The width of the rectangle. + * @param h The height of the rectangle. + * @param color The color of the rectangle. + */ void rect(int x, int y, int w, int h, asw::Color color); + /** + * @brief Draw a filled rectangle. + * + * @param x The x position of the rectangle. + * @param y The y position of the rectangle. + * @param w The width of the rectangle. + * @param h The height of the rectangle. + * @param color The color of the rectangle. + */ void rectFill(int x, int y, int w, int h, asw::Color color); + /** + * @brief Draw a cirle. + * + * @param x The x position of the center of the circle. + * @param y The y position of the center of the circle. + * @param r The radius of the circle. + * @param color The color of the circle. + */ void circle(int x, int y, int r, asw::Color color); + /** + * @brief Draw a filled circle. + * + * @param x The x position of the center of the circle. + * @param y The y position of the center of the circle. + * @param r The radius of the circle. + * @param color The color of the circle. + */ void circleFill(int x, int y, int r, asw::Color color); + /** + * @brief Set the blend mode of a texture. + * + * @param texture The texture to set the blend mode of. + * @param mode The blend mode to set. + */ + void setBlendMode(asw::Texture texture, asw::BlendMode mode); + } // namespace asw::draw #endif // ASW_DRAW_H \ No newline at end of file diff --git a/include/asw/modules/input.h b/include/asw/modules/input.h index 9ce7f2f..1a46d36 100644 --- a/include/asw/modules/input.h +++ b/include/asw/modules/input.h @@ -1,17 +1,61 @@ -#ifndef ASW_KEY_STATE_H -#define ASW_KEY_STATE_H +/** + * @file input.h + * @author Allan Legemaate (alegemaate@gmail.com) + * @brief Input module for the ASW library + * @date 2023-09-20 + * + * @copyright Copyright (c) 2023 + * + */ +#ifndef ASW_INPUT_H +#define ASW_INPUT_H #include #include -#define ASW_NUM_KEYS SDL_NUM_SCANCODES -#define ASW_NUM_MOUSE_BUTTONS 5 +#include "./input_keys.h" +#include "./input_mouse_buttons.h" namespace asw::input { + + /** + * @brief Mouse state stores the current state of the mouse. It is updated by + * the core. + * + */ using MouseState = struct MouseState { - std::array pressed{false}; - std::array released{false}; - std::array down{false}; + /** + * @brief Check if a button is down. + * + * @param button The button to check. + * @return true - If the button is down. + * @return false - If the button is not down. + */ + bool isButtonDown(asw::input::MouseButton button) { + return down[static_cast(button)]; + } + + /** + * @brief Check if a button was pressed since the last update. + * + * @param button The button to check. + * @return true - If the button was pressed. + * @return false - If the button was not pressed. + */ + bool wasButtonPressed(asw::input::MouseButton button) { + return pressed[static_cast(button)]; + } + + /** + * @brief Check if a button was released since the last update. + * + * @param button The button to check. + * @return true - If the button was released. + * @return false - If the button was not released. + */ + bool wasButtonReleased(asw::input::MouseButton button) { + return released[static_cast(button)]; + } bool anyPressed{false}; int lastPressed{-1}; @@ -22,11 +66,46 @@ namespace asw::input { int x{0}; int y{0}; int z{0}; + + std::array pressed{false}; + std::array released{false}; + std::array down{false}; }; extern MouseState mouse; using KeyState = struct KeyState { + /** + * @brief Check if a key is down. + * + * @param key The key to check. + * @return true - If the key is down. + * @return false - If the key is not down. + */ + bool isKeyDown(asw::input::Key key) { return down[static_cast(key)]; } + + /** + * @brief Check if a key was pressed since the last update. + * + * @param key The key to check. + * @return true - If the key was pressed. + * @return false - If the key was not pressed. + */ + bool wasKeyPressed(asw::input::Key key) { + return pressed[static_cast(key)]; + } + + /** + * @brief Check if a key was released since the last update. + * + * @param key The key to check. + * @return true - If the key was released. + * @return false - If the key was not released. + */ + bool wasKeyReleased(asw::input::Key key) { + return released[static_cast(key)]; + } + std::array pressed{false}; std::array released{false}; std::array down{false}; @@ -40,4 +119,4 @@ namespace asw::input { void reset(); } // namespace asw::input -#endif // ASW_KEY_STATE_H \ No newline at end of file +#endif // ASW_INPUT_H \ No newline at end of file diff --git a/include/asw/modules/input_keys.h b/include/asw/modules/input_keys.h new file mode 100644 index 0000000..2a7f5ea --- /dev/null +++ b/include/asw/modules/input_keys.h @@ -0,0 +1,270 @@ +/** + * @file input_keys.h + * @author Allan Legemaate (alegemaate@gmail.com) + * @brief Mapping from SDL keys to ASW keys + * @date 2023-09-20 + * + * @copyright Copyright (c) 2023 + * + */ +#ifndef ASW_INPUT_KEYS_H +#define ASW_INPUT_KEYS_H + +#include + +namespace asw::input { + constexpr int ASW_NUM_KEYS = SDL_NUM_SCANCODES; + + enum class Key { + UNKNOWN = SDL_SCANCODE_UNKNOWN, + A = SDL_SCANCODE_A, + B = SDL_SCANCODE_B, + C = SDL_SCANCODE_C, + D = SDL_SCANCODE_D, + E = SDL_SCANCODE_E, + F = SDL_SCANCODE_F, + G = SDL_SCANCODE_G, + H = SDL_SCANCODE_H, + I = SDL_SCANCODE_I, + J = SDL_SCANCODE_J, + K = SDL_SCANCODE_K, + L = SDL_SCANCODE_L, + M = SDL_SCANCODE_M, + N = SDL_SCANCODE_N, + O = SDL_SCANCODE_O, + P = SDL_SCANCODE_P, + Q = SDL_SCANCODE_Q, + R = SDL_SCANCODE_R, + S = SDL_SCANCODE_S, + T = SDL_SCANCODE_T, + U = SDL_SCANCODE_U, + V = SDL_SCANCODE_V, + W = SDL_SCANCODE_W, + X = SDL_SCANCODE_X, + Y = SDL_SCANCODE_Y, + Z = SDL_SCANCODE_Z, + NUM_1 = SDL_SCANCODE_1, + NUM_2 = SDL_SCANCODE_2, + NUM_3 = SDL_SCANCODE_3, + NUM_4 = SDL_SCANCODE_4, + NUM_5 = SDL_SCANCODE_5, + NUM_6 = SDL_SCANCODE_6, + NUM_7 = SDL_SCANCODE_7, + NUM_8 = SDL_SCANCODE_8, + NUM_9 = SDL_SCANCODE_9, + NUM_0 = SDL_SCANCODE_0, + RETURN = SDL_SCANCODE_RETURN, + ESCAPE = SDL_SCANCODE_ESCAPE, + BACKSPACE = SDL_SCANCODE_BACKSPACE, + TAB = SDL_SCANCODE_TAB, + SPACE = SDL_SCANCODE_SPACE, + MINUS = SDL_SCANCODE_MINUS, + EQUALS = SDL_SCANCODE_EQUALS, + LEFT_BRACKET = SDL_SCANCODE_LEFTBRACKET, + RIGHT_BRACKET = SDL_SCANCODE_RIGHTBRACKET, + BACKSLASH = SDL_SCANCODE_BACKSLASH, + NONUSHASH = SDL_SCANCODE_NONUSHASH, + SEMICOLON = SDL_SCANCODE_SEMICOLON, + APOSTROPHE = SDL_SCANCODE_APOSTROPHE, + GRAVE = SDL_SCANCODE_GRAVE, + COMMA = SDL_SCANCODE_COMMA, + PERIOD = SDL_SCANCODE_PERIOD, + SLASH = SDL_SCANCODE_SLASH, + CAPSLOCK = SDL_SCANCODE_CAPSLOCK, + F1 = SDL_SCANCODE_F1, + F2 = SDL_SCANCODE_F2, + F3 = SDL_SCANCODE_F3, + F4 = SDL_SCANCODE_F4, + F5 = SDL_SCANCODE_F5, + F6 = SDL_SCANCODE_F6, + F7 = SDL_SCANCODE_F7, + F8 = SDL_SCANCODE_F8, + F9 = SDL_SCANCODE_F9, + F10 = SDL_SCANCODE_F10, + F11 = SDL_SCANCODE_F11, + F12 = SDL_SCANCODE_F12, + PRINT_SCREEN = SDL_SCANCODE_PRINTSCREEN, + SCROL_LLOCK = SDL_SCANCODE_SCROLLLOCK, + PAUSE = SDL_SCANCODE_PAUSE, + INSERT = SDL_SCANCODE_INSERT, + HOME = SDL_SCANCODE_HOME, + PAGE_UP = SDL_SCANCODE_PAGEUP, + DELETE = SDL_SCANCODE_DELETE, + END = SDL_SCANCODE_END, + PAGE_DOWN = SDL_SCANCODE_PAGEDOWN, + RIGHT = SDL_SCANCODE_RIGHT, + LEFT = SDL_SCANCODE_LEFT, + DOWN = SDL_SCANCODE_DOWN, + UP = SDL_SCANCODE_UP, + NUM_LOCK_CLEAR = SDL_SCANCODE_NUMLOCKCLEAR, + KP_DIVIDE = SDL_SCANCODE_KP_DIVIDE, + KP_MULTIPLY = SDL_SCANCODE_KP_MULTIPLY, + KP_MINUS = SDL_SCANCODE_KP_MINUS, + KP_PLUS = SDL_SCANCODE_KP_PLUS, + KP_ENTER = SDL_SCANCODE_KP_ENTER, + KP_1 = SDL_SCANCODE_KP_1, + KP_2 = SDL_SCANCODE_KP_2, + KP_3 = SDL_SCANCODE_KP_3, + KP_4 = SDL_SCANCODE_KP_4, + KP_5 = SDL_SCANCODE_KP_5, + KP_6 = SDL_SCANCODE_KP_6, + KP_7 = SDL_SCANCODE_KP_7, + KP_8 = SDL_SCANCODE_KP_8, + KP_9 = SDL_SCANCODE_KP_9, + KP_0 = SDL_SCANCODE_KP_0, + KP_PERIOD = SDL_SCANCODE_KP_PERIOD, + NONUS_BACKSLASH = SDL_SCANCODE_NONUSBACKSLASH, + APPLICATION = SDL_SCANCODE_APPLICATION, + POWER = SDL_SCANCODE_POWER, + KP_EQUALS = SDL_SCANCODE_KP_EQUALS, + F13 = SDL_SCANCODE_F13, + F14 = SDL_SCANCODE_F14, + F15 = SDL_SCANCODE_F15, + F16 = SDL_SCANCODE_F16, + F17 = SDL_SCANCODE_F17, + F18 = SDL_SCANCODE_F18, + F19 = SDL_SCANCODE_F19, + F20 = SDL_SCANCODE_F20, + F21 = SDL_SCANCODE_F21, + F22 = SDL_SCANCODE_F22, + F23 = SDL_SCANCODE_F23, + F24 = SDL_SCANCODE_F24, + EXECUTE = SDL_SCANCODE_EXECUTE, + HELP = SDL_SCANCODE_HELP, + MENU = SDL_SCANCODE_MENU, + SELECT = SDL_SCANCODE_SELECT, + STOP = SDL_SCANCODE_STOP, + AGAIN = SDL_SCANCODE_AGAIN, + UNDO = SDL_SCANCODE_UNDO, + CUT = SDL_SCANCODE_CUT, + COPY = SDL_SCANCODE_COPY, + PASTE = SDL_SCANCODE_PASTE, + FIND = SDL_SCANCODE_FIND, + MUTE = SDL_SCANCODE_MUTE, + VOLUME_UP = SDL_SCANCODE_VOLUMEUP, + VOLUME_DOWN = SDL_SCANCODE_VOLUMEDOWN, + KP_COMMA = SDL_SCANCODE_KP_COMMA, + KP_EQUALSAS_400 = SDL_SCANCODE_KP_EQUALSAS400, + INTERNATIONAL_1 = SDL_SCANCODE_INTERNATIONAL1, + INTERNATIONAL_2 = SDL_SCANCODE_INTERNATIONAL2, + INTERNATIONAL_3 = SDL_SCANCODE_INTERNATIONAL3, + INTERNATIONAL_4 = SDL_SCANCODE_INTERNATIONAL4, + INTERNATIONAL_5 = SDL_SCANCODE_INTERNATIONAL5, + INTERNATIONAL_6 = SDL_SCANCODE_INTERNATIONAL6, + INTERNATIONAL_7 = SDL_SCANCODE_INTERNATIONAL7, + INTERNATIONAL_8 = SDL_SCANCODE_INTERNATIONAL8, + INTERNATIONAL_9 = SDL_SCANCODE_INTERNATIONAL9, + LANG_1 = SDL_SCANCODE_LANG1, + LANG_2 = SDL_SCANCODE_LANG2, + LANG_3 = SDL_SCANCODE_LANG3, + LANG_4 = SDL_SCANCODE_LANG4, + LANG_5 = SDL_SCANCODE_LANG5, + LANG_6 = SDL_SCANCODE_LANG6, + LANG_7 = SDL_SCANCODE_LANG7, + LANG_8 = SDL_SCANCODE_LANG8, + LANG_9 = SDL_SCANCODE_LANG9, + ALT_ERASE = SDL_SCANCODE_ALTERASE, + SYS_REQ = SDL_SCANCODE_SYSREQ, + CANCEL = SDL_SCANCODE_CANCEL, + CLEAR = SDL_SCANCODE_CLEAR, + PRIOR = SDL_SCANCODE_PRIOR, + RETURN_2 = SDL_SCANCODE_RETURN2, + SEPARATOR = SDL_SCANCODE_SEPARATOR, + OUT = SDL_SCANCODE_OUT, + OPER = SDL_SCANCODE_OPER, + CLEAR_AGAIN = SDL_SCANCODE_CLEARAGAIN, + CRSEL = SDL_SCANCODE_CRSEL, + EXSEL = SDL_SCANCODE_EXSEL, + KP_00 = SDL_SCANCODE_KP_00, + KP_000 = SDL_SCANCODE_KP_000, + THOUSANDS_SEPARATOR = SDL_SCANCODE_THOUSANDSSEPARATOR, + DECIMAL_SEPARATOR = SDL_SCANCODE_DECIMALSEPARATOR, + CURRENCY_UNIT = SDL_SCANCODE_CURRENCYUNIT, + CURRENCY_SUBUNIT = SDL_SCANCODE_CURRENCYSUBUNIT, + KP_LEFT_PAREN = SDL_SCANCODE_KP_LEFTPAREN, + KP_RIGHT_PAREN = SDL_SCANCODE_KP_RIGHTPAREN, + KP_LEFT_BRACE = SDL_SCANCODE_KP_LEFTBRACE, + KP_RIGHT_BRACE = SDL_SCANCODE_KP_RIGHTBRACE, + KP_TAB = SDL_SCANCODE_KP_TAB, + KP_BACKSPACE = SDL_SCANCODE_KP_BACKSPACE, + KP_A = SDL_SCANCODE_KP_A, + KP_B = SDL_SCANCODE_KP_B, + KP_C = SDL_SCANCODE_KP_C, + KP_D = SDL_SCANCODE_KP_D, + KP_E = SDL_SCANCODE_KP_E, + KP_F = SDL_SCANCODE_KP_F, + KP_XOR = SDL_SCANCODE_KP_XOR, + KP_POWER = SDL_SCANCODE_KP_POWER, + KP_PERCENT = SDL_SCANCODE_KP_PERCENT, + KP_LESS = SDL_SCANCODE_KP_LESS, + KP_GREATER = SDL_SCANCODE_KP_GREATER, + KP_AMPERSAND = SDL_SCANCODE_KP_AMPERSAND, + KP_DOUBLE_AMPERSAND = SDL_SCANCODE_KP_DBLAMPERSAND, + KP_VERTICAL_BAR = SDL_SCANCODE_KP_VERTICALBAR, + KP_DOUBLE_VERTICAL_BAR = SDL_SCANCODE_KP_DBLVERTICALBAR, + KP_COLON = SDL_SCANCODE_KP_COLON, + KP_HASH = SDL_SCANCODE_KP_HASH, + KP_SPACE = SDL_SCANCODE_KP_SPACE, + KP_AT = SDL_SCANCODE_KP_AT, + KP_EXCLAMATION = SDL_SCANCODE_KP_EXCLAM, + KP_MEM_STORE = SDL_SCANCODE_KP_MEMSTORE, + KP_MEM_RECALL = SDL_SCANCODE_KP_MEMRECALL, + KP_MEM_CLEAR = SDL_SCANCODE_KP_MEMCLEAR, + KP_MEM_ADD = SDL_SCANCODE_KP_MEMADD, + KP_MEM_SUBTRACT = SDL_SCANCODE_KP_MEMSUBTRACT, + KP_MEM_MULTIPLY = SDL_SCANCODE_KP_MEMMULTIPLY, + KP_MEM_DIVIDE = SDL_SCANCODE_KP_MEMDIVIDE, + KP_PLUS_MINUS = SDL_SCANCODE_KP_PLUSMINUS, + KP_CLEAR = SDL_SCANCODE_KP_CLEAR, + KP_CLEAR_ENTRY = SDL_SCANCODE_KP_CLEARENTRY, + KP_BINARY = SDL_SCANCODE_KP_BINARY, + KP_OCTAL = SDL_SCANCODE_KP_OCTAL, + KP_DECIMAL = SDL_SCANCODE_KP_DECIMAL, + KP_HEXADECIMAL = SDL_SCANCODE_KP_HEXADECIMAL, + LCTRL = SDL_SCANCODE_LCTRL, + LSHIFT = SDL_SCANCODE_LSHIFT, + LALT = SDL_SCANCODE_LALT, + LGUI = SDL_SCANCODE_LGUI, + RCTRL = SDL_SCANCODE_RCTRL, + RSHIFT = SDL_SCANCODE_RSHIFT, + RALT = SDL_SCANCODE_RALT, + RGUI = SDL_SCANCODE_RGUI, + MODE = SDL_SCANCODE_MODE, + AUDIO_NEXT = SDL_SCANCODE_AUDIONEXT, + AUDIO_PREV = SDL_SCANCODE_AUDIOPREV, + AUDIO_STOP = SDL_SCANCODE_AUDIOSTOP, + AUDIO_PLAY = SDL_SCANCODE_AUDIOPLAY, + AUDIO_MUTE = SDL_SCANCODE_AUDIOMUTE, + MEDIA_SELECT = SDL_SCANCODE_MEDIASELECT, + WWW = SDL_SCANCODE_WWW, + MAIL = SDL_SCANCODE_MAIL, + CALCULATOR = SDL_SCANCODE_CALCULATOR, + COMPUTER = SDL_SCANCODE_COMPUTER, + AC_SEARCH = SDL_SCANCODE_AC_SEARCH, + AC_HOME = SDL_SCANCODE_AC_HOME, + AC_BACK = SDL_SCANCODE_AC_BACK, + AC_FORWARD = SDL_SCANCODE_AC_FORWARD, + AC_STOP = SDL_SCANCODE_AC_STOP, + AC_REFRESH = SDL_SCANCODE_AC_REFRESH, + AC_BOOKMARKS = SDL_SCANCODE_AC_BOOKMARKS, + BRIGHTNESS_DOWN = SDL_SCANCODE_BRIGHTNESSDOWN, + BRIGHTNESS_UP = SDL_SCANCODE_BRIGHTNESSUP, + DISPLAY_SWITCH = SDL_SCANCODE_DISPLAYSWITCH, + ILLUMINATION_TOGGLE = SDL_SCANCODE_KBDILLUMTOGGLE, + ILLUMINATION_DOWN = SDL_SCANCODE_KBDILLUMDOWN, + ILLUMINATION_UP = SDL_SCANCODE_KBDILLUMUP, + EJECT = SDL_SCANCODE_EJECT, + SLEEP = SDL_SCANCODE_SLEEP, + APP1 = SDL_SCANCODE_APP1, + APP2 = SDL_SCANCODE_APP2, + AUDIO_REWIND = SDL_SCANCODE_AUDIOREWIND, + AUDIO_FAST_FORWARD = SDL_SCANCODE_AUDIOFASTFORWARD, + SOFT_LEFT = SDL_SCANCODE_SOFTLEFT, + SOFT_RIGHT = SDL_SCANCODE_SOFTRIGHT, + CALL = SDL_SCANCODE_CALL, + ENDCALL = SDL_SCANCODE_ENDCALL, + NUM_SCANCODES = ASW_NUM_KEYS + }; +} // namespace asw::input + +#endif // ASW_INPUT_KEYS_H \ No newline at end of file diff --git a/include/asw/modules/input_mouse_buttons.h b/include/asw/modules/input_mouse_buttons.h new file mode 100644 index 0000000..798459d --- /dev/null +++ b/include/asw/modules/input_mouse_buttons.h @@ -0,0 +1,28 @@ +/** + * @file input_mouse_buttons.h + * @author Allan Legemaate (alegemaate@gmail.com) + * @brief Mappings from SDL mouse buttons to ASW mouse buttons + * @date 2023-09-20 + * + * @copyright Copyright (c) 2023 + * + */ +#ifndef ASW_INPUT_MOUSE_BUTTONS_H +#define ASW_INPUT_MOUSE_BUTTONS_H + +#include + +namespace asw::input { + constexpr int ASW_NUM_MOUSE_BUTTONS = 5; + + enum class MouseButton { + LEFT = SDL_BUTTON_LEFT, + MIDDLE = SDL_BUTTON_MIDDLE, + RIGHT = SDL_BUTTON_RIGHT, + X1 = SDL_BUTTON_X1, + X2 = SDL_BUTTON_X2, + MAX = ASW_NUM_MOUSE_BUTTONS + }; +} // namespace asw::input + +#endif // ASW_INPUT_MOUSE_BUTTONS_H \ No newline at end of file diff --git a/include/asw/modules/sound.h b/include/asw/modules/sound.h index bb5a3f6..19d7973 100644 --- a/include/asw/modules/sound.h +++ b/include/asw/modules/sound.h @@ -1,9 +1,26 @@ +/** + * @file sound.h + * @author Allan Legemaate (alegemaate@gmail.com) + * @brief Sound module for the ASW library + * @date 2023-09-20 + * + * @copyright Copyright (c) 2023 + * + */ #ifndef ASW_SOUND_H #define ASW_SOUND_H #include "./types.h" namespace asw::sound { + /** + * @brief Play a sample. + * + * @param sample Sample to play + * @param volume Playback volume + * @param pan Panning (0-255) + * @param loop Number of times to loop (0 = no loop, -1 = infinite loop) + */ void play(asw::Sample sample, int volume = 255, unsigned char pan = 128, diff --git a/include/asw/modules/types.h b/include/asw/modules/types.h index 34587fe..b70090e 100644 --- a/include/asw/modules/types.h +++ b/include/asw/modules/types.h @@ -1,3 +1,12 @@ +/** + * @file types.h + * @author Allan Legemaate (alegemaate@gmail.com) + * @brief Types used throughout the ASW library + * @date 2023-09-20 + * + * @copyright Copyright (c) 2023 + * + */ #ifndef ASW_TYPES_H #define ASW_TYPES_H @@ -7,12 +16,46 @@ #include namespace asw { + /** + * @brief Alias for a shared pointer to an SDL_Texture + */ using Texture = std::shared_ptr; + + /** + * @brief Alias for a shared pointer to an TTF_Font + */ using Font = std::shared_ptr; + + /** + * @brief Alias for a shared pointer to an Mix_Chunk + */ using Sample = std::shared_ptr; + + /** + * @brief Alias for a shared pointer to an SDL_Renderer + */ using Renderer = SDL_Renderer; + + /** + * @brief Alias for a shared pointer to an SDL_Window + */ using Window = SDL_Window; + + /** + * @brief Alias for an SDL_Color + */ using Color = SDL_Color; + + /** + * @brief Mappings from SDL_BLENDMODE to ASW BlendMode + */ + enum class BlendMode { + NONE = SDL_BLENDMODE_NONE, + BLEND = SDL_BLENDMODE_BLEND, + ADD = SDL_BLENDMODE_ADD, + MODULATE = SDL_BLENDMODE_MOD, + MULTIPLY = SDL_BLENDMODE_MUL + }; } // namespace asw #endif // ASW_TYPES_H \ No newline at end of file diff --git a/include/asw/modules/util.h b/include/asw/modules/util.h index 911a3ba..6b47166 100644 --- a/include/asw/modules/util.h +++ b/include/asw/modules/util.h @@ -1,3 +1,12 @@ +/** + * @file util.h + * @author Allan Legemaate (alegemaate@gmail.com) + * @brief General utility functions + * @date 2023-09-20 + * + * @copyright Copyright (c) 2023 + * + */ #ifndef ASW_UTIL_H #define ASW_UTIL_H @@ -6,15 +15,49 @@ #include "./types.h" namespace asw::util { - + /** + * @brief Abort program and display error message + * + * @param message Message to display + */ void abortOnError(const std::string& message); + /** + * @brief Make a color from RGB values + * + * @param r Red value (0-255) + * @param g Green value (0-255) + * @param b Blue value (0-255) + * @return The color + */ asw::Color makeColor(int r, int g, int b); + /** + * @brief Make a color from RGBA values + * + * @param r Red value (0-255) + * @param g Green value (0-255) + * @param b Blue value (0-255) + * @param a Alpha value (0-255) + * @return The color + */ asw::Color makeColor(int r, int g, int b, int a); + /** + * @brief Get texture size + * + * @param tex Texture to get size of + * @return Size as SDL_Point + */ SDL_Point getTextureSize(asw::Texture tex); + /** + * @brief Get text size + * + * @param font Font to use + * @param text Text to get size of + * @return Size as SDL_Point + */ SDL_Point getTextSize(asw::Font font, const std::string& text); } // namespace asw::util diff --git a/src/modules/display.cpp b/src/modules/display.cpp index df963e3..903c53a 100644 --- a/src/modules/display.cpp +++ b/src/modules/display.cpp @@ -48,4 +48,20 @@ SDL_FPoint asw::display::getScale() { SDL_FPoint scale; SDL_RenderGetScale(asw::display::renderer, &scale.x, &scale.y); return scale; +} + +void asw::display::setRenderTarget(asw::Texture texture) { + SDL_SetRenderTarget(asw::display::renderer, texture.get()); +} + +void asw::display::resetRenderTarget() { + SDL_SetRenderTarget(asw::display::renderer, nullptr); +} + +void asw::display::clear() { + SDL_RenderClear(asw::display::renderer); +} + +void asw::display::present() { + SDL_RenderPresent(asw::display::renderer); } \ No newline at end of file diff --git a/src/modules/draw.cpp b/src/modules/draw.cpp index 0a5331b..56848bb 100644 --- a/src/modules/draw.cpp +++ b/src/modules/draw.cpp @@ -19,22 +19,25 @@ void asw::draw::sprite(asw::Texture tex, int x, int y) { SDL_RenderCopy(asw::display::renderer, tex.get(), nullptr, &dest); } -void asw::draw::spriteHFlip(asw::Texture tex, int x, int y) { +void asw::draw::spriteFlip(asw::Texture tex, + int x, + int y, + bool flipX, + bool flipY) { SDL_Point size = asw::util::getTextureSize(tex); SDL_Rect dest = {x, y, size.x, size.y}; - SDL_RenderCopy(asw::display::renderer, tex.get(), nullptr, &dest); -} + SDL_RendererFlip flip = SDL_FLIP_NONE; -void asw::draw::spriteVFlip(asw::Texture tex, int x, int y) { - SDL_Point size = asw::util::getTextureSize(tex); - SDL_Rect dest = {x, y, size.x, size.y}; - SDL_RenderCopy(asw::display::renderer, tex.get(), nullptr, &dest); -} + if (flipX) { + flip = static_cast(flip | SDL_FLIP_HORIZONTAL); + } -void asw::draw::spriteVHFlip(asw::Texture tex, int x, int y) { - SDL_Point size = asw::util::getTextureSize(tex); - SDL_Rect dest = {x, y, size.x, size.y}; - SDL_RenderCopy(asw::display::renderer, tex.get(), nullptr, &dest); + if (flipY) { + flip = static_cast(flip | SDL_FLIP_VERTICAL); + } + + SDL_RenderCopyEx(asw::display::renderer, tex.get(), nullptr, &dest, 0, + nullptr, flip); } void asw::draw::stretchSprite(asw::Texture tex, int x, int y, int w, int h) { @@ -42,6 +45,13 @@ void asw::draw::stretchSprite(asw::Texture tex, int x, int y, int w, int h) { SDL_RenderCopy(asw::display::renderer, tex.get(), nullptr, &dest); } +void asw::draw::rotateSprite(asw::Texture tex, int x, int y, int angleDeg) { + SDL_Point size = asw::util::getTextureSize(tex); + SDL_Rect dest = {x, y, size.x, size.y}; + SDL_RenderCopyEx(asw::display::renderer, tex.get(), nullptr, &dest, angleDeg, + nullptr, SDL_FLIP_NONE); +} + void asw::draw::stretchSpriteBlit(asw::Texture tex, int x1, int y1, @@ -136,3 +146,7 @@ void asw::draw::circleFill(int x, int y, int r, asw::Color color) { y + r * sin(i)); } } + +void asw::draw::setBlendMode(asw::Texture texture, asw::BlendMode mode) { + SDL_SetTextureBlendMode(texture.get(), static_cast(mode)); +}