]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
4000b1. Lagless vsync and multimonitor megapatch.
authorToni Wilen <twilen@winuae.net>
Sun, 8 Apr 2018 17:27:06 +0000 (20:27 +0300)
committerToni Wilen <twilen@winuae.net>
Sun, 8 Apr 2018 17:27:06 +0000 (20:27 +0300)
57 files changed:
ar.cpp
arcadia.cpp
blitter.cpp
cfgfile.cpp
consolehook.cpp
custom.cpp
debug.cpp
devices.cpp
drawing.cpp
events.cpp
framebufferboards.cpp
gfxboard.cpp
gfxutil.cpp
include/custom.h
include/drawing.h
include/events.h
include/gfxboard.h
include/gfxfilter.h
include/inputdevice.h
include/options.h
include/scsi.h
include/specialmonitors.h
include/statusline.h
include/xwin.h
inputdevice.cpp
main.cpp
mame/a2410.cpp
od-win32/ahidsound_dsonly.cpp
od-win32/avioutput.cpp
od-win32/bsdsock.cpp
od-win32/dinput.cpp
od-win32/direct3d.cpp
od-win32/direct3d.h
od-win32/direct3d11.cpp
od-win32/dxwrap.cpp
od-win32/dxwrap.h
od-win32/keyboard_win32.cpp
od-win32/parser.cpp
od-win32/picasso96_win.cpp
od-win32/picasso96_win.h
od-win32/resources/resource.h
od-win32/resources/winuae.rc
od-win32/rp.cpp
od-win32/scaler_more.cpp
od-win32/screenshot.cpp
od-win32/sounddep/sound.cpp
od-win32/statusline_win32.cpp
od-win32/win32.cpp
od-win32/win32.h
od-win32/win32_scaler.cpp
od-win32/win32gfx.cpp
od-win32/win32gfx.h
od-win32/win32gui.cpp
od-win32/win32gui_extra.cpp
od-win32/winuae_msvc15/winuae_msvc.vcxproj
specialmonitors.cpp
statusline.cpp

diff --git a/ar.cpp b/ar.cpp
index a0d0e26a8da7753ef5e584235e5d6357687c5aa1..e45cbe1ac0faedfba1433ccf8b18c487650d62bc 100644 (file)
--- a/ar.cpp
+++ b/ar.cpp
 #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
 }
index 49890dfee450105fae0150039705675b9ab1d6ad..b2551ee376cb46c0c70b60db763f55f80657f1e5 100644 (file)
@@ -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;
index 914dbaed4ad1ad0c0441796ddd5b380bc2130000..655890531a28980ba265eef5a164583793d720a1 100644 (file)
@@ -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;
index d7995e4e1611027595c27dacd700dfcfd1c267cf..d7b8749d29b0e7f68ec2d60254294eafb0b81b89 100644 (file)
@@ -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;
index 69b58bee48ddf8f2aaad624d41d1df7a223fd759..870e2b3e3da3ee42b693b9eaf823fcbbedfe1fb2 100644 (file)
@@ -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;
index 7bef8fc033a4d2a0d503b221ceacc735071199ff..5a3042027f19fa0f72b56d8bba70403425fb0933 100644 (file)
@@ -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
 }
 
index 7068aedb6e648b9bb5e66baac8f6a5bc5c31d822..e25e71e93e77f837179062c45233a4f9f1eaf37e 100644 (file)
--- 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)
index 5b73a72fc3f51304eef15d3a9426d5df27127d87..e6760c4e77494f8aa0c75f726e31dc5a861a1eee 100644 (file)
@@ -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 ();
index 6326c0dfb12a594ba2aae1138b6390a115c349e6..37a4ae9ca07776357a5da45fdd6b39c0cbcfcf16 100644 (file)
@@ -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 ();
index 4abf9d1fc537add9583db5991ffc69e6fbd5503f..0c70d0a1b24e24d20cc03420536499893862a19f 100644 (file)
@@ -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);
index d272a0528a004699a2f6f4a94c78dc2a8a934ae1..2c73de069c9fcdd1628012b24626d49ccf430765 100644 (file)
@@ -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;
index 9e2271559e34a59c18fe36c8132ad5a042e854bb..a94c3a17fe1c44826d1c6dabca01c94c6bef7336 100644 (file)
@@ -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) {
index 5a7910e324c82e9f6d91202be9667874921abc18..4c3f0361056d5ca821954f539b78e72ab10d1532 100644 (file)
 
 #include <math.h>
 
-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
index 98c377f03441796f30dc38bdf87205eaa68460d7..f9da2fb8607c0f29053cf15ed1a3dae1731ace56 100644 (file)
@@ -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;
 
index 01dfcfe02bfd18abe05b4a6a5ee5e798f0a72a1c..10cfc9023a989a1682eb238b1f0841c364ec0f46 100644 (file)
@@ -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 */
index d461b8a5eeee5eccf1cba990b9e8ad66f60285f9..fb094a9d9a8a342bd7fbe43e256e2f9e72fe3cb9 100644 (file)
@@ -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;
 
index 3f60654c9ed4375d6a7ac4f2c7124ca8720d143d..7a01f1be2de236b06ff54daef6229e27beab1695 100644 (file)
@@ -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;
index 5c5a974428db86953822b047f6d83d2f462a8cf3..b46003b6de228a0c2fc0f4fa1c61af58ee234895 100644 (file)
@@ -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 */
 
index f54072521f6a07ea1bb300d36be29a046ab03c75..9ffccd6d3584f575a1bc4b7490c92536079d15ef 100644 (file)
@@ -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);
index 8eee94d730f480d49a327c4af8e8e8237181ff42..bc839fbf1c1ee7619adbcd7c4a6fd6801bf0d82f 100644 (file)
 
 #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;
