summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author cam900 <dbtlrchl@naver.com>2020-02-18 07:23:57 +0900
committer GitHub <noreply@github.com>2020-02-17 17:23:57 -0500
commit09e068aaad8d0d6cd9a79fb534a9b403091a59cb (patch)
tree067671581a5c26e8295f52c369a97ec4d0988bc9
parent8b3a65302bcc896047d503b756160233c00fa36e (diff)
boogwing.cpp : Further blending implementation, Typo (#6316)
* boogwing.cpp : Further blending implementation, Typo * deco_ace.cpp : Add notes * deco32.cpp : ACE ram is not masked * deco_ace : Minor fix addressing * boogwing.cpp : Add reference * boogwing.cpp : Partially blended tilemap handling
-rw-r--r--src/mame/drivers/boogwing.cpp18
-rw-r--r--src/mame/includes/boogwing.h5
-rw-r--r--src/mame/video/boogwing.cpp55
-rw-r--r--src/mame/video/deco_ace.cpp6
4 files changed, 66 insertions, 18 deletions
diff --git a/src/mame/drivers/boogwing.cpp b/src/mame/drivers/boogwing.cpp
index da4f8945578..a09f0df8960 100644
--- a/src/mame/drivers/boogwing.cpp
+++ b/src/mame/drivers/boogwing.cpp
@@ -92,7 +92,6 @@
#include "machine/gen_latch.h"
#include "sound/ym2151.h"
#include "sound/okim6295.h"
-#include "screen.h"
#include "speaker.h"
#define MAIN_XTAL XTAL(28'000'000)
@@ -118,7 +117,14 @@ WRITE16_MEMBER( boogwing_state::boogwing_protection_region_0_104_w )
WRITE16_MEMBER( boogwing_state::priority_w )
{
COMBINE_DATA(&m_priority);
- m_deco_ace->set_palette_effect_max((m_priority & 0x8) ? 0x6ff : 0xfff);
+ m_deco_ace->set_palette_effect_max((m_priority & 0x8) ? ((m_deco_ace->get_aceram(0x10) & 0x1000) ? 0x4ff : 0x6ff) : 0xfff);
+}
+
+WRITE16_MEMBER( boogwing_state::boogwing_ace_w )
+{
+ m_deco_ace->ace_w(space, offset, data, mem_mask);
+ if (offset == 0x10)
+ m_deco_ace->set_palette_effect_max((m_priority & 0x8) ? ((m_deco_ace->get_aceram(0x10) & 0x1000) ? 0x4ff : 0x6ff) : 0xfff);
}
@@ -157,7 +163,7 @@ void boogwing_state::boogwing_map(address_map &map)
map(0x282008, 0x282009).w(m_deco_ace, FUNC(deco_ace_device::palette_dma_w));
map(0x284000, 0x285fff).rw(m_deco_ace, FUNC(deco_ace_device::buffered_palette16_r), FUNC(deco_ace_device::buffered_palette16_w));
- map(0x3c0000, 0x3c004f).rw(m_deco_ace, FUNC(deco_ace_device::ace_r), FUNC(deco_ace_device::ace_w));
+ map(0x3c0000, 0x3c004f).r(m_deco_ace, FUNC(deco_ace_device::ace_r)).w(FUNC(boogwing_state::boogwing_ace_w));
}
void boogwing_state::decrypted_opcodes_map(address_map &map)
@@ -339,9 +345,9 @@ void boogwing_state::boogwing(machine_config &config)
m_audiocpu->add_route(ALL_OUTPUTS, "rspeaker", 0);
/* video hardware */
- screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
- screen.set_raw(MAIN_XTAL / 4, 442, 0, 320, 274, 8, 248); // same as robocop2(cninja.cpp)? verify this from real pcb.
- screen.set_screen_update(FUNC(boogwing_state::screen_update_boogwing));
+ SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
+ m_screen->set_raw(MAIN_XTAL / 4, 442, 0, 320, 274, 8, 248); // same as robocop2(cninja.cpp)? verify this from real pcb.
+ m_screen->set_screen_update(FUNC(boogwing_state::screen_update_boogwing));
GFXDECODE(config, "gfxdecode", m_deco_ace, gfx_boogwing);
diff --git a/src/mame/includes/boogwing.h b/src/mame/includes/boogwing.h
index e0c8f0a09a1..befca5714c8 100644
--- a/src/mame/includes/boogwing.h
+++ b/src/mame/includes/boogwing.h
@@ -13,6 +13,7 @@
#include "video/bufsprite.h"
#include "video/decospr.h"
#include "machine/deco104.h"
+#include "screen.h"
class boogwing_state : public driver_device
{
@@ -23,6 +24,7 @@ public:
, m_audiocpu(*this, "audiocpu")
, m_deco104(*this, "ioprot")
, m_deco_ace(*this, "deco_ace")
+ , m_screen(*this, "screen")
, m_deco_tilegen(*this, "tilegen%u", 1)
, m_oki(*this, "oki%u", 1)
, m_sprgen(*this, "spritegen%u", 1)
@@ -36,6 +38,7 @@ public:
required_device<h6280_device> m_audiocpu;
required_device<deco104_device> m_deco104;
required_device<deco_ace_device> m_deco_ace;
+ required_device<screen_device> m_screen;
required_device_array<deco16ic_device, 2> m_deco_tilegen;
required_device_array<okim6295_device, 2> m_oki;
required_device_array<decospr_device, 2> m_sprgen;
@@ -45,9 +48,11 @@ public:
required_shared_ptr<uint16_t> m_decrypted_opcodes;
uint16_t m_priority;
+ bitmap_ind16 m_alpha_tmap_bitmap;
DECLARE_WRITE8_MEMBER(sound_bankswitch_w);
DECLARE_WRITE16_MEMBER(priority_w);
+ DECLARE_WRITE16_MEMBER(boogwing_ace_w);
void init_boogwing();
virtual void machine_reset() override;
virtual void video_start() override;
diff --git a/src/mame/video/boogwing.cpp b/src/mame/video/boogwing.cpp
index d0b38966639..0072208c843 100644
--- a/src/mame/video/boogwing.cpp
+++ b/src/mame/video/boogwing.cpp
@@ -2,7 +2,6 @@
// copyright-holders:Bryan McPhail, David Haywood
#include "emu.h"
#include "includes/boogwing.h"
-#include "screen.h"
void boogwing_state::video_start()
@@ -10,6 +9,7 @@ void boogwing_state::video_start()
m_priority = 0;
m_sprgen[0]->alloc_sprite_bitmap();
m_sprgen[1]->alloc_sprite_bitmap();
+ m_screen->register_screen_bitmap(m_alpha_tmap_bitmap);
save_item(NAME(m_priority));
}
@@ -22,28 +22,32 @@ void boogwing_state::video_start()
fixed, with manual mixing you have full control.
apparently priority is based on a PROM, that should be used if possible.
+
+ Reference video : https://www.youtube.com/watch?v=mRdIlP_erBM (Live stream)
*/
void boogwing_state::mix_boogwing(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
int y, x;
const pen_t *paldata = &m_deco_ace->pen(0);
- bitmap_ind16 *sprite_bitmap1, *sprite_bitmap2;
+ bitmap_ind16 *sprite_bitmap1, *sprite_bitmap2, *alpha_tmap_bitmap;
bitmap_ind8* priority_bitmap;
uint16_t priority = m_priority;
sprite_bitmap1 = &m_sprgen[0]->get_sprite_temp_bitmap();
sprite_bitmap2 = &m_sprgen[1]->get_sprite_temp_bitmap();
+ alpha_tmap_bitmap = &m_alpha_tmap_bitmap;
priority_bitmap = &screen.priority();
uint32_t* dstline;
- uint16_t *srcline1, *srcline2;
+ uint16_t *srcline1, *srcline2, *srcline3;
uint8_t *srcpriline;
for (y=cliprect.top();y<=cliprect.bottom();y++)
{
srcline1=&sprite_bitmap1->pix16(y,0);
srcline2=&sprite_bitmap2->pix16(y,0);
+ srcline3=&alpha_tmap_bitmap->pix16(y,0);
srcpriline=&priority_bitmap->pix8(y,0);
dstline=&bitmap.pix32(y,0);
@@ -52,15 +56,18 @@ void boogwing_state::mix_boogwing(screen_device &screen, bitmap_rgb32 &bitmap, c
{
uint16_t pix1 = srcline1[x];
uint16_t pix2 = srcline2[x];
+ uint16_t pix3 = srcline3[x];
/* Here we have
- pix1 - raw pixel / colour / priority data from first 1sdt chip
+ pix1 - raw pixel / colour / priority data from first 1st chip
pix2 - raw pixel / colour / priority data from first 2nd chip
+ pix3 - raw pixel data from alpha blended tilemap
*/
- int pri1, pri2;
- int spri1, spri2, alpha2;
+ int pri1, pri2, pri3 = 0;
+ int spri1, spri2, alpha2, alpha3;
alpha2 = m_deco_ace->get_alpha((pix2 >> 4) & 0xf);
+ alpha3 = m_deco_ace->get_alpha(0x1f);
// pix1 sprite vs pix2 sprite
if (pix1 & 0x400) // TODO - check only in pri mode 2??
@@ -102,8 +109,14 @@ void boogwing_state::mix_boogwing(screen_device &screen, bitmap_rgb32 &bitmap, c
// Transparency
if (pix2 & 0x100)
- alpha2 = 0x80; // TODO : Uses 0x10-0x14 of Aceram?
- // alpha2 = m_deco_ace->get_alpha(0x14 + ((pix & 0xf0) > 0x50) ? 0x5 : ((pix2 >> 4) & 0x7)); This fixes explosion effects, but this is HACK.
+ {
+ if (pix2 & 0x800) // Use LUT, ex : Explosions
+ alpha2 = (pix2 & 8) ? 0xff : m_deco_ace->get_alpha(0x14 + (pix2 & 0x7)); // TODO : -1?
+ else
+ alpha2 = m_deco_ace->get_alpha(0x10 + ((pix2 & 0x80) >> 7));
+ }
+ else if (pix2 & 0x800)
+ alpha2 = m_deco_ace->get_alpha(0x12 + ((pix2 & 0x80) >> 7));
// pix2 sprite vs playfield
switch (priority)
@@ -124,6 +137,8 @@ void boogwing_state::mix_boogwing(screen_device &screen, bitmap_rgb32 &bitmap, c
}
break;
+ case 0x03:
+ pri3 = 32;
default:
{
if ((pix2 & 0x400) == 0x400)
@@ -142,6 +157,7 @@ void boogwing_state::mix_boogwing(screen_device &screen, bitmap_rgb32 &bitmap, c
spri1 - 8/32 (priority of sprite chip 1 relative to other sprite chip)
spri2 - 4/16/64 (priority of sprite chip 2 relative to other sprite chip)
alpha2 - 0x80/0xff alpha level of sprite chip 2 pixels (0x80 if enabled, 0xff if not)
+ alpha3 - alpha level of alpha-blended playfield pixels
bgpri - 0 / 8 / 32 (from drawing tilemaps earlier, to compare above pri1/pri2 priorities against)
pix1 - same as before (ready to extract just colour data from)
@@ -154,7 +170,7 @@ void boogwing_state::mix_boogwing(screen_device &screen, bitmap_rgb32 &bitmap, c
if (pri1 > bgpri)
{
dstline[x] = paldata[(pix1&0x1ff)+0x500];
- drawnpixe1 = 1;
+ drawnpixe1 |= 1;
}
}
@@ -173,6 +189,24 @@ void boogwing_state::mix_boogwing(screen_device &screen, bitmap_rgb32 &bitmap, c
uint32_t base = dstline[x];
dstline[x] = alpha_blend_r32(base, paldata[(pix2&0xff)+0x700], alpha2);
}
+ drawnpixe1 |= 2;
+ }
+ }
+ }
+
+ // alpha blended tilemap handling
+ if (pix3 & 0xf)
+ {
+ // TODO : sprite vs playfield priority, actual behavior of shadowing
+ if ((m_priority & 0x7) == 0x3)
+ {
+ bool bg2_drawed = (bgpri == 8) && (!drawnpixe1);
+ bool sprite1_drawed = (drawnpixe1 & 1) && (pri1 <= pri3);
+ bool sprite2_drawed = (drawnpixe1 & 2) && (pri2 <= pri3);
+ if ((bg2_drawed) || ((sprite1_drawed && (~drawnpixe1 & 2)) || (sprite2_drawed && (~drawnpixe1 & 1)) || (sprite1_drawed && sprite2_drawed)))
+ {
+ if (((pix2 & 0x900) != 0x900) || ((spri2 <= spri1) && sprite1_drawed))
+ dstline[x] = alpha_blend_r32(dstline[x], paldata[pix3], alpha3);
}
}
}
@@ -221,7 +255,8 @@ uint32_t boogwing_state::screen_update_boogwing(screen_device &screen, bitmap_rg
// This mode uses playfield 3 to shadow sprites & playfield 2 (instead of
// regular alpha-blending, the destination is inverted). Not yet implemented.
- // m_deco_tilegen[1]->tilemap_1_draw(screen, bitmap, cliprect, TILEMAP_DRAW_ALPHA(0x80), 32);
+ m_alpha_tmap_bitmap.fill(0, cliprect);
+ m_deco_tilegen[1]->tilemap_1_draw(screen, m_alpha_tmap_bitmap, cliprect, 0, 0); // 32
}
else
{
diff --git a/src/mame/video/deco_ace.cpp b/src/mame/video/deco_ace.cpp
index b734817a513..2a31c5c05c4 100644
--- a/src/mame/video/deco_ace.cpp
+++ b/src/mame/video/deco_ace.cpp
@@ -221,7 +221,7 @@ uint8_t deco_ace_device::get_alpha(uint8_t val)
int alpha = m_ace_ram[val] & 0xff;
if (alpha > 0x20)
{
- return 0x80; // TODO
+ return 0x80; // TODO : Special blending command? 0x21, 0x22 confirmed
}
else
{
@@ -241,7 +241,9 @@ uint8_t deco_ace_device::get_alpha(uint8_t val)
uint16_t deco_ace_device::get_aceram(uint8_t val)
{
- val &= 0x3f;
+ if (val >= 0x28)
+ return 0;
+
return m_ace_ram[val];
}