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  unsigned getWidth() const { return surface->w; }
24  unsigned getHeight() const { return surface->h; }
26 
27  int getX() const { return xOffset; }
28  int getY() const { return yOffset; }
29 
30  const SDL_PixelFormat& getSDLFormat() const { return format; }
31  SDL_Surface* getSDLSurface() const { return surface; }
32  SDL_Renderer* getSDLRenderer() const { return renderer; }
33 
38  unsigned mapRGB(gl::vec3 rgb)
39  {
40  return mapRGB255(gl::ivec3(rgb * 255.0f));
41  }
42 
45  unsigned mapRGB255(gl::ivec3 rgb)
46  {
47  return SDL_MapRGB(&format, rgb[0], rgb[1], rgb[2]); // alpha is fully opaque
48  }
49 
52  template<typename Pixel> inline Pixel getKeyColor() const
53  {
54  return sizeof(Pixel) == 2
55  ? 0x0001 // lowest bit of 'some' color component is set
56  : 0x00000000; // alpha = 0
57  }
58 
63  template<typename Pixel> inline Pixel getKeyColorClash() const
64  {
65  assert(sizeof(Pixel) != 4); // shouldn't get clashes in 32bpp
66  return 0; // is visually very close, practically
67  // indistinguishable, from the actual KeyColor
68  }
69 
74  template<typename Pixel> Pixel mapKeyedRGB255(gl::ivec3 rgb)
75  {
76  Pixel p = mapRGB255(rgb);
77  if (sizeof(Pixel) == 2) {
78  return (p != getKeyColor<Pixel>())
79  ? p
80  : getKeyColorClash<Pixel>();
81  } else {
82  assert(p != getKeyColor<Pixel>());
83  return p;
84  }
85  }
86 
91  template<typename Pixel> Pixel mapKeyedRGB(gl::vec3 rgb)
92  {
93  return mapKeyedRGB255<Pixel>(gl::ivec3(rgb * 255.0f));
94  }
95 
100  void lock();
101 
105  void unlock();
106 
109  bool isLocked() const { return locked; }
110 
115  template <typename Pixel>
116  Pixel* getLinePtrDirect(unsigned y) {
117  assert(isLocked());
118  return reinterpret_cast<Pixel*>(data + y * pitch);
119  }
120 
124  virtual void flushFrameBuffer();
125 
129  virtual void saveScreenshot(const std::string& filename) = 0;
130 
133  virtual void clearScreen() = 0;
134 
135 protected:
136  OutputSurface() = default;
137 
138  void setPosition(int x, int y);
139  void setSDLSurface(SDL_Surface* surface_) { surface = surface_; }
140  void setSDLRenderer(SDL_Renderer* r) { renderer = r; }
141  void setSDLFormat(const SDL_PixelFormat& format);
142  void setBufferPtr(char* data, unsigned pitch);
143 
144 private:
145  SDL_Surface* surface = nullptr;
146  SDL_Renderer* renderer = nullptr;
147  SDL_PixelFormat format;
148  char* data;
149  unsigned pitch;
150  int xOffset = 0, yOffset = 0;
151 
152  bool locked = false;
153 
154  friend class SDLGLOutputSurface; // for setBufferPtr()
155 };
156 
157 } // namespace openmsx
158 
159 #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 getWidth() const
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
A frame buffer where pixels can be written to.
uint32_t Pixel
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.
virtual void flushFrameBuffer()
For SDLGL-FB-nn, copy frame buffer to OpenGL display.
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
vecN< 2, int > ivec2
Definition: gl_vec.hh:142
unsigned mapRGB(gl::vec3 rgb)
Returns the pixel value for the given RGB color.
SDL_Surface * getSDLSurface() const
void setPosition(int x, int y)
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.
gl::ivec2 getOutputSize() const
void unlock()
Unlock this OutputSurface.
void setSDLRenderer(SDL_Renderer *r)
unsigned getHeight() const
void setSDLSurface(SDL_Surface *surface_)
Pixel getKeyColor() const
Returns the color key for this output surface.
bool isLocked() const
Is this OutputSurface currently locked?
const SDL_PixelFormat & getSDLFormat() const