diff options
Diffstat (limited to 'src/mame/video/liberate.c')
-rw-r--r-- | src/mame/video/liberate.c | 419 |
1 files changed, 419 insertions, 0 deletions
diff --git a/src/mame/video/liberate.c b/src/mame/video/liberate.c new file mode 100644 index 00000000000..1815baa2bd1 --- /dev/null +++ b/src/mame/video/liberate.c @@ -0,0 +1,419 @@ +/******************************************************************************* + + Todo: + There are some kind of resistors hooked up to the background colours, + the same prom colours can change for the background but not the + foreground. It's rarely used (Liberation title screen only?). + + Emulation by Bryan McPhail, mish@tendril.co.uk + +*******************************************************************************/ + +#include "driver.h" +#include "cpu/m6502/m6502.h" + +static int background_color,background_disable; +static tilemap *background_tilemap, *fix_tilemap; +static UINT8 deco16_io_ram[16]; + +#if 0 +void debug_print(mame_bitmap *bitmap) +{ + int i,j; + char buf[20*16]; + char *bufptr = buf; + for (i = 0;i < 16;i+=2) + bufptr += sprintf(bufptr,"%04X",deco16_io_ram[i+1]|(deco16_io_ram[i]<<8)); + ui_draw_text(buf, 10, 6*6); +} +#endif + +static TILEMAP_MAPPER( back_scan ) +{ + /* logical (col,row) -> memory offset */ + return ((row & 0xf)) + ((15-(col &0xf))<<4) + ((row&0x10)<<5) + ((col&0x10)<<4); +} + +static TILEMAP_MAPPER( fix_scan ) +{ + /* logical (col,row) -> memory offset */ + return (row & 0x1f) + ((31-(col &0x1f))<<5); +} + +static TILE_GET_INFO( get_back_tile_info ) +{ + const UINT8 *RAM = memory_region(REGION_USER1); + int tile,bank; + + /* Convert tile index of 512x512 to paged format */ + if (tile_index&0x100) { + if (tile_index&0x200) + tile_index=(tile_index&0xff)+(deco16_io_ram[5]<<8); /* Bottom right */ + else + tile_index=(tile_index&0xff)+(deco16_io_ram[4]<<8); /* Bottom left */ + } else { + if (tile_index&0x200) + tile_index=(tile_index&0xff)+(deco16_io_ram[3]<<8); /* Top right */ + else + tile_index=(tile_index&0xff)+(deco16_io_ram[2]<<8); /* Top left */ + } + + tile=RAM[tile_index]; + if (tile>0x7f) bank=3; else bank=2; + SET_TILE_INFO(bank,tile&0x7f,background_color,0); +} + +static TILE_GET_INFO( get_fix_tile_info ) +{ + int tile,color; + + tile=videoram[tile_index+0x400]+((videoram[tile_index]&0x7)<<8); + color=(videoram[tile_index]&0x70)>>4; + +//if (tile&0x300) tile-=0x000; +//else if(tile&0x200) tile-=0x100; +//else if (tile&0x100) tile-=0x100; +//else tile+=0x200; + + SET_TILE_INFO(0,tile,color,0); +} + +/***************************************************************************/ + +WRITE8_HANDLER( deco16_io_w ) +{ + deco16_io_ram[offset]=data; + if (offset>1 && offset<6) + tilemap_mark_all_tiles_dirty(background_tilemap); + + switch (offset) { + case 6: /* Background colour */ + if (((data>>4)&3)!=background_color) { + background_color=(data>>4)&3; + tilemap_mark_all_tiles_dirty(background_tilemap); + } + background_disable=data&0x4; + flip_screen_set(data&0x1); + break; + case 7: /* Background palette resistors? */ + /* Todo */ + break; + case 8: /* Irq ack */ + cpunum_set_input_line(0,DECO16_IRQ_LINE,CLEAR_LINE); + break; + case 9: /* Sound */ + soundlatch_w(0,data); + cpunum_set_input_line(1,M6502_IRQ_LINE,HOLD_LINE); + break; + } +} + +WRITE8_HANDLER( liberate_videoram_w ) +{ + videoram[offset]=data; + tilemap_mark_tile_dirty(fix_tilemap,offset&0x3ff); +} + +/***************************************************************************/ + +VIDEO_START( prosoccr ) +{ + background_tilemap = tilemap_create(get_back_tile_info,back_scan,TILEMAP_TYPE_PEN,16,16,32,32); + fix_tilemap = tilemap_create(get_fix_tile_info,fix_scan,TILEMAP_TYPE_PEN,8,8,32,32); + + tilemap_set_transparent_pen(fix_tilemap,0); +} + +VIDEO_START( boomrang ) +{ + background_tilemap = tilemap_create(get_back_tile_info,back_scan,TILEMAP_TYPE_PEN,16,16,32,32); + fix_tilemap = tilemap_create(get_fix_tile_info,fix_scan,TILEMAP_TYPE_PEN,8,8,32,32); + + tilemap_set_transmask(background_tilemap,0,0x0001,0x007e); /* Bottom 1 pen/Top 7 pens */ + tilemap_set_transparent_pen(fix_tilemap,0); +} + +VIDEO_START( liberate ) +{ + background_tilemap = tilemap_create(get_back_tile_info,back_scan,TILEMAP_TYPE_PEN,16,16,32,32); + fix_tilemap = tilemap_create(get_fix_tile_info,fix_scan,TILEMAP_TYPE_PEN,8,8,32,32); + + tilemap_set_transparent_pen(fix_tilemap,0); +} + +/***************************************************************************/ + +WRITE8_HANDLER( prosport_paletteram_w ) +{ + /* RGB output is inverted */ + paletteram_BBGGGRRR_w(offset,~data); +} + +PALETTE_INIT( liberate ) +{ + int i,bit0,bit1,bit2,g,r,b; + + for (i = 0;i < 32;i++) + { + /* red component */ + bit0 = (*color_prom >> 0) & 0x01; + bit1 = (*color_prom >> 1) & 0x01; + bit2 = (*color_prom >> 2) & 0x01; + r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; + + /* green component */ + bit0 = (*color_prom >> 3) & 0x01; + bit1 = (*color_prom >> 4) & 0x01; + bit2 = (*color_prom >> 5) & 0x01; + g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; + + /* blue component */ + bit0 = 0; + bit1 = (*color_prom >> 6) & 0x01; + bit2 = (*color_prom >> 7) & 0x01; + b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2; + + color_prom++; + palette_set_color(machine,i,MAKE_RGB(r,g,b)); + } + palette_set_color(machine,32,MAKE_RGB(0,0,0)); /* Allocate black for when no background is displayed */ +} + +/***************************************************************************/ + +static void liberate_draw_sprites(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect) +{ + int offs; + + /* Sprites */ + for (offs = 0;offs < 0x800;offs += 4) + { + int multi,fx,fy,sx,sy,sy2,code,color; + + code = spriteram[offs+1] + ( ( spriteram[offs+0] & 0x60 ) << 3 ); + sx = (240 - spriteram[offs+3]); + //if (sx < -7) sx += 256; + + sy = 240-spriteram[offs+2]; + color = 0;//(spriteram[offs+1] & 0x03);// + ((spriteram[offs+1] & 0x08) >> 1); + +// if (pri==0 && color!=0) continue; +// if (pri==1 && color==0) continue; + + fx = spriteram[offs+0] & 0x04; + fy = spriteram[offs+0] & 0x08; // or 0x02 ? + multi = spriteram[offs+0] & 0x10; + + + if (multi) sy-=16; + + if (flip_screen) { + sy=240-sy; + sx=240-sx; + if (fx) fx=0; else fx=1; + if (fy) fy=0; else fy=1; + sy2=sy-16; + } + else sy2=sy+16; + + drawgfx(bitmap,machine->gfx[1], + code, + color, + fx,fy, + sx,sy, + cliprect,TRANSPARENCY_PEN,0); + if (multi) + drawgfx(bitmap,machine->gfx[1], + code+1, + color, + fx,fy, + sx,sy2, + cliprect,TRANSPARENCY_PEN,0); + } +} + +static void prosport_draw_sprites(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect) +{ + int offs,multi,fx,fy,sx,sy,sy2,code,code2,color; + + for (offs = 0x000;offs < 0x800;offs += 4) + { + // if ((spriteram[offs+0]&1)!=1) continue; + + code = spriteram[offs+1] + ((spriteram[offs+0]&0x3)<<8); + code2=code+1; + + multi = spriteram[offs+0] & 0x10; + + sy=spriteram[offs+2]; + if (multi) sy+=16; + sx = (240 - spriteram[offs+3]); +// sy = (240-spriteram[offs+2]);//-16; + sy = 240-sy; + + color = 1;//(spriteram[offs+0]&0x4)>>2; + + fx = 0; + fy = spriteram[offs+0] & 0x04; + multi = 0;// spriteram[offs+0] & 0x10; + +// if (multi) sy-=16; + if (fy && multi) { code2=code; code++; } + + if (flip_screen) { + sy=240-sy; + sx=240-sx; + if (fx) fx=0; else fx=1; + if (fy) fy=0; else fy=1; + sy2=sy-16; + } + else { + sy2=sy+16; + } + + drawgfx(bitmap,machine->gfx[1], + code, + color, + fx,fy, + sx,sy, + cliprect,TRANSPARENCY_PEN,0); + if (multi) + drawgfx(bitmap,machine->gfx[1], + code2, + color, + fx,fy, + sx,sy2, + cliprect,TRANSPARENCY_PEN,0); + } +} + +static void boomrang_draw_sprites(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect, int pri) +{ + int offs,multi,fx,fy,sx,sy,sy2,code,code2,color; + + for (offs = 0x000;offs < 0x800;offs += 4) + { + if ((spriteram[offs+0]&1)!=1) continue; + if ((spriteram[offs+0]&0x8)!=pri) continue; + + code = spriteram[offs+1] + ((spriteram[offs+0]&0xe0)<<3); + code2=code+1; + + multi = spriteram[offs+0] & 0x10; + + sy=spriteram[offs+2]; + if (multi) sy+=16; + sx = (240 - spriteram[offs+3]); +// sy = (240-spriteram[offs+2]);//-16; + sy = 240-sy; + + color = (spriteram[offs+0]&0x4)>>2; + + fx = 0; + fy = spriteram[offs+0] & 0x02; + multi = spriteram[offs+0] & 0x10; + +// if (multi) sy-=16; + if (fy && multi) { code2=code; code++; } + + if (flip_screen) { + sy=240-sy; + sx=240-sx; + if (fx) fx=0; else fx=1; + if (fy) fy=0; else fy=1; + sy2=sy-16; + } + else { + sy2=sy+16; + } + + drawgfx(bitmap,machine->gfx[1], + code, + color, + fx,fy, + sx,sy, + cliprect,TRANSPARENCY_PEN,0); + if (multi) + drawgfx(bitmap,machine->gfx[1], + code2, + color, + fx,fy, + sx,sy2, + cliprect,TRANSPARENCY_PEN,0); + } +} + +/***************************************************************************/ + +VIDEO_UPDATE( prosoccr ) +{ + tilemap_set_scrolly(background_tilemap,0,deco16_io_ram[1]); + tilemap_set_scrollx(background_tilemap,0,-deco16_io_ram[0]); + + if (background_disable) + fillbitmap(bitmap,machine->pens[32],cliprect); + else + tilemap_draw(bitmap,cliprect,background_tilemap,0,0); + boomrang_draw_sprites(machine,bitmap,cliprect,0); + tilemap_draw(bitmap,cliprect,fix_tilemap,0,0); + return 0; +} + +VIDEO_UPDATE( prosport ) +{ + int mx,my,tile,color,offs; + + fillbitmap(bitmap,machine->pens[0],cliprect); + + prosport_draw_sprites(machine,bitmap,cliprect); + + for (offs = 0;offs < 0x400;offs++) { + tile=videoram[offs+0x400]+((videoram[offs]&0x3)<<8); + + tile+=((deco16_io_ram[0]&0x30)<<6); + + if (!tile) continue; + + color=1;//(videoram[offs]&0x70)>>4; + my = (offs) % 32; + mx = (offs) / 32; + + drawgfx(bitmap,machine->gfx[0], + tile,1,0,0,248-8*mx,8*my, + cliprect,TRANSPARENCY_PEN,0); + } + return 0; +} + +VIDEO_UPDATE( boomrang ) +{ + tilemap_set_scrolly(background_tilemap,0, deco16_io_ram[1]); + tilemap_set_scrollx(background_tilemap,0,-deco16_io_ram[0]); + + if (background_disable) + fillbitmap(bitmap,machine->pens[32],cliprect); + else + tilemap_draw(bitmap,cliprect,background_tilemap,TILEMAP_DRAW_LAYER1,0); + + boomrang_draw_sprites(machine,bitmap,cliprect,8); + if (!background_disable) + tilemap_draw(bitmap,cliprect,background_tilemap,TILEMAP_DRAW_LAYER0,0); + boomrang_draw_sprites(machine,bitmap,cliprect,0); + tilemap_draw(bitmap,cliprect,fix_tilemap,0,0); + return 0; +} + +VIDEO_UPDATE( liberate ) +{ + tilemap_set_scrolly(background_tilemap,0, deco16_io_ram[1]); + tilemap_set_scrollx(background_tilemap,0,-deco16_io_ram[0]); + + if (background_disable) + fillbitmap(bitmap,machine->pens[32],cliprect); + else + tilemap_draw(bitmap,cliprect,background_tilemap,0,0); + + liberate_draw_sprites(machine,bitmap,cliprect); + tilemap_draw(bitmap,cliprect,fix_tilemap,0,0); + return 0; +} |