]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
AGA subpixel bitplane delay support rewritten.
authorToni Wilen <twilen@winuae.net>
Thu, 10 Dec 2015 15:43:24 +0000 (17:43 +0200)
committerToni Wilen <twilen@winuae.net>
Thu, 10 Dec 2015 15:43:24 +0000 (17:43 +0200)
custom.cpp
drawing.cpp
genlinetoscr.cpp
include/drawing.h

index fd9dc961f76fde7bd62feb4bf41ba3539d8ca7ce..00266f80b813d63de651e210cda3d6888ec58741 100644 (file)
@@ -1723,6 +1723,27 @@ STATIC_INLINE void flush_display (int fm)
        toscr_nbits = 0;
 }
 
+static void record_color_change(int hpos, int regno, unsigned long value);
+
+static void hack_shres_delay(int hpos)
+{
+       if (!(currprefs.chipset_mask & CSMASK_AGA) && !toscr_delay_sh[0] && !toscr_delay_sh[1])
+               return;
+       int o0 = toscr_delay_sh[0];
+       int o1 = toscr_delay_sh[1];
+       int shdelay1 = (bplcon1 >> 8) & 3;
+       int shdelay2 = (bplcon1 >> 12) & 3;
+       toscr_delay_sh[0] = (shdelay1 & 3) >> toscr_res;
+       toscr_delay_sh[1] = (shdelay2 & 3) >> toscr_res;
+       if (hpos >= 0 && toscr_delay_sh[0] != o0 || toscr_delay_sh[1] != o1) {
+               record_color_change(hpos, 0, COLOR_CHANGE_SHRES_DELAY | toscr_delay_sh[0]);
+               current_colors.extra &= ~(1 << CE_SHRES_DELAY);
+               current_colors.extra &= ~(1 << (CE_SHRES_DELAY + 1));
+               current_colors.extra |= toscr_delay_sh[0] << CE_SHRES_DELAY;
+               remembered_color_entry = -1;
+       }
+}
+
 static void update_denise_shifter_planes (int hpos)
 {
        int np = GET_PLANES (bplcon0d);
@@ -1768,6 +1789,7 @@ static void update_denise (int hpos)
                toscr_nr_planes2 = toscr_nr_planes;
        }
        toscr_nr_planes_shifter = toscr_nr_planes2;
+       hack_shres_delay(hpos);
 }
 
 STATIC_INLINE void fetch_start (int hpos)
@@ -2945,16 +2967,17 @@ static bool isbrdblank (int hpos, uae_u16 bplcon0, uae_u16 bplcon3)
        brdblank = false;
        brdntrans = false;
 #endif
-       if (hpos >= 0 && (current_colors.borderblank != brdblank || current_colors.borderntrans != brdntrans)) {
-               record_color_change (hpos, 0, COLOR_CHANGE_BRDBLANK | (brdblank ? 1 : 0) | (current_colors.bordersprite ? 2 : 0) | (brdntrans ? 4 : 0));
-               current_colors.borderblank = brdblank;
-               current_colors.borderntrans = brdntrans;
+       if (hpos >= 0 && (ce_is_borderblank(current_colors.extra) != brdblank || ce_is_borderntrans(current_colors.extra) != brdntrans)) {
+               record_color_change (hpos, 0, COLOR_CHANGE_BRDBLANK | (brdblank ? 1 : 0) | (ce_is_bordersprite(current_colors.extra) ? 2 : 0) | (brdntrans ? 4 : 0));
+               current_colors.extra &= ~(1 << CE_BORDERBLANK);
+               current_colors.extra &= ~(1 << CE_BORDERNTRANS);
+               current_colors.extra |= brdblank ? (1 << CE_BORDERBLANK) : 0;
+               current_colors.extra |= brdntrans ? (1 << CE_BORDERNTRANS) : 0;
                remembered_color_entry = -1;
        }
        return brdblank;
 }
 
