|
|
1.1 ! root 1: /* ! 2: * UAE - The Un*x Amiga Emulator ! 3: * ! 4: * Screen drawing functions ! 5: * ! 6: * Copyright 1995-1998 Bernd Schmidt ! 7: * Copyright 1995 Alessandro Bissacco ! 8: */ ! 9: ! 10: #include "sysconfig.h" ! 11: #include "sysdeps.h" ! 12: ! 13: #include <ctype.h> ! 14: #include <assert.h> ! 15: ! 16: #include "config.h" ! 17: #include "options.h" ! 18: #include "threaddep/penguin.h" ! 19: #include "uae.h" ! 20: #include "memory.h" ! 21: #include "custom.h" ! 22: #include "readcpu.h" ! 23: #include "newcpu.h" ! 24: #include "xwin.h" ! 25: #include "autoconf.h" ! 26: #include "gui.h" ! 27: #include "picasso96.h" ! 28: #include "drawing.h" ! 29: #include "p2c.h" ! 30: ! 31: #if defined X86_ASSEMBLY ! 32: #define LORES_HACK ! 33: #endif ! 34: ! 35: int lores_factor, lores_shift, sprite_width; ! 36: ! 37: static int interlace_seen = 0; ! 38: ! 39: static int dblpf_ind1[256], dblpf_ind2[256], dblpf_2nd1[256], dblpf_2nd2[256]; ! 40: static int dblpf_aga1[256], dblpf_aga2[256], linear_map_256[256], lots_of_twos[256]; ! 41: ! 42: static int dblpfofs[] = { 0, 2, 4, 8, 16, 32, 64, 128 }; ! 43: ! 44: /* Big lookup tables for planar to chunky conversion. */ ! 45: ! 46: uae_u32 hirestab_h[256][2]; ! 47: uae_u32 lorestab_h[256][4]; ! 48: ! 49: uae_u32 hirestab_l[256][1]; ! 50: uae_u32 lorestab_l[256][2]; ! 51: ! 52: static uae_u32 clxtab[256]; ! 53: ! 54: /* Video buffer description structure. Filled in by the graphics system ! 55: * dependent code. */ ! 56: ! 57: struct vidbuf_description gfxvidinfo; ! 58: ! 59: /* The color lookup table. */ ! 60: ! 61: xcolnr xcolors[4096]; ! 62: ! 63: struct color_entry colors_for_drawing; ! 64: ! 65: /* 880 isn't a magic number, it's a safe number with some padding at the end. ! 66: * This used to be 1000, but that's excessive. (840 is too low). I'm too lazy ! 67: * to figure out the exact space needed. */ ! 68: union { ! 69: /* Let's try to align this thing. */ ! 70: double uupzuq; ! 71: long int cruxmedo; ! 72: unsigned char apixels[880]; ! 73: } pixdata; ! 74: ! 75: uae_u32 ham_linebuf[880]; ! 76: uae_u32 aga_linebuf[880], *aga_lbufptr; ! 77: ! 78: char *xlinebuffer; ! 79: ! 80: static int *amiga2aspect_line_map, *native2amiga_line_map; ! 81: static char *row_map[2049]; ! 82: static int max_drawn_amiga_line; ! 83: ! 84: /* line_draw_funcs: pfield_do_linetoscr, pfield_do_fill_line, decode_ham6 */ ! 85: typedef void (*line_draw_func)(int, int); ! 86: ! 87: #define LINE_UNDECIDED 1 ! 88: #define LINE_DECIDED 2 ! 89: #define LINE_DECIDED_DOUBLE 3 ! 90: #define LINE_AS_PREVIOUS 4 ! 91: #define LINE_BORDER_NEXT 5 ! 92: #define LINE_BORDER_PREV 6 ! 93: #define LINE_DONE 7 ! 94: #define LINE_DONE_AS_PREVIOUS 8 ! 95: #define LINE_REMEMBERED_AS_PREVIOUS 9 ! 96: ! 97: static char *line_drawn; ! 98: static char linestate[(maxvpos + 1)*2 + 1]; ! 99: ! 100: uae_u8 line_data[(maxvpos+1) * 2][MAX_PLANES * MAX_WORDS_PER_LINE * 2]; ! 101: ! 102: static int min_diwstart, max_diwstop, prev_x_adjust, linetoscr_x_adjust, linetoscr_right_x; ! 103: static int linetoscr_x_adjust_bytes; ! 104: static int thisframe_y_adjust, prev_y_adjust; ! 105: static int thisframe_y_adjust_real, max_ypos_thisframe, min_ypos_for_screen; ! 106: static int extra_y_adjust; ! 107: int thisframe_first_drawn_line, thisframe_last_drawn_line; ! 108: ! 109: static int last_redraw_point; ! 110: ! 111: static int first_drawn_line, last_drawn_line; ! 112: static int first_block_line, last_block_line; ! 113: ! 114: /* These are generated by the drawing code from the line_decisions array for ! 115: * each line that needs to be drawn. */ ! 116: static int bplehb, bplham, bpldualpf, bpldualpfpri, bplplanecnt, bplhires; ! 117: static int bpldelay1, bpldelay2; ! 118: static int plfpri[3]; ! 119: ! 120: int picasso_requested_on; ! 121: int picasso_on; ! 122: ! 123: uae_sem_t gui_sem; ! 124: int inhibit_frame; ! 125: ! 126: int framecnt = 0; ! 127: static int frame_redraw_necessary; ! 128: static int picasso_redraw_necessary; ! 129: ! 130: static __inline__ void count_frame (void) ! 131: { ! 132: framecnt++; ! 133: if (framecnt >= currprefs.framerate) ! 134: framecnt = 0; ! 135: } ! 136: ! 137: int coord_native_to_amiga_x (int x) ! 138: { ! 139: x += linetoscr_x_adjust; ! 140: x <<= (1 - lores_shift); ! 141: return x + 2*DISPLAY_LEFT_SHIFT; ! 142: } ! 143: ! 144: int coord_native_to_amiga_y (int y) ! 145: { ! 146: return native2amiga_line_map[y] + thisframe_y_adjust - minfirstline; ! 147: } ! 148: ! 149: void notice_screen_contents_lost (void) ! 150: { ! 151: picasso_redraw_necessary = 1; ! 152: frame_redraw_necessary = 2; ! 153: } ! 154: ! 155: static struct decision *dp_for_drawing; ! 156: static struct draw_info *dip_for_drawing; ! 157: ! 158: void record_diw_line (int first, int last) ! 159: { ! 160: if (last > max_diwstop) ! 161: max_diwstop = last; ! 162: if (first < min_diwstart) ! 163: min_diwstart = first; ! 164: } ! 165: ! 166: /* ! 167: * Screen update macros/functions ! 168: */ ! 169: ! 170: static unsigned int ham_lastcolor; ! 171: ! 172: static void init_ham_decoding(int first) ! 173: { ! 174: int pix = dp_for_drawing->diwfirstword; ! 175: ham_lastcolor = colors_for_drawing.color_regs[0]; ! 176: while (pix < first) { ! 177: int pv = pixdata.apixels[pix]; ! 178: switch(pv & 0x30) { ! 179: case 0x00: ham_lastcolor = colors_for_drawing.color_regs[pv]; break; ! 180: case 0x10: ham_lastcolor &= 0xFF0; ham_lastcolor |= (pv & 0xF); break; ! 181: case 0x20: ham_lastcolor &= 0x0FF; ham_lastcolor |= (pv & 0xF) << 8; break; ! 182: case 0x30: ham_lastcolor &= 0xF0F; ham_lastcolor |= (pv & 0xF) << 4; break; ! 183: } ! 184: pix++; ! 185: } ! 186: } ! 187: ! 188: static void decode_ham6 (int pix, int stoppos) ! 189: { ! 190: uae_u32 *buf = ham_linebuf; ! 191: ! 192: if (!bplham || bplplanecnt != 6) ! 193: return; ! 194: ! 195: if (stoppos > dp_for_drawing->diwlastword) ! 196: stoppos = dp_for_drawing->diwlastword; ! 197: if (pix < dp_for_drawing->diwfirstword) { ! 198: ham_lastcolor = colors_for_drawing.color_regs[0]; ! 199: pix = dp_for_drawing->diwfirstword; ! 200: } ! 201: #ifdef LORES_HACK ! 202: if (currprefs.gfx_lores == 2) ! 203: pix <<= 1, stoppos <<= 1; ! 204: #endif ! 205: while (pix < stoppos) { ! 206: int pv = pixdata.apixels[pix]; ! 207: switch(pv & 0x30) { ! 208: case 0x00: ham_lastcolor = colors_for_drawing.color_regs[pv]; break; ! 209: case 0x10: ham_lastcolor &= 0xFF0; ham_lastcolor |= (pv & 0xF); break; ! 210: case 0x20: ham_lastcolor &= 0x0FF; ham_lastcolor |= (pv & 0xF) << 8; break; ! 211: case 0x30: ham_lastcolor &= 0xF0F; ham_lastcolor |= (pv & 0xF) << 4; break; ! 212: } ! 213: ! 214: buf[pix++] = ham_lastcolor; ! 215: } ! 216: } ! 217: #if 0 ! 218: static void decode_ham_aga (int pix, int stoppos) ! 219: { ! 220: static uae_u32 lastcolor; ! 221: uae_u32 *buf = ham_linebuf; ! 222: ! 223: if (!bplham || (bplplanecnt != 6 && bplplanecnt != 8)) ! 224: return; ! 225: ! 226: if (pix <= dp_for_drawing->diwfirstword) { ! 227: pix = dp_for_drawing->diwfirstword; ! 228: lastcolor = colors_for_drawing.color_regs[0]; ! 229: } ! 230: ! 231: if (dp_for_drawing->bplplanecnt == 6) { ! 232: /* HAM 6 */ ! 233: while (pix < dp_for_drawing->diwlastword && pix < stoppos) { ! 234: int pv = pixdata.apixels[pix]; ! 235: switch(pv & 0x30) { ! 236: case 0x00: lastcolor = colors_for_drawing.color_regs[pv]; break; ! 237: case 0x10: lastcolor &= 0xFFFF00; lastcolor |= (pv & 0xF)*0x11; break; ! 238: case 0x20: lastcolor &= 0x00FFFF; lastcolor |= (pv & 0xF)*0x11 << 16; break; ! 239: case 0x30: lastcolor &= 0xFF00FF; lastcolor |= (pv & 0xF)*0x11 << 8; break; ! 240: } ! 241: buf[pix++] = lastcolor; ! 242: } ! 243: } else if (dp_for_drawing->bplplanecnt == 8) { ! 244: /* HAM 8 */ ! 245: while (pix < dp_for_drawing->diwlastword && pix < stoppos) { ! 246: int pv = pixdata.apixels[pix]; ! 247: switch(pv & 0x3) { ! 248: case 0x0: lastcolor = colors_for_drawing.color_regs[pv >> 2]; break; ! 249: case 0x1: lastcolor &= 0xFFFF03; lastcolor |= (pv & 0xFC); break; ! 250: case 0x2: lastcolor &= 0x03FFFF; lastcolor |= (pv & 0xFC) << 16; break; ! 251: case 0x3: lastcolor &= 0xFF03FF; lastcolor |= (pv & 0xFC) << 8; break; ! 252: } ! 253: buf[pix++] = lastcolor; ! 254: } ! 255: } ! 256: } ! 257: #endif ! 258: ! 259: #if AGA_CHIPSET != 0 ! 260: /* WARNING: Not too much of this will work correctly yet. */ ! 261: ! 262: static void pfield_linetoscr_aga(int pix, int stoppos) ! 263: { ! 264: uae_u32 *buf = aga_lbufptr; ! 265: int i; ! 266: int xor = (uae_u8)(bplcon4 >> 8); ! 267: int oldpix = pix; \ ! 268: ! 269: buf -= pix; \ ! 270: ! 271: for (i = 0; i < stoppos; i++) ! 272: pixdata.apixels[i] ^= xor; ! 273: ! 274: while (pix < dp_for_drawing->diwfirstword && pix < stoppos) { ! 275: buf[pix++] = colors_for_drawing.color_regs[0]; ! 276: } ! 277: if (bplham) { ! 278: while (pix < dp_for_drawing->diwlastword && pix < stoppos) { ! 279: uae_u32 d = ham_linebuf[pix]; ! 280: buf[pix] = d; ! 281: pix++; ! 282: } ! 283: } else if (bpldualpf) { ! 284: /* Dual playfield */ ! 285: int *lookup = bpldualpfpri ? dblpf_aga2 : dblpf_aga1; ! 286: int *lookup_no = bpldualpfpri ? dblpf_2nd2 : dblpf_2nd1; ! 287: while (pix < dp_for_drawing->diwlastword && pix < stoppos) { ! 288: int pixcol = pixdata.apixels[pix]; ! 289: int pfno = lookup_no[pixcol]; ! 290: ! 291: if (spixstate[pix]) { ! 292: buf[pix] = colors_for_drawing.color_regs[pixcol]; ! 293: } else { ! 294: int val = lookup[pixdata.apixels[pix]]; ! 295: if (pfno == 2) ! 296: val += dblpfofs[(bplcon2 >> 10) & 7]; ! 297: buf[pix] = colors_for_drawing.color_regs[val]; ! 298: } ! 299: pix++; ! 300: } ! 301: } else if (bplehb) { ! 302: while (pix < dp_for_drawing->diwlastword && pix < stoppos) { ! 303: int pixcol = pixdata.apixels[pix]; ! 304: uae_u32 d = colors_for_drawing.color_regs[pixcol]; ! 305: /* What about sprites? */ ! 306: if (pixcol & 0x20) ! 307: d = (d & 0x777777) >> 1; ! 308: buf[pix] = d; ! 309: pix++; ! 310: } ! 311: } else { ! 312: while (pix < dp_for_drawing->diwlastword && pix < stoppos) { ! 313: int pixcol = pixdata.apixels[pix]; ! 314: buf[pix] = colors_for_drawing.color_regs[pixcol]; ! 315: pix++; ! 316: } ! 317: } ! 318: while (pix < stoppos) { ! 319: buf[pix++] = colors_for_drawing.color_regs[0]; ! 320: } ! 321: aga_lbufptr += pix - oldpix; ! 322: } ! 323: ! 324: static void aga_translate32(int start, int stop) ! 325: { ! 326: memcpy (((uae_u32 *)xlinebuffer) + start, aga_linebuf + start, 4*(stop-start)); ! 327: } ! 328: ! 329: static void aga_translate16(int start, int stop) ! 330: { ! 331: int i; ! 332: for (i = start; i < stop; i++) { ! 333: uae_u32 d = aga_linebuf[i]; ! 334: uae_u16 v = ((d & 0xF0) >> 4) | ((d & 0xF000) >> 8) | ((d & 0xF00000) >> 12); ! 335: ((uae_u16 *)xlinebuffer)[i] = xcolors[v]; ! 336: } ! 337: } ! 338: ! 339: static void aga_translate8(int start, int stop) ! 340: { ! 341: int i; ! 342: for (i = start; i < stop; i++) { ! 343: uae_u32 d = aga_linebuf[i]; ! 344: uae_u16 v = ((d & 0xF0) >> 4) | ((d & 0xF000) >> 8) | ((d & 0xF00000) >> 12); ! 345: ((uae_u8 *)xlinebuffer)[i] = xcolors[v]; ! 346: } ! 347: } ! 348: #endif ! 349: ! 350: static int linetoscr_double_offset; ! 351: ! 352: #define LINE_TO_SCR(NAME, TYPE, DO_DOUBLE, CONVERT) \ ! 353: static void NAME(int pix, int lframe_end, int diw_end, int stoppos) \ ! 354: { \ ! 355: TYPE *buf = ((TYPE *)xlinebuffer); \ ! 356: /* int oldpix = pix;*/ \ ! 357: /* These are different for register-allocation purposes. */ \ ! 358: TYPE d1, d2; \ ! 359: int offset; \ ! 360: \ ! 361: if (DO_DOUBLE) offset = linetoscr_double_offset / sizeof(TYPE); \ ! 362: \ ! 363: d1 = CONVERT(colors_for_drawing.acolors[0]); \ ! 364: while (pix < lframe_end) { \ ! 365: buf[pix] = d1; if (DO_DOUBLE) buf[pix+offset] = d1; \ ! 366: pix++; \ ! 367: } \ ! 368: if (bplham && bplplanecnt == 6) { \ ! 369: /* HAM 6 */ \ ! 370: while (pix < diw_end) { \ ! 371: TYPE d = CONVERT(xcolors[ham_linebuf[pix]]); \ ! 372: buf[pix] = d; if (DO_DOUBLE) buf[pix+offset] = d; \ ! 373: pix++; \ ! 374: } \ ! 375: } else if (bpldualpf) { \ ! 376: /* Dual playfield */ \ ! 377: int *lookup = bpldualpfpri ? dblpf_ind2 : dblpf_ind1; \ ! 378: while (pix < diw_end) { \ ! 379: int pixcol = pixdata.apixels[pix]; \ ! 380: TYPE d; \ ! 381: d = CONVERT(colors_for_drawing.acolors[lookup[pixcol]]); \ ! 382: buf[pix] = d; if (DO_DOUBLE) buf[pix+offset] = d; \ ! 383: pix++; \ ! 384: } \ ! 385: } else if (bplehb) { \ ! 386: while (pix < diw_end) { \ ! 387: int p = pixdata.apixels[pix]; \ ! 388: TYPE d = CONVERT (colors_for_drawing.acolors[p]); \ ! 389: if (p >= 32) d = CONVERT(xcolors[(colors_for_drawing.color_regs[p-32] >> 1) & 0x777]); \ ! 390: buf[pix] = d; if (DO_DOUBLE) buf[pix+offset] = d; \ ! 391: pix++; \ ! 392: } \ ! 393: } else { \ ! 394: while (pix < diw_end) { \ ! 395: TYPE d = CONVERT (colors_for_drawing.acolors[pixdata.apixels[pix]]); \ ! 396: buf[pix] = d; if (DO_DOUBLE) buf[pix+offset] = d; \ ! 397: pix++; \ ! 398: } \ ! 399: } \ ! 400: d2 = CONVERT (colors_for_drawing.acolors[0]); \ ! 401: while (pix < stoppos) { \ ! 402: buf[pix] = d2; if (DO_DOUBLE) buf[pix+offset] = d2; \ ! 403: pix++; \ ! 404: } \ ! 405: } ! 406: ! 407: #define FILL_LINE(NAME, TYPE, CONVERT) \ ! 408: static void NAME(char *buf, int start, int stop) \ ! 409: { \ ! 410: TYPE *b = (TYPE *)buf; \ ! 411: int i;\ ! 412: xcolnr col = colors_for_drawing.acolors[0]; \ ! 413: for (i = start; i < stop; i++) \ ! 414: b[i] = CONVERT (col); \ ! 415: } ! 416: ! 417: LINE_TO_SCR(pfield_linetoscr_8, uae_u8, 0,) ! 418: LINE_TO_SCR(pfield_linetoscr_16, uae_u16, 0,) ! 419: LINE_TO_SCR(pfield_linetoscr_32, uae_u32, 0,) ! 420: LINE_TO_SCR(pfield_linetoscr_8_double_slow, uae_u8, 1,) ! 421: LINE_TO_SCR(pfield_linetoscr_16_double_slow, uae_u16, 1,) ! 422: LINE_TO_SCR(pfield_linetoscr_32_double_slow, uae_u32, 1,) ! 423: ! 424: FILL_LINE(fill_line_8, uae_u8,) ! 425: FILL_LINE(fill_line_16, uae_u16,) ! 426: FILL_LINE(fill_line_32, uae_u32,) ! 427: ! 428: #ifdef HAVE_UAE_U24 ! 429: LINE_TO_SCR(pfield_linetoscr_24, uae_u24, 0, uae24_convert) ! 430: LINE_TO_SCR(pfield_linetoscr_24_double_slow, uae_u24, 1, uae24_convert) ! 431: FILL_LINE(fill_line_24, uae_u24, uae24_convert) ! 432: #else ! 433: /* Dummy versions */ ! 434: static void pfield_linetoscr_24 (int pix, int lframe_end, int diw_end, int stoppos) ! 435: { ! 436: } ! 437: static void pfield_linetoscr_24_double_slow (int pix, int lframe_end, int diw_end, int stoppos) ! 438: { ! 439: } ! 440: static void fill_line_24 (char *buf, int start, int stop) ! 441: { ! 442: } ! 443: #endif ! 444: ! 445: static __inline__ void fill_line_full (void) ! 446: { ! 447: switch (gfxvidinfo.pixbytes) { ! 448: case 1: fill_line_8(xlinebuffer, linetoscr_x_adjust, linetoscr_x_adjust + gfxvidinfo.width); break; ! 449: case 2: fill_line_16(xlinebuffer, linetoscr_x_adjust, linetoscr_x_adjust + gfxvidinfo.width); break; ! 450: case 3: fill_line_24(xlinebuffer, linetoscr_x_adjust, linetoscr_x_adjust + gfxvidinfo.width); break; ! 451: case 4: fill_line_32(xlinebuffer, linetoscr_x_adjust, linetoscr_x_adjust + gfxvidinfo.width); break; ! 452: } ! 453: } ! 454: ! 455: #define fill_line fill_line_full ! 456: ! 457: #define pfield_linetoscr_full8 pfield_linetoscr_8 ! 458: #define pfield_linetoscr_full16 pfield_linetoscr_16 ! 459: #define pfield_linetoscr_full24 pfield_linetoscr_24 ! 460: #define pfield_linetoscr_full32 pfield_linetoscr_32 ! 461: ! 462: #define pfield_linetoscr_full8_double pfield_linetoscr_8_double_slow ! 463: #define pfield_linetoscr_full16_double pfield_linetoscr_16_double_slow ! 464: #define pfield_linetoscr_full24_double pfield_linetoscr_24_double_slow ! 465: #define pfield_linetoscr_full32_double pfield_linetoscr_32_double_slow ! 466: ! 467: #if 1 ! 468: #undef fill_line ! 469: static __inline__ void fill_line (void) ! 470: { ! 471: int shift; ! 472: int nints, nrem; ! 473: int *start; ! 474: xcolnr val; ! 475: ! 476: #ifdef HAVE_UAE_U24 ! 477: if (gfxvidinfo.pixbytes == 3) { ! 478: fill_line_24 (xlinebuffer, linetoscr_x_adjust, linetoscr_x_adjust + gfxvidinfo.width); ! 479: return; ! 480: } ! 481: #endif ! 482: ! 483: shift = 0; ! 484: if (gfxvidinfo.pixbytes == 2) ! 485: shift = 1; ! 486: if (gfxvidinfo.pixbytes == 4) ! 487: shift = 2; ! 488: ! 489: nints = gfxvidinfo.width >> (2-shift); ! 490: nrem = nints & 7; ! 491: nints &= ~7; ! 492: start = (int *)(((char *)xlinebuffer) + (linetoscr_x_adjust << shift)); ! 493: val = colors_for_drawing.acolors[0]; ! 494: for (; nints > 0; nints -= 8, start += 8) { ! 495: *start = val; ! 496: *(start+1) = val; ! 497: *(start+2) = val; ! 498: *(start+3) = val; ! 499: *(start+4) = val; ! 500: *(start+5) = val; ! 501: *(start+6) = val; ! 502: *(start+7) = val; ! 503: } ! 504: ! 505: switch (nrem) { ! 506: case 7: ! 507: *start++ = val; ! 508: case 6: ! 509: *start++ = val; ! 510: case 5: ! 511: *start++ = val; ! 512: case 4: ! 513: *start++ = val; ! 514: case 3: ! 515: *start++ = val; ! 516: case 2: ! 517: *start++ = val; ! 518: case 1: ! 519: *start = val; ! 520: } ! 521: } ! 522: ! 523: #ifdef X86_ASSEMBLY ! 524: ! 525: #undef pfield_linetoscr_full8 ! 526: /* The types are lies, of course. */ ! 527: extern void pfield_linetoscr_normal_asm8(void) __asm__("pfield_linetoscr_normal_asm8"); ! 528: extern void pfield_linetoscr_ehb_asm8(void) __asm__("pfield_linetoscr_ehb_asm8"); ! 529: extern void pfield_linetoscr_ham6_asm8(void) __asm__("pfield_linetoscr_ham6_asm8"); ! 530: extern void pfield_linetoscr_dualpf_asm8(void) __asm__("pfield_linetoscr_dualpf_asm8"); ! 531: extern void pfield_linetoscr_hdouble_asm8(void) __asm__("pfield_linetoscr_hdouble_asm8"); ! 532: extern void pfield_linetoscr_hdouble_dpf_asm8(void) __asm__("pfield_linetoscr_hdouble_dpf_asm8"); ! 533: extern void pfield_linetoscr_hdouble_ehb_asm8(void) __asm__("pfield_linetoscr_hdouble_ehb_asm8"); ! 534: extern void pfield_linetoscr_asm8(void (*)(void), int, int, int, int, ...) __asm__("pfield_linetoscr_asm8"); ! 535: ! 536: static void pfield_linetoscr_full8(int pix, int lframe_end, int diw_end, int stoppos) ! 537: { ! 538: int lframe_end_1, diw_end_1; ! 539: ! 540: lframe_end_1 = pix + ((lframe_end - pix) & ~3); ! 541: diw_end_1 = stoppos - ((stoppos - diw_end) & ~3); ! 542: ! 543: if (bplham && bplplanecnt == 6) { ! 544: pfield_linetoscr_asm8(pfield_linetoscr_ham6_asm8, pix, lframe_end_1, diw_end_1, stoppos); ! 545: } else if (bpldualpf) { ! 546: #ifdef LORES_HACK ! 547: if (currprefs.gfx_lores == 2) ! 548: pfield_linetoscr_asm8(pfield_linetoscr_hdouble_dpf_asm8, pix, lframe_end_1, diw_end_1, stoppos, ! 549: bpldualpfpri ? dblpf_ind2 : dblpf_ind1); ! 550: else ! 551: #endif ! 552: pfield_linetoscr_asm8(pfield_linetoscr_dualpf_asm8, pix, lframe_end_1, diw_end_1, stoppos, ! 553: bpldualpfpri ? dblpf_ind2 : dblpf_ind1); ! 554: } else if (bplehb) { ! 555: #ifdef LORES_HACK ! 556: if (currprefs.gfx_lores == 2) ! 557: pfield_linetoscr_asm8(pfield_linetoscr_hdouble_ehb_asm8, pix, lframe_end_1, diw_end_1, stoppos); ! 558: else ! 559: #endif ! 560: pfield_linetoscr_asm8(pfield_linetoscr_ehb_asm8, pix, lframe_end_1, diw_end_1, stoppos); ! 561: } else { ! 562: #ifdef LORES_HACK ! 563: if (currprefs.gfx_lores == 2) ! 564: pfield_linetoscr_asm8(pfield_linetoscr_hdouble_asm8, pix, lframe_end_1, diw_end_1, stoppos); ! 565: else ! 566: #endif ! 567: pfield_linetoscr_asm8(pfield_linetoscr_normal_asm8, pix, lframe_end_1, diw_end_1, stoppos); ! 568: } ! 569: ! 570: /* The assembly functions work on aligned data, so we may have to do some ! 571: * additional work at the edges. */ ! 572: if (lframe_end != lframe_end_1) { ! 573: int i, c = colors_for_drawing.acolors[0]; ! 574: for (i = lframe_end_1; i < lframe_end; i++) ! 575: xlinebuffer[i] = c; ! 576: } ! 577: if (diw_end != diw_end_1) { ! 578: int i, c = colors_for_drawing.acolors[0]; ! 579: for (i = diw_end; i < diw_end_1; i++) ! 580: xlinebuffer[i] = c; ! 581: } ! 582: } ! 583: ! 584: #undef pfield_linetoscr_full16 ! 585: extern void pfield_linetoscr_normal_asm16(void) __asm__("pfield_linetoscr_normal_asm16"); ! 586: extern void pfield_linetoscr_ehb_asm16(void) __asm__("pfield_linetoscr_ehb_asm16"); ! 587: extern void pfield_linetoscr_ham6_asm16(void) __asm__("pfield_linetoscr_ham6_asm16"); ! 588: extern void pfield_linetoscr_dualpf_asm16(void) __asm__("pfield_linetoscr_dualpf_asm16"); ! 589: extern void pfield_linetoscr_hdouble_asm16(void) __asm__("pfield_linetoscr_hdouble_asm16"); ! 590: extern void pfield_linetoscr_hdouble_dpf_asm16(void) __asm__("pfield_linetoscr_hdouble_dpf_asm16"); ! 591: extern void pfield_linetoscr_hdouble_ehb_asm16(void) __asm__("pfield_linetoscr_hdouble_ehb_asm16"); ! 592: extern void pfield_linetoscr_asm16(void (*)(void), int, int, int, int, ...) __asm__("pfield_linetoscr_asm16"); ! 593: ! 594: static void pfield_linetoscr_full16(int pix, int lframe_end, int diw_end, int stoppos) ! 595: { ! 596: int lframe_end_1, diw_end_1; ! 597: ! 598: lframe_end_1 = pix + ((lframe_end - pix) & ~3); ! 599: diw_end_1 = stoppos - ((stoppos - diw_end) & ~3); ! 600: ! 601: if (bplham && bplplanecnt == 6) { ! 602: pfield_linetoscr_asm16(pfield_linetoscr_ham6_asm16, pix, lframe_end_1, diw_end_1, stoppos); ! 603: } else if (bpldualpf) { ! 604: #ifdef LORES_HACK ! 605: if (currprefs.gfx_lores == 2) ! 606: pfield_linetoscr_asm16(pfield_linetoscr_hdouble_dpf_asm16, pix, lframe_end_1, diw_end_1, stoppos, ! 607: bpldualpfpri ? dblpf_ind2 : dblpf_ind1); ! 608: else ! 609: #endif ! 610: pfield_linetoscr_asm16(pfield_linetoscr_dualpf_asm16, pix, lframe_end_1, diw_end_1, stoppos, ! 611: bpldualpfpri ? dblpf_ind2 : dblpf_ind1); ! 612: } else if (bplehb) { ! 613: #ifdef LORES_HACK ! 614: if (currprefs.gfx_lores == 2) ! 615: pfield_linetoscr_asm16(pfield_linetoscr_hdouble_ehb_asm16, pix, lframe_end_1, diw_end_1, stoppos); ! 616: else ! 617: #endif ! 618: pfield_linetoscr_asm16(pfield_linetoscr_ehb_asm16, pix, lframe_end_1, diw_end_1, stoppos); ! 619: } else { ! 620: #ifdef LORES_HACK ! 621: if (currprefs.gfx_lores == 2) ! 622: pfield_linetoscr_asm16(pfield_linetoscr_hdouble_asm16, pix, lframe_end_1, diw_end_1, stoppos); ! 623: else ! 624: #endif ! 625: pfield_linetoscr_asm16(pfield_linetoscr_normal_asm16, pix, lframe_end_1, diw_end_1, stoppos); ! 626: } ! 627: ! 628: /* The assembly functions work on aligned data, so we may have to do some ! 629: * additional work at the edges. */ ! 630: if (lframe_end != lframe_end_1) { ! 631: int i, c = colors_for_drawing.acolors[0]; ! 632: for (i = lframe_end_1; i < lframe_end; i++) ! 633: ((uae_u16 *)xlinebuffer)[i] = c; ! 634: } ! 635: if (diw_end != diw_end_1) { ! 636: int i, c = colors_for_drawing.acolors[0]; ! 637: for (i = diw_end; i < diw_end_1; i++) ! 638: ((uae_u16 *)xlinebuffer)[i] = c; ! 639: } ! 640: } ! 641: #endif ! 642: ! 643: #ifndef NO_DOUBLING_LINETOSCR ! 644: #define NO_DOUBLING_LINETOSCR ! 645: #endif ! 646: ! 647: #endif ! 648: ! 649: #ifdef NO_DOUBLING_LINETOSCR ! 650: #undef pfield_linetoscr_full8_double ! 651: #undef pfield_linetoscr_full16_double ! 652: static void pfield_linetoscr_full8_double(int start, int lframe_end, int diw_end, int stop) ! 653: { ! 654: char *oldxlb = (char *)xlinebuffer; ! 655: pfield_linetoscr_full8(start, lframe_end, diw_end, stop); ! 656: xlinebuffer = oldxlb + linetoscr_double_offset; ! 657: pfield_linetoscr_full8(start, lframe_end, diw_end, stop); ! 658: } ! 659: static void pfield_linetoscr_full16_double(int start, int lframe_end, int diw_end, int stop) ! 660: { ! 661: char *oldxlb = (char *)xlinebuffer; ! 662: pfield_linetoscr_full16(start, lframe_end, diw_end, stop); ! 663: xlinebuffer = oldxlb + linetoscr_double_offset; ! 664: pfield_linetoscr_full16(start, lframe_end, diw_end, stop); ! 665: } ! 666: #endif ! 667: ! 668: static int linetoscr_diw_end, linetoscr_diw_start; ! 669: ! 670: /* Initialize the variables necessary for drawing a line. ! 671: * This involves setting up start/stop positions and display window ! 672: * borders. Also, since the drawing code may not fully overwrite all ! 673: * releveant areas in the pixdata.apixels array for speed reasons, parts of ! 674: * it must possibly be cleared here. */ ! 675: static void pfield_init_linetoscr (void) ! 676: { ! 677: int ddf_left, ddf_right; ! 678: int mindelay = bpldelay1, maxdelay = bpldelay2; ! 679: if (bpldelay1 > bpldelay2) ! 680: maxdelay = bpldelay1, mindelay = bpldelay2; ! 681: ! 682: linetoscr_diw_start = dp_for_drawing->diwfirstword; ! 683: linetoscr_diw_end = dp_for_drawing->diwlastword; ! 684: ! 685: /* We should really look at DDF also when calculating max_diwstop/min_diwstrt, ! 686: * so that centering works better, but I'm afraid that might cost too many ! 687: * cycles. Plus it's dangerous, see the code below that handles the case ! 688: * with sprites. */ ! 689: if (dip_for_drawing->nr_sprites == 0) { ! 690: int hiresadjust = bplhires ? 4 : 8; ! 691: ddf_left = ((dp_for_drawing->plfstrt + hiresadjust)*2 + mindelay - DISPLAY_LEFT_SHIFT) << lores_shift; ! 692: ddf_right = ((dp_for_drawing->plfstrt + dp_for_drawing->plflinelen + hiresadjust)*2 + maxdelay - DISPLAY_LEFT_SHIFT) << lores_shift; ! 693: ! 694: if (linetoscr_diw_start < ddf_left) ! 695: linetoscr_diw_start = ddf_left; ! 696: if (linetoscr_diw_end > ddf_right) ! 697: linetoscr_diw_end = ddf_right; ! 698: ! 699: if (mindelay != maxdelay) { ! 700: /* Raahh... ! 701: * We just clear the maximum amount of space that may need to be ! 702: * cleared. We could do this exactly, but it would come out slower ! 703: * because of the overhead. */ ! 704: if (currprefs.gfx_lores == 2) { ! 705: fuzzy_memset_le32 (pixdata.apixels, 0, (ddf_left>>1), 15); ! 706: fuzzy_memset_le32 (pixdata.apixels, 0, (ddf_right>>1) - 15, 15); ! 707: } else if (currprefs.gfx_lores) { ! 708: fuzzy_memset_le32 (pixdata.apixels, 0, ddf_left, 15); ! 709: fuzzy_memset_le32 (pixdata.apixels, 0, ddf_right - 15, 15); ! 710: } else { ! 711: fuzzy_memset_le32 (pixdata.apixels, 0, ddf_left, 30); ! 712: fuzzy_memset_le32 (pixdata.apixels, 0, ddf_right - 30, 30); ! 713: } ! 714: } ! 715: } else { ! 716: int hiresadjust = bplhires ? 4 : 8; ! 717: /* We swap mindelay and maxdelay here to get rid of the mindelay != maxdelay check. ! 718: * Since we have to do a memset anyway (because there may be sprites), ! 719: * we might as well clear all at once. */ ! 720: ddf_left = ((dp_for_drawing->plfstrt + hiresadjust)*2 + maxdelay - DISPLAY_LEFT_SHIFT) << lores_shift; ! 721: ddf_right = ((dp_for_drawing->plfstrt + dp_for_drawing->plflinelen + hiresadjust)*2 + mindelay - DISPLAY_LEFT_SHIFT) << lores_shift; ! 722: if (linetoscr_diw_start < ddf_left) { ! 723: int strt = linetoscr_diw_start; ! 724: int stop = ddf_left; ! 725: #ifdef LORES_HACK ! 726: if (currprefs.gfx_lores == 2) ! 727: strt >>= 1, stop >>= 1; ! 728: #endif ! 729: if (strt < stop) ! 730: fuzzy_memset (pixdata.apixels, 0, strt, stop - strt); ! 731: } ! 732: ! 733: if (linetoscr_diw_end > ddf_right) { ! 734: int strt = ddf_right; ! 735: int stop = linetoscr_diw_end; ! 736: #ifdef LORES_HACK ! 737: if (currprefs.gfx_lores == 2) ! 738: strt >>= 1, stop >>= 1; ! 739: #endif ! 740: if (strt < stop) ! 741: fuzzy_memset (pixdata.apixels, 0, strt, stop - strt); ! 742: } ! 743: } ! 744: /* Perverse cases happen. */ ! 745: if (linetoscr_diw_end < linetoscr_diw_start) ! 746: linetoscr_diw_end = linetoscr_diw_start; ! 747: } ! 748: ! 749: static void pfield_do_linetoscr(int start, int stop) ! 750: { ! 751: int lframe_end = linetoscr_diw_start, diw_end = linetoscr_diw_end; ! 752: ! 753: if (stop > linetoscr_right_x) ! 754: stop = linetoscr_right_x; ! 755: if (start < linetoscr_x_adjust) ! 756: start = linetoscr_x_adjust; ! 757: ! 758: if (lframe_end < start) ! 759: lframe_end = start; ! 760: if (diw_end > stop) ! 761: diw_end = stop; ! 762: ! 763: if (start >= stop) ! 764: return; ! 765: ! 766: #if AGA_CHIPSET == 0 ! 767: if (start == linetoscr_x_adjust && stop == linetoscr_right_x) { ! 768: switch (gfxvidinfo.pixbytes) { ! 769: case 1: pfield_linetoscr_full8 (start, lframe_end, diw_end, stop); break; ! 770: case 2: pfield_linetoscr_full16 (start, lframe_end, diw_end, stop); break; ! 771: case 3: pfield_linetoscr_full24 (start, lframe_end, diw_end, stop); break; ! 772: case 4: pfield_linetoscr_full32 (start, lframe_end, diw_end, stop); break; ! 773: } ! 774: } else { ! 775: switch (gfxvidinfo.pixbytes) { ! 776: case 1: pfield_linetoscr_8 (start, lframe_end, diw_end, stop); break; ! 777: case 2: pfield_linetoscr_16 (start, lframe_end, diw_end, stop); break; ! 778: case 3: pfield_linetoscr_24 (start, lframe_end, diw_end, stop); break; ! 779: case 4: pfield_linetoscr_32 (start, lframe_end, diw_end, stop); break; ! 780: } ! 781: } ! 782: #else ! 783: pfield_linetoscr_aga(start, lframe_end, diw_end, stop); ! 784: #endif ! 785: } ! 786: ! 787: static void pfield_do_fill_line(int start, int stop) ! 788: { ! 789: if (stop > linetoscr_right_x) ! 790: stop = linetoscr_right_x; ! 791: if (start < linetoscr_x_adjust) ! 792: start = linetoscr_x_adjust; ! 793: ! 794: if (start >= stop) ! 795: return; ! 796: ! 797: switch (gfxvidinfo.pixbytes) { ! 798: case 1: fill_line_8 (xlinebuffer, start, stop); break; ! 799: case 2: fill_line_16 (xlinebuffer, start, stop); break; ! 800: case 3: fill_line_24 (xlinebuffer, start, stop); break; ! 801: case 4: fill_line_32 (xlinebuffer, start, stop); break; ! 802: } ! 803: } ! 804: ! 805: static void pfield_do_linetoscr_full(int double_line) ! 806: { ! 807: int start = linetoscr_x_adjust, stop = start + gfxvidinfo.width; ! 808: int lframe_end = linetoscr_diw_start, diw_end = linetoscr_diw_end; ! 809: if (lframe_end < start) ! 810: lframe_end = start; ! 811: if (diw_end > stop) ! 812: diw_end = stop; ! 813: ! 814: #if AGA_CHIPSET == 0 ! 815: if (double_line) { ! 816: switch (gfxvidinfo.pixbytes) { ! 817: case 1: pfield_linetoscr_full8_double (start, lframe_end, diw_end, stop); break; ! 818: case 2: pfield_linetoscr_full16_double (start, lframe_end, diw_end, stop); break; ! 819: case 3: pfield_linetoscr_full24_double (start, lframe_end, diw_end, stop); break; ! 820: case 4: pfield_linetoscr_full32_double (start, lframe_end, diw_end, stop); break; ! 821: } ! 822: } else ! 823: switch (gfxvidinfo.pixbytes) { ! 824: case 1: pfield_linetoscr_full8 (start, lframe_end, diw_end, stop); break; ! 825: case 2: pfield_linetoscr_full16 (start, lframe_end, diw_end, stop); break; ! 826: case 3: pfield_linetoscr_full24 (start, lframe_end, diw_end, stop); break; ! 827: case 4: pfield_linetoscr_full32 (start, lframe_end, diw_end, stop); break; ! 828: } ! 829: #else ! 830: pfield_linetoscr_aga(start, lframe_end, diw_end, stop); ! 831: #endif ! 832: } ! 833: ! 834: static void gen_pfield_tables(void) ! 835: { ! 836: int i; ! 837: union { ! 838: struct { ! 839: uae_u8 a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p; ! 840: } foo; ! 841: struct { ! 842: uae_u32 a, b, c, d; ! 843: } bar; ! 844: } baz; ! 845: ! 846: /* For now, the AGA stuff is broken in the dual playfield case. We encode ! 847: * sprites in dpf mode by ORing the pixel value with 0x80. To make dual ! 848: * playfield rendering easy, the lookup tables contain are made linear for ! 849: * values >= 128. That only works for OCS/ECS, though. */ ! 850: ! 851: for (i = 0; i < 256; i++) { ! 852: int plane1 = (i & 1) | ((i >> 1) & 2) | ((i >> 2) & 4) | ((i >> 3) & 8); ! 853: int plane2 = ((i >> 1) & 1) | ((i >> 2) & 2) | ((i >> 3) & 4) | ((i >> 4) & 8); ! 854: dblpf_2nd1[i] = plane1 == 0 ? (plane2 == 0 ? 0 : 2) : 1; ! 855: dblpf_2nd2[i] = plane2 == 0 ? (plane1 == 0 ? 0 : 1) : 2; ! 856: if (plane2 > 0) ! 857: plane2 += 8; ! 858: dblpf_ind1[i] = i >= 128 ? i & 0x7F : (plane1 == 0 ? plane2 : plane1); ! 859: dblpf_ind2[i] = i >= 128 ? i & 0x7F : (plane2 == 0 ? plane1 : plane2); ! 860: ! 861: lots_of_twos[i] = i == 0 ? 0 : 2; ! 862: linear_map_256[i] = i; ! 863: } ! 864: ! 865: for (i = 0; i < 256; i++) { ! 866: /* We lose every second pixel in HiRes if UAE runs in a 320x200 screen. */ ! 867: baz.foo.a = i & 64 ? 1 : 0; ! 868: baz.foo.b = i & 16 ? 1 : 0; ! 869: baz.foo.c = i & 4 ? 1 : 0; ! 870: baz.foo.d = i & 1 ? 1 : 0; ! 871: hirestab_l[i][0] = baz.bar.a; ! 872: ! 873: baz.foo.a = i & 128 ? 1 : 0; ! 874: baz.foo.b = i & 64 ? 1 : 0; ! 875: baz.foo.c = i & 32 ? 1 : 0; ! 876: baz.foo.d = i & 16 ? 1 : 0; ! 877: baz.foo.e = i & 8 ? 1 : 0; ! 878: baz.foo.f = i & 4 ? 1 : 0; ! 879: baz.foo.g = i & 2 ? 1 : 0; ! 880: baz.foo.h = i & 1 ? 1 : 0; ! 881: lorestab_l[i][0] = baz.bar.a; ! 882: lorestab_l[i][1] = baz.bar.b; ! 883: clxtab[i] = ((((i & 3) && (i & 12)) << 9) ! 884: | (((i & 3) && (i & 48)) << 10) ! 885: | (((i & 3) && (i & 192)) << 11) ! 886: | (((i & 12) && (i & 48)) << 12) ! 887: | (((i & 12) && (i & 192)) << 13) ! 888: | (((i & 48) && (i & 192)) << 14)); ! 889: } ! 890: ! 891: for (i = 0; i < 256; i++) { ! 892: baz.foo.a = i & 128 ? 1 : 0; ! 893: baz.foo.b = i & 64 ? 1 : 0; ! 894: baz.foo.c = i & 32 ? 1 : 0; ! 895: baz.foo.d = i & 16 ? 1 : 0; ! 896: baz.foo.e = i & 8 ? 1 : 0; ! 897: baz.foo.f = i & 4 ? 1 : 0; ! 898: baz.foo.g = i & 2 ? 1 : 0; ! 899: baz.foo.h = i & 1 ? 1 : 0; ! 900: hirestab_h[i][0] = baz.bar.a; ! 901: hirestab_h[i][1] = baz.bar.b; ! 902: ! 903: baz.foo.a = i & 128 ? 1 : 0; ! 904: baz.foo.b = i & 128 ? 1 : 0; ! 905: baz.foo.c = i & 64 ? 1 : 0; ! 906: baz.foo.d = i & 64 ? 1 : 0; ! 907: baz.foo.e = i & 32 ? 1 : 0; ! 908: baz.foo.f = i & 32 ? 1 : 0; ! 909: baz.foo.g = i & 16 ? 1 : 0; ! 910: baz.foo.h = i & 16 ? 1 : 0; ! 911: baz.foo.i = i & 8 ? 1 : 0; ! 912: baz.foo.j = i & 8 ? 1 : 0; ! 913: baz.foo.k = i & 4 ? 1 : 0; ! 914: baz.foo.l = i & 4 ? 1 : 0; ! 915: baz.foo.m = i & 2 ? 1 : 0; ! 916: baz.foo.n = i & 2 ? 1 : 0; ! 917: baz.foo.o = i & 1 ? 1 : 0; ! 918: baz.foo.p = i & 1 ? 1 : 0; ! 919: lorestab_h[i][0] = baz.bar.a; ! 920: lorestab_h[i][1] = baz.bar.b; ! 921: lorestab_h[i][2] = baz.bar.c; ! 922: lorestab_h[i][3] = baz.bar.d; ! 923: } ! 924: } ! 925: ! 926: static uae_u32 attach_2nd; ! 927: ! 928: static uae_u32 do_sprite_collisions (struct sprite_draw *spd, int prev_overlap, int i, int nr_spr) ! 929: { ! 930: int j; ! 931: int sprxp = spd[i].linepos; ! 932: uae_u32 datab = spd[i].datab; ! 933: uae_u32 mask2 = 0; ! 934: int sbit = 1 << spd[i].num; ! 935: int sprx_shift = 1; ! 936: int attach_compare = -1; ! 937: if (currprefs.gfx_lores != 1) ! 938: sprx_shift = 0; ! 939: ! 940: attach_2nd = 0; ! 941: if ((spd[i].num & 1) == 1 && (spd[i].ctl & 0x80) == 0x80) ! 942: attach_compare = spd[i].num - 1; ! 943: ! 944: for (j = prev_overlap; j < i; j++) { ! 945: uae_u32 mask1; ! 946: int off; ! 947: ! 948: if (spd[i].num < spd[j].num) ! 949: continue; ! 950: ! 951: off = sprxp - spd[j].linepos; ! 952: off <<= sprx_shift; ! 953: mask1 = spd[j].datab >> off; ! 954: ! 955: /* If j is an attachment for i, then j doesn't block i */ ! 956: if (spd[j].num == attach_compare) { ! 957: attach_2nd |= mask1; ! 958: } else { ! 959: mask1 |= (mask1 & 0xAAAAAAAA) >> 1; ! 960: mask1 |= (mask1 & 0x55555555) << 1; ! 961: if (datab & mask1) ! 962: clxdat |= clxtab[(sbit | (1 << spd[j].num)) & clx_sprmask]; ! 963: mask2 |= mask1; ! 964: } ! 965: } ! 966: for (j = i+1; j < nr_spr; j++) { ! 967: uae_u32 mask1; ! 968: int off = spd[j].linepos - sprxp; ! 969: ! 970: if (off >= sprite_width || spd[i].num < spd[j].num) ! 971: break; ! 972: ! 973: off <<= sprx_shift; ! 974: mask1 = spd[j].datab << off; ! 975: ! 976: /* If j is an attachment for i, then j doesn't block i */ ! 977: if (spd[j].num == attach_compare) { ! 978: attach_2nd |= mask1; ! 979: } else { ! 980: mask1 |= (mask1 & 0xAAAAAAAA) >> 1; ! 981: mask1 |= (mask1 & 0x55555555) << 1; ! 982: if (datab & mask1) ! 983: clxdat |= clxtab[(sbit | (1 << spd[j].num)) & clx_sprmask]; ! 984: mask2 |= mask1; ! 985: } ! 986: } ! 987: datab &= ~mask2; ! 988: return datab; ! 989: } ! 990: ! 991: static __inline__ void render_sprite (int spr, int sprxp, uae_u32 datab, int ham, int attch, int sprx_inc) ! 992: { ! 993: uae_u32 datcd; ! 994: int basecol = 16; ! 995: if (!attch) ! 996: basecol += (spr & ~1)*2; ! 997: if (bpldualpf) ! 998: basecol |= 128; ! 999: if (attch) ! 1000: datcd = attach_2nd; ! 1001: ! 1002: for(; attch ? datab | datcd : datab; sprxp += sprx_inc) { ! 1003: int col; ! 1004: ! 1005: if (attch) { ! 1006: col = ((datab & 3) << 2) | (datcd & 3); ! 1007: datcd >>= 2; ! 1008: } else ! 1009: col = datab & 3; ! 1010: datab >>= 2; ! 1011: if (col) { ! 1012: col |= basecol; ! 1013: if (ham) { ! 1014: col = colors_for_drawing.color_regs[col]; ! 1015: ham_linebuf[sprxp] = col; ! 1016: if (sprx_inc == 2) { ! 1017: ham_linebuf[sprxp+1] = col; ! 1018: } ! 1019: } else { ! 1020: pixdata.apixels[sprxp] = col; ! 1021: if (sprx_inc == 2) { ! 1022: pixdata.apixels[sprxp+1] = col; ! 1023: } ! 1024: } ! 1025: } ! 1026: } ! 1027: } ! 1028: ! 1029: static void walk_sprites (struct sprite_draw *spd, int nr_spr) ! 1030: { ! 1031: int i, prev_overlap; ! 1032: int last_sprite_pos = -64; ! 1033: uae_u32 plane1 = 0, plane2 = 0; ! 1034: int sprx_inc = 1, sprx_shift = 1; ! 1035: ! 1036: if (currprefs.gfx_lores == 0) ! 1037: sprx_inc = 2, sprx_shift = 0; ! 1038: ! 1039: prev_overlap = 0; ! 1040: for (i = 0; i < nr_spr; i++) { ! 1041: int sprxp = spd[i].linepos; ! 1042: int m = 1 << spd[i].num; ! 1043: uae_u32 datab; ! 1044: while (prev_overlap < i && spd[prev_overlap].linepos + sprite_width <= sprxp) ! 1045: prev_overlap++; ! 1046: ! 1047: datab = do_sprite_collisions (spd, prev_overlap, i, nr_spr); ! 1048: #ifdef LORES_HACK ! 1049: if (currprefs.gfx_lores == 2) ! 1050: sprxp >>= 1; ! 1051: #endif ! 1052: if ((bpldualpf && plfpri[1] < 256) || (plfpri[2] < 256)) { ! 1053: if (sprxp != last_sprite_pos) { ! 1054: int ok = last_sprite_pos-sprxp+16; ! 1055: int ok2; ! 1056: if (ok <= 0) { ! 1057: ok = ok2 = 0; ! 1058: plane1 = 0; ! 1059: plane2 = 0; ! 1060: } else { ! 1061: ok2 = ok << sprx_shift; ! 1062: plane1 >>= 32 - ok2; ! 1063: plane2 >>= 32 - ok2; ! 1064: } ! 1065: last_sprite_pos = sprxp; ! 1066: ! 1067: if (bpldualpf) { ! 1068: uae_u32 mask = 3 << ok2; ! 1069: int p = sprxp+ok; ! 1070: ! 1071: for (; mask; mask <<= 2, p += sprx_inc) { ! 1072: int data = pixdata.apixels[p]; ! 1073: if (dblpf_2nd2[data] == 2) ! 1074: plane2 |= mask; ! 1075: if (dblpf_2nd1[data] == 1) ! 1076: plane1 |= mask; ! 1077: } ! 1078: } else { ! 1079: uae_u32 mask = 3 << ok2; ! 1080: int p = sprxp+ok; ! 1081: ! 1082: for (; mask; mask <<= 2, p += sprx_inc) { ! 1083: if (pixdata.apixels[p]) ! 1084: plane2 |= mask; ! 1085: } ! 1086: } ! 1087: } ! 1088: if (bpldualpf && m >= plfpri[1]) { ! 1089: datab &= ~plane1; ! 1090: attach_2nd &= ~plane1; ! 1091: } ! 1092: if (m >= plfpri[2]) { ! 1093: datab &= ~plane2; ! 1094: attach_2nd &= ~plane2; ! 1095: } ! 1096: } ! 1097: if ((spd[i].num & 1) == 1 && (spd[i].ctl & 0x80) == 0x80) { ! 1098: /* Attached sprite */ ! 1099: if (bplham) { ! 1100: if (sprx_inc == 1) { ! 1101: render_sprite (spd[i].num, sprxp, datab, 1, 1, 1); ! 1102: } else { ! 1103: render_sprite (spd[i].num, sprxp, datab, 1, 1, 2); ! 1104: } ! 1105: } else { ! 1106: if (sprx_inc == 1) { ! 1107: render_sprite (spd[i].num, sprxp, datab, 0, 1, 1); ! 1108: } else { ! 1109: render_sprite (spd[i].num, sprxp, datab, 0, 1, 2); ! 1110: } ! 1111: } ! 1112: /* This still leaves one attached sprite bug, but at the moment I'm too lazy */ ! 1113: if (i + 1 < nr_spr && spd[i+1].num == spd[i].num - 1 && spd[i+1].linepos == spd[i].linepos) ! 1114: i++; ! 1115: } else { ! 1116: if (bplham) { ! 1117: if (sprx_inc == 1) { ! 1118: render_sprite (spd[i].num, sprxp, datab, 1, 0, 1); ! 1119: } else { ! 1120: render_sprite (spd[i].num, sprxp, datab, 1, 0, 2); ! 1121: } ! 1122: } else { ! 1123: if (sprx_inc == 1) { ! 1124: render_sprite (spd[i].num, sprxp, datab, 0, 0, 1); ! 1125: } else { ! 1126: render_sprite (spd[i].num, sprxp, datab, 0, 0, 2); ! 1127: } ! 1128: } ! 1129: } ! 1130: } ! 1131: } ! 1132: ! 1133: #ifndef SMART_UPDATE ! 1134: #undef UNALIGNED_PROFITABLE ! 1135: #endif ! 1136: ! 1137: #ifdef UNALIGNED_PROFITABLE ! 1138: ! 1139: static void pfield_doline_unaligned_h (int lineno) ! 1140: { ! 1141: int xpos = dp_for_drawing->plfstrt * 4 - DISPLAY_LEFT_SHIFT * 2; ! 1142: ! 1143: if (bplhires) { ! 1144: int xpos1 = xpos + 16 + bpldelay1*2; ! 1145: int xpos2; ! 1146: uae_u8 *dataptr = line_data[lineno]; ! 1147: int len = dp_for_drawing->plflinelen >> 1; ! 1148: ! 1149: if (len <= 0) ! 1150: return; ! 1151: ! 1152: if (bpldelay1 == bpldelay2) { ! 1153: switch (bplplanecnt) { ! 1154: case 1: set_hires_h_0_0 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1155: case 2: set_hires_h_1_0 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1156: case 3: set_hires_h_2_0 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1157: case 4: set_hires_h_3_0 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1158: case 5: set_hires_h_4_0 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1159: case 6: set_hires_h_5_0 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1160: case 7: set_hires_h_6_0 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1161: case 8: set_hires_h_7_0 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1162: } ! 1163: } else { ! 1164: switch (bplplanecnt) { ! 1165: case 1: case 2: set_hires_h_0_1 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1166: case 3: case 4: set_hires_h_1_1 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1167: case 5: case 6: set_hires_h_2_1 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1168: case 7: case 8: set_hires_h_3_1 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1169: } ! 1170: ! 1171: xpos2 = xpos + 16 + bpldelay2*2; ! 1172: switch (bplplanecnt) { ! 1173: case 2: case 3: set_hires_h_0_2 ((uae_u32 *)(pixdata.apixels + xpos2), dataptr, len); break; ! 1174: case 4: case 5: set_hires_h_1_2 ((uae_u32 *)(pixdata.apixels + xpos2), dataptr, len); break; ! 1175: case 6: case 7: set_hires_h_2_2 ((uae_u32 *)(pixdata.apixels + xpos2), dataptr, len); break; ! 1176: case 8: set_hires_h_3_2 ((uae_u32 *)(pixdata.apixels + xpos2), dataptr, len); break; ! 1177: } ! 1178: } ! 1179: } else { ! 1180: int xpos1 = xpos + 32 + bpldelay1*2; ! 1181: int xpos2; ! 1182: uae_u8 *dataptr = line_data[lineno]; ! 1183: int len = dp_for_drawing->plflinelen >> 2; ! 1184: ! 1185: if (len <= 0) ! 1186: return; ! 1187: ! 1188: if (bpldelay1 == bpldelay2) { ! 1189: switch (bplplanecnt) { ! 1190: case 1: set_lores_h_0_0 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1191: case 2: set_lores_h_1_0 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1192: case 3: set_lores_h_2_0 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1193: case 4: set_lores_h_3_0 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1194: case 5: set_lores_h_4_0 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1195: case 6: set_lores_h_5_0 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1196: case 7: set_lores_h_6_0 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1197: case 8: set_lores_h_7_0 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1198: } ! 1199: } else { ! 1200: switch (bplplanecnt) { ! 1201: case 1: case 2: set_lores_h_0_1 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1202: case 3: case 4: set_lores_h_1_1 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1203: case 5: case 6: set_lores_h_2_1 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1204: case 7: case 8: set_lores_h_3_1 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1205: } ! 1206: ! 1207: xpos2 = xpos + 32 + bpldelay2*2; ! 1208: switch (bplplanecnt) { ! 1209: case 2: case 3: set_lores_h_0_2 ((uae_u32 *)(pixdata.apixels + xpos2), dataptr, len); break; ! 1210: case 4: case 5: set_lores_h_1_2 ((uae_u32 *)(pixdata.apixels + xpos2), dataptr, len); break; ! 1211: case 6: case 7: set_lores_h_2_2 ((uae_u32 *)(pixdata.apixels + xpos2), dataptr, len); break; ! 1212: case 8: set_lores_h_3_2 ((uae_u32 *)(pixdata.apixels + xpos2), dataptr, len); break; ! 1213: } ! 1214: } ! 1215: } ! 1216: } ! 1217: ! 1218: static void pfield_doline_unaligned_l (int lineno) ! 1219: { ! 1220: int xpos = dp_for_drawing->plfstrt * 2 - DISPLAY_LEFT_SHIFT; ! 1221: ! 1222: if (bplhires) { ! 1223: int xpos1 = xpos + 8 + bpldelay1; ! 1224: int xpos2; ! 1225: uae_u8 *dataptr = line_data[lineno]; ! 1226: int len = dp_for_drawing->plflinelen >> 1; ! 1227: ! 1228: if (len <= 0) ! 1229: return; ! 1230: ! 1231: if (bpldelay1 == bpldelay2) { ! 1232: switch (bplplanecnt) { ! 1233: case 1: set_hires_l_0_0 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1234: case 2: set_hires_l_1_0 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1235: case 3: set_hires_l_2_0 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1236: case 4: set_hires_l_3_0 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1237: case 5: set_hires_l_4_0 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1238: case 6: set_hires_l_5_0 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1239: case 7: set_hires_l_6_0 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1240: case 8: set_hires_l_7_0 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1241: } ! 1242: } else { ! 1243: switch (bplplanecnt) { ! 1244: case 1: case 2: set_hires_l_0_1 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1245: case 3: case 4: set_hires_l_1_1 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1246: case 5: case 6: set_hires_l_2_1 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1247: case 7: case 8: set_hires_l_3_1 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1248: } ! 1249: ! 1250: xpos2 = xpos + 8 + bpldelay2; ! 1251: switch (bplplanecnt) { ! 1252: case 2: case 3: set_hires_l_0_2 ((uae_u32 *)(pixdata.apixels + xpos2), dataptr, len); break; ! 1253: case 4: case 5: set_hires_l_1_2 ((uae_u32 *)(pixdata.apixels + xpos2), dataptr, len); break; ! 1254: case 6: case 7: set_hires_l_2_2 ((uae_u32 *)(pixdata.apixels + xpos2), dataptr, len); break; ! 1255: case 8: set_hires_l_3_2 ((uae_u32 *)(pixdata.apixels + xpos2), dataptr, len); break; ! 1256: } ! 1257: } ! 1258: } else { ! 1259: int xpos1 = xpos + 16 + bpldelay1; ! 1260: int xpos2; ! 1261: uae_u8 *dataptr = line_data[lineno]; ! 1262: int len = dp_for_drawing->plflinelen >> 2; ! 1263: ! 1264: if (len <= 0) ! 1265: return; ! 1266: ! 1267: if (bpldelay1 == bpldelay2) { ! 1268: switch (bplplanecnt) { ! 1269: case 1: set_hires_h_0_0 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1270: case 2: set_hires_h_1_0 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1271: case 3: set_hires_h_2_0 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1272: case 4: set_hires_h_3_0 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1273: case 5: set_hires_h_4_0 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1274: case 6: set_hires_h_5_0 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1275: case 7: set_hires_h_6_0 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1276: case 8: set_hires_h_7_0 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1277: } ! 1278: } else { ! 1279: switch (bplplanecnt) { ! 1280: case 1: case 2: set_hires_h_0_1 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1281: case 3: case 4: set_hires_h_1_1 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1282: case 5: case 6: set_hires_h_2_1 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1283: case 7: case 8: set_hires_h_3_1 ((uae_u32 *)(pixdata.apixels + xpos1), dataptr, len); break; ! 1284: } ! 1285: ! 1286: xpos2 = xpos + 16 + bpldelay2; ! 1287: switch (bplplanecnt) { ! 1288: case 2: case 3: set_hires_h_0_2 ((uae_u32 *)(pixdata.apixels + xpos2), dataptr, len); break; ! 1289: case 4: case 5: set_hires_h_1_2 ((uae_u32 *)(pixdata.apixels + xpos2), dataptr, len); break; ! 1290: case 6: case 7: set_hires_h_2_2 ((uae_u32 *)(pixdata.apixels + xpos2), dataptr, len); break; ! 1291: case 8: set_hires_h_3_2 ((uae_u32 *)(pixdata.apixels + xpos2), dataptr, len); break; ! 1292: } ! 1293: } ! 1294: } ! 1295: } ! 1296: ! 1297: #define pfield_doline_h pfield_doline_unaligned_h ! 1298: #define pfield_doline_l pfield_doline_unaligned_l ! 1299: ! 1300: #else /* not UNALIGNED_PROFITABLE */ ! 1301: ! 1302: ! 1303: static __inline__ void pfield_orword_hires_h(int data, unsigned char *dp, int bit) ! 1304: { ! 1305: uae_u32 *pixptr = (uae_u32 *)dp; ! 1306: ! 1307: *pixptr |= hirestab_h[data >> 8][0] << bit; ! 1308: *(pixptr+1) |= hirestab_h[data >> 8][1] << bit; ! 1309: *(pixptr+2) |= hirestab_h[data & 255][0] << bit; ! 1310: *(pixptr+3) |= hirestab_h[data & 255][1] << bit; ! 1311: } ! 1312: ! 1313: static __inline__ void pfield_orword_lores_h(int data, unsigned char *dp, int bit) ! 1314: { ! 1315: uae_u32 *pixptr = (uae_u32 *)dp; ! 1316: ! 1317: *pixptr |= lorestab_h[data >> 8][0] << bit; ! 1318: *(pixptr+1) |= lorestab_h[data >> 8][1] << bit; ! 1319: *(pixptr+2) |= lorestab_h[data >> 8][2] << bit; ! 1320: *(pixptr+3) |= lorestab_h[data >> 8][3] << bit; ! 1321: *(pixptr+4) |= lorestab_h[data & 255][0] << bit; ! 1322: *(pixptr+5) |= lorestab_h[data & 255][1] << bit; ! 1323: *(pixptr+6) |= lorestab_h[data & 255][2] << bit; ! 1324: *(pixptr+7) |= lorestab_h[data & 255][3] << bit; ! 1325: } ! 1326: ! 1327: static __inline__ void pfield_setword_hires_h(int data, unsigned char *dp, int bit) ! 1328: { ! 1329: uae_u32 *pixptr = (uae_u32 *)dp; ! 1330: ! 1331: *pixptr = hirestab_h[data >> 8][0] << bit; ! 1332: *(pixptr+1) = hirestab_h[data >> 8][1] << bit; ! 1333: *(pixptr+2) = hirestab_h[data & 255][0] << bit; ! 1334: *(pixptr+3) = hirestab_h[data & 255][1] << bit; ! 1335: } ! 1336: ! 1337: static __inline__ void pfield_setword_lores_h(int data, unsigned char *dp, int bit) ! 1338: { ! 1339: uae_u32 *pixptr = (uae_u32 *)dp; ! 1340: ! 1341: *pixptr = lorestab_h[data >> 8][0] << bit; ! 1342: *(pixptr+1) = lorestab_h[data >> 8][1] << bit; ! 1343: *(pixptr+2) = lorestab_h[data >> 8][2] << bit; ! 1344: *(pixptr+3) = lorestab_h[data >> 8][3] << bit; ! 1345: *(pixptr+4) = lorestab_h[data & 255][0] << bit; ! 1346: *(pixptr+5) = lorestab_h[data & 255][1] << bit; ! 1347: *(pixptr+6) = lorestab_h[data & 255][2] << bit; ! 1348: *(pixptr+7) = lorestab_h[data & 255][3] << bit; ! 1349: } ! 1350: ! 1351: static __inline__ void pfield_orword_hires_l(int data, unsigned char *dp, int bit) ! 1352: { ! 1353: uae_u32 *pixptr = (uae_u32 *)dp; ! 1354: ! 1355: *pixptr |= hirestab_l[data >> 8][0] << bit; ! 1356: *(pixptr+1) |= hirestab_l[data & 255][0] << bit; ! 1357: } ! 1358: ! 1359: static __inline__ void pfield_orword_lores_l(int data, unsigned char *dp, int bit) ! 1360: { ! 1361: uae_u32 *pixptr = (uae_u32 *)dp; ! 1362: ! 1363: *pixptr |= lorestab_l[data >> 8][0] << bit; ! 1364: *(pixptr+1) |= lorestab_l[data >> 8][1] << bit; ! 1365: *(pixptr+2) |= lorestab_l[data & 255][0] << bit; ! 1366: *(pixptr+3) |= lorestab_l[data & 255][1] << bit; ! 1367: } ! 1368: ! 1369: static __inline__ void pfield_setword_hires_l(int data, unsigned char *dp, int bit) ! 1370: { ! 1371: uae_u32 *pixptr = (uae_u32 *)dp; ! 1372: ! 1373: *pixptr = hirestab_l[data >> 8][0] << bit; ! 1374: *(pixptr+1) = hirestab_l[data & 255][0] << bit; ! 1375: } ! 1376: ! 1377: static __inline__ void pfield_setword_lores_l(int data, unsigned char *dp, int bit) ! 1378: { ! 1379: uae_u32 *pixptr = (uae_u32 *)dp; ! 1380: ! 1381: *pixptr = lorestab_l[data >> 8][0] << bit; ! 1382: *(pixptr+1) = lorestab_l[data >> 8][1] << bit; ! 1383: *(pixptr+2) = lorestab_l[data & 255][0] << bit; ! 1384: *(pixptr+3) = lorestab_l[data & 255][1] << bit; ! 1385: } ! 1386: ! 1387: #define DO_ONE_PLANE(POINTER, MULT, FUNC, DELAY, LL_SUB, P_ADD) { \ ! 1388: int i; \ ! 1389: unsigned int bpldat1; \ ! 1390: uae_u16 data; \ ! 1391: unsigned int bpldat2 = 0; \ ! 1392: uae_u8 *ptr = (POINTER); \ ! 1393: for (i = dp_for_drawing->plflinelen; i > 0; i -= LL_SUB) { \ ! 1394: bpldat1 = bpldat2; \ ! 1395: bpldat2 = do_get_mem_word ((uae_u16 *)ptr); \ ! 1396: ptr+=2; \ ! 1397: data = (bpldat1 << (16 - DELAY)) | (bpldat2 >> DELAY); \ ! 1398: FUNC(data, app, MULT); \ ! 1399: app += P_ADD; \ ! 1400: } \ ! 1401: data = bpldat2 << (16 - DELAY); \ ! 1402: FUNC(data, app, MULT); \ ! 1403: } ! 1404: ! 1405: #ifdef SMART_UPDATE ! 1406: #define DATA_POINTER(n) (dataptr + (n)*MAX_WORDS_PER_LINE*2) ! 1407: #else ! 1408: #define DATA_POINTER(n) (real_bplpt[n]) ! 1409: #endif ! 1410: ! 1411: static void pfield_doline_aligned_h (int lineno) ! 1412: { ! 1413: int xpos = dp_for_drawing->plfstrt * 4 - DISPLAY_LEFT_SHIFT * 2; ! 1414: ! 1415: if (bplhires) { ! 1416: if (bplplanecnt > 0) { ! 1417: int xpos1 = xpos + 16 + (bpldelay1 >= 8 ? 16 : 0); ! 1418: int xpos2 = xpos + 16 + (bpldelay2 >= 8 ? 16 : 0); ! 1419: int delay1 = 2*(bpldelay1 & 7); ! 1420: int delay2 = 2*(bpldelay2 & 7); ! 1421: unsigned char *app = pixdata.apixels + xpos1; ! 1422: uae_u8 *dataptr = line_data[lineno]; ! 1423: ! 1424: DO_ONE_PLANE(DATA_POINTER(0), 0, pfield_setword_hires_h, delay1, 4, 16); ! 1425: if (bplplanecnt > 2) { ! 1426: app = pixdata.apixels + xpos1; ! 1427: DO_ONE_PLANE(DATA_POINTER(2), 2, pfield_orword_hires_h, delay1, 4, 16); ! 1428: } ! 1429: #if AGA_CHIPSET == 1 ! 1430: if (bplplanecnt > 4) { ! 1431: app = pixdata.apixels + xpos1; ! 1432: DO_ONE_PLANE(DATA_POINTER(4), 4, pfield_orword_hires_h, delay1, 4, 16); ! 1433: } ! 1434: if (bplplanecnt > 6) { ! 1435: app = pixdata.apixels + xpos1; ! 1436: DO_ONE_PLANE(DATA_POINTER(6), 6, pfield_orword_hires_h, delay1, 4, 16); ! 1437: } ! 1438: #endif ! 1439: if (bplplanecnt > 1) { ! 1440: app = pixdata.apixels + xpos2; ! 1441: DO_ONE_PLANE(DATA_POINTER(1), 1, pfield_orword_hires_h, delay2, 4, 16); ! 1442: } ! 1443: if (bplplanecnt > 3) { ! 1444: app = pixdata.apixels + xpos2; ! 1445: DO_ONE_PLANE(DATA_POINTER(3), 3, pfield_orword_hires_h, delay2, 4, 16); ! 1446: } ! 1447: #if AGA_CHIPSET == 1 ! 1448: if (bplplanecnt > 5) { ! 1449: app = pixdata.apixels + xpos2; ! 1450: DO_ONE_PLANE(DATA_POINTER(5), 5, pfield_orword_hires_h, delay2, 4, 16); ! 1451: } ! 1452: if (bplplanecnt > 7) { ! 1453: app = pixdata.apixels + xpos2; ! 1454: DO_ONE_PLANE(DATA_POINTER(7), 7, pfield_orword_hires_h, delay2, 4, 16); ! 1455: } ! 1456: #endif ! 1457: } else { ! 1458: memset(pixdata.apixels, 0, sizeof(pixdata.apixels)); ! 1459: } ! 1460: } else { ! 1461: if (bplplanecnt > 0) { ! 1462: int x = xpos + 32; ! 1463: unsigned char *app = pixdata.apixels + x; ! 1464: uae_u8 *dataptr = line_data[lineno]; ! 1465: ! 1466: DO_ONE_PLANE(DATA_POINTER(0), 0, pfield_setword_lores_h, bpldelay1, 8, 32); ! 1467: if (bplplanecnt > 2) { ! 1468: app = pixdata.apixels + x; ! 1469: DO_ONE_PLANE(DATA_POINTER(2), 2, pfield_orword_lores_h, bpldelay1, 8, 32); ! 1470: } ! 1471: if (bplplanecnt > 4) { ! 1472: app = pixdata.apixels + x; ! 1473: DO_ONE_PLANE(DATA_POINTER(4), 4, pfield_orword_lores_h, bpldelay1, 8, 32); ! 1474: } ! 1475: #if AGA_CHIPSET == 1 ! 1476: if (bplplanecnt > 6) { ! 1477: app = pixdata.apixels + x; ! 1478: DO_ONE_PLANE(DATA_POINTER(6), 6, pfield_orword_lores_h, bpldelay1, 8, 32); ! 1479: } ! 1480: #endif ! 1481: if (bplplanecnt > 1) { ! 1482: app = pixdata.apixels + x; ! 1483: DO_ONE_PLANE(DATA_POINTER(1), 1, pfield_orword_lores_h, bpldelay2, 8, 32); ! 1484: } ! 1485: if (bplplanecnt > 3) { ! 1486: app = pixdata.apixels + x; ! 1487: DO_ONE_PLANE(DATA_POINTER(3), 3, pfield_orword_lores_h, bpldelay2, 8, 32); ! 1488: } ! 1489: if (bplplanecnt > 5) { ! 1490: app = pixdata.apixels + x; ! 1491: DO_ONE_PLANE(DATA_POINTER(5), 5, pfield_orword_lores_h, bpldelay2, 8, 32); ! 1492: } ! 1493: #if AGA_CHIPSET == 1 ! 1494: if (bplplanecnt > 7) { ! 1495: app = pixdata.apixels + x; ! 1496: DO_ONE_PLANE(DATA_POINTER(7), 7, pfield_orword_lores_h, bpldelay2, 8, 32); ! 1497: } ! 1498: #endif ! 1499: } else { ! 1500: memset(pixdata.apixels, 0, sizeof(pixdata.apixels)); ! 1501: } ! 1502: } ! 1503: } ! 1504: ! 1505: static void pfield_doline_aligned_l (int lineno) ! 1506: { ! 1507: int xpos = dp_for_drawing->plfstrt * 2 - DISPLAY_LEFT_SHIFT; ! 1508: ! 1509: if (bplhires) { ! 1510: if (bplplanecnt > 0) { ! 1511: int xpos1 = xpos + 8 + (bpldelay1 >= 8 ? 8 : 0); ! 1512: int xpos2 = xpos + 8 + (bpldelay2 >= 8 ? 8 : 0); ! 1513: int delay1 = (bpldelay1 & 7) * 2; ! 1514: int delay2 = (bpldelay2 & 7) * 2; ! 1515: unsigned char *app = pixdata.apixels + xpos1; ! 1516: uae_u8 *dataptr = line_data[lineno]; ! 1517: ! 1518: DO_ONE_PLANE(DATA_POINTER(0), 0, pfield_setword_hires_l, delay1, 4, 8); ! 1519: if (bplplanecnt > 2) { ! 1520: app = pixdata.apixels + xpos1; ! 1521: DO_ONE_PLANE(DATA_POINTER(2), 2, pfield_orword_hires_l, delay1, 4, 8); ! 1522: } ! 1523: #if AGA_CHIPSET == 1 ! 1524: if (bplplanecnt > 4) { ! 1525: app = pixdata.apixels + xpos1; ! 1526: DO_ONE_PLANE(DATA_POINTER(4), 4, pfield_orword_hires_l, delay1, 4, 8); ! 1527: } ! 1528: if (bplplanecnt > 6) { ! 1529: app = pixdata.apixels + xpos1; ! 1530: DO_ONE_PLANE(DATA_POINTER(6), 6, pfield_orword_hires_l, delay1, 4, 8); ! 1531: } ! 1532: #endif ! 1533: if (bplplanecnt > 1) { ! 1534: app = pixdata.apixels + xpos2; ! 1535: DO_ONE_PLANE(DATA_POINTER(1), 1, pfield_orword_hires_l, delay2, 4, 8); ! 1536: } ! 1537: if (bplplanecnt > 3) { ! 1538: app = pixdata.apixels + xpos2; ! 1539: DO_ONE_PLANE(DATA_POINTER(3), 3, pfield_orword_hires_l, delay2, 4, 8); ! 1540: } ! 1541: #if AGA_CHIPSET == 1 ! 1542: if (bplplanecnt > 5) { ! 1543: app = pixdata.apixels + xpos2; ! 1544: DO_ONE_PLANE(DATA_POINTER(5), 5, pfield_orword_hires_l, delay2, 4, 8); ! 1545: } ! 1546: if (bplplanecnt > 7) { ! 1547: app = pixdata.apixels + xpos2; ! 1548: DO_ONE_PLANE(DATA_POINTER(7), 7, pfield_orword_hires_l, delay2, 4, 8); ! 1549: } ! 1550: #endif ! 1551: } else { ! 1552: memset(pixdata.apixels, 0, sizeof(pixdata.apixels)); ! 1553: } ! 1554: } else { ! 1555: if (bplplanecnt > 0) { ! 1556: int x = xpos + 16; ! 1557: int delay1 = bpldelay1; ! 1558: int delay2 = bpldelay2; ! 1559: unsigned char *app = pixdata.apixels + x; ! 1560: uae_u8 *dataptr = line_data[lineno]; ! 1561: ! 1562: DO_ONE_PLANE(DATA_POINTER(0), 0, pfield_setword_lores_l, delay1, 8, 16); ! 1563: if (bplplanecnt > 2) { ! 1564: app = pixdata.apixels + x; ! 1565: DO_ONE_PLANE(DATA_POINTER(2), 2, pfield_orword_lores_l, delay1, 8, 16); ! 1566: } ! 1567: if (bplplanecnt > 4) { ! 1568: app = pixdata.apixels + x; ! 1569: DO_ONE_PLANE(DATA_POINTER(4), 4, pfield_orword_lores_l, delay1, 8, 16); ! 1570: } ! 1571: #if AGA_CHIPSET == 1 ! 1572: if (bplplanecnt > 6) { ! 1573: app = pixdata.apixels + x; ! 1574: DO_ONE_PLANE(DATA_POINTER(6), 6, pfield_orword_lores_l, delay1, 8, 16); ! 1575: } ! 1576: #endif ! 1577: if (bplplanecnt > 1) { ! 1578: app = pixdata.apixels + x; ! 1579: DO_ONE_PLANE(DATA_POINTER(1), 1, pfield_orword_lores_l, delay2, 8, 16); ! 1580: } ! 1581: if (bplplanecnt > 3) { ! 1582: app = pixdata.apixels + x; ! 1583: DO_ONE_PLANE(DATA_POINTER(3), 3, pfield_orword_lores_l, delay2, 8, 16); ! 1584: } ! 1585: if (bplplanecnt > 5) { ! 1586: app = pixdata.apixels + x; ! 1587: DO_ONE_PLANE(DATA_POINTER(5), 5, pfield_orword_lores_l, delay2, 8, 16); ! 1588: } ! 1589: #if AGA_CHIPSET == 1 ! 1590: if (bplplanecnt > 7) { ! 1591: app = pixdata.apixels + x; ! 1592: DO_ONE_PLANE(DATA_POINTER(7), 7, pfield_orword_lores_l, delay2, 8, 16); ! 1593: } ! 1594: #endif ! 1595: } else { ! 1596: memset(pixdata.apixels, 0, sizeof(pixdata.apixels)); ! 1597: } ! 1598: } ! 1599: } ! 1600: ! 1601: #define pfield_doline_h pfield_doline_aligned_h ! 1602: #define pfield_doline_l pfield_doline_aligned_l ! 1603: ! 1604: #endif /* UNALIGNED_PROFITABLE */ ! 1605: ! 1606: static void pfield_adjust_delay (void) ! 1607: { ! 1608: int ddf_left = dp_for_drawing->plfstrt; ! 1609: int ddf_right = dp_for_drawing->plfstrt + dp_for_drawing->plflinelen; ! 1610: int i; ! 1611: ! 1612: for (i = dip_for_drawing->last_delay_change-1; i >= dip_for_drawing->first_delay_change-1; i--) { ! 1613: int delayreg = i < dip_for_drawing->first_delay_change ? dp_for_drawing->bplcon1 : delay_changes[i].value; ! 1614: int delay1 = delayreg & 0xF; ! 1615: int delay2 = (delayreg >> 4) & 0xF; ! 1616: int startpos = i == dip_for_drawing->last_delay_change - 1 ? ddf_right + 8 : delay_changes[i+1].linepos; ! 1617: int stoppos = i < dip_for_drawing->first_delay_change ? ddf_left : delay_changes[i].linepos; ! 1618: int j; ! 1619: startpos = PIXEL_XPOS (startpos + (bplhires ? 4 : 8)); ! 1620: stoppos = PIXEL_XPOS (stoppos + (bplhires ? 4 : 8)); ! 1621: if (currprefs.gfx_lores == 0) ! 1622: delay1 <<= 1, delay2 <<= 1; ! 1623: else if (currprefs.gfx_lores == 2) ! 1624: startpos >>= 1, stoppos >>= 1; ! 1625: for (j = startpos-1; j >= stoppos; j--) { ! 1626: pixdata.apixels [j] = (pixdata.apixels[j-delay1] & 0x55) | (pixdata.apixels[j-delay2] & 0xAA); ! 1627: } ! 1628: } ! 1629: } ! 1630: ! 1631: void init_row_map (void) ! 1632: { ! 1633: int i; ! 1634: if (gfxvidinfo.height > 2048) { ! 1635: write_log ("Resolution too high, aborting\n"); ! 1636: abort (); ! 1637: } ! 1638: for (i = 0; i < gfxvidinfo.height + 1; i++) ! 1639: row_map[i] = gfxvidinfo.bufmem + gfxvidinfo.rowbytes * i; ! 1640: } ! 1641: ! 1642: static void init_aspect_maps (void) ! 1643: { ! 1644: int i, maxl; ! 1645: double native_lines_per_amiga_line; ! 1646: ! 1647: if (native2amiga_line_map) ! 1648: free (native2amiga_line_map); ! 1649: if (amiga2aspect_line_map) ! 1650: free (amiga2aspect_line_map); ! 1651: ! 1652: /* At least for this array the +1 is necessary. */ ! 1653: amiga2aspect_line_map = (int *)malloc (sizeof (int) * (maxvpos+1)*2 + 1); ! 1654: native2amiga_line_map = (int *)malloc (sizeof (int) * gfxvidinfo.height); ! 1655: ! 1656: if (currprefs.gfx_correct_aspect) ! 1657: native_lines_per_amiga_line = ((double)gfxvidinfo.height ! 1658: * (currprefs.gfx_lores ? 320 : 640) ! 1659: / (currprefs.gfx_linedbl ? 512 : 256) ! 1660: / gfxvidinfo.width); ! 1661: else ! 1662: native_lines_per_amiga_line = 1; ! 1663: ! 1664: maxl = (maxvpos+1) * (currprefs.gfx_linedbl ? 2 : 1); ! 1665: min_ypos_for_screen = minfirstline << (currprefs.gfx_linedbl ? 1 : 0); ! 1666: max_drawn_amiga_line = -1; ! 1667: for (i = 0; i < maxl; i++) { ! 1668: int v = (i - min_ypos_for_screen) * native_lines_per_amiga_line; ! 1669: if (v >= gfxvidinfo.height && max_drawn_amiga_line == -1) ! 1670: max_drawn_amiga_line = i - min_ypos_for_screen; ! 1671: if (i < min_ypos_for_screen || v >= gfxvidinfo.height) ! 1672: v = -1; ! 1673: amiga2aspect_line_map[i] = v; ! 1674: } ! 1675: if (currprefs.gfx_linedbl) ! 1676: max_drawn_amiga_line >>= 1; ! 1677: ! 1678: if (currprefs.gfx_ycenter && !(currprefs.gfx_correct_aspect)) { ! 1679: extra_y_adjust = (gfxvidinfo.height - (maxvpos << (currprefs.gfx_linedbl ? 1 : 0))) >> 1; ! 1680: if (extra_y_adjust < 0) ! 1681: extra_y_adjust = 0; ! 1682: } ! 1683: ! 1684: for (i = 0; i < gfxvidinfo.height; i++) ! 1685: native2amiga_line_map[i] = -1; ! 1686: ! 1687: if (native_lines_per_amiga_line < 1) { ! 1688: /* Must omit drawing some lines. */ ! 1689: for (i = maxl - 1; i > min_ypos_for_screen; i--) { ! 1690: if (amiga2aspect_line_map[i] == amiga2aspect_line_map[i-1]) { ! 1691: if (currprefs.gfx_linedbl && (i & 1) == 0 && amiga2aspect_line_map[i+1] != -1) { ! 1692: /* If only the first line of a line pair would be omitted, ! 1693: * omit the second one instead to avoid problems with line ! 1694: * doubling. */ ! 1695: amiga2aspect_line_map[i] = amiga2aspect_line_map[i+1]; ! 1696: amiga2aspect_line_map[i+1] = -1; ! 1697: } else ! 1698: amiga2aspect_line_map[i] = -1; ! 1699: } ! 1700: } ! 1701: } ! 1702: ! 1703: for (i = maxl-1; i >= min_ypos_for_screen; i--) { ! 1704: int j; ! 1705: if (amiga2aspect_line_map[i] == -1) ! 1706: continue; ! 1707: for (j = amiga2aspect_line_map[i]; j < gfxvidinfo.height && native2amiga_line_map[j] == -1; j++) ! 1708: native2amiga_line_map[j] = i >> (currprefs.gfx_linedbl ? 1 : 0); ! 1709: } ! 1710: } ! 1711: ! 1712: /* ! 1713: * A raster line has been built in the graphics buffer. Tell the graphics code ! 1714: * to do anything necessary to display it. ! 1715: */ ! 1716: static void do_flush_line_1 (int lineno) ! 1717: { ! 1718: if (lineno < first_drawn_line) ! 1719: first_drawn_line = lineno; ! 1720: if (lineno > last_drawn_line) ! 1721: last_drawn_line = lineno; ! 1722: ! 1723: if (gfxvidinfo.maxblocklines == 0) ! 1724: flush_line(lineno); ! 1725: else { ! 1726: if ((last_block_line+1) != lineno) { ! 1727: if (first_block_line != -2) ! 1728: flush_block (first_block_line, last_block_line); ! 1729: first_block_line = lineno; ! 1730: } ! 1731: last_block_line = lineno; ! 1732: if (last_block_line - first_block_line >= gfxvidinfo.maxblocklines) { ! 1733: flush_block (first_block_line, last_block_line); ! 1734: first_block_line = last_block_line = -2; ! 1735: } ! 1736: } ! 1737: } ! 1738: ! 1739: static __inline__ void do_flush_line (int lineno) ! 1740: { ! 1741: /* We don't want to call X libraries from the second thread right now. */ ! 1742: #ifndef SUPPORT_PENGUINS ! 1743: do_flush_line_1 (lineno); ! 1744: #else ! 1745: line_drawn[lineno] = 1; ! 1746: #endif ! 1747: } ! 1748: ! 1749: /* ! 1750: * One drawing frame has been finished. Tell the graphics code about it. ! 1751: * Note that the actual flush_screen() call is a no-op for all reasonable ! 1752: * systems. ! 1753: */ ! 1754: ! 1755: static __inline__ void do_flush_screen (int start, int stop) ! 1756: { ! 1757: #ifdef SUPPORT_PENGUINS ! 1758: int i; ! 1759: for (i = 0; i < gfxvidinfo.height; i++) { ! 1760: if (line_drawn[i]) ! 1761: do_flush_line_1 (i); ! 1762: } ! 1763: #endif ! 1764: if (gfxvidinfo.maxblocklines != 0 && first_block_line != -2) { ! 1765: flush_block (first_block_line, last_block_line); ! 1766: } ! 1767: if (start <= stop) ! 1768: flush_screen (start, stop); ! 1769: } ! 1770: ! 1771: static int drawing_color_matches; ! 1772: static enum { color_match_acolors, color_match_full } color_match_type; ! 1773: ! 1774: static void adjust_drawing_colors (int ctable, int bplham) ! 1775: { ! 1776: if (drawing_color_matches != ctable) { ! 1777: if (bplham) { ! 1778: memcpy (&colors_for_drawing, curr_color_tables + ctable, ! 1779: sizeof colors_for_drawing); ! 1780: color_match_type = color_match_full; ! 1781: } else { ! 1782: memcpy (colors_for_drawing.acolors, curr_color_tables[ctable].acolors, ! 1783: sizeof colors_for_drawing.acolors); ! 1784: color_match_type = color_match_acolors; ! 1785: } ! 1786: drawing_color_matches = ctable; ! 1787: } else if (bplham && color_match_type != color_match_full) { ! 1788: memcpy (colors_for_drawing.color_regs, curr_color_tables[ctable].color_regs, ! 1789: sizeof colors_for_drawing.color_regs); ! 1790: color_match_type = color_match_full; ! 1791: } ! 1792: } ! 1793: ! 1794: static __inline__ void adjust_color0_for_color_change (void) ! 1795: { ! 1796: drawing_color_matches = -1; ! 1797: if (dp_for_drawing->color0 != 0xFFFFFFFFul) { ! 1798: colors_for_drawing.color_regs[0] = dp_for_drawing->color0; ! 1799: colors_for_drawing.acolors[0] = xcolors[dp_for_drawing->color0]; ! 1800: } ! 1801: } ! 1802: ! 1803: /* Fetched data spends 9 lores pixels somewhere in the chips before it appears ! 1804: * on-screen. We don't emulate this. Instead, we cheat with the copper to ! 1805: * compensate (much easier that way). */ ! 1806: #define COPPER_MAGIC_FUDGE -9 ! 1807: ! 1808: static __inline__ void do_color_changes (line_draw_func worker) ! 1809: { ! 1810: int lastpos = 0, nextpos, i; ! 1811: struct color_change *cc = curr_color_changes + dip_for_drawing->first_color_change; ! 1812: ! 1813: for (i = dip_for_drawing->first_color_change; i <= dip_for_drawing->last_color_change; i++, cc++) { ! 1814: if (i == dip_for_drawing->last_color_change) ! 1815: nextpos = max_diwlastword; ! 1816: else ! 1817: nextpos = PIXEL_XPOS (cc->linepos) + (COPPER_MAGIC_FUDGE << lores_shift); ! 1818: worker (lastpos, nextpos); ! 1819: if (i != dip_for_drawing->last_color_change) { ! 1820: colors_for_drawing.color_regs[cc->regno] = cc->value; ! 1821: colors_for_drawing.acolors[cc->regno] = xcolors[cc->value]; ! 1822: } ! 1823: if (nextpos > lastpos) { ! 1824: lastpos = nextpos; ! 1825: if (lastpos >= linetoscr_right_x) ! 1826: break; ! 1827: } ! 1828: } ! 1829: } ! 1830: ! 1831: /* We only save hardware registers during the hardware frame. Now, when ! 1832: * drawing the frame, we expand the data into a slightly more useful ! 1833: * form. */ ! 1834: static void pfield_expand_dp_bplcon (void) ! 1835: { ! 1836: bplhires = (dp_for_drawing->bplcon0 & 0x8000) == 0x8000; ! 1837: bplplanecnt = (dp_for_drawing->bplcon0 & 0x7000) >> 12; ! 1838: bplham = (dp_for_drawing->bplcon0 & 0x800) == 0x800; ! 1839: #if AGA_CHIPSET == 1 /* The KILLEHB bit exists in ECS, but is apparently meant for Genlock ! 1840: * stuff, and it's set by some demos (e.g. Andromeda Seven Seas) */ ! 1841: bplehb = ((dp_for_drawing->bplcon0 & 0xFCC0) == 0x6000 && !(dp_for_drawing->bplcon2 & 0x200)); ! 1842: #else ! 1843: bplehb = (dp_for_drawing->bplcon0 & 0xFC00) == 0x6000; ! 1844: #endif ! 1845: bpldelay1 = dp_for_drawing->bplcon1 & 0xF; ! 1846: bpldelay2 = (dp_for_drawing->bplcon1 >> 4) & 0xF; ! 1847: plfpri[1] = 1 << 2*(dp_for_drawing->bplcon2 & 7); ! 1848: plfpri[2] = 1 << 2*((dp_for_drawing->bplcon2 >> 3) & 7); ! 1849: bpldualpf = (dp_for_drawing->bplcon0 & 0x400) == 0x400; ! 1850: bpldualpfpri = (dp_for_drawing->bplcon2 & 0x40) == 0x40; ! 1851: } ! 1852: ! 1853: enum double_how { ! 1854: dh_buf, ! 1855: dh_line, ! 1856: dh_emerg ! 1857: }; ! 1858: ! 1859: static __inline__ void pfield_draw_line (int lineno, int gfx_ypos, int follow_ypos) ! 1860: { ! 1861: int border = 0; ! 1862: int do_double = 0; ! 1863: enum double_how dh; ! 1864: ! 1865: dp_for_drawing = 0; ! 1866: dip_for_drawing = 0; ! 1867: switch (linestate[lineno]) { ! 1868: case LINE_AS_PREVIOUS: ! 1869: case LINE_REMEMBERED_AS_PREVIOUS: ! 1870: { ! 1871: static int warned = 0; ! 1872: if (!warned) ! 1873: write_log ("Shouldn't get here... this is a bug.\n"), warned++; ! 1874: } ! 1875: line_decisions[lineno].which = -2; ! 1876: return; ! 1877: ! 1878: case LINE_BORDER_PREV: ! 1879: border = 1; ! 1880: dp_for_drawing = line_decisions + lineno - 1; ! 1881: dip_for_drawing = curr_drawinfo + lineno - 1; ! 1882: break; ! 1883: ! 1884: case LINE_BORDER_NEXT: ! 1885: border = 1; ! 1886: dp_for_drawing = line_decisions + lineno + 1; ! 1887: dip_for_drawing = curr_drawinfo + lineno + 1; ! 1888: break; ! 1889: ! 1890: case LINE_DONE_AS_PREVIOUS: ! 1891: line_decisions[lineno].which = -2; ! 1892: /* fall through */ ! 1893: case LINE_DONE: ! 1894: return; ! 1895: ! 1896: case LINE_DECIDED_DOUBLE: ! 1897: line_decisions[lineno+1].which = -2; ! 1898: if (follow_ypos != -1) { ! 1899: do_double = 1; ! 1900: linetoscr_double_offset = gfxvidinfo.rowbytes * (follow_ypos - gfx_ypos); ! 1901: } ! 1902: ! 1903: /* fall through */ ! 1904: default: ! 1905: dip_for_drawing = curr_drawinfo + lineno; ! 1906: dp_for_drawing = line_decisions + lineno; ! 1907: if (dp_for_drawing->which != 1) ! 1908: border = 1; ! 1909: break; ! 1910: } ! 1911: ! 1912: if (!line_changed[lineno] && !frame_redraw_necessary) { ! 1913: /* The case where we can skip redrawing this line. If this line ! 1914: * is supposed to be doubled, and the next line is remembered as ! 1915: * having been doubled, then the next line is done as well. */ ! 1916: if (do_double) { ! 1917: /* @@@ This is buggy. FIXME */ ! 1918: if (linestate[lineno+1] != LINE_REMEMBERED_AS_PREVIOUS) { ! 1919: if (gfxvidinfo.linemem == 0) ! 1920: memcpy (row_map[follow_ypos], row_map[gfx_ypos], gfxvidinfo.rowbytes); ! 1921: line_decisions[lineno + 1].which = -2; ! 1922: do_flush_line (follow_ypos); ! 1923: } ! 1924: linestate[lineno + 1] = LINE_DONE_AS_PREVIOUS; ! 1925: } ! 1926: linestate[lineno] = LINE_DONE; ! 1927: return; ! 1928: } ! 1929: ! 1930: dh = dh_line; ! 1931: xlinebuffer = gfxvidinfo.linemem; ! 1932: if (xlinebuffer == 0 && do_double && dip_for_drawing->nr_color_changes != 0) ! 1933: xlinebuffer = gfxvidinfo.emergmem, dh = dh_emerg; ! 1934: if (xlinebuffer == 0) ! 1935: xlinebuffer = row_map[gfx_ypos], dh = dh_buf; ! 1936: xlinebuffer -= linetoscr_x_adjust_bytes; ! 1937: aga_lbufptr = aga_linebuf; ! 1938: ! 1939: if (!border) { ! 1940: pfield_expand_dp_bplcon (); ! 1941: ! 1942: #ifdef LORES_HACK ! 1943: if (gfxvidinfo.can_double && !bplhires && !currprefs.gfx_lores ! 1944: && dip_for_drawing->nr_color_changes == 0 && !bplham) ! 1945: currprefs.gfx_lores = 2; ! 1946: #endif ! 1947: pfield_init_linetoscr (); ! 1948: if (dip_for_drawing->first_delay_change != dip_for_drawing->last_delay_change) { ! 1949: bpldelay1 = bpldelay2 = 0; ! 1950: if (currprefs.gfx_lores) ! 1951: pfield_doline_l (lineno); ! 1952: else ! 1953: pfield_doline_h (lineno); ! 1954: pfield_adjust_delay (); ! 1955: } else { ! 1956: if (currprefs.gfx_lores) ! 1957: pfield_doline_l (lineno); ! 1958: else ! 1959: pfield_doline_h (lineno); ! 1960: } ! 1961: ! 1962: /* Check color0 adjust only if we have color changes - shouldn't happen ! 1963: * otherwise. */ ! 1964: adjust_drawing_colors (dp_for_drawing->ctable, bplham || bplehb); ! 1965: ! 1966: /* The problem is that we must call decode_ham6() BEFORE we do the ! 1967: * sprites. */ ! 1968: if (bplham) { ! 1969: init_ham_decoding(linetoscr_x_adjust); ! 1970: if (dip_for_drawing->nr_color_changes == 0) { ! 1971: /* The easy case: need to do HAM decoding only once for the ! 1972: * full line. */ ! 1973: decode_ham6 (linetoscr_x_adjust, linetoscr_right_x); ! 1974: } else /* Argh. */ { ! 1975: adjust_color0_for_color_change (); ! 1976: do_color_changes (decode_ham6); ! 1977: adjust_drawing_colors (dp_for_drawing->ctable, bplham || bplehb); ! 1978: } ! 1979: } ! 1980: ! 1981: if (dip_for_drawing->nr_sprites != 0) ! 1982: walk_sprites (curr_sprite_positions + dip_for_drawing->first_sprite_draw, dip_for_drawing->nr_sprites); ! 1983: ! 1984: if (dip_for_drawing->nr_color_changes == 0) { ! 1985: pfield_do_linetoscr_full (dh == dh_buf ? do_double : 0); ! 1986: do_flush_line (gfx_ypos); ! 1987: linestate[lineno] = LINE_DONE; ! 1988: #if 0 ! 1989: if (dh == dh_emerg) ! 1990: abort (); ! 1991: #endif ! 1992: if (do_double) { ! 1993: /* If dh == dh_line, do_flush_line will re-use the rendered line ! 1994: * from linemem. If dh == dh_buf, the line will have been doubled ! 1995: * by pfield_do_linetoscr_full. */ ! 1996: linestate[lineno + 1] = LINE_DONE_AS_PREVIOUS; ! 1997: do_flush_line (follow_ypos); ! 1998: } ! 1999: } else { ! 2000: adjust_color0_for_color_change (); ! 2001: do_color_changes (pfield_do_linetoscr); ! 2002: ! 2003: if (dh == dh_emerg) ! 2004: memcpy (row_map[gfx_ypos], xlinebuffer + linetoscr_x_adjust_bytes, gfxvidinfo.rowbytes); ! 2005: ! 2006: linestate[lineno] = LINE_DONE; ! 2007: do_flush_line (gfx_ypos); ! 2008: if (do_double) { ! 2009: if (dh == dh_emerg) ! 2010: memcpy (row_map[follow_ypos], xlinebuffer + linetoscr_x_adjust_bytes, gfxvidinfo.rowbytes); ! 2011: else if (dh == dh_buf) ! 2012: memcpy (row_map[follow_ypos], row_map[gfx_ypos], gfxvidinfo.rowbytes); ! 2013: linestate[lineno + 1] = LINE_DONE_AS_PREVIOUS; ! 2014: line_decisions[lineno + 1].which = -2; ! 2015: do_flush_line (follow_ypos); ! 2016: } ! 2017: } ! 2018: #ifdef LORES_HACK ! 2019: if (currprefs.gfx_lores == 2) ! 2020: currprefs.gfx_lores = 0; ! 2021: #endif ! 2022: } else { /* Border. */ ! 2023: adjust_drawing_colors (dp_for_drawing->ctable, 0); ! 2024: ! 2025: /* Check color0 adjust only if we have color changes - shouldn't happen ! 2026: * otherwise. */ ! 2027: ! 2028: if (dip_for_drawing->nr_color_changes == 0) { ! 2029: fill_line (); ! 2030: do_flush_line (gfx_ypos); ! 2031: linestate[lineno] = LINE_DONE; ! 2032: #if 0 ! 2033: if (dh == dh_emerg) ! 2034: abort (); ! 2035: #endif ! 2036: if (do_double) { ! 2037: if (dh == dh_buf) { ! 2038: xlinebuffer = row_map[follow_ypos] - linetoscr_x_adjust_bytes; ! 2039: fill_line (); ! 2040: } ! 2041: /* If dh == dh_line, do_flush_line will re-use the rendered line ! 2042: * from linemem. */ ! 2043: do_flush_line (follow_ypos); ! 2044: linestate[lineno+1] = LINE_DONE_AS_PREVIOUS; ! 2045: } ! 2046: return; ! 2047: } ! 2048: ! 2049: adjust_color0_for_color_change (); ! 2050: do_color_changes (pfield_do_fill_line); ! 2051: ! 2052: if (dh == dh_emerg) ! 2053: memcpy (row_map[gfx_ypos], xlinebuffer + linetoscr_x_adjust_bytes, gfxvidinfo.rowbytes); ! 2054: ! 2055: do_flush_line (gfx_ypos); ! 2056: linestate[lineno] = LINE_DONE; ! 2057: if (do_double) { ! 2058: if (dh == dh_emerg) ! 2059: memcpy (row_map[follow_ypos], xlinebuffer + linetoscr_x_adjust_bytes, gfxvidinfo.rowbytes); ! 2060: else if (dh == dh_buf) ! 2061: memcpy (row_map[follow_ypos], row_map[gfx_ypos], gfxvidinfo.rowbytes); ! 2062: /* If dh == dh_line, do_flush_line will re-use the rendered line ! 2063: * from linemem. */ ! 2064: do_flush_line (follow_ypos); ! 2065: linestate[lineno + 1] = LINE_DONE_AS_PREVIOUS; ! 2066: line_decisions[lineno + 1].which = -2; ! 2067: } ! 2068: } ! 2069: } ! 2070: ! 2071: #ifdef SUPPORT_PENGUINS ! 2072: static smp_comm_pipe drawing_pipe; ! 2073: static uae_sem_t drawing_lock; ! 2074: ! 2075: static void *drawing_penguin (void *cruxmedo) ! 2076: { ! 2077: int l; ! 2078: fprintf (stderr, "Hello, world!\n"); ! 2079: ! 2080: for (;;) { ! 2081: /* Start of a frame. */ ! 2082: int k; ! 2083: new_frame: ! 2084: k = read_comm_pipe_int_blocking (&drawing_pipe); ! 2085: ! 2086: switch (k) { ! 2087: case -2: ! 2088: /* Hoopy */ ! 2089: break; ! 2090: ! 2091: default: ! 2092: write_log ("Penguin got out of sync.\n"); ! 2093: /* what can we do? Try to reduce the damage */ ! 2094: for (;;) { ! 2095: k = read_comm_pipe_int_blocking (&drawing_pipe); ! 2096: if (k == -3) ! 2097: break; ! 2098: if (k == -1) { ! 2099: uae_sem_post (&drawing_lock); ! 2100: goto new_frame; ! 2101: } ! 2102: } ! 2103: case -3: ! 2104: UAE_PENGUIN_EXIT; ! 2105: /* Can't happen */ ! 2106: return 0; ! 2107: } ! 2108: ! 2109: for (;;) { ! 2110: int i, where; ! 2111: int l = read_comm_pipe_int_blocking (&drawing_pipe); ! 2112: switch (l) { ! 2113: case -1: ! 2114: /* End-of-frame synchronization. */ ! 2115: uae_sem_post (&drawing_lock); ! 2116: goto new_frame; ! 2117: case -2: ! 2118: /* customreset called a bit too often. That's harmless. */ ! 2119: continue; ! 2120: case -3: ! 2121: write_log ("Penguin got out of sync.\n"); ! 2122: UAE_PENGUIN_EXIT; ! 2123: return 0; ! 2124: } ! 2125: ! 2126: /* l is the line that has been finished for drawing. */ ! 2127: i = l - thisframe_y_adjust_real; ! 2128: if (i < 0 || i >= max_ypos_thisframe) ! 2129: continue; ! 2130: ! 2131: if (linestate[l] == LINE_UNDECIDED) { ! 2132: fprintf (stderr, "Line scheduled for drawing, but undecided %d!?\n", l); ! 2133: continue; ! 2134: } ! 2135: if (inhibit_frame != 0) ! 2136: continue; ! 2137: where = amiga2aspect_line_map[i+min_ypos_for_screen]; ! 2138: if (where >= gfxvidinfo.height || where == -1) ! 2139: continue; ! 2140: ! 2141: pfield_draw_line (l, where, amiga2aspect_line_map[i+min_ypos_for_screen+1]); ! 2142: } ! 2143: } ! 2144: } ! 2145: ! 2146: static penguin_id our_penguin; ! 2147: ! 2148: static void kill_drawing_penguin (void) ! 2149: { ! 2150: /* ??? does libpthread do that for us? */ ! 2151: } ! 2152: ! 2153: #endif ! 2154: ! 2155: static int penguins_enabled_thisframe; ! 2156: ! 2157: static void center_image (void) ! 2158: { ! 2159: prev_x_adjust = linetoscr_x_adjust; ! 2160: prev_y_adjust = thisframe_y_adjust; ! 2161: ! 2162: if (currprefs.gfx_xcenter) { ! 2163: if (max_diwstop - min_diwstart < gfxvidinfo.width && currprefs.gfx_xcenter == 2) ! 2164: /* Try to center. */ ! 2165: linetoscr_x_adjust = ((max_diwstop - min_diwstart - gfxvidinfo.width) / 2 + min_diwstart) & ~1; ! 2166: else ! 2167: linetoscr_x_adjust = max_diwstop - gfxvidinfo.width; ! 2168: ! 2169: /* Would the old value be good enough? If so, leave it as it is if we want to ! 2170: * be clever. */ ! 2171: if (currprefs.gfx_xcenter == 2) { ! 2172: if (linetoscr_x_adjust < prev_x_adjust && prev_x_adjust < min_diwstart) ! 2173: linetoscr_x_adjust = prev_x_adjust; ! 2174: } ! 2175: } else ! 2176: linetoscr_x_adjust = max_diwlastword - gfxvidinfo.width; ! 2177: if (linetoscr_x_adjust < 0) ! 2178: linetoscr_x_adjust = 0; ! 2179: ! 2180: linetoscr_x_adjust_bytes = linetoscr_x_adjust * gfxvidinfo.pixbytes; ! 2181: ! 2182: linetoscr_right_x = linetoscr_x_adjust + gfxvidinfo.width; ! 2183: if (linetoscr_right_x > max_diwlastword) ! 2184: linetoscr_right_x = max_diwlastword; ! 2185: ! 2186: thisframe_y_adjust = minfirstline; ! 2187: if (currprefs.gfx_ycenter && thisframe_first_drawn_line != -1) { ! 2188: if (thisframe_last_drawn_line - thisframe_first_drawn_line < max_drawn_amiga_line && currprefs.gfx_ycenter == 2) ! 2189: thisframe_y_adjust = (thisframe_last_drawn_line - thisframe_first_drawn_line - max_drawn_amiga_line) / 2 + thisframe_first_drawn_line; ! 2190: else ! 2191: thisframe_y_adjust = thisframe_first_drawn_line; ! 2192: /* Would the old value be good enough? If so, leave it as it is if we want to ! 2193: * be clever. */ ! 2194: if (currprefs.gfx_ycenter == 2) { ! 2195: if (thisframe_y_adjust != prev_y_adjust ! 2196: && prev_y_adjust <= thisframe_first_drawn_line ! 2197: && prev_y_adjust + max_drawn_amiga_line > thisframe_last_drawn_line) ! 2198: thisframe_y_adjust = prev_y_adjust; ! 2199: } ! 2200: /* Make sure the value makes sense */ ! 2201: if (thisframe_y_adjust + max_drawn_amiga_line > maxvpos) ! 2202: thisframe_y_adjust = maxvpos - max_drawn_amiga_line; ! 2203: if (thisframe_y_adjust < minfirstline) ! 2204: thisframe_y_adjust = minfirstline; ! 2205: } ! 2206: thisframe_y_adjust_real = thisframe_y_adjust << (currprefs.gfx_linedbl ? 1 : 0); ! 2207: max_ypos_thisframe = (maxvpos - thisframe_y_adjust) << (currprefs.gfx_linedbl ? 1 : 0); ! 2208: ! 2209: /* @@@ interlace_seen used to be (bplcon0 & 4), but this is probably ! 2210: * better. */ ! 2211: if (prev_x_adjust != linetoscr_x_adjust || prev_y_adjust != thisframe_y_adjust) ! 2212: frame_redraw_necessary |= interlace_seen && currprefs.gfx_linedbl ? 2 : 1; ! 2213: ! 2214: max_diwstop = 0; ! 2215: min_diwstart = 10000; ! 2216: } ! 2217: ! 2218: static void init_drawing_frame (void) ! 2219: { ! 2220: int i, maxline; ! 2221: ! 2222: init_hardware_for_drawing_frame (); ! 2223: ! 2224: if (max_diwstop == 0) ! 2225: max_diwstop = diwlastword; ! 2226: if (min_diwstart > max_diwstop) ! 2227: min_diwstart = 0; ! 2228: ! 2229: if (thisframe_first_drawn_line == -1) ! 2230: thisframe_first_drawn_line = minfirstline; ! 2231: if (thisframe_first_drawn_line > thisframe_last_drawn_line) ! 2232: thisframe_last_drawn_line = thisframe_first_drawn_line; ! 2233: ! 2234: maxline = currprefs.gfx_linedbl ? (maxvpos+1) * 2 + 1 : (maxvpos+1) + 1; ! 2235: #ifdef SMART_UPDATE ! 2236: for (i = 0; i < maxline; i++) ! 2237: linestate[i] = linestate[i] == LINE_DONE_AS_PREVIOUS ? LINE_REMEMBERED_AS_PREVIOUS : LINE_UNDECIDED; ! 2238: #else ! 2239: memset (linestate, LINE_UNDECIDED, maxline); ! 2240: #endif ! 2241: last_drawn_line = 0; ! 2242: first_drawn_line = 32767; ! 2243: ! 2244: first_block_line = last_block_line = -2; ! 2245: if (currprefs.test_drawing_speed) ! 2246: frame_redraw_necessary = 1; ! 2247: else if (frame_redraw_necessary) ! 2248: frame_redraw_necessary--; ! 2249: ! 2250: center_image (); ! 2251: ! 2252: thisframe_first_drawn_line = -1; ! 2253: thisframe_last_drawn_line = -1; ! 2254: #ifdef SUPPORT_PENGUINS ! 2255: penguins_enabled_thisframe = 1; ! 2256: /* Tell the other thread that it can now expect data from us. */ ! 2257: write_comm_pipe_int (&drawing_pipe, -2, 1); ! 2258: memset (line_drawn, 0, sizeof line_drawn); ! 2259: #endif ! 2260: ! 2261: drawing_color_matches = -1; ! 2262: } ! 2263: ! 2264: void finish_drawing_frame (void) ! 2265: { ! 2266: int i; ! 2267: ! 2268: #ifdef SUPPORT_PENGUINS ! 2269: /* Synchronize with other thread, then see whether there's something left for ! 2270: * us to draw. @@@ This is probably a big waste of cycles if the two threads ! 2271: * run at very different speeds - this one could draw stuff as well. */ ! 2272: write_comm_pipe_int (&drawing_pipe, -1, 1); ! 2273: uae_sem_wait (&drawing_lock); ! 2274: #else ! 2275: ! 2276: #ifndef SMART_UPDATE ! 2277: /* @@@ This isn't exactly right yet. FIXME */ ! 2278: if (!interlace_seen) { ! 2279: do_flush_screen (first_drawn_line, last_drawn_line); ! 2280: return; ! 2281: } ! 2282: #endif ! 2283: if (! lockscr ()) { ! 2284: notice_screen_contents_lost (); ! 2285: return; ! 2286: } ! 2287: for (i = 0; i < max_ypos_thisframe; i++) { ! 2288: int where; ! 2289: int line = i + thisframe_y_adjust_real; ! 2290: ! 2291: if (linestate[line] == LINE_UNDECIDED) ! 2292: break; ! 2293: ! 2294: where = amiga2aspect_line_map[i+min_ypos_for_screen]; ! 2295: if (where >= gfxvidinfo.height) ! 2296: break; ! 2297: if (where == -1) ! 2298: continue; ! 2299: ! 2300: pfield_draw_line (line, where, amiga2aspect_line_map[i+min_ypos_for_screen+1]); ! 2301: } ! 2302: unlockscr (); ! 2303: #endif ! 2304: do_flush_screen (first_drawn_line, last_drawn_line); ! 2305: } ! 2306: ! 2307: void hardware_line_completed (int lineno) ! 2308: { ! 2309: #ifdef SUPPORT_PENGUINS ! 2310: if (framecnt == 0 && penguins_enabled_thisframe) { ! 2311: write_comm_pipe_int (&drawing_pipe, lineno, 0); ! 2312: } ! 2313: #endif ! 2314: #ifndef SMART_UPDATE ! 2315: { ! 2316: int i, where; ! 2317: /* l is the line that has been finished for drawing. */ ! 2318: i = lineno - thisframe_y_adjust_real; ! 2319: if (i >= 0 && i < max_ypos_thisframe) { ! 2320: where = amiga2aspect_line_map[i+min_ypos_for_screen]; ! 2321: if (where < gfxvidinfo.height && where != -1) ! 2322: pfield_draw_line (lineno, where, amiga2aspect_line_map[i+min_ypos_for_screen+1]); ! 2323: } ! 2324: } ! 2325: #endif ! 2326: } ! 2327: ! 2328: static __inline__ void check_picasso (void) ! 2329: { ! 2330: #ifdef PICASSO96 ! 2331: if (picasso_on && picasso_redraw_necessary) ! 2332: picasso_refresh (); ! 2333: picasso_redraw_necessary = 0; ! 2334: ! 2335: if (picasso_requested_on == picasso_on) ! 2336: return; ! 2337: ! 2338: picasso_on = picasso_requested_on; ! 2339: ! 2340: if (!picasso_on) ! 2341: clear_inhibit_frame (2); ! 2342: else ! 2343: set_inhibit_frame (2); ! 2344: ! 2345: gfx_set_picasso_state (picasso_on); ! 2346: picasso_enablescreen (picasso_requested_on); ! 2347: ! 2348: notice_screen_contents_lost (); ! 2349: notice_new_xcolors (); ! 2350: #endif ! 2351: } ! 2352: ! 2353: void vsync_handle_redraw (int long_frame, int lof_changed) ! 2354: { ! 2355: last_redraw_point++; ! 2356: if (lof_changed || ! interlace_seen || last_redraw_point >= 2 || long_frame) { ! 2357: last_redraw_point = 0; ! 2358: interlace_seen = 0; ! 2359: ! 2360: if (framecnt == 0) ! 2361: finish_drawing_frame (); ! 2362: ! 2363: /* At this point, we have finished both the hardware and the ! 2364: * drawing frame. Essentially, we are outside of all loops and ! 2365: * can do some things which would cause confusion if they were ! 2366: * done at other times. ! 2367: */ ! 2368: ! 2369: if (quit_program < 0) { ! 2370: quit_program = -quit_program; ! 2371: set_inhibit_frame (1); ! 2372: regs.spcflags |= SPCFLAG_BRK; ! 2373: filesys_prepare_reset (); ! 2374: #ifdef SUPPORT_PENGUINS ! 2375: if (quit_program == 1) ! 2376: /* Stop eating herring */ ! 2377: write_comm_pipe_int (&drawing_pipe, -3, 1); ! 2378: #endif ! 2379: return; ! 2380: } ! 2381: ! 2382: count_frame (); ! 2383: check_picasso (); ! 2384: ! 2385: check_prefs_changed_custom (); ! 2386: check_prefs_changed_cpu (); ! 2387: if (check_prefs_changed_gfx ()) { ! 2388: init_row_map (); ! 2389: init_aspect_maps (); ! 2390: notice_screen_contents_lost (); ! 2391: notice_new_xcolors (); ! 2392: } ! 2393: ! 2394: if (inhibit_frame != 0) ! 2395: framecnt = 1; ! 2396: ! 2397: if (framecnt == 0) ! 2398: init_drawing_frame (); ! 2399: } ! 2400: } ! 2401: ! 2402: void hsync_record_line_state (int lineno, enum nln_how how) ! 2403: { ! 2404: if (framecnt != 0) ! 2405: return; ! 2406: switch (how) { ! 2407: case nln_normal: ! 2408: linestate[lineno] = LINE_DECIDED; ! 2409: break; ! 2410: case nln_doubled: ! 2411: linestate[lineno] = LINE_DECIDED_DOUBLE; ! 2412: if (linestate[lineno+1] != LINE_REMEMBERED_AS_PREVIOUS) ! 2413: linestate[lineno+1] = LINE_AS_PREVIOUS; ! 2414: break; ! 2415: case nln_lower: ! 2416: if (linestate[lineno-1] == LINE_UNDECIDED) ! 2417: linestate[lineno-1] = LINE_BORDER_NEXT; ! 2418: linestate[lineno] = LINE_DECIDED; ! 2419: break; ! 2420: case nln_upper: ! 2421: linestate[lineno] = LINE_DECIDED; ! 2422: if (linestate[lineno+1] == LINE_UNDECIDED ! 2423: || linestate[lineno+1] == LINE_REMEMBERED_AS_PREVIOUS ! 2424: || linestate[lineno+1] == LINE_AS_PREVIOUS) ! 2425: linestate[lineno+1] = LINE_BORDER_PREV; ! 2426: break; ! 2427: } ! 2428: } ! 2429: ! 2430: void notice_interlace_seen (void) ! 2431: { ! 2432: interlace_seen = 1; ! 2433: penguins_enabled_thisframe = 0; ! 2434: } ! 2435: ! 2436: void reset_drawing (void) ! 2437: { ! 2438: int i; ! 2439: ! 2440: inhibit_frame = 0; ! 2441: uae_sem_init (&gui_sem, 0, 1); ! 2442: ! 2443: #ifdef PICASSO96 ! 2444: InitPicasso96 (); ! 2445: picasso_on = 0; ! 2446: picasso_requested_on = 0; ! 2447: gfx_set_picasso_state (0); ! 2448: #endif ! 2449: max_diwstop = 0; ! 2450: ! 2451: lores_factor = currprefs.gfx_lores ? 1 : 2; ! 2452: lores_shift = currprefs.gfx_lores ? 0 : 1; ! 2453: sprite_width = currprefs.gfx_lores ? 16 : 32; ! 2454: ! 2455: /*memset(blitcount, 0, sizeof(blitcount)); blitter debug */ ! 2456: for (i = 0; i < sizeof linestate / sizeof *linestate; i++) ! 2457: linestate[i] = LINE_UNDECIDED; ! 2458: ! 2459: xlinebuffer = gfxvidinfo.bufmem; ! 2460: ! 2461: init_aspect_maps (); ! 2462: ! 2463: if (line_drawn == 0) ! 2464: line_drawn = (char *)malloc (gfxvidinfo.height); ! 2465: ! 2466: init_row_map(); ! 2467: ! 2468: last_redraw_point = 0; ! 2469: ! 2470: init_drawing_frame (); ! 2471: } ! 2472: ! 2473: void drawing_init () ! 2474: { ! 2475: native2amiga_line_map = 0; ! 2476: amiga2aspect_line_map = 0; ! 2477: line_drawn = 0; ! 2478: ! 2479: gen_pfield_tables(); ! 2480: ! 2481: #ifdef SUPPORT_PENGUINS ! 2482: init_comm_pipe (&drawing_pipe, 800, 5); ! 2483: uae_sem_init (&drawing_lock, 0, 0); ! 2484: start_penguin (drawing_penguin, 0, &our_penguin); ! 2485: /*atexit(kill_drawing_penguin);*/ ! 2486: #endif ! 2487: } ! 2488:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.