mirror of
https://github.com/holub/mame
synced 2025-04-19 23:12:11 +03:00
CG-1V/GAE1 video/audio fixes (#8859)
* CG-1V/GAE1 video/audio fixes - support y scroll in rowscroll mode - prevent shadow sprites from corrupting previously drawn shadow sprites - fix cases of samples not being played where the 2nd chunk addresses are written first - remove old hack to work around ancient MAME number of colour limits * Misc Gaelco improvements - fixed thoop, squash priorities - added IRQ acks - set Maniac Square prototype to 1992, and de-cloned it. I'm told this was an earlier project that was redone from scratch for the released game - demoted Thunder Hoop to NOT WORKING due to the stage 4 crash
This commit is contained in:
parent
73b6d39404
commit
22fd521abc
@ -1,5 +1,5 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Manuel Abadia
|
||||
// copyright-holders:Manuel Abadia, David Haywood
|
||||
/***************************************************************************
|
||||
Gaelco Sound Hardware
|
||||
|
||||
@ -215,35 +215,53 @@ void gaelco_gae1_device::gaelcosnd_w(offs_t offset, uint16_t data, uint16_t mem_
|
||||
|
||||
COMBINE_DATA(&m_sndregs[offset]);
|
||||
|
||||
switch(offset & 0x07)
|
||||
switch (offset & 0x07)
|
||||
{
|
||||
case 0x03:
|
||||
/* trigger sound */
|
||||
if ((m_sndregs[offset - 1] != 0) && (data != 0))
|
||||
case 0x03:
|
||||
// if sample end position isn't 0, and length isn't 0
|
||||
if ((m_sndregs[offset - 1] != 0) && (data != 0))
|
||||
{
|
||||
LOG_SOUND(("(GAE1) Playing or Queuing 1st chunk in channel: %02d, type: %02x, bank: %02x, end: %08x, Length: %04x\n", offset >> 3, (m_sndregs[offset - 2] >> 4) & 0x0f, m_sndregs[offset - 2] & 0x03, m_sndregs[offset - 1] << 8, data));
|
||||
|
||||
channel->loop = 1;
|
||||
|
||||
if (!channel->active)
|
||||
{
|
||||
if (!channel->active)
|
||||
{
|
||||
channel->active = 1;
|
||||
channel->chunkNum = 0;
|
||||
channel->loop = 0;
|
||||
LOG_SOUND(("(GAE1) Playing sample channel: %02d, type: %02x, bank: %02x, end: %08x, Length: %04x\n", offset >> 3, (m_sndregs[offset - 2] >> 4) & 0x0f, m_sndregs[offset - 2] & 0x03, m_sndregs[offset - 1] << 8, data));
|
||||
}
|
||||
channel->chunkNum = 0;
|
||||
}
|
||||
else
|
||||
channel->active = 0;
|
||||
|
||||
break;
|
||||
channel->active = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
//channel->loop = 0;
|
||||
channel->active = 0;
|
||||
}
|
||||
|
||||
case 0x07: /* enable/disable looping */
|
||||
if ((m_sndregs[offset - 1] != 0) && (data != 0))
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
// if sample end position isn't 0, and length isn't 0
|
||||
if ((m_sndregs[offset - 1] != 0) && (data != 0))
|
||||
{
|
||||
LOG_SOUND(("(GAE1) Playing or Queuing 2nd chunk in channel: %02d, type: %02x, bank: %02x, end: %08x, Length: %04x\n", offset >> 3, (m_sndregs[offset - 2] >> 4) & 0x0f, m_sndregs[offset - 2] & 0x03, m_sndregs[offset - 1] << 8, data));
|
||||
|
||||
channel->loop = 1;
|
||||
|
||||
if (!channel->active)
|
||||
{
|
||||
LOG_SOUND(("(GAE1) Looping in channel: %02d, type: %02x, bank: %02x, end: %08x, Length: %04x\n", offset >> 3, (m_sndregs[offset - 2] >> 4) & 0x0f, m_sndregs[offset - 2] & 0x03, m_sndregs[offset - 1] << 8, data));
|
||||
channel->loop = 1;
|
||||
channel->chunkNum = 1;
|
||||
}
|
||||
else
|
||||
channel->loop = 0;
|
||||
|
||||
break;
|
||||
channel->active = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
channel->loop = 0;
|
||||
// channel->active = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,19 @@ Year Game PCB NOTES
|
||||
1995 Biomechanical Toy REF 922804/2 Unprotected
|
||||
1996 Maniac Square REF 922804/2 Prototype
|
||||
|
||||
TODO: Figure out why Thunder Hoop crashes if you die on Level 4
|
||||
This can be bypassed by killing yourself at the same time as
|
||||
the Level 3 boss dies, suggesting the end stage animation is
|
||||
somehow corrupting the game state. Could this be a bug in
|
||||
the supported revision of the game? It doesn't depend on
|
||||
CPU clock, vblank timing, there are no unmapped reads or
|
||||
writes of significance. Could it be related to a dipswitch
|
||||
setting?
|
||||
|
||||
Priorities for all games - the games don't make extensive
|
||||
enough use of the priority scheme to properly draw any
|
||||
conclusions.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
@ -64,6 +77,12 @@ void gaelco_state::oki_bankswitch_w(uint8_t data)
|
||||
m_okibank->set_entry(data & 0x0f);
|
||||
}
|
||||
|
||||
void gaelco_state::irqack_w(uint16_t data)
|
||||
{
|
||||
// INT 6 ACK or Watchdog timer - written at the end of an IRQ
|
||||
m_maincpu->set_input_line(6, CLEAR_LINE);
|
||||
}
|
||||
|
||||
/*********** Squash Encryption Related Code ******************/
|
||||
|
||||
void gaelco_state::vram_encrypted_w(offs_t offset, uint16_t data, uint16_t mem_mask)
|
||||
@ -109,7 +128,7 @@ void gaelco_state::bigkarnk_map(address_map &map)
|
||||
map(0x100000, 0x101fff).ram().w(FUNC(gaelco_state::vram_w)).share("videoram"); // Video RAM
|
||||
map(0x102000, 0x103fff).ram(); // Screen RAM
|
||||
map(0x108000, 0x108007).writeonly().share("vregs"); // Video Registers
|
||||
// map(0x10800c, 0x10800d).w("watchdog", FUNC(watchdog_timer_device::reset16_w)); // INT 6 ACK/Watchdog timer
|
||||
map(0x10800c, 0x10800d).w(FUNC(gaelco_state::irqack_w)); // INT 6 ACK/Watchdog timer
|
||||
map(0x200000, 0x2007ff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette"); // Palette
|
||||
map(0x440000, 0x440fff).ram().share("spriteram"); // Sprite RAM
|
||||
map(0x700000, 0x700001).portr("DSW1");
|
||||
@ -138,7 +157,7 @@ void gaelco_state::maniacsq_map(address_map &map)
|
||||
map(0x100000, 0x101fff).ram().w(FUNC(gaelco_state::vram_w)).share("videoram"); // Video RAM
|
||||
map(0x102000, 0x103fff).ram(); // Screen RAM
|
||||
map(0x108000, 0x108007).writeonly().share("vregs"); // Video Registers
|
||||
// map(0x10800c, 0x10800d).w("watchdog", FUNC(watchdog_timer_device::reset16_w)); // INT 6 ACK/Watchdog timer
|
||||
map(0x10800c, 0x10800d).w(FUNC(gaelco_state::irqack_w)); // INT 6 ACK/Watchdog timer
|
||||
map(0x200000, 0x2007ff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette"); // Palette
|
||||
map(0x440000, 0x440fff).ram().share("spriteram"); // Sprite RAM
|
||||
map(0x700000, 0x700001).portr("DSW2");
|
||||
@ -156,7 +175,7 @@ void gaelco_state::squash_map(address_map &map)
|
||||
map(0x100000, 0x101fff).ram().w(FUNC(gaelco_state::vram_encrypted_w)).share("videoram"); // Video RAM
|
||||
map(0x102000, 0x103fff).ram().w(FUNC(gaelco_state::encrypted_w)).share("screenram"); // Screen RAM
|
||||
map(0x108000, 0x108007).writeonly().share("vregs"); // Video Registers
|
||||
// map(0x10800c, 0x10800d).w("watchdog", FUNC(watchdog_timer_device::reset16_w)); // INT 6 ACK/Watchdog timer
|
||||
map(0x10800c, 0x10800d).w(FUNC(gaelco_state::irqack_w)); // INT 6 ACK/Watchdog timer
|
||||
map(0x200000, 0x2007ff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette"); // Palette
|
||||
map(0x440000, 0x440fff).ram().share("spriteram"); // Sprite RAM
|
||||
map(0x700000, 0x700001).portr("DSW2");
|
||||
@ -175,7 +194,7 @@ void gaelco_state::thoop_map(address_map &map)
|
||||
map(0x100000, 0x101fff).ram().w(FUNC(gaelco_state::thoop_vram_encrypted_w)).share("videoram"); // Video RAM
|
||||
map(0x102000, 0x103fff).ram().w(FUNC(gaelco_state::thoop_encrypted_w)).share("screenram"); // Screen RAM
|
||||
map(0x108000, 0x108007).writeonly().share("vregs"); // Video Registers
|
||||
// map(0x10800c, 0x10800d).w("watchdog", FUNC(watchdog_timer_device::reset16_w)); // INT 6 ACK/Watchdog timer
|
||||
map(0x10800c, 0x10800d).w(FUNC(gaelco_state::irqack_w)); // INT 6 ACK/Watchdog timer
|
||||
map(0x200000, 0x2007ff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette"); // Palette
|
||||
map(0x440000, 0x440fff).ram().share("spriteram"); // Sprite RAM
|
||||
map(0x700000, 0x700001).portr("DSW2");
|
||||
@ -641,7 +660,7 @@ void gaelco_state::bigkarnk(machine_config &config)
|
||||
// Basic machine hardware
|
||||
M68000(config, m_maincpu, XTAL(24'000'000)/2); // MC68000P10, 12 MHz?
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &gaelco_state::bigkarnk_map);
|
||||
m_maincpu->set_vblank_int("screen", FUNC(gaelco_state::irq6_line_hold));
|
||||
m_maincpu->set_vblank_int("screen", FUNC(gaelco_state::irq6_line_assert));
|
||||
|
||||
MC6809E(config, m_audiocpu, XTAL(8'000'000)/4); // 68B09EP, 2 MHz?
|
||||
m_audiocpu->set_addrmap(AS_PROGRAM, &gaelco_state::bigkarnk_snd_map);
|
||||
@ -684,7 +703,7 @@ void gaelco_state::maniacsq(machine_config &config)
|
||||
// Basic machine hardware
|
||||
M68000(config, m_maincpu, XTAL(24'000'000)/2); /* verified on pcb */
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &gaelco_state::maniacsq_map);
|
||||
m_maincpu->set_vblank_int("screen", FUNC(gaelco_state::irq6_line_hold));
|
||||
m_maincpu->set_vblank_int("screen", FUNC(gaelco_state::irq6_line_assert));
|
||||
|
||||
// Video hardware
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
|
||||
@ -713,7 +732,7 @@ void gaelco_state::squash(machine_config &config)
|
||||
// Basic machine hardware
|
||||
M68000(config, m_maincpu, XTAL(20'000'000)/2); // Verified on PCB
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &gaelco_state::squash_map);
|
||||
m_maincpu->set_vblank_int("screen", FUNC(gaelco_state::irq6_line_hold));
|
||||
m_maincpu->set_vblank_int("screen", FUNC(gaelco_state::irq6_line_assert));
|
||||
|
||||
config.set_maximum_quantum(attotime::from_hz(600));
|
||||
|
||||
@ -730,13 +749,13 @@ void gaelco_state::squash(machine_config &config)
|
||||
screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500) /* not accurate */);
|
||||
screen.set_size(32*16, 32*16);
|
||||
screen.set_visarea(0, 320-1, 16, 256-1);
|
||||
screen.set_screen_update(FUNC(gaelco_state::screen_update_maniacsq));
|
||||
screen.set_screen_update(FUNC(gaelco_state::screen_update_thoop));
|
||||
screen.set_palette(m_palette);
|
||||
|
||||
GFXDECODE(config, m_gfxdecode, m_palette, gfx_gaelco);
|
||||
PALETTE(config, m_palette).set_format(palette_device::xBGR_555, 1024);
|
||||
|
||||
MCFG_VIDEO_START_OVERRIDE(gaelco_state,maniacsq)
|
||||
MCFG_VIDEO_START_OVERRIDE(gaelco_state,squash)
|
||||
|
||||
// Sound hardware
|
||||
SPEAKER(config, "mono").front_center();
|
||||
@ -751,7 +770,7 @@ void gaelco_state::thoop(machine_config &config)
|
||||
// Basic machine hardware
|
||||
M68000(config, m_maincpu, XTAL(24'000'000)/2); // Verified on PCB
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &gaelco_state::thoop_map);
|
||||
m_maincpu->set_vblank_int("screen", FUNC(gaelco_state::irq6_line_hold));
|
||||
m_maincpu->set_vblank_int("screen", FUNC(gaelco_state::irq6_line_assert));
|
||||
|
||||
config.set_maximum_quantum(attotime::from_hz(600));
|
||||
|
||||
@ -768,13 +787,13 @@ void gaelco_state::thoop(machine_config &config)
|
||||
screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500) /* not accurate */);
|
||||
screen.set_size(32*16, 32*16);
|
||||
screen.set_visarea(0, 320-1, 16, 256-1);
|
||||
screen.set_screen_update(FUNC(gaelco_state::screen_update_maniacsq));
|
||||
screen.set_screen_update(FUNC(gaelco_state::screen_update_thoop));
|
||||
screen.set_palette(m_palette);
|
||||
|
||||
GFXDECODE(config, m_gfxdecode, m_palette, gfx_gaelco);
|
||||
PALETTE(config, m_palette).set_format(palette_device::xBGR_555, 1024);
|
||||
|
||||
MCFG_VIDEO_START_OVERRIDE(gaelco_state,maniacsq)
|
||||
MCFG_VIDEO_START_OVERRIDE(gaelco_state,bigkarnk)
|
||||
|
||||
// Sound hardware
|
||||
SPEAKER(config, "mono").front_center();
|
||||
@ -1164,7 +1183,7 @@ GAME( 1995, biomtoya, biomtoy, maniacsq, biomtoy, gaelco_state, empty_init, RO
|
||||
GAME( 1995, biomtoyb, biomtoy, maniacsq, biomtoy, gaelco_state, empty_init, ROT0, "Gaelco", "Biomechanical Toy (Ver. 1.0.1878)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1994, biomtoyc, biomtoy, maniacsq, biomtoyc, gaelco_state, empty_init, ROT0, "Gaelco", "Biomechanical Toy (Ver. 1.0.1870)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1994, bioplayc, biomtoy, maniacsq, bioplayc, gaelco_state, empty_init, ROT0, "Gaelco", "Bioplaything Cop (Ver. 1.0.1823, prototype)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND ) // copyright based on Ver. 1.0.1870
|
||||
GAME( 1996, maniacsp, maniacsq, maniacsq, maniacsq, gaelco_state, empty_init, ROT0, "Gaelco", "Maniac Square (prototype)", MACHINE_SUPPORTS_SAVE ) // sometimes listed as a 1992 proto?
|
||||
GAME( 1992, maniacsp, 0, maniacsq, maniacsq, gaelco_state, empty_init, ROT0, "Gaelco", "Maniac Square (prototype)", MACHINE_SUPPORTS_SAVE ) // The prototype version was an earlier project, said to be from 1992, game was rewritten in 1996
|
||||
GAME( 1995, lastkm, 0, maniacsq, lastkm, gaelco_state, empty_init, ROT0, "Gaelco", "Last KM (Ver 1.0.0275)", MACHINE_SUPPORTS_SAVE ) // used on 'Salter' exercise bikes
|
||||
GAME( 1992, squash, 0, squash, squash, gaelco_state, empty_init, ROT0, "Gaelco", "Squash (Ver. 1.0)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1992, thoop, 0, thoop, thoop, gaelco_state, empty_init, ROT0, "Gaelco", "Thunder Hoop (Ver. 1, Checksum 02A09F7D)", MACHINE_SUPPORTS_SAVE ) // could be other versions, still Ver. 1 but different checksum listed on boot
|
||||
GAME( 1992, thoop, 0, thoop, thoop, gaelco_state, empty_init, ROT0, "Gaelco", "Thunder Hoop (Ver. 1, Checksum 02A09F7D)", MACHINE_SUPPORTS_SAVE | MACHINE_NOT_WORKING ) // could be other versions, still Ver. 1 but different checksum listed on boot
|
||||
|
@ -1,5 +1,5 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Manuel Abadia
|
||||
// copyright-holders:Manuel Abadia, David Haywood
|
||||
/***************************************************************************
|
||||
|
||||
Gaelco CG-1V/GAE1 based games
|
||||
@ -194,7 +194,7 @@ void gaelco2_state::maniacsq(machine_config &config)
|
||||
screen.set_palette(m_palette);
|
||||
|
||||
GFXDECODE(config, m_gfxdecode, m_palette, gfx_gaelco2);
|
||||
PALETTE(config, m_palette).set_entries(4096*16 - 16); /* game's palette is 4096 but we allocate 15 more for shadows & highlights */
|
||||
PALETTE(config, m_palette).set_entries(0x10000);
|
||||
|
||||
MCFG_VIDEO_START_OVERRIDE(gaelco2_state,gaelco2)
|
||||
|
||||
@ -478,7 +478,7 @@ void gaelco2_state::saltcrdi(machine_config &config)
|
||||
screen.set_palette(m_palette);
|
||||
|
||||
GFXDECODE(config, m_gfxdecode, m_palette, gfx_gaelco2);
|
||||
PALETTE(config, m_palette).set_entries(4096*16 - 16); /* game's palette is 4096 but we allocate 15 more for shadows & highlights */
|
||||
PALETTE(config, m_palette).set_entries(0x10000);
|
||||
|
||||
MCFG_VIDEO_START_OVERRIDE(gaelco2_state,gaelco2)
|
||||
|
||||
@ -1010,7 +1010,7 @@ void gaelco2_state::play2000(machine_config &config)
|
||||
screen.set_palette(m_palette);
|
||||
|
||||
GFXDECODE(config, m_gfxdecode, m_palette, gfx_gaelco2);
|
||||
PALETTE(config, m_palette).set_entries(4096*16 - 16); /* game's palette is 4096 but we allocate 15 more for shadows & highlights */
|
||||
PALETTE(config, m_palette).set_entries(0x10000);
|
||||
|
||||
MCFG_VIDEO_START_OVERRIDE(gaelco2_state,gaelco2)
|
||||
|
||||
@ -1049,7 +1049,7 @@ void gaelco2_state::srollnd(machine_config& config)
|
||||
screen.set_palette(m_palette);
|
||||
|
||||
GFXDECODE(config, m_gfxdecode, m_palette, gfx_gaelco2);
|
||||
PALETTE(config, m_palette).set_entries(4096*16 - 16); /* game's palette is 4096 but we allocate 15 more for shadows & highlights */
|
||||
PALETTE(config, m_palette).set_entries(0x10000);
|
||||
|
||||
MCFG_VIDEO_START_OVERRIDE(gaelco2_state,gaelco2)
|
||||
|
||||
@ -1154,7 +1154,7 @@ void bang_state::bang(machine_config &config)
|
||||
screen.set_palette(m_palette);
|
||||
|
||||
GFXDECODE(config, m_gfxdecode, m_palette, gfx_gaelco2);
|
||||
PALETTE(config, m_palette).set_entries(4096*16 - 16); /* game's palette is 4096 but we allocate 15 more for shadows & highlights */
|
||||
PALETTE(config, m_palette).set_entries(0x10000);
|
||||
|
||||
MCFG_VIDEO_START_OVERRIDE(gaelco2_state,gaelco2)
|
||||
|
||||
@ -1399,7 +1399,7 @@ void gaelco2_state::alighunt(machine_config &config)
|
||||
screen.set_palette(m_palette);
|
||||
|
||||
GFXDECODE(config, m_gfxdecode, m_palette, gfx_gaelco2);
|
||||
PALETTE(config, m_palette).set_entries(4096*16 - 16); /* game's palette is 4096 but we allocate 15 more for shadows & highlights */
|
||||
PALETTE(config, m_palette).set_entries(0x10000);
|
||||
|
||||
MCFG_VIDEO_START_OVERRIDE(gaelco2_state,gaelco2)
|
||||
|
||||
@ -1750,7 +1750,7 @@ void gaelco2_state::touchgo(machine_config &config)
|
||||
/* video hardware */
|
||||
BUFFERED_SPRITERAM16(config, m_spriteram);
|
||||
GFXDECODE(config, m_gfxdecode, m_palette, gfx_gaelco2);
|
||||
PALETTE(config, m_palette).set_entries(4096*16 - 16); /* game's palette is 4096 but we allocate 15 more for shadows & highlights */
|
||||
PALETTE(config, m_palette).set_entries(0x10000);
|
||||
config.set_default_layout(layout_dualhsxs);
|
||||
|
||||
screen_device &lscreen(SCREEN(config, "lscreen", SCREEN_TYPE_RASTER));
|
||||
@ -2069,7 +2069,7 @@ void gaelco2_state::snowboar(machine_config &config)
|
||||
screen.set_palette(m_palette);
|
||||
|
||||
GFXDECODE(config, m_gfxdecode, m_palette, gfx_gaelco2);
|
||||
PALETTE(config, m_palette).set_entries(4096*16 - 16); /* game's palette is 4096 but we allocate 15 more for shadows & highlights */
|
||||
PALETTE(config, m_palette).set_entries(0x10000);
|
||||
|
||||
MCFG_VIDEO_START_OVERRIDE(gaelco2_state,gaelco2)
|
||||
|
||||
@ -2113,7 +2113,7 @@ void gaelco2_state::maniacsqs(machine_config &config)
|
||||
screen.set_palette(m_palette);
|
||||
|
||||
GFXDECODE(config, m_gfxdecode, m_palette, gfx_gaelco2);
|
||||
PALETTE(config, m_palette).set_entries(4096*16 - 16); /* game's palette is 4096 but we allocate 15 more for shadows & highlights */
|
||||
PALETTE(config, m_palette).set_entries(0x10000);
|
||||
|
||||
MCFG_VIDEO_START_OVERRIDE(gaelco2_state,gaelco2)
|
||||
|
||||
@ -2394,7 +2394,7 @@ void wrally2_state::wrally2(machine_config &config)
|
||||
/* video hardware */
|
||||
BUFFERED_SPRITERAM16(config, m_spriteram);
|
||||
GFXDECODE(config, m_gfxdecode, m_palette, gfx_gaelco2);
|
||||
PALETTE(config, m_palette).set_entries(4096*16 - 16); /* game's palette is 4096 but we allocate 15 more for shadows & highlights */
|
||||
PALETTE(config, m_palette).set_entries(0x10000);
|
||||
config.set_default_layout(layout_dualhsxs);
|
||||
|
||||
screen_device &lscreen(SCREEN(config, "lscreen", SCREEN_TYPE_RASTER));
|
||||
|
@ -26,7 +26,9 @@ public:
|
||||
m_videoram(*this, "videoram"),
|
||||
m_vregs(*this, "vregs"),
|
||||
m_spriteram(*this, "spriteram"),
|
||||
m_screenram(*this, "screenram") { }
|
||||
m_screenram(*this, "screenram"),
|
||||
m_sprite_palette_force_high(0x38)
|
||||
{ }
|
||||
|
||||
void bigkarnk(machine_config &config);
|
||||
void thoop(machine_config &config);
|
||||
@ -62,15 +64,18 @@ private:
|
||||
void thoop_vram_encrypted_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
|
||||
void thoop_encrypted_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
|
||||
void vram_w(offs_t offset, u16 data, u16 mem_mask);
|
||||
void irqack_w(uint16_t data);
|
||||
|
||||
template<int Layer> TILE_GET_INFO_MEMBER(get_tile_info);
|
||||
|
||||
virtual void machine_start() override;
|
||||
DECLARE_VIDEO_START(bigkarnk);
|
||||
DECLARE_VIDEO_START(maniacsq);
|
||||
DECLARE_VIDEO_START(squash);
|
||||
|
||||
uint32_t screen_update_bigkarnk(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
uint32_t screen_update_maniacsq(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
uint32_t screen_update_thoop(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect );
|
||||
|
||||
void bigkarnk_map(address_map &map);
|
||||
@ -79,4 +84,7 @@ private:
|
||||
void oki_map(address_map &map);
|
||||
void squash_map(address_map &map);
|
||||
void thoop_map(address_map &map);
|
||||
|
||||
/* per-game configuration */
|
||||
uint8_t m_sprite_palette_force_high;
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Manuel Abadia
|
||||
// copyright-holders:Manuel Abadia, David Haywood
|
||||
#include "cpu/m68000/m68000.h"
|
||||
#include "video/bufsprite.h"
|
||||
#include "machine/74259.h"
|
||||
@ -81,6 +81,7 @@ private:
|
||||
void snowboar_protection_w(offs_t offset, u16 data, u16 mem_mask = ~0);
|
||||
template<unsigned Layer> TILE_GET_INFO_MEMBER(get_tile_info);
|
||||
template<unsigned Layer> TILE_GET_INFO_MEMBER(get_tile_info_dual);
|
||||
int get_rowscrollmode_yscroll(bool first_screen);
|
||||
void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int mask);
|
||||
u32 dual_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int index);
|
||||
void ROM16_split_gfx(const char *src_reg, const char *dst_reg, int start, int length, int dest1, int dest2);
|
||||
|
@ -6,6 +6,11 @@
|
||||
|
||||
Functions to emulate the video hardware of the machine
|
||||
|
||||
TODO:
|
||||
verify priority implementations
|
||||
understand bad sprites in Squash after the continue screen, these do not
|
||||
occur on real hardware.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
@ -75,11 +80,23 @@ VIDEO_START_MEMBER(gaelco_state,bigkarnk)
|
||||
m_tilemap[1]->set_transmask(0, 0xff01, 0x00ff); // pens 1-7 opaque, pens 0, 8-15 transparent
|
||||
}
|
||||
|
||||
VIDEO_START_MEMBER(gaelco_state,squash)
|
||||
{
|
||||
m_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(gaelco_state::get_tile_info<0>)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
|
||||
m_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(gaelco_state::get_tile_info<1>)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
|
||||
|
||||
m_tilemap[0]->set_transmask(0, 0xff01, 0x00ff); // pens 1-7 opaque, pens 0, 8-15 transparent
|
||||
m_tilemap[1]->set_transmask(0, 0xff01, 0x00ff); // pens 1-7 opaque, pens 0, 8-15 transparent
|
||||
|
||||
m_sprite_palette_force_high = 0x3c;
|
||||
}
|
||||
|
||||
VIDEO_START_MEMBER(gaelco_state,maniacsq)
|
||||
{
|
||||
m_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(gaelco_state::get_tile_info<0>)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
|
||||
m_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(gaelco_state::get_tile_info<1>)), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
|
||||
|
||||
// it is possible Maniac Square hardware also has more complex priority handling, but does not use it
|
||||
m_tilemap[0]->set_transparent_pen(0);
|
||||
m_tilemap[1]->set_transparent_pen(0);
|
||||
}
|
||||
@ -131,13 +148,18 @@ void gaelco_state::draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, co
|
||||
int yflip = attr & 0x40;
|
||||
int spr_size, pri_mask;
|
||||
|
||||
/* palettes 0x38-0x3f are used for high priority sprites in Big Karnak */
|
||||
if (color >= 0x38)
|
||||
/* palettes 0x38-0x3f are used for high priority sprites in Big Karnak
|
||||
the same logic in Squash causes player sprites to be drawn over the
|
||||
pixels that form the glass play area.
|
||||
|
||||
Is this accurate, or just exposing a different flaw in the priority
|
||||
handling? */
|
||||
if (color >= m_sprite_palette_force_high)
|
||||
priority = 4;
|
||||
|
||||
switch (priority)
|
||||
{
|
||||
case 0: pri_mask = 0xff00; break;
|
||||
case 0: pri_mask = 0xff00; break; // above everything?
|
||||
case 1: pri_mask = 0xff00 | 0xf0f0; break;
|
||||
case 2: pri_mask = 0xff00 | 0xf0f0 | 0xcccc; break;
|
||||
case 3: pri_mask = 0xff00 | 0xf0f0 | 0xcccc | 0xaaaa; break;
|
||||
@ -202,6 +224,50 @@ uint32_t gaelco_state::screen_update_maniacsq(screen_device &screen, bitmap_ind1
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t gaelco_state::screen_update_thoop(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
/* set scroll registers */
|
||||
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]);
|
||||
|
||||
screen.priority().fill(0, cliprect);
|
||||
bitmap.fill(0, cliprect);
|
||||
|
||||
// the priority handling differs from Big Karnak (or the Big Karnak implementation isn't correct)
|
||||
// the games only make minimal use of the priority features.
|
||||
|
||||
m_tilemap[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 3, 0);
|
||||
m_tilemap[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 3, 0);
|
||||
|
||||
m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 3, 0);
|
||||
m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 3, 0);
|
||||
|
||||
m_tilemap[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 2, 1);
|
||||
m_tilemap[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 2, 1);
|
||||
|
||||
m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 2, 1);
|
||||
m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 2, 1);
|
||||
|
||||
m_tilemap[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 1, 2);
|
||||
m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 1, 2);
|
||||
|
||||
// sprites are sandwiched in here
|
||||
|
||||
m_tilemap[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 1, 4);
|
||||
m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 1, 4);
|
||||
|
||||
m_tilemap[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 0, 8);
|
||||
m_tilemap[1]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 0, 8);
|
||||
|
||||
m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER1 | 0, 8);
|
||||
m_tilemap[0]->draw(screen, bitmap, cliprect, TILEMAP_DRAW_LAYER0 | 0, 8);
|
||||
|
||||
draw_sprites(screen, bitmap, cliprect);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t gaelco_state::screen_update_bigkarnk(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
/* set scroll registers */
|
||||
|
@ -1,5 +1,5 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Manuel Abadia
|
||||
// copyright-holders:Manuel Abadia, David Haywood
|
||||
/***************************************************************************
|
||||
|
||||
Gaelco Type CG-1V/GAE1 Video Hardware
|
||||
@ -235,10 +235,6 @@ void gaelco2_state::palette_w(offs_t offset, u16 data, u16 mem_mask)
|
||||
/* update shadow/highlight palettes */
|
||||
for (int i = 1; i < 16; i++)
|
||||
{
|
||||
/* because the last palette entry is reserved for shadows and highlights, we
|
||||
don't use it and that way we save some colors so the UI looks fine ;-) */
|
||||
if ((offset >= 0xff0) && (offset <= 0xfff)) return;
|
||||
|
||||
const u8 auxr = ADJUST_COLOR(r + pen_color_adjust[i]);
|
||||
const u8 auxg = ADJUST_COLOR(g + pen_color_adjust[i]);
|
||||
const u8 auxb = ADJUST_COLOR(b + pen_color_adjust[i]);
|
||||
@ -393,18 +389,17 @@ void gaelco2_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, co
|
||||
{
|
||||
/* get a pointer to the current line in the screen bitmap */
|
||||
const int ypos = ((sy + ey * 16 + py) & 0x1ff);
|
||||
u16 *const srcy = &bitmap.pix(ypos);
|
||||
|
||||
const int gfx_py = yflip ? (gfx->height() - 1 - py) : py;
|
||||
|
||||
if ((ypos < cliprect.min_y) || (ypos > cliprect.max_y)) continue;
|
||||
|
||||
const int gfx_py = yflip ? (gfx->height() - 1 - py) : py;
|
||||
u16 *const srcy = &bitmap.pix(ypos);
|
||||
|
||||
for (int px = 0; px < gfx->width(); px++)
|
||||
{
|
||||
/* get current pixel */
|
||||
const int xpos = (((sx + ex * 16 + px) & 0x3ff) + spr_x_adjust) & 0x3ff;
|
||||
u16 *const pixel = srcy + xpos;
|
||||
const u16 src_color = *pixel;
|
||||
if ((xpos < cliprect.min_x) || (xpos > cliprect.max_x)) continue;
|
||||
|
||||
const int gfx_px = xflip ? (gfx->width() - 1 - px) : px;
|
||||
|
||||
@ -413,10 +408,11 @@ void gaelco2_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, co
|
||||
|
||||
if ((gfx_pen == 0) || (gfx_pen >= 16)) continue;
|
||||
|
||||
if ((xpos < cliprect.min_x) || (xpos > cliprect.max_x)) continue;
|
||||
u16 *const pixel = srcy + xpos;
|
||||
const u16 src_color = *pixel;
|
||||
|
||||
/* make background color darker or brighter */
|
||||
*pixel = src_color + 4096*gfx_pen;
|
||||
*pixel = (src_color & 0xfff) | 0x1000*gfx_pen;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -449,6 +445,7 @@ u32 gaelco2_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, co
|
||||
m_pant[0]->set_scrolly(0, scroll0y & 0x1ff);
|
||||
m_pant[1]->set_scrolly(0, scroll1y & 0x1ff);
|
||||
|
||||
|
||||
/* set x linescroll registers */
|
||||
for (int i = 0; i < 512; i++)
|
||||
{
|
||||
@ -465,6 +462,132 @@ u32 gaelco2_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, co
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
The Y-scroll value in rowscroll mode has a very unusual implementation
|
||||
the scroll value seems come from a 0x1000 bit being set in one of the
|
||||
512 rowscroll table entries.
|
||||
|
||||
Only the bit representing the largest value is used?
|
||||
|
||||
The ordering of the bits does not appear to be immediatley obvious.
|
||||
|
||||
This is used in Touch & Go for the 'Super Spike' but we only scroll
|
||||
32 possible values, the entries used for the other scroll values
|
||||
are unknown unless a pattern can be derived, or figured out from
|
||||
the game code.
|
||||
|
||||
_______________________________________ entry number
|
||||
1111 1111 1111 1111
|
||||
0123 4567 89ab cdef 0123 4567 89ab cdef
|
||||
_______________________________________ offset into linescroll ram
|
||||
0000 0000 0000 1111 1111 1111 1111 1111
|
||||
6677 7888 8999 0001 1112 2233 3444 4555
|
||||
5814 7036 9258 1470 3692 5814 7036 9258
|
||||
_______________________________________
|
||||
scr = expected scroll value if bit 0x1000 at offset is set
|
||||
|
||||
scr (entry from above)
|
||||
--x- ---- ---- ---- ---- ---- ---- ---- 32 (02)
|
||||
---- ---- ---- --x- ---- ---- ---- ---- 31 (0e)
|
||||
---- ---- --x- ---- ---- ---- ---- ---- 30 (0a)
|
||||
---- ---- ---- ---- ---- ---- ---x ---- 29 (1b)
|
||||
---- ---- ---- ---- ---- -x-- ---- ---- 28 (15)
|
||||
---- ---- ---- ---- ---x ---- ---- ---- 27 (13)
|
||||
---- x--- ---- ---- ---- ---- ---- ---- 26 (04)
|
||||
---- ---- ---- ---- ---- ---- -x-- ---- 25 (19)
|
||||
---- ---- ---- x--- ---- ---- ---- ---- 24 (0c)
|
||||
---- ---- ---- ---- ---- ---- ---- ---x 23 (1f)
|
||||
---- ---- x--- ---- ---- ---- ---- ---- 22 (08)
|
||||
---- ---- ---- ---- ---- ---- ---- -x-- 21 (1d)
|
||||
---- ---- ---- ---- -x-- ---- ---- ---- 20 (11)
|
||||
---- --x- ---- ---- ---- ---- ---- ---- 19 (06)
|
||||
---- ---- ---- ---- ---- ---x ---- ---- 18 (17)
|
||||
---- ---- ---- ---- x--- ---- ---- ---- 17 (10)
|
||||
-x-- ---- ---- ---- ---- ---- ---- ---- 16 (01)
|
||||
---- ---- ---- -x-- ---- ---- ---- ---- 15 (0d)
|
||||
---- ---- ---- ---- ---- --x- ---- ---- 14 (16)
|
||||
---- ---- -x-- ---- ---- ---- ---- ---- 13 (09)
|
||||
---- ---- ---- ---- ---- ---- --x- ---- 12 (1a)
|
||||
---- -x-- ---- ---- ---- ---- ---- ---- 11 (05)
|
||||
---- ---- ---- ---- ---- ---- ---- --x- 10 (1e)
|
||||
x--- ---- ---- ---- ---- ---- ---- ---- 9 (00)
|
||||
---- ---- ---- ---- --x- ---- ---- ---- 8 (12)
|
||||
---- ---- ---x ---- ---- ---- ---- ---- 7 (0b)
|
||||
---- ---- ---- ---- ---- x--- ---- ---- 6 (14)
|
||||
---x ---- ---- ---- ---- ---- ---- ---- 5 (03)
|
||||
---- ---- ---- ---- ---- ---- ---- x--- 4 (1c)
|
||||
---- ---- ---- ---- ---- ---- x--- ---- 3 (18)
|
||||
---- ---x ---- ---- ---- ---- ---- ---- 2 (07)
|
||||
---- ---- ---- ---x ---- ---- ---- ---- 1 (0f)
|
||||
|
||||
================================================== sorted list for reference
|
||||
|
||||
x--- ---- ---- ---- ---- ---- ---- ---- 9
|
||||
-x-- ---- ---- ---- ---- ---- ---- ---- 16
|
||||
--x- ---- ---- ---- ---- ---- ---- ---- 32
|
||||
---x ---- ---- ---- ---- ---- ---- ---- 5
|
||||
|
||||
---- x--- ---- ---- ---- ---- ---- ---- 26
|
||||
---- -x-- ---- ---- ---- ---- ---- ---- 11
|
||||
---- --x- ---- ---- ---- ---- ---- ---- 19
|
||||
---- ---x ---- ---- ---- ---- ---- ---- 2
|
||||
|
||||
---- ---- x--- ---- ---- ---- ---- ---- 22
|
||||
---- ---- -x-- ---- ---- ---- ---- ---- 13
|
||||
---- ---- --x- ---- ---- ---- ---- ---- 30
|
||||
---- ---- ---x ---- ---- ---- ---- ---- 7
|
||||
|
||||
---- ---- ---- x--- ---- ---- ---- ---- 24
|
||||
---- ---- ---- -x-- ---- ---- ---- ---- 15
|
||||
---- ---- ---- --x- ---- ---- ---- ---- 31
|
||||
---- ---- ---- ---x ---- ---- ---- ---- 1
|
||||
|
||||
---- ---- ---- ---- x--- ---- ---- ---- 17
|
||||
---- ---- ---- ---- -x-- ---- ---- ---- 20
|
||||
---- ---- ---- ---- --x- ---- ---- ---- 8
|
||||
---- ---- ---- ---- ---x ---- ---- ---- 27
|
||||
|
||||
---- ---- ---- ---- ---- x--- ---- ---- 6
|
||||
---- ---- ---- ---- ---- -x-- ---- ---- 28
|
||||
---- ---- ---- ---- ---- --x- ---- ---- 14
|
||||
---- ---- ---- ---- ---- ---x ---- ---- 18
|
||||
|
||||
---- ---- ---- ---- ---- ---- x--- ---- 3
|
||||
---- ---- ---- ---- ---- ---- -x-- ---- 25
|
||||
---- ---- ---- ---- ---- ---- --x- ---- 12
|
||||
---- ---- ---- ---- ---- ---- ---x ---- 29
|
||||
|
||||
---- ---- ---- ---- ---- ---- ---- x--- 4
|
||||
---- ---- ---- ---- ---- ---- ---- -x-- 21
|
||||
---- ---- ---- ---- ---- ---- ---- --x- 10
|
||||
---- ---- ---- ---- ---- ---- ---- ---x 23
|
||||
|
||||
*/
|
||||
|
||||
int gaelco2_state::get_rowscrollmode_yscroll(bool first_screen)
|
||||
{
|
||||
uint16_t base = first_screen ? 0x2000 / 2 : 0x2400 / 2;
|
||||
|
||||
uint8_t checkoffsets[32] = {
|
||||
0x02, 0x0e, 0x0a, 0x1b, 0x15, 0x13, 0x04, 0x19,
|
||||
0x0c, 0x1f, 0x08, 0x1d, 0x11, 0x06, 0x17, 0x10,
|
||||
0x01, 0x0d, 0x16, 0x09, 0x1a, 0x05, 0x1e, 0x00,
|
||||
0x12, 0x0b, 0x14, 0x03, 0x1c, 0x18, 0x07, 0x0f };
|
||||
|
||||
int usescroll = 0;
|
||||
for (int i = 31; i >= 0; i--)
|
||||
{
|
||||
int checkoffset = (0x80 / 2) + ((checkoffsets[i] * 3) + 1);
|
||||
|
||||
if (m_videoram[(base)+checkoffset] & 0x1000)
|
||||
{
|
||||
usescroll = 31 - i;
|
||||
}
|
||||
}
|
||||
|
||||
return usescroll;
|
||||
}
|
||||
|
||||
u32 gaelco2_state::dual_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int index)
|
||||
{
|
||||
int xoff0 = 0x14; // intro scenes align better with 0x13, but test screen is definitely 0x14
|
||||
@ -478,17 +601,14 @@ u32 gaelco2_state::dual_update(screen_device &screen, bitmap_ind16 &bitmap, cons
|
||||
int scroll0y = m_videoram[0x2800 / 2] + yoff0;
|
||||
int scroll1y = m_videoram[0x2804 / 2] + yoff1;
|
||||
|
||||
// if linescroll is enabled y-scroll handling changes too?
|
||||
// touchgo uses 0x1f0 / 0x1ef between game and intro screens but actual scroll position needs to be different
|
||||
// this aligns the crowd with the advertising boards
|
||||
if (m_vregs[0] & 0x8000)
|
||||
{
|
||||
scroll0y += 32;
|
||||
scroll0y += get_rowscrollmode_yscroll(true);
|
||||
}
|
||||
|
||||
if (m_vregs[1] & 0x8000)
|
||||
{
|
||||
scroll1y += 32;
|
||||
scroll1y += get_rowscrollmode_yscroll(false);
|
||||
}
|
||||
|
||||
/* set y scroll registers */
|
||||
|
Loading…
Reference in New Issue
Block a user