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 <SDL.h>
7#include <algorithm>
8#include <memory>
9#include <new>
10#include <cassert>
11#include <cstdlib>
12
34{
35public:
36 SDLSurfacePtr(const SDLSurfacePtr&) = delete;
38
41 SDLSurfacePtr(unsigned width, unsigned height, unsigned depth,
42 Uint32 rMask, Uint32 gMask, Uint32 bMask, Uint32 aMask)
43 {
44 assert((depth % 8) == 0);
45 unsigned pitch = width * (depth >> 3);
46 unsigned size = height * pitch;
47 buffer.resize(size);
48 surface = SDL_CreateRGBSurfaceFrom(
49 buffer.data(), width, height, depth, pitch,
50 rMask, gMask, bMask, aMask);
51 if (!surface) throw std::bad_alloc();
52 }
53
54 explicit SDLSurfacePtr(SDL_Surface* surface_ = nullptr)
55 : surface(surface_)
56 {
57 }
58
59 SDLSurfacePtr(SDLSurfacePtr&& other) noexcept
60 : surface(other.surface)
61 , buffer(std::move(other.buffer))
62 {
63 other.surface = nullptr;
64 }
65
67 {
68 if (surface) SDL_FreeSurface(surface);
69 }
70
71 void reset(SDL_Surface* surface_ = nullptr)
72 {
73 SDLSurfacePtr temp(surface_);
74 temp.swap(*this);
75 }
76
77 [[nodiscard]] SDL_Surface* get()
78 {
79 return surface;
80 }
81 [[nodiscard]] const SDL_Surface* get() const
82 {
83 return surface;
84 }
85
86 void swap(SDLSurfacePtr& other) noexcept
87 {
88 std::swap(surface, other.surface);
89 std::swap(buffer, other.buffer );
90 }
91
93 {
94 std::swap(surface, other.surface);
95 std::swap(buffer, other.buffer);
96 return *this;
97 }
98
99 [[nodiscard]] SDL_Surface& operator*()
100 {
101 return *surface;
102 }
103 [[nodiscard]] const SDL_Surface& operator*() const
104 {
105 return *surface;
106 }
107
108 [[nodiscard]] SDL_Surface* operator->()
109 {
110 return surface;
111 }
112 [[nodiscard]] const SDL_Surface* operator->() const
113 {
114 return surface;
115 }
116
117 [[nodiscard]] explicit operator bool() const
118 {
119 return get() != nullptr;
120 }
121
122 [[nodiscard]] void* getLinePtr(unsigned y)
123 {
124 assert(y < unsigned(surface->h));
125 return static_cast<Uint8*>(surface->pixels) + y * surface->pitch;
126 }
127 [[nodiscard]] const void* getLinePtr(unsigned y) const
128 {
129 return const_cast<SDLSurfacePtr*>(this)->getLinePtr(y);
130 }
131
132private:
133 SDL_Surface* surface;
135};
136
137
139 void operator()(SDL_Texture* t) { SDL_DestroyTexture(t); }
140};
141using SDLTexturePtr = std::unique_ptr<SDL_Texture, SDLDestroyTexture>;
142
143
145 void operator()(SDL_Renderer* r) { SDL_DestroyRenderer(r); }
146};
147using SDLRendererPtr = std::unique_ptr<SDL_Renderer, SDLDestroyRenderer>;
148
149
151 void operator()(SDL_Window* w) { SDL_DestroyWindow(w); }
152};
153using SDLWindowPtr = std::unique_ptr<SDL_Window, SDLDestroyWindow>;
154
155
157 void operator()(SDL_PixelFormat* p) { SDL_FreeFormat(p); }
158};
159using SDLAllocFormatPtr = std::unique_ptr<SDL_PixelFormat, SDLFreeFormat>;
160
161
163 void operator()(Uint8* w) { SDL_FreeWAV(w); }
164};
165using SDLWavPtr = std::unique_ptr<Uint8, SDLFreeWav>;
166
167
168template<Uint32 FLAGS>
170{
171public:
174
176 // SDL internally ref-counts sub-system initialization, so we
177 // don't need to worry about it here.
178 if (SDL_InitSubSystem(FLAGS) < 0) {
180 "SDL init failed (", FLAGS, "): ", SDL_GetError());
181 }
182 }
184 SDL_QuitSubSystem(FLAGS);
185 }
186};
187
188#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.
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 swap(openmsx::MemBuffer< T > &l, openmsx::MemBuffer< T > &r) noexcept
Definition: MemBuffer.hh:202
size_t size(std::string_view utf8)
void operator()(SDL_Renderer *r)
void operator()(SDL_Texture *t)
void operator()(SDL_Window *w)
void operator()(SDL_PixelFormat *p)
void operator()(Uint8 *w)