index 6279bf5d301cb407776aa05b2e2fdf919a897a51..fc21b082e627558801b534a2858b43e86b90237d 100644 (file)
@@ -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);
index c735a14f1d917851699c5f437b47d51972ae9b4d..907194061b6e4e1b40bca24c31832cf01c2c4538 100644 (file)
@@ -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 */
index 8b554b5a9def333b5002384305bf08e32003d58a..089fd3f0ee9c0dfebc29e05b99d7d7ec830f65b2 100644 (file)
@@ -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);
 
index 370726a889d41256a8819f5cd39351d187fc4c58..02e73d1c88a2f100f7a41bc45a64fe386244043f 100644 (file)
@@ -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 */
index f018669fc57b656cae7d087e1aed854cb5b2ff74..0177383e18473384578fc85bb1dae805a51d3ff6 100644 (file)
@@ -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;
index 1d6e8c0e0a496385cd7fc7e10331d80eec16dd3d..4acd80046e7f3406d46dddd0ad3c8109029ef2c9 100644 (file)
--- 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
index fb474193f3191338a9368ae33bc0b27810ca97eb..af0daec5a030ba964890b3049b761a0af18d7ef5 100644 (file)
@@ -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++;
        }
index 3cd28a878efdd034fc5697364c024cf98d967d92..8150e15bfc3113c1ce5ef9669c218d5bc4a1911e 100644 (file)
@@ -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)&regs;
        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)) {
index 07f68ffb8d146cf55413767ad732f4409f0d4975..4a6564bbba36f4ce9de23dc8f7ca4430e7034af5 100644 (file)
@@ -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--;
        }
index b3bef4ba7bf32f18b910dd474304520c8e3f2f1b..c47c681b046d840cacc1fa83de94b736c91c6a8d 100644 (file)
 #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;
index 5c80322a48be96f54c9e90d0f4105322985bab97..8d5aa63f35be5b6bbca67403be6c25bf3d54bee6 100644 (file)
@@ -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);
index d4eee60bbe4bc0bba2e37b7d36e9d7665eb13672..399a94abb9be0be0ea96a723d0c2a31a7799eab7 100644 (file)
@@ -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
index d71fb0ea7750d57503de5be89af10cc08428d253..3c623c8bbff870f16346e925c588f559b1580981 100644 (file)
@@ -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
index 0dd619fdeef6dc995d2f2d3f865bba2a41f019f9..bdd1a8ed51ec29c1b874a277916393e9e2e0e1e6 100644 (file)
@@ -37,36 +37,33 @@ using Microsoft::WRL::ComPtr;
 #include <process.h>
 #include <Dwmapi.h>
 
-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<IDXGIFactory2> 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)
index 685d17b2505e24287a2dfa78c3661b1d3976e5f0..88bcf54523fa9a98900d3eb7b5105644bab776d1 100644 (file)
@@ -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)
index 240b5d259c9cc5d227f39530cdd972269000ab87..fb3cd4f63f51d6d25bfb79c16b89ae33ed2dd6ce 100644 (file)
@@ -4,6 +4,7 @@
 #include "rtgmodes.h"
 #include <ddraw.h>
 #include <d3d9.h>
+#include <D3dkmthk.h>
 
 #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,
index 8d469cbae81dec99db0fece2d108b1f0a95e4beb..7d749cdd6a47f6ce764266f169e07f21fd141feb 100644 (file)
@@ -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;
        }
 
index 87aae457cc05147bcab59c05b18f2d21b024882b..523ae2d4a2bb3df2b7caa99bf094786b5891fa6e 100644 (file)
@@ -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);
                                }
                        }
                }
