/***************************************************************************
Bionic Commando Video Hardware
This board handles tile/tile and tile/sprite priority with a PROM. Its
working is complicated and hardcoded in the driver.
The PROM is a 256x4 chip, with address inputs wired as follows:
A0 bg opaque
A1 \
A2 | fg pen
A3 |
A4 /
A5 fg has priority over sprites (bit 5 of tile attribute)
A6 fg has not priority over bg (bits 6 & 7 of tile attribute both set)
A7 sprite opaque
The output selects the active layer, it can be:
0 bg
1 fg
2 sprite
***************************************************************************/
#include "driver.h"
UINT16 *bionicc_fgvideoram;
UINT16 *bionicc_bgvideoram;
UINT16 *bionicc_txvideoram;
static tilemap *tx_tilemap, *bg_tilemap, *fg_tilemap;
/***************************************************************************
Callbacks for the TileMap code
***************************************************************************/
static TILE_GET_INFO( get_bg_tile_info )
{
int attr = bionicc_bgvideoram[2*tile_index+1];
SET_TILE_INFO(
1,
(bionicc_bgvideoram[2*tile_index] & 0xff) + ((attr & 0x07) << 8),
(attr & 0x18) >> 3,
TILE_FLIPXY((attr & 0xc0) >> 6));
}
static TILE_GET_INFO( get_fg_tile_info )
{
int attr = bionicc_fgvideoram[2*tile_index+1];
int flags;
if ((attr & 0xc0) == 0xc0)
{
tileinfo->category = 1;
tileinfo->group = 0;
flags = 0;
}
else
{
tileinfo->category = 0;
tileinfo->group = (attr & 0x20) >> 5;
flags = TILE_FLIPXY((attr & 0xc0) >> 6);
}
SET_TILE_INFO(
2,
(bionicc_fgvideoram[2*tile_index] & 0xff) + ((attr & 0x07) << 8),
(attr & 0x18) >> 3,
flags);
}
static TILE_GET_INFO( get_tx_tile_info )
{
int attr = bionicc_txvideoram[tile_index + 0x400];
SET_TILE_INFO(
0,
(bionicc_txvideoram[tile_index] & 0xff) + ((attr & 0x00c0) << 2),
attr & 0x3f,
0);
}
/***************************************************************************
Start the video hardware emulation.
***************************************************************************/
VIDEO_START( bionicc )
{
tx_tilemap = tilemap_create(get_tx_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN, 8,8,32,32);
fg_tilemap = tilemap_create(get_fg_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN, 16,16,64,64);
bg_tilemap = tilemap_create(get_bg_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN, 8,8,64,64);
tilemap_set_transparent_pen(tx_tilemap,3);
tilemap_set_transmask(fg_tilemap,0,0xffff,0x8000); /* split type 0 is completely transparent in front half */
tilemap_set_transmask(fg_tilemap,1,0xffc1,0x803e); /* split type 1 has pens 1-5 opaque in front half */
tilemap_set_transparent_pen(bg_tilemap,15);
}
/***************************************************************************
Memory handlers
***************************************************************************/
WRITE16_HANDLER( bionicc_bgvideoram_w )
{
COMBINE_DATA(&bionicc_bgvideoram[offset]);
tilemap_mark_tile_dirty(bg_tilemap,offset/2);
}
WRITE16_HANDLER( bionicc_fgvideoram_w )
{
COMBINE_DATA(&bionicc_fgvideoram[offset]);
tilemap_mark_tile_dirty(fg_tilemap,offset/2);
}
WRITE16_HANDLER( bionicc_txvideoram_w )
{
COMBINE_DATA(&bionicc_txvideoram[offset]);
tilemap_mark_tile_dirty(tx_tilemap,offset&0x3ff);
}
WRITE16_HANDLER( bionicc_paletteram_w )
{
data = COMBINE_DATA(&paletteram16[offset]);
paletteram16_RRRRGGGGBBBBIIII_word_w(offset,(data & 0xfff0) | ((data & 0x0007) << 1),0);
}
WRITE16_HANDLER( bionicc_scroll_w )
{
static UINT16 scroll[4];
data = COMBINE_DATA(&scroll[offset]);
switch (offset)
{
case 0:
tilemap_set_scrollx(fg_tilemap,0,data);
break;
case 1:
tilemap_set_scrolly(fg_tilemap,0,data);
break;
case 2:
tilemap_set_scrollx(bg_tilemap,0,data);
break;
case 3:
tilemap_set_scrolly(bg_tilemap,0,data);
break;
}
}
WRITE16_HANDLER( bionicc_gfxctrl_w )
{
if (ACCESSING_MSB)
{
flip_screen_set(data & 0x0100);
tilemap_set_enable(bg_tilemap,data & 0x2000); /* guess */
tilemap_set_enable(fg_tilemap,data & 0x1000); /* guess */
coin_counter_w(0,data & 0x8000);
coin_counter_w(1,data & 0x4000);
}
}
/***************************************************************************
Display refresh
***************************************************************************/
static void draw_sprites(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect )
{
int offs;
const gfx_element *gfx = machine->gfx[3];
for (offs = (spriteram_size-8)/2;offs >= 0;offs -= 4)
{
int tile_number = buffered_spriteram16[offs] & 0x7ff;
if( tile_number!=0x7FF ){
int attr = buffered_spriteram16[offs+1];
int color = (attr&0x3C)>>2;
int flipx = attr&0x02;
int flipy = 0;
int sx = (INT16)buffered_spriteram16[offs+3]; /* signed */
int sy = (INT16)buffered_spriteram16[offs+2]; /* signed */
if(sy>512-16) sy-=512;
if (flip_screen)
{
sx = 240 - sx;
sy = 240 - sy;
flipx = !flipx;
flipy = !flipy;
}
drawgfx( bitmap, gfx,
tile_number,
color,
flipx,flipy,
sx,sy,
cliprect,TRANSPARENCY_PEN,15);
}
}
}
VIDEO_UPDATE( bionicc )
{
fillbitmap(bitmap,machine->pens[0],cliprect);
tilemap_draw(bitmap,cliprect,fg_tilemap,1|TILEMAP_DRAW_LAYER1,0); /* nothing in FRONT */
tilemap_draw(bitmap,cliprect,bg_tilemap,0,0);
tilemap_draw(bitmap,cliprect,fg_tilemap,0|TILEMAP_DRAW_LAYER1,0);
draw_sprites(machine,bitmap,cliprect);
tilemap_draw(bitmap,cliprect,fg_tilemap,0|TILEMAP_DRAW_LAYER0,0);
tilemap_draw(bitmap,cliprect,tx_tilemap,0,0);
return 0;
}
VIDEO_EOF( bionicc )
{
buffer_spriteram16_w(0,0,0);
}