openMSX
SDLSurfacePtr.hh
Go to the documentation of this file.
1#ifndef SDLSURFACEPTR_HH
2#define SDLSURFACEPTR_HH
3
4#include "MemBuffer.hh"
5#include "InitException.hh"
6#include "narrow.hh"
7#include <SDL.h>
8#include <algorithm>
9#include <memory>
10#include <new>
11#include <cassert>
12#include <cstdlib>
13
35{
36public:
37 SDLSurfacePtr(const SDLSurfacePtr&) = delete;
39
42 SDLSurfacePtr(unsigned width, unsigned height, unsigned depth,
43 Uint32 rMask, Uint32 gMask, Uint32 bMask, Uint32 aMask)
44 {
45 assert((depth % 8) == 0);
46 unsigned pitch = width * (depth >> 3);
47 unsigned size = height * pitch;
48 buffer.resize(size);
49 surface = SDL_CreateRGBSurfaceFrom(
50 buffer.data(),
51 narrow<int>(width), narrow<int>(height),
52 narrow<int>(depth), narrow<int>(pitch),
53 rMask, gMask, bMask, aMask);
54 if (!surface) throw std::bad_alloc();
55 }
56
57 explicit SDLSurfacePtr(SDL_Surface* surface_ = nullptr)
58 : surface(surface_)
59 {
60 }
61
62 SDLSurfacePtr(SDLSurfacePtr&& other) noexcept
63 : surface(other.surface)
64 , buffer(std::move(other.buffer))
65 {
66 other.surface = nullptr;
67 }
68
70 {
71 if (surface) SDL_FreeSurface(surface);
72 }
73
74 void reset(SDL_Surface* surface_ = nullptr)
75 {
76 SDLSurfacePtr temp(surface_);
77 temp.swap(*this);
78 }
79
80 [[nodiscard]] SDL_Surface* get()
81 {
82 return surface;
83 }
84 [[nodiscard]] const SDL_Surface* get() const
85 {
86 return surface;
87 }
88
89 void swap(SDLSurfacePtr& other) noexcept
90 {
91 std::swap(surface, other.surface);
92 std::swap(buffer, other.buffer );
93 }
94
96 {
97 std::swap(surface, other.surface);
98 std::swap(buffer, other.buffer);
99 return *this;
100 }
101
102 [[nodiscard]] SDL_Surface& operator*()
103 {
104 return *surface;
105 }
106 [[nodiscard]] const SDL_Surface& operator*() const
107 {
108 return *surface;
109 }
110
111 [[nodiscard]] SDL_Surface* operator->()
112 {
113 return surface;
114 }
115 [[nodiscard]] const SDL_Surface* operator->() const
116 {
117 return surface;
118 }
119
120 [[nodiscard]] explicit operator bool() const
121 {
122 return get() != nullptr;
123 }
124
125 [[nodiscard]] void* getLinePtr(unsigned y)
126 {
127 assert(y < unsigned(surface->h));
128 return static_cast<Uint8*>(surface->pixels) + y * surface->pitch;
129 }
130 [[nodiscard]] const void* getLinePtr(unsigned y) const
131 {
132 return const_cast<SDLSurfacePtr*>(this)->getLinePtr(y);
133 }
134
135private:
136 SDL_Surface* surface;
138};
139
140
142 void operator()(SDL_Texture* t) { SDL_DestroyTexture(t); }
143};
144using SDLTexturePtr = std::unique_ptr<SDL_Texture, SDLDestroyTexture>;
145
146
148 void operator()(SDL_Renderer* r) { SDL_DestroyRenderer(r); }
149};
150using SDLRendererPtr = std::unique_ptr<SDL_Renderer, SDLDestroyRenderer>;
151
152
154 void operator()(SDL_Window* w) { SDL_DestroyWindow(w); }
155};
156using SDLWindowPtr = std::unique_ptr<SDL_Window, SDLDestroyWindow>;
157
158
160 void operator()(SDL_PixelFormat* p) { SDL_FreeFormat(p); }
161};
162using SDLAllocFormatPtr = std::unique_ptr<SDL_PixelFormat, SDLFreeFormat>;
163
164
166 void operator()(Uint8* w) { SDL_FreeWAV(w); }
167};
168using SDLWavPtr = std::unique_ptr<Uint8, SDLFreeWav>;
169
170
171template<Uint32 FLAGS>
173{
174public:
177
179 // SDL internally ref-counts sub-system initialization, so we
180 // don't need to worry about it here.
181 if (SDL_InitSubSystem(FLAGS) < 0) {
183 "SDL init failed (", FLAGS, "): ", SDL_GetError());
184 }
185 }
187 SDL_QuitSubSystem(FLAGS);
188 }
189};
190
191#endif
std::unique_ptr< SDL_PixelFormat, SDLFreeFormat > SDLAllocFormatPtr
std::unique_ptr< SDL_Window, SDLDestroyWindow > SDLWindowPtr
std::unique_ptr< Uint8, SDLFreeWav > SDLWavPtr
std::unique_ptr< SDL_Renderer, SDLDestroyRenderer > SDLRendererPtr
std::unique_ptr< SDL_Texture, SDLDestroyTexture > SDLTexturePtr
TclObject t
SDLSubSystemInitializer & operator=(const SDLSubSystemInitializer &)=delete
SDLSubSystemInitializer(const SDLSubSystemInitializer &)=delete
Wrapper around a SDL_Surface.
void reset(SDL_Surface *surface_=nullptr)
const void * getLinePtr(unsigned y) const
SDLSurfacePtr & operator=(SDLSurfacePtr &&other) noexcept
SDL_Surface & operator*()
SDL_Surface * get()
const SDL_Surface * operator->() const
SDLSurfacePtr & operator=(const SDLSurfacePtr &)=delete
const SDL_Surface & operator*() const
SDL_Surface * operator->()
SDLSurfacePtr(SDLSurfacePtr &&other) noexcept
SDLSurfacePtr(SDL_Surface *surface_=nullptr)
SDLSurfacePtr(const SDLSurfacePtr &)=delete
SDLSurfacePtr(unsigned width, unsigned height, unsigned depth, Uint32 rMask, Uint32 gMask, Uint32 bMask, Uint32 aMask)
Create a (software) surface with uninitialized pixel content.
void swap(SDLSurfacePtr &other) noexcept
const SDL_Surface * get() const
void * getLinePtr(unsigned y)
Thrown when a subsystem initialisation fails.
This class manages the lifetime of a block of memory.
Definition MemBuffer.hh:29
void resize(size_t size)
Grow or shrink the memory block.
Definition MemBuffer.hh:111
const T * data() const
Returns pointer to the start of the memory buffer.
Definition MemBuffer.hh:81
void operator()(SDL_Renderer *r)
void operator()(SDL_Texture *t)
void operator()(SDL_Window *w)
void operator()(SDL_PixelFormat *p)
void operator()(Uint8 *w)