/*************************************************************************** Desert Assault Video emulation - Bryan McPhail, mish@tendril.co.uk ****************************************************************************/ #include "emu.h" #include "video/deco16ic.h" #include "includes/dassault.h" #include "video/decocomn.h" /******************************************************************************/ static void draw_sprites( running_machine& machine, bitmap_t *bitmap, const rectangle *cliprect, int pf_priority ) { dassault_state *state = machine.driver_data(); UINT16 *buffered_spriteram = machine.generic.buffered_spriteram.u16; int x, y, sprite, colour, multi, fx, fy, inc, flash, mult; int offs, bank, gfxbank; const UINT16 *spritebase; /* Have to loop over the two sprite sources */ for (bank = 0; bank < 2; bank++) { for (offs = 0x800 - 4; offs >= 0; offs -= 4) { int alpha = 0xff, pmask = 0; /* Draw the main spritebank after the other one */ if (bank == 0) { spritebase = buffered_spriteram; gfxbank = 3; } else { spritebase = machine.generic.buffered_spriteram2.u16; gfxbank = 4; } sprite = spritebase[offs + 1] & 0x7fff; if (!sprite) continue; x = spritebase[offs + 2]; /* Alpha on chip 2 only */ if (bank == 1 && x & 0xc000) alpha = 0x80; y = spritebase[offs]; flash = y & 0x1000; if (flash && (machine.primary_screen->frame_number() & 1)) continue; colour = (x >> 9) & 0x1f; if (y & 0x8000) colour += 32; fx = y & 0x2000; fy = y & 0x4000; multi = (1 << ((y & 0x0600) >> 9)) - 1; /* 1x, 2x, 4x, 8x height */ x = x & 0x01ff; y = y & 0x01ff; if (x >= 320) x -= 512; if (y >= 256) y -= 512; x = 304 - x; y = 240 - y; if (x > 320) continue; /* Speedup */ sprite &= ~multi; if (fy) inc = -1; else { sprite += multi; inc = 1; } if (flip_screen_get(machine)) { y = 240 - y; x = 304 - x; if (fx) fx = 0; else fx = 1; if (fy) fy = 0; else fy = 1; mult = 16; } else mult = -16; /* Priority */ switch (pf_priority & 3) { case 0: if (bank == 0) { switch (spritebase[offs+2]&0xc000) { case 0xc000: pmask = 1; break; case 0x8000: pmask = 8; break; case 0x4000: pmask = 32; break; case 0x0000: pmask = 128; break; } } else { if (spritebase[offs + 2] & 0x8000) pmask = 64; /* Check */ else pmask = 64; } break; case 1: if (bank == 0) { switch (spritebase[offs + 2] & 0xc000) { case 0xc000: pmask = 1; break; case 0x8000: pmask = 8; break; case 0x4000: pmask = 32; break; case 0x0000: pmask = 128; break; } } else { if (spritebase[offs + 2] & 0x8000) pmask = 16; /* Check */ else pmask = 16; } break; case 2: /* Unused */ case 3: if (bank == 0) { switch (spritebase[offs + 2] & 0xc000) { case 0xc000: pmask = 1; break; case 0x8000: pmask = 8; break; case 0x4000: pmask = 32; break; case 0x0000: pmask = 128; break; } } else { if (spritebase[offs + 2] & 0x8000) pmask = 64; /* Check */ else pmask = 64; } break; } while (multi >= 0) { decocomn_pdrawgfx( state->m_decocomn, bitmap,cliprect,machine.gfx[gfxbank], sprite - multi * inc, colour, fx, fy, x, y + mult * multi, 0, pmask, 1 << bank, 1, alpha); multi--; } } } } /******************************************************************************/ SCREEN_UPDATE( dassault ) { dassault_state *state = screen->machine().driver_data(); UINT16 flip = deco16ic_pf_control_r(state->m_deco_tilegen1, 0, 0xffff); UINT16 priority = decocomn_priority_r(state->m_decocomn, 0, 0xffff); /* Update tilemaps */ flip_screen_set(screen->machine(), BIT(flip, 7)); deco16ic_pf_update(state->m_deco_tilegen1, 0, state->m_pf2_rowscroll); deco16ic_pf_update(state->m_deco_tilegen2, 0, state->m_pf4_rowscroll); /* Draw playfields/update priority bitmap */ decocomn_clear_sprite_priority_bitmap(state->m_decocomn); bitmap_fill(screen->machine().priority_bitmap, cliprect, 0); bitmap_fill(bitmap, cliprect, screen->machine().pens[3072]); deco16ic_tilemap_2_draw(state->m_deco_tilegen2, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0); /* The middle playfields can be swapped priority-wise */ if ((priority & 3) == 0) { deco16ic_tilemap_2_draw(state->m_deco_tilegen1, bitmap, cliprect, 0, 2); deco16ic_tilemap_1_draw(state->m_deco_tilegen2, bitmap, cliprect, 0, 16); } else if ((priority & 3) == 1) { deco16ic_tilemap_1_draw(state->m_deco_tilegen2, bitmap, cliprect, 0, 2); deco16ic_tilemap_2_draw(state->m_deco_tilegen1, bitmap, cliprect, 0, 64); } else if ((priority & 3) == 3) { deco16ic_tilemap_1_draw(state->m_deco_tilegen2, bitmap, cliprect, 0, 2); deco16ic_tilemap_2_draw(state->m_deco_tilegen1, bitmap, cliprect, 0, 16); } else { /* Unused */ } /* Draw sprites - two sprite generators, with selectable priority */ draw_sprites(screen->machine(), bitmap, cliprect, priority); deco16ic_tilemap_1_draw(state->m_deco_tilegen1, bitmap, cliprect, 0, 0); return 0; }