#include "driver.h" #include "cpu/z80/z80.h" #include "snk.h" static int flipscreen, sprite_flip_adjust; static tilemap *fg_tilemap, *bg_tilemap, *tx_tilemap; static UINT8 bg_color, fg_color, old_bg_color, old_fg_color; static rectangle tilemap_clip; /*************************************************************************** ** ** Palette Handling: ** ** Each color entry is encoded by 12 bits in color proms ** ** There are sixteen 8-color sprite palettes ** sprite palette is selected by a nibble of spriteram ** ** There are eight 16-color text layer character palettes ** character palette is determined by character_number ** ** Background and Foreground tilemap layers each have eight 16-color ** palettes. A palette bank select register is associated with the whole ** layer. ** ***************************************************************************/ WRITE8_HANDLER( marvins_palette_bank_w ) { bg_color = data>>4; fg_color = data&0xf; } static void stuff_palette( running_machine *machine, int source_index, int dest_index, int num_colors ) { UINT8 *color_prom = memory_region(REGION_PROMS) + source_index; int i; for( i=0; i> 2) & 0x01; // ? bit1 = (color_prom[0x000] >> 1) & 0x01; bit2 = (color_prom[0x000] >> 2) & 0x01; bit3 = (color_prom[0x000] >> 3) & 0x01; red = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; bit0 = (color_prom[0x800] >> 1) & 0x01; // ? bit1 = (color_prom[0x400] >> 2) & 0x01; bit2 = (color_prom[0x400] >> 3) & 0x01; bit3 = (color_prom[0x000] >> 0) & 0x01; green = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; bit0 = (color_prom[0x800] >> 0) & 0x01; // ? bit1 = (color_prom[0x800] >> 3) & 0x01; // ? bit2 = (color_prom[0x400] >> 0) & 0x01; bit3 = (color_prom[0x400] >> 1) & 0x01; blue = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; palette_set_color( machine, dest_index++, MAKE_RGB(red, green, blue) ); color_prom++; } for (i=0; i<=5; i++) gfx_drawmode_table[i] = DRAWMODE_SOURCE; gfx_drawmode_table[6] = DRAWMODE_SHADOW; gfx_drawmode_table[7] = DRAWMODE_NONE; } static void update_palette(running_machine *machine, int type ) { if( bg_color!=old_bg_color ) { stuff_palette( machine, 256+16*(bg_color&0x7), (0x11-type)*16, 16 ); old_bg_color = bg_color; } if( fg_color!=old_fg_color ) { stuff_palette( machine, 128+16*(fg_color&0x7), (0x10+type)*16, 16 ); old_fg_color = fg_color; } } /*************************************************************************** ** ** Memory Handlers ** ***************************************************************************/ #ifdef UNUSED_FUNCTION WRITE8_HANDLER( marvins_spriteram_w ) { spriteram[offset] = data; } #endif WRITE8_HANDLER( marvins_foreground_ram_w ) { spriteram_2[offset] = data; if (offset < 0x800) tilemap_mark_tile_dirty(fg_tilemap,offset); } WRITE8_HANDLER( marvins_background_ram_w ) { spriteram_3[offset] = data; if (offset < 0x800) tilemap_mark_tile_dirty(bg_tilemap,offset); } WRITE8_HANDLER( marvins_text_ram_w ) { videoram[offset] = data; if (offset < 0x400) tilemap_mark_tile_dirty(tx_tilemap,offset); } /*************************************************************************** ** ** Callbacks for Tilemap Manager ** ***************************************************************************/ static TILE_GET_INFO( get_bg_tilemap_info ) { SET_TILE_INFO( 2, spriteram_3[tile_index], 0, 0); } static TILE_GET_INFO( get_fg_tilemap_info ) { SET_TILE_INFO( 1, spriteram_2[tile_index], 0, 0); } static TILE_GET_INFO( get_tx_tilemap_info ) { int tile_number = videoram[tile_index]; SET_TILE_INFO( 0, tile_number, (tile_number>>5), 0); } /*************************************************************************** ** ** Video Initialization ** ***************************************************************************/ VIDEO_START( marvins ) { flipscreen = -1; old_bg_color = old_fg_color = -1; stuff_palette( machine, 0, 0, 16*8 ); /* load sprite colors */ stuff_palette( machine, 16*8*3, 16*8, 16*8 ); /* load text colors */ fg_tilemap = tilemap_create(get_fg_tilemap_info,tilemap_scan_cols,TILEMAP_TYPE_PEN,8,8,64,32); bg_tilemap = tilemap_create(get_bg_tilemap_info,tilemap_scan_cols,TILEMAP_TYPE_PEN,8,8,64,32); tx_tilemap = tilemap_create(get_tx_tilemap_info,tilemap_scan_cols,TILEMAP_TYPE_PEN,8,8,32,32); { tilemap_clip = machine->screen[0].visarea; if (snk_gamegroup != 1) // not Mad Crasher { tilemap_clip.max_x-=16; tilemap_clip.min_x+=16; } tilemap_set_transparent_pen(fg_tilemap,0xf); tilemap_set_transparent_pen(bg_tilemap,0xf); tilemap_set_transparent_pen(tx_tilemap,0xf); switch (snk_gamegroup) { case 0: // Marvin's Maze tilemap_set_scrolldx( bg_tilemap, 271, 287 ); tilemap_set_scrolldy( bg_tilemap, 0, -40 ); tilemap_set_scrolldx( fg_tilemap, 15, 13+18 ); tilemap_set_scrolldy( fg_tilemap, 0, -40 ); sprite_flip_adjust = 256+182+1; break; /* Old settings for the the following games: tilemap_set_scrolldx( bg_tilemap, -16, -10 ); tilemap_set_scrolldy( bg_tilemap, 0, -40 ); tilemap_set_scrolldx( fg_tilemap, 16, 22 ); tilemap_set_scrolldy( fg_tilemap, 0, -40 ); Note that while the new settings are more accurate they cannot handle flipscreen. */ case 1: // Mad Crasher tilemap_set_scrolldx( bg_tilemap,256, 0 ); tilemap_set_scrolldy( bg_tilemap, 12, 0 ); tilemap_set_scrolldx( fg_tilemap, 0, 0 ); tilemap_set_scrolldy( fg_tilemap, 6, 0 ); break; case 2: // VanguardII tilemap_set_scrolldx( bg_tilemap, 7, 0 ); tilemap_set_scrolldy( bg_tilemap,-20, 0 ); tilemap_set_scrolldx( fg_tilemap, 15, 0 ); tilemap_set_scrolldy( fg_tilemap, 0, 0 ); sprite_flip_adjust = 256+182; break; } tilemap_set_scrolldx( tx_tilemap, 16, 16 ); tilemap_set_scrolldy( tx_tilemap, 0, 0 ); } } /*************************************************************************** ** ** Screen Refresh ** ***************************************************************************/ static void draw_status(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect ) { const UINT8 *base = videoram+0x400; const gfx_element *gfx = machine->gfx[0]; int row; for( row=0; row<4; row++ ) { int sy,sx = (row&1)*8; const UINT8 *source = base + (row&1)*32; if( row>1 ) { sx+=256+16; } else { source+=30*32; } for( sy=0; sy<256; sy+=8 ) { int tile_number = *source++; drawgfx( bitmap, gfx, tile_number, tile_number>>5, 0,0, /* no flip */ sx,sy, cliprect, TRANSPARENCY_NONE, 0xf ); } } } static void draw_sprites(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect, int scrollx, int scrolly, int priority, UINT8 sprite_partition ) { const gfx_element *gfx = machine->gfx[3]; const UINT8 *source, *finish; if( sprite_partition>0x64 ) sprite_partition = 0x64; if( priority ) { source = spriteram + sprite_partition; finish = spriteram + 0x64; } else { source = spriteram; finish = spriteram + sprite_partition; } while( source 512-16) sx -= 512; if (sy > 256-16) sy -= 256; drawgfx( bitmap,gfx, tile_number, color, flipx, flipy, sx, sy, cliprect,TRANSPARENCY_PEN_TABLE,7); source+=4; } } VIDEO_UPDATE( marvins ) { cpuintrf_push_context(0); { UINT8 sprite_partition = program_read_byte(0xfe00); int attributes = program_read_byte(0x8600); /* 0x20: normal, 0xa0: video flipped */ int scroll_attributes = program_read_byte(0xff00); int sprite_scrolly = program_read_byte(0xf800); int sprite_scrollx = program_read_byte(0xf900); int bg_scrolly = program_read_byte(0xfa00); int bg_scrollx = program_read_byte(0xfb00); int fg_scrolly = program_read_byte(0xfc00); int fg_scrollx = program_read_byte(0xfd00); rectangle finalclip = tilemap_clip; sect_rect(&finalclip, cliprect); if( (scroll_attributes & 4)==0 ) bg_scrollx += 256; if( scroll_attributes & 1 ) sprite_scrollx += 256; if( scroll_attributes & 2 ) fg_scrollx += 256; /* palette bank for background/foreground is set by a memory-write handler */ update_palette(machine, 0); if( flipscreen != (attributes&0x80) ) { flipscreen = attributes&0x80; tilemap_set_flip( ALL_TILEMAPS, flipscreen?TILEMAP_FLIPY|TILEMAP_FLIPX:0); } tilemap_set_scrollx( bg_tilemap, 0, bg_scrollx ); tilemap_set_scrolly( bg_tilemap, 0, bg_scrolly ); tilemap_set_scrollx( fg_tilemap, 0, fg_scrollx ); tilemap_set_scrolly( fg_tilemap, 0, fg_scrolly ); tilemap_set_scrollx( tx_tilemap, 0, 0 ); tilemap_set_scrolly( tx_tilemap, 0, 0 ); tilemap_draw( bitmap,&finalclip,fg_tilemap,TILEMAP_DRAW_OPAQUE ,0); draw_sprites( machine,bitmap,cliprect, sprite_scrollx+29+1, sprite_scrolly+16, 0, sprite_partition ); tilemap_draw( bitmap,&finalclip,bg_tilemap,0 ,0); draw_sprites( machine,bitmap,cliprect, sprite_scrollx+29+1, sprite_scrolly+16, 1, sprite_partition ); tilemap_draw( bitmap,&finalclip,tx_tilemap,0 ,0); draw_status( machine,bitmap,cliprect ); } cpuintrf_pop_context(); return 0; } VIDEO_UPDATE( madcrash ) { /*************************************************************************** ** ** Game Specific Initialization ** ** madcrash_vreg defines an offset for the video registers which is ** different in Mad Crasher and Vanguard II. ** ** init_sound defines the location of the polled sound CPU busy bit, ** which also varies across games. ** ***************************************************************************/ cpuintrf_push_context(0); { int madcrash_vreg = (snk_gamegroup == 1) ? 0x00 : 0xf1; // Mad Crasher=0x00, VanguardII=0xf1 UINT8 sprite_partition = program_read_byte(0xfa00); int attributes = program_read_byte(0x8600+madcrash_vreg); /* 0x20: normal, 0xa0: video flipped */ int bg_scrolly = program_read_byte(0xf800+madcrash_vreg); int bg_scrollx = program_read_byte(0xf900+madcrash_vreg); int scroll_attributes = program_read_byte(0xfb00+madcrash_vreg); int sprite_scrolly = program_read_byte(0xfc00+madcrash_vreg); int sprite_scrollx = program_read_byte(0xfd00+madcrash_vreg); int fg_scrolly = program_read_byte(0xfe00+madcrash_vreg); int fg_scrollx = program_read_byte(0xff00+madcrash_vreg); rectangle finalclip = tilemap_clip; sect_rect(&finalclip, cliprect); if( (scroll_attributes & 4)==0 ) bg_scrollx += 256; if( scroll_attributes & 1 ) sprite_scrollx += 256; if( scroll_attributes & 2 ) fg_scrollx += 256; marvins_palette_bank_w(0, program_read_byte(0xc800+madcrash_vreg)); update_palette(machine, 1); if( flipscreen != (attributes&0x80) ) { flipscreen = attributes&0x80; tilemap_set_flip( ALL_TILEMAPS, flipscreen?TILEMAP_FLIPY|TILEMAP_FLIPX:0); } tilemap_set_scrollx( bg_tilemap, 0, bg_scrollx ); tilemap_set_scrolly( bg_tilemap, 0, bg_scrolly ); tilemap_set_scrollx( fg_tilemap, 0, fg_scrollx ); tilemap_set_scrolly( fg_tilemap, 0, fg_scrolly ); tilemap_set_scrollx( tx_tilemap, 0, 0 ); tilemap_set_scrolly( tx_tilemap, 0, 0 ); tilemap_draw( bitmap,&finalclip,bg_tilemap,TILEMAP_DRAW_OPAQUE ,0); draw_sprites( machine,bitmap,cliprect, sprite_scrollx+29, sprite_scrolly+17, 0, sprite_partition ); tilemap_draw( bitmap,&finalclip,fg_tilemap,0 ,0); draw_sprites( machine,bitmap,cliprect, sprite_scrollx+29, sprite_scrolly+17, 1, sprite_partition ); tilemap_draw( bitmap,&finalclip,tx_tilemap,0 ,0); draw_status( machine,bitmap,cliprect ); } cpuintrf_pop_context(); return 0; }