openMSX
OutputSurface.hh
Go to the documentation of this file.
1 #ifndef OUTPUTSURFACE_HH
2 #define OUTPUTSURFACE_HH
3 
4 #include "gl_vec.hh"
5 #include <string>
6 #include <cassert>
7 #include <SDL.h>
8 
9 namespace openmsx {
10 
16 {
17 public:
18  OutputSurface(const OutputSurface&) = delete;
19  OutputSurface& operator=(const OutputSurface&) = delete;
20 
21  virtual ~OutputSurface() = default;
22 
23  int getWidth() const { return surface->w; }
24  int getHeight() const { return surface->h; }
25  gl::ivec2 getLogicalSize() const { return {getWidth(), getHeight()}; }
26  gl::ivec2 getPhysicalSize() const { return m_physSize; }
27 
28  gl::ivec2 getViewOffset() const { return m_viewOffset; }
29  gl::ivec2 getViewSize() const { return m_viewSize; }
30  gl::vec2 getViewScale() const { return m_viewScale; }
31  bool isViewScaled() const { return m_viewScale != gl::vec2(1.0f); }
32 
33  const SDL_PixelFormat& getSDLFormat() const { return format; }
34  SDL_Surface* getSDLSurface() const { return surface; }
35  SDL_Renderer* getSDLRenderer() const { return renderer; }
36 
41  unsigned mapRGB(gl::vec3 rgb)
42  {
43  return mapRGB255(gl::ivec3(rgb * 255.0f));
44  }
45 
48  unsigned mapRGB255(gl::ivec3 rgb)
49  {
50  return SDL_MapRGB(&format, rgb[0], rgb[1], rgb[2]); // alpha is fully opaque
51  }
52 
55  template<typename Pixel> inline Pixel getKeyColor() const
56  {
57  return sizeof(Pixel) == 2
58  ? 0x0001 // lowest bit of 'some' color component is set
59  : 0x00000000; // alpha = 0
60  }
61 
66  template<typename Pixel> inline Pixel getKeyColorClash() const
67  {
68  assert(sizeof(Pixel) != 4); // shouldn't get clashes in 32bpp
69  return 0; // is visually very close, practically
70  // indistinguishable, from the actual KeyColor
71  }
72 
77  template<typename Pixel> Pixel mapKeyedRGB255(gl::ivec3 rgb)
78  {
79  Pixel p = mapRGB255(rgb);
80  if (sizeof(Pixel) == 2) {
81  return (p != getKeyColor<Pixel>())
82  ? p
83  : getKeyColorClash<Pixel>();
84  } else {
85  assert(p != getKeyColor<Pixel>());
86  return p;
87  }
88  }
89 
94  template<typename Pixel> Pixel mapKeyedRGB(gl::vec3 rgb)
95  {
96  return mapKeyedRGB255<Pixel>(gl::ivec3(rgb * 255.0f));
97  }
98 
103  void lock();
104 
108  void unlock();
109 
112  bool isLocked() const { return locked; }
113 
118  template <typename Pixel>
119  Pixel* getLinePtrDirect(unsigned y) {
120  assert(isLocked());
121  return reinterpret_cast<Pixel*>(data + y * pitch);
122  }
123 
127  virtual void flushFrameBuffer();
128 
132  virtual void saveScreenshot(const std::string& filename) = 0;
133 
136  virtual void clearScreen() = 0;
137 
138 protected:
139  OutputSurface() = default;
140 
141  void calculateViewPort(gl::ivec2 physSize);
142  void setSDLSurface(SDL_Surface* surface_) { surface = surface_; }
143  void setSDLRenderer(SDL_Renderer* r) { renderer = r; }
144  void setSDLFormat(const SDL_PixelFormat& format);
145  void setBufferPtr(char* data, unsigned pitch);
146 
147 private:
148  SDL_Surface* surface = nullptr;
149  SDL_Renderer* renderer = nullptr;
150  SDL_PixelFormat format;
151  char* data;
152  unsigned pitch;
153  gl::ivec2 m_physSize;
154  gl::ivec2 m_viewOffset;
155  gl::ivec2 m_viewSize;
156  gl::vec2 m_viewScale{1.0f};
157 
158  bool locked = false;
159 
160  friend class SDLGLOutputSurface; // for setBufferPtr()
161 };
162 
163 } // namespace openmsx
164 
165 #endif
virtual ~OutputSurface()=default
void lock()
Lock this OutputSurface.
Definition: OutputSurface.cc:7
SDL_Renderer * getSDLRenderer() const
Pixel mapKeyedRGB255(gl::ivec3 rgb)
Returns the pixel value for the given RGB color.
void setBufferPtr(char *data, unsigned pitch)
unsigned mapRGB255(gl::ivec3 rgb)
Same as mapRGB, but RGB components are in range [0..255].
Pixel mapKeyedRGB(gl::vec3 rgb)
Returns the pixel value for the given RGB color.
virtual void clearScreen()=0
Clear screen (paint it black).
OutputSurface & operator=(const OutputSurface &)=delete
gl::ivec2 getLogicalSize() const
A frame buffer where pixels can be written to.
uint32_t Pixel
gl::ivec2 getViewSize() const
gl::vec2 getViewScale() const
vecN< 3, int > ivec3
Definition: gl_vec.hh:143
void setSDLFormat(const SDL_PixelFormat &format)
Pixel getKeyColorClash() const
Returns a color that is visually very close to the key color.
bool isViewScaled() const
virtual void flushFrameBuffer()
For SDLGL-FB-nn, copy frame buffer to OpenGL display.
gl::ivec2 getViewOffset() const
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
unsigned mapRGB(gl::vec3 rgb)
Returns the pixel value for the given RGB color.
SDL_Surface * getSDLSurface() const
virtual void saveScreenshot(const std::string &filename)=0
Save the content of this OutputSurface to a PNG file.
Pixel * getLinePtrDirect(unsigned y)
Returns a pointer to the requested line in the pixel buffer.
This is a common base class for SDLGLVisibleSurface and SDLGLOffScreenSurface.
void unlock()
Unlock this OutputSurface.
void setSDLRenderer(SDL_Renderer *r)
void calculateViewPort(gl::ivec2 physSize)
vecN< 2, float > vec2
Definition: gl_vec.hh:139
void setSDLSurface(SDL_Surface *surface_)
gl::ivec2 getPhysicalSize() const
Pixel getKeyColor() const
Returns the color key for this output surface.
bool isLocked() const
Is this OutputSurface currently locked?
const SDL_PixelFormat & getSDLFormat() const