diff options
| author | 2016-07-01 16:03:10 +1000 | |
|---|---|---|
| committer | 2016-07-01 16:03:31 +1000 | |
| commit | 0630edb2bfbf7bb5b2e2d5acefa4bfd4b494b5f9 (patch) | |
| tree | 06c3befa1017bbb984c7a9bbc19d7e1ba87019e1 /src | |
| parent | f23c2db0db31e68a6bf96fa371b771017fb19842 (diff) | |
MT06268 fix crash when drawing menus
Diffstat (limited to 'src')
| -rw-r--r-- | src/frontend/mame/ui/menu.cpp | 121 |
1 files changed, 52 insertions, 69 deletions
diff --git a/src/frontend/mame/ui/menu.cpp b/src/frontend/mame/ui/menu.cpp index 0dced188c9d..a8f8be24390 100644 --- a/src/frontend/mame/ui/menu.cpp +++ b/src/frontend/mame/ui/menu.cpp @@ -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; |
