diff --git a/.github/workflows/linux-ci.yml b/.github/workflows/linux-ci.yml index 58869473..6239a6cd 100644 --- a/.github/workflows/linux-ci.yml +++ b/.github/workflows/linux-ci.yml @@ -15,9 +15,9 @@ jobs: - name: set environment run: | - echo "::set-env name=VULKAN_SDK_URL:: https://sdk.lunarg.com/sdk/download/$VULKAN_SDK_VER/linux/vulkansdk-linux-x86_64-$VULKAN_SDK_VER.tar.gz" - echo "::set-env name=VCPKG_PATH::${{github.workspace}}/vcpkg" - echo "::set-env name=VULKAN_SDK::${{github.workspace}}/vulkan/$VULKAN_SDK_VER/x86_64" + echo "VULKAN_SDK_URL=https://sdk.lunarg.com/sdk/download/$VULKAN_SDK_VER/linux/vulkansdk-linux-x86_64-$VULKAN_SDK_VER.tar.gz" >> $GITHUB_ENV + echo "VCPKG_PATH=${{github.workspace}}/vcpkg" >> $GITHUB_ENV + echo "VULKAN_SDK=${{github.workspace}}/vulkan/$VULKAN_SDK_VER/x86_64" >> $GITHUB_ENV - name: install apt dependencies run: sudo apt-get install g++-8 libgl1-mesa-dev libgles2-mesa-dev diff --git a/.github/workflows/windows-ci.yml b/.github/workflows/windows-ci.yml index 538ce387..6fa3d779 100644 --- a/.github/workflows/windows-ci.yml +++ b/.github/workflows/windows-ci.yml @@ -15,9 +15,9 @@ jobs: - name: set environment run: | - echo "::set-env name=VULKAN_SDK::C:\VulkanSDK\$env:VULKAN_SDK_VER" - echo "::set-env name=VULKAN_SDK_URL::https://sdk.lunarg.com/sdk/download/$env:VULKAN_SDK_VER/windows/VulkanSDK-$env:VULKAN_SDK_VER-Installer.exe" - echo "::set-env name=VCPKG_PATH::${{github.workspace}}/vcpkg" + echo "VULKAN_SDK_URL=https://sdk.lunarg.com/sdk/download/$env:VULKAN_SDK_VER/windows/VulkanSDK-$env:VULKAN_SDK_VER-Installer.exe" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + echo "VCPKG_PATH=${{github.workspace}}/vcpkg" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + echo "VULKAN_SDK=C:\VulkanSDK\$env:VULKAN_SDK_VER" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append # TODO: for some reason, this always fail, taking time for nothing # - name: cache vulkan sdk diff --git a/README.md b/README.md index a924e0c1..56a96071 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,10 @@ header. You still need a vulkan runtime and a recent version of the vulkan sdk. This uses the SDL2_Image library to load surfaces more easily. You still need to have the library installed and visible. +### CPP_SDL2_ENABLE_SDL_TTF + +This uses the SDL2_TTF library to load fonts more easily. You still need to have the library installed and visible. + ### CPP_SDL2_DISABLE_EXCEPTIONS `cpp-sdl2` uses exceptions very conservatively, and most of them indicate a failure that it probably not recoverable. @@ -72,6 +76,7 @@ replace exceptions by a log to `stderr` followed by an `abort()`. ### Optional - SDL2_image +- SDL_ttf - OpenGL - Vulkan @@ -118,9 +123,9 @@ int main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[]) if (event.type == SDL_MOUSEBUTTONUP) { - color.r = std::rand() % 256; - color.g = std::rand() % 256; - color.b = std::rand() % 256; + background.r = std::rand() % 256; + background.g = std::rand() % 256; + background.b = std::rand() % 256; redraw = true; } } diff --git a/sources/cpp-sdl2/renderer.hpp b/sources/cpp-sdl2/renderer.hpp index 474a5847..1364717d 100644 --- a/sources/cpp-sdl2/renderer.hpp +++ b/sources/cpp-sdl2/renderer.hpp @@ -65,7 +65,25 @@ class Renderer return info; } - // Get the current draw color + ///Get output size + std::pair get_output_size() const + { + int w, h; + SDL_GetRendererOutputSize(renderer_, &w, &h); + return std::pair(w, h); + } + + ///Set device-independent render size + ///\param w Width + ///\param h Height + void set_logical_size(int w, int h) const + { + if (SDL_RenderSetLogicalSize(renderer_, w, h) != 0) { + throw Exception{"SDL_RenderSetLogicalSize"}; + } + } + + ///Get the current draw color Color drawcolor() const { Color c; diff --git a/sources/cpp-sdl2/ttf.hpp b/sources/cpp-sdl2/ttf.hpp new file mode 100644 index 00000000..accf119a --- /dev/null +++ b/sources/cpp-sdl2/ttf.hpp @@ -0,0 +1,87 @@ +#pragma once +#ifdef CPP_SDL2_ENABLE_SDL_TTF +#include +#include +#include +#include + +namespace sdl +{ +///Class that represents a SDL_ttf font +class TTF +{ +public: + enum class Style { + normal=0x00, + bold=0x01, + italic=0x02, + underline=0x04, + strikethrough=0x08 + }; + + enum class Hinting { + normal=0, + light=1, + mono=2, + none=3 + }; + + ///Construct a font from the TTF_Font C object + explicit TTF(TTF_Font* font) : font_{font} {} + + ///Default ctor, create an empty font object + TTF() {} + + ///Default ctor, create an empty font object + TTF(const char* font, size_t size): font_(TTF_OpenFont(font, size)) + { + if (!font_) throw Exception{"SDL_TTF_OpenFont"}; + } + + ///Default move ctor + TTF(TTF&& other) noexcept { *this = std::move(other); } + + ///Move a font to this one + TTF& operator=(TTF&& other) noexcept + { + if (font_ != other.font_) + { + TTF_CloseFont(font_); + font_ = other.font_; + other.font_ = nullptr; + } + return *this; + } + + ///Destroy the font automaticlally when object goes out of scope + ~TTF() { TTF_CloseFont(font_); } + + ///This is a managed RAII resource. this object is not copyable + TTF(TTF const&) = delete; + + ///This is a managed RAII resource. this object is not copyable + TTF& operator=(TTF const&) = delete; + + ///Return a pointer to the wrapped C TTF_Font + TTF_Font* ptr() const { return font_; } + + sdl::Surface renderUTF8Solid(const char* text, sdl::Color fg = {0, 0, 0}) const + { + return sdl::Surface(TTF_RenderUTF8_Solid(font_, text, fg)); + } + + sdl::Surface renderUTF8Blended(const char* text, sdl::Color fg = {0, 0, 0}) const + { + return sdl::Surface(TTF_RenderUTF8_Blended(font_, text, fg)); + } + + static void Init() + { + TTF_Init(); + } +private: + ///Pointer to raw TTF_Font + TTF_Font* font_ = nullptr; +}; +}; +#endif \ No newline at end of file diff --git a/sources/cpp-sdl2/window.hpp b/sources/cpp-sdl2/window.hpp index 4217a241..c9279cfe 100644 --- a/sources/cpp-sdl2/window.hpp +++ b/sources/cpp-sdl2/window.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "renderer.hpp" #include "vec2.hpp" @@ -88,6 +89,13 @@ class Window } } + ///Set resizability + ///\param resizable User-resizable window? + void set_resizable(const bool resizable) const + { + SDL_SetWindowResizable(window_, resizable ? SDL_TRUE : SDL_FALSE); + } + ///Get the current display mode SDL_DisplayMode display_mode() const { @@ -398,6 +406,15 @@ class Window #endif + ///Add event watcher + void add_event_watch(std::function lambda) { + SDL_AddEventWatch([](void* userdata, SDL_Event* event) { + auto& lambda = *(std::function*)(userdata); + auto evt = sdl::Event(*event); + return lambda(evt); + }, &lambda); + } + private: ///Raw naked pointer to an SDL window SDL_Window* window_ = nullptr;