/*************************************************************************** Legionnaire / Heated Barrel video hardware (derived from D-Con) ***************************************************************************/ #include "emu.h" #include "includes/legionna.h" /******************************************************************************/ void heatbrl_setgfxbank(running_machine &machine, UINT16 data) { legionna_state *state = machine.driver_data(); state->m_back_gfx_bank = (data &0x4000) >> 2; } /*xxx- --- ---- ---- banking*/ void denjinmk_setgfxbank(running_machine &machine, UINT16 data) { legionna_state *state = machine.driver_data(); state->m_fore_gfx_bank = (data &0x2000) >> 1;//??? state->m_back_gfx_bank = (data &0x4000) >> 2; state->m_mid_gfx_bank = (data &0x8000) >> 3;//??? tilemap_mark_all_tiles_dirty (state->m_background_layer); tilemap_mark_all_tiles_dirty (state->m_foreground_layer); tilemap_mark_all_tiles_dirty (state->m_midground_layer); tilemap_mark_all_tiles_dirty (state->m_text_layer); } WRITE16_HANDLER( legionna_background_w ) { legionna_state *state = space->machine().driver_data(); COMBINE_DATA(&state->m_back_data[offset]); tilemap_mark_tile_dirty(state->m_background_layer,offset); } WRITE16_HANDLER( legionna_midground_w ) { legionna_state *state = space->machine().driver_data(); COMBINE_DATA(&state->m_mid_data[offset]); tilemap_mark_tile_dirty(state->m_midground_layer,offset); } WRITE16_HANDLER( legionna_foreground_w ) { legionna_state *state = space->machine().driver_data(); COMBINE_DATA(&state->m_fore_data[offset]); tilemap_mark_tile_dirty(state->m_foreground_layer,offset); } WRITE16_HANDLER( legionna_text_w ) { legionna_state *state = space->machine().driver_data(); COMBINE_DATA(&state->m_textram[offset]); tilemap_mark_tile_dirty(state->m_text_layer,offset); } static TILE_GET_INFO( get_back_tile_info ) { legionna_state *state = machine.driver_data(); int tile=state->m_back_data[tile_index]; int color=(tile>>12)&0xf; tile &= 0xfff; tile |= state->m_back_gfx_bank; /* Heatbrl uses banking */ SET_TILE_INFO(1,tile,color,0); } static TILE_GET_INFO( get_mid_tile_info ) { legionna_state *state = machine.driver_data(); int tile=state->m_mid_data[tile_index]; int color=(tile>>12)&0xf; tile &= 0xfff; SET_TILE_INFO(5,tile,color,0); } static TILE_GET_INFO( get_mid_tile_info_denji ) { legionna_state *state = machine.driver_data(); int tile=state->m_mid_data[tile_index]; int color=(tile>>12)&0xf; tile &= 0xfff; tile |= state->m_mid_gfx_bank; SET_TILE_INFO(5,tile,color,0); } static TILE_GET_INFO( get_mid_tile_info_cupsoc ) { legionna_state *state = machine.driver_data(); int tile=state->m_mid_data[tile_index]; int color=(tile>>12)&0xf; tile &= 0xfff; tile |= 0x1000; color += 0x10; SET_TILE_INFO(1,tile,color,0); } static TILE_GET_INFO( get_fore_tile_info ) /* this is giving bad tiles... */ { legionna_state *state = machine.driver_data(); int tile=state->m_fore_data[tile_index]; int color=(tile>>12)&0xf; // legionnaire tile numbers / gfx set wrong, see screen after coin insertion tile &= 0xfff; SET_TILE_INFO(4,tile,color,0); } static TILE_GET_INFO( get_fore_tile_info_denji ) { legionna_state *state = machine.driver_data(); int tile=state->m_fore_data[tile_index]; int color=(tile>>12)&0xf; tile &= 0xfff; tile |= state->m_fore_gfx_bank; SET_TILE_INFO(4,tile,color,0); } static TILE_GET_INFO( get_text_tile_info ) { legionna_state *state = machine.driver_data(); int tile = state->m_textram[tile_index]; int color=(tile>>12)&0xf; tile &= 0xfff; SET_TILE_INFO(0,tile,color,0); } VIDEO_START( legionna ) { legionna_state *state = machine.driver_data(); state->m_background_layer = tilemap_create(machine, get_back_tile_info,tilemap_scan_rows,16,16,32,32); state->m_foreground_layer = tilemap_create(machine, get_fore_tile_info,tilemap_scan_rows,16,16,32,32); state->m_midground_layer = tilemap_create(machine, get_mid_tile_info, tilemap_scan_rows,16,16,32,32); state->m_text_layer = tilemap_create(machine, get_text_tile_info,tilemap_scan_rows, 8,8,64,32); state->m_scrollram16 = auto_alloc_array(machine, UINT16, 0x60/2); state->m_sprite_xoffs = 0; state->m_sprite_yoffs = 0; state->m_has_extended_banking = 0; state->m_has_extended_priority = 0; tilemap_set_transparent_pen(state->m_background_layer,15); tilemap_set_transparent_pen(state->m_midground_layer,15); tilemap_set_transparent_pen(state->m_foreground_layer,15); tilemap_set_transparent_pen(state->m_text_layer,15); } VIDEO_START( denjinmk ) { legionna_state *state = machine.driver_data(); state->m_background_layer = tilemap_create(machine, get_back_tile_info,tilemap_scan_rows,16,16,32,32); state->m_foreground_layer = tilemap_create(machine, get_fore_tile_info_denji,tilemap_scan_rows,16,16,32,32); state->m_midground_layer = tilemap_create(machine, get_mid_tile_info_denji, tilemap_scan_rows,16,16,32,32); state->m_text_layer = tilemap_create(machine, get_text_tile_info,tilemap_scan_rows, 8,8,64,32); state->m_scrollram16 = auto_alloc_array(machine, UINT16, 0x60/2); state->m_sprite_xoffs = 0; state->m_sprite_yoffs = 0; state->m_has_extended_banking = 1; state->m_has_extended_priority = 0; tilemap_set_transparent_pen(state->m_background_layer,15); tilemap_set_transparent_pen(state->m_midground_layer,15); tilemap_set_transparent_pen(state->m_foreground_layer,15); tilemap_set_transparent_pen(state->m_text_layer,7);//? } VIDEO_START( cupsoc ) { legionna_state *state = machine.driver_data(); state->m_background_layer = tilemap_create(machine, get_back_tile_info,tilemap_scan_rows,16,16,32,32); state->m_foreground_layer = tilemap_create(machine, get_fore_tile_info,tilemap_scan_rows,16,16,32,32); state->m_midground_layer = tilemap_create(machine, get_mid_tile_info_cupsoc, tilemap_scan_rows,16,16,32,32); state->m_text_layer = tilemap_create(machine, get_text_tile_info,tilemap_scan_rows, 8,8,64,32); state->m_scrollram16 = auto_alloc_array(machine, UINT16, 0x60/2); state->m_sprite_xoffs = 0; state->m_sprite_yoffs = 0; state->m_has_extended_banking = 0; state->m_has_extended_priority = 1; tilemap_set_transparent_pen(state->m_background_layer,15); tilemap_set_transparent_pen(state->m_midground_layer,15); tilemap_set_transparent_pen(state->m_foreground_layer,15); tilemap_set_transparent_pen(state->m_text_layer,15); } VIDEO_START(grainbow) { legionna_state *state = machine.driver_data(); VIDEO_START_CALL(legionna); state->m_sprite_xoffs = state->m_sprite_yoffs = 16; state->m_has_extended_banking = 0; state->m_has_extended_priority = 1; } VIDEO_START(godzilla) { legionna_state *state = machine.driver_data(); VIDEO_START_CALL(legionna); state->m_has_extended_banking = 1; state->m_has_extended_priority = 0; } /************************************************************************* Legionnaire Spriteram (similar to Dcon) --------------------- It has "big sprites" created by setting width or height >0. Tile numbers are read consecutively. +0 x....... ........ Sprite enable +0 .x...... ........ Flip x +0 ..x..... ........ Flip y ??? +0 ...xxx.. ........ Width: do this many tiles horizontally +0 ......xx x....... Height: do this many tiles vertically +0 ........ .x...... Tile bank,used in Denjin Makai / extra Priority in Grainbow (to external pin?) +0 ........ ..xxxxxx Color bank +1 xx...... ........ Priority? (1=high?) +1 ..xxxxxx xxxxxxxx Tile number +2 ----xxxx xxxxxxxx X coordinate (signed) +3 b------- -------- more tile banking used by Denjin Makai +3 ----xxxx xxxxxxxx Y coordinate (signed) *************************************************************************/ static void draw_sprites(running_machine &machine, bitmap_t *bitmap,const rectangle *cliprect) { legionna_state *state = machine.driver_data(); UINT16 *spriteram16 = machine.generic.spriteram.u16; int offs,fx,fy,x,y,color,sprite,cur_pri; int dx,dy,ax,ay; int pri_mask; for (offs = 0;offs < 0x400;offs += 4) { UINT16 data = spriteram16[offs]; if (!(data &0x8000)) continue; pri_mask = 0; if (state->m_has_extended_priority) { cur_pri = (spriteram16[offs+1] & 0xc000) >> 14; if(data & 0x0040) { cur_pri |= 0x4; // definitely seems to be needed by grainbow } // // -4 behind bg? (mask sprites) // -32 behind mid // -256 behind tx // 0 above all // is the low bit REALLY priority? switch (cur_pri) { case 0: pri_mask = -256; break; // gumdam swamp monster l2 case 1: pri_mask = -256; break; // cupsoc case 2: pri_mask = -4; break; // masking effect for gundam l2 monster case 3: pri_mask = -4; break; // cupsoc (not sure what..) case 4: pri_mask = -32; break; // gundam level 2/3 player //case 5: pri_mask = 0; break; case 6: pri_mask = 0; break; // insert coin in gundam //case 7: pri_mask = 0; break; default: printf("unhandled pri %d\n",cur_pri); pri_mask=0; } } else { cur_pri = (spriteram16[offs+1] & 0xc000) >> 14; switch (cur_pri) { case 0: pri_mask = 0xfffc; break; //? case 1: pri_mask = 0xfffc; break; //? case 2: pri_mask = 0xfffc; break; // player sprites in legionnaire case 3: pri_mask = 0xfffe; break; // stuff that goes behind the playfield (barriers on train level in legionnaire) } } sprite = spriteram16[offs+1]; sprite &= 0x3fff; if (state->m_has_extended_banking) { if(data & 0x0040) { sprite |= 0x4000;//tile banking,used in Denjin Makai } if(spriteram16[offs+3] & 0x8000) { sprite |= 0x8000;//tile banking?,used in Denjin Makai } } y = spriteram16[offs+3]; x = spriteram16[offs+2]; /* heated barrel hardware seems to need 0x1ff with 0x100 sign bit for sprite warp, this doesn't work on denjin makai as the visible area is larger */ if (cliprect->max_x<(320-1)) { x&=0x1ff; y&=0x1ff; if (x&0x100) x-=0x200; if (y&0x100) y-=0x200; } else { x&=0xfff; y&=0xfff; if (x&0x800) x-=0x1000; if (y&0x800) y-=0x1000; } color = (data &0x3f) + 0x40; fx = (data &0x4000) >> 14; fy = (data &0x2000) >> 13; dy = ((data &0x0380) >> 7) + 1; dx = ((data &0x1c00) >> 10) + 1; if (!fx) { if(!fy) { for (ax=0; axm_sprite_xoffs,y+ay*16+state->m_sprite_yoffs, machine.priority_bitmap,pri_mask, 15); } } else { for (ax=0; axm_sprite_xoffs,y+(dy-ay-1)*16+state->m_sprite_yoffs, machine.priority_bitmap,pri_mask,15); } } } else { if(!fy) { for (ax=0; axm_sprite_xoffs,y+ay*16+state->m_sprite_yoffs, machine.priority_bitmap,pri_mask,15); } } else { for (ax=0; axm_sprite_xoffs,y+(dy-ay-1)*16+state->m_sprite_yoffs, machine.priority_bitmap,pri_mask, 15); } } } } } #define LAYER_DB 0 SCREEN_UPDATE( legionna ) { legionna_state *state = screen->machine().driver_data(); /* Setup the tilemaps */ tilemap_set_scrollx( state->m_background_layer, 0, state->m_scrollram16[0] ); tilemap_set_scrolly( state->m_background_layer, 0, state->m_scrollram16[1] ); tilemap_set_scrollx( state->m_midground_layer, 0, state->m_scrollram16[2] ); tilemap_set_scrolly( state->m_midground_layer, 0, state->m_scrollram16[3] ); tilemap_set_scrollx( state->m_foreground_layer, 0, state->m_scrollram16[4] ); tilemap_set_scrolly( state->m_foreground_layer, 0, state->m_scrollram16[5] ); tilemap_set_scrollx( state->m_text_layer, 0, 0/*state->m_scrollram16[6]*/ ); tilemap_set_scrolly( state->m_text_layer, 0, 0/*state->m_scrollram16[7]*/ ); bitmap_fill(screen->machine().priority_bitmap,cliprect,0); bitmap_fill(bitmap,cliprect,get_black_pen(screen->machine())); /* wrong color? */ /* state->m_layer_disable is a guess based on 'stage 1' screen in heatbrl */ if (!(state->m_layer_disable&0x0020)) tilemap_draw(bitmap,cliprect,state->m_foreground_layer,0, 0); if (!(state->m_layer_disable&0x0010)) tilemap_draw(bitmap,cliprect,state->m_midground_layer,0, 0); if (!(state->m_layer_disable&0x0002)) tilemap_draw(bitmap,cliprect,state->m_background_layer,0, 1); if (!(state->m_layer_disable&0x0001)) tilemap_draw(bitmap,cliprect,state->m_text_layer,0, 2); draw_sprites(screen->machine(),bitmap,cliprect); return 0; } SCREEN_UPDATE( godzilla ) { legionna_state *state = screen->machine().driver_data(); // tilemap_set_scrollx( state->m_text_layer, 0, 0 ); // tilemap_set_scrolly( state->m_text_layer, 0, 112 ); /* Setup the tilemaps */ tilemap_set_scrollx( state->m_background_layer, 0, state->m_scrollram16[0] ); tilemap_set_scrolly( state->m_background_layer, 0, state->m_scrollram16[1] ); tilemap_set_scrollx( state->m_midground_layer, 0, state->m_scrollram16[2] ); tilemap_set_scrolly( state->m_midground_layer, 0, state->m_scrollram16[3] ); tilemap_set_scrollx( state->m_foreground_layer, 0, state->m_scrollram16[4] ); tilemap_set_scrolly( state->m_foreground_layer, 0, state->m_scrollram16[5] ); tilemap_set_scrollx( state->m_text_layer, 0, 0/*state->m_scrollram16[6]*/ ); tilemap_set_scrolly( state->m_text_layer, 0, 0/*state->m_scrollram16[7]*/ ); bitmap_fill(bitmap,cliprect,0x0200); bitmap_fill(screen->machine().priority_bitmap,cliprect,0); if (!(state->m_layer_disable&0x0001)) tilemap_draw(bitmap,cliprect,state->m_background_layer,0,0); if (!(state->m_layer_disable&0x0002)) tilemap_draw(bitmap,cliprect,state->m_midground_layer,0,0); if (!(state->m_layer_disable&0x0004)) tilemap_draw(bitmap,cliprect,state->m_foreground_layer,0,1); if (!(state->m_layer_disable&0x0008)) tilemap_draw(bitmap,cliprect,state->m_text_layer,0,2); draw_sprites(screen->machine(),bitmap,cliprect); return 0; } SCREEN_UPDATE( grainbow ) { legionna_state *state = screen->machine().driver_data(); /* Setup the tilemaps */ tilemap_set_scrollx( state->m_background_layer, 0, state->m_scrollram16[0] ); tilemap_set_scrolly( state->m_background_layer, 0, state->m_scrollram16[1] ); tilemap_set_scrollx( state->m_midground_layer, 0, state->m_scrollram16[2] ); tilemap_set_scrolly( state->m_midground_layer, 0, state->m_scrollram16[3] ); tilemap_set_scrollx( state->m_foreground_layer, 0, state->m_scrollram16[4] ); tilemap_set_scrolly( state->m_foreground_layer, 0, state->m_scrollram16[5] ); tilemap_set_scrollx( state->m_text_layer, 0, 0/*state->m_scrollram16[6]*/ ); tilemap_set_scrolly( state->m_text_layer, 0, 0/*state->m_scrollram16[7]*/ ); bitmap_fill(bitmap,cliprect,get_black_pen(screen->machine())); bitmap_fill(screen->machine().priority_bitmap,cliprect,0); if(!(state->m_layer_disable & 1)) tilemap_draw(bitmap,cliprect,state->m_background_layer,0,1); if(!(state->m_layer_disable & 2)) tilemap_draw(bitmap,cliprect,state->m_midground_layer,0,2); if(!(state->m_layer_disable & 4)) tilemap_draw(bitmap,cliprect,state->m_foreground_layer,0,4); if(!(state->m_layer_disable & 8)) tilemap_draw(bitmap,cliprect,state->m_text_layer,0,8); draw_sprites(screen->machine(),bitmap,cliprect); return 0; }