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;
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)
{
beamcon0 = new_beamcon0;
doublescan = 0;
+ doublescan2x = 0;
programmedmode = 0;
lines_after_beamcon_change = 5;
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) {
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;
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. */
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--;
}
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;
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;
#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
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);
}
}
#endif
- cw = avidinfo->outbuffer->outwidth << 1;
+ cw = avidinfo->outbuffer->outwidth << (RES_MAX - currprefs.gfx_resolution);
} else {
cw = v;
}
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;
}
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) {
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;
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;
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;
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: