13 template<
typename Pixel>
15 const Pixel* palette16_,
const Pixel* palette256_,
16 const Pixel* palette32768_)
17 : palette16(palette16_)
18 , palette256(palette256_)
19 , palette32768(palette32768_)
20 , dPaletteValid(false)
24 template<
typename Pixel>
28 unsigned bits =
sizeof(
Pixel) * 8;
29 for (
auto i :
xrange(16)) {
30 DPixel p0 = palette16[i];
31 for (
auto j :
xrange(16)) {
32 DPixel p1 = palette16[j];
33 DPixel dp = OPENMSX_BIGENDIAN
36 dPalette[16 * i + j] = dp;
41 template<
typename Pixel>
43 Pixel* linePtr,
const byte* vramPtr)
45 switch (mode.getByte()) {
48 renderGraphic4(linePtr, vramPtr);
52 renderGraphic5(linePtr, vramPtr);
75 template<
typename Pixel>
77 Pixel* linePtr,
const byte* vramPtr0,
const byte* vramPtr1)
79 switch (mode.getByte()) {
82 renderGraphic6(linePtr, vramPtr0, vramPtr1);
86 renderGraphic7(linePtr, vramPtr0, vramPtr1);
90 renderYJK(linePtr, vramPtr0, vramPtr1);
94 renderYAE(linePtr, vramPtr0, vramPtr1);
107 renderBogus(linePtr);
112 template<
typename Pixel>
114 Pixel* __restrict pixelPtr,
115 const byte* __restrict vramPtr0)
130 if ((
sizeof(
Pixel) == 2) && ((uintptr_t(pixelPtr) & 1) == 1)) {
135 const auto* in =
reinterpret_cast<const unsigned*
>(vramPtr0);
136 unsigned data = in[0];
137 if constexpr (OPENMSX_BIGENDIAN) {
138 pixelPtr[0] = palette16[(data >> 28) & 0x0F];
141 pixelPtr[0] = palette16[(data >> 0) & 0x0F];
146 auto out =
reinterpret_cast<DPixel*
>(pixelPtr);
147 for (
auto i :
xrange(256 / 8)) {
149 if constexpr (OPENMSX_BIGENDIAN) {
150 out[4 * i + 0] = dPalette[(data >> 24) & 0xFF];
151 out[4 * i + 1] = dPalette[(data >> 16) & 0xFF];
152 out[4 * i + 2] = dPalette[(data >> 8) & 0xFF];
153 if (i == (256-8) / 8) {
155 pixelPtr[254] = palette16[(data >> 0) & 0x0F];
160 unsigned prevData = data;
162 out[4 * i + 3] = dPalette[(prevData & 0xF0) | ((data >> 28) & 0x0F)];
166 out[4 * i + 0] = dPalette[(data >> 0) & 0xFF];
167 out[4 * i + 1] = dPalette[(data >> 8) & 0xFF];
168 out[4 * i + 2] = dPalette[(data >> 16) & 0xFF];
169 if (i != (256-8) / 8) {
171 pixelPtr[254] = palette16[(data >> 24) & 0x0F];
176 unsigned prevData = data;
178 out[4 * i + 3] = dPalette[((prevData >> 24) & 0x0F) | ((data & 0x0F)<<4)];
186 auto* out =
reinterpret_cast<DPixel*
>(pixelPtr);
187 const auto* in =
reinterpret_cast<const unsigned*
>(vramPtr0);
188 for (
auto i :
xrange(256 / 8)) {
190 unsigned data = in[i];
191 if constexpr (OPENMSX_BIGENDIAN) {
192 out[4 * i + 0] = dPalette[(data >> 24) & 0xFF];
193 out[4 * i + 1] = dPalette[(data >> 16) & 0xFF];
194 out[4 * i + 2] = dPalette[(data >> 8) & 0xFF];
195 out[4 * i + 3] = dPalette[(data >> 0) & 0xFF];
197 out[4 * i + 0] = dPalette[(data >> 0) & 0xFF];
198 out[4 * i + 1] = dPalette[(data >> 8) & 0xFF];
199 out[4 * i + 2] = dPalette[(data >> 16) & 0xFF];
200 out[4 * i + 3] = dPalette[(data >> 24) & 0xFF];
205 template<
typename Pixel>
206 void BitmapConverter<Pixel>::renderGraphic5(
207 Pixel* __restrict pixelPtr,
208 const byte* __restrict vramPtr0)
210 for (
auto i :
xrange(128)) {
211 unsigned data = vramPtr0[i];
212 pixelPtr[4 * i + 0] = palette16[ 0 + (data >> 6) ];
213 pixelPtr[4 * i + 1] = palette16[16 + ((data >> 4) & 3)];
214 pixelPtr[4 * i + 2] = palette16[ 0 + ((data >> 2) & 3)];
215 pixelPtr[4 * i + 3] = palette16[16 + ((data >> 0) & 3)];
219 template<
typename Pixel>
220 void BitmapConverter<Pixel>::renderGraphic6(
221 Pixel* __restrict pixelPtr,
222 const byte* __restrict vramPtr0,
223 const byte* __restrict vramPtr1)
236 auto* out =
reinterpret_cast<DPixel*
>(pixelPtr);
237 const auto* in0 =
reinterpret_cast<const unsigned*
>(vramPtr0);
238 const auto* in1 =
reinterpret_cast<const unsigned*
>(vramPtr1);
239 for (
auto i :
xrange(512 / 16)) {
241 unsigned data0 = in0[i];
242 unsigned data1 = in1[i];
243 if constexpr (OPENMSX_BIGENDIAN) {
244 out[8 * i + 0] = dPalette[(data0 >> 24) & 0xFF];
245 out[8 * i + 1] = dPalette[(data1 >> 24) & 0xFF];
246 out[8 * i + 2] = dPalette[(data0 >> 16) & 0xFF];
247 out[8 * i + 3] = dPalette[(data1 >> 16) & 0xFF];
248 out[8 * i + 4] = dPalette[(data0 >> 8) & 0xFF];
249 out[8 * i + 5] = dPalette[(data1 >> 8) & 0xFF];
250 out[8 * i + 6] = dPalette[(data0 >> 0) & 0xFF];
251 out[8 * i + 7] = dPalette[(data1 >> 0) & 0xFF];
253 out[8 * i + 0] = dPalette[(data0 >> 0) & 0xFF];
254 out[8 * i + 1] = dPalette[(data1 >> 0) & 0xFF];
255 out[8 * i + 2] = dPalette[(data0 >> 8) & 0xFF];
256 out[8 * i + 3] = dPalette[(data1 >> 8) & 0xFF];
257 out[8 * i + 4] = dPalette[(data0 >> 16) & 0xFF];
258 out[8 * i + 5] = dPalette[(data1 >> 16) & 0xFF];
259 out[8 * i + 6] = dPalette[(data0 >> 24) & 0xFF];
260 out[8 * i + 7] = dPalette[(data1 >> 24) & 0xFF];
265 template<
typename Pixel>
266 void BitmapConverter<Pixel>::renderGraphic7(
267 Pixel* __restrict pixelPtr,
268 const byte* __restrict vramPtr0,
269 const byte* __restrict vramPtr1)
271 for (
auto i :
xrange(128)) {
272 pixelPtr[2 * i + 0] = palette256[vramPtr0[i]];
273 pixelPtr[2 * i + 1] = palette256[vramPtr1[i]];
277 static constexpr std::tuple<int, int, int> yjk2rgb(
int y,
int j,
int k)
281 int b =
std::clamp((5 * y - 2 * j - k) / 4, 0, 31);
285 template<
typename Pixel>
286 void BitmapConverter<Pixel>::renderYJK(
287 Pixel* __restrict pixelPtr,
288 const byte* __restrict vramPtr0,
289 const byte* __restrict vramPtr1)
291 for (
auto i :
xrange(64)) {
293 p[0] = vramPtr0[2 * i + 0];
294 p[1] = vramPtr1[2 * i + 0];
295 p[2] = vramPtr0[2 * i + 1];
296 p[3] = vramPtr1[2 * i + 1];
298 int j = (p[2] & 7) + ((p[3] & 3) << 3) - ((p[3] & 4) << 3);
299 int k = (p[0] & 7) + ((p[1] & 3) << 3) - ((p[1] & 4) << 3);
301 for (
auto n :
xrange(4)) {
303 auto [r,
g, b] = yjk2rgb(y, j, k);
304 int col = (r << 10) + (
g << 5) + b;
305 pixelPtr[4 * i + n] = palette32768[col];
310 template<
typename Pixel>
311 void BitmapConverter<Pixel>::renderYAE(
312 Pixel* __restrict pixelPtr,
313 const byte* __restrict vramPtr0,
314 const byte* __restrict vramPtr1)
316 for (
auto i :
xrange(64)) {
318 p[0] = vramPtr0[2 * i + 0];
319 p[1] = vramPtr1[2 * i + 0];
320 p[2] = vramPtr0[2 * i + 1];
321 p[3] = vramPtr1[2 * i + 1];
323 int j = (p[2] & 7) + ((p[3] & 3) << 3) - ((p[3] & 4) << 3);
324 int k = (p[0] & 7) + ((p[1] & 3) << 3) - ((p[1] & 4) << 3);
326 for (
auto n :
xrange(4)) {
330 pix = palette16[p[n] >> 4];
334 auto [r,
g, b] = yjk2rgb(y, j, k);
335 pix = palette32768[(r << 10) + (
g << 5) + b];
337 pixelPtr[4 * i + n] = pix;
342 template<
typename Pixel>
343 void BitmapConverter<Pixel>::renderBogus(
Pixel* pixelPtr)
349 std::fill_n(pixelPtr, 256, palette16[15]);
354 template class BitmapConverter<uint16_t>;
356 #if HAVE_32BPP || COMPONENT_GL
357 template class BitmapConverter<uint32_t>;
Utility class for converting VRAM contents to host pixels.
void convertLinePlanar(Pixel *linePtr, const byte *vramPtr0, const byte *vramPtr1)
Convert a line of V9938 VRAM to 512 host pixels.
BitmapConverter(const Pixel *palette16, const Pixel *palette256, const Pixel *palette32768)
Create a new bitmap scanline converter.
void convertLine(Pixel *linePtr, const byte *vramPtr)
Convert a line of V9938 VRAM to 512 host pixels.
static constexpr byte YAE
Encoding of YAE flag.
static constexpr byte YJK
Encoding of YJK flag.
constexpr vecN< N, T > clamp(const vecN< N, T > &x, const vecN< N, T > &minVal, const vecN< N, T > &maxVal)
This file implemented 3 utility functions:
constexpr auto xrange(T e)