mirror of
https://github.com/holub/mame
synced 2025-07-02 00:29:37 +03:00
(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.
This commit is contained in:
parent
90efe5e074
commit
f1e5cfc78b
@ -11,7 +11,6 @@
|
|||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
#include "formats/imageutl.h"
|
#include "formats/imageutl.h"
|
||||||
#include "cassette.h"
|
#include "cassette.h"
|
||||||
#include "ui/uimain.h"
|
|
||||||
|
|
||||||
#define LOG_WARN (1U<<1) // Warnings
|
#define LOG_WARN (1U<<1) // Warnings
|
||||||
#define LOG_DETAIL (1U<<2) // Details
|
#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;
|
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:
|
case CASSETTE_RECORD:
|
||||||
cassette_put_sample(m_cassette, m_channel, m_position, new_position - m_position, m_value);
|
cassette_put_sample(m_cassette, m_channel, m_position, new_position - m_position, m_value);
|
||||||
break;
|
break;
|
||||||
@ -124,29 +124,21 @@ void cassette_image_device::update()
|
|||||||
|
|
||||||
void cassette_image_device::change_state(cassette_state state, cassette_state mask)
|
void cassette_image_device::change_state(cassette_state state, cassette_state mask)
|
||||||
{
|
{
|
||||||
cassette_state new_state;
|
cassette_state new_state = m_state;
|
||||||
|
|
||||||
new_state = m_state;
|
|
||||||
new_state = (cassette_state)(new_state & ~mask);
|
new_state = (cassette_state)(new_state & ~mask);
|
||||||
new_state = (cassette_state)(new_state | (state & mask));
|
new_state = (cassette_state)(new_state | (state & mask));
|
||||||
|
if ((m_state ^ new_state) & (CASSETTE_MASK_UISTATE | CASSETTE_MASK_MOTOR))
|
||||||
if (new_state != m_state)
|
m_position_time = machine().time().as_double();
|
||||||
{
|
m_state = new_state;
|
||||||
update();
|
|
||||||
m_state = new_state;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
double cassette_image_device::input()
|
double cassette_image_device::input()
|
||||||
{
|
{
|
||||||
int32_t sample;
|
|
||||||
double double_value;
|
|
||||||
|
|
||||||
update();
|
update();
|
||||||
sample = m_value;
|
int32_t sample = m_value;
|
||||||
double_value = sample / ((double) 0x7FFFFFFF);
|
double double_value = sample / ((double) 0x7FFFFFFF);
|
||||||
|
|
||||||
LOGMASKED(LOG_DETAIL, "cassette_input(): time_index=%g value=%g\n", m_position, double_value);
|
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 cassette_image_device::get_position()
|
||||||
{
|
{
|
||||||
double position = m_position;
|
return m_position;
|
||||||
|
|
||||||
if (is_motor_on())
|
|
||||||
position += (machine().time().as_double() - m_position_time)*m_speed*m_direction;
|
|
||||||
return position;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -211,11 +199,7 @@ void cassette_image_device::go_reverse()
|
|||||||
|
|
||||||
void cassette_image_device::seek(double time, int origin)
|
void cassette_image_device::seek(double time, int origin)
|
||||||
{
|
{
|
||||||
double length;
|
double length = get_length();
|
||||||
|
|
||||||
update();
|
|
||||||
|
|
||||||
length = get_length();
|
|
||||||
|
|
||||||
switch(origin) {
|
switch(origin) {
|
||||||
case SEEK_SET:
|
case SEEK_SET:
|
||||||
@ -272,7 +256,7 @@ image_init_result cassette_image_device::internal_load(bool is_create)
|
|||||||
device_image_interface *image = nullptr;
|
device_image_interface *image = nullptr;
|
||||||
interface(image);
|
interface(image);
|
||||||
|
|
||||||
if (is_create)
|
if (is_create || (length()==0)) // empty existing images are fine to write over.
|
||||||
{
|
{
|
||||||
// creating an image
|
// creating an image
|
||||||
err = cassette_create((void *)image, &image_ioprocs, &wavfile_format, m_create_opts, CASSETTE_FLAG_READWRITE|CASSETTE_FLAG_SAVEONEXIT, &m_cassette);
|
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 */
|
/* 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 */
|
/* reset the position */
|
||||||
m_position = 0.0;
|
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
|
// only show the image when a cassette is loaded and the motor is on
|
||||||
if (exists() && is_motor_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" };
|
static char const *const shapes[] = { u8"\u2500", u8"\u2572", u8"\u2502", u8"\u2571" };
|
||||||
|
|
||||||
// figure out where we are in the cassette
|
// figure out where we are in the cassette
|
||||||
position = get_position();
|
double position = get_position();
|
||||||
length = get_length();
|
double length = get_length();
|
||||||
uistate = (cassette_state)(get_state() & CASSETTE_MASK_UISTATE);
|
cassette_state uistate = cassette_state(get_state() & CASSETTE_MASK_UISTATE);
|
||||||
|
|
||||||
// choose which frame of the animation we are at
|
// 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
|
// play or record
|
||||||
const char *status_icon = (uistate == CASSETTE_PLAY)
|
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 % 60),
|
((int)length % 60),
|
||||||
(int)length);
|
(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;
|
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)
|
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 *left_buffer = outputs[0];
|
||||||
stream_sample_t *right_buffer = nullptr;
|
stream_sample_t *right_buffer = nullptr;
|
||||||
int i;
|
|
||||||
|
|
||||||
if (m_stereo)
|
if (m_stereo)
|
||||||
right_buffer = outputs[1];
|
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)))
|
if (exists() && (state == (CASSETTE_PLAY | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED)))
|
||||||
{
|
{
|
||||||
cassette_image *cassette = get_image();
|
cassette_image *cassette = get_image();
|
||||||
time_index = get_position();
|
double time_index = get_position();
|
||||||
duration = ((double) samples) / machine().sample_rate();
|
double duration = ((double) samples) / machine().sample_rate();
|
||||||
|
|
||||||
cassette_get_samples(cassette, 0, time_index, duration, samples, 2, left_buffer, CASSETTE_WAVEFORM_16BIT);
|
cassette_get_samples(cassette, 0, time_index, duration, samples, 2, left_buffer, CASSETTE_WAVEFORM_16BIT);
|
||||||
if (m_stereo)
|
if (m_stereo)
|
||||||
cassette_get_samples(cassette, 1, time_index, duration, samples, 2, right_buffer, CASSETTE_WAVEFORM_16BIT);
|
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];
|
left_buffer[i] = ((int16_t *) left_buffer)[i];
|
||||||
if (m_stereo)
|
if (m_stereo)
|
||||||
|
Loading…
Reference in New Issue
Block a user