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