openMSX
StretchScalerOutput.cc
Go to the documentation of this file.
1 #include "StretchScalerOutput.hh"
2 #include "DirectScalerOutput.hh"
3 #include "LineScalers.hh"
4 #include "PixelOperations.hh"
5 #include "MemoryOps.hh"
6 #include "build-info.hh"
7 #include <cstdint>
8 #include <memory>
9 #include <vector>
10 
11 using std::unique_ptr;
12 
13 namespace openmsx {
14 
15 template<typename Pixel>
17 {
18 public:
21  ~StretchScalerOutputBase() override;
22 
23  unsigned getWidth() const override;
24  unsigned getHeight() const override;
25  Pixel* acquireLine(unsigned y) override;
26  void fillLine (unsigned y, Pixel color) override;
27 
28 protected:
29  Pixel* releasePre(unsigned y, Pixel* buf);
30  void releasePost(unsigned y, Pixel* dstLine);
31 
33 
34 private:
35  unique_ptr<ScalerOutput<Pixel>> output;
36  std::vector<Pixel*> pool;
37 };
38 
39 template<typename Pixel>
41 {
42 public:
43  StretchScalerOutput(unique_ptr<ScalerOutput<Pixel>> output,
45  unsigned inWidth);
46  void releaseLine(unsigned y, Pixel* buf) override;
47 
48 private:
49  unsigned inWidth;
50 };
51 
52 template<typename Pixel, unsigned IN_WIDTH, typename SCALE>
54 {
55 public:
56  StretchScalerOutputN(unique_ptr<ScalerOutput<Pixel>> output,
58  void releaseLine(unsigned y, Pixel* buf) override;
59 };
60 
61 template<typename Pixel>
63  : public StretchScalerOutputN<Pixel, 256, Scale_4on5<Pixel>>
64 {
65 public:
68 };
69 
70 template<typename Pixel>
72  : public StretchScalerOutputN<Pixel, 272, Scale_17on20<Pixel>>
73 {
74 public:
77 };
78 
79 template<typename Pixel>
81  : public StretchScalerOutputN<Pixel, 280, Scale_7on8<Pixel>>
82 {
83 public:
86 };
87 
88 template<typename Pixel>
90  : public StretchScalerOutputN<Pixel, 288, Scale_9on10<Pixel>>
91 {
92 public:
95 };
96 
97 
98 // class StretchScalerOutputBase
99 
100 template<typename Pixel>
102  unique_ptr<ScalerOutput<Pixel>> output_,
103  PixelOperations<Pixel> pixelOps_)
104  : pixelOps(std::move(pixelOps_))
105  , output(std::move(output_))
106 {
107 }
108 
109 template<typename Pixel>
111 {
112  for (auto& p : pool) {
114  }
115 }
116 
117 template<typename Pixel>
119 {
120  return output->getWidth();
121 }
122 
123 template<typename Pixel>
125 {
126  return output->getHeight();
127 }
128 
129 template<typename Pixel>
131 {
132  if (!pool.empty()) {
133  Pixel* buf = pool.back();
134  pool.pop_back();
135  return buf;
136  } else {
137  unsigned size = sizeof(Pixel) * output->getWidth();
138  return static_cast<Pixel*>(MemoryOps::mallocAligned(64, size));
139  }
140 }
141 
142 template<typename Pixel>
144 {
145  pool.push_back(buf);
146  return output->acquireLine(y);
147 }
148 
149 template<typename Pixel>
151 {
152  output->releaseLine(y, dstLine);
153 }
154 
155 template<typename Pixel>
157 {
158  Pixel* dstLine = output->acquireLine(y);
160  memset(dstLine, output->getWidth(), color);
161  output->releaseLine(y, dstLine);
162 }
163 
164 
165 // class StretchScalerOutput
166 
167 template<typename Pixel>
169  unique_ptr<ScalerOutput<Pixel>> output_,
170  PixelOperations<Pixel> pixelOps_,
171  unsigned inWidth_)
172  : StretchScalerOutputBase<Pixel>(std::move(output_), std::move(pixelOps_))
173  , inWidth(inWidth_)
174 {
175 }
176 
177 template<typename Pixel>
179 {
180  Pixel* dstLine = this->releasePre(y, buf);
181 
182  unsigned dstWidth = StretchScalerOutputBase<Pixel>::getWidth();
183  unsigned srcWidth = (dstWidth / 320) * inWidth;
184  unsigned srcOffset = (dstWidth - srcWidth) / 2;
185  ZoomLine<Pixel> zoom(this->pixelOps);
186  zoom(buf + srcOffset, srcWidth, dstLine, dstWidth);
187 
188  this->releasePost(y, dstLine);
189 }
190 
191 
192 // class StretchScalerOutputN
193 
194 template<typename Pixel, unsigned IN_WIDTH, typename SCALE>
196  unique_ptr<ScalerOutput<Pixel>> output_,
197  PixelOperations<Pixel> pixelOps_)
198  : StretchScalerOutputBase<Pixel>(std::move(output_), std::move(pixelOps_))
199 {
200 }
201 
202 template<typename Pixel, unsigned IN_WIDTH, typename SCALE>
204 {
205  Pixel* dstLine = this->releasePre(y, buf);
206 
207  unsigned dstWidth = StretchScalerOutputBase<Pixel>::getWidth();
208  unsigned srcWidth = (dstWidth / 320) * IN_WIDTH;
209  unsigned srcOffset = (dstWidth - srcWidth) / 2;
210  SCALE scale(this->pixelOps);
211  scale(buf + srcOffset, dstLine, dstWidth);
212 
213  this->releasePost(y, dstLine);
214 }
215 
216 
217 // class StretchScalerOutput256
218 
219 template<typename Pixel>
221  unique_ptr<ScalerOutput<Pixel>> output_,
222  PixelOperations<Pixel> pixelOps_)
224  std::move(output_), std::move(pixelOps_))
225 {
226 }
227 
228 
229 // class StretchScalerOutput272
230 
231 template<typename Pixel>
233  unique_ptr<ScalerOutput<Pixel>> output_,
234  PixelOperations<Pixel> pixelOps_)
236  std::move(output_), std::move(pixelOps_))
237 {
238 }
239 
240 
241 // class StretchScalerOutput280
242 
243 template<typename Pixel>
245  unique_ptr<ScalerOutput<Pixel>> output_,
246  PixelOperations<Pixel> pixelOps_)
248  std::move(output_), std::move(pixelOps_))
249 {
250 }
251 
252 
253 // class StretchScalerOutput288
254 
255 template<typename Pixel>
257  unique_ptr<ScalerOutput<Pixel>> output_,
258  PixelOperations<Pixel> pixelOps_)
260  std::move(output_), std::move(pixelOps_))
261 {
262 }
263 
264 
265 // class StretchScalerOutputFactory
266 
267 template<typename Pixel>
268 unique_ptr<ScalerOutput<Pixel>> StretchScalerOutputFactory<Pixel>::create(
269  SDLOutputSurface& output,
270  PixelOperations<Pixel> pixelOps,
271  unsigned inWidth)
272 {
273  auto direct = std::make_unique<DirectScalerOutput<Pixel>>(output);
274  switch (inWidth) {
275  case 320:
276  return direct;
277  case 288:
278  return std::make_unique<StretchScalerOutput288<Pixel>>(
279  std::move(direct), std::move(pixelOps));
280  case 280:
281  return std::make_unique<StretchScalerOutput280<Pixel>>(
282  std::move(direct), std::move(pixelOps));
283  case 272:
284  return std::make_unique<StretchScalerOutput272<Pixel>>(
285  std::move(direct), std::move(pixelOps));
286  case 256:
287  return std::make_unique<StretchScalerOutput256<Pixel>>(
288  std::move(direct), std::move(pixelOps));
289  default:
290  return std::make_unique<StretchScalerOutput<Pixel>>(
291  std::move(direct), std::move(pixelOps), inWidth);
292  }
293 }
294 
295 // Force template instantiation.
296 #if HAVE_16BPP
298 #endif
299 #if HAVE_32BPP
301 #endif
302 
303 } // namespace openmsx
MemoryOps.hh
DirectScalerOutput.hh
openmsx::PixelOperations
Definition: PixelOperations.hh:142
openmsx::MemoryOps::freeAligned
void freeAligned(void *)
Definition: MemoryOps.cc:281
openmsx::StretchScalerOutput::StretchScalerOutput
StretchScalerOutput(unique_ptr< ScalerOutput< Pixel >> output, PixelOperations< Pixel > pixelOps, unsigned inWidth)
Definition: StretchScalerOutput.cc:168
openmsx::StretchScalerOutputBase::getWidth
unsigned getWidth() const override
Definition: StretchScalerOutput.cc:118
utf8::unchecked::size
size_t size(std::string_view utf8)
Definition: utf8_unchecked.hh:227
openmsx::StretchScalerOutputN::StretchScalerOutputN
StretchScalerOutputN(unique_ptr< ScalerOutput< Pixel >> output, PixelOperations< Pixel > pixelOps)
Definition: StretchScalerOutput.cc:195
openmsx::StretchScalerOutputN
Definition: StretchScalerOutput.cc:53
openmsx::StretchScalerOutput280
Definition: StretchScalerOutput.cc:80
openmsx::StretchScalerOutputFactory
Definition: StretchScalerOutput.hh:13
openmsx::StretchScalerOutput256
Definition: StretchScalerOutput.cc:62
openmsx::StretchScalerOutputN::releaseLine
void releaseLine(unsigned y, Pixel *buf) override
Definition: StretchScalerOutput.cc:203
openmsx::StretchScalerOutput272
Definition: StretchScalerOutput.cc:71
openmsx::StretchScalerOutputBase::releasePost
void releasePost(unsigned y, Pixel *dstLine)
Definition: StretchScalerOutput.cc:150
openmsx::ZoomLine
Stretch (or zoom) a given input line to a wider output line.
Definition: LineScalers.hh:238
openmsx::StretchScalerOutput
Definition: StretchScalerOutput.cc:40
openmsx::StretchScalerOutput256::StretchScalerOutput256
StretchScalerOutput256(unique_ptr< ScalerOutput< Pixel >> output, PixelOperations< Pixel > pixelOps)
Definition: StretchScalerOutput.cc:220
openmsx::ScalerOutput
Definition: Scaler.hh:8
openmsx::Pixel
uint32_t Pixel
Definition: GLHQLiteScaler.cc:93
openmsx::StretchScalerOutputBase::getHeight
unsigned getHeight() const override
Definition: StretchScalerOutput.cc:124
openmsx::SCALE
constexpr int SCALE
Definition: ArkanoidPad.cc:29
openmsx::StretchScalerOutput288::StretchScalerOutput288
StretchScalerOutput288(unique_ptr< ScalerOutput< Pixel >> output, PixelOperations< Pixel > pixelOps)
Definition: StretchScalerOutput.cc:256
openmsx::MemoryOps::MemSet
Definition: MemoryOps.hh:8
openmsx::StretchScalerOutput272::StretchScalerOutput272
StretchScalerOutput272(unique_ptr< ScalerOutput< Pixel >> output, PixelOperations< Pixel > pixelOps)
Definition: StretchScalerOutput.cc:232
openmsx::Scale_4on5
Definition: LineScalers.hh:181
openmsx::MemoryOps::mallocAligned
void * mallocAligned(size_t alignment, size_t size)
Definition: MemoryOps.cc:251
openmsx::SDLOutputSurface
A frame buffer where pixels can be written to.
Definition: SDLOutputSurface.hh:29
build-info.hh
openmsx::Scale_17on20
Definition: LineScalers.hh:199
openmsx::StretchScalerOutputFactory::create
static std::unique_ptr< ScalerOutput< Pixel > > create(SDLOutputSurface &output, PixelOperations< Pixel > pixelOps, unsigned inWidth)
Definition: StretchScalerOutput.cc:268
PixelOperations.hh
LineScalers.hh
openmsx::StretchScalerOutput::releaseLine
void releaseLine(unsigned y, Pixel *buf) override
Definition: StretchScalerOutput.cc:178
gl::scale
mat4 scale(const vec3 &xyz)
Definition: gl_transform.hh:19
openmsx::StretchScalerOutputBase::releasePre
Pixel * releasePre(unsigned y, Pixel *buf)
Definition: StretchScalerOutput.cc:143
openmsx::StretchScalerOutputBase::acquireLine
Pixel * acquireLine(unsigned y) override
Definition: StretchScalerOutput.cc:130
openmsx::Scale_9on10
Definition: LineScalers.hh:208
openmsx::StretchScalerOutputBase::~StretchScalerOutputBase
~StretchScalerOutputBase() override
Definition: StretchScalerOutput.cc:110
openmsx::StretchScalerOutput280::StretchScalerOutput280
StretchScalerOutput280(unique_ptr< ScalerOutput< Pixel >> output, PixelOperations< Pixel > pixelOps)
Definition: StretchScalerOutput.cc:244
StretchScalerOutput.hh
openmsx::Scale_7on8
Definition: LineScalers.hh:190
openmsx::StretchScalerOutputBase::pixelOps
const PixelOperations< Pixel > pixelOps
Definition: StretchScalerOutput.cc:32
openmsx::StretchScalerOutput288
Definition: StretchScalerOutput.cc:89
openmsx
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
openmsx::StretchScalerOutputBase
Definition: StretchScalerOutput.cc:16
openmsx::StretchScalerOutputBase::StretchScalerOutputBase
StretchScalerOutputBase(unique_ptr< ScalerOutput< Pixel >> output, PixelOperations< Pixel > pixelOps)
Definition: StretchScalerOutput.cc:101
openmsx::StretchScalerOutputBase::fillLine
void fillLine(unsigned y, Pixel color) override
Definition: StretchScalerOutput.cc:156