From: Toni Wilen Date: Thu, 17 Apr 2014 17:33:26 +0000 (+0300) Subject: 2800b16 X-Git-Tag: 2800~3 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=1e47b23058e1787047cec2f61b8c6d8da8a2f72a;p=francis%2Fwinuae.git 2800b16 --- diff --git a/custom.cpp b/custom.cpp index f2c3a388..58e5782b 100644 --- a/custom.cpp +++ b/custom.cpp @@ -217,8 +217,6 @@ static int diw_hcounter; #define HSYNCTIME (maxhpos * CYCLE_UNIT); -/* This is but an educated guess. It seems to be correct, but this stuff -* isn't documented well. */ struct sprite { uaecptr pt; int xpos; @@ -229,6 +227,7 @@ struct sprite { int dmastate; int dmacycle; int ptxhpos; + int ptxhpos2, ptxvpos2; }; static struct sprite spr[MAX_SPRITES]; @@ -250,6 +249,7 @@ static uae_u16 sprdata[MAX_SPRITES][1], sprdatb[MAX_SPRITES][1]; static int sprite_last_drawn_at[MAX_SPRITES]; static int last_sprite_point, nr_armed; static int sprite_width, sprres; +static int sprite_sprctlmask; int sprite_buffer_res; #ifdef CPUEMU_13 @@ -515,6 +515,12 @@ static void update_mirrors (void) { aga_mode = (currprefs.chipset_mask & CSMASK_AGA) != 0; direct_rgb = aga_mode; + if (currprefs.chipset_mask & CSMASK_AGA) + sprite_sprctlmask = 0x01 | 0x08 | 0x10; + else if (currprefs.chipset_mask & CSMASK_ECS_DENISE) + sprite_sprctlmask = 0x01 | 0x10; + else + sprite_sprctlmask = 0x01; } STATIC_INLINE uae_u8 *pfield_xlateptr (uaecptr plpt, int bytecount) @@ -3156,11 +3162,11 @@ static void calcsprite (void) } } -static void decide_sprites (int hpos) +static void decide_sprites (int hpos, bool usepointx) { int nrs[MAX_SPRITES * 2], posns[MAX_SPRITES * 2]; int count, i; - int point = hpos * 2 + 1; + int point = hpos * 2 + 0; int width = sprite_width; int sscanmask = 0x100 << sprite_buffer_res; int gotdata = 0; @@ -3179,6 +3185,7 @@ static void decide_sprites (int hpos) for (i = 0; i < MAX_SPRITES; i++) { int sprxp = (fmode & 0x8000) ? (spr[i].xpos & ~sscanmask) : spr[i].xpos; int hw_xp = sprxp >> sprite_buffer_res; + int pointx = usepointx && (sprctl[i] & sprite_sprctlmask) ? 0 : 1; if (spr[i].xpos < 0) continue; @@ -3189,15 +3196,17 @@ static void decide_sprites (int hpos) if (! spr[i].armed) continue; - if (hw_xp > last_sprite_point && hw_xp <= point) + if (hw_xp > last_sprite_point && hw_xp <= point + pointx) { add_sprite (&count, i, sprxp, posns, nrs); + } /* SSCAN2-bit is fun.. */ if ((fmode & 0x8000) && !(sprxp & sscanmask)) { sprxp |= sscanmask; hw_xp = sprxp >> sprite_buffer_res; - if (hw_xp > last_sprite_point && hw_xp <= point) + if (hw_xp > last_sprite_point && hw_xp <= point + pointx) { add_sprite (&count, MAX_SPRITES + i, sprxp, posns, nrs); + } } } @@ -3237,6 +3246,10 @@ static void decide_sprites (int hpos) } #endif } +static void decide_sprites(int hpos) +{ + decide_sprites(hpos, false); +} static int sprites_differ (struct draw_info *dip, struct draw_info *dip_old) { @@ -5350,25 +5363,64 @@ static void SPRxDATB_1(uae_u16 v, int num, int hpos) #endif } -// hpos - 1 is a hack! There is 1 cycle delay before SPRxPOS matches and DATx are copied to -// shift register, it is easier and much faster to emulate this way, than to separate -// decide_sprites() in two parts. -// Shed Tears / Ozone scroller +/* + SPRxDATA and SPRxDATB is moved to shift register when SPRxPOS matches. + + When copper writes to SPRxDATx exactly when SPRxPOS matches: + - If sprite low x bit (SPRCTL bit 0) is not set, shift register copy + is done first (previously loaded SPRxDATx value is shown) and then + new SPRxDATx gets stored for future use. + - If sprite low x bit is set, new SPRxDATx is stored, then SPRxPOS + matches and value written to SPRxDATx is visible. + + - Writing to SPRxPOS when SPRxPOS matches: shift register + copy is always done first, then new SPRxPOS value is stored + for future use. (SPRxCTL not tested) +*/ + static void SPRxDATA (int hpos, uae_u16 v, int num) { - int hp = hpos == 0 ? 0 : hpos - 1; - decide_sprites (hp); - SPRxDATA_1 (v, num, hp); + decide_sprites(hpos, true); + SPRxDATA_1(v, num, hpos); } static void SPRxDATB (int hpos, uae_u16 v, int num) { - int hp = hpos; - decide_sprites (hp); - SPRxDATB_1 (v, num, hp); + decide_sprites(hpos, true); + SPRxDATB_1(v, num, hpos); +} + +static void SPRxCTL (int hpos, uae_u16 v, int num) +{ +#if SPRITE_DEBUG > 0 + if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY && (SPRITE_DEBUG & (1 << num))) { + write_log(_T("%d:%d:SPR%dCTLC %06X\n"), vpos, hpos, num, spr[num].pt); + } +#endif + + decide_sprites(hpos); + SPRxCTL_1(v, num, hpos); +} +static void SPRxPOS (int hpos, uae_u16 v, int num) +{ + struct sprite *s = &spr[num]; + int oldvpos; +#if SPRITE_DEBUG > 0 + if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY && (SPRITE_DEBUG & (1 << num))) { + write_log(_T("%d:%d:SPR%dPOSC %06X\n"), vpos, hpos, num, s->pt); + } +#endif + decide_sprites(hpos); + oldvpos = s->vstart; + SPRxPOS_1(v, num, hpos); + // Superfrog flashing intro bees fix. + // if SPRxPOS is written one cycle before sprite's first DMA slot and sprite's vstart matches after + // SPRxPOS write, current line's DMA slot's stay idle. DMA decision seems to be done 4 cycles earlier. + if (hpos >= SPR0_HPOS + num * 4 - 4 && hpos <= SPR0_HPOS + num * 4 - 1 && oldvpos != vpos) { + s->ptxvpos2 = vpos; + s->ptxhpos2 = hpos + 4; + } } -static void SPRxCTL (int hpos, uae_u16 v, int num) { decide_sprites (hpos); SPRxCTL_1 (v, num, hpos); } -static void SPRxPOS (int hpos, uae_u16 v, int num) { decide_sprites (hpos); SPRxPOS_1 (v, num, hpos); } static void SPRxPTH (int hpos, uae_u16 v, int num) { decide_sprites (hpos); @@ -5657,8 +5709,12 @@ static int customdelay[]= { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 16 */ /* SPRxPTH/SPRxPTL */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 16 */ + /* SPRxPOS/SPRxCTL/SPRxDATA/SPRxDATB */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +// 1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0, +// 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + /* COLORxx */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* RESERVED */ @@ -5886,12 +5942,7 @@ static void update_copper (int until_hpos) cop_state.movedata = data; cop_state.movedelay = customdelay[cop_state.moveaddr / 2]; } else { - int hpos2 = old_hpos; - custom_wput_copper (hpos2, reg, data, 0); - hpos2++; - if (!nocustom () && reg >= 0x140 && reg < 0x180 && hpos2 >= SPR0_HPOS && hpos2 < SPR0_HPOS + 4 * MAX_SPRITES) { - do_sprites (hpos2); - } + custom_wput_copper (old_hpos, reg, data, 0); } #endif } @@ -6185,6 +6236,8 @@ static void do_sprites_1(int num, int cycle, int hpos) write_log (_T("%d:%d:SPR%d START\n"), vpos, hpos, num); #endif s->dmastate = 1; + if (s->ptxvpos2 == vpos && hpos < s->ptxhpos2) + return; if (num == 0 && cycle == 0) cursorsprite (); } @@ -6194,19 +6247,10 @@ static void do_sprites_1(int num, int cycle, int hpos) write_log (_T("%d:%d:SPR%d STOP\n"), vpos, hpos, num); #endif s->dmastate = 0; -#if 0 - // roots 2.0 flower zoomer bottom part missing if this enabled - if (vpos == s->vstop) { - spr_arm (num, 0); - //return; - } -#endif } if (!isdma) return; - if (cycle && !s->dmacycle) - return; /* Superfrog intro flashing bee fix */ dma = hpos < plfstrt_sprite || diwstate != DIW_waiting_stop; if (vpos == s->vstop || vpos == sprite_vblank_endline) { @@ -6421,8 +6465,10 @@ static void init_hardware_frame (void) first_bplcon0 = 0; autoscale_bordercolors = 0; - for (i = 0; i < MAX_SPRITES; i++) + for (i = 0; i < MAX_SPRITES; i++) { spr[i].ptxhpos = MAXHPOS; + spr[i].ptxvpos2 = -1; + } plf_state = plf_end; } diff --git a/drawing.cpp b/drawing.cpp index 7dca4e7f..39d3f880 100644 --- a/drawing.cpp +++ b/drawing.cpp @@ -827,16 +827,22 @@ static void pfield_init_linetoscr (bool border) // Sprite hpos don't include DIW_DDF_OFFSET and can appear 1 lores pixel // before first bitplane pixel appears. // This means "bordersprite" condition is possible under OCS/ECS too. Argh! - if (dip_for_drawing->nr_sprites && !colors_for_drawing.borderblank) { - /* bordersprite off or not supported: sprites are visible until diw_end */ - if (playfield_end < linetoscr_diw_end && hblank_right_stop > playfield_end) { - playfield_end = linetoscr_diw_end; - } - int left = coord_hw_to_window_x (dp_for_drawing->plfleft * 2); - if (left < visible_left_border) - left = visible_left_border; - if (left < playfield_start && left >= linetoscr_diw_start) { - playfield_start = left; + if (dip_for_drawing->nr_sprites) { + if (!colors_for_drawing.borderblank) { + /* bordersprite off or not supported: sprites are visible until diw_end */ + if (playfield_end < linetoscr_diw_end && hblank_right_stop > playfield_end) { + playfield_end = linetoscr_diw_end; + } + int left = coord_hw_to_window_x (dp_for_drawing->plfleft * 2); + if (left < visible_left_border) + left = visible_left_border; + if (left < playfield_start && left >= linetoscr_diw_start) { + playfield_start = left; + } + } else { + if (playfield_end < linetoscr_diw_end && hblank_right_stop > playfield_end) { + playfield_end = linetoscr_diw_end; + } } } @@ -2656,9 +2662,6 @@ static void init_drawing_frame (void) static int frame_res_old; if (lines_count > 0) { - int frame_res_detected; - int frame_res_lace_detected = frame_res_lace; - int largest_count = 0; int largest_count_res = 0; int largest_res = 0; @@ -2696,6 +2699,8 @@ static void init_drawing_frame (void) } if (currprefs.gfx_autoresolution) { + int frame_res_detected; + int frame_res_lace_detected = frame_res_lace; if (currprefs.gfx_autoresolution == 1 || currprefs.gfx_autoresolution >= 100) frame_res_detected = largest_res; diff --git a/newcpu.cpp b/newcpu.cpp index eb01629a..332d3f5d 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -1305,7 +1305,7 @@ static int check_prefs_changed_cpu2(void) int changed = 0; #ifdef JIT - changed = check_prefs_changed_comp (); + changed = check_prefs_changed_comp() ? 1 : 0; #endif if (changed || currprefs.cpu_model != changed_prefs.cpu_model @@ -1322,8 +1322,6 @@ static int check_prefs_changed_cpu2(void) || currprefs.m68k_speed_throttle != changed_prefs.m68k_speed_throttle || currprefs.cpu_clock_multiplier != changed_prefs.cpu_clock_multiplier || currprefs.cpu_frequency != changed_prefs.cpu_frequency) { - currprefs.m68k_speed = changed_prefs.m68k_speed; - currprefs.m68k_speed_throttle = changed_prefs.m68k_speed_throttle; changed |= 2; } return changed; @@ -4307,6 +4305,7 @@ void m68k_go (int may_quit) fill_prefetch(); } if (v & 2) { + fixup_cpu(&changed_prefs); currprefs.m68k_speed = changed_prefs.m68k_speed; currprefs.m68k_speed_throttle = changed_prefs.m68k_speed_throttle; update_68k_cycles(); diff --git a/od-win32/avioutput.cpp b/od-win32/avioutput.cpp index 32309c33..9e655a72 100644 --- a/od-win32/avioutput.cpp +++ b/od-win32/avioutput.cpp @@ -560,19 +560,17 @@ static int AVIOutput_GetCOMPVARSFromRegistry (COMPVARS *pcv) pcv->lpbiIn = pcv->lpbiOut = 0; pcv->cbState = 0; if (regquerydatasize (avikey, _T("VideoConfigurationState"), &ss)) { + LPBYTE state = NULL; if (ss > 0) { - LPBYTE state = xmalloc (BYTE, ss); - if (regquerydata (avikey, _T("VideoConfigurationState"), state, &ss)) { - pcv->hic = ICOpen (pcv->fccType, pcv->fccHandler, ICMODE_COMPRESS); - if (pcv->hic) { - ok = 1; - ICSetState (pcv->hic, state, ss); - } - } - xfree (state); - } else { + state = xmalloc (BYTE, ss); + regquerydata(avikey, _T("VideoConfigurationState"), state, &ss); + } + pcv->hic = ICOpen (pcv->fccType, pcv->fccHandler, ICMODE_COMPRESS); + if (pcv->hic) { ok = 1; + ICSetState (pcv->hic, state, ss); } + xfree (state); } } } diff --git a/od-win32/win32.h b/od-win32/win32.h index 628e7061..d86ec664 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -19,11 +19,11 @@ #define LANG_DLL 1 #if WINUAEPUBLICBETA -#define WINUAEBETA _T("15") +#define WINUAEBETA _T("16") #else #define WINUAEBETA _T("") #endif -#define WINUAEDATE MAKEBD(2014, 4, 13) +#define WINUAEDATE MAKEBD(2014, 4, 17) #define WINUAEEXTRA _T("") //#define WINUAEEXTRA _T("AmiKit Preview") //#define WINUAEEXTRA _T("Amiga Forever Edition") diff --git a/od-win32/win32gfx.cpp b/od-win32/win32gfx.cpp index e5bcf5be..1e032007 100644 --- a/od-win32/win32gfx.cpp +++ b/od-win32/win32gfx.cpp @@ -1769,6 +1769,8 @@ int check_prefs_changed_gfx (void) c |= gf->gfx_filter_scanlinelevel != gfc->gfx_filter_scanlinelevel ? (1|8) : 0; c |= gf->gfx_filter_scanlineratio != gfc->gfx_filter_scanlineratio ? (1|8) : 0; c |= gf->gfx_filter_aspect != gfc->gfx_filter_aspect ? (1) : 0; + c |= gf->gfx_filter_keep_aspect != gfc->gfx_filter_keep_aspect ? (1) : 0; + c |= gf->gfx_filter_keep_autoscale_aspect != gfc->gfx_filter_keep_autoscale_aspect ? (1) : 0; c |= gf->gfx_filter_luminance != gfc->gfx_filter_luminance ? (1) : 0; c |= gf->gfx_filter_contrast != gfc->gfx_filter_contrast ? (1) : 0; c |= gf->gfx_filter_saturation != gfc->gfx_filter_saturation ? (1) : 0; @@ -1867,6 +1869,8 @@ int check_prefs_changed_gfx (void) gf->gfx_filter_noise = gfc->gfx_filter_noise; gf->gfx_filter_blur = gfc->gfx_filter_blur; gf->gfx_filter_aspect = gfc->gfx_filter_aspect; + gf->gfx_filter_keep_aspect = gfc->gfx_filter_keep_aspect; + gf->gfx_filter_keep_autoscale_aspect = gfc->gfx_filter_keep_autoscale_aspect; gf->gfx_filter_luminance = gfc->gfx_filter_luminance; gf->gfx_filter_contrast = gfc->gfx_filter_contrast; gf->gfx_filter_saturation = gfc->gfx_filter_saturation; diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index ea4b8108..631b385d 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -11,6 +11,15 @@ - restore only single input target to default. +Beta 16: + +- Borderblank blanked sprites incorrectly in some situations (b11, Roots AGA) +- SPRxDATx/SPRxPOS copper write/Denise internal sprite behavior should now fully match real hardware. +- Ancient (and recently non-working) Superfrog flashing intro bee hack removed, properly emulated now. +- gfx_filter_keep_autoscale_aspect and gfx_filter_keep_aspect config entry change was not detected + when using using uae-configuration. +- Last used AVI codec was not restored from registry if ICGetState() returned zero size data block. + Beta 15: - Finally bumped version to 2.8.0. This isn't small 2.7.0 update (Should have been done since b6 or so..)