diff options
Diffstat (limited to 'src/emu/ui/datmenu.cpp')
-rw-r--r-- | src/emu/ui/datmenu.cpp | 570 |
1 files changed, 570 insertions, 0 deletions
diff --git a/src/emu/ui/datmenu.cpp b/src/emu/ui/datmenu.cpp new file mode 100644 index 00000000000..91dbcdcd41c --- /dev/null +++ b/src/emu/ui/datmenu.cpp @@ -0,0 +1,570 @@ +// license:BSD-3-Clause +// copyright-holders:Dankan1890 +/********************************************************************* + + mewui/datmenu.cpp + + Internal MEWUI user interface. + +*********************************************************************/ + +#include "emu.h" +#include "ui/ui.h" +#include "ui/menu.h" +#include "drivenum.h" +#include "rendfont.h" +#include "ui/datfile.h" +#include "ui/datmenu.h" +#include "ui/utils.h" +#include "softlist.h" + +/************************************************** + MENU COMMAND +**************************************************/ +//------------------------------------------------- +// ctor / dtor +//------------------------------------------------- + +ui_menu_command::ui_menu_command(running_machine &machine, render_container *container, const game_driver *driver) : ui_menu(machine, container) +{ + m_driver = (driver == nullptr) ? &machine.system() : driver; +} + +ui_menu_command::~ui_menu_command() +{ +} + +//------------------------------------------------- +// populate +//------------------------------------------------- + +void ui_menu_command::populate() +{ + std::vector<std::string> text; + machine().datfile().command_sub_menu(m_driver, text); + + if (!text.empty()) + { + for (size_t menu_items = 0; menu_items < text.size(); menu_items++) + item_append(text[menu_items].c_str(), nullptr, 0, (void *)(FPTR)menu_items); + } + else + item_append("No available Command for this machine.", nullptr, MENU_FLAG_DISABLE, nullptr); + + item_append(MENU_SEPARATOR_ITEM, nullptr, 0, nullptr); + customtop = machine().ui().get_line_height() + 3.0f * UI_BOX_TB_BORDER; + +} + +//------------------------------------------------- +// handle +//------------------------------------------------- + +void ui_menu_command::handle() +{ + // process the menu + const ui_menu_event *m_event = process(0); + + if (m_event != nullptr && m_event->iptkey == IPT_UI_SELECT) + { + std::string m_title(item[selected].text); + ui_menu::stack_push(auto_alloc_clear(machine(), <ui_menu_command_content>(machine(), container, m_title, m_driver))); + } +} + +//------------------------------------------------- +// perform our special rendering +//------------------------------------------------- + +void ui_menu_command::custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2) +{ + float width; + ui_manager &mui = machine().ui(); + std::string tempbuf = std::string("Command Info - Game: ").append(m_driver->description); + + // get the size of the text + mui.draw_text_full(container, tempbuf.c_str(), 0.0f, 0.0f, 1.0f, JUSTIFY_CENTER, WRAP_NEVER, + DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &width, nullptr); + width += (2.0f * UI_BOX_LR_BORDER) + 0.01f; + float maxwidth = MAX(width, origx2 - origx1); + + // compute our bounds + float x1 = 0.5f - 0.5f * maxwidth; + float x2 = x1 + maxwidth; + float y1 = origy1 - top; + float y2 = origy1 - UI_BOX_TB_BORDER; + + // draw a box + mui.draw_outlined_box(container, x1, y1, x2, y2, UI_GREEN_COLOR); + + // take off the borders + x1 += UI_BOX_LR_BORDER; + x2 -= UI_BOX_LR_BORDER; + y1 += UI_BOX_TB_BORDER; + + // draw the text within it + mui.draw_text_full(container, tempbuf.c_str(), x1, y1, x2 - x1, JUSTIFY_CENTER, WRAP_NEVER, + DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr); + +} + +//------------------------------------------------- +// ctor / dtor +//------------------------------------------------- + +ui_menu_command_content::ui_menu_command_content(running_machine &machine, render_container *container, std::string p_title, const game_driver *driver) : ui_menu(machine, container) +{ + m_driver = (driver == nullptr) ? &machine.system() : driver; + m_title = p_title; +} + +ui_menu_command_content::~ui_menu_command_content() +{ +} + +//------------------------------------------------- +// handle +//------------------------------------------------- + +void ui_menu_command_content::handle() +{ + // process the menu + process(0); +} + +//------------------------------------------------- +// populate +//------------------------------------------------- + +void ui_menu_command_content::populate() +{ + machine().pause(); + std::string buffer; + machine().datfile().load_command_info(buffer, m_title); + if (!buffer.empty()) + { + float line_height = machine().ui().get_line_height(); + float lr_arrow_width = 0.4f * line_height * machine().render().ui_aspect(); + float gutter_width = lr_arrow_width * 1.3f; + std::vector<int> xstart; + std::vector<int> xend; + int total_lines; + convert_command_glyph(buffer); + machine().ui().wrap_text(container, buffer.c_str(), 0.0f, 0.0f, 1.0f - (2.0f * UI_BOX_LR_BORDER) - 0.02f - (2.0f * gutter_width), + total_lines, xstart, xend); + for (int r = 0; r < total_lines; r++) + { + std::string tempbuf(buffer.substr(xstart[r], xend[r] - xstart[r])); + int first_dspace = tempbuf.find(" "); + if (first_dspace > 0 ) + { + std::string first_part(tempbuf.substr(0, first_dspace)); + std::string last_part(tempbuf.substr(first_dspace)); + strtrimspace(last_part); + item_append(first_part.c_str(), last_part.c_str(), MENU_FLAG_MEWUI_HISTORY, nullptr); + } + else + item_append(tempbuf.c_str(), nullptr, MENU_FLAG_MEWUI_HISTORY, nullptr); + } + item_append(MENU_SEPARATOR_ITEM, nullptr, 0, nullptr); + } + + machine().resume(); + customtop = custombottom = machine().ui().get_line_height() + 3.0f * UI_BOX_TB_BORDER; +} + +//------------------------------------------------- +// perform our special rendering +//------------------------------------------------- + +void ui_menu_command_content::custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2) +{ + float width; + ui_manager &mui = machine().ui(); + + // get the size of the text + mui.draw_text_full(container, m_title.c_str(), 0.0f, 0.0f, 1.0f, JUSTIFY_CENTER, WRAP_NEVER, + DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &width, nullptr); + width += (2.0f * UI_BOX_LR_BORDER) + 0.01f; + float maxwidth = MAX(width, origx2 - origx1); + + // compute our bounds + float x1 = 0.5f - 0.5f * maxwidth; + float x2 = x1 + maxwidth; + float y1 = origy1 - top; + float y2 = origy1 - UI_BOX_TB_BORDER; + + // draw a box + mui.draw_outlined_box(container, x1, y1, x2, y2, UI_GREEN_COLOR); + + // take off the borders + x1 += UI_BOX_LR_BORDER; + x2 -= UI_BOX_LR_BORDER; + y1 += UI_BOX_TB_BORDER; + + // draw the text within it + mui.draw_text_full(container, m_title.c_str(), x1, y1, x2 - x1, JUSTIFY_CENTER, WRAP_NEVER, + DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr); + + std::string tempbuf = std::string("Command Info - Game: ").append(m_driver->description); + + mui.draw_text_full(container, tempbuf.c_str(), 0.0f, 0.0f, 1.0f, JUSTIFY_CENTER, WRAP_NEVER, + DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &width, nullptr); + width += 2 * UI_BOX_LR_BORDER; + maxwidth = MAX(origx2 - origx1, width); + + // compute our bounds + x1 = 0.5f - 0.5f * maxwidth; + x2 = x1 + maxwidth; + y1 = origy2 + UI_BOX_TB_BORDER; + y2 = origy2 + bottom; + + // draw a box + mui.draw_outlined_box(container, x1, y1, x2, y2, UI_GREEN_COLOR); + + // take off the borders + x1 += UI_BOX_LR_BORDER; + x2 -= UI_BOX_LR_BORDER; + y1 += UI_BOX_TB_BORDER; + + // draw the text within it + mui.draw_text_full(container, tempbuf.c_str(), x1, y1, x2 - x1, JUSTIFY_CENTER, WRAP_NEVER, + DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr); +} + +/************************************************** + MENU SOFTWARE HISTORY +**************************************************/ +//------------------------------------------------- +// ctor / dtor +//------------------------------------------------- + +ui_menu_history_sw::ui_menu_history_sw(running_machine &machine, render_container *container, ui_software_info *swinfo, const game_driver *driver) : ui_menu(machine, container) +{ + m_list = swinfo->listname; + m_short = swinfo->shortname; + m_long = swinfo->longname; + m_parent = swinfo->parentname; + m_driver = (driver == nullptr) ? &machine.system() : driver; +} + +ui_menu_history_sw::ui_menu_history_sw(running_machine &machine, render_container *container, const game_driver *driver) : ui_menu(machine, container) +{ + image_interface_iterator iter(machine.root_device()); + for (device_image_interface *image = iter.first(); image != nullptr; image = iter.next()) + { + if (image->filename()) + { + m_list = strensure(image->software_list_name()); + m_short = strensure(image->software_entry()->shortname()); + m_long = strensure(image->software_entry()->longname()); + m_parent = strensure(image->software_entry()->parentname()); + } + } + m_driver = (driver == nullptr) ? &machine.system() : driver; +} + +ui_menu_history_sw::~ui_menu_history_sw() +{ +} + +//------------------------------------------------- +// handle +//------------------------------------------------- + +void ui_menu_history_sw::handle() +{ + // process the menu + process(0); +} + +//------------------------------------------------- +// populate +//------------------------------------------------- + +void ui_menu_history_sw::populate() +{ + machine().pause(); + std::string buffer; + machine().datfile().load_software_info(m_list, buffer, m_short, m_parent); + if (!buffer.empty()) + { + float line_height = machine().ui().get_line_height(); + float lr_arrow_width = 0.4f * line_height * machine().render().ui_aspect(); + float gutter_width = lr_arrow_width * 1.3f; + std::vector<int> xstart; + std::vector<int> xend; + int total_lines; + + machine().ui().wrap_text(container, buffer.c_str(), 0.0f, 0.0f, 1.0f - (2.0f * UI_BOX_LR_BORDER) - 0.02f - (2.0f * gutter_width), + total_lines, xstart, xend); + + for (int r = 0; r < total_lines; r++) + { + std::string tempbuf(buffer.substr(xstart[r], xend[r] - xstart[r])); + item_append(tempbuf.c_str(), nullptr, MENU_FLAG_MEWUI_HISTORY, nullptr); + } + } + else + item_append("No available History for this software.", nullptr, MENU_FLAG_DISABLE, nullptr); + + machine().resume(); + + item_append(MENU_SEPARATOR_ITEM, nullptr, 0, nullptr); + customtop = custombottom = machine().ui().get_line_height() + 3.0f * UI_BOX_TB_BORDER; +} + +//------------------------------------------------- +// perform our special rendering +//------------------------------------------------- + +void ui_menu_history_sw::custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2) +{ + float width; + std::string tempbuf = std::string("Software info - ").append(m_long); + ui_manager &mui = machine().ui(); + + // get the size of the text + mui.draw_text_full(container, tempbuf.c_str(), 0.0f, 0.0f, 1.0f, JUSTIFY_CENTER, WRAP_NEVER, + DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &width, nullptr); + width += (2.0f * UI_BOX_LR_BORDER) + 0.01f; + float maxwidth = MAX(width, origx2 - origx1); + + // compute our bounds + float x1 = 0.5f - 0.5f * maxwidth; + float x2 = x1 + maxwidth; + float y1 = origy1 - top; + float y2 = origy1 - UI_BOX_TB_BORDER; + + // draw a box + mui.draw_outlined_box(container, x1, y1, x2, y2, UI_GREEN_COLOR); + + // take off the borders + x1 += UI_BOX_LR_BORDER; + x2 -= UI_BOX_LR_BORDER; + y1 += UI_BOX_TB_BORDER; + + // draw the text within it + mui.draw_text_full(container, tempbuf.c_str(), x1, y1, x2 - x1, JUSTIFY_CENTER, WRAP_NEVER, + DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr); + + tempbuf.assign("System driver: ").append(m_driver->description); + + mui.draw_text_full(container, tempbuf.c_str(), 0.0f, 0.0f, 1.0f, JUSTIFY_CENTER, WRAP_TRUNCATE, + DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &width, nullptr); + width += 2 * UI_BOX_LR_BORDER; + maxwidth = MAX(origx2 - origx1, width); + + // compute our bounds + x1 = 0.5f - 0.5f * maxwidth; + x2 = x1 + maxwidth; + y1 = origy2 + UI_BOX_TB_BORDER; + y2 = origy2 + bottom; + + // draw a box + mui.draw_outlined_box(container, x1, y1, x2, y2, UI_GREEN_COLOR); + + // take off the borders + x1 += UI_BOX_LR_BORDER; + x2 -= UI_BOX_LR_BORDER; + y1 += UI_BOX_TB_BORDER; + + // draw the text within it + mui.draw_text_full(container, tempbuf.c_str(), x1, y1, x2 - x1, JUSTIFY_CENTER, WRAP_TRUNCATE, + DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr); +} + +/************************************************** + MENU DATS +**************************************************/ +//------------------------------------------------- +// ctor / dtor +//------------------------------------------------- + +ui_menu_dats::ui_menu_dats(running_machine &machine, render_container *container, int _flags, const game_driver *driver) : ui_menu(machine, container) +{ + m_driver = (driver == nullptr) ? &machine.system() : driver; + m_flags = _flags; +} + +ui_menu_dats::~ui_menu_dats() +{ +} + +//------------------------------------------------- +// handle +//------------------------------------------------- + +void ui_menu_dats::handle() +{ + // process the menu + process(0); +} + +//------------------------------------------------- +// populate +//------------------------------------------------- + +void ui_menu_dats::populate() +{ + machine().pause(); + switch (m_flags) + { + case MEWUI_HISTORY_LOAD: + if (!get_data(m_driver, m_flags)) + item_append("No available History for this machine.", nullptr, MENU_FLAG_DISABLE, nullptr); + break; + + case MEWUI_MAMEINFO_LOAD: + if (!get_data(m_driver, m_flags)) + item_append("No available MameInfo for this machine.", nullptr, MENU_FLAG_DISABLE, nullptr); + break; + + case MEWUI_MESSINFO_LOAD: + if (!get_data(m_driver, m_flags)) + item_append("No available MessInfo for this machine.", nullptr, MENU_FLAG_DISABLE, nullptr); + break; + + case MEWUI_STORY_LOAD: + if (!get_data(m_driver, MEWUI_STORY_LOAD)) + item_append("No available Mamescore for this machine.", nullptr, MENU_FLAG_DISABLE, nullptr); + break; + + case MEWUI_SYSINFO_LOAD: + if (!get_data(m_driver, MEWUI_SYSINFO_LOAD)) + item_append("No available Sysinfo for this machine.", nullptr, MENU_FLAG_DISABLE, nullptr); + break; + } + + machine().resume(); + item_append(MENU_SEPARATOR_ITEM, nullptr, 0, nullptr); + customtop = custombottom = machine().ui().get_line_height() + 3.0f * UI_BOX_TB_BORDER; +} + +//------------------------------------------------- +// perform our special rendering +//------------------------------------------------- + +void ui_menu_dats::custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2) +{ + float width; + std::string tempbuf, revision; + datfile_manager &datfile = machine().datfile(); + ui_manager &mui = machine().ui(); + + switch (m_flags) + { + case MEWUI_HISTORY_LOAD: + tempbuf.assign("History - Game / System: ").append(m_driver->description); + revision.assign("History.dat Revision: ").append(datfile.rev_history()); + break; + + case MEWUI_MESSINFO_LOAD: + tempbuf.assign("MessInfo - System: ").append(m_driver->description); + revision.assign("Messinfo.dat Revision: ").append(datfile.rev_messinfo()); + break; + + case MEWUI_MAMEINFO_LOAD: + tempbuf.assign("MameInfo - Game: ").append(m_driver->description); + revision.assign("Mameinfo.dat Revision: ").append(datfile.rev_mameinfo()); + break; + + case MEWUI_SYSINFO_LOAD: + tempbuf.assign("Sysinfo - System: ").append(m_driver->description); + revision.assign("Sysinfo.dat Revision: ").append(datfile.rev_sysinfo()); + break; + + case MEWUI_STORY_LOAD: + tempbuf.assign("MAMESCORE - Game: ").append(m_driver->description); + revision.assign("Story.dat Revision: ").append(machine().datfile().rev_storyinfo()); + break; + } + + // get the size of the text + mui.draw_text_full(container, tempbuf.c_str(), 0.0f, 0.0f, 1.0f, JUSTIFY_CENTER, WRAP_NEVER, + DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &width, nullptr); + width += (2.0f * UI_BOX_LR_BORDER) + 0.01f; + float maxwidth = MAX(width, origx2 - origx1); + + // compute our bounds + float x1 = 0.5f - 0.5f * maxwidth; + float x2 = x1 + maxwidth; + float y1 = origy1 - top; + float y2 = origy1 - UI_BOX_TB_BORDER; + + // draw a box + mui.draw_outlined_box(container, x1, y1, x2, y2, UI_GREEN_COLOR); + + // take off the borders + x1 += UI_BOX_LR_BORDER; + x2 -= UI_BOX_LR_BORDER; + y1 += UI_BOX_TB_BORDER; + + // draw the text within it + mui.draw_text_full(container, tempbuf.c_str(), x1, y1, x2 - x1, JUSTIFY_CENTER, WRAP_NEVER, + DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr); + + mui.draw_text_full(container, revision.c_str(), 0.0f, 0.0f, 1.0f, JUSTIFY_CENTER, WRAP_TRUNCATE, + DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &width, nullptr); + width += 2 * UI_BOX_LR_BORDER; + maxwidth = MAX(origx2 - origx1, width); + + // compute our bounds + x1 = 0.5f - 0.5f * maxwidth; + x2 = x1 + maxwidth; + y1 = origy2 + UI_BOX_TB_BORDER; + y2 = origy2 + bottom; + + // draw a box + mui.draw_outlined_box(container, x1, y1, x2, y2, UI_GREEN_COLOR); + + // take off the borders + x1 += UI_BOX_LR_BORDER; + x2 -= UI_BOX_LR_BORDER; + y1 += UI_BOX_TB_BORDER; + + // draw the text within it + mui.draw_text_full(container, revision.c_str(), x1, y1, x2 - x1, JUSTIFY_CENTER, WRAP_TRUNCATE, + DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr); +} + +//------------------------------------------------- +// load data from DATs +//------------------------------------------------- + +bool ui_menu_dats::get_data(const game_driver *driver, int flags) +{ + std::string buffer; + machine().datfile().load_data_info(driver, buffer, flags); + + if (buffer.empty()) + return false; + + float line_height = machine().ui().get_line_height(); + float lr_arrow_width = 0.4f * line_height * machine().render().ui_aspect(); + float gutter_width = lr_arrow_width * 1.3f; + std::vector<int> xstart; + std::vector<int> xend; + int tlines; + + machine().ui().wrap_text(container, buffer.c_str(), 0.0f, 0.0f, 1.0f - (2.0f * UI_BOX_LR_BORDER) - 0.02f - (2.0f * gutter_width), tlines, xstart, xend); + for (int r = 0; r < tlines; r++) + { + std::string tempbuf(buffer.substr(xstart[r], xend[r] - xstart[r])); + // special case for mamescore + if (flags == MEWUI_STORY_LOAD) + { + size_t last_underscore = tempbuf.find_last_of('_'); + if (last_underscore != std::string::npos) + { + std::string last_part(tempbuf.substr(last_underscore + 1)); + int primary = tempbuf.find("___"); + std::string first_part(tempbuf.substr(0, primary)); + item_append(first_part.c_str(), last_part.c_str(), MENU_FLAG_MEWUI_HISTORY, nullptr); + } + } + else + item_append(tempbuf.c_str(), nullptr, MENU_FLAG_MEWUI_HISTORY, nullptr); + } + return true; +} |