static void draw_sprites(running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect, int bank ) { contra_state *state = machine.driver_data<contra_state>(); device_t *k007121 = bank ? state->m_k007121_2 : state->m_k007121_1; address_space &space = machine.driver_data()->generic_space(); int base_color = (k007121_ctrlram_r(k007121, space, 6) & 0x30) * 2; const UINT8 *source; if (bank == 0) source = state->m_buffered_spriteram; else source = state->m_buffered_spriteram_2; k007121_sprites_draw(k007121, bitmap, cliprect, machine.gfx[bank], machine.colortable, source, base_color, 40, 0, (UINT32)-1); }
void deco_bac06_device::custom_tilemap_draw(running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect, tilemap_t *tilemap_ptr, const UINT16 *rowscroll_ptr, const UINT16 *colscroll_ptr, const UINT16 *control0, const UINT16 *control1, int flags, UINT16 penmask, UINT16 pencondition, UINT16 colprimask, UINT16 colpricondition ) { const bitmap_ind16 &src_bitmap = tilemap_ptr->pixmap(); const bitmap_ind8 &flags_bitmap = tilemap_ptr->flagsmap(); int x, y, p, colpri; int column_offset=0, src_x=0, src_y=0; UINT32 scrollx = 0; UINT32 scrolly = 0; if (control1) { scrollx = control1[0]; scrolly = control1[1]; } int width_mask; int height_mask; int row_scroll_enabled = 0; int col_scroll_enabled = 0; if (control0) { row_scroll_enabled = (rowscroll_ptr && (control0[0]&0x4)); col_scroll_enabled = (colscroll_ptr && (control0[0]&0x8)); } width_mask = src_bitmap.width() - 1; height_mask = src_bitmap.height() - 1; /* Column scroll & row scroll may per applied per pixel, there are shift registers for each which control the granularity of the row/col offset (down to per line level for row, and per 8 lines for column). Nb: The row & col selectors are _not_ affected by the shape of the playfield (ie, 256*1024, 512*512 or 1024*256). So even if the tilemap width is only 256, 'src_x' should not wrap at 256 in the code below (to do so would mean the top half of row RAM would never be accessed which is incorrect). Nb2: Real hardware exhibits a strange bug with column scroll on 'mode 2' (256*1024) - the first column has a strange additional offset, but curiously the first 'wrap' (at scroll offset 256) does not have this offset, it is displayed as expected. The bug is confimed to only affect this mode, the other two modes work as expected. This bug is not emulated, as it doesn't affect any games. */ if (machine.driver_data()->flip_screen()) src_y = (src_bitmap.height() - 256) - scrolly; else src_y = scrolly; for (y=0; y<=cliprect.max_y; y++) { if (row_scroll_enabled) src_x=scrollx + rowscroll_ptr[(src_y >> (control1[3]&0xf))&(0x1ff>>(control1[3]&0xf))]; else src_x=scrollx; if (machine.driver_data()->flip_screen()) src_x=(src_bitmap.width() - 256) - src_x; for (x=0; x<=cliprect.max_x; x++) { if (col_scroll_enabled) column_offset=colscroll_ptr[((src_x >> 3) >> (control1[2]&0xf))&(0x3f>>(control1[2]&0xf))]; p = src_bitmap.pix16((src_y + column_offset)&height_mask, src_x&width_mask); colpri = flags_bitmap.pix8((src_y + column_offset)&height_mask, src_x&width_mask)&0xf; src_x++; if ((flags&TILEMAP_DRAW_OPAQUE) || (p&m_bppmask)) { if ((p&penmask)==pencondition) if((colpri&colprimask)==colpricondition) bitmap.pix16(y, x) = p+(colpri&m_gfxcolmask)*m_bppmult; } } src_y++; }
static void parentj_draw_sprites( running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect, int priority ) { /* Y chain size is 16/32?/64/64? pixels. X chain size is always 64 pixels. */ taitoo_state *state = machine.driver_data<taitoo_state>(); address_space &space = machine.driver_data()->generic_space(); static const int size[] = { 1, 2, 4, 4 }; int x0, y0, x, y, dx, dy, ex, ey, zx, zy; int ysize; int j, k; int offs; /* sprite RAM offset */ int tile_offs; /* sprite chain offset */ int zoomx, zoomy; /* zoom value */ for (offs = 0x03f8 / 2; offs >= 0; offs -= 0x008 / 2) { if (offs < 0x01b0 && priority == 0) continue; if (offs >= 0x01b0 && priority == 1) continue; x0 = tc0080vco_sprram_r(state->m_tc0080vco, space, offs + 1, 0xffff) & 0x3ff; y0 = tc0080vco_sprram_r(state->m_tc0080vco, space, offs + 0, 0xffff) & 0x3ff; zoomx = (tc0080vco_sprram_r(state->m_tc0080vco, space, offs + 2, 0xffff) & 0x7f00) >> 8; zoomy = (tc0080vco_sprram_r(state->m_tc0080vco, space, offs + 2, 0xffff) & 0x007f); tile_offs = (tc0080vco_sprram_r(state->m_tc0080vco, space, offs + 3, 0xffff) & 0x1fff) << 2; ysize = size[(tc0080vco_sprram_r(state->m_tc0080vco, space, offs, 0xffff) & 0x0c00) >> 10]; if (tile_offs) { /* Convert zoomy value to real value as zoomx */ zoomy = zoomy_conv_table[zoomy]; if (zoomx < 63) { dx = 8 + (zoomx + 2) / 8; ex = (zoomx + 2) % 8; zx = ((dx << 1) + ex) << 11; } else { dx = 16 + (zoomx - 63) / 4; ex = (zoomx - 63) % 4; zx = (dx + ex) << 12; } if (zoomy < 63) { dy = 8 + (zoomy + 2) / 8; ey = (zoomy + 2) % 8; zy = ((dy << 1) + ey) << 11; } else { dy = 16 + (zoomy - 63) / 4; ey = (zoomy - 63) % 4; zy = (dy + ey) << 12; } if (x0 >= 0x200) x0 -= 0x400; if (y0 >= 0x200) y0 -= 0x400; if (tc0080vco_flipscreen_r(state->m_tc0080vco)) { x0 = 497 - x0; y0 = 498 - y0; dx = -dx; dy = -dy; } else { x0 += 1; y0 += 2; } y = y0; for (j = 0; j < ysize; j ++) { x = x0; for (k = 0; k < 4; k ++) { if (tile_offs >= 0x1000) { int tile, color, flipx, flipy; tile = tc0080vco_cram_0_r(state->m_tc0080vco, space, tile_offs, 0xffff) & 0x7fff; color = tc0080vco_cram_1_r(state->m_tc0080vco, space, tile_offs, 0xffff) & 0x001f; flipx = tc0080vco_cram_1_r(state->m_tc0080vco, space, tile_offs, 0xffff) & 0x0040; flipy = tc0080vco_cram_1_r(state->m_tc0080vco, space, tile_offs, 0xffff) & 0x0080; if (tc0080vco_flipscreen_r(state->m_tc0080vco)) { flipx ^= 0x0040; flipy ^= 0x0080; } drawgfxzoom_transpen( bitmap, cliprect, machine.gfx[0], tile, color, flipx, flipy, x, y, zx, zy, 0 ); } tile_offs ++; x += dx; } y += dy; } } } }
void deco_karnovsprites_device::draw_sprites( running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect, UINT16* spriteram, int size, int priority ) { int offs; for (offs = 0; offs < size; offs += 4) { int x, y, sprite, sprite2, colour, fx, fy, extra; y = spriteram[offs]; if (!(y & 0x8000)) continue; y = y & 0x1ff; sprite = spriteram[offs + 3]; colour = sprite >> 12; if (priority == 1 && (colour & 8)) continue; if (priority == 2 && !(colour & 8)) continue; sprite = sprite & 0xfff; x = spriteram[offs + 2] & 0x1ff; fx = spriteram[offs + 1]; /* the 8-bit implementation had this. illustrated by enemy projectile explosions in Shackled being left on screen. */ if ((fx & 0x1) == 0) continue; extra = (fx & 0x10) ? 1 : 0; fy = fx & 0x2; fx = fx & 0x4; if (extra) { y = y + 16; sprite &= 0xffe; // taken from 8-bit version } /* Convert the co-ords..*/ x = (x + 16) % 0x200; y = (y + 16) % 0x200; x = 256 - x; y = 256 - y; if (machine.driver_data()->flip_screen()) { y = 240 - y; x = 240 - x; if (fx) fx = 0; else fx = 1; if (fy) fy = 0; else fy = 1; if (extra) y = y - 16; } /* Y Flip determines order of multi-sprite */ if (extra && fy) { sprite2 = sprite; sprite++; } else sprite2 = sprite + 1; drawgfx_transpen(bitmap,cliprect,machine.gfx[m_gfxregion], sprite, colour,fx,fy,x,y,0); /* 1 more sprite drawn underneath */ if (extra) drawgfx_transpen(bitmap,cliprect,machine.gfx[m_gfxregion], sprite2, colour,fx,fy,x,y+16,0); } }
/* Mix the 2 sprite planes with the already rendered tilemaps.. note, if we implement tilemap blending etc. too we'll probably have to mix those in here as well.. this is just a reimplementation of the old priority system used before conversion but to work with the bitmaps. It could probably be simplified / improved greatly, along with the long-standing bugs fixed, with manual mixing you have full control. apparently priority is based on a PROM, that should be used if possible. */ static void mix_boogwing(running_machine &machine, bitmap_rgb32 &bitmap, const rectangle &cliprect) { boogwing_state *state = machine.driver_data<boogwing_state>(); int y, x; const pen_t *paldata = machine.pens; bitmap_ind16 *sprite_bitmap1, *sprite_bitmap2; bitmap_ind8* priority_bitmap; address_space &space = machine.driver_data()->generic_space(); UINT16 priority = decocomn_priority_r(state->m_decocomn, space, 0, 0xffff); sprite_bitmap1 = &machine.device<decospr_device>("spritegen1")->get_sprite_temp_bitmap(); sprite_bitmap2 = &machine.device<decospr_device>("spritegen2")->get_sprite_temp_bitmap(); priority_bitmap = &machine.priority_bitmap; UINT32* dstline; UINT16 *srcline1, *srcline2; UINT8 *srcpriline; for (y=cliprect.min_y;y<=cliprect.max_y;y++) { srcline1=&sprite_bitmap1->pix16(y,0); srcline2=&sprite_bitmap2->pix16(y,0); srcpriline=&priority_bitmap->pix8(y,0); dstline=&bitmap.pix32(y,0); for (x=cliprect.min_x;x<=cliprect.max_x;x++) { UINT16 pix1 = srcline1[x]; UINT16 pix2 = srcline2[x]; /* Here we have pix1 - raw pixel / colour / priority data from first 1sdt chip pix2 - raw pixel / colour / priority data from first 2nd chip */ int pri1, pri2; int spri1, spri2, alpha2; alpha2 = 0xff; // pix1 sprite vs pix2 sprite if (pix1 & 0x400) // todo - check only in pri mode 2?? spri1 = 8; else spri1 = 32; // pix1 sprite vs playfield switch (priority) { case 0x01: { if ((pix1 & 0x600)) pri1 = 16; else pri1 = 64; } break; default: { if ((pix1 & 0x600) == 0x600) pri1 = 4; else if ((pix1 & 0x600) == 0x400) pri1 = 16; else pri1 = 64; } break; } // pix2 sprite vs pix1 sprite if ((pix2 & 0x600) == 0x600) spri2 = 4; else if ((pix2 & 0x600)) spri2 = 16; else spri2 = 64; // Transparency if (pix2 & 0x100) alpha2 = 0x80; // pix2 sprite vs playfield switch (priority) { case 0x02: { // Additional sprite alpha in this mode if (pix2 & 0x400) alpha2 = 0x80; // Sprite vs playfield if ((pix2 & 0x600) == 0x600) pri2 = 4; else if ((pix2 & 0x600) == 0x400) pri2 = 16; else pri2 = 64; } break; default: { if ((pix2 & 0x400) == 0x400) pri2 = 16; else pri2 = 64; } break; } UINT8 bgpri = srcpriline[x]; /* once we get here we have pri1 - 4/16/64 (sprite chip 1 pixel priority relative to bg) pri2 - 4/16/64 (sprite chip 2 pixel priority relative to bg) spri1 - 8/32 (priority of sprite chip 1 relative to other sprite chip) spri2 - 4/16/64 (priority of sprite chip 2 relative to other sprite chip) alpha2 - 0x80/0xff alpha level of sprite chip 2 pixels (0x80 if enabled, 0xff if not) bgpri - 0 / 8 / 32 (from drawing tilemaps earlier, to compare above pri1/pri2 priorities against) pix1 - same as before (ready to extract just colour data from) pix2 - same as before ^^ */ int drawnpixe1 = 0; if (pix1 & 0xf) { if (pri1 > bgpri) { dstline[x] = paldata[(pix1&0x1ff)+0x500]; drawnpixe1 = 1; } } if (pix2 & 0xf) { if (pri2 > bgpri) { if ((!drawnpixe1) || (spri2 > spri1)) { if (alpha2==0xff) { dstline[x] = paldata[(pix2&0xff)+0x700]; } else { UINT32 base = dstline[x]; dstline[x] = alpha_blend_r32(base, paldata[(pix2&0xff)+0x700], alpha2); } } } } } } }