171 lines
3.6 KiB
C++
171 lines
3.6 KiB
C++
#ifndef WC3RE_RENDER_SDLUTIL_HH__
|
|
#define WC3RE_RENDER_SDLUTIL_HH__
|
|
|
|
namespace render {
|
|
|
|
class SDLException : public Exception {
|
|
public:
|
|
SDLException() : Exception(SDL_GetError()) {
|
|
}
|
|
|
|
std::string toString() const override {
|
|
return "SDLException: " + msg_;
|
|
}
|
|
};
|
|
|
|
class TTFException : public Exception {
|
|
public:
|
|
TTFException() : Exception(TTF_GetError()) {
|
|
}
|
|
|
|
std::string toString() const override {
|
|
return "TTFException: " + msg_;
|
|
}
|
|
};
|
|
|
|
// Some helpers to C++11-ify SDL
|
|
|
|
struct SDLSurfaceDeleter {
|
|
void operator()(SDL_Surface *ptr) const {
|
|
SDL_FreeSurface(ptr);
|
|
}
|
|
};
|
|
|
|
using SDLSurfaceUPtr = std::unique_ptr<SDL_Surface, SDLSurfaceDeleter>;
|
|
|
|
struct SDLWindowDeleter {
|
|
void operator()(SDL_Window *ptr) const {
|
|
SDL_DestroyWindow(ptr);
|
|
}
|
|
};
|
|
|
|
using SDLWindowUPtr = std::unique_ptr<SDL_Window, SDLWindowDeleter>;
|
|
|
|
struct TTFFontDeleter {
|
|
void operator()(TTF_Font* font) const {
|
|
TTF_CloseFont(font);
|
|
}
|
|
};
|
|
|
|
using TTFFontUPtr = std::unique_ptr<TTF_Font, TTFFontDeleter>;
|
|
|
|
|
|
class SDLSurfaceScopedLock {
|
|
public:
|
|
SDLSurfaceScopedLock(SDL_Surface *surf) : surf_(surf) {
|
|
if (SDL_MUSTLOCK(surf_))
|
|
if (SDL_LockSurface(surf_) != 0)
|
|
throw SDLException{};
|
|
}
|
|
|
|
SDLSurfaceScopedLock(SDLSurfaceUPtr& surf) : surf_(surf.get()) {
|
|
if (SDL_MUSTLOCK(surf_))
|
|
if (SDL_LockSurface(surf_) != 0)
|
|
throw SDLException{};
|
|
}
|
|
|
|
SDLSurfaceScopedLock(SDLSurfaceScopedLock const& copy) = delete;
|
|
SDLSurfaceScopedLock& operator=(SDLSurfaceScopedLock const& copy) = delete;
|
|
|
|
~SDLSurfaceScopedLock() {
|
|
if (surf_ && SDL_MUSTLOCK(surf_))
|
|
SDL_UnlockSurface(surf_);
|
|
}
|
|
|
|
void unlock() {
|
|
if (surf_ && SDL_MUSTLOCK(surf_))
|
|
SDL_UnlockSurface(surf_);
|
|
surf_ = nullptr;
|
|
}
|
|
|
|
private:
|
|
SDL_Surface *surf_;
|
|
};
|
|
|
|
static bool operator==(SDL_Color const& a, SDL_Color const& b) {
|
|
return ((a.r == b.r) && (a.g == b.g) && (a.b == b.b) && (a.a == b.a));
|
|
}
|
|
|
|
static bool operator!=(SDL_Color const& a, SDL_Color const& b) {
|
|
return ((a.r != b.r) || (a.g != b.g) || (a.b != b.b) || (a.a != b.a));
|
|
}
|
|
|
|
// RAII wrapper for SDL_Init
|
|
class SDLInit {
|
|
public:
|
|
SDLInit(uint32_t flags = SDL_INIT_VIDEO) {
|
|
if (SDL_Init(flags) < 0)
|
|
throw SDLException{};
|
|
}
|
|
|
|
SDLInit(SDLInit const& copy) = delete;
|
|
SDLInit& operator=(SDLInit const& copy) = delete;
|
|
|
|
~SDLInit() {
|
|
SDL_Quit();
|
|
}
|
|
};
|
|
|
|
// RAII wrapper for TTF_Init
|
|
class TTFInit {
|
|
public:
|
|
TTFInit() {
|
|
if (TTF_Init() < 0)
|
|
throw TTFException{};
|
|
}
|
|
|
|
TTFInit(TTFInit const& copy) = delete;
|
|
TTFInit& operator=(TTFInit const& copy) = delete;
|
|
|
|
~TTFInit() {
|
|
TTF_Quit();
|
|
}
|
|
};
|
|
|
|
|
|
// RAII wrapper for SDL_GLContext
|
|
class SDLGLContext {
|
|
public:
|
|
SDLGLContext(SDL_Window *win)
|
|
: context_(SDL_GL_CreateContext(win)) {
|
|
if (!context_)
|
|
throw SDLException{};
|
|
}
|
|
|
|
SDLGLContext()
|
|
: context_(nullptr) {
|
|
}
|
|
|
|
SDLGLContext(SDLGLContext const& copy) = delete;
|
|
SDLGLContext& operator=(SDLGLContext const& copy) = delete;
|
|
|
|
SDLGLContext(SDLGLContext && move):
|
|
context_(move.context_) {
|
|
move.context_ = nullptr;
|
|
}
|
|
|
|
SDLGLContext& operator=(SDLGLContext && move) {
|
|
if (context_)
|
|
SDL_GL_DeleteContext(context_);
|
|
context_ = move.context_;
|
|
move.context_ = nullptr;
|
|
|
|
return *this;
|
|
}
|
|
|
|
~SDLGLContext() {
|
|
if (context_)
|
|
SDL_GL_DeleteContext(context_);
|
|
}
|
|
|
|
operator SDL_GLContext() const {
|
|
return context_;
|
|
}
|
|
private:
|
|
SDL_GLContext context_;
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|