darkmist.cpp: added actual transparent pen mixing from proms, fixes ranking screen and gameplay area in Dark Mist [Angelo Salese]

This commit is contained in:
angelosa 2016-11-02 01:10:19 +01:00
parent 170f2b946d
commit fb9f1157cf
3 changed files with 106 additions and 68 deletions

View File

@ -59,7 +59,7 @@ static ADDRESS_MAP_START( memmap, AS_PROGRAM, 8, darkmist_state )
AM_RANGE(0xd681, 0xd681) AM_DEVREAD("t5182", t5182_device, sharedram_semaphore_snd_r)
AM_RANGE(0xd682, 0xd682) AM_DEVWRITE("t5182", t5182_device, sharedram_semaphore_main_acquire_w)
AM_RANGE(0xd683, 0xd683) AM_DEVWRITE("t5182", t5182_device, sharedram_semaphore_main_release_w)
AM_RANGE(0xd800, 0xdfff) AM_RAM AM_SHARE("videoram")
AM_RANGE(0xd800, 0xdfff) AM_RAM_WRITE(tx_vram_w) AM_SHARE("videoram")
AM_RANGE(0xe000, 0xefff) AM_RAM AM_SHARE("workram")
AM_RANGE(0xf000, 0xffff) AM_RAM AM_SHARE("spriteram")
ADDRESS_MAP_END
@ -214,10 +214,10 @@ static const gfx_layout tilelayout =
static GFXDECODE_START( darkmist )
GFXDECODE_ENTRY( "tx_gfx", 0, charlayout, 0, 16*4 )
GFXDECODE_ENTRY( "bg_gfx", 0, tilelayout, 0, 16*4 )
GFXDECODE_ENTRY( "fg_gfx", 0, tilelayout, 0, 16*4 )
GFXDECODE_ENTRY( "spr_gfx", 0, tilelayout, 0, 16*4 )
GFXDECODE_ENTRY( "tx_gfx", 0, charlayout, 0x300, 16 )
GFXDECODE_ENTRY( "bg_gfx", 0, tilelayout, 0x000, 16 )
GFXDECODE_ENTRY( "fg_gfx", 0, tilelayout, 0x100, 16 )
GFXDECODE_ENTRY( "spr_gfx", 0, tilelayout, 0x200, 16 )
GFXDECODE_END
TIMER_DEVICE_CALLBACK_MEMBER(darkmist_state::scanline)
@ -242,7 +242,6 @@ static MACHINE_CONFIG_START( darkmist, darkmist_state )
MCFG_DEVICE_ADD("t5182", T5182, 0)
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(60)

View File

