From 36961287022803562684c0ab37e825746f118ab4 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sun, 25 Jul 2021 21:26:10 +0300 Subject: [PATCH] RTG crash fix. Set default resolution if activating without initialized mode. --- framebufferboards.cpp | 2 +- gfxboard.cpp | 10 ++-- include/xwin.h | 2 +- mame/a2410.cpp | 2 +- od-win32/avioutput.cpp | 2 +- od-win32/picasso96_win.cpp | 96 ++++++++++++++++++++++++++------------ od-win32/picasso96_win.h | 2 +- od-win32/win32gfx.cpp | 18 +++---- 8 files changed, 83 insertions(+), 51 deletions(-) diff --git a/framebufferboards.cpp b/framebufferboards.cpp index 7a19064e..acb29629 100644 --- a/framebufferboards.cpp +++ b/framebufferboards.cpp @@ -70,7 +70,7 @@ static bool fb_get_surface(struct fb_struct *data) bool gotsurf = false; if (ad->picasso_on) { if (data->surface == NULL) { - data->surface = gfx_lock_picasso(data->monitor_id, false, false); + data->surface = gfx_lock_picasso(data->monitor_id, false); gotsurf = true; } if (data->surface && gotsurf) { diff --git a/gfxboard.cpp b/gfxboard.cpp index e20661a1..72dab22c 100644 --- a/gfxboard.cpp +++ b/gfxboard.cpp @@ -695,7 +695,7 @@ void video_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) pcem_flush(gb, i); if (rtg_visible[gb->monitor_id] >= 0 && gb->monswitch_delay == 0 && gb->monswitch_current == gb->monswitch_new) { if (gb->gfxboard_surface == NULL) { - gb->gfxboard_surface = gfx_lock_picasso(gb->monitor_id, false, false); + gb->gfxboard_surface = gfx_lock_picasso(gb->monitor_id, false); } if (gb->gfxboard_surface) { struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[gb->monitor_id]; @@ -1364,7 +1364,7 @@ int surface_stride(DisplaySurface *s) if (s == &gb->fakesurface || !gb->vga_refresh_active) return 0; if (gb->gfxboard_surface == NULL) - gb->gfxboard_surface = gfx_lock_picasso(gb->monitor_id, false, false); + gb->gfxboard_surface = gfx_lock_picasso(gb->monitor_id, false); struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[gb->monitor_id]; return vidinfo->rowbytes; } @@ -1380,7 +1380,7 @@ uint8_t *surface_data(DisplaySurface *s) if (s == &gb->fakesurface || !gb->vga_refresh_active) return gb->fakesurface_surface; if (gb->gfxboard_surface == NULL) - gb->gfxboard_surface = gfx_lock_picasso(gb->monitor_id, false, false); + gb->gfxboard_surface = gfx_lock_picasso(gb->monitor_id, false); return gb->gfxboard_surface; } @@ -1609,7 +1609,7 @@ void gfxboard_vsync_handler(bool full_redraw_required, bool redraw_required) 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); + gb->gfxboard_surface = gfx_lock_picasso(gb->monitor_id, false); } if (gb->gfxboard_surface) { if (softstatusline()) @@ -3147,7 +3147,7 @@ void gfxboard_reset (void) } } if (gb->monitor_id > 0) { - close_rtg(gb->monitor_id); + close_rtg(gb->monitor_id, true); } } for (int i = 0; i < MAX_AMIGADISPLAYS; i++) { diff --git a/include/xwin.h b/include/xwin.h index 2e993f37..0775f0c0 100644 --- a/include/xwin.h +++ b/include/xwin.h @@ -29,7 +29,7 @@ extern void setup_brkhandler (void); extern int isfullscreen (void); extern void toggle_fullscreen(int monid, int); extern bool toggle_rtg(int monid, int); -extern void close_rtg(int monid); +extern void close_rtg(int monid, bool reset); extern void toggle_mousegrab (void); void setmouseactivexy(int monid, int x, int y, int dir); diff --git a/mame/a2410.cpp b/mame/a2410.cpp index 62b7f3e9..0ecf4e9d 100644 --- a/mame/a2410.cpp +++ b/mame/a2410.cpp @@ -676,7 +676,7 @@ static void get_a2410_surface(struct a2410_struct *data) bool gotsurf = false; if (ad->picasso_on) { if (data->a2410_surface == NULL) { - data->a2410_surface = gfx_lock_picasso(monid, false, false); + data->a2410_surface = gfx_lock_picasso(monid, false); gotsurf = true; } if (data->a2410_surface && gotsurf) { diff --git a/od-win32/avioutput.cpp b/od-win32/avioutput.cpp index d1b2f71f..f4870171 100644 --- a/od-win32/avioutput.cpp +++ b/od-win32/avioutput.cpp @@ -537,7 +537,7 @@ static int AVIOutput_AllocateVideo(void) avioutput_fps = (int)(vblank_hz + 0.5); if (!avioutput_fps) - avioutput_fps = ispal() ? 50 : 60; + avioutput_fps = ispal(NULL) ? 50 : 60; if (avioutput_originalsize || WIN32GFX_IsPicassoScreen(mon)) { int pitch; if (!gfxboard_isgfxboardscreen(0)) { diff --git a/od-win32/picasso96_win.cpp b/od-win32/picasso96_win.cpp index 439fe237..29174bf5 100644 --- a/od-win32/picasso96_win.cpp +++ b/od-win32/picasso96_win.cpp @@ -187,6 +187,7 @@ static int overlay_occlusion; static struct MyCLUTEntry overlay_clutc[256 * 2]; static uae_u32 overlay_clut[256 * 2]; static uae_u32 *p96_rgbx16_ovl; +static bool delayed_set_switch; static int uaegfx_old, uaegfx_active; static uae_u32 reserved_gfxmem; @@ -1164,6 +1165,12 @@ static void picasso_handle_vsync2(struct AmigaMonitor *mon) vidinfo->picasso_changed = true; init_picasso_screen(mon->monitor_id); init_hz_p96(mon->monitor_id); + if (delayed_set_switch) { + delayed_set_switch = false; + atomic_or(&vidinfo->picasso_state_change, PICASSO_STATE_SETSWITCH); + ad->picasso_requested_on = 1; + set_config_changed(); + } } if (state & PICASSO_STATE_SETSWITCH) { atomic_and(&vidinfo->picasso_state_change, ~PICASSO_STATE_SETSWITCH); @@ -1258,7 +1265,8 @@ void picasso_handle_vsync(void) createwindowscursor(mon->monitor_id, 0, 0, 0, 0, 0, 1); } picasso_trigger_vblank(); - return; + if (!delayed_set_switch) + return; } int vsync = isvsync_rtg(); @@ -2788,17 +2796,30 @@ static uae_u32 REGPARAM2 picasso_SetSwitch (TrapContext *ctx) struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; uae_u16 flag = trap_get_dreg(ctx, 0) & 0xFFFF; - 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 && (state->BytesPerPixel == 0 || state->Width == 0 || state->Height == 0) && monid > 0) { + state->Width = 640; + state->VirtualWidth = state->Width; + state->Height = 480; + state->VirtualHeight = state->Height; + state->GC_Depth = 8; + state->GC_Flags = 0; + state->BytesPerPixel = 1; + state->HostAddress = NULL; + delayed_set_switch = true; + atomic_or(&vidinfo->picasso_state_change, PICASSO_STATE_SETGC); + } else { + delayed_set_switch = false; + atomic_or(&vidinfo->picasso_state_change, PICASSO_STATE_SETSWITCH); + ad->picasso_requested_on = flag != 0; + set_config_changed(); + } if (flag) _stprintf(p96text, _T("Picasso96 %dx%dx%d (%dx%dx%d)"), 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); + write_log(_T("SetSwitch() - %s - %s. Monitor=%d\n"), flag ? p96text : _T("amiga"), delayed_set_switch ? _T("delayed") : _T("immediate"), monid); /* Put old switch-state in D0 */ unlockrtg(); @@ -5239,7 +5260,6 @@ static void picasso_flushpixels(int index, uae_u8 *src, int off, bool render) struct picasso96_state_struct *state = &picasso96_state[monid]; uae_u8 *src_start[2]; uae_u8 *src_end[2]; - uae_u8 *dst = NULL; ULONG_PTR gwwcnt; int pwidth = state->Width > state->VirtualWidth ? state->VirtualWidth : state->Width; int pheight = state->Height > state->VirtualHeight ? state->VirtualHeight : state->Height; @@ -5249,12 +5269,6 @@ static void picasso_flushpixels(int index, uae_u8 *src, int off, bool render) struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; bool overlay_updated = false; - // safety check - if (pwidth > vidinfo->rowbytes / vidinfo->pixbytes) - pwidth = vidinfo->rowbytes / vidinfo->pixbytes; - if (pheight > vidinfo->height) - pheight = vidinfo->height; - src_start[0] = src + (off & ~gwwpagemask[index]); src_end[0] = src + ((off + state->BytesPerRow * pheight + gwwpagesize[index] - 1) & ~gwwpagemask[index]); if (vidinfo->splitypos >= 0) { @@ -5280,7 +5294,9 @@ static void picasso_flushpixels(int index, uae_u8 *src, int off, bool render) if (vidinfo->full_refresh || vidinfo->rtg_clear_flag) vidinfo->full_refresh = -1; + uae_u8 *dstp = NULL; for (;;) { + uae_u8 *dst = NULL; bool dofull; gwwcnt = 0; @@ -5325,12 +5341,34 @@ static void picasso_flushpixels(int index, uae_u8 *src, int off, bool render) dofull = gwwcnt >= (regionsize / gwwpagesize[index]) * 80 / 100; - dst = gfx_lock_picasso(monid, dofull, vidinfo->rtg_clear_flag != 0); - if (vidinfo->rtg_clear_flag) - vidinfo->rtg_clear_flag--; - if (dst == NULL) { + if (!dstp) { + dstp = gfx_lock_picasso(monid, dofull); + } + if (dstp == NULL) { continue; } + dst = dstp; + + // safety check + if (pwidth > vidinfo->rowbytes / vidinfo->pixbytes) { + pwidth = vidinfo->rowbytes / vidinfo->pixbytes; + } + if (pheight > vidinfo->height) { + pheight = vidinfo->height; + } + + if (!split && vidinfo->rtg_clear_flag) { + uae_u8 *p2 = dst; + for (int h = 0; h < pheight; h++) { + memset(p2, 0, pwidth * vidinfo->pixbytes); + p2 += vidinfo->rowbytes; + } + } + + if (vidinfo->rtg_clear_flag) { + vidinfo->rtg_clear_flag--; + } + dst += vidinfo->offset; if (doskip() && p96skipmode == 2) { @@ -5413,11 +5451,11 @@ static void picasso_flushpixels(int index, uae_u8 *src, int off, bool render) } if (!index && overlay_vram && overlay_active && (flushlines || overlay_updated)) { - if (dst == NULL) { - dst = gfx_lock_picasso(monid, false, false); + if (dstp == NULL) { + dstp = gfx_lock_picasso(monid, false); } - if (dst) - picasso_flushoverlay(index, src, off, dst); + if (dstp) + picasso_flushoverlay(index, src, off, dstp); } if (0 && flushlines) { @@ -5425,12 +5463,12 @@ static void picasso_flushpixels(int index, uae_u8 *src, int off, bool render) } if (currprefs.leds_on_screen & STATUSLINE_RTG) { - if (dst == NULL) { - dst = gfx_lock_picasso(monid, false, false); + if (dstp == NULL) { + dstp = gfx_lock_picasso(monid, false); } - if (dst) { + if (dstp) { if (softstatusline()) { - picasso_statusline(monid, dst); + picasso_statusline(monid, dstp); } maxy = vidinfo->height; if (miny > vidinfo->height - TD_TOTAL_HEIGHT) @@ -5445,11 +5483,11 @@ static void picasso_flushpixels(int index, uae_u8 *src, int off, bool render) } } - if (dst || render) { + if (dstp || render) { gfx_unlock_picasso(monid, render); } - if (dst && gwwcnt) { + if (dstp && gwwcnt) { vidinfo->full_refresh = 0; } } @@ -5532,8 +5570,6 @@ void InitPicasso96(int monid) oldscr = 0; //fastscreen memset (state, 0, sizeof (struct picasso96_state_struct)); - state->Width = 640; - state->Height = 480; for (i = 0; i < 256; i++) { p2ctab[i][0] = (((i & 128) ? 0x01000000 : 0) @@ -6317,7 +6353,7 @@ static void picasso_reset2(int monid) } if (is_uaegfx_active() && currprefs.rtgboards[0].monitor_id > 0) { - close_rtg(currprefs.rtgboards[0].monitor_id); + close_rtg(currprefs.rtgboards[0].monitor_id, true); } for (int i = 0; i < MAX_AMIGADISPLAYS; i++) { diff --git a/od-win32/picasso96_win.h b/od-win32/picasso96_win.h index c9866c4b..b61d23b1 100644 --- a/od-win32/picasso96_win.h +++ b/od-win32/picasso96_win.h @@ -684,7 +684,7 @@ extern struct picasso_vidbuf_description picasso_vidinfo[MAX_AMIGAMONITORS]; 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 uae_u8 *gfx_lock_picasso(int monid, 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); diff --git a/od-win32/win32gfx.cpp b/od-win32/win32gfx.cpp index 2684c3c8..3963c960 100644 --- a/od-win32/win32gfx.cpp +++ b/od-win32/win32gfx.cpp @@ -1819,7 +1819,7 @@ static uae_u8 *gfx_lock_picasso2(int monid, bool fullupdate) return DirectDraw_GetSurfacePointer (); } } -uae_u8 *gfx_lock_picasso(int monid, bool fullupdate, bool doclear) +uae_u8 *gfx_lock_picasso(int monid, bool fullupdate) { struct AmigaMonitor *mon = &AMonitors[monid]; struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid]; @@ -1833,13 +1833,6 @@ uae_u8 *gfx_lock_picasso(int monid, bool fullupdate, bool doclear) gfx_unlock(); } else { mon->rtg_locked = true; - if (doclear) { - uae_u8 *p2 = p; - for (int h = 0; h < vidinfo->height; h++) { - memset (p2, 0, vidinfo->width * vidinfo->pixbytes); - p2 += vidinfo->rowbytes; - } - } } return p; } @@ -1924,7 +1917,6 @@ static void close_hwnds(struct AmigaMonitor *mon) if (mon->screen_is_initialized) releasecapture(mon); mon->screen_is_initialized = 0; - mon->screen_is_picasso = 0; if (!mon->monitor_id) { display_vblank_thread_kill(); #ifdef AVIOUTPUT @@ -4481,9 +4473,13 @@ bool toggle_rtg (int monid, int mode) return false; } -void close_rtg(int monid) +void close_rtg(int monid, bool reset) { - close_windows(&AMonitors[monid]); + struct AmigaMonitor *mon = &AMonitors[monid]; + close_windows(mon); + if (reset) { + mon->screen_is_picasso = false; + } } void toggle_fullscreen(int monid, int mode) -- 2.47.3