summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/othldrby.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/video/othldrby.c')
-rw-r--r--src/mame/video/othldrby.c224
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]));
+}