@ -9,6 +9,7 @@ public:
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_t5182(*this, "t5182"),
m_screen(*this, "screen"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette"),
m_spritebank(*this, "spritebank"),
@ -16,10 +17,15 @@ public:
m_videoram(*this, "videoram"),
m_workram(*this, "workram"),
m_spriteram(*this, "spriteram"),
m_bg_clut(*this, "bg_clut"),
m_fg_clut(*this, "fg_clut"),
m_spr_clut(*this, "spr_clut"),
m_tx_clut(*this, "tx_clut"),
m_decrypted_opcodes(*this, "decrypted_opcodes") { }
required_device<cpu_device> m_maincpu;
required_device<t5182_device> m_t5182;
required_device<screen_device> m_screen;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
@ -28,6 +34,10 @@ public:
required_shared_ptr<uint8_t> m_videoram;
required_shared_ptr<uint8_t> m_workram;
required_shared_ptr<uint8_t> m_spriteram;
required_region_ptr<uint8_t> m_bg_clut;
required_region_ptr<uint8_t> m_fg_clut;
required_region_ptr<uint8_t> m_spr_clut;
required_region_ptr<uint8_t> m_tx_clut;
optional_shared_ptr<uint8_t> m_decrypted_opcodes;
int m_hw;
@ -36,7 +46,8 @@ public:
tilemap_t *m_txtilemap;
DECLARE_WRITE8_MEMBER(hw_w);
DECLARE_WRITE8_MEMBER(tx_vram_w);
TILE_GET_INFO_MEMBER(get_bgtile_info);
TILE_GET_INFO_MEMBER(get_fgtile_info);
TILE_GET_INFO_MEMBER(get_txttile_info);
@ -46,7 +57,10 @@ public:
virtual void video_start() override;
DECLARE_PALETTE_INIT(darkmist);
bitmap_ind16 m_temp_bitmap;
void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void mix_layer(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, uint8_t* clut);
void decrypt_fgbgtiles(uint8_t* rgn, int size);
void decrypt_gfx();
void decrypt_snd();

View File

@ -21,7 +21,7 @@ TILE_GET_INFO_MEMBER(darkmist_state::get_bgtile_info)
attr=memregion("bg_map")->base()[(tile_index*2)+1]; /* -PPP--TT - FIXED BITS (0xxx00xx) */
code+=(attr&3)<<8;
pal=(attr>>4);
pal=(attr>>4) & 0xf;
SET_TILE_INFO_MEMBER(1,
code,
@ -37,9 +37,7 @@ TILE_GET_INFO_MEMBER(darkmist_state::get_fgtile_info)
attr = memregion("fg_map")->base()[(tile_index*2)+1]; /* -PPP--TT - FIXED BITS (0xxx00xx) */
code+=(attr&3)<<8;
pal=attr>>4;
pal+=16;
pal=(attr>>4) & 0xf;
SET_TILE_INFO_MEMBER(2,
code,
@ -57,22 +55,15 @@ TILE_GET_INFO_MEMBER(darkmist_state::get_txttile_info)
code+=(attr&1)<<8;
pal+=48;
SET_TILE_INFO_MEMBER(0,
code,
pal,
pal & 0xf,
0);
}
PALETTE_INIT_MEMBER(darkmist_state, darkmist)
{
const uint8_t *bg_clut = memregion("bg_clut")->base();
const uint8_t *fg_clut = memregion("fg_clut")->base();
const uint8_t *spr_clut = memregion("spr_clut")->base();
const uint8_t *tx_clut = memregion("tx_clut")->base();
palette.set_indirect_color(0x100, rgb_t::black());
// palette.set_indirect_color(0x100, rgb_t::black());
for (int i = 0; i < 0x400; i++)
{
@ -81,15 +72,15 @@ PALETTE_INIT_MEMBER(darkmist_state, darkmist)
switch (i & 0x300)
{
case 0x000: clut = bg_clut[i&0xff]; break;
case 0x100: clut = fg_clut[i&0xff]; break;
case 0x200: clut = spr_clut[i&0xff]; break;
case 0x300: clut = tx_clut[i&0xff]; break;
case 0x000: clut = m_bg_clut[i&0xff]; break;
case 0x100: clut = m_fg_clut[i&0xff]; break;
case 0x200: clut = m_spr_clut[i&0xff]; break;
case 0x300: clut = m_tx_clut[i&0xff]; break;
}
if (clut & 0x40) // 0x40 indicates non-transparent
ctabentry = 0x100;
else
// if (clut & 0x40) // 0x40 indicates transparent pen
// ctabentry = 0x100;
// else
{
ctabentry = (clut & 0x3f);
@ -112,31 +103,31 @@ void darkmist_state::video_start()
m_bgtilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(darkmist_state::get_bgtile_info),this),TILEMAP_SCAN_ROWS,16,16,512,64 );
m_fgtilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(darkmist_state::get_fgtile_info),this),TILEMAP_SCAN_ROWS,16,16,64,256 );
m_txtilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(darkmist_state::get_txttile_info),this),TILEMAP_SCAN_ROWS,8,8,32,32 );
m_fgtilemap->set_transparent_pen(0);
m_txtilemap->set_transparent_pen(0);
// m_fgtilemap->set_transparent_pen(0);
// m_txtilemap->set_transparent_pen(0);
save_item(NAME(m_hw));
m_screen->register_screen_bitmap(m_temp_bitmap);
}
uint32_t darkmist_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
// TODO: move this code into framework or substitute with a valid alternative
void darkmist_state::mix_layer(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, uint8_t* clut)
{
#define DM_GETSCROLL(n) (((m_scroll[(n)]<<1)&0xff) + ((m_scroll[(n)]&0x80)?1:0) +( ((m_scroll[(n)-1]<<4) | (m_scroll[(n)-1]<<12) )&0xff00))
m_bgtilemap->set_scrollx(0, DM_GETSCROLL(0x2));
m_bgtilemap->set_scrolly(0, DM_GETSCROLL(0x6));
m_fgtilemap->set_scrollx(0, DM_GETSCROLL(0xa));
m_fgtilemap->set_scrolly(0, DM_GETSCROLL(0xe));
bitmap.fill(m_palette->black_pen(), cliprect);
if(m_hw & DISPLAY_BG)
m_bgtilemap->draw(screen, bitmap, cliprect, 0,0);
if(m_hw & DISPLAY_FG)
m_fgtilemap->draw(screen, bitmap, cliprect, 0,0);
if(m_hw & DISPLAY_SPR)
for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
{
uint16_t *dest = &bitmap.pix16(y);
uint16_t *src = &m_temp_bitmap.pix16(y);
for (int x = cliprect.min_x; x <= cliprect.max_x; x++)
{
uint16_t pix = (src[x] & 0xff);
uint16_t real = clut[pix];
if (!(real & 0x40))
dest[x] = src[x];
}
}
}
/*
Sprites
@ -148,40 +139,74 @@ uint32_t darkmist_state::screen_update(screen_device &screen, bitmap_ind16 &bitm
3 - XXXX XXXX - x coord
*/
int i,fx,fy,tile,palette;
for(i=0;i<m_spriteram.bytes();i+=32)
{
fy=m_spriteram[i+1]&0x40;
fx=m_spriteram[i+1]&0x80;
void darkmist_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
int i,fx,fy,tile,palette;
for(i=0;i<m_spriteram.bytes();i+=32)
{
fy=m_spriteram[i+1]&0x40;
fx=m_spriteram[i+1]&0x80;
tile=m_spriteram[i+0];
tile=m_spriteram[i+0];
if(m_spriteram[i+1]&0x20)
tile += (*m_spritebank << 8);
if(m_spriteram[i+1]&0x20)
tile += (*m_spritebank << 8);
palette=((m_spriteram[i+1])>>1)&0xf;
palette=((m_spriteram[i+1])>>1)&0xf;
if(m_spriteram[i+1]&0x1)
palette=machine().rand()&15;
if(m_spriteram[i+1]&0x1)
palette=machine().rand()&15;
palette+=32;
m_gfxdecode->gfx(3)->transpen(
bitmap,cliprect,
tile,
palette,
fx,fy,
m_spriteram[i+3],m_spriteram[i+2],0 );
}
}
uint32_t darkmist_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
#define DM_GETSCROLL(n) (((m_scroll[(n)]<<1)&0xff) + ((m_scroll[(n)]&0x80)?1:0) +( ((m_scroll[(n)-1]<<4) | (m_scroll[(n)-1]<<12) )&0xff00))
m_gfxdecode->gfx(3)->transpen(
bitmap,cliprect,
tile,
palette,
fx,fy,
m_spriteram[i+3],m_spriteram[i+2],0 );
}
m_bgtilemap->set_scrollx(0, DM_GETSCROLL(0x2));
m_bgtilemap->set_scrolly(0, DM_GETSCROLL(0x6));
m_fgtilemap->set_scrollx(0, DM_GETSCROLL(0xa));
m_fgtilemap->set_scrolly(0, DM_GETSCROLL(0xe));
m_temp_bitmap.fill(0,cliprect);
bitmap.fill(m_palette->black_pen(), cliprect);
if(m_hw & DISPLAY_BG)
{
m_bgtilemap->draw(screen, m_temp_bitmap, cliprect, 0,0);
mix_layer(screen, bitmap, cliprect, m_bg_clut);
}
if(m_hw & DISPLAY_FG)
{
m_fgtilemap->draw(screen, m_temp_bitmap, cliprect, 0,0);
mix_layer(screen, bitmap, cliprect, m_fg_clut);
}
if(m_hw & DISPLAY_SPR)
{
draw_sprites(m_temp_bitmap,cliprect);
mix_layer(screen, bitmap, cliprect, m_spr_clut);
}
if(m_hw & DISPLAY_TXT)
{
m_txtilemap->mark_all_dirty();
m_txtilemap->draw(screen, bitmap, cliprect, 0,0);
m_txtilemap->draw(screen, m_temp_bitmap, cliprect, 0,0);
mix_layer(screen, bitmap, cliprect, m_tx_clut);
}
return 0;
}
WRITE8_MEMBER(darkmist_state::tx_vram_w)
{
m_videoram[offset] = data;
m_txtilemap->mark_tile_dirty(offset & 0x3ff);
}