index f72956f86bc0e38879ca5c288cad6644ba7b5524..5518aaa15494e576cc84444e686e0563257ae10d 100644 (file)
@@ -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;
index 6c13b2c644d7afdb8ad0b7707ac2c33427d6f954..4342ccd6878813e60361c41e96e4889561b959fe 100644 (file)
@@ -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;
 
index 51aa0df0b5103e7a65d91563da754ff9d91eb7c3..3a81d821e6cfe2bbebe165d723da31d217427ca9 100644 (file)
 #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
 #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
 #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
 #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
index c05d7083cfc9dd8b5f7e33d0e07c0087b11985d3..2876e4ceb586d5a17e6a1e3fb0f1a15cdc40fd17 100644 (file)
@@ -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]"
index 12ae40f45d4221688c4e5f31c893273e7cc75763..94d76878010f7b15fa178660c478d6fbb0a07c62 100644 (file)
@@ -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) {
index 28a707211cc9f469ac05e621f821551b1a943a70..bef83ab123b67a37b1b193da326bae324575d4f9 100644 (file)
@@ -5,6 +5,7 @@
 #include "options.h"
 #include "filter.h"
 #include "custom.h"
+#include "xwin.h"
 
 #include <math.h>
 
@@ -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
index e08c834db092068484b7537144734646608c1d5d..8da2ad7fb85ef077e4ac304c87e1540aa6f71124 100644 (file)
@@ -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;
index 47055002e8a93fad96f69e72681000e80fbc0048..5822a8b9eb59c767258c824477f40d0b51894641 100644 (file)
@@ -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;
index c9187e9bc8418a72f5aa28d5fb0bbe66e50f808b..a612edc15ea253137ed942e774f7225e0064d196 100644 (file)
@@ -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!");
index c1c6a0ce41708f8cd17977636db850812f7bbd34..0df2cb1a1c5a98acf67d65164c0158f601f4a763 100644 (file)
 #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;
index 35eee3361e1861af167e4cddb90f77b07f30d398..e305bf389a30521bcdde9861c376f00196c1cd31 100644 (file)
 #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")
 #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];
index cd04da8c41e57e243a4a99c22c273ac28b63a8b9..099ac6ebfc3ffc6cd611cfdefd61d2c0e1d62ed8 100644 (file)
@@ -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;
 }
index a29f3f62f5685f9361df16d79e006f7a17e67ccd..d07c73160045d197eee19cba4e82c4978a2d609d 100644 (file)
@@ -19,6 +19,8 @@
 #include <ddraw.h>
 #include <shellapi.h>
 #include <dwmapi.h>
+#include <D3dkmthk.h>
+#include <process.h>
 
 #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"
 #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 = &currentmodestruct;
 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 <process.h>
-
-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, &currentmode->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, &currentmode->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);
 }
index 770212d966d7c8bffc9d24c1059b4086d6a66f6c..e5af53ed631fdabcf3a6bf495c63ae5b08542df7 100644 (file)
@@ -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
index 69860f032bcb10cb0540e0d9e748f7d30341568f..4de8c1817b79b1db0001abeed5c76db195f6a790 100644 (file)
@@ -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);
        }
 }
 
index ccd42825ba151f2e0035ec436bdc5d39236c3dad..3e322c24b37e6a26f62055f328b8f4bf91759487 100644 (file)
@@ -7,6 +7,7 @@
 #include "sysconfig.h"
 #include "sysdeps.h"
 
+#include "options.h"
 #include "resource.h"
 #include "registry.h"
 #include "win32.h"
