#include "emu.h" #include "includes/snk.h" /******************************************************************************* Shadow Handling Notes ******************************************************************************** Shadows are handled by changing palette bank. Games Not Using Shadows those using gwar_vh_screenrefresh (gwar, bermudat, psychos, chopper1) (0-15 , 15 is transparent) Games Using Shadows those using tnk3_vh_screenrefresh (tnk3, athena, fitegolf) sgladiat is similar (0-7 , 6 is shadow, 7 is transparent) * these are using aso colour prom convert * those using ikari_vh_screenrefresh (ikari, victroad) (0-7 , 6 is shadow, 7 is transparent) those using tdfever_vh_screenrefresh (tdfever, fsoccer) (0-15 , 14 is shadow, 15 is transparent) *******************************************************************************/ /**************************************************************************************/ PALETTE_INIT( tnk3 ) { int i; int num_colors = 0x400; for( i=0; i> 3) & 0x01; bit1 = (color_prom[i] >> 1) & 0x01; bit2 = (color_prom[i] >> 2) & 0x01; bit3 = (color_prom[i] >> 3) & 0x01; r = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; bit0 = (color_prom[i + 2*num_colors] >> 2) & 0x01; bit1 = (color_prom[i + num_colors] >> 2) & 0x01; bit2 = (color_prom[i + num_colors] >> 3) & 0x01; bit3 = (color_prom[i] >> 0) & 0x01; g = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; bit0 = (color_prom[i + 2*num_colors] >> 0) & 0x01; bit1 = (color_prom[i + 2*num_colors] >> 1) & 0x01; bit2 = (color_prom[i + num_colors] >> 0) & 0x01; bit3 = (color_prom[i + num_colors] >> 1) & 0x01; b = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; palette_set_color(machine,i,MAKE_RGB(r,g,b)); } } /**************************************************************************************/ static TILEMAP_MAPPER( marvins_tx_scan_cols ) { // tilemap is 36x28, the central part is from the first RAM page and the // extra 4 columns are from the second page col -= 2; if (col & 0x20) return 0x400 + row + ((col & 0x1f) << 5); else return row + (col << 5); } static TILE_GET_INFO( marvins_get_tx_tile_info ) { snk_state *state = machine.driver_data(); int code = state->m_tx_videoram[tile_index]; int color = code >> 5; SET_TILE_INFO(0, state->m_tx_tile_offset + code, color, tile_index & 0x400 ? TILE_FORCE_LAYER0 : 0); } static TILE_GET_INFO( ikari_get_tx_tile_info ) { snk_state *state = machine.driver_data(); int code = state->m_tx_videoram[tile_index]; SET_TILE_INFO(0, state->m_tx_tile_offset + code, 0, tile_index & 0x400 ? TILE_FORCE_LAYER0 : 0); } static TILE_GET_INFO( gwar_get_tx_tile_info ) { snk_state *state = machine.driver_data(); int code = state->m_tx_videoram[tile_index]; SET_TILE_INFO(0, state->m_tx_tile_offset + code, 0, 0); } static TILE_GET_INFO( marvins_get_fg_tile_info ) { snk_state *state = machine.driver_data(); int code = state->m_fg_videoram[tile_index]; SET_TILE_INFO(1, code, 0, 0); } static TILE_GET_INFO( marvins_get_bg_tile_info ) { snk_state *state = machine.driver_data(); int code = state->m_bg_videoram[tile_index]; SET_TILE_INFO(2, code, 0, 0); } static TILE_GET_INFO( aso_get_bg_tile_info ) { snk_state *state = machine.driver_data(); int code = state->m_bg_videoram[tile_index]; SET_TILE_INFO(1, state->m_bg_tile_offset + code, 0, 0); } static TILE_GET_INFO( tnk3_get_bg_tile_info ) { snk_state *state = machine.driver_data(); int attr = state->m_bg_videoram[2*tile_index+1]; int code = state->m_bg_videoram[2*tile_index] | ((attr & 0x30) << 4); int color = (attr & 0xf) ^ 8; SET_TILE_INFO(1, code, color, 0); } static TILE_GET_INFO( ikari_get_bg_tile_info ) { snk_state *state = machine.driver_data(); int attr = state->m_bg_videoram[2*tile_index+1]; int code = state->m_bg_videoram[2*tile_index] | ((attr & 0x03) << 8); int color = (attr & 0x70) >> 4; SET_TILE_INFO(1, code, color, 0); } static TILE_GET_INFO( gwar_get_bg_tile_info ) { snk_state *state = machine.driver_data(); int attr = state->m_bg_videoram[2*tile_index+1]; int code = state->m_bg_videoram[2*tile_index] | ((attr & 0x0f) << 8); int color = (attr & 0xf0) >> 4; if (state->m_is_psychos) // psychos has a separate palette bank bit color &= 7; SET_TILE_INFO(1, code, color, 0); // bermudat, tdfever use FFFF to blank the background. // (still call SET_TILE_INFO, otherwise problems might occur on boot when // the tile data hasn't been initialised) if (code >= machine.gfx[1]->total_elements) tileinfo->pen_data = state->m_empty_tile; } /**************************************************************************************/ static VIDEO_START( snk_3bpp_shadow ) { snk_state *state = machine.driver_data(); int i; if(!(machine.config().m_video_attributes & VIDEO_HAS_SHADOWS)) fatalerror("driver should use VIDEO_HAS_SHADOWS"); /* prepare shadow draw table */ for(i = 0; i <= 5; i++) state->m_drawmode_table[i] = DRAWMODE_SOURCE; state->m_drawmode_table[6] = (machine.config().m_video_attributes & VIDEO_HAS_SHADOWS) ? DRAWMODE_SHADOW : DRAWMODE_SOURCE; state->m_drawmode_table[7] = DRAWMODE_NONE; for (i = 0x000;i < 0x400;i++) machine.shadow_table[i] = i | 0x200; } static VIDEO_START( snk_4bpp_shadow ) { snk_state *state = machine.driver_data(); int i; if(!(machine.config().m_video_attributes & VIDEO_HAS_SHADOWS)) fatalerror("driver should use VIDEO_HAS_SHADOWS"); /* prepare shadow draw table */ for(i = 0; i <= 13; i++) state->m_drawmode_table[i] = DRAWMODE_SOURCE; state->m_drawmode_table[14] = DRAWMODE_SHADOW; state->m_drawmode_table[15] = DRAWMODE_NONE; /* all palette entries are not affected by shadow sprites... */ for (i = 0x000;i < 0x400;i++) machine.shadow_table[i] = i; /* ... except for tilemap colors */ for (i = 0x200;i < 0x300;i++) machine.shadow_table[i] = i + 0x100; } VIDEO_START( marvins ) { snk_state *state = machine.driver_data(); VIDEO_START_CALL(snk_3bpp_shadow); state->m_tx_tilemap = tilemap_create(machine, marvins_get_tx_tile_info, marvins_tx_scan_cols, 8, 8, 36, 28); state->m_fg_tilemap = tilemap_create(machine, marvins_get_fg_tile_info, tilemap_scan_cols, 8, 8, 64, 32); state->m_bg_tilemap = tilemap_create(machine, marvins_get_bg_tile_info, tilemap_scan_cols, 8, 8, 64, 32); tilemap_set_transparent_pen(state->m_tx_tilemap, 15); tilemap_set_scrolldy(state->m_tx_tilemap, 8, 8); tilemap_set_transparent_pen(state->m_fg_tilemap, 15); tilemap_set_scrolldx(state->m_fg_tilemap, 15, 31); tilemap_set_scrolldy(state->m_fg_tilemap, 8, -32); tilemap_set_scrolldx(state->m_bg_tilemap, 15, 31); tilemap_set_scrolldy(state->m_bg_tilemap, 8, -32); state->m_tx_tile_offset = 0; } VIDEO_START( jcross ) { snk_state *state = machine.driver_data(); VIDEO_START_CALL(snk_3bpp_shadow); state->m_tx_tilemap = tilemap_create(machine, marvins_get_tx_tile_info, marvins_tx_scan_cols, 8, 8, 36, 28); state->m_bg_tilemap = tilemap_create(machine, aso_get_bg_tile_info, tilemap_scan_cols, 8, 8, 64, 64); tilemap_set_transparent_pen(state->m_tx_tilemap, 15); tilemap_set_scrolldy(state->m_tx_tilemap, 8, 8); tilemap_set_scrolldx(state->m_bg_tilemap, 15, 24); tilemap_set_scrolldy(state->m_bg_tilemap, 8, -32); state->m_num_sprites = 25; state->m_yscroll_mask = 0x1ff; state->m_bg_tile_offset = 0; state->m_tx_tile_offset = 0; } VIDEO_START( sgladiat ) { snk_state *state = machine.driver_data(); VIDEO_START_CALL(snk_3bpp_shadow); state->m_tx_tilemap = tilemap_create(machine, marvins_get_tx_tile_info, marvins_tx_scan_cols, 8, 8, 36, 28); state->m_bg_tilemap = tilemap_create(machine, aso_get_bg_tile_info, tilemap_scan_cols, 8, 8, 64, 32); tilemap_set_transparent_pen(state->m_tx_tilemap, 15); tilemap_set_scrolldy(state->m_tx_tilemap, 8, 8); tilemap_set_scrolldx(state->m_bg_tilemap, 15, 24); tilemap_set_scrolldy(state->m_bg_tilemap, 8, -32); state->m_num_sprites = 25; state->m_yscroll_mask = 0x0ff; state->m_bg_tile_offset = 0; state->m_tx_tile_offset = 0; } VIDEO_START( hal21 ) { snk_state *state = machine.driver_data(); VIDEO_START_CALL(jcross); tilemap_set_scrolldy(state->m_bg_tilemap, 8, -32+256); state->m_num_sprites = 50; state->m_yscroll_mask = 0x1ff; } VIDEO_START( aso ) { snk_state *state = machine.driver_data(); VIDEO_START_CALL(jcross); tilemap_set_scrolldx(state->m_bg_tilemap, 15+256, 24+256); state->m_num_sprites = 50; state->m_yscroll_mask = 0x1ff; } VIDEO_START( tnk3 ) { snk_state *state = machine.driver_data(); VIDEO_START_CALL(snk_3bpp_shadow); state->m_tx_tilemap = tilemap_create(machine, marvins_get_tx_tile_info, marvins_tx_scan_cols, 8, 8, 36, 28); state->m_bg_tilemap = tilemap_create(machine, tnk3_get_bg_tile_info, tilemap_scan_cols, 8, 8, 64, 64); tilemap_set_transparent_pen(state->m_tx_tilemap, 15); tilemap_set_scrolldy(state->m_tx_tilemap, 8, 8); tilemap_set_scrolldx(state->m_bg_tilemap, 15, 24); tilemap_set_scrolldy(state->m_bg_tilemap, 8, -32); state->m_num_sprites = 50; state->m_yscroll_mask = 0x1ff; state->m_tx_tile_offset = 0; } VIDEO_START( ikari ) { snk_state *state = machine.driver_data(); VIDEO_START_CALL(snk_3bpp_shadow); state->m_tx_tilemap = tilemap_create(machine, ikari_get_tx_tile_info, marvins_tx_scan_cols, 8, 8, 36, 28); state->m_bg_tilemap = tilemap_create(machine, ikari_get_bg_tile_info, tilemap_scan_cols, 16, 16, 32, 32); tilemap_set_transparent_pen(state->m_tx_tilemap, 15); tilemap_set_scrolldy(state->m_tx_tilemap, 8, 8); tilemap_set_scrolldx(state->m_bg_tilemap, 15, 24); tilemap_set_scrolldy(state->m_bg_tilemap, 8, -32); state->m_tx_tile_offset = 0; } VIDEO_START( gwar ) { snk_state *state = machine.driver_data(); int i; /* prepare drawmode table */ for(i = 0; i <= 14; i++) state->m_drawmode_table[i] = DRAWMODE_SOURCE; state->m_drawmode_table[15] = DRAWMODE_NONE; memset(state->m_empty_tile, 0xf, sizeof(state->m_empty_tile)); state->m_tx_tilemap = tilemap_create(machine, gwar_get_tx_tile_info, tilemap_scan_cols, 8, 8, 50, 32); state->m_bg_tilemap = tilemap_create(machine, gwar_get_bg_tile_info, tilemap_scan_cols, 16, 16, 32, 32); tilemap_set_transparent_pen(state->m_tx_tilemap, 15); tilemap_set_scrolldx(state->m_bg_tilemap, 16, 143); tilemap_set_scrolldy(state->m_bg_tilemap, 0, -32); state->m_tx_tile_offset = 0; state->m_is_psychos = 0; } VIDEO_START( psychos ) { snk_state *state = machine.driver_data(); VIDEO_START_CALL(gwar); state->m_is_psychos = 1; } VIDEO_START( tdfever ) { VIDEO_START_CALL(gwar); VIDEO_START_CALL(snk_4bpp_shadow); } /**************************************************************************************/ WRITE8_HANDLER( snk_tx_videoram_w ) { snk_state *state = space->machine().driver_data(); state->m_tx_videoram[offset] = data; tilemap_mark_tile_dirty(state->m_tx_tilemap, offset); } WRITE8_HANDLER( marvins_fg_videoram_w ) { snk_state *state = space->machine().driver_data(); state->m_fg_videoram[offset] = data; tilemap_mark_tile_dirty(state->m_fg_tilemap, offset); } WRITE8_HANDLER( marvins_bg_videoram_w ) { snk_state *state = space->machine().driver_data(); state->m_bg_videoram[offset] = data; tilemap_mark_tile_dirty(state->m_bg_tilemap, offset); } WRITE8_HANDLER( snk_bg_videoram_w ) { snk_state *state = space->machine().driver_data(); state->m_bg_videoram[offset] = data; tilemap_mark_tile_dirty(state->m_bg_tilemap, offset >> 1); } WRITE8_HANDLER( snk_fg_scrollx_w ) { snk_state *state = space->machine().driver_data(); state->m_fg_scrollx = (state->m_fg_scrollx & ~0xff) | data; } WRITE8_HANDLER( snk_fg_scrolly_w ) { snk_state *state = space->machine().driver_data(); state->m_fg_scrolly = (state->m_fg_scrolly & ~0xff) | data; } WRITE8_HANDLER( snk_bg_scrollx_w ) { snk_state *state = space->machine().driver_data(); state->m_bg_scrollx = (state->m_bg_scrollx & ~0xff) | data; } WRITE8_HANDLER( snk_bg_scrolly_w ) { snk_state *state = space->machine().driver_data(); state->m_bg_scrolly = (state->m_bg_scrolly & ~0xff) | data; } WRITE8_HANDLER( snk_sp16_scrollx_w ) { snk_state *state = space->machine().driver_data(); state->m_sp16_scrollx = (state->m_sp16_scrollx & ~0xff) | data; } WRITE8_HANDLER( snk_sp16_scrolly_w ) { snk_state *state = space->machine().driver_data(); state->m_sp16_scrolly = (state->m_sp16_scrolly & ~0xff) | data; } WRITE8_HANDLER( snk_sp32_scrollx_w ) { snk_state *state = space->machine().driver_data(); state->m_sp32_scrollx = (state->m_sp32_scrollx & ~0xff) | data; } WRITE8_HANDLER( snk_sp32_scrolly_w ) { snk_state *state = space->machine().driver_data(); state->m_sp32_scrolly = (state->m_sp32_scrolly & ~0xff) | data; } WRITE8_HANDLER( snk_sprite_split_point_w ) { snk_state *state = space->machine().driver_data(); state->m_sprite_split_point = data; } WRITE8_HANDLER( marvins_palette_bank_w ) { snk_state *state = space->machine().driver_data(); tilemap_set_palette_offset(state->m_bg_tilemap, data & 0x70); tilemap_set_palette_offset(state->m_fg_tilemap, (data & 0x07) << 4); } WRITE8_HANDLER( marvins_flipscreen_w ) { flip_screen_set(space->machine(), data & 0x80); // other bits unknown } WRITE8_HANDLER( sgladiat_flipscreen_w ) { snk_state *state = space->machine().driver_data(); flip_screen_set(space->machine(), data & 0x80); tilemap_set_palette_offset(state->m_bg_tilemap, ((data & 0xf) ^ 8) << 4); // other bits unknown } WRITE8_HANDLER( hal21_flipscreen_w ) { snk_state *state = space->machine().driver_data(); flip_screen_set(space->machine(), data & 0x80); tilemap_set_palette_offset(state->m_bg_tilemap, ((data & 0xf) ^ 8) << 4); if (state->m_bg_tile_offset != ((data & 0x20) << 3)) { state->m_bg_tile_offset = (data & 0x20) << 3; tilemap_mark_all_tiles_dirty(state->m_bg_tilemap); } // other bits unknown } WRITE8_HANDLER( marvins_scroll_msb_w ) { snk_state *state = space->machine().driver_data(); state->m_bg_scrollx = (state->m_bg_scrollx & 0xff) | ((data & 0x04) << 6); state->m_fg_scrollx = (state->m_fg_scrollx & 0xff) | ((data & 0x02) << 7); state->m_sp16_scrollx = (state->m_sp16_scrollx & 0xff) | ((data & 0x01) << 8); } WRITE8_HANDLER( jcross_scroll_msb_w ) { snk_state *state = space->machine().driver_data(); state->m_bg_scrolly = (state->m_bg_scrolly & 0xff) | ((data & 0x10) << 4); state->m_sp16_scrolly = (state->m_sp16_scrolly & 0xff) | ((data & 0x08) << 5); state->m_bg_scrollx = (state->m_bg_scrollx & 0xff) | ((data & 0x02) << 7); state->m_sp16_scrollx = (state->m_sp16_scrollx & 0xff) | ((data & 0x01) << 8); } WRITE8_HANDLER( sgladiat_scroll_msb_w ) { snk_state *state = space->machine().driver_data(); state->m_bg_scrollx = (state->m_bg_scrollx & 0xff) | ((data & 0x02) << 7); state->m_sp16_scrollx = (state->m_sp16_scrollx & 0xff) | ((data & 0x01) << 8); } WRITE8_HANDLER( aso_videoattrs_w ) { /* video attributes: X------- -X------ --X----- flip screen ---X---- scrolly MSB (background) ----X--- scrolly MSB (sprites) -----X-- ------X- scrollx MSB (background) -------X scrollx MSB (sprites) */ snk_state *state = space->machine().driver_data(); flip_screen_set(space->machine(), data & 0x20); state->m_bg_scrolly = (state->m_bg_scrolly & 0xff) | ((data & 0x10) << 4); state->m_sp16_scrolly = (state->m_sp16_scrolly & 0xff) | ((data & 0x08) << 5); state->m_bg_scrollx = (state->m_bg_scrollx & 0xff) | ((data & 0x02) << 7); state->m_sp16_scrollx = (state->m_sp16_scrollx & 0xff) | ((data & 0x01) << 8); } WRITE8_HANDLER( tnk3_videoattrs_w ) { /* video attributes: X------- flip screen -X------ character bank (for text layer) --X----- ---X---- scrolly MSB (background) ----X--- scrolly MSB (sprites) -----X-- ------X- scrollx MSB (background) -------X scrollx MSB (sprites) */ snk_state *state = space->machine().driver_data(); flip_screen_set(space->machine(), data & 0x80); if (state->m_tx_tile_offset != ((data & 0x40) << 2)) { state->m_tx_tile_offset = (data & 0x40) << 2; tilemap_mark_all_tiles_dirty(state->m_tx_tilemap); } state->m_bg_scrolly = (state->m_bg_scrolly & 0xff) | ((data & 0x10) << 4); state->m_sp16_scrolly = (state->m_sp16_scrolly & 0xff) | ((data & 0x08) << 5); state->m_bg_scrollx = (state->m_bg_scrollx & 0xff) | ((data & 0x02) << 7); state->m_sp16_scrollx = (state->m_sp16_scrollx & 0xff) | ((data & 0x01) << 8); } WRITE8_HANDLER( aso_bg_bank_w ) { snk_state *state = space->machine().driver_data(); tilemap_set_palette_offset(state->m_bg_tilemap, ((data & 0xf) ^ 8) << 4); if (state->m_bg_tile_offset != ((data & 0x30) << 4)) { state->m_bg_tile_offset = (data & 0x30) << 4; tilemap_mark_all_tiles_dirty(state->m_bg_tilemap); } } WRITE8_HANDLER( ikari_bg_scroll_msb_w ) { snk_state *state = space->machine().driver_data(); state->m_bg_scrollx = (state->m_bg_scrollx & 0xff) | ((data & 0x02) << 7); state->m_bg_scrolly = (state->m_bg_scrolly & 0xff) | ((data & 0x01) << 8); } WRITE8_HANDLER( ikari_sp_scroll_msb_w ) { snk_state *state = space->machine().driver_data(); state->m_sp32_scrollx = (state->m_sp32_scrollx & 0xff) | ((data & 0x20) << 3); state->m_sp16_scrollx = (state->m_sp16_scrollx & 0xff) | ((data & 0x10) << 4); state->m_sp32_scrolly = (state->m_sp32_scrolly & 0xff) | ((data & 0x08) << 5); state->m_sp16_scrolly = (state->m_sp16_scrolly & 0xff) | ((data & 0x04) << 6); } WRITE8_HANDLER( ikari_unknown_video_w ) { /* meaning of 0xc980 uncertain. Normally 0x20, ikaria/ikarijp sets it to 0x31 during test mode. Changing char bank is necessary to fix the display during the hard flags test and the test grid. Changing palette bank is necessary to fix colors in test mode. */ snk_state *state = space->machine().driver_data(); if (data != 0x20 && // normal data != 0x31 && // ikari test data != 0xaa) // victroad spurious during boot popmessage("attrs %02x contact MAMEDEV", data); tilemap_set_palette_offset(state->m_tx_tilemap, (data & 0x01) << 4); if (state->m_tx_tile_offset != ((data & 0x10) << 4)) { state->m_tx_tile_offset = (data & 0x10) << 4; tilemap_mark_all_tiles_dirty(state->m_tx_tilemap); } } WRITE8_HANDLER( gwar_tx_bank_w ) { snk_state *state = space->machine().driver_data(); tilemap_set_palette_offset(state->m_tx_tilemap, (data & 0xf) << 4); if (state->m_tx_tile_offset != ((data & 0x30) << 4)) { state->m_tx_tile_offset = (data & 0x30) << 4; tilemap_mark_all_tiles_dirty(state->m_tx_tilemap); } if (state->m_is_psychos) tilemap_set_palette_offset(state->m_bg_tilemap, (data & 0x80)); } WRITE8_HANDLER( gwar_videoattrs_w ) { snk_state *state = space->machine().driver_data(); flip_screen_set(space->machine(), data & 0x04); state->m_sp32_scrollx = (state->m_sp32_scrollx & 0xff) | ((data & 0x80) << 1); state->m_sp16_scrollx = (state->m_sp16_scrollx & 0xff) | ((data & 0x40) << 2); state->m_sp32_scrolly = (state->m_sp32_scrolly & 0xff) | ((data & 0x20) << 3); state->m_sp16_scrolly = (state->m_sp16_scrolly & 0xff) | ((data & 0x10) << 4); state->m_bg_scrollx = (state->m_bg_scrollx & 0xff) | ((data & 0x02) << 7); state->m_bg_scrolly = (state->m_bg_scrolly & 0xff) | ((data & 0x01) << 8); } WRITE8_HANDLER( gwara_videoattrs_w ) { snk_state *state = space->machine().driver_data(); flip_screen_set(space->machine(), data & 0x10); state->m_bg_scrollx = (state->m_bg_scrollx & 0xff) | ((data & 0x02) << 7); state->m_bg_scrolly = (state->m_bg_scrolly & 0xff) | ((data & 0x01) << 8); } WRITE8_HANDLER( gwara_sp_scroll_msb_w ) { snk_state *state = space->machine().driver_data(); state->m_sp32_scrollx = (state->m_sp32_scrollx & 0xff) | ((data & 0x20) << 3); state->m_sp16_scrollx = (state->m_sp16_scrollx & 0xff) | ((data & 0x10) << 4); state->m_sp32_scrolly = (state->m_sp32_scrolly & 0xff) | ((data & 0x08) << 5); state->m_sp16_scrolly = (state->m_sp16_scrolly & 0xff) | ((data & 0x04) << 6); } WRITE8_HANDLER( tdfever_sp_scroll_msb_w ) { snk_state *state = space->machine().driver_data(); state->m_sp32_scrolly = (state->m_sp32_scrolly & 0xff) | ((data & 0x80) << 1); state->m_sp32_scrollx = (state->m_sp32_scrollx & 0xff) | ((data & 0x40) << 2); } WRITE8_HANDLER( tdfever_spriteram_w ) { snk_state *state = space->machine().driver_data(); /* partial updates avoid flickers in the fsoccer radar. */ if (offset < 0x80 && state->m_spriteram[offset] != data) { int vpos = space->machine().primary_screen->vpos(); if (vpos > 0) space->machine().primary_screen->update_partial(vpos - 1); } state->m_spriteram[offset] = data; } /**************************************************************************************/ static void marvins_draw_sprites(running_machine &machine, bitmap_t *bitmap, const rectangle *cliprect, const int scrollx, const int scrolly, const int from, const int to) { snk_state *state = machine.driver_data(); const gfx_element *gfx = machine.gfx[3]; const UINT8 *source, *finish; source = state->m_spriteram + from*4; finish = state->m_spriteram + to*4; while( source 512-16) sx -= 512; if (sy > 256-16) sy -= 256; drawgfx_transtable(bitmap,cliprect,gfx, tile_number, color, flipx, flipy, sx, sy, state->m_drawmode_table, machine.shadow_table); source+=4; } } static void tnk3_draw_sprites(running_machine &machine, bitmap_t *bitmap, const rectangle *cliprect, const int xscroll, const int yscroll) { snk_state *state = machine.driver_data(); UINT8 *spriteram = state->m_spriteram; const gfx_element *gfx = machine.gfx[2]; const int size = gfx->width; int tile_number, attributes, color, sx, sy; int xflip,yflip; int offs; /* jcross and sgladiat have only 25 sprites, the others 50 */ /* jcross has 256 tiles, attribute bit 6 is unused and bit 5 is y-flip */ /* sgladiat and tnk3 have 512 tiles, bit 6 is bank and bit 5 is y-flip */ /* athena has 1024 tiles, bit 6 and bit 5 are bank */ for (offs = 0; offs < state->m_num_sprites*4; offs += 4) { tile_number = spriteram[offs+1]; attributes = spriteram[offs+3]; color = attributes & 0xf; sx = xscroll + 301 - size - spriteram[offs+2]; sy = -yscroll + 7 - size + spriteram[offs]; sx += (attributes & 0x80) << 1; sy += (attributes & 0x10) << 4; xflip = 0; yflip = 0; if (gfx->total_elements > 256) // all except jcross { tile_number |= (attributes & 0x40) << 2; } if (gfx->total_elements > 512) // athena { tile_number |= (attributes & 0x20) << 4; } else // all others { yflip = attributes & 0x20; } if (flip_screen_get(machine)) { sx = 89 - size - sx; // this causes slight misalignment in tnk3 but is correct for athena and fitegolf sy = 262 - size - sy; xflip = !xflip; yflip = !yflip; } sx &= 0x1ff; sy &= state->m_yscroll_mask; // sgladiat apparently has only 256 pixels of vertical scrolling range if (sx > 512-size) sx -= 512; if (sy > (state->m_yscroll_mask+1)-size) sy -= (state->m_yscroll_mask+1); drawgfx_transtable(bitmap,cliprect,gfx, tile_number, color, xflip,yflip, sx,sy, state->m_drawmode_table, machine.shadow_table); } } static void ikari_draw_sprites(running_machine &machine, bitmap_t *bitmap, const rectangle *cliprect, const int start, const int xscroll, const int yscroll, const UINT8 *source, const int gfxnum ) { snk_state *state = machine.driver_data(); const gfx_element *gfx = machine.gfx[gfxnum]; const int size = gfx->width; int tile_number, attributes, color, sx, sy; int which, finish; finish = (start+25)*4; for (which = start*4; which < finish; which += 4) { tile_number = source[which+1]; attributes = source[which+3]; color = attributes & 0xf; sx = xscroll + 300 - size - source[which+2]; sy = -yscroll + 7 - size + source[which]; sx += (attributes & 0x80) << 1; sy += (attributes & 0x10) << 4; switch (size) { case 16: tile_number |= (attributes & 0x60) << 3; break; case 32: tile_number |= (attributes & 0x40) << 2; break; } sx &= 0x1ff; sy &= 0x1ff; if (sx > 512-size) sx -= 512; if (sy > 512-size) sy -= 512; drawgfx_transtable(bitmap,cliprect,gfx, tile_number, color, 0,0, sx,sy, state->m_drawmode_table, machine.shadow_table); } } /**************************************************************/ /* Sprite Format ------------- byte0: y offset byte1: tile number byte2: x offset byte3: attributes 32x32 attributes: 76543210 ----xxxx (color) ---x---- (y offset bit8) -xx----- (bank number) x------- (x offset bit8) 16x16 attributes: 76543210 -----xxx (color) ---x---- (y offset bit8) -xx-x--- (bank number) x------- (x offset bit8) */ static void tdfever_draw_sprites(running_machine &machine, bitmap_t *bitmap, const rectangle *cliprect, const int xscroll, const int yscroll, const UINT8 *source, const int gfxnum, const int hw_xflip, const int from, const int to ) { snk_state *state = machine.driver_data(); const gfx_element *gfx = machine.gfx[gfxnum]; const int size = gfx->width; int tile_number, attributes, sx, sy, color; int which; int flipx, flipy; for(which = from*4; which < to*4; which+=4) { tile_number = source[which+1]; attributes = source[which+3]; color = attributes & 0x0f; sx = -xscroll - 9 + source[which+2]; sy = -yscroll + 1 - size + source[which]; sx += (attributes & 0x80) << 1; sy += (attributes & 0x10) << 4; switch (size) { case 16: tile_number |= ((attributes & 0x08) << 5) | ((attributes & 0x60) << 4); color &= 7; // attribute bit 3 is used for bank select if (from == 0) color |= 8; // low priority sprites use the other palette bank break; case 32: tile_number |= (attributes & 0x60) << 3; break; } flipx = hw_xflip; flipy = 0; if (hw_xflip) sx = 495 - size - sx; if (flip_screen_get(machine)) { sx = 495 - size - sx; sy = 258 - size - sy; flipx = !flipx; flipy = !flipy; } sx &= 0x1ff; sy &= 0x1ff; if (sx > 512-size) sx -= 512; if (sy > 512-size) sy -= 512; drawgfx_transtable(bitmap,cliprect,gfx, tile_number, color, flipx,flipy, sx,sy, state->m_drawmode_table, machine.shadow_table); } } /**************************************************************/ SCREEN_UPDATE( marvins ) { snk_state *state = screen->machine().driver_data(); tilemap_set_scrollx(state->m_bg_tilemap, 0, state->m_bg_scrollx); tilemap_set_scrolly(state->m_bg_tilemap, 0, state->m_bg_scrolly); tilemap_set_scrollx(state->m_fg_tilemap, 0, state->m_fg_scrollx); tilemap_set_scrolly(state->m_fg_tilemap, 0, state->m_fg_scrolly); tilemap_draw(bitmap, cliprect, state->m_bg_tilemap, 0, 0); marvins_draw_sprites(screen->machine(), bitmap, cliprect, state->m_sp16_scrollx, state->m_sp16_scrolly, 0, state->m_sprite_split_point>>2); tilemap_draw(bitmap, cliprect, state->m_fg_tilemap, 0, 0); marvins_draw_sprites(screen->machine(), bitmap, cliprect, state->m_sp16_scrollx, state->m_sp16_scrolly, state->m_sprite_split_point>>2, 25); tilemap_draw(bitmap, cliprect, state->m_tx_tilemap, 0, 0); return 0; } SCREEN_UPDATE( tnk3 ) { snk_state *state = screen->machine().driver_data(); tilemap_set_scrollx(state->m_bg_tilemap, 0, state->m_bg_scrollx); tilemap_set_scrolly(state->m_bg_tilemap, 0, state->m_bg_scrolly); tilemap_draw(bitmap, cliprect, state->m_bg_tilemap, 0, 0); tnk3_draw_sprites(screen->machine(), bitmap, cliprect, state->m_sp16_scrollx, state->m_sp16_scrolly); tilemap_draw(bitmap, cliprect, state->m_tx_tilemap, 0, 0); return 0; } SCREEN_UPDATE( ikari ) { snk_state *state = screen->machine().driver_data(); tilemap_set_scrollx(state->m_bg_tilemap, 0, state->m_bg_scrollx); tilemap_set_scrolly(state->m_bg_tilemap, 0, state->m_bg_scrolly); tilemap_draw(bitmap, cliprect, state->m_bg_tilemap, 0, 0); ikari_draw_sprites(screen->machine(), bitmap, cliprect, 0, state->m_sp16_scrollx, state->m_sp16_scrolly, state->m_spriteram + 0x800, 2 ); ikari_draw_sprites(screen->machine(), bitmap, cliprect, 0, state->m_sp32_scrollx, state->m_sp32_scrolly, state->m_spriteram, 3 ); ikari_draw_sprites(screen->machine(), bitmap, cliprect, 25, state->m_sp16_scrollx, state->m_sp16_scrolly, state->m_spriteram + 0x800, 2 ); tilemap_draw(bitmap, cliprect, state->m_tx_tilemap, 0, 0); return 0; } SCREEN_UPDATE( gwar ) { snk_state *state = screen->machine().driver_data(); tilemap_set_scrollx(state->m_bg_tilemap, 0, state->m_bg_scrollx); tilemap_set_scrolly(state->m_bg_tilemap, 0, state->m_bg_scrolly); tilemap_draw(bitmap, cliprect, state->m_bg_tilemap, 0, 0); tdfever_draw_sprites(screen->machine(), bitmap, cliprect, state->m_sp16_scrollx, state->m_sp16_scrolly, state->m_spriteram + 0x800, 2, 0, 0, state->m_sprite_split_point ); tdfever_draw_sprites(screen->machine(), bitmap, cliprect, state->m_sp32_scrollx, state->m_sp32_scrolly, state->m_spriteram, 3, 0, 0, 32 ); tdfever_draw_sprites(screen->machine(), bitmap, cliprect, state->m_sp16_scrollx, state->m_sp16_scrolly, state->m_spriteram + 0x800, 2, 0, state->m_sprite_split_point, 64 ); tilemap_draw(bitmap, cliprect, state->m_tx_tilemap, 0, 0); return 0; } SCREEN_UPDATE( tdfever ) { snk_state *state = screen->machine().driver_data(); tilemap_set_scrollx(state->m_bg_tilemap, 0, state->m_bg_scrollx); tilemap_set_scrolly(state->m_bg_tilemap, 0, state->m_bg_scrolly); tilemap_draw(bitmap, cliprect, state->m_bg_tilemap, 0, 0); tdfever_draw_sprites(screen->machine(), bitmap, cliprect, state->m_sp32_scrollx, state->m_sp32_scrolly, state->m_spriteram, 2, 1, 0, 32 ); tilemap_draw(bitmap, cliprect, state->m_tx_tilemap, 0, 0); return 0; }