mirror of
https://github.com/holub/mame
synced 2025-04-20 15:32:45 +03:00
Merge pull request #6373 from cam900/tattass
deco32.cpp : Improve blending behavior for Tattoo Assassins
This commit is contained in:
commit
fd7c87116f
@ -576,9 +576,9 @@ void nslasher_state::tattass_map(address_map &map)
|
||||
map(0x150000, 0x150003).w(FUNC(nslasher_state::tattass_control_w)); /* Volume port/Eprom/Priority */
|
||||
map(0x162000, 0x162fff).ram(); /* 'Jack' RAM!? */
|
||||
map(0x163000, 0x16309f).rw(m_deco_ace, FUNC(deco_ace_device::ace_r), FUNC(deco_ace_device::ace_w)).umask32(0x0000ffff); /* 'Ace' RAM */
|
||||
map(0x164000, 0x164003).nopw(); /* Palette control BG2/3 ($1a constant) */
|
||||
map(0x164004, 0x164007).nopw(); /* Palette control Obj1 ($6 constant) */
|
||||
map(0x164008, 0x16400b).nopw(); /* Palette control Obj2 ($5 constant) */
|
||||
map(0x164000, 0x164000).w(FUNC(nslasher_state::tilemap_color_bank_w));
|
||||
map(0x164004, 0x164004).w(FUNC(nslasher_state::sprite1_color_bank_w));
|
||||
map(0x164008, 0x164008).w(FUNC(nslasher_state::sprite2_color_bank_w));
|
||||
map(0x16400c, 0x16400f).nopw();
|
||||
map(0x168000, 0x169fff).rw(m_deco_ace, FUNC(deco_ace_device::buffered_palette_r), FUNC(deco_ace_device::buffered_palette_w));
|
||||
map(0x16c000, 0x16c003).nopw();
|
||||
@ -614,9 +614,9 @@ void nslasher_state::nslasher_map(address_map &map)
|
||||
map(0x150000, 0x150000).w(FUNC(nslasher_state::eeprom_w));
|
||||
map(0x150001, 0x150001).w(FUNC(nslasher_state::volume_w));
|
||||
map(0x163000, 0x16309f).rw(m_deco_ace, FUNC(deco_ace_device::ace_r), FUNC(deco_ace_device::ace_w)).umask32(0x0000ffff); /* 'Ace' RAM */
|
||||
map(0x164000, 0x164003).nopw(); /* Palette control BG2/3 ($1a constant) */
|
||||
map(0x164004, 0x164007).nopw(); /* Palette control Obj1 ($4 constant) */
|
||||
map(0x164008, 0x16400b).nopw(); /* Palette control Obj2 ($6 constant) */
|
||||
map(0x164000, 0x164000).w(FUNC(nslasher_state::tilemap_color_bank_w));
|
||||
map(0x164004, 0x164004).w(FUNC(nslasher_state::sprite1_color_bank_w));
|
||||
map(0x164008, 0x164008).w(FUNC(nslasher_state::sprite2_color_bank_w));
|
||||
map(0x16400c, 0x16400f).nopw();
|
||||
map(0x168000, 0x169fff).rw(m_deco_ace, FUNC(deco_ace_device::buffered_palette_r), FUNC(deco_ace_device::buffered_palette_w));
|
||||
map(0x16c000, 0x16c003).nopw();
|
||||
@ -976,7 +976,7 @@ void deco32_state::eeprom_w(u8 data)
|
||||
// --5----- eeprom clk
|
||||
// ---4---- eeprom di
|
||||
// ----3--- unknown
|
||||
// -----2-- color fading effect (0 = without obj1, 1 = with obj1) (used in nslasher, TODO : not implemented)
|
||||
// -----2-- color fading effect mode (0 = without obj1, 1 = with obj1)
|
||||
// ------1- bg2/3 joint mode (8bpp) (not used by fghthist?)
|
||||
// -------0 layer priority
|
||||
|
||||
@ -1124,7 +1124,7 @@ void nslasher_state::tattass_control_w(offs_t offset, u32 data, u32 mem_mask)
|
||||
}
|
||||
|
||||
/* Playfield control - Only written in full word memory accesses */
|
||||
pri_w(data & 0x3); /* Bit 0 - layer priority toggle, Bit 1 - BG2/3 Joint mode (8bpp) */
|
||||
pri_w(data & 0x7); /* Bit 0 - layer priority toggle, Bit 1 - BG2/3 Joint mode (8bpp), Bit 2 - color fading effect mode (with/without OBJ1)? */
|
||||
|
||||
/* Sound board reset control */
|
||||
if (BIT(data, 7))
|
||||
@ -1816,20 +1816,12 @@ static GFXDECODE_START( gfx_dragngun )
|
||||
GFXDECODE_ENTRY( "gfx4", 0, spritelayout5, 0, 32 ) /* Sprites 16x16 */
|
||||
GFXDECODE_END
|
||||
|
||||
static GFXDECODE_START( gfx_tattass )
|
||||
GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0x800, 128 ) /* Characters 8x8 */
|
||||
GFXDECODE_ENTRY( "gfx1", 0, tilelayout, 0, 128 ) /* Tiles 16x16 */
|
||||
GFXDECODE_ENTRY( "gfx2", 0, tilelayout, 0, 128 ) /* Tiles 16x16 */
|
||||
GFXDECODE_ENTRY( "gfx3", 0, tilelayout_5bpp, 0x600, 16 ) /* Sprites 16x16 */
|
||||
GFXDECODE_ENTRY( "gfx4", 0, tilelayout, 0x500, 16 ) /* Sprites 16x16 */
|
||||
GFXDECODE_END
|
||||
|
||||
static GFXDECODE_START( gfx_nslasher )
|
||||
GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0x800, 128 ) /* Characters 8x8 */
|
||||
GFXDECODE_ENTRY( "gfx1", 0, tilelayout, 0, 128 ) /* Tiles 16x16 */
|
||||
GFXDECODE_ENTRY( "gfx2", 0, tilelayout, 0, 128 ) /* Tiles 16x16 */
|
||||
GFXDECODE_ENTRY( "gfx3", 0, tilelayout_5bpp, 0x400, 16 ) /* Sprites 16x16 */
|
||||
GFXDECODE_ENTRY( "gfx4", 0, tilelayout, 0x600, 16 ) /* Sprites 16x16 */
|
||||
GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0x800, 128 ) /* Characters 8x8 */
|
||||
GFXDECODE_ENTRY( "gfx1", 0, tilelayout, 0, 128 ) /* Tiles 16x16 */
|
||||
GFXDECODE_ENTRY( "gfx2", 0, tilelayout, 0, 128 ) /* Tiles 16x16 */
|
||||
GFXDECODE_ENTRY( "gfx3", 0, tilelayout_5bpp, 0, 16 ) /* Sprites 16x16 */
|
||||
GFXDECODE_ENTRY( "gfx4", 0, tilelayout, 0, 16 ) /* Sprites 16x16 */
|
||||
GFXDECODE_END
|
||||
|
||||
|
||||
@ -2265,7 +2257,7 @@ void nslasher_state::tattass(machine_config &config)
|
||||
|
||||
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
|
||||
m_screen->set_raw(XTAL(28'000'000) / 4, 442, 0, 320, 274, 8, 248);
|
||||
m_screen->set_screen_update(FUNC(nslasher_state::screen_update));
|
||||
m_screen->set_screen_update(FUNC(nslasher_state::screen_update_tattass));
|
||||
|
||||
DECO_ACE(config, m_deco_ace, 0);
|
||||
|
||||
@ -2307,7 +2299,7 @@ void nslasher_state::tattass(machine_config &config)
|
||||
m_sprgen[1]->set_gfx_region(4);
|
||||
m_sprgen[1]->set_gfxdecode_tag(m_gfxdecode);
|
||||
|
||||
GFXDECODE(config, m_gfxdecode, m_deco_ace, gfx_tattass);
|
||||
GFXDECODE(config, m_gfxdecode, m_deco_ace, gfx_nslasher);
|
||||
|
||||
DECO104PROT(config, m_ioprot, 0);
|
||||
m_ioprot->port_a_cb().set_ioport("IN0");
|
||||
@ -2339,7 +2331,7 @@ void nslasher_state::nslasher(machine_config &config)
|
||||
|
||||
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
|
||||
m_screen->set_raw(XTAL(28'322'000) / 4, 442, 0, 320, 274, 8, 248);
|
||||
m_screen->set_screen_update(FUNC(nslasher_state::screen_update));
|
||||
m_screen->set_screen_update(FUNC(nslasher_state::screen_update_nslasher));
|
||||
|
||||
DECO_ACE(config, m_deco_ace, 0);
|
||||
|
||||
|
@ -178,13 +178,17 @@ public:
|
||||
private:
|
||||
required_device<deco_ace_device> m_deco_ace;
|
||||
|
||||
void tilemap_color_bank_w(u8 data);
|
||||
void sprite1_color_bank_w(u8 data);
|
||||
void sprite2_color_bank_w(u8 data);
|
||||
void tattass_control_w(offs_t offset, u32 data, u32 mem_mask = ~0);
|
||||
DECLARE_WRITE_LINE_MEMBER(tattass_sound_irq_w);
|
||||
u16 nslasher_debug_r();
|
||||
|
||||
virtual void video_start() override;
|
||||
|
||||
u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
u32 screen_update_nslasher(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
u32 screen_update_tattass(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
|
||||
u16 port_b_tattass();
|
||||
DECO16IC_BANK_CB_MEMBER(bank_callback);
|
||||
@ -192,7 +196,8 @@ private:
|
||||
void nslasher_map(address_map &map);
|
||||
void tattass_map(address_map &map);
|
||||
|
||||
void mixDualAlphaSprites(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, gfx_element *gfx0, gfx_element *gfx1, int mixAlphaTilemap);
|
||||
void mix_nslasher(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, gfx_element *gfx0, gfx_element *gfx1, int mixAlphaTilemap);
|
||||
void mix_tattass(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, gfx_element *gfx0, gfx_element *gfx1, int mixAlphaTilemap);
|
||||
|
||||
std::unique_ptr<bitmap_ind16> m_tilemap_alpha_bitmap;
|
||||
|
||||
|
@ -448,6 +448,7 @@ void deco16ic_device::custom_tilemap_draw(
|
||||
if (sizeof(*dest) == 2) rgb = 0;
|
||||
else rgb = 1;
|
||||
|
||||
gfx_element *gfx = m_gfxdecode->gfx(BIT(control1, 7) ? m_pf12_8x8_gfx_bank : m_pf12_16x16_gfx_bank);
|
||||
tilemap_t *tilemap0 = BIT(control1, 7) ? tilemap0_8x8 : tilemap0_16x16;
|
||||
tilemap_t *tilemap1 = BIT(control1, 7) ? tilemap1_8x8 : tilemap1_16x16;
|
||||
const bitmap_ind16 *src_bitmap0 = tilemap0 ? &tilemap0->pixmap() : nullptr;
|
||||
@ -494,13 +495,13 @@ void deco16ic_device::custom_tilemap_draw(
|
||||
{
|
||||
if (!is_tattoo)
|
||||
{
|
||||
// does boogie wings actually use this, or is the tattoo assassing code correct in this mode?
|
||||
// does boogie wings actually use this, or is the tattoo assassin code correct in this mode?
|
||||
p |= (src_bitmap1->pix16((src_y + column_offset) & height_mask, src_x) & combine_mask) << combine_shift;
|
||||
}
|
||||
else
|
||||
{
|
||||
const u16 p2 = src_bitmap1->pix16((src_y + column_offset) & height_mask, src_x);
|
||||
p = 0x200 + (((p & 0x30) << 4) | (p & 0x0f) | ((p2 & 0x0f) << 4));
|
||||
p = gfx->colorbase() + (m_pf1_colour_bank * gfx->granularity()) + (((p & 0x30) << 4) | (p & 0x0f) | ((p2 & 0x0f) << 4));
|
||||
}
|
||||
}
|
||||
src_x = (src_x + 1) & width_mask;
|
||||
@ -550,8 +551,35 @@ void deco16ic_device::set_tilemap_colour_mask(int tmap, int mask)
|
||||
{
|
||||
switch (tmap)
|
||||
{
|
||||
case 0: m_pf1_colourmask = mask; break;
|
||||
case 1: m_pf2_colourmask = mask; break;
|
||||
case 0: m_pf1_colourmask = mask; m_pf1_tilemap_16x16->mark_all_dirty(); m_pf1_tilemap_8x8->mark_all_dirty(); break;
|
||||
case 1: m_pf2_colourmask = mask; m_pf2_tilemap_16x16->mark_all_dirty(); m_pf2_tilemap_8x8->mark_all_dirty(); break;
|
||||
}
|
||||
}
|
||||
|
||||
void deco16ic_device::set_tilemap_colour_bank(int tmap, int bank)
|
||||
{
|
||||
switch (tmap)
|
||||
{
|
||||
case 0:
|
||||
if (m_pf1_colour_bank != bank)
|
||||
{
|
||||
m_pf1_colour_bank = bank;
|
||||
if (m_pf1_tilemap_16x16)
|
||||
m_pf1_tilemap_16x16->mark_all_dirty();
|
||||
if (m_pf1_tilemap_8x8)
|
||||
m_pf1_tilemap_8x8->mark_all_dirty();
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (m_pf2_colour_bank != bank)
|
||||
{
|
||||
m_pf2_colour_bank = bank;
|
||||
if (m_pf2_tilemap_16x16)
|
||||
m_pf2_tilemap_16x16->mark_all_dirty();
|
||||
if (m_pf2_tilemap_8x8)
|
||||
m_pf2_tilemap_8x8->mark_all_dirty();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,6 +100,9 @@ public:
|
||||
/* used by cninjabl */
|
||||
void set_enable(int tmap, int enable );
|
||||
|
||||
/* used by nslasher */
|
||||
void set_tilemap_colour_bank(int tmap, int bank);
|
||||
|
||||
template<class _BitmapClass>
|
||||
void custom_tilemap_draw(
|
||||
screen_device &screen,
|
||||
|
@ -52,6 +52,25 @@ void deco32_state::palette_dma_w(u32 data)
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// sprite and BG2/3 color banks are changeable at run time
|
||||
void nslasher_state::tilemap_color_bank_w(u8 data)
|
||||
{
|
||||
m_deco_tilegen[1]->set_tilemap_colour_bank(0, ((data >> 0) & 7) << 4);
|
||||
m_deco_tilegen[1]->set_tilemap_colour_bank(1, ((data >> 3) & 7) << 4);
|
||||
}
|
||||
|
||||
void nslasher_state::sprite1_color_bank_w(u8 data)
|
||||
{
|
||||
m_gfxdecode->gfx(3)->set_colorbase((data & 7) << 8);
|
||||
}
|
||||
|
||||
void nslasher_state::sprite2_color_bank_w(u8 data)
|
||||
{
|
||||
m_gfxdecode->gfx(4)->set_colorbase((data & 7) << 8);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void deco32_state::video_start()
|
||||
{
|
||||
save_item(NAME(m_pri));
|
||||
@ -236,7 +255,7 @@ u32 fghthist_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, c
|
||||
|
||||
reference : https://www.youtube.com/watch?v=y73dJ6UQw8M (nslasher)
|
||||
*/
|
||||
void nslasher_state::mixDualAlphaSprites(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, gfx_element *gfx0, gfx_element *gfx1, int mixAlphaTilemap)
|
||||
void nslasher_state::mix_nslasher(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, gfx_element *gfx0, gfx_element *gfx1, int mixAlphaTilemap)
|
||||
{
|
||||
const pen_t *pens = m_deco_ace->pens();
|
||||
const pen_t *pal0 = &pens[gfx0->colorbase()];
|
||||
@ -303,6 +322,7 @@ void nslasher_state::mixDualAlphaSprites(screen_device &screen, bitmap_rgb32 &bi
|
||||
|
||||
coloffs = (((m_pri & 4) == 0) && sprite1_drawn) ? 0x800 : 0;
|
||||
/* Alpha values are tied to ACE ram... */
|
||||
// TODO : verify this from real hardware
|
||||
int alpha = ((!alpha1) || alpha2) ? m_deco_ace->get_alpha((col1 & 0x8) ? (0x4 + ((col1 & 0x3) / 2)) : ((col1 & 0x7) / 2)) : 0xff;
|
||||
|
||||
/* I don't really understand how object ACE ram is really hooked up,
|
||||
@ -377,7 +397,7 @@ void nslasher_state::mixDualAlphaSprites(screen_device &screen, bitmap_rgb32 &bi
|
||||
}
|
||||
}
|
||||
|
||||
u32 nslasher_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
u32 nslasher_state::screen_update_nslasher(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
bool alphaTilemap = false;
|
||||
m_deco_tilegen[0]->pf_update(m_pf_rowscroll[0].get(), m_pf_rowscroll[1].get());
|
||||
@ -431,7 +451,209 @@ u32 nslasher_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, c
|
||||
}
|
||||
}
|
||||
|
||||
mixDualAlphaSprites(screen, bitmap, cliprect, m_gfxdecode->gfx(3), m_gfxdecode->gfx(4), alphaTilemap);
|
||||
mix_nslasher(screen, bitmap, cliprect, m_gfxdecode->gfx(3), m_gfxdecode->gfx(4), alphaTilemap);
|
||||
|
||||
m_deco_tilegen[0]->tilemap_1_draw(screen, bitmap, cliprect, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// different alpha blending behavior, priority? TODO : verify behavior from real hardware
|
||||
// reference : https://www.youtube.com/watch?v=ax-_P3meUiA (review)
|
||||
void nslasher_state::mix_tattass(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, gfx_element *gfx0, gfx_element *gfx1, int mixAlphaTilemap)
|
||||
{
|
||||
const pen_t *pens = m_deco_ace->pens();
|
||||
const pen_t *pal0 = &pens[gfx0->colorbase()];
|
||||
const pen_t *pal1 = &pens[gfx1->colorbase()];
|
||||
const pen_t *pal2 = &pens[m_gfxdecode->gfx((m_pri & 1) ? 1 : 2)->colorbase()];
|
||||
bitmap_ind16& sprite0_mix_bitmap = m_sprgen[0]->get_sprite_temp_bitmap();
|
||||
bitmap_ind16& sprite1_mix_bitmap = m_sprgen[1]->get_sprite_temp_bitmap();
|
||||
|
||||
/* Mix sprites into main bitmap, based on priority & alpha */
|
||||
for (int y = cliprect.top(); y <= cliprect.bottom(); y++)
|
||||
{
|
||||
const u16* sprite0 = &sprite0_mix_bitmap.pix16(y);
|
||||
const u16* sprite1 = &sprite1_mix_bitmap.pix16(y);
|
||||
const u16* alphaTilemap = &m_tilemap_alpha_bitmap->pix16(y);
|
||||
const u8* tilemapPri = &screen.priority().pix8(y);
|
||||
u32* destLine = &bitmap.pix32(y);
|
||||
|
||||
for (int x = cliprect.left(); x <= cliprect.right(); x++)
|
||||
{
|
||||
const u16 priColAlphaPal0 = sprite0[x];
|
||||
const u16 priColAlphaPal1 = sprite1[x];
|
||||
const u16 pri0 = (priColAlphaPal0 & 0x6000) >> 13;
|
||||
const u16 pri1 = (priColAlphaPal1 & 0x6000) >> 13;
|
||||
const u16 col0 = (((priColAlphaPal0 & 0x0f00) >> 8) % gfx0->colors()) * gfx0->granularity();
|
||||
u16 col1 = ((priColAlphaPal1 & 0x3f00) >> 8);
|
||||
const bool alpha1 = (priColAlphaPal1 & 0x8000); // Unknown behavior, just priority?
|
||||
|
||||
// Apply sprite bitmap 0 according to priority rules
|
||||
u16 coloffs = ((m_pri & 4) == 4) ? 0x800 : 0;
|
||||
bool sprite1_drawn = false;
|
||||
if ((priColAlphaPal0 & 0xff) != 0)
|
||||
{
|
||||
/*
|
||||
Sprite 0 priority rules:
|
||||
|
||||
0 = Sprite above all layers
|
||||
1 = Sprite under top playfield
|
||||
2 = Sprite under top two playfields
|
||||
3 = Sprite under all playfields
|
||||
*/
|
||||
if ((pri0 & 0x3) == 0 || (pri0 & 0x3) == 1 || ((pri0 & 0x3) == 2 && mixAlphaTilemap)) // Spri0 on top of everything, or under alpha playfield
|
||||
{
|
||||
destLine[x] = pal0[coloffs | ((priColAlphaPal0 & 0xff) + col0)];
|
||||
sprite1_drawn = true;
|
||||
}
|
||||
else if ((pri0 & 0x3) == 2) // Spri0 under top playfield
|
||||
{
|
||||
if (tilemapPri[x] < 4)
|
||||
{
|
||||
destLine[x] = pal0[coloffs | ((priColAlphaPal0 & 0xff) + col0)];
|
||||
sprite1_drawn = true;
|
||||
}
|
||||
}
|
||||
else // Spri0 under top & middle playfields
|
||||
{
|
||||
if (tilemapPri[x] < 2)
|
||||
{
|
||||
destLine[x] = pal0[coloffs | ((priColAlphaPal0 & 0xff) + col0)];
|
||||
sprite1_drawn = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
coloffs = (((m_pri & 4) == 4) && sprite1_drawn) ? 0x800 : 0;
|
||||
/* Alpha values are tied to ACE ram... */
|
||||
int alpha = m_deco_ace->get_alpha(col1 / 8);
|
||||
|
||||
/* I don't really understand how object ACE ram is really hooked up,
|
||||
the only obvious place in Night Slashers is the stagecoach in level 2 */
|
||||
|
||||
col1 = ((col1 & 0xf) % gfx1->colors()) * gfx1->granularity();
|
||||
// Apply sprite bitmap 1 according to priority rules
|
||||
if ((priColAlphaPal1 & 0xff) != 0)
|
||||
{
|
||||
// Apply alpha for this pixel based on Ace setting
|
||||
if (alpha1)
|
||||
{
|
||||
/*
|
||||
Alpha rules:
|
||||
|
||||
Pri 0 - Over all tilemaps, but under sprite 0 pri 0, pri 1, pri 2
|
||||
Pri 1 - Under uppermost tilemap, sprite 0 pri 0, pri 1?
|
||||
Pri 2 -
|
||||
Pri 3 -
|
||||
*/
|
||||
|
||||
if (pri1 == 0 && (((priColAlphaPal0 & 0xff) == 0 || ((pri0 & 0x3) != 0 && (pri0 & 0x3) != 1 && (pri0 & 0x3) != 2))))
|
||||
{
|
||||
if ((m_pri & 1) == 0 || ((m_pri & 1) == 1 && tilemapPri[x] < 4) || ((m_pri & 1) == 1 &&
|
||||
(mixAlphaTilemap && ((alphaTilemap[x] & 0xf) == 0))))
|
||||
destLine[x] = alpha_blend_r32(destLine[x], pal1[coloffs | ((priColAlphaPal1 & 0xff) + col1)], alpha);
|
||||
}
|
||||
else if (pri1 == 1 && ((m_pri & 1) == 0 || tilemapPri[x] < 4)
|
||||
&& ((priColAlphaPal0 & 0xff) == 0 || ((pri0 & 0x3) != 0 && (pri0 & 0x3) != 1)))
|
||||
destLine[x] = alpha_blend_r32(destLine[x], pal1[coloffs | ((priColAlphaPal1 & 0xff) + col1)], alpha);
|
||||
else if (pri1 == 2) // TODO
|
||||
destLine[x] = alpha_blend_r32(destLine[x], pal1[coloffs | ((priColAlphaPal1 & 0xff) + col1)], alpha);
|
||||
else if (pri1 == 3) // TODO
|
||||
destLine[x] = alpha_blend_r32(destLine[x], pal1[coloffs | ((priColAlphaPal1 & 0xff) + col1)], alpha);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
Non alpha rules:
|
||||
|
||||
Pri 0 - Under sprite 0 pri 0, over all tilemaps
|
||||
*/
|
||||
if (pri1 == 0 && ((priColAlphaPal0 & 0xff) == 0 || ((pri0 & 0x3) != 0)))
|
||||
destLine[x] = alpha_blend_r32(destLine[x], pal1[coloffs | ((priColAlphaPal1 & 0xff) + col1)], alpha);
|
||||
else if (pri1 == 1) // TODO
|
||||
destLine[x] = alpha_blend_r32(destLine[x], pal1[coloffs | ((priColAlphaPal1 & 0xff) + col1)], alpha);
|
||||
else if (pri1 == 2) // TODO
|
||||
destLine[x] = alpha_blend_r32(destLine[x], pal1[coloffs | ((priColAlphaPal1 & 0xff) + col1)], alpha);
|
||||
else if (pri1 == 3) // TODO
|
||||
destLine[x] = alpha_blend_r32(destLine[x], pal1[coloffs | ((priColAlphaPal1 & 0xff) + col1)], alpha);
|
||||
}
|
||||
}
|
||||
|
||||
/* Optionally mix in alpha tilemap */
|
||||
if (mixAlphaTilemap)
|
||||
{
|
||||
const u16 p = alphaTilemap[x];
|
||||
if (p & 0xf)
|
||||
{
|
||||
/* Alpha tilemap under top two sprite 0 priorities */
|
||||
if (((priColAlphaPal0 & 0xff) == 0 || (pri0 & 0x3) == 2 || (pri0 & 0x3) == 3)
|
||||
&& ((priColAlphaPal1 & 0xff) == 0 || (pri1 & 0x3) == 2 || (pri1 & 0x3) == 3 || alpha1))
|
||||
{
|
||||
/* Alpha values are tied to ACE ram */
|
||||
int alpha = m_deco_ace->get_alpha(0x17 + (((p & 0xf0) >> 4) / 2));
|
||||
|
||||
destLine[x] = alpha_blend_r32(destLine[x], pal2[coloffs | p], alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u32 nslasher_state::screen_update_tattass(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
bool alphaTilemap = false;
|
||||
m_deco_tilegen[0]->pf_update(m_pf_rowscroll[0].get(), m_pf_rowscroll[1].get());
|
||||
m_deco_tilegen[1]->pf_update(m_pf_rowscroll[2].get(), m_pf_rowscroll[3].get());
|
||||
|
||||
/* This is not a conclusive test for deciding if tilemap needs alpha blending */
|
||||
if (m_deco_ace->get_aceram(0x17) != 0x0 && (m_pri & 3))
|
||||
alphaTilemap = true;
|
||||
|
||||
screen.priority().fill(0, cliprect);
|
||||
|
||||
bitmap.fill(m_deco_ace->pen(0x300), cliprect); // TODO : verify this from real hardware
|
||||
|
||||
/* Draw sprites to temporary bitmaps, saving alpha & priority info for later mixing */
|
||||
m_sprgen[0]->set_pix_raw_shift(8);
|
||||
m_sprgen[1]->set_pix_raw_shift(8);
|
||||
|
||||
// sprites are flipped relative to tilemaps
|
||||
m_sprgen[0]->set_flip_screen(true);
|
||||
m_sprgen[1]->set_flip_screen(true);
|
||||
m_sprgen[0]->draw_sprites(bitmap, cliprect, m_spriteram16_buffered[0].get(), 0x800);
|
||||
m_sprgen[1]->draw_sprites(bitmap, cliprect, m_spriteram16_buffered[1].get(), 0x800);
|
||||
|
||||
/* Render alpha-blended tilemap to separate buffer for proper mixing */
|
||||
m_tilemap_alpha_bitmap->fill(0, cliprect);
|
||||
|
||||
/* Draw playfields & sprites */
|
||||
if (m_pri & 2)
|
||||
{
|
||||
m_deco_tilegen[1]->tilemap_12_combine_draw(screen, bitmap, cliprect, 0, 1, 1);
|
||||
m_deco_tilegen[0]->tilemap_2_draw(screen, bitmap, cliprect, 0, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_deco_tilegen[1]->tilemap_2_draw(screen, bitmap, cliprect, 0, 1);
|
||||
if (m_pri & 1)
|
||||
{
|
||||
m_deco_tilegen[0]->tilemap_2_draw(screen, bitmap, cliprect, 0, 2);
|
||||
if (alphaTilemap)
|
||||
m_deco_tilegen[1]->tilemap_1_draw(screen, *m_tilemap_alpha_bitmap, cliprect, 0, 4);
|
||||
else
|
||||
m_deco_tilegen[1]->tilemap_1_draw(screen, bitmap, cliprect, 0, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_deco_tilegen[1]->tilemap_1_draw(screen, bitmap, cliprect, 0, 2);
|
||||
if (alphaTilemap)
|
||||
m_deco_tilegen[0]->tilemap_2_draw(screen, *m_tilemap_alpha_bitmap, cliprect, 0, 4);
|
||||
else
|
||||
m_deco_tilegen[0]->tilemap_2_draw(screen, bitmap, cliprect, 0, 4);
|
||||
}
|
||||
}
|
||||
|
||||
mix_tattass(screen, bitmap, cliprect, m_gfxdecode->gfx(3), m_gfxdecode->gfx(4), alphaTilemap);
|
||||
|
||||
m_deco_tilegen[0]->tilemap_1_draw(screen, bitmap, cliprect, 0, 0);
|
||||
return 0;
|
||||
|
@ -13,7 +13,13 @@
|
||||
|
||||
Bytes 0 to 0x1f : Alpha Control
|
||||
Tattoo Assassins :
|
||||
Bytes 0x00 to 0x16(0x58) - object alpha control?
|
||||
Bytes 0x00 to 0x07(0x1c) - object alpha control per palette/priority / 8
|
||||
Bytes 0x08(0x20) to 0x16(0x58) - used, unknown condition/purpose (possibly object)
|
||||
Bytes 0x17(0x5c) to 0x1f(0x7c) - tilemap alpha control
|
||||
|
||||
Night slashers :
|
||||
Bytes 0x00 to 0x05(0x14) - object alpha control per palette / 2 (if ((pix & 0x900) != 0x100))
|
||||
Bytes 0x06(0x18) to 0x16(0x58) - unused/unknown
|
||||
Bytes 0x17(0x5c) to 0x1f(0x7c) - tilemap alpha control
|
||||
|
||||
Boogie Wings:
|
||||
|
Loading…
Reference in New Issue
Block a user