1 #include "sysconfig.h"
2 #include "sysdeps.h"
3 
4 #include "options.h"
5 #include "xwin.h"
6 #include "uae.h"
7 #include "custom.h"
8 #include "drawing.h"
9 #include "gfxfilter.h"
10 #include "gui.h"
11 #include "uae/fs.h"
12 
13 #include <limits.h>
14 #include <stdlib.h>
15 
16 #ifdef PICASSO96
17 #include "picasso96.h"
18 #endif
19 
20 #include <fs/emu/video.h>
21 
22 int max_uae_width = 3072;
23 int max_uae_height = 2048;
24 
25 volatile bool vblank_found_chipset;
26 volatile bool vblank_found_rtg;
27 
28 #define MAXBLOCKLINES_MAX INT_MAX;
29 
30 #define AMIGA_WIDTH (AMIGA_WIDTH_MAX * 2)
31 //#define AMIGA_HEIGHT (AMIGA_HEIGHT_MAX * 2)
32 //#define AMIGA_HEIGHT 574
33 #define AMIGA_HEIGHT 572
34 
35 uae_s32 tyhrgb[65536];
36 uae_s32 tylrgb[65536];
37 uae_s32 tcbrgb[65536];
38 uae_s32 tcrrgb[65536];
39 
40 //#define USE_BUFMEM
41 //#define USE_LINEMEM
42 
43 struct MultiDisplay Displays[MAX_DISPLAYS + 1] = {};
44 
45 static int g_picasso_enabled = 0;
46 static int g_picasso_width = 0;
47 static int g_picasso_height = 0;
48 static int g_picasso_depth = 0;
49 static int g_picasso_format = 0;
50 
51 static int g_has_flushed_line = 0;
52 static int g_has_flushed_block = 0;
53 static int g_has_flushed_screen = 0;
54 
55 static int g_largest_width = 0;
56 static int g_largest_height = 0;
57 
58 struct uae_filter uaefilters[] = {
59     { UAE_FILTER_NULL, 0, 1, _T("Null filter"), _T("null"),
60             UAE_FILTER_MODE_16_16 | UAE_FILTER_MODE_32_32 },
61     { 0 }
62 };
63 
64 #define SET_FLAG(x, y) ((x) |= (y))
65 #define CLEAR_FLAG(x, y) ((x) &= ~(y))
66 #define SET_OR_CLEAR_FLAG(x, y, z) ((z) ? \
67         SET_FLAG((x), (y)) : CLEAR_FLAG((x), (y)))
68 
69 static volatile bool render_ok, wait_render;
70 
71 volatile bool thread_vblank_found;
72 // --- win32gfx.c
73 int screen_is_picasso = 0;
74 struct uae_filter *usedfilter;
75 uae_u32 redc[3 * 256], grec[3 * 256], bluc[3 * 256];
76 
77 static double remembered_vblank;
78 static int vblankbasewait, vblankbasefull;
79 RenderData g_renderdata;
80 static int g_screen_updated = 0;
81 
82 static uae_u8 g_linemem[4096 * 4];
83 static unsigned char* g_bufmem = NULL;
84 
85 static int g_red_bits;
86 static int g_green_bits;
87 static int g_blue_bits;
88 static int g_alpha_bits;
89 static int g_red_shift;
90 static int g_green_shift;
91 static int g_blue_shift;
92 static int g_alpha_shift;
93 
94 int g_amiga_rtg_modes[] = {
95         640, 360, // 16:9
96 
97         800, 450, // 16:9
98         800, 500, // 16:10
99         800, 600,
100 
101         1024, 576, // 16:9
102         1024, 600, // 16:10
103         1024, 768,
104 
105         1280, 720, // 16:9
106         //add_mode (md1, 1280, 800, 32, 50, 1); // 16:10
107         //add_mode (md1, 1280, 720, 32, 50, 1);
108 
109         0, 0,
110         0, 0,
111         0, 0,
112         0, 0,
113         0, 0,
114         0, 0,
115         0, 0,
116         0, 0,
117         0, 0,
118         -1, -1,
119 };
120 
121 #if 0
122 void uae_line_update(int line, int update) {
123     printf("%d %d\n", line, update);
124     if (!update) {
125         return;
126     }
127     // mark this line as not needing copy from the previous render buffer
128     g_renderdata.line[line] = 0;
129     g_screen_updated = 1;
130 }
131 #endif
132 
frame_drawn(void)133 void frame_drawn(void) {
134 
135 }
136 
flush_screen(struct vidbuffer * buffer,int first_line,int last_line)137 void flush_screen (struct vidbuffer *buffer, int first_line, int last_line) {
138     //write_log("flush_screen\n");
139     g_has_flushed_screen = 1;
140 }
141 
142 
target_graphics_buffer_update(void)143 bool target_graphics_buffer_update (void) {
144     write_log("target_graphics_buffer_update - clearing buffer\n");
145     memset(g_renderdata.pixels, 0, \
146             AMIGA_WIDTH * AMIGA_HEIGHT * g_amiga_video_bpp);
147     memset(g_renderdata.line, 0, AMIGA_MAX_LINES);
148     return 0;
149 }
150 
render_frame(bool immediate)151 static bool render_frame(bool immediate)
152 {
153 // FIXME: immediate is a new parameter
154 
155     //write_log("render_screen line: %d block %d screen %d\n",
156     //        g_has_flushed_line, g_has_flushed_block, g_has_flushed_screen);
157     int flushed = g_has_flushed_line || g_has_flushed_block ||
158             g_has_flushed_screen;
159 
160     g_renderdata.bpp = g_amiga_video_bpp;
161     // printf("%d %d %d\n", g_amiga_video_bpp, AMIGA_WIDTH, AMIGA_HEIGHT);
162 
163     static int cx, cy, cw, ch, crealh;
164     //printf("g_picasso_enabled %d\n", g_picasso_enabled);
165     if (g_picasso_enabled) {
166         g_renderdata.width = g_picasso_width;
167         g_renderdata.height = g_picasso_height;
168         g_renderdata.limit_x = 0;
169         g_renderdata.limit_y = 0;
170         g_renderdata.limit_w = g_picasso_width;
171         g_renderdata.limit_h = g_picasso_height;
172         //g_renderdata.updated = g_screen_updated;
173         g_renderdata.flags |= AMIGA_VIDEO_RTG_MODE;
174 
175 #ifdef USE_BUFMEM
176         //memcpy(g_renderdata.pixels, g_bufmem, g_picasso_width * g_picasso_height * g_amiga_video_bpp);
177 #endif
178         // FIXME
179         memset(g_renderdata.line, 0, AMIGA_MAX_LINES);
180     }
181     else {
182         if (gfxvidinfo.outbuffer) {
183             // if gfxvidinfo.outbuffer is not set, get_custom_limits will
184             // crash
185             if (flushed) {
186                 get_custom_limits(&cw, &ch, &cx, &cy, &crealh);
187                 // FIXME: crealh is new - find out what it does
188             }
189             else {
190                 // reuse last custom limits
191             }
192         }
193         if (cx < 0) {
194             //write_log("WARNING: custom limit x (%d) is < 0 - clamping\n", cx);
195             cx = 0;
196         }
197         if (cy < 0) {
198             //write_log("WARNING: custom limit y (%d) is < 0 - clamping\n", cy);
199             cy = 0;
200         }
201         if (cx + cw > AMIGA_WIDTH) {
202             //write_log("WARNING: custom limit x (%d) + w (%d) is > "
203             //        "AMIGA_WIDTH (%d) - clamping\n", cx, cw, AMIGA_WIDTH);
204             cw = AMIGA_WIDTH - cx;
205         }
206         if (cy + ch > AMIGA_HEIGHT) {
207             //write_log("WARNING: custom limit y (%d) + h (%d) is > "
208             //        "AMIGA_HEIGHT (%d) - clamping\n", cy, ch, AMIGA_HEIGHT);
209             ch = AMIGA_HEIGHT - cy;
210         }
211         g_renderdata.width = AMIGA_WIDTH;
212         g_renderdata.height = AMIGA_HEIGHT;
213         g_renderdata.limit_x = cx;
214         g_renderdata.limit_y = cy;
215         g_renderdata.limit_w = cw;
216         g_renderdata.limit_h = ch;
217         //g_renderdata.updated = g_screen_updated;
218         CLEAR_FLAG(g_renderdata.flags, AMIGA_VIDEO_RTG_MODE);
219         SET_OR_CLEAR_FLAG(g_renderdata.flags, AMIGA_VIDEO_LOW_RESOLUTION,
220                 currprefs.gfx_resolution == 0);
221         SET_OR_CLEAR_FLAG(g_renderdata.flags, AMIGA_VIDEO_LINE_DOUBLING,
222                 currprefs.gfx_vresolution == 1);
223 
224 #ifdef USE_BUFMEM
225         //printf("g_renderdata.pixels %p %p", g_renderdata.pixels, g_bufmem);
226         memcpy(g_renderdata.pixels, g_bufmem, AMIGA_WIDTH * AMIGA_HEIGHT * g_amiga_video_bpp);
227 #endif
228     }
229     //g_renderdata.line[first_line] = 0;
230     //g_renderdata.line[first_line + 1] = 0;
231     //for (int y = first_line; y <= last_line; y++) {
232     //    g_renderdata.line[y] = 0;
233     //}
234     g_screen_updated = 0;
235     //printf("flush_screen (%d -> %d) %d %d %d %d\n", first_line, last_line,
236     //        cx, cy, cw, ch);
237 
238     od_fs_update_leds();
239 
240     if (currprefs.turbo_emulation) {
241         g_renderdata.refresh_rate = -1;
242     }
243     else {
244         g_renderdata.refresh_rate = currprefs.chipset_refreshrate;
245     }
246 #if 0
247     printf("%0.2f\n", g_renderdata.refresh_rate);
248 #endif
249     if (g_libamiga_callbacks.render) {
250         g_libamiga_callbacks.render(&g_renderdata);
251     }
252 
253     g_has_flushed_line = 0;
254     g_has_flushed_block = 0;
255     g_has_flushed_screen = 0;
256 
257     if (fse_drivers()) {
258         notice_screen_contents_lost();
259     }
260     return 1;
261 }
262 
263 static int minimized;
264 static int monitor_off;
265 
dx_islost(void)266 static int dx_islost(void)
267 {
268         return 0;
269 }
270 
render_screen(bool immediate)271 bool render_screen(bool immediate)
272 {
273     bool v = false;
274     int cnt;
275 
276     render_ok = false;
277     if (minimized || picasso_on || monitor_off || dx_islost ())
278             return render_ok;
279     cnt = 0;
280     while (wait_render) {
281             sleep_millis (1);
282             cnt++;
283             if (cnt > 500)
284                     return render_ok;
285     }
286 #if 0
287     flushymin = 0;
288     flushymax = currentmode->amiga_height;
289     //EnterCriticalSection (&screen_cs);
290     if (currentmode->flags & DM_D3D) {
291             v = D3D_renderframe (immediate);
292 #endif
293     v = render_frame(immediate);
294 #if 0
295     } else if (currentmode->flags & DM_SWSCALE) {
296             S2X_render ();
297             v = true;
298     } else if (currentmode->flags & DM_DDRAW) {
299             v = true;
300     }
301 #endif
302     render_ok = v;
303     //LeaveCriticalSection (&screen_cs);
304     return render_ok;
305 }
306 
toggle_rtg(int mode)307 bool toggle_rtg (int mode)
308 {
309     UAE_LOG_STUB("mode=%d", mode);
310 #if 0
311         if (mode == 0) {
312                 if (!picasso_on)
313                         return false;
314         } else if (mode > 0) {
315                 if (picasso_on)
316                         return false;
317         }
318         if (currprefs.rtgmem_type >= GFXBOARD_HARDWARE) {
319                 return gfxboard_toggle (mode);
320         } else {
321                 // can always switch from RTG to custom
322                 if (picasso_requested_on && picasso_on) {
323                         picasso_requested_on = false;
324                         return true;
325                 }
326                 if (picasso_on)
327                         return false;
328                 // can only switch from custom to RTG if there is some mode act$
329                 if (picasso_is_active ()) {
330                         picasso_requested_on = true;
331                         return true;
332                 }
333         }
334 #endif
335         return false;
336 }
337 
show_screen(int mode)338 void show_screen (int mode)
339 {
340 #ifdef DEBUG_SHOW_SCREEN
341     printf("show_screen mode=%d\n\n", mode);
342 #endif
343     if (g_libamiga_callbacks.display) {
344         g_libamiga_callbacks.display();
345     }
346 }
347 
show_screen_maybe(bool show)348 bool show_screen_maybe (bool show) {
349 #ifdef DEBUG_SHOW_SCREEN
350     printf("show_screen_maybe %d (picasso_on=%d)\n", show, picasso_on);
351 #endif
352 
353     struct apmode *ap = picasso_on ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0];
354     if (!ap->gfx_vflip || ap->gfx_vsyncmode == 0 || !ap->gfx_vsync) {
355         if (show) {
356         //if (show && !picasso_on) {
357             show_screen (0);
358         }
359         return false;
360     }
361 #if 0
362 	if (ap->gfx_vflip < 0) {
363 		doflipevent ();
364 		return true;
365 	}
366 #endif
367     return false;
368 }
369 
vblank_calibrate(double approx_vblank,bool waitonly)370 double vblank_calibrate (double approx_vblank, bool waitonly) {
371     UAE_LOG_STUB("");
372     return -1;
373 }
374 
375 // FIXME: What is this?
376 int extraframewait = 0;
377 static int frame_missed, frame_counted, frame_errors;
378 static int frame_usage, frame_usage_avg, frame_usage_total;
379 //extern int log_vsync;
380 static bool dooddevenskip;
381 static volatile frame_time_t vblank_prev_time, thread_vblank_time;
382 //static bool vblankbaselace;
383 static int vblankbaselace_chipset;
384 //static bool vblankthread_oddeven;
385 
386 int log_vsync = 0, debug_vsync_min_delay = 0, debug_vsync_forced_delay = 0;
387 
vsync_busywait_start(void)388 void vsync_busywait_start(void) {
389     UAE_LOG_STUB("");
390     //changevblankthreadmode_fast (VBLANKTH_ACTIVE_START);
391     vblank_prev_time = thread_vblank_time;
392 }
393 
isthreadedvsync(void)394 static bool isthreadedvsync (void) {
395     return isvsync_chipset () <= -2 || isvsync_rtg () < 0;
396 }
397 
398 // FIXME
vsync_isdone(void)399 bool vsync_isdone (void) {
400     return vblank_found_chipset || dooddevenskip;
401 }
402 
vsync_busywait_do(int * freetime,bool lace,bool oddeven)403 int vsync_busywait_do (int *freetime, bool lace, bool oddeven) {
404     UAE_LOG_STUB("");
405     return false;
406 #if 0
407     bool v;
408     static bool framelost;
409     int ti;
410     frame_time_t t;
411     frame_time_t prevtime = vblank_prev_time;
412 
413     dooddevenskip = false;
414 
415     if (lace)
416         vblankbaselace_chipset = oddeven;
417     else
418         vblankbaselace_chipset = -1;
419 
420     t = read_processor_time ();
421     ti = t - prevtime;
422     //if (ti > 2 * vblankbasefull || ti < -2 * vblankbasefull) {
423     if (ti > 1 * vblankbasefull || ti < -1 * vblankbasefull) {
424 #if 0
425         waitvblankstate (false, NULL);
426 #endif
427         t = read_processor_time ();
428         vblank_prev_time = t;
429         thread_vblank_time = t;
430         frame_missed++;
431         return true;
432     }
433 
434     //if (log_vsync) {
435     //    console_out_f(_T("F:%8d M:%8d E:%8d %3d%% (%3d%%) %10d\r"), frame_counted, frame_missed, frame_errors, frame_usage, frame_usage_avg, (t - vblank_prev_time) - vblankbasefull);
436     //}
437 
438     if (freetime)
439         *freetime = 0;
440     if (currprefs.turbo_emulation) {
441         frame_missed++;
442         return true;
443     }
444 #if 0
445     frame_usage = (t - prevtime) * 100 / vblankbasefull;
446     if (frame_usage > 99)
447         frame_usage = 99;
448     else if (frame_usage < 0)
449         frame_usage = 0;
450     frame_usage_total += frame_usage;
451     if (freetime)
452         *freetime = frame_usage;
453     if (frame_counted)
454         frame_usage_avg = frame_usage_total / frame_counted;
455 #endif
456     v = false;
457 
458     if (isthreadedvsync ()) {
459 
460         framelost = false;
461         v = true;
462 
463     } else {
464 #if 0
465         bool doskip = false;
466 
467         if (!framelost && t - prevtime > vblankbasefull) {
468             framelost = true;
469             frame_missed++;
470             return true;
471         }
472 
473         if (vblanklaceskip ()) {
474             doskip = true;
475             dooddevenskip = true;
476         }
477 
478         if (!doskip) {
479             while (!framelost && read_processor_time () - prevtime < vblankbasewait1) {
480                 vsync_sleep (false);
481             }
482             v = vblank_wait ();
483         } else {
484             v = true;
485         }
486         framelost = false;
487 #endif
488     }
489 
490     if (v) {
491         vblank_prev_time = read_processor_time ();
492         frame_counted++;
493         return true;
494     }
495     frame_errors++;
496     return false;
497 #endif
498 }
499 
vsync_sleep(bool preferbusy)500 static void vsync_sleep (bool preferbusy) {
501 #if 0
502     struct apmode *ap = picasso_on ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0];
503     bool dowait;
504     if (vsync_busy_wait_mode == 0) {
505         dowait = ap->gfx_vflip || !preferbusy;
506     } else if (vsync_busy_wait_mode < 0) {
507         dowait = true;
508     } else {
509         dowait = false;
510     }
511     dowait = true;
512     if (dowait && currprefs.m68k_speed >= 0)
513         sleep_millis_main (1);
514 #endif
515 }
516 
517 
vsync_notvblank(void)518 static void vsync_notvblank (void) {
519     return;
520 #if 0
521     for (;;) {
522         int vp;
523         if (!getvblankpos (&vp))
524             return;
525         if (vp > 0) {
526             //write_log (_T("%d "), vpos);
527             break;
528         }
529         vsync_sleep (true);
530     }
531 #endif
532 }
533 
target_get_display(const TCHAR * name)534 int target_get_display (const TCHAR *name) {
535     return 0;
536 }
target_get_display_name(int num,bool friendlyname)537 const TCHAR *target_get_display_name (int num, bool friendlyname) {
538     // FIXME
539     return (TCHAR *) "Dummy Display";
540 }
541 
542 // FIXME
543 extern "C" {
544 int fs_ml_get_vblank_count();
545 }
546 
vsync_busywait_end(int * flipdelay)547 frame_time_t vsync_busywait_end (int *flipdelay) {
548 #if 0
549     printf("vsync_busywait_end\n");
550     show_screen ();
551 
552     static int last_vblank = 0;
553     while (fs_ml_get_vblank_count() == last_vblank) {
554 
555     }
556     last_vblank++;// = fs_ml_get_vblank_count();
557 
558     if (!dooddevenskip) {
559 #if 0
560         vsync_notvblank ();
561         while (!vblank_found && vblankthread_mode == VBLANKTH_ACTIVE) {
562             vsync_sleep (currprefs.m68k_speed < 0);
563         }
564 #endif
565     }
566     //changevblankthreadmode_fast (VBLANKTH_ACTIVE_WAIT);
567 #if 0
568     return thread_vblank_time;
569 
570     write_log("vsync_busywait_end\n");
571 #endif
572 #endif
573     return read_processor_time();
574 }
575 
getcurrentvblankrate(void)576 double getcurrentvblankrate (void)
577 {
578     UAE_LOG_STUB("");
579     if (remembered_vblank) {
580         return remembered_vblank;
581     }
582     return 50;
583 }
584 
uae_bits_in_mask(unsigned int mask)585 static int uae_bits_in_mask (unsigned int mask)
586 {
587     int n = 0;
588     while (mask) {
589         n += mask & 1;
590         mask >>= 1;
591     }
592     return n;
593 }
594 
uae_mask_shift(unsigned int mask)595 static int uae_mask_shift (unsigned int mask)
596 {
597     int n = 0;
598     while (!(mask & 1)) {
599         n++;
600         mask >>= 1;
601     }
602     return n;
603 }
604 
init_colors(void)605 static int init_colors (void)
606 {
607     write_log("init_colors\n");
608     alloc_colors64k(g_red_bits, g_green_bits, g_blue_bits, g_red_shift,
609             g_green_shift, g_blue_shift, 0, 0, 0, 0);
610     return 1;
611 }
612 
613 #include <fs/emu/hacks.h>
614 
getgfxoffset(float * dxp,float * dyp,float * mxp,float * myp)615 void getgfxoffset (float *dxp, float *dyp, float *mxp, float *myp)
616 {
617     /* Offset and scale factors used for magic mouse (in order to translate
618      * mouse coordinates to Amiga coordinates) */
619     *dxp = fs_emu_video_offset_x;
620     *dyp = fs_emu_video_offset_y;
621     *mxp = fs_emu_video_scale_x;
622     *myp = fs_emu_video_scale_y;
623 }
624 
toggle_fullscreen(int mode)625 void toggle_fullscreen (int mode)
626 {
627 
628 }
629 
isfullscreen(void)630 int isfullscreen (void)
631 {
632     return 0;
633 }
634 
flush_line(struct vidbuffer * buffer,int line_no)635 void flush_line (struct vidbuffer *buffer, int line_no)
636 {
637     //printf("- flush_line %d\n", line_no);
638 
639     //scrlinebuf
640 #ifdef USE_LINEMEM
641     unsigned char *dst = g_renderdata.pixels + AMIGA_WIDTH * g_amiga_video_bpp * line_no;
642     memcpy(dst, g_linemem, AMIGA_WIDTH * g_amiga_video_bpp);
643 #endif
644 
645 #ifndef USE_BUFMEM
646     // mark this line as not needing copy from the previous render buffer
647     g_renderdata.line[line_no] = 0;
648 #endif
649     g_screen_updated = 1;
650     g_has_flushed_line = 1;
651 }
652 
flush_block(struct vidbuffer * buffer,int first_line,int last_line)653 void flush_block (struct vidbuffer *buffer, int first_line, int last_line)
654 {
655     //printf("- flush_block %d %d\n", first_line, last_line);
656     //g_screen_updated = 1;
657     g_has_flushed_block = 1;
658 }
659 
lockscr(struct vidbuffer * buffer,bool fullupdate)660 int lockscr(struct vidbuffer *buffer, bool fullupdate)
661 {
662     return gfxvidinfo.drawbuffer.lockscr(&gfxvidinfo, buffer);
663 }
664 
unlockscr(struct vidbuffer * buffer)665 void unlockscr(struct vidbuffer *buffer)
666 {
667     gfxvidinfo.drawbuffer.unlockscr(&gfxvidinfo, buffer);
668 }
669 
graphics_setup()670 int graphics_setup()
671 {
672     write_log("graphics_setup\n");
673     return 1;
674 }
675 
grow_render_buffer(int width,int height)676 static void grow_render_buffer(int width, int height)
677 {
678     unsigned char *new_pixels = (unsigned char*) g_renderdata.grow(width, height);
679     if (new_pixels != g_renderdata.pixels) {
680         //printf("new %p old %p\n", new_pixels, g_renderdata.pixels);
681         //printf("grow_render_buffer %d %d\n", width, height);
682         g_renderdata.pixels = new_pixels;
683         gfxvidinfo.drawbuffer.bufmem = new_pixels;
684         init_row_map();
685         //printf("grow_render_buffer %d %d done\n", width, height);
686     }
687 }
688 
amiga_set_render_buffer(void * data,int size,int need_redraw,void * (* grow)(int width,int height))689 void amiga_set_render_buffer(void *data, int size, int need_redraw,
690         void *(*grow)(int width, int height))
691 {
692     //printf("set render buffer %p\n", data);
693     g_renderdata.grow = grow;
694     g_renderdata.pixels = (unsigned char *) data;
695 
696     //printf("\n\n\n\n\n\n\n\n set buffer %p %d\n", data, size);
697     //g_renderdata.pixels = (unsigned char*) data;
698     //g_renderdata.pixels = (unsigned char*) data;
699 
700 #ifndef USE_BUFMEM
701     // reset line information
702     memset(g_renderdata.line, 1, AMIGA_MAX_LINES);
703 #ifndef USE_LINEMEM
704     //printf("setting bufmem\n");
705     gfxvidinfo.drawbuffer.bufmem = (unsigned char*) data;
706 #endif
707     //printf("updating row map\n");
708 
709     grow_render_buffer(g_largest_width, g_largest_height);
710     init_row_map();
711 #endif
712 }
713 
uae_get_render_buffer()714 uint8_t *uae_get_render_buffer()
715 {
716     return g_renderdata.pixels;
717 }
718 
719 #define RGBA_MASK_R 0x000000ff
720 #define RGBA_MASK_G 0x0000ff00
721 #define RGBA_MASK_B 0x00ff0000
722 #define RGBA_MASK_A 0xff000000
723 
724 #define R5G6B5_MASK_R 0xf800
725 #define R5G6B5_MASK_G 0x07e0
726 #define R5G6B5_MASK_B 0x001f
727 
728 #define R5G5B5A1_MASK_R 0xf800
729 #define R5G5B5A1_MASK_G 0x07c0
730 #define R5G5B5A1_MASK_B 0x003e
731 #define R5G5B5A1_MASK_A 0x0001
732 
graphics_init(bool mousecapture)733 int graphics_init(bool mousecapture)
734 {
735     write_log("graphics_init\n");
736 
737     // FIXME: perhaps modify so custom_limits defaults to -1, -1, -1, -1
738     set_custom_limits (-1, -1, -1, -1);
739 
740     if (g_amiga_video_format == AMIGA_VIDEO_FORMAT_R5G6B5) {
741         g_red_bits    = uae_bits_in_mask(R5G6B5_MASK_R);
742         g_red_shift   = uae_mask_shift(R5G6B5_MASK_R);
743         g_green_bits  = uae_bits_in_mask(R5G6B5_MASK_G);
744         g_green_shift = uae_mask_shift(R5G6B5_MASK_G);
745         g_blue_bits   = uae_bits_in_mask(R5G6B5_MASK_B);
746         g_blue_shift  = uae_mask_shift(R5G6B5_MASK_B);
747         g_alpha_bits   = 0;
748         g_alpha_shift  = 0;
749     }
750     else if (g_amiga_video_format == AMIGA_VIDEO_FORMAT_R5G5B5A1) {
751         g_red_bits    = uae_bits_in_mask(R5G5B5A1_MASK_R);
752         g_red_shift   = uae_mask_shift(R5G5B5A1_MASK_R);
753         g_green_bits  = uae_bits_in_mask(R5G5B5A1_MASK_G);
754         g_green_shift = uae_mask_shift(R5G5B5A1_MASK_G);
755         g_blue_bits   = uae_bits_in_mask(R5G5B5A1_MASK_B);
756         g_blue_shift  = uae_mask_shift(R5G5B5A1_MASK_B);
757         g_alpha_bits   = uae_bits_in_mask(R5G5B5A1_MASK_A);
758         g_alpha_shift  = uae_mask_shift(R5G5B5A1_MASK_A);
759     }
760     else { // RGBA or BGRA
761         if (g_amiga_video_format == AMIGA_VIDEO_FORMAT_RGBA) {
762             g_red_bits    = uae_bits_in_mask(RGBA_MASK_R);
763             g_red_shift   = uae_mask_shift(RGBA_MASK_R);
764             g_blue_bits   = uae_bits_in_mask(RGBA_MASK_B);
765             g_blue_shift  = uae_mask_shift(RGBA_MASK_B);
766         }
767         else { // BGRA
768             g_red_bits   = uae_bits_in_mask(RGBA_MASK_B);
769             g_red_shift  = uae_mask_shift(RGBA_MASK_B);
770             g_blue_bits    = uae_bits_in_mask(RGBA_MASK_R);
771             g_blue_shift   = uae_mask_shift(RGBA_MASK_R);
772         }
773         g_green_bits  = uae_bits_in_mask(RGBA_MASK_G);
774         g_green_shift = uae_mask_shift(RGBA_MASK_G);
775         g_alpha_bits   = uae_bits_in_mask(RGBA_MASK_A);
776         g_alpha_shift  = uae_mask_shift(RGBA_MASK_A);
777     }
778 
779     //g_renderdata.pixels = (unsigned char*) malloc(AMIGA_WIDTH*AMIGA_HEIGHT*4);
780 
781     memset(g_renderdata.line, 0, AMIGA_MAX_LINES);
782     gfxvidinfo.maxblocklines = 0;
783 #ifdef USE_BUFMEM
784     g_bufmem = (unsigned char*) malloc(AMIGA_WIDTH * AMIGA_HEIGHT * g_amiga_video_bpp);
785     gfxvidinfo.drawbuffer.bufmem = g_bufmem;
786     memset(g_bufmem, 0, AMIGA_WIDTH * AMIGA_HEIGHT * g_amiga_video_bpp);
787     gfxvidinfo.maxblocklines = MAXBLOCKLINES_MAX;
788 #endif
789 
790 #ifdef USE_LINEMEM
791     gfxvidinfo.drawbuffer.emergmem = 0;
792     gfxvidinfo.drawbuffer.linemem = g_linemem;
793 #else
794     gfxvidinfo.drawbuffer.emergmem = 0; //g_linemem;
795     gfxvidinfo.drawbuffer.linemem = 0;
796 #endif
797     gfxvidinfo.drawbuffer.pixbytes = g_amiga_video_bpp;
798     gfxvidinfo.drawbuffer.rowbytes = AMIGA_WIDTH * g_amiga_video_bpp;
799     gfxvidinfo.drawbuffer.height_allocated = AMIGA_HEIGHT;
800     gfxvidinfo.drawbuffer.inheight = AMIGA_HEIGHT;
801     gfxvidinfo.drawbuffer.outheight = AMIGA_HEIGHT;
802     gfxvidinfo.drawbuffer.width_allocated = AMIGA_WIDTH;
803     gfxvidinfo.drawbuffer.inwidth = AMIGA_WIDTH;
804     gfxvidinfo.drawbuffer.outwidth = AMIGA_WIDTH;
805 
806     //gfxvidinfo.flush_block = libamiga_flush_block;
807     //gfxvidinfo.flush_screen = libamiga_flush_screen;
808     //SDL_SetColors (display, arSDLColors, 0, 256);
809     write_log("calling reset_drawing\n");
810     reset_drawing ();
811     init_colors ();
812 
813 //#ifdef USE_BUFMEM
814 //    init_row_map();
815 //#endif
816 
817     //write_log("FIXME: NOT USING VSYNC TRICK\n");
818     // Trick UAE into sending believing we are in vsync / fullscreen
819     // so a flush command is sent for each frame update in do_flush_screen.
820 
821     if (currprefs.m68k_speed == -1) {
822         write_log("currprefs.m68k_speed is -1, not allowing full sync\n");
823     }
824     else {
825         //currprefs.gfx_apmode[0].gfx_fullscreen = GFX_FULLSCREEN;
826         currprefs.gfx_apmode[0].gfx_vsync = 1;
827     }
828 
829     //currprefs.gfx_apmode[0].gfx_fullscreen = GFX_FULLSCREEN;
830     //currprefs.gfx_apmode[0].gfx_vsync = 1;
831 
832     //currprefs.gfx_apmode[0].gfx_vsyncmode = 1;
833     //currprefs.gfx_apmode[1].gfx_fullscreen = GFX_FULLSCREEN;
834     //currprefs.gfx_apmode[1].gfx_vsync = 1;
835 
836     //amiga_set_option("gfx_vsync", "true");
837     //amiga_set_option("gfx_vsyncmode", "busywait");
838 
839     return 1;
840 }
841 
graphics_leave(void)842 void graphics_leave (void)
843 {
844 
845 }
846 
check_prefs_changed_gfx(void)847 int check_prefs_changed_gfx (void)
848 {
849     //write_log("check_prefs_changed_gfx\n");
850     return 0;
851 }
852 
gui_fps(int fps,int idle,int color)853 void gui_fps (int fps, int idle, int color)
854 {
855     UAE_LOG_STUB_MAX(1, "");
856 }
857 
gui_update(void)858 int gui_update (void)
859 {
860     return 0;
861 }
862 
gfx_set_picasso_colors(RGBFTYPE rgbfmt)863 void gfx_set_picasso_colors (RGBFTYPE rgbfmt)
864 {
865     write_log("gfx_set_picasso_colors %d\n", rgbfmt);
866 
867     alloc_colors_picasso(g_red_bits, g_green_bits, g_blue_bits, g_red_shift,
868             g_green_shift, g_blue_shift, rgbfmt);
869 }
870 
picasso_palette(void)871 int picasso_palette (void)
872 {
873     int i, changed;
874 
875     changed = 0;
876     for (i = 0; i < 256; i++) {
877         int r = picasso96_state.CLUT[i].Red;
878         int g = picasso96_state.CLUT[i].Green;
879         int b = picasso96_state.CLUT[i].Blue;
880         uae_u32 v = (doMask256 (r, g_red_bits, g_red_shift)
881             | doMask256 (g, g_green_bits, g_green_shift)
882             | doMask256 (b, g_blue_bits, g_blue_shift))
883             | doMask256 (0xff, g_alpha_bits, g_alpha_shift);
884         if (v != picasso_vidinfo.clut[i]) {
885             //write_log (_T("%d:%08x\n"), i, v);
886             picasso_vidinfo.clut[i] = v;
887             changed = 1;
888         }
889     }
890     return changed;
891 }
892 
893 static bool rtg_locked;
894 
gfx_lock_picasso2(bool fullupdate)895 static uae_u8 *gfx_lock_picasso2 (bool fullupdate)
896 {
897     picasso_vidinfo.rowbytes = picasso_vidinfo.width * g_amiga_video_bpp;
898     uae_u8 *buffer = uae_get_render_buffer();
899     // printf("gfx_lock_picasso2 buffer=%p\n", buffer);
900     return buffer;
901 }
902 
gfx_lock_picasso(bool fullupdate,bool doclear)903 uae_u8 *gfx_lock_picasso (bool fullupdate, bool doclear)
904 {
905     // FIXME: currently ignoring fullupdate (what does it do?)
906     static uae_u8 *p;
907     if (rtg_locked) {
908             return p;
909     }
910 #if 0
911     EnterCriticalSection (&screen_cs);
912 #endif
913     p = gfx_lock_picasso2 (fullupdate);
914     if (!p) {
915 #if 0
916             LeaveCriticalSection (&screen_cs);
917 #endif
918     } else {
919         rtg_locked = true;
920         if (doclear) {
921             uae_u8 *p2 = p;
922             for (int h = 0; h < picasso_vidinfo.height; h++) {
923                 memset (p2, 0, picasso_vidinfo.width * picasso_vidinfo.pixbytes);
924                 p2 += picasso_vidinfo.rowbytes;
925             }
926         }
927     }
928     return p;
929 }
930 
gfx_unlock_picasso(bool dorender)931 void gfx_unlock_picasso (bool dorender)
932 {
933 #ifdef DEBUG_SHOW_SCREEN
934     printf("gfx_unlock_picasso dorender=%d\n", dorender);
935 #endif
936 
937 #if 0
938     if (!rtg_locked)
939             EnterCriticalSection (&screen_cs);
940 #endif
941 
942     rtg_locked = false;
943 
944     if (dorender) {
945         //render_screen(1);
946         // FIXME: check what mode parameter is supposed to do
947         //show_screen(0);
948         if (render_frame(false)) {
949             show_screen_maybe(true);
950         }
951     }
952 }
953 
954 #if 1
955 
gfx_set_picasso_state(int on)956 void gfx_set_picasso_state (int on)
957 {
958     write_log("gfx_set_picasso_state %d\n", on);
959     g_picasso_enabled = (on != 0);
960 }
961 
962 #else
963 
gfx_set_picasso_state(int on)964 void gfx_set_picasso_state (int on)
965 {
966 	printf("gfx_set_picasso_state %d\n", on);
967 #if 0
968 
969 	//struct winuae_currentmode wc;
970 	int mode;
971 
972 	if (screen_is_picasso == on)
973 		return;
974 	screen_is_picasso = on;
975 	//rp_rtg_switch ();
976 	//memcpy (&wc, currentmode, sizeof (wc));
977 
978 	//updatemodes ();
979 	//update_gfxparams ();
980 	//clearscreen ();
981 	if (currprefs.gfx_apmode[0].gfx_fullscreen != currprefs.gfx_apmode[1].gfx_fullscreen || (currprefs.gfx_apmode[0].gfx_fullscreen == GFX_FULLSCREEN && currprefs.gfx_api)) {
982 		mode = 1;
983 	} else {
984 		mode = modeswitchneeded (&wc);
985 		if (!mode)
986 			goto end;
987 	}
988 	if (mode < 0) {
989 		open_windows (0);
990 	} else {
991 		open_screen (); // reopen everything
992 	}
993 	if (on && isvsync_rtg () < 0)
994 		vblank_calibrate (0, false);
995 end:
996 #ifdef RETROPLATFORM
997 	rp_set_hwnd (hAmigaWnd);
998 #endif
999 #endif
1000 }
1001 
1002 #endif
1003 
1004 #if 1
1005 
gfx_set_picasso_modeinfo(uae_u32 w,uae_u32 h,uae_u32 depth,RGBFTYPE rgbfmt)1006 void gfx_set_picasso_modeinfo (uae_u32 w, uae_u32 h, uae_u32 depth,
1007         RGBFTYPE rgbfmt) {
1008     write_log("gfx_set_picasso_modeinfo %d %d %d %d\n", w, h, depth, rgbfmt);
1009     g_picasso_width = w;
1010     g_picasso_height = h;
1011     g_picasso_depth = depth;
1012     g_picasso_format = rgbfmt;
1013 
1014     // register largest width seen, so render buffers can be adjusted if
1015     // necessary
1016     if (g_picasso_width > g_largest_width) {
1017         g_largest_width = g_picasso_width;
1018     }
1019     if (g_picasso_height > g_largest_height) {
1020         g_largest_height = g_picasso_height;
1021     }
1022     grow_render_buffer(g_largest_width, g_largest_height);
1023 
1024     gfx_set_picasso_colors (rgbfmt);
1025 
1026     picasso_vidinfo.width = g_picasso_width;
1027     picasso_vidinfo.height = g_picasso_height;
1028 }
1029 
1030 #else
1031 
gfx_set_picasso_modeinfo(uae_u32 w,uae_u32 h,uae_u32 depth,RGBFTYPE rgbfmt)1032 void gfx_set_picasso_modeinfo (uae_u32 w, uae_u32 h, uae_u32 depth, RGBFTYPE rgbfmt)
1033 {
1034 	printf("gfx_set_picasso_modeinfo %d %d %d %d\n", w, h, depth, rgbfmt);
1035 	exit(1);
1036 #if 0
1037 	int need;
1038 	if (!screen_is_picasso)
1039 		return;
1040 	clearscreen ();
1041 #endif
1042 	gfx_set_picasso_colors (rgbfmt);
1043 #if 0
1044 	updatemodes ();
1045 	need = modeswitchneeded (currentmode);
1046 	update_gfxparams ();
1047 	if (need > 0) {
1048 		open_screen ();
1049 	} else if (need < 0) {
1050 		open_windows (0);
1051 	}
1052 #endif
1053 #ifdef RETROPLATFORM
1054 	rp_set_hwnd (hAmigaWnd);
1055 #endif
1056 }
1057 
1058 #endif
1059