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