static void draw_everything(Mame.osd_bitmap bitmap, bool fullDraw) { _BytePtr _base = new _BytePtr(bitmap.line[starty], startx); uint[] sprite_buffer = new uint[(32 * 8) + 256]; _BytePtr overall_priority_base = new _BytePtr(overall_priority, (turbo_fbpla & 8) << 6); _BytePtr sprite_priority_base = new _BytePtr(sprite_priority, (turbo_fbpla & 7) << 7); _BytePtr road_gfxdata_base = new _BytePtr(road_gfxdata, (turbo_opc << 5) & 0x7e0); UShortSubArray road_palette_base = new UShortSubArray(road_expanded_palette, (turbo_fbcol & 1) << 4); int dx = deltax, dy = deltay, rowsize = (bitmap.line[1].offset - bitmap.line[0].offset) * 8 / bitmap.depth; UShortSubArray colortable; int x, y, i; /* expand the appropriate delta */ if ((Mame.Machine.orientation & Mame.ORIENTATION_SWAP_XY) != 0) dx *= rowsize; else dy *= rowsize; /* determine the color offset */ colortable = new UShortSubArray(Mame.Machine.pens, (turbo_fbcol & 6) << 6); /* loop over rows */ for (y = 4; y < (28 * 8) - 4; y++, _base.offset += dy) { int sel, coch, babit, slipar_acciar, area, area1, area2, area3, area4, area5, road = 0; uint[] sprite_data = sprite_buffer; _BytePtr dest = new _BytePtr(_base); /* compute the Y sum between opa and the current scanline (p. 141) */ int va = (y + turbo_opa) & 0xff; /* the upper bit of OPC inverts the road */ if ((turbo_opc & 0x80) == 0) va ^= 0xff; /* clear the sprite buffer and draw the road sprites */ Array.Clear(sprite_buffer, 0, 32 * 8); draw_road_sprites(sprite_buffer, y); /* loop over 8-pixel chunks */ dest.offset += dx * 8; int sdi = 8; for (x = 8; x < (32 * 8); x += 8) { int area5_buffer = road_gfxdata_base[0x4000 + (x >> 3)]; byte back_data = Generic.videoram[(y / 8) * 32 + (x / 8) - 33]; ushort backbits_buffer = back_expanded_data[(back_data << 3) | (y & 7)]; /* loop over columns */ for (i = 0; i < 8; i++, dest.offset += dx) { uint sprite = sprite_data[sdi++]; /* compute the X sum between opb and the current column; only the carry matters (p. 141) */ int carry = (x + i + turbo_opb) >> 8; /* the carry selects which inputs to use (p. 141) */ if (carry != 0) { sel = turbo_ipb; coch = turbo_ipc >> 4; } else { sel = turbo_ipa; coch = turbo_ipc & 15; } /* at this point we also compute area5 (p. 141) */ area5 = (area5_buffer >> 3) & 0x10; area5_buffer <<= 1; /* now look up the rest of the road bits (p. 142) */ area1 = road_gfxdata[0x0000 | ((sel & 15) << 8) | va]; area1 = ((area1 + x + i) >> 8) & 0x01; area2 = road_gfxdata[0x1000 | ((sel & 15) << 8) | va]; area2 = ((area2 + x + i) >> 7) & 0x02; area3 = road_gfxdata[0x2000 | ((sel >> 4) << 8) | va]; area3 = ((area3 + x + i) >> 6) & 0x04; area4 = road_gfxdata[0x3000 | ((sel >> 4) << 8) | va]; area4 = ((area4 + x + i) >> 5) & 0x08; /* compute the final area value and look it up in IC18/PR1115 (p. 144) */ area = area5 | area4 | area3 | area2 | area1; babit = road_enable_collide[area] & 0x07; /* note: SLIPAR is 0 on the road surface only */ /* ACCIAR is 0 on the road surface and the striped edges only */ slipar_acciar = road_enable_collide[area] & 0x30; if (road == 0 && (slipar_acciar & 0x20) != 0) { road = 1; draw_offroad_sprites(sprite_buffer, x + i + 2, y); } /* perform collision detection here */ turbo_collision |= collision_map[(uint)((sprite >> 24) & 7) | (uint)(slipar_acciar >> 1)]; /* we only need to continue if we're actually drawing */ if (fullDraw) { int bacol, red, grn, blu, priority, backbits, mx; /* also use the coch value to look up color info in IC13/PR1114 and IC21/PR1117 (p. 144) */ bacol = road_palette_base[coch & 15]; /* at this point, do the character lookup */ backbits = backbits_buffer & 3; backbits_buffer >>= 2; backbits = back_palette[backbits | (back_data & 0xfc)]; /* look up the sprite priority in IC11/PR1122 */ priority = sprite_priority_base[sprite >> 25]; /* use that to look up the overall priority in IC12/PR1123 */ mx = overall_priority_base[(uint)((priority & 7) | ((sprite >> 21) & 8) | ((back_data >> 3) & 0x10) | ((backbits << 2) & 0x20) | (babit << 6))]; /* the input colors consist of a mix of sprite, road and 1's & 0's */ red = (int)(0x040000 | ((bacol & 0x001f) << 13) | ((backbits & 1) << 12) | ((sprite << 4) & 0x0ff0)); grn = (int)(0x080000 | ((bacol & 0x03e0) << 9) | ((backbits & 2) << 12) | ((sprite >> 3) & 0x1fe0)); blu = (int)(0x100000 | ((bacol & 0x7c00) << 5) | ((backbits & 4) << 12) | ((sprite >> 10) & 0x3fc0)); /* we then go through a muxer; normally these values are inverted, but */ /* we've already taken care of that when we generated the palette */ red = (red >> mx) & 0x10; grn = (grn >> mx) & 0x20; blu = (blu >> mx) & 0x40; dest[0] = (byte)colortable[mx | red | grn | blu]; } } } } }
/* This is a bit slow, but it works. I'll speed it up later */ static void nemesis_drawgfx_zoomup(Mame.osd_bitmap dest, Mame.GfxElement gfx, uint code, uint color, int flipx, int flipy, int sx, int sy, Mame.rectangle clip, int transparency, int transparent_color, int scale) { int ex, ey, y, start, dy; _BytePtr sd; _BytePtr bm; int col; Mame.rectangle myclip = new Mame.rectangle(); ; int dda_x = 0; int dda_y = 0; int ex_count; int ey_count; int real_x; int ysize; int xsize; UShortSubArray paldata; /* ASG 980209 */ int transmask; if (gfx == null) return; code %= gfx.total_elements; color %= (uint)gfx.total_colors; transmask = 1 << transparent_color; if ((gfx.pen_usage[code] & ~transmask) == 0) /* character is totally transparent, no need to draw */ return; if ((Mame.Machine.orientation & Mame.ORIENTATION_SWAP_XY) != 0) { int temp; temp = sx; sx = sy; sy = temp; temp = flipx; flipx = flipy; flipy = temp; if (clip != null) { /* clip and myclip might be the same, so we need a temporary storage */ temp = clip.min_x; myclip.min_x = clip.min_y; myclip.min_y = temp; temp = clip.max_x; myclip.max_x = clip.max_y; myclip.max_y = temp; clip = myclip; } } if ((Mame.Machine.orientation & Mame.ORIENTATION_FLIP_X) != 0) { sx = dest.width - gfx.width - sx; if (clip != null) { int temp; /* clip and myclip might be the same, so we need a temporary storage */ temp = clip.min_x; myclip.min_x = dest.width - 1 - clip.max_x; myclip.max_x = dest.width - 1 - temp; myclip.min_y = clip.min_y; myclip.max_y = clip.max_y; clip = myclip; } } if ((Mame.Machine.orientation & Mame.ORIENTATION_FLIP_Y) != 0) { sy = dest.height - gfx.height - sy; if (clip != null) { int temp; myclip.min_x = clip.min_x; myclip.max_x = clip.max_x; /* clip and myclip might be the same, so we need a temporary storage */ temp = clip.min_y; myclip.min_y = dest.height - 1 - clip.max_y; myclip.max_y = dest.height - 1 - temp; clip = myclip; } } /* check bounds */ xsize = gfx.width; ysize = gfx.height; /* Clipping currently done in code loop */ ex = sx + xsize - 1; ey = sy + ysize - 1; /* if (ex >= dest.width) ex = dest.width-1; if (clip && ex > clip.max_x) ex = clip.max_x; if (sx > ex) return; if (ey >= dest.height) tey = dest.height-1; if (clip && ey > clip.max_y) ey = clip.max_y; if (sy > ey) return; */ /* start = code * gfx.height; */ if (flipy != 0) /* Y flip */ { start = (int)(code * gfx.height + gfx.height - 1); dy = -1; } else /* normal */ { start = (int)(code * gfx.height); dy = 1; } paldata = new UShortSubArray(gfx.colortable, (int)(gfx.color_granularity * color)); if (flipx != 0) /* X flip */ { if ((Mame.Machine.orientation & Mame.ORIENTATION_FLIP_Y) != 0) y = sy + ysize - 1; else y = sy; dda_y = 0x80; ey_count = sy; do { if (y >= clip.min_y && y <= clip.max_y) { if ((Mame.Machine.orientation & Mame.ORIENTATION_FLIP_X) != 0) { bm = new _BytePtr(dest.line[y], sx + xsize - 1); real_x = sx + xsize - 1; } else { bm = new _BytePtr(dest.line[y], sx); real_x = sx; } sd = new _BytePtr(gfx.gfxdata, start * gfx.line_modulo + xsize - 1); dda_x = 0x80; ex_count = sx; col = sd[0]; do { if ((real_x <= clip.max_x) && (real_x >= clip.min_x)) if (col != transparent_color) bm[0] = (byte)paldata[col]; if ((Mame.Machine.orientation & Mame.ORIENTATION_FLIP_X) != 0) { bm.offset--; real_x--; } else { bm.offset++; real_x++; } dda_x -= scale; if (dda_x <= 0) { dda_x += 0x80; sd.offset--; ex_count++; col = sd[0]; } } while (ex_count <= ex); } if ((Mame.Machine.orientation & Mame.ORIENTATION_FLIP_Y) != 0) y--; else y++; dda_y -= scale; if (dda_y <= 0) { dda_y += 0x80; start += dy; ey_count++; } } while (ey_count <= ey); } else /* normal */ { if ((Mame.Machine.orientation & Mame.ORIENTATION_FLIP_Y) != 0) y = sy + ysize - 1; else y = sy; dda_y = 0x80; ey_count = sy; do { if (y >= clip.min_y && y <= clip.max_y) { if ((Mame.Machine.orientation & Mame.ORIENTATION_FLIP_X) != 0) { bm = new _BytePtr(dest.line[y], sx + xsize - 1); real_x = sx + xsize - 1; } else { bm = new _BytePtr(dest.line[y], sx); real_x = sx; } sd = new _BytePtr(gfx.gfxdata, start * gfx.line_modulo); dda_x = 0x80; ex_count = sx; col = sd[0]; do { if ((real_x <= clip.max_x) && (real_x >= clip.min_x)) if (col != transparent_color) bm[0] = (byte)paldata[col]; if ((Mame.Machine.orientation & Mame.ORIENTATION_FLIP_X) != 0) { bm.offset--; real_x--; } else { bm.offset++; real_x++; } dda_x -= scale; if (dda_x <= 0) { dda_x += 0x80; sd.offset++; ex_count++; col = sd[0]; } } while (ex_count <= ex); } if ((Mame.Machine.orientation & Mame.ORIENTATION_FLIP_Y) != 0) y--; else y++; dda_y -= scale; if (dda_y <= 0) { dda_y += 0x80; start += dy; ey_count++; } } while (ey_count <= ey); } }