From f01066bcbb78f22f9317f4f3d5db0aa8834228f4 Mon Sep 17 00:00:00 2001 From: Nathan Woods Date: Sat, 18 Jun 2016 09:15:07 -0400 Subject: [PATCH] Modernized the cassette animation --- src/devices/imagedev/cassette.cpp | 91 ++++++++++++++++--------------- src/devices/imagedev/cassette.h | 2 +- src/emu/diimage.h | 2 +- src/frontend/mame/ui/ui.cpp | 31 +++++++---- 4 files changed, 68 insertions(+), 58 deletions(-) diff --git a/src/devices/imagedev/cassette.cpp b/src/devices/imagedev/cassette.cpp index 96937bac6ea..5826f0abf58 100644 --- a/src/devices/imagedev/cassette.cpp +++ b/src/devices/imagedev/cassette.cpp @@ -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; } diff --git a/src/devices/imagedev/cassette.h b/src/devices/imagedev/cassette.h index cb3cfc717d3..a197cf851b5 100644 --- a/src/devices/imagedev/cassette.h +++ b/src/devices/imagedev/cassette.h @@ -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; } diff --git a/src/emu/diimage.h b/src/emu/diimage.h index f411aa99419..9e57e216375 100644 --- a/src/emu/diimage.h +++ b/src/emu/diimage.h @@ -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; diff --git a/src/frontend/mame/ui/ui.cpp b/src/frontend/mame/ui/ui.cpp index 335b660d285..81b2f2087e5 100644 --- a/src/frontend/mame/ui/ui.cpp +++ b/src/frontend/mame/ui/ui.cpp @@ -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); + } + } } //-------------------------------------------------