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 {
35 public:
36  SDLSurfacePtr(const SDLSurfacePtr&) = delete;
37  SDLSurfacePtr& operator=(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  SDL_Surface* get()
78  {
79  return surface;
80  }
81  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  SDL_Surface& operator*()
100  {
101  return *surface;
102  }
103  const SDL_Surface& operator*() const
104  {
105  return *surface;
106  }
107 
108  SDL_Surface* operator->()
109  {
110  return surface;
111  }
112  const SDL_Surface* operator->() const
113  {
114  return surface;
115  }
116 
117  explicit operator bool() const
118  {
119  return get() != nullptr;
120  }
121 
122  void* getLinePtr(unsigned y)
123  {
124  assert(y < unsigned(surface->h));
125  return static_cast<Uint8*>(surface->pixels) + y * surface->pitch;
126  }
127  const void* getLinePtr(unsigned y) const
128  {
129  return const_cast<SDLSurfacePtr*>(this)->getLinePtr(y);
130  }
131 
132 private:
133  SDL_Surface* surface;
135 };
136 
137 
139  void operator()(SDL_Texture* t) { SDL_DestroyTexture(t); }
140 };
141 using SDLTexturePtr = std::unique_ptr<SDL_Texture, SDLDestroyTexture>;
142 
143 
145  void operator()(SDL_Renderer* r) { SDL_DestroyRenderer(r); }
146 };
147 using SDLRendererPtr = std::unique_ptr<SDL_Renderer, SDLDestroyRenderer>;
148 
149 
151  void operator()(SDL_Window* w) { SDL_DestroyWindow(w); }
152 };
153 using SDLWindowPtr = std::unique_ptr<SDL_Window, SDLDestroyWindow>;
154 
155 
157  void operator()(SDL_PixelFormat* p) { SDL_FreeFormat(p); }
158 };
159 using SDLAllocFormatPtr = std::unique_ptr<SDL_PixelFormat, SDLFreeFormat>;
160 
161 
162 struct SDLFreeWav {
163  void operator()(Uint8* w) { SDL_FreeWAV(w); }
164 };
165 using SDLWavPtr = std::unique_ptr<Uint8, SDLFreeWav>;
166 
167 
168 template<Uint32 FLAGS>
170 {
171 public:
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
void operator()(SDL_Texture *t)
void swap(SDLSurfacePtr &other) noexcept
void operator()(SDL_Renderer *r)
void * getLinePtr(unsigned y)
SDLSurfacePtr & operator=(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.
std::unique_ptr< Uint8, SDLFreeWav > SDLWavPtr
void reset(SDL_Surface *surface_=nullptr)
std::unique_ptr< SDL_Renderer, SDLDestroyRenderer > SDLRendererPtr
SDL_Surface * operator->()
std::unique_ptr< SDL_PixelFormat, SDLFreeFormat > SDLAllocFormatPtr
void operator()(SDL_PixelFormat *p)
size_t size(std::string_view utf8)
Wrapper around a SDL_Surface.
void resize(size_t size)
Grow or shrink the memory block.
Definition: MemBuffer.hh:120
const T * data() const
Returns pointer to the start of the memory buffer.
Definition: MemBuffer.hh:90
SDLSurfacePtr(const SDLSurfacePtr &)=delete
const SDL_Surface & operator*() const
std::unique_ptr< SDL_Window, SDLDestroyWindow > SDLWindowPtr
SDLSurfacePtr(SDL_Surface *surface_=nullptr)
const void * getLinePtr(unsigned y) const
SDL_Surface & operator*()
SDLSurfacePtr(SDLSurfacePtr &&other) noexcept
Thrown when a subsystem initialisation fails.
void operator()(Uint8 *w)
SDLSurfacePtr & operator=(SDLSurfacePtr &&other) noexcept
const SDL_Surface * operator->() const
std::unique_ptr< SDL_Texture, SDLDestroyTexture > SDLTexturePtr
void operator()(SDL_Window *w)
TclObject t