diff options
Diffstat (limited to 'src/mame/video/othldrby.c')
-rw-r--r-- | src/mame/video/othldrby.c | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/src/mame/video/othldrby.c b/src/mame/video/othldrby.c new file mode 100644 index 00000000000..8ca475d0be1 --- /dev/null +++ b/src/mame/video/othldrby.c @@ -0,0 +1,224 @@ +#include "driver.h" + + + +#define VIDEORAM_SIZE 0x1c00 +#define SPRITERAM_START 0x1800 +#define SPRITERAM_SIZE (VIDEORAM_SIZE-SPRITERAM_START) + +static UINT16 *vram,*buf_spriteram,*buf_spriteram2; + +#define VREG_SIZE 18 +static UINT16 vreg[VREG_SIZE]; + +static tilemap *bg_tilemap[3]; + + +/*************************************************************************** + + Callbacks for the TileMap code + +***************************************************************************/ + +INLINE void get_tile_info(running_machine *machine,tile_data *tileinfo,int tile_index,int plane) +{ + UINT16 attr; + + tile_index = 2*tile_index + 0x800*plane; + attr = vram[tile_index]; + SET_TILE_INFO( + 1, + vram[tile_index+1], + attr & 0x7f, + 0); + tileinfo->category = (attr & 0x0600) >> 9; +} + +static TILE_GET_INFO( get_tile_info0 ) +{ + get_tile_info(machine,tileinfo,tile_index,0); +} + +static TILE_GET_INFO( get_tile_info1 ) +{ + get_tile_info(machine,tileinfo,tile_index,1); +} + +static TILE_GET_INFO( get_tile_info2 ) +{ + get_tile_info(machine,tileinfo,tile_index,2); +} + + + +/*************************************************************************** + + Start the video hardware emulation. + +***************************************************************************/ + +VIDEO_START( othldrby ) +{ + bg_tilemap[0] = tilemap_create(get_tile_info0,tilemap_scan_rows,TILEMAP_TYPE_PEN,16,16,32,32); + bg_tilemap[1] = tilemap_create(get_tile_info1,tilemap_scan_rows,TILEMAP_TYPE_PEN,16,16,32,32); + bg_tilemap[2] = tilemap_create(get_tile_info2,tilemap_scan_rows,TILEMAP_TYPE_PEN,16,16,32,32); + + vram = auto_malloc(VIDEORAM_SIZE * sizeof(vram[0])); + buf_spriteram = auto_malloc(2*SPRITERAM_SIZE * sizeof(buf_spriteram[0])); + + buf_spriteram2 = buf_spriteram + SPRITERAM_SIZE; + + tilemap_set_transparent_pen(bg_tilemap[0],0); + tilemap_set_transparent_pen(bg_tilemap[1],0); + tilemap_set_transparent_pen(bg_tilemap[2],0); +} + + + +/*************************************************************************** + + Memory handlers + +***************************************************************************/ + +static UINT32 vram_addr,vreg_addr; + +WRITE16_HANDLER( othldrby_videoram_addr_w ) +{ + vram_addr = data; +} + +READ16_HANDLER( othldrby_videoram_r ) +{ + if (vram_addr < VIDEORAM_SIZE) + return vram[vram_addr++]; + else + { + popmessage("GFXRAM OUT OF BOUNDS %04x",vram_addr); + return 0; + } +} + +WRITE16_HANDLER( othldrby_videoram_w ) +{ + if (vram_addr < VIDEORAM_SIZE) + { + if (vram_addr < SPRITERAM_START) + tilemap_mark_tile_dirty(bg_tilemap[vram_addr/0x800],(vram_addr&0x7ff)/2); + vram[vram_addr++] = data; + } + else + popmessage("GFXRAM OUT OF BOUNDS %04x",vram_addr); +} + +WRITE16_HANDLER( othldrby_vreg_addr_w ) +{ + vreg_addr = data & 0x7f; /* bit 7 is set when screen is flipped */ +} + +WRITE16_HANDLER( othldrby_vreg_w ) +{ + if (vreg_addr < VREG_SIZE) + vreg[vreg_addr++] = data; + else + popmessage("%06x: VREG OUT OF BOUNDS %04x",activecpu_get_pc(),vreg_addr); +} + + + +/*************************************************************************** + + Display refresh + +***************************************************************************/ + +static void draw_sprites(running_machine *machine, mame_bitmap *bitmap,const rectangle *cliprect,int priority) +{ + int offs; + + for (offs = 0;offs < SPRITERAM_SIZE;offs += 4) + { + int x,y,color,code,sx,sy,flipx,flipy,sizex,sizey,pri; + + + pri = (buf_spriteram[offs] & 0x0600) >> 9; + if (pri != priority) continue; + + flipx = buf_spriteram[offs] & 0x1000; + flipy = 0; + color = (buf_spriteram[offs] & 0x01fc) >> 2; + code = buf_spriteram[offs+1] | ((buf_spriteram[offs] & 0x0003) << 16); + sx = (buf_spriteram[offs+2] >> 7); + sy = (buf_spriteram[offs+3] >> 7); + sizex = (buf_spriteram[offs+2] & 0x000f) + 1; + sizey = (buf_spriteram[offs+3] & 0x000f) + 1; + + if (flip_screen) + { + flipx = !flipx; + flipy = !flipy; + sx = 246 - sx; + sy = 16 - sy; + } + + for (y = 0;y < sizey;y++) + { + for (x = 0;x < sizex;x++) + { + drawgfx(bitmap,machine->gfx[0], + code + x + sizex * y, + color, + flipx,flipy, + (sx + (flipx ? (-8*(x+1)+1) : 8*x) - vreg[6]+44) & 0x1ff,(sy + (flipy ? (-8*(y+1)+1) : 8*y) - vreg[7]-9) & 0x1ff, + cliprect,TRANSPARENCY_PEN,0); + } + } + } +} + +VIDEO_UPDATE( othldrby ) +{ + int layer; + + + flip_screen_set(vreg[0x0f] & 0x80); + + for (layer = 0;layer < 3;layer++) + { + if (flip_screen) + { + tilemap_set_scrollx(bg_tilemap[layer],0,vreg[2*layer]+59); + tilemap_set_scrolly(bg_tilemap[layer],0,vreg[2*layer+1]+248); + } + else + { + tilemap_set_scrollx(bg_tilemap[layer],0,vreg[2*layer]-58); + tilemap_set_scrolly(bg_tilemap[layer],0,vreg[2*layer+1]+9); + } + } + + fillbitmap(priority_bitmap,0,cliprect); + + fillbitmap(bitmap,machine->pens[0],cliprect); + + for (layer = 0;layer < 3;layer++) + tilemap_draw(bitmap,cliprect,bg_tilemap[layer],0,0); + draw_sprites(machine,bitmap,cliprect,0); + for (layer = 0;layer < 3;layer++) + tilemap_draw(bitmap,cliprect,bg_tilemap[layer],1,0); + draw_sprites(machine,bitmap,cliprect,1); + for (layer = 0;layer < 3;layer++) + tilemap_draw(bitmap,cliprect,bg_tilemap[layer],2,0); + draw_sprites(machine,bitmap,cliprect,2); + for (layer = 0;layer < 3;layer++) + tilemap_draw(bitmap,cliprect,bg_tilemap[layer],3,0); + draw_sprites(machine,bitmap,cliprect,3); + return 0; +} + +VIDEO_EOF( othldrby ) +{ + /* sprites need to be delayed two frames */ + memcpy(buf_spriteram,buf_spriteram2,SPRITERAM_SIZE*sizeof(buf_spriteram[0])); + memcpy(buf_spriteram2,&vram[SPRITERAM_START],SPRITERAM_SIZE*sizeof(buf_spriteram[0])); +} |