-
 static bool issprbrd (int hpos, uae_u16 bplcon0, uae_u16 bplcon3)
 {
        bool brdsprt;
@@ -2963,14 +2986,15 @@ static bool issprbrd (int hpos, uae_u16 bplcon0, uae_u16 bplcon3)
 #else
        brdsprt = false;
 #endif
-       if (hpos >= 0 && current_colors.bordersprite != brdsprt) {
-               record_color_change (hpos, 0, COLOR_CHANGE_BRDBLANK | (current_colors.borderblank ? 1 : 0) | (current_colors.borderntrans ? 4 : 0) | (brdsprt ? 2 : 0));
-               current_colors.bordersprite = brdsprt;
+       if (hpos >= 0 && ce_is_bordersprite(current_colors.extra) != brdsprt) {
+               record_color_change (hpos, 0, COLOR_CHANGE_BRDBLANK | (ce_is_borderblank(current_colors.extra) ? 1 : 0) | (ce_is_borderntrans(current_colors.extra) ? 4 : 0) | (brdsprt ? 2 : 0));
+               current_colors.extra &= ~(1 << CE_BORDERSPRITE);
+               current_colors.extra |= brdsprt ? (1 << CE_BORDERSPRITE) : 0;
                remembered_color_entry = -1;
-               if (brdsprt && !current_colors.borderblank)
+               if (brdsprt && !ce_is_borderblank(current_colors.extra))
                        thisline_decision.bordersprite_seen = true;
        }
-       return brdsprt && !current_colors.borderblank;
+       return brdsprt && !ce_is_borderblank(current_colors.extra);
 }
 
 static void record_register_change (int hpos, int regno, uae_u16 value)
@@ -5278,17 +5302,6 @@ static void BPLCON0 (int hpos, uae_u16 v)
                BPLCON0_Denise (hpos, v, true);
 }
 
-static void hack_bplcon2(void)
-{
-       // AGA subpixel scrolling in lores/hires modes
-       int shdelay1 = (bplcon1 >> 8) & 3;
-       int shdelay2 = (bplcon1 >> 12) & 3;
-       toscr_delay_sh[0] = (shdelay1 & 3) >> toscr_res;
-       toscr_delay_sh[1] = (shdelay2 & 3) >> toscr_res;
-       bplcon2 &= ~0xc000;
-       bplcon2 |= toscr_delay_sh[0] << 14;
-}
-
 static void BPLCON1 (int hpos, uae_u16 v)
 {
        if (!(currprefs.chipset_mask & CSMASK_AGA))
@@ -5300,16 +5313,7 @@ static void BPLCON1 (int hpos, uae_u16 v)
        decide_fetch_safe (hpos);
        bplcon1_written = true;
        bplcon1 = v;
-
-       if (currprefs.chipset_mask & CSMASK_AGA) {
-               int o0 = toscr_delay_sh[0];
-               int o1 = toscr_delay_sh[1];
-               hack_bplcon2();
-               if (toscr_delay_sh[0] != o0 || toscr_delay_sh[1] != o1) {
-                       // HACK: Use BPLCON2 unused bits to store sh shift
-                       record_register_change(hpos, 0x104, bplcon2);
-               }
-       }
+       hack_shres_delay(hpos);
 }
 
 static void BPLCON2(int hpos, uae_u16 v)
@@ -5320,8 +5324,6 @@ static void BPLCON2(int hpos, uae_u16 v)
                return;
        decide_line (hpos);
        bplcon2 = v;
-       if (currprefs.chipset_mask & CSMASK_AGA)
-               hack_bplcon2();
        record_register_change (hpos, 0x104, bplcon2);
 }
 
@@ -8411,6 +8413,8 @@ void custom_reset (bool hardreset, bool keyboardreset)
        sprite_entries[1][1].first_pixel = MAX_SPR_PIXELS;
        memset (spixels, 0, 2 * MAX_SPR_PIXELS * sizeof *spixels);
        memset (&spixstate, 0, sizeof spixstate);
+       toscr_delay_sh[0] = 0;
+       toscr_delay_sh[1] = 0;
 
        cop_state.state = COP_stop;
        cop_state.movedelay = 0;
@@ -9225,10 +9229,17 @@ uae_u8 *restore_custom (uae_u8 *src)
        i = RW;                                 /* 1FA ? */
        if (i & 0x8000)
                currprefs.ntscmode = changed_prefs.ntscmode = i & 1;
