void k007121_device::sprites_draw( bitmap_ind16 &bitmap, const rectangle &cliprect, gfx_element *gfx, colortable_t *ctable, const UINT8 *source, int base_color, int global_x_offset, int bank_base, bitmap_ind8 &priority_bitmap, UINT32 pri_mask ) { // gfx_element *gfx = gfxs[chip]; int flipscreen = m_flipscreen; int i, num, inc, offs[5]; int is_flakatck = (ctable == NULL); if (is_flakatck) { num = 0x40; inc = -0x20; source += 0x3f * 0x20; offs[0] = 0x0e; offs[1] = 0x0f; offs[2] = 0x06; offs[3] = 0x04; offs[4] = 0x08; } else /* all others */ { /* TODO: sprite limit is supposed to be per-line! (check MT #00185) */ num = 0x40; //num = (k007121->ctrlram[0x03] & 0x40) ? 0x80 : 0x40; /* WRONG!!! (needed by combatsc) */ inc = 5; offs[0] = 0x00; offs[1] = 0x01; offs[2] = 0x02; offs[3] = 0x03; offs[4] = 0x04; /* when using priority buffer, draw front to back */ if (pri_mask != -1) { source += (num - 1)*inc; inc = -inc; } } for (i = 0; i < num; i++) { int number = source[offs[0]]; /* sprite number */ int sprite_bank = source[offs[1]] & 0x0f; /* sprite bank */ int sx = source[offs[3]]; /* vertical position */ int sy = source[offs[2]]; /* horizontal position */ int attr = source[offs[4]]; /* attributes */ int xflip = source[offs[4]] & 0x10; /* flip x */ int yflip = source[offs[4]] & 0x20; /* flip y */ int color = base_color + ((source[offs[1]] & 0xf0) >> 4); int width, height; int transparent_mask; static const int x_offset[4] = {0x0,0x1,0x4,0x5}; static const int y_offset[4] = {0x0,0x2,0x8,0xa}; int x,y, ex, ey, flipx, flipy, destx, desty; if (attr & 0x01) sx -= 256; if (sy >= 240) sy -= 256; number += ((sprite_bank & 0x3) << 8) + ((attr & 0xc0) << 4); number = number << 2; number += (sprite_bank >> 2) & 3; /* Flak Attack doesn't use a lookup PROM, it maps the color code directly */ /* to a palette entry */ if (is_flakatck) transparent_mask = 1 << 0; else transparent_mask = colortable_get_transpen_mask(ctable, gfx, color, 0); if (!is_flakatck || source[0x00]) /* Flak Attack needs this */ { number += bank_base; switch (attr & 0xe) { case 0x06: width = height = 1; break; case 0x04: width = 1; height = 2; number &= (~2); break; case 0x02: width = 2; height = 1; number &= (~1); break; case 0x00: width = height = 2; number &= (~3); break; case 0x08: width = height = 4; number &= (~3); break; default: width = 1; height = 1; // logerror("Unknown sprite size %02x\n", attr & 0xe); // popmessage("Unknown sprite size %02x\n", attr & 0xe); } for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { ex = xflip ? (width - 1 - x) : x; ey = yflip ? (height - 1 - y) : y; if (flipscreen) { flipx = !xflip; flipy = !yflip; destx = 248 - (sx + x * 8); desty = 248 - (sy + y * 8); } else { flipx = xflip; flipy = yflip; destx = global_x_offset + sx + x * 8; desty = sy + y * 8; } if (pri_mask != -1) pdrawgfx_transmask(bitmap,cliprect,gfx, number + x_offset[ex] + y_offset[ey], color, flipx,flipy, destx,desty, priority_bitmap,pri_mask, transparent_mask); else drawgfx_transmask(bitmap,cliprect,gfx, number + x_offset[ex] + y_offset[ey], color, flipx,flipy, destx,desty, transparent_mask); } } } source += inc; } }
static void draw_sprites( running_machine &machine, bitmap_t *bitmap, const rectangle *cliprect ) { docastle_state *state = machine.driver_data<docastle_state>(); int offs; bitmap_fill(machine.priority_bitmap, NULL, 1); for (offs = state->m_spriteram_size - 4; offs >= 0; offs -= 4) { int sx, sy, flipx, flipy, code, color; if (machine.gfx[1]->total_elements > 256) { /* spriteram indoor soccer appears to have a slightly different spriteram format to the other games, allowing a larger number of sprite tiles yyyy yyyy xxxx xxxx TX-T pppp tttt tttt y = ypos x = xpos X = x-flip T = extra tile number bits p = palette t = tile number */ code = state->m_spriteram[offs + 3]; color = state->m_spriteram[offs + 2] & 0x0f; sx = ((state->m_spriteram[offs + 1] + 8) & 0xff) - 8; sy = state->m_spriteram[offs]; flipx = state->m_spriteram[offs + 2] & 0x40; flipy = 0; if (state->m_spriteram[offs + 2] & 0x10) code += 0x100; if (state->m_spriteram[offs + 2] & 0x80) code += 0x200; } else { /* spriteram this is the standard spriteram layout, used by most games yyyy yyyy xxxx xxxx YX-p pppp tttt tttt y = ypos x = xpos X = x-flip Y = y-flip p = palette t = tile number */ code = state->m_spriteram[offs + 3]; color = state->m_spriteram[offs + 2] & 0x1f; sx = ((state->m_spriteram[offs + 1] + 8) & 0xff) - 8; sy = state->m_spriteram[offs]; flipx = state->m_spriteram[offs + 2] & 0x40; flipy = state->m_spriteram[offs + 2] & 0x80; } if (flip_screen_get(machine)) { sx = 240 - sx; sy = 240 - sy; flipx = !flipx; flipy = !flipy; } /* first draw the sprite, visible */ pdrawgfx_transmask(bitmap,cliprect,machine.gfx[1], code, color, flipx,flipy, sx,sy, machine.priority_bitmap, 0x00,0x80ff); /* then draw the mask, behind the background but obscuring following sprites */ pdrawgfx_transmask(bitmap,cliprect,machine.gfx[1], code, color, flipx,flipy, sx,sy, machine.priority_bitmap, 0x02,0x7fff); } }