summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/ui/menu.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/ui/menu.cpp')
-rw-r--r--src/emu/ui/menu.cpp2019
1 files changed, 195 insertions, 1824 deletions
diff --git a/src/emu/ui/menu.cpp b/src/emu/ui/menu.cpp
index 547030298bb..069b05aa913 100644
--- a/src/emu/ui/menu.cpp
+++ b/src/emu/ui/menu.cpp
@@ -2,9 +2,9 @@
// copyright-holders:Nicola Salmoria, Aaron Giles, Nathan Woods
/*********************************************************************
- ui/menu.c
+ ui/menu.c
- Internal MAME menus for the user interface.
+ Internal MAME menus for the user interface.
*********************************************************************/
@@ -15,60 +15,18 @@
#include "ui/ui.h"
#include "ui/menu.h"
#include "ui/mainmenu.h"
-#include "ui/utils.h"
-#include "ui/defimg.h"
-#include "ui/starimg.h"
-#include "ui/optsmenu.h"
-#include "ui/datfile.h"
-#include "rendfont.h"
-#include "ui/custmenu.h"
-#include "ui/icorender.h"
-#include "ui/toolbar.h"
+
/***************************************************************************
- CONSTANTS
+ CONSTANTS
***************************************************************************/
-#define UI_MENU_POOL_SIZE 65536
-#define MAX_ICONS_RENDER 40
-
-struct ui_arts_info
-{
- const char *title, *path, *addpath;
-};
-
-static const ui_arts_info arts_info[] =
-{
- { "Snapshots", OPTION_SNAPSHOT_DIRECTORY, "snap" },
- { "Cabinets", OPTION_CABINETS_PATH, "cabinets;cabdevs" },
- { "Control Panels", OPTION_CPANELS_PATH, "cpanel" },
- { "PCBs", OPTION_PCBS_PATH, "pcb" },
- { "Flyers", OPTION_FLYERS_PATH, "flyers" },
- { "Titles", OPTION_TITLES_PATH, "titles" },
- { "Ends", OPTION_ENDS_PATH, "ends" },
- { "Artwork Preview", OPTION_ARTPREV_PATH, "artwork preview" },
- { "Bosses", OPTION_BOSSES_PATH, "bosses" },
- { "Logos", OPTION_LOGOS_PATH, "logo" },
- { "Versus", OPTION_VERSUS_PATH, "versus" },
- { "Game Over", OPTION_GAMEOVER_PATH, "gameover" },
- { "HowTo", OPTION_HOWTO_PATH, "howto" },
- { "Scores", OPTION_SCORES_PATH, "scores" },
- { "Select", OPTION_SELECT_PATH, "select" },
- { "Marquees", OPTION_MARQUEES_PATH, "marquees" },
- { nullptr }
-};
-
-static const char *hover_msg[] = {
- "Add or remove favorites",
- "Export displayed list to file",
- "Show DATs view",
- "Setup directories",
- "Configure options"
-};
+#define UI_MENU_POOL_SIZE 65536
+#define UI_MENU_ALLOC_ITEMS 256
/***************************************************************************
- GLOBAL VARIABLES
+ GLOBAL VARIABLES
***************************************************************************/
ui_menu *ui_menu::menu_stack;
@@ -76,24 +34,9 @@ ui_menu *ui_menu::menu_free;
std::unique_ptr<bitmap_rgb32> ui_menu::hilight_bitmap;
render_texture *ui_menu::hilight_texture;
render_texture *ui_menu::arrow_texture;
-render_texture *ui_menu::snapx_texture;
-render_texture *ui_menu::hilight_main_texture;
-render_texture *ui_menu::bgrnd_texture;
-render_texture *ui_menu::star_texture;
-render_texture *ui_menu::toolbar_texture[UI_TOOLBAR_BUTTONS];
-render_texture *ui_menu::sw_toolbar_texture[UI_TOOLBAR_BUTTONS];
-render_texture *ui_menu::icons_texture[MAX_ICONS_RENDER];
-std::unique_ptr<bitmap_argb32> ui_menu::snapx_bitmap;
-std::unique_ptr<bitmap_argb32> ui_menu::no_avail_bitmap;
-std::unique_ptr<bitmap_argb32> ui_menu::star_bitmap;
-std::unique_ptr<bitmap_argb32> ui_menu::bgrnd_bitmap;
-bitmap_argb32 *ui_menu::icons_bitmap[MAX_ICONS_RENDER];
-std::unique_ptr<bitmap_rgb32> ui_menu::hilight_main_bitmap;
-bitmap_argb32 *ui_menu::toolbar_bitmap[UI_TOOLBAR_BUTTONS];
-bitmap_argb32 *ui_menu::sw_toolbar_bitmap[UI_TOOLBAR_BUTTONS];
/***************************************************************************
- INLINE FUNCTIONS
+ INLINE FUNCTIONS
***************************************************************************/
//-------------------------------------------------
@@ -126,7 +69,7 @@ inline bool ui_menu::exclusive_input_pressed(int key, int repeat)
/***************************************************************************
- CORE SYSTEM MANAGEMENT
+ CORE SYSTEM MANAGEMENT
***************************************************************************/
//-------------------------------------------------
@@ -135,12 +78,14 @@ inline bool ui_menu::exclusive_input_pressed(int key, int repeat)
void ui_menu::init(running_machine &machine)
{
+ int x;
+
// initialize the menu stack
ui_menu::stack_reset(machine);
// create a texture for hilighting items
hilight_bitmap = std::make_unique<bitmap_rgb32>(256, 1);
- for (int x = 0; x < 256; x++)
+ for (x = 0; x < 256; x++)
{
int alpha = 0xff;
if (x < 25) alpha = 0xff * x / 25;
@@ -153,9 +98,6 @@ void ui_menu::init(running_machine &machine)
// create a texture for arrow icons
arrow_texture = machine.render().texture_alloc(render_triangle);
- // initialize ui
- init_ui(machine);
-
// add an exit callback to free memory
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(ui_menu::exit), &machine));
}
@@ -172,28 +114,14 @@ void ui_menu::exit(running_machine &machine)
ui_menu::clear_free_list(machine);
// free textures
- render_manager &mre = machine.render();
- mre.texture_free(hilight_texture);
- mre.texture_free(arrow_texture);
- mre.texture_free(snapx_texture);
- mre.texture_free(hilight_main_texture);
- mre.texture_free(bgrnd_texture);
- mre.texture_free(star_texture);
-
- for (auto & elem : icons_texture)
- mre.texture_free(elem);
-
- for (int i = 0; i < UI_TOOLBAR_BUTTONS; i++)
- {
- mre.texture_free(sw_toolbar_texture[i]);
- mre.texture_free(toolbar_texture[i]);
- }
+ machine.render().texture_free(hilight_texture);
+ machine.render().texture_free(arrow_texture);
}
/***************************************************************************
- CORE MENU MANAGEMENT
+ CORE MENU MANAGEMENT
***************************************************************************/
//-------------------------------------------------
@@ -206,8 +134,6 @@ ui_menu::ui_menu(running_machine &machine, render_container *_container) : m_mac
container = _container;
reset(UI_MENU_RESET_SELECT_FIRST);
-
- top_line = 0;
}
@@ -222,8 +148,12 @@ ui_menu::~ui_menu()
{
ui_menu_pool *ppool = pool;
pool = pool->next;
- global_free(ppool);
+ auto_free(machine(), ppool);
}
+
+ // free the item array
+ if (item)
+ auto_free(machine(), item);
}
@@ -242,14 +172,14 @@ void ui_menu::reset(ui_menu_reset_options options)
else if (options == UI_MENU_RESET_REMEMBER_REF)
resetref = item[selected].ref;
- // reset all the pools and the item.size() back to 0
+ // reset all the pools and the numitems back to 0
for (ui_menu_pool *ppool = pool; ppool != nullptr; ppool = ppool->next)
ppool->top = (UINT8 *)(ppool + 1);
- item.clear();
+ numitems = 0;
visitems = 0;
selected = 0;
std::string backtext;
- strprintf(backtext, "Return to Machine");
+ strprintf(backtext, "Return to %s", emulator_info::get_capstartgamenoun());
// add an item to return
if (parent == nullptr)
@@ -284,42 +214,66 @@ void ui_menu::set_special_main_menu(bool special)
//-------------------------------------------------
+// populated - returns true if the menu
+// has any non-default items in it
+//-------------------------------------------------
+
+bool ui_menu::populated()
+{
+ return numitems > 1;
+}
+
+
+//-------------------------------------------------
// item_append - append a new item to the
// end of the menu
//-------------------------------------------------
void ui_menu::item_append(const char *text, const char *subtext, UINT32 flags, void *ref)
{
+ ui_menu_item *pitem;
+ int index;
+
// only allow multiline as the first item
if ((flags & MENU_FLAG_MULTILINE) != 0)
- assert(item.size() == 1);
+ assert(numitems == 1);
// only allow a single multi-line item
- else if (item.size() >= 2)
+ else if (numitems >= 2)
assert((item[0].flags & MENU_FLAG_MULTILINE) == 0);
- // allocate a new item and populate it
- ui_menu_item pitem;
- pitem.text = (text != nullptr) ? pool_strdup(text) : nullptr;
- pitem.subtext = (subtext != nullptr) ? pool_strdup(subtext) : nullptr;
- pitem.flags = flags;
- pitem.ref = ref;
-
- // append to array
- int index = item.size();
- if (!item.empty())
+ // realloc the item array if necessary
+ if (numitems >= allocitems)
{
- item.insert(item.end() - 1, pitem);
- --index;
+ int olditems = allocitems;
+ allocitems += UI_MENU_ALLOC_ITEMS;
+ ui_menu_item *newitems = auto_alloc_array(machine(), ui_menu_item, allocitems);
+ for (int itemnum = 0; itemnum < olditems; itemnum++)
+ newitems[itemnum] = item[itemnum];
+ auto_free(machine(), item);
+ item = newitems;
}
- else
- item.push_back(pitem);
+ index = numitems++;
+
+ // copy the previous last item to the next one
+ if (index != 0)
+ {
+ index--;
+ item[index + 1] = item[index];
+ }
+
+ // allocate a new item and populate it
+ pitem = &item[index];
+ pitem->text = (text != nullptr) ? pool_strdup(text) : nullptr;
+ pitem->subtext = (subtext != nullptr) ? pool_strdup(subtext) : nullptr;
+ pitem->flags = flags;
+ pitem->ref = ref;
// update the selection if we need to
if (resetpos == index || (resetref != nullptr && resetref == ref))
selected = index;
- if (resetpos == item.size() - 1)
- selected = item.size() - 1;
+ if (resetpos == numitems - 1)
+ selected = numitems - 1;
}
@@ -334,42 +288,27 @@ const ui_menu_event *ui_menu::process(UINT32 flags)
menu_event.iptkey = IPT_INVALID;
// first make sure our selection is valid
-// if (!(flags & UI_MENU_PROCESS_NOINPUT))
- validate_selection(1);
+ validate_selection(1);
// draw the menu
- if (item.size() > 1 && (item[0].flags & MENU_FLAG_MULTILINE) != 0)
+ if (numitems > 1 && (item[0].flags & MENU_FLAG_MULTILINE) != 0)
draw_text_box();
- else if ((item[0].flags & MENU_FLAG_UI ) != 0 || (item[0].flags & MENU_FLAG_UI_SWLIST ) != 0)
- draw_select_game(flags & UI_MENU_PROCESS_NOINPUT);
- else if ((item[0].flags & MENU_FLAG_UI_PALETTE ) != 0)
- draw_palette_menu();
- else if ((item[0].flags & MENU_FLAG_UI_DATS) != 0)
- draw_dats_menu();
else
- draw(flags & UI_MENU_PROCESS_CUSTOM_ONLY, flags & UI_MENU_PROCESS_NOIMAGE, flags & UI_MENU_PROCESS_NOINPUT);
+ draw(flags & UI_MENU_PROCESS_CUSTOM_ONLY);
// process input
- if (!(flags & UI_MENU_PROCESS_NOKEYS) && !(flags & UI_MENU_PROCESS_NOINPUT))
+ if (!(flags & UI_MENU_PROCESS_NOKEYS))
{
// read events
- if ((item[0].flags & MENU_FLAG_UI ) != 0 || (item[0].flags & MENU_FLAG_UI_SWLIST ) != 0)
- handle_main_events(flags);
- else
- handle_events(flags);
+ handle_events();
// handle the keys if we don't already have an menu_event
if (menu_event.iptkey == IPT_INVALID)
- {
- if ((item[0].flags & MENU_FLAG_UI ) != 0 || (item[0].flags & MENU_FLAG_UI_SWLIST ) != 0)
- handle_main_keys(flags);
- else
- handle_keys(flags);
- }
+ handle_keys(flags);
}
// update the selected item in the menu_event
- if (menu_event.iptkey != IPT_INVALID && selected >= 0 && selected < item.size())
+ if (menu_event.iptkey != IPT_INVALID && selected >= 0 && selected < numitems)
{
menu_event.itemref = item[selected].ref;
return &menu_event;
@@ -399,7 +338,7 @@ void *ui_menu::m_pool_alloc(size_t size)
}
// allocate a new pool
- ppool = (ui_menu_pool *)global_alloc_array_clear<UINT8>(sizeof(*ppool) + UI_MENU_POOL_SIZE);
+ ppool = (ui_menu_pool *)auto_alloc_array_clear(machine(), UINT8, sizeof(*ppool) + UI_MENU_POOL_SIZE);
// wire it up
ppool->next = pool;
@@ -428,7 +367,7 @@ const char *ui_menu::pool_strdup(const char *string)
void *ui_menu::get_selection()
{
- return (selected >= 0 && selected < item.size()) ? item[selected].ref : nullptr;
+ return (selected >= 0 && selected < numitems) ? item[selected].ref : nullptr;
}
@@ -439,8 +378,10 @@ void *ui_menu::get_selection()
void ui_menu::set_selection(void *selected_itemref)
{
+ int itemnum;
+
selected = -1;
- for (int itemnum = 0; itemnum < item.size(); itemnum++)
+ for (itemnum = 0; itemnum < numitems; itemnum++)
if (item[itemnum].ref == selected_itemref)
{
selected = itemnum;
@@ -451,39 +392,38 @@ void ui_menu::set_selection(void *selected_itemref)
/***************************************************************************
- INTERNAL MENU PROCESSING
+ INTERNAL MENU PROCESSING
***************************************************************************/
//-------------------------------------------------
// draw - draw a menu
//-------------------------------------------------
-void ui_menu::draw(bool customonly, bool noimage, bool noinput)
+void ui_menu::draw(bool customonly)
{
- // first draw the FPS counter
- if (machine().ui().show_fps_counter())
- {
- machine().ui().draw_text_full(container, machine().video().speed_text().c_str(), 0.0f, 0.0f, 1.0f,
- JUSTIFY_RIGHT, WRAP_WORD, DRAW_OPAQUE, ARGB_WHITE, ARGB_BLACK, nullptr, nullptr);
- }
-
float line_height = machine().ui().get_line_height();
float lr_arrow_width = 0.4f * line_height * machine().render().ui_aspect();
float ud_arrow_width = line_height * machine().render().ui_aspect();
float gutter_width = lr_arrow_width * 1.3f;
-
- bool selected_subitem_too_big = false;
+ float x1, y1, x2, y2;
+
+ float effective_width, effective_left;
+ float visible_width, visible_main_menu_height;
+ float visible_extra_menu_height;
+ float visible_top, visible_left;
+ int selected_subitem_too_big = FALSE;
+ int visible_lines;
+ int top_line;
int itemnum, linenum;
bool mouse_hit, mouse_button;
+ render_target *mouse_target;
+ INT32 mouse_target_x, mouse_target_y;
float mouse_x = -1, mouse_y = -1;
- if (machine().ui().options().use_background_image() && &machine().system() == &GAME_NAME(___empty) && bgrnd_bitmap->valid() && !noimage)
- container->add_quad(0.0f, 0.0f, 1.0f, 1.0f, ARGB_WHITE, bgrnd_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
-
// compute the width and height of the full menu
- float visible_width = 0;
- float visible_main_menu_height = 0;
- for (itemnum = 0; itemnum < item.size(); itemnum++)
+ visible_width = 0;
+ visible_main_menu_height = 0;
+ for (itemnum = 0; itemnum < numitems; itemnum++)
{
const ui_menu_item &pitem = item[itemnum];
float total_width;
@@ -504,7 +444,7 @@ void ui_menu::draw(bool customonly, bool noimage, bool noinput)
}
// account for extra space at the top and bottom
- float visible_extra_menu_height = customtop + custombottom;
+ visible_extra_menu_height = customtop + custombottom;
// add a little bit of slop for rounding
visible_width += 0.01f;
@@ -522,46 +462,44 @@ void ui_menu::draw(bool customonly, bool noimage, bool noinput)
visible_main_menu_height = (float)visible_lines * line_height;
// compute top/left of inner menu area by centering
- float visible_left = (1.0f - visible_width) * 0.5f;
- float visible_top = (1.0f - (visible_main_menu_height + visible_extra_menu_height)) * 0.5f;
+ visible_left = (1.0f - visible_width) * 0.5f;
+ visible_top = (1.0f - (visible_main_menu_height + visible_extra_menu_height)) * 0.5f;
// if the menu is at the bottom of the extra, adjust
visible_top += customtop;
// first add us a box
- float x1 = visible_left - UI_BOX_LR_BORDER;
- float y1 = visible_top - UI_BOX_TB_BORDER;
- float x2 = visible_left + visible_width + UI_BOX_LR_BORDER;
- float y2 = visible_top + visible_main_menu_height + UI_BOX_TB_BORDER;
+ x1 = visible_left - UI_BOX_LR_BORDER;
+ y1 = visible_top - UI_BOX_TB_BORDER;
+ x2 = visible_left + visible_width + UI_BOX_LR_BORDER;
+ y2 = visible_top + visible_main_menu_height + UI_BOX_TB_BORDER;
if (!customonly)
machine().ui().draw_outlined_box(container, x1, y1, x2, y2, UI_BACKGROUND_COLOR);
// determine the first visible line based on the current selection
- if (top_line < 0 || selected == 0)
+ top_line = selected - visible_lines / 2;
+ if (top_line < 0)
top_line = 0;
- if (top_line + visible_lines >= item.size())
- top_line = item.size() - visible_lines;
+ if (top_line + visible_lines >= numitems)
+ top_line = numitems - visible_lines;
// determine effective positions taking into account the hilighting arrows
- float effective_width = visible_width - 2.0f * gutter_width;
- float effective_left = visible_left + gutter_width;
+ effective_width = visible_width - 2.0f * gutter_width;
+ effective_left = visible_left + gutter_width;
// locate mouse
mouse_hit = false;
mouse_button = false;
- if (!customonly && !noinput)
+ if (!customonly)
{
- INT32 mouse_target_x, mouse_target_y;
- render_target *mouse_target = machine().ui_input().find_mouse(&mouse_target_x, &mouse_target_y, &mouse_button);
+ mouse_target = machine().ui_input().find_mouse(&mouse_target_x, &mouse_target_y, &mouse_button);
if (mouse_target != nullptr)
if (mouse_target->map_point_container(mouse_target_x, mouse_target_y, *container, mouse_x, mouse_y))
mouse_hit = true;
}
// loop over visible lines
- hover = item.size() + 1;
- float line_x0 = x1 + 0.5f * UI_LINE_WIDTH;
- float line_x1 = x2 - 0.5f * UI_LINE_WIDTH;
+ hover = numitems + 1;
if (!customonly)
for (linenum = 0; linenum < visible_lines; linenum++)
{
@@ -573,7 +511,9 @@ void ui_menu::draw(bool customonly, bool noimage, bool noinput)
rgb_t bgcolor = UI_TEXT_BG_COLOR;
rgb_t fgcolor2 = UI_SUBITEM_COLOR;
rgb_t fgcolor3 = UI_CLONE_COLOR;
+ float line_x0 = x1 + 0.5f * UI_LINE_WIDTH;
float line_y0 = line_y;
+ float line_x1 = x2 - 0.5f * UI_LINE_WIDTH;
float line_y1 = line_y + line_height;
// set the hover if this is our item
@@ -590,7 +530,7 @@ void ui_menu::draw(bool customonly, bool noimage, bool noinput)
}
// else if the mouse is over this item, draw with a different background
- else if (itemnum == hover && ((linenum == 0 && top_line != 0) || (linenum == visible_lines - 1 && itemnum != item.size() - 1)))
+ else if (itemnum == hover)
{
fgcolor = UI_MOUSEOVER_COLOR;
bgcolor = UI_MOUSEOVER_BG_COLOR;
@@ -605,7 +545,8 @@ void ui_menu::draw(bool customonly, bool noimage, bool noinput)
// if we're on the top line, display the up arrow
if (linenum == 0 && top_line != 0)
{
- draw_arrow(container,
+ draw_arrow(
+ container,
0.5f * (x1 + x2) - 0.5f * ud_arrow_width,
line_y + 0.25f * line_height,
0.5f * (x1 + x2) + 0.5f * ud_arrow_width,
@@ -613,13 +554,14 @@ void ui_menu::draw(bool customonly, bool noimage, bool noinput)
fgcolor,
ROT0);
if (hover == itemnum)
- hover = HOVER_ARROW_UP;
+ hover = -2;
}
// if we're on the bottom line, display the down arrow
- else if (linenum == visible_lines - 1 && itemnum != item.size() - 1)
+ else if (linenum == visible_lines - 1 && itemnum != numitems - 1)
{
- draw_arrow(container,
+ draw_arrow(
+ container,
0.5f * (x1 + x2) - 0.5f * ud_arrow_width,
line_y + 0.25f * line_height,
0.5f * (x1 + x2) + 0.5f * ud_arrow_width,
@@ -627,7 +569,7 @@ void ui_menu::draw(bool customonly, bool noimage, bool noinput)
fgcolor,
ROT0 ^ ORIENTATION_FLIP_Y);
if (hover == itemnum)
- hover = HOVER_ARROW_DOWN;
+ hover = -1;
}
// if we're just a divider, draw a line
@@ -637,7 +579,7 @@ void ui_menu::draw(bool customonly, bool noimage, bool noinput)
// if we don't have a subitem, just draw the string centered
else if (pitem.subtext == nullptr)
machine().ui().draw_text_full(container, itemtext, effective_left, line_y, effective_width,
- JUSTIFY_CENTER, WRAP_TRUNCATE, DRAW_NORMAL, fgcolor, bgcolor, nullptr, nullptr);
+ JUSTIFY_CENTER, WRAP_TRUNCATE, DRAW_NORMAL, fgcolor, bgcolor, nullptr, nullptr);
// otherwise, draw the item on the left and the subitem text on the right
else
@@ -658,19 +600,9 @@ void ui_menu::draw(bool customonly, bool noimage, bool noinput)
{
subitem_text = "...";
if (itemnum == selected)
- selected_subitem_too_big = true;
+ selected_subitem_too_big = TRUE;
}
- // customize subitem text color
- if (!core_stricmp(subitem_text, "On"))
- fgcolor2 = rgb_t(0xff,0x00,0xff,0x00);
-
- if (!core_stricmp(subitem_text, "Off"))
- fgcolor2 = rgb_t(0xff,0xff,0x00,0x00);
-
- if (!core_stricmp(subitem_text, "Auto"))
- fgcolor2 = rgb_t(0xff,0xff,0xff,0x00);
-
// draw the subitem right-justified
machine().ui().draw_text_full(container, subitem_text, effective_left + item_width, line_y, effective_width - item_width,
JUSTIFY_RIGHT, WRAP_TRUNCATE, DRAW_NORMAL, subitem_invert ? fgcolor3 : fgcolor2, bgcolor, &subitem_width, nullptr);
@@ -678,7 +610,8 @@ void ui_menu::draw(bool customonly, bool noimage, bool noinput)
// apply arrows
if (itemnum == selected && (pitem.flags & MENU_FLAG_LEFT_ARROW))
{
- draw_arrow(container,
+ draw_arrow(
+ container,
effective_left + effective_width - subitem_width - gutter_width,
line_y + 0.1f * line_height,
effective_left + effective_width - subitem_width - gutter_width + lr_arrow_width,
@@ -688,7 +621,8 @@ void ui_menu::draw(bool customonly, bool noimage, bool noinput)
}
if (itemnum == selected && (pitem.flags & MENU_FLAG_RIGHT_ARROW))
{
- draw_arrow(container,
+ draw_arrow(
+ container,
effective_left + effective_width + gutter_width - lr_arrow_width,
line_y + 0.1f * line_height,
effective_left + effective_width + gutter_width,
@@ -711,7 +645,7 @@ void ui_menu::draw(bool customonly, bool noimage, bool noinput)
// compute the multi-line target width/height
machine().ui().draw_text_full(container, pitem.subtext, 0, 0, visible_width * 0.75f,
- JUSTIFY_RIGHT, WRAP_WORD, DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &target_width, &target_height);
+ JUSTIFY_RIGHT, WRAP_WORD, DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &target_width, &target_height);
// determine the target location
target_x = visible_left + visible_width - target_width - UI_BOX_LR_BORDER;
@@ -723,19 +657,16 @@ void ui_menu::draw(bool customonly, bool noimage, bool noinput)
machine().ui().draw_outlined_box(container, target_x - UI_BOX_LR_BORDER,
target_y - UI_BOX_TB_BORDER,
target_x + target_width + UI_BOX_LR_BORDER,
- target_y + target_height + UI_BOX_TB_BORDER,
- subitem_invert ? UI_SELECTED_BG_COLOR : UI_BACKGROUND_COLOR);
+ target_y + target_height + UI_BOX_TB_BORDER, subitem_invert ? UI_SELECTED_BG_COLOR : UI_BACKGROUND_COLOR);
machine().ui().draw_text_full(container, pitem.subtext, target_x, target_y, target_width,
JUSTIFY_RIGHT, WRAP_WORD, DRAW_NORMAL, UI_SELECTED_COLOR, UI_SELECTED_BG_COLOR, nullptr, nullptr);
}
// if there is something special to add, do it by calling the virtual method
- custom_render((selected >= 0 && selected < item.size()) ? item[selected].ref : nullptr, customtop, custombottom, x1, y1, x2, y2);
+ custom_render((selected >= 0 && selected < numitems) ? item[selected].ref : nullptr, customtop, custombottom, x1, y1, x2, y2);
// return the number of visible lines, minus 1 for top arrow and 1 for bottom arrow
- visitems = visible_lines - (top_line != 0) - (top_line + visible_lines != item.size());
-// if (history_flag && (top_line + visible_lines >= item.size()))
-// selected = item.size() - 1;
+ visitems = visible_lines - (top_line != 0) - (top_line + visible_lines != numitems);
}
void ui_menu::custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2)
@@ -760,7 +691,7 @@ void ui_menu::draw_text_box()
// compute the multi-line target width/height
machine().ui().draw_text_full(container, text, 0, 0, 1.0f - 2.0f * UI_BOX_LR_BORDER - 2.0f * gutter_width,
- JUSTIFY_LEFT, WRAP_WORD, DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &target_width, &target_height);
+ JUSTIFY_LEFT, WRAP_WORD, DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &target_width, &target_height);
target_height += 2.0f * line_height;
if (target_height > 1.0f - 2.0f * UI_BOX_TB_BORDER)
target_height = floorf((1.0f - 2.0f * UI_BOX_TB_BORDER) / line_height) * line_height;
@@ -785,25 +716,25 @@ void ui_menu::draw_text_box()
// add a box around that
machine().ui().draw_outlined_box(container, target_x - UI_BOX_LR_BORDER - gutter_width,
- target_y - UI_BOX_TB_BORDER,
- target_x + target_width + gutter_width + UI_BOX_LR_BORDER,
- target_y + target_height + UI_BOX_TB_BORDER,
- (item[0].flags & MENU_FLAG_REDTEXT) ? UI_RED_COLOR : UI_BACKGROUND_COLOR);
+ target_y - UI_BOX_TB_BORDER,
+ target_x + target_width + gutter_width + UI_BOX_LR_BORDER,
+ target_y + target_height + UI_BOX_TB_BORDER, (item[0].flags & MENU_FLAG_REDTEXT) ? UI_RED_COLOR : UI_BACKGROUND_COLOR);
machine().ui().draw_text_full(container, text, target_x, target_y, target_width,
JUSTIFY_LEFT, WRAP_WORD, DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
// draw the "return to prior menu" text with a hilight behind it
- highlight(container,
- target_x + 0.5f * UI_LINE_WIDTH,
- target_y + target_height - line_height,
- target_x + target_width - 0.5f * UI_LINE_WIDTH,
- target_y + target_height,
- UI_SELECTED_BG_COLOR);
+ highlight(
+ container,
+ target_x + 0.5f * UI_LINE_WIDTH,
+ target_y + target_height - line_height,
+ target_x + target_width - 0.5f * UI_LINE_WIDTH,
+ target_y + target_height,
+ UI_SELECTED_BG_COLOR);
machine().ui().draw_text_full(container, backtext, target_x, target_y + target_height - line_height, target_width,
JUSTIFY_CENTER, WRAP_TRUNCATE, DRAW_NORMAL, UI_SELECTED_COLOR, UI_SELECTED_BG_COLOR, nullptr, nullptr);
// artificially set the hover to the last item so a double-click exits
- hover = item.size() - 1;
+ hover = numitems - 1;
}
@@ -812,9 +743,9 @@ void ui_menu::draw_text_box()
// input events for a menu
//-------------------------------------------------
-void ui_menu::handle_events(UINT32 flags)
+void ui_menu::handle_events()
{
- bool stop = false;
+ int stop = FALSE;
ui_event local_menu_event;
// loop while we have interesting events
@@ -824,82 +755,35 @@ void ui_menu::handle_events(UINT32 flags)
{
// if we are hovering over a valid item, select it with a single click
case UI_EVENT_MOUSE_DOWN:
- if ((flags & UI_MENU_PROCESS_ONLYCHAR) == 0)
+ if (hover >= 0 && hover < numitems)
+ selected = hover;
+ else if (hover == -2)
{
- if (hover >= 0 && hover < item.size())
- selected = hover;
- else if (hover == HOVER_ARROW_UP)
- {
- if ((flags & MENU_FLAG_UI_DATS) != 0)
- {
- top_line -= visitems - (top_line + visible_lines == item.size() - 1);
- return;
- }
- selected -= visitems;
- if (selected < 0)
- selected = 0;
- top_line -= visitems - (top_line + visible_lines == item.size() - 1);
- }
- else if (hover == HOVER_ARROW_DOWN)
- {
- if ((flags & MENU_FLAG_UI_DATS) != 0)
- {
- top_line += visible_lines - 2;
- return;
- }
- selected += visible_lines - 2 + (selected == 0);
- if (selected > item.size() - 1)
- selected = item.size() - 1;
- top_line += visible_lines - 2;
- }
+ selected -= visitems - 1;
+ validate_selection(1);
+ }
+ else if (hover == -1)
+ {
+ selected += visitems - 1;
+ validate_selection(1);
}
break;
// if we are hovering over a valid item, fake a UI_SELECT with a double-click
case UI_EVENT_MOUSE_DOUBLE_CLICK:
- if ((flags & UI_MENU_PROCESS_ONLYCHAR) == 0 && hover >= 0 && hover < item.size())
+ if (hover >= 0 && hover < numitems)
{
selected = hover;
- menu_event.iptkey = IPT_UI_SELECT;
- if (selected == item.size() - 1)
+ if (local_menu_event.event_type == UI_EVENT_MOUSE_DOUBLE_CLICK)
{
- menu_event.iptkey = IPT_UI_CANCEL;
- ui_menu::stack_pop(machine());
- }
- stop = true;
- }
- break;
-
- // caught scroll event
- case UI_EVENT_MOUSE_WHEEL:
- if ((flags & UI_MENU_PROCESS_ONLYCHAR) == 0)
- {
- if (local_menu_event.zdelta > 0)
- {
- if ((flags & MENU_FLAG_UI_DATS) != 0)
+ menu_event.iptkey = IPT_UI_SELECT;
+ if (selected == numitems - 1)
{
- top_line -= local_menu_event.num_lines;
- return;
+ menu_event.iptkey = IPT_UI_CANCEL;
+ ui_menu::stack_pop(machine());
}
- selected -= local_menu_event.num_lines;
- validate_selection(-1);
- if (selected < top_line + (top_line != 0))
- top_line -= local_menu_event.num_lines;
- }
- else
- {
- if ((flags & MENU_FLAG_UI_DATS) != 0)
- {
- top_line += local_menu_event.num_lines;
- return;
- }
- selected += local_menu_event.num_lines;
- validate_selection(1);
- if (selected > item.size() - 1)
- selected = item.size() - 1;
- if (selected >= top_line + visitems + (top_line != 0))
- top_line += local_menu_event.num_lines;
}
+ stop = TRUE;
}
break;
@@ -907,7 +791,7 @@ void ui_menu::handle_events(UINT32 flags)
case UI_EVENT_CHAR:
menu_event.iptkey = IPT_SPECIAL;
menu_event.unichar = local_menu_event.ch;
- stop = true;
+ stop = TRUE;
break;
// ignore everything else
@@ -925,17 +809,19 @@ void ui_menu::handle_events(UINT32 flags)
void ui_menu::handle_keys(UINT32 flags)
{
- bool ignorepause = ui_menu::stack_has_special_main_menu();
+ int ignorepause = ui_menu::stack_has_special_main_menu();
+ int ignoreright;
+ int ignoreleft;
int code;
// bail if no items
- if (item.empty())
+ if (numitems == 0)
return;
// if we hit select, return TRUE or pop the stack, depending on the item
if (exclusive_input_pressed(IPT_UI_SELECT, 0))
{
- if (selected == item.size() - 1)
+ if (selected == numitems - 1)
{
menu_event.iptkey = IPT_UI_CANCEL;
ui_menu::stack_pop(machine());
@@ -943,15 +829,10 @@ void ui_menu::handle_keys(UINT32 flags)
return;
}
- // bail out
- if ((flags & UI_MENU_PROCESS_ONLYCHAR) != 0)
- return;
-
// hitting cancel also pops the stack
if (exclusive_input_pressed(IPT_UI_CANCEL, 0))
{
- if (!menu_has_search_active())
- ui_menu::stack_pop(machine());
+ ui_menu::stack_pop(machine());
return;
}
@@ -959,11 +840,8 @@ void ui_menu::handle_keys(UINT32 flags)
validate_selection(1);
// swallow left/right keys if they are not appropriate
- bool ignoreleft = ((item[selected].flags & MENU_FLAG_LEFT_ARROW) == 0);
- bool ignoreright = ((item[selected].flags & MENU_FLAG_RIGHT_ARROW) == 0);
-
- if ((item[0].flags & MENU_FLAG_UI_DATS) != 0)
- ignoreleft = ignoreright = false;
+ ignoreleft = ((item[selected].flags & MENU_FLAG_LEFT_ARROW) == 0);
+ ignoreright = ((item[selected].flags & MENU_FLAG_RIGHT_ARROW) == 0);
// accept left/right keys as-is with repeat
if (!ignoreleft && exclusive_input_pressed(IPT_UI_LEFT, (flags & UI_MENU_PROCESS_LR_REPEAT) ? 6 : 0))
@@ -974,60 +852,42 @@ void ui_menu::handle_keys(UINT32 flags)
// up backs up by one item
if (exclusive_input_pressed(IPT_UI_UP, 6))
{
- if ((item[0].flags & MENU_FLAG_UI_DATS) != 0)
- {
- top_line--;
- return;
- }
- (selected == 0) ? selected = top_line = item.size() - 1 : --selected;
+ selected = (selected + numitems - 1) % numitems;
validate_selection(-1);
- top_line -= (selected == top_line && top_line != 0);
}
// down advances by one item
if (exclusive_input_pressed(IPT_UI_DOWN, 6))
{
- if ((item[0].flags & MENU_FLAG_UI_DATS) != 0)
- {
- top_line++;
- return;
- }
- (selected == item.size() - 1) ? selected = top_line = 0 : ++selected;
- top_line += (selected == top_line + visitems + (top_line != 0));
+ selected = (selected + 1) % numitems;
+ validate_selection(1);
}
// page up backs up by visitems
if (exclusive_input_pressed(IPT_UI_PAGE_UP, 6))
{
- selected -= visitems;
- top_line -= visitems - (top_line + visible_lines == item.size() - 1);
- if (selected < 0)
- selected = 0;
+ selected -= visitems - 1;
validate_selection(1);
}
// page down advances by visitems
if (exclusive_input_pressed(IPT_UI_PAGE_DOWN, 6))
{
- selected += visible_lines - 2 + (selected == 0);
- top_line += visible_lines - 2;
-
- if (selected > item.size() - 1)
- selected = item.size() - 1;
+ selected += visitems - 1;
validate_selection(-1);
}
// home goes to the start
if (exclusive_input_pressed(IPT_UI_HOME, 0))
{
- selected = top_line = 0;
+ selected = 0;
validate_selection(1);
}
// end goes to the last
if (exclusive_input_pressed(IPT_UI_END, 0))
{
- selected = top_line = item.size() - 1;
+ selected = numitems - 1;
validate_selection(-1);
}
@@ -1067,12 +927,12 @@ void ui_menu::validate_selection(int scandir)
// clamp to be in range
if (selected < 0)
selected = 0;
- else if (selected >= item.size())
- selected = item.size() - 1;
+ else if (selected >= numitems)
+ selected = numitems - 1;
// skip past unselectable items
while (!item[selected].is_selectable())
- selected = (selected + item.size() + scandir) % item.size();
+ selected = (selected + numitems + scandir) % numitems;
}
@@ -1088,14 +948,14 @@ void ui_menu::clear_free_list(running_machine &machine)
{
ui_menu *menu = menu_free;
menu_free = menu->parent;
- global_free(menu);
+ auto_free(machine, menu);
}
}
/***************************************************************************
- MENU STACK MANAGEMENT
+ MENU STACK MANAGEMENT
***************************************************************************/
//-------------------------------------------------
@@ -1158,14 +1018,14 @@ bool ui_menu::stack_has_special_main_menu()
void ui_menu::do_handle()
{
- if(item.size() < 2)
+ if(!populated())
populate();
handle();
}
/***************************************************************************
- UI SYSTEM INTERACTION
+ UI SYSTEM INTERACTION
***************************************************************************/
//-------------------------------------------------
@@ -1177,7 +1037,7 @@ UINT32 ui_menu::ui_handler(running_machine &machine, render_container *container
{
// if we have no menus stacked up, start with the main menu
if (menu_stack == nullptr)
- stack_push(global_alloc_clear<ui_menu_main>(machine, container));
+ stack_push(auto_alloc_clear(machine, <ui_menu_main>(machine, container)));
// update the menu state
if (menu_stack != nullptr)
@@ -1194,7 +1054,7 @@ UINT32 ui_menu::ui_handler(running_machine &machine, render_container *container
}
/***************************************************************************
- MENU HELPERS
+ MENU HELPERS
***************************************************************************/
//-------------------------------------------------
@@ -1258,7 +1118,8 @@ void ui_menu::render_triangle(bitmap_argb32 &dest, bitmap_argb32 &source, const
void ui_menu::highlight(render_container *container, float x0, float y0, float x1, float y1, rgb_t bgcolor)
{
- container->add_quad(x0, y0, x1, y1, bgcolor, hilight_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE) | PRIMFLAG_PACKABLE);
+ container->add_quad(x0, y0, x1, y1, bgcolor, hilight_texture,
+ PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE));
}
@@ -1268,1502 +1129,12 @@ void ui_menu::highlight(render_container *container, float x0, float y0, float x
void ui_menu::draw_arrow(render_container *container, float x0, float y0, float x1, float y1, rgb_t fgcolor, UINT32 orientation)
{
- container->add_quad(x0, y0, x1, y1, fgcolor, arrow_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(orientation) | PRIMFLAG_PACKABLE);
-}
-
-//-------------------------------------------------
-// init - initialize the ui menu system
-//-------------------------------------------------
-
-void ui_menu::init_ui(running_machine &machine)
-{
- render_manager &mrender = machine.render();
- // create a texture for hilighting items in main menu
- hilight_main_bitmap = std::make_unique<bitmap_rgb32>(1, 26);
- int r1 = 0, g1 = 169, b1 = 255; //Any start color
- int r2 = 0, g2 = 39, b2 = 130; //Any stop color
- for (int y = 0; y < 26; y++)
- {
- int r = r1 + (y * (r2 - r1) / 26);
- int g = g1 + (y * (g2 - g1) / 26);
- int b = b1 + (y * (b2 - b1) / 26);
- hilight_main_bitmap->pix32(y, 0) = rgb_t(0xff, r, g, b);
- }
-
- hilight_main_texture = mrender.texture_alloc();
- hilight_main_texture->set_bitmap(*hilight_main_bitmap, hilight_main_bitmap->cliprect(), TEXFORMAT_ARGB32);
-
- // create a texture for snapshot
- snapx_bitmap = std::make_unique<bitmap_argb32>(0, 0);
- snapx_texture = mrender.texture_alloc(render_texture::hq_scale);
-
- // allocates and sets the default "no available" image
- no_avail_bitmap = std::make_unique<bitmap_argb32>(256, 256);
- UINT32 *dst = &no_avail_bitmap->pix32(0);
- memcpy(dst, no_avail_bmp, 256 * 256 * sizeof(UINT32));
-
- // allocates and sets the favorites star image
- star_bitmap = std::make_unique<bitmap_argb32>(32, 32);
- dst = &star_bitmap->pix32(0);
- memcpy(dst, favorite_star_bmp, 32 * 32 * sizeof(UINT32));
- star_texture = mrender.texture_alloc();
- star_texture->set_bitmap(*star_bitmap, star_bitmap->cliprect(), TEXFORMAT_ARGB32);
-
- // allocate icons
- for (int i = 0; i < MAX_ICONS_RENDER; i++)
- {
- icons_bitmap[i] = auto_alloc(machine, bitmap_argb32);
- icons_texture[i] = mrender.texture_alloc();
- }
-
- // create a texture for main menu background
- bgrnd_bitmap = std::make_unique<bitmap_argb32>(0, 0);
- bgrnd_texture = mrender.texture_alloc(render_texture::hq_scale);
-
- ui_options &mopt = machine.ui().options();
- if (mopt.use_background_image() && &machine.system() == &GAME_NAME(___empty))
- {
- emu_file backgroundfile(".", OPEN_FLAG_READ);
- render_load_jpeg(*bgrnd_bitmap, backgroundfile, nullptr, "background.jpg");
-
- if (!bgrnd_bitmap->valid())
- render_load_png(*bgrnd_bitmap, backgroundfile, nullptr, "background.png");
-
- if (bgrnd_bitmap->valid())
- bgrnd_texture->set_bitmap(*bgrnd_bitmap, bgrnd_bitmap->cliprect(), TEXFORMAT_ARGB32);
- else
- bgrnd_bitmap->reset();
- }
- else
- bgrnd_bitmap->reset();
-
- // create a texture for toolbar
- for (int x = 0; x < UI_TOOLBAR_BUTTONS; ++x)
- {
- toolbar_bitmap[x] = auto_alloc(machine, bitmap_argb32(32, 32));
- sw_toolbar_bitmap[x] = auto_alloc(machine, bitmap_argb32(32, 32));
- toolbar_texture[x] = mrender.texture_alloc();
- sw_toolbar_texture[x] = mrender.texture_alloc();
- UINT32 *dst = &toolbar_bitmap[x]->pix32(0);
- memcpy(dst, toolbar_bitmap_bmp[x], 32 * 32 * sizeof(UINT32));
- if (toolbar_bitmap[x]->valid())
- toolbar_texture[x]->set_bitmap(*toolbar_bitmap[x], toolbar_bitmap[x]->cliprect(), TEXFORMAT_ARGB32);
- else
- toolbar_bitmap[x]->reset();
-
- if (x == 0 || x == 2)
- {
- dst = &sw_toolbar_bitmap[x]->pix32(0);
- memcpy(dst, toolbar_bitmap_bmp[x], 32 * 32 * sizeof(UINT32));
- if (sw_toolbar_bitmap[x]->valid())
- sw_toolbar_texture[x]->set_bitmap(*sw_toolbar_bitmap[x], sw_toolbar_bitmap[x]->cliprect(), TEXFORMAT_ARGB32);
- else
- sw_toolbar_bitmap[x]->reset();
- }
- else
- sw_toolbar_bitmap[x]->reset();
-
- }
-}
-
-
-//-------------------------------------------------
-// draw main menu
-//-------------------------------------------------
-
-void ui_menu::draw_select_game(bool noinput)
-{
- float line_height = machine().ui().get_line_height();
- float ud_arrow_width = line_height * machine().render().ui_aspect();
- float gutter_width = 0.52f * line_height * machine().render().ui_aspect();
- mouse_x = -1, mouse_y = -1;
- float right_panel_size = (ui_globals::panels_status == HIDE_BOTH || ui_globals::panels_status == HIDE_RIGHT_PANEL) ? 2.0f * UI_BOX_LR_BORDER : 0.3f;
- float visible_width = 1.0f - 4.0f * UI_BOX_LR_BORDER;
- float primary_left = (1.0f - visible_width) * 0.5f;
- float primary_width = visible_width;
- bool is_swlist = ((item[0].flags & MENU_FLAG_UI_SWLIST) != 0);
- bool is_favorites = ((item[0].flags & MENU_FLAG_UI_FAVORITE) != 0);
- ui_manager &mui = machine().ui();
-
- // draw background image if available
- if (machine().ui().options().use_background_image() && bgrnd_bitmap->valid())
- container->add_quad(0.0f, 0.0f, 1.0f, 1.0f, ARGB_WHITE, bgrnd_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
-
- hover = item.size() + 1;
- visible_items = (is_swlist) ? item.size() - 2 : item.size() - 2 - skip_main_items;
- float extra_height = (is_swlist) ? 2.0f * line_height : (2.0f + skip_main_items) * line_height;
- float visible_extra_menu_height = customtop + custombottom + extra_height;
-
- // locate mouse
- mouse_hit = false;
- mouse_button = false;
- if (!noinput)
- {
- mouse_target = machine().ui_input().find_mouse(&mouse_target_x, &mouse_target_y, &mouse_button);
- if (mouse_target != nullptr)
- if (mouse_target->map_point_container(mouse_target_x, mouse_target_y, *container, mouse_x, mouse_y))
- mouse_hit = true;
- }
-
- // account for extra space at the top and bottom
- float visible_main_menu_height = 1.0f - 2.0f * UI_BOX_TB_BORDER - visible_extra_menu_height;
- visible_lines = floor(visible_main_menu_height / line_height);
- visible_main_menu_height = (float)(visible_lines * line_height);
-
- if (!is_swlist)
- ui_globals::visible_main_lines = visible_lines;
- else
- ui_globals::visible_sw_lines = visible_lines;
-
- // compute top/left of inner menu area by centering
- float visible_left = primary_left;
- float visible_top = (1.0f - (visible_main_menu_height + visible_extra_menu_height)) * 0.5f;
-
- // if the menu is at the bottom of the extra, adjust
- visible_top += customtop;
-
- // compute left box size
- float x1 = visible_left - UI_BOX_LR_BORDER;
- float y1 = visible_top - UI_BOX_TB_BORDER;
- float x2 = x1 + 2.0f * UI_BOX_LR_BORDER;
- float y2 = visible_top + visible_main_menu_height + UI_BOX_TB_BORDER + extra_height;
-
- // add left box
- visible_left = draw_left_panel(x1, y1, x2, y2);
- visible_width -= right_panel_size + visible_left - 2.0f * UI_BOX_LR_BORDER;
-
- // compute and add main box
- x1 = visible_left - UI_BOX_LR_BORDER;
- x2 = visible_left + visible_width + UI_BOX_LR_BORDER;
- float line = visible_top + (float)(visible_lines * line_height);
-
- //machine().ui().draw_outlined_box(container, x1, y1, x2, y2, rgb_t(0xEF, 0x12, 0x47, 0x7B));
- mui.draw_outlined_box(container, x1, y1, x2, y2, UI_BACKGROUND_COLOR);
-
- if (visible_items < visible_lines)
- visible_lines = visible_items;
- if (top_line < 0 || selected == 0)
- top_line = 0;
- if (selected < visible_items && top_line + visible_lines >= visible_items)
- top_line = visible_items - visible_lines;
-
- // determine effective positions taking into account the hilighting arrows
- float effective_width = visible_width - 2.0f * gutter_width;
- float effective_left = visible_left + gutter_width;
-
- int n_loop = (visible_items >= visible_lines) ? visible_lines : visible_items;
-
- for (int linenum = 0; linenum < n_loop; linenum++)
- {
- float line_y = visible_top + (float)linenum * line_height;
- int itemnum = top_line + linenum;
- const ui_menu_item &pitem = item[itemnum];
- const char *itemtext = pitem.text;
- rgb_t fgcolor = UI_TEXT_COLOR;
- rgb_t bgcolor = UI_TEXT_BG_COLOR;
- rgb_t fgcolor3 = UI_CLONE_COLOR;
- float line_x0 = x1 + 0.5f * UI_LINE_WIDTH;
- float line_y0 = line_y;
- float line_x1 = x2 - 0.5f * UI_LINE_WIDTH;
- float line_y1 = line_y + line_height;
-
- // set the hover if this is our item
- if (mouse_hit && line_x0 <= mouse_x && line_x1 > mouse_x && line_y0 <= mouse_y && line_y1 > mouse_y && pitem.is_selectable())
- hover = itemnum;
-
- // if we're selected, draw with a different background
- if (itemnum == selected)
- {
- fgcolor = rgb_t(0xff, 0xff, 0xff, 0x00);
- bgcolor = rgb_t(0xff, 0xff, 0xff, 0xff);
- fgcolor3 = rgb_t(0xff, 0xcc, 0xcc, 0x00);
- }
- // else if the mouse is over this item, draw with a different background
- else if (itemnum == hover)
- {
- fgcolor = fgcolor3 = UI_MOUSEOVER_COLOR;
- bgcolor = UI_MOUSEOVER_BG_COLOR;
- }
-
- // if we have some background hilighting to do, add a quad behind everything else
- if (bgcolor != UI_TEXT_BG_COLOR)
- mui.draw_textured_box(container, line_x0 + 0.01f, line_y0, line_x1 - 0.01f, line_y1, bgcolor, rgb_t(255, 43, 43, 43),
- hilight_main_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE));
-
- // if we're on the top line, display the up arrow
- if (linenum == 0 && top_line != 0)
- {
- draw_arrow(container, 0.5f * (x1 + x2) - 0.5f * ud_arrow_width, line_y + 0.25f * line_height,
- 0.5f * (x1 + x2) + 0.5f * ud_arrow_width, line_y + 0.75f * line_height, fgcolor, ROT0);
-
- if (hover == itemnum)
- hover = HOVER_ARROW_UP;
- }
- // if we're on the bottom line, display the down arrow
- else if (linenum == visible_lines - 1 && itemnum != visible_items - 1)
- {
- draw_arrow(container, 0.5f * (x1 + x2) - 0.5f * ud_arrow_width, line_y + 0.25f * line_height,
- 0.5f * (x1 + x2) + 0.5f * ud_arrow_width, line_y + 0.75f * line_height, fgcolor, ROT0 ^ ORIENTATION_FLIP_Y);
-
- if (hover == itemnum)
- hover = HOVER_ARROW_DOWN;
- }
- // if we're just a divider, draw a line
- else if (strcmp(itemtext, MENU_SEPARATOR_ITEM) == 0)
- container->add_line(visible_left, line_y + 0.5f * line_height, visible_left + visible_width, line_y + 0.5f * line_height,
- UI_LINE_WIDTH, UI_TEXT_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
- // draw the item centered
- else if (pitem.subtext == nullptr)
- {
- int item_invert = pitem.flags & MENU_FLAG_INVERT;
- float space = 0.0f;
-
- if (ui_globals::has_icons && !is_swlist)
- {
- if (is_favorites)
- {
- ui_software_info *soft = (ui_software_info *)item[itemnum].ref;
- if (soft->startempty == 1)
- draw_icon(linenum, (void *)soft->driver, effective_left, line_y);
- }
- else
- draw_icon(linenum, item[itemnum].ref, effective_left, line_y);
-
- space = mui.get_line_height() * container->manager().ui_aspect() * 1.5f;
- }
- mui.draw_text_full(container, itemtext, effective_left + space, line_y, effective_width - space, JUSTIFY_LEFT, WRAP_TRUNCATE,
- DRAW_NORMAL, item_invert ? fgcolor3 : fgcolor, bgcolor, nullptr, nullptr);
- }
- else
- {
- int item_invert = pitem.flags & MENU_FLAG_INVERT;
- const char *subitem_text = pitem.subtext;
- float item_width, subitem_width;
-
- // compute right space for subitem
- mui.draw_text_full(container, subitem_text, effective_left, line_y, machine().ui().get_string_width(pitem.subtext),
- JUSTIFY_RIGHT, WRAP_NEVER, DRAW_NONE, item_invert ? fgcolor3 : fgcolor, bgcolor, &subitem_width, nullptr);
- subitem_width += gutter_width;
-
- // draw the item left-justified
- mui.draw_text_full(container, itemtext, effective_left, line_y, effective_width - subitem_width,
- JUSTIFY_LEFT, WRAP_TRUNCATE, DRAW_NORMAL, item_invert ? fgcolor3 : fgcolor, bgcolor, &item_width, nullptr);
-
- // draw the subitem right-justified
- mui.draw_text_full(container, subitem_text, effective_left + item_width, line_y, effective_width - item_width,
- JUSTIFY_RIGHT, WRAP_NEVER, DRAW_NORMAL, item_invert ? fgcolor3 : fgcolor, bgcolor, nullptr, nullptr);
- }
- }
-
- for (size_t count = visible_items; count < item.size(); count++)
- {
- const ui_menu_item &pitem = item[count];
- const char *itemtext = pitem.text;
- float line_x0 = x1 + 0.5f * UI_LINE_WIDTH;
- float line_y0 = line;
- float line_x1 = x2 - 0.5f * UI_LINE_WIDTH;
- float line_y1 = line + line_height;
- rgb_t fgcolor = UI_TEXT_COLOR;
- rgb_t bgcolor = UI_TEXT_BG_COLOR;
-
- if (mouse_hit && line_x0 <= mouse_x && line_x1 > mouse_x && line_y0 <= mouse_y && line_y1 > mouse_y && pitem.is_selectable())
- hover = count;
-
- // if we're selected, draw with a different background
- if (count == selected)
- {
- fgcolor = rgb_t(0xff, 0xff, 0xff, 0x00);
- bgcolor = rgb_t(0xff, 0xff, 0xff, 0xff);
- }
- // else if the mouse is over this item, draw with a different background
- else if (count == hover)
- {
- fgcolor = UI_MOUSEOVER_COLOR;
- bgcolor = UI_MOUSEOVER_BG_COLOR;
- }
-
- // if we have some background hilighting to do, add a quad behind everything else
- if (bgcolor != UI_TEXT_BG_COLOR)
- mui.draw_textured_box(container, line_x0 + 0.01f, line_y0, line_x1 - 0.01f, line_y1, bgcolor, rgb_t(255, 43, 43, 43),
- hilight_main_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE));
-
- if (strcmp(itemtext, MENU_SEPARATOR_ITEM) == 0)
- container->add_line(visible_left, line + 0.5f * line_height, visible_left + visible_width, line + 0.5f * line_height,
- UI_LINE_WIDTH, UI_TEXT_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
- else
- mui.draw_text_full(container, itemtext, effective_left, line, effective_width, JUSTIFY_CENTER, WRAP_TRUNCATE,
- DRAW_NORMAL, fgcolor, bgcolor, nullptr, nullptr);
- line += line_height;
- }
-
- x1 = x2;
- x2 += right_panel_size;
-
- draw_right_panel((selected >= 0 && selected < item.size()) ? item[selected].ref : nullptr, x1, y1, x2, y2);
-
- x1 = primary_left - UI_BOX_LR_BORDER;
- x2 = primary_left + primary_width + UI_BOX_LR_BORDER;
-
- // if there is something special to add, do it by calling the virtual method
- custom_render((selected >= 0 && selected < item.size()) ? item[selected].ref : nullptr, customtop, custombottom, x1, y1, x2, y2);
-
- // return the number of visible lines, minus 1 for top arrow and 1 for bottom arrow
- visitems = visible_lines - (top_line != 0) - (top_line + visible_lines != visible_items);
-
- // reset redraw icon stage
- if (!is_swlist)
- ui_globals::redraw_icon = false;
-}
-
-//-------------------------------------------------
-// get title and search path for right panel
-//-------------------------------------------------
-
-void ui_menu::get_title_search(std::string &snaptext, std::string &searchstr)
-{
- // get arts title text
- snaptext.assign(arts_info[ui_globals::curimage_view].title);
-
- // get search path
- if (ui_globals::curimage_view == SNAPSHOT_VIEW)
- searchstr = machine().options().value(arts_info[ui_globals::curimage_view].path);
- else
- searchstr = machine().ui().options().value(arts_info[ui_globals::curimage_view].path);
-
- path_iterator path(searchstr.c_str());
- std::string curpath;
-
- // iterate over path and add path for zipped formats
- while (path.next(curpath))
- {
- path_iterator path_iter(arts_info[ui_globals::curimage_view].addpath);
- std::string c_path;
- while (path_iter.next(c_path))
- searchstr.append(";").append(curpath).append(PATH_SEPARATOR).append(c_path);
- }
-}
-
-//-------------------------------------------------
-// handle keys for main menu
-//-------------------------------------------------
-
-void ui_menu::handle_main_keys(UINT32 flags)
-{
- bool ignorepause = ui_menu::stack_has_special_main_menu();
-
- // bail if no items
- if (item.size() == 0)
- return;
-
- // if we hit select, return TRUE or pop the stack, depending on the item
- if (exclusive_input_pressed(IPT_UI_SELECT, 0))
- {
- if (selected == item.size() - 1)
- {
- menu_event.iptkey = IPT_UI_CANCEL;
- ui_menu::stack_pop(machine());
- }
- return;
- }
-
- // hitting cancel also pops the stack
- if (exclusive_input_pressed(IPT_UI_CANCEL, 0))
- {
- if (!menu_has_search_active())
- ui_menu::stack_pop(machine());
- // else if (!ui_error)
- // ui_menu::stack_pop(machine()); TODO
- return;
- }
-
- // validate the current selection
- validate_selection(1);
-
- // swallow left/right keys if they are not appropriate
- bool ignoreleft = ((item[selected].flags & MENU_FLAG_LEFT_ARROW) == 0 || ui_globals::panels_status == HIDE_BOTH || ui_globals::panels_status == HIDE_RIGHT_PANEL);
- bool ignoreright = ((item[selected].flags & MENU_FLAG_RIGHT_ARROW) == 0 || ui_globals::panels_status == HIDE_BOTH || ui_globals::panels_status == HIDE_RIGHT_PANEL);
- bool ignoreup = (ui_globals::panels_status == HIDE_BOTH || ui_globals::panels_status == HIDE_LEFT_PANEL);
- bool ignoredown = (ui_globals::panels_status == HIDE_BOTH || ui_globals::panels_status == HIDE_LEFT_PANEL);
-
- input_manager &minput = machine().input();
- // accept left/right keys as-is with repeat
- if (!ignoreleft && exclusive_input_pressed(IPT_UI_LEFT, (flags & UI_MENU_PROCESS_LR_REPEAT) ? 6 : 0))
- {
- // Swap the right panel
- if (minput.code_pressed(KEYCODE_LCONTROL) || minput.code_pressed(JOYCODE_BUTTON1))
- menu_event.iptkey = IPT_UI_LEFT_PANEL;
- return;
- }
-
- if (!ignoreright && exclusive_input_pressed(IPT_UI_RIGHT, (flags & UI_MENU_PROCESS_LR_REPEAT) ? 6 : 0))
- return;
-
- // up backs up by one item
- if (exclusive_input_pressed(IPT_UI_UP, 6))
- {
- // Filter
- if (!ignoreup && (minput.code_pressed(KEYCODE_LALT) || minput.code_pressed(JOYCODE_BUTTON2)))
- {
- menu_event.iptkey = IPT_UI_UP_FILTER;
- return;
- }
-
- // Infos
- if (!ignoreleft && (minput.code_pressed(KEYCODE_LCONTROL) || minput.code_pressed(JOYCODE_BUTTON1)))
- {
- menu_event.iptkey = IPT_UI_UP_PANEL;
- topline_datsview--;
- return;
- }
-
- if (selected == visible_items + 1 || selected == 0 || ui_error)
- return;
-
- selected--;
-
- if (selected == top_line && top_line != 0)
- top_line--;
- }
-
- // down advances by one item
- if (exclusive_input_pressed(IPT_UI_DOWN, 6))
- {
- // Filter
- if (!ignoredown && (minput.code_pressed(KEYCODE_LALT) || minput.code_pressed(JOYCODE_BUTTON2)))
- {
- menu_event.iptkey = IPT_UI_DOWN_FILTER;
- return;
- }
-
- // Infos
- if (!ignoreright && (minput.code_pressed(KEYCODE_LCONTROL) || minput.code_pressed(JOYCODE_BUTTON1)))
- {
- menu_event.iptkey = IPT_UI_DOWN_PANEL;
- topline_datsview++;
- return;
- }
-
- if (selected == item.size() - 1 || selected == visible_items - 1 || ui_error)
- return;
-
- selected++;
-
- if (selected == top_line + visitems + (top_line != 0))
- top_line++;
- }
-
- // page up backs up by visitems
- if (exclusive_input_pressed(IPT_UI_PAGE_UP, 6))
- {
- // Infos
- if (!ignoreleft && (minput.code_pressed(KEYCODE_LCONTROL) || minput.code_pressed(JOYCODE_BUTTON1)))
- {
- menu_event.iptkey = IPT_UI_DOWN_PANEL;
- topline_datsview -= right_visible_lines - 1;
- return;
- }
-
- if (selected < visible_items && !ui_error)
- {
- selected -= visitems;
-
- if (selected < 0)
- selected = 0;
-
- top_line -= visitems - (top_line + visible_lines == visible_items);
- }
- }
-
- // page down advances by visitems
- if (exclusive_input_pressed(IPT_UI_PAGE_DOWN, 6))
- {
- // Infos
- if (!ignoreleft && (minput.code_pressed(KEYCODE_LCONTROL) || minput.code_pressed(JOYCODE_BUTTON1)))
- {
- menu_event.iptkey = IPT_UI_DOWN_PANEL;
- topline_datsview += right_visible_lines - 1;
- return;
- }
-
- if (selected < visible_items && !ui_error)
- {
- selected += visible_lines - 2 + (selected == 0);
-
- if (selected >= visible_items)
- selected = visible_items - 1;
-
- top_line += visible_lines - 2;
- }
- }
-
- // home goes to the start
- if (exclusive_input_pressed(IPT_UI_HOME, 0))
- {
- // Infos
- if (!ignoreleft && (minput.code_pressed(KEYCODE_LCONTROL) || minput.code_pressed(JOYCODE_BUTTON1)))
- {
- menu_event.iptkey = IPT_UI_DOWN_PANEL;
- topline_datsview = 0;
- return;
- }
-
- if (selected < visible_items && !ui_error)
- {
- selected = 0;
- top_line = 0;
- }
- }
-
- // end goes to the last
- if (exclusive_input_pressed(IPT_UI_END, 0))
- {
- // Infos
- if (!ignoreleft && (minput.code_pressed(KEYCODE_LCONTROL) || minput.code_pressed(JOYCODE_BUTTON1)))
- {
- menu_event.iptkey = IPT_UI_DOWN_PANEL;
- topline_datsview = totallines;
- return;
- }
-
- if (selected < visible_items && !ui_error)
- selected = top_line = visible_items - 1;
- }
-
- // pause enables/disables pause
- if (!ui_error && !ignorepause && exclusive_input_pressed(IPT_UI_PAUSE, 0))
- {
- if (machine().paused())
- machine().resume();
- else
- machine().pause();
- }
-
- // handle a toggle cheats request
- if (!ui_error && machine().ui_input().pressed_repeat(IPT_UI_TOGGLE_CHEAT, 0))
- machine().cheat().set_enable(!machine().cheat().enabled());
-
- // see if any other UI keys are pressed
- if (menu_event.iptkey == IPT_INVALID)
- for (int code = IPT_UI_FIRST + 1; code < IPT_UI_LAST; code++)
- {
- if (ui_error || code == IPT_UI_CONFIGURE || (code == IPT_UI_LEFT && ignoreleft) || (code == IPT_UI_RIGHT && ignoreright) || (code == IPT_UI_PAUSE && ignorepause))
- continue;
-
- if (exclusive_input_pressed(code, 0))
- break;
- }
-}
-
-//-------------------------------------------------
-// handle input events for main menu
-//-------------------------------------------------
-
-void ui_menu::handle_main_events(UINT32 flags)
-{
- bool stop = false;
- ui_event local_menu_event;
-
- // loop while we have interesting events
- while (!stop && machine().ui_input().pop_event(&local_menu_event))
- {
- switch (local_menu_event.event_type)
- {
- // if we are hovering over a valid item, select it with a single click
- case UI_EVENT_MOUSE_DOWN:
- {
- if (ui_error)
- {
- menu_event.iptkey = IPT_OTHER;
- stop = true;
- }
- else
- {
- if (hover >= 0 && hover < item.size())
- selected = hover;
- else if (hover == HOVER_ARROW_UP)
- {
- selected -= visitems;
- if (selected < 0)
- selected = 0;
- top_line -= visitems - (top_line + visible_lines == visible_items);
- }
- else if (hover == HOVER_ARROW_DOWN)
- {
- selected += visible_lines - 2 + (selected == 0);
- if (selected >= visible_items)
- selected = visible_items - 1;
- top_line += visible_lines - 2;
- }
- else if (hover == HOVER_UI_RIGHT)
- menu_event.iptkey = IPT_UI_RIGHT;
- else if (hover == HOVER_UI_LEFT)
- menu_event.iptkey = IPT_UI_LEFT;
- else if (hover == HOVER_DAT_DOWN)
- topline_datsview += right_visible_lines - 1;
- else if (hover == HOVER_DAT_UP)
- topline_datsview -= right_visible_lines - 1;
- else if (hover == HOVER_LPANEL_ARROW)
- {
- if (ui_globals::panels_status == HIDE_LEFT_PANEL)
- ui_globals::panels_status = SHOW_PANELS;
- else if (ui_globals::panels_status == HIDE_BOTH)
- ui_globals::panels_status = HIDE_RIGHT_PANEL;
- else if (ui_globals::panels_status == SHOW_PANELS)
- ui_globals::panels_status = HIDE_LEFT_PANEL;
- else if (ui_globals::panels_status == HIDE_RIGHT_PANEL)
- ui_globals::panels_status = HIDE_BOTH;
- }
- else if (hover == HOVER_RPANEL_ARROW)
- {
- if (ui_globals::panels_status == HIDE_RIGHT_PANEL)
- ui_globals::panels_status = SHOW_PANELS;
- else if (ui_globals::panels_status == HIDE_BOTH)
- ui_globals::panels_status = HIDE_LEFT_PANEL;
- else if (ui_globals::panels_status == SHOW_PANELS)
- ui_globals::panels_status = HIDE_RIGHT_PANEL;
- else if (ui_globals::panels_status == HIDE_LEFT_PANEL)
- ui_globals::panels_status = HIDE_BOTH;
- }
- else if (hover == HOVER_B_FAV)
- {
- menu_event.iptkey = IPT_UI_FAVORITES;
- stop = true;
- }
- else if (hover == HOVER_B_EXPORT)
- {
- menu_event.iptkey = IPT_UI_EXPORT;
- stop = true;
- }
- else if (hover == HOVER_B_DATS)
- {
- menu_event.iptkey = IPT_UI_DATS;
- stop = true;
- }
- else if (hover == HOVER_B_SETTINGS)
- {
- menu_event.iptkey = IPT_UI_SELECT;
- selected = visible_items + 1;
- stop = true;
- }
- else if (hover == HOVER_B_FOLDERS)
- {
- menu_event.iptkey = IPT_UI_SELECT;
- selected = visible_items + 2;
- stop = true;
- }
- else if (hover >= HOVER_RP_FIRST && hover <= HOVER_RP_LAST)
- {
- ui_globals::rpanel = (HOVER_RP_FIRST - hover) * (-1);
- stop = true;
- }
- else if (hover >= HOVER_SW_FILTER_FIRST && hover <= HOVER_SW_FILTER_LAST)
- {
- l_sw_hover = (HOVER_SW_FILTER_FIRST - hover) * (-1);
- menu_event.iptkey = IPT_OTHER;
- stop = true;
- }
- else if (hover >= HOVER_FILTER_FIRST && hover <= HOVER_FILTER_LAST)
- {
- l_hover = (HOVER_FILTER_FIRST - hover) * (-1);
- menu_event.iptkey = IPT_OTHER;
- stop = true;
- }
- }
- break;
- }
-
- // if we are hovering over a valid item, fake a UI_SELECT with a double-click
- case UI_EVENT_MOUSE_DOUBLE_CLICK:
- if (hover >= 0 && hover < item.size())
- {
- selected = hover;
- menu_event.iptkey = IPT_UI_SELECT;
- }
-
- if (selected == item.size() - 1)
- {
- menu_event.iptkey = IPT_UI_CANCEL;
- ui_menu::stack_pop(machine());
- }
- stop = true;
- break;
-
- // caught scroll event
- case UI_EVENT_MOUSE_WHEEL:
- if (local_menu_event.zdelta > 0)
- {
- if (selected >= visible_items || selected == 0 || ui_error)
- break;
- selected -= local_menu_event.num_lines;
- if (selected < top_line + (top_line != 0))
- top_line -= local_menu_event.num_lines;
- }
- else
- {
- if (selected >= visible_items - 1 || ui_error)
- break;
- selected += local_menu_event.num_lines;
- if (selected > visible_items - 1)
- selected = visible_items - 1;
- if (selected >= top_line + visitems + (top_line != 0))
- top_line += local_menu_event.num_lines;
- }
- break;
-
- // translate CHAR events into specials
- case UI_EVENT_CHAR:
- menu_event.iptkey = IPT_SPECIAL;
- menu_event.unichar = local_menu_event.ch;
- stop = true;
- break;
-
- // ignore everything else
- default:
- break;
- }
- }
-}
-
-//-------------------------------------------------
-// draw right box title
-//-------------------------------------------------
-
-float ui_menu::draw_right_box_title(float x1, float y1, float x2, float y2)
-{
- ui_manager &mui = machine().ui();
- float line_height = mui.get_line_height();
- float midl = (x2 - x1) * 0.5f;
-
- // add outlined box for options
- mui.draw_outlined_box(container, x1, y1, x2, y2, UI_BACKGROUND_COLOR);
-
- // add separator line
- container->add_line(x1 + midl, y1, x1 + midl, y1 + line_height, UI_LINE_WIDTH, UI_BORDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
-
- std::string buffer[RP_LAST + 1];
- buffer[RP_IMAGES].assign("Images");
- buffer[RP_INFOS].assign("Infos");
-
- for (int cells = RP_IMAGES; cells <= RP_INFOS; cells++)
- {
- rgb_t bgcolor = UI_TEXT_BG_COLOR;
- rgb_t fgcolor = UI_TEXT_COLOR;
-
- if (mouse_hit && x1 <= mouse_x && x1 + midl > mouse_x && y1 <= mouse_y && y1 + line_height > mouse_y)
- {
- if (ui_globals::rpanel != cells)
- {
- bgcolor = UI_MOUSEOVER_BG_COLOR;
- fgcolor = UI_MOUSEOVER_COLOR;
- hover = HOVER_RP_FIRST + cells;
- }
- }
-
- if (ui_globals::rpanel != cells)
- {
- container->add_line(x1, y1 + line_height, x1 + midl, y1 + line_height, UI_LINE_WIDTH,
- UI_BORDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
- if (fgcolor != UI_MOUSEOVER_COLOR)
- fgcolor = UI_CLONE_COLOR;
- }
-
- if (bgcolor != UI_TEXT_BG_COLOR)
- container->add_rect(x1 + UI_LINE_WIDTH, y1 + UI_LINE_WIDTH, x1 + midl - UI_LINE_WIDTH, y1 + line_height,
- bgcolor, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE));
-
- mui.draw_text_full(container, buffer[cells].c_str(), x1 + UI_LINE_WIDTH, y1, midl - UI_LINE_WIDTH,
- JUSTIFY_CENTER, WRAP_NEVER, DRAW_NORMAL, fgcolor, bgcolor, nullptr, nullptr);
- x1 += midl;
- }
-
- return (y1 + line_height + UI_LINE_WIDTH);
-}
-
-//-------------------------------------------------
-// common function for images render
-//-------------------------------------------------
-
-std::string ui_menu::arts_render_common(float origx1, float origy1, float origx2, float origy2)
-{
- std::string snaptext, searchstr;
- get_title_search(snaptext, searchstr);
-
- // apply title to right panel
- float title_size = 0.0f;
- float txt_lenght = 0.0f;
-
- for (int x = FIRST_VIEW; x < LAST_VIEW; x++)
- {
- machine().ui().draw_text_full(container, arts_info[x].title, origx1, origy1, origx2 - origx1, JUSTIFY_CENTER,
- WRAP_TRUNCATE, DRAW_NONE, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, &txt_lenght, nullptr);
- txt_lenght += 0.01f;
- title_size = MAX(txt_lenght, title_size);
- }
-
- machine().ui().draw_text_full(container, snaptext.c_str(), origx1, origy1, origx2 - origx1, JUSTIFY_CENTER, WRAP_TRUNCATE,
- DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
-
- draw_common_arrow(origx1, origy1, origx2, origy2, ui_globals::curimage_view, FIRST_VIEW, LAST_VIEW, title_size);
-
- return searchstr;
+ container->add_quad(
+ x0,
+ y0,
+ x1,
+ y1,
+ fgcolor,
+ arrow_texture,
+ PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(orientation));
}
-
-//-------------------------------------------------
-// draw favorites star
-//-------------------------------------------------
-
-void ui_menu::draw_star(float x0, float y0)
-{
- float y1 = y0 + machine().ui().get_line_height();
- float x1 = x0 + machine().ui().get_line_height() * container->manager().ui_aspect();
- container->add_quad(x0, y0, x1, y1, ARGB_WHITE, star_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_PACKABLE);
-}
-
-//-------------------------------------------------
-// draw toolbar
-//-------------------------------------------------
-
-void ui_menu::draw_toolbar(float x1, float y1, float x2, float y2, bool software)
-{
- ui_manager &mui = machine().ui();
- // draw a box
- mui.draw_outlined_box(container, x1, y1, x2, y2, rgb_t(0xEF, 0x12, 0x47, 0x7B));
-
- // take off the borders
- x1 += UI_BOX_LR_BORDER;
- x2 -= UI_BOX_LR_BORDER;
- y1 += UI_BOX_TB_BORDER;
- y2 -= UI_BOX_TB_BORDER;
-
- render_texture **t_texture = (software) ? sw_toolbar_texture : toolbar_texture;
- bitmap_argb32 **t_bitmap = (software) ? sw_toolbar_bitmap : toolbar_bitmap;
-
- int m_valid = 0;
- for (int x = 0; x < UI_TOOLBAR_BUTTONS; ++x)
- if (t_bitmap[x]->valid())
- m_valid++;
-
- float x_pixel = 1.0f / container->manager().ui_target().width();
- int h_len = mui.get_line_height() * container->manager().ui_target().height();
- h_len = (h_len % 2 == 0) ? h_len : h_len - 1;
- x1 = (x1 + x2) * 0.5f - x_pixel * (m_valid * ((h_len / 2) + 2));
-
- for (int z = 0; z < UI_TOOLBAR_BUTTONS; ++z)
- {
- if (t_bitmap[z]->valid())
- {
- x2 = x1 + x_pixel * h_len;
- rgb_t color(0xEFEFEFEF);
- if (mouse_hit && x1 <= mouse_x && x2 > mouse_x && y1 <= mouse_y && y2 > mouse_y)
- {
- hover = HOVER_B_FAV + z;
- color = ARGB_WHITE;
- float ypos = y2 + machine().ui().get_line_height() + 2.0f * UI_BOX_TB_BORDER;
- mui.draw_text_box(container, hover_msg[z], JUSTIFY_CENTER, 0.5f, ypos, UI_BACKGROUND_COLOR);
- }
-
- container->add_quad(x1, y1, x2, y2, color, t_texture[z], PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
- x1 += x_pixel * (h_len + 2);
- }
- }
-}
-
-
-//-------------------------------------------------
-// perform rendering of image
-//-------------------------------------------------
-
-void ui_menu::arts_render_images(bitmap_argb32 *tmp_bitmap, float origx1, float origy1, float origx2, float origy2, bool software)
-{
- bool no_available = false;
- float line_height = machine().ui().get_line_height();
-
- // if it fails, use the default image
- if (!tmp_bitmap->valid())
- {
- tmp_bitmap->allocate(256, 256);
- for (int x = 0; x < 256; x++)
- for (int y = 0; y < 256; y++)
- tmp_bitmap->pix32(y, x) = no_avail_bitmap->pix32(y, x);
- no_available = true;
- }
-
- if (tmp_bitmap->valid())
- {
- float panel_width = origx2 - origx1 - 0.02f;
- float panel_height = origy2 - origy1 - 0.02f - (2.0f * UI_BOX_TB_BORDER) - (2.0f * line_height);
- int screen_width = machine().render().ui_target().width();
- int screen_height = machine().render().ui_target().height();
- int panel_width_pixel = panel_width * screen_width;
- int panel_height_pixel = panel_height * screen_height;
- float ratio = 0.0f;
-
- // Calculate resize ratios for resizing
- float ratioW = (float)panel_width_pixel / tmp_bitmap->width();
- float ratioH = (float)panel_height_pixel / tmp_bitmap->height();
- float ratioI = (float)tmp_bitmap->height() / tmp_bitmap->width();
- int dest_xPixel = tmp_bitmap->width();
- int dest_yPixel = tmp_bitmap->height();
-
- // force 4:3 ratio min
- if (machine().ui().options().forced_4x3_snapshot() && ratioI < 0.75f && ui_globals::curimage_view == SNAPSHOT_VIEW)
- {
- // smaller ratio will ensure that the image fits in the view
- dest_yPixel = tmp_bitmap->width() * 0.75f;
- ratioH = (float)panel_height_pixel / dest_yPixel;
- ratio = MIN(ratioW, ratioH);
- dest_xPixel = tmp_bitmap->width() * ratio;
- dest_yPixel *= ratio;
- }
- // resize the bitmap if necessary
- else if (ratioW < 1 || ratioH < 1 || (machine().ui().options().enlarge_snaps() && !no_available))
- {
- // smaller ratio will ensure that the image fits in the view
- ratio = MIN(ratioW, ratioH);
- dest_xPixel = tmp_bitmap->width() * ratio;
- dest_yPixel = tmp_bitmap->height() * ratio;
- }
-
- bitmap_argb32 *dest_bitmap;
-
- // resample if necessary
- if (dest_xPixel != tmp_bitmap->width() || dest_yPixel != tmp_bitmap->height())
- {
- dest_bitmap = auto_alloc(machine(), bitmap_argb32);
- dest_bitmap->allocate(dest_xPixel, dest_yPixel);
- render_color color = { 1.0f, 1.0f, 1.0f, 1.0f };
- render_resample_argb_bitmap_hq(*dest_bitmap, *tmp_bitmap, color, true);
- }
- else
- dest_bitmap = tmp_bitmap;
-
- snapx_bitmap->allocate(panel_width_pixel, panel_height_pixel);
- int x1 = (0.5f * panel_width_pixel) - (0.5f * dest_xPixel);
- int y1 = (0.5f * panel_height_pixel) - (0.5f * dest_yPixel);
-
- for (int x = 0; x < dest_xPixel; x++)
- for (int y = 0; y < dest_yPixel; y++)
- snapx_bitmap->pix32(y + y1, x + x1) = dest_bitmap->pix32(y, x);
-
- auto_free(machine(), dest_bitmap);
-
- // apply bitmap
- snapx_texture->set_bitmap(*snapx_bitmap, snapx_bitmap->cliprect(), TEXFORMAT_ARGB32);
- }
- else
- snapx_bitmap->reset();
-}
-
-//-------------------------------------------------
-// draw common arrows
-//-------------------------------------------------
-
-void ui_menu::draw_common_arrow(float origx1, float origy1, float origx2, float origy2, int current, int dmin, int dmax, float title_size)
-{
- 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;
-
- // set left-right arrows dimension
- float ar_x0 = 0.5f * (origx2 + origx1) + 0.5f * title_size + gutter_width - lr_arrow_width;
- float ar_y0 = origy1 + 0.1f * line_height;
- float ar_x1 = 0.5f * (origx2 + origx1) + 0.5f * title_size + gutter_width;
- float ar_y1 = origy1 + 0.9f * line_height;
-
- float al_x0 = 0.5f * (origx2 + origx1) - 0.5f * title_size - gutter_width;
- float al_y0 = origy1 + 0.1f * line_height;
- float al_x1 = 0.5f * (origx2 + origx1) - 0.5f * title_size - gutter_width + lr_arrow_width;
- float al_y1 = origy1 + 0.9f * line_height;
-
- rgb_t fgcolor_right, fgcolor_left;
- fgcolor_right = fgcolor_left = UI_TEXT_COLOR;
-
- // set hover
- if (mouse_hit && ar_x0 <= mouse_x && ar_x1 > mouse_x && ar_y0 <= mouse_y && ar_y1 > mouse_y && current != dmax)
- {
- machine().ui().draw_textured_box(container, ar_x0 + 0.01f, ar_y0, ar_x1 - 0.01f, ar_y1, UI_MOUSEOVER_BG_COLOR, rgb_t(255, 43, 43, 43),
- hilight_main_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE));
- hover = HOVER_UI_RIGHT;
- fgcolor_right = UI_MOUSEOVER_COLOR;
- }
- else if (mouse_hit && al_x0 <= mouse_x && al_x1 > mouse_x && al_y0 <= mouse_y && al_y1 > mouse_y && current != dmin)
- {
- machine().ui().draw_textured_box(container, al_x0 + 0.01f, al_y0, al_x1 - 0.01f, al_y1, UI_MOUSEOVER_BG_COLOR, rgb_t(255, 43, 43, 43),
- hilight_main_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE));
- hover = HOVER_UI_LEFT;
- fgcolor_left = UI_MOUSEOVER_COLOR;
- }
-
- // apply arrow
- if (current == dmin)
- container->add_quad(ar_x0, ar_y0, ar_x1, ar_y1, fgcolor_right, arrow_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(ROT90) | PRIMFLAG_PACKABLE);
- else if (current == dmax)
- container->add_quad(al_x0, al_y0, al_x1, al_y1, fgcolor_left, arrow_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(ROT90 ^ ORIENTATION_FLIP_X) | PRIMFLAG_PACKABLE);
- else
- {
- container->add_quad(ar_x0, ar_y0, ar_x1, ar_y1, fgcolor_right, arrow_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(ROT90) | PRIMFLAG_PACKABLE);
- container->add_quad(al_x0, al_y0, al_x1, al_y1, fgcolor_left, arrow_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(ROT90 ^ ORIENTATION_FLIP_X) | PRIMFLAG_PACKABLE);
- }
-}
-
-//-------------------------------------------------
-// draw icons
-//-------------------------------------------------
-
-void ui_menu::draw_icon(int linenum, void *selectedref, float x0, float y0)
-{
- static const game_driver *olddriver[MAX_ICONS_RENDER] = { nullptr };
- float x1 = x0 + machine().ui().get_line_height() * container->manager().ui_aspect(container);
- float y1 = y0 + machine().ui().get_line_height();
- const game_driver *driver = (const game_driver *)selectedref;
-
- if (olddriver[linenum] != driver || ui_globals::redraw_icon)
- {
- olddriver[linenum] = driver;
-
- // set clone status
- bool cloneof = strcmp(driver->parent, "0");
- if (cloneof)
- {
- int cx = driver_list::find(driver->parent);
- if (cx != -1 && ((driver_list::driver(cx).flags & MACHINE_IS_BIOS_ROOT) != 0))
- cloneof = false;
- }
-
- // get search path
- path_iterator path(machine().ui().options().icons_directory());
- std::string curpath;
- std::string searchstr(machine().ui().options().icons_directory());
-
- // iterate over path and add path for zipped formats
- while (path.next(curpath))
- searchstr.append(";").append(curpath.c_str()).append(PATH_SEPARATOR).append("icons");
-
- bitmap_argb32 *tmp = auto_alloc(machine(), bitmap_argb32);
- emu_file snapfile(searchstr.c_str(), OPEN_FLAG_READ);
- std::string fullname = std::string(driver->name).append(".ico");
- render_load_ico(*tmp, snapfile, nullptr, fullname.c_str());
-
- if (!tmp->valid() && cloneof)
- {
- fullname.assign(driver->parent).append(".ico");
- render_load_ico(*tmp, snapfile, nullptr, fullname.c_str());
- }
-
- if (tmp->valid())
- {
- float panel_width = x1 - x0;
- float panel_height = y1 - y0;
- int screen_width = machine().render().ui_target().width();
- int screen_height = machine().render().ui_target().height();
- int panel_width_pixel = panel_width * screen_width;
- int panel_height_pixel = panel_height * screen_height;
-
- // Calculate resize ratios for resizing
- float ratioW = (float)panel_width_pixel / tmp->width();
- float ratioH = (float)panel_height_pixel / tmp->height();
- int dest_xPixel = tmp->width();
- int dest_yPixel = tmp->height();
-
- if (ratioW < 1 || ratioH < 1)
- {
- // smaller ratio will ensure that the image fits in the view
- float ratio = MIN(ratioW, ratioH);
- dest_xPixel = tmp->width() * ratio;
- dest_yPixel = tmp->height() * ratio;
- }
-
- bitmap_argb32 *dest_bitmap;
- dest_bitmap = auto_alloc(machine(), bitmap_argb32);
-
- // resample if necessary
- if (dest_xPixel != tmp->width() || dest_yPixel != tmp->height())
- {
- dest_bitmap->allocate(dest_xPixel, dest_yPixel);
- render_color color = { 1.0f, 1.0f, 1.0f, 1.0f };
- render_resample_argb_bitmap_hq(*dest_bitmap, *tmp, color, true);
- }
- else
- dest_bitmap = tmp;
-
- icons_bitmap[linenum]->reset();
- icons_bitmap[linenum]->allocate(panel_width_pixel, panel_height_pixel);
-
- for (int x = 0; x < dest_xPixel; x++)
- for (int y = 0; y < dest_yPixel; y++)
- icons_bitmap[linenum]->pix32(y, x) = dest_bitmap->pix32(y, x);
-
- auto_free(machine(), dest_bitmap);
-
- icons_texture[linenum]->set_bitmap(*icons_bitmap[linenum], icons_bitmap[linenum]->cliprect(), TEXFORMAT_ARGB32);
- }
- else {
- if (icons_bitmap[linenum] != nullptr)
- {
- icons_bitmap[linenum]->reset();
- }
- }
- auto_free(machine(), tmp);
- }
-
- if (icons_bitmap[linenum] != nullptr && icons_bitmap[linenum]->valid())
- container->add_quad(x0, y0, x1, y1, ARGB_WHITE, icons_texture[linenum], PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_PACKABLE);
-}
-
-//-------------------------------------------------
-// draw info arrow
-//-------------------------------------------------
-
-void ui_menu::info_arrow(int ub, float origx1, float origx2, float oy1, float line_height, float text_size, float ud_arrow_width)
-{
- rgb_t fgcolor = UI_TEXT_COLOR;
- UINT32 orientation = (!ub) ? ROT0 : ROT0 ^ ORIENTATION_FLIP_Y;
-
- if (mouse_hit && origx1 <= mouse_x && origx2 > mouse_x && oy1 <= mouse_y && oy1 + (line_height * text_size) > mouse_y)
- {
- machine().ui().draw_textured_box(container, origx1 + 0.01f, oy1, origx2 - 0.01f, oy1 + (line_height * text_size), UI_MOUSEOVER_BG_COLOR,
- rgb_t(255, 43, 43, 43), hilight_main_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE));
- hover = (!ub) ? HOVER_DAT_UP : HOVER_DAT_DOWN;
- fgcolor = UI_MOUSEOVER_COLOR;
- }
-
- draw_arrow(container, 0.5f * (origx1 + origx2) - 0.5f * (ud_arrow_width * text_size), oy1 + 0.25f * (line_height * text_size),
- 0.5f * (origx1 + origx2) + 0.5f * (ud_arrow_width * text_size), oy1 + 0.75f * (line_height * text_size), fgcolor, orientation);
-}
-
-//-------------------------------------------------
-// draw - draw palette menu
-//-------------------------------------------------
-
-void ui_menu::draw_palette_menu()
-{
- ui_manager &mui = machine().ui();
- float line_height = mui.get_line_height();
- float lr_arrow_width = 0.4f * line_height * machine().render().ui_aspect();
- float ud_arrow_width = line_height * machine().render().ui_aspect();
- float gutter_width = lr_arrow_width * 1.3f;
- int itemnum, linenum;
-
- if (machine().ui().options().use_background_image() && machine().options().system() == nullptr && bgrnd_bitmap->valid())
- container->add_quad(0.0f, 0.0f, 1.0f, 1.0f, ARGB_WHITE, bgrnd_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
-
- // compute the width and height of the full menu
- float visible_width = 0;
- float visible_main_menu_height = 0;
- for (itemnum = 0; itemnum < item.size(); itemnum++)
- {
- const ui_menu_item &pitem = item[itemnum];
-
- // compute width of left hand side
- float total_width = gutter_width + mui.get_string_width(pitem.text) + gutter_width;
-
- // add in width of right hand side
- if (pitem.subtext)
- total_width += 2.0f * gutter_width + mui.get_string_width(pitem.subtext);
-
- // track the maximum
- if (total_width > visible_width)
- visible_width = total_width;
-
- // track the height as well
- visible_main_menu_height += line_height;
- }
-
- // account for extra space at the top and bottom
- float visible_extra_menu_height = customtop + custombottom;
-
- // add a little bit of slop for rounding
- visible_width += 0.01f;
- visible_main_menu_height += 0.01f;
-
- // if we are too wide or too tall, clamp it down
- if (visible_width + 2.0f * UI_BOX_LR_BORDER > 1.0f)
- visible_width = 1.0f - 2.0f * UI_BOX_LR_BORDER;
-
- // if the menu and extra menu won't fit, take away part of the regular menu, it will scroll
- if (visible_main_menu_height + visible_extra_menu_height + 2.0f * UI_BOX_TB_BORDER > 1.0f)
- visible_main_menu_height = 1.0f - 2.0f * UI_BOX_TB_BORDER - visible_extra_menu_height;
-
- int visible_lines = floor(visible_main_menu_height / line_height);
- visible_main_menu_height = (float)visible_lines * line_height;
-
- // compute top/left of inner menu area by centering
- float visible_left = (1.0f - visible_width) * 0.5f;
- float visible_top = (1.0f - (visible_main_menu_height + visible_extra_menu_height)) * 0.5f;
-
- // if the menu is at the bottom of the extra, adjust
- visible_top += customtop;
-
- // first add us a box
- float x1 = visible_left - UI_BOX_LR_BORDER;
- float y1 = visible_top - UI_BOX_TB_BORDER;
- float x2 = visible_left + visible_width + UI_BOX_LR_BORDER;
- float y2 = visible_top + visible_main_menu_height + UI_BOX_TB_BORDER;
- mui.draw_outlined_box(container, x1, y1, x2, y2, UI_BACKGROUND_COLOR);
-
- // determine the first visible line based on the current selection
- int top_line = selected - visible_lines / 2;
- if (top_line < 0)
- top_line = 0;
- if (top_line + visible_lines >= item.size())
- top_line = item.size() - visible_lines;
-
- // determine effective positions taking into account the hilighting arrows
- float effective_width = visible_width - 2.0f * gutter_width;
- float effective_left = visible_left + gutter_width;
-
- // locate mouse
- mouse_hit = false;
- mouse_button = false;
- mouse_target = machine().ui_input().find_mouse(&mouse_target_x, &mouse_target_y, &mouse_button);
- if (mouse_target != nullptr)
- if (mouse_target->map_point_container(mouse_target_x, mouse_target_y, *container, mouse_x, mouse_y))
- mouse_hit = true;
-
- // loop over visible lines
- hover = item.size() + 1;
- float line_x0 = x1 + 0.5f * UI_LINE_WIDTH;
- float line_x1 = x2 - 0.5f * UI_LINE_WIDTH;
-
- for (linenum = 0; linenum < visible_lines; linenum++)
- {
- float line_y = visible_top + (float)linenum * line_height;
- itemnum = top_line + linenum;
- const ui_menu_item &pitem = item[itemnum];
- const char *itemtext = pitem.text;
- rgb_t fgcolor = UI_TEXT_COLOR;
- rgb_t bgcolor = UI_TEXT_BG_COLOR;
- float line_y0 = line_y;
- float line_y1 = line_y + line_height;
-
- // set the hover if this is our item
- if (mouse_hit && line_x0 <= mouse_x && line_x1 > mouse_x && line_y0 <= mouse_y && line_y1 > mouse_y && pitem.is_selectable())
- hover = itemnum;
-
- // if we're selected, draw with a different background
- if (itemnum == selected)
- {
- fgcolor = UI_SELECTED_COLOR;
- bgcolor = UI_SELECTED_BG_COLOR;
- }
-
- // else if the mouse is over this item, draw with a different background
- else if (itemnum == hover)
- {
- fgcolor = UI_MOUSEOVER_COLOR;
- bgcolor = UI_MOUSEOVER_BG_COLOR;
- }
-
- // if we have some background hilighting to do, add a quad behind everything else
- if (bgcolor != UI_TEXT_BG_COLOR)
- highlight(container, line_x0, line_y0, line_x1, line_y1, bgcolor);
-
- // if we're on the top line, display the up arrow
- if (linenum == 0 && top_line != 0)
- {
- draw_arrow(container,
- 0.5f * (x1 + x2) - 0.5f * ud_arrow_width,
- line_y + 0.25f * line_height,
- 0.5f * (x1 + x2) + 0.5f * ud_arrow_width,
- line_y + 0.75f * line_height,
- fgcolor,
- ROT0);
- if (hover == itemnum)
- hover = HOVER_ARROW_UP;
- }
-
- // if we're on the bottom line, display the down arrow
- else if (linenum == visible_lines - 1 && itemnum != item.size() - 1)
- {
- draw_arrow(container,
- 0.5f * (x1 + x2) - 0.5f * ud_arrow_width,
- line_y + 0.25f * line_height,
- 0.5f * (x1 + x2) + 0.5f * ud_arrow_width,
- line_y + 0.75f * line_height,
- fgcolor,
- ROT0 ^ ORIENTATION_FLIP_Y);
- if (hover == itemnum)
- hover = HOVER_ARROW_DOWN;
- }
-
- // if we're just a divider, draw a line
- else if (strcmp(itemtext, MENU_SEPARATOR_ITEM) == 0)
- container->add_line(visible_left, line_y + 0.5f * line_height, visible_left + visible_width, line_y + 0.5f * line_height, UI_LINE_WIDTH, UI_BORDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
-
- // if we don't have a subitem, just draw the string centered
- else if (pitem.subtext == nullptr)
- mui.draw_text_full(container, itemtext, effective_left, line_y, effective_width,
- JUSTIFY_CENTER, WRAP_TRUNCATE, DRAW_NORMAL, fgcolor, bgcolor, nullptr, nullptr);
-
- // otherwise, draw the item on the left and the subitem text on the right
- else
- {
- const char *subitem_text = pitem.subtext;
- rgb_t color = rgb_t((UINT32)strtoul(subitem_text, nullptr, 16));
-
- // draw the left-side text
- mui.draw_text_full(container, itemtext, effective_left, line_y, effective_width,
- JUSTIFY_LEFT, WRAP_TRUNCATE, DRAW_NORMAL, fgcolor, bgcolor, nullptr, nullptr);
-
- // give 2 spaces worth of padding
- float subitem_width = mui.get_string_width("FF00FF00");
-
- mui.draw_outlined_box(container, effective_left + effective_width - subitem_width, line_y0,
- effective_left + effective_width, line_y1, color);
- }
- }
-
- // if there is something special to add, do it by calling the virtual method
- custom_render((selected >= 0 && selected < item.size()) ? item[selected].ref : nullptr, customtop, custombottom, x1, y1, x2, y2);
-
- // return the number of visible lines, minus 1 for top arrow and 1 for bottom arrow
- visitems = visible_lines - (top_line != 0) - (top_line + visible_lines != item.size());
-}
-
-//-------------------------------------------------
-// draw - draw dats menu
-//-------------------------------------------------
-
-void ui_menu::draw_dats_menu()
-{
- float line_height = machine().ui().get_line_height();
- float ud_arrow_width = line_height * machine().render().ui_aspect();
- float gutter_width = 0.52f * line_height * machine().render().ui_aspect();
- mouse_x = -1, mouse_y = -1;
- float visible_width = 1.0f - 2.0f * UI_BOX_LR_BORDER;
- float visible_left = (1.0f - visible_width) * 0.5f;
- ui_manager &mui = machine().ui();
-
- // draw background image if available
- if (machine().ui().options().use_background_image() && bgrnd_bitmap->valid())
- container->add_quad(0.0f, 0.0f, 1.0f, 1.0f, ARGB_WHITE, bgrnd_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
-
- hover = item.size() + 1;
- visible_items = item.size() - 2;
- float extra_height = 2.0f * line_height;
- float visible_extra_menu_height = customtop + custombottom + extra_height;
-
- // locate mouse
- mouse_hit = false;
- mouse_button = false;
- mouse_target = machine().ui_input().find_mouse(&mouse_target_x, &mouse_target_y, &mouse_button);
- if (mouse_target != nullptr)
- if (mouse_target->map_point_container(mouse_target_x, mouse_target_y, *container, mouse_x, mouse_y))
- mouse_hit = true;
-
- // account for extra space at the top and bottom
- float visible_main_menu_height = 1.0f - 2.0f * UI_BOX_TB_BORDER - visible_extra_menu_height;
- visible_lines = floor(visible_main_menu_height / line_height);
- visible_main_menu_height = (float)(visible_lines * line_height);
-
- // compute top/left of inner menu area by centering
- float visible_top = (1.0f - (visible_main_menu_height + visible_extra_menu_height)) * 0.5f;
-
- // if the menu is at the bottom of the extra, adjust
- visible_top += customtop;
-
- // compute left box size
- float x1 = visible_left;
- float y1 = visible_top - UI_BOX_TB_BORDER;
- float x2 = x1 + visible_width;
- float y2 = visible_top + visible_main_menu_height + UI_BOX_TB_BORDER + extra_height;
- float line = visible_top + (float)(visible_lines * line_height);
-
- //machine().ui().draw_outlined_box(container, x1, y1, x2, y2, rgb_t(0xEF, 0x12, 0x47, 0x7B));
- mui.draw_outlined_box(container, x1, y1, x2, y2, UI_BACKGROUND_COLOR);
-
- if (visible_items < visible_lines)
- visible_lines = visible_items;
- if (top_line < 0)
- top_line = 0;
- if (top_line + visible_lines >= visible_items)
- top_line = visible_items - visible_lines;
-
- // determine effective positions taking into account the hilighting arrows
- float effective_width = visible_width - 2.0f * gutter_width;
- float effective_left = visible_left + gutter_width;
-
- int n_loop = (visible_items >= visible_lines) ? visible_lines : visible_items;
-
- for (int linenum = 0; linenum < n_loop; linenum++)
- {
- float line_y = visible_top + (float)linenum * line_height;
- int itemnum = top_line + linenum;
- const ui_menu_item &pitem = item[itemnum];
- const char *itemtext = pitem.text;
- rgb_t fgcolor = UI_TEXT_COLOR;
- rgb_t bgcolor = UI_TEXT_BG_COLOR;
- float line_x0 = x1 + 0.5f * UI_LINE_WIDTH;
- float line_y0 = line_y;
- float line_x1 = x2 - 0.5f * UI_LINE_WIDTH;
- float line_y1 = line_y + line_height;
-
- // if we're on the top line, display the up arrow
- if (linenum == 0 && top_line != 0)
- {
- draw_arrow(container, 0.5f * (x1 + x2) - 0.5f * ud_arrow_width, line_y + 0.25f * line_height,
- 0.5f * (x1 + x2) + 0.5f * ud_arrow_width, line_y + 0.75f * line_height, fgcolor, ROT0);
-
- if (mouse_hit && line_x0 <= mouse_x && line_x1 > mouse_x && line_y0 <= mouse_y && line_y1 > mouse_y)
- {
- fgcolor = UI_MOUSEOVER_COLOR;
- bgcolor = UI_MOUSEOVER_BG_COLOR;
- highlight(container, line_x0, line_y0, line_x1, line_y1, bgcolor);
- hover = HOVER_ARROW_UP;
- }
- }
- // if we're on the bottom line, display the down arrow
- else if (linenum == visible_lines - 1 && itemnum != visible_items - 1)
- {
- draw_arrow(container, 0.5f * (x1 + x2) - 0.5f * ud_arrow_width, line_y + 0.25f * line_height,
- 0.5f * (x1 + x2) + 0.5f * ud_arrow_width, line_y + 0.75f * line_height, fgcolor, ROT0 ^ ORIENTATION_FLIP_Y);
-
- if (mouse_hit && line_x0 <= mouse_x && line_x1 > mouse_x && line_y0 <= mouse_y && line_y1 > mouse_y)
- {
- fgcolor = UI_MOUSEOVER_COLOR;
- bgcolor = UI_MOUSEOVER_BG_COLOR;
- highlight(container, line_x0, line_y0, line_x1, line_y1, bgcolor);
- hover = HOVER_ARROW_DOWN;
- }
- }
-
- // draw dats text
- else if (pitem.subtext == nullptr)
- {
- mui.draw_text_full(container, itemtext, effective_left, line_y, effective_width, JUSTIFY_LEFT, WRAP_NEVER,
- DRAW_NORMAL, fgcolor, bgcolor, nullptr, nullptr);
- }
- }
-
- for (size_t count = visible_items; count < item.size(); count++)
- {
- const ui_menu_item &pitem = item[count];
- const char *itemtext = pitem.text;
- float line_x0 = x1 + 0.5f * UI_LINE_WIDTH;
- float line_y0 = line;
- float line_x1 = x2 - 0.5f * UI_LINE_WIDTH;
- float line_y1 = line + line_height;
- rgb_t fgcolor = UI_SELECTED_COLOR;
- rgb_t bgcolor = UI_SELECTED_BG_COLOR;
-
- if (mouse_hit && line_x0 <= mouse_x && line_x1 > mouse_x && line_y0 <= mouse_y && line_y1 > mouse_y && pitem.is_selectable())
- hover = count;
-
- if (strcmp(itemtext, MENU_SEPARATOR_ITEM) == 0)
- container->add_line(visible_left, line + 0.5f * line_height, visible_left + visible_width, line + 0.5f * line_height,
- UI_LINE_WIDTH, UI_TEXT_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
- else
- {
- highlight(container, line_x0, line_y0, line_x1, line_y1, bgcolor);
- mui.draw_text_full(container, itemtext, effective_left, line, effective_width, JUSTIFY_CENTER, WRAP_TRUNCATE,
- DRAW_NORMAL, fgcolor, bgcolor, nullptr, nullptr);
- }
- line += line_height;
- }
-
- // if there is something special to add, do it by calling the virtual method
- custom_render((selected >= 0 && selected < item.size()) ? item[selected].ref : nullptr, customtop, custombottom, x1, y1, x2, y2);
-
- // return the number of visible lines, minus 1 for top arrow and 1 for bottom arrow
- visitems = visible_lines - (top_line != 0) - (top_line + visible_lines != visible_items);
-} \ No newline at end of file