]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
2800b16
authorToni Wilen <twilen@winuae.net>
Thu, 17 Apr 2014 17:33:26 +0000 (20:33 +0300)
committerToni Wilen <twilen@winuae.net>
Thu, 17 Apr 2014 17:33:26 +0000 (20:33 +0300)
custom.cpp
drawing.cpp
newcpu.cpp
od-win32/avioutput.cpp
od-win32/win32.h
od-win32/win32gfx.cpp
od-win32/winuaechangelog.txt

index f2c3a388771aeb8cbefff4dbc02ccedba2036ede..58e5782ba5afd64aadce7f5bd26a04aac603abe8 100644 (file)
@@ -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;
 }
 
index 7dca4e7ff323954602e2a64aeb686c2a3b0be3af..39d3f880ab63fae9ff097ad2e2eeb092225927f5 100644 (file)
@@ -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;
index eb01629a8eb714f23564eea1119ecedda79df32b..332d3f5d0f6493d576f0ed82aac7e97ffc48e41d 100644 (file)
@@ -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();
index 32309c3330174de6176ff46a10c84eaad855e529..9e655a72ee4a68ebdb91ea2b44fc0702f5340d4e 100644 (file)
@@ -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);
                        }
                }
        }
index 628e70611c5defe2e5ab896efd80db66e7355741..d86ec664b4e97611e62d9a90c0bcc6222e2a02b1 100644 (file)
 #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")
index e5bcf5bebe2ede5da240e303dfb103d88928e1cd..1e0320072716fe93f44b72ce8b83771a41c624f5 100644 (file)
@@ -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;
index ea4b81087f0a28dc051751aad1e11319184a72e4..631b385d68aa85e228fa2f65197d0d1c0dd56cfc 100644 (file)
 
 - 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..)