#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 }