From ab56f7de85097459665e98578d9eead0af8444d0 Mon Sep 17 00:00:00 2001 From: Ivan Vangelista Date: Thu, 9 Feb 2023 18:05:45 +0100 Subject: [PATCH] atari/toobin.cpp, atari/triplhnt.cpp, atari/tunhunt.cpp. atari/videopin.cpp: consolidated drivers in single files --- src/mame/atari/toobin.cpp | 385 ++++++++++++++++++++-- src/mame/atari/toobin.h | 83 ----- src/mame/atari/toobin_v.cpp | 250 --------------- src/mame/atari/triplhnt.cpp | 334 ++++++++++++++++---- src/mame/atari/triplhnt.h | 108 ------- src/mame/atari/triplhnt_a.cpp | 7 +- src/mame/atari/triplhnt_a.h | 22 ++ src/mame/atari/triplhnt_v.cpp | 113 ------- src/mame/atari/tunhunt.cpp | 580 +++++++++++++++++++++++++++++----- src/mame/atari/tunhunt.h | 94 ------ src/mame/atari/tunhunt_v.cpp | 374 ---------------------- src/mame/atari/videopin.cpp | 279 ++++++++++++---- src/mame/atari/videopin.h | 90 ------ src/mame/atari/videopin_a.cpp | 14 +- src/mame/atari/videopin_a.h | 22 ++ src/mame/atari/videopin_v.cpp | 103 ------ src/mame/misc/cave.cpp | 4 + 17 files changed, 1397 insertions(+), 1465 deletions(-) delete mode 100644 src/mame/atari/toobin.h delete mode 100644 src/mame/atari/toobin_v.cpp delete mode 100644 src/mame/atari/triplhnt.h create mode 100644 src/mame/atari/triplhnt_a.h delete mode 100644 src/mame/atari/triplhnt_v.cpp delete mode 100644 src/mame/atari/tunhunt.h delete mode 100644 src/mame/atari/tunhunt_v.cpp delete mode 100644 src/mame/atari/videopin.h create mode 100644 src/mame/atari/videopin_a.h delete mode 100644 src/mame/atari/videopin_v.cpp diff --git a/src/mame/atari/toobin.cpp b/src/mame/atari/toobin.cpp index ad2731a2fbe..af75a9126c2 100644 --- a/src/mame/atari/toobin.cpp +++ b/src/mame/atari/toobin.cpp @@ -1,5 +1,6 @@ // license:BSD-3-Clause // copyright-holders:Aaron Giles + /*************************************************************************** Atari Toobin' hardware @@ -23,16 +24,330 @@ #include "emu.h" -#include "toobin.h" + +#include "atarijsa.h" +#include "atarimo.h" #include "cpu/m68000/m68010.h" #include "machine/eeprompar.h" #include "machine/watchdog.h" + +#include "emupal.h" +#include "screen.h" #include "speaker.h" - -static constexpr XTAL MASTER_CLOCK = 32_MHz_XTAL; +#include "tilemap.h" +namespace { + +class toobin_state : public driver_device +{ +public: + toobin_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_gfxdecode(*this, "gfxdecode"), + m_screen(*this, "screen"), + m_jsa(*this, "jsa"), + m_playfield_tilemap(*this, "playfield"), + m_alpha_tilemap(*this, "alpha"), + m_mob(*this, "mob"), + m_palette(*this, "palette"), + m_paletteram(*this, "paletteram"), + m_interrupt_scan(*this, "interrupt_scan"), + m_xscroll(*this, "xscroll"), + m_yscroll(*this, "yscroll") + { } + + void toobin(machine_config &config); + +protected: + virtual void machine_start() override; + virtual void video_start() override; + +private: + required_device m_maincpu; + required_device m_gfxdecode; + required_device m_screen; + required_device m_jsa; + required_device m_playfield_tilemap; + required_device m_alpha_tilemap; + required_device m_mob; + required_device m_palette; + + required_shared_ptr m_paletteram; + required_shared_ptr m_interrupt_scan; + required_shared_ptr m_xscroll; + required_shared_ptr m_yscroll; + + double m_brightness = 0; + bitmap_ind16 m_pfbitmap; + + emu_timer *m_scanline_interrupt_timer = nullptr; + + TIMER_CALLBACK_MEMBER(scanline_interrupt); + void scanline_int_ack_w(uint16_t data); + + void interrupt_scan_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + void paletteram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + void intensity_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + void xscroll_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + void yscroll_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + void slip_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + + TILE_GET_INFO_MEMBER(get_alpha_tile_info); + TILE_GET_INFO_MEMBER(get_playfield_tile_info); + + uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + + void main_map(address_map &map); + + static const atari_motion_objects_config s_mob_config; +}; + + +// video + +/************************************* + * + * Tilemap callbacks + * + *************************************/ + +TILE_GET_INFO_MEMBER(toobin_state::get_alpha_tile_info) +{ + uint16_t const data = m_alpha_tilemap->basemem_read(tile_index); + int const code = data & 0x3ff; + int const color = (data >> 12) & 0x0f; + tileinfo.set(2, code, color, (data >> 10) & 1); +} + + +TILE_GET_INFO_MEMBER(toobin_state::get_playfield_tile_info) +{ + uint32_t const data = m_playfield_tilemap->basemem_read(tile_index); + int const code = data & 0x3fff; + int const color = (data >> 16) & 0x0f; + tileinfo.set(0, code, color, TILE_FLIPYX(data >> 14)); + tileinfo.category = (data >> 20) & 3; +} + + + +/************************************* + * + * Video system start + * + *************************************/ + +const atari_motion_objects_config toobin_state::s_mob_config = +{ + 1, // index to which gfx system + 1, // number of motion object banks + 1, // are the entries linked? + 0, // are the entries split? + 0, // render in reverse order? + 1, // render in swapped X/Y order? + 0, // does the neighbor bit affect the next object? + 1024, // pixels per SLIP entry (0 for no-slip) + 0, // pixel offset for SLIPs + 0, // maximum number of links to visit/scanline (0=all) + + 0x100, // base palette entry + 0x100, // maximum number of colors + 0, // transparent pen index + + {{ 0,0,0x00ff,0 }}, // mask for the link + {{ 0,0x3fff,0,0 }}, // mask for the code index + {{ 0,0,0,0x000f }}, // mask for the color + {{ 0,0,0,0xffc0 }}, // mask for the X position + {{ 0x7fc0,0,0,0 }}, // mask for the Y position + {{ 0x0007,0,0,0 }}, // mask for the width, in tiles + {{ 0x0038,0,0,0 }}, // mask for the height, in tiles + {{ 0,0x4000,0,0 }}, // mask for the horizontal flip + {{ 0,0x8000,0,0 }}, // mask for the vertical flip + {{ 0 }}, // mask for the priority + {{ 0 }}, // mask for the neighbor + {{ 0x8000,0,0,0 }}, // mask for absolute coordinates + + {{ 0 }}, // mask for the special value + 0 // resulting value to indicate "special" +}; + +void toobin_state::video_start() +{ + // allocate a playfield bitmap for rendering + m_screen->register_screen_bitmap(m_pfbitmap); + + save_item(NAME(m_brightness)); +} + + + +/************************************* + * + * Palette RAM write handler + * + *************************************/ + +void toobin_state::paletteram_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + COMBINE_DATA(&m_paletteram[offset]); + uint16_t newword = m_paletteram[offset]; + + { + int red = (((newword >> 10) & 31) * 224) >> 5; + int green = (((newword >> 5) & 31) * 224) >> 5; + int blue = ((newword & 31) * 224) >> 5; + + if (red) red += 38; + if (green) green += 38; + if (blue) blue += 38; + + m_palette->set_pen_color(offset & 0x3ff, rgb_t(red, green, blue)); + if (!(newword & 0x8000)) + m_palette->set_pen_contrast(offset & 0x3ff, m_brightness); + else + m_palette->set_pen_contrast(offset & 0x3ff, 1.0); + } +} + + +void toobin_state::intensity_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + if (ACCESSING_BITS_0_7) + { + m_brightness = (double)(~data & 0x1f) / 31.0; + + for (int i = 0; i < 0x400; i++) + if (!BIT(m_paletteram[i], 15)) + m_palette->set_pen_contrast(i, m_brightness); + } +} + + + +/************************************* + * + * X/Y scroll handlers + * + *************************************/ + +void toobin_state::xscroll_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + uint16_t const oldscroll = *m_xscroll; + uint16_t newscroll = oldscroll; + COMBINE_DATA(&newscroll); + + // if anything has changed, force a partial update + if (newscroll != oldscroll) + m_screen->update_partial(m_screen->vpos()); + + // update the playfield scrolling - hscroll is clocked on the following scanline + m_playfield_tilemap->set_scrollx(0, newscroll >> 6); + m_mob->set_xscroll(newscroll >> 6); + + // update the data + *m_xscroll = newscroll; +} + + +void toobin_state::yscroll_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + uint16_t const oldscroll = *m_yscroll; + uint16_t newscroll = oldscroll; + COMBINE_DATA(&newscroll); + + // if anything has changed, force a partial update + if (newscroll != oldscroll) + m_screen->update_partial(m_screen->vpos()); + + // if bit 4 is zero, the scroll value is clocked in right away + m_playfield_tilemap->set_scrolly(0, newscroll >> 6); + m_mob->set_yscroll((newscroll >> 6) & 0x1ff); + + // update the data + *m_yscroll = newscroll; +} + + + +/************************************* + * + * X/Y scroll handlers + * + *************************************/ + +void toobin_state::slip_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + uint16_t const oldslip = m_mob->slipram(offset); + uint16_t newslip = oldslip; + COMBINE_DATA(&newslip); + + // if the SLIP is changing, force a partial update first + if (oldslip != newslip) + m_screen->update_partial(m_screen->vpos()); + + // update the data + m_mob->slipram(offset) = newslip; +} + + + +/************************************* + * + * Main refresh + * + *************************************/ + +uint32_t toobin_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + // start drawing + m_mob->draw_async(cliprect); + + // draw the playfield + bitmap_ind8 &priority_bitmap = screen.priority(); + priority_bitmap.fill(0, cliprect); + m_playfield_tilemap->draw(screen, m_pfbitmap, cliprect, 0, 0); + m_playfield_tilemap->draw(screen, m_pfbitmap, cliprect, 1, 1); + m_playfield_tilemap->draw(screen, m_pfbitmap, cliprect, 2, 2); + m_playfield_tilemap->draw(screen, m_pfbitmap, cliprect, 3, 3); + + // draw and merge the MO + bitmap_ind16 &mobitmap = m_mob->bitmap(); + pen_t const *const palette = m_palette->pens(); + for (int y = cliprect.top(); y <= cliprect.bottom(); y++) + { + uint32_t *const dest = &bitmap.pix(y); + uint16_t const *const mo = &mobitmap.pix(y); + uint16_t const *const pf = &m_pfbitmap.pix(y); + uint8_t const *const pri = &priority_bitmap.pix(y); + for (int x = cliprect.left(); x <= cliprect.right(); x++) + { + uint16_t pix = pf[x]; + if (mo[x] != 0xffff) + { + /* not verified: logic is all controlled in a PAL + + factors: LBPRI1-0, LBPIX3, ANPIX1-0, PFPIX3, PFPRI1-0, + (~LBPIX3 & ~LBPIX2 & ~LBPIX1 & ~LBPIX0) + */ + + // only draw if not high priority PF + if (!pri[x] || !(pix & 8)) + pix = mo[x]; + } + dest[x] = palette[pix]; + } + } + + // add the alpha on top + m_alpha_tilemap->draw(screen, bitmap, cliprect, 0, 0); + return 0; +} + + +// machine /************************************* * @@ -61,11 +376,11 @@ void toobin_state::machine_start() void toobin_state::interrupt_scan_w(offs_t offset, uint16_t data, uint16_t mem_mask) { - int oldword = m_interrupt_scan[offset]; + int const oldword = m_interrupt_scan[offset]; int newword = oldword; COMBINE_DATA(&newword); - /* if something changed, update the word in memory */ + // if something changed, update the word in memory if (oldword != newword) { m_interrupt_scan[offset] = newword; @@ -86,7 +401,7 @@ void toobin_state::scanline_int_ack_w(uint16_t data) * *************************************/ -/* full address map decoded from schematics */ +// full address map decoded from schematics void toobin_state::main_map(address_map &map) { map.global_mask(0xc7ffff); @@ -94,18 +409,18 @@ void toobin_state::main_map(address_map &map) map(0xc00000, 0xc07fff).ram().w(m_playfield_tilemap, FUNC(tilemap_device::write16)).share("playfield"); map(0xc08000, 0xc097ff).mirror(0x046000).ram().w(m_alpha_tilemap, FUNC(tilemap_device::write16)).share("alpha"); map(0xc09800, 0xc09fff).mirror(0x046000).ram().share("mob"); - map(0xc10000, 0xc107ff).mirror(0x047800).ram().w(FUNC(toobin_state::paletteram_w)).share("paletteram"); - map(0x826000, 0x826001).mirror(0x4500fe).nopr(); /* who knows? read at controls time */ + map(0xc10000, 0xc107ff).mirror(0x047800).ram().w(FUNC(toobin_state::paletteram_w)).share(m_paletteram); + map(0x826000, 0x826001).mirror(0x4500fe).nopr(); // who knows? read at controls time map(0x828000, 0x828001).mirror(0x4500fe).w("watchdog", FUNC(watchdog_timer_device::reset16_w)); map(0x828101, 0x828101).mirror(0x4500fe).w(m_jsa, FUNC(atari_jsa_i_device::main_command_w)); map(0x828300, 0x828301).mirror(0x45003e).w(FUNC(toobin_state::intensity_w)); - map(0x828340, 0x828341).mirror(0x45003e).w(FUNC(toobin_state::interrupt_scan_w)).share("interrupt_scan"); + map(0x828340, 0x828341).mirror(0x45003e).w(FUNC(toobin_state::interrupt_scan_w)).share(m_interrupt_scan); map(0x828380, 0x828381).mirror(0x45003e).ram().w(FUNC(toobin_state::slip_w)).share("mob:slip"); map(0x8283c0, 0x8283c1).mirror(0x45003e).w(FUNC(toobin_state::scanline_int_ack_w)); map(0x828400, 0x828401).mirror(0x4500fe).w(m_jsa, FUNC(atari_jsa_i_device::sound_reset_w)); map(0x828500, 0x828501).mirror(0x4500fe).w("eeprom", FUNC(eeprom_parallel_28xx_device::unlock_write16)); - map(0x828600, 0x828601).mirror(0x4500fe).w(FUNC(toobin_state::xscroll_w)).share("xscroll"); - map(0x828700, 0x828701).mirror(0x4500fe).w(FUNC(toobin_state::yscroll_w)).share("yscroll"); + map(0x828600, 0x828601).mirror(0x4500fe).w(FUNC(toobin_state::xscroll_w)).share(m_xscroll); + map(0x828700, 0x828701).mirror(0x4500fe).w(FUNC(toobin_state::yscroll_w)).share(m_yscroll); map(0x828800, 0x828801).mirror(0x4507fe).portr("FF8800"); map(0x829000, 0x829001).mirror(0x4507fe).portr("FF9000"); map(0x829801, 0x829801).mirror(0x4507fe).r(m_jsa, FUNC(atari_jsa_i_device::main_response_r)); @@ -205,8 +520,10 @@ GFXDECODE_END void toobin_state::toobin(machine_config &config) { - /* basic machine hardware */ - m68010_device &maincpu(M68010(config, m_maincpu, MASTER_CLOCK/4)); + static constexpr XTAL MASTER_CLOCK = 32_MHz_XTAL; + + // basic machine hardware + m68010_device &maincpu(M68010(config, m_maincpu, MASTER_CLOCK / 4)); maincpu.set_addrmap(AS_PROGRAM, &toobin_state::main_map); maincpu.disable_interrupt_mixer(); @@ -214,22 +531,22 @@ void toobin_state::toobin(machine_config &config) WATCHDOG_TIMER(config, "watchdog").set_vblank_count(m_screen, 8); - /* video hardware */ - TILEMAP(config, m_playfield_tilemap, m_gfxdecode, 4, 8,8, TILEMAP_SCAN_ROWS, 128,64).set_info_callback(FUNC(toobin_state::get_playfield_tile_info)); - TILEMAP(config, m_alpha_tilemap, m_gfxdecode, 2, 8,8, TILEMAP_SCAN_ROWS, 64,48, 0).set_info_callback(FUNC(toobin_state::get_alpha_tile_info)); + // video hardware + TILEMAP(config, m_playfield_tilemap, m_gfxdecode, 4, 8, 8, TILEMAP_SCAN_ROWS, 128, 64).set_info_callback(FUNC(toobin_state::get_playfield_tile_info)); + TILEMAP(config, m_alpha_tilemap, m_gfxdecode, 2, 8, 8, TILEMAP_SCAN_ROWS, 64, 48, 0).set_info_callback(FUNC(toobin_state::get_alpha_tile_info)); ATARI_MOTION_OBJECTS(config, m_mob, 0, m_screen, toobin_state::s_mob_config); m_mob->set_gfxdecode(m_gfxdecode); SCREEN(config, m_screen, SCREEN_TYPE_RASTER); m_screen->set_video_attributes(VIDEO_UPDATE_BEFORE_VBLANK); - m_screen->set_raw(MASTER_CLOCK/2, 640, 0, 512, 416, 0, 384); + m_screen->set_raw(MASTER_CLOCK / 2, 640, 0, 512, 416, 0, 384); m_screen->set_screen_update(FUNC(toobin_state::screen_update)); GFXDECODE(config, m_gfxdecode, m_palette, gfx_toobin); PALETTE(config, m_palette).set_entries(1024); - /* sound hardware */ + // sound hardware SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "rspeaker").front_right(); @@ -250,7 +567,7 @@ void toobin_state::toobin(machine_config &config) *************************************/ ROM_START( toobin ) - ROM_REGION( 0x80000, "maincpu", 0 ) /* 8*64k for 68000 code */ + ROM_REGION( 0x80000, "maincpu", 0 ) // 68000 code ROM_LOAD16_BYTE( "3133-1j.061", 0x000000, 0x010000, CRC(79a92d02) SHA1(72eebb96a3963f94558bb204e0afe08f2b4c1864) ) ROM_LOAD16_BYTE( "3137-1f.061", 0x000001, 0x010000, CRC(e389ef60) SHA1(24861fe5eb49de852987993a905fefe4dd43b204) ) ROM_LOAD16_BYTE( "3134-2j.061", 0x020000, 0x010000, CRC(3dbe9a48) SHA1(37fe2534fed5708a63995e53ea0cb1d2d23fc1b9) ) @@ -260,7 +577,7 @@ ROM_START( toobin ) ROM_LOAD16_BYTE( "1136-5j.061", 0x060000, 0x010000, CRC(5ae3eeac) SHA1(583b6c3f61e8ad4d98449205fedecf3e21ee993c) ) ROM_LOAD16_BYTE( "1140-5f.061", 0x060001, 0x010000, CRC(dacbbd94) SHA1(0e3a93f439ff9f3dd57ee13604be02e9c74c8eec) ) - ROM_REGION( 0x10000, "jsa:cpu", 0 ) /* 64k for 6502 code */ + ROM_REGION( 0x10000, "jsa:cpu", 0 ) // 6502 code ROM_LOAD( "1141-2k.061", 0x00000, 0x10000, CRC(c0dcce1a) SHA1(285c13f08020cf5827eca2afcc2fa8a3a0a073e0) ) ROM_REGION( 0x080000, "gfx1", 0 ) @@ -305,7 +622,7 @@ ROM_END ROM_START( toobine ) - ROM_REGION( 0x80000, "maincpu", 0 ) /* 8*64k for 68000 code */ + ROM_REGION( 0x80000, "maincpu", 0 ) // 68000 code ROM_LOAD16_BYTE( "3733-1j.061", 0x000000, 0x010000, CRC(286c7fad) SHA1(1f06168327bdc356f1bc4cf9a951f914932c491a) ) ROM_LOAD16_BYTE( "3737-1f.061", 0x000001, 0x010000, CRC(965c161d) SHA1(30d959a945cb7dc7f00ad4ca9db027a377024030) ) ROM_LOAD16_BYTE( "3134-2j.061", 0x020000, 0x010000, CRC(3dbe9a48) SHA1(37fe2534fed5708a63995e53ea0cb1d2d23fc1b9) ) @@ -315,7 +632,7 @@ ROM_START( toobine ) ROM_LOAD16_BYTE( "1136-5j.061", 0x060000, 0x010000, CRC(5ae3eeac) SHA1(583b6c3f61e8ad4d98449205fedecf3e21ee993c) ) ROM_LOAD16_BYTE( "1140-5f.061", 0x060001, 0x010000, CRC(dacbbd94) SHA1(0e3a93f439ff9f3dd57ee13604be02e9c74c8eec) ) - ROM_REGION( 0x10000, "jsa:cpu", 0 ) /* 64k for 6502 code */ + ROM_REGION( 0x10000, "jsa:cpu", 0 ) // 6502 code ROM_LOAD( "1141-2k.061", 0x00000, 0x10000, CRC(c0dcce1a) SHA1(285c13f08020cf5827eca2afcc2fa8a3a0a073e0) ) ROM_REGION( 0x080000, "gfx1", 0 ) @@ -360,7 +677,7 @@ ROM_END ROM_START( toobing ) - ROM_REGION( 0x80000, "maincpu", 0 ) /* 8*64k for 68000 code */ + ROM_REGION( 0x80000, "maincpu", 0 ) // 68000 code ROM_LOAD16_BYTE( "3233-1j.061", 0x000000, 0x010000, CRC(b04eb760) SHA1(760525b4f72fad47cfc457e14db70ade30a9ddac) ) ROM_LOAD16_BYTE( "3237-1f.061", 0x000001, 0x010000, CRC(4e41a470) SHA1(3a4c9b0d93cf4cff80978c0568bb9ef9eeb878dd) ) ROM_LOAD16_BYTE( "3234-2j.061", 0x020000, 0x010000, CRC(8c60f1b4) SHA1(0ff3f4fede83410d73027b6e7445e83044e4b21e) ) @@ -370,7 +687,7 @@ ROM_START( toobing ) ROM_LOAD16_BYTE( "1136-5j.061", 0x060000, 0x010000, CRC(5ae3eeac) SHA1(583b6c3f61e8ad4d98449205fedecf3e21ee993c) ) ROM_LOAD16_BYTE( "1140-5f.061", 0x060001, 0x010000, CRC(dacbbd94) SHA1(0e3a93f439ff9f3dd57ee13604be02e9c74c8eec) ) - ROM_REGION( 0x10000, "jsa:cpu", 0 ) /* 64k for 6502 code */ + ROM_REGION( 0x10000, "jsa:cpu", 0 ) // 6502 code ROM_LOAD( "1141-2k.061", 0x00000, 0x10000, CRC(c0dcce1a) SHA1(285c13f08020cf5827eca2afcc2fa8a3a0a073e0) ) ROM_REGION( 0x080000, "gfx1", 0 ) @@ -415,7 +732,7 @@ ROM_END ROM_START( toobin2e ) - ROM_REGION( 0x80000, "maincpu", 0 ) /* 8*64k for 68000 code */ + ROM_REGION( 0x80000, "maincpu", 0 ) // 68000 code ROM_LOAD16_BYTE( "2733-1j.061", 0x000000, 0x010000, CRC(a6334cf7) SHA1(39e540619c24af65bda44160a5bdaebf3600b64b) ) ROM_LOAD16_BYTE( "2737-1f.061", 0x000001, 0x010000, CRC(9a52dd20) SHA1(a370ae3e4c7af55ea61b57a203a900f2be3ce6b9) ) ROM_LOAD16_BYTE( "2134-2j.061", 0x020000, 0x010000, CRC(2b8164c8) SHA1(aeeaff9df9fda23b295b59efadf52160f084d256) ) @@ -425,7 +742,7 @@ ROM_START( toobin2e ) ROM_LOAD16_BYTE( "1136-5j.061", 0x060000, 0x010000, CRC(5ae3eeac) SHA1(583b6c3f61e8ad4d98449205fedecf3e21ee993c) ) ROM_LOAD16_BYTE( "1140-5f.061", 0x060001, 0x010000, CRC(dacbbd94) SHA1(0e3a93f439ff9f3dd57ee13604be02e9c74c8eec) ) - ROM_REGION( 0x10000, "jsa:cpu", 0 ) /* 64k for 6502 code */ + ROM_REGION( 0x10000, "jsa:cpu", 0 ) // 6502 code ROM_LOAD( "1141-2k.061", 0x00000, 0x10000, CRC(c0dcce1a) SHA1(285c13f08020cf5827eca2afcc2fa8a3a0a073e0) ) ROM_REGION( 0x080000, "gfx1", 0 ) @@ -470,7 +787,7 @@ ROM_END ROM_START( toobin2 ) - ROM_REGION( 0x80000, "maincpu", 0 ) /* 8*64k for 68000 code */ + ROM_REGION( 0x80000, "maincpu", 0 ) // 68000 code ROM_LOAD16_BYTE( "2133-1j.061", 0x000000, 0x010000, CRC(2c3382e4) SHA1(39919e9b5b586b630e0581adabfe25d83b2bfaef) ) ROM_LOAD16_BYTE( "2137-1f.061", 0x000001, 0x010000, CRC(891c74b1) SHA1(2f39d0e4934ccf48bb5fc0737f34fc5a65cfd903) ) ROM_LOAD16_BYTE( "2134-2j.061", 0x020000, 0x010000, CRC(2b8164c8) SHA1(aeeaff9df9fda23b295b59efadf52160f084d256) ) @@ -480,7 +797,7 @@ ROM_START( toobin2 ) ROM_LOAD16_BYTE( "1136-5j.061", 0x060000, 0x010000, CRC(5ae3eeac) SHA1(583b6c3f61e8ad4d98449205fedecf3e21ee993c) ) ROM_LOAD16_BYTE( "1140-5f.061", 0x060001, 0x010000, CRC(dacbbd94) SHA1(0e3a93f439ff9f3dd57ee13604be02e9c74c8eec) ) - ROM_REGION( 0x10000, "jsa:cpu", 0 ) /* 64k for 6502 code */ + ROM_REGION( 0x10000, "jsa:cpu", 0 ) // 6502 code ROM_LOAD( "1141-2k.061", 0x00000, 0x10000, CRC(c0dcce1a) SHA1(285c13f08020cf5827eca2afcc2fa8a3a0a073e0) ) ROM_REGION( 0x080000, "gfx1", 0 ) @@ -525,7 +842,7 @@ ROM_END ROM_START( toobin1 ) - ROM_REGION( 0x80000, "maincpu", 0 ) /* 8*64k for 68000 code */ + ROM_REGION( 0x80000, "maincpu", 0 ) // 68000 code ROM_LOAD16_BYTE( "1133-1j.061", 0x000000, 0x010000, CRC(caeb5d1b) SHA1(8036871a04b5206fd383ac0fd9a9d3218128088b) ) ROM_LOAD16_BYTE( "1137-1f.061", 0x000001, 0x010000, CRC(9713d9d3) SHA1(55791150312de201bdd330bfd4cbb132cb3959e4) ) ROM_LOAD16_BYTE( "1134-2j.061", 0x020000, 0x010000, CRC(119f5d7b) SHA1(edd0b1ab29bb9c15c3b80037635c3b6d5fb434dc) ) @@ -535,7 +852,7 @@ ROM_START( toobin1 ) ROM_LOAD16_BYTE( "1136-5j.061", 0x060000, 0x010000, CRC(5ae3eeac) SHA1(583b6c3f61e8ad4d98449205fedecf3e21ee993c) ) ROM_LOAD16_BYTE( "1140-5f.061", 0x060001, 0x010000, CRC(dacbbd94) SHA1(0e3a93f439ff9f3dd57ee13604be02e9c74c8eec) ) - ROM_REGION( 0x10000, "jsa:cpu", 0 ) /* 64k for 6502 code */ + ROM_REGION( 0x10000, "jsa:cpu", 0 ) // 6502 code ROM_LOAD( "1141-2k.061", 0x00000, 0x10000, CRC(c0dcce1a) SHA1(285c13f08020cf5827eca2afcc2fa8a3a0a073e0) ) ROM_REGION( 0x080000, "gfx1", 0 ) @@ -578,6 +895,8 @@ ROM_START( toobin1 ) ROM_LOAD( "1142-20h.061", 0x000000, 0x004000, CRC(a6ab551f) SHA1(6a11e16f3965416c81737efcb81e751484ba5ace) ) ROM_END +} // anonymous namespace + /************************************* * @@ -585,9 +904,9 @@ ROM_END * *************************************/ -GAME( 1988, toobin, 0, toobin, toobin, toobin_state, empty_init, ROT270, "Atari Games", "Toobin' (rev 3)", MACHINE_SUPPORTS_SAVE ) +GAME( 1988, toobin, 0, toobin, toobin, toobin_state, empty_init, ROT270, "Atari Games", "Toobin' (rev 3)", MACHINE_SUPPORTS_SAVE ) GAME( 1988, toobine, toobin, toobin, toobin, toobin_state, empty_init, ROT270, "Atari Games", "Toobin' (Europe, rev 3)", MACHINE_SUPPORTS_SAVE ) GAME( 1988, toobing, toobin, toobin, toobin, toobin_state, empty_init, ROT270, "Atari Games", "Toobin' (German, rev 3)", MACHINE_SUPPORTS_SAVE ) -GAME( 1988, toobin2, toobin, toobin, toobin, toobin_state, empty_init, ROT270, "Atari Games", "Toobin' (rev 2)", MACHINE_SUPPORTS_SAVE ) +GAME( 1988, toobin2, toobin, toobin, toobin, toobin_state, empty_init, ROT270, "Atari Games", "Toobin' (rev 2)", MACHINE_SUPPORTS_SAVE ) GAME( 1988, toobin2e, toobin, toobin, toobin, toobin_state, empty_init, ROT270, "Atari Games", "Toobin' (Europe, rev 2)", MACHINE_SUPPORTS_SAVE ) -GAME( 1988, toobin1, toobin, toobin, toobin, toobin_state, empty_init, ROT270, "Atari Games", "Toobin' (rev 1)", MACHINE_SUPPORTS_SAVE ) +GAME( 1988, toobin1, toobin, toobin, toobin, toobin_state, empty_init, ROT270, "Atari Games", "Toobin' (rev 1)", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/atari/toobin.h b/src/mame/atari/toobin.h deleted file mode 100644 index ab6ed731a7c..00000000000 --- a/src/mame/atari/toobin.h +++ /dev/null @@ -1,83 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -/************************************************************************* - - Atari Toobin' hardware - -*************************************************************************/ -#ifndef MAME_ATARI_TOOBIN_H -#define MAME_ATARI_TOOBIN_H - -#pragma once - -#include "atarijsa.h" -#include "atarimo.h" -#include "emupal.h" -#include "screen.h" -#include "tilemap.h" - -class toobin_state : public driver_device -{ -public: - toobin_state(const machine_config &mconfig, device_type type, const char *tag) : - driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_gfxdecode(*this, "gfxdecode"), - m_screen(*this, "screen"), - m_jsa(*this, "jsa"), - m_playfield_tilemap(*this, "playfield"), - m_alpha_tilemap(*this, "alpha"), - m_mob(*this, "mob"), - m_palette(*this, "palette"), - m_paletteram(*this, "paletteram"), - m_interrupt_scan(*this, "interrupt_scan"), - m_xscroll(*this, "xscroll"), - m_yscroll(*this, "yscroll") - { } - - void toobin(machine_config &config); - -private: - virtual void machine_start() override; - virtual void video_start() override; - - TIMER_CALLBACK_MEMBER(scanline_interrupt); - void scanline_int_ack_w(uint16_t data); - - void interrupt_scan_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - void paletteram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - void intensity_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - void xscroll_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - void yscroll_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - void slip_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); - - TILE_GET_INFO_MEMBER(get_alpha_tile_info); - TILE_GET_INFO_MEMBER(get_playfield_tile_info); - - uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - - void main_map(address_map &map); - - required_device m_maincpu; - required_device m_gfxdecode; - required_device m_screen; - required_device m_jsa; - required_device m_playfield_tilemap; - required_device m_alpha_tilemap; - required_device m_mob; - required_device m_palette; - - required_shared_ptr m_paletteram; - required_shared_ptr m_interrupt_scan; - required_shared_ptr m_xscroll; - required_shared_ptr m_yscroll; - - double m_brightness = 0; - bitmap_ind16 m_pfbitmap; - - emu_timer *m_scanline_interrupt_timer = nullptr; - - static const atari_motion_objects_config s_mob_config; -}; - -#endif // MAME_ATARI_TOOBIN_H diff --git a/src/mame/atari/toobin_v.cpp b/src/mame/atari/toobin_v.cpp deleted file mode 100644 index b767bc87bed..00000000000 --- a/src/mame/atari/toobin_v.cpp +++ /dev/null @@ -1,250 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -/*************************************************************************** - - Atari Toobin' hardware - -****************************************************************************/ - -#include "emu.h" -#include "toobin.h" - - - -/************************************* - * - * Tilemap callbacks - * - *************************************/ - -TILE_GET_INFO_MEMBER(toobin_state::get_alpha_tile_info) -{ - uint16_t data = m_alpha_tilemap->basemem_read(tile_index); - int code = data & 0x3ff; - int color = (data >> 12) & 0x0f; - tileinfo.set(2, code, color, (data >> 10) & 1); -} - - -TILE_GET_INFO_MEMBER(toobin_state::get_playfield_tile_info) -{ - uint32_t data = m_playfield_tilemap->basemem_read(tile_index); - int code = data & 0x3fff; - int color = (data >> 16) & 0x0f; - tileinfo.set(0, code, color, TILE_FLIPYX(data >> 14)); - tileinfo.category = (data >> 20) & 3; -} - - - -/************************************* - * - * Video system start - * - *************************************/ - -const atari_motion_objects_config toobin_state::s_mob_config = -{ - 1, /* index to which gfx system */ - 1, /* number of motion object banks */ - 1, /* are the entries linked? */ - 0, /* are the entries split? */ - 0, /* render in reverse order? */ - 1, /* render in swapped X/Y order? */ - 0, /* does the neighbor bit affect the next object? */ - 1024, /* pixels per SLIP entry (0 for no-slip) */ - 0, /* pixel offset for SLIPs */ - 0, /* maximum number of links to visit/scanline (0=all) */ - - 0x100, /* base palette entry */ - 0x100, /* maximum number of colors */ - 0, /* transparent pen index */ - - {{ 0,0,0x00ff,0 }}, /* mask for the link */ - {{ 0,0x3fff,0,0 }}, /* mask for the code index */ - {{ 0,0,0,0x000f }}, /* mask for the color */ - {{ 0,0,0,0xffc0 }}, /* mask for the X position */ - {{ 0x7fc0,0,0,0 }}, /* mask for the Y position */ - {{ 0x0007,0,0,0 }}, /* mask for the width, in tiles*/ - {{ 0x0038,0,0,0 }}, /* mask for the height, in tiles */ - {{ 0,0x4000,0,0 }}, /* mask for the horizontal flip */ - {{ 0,0x8000,0,0 }}, /* mask for the vertical flip */ - {{ 0 }}, /* mask for the priority */ - {{ 0 }}, /* mask for the neighbor */ - {{ 0x8000,0,0,0 }}, /* mask for absolute coordinates */ - - {{ 0 }}, /* mask for the special value */ - 0 /* resulting value to indicate "special" */ -}; - -void toobin_state::video_start() -{ - /* allocate a playfield bitmap for rendering */ - m_screen->register_screen_bitmap(m_pfbitmap); - - save_item(NAME(m_brightness)); -} - - - -/************************************* - * - * Palette RAM write handler - * - *************************************/ - -void toobin_state::paletteram_w(offs_t offset, uint16_t data, uint16_t mem_mask) -{ - COMBINE_DATA(&m_paletteram[offset]); - uint16_t newword = m_paletteram[offset]; - - { - int red = (((newword >> 10) & 31) * 224) >> 5; - int green = (((newword >> 5) & 31) * 224) >> 5; - int blue = (((newword ) & 31) * 224) >> 5; - - if (red) red += 38; - if (green) green += 38; - if (blue) blue += 38; - - m_palette->set_pen_color(offset & 0x3ff, rgb_t(red, green, blue)); - if (!(newword & 0x8000)) - m_palette->set_pen_contrast(offset & 0x3ff, m_brightness); - else - m_palette->set_pen_contrast(offset & 0x3ff, 1.0); - } -} - - -void toobin_state::intensity_w(offs_t offset, uint16_t data, uint16_t mem_mask) -{ - if (ACCESSING_BITS_0_7) - { - m_brightness = (double)(~data & 0x1f) / 31.0; - - for (int i = 0; i < 0x400; i++) - if (!BIT(m_paletteram[i], 15)) - m_palette->set_pen_contrast(i, m_brightness); - } -} - - - -/************************************* - * - * X/Y scroll handlers - * - *************************************/ - -void toobin_state::xscroll_w(offs_t offset, uint16_t data, uint16_t mem_mask) -{ - uint16_t oldscroll = *m_xscroll; - uint16_t newscroll = oldscroll; - COMBINE_DATA(&newscroll); - - /* if anything has changed, force a partial update */ - if (newscroll != oldscroll) - m_screen->update_partial(m_screen->vpos()); - - /* update the playfield scrolling - hscroll is clocked on the following scanline */ - m_playfield_tilemap->set_scrollx(0, newscroll >> 6); - m_mob->set_xscroll(newscroll >> 6); - - /* update the data */ - *m_xscroll = newscroll; -} - - -void toobin_state::yscroll_w(offs_t offset, uint16_t data, uint16_t mem_mask) -{ - uint16_t oldscroll = *m_yscroll; - uint16_t newscroll = oldscroll; - COMBINE_DATA(&newscroll); - - /* if anything has changed, force a partial update */ - if (newscroll != oldscroll) - m_screen->update_partial(m_screen->vpos()); - - /* if bit 4 is zero, the scroll value is clocked in right away */ - m_playfield_tilemap->set_scrolly(0, newscroll >> 6); - m_mob->set_yscroll((newscroll >> 6) & 0x1ff); - - /* update the data */ - *m_yscroll = newscroll; -} - - - -/************************************* - * - * X/Y scroll handlers - * - *************************************/ - -void toobin_state::slip_w(offs_t offset, uint16_t data, uint16_t mem_mask) -{ - uint16_t oldslip = m_mob->slipram(offset); - uint16_t newslip = oldslip; - COMBINE_DATA(&newslip); - - /* if the SLIP is changing, force a partial update first */ - if (oldslip != newslip) - m_screen->update_partial(m_screen->vpos()); - - /* update the data */ - m_mob->slipram(offset) = newslip; -} - - - -/************************************* - * - * Main refresh - * - *************************************/ - -uint32_t toobin_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) -{ - // start drawing - m_mob->draw_async(cliprect); - - /* draw the playfield */ - bitmap_ind8 &priority_bitmap = screen.priority(); - priority_bitmap.fill(0, cliprect); - m_playfield_tilemap->draw(screen, m_pfbitmap, cliprect, 0, 0); - m_playfield_tilemap->draw(screen, m_pfbitmap, cliprect, 1, 1); - m_playfield_tilemap->draw(screen, m_pfbitmap, cliprect, 2, 2); - m_playfield_tilemap->draw(screen, m_pfbitmap, cliprect, 3, 3); - - /* draw and merge the MO */ - bitmap_ind16 &mobitmap = m_mob->bitmap(); - pen_t const *const palette = m_palette->pens(); - for (int y = cliprect.top(); y <= cliprect.bottom(); y++) - { - uint32_t *const dest = &bitmap.pix(y); - uint16_t const *const mo = &mobitmap.pix(y); - uint16_t const *const pf = &m_pfbitmap.pix(y); - uint8_t const *const pri = &priority_bitmap.pix(y); - for (int x = cliprect.left(); x <= cliprect.right(); x++) - { - uint16_t pix = pf[x]; - if (mo[x] != 0xffff) - { - /* not verified: logic is all controlled in a PAL - - factors: LBPRI1-0, LBPIX3, ANPIX1-0, PFPIX3, PFPRI1-0, - (~LBPIX3 & ~LBPIX2 & ~LBPIX1 & ~LBPIX0) - */ - - /* only draw if not high priority PF */ - if (!pri[x] || !(pix & 8)) - pix = mo[x]; - } - dest[x] = palette[pix]; - } - } - - /* add the alpha on top */ - m_alpha_tilemap->draw(screen, bitmap, cliprect, 0, 0); - return 0; -} diff --git a/src/mame/atari/triplhnt.cpp b/src/mame/atari/triplhnt.cpp index 5833214e761..83cd0aa5fd0 100644 --- a/src/mame/atari/triplhnt.cpp +++ b/src/mame/atari/triplhnt.cpp @@ -1,5 +1,6 @@ // license:BSD-3-Clause // copyright-holders:Stefan Jokisch + /*************************************************************************** Atari Triple Hunt Driver @@ -9,12 +10,213 @@ Atari Triple Hunt Driver ***************************************************************************/ #include "emu.h" -#include "triplhnt.h" + +#include "triplhnt_a.h" + #include "cpu/m6800/m6800.h" +#include "machine/74259.h" #include "machine/nvram.h" +#include "machine/watchdog.h" +#include "sound/discrete.h" +#include "sound/samples.h" + +#include "emupal.h" +#include "screen.h" #include "speaker.h" +#include "tilemap.h" +namespace { + +class triplhnt_state : public driver_device +{ +public: + triplhnt_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_latch(*this, "latch"), + m_watchdog(*this, "watchdog"), + m_discrete(*this, "discrete"), + m_samples(*this, "samples"), + m_gfxdecode(*this, "gfxdecode"), + m_screen(*this, "screen"), + m_palette(*this, "palette"), + m_playfield_ram(*this, "playfield_ram"), + m_vpos_ram(*this, "vpos_ram"), + m_hpos_ram(*this, "hpos_ram"), + m_orga_ram(*this, "orga_ram"), + m_code_ram(*this, "code_ram"), + m_0c09(*this, "0C09"), + m_0c0b(*this, "0C0B"), + m_vblank(*this, "VBLANK"), + m_stick(*this, "STICK%c", 'X'), + m_lamp(*this, "lamp0") + { } + + void triplhnt(machine_config &config); + + void init_triplhnt(); + +protected: + virtual void machine_start() override; + virtual void video_start() override; + +private: + required_device m_maincpu; + required_device m_latch; + required_device m_watchdog; + required_device m_discrete; + required_device m_samples; + required_device m_gfxdecode; + required_device m_screen; + required_device m_palette; + + required_shared_ptr m_playfield_ram; + required_shared_ptr m_vpos_ram; + required_shared_ptr m_hpos_ram; + required_shared_ptr m_orga_ram; + required_shared_ptr m_code_ram; + required_ioport m_0c09; + required_ioport m_0c0b; + required_ioport m_vblank; + required_ioport_array<2> m_stick; + output_finder<> m_lamp; + + uint8_t m_cmos[16]{}; + uint8_t m_da_latch = 0; + uint8_t m_cmos_latch = 0; + uint8_t m_hit_code = 0; + uint8_t m_sprite_zoom = 0; + uint8_t m_sprite_bank = 0; + bitmap_ind16 m_helper; + emu_timer *m_hit_timer = nullptr; + tilemap_t* m_bg_tilemap = nullptr; + + DECLARE_WRITE_LINE_MEMBER(coin_lockout_w); + DECLARE_WRITE_LINE_MEMBER(tape_control_w); + + uint8_t cmos_r(offs_t offset); + uint8_t input_port_4_r(); + uint8_t misc_r(offs_t offset); + uint8_t da_latch_r(offs_t offset); + + TILE_GET_INFO_MEMBER(get_tile_info); + void palette(palette_device &palette) const; + + uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect); + TIMER_CALLBACK_MEMBER(set_collision); + + void program_map(address_map &map); +}; + + +// video + +TILE_GET_INFO_MEMBER(triplhnt_state::get_tile_info) +{ + int const code = m_playfield_ram[tile_index] & 0x3f; + + tileinfo.set(2, code, code == 0x3f ? 1 : 0, 0); +} + + +void triplhnt_state::video_start() +{ + m_screen->register_screen_bitmap(m_helper); + + m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(triplhnt_state::get_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 16, 16); + + m_hit_timer = timer_alloc(FUNC(triplhnt_state::set_collision), this); + + save_item(NAME(m_cmos)); + save_item(NAME(m_da_latch)); + save_item(NAME(m_cmos_latch)); + save_item(NAME(m_hit_code)); + save_item(NAME(m_sprite_zoom)); + save_item(NAME(m_sprite_bank)); +} + + +void triplhnt_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + int hit_line = 999; + int hit_code = 999; + + for (int i = 0; i < 16; i++) + { + rectangle rect; + + int const j = (m_orga_ram[i] & 15) ^ 15; + + // software sorts sprites by x and stores order in orga RAM + + int hpos = m_hpos_ram[j] ^ 255; + int vpos = m_vpos_ram[j] ^ 255; + int code = m_code_ram[j] ^ 255; + + if (hpos == 255) + continue; + + // sprite placement might be wrong + + if (m_sprite_zoom) + { + rect.set(hpos - 16, hpos - 16 + 63, 196 - vpos, 196 - vpos + 63); + } + else + { + rect.set(hpos - 16, hpos - 16 + 31, 224 - vpos, 224 - vpos + 31); + } + + // render sprite to auxiliary bitmap + + m_gfxdecode->gfx(m_sprite_zoom)->opaque(m_helper, cliprect, + 2 * code + m_sprite_bank, 0, code & 8, 0, + rect.left(), rect.top()); + + rect &= cliprect; + + // check for collisions and copy sprite + for (int x = rect.left(); x <= rect.right(); x++) + { + for (int y = rect.top(); y <= rect.bottom(); y++) + { + pen_t const a = m_helper.pix(y, x); + pen_t const b = bitmap.pix(y, x); + + if (a == 2 && b == 7) + { + hit_code = j; + hit_line = y; + } + + if (a != 1) + bitmap.pix(y, x) = a; + } + } + } + + if (hit_line != 999 && hit_code != 999) + m_hit_timer->adjust(m_screen->time_until_pos(hit_line), hit_code); +} + + +uint32_t triplhnt_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + m_bg_tilemap->mark_all_dirty(); + + m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0); + + draw_sprites(bitmap, cliprect); + + m_discrete->write(TRIPLHNT_BEAR_ROAR_DATA, m_playfield_ram[0xfa] & 15); + m_discrete->write(TRIPLHNT_SHOT_DATA, m_playfield_ram[0xfc] & 15); + return 0; +} + + +// machine void triplhnt_state::init_triplhnt() { @@ -39,16 +241,16 @@ WRITE_LINE_MEMBER(triplhnt_state::coin_lockout_w) WRITE_LINE_MEMBER(triplhnt_state::tape_control_w) { - bool is_witch_hunt = ioport("0C09")->read() == 0x40; - bool bit = !state; + bool const is_witch_hunt = m_0c09->read() == 0x40; + bool const bit = !state; - /* if we're not playing the sample yet, start it */ + // if we're not playing the sample yet, start it if (!m_samples->playing(0)) m_samples->start(0, 0, true); if (!m_samples->playing(1)) m_samples->start(1, 1, true); - /* bit 6 turns cassette on/off */ + // bit 6 turns cassette on/off m_samples->pause(0, is_witch_hunt || bit); m_samples->pause(1, !is_witch_hunt || bit); } @@ -65,25 +267,25 @@ uint8_t triplhnt_state::cmos_r(offs_t offset) uint8_t triplhnt_state::input_port_4_r() { m_watchdog->watchdog_reset(); - return ioport("0C0B")->read(); + return m_0c0b->read(); } uint8_t triplhnt_state::misc_r(offs_t offset) { m_latch->write_a0(offset); - return ioport("VBLANK")->read() | m_hit_code; + return m_vblank->read() | m_hit_code; } uint8_t triplhnt_state::da_latch_r(offs_t offset) { - int cross_x = ioport("STICKX")->read(); - int cross_y = ioport("STICKY")->read(); + int const cross_x = m_stick[0]->read(); + int const cross_y = m_stick[1]->read(); m_da_latch = offset; - /* the following is a slight simplification */ + // the following is a slight simplification return (offset & 1) ? cross_x : cross_y; } @@ -97,15 +299,15 @@ void triplhnt_state::machine_start() } -void triplhnt_state::triplhnt_map(address_map &map) +void triplhnt_state::program_map(address_map &map) { map.global_mask(0x7fff); map(0x0000, 0x00ff).ram().mirror(0x300); - map(0x0400, 0x04ff).writeonly().share("playfield_ram"); - map(0x0800, 0x080f).writeonly().share("vpos_ram"); - map(0x0810, 0x081f).writeonly().share("hpos_ram"); - map(0x0820, 0x082f).writeonly().share("orga_ram"); - map(0x0830, 0x083f).writeonly().share("code_ram"); + map(0x0400, 0x04ff).writeonly().share(m_playfield_ram); + map(0x0800, 0x080f).writeonly().share(m_vpos_ram); + map(0x0810, 0x081f).writeonly().share(m_hpos_ram); + map(0x0820, 0x082f).writeonly().share(m_orga_ram); + map(0x0830, 0x083f).writeonly().share(m_code_ram); map(0x0c00, 0x0c00).portr("0C00"); map(0x0c08, 0x0c08).portr("0C08"); map(0x0c09, 0x0c09).portr("0C09"); @@ -116,44 +318,44 @@ void triplhnt_state::triplhnt_map(address_map &map) map(0x0c30, 0x0c3f).r(FUNC(triplhnt_state::misc_r)).w(m_latch, FUNC(f9334_device::write_a0)); map(0x0c40, 0x0c40).portr("0C40"); map(0x0c48, 0x0c48).portr("0C48"); - map(0x7000, 0x7fff).rom(); /* program */ + map(0x7000, 0x7fff).rom(); } static INPUT_PORTS_START( triplhnt ) - PORT_START("0C00") /* 0C00 */ + PORT_START("0C00") PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START1 ) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_COIN1 ) - PORT_START("0C08") /* 0C08 */ + PORT_START("0C08") PORT_DIPNAME( 0xc0, 0x00, "Play Time" ) PORT_DIPSETTING( 0x00, "32 seconds / 16 raccoons" ) PORT_DIPSETTING( 0x40, "64 seconds / 32 raccoons" ) PORT_DIPSETTING( 0x80, "96 seconds / 48 raccoons" ) PORT_DIPSETTING( 0xc0, "128 seconds / 64 raccoons" ) - PORT_START("0C09") /* 0C09 */ + PORT_START("0C09") PORT_DIPNAME( 0xc0, 0x40, "Game Select" ) PORT_DIPSETTING( 0x00, "Hit the Bear" ) PORT_DIPSETTING( 0x40, "Witch Hunt" ) PORT_DIPSETTING( 0xc0, "Raccoon Hunt" ) - PORT_START("0C0A") /* 0C0A */ + PORT_START("0C0A") PORT_DIPNAME( 0xc0, 0x00, DEF_STR( Coinage )) PORT_DIPSETTING( 0x40, DEF_STR( 2C_1C )) PORT_DIPSETTING( 0x00, DEF_STR( 1C_1C )) PORT_DIPSETTING( 0x80, DEF_STR( 1C_2C )) - PORT_START("0C0B") /* 0C0B */ + PORT_START("0C0B") PORT_DIPNAME( 0x80, 0x00, "Extended Play" ) PORT_DIPSETTING( 0x80, DEF_STR( Off )) PORT_DIPSETTING( 0x00, DEF_STR( On )) - PORT_START("0C40") /* 0C40 */ + PORT_START("0C40") PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_TILT ) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_COIN2 ) - PORT_START("0C48") /* 0C48 */ + PORT_START("0C48") // default to service enabled to make users calibrate gun // PORT_SERVICE( 0x40, IP_ACTIVE_LOW ) PORT_DIPNAME( 0x40, 0x00, DEF_STR( Service_Mode )) PORT_TOGGLE PORT_CODE(KEYCODE_F2) @@ -170,31 +372,31 @@ static INPUT_PORTS_START( triplhnt ) PORT_START("STICKY") PORT_BIT( 0xfc, 0x78, IPT_AD_STICK_Y ) PORT_MINMAX(0x00,0xec) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(25) PORT_KEYDELTA(15) - PORT_START("BEAR") /* 10 */ + PORT_START("BEAR") // 10 PORT_ADJUSTER( 35, "Bear Roar Frequency" ) INPUT_PORTS_END static const gfx_layout triplhnt_small_sprite_layout = { - 32, 32, /* width, height */ - 16, /* total */ - 2, /* planes */ - /* plane offsets */ + 32, 32, // width, height + 16, // total + 2, // planes + // plane offsets { 0x0000, 0x4000 }, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, { - 0x000, 0x020, 0x040, 0x060, 0x080, 0x0A0, 0x0C0, 0x0E0, - 0x100, 0x120, 0x140, 0x160, 0x180, 0x1A0, 0x1C0, 0x1E0, - 0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0, - 0x300, 0x320, 0x340, 0x360, 0x380, 0x3A0, 0x3C0, 0x3E0 + 0x000, 0x020, 0x040, 0x060, 0x080, 0x0a0, 0x0c0, 0x0e0, + 0x100, 0x120, 0x140, 0x160, 0x180, 0x1a0, 0x1c0, 0x1e0, + 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, + 0x300, 0x320, 0x340, 0x360, 0x380, 0x3a0, 0x3c0, 0x3e0 }, - 0x400 /* increment */ + 0x400 // increment }; @@ -202,31 +404,31 @@ static const uint32_t triplhnt_large_sprite_layout_xoffset[64] = { 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, - 0x08, 0x08, 0x09, 0x09, 0x0A, 0x0A, 0x0B, 0x0B, - 0x0C, 0x0C, 0x0D, 0x0D, 0x0E, 0x0E, 0x0F, 0x0F, + 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, + 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, 0x13, 0x14, 0x14, 0x15, 0x15, 0x16, 0x16, 0x17, 0x17, - 0x18, 0x18, 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B, - 0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F + 0x18, 0x18, 0x19, 0x19, 0x1a, 0x1a, 0x1b, 0x1b, + 0x1c, 0x1c, 0x1d, 0x1d, 0x1e, 0x1e, 0x1f, 0x1f }; static const uint32_t triplhnt_large_sprite_layout_yoffset[64] = { 0x000, 0x000, 0x020, 0x020, 0x040, 0x040, 0x060, 0x060, - 0x080, 0x080, 0x0A0, 0x0A0, 0x0C0, 0x0C0, 0x0E0, 0x0E0, + 0x080, 0x080, 0x0a0, 0x0a0, 0x0c0, 0x0c0, 0x0e0, 0x0e0, 0x100, 0x100, 0x120, 0x120, 0x140, 0x140, 0x160, 0x160, - 0x180, 0x180, 0x1A0, 0x1A0, 0x1C0, 0x1C0, 0x1E0, 0x1E0, + 0x180, 0x180, 0x1a0, 0x1a0, 0x1c0, 0x1c0, 0x1e0, 0x1e0, 0x200, 0x200, 0x220, 0x220, 0x240, 0x240, 0x260, 0x260, - 0x280, 0x280, 0x2A0, 0x2A0, 0x2C0, 0x2C0, 0x2E0, 0x2E0, + 0x280, 0x280, 0x2a0, 0x2a0, 0x2c0, 0x2c0, 0x2e0, 0x2e0, 0x300, 0x300, 0x320, 0x320, 0x340, 0x340, 0x360, 0x360, - 0x380, 0x380, 0x3A0, 0x3A0, 0x3C0, 0x3C0, 0x3E0, 0x3E0 + 0x380, 0x380, 0x3a0, 0x3a0, 0x3c0, 0x3c0, 0x3e0, 0x3e0 }; static const gfx_layout triplhnt_large_sprite_layout = { - 64, 64, /* width, height */ - 16, /* total */ - 2, /* planes */ + 64, 64, // width, height + 16, // total + 2, // planes { 0x0000, 0x4000 }, EXTENDED_XOFFS, EXTENDED_YOFFS, @@ -238,10 +440,10 @@ static const gfx_layout triplhnt_large_sprite_layout = static const gfx_layout triplhnt_tile_layout = { - 16, 16, /* width, height */ - 64, /* total */ - 1, /* planes */ - { 0 }, /* plane offsets */ + 16, 16, // width, height + 64, // total + 1, // planes + { 0 }, // plane offsets { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7 }, @@ -249,18 +451,18 @@ static const gfx_layout triplhnt_tile_layout = 0x00, 0x00, 0x08, 0x08, 0x10, 0x10, 0x18, 0x18, 0x20, 0x20, 0x28, 0x28, 0x30, 0x30, 0x38, 0x38 }, - 0x40 /* increment */ + 0x40 // increment }; static GFXDECODE_START( gfx_triplhnt ) - GFXDECODE_ENTRY( "gfx1", 0, triplhnt_small_sprite_layout, 0, 1 ) - GFXDECODE_ENTRY( "gfx1", 0, triplhnt_large_sprite_layout, 0, 1 ) - GFXDECODE_ENTRY( "gfx2", 0, triplhnt_tile_layout, 4, 2 ) + GFXDECODE_ENTRY( "sprites", 0, triplhnt_small_sprite_layout, 0, 1 ) + GFXDECODE_ENTRY( "sprites", 0, triplhnt_large_sprite_layout, 0, 1 ) + GFXDECODE_ENTRY( "tiles", 0, triplhnt_tile_layout, 4, 2 ) GFXDECODE_END -void triplhnt_state::triplhnt_palette(palette_device &palette) const +void triplhnt_state::palette(palette_device &palette) const { palette.set_pen_color(0, rgb_t(0xaf, 0xaf, 0xaf)); // sprites palette.set_pen_color(1, rgb_t(0x00, 0x00, 0x00)); @@ -275,9 +477,9 @@ void triplhnt_state::triplhnt_palette(palette_device &palette) const void triplhnt_state::triplhnt(machine_config &config) { - /* basic machine hardware */ - M6800(config, m_maincpu, 800000); - m_maincpu->set_addrmap(AS_PROGRAM, &triplhnt_state::triplhnt_map); + // basic machine hardware + M6800(config, m_maincpu, 800'000); + m_maincpu->set_addrmap(AS_PROGRAM, &triplhnt_state::program_map); m_maincpu->set_vblank_int("screen", FUNC(triplhnt_state::irq0_line_hold)); NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); // battery-backed 74C89 at J5 @@ -296,7 +498,7 @@ void triplhnt_state::triplhnt(machine_config &config) WATCHDOG_TIMER(config, m_watchdog); - /* video hardware */ + // video hardware screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); screen.set_refresh_hz(60); screen.set_size(256, 262); @@ -305,13 +507,13 @@ void triplhnt_state::triplhnt(machine_config &config) screen.set_palette(m_palette); GFXDECODE(config, m_gfxdecode, m_palette, gfx_triplhnt); - PALETTE(config, m_palette, FUNC(triplhnt_state::triplhnt_palette), 8); + PALETTE(config, m_palette, FUNC(triplhnt_state::palette), 8); - /* sound hardware */ + // sound hardware SPEAKER(config, "mono").front_center(); SAMPLES(config, m_samples); - m_samples->set_channels(2); /* 2 channels */ + m_samples->set_channels(2); m_samples->set_samples_names(triplhnt_sample_names); m_samples->add_route(ALL_OUTPUTS, "mono", 0.20); @@ -331,14 +533,16 @@ ROM_START( triplhnt ) ROM_LOAD_NIB_HIGH( "8401.c1", 0x7C00, 0x400, CRC(7461b05e) SHA1(16573ae655c306a38ff0f29a3c3285d636907f38) ) ROM_LOAD_NIB_LOW ( "8405.c2", 0x7C00, 0x400, CRC(ba370b97) SHA1(5d799ce6ae56c315ff0abedea7ad9204bacc266b) ) - ROM_REGION( 0x1000, "gfx1", 0 ) /* sprites */ + ROM_REGION( 0x1000, "sprites", 0 ) ROM_LOAD( "8423.n1", 0x0000, 0x800, CRC(9937d0da) SHA1(abb906c2d9869b09be5172cc7639bb9cda38831b) ) ROM_LOAD( "8422.r1", 0x0800, 0x800, CRC(803621dd) SHA1(ffbd7f87a86477e5eb94f12fc20a837128a02442) ) - ROM_REGION( 0x200, "gfx2", 0 ) /* tiles */ + ROM_REGION( 0x200, "tiles", 0 ) ROM_LOAD_NIB_HIGH( "8409.l3", 0x0000, 0x200, CRC(ec304172) SHA1(ccbf7e117fef7fa4288e3bf68f1a150b3a492ce6) ) ROM_LOAD_NIB_LOW ( "8410.m3", 0x0000, 0x200, CRC(f75a1b08) SHA1(81b4733194462cd4cef7f4221ecb7abd1556b871) ) ROM_END +} // anonymous namespace + GAME( 1977, triplhnt, 0, triplhnt, triplhnt, triplhnt_state, init_triplhnt, 0, "Atari", "Triple Hunt", MACHINE_REQUIRES_ARTWORK | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/atari/triplhnt.h b/src/mame/atari/triplhnt.h deleted file mode 100644 index c4603ec546d..00000000000 --- a/src/mame/atari/triplhnt.h +++ /dev/null @@ -1,108 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Stefan Jokisch -/************************************************************************* - - Atari Triple Hunt hardware - -*************************************************************************/ -#ifndef MAME_ATARI_TRIPLHNT_H -#define MAME_ATARI_TRIPLHNT_H - -#pragma once - -#include "machine/74259.h" -#include "machine/watchdog.h" -#include "sound/discrete.h" -#include "sound/samples.h" -#include "emupal.h" -#include "screen.h" -#include "tilemap.h" - - -/* Discrete Sound Input Nodes */ -#define TRIPLHNT_BEAR_ROAR_DATA NODE_01 -#define TRIPLHNT_BEAR_EN NODE_02 -#define TRIPLHNT_SHOT_DATA NODE_03 -#define TRIPLHNT_SCREECH_EN NODE_04 -#define TRIPLHNT_LAMP_EN NODE_05 - - -class triplhnt_state : public driver_device -{ -public: - triplhnt_state(const machine_config &mconfig, device_type type, const char *tag) : - driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_latch(*this, "latch"), - m_watchdog(*this, "watchdog"), - m_discrete(*this, "discrete"), - m_samples(*this, "samples"), - m_gfxdecode(*this, "gfxdecode"), - m_screen(*this, "screen"), - m_palette(*this, "palette"), - m_playfield_ram(*this, "playfield_ram"), - m_vpos_ram(*this, "vpos_ram"), - m_hpos_ram(*this, "hpos_ram"), - m_orga_ram(*this, "orga_ram"), - m_code_ram(*this, "code_ram"), - m_lamp(*this, "lamp0") - { } - - void triplhnt(machine_config &config); - - void init_triplhnt(); - -protected: - virtual void machine_start() override; - virtual void video_start() override; - -private: - DECLARE_WRITE_LINE_MEMBER(coin_lockout_w); - DECLARE_WRITE_LINE_MEMBER(tape_control_w); - - uint8_t cmos_r(offs_t offset); - uint8_t input_port_4_r(); - uint8_t misc_r(offs_t offset); - uint8_t da_latch_r(offs_t offset); - - TILE_GET_INFO_MEMBER(get_tile_info); - void triplhnt_palette(palette_device &palette) const; - - uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect); - TIMER_CALLBACK_MEMBER(set_collision); - - void triplhnt_map(address_map &map); - - required_device m_maincpu; - required_device m_latch; - required_device m_watchdog; - required_device m_discrete; - required_device m_samples; - required_device m_gfxdecode; - required_device m_screen; - required_device m_palette; - - required_shared_ptr m_playfield_ram; - required_shared_ptr m_vpos_ram; - required_shared_ptr m_hpos_ram; - required_shared_ptr m_orga_ram; - required_shared_ptr m_code_ram; - output_finder<> m_lamp; - - uint8_t m_cmos[16]{}; - uint8_t m_da_latch = 0; - uint8_t m_cmos_latch = 0; - uint8_t m_hit_code = 0; - int m_sprite_zoom = 0; - int m_sprite_bank = 0; - bitmap_ind16 m_helper; - emu_timer *m_hit_timer = nullptr; - tilemap_t* m_bg_tilemap = nullptr; -}; - -/*----------- defined in audio/triplhnt.cpp -----------*/ -DISCRETE_SOUND_EXTERN( triplhnt_discrete ); -extern const char *const triplhnt_sample_names[]; - -#endif // MAME_ATARI_TRIPLHNT_H diff --git a/src/mame/atari/triplhnt_a.cpp b/src/mame/atari/triplhnt_a.cpp index 9c7cca937dd..e92707ac56a 100644 --- a/src/mame/atari/triplhnt_a.cpp +++ b/src/mame/atari/triplhnt_a.cpp @@ -1,12 +1,15 @@ // license:BSD-3-Clause // copyright-holders:Derrick Renaud + /************************************************************************* - audio\triplhnt.cpp + atari\triplhnt_a.cpp *************************************************************************/ #include "emu.h" -#include "triplhnt.h" + +#include "triplhnt_a.h" + #include "sound/discrete.h" diff --git a/src/mame/atari/triplhnt_a.h b/src/mame/atari/triplhnt_a.h new file mode 100644 index 00000000000..a720ac00092 --- /dev/null +++ b/src/mame/atari/triplhnt_a.h @@ -0,0 +1,22 @@ +// license:BSD-3-Clause +// copyright-holders:Derrick Renaud + +/*************************************************************************** + +Triple Hunt Audio + +***************************************************************************/ + +#include "sound/discrete.h" + +// discrete sound input nodes + +#define TRIPLHNT_BEAR_ROAR_DATA NODE_01 +#define TRIPLHNT_BEAR_EN NODE_02 +#define TRIPLHNT_SHOT_DATA NODE_03 +#define TRIPLHNT_SCREECH_EN NODE_04 +#define TRIPLHNT_LAMP_EN NODE_05 + + +DISCRETE_SOUND_EXTERN( triplhnt_discrete ); +extern const char *const triplhnt_sample_names[]; diff --git a/src/mame/atari/triplhnt_v.cpp b/src/mame/atari/triplhnt_v.cpp deleted file mode 100644 index 0e4e6604b72..00000000000 --- a/src/mame/atari/triplhnt_v.cpp +++ /dev/null @@ -1,113 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Stefan Jokisch -/*************************************************************************** - -Atari Triple Hunt video emulation - -***************************************************************************/ - -#include "emu.h" -#include "triplhnt.h" - - -TILE_GET_INFO_MEMBER(triplhnt_state::get_tile_info) -{ - int code = m_playfield_ram[tile_index] & 0x3f; - - tileinfo.set(2, code, code == 0x3f ? 1 : 0, 0); -} - - -void triplhnt_state::video_start() -{ - m_screen->register_screen_bitmap(m_helper); - - m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(triplhnt_state::get_tile_info)), TILEMAP_SCAN_ROWS, 16, 16, 16, 16); - - m_hit_timer = timer_alloc(FUNC(triplhnt_state::set_collision), this); - - save_item(NAME(m_cmos)); - save_item(NAME(m_da_latch)); - save_item(NAME(m_cmos_latch)); - save_item(NAME(m_hit_code)); - save_item(NAME(m_sprite_zoom)); - save_item(NAME(m_sprite_bank)); -} - - -void triplhnt_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - int hit_line = 999; - int hit_code = 999; - - for (int i = 0; i < 16; i++) - { - rectangle rect; - - int j = (m_orga_ram[i] & 15) ^ 15; - - /* software sorts sprites by x and stores order in orga RAM */ - - int hpos = m_hpos_ram[j] ^ 255; - int vpos = m_vpos_ram[j] ^ 255; - int code = m_code_ram[j] ^ 255; - - if (hpos == 255) - continue; - - /* sprite placement might be wrong */ - - if (m_sprite_zoom) - { - rect.set(hpos - 16, hpos - 16 + 63, 196 - vpos, 196 - vpos + 63); - } - else - { - rect.set(hpos - 16, hpos - 16 + 31, 224 - vpos, 224 - vpos + 31); - } - - /* render sprite to auxiliary bitmap */ - - m_gfxdecode->gfx(m_sprite_zoom)->opaque(m_helper,cliprect, - 2 * code + m_sprite_bank, 0, code & 8, 0, - rect.left(), rect.top()); - - rect &= cliprect; - - /* check for collisions and copy sprite */ - for (int x = rect.left(); x <= rect.right(); x++) - { - for (int y = rect.top(); y <= rect.bottom(); y++) - { - pen_t const a = m_helper.pix(y, x); - pen_t const b = bitmap.pix(y, x); - - if (a == 2 && b == 7) - { - hit_code = j; - hit_line = y; - } - - if (a != 1) - bitmap.pix(y, x) = a; - } - } - } - - if (hit_line != 999 && hit_code != 999) - m_hit_timer->adjust(m_screen->time_until_pos(hit_line), hit_code); -} - - -uint32_t triplhnt_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - m_bg_tilemap->mark_all_dirty(); - - m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0); - - draw_sprites(bitmap, cliprect); - - m_discrete->write(TRIPLHNT_BEAR_ROAR_DATA, m_playfield_ram[0xfa] & 15); - m_discrete->write(TRIPLHNT_SHOT_DATA, m_playfield_ram[0xfc] & 15); - return 0; -} diff --git a/src/mame/atari/tunhunt.cpp b/src/mame/atari/tunhunt.cpp index 3c9fcd06c72..0bb34f0d989 100644 --- a/src/mame/atari/tunhunt.cpp +++ b/src/mame/atari/tunhunt.cpp @@ -1,5 +1,6 @@ // license:BSD-3-Clause // copyright-holders:Phil Stroffolino, David Haywood + /*************************************************************************** Atari Tunnel Hunt hardware @@ -26,8 +27,8 @@ Colors: - Hues are hardcoded. There doesn't appear to be any logical way to - map the color proms so that the correct colors appear. - See last page of schematics for details. Are color proms bad? + map the color PROMs so that the correct colors appear. + See last page of schematics for details. Are color PROMs bad? (shouldn't be, both sets were the same) Shell Objects: @@ -46,13 +47,462 @@ ***************************************************************************/ #include "emu.h" -#include "tunhunt.h" #include "cpu/m6502/m6502.h" #include "machine/rescap.h" #include "sound/pokey.h" -#include "speaker.h" +#include "emupal.h" +#include "screen.h" +#include "speaker.h" +#include "tilemap.h" + + +namespace { + +class tunhunt_state : public driver_device +{ +public: + tunhunt_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_gfxdecode(*this, "gfxdecode"), + m_screen(*this, "screen"), + m_palette(*this, "palette"), + m_workram(*this, "workram"), + m_videoram(*this, "videoram"), + m_spriteram(*this, "spriteram"), + m_paletteram(*this, "paletteram"), + m_in0(*this, "IN0"), + m_dsw(*this, "DSW"), + m_led(*this, "led0") + { } + + void tunhunt(machine_config &config); + +protected: + virtual void machine_start() override { m_led.resolve(); } + virtual void machine_reset() override; + virtual void video_start() override; + +private: + required_device m_maincpu; + required_device m_gfxdecode; + required_device m_screen; + required_device m_palette; + + required_shared_ptr m_workram; + required_shared_ptr m_videoram; + required_shared_ptr m_spriteram; + required_shared_ptr m_paletteram; + required_ioport m_in0; + required_ioport m_dsw; + output_finder<> m_led; + + uint8_t m_control = 0; + tilemap_t *m_fg_tilemap = nullptr; + bitmap_ind16 m_tmpbitmap; + + uint8_t m_mobsc0 = 0; + uint8_t m_mobsc1 = 0; + uint8_t m_lineh[13]{}; + uint8_t m_shl0st = 0; + uint8_t m_shl1st = 0; + uint8_t m_vstrlo = 0; + uint8_t m_linesh = 0; + uint8_t m_shl0pc = 0; + uint8_t m_shl1pc = 0; + uint8_t m_linec[13]{}; + uint8_t m_shl0v = 0; + uint8_t m_shl1v = 0; + uint8_t m_mobjh = 0; + uint8_t m_linev[13]{}; + uint8_t m_shl0vs = 0; + uint8_t m_shl1vs = 0; + uint8_t m_mobvs = 0; + uint8_t m_linevs[13]{}; + uint8_t m_shel0h = 0; + uint8_t m_mobst = 0; + uint8_t m_shel1h = 0; + uint8_t m_mobjv = 0; + + void control_w(uint8_t data); + uint8_t button_r(offs_t offset); + void videoram_w(offs_t offset, uint8_t data); + template uint8_t dsw2_r(); + + TILE_GET_INFO_MEMBER(get_fg_tile_info); + + void palette(palette_device &palette) const; + + uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + void set_pens(); + void draw_motion_object(bitmap_ind16 &bitmap, const rectangle &cliprect); + void draw_box(bitmap_ind16 &bitmap, const rectangle &cliprect); + void draw_shell(bitmap_ind16 &bitmap, const rectangle &cliprect, int picture_code, int hposition, int vstart, int vstop, int vstretch, int hstretch); + void main_map(address_map &map); +}; + + +// video + +/****************************************************************************************/ + +void tunhunt_state::videoram_w(offs_t offset, uint8_t data) +{ + m_videoram[offset] = data; + m_fg_tilemap->mark_tile_dirty(offset); +} + +TILE_GET_INFO_MEMBER(tunhunt_state::get_fg_tile_info) +{ + int const attr = m_videoram[tile_index]; + int const code = attr & 0x3f; + int const color = attr >> 6; + int const flags = color ? TILE_FORCE_LAYER0 : 0; + + tileinfo.set(0, code, color, flags); +} + +void tunhunt_state::video_start() +{ + /* + Motion Object RAM contains 64 lines of run-length encoded data. + We keep track of dirty lines and cache the expanded bitmap. + With max RLE expansion, bitmap size is 256x64. + */ + + m_tmpbitmap.allocate(256, 64, m_screen->format()); + + m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(tunhunt_state::get_fg_tile_info)), TILEMAP_SCAN_COLS, 8, 8, 8, 32); + + m_fg_tilemap->set_transparent_pen(0); + m_fg_tilemap->set_scrollx(0, 64); + + save_item(NAME(m_control)); + save_item(NAME(m_mobsc0)); + save_item(NAME(m_mobsc1)); + save_item(NAME(m_lineh)); + save_item(NAME(m_shl0st)); + save_item(NAME(m_shl1st)); + save_item(NAME(m_vstrlo)); + save_item(NAME(m_linesh)); + save_item(NAME(m_shl0pc)); + save_item(NAME(m_shl1pc)); + save_item(NAME(m_linec)); + save_item(NAME(m_shl0v)); + save_item(NAME(m_shl1v)); + save_item(NAME(m_mobjh)); + save_item(NAME(m_linev)); + save_item(NAME(m_shl0vs)); + save_item(NAME(m_shl1vs)); + save_item(NAME(m_mobvs)); + save_item(NAME(m_linevs)); + save_item(NAME(m_shel0h)); + save_item(NAME(m_mobst)); + save_item(NAME(m_shel1h)); + save_item(NAME(m_mobjv)); +} + +void tunhunt_state::palette(palette_device &palette) const +{ + /* Tunnel Hunt uses a combination of color PROMs and palette RAM to specify a 16 color + * palette. Here, we manage only the mappings for alphanumeric characters and SHELL + * graphics, which are unpacked ahead of time and drawn using MAME's drawgfx primitives. + */ + + // motion objects/box + for (int i = 0; i < 0x10; i++) + palette.set_pen_indirect(i, i); + + /* AlphaNumerics (1bpp) + * 2 bits of hilite select from 4 different background colors + * Foreground color is always pen#4 + * Background color is mapped as follows: + */ + + // alpha hilite#0 + palette.set_pen_indirect(0x10, 0x0); // background color#0 (transparent) + palette.set_pen_indirect(0x11, 0x4); // foreground color + + // alpha hilite#1 + palette.set_pen_indirect(0x12, 0x5); // background color#1 + palette.set_pen_indirect(0x13, 0x4); // foreground color + + // alpha hilite#2 + palette.set_pen_indirect(0x14, 0x6); // background color#2 + palette.set_pen_indirect(0x15, 0x4); // foreground color + + // alpha hilite#3 + palette.set_pen_indirect(0x16, 0xf); // background color#3 + palette.set_pen_indirect(0x17, 0x4); // foreground color + + /* shell graphics; these are either 1bpp (2 banks) or 2bpp. It isn't clear which. + * In any event, the following pens are associated with the shell graphics: + */ + palette.set_pen_indirect(0x18, 0); + palette.set_pen_indirect(0x19, 4);//1; +} + +/* +Color Array RAM Assignments: + Location + 0 Blanking, border + 1 Mot Obj (10) (D), Shell (01) + 2 Mot Obj (01) (G), Shell (10) + 3 Mot Obj (00) (W) + 4 Alpha & Shell (11) - shields + 5 Hilight 1 + 6 Hilight 2 + 8-E Lines (as normal) background + F Hilight 3 +*/ +void tunhunt_state::set_pens() +{ +/* + The actual contents of the color PROMs (unused by this driver) + are as follows: + + D11 "blue/green" + 0000: 00 00 8b 0b fb 0f ff 0b + 00 00 0f 0f fb f0 f0 ff + + C11 "red" + 0020: 00 f0 f0 f0 b0 b0 00 f0 + 00 f0 f0 00 b0 00 f0 f0 +*/ + //const uint8_t *color_prom = memregion("proms")->base(); + + for (int i = 0; i < 16; i++) + { + int color = m_paletteram[i]; + int const shade = 0xf^(color>>4); + int red, green, blue; + + color &= 0xf; // hue select + switch (color) + { + default: + case 0x0: red = 0xff; green = 0xff; blue = 0xff; break; // white + case 0x1: red = 0xff; green = 0x00; blue = 0xff; break; // purple + case 0x2: red = 0x00; green = 0x00; blue = 0xff; break; // blue + case 0x3: red = 0x00; green = 0xff; blue = 0xff; break; // cyan + case 0x4: red = 0x00; green = 0xff; blue = 0x00; break; // green + case 0x5: red = 0xff; green = 0xff; blue = 0x00; break; // yellow + case 0x6: red = 0xff; green = 0x00; blue = 0x00; break; // red + case 0x7: red = 0x00; green = 0x00; blue = 0x00; break; // black? + + case 0x8: red = 0xff; green = 0x7f; blue = 0x00; break; // orange + case 0x9: red = 0x7f; green = 0xff; blue = 0x00; break; // ? + case 0xa: red = 0x00; green = 0xff; blue = 0x7f; break; // ? + case 0xb: red = 0x00; green = 0x7f; blue = 0xff; break; // ? + case 0xc: red = 0xff; green = 0x00; blue = 0x7f; break; // ? + case 0xd: red = 0x7f; green = 0x00; blue = 0xff; break; // ? + case 0xe: red = 0xff; green = 0xaa; blue = 0xaa; break; // ? + case 0xf: red = 0xaa; green = 0xaa; blue = 0xff; break; // ? + } + + // combine color components with shade value (0..0xf) + #define APPLY_SHADE( C,S ) ((C*S)/0xf) + red = APPLY_SHADE(red, shade); + green = APPLY_SHADE(green, shade); + blue = APPLY_SHADE(blue, shade); + + m_palette->set_indirect_color(i, rgb_t(red, green, blue)); + } +} + +void tunhunt_state::draw_motion_object(bitmap_ind16 &bitmap, const rectangle &cliprect) +{ +/* + * VSTRLO 0x1202 + * normally 0x02 (gameplay, attract1) + * in attract2 (with "Tunnel Hunt" graphic), decrements from 0x2f down to 0x01 + * goes to 0x01 for some enemy shots + * + * MOBSC0 0x1080 + * MOBSC1 0x1081 + * always 0x00? + */ + + bitmap_ind16 &tmpbitmap = m_tmpbitmap; + //int skip = m_mobst; + const int x0 = 255 - m_mobjv; + const int y0 = 255 - m_mobjh; + + for (int line = 0; line < 64; line++) + { + int x = 0; + const uint8_t *const source = &m_spriteram[line * 0x10]; + for (int span = 0; span < 0x10; span++) + { + const int span_data = source[span]; + if (span_data == 0xff) break; + const int color = ((span_data >> 6) & 0x3) ^ 0x3; + int count = (span_data & 0x1f) + 1; + while (count-- && x < 256) + tmpbitmap.pix(line, x++) = color; + } + while (x < 256) + tmpbitmap.pix(line, x++) = 0; + } + + int scaley; + switch (m_vstrlo) + { + case 0x01: + scaley = (1 << 16) * 0.33; // seems correct + break; + + case 0x02: + scaley = (1 << 16) * 0.50; // seems correct + break; + + default: + scaley = (1 << 16) * m_vstrlo / 4; // ??? + break; + } + const int scalex = 1 << 16; + + copyrozbitmap_trans( + bitmap, cliprect, tmpbitmap, + -x0 * scalex, // startx + -y0 * scaley, // starty + scalex, // incxx + 0, 0, // incxy, incyx + scaley, // incyy + false, // no wraparound + 0); +} + +void tunhunt_state::draw_box(bitmap_ind16 &bitmap, const rectangle &cliprect) +{ +/* + This is unnecessarily slow, but the box priorities aren't completely understood, + yet. Once understood, this function should be converted to use bitmap_fill with + rectangular chunks instead of BITMAP_ADDR. + + Tunnels: + 1080: 00 00 00 01 e7 18 ae 51 94 6b 88 77 83 7c 80 7f x0 + 1480: 00 f0 17 00 22 22 5b 5b 75 75 81 81 86 86 89 89 y0 + 1400: 00 00 97 ff f1 f1 b8 b8 9e 9e 92 92 8d 8d 8a 8a y1 + 1280: 07 03 00 07 07 0c 0c 0d 0d 0e 0e 08 08 09 09 0a palette select + + Color Bars: + 1080: 00 00 00 01 00 20 40 60 80 a0 c0 e0 01 2a 50 7a x0 + 1480: 00 f0 00 00 40 40 40 40 40 40 40 40 00 00 00 00 y0 + 1400: 00 00 00 ff ff ff ff ff ff ff ff ff 40 40 40 40 y1 + 1280: 07 03 00 01 07 06 04 05 02 07 03 00 09 0a 0b 0c palette select + ->hue 06 02 ff 60 06 05 03 04 01 06 02 ff d2 00 c2 ff +*/ + + for (int y = 0; y < 256; y++) + { + if (0xff - y >= cliprect.top() && 0xff - y <= cliprect.bottom()) + for (int x = 0; x < 256; x++) + { + int color = 0; + int z = 0; + for (int span = 0; span < 13; span++) + { + int const x0 = m_lineh[span]; + int const y0 = m_linevs[span]; + int const y1 = m_linev[span]; + + if (y >= y0 && y <= y1 && x >= x0 && x0 >= z) + { + color = m_linec[span] & 0xf; + z = x0; // give priority to rightmost spans + } + } + if (x >= cliprect.left() && x <= cliprect.right()) + bitmap.pix(0xff - y, x) = color; + } + } +} + +// "shell" graphics are 16x16 pixel tiles used for player shots and targeting cursor +void tunhunt_state::draw_shell(bitmap_ind16 &bitmap, + const rectangle &cliprect, + int picture_code, + int hposition, + int vstart, + int vstop, + int vstretch, + int hstretch ) +{ + if (hstretch) + { + for (int sx = 0; sx < 256; sx += 16) + { + for (int sy = 0; sy < 256; sy += 16) + { + m_gfxdecode->gfx(1)->transpen(bitmap, cliprect, + picture_code, + 0, // color + 0, 0, // flip + sx, sy, 0); + } + } + } + else + /* + vstretch is normally 0x01 + + targeting cursor: + hposition = 0x78 + vstart = 0x90 + vstop = 0x80 + + during grid test: + vstretch = 0xff + hposition = 0xff + vstart = 0xff + vstop = 0x00 + + */ + + m_gfxdecode->gfx(1)->transpen(bitmap, cliprect, + picture_code, + 0, // color + 0, 0, // flip + 255 - hposition - 16, vstart - 32, 0); +} + +uint32_t tunhunt_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + set_pens(); + + draw_box(bitmap, cliprect); + + draw_motion_object(bitmap, cliprect); + + draw_shell(bitmap, cliprect, + m_shl0pc, // picture code + m_shel0h, // hposition + m_shl0v, // vstart + m_shl0vs, // vstop + m_shl0st, // vstretch + m_control & 0x08); // hstretch + + draw_shell(bitmap, cliprect, + m_shl1pc, // picture code + m_shel1h, // hposition + m_shl1v, // vstart + m_shl1vs, // vstop + m_shl1st, // vstretch + m_control & 0x10); // hstretch + + rectangle cr = cliprect; + if (cr.min_x < 192) + cr.min_x = 192; + + m_fg_tilemap->draw(screen, bitmap, cr, 0, 0); + return 0; +} + + +// machine /************************************* * @@ -75,7 +525,7 @@ void tunhunt_state::control_w(uint8_t data) m_control = data; machine().bookkeeping().coin_counter_w(0, BIT(data, 0)); machine().bookkeeping().coin_counter_w(1, BIT(data, 1)); - m_led = BIT(data , 6); /* start */ + m_led = BIT(data , 6); // start } @@ -88,40 +538,18 @@ void tunhunt_state::control_w(uint8_t data) uint8_t tunhunt_state::button_r(offs_t offset) { - int data = ioport("IN0")->read(); - return ((data>>offset)&1)?0x00:0x80; + int const data = m_in0->read(); + return ((data >> offset) & 1) ? 0x00 : 0x80; } -uint8_t tunhunt_state::dsw2_0r() +template +uint8_t tunhunt_state::dsw2_r() { - return (ioport("DSW")->read()&0x0100)?0x80:0x00; + return (m_dsw->read()& Mask) ? 0x80 : 0x00; } -uint8_t tunhunt_state::dsw2_1r() -{ - return (ioport("DSW")->read()&0x0200)?0x80:0x00; -} - - -uint8_t tunhunt_state::dsw2_2r() -{ - return (ioport("DSW")->read()&0x0400)?0x80:0x00; -} - - -uint8_t tunhunt_state::dsw2_3r() -{ - return (ioport("DSW")->read()&0x0800)?0x80:0x00; -} - - -uint8_t tunhunt_state::dsw2_4r() -{ - return (ioport("DSW")->read()&0x1000)?0x80:0x00; -} - void tunhunt_state::machine_reset() { m_mobsc0 = 0; @@ -159,7 +587,7 @@ void tunhunt_state::machine_reset() void tunhunt_state::main_map(address_map &map) { map.global_mask(0x7fff); - map(0x0000, 0x03ff).ram().share("workram"); /* Work RAM */ + map(0x0000, 0x03ff).ram().share(m_workram); map(0x1080, 0x1080).lw8(NAME([this](uint8_t data) { m_mobsc0 = data; })); // SCAN ROM START FOR MOBJ (unused?) map(0x1081, 0x1081).lw8(NAME([this](uint8_t data) { m_mobsc1 = data; })); // (unused?) @@ -179,18 +607,18 @@ void tunhunt_state::main_map(address_map &map) map(0x1481, 0x1481).lw8(NAME([this](uint8_t data) { m_shl1vs = data; })); map(0x1482, 0x1482).lw8(NAME([this](uint8_t data) { m_mobvs = data; })); // V STOP OF MOTION OBJECT (NORMAL SCREEN) map(0x1483, 0x148f).lw8(NAME([this](offs_t offset, uint8_t data) { m_linevs[offset] = data; })); // LINES VERT STOP - map(0x1600, 0x160f).writeonly().share("paletteram"); // COLRAM (D7-D4 SHADE; D3-D0 COLOR) + map(0x1600, 0x160f).writeonly().share(m_paletteram); // COLRAM (D7-D4 SHADE; D3-D0 COLOR) map(0x1800, 0x1800).lw8(NAME([this](uint8_t data) { m_shel0h = data; })); // SHELL H POSITON (NORMAL SCREEN) map(0x1802, 0x1802).lw8(NAME([this](uint8_t data) { m_mobst = data; })); // STARTING LINE FOR RAM SCAN ON MOBJ map(0x1a00, 0x1a00).lw8(NAME([this](uint8_t data) { m_shel1h = data; })); map(0x1c00, 0x1c00).lw8(NAME([this](uint8_t data) { m_mobjv = data; })); // V POSITION (SCREEN ON SIDE) - map(0x1e00, 0x1eff).w(FUNC(tunhunt_state::videoram_w)).share("videoram"); /* ALPHA */ + map(0x1e00, 0x1eff).w(FUNC(tunhunt_state::videoram_w)).share(m_videoram); // ALPHA - map(0x2000, 0x2000).nopw(); /* watchdog */ + map(0x2000, 0x2000).nopw(); // watchdog map(0x2000, 0x2007).r(FUNC(tunhunt_state::button_r)); - map(0x2400, 0x2400).nopw(); /* INT ACK */ + map(0x2400, 0x2400).nopw(); // INT ACK map(0x2800, 0x2800).w(FUNC(tunhunt_state::control_w)); - map(0x2c00, 0x2fff).writeonly().share("spriteram"); + map(0x2c00, 0x2fff).writeonly().share(m_spriteram); map(0x3000, 0x300f).rw("pokey1", FUNC(pokey_device::read), FUNC(pokey_device::write)); map(0x4000, 0x400f).rw("pokey2", FUNC(pokey_device::read), FUNC(pokey_device::write)); @@ -283,29 +711,29 @@ static const gfx_layout alpha_layout = static const gfx_layout obj_layout = { 16,16, - 8, /* number of objects */ - 1, /* number of bitplanes */ - { 4 }, /* plane offsets */ + 8, // number of objects + 1, // number of bitplanes + { 4 }, // plane offsets { 0x00+0,0x00+1,0x00+2,0x00+3, 0x08+0,0x08+1,0x08+2,0x08+3, 0x10+0,0x10+1,0x10+2,0x10+3, 0x18+0,0x18+1,0x18+2,0x18+3 - }, /* x offsets */ + }, // x offsets { 0x0*0x20, 0x1*0x20, 0x2*0x20, 0x3*0x20, 0x4*0x20, 0x5*0x20, 0x6*0x20, 0x7*0x20, 0x8*0x20, 0x9*0x20, 0xa*0x20, 0xb*0x20, 0xc*0x20, 0xd*0x20, 0xe*0x20, 0xf*0x20 - }, /* y offsets */ + }, // y offsets 0x200 }; static GFXDECODE_START( gfx_tunhunt ) - GFXDECODE_ENTRY( "gfx1", 0x000, alpha_layout, 0x10, 4 ) - GFXDECODE_ENTRY( "gfx2", 0x200, obj_layout, 0x18, 1 ) - GFXDECODE_ENTRY( "gfx2", 0x000, obj_layout, 0x18, 1 ) /* second bank, or second bitplane? */ + GFXDECODE_ENTRY( "chars", 0x000, alpha_layout, 0x10, 4 ) + GFXDECODE_ENTRY( "sprites", 0x200, obj_layout, 0x18, 1 ) + GFXDECODE_ENTRY( "sprites", 0x000, obj_layout, 0x18, 1 ) // second bank, or second bitplane? GFXDECODE_END @@ -317,39 +745,39 @@ GFXDECODE_END void tunhunt_state::tunhunt(machine_config &config) { - /* basic machine hardware */ - M6502(config, m_maincpu, 12.096_MHz_XTAL/6); /* ??? */ + // basic machine hardware + M6502(config, m_maincpu, 12.096_MHz_XTAL / 6); // ??? m_maincpu->set_addrmap(AS_PROGRAM, &tunhunt_state::main_map); - m_maincpu->set_periodic_int(FUNC(tunhunt_state::irq0_line_hold), attotime::from_hz(4*60)); /* 48V, 112V, 176V, 240V */ + m_maincpu->set_periodic_int(FUNC(tunhunt_state::irq0_line_hold), attotime::from_hz(4*60)); // 48V, 112V, 176V, 240V - /* video hardware */ + // video hardware SCREEN(config, m_screen, SCREEN_TYPE_RASTER); m_screen->set_refresh_hz(60); - m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */ + m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500)); // not accurate m_screen->set_size(256, 256-16); m_screen->set_visarea(0, 255, 0, 255-16); m_screen->set_screen_update(FUNC(tunhunt_state::screen_update)); m_screen->set_palette(m_palette); GFXDECODE(config, m_gfxdecode, m_palette, gfx_tunhunt); - PALETTE(config, m_palette, FUNC(tunhunt_state::tunhunt_palette), 0x1a, 16); + PALETTE(config, m_palette, FUNC(tunhunt_state::palette), 0x1a, 16); - /* sound hardware */ + // sound hardware SPEAKER(config, "mono").front_center(); - pokey_device &pokey1(POKEY(config, "pokey1", 12.096_MHz_XTAL/10)); + pokey_device &pokey1(POKEY(config, "pokey1", 12.096_MHz_XTAL / 10)); pokey1.allpot_r().set_ioport("DSW"); pokey1.set_output_rc(RES_K(1), CAP_U(0.047), 5.0); pokey1.add_route(ALL_OUTPUTS, "mono", 0.50); - pokey_device &pokey2(POKEY(config, "pokey2", 12.096_MHz_XTAL/10)); + pokey_device &pokey2(POKEY(config, "pokey2", 12.096_MHz_XTAL / 10)); pokey2.pot_r<0>().set_ioport("IN1"); pokey2.pot_r<1>().set_ioport("IN2"); - pokey2.pot_r<2>().set(FUNC(tunhunt_state::dsw2_0r)); - pokey2.pot_r<3>().set(FUNC(tunhunt_state::dsw2_1r)); - pokey2.pot_r<4>().set(FUNC(tunhunt_state::dsw2_2r)); - pokey2.pot_r<5>().set(FUNC(tunhunt_state::dsw2_3r)); - pokey2.pot_r<6>().set(FUNC(tunhunt_state::dsw2_4r)); + pokey2.pot_r<2>().set(FUNC(tunhunt_state::dsw2_r<0x100>)); + pokey2.pot_r<3>().set(FUNC(tunhunt_state::dsw2_r<0x200>)); + pokey2.pot_r<4>().set(FUNC(tunhunt_state::dsw2_r<0x400>)); + pokey2.pot_r<5>().set(FUNC(tunhunt_state::dsw2_r<0x800>)); + pokey2.pot_r<6>().set(FUNC(tunhunt_state::dsw2_r<0x1000>)); pokey2.set_output_rc(RES_K(1), CAP_U(0.047), 5.0); pokey2.add_route(ALL_OUTPUTS, "mono", 0.50); } @@ -392,44 +820,45 @@ ROM_START( tunhunt ) ROM_LOAD( "005.ef1", 0x7000, 0x800, CRC(e17badf0) SHA1(6afbf517486340fe54b01fa26258877b2a8fc510) ) ROM_LOAD( "006.d1", 0x7800, 0x800, CRC(c3ae8519) SHA1(2b2e49065bc38429894ef29a29ffc60f96e64840) ) - ROM_REGION( 0x400, "gfx1", 0 ) /* alphanumeric characters */ + ROM_REGION( 0x400, "chars", 0 ) ROM_LOAD( "019.c10", 0x000, 0x400, CRC(d6fd45a9) SHA1(c86ea3790c29c554199af8ad6f3d563dcb7723c7) ) - ROM_REGION( 0x400, "gfx2", 0 ) /* "SHELL" objects (16x16 pixel sprites) */ + ROM_REGION( 0x400, "sprites", 0 ) // "SHELL" objects (16x16 pixel sprites) ROM_LOAD( "016.a8", 0x000, 0x200, CRC(830e6c34) SHA1(37a5eeb722dd80c4224c7f622b0edabb3ac1ca19) ) ROM_LOAD( "017.b8", 0x200, 0x200, CRC(5bef8b5a) SHA1(bfd9c592a34ed4861a6ad76ef10ea0d9b76a92b2) ) ROM_REGION( 0x540, "proms", 0 ) - ROM_LOAD( "013.d11", 0x000, 0x020, CRC(66f1f5eb) SHA1(bcf5348ae328cf943d2bf6e38df727c0c4c466b7) ) /* hue: BBBBGGGG? */ - ROM_LOAD( "014.c11", 0x020, 0x020, CRC(662444b2) SHA1(2e510c1d9b7e34a3045048a46045e61fabaf918e) ) /* hue: RRRR----? */ - ROM_LOAD( "015.n4", 0x040, 0x100, CRC(00e224a0) SHA1(1a384ef488791c62566c91b18d6a1fb4a5def2ba) ) /* timing? */ - ROM_LOAD( "018.h9", 0x140, 0x400, CRC(6547c208) SHA1(f19c334f9b4a1cfcbc913c0920688db2730dded0) ) /* color lookup table? */ + ROM_LOAD( "013.d11", 0x000, 0x020, CRC(66f1f5eb) SHA1(bcf5348ae328cf943d2bf6e38df727c0c4c466b7) ) // hue: BBBBGGGG? + ROM_LOAD( "014.c11", 0x020, 0x020, CRC(662444b2) SHA1(2e510c1d9b7e34a3045048a46045e61fabaf918e) ) // hue: RRRR----? + ROM_LOAD( "015.n4", 0x040, 0x100, CRC(00e224a0) SHA1(1a384ef488791c62566c91b18d6a1fb4a5def2ba) ) // timing? + ROM_LOAD( "018.h9", 0x140, 0x400, CRC(6547c208) SHA1(f19c334f9b4a1cfcbc913c0920688db2730dded0) ) // color lookup table? ROM_END ROM_START( tunhuntc ) ROM_REGION( 0x10000, "maincpu", 0 ) ROM_LOAD( "001.lm1", 0x5000, 0x800, CRC(2601a3a4) SHA1(939bafc54576fdaccf688b49cc9d201b03feec3a) ) ROM_LOAD( "002.k1", 0x5800, 0x800, CRC(29bbf3df) SHA1(4a0ec4cfab362a976d3962b347f687db45095cfd) ) - ROM_LOAD( "003.j1", 0x6000, 0x800, CRC(360c0f47) SHA1(8e3d815836504c7651812e0e26423b0c7045621c) ) /* bad crc? fails self-test */ - /* 0xcaa6bb2a: alternate prom (re)dumped by Al also fails, they simply modified the rom without fixing the checksum routine? */ + ROM_LOAD( "003.j1", 0x6000, 0x800, CRC(360c0f47) SHA1(8e3d815836504c7651812e0e26423b0c7045621c) ) // bad CRC? fails self-test + // 0xcaa6bb2a: alternate PROM (re)dumped by Al also fails, they simply modified the ROM without fixing the checksum routine? ROM_LOAD( "004.fh1", 0x6800, 0x800, CRC(4d6c920e) SHA1(2ef274356f4b8a0170a267cd6a3758b2bda693b5) ) ROM_LOAD( "005.ef1", 0x7000, 0x800, CRC(e17badf0) SHA1(6afbf517486340fe54b01fa26258877b2a8fc510) ) ROM_LOAD( "006.d1", 0x7800, 0x800, CRC(c3ae8519) SHA1(2b2e49065bc38429894ef29a29ffc60f96e64840) ) - ROM_REGION( 0x400, "gfx1", 0 ) /* alphanumeric characters */ + ROM_REGION( 0x400, "chars", 0 ) ROM_LOAD( "019.c10", 0x000, 0x400, CRC(d6fd45a9) SHA1(c86ea3790c29c554199af8ad6f3d563dcb7723c7) ) - ROM_REGION( 0x400, "gfx2", 0 ) /* "SHELL" objects (16x16 pixel sprites) */ + ROM_REGION( 0x400, "sprites", 0 ) // "SHELL" objects (16x16 pixel sprites) ROM_LOAD( "016.a8", 0x000, 0x200, CRC(830e6c34) SHA1(37a5eeb722dd80c4224c7f622b0edabb3ac1ca19) ) ROM_LOAD( "017.b8", 0x200, 0x200, CRC(5bef8b5a) SHA1(bfd9c592a34ed4861a6ad76ef10ea0d9b76a92b2) ) ROM_REGION( 0x540, "proms", 0 ) - ROM_LOAD( "013.d11", 0x000, 0x020, CRC(66f1f5eb) SHA1(bcf5348ae328cf943d2bf6e38df727c0c4c466b7) ) /* hue: BBBBGGGG? */ - ROM_LOAD( "014.c11", 0x020, 0x020, CRC(662444b2) SHA1(2e510c1d9b7e34a3045048a46045e61fabaf918e) ) /* hue: RRRR----? */ - ROM_LOAD( "015.n4", 0x040, 0x100, CRC(00e224a0) SHA1(1a384ef488791c62566c91b18d6a1fb4a5def2ba) ) /* timing? */ - ROM_LOAD( "018.h9", 0x140, 0x400, CRC(6547c208) SHA1(f19c334f9b4a1cfcbc913c0920688db2730dded0) ) /* color lookup table? */ + ROM_LOAD( "013.d11", 0x000, 0x020, CRC(66f1f5eb) SHA1(bcf5348ae328cf943d2bf6e38df727c0c4c466b7) ) // hue: BBBBGGGG? + ROM_LOAD( "014.c11", 0x020, 0x020, CRC(662444b2) SHA1(2e510c1d9b7e34a3045048a46045e61fabaf918e) ) // hue: RRRR----? + ROM_LOAD( "015.n4", 0x040, 0x100, CRC(00e224a0) SHA1(1a384ef488791c62566c91b18d6a1fb4a5def2ba) ) // timing? + ROM_LOAD( "018.h9", 0x140, 0x400, CRC(6547c208) SHA1(f19c334f9b4a1cfcbc913c0920688db2730dded0) ) // color lookup table? ROM_END +} // anonymous namespace /************************************* @@ -438,6 +867,5 @@ ROM_END * *************************************/ -/* rom parent machine inp state init */ -GAME( 1979,tunhunt, 0, tunhunt, tunhunt, tunhunt_state, empty_init, ORIENTATION_SWAP_XY, "Atari", "Tunnel Hunt", MACHINE_SUPPORTS_SAVE ) +GAME( 1979,tunhunt, 0, tunhunt, tunhunt, tunhunt_state, empty_init, ORIENTATION_SWAP_XY, "Atari", "Tunnel Hunt", MACHINE_SUPPORTS_SAVE ) GAME( 1981,tunhuntc, tunhunt, tunhunt, tunhunt, tunhunt_state, empty_init, ORIENTATION_SWAP_XY, "Atari (Centuri license)", "Tunnel Hunt (Centuri)", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/atari/tunhunt.h b/src/mame/atari/tunhunt.h deleted file mode 100644 index e38eefdb98d..00000000000 --- a/src/mame/atari/tunhunt.h +++ /dev/null @@ -1,94 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Phil Stroffolino, David Haywood -#ifndef MAME_ATARI_TUNHUNT_H -#define MAME_ATARI_TUNHUNT_H - -#pragma once - -#include "emupal.h" -#include "screen.h" -#include "tilemap.h" - -class tunhunt_state : public driver_device -{ -public: - tunhunt_state(const machine_config &mconfig, device_type type, const char *tag) : - driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_gfxdecode(*this, "gfxdecode"), - m_screen(*this, "screen"), - m_palette(*this, "palette"), - m_workram(*this, "workram"), - m_videoram(*this, "videoram"), - m_spriteram(*this, "spriteram"), - m_generic_paletteram_8(*this, "paletteram"), - m_led(*this, "led0") - { } - - void tunhunt(machine_config &config); - -private: - void control_w(uint8_t data); - uint8_t button_r(offs_t offset); - void videoram_w(offs_t offset, uint8_t data); - uint8_t dsw2_0r(); - uint8_t dsw2_1r(); - uint8_t dsw2_2r(); - uint8_t dsw2_3r(); - uint8_t dsw2_4r(); - - TILE_GET_INFO_MEMBER(get_fg_tile_info); - - virtual void machine_start() override { m_led.resolve(); } - virtual void video_start() override; - void tunhunt_palette(palette_device &palette) const; - - uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - void set_pens(); - void draw_motion_object(bitmap_ind16 &bitmap, const rectangle &cliprect); - void draw_box(bitmap_ind16 &bitmap, const rectangle &cliprect); - void draw_shell(bitmap_ind16 &bitmap, const rectangle &cliprect, int picture_code, - int hposition,int vstart,int vstop,int vstretch,int hstretch); - void main_map(address_map &map); - virtual void machine_reset() override; - - required_device m_maincpu; - required_device m_gfxdecode; - required_device m_screen; - required_device m_palette; - - required_shared_ptr m_workram; - required_shared_ptr m_videoram; - required_shared_ptr m_spriteram; - required_shared_ptr m_generic_paletteram_8; - output_finder<> m_led; - - uint8_t m_control = 0; - tilemap_t *m_fg_tilemap = nullptr; - bitmap_ind16 m_tmpbitmap; - - uint8_t m_mobsc0 = 0; - uint8_t m_mobsc1 = 0; - uint8_t m_lineh[13]{}; - uint8_t m_shl0st = 0; - uint8_t m_shl1st = 0; - uint8_t m_vstrlo = 0; - uint8_t m_linesh = 0; - uint8_t m_shl0pc = 0; - uint8_t m_shl1pc = 0; - uint8_t m_linec[13]{}; - uint8_t m_shl0v = 0; - uint8_t m_shl1v = 0; - uint8_t m_mobjh = 0; - uint8_t m_linev[13]{}; - uint8_t m_shl0vs = 0; - uint8_t m_shl1vs = 0; - uint8_t m_mobvs = 0; - uint8_t m_linevs[13]{}; - uint8_t m_shel0h = 0; - uint8_t m_mobst = 0; - uint8_t m_shel1h = 0; - uint8_t m_mobjv = 0; -}; - -#endif // MAME_ATARI_TUNHUNT_H diff --git a/src/mame/atari/tunhunt_v.cpp b/src/mame/atari/tunhunt_v.cpp deleted file mode 100644 index 489f8cf69c6..00000000000 --- a/src/mame/atari/tunhunt_v.cpp +++ /dev/null @@ -1,374 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Phil Stroffolino, David Haywood -/************************************************************************* - - Atari Tunnel Hunt hardware - -*************************************************************************/ - -#include "emu.h" -#include "tunhunt.h" - - -/****************************************************************************************/ - -void tunhunt_state::videoram_w(offs_t offset, uint8_t data) -{ - m_videoram[offset] = data; - m_fg_tilemap->mark_tile_dirty(offset); -} - -TILE_GET_INFO_MEMBER(tunhunt_state::get_fg_tile_info) -{ - int attr = m_videoram[tile_index]; - int code = attr & 0x3f; - int color = attr >> 6; - int flags = color ? TILE_FORCE_LAYER0 : 0; - - tileinfo.set(0, code, color, flags); -} - -void tunhunt_state::video_start() -{ - /* - Motion Object RAM contains 64 lines of run-length encoded data. - We keep track of dirty lines and cache the expanded bitmap. - With max RLE expansion, bitmap size is 256x64. - */ - - m_tmpbitmap.allocate(256, 64, m_screen->format()); - - m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(tunhunt_state::get_fg_tile_info)), TILEMAP_SCAN_COLS, 8, 8, 8, 32); - - m_fg_tilemap->set_transparent_pen(0); - m_fg_tilemap->set_scrollx(0, 64); - - save_item(NAME(m_control)); - save_item(NAME(m_mobsc0)); - save_item(NAME(m_mobsc1)); - save_item(NAME(m_lineh)); - save_item(NAME(m_shl0st)); - save_item(NAME(m_shl1st)); - save_item(NAME(m_vstrlo)); - save_item(NAME(m_linesh)); - save_item(NAME(m_shl0pc)); - save_item(NAME(m_shl1pc)); - save_item(NAME(m_linec)); - save_item(NAME(m_shl0v)); - save_item(NAME(m_shl1v)); - save_item(NAME(m_mobjh)); - save_item(NAME(m_linev)); - save_item(NAME(m_shl0vs)); - save_item(NAME(m_shl1vs)); - save_item(NAME(m_mobvs)); - save_item(NAME(m_linevs)); - save_item(NAME(m_shel0h)); - save_item(NAME(m_mobst)); - save_item(NAME(m_shel1h)); - save_item(NAME(m_mobjv)); -} - -void tunhunt_state::tunhunt_palette(palette_device &palette) const -{ - /* Tunnel Hunt uses a combination of color proms and palette RAM to specify a 16 color - * palette. Here, we manage only the mappings for alphanumeric characters and SHELL - * graphics, which are unpacked ahead of time and drawn using MAME's drawgfx primitives. - */ - - /* motion objects/box */ - for (int i = 0; i < 0x10; i++) - palette.set_pen_indirect(i, i); - - /* AlphaNumerics (1bpp) - * 2 bits of hilite select from 4 different background colors - * Foreground color is always pen#4 - * Background color is mapped as follows: - */ - - /* alpha hilite#0 */ - palette.set_pen_indirect(0x10, 0x0); // background color#0 (transparent) - palette.set_pen_indirect(0x11, 0x4); // foreground color - - /* alpha hilite#1 */ - palette.set_pen_indirect(0x12, 0x5); // background color#1 - palette.set_pen_indirect(0x13, 0x4); // foreground color - - /* alpha hilite#2 */ - palette.set_pen_indirect(0x14, 0x6); // background color#2 - palette.set_pen_indirect(0x15, 0x4); // foreground color - - /* alpha hilite#3 */ - palette.set_pen_indirect(0x16, 0xf); // background color#3 - palette.set_pen_indirect(0x17, 0x4); // foreground color - - /* shell graphics; these are either 1bpp (2 banks) or 2bpp. It isn't clear which. - * In any event, the following pens are associated with the shell graphics: - */ - palette.set_pen_indirect(0x18, 0); - palette.set_pen_indirect(0x19, 4);//1; -} - -/* -Color Array Ram Assignments: - Location - 0 Blanking, border - 1 Mot Obj (10) (D), Shell (01) - 2 Mot Obj (01) (G), Shell (10) - 3 Mot Obj (00) (W) - 4 Alpha & Shell (11) - shields - 5 Hilight 1 - 6 Hilight 2 - 8-E Lines (as normal) background - F Hilight 3 -*/ -void tunhunt_state::set_pens() -{ -/* - The actual contents of the color proms (unused by this driver) - are as follows: - - D11 "blue/green" - 0000: 00 00 8b 0b fb 0f ff 0b - 00 00 0f 0f fb f0 f0 ff - - C11 "red" - 0020: 00 f0 f0 f0 b0 b0 00 f0 - 00 f0 f0 00 b0 00 f0 f0 -*/ - //const uint8_t *color_prom = memregion( "proms" )->base(); - int color; - int shade; - int red,green,blue; - - for( int i=0; i<16; i++ ) - { - color = m_generic_paletteram_8[i]; - shade = 0xf^(color>>4); - - color &= 0xf; /* hue select */ - switch( color ) - { - default: - case 0x0: red = 0xff; green = 0xff; blue = 0xff; break; /* white */ - case 0x1: red = 0xff; green = 0x00; blue = 0xff; break; /* purple */ - case 0x2: red = 0x00; green = 0x00; blue = 0xff; break; /* blue */ - case 0x3: red = 0x00; green = 0xff; blue = 0xff; break; /* cyan */ - case 0x4: red = 0x00; green = 0xff; blue = 0x00; break; /* green */ - case 0x5: red = 0xff; green = 0xff; blue = 0x00; break; /* yellow */ - case 0x6: red = 0xff; green = 0x00; blue = 0x00; break; /* red */ - case 0x7: red = 0x00; green = 0x00; blue = 0x00; break; /* black? */ - - case 0x8: red = 0xff; green = 0x7f; blue = 0x00; break; /* orange */ - case 0x9: red = 0x7f; green = 0xff; blue = 0x00; break; /* ? */ - case 0xa: red = 0x00; green = 0xff; blue = 0x7f; break; /* ? */ - case 0xb: red = 0x00; green = 0x7f; blue = 0xff; break; /* ? */ - case 0xc: red = 0xff; green = 0x00; blue = 0x7f; break; /* ? */ - case 0xd: red = 0x7f; green = 0x00; blue = 0xff; break; /* ? */ - case 0xe: red = 0xff; green = 0xaa; blue = 0xaa; break; /* ? */ - case 0xf: red = 0xaa; green = 0xaa; blue = 0xff; break; /* ? */ - } - - /* combine color components with shade value (0..0xf) */ - #define APPLY_SHADE( C,S ) ((C*S)/0xf) - red = APPLY_SHADE(red,shade); - green = APPLY_SHADE(green,shade); - blue = APPLY_SHADE(blue,shade); - - m_palette->set_indirect_color( i,rgb_t(red,green,blue) ); - } -} - -void tunhunt_state::draw_motion_object(bitmap_ind16 &bitmap, const rectangle &cliprect) -{ -/* - * VSTRLO 0x1202 - * normally 0x02 (gameplay, attract1) - * in attract2 (with "Tunnel Hunt" graphic), decrements from 0x2f down to 0x01 - * goes to 0x01 for some enemy shots - * - * MOBSC0 0x1080 - * MOBSC1 0x1081 - * always 0x00? - */ - - bitmap_ind16 &tmpbitmap = m_tmpbitmap; - //int skip = m_mobst; - const int x0 = 255 - m_mobjv; - const int y0 = 255 - m_mobjh; - - for (int line = 0; line < 64; line++) - { - int x = 0; - const uint8_t *const source = &m_spriteram[line * 0x10]; - for (int span = 0; span < 0x10; span++) - { - const int span_data = source[span]; - if (span_data == 0xff) break; - const int color = ((span_data >> 6) & 0x3) ^ 0x3; - int count = (span_data & 0x1f) + 1; - while (count-- && x < 256) - tmpbitmap.pix(line, x++) = color; - } - while (x < 256) - tmpbitmap.pix(line, x++) = 0; - } - - int scaley; - switch (m_vstrlo) - { - case 0x01: - scaley = (1 << 16) * 0.33; // seems correct - break; - - case 0x02: - scaley = (1 << 16) * 0.50; // seems correct - break; - - default: - scaley = (1 << 16) * m_vstrlo / 4; // ??? - break; - } - const int scalex = 1 << 16; - - copyrozbitmap_trans( - bitmap, cliprect, tmpbitmap, - -x0 * scalex, // startx - -y0 * scaley, // starty - scalex, // incxx - 0, 0, // incxy, incyx - scaley, // incyy - false, // no wraparound - 0); -} - -void tunhunt_state::draw_box(bitmap_ind16 &bitmap, const rectangle &cliprect) -{ -/* - This is unnecessarily slow, but the box priorities aren't completely understood, - yet. Once understood, this function should be converted to use bitmap_fill with - rectangular chunks instead of BITMAP_ADDR. - - Tunnels: - 1080: 00 00 00 01 e7 18 ae 51 94 6b 88 77 83 7c 80 7f x0 - 1480: 00 f0 17 00 22 22 5b 5b 75 75 81 81 86 86 89 89 y0 - 1400: 00 00 97 ff f1 f1 b8 b8 9e 9e 92 92 8d 8d 8a 8a y1 - 1280: 07 03 00 07 07 0c 0c 0d 0d 0e 0e 08 08 09 09 0a palette select - - Color Bars: - 1080: 00 00 00 01 00 20 40 60 80 a0 c0 e0 01 2a 50 7a x0 - 1480: 00 f0 00 00 40 40 40 40 40 40 40 40 00 00 00 00 y0 - 1400: 00 00 00 ff ff ff ff ff ff ff ff ff 40 40 40 40 y1 - 1280: 07 03 00 01 07 06 04 05 02 07 03 00 09 0a 0b 0c palette select - ->hue 06 02 ff 60 06 05 03 04 01 06 02 ff d2 00 c2 ff -*/ - int span,x,y; - int color; -// rectangle bbox; - int z; - int x0,y0,y1; - - for( y=0; y<256; y++ ) - { - if (0xff-y >= cliprect.top() && 0xff-y <= cliprect.bottom()) - for( x=0; x<256; x++ ) - { - color = 0; - z = 0; - for( span=0; span<13; span++ ) - { - x0 = m_lineh[span]; - y0 = m_linevs[span]; - y1 = m_linev[span]; - - if( y>=y0 && y<=y1 && x>=x0 && x0>=z ) - { - color = m_linec[span]&0xf; - z = x0; /* give priority to rightmost spans */ - } - } - if (x >= cliprect.left() && x <= cliprect.right()) - bitmap.pix(0xff-y, x) = color; - } - } -} - -/* "shell" graphics are 16x16 pixel tiles used for player shots and targeting cursor */ -void tunhunt_state::draw_shell(bitmap_ind16 &bitmap, - const rectangle &cliprect, - int picture_code, - int hposition, - int vstart, - int vstop, - int vstretch, - int hstretch ) -{ - if( hstretch ) - { - int sx,sy; - for( sx=0; sx<256; sx+=16 ) - { - for( sy=0; sy<256; sy+=16 ) - { - m_gfxdecode->gfx(1)->transpen(bitmap,cliprect, - picture_code, - 0, /* color */ - 0,0, /* flip */ - sx,sy,0 ); - } - } - } - else - /* - vstretch is normally 0x01 - - targeting cursor: - hposition = 0x78 - vstart = 0x90 - vstop = 0x80 - - during grid test: - vstretch = 0xff - hposition = 0xff - vstart = 0xff - vstop = 0x00 - - */ - - m_gfxdecode->gfx(1)->transpen(bitmap,cliprect, - picture_code, - 0, /* color */ - 0,0, /* flip */ - 255-hposition-16,vstart-32,0 ); -} - -uint32_t tunhunt_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - set_pens(); - - draw_box(bitmap, cliprect); - - draw_motion_object(bitmap, cliprect); - - draw_shell(bitmap, cliprect, - m_shl0pc, /* picture code */ - m_shel0h, /* hposition */ - m_shl0v, /* vstart */ - m_shl0vs, /* vstop */ - m_shl0st, /* vstretch */ - m_control&0x08 ); /* hstretch */ - - draw_shell(bitmap, cliprect, - m_shl1pc, /* picture code */ - m_shel1h, /* hposition */ - m_shl1v, /* vstart */ - m_shl1vs, /* vstop */ - m_shl1st, /* vstretch */ - m_control&0x10 ); /* hstretch */ - - rectangle cr = cliprect; - if( cr.min_x < 192 ) - cr.min_x = 192; - - m_fg_tilemap->draw(screen, bitmap, cr, 0, 0); - return 0; -} diff --git a/src/mame/atari/videopin.cpp b/src/mame/atari/videopin.cpp index 83580fc733c..7bb999b8527 100644 --- a/src/mame/atari/videopin.cpp +++ b/src/mame/atari/videopin.cpp @@ -1,5 +1,6 @@ // license:BSD-3-Clause // copyright-holders:Sebastien Monassa + /************************************************************************* Atari Video Pinball driver @@ -18,19 +19,177 @@ *************************************************************************/ #include "emu.h" -#include "videopin.h" + +#include "videopin_a.h" #include "cpu/m6502/m6502.h" #include "machine/watchdog.h" #include "sound/discrete.h" + +#include "emupal.h" +#include "screen.h" #include "speaker.h" +#include "tilemap.h" #include "videopin.lh" +namespace { + +class videopin_state : public driver_device +{ +public: + videopin_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_discrete(*this, "discrete"), + m_gfxdecode(*this, "gfxdecode"), + m_screen(*this, "screen"), + m_palette(*this, "palette"), + m_video_ram(*this, "video_ram"), + m_in(*this, "IN%u", 1U), + m_leds(*this, "LED%02u", 1U) + { } + + void videopin(machine_config &config); + +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + virtual void video_start() override; + +private: + required_device m_maincpu; + required_device m_discrete; + required_device m_gfxdecode; + required_device m_screen; + required_device m_palette; + + required_shared_ptr m_video_ram; + required_ioport_array<2> m_in; + output_finder<32> m_leds; + + attotime m_time_pushed; + attotime m_time_released; + uint8_t m_prev = 0; + uint8_t m_mask = 0; + uint8_t m_ball_x = 0; + uint8_t m_ball_y = 0; + tilemap_t *m_bg_tilemap = nullptr; + emu_timer *m_interrupt_timer = nullptr; + + void main_map(address_map &map); + + uint8_t misc_r(); + void led_w(uint8_t data); + void ball_w(uint8_t data); + void video_ram_w(offs_t offset, uint8_t data); + void out1_w(uint8_t data); + void out2_w(uint8_t data); + void note_dvsr_w(uint8_t data); + + TILEMAP_MAPPER_MEMBER(get_memory_offset); + TILE_GET_INFO_MEMBER(get_tile_info); + + uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + + TIMER_CALLBACK_MEMBER(interrupt_callback); + void update_plunger(); + double calc_plunger_pos(); +}; + + +// video + +TILEMAP_MAPPER_MEMBER(videopin_state::get_memory_offset) +{ + return num_rows * ((col + 16) % 48) + row; +} + + +TILE_GET_INFO_MEMBER(videopin_state::get_tile_info) +{ + uint8_t const code = m_video_ram[tile_index]; + + tileinfo.set(0, code, 0, (code & 0x40) ? TILE_FLIPY : 0); +} + + +void videopin_state::video_start() +{ + m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(videopin_state::get_tile_info)), tilemap_mapper_delegate(*this, FUNC(videopin_state::get_memory_offset)), 8, 8, 48, 32); + + save_item(NAME(m_ball_x)); + save_item(NAME(m_ball_y)); +} + + +uint32_t videopin_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + m_bg_tilemap->set_scrollx(0, -8); // account for delayed loading of shift reg C6 + + m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0); + + for (int row = 0; row < 32; row++) + { + for (int col = 0; col < 48; col++) + { + uint32_t const offset = m_bg_tilemap->memory_index(col, row); + + if (m_video_ram[offset] & 0x80) // ball bit found + { + int x = 8 * col; + int y = 8 * row; + + x += 4; // account for delayed loading of flip-flop C4 + + rectangle rect(x, x + 15, y, y + 15); + rect &= cliprect; + + x -= m_ball_x; + y -= m_ball_y; + + // ball placement is still 0.5 pixels off but don't tell anyone + + for (int i = 0; i < 2; i++) + { + for (int j = 0; j < 2; j++) + { + m_gfxdecode->gfx(1)->transpen(bitmap, rect, + 0, 0, + 0, 0, + x + 16 * i, + y + 16 * j, 0); + } + } + + return 0; // keep things simple and ignore the rest + } + } + } + return 0; +} + + +void videopin_state::ball_w(uint8_t data) +{ + m_ball_x = data & 15; + m_ball_y = data >> 4; +} + + +void videopin_state::video_ram_w(offs_t offset, uint8_t data) +{ + m_video_ram[offset] = data; + m_bg_tilemap->mark_tile_dirty(offset); +} + + +// machine + void videopin_state::update_plunger() { - uint8_t val = ioport("IN2")->read(); + uint8_t const val = m_in[1]->read(); if (m_prev != val) { @@ -82,7 +241,7 @@ void videopin_state::machine_reset() { m_interrupt_timer->adjust(m_screen->time_until_pos(32), 32); - /* both output latches are cleared on reset */ + // both output latches are cleared on reset out1_w(0); out2_w(0); @@ -108,15 +267,15 @@ uint8_t videopin_state::misc_r() // signals received. This results in the MPU displaying the // ball being shot onto the playfield at a certain speed. - uint8_t val = ioport("IN1")->read(); + uint8_t val = m_in[0]->read(); if (plunger >= 0.000 && plunger <= 0.001) { - val &= ~1; /* PLUNGER1 */ + val &= ~1; // PLUNGER1 } if (plunger >= 0.006 && plunger <= 0.007) { - val &= ~2; /* PLUNGER2 */ + val &= ~2; // PLUNGER2 } return val; @@ -140,7 +299,7 @@ void videopin_state::led_w(uint8_t data) }; // anode from 32V,64V,128V - int a = m_screen->vpos() >> 5 & 7; + int const a = m_screen->vpos() >> 5 & 7; for (int c = 0; c < 4; c++) m_leds[matrix[a][c] - 1] = BIT(data, c); @@ -151,14 +310,14 @@ void videopin_state::led_w(uint8_t data) void videopin_state::out1_w(uint8_t data) { - /* D0 => OCTAVE0 */ - /* D1 => OCTACE1 */ - /* D2 => OCTAVE2 */ - /* D3 => LOCKOUT */ - /* D4 => NMIMASK */ - /* D5 => NOT USED */ - /* D6 => NOT USED */ - /* D7 => NOT USED */ + // D0 => OCTAVE0 + // D1 => OCTACE1 + // D2 => OCTAVE2 + // D3 => LOCKOUT + // D4 => NMIMASK + // D5 => NOT USED + // D6 => NOT USED + // D7 => NOT USED m_mask = ~data & 0x10; @@ -167,21 +326,21 @@ void videopin_state::out1_w(uint8_t data) machine().bookkeeping().coin_lockout_global_w(~data & 0x08); - /* Convert octave data to divide value and write to sound */ + // Convert octave data to divide value and write to sound m_discrete->write(VIDEOPIN_OCTAVE_DATA, (0x01 << (~data & 0x07)) & 0xfe); } void videopin_state::out2_w(uint8_t data) { - /* D0 => VOL0 */ - /* D1 => VOL1 */ - /* D2 => VOL2 */ - /* D3 => NOT USED */ - /* D4 => COIN CNTR */ - /* D5 => BONG */ - /* D6 => BELL */ - /* D7 => ATTRACT */ + // D0 => VOL0 + // D1 => VOL1 + // D2 => VOL2 + // D3 => NOT USED + // D4 => COIN CNTR + // D5 => BONG + // D6 => BELL + // D7 => ATTRACT machine().bookkeeping().coin_counter_w(0, data & 0x10); @@ -194,7 +353,7 @@ void videopin_state::out2_w(uint8_t data) void videopin_state::note_dvsr_w(uint8_t data) { - /* note data */ + // note data m_discrete->write(VIDEOPIN_NOTE_DATA, ~data &0xff); } @@ -208,7 +367,7 @@ void videopin_state::note_dvsr_w(uint8_t data) void videopin_state::main_map(address_map &map) { map(0x0000, 0x01ff).ram(); - map(0x0200, 0x07ff).ram().w(FUNC(videopin_state::video_ram_w)).share("video_ram"); + map(0x0200, 0x07ff).ram().w(FUNC(videopin_state::video_ram_w)).share(m_video_ram); map(0x0800, 0x0800).r(FUNC(videopin_state::misc_r)).w(FUNC(videopin_state::note_dvsr_w)); map(0x0801, 0x0801).w(FUNC(videopin_state::led_w)); map(0x0802, 0x0802).w("watchdog", FUNC(watchdog_timer_device::reset_w)); @@ -229,7 +388,7 @@ void videopin_state::main_map(address_map &map) *************************************/ static INPUT_PORTS_START( videopin ) - PORT_START("IN0") /* IN0 */ + PORT_START("IN0") // IN0 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Left Flipper") PORT_CODE(KEYCODE_LCONTROL) @@ -239,7 +398,7 @@ static INPUT_PORTS_START( videopin ) PORT_SERVICE( 0x40, IP_ACTIVE_LOW ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_START("DSW") /* IN1 */ + PORT_START("DSW") // IN1 PORT_DIPNAME( 0xc0, 0x80, DEF_STR( Coinage ) ) PORT_DIPLOCATION("DSW:8,7") PORT_DIPSETTING( 0xc0, DEF_STR( 2C_1C ) ) PORT_DIPSETTING( 0x80, DEF_STR( 1C_1C ) ) @@ -263,9 +422,9 @@ static INPUT_PORTS_START( videopin ) PORT_DIPSETTING( 0x00, "180000 (3 balls) / 300000 (5 balls)" ) PORT_DIPSETTING( 0x01, "210000 (3 balls) / 350000 (5 balls)" ) - PORT_START("IN1") /* IN2 */ - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_CUSTOM ) /* PLUNGER 1 */ - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_CUSTOM ) /* PLUNGER 2 */ + PORT_START("IN1") // IN2 + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_CUSTOM ) // PLUNGER 1 + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_CUSTOM ) // PLUNGER 2 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) @@ -298,22 +457,6 @@ INPUT_PORTS_END * *************************************/ -static const gfx_layout tile_layout = -{ - 8, 8, - 64, - 1, - { 0 }, - { - 0, 1, 2, 3, 4, 5, 6, 7 - }, - { - 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38 - }, - 0x40 -}; - - static const gfx_layout ball_layout = { 16, 16, @@ -334,8 +477,8 @@ static const gfx_layout ball_layout = static GFXDECODE_START( gfx_videopin ) - GFXDECODE_ENTRY( "gfx1", 0x0000, tile_layout, 0, 1 ) - GFXDECODE_ENTRY( "gfx2", 0x0000, ball_layout, 0, 1 ) + GFXDECODE_ENTRY( "tiles", 0x0000, gfx_8x8x1, 0, 1 ) + GFXDECODE_ENTRY( "ball", 0x0000, ball_layout, 0, 1 ) GFXDECODE_END @@ -348,13 +491,13 @@ GFXDECODE_END void videopin_state::videopin(machine_config &config) { - /* basic machine hardware */ - M6502(config, m_maincpu, 12096000 / 16); + // basic machine hardware + M6502(config, m_maincpu, 12'096'000 / 16); m_maincpu->set_addrmap(AS_PROGRAM, &videopin_state::main_map); WATCHDOG_TIMER(config, "watchdog"); - /* video hardware */ + // video hardware SCREEN(config, m_screen, SCREEN_TYPE_RASTER); m_screen->set_refresh_hz(60); m_screen->set_size(304, 263); @@ -366,7 +509,7 @@ void videopin_state::videopin(machine_config &config) PALETTE(config, m_palette, palette_device::MONOCHROME); - /* sound hardware */ + // sound hardware SPEAKER(config, "mono").front_center(); DISCRETE(config, m_discrete, videopin_discrete).add_route(ALL_OUTPUTS, "mono", 1.0); @@ -403,15 +546,15 @@ ROM_START( videopin ) ROM_LOAD_NIB_HIGH( "34241-01.f0", 0x3c00, 0x0400, CRC(5bfb83da) SHA1(9f392b0d4a972b6ae15ec12913a7e66761f4175d) ) ROM_RELOAD( 0xfc00, 0x0400 ) - ROM_REGION( 0x0200, "gfx1", 0 ) /* tiles */ + ROM_REGION( 0x0200, "tiles", 0 ) ROM_LOAD_NIB_LOW ( "34259-01.d5", 0x0000, 0x0200, CRC(6cd98c06) SHA1(48bf077b7abbd2f529a19bdf85700b93014f39f9) ) ROM_LOAD_NIB_HIGH( "34258-01.c5", 0x0000, 0x0200, CRC(91a5f117) SHA1(03ac6b0b3da0ed5faf1ba6695d16918d12ceeff5) ) - ROM_REGION( 0x0020, "gfx2", 0 ) /* ball */ + ROM_REGION( 0x0020, "ball", 0 ) ROM_LOAD( "34257-01.m1", 0x0000, 0x0020, CRC(50245866) SHA1(b0692bc8d44f127f6e7182a1ce75a785e22ac5b9) ) - ROM_REGION( 0x0100, "proms", 0 ) - ROM_LOAD( "9402-01.h4", 0x0000, 0x0100, CRC(b8094b4c) SHA1(82dc6799a19984f3b204ee3aeeb007e55afc8be3) ) /* sync */ + ROM_REGION( 0x0100, "sync_prom", 0 ) + ROM_LOAD( "9402-01.h4", 0x0000, 0x0100, CRC(b8094b4c) SHA1(82dc6799a19984f3b204ee3aeeb007e55afc8be3) ) ROM_END // This is an even later revision (marked -02) with 4 EPROMs (4096x8 according to manual, while 2048x8 in reality) @@ -423,15 +566,15 @@ ROM_START( videopina ) ROM_LOAD( "034256-01.k2", 0x3800, 0x0800, CRC(9f24428c) SHA1(df35225afebb4cc18a593ec665e94f677b3606ee) ) ROM_COPY( "maincpu" , 0x3c00, 0xfc00, 0x400 ) - ROM_REGION( 0x0200, "gfx1", 0 ) // tiles + ROM_REGION( 0x0200, "tiles", 0 ) ROM_LOAD_NIB_LOW ( "34259-01.d5", 0x0000, 0x0200, CRC(6cd98c06) SHA1(48bf077b7abbd2f529a19bdf85700b93014f39f9) ) ROM_LOAD_NIB_HIGH( "34258-01.c5", 0x0000, 0x0200, CRC(91a5f117) SHA1(03ac6b0b3da0ed5faf1ba6695d16918d12ceeff5) ) - ROM_REGION( 0x0020, "gfx2", 0 ) // ball + ROM_REGION( 0x0020, "ball", 0 ) ROM_LOAD( "34257-01.m1", 0x0000, 0x0020, CRC(50245866) SHA1(b0692bc8d44f127f6e7182a1ce75a785e22ac5b9) ) - ROM_REGION( 0x0100, "proms", 0 ) - ROM_LOAD( "9402-01.h4", 0x0000, 0x0100, CRC(b8094b4c) SHA1(82dc6799a19984f3b204ee3aeeb007e55afc8be3) ) // sync + ROM_REGION( 0x0100, "sync_prom", 0 ) + ROM_LOAD( "9402-01.h4", 0x0000, 0x0100, CRC(b8094b4c) SHA1(82dc6799a19984f3b204ee3aeeb007e55afc8be3) ) ROM_END ROM_START( solarwar ) @@ -455,17 +598,19 @@ ROM_START( solarwar ) ROM_LOAD_NIB_HIGH( "36158-02.f0", 0x3c00, 0x0400, CRC(2606b87e) SHA1(ea72e36837eccf29cd5c82fe9a6a018a1a94730c) ) ROM_RELOAD( 0xfc00, 0x0400 ) - ROM_REGION( 0x0200, "gfx1", 0 ) /* tiles */ + ROM_REGION( 0x0200, "tiles", 0 ) ROM_LOAD_NIB_LOW ( "34259-01.d5", 0x0000, 0x0200, CRC(6cd98c06) SHA1(48bf077b7abbd2f529a19bdf85700b93014f39f9) ) ROM_LOAD_NIB_HIGH( "34258-01.c5", 0x0000, 0x0200, CRC(91a5f117) SHA1(03ac6b0b3da0ed5faf1ba6695d16918d12ceeff5) ) - ROM_REGION( 0x0020, "gfx2", 0 ) /* ball */ + ROM_REGION( 0x0020, "ball", 0 ) ROM_LOAD( "34257-01.m1", 0x0000, 0x0020, CRC(50245866) SHA1(b0692bc8d44f127f6e7182a1ce75a785e22ac5b9) ) - ROM_REGION( 0x0100, "proms", 0 ) - ROM_LOAD( "9402-01.h4", 0x0000, 0x0100, CRC(b8094b4c) SHA1(82dc6799a19984f3b204ee3aeeb007e55afc8be3) ) /* sync */ + ROM_REGION( 0x0100, "sync_prom", 0 ) + ROM_LOAD( "9402-01.h4", 0x0000, 0x0100, CRC(b8094b4c) SHA1(82dc6799a19984f3b204ee3aeeb007e55afc8be3) ) ROM_END +} // anonymous namespace + /************************************* * @@ -474,5 +619,5 @@ ROM_END *************************************/ GAMEL( 1979, videopin, 0, videopin, videopin, videopin_state, empty_init, ROT270, "Atari", "Video Pinball (16 PROMs version)", MACHINE_SUPPORTS_SAVE | MACHINE_REQUIRES_ARTWORK, layout_videopin ) -GAMEL( 1979, videopina, videopin, videopin, videopin, videopin_state, empty_init, ROT270, "Atari", "Video Pinball (4 ROMs version)", MACHINE_SUPPORTS_SAVE | MACHINE_REQUIRES_ARTWORK, layout_videopin ) -GAMEL( 1979, solarwar, 0, videopin, solarwar, videopin_state, empty_init, ROT270, "Atari", "Solar War", MACHINE_SUPPORTS_SAVE | MACHINE_REQUIRES_ARTWORK, layout_videopin ) +GAMEL( 1979, videopina, videopin, videopin, videopin, videopin_state, empty_init, ROT270, "Atari", "Video Pinball (4 ROMs version)", MACHINE_SUPPORTS_SAVE | MACHINE_REQUIRES_ARTWORK, layout_videopin ) +GAMEL( 1979, solarwar, 0, videopin, solarwar, videopin_state, empty_init, ROT270, "Atari", "Solar War", MACHINE_SUPPORTS_SAVE | MACHINE_REQUIRES_ARTWORK, layout_videopin ) diff --git a/src/mame/atari/videopin.h b/src/mame/atari/videopin.h deleted file mode 100644 index b118ab5476f..00000000000 --- a/src/mame/atari/videopin.h +++ /dev/null @@ -1,90 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Sebastien Monassa -/************************************************************************* - - Atari Video Pinball hardware - -*************************************************************************/ -#ifndef MAME_ATARI_VIDEOPIN_H -#define MAME_ATARI_VIDEOPIN_H - -#pragma once - -#include "sound/discrete.h" -#include "emupal.h" -#include "screen.h" -#include "tilemap.h" - -/* Discrete Sound Input Nodes */ -#define VIDEOPIN_OCTAVE_DATA NODE_01 -#define VIDEOPIN_NOTE_DATA NODE_02 -#define VIDEOPIN_BELL_EN NODE_03 -#define VIDEOPIN_BONG_EN NODE_04 -#define VIDEOPIN_ATTRACT_EN NODE_05 -#define VIDEOPIN_VOL_DATA NODE_06 - - -class videopin_state : public driver_device -{ -public: - videopin_state(const machine_config &mconfig, device_type type, const char *tag) : - driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_discrete(*this, "discrete"), - m_gfxdecode(*this, "gfxdecode"), - m_screen(*this, "screen"), - m_palette(*this, "palette"), - m_video_ram(*this, "video_ram"), - m_leds(*this, "LED%02u", 1U) - { } - - void videopin(machine_config &config); - -protected: - virtual void machine_start() override; - virtual void machine_reset() override; - virtual void video_start() override; - -private: - void main_map(address_map &map); - - uint8_t misc_r(); - void led_w(uint8_t data); - void ball_w(uint8_t data); - void video_ram_w(offs_t offset, uint8_t data); - void out1_w(uint8_t data); - void out2_w(uint8_t data); - void note_dvsr_w(uint8_t data); - - TILEMAP_MAPPER_MEMBER(get_memory_offset); - TILE_GET_INFO_MEMBER(get_tile_info); - - uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - - TIMER_CALLBACK_MEMBER(interrupt_callback); - void update_plunger(); - double calc_plunger_pos(); - - required_device m_maincpu; - required_device m_discrete; - required_device m_gfxdecode; - required_device m_screen; - required_device m_palette; - - required_shared_ptr m_video_ram; - output_finder<32> m_leds; - - attotime m_time_pushed; - attotime m_time_released; - uint8_t m_prev = 0; - uint8_t m_mask = 0; - int m_ball_x = 0; - int m_ball_y = 0; - tilemap_t* m_bg_tilemap = nullptr; - emu_timer *m_interrupt_timer = nullptr; -}; - -/*----------- defined in audio/videopin.c -----------*/ -DISCRETE_SOUND_EXTERN( videopin_discrete ); - -#endif // MAME_ATARI_VIDEOPIN_H diff --git a/src/mame/atari/videopin_a.cpp b/src/mame/atari/videopin_a.cpp index a253243c242..ab615af0a16 100644 --- a/src/mame/atari/videopin_a.cpp +++ b/src/mame/atari/videopin_a.cpp @@ -1,14 +1,14 @@ // license:BSD-3-Clause // copyright-holders:Derrick Renaud + /************************************************************************* - audio\videopin.c + atari\videopin_a.cpp *************************************************************************/ #include "emu.h" -#include "videopin.h" -#include "sound/discrete.h" +#include "videopin_a.h" /************************************************************************/ /* videopin Sound System Analog emulation */ @@ -22,7 +22,7 @@ DISCRETE_SOUND_START(videopin_discrete) /************************************************/ - /* videopin Effects Relataive Gain Table */ + /* videopin Effects Relative Gain Table */ /* */ /* Effect V-ampIn Gain ratio Relative */ /* Vol0 3.8 10/(10+50) 1000.0 */ @@ -83,11 +83,11 @@ DISCRETE_SOUND_START(videopin_discrete) /************************************************/ /* Bell is Hsync/16 with an R/C decay amplitude */ - /* the 1uF cap is rapidally charged when BELL */ - /* is enabled, then dischaged through the 1M */ + /* the 1uF cap is rapidly charged when BELL */ + /* is enabled, then discharged through the 1M */ /* resistor when disabled. */ /* We use 180 phase because of inverter Q17, */ - /* but it rally has no effect on sound. */ + /* but it really has no effect on sound. */ /************************************************/ DISCRETE_RCDISC2(NODE_30, VIDEOPIN_BELL_EN, 740.2, 1, 0, 1e6, 1e-6) DISCRETE_SQUAREWFIX(VIDEOPIN_BELL_SND, VIDEOPIN_BELL_EN, 15750.0/16.0, NODE_30, 50.0, 0, 180.0) diff --git a/src/mame/atari/videopin_a.h b/src/mame/atari/videopin_a.h new file mode 100644 index 00000000000..12eb7998f03 --- /dev/null +++ b/src/mame/atari/videopin_a.h @@ -0,0 +1,22 @@ +// license:BSD-3-Clause +// copyright-holders:Derrick Renaud + +/*************************************************************************** + +Video Pinball Audio + +***************************************************************************/ + +#include "sound/discrete.h" + +// discrete sound input nodes + +#define VIDEOPIN_OCTAVE_DATA NODE_01 +#define VIDEOPIN_NOTE_DATA NODE_02 +#define VIDEOPIN_BELL_EN NODE_03 +#define VIDEOPIN_BONG_EN NODE_04 +#define VIDEOPIN_ATTRACT_EN NODE_05 +#define VIDEOPIN_VOL_DATA NODE_06 + + +DISCRETE_SOUND_EXTERN( videopin_discrete ); diff --git a/src/mame/atari/videopin_v.cpp b/src/mame/atari/videopin_v.cpp deleted file mode 100644 index 543aaa9651b..00000000000 --- a/src/mame/atari/videopin_v.cpp +++ /dev/null @@ -1,103 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Sebastien Monassa -/************************************************************************* - - Atari Video Pinball video emulation - -*************************************************************************/ - -#include "emu.h" -#include "videopin.h" - - - - - -TILEMAP_MAPPER_MEMBER(videopin_state::get_memory_offset) -{ - return num_rows * ((col + 16) % 48) + row; -} - - -TILE_GET_INFO_MEMBER(videopin_state::get_tile_info) -{ - uint8_t code = m_video_ram[tile_index]; - - tileinfo.set(0, code, 0, (code & 0x40) ? TILE_FLIPY : 0); -} - - -void videopin_state::video_start() -{ - m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(videopin_state::get_tile_info)), tilemap_mapper_delegate(*this, FUNC(videopin_state::get_memory_offset)), 8, 8, 48, 32); - - save_item(NAME(m_ball_x)); - save_item(NAME(m_ball_y)); -} - - -uint32_t videopin_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - int col; - int row; - - m_bg_tilemap->set_scrollx(0, -8); /* account for delayed loading of shift reg C6 */ - - m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0); - - for (row = 0; row < 32; row++) - { - for (col = 0; col < 48; col++) - { - uint32_t offset = m_bg_tilemap->memory_index(col, row); - - if (m_video_ram[offset] & 0x80) /* ball bit found */ - { - int x = 8 * col; - int y = 8 * row; - - int i; - int j; - - x += 4; /* account for delayed loading of flip-flop C4 */ - - rectangle rect(x, x + 15, y, y + 15); - rect &= cliprect; - - x -= m_ball_x; - y -= m_ball_y; - - /* ball placement is still 0.5 pixels off but don't tell anyone */ - - for (i = 0; i < 2; i++) - { - for (j = 0; j < 2; j++) - { - m_gfxdecode->gfx(1)->transpen(bitmap,rect, - 0, 0, - 0, 0, - x + 16 * i, - y + 16 * j, 0); - } - } - - return 0; /* keep things simple and ignore the rest */ - } - } - } - return 0; -} - - -void videopin_state::ball_w(uint8_t data) -{ - m_ball_x = data & 15; - m_ball_y = data >> 4; -} - - -void videopin_state::video_ram_w(offs_t offset, uint8_t data) -{ - m_video_ram[offset] = data; - m_bg_tilemap->mark_tile_dirty(offset); -} diff --git a/src/mame/misc/cave.cpp b/src/mame/misc/cave.cpp index 5f87be3c52e..9fcd21b553d 100644 --- a/src/mame/misc/cave.cpp +++ b/src/mame/misc/cave.cpp @@ -82,6 +82,10 @@ Versions known to exist but not dumped: PCBs were shown running (and could be played) at a Cave fan show known as Cave Festival 2006. There are videos of the game being played floating around the internet and on YouTube. AKA DDP-CV or DDP BLUE ROM +NOTE: Easter egg in Fereron SOS / Dangun Feveron: + Insert a coin and with the joystick move: Down, Up, Right, Left, Up, Down, Left, Right + If you did the above right, you'll hear a MEOW sound. Start the game and your ship is now a cat! + ***************************************************************************/ #include "emu.h"