index 90ef139915b49e4381ac7f611c17da265ada1619..99989db4423d160d88142f91f7d7050aeaeacd59 100644 (file)
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">winuae64</TargetName>
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Test|x64'">winuae64</TargetName>
     <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">winuae64</TargetName>
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(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)</IncludePath>
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Test|Win32'">$(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)</IncludePath>
-    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(MSBuildProgramFiles32)\Windows Kits\10\lib\10.0.10240.0\ucrt\$(PlatformShortName);C:\dev\lib;$(LibraryPath)</LibraryPath>
-    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Test|Win32'">$(MSBuildProgramFiles32)\Windows Kits\10\lib\10.0.16299.0\ucrt\$(PlatformShortName);C:\dev\lib;$(LibraryPath)</LibraryPath>
-    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">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)</LibraryPath>
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;C:\dev\include;$(IncludePath)</IncludePath>
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='FullRelease|Win32'">$(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)</IncludePath>
-    <ReferencePath Condition="'$(Configuration)|$(Platform)'=='FullRelease|Win32'">$(ReferencePath)</ReferencePath>
-    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='FullRelease|Win32'">$(MSBuildProgramFiles32)\Windows Kits\10\lib\10.0.16299.0\ucrt\$(PlatformShortName);C:\dev\lib;$(LibraryPath)</LibraryPath>
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(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)</IncludePath>
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Test|Win32'">$(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)</IncludePath>
+    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">C:\dev\lib;$(LibraryPath)</LibraryPath>
+    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Test|Win32'">C:\dev\lib;$(LibraryPath)</LibraryPath>
+    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">C:\dev\lib;$(LibraryPath)</LibraryPath>
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(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)</IncludePath>
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='FullRelease|Win32'">$(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)</IncludePath>
+    <ReferencePath Condition="'$(Configuration)|$(Platform)'=='FullRelease|Win32'">$(VC_ReferencesPath_x86);</ReferencePath>
+    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='FullRelease|Win32'">C:\dev\lib;$(LibraryPath)</LibraryPath>
     <EmbedManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</EmbedManifest>
     <EmbedManifest Condition="'$(Configuration)|$(Platform)'=='Test|Win32'">true</EmbedManifest>
     <EmbedManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</EmbedManifest>
     <EmbedManifest Condition="'$(Configuration)|$(Platform)'=='FullRelease|Win32'">true</EmbedManifest>
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">C:\dev\include;C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;$(IncludePath)</IncludePath>
-    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">C:\dev\lib\x64;C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64;$(LibraryPath)</LibraryPath>
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">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)</IncludePath>
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Test|x64'">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)</IncludePath>
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(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)</IncludePath>
+    <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">C:\dev\lib\x64;$(LibraryPath)</LibraryPath>
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(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)</IncludePath>
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='Test|x64'">$(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)</IncludePath>
     <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">C:\dev\lib\x64;$(LibraryPath)</LibraryPath>
     <LibraryPath Condition="'$(Configuration)|$(Platform)'=='Test|x64'">C:\dev\lib\x64;$(LibraryPath)</LibraryPath>
-    <IncludePath Condition="'$(Configuration)|$(Platform)'=='FullRelease|x64'">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)</IncludePath>
+    <IncludePath Condition="'$(Configuration)|$(Platform)'=='FullRelease|x64'">$(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)</IncludePath>
     <LibraryPath Condition="'$(Configuration)|$(Platform)'=='FullRelease|x64'">C:\dev\lib\x64;$(LibraryPath)</LibraryPath>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Test|x64'">
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Test|Win32'">
     <ExecutablePath>$(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.16299.0\x86;$(ExecutablePath)</ExecutablePath>
+    <ExcludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(MSBuild_ExecutablePath);$(VC_LibraryPath_x86);</ExcludePath>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ExecutablePath>$(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.16299.0\x86;$(ExecutablePath)</ExecutablePath>
+    <ExcludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(MSBuild_ExecutablePath);$(VC_LibraryPath_x86);</ExcludePath>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='FullRelease|Win32'">
     <ExecutablePath>$(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.16299.0\x86;$(ExecutablePath)</ExecutablePath>
+    <ExcludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(MSBuild_ExecutablePath);$(VC_LibraryPath_x86);</ExcludePath>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='FullRelease|x64'">
     <ExecutablePath>$(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.16299.0\x64;$(ExecutablePath)</ExecutablePath>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <ExecutablePath>$(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.16299.0\x64;$(ExecutablePath)</ExecutablePath>
+    <CodeAnalysisRuleSet>NativeMinimumRules.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ExecutablePath>$(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.16299.0\x86;$(ExecutablePath)</ExecutablePath>
+    <ExcludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(MSBuild_ExecutablePath);$(VC_LibraryPath_x86);</ExcludePath>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ExecutablePath>$(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.16299.0\x64;$(ExecutablePath)</ExecutablePath>
     <ClCompile Include="..\..\cpuemu_40.cpp" />
     <ClCompile Include="..\..\cpuemu_50.cpp" />
     <ClCompile Include="..\..\cpummu30.cpp" />
+    <ClCompile Include="..\..\debugmem.cpp" />
     <ClCompile Include="..\..\def_icons.cpp" />
     <ClCompile Include="..\..\devices.cpp" />
     <ClCompile Include="..\..\dlopen.cpp" />
index 7034c7d60b531d0c7e5a78b841b84bbf50aaf0b1..5c715e3288748b0033a965a9b9db2975221413ff 100755 (executable)
 
 #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;
 
index aae1f6dda168cec94a00302b05214c92efb0a726..93b00bc5bb4d007d53b811685bce888745a8d926 100644 (file)
@@ -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);
 }