summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/drivers/cdplay.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/drivers/cdplay.cpp')
-rw-r--r--src/mame/drivers/cdplay.cpp273
1 files changed, 273 insertions, 0 deletions
diff --git a/src/mame/drivers/cdplay.cpp b/src/mame/drivers/cdplay.cpp
new file mode 100644
index 00000000000..2247295baa4
--- /dev/null
+++ b/src/mame/drivers/cdplay.cpp
@@ -0,0 +1,273 @@
+// license:BSD-3-Clause
+// copyright-holders:Ryan Holtz
+/***************************************************************************
+
+ cdplay.cpp: Generic CHD-based CD player
+
+****************************************************************************/
+
+#include "emu.h"
+#include "imagedev/chd_cd.h"
+#include "sound/cdda.h"
+#include "sound/vgm_visualizer.h"
+#include "speaker.h"
+
+enum cdplay_inputs : uint8_t
+{
+ CDPLAY_STOP,
+ CDPLAY_PAUSE,
+ CDPLAY_PLAY,
+ CDPLAY_NEXT,
+ CDPLAY_PREV,
+ CDPLAY_VIZ,
+};
+
+class cdplay_state : public driver_device
+{
+public:
+ cdplay_state(const machine_config &mconfig, device_type type, const char *tag)
+ : driver_device(mconfig, type, tag)
+ , m_cdda(*this, "cdda")
+ , m_cdrom(*this, "cdrom")
+ , m_visualizer(*this, "visualizer")
+ { }
+
+ void cdplay(machine_config &config);
+
+ DECLARE_INPUT_CHANGED_MEMBER(key_pressed);
+
+private:
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+
+ static constexpr device_timer_id TIMER_DISK_CHECK = 0;
+
+ void next_track();
+ void prev_track();
+ void set_track(int track);
+ void play_track(int track);
+ void play();
+ void stop();
+ void pause();
+
+ required_device<cdda_device> m_cdda;
+ required_device<cdrom_image_device> m_cdrom;
+ required_device<vgmviz_device> m_visualizer;
+
+ int m_track;
+ int m_max_track;
+ bool m_playing;
+ cdrom_file *m_file;
+ emu_timer *m_disk_check_timer;
+};
+
+static INPUT_PORTS_START( cdplay )
+ PORT_START("CONTROLS")
+ PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_CHANGED_MEMBER(DEVICE_SELF, cdplay_state, key_pressed, CDPLAY_STOP) PORT_CODE(KEYCODE_Z) PORT_NAME("Stop")
+ PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_CHANGED_MEMBER(DEVICE_SELF, cdplay_state, key_pressed, CDPLAY_PAUSE) PORT_CODE(KEYCODE_X) PORT_NAME("Pause")
+ PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_BUTTON3) PORT_CHANGED_MEMBER(DEVICE_SELF, cdplay_state, key_pressed, CDPLAY_PLAY) PORT_CODE(KEYCODE_C) PORT_NAME("Play")
+ PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_BUTTON4) PORT_CHANGED_MEMBER(DEVICE_SELF, cdplay_state, key_pressed, CDPLAY_NEXT) PORT_CODE(KEYCODE_A) PORT_NAME("Next Track")
+ PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_BUTTON5) PORT_CHANGED_MEMBER(DEVICE_SELF, cdplay_state, key_pressed, CDPLAY_PREV) PORT_CODE(KEYCODE_S) PORT_NAME("Previous Track")
+ PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_BUTTON6) PORT_CHANGED_MEMBER(DEVICE_SELF, cdplay_state, key_pressed, CDPLAY_VIZ) PORT_CODE(KEYCODE_D) PORT_NAME("Visualization Mode")
+INPUT_PORTS_END
+
+void cdplay_state::machine_start()
+{
+ save_item(NAME(m_track));
+ save_item(NAME(m_max_track));
+ save_item(NAME(m_playing));
+
+ m_disk_check_timer = timer_alloc(TIMER_DISK_CHECK);
+}
+
+void cdplay_state::machine_reset()
+{
+ m_track = -1;
+ m_max_track = -1;
+ m_playing = false;
+ m_file = nullptr;
+
+ m_disk_check_timer->adjust(attotime::from_msec(100), 0, attotime::from_msec(100));
+}
+
+void cdplay_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+ if (id == TIMER_DISK_CHECK)
+ {
+ cdrom_file *new_file = m_cdrom->get_cdrom_file();
+ if (m_file != new_file)
+ {
+ if (new_file == nullptr && m_playing)
+ {
+ m_cdda->stop_audio();
+ m_cdda->set_cdrom(nullptr);
+ }
+
+ m_track = -1;
+ m_max_track = -1;
+ m_playing = false;
+
+ if (new_file != nullptr)
+ {
+ m_max_track = cdrom_get_last_track(new_file);
+ printf("New file found, max track is %d\n", m_max_track);
+ m_file = new_file;
+ m_cdda->set_cdrom(m_file);
+ }
+ }
+ }
+}
+
+INPUT_CHANGED_MEMBER(cdplay_state::key_pressed)
+{
+ if (!newval)
+ return;
+
+ switch (param)
+ {
+ case CDPLAY_STOP:
+ stop();
+ break;
+ case CDPLAY_PAUSE:
+ pause();
+ break;
+ case CDPLAY_PLAY:
+ play();
+ break;
+ case CDPLAY_NEXT:
+ next_track();
+ break;
+ case CDPLAY_PREV:
+ prev_track();
+ break;
+ case CDPLAY_VIZ:
+ m_visualizer->cycle_viz_mode();
+ break;
+ }
+}
+
+void cdplay_state::next_track()
+{
+ if (m_file == nullptr)
+ {
+ return;
+ }
+
+ do
+ {
+ m_track++;
+ if (m_track > m_max_track)
+ {
+ m_track = 0;
+ }
+ } while (cdrom_get_track_type(m_file, m_track) != CD_TRACK_AUDIO);
+ play_track(m_track);
+}
+
+void cdplay_state::prev_track()
+{
+ if (m_file == nullptr)
+ {
+ return;
+ }
+
+ do
+ {
+ m_track--;
+ if (m_track < 0)
+ {
+ m_track = m_max_track;
+ }
+ } while (cdrom_get_track_type(m_file, m_track) != CD_TRACK_AUDIO);
+ play_track(m_track);
+}
+
+void cdplay_state::set_track(int track)
+{
+ m_track = track;
+ if (m_track <= m_max_track)
+ {
+ play_track(m_track);
+ }
+}
+
+void cdplay_state::play_track(int track)
+{
+ const cdrom_toc *toc = cdrom_get_toc(m_file);
+ printf("Playing track %d, start frame %d, length %d frames\n", m_track, toc->tracks[track].chdframeofs, toc->tracks[track].frames);
+ m_cdda->start_audio(toc->tracks[track].chdframeofs, toc->tracks[track].frames);
+}
+
+void cdplay_state::play()
+{
+ if (m_file == nullptr)
+ {
+ return;
+ }
+
+ m_track = 0;
+
+ while (cdrom_get_track_type(m_file, m_track) != CD_TRACK_AUDIO && m_track != m_max_track)
+ {
+ m_track++;
+ }
+
+ if (m_track <= m_max_track)
+ {
+ m_cdda->set_cdrom(m_file);
+ play_track(m_track);
+ m_playing = true;
+ }
+ else
+ {
+ printf("Unable to play this disc; there are no audio tracks present\n");
+ m_track = -1;
+ m_playing = false;
+ }
+}
+
+void cdplay_state::stop()
+{
+ if (m_file == nullptr)
+ {
+ return;
+ }
+
+ m_track = -1;
+ m_playing = false;
+ m_cdda->stop_audio();
+}
+
+void cdplay_state::pause()
+{
+ printf("%s track %d\n", m_playing ? "Pausing" : "Resuming", m_track);
+ m_cdda->pause_audio(m_playing ? 1 : 0);
+ m_playing = !m_playing;
+}
+
+void cdplay_state::cdplay(machine_config &config)
+{
+ /* sound hardware */
+ VGMVIZ(config, m_visualizer, 0);
+ m_visualizer->add_route(0, "lspeaker", 1);
+ m_visualizer->add_route(1, "rspeaker", 1);
+
+ SPEAKER(config, "lspeaker").front_left();
+ SPEAKER(config, "rspeaker").front_right();
+
+ CDDA(config, m_cdda);
+ m_cdda->add_route(0, m_visualizer, 1, AUTO_ALLOC_INPUT, 0);
+ m_cdda->add_route(1, m_visualizer, 1, AUTO_ALLOC_INPUT, 1);
+
+ CDROM(config, m_cdrom, 0);
+ m_cdrom->set_interface("cdplay_cdrom");
+}
+
+ROM_START( cdplay )
+ROM_END
+
+/* Driver */
+
+/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
+CONS( 2020, cdplay, 0, 0, cdplay, cdplay, cdplay_state, empty_init, "MAME", "CD Player", 0 )