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