mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
MT06268 fix crash when drawing menus
This commit is contained in:
parent
f23c2db0db
commit
0630edb2bf
@ -522,13 +522,10 @@ void menu::draw(UINT32 flags, float origx0, float origy0)
|
||||
bool const customonly = (flags & PROCESS_CUSTOM_ONLY);
|
||||
bool const noimage = (flags & PROCESS_NOIMAGE);
|
||||
bool const noinput = (flags & PROCESS_NOINPUT);
|
||||
float line_height = 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;
|
||||
int itemnum, linenum;
|
||||
float const line_height = ui().get_line_height();
|
||||
float const lr_arrow_width = 0.4f * line_height * machine().render().ui_aspect();
|
||||
float const ud_arrow_width = line_height * machine().render().ui_aspect();
|
||||
float const gutter_width = lr_arrow_width * 1.3f;
|
||||
|
||||
if (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, rgb_t::white, bgrnd_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
|
||||
@ -536,12 +533,10 @@ void menu::draw(UINT32 flags, float origx0, float origy0)
|
||||
// compute the width and height of the full menu
|
||||
float visible_width = 0;
|
||||
float visible_main_menu_height = 0;
|
||||
for (auto & pitem : item)
|
||||
for (auto const &pitem : item)
|
||||
{
|
||||
float total_width;
|
||||
|
||||
// compute width of left hand side
|
||||
total_width = gutter_width + ui().get_string_width(pitem.text.c_str()) + gutter_width;
|
||||
float total_width = gutter_width + ui().get_string_width(pitem.text.c_str()) + gutter_width;
|
||||
|
||||
// add in width of right hand side
|
||||
if (!pitem.subtext.empty())
|
||||
@ -556,7 +551,7 @@ void menu::draw(UINT32 flags, float origx0, float origy0)
|
||||
}
|
||||
|
||||
// account for extra space at the top and bottom
|
||||
float visible_extra_menu_height = customtop + custombottom;
|
||||
float const visible_extra_menu_height = customtop + custombottom;
|
||||
|
||||
// add a little bit of slop for rounding
|
||||
visible_width += 0.01f;
|
||||
@ -575,45 +570,34 @@ void menu::draw(UINT32 flags, float origx0, float origy0)
|
||||
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;
|
||||
float const visible_left = (1.0f - visible_width) * 0.5f;
|
||||
float const visible_top = ((1.0f - visible_main_menu_height - visible_extra_menu_height) * 0.5f) + 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;
|
||||
float const x1 = visible_left - UI_BOX_LR_BORDER;
|
||||
float const y1 = visible_top - UI_BOX_TB_BORDER;
|
||||
float const x2 = visible_left + visible_width + UI_BOX_LR_BORDER;
|
||||
float const y2 = visible_top + visible_main_menu_height + UI_BOX_TB_BORDER;
|
||||
if (!customonly)
|
||||
ui().draw_outlined_box(container, x1, y1, x2, y2, UI_BACKGROUND_COLOR);
|
||||
|
||||
if (top_line < 0 || selected == 0)
|
||||
top_line = 0;
|
||||
if (top_line > item.size() - visible_lines || selected == (item.size() - 1))
|
||||
top_line = item.size() - visible_lines;
|
||||
if (selected >= top_line + visible_lines)
|
||||
if (selected >= (top_line + visible_lines))
|
||||
top_line = selected - (visible_lines / 2);
|
||||
|
||||
bool show_top_arrow = false;
|
||||
bool show_bottom_arrow = false;
|
||||
if ((top_line > (item.size() - visible_lines)) || (selected == (item.size() - 1)))
|
||||
top_line = item.size() - visible_lines;
|
||||
|
||||
// if scrolling, show arrows
|
||||
if (item.size() > visible_lines)
|
||||
{
|
||||
if (top_line > 0)
|
||||
show_top_arrow = true;
|
||||
if (top_line != item.size() - visible_lines)
|
||||
show_bottom_arrow = true;
|
||||
}
|
||||
bool const show_top_arrow((item.size() > visible_lines) && (top_line > 0));
|
||||
bool const show_bottom_arrow((item.size() > visible_lines) && (top_line != (item.size() - visible_lines)));
|
||||
|
||||
// set the number of visible lines, minus 1 for top arrow and 1 for bottom arrow
|
||||
visitems = visible_lines - show_top_arrow - show_bottom_arrow;
|
||||
visitems = visible_lines - (show_top_arrow ? 1 : 0) - (show_bottom_arrow ? 1 : 0);
|
||||
|
||||
// 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;
|
||||
float const effective_width = visible_width - 2.0f * gutter_width;
|
||||
float const effective_left = visible_left + gutter_width;
|
||||
|
||||
// locate mouse
|
||||
mouse_hit = false;
|
||||
@ -629,22 +613,22 @@ void menu::draw(UINT32 flags, float origx0, float origy0)
|
||||
|
||||
// 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;
|
||||
bool selected_subitem_too_big = false;
|
||||
float const line_x0 = x1 + 0.5f * UI_LINE_WIDTH;
|
||||
float const line_x1 = x2 - 0.5f * UI_LINE_WIDTH;
|
||||
if (!customonly)
|
||||
{
|
||||
for (linenum = 0; linenum < visible_lines; linenum++)
|
||||
for (int linenum = 0; linenum < visible_lines; linenum++)
|
||||
{
|
||||
float line_y = visible_top + (float)linenum * line_height;
|
||||
itemnum = top_line + linenum;
|
||||
const menu_item &pitem = item[itemnum];
|
||||
const char *itemtext = pitem.text.c_str();
|
||||
auto const itemnum = top_line + linenum;
|
||||
menu_item const &pitem = item[itemnum];
|
||||
char const *const itemtext = pitem.text.c_str();
|
||||
rgb_t fgcolor = UI_TEXT_COLOR;
|
||||
rgb_t bgcolor = UI_TEXT_BG_COLOR;
|
||||
rgb_t fgcolor2 = UI_SUBITEM_COLOR;
|
||||
rgb_t fgcolor3 = UI_CLONE_COLOR;
|
||||
float line_y0 = line_y;
|
||||
float line_y1 = line_y + line_height;
|
||||
float const line_y0 = visible_top + (float)linenum * line_height;
|
||||
float const line_y1 = line_y0 + 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 && is_selectable(pitem))
|
||||
@ -673,9 +657,9 @@ void menu::draw(UINT32 flags, float origx0, float origy0)
|
||||
{
|
||||
draw_arrow(container,
|
||||
0.5f * (x1 + x2) - 0.5f * ud_arrow_width,
|
||||
line_y + 0.25f * line_height,
|
||||
line_y0 + 0.25f * line_height,
|
||||
0.5f * (x1 + x2) + 0.5f * ud_arrow_width,
|
||||
line_y + 0.75f * line_height,
|
||||
line_y0 + 0.75f * line_height,
|
||||
fgcolor,
|
||||
ROT0);
|
||||
if (hover == itemnum)
|
||||
@ -687,9 +671,9 @@ void menu::draw(UINT32 flags, float origx0, float origy0)
|
||||
{
|
||||
draw_arrow(container,
|
||||
0.5f * (x1 + x2) - 0.5f * ud_arrow_width,
|
||||
line_y + 0.25f * line_height,
|
||||
line_y0 + 0.25f * line_height,
|
||||
0.5f * (x1 + x2) + 0.5f * ud_arrow_width,
|
||||
line_y + 0.75f * line_height,
|
||||
line_y0 + 0.75f * line_height,
|
||||
fgcolor,
|
||||
ROT0 ^ ORIENTATION_FLIP_Y);
|
||||
if (hover == itemnum)
|
||||
@ -698,7 +682,7 @@ void menu::draw(UINT32 flags, float origx0, float origy0)
|
||||
|
||||
// if we're just a divider, draw a line
|
||||
else if (pitem.type == menu_item_type::SEPARATOR)
|
||||
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));
|
||||
container->add_line(visible_left, line_y0 + 0.5f * line_height, visible_left + visible_width, line_y0 + 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.empty())
|
||||
@ -706,22 +690,22 @@ void menu::draw(UINT32 flags, float origx0, float origy0)
|
||||
if (pitem.flags & FLAG_UI_HEADING)
|
||||
{
|
||||
float heading_width = ui().get_string_width(itemtext);
|
||||
container->add_line(visible_left, line_y + 0.5f * line_height, visible_left + ((visible_width - heading_width) / 2) - UI_BOX_LR_BORDER, line_y + 0.5f * line_height, UI_LINE_WIDTH, UI_BORDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
|
||||
container->add_line(visible_left + visible_width - ((visible_width - heading_width) / 2) + UI_BOX_LR_BORDER, 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));
|
||||
container->add_line(visible_left, line_y0 + 0.5f * line_height, visible_left + ((visible_width - heading_width) / 2) - UI_BOX_LR_BORDER, line_y0 + 0.5f * line_height, UI_LINE_WIDTH, UI_BORDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
|
||||
container->add_line(visible_left + visible_width - ((visible_width - heading_width) / 2) + UI_BOX_LR_BORDER, line_y0 + 0.5f * line_height, visible_left + visible_width, line_y0 + 0.5f * line_height, UI_LINE_WIDTH, UI_BORDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
|
||||
}
|
||||
ui().draw_text_full(container, itemtext, effective_left, line_y, effective_width,
|
||||
ui().draw_text_full(container, itemtext, effective_left, line_y0, effective_width,
|
||||
ui::text_layout::CENTER, ui::text_layout::TRUNCATE, mame_ui_manager::NORMAL, fgcolor, bgcolor, nullptr, nullptr);
|
||||
}
|
||||
|
||||
// otherwise, draw the item on the left and the subitem text on the right
|
||||
else
|
||||
{
|
||||
int subitem_invert = pitem.flags & FLAG_INVERT;
|
||||
const char *subitem_text = pitem.subtext.c_str();
|
||||
bool const subitem_invert(pitem.flags & FLAG_INVERT);
|
||||
char const *subitem_text(pitem.subtext.c_str());
|
||||
float item_width, subitem_width;
|
||||
|
||||
// draw the left-side text
|
||||
ui().draw_text_full(container, itemtext, effective_left, line_y, effective_width,
|
||||
ui().draw_text_full(container, itemtext, effective_left, line_y0, effective_width,
|
||||
ui::text_layout::LEFT, ui::text_layout::TRUNCATE, mame_ui_manager::NORMAL, fgcolor, bgcolor, &item_width, nullptr);
|
||||
|
||||
// give 2 spaces worth of padding
|
||||
@ -746,7 +730,7 @@ void menu::draw(UINT32 flags, float origx0, float origy0)
|
||||
fgcolor2 = rgb_t(0xff,0xff,0x00);
|
||||
|
||||
// draw the subitem right-justified
|
||||
ui().draw_text_full(container, subitem_text, effective_left + item_width, line_y, effective_width - item_width,
|
||||
ui().draw_text_full(container, subitem_text, effective_left + item_width, line_y0, effective_width - item_width,
|
||||
ui::text_layout::RIGHT, ui::text_layout::TRUNCATE, mame_ui_manager::NORMAL, subitem_invert ? fgcolor3 : fgcolor2, bgcolor, &subitem_width, nullptr);
|
||||
|
||||
// apply arrows
|
||||
@ -754,9 +738,9 @@ void menu::draw(UINT32 flags, float origx0, float origy0)
|
||||
{
|
||||
draw_arrow(container,
|
||||
effective_left + effective_width - subitem_width - gutter_width,
|
||||
line_y + 0.1f * line_height,
|
||||
line_y0 + 0.1f * line_height,
|
||||
effective_left + effective_width - subitem_width - gutter_width + lr_arrow_width,
|
||||
line_y + 0.9f * line_height,
|
||||
line_y0 + 0.9f * line_height,
|
||||
fgcolor,
|
||||
ROT90 ^ ORIENTATION_FLIP_X);
|
||||
}
|
||||
@ -764,9 +748,9 @@ void menu::draw(UINT32 flags, float origx0, float origy0)
|
||||
{
|
||||
draw_arrow(container,
|
||||
effective_left + effective_width + gutter_width - lr_arrow_width,
|
||||
line_y + 0.1f * line_height,
|
||||
line_y0 + 0.1f * line_height,
|
||||
effective_left + effective_width + gutter_width,
|
||||
line_y + 0.9f * line_height,
|
||||
line_y0 + 0.9f * line_height,
|
||||
fgcolor,
|
||||
ROT90);
|
||||
}
|
||||
@ -777,20 +761,19 @@ void menu::draw(UINT32 flags, float origx0, float origy0)
|
||||
// if the selected subitem is too big, display it in a separate offset box
|
||||
if (selected_subitem_too_big)
|
||||
{
|
||||
const menu_item &pitem = item[selected];
|
||||
int subitem_invert = pitem.flags & FLAG_INVERT;
|
||||
linenum = selected - top_line;
|
||||
float line_y = visible_top + (float)linenum * line_height;
|
||||
menu_item const &pitem = item[selected];
|
||||
bool const subitem_invert(pitem.flags & FLAG_INVERT);
|
||||
auto const linenum = selected - top_line;
|
||||
float const line_y = visible_top + (float)linenum * line_height;
|
||||
float target_width, target_height;
|
||||
float target_x, target_y;
|
||||
|
||||
// compute the multi-line target width/height
|
||||
ui().draw_text_full(container, pitem.subtext.c_str(), 0, 0, visible_width * 0.75f,
|
||||
ui::text_layout::RIGHT, ui::text_layout::WORD, mame_ui_manager::NONE, rgb_t::white, rgb_t::black, &target_width, &target_height);
|
||||
|
||||
// determine the target location
|
||||
target_x = visible_left + visible_width - target_width - UI_BOX_LR_BORDER;
|
||||
target_y = line_y + line_height + UI_BOX_TB_BORDER;
|
||||
float const target_x = visible_left + visible_width - target_width - UI_BOX_LR_BORDER;
|
||||
float target_y = line_y + line_height + UI_BOX_TB_BORDER;
|
||||
if (target_y + target_height + UI_BOX_TB_BORDER > visible_main_menu_height)
|
||||
target_y = line_y - target_height - UI_BOX_TB_BORDER;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user