From f1e5cfc78ba664f4b9ad5fb7f0f08eb6c189fa8f Mon Sep 17 00:00:00 2001 From: Robbbert Date: Sun, 21 Jul 2019 15:00:45 +1000 Subject: [PATCH] (nw) cassette: cleanup, and fixed a few minor but annoying bugs - Create new tape, hit Reset: fatal error - internal error - Load empty file to record onto, same error - Randomly have to hit Play a number of times before it takes - Randomly tape "plays" silently with the motor off. --- src/devices/imagedev/cassette.cpp | 76 +++++++++---------------------- 1 file changed, 21 insertions(+), 55 deletions(-) diff --git a/src/devices/imagedev/cassette.cpp b/src/devices/imagedev/cassette.cpp index d94812ba860..3007ea752f5 100644 --- a/src/devices/imagedev/cassette.cpp +++ b/src/devices/imagedev/cassette.cpp @@ -11,7 +11,6 @@ #include "emu.h" #include "formats/imageutl.h" #include "cassette.h" -#include "ui/uimain.h" #define LOG_WARN (1U<<1) // Warnings #define LOG_DETAIL (1U<<2) // Details @@ -93,7 +92,8 @@ void cassette_image_device::update() { double new_position = m_position + (cur_time - m_position_time)*m_speed*m_direction; - switch(m_state & CASSETTE_MASK_UISTATE) { + switch(m_state & CASSETTE_MASK_UISTATE) + { case CASSETTE_RECORD: cassette_put_sample(m_cassette, m_channel, m_position, new_position - m_position, m_value); break; @@ -124,29 +124,21 @@ void cassette_image_device::update() void cassette_image_device::change_state(cassette_state state, cassette_state mask) { - cassette_state new_state; - - new_state = m_state; + cassette_state new_state = m_state; new_state = (cassette_state)(new_state & ~mask); new_state = (cassette_state)(new_state | (state & mask)); - - if (new_state != m_state) - { - update(); - m_state = new_state; - } + if ((m_state ^ new_state) & (CASSETTE_MASK_UISTATE | CASSETTE_MASK_MOTOR)) + m_position_time = machine().time().as_double(); + m_state = new_state; } double cassette_image_device::input() { - int32_t sample; - double double_value; - update(); - sample = m_value; - double_value = sample / ((double) 0x7FFFFFFF); + int32_t sample = m_value; + double double_value = sample / ((double) 0x7FFFFFFF); LOGMASKED(LOG_DETAIL, "cassette_input(): time_index=%g value=%g\n", m_position, double_value); @@ -171,11 +163,7 @@ void cassette_image_device::output(double value) double cassette_image_device::get_position() { - double position = m_position; - - if (is_motor_on()) - position += (machine().time().as_double() - m_position_time)*m_speed*m_direction; - return position; + return m_position; } @@ -211,11 +199,7 @@ void cassette_image_device::go_reverse() void cassette_image_device::seek(double time, int origin) { - double length; - - update(); - - length = get_length(); + double length = get_length(); switch(origin) { case SEEK_SET: @@ -272,7 +256,7 @@ image_init_result cassette_image_device::internal_load(bool is_create) device_image_interface *image = nullptr; interface(image); - if (is_create) + if (is_create || (length()==0)) // empty existing images are fine to write over. { // creating an image err = cassette_create((void *)image, &image_ioprocs, &wavfile_format, m_create_opts, CASSETTE_FLAG_READWRITE|CASSETTE_FLAG_SAVEONEXIT, &m_cassette); @@ -308,7 +292,8 @@ image_init_result cassette_image_device::internal_load(bool is_create) } /* set to default state, but only change the UI state */ - change_state(m_default_state, CASSETTE_MASK_UISTATE); + //change_state(m_default_state, CASSETTE_MASK_UISTATE); + m_state = m_default_state; /* reset the position */ m_position = 0.0; @@ -376,18 +361,15 @@ std::string cassette_image_device::call_display() // only show the image when a cassette is loaded and the motor is on if (exists() && is_motor_on()) { - int n; - double position, length; - cassette_state uistate; static char const *const shapes[] = { u8"\u2500", u8"\u2572", u8"\u2502", u8"\u2571" }; // figure out where we are in the cassette - position = get_position(); - length = get_length(); - uistate = (cassette_state)(get_state() & CASSETTE_MASK_UISTATE); + double position = get_position(); + double length = get_length(); + cassette_state uistate = cassette_state(get_state() & CASSETTE_MASK_UISTATE); // choose which frame of the animation we are at - n = ((int)position / ANIMATION_FPS) % ARRAY_LENGTH(shapes); + int n = (int(position) / ANIMATION_FPS) % ARRAY_LENGTH(shapes); // play or record const char *status_icon = (uistate == CASSETTE_PLAY) @@ -404,18 +386,6 @@ std::string cassette_image_device::call_display() ((int)length / 60), ((int)length % 60), (int)length); - - // make sure tape stops at end when playing - if ((m_state & CASSETTE_MASK_UISTATE) == CASSETTE_PLAY) - { - if (m_cassette) - { - if (get_position() > get_length()) - { - m_state = (cassette_state)((m_state & ~CASSETTE_MASK_UISTATE) | CASSETTE_STOPPED); - } - } - } } return result; } @@ -426,29 +396,25 @@ std::string cassette_image_device::call_display() void cassette_image_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) { - cassette_state state; - double time_index; - double duration; stream_sample_t *left_buffer = outputs[0]; stream_sample_t *right_buffer = nullptr; - int i; if (m_stereo) right_buffer = outputs[1]; - state = (cassette_state)(get_state() & (CASSETTE_MASK_UISTATE | CASSETTE_MASK_MOTOR | CASSETTE_MASK_SPEAKER)); + cassette_state state = get_state(); if (exists() && (state == (CASSETTE_PLAY | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED))) { cassette_image *cassette = get_image(); - time_index = get_position(); - duration = ((double) samples) / machine().sample_rate(); + double time_index = get_position(); + double duration = ((double) samples) / machine().sample_rate(); cassette_get_samples(cassette, 0, time_index, duration, samples, 2, left_buffer, CASSETTE_WAVEFORM_16BIT); if (m_stereo) cassette_get_samples(cassette, 1, time_index, duration, samples, 2, right_buffer, CASSETTE_WAVEFORM_16BIT); - for (i = samples - 1; i >= 0; i--) + for (int i = samples - 1; i >= 0; i--) { left_buffer[i] = ((int16_t *) left_buffer)[i]; if (m_stereo)