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:
39 SDLSurfacePtr(unsigned width, unsigned height, unsigned depth,
40 Uint32 rMask, Uint32 gMask, Uint32 bMask, Uint32 aMask)
41 {
42 assert((depth % 8) == 0);
43 unsigned pitch = width * (depth >> 3);
44 unsigned size = height * pitch;
45 buffer.resize(size);
46 surface = SDL_CreateRGBSurfaceFrom(
47 buffer.data(),
48 narrow<int>(width), narrow<int>(height),
49 narrow<int>(depth), narrow<int>(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
66 SDLSurfacePtr(const SDLSurfacePtr&) = delete;
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) const { SDL_DestroyTexture(t); }
143};
144using SDLTexturePtr = std::unique_ptr<SDL_Texture, SDLDestroyTexture>;
145
146
148 void operator()(SDL_Renderer* r) const { SDL_DestroyRenderer(r); }
149};
150using SDLRendererPtr = std::unique_ptr<SDL_Renderer, SDLDestroyRenderer>;
151
152
154 void operator()(SDL_Window* w) const { SDL_DestroyWindow(w); }
155};
156using SDLWindowPtr = std::unique_ptr<SDL_Window, SDLDestroyWindow>;
157
158
160 void operator()(SDL_PixelFormat* p) const { SDL_FreeFormat(p); }
161};
162using SDLAllocFormatPtr = std::unique_ptr<SDL_PixelFormat, SDLFreeFormat>;
163
164
166 void operator()(Uint8* w) const { SDL_FreeWAV(w); }
167};
168using SDLWavPtr = std::unique_ptr<Uint8, SDLFreeWav>;
169
170
171template<Uint32 FLAGS>
173{
174public:
179
181 // SDL internally ref-counts sub-system initialization, so we
182 // don't need to worry about it here.
183 if (SDL_InitSubSystem(FLAGS) < 0) {
185 "SDL init failed (", FLAGS, "): ", SDL_GetError());
186 }
187 }
189 SDL_QuitSubSystem(FLAGS);
190 }
191};
192
193#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=(SDLSubSystemInitializer &&)=delete
SDLSubSystemInitializer(SDLSubSystemInitializer &&)=delete
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) const
void operator()(SDL_Texture *t) const
void operator()(SDL_Window *w) const
void operator()(SDL_PixelFormat *p) const
void operator()(Uint8 *w) const