summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Ryan Holtz <ryan.holtz@arrowheadgs.com>2020-05-01 18:59:48 +0200
committer Ryan Holtz <ryan.holtz@arrowheadgs.com>2020-05-01 18:59:48 +0200
commit1af90f923e0d17cd70fc9ee4598a2cb263e54813 (patch)
tree2af6242c3e2303f19e8dba1b285dad5c3ccaf74b
parenta97d097b3b79e9fa395eabec4829dd82abc2ba47 (diff)
-cdplay: Created branch for experimental cd-player driver. [Ryan Holtz]cdplay
-rw-r--r--scripts/target/mame/virtual.lua2
-rw-r--r--src/devices/sound/vgm_visualizer.cpp16
-rw-r--r--src/devices/sound/vgm_visualizer.h2
-rw-r--r--src/mame/drivers/cdplay.cpp273
-rw-r--r--src/mame/mame.lst3
-rw-r--r--src/mame/virtual.lst1
6 files changed, 289 insertions, 8 deletions
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<float>(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<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 )
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