From 9b964fa00e6aad80a85b4a93b04f42c5c5243fcc Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sun, 8 Apr 2018 20:27:06 +0300 Subject: [PATCH] 4000b1. Lagless vsync and multimonitor megapatch. --- ar.cpp | 11 +- arcadia.cpp | 6 +- blitter.cpp | 72 +- cfgfile.cpp | 187 +- consolehook.cpp | 4 +- custom.cpp | 746 +++-- debug.cpp | 8 +- devices.cpp | 8 +- drawing.cpp | 858 +++--- events.cpp | 119 +- framebufferboards.cpp | 20 +- gfxboard.cpp | 299 +- gfxutil.cpp | 52 +- include/custom.h | 9 +- include/drawing.h | 28 +- include/events.h | 2 - include/gfxboard.h | 10 +- include/gfxfilter.h | 35 +- include/inputdevice.h | 6 +- include/options.h | 28 +- include/scsi.h | 1 + include/specialmonitors.h | 4 + include/statusline.h | 14 +- include/xwin.h | 85 +- inputdevice.cpp | 117 +- main.cpp | 86 +- mame/a2410.cpp | 43 +- od-win32/ahidsound_dsonly.cpp | 8 +- od-win32/avioutput.cpp | 60 +- od-win32/bsdsock.cpp | 29 +- od-win32/dinput.cpp | 30 +- od-win32/direct3d.cpp | 230 +- od-win32/direct3d.h | 53 +- od-win32/direct3d11.cpp | 490 ++-- od-win32/dxwrap.cpp | 19 +- od-win32/dxwrap.h | 54 + od-win32/keyboard_win32.cpp | 8 +- od-win32/parser.cpp | 12 +- od-win32/picasso96_win.cpp | 769 ++--- od-win32/picasso96_win.h | 68 +- od-win32/resources/resource.h | 5 +- od-win32/resources/winuae.rc | 94 +- od-win32/rp.cpp | 125 +- od-win32/scaler_more.cpp | 12 +- od-win32/screenshot.cpp | 46 +- od-win32/sounddep/sound.cpp | 4 +- od-win32/statusline_win32.cpp | 33 +- od-win32/win32.cpp | 726 +++-- od-win32/win32.h | 33 +- od-win32/win32_scaler.cpp | 245 +- od-win32/win32gfx.cpp | 3069 ++++++++------------ od-win32/win32gfx.h | 33 +- od-win32/win32gui.cpp | 310 +- od-win32/win32gui_extra.cpp | 1 + od-win32/winuae_msvc15/winuae_msvc.vcxproj | 34 +- specialmonitors.cpp | 126 +- statusline.cpp | 15 +- 57 files changed, 4949 insertions(+), 4650 deletions(-) diff --git a/ar.cpp b/ar.cpp index a0d0e26a..e45cbe1a 100644 --- a/ar.cpp +++ b/ar.cpp @@ -215,6 +215,7 @@ #include "savestate.h" #include "crc32.h" #include "akiko.h" +#include "xwin.h" #define DEBUG #ifdef DEBUG @@ -267,18 +268,20 @@ void check_prefs_changed_carts (int in_memory_reset); static int stored_picasso_on = -1; -static void cartridge_enter (void) +static void cartridge_enter(void) { + struct amigadisplay *ad = &adisplays[0]; #ifdef PICASSO96 - stored_picasso_on = picasso_requested_on; - picasso_requested_on = 0; + stored_picasso_on = ad->picasso_requested_on; + ad->picasso_requested_on = 0; #endif } static void cartridge_exit (void) { + struct amigadisplay *ad = &adisplays[0]; #ifdef PICASSO96 if (stored_picasso_on > 0) - picasso_requested_on = 1; + ad->picasso_requested_on = 1; stored_picasso_on = -1; #endif } diff --git a/arcadia.cpp b/arcadia.cpp index 49890dfe..b2551ee3 100644 --- a/arcadia.cpp +++ b/arcadia.cpp @@ -1044,14 +1044,16 @@ static int ts_height_offset = -8; int touch_serial_write(void) { + struct vidbuf_description *avidinfo = &adisplays[0].gfxvidinfo; + if (!(cubo_settings & 0x40000)) return -1; if (!touch_write_buf_offset && touch_active) { if ((cubo_flag & 0x80000000) && !(cubo_flag & 0x40000000)) { uae_u8 *p = touch_data_w; - int sw = gfxvidinfo.drawbuffer.inwidth * ts_width_mult / 1000; - int sh = gfxvidinfo.drawbuffer.inheight * ts_height_mult / 1000; + int sw = avidinfo->drawbuffer.inwidth * ts_width_mult / 1000; + int sh = avidinfo->drawbuffer.inheight * ts_height_mult / 1000; int x = ((lightpen_x[0] + ts_width_offset) * 999) / sw; int y = ((lightpen_y[0] + ts_height_offset) * 999) / sh; diff --git a/blitter.cpp b/blitter.cpp index 914dbaed..65589053 100644 --- a/blitter.cpp +++ b/blitter.cpp @@ -73,6 +73,7 @@ uae_u32 blit_masktable[BLITTER_MAX_WORDS]; enum blitter_states bltstate; static int blit_cyclecounter, blit_waitcyclecounter; +static uaecptr blit_waitpc; static int blit_maxcyclecounter, blit_slowdown, blit_totalcyclecounter; static int blit_startcycles, blit_misscyclecounter; @@ -95,6 +96,15 @@ int blit_interrupt; static int last_blitter_hpos; +static uae_u16 debug_bltcon0, debug_bltcon1; +static uae_u32 debug_bltapt, debug_bltbpt, debug_bltcpt, debug_bltdpt; +static uae_u16 debug_bltamod, debug_bltbmod, debug_bltcmod, debug_bltdmod; +static uae_u32 debug_bltafwm, debug_bltalwm; +static uae_u32 debug_bltpc; +static int debug_bltcop; +static uae_u16 debug_bltsizev, debug_bltsizeh; +static uae_u16 debug_bltadat, debug_bltbdat, debug_bltcdat; + #define BLITTER_STARTUP_CYCLES 2 /* @@ -307,20 +317,56 @@ STATIC_INLINE void record_dma_blit (uae_u16 reg, uae_u16 dat, uae_u32 addr, int #endif } +static void blitter_debugsave(int copper, uaecptr pc) +{ + debug_bltcon0 = bltcon0; + debug_bltcon1 = bltcon1; + debug_bltsizev = blt_info.vblitsize; + debug_bltsizeh = blt_info.hblitsize; + debug_bltapt = bltapt; + debug_bltbpt = bltbpt; + debug_bltcpt = bltcpt; + debug_bltdpt = bltdpt; + debug_bltadat = blt_info.bltadat; + debug_bltbdat = blt_info.bltbdat; + debug_bltcdat = blt_info.bltcdat; + debug_bltamod = blt_info.bltamod; + debug_bltbmod = blt_info.bltbmod; + debug_bltcmod = blt_info.bltcmod; + debug_bltdmod = blt_info.bltdmod; + debug_bltafwm = blt_info.bltafwm; + debug_bltalwm = blt_info.bltalwm; + debug_bltpc = pc; + debug_bltcop = copper; +} + static void blitter_dump (void) { int chipsize = currprefs.chipmem_size; - write_log (_T("PT A=%08X B=%08X C=%08X D=%08X\n"), bltapt, bltbpt, bltcpt, bltdpt); - write_log (_T("CON0=%04X CON1=%04X DAT A=%04X B=%04X C=%04X\n"), + console_out_f(_T("PT A=%08X B=%08X C=%08X D=%08X\n"), bltapt, bltbpt, bltcpt, bltdpt); + console_out_f(_T("CON0=%04X CON1=%04X DAT A=%04X B=%04X C=%04X\n"), bltcon0, bltcon1, blt_info.bltadat, blt_info.bltbdat, blt_info.bltcdat); - write_log (_T("AFWM=%04X ALWM=%04X MOD A=%04X B=%04X C=%04X D=%04X\n"), + console_out_f(_T("AFWM=%04X ALWM=%04X MOD A=%04X B=%04X C=%04X D=%04X\n"), blt_info.bltafwm, blt_info.bltalwm, blt_info.bltamod & 0xffff, blt_info.bltbmod & 0xffff, blt_info.bltcmod & 0xffff, blt_info.bltdmod & 0xffff); - write_log (_T("PC=%08X DMA=%d\n"), m68k_getpc (), dmaen (DMA_BLITTER)); + console_out_f(_T("PC=%08X DMA=%d\n"), m68k_getpc(), dmaen (DMA_BLITTER)); if (((bltcon0 & 0x800) && bltapt >= chipsize) || ((bltcon0 & 0x400) && bltbpt >= chipsize) || ((bltcon0 & 0x200) && bltcpt >= chipsize) || ((bltcon0 & 0x100) && bltdpt >= chipsize)) - write_log (_T("PT outside of chipram\n")); + console_out_f(_T("PT outside of chipram\n")); +} + +void blitter_debugdump(void) +{ + console_out(_T("Blitter registers at start:\n")); + console_out_f(_T("PT A=%08X B=%08X C=%08X D=%08X\n"), debug_bltapt, debug_bltbpt, debug_bltcpt, debug_bltdpt); + console_out_f(_T("CON0=%04X CON1=%04X DAT A=%04X B=%04X C=%04X\n"), + debug_bltcon0, debug_bltcon1, debug_bltadat, debug_bltbdat, debug_bltcdat); + console_out_f(_T("AFWM=%04X ALWM=%04X MOD A=%04X B=%04X C=%04X D=%04X\n"), + debug_bltafwm, debug_bltalwm, debug_bltamod, debug_bltbmod, debug_bltcmod, debug_bltdmod); + console_out_f(_T("COP=%d PC=%08X\n"), debug_bltcop, debug_bltpc); + console_out(_T("Blitter registers now:\n")); + blitter_dump(); } STATIC_INLINE const int *get_ch (void) @@ -796,7 +842,7 @@ static void decide_blitter_line (int hsync, int hpos) blit_cyclecounter++; blit_totalcyclecounter++; if (blit_cyclecounter >= 2) { - blitter_done (last_blitter_hpos); + blitter_done(last_blitter_hpos); return; } break; @@ -1107,7 +1153,7 @@ static void do_startcycles (int hpos) blit_faulty = -1; bltstate = BLT_done; blit_final = 0; - do_blitter (vhpos, 0); + do_blitter(vhpos, 0, blit_waitpc); blit_startcycles = 0; blit_cyclecounter = 0; blit_waitcyclecounter = 0; @@ -1515,7 +1561,7 @@ static void blitter_start_init (void) } } -static void do_blitter2 (int hpos, int copper) +static void do_blitter2(int hpos, int copper, uaecptr pc) { int cycles; int cleanstart; @@ -1564,6 +1610,9 @@ static void do_blitter2 (int hpos, int copper) original_line = blitline; } + if (memwatch_enabled) + blitter_debugsave(copper, pc); + if ((log_blitter & 1) || ((log_blitter & 32) && !blitline)) { blitter_dontdo = 0; if (1) { @@ -1660,10 +1709,10 @@ void blitter_check_start (void) } } -void do_blitter (int hpos, int copper) +void do_blitter(int hpos, int copper, uaecptr pc) { if (bltstate == BLT_done || !blitter_cycle_exact) { - do_blitter2 (hpos, copper); + do_blitter2(hpos, copper, pc); return; } if (!dmaen (DMA_BLITTER) || !blt_info.got_cycle) @@ -1672,6 +1721,7 @@ void do_blitter (int hpos, int copper) // and we must let it finish blit_startcycles = BLITTER_STARTUP_CYCLES; blit_waitcyclecounter = copper; + blit_waitpc = pc; } void maybe_blit (int hpos, int hack) @@ -1939,7 +1989,7 @@ uae_u8 *restore_blitter_new (uae_u8 *src) bltstate = BLT_done; if (!blitter_cycle_exact) { if (state > 0) - do_blitter (0, 0); + do_blitter(0, 0, 0); } else { if (state == 1) bltstate = BLT_init; diff --git a/cfgfile.cpp b/cfgfile.cpp index d7995e4e..d7b8749d 100644 --- a/cfgfile.cpp +++ b/cfgfile.cpp @@ -39,6 +39,7 @@ #include "ethernet.h" #include "native2amiga_api.h" #include "ini.h" +#include "specialmonitors.h" #define cfgfile_warning write_log #define cfgfile_warning_obsolete write_log @@ -198,7 +199,7 @@ static const TCHAR *joyportmodes[] = { _T(""), _T("mouse"), _T("mousenowheel"), static const TCHAR *joyaf[] = { _T("none"), _T("normal"), _T("toggle"), _T("always"), 0 }; static const TCHAR *epsonprinter[] = { _T("none"), _T("ascii"), _T("epson_matrix_9pin"), _T("epson_matrix_24pin"), _T("epson_matrix_48pin"), 0 }; static const TCHAR *aspects[] = { _T("none"), _T("vga"), _T("tv"), 0 }; -static const TCHAR *vsyncmodes[] = { _T("adaptive"), _T("false"), _T("true"), _T("autoswitch"), 0 }; +static const TCHAR *vsyncmodes[] = { _T("false"), _T("true"), _T("autoswitch"), 0 }; static const TCHAR *vsyncmodes2[] = { _T("normal"), _T("busywait"), 0 }; static const TCHAR *filterapi[] = { _T("directdraw"), _T("direct3d"), _T("direct3d11"), 0 }; static const TCHAR *filterapiopts[] = { _T("hardware"), _T("software"), 0 }; @@ -211,8 +212,6 @@ static const TCHAR *dongles[] = }; static const TCHAR *cdmodes[] = { _T("disabled"), _T(""), _T("image"), _T("ioctl"), _T("spti"), _T("aspi"), 0 }; static const TCHAR *cdconmodes[] = { _T(""), _T("uae"), _T("ide"), _T("scsi"), _T("cdtv"), _T("cd32"), 0 }; -static const TCHAR *specialmonitors[] = { _T("none"), _T("autodetect"), _T("a2024"), _T("graffiti"), -_T("ham_e"), _T("ham_e_plus"), _T("videodac18"), _T("avideo12"), _T("avideo24"), _T("firecracker24"), _T("dctv"), _T("opalvision"), _T("colorburst"), 0 }; static const TCHAR *genlockmodes[] = { _T("none"), _T("noise"), _T("testcard"), _T("image"), _T("video"), _T("stream"), _T("ld"), _T("sony_ld"), _T("pioneer_ld"), NULL }; static const TCHAR *ppc_implementations[] = { _T("auto"), @@ -1902,15 +1901,13 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) cfgfile_write_str (f, _T("gfx_display_name_rtg"), target_get_display_name (p->gfx_apmode[APMODE_RTG].gfx_display, false)); cfgfile_write (f, _T("gfx_framerate"), _T("%d"), p->gfx_framerate); - write_resolution (f, _T("gfx_width"), _T("gfx_height"), &p->gfx_size_win); /* compatibility with old versions */ - cfgfile_write (f, _T("gfx_top_windowed"), _T("%d"), p->gfx_size_win.x); - cfgfile_write (f, _T("gfx_left_windowed"), _T("%d"), p->gfx_size_win.y); - write_resolution (f, _T("gfx_width_windowed"), _T("gfx_height_windowed"), &p->gfx_size_win); - write_resolution (f, _T("gfx_width_fullscreen"), _T("gfx_height_fullscreen"), &p->gfx_size_fs); + write_resolution (f, _T("gfx_width"), _T("gfx_height"), &p->gfx_monitor[0].gfx_size_win); /* compatibility with old versions */ + cfgfile_write (f, _T("gfx_top_windowed"), _T("%d"), p->gfx_monitor[0].gfx_size_win.x); + cfgfile_write (f, _T("gfx_left_windowed"), _T("%d"), p->gfx_monitor[0].gfx_size_win.y); + write_resolution (f, _T("gfx_width_windowed"), _T("gfx_height_windowed"), &p->gfx_monitor[0].gfx_size_win); + write_resolution (f, _T("gfx_width_fullscreen"), _T("gfx_height_fullscreen"), &p->gfx_monitor[0].gfx_size_fs); cfgfile_write (f, _T("gfx_refreshrate"), _T("%d"), p->gfx_apmode[0].gfx_refreshrate); cfgfile_dwrite (f, _T("gfx_refreshrate_rtg"), _T("%d"), p->gfx_apmode[1].gfx_refreshrate); - cfgfile_write_bool(f, _T("gfx_tearing"), p->gfx_apmode[0].gfx_tearing); - cfgfile_write_bool(f, _T("gfx_tearing_rtg"), p->gfx_apmode[1].gfx_tearing); cfgfile_write (f, _T("gfx_autoresolution"), _T("%d"), p->gfx_autoresolution); cfgfile_dwrite (f, _T("gfx_autoresolution_delay"), _T("%d"), p->gfx_autoresolution_delay); @@ -1922,9 +1919,9 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) cfgfile_write (f, _T("gfx_backbuffers_rtg"), _T("%d"), p->gfx_apmode[1].gfx_backbuffers); if (p->gfx_apmode[APMODE_NATIVE].gfx_interlaced) cfgfile_write_bool (f, _T("gfx_interlace"), p->gfx_apmode[APMODE_NATIVE].gfx_interlaced); - cfgfile_write_str (f, _T("gfx_vsync"), vsyncmodes[p->gfx_apmode[0].gfx_vsync + 1]); + cfgfile_write_str (f, _T("gfx_vsync"), vsyncmodes[p->gfx_apmode[0].gfx_vsync]); cfgfile_write_str (f, _T("gfx_vsyncmode"), vsyncmodes2[p->gfx_apmode[0].gfx_vsyncmode]); - cfgfile_write_str (f, _T("gfx_vsync_picasso"), vsyncmodes[p->gfx_apmode[1].gfx_vsync + 1]); + cfgfile_write_str (f, _T("gfx_vsync_picasso"), vsyncmodes[p->gfx_apmode[1].gfx_vsync]); cfgfile_write_str (f, _T("gfx_vsyncmode_picasso"), vsyncmodes2[p->gfx_apmode[1].gfx_vsyncmode]); cfgfile_write_bool (f, _T("gfx_lores"), p->gfx_resolution == 0); cfgfile_write_str (f, _T("gfx_resolution"), lorestype1[p->gfx_resolution]); @@ -1943,7 +1940,9 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) cfgfile_dwrite(f, _T("gfx_black_frame_insertion_ratio"), _T("%d"), p->lightboost_strobo_ratio); cfgfile_write_str(f, _T("gfx_api"), filterapi[p->gfx_api]); cfgfile_write_str(f, _T("gfx_api_options"), filterapiopts[p->gfx_api_options]); - cfgfile_dwrite (f, _T("gfx_horizontal_tweak"), _T("%d"), p->gfx_extrawidth); + cfgfile_dwrite(f, _T("gfx_horizontal_tweak"), _T("%d"), p->gfx_extrawidth); + cfgfile_dwrite(f, _T("gfx_frame_slices"), _T("%d"), p->gfx_display_sections); + cfgfile_dwrite_bool(f, _T("gfx_vrr_monitor"), p->gfx_variable_sync != 0); #ifdef GFXFILTER for (int j = 0; j < 2; j++) { @@ -2054,7 +2053,8 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) cfgfile_dwrite_str(f, _T("genlock_video"), p->genlock_video_file); cfgfile_dwrite(f, _T("genlock_mix"), _T("%d"), p->genlock_mix); cfgfile_dwrite(f, _T("genlock_scale"), _T("%d"), p->genlock_scale); - cfgfile_dwrite_str(f, _T("monitoremu"), specialmonitors[p->monitoremu]); + cfgfile_dwrite_str(f, _T("monitoremu"), specialmonitorconfignames[p->monitoremu]); + cfgfile_dwrite(f, _T("monitoremu_monitor"), _T("%d"), p->monitoremu_mon); cfgfile_dwrite_coords(f, _T("lightpen_offset"), p->lightpen_offset[0], p->lightpen_offset[1]); cfgfile_dwrite_bool(f, _T("lightpen_crosshair"), p->lightpen_crosshair); @@ -2283,8 +2283,16 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type) else _tcscpy(tmp, _T("gfxcard_type")); cfgfile_dwrite_str(f, tmp, gfxboard_get_configname(rbc->rtgmem_type)); + tmp2[0] = 0; if (rbc->device_order > 0 && p->autoconfig_custom_sort) { _stprintf(tmp2, _T("order=%d"), rbc->device_order); + } + if (rbc->monitor_id) { + if (tmp2) + _tcscat(tmp2, _T(",")); + _stprintf(tmp2 + _tcslen(tmp2), _T("monitor=%d"), rbc->monitor_id); + } + if (tmp2[0]) { if (i > 0) _stprintf(tmp, _T("gfxcard%d_options"), i + 1); else @@ -3016,9 +3024,10 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) || cfgfile_intval (option, value, _T("sampler_buffer"), &p->sampler_buffer, 1) || cfgfile_intval (option, value, _T("warp_limit"), &p->turbo_emulation_limit, 1) - || cfgfile_intval (option, value, _T("gfx_framerate"), &p->gfx_framerate, 1) - || cfgfile_intval (option, value, _T("gfx_top_windowed"), &p->gfx_size_win.x, 1) - || cfgfile_intval (option, value, _T("gfx_left_windowed"), &p->gfx_size_win.y, 1) + || cfgfile_intval(option, value, _T("gfx_frame_slices"), &p->gfx_display_sections, 1) + || cfgfile_intval(option, value, _T("gfx_framerate"), &p->gfx_framerate, 1) + || cfgfile_intval (option, value, _T("gfx_top_windowed"), &p->gfx_monitor[0].gfx_size_win.x, 1) + || cfgfile_intval (option, value, _T("gfx_left_windowed"), &p->gfx_monitor[0].gfx_size_win.y, 1) || cfgfile_intval (option, value, _T("gfx_refreshrate"), &p->gfx_apmode[APMODE_NATIVE].gfx_refreshrate, 1) || cfgfile_intval (option, value, _T("gfx_refreshrate_rtg"), &p->gfx_apmode[APMODE_RTG].gfx_refreshrate, 1) || cfgfile_intval (option, value, _T("gfx_autoresolution_delay"), &p->gfx_autoresolution_delay, 1) @@ -3026,8 +3035,7 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) || cfgfile_intval (option, value, _T("gfx_backbuffers_rtg"), &p->gfx_apmode[APMODE_RTG].gfx_backbuffers, 1) || cfgfile_yesno (option, value, _T("gfx_interlace"), &p->gfx_apmode[APMODE_NATIVE].gfx_interlaced) || cfgfile_yesno(option, value, _T("gfx_interlace_rtg"), &p->gfx_apmode[APMODE_RTG].gfx_interlaced) - || cfgfile_yesno(option, value, _T("gfx_tearing"), &p->gfx_apmode[APMODE_NATIVE].gfx_tearing) - || cfgfile_yesno(option, value, _T("gfx_tearing_rtg"), &p->gfx_apmode[APMODE_RTG].gfx_tearing) + || cfgfile_yesno(option, value, _T("gfx_vrr_monitor"), &p->gfx_variable_sync) || cfgfile_intval(option, value, _T("gfx_black_frame_insertion_ratio"), &p->lightboost_strobo_ratio, 1) || cfgfile_intval (option, value, _T("gfx_center_horizontal_position"), &p->gfx_xcenter_pos, 1) @@ -3193,41 +3201,41 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) if (_tcscmp (option, _T("gfx_width_windowed")) == 0) { if (!_tcscmp (value, _T("native"))) { - p->gfx_size_win.width = 0; - p->gfx_size_win.height = 0; + p->gfx_monitor[0].gfx_size_win.width = 0; + p->gfx_monitor[0].gfx_size_win.height = 0; } else { - cfgfile_intval (option, value, _T("gfx_width_windowed"), &p->gfx_size_win.width, 1); + cfgfile_intval (option, value, _T("gfx_width_windowed"), &p->gfx_monitor[0].gfx_size_win.width, 1); } return 1; } if (_tcscmp (option, _T("gfx_height_windowed")) == 0) { if (!_tcscmp (value, _T("native"))) { - p->gfx_size_win.width = 0; - p->gfx_size_win.height = 0; + p->gfx_monitor[0].gfx_size_win.width = 0; + p->gfx_monitor[0].gfx_size_win.height = 0; } else { - cfgfile_intval (option, value, _T("gfx_height_windowed"), &p->gfx_size_win.height, 1); + cfgfile_intval (option, value, _T("gfx_height_windowed"), &p->gfx_monitor[0].gfx_size_win.height, 1); } return 1; } if (_tcscmp (option, _T("gfx_width_fullscreen")) == 0) { if (!_tcscmp (value, _T("native"))) { - p->gfx_size_fs.width = 0; - p->gfx_size_fs.height = 0; - p->gfx_size_fs.special = WH_NATIVE; + p->gfx_monitor[0].gfx_size_fs.width = 0; + p->gfx_monitor[0].gfx_size_fs.height = 0; + p->gfx_monitor[0].gfx_size_fs.special = WH_NATIVE; } else { - cfgfile_intval (option, value, _T("gfx_width_fullscreen"), &p->gfx_size_fs.width, 1); - p->gfx_size_fs.special = 0; + cfgfile_intval (option, value, _T("gfx_width_fullscreen"), &p->gfx_monitor[0].gfx_size_fs.width, 1); + p->gfx_monitor[0].gfx_size_fs.special = 0; } return 1; } if (_tcscmp (option, _T("gfx_height_fullscreen")) == 0) { if (!_tcscmp (value, _T("native"))) { - p->gfx_size_fs.width = 0; - p->gfx_size_fs.height = 0; - p->gfx_size_fs.special = WH_NATIVE; + p->gfx_monitor[0].gfx_size_fs.width = 0; + p->gfx_monitor[0].gfx_size_fs.height = 0; + p->gfx_monitor[0].gfx_size_fs.special = WH_NATIVE; } else { - cfgfile_intval (option, value, _T("gfx_height_fullscreen"), &p->gfx_size_fs.height, 1); - p->gfx_size_fs.special = 0; + cfgfile_intval (option, value, _T("gfx_height_fullscreen"), &p->gfx_monitor[0].gfx_size_fs.height, 1); + p->gfx_monitor[0].gfx_size_fs.special = 0; } return 1; } @@ -3285,14 +3293,12 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) } if (_tcscmp (option, _T("gfx_vsync")) == 0) { if (cfgfile_strval (option, value, _T("gfx_vsync"), &p->gfx_apmode[APMODE_NATIVE].gfx_vsync, vsyncmodes, 0) >= 0) { - p->gfx_apmode[APMODE_NATIVE].gfx_vsync--; return 1; } return cfgfile_yesno (option, value, _T("gfx_vsync"), &p->gfx_apmode[APMODE_NATIVE].gfx_vsync); } if (_tcscmp (option, _T("gfx_vsync_picasso")) == 0) { if (cfgfile_strval (option, value, _T("gfx_vsync_picasso"), &p->gfx_apmode[APMODE_RTG].gfx_vsync, vsyncmodes, 0) >= 0) { - p->gfx_apmode[APMODE_RTG].gfx_vsync--; return 1; } return cfgfile_yesno (option, value, _T("gfx_vsync_picasso"), &p->gfx_apmode[APMODE_RTG].gfx_vsync); @@ -3508,18 +3514,18 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) #endif if (_tcscmp (option, _T("gfx_width")) == 0 || _tcscmp (option, _T("gfx_height")) == 0) { - cfgfile_intval (option, value, _T("gfx_width"), &p->gfx_size_win.width, 1); - cfgfile_intval (option, value, _T("gfx_height"), &p->gfx_size_win.height, 1); - p->gfx_size_fs.width = p->gfx_size_win.width; - p->gfx_size_fs.height = p->gfx_size_win.height; + cfgfile_intval (option, value, _T("gfx_width"), &p->gfx_monitor[0].gfx_size_win.width, 1); + cfgfile_intval (option, value, _T("gfx_height"), &p->gfx_monitor[0].gfx_size_win.height, 1); + p->gfx_monitor[0].gfx_size_fs.width = p->gfx_monitor[0].gfx_size_win.width; + p->gfx_monitor[0].gfx_size_fs.height = p->gfx_monitor[0].gfx_size_win.height; return 1; } if (_tcscmp (option, _T("gfx_fullscreen_multi")) == 0 || _tcscmp (option, _T("gfx_windowed_multi")) == 0) { TCHAR tmp[256], *tmpp, *tmpp2; - struct wh *wh = p->gfx_size_win_xtra; + struct wh *wh = p->gfx_monitor[0].gfx_size_win_xtra; if (_tcscmp (option, _T("gfx_fullscreen_multi")) == 0) - wh = p->gfx_size_fs_xtra; + wh = p->gfx_monitor[0].gfx_size_fs_xtra; _stprintf (tmp, _T(",%s,"), value); tmpp2 = tmp; for (i = 0; i < 4; i++) { @@ -5148,40 +5154,43 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH || cfgfile_yesno (option, value, _T("uaeserial"), &p->uaeserial)) return 1; - if (cfgfile_intval (option, value, _T("cachesize"), &p->cachesize, 1) - || cfgfile_intval (option, value, _T("cd32nvram_size"), &p->cs_cd32nvram_size, 1024) - || cfgfile_intval (option, value, _T("chipset_hacks"), &p->cs_hacks, 1) - || cfgfile_intval (option, value, _T("serial_stopbits"), &p->serial_stopbits, 1) - || cfgfile_intval (option, value, _T("cpu060_revision"), &p->cpu060_revision, 1) - || cfgfile_intval (option, value, _T("fpu_revision"), &p->fpu_revision, 1) - || cfgfile_intval (option, value, _T("cdtvramcard"), &p->cs_cdtvcard, 1) - || cfgfile_intval (option, value, _T("fatgary"), &p->cs_fatgaryrev, 1) - || cfgfile_intval (option, value, _T("ramsey"), &p->cs_ramseyrev, 1) - || cfgfile_doubleval (option, value, _T("chipset_refreshrate"), &p->chipset_refreshrate) + if (cfgfile_intval(option, value, _T("cachesize"), &p->cachesize, 1) + || cfgfile_intval(option, value, _T("cd32nvram_size"), &p->cs_cd32nvram_size, 1024) + || cfgfile_intval(option, value, _T("chipset_hacks"), &p->cs_hacks, 1) + || cfgfile_intval(option, value, _T("serial_stopbits"), &p->serial_stopbits, 1) + || cfgfile_intval(option, value, _T("cpu060_revision"), &p->cpu060_revision, 1) + || cfgfile_intval(option, value, _T("fpu_revision"), &p->fpu_revision, 1) + || cfgfile_intval(option, value, _T("cdtvramcard"), &p->cs_cdtvcard, 1) + || cfgfile_intval(option, value, _T("fatgary"), &p->cs_fatgaryrev, 1) + || cfgfile_intval(option, value, _T("ramsey"), &p->cs_ramseyrev, 1) + || cfgfile_doubleval(option, value, _T("chipset_refreshrate"), &p->chipset_refreshrate) || cfgfile_intval(option, value, _T("cpuboardmem1_size"), &p->cpuboardmem1_size, 0x100000) || cfgfile_intval(option, value, _T("cpuboardmem2_size"), &p->cpuboardmem2_size, 0x100000) - || cfgfile_intval (option, value, _T("mem25bit_size"), &p->mem25bit_size, 0x100000) - || cfgfile_intval (option, value, _T("a3000mem_size"), &p->mbresmem_low_size, 0x100000) - || cfgfile_intval (option, value, _T("mbresmem_size"), &p->mbresmem_high_size, 0x100000) - || cfgfile_intval (option, value, _T("megachipmem_size"), &p->z3chipmem_size, 0x100000) - || cfgfile_intval (option, value, _T("z3mem_start"), &p->z3autoconfig_start, 1) - || cfgfile_intval (option, value, _T("bogomem_size"), &p->bogomem_size, 0x40000) + || cfgfile_intval(option, value, _T("debugmem_size"), &p->debugmem_size, 0x100000) + || cfgfile_intval(option, value, _T("mem25bit_size"), &p->mem25bit_size, 0x100000) + || cfgfile_intval(option, value, _T("a3000mem_size"), &p->mbresmem_low_size, 0x100000) + || cfgfile_intval(option, value, _T("mbresmem_size"), &p->mbresmem_high_size, 0x100000) + || cfgfile_intval(option, value, _T("megachipmem_size"), &p->z3chipmem_size, 0x100000) + || cfgfile_intval(option, value, _T("z3mem_start"), &p->z3autoconfig_start, 1) + || cfgfile_intval(option, value, _T("debugmem_start"), &p->debugmem_start, 1) + || cfgfile_intval(option, value, _T("bogomem_size"), &p->bogomem_size, 0x40000) || cfgfile_intval(option, value, _T("rtg_modes"), &p->picasso96_modeflags, 1) - || cfgfile_intval (option, value, _T("floppy_speed"), &p->floppy_speed, 1) - || cfgfile_intval (option, value, _T("cd_speed"), &p->cd_speed, 1) - || cfgfile_intval (option, value, _T("floppy_write_length"), &p->floppy_write_length, 1) - || cfgfile_intval (option, value, _T("floppy_random_bits_min"), &p->floppy_random_bits_min, 1) - || cfgfile_intval (option, value, _T("floppy_random_bits_max"), &p->floppy_random_bits_max, 1) - || cfgfile_intval (option, value, _T("nr_floppies"), &p->nr_floppies, 1) - || cfgfile_intval (option, value, _T("floppy0type"), &p->floppyslots[0].dfxtype, 1) - || cfgfile_intval (option, value, _T("floppy1type"), &p->floppyslots[1].dfxtype, 1) - || cfgfile_intval (option, value, _T("floppy2type"), &p->floppyslots[2].dfxtype, 1) - || cfgfile_intval (option, value, _T("floppy3type"), &p->floppyslots[3].dfxtype, 1) - || cfgfile_intval (option, value, _T("maprom"), &p->maprom, 1) - || cfgfile_intval (option, value, _T("parallel_autoflush"), &p->parallel_autoflush_time, 1) - || cfgfile_intval (option, value, _T("uae_hide"), &p->uae_hide, 1) - || cfgfile_intval (option, value, _T("cpu_frequency"), &p->cpu_frequency, 1) + || cfgfile_intval(option, value, _T("floppy_speed"), &p->floppy_speed, 1) + || cfgfile_intval(option, value, _T("cd_speed"), &p->cd_speed, 1) + || cfgfile_intval(option, value, _T("floppy_write_length"), &p->floppy_write_length, 1) + || cfgfile_intval(option, value, _T("floppy_random_bits_min"), &p->floppy_random_bits_min, 1) + || cfgfile_intval(option, value, _T("floppy_random_bits_max"), &p->floppy_random_bits_max, 1) + || cfgfile_intval(option, value, _T("nr_floppies"), &p->nr_floppies, 1) + || cfgfile_intval(option, value, _T("floppy0type"), &p->floppyslots[0].dfxtype, 1) + || cfgfile_intval(option, value, _T("floppy1type"), &p->floppyslots[1].dfxtype, 1) + || cfgfile_intval(option, value, _T("floppy2type"), &p->floppyslots[2].dfxtype, 1) + || cfgfile_intval(option, value, _T("floppy3type"), &p->floppyslots[3].dfxtype, 1) + || cfgfile_intval(option, value, _T("maprom"), &p->maprom, 1) + || cfgfile_intval(option, value, _T("parallel_autoflush"), &p->parallel_autoflush_time, 1) + || cfgfile_intval(option, value, _T("uae_hide"), &p->uae_hide, 1) + || cfgfile_intval(option, value, _T("cpu_frequency"), &p->cpu_frequency, 1) || cfgfile_intval(option, value, _T("kickstart_ext_rom_file2addr"), &p->romextfile2addr, 1) + || cfgfile_intval(option, value, _T("monitoremu_monitor"), &p->monitoremu_mon, 1) || cfgfile_intval(option, value, _T("genlock_scale"), &p->genlock_scale, 1) || cfgfile_intval(option, value, _T("genlock_mix"), &p->genlock_mix, 1)) return 1; @@ -5195,7 +5204,7 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH || cfgfile_strval (option, value, _T("comp_trustnaddr"), &p->comptrustnaddr, compmode, 0) || cfgfile_strval (option, value, _T("collision_level"), &p->collision_level, collmode, 0) || cfgfile_strval (option, value, _T("parallel_matrix_emulation"), &p->parallel_matrix_emulation, epsonprinter, 0) - || cfgfile_strval(option, value, _T("monitoremu"), &p->monitoremu, specialmonitors, 0) + || cfgfile_strval(option, value, _T("monitoremu"), &p->monitoremu, specialmonitorconfignames, 0) || cfgfile_strval(option, value, _T("genlockmode"), &p->genlock_image, genlockmodes, 0) || cfgfile_strval (option, value, _T("waiting_blits"), &p->waiting_blits, waitblits, 0) || cfgfile_strval (option, value, _T("floppy_auto_extended_adf"), &p->floppy_auto_ext2, autoext2, 0) @@ -5330,6 +5339,10 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCH if (s) { rbc->device_order = _tstol(s); } + s = cfgfile_option_get(value, _T("monitor")); + if (s) { + rbc->monitor_id = _tstol(s); + } return 1; } if (i > 0) @@ -6272,6 +6285,9 @@ int cfgfile_load (struct uae_prefs *p, const TCHAR *filename, int *type, int ign } end: recursive--; + for (int i = 1; i < MAX_AMIGADISPLAYS; i++) { + memcpy(&p->gfx_monitor[i], &p->gfx_monitor[0], sizeof(struct monconfig)); + } fixup_prefs (p, userconfig != 0); return v; } @@ -6414,8 +6430,8 @@ static void parse_gfx_specs (struct uae_prefs *p, const TCHAR *spec) goto argh; *x1++ = 0; *x2++ = 0; - p->gfx_size_win.width = p->gfx_size_fs.width = _tstoi (x0); - p->gfx_size_win.height = p->gfx_size_fs.height = _tstoi (x1); + p->gfx_monitor[0].gfx_size_win.width = p->gfx_monitor[0].gfx_size_fs.width = _tstoi (x0); + p->gfx_monitor[0].gfx_size_win.height = p->gfx_monitor[0].gfx_size_fs.height = _tstoi (x1); p->gfx_resolution = _tcschr (x2, 'l') != 0 ? 1 : 0; p->gfx_xcenter = _tcschr (x2, 'x') != 0 ? 1 : _tcschr (x2, 'X') != 0 ? 2 : 0; p->gfx_ycenter = _tcschr (x2, 'y') != 0 ? 1 : _tcschr (x2, 'Y') != 0 ? 2 : 0; @@ -7015,6 +7031,7 @@ uae_u32 cfgfile_modify (uae_u32 index, const TCHAR *parms, uae_u32 size, TCHAR * if (size > 10000) return 10; + argv = cmdlineparser (parms, argc, UAELIB_MAX_PARSE); if (argv <= 1 && index == 0xffffffff) { @@ -7359,15 +7376,15 @@ void default_prefs (struct uae_prefs *p, bool reset, int type) p->gfx_framerate = 1; p->gfx_autoframerate = 50; - p->gfx_size_fs.width = 800; - p->gfx_size_fs.height = 600; - p->gfx_size_win.width = 720; - p->gfx_size_win.height = 568; + p->gfx_monitor[0].gfx_size_fs.width = 800; + p->gfx_monitor[0].gfx_size_fs.height = 600; + p->gfx_monitor[0].gfx_size_win.width = 720; + p->gfx_monitor[0].gfx_size_win.height = 568; for (i = 0; i < 4; i++) { - p->gfx_size_fs_xtra[i].width = 0; - p->gfx_size_fs_xtra[i].height = 0; - p->gfx_size_win_xtra[i].width = 0; - p->gfx_size_win_xtra[i].height = 0; + p->gfx_monitor[0].gfx_size_fs_xtra[i].width = 0; + p->gfx_monitor[0].gfx_size_fs_xtra[i].height = 0; + p->gfx_monitor[0].gfx_size_win_xtra[i].width = 0; + p->gfx_monitor[0].gfx_size_win_xtra[i].height = 0; } p->gfx_resolution = RES_HIRES; p->gfx_vresolution = VRES_DOUBLE; @@ -7388,6 +7405,8 @@ void default_prefs (struct uae_prefs *p, bool reset, int type) p->gfx_autoresolution_vga = true; p->gfx_apmode[0].gfx_backbuffers = 2; p->gfx_apmode[1].gfx_backbuffers = 1; + p->gfx_display_sections = 4; + p->gfx_variable_sync = 0; p->immediate_blits = 0; p->waiting_blits = 0; diff --git a/consolehook.cpp b/consolehook.cpp index 69b58bee..870e2b3e 100644 --- a/consolehook.cpp +++ b/consolehook.cpp @@ -45,8 +45,8 @@ void consolehook_config (struct uae_prefs *p) p->floppyslots[1].dfxtype = DRV_NONE; p->floppy_speed = 0; p->start_gui = 0; - p->gfx_size_win.width = 320; - p->gfx_size_win.height = 256; + p->gfx_monitor[0].gfx_size_win.width = 320; + p->gfx_monitor[0].gfx_size_win.height = 256; p->turbo_emulation = 0; //p->win32_automount_drives = 2; //p->win32_automount_cddrives = 2; diff --git a/custom.cpp b/custom.cpp index 7bef8fc0..5a304202 100644 --- a/custom.cpp +++ b/custom.cpp @@ -65,7 +65,8 @@ extern uae_u16 serper; STATIC_INLINE bool nocustom (void) { - if (picasso_on && currprefs.picasso96_nocustom) + struct amigadisplay *ad = &adisplays[0]; + if (ad->picasso_on && currprefs.picasso96_nocustom) return true; return false; } @@ -111,6 +112,9 @@ static unsigned int total_skipped = 0; extern int cpu_last_stop_vpos, cpu_stopped_lines; static int cpu_sleepmode, cpu_sleepmode_cnt; +extern int vsync_activeheight, vsync_totalheight; +extern float vsync_vblank, vsync_hblank; + STATIC_INLINE void sync_copper (int hpos); @@ -139,7 +143,7 @@ static bool lof_lace; static bool bplcon0_interlace_seen; static int scandoubled_line; static bool vsync_rendered, frame_rendered, frame_shown; -static int vsynctimeperline; +static float vsynctimeperline; static int frameskiptime; static bool genlockhtoggle; static bool genlockvtoggle; @@ -195,8 +199,8 @@ int minfirstline = VBLANK_ENDLINE_PAL; int firstblankedline; static int equ_vblank_endline = EQU_ENDLINE_PAL; static bool equ_vblank_toggle = true; -double vblank_hz = VBLANK_HZ_PAL, fake_vblank_hz, vblank_hz_stored, vblank_hz_nom; -double hblank_hz; +float vblank_hz = VBLANK_HZ_PAL, fake_vblank_hz, vblank_hz_stored, vblank_hz_nom; +float hblank_hz; static float vblank_hz_lof, vblank_hz_shf, vblank_hz_lace; static int vblank_hz_mult, vblank_hz_state; static struct chipset_refresh *stored_chipset_refresh; @@ -454,9 +458,10 @@ STATIC_INLINE int ecsshres(void) return bplcon0_res == RES_SUPERHIRES && (currprefs.chipset_mask & CSMASK_ECS_DENISE) && !(currprefs.chipset_mask & CSMASK_AGA); } -STATIC_INLINE int nodraw (void) +STATIC_INLINE int nodraw(void) { - return !currprefs.cpu_memory_cycle_exact && framecnt != 0; + struct amigadisplay *ad = &adisplays[0]; + return !currprefs.cpu_memory_cycle_exact && ad->framecnt != 0; } static int doflickerfix (void) @@ -3788,8 +3793,9 @@ static int color_changes_differ (struct draw_info *dip, struct draw_info *dip_ol /* End of a horizontal scan line. Finish off all decisions that were not * made yet. */ -static void finish_decisions (void) +static void finish_decisions(void) { + struct amigadisplay *ad = &adisplays[0]; struct draw_info *dip; struct draw_info *dip_old; struct decision *dp; @@ -3838,7 +3844,7 @@ static void finish_decisions (void) dip = curr_drawinfo + next_lineno; dip_old = prev_drawinfo + next_lineno; dp = line_decisions + next_lineno; - changed = thisline_changed | custom_frame_redraw_necessary; + changed = thisline_changed | ad->custom_frame_redraw_necessary; if (thisline_decision.plfleft >= 0 && thisline_decision.nr_planes > 0) record_diw_line (thisline_decision.plfleft, diwfirstword, diwlastword); @@ -4042,8 +4048,8 @@ void compute_vsynctime (void) vblank_hz = currprefs.chipset_refreshrate; if (isvsync_chipset ()) { int mult = 0; - if (getvsyncrate (vblank_hz, &mult) != vblank_hz) { - vblank_hz = getvsyncrate (vblank_hz, &vblank_hz_mult); + if (getvsyncrate(0, vblank_hz, &mult) != vblank_hz) { + vblank_hz = getvsyncrate(0, vblank_hz, &vblank_hz_mult); if (vblank_hz_mult > 0) vblank_hz_state = 0; } @@ -4079,7 +4085,7 @@ void compute_vsynctime (void) } if (currprefs.produce_sound > 1) { double clk = svpos * shpos * fake_vblank_hz; - //write_log (_T("SNDRATE %.1f*%.1f*%.6f=%.6f\n"), svpos, shpos, fake_vblank_hz, clk); + write_log (_T("SNDRATE %.1f*%.1f*%.6f=%.6f\n"), svpos, shpos, fake_vblank_hz, clk); devices_update_sound(clk, syncadjust); } devices_update_sync(svpos, syncadjust); @@ -4145,6 +4151,7 @@ static void checklacecount (bool lace) struct chipset_refresh *get_chipset_refresh (void) { + struct amigadisplay *ad = &adisplays[0]; int islace = interlace_seen ? 1 : 0; int isntsc = (beamcon0 & 0x20) ? 0 : 1; int custom = (beamcon0 & 0x80) ? 1 : 0; @@ -4164,7 +4171,7 @@ struct chipset_refresh *get_chipset_refresh (void) (cr->lace < 0 || (cr->lace > 0 && islace) || (cr->lace == 0 && !islace)) && (cr->resolution == 0 || cr->resolution == 7 || (cr->resolution & (1 << detected_screen_resolution))) && (cr->framelength < 0 || (cr->framelength > 0 && lof_store) || (cr->framelength == 0 && !lof_store) || (cr->framelength >= 0 && islace)) && - ((cr->rtg && picasso_on) || (!cr->rtg && !picasso_on)) && + ((cr->rtg && ad->picasso_on) || (!cr->rtg && !ad->picasso_on)) && (cr->vsync < 0 || (cr->vsync > 0 && isvsync_chipset ()) || (cr->vsync == 0 && !isvsync_chipset ()))) return cr; } @@ -4179,8 +4186,10 @@ static bool changed_chipset_refresh (void) return stored_chipset_refresh != get_chipset_refresh (); } -void compute_framesync (void) +void compute_framesync(void) { + struct vidbuf_description *vidinfo = &adisplays[0].gfxvidinfo; + struct amigadisplay *ad = &adisplays[0]; int islace = interlace_seen ? 1 : 0; int isntsc = (beamcon0 & 0x20) ? 0 : 1; bool found = false; @@ -4193,21 +4202,22 @@ void compute_framesync (void) vblank_hz = vblank_hz_shf; } - vblank_hz = target_adjust_vblank_hz(vblank_hz); + vblank_hz = target_adjust_vblank_hz(0, vblank_hz); struct chipset_refresh *cr = get_chipset_refresh (); while (cr) { double v = -1; - if (!picasso_on && !picasso_requested_on) { + if (!ad->picasso_on && !ad->picasso_requested_on) { if (isvsync_chipset ()) { if (cr->index == CHIPSET_REFRESH_PAL || cr->index == CHIPSET_REFRESH_NTSC) { if ((fabs (vblank_hz - 50) < 1 || fabs (vblank_hz - 60) < 1 || fabs (vblank_hz - 100) < 1 || fabs (vblank_hz - 120) < 1) && currprefs.gfx_apmode[0].gfx_vsync == 2 && currprefs.gfx_apmode[0].gfx_fullscreen > 0) { - vsync_switchmode ((int)vblank_hz); + vsync_switchmode(0, (int)vblank_hz); } } if (isvsync_chipset () < 0) { + double v2; - v2 = vblank_calibrate (cr->locked ? cr->rate : vblank_hz, cr->locked); + v2 = target_getcurrentvblankrate(0); if (!cr->locked) v = v2; } else if (isvsync_chipset () > 0) { @@ -4255,8 +4265,8 @@ void compute_framesync (void) lof_togglecnt_nlace = 0; //nlace_cnt = NLACE_CNT_NEEDED; lof_changing = 0; - gfxvidinfo.drawbuffer.inxoffset = -1; - gfxvidinfo.drawbuffer.inyoffset = -1; + vidinfo->drawbuffer.inxoffset = -1; + vidinfo->drawbuffer.inyoffset = -1; if (beamcon0 & 0x80) { int res = GET_RES_AGNUS (bplcon0); @@ -4281,52 +4291,52 @@ void compute_framesync (void) int start = hsyncstartpos; //hbstrt; int stop = hsyncendpos; //hbstop; - gfxvidinfo.drawbuffer.inwidth = ((maxhpos - (maxhpos - start + DISPLAY_LEFT_SHIFT / 2) + 1) * 2) << res2; - gfxvidinfo.drawbuffer.inxoffset = stop * 2; + vidinfo->drawbuffer.inwidth = ((maxhpos - (maxhpos - start + DISPLAY_LEFT_SHIFT / 2) + 1) * 2) << res2; + vidinfo->drawbuffer.inxoffset = stop * 2; - gfxvidinfo.drawbuffer.extrawidth = 0; - gfxvidinfo.drawbuffer.inwidth2 = gfxvidinfo.drawbuffer.inwidth; + vidinfo->drawbuffer.extrawidth = 0; + vidinfo->drawbuffer.inwidth2 = vidinfo->drawbuffer.inwidth; - gfxvidinfo.drawbuffer.inheight = ((firstblankedline < maxvpos ? firstblankedline : maxvpos) - minfirstline + 1) << vres2; - gfxvidinfo.drawbuffer.inheight2 = gfxvidinfo.drawbuffer.inheight; + vidinfo->drawbuffer.inheight = ((firstblankedline < maxvpos ? firstblankedline : maxvpos) - minfirstline + 1) << vres2; + vidinfo->drawbuffer.inheight2 = vidinfo->drawbuffer.inheight; } else { - gfxvidinfo.drawbuffer.inwidth = AMIGA_WIDTH_MAX << currprefs.gfx_resolution; - gfxvidinfo.drawbuffer.extrawidth = currprefs.gfx_extrawidth ? currprefs.gfx_extrawidth : -1; - gfxvidinfo.drawbuffer.inwidth2 = gfxvidinfo.drawbuffer.inwidth; - gfxvidinfo.drawbuffer.inheight = (maxvpos_display - minfirstline + 1) << currprefs.gfx_vresolution; - gfxvidinfo.drawbuffer.inheight2 = gfxvidinfo.drawbuffer.inheight; + vidinfo->drawbuffer.inwidth = AMIGA_WIDTH_MAX << currprefs.gfx_resolution; + vidinfo->drawbuffer.extrawidth = currprefs.gfx_extrawidth ? currprefs.gfx_extrawidth : -1; + vidinfo->drawbuffer.inwidth2 = vidinfo->drawbuffer.inwidth; + vidinfo->drawbuffer.inheight = (maxvpos_display - minfirstline + 1) << currprefs.gfx_vresolution; + vidinfo->drawbuffer.inheight2 = vidinfo->drawbuffer.inheight; } - if (gfxvidinfo.drawbuffer.inwidth < 16) - gfxvidinfo.drawbuffer.inwidth = 16; - if (gfxvidinfo.drawbuffer.inwidth2 < 16) - gfxvidinfo.drawbuffer.inwidth2 = 16; - if (gfxvidinfo.drawbuffer.inheight < 1) - gfxvidinfo.drawbuffer.inheight = 1; - if (gfxvidinfo.drawbuffer.inheight2 < 1) - gfxvidinfo.drawbuffer.inheight2 = 1; + if (vidinfo->drawbuffer.inwidth < 16) + vidinfo->drawbuffer.inwidth = 16; + if (vidinfo->drawbuffer.inwidth2 < 16) + vidinfo->drawbuffer.inwidth2 = 16; + if (vidinfo->drawbuffer.inheight < 1) + vidinfo->drawbuffer.inheight = 1; + if (vidinfo->drawbuffer.inheight2 < 1) + vidinfo->drawbuffer.inheight2 = 1; - if (gfxvidinfo.drawbuffer.inwidth > gfxvidinfo.drawbuffer.width_allocated) - gfxvidinfo.drawbuffer.inwidth = gfxvidinfo.drawbuffer.width_allocated; - if (gfxvidinfo.drawbuffer.inwidth2 > gfxvidinfo.drawbuffer.width_allocated) - gfxvidinfo.drawbuffer.inwidth2 = gfxvidinfo.drawbuffer.width_allocated; + if (vidinfo->drawbuffer.inwidth > vidinfo->drawbuffer.width_allocated) + vidinfo->drawbuffer.inwidth = vidinfo->drawbuffer.width_allocated; + if (vidinfo->drawbuffer.inwidth2 > vidinfo->drawbuffer.width_allocated) + vidinfo->drawbuffer.inwidth2 = vidinfo->drawbuffer.width_allocated; - if (gfxvidinfo.drawbuffer.inheight > gfxvidinfo.drawbuffer.height_allocated) - gfxvidinfo.drawbuffer.inheight = gfxvidinfo.drawbuffer.height_allocated; - if (gfxvidinfo.drawbuffer.inheight2 > gfxvidinfo.drawbuffer.height_allocated) - gfxvidinfo.drawbuffer.inheight2 = gfxvidinfo.drawbuffer.height_allocated; + if (vidinfo->drawbuffer.inheight > vidinfo->drawbuffer.height_allocated) + vidinfo->drawbuffer.inheight = vidinfo->drawbuffer.height_allocated; + if (vidinfo->drawbuffer.inheight2 > vidinfo->drawbuffer.height_allocated) + vidinfo->drawbuffer.inheight2 = vidinfo->drawbuffer.height_allocated; - gfxvidinfo.drawbuffer.outwidth = gfxvidinfo.drawbuffer.inwidth; - gfxvidinfo.drawbuffer.outheight = gfxvidinfo.drawbuffer.inheight; + vidinfo->drawbuffer.outwidth = vidinfo->drawbuffer.inwidth; + vidinfo->drawbuffer.outheight = vidinfo->drawbuffer.inheight; - if (gfxvidinfo.drawbuffer.outwidth > gfxvidinfo.drawbuffer.width_allocated) - gfxvidinfo.drawbuffer.outwidth = gfxvidinfo.drawbuffer.width_allocated; + if (vidinfo->drawbuffer.outwidth > vidinfo->drawbuffer.width_allocated) + vidinfo->drawbuffer.outwidth = vidinfo->drawbuffer.width_allocated; - if (gfxvidinfo.drawbuffer.outheight > gfxvidinfo.drawbuffer.height_allocated) - gfxvidinfo.drawbuffer.outheight = gfxvidinfo.drawbuffer.height_allocated; + if (vidinfo->drawbuffer.outheight > vidinfo->drawbuffer.height_allocated) + vidinfo->drawbuffer.outheight = vidinfo->drawbuffer.height_allocated; memset (line_decisions, 0, sizeof line_decisions); memset (line_drawinfo, 0, sizeof line_drawinfo); @@ -4347,12 +4357,12 @@ void compute_framesync (void) maxhpos, maxvpos, lof_store ? 1 : 0, cr ? cr->index : -1, cr != NULL && cr->label != NULL ? cr->label : _T(""), - currprefs.gfx_apmode[picasso_on ? 1 : 0].gfx_display, picasso_on, picasso_requested_on + currprefs.gfx_apmode[ad->picasso_on ? 1 : 0].gfx_display, ad->picasso_on, ad->picasso_requested_on ); set_config_changed (); - if (target_graphics_buffer_update ()) { + if (target_graphics_buffer_update(0)) { reset_drawing (); } } @@ -4565,10 +4575,10 @@ static void init_hz (bool checkvposw) devices_syncchange(); #ifdef PICASSO96 - init_hz_p96 (); + init_hz_p96(0); #endif if (vblank_hz != ovblank) - updatedisplayarea (); + updatedisplayarea(0); inputdevice_tablet_strobe (); if (varsync_changed) { @@ -5399,10 +5409,11 @@ static void BEAMCON0 (uae_u16 v) static void varsync (void) { + struct amigadisplay *ad = &adisplays[0]; if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) return; #ifdef PICASSO96 - if (picasso_on && p96refresh_active) { + if (ad->picasso_on && p96refresh_active) { vtotal = p96refresh_active; return; } @@ -5415,7 +5426,8 @@ static void varsync (void) #ifdef PICASSO96 void set_picasso_hack_rate (int hz) { - if (!picasso_on) + struct amigadisplay *ad = &adisplays[0]; + if (!ad->picasso_on) return; vpos_count = 0; p96refresh_active = (int)(maxvpos_stored * vblank_hz_stored / hz); @@ -5966,7 +5978,7 @@ static void BLTSIZE (int hpos, uae_u16 v) blt_info.vblitsize = 1024; if (!blt_info.hblitsize) blt_info.hblitsize = 64; - do_blitter (hpos, copper_access); + do_blitter(hpos, copper_access, copper_access ? cop_state.ip : M68K_GETPC); dcheck_is_blit_dangerous (); } @@ -5988,7 +6000,7 @@ static void BLTSIZH (int hpos, uae_u16 v) blt_info.vblitsize = 0x8000; if (!blt_info.hblitsize) blt_info.hblitsize = 0x0800; - do_blitter (hpos, copper_access); + do_blitter(hpos, copper_access, copper_access ? cop_state.ip : M68K_GETPC); } STATIC_INLINE void spr_arm (int num, int state) @@ -7351,10 +7363,12 @@ static void rtg_vsync (void) static void rtg_vsynccheck (void) { +#if 0 if (vblank_found_rtg) { vblank_found_rtg = false; rtg_vsync (); } +#endif } @@ -7401,6 +7415,7 @@ static int mavg (struct mavg_data *md, int newval, int size) extern int log_vsync, debug_vsync_min_delay, debug_vsync_forced_delay; static bool framewait (void) { + struct amigadisplay *ad = &adisplays[0]; frame_time_t curr_time; frame_time_t start; int vs = isvsync_chipset (); @@ -7421,8 +7436,8 @@ static bool framewait (void) curr_time = read_processor_time (); vsyncwaittime = vsyncmaxtime = curr_time + vsynctimebase; - if (!frame_rendered && !picasso_on) - frame_rendered = render_screen (false); + if (!frame_rendered && !ad->picasso_on) + frame_rendered = render_screen(0, 1, false); start = read_processor_time (); t = 0; @@ -7430,9 +7445,9 @@ static bool framewait (void) t += (int)start - (int)vsync_time; if (!frame_shown) { - show_screen (1); + show_screen(0, 1); if (currprefs.gfx_apmode[0].gfx_strobo) - show_screen (2); + show_screen(0, 2); } maybe_process_pull_audio(); @@ -7461,7 +7476,7 @@ static bool framewait (void) vsynctimeperline = 1; if (0 || (log_vsync & 2)) { - write_log (_T("%06d %06d/%06d %03d%%\n"), t, vsynctimeperline, vsynctimebase, t * 100 / vsynctimebase); + write_log (_T("%06d %.2f/%06d %03d%%\n"), t, vsynctimeperline, vsynctimebase, t * 100 / vsynctimebase); } frame_shown = true; @@ -7469,162 +7484,14 @@ static bool framewait (void) } else if (vs < 0) { - int freetime; - extern int extraframewait, extraframewait2; - if (!vblank_hz_state) return status != 0; - if (vs == -2 || vs == -3) { - - // fastest possible - int max, adjust, flipdelay, val; - frame_time_t now; - static struct mavg_data ma_skip, ma_adjust; - - val = 0; - - if (!frame_rendered && !picasso_on) { - frame_time_t start, end; - start = read_processor_time (); - frame_rendered = render_screen (currprefs.gfx_apmode[0].gfx_vflip == 0); - end = read_processor_time (); - val += end - start; - } - - curr_time = vsync_busywait_end (&flipdelay); // vsync time - status = vsync_busywait_do (NULL, (bplcon0 & 4) != 0 && !lof_changed && !lof_changing, lof_store != 0); - vsync_busywait_start (); - - now = read_processor_time (); // current time - adjust = (int)now - (int)curr_time; - //write_log (_T("%d "), adjust); - if (adjust < 0 || adjust >= vsynctimebase) - adjust = 0; - if (adjust > vsynctimebase * 2 / 3) - adjust = vsynctimebase * 2 / 3; - - int adjust_avg = mavg (&ma_adjust, adjust, MAVG_VSYNC_SIZE); - - val += adjust_avg; - - int flipdelay_avg = mavg (&ma_skip, flipdelay, MAVG_VSYNC_SIZE); - if (flipdelay > flipdelay_avg) - flipdelay_avg = flipdelay; - if (currprefs.gfx_apmode[0].gfx_vflip == 0) { - val += flipdelay_avg; - //write_log (_T("%d "), skipcnt); - } - val += frameskipt_avg; - - if (currprefs.gfx_apmode[0].gfx_vflip == 0) { - if (debug_vsync_min_delay && val < debug_vsync_min_delay * vsynctimebase / 100) - val = debug_vsync_min_delay * vsynctimebase / 100; - if (debug_vsync_forced_delay > 0) - val = debug_vsync_forced_delay * vsynctimebase / 100; - } - - //write_log (_T("%d "), adjust); - - if (val > vsynctimebase * 2 / 3) - val = vsynctimebase * 2 / 3; - - max = (int)((vsynctimebase - val) * (1000.0 + currprefs.m68k_speed_throttle) / 1000.0); - if (max < 1) - max = 1; - - vsyncmintime = now; - vsyncwaittime = curr_time + (vsynctimebase - 0); - - vsynctimeperline = max / (maxvpos_display + 1); - if (status <= 0 || vsynctimeperline < 1) - vsynctimeperline = 1; - vsyncmaxtime = now + max; - - if (0 || (log_vsync & 2)) { - write_log (_T("%05d:%05d:%05d=%05d:%05d/%05d %03d%%\n"), adjust_avg, frameskipt_avg, flipdelay_avg, - val, vsynctimeperline, vsynctimebase, val * 100 / vsynctimebase); - } - - frame_shown = true; - - } else { - - int max, adjust, flipdelay, flipdelay_avg; - static struct mavg_data ma_skip; - frame_time_t now; - - flipdelay = 0; - curr_time = vsync_busywait_end (&flipdelay); - if (!frame_rendered && !picasso_on) - frame_rendered = render_screen (false); - - status = vsync_busywait_do (&freetime, (bplcon0 & 4) != 0 && !lof_changed && !lof_changing, lof_store != 0); - vsync_busywait_start (); - - now = read_processor_time (); - - maybe_process_pull_audio(); - if (extraframewait && !currprefs.turbo_emulation) { - cpu_sleep_millis(-extraframewait); - maybe_process_pull_audio(); - } else if (extraframewait2 && !currprefs.turbo_emulation) { - uae_time_t add = ((uae_s64)extraframewait2) * syncbase / (1000 * 1000); - frame_time_t efw = read_processor_time() + add; - for (;;) { - frame_time_t nfw = read_processor_time(); - if (audio_is_pull_event()) - break; - if ((int)efw - (int)nfw <= 0) - break; - } - maybe_process_pull_audio(); - } - - adjust = (int)now - (int)curr_time; - int adjustx = adjust; - if (adjust < 0) - adjust = 0; - if (adjust > vsynctimebase) - adjust = 0; - if (adjust > vsynctimebase / 2) - adjust = vsynctimebase / 2; - - vsyncmintime = now; - vsyncwaittime = curr_time + vsynctimebase; - - if (currprefs.gfx_apmode[0].gfx_vflip == 0) { - flipdelay_avg = mavg (&ma_skip, flipdelay, MAVG_VSYNC_SIZE); - if (flipdelay > flipdelay_avg) - flipdelay_avg = flipdelay; - } else { - flipdelay_avg = 0; - } - - max = vsynctimebase - adjust - flipdelay_avg; - - if (currprefs.gfx_apmode[0].gfx_vflip == 0) { - int val = vsynctimebase - max; - if (debug_vsync_min_delay && val < debug_vsync_min_delay * vsynctimebase / 100) - val = debug_vsync_min_delay * vsynctimebase / 100; - if (debug_vsync_forced_delay > 0) - val = debug_vsync_forced_delay * vsynctimebase / 100; - max = vsynctimebase - val; - } - - vsynctimeperline = max / 3; - if (status <= 0 || vsynctimeperline < 1) - vsynctimeperline = 1; - vsyncmaxtime = now + max; - - if (0 || (log_vsync & 2)) { - write_log (_T("%06d:%06d:%06d:%06d %06d/%06d %03d%%\n"), frameskipt_avg, flipdelay_avg, adjust, adjustx, - vsynctimeperline, vsynctimebase, (vsynctimebase - max) * 100 / vsynctimebase); - } - + if (vs < 0) { frame_shown = true; + status = 1; + return status != 0; } - return status != 0; } status = 1; @@ -7634,33 +7501,8 @@ static bool framewait (void) if (currprefs.m68k_speed < 0 && !cpu_sleepmode && !currprefs.cpu_memory_cycle_exact) { -#if 0 - static uae_u32 prevtick; - static int frametickcnt; - - uae_u32 tick = read_system_time (); // milliseconds - uae_s32 tickdiff = tick - prevtick; - uae_s32 framems = (frametickcnt * 1000) / (int)(vblank_hz + 0.5); - if (abs (framems - tickdiff) >= 2000) { - framems = 0; - tickdiff = 0; - prevtick = tick; - frametickcnt = 0; - write_log (_T("Clock sync reset!\n")); - } else { - frametickcnt++; - } - int diff = (framems - tickdiff) / 1; - if (diff < -100) - diff = -100; - else if (diff > 100) - diff = 100; - clockadjust = -vsynctimebase * diff / 10000; - //write_log (_T("%05d:%05d:%05d\n"), framems - tickdiff, diff, clockadjust); -#endif - - if (!frame_rendered && !picasso_on) - frame_rendered = render_screen (false); + if (!frame_rendered && !ad->picasso_on) + frame_rendered = render_screen(0, 1, false); if (currprefs.m68k_speed_throttle) { // this delay can safely overshoot frame time by 1-2 ms, following code will compensate for it. @@ -7703,12 +7545,12 @@ static bool framewait (void) int t = 0; start = read_processor_time(); - if (!frame_rendered && !picasso_on) { - frame_rendered = render_screen (false); + if (!frame_rendered && !ad->picasso_on) { + frame_rendered = render_screen(0, 1, false); t = read_processor_time () - start; } while (!currprefs.turbo_emulation) { - double v = rpt_vsync (clockadjust) / (syncbase / 1000.0); + float v = rpt_vsync (clockadjust) / (syncbase / 1000.0); if (v >= -2) break; rtg_vsynccheck (); @@ -7726,7 +7568,7 @@ static bool framewait (void) vsyncmintime = curr_time; vsyncmaxtime = vsyncwaittime = curr_time + vstb; if (frame_rendered) { - show_screen (0); + show_screen(0, 0); t += read_processor_time () - curr_time; } t += frameskipt_avg; @@ -7808,6 +7650,8 @@ static void fpscounter (bool frameok) // vsync functions that are not hardware timing related static void vsync_handler_pre (void) { + struct amigadisplay *ad = &adisplays[0]; + #if 1 if (currprefs.m68k_speed < 0) { if (regs.stopped) { @@ -7857,7 +7701,7 @@ static void vsync_handler_pre (void) if (!vsync_rendered) { frame_time_t start, end; start = read_processor_time (); - vsync_handle_redraw (lof_store, lof_changed, bplcon0, bplcon3); + vsync_handle_redraw(lof_store, lof_changed, bplcon0, bplcon3, isvsync_chipset() >= 0); vsync_rendered = true; end = read_processor_time (); frameskiptime += end - start; @@ -7865,12 +7709,12 @@ static void vsync_handler_pre (void) bool frameok = framewait (); - if (!picasso_on) { + if (!ad->picasso_on) { if (!frame_rendered && vblank_hz_state) { - frame_rendered = render_screen (false); + frame_rendered = render_screen(0, 1, false); } if (frame_rendered && !frame_shown) { - frame_shown = show_screen_maybe (isvsync_chipset () >= 0); + frame_shown = show_screen_maybe(0, isvsync_chipset () >= 0); } } @@ -7882,22 +7726,22 @@ static void vsync_handler_pre (void) bool waspaused = false; while (handle_events()) { if (!waspaused) { - render_screen(true); - show_screen(0); + render_screen(0, 1, true); + show_screen(0, 0); waspaused = true; } // we are paused, do all config checks but don't do any emulation if (vsync_handle_check()) { redraw_frame(); - render_screen(true); - show_screen(0); + render_screen(0, 1, true); + show_screen(0, 0); } config_check_vsync(); } if (quit_program > 0) { /* prevent possible infinite loop at wait_cycles().. */ - framecnt = 0; + ad->framecnt = 0; reset_decisions(); return; } @@ -7918,6 +7762,7 @@ static void vsync_handler_pre (void) // emulated hardware vsync static void vsync_handler_post (void) { + int monid = 0; static frame_time_t prevtime; //write_log (_T("%d %d %d\n"), vsynctimebase, read_processor_time () - vsyncmintime, read_processor_time () - prevtime); @@ -7965,12 +7810,12 @@ static void vsync_handler_post (void) if (lof_togglecnt_lace >= LOF_TOGGLES_NEEDED) { interlace_changed = notice_interlace_seen (true); if (interlace_changed) { - notice_screen_contents_lost (); + notice_screen_contents_lost(monid); } } else if (lof_togglecnt_nlace >= LOF_TOGGLES_NEEDED) { interlace_changed = notice_interlace_seen (false); if (interlace_changed) { - notice_screen_contents_lost (); + notice_screen_contents_lost(monid); } } if (lof_changing) { @@ -8130,7 +7975,6 @@ static void hsync_scandoubler (void) finish_decisions (); hsync_record_line_state (next_lineno, nln_normal, thisline_changed); - hardware_line_completed (next_lineno); scandoubled_line = 0; dmacon = odmacon; @@ -8269,6 +8113,20 @@ static bool is_custom_vsync (void) return false; } +static bool do_render_slice(int mode, int slicecnt) +{ + draw_lines(vpos, slicecnt); + render_screen(0, mode, true); + return true; +} + +static bool do_display_slice(void) +{ + show_screen(0, -1); + inputdevice_hsync(true); + return true; +} + static void set_hpos (void) { maxhpos = maxhpos_short + lol; @@ -8324,7 +8182,6 @@ static void hsync_handler_pre (bool onvsync) } } } - hardware_line_completed (next_lineno); if (doflickerfix () && interlace_seen > 0) hsync_scandoubler (); notice_resolution_seen (GET_RES_AGNUS (bplcon0), interlace_seen != 0); @@ -8366,6 +8223,324 @@ STATIC_INLINE bool is_last_line (void) return vpos + 1 == maxvpos + lof_store; } +// low latency vsync + +static void scanlinesleep(int currline, int nextline) +{ + if (currline < 0) + return; + if (currline >= nextline) + return; + int diff = vsync_hblank / (nextline - currline); + int us = 1000000 / diff; + if (us < 2100) { // less than 2ms + target_spin(nextline - currline - 1); + return; + } + cpu_sleep_millis(1); +} + +static bool linesync_beam_single(void) +{ + is_syncline = 0; + maybe_process_pull_audio(); + if (is_last_line()) { + do_render_slice(-1, 0); + while (!currprefs.turbo_emulation) { + maybe_process_pull_audio(); + target_spin(0); + int vp = target_get_display_scanline(-1); + if (vp >= 0) + break; + } + vsync_clear(); + while (!currprefs.turbo_emulation) { + maybe_process_pull_audio(); + int vp = target_get_display_scanline(-1); + if (vp >= vsync_activeheight - 1 || vp < 0) + break; + scanlinesleep(vp, vsync_activeheight - 1); + } + while (!currprefs.turbo_emulation) { + maybe_process_pull_audio(); + target_spin(0); + int vp = target_get_display_scanline(-1); + if (vp < 0) + break; + } + frame_rendered = true; + frame_shown = true; + return do_display_slice(); + } + return false; +} + + +static bool linesync_beam_multi_dual(void) +{ + static int vsyncnextscanline; + static int nextwaitvpos; + static int display_slice_cnt; + static int display_slice_lines; + static int display_slices; + static bool display_rendered; + bool input_read_done = false; + bool was_syncline = is_syncline != 0; + + is_syncline = 0; + if (vpos == 0 && !was_syncline) { + display_slices = currprefs.gfx_display_sections; + if (display_slices <= 0) + display_slices = 1; + display_slice_cnt = 0; + vsyncnextscanline = vsync_activeheight / display_slices + 1; + display_slice_lines = (maxvpos_display - minfirstline) / display_slices + 1; + nextwaitvpos = minfirstline + display_slice_lines; + if (display_slices <= 1) + nextwaitvpos = maxvpos_display + 1; + if (display_slices <= 2 && vsyncnextscanline > vsync_activeheight * 2 / 3) + vsyncnextscanline = vsync_activeheight * 2 / 3; + display_rendered = false; + frame_rendered = true; + frame_shown = true; + } + + if (vpos >= nextwaitvpos || is_last_line()) { + + if (display_slice_cnt == 0) { + + if (!was_syncline) { + do_render_slice(1, display_slice_cnt); + display_rendered = true; + } + if (!currprefs.turbo_emulation) { + while (!currprefs.turbo_emulation) { + frame_time_t rpt = read_processor_time(); + if ((int)rpt - (int)vsyncmintime >= 0 || (int)rpt - (int)vsyncmintime < -vsynctimebase * 2) { + vsyncmintime = rpt + vsynctimebase; + break; + } + maybe_process_pull_audio(); + target_spin(0); + } + do_display_slice(); + display_rendered = false; + input_read_done = true; + } + + } else { + + if (!currprefs.turbo_emulation) { + if (!was_syncline && !display_rendered) { + do_render_slice(0, display_slice_cnt); + display_rendered = true; + } + for (;;) { + int vp = target_get_display_scanline(-1); + if (vp == -1) { + maybe_process_pull_audio(); + target_spin(0); + continue; + } + if (vp < 0 || vp >= vsyncnextscanline) + break; + if (currprefs.m68k_speed < 0 && !was_syncline) { + is_syncline = vsyncnextscanline; + return 0; + } + maybe_process_pull_audio(); + scanlinesleep(vp, vsyncnextscanline); + } + do_display_slice(); + input_read_done = true; + display_rendered = false; + } + vsyncnextscanline += vsync_activeheight / display_slices; + vsync_clear(); + + if (is_last_line()) { + // wait until about middle of second frame + while (!currprefs.turbo_emulation) { + frame_time_t rpt = read_processor_time(); + if ((int)rpt - ((int)vsyncmintime - vsynctimebase * 1 / 4) >= 0) + break; + maybe_process_pull_audio(); + target_spin(0); + } + } + } + + nextwaitvpos += display_slice_lines; + display_slice_cnt++; + + + } + return input_read_done; +} + + +static bool linesync_beam_multi(void) +{ + static int vsyncnextscanline; + static int vsyncnextscanline_add; + static int nextwaitvpos; + static int display_slice_cnt; + static int display_slice_lines; + static int display_slices; + static bool display_rendered; + bool input_read_done = false; + bool was_syncline = is_syncline != 0; + + is_syncline = 0; + if (vpos == 0 && !was_syncline) { + display_slices = currprefs.gfx_display_sections; + if (!display_slices) + display_slices = 1; + display_slice_cnt = 0; + vsyncnextscanline = vsync_activeheight / display_slices + 1; + vsyncnextscanline_add = vsync_activeheight / display_slices; + display_slice_lines = (maxvpos_display - minfirstline) / display_slices + 1; + nextwaitvpos = minfirstline + display_slice_lines + display_slice_lines / 2; + if (display_slices <= 1) + nextwaitvpos = maxvpos_display + 1; + if (display_slices <= 2 && vsyncnextscanline > vsync_activeheight * 2 / 3) + vsyncnextscanline = vsync_activeheight * 2 / 3; + + display_rendered = false; + frame_rendered = true; + frame_shown = true; + } + + if (is_last_line()) { + + if (!was_syncline && !display_rendered) { + do_render_slice(0, display_slice_cnt); + display_rendered = true; + } + while (!currprefs.turbo_emulation) { + int vp = target_get_display_scanline(-1); + if (vp < 0 || vp >= vsyncnextscanline) + break; + maybe_process_pull_audio(); + if (currprefs.m68k_speed < 0 && !was_syncline) { + is_syncline = vsyncnextscanline; + return 0; + } + scanlinesleep(vp, vsyncnextscanline); + } + do_display_slice(); + input_read_done = true; + display_slice_cnt = -1; + display_rendered = false; + + } else if (vpos >= nextwaitvpos) { + + if (display_slice_cnt == 0) { + // topmost slice + + if (currprefs.gfx_variable_sync) { + + do_render_slice(1, display_slice_cnt); + display_rendered = true; + + for (;;) { + frame_time_t rpt = read_processor_time(); + if ((int)rpt - (int)vsyncmintime >= 0 || (int)rpt - (int)vsyncmintime < -2 * vsynctimebase) + break; + maybe_process_pull_audio(); + target_spin(0); + } + vsyncmintime = read_processor_time() + vsynctimebase; + + while (!currprefs.turbo_emulation) { + maybe_process_pull_audio(); + int vp = target_get_display_scanline(-1); + if (vp < 0) + break; + scanlinesleep(vp, vsync_activeheight - 1); + } + + do_display_slice(); + display_rendered = false; + input_read_done = true; + + } else { + + if (!currprefs.turbo_emulation) { + if (!was_syncline) { + do_render_slice(1, display_slice_cnt); + display_rendered = true; + } + + for (;;) { + int vp = target_get_display_scanline(-1); + maybe_process_pull_audio(); + if (vp < 0 || vp < vsync_activeheight / 2 || vp >= vsync_activeheight - 1) + break; + if (currprefs.m68k_speed < 0 && !was_syncline) { + is_syncline = -1; + return 0; + } + target_spin(0); + } + do_display_slice(); + display_rendered = false; + input_read_done = true; + } + + } + + } else { + + // skip if too close + int vp2 = target_get_display_scanline(-1); + if (!currprefs.turbo_emulation && (currprefs.m68k_speed < 0 || vp2 < vsyncnextscanline - vsyncnextscanline_add / 10)) { + if (!was_syncline && !display_rendered) { + do_render_slice(0, display_slice_cnt); + display_rendered = true; + } + for(;;) { + int vp = target_get_display_scanline(-1); + if (vp == -1) { + maybe_process_pull_audio(); + target_spin(0); + continue; + } + if (vp < 0 || vp >= vsyncnextscanline) + break; + maybe_process_pull_audio(); + if (currprefs.m68k_speed < 0 && !was_syncline) { + is_syncline = vsyncnextscanline; + return 0; + } + scanlinesleep(vp, vsyncnextscanline); + } + do_display_slice(); + input_read_done = true; + display_rendered = false; + } + vsyncnextscanline += vsyncnextscanline_add; + vsync_clear(); + } + nextwaitvpos += display_slice_lines; + display_slice_cnt++; + } + return input_read_done; +} + +// called when extra CPU wait is done +void vsync_event_done(void) +{ + if (currprefs.gfx_display_sections <= 1) { + linesync_beam_single(); + } else { + if (vsync_hblank >= 85 && currprefs.gfx_variable_sync) + linesync_beam_multi_dual(); + else + linesync_beam_multi(); + } +} + // this prepares for new line static void hsync_handler_post (bool onvsync) { @@ -8441,8 +8616,6 @@ static void hsync_handler_post (bool onvsync) } } - inputdevice_hsync (); - if (!nocustom ()) { if (!currprefs.blitter_cycle_exact && bltstate != BLT_done && dmaen (DMA_BITPLANE) && diwstate == DIW_waiting_stop) { blitter_slowdown (thisline_decision.plfleft, thisline_decision.plfright - (16 << fetchmode), @@ -8512,7 +8685,21 @@ static void hsync_handler_post (bool onvsync) port_get_custom (1, out); } #endif - if (!currprefs.cpu_thread && !cpu_sleepmode && currprefs.m68k_speed < 0 && !currprefs.cpu_memory_cycle_exact) { + bool input_read_done = false; + + if (isvsync_chipset() < 0) { + + if (currprefs.gfx_display_sections <= 1) { + input_read_done = linesync_beam_single(); + } else { + if (vsync_hblank >= 85 && currprefs.gfx_variable_sync) + input_read_done = linesync_beam_multi_dual(); + else + input_read_done = linesync_beam_multi(); + } + + } else if (!currprefs.cpu_thread && !cpu_sleepmode && currprefs.m68k_speed < 0 && !currprefs.cpu_memory_cycle_exact) { + static int sleeps_remaining; if (is_last_line ()) { sleeps_remaining = (165 - currprefs.cpu_idle) / 6; @@ -8522,7 +8709,7 @@ static void hsync_handler_post (bool onvsync) if (regs.stopped && currprefs.cpu_idle) { // CPU in STOP state: sleep if enough time left. frame_time_t rpt = read_processor_time (); - while (!vsync_isdone () && (int)vsyncmintime - (int)(rpt + vsynctimebase / 10) > 0 && (int)vsyncmintime - (int)rpt < vsynctimebase) { + while (vsync_isdone(NULL) <= 0 && (int)vsyncmintime - (int)(rpt + vsynctimebase / 10) > 0 && (int)vsyncmintime - (int)rpt < vsynctimebase) { maybe_process_pull_audio(); if (!execute_other_cpu(rpt + vsynctimebase / 10)) { if (cpu_sleep_millis(1) < 0) @@ -8537,7 +8724,7 @@ static void hsync_handler_post (bool onvsync) } else { vsyncmintime = vsyncmaxtime; /* emulate if still time left */ is_syncline_end = read_processor_time () + vsynctimebase; /* far enough in future, we never wait that long */ - is_syncline = 2; + is_syncline = -12; maybe_process_pull_audio(); } } else { @@ -8546,7 +8733,7 @@ static void hsync_handler_post (bool onvsync) vsyncmintime += vsynctimeperline; linecounter++; is_syncline = 0; - if (!vsync_isdone () && !currprefs.turbo_emulation) { + if (vsync_isdone(NULL) <= 0 && !currprefs.turbo_emulation) { if ((int)vsyncmaxtime - (int)vsyncmintime > 0) { if ((int)vsyncwaittime - (int)vsyncmintime > 0) { frame_time_t rpt = read_processor_time (); @@ -8558,7 +8745,7 @@ static void hsync_handler_post (bool onvsync) sleeps_remaining--; maybe_process_pull_audio(); } else { - is_syncline = 1; + is_syncline = -11; /* limit extra time */ is_syncline_end = rpt + vsynctimeperline; linecounter = 0; @@ -8568,7 +8755,7 @@ static void hsync_handler_post (bool onvsync) if (!isvsync ()) { // extra cpu emulation time if previous 10 lines without extra time. if (!is_syncline && linecounter >= 10 && (!regs.stopped || !currprefs.cpu_idle)) { - is_syncline = -1; + is_syncline = -10; is_syncline_end = read_processor_time () + vsynctimeperline; linecounter = 0; } @@ -8577,14 +8764,17 @@ static void hsync_handler_post (bool onvsync) } maybe_process_pull_audio(); } + } else if (!currprefs.cpu_thread) { + + // the rest static int nextwaitvpos; if (vpos == 0) nextwaitvpos = maxvpos_display * 1 / 4; if (audio_is_pull() > 0 && !currprefs.turbo_emulation) { maybe_process_pull_audio(); frame_time_t rpt = read_processor_time(); - while (audio_pull_buffer() > 1 && (!isvsync() || (!vsync_isdone() && (int)vsyncmintime - (int)(rpt + vsynctimebase / 10) > 0 && (int)vsyncmintime - (int)rpt < vsynctimebase))) { + while (audio_pull_buffer() > 1 && (!isvsync() || (vsync_isdone(NULL) <= 0 && (int)vsyncmintime - (int)(rpt + vsynctimebase / 10) > 0 && (int)vsyncmintime - (int)rpt < vsynctimebase))) { cpu_sleep_millis(1); maybe_process_pull_audio(); rpt = read_processor_time(); @@ -8593,22 +8783,24 @@ static void hsync_handler_post (bool onvsync) if (vpos + 1 < maxvpos + lof_store && vpos >= nextwaitvpos && vpos < maxvpos - (maxvpos / 3) && (audio_is_pull() <= 0 || (audio_is_pull() > 0 && audio_pull_buffer()))) { nextwaitvpos += maxvpos_display * 1 / 3; vsyncmintime += vsynctimeperline; - if (!vsync_isdone () && !currprefs.turbo_emulation) { - frame_time_t rpt = read_processor_time (); + if (vsync_isdone(NULL) <= 0 && !currprefs.turbo_emulation) { + frame_time_t rpt = read_processor_time(); // sleep if more than 2ms "free" time - while (!vsync_isdone () && (int)vsyncmintime - (int)(rpt + vsynctimebase / 10) > 0 && (int)vsyncmintime - (int)rpt < vsynctimebase) { + while (vsync_isdone(NULL) <= 0 && (int)vsyncmintime - (int)(rpt + vsynctimebase / 10) > 0 && (int)vsyncmintime - (int)rpt < vsynctimebase) { maybe_process_pull_audio(); if (!execute_other_cpu(rpt + vsynctimebase / 10)) { if (cpu_sleep_millis(1) < 0) break; } - rpt = read_processor_time (); - //write_log (_T("*")); + rpt = read_processor_time(); } } } } + if (!input_read_done) + inputdevice_hsync(false); + if (!nocustom ()) { int lineno = vpos; if (lineno >= MAXVPOS) @@ -8709,6 +8901,7 @@ static void hsync_handler_post (bool onvsync) if (diw_change > 0) diw_change--; +#if 0 /* fastest possible + last line and no vflip wait: render the frame as early as possible */ if (is_last_line () && isvsync_chipset () <= -2 && !vsync_rendered && currprefs.gfx_apmode[0].gfx_vflip == 0) { frame_time_t start, end; @@ -8716,11 +8909,12 @@ static void hsync_handler_post (bool onvsync) vsync_rendered = true; vsync_handle_redraw (lof_store, lof_changed, bplcon0, bplcon3); if (vblank_hz_state) { - frame_rendered = render_screen (true); + frame_rendered = render_screen(1, true); } end = read_processor_time (); frameskiptime += end - start; } +#endif rtg_vsynccheck (); @@ -8994,7 +9188,7 @@ void custom_reset (bool hardreset, bool keyboardreset) rtc_hardreset(); #ifdef PICASSO96 - picasso_reset (); + picasso_reset(0); #endif } diff --git a/debug.cpp b/debug.cpp index 7068aedb..e25e71e9 100644 --- a/debug.cpp +++ b/debug.cpp @@ -5294,7 +5294,7 @@ static bool debug_line (TCHAR *input) debugmem_list_segment(0, addr); } } else if (*inptr == 'c') { - screenshot (1, 1); + screenshot(0, 1, 1); } else if (*inptr == 'p') { inptr++; debug_sprite (&inptr); @@ -5566,7 +5566,7 @@ static bool debug_line (TCHAR *input) debug_bpl_mask = readhex (&inptr) & 0xff; if (more_params (&inptr)) debug_bpl_mask_one = readhex (&inptr) & 0xff; - notice_screen_contents_lost (); + notice_screen_contents_lost(0); } console_out_f (_T("Bitplane mask: %02X (%02X)\n"), debug_bpl_mask, debug_bpl_mask_one); break; @@ -6019,7 +6019,7 @@ void debug (void) #endif inputdevice_unacquire (); pause_sound (); - setmouseactive (0); + setmouseactive(0, 0); activate_console (); trace_mode = 0; exception_debugging = 0; @@ -6056,7 +6056,7 @@ void debug (void) #ifdef WITH_PPC uae_ppc_pause(0); #endif - setmouseactive (wasactive ? 2 : 0); + setmouseactive(0, wasactive ? 2 : 0); } const TCHAR *debuginfo (int mode) diff --git a/devices.cpp b/devices.cpp index 5b73a72f..e6760c4e 100644 --- a/devices.cpp +++ b/devices.cpp @@ -154,10 +154,6 @@ void devices_vsync_pre(void) void devices_vsync_post(void) { -#ifdef GFXBOARD - if (!picasso_on) - gfxboard_vsync_handler(false); -#endif #ifdef WITH_TOCCATA sndboard_vsync(); #endif @@ -283,7 +279,9 @@ void reset_all_systems (void) uae_ppc_reset(is_hardreset()); #endif #ifdef PICASSO96 - picasso_reset (); + for (int i = 0; i < MAX_AMIGADISPLAYS; i++) { + picasso_reset(i); + } #endif #ifdef SCSIEMU scsi_reset (); diff --git a/drawing.cpp b/drawing.cpp index 6326c0df..37a4ae9c 100644 --- a/drawing.cpp +++ b/drawing.cpp @@ -55,6 +55,8 @@ happening, all ports should restrict window widths to be multiples of 16 pixels. #define BG_COLOR_DEBUG 0 //#define XLINECHECK +struct amigadisplay adisplays[MAX_AMIGADISPLAYS]; + typedef enum { CMODE_NORMAL, @@ -138,8 +140,6 @@ static uae_u32 clxtab[256]; /* Video buffer description structure. Filled in by the graphics system * dependent code. */ -struct vidbuf_description gfxvidinfo; - /* OCS/ECS color lookup table. */ xcolnr xcolors[4096]; @@ -268,54 +268,61 @@ static int plf1pri, plf2pri, bplxor, bpland, bpldelay_sh; static uae_u32 plf_sprite_mask; static int sbasecol[2] = { 16, 16 }; static int hposblank; -static bool specialmonitoron; static bool ecs_genlock_features_active; static uae_u8 ecs_genlock_features_mask; static bool ecs_genlock_features_colorkey; static int hsync_shift_hack; -bool picasso_requested_on, picasso_requested_forced_on, picasso_on; - uae_sem_t gui_sem; -int inhibit_frame; -int framecnt; -int custom_frame_redraw_necessary; -static int frame_redraw_necessary; -static int picasso_redraw_necessary; +void set_inhibit_frame(int monid, int bit) +{ + struct amigadisplay *ad = &adisplays[monid]; + ad->inhibit_frame |= 1 << bit; +} +void clear_inhibit_frame(int monid, int bit) +{ + struct amigadisplay *ad = &adisplays[monid]; + ad->inhibit_frame &= ~(1 << bit); +} +void toggle_inhibit_frame(int monid, int bit) +{ + struct amigadisplay *ad = &adisplays[monid]; + ad->inhibit_frame ^= 1 << bit; +} #ifdef XLINECHECK static void xlinecheck (unsigned int start, unsigned int end) { - unsigned int xstart = (unsigned int)xlinebuffer + start * gfxvidinfo.drawbuffer.pixbytes; - unsigned int xend = (unsigned int)xlinebuffer + end * gfxvidinfo.drawbuffer.pixbytes; - unsigned int end1 = (unsigned int)gfxvidinfo.drawbuffer.bufmem + gfxvidinfo.drawbuffer.rowbytes * gfxvidinfo.drawbuffer.height; - int min = linetoscr_x_adjust_bytes / gfxvidinfo.drawbuffer.pixbytes; + unsigned int xstart = (unsigned int)xlinebuffer + start * vidinfo->drawbuffer.pixbytes; + unsigned int xend = (unsigned int)xlinebuffer + end * vidinfo->drawbuffer.pixbytes; + unsigned int end1 = (unsigned int)vidinfo->drawbuffer.bufmem + vidinfo->drawbuffer.rowbytes * vidinfo->drawbuffer.height; + int min = linetoscr_x_adjust_bytes / vidinfo->drawbuffer.pixbytes; int ok = 1; - if (xstart >= gfxvidinfo.drawbuffer.emergmem && xstart < gfxvidinfo.drawbuffer.emergmem + 4096 * gfxvidinfo.drawbuffer.pixbytes && - xend >= gfxvidinfo.drawbuffer.emergmem && xend < gfxvidinfo.drawbuffer.emergmem + 4096 * gfxvidinfo.drawbuffer.pixbytes) + if (xstart >= vidinfo->drawbuffer.emergmem && xstart < vidinfo->drawbuffer.emergmem + 4096 * vidinfo->drawbuffer.pixbytes && + xend >= vidinfo->drawbuffer.emergmem && xend < vidinfo->drawbuffer.emergmem + 4096 * vidinfo->drawbuffer.pixbytes) return; - if (xstart < (unsigned int)gfxvidinfo.drawbuffer.bufmem || xend < (unsigned int)gfxvidinfo.drawbuffer.bufmem) + if (xstart < (unsigned int)vidinfo->drawbuffer.bufmem || xend < (unsigned int)vidinfo->drawbuffer.bufmem) ok = 0; if (xend > end1 || xstart >= end1) ok = 0; - xstart -= (unsigned int)gfxvidinfo.drawbuffer.bufmem; - xend -= (unsigned int)gfxvidinfo.drawbuffer.bufmem; - if ((xstart % gfxvidinfo.drawbuffer.rowbytes) >= gfxvidinfo.drawbuffer.width * gfxvidinfo.drawbuffer.pixbytes) + xstart -= (unsigned int)vidinfo->drawbuffer.bufmem; + xend -= (unsigned int)vidinfo->drawbuffer.bufmem; + if ((xstart % vidinfo->drawbuffer.rowbytes) >= vidinfo->drawbuffer.width * vidinfo->drawbuffer.pixbytes) ok = 0; - if ((xend % gfxvidinfo.drawbuffer.rowbytes) >= gfxvidinfo.drawbuffer.width * gfxvidinfo.drawbuffer.pixbytes) + if ((xend % vidinfo->drawbuffer.rowbytes) >= vidinfo->drawbuffer.width * vidinfo->drawbuffer.pixbytes) ok = 0; if (xstart >= xend) ok = 0; - if (xend - xstart > gfxvidinfo.drawbuffer.width * gfxvidinfo.drawbuffer.pixbytes) + if (xend - xstart > vidinfo->drawbuffer.width * vidinfo->drawbuffer.pixbytes) ok = 0; if (!ok) { write_log (_T("*** %d-%d (%dx%dx%d %d) %p\n"), - start - min, end - min, gfxvidinfo.drawbuffer.width, gfxvidinfo.drawbuffer.height, - gfxvidinfo.drawbuffer.pixbytes, gfxvidinfo.drawbuffer.rowbytes, + start - min, end - min, vidinfo->drawbuffer.width, vidinfo->drawbuffer.height, + vidinfo->drawbuffer.pixbytes, vidinfo->drawbuffer.rowbytes, xlinebuffer); } } @@ -341,13 +348,14 @@ static void reset_decision_table (void) } } -STATIC_INLINE void count_frame (void) +static void count_frame(int monid) { - framecnt++; - if (framecnt >= currprefs.gfx_framerate || currprefs.monitoremu == MONITOREMU_A2024) - framecnt = 0; - if (inhibit_frame) - framecnt = 1; + struct amigadisplay *ad = &adisplays[monid]; + ad->framecnt++; + if (ad->framecnt >= currprefs.gfx_framerate || currprefs.monitoremu == MONITOREMU_A2024) + ad->framecnt = 0; + if (ad->inhibit_frame) + ad->framecnt = 1; } STATIC_INLINE int xshift (int x, int shift) @@ -384,19 +392,21 @@ STATIC_INLINE int res_shift_from_amiga (int x) return x << -res_shift; } -void notice_screen_contents_lost (void) +void notice_screen_contents_lost(int monid) { - picasso_redraw_necessary = 1; - frame_redraw_necessary = 2; + struct amigadisplay *ad = &adisplays[monid]; + ad->picasso_redraw_necessary = 1; + ad->frame_redraw_necessary = 2; } -bool isnativevidbuf (void) +bool isnativevidbuf(int monid) { - if (gfxvidinfo.outbuffer == NULL) + struct vidbuf_description *vidinfo = &adisplays[monid].gfxvidinfo; + if (vidinfo->outbuffer == NULL) return false; - if (gfxvidinfo.outbuffer == &gfxvidinfo.drawbuffer) + if (vidinfo->outbuffer == &vidinfo->drawbuffer) return true; - return gfxvidinfo.outbuffer->nativepositioning; + return vidinfo->outbuffer->nativepositioning; } extern int plffirstline_total, plflastline_total; @@ -417,8 +427,7 @@ static int stored_left_start, stored_top_start, stored_width, stored_height; void get_custom_topedge (int *xp, int *yp, bool max) { - - if (isnativevidbuf () && !max) { + if (isnativevidbuf(0) && !max) { int x, y; x = visible_left_border + (DISPLAY_LEFT_SHIFT << currprefs.gfx_resolution); y = minfirstline << currprefs.gfx_vresolution; @@ -543,7 +552,7 @@ void set_custom_limits (int w, int h, int dx, int dy) if (vls != visible_left_start || vrs != visible_right_stop || vts != visible_top_start || vbs != visible_bottom_stop) - notice_screen_contents_lost (); + notice_screen_contents_lost(0); check_custom_limits(); } @@ -566,6 +575,7 @@ void store_custom_limits (int w, int h, int x, int y) int get_custom_limits (int *pw, int *ph, int *pdx, int *pdy, int *prealh) { + struct vidbuf_description *vidinfo = &adisplays[0].gfxvidinfo; int w, h, dx, dy, y1, y2, dbl1, dbl2; int ret = 0; @@ -574,9 +584,9 @@ int get_custom_limits (int *pw, int *ph, int *pdx, int *pdy, int *prealh) return 0; } - if (!isnativevidbuf ()) { - *pw = gfxvidinfo.outbuffer->outwidth; - *ph = gfxvidinfo.outbuffer->outheight; + if (!isnativevidbuf(0)) { + *pw = vidinfo->outbuffer->outwidth; + *ph = vidinfo->outbuffer->outheight; *pdx = 0; *pdy = 0; *prealh = -1; @@ -710,9 +720,9 @@ int get_custom_limits (int *pw, int *ph, int *pdx, int *pdy, int *prealh) if (w <= 0 || h <= 0 || dx < 0 || dy < 0) return ret; if (doublescan <= 0 && !programmedmode) { - if (dx > gfxvidinfo.outbuffer->inwidth / 3) + if (dx > vidinfo->outbuffer->inwidth / 3) return ret; - if (dy > gfxvidinfo.outbuffer->inheight / 3) + if (dy > vidinfo->outbuffer->inheight / 3) return ret; } @@ -1135,9 +1145,10 @@ STATIC_INLINE void fill_line_32 (uae_u8 *buf, int start, int stop, bool blank) static void pfield_do_fill_line (int start, int stop, bool blank) { + struct vidbuf_description *vidinfo = &adisplays[0].gfxvidinfo; if (stop <= start) return; - switch (gfxvidinfo.drawbuffer.pixbytes) { + switch (vidinfo->drawbuffer.pixbytes) { case 2: fill_line_16 (xlinebuffer, start, stop, blank); break; case 4: fill_line_32 (xlinebuffer, start, stop, blank); break; } @@ -1148,15 +1159,16 @@ static void pfield_do_fill_line (int start, int stop, bool blank) static void fill_line2 (int startpos, int len) { + struct vidbuf_description *vidinfo = &adisplays[0].gfxvidinfo; int shift; int nints, nrem; int *start; xcolnr val; shift = 0; - if (gfxvidinfo.drawbuffer.pixbytes == 2) + if (vidinfo->drawbuffer.pixbytes == 2) shift = 1; - if (gfxvidinfo.drawbuffer.pixbytes == 4) + if (vidinfo->drawbuffer.pixbytes == 4) shift = 2; nints = len >> (2 - shift); @@ -1195,15 +1207,16 @@ static void fill_line2 (int startpos, int len) static void fill_line_border (int lineno) { + struct vidbuf_description *vidinfo = &adisplays[0].gfxvidinfo; int lastpos = visible_left_border; - int endpos = visible_left_border + gfxvidinfo.drawbuffer.inwidth; + int endpos = visible_left_border + vidinfo->drawbuffer.inwidth; if (lineno < visible_top_start || lineno >= visible_bottom_stop) { int b = hposblank; hposblank = 3; - fill_line2(lastpos, gfxvidinfo.drawbuffer.inwidth); + fill_line2(lastpos, vidinfo->drawbuffer.inwidth); if (need_genlock_data) { - memset(xlinebuffer_genlock + lastpos, 0, gfxvidinfo.drawbuffer.inwidth); + memset(xlinebuffer_genlock + lastpos, 0, vidinfo->drawbuffer.inwidth); } hposblank = b; return; @@ -1212,17 +1225,17 @@ static void fill_line_border (int lineno) // full hblank if (hposblank) { hposblank = 3; - fill_line2(lastpos, gfxvidinfo.drawbuffer.inwidth); + fill_line2(lastpos, vidinfo->drawbuffer.inwidth); if (need_genlock_data) { - memset(xlinebuffer_genlock + lastpos, 0, gfxvidinfo.drawbuffer.inwidth); + memset(xlinebuffer_genlock + lastpos, 0, vidinfo->drawbuffer.inwidth); } return; } // hblank not visible if (hblank_left_start <= lastpos && hblank_right_stop >= endpos) { - fill_line2(lastpos, gfxvidinfo.drawbuffer.inwidth); + fill_line2(lastpos, vidinfo->drawbuffer.inwidth); if (need_genlock_data) { - memset(xlinebuffer_genlock + lastpos, 0, gfxvidinfo.drawbuffer.inwidth); + memset(xlinebuffer_genlock + lastpos, 0, vidinfo->drawbuffer.inwidth); } return; } @@ -1710,8 +1723,9 @@ static call_linetoscr pfield_do_linetoscr_shdelay_sprite; static int pfield_do_linetoscr_normal_shdelay(int spix, int dpix, int dpix_end) { + struct vidbuf_description *vidinfo = &adisplays[0].gfxvidinfo; int add = get_shdelay_add(); - int add2 = add * gfxvidinfo.drawbuffer.pixbytes; + int add2 = add * vidinfo->drawbuffer.pixbytes; if (add) { // Clear skipped pixel(s). pfield_do_linetoscr_shdelay_sprite(spix, dpix, dpix + add); @@ -1723,6 +1737,7 @@ static int pfield_do_linetoscr_normal_shdelay(int spix, int dpix, int dpix_end) } static int pfield_do_linetoscr_sprite_shdelay(int spix, int dpix, int dpix_end) { + struct vidbuf_description *vidinfo = &adisplays[0].gfxvidinfo; int out = spix; if (dpix < real_playfield_start && dpix_end > real_playfield_start) { // Crosses real_playfield_start. @@ -1737,7 +1752,7 @@ static int pfield_do_linetoscr_sprite_shdelay(int spix, int dpix, int dpix_end) } // Render bitplane with subpixel scroll, from real_playfield_start to end. int add = get_shdelay_add(); - int add2 = add * gfxvidinfo.drawbuffer.pixbytes; + int add2 = add * vidinfo->drawbuffer.pixbytes; if (add) { pfield_do_linetoscr_shdelay_sprite(out, dpix, dpix + add); } @@ -1753,6 +1768,7 @@ static int pfield_do_linetoscr_sprite_shdelay(int spix, int dpix, int dpix_end) static void pfield_set_linetoscr (void) { + struct vidbuf_description *vidinfo = &adisplays[0].gfxvidinfo; xlinecheck(start, stop); p_acolors = colors_for_drawing.acolors; p_xcolors = xcolors; @@ -1765,7 +1781,7 @@ static void pfield_set_linetoscr (void) #ifdef AGA if (currprefs.chipset_mask & CSMASK_AGA) { if (res_shift == 0) { - switch (gfxvidinfo.drawbuffer.pixbytes) { + switch (vidinfo->drawbuffer.pixbytes) { case 2: pfield_do_linetoscr_normal = need_genlock_data ? linetoscr_16_aga_genlock : linetoscr_16_aga; pfield_do_linetoscr_sprite = need_genlock_data ? linetoscr_16_aga_spr_genlock : linetoscr_16_aga_spr; @@ -1778,7 +1794,7 @@ static void pfield_set_linetoscr (void) break; } } else if (res_shift == 2) { - switch (gfxvidinfo.drawbuffer.pixbytes) { + switch (vidinfo->drawbuffer.pixbytes) { case 2: pfield_do_linetoscr_normal = need_genlock_data ? linetoscr_16_stretch2_aga_genlock : linetoscr_16_stretch2_aga; pfield_do_linetoscr_sprite = need_genlock_data ? linetoscr_16_stretch2_aga_spr_genlock : linetoscr_16_stretch2_aga_spr; @@ -1791,7 +1807,7 @@ static void pfield_set_linetoscr (void) break; } } else if (res_shift == 1) { - switch (gfxvidinfo.drawbuffer.pixbytes) { + switch (vidinfo->drawbuffer.pixbytes) { case 2: pfield_do_linetoscr_normal = need_genlock_data ? linetoscr_16_stretch1_aga_genlock : linetoscr_16_stretch1_aga; pfield_do_linetoscr_sprite = need_genlock_data ? linetoscr_16_stretch1_aga_spr_genlock : linetoscr_16_stretch1_aga_spr; @@ -1805,7 +1821,7 @@ static void pfield_set_linetoscr (void) } } else if (res_shift == -1) { if (currprefs.gfx_lores_mode) { - switch (gfxvidinfo.drawbuffer.pixbytes) { + switch (vidinfo->drawbuffer.pixbytes) { case 2: pfield_do_linetoscr_normal = need_genlock_data ? linetoscr_16_shrink1f_aga_genlock : linetoscr_16_shrink1f_aga; pfield_do_linetoscr_sprite = need_genlock_data ? linetoscr_16_shrink1f_aga_spr_genlock : linetoscr_16_shrink1f_aga_spr; @@ -1818,7 +1834,7 @@ static void pfield_set_linetoscr (void) break; } } else { - switch (gfxvidinfo.drawbuffer.pixbytes) { + switch (vidinfo->drawbuffer.pixbytes) { case 2: pfield_do_linetoscr_normal = need_genlock_data ? linetoscr_16_shrink1_aga_genlock : linetoscr_16_shrink1_aga; pfield_do_linetoscr_sprite = need_genlock_data ? linetoscr_16_shrink1_aga_spr_genlock : linetoscr_16_shrink1_aga_spr; @@ -1833,7 +1849,7 @@ static void pfield_set_linetoscr (void) } } else if (res_shift == -2) { if (currprefs.gfx_lores_mode) { - switch (gfxvidinfo.drawbuffer.pixbytes) { + switch (vidinfo->drawbuffer.pixbytes) { case 2: pfield_do_linetoscr_normal = need_genlock_data ? linetoscr_16_shrink2f_aga_genlock : linetoscr_16_shrink2f_aga; pfield_do_linetoscr_sprite = need_genlock_data ? linetoscr_16_shrink2f_aga_spr_genlock : linetoscr_16_shrink2f_aga_spr; @@ -1846,7 +1862,7 @@ static void pfield_set_linetoscr (void) break; } } else { - switch (gfxvidinfo.drawbuffer.pixbytes) { + switch (vidinfo->drawbuffer.pixbytes) { case 2: pfield_do_linetoscr_normal = need_genlock_data ? linetoscr_16_shrink2_aga_genlock : linetoscr_16_shrink2_aga; pfield_do_linetoscr_sprite = need_genlock_data ? linetoscr_16_shrink2_aga_spr_genlock : linetoscr_16_shrink2_aga_spr; @@ -1872,7 +1888,7 @@ static void pfield_set_linetoscr (void) if (!(currprefs.chipset_mask & CSMASK_AGA) && ecsshres) { // TODO: genlock support if (res_shift == 0) { - switch (gfxvidinfo.drawbuffer.pixbytes) { + switch (vidinfo->drawbuffer.pixbytes) { case 2: pfield_do_linetoscr_normal = linetoscr_16_sh; pfield_do_linetoscr_sprite = linetoscr_16_sh_spr; @@ -1884,7 +1900,7 @@ static void pfield_set_linetoscr (void) } } else if (res_shift == -1) { if (currprefs.gfx_lores_mode) { - switch (gfxvidinfo.drawbuffer.pixbytes) { + switch (vidinfo->drawbuffer.pixbytes) { case 2: pfield_do_linetoscr_normal = linetoscr_16_shrink1f_sh; pfield_do_linetoscr_sprite = linetoscr_16_shrink1f_sh_spr; @@ -1895,7 +1911,7 @@ static void pfield_set_linetoscr (void) break; } } else { - switch (gfxvidinfo.drawbuffer.pixbytes) { + switch (vidinfo->drawbuffer.pixbytes) { case 2: pfield_do_linetoscr_normal = linetoscr_16_shrink1_sh; pfield_do_linetoscr_sprite = linetoscr_16_shrink1_sh_spr; @@ -1908,7 +1924,7 @@ static void pfield_set_linetoscr (void) } } else if (res_shift == -2) { if (currprefs.gfx_lores_mode) { - switch (gfxvidinfo.drawbuffer.pixbytes) { + switch (vidinfo->drawbuffer.pixbytes) { case 2: pfield_do_linetoscr_normal = linetoscr_16_shrink2f_sh; pfield_do_linetoscr_sprite = linetoscr_16_shrink2f_sh_spr; @@ -1919,7 +1935,7 @@ static void pfield_set_linetoscr (void) break; } } else { - switch (gfxvidinfo.drawbuffer.pixbytes) { + switch (vidinfo->drawbuffer.pixbytes) { case 2: pfield_do_linetoscr_normal = linetoscr_16_shrink2_sh; pfield_do_linetoscr_sprite = linetoscr_16_shrink2_sh_spr; @@ -1935,7 +1951,7 @@ static void pfield_set_linetoscr (void) #endif if (!(currprefs.chipset_mask & CSMASK_AGA) && !ecsshres) { if (res_shift == 0) { - switch (gfxvidinfo.drawbuffer.pixbytes) { + switch (vidinfo->drawbuffer.pixbytes) { case 2: pfield_do_linetoscr_normal = need_genlock_data ? linetoscr_16_genlock : linetoscr_16; pfield_do_linetoscr_sprite = need_genlock_data ? linetoscr_16_spr_genlock : linetoscr_16_spr; @@ -1946,7 +1962,7 @@ static void pfield_set_linetoscr (void) break; } } else if (res_shift == 2) { - switch (gfxvidinfo.drawbuffer.pixbytes) { + switch (vidinfo->drawbuffer.pixbytes) { case 2: pfield_do_linetoscr_normal = need_genlock_data ? linetoscr_16_stretch2_genlock : linetoscr_16_stretch2; pfield_do_linetoscr_sprite = need_genlock_data ? linetoscr_16_stretch2_spr_genlock : linetoscr_16_stretch2_spr; @@ -1957,7 +1973,7 @@ static void pfield_set_linetoscr (void) break; } } else if (res_shift == 1) { - switch (gfxvidinfo.drawbuffer.pixbytes) { + switch (vidinfo->drawbuffer.pixbytes) { case 2: pfield_do_linetoscr_normal = need_genlock_data ? linetoscr_16_stretch1_genlock : linetoscr_16_stretch1; pfield_do_linetoscr_sprite = need_genlock_data ? linetoscr_16_stretch1_spr_genlock : linetoscr_16_stretch1_spr; @@ -1969,7 +1985,7 @@ static void pfield_set_linetoscr (void) } } else if (res_shift == -1) { if (currprefs.gfx_lores_mode) { - switch (gfxvidinfo.drawbuffer.pixbytes) { + switch (vidinfo->drawbuffer.pixbytes) { case 2: pfield_do_linetoscr_normal = need_genlock_data ? linetoscr_16_shrink1f_genlock : linetoscr_16_shrink1f; pfield_do_linetoscr_sprite = need_genlock_data ? linetoscr_16_shrink1f_spr_genlock : linetoscr_16_shrink1f_spr; @@ -1980,7 +1996,7 @@ static void pfield_set_linetoscr (void) break; } } else { - switch (gfxvidinfo.drawbuffer.pixbytes) { + switch (vidinfo->drawbuffer.pixbytes) { case 2: pfield_do_linetoscr_normal = need_genlock_data ? linetoscr_16_shrink1_genlock : linetoscr_16_shrink1; pfield_do_linetoscr_sprite = need_genlock_data ? linetoscr_16_shrink1_spr_genlock : linetoscr_16_shrink1_spr; @@ -2404,7 +2420,6 @@ static void pfield_doline (int lineno) int wordcount = dp_for_drawing->plflinelen; uae_u32 *data = pixdata.apixels_l + MAX_PIXELS_PER_LINE / 4; -#ifdef SMART_UPDATE #define DATA_POINTER(n) ((debug_bpl_mask & (1 << n)) ? (line_data[lineno] + (n) * MAX_WORDS_PER_LINE * 2) : (debug_bpl_mask_one ? all_ones : all_zeros)) real_bplpt[0] = DATA_POINTER (0); real_bplpt[1] = DATA_POINTER (1); @@ -2415,7 +2430,6 @@ static void pfield_doline (int lineno) #ifdef AGA real_bplpt[6] = DATA_POINTER (6); real_bplpt[7] = DATA_POINTER (7); -#endif #endif switch (bplplanecnt) { @@ -2454,14 +2468,15 @@ static void pfield_doline (int lineno) } -void init_row_map (void) +void init_row_map(void) { + struct vidbuf_description *vidinfo = &adisplays[0].gfxvidinfo; static uae_u8 *oldbufmem; static int oldheight, oldpitch; static bool oldgenlock; int i, j; - if (gfxvidinfo.drawbuffer.height_allocated > max_uae_height) { + if (vidinfo->drawbuffer.height_allocated > max_uae_height) { write_log (_T("Resolution too high, aborting\n")); abort (); } @@ -2470,42 +2485,43 @@ void init_row_map (void) row_map_genlock = xmalloc(uae_u8*, max_uae_height + 1); } - if (oldbufmem && oldbufmem == gfxvidinfo.drawbuffer.bufmem && - oldheight == gfxvidinfo.drawbuffer.height_allocated && - oldpitch == gfxvidinfo.drawbuffer.rowbytes && + if (oldbufmem && oldbufmem == vidinfo->drawbuffer.bufmem && + oldheight == vidinfo->drawbuffer.height_allocated && + oldpitch == vidinfo->drawbuffer.rowbytes && oldgenlock == init_genlock_data) return; xfree(row_map_genlock_buffer); row_map_genlock_buffer = NULL; if (init_genlock_data) { - row_map_genlock_buffer = xcalloc(uae_u8, gfxvidinfo.drawbuffer.width_allocated * (gfxvidinfo.drawbuffer.height_allocated + 2)); + row_map_genlock_buffer = xcalloc(uae_u8, vidinfo->drawbuffer.width_allocated * (vidinfo->drawbuffer.height_allocated + 2)); } xfree(row_map_color_burst_buffer); row_map_color_burst_buffer = NULL; if (currprefs.cs_color_burst) { - row_map_color_burst_buffer = xcalloc(uae_u8, gfxvidinfo.drawbuffer.height_allocated + 2); + row_map_color_burst_buffer = xcalloc(uae_u8, vidinfo->drawbuffer.height_allocated + 2); } j = oldheight == 0 ? max_uae_height : oldheight; - for (i = gfxvidinfo.drawbuffer.height_allocated; i < max_uae_height + 1 && i < j + 1; i++) { + for (i = vidinfo->drawbuffer.height_allocated; i < max_uae_height + 1 && i < j + 1; i++) { row_map[i] = row_tmp; row_map_genlock[i] = row_tmp; } - for (i = 0, j = 0; i < gfxvidinfo.drawbuffer.height_allocated; i++, j += gfxvidinfo.drawbuffer.rowbytes) { - row_map[i] = gfxvidinfo.drawbuffer.bufmem + j; + for (i = 0, j = 0; i < vidinfo->drawbuffer.height_allocated; i++, j += vidinfo->drawbuffer.rowbytes) { + row_map[i] = vidinfo->drawbuffer.bufmem + j; if (init_genlock_data) { - row_map_genlock[i] = row_map_genlock_buffer + gfxvidinfo.drawbuffer.width_allocated * (i + 1); + row_map_genlock[i] = row_map_genlock_buffer + vidinfo->drawbuffer.width_allocated * (i + 1); } else { row_map_genlock[i] = NULL; } } - oldbufmem = gfxvidinfo.drawbuffer.bufmem; - oldheight = gfxvidinfo.drawbuffer.height_allocated; - oldpitch = gfxvidinfo.drawbuffer.rowbytes; + oldbufmem = vidinfo->drawbuffer.bufmem; + oldheight = vidinfo->drawbuffer.height_allocated; + oldpitch = vidinfo->drawbuffer.rowbytes; oldgenlock = init_genlock_data; } -static void init_aspect_maps (void) +static void init_aspect_maps(void) { + struct vidbuf_description *vidinfo = &adisplays[0].gfxvidinfo; int i, maxl, h; linedbld = linedbl = currprefs.gfx_vresolution; @@ -2517,8 +2533,8 @@ static void init_aspect_maps (void) min_ypos_for_screen = minfirstline << linedbl; max_drawn_amiga_line = -1; - gfxvidinfo.xchange = 1 << (RES_MAX - currprefs.gfx_resolution); - gfxvidinfo.ychange = linedbl ? 1 : 2; + vidinfo->xchange = 1 << (RES_MAX - currprefs.gfx_resolution); + vidinfo->ychange = linedbl ? 1 : 2; visible_left_start = 0; visible_right_stop = MAX_STOP; @@ -2526,7 +2542,7 @@ static void init_aspect_maps (void) visible_bottom_stop = MAX_STOP; set_blanking_limits(); - h = gfxvidinfo.drawbuffer.height_allocated; + h = vidinfo->drawbuffer.height_allocated; if (h == 0) /* Do nothing if the gfx driver hasn't initialized the screen yet */ return; @@ -2563,65 +2579,6 @@ static void init_aspect_maps (void) } } -/* -* A raster line has been built in the graphics buffer. Tell the graphics code -* to do anything necessary to display it. -*/ -static void do_flush_line_1 (struct vidbuffer *vb, int lineno) -{ - if (lineno < first_drawn_line) - first_drawn_line = lineno; - if (lineno > last_drawn_line) - last_drawn_line = lineno; - - if (gfxvidinfo.maxblocklines == 0) { - flush_line (vb, lineno); - } else { - if ((last_block_line + 2) < lineno) { - if (first_block_line != NO_BLOCK) - flush_block (vb, first_block_line, last_block_line); - first_block_line = lineno; - } - last_block_line = lineno; - if (last_block_line - first_block_line >= gfxvidinfo.maxblocklines) { - flush_block (vb, first_block_line, last_block_line); - first_block_line = last_block_line = NO_BLOCK; - } - } -} - -STATIC_INLINE void do_flush_line (struct vidbuffer *vb, int lineno) -{ - if (vb) - do_flush_line_1 (vb, lineno); -} - -/* -* One drawing frame has been finished. Tell the graphics code about it. -* Note that the actual flush_screen() call is a no-op for all reasonable -* systems. -*/ - -static void do_flush_screen (struct vidbuffer *vb, int start, int stop) -{ - /* TODO: this flush operation is executed outside locked state! - Should be corrected. - (sjo 26.9.99) */ - - if (vb != gfxvidinfo.outbuffer) - return; - - xlinecheck (start, stop); - if (gfxvidinfo.maxblocklines != 0 && first_block_line != NO_BLOCK) { - flush_block (vb, first_block_line, last_block_line); - } - unlockscr (vb); - if (start <= stop) - flush_screen (vb, start, stop); - else if (isvsync_chipset ()) - flush_screen (vb, 0, 0); /* vsync mode */ -} - static void setbplmode(void) { if (bplham) @@ -2809,9 +2766,10 @@ static void playfield_hard_way(line_draw_func worker_pfield, int first, int last static void do_color_changes (line_draw_func worker_border, line_draw_func worker_pfield, int vp) { + struct vidbuf_description *vidinfo = &adisplays[0].gfxvidinfo; int i; int lastpos = visible_left_border; - int endpos = visible_left_border + gfxvidinfo.drawbuffer.inwidth; + int endpos = visible_left_border + vidinfo->drawbuffer.inwidth; for (i = dip_for_drawing->first_color_change; i <= dip_for_drawing->last_color_change; i++) { int regno = curr_color_changes[i].regno; @@ -2896,15 +2854,15 @@ static void do_color_changes (line_draw_func worker_border, line_draw_func worke // outside of visible area // Just overwrite with black. Above code needs to run because of custom registers, // not worth the trouble for separate code path just for max 10 lines or so - (*worker_border) (visible_left_border, visible_left_border + gfxvidinfo.drawbuffer.inwidth, true); + (*worker_border) (visible_left_border, visible_left_border + vidinfo->drawbuffer.inwidth, true); } #endif if (hsync_shift_hack > 0) { // hpos shift hack - int shift = (hsync_shift_hack << lores_shift) * gfxvidinfo.drawbuffer.pixbytes; + int shift = (hsync_shift_hack << lores_shift) * vidinfo->drawbuffer.pixbytes; if (shift) { - int firstpos = visible_left_border * gfxvidinfo.drawbuffer.pixbytes; - int lastpos = (visible_left_border + gfxvidinfo.drawbuffer.inwidth) * gfxvidinfo.drawbuffer.pixbytes; + int firstpos = visible_left_border * vidinfo->drawbuffer.pixbytes; + int lastpos = (visible_left_border + vidinfo->drawbuffer.inwidth) * vidinfo->drawbuffer.pixbytes; memmove(xlinebuffer + firstpos, xlinebuffer + firstpos + shift, lastpos - firstpos - shift); memset(xlinebuffer + lastpos - shift, 0, shift); } @@ -2926,6 +2884,7 @@ enum double_how { static void pfield_draw_line (struct vidbuffer *vb, int lineno, int gfx_ypos, int follow_ypos) { + struct vidbuf_description *vidinfo = &adisplays[0].gfxvidinfo; static int warned = 0; int border = 0; int do_double = 0; @@ -2986,10 +2945,10 @@ static void pfield_draw_line (struct vidbuffer *vb, int lineno, int gfx_ypos, in have_color_changes = is_color_changes(dip_for_drawing); dh = dh_line; - xlinebuffer = gfxvidinfo.drawbuffer.linemem; + xlinebuffer = vidinfo->drawbuffer.linemem; if (xlinebuffer == 0 && do_double && (border == 0 || have_color_changes)) - xlinebuffer = gfxvidinfo.drawbuffer.emergmem, dh = dh_emerg; + xlinebuffer = vidinfo->drawbuffer.emergmem, dh = dh_emerg; if (xlinebuffer == 0) xlinebuffer = row_map[gfx_ypos], dh = dh_buf; xlinebuffer -= linetoscr_x_adjust_pixbytes; @@ -3055,17 +3014,15 @@ static void pfield_draw_line (struct vidbuffer *vb, int lineno, int gfx_ypos, in do_color_changes (pfield_do_fill_line, dip_for_drawing->nr_sprites ? pfield_do_linetoscr_spr : pfield_do_linetoscr, lineno); if (dh == dh_emerg) - memcpy (row_map[gfx_ypos], xlinebuffer + linetoscr_x_adjust_pixbytes, gfxvidinfo.drawbuffer.pixbytes * gfxvidinfo.drawbuffer.inwidth); + memcpy (row_map[gfx_ypos], xlinebuffer + linetoscr_x_adjust_pixbytes, vidinfo->drawbuffer.pixbytes * vidinfo->drawbuffer.inwidth); - do_flush_line (vb, gfx_ypos); if (do_double) { if (dh == dh_emerg) - memcpy (row_map[follow_ypos], xlinebuffer + linetoscr_x_adjust_pixbytes, gfxvidinfo.drawbuffer.pixbytes * gfxvidinfo.drawbuffer.inwidth); + memcpy (row_map[follow_ypos], xlinebuffer + linetoscr_x_adjust_pixbytes, vidinfo->drawbuffer.pixbytes * vidinfo->drawbuffer.inwidth); else if (dh == dh_buf) - memcpy (row_map[follow_ypos], row_map[gfx_ypos], gfxvidinfo.drawbuffer.pixbytes * gfxvidinfo.drawbuffer.inwidth); + memcpy (row_map[follow_ypos], row_map[gfx_ypos], vidinfo->drawbuffer.pixbytes * vidinfo->drawbuffer.inwidth); if (need_genlock_data) - memcpy(row_map_genlock[follow_ypos], row_map_genlock[gfx_ypos], gfxvidinfo.drawbuffer.inwidth); - do_flush_line (vb, follow_ypos); + memcpy(row_map_genlock[follow_ypos], row_map_genlock[gfx_ypos], vidinfo->drawbuffer.inwidth); } if (dip_for_drawing->nr_sprites) @@ -3098,7 +3055,6 @@ static void pfield_draw_line (struct vidbuffer *vb, int lineno, int gfx_ypos, in fill_line_border(lineno); } - do_flush_line (vb, gfx_ypos); if (do_double) { if (dh == dh_buf) { xlinebuffer = row_map[follow_ypos] - linetoscr_x_adjust_pixbytes; @@ -3107,7 +3063,6 @@ static void pfield_draw_line (struct vidbuffer *vb, int lineno, int gfx_ypos, in } /* If dh == dh_line, do_flush_line will re-use the rendered line * from linemem. */ - do_flush_line (vb, follow_ypos); } return; } @@ -3131,16 +3086,14 @@ static void pfield_draw_line (struct vidbuffer *vb, int lineno, int gfx_ypos, in } if (dh == dh_emerg) - memcpy (row_map[gfx_ypos], xlinebuffer + linetoscr_x_adjust_pixbytes, gfxvidinfo.drawbuffer.pixbytes * gfxvidinfo.drawbuffer.inwidth); - do_flush_line (vb, gfx_ypos); + memcpy (row_map[gfx_ypos], xlinebuffer + linetoscr_x_adjust_pixbytes, vidinfo->drawbuffer.pixbytes * vidinfo->drawbuffer.inwidth); if (do_double) { if (dh == dh_emerg) - memcpy (row_map[follow_ypos], xlinebuffer + linetoscr_x_adjust_pixbytes, gfxvidinfo.drawbuffer.pixbytes * gfxvidinfo.drawbuffer.inwidth); + memcpy (row_map[follow_ypos], xlinebuffer + linetoscr_x_adjust_pixbytes, vidinfo->drawbuffer.pixbytes * vidinfo->drawbuffer.inwidth); else if (dh == dh_buf) - memcpy (row_map[follow_ypos], row_map[gfx_ypos], gfxvidinfo.drawbuffer.pixbytes * gfxvidinfo.drawbuffer.inwidth); + memcpy (row_map[follow_ypos], row_map[gfx_ypos], vidinfo->drawbuffer.pixbytes * vidinfo->drawbuffer.inwidth); if (need_genlock_data) - memcpy(row_map_genlock[follow_ypos], row_map_genlock[gfx_ypos], gfxvidinfo.drawbuffer.inwidth); - do_flush_line(vb, follow_ypos); + memcpy(row_map_genlock[follow_ypos], row_map_genlock[gfx_ypos], vidinfo->drawbuffer.inwidth); } } else { @@ -3150,17 +3103,18 @@ static void pfield_draw_line (struct vidbuffer *vb, int lineno, int gfx_ypos, in hposblank = 1; fill_line_border(lineno); hposblank = tmp; - do_flush_line(vb, gfx_ypos); } } static void center_image (void) { + struct amigadisplay *ad = &adisplays[0]; + struct vidbuf_description *vidinfo = &ad->gfxvidinfo; int prev_x_adjust = visible_left_border; int prev_y_adjust = thisframe_y_adjust; - int w = gfxvidinfo.drawbuffer.inwidth; + int w = vidinfo->drawbuffer.inwidth; if (currprefs.gfx_xcenter && !currprefs.gf[0].gfx_filter_autoscale && max_diwstop > 0) { if (max_diwstop - min_diwstart < w && currprefs.gfx_xcenter == 2) @@ -3178,15 +3132,15 @@ static void center_image (void) } } #endif - } else if (gfxvidinfo.drawbuffer.extrawidth) { + } else if (vidinfo->drawbuffer.extrawidth) { visible_left_border = max_diwlastword - w; - if (gfxvidinfo.drawbuffer.extrawidth > 0) - visible_left_border += gfxvidinfo.drawbuffer.extrawidth << currprefs.gfx_resolution; + if (vidinfo->drawbuffer.extrawidth > 0) + visible_left_border += vidinfo->drawbuffer.extrawidth << currprefs.gfx_resolution; } else { - if (gfxvidinfo.drawbuffer.inxoffset < 0) { + if (vidinfo->drawbuffer.inxoffset < 0) { visible_left_border = 0; } else { - visible_left_border = gfxvidinfo.drawbuffer.inxoffset - DISPLAY_LEFT_SHIFT; + visible_left_border = vidinfo->drawbuffer.inxoffset - DISPLAY_LEFT_SHIFT; } } @@ -3196,18 +3150,18 @@ static void center_image (void) visible_left_border = 0; visible_left_border &= ~((xshift (1, lores_shift)) - 1); - //write_log (_T("%d %d %d %d %d\n"), max_diwlastword, gfxvidinfo.drawbuffer.width, lores_shift, currprefs.gfx_resolution, visible_left_border); + //write_log (_T("%d %d %d %d %d\n"), max_diwlastword, vidinfo->drawbuffer.width, lores_shift, currprefs.gfx_resolution, visible_left_border); linetoscr_x_adjust_pixels = visible_left_border; - linetoscr_x_adjust_pixbytes = linetoscr_x_adjust_pixels * gfxvidinfo.drawbuffer.pixbytes; + linetoscr_x_adjust_pixbytes = linetoscr_x_adjust_pixels * vidinfo->drawbuffer.pixbytes; visible_right_border = visible_left_border + w; if (visible_right_border > max_diwlastword) visible_right_border = max_diwlastword; int max_drawn_amiga_line_tmp = max_drawn_amiga_line; - if (max_drawn_amiga_line_tmp > gfxvidinfo.drawbuffer.inheight) - max_drawn_amiga_line_tmp = gfxvidinfo.drawbuffer.inheight; + if (max_drawn_amiga_line_tmp > vidinfo->drawbuffer.inheight) + max_drawn_amiga_line_tmp = vidinfo->drawbuffer.inheight; max_drawn_amiga_line_tmp >>= linedbl; thisframe_y_adjust = minfirstline; @@ -3239,15 +3193,15 @@ static void center_image (void) if (prev_x_adjust != visible_left_border || prev_y_adjust != thisframe_y_adjust) { int redraw = interlace_seen > 0 && linedbl ? 2 : 1; - if (redraw > frame_redraw_necessary) - frame_redraw_necessary = redraw; + if (redraw > ad->frame_redraw_necessary) + ad->frame_redraw_necessary = redraw; } max_diwstop = 0; min_diwstart = MAX_STOP; - gfxvidinfo.drawbuffer.xoffset = (DISPLAY_LEFT_SHIFT << RES_MAX) + (visible_left_border << (RES_MAX - currprefs.gfx_resolution)); - gfxvidinfo.drawbuffer.yoffset = thisframe_y_adjust << VRES_MAX; + vidinfo->drawbuffer.xoffset = (DISPLAY_LEFT_SHIFT << RES_MAX) + (visible_left_border << (RES_MAX - currprefs.gfx_resolution)); + vidinfo->drawbuffer.yoffset = thisframe_y_adjust << VRES_MAX; center_reset = false; horizontal_changed = false; @@ -3258,6 +3212,8 @@ static int frame_res_cnt; static int autoswitch_old_resolution; static void init_drawing_frame (void) { + struct amigadisplay *ad = &adisplays[0]; + struct vidbuf_description *vidinfo = &ad->gfxvidinfo; int i, maxline; static int frame_res_old; @@ -3278,11 +3234,11 @@ static void init_drawing_frame (void) if (currprefs.gfx_resolution == changed_prefs.gfx_resolution && lines_count > 0) { - if (currprefs.gfx_autoresolution_vga && programmedmode && gfxvidinfo.gfx_resolution_reserved >= RES_HIRES && gfxvidinfo.gfx_vresolution_reserved >= VRES_DOUBLE) { - if (largest_res == RES_SUPERHIRES && (gfxvidinfo.gfx_resolution_reserved < RES_SUPERHIRES || gfxvidinfo.gfx_vresolution_reserved < 1)) { + if (currprefs.gfx_autoresolution_vga && programmedmode && vidinfo->gfx_resolution_reserved >= RES_HIRES && vidinfo->gfx_vresolution_reserved >= VRES_DOUBLE) { + if (largest_res == RES_SUPERHIRES && (vidinfo->gfx_resolution_reserved < RES_SUPERHIRES || vidinfo->gfx_vresolution_reserved < 1)) { // enable full doubling/superhires support if programmed mode. It may be "half-width" only and may fit in normal display window. - gfxvidinfo.gfx_resolution_reserved = RES_SUPERHIRES; - gfxvidinfo.gfx_vresolution_reserved = VRES_DOUBLE; + vidinfo->gfx_resolution_reserved = RES_SUPERHIRES; + vidinfo->gfx_vresolution_reserved = VRES_DOUBLE; graphics_reset(false); } int newres = largest_res; @@ -3334,9 +3290,9 @@ static void init_drawing_frame (void) frame_res_cnt--; if (frame_res_cnt == 0) { int m = frame_res_detected * 2 + frame_res_lace_detected; - struct wh *dst = currprefs.gfx_apmode[0].gfx_fullscreen ? &changed_prefs.gfx_size_fs : &changed_prefs.gfx_size_win; + struct wh *dst = currprefs.gfx_apmode[0].gfx_fullscreen ? &changed_prefs.gfx_monitor[0].gfx_size_fs : &changed_prefs.gfx_monitor[0].gfx_size_win; while (m < 3 * 2) { - struct wh *src = currprefs.gfx_apmode[0].gfx_fullscreen ? &currprefs.gfx_size_fs_xtra[m] : &currprefs.gfx_size_win_xtra[m]; + struct wh *src = currprefs.gfx_apmode[0].gfx_fullscreen ? &currprefs.gfx_monitor[0].gfx_size_fs_xtra[m] : &currprefs.gfx_monitor[0].gfx_size_win_xtra[m]; if ((src->width > 0 && src->height > 0) || (currprefs.gfx_api || currprefs.gf[0].gfx_filter > 0)) { int nr = m >> 1; int nl = (m & 1) == 0 ? 0 : 1; @@ -3360,10 +3316,10 @@ static void init_drawing_frame (void) nl = currprefs.gfx_autoresolution_minv; } - if (nr > gfxvidinfo.gfx_resolution_reserved) - nr = gfxvidinfo.gfx_resolution_reserved; - if (nl > gfxvidinfo.gfx_vresolution_reserved) - nl = gfxvidinfo.gfx_vresolution_reserved; + if (nr > vidinfo->gfx_resolution_reserved) + nr = vidinfo->gfx_resolution_reserved; + if (nl > vidinfo->gfx_vresolution_reserved) + nl = vidinfo->gfx_vresolution_reserved; if (changed_prefs.gfx_resolution != nr || changed_prefs.gfx_vresolution != nl) { changed_prefs.gfx_resolution = nr; @@ -3371,7 +3327,7 @@ static void init_drawing_frame (void) write_log (_T("RES -> %d (%d) LINE -> %d (%d) (%d - %d, %d - %d)\n"), nr, nr_o, nl, nl_o, currprefs.gfx_autoresolution_minh, currprefs.gfx_autoresolution_minv, - gfxvidinfo.gfx_resolution_reserved, gfxvidinfo.gfx_vresolution_reserved); + vidinfo->gfx_resolution_reserved, vidinfo->gfx_vresolution_reserved); set_config_changed (); } if (src->width > 0 && src->height > 0) { @@ -3417,7 +3373,6 @@ static void init_drawing_frame (void) thisframe_last_drawn_line = thisframe_first_drawn_line; maxline = ((maxvpos_display + 1) << linedbl) + 2; -#ifdef SMART_UPDATE for (i = 0; i < maxline; i++) { int ls = linestate[i]; switch (ls) { @@ -3431,19 +3386,16 @@ static void init_drawing_frame (void) break; } } -#else - memset (linestate, LINE_UNDECIDED, maxline); -#endif last_drawn_line = 0; first_drawn_line = 32767; first_block_line = last_block_line = NO_BLOCK; - if (frame_redraw_necessary) { + if (ad->frame_redraw_necessary) { reset_decision_table(); - custom_frame_redraw_necessary = 1; - frame_redraw_necessary--; + ad->custom_frame_redraw_necessary = 1; + ad->frame_redraw_necessary--; } else { - custom_frame_redraw_necessary = 0; + ad->custom_frame_redraw_necessary = 0; } center_image (); @@ -3499,36 +3451,39 @@ void putpixel(uae_u8 *buf, uae_u8 *genlockbuf, int bpp, int x, xcolnr c8, int op } } -static uae_u8 *status_line_ptr(int line) +static uae_u8 *status_line_ptr(int monid, int line) { + struct vidbuf_description *vidinfo = &adisplays[monid].gfxvidinfo; int y; - y = line - (gfxvidinfo.drawbuffer.outheight - TD_TOTAL_HEIGHT); - xlinebuffer = gfxvidinfo.drawbuffer.linemem; + y = line - (vidinfo->drawbuffer.outheight - TD_TOTAL_HEIGHT); + xlinebuffer = vidinfo->drawbuffer.linemem; if (xlinebuffer == 0) xlinebuffer = row_map[line]; xlinebuffer_genlock = row_map_genlock[line]; return xlinebuffer; } -static void draw_status_line (int line, int statusy) +static void draw_status_line(int monid, int line, int statusy) { - uae_u8 *buf = status_line_ptr(line); + struct vidbuf_description *vidinfo = &adisplays[monid].gfxvidinfo; + uae_u8 *buf = status_line_ptr(monid, line); if (!buf) return; if (statusy < 0) - statusline_render(buf, gfxvidinfo.drawbuffer.pixbytes, gfxvidinfo.drawbuffer.rowbytes, gfxvidinfo.drawbuffer.outwidth, TD_TOTAL_HEIGHT, xredcolors, xgreencolors, xbluecolors, NULL); + statusline_render(monid, buf, vidinfo->drawbuffer.pixbytes, vidinfo->drawbuffer.rowbytes, vidinfo->drawbuffer.outwidth, TD_TOTAL_HEIGHT, xredcolors, xgreencolors, xbluecolors, NULL); else - draw_status_line_single(buf, gfxvidinfo.drawbuffer.pixbytes, statusy, gfxvidinfo.drawbuffer.outwidth, xredcolors, xgreencolors, xbluecolors, NULL); + draw_status_line_single(monid, buf, vidinfo->drawbuffer.pixbytes, statusy, vidinfo->drawbuffer.outwidth, xredcolors, xgreencolors, xbluecolors, NULL); } -static void draw_debug_status_line (int line) +static void draw_debug_status_line(int monid, int line) { - xlinebuffer = gfxvidinfo.drawbuffer.linemem; + struct vidbuf_description *vidinfo = &adisplays[monid].gfxvidinfo; + xlinebuffer = vidinfo->drawbuffer.linemem; if (xlinebuffer == 0) xlinebuffer = row_map[line]; xlinebuffer_genlock = row_map_genlock[line]; - debug_draw(xlinebuffer, gfxvidinfo.drawbuffer.pixbytes, line, gfxvidinfo.drawbuffer.outwidth, gfxvidinfo.drawbuffer.outheight, xredcolors, xgreencolors, xbluecolors); + debug_draw(xlinebuffer, vidinfo->drawbuffer.pixbytes, line, vidinfo->drawbuffer.outwidth, vidinfo->drawbuffer.outheight, xredcolors, xgreencolors, xbluecolors); } #define LIGHTPEN_HEIGHT 12 @@ -3549,13 +3504,14 @@ static const char *lightpen_cursor = { "------.....------" }; -static void draw_lightpen_cursor (int x, int y, int line, int onscreen, int lpnum) +static void draw_lightpen_cursor(int monid, int x, int y, int line, int onscreen, int lpnum) { + struct vidbuf_description *vidinfo = &adisplays[monid].gfxvidinfo; const char *p; int color1 = onscreen ? (lpnum ? 0x0ff : 0xff0) : (lpnum ? 0x0f0 : 0xf00); int color2 = 0x000; - xlinebuffer = gfxvidinfo.drawbuffer.linemem; + xlinebuffer = vidinfo->drawbuffer.linemem; if (xlinebuffer == 0) xlinebuffer = row_map[line]; xlinebuffer_genlock = row_map_genlock[line]; @@ -3563,26 +3519,27 @@ static void draw_lightpen_cursor (int x, int y, int line, int onscreen, int lpnu p = lightpen_cursor + y * LIGHTPEN_WIDTH; for (int i = 0; i < LIGHTPEN_WIDTH; i++) { int xx = x + i - LIGHTPEN_WIDTH / 2; - if (*p != '-' && xx >= 0 && xx < gfxvidinfo.drawbuffer.outwidth) { - putpixel (xlinebuffer, xlinebuffer_genlock, gfxvidinfo.drawbuffer.pixbytes, xx, *p == 'x' ? xcolors[color1] : xcolors[color2], 1); + if (*p != '-' && xx >= 0 && xx < vidinfo->drawbuffer.outwidth) { + putpixel (xlinebuffer, xlinebuffer_genlock, vidinfo->drawbuffer.pixbytes, xx, *p == 'x' ? xcolors[color1] : xcolors[color2], 1); } p++; } } -static void lightpen_update (struct vidbuffer *vb, int lpnum) +static void lightpen_update(struct vidbuffer *vb, int lpnum) { + struct vidbuf_description *vidinfo = &adisplays[vb->monitor_id].gfxvidinfo; if (lightpen_x[lpnum] < 0 || lightpen_y[lpnum] < 0) return; if (lightpen_x[lpnum] < LIGHTPEN_WIDTH + 1) lightpen_x[lpnum] = LIGHTPEN_WIDTH + 1; - if (lightpen_x[lpnum] >= gfxvidinfo.drawbuffer.inwidth - LIGHTPEN_WIDTH - 1) - lightpen_x[lpnum] = gfxvidinfo.drawbuffer.inwidth - LIGHTPEN_WIDTH - 2; + if (lightpen_x[lpnum] >= vidinfo->drawbuffer.inwidth - LIGHTPEN_WIDTH - 1) + lightpen_x[lpnum] = vidinfo->drawbuffer.inwidth - LIGHTPEN_WIDTH - 2; if (lightpen_y[lpnum] < LIGHTPEN_HEIGHT + 1) lightpen_y[lpnum] = LIGHTPEN_HEIGHT + 1; - if (lightpen_y[lpnum] >= gfxvidinfo.drawbuffer.inheight - LIGHTPEN_HEIGHT - 1) - lightpen_y[lpnum] = gfxvidinfo.drawbuffer.inheight - LIGHTPEN_HEIGHT - 2; + if (lightpen_y[lpnum] >= vidinfo->drawbuffer.inheight - LIGHTPEN_HEIGHT - 1) + lightpen_y[lpnum] = vidinfo->drawbuffer.inheight - LIGHTPEN_HEIGHT - 2; if (lightpen_y[lpnum] >= max_ypos_thisframe - LIGHTPEN_HEIGHT - 1) lightpen_y[lpnum] = max_ypos_thisframe - LIGHTPEN_HEIGHT - 2; @@ -3608,8 +3565,7 @@ static void lightpen_update (struct vidbuffer *vb, int lpnum) int line = lightpen_y[lpnum] + i - LIGHTPEN_HEIGHT / 2; if (line >= 0 || line < max_ypos_thisframe) { if (lightpen_active > 0 && currprefs.lightpen_crosshair) { - draw_lightpen_cursor (lightpen_x[lpnum], i, line, cx > 0, lpnum); - flush_line (vb, line); + draw_lightpen_cursor(vb->monitor_id, lightpen_x[lpnum], i, line, cx > 0, lpnum); } } } @@ -3646,6 +3602,7 @@ static const int refresh_indicator_colors[] = { 0x777, 0x0f0, 0x00f, 0xff0, 0xf0 static void refresh_indicator_update(struct vidbuffer *vb) { + struct vidbuf_description *vidinfo = &adisplays[vb->monitor_id].gfxvidinfo; for (int i = 0; i < max_ypos_thisframe; i++) { int i1 = i + min_ypos_for_screen; int line = i + thisframe_y_adjust_real; @@ -3673,29 +3630,23 @@ static void refresh_indicator_update(struct vidbuffer *vb) color2 = refresh_indicator_colors[pixel - 5]; } for (int x = 0; x < 8; x++) { - putpixel(xlinebuffer, NULL, gfxvidinfo.drawbuffer.pixbytes, x, xcolors[color1], 1); + putpixel(xlinebuffer, NULL, vidinfo->drawbuffer.pixbytes, x, xcolors[color1], 1); } for (int x = 8; x < 16; x++) { - putpixel(xlinebuffer, NULL, gfxvidinfo.drawbuffer.pixbytes, x, xcolors[color2], 1); + putpixel(xlinebuffer, NULL, vidinfo->drawbuffer.pixbytes, x, xcolors[color2], 1); } } } -struct vidbuffer *xvbin, *xvbout; - #define LARGEST_LINE_DEBUG 0 -static void draw_frame2 (struct vidbuffer *vbin, struct vidbuffer *vbout) +static void draw_frame2(struct vidbuffer *vbin, struct vidbuffer *vbout) { - int i; - - xvbin = vbin; - xvbout = vbout; - #if LARGEST_LINE_DEBUG int largest = 0; #endif - for (i = 0; i < max_ypos_thisframe; i++) { + + for (int i = 0; i < max_ypos_thisframe; i++) { int i1 = i + min_ypos_for_screen; int line = i + thisframe_y_adjust_real; int whereline = amiga2aspect_line_map[i1]; @@ -3720,13 +3671,92 @@ static void draw_frame2 (struct vidbuffer *vbin, struct vidbuffer *vbout) #endif } +static void draw_frame_extras(struct vidbuffer *vb, int y_start, int y_end) +{ + if (currprefs.leds_on_screen && ((currprefs.leds_on_screen & STATUSLINE_CHIPSET) && !(currprefs.leds_on_screen & STATUSLINE_TARGET))) { + int slx, sly; + statusline_getpos(vb->monitor_id, &slx, &sly, vb->outwidth, vb->outheight, 1, 1); + statusbar_y1 = sly + min_ypos_for_screen - 1; + statusbar_y2 = statusbar_y1 + TD_TOTAL_HEIGHT + 1; + draw_status_line(vb->monitor_id, sly, -1); + for (int i = 0; i < TD_TOTAL_HEIGHT; i++) { + int line = sly + i; + draw_status_line(vb->monitor_id, line, i); + } + } + if (debug_dma > 1 || debug_heatmap > 1) { + for (int i = 0; i < vb->outheight; i++) { + int line = i; + draw_debug_status_line(vb->monitor_id, line); + } + } + + if (lightpen_active) { + lightpen_update(vb, 0); + if (inputdevice_get_lightpen_id() >= 0) + lightpen_update(vb, 1); + } + if (refresh_indicator_buffer) + refresh_indicator_update(vb); +} + +void draw_lines(int end, int section) +{ + int monid = 0; + struct vidbuf_description *vidinfo = &adisplays[monid].gfxvidinfo; + struct vidbuffer *vb = &vidinfo->drawbuffer; + int y_start = -1; + int y_end = -1; + + end -= minfirstline; + if (end < 0) + return; + end <<= linedbl; + + vidinfo->outbuffer = vb; + if (!lockscr(vb, false, vb->last_drawn_line ? false : true)) + return; + while (vb->last_drawn_line < end) { + int i = vb->last_drawn_line; + int i1 = i + min_ypos_for_screen; + int line = i + thisframe_y_adjust_real; + int whereline = amiga2aspect_line_map[i1]; + int wherenext = amiga2aspect_line_map[i1 + 1]; + if (whereline >= vb->inheight) + break; + if (whereline < 0) + continue; + if (y_start < 0) + y_start = whereline; + hposblank = 0; + pfield_draw_line(vb, line, whereline, wherenext); + +#if 0 + static const int section_colors[] = { 0x777, 0xf00, 0x0f0, 0x00f }; + int color = section_colors[section & 3]; + xlinebuffer = row_map[whereline]; + for (int x = 0; x < 4; x++) { + putpixel(xlinebuffer, NULL, vidinfo->drawbuffer.pixbytes, x, xcolors[color], 1); + } +#endif + + vb->last_drawn_line++; + if (vb->last_drawn_line == end) { + y_end = whereline; + } + } + draw_frame_extras(vb, y_start, y_end + 1); + unlockscr(vb, y_start, y_end + 1); +} + bool draw_frame (struct vidbuffer *vb) { + struct vidbuf_description *vidinfo = &adisplays[vb->monitor_id].gfxvidinfo; uae_u8 oldstate[LINESTATE_SIZE]; struct vidbuffer oldvb; - memcpy (&oldvb, &gfxvidinfo.drawbuffer, sizeof (struct vidbuffer)); - memcpy (&gfxvidinfo.drawbuffer, vb, sizeof (struct vidbuffer)); + memcpy (&oldvb, &vidinfo->drawbuffer, sizeof (struct vidbuffer)); + memcpy (&vidinfo->drawbuffer, vb, sizeof (struct vidbuffer)); clearbuffer (vb); init_row_map (); memcpy (oldstate, linestate, LINESTATE_SIZE); @@ -3755,205 +3785,179 @@ bool draw_frame (struct vidbuffer *vb) first_drawn_line = 32767; drawing_color_matches = -1; memcpy (linestate, oldstate, LINESTATE_SIZE); - memcpy (&gfxvidinfo.drawbuffer, &oldvb, sizeof (struct vidbuffer)); + memcpy (&vidinfo->drawbuffer, &oldvb, sizeof (struct vidbuffer)); init_row_map (); return true; } static void setnativeposition(struct vidbuffer *vb) { - vb->inwidth = gfxvidinfo.drawbuffer.inwidth; - vb->inheight = gfxvidinfo.drawbuffer.inheight; - vb->inwidth2 = gfxvidinfo.drawbuffer.inwidth2; - vb->inheight2 = gfxvidinfo.drawbuffer.inheight2; - vb->outwidth = gfxvidinfo.drawbuffer.outwidth; - vb->outheight = gfxvidinfo.drawbuffer.outheight; + struct vidbuf_description *vidinfo = &adisplays[0].gfxvidinfo; + vb->inwidth = vidinfo->drawbuffer.inwidth; + vb->inheight = vidinfo->drawbuffer.inheight; + vb->inwidth2 = vidinfo->drawbuffer.inwidth2; + vb->inheight2 = vidinfo->drawbuffer.inheight2; + vb->outwidth = vidinfo->drawbuffer.outwidth; + vb->outheight = vidinfo->drawbuffer.outheight; } static void setspecialmonitorpos(struct vidbuffer *vb) { - vb->extrawidth = gfxvidinfo.drawbuffer.extrawidth; - vb->xoffset = gfxvidinfo.drawbuffer.xoffset; - vb->yoffset = gfxvidinfo.drawbuffer.yoffset; - vb->inxoffset = gfxvidinfo.drawbuffer.inxoffset; - vb->inyoffset = gfxvidinfo.drawbuffer.inyoffset; + struct vidbuf_description *vidinfo = &adisplays[0].gfxvidinfo; + vb->extrawidth = vidinfo->drawbuffer.extrawidth; + vb->xoffset = vidinfo->drawbuffer.xoffset; + vb->yoffset = vidinfo->drawbuffer.yoffset; + vb->inxoffset = vidinfo->drawbuffer.inxoffset; + vb->inyoffset = vidinfo->drawbuffer.inyoffset; } -static void finish_drawing_frame (void) +static void finish_drawing_frame(bool drawlines) { - int i; - bool didflush = false; - struct vidbuffer *vb = &gfxvidinfo.drawbuffer; + int monid = 0; + struct amigadisplay *ad = &adisplays[monid]; + struct vidbuf_description *vidinfo = &ad->gfxvidinfo; + struct vidbuffer *vb = &vidinfo->drawbuffer; - gfxvidinfo.outbuffer = vb; + vidinfo->outbuffer = vb; + vb->last_drawn_line = 0; - if (! lockscr (vb, false)) { - notice_screen_contents_lost (); + if (!drawlines) { return; } -#ifndef SMART_UPDATE - /* @@@ This isn't exactly right yet. FIXME */ - if (!interlace_seen) - do_flush_screen (first_drawn_line, last_drawn_line); - else - unlockscr (); - return; -#endif - - draw_frame2 (vb, vb); - - if (currprefs.leds_on_screen && ((currprefs.leds_on_screen & STATUSLINE_CHIPSET) && !(currprefs.leds_on_screen & STATUSLINE_TARGET))) { - int slx, sly; - statusline_getpos(&slx, &sly, vb->outwidth, vb->outheight, 1, 1); - statusbar_y1 = sly + min_ypos_for_screen - 1; - statusbar_y2 = statusbar_y1 + TD_TOTAL_HEIGHT + 1; - draw_status_line(sly, -1); - for (i = 0; i < TD_TOTAL_HEIGHT; i++) { - int line = sly + i; - draw_status_line (line, i); - do_flush_line (vb, line); - } - } - if (debug_dma > 1 || debug_heatmap > 1) { - for (i = 0; i < vb->outheight; i++) { - int line = i; - draw_debug_status_line (line); - do_flush_line (vb, line); - } + if (!lockscr(vb, false, true)) { + notice_screen_contents_lost(monid); + return; } - if (lightpen_active) { - lightpen_update (vb, 0); - if (inputdevice_get_lightpen_id() >= 0) - lightpen_update (vb, 1); - } - if (refresh_indicator_buffer) - refresh_indicator_update(vb); + draw_frame2(vb, vb); + + draw_frame_extras(vb, -1, -1); - if (currprefs.monitoremu && gfxvidinfo.tempbuffer.bufmem_allocated) { - setspecialmonitorpos(&gfxvidinfo.tempbuffer); + if (currprefs.monitoremu) { + struct vidbuf_description *outvi = &adisplays[currprefs.monitoremu_mon].gfxvidinfo; + struct vidbuffer *out = &outvi->drawbuffer; if (init_genlock_data != specialmonitor_need_genlock()) { init_genlock_data = specialmonitor_need_genlock(); init_row_map(); } - if (emulate_specialmonitors (vb, &gfxvidinfo.tempbuffer)) { - vb = gfxvidinfo.outbuffer = &gfxvidinfo.tempbuffer; - if (vb->nativepositioning) - setnativeposition(vb); - gfxvidinfo.drawbuffer.tempbufferinuse = true; - need_genlock_data = specialmonitor_need_genlock(); - if (!specialmonitoron) { + bool locked = true; + bool multimon = currprefs.monitoremu_mon != 0; + if (multimon) { + locked = lockscr(out, false, true); + outvi->xchange = vidinfo->xchange; + outvi->ychange = vidinfo->ychange; + } else { + out = &vidinfo->tempbuffer; + } + setspecialmonitorpos(out); + if (locked && emulate_specialmonitors(vb, out)) { + if (!multimon) { + vb = vidinfo->outbuffer = out; + } + if (out->nativepositioning) + setnativeposition(out); + out->tempbufferinuse = true; + if (!ad->specialmonitoron) { + ad->specialmonitoron = true; compute_framesync(); + pfield_set_linetoscr(); } - specialmonitoron = true; - pfield_set_linetoscr(); - do_flush_screen (vb, 0, vb->outheight); - didflush = true; } else { pfield_set_linetoscr(); need_genlock_data = false; - if (specialmonitoron || gfxvidinfo.drawbuffer.tempbufferinuse) { - gfxvidinfo.drawbuffer.tempbufferinuse = false; - specialmonitoron = false; + if (ad->specialmonitoron || out->tempbufferinuse) { + out->tempbufferinuse = false; + ad->specialmonitoron = false; compute_framesync(); } } + if (multimon && locked) { + unlockscr(out, -1, -1); + render_screen(out->monitor_id, 0, true); + show_screen(out->monitor_id, 0); + } } - if (!currprefs.monitoremu && gfxvidinfo.tempbuffer.bufmem_allocated && ((!bplcolorburst_field && currprefs.cs_color_burst) || (currprefs.gfx_grayscale))) { - setspecialmonitorpos(&gfxvidinfo.tempbuffer); - emulate_grayscale(vb, &gfxvidinfo.tempbuffer); - vb = gfxvidinfo.outbuffer = &gfxvidinfo.tempbuffer; + if (!currprefs.monitoremu && vidinfo->tempbuffer.bufmem_allocated && ((!bplcolorburst_field && currprefs.cs_color_burst) || (currprefs.gfx_grayscale))) { + setspecialmonitorpos(&vidinfo->tempbuffer); + emulate_grayscale(vb, &vidinfo->tempbuffer); + vb = vidinfo->outbuffer = &vidinfo->tempbuffer; if (vb->nativepositioning) setnativeposition(vb); - gfxvidinfo.drawbuffer.tempbufferinuse = true; - do_flush_screen(vb, 0, vb->outheight); - didflush = true; + vidinfo->drawbuffer.tempbufferinuse = true; } - if (currprefs.genlock_image && !currprefs.monitoremu && !currprefs.cs_color_burst && gfxvidinfo.tempbuffer.bufmem_allocated && currprefs.genlock) { - setspecialmonitorpos(&gfxvidinfo.tempbuffer); + if (currprefs.genlock_image && !currprefs.monitoremu && !currprefs.cs_color_burst && vidinfo->tempbuffer.bufmem_allocated && currprefs.genlock) { + setspecialmonitorpos(&vidinfo->tempbuffer); if (init_genlock_data != specialmonitor_need_genlock()) { need_genlock_data = init_genlock_data = specialmonitor_need_genlock(); init_row_map(); } - emulate_genlock(vb, &gfxvidinfo.tempbuffer); - vb = gfxvidinfo.outbuffer = &gfxvidinfo.tempbuffer; + emulate_genlock(vb, &vidinfo->tempbuffer); + vb = vidinfo->outbuffer = &vidinfo->tempbuffer; if (vb->nativepositioning) setnativeposition(vb); - gfxvidinfo.drawbuffer.tempbufferinuse = true; - do_flush_screen(vb, 0, vb->outheight); - didflush = true; + vidinfo->drawbuffer.tempbufferinuse = true; } - if (!currprefs.monitoremu && gfxvidinfo.tempbuffer.bufmem_allocated && currprefs.cs_cd32fmv) { + if (!currprefs.monitoremu && vidinfo->tempbuffer.bufmem_allocated && currprefs.cs_cd32fmv) { if (cd32_fmv_active) { - cd32_fmv_genlock(vb, &gfxvidinfo.tempbuffer); - vb = gfxvidinfo.outbuffer = &gfxvidinfo.tempbuffer; + cd32_fmv_genlock(vb, &vidinfo->tempbuffer); + vb = vidinfo->outbuffer = &vidinfo->tempbuffer; setnativeposition(vb); - gfxvidinfo.drawbuffer.tempbufferinuse = true; - do_flush_screen(vb, 0, vb->outheight); - didflush = true; + vidinfo->drawbuffer.tempbufferinuse = true; } else { - gfxvidinfo.drawbuffer.tempbufferinuse = false; + vidinfo->drawbuffer.tempbufferinuse = false; } } - if (!didflush) - do_flush_screen (vb, first_drawn_line, last_drawn_line); -} - -void hardware_line_completed (int lineno) -{ -#ifndef SMART_UPDATE - { - int i, where; - /* l is the line that has been finished for drawing. */ - i = lineno - thisframe_y_adjust_real; - if (i >= 0 && i < max_ypos_thisframe) { - where = amiga2aspect_line_map[i+min_ypos_for_screen]; - if (where < gfxvidinfo.drawbuffer.outheight && where >= 0) - pfield_draw_line (lineno, where, amiga2aspect_line_map[i+min_ypos_for_screen+1]); - } - } -#endif + unlockscr(vb, -1, -1); } void check_prefs_picasso(void) { #ifdef PICASSO96 - if (picasso_on && picasso_redraw_necessary) - picasso_refresh (); - picasso_redraw_necessary = 0; + for (int monid = 0; monid < MAX_AMIGAMONITORS; monid++) { + struct amigadisplay *ad = &adisplays[monid]; - if (picasso_requested_on == picasso_on && !picasso_requested_forced_on) - return; + if (ad->picasso_on && ad->picasso_redraw_necessary) + picasso_refresh(monid); + ad->picasso_redraw_necessary = 0; - if (picasso_requested_on) { - if (!toggle_rtg(-2)) { - picasso_requested_forced_on = false; - picasso_on = false; - picasso_requested_on = false; - return; + if (ad->picasso_requested_on == ad->picasso_on && !ad->picasso_requested_forced_on) + continue; + + if (!ad->picasso_requested_on && monid > 0) { + ad->picasso_requested_on = ad->picasso_on; + continue; } - } - picasso_requested_forced_on = false; - picasso_on = picasso_requested_on; + if (ad->picasso_requested_on) { + if (!toggle_rtg(monid, -2)) { + ad->picasso_requested_forced_on = false; + ad->picasso_on = false; + ad->picasso_requested_on = false; + continue; + } + } - if (!picasso_on) - clear_inhibit_frame (IHF_PICASSO); - else - set_inhibit_frame (IHF_PICASSO); + ad->picasso_requested_forced_on = false; + ad->picasso_on = ad->picasso_requested_on; - gfx_set_picasso_state (picasso_on); - picasso_enablescreen (picasso_requested_on); + if (!ad->picasso_on) + clear_inhibit_frame(monid, IHF_PICASSO); + else + set_inhibit_frame(monid, IHF_PICASSO); + + gfx_set_picasso_state(monid, ad->picasso_on); + picasso_enablescreen(monid, ad->picasso_requested_on); - notice_screen_contents_lost (); - notice_new_xcolors (); - count_frame (); - compute_framesync(); + notice_screen_contents_lost(monid); + notice_new_xcolors(); + count_frame(monid); + compute_framesync(); + } #endif } @@ -3961,40 +3965,46 @@ void redraw_frame (void) { last_drawn_line = 0; first_drawn_line = 32767; - finish_drawing_frame (); - flush_screen (gfxvidinfo.inbuffer, 0, 0); + finish_drawing_frame(true); + //flush_screen (vidinfo->inbuffer, 0, 0); } bool vsync_handle_check (void) { + int monid = 0; + struct amigadisplay *ad = &adisplays[monid]; int changed = check_prefs_changed_gfx (); if (changed > 0) { reset_drawing (); init_row_map (); init_aspect_maps (); - notice_screen_contents_lost (); + notice_screen_contents_lost(monid); notice_new_xcolors (); } else if (changed < 0) { reset_drawing (); init_row_map (); init_aspect_maps (); - notice_screen_contents_lost (); + notice_screen_contents_lost(monid); notice_new_xcolors (); } - device_check_config(); + if (config_changed) { + device_check_config(); + } return changed != 0; } -void vsync_handle_redraw (int long_field, int lof_changed, uae_u16 bplcon0p, uae_u16 bplcon3p) +void vsync_handle_redraw(int long_field, int lof_changed, uae_u16 bplcon0p, uae_u16 bplcon3p, bool drawlines) { + int monid = 0; + struct amigadisplay *ad = &adisplays[monid]; last_redraw_point++; if (lof_changed || interlace_seen <= 0 || (currprefs.gfx_iscanlines && interlace_seen > 0) || last_redraw_point >= 2 || long_field || doublescan < 0) { last_redraw_point = 0; - if (framecnt == 0) { - finish_drawing_frame(); + if (ad->framecnt == 0) { + finish_drawing_frame(drawlines); #ifdef AVIOUTPUT - if (!picasso_on) { + if (!ad->picasso_on) { frame_drawn(); } #endif @@ -4020,22 +4030,24 @@ void vsync_handle_redraw (int long_field, int lof_changed, uae_u16 bplcon0p, uae } #endif quit_program = -quit_program; - set_inhibit_frame(IHF_QUIT_PROGRAM); + set_inhibit_frame(monid, IHF_QUIT_PROGRAM); set_special(SPCFLAG_BRK | SPCFLAG_MODE_CHANGE); return; } - count_frame(); + count_frame(monid); - if (framecnt == 0) { + if (ad->framecnt == 0) { init_drawing_frame(); } else if (currprefs.cpu_memory_cycle_exact) { init_hardware_for_drawing_frame(); } } else { +#if 0 if (isvsync_chipset()) { - flush_screen(gfxvidinfo.inbuffer, 0, 0); /* vsync mode */ + flush_screen(vidinfo->inbuffer, 0, 0); /* vsync mode */ } +#endif } gui_flicker_led (-1, 0, 0); @@ -4043,13 +4055,14 @@ void vsync_handle_redraw (int long_field, int lof_changed, uae_u16 bplcon0p, uae void hsync_record_line_state (int lineno, enum nln_how how, int changed) { + struct amigadisplay *ad = &adisplays[0]; uae_u8 *state; - if (framecnt != 0) + if (ad->framecnt != 0) return; state = linestate + lineno; - changed |= frame_redraw_necessary != 0 || refresh_indicator_buffer != NULL || + changed |= ad->frame_redraw_necessary != 0 || refresh_indicator_buffer != NULL || ((lineno >= lightpen_y1[0] && lineno < lightpen_y2[0]) || (lineno >= lightpen_y1[1] && lineno < lightpen_y2[1]) || (lineno >= statusbar_y1 && lineno < statusbar_y2)); @@ -4142,14 +4155,15 @@ static void dummy_unlock (struct vidbuf_description *gfxinfo, struct vidbuffer * { } -static void gfxbuffer_reset (void) +static void gfxbuffer_reset(int monid) { - gfxvidinfo.drawbuffer.flush_line = dummy_flush_line; - gfxvidinfo.drawbuffer.flush_block = dummy_flush_block; - gfxvidinfo.drawbuffer.flush_screen = dummy_flush_screen; - gfxvidinfo.drawbuffer.flush_clear_screen = dummy_flush_clear_screen; - gfxvidinfo.drawbuffer.lockscr = dummy_lock; - gfxvidinfo.drawbuffer.unlockscr = dummy_unlock; + struct vidbuf_description *vidinfo = &adisplays[monid].gfxvidinfo; + vidinfo->drawbuffer.flush_line = dummy_flush_line; + vidinfo->drawbuffer.flush_block = dummy_flush_block; + vidinfo->drawbuffer.flush_screen = dummy_flush_screen; + vidinfo->drawbuffer.flush_clear_screen = dummy_flush_clear_screen; + vidinfo->drawbuffer.lockscr = dummy_lock; + vidinfo->drawbuffer.unlockscr = dummy_unlock; } void notice_resolution_seen (int res, bool lace) @@ -4182,9 +4196,10 @@ bool notice_interlace_seen (bool lace) return changed; } -void allocvidbuffer (struct vidbuffer *buf, int width, int height, int depth) +void allocvidbuffer(int monid, struct vidbuffer *buf, int width, int height, int depth) { memset (buf, 0, sizeof (struct vidbuffer)); + buf->monitor_id = monid; buf->pixbytes = (depth + 7) / 8; buf->width_allocated = (width + 7) & ~7; buf->height_allocated = height; @@ -4202,7 +4217,7 @@ void allocvidbuffer (struct vidbuffer *buf, int width, int height, int depth) buf->bufmem_lockable = true; } -void freevidbuffer (struct vidbuffer *buf) +void freevidbuffer(int monid, struct vidbuffer *buf) { xfree (buf->realbufmem); memset (buf, 0, sizeof (struct vidbuffer)); @@ -4210,6 +4225,10 @@ void freevidbuffer (struct vidbuffer *buf) void reset_drawing (void) { + int monid = 0; + struct amigadisplay *ad = &adisplays[monid]; + struct vidbuf_description *vidinfo = &ad->gfxvidinfo; + max_diwstop = 0; lores_reset (); @@ -4225,7 +4244,7 @@ void reset_drawing (void) memset (spixels, 0, sizeof spixels); memset (&spixstate, 0, sizeof spixstate); - notice_screen_contents_lost(); + notice_screen_contents_lost(monid); init_drawing_frame (); pfield_set_linetoscr(); @@ -4235,11 +4254,11 @@ void reset_drawing (void) reset_custom_limits (); - clearbuffer (&gfxvidinfo.drawbuffer); - clearbuffer (&gfxvidinfo.tempbuffer); + clearbuffer (&vidinfo->drawbuffer); + clearbuffer (&vidinfo->tempbuffer); center_reset = true; - specialmonitoron = false; + ad->specialmonitoron = false; bplcolorburst_field = 1; hsync_shift_hack = 0; } @@ -4257,6 +4276,10 @@ static void gen_direct_drawing_table(void) void drawing_init (void) { + int monid = 0; + struct amigadisplay *ad = &adisplays[monid]; + struct vidbuf_description *vidinfo = &ad->gfxvidinfo; + refresh_indicator_init(); gen_pfield_tables(); @@ -4266,23 +4289,24 @@ void drawing_init (void) uae_sem_init (&gui_sem, 0, 1); #ifdef PICASSO96 if (!isrestore ()) { - picasso_on = 0; - picasso_requested_on = 0; - gfx_set_picasso_state (0); + ad->picasso_on = 0; + ad->picasso_requested_on = 0; + gfx_set_picasso_state(0, 0); } #endif - xlinebuffer = gfxvidinfo.drawbuffer.bufmem; + xlinebuffer = vidinfo->drawbuffer.bufmem; xlinebuffer_genlock = NULL; - inhibit_frame = 0; + ad->inhibit_frame = 0; - gfxbuffer_reset (); + gfxbuffer_reset(0); reset_drawing (); } -int isvsync_chipset (void) +int isvsync_chipset(void) { - if (picasso_on || currprefs.gfx_apmode[0].gfx_vsync <= 0) + struct amigadisplay *ad = &adisplays[0]; + if (ad->picasso_on || currprefs.gfx_apmode[0].gfx_vsync <= 0) return 0; if (currprefs.gfx_apmode[0].gfx_vsyncmode == 0) return 1; @@ -4291,9 +4315,10 @@ int isvsync_chipset (void) return currprefs.cachesize ? -3 : -2; } -int isvsync_rtg (void) +int isvsync_rtg(void) { - if (!picasso_on || currprefs.gfx_apmode[1].gfx_vsync <= 0) + struct amigadisplay *ad = &adisplays[0]; + if (!ad->picasso_on || currprefs.gfx_apmode[1].gfx_vsync <= 0) return 0; if (currprefs.gfx_apmode[1].gfx_vsyncmode == 0) return 1; @@ -4302,9 +4327,10 @@ int isvsync_rtg (void) return currprefs.cachesize ? -3 : -2; } -int isvsync (void) +int isvsync(void) { - if (picasso_on) + struct amigadisplay *ad = &adisplays[0]; + if (ad->picasso_on) return isvsync_rtg (); else return isvsync_chipset (); diff --git a/events.cpp b/events.cpp index 4abf9d1f..0c70d0a1 100644 --- a/events.cpp +++ b/events.cpp @@ -16,7 +16,9 @@ #include "memory.h" #include "newcpu.h" #include "uae/ppc.h" +#include "xwin.h" #include "x86.h" +#include "audio.h" static const int pissoff_nojit_value = 256 * CYCLE_UNIT; @@ -47,6 +49,9 @@ void events_schedule (void) nextevent = currcycle + mintime; } +extern void vsync_event_done(void); +extern int vsync_activeheight; + void do_cycles_slow (unsigned long cycles_to_add) { #ifdef WITH_X86 @@ -62,60 +67,106 @@ void do_cycles_slow (unsigned long cycles_to_add) pissoff = 0; while ((nextevent - currcycle) <= cycles_to_add) { - int i; /* Keep only CPU emulation running while waiting for sync point. */ - if (is_syncline) { - if (!vblank_found_chipset) { - if (is_syncline > 0) { - int rpt = read_processor_time (); - int v = rpt - vsyncmintime; - int v2 = rpt - is_syncline_end; - if (v > vsynctimebase || v < -vsynctimebase) { - v = 0; + if (is_syncline == -1) { + audio_finish_pull(); + // wait for vblank + int done = vsync_isdone(NULL); + if (!done) { +#ifdef WITH_PPC + if (ppc_state) { + if (is_syncline == 1) { + uae_ppc_execute_check(); + } else { + uae_ppc_execute_quick(); } - if (v < 0 && v2 < 0 && event_wait) { + } +#endif + if (currprefs.cachesize) + pissoff = pissoff_value; + else + pissoff = pissoff_nojit_value; + return; + } + vsync_clear(); + vsync_event_done(); + } else if (is_syncline > 0) { + + audio_finish_pull(); + // wait for specific scanline + int vp = target_get_display_scanline(-1); + if (vp < 0 || is_syncline > vp) { #ifdef WITH_PPC - if (ppc_state) { - if (is_syncline == 1) { - uae_ppc_execute_check(); - } else { - uae_ppc_execute_quick(); - } - } + if (ppc_state) { + uae_ppc_execute_check(); + } #endif - if (currprefs.cachesize) - pissoff = pissoff_value; - else - pissoff = pissoff_nojit_value; - return; + if (currprefs.cachesize) + pissoff = pissoff_value; + else + pissoff = pissoff_nojit_value; + return; + } + vsync_event_done(); + + } else if (is_syncline == -10) { + + // wait is_syncline_end + if (event_wait) { + int rpt = read_processor_time(); + int v = rpt - is_syncline_end; + if (v < 0) { +#ifdef WITH_PPC + if (ppc_state) { + uae_ppc_execute_check(); } - } else if (is_syncline < 0) { - int rpt = read_processor_time (); - int v = rpt - is_syncline_end; - if (v < 0 && event_wait) { +#endif + if (currprefs.cachesize) + pissoff = pissoff_value; + else + pissoff = pissoff_nojit_value; + return; + } + } + is_syncline = 0; + + } else if (is_syncline < -10) { + // wait is_syncline_end/vsyncmintime + if (event_wait) { + int rpt = read_processor_time(); + int v = rpt - vsyncmintime; + int v2 = rpt - is_syncline_end; + if (v > vsynctimebase || v < -vsynctimebase) { + v = 0; + } + if (v < 0 && v2 < 0) { #ifdef WITH_PPC - if (ppc_state) { + if (ppc_state) { + if (is_syncline == -11) { uae_ppc_execute_check(); + } else { + uae_ppc_execute_quick(); } -#endif - if (currprefs.cachesize) - pissoff = pissoff_value; - else - pissoff = pissoff_nojit_value; - return; } +#endif + if (currprefs.cachesize) + pissoff = pissoff_value; + else + pissoff = pissoff_nojit_value; + return; } } is_syncline = 0; + } cycles_to_add -= nextevent - currcycle; currcycle = nextevent; - for (i = 0; i < ev_max; i++) { + for (int i = 0; i < ev_max; i++) { if (eventtab[i].active && eventtab[i].evtime == currcycle) { if (eventtab[i].handler == NULL) { gui_message(_T("eventtab[%d].handler is null!\n"), i); diff --git a/framebufferboards.cpp b/framebufferboards.cpp index d272a052..2c73de06 100644 --- a/framebufferboards.cpp +++ b/framebufferboards.cpp @@ -19,6 +19,7 @@ #include "statusline.h" #include "rommgr.h" #include "framebufferboards.h" +#include "xwin.h" typedef uae_u32(REGPARAM3 *fb_get_func)(struct fb_struct *, uaecptr) REGPARAM; typedef void (REGPARAM3 *fb_put_func)(struct fb_struct *, uaecptr, uae_u32) REGPARAM; @@ -28,6 +29,7 @@ extern addrbank generic_fb_bank; struct fb_struct { int devnum; + int monitor_id; uae_u32 configured; uae_u32 io_start, io_end; uae_u8 data[16]; @@ -64,15 +66,16 @@ static struct fb_struct *fb_last; static bool fb_get_surface(struct fb_struct *data) { + struct amigadisplay *ad = &adisplays[data->monitor_id]; bool gotsurf = false; - if (picasso_on) { + if (ad->picasso_on) { if (data->surface == NULL) { - data->surface = gfx_lock_picasso(false, false); + data->surface = gfx_lock_picasso(data->monitor_id, false, false); gotsurf = true; } if (data->surface && gotsurf) { if (!(currprefs.leds_on_screen & STATUSLINE_TARGET)) - picasso_statusline(data->surface); + picasso_statusline(data->monitor_id, data->surface); } } return data->surface != NULL; @@ -81,7 +84,7 @@ static void fb_free_surface(struct fb_struct *data) { if (!data->surface) return; - gfx_unlock_picasso(true); + gfx_unlock_picasso(data->monitor_id, true); data->surface = NULL; } @@ -299,6 +302,7 @@ static void harlequin_hsync(void *userdata) static void harlequin_convert(struct fb_struct *data) { + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[data->monitor_id]; bool r = (data->data[1] & 0x80) != 0; bool g = (data->data[1] & 0x40) != 0; bool b = (data->data[1] & 0x20) != 0; @@ -310,12 +314,12 @@ static void harlequin_convert(struct fb_struct *data) offset += data->fb_vram_size / 2; int sy = 0; - int w = picasso_vidinfo.width < data->width ? picasso_vidinfo.width : data->width; - int h = picasso_vidinfo.height < data->height ? picasso_vidinfo.height : data->height; + int w = vidinfo->width < data->width ? vidinfo->width : data->width; + int h = vidinfo->height < data->height ? vidinfo->height : data->height; for (int y = 0; y < h; y++) { uae_u8 *s = data->fb + offset + laceoffset + sy * data->width * 4; if (r && g && b) { - fb_copyrow(s, data->surface, 0, 0, data->width, 4, y); + fb_copyrow(data->monitor_id, s, data->surface, 0, 0, data->width, 4, y); } else { uae_u8 tmp[1000 * 4]; uae_u8 *d = tmp; @@ -325,7 +329,7 @@ static void harlequin_convert(struct fb_struct *data) d[x + 2] = b ? s[x + 2] : 0; d[x + 3] = 0; } - fb_copyrow(d, data->surface, 0, 0, data->width, 4, y); + fb_copyrow(data->monitor_id, d, data->surface, 0, 0, data->width, 4, y); } if (data->lace) { laceoffset = laceoffset ? 0 : laceoffsetv; diff --git a/gfxboard.cpp b/gfxboard.cpp index 9e227155..a94c3a17 100644 --- a/gfxboard.cpp +++ b/gfxboard.cpp @@ -41,6 +41,7 @@ static bool memlogw = true; #include "zfile.h" #include "gfxboard.h" #include "rommgr.h" +#include "xwin.h" #include "qemuvga/qemuuaeglue.h" #include "qemuvga/vga.h" @@ -198,6 +199,7 @@ struct rtggfxboard { bool active; int rtg_index; + int monitor_id; struct rtgboardconfig *rbc; TCHAR memorybankname[40]; TCHAR memorybanknamenojit[40]; @@ -226,6 +228,7 @@ struct rtggfxboard int vram_start_offset; uae_u32 gfxboardmem_start; bool monswitch_current, monswitch_new; + bool monswitch_keep_trying; bool monswitch_reset; int monswitch_delay; int fullrefresh; @@ -266,7 +269,8 @@ struct rtggfxboard static struct rtggfxboard rtggfxboards[MAX_RTG_BOARDS]; static struct rtggfxboard *only_gfx_board; -static int rtg_visible = -1; +static int rtg_visible[MAX_AMIGADISPLAYS]; +static int rtg_initial[MAX_AMIGADISPLAYS]; static int total_active_gfx_boards; static int vram_ram_a8; static DisplaySurface fakesurface; @@ -475,24 +479,30 @@ static int GetBytesPerPixel(RGBFTYPE RGBfmt) static bool gfxboard_setmode(struct rtggfxboard *gb, struct gfxboard_mode *mode) { - picasso96_state.Width = mode->width; - picasso96_state.Height = mode->height; + struct amigadisplay *ad = &adisplays[gb->monitor_id]; + struct picasso96_state_struct *state = &picasso96_state[gb->monitor_id]; + + state->Width = mode->width; + state->Height = mode->height; int bpp = GetBytesPerPixel(mode->mode); - picasso96_state.BytesPerPixel = bpp; - picasso96_state.RGBFormat = mode->mode; + state->BytesPerPixel = bpp; + state->RGBFormat = mode->mode; write_log(_T("GFXBOARD %dx%dx%d\n"), mode->width, mode->height, bpp); - if (!picasso_requested_on && !picasso_on) - picasso_requested_on = true; - //gfx_set_picasso_modeinfo(width, height, bpp, RGBFB_NONE); + if (!ad->picasso_requested_on && !ad->picasso_on) { + ad->picasso_requested_on = true; + set_config_changed(); + } return true; } static void gfxboard_free_slot2(struct rtggfxboard *gb) { + struct amigadisplay *ad = &adisplays[gb->monitor_id]; gb->active = false; - if (rtg_visible == gb->rtg_index) { - rtg_visible = -1; - picasso_requested_on = false; + if (rtg_visible[gb->monitor_id] == gb->rtg_index) { + rtg_visible[gb->monitor_id] = -1; + ad->picasso_requested_on = false; + set_config_changed(); } gb->userdata = NULL; gb->func = NULL; @@ -576,6 +586,7 @@ bool gfxboard_init_board(struct autoconfig_info *aci) const struct gfxboard *gfxb = &boards[aci->prefs->rtgboards[aci->devnum].rtgmem_type - GFXBOARD_HARDWARE]; struct rtggfxboard *gb = &rtggfxboards[aci->devnum]; gb->func = gfxb->func; + gb->monitor_id = aci->prefs->rtgboards[aci->devnum].monitor_id; memset(aci->autoconfig_bytes, 0xff, sizeof aci->autoconfig_bytes); if (!gb->automemory) gb->automemory = xmalloc(uae_u8, GFXBOARD_AUTOCONFIG_SIZE); @@ -636,65 +647,66 @@ static bool gfxboard_setmode_qemu(struct rtggfxboard *gb) } } gfxboard_setmode(gb, &mode); - gfx_set_picasso_modeinfo(mode.mode); + gfx_set_picasso_modeinfo(gb->monitor_id, mode.mode); gb->fullrefresh = 2; gb->vga_changed = false; return true; } -static int rtg_initial; - -void gfxboard_rtg_disable(int index) +void gfxboard_rtg_disable(int monid, int index) { - if (index == rtg_visible && rtg_visible >= 0) { + if (monid > 0) + return; + if (index == rtg_visible[monid] && rtg_visible[monid] >= 0) { struct rtggfxboard *gb = &rtggfxboards[index]; - if (rtg_visible >= 0 && gb->func) { + if (rtg_visible[monid] >= 0 && gb->func) { gb->func->toggle(gb->userdata, 0); } - rtg_visible = -1; + rtg_visible[monid] = -1; } } -bool gfxboard_rtg_enable_initial(int index) +bool gfxboard_rtg_enable_initial(int monid, int index) { - // if some RTG already enabled, don't override - if (rtg_visible >= 0 || rtg_initial >= 0) + struct amigadisplay *ad = &adisplays[monid]; + // if some RTG already enabled and located in monitor 0, don't override + if ((rtg_visible[monid] >= 0 || rtg_initial[monid] >= 0) && !monid) return false; - if (picasso_on) + if (ad->picasso_on) return false; - rtg_initial = index; - gfxboard_toggle(index, false); + rtg_initial[monid] = index; + gfxboard_toggle(monid, index, false); // check_prefs_picasso() calls gfxboard_toggle when ready return true; } -int gfxboard_toggle (int index, int log) +int gfxboard_toggle(int monid, int index, int log) { bool initial = false; - if (rtg_visible < 0 && rtg_initial >= 0 && rtg_initial < MAX_RTG_BOARDS) { - index = rtg_initial; + if (rtg_visible[monid] < 0 && rtg_initial[monid] >= 0 && rtg_initial[monid] < MAX_RTG_BOARDS) { + index = rtg_initial[monid]; initial = true; } - gfxboard_rtg_disable(rtg_visible); + gfxboard_rtg_disable(monid, rtg_visible[monid]); - rtg_visible = -1; + rtg_visible[monid] = -1; - struct rtggfxboard *gb = &rtggfxboards[index]; - if (!gb->active) + if (index < 0) goto end; - if (index < 0) + struct rtggfxboard *gb = &rtggfxboards[index]; + if (!gb->active) goto end; if (gb->func) { bool r = gb->func->toggle(gb->userdata, 1); if (r) { - rtg_initial = MAX_RTG_BOARDS; - rtg_visible = gb->rtg_index; - if (log) + rtg_initial[monid] = MAX_RTG_BOARDS; + rtg_visible[monid] = gb->rtg_index; + if (log && !monid) statusline_add_message(STATUSTYPE_DISPLAY, _T("RTG %d: %s"), index + 1, gb->board->name); return index; } @@ -707,32 +719,33 @@ int gfxboard_toggle (int index, int log) if (gb->vga_width > 16 && gb->vga_height > 16) { if (!gfxboard_setmode_qemu(gb)) goto end; - rtg_initial = MAX_RTG_BOARDS; - rtg_visible = gb->rtg_index; + rtg_initial[monid] = MAX_RTG_BOARDS; + rtg_visible[monid] = gb->rtg_index; gb->monswitch_new = true; gb->monswitch_delay = 1; - if (log) + if (log && !monid) statusline_add_message(STATUSTYPE_DISPLAY, _T("RTG %d: %s"), index + 1, gb->board->name); return index; } end: if (initial) { - rtg_initial = -1; + rtg_initial[monid] = -1; return -2; } return -1; } -static bool gfxboard_checkchanged (struct rtggfxboard *gb) +static bool gfxboard_checkchanged(struct rtggfxboard *gb) { + struct picasso96_state_struct *state = &picasso96_state[gb->monitor_id]; int bpp = gb->vga.vga.get_bpp (&gb->vga.vga); if (bpp == 0) bpp = 8; if (gb->vga_width <= 16 || gb->vga_height <= 16) return false; - if (picasso96_state.Width != gb->vga_width || - picasso96_state.Height != gb->vga_height || - picasso96_state.BytesPerPixel != bpp / 8) + if (state->Width != gb->vga_width || + state->Height != gb->vga_height || + state->BytesPerPixel != bpp / 8) return true; return false; } @@ -790,54 +803,66 @@ DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp, int surface_bits_per_pixel(DisplaySurface *s) { - if (rtg_visible < 0) - return 32; struct rtggfxboard *gb = (struct rtggfxboard*)s->data; + if (rtg_visible[gb->monitor_id] < 0) + return 32; if (s == &gb->fakesurface) return 32; - return picasso_vidinfo.pixbytes * 8; + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[gb->monitor_id]; + return vidinfo->pixbytes * 8; } int surface_bytes_per_pixel(DisplaySurface *s) { - if (rtg_visible < 0) - return 4; struct rtggfxboard *gb = (struct rtggfxboard*)s->data; + if (rtg_visible[gb->monitor_id] < 0) + return 4; if (s == &gb->fakesurface) return 4; - return picasso_vidinfo.pixbytes; + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[gb->monitor_id]; + return vidinfo->pixbytes; } int surface_stride(DisplaySurface *s) { - if (rtg_visible < 0) - return 0; struct rtggfxboard *gb = (struct rtggfxboard*)s->data; + if (rtg_visible[gb->monitor_id] < 0) + return 0; if (s == &gb->fakesurface || !gb->vga_refresh_active) return 0; if (gb->gfxboard_surface == NULL) - gb->gfxboard_surface = gfx_lock_picasso (false, false); - return picasso_vidinfo.rowbytes; + gb->gfxboard_surface = gfx_lock_picasso(gb->monitor_id, false, false); + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[gb->monitor_id]; + return vidinfo->rowbytes; } uint8_t *surface_data(DisplaySurface *s) { - if (rtg_visible < 0) - return NULL; struct rtggfxboard *gb = (struct rtggfxboard*)s->data; if (!gb) return NULL; + if (rtg_visible[gb->monitor_id] < 0) + return NULL; if (gb->vga_changed) return NULL; if (s == &gb->fakesurface || !gb->vga_refresh_active) return gb->fakesurface_surface; if (gb->gfxboard_surface == NULL) - gb->gfxboard_surface = gfx_lock_picasso (false, false); + gb->gfxboard_surface = gfx_lock_picasso(gb->monitor_id, false, false); return gb->gfxboard_surface; } -void gfxboard_refresh (void) +void gfxboard_refresh(int monid) { - if (rtg_visible >= 0) { - rtggfxboards[rtg_visible].fullrefresh = 2; + if (monid > 0) { + for (int i = 0; i < MAX_RTG_BOARDS; i++) { + struct rtggfxboard *gb = &rtggfxboards[i]; + if (gb->monitor_id == monid) { + gb->fullrefresh = 2; + } + } + } else { + if (rtg_visible[monid] >= 0) { + rtggfxboards[rtg_visible[monid]].fullrefresh = 2; + } } } @@ -851,27 +876,29 @@ void gfxboard_hsync_handler(void) } } -bool gfxboard_vsync_handler (bool redraw_required) +bool gfxboard_vsync_handler(bool full_redraw_required, bool redraw_required) { bool flushed = false; for (int i = 0; i < MAX_RTG_BOARDS; i++) { struct rtggfxboard *gb = &rtggfxboards[i]; + struct amigadisplay *ad = &adisplays[gb->monitor_id]; + struct picasso96_state_struct *state = &picasso96_state[gb->monitor_id]; if (gb->func) { if (gb->userdata) { struct gfxboard_mode mode = { 0 }; - mode.redraw_required = redraw_required; + mode.redraw_required = full_redraw_required; flushed = gb->func->vsync(gb->userdata, &mode); if (mode.mode && mode.width && mode.height) { - if (picasso96_state.Width != mode.width || - picasso96_state.Height != mode.height || - picasso96_state.RGBFormat != mode.mode || - !picasso_on) { + if (state->Width != mode.width || + state->Height != mode.height || + state->RGBFormat != mode.mode || + !ad->picasso_on) { if (mode.width && mode.height && mode.mode) { gfxboard_setmode(gb, &mode); - gfx_set_picasso_modeinfo(mode.mode); + gfx_set_picasso_modeinfo(gb->monitor_id, mode.mode); } } } @@ -879,25 +906,42 @@ bool gfxboard_vsync_handler (bool redraw_required) } else if (gb->configured_mem > 0 && gb->configured_regs > 0) { + if (gb->monswitch_keep_trying) { + vga_update_size(gb); + if (gb->vga_width > 16 || gb->vga_height > 16) { + gb->monswitch_keep_trying = false; + gb->monswitch_new = true; + gb->monswitch_delay = 0; + } + } + if (gb->monswitch_new != gb->monswitch_current) { if (gb->monswitch_delay > 0) gb->monswitch_delay--; if (gb->monswitch_delay == 0) { - if (!gb->monswitch_new && rtg_visible == i) { - gfxboard_rtg_disable(i); + if (!gb->monswitch_new && rtg_visible[gb->monitor_id] == i) { + gfxboard_rtg_disable(gb->monitor_id, i); } gb->monswitch_current = gb->monswitch_new; vga_update_size(gb); - write_log(_T("GFXBOARD %d ACTIVE=%d\n"), i, gb->monswitch_current); - if (gb->monswitch_current) { - if (!gfxboard_rtg_enable_initial(i)) { - // Nothing visible? Re-enable our display. - if (rtg_visible < 0) { - gfxboard_toggle(i, 0); + write_log(_T("GFXBOARD %d MONITOR=%d ACTIVE=%d\n"), i, gb->monitor_id, gb->monswitch_current); + if (gb->monitor_id > 0) { + if (gb->monswitch_new) + gfxboard_toggle(gb->monitor_id, i, 0); + } else { + if (gb->monswitch_current) { + if (!gfxboard_rtg_enable_initial(gb->monitor_id, i)) { + // Nothing visible? Re-enable our display. + if (rtg_visible[gb->monitor_id] < 0) { + gfxboard_toggle(gb->monitor_id, i, 0); + } + } + } else { + if (ad->picasso_requested_on) { + ad->picasso_requested_on = false; + set_config_changed(); } } - } else { - picasso_requested_on = false; } } } else { @@ -918,51 +962,65 @@ bool gfxboard_vsync_handler (bool redraw_required) } } - if (rtg_visible < 0) - return flushed; - - struct rtggfxboard *gb = &rtggfxboards[rtg_visible]; + for (int i = 0; i < MAX_RTG_BOARDS; i++) { + struct rtggfxboard *gb = &rtggfxboards[i]; + struct amigadisplay *ad = &adisplays[gb->monitor_id]; + struct picasso96_state_struct *state = &picasso96_state[gb->monitor_id]; + + if (gb->monitor_id == 0) { + // if default monitor: show rtg_visible + if (rtg_visible[gb->monitor_id] < 0) + continue; + if (i != rtg_visible[gb->monitor_id]) + continue; + } - if (gb->configured_mem <= 0 || gb->configured_regs <= 0) - return flushed; + if (gb->configured_mem <= 0 || gb->configured_regs <= 0) + continue; - if (gb->monswitch_current && (gb->modechanged || gfxboard_checkchanged(gb))) { - gb->modechanged = false; - if (!gfxboard_setmode_qemu(gb)) { - gfxboard_rtg_disable(rtg_visible); - return false; + if (gb->monswitch_current && (gb->modechanged || gfxboard_checkchanged(gb))) { + gb->modechanged = false; + if (!gfxboard_setmode_qemu(gb)) { + gfxboard_rtg_disable(gb->monitor_id, i); + continue; + } + continue; } - return flushed; - } - if (!gb->monswitch_delay && gb->monswitch_current && picasso_on && picasso_requested_on && !gb->vga_changed) { - picasso_getwritewatch (rtg_visible, gb->vram_start_offset); - if (gb->fullrefresh) - gb->vga.vga.graphic_mode = -1; - gb->vga_refresh_active = true; - gb->vga.vga.hw_ops->gfx_update(&gb->vga); - gb->vga_refresh_active = false; - } + if (!redraw_required) + continue; - if (picasso_on && !gb->vga_changed) { - if (currprefs.leds_on_screen & STATUSLINE_RTG) { - if (gb->gfxboard_surface == NULL) { - gb->gfxboard_surface = gfx_lock_picasso (false, false); - } - if (gb->gfxboard_surface) { - if (!(currprefs.leds_on_screen & STATUSLINE_TARGET)) - picasso_statusline (gb->gfxboard_surface); + if (!gb->monswitch_delay && gb->monswitch_current && ad->picasso_on && ad->picasso_requested_on && !gb->vga_changed) { + picasso_getwritewatch(i, gb->vram_start_offset); + if (gb->fullrefresh) + gb->vga.vga.graphic_mode = -1; + gb->vga_refresh_active = true; + gb->vga.vga.hw_ops->gfx_update(&gb->vga); + gb->vga_refresh_active = false; + } + + if (ad->picasso_on && !gb->vga_changed) { + if (!gb->monitor_id) { + if (currprefs.leds_on_screen & STATUSLINE_RTG) { + if (gb->gfxboard_surface == NULL) { + gb->gfxboard_surface = gfx_lock_picasso(gb->monitor_id, false, false); + } + if (gb->gfxboard_surface) { + if (!(currprefs.leds_on_screen & STATUSLINE_TARGET)) + picasso_statusline(gb->monitor_id, gb->gfxboard_surface); + } + } } + if (gb->fullrefresh > 0) + gb->fullrefresh--; } - if (gb->fullrefresh > 0) - gb->fullrefresh--; - } - if (gb->gfxboard_surface) { - flushed = true; - gfx_unlock_picasso (true); + if (gb->gfxboard_surface) { + flushed = true; + gfx_unlock_picasso(gb->monitor_id, true); + } + gb->gfxboard_surface = NULL; } - gb->gfxboard_surface = NULL; return flushed; } @@ -974,7 +1032,7 @@ double gfxboard_get_vsync (void) void dpy_gfx_update(QemuConsole *con, int x, int y, int w, int h) { - picasso_invalidate (x, y, w, h); + picasso_invalidate(0, x, y, w, h); } void memory_region_init_alias(MemoryRegion *mr, @@ -2237,7 +2295,6 @@ void gfxboard_free(void) void gfxboard_reset (void) { - rtg_initial = -1; for (int i = 0; i < MAX_RTG_BOARDS; i++) { struct rtggfxboard *gb = &rtggfxboards[i]; gb->rbc = &currprefs.rtgboards[gb->rtg_index]; @@ -2258,8 +2315,14 @@ void gfxboard_reset (void) reset_func (reset_parm); } } + if (gb->monitor_id > 0) { + close_rtg(gb->monitor_id); + } + } + for (int i = 0; i < MAX_AMIGADISPLAYS; i++) { + rtg_visible[i] = -1; + rtg_initial[i] = -1; } - rtg_visible = -1; } static uae_u32 REGPARAM2 gfxboards_lget_regs (uaecptr addr) @@ -2601,7 +2664,7 @@ const TCHAR *gfxboard_get_name(int type) if (type == GFXBOARD_UAE_Z2) return _T("UAE Zorro II"); if (type == GFXBOARD_UAE_Z3) - return _T("UAE Zorro III (*)"); + return _T("UAE Zorro III"); return boards[type - GFXBOARD_HARDWARE].name; } @@ -2726,6 +2789,7 @@ static void gfxboard_init (struct autoconfig_info *aci, struct rtggfxboard *gb) memset (gb->automemory, 0xff, GFXBOARD_AUTOCONFIG_SIZE); struct rtgboardconfig *rbc = &p->rtgboards[gb->rtg_index]; gb->rbc = rbc; + gb->monitor_id = rbc->monitor_id; if (!aci->doinit) return; gb->gfxmem_bank = gfxmem_banks[gb->rtg_index]; @@ -2856,6 +2920,9 @@ bool gfxboard_init_memory (struct autoconfig_info *aci) aci->addrbank = &gb->gfxboard_bank_memory; if (gb->rbc->rtgmem_type == GFXBOARD_VGA) { aci->zorro = -1; + if (gb->monitor_id > 0) { + gb->monswitch_keep_trying = true; + } } aci->parent = aci; if (!aci->doinit) { diff --git a/gfxutil.cpp b/gfxutil.cpp index 5a7910e3..4c3f0361 100644 --- a/gfxutil.cpp +++ b/gfxutil.cpp @@ -16,9 +16,10 @@ #include -double getvsyncrate (double hz, int *mult) +float getvsyncrate(int monid, float hz, int *mult) { - struct apmode *ap = picasso_on ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0]; + struct amigadisplay *ad = &adisplays[monid]; + struct apmode *ap = ad->picasso_on ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0]; if (hz < 0) return 0; @@ -134,8 +135,9 @@ static float video_gamma (float value, float gamma, float bri, float con) static uae_u32 gamma[256 * 3][3]; static int lf, hf; -static void video_calc_gammatable (void) +static void video_calc_gammatable(int monid) { + struct amigadisplay *ad = &adisplays[monid]; float bri, con, gam, gams[3]; bri = ((float)(currprefs.gfx_luminance)) * (128.0f / 1000.0f); @@ -145,7 +147,7 @@ static void video_calc_gammatable (void) gams[1] = gam + ((float)(1000 - currprefs.gfx_gamma_ch[1])) / 1000.0f; gams[2] = gam + ((float)(1000 - currprefs.gfx_gamma_ch[2])) / 1000.0f; - lf = 64 * currprefs.gf[picasso_on].gfx_filter_blur / 1000; + lf = 64 * currprefs.gf[ad->picasso_on].gfx_filter_blur / 1000; hf = 256 - lf * 2; for (int i = 0; i < (256 * 3); i++) { @@ -178,43 +180,45 @@ static void video_calc_gammatable (void) } } -static uae_u32 limit256 (double v) +static uae_u32 limit256(int monid, double v) { - v = v * (double)(currprefs.gf[picasso_on].gfx_filter_contrast + 1000) / 1000.0 + currprefs.gf[picasso_on].gfx_filter_luminance / 10.0; + struct amigadisplay *ad = &adisplays[monid]; + v = v * (double)(currprefs.gf[ad->picasso_on].gfx_filter_contrast + 1000) / 1000.0 + currprefs.gf[ad->picasso_on].gfx_filter_luminance / 10.0; if (v < 0) v = 0; if (v > 255) v = 255; return ((uae_u32)v) & 0xff; } -static uae_u32 limit256rb (double v) +static uae_u32 limit256rb(int monid, double v) { - v *= (double)(currprefs.gf[picasso_on].gfx_filter_saturation + 1000) / 1000.0; + struct amigadisplay *ad = &adisplays[monid]; + v *= (double)(currprefs.gf[ad->picasso_on].gfx_filter_saturation + 1000) / 1000.0; if (v < -128) v = -128; if (v > 127) v = 127; return ((uae_u32)v) & 0xff; } -static double get_y (int r, int g, int b) +static double get_y(int r, int g, int b) { return 0.2989f * r + 0.5866f * g + 0.1145f * b; } -static uae_u32 get_yh (int r, int g, int b) +static uae_u32 get_yh(int monid, int r, int g, int b) { - return limit256 (get_y (r, g, b) * hf / 256); + return limit256(monid, get_y (r, g, b) * hf / 256); } -static uae_u32 get_yl (int r, int g, int b) +static uae_u32 get_yl(int monid, int r, int g, int b) { - return limit256 (get_y (r, g, b) * lf / 256); + return limit256(monid, get_y (r, g, b) * lf / 256); } -static uae_u32 get_cb (int r, int g, int b) +static uae_u32 get_cb(int monid, int r, int g, int b) { - return limit256rb (-0.168736f * r - 0.331264f * g + 0.5f * b); + return limit256rb(monid, -0.168736f * r - 0.331264f * g + 0.5f * b); } -static uae_u32 get_cr (int r, int g, int b) +static uae_u32 get_cr(int monid, int r, int g, int b) { - return limit256rb (0.5f * r - 0.418688f * g - 0.081312f * b); + return limit256rb(monid, 0.5f * r - 0.418688f * g - 0.081312f * b); } extern uae_s32 tyhrgb[65536]; @@ -362,12 +366,12 @@ void alloc_colors_rgb (int rw, int gw, int bw, int rs, int gs, int bs, int aw, i } } -void alloc_colors64k (int rw, int gw, int bw, int rs, int gs, int bs, int aw, int as, int alpha, int byte_swap) +void alloc_colors64k(int monid, int rw, int gw, int bw, int rs, int gs, int bs, int aw, int as, int alpha, int byte_swap, bool yuv) { int bpp = rw + gw + bw + aw; int i, j; - video_calc_gammatable (); + video_calc_gammatable(monid); j = 256; for (i = 0; i < 4096; i++) { int r = ((i >> 8) << 4) | (i >> 8); @@ -405,7 +409,7 @@ void alloc_colors64k (int rw, int gw, int bw, int rs, int gs, int bs, int aw, in bluc[2 * 256 + i] = xbluecolors[255]; } #ifdef GFXFILTER - if (usedfilter && usedfilter->yuv) { + if (yuv) { /* create internal 5:6:5 color tables */ for (i = 0; i < 256; i++) { j = i + 256; @@ -450,10 +454,10 @@ void alloc_colors64k (int rw, int gw, int bw, int rs, int gs, int bs, int aw, in g = gamma[g + 256][1]; b = (((i >> 0) & 31) << 3) | lowbits (i, 0, 3); b = gamma[b + 256][2]; - tyhrgb[i] = get_yh (r, g, b) * 256 * 256; - tylrgb[i] = get_yl (r, g, b) * 256 * 256; - tcbrgb[i] = ((uae_s8)get_cb (r, g, b)) * 256; - tcrrgb[i] = ((uae_s8)get_cr (r, g, b)) * 256; + tyhrgb[i] = get_yh(monid, r, g, b) * 256 * 256; + tylrgb[i] = get_yl(monid, r, g, b) * 256 * 256; + tcbrgb[i] = ((uae_s8)get_cb(monid, r, g, b)) * 256; + tcrrgb[i] = ((uae_s8)get_cr(monid, r, g, b)) * 256; } } #endif diff --git a/include/custom.h b/include/custom.h index 98c377f0..f9da2fb8 100644 --- a/include/custom.h +++ b/include/custom.h @@ -39,13 +39,12 @@ extern void do_disk (void); extern void do_copper (void); extern void notice_new_xcolors (void); -extern void notice_screen_contents_lost (void); +extern void notice_screen_contents_lost(int monid); extern void init_row_map (void); extern void init_hz_normal (void); extern void init_custom (void); -extern bool picasso_requested_on, picasso_requested_forced_on, picasso_on; -extern void set_picasso_hack_rate (int hz); +extern void set_picasso_hack_rate(int hz); /* Set to 1 to leave out the current frame in average frame time calculation. * Useful if the debugger was active. */ @@ -130,8 +129,8 @@ extern int maxhpos, maxhpos_short; extern int maxvpos, maxvpos_nom, maxvpos_display; extern int hsyncstartpos, hsyncendpos; extern int minfirstline, vblank_endline, numscrlines; -extern double vblank_hz, fake_vblank_hz; -extern double hblank_hz; +extern float vblank_hz, fake_vblank_hz; +extern float hblank_hz; extern int vblank_skip, doublescan; extern bool programmedmode; diff --git a/include/drawing.h b/include/drawing.h index 01dfcfe0..10cfc902 100644 --- a/include/drawing.h +++ b/include/drawing.h @@ -84,9 +84,6 @@ STATIC_INLINE int coord_window_to_diw_x (int x) return x - DIW_DDF_OFFSET; } -extern int framecnt; -extern int custom_frame_redraw_necessary; - /* color values in two formats: 12 (OCS/ECS) or 24 (AGA) bit Amiga RGB (color_regs), * and the native color value; both for each Amiga hardware color register. * @@ -290,7 +287,6 @@ extern int coord_native_to_amiga_y (int); extern int coord_native_to_amiga_x (int); extern void record_diw_line (int plfstrt, int first, int last); -extern void hardware_line_completed (int lineno); /* Determine how to draw a scan line. */ enum nln_how { @@ -311,8 +307,9 @@ enum nln_how { }; extern void hsync_record_line_state (int lineno, enum nln_how, int changed); -extern void vsync_handle_redraw (int long_field, int lof_changed, uae_u16, uae_u16); +extern void vsync_handle_redraw (int long_field, int lof_changed, uae_u16, uae_u16, bool drawlines); extern bool vsync_handle_check (void); +extern void draw_lines(int end, int section); extern void init_hardware_for_drawing_frame (void); extern void reset_drawing (void); extern void drawing_init (void); @@ -329,8 +326,8 @@ extern void get_custom_topedge (int *x, int *y, bool max); extern void get_custom_raw_limits (int *pw, int *ph, int *pdx, int *pdy); void get_custom_mouse_limits (int *pw, int *ph, int *pdx, int *pdy, int dbl); extern void putpixel (uae_u8 *buf, uae_u8 *genlockbuf, int bpp, int x, xcolnr c8, int opaq); -extern void allocvidbuffer (struct vidbuffer *buf, int width, int height, int depth); -extern void freevidbuffer (struct vidbuffer *buf); +extern void allocvidbuffer(int monid, struct vidbuffer *buf, int width, int height, int depth); +extern void freevidbuffer(int monid, struct vidbuffer *buf); extern void check_prefs_picasso(void); /* Finally, stuff that shouldn't really be shared. */ @@ -341,19 +338,8 @@ extern int thisframe_first_drawn_line, thisframe_last_drawn_line; #define IHF_QUIT_PROGRAM 1 #define IHF_PICASSO 2 -extern int inhibit_frame; - -STATIC_INLINE void set_inhibit_frame (int bit) -{ - inhibit_frame |= 1 << bit; -} -STATIC_INLINE void clear_inhibit_frame (int bit) -{ - inhibit_frame &= ~(1 << bit); -} -STATIC_INLINE void toggle_inhibit_frame (int bit) -{ - inhibit_frame ^= 1 << bit; -} +void set_inhibit_frame(int monid, int bit); +void clear_inhibit_frame(int monid, int bit); +void toggle_inhibit_frame(int monid, int bit); #endif /* UAE_DRAWING_H */ diff --git a/include/events.h b/include/events.h index d461b8a5..fb094a9d 100644 --- a/include/events.h +++ b/include/events.h @@ -77,8 +77,6 @@ extern uae_s32 pissoff; extern struct ev eventtab[ev_max]; extern struct ev2 eventtab2[ev2_max]; -extern volatile bool vblank_found_chipset; -extern volatile bool vblank_found_rtg; extern int hpos_offset; extern int maxhpos; diff --git a/include/gfxboard.h b/include/gfxboard.h index 3f60654c..7a01f1be 100644 --- a/include/gfxboard.h +++ b/include/gfxboard.h @@ -8,7 +8,7 @@ extern bool gfxboard_init_memory_p4_z2(struct autoconfig_info*); extern bool gfxboard_init_registers(struct autoconfig_info*); extern void gfxboard_free (void); extern void gfxboard_reset (void); -extern bool gfxboard_vsync_handler (bool); +extern bool gfxboard_vsync_handler (bool, bool); extern void gfxboard_hsync_handler(void); extern int gfxboard_get_configtype (struct rtgboardconfig*); extern bool gfxboard_is_registers (struct rtgboardconfig*); @@ -17,8 +17,8 @@ extern int gfxboard_get_vram_max (struct rtgboardconfig*); extern bool gfxboard_need_byteswap (struct rtgboardconfig*); extern int gfxboard_get_autoconfig_size(struct rtgboardconfig*); extern double gfxboard_get_vsync (void); -extern void gfxboard_refresh (void); -extern int gfxboard_toggle (int mode, int msg); +extern void gfxboard_refresh (int monid); +extern int gfxboard_toggle (int monid, int mode, int msg); extern int gfxboard_num_boards (struct rtgboardconfig*); extern uae_u32 gfxboard_get_romtype(struct rtgboardconfig*); extern const TCHAR *gfxboard_get_name(int); @@ -28,8 +28,8 @@ extern struct gfxboard_func *gfxboard_get_func(struct rtgboardconfig *rbc); extern bool gfxboard_allocate_slot(int, int); extern void gfxboard_free_slot(int); -extern bool gfxboard_rtg_enable_initial(int); -extern void gfxboard_rtg_disable(int); +extern bool gfxboard_rtg_enable_initial(int monid, int); +extern void gfxboard_rtg_disable(int monid, int); extern bool gfxboard_init_board(struct autoconfig_info*); extern struct gfxboard_func a2410_func; diff --git a/include/gfxfilter.h b/include/gfxfilter.h index 5c5a9744..b46003b6 100644 --- a/include/gfxfilter.h +++ b/include/gfxfilter.h @@ -9,14 +9,14 @@ typedef unsigned char u8; typedef unsigned short u16; typedef unsigned long u32; -extern void S2X_refresh (void); -extern void S2X_render (void); -extern bool S2X_init (int dw, int dh, int dd); -extern void S2X_reset (void); -extern void S2X_free (void); -extern int S2X_getmult (void); - -extern void PAL_init (void); +extern void S2X_refresh(int); +extern void S2X_render(int, int, int); +extern bool S2X_init (int, int dw, int dh, int dd); +extern void S2X_reset(int); +extern void S2X_free(int); +extern int S2X_getmult(int); + +extern void PAL_init(int monid); extern void PAL_1x1_32 (uae_u32 *src, int pitchs, uae_u32 *trg, int pitcht, int width, int height); extern void PAL_1x1_16 (uae_u16 *src, int pitchs, uae_u16 *trg, int pitcht, int width, int height); @@ -26,7 +26,7 @@ typedef int bool; extern "C" { - extern void S2X_configure (int rb, int gb, int bb, int rs, int gs, int bs); + extern void S2X_configure(int, int rb, int gb, int bb, int rs, int gs, int bs); extern int Init_2xSaI (int rb, int gb, int bb, int rs, int gs, int bs); extern void Super2xSaI_16 (const uae_u8 *srcPtr, uae_u32 srcPitch, uae_u8 *dstPtr, uae_u32 dstPitch, int width, int height); extern void Super2xSaI_32 (const uae_u8 *srcPtr, uae_u32 srcPitch, uae_u8 *dstPtr, uae_u32 dstPitch, int width, int height); @@ -76,19 +76,18 @@ struct uae_filter }; extern struct uae_filter uaefilters[]; -extern struct uae_filter *usedfilter; -void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height, int aw, int ah, int scale, int temp_width, int temp_height); -void getfilteroffset (float *dx, float *dy, float *mx, float *my); -uae_u8 *getfilterbuffer3d (int *widthp, int *heightp, int *pitch, int *depth); +void getfilterrect2(int monid, RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height, int aw, int ah, int scale, int temp_width, int temp_height); +void getfilteroffset(int monid, float *dx, float *dy, float *mx, float *my); +uae_u8 *getfilterbuffer3d(int monid, int *widthp, int *heightp, int *pitch, int *depth); -uae_u8 *getfilterbuffer (int *widthp, int *heightp, int *pitch, int *depth); -void freefilterbuffer(uae_u8*); +uae_u8 *getfilterbuffer(int monid, int *widthp, int *heightp, int *pitch, int *depth); +void freefilterbuffer(int monid, uae_u8*); -uae_u8 *getrtgbuffer (int *widthp, int *heightp, int *pitch, int *depth, uae_u8 *palette); -void freertgbuffer (uae_u8 *dst); +uae_u8 *getrtgbuffer(int monid, int *widthp, int *heightp, int *pitch, int *depth, uae_u8 *palette); +void freertgbuffer(int monid, uae_u8 *dst); -extern void getrtgfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height); +extern void getrtgfilterrect2(int monid, RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height); #endif /* GFXFILTER */ diff --git a/include/inputdevice.h b/include/inputdevice.h index f5407252..9ffccd6d 100644 --- a/include/inputdevice.h +++ b/include/inputdevice.h @@ -235,8 +235,8 @@ extern void input_mousehack_mouseoffset (uaecptr pointerprefs); extern int mousehack_alive (void); extern void mousehack_wakeup(void); extern void mousehack_write(int reg, uae_u16 val); -extern void setmouseactive (int); -extern bool ismouseactive (void); +extern void setmouseactive(int monid, int); +extern bool ismouseactive(void); extern void setmousebuttonstateall (int mouse, uae_u32 buttonbits, uae_u32 buttonmask); extern void setjoybuttonstateall (int joy, uae_u32 buttonbits, uae_u32 buttonmask); @@ -286,7 +286,7 @@ extern void JOYSET (int num, uae_u16 v); extern uae_u16 JOYGET (int num); extern void inputdevice_vsync (void); -extern void inputdevice_hsync (void); +extern void inputdevice_hsync (bool); extern void inputdevice_reset (void); extern void write_inputdevice_config (struct uae_prefs *p, struct zfile *f); diff --git a/include/options.h b/include/options.h index 8eee94d7..bc839fbf 100644 --- a/include/options.h +++ b/include/options.h @@ -14,9 +14,11 @@ #include "traps.h" -#define UAEMAJOR 3 -#define UAEMINOR 6 -#define UAESUBREV 1 +#define UAEMAJOR 4 +#define UAEMINOR 0 +#define UAESUBREV 0 + +#define MAX_AMIGADISPLAYS 4 typedef enum { KBD_LANG_US, KBD_LANG_DK, KBD_LANG_DE, KBD_LANG_SE, KBD_LANG_FR, KBD_LANG_IT, KBD_LANG_ES } KbdLang; @@ -321,7 +323,6 @@ struct apmode int gfx_backbuffers; bool gfx_interlaced; int gfx_refreshrate; - bool gfx_tearing; }; #define MAX_LUA_STATES 16 @@ -389,6 +390,7 @@ struct rtgboardconfig int rtgmem_type; uae_u32 rtgmem_size; int device_order; + int monitor_id; }; #define MAX_RAM_BOARDS 4 struct ramboard @@ -414,6 +416,15 @@ struct expansion_params #define Z3MAPPING_UAE 1 #define Z3MAPPING_REAL 2 +struct monconfig +{ + struct wh gfx_size_win; + struct wh gfx_size_fs; + struct wh gfx_size; + struct wh gfx_size_win_xtra[6]; + struct wh gfx_size_fs_xtra[6]; +}; + struct uae_prefs { struct strlist *all_lines; @@ -484,12 +495,8 @@ struct uae_prefs { bool fpu_strict; bool fpu_softfloat; + struct monconfig gfx_monitor[MAX_AMIGADISPLAYS]; int gfx_framerate, gfx_autoframerate; - struct wh gfx_size_win; - struct wh gfx_size_fs; - struct wh gfx_size; - struct wh gfx_size_win_xtra[6]; - struct wh gfx_size_fs_xtra[6]; bool gfx_autoresolution_vga; int gfx_autoresolution; int gfx_autoresolution_delay; @@ -516,6 +523,8 @@ struct uae_prefs { bool gfx_grayscale; bool lightpen_crosshair; int lightpen_offset[2]; + int gfx_display_sections; + int gfx_variable_sync; struct gfx_filterdata gf[2]; @@ -537,6 +546,7 @@ struct uae_prefs { TCHAR genlock_image_file[MAX_DPATH]; TCHAR genlock_video_file[MAX_DPATH]; int monitoremu; + int monitoremu_mon; double chipset_refreshrate; struct chipset_refresh cr[MAX_CHIPSET_REFRESH + 2]; int cr_selected; diff --git a/include/scsi.h b/include/scsi.h index 6279bf5d..fc21b082 100644 --- a/include/scsi.h +++ b/include/scsi.h @@ -72,6 +72,7 @@ extern int scsi_receive_data(struct scsi_data*, uae_u8*, bool next); extern void scsi_emulate_cmd(struct scsi_data *sd); extern void scsi_illegal_lun(struct scsi_data *sd); extern void scsi_clear_sense(struct scsi_data *sd); +extern bool scsi_cmd_is_safe(uae_u8 cmd); extern int scsi_hd_emulate(struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, uae_u8 *cmdbuf, int scsi_cmd_len, uae_u8 *scsi_data, int *data_len, uae_u8 *r, int *reply_len, uae_u8 *s, int *sense_len); diff --git a/include/specialmonitors.h b/include/specialmonitors.h index c735a14f..90719406 100644 --- a/include/specialmonitors.h +++ b/include/specialmonitors.h @@ -14,4 +14,8 @@ bool emulate_genlock(struct vidbuffer*, struct vidbuffer*); bool emulate_grayscale(struct vidbuffer*, struct vidbuffer*); bool specialmonitor_linebased(void); +const TCHAR *specialmonitorfriendlynames[]; +const TCHAR *specialmonitormanufacturernames[]; +const TCHAR *specialmonitorconfignames[]; + #endif /* UAE_SPECIALMONITORS_H */ diff --git a/include/statusline.h b/include/statusline.h index 8b554b5a..089fd3f0 100644 --- a/include/statusline.h +++ b/include/statusline.h @@ -27,9 +27,9 @@ static int td_pos = (TD_RIGHT | TD_BOTTOM); #define STATUSLINE_RTG 2 #define STATUSLINE_TARGET 0x80 -extern void draw_status_line_single (uae_u8 *buf, int bpp, int y, int totalwidth, uae_u32 *rc, uae_u32 *gc, uae_u32 *bc, uae_u32 *alpha); -extern void statusline_single_erase(uae_u8 *buf, int bpp, int y, int totalwidth); -extern void statusline_getpos(int *x, int *y, int width, int height, int hx, int vx); +extern void draw_status_line_single(int monid, uae_u8 *buf, int bpp, int y, int totalwidth, uae_u32 *rc, uae_u32 *gc, uae_u32 *bc, uae_u32 *alpha); +extern void statusline_single_erase(int monid, uae_u8 *buf, int bpp, int y, int totalwidth); +extern void statusline_getpos(int monid, int *x, int *y, int width, int height, int hx, int vx); #define STATUSTYPE_FLOPPY 1 #define STATUSTYPE_DISPLAY 2 @@ -37,13 +37,13 @@ extern void statusline_getpos(int *x, int *y, int width, int height, int hx, int #define STATUSTYPE_CD 4 #define STATUSTYPE_OTHER 5 -extern bool createstatusline(void); -extern void deletestatusline(void); -extern void statusline_render(uae_u8 *buf, int bpp, int pitch, int width, int height, uae_u32 *rc, uae_u32 *gc, uae_u32 *bc, uae_u32 *alpha); +extern bool createstatusline(int); +extern void deletestatusline(int); +extern void statusline_render(int, uae_u8 *buf, int bpp, int pitch, int width, int height, uae_u32 *rc, uae_u32 *gc, uae_u32 *bc, uae_u32 *alpha); extern void statusline_add_message(int statustype, const TCHAR *format, ...); extern void statusline_clear(void); extern void statusline_vsync(void); -extern void statusline_updated(void); +extern void statusline_updated(int); extern bool has_statusline_updated(void); extern const TCHAR *statusline_fetch(void); diff --git a/include/xwin.h b/include/xwin.h index 370726a8..02e73d1c 100644 --- a/include/xwin.h +++ b/include/xwin.h @@ -27,45 +27,45 @@ extern bool handle_events (void); extern int handle_msgpump (void); extern void setup_brkhandler (void); extern int isfullscreen (void); -extern void toggle_fullscreen (int); -extern bool toggle_rtg (int); +extern void toggle_fullscreen(int monid, int); +extern bool toggle_rtg(int monid, int); +extern void close_rtg(int monid); extern void toggle_mousegrab (void); -void setmouseactivexy (int x, int y, int dir); - -extern void desktop_coords (int *dw, int *dh, int *x, int *y, int *w, int *h); -extern bool vsync_switchmode (int); -extern frame_time_t vsync_busywait_end (int*); -extern int vsync_busywait_do (int*, bool, bool); -extern void vsync_busywait_start (void); -extern double vblank_calibrate (double, bool); -extern bool vsync_isdone (void); +void setmouseactivexy(int monid, int x, int y, int dir); + +extern void desktop_coords(int monid, int *dw, int *dh, int *x, int *y, int *w, int *h); +extern bool vsync_switchmode(int monid, int hz); +extern void vsync_clear(void); +extern int vsync_isdone(frame_time_t*); extern void doflashscreen (void); extern int flashscreen; -extern void updatedisplayarea (void); +extern void updatedisplayarea(int monid); extern int isvsync_chipset (void); extern int isvsync_rtg (void); extern int isvsync (void); -extern void flush_line (struct vidbuffer*, int); -extern void flush_block (struct vidbuffer*, int, int); -extern void flush_screen (struct vidbuffer*, int, int); -extern void flush_clear_screen (struct vidbuffer*); -extern bool render_screen (bool); -extern void show_screen (int); -extern bool show_screen_maybe (bool); +extern void flush_line(struct vidbuffer*, int); +extern void flush_block(struct vidbuffer*, int, int); +extern void flush_screen(struct vidbuffer*, int, int); +extern void flush_clear_screen(struct vidbuffer*); +extern bool render_screen(int monid, int, bool); +extern void show_screen(int monid, int mode); +extern bool show_screen_maybe(int monid, bool); -extern int lockscr (struct vidbuffer*, bool); -extern void unlockscr (struct vidbuffer*); -extern bool target_graphics_buffer_update (void); -extern double target_adjust_vblank_hz(double); +extern int lockscr(struct vidbuffer*, bool, bool); +extern void unlockscr(struct vidbuffer*, int, int); +extern bool target_graphics_buffer_update(int monid); +extern float target_adjust_vblank_hz(int monid, float); +extern int target_get_display_scanline(int displayindex); +extern void target_spin(int); -void getgfxoffset (float *dxp, float *dyp, float *mxp, float *myp); -double getcurrentvblankrate (void); /* todo: remove from od-win32/win32gfx.h */ +void getgfxoffset(int monid, float *dxp, float *dyp, float *mxp, float *myp); +float target_getcurrentvblankrate(int monid); extern int debuggable (void); extern void LED (int); -extern void screenshot (int,int); +extern void screenshot(int monid, int,int); void refreshtitle (void); extern int bits_in_mask (unsigned long mask); @@ -74,7 +74,7 @@ extern unsigned int doMask (int p, int bits, int shift); extern unsigned int doMask256 (int p, int bits, int shift); extern void setup_maxcol (int); extern void alloc_colors256 (int (*)(int, int, int, xcolnr *)); -extern void alloc_colors64k (int, int, int, int, int, int, int, int, int, int); +extern void alloc_colors64k (int monid, int, int, int, int, int, int, int, int, int, int, bool); extern void alloc_colors_rgb (int rw, int gw, int bw, int rs, int gs, int bs, int aw, int as, int alpha, int byte_swap, uae_u32 *rc, uae_u32 *gc, uae_u32 *bc); extern void alloc_colors_picasso (int rw, int gw, int bw, int rs, int gs, int bs, int rgbfmt); @@ -82,7 +82,7 @@ extern void setup_greydither (int bits, allocfunc_type allocfunc); extern void setup_greydither_maxcol (int maxcol, allocfunc_type allocfunc); extern void setup_dither (int bits, allocfunc_type allocfunc); extern void DitherLine (uae_u8 *l, uae_u16 *r4g4b4, int x, int y, uae_s16 len, int bits) ASM_SYM_FOR_FUNC("DitherLine"); -extern double getvsyncrate (double hz, int *mult); +extern float getvsyncrate(int monid, float hz, int *mult); /* The graphics code has a choice whether it wants to use a large buffer * for the whole display, or only a small buffer for a single line. @@ -140,18 +140,16 @@ struct vidbuffer int inxoffset; /* positive if sync positioning */ int inyoffset; + + int monitor_id; + int last_drawn_line; }; -extern bool isnativevidbuf (void); +extern bool isnativevidbuf(int monid); extern int max_uae_width, max_uae_height; struct vidbuf_description { - - int maxblocklines; /* Set to 0 if you want calls to flush_line after each drawn line, or the number of - * lines that flush_block wants to/can handle (it isn't really useful to use another - * value than maxline here). */ - struct vidbuffer drawbuffer; /* output buffer when using A2024 emulation */ struct vidbuffer tempbuffer; @@ -165,10 +163,21 @@ struct vidbuf_description int ychange; /* how many interlaced lines in one line in buffer */ }; -extern struct vidbuf_description gfxvidinfo; +struct amigadisplay +{ + bool picasso_requested_on; + bool picasso_requested_forced_on; + bool picasso_on; + int picasso_redraw_necessary; + int custom_frame_redraw_necessary; + int frame_redraw_necessary; + int framecnt; + bool specialmonitoron; + int inhibit_frame; + + struct vidbuf_description gfxvidinfo; +}; -/* For ports using tui.c, this should be built by graphics_setup(). */ -extern struct bstring *video_mode_menu; -extern void vidmode_menu_selected(int); +extern struct amigadisplay adisplays[MAX_AMIGADISPLAYS]; #endif /* UAE_XWIN_H */ diff --git a/inputdevice.cpp b/inputdevice.cpp index f018669f..0177383e 100644 --- a/inputdevice.cpp +++ b/inputdevice.cpp @@ -2203,7 +2203,7 @@ static void inputdevice_update_tablet_params(void) p[MH_MAXAZ + 1] = tablet_maxaz; } -void input_mousehack_mouseoffset (uaecptr pointerprefs) +void input_mousehack_mouseoffset(uaecptr pointerprefs) { mouseoffset_x = (uae_s16)get_word (pointerprefs + 28); mouseoffset_y = (uae_s16)get_word (pointerprefs + 30); @@ -2211,6 +2211,10 @@ void input_mousehack_mouseoffset (uaecptr pointerprefs) static bool get_mouse_position(int *xp, int *yp, int inx, int iny) { + int monid = 0; + struct vidbuf_description *vidinfo = &adisplays[monid].gfxvidinfo; + struct amigadisplay *ad = &adisplays[monid]; + struct picasso96_state_struct *state = &picasso96_state[monid]; int x, y; float fdy, fdx, fmx, fmy; bool ob = false; @@ -2218,12 +2222,12 @@ static bool get_mouse_position(int *xp, int *yp, int inx, int iny) x = inx; y = iny; - getgfxoffset (&fdx, &fdy, &fmx, &fmy); + getgfxoffset(0, &fdx, &fdy, &fmx, &fmy); #ifdef PICASSO96 - if (picasso_on) { - x -= picasso96_state.XOffset; - y -= picasso96_state.YOffset; + if (ad->picasso_on) { + x -= state->XOffset; + y -= state->YOffset; x = (int)(x * fmx); y = (int)(y * fmy); x -= (int)(fdx * fmx); @@ -2231,7 +2235,7 @@ static bool get_mouse_position(int *xp, int *yp, int inx, int iny) } else #endif { - if (gfxvidinfo.outbuffer == NULL) { + if (vidinfo->outbuffer == NULL) { *xp = 0; *yp = 0; return false; @@ -2243,7 +2247,7 @@ static bool get_mouse_position(int *xp, int *yp, int inx, int iny) x = coord_native_to_amiga_x(x); if (y >= 0) y = coord_native_to_amiga_y(y) * 2; - if (x < 0 || y < 0 || x >= gfxvidinfo.outbuffer->outwidth || y >= gfxvidinfo.outbuffer->outheight) + if (x < 0 || y < 0 || x >= vidinfo->outbuffer->outwidth || y >= vidinfo->outbuffer->outheight) ob = true; } *xp = x; @@ -2330,10 +2334,13 @@ int inputdevice_get_lightpen_id(void) void tablet_lightpen(int tx, int ty, int tmaxx, int tmaxy, int touch, int buttonmask, bool touchmode, int devid, int lpnum) { - if (picasso_on) + int monid = 0; + struct vidbuf_description *vidinfo = &adisplays[monid].gfxvidinfo; + struct amigadisplay *ad = &adisplays[monid]; + if (ad->picasso_on) goto end; - if (gfxvidinfo.outbuffer == NULL) + if (vidinfo->outbuffer == NULL) goto end; if (touch < 0) @@ -2346,7 +2353,7 @@ void tablet_lightpen(int tx, int ty, int tmaxx, int tmaxy, int touch, int button fx = (float)tx; fy = (float)ty; - desktop_coords (&dw, &dh, &ax, &ay, &aw, &ah); + desktop_coords (0, &dw, &dh, &ax, &ay, &aw, &ah); if (tmaxx < 0 || tmaxy < 0) { tmaxx = dw; @@ -2373,7 +2380,7 @@ void tablet_lightpen(int tx, int ty, int tmaxx, int tmaxy, int touch, int button fy -= ay; float fdx, fdy, fmx, fmy; - getgfxoffset (&fdx, &fdy, &fmx, &fmy); + getgfxoffset(0, &fdx, &fdy, &fmx, &fmy); int x = (int)(fx * fmx); int y = (int)(fy * fmy); @@ -2813,8 +2820,9 @@ static int mouseedge_x, mouseedge_y, mouseedge_time; #define MOUSEEDGE_RANGE 100 #define MOUSEEDGE_TIME 2 -static int mouseedge (void) +static int mouseedge(int monid) { + struct amigadisplay *ad = &adisplays[monid]; int x, y, dir; uaecptr ib; static int melast_x, melast_y; @@ -2886,16 +2894,16 @@ static int mouseedge (void) end: mouseedge_time = 0; if (dir) { - if (!picasso_on) { + if (!ad->picasso_on) { int aw = 0, ah = 0, dx, dy; get_custom_mouse_limits (&aw, &ah, &dx, &dy, dimensioninfo_dbl); x += dx; y += dy; } if (!dmaen (DMA_SPRITE)) - setmouseactivexy (x, y, 0); + setmouseactivexy(0, x, y, 0); else - setmouseactivexy (x, y, dir); + setmouseactivexy(0, x, y, dir); } return 1; } @@ -3143,7 +3151,7 @@ static void joymousecounter (int joy) static int inputread; -static void inputdevice_read(bool peek) +static void inputdevice_read(void) { // if ((inputdevice_logging & (2 | 4))) // write_log(_T("INPUTREAD\n")); @@ -3163,11 +3171,10 @@ static void inputdevice_read(bool peek) static void maybe_read_input(void) { - if (inputread >= 0 && inputread + 10 > vpos) + if (inputread >= 0 && (vpos - inputread) <= maxvpos_display / 3) return; - bool peek = inputread >= 0 && inputread + 50 > vpos; inputread = vpos; - inputdevice_read(peek); + inputdevice_read(); } static uae_u16 getjoystate (int joy) @@ -3811,7 +3818,7 @@ int handle_custom_event (const TCHAR *custom, int append) return 0; } -void inputdevice_hsync (void) +void inputdevice_hsync (bool forceread) { cap_check (); @@ -3879,7 +3886,7 @@ void inputdevice_hsync (void) if (input_record && input_record != INPREC_RECORD_PLAYING) { if (vpos == 0) - inputdevice_read(false); + inputdevice_read(); } if (input_play) { inprec_playdiskchange (); @@ -3890,7 +3897,12 @@ void inputdevice_hsync (void) handle_msgpump (); } if (!input_record && !input_play) { - maybe_read_input(); + if (forceread) { + inputread = maxvpos + 1; + inputdevice_read(); + } else { + maybe_read_input(); + } } } @@ -4124,7 +4136,7 @@ static bool needcputrace (int code) void target_paste_to_keyboard(void); -static bool inputdevice_handle_inputcode2 (int code, int state, const TCHAR *s) +static bool inputdevice_handle_inputcode2(int monid, int code, int state, const TCHAR *s) { static int swapperslot; static int tracer_enable; @@ -4257,7 +4269,7 @@ static bool inputdevice_handle_inputcode2 (int code, int state, const TCHAR *s) { case AKS_SCREENSHOT_FILE: // stop multiscreenshot - screenshot(4, 1); + screenshot(0, 4, 1); break; } return false; @@ -4271,13 +4283,13 @@ static bool inputdevice_handle_inputcode2 (int code, int state, const TCHAR *s) break; case AKS_SCREENSHOT_FILE: if (state > 1) { - screenshot(3, 1); + screenshot(0, 3, 1); } else { - screenshot(1, 1); + screenshot(0, 1, 1); } break; case AKS_SCREENSHOT_CLIPBOARD: - screenshot (0, 1); + screenshot(0, 0, 1); break; #ifdef AVIOUTPUT case AKS_VIDEORECORD: @@ -4356,7 +4368,7 @@ static bool inputdevice_handle_inputcode2 (int code, int state, const TCHAR *s) warpmode (newstate); break; case AKS_INHIBITSCREEN: - toggle_inhibit_frame (IHF_SCROLLLOCK); + toggle_inhibit_frame(monid, IHF_SCROLLLOCK); break; case AKS_STATEREWIND: savestate_dorewind (-2); @@ -4419,16 +4431,16 @@ static bool inputdevice_handle_inputcode2 (int code, int state, const TCHAR *s) savestate_quick ((code - AKS_STATERESTOREQUICK) / 2, 0); break; case AKS_TOGGLEDEFAULTSCREEN: - toggle_fullscreen (-1); + toggle_fullscreen(0, -1); break; case AKS_TOGGLEWINDOWEDFULLSCREEN: - toggle_fullscreen (0); + toggle_fullscreen(0, 0); break; case AKS_TOGGLEFULLWINDOWFULLSCREEN: - toggle_fullscreen (1); + toggle_fullscreen(0, 1); break; case AKS_TOGGLEWINDOWFULLWINDOW: - toggle_fullscreen (2); + toggle_fullscreen(0, 2); break; case AKS_TOGGLEMOUSEGRAB: toggle_mousegrab(); @@ -4525,17 +4537,17 @@ static bool inputdevice_handle_inputcode2 (int code, int state, const TCHAR *s) disk_prevnext (code - AKS_DISK_NEXT0, 1); break; case AKS_RTG_PREV: - toggle_rtg(-1); + toggle_rtg(0, -1); break; case AKS_RTG_NEXT: - toggle_rtg(MAX_RTG_BOARDS + 1); + toggle_rtg(0, MAX_RTG_BOARDS + 1); break; case AKS_RTG_C: case AKS_RTG_0: case AKS_RTG_1: case AKS_RTG_2: case AKS_RTG_3: - toggle_rtg(code - AKS_RTG_C); + toggle_rtg(0, code - AKS_RTG_C); break; case AKS_VIDEOGRAB_RESTART: getsetpositionvideograb(0); @@ -4581,15 +4593,16 @@ end: return false; } -void inputdevice_handle_inputcode (void) +void inputdevice_handle_inputcode(void) { + int monid = 0; bool got = false; for (int i = 0; i < MAX_PENDING_EVENTS; i++) { int code = inputcode_pending[i].code; int state = inputcode_pending[i].state; const TCHAR *s = inputcode_pending[i].s; if (code) { - if (!inputdevice_handle_inputcode2 (code, state, s)) { + if (!inputdevice_handle_inputcode2(monid, code, state, s)) { xfree(inputcode_pending[i].s); inputcode_pending[i].code = 0; } @@ -4597,7 +4610,7 @@ void inputdevice_handle_inputcode (void) } } if (!got) - inputdevice_handle_inputcode2 (0, 0, NULL); + inputdevice_handle_inputcode2(monid, 0, 0, NULL); } @@ -4616,8 +4629,9 @@ static uae_u64 isqual (int evt) return ID_FLAG_QUALIFIER1 << (num * 2); } -static int handle_input_event2 (int nr, int state, int max, int flags, int extra) +static int handle_input_event2(int nr, int state, int max, int flags, int extra) { + struct vidbuf_description *vidinfo = &adisplays[0].gfxvidinfo; const struct inputevent *ie; int joy; bool isaks = false; @@ -4668,8 +4682,8 @@ static int handle_input_event2 (int nr, int state, int max, int flags, int extra int unit = (ie->data & 1) ? 1 : 0; int lpnum = ie->unit - 5; if (lightpen_active <= 0) { - lightpen_x[0] = gfxvidinfo.outbuffer->outwidth / 2; - lightpen_y[0] = gfxvidinfo.outbuffer->outheight / 2; + lightpen_x[0] = vidinfo->outbuffer->outwidth / 2; + lightpen_y[0] = vidinfo->outbuffer->outheight / 2; lightpen_x[1] = -1; lightpen_y[1] = -1; } @@ -4729,12 +4743,12 @@ static int handle_input_event2 (int nr, int state, int max, int flags, int extra } if (lightpen_x[lpnum] < -10) lightpen_x[lpnum] = -10; - if (lightpen_x[lpnum] >= gfxvidinfo.drawbuffer.inwidth + 10) - lightpen_x[lpnum] = gfxvidinfo.drawbuffer.inwidth + 10; + if (lightpen_x[lpnum] >= vidinfo->drawbuffer.inwidth + 10) + lightpen_x[lpnum] = vidinfo->drawbuffer.inwidth + 10; if (lightpen_y[lpnum] < -10) lightpen_y[lpnum] = -10; - if (lightpen_y[lpnum] >= gfxvidinfo.drawbuffer.inheight + 10) - lightpen_y[lpnum] = gfxvidinfo.drawbuffer.inheight + 10; + if (lightpen_y[lpnum] >= vidinfo->drawbuffer.inheight + 10) + lightpen_y[lpnum] = vidinfo->drawbuffer.inheight + 10; #if 0 write_log(_T("%d*%d\n"), lightpen_x[0], lightpen_y[0]); #endif @@ -5075,6 +5089,7 @@ static void inputdevice_checkconfig (void) void inputdevice_vsync (void) { + int monid = 0; if (inputdevice_logging & 32) write_log (_T("*\n")); @@ -5096,18 +5111,18 @@ void inputdevice_vsync (void) if (arcadia_bios || alg_flag || cubo_enabled) arcadia_vsync (); #endif - if (mouseedge ()) + if (mouseedge(monid)) mouseedge_alive = 10; if (mousehack_alive_cnt > 0) { mousehack_alive_cnt--; if (mousehack_alive_cnt == 0) - setmouseactive (-1); + setmouseactive(0, -1); } else if (mousehack_alive_cnt < 0) { mousehack_alive_cnt++; if (mousehack_alive_cnt == 0) { mousehack_alive_cnt = 100; - setmouseactive (0); - setmouseactive (1); + setmouseactive(0, 0); + setmouseactive(0, 1); } } inputdevice_checkconfig (); @@ -8587,7 +8602,7 @@ void inputdevice_settest (int set) int inputdevice_testread_count (void) { - inputdevice_read (false); + inputdevice_read(); if (testmode != 1) { testmode = 0; return -1; @@ -8598,7 +8613,7 @@ int inputdevice_testread_count (void) int inputdevice_testread (int *devnum, int *wtype, int *state, bool doread) { if (doread) { - inputdevice_read (false); + inputdevice_read(); if (testmode != 1) { testmode = 0; return -1; diff --git a/main.cpp b/main.cpp index 1d6e8c0e..4acd8004 100644 --- a/main.cpp +++ b/main.cpp @@ -119,7 +119,7 @@ TCHAR *my_strdup_trim (const TCHAR *s) return out; } -void discard_prefs (struct uae_prefs *p, int type) +void discard_prefs(struct uae_prefs *p, int type) { struct strlist **ps = &p->all_lines; while (*ps) { @@ -136,32 +136,38 @@ void discard_prefs (struct uae_prefs *p, int type) #endif } -static void fixup_prefs_dim2 (struct wh *wh) +static void fixup_prefs_dim2(int monid, struct wh *wh) { if (wh->special) return; if (wh->width < 160) { - error_log (_T("Width (%d) must be at least 160."), wh->width); + if (!monid) + error_log (_T("Width (%d) must be at least 160."), wh->width); wh->width = 160; } if (wh->height < 128) { - error_log (_T("Height (%d) must be at least 128."), wh->height); + if (!monid) + error_log (_T("Height (%d) must be at least 128."), wh->height); wh->height = 128; } if (wh->width > max_uae_width) { - error_log (_T("Width (%d) max is %d."), wh->width, max_uae_width); + if (!monid) + error_log (_T("Width (%d) max is %d."), wh->width, max_uae_width); wh->width = max_uae_width; } if (wh->height > max_uae_height) { - error_log (_T("Height (%d) max is %d."), wh->height, max_uae_height); + if (!monid) + error_log (_T("Height (%d) max is %d."), wh->height, max_uae_height); wh->height = max_uae_height; } } void fixup_prefs_dimensions (struct uae_prefs *prefs) { - fixup_prefs_dim2 (&prefs->gfx_size_fs); - fixup_prefs_dim2 (&prefs->gfx_size_win); + for (int i = 0; i < MAX_AMIGADISPLAYS; i++) { + fixup_prefs_dim2(i, &prefs->gfx_monitor[i].gfx_size_fs); + fixup_prefs_dim2(i, &prefs->gfx_monitor[i].gfx_size_win); + } if (prefs->gfx_apmode[1].gfx_vsync > 0) prefs->gfx_apmode[1].gfx_vsyncmode = 1; @@ -169,25 +175,15 @@ void fixup_prefs_dimensions (struct uae_prefs *prefs) struct apmode *ap = &prefs->gfx_apmode[i]; ap->gfx_vflip = 0; ap->gfx_strobo = false; -#if 0 - if (currprefs.gfx_api > 1 && ap->gfx_vsyncmode) { - ap->gfx_vsyncmode = false; - error_log(_T("Low latency vsync is not yet supported in Direct3D11 mode.")); - } -#endif if (ap->gfx_vsync < 0) { // adaptive sync ap->gfx_vsyncmode = 0; - ap->gfx_vflip = 0; + ap->gfx_vflip = 1; ap->gfx_strobo = prefs->lightboost_strobo; } else if (ap->gfx_vsync > 0) { if (ap->gfx_vsyncmode) { - // low latency vsync: no flip only if no-buffer - if (ap->gfx_backbuffers >= 1) - ap->gfx_vflip = 1; - if (!i && ap->gfx_backbuffers == 2) - ap->gfx_vflip = 1; - ap->gfx_strobo = prefs->lightboost_strobo; + ap->gfx_backbuffers = 1; + ap->gfx_strobo = false; } else { // legacy vsync: always wait for flip ap->gfx_vflip = -1; @@ -396,22 +392,57 @@ void fixup_prefs (struct uae_prefs *p, bool userconfig) } } +#ifdef _WIN32 + if (p->monitoremu && p->monitoremu_mon > 0) { + if (!p->gfx_api) { + p->monitoremu_mon = 0; + error_log(_T("Multi virtual monitor support requires Direct3D mode.")); + } + if (isfullscreen() != 0) { + p->monitoremu_mon = 0; + error_log(_T("Multi virtual monitor support requires windowed mode.")); + } + } +#endif + for (int i = 0; i < MAX_RTG_BOARDS; i++) { struct rtgboardconfig *rbc = &p->rtgboards[i]; + if (rbc->monitor_id > 0 && p->monitoremu_mon == rbc->monitor_id) { + error_log(_T("Video port monitor %d was allocated for graphics card %d."), rbc->monitor_id + 1, i + 1); + p->monitoremu_mon = 0; + } + if (rbc->monitor_id > 0) { + if (!p->gfx_api) { + rbc->monitor_id = 0; + error_log(_T("Multi virtual monitor support requires Direct3D mode.")); + } + if (isfullscreen() != 0) { + rbc->monitor_id = 0; + error_log(_T("Multi virtual monitor support requires windowed mode.")); + } + } if (rbc->rtgmem_size > max_z3fastmem && rbc->rtgmem_type == GFXBOARD_UAE_Z3) { - error_log (_T("Graphics card memory size %d (0x%x) larger than maximum reserved %d (0x%x)."), rbc->rtgmem_size, rbc->rtgmem_size, max_z3fastmem, max_z3fastmem); + error_log (_T("Graphics card %d memory size %d (0x%x) larger than maximum reserved %d (0x%x)."), i + 1, rbc->rtgmem_size, rbc->rtgmem_size, max_z3fastmem, max_z3fastmem); rbc->rtgmem_size = max_z3fastmem; err = 1; } - if ((rbc->rtgmem_size & (rbc->rtgmem_size - 1)) != 0 || (rbc->rtgmem_size != 0 && (rbc->rtgmem_size < 0x100000))) { - error_log (_T("Unsupported graphics card memory size %d (0x%x)."), rbc->rtgmem_size, rbc->rtgmem_size); + error_log (_T("Unsupported graphics card %d memory size %d (0x%x)."), rbc->rtgmem_size, rbc->rtgmem_size, i + 1); if (rbc->rtgmem_size > max_z3fastmem) rbc->rtgmem_size = max_z3fastmem; else rbc->rtgmem_size = 0; err = 1; } + for (int j = 0; j < MAX_RTG_BOARDS; j++) { + struct rtgboardconfig *rbc2 = &p->rtgboards[j]; + if (j == i) + continue; + if (rbc->monitor_id > 0 && rbc2->monitor_id == rbc->monitor_id) { + rbc2->monitor_id = 0; + error_log(_T("Graphics card %d and %d can't use same monitor %d."), i + 1, j + 1); + } + } } for (int i = 0; i < MAX_RAM_BOARDS; i++) { @@ -694,6 +725,11 @@ void fixup_prefs (struct uae_prefs *p, bool userconfig) #endif if (p->gfx_framerate < 1) p->gfx_framerate = 1; + if (p->gfx_display_sections < 1) { + p->gfx_display_sections = 1; + } else if (p->gfx_display_sections > 99) { + p->gfx_display_sections = 99; + } if (p->maprom && !p->address_space_24) { p->maprom = 0x0f000000; } @@ -1107,7 +1143,7 @@ static int real_main2 (int argc, TCHAR **argv) uae_lua_init (); #endif #ifdef PICASSO96 - picasso_reset (); + picasso_reset(0); #endif #if 0 diff --git a/mame/a2410.cpp b/mame/a2410.cpp index fb474193..af0daec5 100644 --- a/mame/a2410.cpp +++ b/mame/a2410.cpp @@ -17,6 +17,7 @@ #include "statusline.h" #include "newcpu.h" #include "gfxboard.h" +#include "xwin.h" rectangle tms_rectangle; static mscreen tms_screen; @@ -571,7 +572,7 @@ static void tms_reset(void *userdata) struct a2410_struct *data = (struct a2410_struct*)userdata; if (data->a2410_surface) - gfx_unlock_picasso(true); + gfx_unlock_picasso(0, true); data->a2410_surface = NULL; data->a2410_modechanged = false; @@ -598,7 +599,7 @@ static void tms_free(void *userdata) struct a2410_struct *data = (struct a2410_struct*)userdata; if (data->a2410_surface) - gfx_unlock_picasso(true); + gfx_unlock_picasso(0, true); data->a2410_surface = NULL; if (data->a2410_gfxboard >= 0) { gfxboard_free_vram(data->a2410_gfxboard); @@ -667,15 +668,18 @@ void mscreen::configure(int width, int height, rectangle vis) static void get_a2410_surface(struct a2410_struct *data) { + int monid = currprefs.rtgboards[data->a2410_gfxboard].monitor_id; + struct amigadisplay *ad = &adisplays[monid]; + bool gotsurf = false; - if (picasso_on) { + if (ad->picasso_on) { if (data->a2410_surface == NULL) { - data->a2410_surface = gfx_lock_picasso(false, false); + data->a2410_surface = gfx_lock_picasso(monid, false, false); gotsurf = true; } if (data->a2410_surface && gotsurf) { if (!(currprefs.leds_on_screen & STATUSLINE_TARGET)) - picasso_statusline(data->a2410_surface); + picasso_statusline(monid, data->a2410_surface); } } } @@ -710,6 +714,9 @@ static bool tms_toggle(void *userdata, int mode) static void tms_vsync_handler2(struct a2410_struct *data, bool internalsync) { + int monid = currprefs.rtgboards[data->a2410_gfxboard].monitor_id; + struct amigadisplay *ad = &adisplays[monid]; + if (!data->tms_configured) return; @@ -718,13 +725,13 @@ static void tms_vsync_handler2(struct a2410_struct *data, bool internalsync) bool enabled = parms.enabled != 0 && data->a2410_gotmode > 0; if (!data->a2410_visible && data->a2410_modechanged) { - gfxboard_rtg_enable_initial(data->a2410_gfxboard); + gfxboard_rtg_enable_initial(monid, data->a2410_gfxboard); } if (data->a2410_visible) { if (enabled != data->a2410_enabled || data->a2410_modechanged) { if (data->a2410_surface) - gfx_unlock_picasso(false); + gfx_unlock_picasso(monid, false); data->a2410_surface = NULL; if (enabled) { @@ -732,10 +739,10 @@ static void tms_vsync_handler2(struct a2410_struct *data, bool internalsync) data->fullrefresh = 2; } data->a2410_enabled = enabled; - write_log(_T("A2410 ACTIVE=%d\n"), data->a2410_enabled); + write_log(_T("A2410 MONITOR=%d ACTIVE=%d\n"), monid, data->a2410_enabled); } - if (picasso_on) { + if (ad->picasso_on) { if (currprefs.leds_on_screen & STATUSLINE_RTG) { get_a2410_surface(data); } @@ -748,7 +755,7 @@ static void tms_vsync_handler2(struct a2410_struct *data, bool internalsync) } if (data->a2410_surface) - gfx_unlock_picasso(true); + gfx_unlock_picasso(monid, true); data->a2410_surface = NULL; } @@ -781,7 +788,7 @@ static bool tms_vsync(void *userdata, struct gfxboard_mode *mode) tms_vsync_handler2(data, false); if (data->a2410_surface) { - gfx_unlock_picasso(false); + gfx_unlock_picasso(0, false); flushed = true; } data->a2410_surface = NULL; @@ -797,6 +804,10 @@ static bool tms_vsync(void *userdata, struct gfxboard_mode *mode) static void tms_hsync_handler2(struct a2410_struct *data) { + int monid = currprefs.rtgboards[data->a2410_gfxboard].monitor_id; + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; + struct amigadisplay *ad = &adisplays[monid]; + if (!data->tms_configured) return; @@ -815,7 +826,7 @@ static void tms_hsync_handler2(struct a2410_struct *data) picasso_getwritewatch(data->a2410_gfxboard, data->a2410_vram_start_offset); } - if (data->a2410_modechanged || !picasso_on) + if (data->a2410_modechanged || !ad->picasso_on) return; if (a2410_vpos == 0 && data->fullrefresh > 0) { @@ -846,7 +857,7 @@ static void tms_hsync_handler2(struct a2410_struct *data) overlay_yoffset++; } - if (overlay_yoffset >= data->a2410_height || overlay_yoffset >= picasso_vidinfo.height) + if (overlay_yoffset >= data->a2410_height || overlay_yoffset >= vidinfo->height) return; if (!data->fullrefresh && !data->a2410_modified[overlay_yoffset]) { @@ -864,7 +875,7 @@ static void tms_hsync_handler2(struct a2410_struct *data) data->a2410_modified[overlay_yoffset] = false; - dst += overlay_yoffset * picasso_vidinfo.rowbytes; + dst += overlay_yoffset * vidinfo->rowbytes; uae_u32 *dst32 = (uae_u32*)dst; uae_u8 *overlay0 = data->program_ram + overlayoffset * OVERLAY_WIDTH / 8; @@ -887,7 +898,7 @@ static void tms_hsync_handler2(struct a2410_struct *data) int overlay_bitcount = 0; uae_u8 opix0 = 0, opix1 = 0; - for (int x = parms.heblnk; x < parms.hsblnk && xx < picasso_vidinfo.width; x += 2, xx += 2) { + for (int x = parms.heblnk; x < parms.hsblnk && xx < vidinfo->width; x += 2, xx += 2) { if (a2410_vpos >= parms.veblnk && a2410_vpos < parms.vsblnk) { @@ -939,7 +950,7 @@ static void tms_hsync_handler2(struct a2410_struct *data) } } - while (xx < picasso_vidinfo.width) { + while (xx < vidinfo->width) { *dst32++ = 0; xx++; } diff --git a/od-win32/ahidsound_dsonly.cpp b/od-win32/ahidsound_dsonly.cpp index 3cd28a87..8150e15b 100644 --- a/od-win32/ahidsound_dsonly.cpp +++ b/od-win32/ahidsound_dsonly.cpp @@ -59,8 +59,6 @@ static int amigablksize; static DWORD sound_flushes2 = 0; -extern HWND hAmigaWnd; - static LPDIRECTSOUND lpDS2 = NULL; static LPDIRECTSOUNDBUFFER lpDSBprimary2 = NULL; static LPDIRECTSOUNDBUFFER lpDSB2 = NULL; @@ -90,6 +88,7 @@ static struct winuae *a6; static uae_u32 REGPARAM2 emulib_ExecuteNativeCode2 (TrapContext *context) { + struct AmigaMonitor *mon = &AMonitors[0]; unsigned int espstore; uae_u8* object_UAM = (uae_u8*) m68k_areg (regs, 0); uae_u32 d1 = m68k_dreg (regs, 1); @@ -108,7 +107,7 @@ static uae_u32 REGPARAM2 emulib_ExecuteNativeCode2 (TrapContext *context) uae_u32 regs_ = (uae_u32)®s; CREATE_NATIVE_FUNC_PTR2; uaevar.z3offset = (uae_u32)(get_real_address (z3fastmem_bank[0].start) - z3fastmem_bank[0].start); - uaevar.amigawnd = hAmigaWnd; + uaevar.amigawnd = mon->hAmigaWnd; a6 = &uaevar; if (object_UAM) { SET_NATIVE_FUNC2 (object_UAM); @@ -311,6 +310,7 @@ void setvolume_ahi (LONG vol) static int ahi_init_sound_win32 (void) { + struct AmigaMonitor *mon = &AMonitors[0]; HRESULT hr; DSBUFFERDESC sound_buffer; DSCAPS DSCaps; @@ -357,7 +357,7 @@ static int ahi_init_sound_win32 (void) if (DSCaps.dwFlags & DSCAPS_EMULDRIVER) write_log (_T("AHI: Your DirectSound Driver is emulated via WaveOut - yuck!\n")); } - if (FAILED (IDirectSound_SetCooperativeLevel (lpDS2, hMainWnd, DSSCL_PRIORITY))) + if (FAILED (IDirectSound_SetCooperativeLevel (lpDS2, mon->hMainWnd, DSSCL_PRIORITY))) return 0; hr = IDirectSound_CreateSoundBuffer (lpDS2, &sound_buffer, &lpDSBprimary2, NULL); if (FAILED (hr)) { diff --git a/od-win32/avioutput.cpp b/od-win32/avioutput.cpp index 07f68ffb..4a6564bb 100644 --- a/od-win32/avioutput.cpp +++ b/od-win32/avioutput.cpp @@ -526,6 +526,7 @@ void AVIOutput_ReleaseVideo (void) static int AVIOutput_AllocateVideo (void) { + struct AmigaMonitor *mon = &AMonitors[0]; avioutput_width = avioutput_height = avioutput_bits = 0; aviout_width_out = aviout_height_out = 0; aviout_xoffset_out = aviout_yoffset_out = 0; @@ -533,12 +534,12 @@ static int AVIOutput_AllocateVideo (void) avioutput_fps = (int)(vblank_hz + 0.5); if (!avioutput_fps) avioutput_fps = ispal () ? 50 : 60; - if (avioutput_originalsize || WIN32GFX_IsPicassoScreen ()) { + if (avioutput_originalsize || WIN32GFX_IsPicassoScreen(mon)) { int pitch; - if (!WIN32GFX_IsPicassoScreen ()) { - getfilterbuffer (&avioutput_width, &avioutput_height, &pitch, &avioutput_bits); + if (!WIN32GFX_IsPicassoScreen(mon)) { + getfilterbuffer(0, &avioutput_width, &avioutput_height, &pitch, &avioutput_bits); } else { - freertgbuffer (getrtgbuffer (&avioutput_width, &avioutput_height, &pitch, &avioutput_bits, NULL)); + freertgbuffer(0, getrtgbuffer(0, &avioutput_width, &avioutput_height, &pitch, &avioutput_bits, NULL)); } aviout_width_out = avioutput_width + 15; aviout_width_out &= ~15; @@ -547,17 +548,17 @@ static int AVIOutput_AllocateVideo (void) } if (avioutput_width == 0 || avioutput_height == 0 || avioutput_bits == 0) { - avioutput_width = WIN32GFX_GetWidth (); - avioutput_height = WIN32GFX_GetHeight (); - avioutput_bits = WIN32GFX_GetDepth (0); + avioutput_width = WIN32GFX_GetWidth(mon); + avioutput_height = WIN32GFX_GetHeight(mon); + avioutput_bits = WIN32GFX_GetDepth(mon, 0); } AVIOutput_Initialize (); AVIOutput_ReleaseVideo (); if (avioutput_width == 0 || avioutput_height == 0) { - avioutput_width = workprefs.gfx_size.width; - avioutput_height = workprefs.gfx_size.height; - avioutput_bits = WIN32GFX_GetDepth (0); + avioutput_width = workprefs.gfx_monitor[0].gfx_size.width; + avioutput_height = workprefs.gfx_monitor[0].gfx_size.height; + avioutput_bits = WIN32GFX_GetDepth(mon, 0); } if (!aviout_height_out) aviout_height_out = avioutput_height; @@ -953,7 +954,7 @@ static int getFromRenderTarget11(struct avientry *avie) int w, h, pitch, bits = 32; void *data; - bool got = D3D11_capture(&data, &w, &h, &pitch); + bool got = D3D11_capture(0, &data, &w, &h, &pitch); if (got) { int dpitch = ((aviout_width_out * avioutput_bits + 31) & ~31) / 8; for (int y = 0; y < h; y++) { @@ -972,7 +973,7 @@ static int getFromRenderTarget11(struct avientry *avie) } } } - D3D11_capture(NULL, NULL, NULL, NULL); + D3D11_capture(0, NULL, NULL, NULL, NULL); ok = 1; } return ok; @@ -984,7 +985,7 @@ static int getFromRenderTarget(struct avientry *avie) int w, h, bits; HRESULT hr; D3DLOCKED_RECT l; - LPDIRECT3DSURFACE9 s = D3D_capture(&w, &h, &bits); + LPDIRECT3DSURFACE9 s = D3D_capture(0, &w, &h, &bits); if (s) { hr = s->LockRect(&l, NULL, D3DLOCK_READONLY); if (SUCCEEDED(hr)) { @@ -1081,8 +1082,10 @@ void AVIOutput_RGBinfo (int rb, int gb, int bb, int ab, int rs, int gs, int bs, #if defined (GFXFILTER) extern uae_u8 *bufmem_ptr; -static int getFromBuffer (struct avientry *ae, int original) +static int getFromBuffer(struct avientry *ae, int original) { + struct AmigaMonitor *mon = &AMonitors[0]; + struct vidbuf_description *vidinfo = &adisplays[0].gfxvidinfo; int x, y, w, h, d; uae_u8 *src, *mem; uae_u8 *dst = ae->lpVideo; @@ -1091,21 +1094,21 @@ static int getFromBuffer (struct avientry *ae, int original) mem = NULL; dpitch = ((aviout_width_out * avioutput_bits + 31) & ~31) / 8; - if (original || WIN32GFX_IsPicassoScreen ()) { - if (!WIN32GFX_IsPicassoScreen ()) { - src = getfilterbuffer (&w, &h, &spitch, &d); - maxw = gfxvidinfo.outbuffer->outwidth; - maxh = gfxvidinfo.outbuffer->outheight; + if (original || WIN32GFX_IsPicassoScreen(mon)) { + if (!WIN32GFX_IsPicassoScreen(mon)) { + src = getfilterbuffer(0, &w, &h, &spitch, &d); + maxw = vidinfo->outbuffer->outwidth; + maxh = vidinfo->outbuffer->outheight; } else { - src = mem = getrtgbuffer (&w, &h, &spitch, &d, NULL); + src = mem = getrtgbuffer(0, &w, &h, &spitch, &d, NULL); maxw = w; maxh = h; } } else { - spitch = gfxvidinfo.outbuffer->rowbytes; + spitch = vidinfo->outbuffer->rowbytes; src = bufmem_ptr; - maxw = gfxvidinfo.outbuffer->outwidth; - maxh = gfxvidinfo.outbuffer->outheight; + maxw = vidinfo->outbuffer->outwidth; + maxh = vidinfo->outbuffer->outheight; } if (!src) return 0; @@ -1175,13 +1178,14 @@ static int getFromBuffer (struct avientry *ae, int original) src += spitch; } if (mem) - freertgbuffer (mem); + freertgbuffer(0, mem); return 1; } #endif void AVIOutput_WriteVideo (void) { + struct AmigaMonitor *mon = &AMonitors[0]; struct avientry *ae; int v; @@ -1195,12 +1199,12 @@ void AVIOutput_WriteVideo (void) dorestart (); waitqueuefull (); ae = allocavientry_video (); - if (avioutput_originalsize || WIN32GFX_IsPicassoScreen ()) { + if (avioutput_originalsize || WIN32GFX_IsPicassoScreen(mon)) { v = getFromBuffer (ae, 1); } else { - if (D3D_isenabled() == 2) { + if (D3D_isenabled(0) == 2) { v = getFromRenderTarget11(ae); - } else if (D3D_isenabled() == 1) { + } else if (D3D_isenabled(0) == 1) { v = getFromRenderTarget(ae); } else { v = getFromDC (ae); @@ -1746,7 +1750,7 @@ bool frame_drawn (void) start_if_requested(); if (screenshot_multi) { - screenshot(1, 1); + screenshot(0, 1, 1); if (screenshot_multi > 0) screenshot_multi--; } diff --git a/od-win32/bsdsock.cpp b/od-win32/bsdsock.cpp index b3bef4ba..c47c681b 100644 --- a/od-win32/bsdsock.cpp +++ b/od-win32/bsdsock.cpp @@ -39,9 +39,11 @@ #include "wininet.h" #include "mmsystem.h" #include "win32.h" +#include "dxwrap.h" int rawsockets = 0; static int hWndSelector = 0; /* Set this to zero to get hSockWnd */ +static HWND hAmigaSockWnd; struct threadargs { struct socketbase *sb; @@ -97,9 +99,6 @@ static int threadindextable[MAX_GET_THREADS]; static unsigned int __stdcall sock_thread(void *); - -extern HWND hAmigaWnd; - #define THREAD(func,arg) (HANDLE)_beginthreadex(NULL, 0, func, arg, 0, &bsd->threadid) #define THREADEND(result) _endthreadex(result) @@ -408,7 +407,7 @@ static void sockmsg(unsigned int msg, WPARAM wParam, LPARAM lParam) if ((SOCKET)wParam != bsd->asyncsock[index]) { // cancel socket event - WSAAsyncSelect((SOCKET)wParam, hWndSelector ? hAmigaWnd : bsd->hSockWnd, 0, 0); + WSAAsyncSelect((SOCKET)wParam, hWndSelector ? hAmigaSockWnd : bsd->hSockWnd, 0, 0); BSDTRACE((_T("unknown sockmsg %d\n"), index)); return; } @@ -548,7 +547,7 @@ static void setWSAAsyncSelect(SB, uae_u32 sd, SOCKET s, long lEvent ) bsd->asyncsb[i] = sb; bsd->asyncsd[i] = sd; bsd->asyncsock[i] = s; - WSAAsyncSelect(s, hWndSelector ? hAmigaWnd : bsd->hSockWnd, sb->mtable[sd - 1], wsbevents); + WSAAsyncSelect(s, hWndSelector ? hAmigaSockWnd : bsd->hSockWnd, sb->mtable[sd - 1], wsbevents); unlocksigqueue(); } @@ -741,7 +740,7 @@ void host_accept(TrapContext *ctx, SB, uae_u32 sd, uae_u32 name, uae_u32 namelen if ((sb->ftable[sd - 1] & SF_BLOCKING) && sb->sb_errno == WSAEWOULDBLOCK - WSABASEERR) { if (sb->mtable[sd - 1] || (wMsg = allocasyncmsg(ctx, sb, sd, s)) != 0) { if (sb->mtable[sd - 1] == 0) { - WSAAsyncSelect(s,hWndSelector ? hAmigaWnd : bsd->hSockWnd, wMsg, FD_ACCEPT); + WSAAsyncSelect(s,hWndSelector ? hAmigaSockWnd : bsd->hSockWnd, wMsg, FD_ACCEPT); } else { setWSAAsyncSelect(sb, sd, s, FD_ACCEPT); } @@ -994,7 +993,7 @@ void host_connect(TrapContext *ctx, SB, uae_u32 sd, uae_u32 name, uae_u32 namele if (namelen <= MAXADDRLEN) { if (sb->mtable[sd-1] || (wMsg = allocasyncmsg(ctx, sb,sd,s)) != 0) { if (sb->mtable[sd-1] == 0) { - WSAAsyncSelect(s, hWndSelector ? hAmigaWnd : bsd->hSockWnd, wMsg, FD_CONNECT); + WSAAsyncSelect(s, hWndSelector ? hAmigaSockWnd : bsd->hSockWnd, wMsg, FD_CONNECT); } else { setWSAAsyncSelect(sb, sd, s, FD_CONNECT); } @@ -1220,7 +1219,7 @@ void host_sendto (TrapContext *ctx, SB, uae_u32 sd, uae_u32 msg, uae_u8 *hmsg, u if (sb->mtable[sd - 1] || (wMsg = allocasyncmsg(ctx, sb, sd, s)) != 0) { if (sb->mtable[sd - 1] == 0) { - WSAAsyncSelect(s,hWndSelector ? hAmigaWnd : bsd->hSockWnd,wMsg,FD_WRITE); + WSAAsyncSelect(s,hWndSelector ? hAmigaSockWnd : bsd->hSockWnd,wMsg,FD_WRITE); } else { setWSAAsyncSelect(sb, sd, s, FD_WRITE); } @@ -1338,7 +1337,7 @@ void host_recvfrom(TrapContext *ctx, SB, uae_u32 sd, uae_u32 msg, uae_u8 *hmsg, if (sb->sb_errno == WSAEWOULDBLOCK - WSABASEERR && (sb->ftable[sd-1] & SF_BLOCKING)) { if (sb->mtable[sd-1] || (wMsg = allocasyncmsg(ctx, sb,sd,s)) != 0) { if (sb->mtable[sd-1] == 0) { - WSAAsyncSelect(s, hWndSelector ? hAmigaWnd : bsd->hSockWnd, wMsg, FD_READ|FD_CLOSE); + WSAAsyncSelect(s, hWndSelector ? hAmigaSockWnd : bsd->hSockWnd, wMsg, FD_READ|FD_CLOSE); } else { setWSAAsyncSelect(sb, sd, s, FD_READ|FD_CLOSE); } @@ -1459,7 +1458,7 @@ void host_setsockopt(SB, uae_u32 sd, uae_u32 level, uae_u32 optname, uae_u32 opt wsbevents |= FD_CLOSE; if (sb->mtable[sd-1] || (sb->mtable[sd-1] = allocasyncmsg(ctx, sb,sd,s))) { - WSAAsyncSelect(s,hWndSelector ? hAmigaWnd : bsd->hSockWnd,sb->mtable[sd-1],wsbevents); + WSAAsyncSelect(s,hWndSelector ? hAmigaSockWnd : bsd->hSockWnd,sb->mtable[sd-1],wsbevents); sb->resultval = 0; } else sb->resultval = -1; @@ -1653,7 +1652,7 @@ uae_u32 host_IoctlSocket(TrapContext *ctx, SB, uae_u32 sd, uae_u32 request, uae_ BSDTRACE((_T("[FIOASYNC] -> enabled\n"))); if (sb->mtable[sd-1] || (sb->mtable[sd-1] = allocasyncmsg(ctx, sb, sd, s))) { - WSAAsyncSelect(s,hWndSelector ? hAmigaWnd : bsd-> hSockWnd, sb->mtable[sd-1], + WSAAsyncSelect(s,hWndSelector ? hAmigaSockWnd : bsd-> hSockWnd, sb->mtable[sd-1], FD_ACCEPT | FD_CONNECT | FD_OOB | FD_READ | FD_WRITE | FD_CLOSE); success = 0; break; @@ -1710,7 +1709,7 @@ int host_CloseSocket(TrapContext *ctx, SB, int sd) break; if ((wMsg = allocasyncmsg(ctx, sb, sd, s)) != 0) { - WSAAsyncSelect(s,hWndSelector ? hAmigaWnd : bsd->hSockWnd,wMsg,FD_CLOSE); + WSAAsyncSelect(s,hWndSelector ? hAmigaSockWnd : bsd->hSockWnd,wMsg,FD_CLOSE); WAITSIGNAL; @@ -2180,9 +2179,11 @@ uae_u32 host_inet_addr(TrapContext *ctx, uae_u32 cp) int isfullscreen (void); static BOOL CheckOnline(SB) { + struct AmigaMonitor *mon = &AMonitors[0]; DWORD dwFlags; BOOL bReturn = TRUE; + hAmigaSockWnd = mon->hAmigaWnd; if (InternetGetConnectedState(&dwFlags,0) == FALSE) { // Internet is offline if (InternetAttemptConnect(0) != ERROR_SUCCESS) { // Show Dialer window sb->sb_errno = 10001; @@ -2191,8 +2192,8 @@ static BOOL CheckOnline(SB) // No success or aborted } if (isfullscreen() > 0) { - ShowWindow (hAmigaWnd, SW_RESTORE); - SetActiveWindow(hAmigaWnd); + ShowWindow(mon->hAmigaWnd, SW_RESTORE); + SetActiveWindow(mon->hAmigaWnd); } } return bReturn; diff --git a/od-win32/dinput.cpp b/od-win32/dinput.cpp index 5c80322a..8d5aa63f 100644 --- a/od-win32/dinput.cpp +++ b/od-win32/dinput.cpp @@ -412,6 +412,7 @@ static int rawinput_reg; static int doregister_rawinput (bool add) { + struct AmigaMonitor *mon = &AMonitors[0]; int num; RAWINPUTDEVICE rid[2 + 2 + MAX_INPUT_DEVICES] = { 0 }; @@ -428,9 +429,9 @@ static int doregister_rawinput (bool add) if (!add) { rid[num].dwFlags = RIDEV_REMOVE; } else { - if (hMainWnd) { + if (mon->hMainWnd) { rid[num].dwFlags = RIDEV_INPUTSINK; - rid[num].hwndTarget = hMainWnd; + rid[num].hwndTarget = mon->hMainWnd; } rid[num].dwFlags |= (os_vista ? RIDEV_DEVNOTIFY : 0); } @@ -443,9 +444,9 @@ static int doregister_rawinput (bool add) if (!add) { rid[num].dwFlags = RIDEV_REMOVE; } else { - if (hMainWnd) { + if (mon->hMainWnd) { rid[num].dwFlags = RIDEV_INPUTSINK; - rid[num].hwndTarget = hMainWnd; + rid[num].hwndTarget = mon->hMainWnd; } rid[num].dwFlags |= RIDEV_NOHOTKEYS | (os_vista ? RIDEV_DEVNOTIFY : 0); } @@ -460,9 +461,9 @@ static int doregister_rawinput (bool add) if (!add) { rid[num].dwFlags = RIDEV_REMOVE; } else { - if (hMainWnd) { + if (mon->hMainWnd) { rid[num].dwFlags = RIDEV_INPUTSINK; - rid[num].hwndTarget = hMainWnd; + rid[num].hwndTarget = mon->hMainWnd; } rid[num].dwFlags |= (os_vista ? RIDEV_DEVNOTIFY : 0); } @@ -474,9 +475,9 @@ static int doregister_rawinput (bool add) if (!add) { rid[num].dwFlags = RIDEV_REMOVE; } else { - if (hMainWnd) { + if (mon->hMainWnd) { rid[num].dwFlags = RIDEV_INPUTSINK; - rid[num].hwndTarget = hMainWnd; + rid[num].hwndTarget = mon->hMainWnd; } rid[num].dwFlags |= (os_vista ? RIDEV_DEVNOTIFY : 0); } @@ -2212,9 +2213,9 @@ static void handle_rawinput_2 (RAWINPUT *raw) if (did->buttons >= 3 && (rm->usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_DOWN)) { if (currprefs.input_mouse_untrap & MOUSEUNTRAP_MIDDLEBUTTON) { if ((isfullscreen() < 0 && currprefs.win32_minimize_inactive) || isfullscreen() > 0) - minimizewindow (); + minimizewindow(0); if (mouseactive) - setmouseactive (0); + setmouseactive(0, 0); } } } @@ -2750,12 +2751,13 @@ static int acquire (LPDIRECTINPUTDEVICE8 lpdi, TCHAR *txt) static int setcoop (struct didata *did, DWORD mode, TCHAR *txt) { + struct AmigaMonitor *mon = &AMonitors[0]; HRESULT hr = DI_OK; HWND hwnd; int test = inputdevice_istest (); if (!test) - hwnd = hMainWnd; + hwnd = mon->hMainWnd; else hwnd = hGUIWnd; @@ -3556,9 +3558,9 @@ static void read_mouse (void) } if (!istest && isfocus () && (currprefs.input_mouse_untrap & MOUSEUNTRAP_MIDDLEBUTTON) && dimofs == DIMOFS_BUTTON2 && state) { if ((isfullscreen() < 0 && currprefs.win32_minimize_inactive) || isfullscreen() > 0) - minimizewindow (); + minimizewindow(0); if (mouseactive) - setmouseactive (0); + setmouseactive(0, 0); } } } else if (hr == DIERR_INPUTLOST) { @@ -3932,7 +3934,7 @@ static void read_kb (void) IDirectInputDevice8_Poll (lpdi); } #ifdef CATWEASEL - if (isfocus () || istest) { + if (isfocus() || istest) { uae_u8 kc; if (stopoutput == 0 && catweasel_read_keyboard (&kc)) inputdevice_do_keyboard (kc & 0x7f, kc & 0x80); diff --git a/od-win32/direct3d.cpp b/od-win32/direct3d.cpp index d4eee60b..399a94ab 100644 --- a/od-win32/direct3d.cpp +++ b/od-win32/direct3d.cpp @@ -175,9 +175,15 @@ struct d3dstruct int ddraw_fs; int ddraw_fs_attempt; LPDIRECTDRAW7 ddraw; + + int slicecnt; + int clearcnt; + bool debugcolors; + bool noclear; + bool cannoclear; }; -static struct d3dstruct d3ddata[1]; +static struct d3dstruct d3ddata[MAX_AMIGAMONITORS]; #define NUMVERTICES 8 #define D3DFVF_TLVERTEX D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1 @@ -1337,6 +1343,10 @@ static void updateleds (struct d3dstruct *d3d) } done = 1; } + + if (d3d != d3ddata) + return; + hr = d3d->ledtexture->LockRect (0, &locked, NULL, D3DLOCK_DISCARD); if (FAILED (hr)) { write_log (_T("%d: SL LockRect failed: %s\n"), D3DHEAD, D3D_ErrorString (hr)); @@ -1345,14 +1355,14 @@ static void updateleds (struct d3dstruct *d3d) for (int y = 0; y < TD_TOTAL_HEIGHT * d3d->statusbar_vx; y++) { uae_u8 *buf = (uae_u8*)locked.pBits + y * locked.Pitch; - statusline_single_erase(buf, 32 / 8, y, d3d->ledwidth * d3d->statusbar_hx); + statusline_single_erase(d3d - d3ddata, buf, 32 / 8, y, d3d->ledwidth * d3d->statusbar_hx); } - statusline_render((uae_u8*)locked.pBits, 32 / 8, locked.Pitch, d3d->ledwidth, d3d->ledheight, rc, gc, bc, a); + statusline_render(d3d - d3ddata, (uae_u8*)locked.pBits, 32 / 8, locked.Pitch, d3d->ledwidth, d3d->ledheight, rc, gc, bc, a); int y = 0; for (int yy = 0; yy < d3d->statusbar_vx * TD_TOTAL_HEIGHT; yy++) { uae_u8 *buf = (uae_u8*)locked.pBits + yy * locked.Pitch; - draw_status_line_single (buf, 32 / 8, y, d3d->ledwidth, rc, gc, bc, a); + draw_status_line_single(d3d - d3ddata, buf, 32 / 8, y, d3d->ledwidth, rc, gc, bc, a); if ((yy % d3d->statusbar_vx) == 0) y++; } @@ -1482,6 +1492,7 @@ static int findedge (D3DLOCKED_RECT *lock, int w, int h, int dx, int dy) static int createmask2texture (struct d3dstruct *d3d, const TCHAR *filename) { + struct AmigaMonitor *mon = &AMonitors[d3d - d3ddata]; struct zfile *zf; int size; uae_u8 *buf; @@ -1494,7 +1505,7 @@ static int createmask2texture (struct d3dstruct *d3d, const TCHAR *filename) d3d->mask2texture->Release(); d3d->mask2texture = NULL; - if (filename[0] == 0 || WIN32GFX_IsPicassoScreen ()) + if (filename[0] == 0 || WIN32GFX_IsPicassoScreen(mon)) return 0; zf = NULL; @@ -1767,17 +1778,19 @@ end: return 0; } -static bool xD3D_getscalerect(float *mx, float *my, float *sx, float *sy) +static bool xD3D_getscalerect(int monid, float *mx, float *my, float *sx, float *sy) { - struct d3dstruct *d3d = &d3ddata[0]; + struct d3dstruct *d3d = &d3ddata[monid]; + struct vidbuf_description *vidinfo = &adisplays[monid].gfxvidinfo; + if (!d3d->mask2texture) return false; float mw = d3d->mask2rect.right - d3d->mask2rect.left; float mh = d3d->mask2rect.bottom - d3d->mask2rect.top; - float mxt = (float)mw / gfxvidinfo.outbuffer->inwidth2; - float myt = (float)mh / gfxvidinfo.outbuffer->inheight2; + float mxt = (float)mw / vidinfo->outbuffer->inwidth2; + float myt = (float)mh / vidinfo->outbuffer->inheight2; *mx = d3d->mask2texture_minusx / mxt; *my = d3d->mask2texture_minusy / myt; @@ -1793,23 +1806,25 @@ static bool xD3D_getscalerect(float *mx, float *my, float *sx, float *sy) static void setupscenecoords (struct d3dstruct *d3d) { + int monid = d3d - d3ddata; + struct vidbuf_description *vidinfo = &adisplays[monid].gfxvidinfo; RECT sr, dr, zr; float w, h; float dw, dh; - static RECT sr2, dr2, zr2; + static RECT sr2[MAX_AMIGAMONITORS], dr2[MAX_AMIGAMONITORS], zr2[MAX_AMIGAMONITORS]; //write_log (_T("%dx%d %dx%d %dx%d\n"), tin_w, tin_h, tin_w, tin_h, window_w, window_h); - getfilterrect2 (&dr, &sr, &zr, d3d->window_w, d3d->window_h, d3d->tin_w / d3d->dmult, d3d->tin_h / d3d->dmult, d3d->dmult, d3d->tin_w, d3d->tin_h); + getfilterrect2 (monid, &dr, &sr, &zr, d3d->window_w, d3d->window_h, d3d->tin_w / d3d->dmult, d3d->tin_h / d3d->dmult, d3d->dmult, d3d->tin_w, d3d->tin_h); - if (memcmp (&sr, &sr2, sizeof RECT) || memcmp (&dr, &dr2, sizeof RECT) || memcmp (&zr, &zr2, sizeof RECT)) { + if (memcmp (&sr, &sr2[monid], sizeof RECT) || memcmp (&dr, &dr2[monid], sizeof RECT) || memcmp (&zr, &zr2[monid], sizeof RECT)) { write_log (_T("POS (%d %d %d %d) - (%d %d %d %d)[%d,%d] (%d %d)\n"), dr.left, dr.top, dr.right, dr.bottom, sr.left, sr.top, sr.right, sr.bottom, sr.right - sr.left, sr.bottom - sr.top, zr.left, zr.top); - sr2 = sr; - dr2 = dr; - zr2 = zr; + sr2[monid] = sr; + dr2[monid] = dr; + zr2[monid] = zr; } dw = dr.right - dr.left; @@ -1838,12 +1853,12 @@ static void setupscenecoords (struct d3dstruct *d3d) float xshift = -zr.left; float yshift = -zr.top; - sw = dw * d3d->tin_w / gfxvidinfo.outbuffer->inwidth2; + sw = dw * d3d->tin_w / vidinfo->outbuffer->inwidth2; sw *= mw / d3d->window_w; tx = -0.5f + d3d->window_w / 2; - sh = dh * d3d->tin_h / gfxvidinfo.outbuffer->inheight2; + sh = dh * d3d->tin_h / vidinfo->outbuffer->inheight2; sh *= mh / d3d->window_h; ty = +0.5f + d3d->window_h / 2; @@ -1897,7 +1912,8 @@ static void setupscenecoords (struct d3dstruct *d3d) D3DXMatrixMultiply (&d3d->postproj, &tmpmatrix, &d3d->m_matProj_out); } -uae_u8 *getfilterbuffer3d (struct vidbuffer *vb, int *widthp, int *heightp, int *pitch, int *depth) +#if 0 +uae_u8 *getfilterbuffer3d(struct vidbuffer *vb, int *widthp, int *heightp, int *pitch, int *depth) { struct d3dstruct *d3d = &d3ddata[0]; RECT dr, sr, zr; @@ -1916,6 +1932,7 @@ uae_u8 *getfilterbuffer3d (struct vidbuffer *vb, int *widthp, int *heightp, int *heightp = h; return p; } +#endif static void createvertex (struct d3dstruct *d3d) { @@ -2234,9 +2251,9 @@ static void D3D_free2 (struct d3dstruct *d3d) currprefs.leds_on_screen &= ~STATUSLINE_TARGET; } -void xD3D_free (bool immediate) +void xD3D_free (int monid, bool immediate) { - struct d3dstruct *d3d = &d3ddata[0]; + struct d3dstruct *d3d = &d3ddata[monid]; if (!fakemodewaitms || immediate) { waitfakemode (d3d); D3D_free2 (d3d); @@ -2309,6 +2326,8 @@ static int getd3dadapter (IDirect3D9 *id3d) static const TCHAR *D3D_init2 (struct d3dstruct *d3d, HWND ahwnd, int w_w, int w_h, int depth, int *freq, int mmult) { + int monid = d3d - d3ddata; + struct amigadisplay *ad = &adisplays[monid]; HRESULT ret, hr; static TCHAR errmsg[300] = { 0 }; D3DDISPLAYMODE mode = { 0 }; @@ -2319,11 +2338,11 @@ static const TCHAR *D3D_init2 (struct d3dstruct *d3d, HWND ahwnd, int w_w, int w typedef HRESULT (WINAPI *LPDIRECT3DCREATE9EX)(UINT, IDirect3D9Ex**); LPDIRECT3DCREATE9EX d3dexp = NULL; int vsync = isvsync (); - struct apmode *apm = picasso_on ? &currprefs.gfx_apmode[APMODE_RTG] : &currprefs.gfx_apmode[APMODE_NATIVE]; + struct apmode *apm = ad->picasso_on ? &currprefs.gfx_apmode[APMODE_RTG] : &currprefs.gfx_apmode[APMODE_NATIVE]; struct apmode ap; D3DADAPTER_IDENTIFIER9 did; - filterd3didx = picasso_on; + filterd3didx = ad->picasso_on; filterd3d = &currprefs.gf[filterd3didx]; D3D_free2 (d3d); @@ -2377,7 +2396,7 @@ static const TCHAR *D3D_init2 (struct d3dstruct *d3d, HWND ahwnd, int w_w, int w d3d->d3dex = NULL; d3d->d3d = Direct3DCreate9 (D3D_SDK_VERSION); if (d3d->d3d == NULL) { - D3D_free (true); + D3D_free(monid, true); _tcscpy (errmsg, _T("Direct3D: failed to create D3D object")); return errmsg; } @@ -2413,7 +2432,8 @@ static const TCHAR *D3D_init2 (struct d3dstruct *d3d, HWND ahwnd, int w_w, int w xfree (s); } - d3d->variablerefresh = ap.gfx_vsync < 0; + d3d->variablerefresh = false; + d3d->cannoclear = ap.gfx_vsyncmode != 0; memset (&d3d->dpp, 0, sizeof (d3d->dpp)); d3d->dpp.Windowed = isfullscreen () <= 0; @@ -2434,11 +2454,11 @@ static const TCHAR *D3D_init2 (struct d3dstruct *d3d, HWND ahwnd, int w_w, int w d3d->vsync2 = 0; int hzmult = 0; if (isfullscreen () > 0) { - d3d->dpp.FullScreen_RefreshRateInHz = getrefreshrate (d3d->modeex.Width, d3d->modeex.Height); + d3d->dpp.FullScreen_RefreshRateInHz = getrefreshrate(monid, d3d->modeex.Width, d3d->modeex.Height); d3d->modeex.RefreshRate = d3d->dpp.FullScreen_RefreshRateInHz; if (vsync > 0) { d3d->dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; - getvsyncrate (d3d->dpp.FullScreen_RefreshRateInHz, &hzmult); + getvsyncrate(monid, d3d->dpp.FullScreen_RefreshRateInHz, &hzmult); if (hzmult < 0) { if (!ap.gfx_strobo) { if (d3dCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO) @@ -2455,7 +2475,7 @@ static const TCHAR *D3D_init2 (struct d3dstruct *d3d, HWND ahwnd, int w_w, int w if (mode.RefreshRate > 0) { if (vsync > 0) { d3d->dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; - getvsyncrate(mode.RefreshRate, &hzmult); + getvsyncrate(monid, mode.RefreshRate, &hzmult); if (hzmult < 0) { if (!ap.gfx_strobo) { if ((d3dCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO) && isfullscreen() > 0) @@ -2473,7 +2493,7 @@ static const TCHAR *D3D_init2 (struct d3dstruct *d3d, HWND ahwnd, int w_w, int w if (vsync < 0) { d3d->vsync2 = 0; - getvsyncrate (isfullscreen() > 0 ? d3d->dpp.FullScreen_RefreshRateInHz : mode.RefreshRate, &hzmult); + getvsyncrate(monid, isfullscreen() > 0 ? d3d->dpp.FullScreen_RefreshRateInHz : mode.RefreshRate, &hzmult); if (hzmult > 0) { d3d->vsync2 = 1; } else if (hzmult < 0) { @@ -2530,7 +2550,7 @@ static const TCHAR *D3D_init2 (struct d3dstruct *d3d, HWND ahwnd, int w_w, int w write_log (_T("%s\n"), errmsg); write_log (_T("%s: Retrying fullscreen with DirectDraw\n"), D3DHEAD); if (ddraw_fs_hack_init (d3d)) { - const TCHAR *err2 = D3D_init (ahwnd, w_w, w_h, depth, freq, mmult); + const TCHAR *err2 = D3D_init (ahwnd, monid, w_w, w_h, depth, freq, mmult); if (err2) ddraw_fs_hack_free (d3d); return err2; @@ -2539,9 +2559,9 @@ static const TCHAR *D3D_init2 (struct d3dstruct *d3d, HWND ahwnd, int w_w, int w if (d3d->d3d_ex && D3DEX) { write_log (_T("%s\n"), errmsg); D3DEX = 0; - return D3D_init (ahwnd, w_w, w_h, depth, freq, mmult); + return D3D_init(ahwnd, monid, w_w, w_h, depth, freq, mmult); } - D3D_free (true); + D3D_free(monid, true); return errmsg; } @@ -2604,7 +2624,7 @@ static const TCHAR *D3D_init2 (struct d3dstruct *d3d, HWND ahwnd, int w_w, int w write_log (_T("Using non-shader version\n")); d3d->dmultx = mmult; - d3d->dmult = S2X_getmult (); + d3d->dmult = S2X_getmult(d3d - d3ddata); d3d->window_w = w_w; d3d->window_h = w_h; @@ -2644,7 +2664,7 @@ static const TCHAR *D3D_init2 (struct d3dstruct *d3d, HWND ahwnd, int w_w, int w currprefs.leds_on_screen |= STATUSLINE_TARGET; if (!restoredeviceobjects (d3d)) { - D3D_free (true); + D3D_free(monid, true); _stprintf (errmsg, _T("%s: initialization failed."), D3DHEAD); return errmsg; } @@ -2665,10 +2685,13 @@ static const TCHAR *D3D_init2 (struct d3dstruct *d3d, HWND ahwnd, int w_w, int w v = 1; } hr = S_OK; - if (forcedframelatency >= 0) - hr = d3d->d3ddevex->SetMaximumFrameLatency (forcedframelatency); - else if (d3d->dpp.PresentationInterval == D3DPRESENT_INTERVAL_IMMEDIATE && (v > 1 || !vsync)) - hr = d3d->d3ddevex->SetMaximumFrameLatency ((vsync || d3d->variablerefresh) ? (hzmult < 0 && !ap.gfx_strobo && !d3d->variablerefresh ? 2 : 1) : 0); + if (forcedframelatency >= 0) { + hr = d3d->d3ddevex->SetMaximumFrameLatency(forcedframelatency); + } else if (ap.gfx_vsyncmode) { + hr = d3d->d3ddevex->SetMaximumFrameLatency(1); + } else if (d3d->dpp.PresentationInterval == D3DPRESENT_INTERVAL_IMMEDIATE && (v > 1 || !vsync)) { + hr = d3d->d3ddevex->SetMaximumFrameLatency((vsync || d3d->variablerefresh) ? (hzmult < 0 && !ap.gfx_strobo && !d3d->variablerefresh ? 2 : 1) : 0); + } if (FAILED (hr)) write_log (_T("%s: SetMaximumFrameLatency() failed: %s\n"), D3DHEAD, D3D_ErrorString (hr)); } @@ -2724,9 +2747,9 @@ static void *D3D_init_start (void *p) return NULL; } -static const TCHAR *xD3D_init (HWND ahwnd, int w_w, int w_h, int depth, int *freq, int mmult) +static const TCHAR *xD3D_init (HWND ahwnd, int monid, int w_w, int w_h, int depth, int *freq, int mmult) { - struct d3dstruct *d3d = &d3ddata[0]; + struct d3dstruct *d3d = &d3ddata[monid]; if (!fakemodewaitms) return D3D_init2 (d3d, ahwnd, w_w, w_h, depth, freq, mmult); @@ -2750,9 +2773,9 @@ static bool alloctextures (struct d3dstruct *d3d) return true; } -static bool xD3D_alloctexture (int w, int h) +static bool xD3D_alloctexture (int monid, int w, int h) { - struct d3dstruct *d3d = &d3ddata[0]; + struct d3dstruct *d3d = &d3ddata[monid]; d3d->tin_w = w * d3d->dmult; d3d->tin_h = h * d3d->dmult; @@ -2895,16 +2918,16 @@ static void D3D_showframe2 (struct d3dstruct *d3d, bool dowait) } } -static void xD3D_restore (void) +static void xD3D_restore(int monid) { - struct d3dstruct *d3d = &d3ddata[0]; + struct d3dstruct *d3d = &d3ddata[monid]; d3d->renderdisabled = false; } -static void xD3D_clear (void) +static void xD3D_clear (int monid) { - struct d3dstruct *d3d = &d3ddata[0]; + struct d3dstruct *d3d = &d3ddata[monid]; int i; HRESULT hr; @@ -2998,8 +3021,41 @@ pass2: return s->lpTempTexture; } -static void D3D_render2 (struct d3dstruct *d3d) +static int xD3D_debug(int monid, int mode) +{ + struct d3dstruct *d3d = &d3ddata[monid]; + int old = d3d->debugcolors ? 1 : 0; + d3d->debugcolors = (mode & 1) != 0; + d3d->noclear = d3d->debugcolors ? false : true; + d3d->clearcnt = 0; + return old; +} + +static void clearrt(struct d3dstruct *d3d) { + HRESULT hr; + uae_u8 color[4] = { 0, 0, 0, 0 }; + + if (d3d->noclear && d3d->cannoclear) { + if (d3d->clearcnt > 3) + return; + d3d->clearcnt++; + } + + if (!d3d->noclear && d3d->debugcolors && d3d->slicecnt > 0) { + int cnt = d3d->slicecnt - 1; + int v = cnt % 3; + if (cnt / 3 == 1) + color[(v + 1) % 3] = 80; + color[v] = 80; + } + + hr = d3d->d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(color[0], d3ddebug ? 0x80 : color[1], color[2]), 0, 0); +} + +static void D3D_render2(struct d3dstruct *d3d, int mode) +{ + struct AmigaMonitor *mon = &AMonitors[d3d - d3ddata]; HRESULT hr; LPDIRECT3DTEXTURE9 srctex = d3d->texture; UINT uPasses, uPass; @@ -3007,7 +3063,14 @@ static void D3D_render2 (struct d3dstruct *d3d) if (!isd3d (d3d) || !d3d->texture) return; - hr = d3d->d3ddev->Clear (0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, d3ddebug ? 0x80 : 0, 0), 0, 0); + if (mode > 0) + d3d->slicecnt = 0; + else if (mode < 0) + d3d->slicecnt = d3d->slicecnt == 2 ? 0 : d3d->slicecnt; + + clearrt(d3d); + + d3d->slicecnt++; if (FAILED (hr = d3d->d3ddev->BeginScene ())) { write_log (_T("%s: BeginScene: %s\n"), D3DHEAD, D3D_ErrorString (hr)); @@ -3276,9 +3339,9 @@ static void D3D_render2 (struct d3dstruct *d3d) } } - if (d3d->ledtexture && (((currprefs.leds_on_screen & STATUSLINE_RTG) && WIN32GFX_IsPicassoScreen ()) || ((currprefs.leds_on_screen & STATUSLINE_CHIPSET) && !WIN32GFX_IsPicassoScreen ()))) { + if (d3d->ledtexture && (((currprefs.leds_on_screen & STATUSLINE_RTG) && WIN32GFX_IsPicassoScreen(mon)) || ((currprefs.leds_on_screen & STATUSLINE_CHIPSET) && !WIN32GFX_IsPicassoScreen(mon)))) { int slx, sly; - statusline_getpos (&slx, &sly, d3d->window_w, d3d->window_h, d3d->statusbar_hx, d3d->statusbar_vx); + statusline_getpos(d3d - d3ddata, &slx, &sly, d3d->window_w, d3d->window_h, d3d->statusbar_hx, d3d->statusbar_vx); v.x = slx; v.y = sly; v.z = 0; @@ -3293,9 +3356,9 @@ static void D3D_render2 (struct d3dstruct *d3d) write_log (_T("%s: EndScene() %s\n"), D3DHEAD, D3D_ErrorString (hr)); } -static bool xD3D_setcursor (int x, int y, int width, int height, bool visible, bool noscale) +static bool xD3D_setcursor(int monid, int x, int y, int width, int height, bool visible, bool noscale) { - struct d3dstruct *d3d = &d3ddata[0]; + struct d3dstruct *d3d = &d3ddata[monid]; if (width < 0 || height < 0) return true; @@ -3314,9 +3377,9 @@ static bool xD3D_setcursor (int x, int y, int width, int height, bool visible, b return true; } -static void xD3D_unlocktexture (void) +static void xD3D_unlocktexture(int monid, int y_start, int y_end) { - struct d3dstruct *d3d = &d3ddata[0]; + struct d3dstruct *d3d = &d3ddata[monid]; HRESULT hr; if (!isd3d (d3d) || !d3d->texture) @@ -3331,9 +3394,9 @@ static void xD3D_unlocktexture (void) d3d->fulllocked = 0; } -static void xD3D_flushtexture (int miny, int maxy) +static void xD3D_flushtexture(int monid, int miny, int maxy) { - struct d3dstruct *d3d = &d3ddata[0]; + struct d3dstruct *d3d = &d3ddata[monid]; if (d3d->fakemode || d3d->fulllocked || !d3d->texture || d3d->renderdisabled) return; @@ -3353,9 +3416,9 @@ static void xD3D_flushtexture (int miny, int maxy) } } -static uae_u8 *xD3D_locktexture (int *pitch, int *height, bool fullupdate) +static uae_u8 *xD3D_locktexture (int monid, int *pitch, int *height, bool fullupdate) { - struct d3dstruct *d3d = &d3ddata[0]; + struct d3dstruct *d3d = &d3ddata[monid]; D3DLOCKED_RECT lock; HRESULT hr; @@ -3385,7 +3448,7 @@ static uae_u8 *xD3D_locktexture (int *pitch, int *height, bool fullupdate) d3d->locked = 1; if (lock.pBits == NULL || lock.Pitch == 0) { write_log (_T("%s: LockRect returned NULL texture\n"), D3DHEAD); - D3D_unlocktexture (); + D3D_unlocktexture(monid, -1, -1); return NULL; } d3d->fulllocked = fullupdate; @@ -3416,9 +3479,9 @@ static void flushgpu (struct d3dstruct *d3d, bool wait) } } -static bool xD3D_renderframe (bool immediate) +static bool xD3D_renderframe(int monid, int mode, bool immediate) { - struct d3dstruct *d3d = &d3ddata[0]; + struct d3dstruct *d3d = &d3ddata[monid]; static int vsync2_cnt; d3d->frames_since_init++; @@ -3449,15 +3512,15 @@ static bool xD3D_renderframe (bool immediate) return true; } - D3D_render2 (d3d); + D3D_render2 (d3d, mode); flushgpu (d3d, immediate); return true; } -static void xD3D_showframe (void) +static void xD3D_showframe (int monid) { - struct d3dstruct *d3d = &d3ddata[0]; + struct d3dstruct *d3d = &d3ddata[monid]; if (!isd3d (d3d)) return; @@ -3478,9 +3541,9 @@ static void xD3D_showframe (void) } } -static void xD3D_showframe_special (int mode) +static void xD3D_showframe_special (int monid, int mode) { - struct d3dstruct *d3d = &d3ddata[0]; + struct d3dstruct *d3d = &d3ddata[monid]; HRESULT hr; if (!isd3d (d3d)) @@ -3494,15 +3557,15 @@ static void xD3D_showframe_special (int mode) flushgpu (d3d,true); } -static void xD3D_refresh (void) +static void xD3D_refresh (int monid) { - struct d3dstruct *d3d = &d3ddata[0]; + struct d3dstruct *d3d = &d3ddata[monid]; if (!isd3d (d3d)) return; - D3D_render2 (d3d); + D3D_render2 (d3d, true); D3D_showframe2 (d3d, true); - D3D_render2 (d3d); + D3D_render2 (d3d, true); D3D_showframe2 (d3d, true); createscanlines (d3d, 0); } @@ -3547,9 +3610,9 @@ void D3D_getpixelformat (int depth, int *rb, int *gb, int *bb, int *rs, int *gs, } } -static double xD3D_getrefreshrate (void) +static float xD3D_getrefreshrate(int monid) { - struct d3dstruct *d3d = &d3ddata[0]; + struct d3dstruct *d3d = &d3ddata[monid]; HRESULT hr; D3DDISPLAYMODE dmode; @@ -3562,9 +3625,9 @@ static double xD3D_getrefreshrate (void) return dmode.RefreshRate; } -static void xD3D_guimode (int guion) +static void xD3D_guimode(int monid, int guion) { - struct d3dstruct *d3d = &d3ddata[0]; + struct d3dstruct *d3d = &d3ddata[monid]; HRESULT hr; if (guion != 0 && guion != 1) @@ -3573,7 +3636,7 @@ static void xD3D_guimode (int guion) waitfakemode (d3d); if (!isd3d (d3d)) return; - D3D_render2(d3d); + D3D_render2(d3d, true); D3D_showframe2(d3d, true); hr = d3d->d3ddev->SetDialogBoxMode (guion ? TRUE : FALSE); if (FAILED (hr)) @@ -3581,9 +3644,9 @@ static void xD3D_guimode (int guion) d3d->guimode = guion; } -LPDIRECT3DSURFACE9 D3D_capture(int *w, int *h, int *bits) +LPDIRECT3DSURFACE9 D3D_capture(int monid, int *w, int *h, int *bits) { - struct d3dstruct *d3d = &d3ddata[0]; + struct d3dstruct *d3d = &d3ddata[monid]; LPDIRECT3DSURFACE9 rt; HRESULT hr; @@ -3607,9 +3670,9 @@ LPDIRECT3DSURFACE9 D3D_capture(int *w, int *h, int *bits) return d3d->screenshotsurface; } -static HDC xD3D_getDC (HDC hdc) +static HDC xD3D_getDC(int monid, HDC hdc) { - struct d3dstruct *d3d = &d3ddata[0]; + struct d3dstruct *d3d = &d3ddata[monid]; static LPDIRECT3DSURFACE9 bb; HRESULT hr; @@ -3636,15 +3699,15 @@ static HDC xD3D_getDC (HDC hdc) return 0; } -static int xD3D_isenabled(void) +static int xD3D_isenabled(int monid) { - struct d3dstruct *d3d = &d3ddata[0]; + struct d3dstruct *d3d = &d3ddata[monid]; return d3d->d3d_enabled ? 1 : 0; } -static uae_u8 *xD3D_setcursorsurface(int *pitch) +static uae_u8 *xD3D_setcursorsurface(int monid, int *pitch) { - struct d3dstruct *d3d = &d3ddata[0]; + struct d3dstruct *d3d = &d3ddata[monid]; if (pitch) { D3DLOCKED_RECT locked; HRESULT hr = d3d->cursorsurfaced3d->LockRect(0, &locked, NULL, 0); @@ -3678,14 +3741,13 @@ void d3d9_select(void) D3D_goodenough = xD3D_goodenough; D3D_setcursor = xD3D_setcursor; D3D_setcursorsurface = xD3D_setcursorsurface; - D3D_getvblankpos = xD3D_getvblankpos; D3D_getrefreshrate = xD3D_getrefreshrate; - D3D_vblank_reset = xD3D_vblank_reset; D3D_restore = xD3D_restore; D3D_resize = NULL; D3D_change = NULL; D3D_getscalerect = xD3D_getscalerect; D3D_run = NULL; + D3D_debug = xD3D_debug; } #endif diff --git a/od-win32/direct3d.h b/od-win32/direct3d.h index d71fb0ea..3c623c8b 100644 --- a/od-win32/direct3d.h +++ b/od-win32/direct3d.h @@ -1,33 +1,32 @@ -extern void(*D3D_free)(bool immediate); -extern const TCHAR* (*D3D_init)(HWND ahwnd, int w_w, int h_h, int depth, int *freq, int mmult); -extern bool(*D3D_alloctexture)(int, int); -extern void(*D3D_refresh)(void); -extern bool(*D3D_renderframe)(bool); -extern void(*D3D_showframe)(void); -extern void(*D3D_showframe_special)(int); -extern uae_u8* (*D3D_locktexture)(int*, int*, bool); -extern void(*D3D_unlocktexture)(void); -extern void(*D3D_flushtexture)(int miny, int maxy); -extern void(*D3D_guimode)(int); -extern HDC(*D3D_getDC)(HDC hdc); -extern int(*D3D_isenabled)(void); -extern void(*D3D_clear)(void); +extern void(*D3D_free)(int, bool immediate); +extern const TCHAR* (*D3D_init)(HWND ahwnd, int, int w_w, int h_h, int depth, int *freq, int mmult); +extern bool(*D3D_alloctexture)(int, int, int); +extern void(*D3D_refresh)(int); +extern bool(*D3D_renderframe)(int, int,bool); +extern void(*D3D_showframe)(int); +extern void(*D3D_showframe_special)(int, int); +extern uae_u8* (*D3D_locktexture)(int, int*, int*, bool); +extern void(*D3D_unlocktexture)(int, int, int); +extern void(*D3D_flushtexture)(int, int miny, int maxy); +extern void(*D3D_guimode)(int, int); +extern HDC(*D3D_getDC)(int, HDC hdc); +extern int(*D3D_isenabled)(int); +extern void(*D3D_clear)(int); extern int(*D3D_canshaders)(void); extern int(*D3D_goodenough)(void); -extern bool(*D3D_setcursor)(int x, int y, int width, int height, bool visible, bool noscale); -extern uae_u8* (*D3D_setcursorsurface)(int *pitch); -extern bool(*D3D_getvblankpos)(int *vpos); -extern double(*D3D_getrefreshrate)(void); -extern void(*D3D_vblank_reset)(double freq); -extern void(*D3D_restore)(void); -extern void(*D3D_resize)(int); -extern void(*D3D_change)(int); -extern bool(*D3D_getscalerect)(float *mx, float *my, float *sx, float *sy); -extern void(*D3D_run)(void); +extern bool(*D3D_setcursor)(int, int x, int y, int width, int height, bool visible, bool noscale); +extern uae_u8* (*D3D_setcursorsurface)(int, int *pitch); +extern float(*D3D_getrefreshrate)(int); +extern void(*D3D_restore)(int); +extern void(*D3D_resize)(int, int); +extern void(*D3D_change)(int, int); +extern bool(*D3D_getscalerect)(int, float *mx, float *my, float *sx, float *sy); +extern void(*D3D_run)(int); +extern int(*D3D_debug)(int, int); -extern LPDIRECT3DSURFACE9 D3D_capture(int*,int*,int*); -extern bool D3D11_capture(void**,int*, int*,int*); +extern LPDIRECT3DSURFACE9 D3D_capture(int, int*,int*,int*); +extern bool D3D11_capture(int, void**,int*, int*,int*); void D3D_getpixelformat(int depth, int *rb, int *gb, int *bb, int *rs, int *gs, int *bs, int *ab, int *as, int *a); @@ -35,8 +34,6 @@ void d3d9_select(void); void d3d11_select(void); void d3d_select(struct uae_prefs *p); int can_D3D11(bool checkdevice); -bool d3d11_vsync_isdone(void); -double d3d11_get_hz(void); #define CURSORMAXWIDTH 64 #define CURSORMAXHEIGHT 64 diff --git a/od-win32/direct3d11.cpp b/od-win32/direct3d11.cpp index 0dd619fd..bdd1a8ed 100644 --- a/od-win32/direct3d11.cpp +++ b/od-win32/direct3d11.cpp @@ -37,36 +37,33 @@ using Microsoft::WRL::ComPtr; #include #include -void (*D3D_free)(bool immediate); -const TCHAR* (*D3D_init)(HWND ahwnd, int w_w, int h_h, int depth, int *freq, int mmult); -bool (*D3D_alloctexture)(int, int); -void(*D3D_refresh)(void); -bool(*D3D_renderframe)(bool); -void(*D3D_showframe)(void); -void(*D3D_showframe_special)(int); -uae_u8* (*D3D_locktexture)(int*, int*, bool); -void (*D3D_unlocktexture)(void); -void (*D3D_flushtexture)(int miny, int maxy); -void (*D3D_guimode)(int); -HDC (*D3D_getDC)(HDC hdc); -int (*D3D_isenabled)(void); -void (*D3D_clear)(void); +void (*D3D_free)(int, bool immediate); +const TCHAR* (*D3D_init)(HWND ahwnd, int, int w_w, int h_h, int depth, int *freq, int mmult); +bool (*D3D_alloctexture)(int, int, int); +void(*D3D_refresh)(int); +bool(*D3D_renderframe)(int, int,bool); +void(*D3D_showframe)(int); +void(*D3D_showframe_special)(int, int); +uae_u8* (*D3D_locktexture)(int, int*, int*, bool); +void (*D3D_unlocktexture)(int, int, int); +void (*D3D_flushtexture)(int, int miny, int maxy); +void (*D3D_guimode)(int, int); +HDC (*D3D_getDC)(int, HDC hdc); +int (*D3D_isenabled)(int); +void (*D3D_clear)(int); int (*D3D_canshaders)(void); int (*D3D_goodenough)(void); -bool (*D3D_setcursor)(int x, int y, int width, int height, bool visible, bool noscale); -uae_u8* (*D3D_setcursorsurface)(int *pitch); -bool (*D3D_getvblankpos)(int *vpos); -double (*D3D_getrefreshrate)(void); -void (*D3D_vblank_reset)(double freq); -void(*D3D_restore)(void); -void(*D3D_resize)(int); -void (*D3D_change)(int); -bool(*D3D_getscalerect)(float *mx, float *my, float *sx, float *sy); -void(*D3D_run)(void); - -static volatile int vblankthread_mode; +bool (*D3D_setcursor)(int, int x, int y, int width, int height, bool visible, bool noscale); +uae_u8* (*D3D_setcursorsurface)(int, int *pitch); +float (*D3D_getrefreshrate)(int); +void(*D3D_restore)(int); +void(*D3D_resize)(int, int); +void (*D3D_change)(int, int); +bool(*D3D_getscalerect)(int, float *mx, float *my, float *sx, float *sy); +void(*D3D_run)(int); +int(*D3D_debug)(int, int); + static HMODULE hd3d11, hdxgi, hd3dcompiler, dwmapi; -static HANDLE vblankevent; static struct gfx_filterdata *filterd3d; static int filterd3didx; @@ -164,8 +161,6 @@ struct d3d11sprite struct d3d11struct { IDXGISwapChain1 *m_swapChain; - IDXGISwapChain2 *m_swapChain2; - HANDLE FrameLatencyHandle; ID3D11Device *m_device; ID3D11DeviceContext *m_deviceContext; ID3D11RenderTargetView *m_renderTargetView; @@ -232,10 +227,9 @@ struct d3d11struct int framecount; UINT syncinterval; bool flipped; - double vblank; + float vblank; DWM_FRAME_COUNT lastframe; int frames_since_init; - bool needvblankevent; bool resizeretry; bool d3dinit_done; @@ -269,6 +263,12 @@ struct d3d11struct ID3DX11EffectTechnique *technique; ID3DX11EffectPass *effectpass; + bool debugcolors; + bool cannoclear; + bool noclear; + int clearcnt; + int slicecnt; + #ifndef NDEBUG ID3D11InfoQueue *m_debugInfoQueue; ID3D11Debug *m_debug; @@ -298,7 +298,7 @@ struct MatrixBufferType D3DXMATRIX projection; }; -static struct d3d11struct d3d11data[1]; +static struct d3d11struct d3d11data[MAX_AMIGAMONITORS]; typedef HRESULT (WINAPI* CREATEDXGIFACTORY1)(REFIID riid, void **ppFactory); typedef HRESULT (WINAPI* D3DCOMPILEFROMFILE)(LPCWSTR pFileName, @@ -1434,7 +1434,7 @@ static void setupscenecoords(struct d3d11struct *d3d) { RECT sr, dr, zr; - getfilterrect2(&dr, &sr, &zr, d3d->m_screenWidth, d3d->m_screenHeight, d3d->m_bitmapWidth / d3d->dmult, d3d->m_bitmapHeight / d3d->dmult, d3d->dmult, d3d->m_bitmapWidth, d3d->m_bitmapHeight); + getfilterrect2(d3d - d3d11data, &dr, &sr, &zr, d3d->m_screenWidth, d3d->m_screenHeight, d3d->m_bitmapWidth / d3d->dmult, d3d->m_bitmapHeight / d3d->dmult, d3d->dmult, d3d->m_bitmapWidth, d3d->m_bitmapHeight); if (!memcmp(&sr, &d3d->sr2, sizeof RECT) && !memcmp(&dr, &d3d->dr2, sizeof RECT) && !memcmp(&zr, &d3d->zr2, sizeof RECT)) { return; @@ -1506,10 +1506,10 @@ static void updateleds(struct d3d11struct *d3d) done = 1; } - if (!d3d->osd.texture) + if (!d3d->osd.texture || d3d != d3d11data) return; - statusline_getpos(&d3d->osd.x, &d3d->osd.y, d3d->m_screenWidth, d3d->m_screenHeight, d3d->statusbar_hx, d3d->statusbar_vx); + statusline_getpos(d3d - d3d11data, &d3d->osd.x, &d3d->osd.y, d3d->m_screenWidth, d3d->m_screenHeight, d3d->statusbar_hx, d3d->statusbar_vx); hr = d3d->m_deviceContext->Map(d3d->osd.texture, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); if (FAILED(hr)) { @@ -1518,14 +1518,14 @@ static void updateleds(struct d3d11struct *d3d) } for (int y = 0; y < TD_TOTAL_HEIGHT * d3d->statusbar_vx; y++) { uae_u8 *buf = (uae_u8*)map.pData + y * map.RowPitch; - statusline_single_erase(buf, 32 / 8, y, d3d->ledwidth * d3d->statusbar_hx); + statusline_single_erase(d3d - d3d11data, buf, 32 / 8, y, d3d->ledwidth * d3d->statusbar_hx); } - statusline_render((uae_u8*)map.pData, 32 / 8, map.RowPitch, d3d->ledwidth, d3d->ledheight, rc, gc, bc, a); + statusline_render(d3d - d3d11data, (uae_u8*)map.pData, 32 / 8, map.RowPitch, d3d->ledwidth, d3d->ledheight, rc, gc, bc, a); int y = 0; for (int yy = 0; yy < d3d->statusbar_vx * TD_TOTAL_HEIGHT; yy++) { uae_u8 *buf = (uae_u8*)map.pData + yy * map.RowPitch; - draw_status_line_single(buf, 32 / 8, y, d3d->ledwidth, rc, gc, bc, a); + draw_status_line_single(d3d - d3d11data, buf, 32 / 8, y, d3d->ledwidth, rc, gc, bc, a); if ((yy % d3d->statusbar_vx) == 0) y++; } @@ -2274,6 +2274,7 @@ static int findedge(struct uae_image *img, int w, int h, int dx, int dy) static int createmask2texture(struct d3d11struct *d3d, const TCHAR *filename) { + struct AmigaMonitor *mon = &AMonitors[d3d - d3d11data]; struct zfile *zf; TCHAR tmp[MAX_DPATH]; ID3D11Texture2D *tx = NULL; @@ -2282,7 +2283,7 @@ static int createmask2texture(struct d3d11struct *d3d, const TCHAR *filename) freesprite(&d3d->mask2texture); freesprite(&d3d->blanksprite); - if (filename[0] == 0 || WIN32GFX_IsPicassoScreen()) + if (filename[0] == 0 || WIN32GFX_IsPicassoScreen(mon)) return 0; zf = NULL; @@ -2810,10 +2811,11 @@ static bool initd3d(struct d3d11struct *d3d) static void setswapchainmode(struct d3d11struct *d3d, int fs) { - struct apmode *apm = picasso_on ? &currprefs.gfx_apmode[APMODE_RTG] : &currprefs.gfx_apmode[APMODE_NATIVE]; + struct amigadisplay *ad = &adisplays[d3d - d3d11data]; + struct apmode *apm = ad->picasso_on ? &currprefs.gfx_apmode[APMODE_RTG] : &currprefs.gfx_apmode[APMODE_NATIVE]; // It is recommended to always use the tearing flag when it is supported. d3d->swapChainDesc.Flags &= ~DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING; - if (d3d->m_tearingSupport && (d3d->swapChainDesc.SwapEffect == DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL || d3d->swapChainDesc.SwapEffect == DXGI_SWAP_EFFECT_FLIP_DISCARD) && !apm->gfx_vflip && apm->gfx_backbuffers == 0) { + if (d3d->m_tearingSupport && (d3d->swapChainDesc.SwapEffect == DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL || d3d->swapChainDesc.SwapEffect == DXGI_SWAP_EFFECT_FLIP_DISCARD)) { d3d->swapChainDesc.Flags |= DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING; } if (0 && os_win8 > 1 && fs <= 0) { @@ -2942,6 +2944,8 @@ static bool device_error(struct d3d11struct *d3d) static void do_present(struct d3d11struct *d3d, int black) { + struct amigadisplay *ad = &adisplays[d3d - d3d11data]; + struct apmode *apm = ad->picasso_on ? &currprefs.gfx_apmode[APMODE_RTG] : &currprefs.gfx_apmode[APMODE_NATIVE]; HRESULT hr; UINT presentFlags = 0; @@ -2955,16 +2959,13 @@ static void do_present(struct d3d11struct *d3d, int black) d3d->m_deviceContext->ClearRenderTargetView(d3d->m_renderTargetView, color); } - if (d3d->FrameLatencyHandle) { - WaitForSingleObjectEx(d3d->FrameLatencyHandle, 100, TRUE); - } - - struct apmode *apm = picasso_on ? &currprefs.gfx_apmode[APMODE_RTG] : &currprefs.gfx_apmode[APMODE_NATIVE]; int vsync = isvsync(); UINT syncinterval = d3d->vblankintervals; if (d3d->m_tearingSupport && (d3d->swapChainDesc.Flags & DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING)) { - presentFlags |= DXGI_PRESENT_ALLOW_TEARING; - syncinterval = 0; + if (1 || apm->gfx_vsyncmode || d3d - d3d11data > 0 || currprefs.turbo_emulation) { + presentFlags |= DXGI_PRESENT_ALLOW_TEARING; + syncinterval = 0; + } } d3d->flipped = true; if (!vsync) { @@ -2976,6 +2977,7 @@ static void do_present(struct d3d11struct *d3d, int black) syncinterval = 0; } d3d->syncinterval = syncinterval; + hr = d3d->m_swapChain->Present(syncinterval, presentFlags); if (currprefs.turbo_emulation && hr == DXGI_ERROR_WAS_STILL_DRAWING) hr = S_OK; @@ -2987,55 +2989,35 @@ static void do_present(struct d3d11struct *d3d, int black) } write_log(_T("D3D11 Present %08x\n"), hr); } + d3d->slicecnt++; } -static unsigned int __stdcall vblankthread(void *dummy) -{ - struct d3d11struct *d3d = &d3d11data[0]; - - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); - while (vblankthread_mode) { - HRESULT hr = d3d->outputAdapter->WaitForVBlank(); - if (FAILED(hr)) { - Sleep(10); - } else { - SetEvent(vblankevent); - } - d3d->framecount++; - } - vblankthread_mode = -1; - write_log(_T("vblankthread exited\n")); - return 0; -} - -static void initthread(struct d3d11struct *d3d) +static float xD3D_getrefreshrate(int monid) { - unsigned int th; - - if (!vblankthread_mode && d3d->outputAdapter && d3d->needvblankevent) { - vblankevent = CreateEvent(NULL, FALSE, FALSE, NULL); - vblankthread_mode = 1; - _beginthreadex(NULL, 0, vblankthread, 0, 0, &th); + struct d3d11struct *d3d = &d3d11data[monid]; + d3d->lastframe = 0; + if (isfs(d3d) != 0 && d3d->fsSwapChainDesc.RefreshRate.Denominator) { + d3d->vblank = (float)d3d->fsSwapChainDesc.RefreshRate.Numerator / d3d->fsSwapChainDesc.RefreshRate.Denominator; + return d3d->vblank; } -} - -static void freethread(struct d3d11struct *d3d) -{ - if (vblankthread_mode) { - vblankthread_mode = 0; - while (vblankthread_mode == 0) { - Sleep(10); - } - vblankthread_mode = 0; - CloseHandle(vblankevent); - vblankevent = NULL; + if (!pDwmGetCompositionTimingInfo) + return 0; + DWM_TIMING_INFO ti; + ti.cbSize = sizeof ti; + HRESULT hr = pDwmGetCompositionTimingInfo(NULL, &ti); + if (FAILED(hr)) { + write_log(_T("DwmGetCompositionTimingInfo1 %08x\n"), hr); + return 0; } + d3d->vblank = (float)ti.rateRefresh.uiNumerator / ti.rateRefresh.uiDenominator; + return d3d->vblank; } -static int xxD3D11_init2(HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int depth, int *freq, int mmult) +static int xxD3D11_init2(HWND ahwnd, int monid, int w_w, int w_h, int t_w, int t_h, int depth, int *freq, int mmult) { - struct d3d11struct *d3d = &d3d11data[0]; - struct apmode *apm = picasso_on ? &currprefs.gfx_apmode[APMODE_RTG] : &currprefs.gfx_apmode[APMODE_NATIVE]; + struct d3d11struct *d3d = &d3d11data[monid]; + struct amigadisplay *ad = &adisplays[monid]; + struct apmode *apm = ad->picasso_on ? &currprefs.gfx_apmode[APMODE_RTG] : &currprefs.gfx_apmode[APMODE_NATIVE]; HRESULT result; ComPtr factory2; @@ -3049,9 +3031,9 @@ static int xxD3D11_init2(HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int dep DXGI_MODE_DESC1* displayModeList; DXGI_ADAPTER_DESC adapterDesc; - write_log(_T("D3D11 init start. (%d*%d) (%d*%d) RTG=%d Depth=%d.\n"), w_w, w_h, t_w, t_h, picasso_on, depth); + write_log(_T("D3D11 init start. (%d*%d) (%d*%d) RTG=%d Depth=%d.\n"), w_w, w_h, t_w, t_h, ad->picasso_on, depth); - filterd3didx = picasso_on; + filterd3didx = ad->picasso_on; filterd3d = &currprefs.gf[filterd3didx]; d3d->delayedfs = 0; @@ -3174,7 +3156,7 @@ static int xxD3D11_init2(HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int dep ZeroMemory(&d3d->fsSwapChainDesc, sizeof(d3d->fsSwapChainDesc)); - int hz = getrefreshrate(w_w, w_h); + int hz = getrefreshrate(monid, w_w, w_h); // Now go through all the display modes and find the one that matches the screen width and height. // When a match is found store the numerator and denominator of the refresh rate for that monitor. @@ -3196,12 +3178,12 @@ static int xxD3D11_init2(HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int dep write_log(_T("D3D11 found matching fullscreen mode. SLO=%d S=%d. Default refresh rate.\n"), m->ScanlineOrdering, m->Scaling); break; } - if (isfs(d3d) > 0 && m->RefreshRate.Numerator && m->RefreshRate.Denominator) { + if (isfs(d3d) != 0 && m->RefreshRate.Numerator && m->RefreshRate.Denominator) { float mhz = (float)m->RefreshRate.Numerator / m->RefreshRate.Denominator; if ((int)(mhz + 0.5) == hz || (int)(mhz) == hz) { d3d->fsSwapChainDesc.RefreshRate.Denominator = m->RefreshRate.Denominator; d3d->fsSwapChainDesc.RefreshRate.Numerator = m->RefreshRate.Numerator; - write_log(_T("D3D11 found matching fullscreen refresh rate %d/%d=%.2f. SLO=%d\n"), m->RefreshRate.Numerator, m->RefreshRate.Denominator, (float)mhz, m->ScanlineOrdering); + write_log(_T("D3D11 found matching refresh rate %d/%d=%.2f. SLO=%d\n"), m->RefreshRate.Numerator, m->RefreshRate.Denominator, (float)mhz, m->ScanlineOrdering); *freq = hz; break; } @@ -3228,7 +3210,9 @@ static int xxD3D11_init2(HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int dep ffreq = nfreq; d3d->fsSwapChainDesc.RefreshRate.Denominator = m->RefreshRate.Denominator; d3d->fsSwapChainDesc.RefreshRate.Numerator = m->RefreshRate.Numerator; - *freq = nfreq; + if (!currprefs.gfx_variable_sync) { + *freq = nfreq; + } } } write_log(_T("D3D11 Highest freq: %d/%d=%.2f W=%d H=%d\n"), @@ -3248,18 +3232,20 @@ static int xxD3D11_init2(HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int dep } else { d3d->fsSwapChainDesc.RefreshRate.Denominator = md2.RefreshRate.Denominator; d3d->fsSwapChainDesc.RefreshRate.Numerator = md2.RefreshRate.Numerator; - *freq = 0; - if (md2.RefreshRate.Denominator && md2.RefreshRate.Numerator) - *freq = md2.RefreshRate.Numerator / md2.RefreshRate.Denominator; - write_log(_T("D3D11 FindClosestMatchingMode1() %d/%d=%.2f SLO=%d W=%d H=%d\n"), - md2.RefreshRate.Numerator, md2.RefreshRate.Denominator, - (float)md2.RefreshRate.Numerator / md2.RefreshRate.Denominator, md1.ScanlineOrdering, - md2.Width, md2.Height); + if (!currprefs.gfx_variable_sync) { + *freq = 0; + if (md2.RefreshRate.Denominator && md2.RefreshRate.Numerator) + *freq = md2.RefreshRate.Numerator / md2.RefreshRate.Denominator; + write_log(_T("D3D11 FindClosestMatchingMode1() %d/%d=%.2f SLO=%d W=%d H=%d\n"), + md2.RefreshRate.Numerator, md2.RefreshRate.Denominator, + (float)md2.RefreshRate.Numerator / md2.RefreshRate.Denominator, md1.ScanlineOrdering, + md2.Width, md2.Height); + } } } - if (isfs(d3d) <= 0) { - *freq = (int)d3d11_get_hz(); + if (isfs(d3d) <= 0 && !currprefs.gfx_variable_sync) { + *freq = (int)xD3D_getrefreshrate(monid); } // Get the adapter (video card) description. @@ -3370,9 +3356,12 @@ static int xxD3D11_init2(HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int dep d3d->swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; } - d3d->needvblankevent = false; - if (apm->gfx_vsyncmode && isfs(d3d) > 0) { - d3d->needvblankevent = true; + d3d->vblankintervals = 1; + d3d->debugcolors = false; + d3d->cannoclear = false; + if (apm->gfx_vsyncmode) { + d3d->cannoclear = true; + d3d->vblankintervals = 0; } d3d->swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; @@ -3381,11 +3370,10 @@ static int xxD3D11_init2(HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int dep d3d->swapChainDesc.Scaling = (d3d->swapChainDesc.SwapEffect == DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL || d3d->swapChainDesc.SwapEffect == DXGI_SWAP_EFFECT_FLIP_DISCARD) ? DXGI_SCALING_NONE : DXGI_SCALING_STRETCH; - d3d->vblankintervals = 1; d3d->blackscreen = false; if (!apm->gfx_backbuffers) { int hzmult = 0; - getvsyncrate(*freq, &hzmult); + getvsyncrate(monid, *freq, &hzmult); if (hzmult < 0) { if (!apm->gfx_strobo) { if (isfullscreen() > 0) { @@ -3393,19 +3381,22 @@ static int xxD3D11_init2(HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int dep } } else { d3d->blackscreen = true; - d3d->needvblankevent = true; } } } int vsync = isvsync(); - if (vsync) { + if (vsync > 0 && !apm->gfx_vsyncmode) { int hzmult; - getvsyncrate(hz, &hzmult); + getvsyncrate(monid, hz, &hzmult); if (hzmult > 0) { d3d->vblankintervals = hzmult + (d3d->blackscreen ? 0 : 1); } } + if (monid) { + d3d->vblankintervals = 0; + } + // Create the swap chain, Direct3D device, and Direct3D device context. result = factory2->CreateSwapChainForHwnd(d3d->m_device, ahwnd, &d3d->swapChainDesc, isfs(d3d) > 0 ? &d3d->fsSwapChainDesc : NULL, NULL, &d3d->m_swapChain); if (FAILED(result)) { @@ -3413,12 +3404,6 @@ static int xxD3D11_init2(HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int dep return 0; } - d3d->m_swapChain2 = NULL; - if (d3d->swapChainDesc.Flags & DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT) { - result = d3d->m_swapChain->QueryInterface(__uuidof(IDXGISwapChain2), (void**)&d3d->m_swapChain2); - d3d->FrameLatencyHandle = d3d->m_swapChain2->GetFrameLatencyWaitableObject(); - } - IDXGIFactory1 *pFactory = NULL; result = d3d->m_swapChain->GetParent(__uuidof (IDXGIFactory1), (void **)&pFactory); if (SUCCEEDED(result)) { @@ -3431,14 +3416,13 @@ static int xxD3D11_init2(HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int dep d3d->invalidmode = false; d3d->fsmode = 0; - - initthread(d3d); + d3d->clearcnt = 0; write_log(_T("D3D11 %d %08x %08x\n"), d3d->swapChainDesc.BufferCount, d3d->swapChainDesc.Flags, d3d->swapChainDesc.Format); if (isfs(d3d) > 0) - D3D_resize(1); - D3D_resize(0); + D3D_resize(monid, 1); + D3D_resize(monid, 0); write_log(_T("D3D11 init end\n")); return 1; @@ -3538,13 +3522,13 @@ static void freed3d(struct d3d11struct *d3d) write_log(_T("D3D11 freed3d end\n")); } -static void xD3D11_free(bool immediate) +static void xD3D11_free(int monid, bool immediate) { - struct d3d11struct *d3d = &d3d11data[0]; + struct d3d11struct *d3d = &d3d11data[monid]; write_log(_T("D3D11 free start\n")); - freethread(d3d); + //freethread(d3d); freed3d(d3d); @@ -3554,10 +3538,6 @@ static void xD3D11_free(bool immediate) d3d->m_swapChain->Release(); d3d->m_swapChain = NULL; } - if (d3d->m_swapChain2) { - d3d->m_swapChain2->Release(); - d3d->m_swapChain2 = NULL; - } if (d3d->m_deviceContext) { d3d->m_deviceContext->ClearState(); d3d->m_deviceContext->Flush(); @@ -3594,19 +3574,19 @@ static void xD3D11_free(bool immediate) write_log(_T("D3D11 free end\n")); } -static int xxD3D11_init(HWND ahwnd, int w_w, int w_h, int depth, int *freq, int mmult) +static int xxD3D11_init(HWND ahwnd, int monid, int w_w, int w_h, int depth, int *freq, int mmult) { - return xxD3D11_init2(ahwnd, w_w, w_h, w_w, w_h, depth, freq, mmult); + return xxD3D11_init2(ahwnd, monid, w_w, w_h, w_w, w_h, depth, freq, mmult); } -static const TCHAR *xD3D11_init(HWND ahwnd, int w_w, int w_h, int depth, int *freq, int mmult) +static const TCHAR *xD3D11_init(HWND ahwnd, int monid, int w_w, int w_h, int depth, int *freq, int mmult) { if (!can_D3D11(false)) return _T("D3D11 FAILED TO INIT"); - int v = xxD3D11_init(ahwnd, w_w, w_h, depth, freq, mmult); + int v = xxD3D11_init(ahwnd, monid, w_w, w_h, depth, freq, mmult); if (v > 0) return NULL; - xD3D11_free(true); + xD3D11_free(monid, true); if (v <= 0) return _T(""); return _T("D3D11 INITIALIZATION ERROR"); @@ -3806,6 +3786,43 @@ static void renderoverlay(struct d3d11struct *d3d) } } +static int xD3D11_debug(int monid, int mode) +{ + struct d3d11struct *d3d = &d3d11data[monid]; + int old = d3d->debugcolors ? 1 : 0; + d3d->debugcolors = (mode & 1) != 0; + d3d->noclear = d3d->debugcolors ? false : true; + d3d->clearcnt = 0; + return old; +} + +static void clearrt(struct d3d11struct *d3d) +{ + // Setup the color to clear the buffer to. + float color[4]; + color[0] = 0; + color[1] = 0; + color[2] = 0; + color[3] = 0; + + if (d3d->noclear && d3d->cannoclear) { + if (d3d->clearcnt > 3) + return; + d3d->clearcnt++; + } + + if (!d3d->noclear && d3d->debugcolors && d3d->slicecnt > 0) { + int cnt = d3d->slicecnt - 1; + int v = cnt % 3; + if (cnt / 3 == 1) + color[(v + 1) % 3] = 0.3; + color[v] = 0.3; + } + + // Clear the back buffer. + d3d->m_deviceContext->ClearRenderTargetView(d3d->m_renderTargetView, color); +} + static bool renderframe(struct d3d11struct *d3d) { ID3D11ShaderResourceView *empty = NULL; @@ -3874,14 +3891,7 @@ static bool renderframe(struct d3d11struct *d3d) d3d->m_deviceContext->OMSetRenderTargets(1, &d3d->lpPostTempTexture.rt, NULL); } else { d3d->m_deviceContext->OMSetRenderTargets(1, &d3d->m_renderTargetView, NULL); - // Setup the color to clear the buffer to. - float color[4]; - color[0] = 0; - color[1] = 0; - color[2] = 0; - color[3] = 0; - // Clear the back buffer. - d3d->m_deviceContext->ClearRenderTargetView(d3d->m_renderTargetView, color); + clearrt(d3d); } // Now render the prepared buffers with the shader. @@ -3889,13 +3899,7 @@ static bool renderframe(struct d3d11struct *d3d) if (after >= 0) { d3d->m_deviceContext->OMSetRenderTargets(1, &d3d->m_renderTargetView, NULL); - float color[4]; - color[0] = 0; - color[1] = 0; - color[2] = 0; - color[3] = 0; - // Clear the back buffer. - d3d->m_deviceContext->ClearRenderTargetView(d3d->m_renderTargetView, color); + clearrt(d3d); } if (after >= 0) { @@ -4115,17 +4119,24 @@ static bool restore(struct d3d11struct *d3d) static void resizemode(struct d3d11struct *d3d); -static bool xD3D11_renderframe(bool immediate) +static bool xD3D11_renderframe(int monid, int mode, bool immediate) { - struct d3d11struct *d3d = &d3d11data[0]; + struct amigadisplay *ad = &adisplays[monid]; + struct apmode *apm = ad->picasso_on ? &currprefs.gfx_apmode[APMODE_RTG] : &currprefs.gfx_apmode[APMODE_NATIVE]; + struct d3d11struct *d3d = &d3d11data[monid]; d3d->frames_since_init++; + if (mode > 0) + d3d->slicecnt = 0; + else if (mode < 0) + d3d->slicecnt = d3d->slicecnt == 2 ? 0 : d3d->slicecnt; + if (!d3d->m_swapChain) return false; if (d3d->fsmodechange) - D3D_resize(0); + D3D_resize(monid, 0); if (d3d->invalidmode) return false; @@ -4150,16 +4161,18 @@ static bool xD3D11_renderframe(bool immediate) } if (notify) { write_log(_T("D3D11 shader file modification notification.\n")); - D3D_resize(0); + D3D_resize(monid, 0); } } + if (apm->gfx_vsyncmode) + d3d->m_deviceContext->Flush(); return true; } -static void xD3D11_showframe(void) +static void xD3D11_showframe(int monid) { - struct d3d11struct *d3d = &d3d11data[0]; + struct d3d11struct *d3d = &d3d11data[monid]; if (d3d->invalidmode || d3d->delayedfs || !d3d->texture2d || !d3d->d3dinit_done) return; @@ -4169,9 +4182,9 @@ static void xD3D11_showframe(void) EndScene(d3d); } -static void xD3D11_clear(void) +static void xD3D11_clear(int monid) { - struct d3d11struct *d3d = &d3d11data[0]; + struct d3d11struct *d3d = &d3d11data[monid]; if (d3d->invalidmode) return; if (!d3d->m_swapChain) @@ -4187,6 +4200,8 @@ static void xD3D11_clear(void) d3d->m_deviceContext->OMSetRenderTargets(1, &d3d->m_renderTargetView, NULL); // Clear the back buffer. d3d->m_deviceContext->ClearRenderTargetView(d3d->m_renderTargetView, color); + d3d->m_deviceContext->Flush(); + d3d->clearcnt = 0; } @@ -4204,17 +4219,18 @@ static bool xD3D11_quit(struct d3d11struct *d3d) return true; } -static void xD3D11_refresh(void) +static void xD3D11_refresh(int monid) { - struct d3d11struct *d3d = &d3d11data[0]; + struct d3d11struct *d3d = &d3d11data[monid]; if (!d3d->m_swapChain) return; createscanlines(d3d, 0); - if (xD3D11_renderframe(true)) { - xD3D11_showframe(); + if (xD3D11_renderframe(monid, true, true)) { + xD3D11_showframe(monid); } + d3d->clearcnt = 0; } @@ -4237,7 +4253,7 @@ static void D3D11_resize_do(struct d3d11struct *d3d) hr = d3d->m_swapChain->SetFullscreenState(TRUE, d3d->outputAdapter); if (FAILED(hr)) { write_log(_T("SetFullscreenState(TRUE) failed %08X\n"), hr); - toggle_fullscreen(10); + toggle_fullscreen(d3d - d3d11data, 10); } else { d3d->fsmode = 0; } @@ -4257,7 +4273,7 @@ static void D3D11_resize_do(struct d3d11struct *d3d) } resizemode(d3d); - notice_screen_contents_lost(); + notice_screen_contents_lost(d3d - d3d11data); write_log(_T("D3D11 resize exit\n")); } @@ -4274,17 +4290,17 @@ static void recheck(struct d3d11struct *d3d) } if (!d3d->delayedfs) return; - xD3D11_free(d3d); + xD3D11_free(d3d - d3d11data, true); d3d->delayedfs = 0; ShowWindow(d3d->ahwnd, SW_SHOWNORMAL); int freq = 0; - if (!xxD3D11_init2(d3d->ahwnd, d3d->m_screenWidth, d3d->m_screenHeight, d3d->m_bitmapWidth2, d3d->m_bitmapHeight2, 32, &freq, d3d->dmultx)) + if (!xxD3D11_init2(d3d->ahwnd, d3d - d3d11data, d3d->m_screenWidth, d3d->m_screenHeight, d3d->m_bitmapWidth2, d3d->m_bitmapHeight2, 32, &freq, d3d->dmultx)) d3d->invalidmode = true; } -static bool xD3D11_alloctexture(int w, int h) +static bool xD3D11_alloctexture(int monid, int w, int h) { - struct d3d11struct *d3d = &d3d11data[0]; + struct d3d11struct *d3d = &d3d11data[monid]; bool v; recheck(d3d); @@ -4295,7 +4311,7 @@ static bool xD3D11_alloctexture(int w, int h) d3d->m_bitmapHeight = h; d3d->m_bitmapWidth2 = d3d->m_bitmapWidth; d3d->m_bitmapHeight2 = d3d->m_bitmapHeight; - d3d->dmult = S2X_getmult(); + d3d->dmult = S2X_getmult(monid); d3d->m_bitmapWidthX = d3d->m_bitmapWidth * d3d->dmultx; d3d->m_bitmapHeightX = d3d->m_bitmapHeight * d3d->dmultx; @@ -4318,9 +4334,9 @@ static bool xD3D11_alloctexture(int w, int h) return true; } -static uae_u8 *xD3D11_locktexture(int *pitch, int *height, bool fullupdate) +static uae_u8 *xD3D11_locktexture(int monid, int *pitch, int *height, bool fullupdate) { - struct d3d11struct *d3d = &d3d11data[0]; + struct d3d11struct *d3d = &d3d11data[monid]; recheck(d3d); @@ -4341,9 +4357,10 @@ static uae_u8 *xD3D11_locktexture(int *pitch, int *height, bool fullupdate) return (uae_u8*)map.pData; } -static void xD3D11_unlocktexture(void) +static void xD3D11_unlocktexture(int monid, int y_start, int y_end) { - struct d3d11struct *d3d = &d3d11data[0]; + struct AmigaMonitor *mon = &AMonitors[monid]; + struct d3d11struct *d3d = &d3d11data[monid]; if (!d3d->texturelocked || d3d->invalidmode) return; @@ -4351,23 +4368,31 @@ static void xD3D11_unlocktexture(void) d3d->m_deviceContext->Unmap(d3d->texture2dstaging, 0); - bool rtg = WIN32GFX_IsPicassoScreen(); + bool rtg = WIN32GFX_IsPicassoScreen(mon); if (((currprefs.leds_on_screen & STATUSLINE_CHIPSET) && !rtg) || ((currprefs.leds_on_screen & STATUSLINE_RTG) && rtg)) { d3d->osd.enabled = true; updateleds(d3d); } else { d3d->osd.enabled = false; } - - d3d->m_deviceContext->CopyResource(d3d->texture2d, d3d->texture2dstaging); + if (y_start < 0) { + d3d->m_deviceContext->CopyResource(d3d->texture2d, d3d->texture2dstaging); + } else { + D3D11_BOX box = { 0 }; + box.right = d3d->m_bitmapWidth; + box.top = y_start; + box.bottom = y_end; + box.back = 1; + d3d->m_deviceContext->CopySubresourceRegion(d3d->texture2d, 0, 0, y_start, 0, d3d->texture2dstaging, 0, &box); + } } -static void xD3D11_flushtexture(int miny, int maxy) +static void xD3D11_flushtexture(int monid, int miny, int maxy) { - struct d3d11struct *d3d = &d3d11data[0]; + struct d3d11struct *d3d = &d3d11data[monid]; } -static void xD3D11_restore(void) +static void xD3D11_restore(int monid) { } @@ -4385,9 +4410,10 @@ static int xD3D11_goodenough(void) return 1; } -static void xD3D11_change(int temp) +static void xD3D11_change(int monid, int temp) { - struct d3d11struct *d3d = &d3d11data[0]; + struct d3d11struct *d3d = &d3d11data[monid]; + d3d->clearcnt = 0; } static void resizemode(struct d3d11struct *d3d) @@ -4409,21 +4435,21 @@ static void resizemode(struct d3d11struct *d3d) } if (!d3d->invalidmode) { if (!initd3d(d3d)) { - xD3D11_free(true); + xD3D11_free(d3d - d3d11data, true); gui_message(_T("D3D11 Resize failed.")); d3d->invalidmode = true; } else { - xD3D11_alloctexture(d3d->m_bitmapWidth, d3d->m_bitmapHeight); + xD3D11_alloctexture(d3d - d3d11data, d3d->m_bitmapWidth, d3d->m_bitmapHeight); } } write_log(_T("D3D11 resizemode end\n")); } } -static void xD3D11_resize(int activate) +static void xD3D11_resize(int monid, int activate) { static int recursive; - struct d3d11struct *d3d = &d3d11data[0]; + struct d3d11struct *d3d = &d3d11data[monid]; write_log(_T("D3D11_resize %d %d %d (%d)\n"), activate, d3d->fsmodechange, d3d->fsmode, d3d->guimode); @@ -4446,9 +4472,9 @@ static void xD3D11_resize(int activate) d3d->fsresizedo = true; } -static void xD3D11_guimode(int guion) +static void xD3D11_guimode(int monid, int guion) { - struct d3d11struct *d3d = &d3d11data[0]; + struct d3d11struct *d3d = &d3d11data[monid]; d3d->reloadshaders = true; @@ -4458,18 +4484,18 @@ static void xD3D11_guimode(int guion) write_log(_T("fs guimode %d\n"), guion); d3d->guimode = guion; if (guion > 0) { - xD3D11_free(d3d); + xD3D11_free(d3d - d3d11data, true); ShowWindow(d3d->ahwnd, SW_HIDE); } else if (guion == 0) { d3d->delayedfs = 1; - notice_screen_contents_lost(); + notice_screen_contents_lost(monid); } write_log(_T("fs guimode end\n")); } -static int xD3D_isenabled(void) +static int xD3D_isenabled(int monid) { - struct d3d11struct *d3d = &d3d11data[0]; + struct d3d11struct *d3d = &d3d11data[monid]; return d3d->m_device != NULL ? 2 : 0; } @@ -4479,9 +4505,9 @@ static bool xD3D_getvblankpos(int *vp) return false; } -static HDC xD3D_getDC(HDC hdc) +static HDC xD3D_getDC(int monid, HDC hdc) { - struct d3d11struct *d3d = &d3d11data[0]; + struct d3d11struct *d3d = &d3d11data[monid]; IDXGISurface1 *g_pSurface1 = NULL; HRESULT hr; @@ -4509,9 +4535,9 @@ static HDC xD3D_getDC(HDC hdc) } } -bool D3D11_capture(void **data, int *w, int *h, int *pitch) +bool D3D11_capture(int monid, void **data, int *w, int *h, int *pitch) { - struct d3d11struct *d3d = &d3d11data[0]; + struct d3d11struct *d3d = &d3d11data[monid]; HRESULT hr; if (!d3d->screenshottexture) @@ -4546,9 +4572,9 @@ bool D3D11_capture(void **data, int *w, int *h, int *pitch) return false; } -static bool xD3D_setcursor(int x, int y, int width, int height, bool visible, bool noscale) +static bool xD3D_setcursor(int monid, int x, int y, int width, int height, bool visible, bool noscale) { - struct d3d11struct *d3d = &d3d11data[0]; + struct d3d11struct *d3d = &d3d11data[monid]; if (width < 0 || height < 0) return true; @@ -4580,9 +4606,9 @@ static bool xD3D_setcursor(int x, int y, int width, int height, bool visible, bo return true; } -static uae_u8 *xD3D_setcursorsurface(int *pitch) +static uae_u8 *xD3D_setcursorsurface(int monid, int *pitch) { - struct d3d11struct *d3d = &d3d11data[0]; + struct d3d11struct *d3d = &d3d11data[monid]; if (!d3d->hwsprite.texture) return NULL; if (pitch) { @@ -4600,17 +4626,18 @@ static uae_u8 *xD3D_setcursorsurface(int *pitch) } } -static bool xD3D11_getscalerect(float *mx, float *my, float *sx, float *sy) +static bool xD3D11_getscalerect(int monid, float *mx, float *my, float *sx, float *sy) { - struct d3d11struct *d3d = &d3d11data[0]; + struct d3d11struct *d3d = &d3d11data[monid]; + struct vidbuf_description *vidinfo = &adisplays[monid].gfxvidinfo; if (!d3d->mask2texture.enabled) return false; float mw = d3d->mask2rect.right - d3d->mask2rect.left; float mh = d3d->mask2rect.bottom - d3d->mask2rect.top; - float mxt = (float)mw / gfxvidinfo.outbuffer->inwidth2; - float myt = (float)mh / gfxvidinfo.outbuffer->inheight2; + float mxt = (float)mw / vidinfo->outbuffer->inwidth2; + float myt = (float)mh / vidinfo->outbuffer->inheight2; *mx = d3d->mask2texture_minusx / mxt; *my = d3d->mask2texture_minusy / myt; @@ -4624,59 +4651,9 @@ static bool xD3D11_getscalerect(float *mx, float *my, float *sx, float *sy) return true; } -double d3d11_get_hz(void) -{ - struct d3d11struct *d3d = &d3d11data[0]; - d3d->lastframe = 0; - if (isfs(d3d) > 0) { - d3d->vblank = (double)d3d->fsSwapChainDesc.RefreshRate.Numerator / d3d->fsSwapChainDesc.RefreshRate.Denominator; - return d3d->vblank; - } - if (!pDwmGetCompositionTimingInfo) - return 0; - DWM_TIMING_INFO ti; - ti.cbSize = sizeof ti; - HRESULT hr = pDwmGetCompositionTimingInfo(NULL, &ti); - if (FAILED(hr)) { - write_log(_T("DwmGetCompositionTimingInfo1 %08x\n"), hr); - return 0; - } - d3d->vblank = (double)ti.rateRefresh.uiNumerator / ti.rateRefresh.uiDenominator; - return d3d->vblank; -} - -bool d3d11_vsync_isdone(void) -{ - struct d3d11struct *d3d = &d3d11data[0]; - if (d3d->FrameLatencyHandle) { - if (WaitForSingleObject(d3d->FrameLatencyHandle, 0) != WAIT_OBJECT_0) - return false; - } - if (vblankevent) { - if (WaitForSingleObject(vblankevent, 0) == WAIT_OBJECT_0) - return true; - return false; - } - if (!pDwmGetCompositionTimingInfo) - return false; - DWM_TIMING_INFO ti; - ti.cbSize = sizeof ti; - HRESULT hr = pDwmGetCompositionTimingInfo(NULL, &ti); - if (FAILED(hr)) { - write_log(_T("DwmGetCompositionTimingInfo2 %08x\n"), hr); - return false; - } - QPC_TIME qpc = ti.qpcVBlank + ti.qpcRefreshPeriod; - LARGE_INTEGER now; - QueryPerformanceCounter(&now); - if (now.QuadPart >= qpc) { - return true; - } - return false; -} -static void xD3D11_run(void) +static void xD3D11_run(int monid) { - struct d3d11struct *d3d = &d3d11data[0]; + struct d3d11struct *d3d = &d3d11data[monid]; if (xD3D11_quit(d3d)) return; @@ -4706,13 +4683,12 @@ void d3d11_select(void) D3D_goodenough = xD3D11_goodenough; D3D_setcursor = xD3D_setcursor; D3D_setcursorsurface = xD3D_setcursorsurface; - D3D_getvblankpos = xD3D_getvblankpos; - D3D_getrefreshrate = NULL; - D3D_vblank_reset = xD3D11_vblank_reset; + D3D_getrefreshrate = xD3D_getrefreshrate; D3D_resize = xD3D11_resize; D3D_change = xD3D11_change; D3D_getscalerect = xD3D11_getscalerect; D3D_run = xD3D11_run; + D3D_debug = xD3D11_debug; } void d3d_select(struct uae_prefs *p) diff --git a/od-win32/dxwrap.cpp b/od-win32/dxwrap.cpp index 685d17b2..88bcf545 100644 --- a/od-win32/dxwrap.cpp +++ b/od-win32/dxwrap.cpp @@ -33,7 +33,8 @@ HRESULT DirectDraw_GetDisplayMode (void) static LPDIRECTDRAWSURFACE7 getlocksurface (void) { - if (dxdata.backbuffers > 0 && currprefs.gfx_apmode[APMODE_NATIVE].gfx_fullscreen > 0 && !WIN32GFX_IsPicassoScreen ()) + struct AmigaMonitor *mon = &AMonitors[0]; + if (dxdata.backbuffers > 0 && currprefs.gfx_apmode[APMODE_NATIVE].gfx_fullscreen > 0 && !WIN32GFX_IsPicassoScreen(mon)) return dxdata.flipping[0]; return dxdata.secondary; } @@ -332,10 +333,11 @@ static void createstatussurface (void) HRESULT DirectDraw_CreateMainSurface (int width, int height) { + struct AmigaMonitor *mon = &AMonitors[0]; HRESULT ddrval; DDSURFACEDESC2 desc = { 0 }; LPDIRECTDRAWSURFACE7 surf; - struct apmode *ap = WIN32GFX_IsPicassoScreen () ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0]; + struct apmode *ap = WIN32GFX_IsPicassoScreen(mon) ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0]; width = (width + 7) & ~7; desc.dwSize = sizeof (desc); @@ -424,7 +426,7 @@ HRESULT DirectDraw_SetDisplayMode (int width, int height, int bits, int freq) dxdata.depth == bits && dxdata.freq == freq) return DD_OK; - getvsyncrate (freq, &dxdata.vblank_skip); + getvsyncrate(0, freq, &dxdata.vblank_skip); dxdata.vblank_skip_cnt = 0; ddrval = IDirectDraw7_SetDisplayMode (dxdata.maindd, width, height, bits, freq, 0); if (FAILED (ddrval)) { @@ -709,6 +711,7 @@ HRESULT DirectDraw_FlipToGDISurface (void) int DirectDraw_BlitToPrimaryScale (RECT *dstrect, RECT *srcrect) { + struct AmigaMonitor *mon = &AMonitors[0]; LPDIRECTDRAWSURFACE7 dst; int result = 0; HRESULT ddrval; @@ -720,7 +723,7 @@ int DirectDraw_BlitToPrimaryScale (RECT *dstrect, RECT *srcrect) dstrect = &dstrect2; SetRect (dstrect, x, y, x + w, y + h); } - centerdstrect (dstrect); + centerdstrect(mon, dstrect); while (FAILED (ddrval = IDirectDrawSurface7_Blt (dst, dstrect, dxdata.secondary, srcrect, DDBLT_WAIT, NULL))) { if (ddrval == DDERR_SURFACELOST) { ddrval = restoresurfacex (dst, dxdata.secondary); @@ -742,6 +745,7 @@ int DirectDraw_BlitToPrimaryScale (RECT *dstrect, RECT *srcrect) static int DirectDraw_BlitToPrimary2 (RECT *rect, int dooffset) { + struct AmigaMonitor *mon = &AMonitors[0]; LPDIRECTDRAWSURFACE7 dst; int result = 0; HRESULT ddrval; @@ -764,7 +768,7 @@ static int DirectDraw_BlitToPrimary2 (RECT *rect, int dooffset) SetRect (&srcrect, x, y, x + w, y + h); SetRect (&dstrect, x, y, x + w, y + h); if (rect || dooffset) - centerdstrect (&dstrect); + centerdstrect(mon, &dstrect); while (FAILED(ddrval = IDirectDrawSurface7_Blt (dst, &dstrect, dxdata.secondary, &srcrect, DDBLT_WAIT, NULL))) { if (ddrval == DDERR_SURFACELOST) { ddrval = restoresurfacex (dst, dxdata.secondary); @@ -909,12 +913,13 @@ void DirectDraw_FillPrimary (void) static void flip (void) { + struct AmigaMonitor *mon = &AMonitors[0]; int result = 0; HRESULT ddrval = DD_OK; DWORD flags = 0; // Why did I put DDFLIP_DONOTWAIT here? int vsync = isvsync (); bool novsync = false; - struct apmode *ap = WIN32GFX_IsPicassoScreen () ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0]; + struct apmode *ap = WIN32GFX_IsPicassoScreen(mon) ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0]; if (currprefs.turbo_emulation || !ap->gfx_vflip) { novsync = true; @@ -1327,7 +1332,7 @@ bool DD_getvblankpos (int *vpos) void DD_vblank_reset (double freq) { - getvsyncrate (freq, &dxdata.vblank_skip); + getvsyncrate(0, freq, &dxdata.vblank_skip); dxdata.vblank_skip_cnt = 0; dx_check (); if ((dxdata.primary == NULL && dxdata.fsmodeset > 0) || dxdata.islost || !dxdata.maindd) diff --git a/od-win32/dxwrap.h b/od-win32/dxwrap.h index 240b5d25..fb3cd4f6 100644 --- a/od-win32/dxwrap.h +++ b/od-win32/dxwrap.h @@ -4,6 +4,7 @@ #include "rtgmodes.h" #include #include +#include #define MAX_DISPLAYS 10 @@ -78,9 +79,62 @@ struct MultiDisplay { struct PicassoResolution *DisplayModes; RECT rect; RECT workrect; + LUID AdapterLuid; + UINT VidPnSourceId; + UINT AdapterHandle; }; extern struct MultiDisplay Displays[MAX_DISPLAYS + 1]; +extern int amigamonid; + +struct winuae_currentmode { + unsigned int flags; + int native_width, native_height, native_depth, pitch; + int current_width, current_height, current_depth; + int amiga_width, amiga_height; + int initdone; + int fullfill; + int vsync; + int freq; +}; + +#define MAX_AMIGAMONITORS 4 +struct AmigaMonitor { + int monitor_id; + HWND hAmigaWnd; + HWND hMainWnd; + + RECT amigawin_rect, mainwin_rect; + RECT amigawinclip_rect; + int window_extra_width, window_extra_height; + int win_x_diff, win_y_diff; + int setcursoroffset_x, setcursoroffset_y; + int mouseposx, mouseposy; + int windowmouse_max_w; + int windowmouse_max_h; + int prevsbheight; + bool render_ok, wait_render; + + int in_sizemove; + int manual_painting_needed; + int minimized; + int screen_is_picasso; + int screen_is_initialized; + int scalepicasso; + bool rtg_locked; + int p96_double_buffer_firstx, p96_double_buffer_lastx; + int p96_double_buffer_first, p96_double_buffer_last; + int p96_double_buffer_needs_flushing; + + HWND hStatusWnd; + HBRUSH hStatusBkgB; + + struct winuae_currentmode currentmode; + struct uae_filter *usedfilter; +}; +extern struct AmigaMonitor *amon; +extern struct AmigaMonitor AMonitors[MAX_AMIGAMONITORS]; + typedef enum { red_mask, diff --git a/od-win32/keyboard_win32.cpp b/od-win32/keyboard_win32.cpp index 8d469cba..7d749cdd 100644 --- a/od-win32/keyboard_win32.cpp +++ b/od-win32/keyboard_win32.cpp @@ -431,8 +431,12 @@ bool my_kbd_handler (int keyboard, int scancode, int newstate, bool alwaysreleas code = AKS_QUIT; if (scancode == DIK_F9 && specialpressed ()) { - if (newstate) - toggle_rtg (MAX_RTG_BOARDS + 1); + extern bool toggle_3d_debug(void); + if (newstate) { + if (!toggle_3d_debug()) { + toggle_rtg(0, MAX_RTG_BOARDS + 1); + } + } return true; } diff --git a/od-win32/parser.cpp b/od-win32/parser.cpp index 87aae457..523ae2d4 100644 --- a/od-win32/parser.cpp +++ b/od-win32/parser.cpp @@ -1349,10 +1349,10 @@ int flashscreen; void doflashscreen (void) { flashscreen = 10; - init_colors (); - picasso_refresh (); + init_colors(0); + picasso_refresh(0); reset_drawing (); - flush_screen (gfxvidinfo.outbuffer, 0, 0); + //flush_screen (gfxvidinfo.outbuffer, 0, 0); } void hsyncstuff (void) @@ -1385,10 +1385,10 @@ void hsyncstuff (void) if (flashscreen > 0) { flashscreen--; if (flashscreen == 0) { - init_colors (); + init_colors(0); reset_drawing (); - picasso_refresh (); - flush_screen (gfxvidinfo.outbuffer, 0, 0); + picasso_refresh(0); + //flush_screen (gfxvidinfo.outbuffer, 0, 0); } } } diff --git a/od-win32/picasso96_win.cpp b/od-win32/picasso96_win.cpp index f72956f8..5518aaa1 100644 --- a/od-win32/picasso96_win.cpp +++ b/od-win32/picasso96_win.cpp @@ -73,6 +73,7 @@ #include "clipboard.h" #include "gfxboard.h" #include "gfxfilter.h" +#include "dxwrap.h" int debug_rtg_blitter = 3; @@ -93,7 +94,7 @@ bool picasso_flushpixels(int index, uae_u8 *src, int offset); int p96refresh_active; bool have_done_picasso = 1; /* For the JIT compiler */ static int p96syncrate; -static int p96hsync_counter, full_refresh; +static int p96hsync_counter; static smp_comm_pipe *render_pipe; static volatile int render_thread_state; @@ -104,7 +105,6 @@ static CRITICAL_SECTION render_cs; #define PICASSO_STATE_SETGC 4 #define PICASSO_STATE_SETDAC 8 #define PICASSO_STATE_SETSWITCH 16 -static uae_atomic picasso_state_change; #if defined(X86_MSVC_ASSEMBLY) #define SWAPSPEEDUP @@ -133,13 +133,11 @@ static uae_atomic picasso_state_change; static uae_u8 all_ones_bitmap, all_zeros_bitmap; /* yuk */ -struct picasso96_state_struct picasso96_state; -static struct picasso96_state_struct picasso96_state_uaegfx; -struct picasso_vidbuf_description picasso_vidinfo; +struct picasso96_state_struct picasso96_state[MAX_AMIGAMONITORS]; +//static struct picasso96_state_struct picasso96_state_uaegfx; +struct picasso_vidbuf_description picasso_vidinfo[MAX_AMIGAMONITORS]; static struct PicassoResolution *newmodes; -static int picasso_convert, host_mode; - /* These are the maximum resolutions... They are filled in by GetSupportedResolutions() */ /* have to fill this in, otherwise problems occur on the Amiga side P96 s/w which expects /* data here. */ @@ -161,10 +159,7 @@ static HCURSOR wincursor; static int wincursor_shown; static uaecptr boardinfo, ABI_interrupt; static int interrupt_enabled; -double p96vblank; -static int rtg_clear_flag; -static bool picasso_active; -static bool picasso_changed; +float p96vblank; static int uaegfx_old, uaegfx_active; static uae_u32 reserved_gfxmem; @@ -197,7 +192,7 @@ typedef enum { #include "win32gui.h" #include "resource.h" -static void init_picasso_screen(void); +static void init_picasso_screen(int); static uae_u32 p2ctab[256][2]; static int set_gc_called = 0, init_picasso_screen_called = 0; //fastscreen @@ -717,17 +712,18 @@ static void do_fillrect_frame_buffer(struct RenderInfo *ri, int X, int Y, int Wi } } -static void setupcursor (void) +static void setupcursor(void) { uae_u8 *dptr; int bpp = 4; int pitch; + struct rtgboardconfig *rbc = &currprefs.rtgboards[0]; - if (currprefs.rtgboards[0].rtgmem_type >= GFXBOARD_HARDWARE || !currprefs.gfx_api) + if (rbc->rtgmem_type >= GFXBOARD_HARDWARE || !currprefs.gfx_api) return; gfx_lock (); setupcursor_needed = 1; - dptr = D3D_setcursorsurface(&pitch); + dptr = D3D_setcursorsurface(rbc->monitor_id, &pitch); if (dptr) { for (int y = 0; y < CURSORMAXHEIGHT; y++) { uae_u8 *p2 = dptr + pitch * y; @@ -740,7 +736,7 @@ static void setupcursor (void) memcpy (p2, p1, cursorwidth * bpp); } } - D3D_setcursorsurface(NULL); + D3D_setcursorsurface(rbc->monitor_id, NULL); setupcursor_needed = 0; P96TRACE_SPR((_T("cursorsurface3d updated\n"))); } else { @@ -757,13 +753,14 @@ static void disablemouse (void) return; if (!currprefs.gfx_api) return; - D3D_setcursor (0, 0, 0, 0, false, true); + D3D_setcursor(0, 0, 0, 0, 0, false, true); } static int newcursor_x, newcursor_y; -static void mouseupdate (void) +static void mouseupdate(struct AmigaMonitor *mon) { + struct picasso96_state_struct *state = &picasso96_state[mon->monitor_id]; int x = newcursor_x; int y = newcursor_y; int forced = 0; @@ -781,9 +778,9 @@ static void mouseupdate (void) if (!currprefs.gfx_api) return; if (currprefs.gf[1].gfx_filter_autoscale == RTG_MODE_CENTER) { - D3D_setcursor (x, y, WIN32GFX_GetWidth (), WIN32GFX_GetHeight(), cursorvisible, scalepicasso == 2); + D3D_setcursor(mon->monitor_id, x, y, WIN32GFX_GetWidth(mon), WIN32GFX_GetHeight(mon), cursorvisible, mon->scalepicasso == 2); } else { - D3D_setcursor (x, y, picasso96_state.Width, picasso96_state.Height, cursorvisible, false); + D3D_setcursor(mon->monitor_id, x, y, state->Width, state->Height, cursorvisible, false); } } @@ -807,45 +804,56 @@ void picasso_trigger_vblank(void) INTREQ (0x8000 | 0x0008); } -static bool rtg_render (void) +static bool is_uaegfx_active(void) +{ + if (currprefs.rtgboards[0].rtgmem_type >= GFXBOARD_HARDWARE || !currprefs.rtgboards[0].rtgmem_size) + return false; + return true; +} + +static bool rtg_render(void) { + int monid = currprefs.rtgboards[0].monitor_id; bool flushed = false; - bool uaegfx_active = rtg_index == 0 && currprefs.rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE && currprefs.rtgboards[0].rtgmem_size; + bool uaegfx_active = is_uaegfx_active(); + int uaegfx_index = 0; + struct AmigaMonitor *mon = &AMonitors[monid]; + struct picasso96_state_struct *state = &picasso96_state[monid]; + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; if (doskip () && p96skipmode == 0) { ; } else { - bool full = full_refresh > 0; + bool full = vidinfo->full_refresh > 0; if (uaegfx_active) { if (!currprefs.rtg_multithread) { - flushed = picasso_flushpixels(rtg_index, gfxmem_banks[rtg_index]->start + natmem_offset, picasso96_state.XYOffset - gfxmem_banks[rtg_index]->start); + flushed = picasso_flushpixels(0, gfxmem_banks[uaegfx_index]->start + natmem_offset, state->XYOffset - gfxmem_banks[uaegfx_index]->start); } } else { - if (full_refresh < 0) - full_refresh = 0; - if (full_refresh > 0) - full_refresh--; + if (vidinfo->full_refresh < 0) + vidinfo->full_refresh = 0; + if (vidinfo->full_refresh > 0) + vidinfo->full_refresh--; } - bool flushed2 = gfxboard_vsync_handler(full); + bool flushed2 = gfxboard_vsync_handler(full, true); if (currprefs.rtg_multithread && uaegfx_active) { - write_comm_pipe_int(render_pipe, rtg_index | (flushed2 ? 0x80000000 : 0), 0); + write_comm_pipe_int(render_pipe, uaegfx_index | (flushed2 ? 0x80000000 : 0), 0); + flushed = true; } flushed |= flushed2; } return flushed; } -static void rtg_show (void) +static void rtg_show(int monid) { - gfx_unlock_picasso (true); + gfx_unlock_picasso(monid, true); } -static void rtg_clear (void) +static void rtg_clear(int monid) { - rtg_clear_flag = 4; + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; + vidinfo->rtg_clear_flag = 4; } -static int set_panning_called = 0; - - enum { /* DEST = RGBFB_B8G8R8A8,32 */ @@ -976,36 +984,38 @@ static int getconvert(int rgbformat, int pixbytes) return v; } -static void setconvert(void) +static void setconvert(int monid) { - static int ohost_mode, orgbformat; - lockrtg(); - picasso_convert = getconvert(picasso96_state.RGBFormat, picasso_vidinfo.pixbytes); + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; + struct picasso96_state_struct *state = &picasso96_state[monid]; + + vidinfo->picasso_convert = getconvert(state->RGBFormat, picasso_vidinfo[monid].pixbytes); if (currprefs.gfx_api) { - host_mode = picasso_vidinfo.pixbytes == 4 ? RGBFB_B8G8R8A8 : RGBFB_B5G6R5PC; + vidinfo->host_mode = picasso_vidinfo[monid].pixbytes == 4 ? RGBFB_B8G8R8A8 : RGBFB_B5G6R5PC; } else { - host_mode = DirectDraw_GetSurfacePixelFormat(NULL); + vidinfo->host_mode = DirectDraw_GetSurfacePixelFormat(NULL); } - if (picasso_vidinfo.pixbytes == 4) + if (picasso_vidinfo[monid].pixbytes == 4) alloc_colors_rgb(8, 8, 8, 16, 8, 0, 0, 0, 0, 0, p96rc, p96gc, p96bc); else alloc_colors_rgb(5, 6, 5, 11, 5, 0, 0, 0, 0, 0, p96rc, p96gc, p96bc); - gfx_set_picasso_colors(picasso96_state.RGBFormat); - picasso_palette(picasso96_state.CLUT); - if (host_mode != ohost_mode || picasso96_state.RGBFormat != orgbformat) { + gfx_set_picasso_colors(monid, state->RGBFormat); + picasso_palette(monid, state->CLUT); + if (vidinfo->host_mode != vidinfo->ohost_mode || state->RGBFormat != vidinfo->orgbformat) { write_log (_T("RTG conversion: Depth=%d HostRGBF=%d P96RGBF=%d Mode=%d\n"), - picasso_vidinfo.pixbytes, host_mode, picasso96_state.RGBFormat, picasso_convert); - ohost_mode = host_mode; - orgbformat = picasso96_state.RGBFormat; + picasso_vidinfo[monid].pixbytes, vidinfo->host_mode, state->RGBFormat, vidinfo->picasso_convert); + vidinfo->ohost_mode = vidinfo->host_mode; + vidinfo->orgbformat = state->RGBFormat; } - full_refresh = 1; + vidinfo->full_refresh = 1; unlockrtg(); } -bool picasso_is_active (void) +bool picasso_is_active(int monid) { - return picasso_active; + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; + return vidinfo->picasso_active; } /* Clear our screen, since we've got a new Picasso screen-mode, and refresh with the proper contents @@ -1014,20 +1024,24 @@ bool picasso_is_active (void) * 2. Picasso-->Picasso transition, via SetPanning(). * 3. whenever the graphics code notifies us that the screen contents have been lost. */ -void picasso_refresh (void) +void picasso_refresh(int monid) { struct RenderInfo ri; + struct AmigaMonitor *mon = &AMonitors[monid]; + struct amigadisplay *ad = &adisplays[monid]; + struct picasso96_state_struct *state = &picasso96_state[monid]; + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; - if (!picasso_on || rtg_index < 0) + if (!ad->picasso_on) return; lockrtg(); - full_refresh = 1; - setconvert(); + vidinfo->full_refresh = 1; + setconvert(monid); setupcursor(); - rtg_clear(); + rtg_clear(monid); - if (currprefs.rtgboards[rtg_index].rtgmem_type >= GFXBOARD_HARDWARE) { - gfxboard_refresh (); + if (currprefs.rtgboards[0].rtgmem_type >= GFXBOARD_HARDWARE) { + gfxboard_refresh(monid); unlockrtg(); return; } @@ -1035,27 +1049,27 @@ void picasso_refresh (void) /* Make sure that the first time we show a Picasso video mode, we don't blit any crap. * We can do this by checking if we have an Address yet. */ - if (picasso96_state.Address) { + if (state->Address) { unsigned int width, height; /* blit the stuff from our static frame-buffer to the gfx-card */ - ri.Memory = gfxmem_bank.baseaddr + (picasso96_state.Address - gfxmem_bank.start); - ri.BytesPerRow = picasso96_state.BytesPerRow; - ri.RGBFormat = picasso96_state.RGBFormat; - - if (set_panning_called) { - width = (picasso96_state.VirtualWidth < picasso96_state.Width) ? - picasso96_state.VirtualWidth : picasso96_state.Width; - height = (picasso96_state.VirtualHeight < picasso96_state.Height) ? - picasso96_state.VirtualHeight : picasso96_state.Height; + ri.Memory = gfxmem_bank.baseaddr + (state->Address - gfxmem_bank.start); + ri.BytesPerRow = state->BytesPerRow; + ri.RGBFormat = state->RGBFormat; + + if (vidinfo->set_panning_called) { + width = (state->VirtualWidth < state->Width) ? + state->VirtualWidth : state->Width; + height = (state->VirtualHeight < state->Height) ? + state->VirtualHeight : state->Height; // Let's put a black-border around the case where we've got a sub-screen... - if (!picasso96_state.BigAssBitmap) { - if (picasso96_state.XOffset || picasso96_state.YOffset) - DX_Fill (0, 0, picasso96_state.Width, picasso96_state.Height, 0); + if (!state->BigAssBitmap) { + if (state->XOffset || state->YOffset) + DX_Fill(mon, 0, 0, state->Width, state->Height, 0); } } else { - width = picasso96_state.Width; - height = picasso96_state.Height; + width = state->Width; + height = state->Height; } } else { write_log (_T("ERROR - picasso_refresh() can't refresh!\n")); @@ -1063,66 +1077,67 @@ void picasso_refresh (void) unlockrtg(); } -static void selectuaegfx(void) -{ - memcpy(&picasso96_state, &picasso96_state_uaegfx, sizeof picasso96_state); -} - -static void picasso_handle_vsync2(void) +static void picasso_handle_vsync2(struct AmigaMonitor *mon) { + struct amigadisplay *ad = &adisplays[mon->monitor_id]; + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[mon->monitor_id]; static int vsynccnt; int thisisvsync = 1; int vsync = isvsync_rtg(); int mult; bool rendered = false; bool uaegfx = currprefs.rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE; + bool uaegfx_active = is_uaegfx_active(); - int state = picasso_state_change; + int state = vidinfo->picasso_state_change; if (state) lockrtg(); if (state & PICASSO_STATE_SETDAC) { - atomic_and(&picasso_state_change, ~PICASSO_STATE_SETDAC); - rtg_clear(); + atomic_and(&vidinfo->picasso_state_change, ~PICASSO_STATE_SETDAC); + rtg_clear(mon->monitor_id); } if (state & PICASSO_STATE_SETGC) { - atomic_and(&picasso_state_change, ~PICASSO_STATE_SETGC); - selectuaegfx(); + atomic_and(&vidinfo->picasso_state_change, ~PICASSO_STATE_SETGC); set_gc_called = 1; - picasso_changed = true; - init_picasso_screen(); - init_hz_p96(); + vidinfo->picasso_changed = true; + init_picasso_screen(mon->monitor_id); + init_hz_p96(mon->monitor_id); } if (state & PICASSO_STATE_SETSWITCH) { - atomic_and(&picasso_state_change, ~PICASSO_STATE_SETSWITCH); - selectuaegfx(); + atomic_and(&vidinfo->picasso_state_change, ~PICASSO_STATE_SETSWITCH); /* Do not switch immediately. Tell the custom chip emulation about the * desired state, and wait for custom.c to call picasso_enablescreen * whenever it is ready to change the screen state. */ - if (picasso_on == picasso_requested_on && picasso_requested_on && picasso_changed) { - picasso_requested_forced_on = true; + if (ad->picasso_on == ad->picasso_requested_on && ad->picasso_requested_on && vidinfo->picasso_changed) { + ad->picasso_requested_forced_on = true; } - picasso_changed = false; - picasso_active = picasso_requested_on; + vidinfo->picasso_changed = false; + vidinfo->picasso_active = ad->picasso_requested_on; } if (state & PICASSO_STATE_SETPANNING) { - atomic_and(&picasso_state_change, ~PICASSO_STATE_SETPANNING); - selectuaegfx(); - full_refresh = 1; - set_panning_called = 1; - init_picasso_screen(); - set_panning_called = 0; + atomic_and(&vidinfo->picasso_state_change, ~PICASSO_STATE_SETPANNING); + vidinfo->full_refresh = 1; + vidinfo->set_panning_called = 1; + init_picasso_screen(mon->monitor_id); + vidinfo->set_panning_called = 0; + } + if (state & PICASSO_STATE_SETDISPLAY) { + atomic_and(&vidinfo->picasso_state_change, ~PICASSO_STATE_SETDISPLAY); + // do nothing } if (state) unlockrtg(); - if (picasso_on) { + if (ad->picasso_on) { +#if 0 if (vsync < 0) { vsync_busywait_end(NULL); vsync_busywait_do(NULL, false, false); } +#endif } - getvsyncrate(currprefs.chipset_refreshrate, &mult); + getvsyncrate(mon->monitor_id, currprefs.chipset_refreshrate, &mult); if (vsync && mult < 0) { vsynccnt++; if (vsynccnt < 2) @@ -1133,49 +1148,55 @@ static void picasso_handle_vsync2(void) p96_framecnt++; - if (!uaegfx && !picasso_on) { + if (!uaegfx && !ad->picasso_on) { rtg_render(); return; } - if (!picasso_on) + if (!ad->picasso_on) return; - if (uaegfx && rtg_index == 0) - mouseupdate(); + if (uaegfx && uaegfx_active) + mouseupdate(mon); if (thisisvsync) { rendered = rtg_render(); - frame_drawn(); + if (mon->monitor_id == 0) + frame_drawn(); } if (uaegfx) { - if (setupcursor_needed && rtg_index == 0) + if (setupcursor_needed && uaegfx_active) setupcursor(); if (thisisvsync) picasso_trigger_vblank(); } +#if 0 if (vsync < 0) { vsync_busywait_start(); } +#endif if (thisisvsync && !rendered) - rtg_show(); + rtg_show(mon->monitor_id); } static int p96hsync; void picasso_handle_vsync(void) { + struct AmigaMonitor *mon = &AMonitors[currprefs.rtgboards[0].monitor_id]; + struct amigadisplay *ad = &adisplays[currprefs.rtgboards[0].monitor_id]; bool uaegfx = currprefs.rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE; + bool uaegfx_active = is_uaegfx_active(); if (currprefs.rtgboards[0].rtgmem_size == 0) return; - if (!picasso_on && uaegfx) { - if (rtg_index == 0) { - createwindowscursor(0, 0, 0, 0, 0, 1); + if (!ad->picasso_on && uaegfx) { + if (uaegfx_active) { + createwindowscursor(mon->monitor_id, 0, 0, 0, 0, 0, 1); } picasso_trigger_vblank(); return; @@ -1184,15 +1205,18 @@ void picasso_handle_vsync(void) int vsync = isvsync_rtg(); if (vsync < 0) { p96hsync = 0; - picasso_handle_vsync2(); + picasso_handle_vsync2(mon); } else if (currprefs.win32_rtgvblankrate == 0) { - picasso_handle_vsync2(); + picasso_handle_vsync2(mon); } } void picasso_handle_hsync(void) { + struct AmigaMonitor *mon = &AMonitors[currprefs.rtgboards[0].monitor_id]; + struct amigadisplay *ad = &adisplays[currprefs.rtgboards[0].monitor_id]; bool uaegfx = currprefs.rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE; + bool uaegfx_active = is_uaegfx_active(); if (currprefs.rtgboards[0].rtgmem_size == 0) return; @@ -1213,15 +1237,15 @@ void picasso_handle_hsync(void) p96hsync++; if (p96hsync >= p96syncrate) { - if (!picasso_on) { + if (!ad->picasso_on) { if (uaegfx) { - if (rtg_index == 0) { - createwindowscursor(0, 0, 0, 0, 0, 1); + if (uaegfx_active) { + createwindowscursor(mon->monitor_id, 0, 0, 0, 0, 0, 1); } picasso_trigger_vblank(); } } else { - picasso_handle_vsync2(); + picasso_handle_vsync2(mon); } p96hsync = 0; } @@ -1579,10 +1603,11 @@ d7: RGBFTYPE RGBFormat */ static uae_u32 REGPARAM2 picasso_SetSpritePosition (TrapContext *ctx) { + struct picasso96_state_struct *state = &picasso96_state[currprefs.rtgboards[0].monitor_id]; uaecptr bi = trap_get_areg(ctx, 0); boardinfo = bi; - newcursor_x = (uae_s16)trap_get_word(ctx, bi + PSSO_BoardInfo_MouseX) - picasso96_state.XOffset; - newcursor_y = (uae_s16)trap_get_word(ctx, bi + PSSO_BoardInfo_MouseY) - picasso96_state.YOffset; + newcursor_x = (uae_s16)trap_get_word(ctx, bi + PSSO_BoardInfo_MouseX) - state->XOffset; + newcursor_y = (uae_s16)trap_get_word(ctx, bi + PSSO_BoardInfo_MouseY) - state->YOffset; if (!hwsprite) return 0; return 1; @@ -1682,7 +1707,7 @@ extern uaecptr sprite_0; extern int sprite_0_width, sprite_0_height, sprite_0_doubled; extern uae_u32 sprite_0_colors[4]; -int createwindowscursor(uaecptr src, int w, int h, int hiressprite, int doubledsprite, int chipset) +int createwindowscursor(int monid, uaecptr src, int w, int h, int hiressprite, int doubledsprite, int chipset) { HBITMAP andBM, xorBM; HBITMAP andoBM, xoroBM; @@ -1849,13 +1874,14 @@ exit: return ret; } -int picasso_setwincursor (void) +int picasso_setwincursor(int monid) { + struct amigadisplay *ad = &adisplays[monid]; if (wincursor) { - SetCursor (wincursor); + SetCursor(wincursor); return 1; - } else if (!picasso_on) { - if (createwindowscursor (0, 0, 0, 0, 0, 1)) + } else if (!ad->picasso_on) { + if (createwindowscursor(monid, 0, 0, 0, 0, 0, 1)) return 1; } return 0; @@ -1896,7 +1922,7 @@ static uae_u32 setspriteimage(TrapContext *ctx, uaecptr bi) goto end; } - createwindowscursor (trap_get_long(ctx, bi + PSSO_BoardInfo_MouseImage) + 4 * hiressprite, + createwindowscursor (0, trap_get_long(ctx, bi + PSSO_BoardInfo_MouseImage) + 4 * hiressprite, w, h, hiressprite, doubledsprite, 0); cursordata = xmalloc (uae_u8, w * h * bpp); @@ -2024,6 +2050,7 @@ static void picasso96_alloc2 (TrapContext *ctx); static uae_u32 REGPARAM2 picasso_FindCard (TrapContext *ctx) { uaecptr AmigaBoardInfo = trap_get_areg(ctx, 0); + struct picasso96_state_struct *state = &picasso96_state[currprefs.rtgboards[0].monitor_id]; /* NOTES: See BoardInfo struct definition in Picasso96 dev info */ if (!uaegfx_active || !(gfxmem_bank.flags & ABFLAG_MAPPED)) return 0; @@ -2033,11 +2060,11 @@ static uae_u32 REGPARAM2 picasso_FindCard (TrapContext *ctx) picasso96_alloc2 (ctx); } boardinfo = AmigaBoardInfo; - if (gfxmem_bank.allocated_size && !picasso96_state_uaegfx.CardFound) { + if (gfxmem_bank.allocated_size && !state->CardFound) { /* Fill in MemoryBase, MemorySize */ trap_put_long(ctx, AmigaBoardInfo + PSSO_BoardInfo_MemoryBase, gfxmem_bank.start); trap_put_long(ctx, AmigaBoardInfo + PSSO_BoardInfo_MemorySize, gfxmem_bank.allocated_size - reserved_gfxmem); - picasso96_state_uaegfx.CardFound = 1; /* mark our "card" as being found */ + state->CardFound = 1; /* mark our "card" as being found */ return -1; } else return 0; @@ -2499,7 +2526,7 @@ static void inituaegfx(TrapContext *ctx, uaecptr ABI) } flags |= BIF_NOMEMORYMODEMIX; flags &= ~BIF_HARDWARESPRITE; - if (currprefs.gfx_api && D3D_goodenough () > 0 && D3D_setcursor(-1, -1, -1, -1, false, false) && USE_HARDWARESPRITE && currprefs.rtg_hardwaresprite) { + if (currprefs.gfx_api && D3D_goodenough () > 0 && D3D_setcursor(0, -1, -1, -1, -1, false, false) && USE_HARDWARESPRITE && currprefs.rtg_hardwaresprite) { hwsprite = 1; flags |= BIF_HARDWARESPRITE; write_log (_T("P96: Hardware sprite support enabled\n")); @@ -2658,18 +2685,23 @@ static uae_u32 REGPARAM2 picasso_InitCard (TrapContext *ctx) static uae_u32 REGPARAM2 picasso_SetSwitch (TrapContext *ctx) { lockrtg(); + int monid = currprefs.rtgboards[0].monitor_id; + struct picasso96_state_struct *state = &picasso96_state[monid]; + struct amigadisplay *ad = &adisplays[monid]; + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; uae_u16 flag = trap_get_dreg(ctx, 0) & 0xFFFF; - atomic_or(&picasso_state_change, PICASSO_STATE_SETSWITCH); - picasso_requested_on = flag != 0; + atomic_or(&vidinfo->picasso_state_change, PICASSO_STATE_SETSWITCH); + ad->picasso_requested_on = flag != 0; + set_config_changed(); TCHAR p96text[100]; p96text[0] = 0; if (flag) _stprintf(p96text, _T("Picasso96 %dx%dx%d (%dx%dx%d)"), - picasso96_state_uaegfx.Width, picasso96_state_uaegfx.Height, picasso96_state_uaegfx.BytesPerPixel * 8, - picasso_vidinfo.width, picasso_vidinfo.height, picasso_vidinfo.pixbytes * 8); - write_log(_T("SetSwitch() - %s\n"), flag ? p96text : _T("amiga")); + state->Width, state->Height, state->BytesPerPixel * 8, + vidinfo->width, vidinfo->height, vidinfo->pixbytes * 8); + write_log(_T("SetSwitch() - %s. Monitor=%d\n"), flag ? p96text : _T("amiga"), monid); /* Put old switch-state in D0 */ unlockrtg(); @@ -2677,22 +2709,23 @@ static uae_u32 REGPARAM2 picasso_SetSwitch (TrapContext *ctx) } -void picasso_enablescreen (int on) +void picasso_enablescreen(int monid, int on) { bool uaegfx = currprefs.rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE && currprefs.rtgboards[0].rtgmem_size; - if (rtg_index == 0 && uaegfx) { - selectuaegfx(); + bool uaegfx_active = is_uaegfx_active(); + + if (uaegfx_active && uaegfx) { if (!init_picasso_screen_called) - init_picasso_screen (); + init_picasso_screen(monid); } - setconvert(); - picasso_refresh (); + setconvert(monid); + picasso_refresh(0); } -static void resetpalette(void) +static void resetpalette(struct picasso96_state_struct *state) { for (int i = 0; i < 256; i++) - picasso96_state_uaegfx.CLUT[i].Pad = 0xff; + state->CLUT[i].Pad = 0xff; } /* @@ -2710,6 +2743,8 @@ static void resetpalette(void) static int updateclut(TrapContext *ctx, uaecptr clut, int start, int count) { bool uaegfx = currprefs.rtgboards[0].rtgmem_type < GFXBOARD_HARDWARE && currprefs.rtgboards[0].rtgmem_size; + int monid = currprefs.rtgboards[0].monitor_id; + struct picasso96_state_struct *state = &picasso96_state[monid]; uae_u8 clutbuf[256 * 3]; int i, changed = 0; clut += start * 3; @@ -2719,27 +2754,28 @@ static int updateclut(TrapContext *ctx, uaecptr clut, int start, int count) int g = clutbuf[i * 3 + 1]; int b = clutbuf[i * 3 + 2]; //write_log(_T("%d: %02x%02x%02x\n"), i, r, g, b); - changed |= picasso96_state_uaegfx.CLUT[i].Red != r - || picasso96_state_uaegfx.CLUT[i].Green != g - || picasso96_state_uaegfx.CLUT[i].Blue != b; - if (picasso96_state_uaegfx.CLUT[i].Pad) { + changed |= state->CLUT[i].Red != r + || state->CLUT[i].Green != g + || state->CLUT[i].Blue != b; + if (state->CLUT[i].Pad) { changed = 1; - picasso96_state_uaegfx.CLUT[i].Pad = 0; + state->CLUT[i].Pad = 0; } - picasso96_state_uaegfx.CLUT[i].Red = r; - picasso96_state_uaegfx.CLUT[i].Green = g; - picasso96_state_uaegfx.CLUT[i].Blue = b; + state->CLUT[i].Red = r; + state->CLUT[i].Green = g; + state->CLUT[i].Blue = b; if (uaegfx) { - picasso96_state.CLUT[i].Red = r; - picasso96_state.CLUT[i].Green = g; - picasso96_state.CLUT[i].Blue = b; + state->CLUT[i].Red = r; + state->CLUT[i].Green = g; + state->CLUT[i].Blue = b; } } - changed |= picasso_palette (picasso96_state.CLUT); + changed |= picasso_palette(monid, state->CLUT); return changed; } static uae_u32 REGPARAM2 picasso_SetColorArray (TrapContext *ctx) { + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[currprefs.rtgboards[0].monitor_id]; /* Fill in some static UAE related structure about this new CLUT setting * We need this for CLUT-based displays, and for mapping CLUT to hi/true colour */ uae_u16 start = trap_get_dreg (ctx, 0); @@ -2749,7 +2785,7 @@ static uae_u32 REGPARAM2 picasso_SetColorArray (TrapContext *ctx) if (start > 256 || count > 256 || start + count > 256) return 0; if (updateclut(ctx, clut, start, count)) - full_refresh = 1; + vidinfo->full_refresh = 1; P96TRACE_SETUP((_T("SetColorArray(%d,%d)\n"), start, count)); return 1; } @@ -2764,29 +2800,32 @@ static uae_u32 REGPARAM2 picasso_SetColorArray (TrapContext *ctx) */ static uae_u32 REGPARAM2 picasso_SetDAC (TrapContext *ctx) { + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[currprefs.rtgboards[0].monitor_id]; /* Fill in some static UAE related structure about this new DAC setting * Lets us keep track of what pixel format the Amiga is thinking about in our frame-buffer */ - atomic_or(&picasso_state_change, PICASSO_STATE_SETDAC); + atomic_or(&vidinfo->picasso_state_change, PICASSO_STATE_SETDAC); P96TRACE_SETUP((_T("SetDAC()\n"))); return 1; } -static void init_picasso_screen (void) +static void init_picasso_screen(int monid) { - if(set_panning_called) { - picasso96_state_uaegfx.Extent = picasso96_state_uaegfx.Address + picasso96_state_uaegfx.BytesPerRow * picasso96_state_uaegfx.VirtualHeight; + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; + struct picasso96_state_struct *state = &picasso96_state[monid]; + if(vidinfo->set_panning_called) { + state->Extent = state->Address + state->BytesPerRow * state->VirtualHeight; } if (set_gc_called) { - gfx_set_picasso_modeinfo (picasso96_state_uaegfx.RGBFormat); + gfx_set_picasso_modeinfo(monid, state->RGBFormat); set_gc_called = 0; } - if((picasso_vidinfo.width == picasso96_state_uaegfx.Width) && - (picasso_vidinfo.height == picasso96_state_uaegfx.Height) && - (picasso_vidinfo.depth == (picasso96_state_uaegfx.GC_Depth >> 3)) && - (picasso_vidinfo.selected_rgbformat == picasso96_state_uaegfx.RGBFormat)) + if((vidinfo->width == state->Width) && + (vidinfo->height == state->Height) && + (vidinfo->depth == (state->GC_Depth >> 3)) && + (vidinfo->selected_rgbformat == state->RGBFormat)) { - picasso_refresh (); + picasso_refresh(monid); } init_picasso_screen_called = 1; mman_ResetWatch (gfxmem_bank.start + natmem_offset, gfxmem_bank.allocated_size); @@ -2807,6 +2846,9 @@ static void init_picasso_screen (void) static uae_u32 REGPARAM2 picasso_SetGC (TrapContext *ctx) { lockrtg(); + int monid = currprefs.rtgboards[0].monitor_id; + struct picasso96_state_struct *state = &picasso96_state[monid]; + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; /* Fill in some static UAE related structure about this new ModeInfo setting */ uaecptr AmigaBoardInfo = trap_get_areg(ctx, 0); uae_u32 border = trap_get_dreg(ctx, 0); @@ -2815,20 +2857,20 @@ static uae_u32 REGPARAM2 picasso_SetGC (TrapContext *ctx) trap_put_long(ctx, AmigaBoardInfo + PSSO_BoardInfo_ModeInfo, modeinfo); trap_put_word(ctx, AmigaBoardInfo + PSSO_BoardInfo_Border, border); - picasso96_state_uaegfx.Width = trap_get_word(ctx, modeinfo + PSSO_ModeInfo_Width); - picasso96_state_uaegfx.VirtualWidth = picasso96_state_uaegfx.Width; /* in case SetPanning doesn't get called */ + state->Width = trap_get_word(ctx, modeinfo + PSSO_ModeInfo_Width); + state->VirtualWidth = state->Width; /* in case SetPanning doesn't get called */ - picasso96_state_uaegfx.Height = trap_get_word(ctx, modeinfo + PSSO_ModeInfo_Height); - picasso96_state_uaegfx.VirtualHeight = picasso96_state_uaegfx.Height; /* in case SetPanning doesn't get called */ + state->Height = trap_get_word(ctx, modeinfo + PSSO_ModeInfo_Height); + state->VirtualHeight = state->Height; /* in case SetPanning doesn't get called */ - picasso96_state_uaegfx.GC_Depth = trap_get_byte(ctx, modeinfo + PSSO_ModeInfo_Depth); - picasso96_state_uaegfx.GC_Flags = trap_get_byte(ctx, modeinfo + PSSO_ModeInfo_Flags); + state->GC_Depth = trap_get_byte(ctx, modeinfo + PSSO_ModeInfo_Depth); + state->GC_Flags = trap_get_byte(ctx, modeinfo + PSSO_ModeInfo_Flags); - P96TRACE_SETUP((_T("SetGC(%d,%d,%d,%d)\n"), picasso96_state_uaegfx.Width, picasso96_state_uaegfx.Height, picasso96_state_uaegfx.GC_Depth, border)); + P96TRACE_SETUP((_T("SetGC(%d,%d,%d,%d)\n"), state->Width, state->Height, state->GC_Depth, border)); - picasso96_state_uaegfx.HostAddress = NULL; + state->HostAddress = NULL; - atomic_or(&picasso_state_change, PICASSO_STATE_SETGC); + atomic_or(&vidinfo->picasso_state_change, PICASSO_STATE_SETGC); unlockrtg(); return 1; } @@ -2856,19 +2898,22 @@ static uae_u32 REGPARAM2 picasso_SetGC (TrapContext *ctx) * because SetSwitch() is not called for subsequent Picasso screens. */ -static void picasso_SetPanningInit (void) +static void picasso_SetPanningInit (struct picasso96_state_struct *state) { - picasso96_state_uaegfx.XYOffset = picasso96_state_uaegfx.Address + (picasso96_state_uaegfx.XOffset * picasso96_state_uaegfx.BytesPerPixel) - + (picasso96_state_uaegfx.YOffset * picasso96_state_uaegfx.BytesPerRow); - if(picasso96_state_uaegfx.VirtualWidth > picasso96_state_uaegfx.Width || picasso96_state_uaegfx.VirtualHeight > picasso96_state_uaegfx.Height) - picasso96_state_uaegfx.BigAssBitmap = 1; + state->XYOffset = state->Address + (state->XOffset * state->BytesPerPixel) + + (state->YOffset * state->BytesPerRow); + if(state->VirtualWidth > state->Width || state->VirtualHeight > state->Height) + state->BigAssBitmap = 1; else - picasso96_state_uaegfx.BigAssBitmap = 0; + state->BigAssBitmap = 0; } static uae_u32 REGPARAM2 picasso_SetPanning (TrapContext *ctx) { lockrtg(); + int monid = currprefs.rtgboards[0].monitor_id; + struct picasso96_state_struct *state = &picasso96_state[monid]; + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; uae_u16 Width = trap_get_dreg(ctx, 0); uaecptr start_of_screen = trap_get_areg(ctx, 1); uaecptr bi = trap_get_areg(ctx, 0); @@ -2888,31 +2933,30 @@ static uae_u32 REGPARAM2 picasso_SetPanning (TrapContext *ctx) bme_width = trap_get_word(ctx, bmeptr + PSSO_BitMapExtra_Width); bme_height = trap_get_word(ctx, bmeptr + PSSO_BitMapExtra_Height); - rgbf = picasso96_state_uaegfx.RGBFormat; + rgbf = state->RGBFormat; - picasso96_state_uaegfx.Address = start_of_screen; /* Amiga-side address */ - picasso96_state_uaegfx.XOffset = (uae_s16)(trap_get_dreg(ctx, 1) & 0xFFFF); - picasso96_state_uaegfx.YOffset = (uae_s16)(trap_get_dreg(ctx, 2) & 0xFFFF); - trap_put_word(ctx, bi + PSSO_BoardInfo_XOffset, picasso96_state_uaegfx.XOffset); - trap_put_word(ctx, bi + PSSO_BoardInfo_YOffset, picasso96_state_uaegfx.YOffset); - picasso96_state_uaegfx.VirtualWidth = bme_width; - picasso96_state_uaegfx.VirtualHeight = bme_height; - picasso96_state_uaegfx.RGBFormat = (RGBFTYPE)trap_get_dreg(ctx, 7); - picasso96_state_uaegfx.BytesPerPixel = GetBytesPerPixel (picasso96_state_uaegfx.RGBFormat); - picasso96_state_uaegfx.BytesPerRow = picasso96_state_uaegfx.VirtualWidth * picasso96_state_uaegfx.BytesPerPixel; - picasso_SetPanningInit(); + state->Address = start_of_screen; /* Amiga-side address */ + state->XOffset = (uae_s16)(trap_get_dreg(ctx, 1) & 0xFFFF); + state->YOffset = (uae_s16)(trap_get_dreg(ctx, 2) & 0xFFFF); + trap_put_word(ctx, bi + PSSO_BoardInfo_XOffset, state->XOffset); + trap_put_word(ctx, bi + PSSO_BoardInfo_YOffset, state->YOffset); + state->VirtualWidth = bme_width; + state->VirtualHeight = bme_height; + state->RGBFormat = (RGBFTYPE)trap_get_dreg(ctx, 7); + state->BytesPerPixel = GetBytesPerPixel (state->RGBFormat); + state->BytesPerRow = state->VirtualWidth * state->BytesPerPixel; + picasso_SetPanningInit(state); - if (rgbf != picasso96_state_uaegfx.RGBFormat && rtg_index <= 0) { - selectuaegfx(); - setconvert(); + if (rgbf != state->RGBFormat) { + setconvert(monid); } P96TRACE_SETUP((_T("SetPanning(%d, %d, %d) (%dx%d) Start 0x%x, BPR %d Bpp %d RGBF %d\n"), - Width, picasso96_state_uaegfx.XOffset, picasso96_state_uaegfx.YOffset, + Width, state->XOffset, state->YOffset, bme_width, bme_height, - start_of_screen, picasso96_state_uaegfx.BytesPerRow, picasso96_state_uaegfx.BytesPerPixel, picasso96_state_uaegfx.RGBFormat)); + start_of_screen, state->BytesPerRow, state->BytesPerPixel, state->RGBFormat)); - atomic_or(&picasso_state_change, PICASSO_STATE_SETPANNING); + atomic_or(&vidinfo->picasso_state_change, PICASSO_STATE_SETPANNING); unlockrtg(); return 1; @@ -3695,21 +3739,24 @@ static uae_u32 REGPARAM2 picasso_CalculateBytesPerRow (TrapContext *ctx) */ static uae_u32 REGPARAM2 picasso_SetDisplay (TrapContext *ctx) { - uae_u32 state = trap_get_dreg(ctx, 0); - P96TRACE_SETUP((_T("SetDisplay(%d)\n"), state)); - resetpalette (); - atomic_or(&picasso_state_change, PICASSO_STATE_SETDISPLAY); - return !state; + int monid = currprefs.rtgboards[0].monitor_id; + struct picasso96_state_struct *state = &picasso96_state[monid]; + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; + uae_u32 setstate = trap_get_dreg(ctx, 0); + P96TRACE_SETUP((_T("SetDisplay(%d)\n"), setstate)); + resetpalette(state); + atomic_or(&vidinfo->picasso_state_change, PICASSO_STATE_SETDISPLAY); + return !setstate; } -void init_hz_p96 (void) +void init_hz_p96(int monid) { if (currprefs.win32_rtgvblankrate < 0 || isvsync_rtg ()) { - double rate = getcurrentvblankrate (); + float rate = target_getcurrentvblankrate(monid); if (rate < 0) p96vblank = vblank_hz; else - p96vblank = getcurrentvblankrate (); + p96vblank = target_getcurrentvblankrate(monid); } else if (currprefs.win32_rtgvblankrate == 0) { p96vblank = vblank_hz; } else { @@ -4073,31 +4120,34 @@ static uae_u32 REGPARAM2 picasso_BlitPlanar2Direct (TrapContext *ctx) } #include "statusline.h" -void picasso_statusline (uae_u8 *dst) +void picasso_statusline(int monid, uae_u8 *dst) { + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; + struct picasso96_state_struct *state = &picasso96_state[monid]; int y, yy, slx, sly; int dst_height, dst_width, pitch; - dst_height = picasso96_state.Height; - if (dst_height > picasso_vidinfo.height) - dst_height = picasso_vidinfo.height; - dst_width = picasso96_state.Width; - if (dst_width > picasso_vidinfo.width) - dst_width = picasso_vidinfo.width; - pitch = picasso_vidinfo.rowbytes; - statusline_getpos (&slx, &sly, picasso96_state.Width, dst_height, 1, 1); + dst_height = state->Height; + if (dst_height > vidinfo->height) + dst_height = vidinfo->height; + dst_width = state->Width; + if (dst_width > vidinfo->width) + dst_width = vidinfo->width; + pitch = vidinfo->rowbytes; + statusline_getpos(monid, &slx, &sly, state->Width, dst_height, 1, 1); if (currprefs.gfx_api) - statusline_render(dst + sly * pitch, picasso_vidinfo.pixbytes, pitch, dst_width, dst_height, p96rc, p96gc, p96bc, NULL); + statusline_render(monid, dst + sly * pitch, vidinfo->pixbytes, pitch, dst_width, dst_height, p96rc, p96gc, p96bc, NULL); yy = 0; for (y = 0; y < TD_TOTAL_HEIGHT; y++) { uae_u8 *buf = dst + (y + sly) * pitch; - draw_status_line_single (buf, picasso_vidinfo.pixbytes, y, dst_width, p96rc, p96gc, p96bc, NULL); + draw_status_line_single(monid, buf, vidinfo->pixbytes, y, dst_width, p96rc, p96gc, p96bc, NULL); yy++; } } -static void copyrow (uae_u8 *src, uae_u8 *dst, int x, int y, int width, int srcbytesperrow, int srcpixbytes, int dy, int dstbytesperrow, int dstpixbytes, bool direct, int convert_mode) +static void copyrow (int monid, uae_u8 *src, uae_u8 *dst, int x, int y, int width, int srcbytesperrow, int srcpixbytes, int dy, int dstbytesperrow, int dstpixbytes, bool direct, int convert_mode) { + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; uae_u8 *src2 = src + y * srcbytesperrow; uae_u8 *dst2 = dst + dy * dstbytesperrow; int endx = x + width, endx4; @@ -4291,21 +4341,21 @@ static void copyrow (uae_u8 *src, uae_u8 *dst, int x, int y, int width, int srcb case RGBFB_CLUT_RGBFB_32: { while ((x & 3) && x < endx) { - ((uae_u32*)dst2)[x] = picasso_vidinfo.clut[src2[x]]; + ((uae_u32*)dst2)[x] = vidinfo->clut[src2[x]]; x++; } while (x < endx4) { - ((uae_u32*)dst2)[x] = picasso_vidinfo.clut[src2[x]]; + ((uae_u32*)dst2)[x] = vidinfo->clut[src2[x]]; x++; - ((uae_u32*)dst2)[x] = picasso_vidinfo.clut[src2[x]]; + ((uae_u32*)dst2)[x] = vidinfo->clut[src2[x]]; x++; - ((uae_u32*)dst2)[x] = picasso_vidinfo.clut[src2[x]]; + ((uae_u32*)dst2)[x] = vidinfo->clut[src2[x]]; x++; - ((uae_u32*)dst2)[x] = picasso_vidinfo.clut[src2[x]]; + ((uae_u32*)dst2)[x] = vidinfo->clut[src2[x]]; x++; } while (x < endx) { - ((uae_u32*)dst2)[x] = picasso_vidinfo.clut[src2[x]]; + ((uae_u32*)dst2)[x] = vidinfo->clut[src2[x]]; x++; } } @@ -4315,21 +4365,21 @@ static void copyrow (uae_u8 *src, uae_u8 *dst, int x, int y, int width, int srcb case RGBFB_CLUT_RGBFB_16: { while ((x & 3) && x < endx) { - ((uae_u16*)dst2)[x] = picasso_vidinfo.clut[src2[x]]; + ((uae_u16*)dst2)[x] = vidinfo->clut[src2[x]]; x++; } while (x < endx4) { - ((uae_u16*)dst2)[x] = picasso_vidinfo.clut[src2[x]]; + ((uae_u16*)dst2)[x] = vidinfo->clut[src2[x]]; x++; - ((uae_u16*)dst2)[x] = picasso_vidinfo.clut[src2[x]]; + ((uae_u16*)dst2)[x] = vidinfo->clut[src2[x]]; x++; - ((uae_u16*)dst2)[x] = picasso_vidinfo.clut[src2[x]]; + ((uae_u16*)dst2)[x] = vidinfo->clut[src2[x]]; x++; - ((uae_u16*)dst2)[x] = picasso_vidinfo.clut[src2[x]]; + ((uae_u16*)dst2)[x] = vidinfo->clut[src2[x]]; x++; } while (x < endx) { - ((uae_u16*)dst2)[x] = picasso_vidinfo.clut[src2[x]]; + ((uae_u16*)dst2)[x] = vidinfo->clut[src2[x]]; x++; } } @@ -4337,12 +4387,14 @@ static void copyrow (uae_u8 *src, uae_u8 *dst, int x, int y, int width, int srcb } } -void fb_copyrow(uae_u8 *src, uae_u8 *dst, int x, int y, int width, int srcpixbytes, int dy) +void fb_copyrow(int monid, uae_u8 *src, uae_u8 *dst, int x, int y, int width, int srcpixbytes, int dy) { - copyrow(src, dst, x, y, width, 0, srcpixbytes, dy, picasso_vidinfo.rowbytes, picasso_vidinfo.pixbytes, picasso96_state.RGBFormat == host_mode, picasso_convert); + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; + struct picasso96_state_struct *state = &picasso96_state[monid]; + copyrow(monid, src, dst, x, y, width, 0, srcpixbytes, dy, picasso_vidinfo[monid].rowbytes, picasso_vidinfo[monid].pixbytes, state->RGBFormat == vidinfo->host_mode, vidinfo->picasso_convert); } -static void copyallinvert (uae_u8 *src, uae_u8 *dst, int pwidth, int pheight, int srcbytesperrow, int srcpixbytes, int dstbytesperrow, int dstpixbytes, bool direct, int mode_convert) +static void copyallinvert(int monid, uae_u8 *src, uae_u8 *dst, int pwidth, int pheight, int srcbytesperrow, int srcpixbytes, int dstbytesperrow, int dstpixbytes, bool direct, int mode_convert) { int x, y, w; @@ -4359,7 +4411,7 @@ static void copyallinvert (uae_u8 *src, uae_u8 *dst, int pwidth, int pheight, in for (y = 0; y < pheight; y++) { for (x = 0; x < w; x++) src2[x] ^= 0xff; - copyrow (src, dst, 0, y, pwidth, srcbytesperrow, srcpixbytes, y, dstbytesperrow, dstpixbytes, direct, mode_convert); + copyrow(monid, src, dst, 0, y, pwidth, srcbytesperrow, srcpixbytes, y, dstbytesperrow, dstpixbytes, direct, mode_convert); for (x = 0; x < w; x++) src2[x] ^= 0xff; src2 += srcbytesperrow; @@ -4367,12 +4419,13 @@ static void copyallinvert (uae_u8 *src, uae_u8 *dst, int pwidth, int pheight, in } } -static void copyall (uae_u8 *src, uae_u8 *dst, int pwidth, int pheight, int srcbytesperrow, int srcpixbytes, int dstbytesperrow, int dstpixbytes, bool direct, int mode_convert) +static void copyall (int monid, uae_u8 *src, uae_u8 *dst, int pwidth, int pheight, int srcbytesperrow, int srcpixbytes, int dstbytesperrow, int dstpixbytes, bool direct, int mode_convert) { + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; int y; if (direct) { - int w = pwidth * picasso_vidinfo.pixbytes; + int w = pwidth * vidinfo->pixbytes; for (y = 0; y < pheight; y++) { memcpy (dst, src, w); dst += dstbytesperrow; @@ -4380,53 +4433,55 @@ static void copyall (uae_u8 *src, uae_u8 *dst, int pwidth, int pheight, int srcb } } else { for (y = 0; y < pheight; y++) - copyrow (src, dst, 0, y, pwidth, srcbytesperrow, srcpixbytes, y, dstbytesperrow, dstpixbytes, direct, mode_convert); + copyrow (monid, src, dst, 0, y, pwidth, srcbytesperrow, srcpixbytes, y, dstbytesperrow, dstpixbytes, direct, mode_convert); } } -uae_u8 *getrtgbuffer (int *widthp, int *heightp, int *pitch, int *depth, uae_u8 *palette) +uae_u8 *getrtgbuffer(int monid, int *widthp, int *heightp, int *pitch, int *depth, uae_u8 *palette) { + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; + struct picasso96_state_struct *state = &picasso96_state[monid]; uae_u8 *src = gfxmem_bank.start + natmem_offset; - int off = picasso96_state.XYOffset - gfxmem_bank.start; + int off = state->XYOffset - gfxmem_bank.start; int width, height, pixbytes; uae_u8 *dst; int convert; int hmode; - if (!picasso_vidinfo.extra_mem) + if (!vidinfo->extra_mem) return NULL; - width = picasso96_state.VirtualWidth; - height = picasso96_state.VirtualHeight; - pixbytes = picasso96_state.BytesPerPixel == 1 && palette ? 1 : 4; + width = state->VirtualWidth; + height = state->VirtualHeight; + pixbytes = state->BytesPerPixel == 1 && palette ? 1 : 4; dst = xmalloc (uae_u8, width * height * pixbytes); if (!dst) return NULL; hmode = pixbytes == 1 ? RGBFB_CLUT : RGBFB_B8G8R8A8; - convert = getconvert (picasso96_state.RGBFormat, pixbytes); - alloc_colors_picasso(8, 8, 8, 16, 8, 0, picasso96_state.RGBFormat); + convert = getconvert (state->RGBFormat, pixbytes); + alloc_colors_picasso(8, 8, 8, 16, 8, 0, state->RGBFormat); if (pixbytes > 1 && hmode != convert) { - copyall (src + off, dst, width, height, picasso96_state.BytesPerRow, picasso96_state.BytesPerPixel, width * pixbytes, pixbytes, false, convert); + copyall (monid, src + off, dst, width, height, state->BytesPerRow, state->BytesPerPixel, width * pixbytes, pixbytes, false, convert); } else { uae_u8 *dstp = dst; uae_u8 *srcp = src; for (int y = 0; y < height; y++) { memcpy (dstp, srcp, width * pixbytes); dstp += width * pixbytes; - srcp += picasso96_state.BytesPerRow; + srcp += state->BytesPerRow; } } if (pixbytes == 1) { for (int i = 0; i < 256; i++) { - palette[i * 3 + 0] = picasso96_state.CLUT[i].Red; - palette[i * 3 + 1] = picasso96_state.CLUT[i].Green; - palette[i * 3 + 2] = picasso96_state.CLUT[i].Blue; + palette[i * 3 + 0] = state->CLUT[i].Red; + palette[i * 3 + 1] = state->CLUT[i].Green; + palette[i * 3 + 2] = state->CLUT[i].Blue; } } - gfx_set_picasso_colors(picasso96_state.RGBFormat); + gfx_set_picasso_colors(monid, state->RGBFormat); *widthp = width; *heightp = height; @@ -4436,46 +4491,49 @@ uae_u8 *getrtgbuffer (int *widthp, int *heightp, int *pitch, int *depth, uae_u8 return dst; } -void freertgbuffer (uae_u8 *dst) +void freertgbuffer(int monid, uae_u8 *dst) { xfree (dst); } -void picasso_invalidate (int x, int y, int w, int h) +void picasso_invalidate(int monid, int x, int y, int w, int h) { - DX_Invalidate (x, y, w, h); + DX_Invalidate(&AMonitors[monid], x, y, w, h); } -static bool picasso_flushpixels (int index, uae_u8 *src, int off) +static bool picasso_flushpixels(int index, uae_u8 *src, int off) { + int monid = currprefs.rtgboards[index].monitor_id; + struct picasso96_state_struct *state = &picasso96_state[monid]; uae_u8 *src_start; uae_u8 *src_end; int lock = 0; uae_u8 *dst = NULL; ULONG_PTR gwwcnt; - int pwidth = picasso96_state.Width > picasso96_state.VirtualWidth ? picasso96_state.VirtualWidth : picasso96_state.Width; - int pheight = picasso96_state.Height > picasso96_state.VirtualHeight ? picasso96_state.VirtualHeight : picasso96_state.Height; + int pwidth = state->Width > state->VirtualWidth ? state->VirtualWidth : state->Width; + int pheight = state->Height > state->VirtualHeight ? state->VirtualHeight : state->Height; int maxy = -1; int miny = pheight - 1; int flushlines = 0, matchcount = 0; + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; src_start = src + (off & ~gwwpagemask[index]); - src_end = src + ((off + picasso96_state.BytesPerRow * pheight + gwwpagesize[index] - 1) & ~gwwpagemask[index]); + src_end = src + ((off + state->BytesPerRow * pheight + gwwpagesize[index] - 1) & ~gwwpagemask[index]); #if 0 - write_log (_T("%dx%d %dx%d %dx%d (%dx%d)\n"), picasso96_state.Width, picasso96_state.Width, - picasso96_state.VirtualWidth, picasso96_state.VirtualHeight, + write_log (_T("%dx%d %dx%d %dx%d (%dx%d)\n"), state->Width, state->Width, + state->VirtualWidth, state->VirtualHeight, picasso_vidinfo.width, picasso_vidinfo.height, pwidth, pheight); #endif - if (!picasso_vidinfo.extra_mem || !gwwbuf[index] || src_start >= src_end) { + if (!vidinfo->extra_mem || !gwwbuf[index] || src_start >= src_end) { return false; } if (flashscreen) { - full_refresh = 1; + vidinfo->full_refresh = 1; } - if (full_refresh || rtg_clear_flag) - full_refresh = -1; + if (vidinfo->full_refresh || vidinfo->rtg_clear_flag) + vidinfo->full_refresh = -1; for (;;) { bool dofull; @@ -4486,9 +4544,9 @@ static bool picasso_flushpixels (int index, uae_u8 *src, int off) break; } - if (full_refresh < 0) { + if (vidinfo->full_refresh < 0) { gwwcnt = (src_end - src_start) / gwwpagesize[index] + 1; - full_refresh = 1; + vidinfo->full_refresh = 1; for (int i = 0; i < gwwcnt; i++) gwwbuf[index][i] = src_start + i * gwwpagesize[index]; } else { @@ -4505,13 +4563,13 @@ static bool picasso_flushpixels (int index, uae_u8 *src, int off) dofull = gwwcnt >= ((src_end - src_start) / gwwpagesize[index]) * 80 / 100; - dst = gfx_lock_picasso (dofull, rtg_clear_flag != 0); - if (rtg_clear_flag) - rtg_clear_flag--; + dst = gfx_lock_picasso(monid, dofull, vidinfo->rtg_clear_flag != 0); + if (vidinfo->rtg_clear_flag) + vidinfo->rtg_clear_flag--; if (dst == NULL) break; lock = 1; - dst += picasso_vidinfo.offset; + dst += vidinfo->offset; if (doskip () && p96skipmode == 2) { break; @@ -4519,15 +4577,15 @@ static bool picasso_flushpixels (int index, uae_u8 *src, int off) if (dofull) { if (flashscreen != 0) - copyallinvert (src + off, dst, pwidth, pheight, - picasso96_state.BytesPerRow, picasso96_state.BytesPerPixel, - picasso_vidinfo.rowbytes, picasso_vidinfo.pixbytes, - picasso96_state.RGBFormat == host_mode, picasso_convert); + copyallinvert(monid, src + off, dst, pwidth, pheight, + state->BytesPerRow, state->BytesPerPixel, + vidinfo->rowbytes, vidinfo->pixbytes, + state->RGBFormat == vidinfo->host_mode, vidinfo->picasso_convert); else - copyall (src + off, dst, pwidth, pheight, - picasso96_state.BytesPerRow, picasso96_state.BytesPerPixel, - picasso_vidinfo.rowbytes, picasso_vidinfo.pixbytes, - picasso96_state.RGBFormat == host_mode, picasso_convert); + copyall(monid, src + off, dst, pwidth, pheight, + state->BytesPerRow, state->BytesPerPixel, + vidinfo->rowbytes, vidinfo->pixbytes, + state->RGBFormat == vidinfo->host_mode, vidinfo->picasso_convert); miny = 0; maxy = pheight; @@ -4547,27 +4605,27 @@ static bool picasso_flushpixels (int index, uae_u8 *src, int off) realoffset = 0; } - y = realoffset / picasso96_state.BytesPerRow; + y = realoffset / state->BytesPerRow; if (y < pheight) { - int w = gwwpagesize[index] / picasso96_state.BytesPerPixel; - x = (realoffset % picasso96_state.BytesPerRow) / picasso96_state.BytesPerPixel; + int w = gwwpagesize[index] / state->BytesPerPixel; + x = (realoffset % state->BytesPerRow) / state->BytesPerPixel; if (x < pwidth) { - copyrow (src + off, dst, x, y, pwidth - x, - picasso96_state.BytesPerRow, picasso96_state.BytesPerPixel, - y, picasso_vidinfo.rowbytes, picasso_vidinfo.pixbytes, - picasso96_state.RGBFormat == host_mode, picasso_convert); + copyrow(monid, src + off, dst, x, y, pwidth - x, + state->BytesPerRow, state->BytesPerPixel, + y, vidinfo->rowbytes, vidinfo->pixbytes, + state->RGBFormat == vidinfo->host_mode, vidinfo->picasso_convert); flushlines++; } - w = (gwwpagesize[index] - (picasso96_state.BytesPerRow - x * picasso96_state.BytesPerPixel)) / picasso96_state.BytesPerPixel; + w = (gwwpagesize[index] - (state->BytesPerRow - x * state->BytesPerPixel)) / state->BytesPerPixel; if (y < miny) miny = y; y++; while (y < pheight && w > 0) { int maxw = w > pwidth ? pwidth : w; - copyrow (src + off, dst, 0, y, maxw, - picasso96_state.BytesPerRow, picasso96_state.BytesPerPixel, - y, picasso_vidinfo.rowbytes, picasso_vidinfo.pixbytes, - picasso96_state.RGBFormat == host_mode, picasso_convert); + copyrow(monid, src + off, dst, 0, y, maxw, + state->BytesPerRow, state->BytesPerPixel, + y, vidinfo->rowbytes, vidinfo->pixbytes, + state->RGBFormat == vidinfo->host_mode, vidinfo->picasso_convert); w -= maxw; y++; flushlines++; @@ -4588,31 +4646,31 @@ static bool picasso_flushpixels (int index, uae_u8 *src, int off) if (currprefs.leds_on_screen & STATUSLINE_RTG) { if (dst == NULL) { - dst = gfx_lock_picasso (false, false); + dst = gfx_lock_picasso(monid, false, false); if (dst) lock = 1; } if (dst) { if (!(currprefs.leds_on_screen & STATUSLINE_TARGET)) { - picasso_statusline (dst); + picasso_statusline(monid, dst); } - maxy = picasso_vidinfo.height; - if (miny > picasso_vidinfo.height - TD_TOTAL_HEIGHT) - miny = picasso_vidinfo.height - TD_TOTAL_HEIGHT; + maxy = vidinfo->height; + if (miny > vidinfo->height - TD_TOTAL_HEIGHT) + miny = vidinfo->height - TD_TOTAL_HEIGHT; } } if (maxy >= 0) { if (doskip () && p96skipmode == 4) { ; } else { - picasso_invalidate (0, miny, pwidth, maxy - miny); + picasso_invalidate(monid, 0, miny, pwidth, maxy - miny); } } if (lock) - gfx_unlock_picasso (true); + gfx_unlock_picasso(monid, true); if (dst && gwwcnt) { - full_refresh = 0; + vidinfo->full_refresh = 0; } return lock != 0; } @@ -4625,11 +4683,15 @@ static void *render_thread(void *v) bool flush = (idx & 0x80000000) != 0; if (idx == -1) break; - if (picasso_on && picasso_requested_on) { + idx &= 0xff; + int monid = currprefs.rtgboards[idx].monitor_id; + struct amigadisplay *ad = &adisplays[monid]; + if (ad->picasso_on && ad->picasso_requested_on) { lockrtg(); - if (!picasso_flushpixels(idx, gfxmem_banks[idx]->start + natmem_offset, picasso96_state.XYOffset - gfxmem_banks[idx]->start)) { + struct picasso96_state_struct *state = &picasso96_state[monid]; + if (!picasso_flushpixels(idx, gfxmem_banks[idx]->start + natmem_offset, state->XYOffset - gfxmem_banks[idx]->start)) { if (flush) - gfx_unlock_picasso(true); + gfx_unlock_picasso(monid, true); } unlockrtg(); } @@ -4679,8 +4741,9 @@ addrbank *gfxmem_banks[MAX_RTG_BOARDS]; /* Call this function first, near the beginning of code flow * Place in InitGraphics() which seems reasonable... * Also put it in reset_drawing() for safe-keeping. */ -void InitPicasso96 (void) +void InitPicasso96(int monid) { + struct picasso96_state_struct *state = &picasso96_state[monid]; int i; gfxmem_banks[0] = &gfxmem_bank; @@ -4691,7 +4754,7 @@ void InitPicasso96 (void) //fastscreen oldscr = 0; //fastscreen - memset (&picasso96_state_uaegfx, 0, sizeof (struct picasso96_state_struct)); + memset (state, 0, sizeof (struct picasso96_state_struct)); for (i = 0; i < 256; i++) { p2ctab[i][0] = (((i & 128) ? 0x01000000 : 0) @@ -5017,9 +5080,10 @@ static void inituaegfxfuncs(TrapContext *ctx, uaecptr start, uaecptr ABI) initvblankABI(ctx, uaegfx_base, ABI); } -void picasso_reset (void) +void picasso_reset(int monid) { - if (currprefs.rtg_multithread) { + struct picasso96_state_struct *state = &picasso96_state[monid]; + if (!monid && currprefs.rtg_multithread) { if (!render_pipe) { InitializeCriticalSection(&render_cs); render_pipe = xmalloc(smp_comm_pipe, 1); @@ -5038,8 +5102,11 @@ void picasso_reset (void) uaegfx_active = 0; interrupt_enabled = 0; reserved_gfxmem = 0; - resetpalette (); - InitPicasso96 (); + resetpalette(state); + InitPicasso96(monid); + } + if (is_uaegfx_active() && currprefs.rtgboards[0].monitor_id > 0) { + close_rtg(currprefs.rtgboards[0].monitor_id); } } @@ -5236,42 +5303,45 @@ void restore_p96_finish (void) set_gc_called = 1; init_picasso_screen (); init_hz_p96 (); - picasso_refresh (); + picasso_refresh(); } #endif } uae_u8 *restore_p96 (uae_u8 *src) { + struct amigadisplay *ad = &adisplays[0]; + struct picasso96_state_struct *state = &picasso96_state[0]; + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[0]; uae_u32 flags; int i; if (restore_u32 () != 2) return src; - InitPicasso96 (); + InitPicasso96(0); flags = restore_u32 (); - picasso_requested_on = !!(flags & 1); + ad->picasso_requested_on = !!(flags & 1); hwsprite = !!(flags & 8); cursorvisible = !!(flags & 16); - picasso96_state_uaegfx.SwitchState = picasso_requested_on; - picasso_on = 0; + state->SwitchState = ad->picasso_requested_on; + ad->picasso_on = 0; init_picasso_screen_called = 0; set_gc_called = !!(flags & 2); - set_panning_called = !!(flags & 4); + vidinfo->set_panning_called = !!(flags & 4); interrupt_enabled = !!(flags & 32); changed_prefs.rtgboards[0].rtgmem_size = restore_u32 (); - picasso96_state_uaegfx.Address = restore_u32 (); - picasso96_state_uaegfx.RGBFormat = (RGBFTYPE)restore_u32 (); - picasso96_state_uaegfx.Width = restore_u16 (); - picasso96_state_uaegfx.Height = restore_u16 (); - picasso96_state_uaegfx.VirtualWidth = restore_u16 (); - picasso96_state_uaegfx.VirtualHeight = restore_u16 (); - picasso96_state_uaegfx.XOffset = restore_u16 (); - picasso96_state_uaegfx.YOffset = restore_u16 (); - picasso96_state_uaegfx.GC_Depth = restore_u8 (); - picasso96_state_uaegfx.GC_Flags = restore_u8 (); - picasso96_state_uaegfx.BytesPerRow = restore_u16 (); - picasso96_state_uaegfx.BytesPerPixel = restore_u8 (); + state->Address = restore_u32 (); + state->RGBFormat = (RGBFTYPE)restore_u32 (); + state->Width = restore_u16 (); + state->Height = restore_u16 (); + state->VirtualWidth = restore_u16 (); + state->VirtualHeight = restore_u16 (); + state->XOffset = restore_u16 (); + state->YOffset = restore_u16 (); + state->GC_Depth = restore_u8 (); + state->GC_Flags = restore_u8 (); + state->BytesPerRow = restore_u16 (); + state->BytesPerPixel = restore_u8 (); uaegfx_base = restore_u32 (); uaegfx_rom = restore_u32 (); boardinfo = restore_u32 (); @@ -5279,19 +5349,22 @@ uae_u8 *restore_p96 (uae_u8 *src) cursorrgb[i] = restore_u32 (); if (flags & 64) { for (i = 0; i < 256; i++) { - picasso96_state_uaegfx.CLUT[i].Red = restore_u8 (); - picasso96_state_uaegfx.CLUT[i].Green = restore_u8 (); - picasso96_state_uaegfx.CLUT[i].Blue = restore_u8 (); + state->CLUT[i].Red = restore_u8 (); + state->CLUT[i].Green = restore_u8 (); + state->CLUT[i].Blue = restore_u8 (); } } - picasso96_state_uaegfx.HostAddress = NULL; - picasso_SetPanningInit(); - picasso96_state_uaegfx.Extent = picasso96_state_uaegfx.Address + picasso96_state_uaegfx.BytesPerRow * picasso96_state_uaegfx.VirtualHeight; + state->HostAddress = NULL; + picasso_SetPanningInit(state); + state->Extent = state->Address + state->BytesPerRow * state->VirtualHeight; return src; } uae_u8 *save_p96 (int *len, uae_u8 *dstptr) { + struct amigadisplay *ad = &adisplays[0]; + struct picasso96_state_struct *state = &picasso96_state[0]; + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[0]; uae_u8 *dstbak, *dst; int i; @@ -5302,30 +5375,30 @@ uae_u8 *save_p96 (int *len, uae_u8 *dstptr) else dstbak = dst = xmalloc (uae_u8, 1000); save_u32 (2); - save_u32 ((picasso_on ? 1 : 0) | (set_gc_called ? 2 : 0) | (set_panning_called ? 4 : 0) | + save_u32 ((ad->picasso_on ? 1 : 0) | (set_gc_called ? 2 : 0) | (vidinfo->set_panning_called ? 4 : 0) | (hwsprite ? 8 : 0) | (cursorvisible ? 16 : 0) | (interrupt_enabled ? 32 : 0) | 64); save_u32 (currprefs.rtgboards[0].rtgmem_size); - save_u32 (picasso96_state_uaegfx.Address); - save_u32 (picasso96_state_uaegfx.RGBFormat); - save_u16 (picasso96_state_uaegfx.Width); - save_u16 (picasso96_state_uaegfx.Height); - save_u16 (picasso96_state_uaegfx.VirtualWidth); - save_u16 (picasso96_state_uaegfx.VirtualHeight); - save_u16 (picasso96_state_uaegfx.XOffset); - save_u16 (picasso96_state_uaegfx.YOffset); - save_u8 (picasso96_state_uaegfx.GC_Depth); - save_u8 (picasso96_state_uaegfx.GC_Flags); - save_u16 (picasso96_state_uaegfx.BytesPerRow); - save_u8 (picasso96_state_uaegfx.BytesPerPixel); + save_u32 (state->Address); + save_u32 (state->RGBFormat); + save_u16 (state->Width); + save_u16 (state->Height); + save_u16 (state->VirtualWidth); + save_u16 (state->VirtualHeight); + save_u16 (state->XOffset); + save_u16 (state->YOffset); + save_u8 (state->GC_Depth); + save_u8 (state->GC_Flags); + save_u16 (state->BytesPerRow); + save_u8 (state->BytesPerPixel); save_u32 (uaegfx_base); save_u32 (uaegfx_rom); save_u32 (boardinfo); for (i = 0; i < 4; i++) save_u32 (cursorrgb[i]); for (i = 0; i < 256; i++) { - save_u8 (picasso96_state_uaegfx.CLUT[i].Red); - save_u8 (picasso96_state_uaegfx.CLUT[i].Green); - save_u8 (picasso96_state_uaegfx.CLUT[i].Blue); + save_u8 (state->CLUT[i].Red); + save_u8 (state->CLUT[i].Green); + save_u8 (state->CLUT[i].Blue); } *len = dst - dstbak; return dstbak; diff --git a/od-win32/picasso96_win.h b/od-win32/picasso96_win.h index 6c13b2c6..4342ccd6 100644 --- a/od-win32/picasso96_win.h +++ b/od-win32/picasso96_win.h @@ -541,52 +541,58 @@ struct picasso96_state_struct long XYOffset; }; -extern void InitPicasso96 (void); +extern void InitPicasso96(int monid); extern int uaegfx_card_found; -extern struct picasso96_state_struct picasso96_state; -extern uae_u16 picasso96_pixel_format; - -extern void picasso_enablescreen (int on); -extern void picasso_refresh (void); -extern void init_hz_p96 (void); -extern void picasso_handle_hsync (void); -extern void picasso_handle_vsync (void); -extern void picasso_trigger_vblank (void); -extern void picasso_reset (void); -extern bool picasso_is_active (void); -extern int picasso_setwincursor (void); -extern int picasso_palette (struct MyCLUTEntry *CLUT); +extern struct picasso96_state_struct picasso96_state[MAX_AMIGAMONITORS]; + +extern void picasso_enablescreen(int monid, int on); +extern void picasso_refresh(int monid); +extern void init_hz_p96(int monid); +extern void picasso_handle_hsync(void); +extern void picasso_handle_vsync(void); +extern void picasso_trigger_vblank(void); +extern void picasso_reset(int monid); +extern bool picasso_is_active(int monid); +extern int picasso_setwincursor(int monid); +extern int picasso_palette(int monid, struct MyCLUTEntry *CLUT); extern void picasso_allocatewritewatch (int index, int gfxmemsize); extern void picasso_getwritewatch (int index, int offset); extern bool picasso_is_vram_dirty (int index, uaecptr addr, int size); -extern void picasso_statusline (uae_u8 *dst); -extern void picasso_invalidate (int x, int y, int w, int h); +extern void picasso_statusline (int monid, uae_u8 *dst); +extern void picasso_invalidate(int monid, int x, int y, int w, int h); extern void picasso_free(void); /* This structure describes the UAE-side framebuffer for the Picasso * screen. */ struct picasso_vidbuf_description { - int width, height, depth; - int rowbytes, pixbytes, offset; - int extra_mem; /* nonzero if there's a second buffer that must be updated */ - uae_u32 rgbformat; - uae_u32 selected_rgbformat; - uae_u32 clut[256]; + int width, height, depth; + int rowbytes, pixbytes, offset; + int extra_mem; /* nonzero if there's a second buffer that must be updated */ + uae_u32 rgbformat; + uae_u32 selected_rgbformat; + uae_u32 clut[256]; + int picasso_convert, host_mode; + int ohost_mode, orgbformat; + int full_refresh; + int set_panning_called; + int rtg_clear_flag; + bool picasso_active; + bool picasso_changed; + uae_atomic picasso_state_change; }; -extern struct picasso_vidbuf_description picasso_vidinfo; +extern struct picasso_vidbuf_description picasso_vidinfo[MAX_AMIGAMONITORS]; -extern void gfx_set_picasso_modeinfo (RGBFTYPE rgbfmt); -extern void gfx_set_picasso_colors (RGBFTYPE rgbfmt); -extern void gfx_set_picasso_baseaddr (uaecptr); -extern void gfx_set_picasso_state (int on); -extern uae_u8 *gfx_lock_picasso (bool, bool); -extern void gfx_unlock_picasso (bool); -extern int createwindowscursor (uaecptr src, int w, int h, int hiressprite, int doubledsprite, int chipset); +extern void gfx_set_picasso_modeinfo(int monid, RGBFTYPE rgbfmt); +extern void gfx_set_picasso_colors(int monid, RGBFTYPE rgbfmt); +extern void gfx_set_picasso_state(int monid,int on); +extern uae_u8 *gfx_lock_picasso(int monid, bool, bool); +extern void gfx_unlock_picasso(int monid, bool); +extern int createwindowscursor(int monid, uaecptr src, int w, int h, int hiressprite, int doubledsprite, int chipset); -void fb_copyrow(uae_u8 *src, uae_u8 *dst, int x, int y, int width, int srcpixbytes, int dy); +void fb_copyrow(int monid, uae_u8 *src, uae_u8 *dst, int x, int y, int width, int srcpixbytes, int dy); extern int p96refresh_active; diff --git a/od-win32/resources/resource.h b/od-win32/resources/resource.h index 51aa0df0..3a81d821 100644 --- a/od-win32/resources/resource.h +++ b/od-win32/resources/resource.h @@ -400,7 +400,6 @@ #define IDS_NUMSG_NO_PPC 404 #define IDS_NUMSG_UAEBOOTROM_PCC 405 #define IDS_AUTOSCALE_OVERSCAN_BLANK 408 -#define IDS_SCREEN_ADAPTIVE_SYNC 409 #define IDS_NUMSG_NOMEMORY 410 #define IDS_EXPANSION_CATEGORY 411 #define IDS_WINUAETITLE_PAUSED 412 @@ -455,6 +454,7 @@ #define IDC_PORT1_JOYSMODE 1030 #define IDC_SCREENMODE_RTG2 1030 #define IDC_PORT2_JOYS 1031 +#define IDC_SCREENMODE_NATIVE3 1031 #define IDC_PORT3_JOYS 1032 #define IDC_PARALLEL 1033 #define IDC_PORT0_AF 1033 @@ -763,7 +763,7 @@ #define IDC_OCS 1520 #define IDC_HDFLOPPY 1520 #define IDC_SETTINGSTEXT3 1520 -#define IDC_DISPLAY_TEARING 1520 +#define IDC_DISPLAY_VARSYNC 1520 #define IDC_ECS_AGNUS 1521 #define IDC_ECS_DENISE 1522 #define IDC_ECS 1523 @@ -1076,6 +1076,7 @@ #define IDC_CS_KSMIRROR_E0 1716 #define IDC_STRINGBOXEDIT 1716 #define IDC_SOUND_OPENAL 1716 +#define IDC_MONITOREMU_MON 1716 #define IDC_CS_CD32CD 1717 #define IDC_CS_CD32C2P 1718 #define IDC_SOUND_PORTAUDIO 1718 diff --git a/od-win32/resources/winuae.rc b/od-win32/resources/winuae.rc index c05d7083..2876e4ce 100644 --- a/od-win32/resources/winuae.rc +++ b/od-win32/resources/winuae.rc @@ -153,18 +153,18 @@ BEGIN RTEXT "Fullscreen:",IDC_STATIC,3,33,51,15,SS_CENTERIMAGE COMBOBOX IDC_RESOLUTION,59,33,76,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_RESOLUTIONDEPTH,144,33,62,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_REFRESHRATE,263,34,122,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_REFRESHRATE,287,34,98,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP RTEXT "Windowed:",IDC_STATIC,2,54,51,15,SS_CENTERIMAGE EDITTEXT IDC_XSIZE,59,56,43,12,ES_NUMBER EDITTEXT IDC_YSIZE,113,56,43,12,ES_NUMBER - COMBOBOX IDC_DISPLAY_BUFFERCNT,263,56,122,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_DISPLAY_BUFFERCNT,288,56,97,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP GROUPBOX "Settings",IDC_SETTINGSTEXT,1,86,283,183 - RTEXT "Native:",IDC_STATIC,9,98,48,15,SS_CENTERIMAGE - COMBOBOX IDC_SCREENMODE_NATIVE,61,98,71,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_SCREENMODE_NATIVE2,142,98,127,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP - RTEXT "RTG:",IDC_STATIC,8,115,49,15,SS_CENTERIMAGE - COMBOBOX IDC_SCREENMODE_RTG,61,118,71,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_SCREENMODE_RTG2,142,118,127,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP + RTEXT "Native:",IDC_STATIC,18,98,32,15,SS_CENTERIMAGE + COMBOBOX IDC_SCREENMODE_NATIVE,54,98,71,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_SCREENMODE_NATIVE2,131,98,108,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP + RTEXT "RTG:",IDC_STATIC,19,115,31,15,SS_CENTERIMAGE + COMBOBOX IDC_SCREENMODE_RTG,54,118,71,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_SCREENMODE_RTG2,131,118,107,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP CONTROL "Blacker than black [] Borderblanked black is blacker than display area black.",IDC_BLACKER_THAN_BLACK, "Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,11,140,139,10 CONTROL "Filtered low resolution [] When scaling hires to lores or superhires to hires, show average color of pixel instead of dropping every other pixel.",IDC_LORES_SMOOTHED, @@ -203,7 +203,8 @@ BEGIN CONTROL "Double, frames",IDC_LM_IDOUBLED,"Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_TABSTOP,299,251,90,10 CONTROL "Double, fields",IDC_LM_IDOUBLED2,"Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_TABSTOP,299,264,90,10 CONTROL "Double, fields+",IDC_LM_IDOUBLED3,"Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_TABSTOP,299,277,90,10 - CONTROL "Allow tearing",IDC_DISPLAY_TEARING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,170,58,84,10 + CONTROL "VRR monitor. Do not tick!",IDC_DISPLAY_VARSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,170,58,112,10 + COMBOBOX IDC_SCREENMODE_NATIVE3,246,98,31,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP END IDD_MEMORY DIALOGEX 0, 0, 396, 266 @@ -734,16 +735,16 @@ BEGIN "Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,12,68,194,10 CONTROL "Cycle-exact (DMA/Memory accesses)",IDC_CYCLEEXACTMEMORY, "Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,12,81,194,10 - RTEXT "Chipset Extra:",IDC_STATIC,72,108,71,15,SS_CENTERIMAGE - COMBOBOX IDC_CS_EXT,148,109,49,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + RTEXT "Chipset Extra:",IDC_STATIC,38,108,71,15,SS_CENTERIMAGE + COMBOBOX IDC_CS_EXT,116,109,88,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP GROUPBOX "Options",IDC_STATIC,221,0,173,137 CONTROL "Keyboard connected",IDC_KEYBOARD_CONNECTED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,234,15,150,10 CONTROL "Immediate Blitter [] Faster but less compatible blitter emulation.",IDC_BLITIMM, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,234,47,150,10 CONTROL "Wait for Blitter [] Compatibility hack for programs that don't wait for the blitter correctly, causing graphics corruption if CPU is too fast.",IDC_BLITWAIT, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,234,60,150,10 - LTEXT "Video port display hardware:",IDC_STATIC,237,91,117,15,SS_CENTERIMAGE - COMBOBOX IDC_MONITOREMU,237,109,147,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Monitor:",IDC_STATIC,240,119,68,15,SS_CENTERIMAGE,WS_EX_RIGHT + COMBOBOX IDC_MONITOREMU,237,103,147,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP GROUPBOX "Collision Level",IDC_STATIC,1,141,393,48 CONTROL "None [] Collision hardware emulation disabled.",IDC_COLLISION0, "Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,47,157,101,10 @@ -763,6 +764,8 @@ BEGIN COMBOBOX IDC_GENLOCKFILE,12,258,356,75,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "...",IDC_GENLOCKFILESELECT,375,257,10,15 CONTROL "Keep aspect ratio",IDC_GENLOCK_KEEP_ASPECT,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,13,242,214,10 + COMBOBOX IDC_MONITOREMU_MON,319,121,65,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Video port display hardware:",IDC_STATIC,241,85,117,15,SS_CENTERIMAGE END IDD_CHIPSET2 DIALOGEX 0, 0, 396, 317 @@ -1189,39 +1192,42 @@ BEGIN CTEXT "Enter address",IDC_DBG_ADDRINPUTTXT,20,1,100,10,SS_CENTERIMAGE | WS_TABSTOP END -IDD_EXPANSION DIALOGEX 0, 0, 396, 194 +IDD_EXPANSION DIALOGEX 0, 0, 396, 208 STYLE DS_LOCALEDIT | DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD FONT 8, "MS Sans Serif", 0, 0, 0x1 BEGIN - GROUPBOX "RTG Graphics Card",IDC_STATIC,1,0,393,189 - COMBOBOX IDC_RTG_Z2Z3,26,14,215,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_RTG_NUM,248,14,37,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP - RTEXT "VRAM size: [] Graphics card memory. Required for RTG (Picasso96) emulation.",IDC_GFXCARDTEXT,2,35,76,10,SS_NOTIFY | SS_CENTERIMAGE - CONTROL "",IDC_P96MEM,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,88,31,103,20 - EDITTEXT IDC_P96RAM,201,34,40,12,ES_CENTER | ES_READONLY + GROUPBOX "RTG Graphics Card",IDC_STATIC,1,0,393,198 + COMBOBOX IDC_RTG_Z2Z3,26,29,215,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_RTG_NUM,248,29,37,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP + RTEXT "VRAM size: [] Graphics card memory. Required for RTG (Picasso96) emulation.",IDC_GFXCARDTEXT,2,50,76,10,SS_NOTIFY | SS_CENTERIMAGE + CONTROL "",IDC_P96MEM,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,88,46,103,20 + EDITTEXT IDC_P96RAM,201,49,40,12,ES_CENTER | ES_READONLY CONTROL "Match host and RTG color depth if possible",IDC_RTG_MATCH_DEPTH, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,25,54,177,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,25,69,177,10 CONTROL "Scale if smaller than display size setting",IDC_RTG_SCALE, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,25,67,175,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,25,82,175,10 CONTROL "Always scale in windowed mode",IDC_RTG_SCALE_ALLOW, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,25,80,170,10 - CONTROL "Always center",IDC_RTG_CENTER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,25,93,169,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,25,95,170,10 + CONTROL "Always center",IDC_RTG_CENTER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,25,108,169,10 CONTROL "Hardware vertical blank interrupt",IDC_RTG_VBINTERRUPT, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,25,106,157,10 - CONTROL "Hardware sprite emulation",IDC_RTG_HWSPRITE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,207,106,148,10 - CTEXT "Color modes:",IDC_STATIC,295,18,83,10,SS_CENTERIMAGE - COMBOBOX IDC_RTG_8BIT,296,33,82,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_RTG_16BIT,296,50,82,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_RTG_24BIT,296,68,82,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_RTG_32BIT,296,85,82,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_RTG_DISPLAYSELECT,11,125,371,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP - CTEXT "Refresh rate:",IDC_STATIC,30,149,83,10,SS_CENTERIMAGE - COMBOBOX IDC_RTG_VBLANKRATE,29,162,84,150,CBS_DROPDOWN | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP - CTEXT "Buffer mode:",IDC_STATIC,154,149,83,10,SS_CENTERIMAGE - COMBOBOX IDC_RTG_BUFFERCNT,153,162,84,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP - CTEXT "Aspect ratio:",IDC_STATIC,282,149,83,10,SS_CENTERIMAGE - COMBOBOX IDC_RTG_SCALE_ASPECTRATIO,282,162,84,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP - CONTROL "Multithreaded",IDC_RTG_THREAD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,207,93,83,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,25,121,157,10 + CONTROL "Hardware sprite emulation",IDC_RTG_HWSPRITE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,207,121,148,10 + CTEXT "Color modes:",IDC_STATIC,295,33,83,10,SS_CENTERIMAGE + COMBOBOX IDC_RTG_8BIT,296,48,82,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_RTG_16BIT,296,65,82,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_RTG_24BIT,296,83,82,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_RTG_32BIT,296,100,82,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_RTG_DISPLAYSELECT,11,140,371,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP + CTEXT "Refresh rate:",IDC_STATIC,30,164,83,10,SS_CENTERIMAGE + COMBOBOX IDC_RTG_VBLANKRATE,29,179,84,150,CBS_DROPDOWN | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP + CTEXT "Buffer mode:",IDC_STATIC,154,164,83,10,SS_CENTERIMAGE + COMBOBOX IDC_RTG_BUFFERCNT,153,179,84,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP + CTEXT "Aspect ratio:",IDC_STATIC,282,164,83,10,SS_CENTERIMAGE + COMBOBOX IDC_RTG_SCALE_ASPECTRATIO,282,179,84,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP + CONTROL "Multithreaded",IDC_RTG_THREAD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,207,108,83,10 + LTEXT "Board:",IDC_STATIC,29,14,61,10 + COMBOBOX IDC_MONITOREMU_MON,175,13,65,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Monitor:",IDC_STATIC,105,14,65,10,0,WS_EX_RIGHT END IDD_INPUTMAP DIALOGEX 0, 0, 421, 341 @@ -1370,8 +1376,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,6,1,0 - PRODUCTVERSION 3,6,1,0 + FILEVERSION 4,0,0,0 + PRODUCTVERSION 4,0,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -1387,12 +1393,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "WinUAE" - VALUE "FileVersion", "3.6.1.0" + VALUE "FileVersion", "4.0.0.0" VALUE "InternalName", "WinUAE" VALUE "LegalCopyright", "© 1996-2018 under the GNU Public License (GPL)" VALUE "OriginalFilename", "WinUAE.exe" VALUE "ProductName", "WinUAE" - VALUE "ProductVersion", "3.6.1.0" + VALUE "ProductVersion", "4.0.0.0" END END BLOCK "VarFileInfo" @@ -1667,6 +1673,7 @@ BEGIN IDD_EXPANSION, DIALOG BEGIN + BOTTOMMARGIN, 198 END IDD_INPUTMAP, DIALOG @@ -2148,7 +2155,6 @@ BEGIN IDS_NUMSG_UAEBOOTROM_PCC "PPC native OS booted with incompatible UAE boot ROM enabled.\nSelect ROM panel ""New UAE (128k, ROM, Indirect)"" option\nor disable all UAE expansions.\n" IDS_AUTOSCALE_OVERSCAN_BLANK "Overscan blanking" - IDS_SCREEN_ADAPTIVE_SYNC "Variable Sync" IDS_NUMSG_NOMEMORY "Out of memory or too much Z3 autoconfig space configured.\nIf 64-bit, make sure RTG board is first in board list." IDS_EXPANSION_CATEGORY "Built-in expansions\nSCSI controllers\nIDE controllers\nSASI controllers\nCustom controllers\nPCI bridgeboards\nx86 bridgeboards\nGraphics boards\nSound cards\nNetwork adapters\nDisk controllers" IDS_WINUAETITLE_PAUSED "[Paused]" diff --git a/od-win32/rp.cpp b/od-win32/rp.cpp index 12ae40f4..94d76878 100644 --- a/od-win32/rp.cpp +++ b/od-win32/rp.cpp @@ -646,6 +646,7 @@ static int winok (void) static void fixup_size (struct uae_prefs *prefs) { + struct monconfig *gm = &prefs->gfx_monitor[0]; static int done; if (done) @@ -661,7 +662,7 @@ static void fixup_size (struct uae_prefs *prefs) } if (hres > max_horiz_dbl) hres = max_horiz_dbl; - prefs->gfx_size_win.width = prefs->gfx_xcenter_size >> (RES_MAX - hres); + gm->gfx_size_win.width = prefs->gfx_xcenter_size >> (RES_MAX - hres); prefs->gf[0].gfx_filter_autoscale = 0; } if (prefs->gfx_ycenter_size > 0) { @@ -673,10 +674,10 @@ static void fixup_size (struct uae_prefs *prefs) } if (vres > max_vert_dbl) vres = max_vert_dbl; - prefs->gfx_size_win.height = (prefs->gfx_ycenter_size * 2) >> (VRES_QUAD - vres); + gm->gfx_size_win.height = (prefs->gfx_ycenter_size * 2) >> (VRES_QUAD - vres); prefs->gf[0].gfx_filter_autoscale = 0; } - write_log(_T("-> %dx%d\n"), prefs->gfx_size_win.width, prefs->gfx_size_win.height); + write_log(_T("-> %dx%d\n"), gm->gfx_size_win.width, gm->gfx_size_win.height); } static int getmult (float mult, bool *half) @@ -710,6 +711,8 @@ static int shift (int val, int shift) static void get_screenmode (struct RPScreenMode *sm, struct uae_prefs *p, bool getclip) { + struct AmigaMonitor *mon = &AMonitors[0]; + struct monconfig *gm = &p->gfx_monitor[mon->monitor_id]; int m, cf; int full = 0; int hres, vres; @@ -725,7 +728,7 @@ static void get_screenmode (struct RPScreenMode *sm, struct uae_prefs *p, bool g m = RP_SCREENMODE_SCALE_1X; cf = 0; half = false; - rtg = WIN32GFX_IsPicassoScreen () != 0; + rtg = WIN32GFX_IsPicassoScreen(mon) != 0; if (rtg) { @@ -822,8 +825,8 @@ static void get_screenmode (struct RPScreenMode *sm, struct uae_prefs *p, bool g } else if ((storeflags & RP_SCREENMODE_SCALEMASK) == RP_SCREENMODE_SCALE_TARGET) { sm->dwScreenMode &= ~RP_SCREENMODE_SCALEMASK; sm->dwScreenMode = RP_SCREENMODE_SCALE_TARGET; - sm->lTargetWidth = p->gfx_size_win.width; - sm->lTargetHeight = p->gfx_size_win.height; + sm->lTargetWidth = gm->gfx_size_win.width; + sm->lTargetHeight = gm->gfx_size_win.height; } sm->dwClipFlags = cf; @@ -832,7 +835,7 @@ static void get_screenmode (struct RPScreenMode *sm, struct uae_prefs *p, bool g rtg ? _T("RTG ") : _T(""), totalhdbl, hres, totalvdbl, vres, full, p->gfx_xcenter_pos, p->gfx_ycenter_pos, - p->gfx_size_win.width, p->gfx_size_win.height, + gm->gfx_size_win.width, gm->gfx_size_win.height, hmult, vmult, half); write_log (_T("GET_RPSM: %08X %dx%d %dx%d hres=%d (%d) vres=%d (%d) disp=%d fs=%d\n"), sm->dwScreenMode, sm->lClipLeft, sm->lClipTop, sm->lClipWidth, sm->lClipHeight, @@ -842,6 +845,10 @@ static void get_screenmode (struct RPScreenMode *sm, struct uae_prefs *p, bool g static void set_screenmode (struct RPScreenMode *sm, struct uae_prefs *p) { + struct AmigaMonitor *mon = &AMonitors[0]; + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[0]; + struct monconfig *gm = &p->gfx_monitor[mon->monitor_id]; + struct monconfig *gmc = &currprefs.gfx_monitor[mon->monitor_id]; int smm = RP_SCREENMODE_SCALE (sm->dwScreenMode); int display = RP_SCREENMODE_DISPLAY (sm->dwScreenMode); int fs = 0; @@ -877,7 +884,7 @@ static void set_screenmode (struct RPScreenMode *sm, struct uae_prefs *p) keepaspect, stretch, forcesize, integerscale); } - if (!WIN32GFX_IsPicassoScreen ()) { + if (!WIN32GFX_IsPicassoScreen(mon)) { if (smm == RP_SCREENMODE_SCALE_3X) { @@ -937,38 +944,38 @@ static void set_screenmode (struct RPScreenMode *sm, struct uae_prefs *p) p->gfx_vresolution = vres; if (sm->lClipWidth <= 0) { - p->gfx_size_win.width = shift (AMIGA_WIDTH_MAX, -hdbl); + gm->gfx_size_win.width = shift (AMIGA_WIDTH_MAX, -hdbl); } else { if (hdbl > RES_MAX) - p->gfx_size_win.width = sm->lClipWidth << (hdbl - RES_MAX); + gm->gfx_size_win.width = sm->lClipWidth << (hdbl - RES_MAX); else - p->gfx_size_win.width = sm->lClipWidth >> (RES_MAX - hdbl); + gm->gfx_size_win.width = sm->lClipWidth >> (RES_MAX - hdbl); } if (sm->lClipHeight <= 0) { - p->gfx_size_win.height = shift (AMIGA_HEIGHT_MAX, -vdbl); + gm->gfx_size_win.height = shift (AMIGA_HEIGHT_MAX, -vdbl); } else { if (vdbl > VRES_MAX) - p->gfx_size_win.height = sm->lClipHeight << (vdbl - VRES_MAX); + gm->gfx_size_win.height = sm->lClipHeight << (vdbl - VRES_MAX); else - p->gfx_size_win.height = sm->lClipHeight >> (VRES_MAX - vdbl); + gm->gfx_size_win.height = sm->lClipHeight >> (VRES_MAX - vdbl); } if (half) { - p->gfx_size_win.width = p->gfx_size_win.width * 3 / 2; - p->gfx_size_win.height = p->gfx_size_win.height * 3 / 2; + gm->gfx_size_win.width = gm->gfx_size_win.width * 3 / 2; + gm->gfx_size_win.height = gm->gfx_size_win.height * 3 / 2; } if (forcesize) { - width = p->gfx_size_win.width = sm->lTargetWidth; - height = p->gfx_size_win.height = sm->lTargetHeight; + width = gm->gfx_size_win.width = sm->lTargetWidth; + height = gm->gfx_size_win.height = sm->lTargetHeight; } if (fs == 1) { - width = p->gfx_size_fs.width = p->gfx_size_win.width; - height = p->gfx_size_fs.height = p->gfx_size_win.height; + width = gm->gfx_size_fs.width = gm->gfx_size_win.width; + height = gm->gfx_size_fs.height = gm->gfx_size_win.height; } else if (fs == 2) { - width = p->gfx_size_fs.width = disp->rect.right - disp->rect.left; - height = p->gfx_size_fs.height = disp->rect.bottom - disp->rect.top; + width = gm->gfx_size_fs.width = disp->rect.right - disp->rect.left; + height = gm->gfx_size_fs.height = disp->rect.bottom - disp->rect.top; } } @@ -991,7 +998,7 @@ static void set_screenmode (struct RPScreenMode *sm, struct uae_prefs *p) } p->rtg_horiz_zoom_mult = p->rtg_vert_zoom_mult = m; - if (WIN32GFX_IsPicassoScreen ()) { + if (WIN32GFX_IsPicassoScreen(mon)) { int m = 1; if (fs == 2) { @@ -1007,8 +1014,8 @@ static void set_screenmode (struct RPScreenMode *sm, struct uae_prefs *p) } } - p->gfx_size_win.width = picasso_vidinfo.width * m; - p->gfx_size_win.height = picasso_vidinfo.height * m; + gm->gfx_size_win.width = vidinfo->width * m; + gm->gfx_size_win.height = vidinfo->height * m; hmult = m; vmult = m; @@ -1059,8 +1066,8 @@ static void set_screenmode (struct RPScreenMode *sm, struct uae_prefs *p) p->gfx_xcenter_size = -1; p->gfx_ycenter_size = -1; if (!forcesize) { - p->gfx_size_win.width = AMIGA_WIDTH_MAX << currprefs.gfx_resolution; - p->gfx_size_win.height = AMIGA_HEIGHT_MAX << currprefs.gfx_vresolution;; + gm->gfx_size_win.width = AMIGA_WIDTH_MAX << currprefs.gfx_resolution; + gm->gfx_size_win.height = AMIGA_HEIGHT_MAX << currprefs.gfx_vresolution;; } } @@ -1091,15 +1098,15 @@ static void set_screenmode (struct RPScreenMode *sm, struct uae_prefs *p) if (log_rp & 2) { write_log(_T("%dx%d %dx%d %dx%d %08x HM=%.1f VM=%.1f\n"), sm->lClipLeft, sm->lClipTop, sm->lClipWidth, sm->lClipHeight, sm->lTargetWidth, sm->lTargetHeight, sm->dwClipFlags, hmult, vmult); - if (WIN32GFX_IsPicassoScreen ()) { + if (WIN32GFX_IsPicassoScreen(mon)) { write_log (_T("RTG WW=%d WH=%d FW=%d FH=%d HM=%.1f VM=%.1f\n"), - p->gfx_size_win.width, p->gfx_size_win.height, - p->gfx_size_fs.width, p->gfx_size_fs.height, + gm->gfx_size_win.width, gm->gfx_size_win.height, + gm->gfx_size_fs.width, gm->gfx_size_fs.height, p->rtg_horiz_zoom_mult, p->rtg_vert_zoom_mult); } else { write_log (_T("WW=%d (%d) WH=%d (%d) FW=%d (%d) FH=%d (%d) HM=%.1f VM=%.1f XP=%d YP=%d XS=%d YS=%d AS=%d AR=%d,%d\n"), - p->gfx_size_win.width, currprefs.gfx_size_win.width, p->gfx_size_win.height, currprefs.gfx_size.height, - p->gfx_size_fs.width, currprefs.gfx_size_fs.width, p->gfx_size_fs.height, currprefs.gfx_size_fs.height, + gm->gfx_size_win.width, gmc->gfx_size_win.width, gm->gfx_size_win.height, gmc->gfx_size.height, + gm->gfx_size_fs.width, gmc->gfx_size_fs.width, gm->gfx_size_fs.height, gmc->gfx_size_fs.height, p->gf[0].gfx_filter_horiz_zoom_mult, p->gf[0].gfx_filter_vert_zoom_mult, p->gfx_xcenter_pos, p->gfx_ycenter_pos, p->gfx_xcenter_size, p->gfx_ycenter_size, @@ -1107,18 +1114,18 @@ static void set_screenmode (struct RPScreenMode *sm, struct uae_prefs *p) } } - updatewinfsmode (p); + updatewinfsmode(0, p); hwndset = 0; set_config_changed (); #if 0 write_log (_T("AFTER WW=%d (%d) WH=%d (%d) FW=%d (%d) FH=%d (%d) HM=%.1f VM=%.1f XP=%d YP=%d XS=%d YS=%d AS=%d AR=%d,%d\n"), - p->gfx_size_win.width, currprefs.gfx_size_win.width, p->gfx_size_win.height, currprefs.gfx_size.height, - p->gfx_size_fs.width, currprefs.gfx_size_fs.width, p->gfx_size_fs.height, currprefs.gfx_size_fs.height, + gm->gfx_size_win.width, currprefs.gfx_size_win.width, gm->gfx_size_win.height, currprefs.gfx_size.height, + gm->gfx_size_fs.width, currprefs.gfx_size_fs.width, gm->gfx_size_fs.height, currprefs.gfx_size_fs.height, p->gf[0].gfx_filter_horiz_zoom_mult, p->gf[0].gfx_filter_vert_zoom_mult, p->gfx_xcenter_pos, p->gfx_ycenter_pos, p->gfx_xcenter_size, p->gfx_ycenter_size, p->gf[0].gfx_filter_autoscale, p->gf[0].gfx_filter_aspect, p->gf[0].gfx_filter_keep_aspect); - write_log (_T("AFTER W=%d (%d) H=%d (%d)\n"), p->gfx_size.width, currprefs.gfx_size.width, p->gfx_size.height, currprefs.gfx_size.height); + write_log (_T("AFTER W=%d (%d) H=%d (%d)\n"), gm->gfx_size.width, currprefs.gfx_size.width, gm->gfx_size.height, currprefs.gfx_size.height); #endif } @@ -1160,6 +1167,7 @@ void parse_guest_event(const TCHAR *ss) static LRESULT CALLBACK RPHostMsgFunction2 (UINT uMessage, WPARAM wParam, LPARAM lParam, LPCVOID pData, DWORD dwDataSize, LPARAM lMsgFunctionParam) { + struct AmigaMonitor *mon = &AMonitors[0]; if (log_rp & 1) { write_log (_T("RPFUNC(%s [%d], %08x, %08x, %08x, %d, %08x)\n"), getmsg (uMessage), uMessage - WM_APP, wParam, lParam, pData, dwDataSize, lMsgFunctionParam); @@ -1216,9 +1224,9 @@ static LRESULT CALLBACK RPHostMsgFunction2 (UINT uMessage, WPARAM wParam, LPARAM case RP_IPC_TO_GUEST_MOUSECAPTURE: { if (wParam & RP_MOUSECAPTURE_CAPTURED) - setmouseactive (1); + setmouseactive(0, 1); else - setmouseactive (0); + setmouseactive(0, 0); } return TRUE; case RP_IPC_TO_GUEST_DEVICECONTENT: @@ -1280,30 +1288,31 @@ static LRESULT CALLBACK RPHostMsgFunction2 (UINT uMessage, WPARAM wParam, LPARAM if (rpsc->szScreenFiltered[0]) ok = screenshotf (rpsc->szScreenFiltered, 1, 1, 0, NULL); if (rpsc->szScreenRaw[0]) { + struct vidbuf_description *avidinfo = &adisplays[0].gfxvidinfo; struct vidbuffer vb; - int w = gfxvidinfo.drawbuffer.inwidth; - int h = gfxvidinfo.drawbuffer.inheight; + int w = avidinfo->drawbuffer.inwidth; + int h = avidinfo->drawbuffer.inheight; if (!programmedmode) { h = (maxvpos + lof_store - minfirstline) << currprefs.gfx_vresolution; } if (interlace_seen && currprefs.gfx_vresolution > 0) { h -= 1 << (currprefs.gfx_vresolution - 1); } - allocvidbuffer (&vb, w, h, gfxvidinfo.drawbuffer.pixbytes * 8); + allocvidbuffer (0, &vb, w, h, avidinfo->drawbuffer.pixbytes * 8); set_custom_limits (-1, -1, -1, -1); draw_frame (&vb); ok |= screenshotf (rpsc->szScreenRaw, 1, 1, 1, &vb); if (log_rp & 2) write_log (_T("Rawscreenshot %dx%d\n"), w, h); //ok |= screenshotf (_T("c:\\temp\\1.bmp"), 1, 1, 1, &vb); - freevidbuffer (&vb); + freevidbuffer(0, &vb); } screenshotmode = ossm; if (log_rp & 2) write_log (_T("->%d\n"), ok); if (!ok) return RP_SCREENCAPTURE_ERROR; - if (WIN32GFX_IsPicassoScreen ()) { + if (WIN32GFX_IsPicassoScreen(mon)) { ret |= RP_GUESTSCREENFLAGS_MODE_DIGITAL; } else { ret |= currprefs.gfx_resolution == RES_LORES ? RP_GUESTSCREENFLAGS_HORIZONTAL_LORES : ((currprefs.gfx_resolution == RES_SUPERHIRES) ? RP_GUESTSCREENFLAGS_HORIZONTAL_SUPERHIRES : 0); @@ -1529,12 +1538,13 @@ void rp_enumdevices (void) static void sendfeatures (void) { + struct AmigaMonitor *mon = &AMonitors[0]; DWORD feat; feat = RP_FEATURE_POWERLED | RP_FEATURE_SCREEN1X | RP_FEATURE_FULLSCREEN; feat |= RP_FEATURE_PAUSE | RP_FEATURE_TURBO_CPU | RP_FEATURE_TURBO_FLOPPY | RP_FEATURE_VOLUME | RP_FEATURE_SCREENCAPTURE; feat |= RP_FEATURE_STATE | RP_FEATURE_DEVICEREADWRITE; - if (WIN32GFX_IsPicassoScreen ()) { + if (WIN32GFX_IsPicassoScreen(mon)) { if (currprefs.gfx_api) feat |= RP_FEATURE_SCREEN2X | RP_FEATURE_SCREEN3X | RP_FEATURE_SCREEN4X; } else { @@ -1547,7 +1557,7 @@ static void sendfeatures (void) feat |= RP_FEATURE_INPUTDEVICE_JOYPAD; feat |= RP_FEATURE_INPUTDEVICE_ANALOGSTICK; feat |= RP_FEATURE_INPUTDEVICE_LIGHTPEN; - write_log (_T("RP_IPC_TO_HOST_FEATURES=%x %d\n"), feat, WIN32GFX_IsPicassoScreen()); + write_log (_T("RP_IPC_TO_HOST_FEATURES=%x %d\n"), feat, WIN32GFX_IsPicassoScreen(mon)); RPSendMessagex (RP_IPC_TO_HOST_FEATURES, feat, 0, NULL, 0, &guestinfo, NULL); } @@ -1556,7 +1566,7 @@ static bool ishd(int n) struct uaedev_config_data *uci = &currprefs.mountconfig[n]; int num = -1; if (uci->ci.controller_type == HD_CONTROLLER_TYPE_UAE) { - num = n; + return uci->ci.type == UAEDEV_DIR; } else if (uci->ci.controller_type >= HD_CONTROLLER_TYPE_IDE_FIRST && uci->ci.controller_type <= HD_CONTROLLER_TYPE_IDE_LAST) { num = uci->ci.controller_unit; } else if (uci->ci.controller_type >= HD_CONTROLLER_TYPE_SCSI_FIRST && uci->ci.controller_type <= HD_CONTROLLER_TYPE_SCSI_LAST) { @@ -1567,7 +1577,7 @@ static bool ishd(int n) void rp_fixup_options (struct uae_prefs *p) { - int i; + struct monconfig *gm = &p->gfx_monitor[0]; struct RPScreenMode sm; if (!initialized) @@ -1581,8 +1591,8 @@ void rp_fixup_options (struct uae_prefs *p) maxjports = (rp_version * 256 + rp_revision) >= 2 * 256 + 3 ? MAX_JPORTS : 2; write_log (_T("w=%dx%d fs=%dx%d pos=%dx%d %dx%d HV=%d,%d J=%d\n"), - p->gfx_size_win.width, p->gfx_size_win.height, - p->gfx_size_fs.width, p->gfx_size_fs.height, + gm->gfx_size_win.width, gm->gfx_size_win.height, + gm->gfx_size_fs.width, gm->gfx_size_fs.height, p->gfx_xcenter_pos, p->gfx_ycenter_pos, p->gfx_xcenter_size, p->gfx_ycenter_size, max_horiz_dbl, max_vert_dbl, maxjports); @@ -1607,7 +1617,7 @@ void rp_fixup_options (struct uae_prefs *p) /* floppy drives */ floppy_mask = 0; - for (i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) { if (p->floppyslots[i].dfxtype >= 0) floppy_mask |= 1 << i; } @@ -1619,7 +1629,7 @@ void rp_fixup_options (struct uae_prefs *p) gameportmask[0] = gameportmask[1] = gameportmask[2] = gameportmask[3] = 0; int parportmask = 0; - for (i = 0; i < 2; i++) { + for (int i = 0; i < 2; i++) { if (p->jports[i + 2].idc.configname[0] || p->jports[i + 2].idc.name[0] || p->jports[i + 2].idc.shortid[0]) parportmask |= 1 << i; } @@ -1631,26 +1641,26 @@ void rp_fixup_options (struct uae_prefs *p) hd_mask = 0; cd_mask = 0; - for (i = 0; i < currprefs.mountitems; i++) { + for (int i = 0; i < currprefs.mountitems; i++) { if (ishd(i)) hd_mask |= 1 << i; } RPSendMessagex (RP_IPC_TO_HOST_DEVICES, RP_DEVICECATEGORY_HD, hd_mask, NULL, 0, &guestinfo, NULL); if (hd_mask) { - for (i = 0; i < currprefs.mountitems; i++) { + for (int i = 0; i < currprefs.mountitems; i++) { struct uaedev_config_data *uci = &currprefs.mountconfig[i]; if (ishd(i) && ((1 << i) & hd_mask)) rp_harddrive_image_change (i, uci->ci.readonly, uci->ci.rootdir); } } - for (i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) { + for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) { if (p->cdslots[i].inuse) cd_mask |= 1 << i; } RPSendMessagex (RP_IPC_TO_HOST_DEVICES, RP_DEVICECATEGORY_CD, cd_mask, NULL, 0, &guestinfo, NULL); if (cd_mask) { - for (i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) { + for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) { if (p->cdslots[i].inuse) rp_cd_image_change (i, p->cdslots[i].name); } @@ -1659,7 +1669,7 @@ void rp_fixup_options (struct uae_prefs *p) rp_update_volume (&currprefs); rp_turbo_cpu (currprefs.turbo_emulation); rp_turbo_floppy (currprefs.floppy_speed == 0); - for (i = 0; i <= 4; i++) + for (int i = 0; i <= 4; i++) rp_update_leds (i, 0, -1, 0); set_config_changed (); @@ -2019,12 +2029,13 @@ static uae_u64 gett (void) void rp_vsync (void) { + struct AmigaMonitor *mon = &AMonitors[0]; if (!initialized) return; if (hwndset_delay > 0) { hwndset_delay--; if (hwndset_delay == 0) - rp_set_hwnd (hAmigaWnd); + rp_set_hwnd(mon->hAmigaWnd); } if (screenmode_request) { diff --git a/od-win32/scaler_more.cpp b/od-win32/scaler_more.cpp index 28a70721..bef83ab1 100644 --- a/od-win32/scaler_more.cpp +++ b/od-win32/scaler_more.cpp @@ -5,6 +5,7 @@ #include "options.h" #include "filter.h" #include "custom.h" +#include "xwin.h" #include @@ -21,10 +22,11 @@ uae_s32 tylrgb[65536]; uae_s32 tcbrgb[65536]; uae_s32 tcrrgb[65536]; -void PAL_init(void) +void PAL_init(int monid) { - int i; - for (i = 0; i < 4096; i++) + struct amigadisplay *ad = &adisplays[0]; + + for (int i = 0; i < 4096; i++) randomtable[i] = rand() | (rand() << 15); predc = &redc[1 * 256]; pgrec = &grec[1 * 256]; @@ -39,8 +41,8 @@ void PAL_init(void) xx2 = 5; xx3 = 7; } - pal_noise_mask = (1 << (currprefs.gf[picasso_on].gfx_filter_noise * 7 / 100)) - 1; - scanlinelevel = 128 - currprefs.gf[picasso_on].gfx_filter_scanlines * 128 / 100; + pal_noise_mask = (1 << (currprefs.gf[ad->picasso_on].gfx_filter_noise * 7 / 100)) - 1; + scanlinelevel = 128 - currprefs.gf[ad->picasso_on].gfx_filter_scanlines * 128 / 100; } #if 0 diff --git a/od-win32/screenshot.cpp b/od-win32/screenshot.cpp index e08c834d..8da2ad7f 100644 --- a/od-win32/screenshot.cpp +++ b/od-win32/screenshot.cpp @@ -56,11 +56,12 @@ static void namesplit (TCHAR *s) static int toclipboard (BITMAPINFO *bi, void *bmp) { + struct AmigaMonitor *mon = &AMonitors[0]; int v = 0; uae_u8 *dib = 0; HANDLE hg; - if (!OpenClipboard (hMainWnd)) + if (!OpenClipboard(mon->hMainWnd)) return v; EmptyClipboard (); hg = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, bi->bmiHeader.biSize + bi->bmiHeader.biSizeImage); @@ -108,6 +109,7 @@ static int rgb_rb, rgb_gb, rgb_bb, rgb_rs, rgb_gs, rgb_bs, rgb_ab, rgb_as; static int screenshot_prepare (int imagemode, struct vidbuffer *vb) { + struct AmigaMonitor *mon = &AMonitors[0]; int width, height; HGDIOBJ hgdiobj; int bits; @@ -131,8 +133,8 @@ static int screenshot_prepare (int imagemode, struct vidbuffer *vb) int screenshot_width = 0, screenshot_height = 0; int screenshot_xoffset = -1, screenshot_yoffset = -1; - if (WIN32GFX_IsPicassoScreen ()) { - src = mem = getrtgbuffer (&width, &height, &spitch, &bits, pal); + if (WIN32GFX_IsPicassoScreen(mon)) { + src = mem = getrtgbuffer(0, &width, &height, &spitch, &bits, pal); needfree = true; rgb_bb2 = 8; rgb_gb2 = 8; @@ -157,7 +159,7 @@ static int screenshot_prepare (int imagemode, struct vidbuffer *vb) rgb_rs2 = rgb_rs; rgb_as2 = rgb_as; } else { - src = mem = getfilterbuffer (&width, &height, &spitch, &bits); + src = mem = getfilterbuffer(0, &width, &height, &spitch, &bits); needfree = true; rgb_bb2 = rgb_bb; rgb_gb2 = rgb_gb; @@ -172,10 +174,10 @@ static int screenshot_prepare (int imagemode, struct vidbuffer *vb) goto donormal; if (width == 0 || height == 0) { if (needfree) { - if (WIN32GFX_IsPicassoScreen()) - freertgbuffer(mem); + if (WIN32GFX_IsPicassoScreen(mon)) + freertgbuffer(0, mem); else - freefilterbuffer(mem); + freefilterbuffer(0, mem); } goto donormal; } @@ -192,7 +194,7 @@ static int screenshot_prepare (int imagemode, struct vidbuffer *vb) screenshot_xoffset = currprefs.screenshot_xoffset; screenshot_yoffset = currprefs.screenshot_yoffset; - if (!WIN32GFX_IsPicassoScreen() && screenshot_clipmode == 1) { + if (!WIN32GFX_IsPicassoScreen(mon) && screenshot_clipmode == 1) { int cw, ch, cx, cy, crealh = 0; if (get_custom_limits(&cw, &ch, &cx, &cy, &crealh)) { int maxw = currprefs.screenshot_max_width << currprefs.gfx_resolution; @@ -269,10 +271,10 @@ static int screenshot_prepare (int imagemode, struct vidbuffer *vb) } if (!(lpvBits = xmalloc(uae_u8, bi->bmiHeader.biSizeImage))) { if (needfree) { - if (WIN32GFX_IsPicassoScreen()) - freertgbuffer(mem); + if (WIN32GFX_IsPicassoScreen(mon)) + freertgbuffer(0, mem); else - freefilterbuffer(mem); + freefilterbuffer(0, mem); } goto oops; } @@ -389,22 +391,22 @@ static int screenshot_prepare (int imagemode, struct vidbuffer *vb) src += spitch; } if (needfree) { - if (WIN32GFX_IsPicassoScreen()) - freertgbuffer(mem); + if (WIN32GFX_IsPicassoScreen(mon)) + freertgbuffer(0, mem); else - freefilterbuffer(mem); + freefilterbuffer(0, mem); } } else { donormal: bool d3dcaptured = false; - width = WIN32GFX_GetWidth (); - height = WIN32GFX_GetHeight (); + width = WIN32GFX_GetWidth(mon); + height = WIN32GFX_GetHeight(mon); - if (D3D_isenabled() == 2) { + if (D3D_isenabled(0) == 2) { int w, h, pitch, bits = 32; void *data; - bool got = D3D11_capture(&data, &w, &h, &pitch); + bool got = D3D11_capture(0, &data, &w, &h, &pitch); int dpitch = (((w * depth + 31) & ~31) / 8); lpvBits = xmalloc(uae_u8, dpitch * h); @@ -441,14 +443,14 @@ donormal: } } if (got) - D3D11_capture(NULL, NULL, NULL, NULL); + D3D11_capture(0, NULL, NULL, NULL, NULL); d3dcaptured = true; - } else if (D3D_isenabled() == 1) { + } else if (D3D_isenabled(0) == 1) { int w, h, bits; HRESULT hr; D3DLOCKED_RECT l; - LPDIRECT3DSURFACE9 s = D3D_capture(&w, &h, &bits); + LPDIRECT3DSURFACE9 s = D3D_capture(0, &w, &h, &bits); if (s) { hr = s->LockRect(&l, NULL, D3DLOCK_READONLY); if (SUCCEEDED(hr)) { @@ -831,7 +833,7 @@ oops: #include "drawing.h" -void screenshot (int mode, int doprepare) +void screenshot(int monid, int mode, int doprepare) { if (mode == 2) { screenshot_multi = 10; diff --git a/od-win32/sounddep/sound.cpp b/od-win32/sounddep/sound.cpp index 47055002..5822a8b9 100644 --- a/od-win32/sounddep/sound.cpp +++ b/od-win32/sounddep/sound.cpp @@ -496,7 +496,6 @@ static void close_audio_ds (struct sound_data *sd) s->lpDS = 0; } -extern HWND hMainWnd; extern void setvolume_ahi (LONG); void set_volume_sound_device (struct sound_data *sd, int volume, int mute) @@ -1440,6 +1439,7 @@ error: static int open_audio_ds (struct sound_data *sd, int index) { + struct AmigaMonitor *mon = &AMonitors[0]; struct sound_dp *s = sd->data; HRESULT hr; DSBUFFERDESC sound_buffer; @@ -1482,7 +1482,7 @@ static int open_audio_ds (struct sound_data *sd, int index) return 0; } - hr = IDirectSound_SetCooperativeLevel (s->lpDS, hMainWnd, DSSCL_PRIORITY); + hr = IDirectSound_SetCooperativeLevel (s->lpDS, mon->hMainWnd, DSSCL_PRIORITY); if (FAILED (hr)) { write_log (_T("DS: Can't set cooperativelevel: %s\n"), DXError (hr)); goto error; diff --git a/od-win32/statusline_win32.cpp b/od-win32/statusline_win32.cpp index c9187e9b..a612edc1 100644 --- a/od-win32/statusline_win32.cpp +++ b/od-win32/statusline_win32.cpp @@ -23,8 +23,11 @@ static HFONT statusline_font; static HPALETTE statusline_palette; static bool statusline_was_updated; -void deletestatusline(void) +void deletestatusline(int monid) { + if (monid) + return; + struct AmigaMonitor *mon = &AMonitors[monid]; if (!statusline_hdc) return; if (!statusline_bitmap) @@ -41,13 +44,16 @@ void deletestatusline(void) statusline_palette = NULL; } -bool createstatusline(void) +bool createstatusline(int monid) { + struct AmigaMonitor *mon = &AMonitors[monid]; BITMAPINFO *bi; BITMAPINFOHEADER *bih; LOGPALETTE *lp; - deletestatusline(); + if (monid) + return false; + deletestatusline(mon->monitor_id); statusline_hdc = CreateCompatibleDC(NULL); if (!statusline_hdc) return false; @@ -59,7 +65,7 @@ bool createstatusline(void) lp->palPalEntry[3].peBlue = lp->palPalEntry[3].peGreen = lp->palPalEntry[3].peRed = 0x7f; statusline_palette = CreatePalette(lp); SelectPalette(statusline_hdc, statusline_palette, FALSE); - statusline_width = (WIN32GFX_GetWidth() + 31) & ~31; + statusline_width = (WIN32GFX_GetWidth(mon) + 31) & ~31; bi = (BITMAPINFO*)xcalloc(uae_u8, sizeof(BITMAPINFOHEADER) + 4 * sizeof(RGBQUAD)); bih = &bi->bmiHeader; bih->biSize = sizeof(BITMAPINFOHEADER); @@ -76,7 +82,7 @@ bool createstatusline(void) statusline_bitmap = CreateDIBSection(statusline_hdc, bi, DIB_RGB_COLORS, &statusline_bm, NULL, 0); xfree(bi); if (!statusline_bitmap) { - deletestatusline(); + deletestatusline(mon->monitor_id); return false; } SelectObject(statusline_hdc, statusline_bitmap); @@ -101,22 +107,29 @@ bool createstatusline(void) return true; } -void statusline_updated(void) +void statusline_updated(int monid) { + if (monid) + return; + struct AmigaMonitor *mon = &AMonitors[monid]; statusline_was_updated = true; - if (hStatusWnd) - PostMessage(hStatusWnd, SB_SETTEXT, (WPARAM)((window_led_msg_start) | SBT_OWNERDRAW), (LPARAM)_T("")); + if (mon->hStatusWnd) + PostMessage(mon->hStatusWnd, SB_SETTEXT, (WPARAM)((window_led_msg_start) | SBT_OWNERDRAW), (LPARAM)_T("")); } -void statusline_render(uae_u8 *buf, int bpp, int pitch, int width, int height, uae_u32 *rc, uae_u32 *gc, uae_u32 *bc, uae_u32 *alpha) +void statusline_render(int monid, uae_u8 *buf, int bpp, int pitch, int width, int height, uae_u32 *rc, uae_u32 *gc, uae_u32 *bc, uae_u32 *alpha) { + struct AmigaMonitor *mon = &AMonitors[monid]; uae_u32 white = rc[0xff] | gc[0xff] | bc[0xff] | (alpha ? alpha[0xff] : 0); uae_u32 back = rc[0x00] | gc[0x00] | bc[0x00] | (alpha ? alpha[0xa0] : 0); const TCHAR *text; int y = -1, x = 10, textwidth = 0; int bar_xstart; - if (currprefs.gf[WIN32GFX_IsPicassoScreen()].gfx_filter == 0 && !currprefs.gfx_api) + if (monid) + return; + + if (currprefs.gf[WIN32GFX_IsPicassoScreen(mon)].gfx_filter == 0 && !currprefs.gfx_api) return; text = statusline_fetch(); //text = _T("Testing string 123!"); diff --git a/od-win32/win32.cpp b/od-win32/win32.cpp index c1c6a0ce..0df2cb1a 100644 --- a/od-win32/win32.cpp +++ b/od-win32/win32.cpp @@ -102,6 +102,7 @@ #include "uae/ppc.h" #include "fsdb.h" #include "uae/time.h" +#include "specialmonitors.h" const static GUID GUID_DEVINTERFACE_HID = { 0x4D1E55B2L, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } }; @@ -145,14 +146,11 @@ int max_uae_height; HINSTANCE hInst = NULL; HMODULE hUIDLL = NULL; HWND (WINAPI *pHtmlHelp)(HWND, LPCWSTR, UINT, LPDWORD) = NULL; -HWND hAmigaWnd, hMainWnd, hHiddenWnd, hGUIWnd; +HWND hHiddenWnd, hGUIWnd; #if KBHOOK static HHOOK hhook; #endif -RECT amigawin_rect, mainwin_rect; -static RECT amigawinclip_rect; -int setcursoroffset_x, setcursoroffset_y; -static int mouseposx, mouseposy; + static UINT TaskbarRestart; static HWND TaskbarRestartHWND; static int forceroms; @@ -168,26 +166,19 @@ TCHAR VersionStr[256]; TCHAR BetaStr[64]; extern pathtype path_type; -int in_sizemove; -int manual_painting_needed; - -int win_x_diff, win_y_diff; - int toggle_sound; int paraport_mask; HKEY hWinUAEKey = NULL; COLORREF g_dwBackgroundColor; -static int activatemouse = 1; int pause_emulation; -static int didmousepos; static int sound_closed; static int recapture; static int focus; +static int mouseinside; int mouseactive; -int mouseinside; int minimized; int monitor_off; @@ -232,6 +223,64 @@ static GETTOUCHINPUTINFO pGetTouchInputInfo; static CLOSETOUCHINPUTHANDLE pCloseTouchInputHandle; #endif +static uae_u64 spincount; + +void target_spin(int total) +{ + if (!spincount) + return; + if (total > 10) + total = 10; + while (total-- >= 0) { + uae_u64 v1 = __rdtsc(); + v1 += spincount; + while (v1 > __rdtsc()); + } +} + +extern int vsync_activeheight; + +void target_calibrate_spin(void) +{ + struct amigadisplay *ad = &adisplays[0]; + struct apmode *ap = ad->picasso_on ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0]; + int vp; + + spincount = 0; + if (!ap->gfx_vsyncmode) + return; + spincount = 0x800000000000; + for (int i = 0; i < 50; i++) { + for (;;) { + vp = target_get_display_scanline(-1); + if (vp >= 1 && vp < vsync_activeheight - 10) + break; + } + for (;;) { + int vp2 = target_get_display_scanline(-1); + if (vp2 == vp + 1) + break; + } + uae_u64 v1 = __rdtsc(); + for (;;) { + int vp2 = target_get_display_scanline(-1); + if (vp2 == vp + 2) { + uae_u64 sc = __rdtsc() - v1; + if (spincount > sc) + spincount = sc; + } + if (vp2 != vp + 1) + break; + } + } + if (spincount == 0x800000000000) { + write_log(_T("Spincount calculation error, spinloop not used.\n"), spincount); + spincount = 0; + } else { + write_log(_T("Spincount = %llu\n"), spincount); + } +} + int timeend (void) { if (!timeon) @@ -285,6 +334,7 @@ void sleep_cpu_wakeup(void) } HANDLE get_sound_event(void); +extern HANDLE waitvblankevent; static int sleep_millis2 (int ms, bool main) { @@ -313,6 +363,9 @@ static int sleep_millis2 (int ms, bool main) if (WaitForSingleObject(cpu_wakeup_event, 0) == WAIT_OBJECT_0) { return 0; } + if (waitvblankevent && WaitForSingleObject(waitvblankevent, 0) == WAIT_OBJECT_0) { + return 0; + } start = read_processor_time (); } EnterCriticalSection (&cs_time); @@ -330,17 +383,26 @@ static int sleep_millis2 (int ms, bool main) TimerEvent = timeSetEvent (ms, 0, (LPTIMECALLBACK)timehandle[cnt], 0, TIME_ONESHOT | TIME_CALLBACK_EVENT_SET); if (main) { int c = 0; - HANDLE evt[3]; + HANDLE evt[4]; + int sound_event_cnt = -1; + int vblank_event_cnt = -1; evt[c++] = timehandle[cnt]; evt[c++] = cpu_wakeup_event; + if (waitvblankevent) { + vblank_event_cnt = c; + evt[c++] = waitvblankevent; + } if (sound_event && pullcheck) { + sound_event_cnt = c; evt[c++] = sound_event; } DWORD status = WaitForMultipleObjects(c, evt, FALSE, ms); - if (status == WAIT_OBJECT_0 + 2) + if (sound_event_cnt >= 0 && status == WAIT_OBJECT_0 + sound_event_cnt) + ret = -1; + if (vblank_event_cnt >= 0 && status == WAIT_OBJECT_0 + vblank_event_cnt) ret = -1; if (wasneg) { - if (status == WAIT_OBJECT_0 + 2) { + if (sound_event_cnt >= 0 && status == WAIT_OBJECT_0 + sound_event_cnt) { write_log(_T("efw %d delayed abort\n"), ms); } else if (status == WAIT_TIMEOUT) { write_log(_T("efw %d full wait\n"), ms); @@ -379,25 +441,22 @@ int sleep_millis_amiga(int ms) return ret; } -static int windowmouse_max_w; -static int windowmouse_max_h; - -static void setcursor (int oldx, int oldy) +static void setcursor(struct AmigaMonitor *mon, int oldx, int oldy) { - int dx = (amigawinclip_rect.left - amigawin_rect.left) + (amigawinclip_rect.right - amigawinclip_rect.left) / 2; - int dy = (amigawinclip_rect.top - amigawin_rect.top) + (amigawinclip_rect.bottom - amigawinclip_rect.top) / 2; - mouseposx = oldx - dx; - mouseposy = oldy - dy; + int dx = (mon->amigawinclip_rect.left - mon->amigawin_rect.left) + (mon->amigawinclip_rect.right - mon->amigawinclip_rect.left) / 2; + int dy = (mon->amigawinclip_rect.top - mon->amigawin_rect.top) + (mon->amigawinclip_rect.bottom - mon->amigawinclip_rect.top) / 2; + mon->mouseposx = oldx - dx; + mon->mouseposy = oldy - dy; - windowmouse_max_w = (amigawinclip_rect.right - amigawinclip_rect.left) / 2 - 50; - windowmouse_max_h = (amigawinclip_rect.bottom - amigawinclip_rect.top) / 2 - 50; - if (windowmouse_max_w < 10) - windowmouse_max_w = 10; - if (windowmouse_max_h < 10) - windowmouse_max_h = 10; + mon->windowmouse_max_w = (mon->amigawinclip_rect.right - mon->amigawinclip_rect.left) / 2 - 50; + mon->windowmouse_max_h = (mon->amigawinclip_rect.bottom - mon->amigawinclip_rect.top) / 2 - 50; + if (mon->windowmouse_max_w < 10) + mon->windowmouse_max_w = 10; + if (mon->windowmouse_max_h < 10) + mon->windowmouse_max_h = 10; if ((currprefs.input_mouse_untrap & MOUSEUNTRAP_MAGIC) && currprefs.input_tablet > 0 && mousehack_alive () && isfullscreen () <= 0) { - mouseposx = mouseposy = 0; + mon->mouseposx = mon->mouseposy = 0; return; } #if MOUSECLIP_LOG @@ -412,17 +471,17 @@ static void setcursor (int oldx, int oldy) if (oldx >= 30000 || oldy >= 30000 || oldx <= -30000 || oldy <= -30000) { oldx = oldy = 0; } else { - if (abs (mouseposx) < windowmouse_max_w && abs (mouseposy) < windowmouse_max_h) + if (abs(mon->mouseposx) < mon->windowmouse_max_w && abs(mon->mouseposy) < mon->windowmouse_max_h) return; } - mouseposx = mouseposy = 0; - if (oldx < 0 || oldy < 0 || oldx > amigawin_rect.right - amigawin_rect.left || oldy > amigawin_rect.bottom - amigawin_rect.top) { + mon->mouseposx = mon->mouseposy = 0; + if (oldx < 0 || oldy < 0 || oldx > mon->amigawin_rect.right - mon->amigawin_rect.left || oldy > mon->amigawin_rect.bottom - mon->amigawin_rect.top) { write_log (_T("Mouse out of range: %dx%d (%dx%d %dx%d)\n"), oldx, oldy, - amigawin_rect.left, amigawin_rect.top, amigawin_rect.right, amigawin_rect.bottom); + mon->amigawin_rect.left, mon->amigawin_rect.top, mon->amigawin_rect.right, mon->amigawin_rect.bottom); return; } - int cx = (amigawinclip_rect.right - amigawinclip_rect.left) / 2 + amigawin_rect.left + (amigawinclip_rect.left - amigawin_rect.left); - int cy = (amigawinclip_rect.bottom - amigawinclip_rect.top) / 2 + amigawin_rect.top + (amigawinclip_rect.top - amigawin_rect.top); + int cx = (mon->amigawinclip_rect.right - mon->amigawinclip_rect.left) / 2 + mon->amigawin_rect.left + (mon->amigawinclip_rect.left - mon->amigawin_rect.left); + int cy = (mon->amigawinclip_rect.bottom - mon->amigawinclip_rect.top) / 2 + mon->amigawin_rect.top + (mon->amigawinclip_rect.top - mon->amigawin_rect.top); #if MOUSECLIP_LOG write_log (_T("SetCursorPos(%d,%d)\n"), cx, cy); #endif @@ -433,37 +492,56 @@ static int showcursor; extern TCHAR config_filename[256]; -static void setmaintitle (HWND hwnd) +static void setmaintitle(int monid) { TCHAR txt[1000], txt2[500]; + HWND hwnd = AMonitors[monid].hMainWnd; #ifdef RETROPLATFORM if (rp_isactive ()) return; #endif txt[0] = 0; - inprec_getstatus (txt); - if (currprefs.config_window_title[0]) { - _tcscat (txt, currprefs.config_window_title); - _tcscat (txt, _T(" - ")); - } else if (config_filename[0]) { - _tcscat (txt, _T("[")); - _tcscat (txt, config_filename); - _tcscat (txt, _T("] - ")); + if (!monid) { + inprec_getstatus(txt); + if (currprefs.config_window_title[0]) { + _tcscat(txt, currprefs.config_window_title); + _tcscat(txt, _T(" - ")); + } else if (config_filename[0]) { + _tcscat(txt, _T("[")); + _tcscat(txt, config_filename); + _tcscat(txt, _T("] - ")); + } + } else { + if (monid == currprefs.monitoremu_mon && currprefs.monitoremu >= 2) { + _tcscat(txt, _T("[")); + _tcscat(txt, specialmonitorfriendlynames[currprefs.monitoremu - 2]); + _tcscat(txt, _T("] - ")); + } else { + for (int i = 0; i < MAX_RTG_BOARDS; i++) { + if (monid == currprefs.rtgboards[i].monitor_id) { + _tcscat(txt, _T("[")); + _tcscat(txt, gfxboard_get_name(currprefs.rtgboards[i].rtgmem_type)); + _tcscat(txt, _T("] - ")); + } + } + } } _tcscat (txt, _T("WinUAE")); txt2[0] = 0; - if (pause_emulation) { - WIN32GUI_LoadUIString (IDS_WINUAETITLE_PAUSED, txt2, sizeof (txt2) / sizeof (TCHAR)); - } else if (mouseactive > 0) { - WIN32GUI_LoadUIString ((currprefs.input_mouse_untrap & MOUSEUNTRAP_MIDDLEBUTTON) ? IDS_WINUAETITLE_MMB : IDS_WINUAETITLE_NORMAL, - txt2, sizeof (txt2) / sizeof (TCHAR)); - } - if (_tcslen (WINUAEBETA) > 0) { - _tcscat (txt, BetaStr); - if (_tcslen (WINUAEEXTRA) > 0) { - _tcscat (txt, _T(" ")); - _tcscat (txt, WINUAEEXTRA); + if (!monid) { + if (pause_emulation) { + WIN32GUI_LoadUIString(IDS_WINUAETITLE_PAUSED, txt2, sizeof(txt2) / sizeof(TCHAR)); + } else if (mouseactive > 0) { + WIN32GUI_LoadUIString((currprefs.input_mouse_untrap & MOUSEUNTRAP_MIDDLEBUTTON) ? IDS_WINUAETITLE_MMB : IDS_WINUAETITLE_NORMAL, + txt2, sizeof(txt2) / sizeof(TCHAR)); + } + if (_tcslen(WINUAEBETA) > 0) { + _tcscat(txt, BetaStr); + if (_tcslen(WINUAEEXTRA) > 0) { + _tcscat(txt, _T(" ")); + _tcscat(txt, WINUAEEXTRA); + } } } if (txt2[0]) { @@ -490,8 +568,9 @@ void setsoundpaused (void) ahi2_pause_sound (1); #endif } -bool resumepaused (int priority) +bool resumepaused(int priority) { + struct AmigaMonitor *mon = &AMonitors[0]; //write_log (_T("resume %d (%d)\n"), priority, pause_emulation); if (pause_emulation > priority) return false; @@ -501,16 +580,17 @@ bool resumepaused (int priority) resumesoundpaused (); if (pausemouseactive) { pausemouseactive = 0; - setmouseactive (-1); + setmouseactive(mon->monitor_id, -1); } pause_emulation = 0; setsystime (); - setmaintitle(hMainWnd); + setmaintitle(mon->monitor_id); wait_keyrelease(); return true; } -bool setpaused (int priority) +bool setpaused(int priority) { + struct AmigaMonitor *mon = &AMonitors[0]; //write_log (_T("pause %d (%d)\n"), priority, pause_emulation); if (pause_emulation > priority) return false; @@ -520,35 +600,39 @@ bool setpaused (int priority) pausemouseactive = 1; if (isfullscreen () <= 0) { pausemouseactive = mouseactive; - setmouseactive (0); + setmouseactive(mon->monitor_id, 0); } - setmaintitle(hMainWnd); + setmaintitle(mon->monitor_id); return true; } -void setminimized (void) +void setminimized(int monid) { if (!minimized) minimized = 1; - set_inhibit_frame (IHF_WINDOWHIDDEN); + set_inhibit_frame(monid, IHF_WINDOWHIDDEN); if (isfullscreen() > 0 && D3D_resize) { write_log(_T("setminimized\n")); - D3D_resize(-1); + D3D_resize(monid, -1); } } -void unsetminimized (void) +void unsetminimized(int monid) { if (minimized < 0) - WIN32GFX_DisplayChangeRequested (2); + WIN32GFX_DisplayChangeRequested(2); minimized = 0; - clear_inhibit_frame (IHF_WINDOWHIDDEN); + clear_inhibit_frame(monid, IHF_WINDOWHIDDEN); } -void refreshtitle (void) +void refreshtitle(void) { - if (isfullscreen () == 0) - setmaintitle (hMainWnd); + for (int i = 0; i < MAX_AMIGAMONITORS; i++) { + struct AmigaMonitor *mon = &AMonitors[i]; + if (mon->hMainWnd && isfullscreen() == 0) { + setmaintitle(mon->monitor_id); + } + } } #ifndef AVIOUTPUT @@ -569,18 +653,18 @@ void setpriority (struct threadpriorities *pri) } } -static void setcursorshape (void) +static void setcursorshape(int monid) { if (currprefs.input_tablet && (currprefs.input_mouse_untrap & MOUSEUNTRAP_MAGIC) && currprefs.input_magic_mouse_cursor == MAGICMOUSE_NATIVE_ONLY) { - if (GetCursor () != NULL) - SetCursor (NULL); - } else if (!picasso_setwincursor ()) { - if (GetCursor () != normalcursor) - SetCursor (normalcursor); + if (GetCursor() != NULL) + SetCursor(NULL); + } else if (!picasso_setwincursor(monid)) { + if (GetCursor() != normalcursor) + SetCursor(normalcursor); } } -static void releasecapture (void) +static void releasecapture(void) { //write_log(_T("releasecapture %d\n"), showcursor); #if 0 @@ -591,16 +675,16 @@ static void releasecapture (void) #endif if (!showcursor) return; - ClipCursor (NULL); - ReleaseCapture (); - ShowCursor (TRUE); + ClipCursor(NULL); + ReleaseCapture(); + ShowCursor(TRUE); showcursor = 0; } -void updatemouseclip (void) +void updatemouseclip(struct AmigaMonitor *mon) { if (showcursor) { - amigawinclip_rect = amigawin_rect; + mon->amigawinclip_rect = mon->amigawin_rect; if (!isfullscreen()) { int idx = 0; reenumeratemonitors(); @@ -612,7 +696,7 @@ void updatemouseclip (void) && md->rect.top == md->workrect.top && md->rect.bottom == md->workrect.bottom) continue; // not in this monitor? - if (!IntersectRect(&out, &md->rect, &amigawin_rect)) + if (!IntersectRect(&out, &md->rect, &mon->amigawin_rect)) continue; for (int e = 0; e < 4; e++) { int v1, v2, x, y; @@ -623,28 +707,28 @@ void updatemouseclip (void) default: v1 = md->rect.left; v2 = md->workrect.left; - lp = &amigawinclip_rect.left; + lp = &mon->amigawinclip_rect.left; x = v1 - 1; y = (md->rect.bottom - md->rect.top) / 2; break; case 1: v1 = md->rect.top; v2 = md->workrect.top; - lp = &amigawinclip_rect.top; + lp = &mon->amigawinclip_rect.top; x = (md->rect.right - md->rect.left) / 2; y = v1 - 1; break; case 2: v1 = md->rect.right; v2 = md->workrect.right; - lp = &amigawinclip_rect.right; + lp = &mon->amigawinclip_rect.right; x = v1 + 1; y = (md->rect.bottom - md->rect.top) / 2; break; case 3: v1 = md->rect.bottom; v2 = md->workrect.bottom; - lp = &amigawinclip_rect.bottom; + lp = &mon->amigawinclip_rect.bottom; x = (md->rect.right - md->rect.left) / 2; y = v1 + 1; break; @@ -668,32 +752,32 @@ void updatemouseclip (void) } } // Too small or invalid? - if (amigawinclip_rect.right <= amigawinclip_rect.left + 7 || amigawinclip_rect.bottom <= amigawinclip_rect.top + 7) - amigawinclip_rect = amigawin_rect; + if (mon->amigawinclip_rect.right <= mon->amigawinclip_rect.left + 7 || mon->amigawinclip_rect.bottom <= mon->amigawinclip_rect.top + 7) + mon->amigawinclip_rect = mon->amigawin_rect; } #if MOUSECLIP_LOG write_log (_T("CLIP %dx%d %dx%d %d\n"), amigawin_rect.left, amigawin_rect.top, amigawin_rect.right, amigawin_rect.bottom, isfullscreen ()); #endif - if (!ClipCursor (&amigawinclip_rect)) + if (!ClipCursor (&mon->amigawinclip_rect)) write_log(_T("ClipCursor error %d\n"), GetLastError()); } } -void updatewinrect (bool allowfullscreen) +void updatewinrect(struct AmigaMonitor *mon, bool allowfullscreen) { int f = isfullscreen (); if (!allowfullscreen && f > 0) return; - GetWindowRect (hAmigaWnd, &amigawin_rect); - GetWindowRect (hAmigaWnd, &amigawinclip_rect); + GetWindowRect(mon->hAmigaWnd, &mon->amigawin_rect); + GetWindowRect(mon->hAmigaWnd, &mon->amigawinclip_rect); #if MOUSECLIP_LOG write_log (_T("GetWindowRect %dx%d %dx%d %d\n"), amigawin_rect.left, amigawin_rect.top, amigawin_rect.right, amigawin_rect.bottom, f); #endif - if (f == 0) { - changed_prefs.gfx_size_win.x = amigawin_rect.left; - changed_prefs.gfx_size_win.y = amigawin_rect.top; - currprefs.gfx_size_win.x = changed_prefs.gfx_size_win.x; - currprefs.gfx_size_win.y = changed_prefs.gfx_size_win.y; + if (f == 0 && mon->monitor_id == 0) { + changed_prefs.gfx_monitor[mon->monitor_id].gfx_size_win.x = mon->amigawin_rect.left; + changed_prefs.gfx_monitor[mon->monitor_id].gfx_size_win.y = mon->amigawin_rect.top; + currprefs.gfx_monitor[mon->monitor_id].gfx_size_win.x = changed_prefs.gfx_monitor[mon->monitor_id].gfx_size_win.x; + currprefs.gfx_monitor[mon->monitor_id].gfx_size_win.y = changed_prefs.gfx_monitor[mon->monitor_id].gfx_size_win.y; } } @@ -721,13 +805,13 @@ static LRESULT CALLBACK captureKey(int nCode, WPARAM wp, LPARAM lp) } #endif -static bool iswindowfocus (void) +static bool iswindowfocus(struct AmigaMonitor *mon) { bool donotfocus = false; HWND f = GetFocus (); HWND fw = GetForegroundWindow (); - HWND w1 = hAmigaWnd; - HWND w2 = hMainWnd; + HWND w1 = mon->hAmigaWnd; + HWND w2 = mon->hMainWnd; HWND w3 = NULL; #ifdef RETROPLATFORM if (rp_isactive ()) @@ -760,11 +844,12 @@ void target_inputdevice_unacquire(void) } void target_inputdevice_acquire(void) { + struct AmigaMonitor *mon = &AMonitors[0]; target_inputdevice_unacquire(); - tablet = open_tablet(hAmigaWnd); + tablet = open_tablet(mon->hAmigaWnd); } -static void setmouseactive2 (int active, bool allowpause) +static void setmouseactive2(struct AmigaMonitor *mon, int active, bool allowpause) { #ifdef RETROPLATFORM bool isrp = rp_isactive () != 0; @@ -773,7 +858,6 @@ static void setmouseactive2 (int active, bool allowpause) #endif //write_log (_T("setmouseactive %d->%d showcursor=%d focus=%d recap=%d\n"), mouseactive, active, showcursor, focus, recapture); - if (active == 0) releasecapture (); if (mouseactive == active && active >= 0) @@ -785,16 +869,16 @@ static void setmouseactive2 (int active, bool allowpause) return; } if (active) { - if (!isrp && !IsWindowVisible (hAmigaWnd)) + if (!isrp && !IsWindowVisible (mon->hAmigaWnd)) return; } if (active < 0) active = 1; - mouseactive = active; + mouseactive = active ? mon->monitor_id + 1 : 0; - mouseposx = mouseposy = 0; + mon->mouseposx = mon->mouseposy = 0; //write_log (_T("setmouseactive(%d)\n"), active); releasecapture (); recapture = 0; @@ -805,7 +889,21 @@ static void setmouseactive2 (int active, bool allowpause) SetCursor (normalcursor); } - if (!iswindowfocus ()) { + bool gotfocus = false; + for (int i = 0; i < MAX_AMIGAMONITORS; i++) { + HWND h = GetFocus(); + if (h && (h == AMonitors[i].hAmigaWnd || h == AMonitors[i].hMainWnd)) { + mon = &AMonitors[i]; + break; + } + } + for (int i = 0; i < MAX_AMIGAMONITORS; i++) { + if (iswindowfocus(&AMonitors[i])) { + gotfocus = true; + break; + } + } + if (!gotfocus) { write_log (_T("Tried to capture mouse but window didn't have focus! F=%d A=%d\n"), focus, mouseactive); focus = 0; mouseactive = 0; @@ -813,7 +911,7 @@ static void setmouseactive2 (int active, bool allowpause) } if (mouseactive > 0) - focus = 1; + focus = mon->monitor_id + 1; if (mouseactive) { if (focus) { @@ -822,21 +920,21 @@ static void setmouseactive2 (int active, bool allowpause) #if MOUSECLIP_HIDE ShowCursor (FALSE); #endif - SetCapture (hAmigaWnd); - updatewinrect (false); - showcursor = 1; - updatemouseclip (); + SetCapture (mon->hAmigaWnd); + updatewinrect(mon, false); + showcursor = mon->monitor_id + 1; + updatemouseclip(mon); } - setcursor (-30000, -30000); + setcursor(mon, -30000, -30000); } - inputdevice_acquire (TRUE); + inputdevice_acquire(TRUE); setpriority (&priorities[currprefs.win32_active_capture_priority]); if (currprefs.win32_active_nocapture_pause) { - resumepaused (2); + resumepaused(2); } else if (currprefs.win32_active_nocapture_nosound && sound_closed < 0) { - resumesoundpaused (); + resumesoundpaused(); } - setmaintitle (hMainWnd); + setmaintitle(mon->monitor_id); #if KBHOOK if (!hhook) { hhook = SetWindowsHookEx(WH_KEYBOARD_LL, captureKey, GetModuleHandle(NULL), 0); @@ -860,24 +958,26 @@ static void setmouseactive2 (int active, bool allowpause) setsoundpaused (); sound_closed = -1; } - setmaintitle (hMainWnd); + setmaintitle(mon->monitor_id); } #ifdef RETROPLATFORM - rp_mouse_capture (active); - rp_mouse_magic (magicmouse_alive ()); + rp_mouse_capture(active); + rp_mouse_magic(magicmouse_alive()); #endif } -void setmouseactive (int active) + +void setmouseactive(int monid, int active) { + struct AmigaMonitor *mon = &AMonitors[monid]; monitor_off = 0; if (active > 1) - SetForegroundWindow (hAmigaWnd); - setmouseactive2 (active, true); + SetForegroundWindow(mon->hAmigaWnd); + setmouseactive2(mon, active, true); } static int hotkeys[] = { VK_VOLUME_UP, VK_VOLUME_DOWN, VK_VOLUME_MUTE, -1 }; -static void winuae_active (HWND hWnd, int minimized) +static void winuae_active(struct AmigaMonitor *mon, HWND hwnd, int minimized) { struct threadpriorities *pri; @@ -889,11 +989,11 @@ static void winuae_active (HWND hWnd, int minimized) sleep_millis (2); timebegin (); - focus = 1; + focus = mon->monitor_id + 1; pri = &priorities[currprefs.win32_inactive_priority]; if (!minimized) pri = &priorities[currprefs.win32_active_capture_priority]; - setpriority (pri); + setpriority(pri); if (sound_closed) { if (sound_closed < 0) { @@ -910,20 +1010,20 @@ static void winuae_active (HWND hWnd, int minimized) sound_closed = 0; } #if 0 - RegisterHotKey (hAmigaWnd, IDHOT_SNAPDESKTOP, 0, VK_SNAPSHOT); + RegisterHotKey (mon->hAmigaWnd, IDHOT_SNAPDESKTOP, 0, VK_SNAPSHOT); for (int i = 0; hotkeys[i] >= 0; i++) - RegisterHotKey (hAmigaWnd, hotkeys[i], 0, hotkeys[i]); + RegisterHotKey (mon->hAmigaWnd, hotkeys[i], 0, hotkeys[i]); #endif getcapslock (); wait_keyrelease (); inputdevice_acquire (TRUE); if (isfullscreen () != 0 && !gui_active) - setmouseactive (1); + setmouseactive(mon->monitor_id, 1); #ifdef LOGITECHLCD if (!minimized) lcd_priority (1); #endif - clipboard_active (hAmigaWnd, 1); + clipboard_active(mon->hAmigaWnd, 1); #if USETHREADCHARACTERICS if (os_vista && AVTask == NULL) { typedef HANDLE(WINAPI* AVSETMMTHREADCHARACTERISTICS)(LPCTSTR, LPDWORD); @@ -939,7 +1039,7 @@ static void winuae_active (HWND hWnd, int minimized) #endif } -static void winuae_inactive (HWND hWnd, int minimized) +static void winuae_inactive(struct AmigaMonitor *mon, HWND hWnd, int minimized) { struct threadpriorities *pri; int wasfocus = focus; @@ -958,16 +1058,16 @@ static void winuae_inactive (HWND hWnd, int minimized) if (!currprefs.win32_powersavedisabled) SetThreadExecutionState (ES_CONTINUOUS); if (minimized) - exit_gui (0); + exit_gui(0); #if 0 for (int i = 0; hotkeys[i] >= 0; i++) - UnregisterHotKey (hAmigaWnd, hotkeys[i]); - UnregisterHotKey (hAmigaWnd, IDHOT_SNAPDESKTOP); + UnregisterHotKey (mon->hAmigaWnd, hotkeys[i]); + UnregisterHotKey (mon->hAmigaWnd, IDHOT_SNAPDESKTOP); #endif focus = 0; wait_keyrelease (); - setmouseactive (0); - clipboard_active (hAmigaWnd, 0); + setmouseactive(mon->monitor_id, 0); + clipboard_active(mon->hAmigaWnd, 0); pri = &priorities[currprefs.win32_inactive_priority]; if (!quit_program) { if (minimized) { @@ -1017,28 +1117,29 @@ static void winuae_inactive (HWND hWnd, int minimized) #endif } -void minimizewindow (void) +void minimizewindow(int monid) { - ShowWindow (hMainWnd, SW_MINIMIZE); + struct AmigaMonitor *mon = &AMonitors[monid]; + ShowWindow (mon->hMainWnd, SW_MINIMIZE); } -void enablecapture (void) +void enablecapture(int monid) { if (pause_emulation > 2) return; - setmouseactive (1); + setmouseactive(monid, 1); if (sound_closed < 0) { - resumesoundpaused (); + resumesoundpaused(); sound_closed = 0; } if (currprefs.win32_inactive_pause || currprefs.win32_active_nocapture_pause) { - resumepaused (2); + resumepaused(2); } } -void disablecapture (void) +void disablecapture(void) { - setmouseactive (0); + setmouseactive(0, 0); focus = 0; if (currprefs.win32_active_nocapture_pause && sound_closed == 0) { setpaused (2); @@ -1107,25 +1208,26 @@ void gui_gameport_axis_change (int port, int axis, int state, int max) } -void setmouseactivexy (int x, int y, int dir) +void setmouseactivexy(int monid, int x, int y, int dir) { + struct AmigaMonitor *mon = &AMonitors[monid]; int diff = 8; if (isfullscreen () > 0) return; - x += amigawin_rect.left; - y += amigawin_rect.top; + x += mon->amigawin_rect.left; + y += mon->amigawin_rect.top; if (dir & 1) - x = amigawin_rect.left - diff; + x = mon->amigawin_rect.left - diff; if (dir & 2) - x = amigawin_rect.right + diff; + x = mon->amigawin_rect.right + diff; if (dir & 4) - y = amigawin_rect.top - diff; + y = mon->amigawin_rect.top - diff; if (dir & 8) - y = amigawin_rect.bottom + diff; + y = mon->amigawin_rect.bottom + diff; if (!dir) { - x += (amigawin_rect.right - amigawin_rect.left) / 2; - y += (amigawin_rect.bottom - amigawin_rect.top) / 2; + x += (mon->amigawin_rect.right - mon->amigawin_rect.left) / 2; + y += (mon->amigawin_rect.bottom - mon->amigawin_rect.top) / 2; } if (isfullscreen () < 0) { POINT pt; @@ -1142,7 +1244,7 @@ void setmouseactivexy (int x, int y, int dir) } } -int isfocus (void) +int isfocus(void) { if (isfullscreen () > 0) { if (!minimized) @@ -1163,18 +1265,18 @@ int isfocus (void) return 0; } -static void activationtoggle (bool inactiveonly) +static void activationtoggle(int monid, bool inactiveonly) { if (mouseactive) { if ((isfullscreen () > 0) || (isfullscreen () < 0 && currprefs.win32_minimize_inactive)) { disablecapture(); - minimizewindow(); + minimizewindow(monid); } else { - setmouseactive(0); + setmouseactive(monid, 0); } } else { if (!inactiveonly) - setmouseactive(1); + setmouseactive(monid, 1); } } @@ -1426,7 +1528,7 @@ static void touch_event(DWORD id, int pressrel, int x, int y, const RECT *rcontr static int touch_prev_x, touch_prev_y; static DWORD touch_prev_flags; -static void processtouch(HWND hwnd, WPARAM wParam, LPARAM lParam) +static void processtouch(struct AmigaMonitor *mon, HWND hwnd, WPARAM wParam, LPARAM lParam) { RECT rgui, rcontrol[2]; int bottom; @@ -1435,17 +1537,17 @@ static void processtouch(HWND hwnd, WPARAM wParam, LPARAM lParam) return; if (isfullscreen()) { - rgui.left = amigawin_rect.left; - rgui.top = amigawin_rect.top; - rgui.right = amigawin_rect.right; - rgui.bottom = amigawin_rect.top + 30; - bottom = amigawin_rect.bottom; + rgui.left = mon->amigawin_rect.left; + rgui.top = mon->amigawin_rect.top; + rgui.right = mon->amigawin_rect.right; + rgui.bottom = mon->amigawin_rect.top + 30; + bottom = mon->amigawin_rect.bottom; } else { - rgui.left = mainwin_rect.left; - rgui.top = mainwin_rect.top; - rgui.right = mainwin_rect.right; - rgui.bottom = amigawin_rect.top + GetSystemMetrics(SM_CYMENU) + 2; - bottom = mainwin_rect.bottom; + rgui.left = mon->mainwin_rect.left; + rgui.top = mon->mainwin_rect.top; + rgui.right = mon->mainwin_rect.right; + rgui.bottom = mon->amigawin_rect.top + GetSystemMetrics(SM_CYMENU) + 2; + bottom = mon->mainwin_rect.bottom; } int maxx = rgui.right - rgui.left; int maxy = rgui.bottom - rgui.top; @@ -1529,14 +1631,29 @@ static void processtouch(HWND hwnd, WPARAM wParam, LPARAM lParam) #define MSGDEBUG 1 -static LRESULT CALLBACK AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +static LRESULT CALLBACK AmigaWindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { + struct AmigaMonitor *mon = NULL; HDC hDC; int mx, my; - int istablet = (GetMessageExtraInfo () & 0xFFFFFF00) == 0xFF515700; + int istablet = (GetMessageExtraInfo() & 0xFFFFFF00) == 0xFF515700; static int mm, recursive, ignoremousemove; static bool ignorelbutton; + for (int i = 0; i < MAX_AMIGAMONITORS; i++) { + if (hWnd == AMonitors[i].hAmigaWnd) { + mon = &AMonitors[i]; + break; + } + if (hWnd == AMonitors[i].hMainWnd) { + mon = &AMonitors[i]; + break; + } + } + if (!mon) { + mon = &AMonitors[0]; + } + #if MSGDEBUG > 1 write_log (_T("AWP: %p %08x %08x %08x\n"), hWnd, message, wParam, lParam); #endif @@ -1548,7 +1665,7 @@ static LRESULT CALLBACK AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, { case WM_QUERYENDSESSION: { - if (hWnd == hMainWnd && currprefs.win32_shutdown_notification && !rp_isactive()) { + if (hWnd == mon->hMainWnd && currprefs.win32_shutdown_notification && !rp_isactive()) { return FALSE; } return TRUE; @@ -1578,8 +1695,8 @@ static LRESULT CALLBACK AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, { case WM_SETFOCUS: - winuae_active(hWnd, minimized); - unsetminimized(); + winuae_active(mon, hWnd, minimized); + unsetminimized(mon->monitor_id); dx_check(); return 0; case WM_EXITSIZEMOVE: @@ -1587,20 +1704,20 @@ static LRESULT CALLBACK AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, if (D3D_resize) { if (isfullscreen() > 0 && wParam == SIZE_RESTORED) { write_log(_T("WM_EXITSIZEMOVE restored\n")); - D3D_resize(1); + D3D_resize(0, 1); } write_log(_T("WM_EXITSIZEMOVE\n")); - D3D_resize(0); + D3D_resize(0, 0); } } return 0; case WM_SIZE: - if (hStatusWnd) - SendMessage(hStatusWnd, WM_SIZE, wParam, lParam); + if (mon->hStatusWnd) + SendMessage(mon->hStatusWnd, WM_SIZE, wParam, lParam); if (wParam == SIZE_MINIMIZED && !minimized) { write_log(_T("SIZE_MINIMIZED\n")); - setminimized(); - winuae_inactive(hWnd, minimized); + setminimized(mon->monitor_id); + winuae_inactive(mon, hWnd, minimized); } return 0; case WM_ACTIVATE: @@ -1608,10 +1725,10 @@ static LRESULT CALLBACK AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, if (LOWORD(wParam) == WA_INACTIVE) { //write_log(_T("WM_ACTIVATE %x\n"), wParam); if (HIWORD(wParam)) - setminimized(); + setminimized(mon->monitor_id); else - unsetminimized(); - winuae_inactive(hWnd, minimized); + unsetminimized(mon->monitor_id); + winuae_inactive(mon, hWnd, minimized); } dx_check(); return 0; @@ -1620,17 +1737,17 @@ static LRESULT CALLBACK AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, ignorelbutton = true; break; case WM_ACTIVATEAPP: - D3D_restore(); + D3D_restore(0); //write_log(_T("WM_ACTIVATEAPP %08x\n"), wParam); if (!wParam && isfullscreen() > 0 && D3D_resize && !gui_active) { write_log(_T("WM_ACTIVATEAPP inactive %p\n"), hWnd); - D3D_resize(-1); + D3D_resize(0, -1); } else if (wParam && isfullscreen() > 0 && D3D_resize && !gui_active) { write_log(_T("WM_ACTIVATEAPP active %p\n"), hWnd); - D3D_resize(1); + D3D_resize(0, 1); } if (!wParam && isfullscreen() <= 0 && currprefs.win32_minimize_inactive) { - minimizewindow(); + minimizewindow(mon->monitor_id); } #ifdef RETROPLATFORM rp_activate(wParam, lParam); @@ -1657,11 +1774,11 @@ static LRESULT CALLBACK AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, } if (message == WM_LBUTTONDOWN && isfullscreen() == 0 && currprefs.win32_borderless && !rp_isactive()) { // full-window drag - SendMessage(hAmigaWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0); + SendMessage(mon->hAmigaWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0); return 0; } if (!pause_emulation || currprefs.win32_active_nocapture_pause) - setmouseactive((message == WM_LBUTTONDBLCLK || isfullscreen() > 0) ? 2 : 1); + setmouseactive(mon->monitor_id, (message == WM_LBUTTONDBLCLK || isfullscreen() > 0) ? 2 : 1); } else if (dinput_winmouse() >= 0 && isfocus()) { setmousebuttonstate(dinput_winmouse(), 0, 1); } @@ -1684,7 +1801,7 @@ static LRESULT CALLBACK AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: if (currprefs.input_mouse_untrap & MOUSEUNTRAP_MIDDLEBUTTON) { - activationtoggle(true); + activationtoggle(mon->monitor_id, true); } else { if (dinput_winmouse() >= 0 && isfocus() > 0) setmousebuttonstate(dinput_winmouse(), 2, 1); @@ -1732,11 +1849,11 @@ static LRESULT CALLBACK AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, if (recursive == 0) { PAINTSTRUCT ps; recursive++; - notice_screen_contents_lost(); + notice_screen_contents_lost(mon->monitor_id); hDC = BeginPaint(hWnd, &ps); /* Check to see if this WM_PAINT is coming while we've got the GUI visible */ - if (manual_painting_needed) - updatedisplayarea(); + if (mon->manual_painting_needed) + updatedisplayarea(mon->monitor_id); EndPaint(hWnd, &ps); recursive--; } @@ -1811,15 +1928,16 @@ static LRESULT CALLBACK AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, #endif DragAcceptFiles(hWnd, TRUE); normalcursor = LoadCursor(NULL, IDC_ARROW); - hwndNextViewer = SetClipboardViewer(hWnd); - clipboard_init(hWnd); + if (mon->monitor_id == 0 && !hwndNextViewer) { + hwndNextViewer = SetClipboardViewer(hWnd); + clipboard_init(hWnd); + } return 0; case WM_DESTROY: if (device_change_timer) KillTimer(hWnd, 4); device_change_timer = 0; - ChangeClipboardChain(hWnd, hwndNextViewer); wait_keyrelease(); inputdevice_unacquire(); dinput_window(); @@ -1833,9 +1951,9 @@ static LRESULT CALLBACK AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, { WINDOWPOS *wp = (WINDOWPOS*)lParam; if (isfullscreen() <= 0) { - if (!IsIconic(hWnd) && hWnd == hAmigaWnd) { - updatewinrect(false); - updatemouseclip(); + if (!IsIconic(hWnd) && hWnd == mon->hAmigaWnd) { + updatewinrect(mon, false); + updatemouseclip(mon); } } } @@ -1843,9 +1961,9 @@ static LRESULT CALLBACK AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, case WM_SETCURSOR: { - if ((HWND)wParam == hAmigaWnd && currprefs.input_tablet > 0 && (currprefs.input_mouse_untrap & MOUSEUNTRAP_MAGIC) && isfullscreen() <= 0) { + if ((HWND)wParam == mon->hAmigaWnd && currprefs.input_tablet > 0 && (currprefs.input_mouse_untrap & MOUSEUNTRAP_MAGIC) && isfullscreen() <= 0) { if (mousehack_alive()) { - setcursorshape(); + setcursorshape(mon->monitor_id); return 1; } } @@ -1866,7 +1984,7 @@ static LRESULT CALLBACK AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, mouseinside = true; tme.cbSize = sizeof tme; tme.dwFlags = TME_LEAVE; - tme.hwndTrack = hAmigaWnd; + tme.hwndTrack = mon->hAmigaWnd; TrackMouseEvent(&tme); } @@ -1880,11 +1998,11 @@ static LRESULT CALLBACK AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, #endif //write_log (_T("%d %d %d %d %d %d %dx%d %dx%d\n"), wm, mouseactive, focus, showcursor, recapture, isfullscreen (), mx, my, mouseposx, mouseposy); - mx -= mouseposx; - my -= mouseposy; + mx -= mon->mouseposx; + my -= mon->mouseposy; if (recapture && isfullscreen() <= 0) { - enablecapture(); + enablecapture(mon->monitor_id); return 0; } if (wm < 0 && (istablet || currprefs.input_tablet >= TABLET_MOUSEHACK)) { @@ -1903,8 +2021,8 @@ static LRESULT CALLBACK AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, if (!focus || !mouseactive) return DefWindowProc(hWnd, message, wParam, lParam); /* relative */ - int mxx = (amigawinclip_rect.left - amigawin_rect.left) + (amigawinclip_rect.right - amigawinclip_rect.left) / 2; - int myy = (amigawinclip_rect.top - amigawin_rect.top) + (amigawinclip_rect.bottom - amigawinclip_rect.top) / 2; + int mxx = (mon->amigawinclip_rect.left - mon->amigawin_rect.left) + (mon->amigawinclip_rect.right - mon->amigawinclip_rect.left) / 2; + int myy = (mon->amigawinclip_rect.top - mon->amigawin_rect.top) + (mon->amigawinclip_rect.bottom - mon->amigawinclip_rect.top) / 2; mx = mx - mxx; my = my - myy; setmousestate(dinput_winmouse(), 0, mx, 0); @@ -1914,7 +2032,7 @@ static LRESULT CALLBACK AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, setmousestate(0, 1, my, 1); } if (showcursor || mouseactive) - setcursor(LOWORD(lParam), HIWORD(lParam)); + setcursor(mon, LOWORD(lParam), HIWORD(lParam)); return 0; } break; @@ -2064,7 +2182,7 @@ static LRESULT CALLBACK AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, switch (wParam & 0xfff0) { case SC_MINIMIZE: - winuae_inactive(hWnd, 1); + winuae_inactive(mon, hWnd, 1); break; case SC_RESTORE: break; @@ -2085,7 +2203,7 @@ static LRESULT CALLBACK AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, case WM_NOTIFY: { LPNMHDR nm = (LPNMHDR)lParam; - if (nm->hwndFrom == hStatusWnd) { + if (nm->hwndFrom == mon->hStatusWnd) { switch (nm->code) { /* status bar clicks */ @@ -2111,7 +2229,7 @@ static LRESULT CALLBACK AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, } else if (num == 4) { if (pause_emulation) { resumepaused(9); - setmouseactive(1); + setmouseactive(mon->monitor_id, 1); } } return TRUE; @@ -2122,15 +2240,21 @@ static LRESULT CALLBACK AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, break; case WM_CHANGECBCHAIN: - if ((HWND)wParam == hwndNextViewer) - hwndNextViewer = (HWND)lParam; - else if (hwndNextViewer != NULL) - SendMessage(hwndNextViewer, message, wParam, lParam); - return 0; + if (mon->monitor_id == 0 && hwndNextViewer) { + if ((HWND)wParam == hwndNextViewer) + hwndNextViewer = (HWND)lParam; + else if (hwndNextViewer != NULL) + SendMessage(hwndNextViewer, message, wParam, lParam); + return 0; + } + break; case WM_DRAWCLIPBOARD: - clipboard_changed(hWnd); - SendMessage(hwndNextViewer, message, wParam, lParam); - return 0; + if (mon->monitor_id == 0 && hwndNextViewer) { + clipboard_changed(hWnd); + SendMessage(hwndNextViewer, message, wParam, lParam); + return 0; + } + break; case WM_WTSSESSION_CHANGE: { @@ -2140,13 +2264,13 @@ static LRESULT CALLBACK AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, case WTS_CONSOLE_CONNECT: case WTS_SESSION_UNLOCK: if (wasactive) - winuae_active(hWnd, 0); + winuae_active(mon, hWnd, 0); wasactive = 0; break; case WTS_CONSOLE_DISCONNECT: case WTS_SESSION_LOCK: wasactive = mouseactive; - winuae_inactive(hWnd, 0); + winuae_inactive(mon, hWnd, 0); break; } } @@ -2180,7 +2304,7 @@ static LRESULT CALLBACK AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, rot = pkt.pkRotation; buttons = pkt.pkButtons; proxi = pkt.pkStatus; - send_tablet(x, y, z, pres, buttons, proxi, ori.orAzimuth, ori.orAltitude, ori.orTwist, rot.roPitch, rot.roRoll, rot.roYaw, &amigawin_rect); + send_tablet(x, y, z, pres, buttons, proxi, ori.orAzimuth, ori.orAltitude, ori.orTwist, rot.roPitch, rot.roRoll, rot.roYaw, &mon->amigawin_rect); } return 0; @@ -2188,7 +2312,7 @@ static LRESULT CALLBACK AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, #if TOUCH_SUPPORT case WM_TOUCH: - processtouch(hWnd, wParam, lParam); + processtouch(mon, hWnd, wParam, lParam); break; #endif @@ -2199,11 +2323,11 @@ static LRESULT CALLBACK AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, return DefWindowProc (hWnd, message, wParam, lParam); } -static int canstretch (void) +static int canstretch(struct AmigaMonitor *mon) { if (isfullscreen () != 0) return 0; - if (!WIN32GFX_IsPicassoScreen ()) { + if (!WIN32GFX_IsPicassoScreen(mon)) { if (currprefs.gf[APMODE_NATIVE].gfx_filter_autoscale == AUTOSCALE_RESIZE) return 0; return 1; @@ -2243,10 +2367,21 @@ static void plot (LPDRAWITEMSTRUCT lpDIS, int x, int y, int dx, int dy, int idx) static LRESULT CALLBACK MainWindowProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { static RECT myrect; + struct AmigaMonitor *mon = NULL; PAINTSTRUCT ps; RECT rc; HDC hDC; + for (int i = 0; i < MAX_AMIGAMONITORS; i++) { + if (hWnd == AMonitors[i].hMainWnd) { + mon = &AMonitors[i]; + break; + } + } + if (!mon) { + mon = &AMonitors[0]; + } + #if MSGDEBUG > 1 write_log (_T("MWP: %x %d\n"), hWnd, message); #endif @@ -2326,64 +2461,64 @@ static LRESULT CALLBACK MainWindowProc (HWND hWnd, UINT message, WPARAM wParam, { LPMINMAXINFO lpmmi; lpmmi = (LPMINMAXINFO)lParam; - lpmmi->ptMinTrackSize.x = 160 + window_extra_width; - lpmmi->ptMinTrackSize.y = 128 + window_extra_height; - lpmmi->ptMaxTrackSize.x = max_uae_width + window_extra_width; - lpmmi->ptMaxTrackSize.y = max_uae_height + window_extra_height; + lpmmi->ptMinTrackSize.x = 160 + mon->window_extra_width; + lpmmi->ptMinTrackSize.y = 128 + mon->window_extra_height; + lpmmi->ptMaxTrackSize.x = max_uae_width + mon->window_extra_width; + lpmmi->ptMaxTrackSize.y = max_uae_height + mon->window_extra_height; } return 0; case WM_ENTERSIZEMOVE: - in_sizemove++; + mon->in_sizemove++; break; case WM_EXITSIZEMOVE: - in_sizemove--; + mon->in_sizemove--; /* fall through */ case WM_WINDOWPOSCHANGED: { if (isfullscreen () > 0) break; - if (in_sizemove > 0) + if (mon->in_sizemove > 0) break; int iconic = IsIconic (hWnd); - if (hAmigaWnd && hWnd == hMainWnd && !iconic) { + if (mon->hAmigaWnd && hWnd == mon->hMainWnd && !iconic) { //write_log (_T("WM_WINDOWPOSCHANGED MAIN\n")); - GetWindowRect (hMainWnd, &mainwin_rect); - updatewinrect (false); - updatemouseclip (); + GetWindowRect(mon->hMainWnd, &mon->mainwin_rect); + updatewinrect(mon, false); + updatemouseclip(mon); if (minimized) { - unsetminimized (); - winuae_active (hAmigaWnd, minimized); + unsetminimized(mon->monitor_id); + winuae_active(mon, mon->hAmigaWnd, minimized); } if (isfullscreen() == 0) { static int store_xy; RECT rc2; - if (GetWindowRect (hMainWnd, &rc2)) { - DWORD left = rc2.left - win_x_diff; - DWORD top = rc2.top - win_y_diff; + if (GetWindowRect (mon->hMainWnd, &rc2)) { + DWORD left = rc2.left - mon->win_x_diff; + DWORD top = rc2.top - mon->win_y_diff; DWORD width = rc2.right - rc2.left; DWORD height = rc2.bottom - rc2.top; - if (store_xy++) { + if (store_xy++ && !mon->monitor_id) { regsetint (NULL, _T("MainPosX"), left); regsetint (NULL, _T("MainPosY"), top); } - changed_prefs.gfx_size_win.x = left; - changed_prefs.gfx_size_win.y = top; - if (canstretch ()) { - int w = mainwin_rect.right - mainwin_rect.left; - int h = mainwin_rect.bottom - mainwin_rect.top; - if (w != changed_prefs.gfx_size_win.width + window_extra_width || - h != changed_prefs.gfx_size_win.height + window_extra_height) { - changed_prefs.gfx_size_win.width = w - window_extra_width; - changed_prefs.gfx_size_win.height = h - window_extra_height; - set_config_changed (); + changed_prefs.gfx_monitor[mon->monitor_id].gfx_size_win.x = left; + changed_prefs.gfx_monitor[mon->monitor_id].gfx_size_win.y = top; + if (canstretch(mon)) { + int w = mon->mainwin_rect.right - mon->mainwin_rect.left; + int h = mon->mainwin_rect.bottom - mon->mainwin_rect.top; + if (w != changed_prefs.gfx_monitor[mon->monitor_id].gfx_size_win.width + mon->window_extra_width || + h != changed_prefs.gfx_monitor[mon->monitor_id].gfx_size_win.height + mon->window_extra_height) { + changed_prefs.gfx_monitor[mon->monitor_id].gfx_size_win.width = w - mon->window_extra_width; + changed_prefs.gfx_monitor[mon->monitor_id].gfx_size_win.height = h - mon->window_extra_height; + set_config_changed(); } } } - if (hStatusWnd) - SendMessage (hStatusWnd, WM_SIZE, wParam, lParam); + if (mon->hStatusWnd) + SendMessage(mon->hStatusWnd, WM_SIZE, wParam, lParam); return 0; } } @@ -2393,7 +2528,7 @@ static LRESULT CALLBACK MainWindowProc (HWND hWnd, UINT message, WPARAM wParam, case WM_WINDOWPOSCHANGING: { WINDOWPOS *wp = (WINDOWPOS*)lParam; - if (!canstretch ()) + if (!canstretch(mon)) wp->flags |= SWP_NOSIZE; break; } @@ -2408,10 +2543,10 @@ static LRESULT CALLBACK MainWindowProc (HWND hWnd, UINT message, WPARAM wParam, case WM_NCLBUTTONDBLCLK: if (wParam == HTCAPTION) { if (GetKeyState (VK_SHIFT)) { - toggle_fullscreen (0); + toggle_fullscreen(0, 0); return 0; } else if (GetKeyState (VK_CONTROL)) { - toggle_fullscreen (2); + toggle_fullscreen(0, 2); return 0; } } @@ -2420,16 +2555,16 @@ static LRESULT CALLBACK MainWindowProc (HWND hWnd, UINT message, WPARAM wParam, case WM_DRAWITEM: { LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT)lParam; - if (lpDIS->hwndItem == hStatusWnd) { + if (lpDIS->hwndItem == mon->hStatusWnd) { HBRUSH b = (HBRUSH)(COLOR_3DFACE + 1); - if (hStatusBkgB == NULL) { + if (mon->hStatusBkgB == NULL) { COLORREF c = GetPixel(lpDIS->hDC, lpDIS->rcItem.left + (lpDIS->rcItem.right - lpDIS->rcItem.left) / 2, lpDIS->rcItem.top + (lpDIS->rcItem.bottom - lpDIS->rcItem.top) / 2); if (c != CLR_INVALID) { - hStatusBkgB = CreateSolidBrush(c); + mon->hStatusBkgB = CreateSolidBrush(c); } } - if (hStatusBkgB != NULL) { - b = hStatusBkgB; + if (mon->hStatusBkgB != NULL) { + b = mon->hStatusBkgB; } if (lpDIS->itemID == window_led_msg_start) { COLORREF oc; @@ -2438,7 +2573,7 @@ static LRESULT CALLBACK MainWindowProc (HWND hWnd, UINT message, WPARAM wParam, const TCHAR *txt = statusline_fetch(); int flags = DT_VCENTER | DT_SINGLELINE | DT_LEFT; - FillRect(lpDIS->hDC, &lpDIS->rcItem, hStatusBkgB); + FillRect(lpDIS->hDC, &lpDIS->rcItem, mon->hStatusBkgB); if (txt) { SetBkMode(lpDIS->hDC, TRANSPARENT); oc = SetTextColor(lpDIS->hDC, RGB(0x00, 0x00, 0x00)); @@ -2454,7 +2589,7 @@ static LRESULT CALLBACK MainWindowProc (HWND hWnd, UINT message, WPARAM wParam, r.right--; r.top++; r.bottom--; - FillRect (lpDIS->hDC, &r, hStatusBkgB); + FillRect (lpDIS->hDC, &r, mon->hStatusBkgB); for (int i = 0; i < 2; i++) { int buttons = guijoybutton[port + i * 2]; int m = i == 0 ? 1 : 2; @@ -2542,13 +2677,14 @@ static LRESULT CALLBACK MainWindowProc (HWND hWnd, UINT message, WPARAM wParam, static LRESULT CALLBACK HiddenWindowProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { + struct AmigaMonitor *mon = &AMonitors[0]; switch (message) { case WM_USER + 1: /* Systray icon */ switch (lParam) { case WM_LBUTTONDOWN: - SetForegroundWindow (hGUIWnd ? hGUIWnd : hMainWnd); + SetForegroundWindow (hGUIWnd ? hGUIWnd : mon->hMainWnd); break; case WM_LBUTTONDBLCLK: case NIN_SELECT: @@ -2561,7 +2697,7 @@ static LRESULT CALLBACK HiddenWindowProc (HWND hWnd, UINT message, WPARAM wParam if (!gui_active) systraymenu (hWnd); else - SetForegroundWindow (hGUIWnd ? hGUIWnd : hMainWnd); + SetForegroundWindow (hGUIWnd ? hGUIWnd : mon->hMainWnd); break; } break; @@ -2644,14 +2780,15 @@ int handle_msgpump (void) bool handle_events (void) { + struct AmigaMonitor *mon = &AMonitors[0]; static int was_paused = 0; static int cnt1, cnt2; static int pausedelay; - if (hStatusWnd && guijoychange && window_led_joy_start > 0) { + if (mon->hStatusWnd && guijoychange && window_led_joy_start > 0) { guijoychange = false; for (int i = 0; i < window_led_joy_start; i++) - PostMessage (hStatusWnd, SB_SETTEXT, (WPARAM)((i + 1) | SBT_OWNERDRAW), (LPARAM)_T("")); + PostMessage(mon->hStatusWnd, SB_SETTEXT, (WPARAM)((i + 1) | SBT_OWNERDRAW), (LPARAM)_T("")); } pausedelay = 0; @@ -2661,7 +2798,7 @@ bool handle_events (void) timeend(); setpaused (pause_emulation); was_paused = pause_emulation; - manual_painting_needed++; + mon->manual_painting_needed++; gui_fps (0, 0, 0); gui_led (LED_SND, 0, -1); // we got just paused, report it to caller. @@ -2673,7 +2810,7 @@ bool handle_events (void) DispatchMessage (&msg); } if (D3D_run) - D3D_run(); + D3D_run(0); inputdevicefunc_keyboard.read (); inputdevicefunc_mouse.read (); inputdevicefunc_joystick.read (); @@ -2693,8 +2830,8 @@ bool handle_events (void) } } if (was_paused && (!pause_emulation || quit_program)) { - updatedisplayarea (); - manual_painting_needed--; + updatedisplayarea(mon->monitor_id); + mon->manual_painting_needed--; pause_emulation = was_paused; resumepaused (was_paused); sound_closed = 0; @@ -2714,7 +2851,7 @@ bool handle_events (void) } } if (D3D_run) - D3D_run(); + D3D_run(0); return pause_emulation != 0; } @@ -3081,9 +3218,9 @@ int debuggable (void) return 0; } -void toggle_mousegrab (void) +void toggle_mousegrab(void) { - activationtoggle(false); + activationtoggle(0, false); } @@ -3702,18 +3839,20 @@ void target_fixup_options (struct uae_prefs *p) } struct MultiDisplay *md = getdisplay (p); - if (p->gfx_size_fs.special == WH_NATIVE) { - int i; - for (i = 0; md->DisplayModes[i].depth >= 0; i++) { - if (md->DisplayModes[i].res.width == md->rect.right - md->rect.left && - md->DisplayModes[i].res.height == md->rect.bottom - md->rect.top) { - p->gfx_size_fs.width = md->DisplayModes[i].res.width; - p->gfx_size_fs.height = md->DisplayModes[i].res.height; + for (int i = 0; i < MAX_AMIGADISPLAYS; i++) { + if (p->gfx_monitor[i].gfx_size_fs.special == WH_NATIVE) { + int i; + for (i = 0; md->DisplayModes[i].depth >= 0; i++) { + if (md->DisplayModes[i].res.width == md->rect.right - md->rect.left && + md->DisplayModes[i].res.height == md->rect.bottom - md->rect.top) { + p->gfx_monitor[i].gfx_size_fs.width = md->DisplayModes[i].res.width; + p->gfx_monitor[i].gfx_size_fs.height = md->DisplayModes[i].res.height; break; + } } + if (md->DisplayModes[i].depth < 0) + p->gfx_monitor[i].gfx_size_fs.special = 0; } - if (md->DisplayModes[i].depth < 0) - p->gfx_size_fs.special = 0; } /* switch from 32 to 16 or vice versa if mode does not exist */ if (1 || isfullscreen() > 0) { @@ -5652,7 +5791,6 @@ extern void test (void); extern int screenshotmode, postscript_print_debugging, sound_debug, log_uaeserial, clipboard_debug; extern int force_direct_catweasel, sound_mode_skip, maxmem; extern int pngprint, log_sercon, midi_inbuflen; -extern int vsync_busy_wait_mode; extern int debug_rtg_blitter; extern int log_bsd; extern int inputdevice_logging; @@ -5663,7 +5801,6 @@ extern int slirp_debug; extern int fakemodewaitms; extern float sound_sync_multiplier; extern int log_cd32; -extern int scanline_adjust; extern int log_ld; extern int logitech_lcd; extern uae_s64 max_avi_size; @@ -6059,10 +6196,6 @@ static int parseargs(const TCHAR *argx, const TCHAR *np, const TCHAR *np2) log_ethernet = getval(np); return 2; } - if (!_tcscmp(arg, _T("scanlineadjust"))) { - scanline_adjust = getval(np); - return 2; - } if (!_tcscmp (arg, _T("vsync_modechangetimeout"))) { vsync_modechangetimeout = getval (np); return 2; @@ -6107,10 +6240,6 @@ static int parseargs(const TCHAR *argx, const TCHAR *np, const TCHAR *np2) log_ld = getval (np); return 2; } - if (!_tcscmp (arg, _T("vsyncbusywait"))) { - vsync_busy_wait_mode = getval (np); - return 2; - } if (!_tcscmp (arg, _T("midiinbuffer"))) { midi_inbuflen = getval (np); if (midi_inbuflen < 16000) @@ -7281,9 +7410,10 @@ struct winuae //this struct is put in a6 if you call void *uaenative_get_uaevar (void) { + struct AmigaMonitor *mon = &AMonitors[0]; static struct winuae uaevar; #ifdef _WIN32 - uaevar.amigawnd = hAmigaWnd; + uaevar.amigawnd = mon->hAmigaWnd; #endif uaevar.z3offset = (uae_u32)get_real_address (z3fastmem_bank[0].start) - z3fastmem_bank[0].start; return &uaevar; diff --git a/od-win32/win32.h b/od-win32/win32.h index 35eee336..e305bf38 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -15,17 +15,17 @@ #define GETBDM(x) (((x) - ((x / 10000) * 10000)) / 100) #define GETBDD(x) ((x) % 100) -#define WINUAEPUBLICBETA 0 +#define WINUAEPUBLICBETA 1 #define LANG_DLL 1 #define LANG_DLL_FULL_VERSION_MATCH 1 #if WINUAEPUBLICBETA -#define WINUAEBETA _T("") +#define WINUAEBETA _T("1") #else #define WINUAEBETA _T("") #endif -#define WINUAEDATE MAKEBD(2018, 3, 4) +#define WINUAEDATE MAKEBD(2018, 4, 8) //#define WINUAEEXTRA _T("AmiKit Preview") //#define WINUAEEXTRA _T("Amiga Forever Edition") @@ -40,10 +40,7 @@ #define IHF_WINDOWHIDDEN 6 #define WINUAEAPPNAME _T("Arabuusimiehet.WinUAE") extern HMODULE hUIDLL; -extern HWND hAmigaWnd, hMainWnd, hHiddenWnd, hGUIWnd; -extern RECT amigawin_rect, mainwin_rect; -extern int in_sizemove; -extern int manual_painting_needed; +extern HWND hHiddenWnd, hGUIWnd; extern int mouseactive; extern int minimized; extern int monitor_off; @@ -67,28 +64,27 @@ void WIN32_HandleRegistryStuff (void); extern void setup_brkhandler (void); extern void remove_brkhandler (void); extern void disablecapture (void); -extern int isfocus (void); +extern int isfocus(void); extern void gui_restart (void); int timebegin (void); int timeend (void); -extern void setmouseactive (int active); -extern void minimizewindow (void); -extern uae_u32 OSDEP_minimize_uae (void); -extern void updatemouseclip (void); -extern void updatewinrect (bool); +extern void setmouseactive(int monid, int active); +extern void minimizewindow(int monid); +extern uae_u32 OSDEP_minimize_uae(void); +extern void updatemouseclip(struct AmigaMonitor*); +extern void updatewinrect(struct AmigaMonitor*, bool); extern bool resumepaused (int priority); extern bool setpaused (int priority); -extern void unsetminimized (void); -extern void setminimized (void); +extern void unsetminimized (int monid); +extern void setminimized(int monid); void finishjob (void); -void init_colors (void); +void init_colors(int monid); extern int pause_emulation; extern int sound_available; -extern int framecnt; extern TCHAR VersionStr[256]; extern TCHAR BetaStr[64]; extern int os_admin, os_64bit, os_vista, os_win7, os_win8, os_win10, cpu_number, os_touch; @@ -99,10 +95,7 @@ extern int gui_active; extern int quickstart, configurationcache, saveimageoriginalpath, relativepaths, artcache, recursiveromscan; extern HKEY hWinUAEKey; -extern int screen_is_picasso; extern HINSTANCE hInst; -extern int win_x_diff, win_y_diff; -extern int window_extra_width, window_extra_height; extern int af_path_2005; extern TCHAR start_path_new1[MAX_DPATH], start_path_new2[MAX_DPATH]; extern TCHAR bootlogpath[MAX_DPATH]; diff --git a/od-win32/win32_scaler.cpp b/od-win32/win32_scaler.cpp index cd04da8c..099ac6eb 100644 --- a/od-win32/win32_scaler.cpp +++ b/od-win32/win32_scaler.cpp @@ -56,7 +56,7 @@ static int deskw, deskh; static int d3d; static bool inited; -void getfilteroffset (float *dx, float *dy, float *mx, float *my) +void getfilteroffset(int monid, float *dx, float *dy, float *mx, float *my) { *dx = filteroffsetx; *dy = filteroffsety; @@ -99,10 +99,11 @@ static void sizeoffset (RECT *dr, RECT *zr, int w, int h) OffsetRect (zr, w / 2, h / 2); } -static void getmanualpos (int *cxp, int *cyp, int *cwp, int *chp) +static void getmanualpos(int monid, int *cxp, int *cyp, int *cwp, int *chp) { + struct vidbuf_description *avidinfo = &adisplays[monid].gfxvidinfo; int v, cx, cy, cw, ch; - bool native = isnativevidbuf (); + bool native = isnativevidbuf(monid); cx = *cxp; cy = *cyp; @@ -117,9 +118,9 @@ static void getmanualpos (int *cxp, int *cyp, int *cwp, int *chp) v = currprefs.gfx_xcenter_size; if (v <= 0) { if (programmedmode && native) { - cw = gfxvidinfo.outbuffer->outwidth << (RES_MAX - currprefs.gfx_resolution); + cw = avidinfo->outbuffer->outwidth << (RES_MAX - currprefs.gfx_resolution); } else { - cw = native ? AMIGA_WIDTH_MAX << RES_MAX : gfxvidinfo.outbuffer->outwidth; + cw = native ? AMIGA_WIDTH_MAX << RES_MAX : avidinfo->outbuffer->outwidth; } } else { cw = v; @@ -129,9 +130,9 @@ static void getmanualpos (int *cxp, int *cyp, int *cwp, int *chp) v = currprefs.gfx_ycenter_size; if (v <= 0) { if (programmedmode && native) { - ch = gfxvidinfo.outbuffer->outheight << (VRES_MAX - currprefs.gfx_vresolution); + ch = avidinfo->outbuffer->outheight << (VRES_MAX - currprefs.gfx_vresolution); } else { - ch = native ? AMIGA_HEIGHT_MAX << VRES_MAX : gfxvidinfo.outbuffer->outheight; + ch = native ? AMIGA_HEIGHT_MAX << VRES_MAX : avidinfo->outbuffer->outheight; } } else { ch = v; @@ -144,10 +145,11 @@ static void getmanualpos (int *cxp, int *cyp, int *cwp, int *chp) *chp = ch; } -static bool get_auto_aspect_ratio(int cw, int ch, int crealh, int scalemode, float *autoaspectratio) +static bool get_auto_aspect_ratio(int monid, int cw, int ch, int crealh, int scalemode, float *autoaspectratio) { + struct amigadisplay *ad = &adisplays[monid]; *autoaspectratio = 0; - if (currprefs.gf[picasso_on].gfx_filter_keep_autoscale_aspect && cw > 0 && ch > 0 && crealh > 0 && (scalemode == AUTOSCALE_NORMAL || + if (currprefs.gf[ad->picasso_on].gfx_filter_keep_autoscale_aspect && cw > 0 && ch > 0 && crealh > 0 && (scalemode == AUTOSCALE_NORMAL || scalemode == AUTOSCALE_INTEGER_AUTOSCALE || scalemode == AUTOSCALE_MANUAL)) { float cw2 = cw; float ch2 = ch; @@ -163,8 +165,9 @@ static bool get_auto_aspect_ratio(int cw, int ch, int crealh, int scalemode, flo return false; } -static bool get_aspect(float *dstratiop, float *srcratiop, float *xmultp, float *ymultp, bool doautoaspect, float autoaspectratio) +static bool get_aspect(int monid, float *dstratiop, float *srcratiop, float *xmultp, float *ymultp, bool doautoaspect, float autoaspectratio) { + struct amigadisplay *ad = &adisplays[monid]; bool aspect = false; float dstratio = *dstratiop; float srcratio = *srcratiop; @@ -172,23 +175,23 @@ static bool get_aspect(float *dstratiop, float *srcratiop, float *xmultp, float *xmultp = 1.0; *ymultp = 1.0; - if (currprefs.gf[picasso_on].gfx_filter_keep_aspect || currprefs.gf[picasso_on].gfx_filter_aspect != 0) { + if (currprefs.gf[ad->picasso_on].gfx_filter_keep_aspect || currprefs.gf[ad->picasso_on].gfx_filter_aspect != 0) { - if (currprefs.gf[picasso_on].gfx_filter_keep_aspect) { + if (currprefs.gf[ad->picasso_on].gfx_filter_keep_aspect) { if (isvga()) { - if (currprefs.gf[picasso_on].gfx_filter_keep_aspect == 1) + if (currprefs.gf[ad->picasso_on].gfx_filter_keep_aspect == 1) dstratio = dstratio * 0.93f; } else { if (currprefs.ntscmode) { dstratio = dstratio * 1.21f; - if (currprefs.gf[picasso_on].gfx_filter_keep_aspect == 2 && ispal()) + if (currprefs.gf[ad->picasso_on].gfx_filter_keep_aspect == 2 && ispal()) dstratio = dstratio * 0.93f; - else if (currprefs.gf[picasso_on].gfx_filter_keep_aspect == 1 && !ispal()) + else if (currprefs.gf[ad->picasso_on].gfx_filter_keep_aspect == 1 && !ispal()) dstratio = dstratio * 0.98f; } else { - if (currprefs.gf[picasso_on].gfx_filter_keep_aspect == 2 && ispal()) + if (currprefs.gf[ad->picasso_on].gfx_filter_keep_aspect == 2 && ispal()) dstratio = dstratio * 0.95f; - else if (currprefs.gf[picasso_on].gfx_filter_keep_aspect == 1 && !ispal()) + else if (currprefs.gf[ad->picasso_on].gfx_filter_keep_aspect == 1 && !ispal()) dstratio = dstratio * 0.95f; } } @@ -218,25 +221,31 @@ static bool get_aspect(float *dstratiop, float *srcratiop, float *xmultp, float return aspect; } -void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height, int aw, int ah, int scale, int temp_width, int temp_height) +void getfilterrect2(int monid, RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height, int aw, int ah, int scale, int temp_width, int temp_height) { + struct AmigaMonitor *mon = &AMonitors[monid]; + struct amigadisplay *ad = &adisplays[monid]; + struct vidbuf_description *avidinfo = &adisplays[monid].gfxvidinfo; + struct uae_filter *usedfilter = mon->usedfilter; + struct monconfig *gmc = &currprefs.gfx_monitor[mon->monitor_id]; + struct monconfig *gmh = &changed_prefs.gfx_monitor[mon->monitor_id]; float srcratio, dstratio; int aws, ahs; int xs, ys; int extraw, extrah; int fpuv; - bool specialmode = !isnativevidbuf (); + bool specialmode = !isnativevidbuf(monid); float mrmx, mrmy, mrsx, mrsy; int extraw2; bool doautoaspect = false; float autoaspectratio; - float filter_horiz_zoom = currprefs.gf[picasso_on].gfx_filter_horiz_zoom / 1000.0f; - float filter_vert_zoom = currprefs.gf[picasso_on].gfx_filter_vert_zoom / 1000.0f; - float filter_horiz_zoom_mult = currprefs.gf[picasso_on].gfx_filter_horiz_zoom_mult; - float filter_vert_zoom_mult = currprefs.gf[picasso_on].gfx_filter_vert_zoom_mult; - float filter_horiz_offset = currprefs.gf[picasso_on].gfx_filter_horiz_offset / 10000.0f; - float filter_vert_offset = currprefs.gf[picasso_on].gfx_filter_vert_offset / 10000.0f; + float filter_horiz_zoom = currprefs.gf[ad->picasso_on].gfx_filter_horiz_zoom / 1000.0f; + float filter_vert_zoom = currprefs.gf[ad->picasso_on].gfx_filter_vert_zoom / 1000.0f; + float filter_horiz_zoom_mult = currprefs.gf[ad->picasso_on].gfx_filter_horiz_zoom_mult; + float filter_vert_zoom_mult = currprefs.gf[ad->picasso_on].gfx_filter_vert_zoom_mult; + float filter_horiz_offset = currprefs.gf[ad->picasso_on].gfx_filter_horiz_offset / 10000.0f; + float filter_vert_offset = currprefs.gf[ad->picasso_on].gfx_filter_vert_offset / 10000.0f; store_custom_limits (-1, -1, -1, -1); @@ -246,8 +255,8 @@ void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height filter_horiz_offset = filter_vert_offset = 0.0; } - if (screen_is_picasso) { - getrtgfilterrect2 (sr, dr, zr, dst_width, dst_height); + if (mon->screen_is_picasso) { + getrtgfilterrect2(monid, sr, dr, zr, dst_width, dst_height); return; } @@ -257,11 +266,11 @@ void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height aws = aw * scale; ahs = ah * scale; //write_log (_T("%d %d %d\n"), dst_width, temp_width, aws); - extraw = -aws * (filter_horiz_zoom - currprefs.gf[picasso_on].gfx_filteroverlay_overscan * 10) / 2.0f; - extrah = -ahs * (filter_vert_zoom - currprefs.gf[picasso_on].gfx_filteroverlay_overscan * 10) / 2.0f; + extraw = -aws * (filter_horiz_zoom - currprefs.gf[ad->picasso_on].gfx_filteroverlay_overscan * 10) / 2.0f; + extrah = -ahs * (filter_vert_zoom - currprefs.gf[ad->picasso_on].gfx_filteroverlay_overscan * 10) / 2.0f; extraw2 = 0; - if (D3D_getscalerect && D3D_getscalerect(&mrmx, &mrmy, &mrsx, &mrsy)) { + if (D3D_getscalerect && D3D_getscalerect(0, &mrmx, &mrmy, &mrsx, &mrsy)) { extraw2 = mrmx; //extrah -= mrmy; } @@ -283,9 +292,9 @@ void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height float ymult = filter_vert_zoom_mult; srcratio = 4.0f / 3.0f; - if (currprefs.gf[picasso_on].gfx_filter_aspect > 0) { - dstratio = (currprefs.gf[picasso_on].gfx_filter_aspect / ASPECTMULT) * 1.0f / (currprefs.gf[picasso_on].gfx_filter_aspect & (ASPECTMULT - 1)); - } else if (currprefs.gf[picasso_on].gfx_filter_aspect < 0) { + if (currprefs.gf[ad->picasso_on].gfx_filter_aspect > 0) { + dstratio = (currprefs.gf[ad->picasso_on].gfx_filter_aspect / ASPECTMULT) * 1.0f / (currprefs.gf[ad->picasso_on].gfx_filter_aspect & (ASPECTMULT - 1)); + } else if (currprefs.gf[ad->picasso_on].gfx_filter_aspect < 0) { if (isfullscreen () && deskw > 0 && deskh > 0) dstratio = 1.0f * deskw / deskh; else @@ -294,8 +303,8 @@ void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height dstratio = srcratio; } - int scalemode = currprefs.gf[picasso_on].gfx_filter_autoscale; - int oscalemode = changed_prefs.gf[picasso_on].gfx_filter_autoscale; + int scalemode = currprefs.gf[ad->picasso_on].gfx_filter_autoscale; + int oscalemode = changed_prefs.gf[ad->picasso_on].gfx_filter_autoscale; if (scalemode == AUTOSCALE_OVERSCAN_BLANK) { oscalemode = scalemode = AUTOSCALE_NONE; } @@ -308,8 +317,8 @@ void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height int w2 = (640 / 2) << currprefs.gfx_resolution; int h1 = (600 / 2) << currprefs.gfx_vresolution; int h2 = (400 / 2) << currprefs.gfx_vresolution; - int w = currprefs.gfx_size_win.width; - int h = currprefs.gfx_size_win.height; + int w = gmc->gfx_size_win.width; + int h = gmc->gfx_size_win.height; if (w <= w1 && h <= h1 && w >= w2 && h >= h2) scalemode = AUTOSCALE_NONE; else @@ -335,13 +344,13 @@ void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height if (specialmode) { cx = 0; cy = 0; - cw = gfxvidinfo.outbuffer->outwidth; - ch = gfxvidinfo.outbuffer->outheight; + cw = avidinfo->outbuffer->outwidth; + ch = avidinfo->outbuffer->outheight; } else { cx = 0; cy = 0; - cw = gfxvidinfo.drawbuffer.inwidth; - ch = gfxvidinfo.drawbuffer.inheight; + cw = avidinfo->drawbuffer.inwidth; + ch = avidinfo->drawbuffer.inheight; cv = 1; if (!(beamcon0 & 0x80) && (scalemode == AUTOSCALE_STATIC_NOMINAL)) { // || scalemode == AUTOSCALE_INTEGER)) { cx = 28 << currprefs.gfx_resolution; @@ -355,14 +364,14 @@ void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height } if (scalemode == AUTOSCALE_INTEGER || scalemode == AUTOSCALE_INTEGER_AUTOSCALE) { - int maxw = currprefs.gfx_size.width; - int maxh = currprefs.gfx_size.height; + int maxw = gmc->gfx_size.width; + int maxh = gmc->gfx_size.height; double mult = 1; bool ok = true; if (currprefs.gfx_xcenter_pos >= 0 || currprefs.gfx_ycenter_pos >= 0) { - changed_prefs.gf[picasso_on].gfx_filter_horiz_offset = currprefs.gf[picasso_on].gfx_filter_horiz_offset = 0.0; - changed_prefs.gf[picasso_on].gfx_filter_vert_offset = currprefs.gf[picasso_on].gfx_filter_vert_offset = 0.0; + changed_prefs.gf[ad->picasso_on].gfx_filter_horiz_offset = currprefs.gf[ad->picasso_on].gfx_filter_horiz_offset = 0.0; + changed_prefs.gf[ad->picasso_on].gfx_filter_vert_offset = currprefs.gf[ad->picasso_on].gfx_filter_vert_offset = 0.0; filter_horiz_offset = 0.0; filter_vert_offset = 0.0; get_custom_topedge (&cx, &cy, false); @@ -374,8 +383,8 @@ void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height store_custom_limits (cw, ch, cx, cy); } if (scalemode == AUTOSCALE_INTEGER || ok == false) { - getmanualpos (&cx, &cy, &cw, &ch); - store_custom_limits (cw, ch, cx, cy); + getmanualpos(monid, &cx, &cy, &cw, &ch); + store_custom_limits(cw, ch, cx, cy); } #if 0 @@ -400,7 +409,7 @@ void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height filter_horiz_zoom_mult = 1.0; filter_vert_zoom_mult = 1.0; - double multadd = 1.0 / (1 << currprefs.gf[picasso_on].gfx_filter_integerscalelimit); + double multadd = 1.0 / (1 << currprefs.gf[ad->picasso_on].gfx_filter_integerscalelimit); if (cw2 > maxw || ch2 > maxh) { while (cw2 / mult > maxw || ch2 / mult > maxh) mult += multadd; @@ -425,17 +434,17 @@ void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height } else if (scalemode == AUTOSCALE_MANUAL) { - changed_prefs.gf[picasso_on].gfx_filter_horiz_offset = currprefs.gf[picasso_on].gfx_filter_horiz_offset = 0.0; - changed_prefs.gf[picasso_on].gfx_filter_vert_offset = currprefs.gf[picasso_on].gfx_filter_vert_offset = 0.0; + changed_prefs.gf[ad->picasso_on].gfx_filter_horiz_offset = currprefs.gf[ad->picasso_on].gfx_filter_horiz_offset = 0.0; + changed_prefs.gf[ad->picasso_on].gfx_filter_vert_offset = currprefs.gf[ad->picasso_on].gfx_filter_vert_offset = 0.0; filter_horiz_offset = 0.0; filter_vert_offset = 0.0; get_custom_topedge (&cx, &cy, currprefs.gfx_xcenter_pos < 0 && currprefs.gfx_ycenter_pos < 0); //write_log (_T("%dx%d %dx%d\n"), cx, cy, currprefs.gfx_resolution, currprefs.gfx_vresolution); - getmanualpos (&cx, &cy, &cw, &ch); - set_custom_limits (cw, ch, cx, cy); - store_custom_limits (cw, ch, cx, cy); + getmanualpos(monid, &cx, &cy, &cw, &ch); + set_custom_limits(cw, ch, cx, cy); + store_custom_limits(cw, ch, cx, cy); scl = true; //write_log (_T("%dx%d %dx%d %dx%d\n"), currprefs.gfx_xcenter_pos, currprefs.gfx_ycenter_pos, cx, cy, cw, ch); @@ -464,7 +473,7 @@ void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height } if (!autoaspect_done) { - doautoaspect = get_auto_aspect_ratio(cw, ch, crealh, scalemode, &autoaspectratio); + doautoaspect = get_auto_aspect_ratio(monid, cw, ch, crealh, scalemode, &autoaspectratio); } if (currprefs.gfx_api == 0) { @@ -493,7 +502,7 @@ void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height OffsetRect (zr, cx * scale - (dst_width - ww) / 2, cy * scale - (dst_height - hh) / 2); goto cont; - } else if (scalemode == AUTOSCALE_RESIZE && isfullscreen () == 0 && !currprefs.gf[picasso_on].gfx_filteroverlay[0]) { + } else if (scalemode == AUTOSCALE_RESIZE && isfullscreen() == 0 && !currprefs.gf[ad->picasso_on].gfx_filteroverlay[0]) { static int lastresize = 0; static int lastdelay = 1; @@ -534,8 +543,8 @@ void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height lastresize = AUTORESIZE_FRAME_DELAY; lastdelay = 0; } - float scalex = currprefs.gf[picasso_on].gfx_filter_horiz_zoom_mult > 0 ? currprefs.gf[picasso_on].gfx_filter_horiz_zoom_mult : 1.0f; - float scaley = currprefs.gf[picasso_on].gfx_filter_vert_zoom_mult > 0 ? currprefs.gf[picasso_on].gfx_filter_vert_zoom_mult : 1.0f; + float scalex = currprefs.gf[ad->picasso_on].gfx_filter_horiz_zoom_mult > 0 ? currprefs.gf[ad->picasso_on].gfx_filter_horiz_zoom_mult : 1.0f; + float scaley = currprefs.gf[ad->picasso_on].gfx_filter_vert_zoom_mult > 0 ? currprefs.gf[ad->picasso_on].gfx_filter_vert_zoom_mult : 1.0f; SetRect (sr, 0, 0, cw * scale * scalex, ch * scale * scaley); dr->left = (temp_width - aws) /2; dr->top = (temp_height - ahs) / 2; @@ -549,15 +558,15 @@ void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height if (currprefs.gfx_ycenter_size >= 0) hh = currprefs.gfx_ycenter_size; if (scalemode == oscalemode) { - int oldwinw = currprefs.gfx_size_win.width; - int oldwinh = currprefs.gfx_size_win.height; - changed_prefs.gfx_size_win.width = ww; - changed_prefs.gfx_size_win.height = hh; + int oldwinw = gmc->gfx_size_win.width; + int oldwinh = gmc->gfx_size_win.height; + gmh->gfx_size_win.width = ww; + gmh->gfx_size_win.height = hh; fixup_prefs_dimensions (&changed_prefs); - if (oldwinw != changed_prefs.gfx_size_win.width || oldwinh != changed_prefs.gfx_size_win.height) + if (oldwinw != gmh->gfx_size_win.width || oldwinh != gmh->gfx_size_win.height) set_config_changed (); } - OffsetRect (zr, -(changed_prefs.gfx_size_win.width - ww + 1) / 2, -(changed_prefs.gfx_size_win.height - hh + 1) / 2); + OffsetRect (zr, -(gmh->gfx_size_win.width - ww + 1) / 2, -(gmh->gfx_size_win.height - hh + 1) / 2); filteroffsetx = -zr->left / scale; filteroffsety = -zr->top / scale; goto end; @@ -593,7 +602,7 @@ void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height diffy = dr->bottom - dr->top; } - if (get_aspect(&dstratio, &srcratio, &xmult, &ymult, doautoaspect, autoaspectratio)) { + if (get_aspect(monid, &dstratio, &srcratio, &xmult, &ymult, doautoaspect, autoaspectratio)) { diff = diffx - diffx * xmult; sizeoffset(dr, zr, diff, 0); filteroffsetx += diff / 2; @@ -620,7 +629,7 @@ cont: sizeoffset (dr, zr, extraw, extrah); - if (currprefs.gf[picasso_on].gfx_filter_keep_aspect) { + if (currprefs.gf[ad->picasso_on].gfx_filter_keep_aspect) { float xm, ym, m; xm = aws / dst_width; @@ -638,14 +647,14 @@ cont: } if (currprefs.ntscmode) { - if (currprefs.gf[picasso_on].gfx_filter_keep_aspect == 2 && ispal ()) + if (currprefs.gf[ad->picasso_on].gfx_filter_keep_aspect == 2 && ispal ()) dstratio = dstratio * 0.93f; - else if (currprefs.gf[picasso_on].gfx_filter_keep_aspect == 1 && !ispal ()) + else if (currprefs.gf[ad->picasso_on].gfx_filter_keep_aspect == 1 && !ispal ()) dstratio = dstratio * 0.98f; } else { - if (currprefs.gf[picasso_on].gfx_filter_keep_aspect == 2 && ispal ()) + if (currprefs.gf[ad->picasso_on].gfx_filter_keep_aspect == 2 && ispal ()) dstratio = dstratio * 0.95f; - else if (currprefs.gf[picasso_on].gfx_filter_keep_aspect == 1 && !ispal ()) + else if (currprefs.gf[ad->picasso_on].gfx_filter_keep_aspect == 1 && !ispal ()) dstratio = dstratio * 0.95f; } @@ -688,7 +697,7 @@ cont: end: - if (D3D_getscalerect && D3D_getscalerect(&mrmx, &mrmy, &mrsx, &mrsy)) { + if (D3D_getscalerect && D3D_getscalerect(0, &mrmx, &mrmy, &mrsx, &mrsy)) { sizeoffset (dr, zr, mrmx, mrmy); OffsetRect (dr, mrsx, mrsy); } @@ -709,18 +718,24 @@ end: } -void freefilterbuffer(uae_u8 *buf) +void freefilterbuffer(int monid, uae_u8 *buf) { - struct vidbuffer *vb = gfxvidinfo.outbuffer; + struct AmigaMonitor *mon = &AMonitors[monid]; + struct vidbuf_description *avidinfo = &adisplays[monid].gfxvidinfo; + struct vidbuffer *vb = avidinfo->outbuffer; + struct uae_filter *usedfilter = mon->usedfilter; if (usedfilter == NULL) { unlockscr3d(vb); } } -uae_u8 *getfilterbuffer (int *widthp, int *heightp, int *pitch, int *depth) +uae_u8 *getfilterbuffer(int monid, int *widthp, int *heightp, int *pitch, int *depth) { - struct vidbuffer *vb = gfxvidinfo.outbuffer; + struct AmigaMonitor *mon = &AMonitors[monid]; + struct vidbuf_description *avidinfo = &adisplays[monid].gfxvidinfo; + struct vidbuffer *vb = avidinfo->outbuffer; + struct uae_filter *usedfilter = mon->usedfilter; *widthp = 0; *heightp = 0; @@ -757,7 +772,7 @@ uae_u8 *getfilterbuffer (int *widthp, int *heightp, int *pitch, int *depth) #endif } -static void statusline (void) +static void statusline(int monid) { DDSURFACEDESC2 desc; RECT sr, dr; @@ -767,39 +782,39 @@ static void statusline (void) if (!(currprefs.leds_on_screen & STATUSLINE_CHIPSET) || !tempsurf) return; - statusline_getpos (&slx, &sly, dst_width, dst_height, 1, 1); + statusline_getpos(monid, &slx, &sly, dst_width, dst_height, 1, 1); lx = dst_width; ly = dst_height; - SetRect (&sr, slx, 0, slx + lx, TD_TOTAL_HEIGHT); - SetRect (&dr, slx, sly, slx + lx, sly + TD_TOTAL_HEIGHT); - DirectDraw_BlitRect (tempsurf, &sr, NULL, &dr); - if (DirectDraw_LockSurface (tempsurf, &desc)) { - statusline_render((uae_u8*)desc.lpSurface, dst_depth / 8, desc.lPitch, lx, ly, rc, gc, bc, NULL); + SetRect(&sr, slx, 0, slx + lx, TD_TOTAL_HEIGHT); + SetRect(&dr, slx, sly, slx + lx, sly + TD_TOTAL_HEIGHT); + DirectDraw_BlitRect(tempsurf, &sr, NULL, &dr); + if (DirectDraw_LockSurface(tempsurf, &desc)) { + statusline_render(0, (uae_u8*)desc.lpSurface, dst_depth / 8, desc.lPitch, lx, ly, rc, gc, bc, NULL); for (y = 0; y < TD_TOTAL_HEIGHT; y++) { uae_u8 *buf = (uae_u8*)desc.lpSurface + y * desc.lPitch; - draw_status_line_single (buf, dst_depth / 8, y, lx, rc, gc, bc, NULL); + draw_status_line_single(monid, buf, dst_depth / 8, y, lx, rc, gc, bc, NULL); } - DirectDraw_UnlockSurface (tempsurf); - DirectDraw_BlitRect (NULL, &dr, tempsurf, &sr); + DirectDraw_UnlockSurface(tempsurf); + DirectDraw_BlitRect(NULL, &dr, tempsurf, &sr); } } -void S2X_configure (int rb, int gb, int bb, int rs, int gs, int bs) +void S2X_configure(int monid, int rb, int gb, int bb, int rs, int gs, int bs) { - Init_2xSaI (rb, gb, bb, rs, gs, bs); - hq_init (rb, gb, bb, rs, gs, bs); - PAL_init (); + Init_2xSaI(rb, gb, bb, rs, gs, bs); + hq_init(rb, gb, bb, rs, gs, bs); + PAL_init(monid); bufmem_ptr = 0; } -void S2X_reset (void) +void S2X_reset(int monid) { if (!inited) return; - S2X_init (dst_width2, dst_height2, amiga_depth2); + S2X_init(monid, dst_width2, dst_height2, amiga_depth2); } -void S2X_free (void) +void S2X_free(int monid) { changed_prefs.leds_on_screen &= ~STATUSLINE_TARGET; currprefs.leds_on_screen &= ~STATUSLINE_TARGET; @@ -818,10 +833,14 @@ void S2X_free (void) inited = false; } -bool S2X_init (int dw, int dh, int dd) +bool S2X_init(int monid, int dw, int dh, int dd) { + struct vidbuf_description *avidinfo = &adisplays[monid].gfxvidinfo; + struct amigadisplay *ad = &adisplays[monid]; + struct vidbuffer *vb = avidinfo->outbuffer; + struct AmigaMonitor *mon = &AMonitors[monid]; + struct uae_filter *usedfilter = mon->usedfilter; int flags = 0; - struct vidbuffer *vb = gfxvidinfo.outbuffer; dst_width2 = dw; dst_height2 = dh; @@ -830,7 +849,7 @@ bool S2X_init (int dw, int dh, int dd) amiga_height2 = vb->outheight; amiga_depth2 = vb->pixbytes * 8; - S2X_free (); + S2X_free(monid); d3d = currprefs.gfx_api; changed_prefs.leds_on_screen |= STATUSLINE_TARGET; currprefs.leds_on_screen |= STATUSLINE_TARGET; @@ -843,10 +862,10 @@ bool S2X_init (int dw, int dh, int dd) else alloc_colors_rgb (5, 6, 5, 11, 5, 0, 0, 0, 0, 0, rc, gc, bc); - if (WIN32GFX_IsPicassoScreen ()) + if (WIN32GFX_IsPicassoScreen(mon)) return true; - if (!currprefs.gf[picasso_on].gfx_filter || !usedfilter) { + if (!currprefs.gf[ad->picasso_on].gfx_filter || !usedfilter) { usedfilter = &uaefilters[0]; scale = 1; } else { @@ -855,7 +874,7 @@ bool S2X_init (int dw, int dh, int dd) if ((amiga_depth2 == 16 && !(flags & UAE_FILTER_MODE_16)) || (amiga_depth2 == 32 && !(flags & UAE_FILTER_MODE_32))) { usedfilter = &uaefilters[0]; scale = 1; - changed_prefs.gf[picasso_on].gfx_filter = usedfilter->type; + changed_prefs.gf[ad->picasso_on].gfx_filter = usedfilter->type; } } #if 0 @@ -875,7 +894,7 @@ bool S2X_init (int dw, int dh, int dd) amiga_depth = vb->pixbytes * 8; if (d3d) { - int m = currprefs.gf[picasso_on].gfx_filter_filtermode + 1; + int m = currprefs.gf[ad->picasso_on].gfx_filter_filtermode + 1; if (m < scale) m = scale; temp_width = dst_width * m; @@ -930,9 +949,13 @@ bool S2X_init (int dw, int dh, int dd) return true; } -void S2X_render (void) +void S2X_render(int monid, int y_start, int y_end) { - struct vidbuffer *vb = gfxvidinfo.outbuffer; + struct AmigaMonitor *mon = &AMonitors[monid]; + struct amigadisplay *ad = &adisplays[monid]; + struct uae_filter *usedfilter = mon->usedfilter; + struct vidbuf_description *avidinfo = &adisplays[monid].gfxvidinfo; + struct vidbuffer *vb = avidinfo->outbuffer; int aw, ah, aws, ahs; uae_u8 *dptr, *enddptr, *sptr, *endsptr; int ok = 0; @@ -958,7 +981,7 @@ void S2X_render (void) bufmem_ptr = sptr; if (d3d) { - surfstart = D3D_locktexture (&pitch, &surf_height, true); + surfstart = D3D_locktexture(monid, &pitch, &surf_height, true); if (surfstart == NULL) return; } else { @@ -1112,9 +1135,9 @@ void S2X_render (void) } - if (ok == 0 && currprefs.gf[picasso_on].gfx_filter) { + if (ok == 0 && currprefs.gf[ad->picasso_on].gfx_filter) { usedfilter = &uaefilters[0]; - changed_prefs.gf[picasso_on].gfx_filter = usedfilter->type; + changed_prefs.gf[ad->picasso_on].gfx_filter = usedfilter->type; } end: @@ -1123,7 +1146,7 @@ end: } else { DirectDraw_UnlockSurface (tempsurf); - getfilterrect2 (&dr, &sr, &zr, dst_width, dst_height, aw, ah, scale, temp_width, temp_height); + getfilterrect2(monid, &dr, &sr, &zr, dst_width, dst_height, aw, ah, scale, temp_width, temp_height); //write_log (_T("(%d %d %d %d) - (%d %d %d %d) (%d %d)\n"), dr.left, dr.top, dr.right, dr.bottom, sr.left, sr.top, sr.right, sr.bottom, zr.left, zr.top); OffsetRect (&sr, zr.left, zr.top); if (sr.left < 0) @@ -1134,21 +1157,23 @@ end: if (sr.left < sr.right && sr.top < sr.bottom) DirectDraw_BlitRect (NULL, &dr, tempsurf, &sr); } - statusline (); + statusline(monid); } } -void S2X_refresh (void) +void S2X_refresh(int monid) { - DirectDraw_ClearSurface (NULL); - S2X_render (); + DirectDraw_ClearSurface(NULL); + S2X_render(monid, -1, -1); } -int S2X_getmult (void) +int S2X_getmult(int monid) { + struct AmigaMonitor *mon = &AMonitors[monid]; + struct uae_filter *usedfilter = mon->usedfilter; if (!usedfilter) return 1; - if (screen_is_picasso) + if (mon->screen_is_picasso) return 1; return usedfilter->intmul; } diff --git a/od-win32/win32gfx.cpp b/od-win32/win32gfx.cpp index a29f3f62..d07c7316 100644 --- a/od-win32/win32gfx.cpp +++ b/od-win32/win32gfx.cpp @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include "sysdeps.h" @@ -43,7 +45,6 @@ #include "win32gui.h" #include "sound.h" #include "inputdevice.h" -#include "opengl.h" #include "direct3d.h" #include "midi.h" #include "gui.h" @@ -81,64 +82,29 @@ #define SM_FULLWINDOW 7 #define SM_NONE 11 -struct uae_filter *usedfilter; -int scalepicasso; -static double remembered_vblank; -static volatile int vblankthread_mode, vblankthread_counter; static int deskhz; -struct winuae_currentmode { - unsigned int flags; - int native_width, native_height, native_depth, pitch; - int current_width, current_height, current_depth; - int amiga_width, amiga_height; - int initdone; - int fullfill; - int vsync; - int freq; -}; - struct MultiDisplay Displays[MAX_DISPLAYS + 1]; -static struct winuae_currentmode currentmodestruct; -static int screen_is_initialized; +struct AmigaMonitor AMonitors[MAX_AMIGAMONITORS]; +struct AmigaMonitor *amon = NULL; + static int display_change_requested; int window_led_drives, window_led_drives_end; int window_led_hd, window_led_hd_end; int window_led_joys, window_led_joys_end, window_led_joy_start; int window_led_msg, window_led_msg_end, window_led_msg_start; extern int console_logging; -int window_extra_width, window_extra_height; -static struct winuae_currentmode *currentmode = ¤tmodestruct; static int wasfullwindow_a, wasfullwindow_p; -static int vblankbasewait1, vblankbasewait2, vblankbasewait3, vblankbasefull, vblankbaseadjust; -static bool vblankbaselace; -static int vblankbaselace_chipset; -static bool vblankthread_oddeven, vblankthread_oddeven_got; -static int graphics_mode_changed; int vsync_modechangetimeout = 10; -int screen_is_picasso = 0; - -extern int reopen (int, bool); - -#define VBLANKTH_KILL 0 -#define VBLANKTH_CALIBRATE 1 -#define VBLANKTH_IDLE 2 -#define VBLANKTH_ACTIVE_WAIT 3 -#define VBLANKTH_ACTIVE 4 -#define VBLANKTH_ACTIVE_START 5 -#define VBLANKTH_ACTIVE_SKIPFRAME 6 -#define VBLANKTH_ACTIVE_SKIPFRAME2 7 - -static volatile bool vblank_found; -static volatile int flipthread_mode; -volatile bool vblank_found_chipset; -volatile bool vblank_found_rtg; -static HANDLE flipevent, flipevent2, vblankwaitevent; -static volatile int flipevent_mode; +int vsync_activeheight, vsync_totalheight; +float vsync_vblank, vsync_hblank; + +int reopen(struct AmigaMonitor *, int, bool); + static CRITICAL_SECTION screen_cs; static bool screen_cs_allocated; @@ -151,69 +117,14 @@ void gfx_unlock (void) LeaveCriticalSection (&screen_cs); } -int vsync_busy_wait_mode; - -static void vsync_sleep (bool preferbusy) -{ - struct apmode *ap = picasso_on ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0]; - bool dowait; - - if (vsync_busy_wait_mode == 0) { - dowait = ap->gfx_vflip || !preferbusy; - //dowait = !preferbusy; - } else if (vsync_busy_wait_mode < 0) { - dowait = true; - } else { - dowait = false; - } - if (dowait && (currprefs.m68k_speed >= 0 || currprefs.m68k_speed_throttle < 0)) - sleep_millis_main (1); - audio_finish_pull(); -} - -static void changevblankthreadmode_do (int newmode, bool fast) -{ - int t = vblankthread_counter; - vblank_found = false; - vblank_found_chipset = false; - vblank_found_rtg = false; - if (vblankthread_mode <= 0 || vblankthread_mode == newmode) - return; - vblankthread_mode = newmode; - if (newmode == VBLANKTH_KILL) { - flipthread_mode = 0; - SetEvent (flipevent); - while (flipthread_mode == 0) - sleep_millis_main (1); - CloseHandle (flipevent); - CloseHandle (flipevent2); - CloseHandle (vblankwaitevent); - flipevent = NULL; - flipevent2 = NULL; - vblankwaitevent = NULL; - } - if (!fast) { - while (t == vblankthread_counter && vblankthread_mode > 0); - } -} - -static void changevblankthreadmode (int newmode) -{ - changevblankthreadmode_do (newmode, false); -} -static void changevblankthreadmode_fast (int newmode) -{ - changevblankthreadmode_do (newmode, true); -} - -int WIN32GFX_IsPicassoScreen (void) +int WIN32GFX_IsPicassoScreen(struct AmigaMonitor *mon) { - return screen_is_picasso ? 1 : 0; + return mon->screen_is_picasso ? 1 : 0; } -int isscreen (void) +static int isscreen(struct AmigaMonitor *mon) { - return hMainWnd ? 1 : 0; + return mon->hMainWnd ? 1 : 0; } static void clearscreen (void) @@ -221,52 +132,46 @@ static void clearscreen (void) DirectDraw_FillPrimary (); } -static int isfullscreen_2 (struct uae_prefs *p) +static int isfullscreen_2(struct uae_prefs *p) { - int idx = screen_is_picasso ? 1 : 0; + struct AmigaMonitor *mon = &AMonitors[0]; + int idx = mon->screen_is_picasso ? 1 : 0; return p->gfx_apmode[idx].gfx_fullscreen == GFX_FULLSCREEN ? 1 : (p->gfx_apmode[idx].gfx_fullscreen == GFX_FULLWINDOW ? -1 : 0); } -int isfullscreen (void) +int isfullscreen(void) { - return isfullscreen_2 (&currprefs); + return isfullscreen_2(&currprefs); } -int is3dmode (void) +int WIN32GFX_GetDepth(struct AmigaMonitor *mon, int real) { - return currentmode->flags & (DM_D3D); + if (!mon->currentmode.native_depth) + return mon->currentmode.current_depth; + return real ? mon->currentmode.native_depth : mon->currentmode.current_depth; } -int WIN32GFX_GetDepth (int real) +int WIN32GFX_GetWidth(struct AmigaMonitor *mon) { - if (!currentmode->native_depth) - return currentmode->current_depth; - return real ? currentmode->native_depth : currentmode->current_depth; + return mon->currentmode.current_width; } -int WIN32GFX_GetWidth (void) +int WIN32GFX_GetHeight(struct AmigaMonitor *mon) { - return currentmode->current_width; + return mon->currentmode.current_height; } -int WIN32GFX_GetHeight (void) -{ - return currentmode->current_height; -} - -static int init_round; -static BOOL doInit (void); +static BOOL doInit (struct AmigaMonitor*); int default_freq = 60; -HWND hStatusWnd; -HBRUSH hStatusBkgB; - static uae_u8 *scrlinebuf; -static struct MultiDisplay *getdisplay2 (struct uae_prefs *p, int index) + +static struct MultiDisplay *getdisplay2(struct uae_prefs *p, int index) { + struct AmigaMonitor *mon = &AMonitors[0]; int max; - int display = index < 0 ? p->gfx_apmode[screen_is_picasso ? APMODE_RTG : APMODE_NATIVE].gfx_display - 1 : index; + int display = index < 0 ? p->gfx_apmode[mon->screen_is_picasso ? APMODE_RTG : APMODE_NATIVE].gfx_display - 1 : index; max = 0; while (Displays[max].monitorname) @@ -288,16 +193,17 @@ struct MultiDisplay *getdisplay (struct uae_prefs *p) return getdisplay2 (p, -1); } -void desktop_coords (int *dw, int *dh, int *ax, int *ay, int *aw, int *ah) +void desktop_coords(int monid, int *dw, int *dh, int *ax, int *ay, int *aw, int *ah) { + struct AmigaMonitor *mon = &AMonitors[monid]; struct MultiDisplay *md = getdisplay (&currprefs); *dw = md->rect.right - md->rect.left; *dh = md->rect.bottom - md->rect.top; - *ax = amigawin_rect.left; - *ay = amigawin_rect.top; - *aw = amigawin_rect.right - *ax; - *ah = amigawin_rect.bottom - *ay; + *ax = mon->amigawin_rect.left; + *ay = mon->amigawin_rect.top; + *aw = mon->amigawin_rect.right - *ax; + *ah = mon->amigawin_rect.bottom - *ay; } static int target_get_display2(const TCHAR *name, int mode) @@ -417,6 +323,167 @@ int target_get_display(const TCHAR *name) return -1; } +typedef NTSTATUS(CALLBACK* D3DKMTOPENADAPTERFROMHDC)(D3DKMT_OPENADAPTERFROMHDC*); +static D3DKMTOPENADAPTERFROMHDC pD3DKMTOpenAdapterFromHdc; +typedef NTSTATUS(CALLBACK* D3DKMTGETSCANLINE)(D3DKMT_GETSCANLINE*); +static D3DKMTGETSCANLINE pD3DKMTGetScanLine; +typedef NTSTATUS(CALLBACK* D3DKMTWAITFORVERTICALBLANKEVENT)(const D3DKMT_WAITFORVERTICALBLANKEVENT*); +static D3DKMTWAITFORVERTICALBLANKEVENT pD3DKMTWaitForVerticalBlankEvent; +#define STATUS_SUCCESS ((NTSTATUS)0) + +int target_get_display_scanline(int displayindex) +{ + if (!pD3DKMTGetScanLine) + return -2; + D3DKMT_GETSCANLINE sl = { 0 }; + struct MultiDisplay *md = displayindex < 0 ? getdisplay(&currprefs) : &Displays[displayindex]; + sl.VidPnSourceId = md->VidPnSourceId; + sl.hAdapter = md->AdapterHandle; + if (pD3DKMTGetScanLine(&sl) == STATUS_SUCCESS) { + if (sl.InVerticalBlank) + return -1; + return sl.ScanLine; + } + return -2; +} + +typedef LONG(CALLBACK* QUERYDISPLAYCONFIG)(UINT32, UINT32*, DISPLAYCONFIG_PATH_INFO*, UINT32*, DISPLAYCONFIG_MODE_INFO*, DISPLAYCONFIG_TOPOLOGY_ID*); +typedef LONG(CALLBACK* GETDISPLAYCONFIGBUFFERSIZES)(UINT32, UINT32*, UINT32*); +typedef LONG(CALLBACK* DISPLAYCONFIGGETDEVICEINFO)(DISPLAYCONFIG_DEVICE_INFO_HEADER*); + +static bool get_display_vblank_params(int displayindex, int *activeheightp, int *totalheightp, float *vblankp, float *hblankp) +{ + static QUERYDISPLAYCONFIG pQueryDisplayConfig; + static GETDISPLAYCONFIGBUFFERSIZES pGetDisplayConfigBufferSizes; + static DISPLAYCONFIGGETDEVICEINFO pDisplayConfigGetDeviceInfo; + if (!pQueryDisplayConfig) + pQueryDisplayConfig = (QUERYDISPLAYCONFIG)GetProcAddress(GetModuleHandle(_T("user32.dll")), "QueryDisplayConfig"); + if (!pGetDisplayConfigBufferSizes) + pGetDisplayConfigBufferSizes = (GETDISPLAYCONFIGBUFFERSIZES)GetProcAddress(GetModuleHandle(_T("user32.dll")), "GetDisplayConfigBufferSizes"); + if (!pDisplayConfigGetDeviceInfo) + pDisplayConfigGetDeviceInfo = (DISPLAYCONFIGGETDEVICEINFO)GetProcAddress(GetModuleHandle(_T("user32.dll")), "DisplayConfigGetDeviceInfo"); + if (!pQueryDisplayConfig || !pGetDisplayConfigBufferSizes || !pDisplayConfigGetDeviceInfo) + return false; + struct MultiDisplay *md = displayindex < 0 ? getdisplay (&currprefs) : &Displays[displayindex]; + UINT32 pathCount, modeCount; + bool ret = false; + if (pGetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &pathCount, &modeCount) == ERROR_SUCCESS) { + DISPLAYCONFIG_PATH_INFO *displayPaths; + DISPLAYCONFIG_MODE_INFO *displayModes; + displayPaths = xmalloc(DISPLAYCONFIG_PATH_INFO, pathCount); + displayModes = xmalloc(DISPLAYCONFIG_MODE_INFO, modeCount); + if (pQueryDisplayConfig(QDC_ONLY_ACTIVE_PATHS, &pathCount, displayPaths, &modeCount, displayModes, NULL) == ERROR_SUCCESS) { + for (int i = 0; i < pathCount; i++) { + DISPLAYCONFIG_PATH_INFO *path = &displayPaths[i]; + DISPLAYCONFIG_MODE_INFO *target = &displayModes[path->targetInfo.modeInfoIdx]; + DISPLAYCONFIG_MODE_INFO *source = &displayModes[path->sourceInfo.modeInfoIdx]; + DISPLAYCONFIG_SOURCE_DEVICE_NAME dcsdn; + DISPLAYCONFIG_DEVICE_INFO_HEADER *dcdih = &dcsdn.header; + dcdih->size = sizeof dcsdn; + dcdih->adapterId = source->adapterId; + dcdih->id = source->id; + dcdih->type = DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME; + if (pDisplayConfigGetDeviceInfo(dcdih) == ERROR_SUCCESS) { + if (!_tcscmp(md->adapterid, dcsdn.viewGdiDeviceName)) { + DISPLAYCONFIG_VIDEO_SIGNAL_INFO *si = &target->targetMode.targetVideoSignalInfo; + if (activeheightp) + *activeheightp = si->activeSize.cy; + if (totalheightp) + *totalheightp = si->totalSize.cy; + float vblank = (float)si->vSyncFreq.Numerator / si->vSyncFreq.Denominator; + float hblank = (float)si->hSyncFreq.Numerator / si->hSyncFreq.Denominator; + if (vblankp) + *vblankp = vblank; + if (hblankp) + *hblankp = hblank; + write_log(_T("ActiveHeight: %d TotalHeight: %d VFreq=%d/%d=%.2fHz HFreq=%d/%d=%.3fKHz\n"), + target->targetMode.targetVideoSignalInfo.activeSize.cy, + target->targetMode.targetVideoSignalInfo.totalSize.cy, + target->targetMode.targetVideoSignalInfo.vSyncFreq.Numerator, + target->targetMode.targetVideoSignalInfo.vSyncFreq.Denominator, + vblank, + target->targetMode.targetVideoSignalInfo.hSyncFreq.Numerator, + target->targetMode.targetVideoSignalInfo.hSyncFreq.Denominator, + hblank / 1000.0); + ret = true; + break; + } + } + } + } + xfree(displayModes); + xfree(displayPaths); + } + return ret; +} + +static volatile int waitvblankthread_mode; +HANDLE waitvblankevent; +static frame_time_t wait_vblank_timestamp; +static MultiDisplay *wait_vblank_display; +static volatile bool vsync_active; + +static unsigned int __stdcall waitvblankthread(void *dummy) +{ + waitvblankthread_mode = 2; + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); + while (waitvblankthread_mode) { + D3DKMT_WAITFORVERTICALBLANKEVENT e = { 0 }; + e.hAdapter = wait_vblank_display->AdapterHandle; + e.VidPnSourceId = wait_vblank_display->VidPnSourceId; + pD3DKMTWaitForVerticalBlankEvent(&e); + wait_vblank_timestamp = read_processor_time(); + vsync_active = true; + SetEvent(waitvblankevent); + } + waitvblankthread_mode = -1; + return 0; +} + +extern void target_calibrate_spin(void); +static void display_param_init(struct AmigaMonitor *mon) +{ + struct amigadisplay *ad = &adisplays[mon->monitor_id]; + struct apmode *ap = ad->picasso_on ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0]; + + wait_vblank_display = getdisplay(&currprefs); + + vsync_activeheight = mon->currentmode.current_height; + vsync_totalheight = vsync_activeheight * 1125 / 1080; + vsync_vblank = 0; + vsync_hblank = 0; + get_display_vblank_params(-1, &vsync_activeheight, &vsync_totalheight, &vsync_vblank, &vsync_hblank); + // GPU scaled mode? + if (vsync_activeheight > mon->currentmode.current_height) { + float m = (float)vsync_activeheight / mon->currentmode.current_height; + vsync_hblank = (int)(vsync_hblank / m + 0.5); + vsync_activeheight = mon->currentmode.current_height; + } + + if (ap->gfx_vsyncmode && pD3DKMTWaitForVerticalBlankEvent) { + waitvblankevent = CreateEvent(NULL, FALSE, FALSE, NULL); + waitvblankthread_mode = 1; + unsigned int th; + _beginthreadex(NULL, 0, waitvblankthread, 0, 0, &th); + } + Sleep(10); + target_calibrate_spin(); +} + +static void display_param_free(void) +{ + if (waitvblankthread_mode == 2) { + waitvblankthread_mode = 0; + while (waitvblankthread_mode != -1) { + Sleep(10); + } + waitvblankthread_mode = 0; + CloseHandle(waitvblankevent); + waitvblankevent = NULL; + } + wait_vblank_display = NULL; +} + const TCHAR *target_get_display_name (int num, bool friendlyname) { if (num <= 0) @@ -429,33 +496,37 @@ const TCHAR *target_get_display_name (int num, bool friendlyname) return md->monitorid; } -void centerdstrect (RECT *dr) +void centerdstrect(struct AmigaMonitor *mon, RECT *dr) { - if(!(currentmode->flags & (DM_DX_FULLSCREEN | DM_D3D_FULLSCREEN | DM_W_FULLSCREEN))) - OffsetRect (dr, amigawin_rect.left, amigawin_rect.top); - if (currentmode->flags & DM_W_FULLSCREEN) { - if (scalepicasso && screen_is_picasso) + struct uae_filter *usedfilter = mon->usedfilter; + if(!(mon->currentmode.flags & (DM_DX_FULLSCREEN | DM_D3D_FULLSCREEN | DM_W_FULLSCREEN))) + OffsetRect (dr, mon->amigawin_rect.left, mon->amigawin_rect.top); + if (mon->currentmode.flags & DM_W_FULLSCREEN) { + if (mon->scalepicasso && mon->screen_is_picasso) return; - if (usedfilter && !screen_is_picasso) + if (usedfilter && !mon->screen_is_picasso) return; - if (currentmode->fullfill && (currentmode->current_width > currentmode->native_width || currentmode->current_height > currentmode->native_height)) + if (mon->currentmode.fullfill && (mon->currentmode.current_width > mon->currentmode.native_width || mon->currentmode.current_height > mon->currentmode.native_height)) return; - OffsetRect (dr, (currentmode->native_width - currentmode->current_width) / 2, - (currentmode->native_height - currentmode->current_height) / 2); + OffsetRect (dr, (mon->currentmode.native_width - mon->currentmode.current_width) / 2, + (mon->currentmode.native_height - mon->currentmode.current_height) / 2); } } static int picasso_offset_x, picasso_offset_y; static float picasso_offset_mx, picasso_offset_my; -void getgfxoffset (float *dxp, float *dyp, float *mxp, float *myp) +void getgfxoffset(int monid, float *dxp, float *dyp, float *mxp, float *myp) { + struct AmigaMonitor *mon = &AMonitors[monid]; + struct amigadisplay *ad = &adisplays[monid]; + struct uae_filter *usedfilter = mon->usedfilter; float dx, dy; - getfilteroffset (&dx, &dy, mxp, myp); + getfilteroffset(monid, &dx, &dy, mxp, myp); *dxp = dx; *dyp = dy; - if (picasso_on) { + if (ad->picasso_on) { dx = picasso_offset_x; dy = picasso_offset_y; *mxp = picasso_offset_mx; @@ -463,27 +534,27 @@ void getgfxoffset (float *dxp, float *dyp, float *mxp, float *myp) } *dxp = dx; *dyp = dy; - if (currentmode->flags & DM_W_FULLSCREEN) { - if (scalepicasso && screen_is_picasso) + if (mon->currentmode.flags & DM_W_FULLSCREEN) { + if (mon->scalepicasso && mon->screen_is_picasso) return; - if (usedfilter && !screen_is_picasso) + if (usedfilter && !mon->screen_is_picasso) return; - if (currentmode->fullfill && (currentmode->current_width > currentmode->native_width || currentmode->current_height > currentmode->native_height)) + if (mon->currentmode.fullfill && (mon->currentmode.current_width > mon->currentmode.native_width || mon->currentmode.current_height > mon->currentmode.native_height)) return; - dx += (currentmode->native_width - currentmode->current_width) / 2; - dy += (currentmode->native_height - currentmode->current_height) / 2; + dx += (mon->currentmode.native_width - mon->currentmode.current_width) / 2; + dy += (mon->currentmode.native_height - mon->currentmode.current_height) / 2; } *dxp = dx; *dyp = dy; } -void DX_Fill (int dstx, int dsty, int width, int height, uae_u32 color) +void DX_Fill(struct AmigaMonitor *mon, int dstx, int dsty, int width, int height, uae_u32 color) { RECT dstrect; if (width < 0) - width = currentmode->current_width; + width = mon->currentmode.current_width; if (height < 0) - height = currentmode->current_height; + height = mon->currentmode.current_height; SetRect (&dstrect, dstx, dsty, dstx + width, dsty + height); DirectDraw_Fill (&dstrect, color); } @@ -499,9 +570,10 @@ static int rgbformat_bits (RGBFTYPE t) : 0); } -int getrefreshrate (int width, int height) +int getrefreshrate(int monid, int width, int height) { - struct apmode *ap = picasso_on ? &currprefs.gfx_apmode[APMODE_RTG] : &currprefs.gfx_apmode[APMODE_NATIVE]; + struct amigadisplay *ad = &adisplays[monid]; + struct apmode *ap = ad->picasso_on ? &currprefs.gfx_apmode[APMODE_RTG] : &currprefs.gfx_apmode[APMODE_NATIVE]; int freq = 0; if (ap->gfx_refreshrate <= 0) @@ -523,23 +595,26 @@ int getrefreshrate (int width, int height) return freq; } -static int set_ddraw_2 (void) +static int set_ddraw_2(struct AmigaMonitor *mon) { + struct amigadisplay *ad = &adisplays[mon->monitor_id]; + struct picasso96_state_struct *state = &picasso96_state[mon->monitor_id]; + HRESULT ddrval; - int bits = (currentmode->current_depth + 7) & ~7; - int width = currentmode->native_width; - int height = currentmode->native_height; + int bits = (mon->currentmode.current_depth + 7) & ~7; + int width = mon->currentmode.native_width; + int height = mon->currentmode.native_height; int dxfullscreen, wfullscreen, dd; - struct apmode *ap = picasso_on ? &currprefs.gfx_apmode[APMODE_RTG] : &currprefs.gfx_apmode[APMODE_NATIVE]; + struct apmode *ap = ad->picasso_on ? &currprefs.gfx_apmode[APMODE_RTG] : &currprefs.gfx_apmode[APMODE_NATIVE]; int freq = ap->gfx_refreshrate; - dxfullscreen = (currentmode->flags & DM_DX_FULLSCREEN) ? TRUE : FALSE; - wfullscreen = (currentmode->flags & DM_W_FULLSCREEN) ? TRUE : FALSE; - dd = (currentmode->flags & DM_DDRAW) ? TRUE : FALSE; + dxfullscreen = (mon->currentmode.flags & DM_DX_FULLSCREEN) ? TRUE : FALSE; + wfullscreen = (mon->currentmode.flags & DM_W_FULLSCREEN) ? TRUE : FALSE; + dd = (mon->currentmode.flags & DM_DDRAW) ? TRUE : FALSE; - if (WIN32GFX_IsPicassoScreen () && (picasso96_state.Width > width || picasso96_state.Height > height)) { - width = picasso96_state.Width; - height = picasso96_state.Height; + if (WIN32GFX_IsPicassoScreen(mon) && (state->Width > width || state->Height > height)) { + width = state->Width; + height = state->Height; } DirectDraw_FreeMainSurface (); @@ -547,14 +622,14 @@ static int set_ddraw_2 (void) if (!dd && !dxfullscreen) return 1; - ddrval = DirectDraw_SetCooperativeLevel (hAmigaWnd, dxfullscreen, TRUE); + ddrval = DirectDraw_SetCooperativeLevel (mon->hAmigaWnd, dxfullscreen, TRUE); if (FAILED (ddrval)) goto oops; if (dxfullscreen) { for (;;) { HRESULT olderr; - freq = getrefreshrate (width, height); + freq = getrefreshrate(mon->monitor_id, width, height); write_log (_T("set_ddraw: trying %dx%d, bits=%d, refreshrate=%d\n"), width, height, bits, freq); ddrval = DirectDraw_SetDisplayMode (width, height, bits, freq); if (SUCCEEDED (ddrval)) @@ -563,7 +638,7 @@ static int set_ddraw_2 (void) if (freq) { write_log (_T("set_ddraw: failed, trying without forced refresh rate\n")); freq = 0; - DirectDraw_SetCooperativeLevel (hAmigaWnd, dxfullscreen, TRUE); + DirectDraw_SetCooperativeLevel (mon->hAmigaWnd, dxfullscreen, TRUE); ddrval = DirectDraw_SetDisplayMode (width, height, bits, freq); if (SUCCEEDED (ddrval)) break; @@ -572,8 +647,8 @@ static int set_ddraw_2 (void) goto oops; return -1; } - currentmode->freq = freq; - updatewinrect (true); + mon->currentmode.freq = freq; + updatewinrect(mon, true); } if (dd) { @@ -585,11 +660,11 @@ static int set_ddraw_2 (void) write_log (_T("set_ddraw: couldn't CreateSurface() for primary because %s.\n"), DXError (ddrval)); goto oops; } - ddrval = DirectDraw_SetClipper (hAmigaWnd); + ddrval = DirectDraw_SetClipper(mon->hAmigaWnd); if (FAILED (ddrval)) goto oops; if (DirectDraw_SurfaceLock ()) { - currentmode->pitch = DirectDraw_GetSurfacePitch (); + mon->currentmode.pitch = DirectDraw_GetSurfacePitch (); DirectDraw_SurfaceUnlock (); } } @@ -856,6 +931,7 @@ static BOOL CALLBACK monitorEnumProc2(HMONITOR h, HDC hdc, LPRECT rect, LPARAM d } return TRUE; } + void reenumeratemonitors(void) { for (int i = 0; i < MAX_DISPLAYS; i++) { @@ -945,6 +1021,20 @@ static bool enumeratedisplays2 (bool selectall) md->monitorid = my_strdup (mdd.DeviceKey); if (add.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) md->primary = true; + if (pD3DKMTOpenAdapterFromHdc) { + HDC hdc = CreateDC(NULL, add.DeviceName, NULL, NULL); + if (hdc != NULL) { + D3DKMT_OPENADAPTERFROMHDC OpenAdapterData = { 0 }; + OpenAdapterData.hDc = hdc; + if (pD3DKMTOpenAdapterFromHdc(&OpenAdapterData) == STATUS_SUCCESS) { + md->AdapterLuid = OpenAdapterData.AdapterLuid; + md->VidPnSourceId = OpenAdapterData.VidPnSourceId; + md->AdapterHandle = OpenAdapterData.hAdapter; + } + DeleteDC(hdc); + } + } + md++; } if (md - Displays >= MAX_DISPLAYS) @@ -974,6 +1064,11 @@ static bool enumeratedisplays2 (bool selectall) } void enumeratedisplays (void) { + if (!pD3DKMTWaitForVerticalBlankEvent) { + pD3DKMTOpenAdapterFromHdc = (D3DKMTOPENADAPTERFROMHDC)GetProcAddress(GetModuleHandle(_T("Gdi32.dll")), "D3DKMTOpenAdapterFromHdc"); + pD3DKMTGetScanLine = (D3DKMTGETSCANLINE)GetProcAddress(GetModuleHandle(_T("Gdi32.dll")), "D3DKMTGetScanLine"); + pD3DKMTWaitForVerticalBlankEvent = (D3DKMTWAITFORVERTICALBLANKEVENT)GetProcAddress(GetModuleHandle(_T("Gdi32.dll")), "D3DKMTWaitForVerticalBlankEvent"); + } if (!enumeratedisplays2 (false)) enumeratedisplays2(true); } @@ -1128,6 +1223,7 @@ int WIN32GFX_AdjustScreenmode (struct MultiDisplay *md, int *pwidth, int *pheigh return index; } +#if 0 static int flushymin, flushymax; #define FLUSH_DIFF 50 @@ -1135,12 +1231,12 @@ static void flushit (struct vidbuffer *vb, int lineno) { if (!currprefs.gfx_api) return; - if (currentmode->flags & DM_SWSCALE) + if (mon->currentmode.flags & DM_SWSCALE) return; if (flushymin > lineno) { if (flushymin - lineno > FLUSH_DIFF && flushymax != 0) { D3D_flushtexture (flushymin, flushymax); - flushymin = currentmode->amiga_height; + flushymin = mon->currentmode.amiga_height; flushymax = 0; } else { flushymin = lineno; @@ -1149,7 +1245,7 @@ static void flushit (struct vidbuffer *vb, int lineno) if (flushymax < lineno) { if (lineno - flushymax > FLUSH_DIFF && flushymax != 0) { D3D_flushtexture (flushymin, flushymax); - flushymin = currentmode->amiga_height; + flushymin = mon->currentmode.amiga_height; flushymax = 0; } else { flushymax = lineno; @@ -1171,64 +1267,51 @@ void flush_block (struct vidbuffer *vb, int first, int last) void flush_screen (struct vidbuffer *vb, int a, int b) { } +#endif -static volatile bool render_ok, wait_render; - -bool render_screen (bool immediate) +bool render_screen(int monid, int mode, bool immediate) { + struct AmigaMonitor *mon = &AMonitors[monid]; + struct amigadisplay *ad = &adisplays[monid]; bool v = false; int cnt; - render_ok = false; - if (minimized || picasso_on || monitor_off || dx_islost ()) { - return render_ok; + mon->render_ok = false; + if (minimized || ad->picasso_on || monitor_off || dx_islost ()) { + return mon->render_ok; } cnt = 0; - while (wait_render) { + while (mon->wait_render) { sleep_millis (1); cnt++; if (cnt > 500) { - return render_ok; + return mon->render_ok; } } - flushymin = 0; - flushymax = currentmode->amiga_height; +// flushymin = 0; +// flushymax = mon->currentmode.amiga_height; gfx_lock(); - if (currentmode->flags & DM_D3D) { - v = D3D_renderframe (immediate); - } else if (currentmode->flags & DM_SWSCALE) { - S2X_render (); + if (mon->currentmode.flags & DM_D3D) { + v = D3D_renderframe(monid, mode, immediate); + } else if (mon->currentmode.flags & DM_SWSCALE) { + S2X_render(monid, -1, -1); v = true; - } else if (currentmode->flags & DM_DDRAW) { + } else if (mon->currentmode.flags & DM_DDRAW) { v = true; } - render_ok = v; + mon->render_ok = v; gfx_unlock(); - return render_ok; -} - -static void waitflipevent (void) -{ - while (flipevent_mode) { - if (WaitForSingleObject (flipevent2, 10) == WAIT_ABANDONED) - break; - } -} -static void doflipevent (int mode) -{ - if (flipevent == NULL) - return; - waitflipevent (); - flipevent_mode = mode; - SetEvent (flipevent); + return mon->render_ok; } -bool show_screen_maybe (bool show) +bool show_screen_maybe(int monid, bool show) { - struct apmode *ap = picasso_on ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0]; + struct AmigaMonitor *mon = &AMonitors[monid]; + struct amigadisplay *ad = &adisplays[monid]; + struct apmode *ap = ad->picasso_on ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0]; if (!ap->gfx_vflip || ap->gfx_vsyncmode == 0 || ap->gfx_vsync <= 0) { if (show) - show_screen (0); + show_screen(monid, 0); return false; } #if 0 @@ -1242,13 +1325,14 @@ bool show_screen_maybe (bool show) void show_screen_special (void) { - if (!screen_is_initialized) + struct AmigaMonitor *mon = &AMonitors[0]; + if (!mon->screen_is_initialized) return; if (!D3D_showframe_special) return; - if (currentmode->flags & DM_D3D) { + if (mon->currentmode.flags & DM_D3D) { gfx_lock(); - D3D_showframe_special (1); + D3D_showframe_special(0, 1); gfx_unlock(); } } @@ -1264,7 +1348,8 @@ static void CALLBACK blackinsertion_cb( DWORD_PTR dw2 ) { - if (screen_is_initialized) { + struct AmigaMonitor *mon = &AMonitors[0]; + if (mon->screen_is_initialized) { while (strobo_active) { frame_time_t ct = read_processor_time(); int diff = (int)strobo_time - (int)ct; @@ -1284,13 +1369,14 @@ static void CALLBACK blackinsertion_cb( strobo_active = false; } -double target_adjust_vblank_hz(double hz) +float target_adjust_vblank_hz(int monid, float hz) { + struct AmigaMonitor *mon = &AMonitors[monid]; int maxrate; if (!currprefs.lightboost_strobo) return hz; if (isfullscreen() > 0) { - maxrate = currentmode->freq; + maxrate = mon->currentmode.freq; } else { maxrate = deskhz; } @@ -1300,37 +1386,39 @@ double target_adjust_vblank_hz(double hz) return hz; } -void show_screen (int mode) +void show_screen(int monid, int mode) { + struct AmigaMonitor *mon = &AMonitors[monid]; + struct amigadisplay *ad = &adisplays[monid]; strobo_active = false; strobo_active2 = false; gfx_lock(); if (mode == 2) { - if ((currentmode->flags & DM_D3D) && D3D_showframe_special) { - D3D_showframe_special (1); + if ((mon->currentmode.flags & DM_D3D) && D3D_showframe_special) { + D3D_showframe_special(0, 1); } gfx_unlock(); return; } - if (!render_ok) { + if (mode >= 0 && !mon->render_ok) { gfx_unlock(); return; } - if (currentmode->flags & DM_D3D) { - struct apmode *ap = picasso_on ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0]; + if (mon->currentmode.flags & DM_D3D) { + struct apmode *ap = ad->picasso_on ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0]; if (ap->gfx_vsync < 0 && ap->gfx_strobo && currprefs.gfx_api < 2) { - double vblank = vblank_hz; - if (WIN32GFX_IsPicassoScreen()) { + float vblank = vblank_hz; + if (WIN32GFX_IsPicassoScreen(mon)) { if (currprefs.win32_rtgvblankrate > 0) vblank = currprefs.win32_rtgvblankrate; } bool ok = true; int ratio = currprefs.lightboost_strobo_ratio; - int ms = 1000 / vblank; + int ms = (int)(1000 / vblank); int waitms = ms * ratio / 100 - 1; int maxrate; if (isfullscreen() > 0) { - maxrate = currentmode->freq; + maxrate = mon->currentmode.freq; } else { maxrate = deskhz; } @@ -1346,39 +1434,42 @@ void show_screen (int mode) timeSetEvent(waitms, 0, blackinsertion_cb, NULL, TIME_ONESHOT | TIME_CALLBACK_FUNCTION); } } - D3D_showframe(); - strobo_active2 = true; + D3D_showframe(monid); + if (monid == 0) + strobo_active2 = true; #ifdef GFXFILTER - } else if (currentmode->flags & DM_SWSCALE) { - if (!dx_islost () && !picasso_on) - DirectDraw_Flip (1); + } else if (mon->currentmode.flags & DM_SWSCALE) { + if (!dx_islost () && !ad->picasso_on) + DirectDraw_Flip(1); #endif - } else if (currentmode->flags & DM_DDRAW) { - if (!dx_islost () && !picasso_on) - DirectDraw_Flip (1); + } else if (mon->currentmode.flags & DM_DDRAW) { + if (!dx_islost () && !ad->picasso_on) + DirectDraw_Flip(1); } gfx_unlock(); - render_ok = false; + mon->render_ok = false; } static uae_u8 *ddraw_dolock (void) { + struct vidbuf_description *avidinfo = &adisplays[0].gfxvidinfo; if (!DirectDraw_SurfaceLock ()) { dx_check (); return 0; } - gfxvidinfo.outbuffer->bufmem = DirectDraw_GetSurfacePointer (); - gfxvidinfo.outbuffer->rowbytes = DirectDraw_GetSurfacePitch (); + avidinfo->outbuffer->bufmem = DirectDraw_GetSurfacePointer (); + avidinfo->outbuffer->rowbytes = DirectDraw_GetSurfacePitch (); init_row_map (); - clear_inhibit_frame (IHF_WINDOWHIDDEN); - return gfxvidinfo.outbuffer->bufmem; + clear_inhibit_frame(0, IHF_WINDOWHIDDEN); + return avidinfo->outbuffer->bufmem; } bool lockscr3d(struct vidbuffer *vb) { - if (currentmode->flags & DM_D3D) { - if (!(currentmode->flags & DM_SWSCALE)) { - vb->bufmem = D3D_locktexture(&vb->rowbytes, NULL, false); + struct AmigaMonitor *mon = &AMonitors[vb->monitor_id]; + if (mon->currentmode.flags & DM_D3D) { + if (!(mon->currentmode.flags & DM_SWSCALE)) { + vb->bufmem = D3D_locktexture(vb->monitor_id, &vb->rowbytes, NULL, false); if (vb->bufmem) return true; } @@ -1388,57 +1479,62 @@ bool lockscr3d(struct vidbuffer *vb) void unlockscr3d(struct vidbuffer *vb) { - if (currentmode->flags & DM_D3D) { - if (!(currentmode->flags & DM_SWSCALE)) { - D3D_unlocktexture(); + struct AmigaMonitor *mon = &AMonitors[vb->monitor_id]; + if (mon->currentmode.flags & DM_D3D) { + if (!(mon->currentmode.flags & DM_SWSCALE)) { + D3D_unlocktexture(vb->monitor_id, -1, -1); } } } -int lockscr (struct vidbuffer *vb, bool fullupdate) +int lockscr(struct vidbuffer *vb, bool fullupdate, bool first) { + struct AmigaMonitor *mon = &AMonitors[vb->monitor_id]; int ret = 0; - if (!isscreen ()) + if (!isscreen(mon)) return ret; - flushymin = currentmode->amiga_height; +#if 0 + flushymin = mon->currentmode.amiga_height; flushymax = 0; +#endif ret = 1; - if (currentmode->flags & DM_D3D) { + if (mon->currentmode.flags & DM_D3D) { #ifdef D3D - if (currentmode->flags & DM_SWSCALE) { + if (mon->currentmode.flags & DM_SWSCALE) { ret = 1; } else { ret = 0; - vb->bufmem = D3D_locktexture (&vb->rowbytes, NULL, fullupdate); + vb->bufmem = D3D_locktexture(vb->monitor_id, &vb->rowbytes, NULL, fullupdate); if (vb->bufmem) { - init_row_map (); + if (first) + init_row_map(); ret = 1; } } #endif - } else if (currentmode->flags & DM_SWSCALE) { + } else if (mon->currentmode.flags & DM_SWSCALE) { ret = 1; - } else if (currentmode->flags & DM_DDRAW) { - ret = ddraw_dolock () != 0; + } else if (mon->currentmode.flags & DM_DDRAW) { + ret = ddraw_dolock() != 0; } return ret; } -void unlockscr (struct vidbuffer *vb) +void unlockscr(struct vidbuffer *vb, int y_start, int y_end) { - if (currentmode->flags & DM_D3D) { - if (currentmode->flags & DM_SWSCALE) { - S2X_render (); + struct AmigaMonitor *mon = &AMonitors[vb->monitor_id]; + if (mon->currentmode.flags & DM_D3D) { + if (mon->currentmode.flags & DM_SWSCALE) { + S2X_render(vb->monitor_id, y_start, y_end); } else { - D3D_flushtexture (flushymin, flushymax); vb->bufmem = NULL; } - D3D_unlocktexture (); - } else if (currentmode->flags & DM_SWSCALE) { + D3D_unlocktexture(vb->monitor_id, y_start, y_end); + } else if (mon->currentmode.flags & DM_SWSCALE) { return; - } else if (currentmode->flags & DM_DDRAW) { - DirectDraw_SurfaceUnlock (); + } else if (mon->currentmode.flags & DM_DDRAW) { + DirectDraw_SurfaceUnlock(); vb->bufmem = NULL; } } @@ -1447,45 +1543,40 @@ void flush_clear_screen (struct vidbuffer *vb) { if (!vb) return; - if (lockscr (vb, true)) { + if (lockscr(vb, true, true)) { int y; for (y = 0; y < vb->height_allocated; y++) { - memset (vb->bufmem + y * vb->rowbytes, 0, vb->width_allocated * vb->pixbytes); + memset(vb->bufmem + y * vb->rowbytes, 0, vb->width_allocated * vb->pixbytes); } - unlockscr (vb); - flush_screen (vb, 0, 0); + unlockscr(vb, -1, -1); } } -/* For the DX_Invalidate() and gfx_unlock_picasso() functions */ -static int p96_double_buffer_firstx, p96_double_buffer_lastx; -static int p96_double_buffer_first, p96_double_buffer_last; -static int p96_double_buffer_needs_flushing = 0; - -static void DX_Blit96 (int x, int y, int w, int h) +static void DX_Blit96(struct AmigaMonitor *mon, int x, int y, int w, int h) { + struct picasso96_state_struct *state = &picasso96_state[mon->monitor_id]; RECT dr, sr; picasso_offset_x = 0; picasso_offset_y = 0; picasso_offset_mx = 1.0; picasso_offset_my = 1.0; - if (scalepicasso) { + if (mon->scalepicasso) { int srcratio, dstratio; int srcwidth, srcheight; - if (scalepicasso < 0 || scalepicasso > 1) { - srcwidth = picasso96_state.Width; - srcheight = picasso96_state.Height; + if (mon->scalepicasso < 0 || mon->scalepicasso > 1) { + srcwidth = state->Width; + srcheight = state->Height; } else { - srcwidth = currentmode->native_width; - srcheight = currentmode->native_height; + srcwidth = mon->currentmode.native_width; + srcheight = mon->currentmode.native_height; } - SetRect (&sr, 0, 0, picasso96_state.Width, picasso96_state.Height); + SetRect (&sr, 0, 0, state->Width, state->Height); if (currprefs.win32_rtgscaleaspectratio < 0) { // automatic - srcratio = picasso96_state.Width * ASPECTMULT / picasso96_state.Height; + srcratio = state->Width * ASPECTMULT / state->Height; dstratio = srcwidth * ASPECTMULT / srcheight; } else if (currprefs.win32_rtgscaleaspectratio == 0) { // none @@ -1506,8 +1597,8 @@ static void DX_Blit96 (int x, int y, int w, int h) SetRect (&dr, xx / 2, 0,srcwidth - xx / 2, srcheight); picasso_offset_x = xx / 2; } - picasso_offset_mx = (float)picasso96_state.Width / (dr.right - dr.left); - picasso_offset_my = (float)picasso96_state.Height / (dr.bottom - dr.top); + picasso_offset_mx = (float)state->Width / (dr.right - dr.left); + picasso_offset_my = (float)state->Height / (dr.bottom - dr.top); DirectDraw_BlitToPrimaryScale (&dr, &sr); } else { SetRect (&sr, x, y, x + w, y + h); @@ -1515,10 +1606,14 @@ static void DX_Blit96 (int x, int y, int w, int h) } } -void getrtgfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height) +void getrtgfilterrect2(int monid, RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height) { - SetRect (sr, 0, 0, currentmode->native_width, currentmode->native_height); - SetRect (dr, 0, 0, picasso96_state.Width, picasso96_state.Height); + struct AmigaMonitor *mon = &AMonitors[monid]; + struct amigadisplay *ad = &adisplays[monid]; + struct picasso96_state_struct *state = &picasso96_state[monid]; + + SetRect (sr, 0, 0, mon->currentmode.native_width, mon->currentmode.native_height); + SetRect (dr, 0, 0, state->Width, state->Height); SetRect (zr, 0, 0, 0, 0); picasso_offset_x = 0; @@ -1526,38 +1621,38 @@ void getrtgfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_hei picasso_offset_mx = 1.0; picasso_offset_my = 1.0; - if (!picasso_on) + if (!ad->picasso_on) return; - if (!scalepicasso) + if (!mon->scalepicasso) return; int srcratio, dstratio; int srcwidth, srcheight; - srcwidth = picasso96_state.Width; - srcheight = picasso96_state.Height; + srcwidth = state->Width; + srcheight = state->Height; if (!srcwidth || !srcheight) return; - if (scalepicasso == RTG_MODE_INTEGER_SCALE) { - int divx = currentmode->native_width / srcwidth; - int divy = currentmode->native_height / srcheight; + if (mon->scalepicasso == RTG_MODE_INTEGER_SCALE) { + int divx = mon->currentmode.native_width / srcwidth; + int divy = mon->currentmode.native_height / srcheight; int mul = divx > divy ? divy : divx; int xx = srcwidth * mul; int yy = srcheight * mul; - SetRect (dr, 0, 0, currentmode->native_width / mul, currentmode->native_height / mul); - //picasso_offset_x = -(picasso96_state.Width - xx) / 2; - //picasso_offset_y = -(currentmode->native_height - srcheight) / 2; - } else if (scalepicasso == RTG_MODE_CENTER) { - int xx = (currentmode->native_width - srcwidth) / 2; - int yy = (currentmode->native_height - srcheight) / 2; + SetRect (dr, 0, 0, mon->currentmode.native_width / mul, mon->currentmode.native_height / mul); + //picasso_offset_x = -(state->Width - xx) / 2; + //picasso_offset_y = -(mon->currentmode.native_height - srcheight) / 2; + } else if (mon->scalepicasso == RTG_MODE_CENTER) { + int xx = (mon->currentmode.native_width - srcwidth) / 2; + int yy = (mon->currentmode.native_height - srcheight) / 2; picasso_offset_x = -xx; picasso_offset_y = -yy; - SetRect (dr, 0, 0, currentmode->native_width, currentmode->native_height); + SetRect (dr, 0, 0, mon->currentmode.native_width, mon->currentmode.native_height); } else { if (currprefs.win32_rtgscaleaspectratio < 0) { // automatic srcratio = srcwidth * ASPECTMULT / srcheight; - dstratio = currentmode->native_width * ASPECTMULT / currentmode->native_height; + dstratio = mon->currentmode.native_width * ASPECTMULT / mon->currentmode.native_height; } else if (currprefs.win32_rtgscaleaspectratio == 0) { // none srcratio = dstratio = 0; @@ -1572,11 +1667,11 @@ void getrtgfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_hei } else if (srcratio > dstratio) { int yy = srcheight * srcratio / dstratio; SetRect (dr, 0, 0, srcwidth, yy); - picasso_offset_y = (picasso96_state.Height - yy) / 2; + picasso_offset_y = (state->Height - yy) / 2; } else { int xx = srcwidth * dstratio / srcratio; SetRect (dr, 0, 0, xx, srcheight); - picasso_offset_x = (picasso96_state.Width - xx) / 2; + picasso_offset_x = (state->Width - xx) / 2; } } @@ -1585,65 +1680,67 @@ void getrtgfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_hei picasso_offset_my = (float)srcheight / (dr->bottom - dr->top); } -static bool rtg_locked; - -static uae_u8 *gfx_lock_picasso2 (bool fullupdate) +static uae_u8 *gfx_lock_picasso2(int monid, bool fullupdate) { + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; if (currprefs.gfx_api) { int pitch; - uae_u8 *p = D3D_locktexture (&pitch, NULL, fullupdate); - picasso_vidinfo.rowbytes = pitch; + uae_u8 *p = D3D_locktexture(monid, &pitch, NULL, fullupdate); + vidinfo->rowbytes = pitch; return p; } else { if (!DirectDraw_SurfaceLock ()) { dx_check (); return 0; } - picasso_vidinfo.rowbytes = DirectDraw_GetSurfacePitch (); + vidinfo->rowbytes = DirectDraw_GetSurfacePitch (); return DirectDraw_GetSurfacePointer (); } } -uae_u8 *gfx_lock_picasso (bool fullupdate, bool doclear) +uae_u8 *gfx_lock_picasso(int monid, bool fullupdate, bool doclear) { + struct AmigaMonitor *mon = &AMonitors[monid]; + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; static uae_u8 *p; - if (rtg_locked) { + if (mon->rtg_locked) { return p; } gfx_lock(); - p = gfx_lock_picasso2 (fullupdate); + p = gfx_lock_picasso2(monid, fullupdate); if (!p) { gfx_unlock(); } else { - rtg_locked = true; + mon->rtg_locked = true; if (doclear) { uae_u8 *p2 = p; - for (int h = 0; h < picasso_vidinfo.height; h++) { - memset (p2, 0, picasso_vidinfo.width * picasso_vidinfo.pixbytes); - p2 += picasso_vidinfo.rowbytes; + for (int h = 0; h < vidinfo->height; h++) { + memset (p2, 0, vidinfo->width * vidinfo->pixbytes); + p2 += vidinfo->rowbytes; } } } return p; } -void gfx_unlock_picasso (bool dorender) +void gfx_unlock_picasso(int monid, bool dorender) { - if (!rtg_locked) + struct AmigaMonitor *mon = &AMonitors[monid]; + if (!mon->rtg_locked) gfx_lock(); - rtg_locked = false; + mon->rtg_locked = false; if (currprefs.gfx_api) { if (dorender) { - if (p96_double_buffer_needs_flushing) { - D3D_flushtexture (p96_double_buffer_first, p96_double_buffer_last); - p96_double_buffer_needs_flushing = 0; + if (mon->p96_double_buffer_needs_flushing) { + D3D_flushtexture(monid, mon->p96_double_buffer_first, mon->p96_double_buffer_last); + mon->p96_double_buffer_needs_flushing = 0; } } - D3D_unlocktexture (); + D3D_unlocktexture(monid, -1, -1); if (dorender) { - if (D3D_renderframe (false)) { + if (D3D_renderframe(monid, true, false)) { gfx_unlock(); - render_ok = true; - show_screen_maybe (true); + mon->render_ok = true; + show_screen_maybe(monid, true); } else { gfx_unlock(); } @@ -1653,11 +1750,11 @@ void gfx_unlock_picasso (bool dorender) } else { DirectDraw_SurfaceUnlock (); if (dorender) { - if (p96_double_buffer_needs_flushing) { - DX_Blit96 (p96_double_buffer_firstx, p96_double_buffer_first, - p96_double_buffer_lastx - p96_double_buffer_firstx + 1, - p96_double_buffer_last - p96_double_buffer_first + 1); - p96_double_buffer_needs_flushing = 0; + if (mon->p96_double_buffer_needs_flushing) { + DX_Blit96(mon, mon->p96_double_buffer_firstx, mon->p96_double_buffer_first, + mon->p96_double_buffer_lastx - mon->p96_double_buffer_firstx + 1, + mon->p96_double_buffer_last - mon->p96_double_buffer_first + 1); + mon->p96_double_buffer_needs_flushing = 0; } } gfx_unlock(); @@ -1700,51 +1797,56 @@ static void createblankwindows (void) } } -static void close_hwnds (void) +static void close_hwnds(struct AmigaMonitor *mon) { - screen_is_initialized = 0; + mon->screen_is_initialized = 0; + if (!mon->monitor_id) { + display_param_free(); #ifdef AVIOUTPUT - AVIOutput_Restart (); + AVIOutput_Restart(); #endif - setmouseactive (0); #ifdef RETROPLATFORM - rp_set_hwnd (NULL); + rp_set_hwnd(NULL); #endif - closeblankwindows (); - deletestatusline(); - rawinput_release(); - if (hStatusWnd) { - ShowWindow (hStatusWnd, SW_HIDE); - DestroyWindow (hStatusWnd); - hStatusWnd = 0; - if (hStatusBkgB) - DeleteObject(hStatusBkgB); - hStatusBkgB = NULL; - } - if (hAmigaWnd) { - addnotifications (hAmigaWnd, TRUE, FALSE); + closeblankwindows(); + rawinput_release(); + } + if (mon->monitor_id > 0 && mon->hMainWnd) + setmouseactive(mon->monitor_id, 0); + deletestatusline(mon->monitor_id); + if (mon->hStatusWnd) { + ShowWindow(mon->hStatusWnd, SW_HIDE); + DestroyWindow(mon->hStatusWnd); + mon->hStatusWnd = 0; + if (mon->hStatusBkgB) + DeleteObject(mon->hStatusBkgB); + mon->hStatusBkgB = NULL; + } + if (mon->hAmigaWnd) { + addnotifications (mon->hAmigaWnd, TRUE, FALSE); #ifdef D3D - D3D_free (true); + D3D_free(mon->monitor_id, true); #endif - ShowWindow (hAmigaWnd, SW_HIDE); - DestroyWindow (hAmigaWnd); - if (hAmigaWnd == hMainWnd) - hMainWnd = 0; - hAmigaWnd = 0; + ShowWindow (mon->hAmigaWnd, SW_HIDE); + DestroyWindow (mon->hAmigaWnd); + if (mon->hAmigaWnd == mon->hMainWnd) + mon->hMainWnd = 0; + mon->hAmigaWnd = 0; } - if (hMainWnd) { - ShowWindow (hMainWnd, SW_HIDE); - DestroyWindow (hMainWnd); - hMainWnd = 0; + if (mon->hMainWnd) { + ShowWindow(mon->hMainWnd, SW_HIDE); + DestroyWindow(mon->hMainWnd); + mon->hMainWnd = 0; } } -static void updatemodes (void) +static void updatemodes(struct AmigaMonitor *mon) { + struct uae_filter *usedfilter = mon->usedfilter; DWORD flags; - currentmode->fullfill = 0; + mon->currentmode.fullfill = 0; flags = DM_DDRAW; if (isfullscreen () > 0) flags |= DM_DX_FULLSCREEN; @@ -1753,8 +1855,8 @@ static void updatemodes (void) #if defined (GFXFILTER) if (usedfilter) { flags |= DM_SWSCALE; - if (currentmode->current_depth < 15) - currentmode->current_depth = 16; + if (mon->currentmode.current_depth < 15) + mon->currentmode.current_depth = 16; } #endif if (currprefs.gfx_api) { @@ -1765,29 +1867,31 @@ static void updatemodes (void) } flags &= ~DM_DDRAW; } - currentmode->flags = flags; + mon->currentmode.flags = flags; if (flags & DM_SWSCALE) - currentmode->fullfill = 1; + mon->currentmode.fullfill = 1; if (flags & DM_W_FULLSCREEN) { RECT rc = getdisplay (&currprefs)->rect; - currentmode->native_width = rc.right - rc.left; - currentmode->native_height = rc.bottom - rc.top; - currentmode->current_width = currentmode->native_width; - currentmode->current_height = currentmode->native_height; + mon->currentmode.native_width = rc.right - rc.left; + mon->currentmode.native_height = rc.bottom - rc.top; + mon->currentmode.current_width = mon->currentmode.native_width; + mon->currentmode.current_height = mon->currentmode.native_height; } else { - currentmode->native_width = currentmode->current_width; - currentmode->native_height = currentmode->current_height; + mon->currentmode.native_width = mon->currentmode.current_width; + mon->currentmode.native_height = mon->currentmode.current_height; } } -static void update_gfxparams (void) +static void update_gfxparams(struct AmigaMonitor *mon) { - updatewinfsmode (&currprefs); + struct picasso96_state_struct *state = &picasso96_state[mon->monitor_id]; + + updatewinfsmode(mon->monitor_id, &currprefs); #ifdef PICASSO96 - currentmode->vsync = 0; - if (screen_is_picasso) { - currentmode->current_width = (int)(picasso96_state.Width * currprefs.rtg_horiz_zoom_mult); - currentmode->current_height = (int)(picasso96_state.Height * currprefs.rtg_vert_zoom_mult); + mon->currentmode.vsync = 0; + if (mon->screen_is_picasso) { + mon->currentmode.current_width = (int)(state->Width * currprefs.rtg_horiz_zoom_mult); + mon->currentmode.current_height = (int)(state->Height * currprefs.rtg_vert_zoom_mult); currprefs.gfx_apmode[1].gfx_interlaced = false; if (currprefs.win32_rtgvblankrate == 0) { currprefs.gfx_apmode[1].gfx_refreshrate = currprefs.gfx_apmode[0].gfx_refreshrate; @@ -1800,185 +1904,184 @@ static void update_gfxparams (void) currprefs.gfx_apmode[1].gfx_refreshrate = currprefs.win32_rtgvblankrate; } if (currprefs.gfx_apmode[1].gfx_vsync) - currentmode->vsync = 1 + currprefs.gfx_apmode[1].gfx_vsyncmode; + mon->currentmode.vsync = 1 + currprefs.gfx_apmode[1].gfx_vsyncmode; } else { #endif - currentmode->current_width = currprefs.gfx_size.width; - currentmode->current_height = currprefs.gfx_size.height; + mon->currentmode.current_width = currprefs.gfx_monitor[mon->monitor_id].gfx_size.width; + mon->currentmode.current_height = currprefs.gfx_monitor[mon->monitor_id].gfx_size.height; if (currprefs.gfx_apmode[0].gfx_vsync) - currentmode->vsync = 1 + currprefs.gfx_apmode[0].gfx_vsyncmode; + mon->currentmode.vsync = 1 + currprefs.gfx_apmode[0].gfx_vsyncmode; #ifdef PICASSO96 } #endif #if FORCE16BIT - currentmode->current_depth = 16; + mon->currentmode.current_depth = 16; #else - currentmode->current_depth = currprefs.color_mode < 5 ? 16 : 32; + mon->currentmode.current_depth = currprefs.color_mode < 5 ? 16 : 32; #endif - if (screen_is_picasso && currprefs.win32_rtgmatchdepth && isfullscreen () > 0) { - int pbits = picasso96_state.BytesPerPixel * 8; + if (mon->screen_is_picasso && currprefs.win32_rtgmatchdepth && isfullscreen () > 0) { + int pbits = state->BytesPerPixel * 8; if (pbits <= 8) { - if (currentmode->current_depth == 32) + if (mon->currentmode.current_depth == 32) pbits = 32; else pbits = 16; } if (pbits == 24) pbits = 32; - currentmode->current_depth = pbits; + mon->currentmode.current_depth = pbits; } - currentmode->amiga_width = currentmode->current_width; - currentmode->amiga_height = currentmode->current_height; + mon->currentmode.amiga_width = mon->currentmode.current_width; + mon->currentmode.amiga_height = mon->currentmode.current_height; - scalepicasso = 0; - if (screen_is_picasso) { + mon->scalepicasso = 0; + if (mon->screen_is_picasso) { if (isfullscreen () < 0) { - if ((currprefs.gf[1].gfx_filter_autoscale == RTG_MODE_CENTER || currprefs.gf[1].gfx_filter_autoscale == RTG_MODE_SCALE || currprefs.win32_rtgallowscaling) && (picasso96_state.Width != currentmode->native_width || picasso96_state.Height != currentmode->native_height)) - scalepicasso = 1; + if ((currprefs.gf[1].gfx_filter_autoscale == RTG_MODE_CENTER || currprefs.gf[1].gfx_filter_autoscale == RTG_MODE_SCALE || currprefs.win32_rtgallowscaling) && (state->Width != mon->currentmode.native_width || state->Height != mon->currentmode.native_height)) + mon->scalepicasso = 1; if (currprefs.gf[1].gfx_filter_autoscale == RTG_MODE_CENTER) - scalepicasso = currprefs.gf[1].gfx_filter_autoscale; - if (!scalepicasso && currprefs.win32_rtgscaleaspectratio) - scalepicasso = -1; + mon->scalepicasso = currprefs.gf[1].gfx_filter_autoscale; + if (!mon->scalepicasso && currprefs.win32_rtgscaleaspectratio) + mon->scalepicasso = -1; } else if (isfullscreen () > 0) { if (!currprefs.win32_rtgmatchdepth) { // can't scale to different color depth - if (currentmode->native_width > picasso96_state.Width && currentmode->native_height > picasso96_state.Height) { + if (mon->currentmode.native_width > state->Width && mon->currentmode.native_height > state->Height) { if (currprefs.gf[1].gfx_filter_autoscale) - scalepicasso = 1; + mon->scalepicasso = 1; } if (currprefs.gf[1].gfx_filter_autoscale == RTG_MODE_CENTER) - scalepicasso = currprefs.gf[1].gfx_filter_autoscale; - if (!scalepicasso && currprefs.win32_rtgscaleaspectratio) - scalepicasso = -1; + mon->scalepicasso = currprefs.gf[1].gfx_filter_autoscale; + if (!mon->scalepicasso && currprefs.win32_rtgscaleaspectratio) + mon->scalepicasso = -1; } } else if (isfullscreen () == 0) { if (currprefs.gf[1].gfx_filter_autoscale == RTG_MODE_INTEGER_SCALE) { - scalepicasso = RTG_MODE_INTEGER_SCALE; - currentmode->current_width = currprefs.gfx_size.width; - currentmode->current_height = currprefs.gfx_size.height; + mon->scalepicasso = RTG_MODE_INTEGER_SCALE; + mon->currentmode.current_width = currprefs.gfx_monitor[mon->monitor_id].gfx_size.width; + mon->currentmode.current_height = currprefs.gfx_monitor[mon->monitor_id].gfx_size.height; } else if (currprefs.gf[1].gfx_filter_autoscale == RTG_MODE_CENTER) { - if (currprefs.gfx_size.width < picasso96_state.Width || currprefs.gfx_size.height < picasso96_state.Height) { + if (currprefs.gfx_monitor[mon->monitor_id].gfx_size.width < state->Width || currprefs.gfx_monitor[mon->monitor_id].gfx_size.height < state->Height) { if (!currprefs.win32_rtgallowscaling) { ; } else if (currprefs.win32_rtgscaleaspectratio) { - scalepicasso = -1; - currentmode->current_width = currprefs.gfx_size.width; - currentmode->current_height = currprefs.gfx_size.height; + mon->scalepicasso = -1; + mon->currentmode.current_width = currprefs.gfx_monitor[mon->monitor_id].gfx_size.width; + mon->currentmode.current_height = currprefs.gfx_monitor[mon->monitor_id].gfx_size.height; } } else { - scalepicasso = 2; - currentmode->current_width = currprefs.gfx_size.width; - currentmode->current_height = currprefs.gfx_size.height; + mon->scalepicasso = 2; + mon->currentmode.current_width = currprefs.gfx_monitor[mon->monitor_id].gfx_size.width; + mon->currentmode.current_height = currprefs.gfx_monitor[mon->monitor_id].gfx_size.height; } } else if (currprefs.gf[1].gfx_filter_autoscale == RTG_MODE_SCALE) { - if (currprefs.gfx_size.width > picasso96_state.Width || currprefs.gfx_size.height > picasso96_state.Height) - scalepicasso = 1; - if ((currprefs.gfx_size.width != picasso96_state.Width || currprefs.gfx_size.height != picasso96_state.Height) && currprefs.win32_rtgallowscaling) { - scalepicasso = 1; - } else if (currprefs.gfx_size.width < picasso96_state.Width || currprefs.gfx_size.height < picasso96_state.Height) { + if (currprefs.gfx_monitor[mon->monitor_id].gfx_size.width > state->Width || currprefs.gfx_monitor[mon->monitor_id].gfx_size.height > state->Height) + mon->scalepicasso = 1; + if ((currprefs.gfx_monitor[mon->monitor_id].gfx_size.width != state->Width || currprefs.gfx_monitor[mon->monitor_id].gfx_size.height != state->Height) && currprefs.win32_rtgallowscaling) { + mon->scalepicasso = 1; + } else if (currprefs.gfx_monitor[mon->monitor_id].gfx_size.width < state->Width || currprefs.gfx_monitor[mon->monitor_id].gfx_size.height < state->Height) { // no always scaling and smaller? Back to normal size and set new configured max size - currentmode->current_width = changed_prefs.gfx_size_win.width = picasso96_state.Width; - currentmode->current_height = changed_prefs.gfx_size_win.height = picasso96_state.Height; - } else if (currprefs.gfx_size.width == picasso96_state.Width || currprefs.gfx_size.height == picasso96_state.Height) { + mon->currentmode.current_width = changed_prefs.gfx_monitor[mon->monitor_id].gfx_size_win.width = state->Width; + mon->currentmode.current_height = changed_prefs.gfx_monitor[mon->monitor_id].gfx_size_win.height = state->Height; + } else if (currprefs.gfx_monitor[mon->monitor_id].gfx_size.width == state->Width || currprefs.gfx_monitor[mon->monitor_id].gfx_size.height == state->Height) { ; - } else if (!scalepicasso && currprefs.win32_rtgscaleaspectratio) { - scalepicasso = -1; + } else if (!mon->scalepicasso && currprefs.win32_rtgscaleaspectratio) { + mon->scalepicasso = -1; } } else { - if ((currprefs.gfx_size.width != picasso96_state.Width || currprefs.gfx_size.height != picasso96_state.Height) && currprefs.win32_rtgallowscaling) - scalepicasso = 1; - if (!scalepicasso && currprefs.win32_rtgscaleaspectratio) - scalepicasso = -1; + if ((currprefs.gfx_monitor[mon->monitor_id].gfx_size.width != state->Width || currprefs.gfx_monitor[mon->monitor_id].gfx_size.height != state->Height) && currprefs.win32_rtgallowscaling) + mon->scalepicasso = 1; + if (!mon->scalepicasso && currprefs.win32_rtgscaleaspectratio) + mon->scalepicasso = -1; } } - if (scalepicasso > 0 && (currprefs.gfx_size.width != picasso96_state.Width || currprefs.gfx_size.height != picasso96_state.Height)) { - currentmode->current_width = currprefs.gfx_size.width; - currentmode->current_height = currprefs.gfx_size.height; + if (mon->scalepicasso > 0 && (currprefs.gfx_monitor[mon->monitor_id].gfx_size.width != state->Width || currprefs.gfx_monitor[mon->monitor_id].gfx_size.height != state->Height)) { + mon->currentmode.current_width = currprefs.gfx_monitor[mon->monitor_id].gfx_size.width; + mon->currentmode.current_height = currprefs.gfx_monitor[mon->monitor_id].gfx_size.height; } } } -static int open_windows (bool mousecapture) +static int open_windows(struct AmigaMonitor *mon, bool mousecapture, bool started) { - static bool started = false; - int ret, i; + bool recapture = false; + int ret; - changevblankthreadmode (VBLANKTH_IDLE); + mon->screen_is_initialized = 0; - screen_is_initialized = 0; - inputdevice_unacquire (); - reset_sound (); - if (hAmigaWnd == NULL) + if (mon->monitor_id && mouseactive) + recapture = true; + + inputdevice_unacquire(); + reset_sound(); + if (mon->hAmigaWnd == NULL) wait_keyrelease(); - in_sizemove = 0; + mon->in_sizemove = 0; - updatewinfsmode (&currprefs); + updatewinfsmode(mon->monitor_id, &currprefs); #ifdef D3D gfx_lock(); - D3D_free (false); + D3D_free(mon->monitor_id, false); gfx_unlock(); #endif -#ifdef OPENGL - OGL_free (); -#endif - if (!DirectDraw_Start ()) + if (!DirectDraw_Start()) return 0; - init_round = 0; + int init_round = 0; ret = -2; do { if (ret < -1) { - updatemodes (); - update_gfxparams (); + updatemodes(mon); + update_gfxparams(mon); } - ret = doInit (); + ret = doInit(mon); init_round++; if (ret < -9) { - DirectDraw_Release (); - if (!DirectDraw_Start ()) + DirectDraw_Release(); + if (!DirectDraw_Start()) return 0; } } while (ret < 0); if (!ret) { - DirectDraw_Release (); + DirectDraw_Release(); return ret; } bool startactive = (started && mouseactive) || (!started && !currprefs.win32_start_uncaptured && !currprefs.win32_start_minimized); - bool startpaused = !started && ((currprefs.win32_start_minimized && currprefs.win32_iconified_pause) || (currprefs.win32_start_uncaptured && currprefs.win32_inactive_pause && isfullscreen () <= 0)); - bool startminimized = !started && currprefs.win32_start_minimized && isfullscreen () <= 0; + bool startpaused = !started && ((currprefs.win32_start_minimized && currprefs.win32_iconified_pause) || (currprefs.win32_start_uncaptured && currprefs.win32_inactive_pause && isfullscreen() <= 0)); + bool startminimized = !started && currprefs.win32_start_minimized && isfullscreen() <= 0; int input = 0; - if (mousecapture && startactive) - setmouseactive (-1); + if ((mousecapture && startactive) || recapture) + setmouseactive(mon->monitor_id, -1); int upd = 0; if (startactive) { - setpriority (&priorities[currprefs.win32_active_capture_priority]); + setpriority(&priorities[currprefs.win32_active_capture_priority]); upd = 2; } else if (startminimized) { - setpriority (&priorities[currprefs.win32_iconified_priority]); - setminimized (); + setpriority(&priorities[currprefs.win32_iconified_priority]); + setminimized(mon->monitor_id); input = currprefs.win32_inactive_input; upd = 1; } else { - setpriority (&priorities[currprefs.win32_inactive_priority]); + setpriority(&priorities[currprefs.win32_inactive_priority]); input = currprefs.win32_inactive_input; upd = 2; } if (upd > 1) { - for (i = 0; i < NUM_LEDS; i++) - gui_flicker_led (i, -1, -1); - gui_led (LED_POWER, gui_data.powerled, gui_data.powerled_brightness); - gui_fps (0, 0, 0); + for (int i = 0; i < NUM_LEDS; i++) + gui_flicker_led(i, -1, -1); + gui_led(LED_POWER, gui_data.powerled, gui_data.powerled_brightness); + gui_fps(0, 0, 0); if (gui_data.md >= 0) - gui_led (LED_MD, 0, -1); - for (i = 0; i < 4; i++) { + gui_led(LED_MD, 0, -1); + for (int i = 0; i < 4; i++) { if (currprefs.floppyslots[i].dfxtype >= 0) - gui_led (LED_DF0 + i, 0, -1); + gui_led(LED_DF0 + i, 0, -1); } } if (upd > 0) { @@ -1988,27 +2091,26 @@ static int open_windows (bool mousecapture) } if (startpaused) - setpaused (1); + setpaused(1); - statusline_updated(); + statusline_updated(mon->monitor_id); + refreshtitle(); - started = true; return ret; } -static void reopen_gfx (void) +static void reopen_gfx(struct AmigaMonitor *mon) { - open_windows (false); - - if (isvsync () < 0) - vblank_calibrate (0, false); - + open_windows(mon, false, true); if (isfullscreen () <= 0) DirectDraw_FillPrimary (); + render_screen(mon->monitor_id, 1, true); } -static int getstatuswindowheight (void) +static int getstatuswindowheight(int monid) { + if (monid > 0) + return 0; int def = GetSystemMetrics (SM_CYMENU) + 3; WINDOWINFO wi; HWND h = CreateWindowEx ( @@ -2045,15 +2147,27 @@ void WIN32GFX_DisplayChangeRequested (int mode) int check_prefs_changed_gfx (void) { int c = 0; + bool monitors[MAX_AMIGAMONITORS]; if (!config_changed && !display_change_requested) return 0; c |= currprefs.win32_statusbar != changed_prefs.win32_statusbar ? 512 : 0; - c |= currprefs.gfx_size_fs.width != changed_prefs.gfx_size_fs.width ? 16 : 0; - c |= currprefs.gfx_size_fs.height != changed_prefs.gfx_size_fs.height ? 16 : 0; - c |= ((currprefs.gfx_size_win.width + 7) & ~7) != ((changed_prefs.gfx_size_win.width + 7) & ~7) ? 16 : 0; - c |= currprefs.gfx_size_win.height != changed_prefs.gfx_size_win.height ? 16 : 0; + + for (int i = 0; i < MAX_AMIGADISPLAYS; i++) { + monitors[i] = false; + int c2 = 0; + c2 |= currprefs.gfx_monitor[i].gfx_size_fs.width != changed_prefs.gfx_monitor[i].gfx_size_fs.width ? 16 : 0; + c2 |= currprefs.gfx_monitor[i].gfx_size_fs.height != changed_prefs.gfx_monitor[i].gfx_size_fs.height ? 16 : 0; + c2 |= ((currprefs.gfx_monitor[i].gfx_size_win.width + 7) & ~7) != ((changed_prefs.gfx_monitor[i].gfx_size_win.width + 7) & ~7) ? 16 : 0; + c2 |= currprefs.gfx_monitor[i].gfx_size_win.height != changed_prefs.gfx_monitor[i].gfx_size_win.height ? 16 : 0; + if (c2) { + c |= c2; + monitors[i] = true; + } + } + monitors[0] = true; + #if 0 c |= currprefs.gfx_size_win.x != changed_prefs.gfx_size_win.x ? 16 : 0; c |= currprefs.gfx_size_win.y != changed_prefs.gfx_size_win.y ? 16 : 0; @@ -2141,6 +2255,9 @@ int check_prefs_changed_gfx (void) c |= currprefs.gfx_threebitcolors != changed_prefs.gfx_threebitcolors ? (256) : 0; c |= currprefs.gfx_grayscale != changed_prefs.gfx_grayscale ? (512) : 0; + c |= currprefs.gfx_display_sections != changed_prefs.gfx_display_sections ? (512) : 0; + c |= currprefs.gfx_variable_sync != changed_prefs.gfx_variable_sync ? 1 : 0; + c |= currprefs.gfx_apmode[APMODE_NATIVE].gfx_display != changed_prefs.gfx_apmode[APMODE_NATIVE].gfx_display ? (2|4|8) : 0; c |= currprefs.gfx_apmode[APMODE_RTG].gfx_display != changed_prefs.gfx_apmode[APMODE_RTG].gfx_display ? (2|4|8) : 0; c |= currprefs.gfx_blackerthanblack != changed_prefs.gfx_blackerthanblack ? (2 | 8) : 0; @@ -2237,6 +2354,10 @@ int check_prefs_changed_gfx (void) currprefs.gfx_scandoubler = changed_prefs.gfx_scandoubler; currprefs.gfx_threebitcolors = changed_prefs.gfx_threebitcolors; currprefs.gfx_grayscale = changed_prefs.gfx_grayscale; + + currprefs.gfx_display_sections = changed_prefs.gfx_display_sections; + currprefs.gfx_variable_sync = changed_prefs.gfx_variable_sync; + currprefs.gfx_apmode[APMODE_NATIVE].gfx_display = changed_prefs.gfx_apmode[APMODE_NATIVE].gfx_display; currprefs.gfx_apmode[APMODE_RTG].gfx_display = changed_prefs.gfx_apmode[APMODE_RTG].gfx_display; currprefs.gfx_blackerthanblack = changed_prefs.gfx_blackerthanblack; @@ -2258,74 +2379,78 @@ int check_prefs_changed_gfx (void) currprefs.win32_rtgvblankrate = changed_prefs.win32_rtgvblankrate; bool unacquired = false; - if (c & 64) { - if (!unacquired) { - inputdevice_unacquire (); - unacquired = true; + for (int monid = MAX_AMIGAMONITORS - 1; monid >= 0; monid--) { + if (!monitors[monid]) + continue; + struct AmigaMonitor *mon = &AMonitors[monid]; + + if (c & 64) { + if (!unacquired) { + inputdevice_unacquire(); + unacquired = true; + } + DirectDraw_Fill(NULL, 0); + DirectDraw_BlitToPrimary(NULL); } - DirectDraw_Fill (NULL, 0); - DirectDraw_BlitToPrimary (NULL); - } - if (c & 256) { - init_colors (); - reset_drawing (); - } - if (c & 128) { - if (currprefs.gfx_autoresolution) { - c |= 2 | 8; - } else { - c |= 16; - reset_drawing (); - S2X_reset (); + if (c & 256) { + init_colors(mon->monitor_id); + reset_drawing(); } - } - if (c & 1024) { - target_graphics_buffer_update(); - } - if (c & 512) { - reopen_gfx (); - graphics_mode_changed = 1; - } - if ((c & 16) || ((c & 8) && keepfsmode)) { - if (reopen (c & 2, unacquired == false)) { - c |= 2; - } else { - unacquired = true; + if (c & 128) { + if (currprefs.gfx_autoresolution) { + c |= 2 | 8; + } else { + c |= 16; + reset_drawing(); + S2X_reset(mon->monitor_id); + } } - graphics_mode_changed = 1; - } - if ((c & 32) || ((c & 2) && !keepfsmode)) { - if (!unacquired) { - inputdevice_unacquire (); - unacquired = true; + if (c & 1024) { + target_graphics_buffer_update(mon->monitor_id); } - close_windows (); - if (currprefs.gfx_api != changed_prefs.gfx_api || currprefs.gfx_api_options != changed_prefs.gfx_api_options) { - currprefs.gfx_api = changed_prefs.gfx_api; - currprefs.gfx_api_options = changed_prefs.gfx_api_options; - d3d_select(&currprefs); + if (c & 512) { + reopen_gfx(mon); + } + if ((c & 16) || ((c & 8) && keepfsmode)) { + if (reopen(mon, c & 2, unacquired == false)) { + c |= 2; + } else { + unacquired = true; + } + } + if ((c & 32) || ((c & 2) && !keepfsmode)) { + if (!unacquired) { + inputdevice_unacquire(); + unacquired = true; + } + close_windows(mon); + if (currprefs.gfx_api != changed_prefs.gfx_api || currprefs.gfx_api_options != changed_prefs.gfx_api_options) { + currprefs.gfx_api = changed_prefs.gfx_api; + currprefs.gfx_api_options = changed_prefs.gfx_api_options; + d3d_select(&currprefs); + } + graphics_init(dontcapture ? false : true); } - graphics_init (dontcapture ? false : true); - graphics_mode_changed = 1; } - init_custom (); + + init_custom(); if (c & 4) { - pause_sound (); - reset_sound (); - resume_sound (); + pause_sound(); + reset_sound(); + resume_sound(); } - + if (setpause || dontcapture) { if (!unacquired) - inputdevice_unacquire (); + inputdevice_unacquire(); unacquired = false; } if (unacquired) - inputdevice_acquire (TRUE); - + inputdevice_acquire(TRUE); + if (setpause) - setpaused (1); + setpaused(1); return 1; } @@ -2500,11 +2625,12 @@ static int red_bits, green_bits, blue_bits, alpha_bits; static int red_shift, green_shift, blue_shift, alpha_shift; static int alpha; -void init_colors (void) +void init_colors(int monid) { + struct AmigaMonitor *mon = &AMonitors[monid]; /* init colors */ - if (currentmode->flags & DM_D3D) { - D3D_getpixelformat (currentmode->current_depth, + if (mon->currentmode.flags & DM_D3D) { + D3D_getpixelformat (mon->currentmode.current_depth, &red_bits, &green_bits, &blue_bits, &red_shift, &green_shift, &blue_shift, &alpha_bits, &alpha_shift, &alpha); } else { red_bits = bits_in_mask (DirectDraw_GetPixelFormatBitMask (red_mask)); @@ -2517,9 +2643,9 @@ void init_colors (void) alpha_shift = 0; } - if (!(currentmode->flags & (DM_D3D))) { - if (currentmode->current_depth != currentmode->native_depth) { - if (currentmode->current_depth == 16) { + if (!(mon->currentmode.flags & (DM_D3D))) { + if (mon->currentmode.current_depth != mon->currentmode.native_depth) { + if (mon->currentmode.current_depth == 16) { red_bits = 5; green_bits = 6; blue_bits = 5; red_shift = 11; green_shift = 5; blue_shift = 0; } else { @@ -2528,10 +2654,10 @@ void init_colors (void) } } } - alloc_colors64k (red_bits, green_bits, blue_bits, red_shift,green_shift, blue_shift, alpha_bits, alpha_shift, alpha, 0); + alloc_colors64k(monid, red_bits, green_bits, blue_bits, red_shift,green_shift, blue_shift, alpha_bits, alpha_shift, alpha, 0, mon->usedfilter && mon->usedfilter->yuv); notice_new_xcolors (); #ifdef GFXFILTER - S2X_configure (red_bits, green_bits, blue_bits, red_shift,green_shift, blue_shift); + S2X_configure(monid, red_bits, green_bits, blue_bits, red_shift,green_shift, blue_shift); #endif #ifdef AVIOUTPUT AVIOutput_RGBinfo (red_bits, green_bits, blue_bits, alpha_bits, red_shift, green_shift, blue_shift, alpha_shift); @@ -2541,8 +2667,9 @@ void init_colors (void) #ifdef PICASSO96 -int picasso_palette (struct MyCLUTEntry *CLUT) +int picasso_palette(int monid, struct MyCLUTEntry *CLUT) { + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; int i, changed; changed = 0; @@ -2554,63 +2681,65 @@ int picasso_palette (struct MyCLUTEntry *CLUT) | doMask256 (g, green_bits, green_shift) | doMask256 (b, blue_bits, blue_shift)) | doMask256 (0xff, alpha_bits, alpha_shift); - if (v != picasso_vidinfo.clut[i]) { + if (v != vidinfo->clut[i]) { //write_log (_T("%d:%08x\n"), i, v); - picasso_vidinfo.clut[i] = v; + vidinfo->clut[i] = v; changed = 1; } } return changed; } -void DX_Invalidate (int x, int y, int width, int height) +void DX_Invalidate(struct AmigaMonitor *mon, int x, int y, int width, int height) { + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[mon->monitor_id]; int last, lastx; if (width == 0 || height == 0) return; if (y < 0 || height < 0) { y = 0; - height = picasso_vidinfo.height; + height = vidinfo->height; } if (x < 0 || width < 0) { x = 0; - width = picasso_vidinfo.width; + width = vidinfo->width; } last = y + height - 1; lastx = x + width - 1; - p96_double_buffer_first = y; - p96_double_buffer_last = last; - p96_double_buffer_firstx = x; - p96_double_buffer_lastx = lastx; - p96_double_buffer_needs_flushing = 1; + mon->p96_double_buffer_first = y; + mon->p96_double_buffer_last = last; + mon->p96_double_buffer_firstx = x; + mon->p96_double_buffer_lastx = lastx; + mon->p96_double_buffer_needs_flushing = 1; } #endif -static void open_screen (void) +static void open_screen(struct AmigaMonitor *mon) { - close_windows (); - open_windows (true); + close_windows(mon); + open_windows(mon, true, true); } -static int ifs (struct uae_prefs *p) +static int ifs(struct AmigaMonitor *mon, struct uae_prefs *p) { - int idx = screen_is_picasso ? 1 : 0; + int idx = mon->screen_is_picasso ? 1 : 0; return p->gfx_apmode[idx].gfx_fullscreen == GFX_FULLSCREEN ? 1 : (p->gfx_apmode[idx].gfx_fullscreen == GFX_FULLWINDOW ? -1 : 0); } -static int reopen (int full, bool unacquire) +static int reopen(struct AmigaMonitor *mon, int full, bool unacquire) { + struct amigadisplay *ad = &adisplays[mon->monitor_id]; int quick = 0; - int idx = screen_is_picasso ? 1 : 0; - struct apmode *ap = picasso_on ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0]; + int idx = mon->screen_is_picasso ? 1 : 0; + struct apmode *ap = ad->picasso_on ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0]; - updatewinfsmode (&changed_prefs); + updatewinfsmode(mon->monitor_id, &changed_prefs); - if (changed_prefs.gfx_apmode[0].gfx_fullscreen != currprefs.gfx_apmode[0].gfx_fullscreen && !screen_is_picasso) + if (changed_prefs.gfx_apmode[0].gfx_fullscreen != currprefs.gfx_apmode[0].gfx_fullscreen && !mon->screen_is_picasso) full = 1; - if (changed_prefs.gfx_apmode[1].gfx_fullscreen != currprefs.gfx_apmode[1].gfx_fullscreen && screen_is_picasso) + if (changed_prefs.gfx_apmode[1].gfx_fullscreen != currprefs.gfx_apmode[1].gfx_fullscreen && mon->screen_is_picasso) full = 1; /* fullscreen to fullscreen? */ @@ -2624,12 +2753,12 @@ static int reopen (int full, bool unacquire) quick = 1; } - currprefs.gfx_size_fs.width = changed_prefs.gfx_size_fs.width; - currprefs.gfx_size_fs.height = changed_prefs.gfx_size_fs.height; - currprefs.gfx_size_win.width = changed_prefs.gfx_size_win.width; - currprefs.gfx_size_win.height = changed_prefs.gfx_size_win.height; - currprefs.gfx_size_win.x = changed_prefs.gfx_size_win.x; - currprefs.gfx_size_win.y = changed_prefs.gfx_size_win.y; + currprefs.gfx_monitor[mon->monitor_id].gfx_size_fs.width = changed_prefs.gfx_monitor[mon->monitor_id].gfx_size_fs.width; + currprefs.gfx_monitor[mon->monitor_id].gfx_size_fs.height = changed_prefs.gfx_monitor[mon->monitor_id].gfx_size_fs.height; + currprefs.gfx_monitor[mon->monitor_id].gfx_size_win.width = changed_prefs.gfx_monitor[mon->monitor_id].gfx_size_win.width; + currprefs.gfx_monitor[mon->monitor_id].gfx_size_win.height = changed_prefs.gfx_monitor[mon->monitor_id].gfx_size_win.height; + currprefs.gfx_monitor[mon->monitor_id].gfx_size_win.x = changed_prefs.gfx_monitor[mon->monitor_id].gfx_size_win.x; + currprefs.gfx_monitor[mon->monitor_id].gfx_size_win.y = changed_prefs.gfx_monitor[mon->monitor_id].gfx_size_win.y; currprefs.gfx_apmode[0].gfx_fullscreen = changed_prefs.gfx_apmode[0].gfx_fullscreen; currprefs.gfx_apmode[1].gfx_fullscreen = changed_prefs.gfx_apmode[1].gfx_fullscreen; @@ -2654,18 +2783,19 @@ static int reopen (int full, bool unacquire) inputdevice_unacquire (); } - reopen_gfx (); + reopen_gfx(mon); return 0; } -bool vsync_switchmode (int hz) +bool vsync_switchmode(int monid, int hz) { + struct AmigaMonitor *mon = &AMonitors[monid]; static struct PicassoResolution *oldmode; static int oldhz; - int w = currentmode->native_width; - int h = currentmode->native_height; - int d = currentmode->native_depth / 8; + int w = mon->currentmode.native_width; + int h = mon->currentmode.native_height; + int d = mon->currentmode.native_depth / 8; struct MultiDisplay *md = getdisplay (&currprefs); struct PicassoResolution *found; int newh, i, cnt; @@ -2744,10 +2874,10 @@ bool vsync_switchmode (int hz) return false; } else { newh = found->res.height; - changed_prefs.gfx_size_fs.height = newh; + changed_prefs.gfx_monitor[mon->monitor_id].gfx_size_fs.height = newh; changed_prefs.gfx_apmode[APMODE_NATIVE].gfx_refreshrate = hz; changed_prefs.gfx_apmode[APMODE_NATIVE].gfx_interlaced = lace; - if (changed_prefs.gfx_size_fs.height != currprefs.gfx_size_fs.height || + if (changed_prefs.gfx_monitor[mon->monitor_id].gfx_size_fs.height != currprefs.gfx_monitor[mon->monitor_id].gfx_size_fs.height || changed_prefs.gfx_apmode[APMODE_NATIVE].gfx_refreshrate != currprefs.gfx_apmode[APMODE_NATIVE].gfx_refreshrate) { write_log (_T("refresh rate changed to %d%s, new screenmode %dx%d\n"), hz, lace ? _T("i") : _T("p"), w, newh); set_config_changed (); @@ -2756,36 +2886,54 @@ bool vsync_switchmode (int hz) } } +void vsync_clear(void) +{ + vsync_active = false; + ResetEvent(waitvblankevent); +} + +int vsync_isdone(frame_time_t *dt) +{ + if (isvsync() == 0) + return -1; + if (dt) + *dt = wait_vblank_timestamp; + return vsync_active ? 1 : 0; +} + #ifdef PICASSO96 -static int modeswitchneeded (struct winuae_currentmode *wc) +static int modeswitchneeded(struct AmigaMonitor *mon, struct winuae_currentmode *wc) { + struct vidbuf_description *avidinfo = &adisplays[mon->monitor_id].gfxvidinfo; + struct picasso96_state_struct *state = &picasso96_state[mon->monitor_id]; + if (isfullscreen () > 0) { /* fullscreen to fullscreen */ - if (screen_is_picasso) { - if (picasso96_state.BytesPerPixel > 1 && picasso96_state.BytesPerPixel * 8 != wc->current_depth && currprefs.win32_rtgmatchdepth) + if (mon->screen_is_picasso) { + if (state->BytesPerPixel > 1 && state->BytesPerPixel * 8 != wc->current_depth && currprefs.win32_rtgmatchdepth) return -1; - if (picasso96_state.Width < wc->current_width && picasso96_state.Height < wc->current_height) { + if (state->Width < wc->current_width && state->Height < wc->current_height) { if ((currprefs.gf[1].gfx_filter_autoscale == 1 || (currprefs.gf[1].gfx_filter_autoscale == 2 && currprefs.win32_rtgallowscaling)) && !currprefs.win32_rtgmatchdepth) return 0; } - if (picasso96_state.Width != wc->current_width || - picasso96_state.Height != wc->current_height) + if (state->Width != wc->current_width || + state->Height != wc->current_height) return 1; - if (picasso96_state.Width == wc->current_width && - picasso96_state.Height == wc->current_height) { - if (picasso96_state.BytesPerPixel * 8 == wc->current_depth || picasso96_state.BytesPerPixel == 1) + if (state->Width == wc->current_width && + state->Height == wc->current_height) { + if (state->BytesPerPixel * 8 == wc->current_depth || state->BytesPerPixel == 1) return 0; if (!currprefs.win32_rtgmatchdepth) return 0; } return 1; } else { - if (currentmode->current_width != wc->current_width || - currentmode->current_height != wc->current_height || - currentmode->current_depth != wc->current_depth) + if (mon->currentmode.current_width != wc->current_width || + mon->currentmode.current_height != wc->current_height || + mon->currentmode.current_depth != wc->current_depth) return -1; - if (!gfxvidinfo.outbuffer->bufmem_lockable) + if (!avidinfo->outbuffer->bufmem_lockable) return -1; } } else if (isfullscreen () == 0) { @@ -2795,13 +2943,13 @@ static int modeswitchneeded (struct winuae_currentmode *wc) /* fullwindow to fullwindow */ DirectDraw_Fill (NULL, 0); DirectDraw_BlitToPrimary (NULL); - if (screen_is_picasso) { - if (currprefs.gf[1].gfx_filter_autoscale && ((wc->native_width > picasso96_state.Width && wc->native_height >= picasso96_state.Height) || (wc->native_height > picasso96_state.Height && wc->native_width >= picasso96_state.Width))) + if (mon->screen_is_picasso) { + if (currprefs.gf[1].gfx_filter_autoscale && ((wc->native_width > state->Width && wc->native_height >= state->Height) || (wc->native_height > state->Height && wc->native_width >= state->Width))) return -1; - if (currprefs.win32_rtgallowscaling && (picasso96_state.Width != wc->native_width || picasso96_state.Height != wc->native_height)) + if (currprefs.win32_rtgallowscaling && (state->Width != wc->native_width || state->Height != wc->native_height)) return -1; #if 0 - if (wc->native_width < picasso96_state.Width || wc->native_height < picasso96_state.Height) + if (wc->native_width < state->Width || wc->native_height < state->Height) return 1; #endif } @@ -2810,18 +2958,19 @@ static int modeswitchneeded (struct winuae_currentmode *wc) return 0; } -void gfx_set_picasso_state (int on) +void gfx_set_picasso_state(int monid, int on) { + struct AmigaMonitor *mon = &AMonitors[monid]; struct winuae_currentmode wc; struct apmode *newmode, *oldmode; struct gfx_filterdata *newf, *oldf; int mode; - if (screen_is_picasso == on) + if (mon->screen_is_picasso == on) return; - screen_is_picasso = on; + mon->screen_is_picasso = on; rp_rtg_switch (); - memcpy (&wc, currentmode, sizeof (wc)); + memcpy (&wc, &mon->currentmode, sizeof (wc)); newmode = &currprefs.gfx_apmode[on ? 1 : 0]; oldmode = &currprefs.gfx_apmode[on ? 0 : 1]; @@ -2829,9 +2978,9 @@ void gfx_set_picasso_state (int on) newf = &currprefs.gf[on ? 1 : 0]; oldf = &currprefs.gf[on ? 0 : 1]; - updatemodes (); - update_gfxparams (); - clearscreen (); + updatemodes(mon); + update_gfxparams(mon); + clearscreen(); // if filter changes, need to reset mode = 0; @@ -2855,7 +3004,7 @@ void gfx_set_picasso_state (int on) mode = 1; } if (mode <= 0) { - int m = modeswitchneeded (&wc); + int m = modeswitchneeded(mon, &wc); if (m > 0) mode = m; if (m < 0 && !mode) @@ -2864,53 +3013,55 @@ void gfx_set_picasso_state (int on) goto end; } if (mode < 0) { - open_windows (true); + open_windows(mon, true, true); } else { - open_screen (); // reopen everything + open_screen(mon); // reopen everything } - if (on && isvsync_rtg () < 0) - vblank_calibrate (0, false); end: #ifdef RETROPLATFORM - rp_set_hwnd (hAmigaWnd); + rp_set_hwnd (mon->hAmigaWnd); #endif } -void gfx_set_picasso_modeinfo (RGBFTYPE rgbfmt) +void gfx_set_picasso_modeinfo(int monid, RGBFTYPE rgbfmt) { + struct AmigaMonitor *mon = &AMonitors[monid]; int need; - if (!screen_is_picasso) + if (!mon->screen_is_picasso) return; - clearscreen (); - gfx_set_picasso_colors (rgbfmt); - updatemodes (); - need = modeswitchneeded (currentmode); - update_gfxparams (); + clearscreen(); + gfx_set_picasso_colors(monid, rgbfmt); + updatemodes(mon); + need = modeswitchneeded(mon, &mon->currentmode); + update_gfxparams(mon); if (need > 0) { - open_screen (); + open_screen(mon); } else if (need < 0) { - open_windows (true); + open_windows(mon, true, true); } #ifdef RETROPLATFORM - rp_set_hwnd (hAmigaWnd); + rp_set_hwnd(mon->hAmigaWnd); #endif } #endif -void gfx_set_picasso_colors (RGBFTYPE rgbfmt) +void gfx_set_picasso_colors(int monid, RGBFTYPE rgbfmt) { - alloc_colors_picasso (red_bits, green_bits, blue_bits, red_shift, green_shift, blue_shift, rgbfmt); + alloc_colors_picasso(red_bits, green_bits, blue_bits, red_shift, green_shift, blue_shift, rgbfmt); } -static void gfxmode_reset (void) +static void gfxmode_reset(int monid) { + struct amigadisplay *ad = &adisplays[monid]; + struct uae_filter **usedfilter = &AMonitors[monid].usedfilter; + #ifdef GFXFILTER - usedfilter = 0; - if (currprefs.gf[picasso_on].gfx_filter > 0) { + *usedfilter = NULL; + if (currprefs.gf[ad->picasso_on].gfx_filter > 0) { int i = 0; while (uaefilters[i].name) { - if (uaefilters[i].type == currprefs.gf[picasso_on].gfx_filter) { - usedfilter = &uaefilters[i]; + if (uaefilters[i].type == currprefs.gf[ad->picasso_on].gfx_filter) { + *usedfilter = &uaefilters[i]; break; } i++; @@ -2919,12 +3070,17 @@ static void gfxmode_reset (void) #endif } -int machdep_init (void) +int machdep_init(void) { - picasso_requested_on = 0; - picasso_on = 0; - screen_is_picasso = 0; - memset (currentmode, 0, sizeof (*currentmode)); + for (int i = 0; i < MAX_AMIGAMONITORS; i++) { + struct AmigaMonitor *mon = &AMonitors[i]; + struct amigadisplay *ad = &adisplays[i]; + mon->monitor_id = i; + ad->picasso_requested_on = 0; + ad->picasso_on = 0; + mon->screen_is_picasso = 0; + memset(&mon->currentmode, 0, sizeof(*&mon->currentmode)); + } #ifdef LOGITECHLCD lcd_open (); #endif @@ -2932,44 +3088,52 @@ int machdep_init (void) return 1; } -void machdep_free (void) +void machdep_free(void) { #ifdef LOGITECHLCD lcd_close (); #endif } -int graphics_init (bool mousecapture) +int graphics_init(bool mousecapture) { systray (hHiddenWnd, TRUE); systray (hHiddenWnd, FALSE); d3d_select(&currprefs); - gfxmode_reset(); - graphics_mode_changed = 1; - return open_windows (mousecapture); + gfxmode_reset(0); + if (open_windows(&AMonitors[0], mousecapture, false)) { + if (currprefs.monitoremu_mon > 0 && currprefs.monitoremu) { + gfxmode_reset(currprefs.monitoremu_mon); + open_windows(&AMonitors[currprefs.monitoremu_mon], mousecapture, false); + } + return true; + } + return false; } -int graphics_setup (void) +int graphics_setup(void) { if (!screen_cs_allocated) { InitializeCriticalSection(&screen_cs); screen_cs_allocated = true; } #ifdef PICASSO96 - InitPicasso96 (); + InitPicasso96(0); #endif return 1; } -void graphics_leave (void) +void graphics_leave(void) { - changevblankthreadmode (VBLANKTH_KILL); - close_windows (); + for (int i = 0; i < MAX_AMIGAMONITORS; i++) { + close_windows(&AMonitors[i]); + } } uae_u32 OSDEP_minimize_uae (void) { - return ShowWindow (hAmigaWnd, SW_MINIMIZE); + struct AmigaMonitor *mon = &AMonitors[0]; + return ShowWindow(mon->hAmigaWnd, SW_MINIMIZE); } typedef HRESULT (CALLBACK* DWMENABLEMMCSS)(BOOL); @@ -2978,28 +3142,27 @@ static void setDwmEnableMMCSS (bool state) if (!os_vista) return; DWMENABLEMMCSS pDwmEnableMMCSS; - pDwmEnableMMCSS = (DWMENABLEMMCSS)GetProcAddress ( - GetModuleHandle (_T("dwmapi.dll")), "DwmEnableMMCSS"); + pDwmEnableMMCSS = (DWMENABLEMMCSS)GetProcAddress(GetModuleHandle(_T("dwmapi.dll")), "DwmEnableMMCSS"); if (pDwmEnableMMCSS) pDwmEnableMMCSS (state); } -void close_windows (void) +void close_windows(struct AmigaMonitor *mon) { - changevblankthreadmode (VBLANKTH_IDLE); - waitflipevent (); + struct vidbuf_description *avidinfo = &adisplays[mon->monitor_id].gfxvidinfo; + setDwmEnableMMCSS (FALSE); reset_sound (); #if defined (GFXFILTER) - S2X_free (); + S2X_free(mon->monitor_id); #endif - freevidbuffer (&gfxvidinfo.drawbuffer); - freevidbuffer (&gfxvidinfo.tempbuffer); - DirectDraw_Release (); - close_hwnds (); + freevidbuffer(mon->monitor_id, &avidinfo->drawbuffer); + freevidbuffer(mon->monitor_id, &avidinfo->tempbuffer); + DirectDraw_Release(); + close_hwnds(mon); } -static void createstatuswindow (void) +static void createstatuswindow(struct AmigaMonitor *mon) { HDC hdc; RECT rc; @@ -3013,30 +3176,30 @@ static void createstatuswindow (void) WINDOWINFO wi; int extra; - if (hStatusWnd) { - ShowWindow (hStatusWnd, SW_HIDE); - DestroyWindow (hStatusWnd); + if (mon->hStatusWnd) { + ShowWindow(mon->hStatusWnd, SW_HIDE); + DestroyWindow(mon->hStatusWnd); } - if (currprefs.win32_statusbar == 0) + if (currprefs.win32_statusbar == 0 || mon->monitor_id > 0) return; if (isfullscreen () != 0) return; if (currprefs.win32_borderless) return; - hStatusWnd = CreateWindowEx ( + mon->hStatusWnd = CreateWindowEx ( WS_EX_COMPOSITED, STATUSCLASSNAME, (LPCTSTR) NULL, SBARS_TOOLTIPS | WS_CHILD | WS_VISIBLE, - 0, 0, 0, 0, hMainWnd, (HMENU) 1, hInst, NULL); - if (!hStatusWnd) + 0, 0, 0, 0, mon->hMainWnd, (HMENU) 1, hInst, NULL); + if (!mon->hStatusWnd) return; wi.cbSize = sizeof wi; - GetWindowInfo (hMainWnd, &wi); + GetWindowInfo(mon->hMainWnd, &wi); extra = wi.rcClient.top - wi.rcWindow.top; - hdc = GetDC (hStatusWnd); - scaleX = GetDeviceCaps (hdc, LOGPIXELSX) / 96.0; - scaleY = GetDeviceCaps (hdc, LOGPIXELSY) / 96.0; - ReleaseDC (hStatusWnd, hdc); + hdc = GetDC(mon->hStatusWnd); + scaleX = GetDeviceCaps(hdc, LOGPIXELSX) / 96.0; + scaleY = GetDeviceCaps(hdc, LOGPIXELSY) / 96.0; + ReleaseDC(mon->hStatusWnd, hdc); drive_width = (int)(24 * scaleX); hd_width = (int)(24 * scaleX); cd_width = (int)(24 * scaleX); @@ -3050,7 +3213,7 @@ static void createstatuswindow (void) idle_width += (int)(68 * scaleX); snd_width = (int)(72 * scaleX); joy_width = (int)(24 * scaleX); - GetClientRect (hMainWnd, &rc); + GetClientRect(mon->hMainWnd, &rc); /* Allocate an array for holding the right edge coordinates. */ hloc = LocalAlloc (LHND, sizeof (int) * (num_parts + 1)); if (hloc) { @@ -3117,11 +3280,11 @@ static void createstatuswindow (void) window_led_drives_end = lpParts[i1 + 3 + 4]; /* Create the parts */ - SendMessage (hStatusWnd, SB_SETPARTS, (WPARAM)num_parts, (LPARAM)lpParts); - LocalUnlock (hloc); - LocalFree (hloc); + SendMessage(mon->hStatusWnd, SB_SETPARTS, (WPARAM)num_parts, (LPARAM)lpParts); + LocalUnlock(hloc); + LocalFree(hloc); } - registertouch(hStatusWnd); + registertouch(mon->hStatusWnd); } #if 0 @@ -3149,7 +3312,7 @@ static int createnotification (HWND hwnd) } #endif -static int getbestmode (int nextbest) +static int getbestmode(struct AmigaMonitor *mon, int nextbest) { int i, startidx; struct MultiDisplay *md; @@ -3160,16 +3323,16 @@ static int getbestmode (int nextbest) md = getdisplay2 (&currprefs, index); if (!md) return 0; - ratio = currentmode->native_width > currentmode->native_height ? 1 : 0; + ratio = mon->currentmode.native_width > mon->currentmode.native_height ? 1 : 0; for (i = 0; md->DisplayModes[i].depth >= 0; i++) { struct PicassoResolution *pr = &md->DisplayModes[i]; - if (pr->res.width == currentmode->native_width && pr->res.height == currentmode->native_height) + if (pr->res.width == mon->currentmode.native_width && pr->res.height == mon->currentmode.native_height) break; } if (md->DisplayModes[i].depth >= 0) { if (!nextbest) break; - while (md->DisplayModes[i].res.width == currentmode->native_width && md->DisplayModes[i].res.height == currentmode->native_height) + while (md->DisplayModes[i].res.width == mon->currentmode.native_width && md->DisplayModes[i].res.height == mon->currentmode.native_height) i++; } else { i = 0; @@ -3179,13 +3342,13 @@ static int getbestmode (int nextbest) for (; md->DisplayModes[i].depth >= 0; i++) { struct PicassoResolution *pr = &md->DisplayModes[i]; int r = pr->res.width > pr->res.height ? 1 : 0; - if (pr->res.width >= currentmode->native_width && pr->res.height >= currentmode->native_height && r == ratio) { - write_log (_T("FS: %dx%d -> %dx%d %d %d\n"), currentmode->native_width, currentmode->native_height, + if (pr->res.width >= mon->currentmode.native_width && pr->res.height >= mon->currentmode.native_height && r == ratio) { + write_log (_T("FS: %dx%d -> %dx%d %d %d\n"), mon->currentmode.native_width, mon->currentmode.native_height, pr->res.width, pr->res.height, ratio, index); - currentmode->native_width = pr->res.width; - currentmode->native_height = pr->res.height; - currentmode->current_width = currentmode->native_width; - currentmode->current_height = currentmode->native_height; + mon->currentmode.native_width = pr->res.width; + mon->currentmode.native_height = pr->res.height; + mon->currentmode.current_width = mon->currentmode.native_width; + mon->currentmode.current_height = mon->currentmode.native_height; goto end; } } @@ -3194,13 +3357,13 @@ static int getbestmode (int nextbest) for (; md->DisplayModes[i].depth >= 0; i++) { struct PicassoResolution *pr = &md->DisplayModes[i]; int r = pr->res.width > pr->res.height ? 1 : 0; - if (pr->res.width >= currentmode->native_width && pr->res.height >= currentmode->native_height) { - write_log (_T("FS: %dx%d -> %dx%d\n"), currentmode->native_width, currentmode->native_height, + if (pr->res.width >= mon->currentmode.native_width && pr->res.height >= mon->currentmode.native_height) { + write_log (_T("FS: %dx%d -> %dx%d\n"), mon->currentmode.native_width, mon->currentmode.native_height, pr->res.width, pr->res.height); - currentmode->native_width = pr->res.width; - currentmode->native_height = pr->res.height; - currentmode->current_width = currentmode->native_width; - currentmode->current_height = currentmode->native_height; + mon->currentmode.native_width = pr->res.width; + mon->currentmode.native_height = pr->res.height; + mon->currentmode.current_width = mon->currentmode.native_width; + mon->currentmode.current_height = mon->currentmode.native_height; goto end; } } @@ -3208,975 +3371,90 @@ static int getbestmode (int nextbest) } end: if (index >= 0) { - currprefs.gfx_apmode[screen_is_picasso ? APMODE_RTG : APMODE_NATIVE].gfx_display = - changed_prefs.gfx_apmode[screen_is_picasso ? APMODE_RTG : APMODE_NATIVE].gfx_display = index; - write_log (L"Can't find mode %dx%d ->\n", currentmode->native_width, currentmode->native_height); + currprefs.gfx_apmode[mon->screen_is_picasso ? APMODE_RTG : APMODE_NATIVE].gfx_display = + changed_prefs.gfx_apmode[mon->screen_is_picasso ? APMODE_RTG : APMODE_NATIVE].gfx_display = index; + write_log (L"Can't find mode %dx%d ->\n", mon->currentmode.native_width, mon->currentmode.native_height); write_log (L"Monitor switched to '%s'\n", md->adaptername); } return 1; } -static volatile frame_time_t vblank_prev_time, vblank_real_prev_time, thread_vblank_time; -static volatile int vblank_found_flipdelay; - -#include - -double getcurrentvblankrate (void) -{ - if (remembered_vblank) - return remembered_vblank; - if (currprefs.gfx_api) - return D3D_getrefreshrate (); - else - return DirectDraw_CurrentRefreshRate (); -} - -static int maxscanline, minscanline, prevvblankpos; -int scanline_adjust; - -static bool getvblankpos (int *vp, bool updateprev) +float target_getcurrentvblankrate(int monid) { - int sl; -#if 0 - frame_time_t t = read_processor_time (); -#endif - *vp = -2; - if (currprefs.gfx_api) { - if (!D3D_getvblankpos (&sl)) - return false; + struct AmigaMonitor *mon = &AMonitors[monid]; + float vb; + if (currprefs.gfx_variable_sync) + return (float)mon->currentmode.freq; + if (get_display_vblank_params(-1, NULL, NULL, &vb, NULL)) { + return vb; + } else if (currprefs.gfx_api) { + return D3D_getrefreshrate(0); } else { - if (!DD_getvblankpos (&sl)) - return false; + return (float)DirectDraw_CurrentRefreshRate(); } -#if 0 - t = read_processor_time () - t; - write_log (_T("(%d:%d)"), t, sl); -#endif - if (updateprev && sl > prevvblankpos) - prevvblankpos = sl; - if (sl > maxscanline) - maxscanline = sl; - if (sl > 0) { - if (sl < minscanline || minscanline < 0) - minscanline = sl; - } - if (maxscanline > minscanline) { - sl += scanline_adjust; - while (sl < -1) - sl += maxscanline + 2; - while (sl > maxscanline) - sl -= maxscanline + 2; - } - *vp = sl; - return true; } -static bool getvblankpos2 (int *vp, int *flags, bool updateprev) +static void movecursor (int x, int y) { - if (!getvblankpos (vp, updateprev)) - return false; - if (*vp > 100 && flags) { - if ((*vp) & 1) - *flags |= 2; - else - *flags |= 1; - } - return true; + write_log (_T("SetCursorPos %dx%d\n"), x, y); + SetCursorPos (x, y); } -static bool waitvblankstate (bool state, int *maxvpos, int *flags) +static void getextramonitorpos(struct AmigaMonitor *mon, RECT *r) { - bool waitzero = false; - int vp; - int count = 0; - if (flags) - *flags = 0; - uae_u32 t = getlocaltime () + 5; - for (;;) { - int omax = maxscanline; - if (!getvblankpos2 (&vp, flags, true)) - return false; - while (omax != maxscanline) { - omax = maxscanline; - if (!getvblankpos2 (&vp, flags, true)) - return false; - } - if (maxvpos) - *maxvpos = maxscanline; - if (vp < 0 || (waitzero && vp == 0)) { - if (state) - return true; - } else { - if (vp > 0) - waitzero = true; - if (!state) - return true; - } - count--; - if (count < 0) { - if (getlocaltime () > t) - return false; - count = 1000; - } - } -} + typedef HRESULT(CALLBACK* DWMGETWINDOWATTRIBUTE)(HWND hwnd, DWORD dwAttribute, PVOID pvAttribute, DWORD cbAttribute); + static DWMGETWINDOWATTRIBUTE pDwmGetWindowAttribute; + static HMODULE dwmapihandle; -static int timezeroonevblank (int startline, int endline) -{ - int vp; - for (;;) { - if (!getvblankpos (&vp, false)) - return -1; - if (vp > endline) - break; - } - for (;;) { - if (!getvblankpos (&vp, false)) - return -1; - if (vp == startline || (vp == 0 && startline < 0)) - break; - } - frame_time_t start = read_processor_time (); - for (;;) { - if (!getvblankpos (&vp, false)) - return -1; - if (vp >= endline) - break; + RECT r1, r2; + if (!pDwmGetWindowAttribute && !dwmapihandle && os_vista) { + dwmapihandle = LoadLibrary(_T("dwmapi.dll")); + if (dwmapihandle) + pDwmGetWindowAttribute = (DWMGETWINDOWATTRIBUTE)GetProcAddress(dwmapihandle, "DwmGetWindowAttribute"); } - frame_time_t end = read_processor_time (); - return end - start; -} - -static int vblank_wait (void) -{ - int vp; + // find rightmost window edge + int monid = MAX_AMIGAMONITORS - 1; + int rightmon = -1; + int rightedge = 0; + HWND hwnd = NULL; for (;;) { - int opos = prevvblankpos; - if (!getvblankpos (&vp, true)) - return -2; - if (opos >= 0 && opos > (maxscanline + minscanline) / 2 && vp < (maxscanline + minscanline) / 3) - return vp; - if (vp <= 0) - return vp; - vsync_sleep (true); - } -} - -static bool vblank_getstate (bool *state, int *pvp) -{ - int vp, opos; - - *state = false; - opos = prevvblankpos; - if (!getvblankpos (&vp, true)) - return false; - if (pvp) - *pvp = vp; - if (opos >= 0 && opos > (maxscanline + minscanline) / 2 && vp < (maxscanline + minscanline) / 3) { - *state = true; - return true; - } - if (opos > vp && vp <= 0) { - *state = true; - return true; - } - *state = false; - return true; -} -static bool vblank_getstate (bool *state) -{ - return vblank_getstate (state, NULL); -} - -void vblank_reset (double freq) -{ - if (currprefs.gfx_api) - D3D_vblank_reset (freq); - else - DD_vblank_reset (freq); -} - -static unsigned int __stdcall flipthread (void *dummy) -{ - SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST); - while (flipthread_mode) { - WaitForSingleObject (flipevent, INFINITE); - if (flipthread_mode == 0) - break; - frame_time_t t = read_processor_time (); - while ((flipevent_mode & 1) && !render_ok) { - sleep_millis (1); - if (read_processor_time () - t > vblankbasefull) - break; - } - if (flipevent_mode & 1) { - show_screen (0); - render_ok = false; - } - if (flipevent_mode & 2) { - show_screen_special (); - wait_render = false; - } - flipevent_mode = 0; - SetEvent (flipevent2); - } - flipevent_mode = 0; - flipthread_mode = -1; - return 0; -} - -static int frame_missed, frame_counted, frame_errors; -static int frame_usage, frame_usage_avg, frame_usage_total; -extern int log_vsync; -static int dooddevenskip; -static volatile int vblank_skipeveryother; -static int vblank_flip_delay; - -static int lacemismatch_post_frames = 5; -static int lacemismatch_pre_frames = 5; - -static bool vblanklaceskip (void) -{ - if (graphics_mode_changed) - return false; - if (vblankbaselace_chipset >= 0 && vblankbaselace) { - if ((vblankbaselace_chipset && !vblankthread_oddeven) || (!vblankbaselace_chipset && vblankthread_oddeven)) - return true; - } - return false; -} - -static bool vblanklaceskip_check (void) -{ - int vp = -2; - if (!vblanklaceskip ()) { -// if (vblankbaselace_chipset >= 0) -// write_log (_T("%d == %d\n"), vblankbaselace_chipset, vblankthread_oddeven); - return false; - } - getvblankpos (&vp, false); - if (vp >= maxscanline / 20 && vp <= maxscanline - maxscanline / 20) - write_log (_T("Interlaced frame type mismatch %d<>%d (%d,%d)\n"), vblankbaselace_chipset, vblankthread_oddeven, vp, prevvblankpos); - return true; -} - -static unsigned int __stdcall vblankthread (void *dummy) -{ - bool firstvblankbasewait2; - frame_time_t vblank_prev_time2; - bool doflipped; - - while (vblankthread_mode > VBLANKTH_KILL) { - struct apmode *ap = picasso_on ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0]; - vblankthread_counter++; - int mode = vblankthread_mode; - if (mode == VBLANKTH_CALIBRATE) { - // calibrate mode, try to keep CPU power saving inactive - SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_LOWEST); - while (vblankthread_mode == 0) - vblankthread_counter++; - SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST); - } else if (mode == VBLANKTH_IDLE) { - // idle mode - Sleep (100); - } else if (mode == VBLANKTH_ACTIVE_WAIT) { - sleep_millis (1); - } else if (mode == VBLANKTH_ACTIVE_START) { - // do not start until vblank has passed - int vp; - if (!getvblankpos (&vp, false)) { - // bad things happening - vblankthread_mode = VBLANKTH_ACTIVE; - continue; - } - if (vp <= 0) { - sleep_millis (1); - continue; - } - ResetEvent (vblankwaitevent); - if (dooddevenskip == 1) { - frame_time_t rpt = read_processor_time (); - for (;;) { - sleep_millis (1); - if (!getvblankpos (&vp, false)) - break; - if (read_processor_time () - rpt > 2 * vblankbasefull) - break; - if (vp >= (maxscanline + minscanline) / 2) - break; - } - for (;;) { - sleep_millis (1); - if (!getvblankpos (&vp, false)) - break; - if (read_processor_time () - rpt > 2 * vblankbasefull) - break; - if (vp < (maxscanline + minscanline) / 2) - break; - } - } - if (dooddevenskip > 1) { - dooddevenskip++; - if (dooddevenskip > lacemismatch_post_frames) - dooddevenskip = 0; - } - if (vp > maxscanline / 2) - vp = maxscanline / 2; - frame_time_t rpt = read_processor_time (); - vblank_prev_time2 = rpt - (vblankbaseadjust + (vblankbasefull * vp / maxscanline) / (vblank_skipeveryother > 0 ? 2 : 1)); - vblank_prev_time = vblank_prev_time2; - firstvblankbasewait2 = false; - prevvblankpos = -1; - vblank_found_flipdelay = 0; - doflipped = false; - if (vblank_skipeveryother > 0) // wait for first vblank in skip frame mode (100Hz+) - vblankthread_mode = VBLANKTH_ACTIVE_SKIPFRAME; - else - vblankthread_mode = VBLANKTH_ACTIVE; - } else if (mode == VBLANKTH_ACTIVE_SKIPFRAME) { - int vp; - sleep_millis (1); - getvblankpos (&vp, true); - if (vp >= (maxscanline + minscanline) / 2) - vblankthread_mode = VBLANKTH_ACTIVE_SKIPFRAME2; - // something is wrong? - if (read_processor_time () - vblank_prev_time2 > vblankbasefull * 2) - vblankthread_mode = VBLANKTH_ACTIVE; - } else if (mode == VBLANKTH_ACTIVE_SKIPFRAME2) { - int vp; - sleep_millis (1); - getvblankpos (&vp, true); - if (vp > 0 && vp < (maxscanline + minscanline) / 2) { - prevvblankpos = 0; - vblankthread_mode = VBLANKTH_ACTIVE; - } - if (read_processor_time () - vblank_prev_time2 > vblankbasefull * 2) - vblankthread_mode = VBLANKTH_ACTIVE; - } else if (mode == VBLANKTH_ACTIVE) { - // busy wait mode - frame_time_t t = read_processor_time (); - bool donotwait = false; - bool end = false; - bool vblank_found_rtg2 = false; - bool vblank_found2 = false; - frame_time_t thread_vblank_time2 = 0; - - if (t - vblank_prev_time2 > vblankbasewait2) { - int vp = 0; - bool vb = false; - bool ok; - if (firstvblankbasewait2 == false) { - firstvblankbasewait2 = true; - vblank_getstate (&vb, &vp); - vblankthread_oddeven = (vp & 1) != 0; - } - if (!doflipped && ap->gfx_vflip > 0) { - int flag = 1; - if (ap->gfx_strobo && vblank_skipeveryother > 0) - flag |= 2; - doflipevent (flag); - doflipped = true; - } - ok = vblank_getstate (&vb, &vp); - if (!ok || vb) { - thread_vblank_time2 = t; - vblank_found_chipset = true; - if (!ap->gfx_vflip) { - if (vblank_skipeveryother >= 0) { - while (!render_ok) { - if (read_processor_time () - t > vblankbasefull) - break; - } - show_screen (0); - render_ok = false; - } else if (vblank_skipeveryother == -1) { - while (!render_ok) { - if (read_processor_time () - t > vblankbasefull) - break; - } - show_screen (0); - render_ok = false; - wait_render = true; - vblank_skipeveryother = -2; - } else { // == -2 - show_screen (2); - wait_render = false; - vblank_skipeveryother = -1; - } - int delay = read_processor_time () - t; - if (delay < 0) - delay = 0; - else if (delay >= vblankbasefull) - delay = 0; - else if (delay > vblankbasefull * 2 / 3) - delay = vblankbasefull * 2 / 3; - vblank_found_flipdelay = delay; - } - vblank_found_rtg2 = true; - vblank_found2 = true; - if (!dooddevenskip && vblanklaceskip_check ()) - dooddevenskip = 1; - end = true; - } - if (t - vblank_prev_time2 > vblankbasewait3) - donotwait = true; - } - if (!end && t - vblank_prev_time2 > vblankbasefull * 2) { - thread_vblank_time2 = t; - vblank_found2 = true; - vblank_found_rtg2 = true; - vblank_found_chipset = true; - end = true; - } - if (end) { - if (ap->gfx_vflip > 0 && !doflipped) { - doflipevent (1); - doflipped = true; - } - thread_vblank_time = thread_vblank_time2; - vblank_found_rtg = vblank_found_rtg2; - vblank_found = vblank_found2; - if (vblank_skipeveryother == -2) - vblankthread_mode = VBLANKTH_ACTIVE_START; - else - vblankthread_mode = VBLANKTH_ACTIVE_WAIT; - SetEvent (vblankwaitevent); - } else if (!donotwait || ap->gfx_vflip || picasso_on) { - sleep_millis (1); - } - } else { - break; - } - } - vblankthread_mode = -1; - return 0; -} - - -static bool isthreadedvsync (void) -{ - struct apmode *ap = picasso_on ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0]; - return isvsync_chipset () <= -2 || isvsync_rtg () < 0 || ap->gfx_strobo; -} - -frame_time_t vsync_busywait_end (int *flipdelay) -{ - if (graphics_mode_changed > 0) { - graphics_mode_changed++; - if (graphics_mode_changed >= vsync_modechangetimeout) - graphics_mode_changed = 0; - } - - if (isthreadedvsync ()) { - frame_time_t prev; - - if (!currprefs.turbo_emulation) { - for (;;) { - int v = vblankthread_mode; - if (v != VBLANKTH_ACTIVE_START && v != VBLANKTH_ACTIVE_SKIPFRAME && v != VBLANKTH_ACTIVE_SKIPFRAME2) - break; - sleep_millis_main (1); - } - prev = vblank_prev_time; - if (!vblanklaceskip ()) { - int delay = 10; - frame_time_t t = read_processor_time (); - while (delay-- > 0) { - if (WaitForSingleObject (vblankwaitevent, 10) != WAIT_TIMEOUT) - break; - } - idletime += read_processor_time () - t; - } - if (flipdelay) - *flipdelay = vblank_found_flipdelay; - } else { - show_screen (0); - prev = read_processor_time (); - } - changevblankthreadmode_fast (VBLANKTH_ACTIVE_WAIT); - return prev + vblankbasefull; - } else { - if (flipdelay) - *flipdelay = vblank_flip_delay; - return vblank_prev_time; - } -} - -static bool vblank_sync_started; - -bool vsync_isdone (void) -{ - if (isvsync () == 0) - return false; - if (currprefs.gfx_api > 1) { - return d3d11_vsync_isdone(); - } else { - if (!isthreadedvsync()) { - int vp = -2; - getvblankpos(&vp, true); - if (!vblankthread_oddeven_got) { - // need to get odd/even state early - while (vp < 0) { - if (!getvblankpos(&vp, true)) - break; - } - vblankthread_oddeven = (vp & 1) != 0; - vblankthread_oddeven_got = true; - } - } - if (dooddevenskip) - return true; - if (vblank_found_chipset) - return true; - } - return false; -} - -void vsync_busywait_start (void) -{ - if (isthreadedvsync ()) { - if (vblankthread_mode < 0) - write_log (L"low latency threaded mode but thread is not running!?\n"); - else if (vblankthread_mode != VBLANKTH_ACTIVE_WAIT) - write_log (L"low latency vsync state mismatch %d\n", vblankthread_mode); - changevblankthreadmode_fast (VBLANKTH_ACTIVE_START); - } else { - vblank_found_chipset = false; - } -} - -int vsync_busywait_do (int *freetime, bool lace, bool oddeven) -{ - int v; - static bool framelost; - int ti; - frame_time_t t; - frame_time_t prevtime = vblank_prev_time; - struct apmode *ap = picasso_on ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0]; - - if (currprefs.gfx_api == 2) { - show_screen(0); - return 1; - } - - vblank_sync_started = true; - if (lace) - vblankbaselace_chipset = oddeven == true ? 1 : 0; - else - vblankbaselace_chipset = -1; - - t = read_processor_time (); - ti = t - prevtime; - if (ti > 2 * vblankbasefull || ti < -2 * vblankbasefull) { - changevblankthreadmode_fast (VBLANKTH_ACTIVE_WAIT); - waitvblankstate (false, NULL, NULL); - vblank_prev_time = t; - thread_vblank_time = t; - frame_missed++; - return 0; - } - - if (0 || (log_vsync & 1)) { - 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); - //write_log(_T("F:%8d M:%8d E:%8d %3d%% (%3d%%) %10d\n"), frame_counted, frame_missed, frame_errors, frame_usage, frame_usage_avg, (t - vblank_prev_time) - vblankbasefull); - } - - if (freetime) - *freetime = 0; - - frame_usage = (t - prevtime) * 100 / vblankbasefull; - if (frame_usage > 99) - frame_usage = 99; - else if (frame_usage < 0) - frame_usage = 0; - frame_usage_total += frame_usage; - if (freetime) - *freetime = frame_usage; - if (frame_counted) - frame_usage_avg = frame_usage_total / frame_counted; - - v = 0; - - if (isthreadedvsync ()) { - - framelost = false; - v = 1; - - } else { - int vp; - - vblank_flip_delay = 0; - - vblankthread_oddeven_got = false; - - if (currprefs.turbo_emulation) { - - show_screen (0); - dooddevenskip = 0; - vblank_prev_time = read_processor_time (); - framelost = true; - v = -1; - prevvblankpos = -1; - - } else { - - //write_log (L"%d\n", prevvblankpos); - - if (dooddevenskip > 0 && dooddevenskip != lacemismatch_pre_frames) { - dooddevenskip++; - if (dooddevenskip > lacemismatch_pre_frames + lacemismatch_post_frames) - dooddevenskip = 0; - } - - if (!dooddevenskip && vblanklaceskip_check ()) { - dooddevenskip = 1; - } - - if (ap->gfx_vflip == 0 && vblank_skipeveryother) { - // make sure that we really did skip one field - while (!framelost && read_processor_time () - vblank_real_prev_time < vblankbasewait1) { - vsync_sleep (false); - } - } - - if (ap->gfx_vflip != 0) { - show_screen (0); - if (ap->gfx_strobo && vblank_skipeveryother) { - wait_render = true; - doflipevent (2); - } - } - while (!framelost && read_processor_time () - prevtime < vblankbasewait1) { - vsync_sleep (false); - } - vp = vblank_wait (); - - if (dooddevenskip == lacemismatch_pre_frames) { - if (vblanklaceskip_check ()) { - for (;;) { - if (!getvblankpos (&vp, true)) - break; - if (vp > maxscanline * 2 / 3) - break; - } - vp = vblank_wait (); - dooddevenskip++; - } else { - dooddevenskip = 0; - } - } - - if (vp >= -1) { - vblank_real_prev_time = vblank_prev_time = read_processor_time (); - if (ap->gfx_vflip == 0) { - show_screen (0); - vblank_flip_delay = (read_processor_time () - vblank_prev_time) / (vblank_skipeveryother ? 2 : 1); - if (vblank_flip_delay < 0) - vblank_flip_delay = 0; - else if (vblank_flip_delay > vblankbasefull * 2 / 3) - vblank_flip_delay = vblankbasefull * 2 / 3; - } - - vblank_prev_time -= vblankbaseadjust; - if (vp > 0) { - vblank_prev_time -= (vblankbasefull * vp / maxscanline) / (vblank_skipeveryother ? 2 : 1 ); - vblank_sync_started = false; - } - - v = dooddevenskip || framelost ? -1 : 1; - } - - prevvblankpos = -1; - framelost = false; - } - } - - if (v) { - frame_counted++; - return v; - } - frame_errors++; - return 0; -} - -static struct remembered_vsync *vsyncmemory; - -struct remembered_vsync -{ - struct remembered_vsync *next; - int width, height, depth, rate, mode; - bool rtg, lace; - double remembered_rate, remembered_rate2; - int remembered_adjust; - int maxscanline, minscanline, maxvpos; -}; - -double vblank_calibrate (double approx_vblank, bool waitonly) -{ - frame_time_t t1, t2; - double tsum, tsum2, tval, tfirst, div; - int maxcnt, maxtotal, total, cnt, tcnt2; - HANDLE th; - int maxvpos, mult; - int width, height, depth, rate, mode; - struct remembered_vsync *rv; - double rval = -1; - struct apmode *ap = picasso_on ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0]; - struct apmode *apc = picasso_on ? &changed_prefs.gfx_apmode[1] : &changed_prefs.gfx_apmode[0]; - bool remembered = false; - bool lace = false; - - if (currprefs.gfx_api == 2) { - double hz = d3d11_get_hz(); - if (hz <= 0) - goto fail; - write_log(_T("VSync: %.6fHz\n"), hz); - return hz; - } - - if (picasso_on) { - width = picasso96_state.Width; - height = picasso96_state.Height; - depth = picasso96_state.BytesPerPixel; - } else { - width = currentmode->native_width; - height = currentmode->native_height; - depth = (currentmode->native_depth + 7) / 8; - } - - rate = ap->gfx_refreshrate; - mode = isfullscreen (); - - // clear remembered modes if restarting and start thread again. - if (vblankthread_mode <= 0) { - rv = vsyncmemory; - while (rv) { - struct remembered_vsync *rvo = rv->next; - xfree (rv); - rv = rvo; - } - vsyncmemory = NULL; - } - - rv = vsyncmemory; - while (rv) { - if (rv->width == width && rv->height == height && rv->depth == depth && rv->rate == rate && rv->mode == mode && rv->rtg == picasso_on) { - approx_vblank = rv->remembered_rate2; - tsum = rval = rv->remembered_rate; - maxscanline = rv->maxscanline; - minscanline = rv->minscanline; - vblankbaseadjust = rv->remembered_adjust; - maxvpos = rv->maxvpos; - lace = rv->lace; - waitonly = true; - remembered = true; - goto skip; - } - rv = rv->next; - } - - th = GetCurrentThread (); - int oldpri = GetThreadPriority (th); - SetThreadPriority (th, THREAD_PRIORITY_HIGHEST); - if (vblankthread_mode <= VBLANKTH_KILL) { - unsigned th; - vblankthread_mode = VBLANKTH_CALIBRATE; - _beginthreadex (NULL, 0, vblankthread, 0, 0, &th); - flipthread_mode = 1; - flipevent_mode = 0; - flipevent = CreateEvent (NULL, FALSE, FALSE, NULL); - flipevent2 = CreateEvent (NULL, FALSE, FALSE, NULL); - vblankwaitevent = CreateEvent (NULL, FALSE, FALSE, NULL); - _beginthreadex (NULL, 0, flipthread, 0, 0, &th); - } else { - changevblankthreadmode (VBLANKTH_CALIBRATE); - } - sleep_millis (100); - - maxtotal = 10; - maxcnt = maxtotal; - maxscanline = 0; - minscanline = -1; - tsum2 = 0; - tcnt2 = 0; - for (maxcnt = 0; maxcnt < maxtotal; maxcnt++) { - total = 5; - tsum = 0; - cnt = total; - for (cnt = 0; cnt < total; cnt++) { - int maxvpos1, maxvpos2; - int flags1, flags2; - if (!waitvblankstate (true, NULL, NULL)) - goto fail; - if (!waitvblankstate (false, NULL, NULL)) - goto fail; - if (!waitvblankstate (true, NULL, NULL)) - goto fail; - t1 = read_processor_time (); - if (!waitvblankstate (false, NULL, NULL)) - goto fail; - maxscanline = 0; - if (!waitvblankstate (true, &maxvpos1, &flags1)) - goto fail; - if (!waitvblankstate (false, NULL, NULL)) - goto fail; - maxscanline = 0; - if (!waitvblankstate (true, &maxvpos2, &flags2)) - goto fail; - t2 = read_processor_time (); - maxvpos = maxvpos1 > maxvpos2 ? maxvpos1 : maxvpos2; - // count two fields: works with interlaced modes too. - tval = (double)syncbase * 2.0 / (t2 - t1); - if (cnt == 0) { - tfirst = tval; - } - if (tval > 1100 && maxcnt >= maxtotal - 1) { - write_log (_T("Out of range value %.6f, disabling low latency vsync..\n"), tval); - goto fail; - } - if (tval > 1100 || abs (tval - tfirst) > 1) { - write_log (_T("Very unstable vsync! %.6f vs %.6f, retrying..\n"), tval, tfirst); - break; - } - tsum2 += tval; - tcnt2++; - if (abs (tval - tfirst) > 0.1) { - write_log (_T("Unstable vsync! %.6f vs %.6f\n"), tval, tfirst); - break; - } - tsum += tval; - if ((flags1 > 0 && flags1 < 3) && (flags2 > 0 && flags2 < 3) && (flags1 != flags2)) { - lace = true; - } - } - if (cnt >= total) + if (monid < 1) break; - } - vblankbaseadjust = timezeroonevblank (-1, 1); - - changevblankthreadmode (VBLANKTH_IDLE); - - if (maxcnt >= maxtotal) { - tsum = tsum2 / tcnt2; - write_log (_T("Unstable vsync reporting, using average value\n")); - } else { - tsum /= total; - } - - if (ap->gfx_vflip == 0) { - int vsdetect = 0; - int detectcnt = 6; - for (cnt = 0; cnt < detectcnt; cnt++) { - render_screen (true); - show_screen (0); - sleep_millis (1); - frame_time_t t = read_processor_time () + 1 * (syncbase / tsum); - for (int cnt2 = 0; cnt2 < 4; cnt2++) { - render_ok = true; - show_screen (0); - } - int diff = (int)read_processor_time () - (int)t; - if (diff >= 0) - vsdetect++; - } - if (vsdetect >= detectcnt / 2) { - write_log (_T("Forced vsync detected, switching to double buffered\n")); - changed_prefs.gfx_apmode[0].gfx_backbuffers = 1; - } - } - - SetThreadPriority (th, oldpri); - - if (waitonly) - tsum = approx_vblank; - waitonly = false; -skip: - - vblank_skipeveryother = 0; - getvsyncrate (tsum, &mult); - if (mult < 0) { - div = 2.0; - vblank_skipeveryother = 1; - if (ap->gfx_strobo && ap->gfx_vflip == 0) { - vblank_skipeveryother = -1; - div = 1.0; + monid--; + hwnd = AMonitors[monid].hMainWnd; + if (!hwnd) + continue; + GetWindowRect(hwnd, &r1); + if (r1.right > rightedge) { + rightedge = r1.right; + rightmon = monid; } - } else if (mult > 0) { - div = 0.5; - } else { - div = 1.0; - } - tsum2 = tsum / div; - - vblankbasefull = (syncbase / tsum2); - vblankbasewait1 = (syncbase / tsum2) * 70 / 100; - vblankbasewait2 = (syncbase / tsum2) * 55 / 100; - vblankbasewait3 = (syncbase / tsum2) * 99 / 100 - syncbase / (250 * (vblank_skipeveryother > 0 ? 1 : 2)); // at least 2ms before vblank - vblankbaselace = lace; - - write_log (_T("VSync %s: %.6fHz/%.1f=%.6fHz. MinV=%d MaxV=%d%s Adj=%d Units=%d %.1f%%\n"), - waitonly ? _T("remembered") : _T("calibrated"), tsum, div, tsum2, - minscanline, maxvpos, lace ? _T("i") : _T(""), vblankbaseadjust, vblankbasefull, - vblankbasewait3 * 100 / (syncbase / tsum2)); - - if (minscanline == 1) { - if (vblankbaseadjust < 0) - vblankbaseadjust = 0; - else if (vblankbaseadjust > vblankbasefull / 10) - vblankbaseadjust = vblankbasefull / 10; - } else { - vblankbaseadjust = 0; } + if (rightmon < 0) + return; + hwnd = AMonitors[rightmon].hMainWnd; + GetWindowRect(hwnd, &r1); + r2 = r1; - remembered_vblank = tsum; - vblank_prev_time = read_processor_time (); - - if (!remembered) { - rv = xcalloc (struct remembered_vsync, 1); - rv->width = width; - rv->height = height; - rv->depth = depth; - rv->rate = rate; - rv->mode = isfullscreen (); - rv->rtg = picasso_on; - rv->remembered_rate = tsum; - rv->remembered_rate2 = tsum2; - rv->remembered_adjust = vblankbaseadjust; - rv->maxscanline = maxscanline; - rv->minscanline = minscanline; - rv->maxvpos = maxvpos; - rv->lace = lace; - if (vsyncmemory == NULL) { - vsyncmemory = rv; - } else { - rv->next = vsyncmemory; - vsyncmemory = rv; - } + if (pDwmGetWindowAttribute) { + pDwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &r2, sizeof(r2)); } - - vblank_reset (tsum); - return tsum; -fail: - write_log (_T("VSync calibration failed\n")); - ap->gfx_vsync = 0; - apc->gfx_vsync = 0; - return -1; -} + int width = r->right - r->left; + int height = r->bottom - r->top; -static void movecursor (int x, int y) -{ - write_log (_T("SetCursorPos %dx%d\n"), x, y); - SetCursorPos (x, y); + r->left = r1.right - ((r2.left - r1.left) + (r1.right - r2.right)); + r->top = r1.top; + r->bottom = r->top + height; + r->right = r->left + width; } -static int create_windows_2 (void) +static int create_windows_2(struct AmigaMonitor *mon) { static bool firstwindow = true; - static int prevsbheight; - int dxfs = currentmode->flags & (DM_DX_FULLSCREEN); - int d3dfs = currentmode->flags & (DM_D3D_FULLSCREEN); - int fsw = currentmode->flags & (DM_W_FULLSCREEN); + int dxfs = mon->currentmode.flags & (DM_DX_FULLSCREEN); + int d3dfs = mon->currentmode.flags & (DM_D3D_FULLSCREEN); + int fsw = mon->currentmode.flags & (DM_W_FULLSCREEN); DWORD exstyle = (currprefs.win32_notaskbarbutton ? WS_EX_TOOLWINDOW : WS_EX_APPWINDOW) | 0; DWORD flags = 0; int borderless = currprefs.win32_borderless; @@ -4187,9 +3465,9 @@ static int create_windows_2 (void) struct MultiDisplay *md = getdisplay (&currprefs); int sbheight; - sbheight = currprefs.win32_statusbar ? getstatuswindowheight () : 0; + sbheight = currprefs.win32_statusbar ? getstatuswindowheight(mon->monitor_id) : 0; - if (hAmigaWnd) { + if (mon->hAmigaWnd) { RECT r; int w, h, x, y; int nw, nh, nx, ny; @@ -4205,7 +3483,7 @@ static int create_windows_2 (void) ShowWindow (hMainWnd, SW_RESTORE); } #endif - GetWindowRect (hAmigaWnd, &r); + GetWindowRect (mon->hAmigaWnd, &r); x = r.left; y = r.top; w = r.right - r.left; @@ -4213,12 +3491,12 @@ static int create_windows_2 (void) nx = x; ny = y; - if (screen_is_picasso) { - nw = currentmode->current_width; - nh = currentmode->current_height; + if (mon->screen_is_picasso) { + nw = mon->currentmode.current_width; + nh = mon->currentmode.current_height; } else { - nw = currprefs.gfx_size_win.width; - nh = currprefs.gfx_size_win.height; + nw = currprefs.gfx_monitor[mon->monitor_id].gfx_size_win.width; + nh = currprefs.gfx_monitor[mon->monitor_id].gfx_size_win.height; } if (fsw || dxfs) { @@ -4229,8 +3507,8 @@ static int create_windows_2 (void) nh = rc.bottom - rc.top; } else if (d3dfs) { RECT rc = md->rect; - nw = currentmode->native_width; - nh = currentmode->native_height; + nw = mon->currentmode.native_width; + nh = mon->currentmode.native_height; if (rc.left >= 0) nx = rc.left; else @@ -4240,42 +3518,42 @@ static int create_windows_2 (void) else ny = rc.top + (rc.bottom - rc.top - nh); } - if (w != nw || h != nh || x != nx || y != ny || sbheight != prevsbheight) { + if (w != nw || h != nh || x != nx || y != ny || sbheight != mon->prevsbheight) { w = nw; h = nh; x = nx; y = ny; - in_sizemove++; - if (hMainWnd && !fsw && !dxfs && !d3dfs && !rp_isactive ()) { - window_extra_height += (sbheight - prevsbheight); - GetWindowRect (hMainWnd, &r); + mon->in_sizemove++; + if (mon->hMainWnd && !fsw && !dxfs && !d3dfs && !rp_isactive ()) { + mon->window_extra_height += (sbheight - mon->prevsbheight); + GetWindowRect(mon->hMainWnd, &r); x = r.left; y = r.top; - SetWindowPos (hMainWnd, HWND_TOP, x, y, w + window_extra_width, h + window_extra_height, + SetWindowPos(mon->hMainWnd, HWND_TOP, x, y, w + mon->window_extra_width, h + mon->window_extra_height, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | SWP_NOZORDER); x = gap; y = gap; } - SetWindowPos (hAmigaWnd, HWND_TOP, x, y, w, h, + SetWindowPos(mon->hAmigaWnd, HWND_TOP, x, y, w, h, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | SWP_NOZORDER); - in_sizemove--; + mon->in_sizemove--; } else { w = nw; h = nh; x = nx; y = ny; } - createstatuswindow(); - createstatusline(); - updatewinrect (false); - GetWindowRect (hMainWnd, &mainwin_rect); + createstatuswindow(mon); + createstatusline(mon->monitor_id); + updatewinrect(mon, false); + GetWindowRect (mon->hMainWnd, &mon->mainwin_rect); if (d3dfs || dxfs) movecursor (x + w / 2, y + h / 2); write_log (_T("window already open (%dx%d %dx%d)\n"), - amigawin_rect.left, amigawin_rect.top, amigawin_rect.right - amigawin_rect.left, amigawin_rect.bottom - amigawin_rect.top); - updatemouseclip (); + mon->amigawin_rect.left, mon->amigawin_rect.top, mon->amigawin_rect.right - mon->amigawin_rect.left, mon->amigawin_rect.bottom - mon->amigawin_rect.top); + updatemouseclip(mon); rp_screenmode_changed (); - prevsbheight = sbheight; + mon->prevsbheight = sbheight; return 1; } @@ -4283,7 +3561,7 @@ static int create_windows_2 (void) borderless = 1; window_led_drives = 0; window_led_drives_end = 0; - hMainWnd = NULL; + mon->hMainWnd = NULL; x = 0; y = 0; if (borderless) sbheight = cyborder = 0; @@ -4293,13 +3571,13 @@ static int create_windows_2 (void) int stored_x = 1, stored_y = sbheight + cyborder; int oldx, oldy; int first = 2; - + regqueryint (NULL, _T("MainPosX"), &stored_x); regqueryint (NULL, _T("MainPosY"), &stored_y); if (borderless) { - stored_x = currprefs.gfx_size_win.x; - stored_y = currprefs.gfx_size_win.y; + stored_x = currprefs.gfx_monitor[mon->monitor_id].gfx_size_win.x; + stored_y = currprefs.gfx_monitor[mon->monitor_id].gfx_size_win.y; } while (first) { @@ -4319,20 +3597,24 @@ static int create_windows_2 (void) else rc.top = stored_y; - rc.right = rc.left + gap + currentmode->current_width + gap; - rc.bottom = rc.top + gap + currentmode->current_height + gap + sbheight; + rc.right = rc.left + gap + mon->currentmode.current_width + gap; + rc.bottom = rc.top + gap + mon->currentmode.current_height + gap + sbheight; oldx = rc.left; oldy = rc.top; AdjustWindowRect (&rc, borderless ? WS_POPUP : style, FALSE); - win_x_diff = rc.left - oldx; - win_y_diff = rc.top - oldy; + mon->win_x_diff = rc.left - oldx; + mon->win_y_diff = rc.top - oldy; if (MonitorFromRect (&rc, MONITOR_DEFAULTTONULL) == NULL) { write_log (_T("window coordinates are not visible on any monitor, reseting..\n")); stored_x = stored_y = 0; continue; } + + if (mon->monitor_id > 0) { + getextramonitorpos(mon, &rc); + } break; } @@ -4340,41 +3622,41 @@ static int create_windows_2 (void) rc = md->rect; flags |= WS_EX_TOPMOST; style = WS_POPUP; - currentmode->native_width = rc.right - rc.left; - currentmode->native_height = rc.bottom - rc.top; + mon->currentmode.native_width = rc.right - rc.left; + mon->currentmode.native_height = rc.bottom - rc.top; } flags |= (currprefs.win32_main_alwaysontop ? WS_EX_TOPMOST : 0); if (!borderless) { RECT rc2; - hMainWnd = CreateWindowEx (WS_EX_ACCEPTFILES | exstyle | flags, + mon->hMainWnd = CreateWindowEx(WS_EX_ACCEPTFILES | exstyle | flags, _T("PCsuxRox"), _T("WinUAE"), style, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInst, NULL); - if (!hMainWnd) { + if (!mon->hMainWnd) { write_log (_T("main window creation failed\n")); return 0; } - GetWindowRect (hMainWnd, &rc2); - window_extra_width = rc2.right - rc2.left - currentmode->current_width; - window_extra_height = rc2.bottom - rc2.top - currentmode->current_height; - createstatuswindow(); - createstatusline(); + GetWindowRect(mon->hMainWnd, &rc2); + mon->window_extra_width = rc2.right - rc2.left - mon->currentmode.current_width; + mon->window_extra_height = rc2.bottom - rc2.top - mon->currentmode.current_height; + createstatuswindow(mon); + createstatusline(mon->monitor_id); } else { x = rc.left; y = rc.top; } - w = currentmode->native_width; - h = currentmode->native_height; + w = mon->currentmode.native_width; + h = mon->currentmode.native_height; } else { RECT rc; - getbestmode (0); - w = currentmode->native_width; - h = currentmode->native_height; + getbestmode(mon, 0); + w = mon->currentmode.native_width; + h = mon->currentmode.native_height; rc = md->rect; if (rc.left >= 0) x = rc.left; @@ -4388,62 +3670,69 @@ static int create_windows_2 (void) if (rp_isactive () && !dxfs && !d3dfs && !fsw) { HWND parent = rp_getparent (); - hAmigaWnd = CreateWindowEx (dxfs || d3dfs ? WS_EX_ACCEPTFILES | WS_EX_TOPMOST : WS_EX_ACCEPTFILES | WS_EX_TOOLWINDOW | (currprefs.win32_main_alwaysontop ? WS_EX_TOPMOST : 0), + mon->hAmigaWnd = CreateWindowEx (dxfs || d3dfs ? WS_EX_ACCEPTFILES | WS_EX_TOPMOST : WS_EX_ACCEPTFILES | WS_EX_TOOLWINDOW | (currprefs.win32_main_alwaysontop ? WS_EX_TOPMOST : 0), _T("AmigaPowah"), _T("WinUAE"), WS_POPUP, 0, 0, w, h, parent, NULL, hInst, NULL); } else { - hAmigaWnd = CreateWindowEx ( + mon->hAmigaWnd = CreateWindowEx ( ((dxfs || d3dfs || currprefs.win32_main_alwaysontop) ? WS_EX_TOPMOST : WS_EX_ACCEPTFILES) | exstyle, _T("AmigaPowah"), _T("WinUAE"), - ((dxfs || d3dfs || currprefs.headless) ? WS_POPUP : (WS_CLIPCHILDREN | WS_CLIPSIBLINGS | (hMainWnd ? WS_VISIBLE | WS_CHILD : WS_VISIBLE | WS_POPUP | WS_SYSMENU | WS_MINIMIZEBOX))), + ((dxfs || d3dfs || currprefs.headless) ? WS_POPUP : (WS_CLIPCHILDREN | WS_CLIPSIBLINGS | (mon->hMainWnd ? WS_VISIBLE | WS_CHILD : WS_VISIBLE | WS_POPUP | WS_SYSMENU | WS_MINIMIZEBOX))), x, y, w, h, - borderless ? NULL : (hMainWnd ? hMainWnd : NULL), + borderless ? NULL : (mon->hMainWnd ? mon->hMainWnd : NULL), NULL, hInst, NULL); } - if (!hAmigaWnd) { + if (!mon->hAmigaWnd) { write_log (_T("creation of amiga window failed\n")); - close_hwnds (); + close_hwnds(mon); return 0; } - if (hMainWnd == NULL) { - hMainWnd = hAmigaWnd; - registertouch(hAmigaWnd); + if (mon->hMainWnd == NULL) { + mon->hMainWnd = mon->hAmigaWnd; + registertouch(mon->hAmigaWnd); } else { - registertouch(hMainWnd); - registertouch(hAmigaWnd); + registertouch(mon->hMainWnd); + registertouch(mon->hAmigaWnd); } - updatewinrect (true); - GetWindowRect (hMainWnd, &mainwin_rect); + updatewinrect(mon, true); + GetWindowRect(mon->hMainWnd, &mon->mainwin_rect); if (dxfs || d3dfs) movecursor (x + w / 2, y + h / 2); - addnotifications (hAmigaWnd, FALSE, FALSE); - createblankwindows (); - - if (hMainWnd != hAmigaWnd) { - if (!currprefs.headless && !rp_isactive ()) - ShowWindow (hMainWnd, firstwindow ? (currprefs.win32_start_minimized ? SW_SHOWMINIMIZED : SW_SHOWDEFAULT) : SW_SHOWNORMAL); - UpdateWindow (hMainWnd); - } - if (!currprefs.headless && !rp_isactive ()) - ShowWindow (hAmigaWnd, SW_SHOWNORMAL); - UpdateWindow (hAmigaWnd); - firstwindow = false; - setDwmEnableMMCSS (true); - prevsbheight = sbheight; - rawinput_alloc(); - - if (currprefs.win32_shutdown_notification && !rp_isactive()) { - typedef BOOL(WINAPI *SHUTDOWNBLOCKREASONCREATE)(HWND, LPCWSTR); - SHUTDOWNBLOCKREASONCREATE pShutdownBlockReasonCreate; - pShutdownBlockReasonCreate = (SHUTDOWNBLOCKREASONCREATE)GetProcAddress(GetModuleHandle(_T("user32.dll")), "ShutdownBlockReasonCreate"); - if (pShutdownBlockReasonCreate) { - TCHAR tmp[MAX_DPATH]; - WIN32GUI_LoadUIString(IDS_SHUTDOWN_NOTIFICATION, tmp, MAX_DPATH); - if (!pShutdownBlockReasonCreate(hMainWnd, tmp)) { - write_log(_T("ShutdownBlockReasonCreate %08x\n"), GetLastError()); + addnotifications (mon->hAmigaWnd, FALSE, FALSE); + mon->prevsbheight = sbheight; + + if (mon->monitor_id) { + ShowWindow(mon->hMainWnd, SW_SHOWNOACTIVATE); + UpdateWindow(mon->hMainWnd); + ShowWindow(mon->hAmigaWnd, SW_SHOWNOACTIVATE); + UpdateWindow(mon->hAmigaWnd); + } else { + createblankwindows(); + if (mon->hMainWnd != mon->hAmigaWnd) { + if (!currprefs.headless && !rp_isactive()) + ShowWindow(mon->hMainWnd, firstwindow ? (currprefs.win32_start_minimized ? SW_SHOWMINIMIZED : SW_SHOWDEFAULT) : SW_SHOWNORMAL); + UpdateWindow(mon->hMainWnd); + } + if (!currprefs.headless && !rp_isactive()) + ShowWindow(mon->hAmigaWnd, SW_SHOWNORMAL); + UpdateWindow(mon->hAmigaWnd); + firstwindow = false; + setDwmEnableMMCSS(true); + rawinput_alloc(); + + if (currprefs.win32_shutdown_notification && !rp_isactive()) { + typedef BOOL(WINAPI *SHUTDOWNBLOCKREASONCREATE)(HWND, LPCWSTR); + SHUTDOWNBLOCKREASONCREATE pShutdownBlockReasonCreate; + pShutdownBlockReasonCreate = (SHUTDOWNBLOCKREASONCREATE)GetProcAddress(GetModuleHandle(_T("user32.dll")), "ShutdownBlockReasonCreate"); + if (pShutdownBlockReasonCreate) { + TCHAR tmp[MAX_DPATH]; + WIN32GUI_LoadUIString(IDS_SHUTDOWN_NOTIFICATION, tmp, MAX_DPATH); + if (!pShutdownBlockReasonCreate(mon->hMainWnd, tmp)) { + write_log(_T("ShutdownBlockReasonCreate %08x\n"), GetLastError()); + } } } } @@ -4451,17 +3740,17 @@ static int create_windows_2 (void) return 1; } -static int set_ddraw (void) +static int set_ddraw(struct AmigaMonitor *mon) { int cnt, ret; cnt = 3; for (;;) { - ret = set_ddraw_2 (); + ret = set_ddraw_2(mon); if (cnt-- <= 0) return 0; if (ret < 0) { - getbestmode (1); + getbestmode(mon, 1); continue; } if (ret == 0) @@ -4471,15 +3760,18 @@ static int set_ddraw (void) return 1; } -static void allocsoftbuffer (const TCHAR *name, struct vidbuffer *buf, int flags, int width, int height, int depth) +static void allocsoftbuffer(int monid, const TCHAR *name, struct vidbuffer *buf, int flags, int width, int height, int depth) { + struct vidbuf_description *vidinfo = &adisplays[monid].gfxvidinfo; + + buf->monitor_id = monid; buf->pixbytes = (depth + 7) / 8; buf->width_allocated = (width + 7) & ~7; buf->height_allocated = height; if (!(flags & DM_SWSCALE)) { - if (buf != &gfxvidinfo.drawbuffer) + if (buf != &vidinfo->drawbuffer) return; buf->bufmem = NULL; @@ -4488,7 +3780,7 @@ static void allocsoftbuffer (const TCHAR *name, struct vidbuffer *buf, int flags buf->bufmem_allocated = NULL; buf->bufmem_lockable = true; - write_log (_T("Reserved %s temp buffer (%d*%d*%d)\n"), name, width, height, depth); + write_log (_T("Mon %d reserved %s temp buffer (%d*%d*%d)\n"), monid, name, width, height, depth); } else if (flags & DM_SWSCALE) { @@ -4496,26 +3788,26 @@ static void allocsoftbuffer (const TCHAR *name, struct vidbuffer *buf, int flags int h = buf->height_allocated; int size = (w * 2) * (h * 2) * buf->pixbytes; buf->rowbytes = w * 2 * buf->pixbytes; - buf->realbufmem = xcalloc (uae_u8, size); + buf->realbufmem = xcalloc(uae_u8, size); buf->bufmem_allocated = buf->bufmem = buf->realbufmem + (h / 2) * buf->rowbytes + (w / 2) * buf->pixbytes; buf->bufmemend = buf->realbufmem + size - buf->rowbytes; buf->bufmem_lockable = true; - write_log (_T("Allocated %s temp buffer (%d*%d*%d) = %p\n"), name, width, height, depth, buf->realbufmem); + write_log (_T("Mon %d allocated %s temp buffer (%d*%d*%d) = %p\n"), monid, name, width, height, depth, buf->realbufmem); } } -static int create_windows (void) +static int create_windows(struct AmigaMonitor *mon) { - if (!create_windows_2 ()) + if (!create_windows_2(mon)) return 0; - return set_ddraw (); + return set_ddraw(mon); } static int oldtex_w, oldtex_h, oldtex_rtg; -static BOOL doInit (void) +static BOOL doInit(struct AmigaMonitor *mon) { int fs_warning = -1; TCHAR tmpstr[300]; @@ -4523,36 +3815,38 @@ static BOOL doInit (void) int ret = 0; retry: - remembered_vblank = -1; + struct vidbuf_description *avidinfo = &adisplays[mon->monitor_id].gfxvidinfo; + struct amigadisplay *ad = &adisplays[mon->monitor_id]; + if (wasfullwindow_a == 0) wasfullwindow_a = currprefs.gfx_apmode[0].gfx_fullscreen == GFX_FULLWINDOW ? 1 : -1; if (wasfullwindow_p == 0) wasfullwindow_p = currprefs.gfx_apmode[1].gfx_fullscreen == GFX_FULLWINDOW ? 1 : -1; - gfxmode_reset (); - freevidbuffer (&gfxvidinfo.drawbuffer); - freevidbuffer (&gfxvidinfo.tempbuffer); + gfxmode_reset(mon->monitor_id); + freevidbuffer(mon->monitor_id, &avidinfo->drawbuffer); + freevidbuffer(mon->monitor_id, &avidinfo->tempbuffer); for (;;) { - updatemodes (); - currentmode->native_depth = 0; - tmp_depth = currentmode->current_depth; + updatemodes(mon); + mon->currentmode.native_depth = 0; + tmp_depth = mon->currentmode.current_depth; - if (currentmode->flags & DM_W_FULLSCREEN) { + if (mon->currentmode.flags & DM_W_FULLSCREEN) { RECT rc = getdisplay (&currprefs)->rect; - currentmode->native_width = rc.right - rc.left; - currentmode->native_height = rc.bottom - rc.top; + mon->currentmode.native_width = rc.right - rc.left; + mon->currentmode.native_height = rc.bottom - rc.top; } - if (isfullscreen() <= 0 && !(currentmode->flags & (DM_D3D))) { - currentmode->current_depth = DirectDraw_GetCurrentDepth (); - updatemodes (); + if (isfullscreen() <= 0 && !(mon->currentmode.flags & (DM_D3D))) { + mon->currentmode.current_depth = DirectDraw_GetCurrentDepth (); + updatemodes(mon); } - if (!(currentmode->flags & (DM_D3D)) && DirectDraw_GetCurrentDepth () == currentmode->current_depth) { - updatemodes (); + if (!(mon->currentmode.flags & (DM_D3D)) && DirectDraw_GetCurrentDepth () == mon->currentmode.current_depth) { + updatemodes(mon); } - if (!rp_isactive () && (currentmode->current_width > GetSystemMetrics(SM_CXVIRTUALSCREEN) || - currentmode->current_height > GetSystemMetrics(SM_CYVIRTUALSCREEN))) { + if (!rp_isactive () && (mon->currentmode.current_width > GetSystemMetrics(SM_CXVIRTUALSCREEN) || + mon->currentmode.current_height > GetSystemMetrics(SM_CYVIRTUALSCREEN))) { if (!console_logging) fs_warning = IDS_UNSUPPORTEDSCREENMODE_3; } @@ -4566,70 +3860,70 @@ retry: _stprintf (tmpstr, szMessage, szMessage2); gui_message (tmpstr); DirectDraw_Start (); - if (screen_is_picasso) + if (mon->screen_is_picasso) changed_prefs.gfx_apmode[1].gfx_fullscreen = currprefs.gfx_apmode[1].gfx_fullscreen = GFX_FULLSCREEN; else changed_prefs.gfx_apmode[0].gfx_fullscreen = currprefs.gfx_apmode[0].gfx_fullscreen = GFX_FULLSCREEN; - updatewinfsmode (&currprefs); - updatewinfsmode (&changed_prefs); - currentmode->current_depth = tmp_depth; - updatemodes (); + updatewinfsmode(mon->monitor_id, &currprefs); + updatewinfsmode(mon->monitor_id, &changed_prefs); + mon->currentmode.current_depth = tmp_depth; + updatemodes(mon); ret = -2; goto oops; } - if (! create_windows ()) + if (!create_windows(mon)) goto oops; #ifdef PICASSO96 - if (screen_is_picasso) { + if (mon->screen_is_picasso) { break; } else { #endif - currentmode->native_depth = currentmode->current_depth; + struct uae_filter *usedfilter = mon->usedfilter; + mon->currentmode.native_depth = mon->currentmode.current_depth; - if (currprefs.gfx_resolution > gfxvidinfo.gfx_resolution_reserved) - gfxvidinfo.gfx_resolution_reserved = currprefs.gfx_resolution; - if (currprefs.gfx_vresolution > gfxvidinfo.gfx_vresolution_reserved) - gfxvidinfo.gfx_vresolution_reserved = currprefs.gfx_vresolution; + if (currprefs.gfx_resolution > avidinfo->gfx_resolution_reserved) + avidinfo->gfx_resolution_reserved = currprefs.gfx_resolution; + if (currprefs.gfx_vresolution > avidinfo->gfx_vresolution_reserved) + avidinfo->gfx_vresolution_reserved = currprefs.gfx_vresolution; //gfxvidinfo.drawbuffer.gfx_resolution_reserved = RES_SUPERHIRES; #if defined (GFXFILTER) - if (currentmode->flags & (DM_D3D | DM_SWSCALE)) { + if (mon->currentmode.flags & (DM_D3D | DM_SWSCALE)) { if (!currprefs.gfx_autoresolution) { - currentmode->amiga_width = AMIGA_WIDTH_MAX << currprefs.gfx_resolution; - currentmode->amiga_height = AMIGA_HEIGHT_MAX << currprefs.gfx_vresolution; + mon->currentmode.amiga_width = AMIGA_WIDTH_MAX << currprefs.gfx_resolution; + mon->currentmode.amiga_height = AMIGA_HEIGHT_MAX << currprefs.gfx_vresolution; } else { - currentmode->amiga_width = AMIGA_WIDTH_MAX << gfxvidinfo.gfx_resolution_reserved; - currentmode->amiga_height = AMIGA_HEIGHT_MAX << gfxvidinfo.gfx_vresolution_reserved; + mon->currentmode.amiga_width = AMIGA_WIDTH_MAX << avidinfo->gfx_resolution_reserved; + mon->currentmode.amiga_height = AMIGA_HEIGHT_MAX << avidinfo->gfx_vresolution_reserved; } - if (gfxvidinfo.gfx_resolution_reserved == RES_SUPERHIRES) - currentmode->amiga_height *= 2; - if (currentmode->amiga_height > 1280) - currentmode->amiga_height = 1280; + if (avidinfo->gfx_resolution_reserved == RES_SUPERHIRES) + mon->currentmode.amiga_height *= 2; + if (mon->currentmode.amiga_height > 1280) + mon->currentmode.amiga_height = 1280; - gfxvidinfo.drawbuffer.inwidth = gfxvidinfo.drawbuffer.outwidth = currentmode->amiga_width; - gfxvidinfo.drawbuffer.inheight = gfxvidinfo.drawbuffer.outheight = currentmode->amiga_height; + avidinfo->drawbuffer.inwidth = avidinfo->drawbuffer.outwidth = mon->currentmode.amiga_width; + avidinfo->drawbuffer.inheight = avidinfo->drawbuffer.outheight = mon->currentmode.amiga_height; if (usedfilter) { if ((usedfilter->flags & (UAE_FILTER_MODE_16 | UAE_FILTER_MODE_32)) == (UAE_FILTER_MODE_16 | UAE_FILTER_MODE_32)) { - currentmode->current_depth = currentmode->native_depth; + mon->currentmode.current_depth = mon->currentmode.native_depth; } else { - currentmode->current_depth = (usedfilter->flags & UAE_FILTER_MODE_32) ? 32 : 16; + mon->currentmode.current_depth = (usedfilter->flags & UAE_FILTER_MODE_32) ? 32 : 16; } } - currentmode->pitch = currentmode->amiga_width * currentmode->current_depth >> 3; + mon->currentmode.pitch = mon->currentmode.amiga_width * mon->currentmode.current_depth >> 3; } else #endif { - currentmode->amiga_width = currentmode->current_width; - currentmode->amiga_height = currentmode->current_height; + mon->currentmode.amiga_width = mon->currentmode.current_width; + mon->currentmode.amiga_height = mon->currentmode.current_height; } - gfxvidinfo.drawbuffer.pixbytes = currentmode->current_depth >> 3; - gfxvidinfo.drawbuffer.bufmem = NULL; - gfxvidinfo.drawbuffer.linemem = NULL; - gfxvidinfo.maxblocklines = 0; // flush_screen actually does everything - gfxvidinfo.drawbuffer.rowbytes = currentmode->pitch; + avidinfo->drawbuffer.pixbytes = mon->currentmode.current_depth >> 3; + avidinfo->drawbuffer.bufmem = NULL; + avidinfo->drawbuffer.linemem = NULL; + avidinfo->drawbuffer.rowbytes = mon->currentmode.pitch; break; #ifdef PICASSO96 } @@ -4637,127 +3931,136 @@ retry: } #ifdef PICASSO96 - picasso_vidinfo.rowbytes = 0; - picasso_vidinfo.pixbytes = currentmode->current_depth / 8; - picasso_vidinfo.rgbformat = 0; - picasso_vidinfo.extra_mem = 1; - picasso_vidinfo.height = currentmode->current_height; - picasso_vidinfo.width = currentmode->current_width; - picasso_vidinfo.depth = currentmode->current_depth; - picasso_vidinfo.offset = 0; + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[mon->monitor_id]; + vidinfo->rowbytes = 0; + vidinfo->pixbytes = mon->currentmode.current_depth / 8; + vidinfo->rgbformat = 0; + vidinfo->extra_mem = 1; + vidinfo->height = mon->currentmode.current_height; + vidinfo->width = mon->currentmode.current_width; + vidinfo->depth = mon->currentmode.current_depth; + vidinfo->offset = 0; #endif if (!scrlinebuf) scrlinebuf = xmalloc (uae_u8, max_uae_width * 4); - gfxvidinfo.drawbuffer.emergmem = scrlinebuf; // memcpy from system-memory to video-memory + avidinfo->drawbuffer.emergmem = scrlinebuf; // memcpy from system-memory to video-memory - gfxvidinfo.drawbuffer.realbufmem = NULL; - gfxvidinfo.drawbuffer.bufmem = NULL; - gfxvidinfo.drawbuffer.bufmem_allocated = NULL; - gfxvidinfo.drawbuffer.bufmem_lockable = false; + avidinfo->drawbuffer.realbufmem = NULL; + avidinfo->drawbuffer.bufmem = NULL; + avidinfo->drawbuffer.bufmem_allocated = NULL; + avidinfo->drawbuffer.bufmem_lockable = false; - gfxvidinfo.outbuffer = &gfxvidinfo.drawbuffer; - gfxvidinfo.inbuffer = &gfxvidinfo.drawbuffer; + avidinfo->outbuffer = &avidinfo->drawbuffer; + avidinfo->inbuffer = &avidinfo->drawbuffer; - if (!screen_is_picasso) { + if (!mon->screen_is_picasso) { if (currprefs.gfx_api == 0 && currprefs.gf[0].gfx_filter == 0) { - allocsoftbuffer (_T("draw"), &gfxvidinfo.drawbuffer, currentmode->flags, - currentmode->native_width, currentmode->native_height, currentmode->current_depth); + allocsoftbuffer(mon->monitor_id, _T("draw"), &avidinfo->drawbuffer, mon->currentmode.flags, + mon->currentmode.native_width, mon->currentmode.native_height, mon->currentmode.current_depth); } else { - allocsoftbuffer (_T("draw"), &gfxvidinfo.drawbuffer, currentmode->flags, - 1600, 1280, currentmode->current_depth); + allocsoftbuffer(mon->monitor_id, _T("draw"), &avidinfo->drawbuffer, mon->currentmode.flags, + 1600, 1280, mon->currentmode.current_depth); } if (currprefs.monitoremu || currprefs.cs_cd32fmv || (currprefs.genlock && currprefs.genlock_image) || currprefs.cs_color_burst || currprefs.gfx_grayscale) { - allocsoftbuffer (_T("monemu"), &gfxvidinfo.tempbuffer, currentmode->flags, - currentmode->amiga_width > 1024 ? currentmode->amiga_width : 1024, - currentmode->amiga_height > 1024 ? currentmode->amiga_height : 1024, - currentmode->current_depth); + allocsoftbuffer(mon->monitor_id, _T("monemu"), &avidinfo->tempbuffer, mon->currentmode.flags, + mon->currentmode.amiga_width > 1024 ? mon->currentmode.amiga_width : 1024, + mon->currentmode.amiga_height > 1024 ? mon->currentmode.amiga_height : 1024, + mon->currentmode.current_depth); } init_row_map (); } - init_colors (); + init_colors(mon->monitor_id); - S2X_free (); + S2X_free(mon->monitor_id); oldtex_w = oldtex_h = -1; - if (currentmode->flags & DM_D3D) { - const TCHAR *err = D3D_init (hAmigaWnd, currentmode->native_width, currentmode->native_height, currentmode->current_depth, ¤tmode->freq, screen_is_picasso ? 1 : currprefs.gf[picasso_on].gfx_filter_filtermode + 1); + if (mon->currentmode.flags & DM_D3D) { + const TCHAR *err = D3D_init (mon->hAmigaWnd, mon->monitor_id, mon->currentmode.native_width, mon->currentmode.native_height, mon->currentmode.current_depth, &mon->currentmode.freq, mon->screen_is_picasso ? 1 : currprefs.gf[ad->picasso_on].gfx_filter_filtermode + 1); if (err) { if (currprefs.gfx_api == 2) { - D3D_free(true); + D3D_free(0, true); if (err[0] == 0 && currprefs.color_mode != 5) { changed_prefs.color_mode = currprefs.color_mode = 5; - update_gfxparams(); + update_gfxparams(mon); goto retry; } changed_prefs.gfx_api = currprefs.gfx_api = 1; d3d_select(&currprefs); error_log(_T("Direct3D11 failed to initialize, falling back to Direct3D9.")); - err = D3D_init(hAmigaWnd, currentmode->native_width, currentmode->native_height, currentmode->current_depth, ¤tmode->freq, screen_is_picasso ? 1 : currprefs.gf[picasso_on].gfx_filter_filtermode + 1); + err = D3D_init(mon->hAmigaWnd, mon->monitor_id, mon->currentmode.native_width, mon->currentmode.native_height, mon->currentmode.current_depth, &mon->currentmode.freq, mon->screen_is_picasso ? 1 : currprefs.gf[ad->picasso_on].gfx_filter_filtermode + 1); } if (err) { - D3D_free(true); + D3D_free(0, true); error_log(_T("Direct3D9 failed to initialize, falling back to DirectDraw.")); changed_prefs.gfx_api = currprefs.gfx_api = 0; - changed_prefs.gf[picasso_on].gfx_filter = currprefs.gf[picasso_on].gfx_filter = 1; - currentmode->current_depth = currentmode->native_depth; - gfxmode_reset(); + changed_prefs.gf[ad->picasso_on].gfx_filter = currprefs.gf[ad->picasso_on].gfx_filter = 1; + mon->currentmode.current_depth = mon->currentmode.native_depth; + gfxmode_reset(mon->monitor_id); DirectDraw_Start(); ret = -1; goto oops; } } - target_graphics_buffer_update (); - updatewinrect (true); + target_graphics_buffer_update(mon->monitor_id); + updatewinrect(mon, true); } - screen_is_initialized = 1; - createstatusline(); - picasso_refresh (); + mon->screen_is_initialized = 1; + + display_param_init(mon); + + createstatusline(mon->monitor_id); + picasso_refresh(mon->monitor_id); #ifdef RETROPLATFORM rp_set_hwnd_delayed (); #endif if (isfullscreen () != 0) - setmouseactive (-1); + setmouseactive(mon->monitor_id, -1); return 1; oops: - close_hwnds (); + close_hwnds(mon); return ret; } -bool target_graphics_buffer_update (void) +bool target_graphics_buffer_update(int monid) { + struct AmigaMonitor *mon = &AMonitors[monid]; + struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; + struct vidbuf_description *avidinfo = &adisplays[0].gfxvidinfo; + struct picasso96_state_struct *state = &picasso96_state[monid]; + static bool graphicsbuffer_retry; int w, h; graphicsbuffer_retry = false; - if (screen_is_picasso) { - w = picasso96_state.Width > picasso_vidinfo.width ? picasso96_state.Width : picasso_vidinfo.width; - h = picasso96_state.Height > picasso_vidinfo.height ? picasso96_state.Height : picasso_vidinfo.height; + if (mon->screen_is_picasso) { + w = state->Width > vidinfo->width ? state->Width : vidinfo->width; + h = state->Height > vidinfo->height ? state->Height : vidinfo->height; } else { - struct vidbuffer *vb = gfxvidinfo.drawbuffer.tempbufferinuse ? &gfxvidinfo.tempbuffer : &gfxvidinfo.drawbuffer; - gfxvidinfo.outbuffer = vb; + struct vidbuffer *vb = avidinfo->drawbuffer.tempbufferinuse ? &avidinfo->tempbuffer : &avidinfo->drawbuffer; + avidinfo->outbuffer = vb; w = vb->outwidth; h = vb->outheight; } - if (oldtex_w == w && oldtex_h == h && oldtex_rtg == screen_is_picasso) + if (oldtex_w == w && oldtex_h == h && oldtex_rtg == mon->screen_is_picasso) return false; if (!w || !h) { oldtex_w = w; oldtex_h = h; - oldtex_rtg = screen_is_picasso; + oldtex_rtg = mon->screen_is_picasso; return false; } - S2X_free (); - if (currentmode->flags & DM_D3D) { - if (!D3D_alloctexture (w, h)) { + S2X_free(mon->monitor_id); + if (mon->currentmode.flags & DM_D3D) { + if (!D3D_alloctexture(mon->monitor_id, w, h)) { graphicsbuffer_retry = true; return false; } @@ -4767,55 +4070,71 @@ bool target_graphics_buffer_update (void) oldtex_w = w; oldtex_h = h; - oldtex_rtg = screen_is_picasso; + oldtex_rtg = mon->screen_is_picasso; - write_log (_T("Buffer size (%d*%d) %s\n"), w, h, screen_is_picasso ? _T("RTG") : _T("Native")); + write_log (_T("Buffer size (%d*%d) %s\n"), w, h, mon->screen_is_picasso ? _T("RTG") : _T("Native")); - if ((currentmode->flags & DM_SWSCALE) && !screen_is_picasso) { - if (!S2X_init (currentmode->native_width, currentmode->native_height, currentmode->native_depth)) + if ((mon->currentmode.flags & DM_SWSCALE) && !mon->screen_is_picasso) { + if (!S2X_init(mon->monitor_id, mon->currentmode.native_width, mon->currentmode.native_height, mon->currentmode.native_depth)) return false; } return true; } -void updatedisplayarea (void) +void updatedisplayarea(int monid) { - if (!screen_is_initialized) + struct AmigaMonitor *mon = &AMonitors[monid]; + struct amigadisplay *ad = &adisplays[monid]; + if (!mon->screen_is_initialized) return; if (dx_islost ()) return; #if defined (GFXFILTER) - if (currentmode->flags & DM_D3D) { + if (mon->currentmode.flags & DM_D3D) { #if defined (D3D) - D3D_refresh (); + D3D_refresh(monid); #endif } else #endif - if (currentmode->flags & DM_DDRAW) { + if (mon->currentmode.flags & DM_DDRAW) { #if defined (GFXFILTER) - if (!picasso_on) { - if (currentmode->flags & DM_SWSCALE) - S2X_refresh (); + if (!ad->picasso_on) { + if (mon->currentmode.flags & DM_SWSCALE) + S2X_refresh(monid); } #endif DirectDraw_Flip (0); } } -void updatewinfsmode (struct uae_prefs *p) +void updatewinfsmode(int monid, struct uae_prefs *p) { struct MultiDisplay *md; fixup_prefs_dimensions (p); if (isfullscreen_2 (p) != 0) { - p->gfx_size = p->gfx_size_fs; + p->gfx_monitor[monid].gfx_size = p->gfx_monitor[monid].gfx_size_fs; } else { - p->gfx_size = p->gfx_size_win; + p->gfx_monitor[monid].gfx_size = p->gfx_monitor[monid].gfx_size_win; } md = getdisplay (p); set_config_changed (); } +bool toggle_3d_debug(void) +{ + if (isvsync_chipset() < 0) { + if (D3D_debug) { + int d = D3D_debug(0, 0); + D3D_debug(0, d ? 0 : 1); + } + return true; + } + return false; +} + + + int rtg_index = -1; // -2 = default @@ -4823,10 +4142,16 @@ int rtg_index = -1; // 0 = chipset // 1..4 = rtg // 5 = next -bool toggle_rtg (int mode) +bool toggle_rtg (int monid, int mode) { + struct amigadisplay *ad = &adisplays[monid]; + int old_index = rtg_index; + if (monid > 0) { + return true; + } + if (mode < -1 && rtg_index >= 0) return true; @@ -4844,18 +4169,19 @@ bool toggle_rtg (int mode) rtg_index = MAX_RTG_BOARDS - 1; } if (rtg_index < 0) { - if (picasso_on) { - gfxboard_rtg_disable(old_index); - picasso_requested_on = false; + if (ad->picasso_on) { + gfxboard_rtg_disable(monid, old_index); + ad->picasso_requested_on = false; statusline_add_message(STATUSTYPE_DISPLAY, _T("Chipset display")); + set_config_changed(); return false; } return false; } struct rtgboardconfig *r = &currprefs.rtgboards[rtg_index]; - if (r->rtgmem_size > 0) { + if (r->rtgmem_size > 0 && r->monitor_id == monid) { if (r->rtgmem_type >= GFXBOARD_HARDWARE) { - int idx = gfxboard_toggle(rtg_index, mode >= -1); + int idx = gfxboard_toggle(r->monitor_id, rtg_index, mode >= -1); if (idx >= 0) { rtg_index = idx; return true; @@ -4865,23 +4191,25 @@ bool toggle_rtg (int mode) return false; } } else { - gfxboard_toggle(-1, -1); + gfxboard_toggle(r->monitor_id, -1, -1); if (mode < -1) return true; - gfxboard_rtg_disable(old_index); + gfxboard_rtg_disable(monid, old_index); // can always switch from RTG to custom - if (picasso_requested_on && picasso_on) { - picasso_requested_on = false; + if (ad->picasso_requested_on && ad->picasso_on) { + ad->picasso_requested_on = false; rtg_index = -1; + set_config_changed(); return true; } - if (picasso_on) + if (ad->picasso_on) return false; // can only switch from custom to RTG if there is some mode active - if (picasso_is_active ()) { - picasso_enablescreen(1); - picasso_requested_on = true; + if (picasso_is_active(r->monitor_id)) { + picasso_enablescreen(r->monitor_id, 1); + ad->picasso_requested_on = true; statusline_add_message(STATUSTYPE_DISPLAY, _T("RTG %d: %s"), rtg_index + 1, _T("UAEGFX")); + set_config_changed(); return true; } } @@ -4894,10 +4222,16 @@ bool toggle_rtg (int mode) return false; } -void toggle_fullscreen (int mode) +void close_rtg(int monid) +{ + close_windows(&AMonitors[monid]); +} + +void toggle_fullscreen(int monid, int mode) { - int *p = picasso_on ? &changed_prefs.gfx_apmode[1].gfx_fullscreen : &changed_prefs.gfx_apmode[0].gfx_fullscreen; - int wfw = picasso_on ? wasfullwindow_p : wasfullwindow_a; + struct amigadisplay *ad = &adisplays[monid]; + int *p = ad->picasso_on ? &changed_prefs.gfx_apmode[1].gfx_fullscreen : &changed_prefs.gfx_apmode[0].gfx_fullscreen; + int wfw = ad->picasso_on ? wasfullwindow_p : wasfullwindow_a; int v = *p; if (mode < 0) { @@ -4933,21 +4267,18 @@ void toggle_fullscreen (int mode) v = GFX_WINDOW; } *p = v; - updatewinfsmode (&changed_prefs); + updatewinfsmode(monid, &changed_prefs); } -HDC gethdc (void) +HDC gethdc(void) { HDC hdc = 0; - frame_missed = frame_counted = frame_errors = 0; - frame_usage = frame_usage_avg = frame_usage_total = 0; - #ifdef D3D - if (D3D_isenabled ()) - return D3D_getDC (0); + if (D3D_isenabled(0)) + return D3D_getDC(0, 0); #endif - if(FAILED (DirectDraw_GetDC (&hdc))) + if(FAILED(DirectDraw_GetDC(&hdc))) hdc = 0; return hdc; } @@ -4955,10 +4286,10 @@ HDC gethdc (void) void releasehdc (HDC hdc) { #ifdef D3D - if (D3D_isenabled ()) { - D3D_getDC (hdc); + if (D3D_isenabled(0)) { + D3D_getDC(0, hdc); return; } #endif - DirectDraw_ReleaseDC (hdc); + DirectDraw_ReleaseDC(hdc); } diff --git a/od-win32/win32gfx.h b/od-win32/win32gfx.h index 770212d9..e5af53ed 100644 --- a/od-win32/win32gfx.h +++ b/od-win32/win32gfx.h @@ -11,30 +11,27 @@ extern void sortdisplays (void); extern void enumeratedisplays (void); extern void reenumeratemonitors(void); -int WIN32GFX_IsPicassoScreen (void); -int WIN32GFX_GetWidth (void); -int WIN32GFX_GetHeight(void); -int WIN32GFX_GetDepth (int real); -void WIN32GFX_DisplayChangeRequested (int); -void DX_Invalidate (int x, int y, int width, int height); - -int WIN32GFX_AdjustScreenmode (struct MultiDisplay *md, int *pwidth, int *pheight, int *ppixbits); +int WIN32GFX_IsPicassoScreen(struct AmigaMonitor*); +int WIN32GFX_GetWidth(struct AmigaMonitor*); +int WIN32GFX_GetHeight(struct AmigaMonitor*); +int WIN32GFX_GetDepth(struct AmigaMonitor*, int real); +void WIN32GFX_DisplayChangeRequested(int); +void DX_Invalidate(struct AmigaMonitor*, int x, int y, int width, int height); + +int WIN32GFX_AdjustScreenmode(struct MultiDisplay *md, int *pwidth, int *pheight, int *ppixbits); extern HCURSOR normalcursor; -extern HWND hStatusWnd; -extern HBRUSH hStatusBkgB; extern int default_freq; extern int normal_display_change_starting; extern int window_led_drives, window_led_drives_end; extern int window_led_hd, window_led_hd_end; extern int window_led_joys, window_led_joys_end, window_led_joy_start; extern int window_led_msg, window_led_msg_end, window_led_msg_start; -extern int scalepicasso; extern HDC gethdc (void); extern void releasehdc (HDC hdc); -extern void close_windows (void); -extern void updatewinfsmode (struct uae_prefs *p); +extern void close_windows(struct AmigaMonitor*); +extern void updatewinfsmode(int monid, struct uae_prefs *p); extern int is3dmode (void); extern void gfx_lock (void); extern void gfx_unlock (void); @@ -42,11 +39,9 @@ extern void gfx_unlock (void); extern bool lockscr3d(struct vidbuffer *vb); extern void unlockscr3d(struct vidbuffer *vb); -void DX_Fill (int dstx, int dsty, int width, int height, uae_u32 color); -void DX_Blit (int x, int y, int w, int h); -void centerdstrect (RECT *); +void DX_Fill(struct AmigaMonitor*, int dstx, int dsty, int width, int height, uae_u32 color); +void DX_Blit(int x, int y, int w, int h); +void centerdstrect(struct AmigaMonitor*, RECT *); struct MultiDisplay *getdisplay (struct uae_prefs *p); -double getcurrentvblankrate (void); -void vblank_reset (double freq); -extern int getrefreshrate (int width, int height); +extern int getrefreshrate(int monid, int width, int height); #endif diff --git a/od-win32/win32gui.cpp b/od-win32/win32gui.cpp index 69860f03..4de8c181 100644 --- a/od-win32/win32gui.cpp +++ b/od-win32/win32gui.cpp @@ -97,6 +97,7 @@ #include "rp.h" #endif #include "ini.h" +#include "specialmonitors.h" #define GUI_SCALE_DEFAULT 100 #define MIN_GUI_INTERNAL_WIDTH 512 @@ -2211,22 +2212,25 @@ static bool gui_resize_allowed; // Internal panel max size: 396, 318 static int mm = 0; -static void m (void) -{ - write_log (_T("%d:0: %dx%d %dx%d %dx%d\n"), mm, currprefs.gfx_size.width, currprefs.gfx_size.height, - workprefs.gfx_size.width, workprefs.gfx_size.height, changed_prefs.gfx_size.width, changed_prefs.gfx_size.height); - write_log (_T("%d:1: %dx%d %dx%d %dx%d\n"), mm, currprefs.gfx_size_fs.width, currprefs.gfx_size_fs.height, - workprefs.gfx_size_fs.width, workprefs.gfx_size_fs.height, changed_prefs.gfx_size_fs.width, changed_prefs.gfx_size_fs.height); +static void m(int monid) +{ + struct monconfig *gmw = &workprefs.gfx_monitor[monid]; + struct monconfig *gmc = &currprefs.gfx_monitor[monid]; + struct monconfig *gmh = &changed_prefs.gfx_monitor[monid]; + write_log (_T("%d:0: %dx%d %dx%d %dx%d\n"), mm, gmc->gfx_size.width, gmc->gfx_size.height, + gmw->gfx_size.width, gmw->gfx_size.height, gmh->gfx_size.width, gmh->gfx_size.height); + write_log (_T("%d:1: %dx%d %dx%d %dx%d\n"), mm, gmc->gfx_size_fs.width, gmc->gfx_size_fs.height, + gmw->gfx_size_fs.width, gmw->gfx_size_fs.height, gmh->gfx_size_fs.width, gmh->gfx_size_fs.height); mm++; } -static void flipgui (int opengui) +static void flipgui(int opengui) { - D3D_guimode (opengui); + D3D_guimode(0, opengui); if (opengui) { DirectDraw_FlipToGDISurface(); } else { - vblank_reset(-1); + ;// vblank_reset(-1); } } @@ -2234,6 +2238,9 @@ static int GetSettings (int all_options, HWND hwnd); /* if drive is -1, show the full GUI, otherwise file-requester for DF[drive] */ void gui_display (int shortcut) { + struct AmigaMonitor *mon = &AMonitors[0]; + struct picasso96_state_struct *state = &picasso96_state[0]; + struct monconfig *gm = &currprefs.gfx_monitor[0]; static int here; int w, h; @@ -2250,45 +2257,45 @@ void gui_display (int shortcut) inputdevice_unacquire (); wait_keyrelease(); clearallkeys (); - setmouseactive (0); + setmouseactive(0, 0); } w = h = -1; - if (!WIN32GFX_IsPicassoScreen () && currprefs.gfx_apmode[0].gfx_fullscreen && (currprefs.gfx_size.width < gui_width || currprefs.gfx_size.height < gui_height)) { - w = currprefs.gfx_size.width; - h = currprefs.gfx_size.height; + if (!WIN32GFX_IsPicassoScreen(mon) && currprefs.gfx_apmode[0].gfx_fullscreen && (gm->gfx_size.width < gui_width || gm->gfx_size.height < gui_height)) { + w = gm->gfx_size.width; + h = gm->gfx_size.height; } - if (WIN32GFX_IsPicassoScreen () && currprefs.gfx_apmode[1].gfx_fullscreen && (picasso96_state.Width < gui_width || picasso96_state.Height < gui_height)) { - w = currprefs.gfx_size.width; - h = currprefs.gfx_size.height; + if (WIN32GFX_IsPicassoScreen(mon) && currprefs.gfx_apmode[1].gfx_fullscreen && (state->Width < gui_width || state->Height < gui_height)) { + w = gm->gfx_size.width; + h = gm->gfx_size.height; } - manual_painting_needed++; /* So that WM_PAINT will refresh the display */ + mon->manual_painting_needed++; /* So that WM_PAINT will refresh the display */ flush_log (); if (shortcut == -1) { int ret; - ret = GetSettings (0, hAmigaWnd); + ret = GetSettings(0, mon->hAmigaWnd); if (!ret) { savestate_state = 0; } } else if (shortcut >= 0 && shortcut < 4) { - DiskSelection (hAmigaWnd, IDC_DF0 + shortcut, 0, &changed_prefs, NULL, NULL); + DiskSelection(mon->hAmigaWnd, IDC_DF0 + shortcut, 0, &changed_prefs, NULL, NULL); } else if (shortcut == 5) { - if (DiskSelection (hAmigaWnd, IDC_DOSAVESTATE, 9, &changed_prefs, NULL, NULL)) + if (DiskSelection(mon->hAmigaWnd, IDC_DOSAVESTATE, 9, &changed_prefs, NULL, NULL)) save_state (savestate_fname, _T("Description!")); } else if (shortcut == 4) { - if (DiskSelection (hAmigaWnd, IDC_DOLOADSTATE, 10, &changed_prefs, NULL, NULL)) + if (DiskSelection(mon->hAmigaWnd, IDC_DOLOADSTATE, 10, &changed_prefs, NULL, NULL)) savestate_state = STATE_DORESTORE; } - manual_painting_needed--; /* So that WM_PAINT doesn't need to use custom refreshing */ + mon->manual_painting_needed--; /* So that WM_PAINT doesn't need to use custom refreshing */ reset_sound (); inputdevice_copyconfig (&changed_prefs, &currprefs); inputdevice_config_change_test (); clearallkeys (); if (resumepaused (7)) { inputdevice_acquire (TRUE); - setmouseactive (1); + setmouseactive(0, 1); } flipgui(0); fpscounter_reset (); @@ -2298,7 +2305,7 @@ void gui_display (int shortcut) here--; } -static void prefs_to_gui (struct uae_prefs *p) +static void prefs_to_gui(struct uae_prefs *p) { int st = savestate_state; default_prefs(&workprefs, false, 0); @@ -2306,12 +2313,12 @@ static void prefs_to_gui (struct uae_prefs *p) /* filesys hack */ workprefs.mountitems = currprefs.mountitems; memcpy (&workprefs.mountconfig, &currprefs.mountconfig, MOUNT_CONFIG_SIZE * sizeof (struct uaedev_config_info)); - updatewinfsmode (&workprefs); + updatewinfsmode(0, &workprefs); if (workprefs.statefile[0]) savestate_state = st; } -static void gui_to_prefs (void) +static void gui_to_prefs(void) { /* Always copy our prefs to changed_prefs, ... */ copy_prefs(&workprefs, &changed_prefs); @@ -2319,7 +2326,7 @@ static void gui_to_prefs (void) currprefs.mountitems = changed_prefs.mountitems; memcpy (&currprefs.mountconfig, &changed_prefs.mountconfig, MOUNT_CONFIG_SIZE * sizeof (struct uaedev_config_info)); fixup_prefs (&changed_prefs, true); - updatewinfsmode (&changed_prefs); + updatewinfsmode(0, &changed_prefs); } static int iscd (int n) @@ -2357,6 +2364,7 @@ static void setfilter (int num, int *filter, const TCHAR *fname) static UINT_PTR CALLBACK ofnhook (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { + struct AmigaMonitor *mon = &AMonitors[0]; HWND hWnd; RECT windowRect; int width, height, w2, h2, x, y; @@ -2379,8 +2387,8 @@ static UINT_PTR CALLBACK ofnhook (HWND hDlg, UINT message, WPARAM wParam, LPARAM md = getdisplay (&currprefs); if (!md) return FALSE; - w2 = WIN32GFX_GetWidth (); - h2 = WIN32GFX_GetHeight (); + w2 = WIN32GFX_GetWidth(mon); + h2 = WIN32GFX_GetHeight(mon); write_log (_T("MOVEWINDOW %dx%d %dx%d (%dx%d)\n"), md->rect.left, md->rect.top, md->rect.right, md->rect.bottom, w2, h2); windowRect.left = windowRect.right = windowRect.top = windowRect.bottom = -1; GetWindowRect (hWnd, &windowRect); @@ -6287,6 +6295,7 @@ static struct amigamodels amodels[] = { { 4, IDS_QS_MODEL_CD32 }, // "CD32" { 4, IDS_QS_MODEL_CDTV }, // "CDTV" { 4, IDS_QS_MODEL_ARCADIA }, // "Arcadia" + { 1, IDS_QS_MODEL_CASABLANCA }, { 1, IDS_QS_MODEL_UAE }, // "Expanded UAE example configuration" { -1 } }; @@ -6835,8 +6844,12 @@ static void enable_for_displaydlg (HWND hDlg) ew (hDlg, IDC_LM_IDOUBLED2, !workprefs.gfx_autoresolution && isdouble); ew (hDlg, IDC_LM_IDOUBLED3, !workprefs.gfx_autoresolution && isdouble); - hide(hDlg, IDC_DISPLAY_TEARING, TRUE); - //hide(hDlg, IDC_DISPLAY_TEARING, !(workprefs.gfx_api == 2 && (can_D3D11(false) & 2))); + if (workprefs.gfx_apmode[0].gfx_vsyncmode == 1 || workprefs.gfx_apmode[0].gfx_vsyncmode == 2) { + ew(hDlg, IDC_SCREENMODE_NATIVE3, TRUE); + } else { + ew(hDlg, IDC_SCREENMODE_NATIVE3, FALSE); + } + } static void enable_for_chipsetdlg (HWND hDlg) @@ -6860,6 +6873,8 @@ static void enable_for_chipsetdlg (HWND hDlg) ew(hDlg, IDC_GENLOCK_KEEP_ASPECT, workprefs.genlock ? TRUE : FALSE); ew(hDlg, IDC_GENLOCKFILE, workprefs.genlock && (workprefs.genlock_image >= 6 || (workprefs.genlock_image >= 3 && workprefs.genlock_image < 5)) ? TRUE : FALSE); ew(hDlg, IDC_GENLOCKFILESELECT, workprefs.genlock && (workprefs.genlock_image >= 6 || (workprefs.genlock_image >= 3 && workprefs.genlock_image < 5)) ? TRUE : FALSE); + + ew(hDlg, IDC_MONITOREMU_MON, workprefs.monitoremu != 0); } static const int fakerefreshrates[] = { 50, 60, 100, 120, 0 }; @@ -7043,9 +7058,9 @@ static void update_da (HWND hDlg) currprefs.gfx_contrast = workprefs.gfx_contrast; currprefs.gfx_threebitcolors = workprefs.gfx_threebitcolors; set_da (hDlg); - init_colors (); - init_custom (); - updatedisplayarea (); + init_colors(0); + init_custom(); + updatedisplayarea(0); } static void handle_da (HWND hDlg) @@ -7095,6 +7110,7 @@ static void init_display_mode (HWND hDlg) int d, d2, index; int i, cnt; struct MultiDisplay *md = getdisplay (&workprefs); + struct monconfig *gm = &workprefs.gfx_monitor[0]; switch (workprefs.color_mode) { @@ -7109,7 +7125,7 @@ static void init_display_mode (HWND hDlg) if (workprefs.gfx_apmode[0].gfx_fullscreen) { d2 = d; - if ((index = WIN32GFX_AdjustScreenmode (md, &workprefs.gfx_size_fs.width, &workprefs.gfx_size_fs.height, &d2)) >= 0) { + if ((index = WIN32GFX_AdjustScreenmode (md, &gm->gfx_size_fs.width, &gm->gfx_size_fs.height, &d2)) >= 0) { switch (d2) { case 15: @@ -7128,15 +7144,15 @@ static void init_display_mode (HWND hDlg) d = d / 8; } - if (workprefs.gfx_size_fs.special == WH_NATIVE) { + if (gm->gfx_size_fs.special == WH_NATIVE) { int cnt = (int)SendDlgItemMessage (hDlg, IDC_RESOLUTION, CB_GETCOUNT, 0, 0); SendDlgItemMessage (hDlg, IDC_RESOLUTION, CB_SETCURSEL, cnt - 1, 0); - index = display_mode_index (workprefs.gfx_size_fs.width, workprefs.gfx_size_fs.height, d); + index = display_mode_index (gm->gfx_size_fs.width, gm->gfx_size_fs.height, d); } else { - index = display_mode_index (workprefs.gfx_size_fs.width, workprefs.gfx_size_fs.height, d); + index = display_mode_index (gm->gfx_size_fs.width, gm->gfx_size_fs.height, d); if (index >= 0) SendDlgItemMessage (hDlg, IDC_RESOLUTION, CB_SETCURSEL, md->DisplayModes[index].residx, 0); - workprefs.gfx_size_fs.special = 0; + gm->gfx_size_fs.special = 0; } SendDlgItemMessage(hDlg, IDC_RESOLUTIONDEPTH, CB_RESETCONTENT, 0, 0); cnt = 0; @@ -7232,8 +7248,8 @@ static void values_to_displaydlg (HWND hDlg) init_display_mode (hDlg); - SetDlgItemInt (hDlg, IDC_XSIZE, workprefs.gfx_size_win.width, FALSE); - SetDlgItemInt (hDlg, IDC_YSIZE, workprefs.gfx_size_win.height, FALSE); + SetDlgItemInt (hDlg, IDC_XSIZE, workprefs.gfx_monitor[0].gfx_size_win.width, FALSE); + SetDlgItemInt (hDlg, IDC_YSIZE, workprefs.gfx_monitor[0].gfx_size_win.height, FALSE); SendDlgItemMessage(hDlg, IDC_RATE2BOX, CB_RESETCONTENT, 0, 0); v = 0; @@ -7276,6 +7292,7 @@ static void values_to_displaydlg (HWND hDlg) SendDlgItemMessage(hDlg, IDC_SCREENMODE_NATIVE, CB_RESETCONTENT, 0, 0); SendDlgItemMessage(hDlg, IDC_SCREENMODE_NATIVE2, CB_RESETCONTENT, 0, 0); + SendDlgItemMessage(hDlg, IDC_SCREENMODE_NATIVE3, CB_RESETCONTENT, 0, 0); WIN32GUI_LoadUIString(IDS_SCREEN_WINDOWED, buffer, sizeof buffer / sizeof (TCHAR)); SendDlgItemMessage(hDlg, IDC_SCREENMODE_NATIVE, CB_ADDSTRING, 0, (LPARAM)buffer); @@ -7294,8 +7311,11 @@ static void values_to_displaydlg (HWND hDlg) SendDlgItemMessage(hDlg, IDC_SCREENMODE_NATIVE2, CB_ADDSTRING, 0, (LPARAM)buffer); WIN32GUI_LoadUIString(IDS_SCREEN_VSYNC_AUTOSWITCH, buffer, sizeof buffer / sizeof(TCHAR)); SendDlgItemMessage(hDlg, IDC_SCREENMODE_NATIVE2, CB_ADDSTRING, 0, (LPARAM)buffer); - WIN32GUI_LoadUIString(IDS_SCREEN_ADAPTIVE_SYNC, buffer, sizeof buffer / sizeof(TCHAR)); - SendDlgItemMessage(hDlg, IDC_SCREENMODE_NATIVE2, CB_ADDSTRING, 0, (LPARAM)buffer); + + for (int i = 1; i < 30; i++) { + _stprintf(buffer, _T("%d"), i); + SendDlgItemMessage(hDlg, IDC_SCREENMODE_NATIVE3, CB_ADDSTRING, 0, (LPARAM)buffer); + } SendDlgItemMessage(hDlg, IDC_SCREENMODE_NATIVE, CB_SETCURSEL, workprefs.gfx_apmode[0].gfx_fullscreen, 0); @@ -7307,6 +7327,9 @@ static void values_to_displaydlg (HWND hDlg) } SendDlgItemMessage(hDlg, IDC_SCREENMODE_NATIVE2, CB_SETCURSEL, v, 0); + SendDlgItemMessage(hDlg, IDC_SCREENMODE_NATIVE3, CB_SETCURSEL, workprefs.gfx_display_sections - 1, 0); + + SendDlgItemMessage(hDlg, IDC_SCREENMODE_RTG, CB_RESETCONTENT, 0, 0); SendDlgItemMessage(hDlg, IDC_SCREENMODE_RTG2, CB_RESETCONTENT, 0, 0); @@ -7326,8 +7349,6 @@ static void values_to_displaydlg (HWND hDlg) #endif WIN32GUI_LoadUIString(IDS_SCREEN_VSYNC2, buffer, sizeof buffer / sizeof (TCHAR)); SendDlgItemMessage(hDlg, IDC_SCREENMODE_RTG2, CB_ADDSTRING, 0, (LPARAM)buffer); - WIN32GUI_LoadUIString(IDS_SCREEN_ADAPTIVE_SYNC, buffer, sizeof buffer / sizeof(TCHAR)); - SendDlgItemMessage(hDlg, IDC_SCREENMODE_RTG2, CB_ADDSTRING, 0, (LPARAM)buffer); #if 0 WIN32GUI_LoadUIString(IDS_SCREEN_VSYNC2_AUTOSWITCH, buffer, sizeof buffer / sizeof (TCHAR)); SendDlgItemMessage(hDlg, IDC_SCREENMODE_RTG2, CB_ADDSTRING, 0, (LPARAM)buffer); @@ -7391,7 +7412,7 @@ static void values_to_displaydlg (HWND hDlg) SendDlgItemMessage(hDlg, IDC_DISPLAY_BUFFERCNT, CB_ADDSTRING, 0, (LPARAM)buffer); SendDlgItemMessage (hDlg, IDC_DISPLAY_BUFFERCNT, CB_SETCURSEL, workprefs.gfx_apmode[0].gfx_backbuffers, 0); - CheckDlgButton(hDlg, IDC_DISPLAY_TEARING, workprefs.gfx_apmode[0].gfx_tearing); + CheckDlgButton(hDlg, IDC_DISPLAY_VARSYNC, workprefs.gfx_variable_sync != 0); init_da (hDlg); } @@ -7492,8 +7513,9 @@ static void values_from_displaydlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l { BOOL success = FALSE; int i; - int gfx_width = workprefs.gfx_size_win.width; - int gfx_height = workprefs.gfx_size_win.height; + struct monconfig *gm = &workprefs.gfx_monitor[0]; + int gfx_width = gm->gfx_size_win.width; + int gfx_height = gm->gfx_size_win.height; LRESULT posn; TCHAR tmp[200]; @@ -7553,6 +7575,10 @@ static void values_from_displaydlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l workprefs.gfx_apmode[0].gfx_vsyncmode = 0; } + i = SendDlgItemMessage(hDlg, IDC_SCREENMODE_NATIVE3, CB_GETCURSEL, 0, 0); + if (i >= 0 && i < 100) + workprefs.gfx_display_sections = i + 1; + workprefs.gfx_apmode[1].gfx_fullscreen = SendDlgItemMessage (hDlg, IDC_SCREENMODE_RTG, CB_GETCURSEL, 0, 0); i = SendDlgItemMessage (hDlg, IDC_SCREENMODE_RTG2, CB_GETCURSEL, 0, 0); workprefs.gfx_apmode[1].gfx_vsync = 0; @@ -7631,16 +7657,16 @@ static void values_from_displaydlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l SendDlgItemMessage (hDlg, IDC_FRAMERATE2, TBM_SETPOS, TRUE, (LPARAM)cr->rate); } - workprefs.gfx_size_win.width = GetDlgItemInt (hDlg, IDC_XSIZE, &success, FALSE); + gm->gfx_size_win.width = GetDlgItemInt (hDlg, IDC_XSIZE, &success, FALSE); if(!success) - workprefs.gfx_size_win.width = 800; - workprefs.gfx_size_win.height = GetDlgItemInt (hDlg, IDC_YSIZE, &success, FALSE); + gm->gfx_size_win.width = 800; + gm->gfx_size_win.height = GetDlgItemInt (hDlg, IDC_YSIZE, &success, FALSE); if(!success) - workprefs.gfx_size_win.height = 600; + gm->gfx_size_win.height = 600; workprefs.gfx_xcenter = ischecked (hDlg, IDC_XCENTER) ? 2 : 0; /* Smart centering */ workprefs.gfx_ycenter = ischecked (hDlg, IDC_YCENTER) ? 2 : 0; /* Smart centering */ - workprefs.gfx_apmode[0].gfx_tearing = ischecked(hDlg, IDC_DISPLAY_TEARING); + workprefs.gfx_variable_sync = ischecked(hDlg, IDC_DISPLAY_VARSYNC) ? 1 : 0; LRESULT posn1 = SendDlgItemMessage (hDlg, IDC_AUTORESOLUTIONSELECT, CB_GETCURSEL, 0, 0); if (posn1 != CB_ERR) { @@ -7666,7 +7692,7 @@ static void values_from_displaydlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l if (posn1 != CB_ERR) { if (posn2 == CB_ERR) posn2 = 0; - workprefs.gfx_size_fs.special = 0; + workprefs.gfx_monitor[0].gfx_size_fs.special = 0; for (dmode = 0; md->DisplayModes[dmode].depth >= 0; dmode++) { if (md->DisplayModes[dmode].residx == posn1) break; @@ -7677,7 +7703,7 @@ static void values_from_displaydlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l md->DisplayModes[dmode].res.height == md->rect.bottom - md->rect.top && md->DisplayModes[dmode].depth == gui_display_depths[posn2]) { - workprefs.gfx_size_fs.special = WH_NATIVE; + workprefs.gfx_monitor[0].gfx_size_fs.special = WH_NATIVE; break; } } @@ -7710,8 +7736,8 @@ static void values_from_displaydlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l if (posn != CB_ERR) workprefs.gfx_resolution = posn; } else if ((LOWORD (wParam) == IDC_RESOLUTION || LOWORD(wParam) == IDC_RESOLUTIONDEPTH) && dmode >= 0) { - workprefs.gfx_size_fs.width = md->DisplayModes[dmode].res.width; - workprefs.gfx_size_fs.height = md->DisplayModes[dmode].res.height; + workprefs.gfx_monitor[0].gfx_size_fs.width = md->DisplayModes[dmode].res.width; + workprefs.gfx_monitor[0].gfx_size_fs.height = md->DisplayModes[dmode].res.height; switch(md->DisplayModes[dmode].depth) { case 2: @@ -7726,8 +7752,8 @@ static void values_from_displaydlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l break; } /* Set the Int boxes */ - SetDlgItemInt (hDlg, IDC_XSIZE, workprefs.gfx_size_win.width, FALSE); - SetDlgItemInt (hDlg, IDC_YSIZE, workprefs.gfx_size_win.height, FALSE); + SetDlgItemInt (hDlg, IDC_XSIZE, workprefs.gfx_monitor[0].gfx_size_win.width, FALSE); + SetDlgItemInt (hDlg, IDC_YSIZE, workprefs.gfx_monitor[0].gfx_size_win.height, FALSE); init_display_mode (hDlg); //init_frequency_combo (hDlg, dmode); } else if (LOWORD (wParam) == IDC_REFRESHRATE && dmode >= 0) { @@ -7751,7 +7777,7 @@ static void values_from_displaydlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l } } - updatewinfsmode (&workprefs); + updatewinfsmode(0, &workprefs); } static int hw3d_changed; @@ -7852,6 +7878,7 @@ static void values_to_chipsetdlg (HWND hDlg) CheckDlgButton(hDlg, IDC_CYCLEEXACTMEMORY, workprefs.cpu_memory_cycle_exact); SendDlgItemMessage(hDlg, IDC_CS_EXT, CB_SETCURSEL, workprefs.cs_compatible, 0); SendDlgItemMessage(hDlg, IDC_MONITOREMU, CB_SETCURSEL, workprefs.monitoremu, 0); + SendDlgItemMessage(hDlg, IDC_MONITOREMU_MON, CB_SETCURSEL, workprefs.monitoremu_mon, 0); SendDlgItemMessage(hDlg, IDC_GENLOCKMODE, CB_SETCURSEL, workprefs.genlock_image, 0); SendDlgItemMessage(hDlg, IDC_GENLOCKMIX, CB_SETCURSEL, workprefs.genlock_mix / 25, 0); CheckDlgButton(hDlg, IDC_GENLOCK_ALPHA, workprefs.genlock_alpha); @@ -7938,9 +7965,12 @@ static void values_from_chipsetdlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l cs_compatible = nn; built_in_chipset_prefs (&workprefs); } - nn = SendDlgItemMessage (hDlg, IDC_MONITOREMU, CB_GETCURSEL, 0, 0); + nn = SendDlgItemMessage(hDlg, IDC_MONITOREMU, CB_GETCURSEL, 0, 0); if (nn != CB_ERR) workprefs.monitoremu = nn; + nn = SendDlgItemMessage(hDlg, IDC_MONITOREMU_MON, CB_GETCURSEL, 0, 0); + if (nn != CB_ERR) + workprefs.monitoremu_mon = nn; nn = SendDlgItemMessage(hDlg, IDC_GENLOCKMODE, CB_GETCURSEL, 0, 0); if (nn != CB_ERR && nn != workprefs.genlock_image) { @@ -8021,17 +8051,16 @@ static INT_PTR CALLBACK ChipsetDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPAR SendDlgItemMessage(hDlg, IDC_MONITOREMU, CB_ADDSTRING, 0, (LPARAM)_T("-")); WIN32GUI_LoadUIString(IDS_AUTODETECT, buffer, sizeof buffer / sizeof (TCHAR)); SendDlgItemMessage(hDlg, IDC_MONITOREMU, CB_ADDSTRING, 0, (LPARAM)buffer); - SendDlgItemMessage(hDlg, IDC_MONITOREMU, CB_ADDSTRING, 0, (LPARAM)_T("A2024 (Commodore)")); - SendDlgItemMessage(hDlg, IDC_MONITOREMU, CB_ADDSTRING, 0, (LPARAM)_T("Graffiti (Individual Computers)")); - SendDlgItemMessage(hDlg, IDC_MONITOREMU, CB_ADDSTRING, 0, (LPARAM)_T("HAM-E (Black Belt Systems)")); - SendDlgItemMessage(hDlg, IDC_MONITOREMU, CB_ADDSTRING, 0, (LPARAM)_T("HAM-E Plus (Black Belt Systems)")); - SendDlgItemMessage(hDlg, IDC_MONITOREMU, CB_ADDSTRING, 0, (LPARAM)_T("Video DAC 18 (Newtronic)")); - SendDlgItemMessage(hDlg, IDC_MONITOREMU, CB_ADDSTRING, 0, (LPARAM)_T("AVideo 12 (Archos)")); - SendDlgItemMessage(hDlg, IDC_MONITOREMU, CB_ADDSTRING, 0, (LPARAM)_T("AVideo 24 (Archos)")); - SendDlgItemMessage(hDlg, IDC_MONITOREMU, CB_ADDSTRING, 0, (LPARAM)_T("FireCracker 24 (Impulse)")); - SendDlgItemMessage(hDlg, IDC_MONITOREMU, CB_ADDSTRING, 0, (LPARAM)_T("DCTV (Digital Creations)")); - SendDlgItemMessage(hDlg, IDC_MONITOREMU, CB_ADDSTRING, 0, (LPARAM)_T("OpalVision (Opal Technologies)")); - SendDlgItemMessage(hDlg, IDC_MONITOREMU, CB_ADDSTRING, 0, (LPARAM)_T("ColorBurst (M.A.S.T.)")); + for (int i = 0; specialmonitorfriendlynames[i]; i++) { + _stprintf(buffer, _T("%s (%s)"), specialmonitorfriendlynames[i], specialmonitormanufacturernames[i]); + SendDlgItemMessage(hDlg, IDC_MONITOREMU, CB_ADDSTRING, 0, (LPARAM)buffer); + } + + SendDlgItemMessage(hDlg, IDC_MONITOREMU_MON, CB_RESETCONTENT, 0, 0); + for (int i = 0; i < MAX_AMIGAMONITORS; i++) { + _stprintf(buffer, _T("%d"), i + 1); + SendDlgItemMessage(hDlg, IDC_MONITOREMU_MON, CB_ADDSTRING, 0, (LPARAM)buffer); + } #ifndef AGA ew (hDlg, IDC_AGA, FALSE); @@ -9677,7 +9706,7 @@ static void updatecpuboardsubtypes(HWND hDlg) #endif } -static int rtg_index; +static int gui_rtg_index; static void expansion2filebuttons(HWND hDlg, WPARAM wParam, TCHAR *path) { @@ -9932,13 +9961,14 @@ static void enable_for_expansiondlg(HWND hDlg) en = !!full_property_sheet; - int rtg = workprefs.rtgboards[rtg_index].rtgmem_size && full_property_sheet && workprefs.rtgboards[rtg_index].rtgmem_type < GFXBOARD_HARDWARE; - int rtg2 = workprefs.rtgboards[rtg_index].rtgmem_size || workprefs.rtgboards[rtg_index].rtgmem_type >= GFXBOARD_HARDWARE; - int rtg3 = workprefs.rtgboards[rtg_index].rtgmem_size && workprefs.rtgboards[rtg_index].rtgmem_type < GFXBOARD_HARDWARE; - int rtg4 = workprefs.rtgboards[rtg_index].rtgmem_type < GFXBOARD_HARDWARE; + int rtg = workprefs.rtgboards[gui_rtg_index].rtgmem_size && full_property_sheet && workprefs.rtgboards[gui_rtg_index].rtgmem_type < GFXBOARD_HARDWARE; + int rtg2 = workprefs.rtgboards[gui_rtg_index].rtgmem_size || workprefs.rtgboards[gui_rtg_index].rtgmem_type >= GFXBOARD_HARDWARE; + int rtg3 = workprefs.rtgboards[gui_rtg_index].rtgmem_size && workprefs.rtgboards[gui_rtg_index].rtgmem_type < GFXBOARD_HARDWARE; + int rtg4 = workprefs.rtgboards[gui_rtg_index].rtgmem_type < GFXBOARD_HARDWARE; + int rtg5 = workprefs.rtgboards[gui_rtg_index].rtgmem_size && full_property_sheet; int rtg0 = rtg2; - if (rtg_index > 0) { + if (gui_rtg_index > 0) { rtg = false; rtg2 = false; rtg3 = false; @@ -9947,6 +9977,7 @@ static void enable_for_expansiondlg(HWND hDlg) ew(hDlg, IDC_P96RAM, rtg0); ew(hDlg, IDC_P96MEM, rtg0); ew(hDlg, IDC_RTG_Z2Z3, z3); + ew(hDlg, IDC_MONITOREMU_MON, rtg5); ew(hDlg, IDC_RTG_8BIT, rtg); ew(hDlg, IDC_RTG_16BIT, rtg); ew(hDlg, IDC_RTG_24BIT, rtg); @@ -9974,7 +10005,7 @@ static void values_to_expansiondlg(HWND hDlg) int min_mem = MIN_P96_MEM; int max_mem = MAX_P96_MEM_Z3; - struct rtgboardconfig *rbc = &workprefs.rtgboards[rtg_index]; + struct rtgboardconfig *rbc = &workprefs.rtgboards[gui_rtg_index]; if (gfxboard_get_configtype(rbc) == 2) { int v = rbc->rtgmem_size; max_mem = MAX_P96_MEM_Z2; @@ -10031,7 +10062,8 @@ static void values_to_expansiondlg(HWND hDlg) SetDlgItemText(hDlg, IDC_P96RAM, memsize_names[msi_gfx[mem_size]]); SendDlgItemMessage(hDlg, IDC_RTG_Z2Z3, CB_SETCURSEL, rbc->rtgmem_size == 0 ? 0 : rbc->rtgmem_type + 1, 0); - SendDlgItemMessage(hDlg, IDC_RTG_NUM, CB_SETCURSEL, rtg_index, 0); + SendDlgItemMessage(hDlg, IDC_MONITOREMU_MON, CB_SETCURSEL, rbc->monitor_id, 0); + SendDlgItemMessage(hDlg, IDC_RTG_NUM, CB_SETCURSEL, gui_rtg_index, 0); SendDlgItemMessage(hDlg, IDC_RTG_8BIT, CB_SETCURSEL, (workprefs.picasso96_modeflags & RGBFF_CLUT) ? 1 : 0, 0); SendDlgItemMessage(hDlg, IDC_RTG_16BIT, CB_SETCURSEL, (manybits(workprefs.picasso96_modeflags, RGBFF_R5G6B5PC | RGBFF_R5G6B5PC | RGBFF_R5G6B5 | RGBFF_R5G5B5 | RGBFF_B5G6R5PC | RGBFF_B5G5R5PC)) ? 1 : @@ -10107,6 +10139,12 @@ static INT_PTR CALLBACK ExpansionDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP SendDlgItemMessage(hDlg, IDC_RTG_NUM, CB_ADDSTRING, 0, (LPARAM)tmp); } + SendDlgItemMessage(hDlg, IDC_MONITOREMU_MON, CB_RESETCONTENT, 0, 0); + for (int i = 0; i < MAX_AMIGAMONITORS; i++) { + _stprintf(tmp, _T("%d"), i + 1); + SendDlgItemMessage(hDlg, IDC_MONITOREMU_MON, CB_ADDSTRING, 0, (LPARAM)tmp); + } + SendDlgItemMessage (hDlg, IDC_RTG_Z2Z3, CB_RESETCONTENT, 0, 0); SendDlgItemMessage (hDlg, IDC_RTG_Z2Z3, CB_ADDSTRING, 0, (LPARAM)_T("-")); v = 0; @@ -10150,7 +10188,7 @@ static INT_PTR CALLBACK ExpansionDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP SendDlgItemMessage (hDlg, IDC_RTG_32BIT, CB_ADDSTRING, 0, (LPARAM)_T("A8B8G8R8")); SendDlgItemMessage (hDlg, IDC_RTG_32BIT, CB_ADDSTRING, 0, (LPARAM)_T("R8G8B8A8")); SendDlgItemMessage (hDlg, IDC_RTG_32BIT, CB_ADDSTRING, 0, (LPARAM)_T("B8G8R8A8 (*)")); - SendDlgItemMessage (hDlg, IDC_P96MEM, TBM_SETRANGE, TRUE, MAKELONG (MIN_P96_MEM, gfxboard_get_configtype(&workprefs.rtgboards[rtg_index]) == 3 ? MAX_P96_MEM_Z3 : MAX_P96_MEM_Z2)); + SendDlgItemMessage (hDlg, IDC_P96MEM, TBM_SETRANGE, TRUE, MAKELONG (MIN_P96_MEM, gfxboard_get_configtype(&workprefs.rtgboards[gui_rtg_index]) == 3 ? MAX_P96_MEM_Z3 : MAX_P96_MEM_Z2)); SendDlgItemMessage (hDlg, IDC_RTG_SCALE_ASPECTRATIO, CB_RESETCONTENT, 0, 0); WIN32GUI_LoadUIString (IDS_DISABLED, tmp, sizeof tmp / sizeof (TCHAR)); SendDlgItemMessage (hDlg, IDC_RTG_SCALE_ASPECTRATIO, CB_ADDSTRING, 0, (LPARAM)tmp); @@ -10178,7 +10216,7 @@ static INT_PTR CALLBACK ExpansionDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP break; case WM_HSCROLL: - workprefs.rtgboards[rtg_index].rtgmem_size = memsizes[msi_gfx[SendMessage (GetDlgItem (hDlg, IDC_P96MEM), TBM_GETPOS, 0, 0)]]; + workprefs.rtgboards[gui_rtg_index].rtgmem_size = memsizes[msi_gfx[SendMessage (GetDlgItem (hDlg, IDC_P96MEM), TBM_GETPOS, 0, 0)]]; values_to_expansiondlg(hDlg); enable_for_expansiondlg(hDlg); break; @@ -10242,21 +10280,28 @@ static INT_PTR CALLBACK ExpansionDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP case IDC_RTG_NUM: v = SendDlgItemMessage(hDlg, IDC_RTG_NUM, CB_GETCURSEL, 0, 0L); if (v != CB_ERR) { - rtg_index = v; + gui_rtg_index = v; values_to_expansiondlg(hDlg); enable_for_expansiondlg(hDlg); } break; + case IDC_MONITOREMU_MON: + v = SendDlgItemMessage(hDlg, IDC_MONITOREMU_MON, CB_GETCURSEL, 0, 0L); + if (v != CB_ERR) { + workprefs.rtgboards[gui_rtg_index].monitor_id = v; + values_to_expansiondlg(hDlg); + } + break; case IDC_RTG_Z2Z3: v = SendDlgItemMessage (hDlg, IDC_RTG_Z2Z3, CB_GETCURSEL, 0, 0L); if (v != CB_ERR) { if (v == 0) { - workprefs.rtgboards[rtg_index].rtgmem_type = 1; - workprefs.rtgboards[rtg_index].rtgmem_size = 0; + workprefs.rtgboards[gui_rtg_index].rtgmem_type = 1; + workprefs.rtgboards[gui_rtg_index].rtgmem_size = 0; } else { - workprefs.rtgboards[rtg_index].rtgmem_type = v - 1; - if (workprefs.rtgboards[rtg_index].rtgmem_size == 0) - workprefs.rtgboards[rtg_index].rtgmem_size = 4096 * 1024; + workprefs.rtgboards[gui_rtg_index].rtgmem_type = v - 1; + if (workprefs.rtgboards[gui_rtg_index].rtgmem_size == 0) + workprefs.rtgboards[gui_rtg_index].rtgmem_size = 4096 * 1024; } cfgfile_compatibility_rtg(&workprefs); enable_for_expansiondlg (hDlg); @@ -14715,8 +14760,9 @@ static int getfloppybox (HWND hDlg, int f_text, TCHAR *out, int maxlen, int type bool gui_ask_disk(int drv, TCHAR *name) { + struct AmigaMonitor *mon = &AMonitors[0]; _tcscpy(changed_prefs.floppyslots[drv].df, name); - DiskSelection (hAmigaWnd, IDC_DF0 + drv, 22, &changed_prefs, NULL, NULL); + DiskSelection(mon->hAmigaWnd, IDC_DF0 + drv, 22, &changed_prefs, NULL, NULL); _tcscpy(name, changed_prefs.floppyslots[drv].df); return true; } @@ -18584,7 +18630,7 @@ static void filter_handle (HWND hDlg) } } enable_for_hw3ddlg (hDlg); - updatedisplayarea (); + updatedisplayarea(0); } static INT_PTR CALLBACK hw3dDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) @@ -18688,7 +18734,7 @@ static INT_PTR CALLBACK hw3dDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM currprefs.gf[filter_nativertg].gfx_filter_horiz_zoom_mult = workprefs.gf[filter_nativertg].gfx_filter_horiz_zoom_mult = 1.0; currprefs.gf[filter_nativertg].gfx_filter_vert_zoom_mult = workprefs.gf[filter_nativertg].gfx_filter_vert_zoom_mult = 1.0; values_to_hw3ddlg (hDlg); - updatedisplayarea (); + updatedisplayarea(0); break; case IDC_FILTERPRESETLOAD: case IDC_FILTERPRESETSAVE: @@ -18705,14 +18751,14 @@ static INT_PTR CALLBACK hw3dDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM currprefs.gf[filter_nativertg].gfx_filter_keep_aspect = workprefs.gf[filter_nativertg].gfx_filter_keep_aspect = 0; enable_for_hw3ddlg (hDlg); values_to_hw3ddlg (hDlg); - updatedisplayarea (); + updatedisplayarea(0); } case IDC_FILTERKEEPAUTOSCALEASPECT: { workprefs.gf[filter_nativertg].gfx_filter_keep_autoscale_aspect = currprefs.gf[filter_nativertg].gfx_filter_keep_autoscale_aspect = ischecked (hDlg, IDC_FILTERKEEPAUTOSCALEASPECT) ? 1 : 0; enable_for_hw3ddlg (hDlg); values_to_hw3ddlg (hDlg); - updatedisplayarea (); + updatedisplayarea(0); } break; default: @@ -18770,7 +18816,7 @@ static INT_PTR CALLBACK hw3dDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM item = SendDlgItemMessage (hDlg, IDC_FILTERSLR, CB_GETCURSEL, 0, 0L); if (item != CB_ERR) { currprefs.gf[filter_nativertg].gfx_filter_scanlineratio = workprefs.gf[filter_nativertg].gfx_filter_scanlineratio = scanlineindexes[item]; - updatedisplayarea (); + updatedisplayarea(0); } break; case IDC_FILTEROVERLAYTYPE: @@ -18788,11 +18834,11 @@ static INT_PTR CALLBACK hw3dDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM break; case IDC_FILTERHZMULT: currprefs.gf[filter_nativertg].gfx_filter_horiz_zoom_mult = workprefs.gf[filter_nativertg].gfx_filter_horiz_zoom_mult = getfiltermult (hDlg, IDC_FILTERHZMULT); - updatedisplayarea (); + updatedisplayarea(0); break; case IDC_FILTERVZMULT: currprefs.gf[filter_nativertg].gfx_filter_vert_zoom_mult = workprefs.gf[filter_nativertg].gfx_filter_vert_zoom_mult = getfiltermult (hDlg, IDC_FILTERVZMULT); - updatedisplayarea (); + updatedisplayarea(0); break; case IDC_FILTERASPECT: { @@ -18807,7 +18853,7 @@ static INT_PTR CALLBACK hw3dDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM v2 = getaspectratio (v - 2); } currprefs.gf[filter_nativertg].gfx_filter_aspect = workprefs.gf[filter_nativertg].gfx_filter_aspect = v2; - updatedisplayarea (); + updatedisplayarea(0); } break; case IDC_FILTERASPECT2: @@ -18815,7 +18861,7 @@ static INT_PTR CALLBACK hw3dDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM int v = SendDlgItemMessage (hDlg, IDC_FILTERASPECT2, CB_GETCURSEL, 0, 0L); if (v != CB_ERR) currprefs.gf[filter_nativertg].gfx_filter_keep_aspect = workprefs.gf[filter_nativertg].gfx_filter_keep_aspect = v; - updatedisplayarea (); + updatedisplayarea(0); } break; @@ -18893,10 +18939,10 @@ static INT_PTR CALLBACK hw3dDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM SetDlgItemInt (hDlg, IDC_FILTERXLV, v, TRUE); } if (!full_property_sheet) { - init_colors (); + init_colors(0); notice_new_xcolors (); } - updatedisplayarea (); + updatedisplayarea(0); recursive--; break; } @@ -18909,7 +18955,7 @@ static INT_PTR CALLBACK hw3dDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM static void values_to_avioutputdlg (HWND hDlg) { - updatewinfsmode (&workprefs); + updatewinfsmode(0, &workprefs); SetDlgItemText (hDlg, IDC_AVIOUTPUT_FILETEXT, avioutput_filename_gui); CheckDlgButton (hDlg, IDC_AVIOUTPUT_FRAMELIMITER, avioutput_framelimiter ? FALSE : TRUE); CheckDlgButton (hDlg, IDC_AVIOUTPUT_NOSOUNDOUTPUT, avioutput_nosoundoutput ? TRUE : FALSE); @@ -19147,7 +19193,7 @@ static INT_PTR CALLBACK AVIOutputDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP AVIOutput_Toggle (!avioutput_requested, false); break; case IDC_SCREENSHOT: - screenshot(1, 0); + screenshot(0, 1, 0); break; case IDC_AVIOUTPUT_AUDIO: { @@ -19734,11 +19780,11 @@ static void createTreeView (HWND hDlg) static int dialog_x_offset, dialog_y_offset; -static bool dodialogmousemove (void) +static bool dodialogmousemove(void) { if (full_property_sheet || isfullscreen () <= 0) return false; - if (isfullscreen () > 0 && currprefs.gfx_size_fs.width > gui_width && currprefs.gfx_size.height > gui_height) + if (isfullscreen () > 0 && currprefs.gfx_monitor[0].gfx_size_fs.width > gui_width && currprefs.gfx_monitor[0].gfx_size.height > gui_height) return false; if (currprefs.gfx_api == 2) return false; @@ -19870,6 +19916,7 @@ static bool draghit(DWORD id, POINT pt) int dragdrop (HWND hDlg, HDROP hd, struct uae_prefs *prefs, int currentpage) { + struct AmigaMonitor *mon = &AMonitors[0]; int cnt, i, drv, harddrive, drvdrag, firstdrv; TCHAR file[MAX_DPATH]; TCHAR *filepart = NULL; @@ -19888,9 +19935,9 @@ int dragdrop (HWND hDlg, HDROP hd, struct uae_prefs *prefs, int currentpage) drv = harddrive = 0; drvdrag = 0; if (currentpage < 0) { - GetClientRect (hMainWnd, &r2); - if (hStatusWnd) { - GetClientRect (hStatusWnd, &r); + GetClientRect(mon->hMainWnd, &r2); + if (mon->hStatusWnd) { + GetClientRect(mon->hStatusWnd, &r); if (pt.y >= r2.bottom && pt.y < r2.bottom + r.bottom) { if (pt.x >= window_led_drives && pt.x < window_led_drives_end && window_led_drives > 0) { drv = pt.x - window_led_drives; @@ -20453,6 +20500,7 @@ static RECT dialog_rect; static void dialogmousemove (HWND hDlg) { + struct AmigaMonitor *mon = &AMonitors[0]; static int newmx, newmy; RECT rc; POINT pt; @@ -20465,7 +20513,7 @@ static void dialogmousemove (HWND hDlg) if (!dodialogmousemove ()) return; pmi.cbSize = sizeof (pmi); - GetMonitorInfo (MonitorFromWindow (hAmigaWnd, MONITOR_DEFAULTTOPRIMARY), (LPMONITORINFO)&pmi); + GetMonitorInfo (MonitorFromWindow (mon->hAmigaWnd, MONITOR_DEFAULTTOPRIMARY), (LPMONITORINFO)&pmi); xstart = pmi.rcMonitor.left; ystart = pmi.rcMonitor.top; GetCursorPos (&pt); @@ -20654,7 +20702,7 @@ static int GetSettings (int all_options, HWND hwnd) write_log(_T("GUI Fullscreen %dx%d, closing fullscreen.\n"), gui_width, gui_height); hwnd = currprefs.win32_notaskbarbutton ? hHiddenWnd : NULL; closed = true; - close_windows(); + close_windows(&AMonitors[0]); } else { gui_width = w; gui_height = h; @@ -20679,9 +20727,9 @@ static int GetSettings (int all_options, HWND hwnd) DragAcceptFiles(hwnd, TRUE); fmultx = 0; - write_log (_T("Requested GUI size = %dx%d (%dx%d)\n"), gui_width, gui_height, workprefs.gfx_size.width, workprefs.gfx_size.height); + write_log (_T("Requested GUI size = %dx%d (%dx%d)\n"), gui_width, gui_height, workprefs.gfx_monitor[0].gfx_size.width, workprefs.gfx_monitor[0].gfx_size.height); if (dodialogmousemove () && isfullscreen() > 0) { - if (gui_width >= workprefs.gfx_size.width || gui_height >= workprefs.gfx_size.height) { + if (gui_width >= workprefs.gfx_monitor[0].gfx_size.width || gui_height >= workprefs.gfx_monitor[0].gfx_size.height) { write_log (_T("GUI larger than screen, resize disabled\n")); gui_resize_allowed = false; } @@ -20876,8 +20924,6 @@ void gui_exit (void) #endif } -extern HWND hStatusWnd; - void check_prefs_changed_gui (void) { } @@ -20967,6 +21013,9 @@ void gui_fps (int fps, int idle, int color) #define LED_STRING_WIDTH 40 void gui_led (int led, int on, int brightness) { + int monid = 0; + struct AmigaMonitor *mon = &AMonitors[monid]; + struct amigadisplay *ad = &adisplays[monid]; WORD type; static TCHAR drive_text[NUM_LEDS * LED_STRING_WIDTH]; static TCHAR dfx[4][300]; @@ -20986,7 +21035,7 @@ void gui_led (int led, int on, int brightness) } rp_update_leds (led, on, brightness, writing); #endif - if (!hStatusWnd) + if (!mon->hStatusWnd) return; tt = NULL; if (led >= LED_DF0 && led <= LED_DF3) { @@ -21041,18 +21090,18 @@ void gui_led (int led, int on, int brightness) writing = 1; } else if (led == LED_FPS) { double fps = (double)gui_data.fps / 10.0; - extern double p96vblank; + extern float p96vblank; pos = 2; ptr = drive_text + pos * LED_STRING_WIDTH; if (fps > 9999.9) fps = 9999.9; if (fps < 1000) { - if (picasso_on) + if (ad->picasso_on) _stprintf (ptr, _T("%.1f [%.1f]"), p96vblank, fps); else _stprintf (ptr, _T("FPS: %.1f"), fps); } else { - if (picasso_on) + if (ad->picasso_on) _stprintf(ptr, _T("%.0f [%.0f]"), p96vblank, fps); else _stprintf(ptr, _T("FPS: %.0f"), fps); @@ -21146,9 +21195,9 @@ void gui_led (int led, int on, int brightness) if (active2) ptr[_tcslen (ptr) + 1] |= 16; pos += window_led_joy_start; - PostMessage (hStatusWnd, SB_SETTEXT, (WPARAM)((pos + 1) | type), (LPARAM)ptr); + PostMessage(mon->hStatusWnd, SB_SETTEXT, (WPARAM)((pos + 1) | type), (LPARAM)ptr); if (tt != NULL) - PostMessage (hStatusWnd, SB_SETTIPTEXT, (WPARAM)(pos + 1), (LPARAM)tt); + PostMessage(mon->hStatusWnd, SB_SETTIPTEXT, (WPARAM)(pos + 1), (LPARAM)tt); } } @@ -21158,15 +21207,16 @@ void gui_filename (int num, const TCHAR *name) static int fsdialog (HWND *hwnd, DWORD *flags) { + struct AmigaMonitor *mon = &AMonitors[0]; if (gui_active) { *hwnd = guiDlg; *flags |= MB_SETFOREGROUND; return 0; } - *hwnd = hMainWnd; + *hwnd = mon->hMainWnd; if (isfullscreen () <= 0) return 0; - *hwnd = hAmigaWnd; + *hwnd = mon->hAmigaWnd; flipgui (true); *flags |= MB_SETFOREGROUND; *flags |= MB_TOPMOST; @@ -21185,12 +21235,13 @@ static int fsdialog (HWND *hwnd, DWORD *flags) int gui_message_multibutton (int flags, const TCHAR *format,...) { + struct AmigaMonitor *mon = &AMonitors[0]; TCHAR msg[2048]; TCHAR szTitle[MAX_DPATH]; va_list parms; int flipflop = 0; int fullscreen = 0; - int focuso = isfocus (); + int focuso = isfocus(); int ret; DWORD mbflags; HWND hwnd; @@ -21207,7 +21258,7 @@ int gui_message_multibutton (int flags, const TCHAR *format,...) if (!gui_active) { pause_sound (); if (flipflop) - ShowWindow (hAmigaWnd, SW_MINIMIZE); + ShowWindow(mon->hAmigaWnd, SW_MINIMIZE); } va_start (parms, format); @@ -21224,10 +21275,10 @@ int gui_message_multibutton (int flags, const TCHAR *format,...) if (!gui_active) { flipgui (false); if (flipflop) - ShowWindow (hAmigaWnd, SW_RESTORE); + ShowWindow(mon->hAmigaWnd, SW_RESTORE); reset_sound (); resume_sound (); - setmouseactive (focuso > 0 ? 1 : 0); + setmouseactive(0, focuso > 0 ? 1 : 0); } if (ret == IDOK) return 0; @@ -21242,12 +21293,13 @@ int gui_message_multibutton (int flags, const TCHAR *format,...) void gui_message (const TCHAR *format,...) { + struct AmigaMonitor *mon = &AMonitors[0]; TCHAR msg[2048]; TCHAR szTitle[MAX_DPATH]; va_list parms; int flipflop = 0; int fullscreen = 0; - int focuso = isfocus (); + int focuso = isfocus(); DWORD flags = MB_OK; HWND hwnd; @@ -21264,7 +21316,7 @@ void gui_message (const TCHAR *format,...) if (!gui_active) { pause_sound (); if (flipflop) - ShowWindow (hAmigaWnd, SW_MINIMIZE); + ShowWindow(mon->hAmigaWnd, SW_MINIMIZE); } if (hwnd == NULL) flags |= MB_TASKMODAL; @@ -21281,10 +21333,10 @@ void gui_message (const TCHAR *format,...) if (!gui_active) { flipgui (false); if (flipflop) - ShowWindow (hAmigaWnd, SW_RESTORE); + ShowWindow(mon->hAmigaWnd, SW_RESTORE); reset_sound (); resume_sound (); - setmouseactive (focuso > 0 ? 1 : 0); + setmouseactive(0, focuso > 0 ? 1 : 0); } } diff --git a/od-win32/win32gui_extra.cpp b/od-win32/win32gui_extra.cpp index ccd42825..3e322c24 100644 --- a/od-win32/win32gui_extra.cpp +++ b/od-win32/win32gui_extra.cpp @@ -7,6 +7,7 @@ #include "sysconfig.h" #include "sysdeps.h" +#include "options.h" #include "resource.h" #include "registry.h" #include "win32.h" diff --git a/od-win32/winuae_msvc15/winuae_msvc.vcxproj b/od-win32/winuae_msvc15/winuae_msvc.vcxproj index 90ef1399..99989db4 100644 --- a/od-win32/winuae_msvc15/winuae_msvc.vcxproj +++ b/od-win32/winuae_msvc15/winuae_msvc.vcxproj @@ -156,26 +156,26 @@ winuae64 winuae64 winuae64 - $(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\ucrt;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\shared;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\winrt;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\um;C:\dev\include;$(IncludePath) - $(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\shared;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\ucrt;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\um;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\winrt;C:\dev\include;$(IncludePath) - $(MSBuildProgramFiles32)\Windows Kits\10\lib\10.0.10240.0\ucrt\$(PlatformShortName);C:\dev\lib;$(LibraryPath) - $(MSBuildProgramFiles32)\Windows Kits\10\lib\10.0.16299.0\ucrt\$(PlatformShortName);C:\dev\lib;$(LibraryPath) - C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;C:\dev\lib;C:\dev\WinDDK\7600.16385.1\lib\win7\i386;$(LibraryPath) - C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;C:\dev\include;$(IncludePath) - $(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\ucrt;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\winrt;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\um;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\shared;C:\dev\include;$(IncludePath) - $(ReferencePath) - $(MSBuildProgramFiles32)\Windows Kits\10\lib\10.0.16299.0\ucrt\$(PlatformShortName);C:\dev\lib;$(LibraryPath) + $(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\ucrt;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\winrt;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\um;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\shared;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\km;c:\dev\include;$(IncludePath) + $(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\ucrt;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\winrt;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\um;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\shared;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\km;c:\dev\include;$(IncludePath) + C:\dev\lib;$(LibraryPath) + C:\dev\lib;$(LibraryPath) + C:\dev\lib;$(LibraryPath) + $(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\ucrt;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\winrt;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\um;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\shared;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\km;c:\dev\include;$(IncludePath) + $(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\ucrt;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\winrt;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\um;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\shared;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\km;c:\dev\include;$(IncludePath) + $(VC_ReferencesPath_x86); + C:\dev\lib;$(LibraryPath) true true true true - C:\dev\include;C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;$(IncludePath) - C:\dev\lib\x64;C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64;$(LibraryPath) - C:\dev\include;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\winrt;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\um;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\shared;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\ucrt;$(IncludePath) - C:\dev\include;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\winrt;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\shared;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\ucrt;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\um;$(IncludePath) + $(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\ucrt;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\winrt;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\um;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\shared;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\km;c:\dev\include;$(IncludePath) + C:\dev\lib\x64;$(LibraryPath) + $(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\ucrt;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\winrt;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\um;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\shared;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\km;c:\dev\include;$(IncludePath) + $(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\ucrt;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\winrt;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\um;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\shared;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\km;c:\dev\include;$(IncludePath) C:\dev\lib\x64;$(LibraryPath) C:\dev\lib\x64;$(LibraryPath) - C:\dev\include;C:\Program Files (x86)\Windows Kits\10\Include\10.0.16299.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.16299.0\shared;C:\Program Files (x86)\Windows Kits\10\Include\10.0.16299.0\winrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.16299.0\um;$(IncludePath) + $(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\ucrt;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\winrt;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\um;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\shared;$(MSBuildProgramFiles32)\Windows Kits\10\Include\10.0.16299.0\km;c:\dev\include;$(IncludePath) C:\dev\lib\x64;$(LibraryPath) @@ -185,21 +185,26 @@ $(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.16299.0\x86;$(ExecutablePath) + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(MSBuild_ExecutablePath);$(VC_LibraryPath_x86); $(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.16299.0\x86;$(ExecutablePath) + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(MSBuild_ExecutablePath);$(VC_LibraryPath_x86); $(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.16299.0\x86;$(ExecutablePath) + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(MSBuild_ExecutablePath);$(VC_LibraryPath_x86); $(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.16299.0\x64;$(ExecutablePath) $(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.16299.0\x64;$(ExecutablePath) + NativeMinimumRules.ruleset $(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.16299.0\x86;$(ExecutablePath) + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(MSBuild_ExecutablePath);$(VC_LibraryPath_x86); $(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.16299.0\x64;$(ExecutablePath) @@ -863,6 +868,7 @@ + diff --git a/specialmonitors.cpp b/specialmonitors.cpp index 7034c7d6..5c715e32 100755 --- a/specialmonitors.cpp +++ b/specialmonitors.cpp @@ -17,6 +17,54 @@ #define VIDEOGRAB 1 +const TCHAR *specialmonitorfriendlynames[] = +{ + _T("A2024"), + _T("Graffiti"), + _T("HAM-E"), + _T("HAM-E Plus"), + _T("Video DAC 18"), + _T("AVideo 12"), + _T("AVideo 24"), + _T("FireCracker 24"), + _T("DCTV"), + _T("OpalVision"), + _T("ColorBurst"), + NULL +}; +const TCHAR *specialmonitormanufacturernames[] = +{ + _T("Commodore"), + _T("Individual Computers"), + _T("Black Belt Systems"), + _T("Black Belt Systems"), + _T("Newtronic"), + _T("Archos"), + _T("Archos"), + _T("Impulse"), + _T("Digital Creations"), + _T("Opal Technologies"), + _T("M.A.S.T."), + NULL +}; +const TCHAR *specialmonitorconfignames[] = +{ + _T("none"), + _T("autodetect"), + + _T("a2024"), + _T("graffiti"), + _T("ham_e"), + _T("ham_e_plus"), + _T("videodac18"), + _T("avideo12"), + _T("avideo24"), + _T("firecracker24"), + _T("dctv"), + _T("opalvision"), + _T("colorburst"), + NULL +}; static int opal_debug = 0; static const int opal_video_debug = 0; @@ -257,6 +305,7 @@ static void clearmonitor(struct vidbuffer *dst) static void blank_generic(struct vidbuffer *src, struct vidbuffer *dst, int oddlines) { + struct vidbuf_description *avidinfo = &adisplays[dst->monitor_id].gfxvidinfo; int y, vdbl; int ystart, yend, isntsc; @@ -264,7 +313,7 @@ static void blank_generic(struct vidbuffer *src, struct vidbuffer *dst, int oddl if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) isntsc = currprefs.ntscmode ? 1 : 0; - vdbl = gfxvidinfo.ychange; + vdbl = avidinfo->ychange; ystart = isntsc ? VBLANK_ENDLINE_NTSC : VBLANK_ENDLINE_PAL; yend = isntsc ? MAXVPOS_NTSC : MAXVPOS_PAL; @@ -477,6 +526,7 @@ static int signature_test_y = 0x93; static bool dctv(struct vidbuffer *src, struct vidbuffer *dst, bool doublelines, int oddlines) { + struct vidbuf_description *avidinfo = &adisplays[dst->monitor_id].gfxvidinfo; int y, x, vdbl, hdbl; int ystart, yend, isntsc; int xadd; @@ -485,8 +535,8 @@ static bool dctv(struct vidbuffer *src, struct vidbuffer *dst, bool doublelines, if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) isntsc = currprefs.ntscmode ? 1 : 0; - vdbl = gfxvidinfo.ychange; - hdbl = gfxvidinfo.xchange; + vdbl = avidinfo->ychange; + hdbl = avidinfo->xchange; xadd = ((1 << 1) / hdbl) * src->pixbytes; @@ -722,6 +772,7 @@ STATIC_INLINE uae_u8 MAKEFCOVERLAY(uae_u8 v) static bool firecracker24(struct vidbuffer *src, struct vidbuffer *dst, bool doublelines, int oddlines) { + struct vidbuf_description *avidinfo = &adisplays[dst->monitor_id].gfxvidinfo; int y, x, vdbl, hdbl; int fc24_y, fc24_x, fc24_dx, fc24_xadd, fc24_xmult, fc24_xoffset; int ystart, yend, isntsc; @@ -736,8 +787,8 @@ static bool firecracker24(struct vidbuffer *src, struct vidbuffer *dst, bool dou if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) isntsc = currprefs.ntscmode ? 1 : 0; - vdbl = gfxvidinfo.ychange; - hdbl = gfxvidinfo.xchange; // 4=lores,2=hires,1=shres + vdbl = avidinfo->ychange; + hdbl = avidinfo->xchange; // 4=lores,2=hires,1=shres xaddfc = (1 << 1) / hdbl; // 0=lores,1=hires,2=shres xadd = xaddfc * src->pixbytes; @@ -1176,6 +1227,7 @@ static int avideo_allowed; static bool avideo(struct vidbuffer *src, struct vidbuffer *dst, bool doublelines, int oddlines, int lof) { + struct vidbuf_description *avidinfo = &adisplays[dst->monitor_id].gfxvidinfo; int y, x, vdbl, hdbl; int ystart, yend, isntsc; int xadd, xaddpix; @@ -1224,8 +1276,8 @@ static bool avideo(struct vidbuffer *src, struct vidbuffer *dst, bool doubleline if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) isntsc = currprefs.ntscmode ? 1 : 0; - vdbl = gfxvidinfo.ychange; - hdbl = gfxvidinfo.xchange; + vdbl = avidinfo->ychange; + hdbl = avidinfo->xchange; xaddpix = (1 << 1) / hdbl; xadd = ((1 << 1) / hdbl) * src->pixbytes; @@ -1500,6 +1552,7 @@ static bool do_avideo(struct vidbuffer *src, struct vidbuffer *dst) static bool videodac18(struct vidbuffer *src, struct vidbuffer *dst, bool doublelines, int oddlines) { + struct vidbuf_description *avidinfo = &adisplays[dst->monitor_id].gfxvidinfo; int y, x, vdbl, hdbl; int ystart, yend, isntsc; int xadd, xaddpix; @@ -1519,8 +1572,8 @@ static bool videodac18(struct vidbuffer *src, struct vidbuffer *dst, bool double if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) isntsc = currprefs.ntscmode ? 1 : 0; - vdbl = gfxvidinfo.ychange; - hdbl = gfxvidinfo.xchange; + vdbl = avidinfo->ychange; + hdbl = avidinfo->xchange; xaddpix = (1 << 1) / hdbl; xadd = ((1 << 1) / hdbl) * src->pixbytes; @@ -1605,6 +1658,7 @@ static const uae_u8 ham_e_magic_cookie_ham = 0x18; static bool ham_e(struct vidbuffer *src, struct vidbuffer *dst, bool doublelines, int oddlines) { + struct vidbuf_description *avidinfo = &adisplays[dst->monitor_id].gfxvidinfo; int y, x, vdbl, hdbl; int ystart, yend, isntsc; int xadd, xaddpix; @@ -1614,8 +1668,8 @@ static bool ham_e(struct vidbuffer *src, struct vidbuffer *dst, bool doublelines if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) isntsc = currprefs.ntscmode ? 1 : 0; - vdbl = gfxvidinfo.ychange; - hdbl = gfxvidinfo.xchange; + vdbl = avidinfo->ychange; + hdbl = avidinfo->xchange; xaddpix = (1 << 1) / hdbl; xadd = ((1 << 1) / hdbl) * src->pixbytes; @@ -1820,6 +1874,7 @@ static bool do_hame(struct vidbuffer *src, struct vidbuffer *dst) static bool graffiti(struct vidbuffer *src, struct vidbuffer *dst) { + struct vidbuf_description *avidinfo = &adisplays[dst->monitor_id].gfxvidinfo; int y, x; int ystart, yend, isntsc; int xstart, xend; @@ -1839,15 +1894,15 @@ static bool graffiti(struct vidbuffer *src, struct vidbuffer *dst) if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) isntsc = currprefs.ntscmode ? 1 : 0; - dbl = gfxvidinfo.ychange == 1 ? 2 : 1; + dbl = avidinfo->ychange == 1 ? 2 : 1; ystart = isntsc ? VBLANK_ENDLINE_NTSC : VBLANK_ENDLINE_PAL; yend = isntsc ? MAXVPOS_NTSC : MAXVPOS_PAL; if (src->yoffset >= (ystart << VRES_MAX)) ystart = src->yoffset >> VRES_MAX; - xadd = gfxvidinfo.xchange == 1 ? src->pixbytes * 2 : src->pixbytes; - xpixadd = gfxvidinfo.xchange == 1 ? 4 : 2; + xadd = avidinfo->xchange == 1 ? src->pixbytes * 2 : src->pixbytes; + xpixadd = avidinfo->xchange == 1 ? 4 : 2; xstart = 0x1c * 2 + 1; xend = 0xf0 * 2 + 1; @@ -1856,11 +1911,11 @@ static bool graffiti(struct vidbuffer *src, struct vidbuffer *dst) xend++; } - srcbuf = src->bufmem + (((ystart << VRES_MAX) - src->yoffset) / gfxvidinfo.ychange) * src->rowbytes + (((xstart << RES_MAX) - src->xoffset) / gfxvidinfo.xchange) * src->pixbytes; - srcend = src->bufmem + (((yend << VRES_MAX) - src->yoffset) / gfxvidinfo.ychange) * src->rowbytes; + srcbuf = src->bufmem + (((ystart << VRES_MAX) - src->yoffset) / avidinfo->ychange) * src->rowbytes + (((xstart << RES_MAX) - src->xoffset) / avidinfo->xchange) * src->pixbytes; + srcend = src->bufmem + (((yend << VRES_MAX) - src->yoffset) / avidinfo->ychange) * src->rowbytes; extrapix = 0; - dstbuf = dst->bufmem + (((ystart << VRES_MAX) - src->yoffset) / gfxvidinfo.ychange) * dst->rowbytes + (((xstart << RES_MAX) - src->xoffset) / gfxvidinfo.xchange) * dst->pixbytes; + dstbuf = dst->bufmem + (((ystart << VRES_MAX) - src->yoffset) / avidinfo->ychange) * dst->rowbytes + (((xstart << RES_MAX) - src->xoffset) / avidinfo->xchange) * dst->pixbytes; y = 0; while (srcend > srcbuf && dst->bufmemend > dstbuf) { @@ -1951,7 +2006,7 @@ static bool graffiti(struct vidbuffer *src, struct vidbuffer *dst) PRGB(dst, dstp, r, g, b); dstp += dst->pixbytes; - if (gfxvidinfo.xchange == 1 && !hires) { + if (avidinfo->xchange == 1 && !hires) { PRGB(dst, dstp, r, g, b); dstp += dst->pixbytes; PRGB(dst, dstp, r, g, b); @@ -1985,6 +2040,7 @@ static bool graffiti(struct vidbuffer *src, struct vidbuffer *dst) static bool a2024(struct vidbuffer *src, struct vidbuffer *dst) { + struct vidbuf_description *avidinfo = &adisplays[dst->monitor_id].gfxvidinfo; int y; uae_u8 *srcbuf, *dstbuf; uae_u8 *dataline; @@ -1996,15 +2052,15 @@ static bool a2024(struct vidbuffer *src, struct vidbuffer *dst) int idline; int total_width, total_height; - dbl = gfxvidinfo.ychange == 1 ? 2 : 1; - doff = (128 * 2 / gfxvidinfo.xchange) * src->pixbytes; + dbl = avidinfo->ychange == 1 ? 2 : 1; + doff = (128 * 2 / avidinfo->xchange) * src->pixbytes; found = false; for (idline = 21; idline <= 29; idline += 8) { if (src->yoffset > (idline << VRES_MAX)) continue; // min 178 max 234 - dataline = src->bufmem + (((idline << VRES_MAX) - src->yoffset) / gfxvidinfo.ychange) * src->rowbytes + (((200 << RES_MAX) - src->xoffset) / gfxvidinfo.xchange) * src->pixbytes; + dataline = src->bufmem + (((idline << VRES_MAX) - src->yoffset) / avidinfo->ychange) * src->rowbytes + (((200 << RES_MAX) - src->xoffset) / avidinfo->xchange) * src->pixbytes; #if 0 write_log (_T("%02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x%02x\n"), @@ -2098,10 +2154,10 @@ static bool a2024(struct vidbuffer *src, struct vidbuffer *dst) } total_height = panel_height * dbl; - srcbuf = src->bufmem + (((44 << VRES_MAX) - src->yoffset) / gfxvidinfo.ychange) * src->rowbytes + (((srcxoffset << RES_MAX) - src->xoffset) / gfxvidinfo.xchange) * src->pixbytes; - dstbuf = dst->bufmem + py * (panel_height / gfxvidinfo.ychange) * dst->rowbytes + px * ((panel_width * 2) / gfxvidinfo.xchange) * dst->pixbytes; + srcbuf = src->bufmem + (((44 << VRES_MAX) - src->yoffset) / avidinfo->ychange) * src->rowbytes + (((srcxoffset << RES_MAX) - src->xoffset) / avidinfo->xchange) * src->pixbytes; + dstbuf = dst->bufmem + py * (panel_height / avidinfo->ychange) * dst->rowbytes + px * ((panel_width * 2) / avidinfo->xchange) * dst->pixbytes; - for (y = 0; y < (panel_height / (dbl == 1 ? 1 : 2)) / gfxvidinfo.ychange; y++) { + for (y = 0; y < (panel_height / (dbl == 1 ? 1 : 2)) / avidinfo->ychange; y++) { #if 0 memcpy (dstbuf, srcbuf, ((panel_width * 2) / gfxvidinfo.xchange) * dst->pixbytes); #else @@ -2109,7 +2165,7 @@ static bool a2024(struct vidbuffer *src, struct vidbuffer *dst) uae_u8 *dstp1 = dstbuf; uae_u8 *dstp2 = dstbuf + dst->rowbytes; int x; - for (x = 0; x < (panel_width_draw * 2) / gfxvidinfo.xchange; x++) { + for (x = 0; x < (panel_width_draw * 2) / avidinfo->xchange; x++) { uae_u8 c1 = 0, c2 = 0; if (FR(src, srcp)) // R c1 |= 2; @@ -2313,6 +2369,8 @@ end: static bool do_genlock(struct vidbuffer *src, struct vidbuffer *dst, bool doublelines, int oddlines) { + struct vidbuf_description *avidinfo = &adisplays[dst->monitor_id].gfxvidinfo; + int y, x, vdbl, hdbl; int ystart, yend, isntsc; int mix1 = 0, mix2 = 0; @@ -2443,14 +2501,14 @@ skip: genlock_image_file[0] = 0; } - if (gfxvidinfo.ychange == 1) + if (avidinfo->ychange == 1) vdbl = 0; // double else vdbl = 1; // single - if (gfxvidinfo.xchange == 1) + if (avidinfo->xchange == 1) hdbl = 0; // shres - else if (gfxvidinfo.xchange == 2) + else if (avidinfo->xchange == 2) hdbl = 1; // hires else hdbl = 2; // lores @@ -2584,6 +2642,7 @@ extern uae_u8 *row_map_color_burst_buffer; static bool do_grayscale(struct vidbuffer *src, struct vidbuffer *dst, bool doublelines, int oddlines) { + struct vidbuf_description *avidinfo = &adisplays[dst->monitor_id].gfxvidinfo; int y, x, vdbl; int ystart, yend, isntsc; @@ -2591,7 +2650,7 @@ static bool do_grayscale(struct vidbuffer *src, struct vidbuffer *dst, bool doub if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) isntsc = currprefs.ntscmode ? 1 : 0; - if (gfxvidinfo.ychange == 1) + if (avidinfo->ychange == 1) vdbl = 0; else vdbl = 1; @@ -2830,6 +2889,7 @@ static void opal_pixel(struct opals *opal, uae_u8 *d, uae_u8 *d2, uae_u8 *s, uae static bool opalvision(struct vidbuffer *src, struct vidbuffer *dst, bool doublelines, int oddlines, int yline, bool isopal) { + struct vidbuf_description *avidinfo = &adisplays[dst->monitor_id].gfxvidinfo; int y, x, vdbl, hdbl, hdbl_shift; int isntsc; int xadd, xaddpix; @@ -2852,8 +2912,8 @@ static bool opalvision(struct vidbuffer *src, struct vidbuffer *dst, bool double if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) isntsc = currprefs.ntscmode ? 1 : 0; - vdbl = gfxvidinfo.ychange; - hdbl = gfxvidinfo.xchange; + vdbl = avidinfo->ychange; + hdbl = avidinfo->xchange; xaddpix = (1 << 1) / hdbl; xadd = ((1 << 1) / hdbl) * src->pixbytes; @@ -2972,7 +3032,7 @@ static bool opalvision(struct vidbuffer *src, struct vidbuffer *dst, bool double uae_u8 newval = FIRGB(src, sa); uae_u8 val = prev | newval; - uae_u8 *d = dstline + ((x << 1) >> hdbl_shift) * dst->pixbytes; + uae_u8 *d = dstline + ((x << 1) >> hdbl_shift) * dst->pixbytes + dst->pixbytes; uae_u8 *d2 = d + dst->rowbytes; uae_u8 *s = line + ((ax << 1) >> hdbl_shift) * src->pixbytes; @@ -3421,7 +3481,7 @@ static bool opalvision(struct vidbuffer *src, struct vidbuffer *dst, bool double write_log(_T("Opalvision control line detected\n")); } else if (!opal->opal && monitor != MONITOREMU_COLORBURST) { monitor = MONITOREMU_COLORBURST; - write_log(_T("Colorburst control line line detected\n")); + write_log(_T("Colorburst control line detected\n")); } dst->nativepositioning = true; diff --git a/statusline.cpp b/statusline.cpp index aae1f6dd..93b00bc5 100644 --- a/statusline.cpp +++ b/statusline.cpp @@ -19,7 +19,7 @@ * Some code to put status information on the screen. */ -void statusline_getpos (int *x, int *y, int width, int height, int hx, int vx) +void statusline_getpos(int monid, int *x, int *y, int width, int height, int hx, int vx) { int total_height = TD_TOTAL_HEIGHT * vx; if (currprefs.osd_pos.x >= 20000) { @@ -56,7 +56,7 @@ static const char *numbers = { /* ugly 0123456789CHD%+-PNK */ "+++++++---+++-++++++++++++++----+++++++++++++++++--+++--++++++++++++++++++++-++++++-++++------------------------+++----++++++++++++++" }; -STATIC_INLINE uae_u32 ledcolor (uae_u32 c, uae_u32 *rc, uae_u32 *gc, uae_u32 *bc, uae_u32 *a) +STATIC_INLINE uae_u32 ledcolor(uae_u32 c, uae_u32 *rc, uae_u32 *gc, uae_u32 *bc, uae_u32 *a) { uae_u32 v = rc[(c >> 16) & 0xff] | gc[(c >> 8) & 0xff] | bc[(c >> 0) & 0xff]; if (a) @@ -64,7 +64,7 @@ STATIC_INLINE uae_u32 ledcolor (uae_u32 c, uae_u32 *rc, uae_u32 *gc, uae_u32 *bc return v; } -static void write_tdnumber (uae_u8 *buf, int bpp, int x, int y, int num, uae_u32 c1, uae_u32 c2) +static void write_tdnumber(uae_u8 *buf, int bpp, int x, int y, int num, uae_u32 c1, uae_u32 c2) { int j; const char *numptr; @@ -79,8 +79,9 @@ static void write_tdnumber (uae_u8 *buf, int bpp, int x, int y, int num, uae_u32 } } -void draw_status_line_single (uae_u8 *buf, int bpp, int y, int totalwidth, uae_u32 *rc, uae_u32 *gc, uae_u32 *bc, uae_u32 *alpha) +void draw_status_line_single(int monid, uae_u8 *buf, int bpp, int y, int totalwidth, uae_u32 *rc, uae_u32 *gc, uae_u32 *bc, uae_u32 *alpha) { + struct amigadisplay *ad = &adisplays[monid]; int x_start, j, led, border; uae_u32 c1, c2, cb; @@ -99,7 +100,7 @@ void draw_status_line_single (uae_u8 *buf, int bpp, int y, int totalwidth, uae_u xcolnr on_rgb = 0, on_rgb2 = 0, off_rgb = 0, pen_rgb = 0; int half = 0; - if (!(currprefs.leds_on_screen_mask[picasso_on ? 1 : 0] & (1 << led))) + if (!(currprefs.leds_on_screen_mask[ad->picasso_on ? 1 : 0] & (1 << led))) continue; pen_rgb = c1; @@ -324,7 +325,7 @@ bool has_statusline_updated(void) static void statusline_update_notification(void) { statusline_had_changed = true; - statusline_updated(); + statusline_updated(0); } void statusline_clear(void) @@ -430,7 +431,7 @@ void statusline_vsync(void) statusline_update_notification(); } -void statusline_single_erase(uae_u8 *buf, int bpp, int y, int totalwidth) +void statusline_single_erase(int monid, uae_u8 *buf, int bpp, int y, int totalwidth) { memset(buf, 0, bpp * totalwidth); } -- 2.47.3