]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Screen mode aspect ratio auto detection updates
authorToni Wilen <twilen@winuae.net>
Sun, 8 Mar 2026 18:40:44 +0000 (20:40 +0200)
committerToni Wilen <twilen@winuae.net>
Sun, 8 Mar 2026 18:40:44 +0000 (20:40 +0200)
custom.cpp
drawing.cpp
include/custom.h
include/drawing.h
od-win32/win32_scaler.cpp

index b5d474b0dcca1de838d4a249c337ff72e1317522..883c00d160b0291ba7109651696e3394da2f86c8 100644 (file)
@@ -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) {
index 49626d8c8dcc8d88e756214ab5481e38e8429fa6..9617632ce3b000214beb73264712605c62e1b533 100644 (file)
@@ -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;
index 19f7018b4619e8a74fac96bce0f4aceb4b5ffec1..5bafd4fa7ac709c4c1ec5ca36f87bf42e6efd433 100644 (file)
@@ -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
index a9c9b2f3b0537c3b4f27432591323112ec231dce..16c34420b9e6d89b32b4b5b3b767e3f28252084c 100644 (file)
@@ -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);
index c97636d5a29881bd04728c5d4e5b1bbb04559757..abb79070050224613f9617afaddfe88a979d17ea 100644 (file)
@@ -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: