From 8f84c7b10fb8de97447b96734d74d0138b07486c Mon Sep 17 00:00:00 2001 From: angelosa Date: Fri, 1 Jul 2016 21:38:59 +0200 Subject: [PATCH] Fixed priority issues in Legionnaire, Heated Barrel, Denjin Makai and Godzilla [Angelo Salese] --- src/mame/drivers/legionna.cpp | 14 +- src/mame/includes/legionna.h | 6 +- src/mame/machine/seibucop/seibucop_dma.hxx | 6 +- src/mame/video/legionna.cpp | 154 ++++++++++++++++----- 4 files changed, 129 insertions(+), 51 deletions(-) diff --git a/src/mame/drivers/legionna.cpp b/src/mame/drivers/legionna.cpp index d42a392e9bf..2d44e715579 100644 --- a/src/mame/drivers/legionna.cpp +++ b/src/mame/drivers/legionna.cpp @@ -245,14 +245,6 @@ static ADDRESS_MAP_START( godzilla_map, AS_PROGRAM, 16, legionna_state ) ADDRESS_MAP_END -/* did they swap the lines, or does the protection device swap the words during the DMA?? */ -WRITE16_MEMBER(legionna_state::wordswapram_w) -{ - offset^=1; - COMBINE_DATA(&m_wordswapram[offset]); -} - - static ADDRESS_MAP_START( denjinmk_map, AS_PROGRAM, 16, legionna_state ) AM_IMPORT_FROM( legionna_cop_mem ) AM_RANGE(0x000000, 0x0fffff) AM_ROM @@ -271,7 +263,7 @@ static ADDRESS_MAP_START( denjinmk_map, AS_PROGRAM, 16, legionna_state ) AM_RANGE(0x101800, 0x101fff) AM_RAM // _WRITE(legionna_foreground_w) AM_SHARE("fore_data") AM_RANGE(0x102000, 0x1027ff) AM_RAM // _WRITE(legionna_midground_w) AM_SHARE("mid_data") AM_RANGE(0x102800, 0x103fff) AM_RAM // _WRITE(legionna_text_w) AM_SHARE("textram") - AM_RANGE(0x104000, 0x104fff) AM_RAM_WRITE(wordswapram_w) AM_SHARE("wordswapram") + AM_RANGE(0x104000, 0x104fff) AM_RAM AM_RANGE(0x105000, 0x105fff) AM_RAM AM_SHARE("spriteram") AM_RANGE(0x106000, 0x107fff) AM_RAM AM_RANGE(0x108000, 0x11dfff) AM_RAM @@ -1279,7 +1271,7 @@ static MACHINE_CONFIG_START( heatbrl, legionna_state ) MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) MCFG_SCREEN_SIZE(36*8, 36*8) MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 0*8, 32*8-1) - MCFG_SCREEN_UPDATE_DRIVER(legionna_state, screen_update_legionna) + MCFG_SCREEN_UPDATE_DRIVER(legionna_state, screen_update_heatbrl) MCFG_SCREEN_PALETTE("palette") MCFG_DEVICE_ADD("crtc", SEIBU_CRTC, 0) @@ -1293,7 +1285,7 @@ static MACHINE_CONFIG_START( heatbrl, legionna_state ) MCFG_PALETTE_ADD_INIT_BLACK("palette", 128*16) //MCFG_PALETTE_FORMAT(xBBBBBGGGGGRRRRR) - MCFG_VIDEO_START_OVERRIDE(legionna_state,legionna) + MCFG_VIDEO_START_OVERRIDE(legionna_state,heatbrl) /* sound hardware */ SEIBU_SOUND_SYSTEM_YM3812_INTERFACE(14318180/4,1320000) diff --git a/src/mame/includes/legionna.h b/src/mame/includes/legionna.h index 6d7dfe2d167..335439c5786 100644 --- a/src/mame/includes/legionna.h +++ b/src/mame/includes/legionna.h @@ -24,7 +24,6 @@ public: m_gfxdecode(*this, "gfxdecode"), m_palette(*this, "palette"), m_soundlatch(*this, "soundlatch"), - m_wordswapram(*this, "wordswapram"), m_raiden2cop(*this, "raiden2cop") { memset(scrollvals, 0, sizeof(UINT16)*6); @@ -46,6 +45,7 @@ public: tilemap_t *m_text_layer; int m_has_extended_banking; int m_has_extended_priority; + UINT16 m_sprite_pri_mask[4]; UINT16 m_back_gfx_bank; UINT16 m_fore_gfx_bank; UINT16 m_mid_gfx_bank; @@ -81,15 +81,18 @@ public: TILE_GET_INFO_MEMBER(get_fore_tile_info_denji); TILE_GET_INFO_MEMBER(get_text_tile_info); DECLARE_VIDEO_START(legionna); + DECLARE_VIDEO_START(heatbrl); DECLARE_VIDEO_START(godzilla); DECLARE_VIDEO_START(denjinmk); DECLARE_VIDEO_START(grainbow); DECLARE_VIDEO_START(cupsoc); UINT32 screen_update_legionna(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + UINT32 screen_update_heatbrl(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); UINT32 screen_update_godzilla(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); UINT32 screen_update_grainbow(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap,const rectangle &cliprect); void descramble_legionnaire_gfx(UINT8* src); + void common_video_start(); required_device m_maincpu; required_device m_audiocpu; optional_device m_seibu_sound; @@ -97,7 +100,6 @@ public: required_device m_gfxdecode; required_device m_palette; optional_device m_soundlatch; - optional_shared_ptr m_wordswapram; optional_device m_raiden2cop; }; diff --git a/src/mame/machine/seibucop/seibucop_dma.hxx b/src/mame/machine/seibucop/seibucop_dma.hxx index 54d1546309d..dd8d644089e 100644 --- a/src/mame/machine/seibucop/seibucop_dma.hxx +++ b/src/mame/machine/seibucop/seibucop_dma.hxx @@ -78,8 +78,10 @@ void raiden2cop_device::dma_palette_brightness() } else if (pal_brightness_mode == 4) //Denjin Makai { - UINT16 targetpaldata = m_host_space->read_word(src + (cop_dma_adr_rel * 0x400)); - UINT16 paldata = m_host_space->read_word(src); // ^1 !!! (why?) + // mode 4 swaps endianness between two words, likely that DMA works in dword steps and bit 0. + // TODO: check on V30 flavour + UINT16 targetpaldata = m_host_space->read_word((src + (cop_dma_adr_rel * 0x400)) ^ 2); + UINT16 paldata = m_host_space->read_word(src ^ 2); bt = (targetpaldata & 0x7c00) >> 10; b = (paldata & 0x7c00) >> 10; diff --git a/src/mame/video/legionna.cpp b/src/mame/video/legionna.cpp index 31bac3a97a4..070f307ccf9 100644 --- a/src/mame/video/legionna.cpp +++ b/src/mame/video/legionna.cpp @@ -4,7 +4,7 @@ Legionnaire / Heated Barrel video hardware (derived from D-Con) - priority test (preliminary): + priority test (used by Legionnaire, front to bottom): - OBJ 0 - TXT - OBJ 1 @@ -13,6 +13,8 @@ - MBK - OBJ 3 - LBK + Anything else doesn't seem to match this scheme, guess it's selectable by + PROM, CRTC or COP ... ***************************************************************************/ @@ -106,6 +108,7 @@ WRITE16_MEMBER(legionna_state::videowrite_cb_w) } } +// TODO: move to COP device WRITE16_MEMBER(legionna_state::grainbow_layer_config_w) { // (0x8000|0x1ff), 0x200, 0x1ff, 0x200 written in sequence at startup @@ -181,12 +184,11 @@ TILE_GET_INFO_MEMBER(legionna_state::get_mid_tile_info_cupsoc) SET_TILE_INFO_MEMBER(1,tile,color,0); } -TILE_GET_INFO_MEMBER(legionna_state::get_fore_tile_info)/* this is giving bad tiles... */ +TILE_GET_INFO_MEMBER(legionna_state::get_fore_tile_info) { int tile=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_MEMBER(4,tile,color,0); @@ -213,9 +215,7 @@ TILE_GET_INFO_MEMBER(legionna_state::get_text_tile_info) SET_TILE_INFO_MEMBER(0,tile,color,0); } - - -VIDEO_START_MEMBER(legionna_state,legionna) +void legionna_state::common_video_start() { m_back_data = make_unique_clear(0x800/2); m_fore_data = make_unique_clear(0x800/2); @@ -240,6 +240,41 @@ VIDEO_START_MEMBER(legionna_state,legionna) m_text_layer->set_transparent_pen(15); } +VIDEO_START_MEMBER(legionna_state,legionna) +{ + common_video_start(); + + m_sprite_pri_mask[0] = 0x0000; + m_sprite_pri_mask[1] = 0xfff0; + m_sprite_pri_mask[2] = 0xfffc; + m_sprite_pri_mask[3] = 0xfffe; +} + +VIDEO_START_MEMBER(legionna_state,heatbrl) +{ + common_video_start(); + + m_sprite_pri_mask[0] = 0xfff0; + m_sprite_pri_mask[1] = 0xfffc; + m_sprite_pri_mask[2] = 0xfffe; + // TODO: not shown? + m_sprite_pri_mask[3] = 0xffff; +} + +VIDEO_START_MEMBER(legionna_state,godzilla) +{ + VIDEO_START_CALL_MEMBER(legionna); + + m_has_extended_banking = 1; + m_has_extended_priority = 0; + + m_sprite_pri_mask[0] = 0xfff0; + m_sprite_pri_mask[1] = 0xfffc; + m_sprite_pri_mask[2] = 0xfffe; + // TODO: not shown? + m_sprite_pri_mask[3] = 0xffff; +} + VIDEO_START_MEMBER(legionna_state,denjinmk) { m_back_data = make_unique_clear(0x800/2); @@ -258,7 +293,14 @@ VIDEO_START_MEMBER(legionna_state,denjinmk) m_has_extended_banking = 1; m_has_extended_priority = 0; - + + m_sprite_pri_mask[0] = 0xfff0; + m_sprite_pri_mask[1] = 0xfff8; + // TODO: 2 is used by the door at the end of sewers part in level 1, 3 is the briefing guy + // yet another swapped behaviour caused by a specific port? + m_sprite_pri_mask[2] = 0xfffe; + m_sprite_pri_mask[3] = 0xfffc; + // m_background_layer->set_transparent_pen(15); m_midground_layer->set_transparent_pen(15); m_foreground_layer->set_transparent_pen(15); @@ -301,14 +343,6 @@ VIDEO_START_MEMBER(legionna_state,grainbow) m_layer_config = std::make_unique(0x8/2); } -VIDEO_START_MEMBER(legionna_state,godzilla) -{ - VIDEO_START_CALL_MEMBER(legionna); - - m_has_extended_banking = 1; - m_has_extended_priority = 0; -} - /************************************************************************* Legionnaire Spriteram (similar to Dcon) @@ -384,15 +418,43 @@ void legionna_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap,co else { cur_pri = (spriteram16[offs+1] & 0xc000) >> 14; - - switch (cur_pri) + pri_mask = m_sprite_pri_mask[cur_pri]; + #if 0 + // quick and dirty priority tester + if(cur_pri == 3) { - 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) - } + static UINT16 test = 0xffff; + + if(machine().input().code_pressed_once(KEYCODE_Q)) + test^=1; + if(machine().input().code_pressed_once(KEYCODE_W)) + test^=2; + + if(machine().input().code_pressed_once(KEYCODE_E)) + test^=4; + + if(machine().input().code_pressed_once(KEYCODE_R)) + test^=8; + + if(machine().input().code_pressed_once(KEYCODE_T)) + test^=0x10; + + if(machine().input().code_pressed_once(KEYCODE_Y)) + test^=0x20; + + if(machine().input().code_pressed_once(KEYCODE_U)) + test^=0x40; + + if(machine().input().code_pressed_once(KEYCODE_I)) + test^=0x80; + + pri_mask = 0xffff & test; + data = (data & 0xffc0) | (machine().rand() & 0x3f); + popmessage("%04x %04x %d",pri_mask,test,cur_pri); + //pri_mask = test; + } + #endif } sprite = spriteram16[offs+1]; @@ -495,22 +557,40 @@ void legionna_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap,co } } -#define LAYER_DB 0 - UINT32 legionna_state::screen_update_legionna(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { /* Setup the tilemaps */ screen.priority().fill(0, cliprect); bitmap.fill(m_palette->black_pen(), cliprect); /* wrong color? */ - /* m_layer_disable is a guess based on 'stage 1' screen in heatbrl */ - - if (!(m_layer_disable&0x0020)) m_foreground_layer->draw(screen, bitmap, cliprect, 0, 0); - if (!(m_layer_disable&0x0010)) m_midground_layer->draw(screen, bitmap, cliprect, 0, 0); + if (!(m_layer_disable&0x0001)) m_midground_layer->draw(screen, bitmap, cliprect, 0, 0); if (!(m_layer_disable&0x0002)) m_background_layer->draw(screen, bitmap, cliprect, 0, 1); - if (!(m_layer_disable&0x0001)) m_text_layer->draw(screen, bitmap, cliprect, 0, 2); + if (!(m_layer_disable&0x0004)) m_foreground_layer->draw(screen, bitmap, cliprect, 0, 2); + if (!(m_layer_disable&0x0008)) m_text_layer->draw(screen, bitmap, cliprect, 0, 4); - draw_sprites(screen,bitmap,cliprect); + if (!(m_layer_disable&0x0010)) + draw_sprites(screen,bitmap,cliprect); + + if (machine().input().code_pressed_once(KEYCODE_Z)) + if (m_raiden2cop) m_raiden2cop->dump_table(); + + return 0; +} + +UINT32 legionna_state::screen_update_heatbrl(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + /* Setup the tilemaps */ + screen.priority().fill(0, cliprect); + bitmap.fill(m_palette->black_pen(), cliprect); /* wrong color? */ + + // TODO: priority order is different than anything else? + if (!(m_layer_disable&0x0004)) m_foreground_layer->draw(screen, bitmap, cliprect, 0, 0); + if (!(m_layer_disable&0x0002)) m_midground_layer->draw(screen, bitmap, cliprect, 0, 1); + if (!(m_layer_disable&0x0001)) m_background_layer->draw(screen, bitmap, cliprect, 0, 2); + if (!(m_layer_disable&0x0008)) m_text_layer->draw(screen, bitmap, cliprect, 0, 4); + + if (!(m_layer_disable&0x0010)) + draw_sprites(screen,bitmap,cliprect); if (machine().input().code_pressed_once(KEYCODE_Z)) if (m_raiden2cop) m_raiden2cop->dump_table(); @@ -524,12 +604,13 @@ UINT32 legionna_state::screen_update_godzilla(screen_device &screen, bitmap_ind1 bitmap.fill(0x0200, cliprect); screen.priority().fill(0, cliprect); - if (!(m_layer_disable&0x0001)) m_background_layer->draw(screen, bitmap, cliprect, 0,0); - if (!(m_layer_disable&0x0002)) m_midground_layer->draw(screen, bitmap, cliprect, 0,0); - if (!(m_layer_disable&0x0004)) m_foreground_layer->draw(screen, bitmap, cliprect, 0,1); - if (!(m_layer_disable&0x0008)) m_text_layer->draw(screen, bitmap, cliprect, 0,2); + if (!(m_layer_disable&0x0001)) m_background_layer->draw(screen, bitmap, cliprect, 0, 0); + if (!(m_layer_disable&0x0002)) m_midground_layer->draw(screen, bitmap, cliprect, 0, 1); + if (!(m_layer_disable&0x0004)) m_foreground_layer->draw(screen, bitmap, cliprect, 0, 2); + if (!(m_layer_disable&0x0008)) m_text_layer->draw(screen, bitmap, cliprect, 0, 4); - draw_sprites(screen,bitmap,cliprect); + if (!(m_layer_disable&0x0010)) + draw_sprites(screen,bitmap,cliprect); if (machine().input().code_pressed_once(KEYCODE_Z)) if (m_raiden2cop) m_raiden2cop->dump_table(); @@ -555,7 +636,8 @@ UINT32 legionna_state::screen_update_grainbow(screen_device &screen, bitmap_ind1 if(!(m_layer_disable & 8)) m_text_layer->draw(screen, bitmap, cliprect, 0,8); - draw_sprites(screen,bitmap,cliprect); + if (!(m_layer_disable&0x0010)) + draw_sprites(screen,bitmap,cliprect); if (machine().input().code_pressed_once(KEYCODE_Z)) if (m_raiden2cop) m_raiden2cop->dump_table();