From f45a09ce5dda55868e60ab97a0afe6856ac29b5a Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sat, 6 Oct 2018 18:40:56 +0300 Subject: [PATCH] Implement AGA 32/64-pixel wide sprite undocumented size behavior when FMODE is changed. --- custom.cpp | 225 ++++++++++++++++++++++++++++------------------ drawing.cpp | 25 +++++- include/drawing.h | 13 ++- 3 files changed, 167 insertions(+), 96 deletions(-) diff --git a/custom.cpp b/custom.cpp index 7e9085fa..e82f44e0 100644 --- a/custom.cpp +++ b/custom.cpp @@ -150,6 +150,7 @@ static bool graphicsbuffer_retry; static int scanlinecount; static int cia_hsync; static bool toscr_scanline_complex_bplcon1; +static bool spr_width_64_seen; #define LOF_TOGGLES_NEEDED 3 //#define NLACE_CNT_NEEDED 50 @@ -233,6 +234,14 @@ struct sprite { int ptxhpos; int ptxhpos2, ptxvpos2; bool ignoreverticaluntilnextline; + int width; + + uae_u16 ctl, pos; +#ifdef AGA + uae_u16 data[4], datb[4]; +#else + uae_u16 data[1], datb[1]; +#endif }; static struct sprite spr[MAX_SPRITES]; @@ -246,13 +255,6 @@ static uae_u8 magic_sprite_mask = 0xff; static int sprite_vblank_endline = VBLANK_SPRITE_PAL; -static uae_u16 sprctl[MAX_SPRITES], sprpos[MAX_SPRITES]; -#ifdef AGA -static uae_u16 sprdata[MAX_SPRITES][4], sprdatb[MAX_SPRITES][4]; -#else -static uae_u16 sprdata[MAX_SPRITES][1], sprdatb[MAX_SPRITES][1]; -#endif -static int sprite_last_drawn_at[MAX_SPRITES]; static int last_sprite_point, nr_armed; static int sprite_width, sprres; static int sprite_sprctlmask; @@ -858,6 +860,7 @@ static void finish_playfield_line (void) #endif #ifdef AGA || line_decisions[next_lineno].bplcon4 != thisline_decision.bplcon4 + || line_decisions[next_lineno].fmode != thisline_decision.fmode #endif ) #endif /* SMART_UPDATE */ @@ -3882,12 +3885,12 @@ superhires pixels (if AGA). */ static void record_sprite (int line, int num, int sprxp, uae_u16 *data, uae_u16 *datb, unsigned int ctl) { struct sprite_entry *e = curr_sprite_entries + next_sprite_entry; - int i; int word_offs; uae_u32 collision_mask; int width, dbl, half; unsigned int mask = 0; int attachment; + int spr_width; half = 0; dbl = sprite_buffer_res - sprres; @@ -3896,11 +3899,13 @@ static void record_sprite (int line, int num, int sprxp, uae_u16 *data, uae_u16 dbl = 0; mask = 1 << half; } - width = (sprite_width << sprite_buffer_res) >> sprres; - attachment = sprctl[num | 1] & 0x80; + spr_width = spr[num].width; + width = (spr_width << sprite_buffer_res) >> sprres; + attachment = spr[num | 1].ctl & 0x80; /* Try to coalesce entries if they aren't too far apart */ - if (!next_sprite_forced && e[-1].max + sprite_width >= sprxp) { + /* Don't coelesce 64-bit wide sprites, needed to support FMODE change tricks */ + if (!next_sprite_forced && e[-1].max + spr_width >= sprxp) { e--; } else { next_sprite_entry++; @@ -3918,7 +3923,7 @@ static void record_sprite (int line, int num, int sprxp, uae_u16 *data, uae_u16 collision_mask = clxmask[clxcon >> 12]; word_offs = e->first_pixel + sprxp - e->pos; - for (i = 0; i < sprite_width; i += 16) { + for (int i = 0; i < spr_width; i += 16) { unsigned int da = *data; unsigned int db = *datb; uae_u32 datab = ((sprtaba[da & 0xFF] << 16) | sprtaba[da >> 8] @@ -3937,8 +3942,8 @@ static void record_sprite (int line, int num, int sprxp, uae_u16 *data, uae_u16 low order bit records whether the attach bit was set for this pair. */ if (attachment && !ecsshres ()) { uae_u32 state = 0x01010101 << (num & ~1); - uae_u8 *stb1 = spixstate.bytes + word_offs; - for (i = 0; i < width; i += 8) { + uae_u8 *stb1 = spixstate.stb + word_offs; + for (int i = 0; i < width; i += 8) { stb1[0] |= state; stb1[1] |= state; stb1[2] |= state; @@ -3951,6 +3956,25 @@ static void record_sprite (int line, int num, int sprxp, uae_u16 *data, uae_u16 } e->has_attached = 1; } + /* 64 pixel wide sprites' first 32 pixels work differently than + * last 32 pixels if FMODE is changed when sprite is being drawn + */ + if (spr_width == 64) { + uae_u16 *stbfm = spixstate.stbfm + word_offs; + uae_u16 state = (3 << (2 * num)); + for (int i = 0; i < width / 2; i += 8) { + stbfm[0] |= state; + stbfm[1] |= state; + stbfm[2] |= state; + stbfm[3] |= state; + stbfm[4] |= state; + stbfm[5] |= state; + stbfm[6] |= state; + stbfm[7] |= state; + stbfm += 8; + } + spr_width_64_seen = true; + } } static void add_sprite (int *countp, int num, int sprxp, int posns[], int nrs[]) @@ -4021,7 +4045,6 @@ static void decide_sprites(int spnr, int hpos, bool usepointx, bool quick) int nrs[MAX_SPRITES * 2], posns[MAX_SPRITES * 2]; int count, i; int point; - int width = sprite_width; int sscanmask = 0x100 << sprite_buffer_res; int gotdata = 0; int startnr = 0, endnr = MAX_SPRITES - 1; @@ -4050,10 +4073,11 @@ static void decide_sprites(int spnr, int hpos, bool usepointx, bool quick) count = 0; for (i = startnr; i <= endnr; i++) { + struct sprite *s = &spr[i]; int xpos = spr[i].xpos; int sprxp = (fmode & 0x8000) ? (xpos & ~sscanmask) : xpos; int hw_xp = sprxp >> sprite_buffer_res; - int pointx = usepointx && (sprctl[i] & sprite_sprctlmask) ? 0 : 1; + int pointx = usepointx && (s->ctl & sprite_sprctlmask) ? 0 : 1; if (xpos < 0) continue; @@ -4088,14 +4112,15 @@ static void decide_sprites(int spnr, int hpos, bool usepointx, bool quick) for (i = 0; i < count; i++) { int nr = nrs[i] & (MAX_SPRITES - 1); - record_sprite (next_lineno, nr, posns[i], sprdata[nr], sprdatb[nr], sprctl[nr]); + struct sprite *s = &spr[nr]; + record_sprite (next_lineno, nr, posns[i], s->data, s->datb, s->ctl); /* get left and right sprite edge if brdsprt enabled */ #if AUTOSCALE_SPRITES if (dmaen (DMA_SPRITE) && (bplcon0 & 1) && (bplcon3 & 0x02) && !(bplcon3 & 0x20) && nr > 0) { int j, jj; for (j = 0, jj = 0; j < sprite_width; j+= 16, jj++) { int nx = fromspritexdiw (posns[i] + j); - if (sprdata[nr][jj] || sprdatb[nr][jj]) { + if (s->data[jj] || s->datb[jj]) { if (diwfirstword_total > nx && nx >= (48 << currprefs.gfx_resolution)) diwfirstword_total = nx; if (diwlastword_total < nx + 16 && nx <= (448 << currprefs.gfx_resolution)) @@ -4128,9 +4153,10 @@ static void decide_sprites(int spnr, int hpos) } static void maybe_decide_sprites(int spnr, int hpos) { - if (!spr[spnr].armed) + struct sprite *s = &spr[spnr]; + if (!s->armed) return; - if (!sprdata[spnr] && !sprdatb[spnr]) + if (!s->data && !s->datb) return; decide_sprites(spnr, hpos, true, true); } @@ -4160,7 +4186,7 @@ static int sprites_differ (struct draw_info *dip, struct draw_info *dip_old) if (memcmp (spixels + this_first->first_pixel, spixels + prev_first->first_pixel, npixels * sizeof (uae_u16)) != 0) return 1; - if (memcmp (spixstate.bytes + this_first->first_pixel, spixstate.bytes + prev_first->first_pixel, npixels) != 0) + if (memcmp (spixstate.stb + this_first->first_pixel, spixstate.stb + prev_first->first_pixel, npixels) != 0) return 1; return 0; } @@ -4418,6 +4444,7 @@ static void reset_decisions (void) #endif #ifdef AGA thisline_decision.bplcon4 = bplcon4; + thisline_decision.fmode = fmode; #endif bplcon0d_old = -1; toscr_res_old = -1; @@ -6228,6 +6255,7 @@ static void FMODE (int hpos, uae_u16 v) fmode_saved = v; set_chipset_mode(); bpldmainitdelay (hpos); + record_register_change(hpos, 0x1fc, fmode); } static void FNULL (uae_u16 v) @@ -6440,45 +6468,45 @@ static void SPRxCTLPOS(int num) struct sprite *s = &spr[num]; sprstartstop (s); - sprxp = (sprpos[num] & 0xFF) * 2 + (sprctl[num] & 1); + sprxp = (s->pos & 0xFF) * 2 + (s->ctl & 1); sprxp <<= sprite_buffer_res; /* Quite a bit salad in this register... */ if (0) { } #ifdef AGA else if (currprefs.chipset_mask & CSMASK_AGA) { - sprxp |= ((sprctl[num] >> 3) & 3) >> (RES_MAX - sprite_buffer_res); - s->dblscan = sprpos[num] & 0x80; + sprxp |= ((s->ctl >> 3) & 3) >> (RES_MAX - sprite_buffer_res); + s->dblscan = s->pos & 0x80; } #endif #ifdef ECS_DENISE else if (currprefs.chipset_mask & CSMASK_ECS_DENISE) { - sprxp |= ((sprctl[num] >> 3) & 2) >> (RES_MAX - sprite_buffer_res); + sprxp |= ((s->ctl >> 3) & 2) >> (RES_MAX - sprite_buffer_res); } #endif s->xpos = sprxp; - s->vstart = sprpos[num] >> 8; - s->vstart |= (sprctl[num] & 0x04) ? 0x0100 : 0; - s->vstop = sprctl[num] >> 8; - s->vstop |= (sprctl[num] & 0x02) ? 0x100 : 0; + s->vstart = s->pos >> 8; + s->vstart |= (s->ctl & 0x04) ? 0x0100 : 0; + s->vstop = s->ctl >> 8; + s->vstop |= (s->ctl & 0x02) ? 0x100 : 0; if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) { - s->vstart |= (sprctl[num] & 0x40) ? 0x0200 : 0; - s->vstop |= (sprctl[num] & 0x20) ? 0x0200 : 0; + s->vstart |= (s->ctl & 0x40) ? 0x0200 : 0; + s->vstop |= (s->ctl & 0x20) ? 0x0200 : 0; } sprstartstop (s); } static void SPRxCTL_1(uae_u16 v, int num, int hpos) { - if (hpos >= maxhpos - 2 && sprctl[num] != v && vpos < maxvpos - 1) { - struct sprite *s = &spr[num]; + struct sprite *s = &spr[num]; + if (hpos >= maxhpos - 2 && s->ctl != v && vpos < maxvpos - 1) { vpos++; sprstartstop(s); vpos--; s->ignoreverticaluntilnextline = true; sprite_ignoreverticaluntilnextline = true; } - sprctl[num] = v; + s->ctl = v; spr_arm (num, 0); SPRxCTLPOS (num); @@ -6493,18 +6521,17 @@ static void SPRxCTL_1(uae_u16 v, int num, int hpos) } static void SPRxPOS_1(uae_u16 v, int num, int hpos) { - if (hpos >= maxhpos - 2 && sprpos[num] != v && vpos < maxvpos - 1) { - struct sprite *s = &spr[num]; + struct sprite *s = &spr[num]; + if (hpos >= maxhpos - 2 && s->pos != v && vpos < maxvpos - 1) { vpos++; sprstartstop(s); vpos--; s->ignoreverticaluntilnextline = true; sprite_ignoreverticaluntilnextline = true; } - sprpos[num] = v; + s->pos = v; SPRxCTLPOS (num); #if SPRITE_DEBUG > 0 - struct sprite *s = &spr[num]; if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY && (SPRITE_DEBUG & (1 << num))) { write_log (_T("%d:%d:SPR%dPOS %04X P=%06X VSTRT=%d VSTOP=%d HSTRT=%d D=%d A=%d CP=%x PC=%x\n"), vpos, hpos, num, v, s->pt, s->vstart, s->vstop, s->xpos, spr[num].dmastate, spr[num].armed, cop_state.ip, M68K_GETPC); @@ -6513,11 +6540,13 @@ static void SPRxPOS_1(uae_u16 v, int num, int hpos) } static void SPRxDATA_1(uae_u16 v, int num, int hpos) { - sprdata[num][0] = v; + struct sprite *s = &spr[num]; + s->data[0] = v; #ifdef AGA - sprdata[num][1] = v; - sprdata[num][2] = v; - sprdata[num][3] = v; + s->data[1] = v; + s->data[2] = v; + s->data[3] = v; + s->width = sprite_width; #endif spr_arm (num, 1); #if SPRITE_DEBUG >= 256 @@ -6529,11 +6558,13 @@ static void SPRxDATA_1(uae_u16 v, int num, int hpos) } static void SPRxDATB_1(uae_u16 v, int num, int hpos) { - sprdatb[num][0] = v; + struct sprite *s = &spr[num]; + s->datb[0] = v; #ifdef AGA - sprdatb[num][1] = v; - sprdatb[num][2] = v; - sprdatb[num][3] = v; + s->datb[1] = v; + s->datb[2] = v; + s->datb[3] = v; + s->width = sprite_width; #endif #if SPRITE_DEBUG >= 256 if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY && (SPRITE_DEBUG & (1 << num))) { @@ -7583,20 +7614,25 @@ static void do_sprites_1(int num, int cycle, int hpos) { case 64: if (cycle == 0) { - sprdata[num][1] = data321; - sprdata[num][2] = data322 >> 16; - sprdata[num][3] = data322; + s->data[1] = data321; + s->data[2] = data322 >> 16; + s->data[3] = data322; } else { - sprdatb[num][1] = data321; - sprdatb[num][2] = data322 >> 16; - sprdatb[num][3] = data322; + s->datb[1] = data321; + s->datb[2] = data322 >> 16; + s->datb[3] = data322; } break; case 32: - if (cycle == 0) - sprdata[num][1] = data321; - else - sprdatb[num][1] = data321; + if (cycle == 0) { + s->data[1] = data321; + s->data[2] = data; + s->data[3] = data321; + } else { + s->datb[1] = data321; + s->datb[2] = data; + s->datb[3] = data321; + } break; } #endif @@ -7652,8 +7688,11 @@ static void do_sprites (int hpos) static void init_sprites (void) { - memset (sprpos, 0, sizeof sprpos); - memset (sprctl, 0, sizeof sprctl); + for (int i = 0; i < MAX_SPRITES; i++) { + struct sprite *s = &spr[i]; + s->pos = 0; + s->ctl = 0; + } } static void init_hardware_frame (void) @@ -7715,7 +7754,11 @@ void init_hardware_for_drawing_frame (void) int first_pixel = prev_sprite_entries[0].first_pixel; int npixels = prev_sprite_entries[prev_next_sprite_entry].first_pixel - first_pixel; memset (spixels + first_pixel, 0, npixels * sizeof *spixels); - memset (spixstate.bytes + first_pixel, 0, npixels * sizeof *spixstate.bytes); + memset(spixstate.stb + first_pixel, 0, npixels * sizeof *spixstate.stb); + if (spr_width_64_seen) { + memset(spixstate.stbfm + first_pixel, 0, npixels * sizeof *spixstate.stbfm); + spr_width_64_seen = false; + } } prev_next_sprite_entry = next_sprite_entry; @@ -9824,6 +9867,9 @@ void custom_reset (bool hardreset, bool keyboardreset) CLXCON2 (0); setup_fmodes (0); sprite_width = GET_SPRITEWIDTH (fmode); + for (int i = 0; i < MAX_SPRITES; i++) { + spr[i].width = sprite_width; + } beamcon0 = new_beamcon0 = currprefs.ntscmode ? 0x00 : 0x20; bltstate = BLT_done; blit_interrupt = 1; @@ -10810,10 +10856,11 @@ uae_u8 *save_custom (int *len, uae_u8 *dstptr, int full) SL (spr[i].pt); /* 120-13E SPRxPT */ } for (i = 0; i < 8; i++) { - SW (sprpos[i]); /* 1x0 SPRxPOS */ - SW (sprctl[i]); /* 1x2 SPRxPOS */ - SW (sprdata[i][0]); /* 1x4 SPRxDATA */ - SW (sprdatb[i][0]); /* 1x6 SPRxDATB */ + struct sprite *s = &spr[i]; + SW (s->pos); /* 1x0 SPRxPOS */ + SW (s->ctl); /* 1x2 SPRxPOS */ + SW (s->data[0]); /* 1x4 SPRxDATA */ + SW (s->datb[0]); /* 1x6 SPRxDATB */ } } for (i = 0; i < 32; i++) { @@ -10912,42 +10959,44 @@ uae_u8 *save_custom_agacolors (int *len, uae_u8 *dstptr) uae_u8 *restore_custom_sprite (int num, uae_u8 *src) { - memset (&spr[num], 0, sizeof (struct sprite)); - spr[num].pt = RL; /* 120-13E SPRxPT */ - sprpos[num] = RW; /* 1x0 SPRxPOS */ - sprctl[num] = RW; /* 1x2 SPRxPOS */ - sprdata[num][0] = RW; /* 1x4 SPRxDATA */ - sprdatb[num][0] = RW; /* 1x6 SPRxDATB */ - sprdata[num][1] = RW; - sprdatb[num][1] = RW; - sprdata[num][2] = RW; - sprdatb[num][2] = RW; - sprdata[num][3] = RW; - sprdatb[num][3] = RW; - spr[num].armed = RB & 1; + struct sprite *s = &spr[num]; + memset (s, 0, sizeof (struct sprite)); + s->pt = RL; /* 120-13E SPRxPT */ + s->pos = RW; /* 1x0 SPRxPOS */ + s->ctl = RW; /* 1x2 SPRxPOS */ + s->data[0] = RW; /* 1x4 SPRxDATA */ + s->datb[0] = RW; /* 1x6 SPRxDATB */ + s->data[1] = RW; + s->datb[1] = RW; + s->data[2] = RW; + s->datb[2] = RW; + s->data[3] = RW; + s->datb[3] = RW; + s->armed = RB & 1; return src; } uae_u8 *save_custom_sprite (int num, int *len, uae_u8 *dstptr) { uae_u8 *dstbak, *dst; + struct sprite *s = &spr[num]; if (dstptr) dstbak = dst = dstptr; else dstbak = dst = xmalloc (uae_u8, 30); - SL (spr[num].pt); /* 120-13E SPRxPT */ - SW (sprpos[num]); /* 1x0 SPRxPOS */ - SW (sprctl[num]); /* 1x2 SPRxPOS */ - SW (sprdata[num][0]); /* 1x4 SPRxDATA */ - SW (sprdatb[num][0]); /* 1x6 SPRxDATB */ - SW (sprdata[num][1]); - SW (sprdatb[num][1]); - SW (sprdata[num][2]); - SW (sprdatb[num][2]); - SW (sprdata[num][3]); - SW (sprdatb[num][3]); - SB (spr[num].armed ? 1 : 0); + SL (s->pt); /* 120-13E SPRxPT */ + SW (s->pos); /* 1x0 SPRxPOS */ + SW (s->ctl); /* 1x2 SPRxPOS */ + SW (s->data[0]); /* 1x4 SPRxDATA */ + SW (s->datb[0]); /* 1x6 SPRxDATB */ + SW (s->data[1]); + SW (s->datb[1]); + SW (s->data[2]); + SW (s->datb[2]); + SW (s->data[3]); + SW (s->datb[3]); + SB (s->armed ? 1 : 0); *len = dst - dstbak; return dstbak; } diff --git a/drawing.cpp b/drawing.cpp index 6d346a2f..c5795456 100644 --- a/drawing.cpp +++ b/drawing.cpp @@ -149,8 +149,9 @@ static uae_u32 clxtab[256]; xcolnr xcolors[4096]; struct spritepixelsbuf { - uae_u8 attach; + bool attach; uae_u8 stdata; + uae_u16 stfmdata; uae_u16 data; }; static struct spritepixelsbuf spritepixels_buffer[MAX_PIXELS_PER_LINE]; @@ -194,8 +195,7 @@ uae_u16 *spixels; uae_u16 spixels[2 * MAX_SPR_PIXELS]; #endif -/* Eight bits for every pixel. */ -union sps_union spixstate; +struct sprite_stb spixstate; static uae_u32 ham_linebuf[MAX_PIXELS_PER_LINE * 2]; static uae_u8 *real_bplpt[8]; @@ -274,6 +274,7 @@ static bool ecs_genlock_features_active; static uae_u8 ecs_genlock_features_mask; static bool ecs_genlock_features_colorkey; static int hsync_shift_hack; +static bool sprite_smaller_than_64; uae_sem_t gui_sem; @@ -1283,6 +1284,13 @@ static uae_u8 render_sprites (int pos, int dualpf, uae_u8 apixel, int aga) int *shift_lookup = dualpf ? (bpldualpfpri ? dblpf_ms2 : dblpf_ms1) : dblpf_ms; int maskshift, plfmask; + // If 64 pixel wide sprite and FMODE gets lowered when sprite's + // first 32 pixels are being drawn: matching pixel(s) in second + // 32 pixel part gets blanked. + if (aga && spb->stfmdata && sprite_smaller_than_64) { + spb[32 << currprefs.gfx_resolution].data &= ~spb->stfmdata; + } + // shdelay hack, above &spritepixels[pos] is correct. pos += sprite_shdelay; /* The value in the shift lookup table is _half_ the shift count we @@ -2240,13 +2248,15 @@ that many of the if statements will go away completely after inlining. */ STATIC_INLINE void draw_sprites_1 (struct sprite_entry *e, int dualpf, int has_attach) { uae_u16 *buf = spixels + e->first_pixel; - uae_u8 *stbuf = spixstate.bytes + e->first_pixel; + uae_u8 *stbuf = spixstate.stb + e->first_pixel; + uae_u16 *stfmbuf = spixstate.stbfm + e->first_pixel; int spr_pos, pos; int epos = e->pos; int emax = e->max; buf -= epos; stbuf -= epos; + stfmbuf -= epos; spr_pos = epos + ((DIW_DDF_OFFSET - DISPLAY_LEFT_SHIFT) << sprite_buffer_res); @@ -2257,6 +2267,7 @@ STATIC_INLINE void draw_sprites_1 (struct sprite_entry *e, int dualpf, int has_a if (spr_pos >= 0 && spr_pos < MAX_PIXELS_PER_LINE) { spritepixels[spr_pos].data = buf[pos]; spritepixels[spr_pos].stdata = stbuf[pos]; + spritepixels[spr_pos].stfmdata = stfmbuf[pos]; spritepixels[spr_pos].attach = has_attach; } } @@ -2777,6 +2788,7 @@ static void pfield_expand_dp_bplcon (void) bpldelay_sh = sh; pfield_mode_changed = true; } + sprite_smaller_than_64 = (dp_for_drawing->fmode & 0x0c) != 0x0c; #endif 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) { @@ -2843,6 +2855,9 @@ static void pfield_expand_dp_bplconx (int regno, int v) case 0x10c: // BPLCON4 dp_for_drawing->bplcon4 = v; break; + case 0x1fc: // FMODE + dp_for_drawing->fmode = v; + break; #endif } pfield_expand_dp_bplcon (); @@ -3137,6 +3152,7 @@ static void pfield_draw_line (struct vidbuffer *vb, int lineno, int gfx_ypos, in uae_u16 b2 = dp_for_drawing->bplcon2; uae_u16 b3 = dp_for_drawing->bplcon3; uae_u16 b4 = dp_for_drawing->bplcon4; + uae_u16 fm = dp_for_drawing->fmode; init_ham_decoding (); do_color_changes (dummy_worker, decode_ham, lineno); if (have_color_changes) { @@ -3146,6 +3162,7 @@ static void pfield_draw_line (struct vidbuffer *vb, int lineno, int gfx_ypos, in dp_for_drawing->bplcon2 = b2; dp_for_drawing->bplcon3 = b3; dp_for_drawing->bplcon4 = b4; + dp_for_drawing->fmode = fm; pfield_expand_dp_bplcon (); } hposblank = ohposblank; diff --git a/include/drawing.h b/include/drawing.h index 1dce48aa..1f9961d2 100644 --- a/include/drawing.h +++ b/include/drawing.h @@ -232,11 +232,15 @@ struct sprite_entry bool has_attached; }; -union sps_union { - uae_u8 bytes[2 * MAX_SPR_PIXELS]; - uae_u32 words[2 * MAX_SPR_PIXELS / 4]; +struct sprite_stb +{ + /* Eight bits for every pixel for attachment + * Another eight for 64/32 status + */ + uae_u8 stb[2 * MAX_SPR_PIXELS]; + uae_u16 stbfm[2 * MAX_SPR_PIXELS]; }; -extern union sps_union spixstate; +extern struct sprite_stb spixstate; #ifdef OS_WITHOUT_MEMORY_MANAGEMENT extern uae_u16 *spixels; @@ -265,6 +269,7 @@ struct decision { uae_u16 bplcon0, bplcon2; #ifdef AGA uae_u16 bplcon3, bplcon4; + uae_u16 fmode; #endif uae_u8 nr_planes; uae_u8 bplres; -- 2.47.3