12 template<
typename Pixel>
15 const Pixel* palette64_,
const int16_t* palette64_32768_,
16 const Pixel* palette256_,
const int16_t* palette256_32768_,
17 const Pixel* palette32768_)
18 : vdp(vdp_), vram(vdp.getVRAM())
19 , palette64 (palette64_ ), palette64_32768 (palette64_32768_ )
20 , palette256(palette256_), palette256_32768(palette256_32768_)
21 , palette32768(palette32768_)
26 template<
bool YJK,
bool PAL,
bool SKIP,
typename Pixel,
typename ColorLookup>
27 static inline void draw_YJK_YUV_PAL(
29 Pixel* __restrict& out,
unsigned& address,
int firstX = 0)
32 for (
auto& d : data) {
36 int u = (data[2] & 7) + ((data[3] & 3) << 3) - ((data[3] & 4) << 3);
37 int v = (data[0] & 7) + ((data[1] & 3) << 3) - ((data[1] & 4) << 3);
39 for (
auto i :
xrange(SKIP ? firstX : 0, 4)) {
40 if (PAL && (data[i] & 0x08)) {
41 *out++ = color.lookup64(data[i] >> 4);
43 int y = (data[i] & 0xF8) >> 3;
50 *out++ = color.lookup32768((
g << 10) + (r << 5) + b);
55 template<
typename Pixel,
typename ColorLookup>
56 static void rasterBYUV(
58 Pixel* __restrict out,
unsigned x,
unsigned y,
int nrPixels)
60 unsigned address = (
x & ~3) + y * vdp.getImageWidth();
62 draw_YJK_YUV_PAL<false, false, true>(
63 color, vram, out, address,
x & 3);
64 nrPixels -= 4 - (
x & 3);
66 for (; nrPixels > 0; nrPixels -= 4) {
67 draw_YJK_YUV_PAL<false, false, false>(
68 color, vram, out, address);
73 template<
typename Pixel,
typename ColorLookup>
74 static void rasterBYUVP(
76 Pixel* __restrict out,
unsigned x,
unsigned y,
int nrPixels)
80 unsigned address = (
x & ~3) + y * vdp.getImageWidth();
82 draw_YJK_YUV_PAL<false, true, true>(
83 color, vram, out, address,
x & 3);
84 nrPixels -= 4 - (
x & 3);
86 for (; nrPixels > 0; nrPixels -= 4) {
87 draw_YJK_YUV_PAL<false, true, false>(
88 color, vram, out, address);
93 template<
typename Pixel,
typename ColorLookup>
94 static void rasterBYJK(
96 Pixel* __restrict out,
unsigned x,
unsigned y,
int nrPixels)
98 unsigned address = (
x & ~3) + y * vdp.getImageWidth();
100 draw_YJK_YUV_PAL<true, false, true>(
101 color, vram, out, address,
x & 3);
102 nrPixels -= 4 - (
x & 3);
104 for (; nrPixels > 0; nrPixels -= 4) {
105 draw_YJK_YUV_PAL<true, false, false>(
106 color, vram, out, address);
111 template<
typename Pixel,
typename ColorLookup>
112 static void rasterBYJKP(
114 Pixel* __restrict out,
unsigned x,
unsigned y,
int nrPixels)
118 unsigned address = (
x & ~3) + y * vdp.getImageWidth();
120 draw_YJK_YUV_PAL<true, true, true>(
121 color, vram, out, address,
x & 3);
122 nrPixels -= 4 - (
x & 3);
124 for (; nrPixels > 0; nrPixels -= 4) {
125 draw_YJK_YUV_PAL<true, true, false>(
126 color, vram, out, address);
131 template<
typename Pixel,
typename ColorLookup>
132 static void rasterBD16(
134 Pixel* __restrict out,
unsigned x,
unsigned y,
int nrPixels)
136 unsigned address = 2 * (
x + y * vdp.getImageWidth());
137 if (vdp.isSuperimposing()) {
138 auto transparant = color.lookup256(0);
139 for (; nrPixels > 0; --nrPixels) {
140 byte high = vram.readVRAMBx(address + 1);
144 byte low = vram.readVRAMBx(address + 0);
145 *out = color.lookup32768(low + 256 * high);
151 for (; nrPixels > 0; --nrPixels) {
152 byte low = vram.readVRAMBx(address++);
153 byte high = vram.readVRAMBx(address++);
154 *out++ = color.lookup32768((low + 256 * high) & 0x7FFF);
159 template<
typename Pixel,
typename ColorLookup>
160 static void rasterBD8(
162 Pixel* __restrict out,
unsigned x,
unsigned y,
int nrPixels)
164 unsigned address =
x + y * vdp.getImageWidth();
165 for (; nrPixels > 0; --nrPixels) {
166 *out++ = color.lookup256(vram.readVRAMBx(address++));
170 template<
typename Pixel,
typename ColorLookup>
171 static void rasterBP6(
173 Pixel* __restrict out,
unsigned x,
unsigned y,
int nrPixels)
175 unsigned address =
x + y * vdp.getImageWidth();
176 for (; nrPixels > 0; --nrPixels) {
177 *out++ = color.lookup64(vram.readVRAMBx(address++) & 0x3F);
181 template<
typename Pixel,
typename ColorLookup>
182 static void rasterBP4(
184 Pixel* __restrict out,
unsigned x,
unsigned y,
int nrPixels)
186 assert(nrPixels > 0);
187 unsigned address = (
x + y * vdp.getImageWidth()) / 2;
188 color.set64Offset((vdp.getPaletteOffset() & 0xC) << 2);
190 byte data = vram.readVRAMBx(address++);
191 *out++ = color.lookup64(data & 0x0F);
194 for (; nrPixels > 0; nrPixels -= 2) {
195 byte data = vram.readVRAMBx(address++);
196 *out++ = color.lookup64(data >> 4);
197 *out++ = color.lookup64(data & 0x0F);
201 template<
typename Pixel,
typename ColorLookup>
202 static void rasterBP4HiRes(
204 Pixel* __restrict out,
unsigned x,
unsigned y,
int nrPixels)
209 unsigned address = (
x + y * vdp.getImageWidth()) / 2;
210 color.set64Offset((vdp.getPaletteOffset() & 0x4) << 2);
212 byte data = vram.readVRAMBx(address++);
213 *out++ = color.lookup64(32 | (data & 0x0F));
216 for (; nrPixels > 0; nrPixels -= 2) {
217 byte data = vram.readVRAMBx(address++);
218 *out++ = color.lookup64( 0 | (data >> 4 ));
219 *out++ = color.lookup64(32 | (data & 0x0F));
224 template<
typename Pixel,
typename ColorLookup>
225 static void rasterBP2(
227 Pixel* __restrict out,
unsigned x,
unsigned y,
int nrPixels)
229 assert(nrPixels > 0);
230 unsigned address = (
x + y * vdp.getImageWidth()) / 4;
231 color.set64Offset(vdp.getPaletteOffset() << 2);
233 byte data = vram.readVRAMBx(address++);
234 if ((
x & 3) <= 1) *out++ = color.lookup64((data & 0x30) >> 4);
235 if ((
x & 3) <= 2) *out++ = color.lookup64((data & 0x0C) >> 2);
236 if (
true) *out++ = color.lookup64((data & 0x03) >> 0);
237 nrPixels -= 4 - (
x & 3);
239 for (; nrPixels > 0; nrPixels -= 4) {
240 byte data = vram.readVRAMBx(address++);
241 *out++ = color.lookup64((data & 0xC0) >> 6);
242 *out++ = color.lookup64((data & 0x30) >> 4);
243 *out++ = color.lookup64((data & 0x0C) >> 2);
244 *out++ = color.lookup64((data & 0x03) >> 0);
248 template<
typename Pixel,
typename ColorLookup>
249 static void rasterBP2HiRes(
251 Pixel* __restrict out,
unsigned x,
unsigned y,
int nrPixels)
256 assert(nrPixels > 0);
257 unsigned address = (
x + y * vdp.getImageWidth()) / 4;
258 color.set64Offset((vdp.getPaletteOffset() & 0x7) << 2);
260 byte data = vram.readVRAMBx(address++);
261 if ((
x & 3) <= 1) *out++ = color.lookup64(32 | ((data & 0x30) >> 4));
262 if ((
x & 3) <= 2) *out++ = color.lookup64( 0 | ((data & 0x0C) >> 2));
263 if (
true) *out++ = color.lookup64(32 | ((data & 0x03) >> 0));
264 nrPixels -= 4 - (
x & 3);
266 for (; nrPixels > 0; nrPixels -= 4) {
267 byte data = vram.readVRAMBx(address++);
268 *out++ = color.lookup64( 0 | ((data & 0xC0) >> 6));
269 *out++ = color.lookup64(32 | ((data & 0x30) >> 4));
270 *out++ = color.lookup64( 0 | ((data & 0x0C) >> 2));
271 *out++ = color.lookup64(32 | ((data & 0x03) >> 0));
277 template<
typename Pixel>
282 const Pixel* palette32768_)
283 : palette64(palette64_)
284 , palette256(palette256_)
285 , palette32768(palette32768_)
295 const Pixel* palette64;
296 const Pixel* palette256;
297 const Pixel* palette32768;
305 IndexLookup(
const int16_t* palette64_,
const int16_t* palette256_)
306 : palette64_32768(palette64_)
307 , palette256_32768(palette256_)
312 [[nodiscard]] int16_t
lookup64 (
size_t idx)
const {
return palette64_32768 [idx]; }
313 [[nodiscard]] int16_t
lookup256 (
size_t idx)
const {
return palette256_32768[idx]; }
314 [[nodiscard]] int16_t
lookup32768(
size_t idx)
const {
return int16_t(idx); }
317 const int16_t* palette64_32768;
318 const int16_t* palette256_32768;
321 template<
typename Pixel,
typename ColorLookup>
324 Pixel* __restrict out,
unsigned x,
unsigned y,
int nrPixels)
327 case BYUV:
return rasterBYUV <Pixel>(color, vdp, vram, out,
x, y, nrPixels);
328 case BYUVP:
return rasterBYUVP<Pixel>(color, vdp, vram, out,
x, y, nrPixels);
329 case BYJK:
return rasterBYJK <Pixel>(color, vdp, vram, out,
x, y, nrPixels);
330 case BYJKP:
return rasterBYJKP<Pixel>(color, vdp, vram, out,
x, y, nrPixels);
331 case BD16:
return rasterBD16 <Pixel>(color, vdp, vram, out,
x, y, nrPixels);
332 case BD8:
return rasterBD8 <Pixel>(color, vdp, vram, out,
x, y, nrPixels);
333 case BP6:
return rasterBP6 <Pixel>(color, vdp, vram, out,
x, y, nrPixels);
334 case BP4:
return highRes ? rasterBP4HiRes<Pixel>(color, vdp, vram, out,
x, y, nrPixels)
335 : rasterBP4 <
Pixel>(color, vdp, vram, out,
x, y, nrPixels);
336 case BP2:
return highRes ? rasterBP2HiRes<Pixel>(color, vdp, vram, out,
x, y, nrPixels)
337 : rasterBP2 <
Pixel>(color, vdp, vram, out,
x, y, nrPixels);
375 unsigned attrAddr,
unsigned patAddr,
376 int displayY,
bool drawCursor)
384 if (!drawCursor)
return;
386 unsigned attrY = vram.
readVRAMBx(attrAddr + 0) +
389 unsigned cursorLine = (displayY - attrY) & 511;
390 if (cursorLine >= 32)
return;
393 if ((attr & 0x10) || ((attr & 0xe0) == 0x00)) {
399 + (vram.
readVRAMBx(patAddr + 4 * cursorLine + 1) << 16)
400 + (vram.
readVRAMBx(patAddr + 4 * cursorLine + 2) << 8)
401 + (vram.
readVRAMBx(patAddr + 4 * cursorLine + 3) << 0);
408 x = vram.
readVRAMBx(attrAddr + 4) + (attr & 3) * 256;
410 doXor = (attr & 0xe0) == 0x20;
413 color = palette64_32768[colorIdx];
414 if (attr & 0x20)
color ^= 0x7fff;
418 return x != unsigned(-1);
420 [[nodiscard]]
bool dot()
const {
421 return (
x == 0) && (
pattern & 0x80000000);
438 template<
typename Pixel>
440 Pixel* linePtr,
unsigned x,
unsigned y,
int nrPixels,
441 int cursorY,
bool drawCursors)
443 assert(nrPixels <= 1024);
445 CursorInfo cursor0(vdp, vram, palette64_32768, 0x7fe00, 0x7ff00, cursorY, drawCursors);
446 CursorInfo cursor1(vdp, vram, palette64_32768, 0x7fe08, 0x7ff80, cursorY, drawCursors);
451 raster(colorMode, highRes,
454 buf,
x, y, nrPixels);
461 for (
auto i :
xrange(nrPixels)) {
466 buf[i] = cursor0.
color;
468 }
else if (cursor1.
dot()) {
472 buf[i] = cursor1.
color;
481 for (
auto i :
xrange(nrPixels)) {
482 linePtr[i] = palette32768[buf[i]];
486 raster(colorMode, highRes,
489 linePtr,
x, y, nrPixels);
497 #if HAVE_32BPP || COMPONENT_GL