diff --git a/src/mame/audio/gottlieb.c b/src/mame/audio/gottlieb.c index be38034f0fb..df87f954af2 100644 --- a/src/mame/audio/gottlieb.c +++ b/src/mame/audio/gottlieb.c @@ -206,7 +206,7 @@ static const char *const reactor_sample_names[] = "fx_39j", /* "45000" */ "fx_39k", /* "50000" */ "fx_39l", /* "55000" */ - 0 /* end of array */ + 0 /* end of array */ }; static const char *const qbert_sample_names[] = @@ -256,7 +256,6 @@ static const char *const qbert_sample_names[] = "fx_23", /* O1 with varying voice clock */ "fx_28", "fx_36", - "knocker", 0 /* end of array */ }; @@ -286,6 +285,47 @@ MACHINE_CONFIG_END +//************************************************************************** +// QBERT MECHANICAL KNOCKER +//************************************************************************** + +//------------------------------------------------- +// qbert cabinets have a mechanical knocker near the floor, +// MAME simulates this with a sample. +// (like all MAME samples, it is optional. If you actually have +// a real kicker/knocker, hook it up via output "knocker0") +//------------------------------------------------- + +void gottlieb_state::qbert_knocker(UINT8 knock) +{ + output_set_value("knocker0", knock); + + // start sound on rising edge + if (knock & ~m_knocker_prev) + m_knocker_sample->start(0, 0); + m_knocker_prev = knock; +} + +static const char *const qbert_knocker_names[] = +{ + "*qbert", + "knocker", + 0 /* end of array */ +}; + +static const samples_interface qbert_knocker_interface = +{ + 1, /* one channel */ + qbert_knocker_names +}; + +MACHINE_CONFIG_FRAGMENT( qbert_knocker ) + MCFG_SAMPLES_ADD("knocker", qbert_knocker_interface) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0) +MACHINE_CONFIG_END + + + //************************************************************************** // REV 1 SOUND BOARD: 6502 + DAC //************************************************************************** diff --git a/src/mame/drivers/gottlieb.c b/src/mame/drivers/gottlieb.c index e58f105a795..680e3ab1e8e 100644 --- a/src/mame/drivers/gottlieb.c +++ b/src/mame/drivers/gottlieb.c @@ -313,14 +313,11 @@ WRITE8_MEMBER(gottlieb_state::general_output_w) else gottlieb_laserdisc_video_control_w(space, offset, data); - /* bit 4 controls the coin meter */ + /* bit 4 normally controls the coin meter */ coin_counter_w(machine(), 0, data & 0x10); - /* bit 5 controls the knocker */ - output_set_value("knocker0", (data >> 5) & 1); - + /* bit 5 doesn't have a generic function */ /* bit 6 controls "COIN1"; it appears that no games used this */ - /* bit 7 controls the optional coin lockout; it appears that no games used this */ } @@ -334,6 +331,14 @@ WRITE8_MEMBER(gottlieb_state::reactor_output_w) set_led_status(machine(), 2, data & 0x80); } +WRITE8_MEMBER(gottlieb_state::qbert_output_w) +{ + general_output_w(space, offset, data & ~0x20); + + // bit 5 controls the knocker + qbert_knocker(data >> 5 & 1); +} + WRITE8_MEMBER(gottlieb_state::qbertqub_output_w) { // coincounter is on bit 5 instead @@ -1766,16 +1771,23 @@ static MACHINE_CONFIG_DERIVED( reactor, gottlieb1 ) MCFG_CPU_PROGRAM_MAP(reactor_map) MCFG_DEVICE_REMOVE("nvram") + + /* sound hardware */ MCFG_FRAGMENT_ADD(reactor_samples) MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( qbert, gottlieb1 ) + + /* sound hardware */ + MCFG_FRAGMENT_ADD(qbert_knocker) MCFG_FRAGMENT_ADD(qbert_samples) MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( tylz, gottlieb1 ) + + /* sound hardware */ MCFG_FRAGMENT_ADD(qbert_samples) MACHINE_CONFIG_END @@ -1800,6 +1812,9 @@ MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( qbert, gottlieb1_votrax ) + + /* sound hardware */ + MCFG_FRAGMENT_ADD(qbert_knocker) MACHINE_CONFIG_END @@ -2441,6 +2456,13 @@ DRIVER_INIT_MEMBER(gottlieb_state,romtiles) } +DRIVER_INIT_MEMBER(gottlieb_state,qbert) +{ + DRIVER_INIT_CALL(romtiles); + machine().device("maincpu")->memory().space(AS_PROGRAM).install_write_handler(0x5803, 0x5803, 0, 0x07f8, write8_delegate(FUNC(gottlieb_state::qbert_output_w),this)); +} + + DRIVER_INIT_MEMBER(gottlieb_state,qbertqub) { DRIVER_INIT_CALL(romtiles); @@ -2478,12 +2500,12 @@ DRIVER_INIT_MEMBER(gottlieb_state,vidvince) /* games using rev 1 sound board */ GAME( 1982, reactor, 0, reactor, reactor, gottlieb_state, ramtiles, ROT0, "Gottlieb", "Reactor", GAME_IMPERFECT_SOUND ) -GAME( 1982, qbert, 0, qbert, qbert, gottlieb_state, romtiles, ROT270, "Gottlieb", "Q*bert (US set 1)", GAME_IMPERFECT_SOUND ) -GAME( 1982, qberta, qbert, qbert, qbert, gottlieb_state, romtiles, ROT270, "Gottlieb", "Q*bert (US set 2)", GAME_IMPERFECT_SOUND ) -GAME( 1982, qbertj, qbert, qbert, qbert, gottlieb_state, romtiles, ROT270, "Gottlieb (Konami license)", "Q*bert (Japan)", GAME_IMPERFECT_SOUND ) -GAME( 1982, myqbert, qbert, qbert, qbert, gottlieb_state, romtiles, ROT270, "Gottlieb", "Mello Yello Q*bert", GAME_IMPERFECT_SOUND ) -GAME( 1982, qberttst, qbert, qbert, qbert, gottlieb_state, romtiles, ROT270, "Gottlieb", "Q*bert (early test version)", GAME_IMPERFECT_SOUND ) -GAME( 1982, qbtrktst, qbert, qbert, qbert, gottlieb_state, romtiles, ROT270, "Gottlieb", "Q*bert Board Input Test Rom", GAME_IMPERFECT_SOUND ) +GAME( 1982, qbert, 0, qbert, qbert, gottlieb_state, qbert, ROT270, "Gottlieb", "Q*bert (US set 1)", GAME_IMPERFECT_SOUND ) +GAME( 1982, qberta, qbert, qbert, qbert, gottlieb_state, qbert, ROT270, "Gottlieb", "Q*bert (US set 2)", GAME_IMPERFECT_SOUND ) +GAME( 1982, qbertj, qbert, qbert, qbert, gottlieb_state, qbert, ROT270, "Gottlieb (Konami license)", "Q*bert (Japan)", GAME_IMPERFECT_SOUND ) +GAME( 1982, myqbert, qbert, qbert, qbert, gottlieb_state, qbert, ROT270, "Gottlieb", "Mello Yello Q*bert", GAME_IMPERFECT_SOUND ) +GAME( 1982, qberttst, qbert, qbert, qbert, gottlieb_state, qbert, ROT270, "Gottlieb", "Q*bert (early test version)", GAME_IMPERFECT_SOUND ) +GAME( 1982, qbtrktst, qbert, qbert, qbert, gottlieb_state, qbert, ROT270, "Gottlieb", "Q*bert Board Input Test Rom", GAME_IMPERFECT_SOUND ) GAME( 1982, insector, 0, gottlieb1, insector, gottlieb_state, romtiles, ROT0, "Gottlieb", "Insector (prototype)", 0 ) GAME( 1982, tylz, 0, tylz, tylz, gottlieb_state, romtiles, ROT0, "Mylstar", "Tylz (prototype)", GAME_IMPERFECT_SOUND ) // modified sound hw? GAME( 1984, argusg, 0, gottlieb1, argusg, gottlieb_state, ramtiles, ROT0, "Gottlieb", "Argus (Gottlieb, prototype)" , 0) // aka Guardian / Protector? @@ -2491,7 +2513,7 @@ GAME( 1983, mplanets, 0, gottlieb1, mplanets, gottlieb_state, romtiles, GAME( 1983, mplanetsuk,mplanets, gottlieb1, mplanets, gottlieb_state, romtiles, ROT270, "Gottlieb (Taitel license)", "Mad Planets (UK)", 0 ) GAME( 1983, krull, 0, gottlieb1, krull, gottlieb_state, ramtiles, ROT270, "Gottlieb", "Krull", 0 ) GAME( 1983, kngtmare, 0, gottlieb1, kngtmare, gottlieb_state, romtiles, ROT0, "Gottlieb", "Knightmare (prototype)", GAME_NO_SOUND ) -GAME( 1983, sqbert, 0, qbert, qbert, gottlieb_state, romtiles, ROT270, "Mylstar", "Faster, Harder, More Challenging Q*bert (prototype)", GAME_IMPERFECT_SOUND ) +GAME( 1983, sqbert, 0, qbert, qbert, gottlieb_state, qbert, ROT270, "Mylstar", "Faster, Harder, More Challenging Q*bert (prototype)", GAME_IMPERFECT_SOUND ) GAME( 1983, qbertqub, 0, qbert, qbertqub, gottlieb_state, qbertqub, ROT270, "Mylstar", "Q*bert's Qubes", GAME_IMPERFECT_SOUND ) GAME( 1984, curvebal, 0, gottlieb1, curvebal, gottlieb_state, romtiles, ROT270, "Mylstar", "Curve Ball", 0 ) diff --git a/src/mame/includes/gottlieb.h b/src/mame/includes/gottlieb.h index c85d8b5a71c..5e476c03528 100644 --- a/src/mame/includes/gottlieb.h +++ b/src/mame/includes/gottlieb.h @@ -239,6 +239,7 @@ public: m_laserdisc(*this, "laserdisc"), m_r1_sound(*this, "r1sound"), m_r2_sound(*this, "r2sound"), + m_knocker_sample(*this, "knocker"), m_videoram(*this, "videoram"), m_charram(*this, "charram"), m_spriteram(*this, "spriteram") @@ -249,11 +250,13 @@ public: optional_device m_laserdisc; optional_device m_r1_sound; optional_device m_r2_sound; + optional_device m_knocker_sample; required_shared_ptr m_videoram; required_shared_ptr m_charram; required_shared_ptr m_spriteram; + UINT8 m_knocker_prev; UINT8 m_joystick_select; UINT8 m_track[2]; emu_timer *m_laserdisc_bit_timer; @@ -277,11 +280,14 @@ public: tilemap_t *m_bg_tilemap; double m_weights[4]; + void qbert_knocker(UINT8 knock); + DECLARE_WRITE8_MEMBER(gottlieb_analog_reset_w); DECLARE_WRITE8_MEMBER(general_output_w); DECLARE_WRITE8_MEMBER(reactor_output_w); DECLARE_WRITE8_MEMBER(stooges_output_w); DECLARE_WRITE8_MEMBER(qbertqub_output_w); + DECLARE_WRITE8_MEMBER(qbert_output_w); DECLARE_READ8_MEMBER(laserdisc_status_r); DECLARE_WRITE8_MEMBER(laserdisc_select_w); DECLARE_WRITE8_MEMBER(laserdisc_command_w); @@ -298,6 +304,7 @@ public: DECLARE_DRIVER_INIT(vidvince); DECLARE_DRIVER_INIT(ramtiles); DECLARE_DRIVER_INIT(stooges); + DECLARE_DRIVER_INIT(qbert); DECLARE_DRIVER_INIT(qbertqub); TILE_GET_INFO_MEMBER(get_bg_tile_info); TILE_GET_INFO_MEMBER(get_screwloo_bg_tile_info); @@ -313,7 +320,9 @@ public: TIMER_CALLBACK_MEMBER(nmi_clear); }; -/*----------- defined in video/gottlieb.c -----------*/ +/*----------- defined in audio/gottlieb.c -----------*/ + +MACHINE_CONFIG_EXTERN( qbert_knocker ); #if USE_FAKE_VOTRAX MACHINE_CONFIG_EXTERN( reactor_samples );