]> git.sesse.net Git - pistorm/blob - platforms/amiga/rtg/rtg-gfx.c
058a8b1b60dd3969e20b342b29b798c2222bc4ab
[pistorm] / platforms / amiga / rtg / rtg-gfx.c
1 #include <stdio.h>
2 #include <stdint.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include "../../../config_file/config_file.h"
6 #ifndef FAKESTORM
7 #include "../../../gpio/gpio.h"
8 #endif
9 #include "rtg.h"
10
11 extern uint32_t rtg_address[8];
12 extern uint32_t rtg_address_adj[8];
13 extern uint8_t *rtg_mem; // FIXME
14 extern uint16_t rtg_display_format;
15 extern uint16_t rtg_user[8];
16 extern uint16_t rtg_x[8], rtg_y[8];
17
18 extern uint8_t realtime_graphics_debug;
19
20 void rtg_fillrect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint32_t color, uint16_t pitch, uint16_t format, uint8_t mask) {
21     if (mask) {}
22     uint8_t *dptr = &rtg_mem[rtg_address_adj[0] + (x << format) + (y * pitch)];
23     switch(format) {
24         case RTGFMT_8BIT: {
25             for (int xs = 0; xs < w; xs++) {
26                 dptr[xs] = color & 0xFF;
27             }
28             break;
29         }
30         case RTGFMT_RBG565: {
31             color = htobe16((color & 0xFFFF));
32             uint16_t *ptr = (uint16_t *)dptr;
33             for (int xs = 0; xs < w; xs++) {
34                 ptr[xs] = color;
35             }
36             break;
37         }
38         case RTGFMT_RGB32: {
39             color = htobe32(color);
40             uint32_t *ptr = (uint32_t *)dptr;
41             for (int xs = 0; xs < w; xs++) {
42                 ptr[xs] = color;
43             }
44             break;
45         }
46     }
47     for (int ys = 1; ys < h; ys++) {
48         dptr += pitch;
49         memcpy(dptr, (void *)(size_t)(dptr - pitch), (w << format));
50     }
51 }
52
53 void rtg_invertrect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t pitch, uint16_t format, uint8_t mask) {
54     if (mask) {}
55     uint8_t *dptr = &rtg_mem[rtg_address_adj[0] + (x << format) + (y * pitch)];
56     for (int ys = 1; ys < h; ys++) {
57         switch(format) {
58             case RTGFMT_8BIT: {
59                 for (int xs = 0; xs < w; xs++) {
60                     dptr[xs] = ~dptr[xs];
61                 }
62                 break;
63             }
64             case RTGFMT_RBG565: {
65                 for (int xs = 0; xs < w; xs++) {
66                     ((uint16_t *)dptr)[xs] = ~((uint16_t *)dptr)[xs];
67                 }
68                 break;
69             }
70             case RTGFMT_RGB32: {
71                 for (int xs = 0; xs < w; xs++) {
72                     ((uint32_t *)dptr)[xs] = ~((uint32_t *)dptr)[xs];
73                 }
74                 break;
75             }
76         }
77         dptr += pitch;
78     }
79 }
80
81 void rtg_blitrect(uint16_t x, uint16_t y, uint16_t dx, uint16_t dy, uint16_t w, uint16_t h, uint16_t pitch, uint16_t format, uint8_t mask) {
82     if (mask) {}
83     uint8_t *sptr = &rtg_mem[rtg_address_adj[0] + (x << format) + (y * pitch)];
84     uint8_t *dptr = &rtg_mem[rtg_address_adj[0] + (dx << format) + (dy * pitch)];
85
86     uint32_t xdir = 1, pitchstep = pitch;
87
88     if (y < dy) {
89         pitchstep = -pitch;
90         sptr += ((h - 1) * pitch);
91         dptr += ((h - 1) * pitch);
92     }
93     if (x < dx) {
94         xdir = 0;
95     }
96
97     for (int ys = 0; ys < h; ys++) {
98         if (xdir)
99             memcpy(dptr, sptr, w << format);
100         else
101             memmove(dptr, sptr, w << format);
102         sptr += pitchstep;
103         dptr += pitchstep;
104     }
105 }
106
107 void rtg_blitrect_nomask_complete(uint16_t sx, uint16_t sy, uint16_t dx, uint16_t dy, uint16_t w, uint16_t h, uint16_t srcpitch, uint16_t dstpitch, uint32_t src_addr, uint32_t dst_addr, uint16_t format, uint8_t minterm) {
108     if (minterm) {}
109     uint8_t *sptr = &rtg_mem[src_addr - (PIGFX_RTG_BASE + PIGFX_REG_SIZE) + (sx << format) + (sy * srcpitch)];
110     uint8_t *dptr = &rtg_mem[dst_addr - (PIGFX_RTG_BASE + PIGFX_REG_SIZE) + (dx << format) + (dy * dstpitch)];
111
112     uint32_t xdir = 1, src_pitchstep = srcpitch, dst_pitchstep = dstpitch;
113
114     if (src_addr == dst_addr) {
115         if (sy < dy) {
116             src_pitchstep = -srcpitch;
117             sptr += ((h - 1) * srcpitch);
118             dst_pitchstep = -dstpitch;
119             dptr += ((h - 1) * dstpitch);
120         }
121         if (sx < dx) {
122             xdir = 0;
123         }
124     }
125
126     for (int ys = 0; ys < h; ys++) {
127         if (xdir)
128             memcpy(dptr, sptr, w << format);
129         else
130             memmove(dptr, sptr, w << format);
131         sptr += src_pitchstep;
132         dptr += dst_pitchstep;
133     }
134 }
135
136 extern struct emulator_config *cfg;
137
138 void rtg_blittemplate(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint32_t src_addr, uint32_t fgcol, uint32_t bgcol, uint16_t pitch, uint16_t t_pitch, uint16_t format, uint16_t offset_x, uint8_t mask, uint8_t draw_mode) {
139     if (mask) {}
140
141     uint8_t *dptr = &rtg_mem[rtg_address_adj[1] + (x << format) + (y * pitch)];
142     uint8_t *sptr = NULL;
143     uint8_t cur_bit = 0, base_bit = 0, cur_byte = 0;
144     uint8_t invert = (draw_mode & DRAWMODE_INVERSVID);
145     uint16_t tmpl_x = 0;
146
147     draw_mode &= 0x03;
148
149         tmpl_x = offset_x / 8;
150     cur_bit = base_bit = (0x80 >> (offset_x % 8));
151
152     if (realtime_graphics_debug) {
153         printf("DEBUG: BlitTemplate - %d, %d (%dx%d)\n", x, y, w, h);
154         printf("Src: %.8X (%.8X)\n", src_addr, rtg_address_adj[0]);
155         printf("Dest: %.8X (%.8X)\n", rtg_address[1], rtg_address_adj[1]);
156         printf("pitch: %d t_pitch: %d format: %d\n", pitch, t_pitch, format);
157         printf("offset_x: %d mask: %.2X draw_mode: %d\n", offset_x, mask, draw_mode);
158     }
159
160     uint32_t fg_color[3] = {
161         (fgcol & 0xFF),
162         htobe16((fgcol & 0xFFFF)),
163         htobe32(fgcol),
164     };
165     uint32_t bg_color[3] = {
166         (bgcol & 0xFF),
167         htobe16((bgcol & 0xFFFF)),
168         htobe32(bgcol),
169     };
170
171     if (src_addr >= (PIGFX_RTG_BASE + PIGFX_REG_SIZE)) {
172         sptr = &rtg_mem[src_addr - (PIGFX_RTG_BASE + PIGFX_REG_SIZE)];
173         if (realtime_graphics_debug) {
174             printf("Origin: %.8X\n", rtg_address[2]);
175             printf("Grabbing data from RTG memory.\nData:\n");
176             for (int i = 0; i < h; i++) {
177                 for (int j = 0; j < t_pitch; j++) {
178                     printf("%.2X", sptr[j + (i * t_pitch)]);
179                 }
180                 printf("\n");
181             }
182 #ifndef FAKESTORM
183             printf("Data available at origin:\n");
184             for (int i = 0; i < h; i++) {
185                 for (int j = 0; j < w; j++) {
186                     printf("%.2X", read8(rtg_address[2] + j + (i * t_pitch)));
187                 }
188                 printf("\n");
189             }
190 #endif
191         }
192     }
193     else {
194         int i = get_mapped_item_by_address(cfg, src_addr);
195         if (i != -1) {
196             sptr = &cfg->map_data[i][src_addr - cfg->map_offset[i]];
197             if (realtime_graphics_debug) {
198                 printf("Grabbing data from maping %d - offset %.8X\nData:\n", i, src_addr - cfg->map_offset[i]);
199                 for (int i = 0; i < h; i++) {
200                     for (int j = 0; j < t_pitch; j++) {
201                         printf("%.2X", sptr[j + (i * t_pitch)]);
202                     }
203                     printf("\n");
204                 }
205             }
206         }
207         else {
208             printf("BlitTemplate: Failed to find mapped range for address %.8X\n", src_addr);
209             return;
210         }
211     }
212
213     switch (draw_mode) {
214         case DRAWMODE_JAM1:
215             for (uint16_t ys = 0; ys < h; ys++) {
216                 cur_byte = (invert) ? sptr[tmpl_x] ^ 0xFF : sptr[tmpl_x];
217
218                 for (int xs = 0; xs < w; xs++) {
219                     if (w >= 8 && cur_bit == 0x80 && xs < w - 8) {
220                         SET_RTG_PIXELS(&dptr[xs << format], fg_color[format], format);
221                         xs += 7;
222                     }
223                     else {
224                         while (cur_bit > 0 && xs < w) {
225                             if (cur_byte & cur_bit) {
226                                 SET_RTG_PIXEL(&dptr[xs << format], fg_color[format], format);
227                             }
228                             xs++;
229                             cur_bit >>= 1;
230                         }
231                         xs--;
232                         cur_bit = 0x80;
233                     }
234                     TEMPLATE_LOOPX;
235                 }
236                 TEMPLATE_LOOPY;
237             }
238             return;
239         case DRAWMODE_JAM2:
240             for (uint16_t ys = 0; ys < h; ys++) {
241                 cur_byte = (invert) ? sptr[tmpl_x] ^ 0xFF : sptr[tmpl_x];
242
243                 for (int xs = 0; xs < w; xs++) {
244                     if (w >= 8 && cur_bit == 0x80 && xs < w - 8) {
245                         SET_RTG_PIXELS2_COND(&dptr[xs << format], fg_color[format], bg_color[format], format);
246                         xs += 7;
247                     }
248                     else {
249                         while (cur_bit > 0 && xs < w) {
250                             if (cur_byte & cur_bit) {
251                                 SET_RTG_PIXEL(&dptr[xs << format], fg_color[format], format);
252                             }
253                             else {
254                                 SET_RTG_PIXEL(&dptr[xs << format], bg_color[format], format);
255                             }
256                             xs++;
257                             cur_bit >>= 1;
258                         }
259                         xs--;
260                         cur_bit = 0x80;
261                     }
262                     TEMPLATE_LOOPX;
263                 }
264                 TEMPLATE_LOOPY;
265             }
266             return;
267         case DRAWMODE_COMPLEMENT:
268             for (uint16_t ys = 0; ys < h; ys++) {
269                 cur_byte = (invert) ? sptr[tmpl_x] ^ 0xFF : sptr[tmpl_x];
270
271                 for (int xs = 0; xs < w; xs++) {
272                     if (w >= 8 && cur_bit == 0x80 && xs < w - 8) {
273                         INVERT_RTG_PIXELS(&dptr[xs << format], format)
274                         xs += 7;
275                     }
276                     else {
277                         while (cur_bit > 0 && xs < w) {
278                             if (cur_byte & cur_bit) {
279                                 INVERT_RTG_PIXEL(&dptr[xs << format], format)
280                             }
281                             xs++;
282                             cur_bit >>= 1;
283                         }
284                         xs--;
285                         cur_bit = 0x80;
286                     }
287                     TEMPLATE_LOOPX;
288                 }
289                 TEMPLATE_LOOPY;
290             }
291             return;
292     }
293 }
294
295 void rtg_blitpattern(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint32_t src_addr, uint32_t fgcol, uint32_t bgcol, uint16_t pitch, uint16_t format, uint16_t offset_x, uint16_t offset_y, uint8_t mask, uint8_t draw_mode, uint8_t loop_rows) {
296     if (mask) {}
297
298     uint8_t *dptr = &rtg_mem[rtg_address_adj[1] + (x << format) + (y * pitch)];
299     uint8_t *sptr = NULL, *sptr_base = NULL;
300     uint8_t cur_bit = 0, base_bit = 0, cur_byte = 0;
301     uint8_t invert = (draw_mode & DRAWMODE_INVERSVID);
302     uint16_t tmpl_x = 0;
303
304     draw_mode &= 0x03;
305
306         tmpl_x = (offset_x / 8) % 2;
307     cur_bit = base_bit = (0x80 >> (offset_x % 8));
308
309     uint32_t fg_color[3] = {
310         (fgcol & 0xFF),
311         htobe16((fgcol & 0xFFFF)),
312         htobe32(fgcol),
313     };
314     uint32_t bg_color[3] = {
315         (bgcol & 0xFF),
316         htobe16((bgcol & 0xFFFF)),
317         htobe32(bgcol),
318     };
319
320
321     if (src_addr >= (PIGFX_RTG_BASE + PIGFX_REG_SIZE))
322         sptr = &rtg_mem[src_addr - (PIGFX_RTG_BASE + PIGFX_REG_SIZE)];
323     else {
324         int i = get_mapped_item_by_address(cfg, src_addr);
325         if (i != -1) {
326             sptr = &cfg->map_data[i][src_addr - cfg->map_offset[i]];
327         }
328         else {
329             printf("BlitPattern: Failed to find mapped range for address %.8X\n", src_addr);
330             return;
331         }
332     }
333
334     sptr_base = sptr;
335     sptr += (offset_y % loop_rows) * 2;
336
337     switch (draw_mode) {
338         case DRAWMODE_JAM1:
339             for (uint16_t ys = 0; ys < h; ys++) {
340                 cur_byte = (invert) ? sptr[tmpl_x] ^ 0xFF : sptr[tmpl_x];
341
342                 for (int xs = 0; xs < w; xs++) {
343                     if (w >= 8 && cur_bit == 0x80 && xs < w - 8) {
344                         SET_RTG_PIXELS(&dptr[xs << format], fg_color[format], format);
345                         xs += 7;
346                     }
347                     else {
348                         while (cur_bit > 0 && xs < w) {
349                             if (cur_byte & cur_bit) {
350                                 SET_RTG_PIXEL(&dptr[xs << format], fg_color[format], format);
351                             }
352                             xs++;
353                             cur_bit >>= 1;
354                         }
355                         xs--;
356                         cur_bit = 0x80;
357                     }
358                     PATTERN_LOOPX;
359                 }
360                 PATTERN_LOOPY;
361             }
362             return;
363         case DRAWMODE_JAM2:
364             for (uint16_t ys = 0; ys < h; ys++) {
365                 cur_byte = (invert) ? sptr[tmpl_x] ^ 0xFF : sptr[tmpl_x];
366
367                 for (int xs = 0; xs < w; xs++) {
368                     if (w >= 8 && cur_bit == 0x80 && xs < w - 8) {
369                         SET_RTG_PIXELS2_COND(&dptr[xs << format], fg_color[format], bg_color[format], format);
370                         xs += 7;
371                     }
372                     else {
373                         while (cur_bit > 0 && xs < w) {
374                             if (cur_byte & cur_bit) {
375                                 SET_RTG_PIXEL(&dptr[xs << format], fg_color[format], format);
376                             }
377                             else {
378                                 SET_RTG_PIXEL(&dptr[xs << format], bg_color[format], format);
379                             }
380                             xs++;
381                             cur_bit >>= 1;
382                         }
383                         xs--;
384                         cur_bit = 0x80;
385                     }
386                     PATTERN_LOOPX;
387                 }
388                 PATTERN_LOOPY;
389             }
390             return;
391         case DRAWMODE_COMPLEMENT:
392             for (uint16_t ys = 0; ys < h; ys++) {
393                 cur_byte = (invert) ? sptr[tmpl_x] ^ 0xFF : sptr[tmpl_x];
394
395                 for (int xs = 0; xs < w; xs++) {
396                     if (w >= 8 && cur_bit == 0x80 && xs < w - 8) {
397                         INVERT_RTG_PIXELS(&dptr[xs << format], format)
398                         xs += 7;
399                     }
400                     else {
401                         while (cur_bit > 0 && xs < w) {
402                             if (cur_byte & cur_bit) {
403                                 INVERT_RTG_PIXEL(&dptr[xs << format], format)
404                             }
405                             xs++;
406                             cur_bit >>= 1;
407                         }
408                         xs--;
409                         cur_bit = 0x80;
410                     }
411                     PATTERN_LOOPX;
412                 }
413                 PATTERN_LOOPY;
414             }
415             return;
416     }
417 }
418
419 void rtg_drawline_solid(int16_t x1_, int16_t y1_, int16_t x2_, int16_t y2_, uint16_t len, uint32_t fgcol, uint16_t pitch, uint16_t format) {
420         int16_t x1 = x1_, y1 = y1_;
421         int16_t x2 = x1_ + x2_, y2 = y1 + y2_;
422
423     uint32_t fg_color[3] = {
424         (fgcol & 0xFF),
425         htobe16((fgcol & 0xFFFF)),
426         htobe32(fgcol),
427     };
428
429     uint8_t *dptr = &rtg_mem[rtg_address_adj[0] + (y1 * pitch)];
430
431         int32_t line_step = pitch;
432         int8_t x_step = 1;
433
434         int16_t dx, dy, dx_abs, dy_abs, ix, iy, x = x1;
435
436         if (x2 < x1)
437                 x_step = -1;
438         if (y2 < y1)
439                 line_step = -pitch;
440
441         dx = x2 - x1;
442         dy = y2 - y1;
443         dx_abs = abs(dx);
444         dy_abs = abs(dy);
445         ix = dy_abs >> 1;
446         iy = dx_abs >> 1;
447
448     SET_RTG_PIXEL(&dptr[x << format], fg_color[format], format);
449
450         if (dx_abs >= dy_abs) {
451                 if (!len) len = dx_abs;
452                 for (uint16_t i = 0; i < len; i++) {
453                         iy += dy_abs;
454                         if (iy >= dx_abs) {
455                                 iy -= dx_abs;
456                                 dptr += line_step;
457                         }
458                         x += x_step;
459
460             SET_RTG_PIXEL(&dptr[x << format], fg_color[format], format);
461                 }
462         }
463         else {
464                 if (!len) len = dy_abs;
465                 for (uint16_t i = 0; i < len; i++) {
466                         ix += dx_abs;
467                         if (ix >= dy_abs) {
468                                 ix -= dy_abs;
469                                 x += x_step;
470                         }
471                         dptr += line_step;
472
473                         SET_RTG_PIXEL(&dptr[x << format], fg_color[format], format);
474                 }
475         }
476 }
477
478 #define DRAW_LINE_PIXEL \
479     if (pattern & cur_bit) { \
480         if (invert) { INVERT_RTG_PIXEL(&dptr[x << format], format) } \
481         else { \
482             if (mask == 0xFF || format != RTGFMT_8BIT) { SET_RTG_PIXEL(&dptr[x << format], fg_color[format], format); } \
483             else { SET_RTG_PIXEL_MASK(&dptr[x << format], fg_color[format], format); } \
484         } \
485     } \
486     else if (draw_mode == DRAWMODE_JAM2) { \
487         if (invert) { INVERT_RTG_PIXEL(&dptr[x << format], format) } \
488         else { \
489             if (mask == 0xFF || format != RTGFMT_8BIT) { SET_RTG_PIXEL(&dptr[x << format], bg_color[format], format); } \
490             else { SET_RTG_PIXEL_MASK(&dptr[x << format], bg_color[format], format); } \
491         } \
492     } \
493     if ((cur_bit >>= 1) == 0) \
494             cur_bit = 0x8000;
495
496 void rtg_drawline (int16_t x1_, int16_t y1_, int16_t x2_, int16_t y2_, uint16_t len, uint16_t pattern, uint16_t pattern_offset, uint32_t fgcol, uint32_t bgcol, uint16_t pitch, uint16_t format, uint8_t mask, uint8_t draw_mode) {
497     if (pattern_offset) {}
498
499         int16_t x1 = x1_, y1 = y1_;
500         int16_t x2 = x1_ + x2_, y2 = y1 + y2_;
501     uint16_t cur_bit = 0x8000;
502     uint32_t color_mask = 0xFFFF0000;
503     uint8_t invert = 0;
504
505     uint32_t fg_color[3] = {
506         (fgcol & 0xFF),
507         htobe16((fgcol & 0xFFFF)),
508         htobe32(fgcol),
509     };
510     uint32_t bg_color[3] = {
511         (bgcol & 0xFF),
512         htobe16((bgcol & 0xFFFF)),
513         htobe32(bgcol),
514     };
515
516     uint8_t *dptr = &rtg_mem[rtg_address_adj[0] + (y1 * pitch)];
517
518         int32_t line_step = pitch;
519         int8_t x_step = 1;
520
521         int16_t dx, dy, dx_abs, dy_abs, ix, iy, x = x1;
522
523         if (x2 < x1)
524                 x_step = -1;
525         if (y2 < y1)
526                 line_step = -pitch;
527
528         dx = x2 - x1;
529         dy = y2 - y1;
530         dx_abs = abs(dx);
531         dy_abs = abs(dy);
532         ix = dy_abs >> 1;
533         iy = dx_abs >> 1;
534
535     if (draw_mode & DRAWMODE_INVERSVID)
536         pattern = ~pattern;
537     if (draw_mode & DRAWMODE_COMPLEMENT) {
538         invert = 1;
539     }
540     draw_mode &= 0x01;
541
542     DRAW_LINE_PIXEL;
543
544         if (dx_abs >= dy_abs) {
545                 if (!len) len = dx_abs;
546                 for (uint16_t i = 0; i < len; i++) {
547                         iy += dy_abs;
548                         if (iy >= dx_abs) {
549                                 iy -= dx_abs;
550                                 dptr += line_step;
551                         }
552                         x += x_step;
553
554             DRAW_LINE_PIXEL;
555                 }
556         }
557         else {
558                 if (!len) len = dy_abs;
559                 for (uint16_t i = 0; i < len; i++) {
560                         ix += dx_abs;
561                         if (ix >= dy_abs) {
562                                 ix -= dy_abs;
563                                 x += x_step;
564                         }
565                         dptr += line_step;
566
567                         DRAW_LINE_PIXEL;
568                 }
569         }
570 }
571
572 #define HANDLE_MINTERM_PIXEL_8(s, d, f) \
573       switch(draw_mode) {\
574             case MINTERM_NOR: \
575                   s &= ~(d); \
576             SET_RTG_PIXEL_MASK(&d, s, f); break; \
577             case MINTERM_ONLYDST: \
578                   d = d & ~(s); break; \
579             case MINTERM_NOTSRC: \
580             SET_RTG_PIXEL_MASK(&d, s, f); break; \
581             case MINTERM_ONLYSRC: \
582                   s &= (d ^ 0xFF); \
583             SET_RTG_PIXEL_MASK(&d, s, f); break; \
584             case MINTERM_INVERT: \
585                   d ^= 0xFF; break; \
586             case MINTERM_EOR: \
587                   d ^= s; break; \
588             case MINTERM_NAND: \
589                   s = ~(d & ~(s)) & mask; \
590             SET_RTG_PIXEL_MASK(&d, s, f); break; \
591             case MINTERM_AND: \
592                   s &= d; \
593             SET_RTG_PIXEL_MASK(&d, s, f); break; \
594             case MINTERM_NEOR: \
595                   d ^= (s & mask); break; \
596             case MINTERM_DST: /* This one does nothing. */ \
597                   return; break; \
598             case MINTERM_NOTONLYSRC: \
599                   d |= (s & mask); break; \
600             case MINTERM_SRC: \
601             SET_RTG_PIXEL_MASK(&d, s, f); break; \
602             case MINTERM_NOTONLYDST: \
603                   s = ~(d & s) & mask; \
604             SET_RTG_PIXEL_MASK(&d, s, f); break; \
605             case MINTERM_OR: \
606                   d |= (s & mask); break; \
607       }
608
609
610 #define DECODE_PLANAR_PIXEL(a) \
611         switch (planes) { \
612                 case 8: if (layer_mask & 0x80 && bmp_data[(plane_size * 7) + cur_byte] & cur_bit) a |= 0x80; \
613                 case 7: if (layer_mask & 0x40 && bmp_data[(plane_size * 6) + cur_byte] & cur_bit) a |= 0x40; \
614                 case 6: if (layer_mask & 0x20 && bmp_data[(plane_size * 5) + cur_byte] & cur_bit) a |= 0x20; \
615                 case 5: if (layer_mask & 0x10 && bmp_data[(plane_size * 4) + cur_byte] & cur_bit) a |= 0x10; \
616                 case 4: if (layer_mask & 0x08 && bmp_data[(plane_size * 3) + cur_byte] & cur_bit) a |= 0x08; \
617                 case 3: if (layer_mask & 0x04 && bmp_data[(plane_size * 2) + cur_byte] & cur_bit) a |= 0x04; \
618                 case 2: if (layer_mask & 0x02 && bmp_data[plane_size + cur_byte] & cur_bit) a |= 0x02; \
619                 case 1: if (layer_mask & 0x01 && bmp_data[cur_byte] & cur_bit) a |= 0x01; \
620                         break; \
621         }
622
623 #define DECODE_INVERTED_PLANAR_PIXEL(a) \
624         switch (planes) { \
625                 case 8: if (layer_mask & 0x80 && (bmp_data[(plane_size * 7) + cur_byte] ^ 0xFF) & cur_bit) a |= 0x80; \
626                 case 7: if (layer_mask & 0x40 && (bmp_data[(plane_size * 6) + cur_byte] ^ 0xFF) & cur_bit) a |= 0x40; \
627                 case 6: if (layer_mask & 0x20 && (bmp_data[(plane_size * 5) + cur_byte] ^ 0xFF) & cur_bit) a |= 0x20; \
628                 case 5: if (layer_mask & 0x10 && (bmp_data[(plane_size * 4) + cur_byte] ^ 0xFF) & cur_bit) a |= 0x10; \
629                 case 4: if (layer_mask & 0x08 && (bmp_data[(plane_size * 3) + cur_byte] ^ 0xFF) & cur_bit) a |= 0x08; \
630                 case 3: if (layer_mask & 0x04 && (bmp_data[(plane_size * 2) + cur_byte] ^ 0xFF) & cur_bit) a |= 0x04; \
631                 case 2: if (layer_mask & 0x02 && (bmp_data[plane_size + cur_byte] ^ 0xFF) & cur_bit) a |= 0x02; \
632                 case 1: if (layer_mask & 0x01 && (bmp_data[cur_byte] ^ 0xFF) & cur_bit) a |= 0x01; \
633                         break; \
634         }
635
636 void rtg_p2c (int16_t sx, int16_t sy, int16_t dx, int16_t dy, int16_t w, int16_t h, uint8_t draw_mode, uint8_t planes, uint8_t mask, uint8_t layer_mask, uint16_t src_line_pitch, uint8_t *bmp_data_src) {
637     uint16_t pitch = rtg_x[3];
638     uint8_t *dptr = &rtg_mem[rtg_address_adj[0] + (dy * pitch)];
639
640         uint8_t cur_bit, base_bit, base_byte;
641         uint16_t cur_byte = 0, u8_fg = 0;
642     uint32_t color_mask = 0xFFFFFFFF;
643
644         uint32_t plane_size = src_line_pitch * h;
645         uint8_t *bmp_data = bmp_data_src;
646
647         cur_bit = base_bit = (0x80 >> (sx % 8));
648         cur_byte = base_byte = ((sx / 8) % src_line_pitch);
649
650     if (realtime_graphics_debug) {
651         printf("P2C: %d,%d - %d,%d (%dx%d) %d, %.2X\n", sx, sy, dx, dy, w, h, planes, layer_mask);
652         printf("Mask: %.2X Minterm: %.2X\n", mask, draw_mode);
653         printf("Pitch: %d Src Pitch: %d (!!!: %.4X)\n", pitch, src_line_pitch, rtg_user[0]);
654         printf("Curbyte: %d Curbit: %d\n", cur_byte, cur_bit);
655         printf("Plane size: %d Total size: %d (%X)\n", plane_size, plane_size * planes, plane_size * planes);
656         printf("Source: %.8X - %.8X\n", rtg_address[1], rtg_address_adj[1]);
657         printf("Target: %.8X - %.8X\n", rtg_address[0], rtg_address_adj[0]);
658         fflush(stdout);
659
660         printf("Grabbing data from RTG memory.\nData:\n");
661         for (int i = 0; i < h; i++) {
662             for (int k = 0; k < planes; k++) {
663                 for (int j = 0; j < src_line_pitch; j++) {
664                     printf("%.2X", bmp_data_src[j + (i * src_line_pitch) + (plane_size * k)]);
665                 }
666                 printf("  ");
667             }
668             printf("\n");
669         }
670     }
671
672         for (int16_t line_y = 0; line_y < h; line_y++) {
673                 for (int16_t x = dx; x < dx + w; x++) {
674                         u8_fg = 0;
675                         if (draw_mode & 0x01) {
676                                 DECODE_INVERTED_PLANAR_PIXEL(u8_fg)
677             }
678                         else {
679                                 DECODE_PLANAR_PIXEL(u8_fg)
680             }
681
682                         if (mask == 0xFF && (draw_mode == MINTERM_SRC || draw_mode == MINTERM_NOTSRC)) {
683                                 dptr[x] = u8_fg;
684                                 goto skip;
685                         }
686
687                         //HANDLE_MINTERM_PIXEL_8(u8_fg, ((uint8_t *)dptr)[x]);
688             HANDLE_MINTERM_PIXEL_8(u8_fg, dptr[x], rtg_display_format);
689
690                         skip:;
691                         if ((cur_bit >>= 1) == 0) {
692                                 cur_bit = 0x80;
693                                 cur_byte++;
694                                 cur_byte %= src_line_pitch;
695                         }
696
697                 }
698                 dptr += pitch;
699                 if ((line_y + sy + 1) % h)
700                         bmp_data += src_line_pitch;
701                 else
702                         bmp_data = bmp_data_src;
703                 cur_bit = base_bit;
704                 cur_byte = base_byte;
705         }
706 }
707
708 //void rtg_p2c_broken(int16_t sx, int16_t sy, int16_t dx, int16_t dy, int16_t w, int16_t h, uint16_t pitch, uint8_t mask, uint8_t minterm, uint8_t depth, uint16_t planemask_) {
709     /*uint8_t *planeptr_src = &rtg_mem[rtg_address_adj[1]];
710     uint8_t *dptr = &rtg_mem[rtg_address_adj[0] + (dy * pitch)];
711
712         uint8_t cur_bit, base_bit, base_byte;
713         uint16_t cur_byte = 0;//, color = 0;
714     uint16_t srcpitch = rtg_user[1];
715     uint32_t plane_size = srcpitch * rtg_y[3];
716     uint32_t color_mask = 0x00FFFFFF;
717     uint8_t color = 0;
718
719     uint8_t planemask = planemask_ & 0xFF;
720     uint8_t planemask_0 = (planemask_ >> 8);
721
722         cur_bit = base_bit = (0x80 >> (sx % 8));
723         cur_byte = base_byte = ((sx / 8) % srcpitch);
724
725     planeptr_src += (srcpitch * sy);
726
727     if (realtime_graphics_debug) {
728         uint8_t *sptr = NULL;
729
730         printf("P2C: %d,%d - %d,%d (%dx%d) %d, %.4X\n", sx, sy, dx, dy, w, h, depth, planemask_);
731         printf("Mask: %.2X Minterm: %.2X\n", mask, minterm);
732         printf("Pitch: %d Src Pitch: %d (!!!: %d)\n", pitch, srcpitch, rtg_user[1]);
733         printf("Curbyte: %d Curbit: %d\n", cur_byte, cur_bit);
734         printf("Plane size: %d Total size: %d (%X)\n", plane_size, plane_size * depth, plane_size * depth);
735         printf("Source: %.8X - %.8X\n", rtg_address[1], rtg_address_adj[1]);
736         printf("Target: %.8X - %.8X\n", rtg_address[0], rtg_address_adj[0]);
737         fflush(stdout);
738
739         printf("Origin: %.8X\n", rtg_address[2]);
740         printf("Grabbing data from RTG memory.\nData:\n");
741         for (int i = 0; i < h; i++) {
742             for (int k = 0; k < depth; k++) {
743                 for (int j = 0; j < srcpitch; j++) {
744                     printf("%.2X", planeptr_src[j + (i * srcpitch) + (plane_size * k)]);
745                 }
746                 printf("  ");
747             }
748             printf("\n");
749         }
750 #ifndef FAKESTORM
751         printf("Data available at origin:\n");
752         for (int i = 0; i < h; i++) {
753             for (int k = 0; k < depth; k++) {
754                 for (int j = 0; j < srcpitch; j++) {
755                     printf("%.2X", read8(rtg_address[2] + j + (i * srcpitch) + (plane_size * k)));
756                 }
757                 printf("  ");
758             }
759             printf("\n");
760         }
761 #endif
762     }
763
764         for (int16_t line_y = 0; line_y < h; line_y++) {
765                 for (int16_t xs = dx; xs < dx + w; xs++) {
766                         color = 0;
767                         if (minterm & 0x01) {
768                 //printf("Decode inverted planar pixel.\n");
769                                 DECODE_INVERTED_PLANAR_PIXEL(color, planeptr_src);
770             }
771                         else {
772                 //printf("Decode planar pixel.\n");
773                                 DECODE_PLANAR_PIXEL(color, planeptr_src);
774             }
775                         
776                         if (mask == 0xFF && (minterm == MINTERM_SRC || minterm == MINTERM_NOTSRC)) {
777                                 dptr[xs << rtg_display_format] = color;
778                                 goto skip;
779                         }
780
781             //printf("Place pixel.\n");
782                         HANDLE_MINTERM_PIXEL_8(color, dptr[xs << rtg_display_format], rtg_display_format);
783
784                         skip:;
785                         if ((cur_bit >>= 1) == 0) {
786                                 cur_bit = 0x80;
787                                 cur_byte++;
788                                 cur_byte %= srcpitch;
789                         }
790                 }
791                 dptr += pitch;
792         //if (line_y + sy + 1 == rtg_y[3])
793             //planeptr_src = &rtg_mem[rtg_address_adj[1]];// + (srcpitch * sy);
794         //else
795                 planeptr_src += srcpitch;
796                 cur_bit = base_bit;
797                 cur_byte = base_byte;
798         }*/
799 //}