summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author David Haywood <mamehaze@gmail.com>2018-11-22 01:54:50 +0000
committer R. Belmont <rb6502@users.noreply.github.com>2018-11-21 20:54:50 -0500
commit1f4f1c4a30941dee2cb9b45bddd03055dd88ae8e (patch)
tree9ed3b61d9c0c69db2a1e311660e23fbc1be2b444
parent98b1f5a852e33e1a94f334303b4b3847e05b0586 (diff)
World Rally / Blomby Car improvements (shadow / headlight in Blomby Car) (#4318)
* experimental code (nw) * better code, fix issues (nw) * works for both games (nw) * refactor (nw) * this seems to match reference material (nw)
-rw-r--r--scripts/target/mame/arcade.lua8
-rw-r--r--src/mame/drivers/blmbycar.cpp13
-rw-r--r--src/mame/drivers/wrally.cpp5
-rw-r--r--src/mame/includes/blmbycar.h5
-rw-r--r--src/mame/includes/wrally.h9
-rw-r--r--src/mame/machine/wrally.cpp2
-rw-r--r--src/mame/video/blmbycar.cpp110
-rw-r--r--src/mame/video/gaelco_wrally_sprites.cpp243
-rw-r--r--src/mame/video/gaelco_wrally_sprites.h48
-rw-r--r--src/mame/video/wrally.cpp137
10 files changed, 350 insertions, 230 deletions
diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua
index 9773c6c9f8c..2c2dca39817 100644
--- a/scripts/target/mame/arcade.lua
+++ b/scripts/target/mame/arcade.lua
@@ -1311,9 +1311,6 @@ files {
createMAMEProjects(_target, _subtarget, "atlus")
files {
- MAME_DIR .. "src/mame/drivers/blmbycar.cpp",
- MAME_DIR .. "src/mame/includes/blmbycar.h",
- MAME_DIR .. "src/mame/video/blmbycar.cpp",
MAME_DIR .. "src/mame/drivers/ohmygod.cpp",
MAME_DIR .. "src/mame/includes/ohmygod.h",
MAME_DIR .. "src/mame/video/ohmygod.cpp",
@@ -1913,6 +1910,11 @@ files {
MAME_DIR .. "src/mame/includes/wrally.h",
MAME_DIR .. "src/mame/machine/wrally.cpp",
MAME_DIR .. "src/mame/video/wrally.cpp",
+ MAME_DIR .. "src/mame/drivers/blmbycar.cpp",
+ MAME_DIR .. "src/mame/includes/blmbycar.h",
+ MAME_DIR .. "src/mame/video/blmbycar.cpp",
+ MAME_DIR .. "src/mame/video/gaelco_wrally_sprites.cpp",
+ MAME_DIR .. "src/mame/video/gaelco_wrally_sprites.h",
MAME_DIR .. "src/mame/drivers/xorworld.cpp",
MAME_DIR .. "src/mame/includes/xorworld.h",
MAME_DIR .. "src/mame/video/xorworld.cpp",
diff --git a/src/mame/drivers/blmbycar.cpp b/src/mame/drivers/blmbycar.cpp
index 4cf229df310..1d5ae8648ec 100644
--- a/src/mame/drivers/blmbycar.cpp
+++ b/src/mame/drivers/blmbycar.cpp
@@ -120,8 +120,7 @@ void blmbycar_state::common_map(address_map &map)
map(0x108000, 0x10bfff).writeonly(); // ???
map(0x10c000, 0x10c003).writeonly().share("scroll_1"); // Scroll 1
map(0x10c004, 0x10c007).writeonly().share("scroll_0"); // Scroll 0
- map(0x200000, 0x2005ff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette").mirror(0x4000); // Palette
- map(0x200600, 0x203fff).ram().mirror(0x4000);
+ map(0x200000, 0x203fff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette").mirror(0x4000); // Palette
map(0x440000, 0x441fff).ram();
map(0x444000, 0x445fff).writeonly().share("spriteram");// Sprites (size?)
map(0x700000, 0x700001).portr("DSW");
@@ -189,7 +188,7 @@ static INPUT_PORTS_START( blmbycar )
PORT_DIPSETTING( 0x0018, DEF_STR( Joystick ) )
PORT_DIPSETTING( 0x0010, "Pot Wheel" ) // Preliminary
PORT_DIPSETTING( 0x0008, "Opt Wheel" ) // Preliminary
-// PORT_DIPSETTING( 0x0000, DEF_STR( Unused ) ) // Time goes to 0 rally fast!
+ PORT_DIPSETTING( 0x0000, "invalid, breaks game" ) // Time goes to 0 rally fast!
PORT_DIPNAME( 0x0020, 0x0000, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW1:3")
PORT_DIPSETTING( 0x0020, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
@@ -337,7 +336,7 @@ static const gfx_layout layout_16x16x4 =
/* Layers both use the first $20 color codes. Sprites the next $10 */
static GFXDECODE_START( gfx_blmbycar )
- GFXDECODE_ENTRY( "sprites", 0, layout_16x16x4, 0x0, 0x30 ) // [0] Layers + Sprites
+ GFXDECODE_ENTRY( "sprites", 0, layout_16x16x4, 0x0, 64*8 ) // [0] Layers + Sprites
GFXDECODE_END
@@ -386,9 +385,13 @@ MACHINE_CONFIG_START(blmbycar_state::blmbycar)
MCFG_DEVICE_ADD("gfxdecode", GFXDECODE, "palette", gfx_blmbycar)
- MCFG_PALETTE_ADD("palette", 0x300)
+ MCFG_PALETTE_ADD("palette", 0x2000)
MCFG_PALETTE_FORMAT(xxxxBBBBRRRRGGGG)
+ BLMBYCAR_SPRITES(config, m_sprites, 0);
+ m_sprites->set_gfxdecode_tag("gfxdecode");
+ m_sprites->set_screen_tag("screen");
+
/* sound hardware */
SPEAKER(config, "mono").front_center();
diff --git a/src/mame/drivers/wrally.cpp b/src/mame/drivers/wrally.cpp
index 5d9f0b2c825..a0322621d0b 100644
--- a/src/mame/drivers/wrally.cpp
+++ b/src/mame/drivers/wrally.cpp
@@ -187,6 +187,7 @@ static INPUT_PORTS_START( wrally )
PORT_DIPSETTING( 0x0018, DEF_STR( Joystick ) )
PORT_DIPSETTING( 0x0010, "Pot Wheel" )
PORT_DIPSETTING( 0x0000, "Optical Wheel" )
+ PORT_DIPSETTING( 0x0008, "invalid" )
PORT_DIPNAME( 0x0020, 0x0000, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW2:3")
PORT_DIPSETTING( 0x0020, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
@@ -285,6 +286,10 @@ MACHINE_CONFIG_START(wrally_state::wrally)
MCFG_PALETTE_ADD("palette", 1024*8)
MCFG_PALETTE_FORMAT(xxxxBBBBRRRRGGGG)
+ GAELCO_WRALLY_SPRITES(config, m_sprites, 0);
+ m_sprites->set_gfxdecode_tag("gfxdecode");
+ m_sprites->set_screen_tag("screen");
+
LS259(config, m_outlatch);
m_outlatch->q_out_cb<0>().set(FUNC(wrally_state::coin1_lockout_w));
m_outlatch->q_out_cb<1>().set(FUNC(wrally_state::coin2_lockout_w));
diff --git a/src/mame/includes/blmbycar.h b/src/mame/includes/blmbycar.h
index 9734673753c..43ab525d0bd 100644
--- a/src/mame/includes/blmbycar.h
+++ b/src/mame/includes/blmbycar.h
@@ -7,6 +7,7 @@
***************************************************************************/
#include "emupal.h"
+#include "video/gaelco_wrally_sprites.h"
class blmbycar_state : public driver_device
{
@@ -16,6 +17,7 @@ public:
m_maincpu(*this, "maincpu"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette"),
+ m_sprites(*this, "sprites"),
m_vram(*this, "vram_%u", 0U),
m_scroll(*this, "scroll_%u", 0U),
m_spriteram(*this, "spriteram"),
@@ -35,7 +37,8 @@ private:
required_device<cpu_device> m_maincpu;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
-
+ required_device<gaelco_wrally_sprites_device> m_sprites;
+
/* memory pointers */
required_shared_ptr_array<uint16_t, 2> m_vram;
required_shared_ptr_array<uint16_t, 2> m_scroll;
diff --git a/src/mame/includes/wrally.h b/src/mame/includes/wrally.h
index 86f49940d3b..d9e04714e8c 100644
--- a/src/mame/includes/wrally.h
+++ b/src/mame/includes/wrally.h
@@ -7,6 +7,7 @@
#include "machine/74259.h"
#include "emupal.h"
+#include "video/gaelco_wrally_sprites.h"
class wrally_state : public driver_device
{
@@ -17,12 +18,13 @@ public:
m_outlatch(*this, "outlatch"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette"),
+ m_sprites(*this, "sprites"),
m_okibank(*this, "okibank"),
m_videoram(*this, "videoram"),
m_vregs(*this, "vregs"),
m_spriteram(*this, "spriteram"),
m_shareram(*this, "shareram"),
- m_pant{ nullptr, nullptr }
+ m_tilemap{ nullptr, nullptr }
{
}
@@ -49,12 +51,11 @@ private:
void oki_map(address_map &map);
void wrally_map(address_map &map);
- void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int priority);
-
required_device<cpu_device> m_maincpu;
required_device<ls259_device> m_outlatch;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
+ required_device<gaelco_wrally_sprites_device> m_sprites;
required_memory_bank m_okibank;
required_shared_ptr<uint16_t> m_videoram;
@@ -62,7 +63,7 @@ private:
required_shared_ptr<uint16_t> m_spriteram;
required_shared_ptr<uint16_t> m_shareram;
- tilemap_t *m_pant[2];
+ tilemap_t *m_tilemap[2];
};
#endif // MAME_INCLUDES_WRALLY_H
diff --git a/src/mame/machine/wrally.cpp b/src/mame/machine/wrally.cpp
index 8e0e273f15e..7721b6cbe31 100644
--- a/src/mame/machine/wrally.cpp
+++ b/src/mame/machine/wrally.cpp
@@ -43,7 +43,7 @@ WRITE16_MEMBER(wrally_state::vram_w)
data = gaelco_decrypt(space, offset, data, 0x1f, 0x522a);
COMBINE_DATA(&m_videoram[offset]);
- m_pant[(offset & 0x1fff) >> 12]->mark_tile_dirty(((offset << 1) & 0x1fff) >> 2);
+ m_tilemap[(offset & 0x1fff) >> 12]->mark_tile_dirty(((offset << 1) & 0x1fff) >> 2);
}
WRITE_LINE_MEMBER(wrally_state::flipscreen_w)
diff --git a/src/mame/video/blmbycar.cpp b/src/mame/video/blmbycar.cpp
index 68a9a38a649..d6bcb3f8e29 100644
--- a/src/mame/video/blmbycar.cpp
+++ b/src/mame/video/blmbycar.cpp
@@ -79,87 +79,9 @@ void blmbycar_state::video_start()
{
m_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(blmbycar_state::get_tile_info<0>),this), TILEMAP_SCAN_ROWS, 16, 16, DIM_NX, DIM_NY );
m_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(blmbycar_state::get_tile_info<1>),this), TILEMAP_SCAN_ROWS, 16, 16, DIM_NX, DIM_NY );
-
- m_tilemap[0]->set_scroll_rows(1);
- m_tilemap[0]->set_scroll_cols(1);
-
- m_tilemap[1]->set_scroll_rows(1);
- m_tilemap[1]->set_scroll_cols(1);
m_tilemap[1]->set_transparent_pen(0);
}
-
-/***************************************************************************
-
-
- Sprites Drawing
-
- Offset: Bits: Value:
-
- 0.w f--- ---- ---- ---- End Of Sprites
- -edc ba9- ---- ----
- ---- ---8 7654 3210 Y (Signed)
-
- 2.w Code
-
- 4.w f--- ---- ---- ---- Flip Y
- -e-- ---- ---- ---- Flip X
- --dc ba98 7654 ----
- ---- ---- ---- 3210 Color (Bit 3 = Priority)
-
- 6.w f--- ---- ---- ---- ? Is this ever used ?
- -e-- ---- ---- ---- ? 1 = Don't Draw ?
- --dc ba9- ---- ----
- ---- ---8 7654 3210 X (Signed)
-
-
-***************************************************************************/
-
-void blmbycar_state::draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect )
-{
- uint16_t *source, *finish;
-
- source = m_spriteram + 0x6 / 2; // !
- finish = m_spriteram + m_spriteram.bytes() / 2 - 8 / 2;
-
- /* Find "the end of sprites" marker */
-
- for ( ; source < finish; source += 8 / 2 )
- if (source[0] & 0x8000) break;
-
- /* Draw sprites in reverse order for pdrawfgfx */
-
- source -= 8 / 2;
- finish = m_spriteram;
-
- for ( ; source >= finish; source -= 8 / 2 )
- {
- int y = source[0];
- int code = source[1];
- int attr = source[2];
- int x = source[3];
-
- int flipx = attr & 0x4000;
- int flipy = attr & 0x8000;
- int pri = (~attr >> 3) & 0x1; // Priority (1 = Low)
- int pri_mask = ~((1 << (pri+1)) - 1); // Above the first "pri" levels
-
- if (x & 0x4000) continue; // ? To get rid of the "shadow" blocks
-
- x = (x & 0x1ff) - 0x10;
- y = 0xf0 - ((y & 0xff) - (y & 0x100));
-
- m_gfxdecode->gfx(0)->prio_transpen(bitmap,cliprect,
- code,
- 0x20 + (attr & 0xf),
- flipx, flipy,
- x, y,
- screen.priority(),
- pri_mask,0);
- }
-}
-
-
/***************************************************************************
@@ -170,7 +92,7 @@ void blmbycar_state::draw_sprites( screen_device &screen, bitmap_ind16 &bitmap,
uint32_t blmbycar_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
- int i, layers_ctrl = -1;
+ m_sprites->draw_sprites(cliprect,m_spriteram,flip_screen());
m_tilemap[0]->set_scrolly(0, m_scroll[0][0]);
m_tilemap[0]->set_scrollx(0, m_scroll[0][1]);
@@ -178,33 +100,19 @@ uint32_t blmbycar_state::screen_update(screen_device &screen, bitmap_ind16 &bitm
m_tilemap[1]->set_scrolly(0, m_scroll[1][0] + 1);
m_tilemap[1]->set_scrollx(0, m_scroll[1][1] + 5);
-#ifdef MAME_DEBUG
-if (machine().input().code_pressed(KEYCODE_Z))
-{
- int msk = 0;
+ screen.priority().fill(0, cliprect);
- if (machine().input().code_pressed(KEYCODE_Q)) msk |= 1;
- if (machine().input().code_pressed(KEYCODE_W)) msk |= 2;
-// if (machine().input().code_pressed(KEYCODE_E)) msk |= 4;
- if (machine().input().code_pressed(KEYCODE_A)) msk |= 8;
- if (msk != 0) layers_ctrl &= msk;
-}
-#endif
+ bitmap.fill(0, cliprect);
- screen.priority().fill(0, cliprect);
+ m_tilemap[0]->draw(screen, bitmap, cliprect, 0, 0);
+ m_tilemap[1]->draw(screen, bitmap, cliprect, 0, 0);
- if (layers_ctrl & 1)
- for (i = 0; i <= 1; i++)
- m_tilemap[0]->draw(screen, bitmap, cliprect, i, i);
- else
- bitmap.fill(0, cliprect);
+ m_sprites->mix_sprites(bitmap, cliprect, 0);
- if (layers_ctrl & 2)
- for (i = 0; i <= 1; i++)
- m_tilemap[1]->draw(screen, bitmap, cliprect, i, i);
+ m_tilemap[0]->draw(screen, bitmap, cliprect, 1, 1);
+ m_tilemap[1]->draw(screen, bitmap, cliprect, 1, 1);
- if (layers_ctrl & 8)
- draw_sprites(screen, bitmap, cliprect);
+ m_sprites->mix_sprites(bitmap, cliprect, 1);
return 0;
}
diff --git a/src/mame/video/gaelco_wrally_sprites.cpp b/src/mame/video/gaelco_wrally_sprites.cpp
new file mode 100644
index 00000000000..6ce719939c9
--- /dev/null
+++ b/src/mame/video/gaelco_wrally_sprites.cpp
@@ -0,0 +1,243 @@
+// license:BSD-3-Clause
+// copyright-holders:Manuel Abadia, Mike Coates, Nicola Salmoria, Miguel Angel Horna, Luca Elia, David Haywood
+
+#include "emu.h"
+#include "gaelco_wrally_sprites.h"
+
+DEFINE_DEVICE_TYPE(GAELCO_WRALLY_SPRITES, gaelco_wrally_sprites_device, "gaelco_wrally_sprites", "Gaelco World Rally Sprites")
+DEFINE_DEVICE_TYPE(BLMBYCAR_SPRITES, blmbycar_sprites_device, "blmbycar_sprites", "Blomby Car Sprites")
+
+gaelco_wrally_sprites_device::gaelco_wrally_sprites_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, type, tag, owner, clock)
+ , m_gfxdecode(*this, finder_base::DUMMY_TAG)
+ , m_screen(*this, finder_base::DUMMY_TAG)
+{
+}
+
+gaelco_wrally_sprites_device::gaelco_wrally_sprites_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : gaelco_wrally_sprites_device(mconfig, GAELCO_WRALLY_SPRITES, tag, owner, clock)
+{
+}
+
+void gaelco_wrally_sprites_device::device_start()
+{
+ m_screen->register_screen_bitmap(m_temp_bitmap_sprites);
+}
+
+void gaelco_wrally_sprites_device::device_reset()
+{
+}
+
+
+/*
+ Sprite Format
+ -------------
+
+ Offs | Bit(s) | Description
+ -----+-FEDCBA98-76543210-+--------------------------
+ 0 | -------- xxxxxxxx | y position
+ 0 | --xxxxxx -------- | not used?
+ 0 | -x------ -------- | flipx
+ 0 | x------- -------- | flipy
+
+ 1 | xxxxxxxx xxxxxxxx | unknown
+
+ 2 | ------xx xxxxxxxx | x position
+ 2 | --xxxx-- -------- | sprite color (low 4 bits)
+ 2 | -x------ -------- | shadows/highlights (see below)
+ 2 | x------- -------- | not used?
+
+ 3 | --xxxxxx xxxxxxxx | sprite code
+ 3 | xx------ -------- | not used?
+
+ For shadows/highlights, the tile color below the sprite will be set using a
+ palette (from the 8 available) based on the gfx pen of the sprite. Only pens
+ in the range 0x8-0xf are used.
+*/
+
+void gaelco_wrally_sprites_device::get_sprites_info(uint16_t* spriteram, int& sx, int& sy, int& number, int& color, int& color_effect, int& attr, int& high_priority, int &end)
+{
+ sx = spriteram[2] & 0x03ff;
+ sy = (240 - (spriteram[0] & 0x00ff)) & 0x00ff;
+ number = spriteram[3] & 0x3fff;
+ color = (spriteram[2] & 0x7c00) >> 10;
+ color_effect = (color & 0x10) >> 4;
+ attr = (spriteram[0] & 0xfe00) >> 9;
+ high_priority = number >= 0x3700; // HACK! this is almost certainly not how the priority is determined
+ end = 0;
+}
+
+void gaelco_wrally_sprites_device::draw_sprites(const rectangle &cliprect, uint16_t* spriteram, int flip_screen)
+{
+ m_temp_bitmap_sprites.fill(0, cliprect);
+
+ int i;
+ gfx_element *gfx = m_gfxdecode->gfx(0);
+
+ for (i = 6 / 2; i < (0x1000 - 6) / 2; i += 4)
+ {
+ int sx, sy, number, color, attr, end, color_effect, high_priority;
+
+ get_sprites_info(spriteram + i, sx, sy, number, color, color_effect, attr, high_priority, end);
+
+ if (end)
+ break;
+
+ int xflip = attr & 0x20;
+ int yflip = attr & 0x40;
+ color = color & 0x0f;
+
+ if (flip_screen)
+ {
+ sy = sy + 248;
+ }
+
+ // wrally adjusts sx by 0x0f, blmbycar implementation was 0x10
+ const uint8_t *gfx_src = gfx->get_data(number % gfx->elements());
+
+ for (int py = 0; py < gfx->height(); py++)
+ {
+ /* get a pointer to the current line in the screen bitmap */
+ int ypos = ((sy + py) & 0x1ff);
+ uint16_t *srcy = &m_temp_bitmap_sprites.pix16(ypos);
+
+ int gfx_py = yflip ? (gfx->height() - 1 - py) : py;
+
+ if ((ypos < cliprect.min_y) || (ypos > cliprect.max_y)) continue;
+
+ for (int px = 0; px < gfx->width(); px++)
+ {
+ /* get current pixel */
+ int xpos = (((sx + px) & 0x3ff) - 0x0f) & 0x3ff;
+ uint16_t *pixel = srcy + xpos;
+ int gfx_px = xflip ? (gfx->width() - 1 - px) : px;
+
+ /* get asociated pen for the current sprite pixel */
+ int gfx_pen = gfx_src[gfx->rowbytes()*gfx_py + gfx_px];
+
+ if ((xpos < cliprect.min_x) || (xpos > cliprect.max_x)) continue;
+
+ if (!color_effect)
+ {
+ if (gfx_pen)
+ {
+ *pixel = gfx_pen | (color << 4) | (high_priority << 8);
+ }
+ }
+ else
+ {
+ int src_color = *pixel;
+
+ /* pens 8..15 are used to select a palette */
+ if ((gfx_pen < 8) || (gfx_pen >= 16)) continue;
+
+ // if there's already a sprite pixel use the existing priority value? (or you get a glitch against the start line arch at the start of a night stage) possibly because existing priority scheme is bogus?
+ // this causes a slight shadow of your car to be visible as you pass through the arch instead, but looking at 14:01 in this video seems to show the same on a PCB https://www.youtube.com/watch?v=vZUUK8c-GZ0
+ if (src_color != 0)
+ {
+ *pixel = src_color |= ((gfx_pen - 8) << 12) | 0x200;
+ }
+ else
+ {
+ /* modify the color of the tile - the pen modifier can be applied over existing sprite pixels, so we store it in the upper bits that we send to the mixer */
+ *pixel = (src_color &0xff) | ((gfx_pen - 8) << 12) | (high_priority << 8) | 0x200;
+ }
+ }
+ }
+ }
+ }
+}
+
+void gaelco_wrally_sprites_device::mix_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int priority)
+{
+ for (int y = cliprect.min_y; y < cliprect.max_y; y++)
+ {
+ const uint16_t* spriteptr = &m_temp_bitmap_sprites.pix16(y);
+ uint16_t* dstptr = &bitmap.pix16(y);
+
+ for (int x = cliprect.min_x; x < cliprect.max_x; x++)
+ {
+ if (spriteptr[x] != 0)
+ {
+ // this is how we've packed the bits here
+ // ssss --ez PPPP pppp s = shadow multiplier e = shadow enabled, z = priority, P = palette select, p = pen
+
+ const int pridat = (spriteptr[x] & 0x100) >> 8;
+
+ if (pridat == priority)
+ {
+ const int shadow = (spriteptr[x] & 0x200) >> 9;
+
+ if (!shadow)
+ {
+ const uint16_t pendat = (spriteptr[x] & 0xff);
+ dstptr[x] = pendat + 0x200;
+ }
+ else
+ {
+ const uint16_t pendat = (spriteptr[x] & 0xff);
+ const int shadowlevel = (spriteptr[x] & 0xf000) >> 12;
+
+ if (pendat != 0)
+ {
+ dstptr[x] = (pendat + 0x200) + (shadowlevel * 0x400);
+ }
+ else
+ {
+ dstptr[x] = (dstptr[x]&0x3ff) + (shadowlevel * 0x400);
+ }
+ }
+ }
+ }
+
+ }
+ }
+}
+
+/***************************************************************************
+
+
+ Sprites Drawing
+
+ Offset: Bits: Value:
+
+ 0 f--- ---- ---- ---- End Of Sprites
+ -edc ba9- ---- ----
+ ---- ---8 7654 3210 Y (Signed)
+
+ 1 Code
+
+ 2 f--- ---- ---- ---- Flip Y
+ -e-- ---- ---- ---- Flip X
+ --dc ba98 7654 ----
+ ---- ---- ---- 3210 Color (Bit 3 = Priority)
+
+ 3 f--- ---- ---- ---- ? Is this ever used ?
+ -e-- ---- ---- ---- ? 1 = shadow sprite!
+ --dc ba9- ---- ----
+ ---- ---8 7654 3210 X (Signed)
+
+
+***************************************************************************/
+
+blmbycar_sprites_device::blmbycar_sprites_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : gaelco_wrally_sprites_device(mconfig, BLMBYCAR_SPRITES, tag, owner, clock)
+{
+}
+
+void blmbycar_sprites_device::get_sprites_info(uint16_t* spriteram, int& sx, int& sy, int& number, int& color, int& color_effect, int& attr, int& high_priority, int &end)
+{
+ // bytes are swapped around and color attribute is moved
+ sx = spriteram[3] & 0x03ff;
+ sy = (spriteram[0] & 0x01ff);
+ sy = 0xf0 - ((sy & 0xff) - (sy & 0x100)); // check if this logic works for wrally
+
+ number = spriteram[1] & 0x3fff;
+ color = (spriteram[2] & 0x000f) >> 0; // note moved
+ color_effect = (spriteram[3] & 0x4000) >> 14;
+
+ attr = (spriteram[2] & 0xfe00) >> 9;
+ end = (spriteram[0] & 0x8000); // does wrally have this too?
+
+ high_priority = (~(color >> 3))&1;
+}
diff --git a/src/mame/video/gaelco_wrally_sprites.h b/src/mame/video/gaelco_wrally_sprites.h
new file mode 100644
index 00000000000..19b450d8217
--- /dev/null
+++ b/src/mame/video/gaelco_wrally_sprites.h
@@ -0,0 +1,48 @@
+// license:BSD-3-Clause
+// copyright-holders:Manuel Abadia, Mike Coates, Nicola Salmoria, Miguel Angel Horna, Luca Elia, David Haywood
+#ifndef MAME_VIDEO_GAELCO_WRALLY_SPRITES_H
+#define MAME_VIDEO_GAELCO_WRALLY_SPRITES_H
+
+#pragma once
+
+#include "screen.h"
+
+class gaelco_wrally_sprites_device : public device_t
+{
+public:
+ gaelco_wrally_sprites_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ template <typename T> void set_gfxdecode_tag(T &&tag) { m_gfxdecode.set_tag(std::forward<T>(tag)); }
+ template <typename T> void set_screen_tag(T &&tag) { m_screen.set_tag(std::forward<T>(tag)); }
+
+ void draw_sprites(const rectangle &cliprect, uint16_t* spriteram, int flip_screen);
+ void mix_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int priority);
+
+protected:
+ gaelco_wrally_sprites_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
+
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ virtual void get_sprites_info(uint16_t* spriteram, int& sx, int& sy, int& number, int& color, int& color_effect, int& attr, int& high_priotiy, int &end);
+
+private:
+ required_device<gfxdecode_device> m_gfxdecode;
+ required_device<screen_device> m_screen;
+
+ bitmap_ind16 m_temp_bitmap_sprites;
+};
+
+class blmbycar_sprites_device : public gaelco_wrally_sprites_device
+{
+public:
+ blmbycar_sprites_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ virtual void get_sprites_info(uint16_t* spriteram, int& sx, int& sy, int& number, int& color, int& color_effect, int& attr, int& high_priotiy, int &end) override;
+};
+
+DECLARE_DEVICE_TYPE(GAELCO_WRALLY_SPRITES, gaelco_wrally_sprites_device)
+DECLARE_DEVICE_TYPE(BLMBYCAR_SPRITES, blmbycar_sprites_device)
+
+#endif // MAME_VIDEO_GAELCO_WRALLY_SPRITES_H
diff --git a/src/mame/video/wrally.cpp b/src/mame/video/wrally.cpp
index 7f24ecb63b9..c3a96bc6fb7 100644
--- a/src/mame/video/wrally.cpp
+++ b/src/mame/video/wrally.cpp
@@ -56,106 +56,11 @@ TILE_GET_INFO_MEMBER(wrally_state::get_tile_info)
void wrally_state::video_start()
{
- m_pant[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(wrally_state::get_tile_info<0>),this),TILEMAP_SCAN_ROWS,16,16,64,32);
- m_pant[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(wrally_state::get_tile_info<1>),this),TILEMAP_SCAN_ROWS,16,16,64,32);
+ m_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(wrally_state::get_tile_info<0>),this),TILEMAP_SCAN_ROWS,16,16,64,32);
+ m_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(wrally_state::get_tile_info<1>),this),TILEMAP_SCAN_ROWS,16,16,64,32);
- m_pant[0]->set_transmask(0,0xff01,0x00ff); /* this layer is split in two (pens 1..7, pens 8-15) */
- m_pant[1]->set_transparent_pen(0);
-}
-
-
-/***************************************************************************
-
- Sprites
-
-***************************************************************************/
-
-/*
- Sprite Format
- -------------
-
- Word | Bit(s) | Description
- -----+-FEDCBA98-76543210-+--------------------------
- 0 | -------- xxxxxxxx | y position
- 0 | --xxxxxx -------- | not used?
- 0 | -x------ -------- | flipx
- 0 | x------- -------- | flipy
- 1 | xxxxxxxx xxxxxxxx | unknown
- 2 | ------xx xxxxxxxx | x position
- 2 | --xxxx-- -------- | sprite color (low 4 bits)
- 2 | -x------ -------- | shadows/highlights (see below)
- 2 | x------- -------- | not used?
- 3 | --xxxxxx xxxxxxxx | sprite code
- 3 | xx------ -------- | not used?
-
- For shadows/highlights, the tile color below the sprite will be set using a
- palette (from the 8 available) based on the gfx pen of the sprite. Only pens
- in the range 0x8-0xf are used.
-*/
-
-void wrally_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int priority)
-{
- int i, px, py;
- gfx_element *gfx = m_gfxdecode->gfx(0);
-
- for (i = 6/2; i < (0x1000 - 6)/2; i += 4) {
- int sx = m_spriteram[i+2] & 0x03ff;
- int sy = (240 - (m_spriteram[i] & 0x00ff)) & 0x00ff;
- int number = m_spriteram[i+3] & 0x3fff;
- int color = (m_spriteram[i+2] & 0x7c00) >> 10;
- int attr = (m_spriteram[i] & 0xfe00) >> 9;
-
- int xflip = attr & 0x20;
- int yflip = attr & 0x40;
- int color_effect = (color & 0x10) >> 4;
- int high_priority = number >= 0x3700;
- color = color & 0x0f;
-
- if (high_priority != priority) continue;
-
- if (flip_screen()) {
- sy = sy + 248;
- }
-
- if (!color_effect) {
- gfx->transpen(bitmap,cliprect,number,
- 0x20 + color,xflip,yflip,
- sx - 0x0f,sy,0);
- } else {
- /* get a pointer to the current sprite's gfx data */
- const uint8_t *gfx_src = gfx->get_data(number % gfx->elements());
-
- for (py = 0; py < gfx->height(); py++){
- /* get a pointer to the current line in the screen bitmap */
- int ypos = ((sy + py) & 0x1ff);
- uint16_t *srcy = &bitmap.pix16(ypos);
-
- int gfx_py = yflip ? (gfx->height() - 1 - py) : py;
-
- if ((ypos < cliprect.min_y) || (ypos > cliprect.max_y)) continue;
-
- for (px = 0; px < gfx->width(); px++){
- /* get current pixel */
- int xpos = (((sx + px) & 0x3ff) - 0x0f) & 0x3ff;
- uint16_t *pixel = srcy + xpos;
- int src_color = *pixel;
-
- int gfx_px = xflip ? (gfx->width() - 1 - px) : px;
-
- /* get asociated pen for the current sprite pixel */
- int gfx_pen = gfx_src[gfx->rowbytes()*gfx_py + gfx_px];
-
- /* pens 8..15 are used to select a palette */
- if ((gfx_pen < 8) || (gfx_pen >= 16)) continue;
-
- if ((xpos < cliprect.min_x) || (xpos > cliprect.max_x)) continue;
-
- /* modify the color of the tile */
- *pixel = src_color + (gfx_pen-8)*1024;
- }
- }
- }
- }
+ m_tilemap[0]->set_transmask(0,0xff01,0x00ff); /* this layer is split in two (pens 1..7, pens 8-15) */
+ m_tilemap[1]->set_transparent_pen(0);
}
/***************************************************************************
@@ -166,32 +71,34 @@ void wrally_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect,
uint32_t wrally_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
+ m_sprites->draw_sprites(cliprect,m_spriteram,flip_screen());
+
/* set scroll registers */
if (!flip_screen()) {
- m_pant[0]->set_scrolly(0, m_vregs[0]);
- m_pant[0]->set_scrollx(0, m_vregs[1]+4);
- m_pant[1]->set_scrolly(0, m_vregs[2]);
- m_pant[1]->set_scrollx(0, m_vregs[3]);
+ m_tilemap[0]->set_scrolly(0, m_vregs[0]);
+ m_tilemap[0]->set_scrollx(0, m_vregs[1]+4);
+ m_tilemap[1]->set_scrolly(0, m_vregs[2]);
+ m_tilemap[1]->set_scrollx(0, m_vregs[3]);
} else {
- m_pant[0]->set_scrolly(0, 248 - m_vregs[0]);
- m_pant[0]->set_scrollx(0, 1024 - m_vregs[1] - 4);
- m_pant[1]->set_scrolly(0, 248 - m_vregs[2]);
- m_pant[1]->set_scrollx(0, 1024 - m_vregs[3]);
+ m_tilemap[0]->set_scrolly(0, 248 - m_vregs[0]);
+ m_tilemap[0]->set_scrollx(0, 1024 - m_vregs[1] - 4);
+ m_tilemap[1]->set_scrolly(0, 248 - m_vregs[2]);
+ m_tilemap[1]->set_scrollx(0, 1024 - m_vregs[3]);
}
/* draw tilemaps + sprites */
- m_pant[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE,0);
- m_pant[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_CATEGORY(0) | TILEMAP_DRAW_LAYER0,0);
- m_pant[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_CATEGORY(0) | TILEMAP_DRAW_LAYER1,0);
+ m_tilemap[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE,0);
+ m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_CATEGORY(0) | TILEMAP_DRAW_LAYER0,0);
+ m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_CATEGORY(0) | TILEMAP_DRAW_LAYER1,0);
- m_pant[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_CATEGORY(1),0);
- m_pant[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_CATEGORY(1) | TILEMAP_DRAW_LAYER0,0);
+ m_tilemap[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_CATEGORY(1),0);
+ m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_CATEGORY(1) | TILEMAP_DRAW_LAYER0,0);
- draw_sprites(bitmap,cliprect,0);
+ m_sprites->mix_sprites(bitmap, cliprect, 0);
- m_pant[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_CATEGORY(1) | TILEMAP_DRAW_LAYER1,0);
+ m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_CATEGORY(1) | TILEMAP_DRAW_LAYER1,0);
- draw_sprites(bitmap,cliprect,1);
+ m_sprites->mix_sprites(bitmap, cliprect, 1);
return 0;
}