From b3aedc5d7e4221aa3af7c885837fd6d224e79aed Mon Sep 17 00:00:00 2001 From: Nathan Woods Date: Thu, 30 Jan 2014 15:13:54 +0000 Subject: [PATCH] Miscellaneous cleanups to src/emu/ui/menu.?, also added some accessors --- src/emu/ui/menu.c | 495 ++++++++++++++++++++++++---------------------- src/emu/ui/menu.h | 101 +++++----- src/emu/ui/ui.h | 2 +- 3 files changed, 316 insertions(+), 282 deletions(-) diff --git a/src/emu/ui/menu.c b/src/emu/ui/menu.c index 07123b9e15d..57d20c990a5 100644 --- a/src/emu/ui/menu.c +++ b/src/emu/ui/menu.c @@ -42,10 +42,10 @@ render_texture *ui_menu::arrow_texture; INLINE FUNCTIONS ***************************************************************************/ -/*------------------------------------------------- - is_selectable - return TRUE if the given - item is selectable --------------------------------------------------*/ +//------------------------------------------------- +// is_selectable - return TRUE if the given +// item is selectable +//------------------------------------------------- inline bool ui_menu_item::is_selectable() const { @@ -53,11 +53,11 @@ inline bool ui_menu_item::is_selectable() const } -/*------------------------------------------------- - exclusive_input_pressed - return TRUE if the - given key is pressed and we haven't already - reported a key --------------------------------------------------*/ +//------------------------------------------------- +// exclusive_input_pressed - return TRUE if the +// given key is pressed and we haven't already +// reported a key +//------------------------------------------------- inline bool ui_menu::exclusive_input_pressed(int key, int repeat) { @@ -75,18 +75,18 @@ inline bool ui_menu::exclusive_input_pressed(int key, int repeat) CORE SYSTEM MANAGEMENT ***************************************************************************/ -/*------------------------------------------------- - init - initialize the menu system --------------------------------------------------*/ +//------------------------------------------------- +// init - initialize the menu system +//------------------------------------------------- void ui_menu::init(running_machine &machine) { int x; - /* initialize the menu stack */ + // initialize the menu stack ui_menu::stack_reset(machine); - /* create a texture for hilighting items */ + // create a texture for hilighting items hilight_bitmap = auto_bitmap_rgb32_alloc(machine, 256, 1); for (x = 0; x < 256; x++) { @@ -98,25 +98,25 @@ void ui_menu::init(running_machine &machine) hilight_texture = machine.render().texture_alloc(); hilight_texture->set_bitmap(*hilight_bitmap, hilight_bitmap->cliprect(), TEXFORMAT_ARGB32); - /* create a texture for arrow icons */ + // create a texture for arrow icons arrow_texture = machine.render().texture_alloc(render_triangle); - /* add an exit callback to free memory */ + // add an exit callback to free memory machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(ui_menu::exit), &machine)); } -/*------------------------------------------------- - exit - clean up after ourselves --------------------------------------------------*/ +//------------------------------------------------- +// exit - clean up after ourselves +//------------------------------------------------- void ui_menu::exit(running_machine &machine) { - /* free menus */ + // free menus ui_menu::stack_reset(machine); ui_menu::clear_free_list(machine); - /* free textures */ + // free textures machine.render().texture_free(hilight_texture); machine.render().texture_free(arrow_texture); } @@ -127,25 +127,26 @@ void ui_menu::exit(running_machine &machine) CORE MENU MANAGEMENT ***************************************************************************/ -/*------------------------------------------------- - ui_menu - menu constructor --------------------------------------------------*/ +//------------------------------------------------- +// ui_menu - menu constructor +//------------------------------------------------- + ui_menu::ui_menu(running_machine &machine, render_container *_container) : m_machine(machine) { - special_main_menu = false; + m_special_main_menu = false; container = _container; reset(UI_MENU_RESET_SELECT_FIRST); } -/*------------------------------------------------- - ~ui_menu - menu destructor --------------------------------------------------*/ +//------------------------------------------------- +// ~ui_menu - menu destructor +//------------------------------------------------- ui_menu::~ui_menu() { - /* free the pools */ + // free the pools while (pool) { ui_menu_pool *ppool = pool; @@ -153,20 +154,20 @@ ui_menu::~ui_menu() auto_free(machine(), ppool); } - /* free the item array */ + // free the item array if (item) auto_free(machine(), item); } -/*------------------------------------------------- - reset - free all items in the menu, - and all memory allocated from the memory pool --------------------------------------------------*/ +//------------------------------------------------- +// reset - free all items in the menu, +// and all memory allocated from the memory pool +//------------------------------------------------- void ui_menu::reset(ui_menu_reset_options options) { - /* based on the reset option, set the reset info */ + // based on the reset option, set the reset info resetpos = 0; resetref = NULL; if (options == UI_MENU_RESET_REMEMBER_POSITION) @@ -174,7 +175,7 @@ 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 numitems back to 0 */ + // reset all the pools and the numitems back to 0 for (ui_menu_pool *ppool = pool; ppool != NULL; ppool = ppool->next) ppool->top = (UINT8 *)(ppool + 1); numitems = 0; @@ -183,7 +184,7 @@ void ui_menu::reset(ui_menu_reset_options options) astring backtext; backtext.printf("Return to %s",emulator_info::get_capstartgamenoun()); - /* add an item to return */ + // add an item to return if (parent == NULL) item_append(backtext.cstr(), NULL, 0, NULL); else if (parent->is_special_main_menu()) @@ -193,30 +194,32 @@ void ui_menu::reset(ui_menu_reset_options options) } -/*------------------------------------------------- - is_special_main_menu - returns whether the - menu has special needs --------------------------------------------------*/ +//------------------------------------------------- +// is_special_main_menu - returns whether the +// menu has special needs +//------------------------------------------------- + bool ui_menu::is_special_main_menu() const { - return special_main_menu; + return m_special_main_menu; } -/*------------------------------------------------- - set_special_main_menu - set whether the - menu has special needs --------------------------------------------------*/ +//------------------------------------------------- +// set_special_main_menu - set whether the +// menu has special needs +//------------------------------------------------- + void ui_menu::set_special_main_menu(bool special) { - special_main_menu = special; + m_special_main_menu = special; } -/*------------------------------------------------- - populated - returns true if the menu - has any non-default items in it --------------------------------------------------*/ +//------------------------------------------------- +// populated - returns true if the menu +// has any non-default items in it +//------------------------------------------------- bool ui_menu::populated() { @@ -224,25 +227,25 @@ bool ui_menu::populated() } -/*------------------------------------------------- - item_append - append a new item to the - end of the menu --------------------------------------------------*/ +//------------------------------------------------- +// 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 */ + // only allow multiline as the first item if ((flags & MENU_FLAG_MULTILINE) != 0) assert(numitems == 1); - /* only allow a single multi-line item */ + // only allow a single multi-line item else if (numitems >= 2) assert((item[0].flags & MENU_FLAG_MULTILINE) == 0); - /* realloc the item array if necessary */ + // realloc the item array if necessary if (numitems >= allocitems) { int olditems = allocitems; @@ -255,21 +258,21 @@ void ui_menu::item_append(const char *text, const char *subtext, UINT32 flags, v } index = numitems++; - /* copy the previous last item to the next one */ + // 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 */ + // allocate a new item and populate it pitem = &item[index]; pitem->text = (text != NULL) ? pool_strdup(text) : NULL; pitem->subtext = (subtext != NULL) ? pool_strdup(subtext) : NULL; pitem->flags = flags; pitem->ref = ref; - /* update the selection if we need to */ + // update the selection if we need to if (resetpos == index || (resetref != NULL && resetref == ref)) selected = index; if (resetpos == numitems - 1) @@ -277,37 +280,37 @@ void ui_menu::item_append(const char *text, const char *subtext, UINT32 flags, v } -/*------------------------------------------------- - process - process a menu, drawing it - and returning any interesting events --------------------------------------------------*/ +//------------------------------------------------- +// process - process a menu, drawing it +// and returning any interesting events +//------------------------------------------------- const ui_menu_event *ui_menu::process(UINT32 flags) { - /* reset the menu_event */ + // reset the menu_event menu_event.iptkey = IPT_INVALID; - /* first make sure our selection is valid */ + // first make sure our selection is valid validate_selection(1); - /* draw the menu */ + // draw the menu if (numitems > 1 && (item[0].flags & MENU_FLAG_MULTILINE) != 0) draw_text_box(); else draw(flags & UI_MENU_PROCESS_CUSTOM_ONLY); - /* process input */ + // process input if (!(flags & UI_MENU_PROCESS_NOKEYS)) { - /* read events */ + // read events handle_events(); - /* handle the keys if we don't already have an menu_event */ + // handle the keys if we don't already have an menu_event if (menu_event.iptkey == IPT_INVALID) handle_keys(flags); } - /* update the selected item in the menu_event */ + // update the selected item in the menu_event if (menu_event.iptkey != IPT_INVALID && selected >= 0 && selected < numitems) { menu_event.itemref = item[selected].ref; @@ -317,10 +320,10 @@ const ui_menu_event *ui_menu::process(UINT32 flags) } -/*------------------------------------------------- - m_pool_alloc - allocate temporary memory - from the menu's memory pool --------------------------------------------------*/ +//------------------------------------------------- +// m_pool_alloc - allocate temporary memory +// from the menu's memory pool +//------------------------------------------------- void *ui_menu::m_pool_alloc(size_t size) { @@ -328,7 +331,7 @@ void *ui_menu::m_pool_alloc(size_t size) assert(size < UI_MENU_POOL_SIZE); - /* find a pool with enough room */ + // find a pool with enough room for (ppool = pool; ppool != NULL; ppool = ppool->next) if (ppool->end - ppool->top >= size) { @@ -337,10 +340,10 @@ void *ui_menu::m_pool_alloc(size_t size) return result; } - /* allocate a new pool */ + // allocate a new pool ppool = (ui_menu_pool *)auto_alloc_array_clear(machine(), UINT8, sizeof(*ppool) + UI_MENU_POOL_SIZE); - /* wire it up */ + // wire it up ppool->next = pool; pool = ppool; ppool->top = (UINT8 *)(ppool + 1); @@ -349,10 +352,10 @@ void *ui_menu::m_pool_alloc(size_t size) } -/*------------------------------------------------- - pool_strdup - make a temporary string - copy in the menu's memory pool --------------------------------------------------*/ +//------------------------------------------------- +// pool_strdup - make a temporary string +// copy in the menu's memory pool +//------------------------------------------------- const char *ui_menu::pool_strdup(const char *string) { @@ -360,10 +363,10 @@ const char *ui_menu::pool_strdup(const char *string) } -/*------------------------------------------------- - get_selection - retrieves the index - of the currently selected menu item --------------------------------------------------*/ +//------------------------------------------------- +// get_selection - retrieves the index +// of the currently selected menu item +//------------------------------------------------- void *ui_menu::get_selection() { @@ -371,10 +374,10 @@ void *ui_menu::get_selection() } -/*------------------------------------------------- - set_selection - changes the index - of the currently selected menu item --------------------------------------------------*/ +//------------------------------------------------- +// set_selection - changes the index +// of the currently selected menu item +//------------------------------------------------- void ui_menu::set_selection(void *selected_itemref) { @@ -395,9 +398,9 @@ void ui_menu::set_selection(void *selected_itemref) INTERNAL MENU PROCESSING ***************************************************************************/ -/*------------------------------------------------- - draw - draw a menu --------------------------------------------------*/ +//------------------------------------------------- +// draw - draw a menu +//------------------------------------------------- void ui_menu::draw(bool customonly) { @@ -420,7 +423,7 @@ void ui_menu::draw(bool customonly) INT32 mouse_target_x, mouse_target_y; float mouse_x = -1, mouse_y = -1; - /* compute the width and height of the full menu */ + // compute the width and height of the full menu visible_width = 0; visible_main_menu_height = 0; for (itemnum = 0; itemnum < numitems; itemnum++) @@ -428,47 +431,47 @@ void ui_menu::draw(bool customonly) const ui_menu_item &pitem = item[itemnum]; float total_width; - /* compute width of left hand side */ + // compute width of left hand side total_width = gutter_width + machine().ui().get_string_width(pitem.text) + gutter_width; - /* add in width of right hand side */ + // add in width of right hand side if (pitem.subtext) total_width += 2.0f * gutter_width + machine().ui().get_string_width(pitem.subtext); - /* track the maximum */ + // track the maximum if (total_width > visible_width) visible_width = total_width; - /* track the height as well */ + // track the height as well visible_main_menu_height += line_height; } - /* account for extra space at the top and bottom */ + // account for extra space at the top and bottom visible_extra_menu_height = customtop + custombottom; - /* add a little bit of slop for rounding */ + // 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 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 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; 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 */ + // compute top/left of inner menu area by centering 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 */ + // if the menu is at the bottom of the extra, adjust visible_top += customtop; - /* first add us a box */ + // first add us a box x1 = visible_left - UI_BOX_LR_BORDER; y1 = visible_top - UI_BOX_TB_BORDER; x2 = visible_left + visible_width + UI_BOX_LR_BORDER; @@ -476,18 +479,18 @@ void ui_menu::draw(bool customonly) 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 */ + // determine the first visible line based on the current selection top_line = selected - visible_lines / 2; if (top_line < 0) top_line = 0; if (top_line + visible_lines >= numitems) top_line = numitems - visible_lines; - /* determine effective positions taking into account the hilighting arrows */ + // determine effective positions taking into account the hilighting arrows effective_width = visible_width - 2.0f * gutter_width; effective_left = visible_left + gutter_width; - /* locate mouse */ + // locate mouse mouse_hit = false; mouse_button = false; if (!customonly) @@ -498,7 +501,7 @@ void ui_menu::draw(bool customonly) mouse_hit = true; } - /* loop over visible lines */ + // loop over visible lines hover = numitems + 1; if (!customonly) for (linenum = 0; linenum < visible_lines; linenum++) @@ -516,11 +519,11 @@ void ui_menu::draw(bool customonly) float line_x1 = x2 - 0.5f * UI_LINE_WIDTH; float line_y1 = line_y + line_height; - /* set the hover if this is our item */ + // 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 we're selected, draw with a different background if (itemnum == selected) { fgcolor = UI_SELECTED_COLOR; @@ -529,7 +532,7 @@ void ui_menu::draw(bool customonly) fgcolor3 = UI_SELECTED_COLOR; } - /* else if the mouse is over this item, draw with a different background */ + // else if the mouse is over this item, draw with a different background else if (itemnum == hover) { fgcolor = UI_MOUSEOVER_COLOR; @@ -538,65 +541,64 @@ void ui_menu::draw(bool customonly) fgcolor3 = UI_MOUSEOVER_COLOR; } - /* if we have some background hilighting to do, add a quad behind everything else */ + // if we have some background hilighting to do, add a quad behind everything else if (bgcolor != UI_TEXT_BG_COLOR) - container->add_quad(line_x0, line_y0, line_x1, line_y1, bgcolor, hilight_texture, - PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE)); + highlight(container, line_x0, line_y0, line_x1, line_y1, bgcolor); - /* if we're on the top line, display the up arrow */ + // if we're on the top line, display the up arrow if (linenum == 0 && top_line != 0) { - container->add_quad( + 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, - arrow_texture, - PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(ROT0)); + ROT0); if (hover == itemnum) hover = -2; } - /* if we're on the bottom line, display the down arrow */ + // if we're on the bottom line, display the down arrow else if (linenum == visible_lines - 1 && itemnum != numitems - 1) { - container->add_quad( + 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, - arrow_texture, - PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(ROT0 ^ ORIENTATION_FLIP_Y)); + ROT0 ^ ORIENTATION_FLIP_Y); if (hover == itemnum) hover = -1; } - /* if we're just a divider, draw a line */ + // 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 */ + // if we don't have a subitem, just draw the string centered else if (pitem.subtext == NULL) machine().ui().draw_text_full(container, itemtext, effective_left, line_y, effective_width, JUSTIFY_CENTER, WRAP_TRUNCATE, DRAW_NORMAL, fgcolor, bgcolor, NULL, NULL); - /* otherwise, draw the item on the left and the subitem text on the right */ + // otherwise, draw the item on the left and the subitem text on the right else { int subitem_invert = pitem.flags & MENU_FLAG_INVERT; const char *subitem_text = pitem.subtext; float item_width, subitem_width; - /* draw the left-side text */ + // draw the left-side text machine().ui().draw_text_full(container, itemtext, effective_left, line_y, effective_width, JUSTIFY_LEFT, WRAP_TRUNCATE, DRAW_NORMAL, fgcolor, bgcolor, &item_width, NULL); - /* give 2 spaces worth of padding */ + // give 2 spaces worth of padding item_width += 2.0f * gutter_width; - /* if the subitem doesn't fit here, display dots */ + // if the subitem doesn't fit here, display dots if (machine().ui().get_string_width(subitem_text) > effective_width - item_width) { subitem_text = "..."; @@ -604,37 +606,37 @@ void ui_menu::draw(bool customonly) selected_subitem_too_big = TRUE; } - /* draw the subitem right-justified */ + // 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, NULL); - /* apply arrows */ + // apply arrows if (itemnum == selected && (pitem.flags & MENU_FLAG_LEFT_ARROW)) { - container->add_quad( + 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, line_y + 0.9f * line_height, fgcolor, - arrow_texture, - PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(ROT90 ^ ORIENTATION_FLIP_X)); + ROT90 ^ ORIENTATION_FLIP_X); } if (itemnum == selected && (pitem.flags & MENU_FLAG_RIGHT_ARROW)) { - container->add_quad( + draw_arrow( + container, effective_left + effective_width + gutter_width - lr_arrow_width, line_y + 0.1f * line_height, effective_left + effective_width + gutter_width, line_y + 0.9f * line_height, fgcolor, - arrow_texture, - PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(ROT90)); + ROT90); } } } - /* if the selected subitem is too big, display it in a separate offset box */ + // if the selected subitem is too big, display it in a separate offset box if (selected_subitem_too_big) { const ui_menu_item &pitem = item[selected]; @@ -644,17 +646,17 @@ void ui_menu::draw(bool customonly) float target_width, target_height; float target_x, target_y; - /* compute the multi-line target width/height */ + // 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); - /* determine the target location */ + // 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; if (target_y + target_height + UI_BOX_TB_BORDER > visible_main_menu_height) target_y = line_y - target_height - UI_BOX_TB_BORDER; - /* add a box around that */ + // add a box around that 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, @@ -663,10 +665,10 @@ void ui_menu::draw(bool customonly) JUSTIFY_RIGHT, WRAP_WORD, DRAW_NORMAL, UI_SELECTED_COLOR, UI_SELECTED_BG_COLOR, NULL, NULL); } - /* if there is something special to add, do it by calling the virtual method */ + // if there is something special to add, do it by calling the virtual method custom_render((selected >= 0 && selected < numitems) ? item[selected].ref : NULL, customtop, custombottom, x1, y1, x2, y2); - /* return the number of visible lines, minus 1 for top arrow and 1 for bottom arrow */ + // 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 != numitems); } @@ -674,11 +676,11 @@ void ui_menu::custom_render(void *selectedref, float top, float bottom, float x, { } -/*------------------------------------------------- - draw_text_box - draw a multiline - word-wrapped text box with a menu item at the - bottom --------------------------------------------------*/ +//------------------------------------------------- +// draw_text_box - draw a multiline +// word-wrapped text box with a menu item at the +// bottom +//------------------------------------------------- void ui_menu::draw_text_box() { @@ -690,22 +692,22 @@ void ui_menu::draw_text_box() float target_width, target_height, prior_width; float target_x, target_y; - /* compute the multi-line target width/height */ + // 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); target_height += 2.0f * line_height; if (target_height > 1.0f - 2.0f * UI_BOX_TB_BORDER) target_height = floor((1.0f - 2.0f * UI_BOX_TB_BORDER) / line_height) * line_height; - /* maximum against "return to prior menu" text */ + // maximum against "return to prior menu" text prior_width = machine().ui().get_string_width(backtext) + 2.0f * gutter_width; target_width = MAX(target_width, prior_width); - /* determine the target location */ + // determine the target location target_x = 0.5f - 0.5f * target_width; target_y = 0.5f - 0.5f * target_height; - /* make sure we stay on-screen */ + // make sure we stay on-screen if (target_x < UI_BOX_LR_BORDER + gutter_width) target_x = UI_BOX_LR_BORDER + gutter_width; if (target_x + target_width + gutter_width + UI_BOX_LR_BORDER > 1.0f) @@ -715,7 +717,7 @@ void ui_menu::draw_text_box() if (target_y + target_height + UI_BOX_TB_BORDER > 1.0f) target_y = 1.0f - UI_BOX_TB_BORDER - target_height; - /* add a box around that */ + // 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, @@ -723,39 +725,38 @@ void ui_menu::draw_text_box() 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, NULL, NULL); - /* draw the "return to prior menu" text with a hilight behind it */ - container->add_quad( + // 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, - hilight_texture, - PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE)); + 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, NULL, NULL); - /* artificially set the hover to the last item so a double-click exits */ + // artificially set the hover to the last item so a double-click exits hover = numitems - 1; } -/*------------------------------------------------- - handle_events - generically handle - input events for a menu --------------------------------------------------*/ +//------------------------------------------------- +// handle_events - generically handle +// input events for a menu +//------------------------------------------------- void ui_menu::handle_events() { int stop = FALSE; ui_event local_menu_event; - /* loop while we have interesting events */ + // loop while we have interesting events while (!stop && ui_input_pop_event(machine(), &local_menu_event)) { switch (local_menu_event.event_type) { - /* if we are hovering over a valid item, select it with a single click */ + // if we are hovering over a valid item, select it with a single click case UI_EVENT_MOUSE_DOWN: if (hover >= 0 && hover < numitems) selected = hover; @@ -771,7 +772,7 @@ void ui_menu::handle_events() } break; - /* if we are hovering over a valid item, fake a UI_SELECT with a double-click */ + // 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 < numitems) { @@ -789,14 +790,14 @@ void ui_menu::handle_events() } break; - /* translate CHAR events into specials */ + // 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 */ + // ignore everything else default: break; } @@ -804,10 +805,10 @@ void ui_menu::handle_events() } -/*------------------------------------------------- - handle_keys - generically handle - keys for a menu --------------------------------------------------*/ +//------------------------------------------------- +// handle_keys - generically handle +// keys for a menu +//------------------------------------------------- void ui_menu::handle_keys(UINT32 flags) { @@ -816,11 +817,11 @@ void ui_menu::handle_keys(UINT32 flags) int ignoreleft = FALSE; int code; - /* bail if no items */ + // bail if no items if (numitems == 0) return; - /* if we hit select, return TRUE or pop the stack, depending on the item */ + // if we hit select, return TRUE or pop the stack, depending on the item if (exclusive_input_pressed(IPT_UI_SELECT, 0)) { if (selected == numitems - 1) @@ -831,69 +832,69 @@ void ui_menu::handle_keys(UINT32 flags) return; } - /* hitting cancel also pops the stack */ + // hitting cancel also pops the stack if (exclusive_input_pressed(IPT_UI_CANCEL, 0)) { ui_menu::stack_pop(machine()); return; } - /* validate the current selection */ + // validate the current selection validate_selection(1); - /* swallow left/right keys if they are not appropriate */ + // swallow left/right keys if they are not appropriate 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 */ + // accept left/right keys as-is with repeat if (!ignoreleft && exclusive_input_pressed(IPT_UI_LEFT, (flags & UI_MENU_PROCESS_LR_REPEAT) ? 6 : 0)) return; if (!ignoreright && exclusive_input_pressed(IPT_UI_RIGHT, (flags & UI_MENU_PROCESS_LR_REPEAT) ? 6 : 0)) return; - /* up backs up by one item */ + // up backs up by one item if (exclusive_input_pressed(IPT_UI_UP, 6)) { selected = (selected + numitems - 1) % numitems; validate_selection(-1); } - /* down advances by one item */ + // down advances by one item if (exclusive_input_pressed(IPT_UI_DOWN, 6)) { selected = (selected + 1) % numitems; validate_selection(1); } - /* page up backs up by visitems */ + // page up backs up by visitems if (exclusive_input_pressed(IPT_UI_PAGE_UP, 6)) { selected -= visitems - 1; validate_selection(1); } - /* page down advances by visitems */ + // page down advances by visitems if (exclusive_input_pressed(IPT_UI_PAGE_DOWN, 6)) { selected += visitems - 1; validate_selection(-1); } - /* home goes to the start */ + // home goes to the start if (exclusive_input_pressed(IPT_UI_HOME, 0)) { selected = 0; validate_selection(1); } - /* end goes to the last */ + // end goes to the last if (exclusive_input_pressed(IPT_UI_END, 0)) { selected = numitems - 1; validate_selection(-1); } - /* pause enables/disables pause */ + // pause enables/disables pause if (!ignorepause && exclusive_input_pressed(IPT_UI_PAUSE, 0)) { if (machine().paused()) @@ -902,11 +903,11 @@ void ui_menu::handle_keys(UINT32 flags) machine().pause(); } - /* handle a toggle cheats request */ + // handle a toggle cheats request if (ui_input_pressed_repeat(machine(), IPT_UI_TOGGLE_CHEAT, 0)) machine().cheat().set_enable(!machine().cheat().enabled()); - /* see if any other UI keys are pressed */ + // see if any other UI keys are pressed if (menu_event.iptkey == IPT_INVALID) for (code = IPT_UI_FIRST + 1; code < IPT_UI_LAST; code++) { @@ -918,31 +919,31 @@ void ui_menu::handle_keys(UINT32 flags) } -/*------------------------------------------------- - validate_selection - validate the - current selection and ensure it is on a - correct item --------------------------------------------------*/ +//------------------------------------------------- +// validate_selection - validate the +// current selection and ensure it is on a +// correct item +//------------------------------------------------- void ui_menu::validate_selection(int scandir) { - /* clamp to be in range */ + // clamp to be in range if (selected < 0) selected = 0; else if (selected >= numitems) selected = numitems - 1; - /* skip past unselectable items */ + // skip past unselectable items while (!item[selected].is_selectable()) selected = (selected + numitems + scandir) % numitems; } -/*------------------------------------------------- - clear_free_list - clear out anything - accumulated in the free list --------------------------------------------------*/ +//------------------------------------------------- +// clear_free_list - clear out anything +// accumulated in the free list +//------------------------------------------------- void ui_menu::clear_free_list(running_machine &machine) { @@ -960,9 +961,9 @@ void ui_menu::clear_free_list(running_machine &machine) MENU STACK MANAGEMENT ***************************************************************************/ -/*------------------------------------------------- - ui_menu::stack_reset - reset the menu stack --------------------------------------------------*/ +//------------------------------------------------- +// ui_menu::stack_reset - reset the menu stack +//------------------------------------------------- void ui_menu::stack_reset(running_machine &machine) { @@ -971,10 +972,10 @@ void ui_menu::stack_reset(running_machine &machine) } -/*------------------------------------------------- - stack_push - push a new menu onto the - stack --------------------------------------------------*/ +//------------------------------------------------- +// stack_push - push a new menu onto the +// stack +//------------------------------------------------- void ui_menu::stack_push(ui_menu *menu) { @@ -985,9 +986,9 @@ void ui_menu::stack_push(ui_menu *menu) } -/*------------------------------------------------- - stack_pop - pop a menu from the stack --------------------------------------------------*/ +//------------------------------------------------- +// stack_pop - pop a menu from the stack +//------------------------------------------------- void ui_menu::stack_pop(running_machine &machine) { @@ -1002,10 +1003,10 @@ void ui_menu::stack_pop(running_machine &machine) } -/*------------------------------------------------- - ui_menu::stack_has_special_main_menu - - check in the special main menu is in the stack --------------------------------------------------*/ +//------------------------------------------------- +// ui_menu::stack_has_special_main_menu - +// check in the special main menu is in the stack +//------------------------------------------------- bool ui_menu::stack_has_special_main_menu() { @@ -1030,25 +1031,25 @@ void ui_menu::do_handle() UI SYSTEM INTERACTION ***************************************************************************/ -/*------------------------------------------------- - ui_menu_ui_handler - displays the current menu - and calls the menu handler --------------------------------------------------*/ +//------------------------------------------------- +// ui_menu_ui_handler - displays the current menu +// and calls the menu handler +//------------------------------------------------- UINT32 ui_menu::ui_handler(running_machine &machine, render_container *container, UINT32 state) { - /* if we have no menus stacked up, start with the main menu */ + // if we have no menus stacked up, start with the main menu if (menu_stack == NULL) stack_push(auto_alloc_clear(machine, ui_menu_main(machine, container))); - /* update the menu state */ + // update the menu state if (menu_stack != NULL) menu_stack->do_handle(); - /* clear up anything pending to be released */ + // clear up anything pending to be released clear_free_list(machine); - /* if the menus are to be hidden, return a cancel here */ + // if the menus are to be hidden, return a cancel here if (machine.ui().is_menu_active() && ((ui_input_pressed(machine, IPT_UI_CONFIGURE) && !stack_has_special_main_menu()) || menu_stack == NULL)) return UI_HANDLER_CANCEL; @@ -1059,11 +1060,11 @@ UINT32 ui_menu::ui_handler(running_machine &machine, render_container *container MENU HELPERS ***************************************************************************/ -/*------------------------------------------------- - render_triangle - render a triangle that - is used for up/down arrows and left/right - indicators --------------------------------------------------*/ +//------------------------------------------------- +// render_triangle - render a triangle that +// is used for up/down arrows and left/right +// indicators +//------------------------------------------------- void ui_menu::render_triangle(bitmap_argb32 &dest, bitmap_argb32 &source, const rectangle &sbounds, void *param) { @@ -1071,16 +1072,16 @@ void ui_menu::render_triangle(bitmap_argb32 &dest, bitmap_argb32 &source, const int height = dest.height(); int x, y; - /* start with all-transparent */ + // start with all-transparent dest.fill(MAKE_ARGB(0x00,0x00,0x00,0x00)); - /* render from the tip to the bottom */ + // render from the tip to the bottom for (y = 0; y < height; y++) { int linewidth = (y * (halfwidth - 1) + (height / 2)) * 255 * 2 / height; UINT32 *target = &dest.pix32(y, halfwidth); - /* don't antialias if height < 12 */ + // don't antialias if height < 12 if (dest.height() < 12) { int pixels = (linewidth + 254) / 255; @@ -1088,27 +1089,55 @@ void ui_menu::render_triangle(bitmap_argb32 &dest, bitmap_argb32 &source, const linewidth = pixels * 255; } - /* loop while we still have data to generate */ + // loop while we still have data to generate for (x = 0; linewidth > 0; x++) { int dalpha; - /* first column we only consume one pixel */ + // first column we only consume one pixel if (x == 0) { dalpha = MIN(0xff, linewidth); target[x] = MAKE_ARGB(dalpha,0xff,0xff,0xff); } - /* remaining columns consume two pixels, one on each side */ + // remaining columns consume two pixels, one on each side else { dalpha = MIN(0x1fe, linewidth); target[x] = target[-x] = MAKE_ARGB(dalpha/2,0xff,0xff,0xff); } - /* account for the weight we consumed */ + // account for the weight we consumed */ linewidth -= dalpha; } } } + + +//------------------------------------------------- +// highlight +//------------------------------------------------- + +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)); +} + + +//------------------------------------------------- +// draw_arrow +//------------------------------------------------- + +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)); +} diff --git a/src/emu/ui/menu.h b/src/emu/ui/menu.h index 3e5d6b74930..080e1b7043a 100644 --- a/src/emu/ui/menu.h +++ b/src/emu/ui/menu.h @@ -21,7 +21,7 @@ CONSTANTS ***************************************************************************/ -/* flags for menu items */ +// flags for menu items #define MENU_FLAG_LEFT_ARROW (1 << 0) #define MENU_FLAG_RIGHT_ARROW (1 << 1) #define MENU_FLAG_INVERT (1 << 2) @@ -29,15 +29,15 @@ #define MENU_FLAG_REDTEXT (1 << 4) #define MENU_FLAG_DISABLE (1 << 5) -/* special menu item for separators */ +// special menu item for separators #define MENU_SEPARATOR_ITEM "---" -/* flags to pass to ui_menu_process */ +// flags to pass to ui_menu_process #define UI_MENU_PROCESS_NOKEYS 1 #define UI_MENU_PROCESS_LR_REPEAT 2 #define UI_MENU_PROCESS_CUSTOM_ONLY 4 -/* options for ui_menu_reset */ +// options for ui_menu_reset enum ui_menu_reset_options { UI_MENU_RESET_SELECT_FIRST, @@ -51,19 +51,19 @@ enum ui_menu_reset_options TYPE DEFINITIONS ***************************************************************************/ -/* menu-related events */ +// menu-related events struct ui_menu_event { - void * itemref; /* reference for the selected item */ - int iptkey; /* one of the IPT_* values from inptport.h */ - unicode_char unichar; /* unicode character if iptkey == IPT_SPECIAL */ + void * itemref; // reference for the selected item + int iptkey; // one of the IPT_* values from inptport.h + unicode_char unichar; // unicode character if iptkey == IPT_SPECIAL }; struct ui_menu_pool { - ui_menu_pool * next; /* chain to next one */ - UINT8 * top; /* top of the pool */ - UINT8 * end; /* end of the pool */ + ui_menu_pool * next; // chain to next one + UINT8 * top; // top of the pool + UINT8 * end; // end of the pool }; @@ -86,81 +86,87 @@ public: running_machine &machine() const { return m_machine; } - render_container * container; /* render_container we render to */ - ui_menu_event menu_event; /* the UI menu_event that occurred */ - ui_menu * parent; /* pointer to parent menu */ - int resetpos; /* reset position */ - void * resetref; /* reset reference */ - int selected; /* which item is selected */ - int hover; /* which item is being hovered over */ - int visitems; /* number of visible items */ - int numitems; /* number of items in the menu */ - int allocitems; /* allocated size of array */ - ui_menu_item * item; /* pointer to array of items */ - float customtop; /* amount of extra height to add at the top */ - float custombottom; /* amount of extra height to add at the bottom */ - ui_menu_pool * pool; /* list of memory pools */ + render_container * container; // render_container we render to + ui_menu_event menu_event; // the UI menu_event that occurred + ui_menu * parent; // pointer to parent menu + int resetpos; // reset position + void * resetref; // reset reference + int selected; // which item is selected + int hover; // which item is being hovered over + int visitems; // number of visible items + int numitems; // number of items in the menu + int allocitems; // allocated size of array + ui_menu_item * item; // pointer to array of items + float customtop; // amount of extra height to add at the top + float custombottom; // amount of extra height to add at the bottom + ui_menu_pool * pool; // list of memory pools - /* free all items in the menu, and all memory allocated from the memory pool */ + // free all items in the menu, and all memory allocated from the memory pool void reset(ui_menu_reset_options options); - /* returns true if the menu has any non-default items in it */ + // returns true if the menu has any non-default items in it bool populated(); - /* append a new item to the end of the menu */ + // append a new item to the end of the menu void item_append(const char *text, const char *subtext, UINT32 flags, void *ref); - /* process a menu, drawing it and returning any interesting events */ + // process a menu, drawing it and returning any interesting events const ui_menu_event *process(UINT32 flags); - /* configure the menu for custom rendering */ + // configure the menu for custom rendering virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2); - /* allocate temporary memory from the menu's memory pool */ + // allocate temporary memory from the menu's memory pool void *m_pool_alloc(size_t size); - /* make a temporary string copy in the menu's memory pool */ + // make a temporary string copy in the menu's memory pool const char *pool_strdup(const char *string); - /* retrieves the index of the currently selected menu item */ + // retrieves the index of the currently selected menu item void *get_selection(); - /* changes the index of the currently selected menu item */ + // changes the index of the currently selected menu item void set_selection(void *selected_itemref); - /* request the specific handling of the game selection main menu */ + // request the specific handling of the game selection main menu bool is_special_main_menu() const; void set_special_main_menu(bool disable); - /* Global initialization */ + // Global initialization static void init(running_machine &machine); static void exit(running_machine &machine); - /* reset the menus, clearing everything */ + // reset the menus, clearing everything static void stack_reset(running_machine &machine); - /* push a new menu onto the stack */ + // push a new menu onto the stack static void stack_push(ui_menu *menu); - /* pop a menu from the stack */ + // pop a menu from the stack static void stack_pop(running_machine &machine); - /* test if one of the menus in the stack requires hide disable */ + // test if one of the menus in the stack requires hide disable static bool stack_has_special_main_menu(); -/* master handler */ + // highlight + static void highlight(render_container *container, float x0, float y0, float x1, float y1, rgb_t bgcolor); + + // draw arrow + static void draw_arrow(render_container *container, float x0, float y0, float x1, float y1, rgb_t fgcolor, UINT32 orientation); + +// master handler static UINT32 ui_handler(running_machine &machine, render_container *container, UINT32 state); - /* Used by sliders */ + // Used by sliders void validate_selection(int scandir); static ui_menu *menu_stack; void do_handle(); - /* To be reimplemented in the menu subclass */ + // To be reimplemented in the menu subclass virtual void populate() = 0; - /* To be reimplemented in the menu subclass */ + // To be reimplemented in the menu subclass virtual void handle() = 0; private: @@ -168,9 +174,8 @@ private: static bitmap_rgb32 *hilight_bitmap; static render_texture *hilight_texture, *arrow_texture; - bool special_main_menu; - - running_machine & m_machine; /* machine we are attached to */ + bool m_special_main_menu; + running_machine & m_machine; // machine we are attached to void draw(bool customonly); void draw_text_box(); @@ -183,4 +188,4 @@ private: static void render_triangle(bitmap_argb32 &dest, bitmap_argb32 &source, const rectangle &sbounds, void *param); }; -#endif /* __UI_MENU_H__ */ +#endif // __UI_MENU_H__ diff --git a/src/emu/ui/ui.h b/src/emu/ui/ui.h index c9fb7471e17..875f42bd6fe 100644 --- a/src/emu/ui/ui.h +++ b/src/emu/ui/ui.h @@ -135,7 +135,7 @@ public: float get_string_width(const char *s); void draw_outlined_box(render_container *container, float x0, float y0, float x1, float y1, rgb_t backcolor); void draw_text(render_container *container, const char *buf, float x, float y); - void draw_text_full(render_container *container, const char *origs, float x, float y, float origwrapwidth, int justify, int wrap, int draw, rgb_t fgcolor, rgb_t bgcolor, float *totalwidth, float *totalheight); + void draw_text_full(render_container *container, const char *origs, float x, float y, float origwrapwidth, int justify, int wrap, int draw, rgb_t fgcolor, rgb_t bgcolor, float *totalwidth = NULL, float *totalheight = NULL); void draw_text_box(render_container *container, const char *text, int justify, float xpos, float ypos, rgb_t backcolor); void draw_message_window(render_container *container, const char *text);