--- uae/src/drawing.c 2018/04/24 16:42:10 1.1.1.1 +++ uae/src/drawing.c 2018/04/24 16:47:27 1.1.1.5 @@ -88,16 +88,16 @@ typedef void (*line_draw_func)(int, int) #define LINE_DECIDED 2 #define LINE_DECIDED_DOUBLE 3 #define LINE_AS_PREVIOUS 4 -#define LINE_BORDER_NEXT 5 -#define LINE_BORDER_PREV 6 +#define LINE_BLACK 5 +#define LINE_REMEMBERED_AS_BLACK 6 #define LINE_DONE 7 #define LINE_DONE_AS_PREVIOUS 8 #define LINE_REMEMBERED_AS_PREVIOUS 9 static char *line_drawn; -static char linestate[(maxvpos + 1)*2 + 1]; +static char linestate[(MAXVPOS + 1)*2 + 1]; -uae_u8 line_data[(maxvpos+1) * 2][MAX_PLANES * MAX_WORDS_PER_LINE * 2]; +uae_u8 line_data[(MAXVPOS + 1) * 2][MAX_PLANES * MAX_WORDS_PER_LINE * 2]; static int min_diwstart, max_diwstop, prev_x_adjust, linetoscr_x_adjust, linetoscr_right_x; static int linetoscr_x_adjust_bytes; @@ -113,7 +113,7 @@ static int first_block_line, last_block_ /* These are generated by the drawing code from the line_decisions array for * each line that needs to be drawn. */ -static int bplehb, bplham, bpldualpf, bpldualpfpri, bplplanecnt, bplhires; +static int bplehb, bplham, bpldualpf, bpldualpfpri, bplplanecnt, bplres; static int bpldelay1, bpldelay2; static int plfpri[3]; @@ -130,7 +130,7 @@ static int picasso_redraw_necessary; static __inline__ void count_frame (void) { framecnt++; - if (framecnt >= currprefs.framerate) + if (framecnt >= currprefs.gfx_framerate) framecnt = 0; } @@ -256,35 +256,38 @@ static void decode_ham_aga (int pix, int } #endif +static int linetoscr_double_offset; + #if AGA_CHIPSET != 0 /* WARNING: Not too much of this will work correctly yet. */ -static void pfield_linetoscr_aga(int pix, int stoppos) +static void pfield_linetoscr_aga (int pix, int lframe_end, int diw_end, int stoppos) { uae_u32 *buf = aga_lbufptr; int i; - int xor = (uae_u8)(bplcon4 >> 8); - int oldpix = pix; \ + int xor = (uae_u8)(dp_for_drawing->bplcon4 >> 8); + int oldpix = pix; - buf -= pix; \ + buf -= pix; for (i = 0; i < stoppos; i++) pixdata.apixels[i] ^= xor; - while (pix < dp_for_drawing->diwfirstword && pix < stoppos) { + while (pix < lframe_end) { buf[pix++] = colors_for_drawing.color_regs[0]; } if (bplham) { - while (pix < dp_for_drawing->diwlastword && pix < stoppos) { + while (pix < diw_end) { uae_u32 d = ham_linebuf[pix]; buf[pix] = d; pix++; } } else if (bpldualpf) { +#if 0 /* FIXME */ /* Dual playfield */ int *lookup = bpldualpfpri ? dblpf_aga2 : dblpf_aga1; int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; - while (pix < dp_for_drawing->diwlastword && pix < stoppos) { + while (pix < diw_end) { int pixcol = pixdata.apixels[pix]; int pfno = lookup_no[pixcol]; @@ -293,13 +296,14 @@ static void pfield_linetoscr_aga(int pix } else { int val = lookup[pixdata.apixels[pix]]; if (pfno == 2) - val += dblpfofs[(bplcon2 >> 10) & 7]; + val += dblpfofs[(dp_for_drawing->bplcon2 >> 10) & 7]; buf[pix] = colors_for_drawing.color_regs[val]; } pix++; } +#endif } else if (bplehb) { - while (pix < dp_for_drawing->diwlastword && pix < stoppos) { + while (pix < diw_end) { int pixcol = pixdata.apixels[pix]; uae_u32 d = colors_for_drawing.color_regs[pixcol]; /* What about sprites? */ @@ -309,7 +313,7 @@ static void pfield_linetoscr_aga(int pix pix++; } } else { - while (pix < dp_for_drawing->diwlastword && pix < stoppos) { + while (pix < diw_end) { int pixcol = pixdata.apixels[pix]; buf[pix] = colors_for_drawing.color_regs[pixcol]; pix++; @@ -321,12 +325,13 @@ static void pfield_linetoscr_aga(int pix aga_lbufptr += pix - oldpix; } -static void aga_translate32(int start, int stop) +static void aga_translate32 (int start, int stop) { - memcpy (((uae_u32 *)xlinebuffer) + start, aga_linebuf + start, 4*(stop-start)); + memcpy (((uae_u32 *)xlinebuffer) + start, aga_lbufptr, 4*(stop-start)); + aga_lbufptr += stop - start; } -static void aga_translate16(int start, int stop) +static void aga_translate16 (int start, int stop) { int i; for (i = start; i < stop; i++) { @@ -336,7 +341,7 @@ static void aga_translate16(int start, i } } -static void aga_translate8(int start, int stop) +static void aga_translate8 (int start, int stop) { int i; for (i = start; i < stop; i++) { @@ -345,9 +350,21 @@ static void aga_translate8(int start, in ((uae_u8 *)xlinebuffer)[i] = xcolors[v]; } } -#endif -static int linetoscr_double_offset; +static void aga_fill_line_32 (char *buf, int start, int stop) +{ + int i; + for (i = start; i < stop; i++) { + ((uae_u32 *)buf)[i] = colors_for_drawing.color_regs[0]; + } +} + +static void fill_line (void) +{ + aga_fill_line_32 (xlinebuffer, linetoscr_x_adjust, linetoscr_x_adjust + gfxvidinfo.width); +} + +#else /* no AGA_CHIPSET */ #define LINE_TO_SCR(NAME, TYPE, DO_DOUBLE, CONVERT) \ static void NAME(int pix, int lframe_end, int diw_end, int stoppos) \ @@ -405,7 +422,7 @@ static void NAME(int pix, int lframe_end } #define FILL_LINE(NAME, TYPE, CONVERT) \ -static void NAME(char *buf, int start, int stop) \ +static void NAME (char *buf, int start, int stop) \ { \ TYPE *b = (TYPE *)buf; \ int i;\ @@ -445,10 +462,10 @@ static void fill_line_24 (char *buf, int static __inline__ void fill_line_full (void) { switch (gfxvidinfo.pixbytes) { - case 1: fill_line_8(xlinebuffer, linetoscr_x_adjust, linetoscr_x_adjust + gfxvidinfo.width); break; - case 2: fill_line_16(xlinebuffer, linetoscr_x_adjust, linetoscr_x_adjust + gfxvidinfo.width); break; - case 3: fill_line_24(xlinebuffer, linetoscr_x_adjust, linetoscr_x_adjust + gfxvidinfo.width); break; - case 4: fill_line_32(xlinebuffer, linetoscr_x_adjust, linetoscr_x_adjust + gfxvidinfo.width); break; + case 1: fill_line_8 (xlinebuffer, linetoscr_x_adjust, linetoscr_x_adjust + gfxvidinfo.width); break; + case 2: fill_line_16 (xlinebuffer, linetoscr_x_adjust, linetoscr_x_adjust + gfxvidinfo.width); break; + case 3: fill_line_24 (xlinebuffer, linetoscr_x_adjust, linetoscr_x_adjust + gfxvidinfo.width); break; + case 4: fill_line_32 (xlinebuffer, linetoscr_x_adjust, linetoscr_x_adjust + gfxvidinfo.width); break; } } @@ -524,16 +541,16 @@ static __inline__ void fill_line (void) #undef pfield_linetoscr_full8 /* The types are lies, of course. */ -extern void pfield_linetoscr_normal_asm8(void) __asm__("pfield_linetoscr_normal_asm8"); -extern void pfield_linetoscr_ehb_asm8(void) __asm__("pfield_linetoscr_ehb_asm8"); -extern void pfield_linetoscr_ham6_asm8(void) __asm__("pfield_linetoscr_ham6_asm8"); -extern void pfield_linetoscr_dualpf_asm8(void) __asm__("pfield_linetoscr_dualpf_asm8"); -extern void pfield_linetoscr_hdouble_asm8(void) __asm__("pfield_linetoscr_hdouble_asm8"); -extern void pfield_linetoscr_hdouble_dpf_asm8(void) __asm__("pfield_linetoscr_hdouble_dpf_asm8"); -extern void pfield_linetoscr_hdouble_ehb_asm8(void) __asm__("pfield_linetoscr_hdouble_ehb_asm8"); -extern void pfield_linetoscr_asm8(void (*)(void), int, int, int, int, ...) __asm__("pfield_linetoscr_asm8"); +extern void pfield_linetoscr_normal_asm8 (void) __asm__("pfield_linetoscr_normal_asm8"); +extern void pfield_linetoscr_ehb_asm8 (void) __asm__("pfield_linetoscr_ehb_asm8"); +extern void pfield_linetoscr_ham6_asm8 (void) __asm__("pfield_linetoscr_ham6_asm8"); +extern void pfield_linetoscr_dualpf_asm8 (void) __asm__("pfield_linetoscr_dualpf_asm8"); +extern void pfield_linetoscr_hdouble_asm8 (void) __asm__("pfield_linetoscr_hdouble_asm8"); +extern void pfield_linetoscr_hdouble_dpf_asm8 (void) __asm__("pfield_linetoscr_hdouble_dpf_asm8"); +extern void pfield_linetoscr_hdouble_ehb_asm8 (void) __asm__("pfield_linetoscr_hdouble_ehb_asm8"); +extern void pfield_linetoscr_asm8 (void (*) (void), int, int, int, int, ...) __asm__("pfield_linetoscr_asm8"); -static void pfield_linetoscr_full8(int pix, int lframe_end, int diw_end, int stoppos) +static void pfield_linetoscr_full8 (int pix, int lframe_end, int diw_end, int stoppos) { int lframe_end_1, diw_end_1; @@ -541,30 +558,30 @@ static void pfield_linetoscr_full8(int p diw_end_1 = stoppos - ((stoppos - diw_end) & ~3); if (bplham && bplplanecnt == 6) { - pfield_linetoscr_asm8(pfield_linetoscr_ham6_asm8, pix, lframe_end_1, diw_end_1, stoppos); + pfield_linetoscr_asm8 (pfield_linetoscr_ham6_asm8, pix, lframe_end_1, diw_end_1, stoppos); } else if (bpldualpf) { #ifdef LORES_HACK if (currprefs.gfx_lores == 2) - pfield_linetoscr_asm8(pfield_linetoscr_hdouble_dpf_asm8, pix, lframe_end_1, diw_end_1, stoppos, + pfield_linetoscr_asm8 (pfield_linetoscr_hdouble_dpf_asm8, pix, lframe_end_1, diw_end_1, stoppos, bpldualpfpri ? dblpf_ind2 : dblpf_ind1); else #endif - pfield_linetoscr_asm8(pfield_linetoscr_dualpf_asm8, pix, lframe_end_1, diw_end_1, stoppos, + pfield_linetoscr_asm8 (pfield_linetoscr_dualpf_asm8, pix, lframe_end_1, diw_end_1, stoppos, bpldualpfpri ? dblpf_ind2 : dblpf_ind1); } else if (bplehb) { #ifdef LORES_HACK if (currprefs.gfx_lores == 2) - pfield_linetoscr_asm8(pfield_linetoscr_hdouble_ehb_asm8, pix, lframe_end_1, diw_end_1, stoppos); + pfield_linetoscr_asm8 (pfield_linetoscr_hdouble_ehb_asm8, pix, lframe_end_1, diw_end_1, stoppos); else #endif - pfield_linetoscr_asm8(pfield_linetoscr_ehb_asm8, pix, lframe_end_1, diw_end_1, stoppos); + pfield_linetoscr_asm8 (pfield_linetoscr_ehb_asm8, pix, lframe_end_1, diw_end_1, stoppos); } else { #ifdef LORES_HACK if (currprefs.gfx_lores == 2) - pfield_linetoscr_asm8(pfield_linetoscr_hdouble_asm8, pix, lframe_end_1, diw_end_1, stoppos); + pfield_linetoscr_asm8 (pfield_linetoscr_hdouble_asm8, pix, lframe_end_1, diw_end_1, stoppos); else #endif - pfield_linetoscr_asm8(pfield_linetoscr_normal_asm8, pix, lframe_end_1, diw_end_1, stoppos); + pfield_linetoscr_asm8 (pfield_linetoscr_normal_asm8, pix, lframe_end_1, diw_end_1, stoppos); } /* The assembly functions work on aligned data, so we may have to do some @@ -582,16 +599,16 @@ static void pfield_linetoscr_full8(int p } #undef pfield_linetoscr_full16 -extern void pfield_linetoscr_normal_asm16(void) __asm__("pfield_linetoscr_normal_asm16"); -extern void pfield_linetoscr_ehb_asm16(void) __asm__("pfield_linetoscr_ehb_asm16"); -extern void pfield_linetoscr_ham6_asm16(void) __asm__("pfield_linetoscr_ham6_asm16"); -extern void pfield_linetoscr_dualpf_asm16(void) __asm__("pfield_linetoscr_dualpf_asm16"); -extern void pfield_linetoscr_hdouble_asm16(void) __asm__("pfield_linetoscr_hdouble_asm16"); -extern void pfield_linetoscr_hdouble_dpf_asm16(void) __asm__("pfield_linetoscr_hdouble_dpf_asm16"); -extern void pfield_linetoscr_hdouble_ehb_asm16(void) __asm__("pfield_linetoscr_hdouble_ehb_asm16"); -extern void pfield_linetoscr_asm16(void (*)(void), int, int, int, int, ...) __asm__("pfield_linetoscr_asm16"); +extern void pfield_linetoscr_normal_asm16 (void) __asm__("pfield_linetoscr_normal_asm16"); +extern void pfield_linetoscr_ehb_asm16 (void) __asm__("pfield_linetoscr_ehb_asm16"); +extern void pfield_linetoscr_ham6_asm16 (void) __asm__("pfield_linetoscr_ham6_asm16"); +extern void pfield_linetoscr_dualpf_asm16 (void) __asm__("pfield_linetoscr_dualpf_asm16"); +extern void pfield_linetoscr_hdouble_asm16 (void) __asm__("pfield_linetoscr_hdouble_asm16"); +extern void pfield_linetoscr_hdouble_dpf_asm16 (void) __asm__("pfield_linetoscr_hdouble_dpf_asm16"); +extern void pfield_linetoscr_hdouble_ehb_asm16 (void) __asm__("pfield_linetoscr_hdouble_ehb_asm16"); +extern void pfield_linetoscr_asm16 (void (*) (void), int, int, int, int, ...) __asm__("pfield_linetoscr_asm16"); -static void pfield_linetoscr_full16(int pix, int lframe_end, int diw_end, int stoppos) +static void pfield_linetoscr_full16 (int pix, int lframe_end, int diw_end, int stoppos) { int lframe_end_1, diw_end_1; @@ -599,30 +616,30 @@ static void pfield_linetoscr_full16(int diw_end_1 = stoppos - ((stoppos - diw_end) & ~3); if (bplham && bplplanecnt == 6) { - pfield_linetoscr_asm16(pfield_linetoscr_ham6_asm16, pix, lframe_end_1, diw_end_1, stoppos); + pfield_linetoscr_asm16 (pfield_linetoscr_ham6_asm16, pix, lframe_end_1, diw_end_1, stoppos); } else if (bpldualpf) { #ifdef LORES_HACK if (currprefs.gfx_lores == 2) - pfield_linetoscr_asm16(pfield_linetoscr_hdouble_dpf_asm16, pix, lframe_end_1, diw_end_1, stoppos, + pfield_linetoscr_asm16 (pfield_linetoscr_hdouble_dpf_asm16, pix, lframe_end_1, diw_end_1, stoppos, bpldualpfpri ? dblpf_ind2 : dblpf_ind1); else #endif - pfield_linetoscr_asm16(pfield_linetoscr_dualpf_asm16, pix, lframe_end_1, diw_end_1, stoppos, + pfield_linetoscr_asm16 (pfield_linetoscr_dualpf_asm16, pix, lframe_end_1, diw_end_1, stoppos, bpldualpfpri ? dblpf_ind2 : dblpf_ind1); } else if (bplehb) { #ifdef LORES_HACK if (currprefs.gfx_lores == 2) - pfield_linetoscr_asm16(pfield_linetoscr_hdouble_ehb_asm16, pix, lframe_end_1, diw_end_1, stoppos); + pfield_linetoscr_asm16 (pfield_linetoscr_hdouble_ehb_asm16, pix, lframe_end_1, diw_end_1, stoppos); else #endif - pfield_linetoscr_asm16(pfield_linetoscr_ehb_asm16, pix, lframe_end_1, diw_end_1, stoppos); + pfield_linetoscr_asm16 (pfield_linetoscr_ehb_asm16, pix, lframe_end_1, diw_end_1, stoppos); } else { #ifdef LORES_HACK if (currprefs.gfx_lores == 2) - pfield_linetoscr_asm16(pfield_linetoscr_hdouble_asm16, pix, lframe_end_1, diw_end_1, stoppos); + pfield_linetoscr_asm16 (pfield_linetoscr_hdouble_asm16, pix, lframe_end_1, diw_end_1, stoppos); else #endif - pfield_linetoscr_asm16(pfield_linetoscr_normal_asm16, pix, lframe_end_1, diw_end_1, stoppos); + pfield_linetoscr_asm16 (pfield_linetoscr_normal_asm16, pix, lframe_end_1, diw_end_1, stoppos); } /* The assembly functions work on aligned data, so we may have to do some @@ -649,22 +666,24 @@ static void pfield_linetoscr_full16(int #ifdef NO_DOUBLING_LINETOSCR #undef pfield_linetoscr_full8_double #undef pfield_linetoscr_full16_double -static void pfield_linetoscr_full8_double(int start, int lframe_end, int diw_end, int stop) +static void pfield_linetoscr_full8_double (int start, int lframe_end, int diw_end, int stop) { char *oldxlb = (char *)xlinebuffer; - pfield_linetoscr_full8(start, lframe_end, diw_end, stop); + pfield_linetoscr_full8 (start, lframe_end, diw_end, stop); xlinebuffer = oldxlb + linetoscr_double_offset; - pfield_linetoscr_full8(start, lframe_end, diw_end, stop); + pfield_linetoscr_full8 (start, lframe_end, diw_end, stop); } -static void pfield_linetoscr_full16_double(int start, int lframe_end, int diw_end, int stop) +static void pfield_linetoscr_full16_double (int start, int lframe_end, int diw_end, int stop) { char *oldxlb = (char *)xlinebuffer; - pfield_linetoscr_full16(start, lframe_end, diw_end, stop); + pfield_linetoscr_full16 (start, lframe_end, diw_end, stop); xlinebuffer = oldxlb + linetoscr_double_offset; - pfield_linetoscr_full16(start, lframe_end, diw_end, stop); + pfield_linetoscr_full16 (start, lframe_end, diw_end, stop); } #endif +#endif /* no AGA_CHIPSET */ + static int linetoscr_diw_end, linetoscr_diw_start; /* Initialize the variables necessary for drawing a line. @@ -674,7 +693,6 @@ static int linetoscr_diw_end, linetoscr_ * it must possibly be cleared here. */ static void pfield_init_linetoscr (void) { - int ddf_left, ddf_right; int mindelay = bpldelay1, maxdelay = bpldelay2; if (bpldelay1 > bpldelay2) maxdelay = bpldelay1, mindelay = bpldelay2; @@ -685,11 +703,15 @@ static void pfield_init_linetoscr (void) /* We should really look at DDF also when calculating max_diwstop/min_diwstrt, * so that centering works better, but I'm afraid that might cost too many * cycles. Plus it's dangerous, see the code below that handles the case - * with sprites. */ - if (dip_for_drawing->nr_sprites == 0) { - int hiresadjust = bplhires ? 4 : 8; - ddf_left = ((dp_for_drawing->plfstrt + hiresadjust)*2 + mindelay - DISPLAY_LEFT_SHIFT) << lores_shift; - ddf_right = ((dp_for_drawing->plfstrt + dp_for_drawing->plflinelen + hiresadjust)*2 + maxdelay - DISPLAY_LEFT_SHIFT) << lores_shift; + * with sprites. + * The fuzzy_memset_le32 code won't work for AGA, so skip this part here. + */ + if (dip_for_drawing->nr_sprites == 0 || (currprefs.chipset_mask & CSMASK_AGA)) { + int hiresadjust = RES_ADJUST (bplres); + int ddf_left = (((dp_for_drawing->plfstrt + hiresadjust)*2 + + mindelay - DISPLAY_LEFT_SHIFT) << lores_shift); + int ddf_right = (((dp_for_drawing->plfstrt + dp_for_drawing->plflinelen + hiresadjust)*2 + + maxdelay - DISPLAY_LEFT_SHIFT) << lores_shift); if (linetoscr_diw_start < ddf_left) linetoscr_diw_start = ddf_left; @@ -713,12 +735,16 @@ static void pfield_init_linetoscr (void) } } } else { - int hiresadjust = bplhires ? 4 : 8; + /* Conservative case. */ + int hiresadjust = RES_ADJUST (bplres); /* We swap mindelay and maxdelay here to get rid of the mindelay != maxdelay check. * Since we have to do a memset anyway (because there may be sprites), * we might as well clear all at once. */ - ddf_left = ((dp_for_drawing->plfstrt + hiresadjust)*2 + maxdelay - DISPLAY_LEFT_SHIFT) << lores_shift; - ddf_right = ((dp_for_drawing->plfstrt + dp_for_drawing->plflinelen + hiresadjust)*2 + mindelay - DISPLAY_LEFT_SHIFT) << lores_shift; + int ddf_left = ((dp_for_drawing->plfstrt + hiresadjust)*2 + + maxdelay - DISPLAY_LEFT_SHIFT) << lores_shift; + int ddf_right = ((dp_for_drawing->plfstrt + dp_for_drawing->plflinelen + hiresadjust)*2 + + mindelay - DISPLAY_LEFT_SHIFT) << lores_shift; + if (linetoscr_diw_start < ddf_left) { int strt = linetoscr_diw_start; int stop = ddf_left; @@ -780,11 +806,11 @@ static void pfield_do_linetoscr(int star } } #else - pfield_linetoscr_aga(start, lframe_end, diw_end, stop); + pfield_linetoscr_aga (start, lframe_end, diw_end, stop); #endif } -static void pfield_do_fill_line(int start, int stop) +static void pfield_do_fill_line (int start, int stop) { if (stop > linetoscr_right_x) stop = linetoscr_right_x; @@ -794,15 +820,20 @@ static void pfield_do_fill_line(int star if (start >= stop) return; +#if AGA_CHIPSET == 0 switch (gfxvidinfo.pixbytes) { case 1: fill_line_8 (xlinebuffer, start, stop); break; case 2: fill_line_16 (xlinebuffer, start, stop); break; case 3: fill_line_24 (xlinebuffer, start, stop); break; case 4: fill_line_32 (xlinebuffer, start, stop); break; } +#else + aga_fill_line_32 (xlinebuffer, start, stop); + /* FIXME */ +#endif } -static void pfield_do_linetoscr_full(int double_line) +static void pfield_do_linetoscr_full (int double_line) { int start = linetoscr_x_adjust, stop = start + gfxvidinfo.width; int lframe_end = linetoscr_diw_start, diw_end = linetoscr_diw_end; @@ -827,11 +858,11 @@ static void pfield_do_linetoscr_full(int case 4: pfield_linetoscr_full32 (start, lframe_end, diw_end, stop); break; } #else - pfield_linetoscr_aga(start, lframe_end, diw_end, stop); + pfield_linetoscr_aga (start, lframe_end, diw_end, stop); #endif } -static void gen_pfield_tables(void) +static void gen_pfield_tables (void) { int i; union { @@ -1140,7 +1171,7 @@ static void pfield_doline_unaligned_h (i { int xpos = dp_for_drawing->plfstrt * 4 - DISPLAY_LEFT_SHIFT * 2; - if (bplhires) { + if (bplres == RES_HIRES) { int xpos1 = xpos + 16 + bpldelay1*2; int xpos2; uae_u8 *dataptr = line_data[lineno]; @@ -1219,7 +1250,7 @@ static void pfield_doline_unaligned_l (i { int xpos = dp_for_drawing->plfstrt * 2 - DISPLAY_LEFT_SHIFT; - if (bplhires) { + if (bplres == RES_HIRES) { int xpos1 = xpos + 8 + bpldelay1; int xpos2; uae_u8 *dataptr = line_data[lineno]; @@ -1412,7 +1443,7 @@ static void pfield_doline_aligned_h (int { int xpos = dp_for_drawing->plfstrt * 4 - DISPLAY_LEFT_SHIFT * 2; - if (bplhires) { + if (bplres == RES_HIRES) { if (bplplanecnt > 0) { int xpos1 = xpos + 16 + (bpldelay1 >= 8 ? 16 : 0); int xpos2 = xpos + 16 + (bpldelay2 >= 8 ? 16 : 0); @@ -1455,7 +1486,7 @@ static void pfield_doline_aligned_h (int } #endif } else { - memset(pixdata.apixels, 0, sizeof(pixdata.apixels)); + memset (pixdata.apixels, 0, sizeof(pixdata.apixels)); } } else { if (bplplanecnt > 0) { @@ -1497,7 +1528,7 @@ static void pfield_doline_aligned_h (int } #endif } else { - memset(pixdata.apixels, 0, sizeof(pixdata.apixels)); + memset (pixdata.apixels, 0, sizeof(pixdata.apixels)); } } } @@ -1506,7 +1537,7 @@ static void pfield_doline_aligned_l (int { int xpos = dp_for_drawing->plfstrt * 2 - DISPLAY_LEFT_SHIFT; - if (bplhires) { + if (bplres == RES_HIRES) { if (bplplanecnt > 0) { int xpos1 = xpos + 8 + (bpldelay1 >= 8 ? 8 : 0); int xpos2 = xpos + 8 + (bpldelay2 >= 8 ? 8 : 0); @@ -1616,8 +1647,8 @@ static void pfield_adjust_delay (void) int startpos = i == dip_for_drawing->last_delay_change - 1 ? ddf_right + 8 : delay_changes[i+1].linepos; int stoppos = i < dip_for_drawing->first_delay_change ? ddf_left : delay_changes[i].linepos; int j; - startpos = PIXEL_XPOS (startpos + (bplhires ? 4 : 8)); - stoppos = PIXEL_XPOS (stoppos + (bplhires ? 4 : 8)); + startpos = PIXEL_XPOS (startpos + RES_ADJUST (bplres)); + stoppos = PIXEL_XPOS (stoppos + RES_ADJUST (bplres)); if (currprefs.gfx_lores == 0) delay1 <<= 1, delay2 <<= 1; else if (currprefs.gfx_lores == 2) @@ -1650,7 +1681,7 @@ static void init_aspect_maps (void) free (amiga2aspect_line_map); /* At least for this array the +1 is necessary. */ - amiga2aspect_line_map = (int *)malloc (sizeof (int) * (maxvpos+1)*2 + 1); + amiga2aspect_line_map = (int *)malloc (sizeof (int) * (MAXVPOS + 1)*2 + 1); native2amiga_line_map = (int *)malloc (sizeof (int) * gfxvidinfo.height); if (currprefs.gfx_correct_aspect) @@ -1661,7 +1692,7 @@ static void init_aspect_maps (void) else native_lines_per_amiga_line = 1; - maxl = (maxvpos+1) * (currprefs.gfx_linedbl ? 2 : 1); + maxl = (MAXVPOS + 1) * (currprefs.gfx_linedbl ? 2 : 1); min_ypos_for_screen = minfirstline << (currprefs.gfx_linedbl ? 1 : 0); max_drawn_amiga_line = -1; for (i = 0; i < maxl; i++) { @@ -1676,6 +1707,7 @@ static void init_aspect_maps (void) max_drawn_amiga_line >>= 1; if (currprefs.gfx_ycenter && !(currprefs.gfx_correct_aspect)) { + /* @@@ verify maxvpos vs. MAXVPOS */ extra_y_adjust = (gfxvidinfo.height - (maxvpos << (currprefs.gfx_linedbl ? 1 : 0))) >> 1; if (extra_y_adjust < 0) extra_y_adjust = 0; @@ -1768,11 +1800,20 @@ static __inline__ void do_flush_screen ( flush_screen (start, stop); } +static __inline__ void finish_line_aga (void) +{ +#if AGA_CHIPSET != 0 + aga_lbufptr = aga_linebuf; + aga_translate32 (linetoscr_x_adjust_bytes, linetoscr_x_adjust_bytes + gfxvidinfo.width); +#endif +} + static int drawing_color_matches; static enum { color_match_acolors, color_match_full } color_match_type; static void adjust_drawing_colors (int ctable, int bplham) { +#if AGA_CHIPSET == 0 if (drawing_color_matches != ctable) { if (bplham) { memcpy (&colors_for_drawing, curr_color_tables + ctable, @@ -1789,6 +1830,13 @@ static void adjust_drawing_colors (int c sizeof colors_for_drawing.color_regs); color_match_type = color_match_full; } +#else + if (drawing_color_matches != ctable) { + memcpy (&colors_for_drawing, curr_color_tables + ctable, + sizeof colors_for_drawing); + drawing_color_matches = ctable; + } +#endif } static __inline__ void adjust_color0_for_color_change (void) @@ -1796,7 +1844,9 @@ static __inline__ void adjust_color0_for drawing_color_matches = -1; if (dp_for_drawing->color0 != 0xFFFFFFFFul) { colors_for_drawing.color_regs[0] = dp_for_drawing->color0; +#if AGA_CHIPSET == 0 colors_for_drawing.acolors[0] = xcolors[dp_for_drawing->color0]; +#endif } } @@ -1818,7 +1868,9 @@ static __inline__ void do_color_changes worker (lastpos, nextpos); if (i != dip_for_drawing->last_color_change) { colors_for_drawing.color_regs[cc->regno] = cc->value; +#if AGA_CHIPSET == 0 colors_for_drawing.acolors[cc->regno] = xcolors[cc->value]; +#endif } if (nextpos > lastpos) { lastpos = nextpos; @@ -1833,8 +1885,12 @@ static __inline__ void do_color_changes * form. */ static void pfield_expand_dp_bplcon (void) { - bplhires = (dp_for_drawing->bplcon0 & 0x8000) == 0x8000; - bplplanecnt = (dp_for_drawing->bplcon0 & 0x7000) >> 12; + bplres = RES_LORES; + if (dp_for_drawing->bplcon0 & 0x8000) + bplres = RES_HIRES; + if (dp_for_drawing->bplcon0 & 0x40) + bplres = RES_SUPERHIRES; + bplplanecnt = GET_PLANES (dp_for_drawing->bplcon0); bplham = (dp_for_drawing->bplcon0 & 0x800) == 0x800; #if AGA_CHIPSET == 1 /* The KILLEHB bit exists in ECS, but is apparently meant for Genlock * stuff, and it's set by some demos (e.g. Andromeda Seven Seas) */ @@ -1862,10 +1918,9 @@ static __inline__ void pfield_draw_line int do_double = 0; enum double_how dh; - dp_for_drawing = 0; - dip_for_drawing = 0; + dp_for_drawing = line_decisions + lineno; + dip_for_drawing = curr_drawinfo + lineno; switch (linestate[lineno]) { - case LINE_AS_PREVIOUS: case LINE_REMEMBERED_AS_PREVIOUS: { static int warned = 0; @@ -1875,16 +1930,22 @@ static __inline__ void pfield_draw_line line_decisions[lineno].which = -2; return; - case LINE_BORDER_PREV: - border = 1; - dp_for_drawing = line_decisions + lineno - 1; - dip_for_drawing = curr_drawinfo + lineno - 1; + case LINE_BLACK: + line_decisions[lineno].which = -2; + linestate[lineno] = LINE_REMEMBERED_AS_BLACK; + border = 2; break; - case LINE_BORDER_NEXT: - border = 1; - dp_for_drawing = line_decisions + lineno + 1; - dip_for_drawing = curr_drawinfo + lineno + 1; + case LINE_REMEMBERED_AS_BLACK: + return; + + case LINE_AS_PREVIOUS: + dp_for_drawing--; + dip_for_drawing--; + if (dp_for_drawing->which != 1) + border = 1; + line_decisions[lineno].which = -2; + linestate[lineno] = LINE_DONE_AS_PREVIOUS; break; case LINE_DONE_AS_PREVIOUS: @@ -1898,49 +1959,31 @@ static __inline__ void pfield_draw_line if (follow_ypos != -1) { do_double = 1; linetoscr_double_offset = gfxvidinfo.rowbytes * (follow_ypos - gfx_ypos); + linestate[lineno + 1] = LINE_DONE_AS_PREVIOUS; } /* fall through */ default: - dip_for_drawing = curr_drawinfo + lineno; - dp_for_drawing = line_decisions + lineno; if (dp_for_drawing->which != 1) border = 1; - break; - } - - if (!line_changed[lineno] && !frame_redraw_necessary) { - /* The case where we can skip redrawing this line. If this line - * is supposed to be doubled, and the next line is remembered as - * having been doubled, then the next line is done as well. */ - if (do_double) { - /* @@@ This is buggy. FIXME */ - if (linestate[lineno+1] != LINE_REMEMBERED_AS_PREVIOUS) { - if (gfxvidinfo.linemem == 0) - memcpy (row_map[follow_ypos], row_map[gfx_ypos], gfxvidinfo.rowbytes); - line_decisions[lineno + 1].which = -2; - do_flush_line (follow_ypos); - } - linestate[lineno + 1] = LINE_DONE_AS_PREVIOUS; - } linestate[lineno] = LINE_DONE; - return; + break; } dh = dh_line; xlinebuffer = gfxvidinfo.linemem; - if (xlinebuffer == 0 && do_double && dip_for_drawing->nr_color_changes != 0) + if (xlinebuffer == 0 && do_double && border != 2 && dip_for_drawing->nr_color_changes != 0) xlinebuffer = gfxvidinfo.emergmem, dh = dh_emerg; if (xlinebuffer == 0) xlinebuffer = row_map[gfx_ypos], dh = dh_buf; xlinebuffer -= linetoscr_x_adjust_bytes; aga_lbufptr = aga_linebuf; - if (!border) { + if (border == 0) { pfield_expand_dp_bplcon (); #ifdef LORES_HACK - if (gfxvidinfo.can_double && !bplhires && !currprefs.gfx_lores + if (gfxvidinfo.can_double && bplres == RES_LORES && !currprefs.gfx_lores && dip_for_drawing->nr_color_changes == 0 && !bplham) currprefs.gfx_lores = 2; #endif @@ -1983,8 +2026,8 @@ static __inline__ void pfield_draw_line if (dip_for_drawing->nr_color_changes == 0) { pfield_do_linetoscr_full (dh == dh_buf ? do_double : 0); + finish_line_aga (); do_flush_line (gfx_ypos); - linestate[lineno] = LINE_DONE; #if 0 if (dh == dh_emerg) abort (); @@ -1993,24 +2036,22 @@ static __inline__ void pfield_draw_line /* If dh == dh_line, do_flush_line will re-use the rendered line * from linemem. If dh == dh_buf, the line will have been doubled * by pfield_do_linetoscr_full. */ - linestate[lineno + 1] = LINE_DONE_AS_PREVIOUS; do_flush_line (follow_ypos); } } else { adjust_color0_for_color_change (); do_color_changes (pfield_do_linetoscr); + finish_line_aga (); if (dh == dh_emerg) memcpy (row_map[gfx_ypos], xlinebuffer + linetoscr_x_adjust_bytes, gfxvidinfo.rowbytes); - linestate[lineno] = LINE_DONE; do_flush_line (gfx_ypos); if (do_double) { if (dh == dh_emerg) memcpy (row_map[follow_ypos], xlinebuffer + linetoscr_x_adjust_bytes, gfxvidinfo.rowbytes); else if (dh == dh_buf) memcpy (row_map[follow_ypos], row_map[gfx_ypos], gfxvidinfo.rowbytes); - linestate[lineno + 1] = LINE_DONE_AS_PREVIOUS; line_decisions[lineno + 1].which = -2; do_flush_line (follow_ypos); } @@ -2019,7 +2060,7 @@ static __inline__ void pfield_draw_line if (currprefs.gfx_lores == 2) currprefs.gfx_lores = 0; #endif - } else { /* Border. */ + } else if (border == 1) { adjust_drawing_colors (dp_for_drawing->ctable, 0); /* Check color0 adjust only if we have color changes - shouldn't happen @@ -2028,7 +2069,6 @@ static __inline__ void pfield_draw_line if (dip_for_drawing->nr_color_changes == 0) { fill_line (); do_flush_line (gfx_ypos); - linestate[lineno] = LINE_DONE; #if 0 if (dh == dh_emerg) abort (); @@ -2041,7 +2081,6 @@ static __inline__ void pfield_draw_line /* If dh == dh_line, do_flush_line will re-use the rendered line * from linemem. */ do_flush_line (follow_ypos); - linestate[lineno+1] = LINE_DONE_AS_PREVIOUS; } return; } @@ -2053,7 +2092,6 @@ static __inline__ void pfield_draw_line memcpy (row_map[gfx_ypos], xlinebuffer + linetoscr_x_adjust_bytes, gfxvidinfo.rowbytes); do_flush_line (gfx_ypos); - linestate[lineno] = LINE_DONE; if (do_double) { if (dh == dh_emerg) memcpy (row_map[follow_ypos], xlinebuffer + linetoscr_x_adjust_bytes, gfxvidinfo.rowbytes); @@ -2062,9 +2100,16 @@ static __inline__ void pfield_draw_line /* If dh == dh_line, do_flush_line will re-use the rendered line * from linemem. */ do_flush_line (follow_ypos); - linestate[lineno + 1] = LINE_DONE_AS_PREVIOUS; line_decisions[lineno + 1].which = -2; } + } else { +#if AGA_CHIPSET == 0 + xcolnr tmp = colors_for_drawing.acolors[0]; + colors_for_drawing.acolors[0] = xcolors[0]; + fill_line (); + do_flush_line (gfx_ypos); + colors_for_drawing.acolors[0] = tmp; +#endif } } @@ -2233,8 +2278,18 @@ static void init_drawing_frame (void) maxline = currprefs.gfx_linedbl ? (maxvpos+1) * 2 + 1 : (maxvpos+1) + 1; #ifdef SMART_UPDATE - for (i = 0; i < maxline; i++) - linestate[i] = linestate[i] == LINE_DONE_AS_PREVIOUS ? LINE_REMEMBERED_AS_PREVIOUS : LINE_UNDECIDED; + for (i = 0; i < maxline; i++) { + switch (linestate[i]) { + case LINE_DONE_AS_PREVIOUS: + linestate[i] = LINE_REMEMBERED_AS_PREVIOUS; + break; + case LINE_REMEMBERED_AS_BLACK: + break; + default: + linestate[i] = LINE_UNDECIDED; + break; + } + } #else memset (linestate, LINE_UNDECIDED, maxline); #endif @@ -2338,9 +2393,9 @@ static __inline__ void check_picasso (vo picasso_on = picasso_requested_on; if (!picasso_on) - clear_inhibit_frame (2); + clear_inhibit_frame (IHF_PICASSO); else - set_inhibit_frame (2); + set_inhibit_frame (IHF_PICASSO); gfx_set_picasso_state (picasso_on); picasso_enablescreen (picasso_requested_on); @@ -2368,7 +2423,7 @@ void vsync_handle_redraw (int long_frame if (quit_program < 0) { quit_program = -quit_program; - set_inhibit_frame (1); + set_inhibit_frame (IHF_QUIT_PROGRAM); regs.spcflags |= SPCFLAG_BRK; filesys_prepare_reset (); #ifdef SUPPORT_PENGUINS @@ -2382,6 +2437,7 @@ void vsync_handle_redraw (int long_frame count_frame (); check_picasso (); + check_prefs_changed_audio (); check_prefs_changed_custom (); check_prefs_changed_cpu (); if (check_prefs_changed_gfx ()) { @@ -2399,30 +2455,40 @@ void vsync_handle_redraw (int long_frame } } -void hsync_record_line_state (int lineno, enum nln_how how) +void hsync_record_line_state (int lineno, enum nln_how how, int changed) { + char *state; if (framecnt != 0) return; + + state = linestate + lineno; + changed += frame_redraw_necessary; + switch (how) { case nln_normal: - linestate[lineno] = LINE_DECIDED; + *state = changed ? LINE_DECIDED : LINE_DONE; break; case nln_doubled: - linestate[lineno] = LINE_DECIDED_DOUBLE; - if (linestate[lineno+1] != LINE_REMEMBERED_AS_PREVIOUS) - linestate[lineno+1] = LINE_AS_PREVIOUS; + *state = changed ? LINE_DECIDED_DOUBLE : LINE_DONE; + changed += state[1] != LINE_REMEMBERED_AS_PREVIOUS; + state[1] = changed ? LINE_AS_PREVIOUS : LINE_DONE_AS_PREVIOUS; + break; + case nln_nblack: + *state = changed ? LINE_DECIDED : LINE_DONE; + if (state[1] != LINE_REMEMBERED_AS_BLACK) + state[1] = LINE_BLACK; break; case nln_lower: - if (linestate[lineno-1] == LINE_UNDECIDED) - linestate[lineno-1] = LINE_BORDER_NEXT; - linestate[lineno] = LINE_DECIDED; + if (state[-1] == LINE_UNDECIDED) + state[-1] = LINE_BLACK; + *state = changed ? LINE_DECIDED : LINE_DONE; break; case nln_upper: - linestate[lineno] = LINE_DECIDED; - if (linestate[lineno+1] == LINE_UNDECIDED - || linestate[lineno+1] == LINE_REMEMBERED_AS_PREVIOUS - || linestate[lineno+1] == LINE_AS_PREVIOUS) - linestate[lineno+1] = LINE_BORDER_PREV; + *state = changed ? LINE_DECIDED : LINE_DONE; + if (state[1] == LINE_UNDECIDED + || state[1] == LINE_REMEMBERED_AS_PREVIOUS + || state[1] == LINE_AS_PREVIOUS) + state[1] = LINE_BLACK; break; } }