diff options
-rw-r--r-- | include/util.hpp | 27 | ||||
-rw-r--r-- | include/video.hpp | 132 | ||||
-rw-r--r-- | include/wsdl2.hpp | 10 | ||||
-rw-r--r-- | ninja/rules.ninja | 2 | ||||
-rw-r--r-- | video.cpp | 23 |
5 files changed, 164 insertions, 30 deletions
diff --git a/include/util.hpp b/include/util.hpp new file mode 100644 index 0000000..c6a7aec --- /dev/null +++ b/include/util.hpp @@ -0,0 +1,27 @@ +#include "debug.hpp" + +extern "C" { +#include <SDL2/SDL_error.h> +} + +namespace wsdl2 { + namespace util { + // constexpr inline bool sdl_bool(SDL_bool b) { + // return b == SDL_TRUE; + // } + + // constexpr inline SDL_bool sdl_bool(bool b) { + // return (b) ? SDL_TRUE : SDL_FALSE; + // } + + constexpr inline bool check(bool expr) { +#ifdef DEBUG + if (!expr) { + npdebug("an internal SDL error occurred:"); + npdebug(" ", const_cast<const char * const>(SDL_GetError())); + } +#endif + return expr; + } + } +}
\ No newline at end of file diff --git a/include/video.hpp b/include/video.hpp index 23c1c6e..dc315ed 100644 --- a/include/video.hpp +++ b/include/video.hpp @@ -1,7 +1,10 @@ #pragma once +#include "util.hpp" + #include <string> #include <array> +#include <type_traits> extern "C" { #include <SDL2/SDL_video.h> @@ -9,11 +12,17 @@ extern "C" { } namespace wsdl2 { - typedef SDL_Point point; - typedef SDL_Rect rect; - + // forward declarations class window; + // name aliases + using rect = SDL_Rect; + using point = SDL_Point; + + struct color { + std::uint8_t r, g, b, a; + }; + class renderer { public: friend class window; @@ -21,23 +30,113 @@ namespace wsdl2 { renderer(window& w); virtual ~renderer(); - inline void clear() { SDL_RenderClear(safe()); } - inline void present() { SDL_RenderPresent(safe()); } + inline void clear() { SDL_RenderClear(sdl()); } + inline void present() { SDL_RenderPresent(sdl()); } + + // set color + + inline void set_color(std::uint8_t r, std::uint8_t g, std::uint8_t b, std::uint8_t a) { + util::check(0 == SDL_SetRenderDrawColor(sdl(), r, g, b, a)); + } + + inline void set_color(const color& c) { + set_color(c.r, c.g, c.b, c.a); + } + + inline color get_color() { + color c; + util::check(0 == SDL_GetRenderDrawColor(sdl(), &c.r, &c.g, &c.b, &c.a)); + return c; + } + + // draw a single element + + inline void draw_point(int x, int y) { + util::check(0 == SDL_RenderDrawPoint(sdl(), x, y)); + } + + inline void draw_point(const point& p) { + draw_point(p.x, p.y); + } + + inline void draw_line(int x1, int y1, int x2, int y2) { + util::check(0 == SDL_RenderDrawLine(sdl(), x1, y1, x2, y2)); + }; + + inline void draw_line(const point& a, const point& b) { + draw_line(a.x, a.y, b.x, b.y); + }; + + inline void draw_rect(int x, int y, int h, int w) { + draw_rect(rect {x, y, h, w}); + } + + inline void draw_rect(const rect& rect) { + util::check(0 == SDL_RenderDrawRect(sdl(), &rect)); + } + + inline void fill_rect(const rect& rect) { + util::check(0 == SDL_RenderFillRect(sdl(), &rect)); + } + + // draw multiple elements + + template<template<typename> typename Container> + inline void draw_lines(const Container<point>& points) { + util::check(0 == SDL_RenderDrawLines(sdl(), points.data(), points.size())); + } + + template<template<typename> typename Container> + inline void draw_points(const Container<point>& points) { + util::check(0 == SDL_RenderDrawLines(sdl(), points.data(), points.size())); + } + + template<template<typename> typename Container> + inline void draw_rects(const Container<rect>& rects) { + util::check(0 == SDL_RenderDrawLines(sdl(), rects.data(), rects.size())); + } + + template<template<typename> typename Container> + inline void fill_rects(const Container<rect>& rects) { + util::check(0 == SDL_RenderFillRects(sdl(), rects.data(), rects.size())); + } + + // overloaded drawing function + + inline void draw(const point& p) { draw_point(p); } + inline void draw(const rect& r) { draw_rect(r); } + inline void fill(const rect& r) { fill_rect(r); } + + template<template<typename> typename Container> + inline void draw(const Container<point>& points) { + draw_points(points); + } + + template<template<typename> typename Container> + inline void draw(const Container<rect>& rects) { + draw_rects(rects); + } + + template<template<typename> typename Container> + inline void fill(const Container<rect>& rects) { + fill_rects(rects); + } - // dirty C code - inline SDL_Renderer* sdl() { return m_renderer; } private: - renderer(); + SDL_Renderer *m_renderer; - SDL_Renderer* safe(); + renderer(); void create_sdl_renderer(SDL_Window *win); - SDL_Renderer *m_renderer; + // dirty C code + SDL_Renderer* sdl(); }; class window { public: + friend class renderer; + window() = delete; window(const window& other) = delete; @@ -48,24 +147,25 @@ namespace wsdl2 { void open(); void close(); - inline void show() { SDL_ShowWindow(m_window); } - inline void hide() { SDL_HideWindow(m_window); } - inline void raise() { SDL_RaiseWindow(m_window); } + inline void show() { SDL_ShowWindow(sdl()); } + inline void hide() { SDL_HideWindow(sdl()); } + inline void raise() { SDL_RaiseWindow(sdl()); } // getters bool is_open(); bool is_visible(); // rendering + renderer& get_renderer() { return m_renderer; } void update(); - // dirty C code - inline SDL_Window* sdl() { return m_window; } - private: bool m_open; renderer m_renderer; SDL_Window *m_window; + + // dirty C code + SDL_Window* sdl(); }; diff --git a/include/wsdl2.hpp b/include/wsdl2.hpp index 16564ac..5761d07 100644 --- a/include/wsdl2.hpp +++ b/include/wsdl2.hpp @@ -7,16 +7,6 @@ extern "C" { namespace wsdl2 { bool initialize(void); void quit(void); - - namespace util { - constexpr inline bool sdl_bool(SDL_bool b) { - return b == SDL_TRUE; - } - - constexpr inline SDL_bool sdl_bool(bool b) { - return (b) ? SDL_TRUE : SDL_FALSE; - } - } // tool functions void delay(unsigned ms); diff --git a/ninja/rules.ninja b/ninja/rules.ninja index 9bdcf64..7e12db2 100644 --- a/ninja/rules.ninja +++ b/ninja/rules.ninja @@ -1,4 +1,4 @@ -includes = -I include +includes = -I . -I include cflags = -Wall -Werror -pedantic -fPIC -std=c++17 -DDEBUG $includes libs = -lSDL2 -lpthread @@ -4,12 +4,15 @@ #include <exception> #include <cstdint> +#include <vector> + extern "C" { #include <SDL2/SDL.h> } using namespace wsdl2; + /* class window */ window::window(const std::string& title, std::size_t width, std::size_t height) { @@ -64,6 +67,18 @@ void window::update() { m_renderer.present(); } +SDL_Window * window::sdl() { +#ifndef DEBUG + if (m_window == NULL) { + throw std::runtime_error( + "attempted to call window::sdl() when m_window is NULL" + ); + } +#endif + + return m_window; +} + /* class renderer */ @@ -71,10 +86,12 @@ renderer::renderer() { npdebug("warning: created uninitialized renderer object"); } -SDL_Renderer * renderer::safe() { -#ifndef WRAPSDL2_UNSAFE +SDL_Renderer * renderer::sdl() { +#ifndef DEBUG if (m_renderer == NULL) { - throw std::runtime_error("attempted to call safe() when m_renderer is NULL"); + throw std::runtime_error( + "attempted to call renderer::sdl() when m_renderer is NULL" + ); } #endif |