From 1af90f923e0d17cd70fc9ee4598a2cb263e54813 Mon Sep 17 00:00:00 2001 From: Ryan Holtz Date: Fri, 1 May 2020 18:59:48 +0200 Subject: -cdplay: Created branch for experimental cd-player driver. [Ryan Holtz] --- scripts/target/mame/virtual.lua | 2 + src/devices/sound/vgm_visualizer.cpp | 16 +- src/devices/sound/vgm_visualizer.h | 2 +- src/mame/drivers/cdplay.cpp | 273 +++++++++++++++++++++++++++++++++++ src/mame/mame.lst | 3 + src/mame/virtual.lst | 1 + 6 files changed, 289 insertions(+), 8 deletions(-) create mode 100644 src/mame/drivers/cdplay.cpp diff --git a/scripts/target/mame/virtual.lua b/scripts/target/mame/virtual.lua index 2c7760fdb7c..6bc4f06bfe5 100644 --- a/scripts/target/mame/virtual.lua +++ b/scripts/target/mame/virtual.lua @@ -26,6 +26,7 @@ CPUS["DSP16"] = true -- for qsound -- only for MAME and so aren't included -------------------------------------------------- +SOUNDS["CDDA"] = true SOUNDS["AY8910"] = true SOUNDS["C140"] = true SOUNDS["C352"] = true @@ -125,6 +126,7 @@ function createProjects_mame_virtual(_target, _subtarget) createVirtualProjects(_target, _subtarget, "virtual") files { MAME_DIR .. "src/mame/drivers/vgmplay.cpp", + MAME_DIR .. "src/mame/drivers/cdplay.cpp", MAME_DIR .. "src/mame/drivers/ldplayer.cpp", MAME_DIR .. "src/mame/machine/mega32x.cpp", MAME_DIR .. "src/mame/machine/mega32x.h", diff --git a/src/devices/sound/vgm_visualizer.cpp b/src/devices/sound/vgm_visualizer.cpp index 129f84c0a5a..60e068c6133 100644 --- a/src/devices/sound/vgm_visualizer.cpp +++ b/src/devices/sound/vgm_visualizer.cpp @@ -168,7 +168,7 @@ void vgmviz_device::apply_waterfall() } int permuted = WDL_fft_permute(FFT_LENGTH / 2, bar); float val = std::max(bins[0][permuted].re, bins[1][permuted].re); - int level = int(log10f(val * 32768.0f) * 95.0f); + int level = int(val * 32768.0f); m_waterfall_buf[m_waterfall_length % SCREEN_WIDTH][total_bars - bar] = (level < 0) ? 0 : (level > 255 ? 255 : level); } m_waterfall_length++; @@ -250,7 +250,7 @@ void vgmviz_device::device_reset() m_waterfall_length = 0; for (int i = 0; i < SCREEN_WIDTH; i++) { - memset(m_waterfall_buf[i], 0, sizeof(int) * 256); + memset(m_waterfall_buf[i], 0, sizeof(float) * 256); } m_viz_mode = VIZ_WAVEFORM; @@ -701,10 +701,12 @@ void vgmviz_device::draw_waterfall(bitmap_rgb32 &bitmap) { const pen_t *pal = m_palette->pens(); float tex_height = ((float)FFT_LENGTH / 2) - 1.0f; + const float log_max = logf(SCREEN_HEIGHT); for (int y = 0; y < SCREEN_HEIGHT; y++) { const float v0 = (float)y / SCREEN_HEIGHT; - const float v1 = (float)(y + 1) / SCREEN_HEIGHT; + const float log_lerp_step = lerp(log_max, 1.0f, v0); + const float v1 = ((float)y + log_lerp_step) / SCREEN_HEIGHT; const float v0h = v0 * tex_height; const float v1h = v1 * tex_height; const int v0_index = (int)v0h; @@ -715,16 +717,16 @@ void vgmviz_device::draw_waterfall(bitmap_rgb32 &bitmap) { if (m_waterfall_length < SCREEN_WIDTH) { - const float s0 = m_waterfall_buf[x][v0_index]; - const float s1 = m_waterfall_buf[x][v1_index]; + const float s0 = (float)m_waterfall_buf[x][v0_index]; + const float s1 = (float)m_waterfall_buf[x][v1_index]; const int sample = (int)std::round(lerp(s0, s1, interp)); *line++ = pal[256 + FFT_LENGTH / 2 + sample]; } else { const int x_index = ((m_waterfall_length - SCREEN_WIDTH) + x) % SCREEN_WIDTH; - const float s0 = m_waterfall_buf[x_index][v0_index]; - const float s1 = m_waterfall_buf[x_index][v1_index]; + const float s0 = (float)m_waterfall_buf[x_index][v0_index]; + const float s1 = (float)m_waterfall_buf[x_index][v1_index]; const int sample = (int)std::round(lerp(s0, s1, interp)); *line++ = pal[256 + FFT_LENGTH / 2 + sample]; } diff --git a/src/devices/sound/vgm_visualizer.h b/src/devices/sound/vgm_visualizer.h index 8455b3d2bc0..e428cc07940 100644 --- a/src/devices/sound/vgm_visualizer.h +++ b/src/devices/sound/vgm_visualizer.h @@ -122,7 +122,7 @@ protected: bool m_audio_available; int m_waterfall_length; - int m_waterfall_buf[SCREEN_WIDTH * 2][FFT_LENGTH / 2]; + float m_waterfall_buf[SCREEN_WIDTH * 2][FFT_LENGTH / 2]; float m_curr_levels[2]; float m_curr_peaks[2]; 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 m_cdda; + required_device m_cdrom; + required_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 ) diff --git a/src/mame/mame.lst b/src/mame/mame.lst index c1f0cbdfcb9..3f50f5cd8b5 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -10058,6 +10058,9 @@ quizard4_40 // (c) TAB Austria 1997 quizard4_41 // (c) TAB Austria 1998 quizard4cz // (c) TAB Austria 1998 +@source:cdplay.cpp +cdplay + @source:cdsys5.cpp minijook // diff --git a/src/mame/virtual.lst b/src/mame/virtual.lst index beac20e0916..638318b3e11 100644 --- a/src/mame/virtual.lst +++ b/src/mame/virtual.lst @@ -3,3 +3,4 @@ vgmplay simldv1000 simpr8210 +cdplay -- cgit v1.2.3