-       fmode = RW;                             /* 1FC FMODE */
+       fmode = fmode_saved = RW; /* 1FC FMODE */
        last_custom_value1 = RW;/* 1FE ? */
 
-       current_colors.borderblank = isbrdblank (-1, bplcon0, bplcon3);
+       current_colors.extra = 0;
+       if (isbrdblank (-1, bplcon0, bplcon3))
+               current_colors.extra |= 1 << CE_BORDERBLANK;
+       if (issprbrd(-1, bplcon0, bplcon3))
+               current_colors.extra |= 1 << CE_BORDERSPRITE;
+       if ((currprefs.chipset_mask & CSMASK_ECS_DENISE) && (bplcon0 & 1) && (bplcon3 & 0x10))
+               current_colors.extra |= 1 << CE_BORDERNTRANS;
+
        DISK_restore_custom (dskpt, dsklen, dskbytr);
 
        return src;
index d618bd2e753b7e6377a66bc081bcf9e50cd0a3e4..3ff4eed2737d2f8963d914972fda4f1b390b1607 100644 (file)
@@ -243,7 +243,6 @@ static int bplehb, bplham, bpldualpf, bpldualpfpri, bpldualpf2of, bplplanecnt, e
 static bool issprites;
 static int bplres;
 static int plf1pri, plf2pri, bplxor, bpldelay_sh;
-static bool enabled_sh;
 static uae_u32 plf_sprite_mask;
 static int sbasecol[2] = { 16, 16 };
 static int hposblank;
@@ -830,7 +829,7 @@ STATIC_INLINE xcolnr getbgc (bool blank)
        //return colors_for_drawing.acolors[0];
        return xcolors[0xf0f];
 #endif
-       return (blank || hposblank || colors_for_drawing.borderblank) ? 0 : colors_for_drawing.acolors[0];
+       return (blank || hposblank || ce_is_borderblank(colors_for_drawing.extra)) ? 0 : colors_for_drawing.acolors[0];
 }
 
 
