From: Toni Wilen Date: Sun, 8 Mar 2026 18:40:44 +0000 (+0200) Subject: Screen mode aspect ratio auto detection updates X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=1722a382062b61d5f3bd7345601916c691f3f6bb;p=francis%2Fwinuae.git Screen mode aspect ratio auto detection updates --- diff --git a/custom.cpp b/custom.cpp index b5d474b0..883c00d1 100644 --- a/custom.cpp +++ b/custom.cpp @@ -619,7 +619,7 @@ 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; -int doublescan; +int doublescan, doublescan2x; int programmedmode; frame_time_t syncbase; static int fmode_saved, fmode, fmode_inuse; @@ -1775,6 +1775,23 @@ void compute_framesync(void) resetfulllinestate(); } +static bool line_is_doubled(void) +{ + if (doflickerfix_active()) { + return true; + } + if (!interlace_seen && doublescan <= 0 && currprefs.gfx_vresolution && currprefs.gfx_pscanlines > 1) { + return true; + } + if ((doublescan <= 0 || interlace_seen > 0) && currprefs.gfx_vresolution && currprefs.gfx_iscanlines) { + return true; + } + if (currprefs.gfx_vresolution && (doublescan <= 0 || interlace_seen > 0)) { + return true; + } + return false; +} + /* set PAL/NTSC or custom timing variables */ static void init_beamcon0(void) { @@ -1785,6 +1802,7 @@ static void init_beamcon0(void) beamcon0 = new_beamcon0; doublescan = 0; + doublescan2x = 0; programmedmode = 0; lines_after_beamcon_change = 5; @@ -2191,13 +2209,30 @@ static void init_beamcon0(void) maxvpos_display = vsync_lines; programmedmode = 2; - if ((hsync_ccks < 226 || hsync_ccks > 229) || (vsync_lines < 256 || vsync_lines > 320)) { - doublescan = hsync_ccks <= 164 && vsync_lines >= 350 ? 1 : 0; - // if superhires and wide enough: not doublescan - if (doublescan && hsync_ccks >= 140 && (bplcon0 & 0x0040)) - doublescan = 0; + } + + int hpixels = maxhpos_display * 2; + int vpixels = vsync_lines - minfirstline; + int hpixelsd = hpixels * 80 / 100; + if (hpixelsd < vpixels) { + doublescan = 1; + if (programmedmode == 2) { programmedmode = 1; } + hpixelsd *= 2; + } + bool dbl = line_is_doubled(); + if (dbl) { + vpixels *= 2; + } + if (hpixelsd < vpixels) { + doublescan2x = 1; + hpixelsd *= 2; + if (hpixelsd < vpixels) { + doublescan2x = 2; + } + } else if (hpixelsd > vpixels * 2) { + doublescan2x = -1; } if (maxvpos_nom >= MAXVPOS) { diff --git a/drawing.cpp b/drawing.cpp index 49626d8c..9617632c 100644 --- a/drawing.cpp +++ b/drawing.cpp @@ -407,6 +407,7 @@ static bool ecs_genlock_features_active; static uae_u8 ecs_genlock_features_mask; static bool ecs_genlock_features_colorkey; static bool aga_genlock_features_zdclken; +static int doublescan2xx; uae_sem_t gui_sem; @@ -1393,8 +1394,9 @@ static void center_image(void) visible_left_border = maxdiw - w; visible_left_border &= ~((xshift(1, 0)) - 1); + int hresdb = hresolution_inv + (doublescan == 1 ? 1 : 0); int ww = (diwlastword_total - diwfirstword_total) >> hresolution_inv; - int wx = ((diwfirstword_total) >> hresolution_inv) - (((hdisplay_left_border - 1) * 4) >> (hresolution_inv + (doublescan == 1 ? 1 : 0))); + int wx = ((diwfirstword_total) >> hresdb) - (((hdisplay_left_border - 1) * 4) >> hresdb); if (ww < w && currprefs.gfx_xcenter == 2) { /* Try to center. */ @@ -3233,9 +3235,24 @@ static void expand_bplcon1(uae_u16 v) check_lts_request(); } +int getvresolution(void) +{ + int v = currprefs.gfx_vresolution; + if (v < 0) { + return 0; + } + return v; +} + int gethresolution(void) { - int h = currprefs.gfx_resolution; + int h = currprefs.gfx_resolution - doublescan2x - doublescan2xx; + if (h < 0) { + h = 0; + } + if (h > RES_MAX2X) { + h = RES_MAX2X; + } if (autoswitch_old_resolution == RES_HIRES && currprefs.gfx_resolution == RES_SUPERHIRES) { h--; } @@ -3245,10 +3262,12 @@ int gethresolution(void) static void sethresolution(void) { hresolution = currprefs.gfx_resolution; + doublescan2xx = 0; if (doublescan == 1) { hresolution++; if (hresolution > RES_SUPERHIRES) { hresolution = RES_SUPERHIRES; + doublescan2xx = 1; } } hresolution_inv = RES_MAX - hresolution; diff --git a/include/custom.h b/include/custom.h index 19f7018b..5bafd4fa 100644 --- a/include/custom.h +++ b/include/custom.h @@ -143,7 +143,7 @@ extern int hsyncstartpos_hw, hsyncendpos_hw; extern int minfirstline, minfirstline_linear, vblank_endline, numscrlines, minfirstline_linear; extern float vblank_hz, fake_vblank_hz; extern float hblank_hz; -extern int vblank_skip, doublescan; +extern int vblank_skip, doublescan, doublescan2x; extern int programmedmode; extern int display_reset; @@ -190,6 +190,7 @@ extern int xbluecolor_s, xbluecolor_b, xbluecolor_m; #define RES_HIRES 1 #define RES_SUPERHIRES 2 #define RES_MAX 2 +#define RES_MAX2X 3 #define VRES_NONDOUBLE 0 #define VRES_DOUBLE 1 #define VRES_QUAD 2 diff --git a/include/drawing.h b/include/drawing.h index a9c9b2f3..16c34420 100644 --- a/include/drawing.h +++ b/include/drawing.h @@ -197,6 +197,7 @@ void denise_handle_quick_strobe_queue(uae_u16 strobe, int strobe_pos, int endpos bool drawing_can_lineoptimizations(void); void set_drawbuffer(void); int gethresolution(void); +int getvresolution(void); void denise_update_reg_queue(uae_u16 reg, uae_u16 v, uae_u32 linecnt); void denise_store_restore_registers_queue(bool store, uae_u32 linecnt); void denise_clearbuffers(void); diff --git a/od-win32/win32_scaler.cpp b/od-win32/win32_scaler.cpp index c97636d5..abb79070 100644 --- a/od-win32/win32_scaler.cpp +++ b/od-win32/win32_scaler.cpp @@ -65,7 +65,7 @@ static bool getmanualpos(int monid, int *cxp, int *cyp, int *cwp, int *chp) } } #endif - cw = avidinfo->outbuffer->outwidth << 1; + cw = avidinfo->outbuffer->outwidth << (RES_MAX - currprefs.gfx_resolution); } else { cw = v; } @@ -83,7 +83,7 @@ static bool getmanualpos(int monid, int *cxp, int *cyp, int *cwp, int *chp) ch = native ? (current_linear_vpos - minfirstline) << VRES_MAX : avidinfo->outbuffer->outheight; } #endif - ch = avidinfo->outbuffer->outheight; + ch = avidinfo->outbuffer->outheight << (VRES_MAX - currprefs.gfx_vresolution); } else { ch = v; } @@ -284,10 +284,11 @@ void getfilterdata(int monid, struct displayscale *ds) filter_aspect = 0; keep_aspect = 0; if (ds->dstwidth >= 640 && ds->dstwidth <= 800 && ds->dstheight >= 480 && ds->dstheight <= 600) { + int hres = currprefs.gfx_resolution + doublescan2x; autoselect = 1; scalemode = AUTOSCALE_NONE; int m = 1; - int w = AMIGA_WIDTH_MAX << currprefs.gfx_resolution; + int w = AMIGA_WIDTH_MAX << hres; int h = AMIGA_HEIGHT_MAX << currprefs.gfx_vresolution; for (;;) { if (w * (m * 2) > ds->dstwidth || h * (m * 2) > ds->dstheight) { @@ -321,7 +322,7 @@ void getfilterdata(int monid, struct displayscale *ds) if (scalemode) { int cw, ch, cx, cy, cv = 0, crealh = 0; int hres = gethresolution(); - int vres = currprefs.gfx_vresolution; + int vres = getvresolution(); static int oxmult, oymult; filterxmult = (float)ds->scale; @@ -526,16 +527,23 @@ void getfilterdata(int monid, struct displayscale *ds) if (scalemode == AUTOSCALE_CENTER) { - int scalex = ds->scale; - int scaley = ds->scale; + float scalex = ds->scale; + float scaley = ds->scale; + float scale2x = 1.0; + float scale2y = 1.0; + if (doublescan2x > 0) { + scale2x = 0.5 / doublescan2x; + } else if (doublescan2x < 0) { + scale2y = 0.5 / (-doublescan2x); + } int ww = cw * scalex; int hh = ch * scaley; - ds->outwidth = ds->dstwidth * ds->scale; - ds->outheight = ds->dstheight * ds->scale; - ds->xoffset += cx * ds->scale - (ds->dstwidth - ww) / 2; - ds->yoffset += cy * ds->scale - (ds->dstheight - hh) / 2; + ds->outwidth = ds->dstwidth * scalex * scale2x; + ds->outheight = ds->dstheight * scaley * scale2y; + ds->xoffset += cx * scalex - (ds->outwidth - ww) / 2; + ds->yoffset += cy * scaley - (ds->outheight - hh) / 2; goto cont; @@ -586,6 +594,12 @@ void getfilterdata(int monid, struct displayscale *ds) float palntscratio = getpalntscratio(dstratio, keep_aspect, palntscadjust); scaley = scaley * palntscratio / dstratio; + if (doublescan2x > 0) { + scalex *= 2.0 * doublescan2x; + } else if (doublescan2x < 0) { + scaley *= 2.0 * (-doublescan2x); + } + ds->outwidth = (int)(cw * ds->scale); ds->outheight = (int)(ch * ds->scale); ds->xoffset += cx * ds->scale; @@ -674,10 +688,18 @@ void getfilterdata(int monid, struct displayscale *ds) int ch = avidinfo->drawbuffer.inheight; set_custom_limits(cw, ch, 0, 0, true); - ds->outwidth = ds->dstwidth; - ds->outheight = ds->dstheight; - ds->xoffset = (ds->srcwidth - ds->dstwidth) / 2; - ds->yoffset = (ds->srcheight - ds->dstheight) / 2; + int dw = ds->dstwidth; + int dh = ds->dstheight; + if (doublescan2x > 0) { + dw >>= doublescan2x; + } else if (doublescan2x < 0) { + dh >>= -doublescan2x; + } + + ds->outwidth = dw; + ds->outheight = dh; + ds->xoffset = (ds->srcwidth - dw) / 2; + ds->yoffset = (ds->srcheight - dh) / 2; } cont: