Modernized the cassette animation

This commit is contained in:
Nathan Woods 2016-06-18 09:15:07 -04:00
parent b54accd6b3
commit f01066bcbb
4 changed files with 68 additions and 58 deletions

View File

@ -357,59 +357,60 @@ void cassette_image_device::call_unload()
}
//-------------------------------------------------
// display a small tape animation, with the
// current position in the tape image
//-------------------------------------------------
#define ANIMATION_FPS 1
#define ANIMATION_FRAMES 4
/*
display a small tape icon, with the current position in the tape image
*/
int cassette_image_device::call_display(std::string& s)
std::string cassette_image_device::call_display()
{
/* abort if we should not be showing the image */
if (!exists())
return -1;
if (!is_motor_on())
return -1;
const int ANIMATION_FPS = 1;
char buf[65];
int n;
double position, length;
cassette_state uistate;
static const UINT8 shapes[8] = { 0x2d, 0x5c, 0x7c, 0x2f, 0x2d, 0x20, 0x20, 0x20 };
std::string result;
/* figure out where we are in the cassette */
position = get_position();
length = get_length();
uistate = (cassette_state)(get_state() & CASSETTE_MASK_UISTATE);
/* choose which frame of the animation we are at */
n = ((int)position / ANIMATION_FPS) % ANIMATION_FRAMES;
/* Since you can have anything in a BDF file, we will use crude ascii characters instead */
snprintf(buf, ARRAY_LENGTH(buf), "%c%c %c %02d:%02d (%04d) [%02d:%02d (%04d)]",
shapes[n], /* cassette icon left */
shapes[n | 4], /* cassette icon right */
(uistate == CASSETTE_PLAY) ? 0x50 : 0x52, /* play (P) or record (R) */
((int)position / 60),
((int)position % 60),
(int)position,
((int)length / 60),
((int)length % 60),
(int)length);
s = buf;
// make sure tape stops at end when playing
if ((m_state & CASSETTE_MASK_UISTATE) == CASSETTE_PLAY)
// only show the image when a cassette is loaded and the motor is on
if (exists() && is_motor_on())
{
if ( m_cassette )
int n;
double position, length;
cassette_state uistate;
static const char *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);
// choose which frame of the animation we are at
n = ((int)position / ANIMATION_FPS) % ARRAY_LENGTH(shapes);
// play or record
const char *status_icon = (uistate == CASSETTE_PLAY)
? u8"\u25BA"
: u8"\u25CF";
// Since you can have anything in a BDF file, we will use crude ascii characters instead
result = string_format("%s %s %02d:%02d (%04d) [%02d:%02d (%04d)]",
shapes[n], // animation
status_icon, // play or record
((int)position / 60),
((int)position % 60),
(int)position,
((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 (get_position() > get_length())
if (m_cassette)
{
m_state = (cassette_state)(( m_state & ~CASSETTE_MASK_UISTATE ) | CASSETTE_STOPPED);
if (get_position() > get_length())
{
m_state = (cassette_state)((m_state & ~CASSETTE_MASK_UISTATE) | CASSETTE_STOPPED);
}
}
}
}
return cassette_device_iterator(machine().root_device()).indexof(*this);
return result;
}

View File

@ -58,7 +58,7 @@ public:
virtual bool call_load() override;
virtual bool call_create(int format_type, option_resolution *format_options) override;
virtual void call_unload() override;
virtual int call_display(std::string& s) override;
virtual std::string call_display() override;
virtual bool call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry) override { return load_software(swlist, swname, start_entry); }
virtual iodevice_t image_type() const override { return IO_CASSETTE; }

View File

@ -152,7 +152,7 @@ public:
virtual bool call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry) { return FALSE; }
virtual bool call_create(int format_type, option_resolution *format_options) { return FALSE; }
virtual void call_unload() { }
virtual int call_display(std::string& s) { return -1; }
virtual std::string call_display() { return std::string(); }
virtual device_image_partialhash_func get_partial_hash() const { return nullptr; }
virtual bool core_opens_image_file() const { return TRUE; }
virtual iodevice_t image_type() const = 0;

View File

@ -1214,20 +1214,29 @@ void mame_ui_manager::draw_profiler(render_container *container)
void mame_ui_manager::image_handler_ingame()
{
// run display routine for devices
if (machine().phase() == MACHINE_PHASE_RUNNING)
for (device_image_interface &image : image_interface_iterator(machine().root_device())) {
std::string str;
int idx = image.call_display(str);
if (idx >= 0) {
float x, y;
/* choose a location on the screen */
x = 0.2f;
y = 0.5f + idx;
y *= get_line_height() + 2.0f * UI_BOX_TB_BORDER;
if (machine().phase() == MACHINE_PHASE_RUNNING)
{
auto layout = create_layout(&machine().render().ui_container());
draw_text_box(&machine().render().ui_container(), str.c_str(), ui::text_layout::LEFT, x, y, UI_BACKGROUND_COLOR);
// loop through all devices, build their text into the layout
for (device_image_interface &image : image_interface_iterator(machine().root_device()))
{
std::string str = image.call_display();
if (!str.empty())
{
layout.add_text(str.c_str());
layout.add_text("\n");
}
}
// did we actually create anything?
if (!layout.empty())
{
float x = 0.2f;
float y = 0.5f * get_line_height() + 2.0f * UI_BOX_TB_BORDER;
draw_text_box(&machine().render().ui_container(), layout, x, y, UI_BACKGROUND_COLOR);
}
}
}
//-------------------------------------------------