@@ -902,7 +901,7 @@ static void pfield_init_linetoscr (bool border)
        // before first bitplane pixel appears.
        // This means "bordersprite" condition is possible under OCS/ECS too. Argh!
        if (dip_for_drawing->nr_sprites) {
-               if (!colors_for_drawing.borderblank) {
+               if (!ce_is_borderblank(colors_for_drawing.extra)) {
                        /* 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;
@@ -923,7 +922,7 @@ static void pfield_init_linetoscr (bool border)
 
 #ifdef AGA
        may_require_hard_way = false;
-       if (dp_for_drawing->bordersprite_seen && !colors_for_drawing.borderblank && dip_for_drawing->nr_sprites) {
+       if (dp_for_drawing->bordersprite_seen && !ce_is_borderblank(colors_for_drawing.extra) && dip_for_drawing->nr_sprites) {
                int min = visible_right_border, max = visible_left_border, i;
                for (i = 0; i < dip_for_drawing->nr_sprites; i++) {
                        int x;
@@ -957,7 +956,7 @@ static void pfield_init_linetoscr (bool border)
        int first_x = sprite_first_x;
        int last_x = sprite_last_x;
        if (first_x < last_x) {
-               if (dp_for_drawing->bordersprite_seen && !colors_for_drawing.borderblank) {
+               if (dp_for_drawing->bordersprite_seen && !ce_is_borderblank(colors_for_drawing.extra)) {
                        if (first_x > visible_left_border)
                                first_x = visible_left_border;
                        if (last_x < visible_right_border)
@@ -1276,7 +1275,7 @@ static uae_u8 render_sprites (int pos, int dualpf, uae_u8 apixel, int aga)
 static bool get_genlock_very_rare_and_complex_case(uae_u8 v)
 {
        // border color without BRDNTRAN bit set = transparent
-       if (v == 0 && !colors_for_drawing.borderntrans)
+       if (v == 0 && !ce_is_borderntrans(colors_for_drawing.extra))
                return false;
        if (ecs_genlock_features_colorkey) {
                // color key match?
@@ -1666,6 +1665,10 @@ static int pfield_do_linetoscr_normal_shdelay(int spix, int dpix, int dpix_end)
 {
        int add = get_shdelay_add();
        int add2 = add * gfxvidinfo.drawbuffer.pixbytes;
+       if (add) {
+               // Clear skipped pixel(s).
+               pfield_do_linetoscr_shdelay_sprite(spix, dpix, dpix + add);
+       }
        xlinebuffer += add2;
        int out = pfield_do_linetoscr_shdelay_normal(spix, dpix, dpix_end);
        xlinebuffer -= add2;
@@ -1673,12 +1676,28 @@ static int pfield_do_linetoscr_normal_shdelay(int spix, int dpix, int dpix_end)
 }
 static int pfield_do_linetoscr_sprite_shdelay(int spix, int dpix, int dpix_end)
 {
+       int out = spix;
+       if (dpix < real_playfield_start && dpix_end > real_playfield_start) {
+               // Crosses real_playfield_start.
+               // Render only from dpix to real_playfield_start.
+               int len = real_playfield_start - dpix;
+               out = pfield_do_linetoscr_spriteonly(out, dpix, dpix + len);
+               dpix = real_playfield_start;
+       } else if (dpix_end <= real_playfield_start) {
+               // Does not cross real_playfield_start, nothing special needed.
+               out = pfield_do_linetoscr_spriteonly(out, dpix, dpix_end);
+               return out;
+       }
+       // Render bitplane with subpixel scroll, from real_playfield_start to end.
        int add = get_shdelay_add();
        int add2 = add * gfxvidinfo.drawbuffer.pixbytes;
+       if (add) {
+               pfield_do_linetoscr_shdelay_sprite(out, dpix, dpix + add);
+       }
        sprite_shdelay = add;
        spritepixels += add;
        xlinebuffer += add2;
-       int out = pfield_do_linetoscr_shdelay_sprite(spix, dpix, dpix_end);
+       out = pfield_do_linetoscr_shdelay_sprite(out, dpix, dpix_end);
        xlinebuffer -= add2;
        spritepixels -= add;
        sprite_shdelay = 0;
@@ -1688,7 +1707,6 @@ static int pfield_do_linetoscr_sprite_shdelay(int spix, int dpix, int dpix_end)
 static void pfield_set_linetoscr (void)
 {
        xlinecheck(start, stop);
-       enabled_sh = false;
        spritepixels = spritepixels_buffer;
        pfield_do_linetoscr_spriteonly = pfield_do_nothing;
 #ifdef AGA
@@ -1794,7 +1812,6 @@ static void pfield_set_linetoscr (void)
                        pfield_do_linetoscr_shdelay_sprite = pfield_do_linetoscr_sprite;
                        pfield_do_linetoscr_normal = pfield_do_linetoscr_normal_shdelay;
                        pfield_do_linetoscr_sprite = pfield_do_linetoscr_sprite_shdelay;
-                       enabled_sh = true;
                }
        }
 #endif
@@ -1932,7 +1949,7 @@ static void pfield_do_linetoscr_bordersprite_aga (int start, int stop, bool blan
                pfield_do_fill_line (start, stop, blank);
                return;
        }
-       src_pixel = pfield_do_linetoscr_spriteonly(src_pixel, start, stop);
+       pfield_do_linetoscr_spriteonly(src_pixel, start, stop);
 }
 
 static void dummy_worker (int start, int stop, bool blank)
@@ -2564,12 +2581,13 @@ static void pfield_expand_dp_bplcon (void)
        sbasecol[0] = ((dp_for_drawing->bplcon4 >> 4) & 15) << 4;
        sbasecol[1] = ((dp_for_drawing->bplcon4 >> 0) & 15) << 4;
        bplxor = dp_for_drawing->bplcon4 >> 8;
-       int obpldelay_sh = bpldelay_sh;
-       bpldelay_sh = dp_for_drawing->bplcon2 >> 14;
-       if ((bpldelay_sh && !obpldelay_sh) || (!bpldelay_sh && obpldelay_sh))
+       int sh = (colors_for_drawing.extra >> CE_SHRES_DELAY) & 3;
+       if (sh != bpldelay_sh) {
+               bpldelay_sh = sh;
                pfield_mode_changed = true;
+       }
 #endif
-       ecs_genlock_features_active = (currprefs.chipset_mask & CSMASK_ECS_DENISE) && ((dp_for_drawing->bplcon2 & 0x0c00) || colors_for_drawing.borderntrans) ? 1 : 0;
+       ecs_genlock_features_active = (currprefs.chipset_mask & CSMASK_ECS_DENISE) && ((dp_for_drawing->bplcon2 & 0x0c00) || ce_is_borderntrans(colors_for_drawing.extra)) ? 1 : 0;
        if (ecs_genlock_features_active) {
                ecs_genlock_features_colorkey = false;
                ecs_genlock_features_mask = 0;
@@ -2650,8 +2668,7 @@ static void adjust_drawing_colors (int ctable, int need_full)
                } else {
                        memcpy (colors_for_drawing.acolors, curr_color_tables[ctable].acolors,
                                sizeof colors_for_drawing.acolors);
-                       colors_for_drawing.borderblank = curr_color_tables[ctable].borderblank;
-                       colors_for_drawing.bordersprite = curr_color_tables[ctable].bordersprite;
+                       colors_for_drawing.extra = curr_color_tables[ctable].extra;
                        color_match_type = color_match_acolors;
                }
                drawing_color_matches = ctable;
@@ -2742,9 +2759,17 @@ static void do_color_changes (line_draw_func worker_border, line_draw_func worke
                        pfield_expand_dp_bplconx (regno, value);
                } else if (regno >= 0) {
                        if (regno == 0 && (value & COLOR_CHANGE_BRDBLANK)) {
-                               colors_for_drawing.borderblank = (value & 1) != 0;
-                               colors_for_drawing.bordersprite = (value & 3) == 2;
-                               colors_for_drawing.borderntrans = (value & 5) == 4;
+                               colors_for_drawing.extra &= ~(1 << CE_BORDERBLANK);
+                               colors_for_drawing.extra &= ~(1 << CE_BORDERNTRANS);
+                               colors_for_drawing.extra &= ~(1 << CE_BORDERSPRITE);
+                               colors_for_drawing.extra |= (value & 1) != 0 ? (1 << CE_BORDERBLANK) : 0;
+                               colors_for_drawing.extra |= (value & 3) == 2 ? (1 << CE_BORDERSPRITE) : 0;
+                               colors_for_drawing.extra |= (value & 5) == 4 ? (1 << CE_BORDERNTRANS) : 0;
+                       } else if (regno == 0 && (value & COLOR_CHANGE_SHRES_DELAY)) {
+                               colors_for_drawing.extra &= ~(1 << CE_SHRES_DELAY);
+                               colors_for_drawing.extra &= ~(1 << (CE_SHRES_DELAY + 1));
+                               colors_for_drawing.extra |= (value & 3) << CE_SHRES_DELAY;
+                               pfield_expand_dp_bplcon();
                        } else {
                                color_reg_set (&colors_for_drawing, regno, value);
                                colors_for_drawing.acolors[regno] = getxcolor (value);
@@ -2873,7 +2898,7 @@ static void pfield_draw_line (struct vidbuffer *vb, int lineno, int gfx_ypos, in
                if (dip_for_drawing->nr_sprites) {
                        int i;
 #ifdef AGA
-                       if (colors_for_drawing.bordersprite && dp_for_drawing->bordersprite_seen && !colors_for_drawing.borderblank)
+                       if (ce_is_bordersprite(colors_for_drawing.extra) && dp_for_drawing->bordersprite_seen && !ce_is_borderblank(colors_for_drawing.extra))
                                clear_bitplane_border_aga ();
 #endif
 
@@ -2888,7 +2913,7 @@ static void pfield_draw_line (struct vidbuffer *vb, int lineno, int gfx_ypos, in
                }
 
 #ifdef AGA
-               if (dip_for_drawing->nr_sprites && colors_for_drawing.bordersprite && !colors_for_drawing.borderblank && dp_for_drawing->bordersprite_seen)
+               if (dip_for_drawing->nr_sprites && ce_is_bordersprite(colors_for_drawing.extra) && !ce_is_borderblank(colors_for_drawing.extra) && dp_for_drawing->bordersprite_seen)
                        do_color_changes (pfield_do_linetoscr_bordersprite_aga, pfield_do_linetoscr_spr, lineno);
                else
 #endif
@@ -2918,7 +2943,7 @@ static void pfield_draw_line (struct vidbuffer *vb, int lineno, int gfx_ypos, in
                adjust_drawing_colors (dp_for_drawing->ctable, 0);
 
 #ifdef AGA /* this makes things complex.. */
-               if (dp_for_drawing->bordersprite_seen && !colors_for_drawing.borderblank && dip_for_drawing->nr_sprites) {
+               if (dp_for_drawing->bordersprite_seen && !ce_is_borderblank(colors_for_drawing.extra) && dip_for_drawing->nr_sprites) {
                        dosprites = true;
                        pfield_expand_dp_bplcon ();
                        pfield_init_linetoscr (true);
index 05695b4fb05cfe979e0368ec5ba99d2c58e62036..43f40f5a60f96bfd555de79103d4d3ca39baa0c0 100644 (file)
@@ -190,8 +190,10 @@ static void out_linetoscr_do_dstpix (DEPTH_T bpp, HMODE_T hmode, int aga, CMODE_
 
 static void out_linetoscr_do_incspix (DEPTH_T bpp, HMODE_T hmode, int aga, CMODE_T cmode, int spr)
 {
-       if (spr < 0)
+       if (spr < 0) {
+               outln("    spix++;");
                return;
+       }
        if (hmode == HMODE_HALVE1F) {
                outln (         "    {");
                outln (         "    uae_u32 tmp_val;");
index a7863bc6b9b8a6d49464c15b54ee5d1259c4fc1b..9f25ef44a7fd6fe8a029518f01f8c5d19a3183e9 100644 (file)
@@ -83,6 +83,24 @@ extern int custom_frame_redraw_necessary;
 *
 * !!! See color_reg_xxx functions below before touching !!!
 */
+#define CE_BORDERBLANK 0
+#define CE_BORDERNTRANS 1
+#define CE_BORDERSPRITE 2
+#define CE_SHRES_DELAY 4
+
+STATIC_INLINE bool ce_is_borderblank(uae_u8 data)
+{
+       return (data & (1 << CE_BORDERBLANK)) != 0;
+}
+STATIC_INLINE bool ce_is_bordersprite(uae_u8 data)
+{
+       return (data & (1 << CE_BORDERSPRITE)) != 0;
+}
+STATIC_INLINE bool ce_is_borderntrans(uae_u8 data)
+{
+       return (data & (1 << CE_BORDERNTRANS)) != 0;
+}
+
 struct color_entry {
        uae_u16 color_regs_ecs[32];
 #ifndef AGA
@@ -91,7 +109,7 @@ struct color_entry {
        xcolnr acolors[256];
        uae_u32 color_regs_aga[256];
 #endif
-       bool borderblank, borderntrans, bordersprite;
+       uae_u8 extra;
 };
 
 #ifdef AGA
@@ -146,14 +164,14 @@ STATIC_INLINE int color_reg_cmp (struct color_entry *ce1, struct color_entry *ce
        else
 #endif
                v = memcmp (ce1->color_regs_ecs, ce2->color_regs_ecs, sizeof (uae_u16) * 32);
-       if (!v && ce1->borderblank == ce2->borderblank)
+       if (!v && ce1->extra == ce2->extra)
                return 0;
        return 1;
 }
 /* ugly copy hack, is there better solution? */
 STATIC_INLINE void color_reg_cpy (struct color_entry *dst, struct color_entry *src)
 {
-       dst->borderblank = src->borderblank;
+       dst->extra = src->extra;
 #ifdef AGA
        if (aga_mode)
                /* copy acolors and color_regs_aga */
@@ -174,6 +192,7 @@ STATIC_INLINE void color_reg_cpy (struct color_entry *dst, struct color_entry *s
 */
 
 #define COLOR_CHANGE_BRDBLANK 0x80000000
+#define COLOR_CHANGE_SHRES_DELAY 0x40000000
 struct color_change {
        int linepos;
        int regno;