openMSX
FrameSource.hh
Go to the documentation of this file.
1 #ifndef FRAMESOURCE_HH
2 #define FRAMESOURCE_HH
3 
4 #include "aligned.hh"
5 #include <algorithm>
6 #include <cassert>
7 
8 struct SDL_PixelFormat;
9 
10 namespace openmsx {
11 
15 {
16 public:
19  enum FieldType {
29  };
30 
34  void init(FieldType fieldType_) { fieldType = fieldType_; }
35 
38  FieldType getField() const {
39  return fieldType;
40  }
41 
44  unsigned getHeight() const {
45  return height;
46  }
47 
51  virtual unsigned getLineWidth(unsigned line) const = 0;
52 
59  unsigned getWidth() const {
60  assert(height > 0);
61  unsigned result = getLineWidth(0);
62  for (unsigned line = 1; line < height; ++line) {
63  assert(result == getLineWidth(line));
64  }
65  return result;
66  }
67 
73  template <typename Pixel>
74  inline Pixel getLineColor(unsigned line) const {
75  alignas(SSE_ALIGNMENT) Pixel buf[1280]; // large enough for widest line
76  unsigned width; // not used
77  return reinterpret_cast<const Pixel*>(
78  getLineInfo(line, width, buf, 1280))[0];
79  }
80 
90  template <typename Pixel>
91  inline const Pixel* getLinePtr(int line, unsigned width, Pixel* buf) const
92  {
93  line = std::min<unsigned>(std::max(0, line), getHeight() - 1);
94  unsigned internalWidth;
95  auto* internalData = reinterpret_cast<const Pixel*>(
96  getLineInfo(line, internalWidth, buf, width));
97  if (internalWidth == width) {
98  return internalData;
99  } else {
100  // slow path, non-inlined
101  // internalData might be equal to buf
102  scaleLine(internalData, buf, internalWidth, width);
103  return buf;
104  }
105  }
106 
112  template <typename Pixel>
113  inline const Pixel* getMultiLinePtr(
114  int line, unsigned numLines, unsigned& actualLines,
115  unsigned width, Pixel* buf) const
116  {
117  actualLines = 1;
118  if ((line < 0) || (int(height) <= line)) {
119  return getLinePtr(line, width, buf);
120  }
121  unsigned internalWidth;
122  auto* internalData = reinterpret_cast<const Pixel*>(
123  getLineInfo(line, internalWidth, buf, width));
124  if (internalWidth != width) {
125  scaleLine(internalData, buf, internalWidth, width);
126  return buf;
127  }
128  if (!hasContiguousStorage()) {
129  return internalData;
130  }
131  while (--numLines) {
132  ++line;
133  if ((line == int(height)) || (getLineWidth(line) != width)) {
134  break;
135  }
136  ++actualLines;
137  }
138  return internalData;
139  }
140 
154  virtual const void* getLineInfo(
155  unsigned line, unsigned& lineWidth,
156  void* buf, unsigned bufWidth) const = 0;
157 
163  template <typename Pixel>
164  const Pixel* getLinePtr320_240(unsigned line, Pixel* buf) const;
165 
170  template <typename Pixel>
171  const Pixel* getLinePtr640_480(unsigned line, Pixel* buf) const;
172 
177  template <typename Pixel>
178  const Pixel* getLinePtr960_720(unsigned line, Pixel* buf) const;
179 
186  virtual unsigned getRowLength() const {
187  return 0;
188  }
189 
190  const SDL_PixelFormat& getSDLPixelFormat() const {
191  return pixelFormat;
192  }
193 
194 protected:
195  explicit FrameSource(const SDL_PixelFormat& format);
196  ~FrameSource() = default;
197 
198  void setHeight(unsigned height_) { height = height_; }
199 
203  virtual bool hasContiguousStorage() const {
204  return false;
205  }
206 
207  template <typename Pixel> void scaleLine(
208  const Pixel* in, Pixel* out,
209  unsigned inWidth, unsigned outWidth) const;
210 
211 private:
214  const SDL_PixelFormat& pixelFormat;
215 
218  unsigned height;
219 
220  FieldType fieldType;
221 };
222 
223 } // namespace openmsx
224 
225 #endif // FRAMESOURCE_HH
void init(FieldType fieldType_)
(Re)initialize an existing FrameSource.
Definition: FrameSource.hh:34
Pixel getLineColor(unsigned line) const
Get the (single) color of the given line.
Definition: FrameSource.hh:74
Interlacing is on and this is an odd frame.
Definition: FrameSource.hh:28
FieldType getField() const
Gets the role this frame plays in interlacing.
Definition: FrameSource.hh:38
unsigned getWidth() const
Get the width of (all) lines in this frame.
Definition: FrameSource.hh:59
uint32_t Pixel
vecN< N, T > max(const vecN< N, T > &x, const vecN< N, T > &y)
Definition: gl_vec.hh:287
const Pixel * getMultiLinePtr(int line, unsigned numLines, unsigned &actualLines, unsigned width, Pixel *buf) const
Similar to the above getLinePtr() method, but now tries to get multiple lines at once.
Definition: FrameSource.hh:113
Interface for getting lines from a video frame.
Definition: FrameSource.hh:14
constexpr auto SSE_ALIGNMENT
Definition: aligned.hh:14
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
Interlacing is on and this is an even frame.
Definition: FrameSource.hh:25
void scaleLine(const Pixel *in, Pixel *out, unsigned inWidth, unsigned outWidth) const
Definition: FrameSource.cc:70
virtual bool hasContiguousStorage() const
Returns true when two consecutive rows are also consecutive in memory.
Definition: FrameSource.hh:203
const Pixel * getLinePtr640_480(unsigned line, Pixel *buf) const
Get a pointer to a given line in this frame, the frame is scaled to 640x480 pixels.
Definition: FrameSource.cc:38
Interlacing is off for this frame.
Definition: FrameSource.hh:22
const Pixel * getLinePtr(int line, unsigned width, Pixel *buf) const
Gets a pointer to the pixels of the given line number.
Definition: FrameSource.hh:91
FieldType
What role does this frame play in interlacing?
Definition: FrameSource.hh:19
void format(SectorAccessibleDisk &disk, bool dos1)
Format the given disk (= a single partition).
void setHeight(unsigned height_)
Definition: FrameSource.hh:198
virtual const void * getLineInfo(unsigned line, unsigned &lineWidth, void *buf, unsigned bufWidth) const =0
Abstract implementation of getLinePtr().
const Pixel * getLinePtr320_240(unsigned line, Pixel *buf) const
Get a pointer to a given line in this frame, the frame is scaled to 320x240 pixels.
Definition: FrameSource.cc:21
virtual unsigned getLineWidth(unsigned line) const =0
Gets the number of display pixels on the given line.
virtual unsigned getRowLength() const
Returns the distance (in pixels) between two consecutive lines.
Definition: FrameSource.hh:186
const Pixel * getLinePtr960_720(unsigned line, Pixel *buf) const
Get a pointer to a given line in this frame, the frame is scaled to 960x720 pixels.
Definition: FrameSource.cc:49
unsigned getHeight() const
Gets the number of lines in this frame.
Definition: FrameSource.hh:44
const SDL_PixelFormat & getSDLPixelFormat() const
Definition: FrameSource.hh:190
FrameSource(const SDL_PixelFormat &format)
Definition: FrameSource.cc:15