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