diff options
Diffstat (limited to 'src/mame/video/bionicc.c')
-rw-r--r-- | src/mame/video/bionicc.c | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/src/mame/video/bionicc.c b/src/mame/video/bionicc.c new file mode 100644 index 00000000000..fc759b953ef --- /dev/null +++ b/src/mame/video/bionicc.c @@ -0,0 +1,232 @@ +/*************************************************************************** + +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); +} |