diff options
Diffstat (limited to 'src/mame/video/dynduke.c')
-rw-r--r-- | src/mame/video/dynduke.c | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/src/mame/video/dynduke.c b/src/mame/video/dynduke.c new file mode 100644 index 00000000000..41f0dc17ac5 --- /dev/null +++ b/src/mame/video/dynduke.c @@ -0,0 +1,248 @@ + +#include "driver.h" + +static tilemap *bg_layer,*fg_layer,*tx_layer; +UINT16 *dynduke_back_data,*dynduke_fore_data,*dynduke_scroll_ram; + +static int back_bankbase,fore_bankbase; +static int back_enable,fore_enable,sprite_enable,txt_enable; + +/******************************************************************************/ + +WRITE16_HANDLER( dynduke_paletteram_w ) +{ + int color; + + COMBINE_DATA(&paletteram16[offset]); + color=paletteram16[offset]; + palette_set_color_rgb(Machine,offset,pal4bit(color >> 0),pal4bit(color >> 4),pal4bit(color >> 8)); +} + +WRITE16_HANDLER( dynduke_background_w ) +{ + COMBINE_DATA(&dynduke_back_data[offset]); + tilemap_mark_tile_dirty(bg_layer,offset); +} + +WRITE16_HANDLER( dynduke_foreground_w ) +{ + COMBINE_DATA(&dynduke_fore_data[offset]); + tilemap_mark_tile_dirty(fg_layer,offset); +} + +WRITE16_HANDLER( dynduke_text_w ) +{ + COMBINE_DATA(&videoram16[offset]); + tilemap_mark_tile_dirty(tx_layer,offset); +} + +static TILE_GET_INFO( get_bg_tile_info ) +{ + int tile=dynduke_back_data[tile_index]; + int color=tile >> 12; + + tile=tile&0xfff; + + SET_TILE_INFO( + 1, + tile+back_bankbase, + color, + 0); +} + +static TILE_GET_INFO( get_fg_tile_info ) +{ + int tile=dynduke_fore_data[tile_index]; + int color=tile >> 12; + + tile=tile&0xfff; + + SET_TILE_INFO( + 2, + tile+fore_bankbase, + color, + 0); +} + +static TILE_GET_INFO( get_tx_tile_info ) +{ + int tile=videoram16[tile_index]; + int color=(tile >> 8) & 0x0f; + + tile = (tile & 0xff) | ((tile & 0xc000) >> 6); + + SET_TILE_INFO( + 0, + tile, + color, + 0); +} + +VIDEO_START( dynduke ) +{ + bg_layer = tilemap_create(get_bg_tile_info,tilemap_scan_cols,TILEMAP_TYPE_PEN, 16,16,32,32); + fg_layer = tilemap_create(get_fg_tile_info,tilemap_scan_cols,TILEMAP_TYPE_PEN,16,16,32,32); + tx_layer = tilemap_create(get_tx_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN, 8, 8,32,32); + + tilemap_set_transparent_pen(fg_layer,15); + tilemap_set_transparent_pen(tx_layer,15); +} + +WRITE16_HANDLER( dynduke_gfxbank_w ) +{ + static int old_back,old_fore; + + if (ACCESSING_LSB) + { + if (data&0x01) back_bankbase=0x1000; else back_bankbase=0; + if (data&0x10) fore_bankbase=0x1000; else fore_bankbase=0; + + if (back_bankbase!=old_back) + tilemap_mark_all_tiles_dirty(bg_layer); + if (fore_bankbase!=old_fore) + tilemap_mark_all_tiles_dirty(fg_layer); + + old_back=back_bankbase; + old_fore=fore_bankbase; + } +} + + +WRITE16_HANDLER( dynduke_control_w ) +{ + + if (ACCESSING_LSB) + { + // bit 0x80 toggles, maybe sprite buffering? + // bit 0x40 is flipscreen + // bit 0x20 not used? + // bit 0x10 not used? + // bit 0x08 is set on the title screen (sprite disable?) + // bit 0x04 unused? txt disable? + // bit 0x02 is used on the map screen (fore disable?) + // bit 0x01 set when inserting coin.. bg disable? + + if (data&0x1) back_enable = 0; else back_enable = 1; + if (data&0x2) fore_enable=0; else fore_enable=1; + if (data&0x4) txt_enable = 0; else txt_enable = 1; + if (data&0x8) sprite_enable=0; else sprite_enable=1; + + flip_screen_set(data & 0x40); + } +} + +static void draw_sprites(running_machine *machine, mame_bitmap *bitmap,const rectangle *cliprect,int pri) +{ + int offs,fx,fy,x,y,color,sprite; + + if (!sprite_enable) return; + + for (offs = 0x800-4;offs >= 0;offs -= 4) + { + /* Don't draw empty sprite table entries */ + if ((buffered_spriteram16[offs+3] >> 8)!=0xf) continue; + if (((buffered_spriteram16[offs+2]>>13)&3)!=pri) continue; + + fx= buffered_spriteram16[offs+0]&0x2000; + fy= buffered_spriteram16[offs+0]&0x4000; + y = buffered_spriteram16[offs+0] & 0xff; + x = buffered_spriteram16[offs+2] & 0xff; + + if (buffered_spriteram16[offs+2]&0x100) x=0-(0x100-x); + + color = (buffered_spriteram16[offs+0]>>8)&0x1f; + sprite = buffered_spriteram16[offs+1]; + sprite &= 0x3fff; + + if (flip_screen) { + x=240-x; + y=240-y; + if (fx) fx=0; else fx=1; + if (fy) fy=0; else fy=1; + } + + drawgfx(bitmap,machine->gfx[3], + sprite, + color,fx,fy,x,y, + cliprect,TRANSPARENCY_PEN,15); + } +} + +static void draw_background(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect, int pri ) +{ + /* The transparency / palette handling on the background layer is very strange */ + mame_bitmap *bm = tilemap_get_pixmap(bg_layer); + int scrolly, scrollx; + int x,y; + + /* if we're disabled, don't draw */ + if (!back_enable) + { + fillbitmap(bitmap,get_black_pen(machine),cliprect); + return; + } + + scrolly = ((dynduke_scroll_ram[0x01]&0x30)<<4)+((dynduke_scroll_ram[0x02]&0x7f)<<1)+((dynduke_scroll_ram[0x02]&0x80)>>7); + scrollx = ((dynduke_scroll_ram[0x09]&0x30)<<4)+((dynduke_scroll_ram[0x0a]&0x7f)<<1)+((dynduke_scroll_ram[0x0a]&0x80)>>7); + + for (y=0;y<256;y++) + { + int realy = (y + scrolly) & 0x1ff; + UINT16 *src = BITMAP_ADDR16(bm, realy, 0); + UINT16 *dst = BITMAP_ADDR16(bitmap, y, 0); + + + for (x=0;x<256;x++) + { + int realx = (x + scrollx) & 0x1ff; + UINT16 srcdat = src[realx]; + + /* 0x01 - data bits + 0x02 + 0x04 + 0x08 + 0x10 - extra colour bit? (first boss) + 0x20 - priority over sprites + the old driver also had 'bg_palbase' but I don't see what it's for? + */ + + if ((srcdat & 0x20) == pri) + { + if (srcdat & 0x10) srcdat += 0x400; + //if (srcdat & 0x10) srcdat += mame_rand(machine)&0x1f; + + srcdat = (srcdat & 0x000f) | ((srcdat & 0xffc0) >> 2); + dst[x] = srcdat; + } + + + } + } +} + +VIDEO_UPDATE( dynduke ) +{ + /* Setup the tilemaps */ + tilemap_set_scrolly( fg_layer,0, ((dynduke_scroll_ram[0x11]&0x30)<<4)+((dynduke_scroll_ram[0x12]&0x7f)<<1)+((dynduke_scroll_ram[0x12]&0x80)>>7) ); + tilemap_set_scrollx( fg_layer,0, ((dynduke_scroll_ram[0x19]&0x30)<<4)+((dynduke_scroll_ram[0x1a]&0x7f)<<1)+((dynduke_scroll_ram[0x1a]&0x80)>>7) ); + tilemap_set_enable( fg_layer,fore_enable); + tilemap_set_enable( tx_layer,txt_enable); + + + draw_background(machine, bitmap, cliprect,0x00); + draw_sprites(machine,bitmap,cliprect,0); // Untested: does anything use it? Could be behind background + draw_sprites(machine,bitmap,cliprect,1); + draw_background(machine, bitmap, cliprect,0x20); + + draw_sprites(machine,bitmap,cliprect,2); + tilemap_draw(bitmap,cliprect,fg_layer,0,0); + draw_sprites(machine,bitmap,cliprect,3); + tilemap_draw(bitmap,cliprect,tx_layer,0,0); + + return 0; +} + +VIDEO_EOF( dynduke ) +{ + buffer_spriteram16_w(0,0,0); // Could be a memory location instead +} |