Fixed priority issues in Legionnaire, Heated Barrel, Denjin Makai and Godzilla [Angelo Salese]

This commit is contained in:
angelosa 2016-07-01 21:38:59 +02:00
parent 715c86f1c7
commit 8f84c7b10f
4 changed files with 129 additions and 51 deletions

View File

@ -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)

View File

@ -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<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
optional_device<seibu_sound_device> m_seibu_sound;
@ -97,7 +100,6 @@ public:
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
optional_device<generic_latch_8_device> m_soundlatch;
optional_shared_ptr<UINT16> m_wordswapram;
optional_device<raiden2cop_device> m_raiden2cop;
};

View File

@ -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;

View File

@ -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<UINT16[]>(0x800/2);
m_fore_data = make_unique_clear<UINT16[]>(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<UINT16[]>(0x800/2);
@ -259,6 +294,13 @@ 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<UINT16[]>(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,21 +557,39 @@ 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);
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))
@ -525,10 +605,11 @@ UINT32 legionna_state::screen_update_godzilla(screen_device &screen, bitmap_ind1
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&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);
if (!(m_layer_disable&0x0010))
draw_sprites(screen,bitmap,cliprect);
if (machine().input().code_pressed_once(KEYCODE_Z))
@ -555,6 +636,7 @@ 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);
if (!(m_layer_disable&0x0010))
draw_sprites(screen,bitmap,cliprect);
if (machine().input().code_pressed_once(KEYCODE_Z))