mirror of
https://github.com/holub/mame
synced 2025-04-16 13:34:55 +03:00
Refactoring and bug fixes for bbusters and mechatt: (#7902)
* Moved sprite handling to a device. * Adjusted audio balance on mechatt (channel 0 was overpowering everything). * Adjusted priority handing on mechatt (planes now correctly rise from underground hanger on stage 3, train carts in later level). * Split driver in two, general refactoring etc. * Removed player 2 inputs from mechattu1 - it doesn't respond to them at all.
This commit is contained in:
parent
2526d94c1b
commit
196a342ae4
@ -3860,8 +3860,9 @@ files {
|
||||
createMAMEProjects(_target, _subtarget, "snk")
|
||||
files {
|
||||
MAME_DIR .. "src/mame/drivers/bbusters.cpp",
|
||||
MAME_DIR .. "src/mame/includes/bbusters.h",
|
||||
MAME_DIR .. "src/mame/video/bbusters.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/mechatt.cpp",
|
||||
MAME_DIR .. "src/mame/video/snk_bbusters_spr.cpp",
|
||||
MAME_DIR .. "src/mame/video/snk_bbusters_spr.h",
|
||||
MAME_DIR .. "src/mame/drivers/dmndrby.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/hng64.cpp",
|
||||
MAME_DIR .. "src/mame/includes/hng64.h",
|
||||
|
@ -751,6 +751,7 @@ mcr3.cpp
|
||||
mcr68.cpp
|
||||
meadows.cpp
|
||||
meadwttl.cpp
|
||||
mechatt.cpp
|
||||
mediagx.cpp
|
||||
megadriv_acbl.cpp
|
||||
megaphx.cpp
|
||||
|
File diff suppressed because it is too large
Load Diff
731
src/mame/drivers/mechatt.cpp
Normal file
731
src/mame/drivers/mechatt.cpp
Normal file
@ -0,0 +1,731 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Bryan McPhail
|
||||
/***************************************************************************
|
||||
|
||||
Mechanized Attack A8002 (c) 1989 SNK Corporation
|
||||
|
||||
Compared to Beast Busters (A9003), Mechanized Attack (A8002) is an
|
||||
earlier design, it only has one sprite chip, no eeprom, and only 2
|
||||
machine guns, but the tilemaps are twice the size.
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
Stephh's notes (based on the games M68000 code and some tests) :
|
||||
|
||||
2) 'mechatt'
|
||||
|
||||
- Country/version is stored at 0x06a000.w and the possible values are :
|
||||
|
||||
Value Country
|
||||
0x0000 Japan
|
||||
0x1111 World (value stored in the current set)
|
||||
0x2222 US
|
||||
0x3333 Asia? (it looks like Japanese text but some "symbols" are missing)
|
||||
|
||||
2a) Japan version
|
||||
|
||||
- All texts are in Japanese.
|
||||
- "(c) 1989 (Corp) S-N-K".
|
||||
- "Coin Slots" Dip Switch has no effect.
|
||||
- "Coin A" and "Coin B" Dip Switches are the same as in the World version.
|
||||
- Coin buttons effect :
|
||||
|
||||
* "Coin Slots" are ALWAYS considered as "Common" :
|
||||
|
||||
. COIN1 : adds coin(s)/credit(s) depending on "Coin A" Dip Switch
|
||||
. COIN2 : adds coin(s)/credit(s) depending on "Coin B" Dip Switch
|
||||
. COIN3 : NO EFFECT !
|
||||
. COIN4 : NO EFFECT !
|
||||
. SERVICE1 : adds coin(s)/credit(s) depending on "Coin A" Dip Switch
|
||||
|
||||
2b) World version
|
||||
|
||||
- All texts are in English.
|
||||
- "(c) 1989 SNK Corporation".
|
||||
- Coin buttons effect :
|
||||
|
||||
* "Coin Slots" Dip Switch set to "Common" :
|
||||
|
||||
. COIN1 : adds coin(s)/credit(s) depending on "Coin A" Dip Switch
|
||||
. COIN2 : adds coin(s)/credit(s) depending on "Coin B" Dip Switch
|
||||
. COIN3 : NO EFFECT !
|
||||
. COIN4 : NO EFFECT !
|
||||
. SERVICE1 : adds coin(s)/credit(s) depending on "Coin A" Dip Switch
|
||||
|
||||
* "Coin Slots" Dip Switch set to "Individual" :
|
||||
|
||||
. COIN1 : adds coin(s)/credit(s) for player 1 depending on "Coin A" Dip Switch
|
||||
. COIN2 : adds coin(s)/credit(s) for player 1 depending on "Coin B" Dip Switch
|
||||
. COIN3 : adds coin(s)/credit(s) for player 2 depending on "Coin A" Dip Switch
|
||||
. COIN4 : adds coin(s)/credit(s) for player 2 depending on "Coin B" Dip Switch
|
||||
. SERVICE1 : adds coin(s)/credit(s) for all players depending on "Coin A" Dip Switch
|
||||
|
||||
2c) US version
|
||||
|
||||
- All texts are in English.
|
||||
- "(c) 1989 SNK Corp. of America".
|
||||
- Additional FBI logo as first screen as well as small FBI notice at the bottom left
|
||||
of the screens until a coin is inserted.
|
||||
- "Coin Slots" Dip Switch has no effect.
|
||||
- "Coin A" Dip Switch is different from the World version :
|
||||
|
||||
World US
|
||||
4C_1C "Free Play"
|
||||
3C_1C special (see below)
|
||||
2C_1C "2 Coins to Start, 1 to Continue"
|
||||
1C_1C 1C_1C
|
||||
|
||||
It's a bit hard to explain the "special" coinage, so here are some infos :
|
||||
|
||||
* when you insert a coin before starting a game, you are awarded 2 credits
|
||||
if credits == 0, else you are awarded 1 credit
|
||||
* when you insert a coin to continue, you are ALWAYS awarded 1 credit
|
||||
|
||||
- "Coin B" Dip Switch has no effect.
|
||||
|
||||
- Coin buttons effect :
|
||||
|
||||
* "Coin Slots" are ALWAYS considered as "Individual" :
|
||||
|
||||
. COIN1 : adds coin(s)/credit(s) for player 1 depending on "Coin A" Dip Switch
|
||||
. COIN2 : adds coin(s)/credit(s) for player 2 depending on "Coin A" Dip Switch
|
||||
. COIN3 : NO EFFECT !
|
||||
. COIN4 : NO EFFECT !
|
||||
. SERVICE1 : adds coin(s)/credit(s) for all players depending on "Coin A" Dip Switch
|
||||
|
||||
2d) Asia? version
|
||||
|
||||
- All texts are in Japanese ? (to be confirmed)
|
||||
- "(c) 1989 SNK Corporation".
|
||||
- "Coin Slots" Dip Switch has no effect.
|
||||
- "Coin A" and "Coin B" Dip Switches are the same as in the World version.
|
||||
- Coin buttons effect :
|
||||
|
||||
* "Coin Slots" are ALWAYS considered as "Common" :
|
||||
|
||||
. COIN1 : adds coin(s)/credit(s) depending on "Coin A" Dip Switch
|
||||
. COIN2 : adds coin(s)/credit(s) depending on "Coin B" Dip Switch
|
||||
. COIN3 : NO EFFECT !
|
||||
. COIN4 : NO EFFECT !
|
||||
. SERVICE1 : adds coin(s)/credit(s) depending on "Coin A" Dip Switch
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
HIGHWAYMAN's notes:
|
||||
|
||||
after adding the mechanized attack u.s. roms I suspect that there is more than just a few bytes changed ;-)
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
Mech Attack Region code works as follows
|
||||
|
||||
ROM[0x06a000/2] = (data << 12) | (data << 8) | (data << 4) | (data << 0);
|
||||
|
||||
Country :
|
||||
- 0x0000 : Japan
|
||||
- 0x1111 : World (default)
|
||||
- 0x2222 : US
|
||||
- 0x3333 : Asia?
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
// src/mame
|
||||
#include "video/snk_bbusters_spr.h"
|
||||
// src/devices
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "cpu/m68000/m68000.h"
|
||||
#include "machine/gen_latch.h"
|
||||
#include "sound/ym2608.h"
|
||||
#include "video/bufsprite.h"
|
||||
// src/emu
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
#include "tilemap.h"
|
||||
|
||||
class mechatt_state : public driver_device
|
||||
{
|
||||
public:
|
||||
mechatt_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_audiocpu(*this, "audiocpu"),
|
||||
m_screen(*this, "screen"),
|
||||
m_gfxdecode(*this, "gfxdecode"),
|
||||
m_sprites(*this, "sprites1"),
|
||||
m_spriteram(*this, "spriteram1"),
|
||||
m_soundlatch(*this, "soundlatch%u", 1U),
|
||||
m_tx_videoram(*this, "tx_videoram"),
|
||||
m_pf_data(*this, "pf%u_data", 1U),
|
||||
m_pf_scroll_data(*this, "pf%u_scroll_data", 1U),
|
||||
m_gun_io(*this, { "GUNX1", "GUNY1", "GUNX2", "GUNY2" }),
|
||||
m_gun_recoil(*this, "Player%u_Gun_Recoil", 1U)
|
||||
{ }
|
||||
|
||||
void mechatt(machine_config &config);
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
virtual void video_start() override;
|
||||
|
||||
private:
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<cpu_device> m_audiocpu;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_device<snk_bbusters_spr_device> m_sprites;
|
||||
required_device<buffered_spriteram16_device> m_spriteram;
|
||||
required_device_array<generic_latch_8_device, 2> m_soundlatch;
|
||||
required_shared_ptr<uint16_t> m_tx_videoram;
|
||||
required_shared_ptr_array<uint16_t, 2> m_pf_data;
|
||||
required_shared_ptr_array<uint16_t, 2> m_pf_scroll_data;
|
||||
required_ioport_array<4> m_gun_io;
|
||||
output_finder<2> m_gun_recoil;
|
||||
|
||||
tilemap_t *m_fix_tilemap;
|
||||
tilemap_t *m_pf_tilemap[2];
|
||||
|
||||
TILE_GET_INFO_MEMBER(get_tile_info);
|
||||
template<int Layer, int Gfx> TILE_GET_INFO_MEMBER(get_pf_tile_info);
|
||||
|
||||
void sound_cpu_w(uint8_t data);
|
||||
void video_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
|
||||
template<int Layer> void pf_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
|
||||
void coin_counter_w(uint8_t data);
|
||||
|
||||
void mechatt_map(address_map &map);
|
||||
void sound_map(address_map &map);
|
||||
void sounda_portmap(address_map &map);
|
||||
|
||||
void two_gun_output_w(uint16_t data);
|
||||
uint16_t mechatt_gun_r(offs_t offset);
|
||||
|
||||
template <typename Proc>
|
||||
void mix_sprites(bitmap_ind16 &bitmap, bitmap_ind16 &srcbitmap, const rectangle &cliprect, Proc MIX);
|
||||
|
||||
bitmap_ind16 m_bitmap_sprites;
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void mechatt_state::machine_start()
|
||||
{
|
||||
m_gun_recoil.resolve();
|
||||
}
|
||||
|
||||
void mechatt_state::sound_cpu_w(uint8_t data)
|
||||
{
|
||||
m_soundlatch[0]->write(data);
|
||||
m_audiocpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
|
||||
}
|
||||
|
||||
template<int Layer>
|
||||
void mechatt_state::pf_w(offs_t offset, uint16_t data, uint16_t mem_mask)
|
||||
{
|
||||
COMBINE_DATA(&m_pf_data[Layer][offset]);
|
||||
m_pf_tilemap[Layer]->mark_tile_dirty(offset);
|
||||
}
|
||||
|
||||
void mechatt_state::coin_counter_w(uint8_t data)
|
||||
{
|
||||
machine().bookkeeping().coin_counter_w(0, BIT(data, 0));
|
||||
machine().bookkeeping().coin_counter_w(1, BIT(data, 1));
|
||||
}
|
||||
|
||||
|
||||
TILE_GET_INFO_MEMBER(mechatt_state::get_tile_info)
|
||||
{
|
||||
uint16_t tile = m_tx_videoram[tile_index];
|
||||
tileinfo.set(0,tile&0xfff,tile>>12,0);
|
||||
}
|
||||
|
||||
template<int Layer, int Gfx>
|
||||
TILE_GET_INFO_MEMBER(mechatt_state::get_pf_tile_info)
|
||||
{
|
||||
uint16_t tile = m_pf_data[Layer][tile_index];
|
||||
tileinfo.set(Gfx,tile&0xfff,tile>>12,0);
|
||||
}
|
||||
|
||||
void mechatt_state::video_w(offs_t offset, uint16_t data, uint16_t mem_mask)
|
||||
{
|
||||
COMBINE_DATA(&m_tx_videoram[offset]);
|
||||
m_fix_tilemap->mark_tile_dirty(offset);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void mechatt_state::video_start()
|
||||
{
|
||||
m_fix_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(mechatt_state::get_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
|
||||
m_fix_tilemap->set_transparent_pen(15);
|
||||
|
||||
m_pf_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, NAME((&mechatt_state::get_pf_tile_info<0,1>))), TILEMAP_SCAN_COLS, 16, 16, 256, 32);
|
||||
m_pf_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, NAME((&mechatt_state::get_pf_tile_info<1,2>))), TILEMAP_SCAN_COLS, 16, 16, 256, 32);
|
||||
|
||||
m_pf_tilemap[0]->set_transparent_pen(15);
|
||||
|
||||
m_screen->register_screen_bitmap(m_bitmap_sprites);
|
||||
m_bitmap_sprites.fill(0xffff);
|
||||
}
|
||||
|
||||
template <typename Proc>
|
||||
void mechatt_state::mix_sprites(bitmap_ind16 &bitmap, bitmap_ind16 &srcbitmap, const rectangle &cliprect, Proc MIX)
|
||||
{
|
||||
for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
|
||||
{
|
||||
uint16_t* srcbuf = &srcbitmap.pix(y);
|
||||
uint16_t* dstbuf = &bitmap.pix(y);
|
||||
for (int x = cliprect.min_x; x <= cliprect.max_x; x++)
|
||||
{
|
||||
uint16_t srcdat = srcbuf[x];
|
||||
if ((srcdat & 0xf) != 0xf)
|
||||
MIX(srcdat, x, dstbuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t mechatt_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
m_bitmap_sprites.fill(0xffff);
|
||||
m_sprites->draw_sprites(m_bitmap_sprites, cliprect);
|
||||
|
||||
m_pf_tilemap[0]->set_scrollx(0, m_pf_scroll_data[0][0]);
|
||||
m_pf_tilemap[0]->set_scrolly(0, m_pf_scroll_data[0][1]);
|
||||
m_pf_tilemap[1]->set_scrollx(0, m_pf_scroll_data[1][0]);
|
||||
m_pf_tilemap[1]->set_scrolly(0, m_pf_scroll_data[1][1]);
|
||||
|
||||
m_pf_tilemap[1]->draw(screen, bitmap, cliprect, 0, 0);
|
||||
|
||||
// during level 3, plane sprites must rise from the underground, obscured by the fg tilemap
|
||||
mix_sprites(bitmap, m_bitmap_sprites, cliprect, [](uint16_t srcdat, uint16_t x, uint16_t* dstbuf) { if ((srcdat & 0xc0) == 0xc0) dstbuf[x] = srcdat + 256; } );
|
||||
m_pf_tilemap[0]->draw(screen, bitmap, cliprect, 0, 0);
|
||||
mix_sprites(bitmap, m_bitmap_sprites, cliprect, [](uint16_t srcdat, uint16_t x, uint16_t* dstbuf) { if ((srcdat & 0xc0) != 0xc0) dstbuf[x] = srcdat + 256; } );
|
||||
|
||||
m_fix_tilemap->draw(screen, bitmap, cliprect, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************/
|
||||
|
||||
void mechatt_state::two_gun_output_w(uint16_t data)
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
m_gun_recoil[i] = BIT(data, i);
|
||||
}
|
||||
|
||||
uint16_t mechatt_state::mechatt_gun_r(offs_t offset)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
x = m_gun_io[offset ? 2 : 0]->read();
|
||||
y = m_gun_io[offset ? 3 : 1]->read();
|
||||
|
||||
/* Todo - does the hardware really clamp like this? */
|
||||
x += 0x18;
|
||||
if (x > 0xff) x = 0xff;
|
||||
if (y > 0xef) y = 0xef;
|
||||
|
||||
return x | (y<<8);
|
||||
}
|
||||
|
||||
void mechatt_state::mechatt_map(address_map &map)
|
||||
{
|
||||
map(0x000000, 0x06ffff).rom();
|
||||
map(0x070000, 0x07ffff).ram().share("ram");
|
||||
map(0x090000, 0x090fff).ram().w(FUNC(mechatt_state::video_w)).share("tx_videoram");
|
||||
map(0x0a0000, 0x0a0fff).ram().share("spriteram1");
|
||||
map(0x0a1000, 0x0a7fff).nopw();
|
||||
map(0x0b0000, 0x0b3fff).ram().w(FUNC(mechatt_state::pf_w<0>)).share("pf1_data");
|
||||
map(0x0b8000, 0x0b8003).writeonly().share("pf1_scroll_data");
|
||||
map(0x0c0000, 0x0c3fff).ram().w(FUNC(mechatt_state::pf_w<1>)).share("pf2_data");
|
||||
map(0x0c8000, 0x0c8003).writeonly().share("pf2_scroll_data");
|
||||
map(0x0d0000, 0x0d07ff).ram().w("palette", FUNC(palette_device::write16)).share("palette");
|
||||
map(0x0e0000, 0x0e0001).portr("IN0");
|
||||
map(0x0e0002, 0x0e0003).portr("DSW1");
|
||||
map(0x0e0004, 0x0e0007).r(FUNC(mechatt_state::mechatt_gun_r));
|
||||
map(0x0e4000, 0x0e4001).w(FUNC(mechatt_state::coin_counter_w));
|
||||
map(0x0e4002, 0x0e4003).w(FUNC(mechatt_state::two_gun_output_w));
|
||||
map(0x0e8001, 0x0e8001).r(m_soundlatch[1], FUNC(generic_latch_8_device::read)).w(FUNC(mechatt_state::sound_cpu_w));
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void mechatt_state::sound_map(address_map &map)
|
||||
{
|
||||
map(0x0000, 0xefff).rom();
|
||||
map(0xf000, 0xf7ff).ram();
|
||||
map(0xf800, 0xf800).r(m_soundlatch[0], FUNC(generic_latch_8_device::read)).w(m_soundlatch[1], FUNC(generic_latch_8_device::write));
|
||||
}
|
||||
|
||||
void mechatt_state::sounda_portmap(address_map &map)
|
||||
{
|
||||
map.global_mask(0xff);
|
||||
map(0x00, 0x03).rw("ymsnd", FUNC(ym2608_device::read), FUNC(ym2608_device::write));
|
||||
map(0xc0, 0xc1).nopw(); /* -> Main CPU */
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static INPUT_PORTS_START( mechatt )
|
||||
PORT_START("IN0")
|
||||
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_COIN1 )
|
||||
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_COIN2 )
|
||||
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_SERVICE1 ) // See notes
|
||||
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_COIN3 )
|
||||
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_COIN4 )
|
||||
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_START1 )
|
||||
PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_NAME("P1 Fire") // "Fire"
|
||||
PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_NAME("P1 Grenade") // "Grenade"
|
||||
PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_START2 )
|
||||
PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_NAME("P2 Fire") // "Fire"
|
||||
PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_NAME("P2 Grenade") // "Grenade"
|
||||
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("DSW1")
|
||||
PORT_DIPNAME( 0x0001, 0x0001, "Coin Slots" ) PORT_DIPLOCATION("SW1:1") // Listed as "Unused" (manual from different revision/region?), See notes
|
||||
PORT_DIPSETTING( 0x0001, "Common" )
|
||||
PORT_DIPSETTING( 0x0000, "Individual" )
|
||||
PORT_DIPNAME( 0x0002, 0x0002, DEF_STR( Allow_Continue ) ) PORT_DIPLOCATION("SW1:2")
|
||||
PORT_DIPSETTING( 0x0000, DEF_STR( No ) )
|
||||
PORT_DIPSETTING( 0x0002, DEF_STR( Yes ) )
|
||||
PORT_DIPNAME( 0x000c, 0x000c, "Magazine / Grenade" ) PORT_DIPLOCATION("SW1:3,4")
|
||||
PORT_DIPSETTING( 0x0008, "5 / 2" )
|
||||
PORT_DIPSETTING( 0x000c, "6 / 3" )
|
||||
PORT_DIPSETTING( 0x0004, "7 / 4" )
|
||||
PORT_DIPSETTING( 0x0000, "8 / 5" )
|
||||
PORT_DIPNAME( 0x0030, 0x0030, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SW1:5,6") // See notes
|
||||
PORT_DIPSETTING( 0x0000, DEF_STR( 4C_1C ) )
|
||||
PORT_DIPSETTING( 0x0010, DEF_STR( 3C_1C ) )
|
||||
PORT_DIPSETTING( 0x0020, DEF_STR( 2C_1C ) )
|
||||
PORT_DIPSETTING( 0x0030, DEF_STR( 1C_1C ) )
|
||||
PORT_DIPNAME( 0x00c0, 0x00c0, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("SW1:7,8") // Listed as "Unused" (manual from different revision/region?), See notes
|
||||
PORT_DIPSETTING( 0x00c0, DEF_STR( 1C_1C ) )
|
||||
PORT_DIPSETTING( 0x0080, DEF_STR( 1C_2C ) )
|
||||
PORT_DIPSETTING( 0x0040, DEF_STR( 1C_3C ) )
|
||||
PORT_DIPSETTING( 0x0000, DEF_STR( 1C_4C ) )
|
||||
PORT_DIPNAME( 0x0300, 0x0300, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW2:1,2")
|
||||
PORT_DIPSETTING( 0x0200, DEF_STR( Easy ) )
|
||||
PORT_DIPSETTING( 0x0300, DEF_STR( Normal ) )
|
||||
PORT_DIPSETTING( 0x0100, DEF_STR( Hard ) )
|
||||
PORT_DIPSETTING( 0x0000, DEF_STR( Hardest ) )
|
||||
PORT_DIPNAME( 0x0c00, 0x0c00, "Game Mode" ) PORT_DIPLOCATION("SW2:3,4")
|
||||
PORT_DIPSETTING( 0x0800, "Demo Sounds Off" )
|
||||
PORT_DIPSETTING( 0x0c00, "Demo Sounds On" )
|
||||
PORT_DIPSETTING( 0x0400, "Infinite Energy (Cheat)")
|
||||
PORT_DIPSETTING( 0x0000, "Freeze" )
|
||||
PORT_DIPUNUSED_DIPLOC(0x1000, 0x1000, "SW2:5" ) /* Listed as "Unused" */
|
||||
PORT_DIPUNUSED_DIPLOC(0x2000, 0x2000, "SW2:6" ) /* Listed as "Unused" */
|
||||
PORT_DIPUNUSED_DIPLOC(0x4000, 0x4000, "SW2:7" ) /* Listed as "Unused" */
|
||||
PORT_SERVICE_DIPLOC( 0x8000, IP_ACTIVE_LOW, "SW2:8" )
|
||||
|
||||
PORT_START("GUNX1")
|
||||
PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X ) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_PLAYER(1)
|
||||
PORT_START("GUNY1")
|
||||
PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_Y ) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_PLAYER(1)
|
||||
|
||||
PORT_START("GUNX2")
|
||||
PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X ) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_PLAYER(2)
|
||||
PORT_START("GUNY2")
|
||||
PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_Y ) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_PLAYER(2)
|
||||
INPUT_PORTS_END
|
||||
|
||||
static INPUT_PORTS_START( mechattj )
|
||||
PORT_INCLUDE( mechatt )
|
||||
|
||||
PORT_MODIFY("DSW1")
|
||||
PORT_DIPUNUSED_DIPLOC( 0x0001, 0x0001, "SW1:1" )
|
||||
INPUT_PORTS_END
|
||||
|
||||
static INPUT_PORTS_START( mechattu )
|
||||
PORT_INCLUDE( mechatt )
|
||||
|
||||
PORT_MODIFY("DSW1")
|
||||
PORT_DIPUNUSED_DIPLOC( 0x0001, 0x0001, "SW1:1" )
|
||||
PORT_DIPNAME( 0x0030, 0x0030, DEF_STR( Coinage ) ) PORT_DIPLOCATION("SW1:5,6")
|
||||
PORT_DIPSETTING( 0x0000, DEF_STR( Free_Play ) )
|
||||
PORT_DIPSETTING( 0x0010, "1 Coin/2 Credits first, then 1 Coin/1 Credit" )
|
||||
PORT_DIPSETTING( 0x0020, "2 Coins/1 Credit first, then 1 Coin/1 Credit" )
|
||||
PORT_DIPSETTING( 0x0030, DEF_STR( 1C_1C ) )
|
||||
PORT_DIPUNUSED_DIPLOC( 0x00c0, 0x00c0, "SW1:7,8" )
|
||||
INPUT_PORTS_END
|
||||
|
||||
static INPUT_PORTS_START( mechattu1 )
|
||||
PORT_INCLUDE( mechattu )
|
||||
|
||||
PORT_MODIFY("IN0")
|
||||
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_MODIFY("GUNX2")
|
||||
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_MODIFY("GUNY2")
|
||||
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
INPUT_PORTS_END
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static const gfx_layout charlayout =
|
||||
{
|
||||
8,8,
|
||||
RGN_FRAC(1,1),
|
||||
4,
|
||||
{ STEP4(0,1) },
|
||||
{ STEP8(0,4) },
|
||||
{ STEP8(0,4*8) },
|
||||
32*8
|
||||
};
|
||||
|
||||
static const gfx_layout tilelayout =
|
||||
{
|
||||
16,16, /* 16*16 sprites */
|
||||
RGN_FRAC(1,1),
|
||||
4, /* 4 bits per pixel */
|
||||
{ STEP4(0,1) },
|
||||
{ STEP8(0,4), STEP8(4*8*16,4) },
|
||||
{ STEP16(0,4*8) },
|
||||
128*8
|
||||
};
|
||||
|
||||
static GFXDECODE_START( gfx_mechatt )
|
||||
GFXDECODE_ENTRY( "tx_tiles", 0, charlayout, 0, 16 )
|
||||
GFXDECODE_ENTRY( "gfx3", 0, tilelayout, 512, 16 )
|
||||
GFXDECODE_ENTRY( "gfx4", 0, tilelayout, 768, 16 )
|
||||
GFXDECODE_END
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void mechatt_state::mechatt(machine_config &config)
|
||||
{
|
||||
/* basic machine hardware */
|
||||
M68000(config, m_maincpu, 12000000);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &mechatt_state::mechatt_map);
|
||||
m_maincpu->set_vblank_int("screen", FUNC(mechatt_state::irq4_line_hold));
|
||||
|
||||
Z80(config, m_audiocpu, 4000000); /* Accurate */
|
||||
m_audiocpu->set_addrmap(AS_PROGRAM, &mechatt_state::sound_map);
|
||||
m_audiocpu->set_addrmap(AS_IO, &mechatt_state::sounda_portmap);
|
||||
|
||||
/* video hardware */
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
|
||||
screen.set_refresh_hz(60);
|
||||
screen.set_size(64*8, 32*8);
|
||||
screen.set_visarea(0*8, 32*8-1, 2*8, 30*8-1);
|
||||
screen.set_screen_update(FUNC(mechatt_state::screen_update));
|
||||
screen.screen_vblank().set(m_spriteram, FUNC(buffered_spriteram16_device::vblank_copy_rising));
|
||||
screen.set_palette("palette");
|
||||
|
||||
GFXDECODE(config, m_gfxdecode, "palette", gfx_mechatt);
|
||||
PALETTE(config, "palette").set_format(palette_device::RGBx_444, 1024);
|
||||
|
||||
BUFFERED_SPRITERAM16(config, m_spriteram);
|
||||
|
||||
SNK_BBUSTERS_SPR(config, m_sprites, 0);
|
||||
m_sprites->set_scaletable_tag("sprites1:scale_table");
|
||||
m_sprites->set_palette("palette");
|
||||
m_sprites->set_spriteram_tag("spriteram1");
|
||||
|
||||
/* sound hardware */
|
||||
SPEAKER(config, "lspeaker").front_left();
|
||||
SPEAKER(config, "rspeaker").front_right();
|
||||
|
||||
GENERIC_LATCH_8(config, m_soundlatch[0]);
|
||||
GENERIC_LATCH_8(config, m_soundlatch[1]);
|
||||
|
||||
ym2608_device &ymsnd(YM2608(config, "ymsnd", 8000000));
|
||||
ymsnd.irq_handler().set_inputline("audiocpu", 0);
|
||||
ymsnd.add_route(0, "lspeaker", 0.15);
|
||||
ymsnd.add_route(0, "rspeaker", 0.15);
|
||||
ymsnd.add_route(1, "lspeaker", 0.80);
|
||||
ymsnd.add_route(2, "rspeaker", 0.80);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
ROM_START( mechatt )
|
||||
ROM_REGION( 0x80000, "maincpu", 0 ) // Located on the A8002-1 main board
|
||||
ROM_LOAD16_BYTE( "ma5-e.n12", 0x000000, 0x20000, CRC(9bbb852a) SHA1(34b696bf79cf53cac1c384a3143c0f3f243a71f3) )
|
||||
ROM_LOAD16_BYTE( "ma4.l12", 0x000001, 0x20000, CRC(0d414918) SHA1(0d51b893d37ba124b983beebb691e65bdc52d300) )
|
||||
ROM_LOAD16_BYTE( "ma7.n13", 0x040000, 0x20000, CRC(61d85e1b) SHA1(46234d48ac21c481a5e70c6a654a341ebdd4cd3a) )
|
||||
ROM_LOAD16_BYTE( "ma6-f.l13", 0x040001, 0x20000, CRC(4055fe8d) SHA1(b4d8bd5f73805ce1c332eff657dddbb88ff45b37) )
|
||||
|
||||
ROM_REGION( 0x10000, "audiocpu", 0 ) // Located on the A8002-1 main board
|
||||
ROM_LOAD( "ma_3.e13", 0x000000, 0x10000, CRC(c06cc8e1) SHA1(65f5f1901120d633f7c3ba07432a188fd7fd7272) )
|
||||
|
||||
ROM_REGION( 0x020000, "tx_tiles", 0 ) // Located on the A8002-2 board
|
||||
ROM_LOAD( "ma_1.l2", 0x000000, 0x10000, CRC(24766917) SHA1(9082a8ae849605ce65b5a0493ae69cfe282f7e7b) )
|
||||
|
||||
ROM_REGION( 0x200000, "sprites1", 0 ) // Located on the A8002-2 board
|
||||
ROM_LOAD16_WORD_SWAP( "mao89p13.bin", 0x000000, 0x80000, CRC(8bcb16cf) SHA1(409ee1944188d9ce39adce29b1df029b560dd5b0) )
|
||||
ROM_LOAD16_WORD_SWAP( "ma189p15.bin", 0x080000, 0x80000, CRC(b84d9658) SHA1(448adecb0067d8f5b219ec2f94a8dec84187a554) )
|
||||
ROM_LOAD16_WORD_SWAP( "ma289p17.bin", 0x100000, 0x80000, CRC(6cbe08ac) SHA1(8f81f6e92b84ab6867452011d52f3e7689c62a1a) )
|
||||
ROM_LOAD16_WORD_SWAP( "ma389m15.bin", 0x180000, 0x80000, CRC(34d4585e) SHA1(38d9fd5d775e4b3c8b8b487a6ba9b8bdcb3274b0) )
|
||||
|
||||
ROM_REGION( 0x80000, "gfx3", 0 ) // Located on the A8002-2 board
|
||||
ROM_LOAD( "mab189a2.bin", 0x000000, 0x80000, CRC(e1c8b4d0) SHA1(2f8a1839cca892f8380c7cffe7a12e615d38fd55) )
|
||||
|
||||
ROM_REGION( 0x80000, "gfx4", 0 ) // Located on the A8002-2 board
|
||||
ROM_LOAD( "mab289c2.bin", 0x000000, 0x80000, CRC(14f97ceb) SHA1(a22033532ea616dc3a3db8b66ad6ccc6172ed7cc) )
|
||||
|
||||
ROM_REGION( 0x20000, "ymsnd", 0 ) // Located on the A8002-1 main board
|
||||
ROM_LOAD( "ma_2.d10", 0x000000, 0x20000, CRC(ea4cc30d) SHA1(d8f089fc0ce76309411706a8110ad907f93dc97e) )
|
||||
|
||||
ROM_REGION( 0x20000, "sprites1:scale_table", 0 ) // Zoom table - Located on the A8002-2 board
|
||||
ROM_LOAD( "ma_8.f10", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) )
|
||||
ROM_LOAD( "ma_9.f12", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) // identical to ma_8.f10
|
||||
ROM_END
|
||||
|
||||
ROM_START( mechattj ) // Uses EPROMs on official SNK A8002-5 & A8002-6 sub boards instead of MaskROMs
|
||||
ROM_REGION( 0x80000, "maincpu", 0 ) // Located on the A8002-1 main board
|
||||
ROM_LOAD16_BYTE( "ma5j.n12", 0x000000, 0x20000, CRC(e6bb5952) SHA1(3b01eccc20d99fd33ff8e303afa902abb66e1036) )
|
||||
ROM_LOAD16_BYTE( "ma4j.l12", 0x000001, 0x20000, CRC(c78baa62) SHA1(c3554698fbc94e3625269c5cb1fc664364f3fb3f) )
|
||||
ROM_LOAD16_BYTE( "ma7j.n13", 0x040000, 0x20000, CRC(12a68fc2) SHA1(c935788723d8ea3bfe99244b8c7b2aff85579912) )
|
||||
ROM_LOAD16_BYTE( "ma6j.l13", 0x040001, 0x20000, CRC(332b2f54) SHA1(c768f5437a20ea406523d3de9e1ea807b39e1622) )
|
||||
|
||||
ROM_REGION( 0x10000, "audiocpu", 0 ) // Located on the A8002-1 main board
|
||||
ROM_LOAD( "ma_3.e13", 0x000000, 0x10000, CRC(c06cc8e1) SHA1(65f5f1901120d633f7c3ba07432a188fd7fd7272) )
|
||||
|
||||
ROM_REGION( 0x020000, "tx_tiles", 0 ) // Located on the A8002-2 board
|
||||
ROM_LOAD( "ma_1.l2", 0x000000, 0x10000, CRC(24766917) SHA1(9082a8ae849605ce65b5a0493ae69cfe282f7e7b) )
|
||||
|
||||
ROM_REGION( 0x200000, "sprites1", 0 ) // Located on the A8002-6 sub board
|
||||
ROM_LOAD16_BYTE( "s_9.a1", 0x000001, 0x20000, CRC(6e8e194c) SHA1(02bbd573a322a3f7f8e92ccceebffdd598b5489e) ) // these 4 == mao89p13.bin
|
||||
ROM_LOAD16_BYTE( "s_1.b1", 0x000000, 0x20000, CRC(fd9161ed) SHA1(b3e2434dd9cb1cafe1022774b863b5f1a008a9d2) )
|
||||
ROM_LOAD16_BYTE( "s_10.a2", 0x040001, 0x20000, CRC(fad6a1ab) SHA1(5347b4493c8004dc8cedc0b37aba494f203142b8) )
|
||||
ROM_LOAD16_BYTE( "s_2.b2", 0x040000, 0x20000, CRC(549056f0) SHA1(f515aa98ab25f3735dbfdefcb8d55ba3b2075b70) )
|
||||
ROM_LOAD16_BYTE( "s_11.a3", 0x080001, 0x20000, CRC(3887a382) SHA1(b40861fc1414b2fa299772e76a78cb8dc00b71b7) ) // these 4 == ma189p15.bin
|
||||
ROM_LOAD16_BYTE( "s_3.b3", 0x080000, 0x20000, CRC(cb99f565) SHA1(9ed1b21f4a33b9a614bca38610378857560cdaba) )
|
||||
ROM_LOAD16_BYTE( "s_12.a4", 0x0c0001, 0x20000, CRC(63417b49) SHA1(786249fa7e8770de5b5882debdc2913d58e9170e) )
|
||||
ROM_LOAD16_BYTE( "s_4.b4", 0x0c0000, 0x20000, CRC(d739d48a) SHA1(04d2ecea72b6e651b815865946c9c9cfae4e5c4d) )
|
||||
ROM_LOAD16_BYTE( "s_13.a5", 0x100001, 0x20000, CRC(eccd47b6) SHA1(6b9c63fee97a7568114f227a89a1effd6b04806a) ) // these 4 == ma289p17.bin
|
||||
ROM_LOAD16_BYTE( "s_5.b5", 0x100000, 0x20000, CRC(e15244da) SHA1(ebf3072565c53d0098d373b5093ba6918c4eddae) )
|
||||
ROM_LOAD16_BYTE( "s_14.a6", 0x140001, 0x20000, CRC(bbbf0461) SHA1(c5299ab1d45f685a5d160492247cf1303ef6937a) )
|
||||
ROM_LOAD16_BYTE( "s_6.b6", 0x140000, 0x20000, CRC(4ee89f75) SHA1(bda0e9095da2d424faac341fd934000a621796eb) )
|
||||
ROM_LOAD16_BYTE( "s_15.a7", 0x180001, 0x20000, CRC(cde29bad) SHA1(24c1b43c6d717eaaf7c01ec7de89837947334224) ) // these 4 == ma389m15.bin
|
||||
ROM_LOAD16_BYTE( "s_7.b7", 0x180000, 0x20000, CRC(065ed221) SHA1(c03ca5b4d1198939a57b5fccf6a79d70afe1faaf) )
|
||||
ROM_LOAD16_BYTE( "s_16.a8", 0x1c0001, 0x20000, CRC(70f28040) SHA1(91012728953563fcc576725337e6ba7e1b49d1ba) )
|
||||
ROM_LOAD16_BYTE( "s_8.b8", 0x1c0000, 0x20000, CRC(a6f8574f) SHA1(87c041669b2eaec495ae10a6f45b6668accb92bf) )
|
||||
|
||||
ROM_REGION( 0x80000, "gfx3", 0 ) // these 4 == mab189a2.bin - Located on the A8002-5 sub board
|
||||
ROM_LOAD( "s_21.b3", 0x000000, 0x20000, CRC(701a0072) SHA1(b03b6fa18e0cfcd5c7c541025fa2d3632d2f8387) )
|
||||
ROM_LOAD( "s_22.b4", 0x020000, 0x20000, CRC(34e6225c) SHA1(f6335084f4f4c7a4b6528e6ad74962b88f81e3bc) )
|
||||
ROM_LOAD( "s_23.b5", 0x040000, 0x20000, CRC(9a7399d3) SHA1(04e0327b0da75f621b51e1831cbdc4537082e32b) )
|
||||
ROM_LOAD( "s_24.b6", 0x060000, 0x20000, CRC(f097459d) SHA1(466364677f048519eb2894ddecf76f5c52f6afe9) )
|
||||
|
||||
ROM_REGION( 0x80000, "gfx4", 0 ) // these 4 == mab289c2.bin - Located on the A8002-5 sub board
|
||||
ROM_LOAD( "s_17.a3", 0x000000, 0x20000, CRC(cc47c4a3) SHA1(140f53b671b4eaed6fcc516c4018f07a6d7c2290) )
|
||||
ROM_LOAD( "s_18.a4", 0x020000, 0x20000, CRC(a04377e8) SHA1(841c6c3073b137f6a5c875db32039186c014f785) )
|
||||
ROM_LOAD( "s_19.a5", 0x040000, 0x20000, CRC(b07f5289) SHA1(8817bd225edf9b0fa439b220617f925365e39253) )
|
||||
ROM_LOAD( "s_20.a6", 0x060000, 0x20000, CRC(a9bb4fa9) SHA1(ccede784671a864667b92a8101d686c26c78d76f) )
|
||||
|
||||
ROM_REGION( 0x20000, "ymsnd", 0 ) // Located on the A8002-1 main board
|
||||
ROM_LOAD( "ma_2.d10", 0x000000, 0x20000, CRC(ea4cc30d) SHA1(d8f089fc0ce76309411706a8110ad907f93dc97e) )
|
||||
|
||||
ROM_REGION( 0x20000, "sprites1:scale_table", 0 ) // Zoom table - Located on the A8002-2 board
|
||||
ROM_LOAD( "ma_8.f10", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) )
|
||||
ROM_LOAD( "ma_9.f12", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) // identical to ma_8.f10
|
||||
ROM_END
|
||||
|
||||
ROM_START( mechattu )
|
||||
ROM_REGION( 0x80000, "maincpu", 0 ) // Located on the A8002-1 main board
|
||||
ROM_LOAD16_BYTE( "ma5u.n12", 0x000000, 0x20000, CRC(485ea606) SHA1(0c499f08d7c6d861ba7c50a8f577823613a7923c) )
|
||||
ROM_LOAD16_BYTE( "ma4u.l12", 0x000001, 0x20000, CRC(09fa31ec) SHA1(008abb2e09f83614c277471e534f20cba3e354d7) )
|
||||
ROM_LOAD16_BYTE( "ma7u.n13", 0x040000, 0x20000, CRC(f45b2c70) SHA1(65523d202d378bab890f1f7bffdde152dd246d4a) )
|
||||
ROM_LOAD16_BYTE( "ma6u.l13", 0x040001, 0x20000, CRC(d5d68ce6) SHA1(16057d882781015f6d1c7bb659e0812a8459c3f0) )
|
||||
|
||||
ROM_REGION( 0x10000, "audiocpu", 0 ) // Located on the A8002-1 main board
|
||||
ROM_LOAD( "ma_3.e13", 0x000000, 0x10000, CRC(c06cc8e1) SHA1(65f5f1901120d633f7c3ba07432a188fd7fd7272) )
|
||||
|
||||
ROM_REGION( 0x020000, "tx_tiles", 0 ) // Located on the A8002-2 board
|
||||
ROM_LOAD( "ma_1.l2", 0x000000, 0x10000, CRC(24766917) SHA1(9082a8ae849605ce65b5a0493ae69cfe282f7e7b) )
|
||||
|
||||
ROM_REGION( 0x200000, "sprites1", 0 ) // Located on the A8002-2 board
|
||||
ROM_LOAD16_WORD_SWAP( "mao89p13.bin", 0x000000, 0x80000, CRC(8bcb16cf) SHA1(409ee1944188d9ce39adce29b1df029b560dd5b0) )
|
||||
ROM_LOAD16_WORD_SWAP( "ma189p15.bin", 0x080000, 0x80000, CRC(b84d9658) SHA1(448adecb0067d8f5b219ec2f94a8dec84187a554) )
|
||||
ROM_LOAD16_WORD_SWAP( "ma289p17.bin", 0x100000, 0x80000, CRC(6cbe08ac) SHA1(8f81f6e92b84ab6867452011d52f3e7689c62a1a) )
|
||||
ROM_LOAD16_WORD_SWAP( "ma389m15.bin", 0x180000, 0x80000, CRC(34d4585e) SHA1(38d9fd5d775e4b3c8b8b487a6ba9b8bdcb3274b0) )
|
||||
|
||||
ROM_REGION( 0x80000, "gfx3", 0 ) // Located on the A8002-2 board
|
||||
ROM_LOAD( "mab189a2.bin", 0x000000, 0x80000, CRC(e1c8b4d0) SHA1(2f8a1839cca892f8380c7cffe7a12e615d38fd55) )
|
||||
|
||||
ROM_REGION( 0x80000, "gfx4", 0 ) // Located on the A8002-2 board
|
||||
ROM_LOAD( "mab289c2.bin", 0x000000, 0x80000, CRC(14f97ceb) SHA1(a22033532ea616dc3a3db8b66ad6ccc6172ed7cc) )
|
||||
|
||||
ROM_REGION( 0x20000, "ymsnd", 0 ) // Located on the A8002-1 main board
|
||||
ROM_LOAD( "ma_2.d10", 0x000000, 0x20000, CRC(ea4cc30d) SHA1(d8f089fc0ce76309411706a8110ad907f93dc97e) )
|
||||
|
||||
ROM_REGION( 0x20000, "sprites1:scale_table", 0 ) // Zoom table - Located on the A8002-2 board
|
||||
ROM_LOAD( "ma_8.f10", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) )
|
||||
ROM_LOAD( "ma_9.f12", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) // identical to ma_8.f10
|
||||
ROM_END
|
||||
|
||||
/* does Ver1 on the roms mean it's a revision, the first version, or used because it's the single player version? */
|
||||
ROM_START( mechattu1 ) // Uses EPROMs on official SNK A8002-5 & A8002-6 sub boards instead of MaskROMs
|
||||
ROM_REGION( 0x80000, "maincpu", 0 ) // Located on the A8002-1 main board
|
||||
ROM_LOAD16_BYTE( "ma_ver1_5u.n12", 0x000000, 0x20000, CRC(dcd2e971) SHA1(e292b251c429b6990e97233e86360e5d43f573f2) )
|
||||
ROM_LOAD16_BYTE( "ma_ver1_4u.l12", 0x000001, 0x20000, CRC(69c8a85b) SHA1(07c6d395772a5e096e3ac42c5248eadccc146ad1) )
|
||||
ROM_LOAD16_BYTE( "ma7u.n13", 0x040000, 0x20000, CRC(f45b2c70) SHA1(65523d202d378bab890f1f7bffdde152dd246d4a) )
|
||||
ROM_LOAD16_BYTE( "ma6u.l13", 0x040001, 0x20000, CRC(d5d68ce6) SHA1(16057d882781015f6d1c7bb659e0812a8459c3f0) )
|
||||
|
||||
ROM_REGION( 0x10000, "audiocpu", 0 ) // Located on the A8002-1 main board
|
||||
ROM_LOAD( "ma_3.e13", 0x000000, 0x10000, CRC(c06cc8e1) SHA1(65f5f1901120d633f7c3ba07432a188fd7fd7272) )
|
||||
|
||||
ROM_REGION( 0x020000, "tx_tiles", 0 ) // Located on the A8002-2 board
|
||||
ROM_LOAD( "ma_1.l2", 0x000000, 0x10000, CRC(24766917) SHA1(9082a8ae849605ce65b5a0493ae69cfe282f7e7b) )
|
||||
|
||||
ROM_REGION( 0x200000, "sprites1", 0 ) // Located on the A8002-6 sub board
|
||||
ROM_LOAD16_BYTE( "s_9.a1", 0x000001, 0x20000, CRC(6e8e194c) SHA1(02bbd573a322a3f7f8e92ccceebffdd598b5489e) ) // these 4 == mao89p13.bin
|
||||
ROM_LOAD16_BYTE( "s_1.b1", 0x000000, 0x20000, CRC(fd9161ed) SHA1(b3e2434dd9cb1cafe1022774b863b5f1a008a9d2) )
|
||||
ROM_LOAD16_BYTE( "s_10.a2", 0x040001, 0x20000, CRC(fad6a1ab) SHA1(5347b4493c8004dc8cedc0b37aba494f203142b8) )
|
||||
ROM_LOAD16_BYTE( "s_2.b2", 0x040000, 0x20000, CRC(549056f0) SHA1(f515aa98ab25f3735dbfdefcb8d55ba3b2075b70) )
|
||||
ROM_LOAD16_BYTE( "s_11.a3", 0x080001, 0x20000, CRC(3887a382) SHA1(b40861fc1414b2fa299772e76a78cb8dc00b71b7) ) // these 4 == ma189p15.bin
|
||||
ROM_LOAD16_BYTE( "s_3.b3", 0x080000, 0x20000, CRC(cb99f565) SHA1(9ed1b21f4a33b9a614bca38610378857560cdaba) )
|
||||
ROM_LOAD16_BYTE( "s_12.a4", 0x0c0001, 0x20000, CRC(63417b49) SHA1(786249fa7e8770de5b5882debdc2913d58e9170e) )
|
||||
ROM_LOAD16_BYTE( "s_4.b4", 0x0c0000, 0x20000, CRC(d739d48a) SHA1(04d2ecea72b6e651b815865946c9c9cfae4e5c4d) )
|
||||
ROM_LOAD16_BYTE( "s_13.a5", 0x100001, 0x20000, CRC(eccd47b6) SHA1(6b9c63fee97a7568114f227a89a1effd6b04806a) ) // these 4 == ma289p17.bin
|
||||
ROM_LOAD16_BYTE( "s_5.b5", 0x100000, 0x20000, CRC(e15244da) SHA1(ebf3072565c53d0098d373b5093ba6918c4eddae) )
|
||||
ROM_LOAD16_BYTE( "s_14.a6", 0x140001, 0x20000, CRC(bbbf0461) SHA1(c5299ab1d45f685a5d160492247cf1303ef6937a) )
|
||||
ROM_LOAD16_BYTE( "s_6.b6", 0x140000, 0x20000, CRC(4ee89f75) SHA1(bda0e9095da2d424faac341fd934000a621796eb) )
|
||||
ROM_LOAD16_BYTE( "s_15.a7", 0x180001, 0x20000, CRC(cde29bad) SHA1(24c1b43c6d717eaaf7c01ec7de89837947334224) ) // these 4 == ma389m15.bin
|
||||
ROM_LOAD16_BYTE( "s_7.b7", 0x180000, 0x20000, CRC(065ed221) SHA1(c03ca5b4d1198939a57b5fccf6a79d70afe1faaf) )
|
||||
ROM_LOAD16_BYTE( "s_16.a8", 0x1c0001, 0x20000, CRC(70f28040) SHA1(91012728953563fcc576725337e6ba7e1b49d1ba) )
|
||||
ROM_LOAD16_BYTE( "s_8.b8", 0x1c0000, 0x20000, CRC(a6f8574f) SHA1(87c041669b2eaec495ae10a6f45b6668accb92bf) )
|
||||
|
||||
ROM_REGION( 0x80000, "gfx3", 0 ) // these 4 == mab189a2.bin - Located on the A8002-5 sub board
|
||||
ROM_LOAD( "s_21.b3", 0x000000, 0x20000, CRC(701a0072) SHA1(b03b6fa18e0cfcd5c7c541025fa2d3632d2f8387) )
|
||||
ROM_LOAD( "s_22.b4", 0x020000, 0x20000, CRC(34e6225c) SHA1(f6335084f4f4c7a4b6528e6ad74962b88f81e3bc) )
|
||||
ROM_LOAD( "s_23.b5", 0x040000, 0x20000, CRC(9a7399d3) SHA1(04e0327b0da75f621b51e1831cbdc4537082e32b) )
|
||||
ROM_LOAD( "s_24.b6", 0x060000, 0x20000, CRC(f097459d) SHA1(466364677f048519eb2894ddecf76f5c52f6afe9) )
|
||||
|
||||
ROM_REGION( 0x80000, "gfx4", 0 ) // these 4 == mab289c2.bin - Located on the A8002-5 sub board
|
||||
ROM_LOAD( "s_17.a3", 0x000000, 0x20000, CRC(cc47c4a3) SHA1(140f53b671b4eaed6fcc516c4018f07a6d7c2290) )
|
||||
ROM_LOAD( "s_18.a4", 0x020000, 0x20000, CRC(a04377e8) SHA1(841c6c3073b137f6a5c875db32039186c014f785) )
|
||||
ROM_LOAD( "s_19.a5", 0x040000, 0x20000, CRC(b07f5289) SHA1(8817bd225edf9b0fa439b220617f925365e39253) )
|
||||
ROM_LOAD( "s_20.a6", 0x060000, 0x20000, CRC(a9bb4fa9) SHA1(ccede784671a864667b92a8101d686c26c78d76f) )
|
||||
|
||||
ROM_REGION( 0x20000, "ymsnd", 0 ) // Located on the A8002-1 main board
|
||||
ROM_LOAD( "ma_2.d10", 0x000000, 0x20000, CRC(ea4cc30d) SHA1(d8f089fc0ce76309411706a8110ad907f93dc97e) )
|
||||
|
||||
ROM_REGION( 0x20000, "sprites1:scale_table", 0 ) // Zoom table - Located on the A8002-2 board
|
||||
ROM_LOAD( "ma_8.f10", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) )
|
||||
ROM_LOAD( "ma_9.f12", 0x000000, 0x10000, CRC(61f3de03) SHA1(736f9634fe054ea68a2aa90a743bd0dc320f23c9) ) // identical to ma_8.f10
|
||||
ROM_END
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
GAME( 1989, mechatt, 0, mechatt, mechatt, mechatt_state, empty_init, ROT0, "SNK", "Mechanized Attack (World)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1989, mechattj, mechatt, mechatt, mechattj, mechatt_state, empty_init, ROT0, "SNK", "Mechanized Attack (Japan)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1989, mechattu, mechatt, mechatt, mechattu, mechatt_state, empty_init, ROT0, "SNK", "Mechanized Attack (US)", MACHINE_SUPPORTS_SAVE )
|
||||
GAME( 1989, mechattu1, mechatt, mechatt, mechattu1,mechatt_state, empty_init, ROT0, "SNK", "Mechanized Attack (US, Version 1, Single Player)", MACHINE_SUPPORTS_SAVE )
|
@ -1,115 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Bryan McPhail
|
||||
#ifndef MAME_INCLUDES_BBUSTERS_H
|
||||
#define MAME_INCLUDES_BBUSTERS_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "machine/gen_latch.h"
|
||||
#include "video/bufsprite.h"
|
||||
#include "screen.h"
|
||||
#include "tilemap.h"
|
||||
|
||||
class bbusters_state_base : public driver_device
|
||||
{
|
||||
protected:
|
||||
bbusters_state_base(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_audiocpu(*this, "audiocpu"),
|
||||
m_gfxdecode(*this, "gfxdecode"),
|
||||
m_spriteram(*this, "spriteram%u", 1U),
|
||||
m_soundlatch(*this, "soundlatch%u", 1U),
|
||||
m_videoram(*this, "videoram"),
|
||||
m_pf_data(*this, "pf%u_data", 1U),
|
||||
m_pf_scroll_data(*this, "pf%u_scroll_data", 1U),
|
||||
m_scale_table(*this, "scale_table"),
|
||||
m_gun_io(*this, { "GUNX1", "GUNY1", "GUNX2", "GUNY2", "GUNX3", "GUNY3" }),
|
||||
m_gun_recoil(*this, "Player%u_Gun_Recoil", 1U)
|
||||
{ }
|
||||
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<cpu_device> m_audiocpu;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
optional_device_array<buffered_spriteram16_device, 2> m_spriteram;
|
||||
required_device_array<generic_latch_8_device, 2> m_soundlatch;
|
||||
|
||||
required_shared_ptr<uint16_t> m_videoram;
|
||||
required_shared_ptr_array<uint16_t, 2> m_pf_data;
|
||||
required_shared_ptr_array<uint16_t, 2> m_pf_scroll_data;
|
||||
|
||||
required_region_ptr<uint8_t> m_scale_table;
|
||||
|
||||
optional_ioport_array<6> m_gun_io;
|
||||
output_finder<3> m_gun_recoil;
|
||||
|
||||
tilemap_t *m_fix_tilemap;
|
||||
tilemap_t *m_pf_tilemap[2];
|
||||
const uint8_t *m_scale_table_ptr;
|
||||
uint8_t m_scale_line_count;
|
||||
|
||||
virtual void machine_start() override;
|
||||
virtual void video_start() override;
|
||||
|
||||
TILE_GET_INFO_MEMBER(get_tile_info);
|
||||
template<int Layer, int Gfx> TILE_GET_INFO_MEMBER(get_pf_tile_info);
|
||||
|
||||
void sound_cpu_w(uint8_t data);
|
||||
void video_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
|
||||
template<int Layer> void pf_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
|
||||
void coin_counter_w(uint8_t data);
|
||||
|
||||
const uint8_t *get_source_ptr(gfx_element *gfx, uint32_t sprite, int dx, int dy, int block);
|
||||
void draw_block(screen_device &screen, bitmap_ind16 &dest,int x,int y,int size,int flipx,int flipy,uint32_t sprite,int color,int bank,int block,int priority);
|
||||
void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const uint16_t *source, int bank);
|
||||
|
||||
void sound_map(address_map &map);
|
||||
};
|
||||
|
||||
class bbusters_state : public bbusters_state_base
|
||||
{
|
||||
public:
|
||||
bbusters_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
bbusters_state_base(mconfig, type, tag),
|
||||
m_eprom_data(*this, "eeprom")
|
||||
{ }
|
||||
|
||||
void bbusters(machine_config &config);
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
virtual void video_start() override;
|
||||
|
||||
private:
|
||||
required_shared_ptr<uint16_t> m_eprom_data;
|
||||
|
||||
uint16_t eprom_r(offs_t offset);
|
||||
void three_gun_output_w(uint16_t data);
|
||||
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void bbusters_map(address_map &map);
|
||||
void sound_portmap(address_map &map);
|
||||
};
|
||||
|
||||
class mechatt_state : public bbusters_state_base
|
||||
{
|
||||
public:
|
||||
mechatt_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
bbusters_state_base(mconfig, type, tag)
|
||||
{ }
|
||||
|
||||
void mechatt(machine_config &config);
|
||||
|
||||
protected:
|
||||
virtual void video_start() override;
|
||||
|
||||
private:
|
||||
void two_gun_output_w(uint16_t data);
|
||||
uint16_t mechatt_gun_r(offs_t offset);
|
||||
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void mechatt_map(address_map &map);
|
||||
void sounda_portmap(address_map &map);
|
||||
};
|
||||
|
||||
#endif // MAME_INCLUDES_BBUSTERS_H
|
@ -3330,10 +3330,6 @@ bbustersu // A9003 'BB' (c) 1989
|
||||
bbustersua // A9003 'BB' (c) 1989
|
||||
bbustersj //
|
||||
bbustersja //
|
||||
mechatt // A8002 'MA' (c) 1989
|
||||
mechattj // A8002 'MA' (c) 1989
|
||||
mechattu // A8002 'MA' (c) 1989
|
||||
mechattu1 // A8002 'MA' (c) 1989
|
||||
|
||||
@source:bcs3.cpp
|
||||
bcs3 //
|
||||
@ -22443,6 +22439,12 @@ cgunship // (c) 1976 Meadows
|
||||
ckidzo // (c) 1976 Meadows
|
||||
mead4in1 // (c) 197? Meadows
|
||||
|
||||
@source:mechatt.cpp
|
||||
mechatt // A8002 'MA' (c) 1989
|
||||
mechattj // A8002 'MA' (c) 1989
|
||||
mechattu // A8002 'MA' (c) 1989
|
||||
mechattu1 // A8002 'MA' (c) 1989
|
||||
|
||||
@source:mediagx.cpp
|
||||
a51site4 // ?? (c) 1998
|
||||
a51site4a // Sept.11,1998 (c) 1998
|
||||
|
@ -1,297 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Bryan McPhail
|
||||
/***************************************************************************
|
||||
|
||||
Emulation by Bryan McPhail, mish@tendril.co.uk
|
||||
|
||||
Like NeoGeo sprite scale Y line selection is from an external rom.
|
||||
|
||||
For 16 high sprites scale data starts at 0x3800 (9 scale levels)
|
||||
For 32 high sprites scale data starts at 0x7000 (17 scale levels)
|
||||
For 64 high sprites scale data starts at 0xa000 (33 scale levels)
|
||||
For 128 pixel high sprites scale data starts 0xc000 (65 scale levels)
|
||||
|
||||
0xe000 and up - possibly X scale data? unconfirmed
|
||||
|
||||
Sprites are also double buffered, and this seems to be performed
|
||||
by having two complete sprite chips that are toggled per frame, rather
|
||||
than just ram. Beast Busters has 4 sprite chips as it has two sprite
|
||||
banks.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "includes/bbusters.h"
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
TILE_GET_INFO_MEMBER(bbusters_state_base::get_tile_info)
|
||||
{
|
||||
uint16_t tile = m_videoram[tile_index];
|
||||
|
||||
tileinfo.set(0,tile&0xfff,tile>>12,0);
|
||||
}
|
||||
|
||||
template<int Layer, int Gfx>
|
||||
TILE_GET_INFO_MEMBER(bbusters_state_base::get_pf_tile_info)
|
||||
{
|
||||
uint16_t tile = m_pf_data[Layer][tile_index];
|
||||
|
||||
tileinfo.set(Gfx,tile&0xfff,tile>>12,0);
|
||||
}
|
||||
|
||||
void bbusters_state_base::video_w(offs_t offset, uint16_t data, uint16_t mem_mask)
|
||||
{
|
||||
COMBINE_DATA(&m_videoram[offset]);
|
||||
m_fix_tilemap->mark_tile_dirty(offset);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void bbusters_state_base::video_start()
|
||||
{
|
||||
m_fix_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(bbusters_state_base::get_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
|
||||
m_fix_tilemap->set_transparent_pen(15);
|
||||
|
||||
save_item(NAME(m_scale_line_count));
|
||||
}
|
||||
|
||||
void bbusters_state::video_start()
|
||||
{
|
||||
bbusters_state_base::video_start();
|
||||
|
||||
m_pf_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, NAME((&bbusters_state::get_pf_tile_info<0,3>))), TILEMAP_SCAN_COLS, 16, 16, 128, 32);
|
||||
m_pf_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, NAME((&bbusters_state::get_pf_tile_info<1,4>))), TILEMAP_SCAN_COLS, 16, 16, 128, 32);
|
||||
|
||||
m_pf_tilemap[0]->set_transparent_pen(15);
|
||||
}
|
||||
|
||||
void mechatt_state::video_start()
|
||||
{
|
||||
bbusters_state_base::video_start();
|
||||
|
||||
m_pf_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, NAME((&mechatt_state::get_pf_tile_info<0,2>))), TILEMAP_SCAN_COLS, 16, 16, 256, 32);
|
||||
m_pf_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, NAME((&mechatt_state::get_pf_tile_info<1,3>))), TILEMAP_SCAN_COLS, 16, 16, 256, 32);
|
||||
|
||||
m_pf_tilemap[0]->set_transparent_pen(15);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
#define ADJUST_4x4 \
|
||||
if ((dx&0x10) && (dy&0x10)) code+=3; \
|
||||
else if (dy&0x10) code+=2; \
|
||||
else if (dx&0x10) code+=1
|
||||
|
||||
#define ADJUST_8x8 \
|
||||
if ((dx&0x20) && (dy&0x20)) code+=12; \
|
||||
else if (dy&0x20) code+=8; \
|
||||
else if (dx&0x20) code+=4
|
||||
|
||||
#define ADJUST_16x16 \
|
||||
if ((dx&0x40) && (dy&0x40)) code+=48; \
|
||||
else if (dy&0x40) code+=32; \
|
||||
else if (dx&0x40) code+=16
|
||||
|
||||
inline const uint8_t *bbusters_state_base::get_source_ptr(gfx_element *gfx, uint32_t sprite, int dx, int dy, int block)
|
||||
{
|
||||
int code=0;
|
||||
|
||||
/* Get a tile index from the x,y position in the block */
|
||||
switch (block)
|
||||
{
|
||||
case 0: /* 16 x 16 sprite */
|
||||
break;
|
||||
|
||||
case 1: /* 32 x 32 block
|
||||
0 1
|
||||
2 3
|
||||
*/
|
||||
ADJUST_4x4;
|
||||
break;
|
||||
|
||||
case 2: /* 64 by 64 block
|
||||
0 1 4 5
|
||||
2 3 6 7
|
||||
|
||||
8 9 12 13
|
||||
10 11 14 15
|
||||
*/
|
||||
ADJUST_4x4;
|
||||
ADJUST_8x8;
|
||||
break;
|
||||
|
||||
case 3: /* 128 by 128 block */
|
||||
ADJUST_4x4;
|
||||
ADJUST_8x8;
|
||||
ADJUST_16x16;
|
||||
break;
|
||||
}
|
||||
|
||||
return gfx->get_data((sprite+code) % gfx->elements()) + ((dy%16) * gfx->rowbytes());
|
||||
}
|
||||
|
||||
void bbusters_state_base::draw_block(screen_device &screen, bitmap_ind16 &dest,int x,int y,int size,int flipx,int flipy,uint32_t sprite,int color,int bank,int block,int priority)
|
||||
{
|
||||
gfx_element *gfx = m_gfxdecode->gfx(bank);
|
||||
pen_t pen_base = gfx->colorbase() + gfx->granularity() * (color % gfx->colors());
|
||||
uint32_t xinc=(m_scale_line_count * 0x10000 ) / size;
|
||||
int dy=y;
|
||||
int ex = m_scale_line_count;
|
||||
|
||||
while (m_scale_line_count) {
|
||||
if (dy>=16 && dy<240) {
|
||||
uint16_t *const destline = &dest.pix(dy);
|
||||
uint8_t *const priorityline = &screen.priority().pix(dy);
|
||||
uint8_t srcline=*m_scale_table_ptr;
|
||||
const uint8_t *srcptr=nullptr;
|
||||
|
||||
if (!flipy)
|
||||
srcline=size-srcline-1;
|
||||
|
||||
int x_index;
|
||||
if (flipx)
|
||||
x_index=(ex-1)*0x10000;
|
||||
else
|
||||
x_index=0;
|
||||
|
||||
for (int sx=0; sx<size; sx++) {
|
||||
if ((sx%16)==0)
|
||||
srcptr=get_source_ptr(gfx,sprite,sx,srcline,block);
|
||||
|
||||
uint8_t pixel=*srcptr++;
|
||||
if (pixel!=15 && priority > priorityline[(x+(x_index>>16)) & 0x1ff])
|
||||
{
|
||||
priorityline[(x+(x_index>>16)) & 0x1ff] = priority;
|
||||
destline[(x+(x_index>>16)) & 0x1ff]= pen_base + pixel;
|
||||
}
|
||||
|
||||
if (flipx)
|
||||
x_index-=xinc;
|
||||
else
|
||||
x_index+=xinc;
|
||||
}
|
||||
}
|
||||
|
||||
dy++;
|
||||
m_scale_table_ptr--;
|
||||
m_scale_line_count--;
|
||||
}
|
||||
}
|
||||
|
||||
void bbusters_state_base::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const uint16_t *source, int bank)
|
||||
{
|
||||
int offs;
|
||||
|
||||
// Sprites are stored in memory in back to front order.
|
||||
// We draw them here front to back with a priority buffer in case any sprite
|
||||
// with priority under a tilemap is later in the list than a sprite with
|
||||
// above tilemap priority (which would cause a cut-out as only the top-most sprite
|
||||
// in the line buffer goes to the priority mixer)
|
||||
for (offs = 0x7fc;offs >=0 ;offs -= 4) {
|
||||
int x,sprite,colour,fx,fy,scale;
|
||||
int16_t y;
|
||||
int block;
|
||||
int priority;
|
||||
|
||||
sprite=source[offs+1];
|
||||
colour=source[offs+0];
|
||||
|
||||
if ((colour==0xf7 || colour==0xffff || colour == 0x43f9) && (sprite==0x3fff || sprite==0xffff || sprite==0x0001))
|
||||
continue; // sprite 1, color 0x43f9 is the dead sprite in the top-right of the screen in Mechanized Attack's High Score table.
|
||||
|
||||
y=source[offs+3];
|
||||
x=source[offs+2];
|
||||
if (x&0x200) x=-(0x100-(x&0xff));
|
||||
if (y > 320 || y < -256) y &= 0x1ff; // fix for bbusters ending & "Zing!" attract-mode fullscreen zombie & Helicopter on the 3rd rotation of the attractmode sequence
|
||||
|
||||
/*
|
||||
Source[0]:
|
||||
0xf000: Colour
|
||||
0x0800: FX
|
||||
0x0400: FY?
|
||||
0x0300: Block control
|
||||
0x0080: ?
|
||||
0x007f: scale
|
||||
|
||||
Scale varies according to block size.
|
||||
Block type 0: 0x70 = no scale, 0x7f == half size - 16 pixel sprite
|
||||
Block type 1: 0x60 = no scale, 0x6f == half size - 32 pixel sprite
|
||||
Block type 2: 0x40 = no scale, 0x5f == half size - 64 pixel sprite
|
||||
Block type 3: 0x00 = no scale, 0x3f == half size - 128 pixel sprite
|
||||
|
||||
*/
|
||||
colour=colour>>12;
|
||||
block=(source[offs+0]>>8)&0x3;
|
||||
fy=source[offs+0]&0x400;
|
||||
fx=source[offs+0]&0x800;
|
||||
sprite=sprite&0x3fff;
|
||||
|
||||
// Palettes 0xc-0xf confirmed to be behind tilemap on Beast Busters for 2nd sprite chip
|
||||
priority = (bank==2) ? (((colour&0xc)==0xc) ? 1 : 4) : 8;
|
||||
|
||||
switch ((source[offs+0]>>8)&0x3) {
|
||||
case 0:
|
||||
scale=source[offs+0]&0x7;
|
||||
m_scale_table_ptr = m_scale_table+0x387f+(0x80*scale);
|
||||
m_scale_line_count = 0x10-scale;
|
||||
draw_block(screen,bitmap,x,y,16,fx,fy,sprite,colour,bank,block,priority);
|
||||
break;
|
||||
case 1: /* 2 x 2 */
|
||||
scale=source[offs+0]&0xf;
|
||||
m_scale_table_ptr = m_scale_table+0x707f+(0x80*scale);
|
||||
m_scale_line_count = 0x20-scale;
|
||||
draw_block(screen,bitmap,x,y,32,fx,fy,sprite,colour,bank,block,priority);
|
||||
break;
|
||||
case 2: /* 64 by 64 block (2 x 2) x 2 */
|
||||
scale=source[offs+0]&0x1f;
|
||||
m_scale_table_ptr = m_scale_table+0xa07f+(0x80*scale);
|
||||
m_scale_line_count = 0x40-scale;
|
||||
draw_block(screen,bitmap,x,y,64,fx,fy,sprite,colour,bank,block,priority);
|
||||
break;
|
||||
case 3: /* 2 x 2 x 2 x 2 */
|
||||
scale=source[offs+0]&0x3f;
|
||||
m_scale_table_ptr = m_scale_table+0xc07f+(0x80*scale);
|
||||
m_scale_line_count = 0x80-scale;
|
||||
draw_block(screen,bitmap,x,y,128,fx,fy,sprite,colour,bank,block,priority);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
uint32_t bbusters_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
screen.priority().fill(0, cliprect);
|
||||
|
||||
m_pf_tilemap[0]->set_scrollx(0, m_pf_scroll_data[0][0]);
|
||||
m_pf_tilemap[0]->set_scrolly(0, m_pf_scroll_data[0][1]);
|
||||
m_pf_tilemap[1]->set_scrollx(0, m_pf_scroll_data[1][0]);
|
||||
m_pf_tilemap[1]->set_scrolly(0, m_pf_scroll_data[1][1]);
|
||||
|
||||
m_pf_tilemap[1]->draw(screen, bitmap, cliprect, 0, 0);
|
||||
m_pf_tilemap[0]->draw(screen, bitmap, cliprect, 0, 2);
|
||||
draw_sprites(screen, bitmap, m_spriteram[1]->buffer(), 2);
|
||||
draw_sprites(screen, bitmap, m_spriteram[0]->buffer(), 1);
|
||||
m_fix_tilemap->draw(screen, bitmap, cliprect, 0, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t mechatt_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
screen.priority().fill(0, cliprect);
|
||||
|
||||
m_pf_tilemap[0]->set_scrollx(0, m_pf_scroll_data[0][0]);
|
||||
m_pf_tilemap[0]->set_scrolly(0, m_pf_scroll_data[0][1]);
|
||||
m_pf_tilemap[1]->set_scrollx(0, m_pf_scroll_data[1][0]);
|
||||
m_pf_tilemap[1]->set_scrolly(0, m_pf_scroll_data[1][1]);
|
||||
|
||||
m_pf_tilemap[1]->draw(screen, bitmap, cliprect, 0, 0);
|
||||
m_pf_tilemap[0]->draw(screen, bitmap, cliprect, 0, 0);
|
||||
draw_sprites(screen, bitmap, m_spriteram[0]->buffer(), 1);
|
||||
m_fix_tilemap->draw(screen, bitmap, cliprect, 0, 0);
|
||||
return 0;
|
||||
}
|
222
src/mame/video/snk_bbusters_spr.cpp
Normal file
222
src/mame/video/snk_bbusters_spr.cpp
Normal file
@ -0,0 +1,222 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Bryan McPhail
|
||||
/***************************************************************************
|
||||
|
||||
Like NeoGeo sprite scale Y line selection is from an external rom.
|
||||
|
||||
For 16 high sprites scale data starts at 0x3800 (9 scale levels)
|
||||
For 32 high sprites scale data starts at 0x7000 (17 scale levels)
|
||||
For 64 high sprites scale data starts at 0xa000 (33 scale levels)
|
||||
For 128 pixel high sprites scale data starts 0xc000 (65 scale levels)
|
||||
|
||||
0xe000 and up - possibly X scale data? unconfirmed
|
||||
|
||||
Sprites are also double buffered, and this seems to be performed
|
||||
by having two complete sprite chips that are toggled per frame, rather
|
||||
than just ram. Beast Busters has 4 sprite chips as it has two sprite
|
||||
banks.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "snk_bbusters_spr.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(SNK_BBUSTERS_SPR, snk_bbusters_spr_device, "snk_bbusters_spr", "SNK Beast Busters Sprites")
|
||||
|
||||
snk_bbusters_spr_device::snk_bbusters_spr_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: device_t(mconfig, SNK_BBUSTERS_SPR, tag, owner, clock)
|
||||
, device_gfx_interface(mconfig, *this, gfxinfo)
|
||||
, m_scale_table(*this, finder_base::DUMMY_TAG)
|
||||
, m_spriteram(*this, finder_base::DUMMY_TAG)
|
||||
{
|
||||
}
|
||||
|
||||
static const gfx_layout spritelayout =
|
||||
{
|
||||
16,16,
|
||||
RGN_FRAC(1,1),
|
||||
4,
|
||||
{ STEP4(0,4) },
|
||||
{
|
||||
STEP4(0,1), STEP4(4*4,1),
|
||||
STEP4(4*4*2*8,1), STEP4(4*4+4*4*2*8,1)
|
||||
},
|
||||
{ STEP8(0,4*4*2), STEP8(16*32,4*8) },
|
||||
128*8
|
||||
};
|
||||
|
||||
GFXDECODE_MEMBER( snk_bbusters_spr_device::gfxinfo )
|
||||
GFXDECODE_DEVICE( DEVICE_SELF, 0, spritelayout, 0, 16*4 )
|
||||
GFXDECODE_END
|
||||
|
||||
|
||||
void snk_bbusters_spr_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_scale_line_count));
|
||||
}
|
||||
|
||||
template<int Size>
|
||||
int snk_bbusters_spr_device::adjust_spritecode(int dx, int dy, int code)
|
||||
{
|
||||
if (dy & (0x10 << Size)) code += 2 << (Size * 2);
|
||||
if (dx & (0x10 << Size)) code += 1 << (Size * 2);
|
||||
return code;
|
||||
}
|
||||
|
||||
inline const uint8_t* snk_bbusters_spr_device::get_source_ptr(gfx_element* tilegfx, uint32_t sprite, int dx, int dy, int block)
|
||||
{
|
||||
int code = 0;
|
||||
|
||||
/* Get a tile index from the x,y position in the block */
|
||||
switch (block)
|
||||
{
|
||||
case 0: /* 16 x 16 sprite */
|
||||
break;
|
||||
|
||||
case 1: /* 32 x 32 block
|
||||
0 1
|
||||
2 3
|
||||
*/
|
||||
code = adjust_spritecode<0>(dx, dy, code); // 4x4
|
||||
break;
|
||||
|
||||
case 2: /* 64 by 64 block
|
||||
0 1 4 5
|
||||
2 3 6 7
|
||||
|
||||
8 9 12 13
|
||||
10 11 14 15
|
||||
*/
|
||||
code = adjust_spritecode<0>(dx, dy, code); // 4x4
|
||||
code = adjust_spritecode<1>(dx, dy, code); // 8x8
|
||||
break;
|
||||
|
||||
case 3: /* 128 by 128 block */
|
||||
code = adjust_spritecode<0>(dx, dy, code); // 4x4
|
||||
code = adjust_spritecode<1>(dx, dy, code); // 8x8
|
||||
code = adjust_spritecode<2>(dx, dy, code); // 16x16
|
||||
break;
|
||||
}
|
||||
|
||||
return tilegfx->get_data((sprite + code) % tilegfx->elements()) + ((dy % 16) * tilegfx->rowbytes());
|
||||
}
|
||||
|
||||
void snk_bbusters_spr_device::draw_block(bitmap_ind16 &dest, const rectangle &cliprect, int x, int y, int size, int flipx, int flipy, uint32_t sprite, int color, int block)
|
||||
{
|
||||
// TODO: respect cliprect
|
||||
|
||||
gfx_element* tilegfx = gfx(0);
|
||||
pen_t pen_base = tilegfx->colorbase() + tilegfx->granularity() * (color % tilegfx->colors());
|
||||
uint32_t xinc = (m_scale_line_count * 0x10000) / size;
|
||||
int dy = y;
|
||||
int ex = m_scale_line_count;
|
||||
|
||||
while (m_scale_line_count)
|
||||
{
|
||||
if (dy >= 16 && dy < 240)
|
||||
{
|
||||
uint16_t* const destline = &dest.pix(dy);
|
||||
uint8_t srcline = *m_scale_table_ptr;
|
||||
const uint8_t* srcptr = nullptr;
|
||||
|
||||
if (!flipy)
|
||||
srcline = size - srcline - 1;
|
||||
|
||||
int x_index;
|
||||
if (flipx)
|
||||
x_index = (ex - 1) * 0x10000;
|
||||
else
|
||||
x_index = 0;
|
||||
|
||||
for (int sx = 0; sx < size; sx++)
|
||||
{
|
||||
if ((sx % 16) == 0)
|
||||
srcptr = get_source_ptr(tilegfx, sprite, sx, srcline, block);
|
||||
|
||||
uint8_t pixel = *srcptr++;
|
||||
if (pixel != 15)
|
||||
destline[(x + (x_index >> 16)) & 0x1ff] = pen_base + pixel;
|
||||
|
||||
if (flipx)
|
||||
x_index -= xinc;
|
||||
else
|
||||
x_index += xinc;
|
||||
}
|
||||
}
|
||||
|
||||
dy++;
|
||||
m_scale_table_ptr--;
|
||||
m_scale_line_count--;
|
||||
}
|
||||
}
|
||||
|
||||
void snk_bbusters_spr_device::draw_sprites(bitmap_ind16& bitmap, const rectangle& cliprect)
|
||||
{
|
||||
const uint16_t* sprram = m_spriteram->buffer();
|
||||
|
||||
for (int offs = 0; offs < 0x800; offs += 4)
|
||||
{
|
||||
int sprite = sprram[offs + 1];
|
||||
int colour = sprram[offs + 0];
|
||||
|
||||
// TODO: get rid of this abominable hack without breaking anything
|
||||
if ((colour == 0xf7 || colour == 0xffff || colour == 0x43f9) && (sprite == 0x3fff || sprite == 0xffff || sprite == 0x0001))
|
||||
continue; // sprite 1, color 0x43f9 is the dead sprite in the top-right of the screen in Mechanized Attack's High Score table.
|
||||
|
||||
int16_t y = sprram[offs + 3];
|
||||
int x = sprram[offs + 2];
|
||||
if (x & 0x200) x = -(0x100 - (x & 0xff));
|
||||
if (y > 320 || y < -256) y &= 0x1ff; // fix for bbusters ending & "Zing!" attract-mode fullscreen zombie & Helicopter on the 3rd rotation of the attractmode sequence
|
||||
|
||||
/*
|
||||
sprram[0]:
|
||||
0xf000: Colour
|
||||
0x0800: FX
|
||||
0x0400: FY?
|
||||
0x0300: Block control
|
||||
0x0080: ?
|
||||
0x007f: scale
|
||||
|
||||
Scale varies according to block size.
|
||||
Block type 0: 0x70 = no scale, 0x7f == half size - 16 pixel sprite
|
||||
Block type 1: 0x60 = no scale, 0x6f == half size - 32 pixel sprite
|
||||
Block type 2: 0x40 = no scale, 0x5f == half size - 64 pixel sprite
|
||||
Block type 3: 0x00 = no scale, 0x3f == half size - 128 pixel sprite
|
||||
|
||||
*/
|
||||
colour = colour >> 12;
|
||||
int block = (sprram[offs + 0] >> 8) & 0x3;
|
||||
int fy = sprram[offs + 0] & 0x400;
|
||||
int fx = sprram[offs + 0] & 0x800;
|
||||
sprite = sprite & 0x3fff;
|
||||
|
||||
int scale;
|
||||
switch ((sprram[offs + 0] >> 8) & 0x3)
|
||||
{
|
||||
case 0:
|
||||
scale = sprram[offs + 0] & 0x7;
|
||||
m_scale_table_ptr = m_scale_table + 0x387f + (0x80 * scale);
|
||||
m_scale_line_count = 0x10 - scale;
|
||||
draw_block(bitmap, cliprect, x, y, 16, fx, fy, sprite, colour, block);
|
||||
break;
|
||||
case 1: /* 2 x 2 */
|
||||
scale = sprram[offs + 0] & 0xf;
|
||||
m_scale_table_ptr = m_scale_table + 0x707f + (0x80 * scale);
|
||||
m_scale_line_count = 0x20 - scale;
|
||||
draw_block(bitmap, cliprect, x, y, 32, fx, fy, sprite, colour, block);
|
||||
break;
|
||||
case 2: /* 64 by 64 block (2 x 2) x 2 */
|
||||
scale = sprram[offs + 0] & 0x1f;
|
||||
m_scale_table_ptr = m_scale_table + 0xa07f + (0x80 * scale);
|
||||
m_scale_line_count = 0x40 - scale;
|
||||
draw_block(bitmap, cliprect, x, y, 64, fx, fy, sprite, colour, block);
|
||||
break;
|
||||
case 3: /* 2 x 2 x 2 x 2 */
|
||||
scale = sprram[offs + 0] & 0x3f;
|
||||
m_scale_table_ptr = m_scale_table + 0xc07f + (0x80 * scale);
|
||||
m_scale_line_count = 0x80 - scale;
|
||||
draw_block(bitmap, cliprect, x, y, 128, fx, fy, sprite, colour, block);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
42
src/mame/video/snk_bbusters_spr.h
Normal file
42
src/mame/video/snk_bbusters_spr.h
Normal file
@ -0,0 +1,42 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Bryan McPhail
|
||||
#ifndef MAME_VIDEO_SNK_BBUSTERS_SPR_H
|
||||
#define MAME_VIDEO_SNK_BBUSTERS_SPR_H
|
||||
|
||||
|
||||
#include "video/bufsprite.h"
|
||||
|
||||
class snk_bbusters_spr_device : public device_t, public device_gfx_interface
|
||||
{
|
||||
public:
|
||||
snk_bbusters_spr_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
// configuration
|
||||
template <typename T> void set_spriteram_tag(T &&tag) { m_spriteram.set_tag(std::forward<T>(tag)); }
|
||||
template <typename T> void set_scaletable_tag(T &&tag) { m_scale_table.set_tag(std::forward<T>(tag)); }
|
||||
|
||||
void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
protected:
|
||||
virtual void device_start() override;
|
||||
|
||||
private:
|
||||
|
||||
DECLARE_GFXDECODE_MEMBER(gfxinfo);
|
||||
|
||||
const uint8_t *m_scale_table_ptr;
|
||||
uint8_t m_scale_line_count;
|
||||
|
||||
template<int Size>
|
||||
int adjust_spritecode(int dx, int dy, int code);
|
||||
|
||||
const uint8_t *get_source_ptr(gfx_element *tilegfx, uint32_t sprite, int dx, int dy, int block);
|
||||
void draw_block(bitmap_ind16 &dest, const rectangle &cliprect, int x,int y,int size,int flipx,int flipy,uint32_t sprite,int color,int block);
|
||||
|
||||
required_region_ptr<uint8_t> m_scale_table;
|
||||
required_device<buffered_spriteram16_device> m_spriteram;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(SNK_BBUSTERS_SPR, snk_bbusters_spr_device)
|
||||
|
||||
#endif // MAME_VIDEO_SNK_BBUSTERS_SPR_H
|
Loading…
Reference in New Issue
Block a user