menu_dats_view::menu_dats_view(mame_ui_manager &mui, render_container &container, const game_driver *driver) : menu(mui, container) , m_actual(0) , m_driver((driver == nullptr) ? &mui.machine().system() : driver) , m_swinfo(nullptr) , m_issoft(false) { for (device_image_interface& image : image_interface_iterator(mui.machine().root_device())) { if (image.filename()) { m_list = strensure(image.software_list_name()); m_short = image.software_entry()->shortname(); m_long = image.software_entry()->longname(); m_parent = image.software_entry()->parentname(); } } std::vector<std::string> lua_list; if (mame_machine_manager::instance()->lua()->call_plugin("data_list", driver ? driver->name : "", lua_list)) { int count = 0; for (std::string& item : lua_list) { std::string version; mame_machine_manager::instance()->lua()->call_plugin("data_version", count, version); m_items_list.emplace_back(item.c_str(), count, std::move(version)); count++; } } }
menu_dats_view::menu_dats_view(mame_ui_manager &mui, render_container &container, const game_driver *driver) : menu(mui, container) , m_actual(0) , m_driver((driver == nullptr) ? &mui.machine().system() : driver) , m_issoft(false) { for (device_image_interface &image : image_interface_iterator(mui.machine().root_device())) { if (image.filename()) { m_list = strensure(image.software_list_name()); m_short = image.software_entry()->shortname(); m_long = image.software_entry()->longname(); m_parent = image.software_entry()->parentname(); } } const char *lua_list = mame_machine_manager::instance()->lua()->call_plugin(driver ? driver->name : "", "data_list"); if(lua_list) { std::string list(lua_list); char *token = strtok((char *)list.c_str(), ","); int count = 0; while(token) { m_items_list.emplace_back(_(token), count, mame_machine_manager::instance()->lua()->call_plugin(util::string_format("%d", count).c_str(), "data_version")); count++; token = strtok(nullptr, ","); } } }
menu_remove_folder::menu_remove_folder(mame_ui_manager &mui, render_container &container, int ref) : menu(mui, container) { m_ref = ref; if (mui.options().exists(s_folders[m_ref].option)) m_searchpath.assign(mui.options().value(s_folders[m_ref].option)); else m_searchpath.assign(mui.machine().options().value(s_folders[m_ref].option)); path_iterator path(m_searchpath.c_str()); std::string curpath; while (path.next(curpath, nullptr)) m_folders.push_back(curpath); }
void cheat_manager::render_text(mame_ui_manager &mui, render_container &container) { // render any text and free it along the way for (int linenum = 0; linenum < m_output.size(); linenum++) if (!m_output[linenum].empty()) { // output the text mui.draw_text_full(container, m_output[linenum].c_str(), 0.0f, (float)linenum * mui.get_line_height(), 1.0f, m_justify[linenum], ui::text_layout::NEVER, mame_ui_manager::OPAQUE_, rgb_t::white(), rgb_t::black(), nullptr, nullptr); } }
void menu_plugin::show_menu(mame_ui_manager &mui, render_container &container, char *menu) { // reset the menu stack menu::stack_reset(mui.machine()); // add the plugin menu entry menu::stack_push<menu_plugin_opt>(mui, container, menu); // force the menus on mui.show_menu(); // make sure MAME is paused mui.machine().pause(); }
// force file manager menu void menu_file_manager::force_file_manager(mame_ui_manager &mui, render_container &container, const char *warnings) { // reset the menu stack menu::stack_reset(mui.machine()); // add the quit entry followed by the game select entry menu::stack_push_special_main<menu_quit_game>(mui, container); menu::stack_push<menu_file_manager>(mui, container, warnings); // force the menus on mui.show_menu(); // make sure MAME is paused mui.machine().pause(); }
menu_dats_view::menu_dats_view(mame_ui_manager &mui, render_container &container, const ui_software_info *swinfo, const game_driver *driver) : menu(mui, container) , m_actual(0) , m_driver((driver == nullptr) ? &mui.machine().system() : driver) , m_swinfo(swinfo) , m_list(swinfo->listname) , m_short(swinfo->shortname) , m_long(swinfo->longname) , m_parent(swinfo->parentname) , m_issoft(true) { if (swinfo != nullptr && !swinfo->usage.empty()) m_items_list.emplace_back(_("Software Usage"), 0, ""); std::vector<std::string> lua_list; if(mame_machine_manager::instance()->lua()->call_plugin("data_list", std::string(m_short).append(1, ',').append(m_list).c_str(), lua_list)) { int count = 1; for(std::string &item : lua_list) { std::string version; mame_machine_manager::instance()->lua()->call_plugin("data_version", count - 1, version); m_items_list.emplace_back(item.c_str(), count, std::move(version)); count++; } } }
menu_dats_view::menu_dats_view(mame_ui_manager &mui, render_container &container, ui_software_info *swinfo, const game_driver *driver) : menu(mui, container) , m_actual(0) , m_driver((driver == nullptr) ? &mui.machine().system() : driver) , m_swinfo(swinfo) , m_list(swinfo->listname) , m_short(swinfo->shortname) , m_long(swinfo->longname) , m_parent(swinfo->parentname) , m_issoft(true) { if (swinfo != nullptr && !swinfo->usage.empty()) m_items_list.emplace_back(_("Software Usage"), 0, ""); const char *lua_list = mame_machine_manager::instance()->lua()->call_plugin(std::string(m_short).append(1, ',').append(m_list).c_str(), "data_list"); if(lua_list) { std::string list(lua_list); char *token = strtok((char *)list.c_str(), ","); int count = 1; while(token) { m_items_list.emplace_back(_(token), count, mame_machine_manager::instance()->lua()->call_plugin(util::string_format("%d", count - 1).c_str(), "data_version")); count++; token = strtok(nullptr, ","); } } }
void simple_menu_select_game::force_game_select(mame_ui_manager &mui, render_container &container) { char *gamename = (char *)mui.machine().options().system_name(); // reset the menu stack menu::stack_reset(mui.machine()); // add the quit entry followed by the game select entry menu::stack_push_special_main<menu_quit_game>(mui, container); menu::stack_push<simple_menu_select_game>(mui, container, gamename); // force the menus on mui.show_menu(); // make sure MAME is paused mui.machine().pause(); }
menu_sound_options::menu_sound_options(mame_ui_manager &mui, render_container *container) : menu(mui, container) { osd_options &options = downcast<osd_options &>(mui.machine().options()); m_sample_rate = mui.machine().options().sample_rate(); m_sound = (strcmp(options.sound(), OSDOPTVAL_NONE) && strcmp(options.sound(), "0")); m_samples = mui.machine().options().samples(); int total = ARRAY_LENGTH(m_sound_rate); for (m_cur_rates = 0; m_cur_rates < total; m_cur_rates++) if (m_sample_rate == m_sound_rate[m_cur_rates]) break; if (m_cur_rates == total) m_cur_rates = 2; }
menu_add_change_folder::menu_add_change_folder(mame_ui_manager &mui, render_container &container, int ref) : menu(mui, container) { m_ref = ref; m_change = (s_folders[ref].action == CHANGE); m_search[0] = '\0'; // configure the starting path osd_get_full_path(m_current_path, "."); std::string searchpath; if (mui.options().exists(s_folders[m_ref].option)) searchpath = mui.options().value(s_folders[m_ref].option); else searchpath = mui.machine().options().value(s_folders[m_ref].option); path_iterator path(searchpath.c_str()); std::string curpath; while (path.next(curpath, nullptr)) m_folders.push_back(curpath); }
menu_autofire::menu_autofire(mame_ui_manager &mui, render_container &container) : menu(mui, container), last_toggle(false) { const screen_device *screen = mui.machine().first_screen(); if (screen == nullptr) { refresh = 60.0; } else { refresh = ATTOSECONDS_TO_HZ(screen->refresh_attoseconds()); } }
menu_control_device_image::menu_control_device_image(mame_ui_manager &mui, render_container &container, device_image_interface &image) : menu(mui, container) , m_image(image) , m_create_ok(false) , m_create_confirmed(false) { m_submenu_result.i = -1; if (m_image.software_list_name()) m_sld = software_list_device::find_by_name(mui.machine().config(), m_image.software_list_name()); else m_sld = nullptr; m_swi = m_image.software_entry(); m_swp = m_image.part_entry(); if (m_swi != nullptr) { m_state = START_OTHER_PART; m_current_directory = m_image.working_directory(); } else { m_state = START_FILE; // if the image exists, set the working directory to the parent directory if (m_image.exists()) { m_current_file.assign(m_image.filename()); util::zippath_parent(m_current_directory, m_current_file); } else { m_current_directory = m_image.working_directory(); } // check to see if the path exists; if not then set to current directory util::zippath_directory::ptr dir; if (util::zippath_directory::open(m_current_directory, dir) != osd_file::error::NONE) osd_get_full_path(m_current_directory, "."); } }
submenu::submenu(mame_ui_manager &mui, render_container &container, std::vector<option> &&suboptions, const game_driver *drv, emu_options *options) : menu(mui, container) , m_options(std::move(suboptions)) , m_driver(drv) { core_options *opts = nullptr; if (m_driver == nullptr) opts = dynamic_cast<core_options*>(&mui.machine().options()); else opts = dynamic_cast<core_options*>(options); for (auto & sm_option : m_options) { switch (sm_option.type) { case option_type::EMU: sm_option.entry = opts->get_entry(sm_option.name); sm_option.options = opts; if (sm_option.entry->type() == OPTION_STRING) { sm_option.value.clear(); std::string namestr(sm_option.entry->description()); int lparen = namestr.find_first_of('(', 0); int vslash = namestr.find_first_of('|', lparen + 1); int rparen = namestr.find_first_of(')', vslash + 1); if (lparen != -1 && vslash != -1 && rparen != -1) { int semi; namestr.erase(rparen); namestr.erase(0, lparen + 1); while ((semi = namestr.find_first_of('|')) != -1) { sm_option.value.emplace_back(namestr.substr(0, semi)); namestr.erase(0, semi + 1); } sm_option.value.emplace_back(namestr); } } break; case option_type::OSD: sm_option.entry = opts->get_entry(sm_option.name); sm_option.options = opts; if (sm_option.entry->type() == OPTION_STRING) { sm_option.value.clear(); std::string descr(sm_option.entry->description()), delim(", "); descr.erase(0, descr.find(":") + 2); size_t p1, p2 = 0; while ((p1 = descr.find_first_not_of(delim, p2)) != std::string::npos) { p2 = descr.find_first_of(delim, p1 + 1); if (p2 != std::string::npos) { std::string txt(descr.substr(p1, p2 - p1)); if (txt != "or") sm_option.value.push_back(txt); } else { sm_option.value.push_back(descr.substr(p1)); break; } } } break; case option_type::UI: sm_option.entry = mui.options().get_entry(sm_option.name); sm_option.options = dynamic_cast<core_options*>(&mui.options()); break; default: break; } } }
static void gfxset_handler(mame_ui_manager &mui, render_container &container, ui_gfx_state &state) { render_font *ui_font = mui.get_font(); int dev = state.gfxset.devindex; int set = state.gfxset.set; ui_gfx_info &info = state.gfxdev[dev]; device_gfx_interface &interface = *info.interface; gfx_element &gfx = *interface.gfx(set); float fullwidth, fullheight; float cellwidth, cellheight; float chwidth, chheight; float titlewidth; float x0, y0; render_bounds cellboxbounds; render_bounds boxbounds; int cellboxwidth, cellboxheight; int targwidth = mui.machine().render().ui_target().width(); int targheight = mui.machine().render().ui_target().height(); int cellxpix, cellypix; int xcells, ycells; int pixelscale = 0; int x, y, skip; // add a half character padding for the box chheight = mui.get_line_height(); chwidth = ui_font->char_width(chheight, mui.machine().render().ui_aspect(), '0'); boxbounds.x0 = 0.0f + 0.5f * chwidth; boxbounds.x1 = 1.0f - 0.5f * chwidth; boxbounds.y0 = 0.0f + 0.5f * chheight; boxbounds.y1 = 1.0f - 0.5f * chheight; // the character cell box bounds starts a half character in from the box cellboxbounds = boxbounds; cellboxbounds.x0 += 0.5f * chwidth; cellboxbounds.x1 -= 0.5f * chwidth; cellboxbounds.y0 += 0.5f * chheight; cellboxbounds.y1 -= 0.5f * chheight; // add space on the left for 5 characters of text, plus a half character of padding cellboxbounds.x0 += 5.5f * chwidth; // add space on the top for a title, a half line of padding, a header, and another half line cellboxbounds.y0 += 3.0f * chheight; // convert back to pixels cellboxwidth = (cellboxbounds.x1 - cellboxbounds.x0) * (float)targwidth; cellboxheight = (cellboxbounds.y1 - cellboxbounds.y0) * (float)targheight; // compute the number of source pixels in a cell cellxpix = 1 + ((info.rotate[set] & ORIENTATION_SWAP_XY) ? gfx.height() : gfx.width()); cellypix = 1 + ((info.rotate[set] & ORIENTATION_SWAP_XY) ? gfx.width() : gfx.height()); // compute the largest pixel scale factor that still fits xcells = info.columns[set]; while (xcells > 1) { pixelscale = (cellboxwidth / xcells) / cellxpix; if (pixelscale != 0) break; xcells--; } info.columns[set] = xcells; // worst case, we need a pixel scale of 1 pixelscale = std::max(1, pixelscale); // in the Y direction, we just display as many as we can ycells = cellboxheight / (pixelscale * cellypix); // now determine the actual cellbox size cellboxwidth = std::min(cellboxwidth, xcells * pixelscale * cellxpix); cellboxheight = std::min(cellboxheight, ycells * pixelscale * cellypix); // compute the size of a single cell at this pixel scale factor, as well as the aspect ratio cellwidth = (cellboxwidth / (float)xcells) / (float)targwidth; cellheight = (cellboxheight / (float)ycells) / (float)targheight; //cellaspect = cellwidth / cellheight; // working from the new width/height, recompute the boxbounds fullwidth = (float)cellboxwidth / (float)targwidth + 6.5f * chwidth; fullheight = (float)cellboxheight / (float)targheight + 4.0f * chheight; // recompute boxbounds from this boxbounds.x0 = (1.0f - fullwidth) * 0.5f; boxbounds.x1 = boxbounds.x0 + fullwidth; boxbounds.y0 = (1.0f - fullheight) * 0.5f; boxbounds.y1 = boxbounds.y0 + fullheight; // recompute cellboxbounds cellboxbounds.x0 = boxbounds.x0 + 6.0f * chwidth; cellboxbounds.x1 = cellboxbounds.x0 + (float)cellboxwidth / (float)targwidth; cellboxbounds.y0 = boxbounds.y0 + 3.5f * chheight; cellboxbounds.y1 = cellboxbounds.y0 + (float)cellboxheight / (float)targheight; // figure out the title std::ostringstream title_buf; util::stream_format(title_buf, "'%s' %d/%d", interface.device().tag(), set, info.setcount - 1); // if the mouse pointer is over a pixel in a tile, add some info about the tile and pixel bool found_pixel = false; int32_t mouse_target_x, mouse_target_y; float mouse_x, mouse_y; bool mouse_button; render_target *mouse_target = mui.machine().ui_input().find_mouse(&mouse_target_x, &mouse_target_y, &mouse_button); if (mouse_target != nullptr && mouse_target->map_point_container(mouse_target_x, mouse_target_y, container, mouse_x, mouse_y) && cellboxbounds.x0 <= mouse_x && cellboxbounds.x1 > mouse_x && cellboxbounds.y0 <= mouse_y && cellboxbounds.y1 > mouse_y) { int code = info.offset[set] + int((mouse_x - cellboxbounds.x0) / cellwidth) + int((mouse_y - cellboxbounds.y0) / cellheight) * xcells; int xpixel = int((mouse_x - cellboxbounds.x0) / (cellwidth / cellxpix)) % cellxpix; int ypixel = int((mouse_y - cellboxbounds.y0) / (cellheight / cellypix)) % cellypix; if (code < gfx.elements() && xpixel < (cellxpix - 1) && ypixel < (cellypix - 1)) { found_pixel = true; if (info.rotate[set] & ORIENTATION_FLIP_X) xpixel = (cellxpix - 2) - xpixel; if (info.rotate[set] & ORIENTATION_FLIP_Y) ypixel = (cellypix - 2) - ypixel; if (info.rotate[set] & ORIENTATION_SWAP_XY) std::swap(xpixel, ypixel); uint8_t pixdata = gfx.get_data(code)[xpixel + ypixel * gfx.rowbytes()]; util::stream_format(title_buf, " #%X:%X @ %d,%d = %X", code, info.color[set], xpixel, ypixel, gfx.colorbase() + info.color[set] * gfx.granularity() + pixdata); } } if (!found_pixel) util::stream_format(title_buf, " %dx%d COLOR %X/%X", gfx.width(), gfx.height(), info.color[set], info.color_count[set]); // expand the outer box to fit the title const std::string title = title_buf.str(); titlewidth = ui_font->string_width(chheight, mui.machine().render().ui_aspect(), title.c_str()); x0 = 0.0f; if (boxbounds.x1 - boxbounds.x0 < titlewidth + chwidth) x0 = boxbounds.x0 - (0.5f - 0.5f * (titlewidth + chwidth)); // go ahead and draw the outer box now mui.draw_outlined_box(container, boxbounds.x0 - x0, boxbounds.y0, boxbounds.x1 + x0, boxbounds.y1, UI_GFXVIEWER_BG_COLOR); // draw the title x0 = 0.5f - 0.5f * titlewidth; y0 = boxbounds.y0 + 0.5f * chheight; for (auto ch : title) { container.add_char(x0, y0, chheight, mui.machine().render().ui_aspect(), rgb_t::white(), *ui_font, ch); x0 += ui_font->char_width(chheight, mui.machine().render().ui_aspect(), ch); } // draw the top column headers skip = (int)(chwidth / cellwidth); for (x = 0; x < xcells; x += 1 + skip) { x0 = boxbounds.x0 + 6.0f * chwidth + (float)x * cellwidth; y0 = boxbounds.y0 + 2.0f * chheight; container.add_char(x0 + 0.5f * (cellwidth - chwidth), y0, chheight, mui.machine().render().ui_aspect(), rgb_t::white(), *ui_font, "0123456789ABCDEF"[x & 0xf]); // if we're skipping, draw a point between the character and the box to indicate which // one it's referring to if (skip != 0) container.add_point(x0 + 0.5f * cellwidth, 0.5f * (y0 + chheight + boxbounds.y0 + 3.5f * chheight), UI_LINE_WIDTH, rgb_t::white(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); } // draw the side column headers skip = (int)(chheight / cellheight); for (y = 0; y < ycells; y += 1 + skip) // only display if there is data to show if (info.offset[set] + y * xcells < gfx.elements()) { char buffer[10]; // if we're skipping, draw a point between the character and the box to indicate which // one it's referring to x0 = boxbounds.x0 + 5.5f * chwidth; y0 = boxbounds.y0 + 3.5f * chheight + (float)y * cellheight; if (skip != 0) container.add_point(0.5f * (x0 + boxbounds.x0 + 6.0f * chwidth), y0 + 0.5f * cellheight, UI_LINE_WIDTH, rgb_t::white(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); // draw the row header sprintf(buffer, "%5X", info.offset[set] + y * xcells); for (x = 4; x >= 0; x--) { x0 -= ui_font->char_width(chheight, mui.machine().render().ui_aspect(), buffer[x]); container.add_char(x0, y0 + 0.5f * (cellheight - chheight), chheight, mui.machine().render().ui_aspect(), rgb_t::white(), *ui_font, buffer[x]); } } // update the bitmap gfxset_update_bitmap(mui.machine(), state, xcells, ycells, gfx); // add the final quad container.add_quad(cellboxbounds.x0, cellboxbounds.y0, cellboxbounds.x1, cellboxbounds.y1, rgb_t::white(), state.texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); // handle keyboard navigation before drawing gfxset_handle_keys(mui.machine(), state, xcells, ycells); }
static void palette_handler(mame_ui_manager &mui, render_container &container, ui_gfx_state &state) { device_palette_interface *palette = state.palette.interface; palette_device *paldev = dynamic_cast<palette_device *>(&palette->device()); int total = state.palette.which ? palette->indirect_entries() : palette->entries(); const rgb_t *raw_color = palette->palette()->entry_list_raw(); render_font *ui_font = mui.get_font(); float chwidth, chheight; float titlewidth; float x0, y0; render_bounds cellboxbounds; render_bounds boxbounds; int x, y, skip; // add a half character padding for the box chheight = mui.get_line_height(); chwidth = ui_font->char_width(chheight, mui.machine().render().ui_aspect(), '0'); boxbounds.x0 = 0.0f + 0.5f * chwidth; boxbounds.x1 = 1.0f - 0.5f * chwidth; boxbounds.y0 = 0.0f + 0.5f * chheight; boxbounds.y1 = 1.0f - 0.5f * chheight; // the character cell box bounds starts a half character in from the box cellboxbounds = boxbounds; cellboxbounds.x0 += 0.5f * chwidth; cellboxbounds.x1 -= 0.5f * chwidth; cellboxbounds.y0 += 0.5f * chheight; cellboxbounds.y1 -= 0.5f * chheight; // add space on the left for 5 characters of text, plus a half character of padding cellboxbounds.x0 += 5.5f * chwidth; // add space on the top for a title, a half line of padding, a header, and another half line cellboxbounds.y0 += 3.0f * chheight; // compute the cell size float cellwidth = (cellboxbounds.x1 - cellboxbounds.x0) / (float)state.palette.columns; float cellheight = (cellboxbounds.y1 - cellboxbounds.y0) / (float)state.palette.columns; // figure out the title std::ostringstream title_buf; util::stream_format(title_buf, "'%s'", palette->device().tag()); if (palette->indirect_entries() > 0) title_buf << (state.palette.which ? _(" COLORS") : _(" PENS")); // if the mouse pointer is over one of our cells, add some info about the corresponding palette entry int32_t mouse_target_x, mouse_target_y; float mouse_x, mouse_y; bool mouse_button; render_target *mouse_target = mui.machine().ui_input().find_mouse(&mouse_target_x, &mouse_target_y, &mouse_button); if (mouse_target != nullptr && mouse_target->map_point_container(mouse_target_x, mouse_target_y, container, mouse_x, mouse_y) && cellboxbounds.x0 <= mouse_x && cellboxbounds.x1 > mouse_x && cellboxbounds.y0 <= mouse_y && cellboxbounds.y1 > mouse_y) { int index = state.palette.offset + int((mouse_x - cellboxbounds.x0) / cellwidth) + int((mouse_y - cellboxbounds.y0) / cellheight) * state.palette.columns; if (index < total) { util::stream_format(title_buf, " #%X", index); if (palette->indirect_entries() > 0 && !state.palette.which) util::stream_format(title_buf, " => %X", palette->pen_indirect(index)); else if (paldev != nullptr && paldev->basemem().base() != nullptr) util::stream_format(title_buf, " = %X", paldev->read_entry(index)); rgb_t col = state.palette.which ? palette->indirect_color(index) : raw_color[index]; util::stream_format(title_buf, " (R:%X G:%X B:%X)", col.r(), col.g(), col.b()); } } // expand the outer box to fit the title const std::string title = title_buf.str(); titlewidth = ui_font->string_width(chheight, mui.machine().render().ui_aspect(), title.c_str()); x0 = 0.0f; if (boxbounds.x1 - boxbounds.x0 < titlewidth + chwidth) x0 = boxbounds.x0 - (0.5f - 0.5f * (titlewidth + chwidth)); // go ahead and draw the outer box now mui.draw_outlined_box(container, boxbounds.x0 - x0, boxbounds.y0, boxbounds.x1 + x0, boxbounds.y1, UI_GFXVIEWER_BG_COLOR); // draw the title x0 = 0.5f - 0.5f * titlewidth; y0 = boxbounds.y0 + 0.5f * chheight; for (auto ch : title) { container.add_char(x0, y0, chheight, mui.machine().render().ui_aspect(), rgb_t::white(), *ui_font, ch); x0 += ui_font->char_width(chheight, mui.machine().render().ui_aspect(), ch); } // draw the top column headers skip = (int)(chwidth / cellwidth); for (x = 0; x < state.palette.columns; x += 1 + skip) { x0 = boxbounds.x0 + 6.0f * chwidth + (float)x * cellwidth; y0 = boxbounds.y0 + 2.0f * chheight; container.add_char(x0 + 0.5f * (cellwidth - chwidth), y0, chheight, mui.machine().render().ui_aspect(), rgb_t::white(), *ui_font, "0123456789ABCDEF"[x & 0xf]); // if we're skipping, draw a point between the character and the box to indicate which // one it's referring to if (skip != 0) container.add_point(x0 + 0.5f * cellwidth, 0.5f * (y0 + chheight + cellboxbounds.y0), UI_LINE_WIDTH, rgb_t::white(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); } // draw the side column headers skip = (int)(chheight / cellheight); for (y = 0; y < state.palette.columns; y += 1 + skip) // only display if there is data to show if (state.palette.offset + y * state.palette.columns < total) { char buffer[10]; // if we're skipping, draw a point between the character and the box to indicate which // one it's referring to x0 = boxbounds.x0 + 5.5f * chwidth; y0 = boxbounds.y0 + 3.5f * chheight + (float)y * cellheight; if (skip != 0) container.add_point(0.5f * (x0 + cellboxbounds.x0), y0 + 0.5f * cellheight, UI_LINE_WIDTH, rgb_t::white(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); // draw the row header sprintf(buffer, "%5X", state.palette.offset + y * state.palette.columns); for (x = 4; x >= 0; x--) { x0 -= ui_font->char_width(chheight, mui.machine().render().ui_aspect(), buffer[x]); container.add_char(x0, y0 + 0.5f * (cellheight - chheight), chheight, mui.machine().render().ui_aspect(), rgb_t::white(), *ui_font, buffer[x]); } } // now add the rectangles for the colors for (y = 0; y < state.palette.columns; y++) for (x = 0; x < state.palette.columns; x++) { int index = state.palette.offset + y * state.palette.columns + x; if (index < total) { pen_t pen = state.palette.which ? palette->indirect_color(index) : raw_color[index]; container.add_rect(cellboxbounds.x0 + x * cellwidth, cellboxbounds.y0 + y * cellheight, cellboxbounds.x0 + (x + 1) * cellwidth, cellboxbounds.y0 + (y + 1) * cellheight, 0xff000000 | pen, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); } } // handle keys palette_handle_keys(mui.machine(), state); }
uint32_t ui_gfx_ui_handler(render_container &container, mame_ui_manager &mui, bool uistate) { ui_gfx_state &state = ui_gfx; // if we have nothing, implicitly cancel if (!ui_gfx_is_relevant(mui.machine())) goto cancel; // if we're not paused, mark the bitmap dirty if (!mui.machine().paused()) state.bitmap_dirty = true; // switch off the state to display something again: switch (state.mode) { case UI_GFX_PALETTE: // if we have a palette, display it if (state.palette.devcount > 0) { palette_handler(mui, container, state); break; } // fall through... state.mode++; case UI_GFX_GFXSET: // if we have graphics sets, display them if (state.gfxset.devcount > 0) { gfxset_handler(mui, container, state); break; } // fall through... state.mode++; case UI_GFX_TILEMAP: // if we have tilemaps, display them if (mui.machine().tilemap().count() > 0) { tilemap_handler(mui, container, state); break; } state.mode = UI_GFX_PALETTE; goto again; } // handle keys if (mui.machine().ui_input().pressed(IPT_UI_SELECT)) { state.mode = (state.mode + 1) % 3; state.bitmap_dirty = true; } if (mui.machine().ui_input().pressed(IPT_UI_PAUSE)) { if (mui.machine().paused()) mui.machine().resume(); else mui.machine().pause(); } if (mui.machine().ui_input().pressed(IPT_UI_CANCEL) || mui.machine().ui_input().pressed(IPT_UI_SHOW_GFX)) goto cancel; return uistate; cancel: if (!uistate) mui.machine().resume(); state.bitmap_dirty = true; return UI_HANDLER_CANCEL; }
static void tilemap_handler(mame_ui_manager &mui, render_container &container, ui_gfx_state &state) { render_font *ui_font = mui.get_font(); float chwidth, chheight; render_bounds mapboxbounds; render_bounds boxbounds; int targwidth = mui.machine().render().ui_target().width(); int targheight = mui.machine().render().ui_target().height(); float titlewidth; float x0, y0; int mapboxwidth, mapboxheight; // get the size of the tilemap itself tilemap_t *tilemap = mui.machine().tilemap().find(state.tilemap.which); uint32_t mapwidth = tilemap->width(); uint32_t mapheight = tilemap->height(); if (state.tilemap.rotate & ORIENTATION_SWAP_XY) std::swap(mapwidth, mapheight); // add a half character padding for the box chheight = mui.get_line_height(); chwidth = ui_font->char_width(chheight, mui.machine().render().ui_aspect(), '0'); boxbounds.x0 = 0.0f + 0.5f * chwidth; boxbounds.x1 = 1.0f - 0.5f * chwidth; boxbounds.y0 = 0.0f + 0.5f * chheight; boxbounds.y1 = 1.0f - 0.5f * chheight; // the tilemap box bounds starts a half character in from the box mapboxbounds = boxbounds; mapboxbounds.x0 += 0.5f * chwidth; mapboxbounds.x1 -= 0.5f * chwidth; mapboxbounds.y0 += 0.5f * chheight; mapboxbounds.y1 -= 0.5f * chheight; // add space on the top for a title and a half line of padding mapboxbounds.y0 += 1.5f * chheight; // convert back to pixels mapboxwidth = (mapboxbounds.x1 - mapboxbounds.x0) * (float)targwidth; mapboxheight = (mapboxbounds.y1 - mapboxbounds.y0) * (float)targheight; // determine the maximum integral scaling factor int pixelscale = state.tilemap.zoom; if (pixelscale == 0) { int maxxscale, maxyscale; for (maxxscale = 1; mapwidth * (maxxscale + 1) < mapboxwidth; maxxscale++) { } for (maxyscale = 1; mapheight * (maxyscale + 1) < mapboxheight; maxyscale++) { } pixelscale = std::min(maxxscale, maxyscale); } // recompute the final box size mapboxwidth = std::min(mapboxwidth, int(mapwidth * pixelscale)); mapboxheight = std::min(mapboxheight, int(mapheight * pixelscale)); // recompute the bounds, centered within the existing bounds mapboxbounds.x0 += 0.5f * ((mapboxbounds.x1 - mapboxbounds.x0) - (float)mapboxwidth / (float)targwidth); mapboxbounds.x1 = mapboxbounds.x0 + (float)mapboxwidth / (float)targwidth; mapboxbounds.y0 += 0.5f * ((mapboxbounds.y1 - mapboxbounds.y0) - (float)mapboxheight / (float)targheight); mapboxbounds.y1 = mapboxbounds.y0 + (float)mapboxheight / (float)targheight; // now recompute the outer box against this new info boxbounds.x0 = mapboxbounds.x0 - 0.5f * chwidth; boxbounds.x1 = mapboxbounds.x1 + 0.5f * chwidth; boxbounds.y0 = mapboxbounds.y0 - 2.0f * chheight; boxbounds.y1 = mapboxbounds.y1 + 0.5f * chheight; // figure out the title std::ostringstream title_buf; util::stream_format(title_buf, "TILEMAP %d/%d", state.tilemap.which + 1, mui.machine().tilemap().count()); // if the mouse pointer is over a tile, add some info about its coordinates and color int32_t mouse_target_x, mouse_target_y; float mouse_x, mouse_y; bool mouse_button; render_target *mouse_target = mui.machine().ui_input().find_mouse(&mouse_target_x, &mouse_target_y, &mouse_button); if (mouse_target != nullptr && mouse_target->map_point_container(mouse_target_x, mouse_target_y, container, mouse_x, mouse_y) && mapboxbounds.x0 <= mouse_x && mapboxbounds.x1 > mouse_x && mapboxbounds.y0 <= mouse_y && mapboxbounds.y1 > mouse_y) { int xpixel = (mouse_x - mapboxbounds.x0) * targwidth; int ypixel = (mouse_y - mapboxbounds.y0) * targheight; if (state.tilemap.rotate & ORIENTATION_FLIP_X) xpixel = (mapboxwidth - 1) - xpixel; if (state.tilemap.rotate & ORIENTATION_FLIP_Y) ypixel = (mapboxheight - 1) - ypixel; if (state.tilemap.rotate & ORIENTATION_SWAP_XY) std::swap(xpixel, ypixel); uint32_t col = ((xpixel / pixelscale + state.tilemap.xoffs) / tilemap->tilewidth()) % tilemap->cols(); uint32_t row = ((ypixel / pixelscale + state.tilemap.yoffs) / tilemap->tileheight()) % tilemap->rows(); uint8_t gfxnum; uint32_t code, color; tilemap->get_info_debug(col, row, gfxnum, code, color); util::stream_format(title_buf, " @ %d,%d = GFX%d #%X:%X", col * tilemap->tilewidth(), row * tilemap->tileheight(), int(gfxnum), code, color); } else util::stream_format(title_buf, " %dx%d OFFS %d,%d", tilemap->width(), tilemap->height(), state.tilemap.xoffs, state.tilemap.yoffs); if (state.tilemap.flags != TILEMAP_DRAW_ALL_CATEGORIES) util::stream_format(title_buf, " CAT %d", state.tilemap.flags); // expand the outer box to fit the title const std::string title = title_buf.str(); titlewidth = ui_font->string_width(chheight, mui.machine().render().ui_aspect(), title.c_str()); if (boxbounds.x1 - boxbounds.x0 < titlewidth + chwidth) { boxbounds.x0 = 0.5f - 0.5f * (titlewidth + chwidth); boxbounds.x1 = boxbounds.x0 + titlewidth + chwidth; } // go ahead and draw the outer box now mui.draw_outlined_box(container, boxbounds.x0, boxbounds.y0, boxbounds.x1, boxbounds.y1, UI_GFXVIEWER_BG_COLOR); // draw the title x0 = 0.5f - 0.5f * titlewidth; y0 = boxbounds.y0 + 0.5f * chheight; for (auto ch : title) { container.add_char(x0, y0, chheight, mui.machine().render().ui_aspect(), rgb_t::white(), *ui_font, ch); x0 += ui_font->char_width(chheight, mui.machine().render().ui_aspect(), ch); } // update the bitmap tilemap_update_bitmap(mui.machine(), state, mapboxwidth / pixelscale, mapboxheight / pixelscale); // add the final quad container.add_quad(mapboxbounds.x0, mapboxbounds.y0, mapboxbounds.x1, mapboxbounds.y1, rgb_t::white(), state.texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(state.tilemap.rotate)); // handle keyboard input tilemap_handle_keys(mui.machine(), state, mapboxwidth, mapboxheight); }
static void palette_handler(mame_ui_manager &mui, render_container *container, ui_gfx_state &state) { palette_device *palette = state.palette.device; int total = state.palette.which ? palette->indirect_entries() : palette->entries(); const rgb_t *raw_color = palette->palette()->entry_list_raw(); render_font *ui_font = mui.get_font(); float cellwidth, cellheight; float chwidth, chheight; float titlewidth; float x0, y0; render_bounds cellboxbounds; render_bounds boxbounds; int x, y, skip; char title[100]; // add a half character padding for the box chheight = mui.get_line_height(); chwidth = ui_font->char_width(chheight, mui.machine().render().ui_aspect(), '0'); boxbounds.x0 = 0.0f + 0.5f * chwidth; boxbounds.x1 = 1.0f - 0.5f * chwidth; boxbounds.y0 = 0.0f + 0.5f * chheight; boxbounds.y1 = 1.0f - 0.5f * chheight; // the character cell box bounds starts a half character in from the box cellboxbounds = boxbounds; cellboxbounds.x0 += 0.5f * chwidth; cellboxbounds.x1 -= 0.5f * chwidth; cellboxbounds.y0 += 0.5f * chheight; cellboxbounds.y1 -= 0.5f * chheight; // add space on the left for 5 characters of text, plus a half character of padding cellboxbounds.x0 += 5.5f * chwidth; // add space on the top for a title, a half line of padding, a header, and another half line cellboxbounds.y0 += 3.0f * chheight; // figure out the title and expand the outer box to fit const char *suffix = palette->indirect_entries() == 0 ? "" : state.palette.which ? _(" COLORS") : _(" PENS"); sprintf(title, "'%s'%s", palette->tag(), suffix); titlewidth = ui_font->string_width(chheight, mui.machine().render().ui_aspect(), title); x0 = 0.0f; if (boxbounds.x1 - boxbounds.x0 < titlewidth + chwidth) x0 = boxbounds.x0 - (0.5f - 0.5f * (titlewidth + chwidth)); // go ahead and draw the outer box now mui.draw_outlined_box(container, boxbounds.x0 - x0, boxbounds.y0, boxbounds.x1 + x0, boxbounds.y1, UI_GFXVIEWER_BG_COLOR); // draw the title x0 = 0.5f - 0.5f * titlewidth; y0 = boxbounds.y0 + 0.5f * chheight; for (x = 0; title[x] != 0; x++) { container->add_char(x0, y0, chheight, mui.machine().render().ui_aspect(), rgb_t::white, *ui_font, title[x]); x0 += ui_font->char_width(chheight, mui.machine().render().ui_aspect(), title[x]); } // compute the cell size cellwidth = (cellboxbounds.x1 - cellboxbounds.x0) / (float)state.palette.columns; cellheight = (cellboxbounds.y1 - cellboxbounds.y0) / (float)state.palette.columns; // draw the top column headers skip = (int)(chwidth / cellwidth); for (x = 0; x < state.palette.columns; x += 1 + skip) { x0 = boxbounds.x0 + 6.0f * chwidth + (float)x * cellwidth; y0 = boxbounds.y0 + 2.0f * chheight; container->add_char(x0 + 0.5f * (cellwidth - chwidth), y0, chheight, mui.machine().render().ui_aspect(), rgb_t::white, *ui_font, "0123456789ABCDEF"[x & 0xf]); // if we're skipping, draw a point between the character and the box to indicate which // one it's referring to if (skip != 0) container->add_point(x0 + 0.5f * cellwidth, 0.5f * (y0 + chheight + cellboxbounds.y0), UI_LINE_WIDTH, rgb_t::white, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); } // draw the side column headers skip = (int)(chheight / cellheight); for (y = 0; y < state.palette.columns; y += 1 + skip) // only display if there is data to show if (state.palette.offset + y * state.palette.columns < total) { char buffer[10]; // if we're skipping, draw a point between the character and the box to indicate which // one it's referring to x0 = boxbounds.x0 + 5.5f * chwidth; y0 = boxbounds.y0 + 3.5f * chheight + (float)y * cellheight; if (skip != 0) container->add_point(0.5f * (x0 + cellboxbounds.x0), y0 + 0.5f * cellheight, UI_LINE_WIDTH, rgb_t::white, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); // draw the row header sprintf(buffer, "%5X", state.palette.offset + y * state.palette.columns); for (x = 4; x >= 0; x--) { x0 -= ui_font->char_width(chheight, mui.machine().render().ui_aspect(), buffer[x]); container->add_char(x0, y0 + 0.5f * (cellheight - chheight), chheight, mui.machine().render().ui_aspect(), rgb_t::white, *ui_font, buffer[x]); } } // now add the rectangles for the colors for (y = 0; y < state.palette.columns; y++) for (x = 0; x < state.palette.columns; x++) { int index = state.palette.offset + y * state.palette.columns + x; if (index < total) { pen_t pen = state.palette.which ? palette->indirect_color(index) : raw_color[index]; container->add_rect(cellboxbounds.x0 + x * cellwidth, cellboxbounds.y0 + y * cellheight, cellboxbounds.x0 + (x + 1) * cellwidth, cellboxbounds.y0 + (y + 1) * cellheight, 0xff000000 | pen, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); } } // handle keys palette_handle_keys(mui.machine(), state); }
static void tilemap_handler(mame_ui_manager &mui, render_container *container, ui_gfx_state &state) { render_font *ui_font = mui.get_font(); float chwidth, chheight; render_bounds mapboxbounds; render_bounds boxbounds; int targwidth = mui.machine().render().ui_target().width(); int targheight = mui.machine().render().ui_target().height(); float titlewidth; float x0, y0; int mapboxwidth, mapboxheight; int maxxscale, maxyscale; UINT32 mapwidth, mapheight; int x, pixelscale; char title[100]; // get the size of the tilemap itself tilemap_t *tilemap = mui.machine().tilemap().find(state.tilemap.which); mapwidth = tilemap->width(); mapheight = tilemap->height(); if (state.tilemap.rotate & ORIENTATION_SWAP_XY) { UINT32 temp = mapwidth; mapwidth = mapheight; mapheight = temp; } // add a half character padding for the box chheight = mui.get_line_height(); chwidth = ui_font->char_width(chheight, mui.machine().render().ui_aspect(), '0'); boxbounds.x0 = 0.0f + 0.5f * chwidth; boxbounds.x1 = 1.0f - 0.5f * chwidth; boxbounds.y0 = 0.0f + 0.5f * chheight; boxbounds.y1 = 1.0f - 0.5f * chheight; // the tilemap box bounds starts a half character in from the box mapboxbounds = boxbounds; mapboxbounds.x0 += 0.5f * chwidth; mapboxbounds.x1 -= 0.5f * chwidth; mapboxbounds.y0 += 0.5f * chheight; mapboxbounds.y1 -= 0.5f * chheight; // add space on the top for a title and a half line of padding mapboxbounds.y0 += 1.5f * chheight; // convert back to pixels mapboxwidth = (mapboxbounds.x1 - mapboxbounds.x0) * (float)targwidth; mapboxheight = (mapboxbounds.y1 - mapboxbounds.y0) * (float)targheight; // determine the maximum integral scaling factor pixelscale = state.tilemap.zoom; if (pixelscale == 0) { for (maxxscale = 1; mapwidth * (maxxscale + 1) < mapboxwidth; maxxscale++) { } for (maxyscale = 1; mapheight * (maxyscale + 1) < mapboxheight; maxyscale++) { } pixelscale = MIN(maxxscale, maxyscale); } // recompute the final box size mapboxwidth = MIN(mapboxwidth, mapwidth * pixelscale); mapboxheight = MIN(mapboxheight, mapheight * pixelscale); // recompute the bounds, centered within the existing bounds mapboxbounds.x0 += 0.5f * ((mapboxbounds.x1 - mapboxbounds.x0) - (float)mapboxwidth / (float)targwidth); mapboxbounds.x1 = mapboxbounds.x0 + (float)mapboxwidth / (float)targwidth; mapboxbounds.y0 += 0.5f * ((mapboxbounds.y1 - mapboxbounds.y0) - (float)mapboxheight / (float)targheight); mapboxbounds.y1 = mapboxbounds.y0 + (float)mapboxheight / (float)targheight; // now recompute the outer box against this new info boxbounds.x0 = mapboxbounds.x0 - 0.5f * chwidth; boxbounds.x1 = mapboxbounds.x1 + 0.5f * chwidth; boxbounds.y0 = mapboxbounds.y0 - 2.0f * chheight; boxbounds.y1 = mapboxbounds.y1 + 0.5f * chheight; // figure out the title and expand the outer box to fit sprintf(title, "TILEMAP %d/%d %dx%d OFFS %d,%d", state.tilemap.which, mui.machine().tilemap().count() - 1, mapwidth, mapheight, state.tilemap.xoffs, state.tilemap.yoffs); titlewidth = ui_font->string_width(chheight, mui.machine().render().ui_aspect(), title); if (boxbounds.x1 - boxbounds.x0 < titlewidth + chwidth) { boxbounds.x0 = 0.5f - 0.5f * (titlewidth + chwidth); boxbounds.x1 = boxbounds.x0 + titlewidth + chwidth; } // go ahead and draw the outer box now mui.draw_outlined_box(container, boxbounds.x0, boxbounds.y0, boxbounds.x1, boxbounds.y1, UI_GFXVIEWER_BG_COLOR); // draw the title x0 = 0.5f - 0.5f * titlewidth; y0 = boxbounds.y0 + 0.5f * chheight; for (x = 0; title[x] != 0; x++) { container->add_char(x0, y0, chheight, mui.machine().render().ui_aspect(), rgb_t::white, *ui_font, title[x]); x0 += ui_font->char_width(chheight, mui.machine().render().ui_aspect(), title[x]); } // update the bitmap tilemap_update_bitmap(mui.machine(), state, mapboxwidth / pixelscale, mapboxheight / pixelscale); // add the final quad container->add_quad(mapboxbounds.x0, mapboxbounds.y0, mapboxbounds.x1, mapboxbounds.y1, rgb_t::white, state.texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(state.tilemap.rotate)); // handle keyboard input tilemap_handle_keys(mui.machine(), state, mapboxwidth, mapboxheight); }
static void gfxset_handler(mame_ui_manager &mui, render_container *container, ui_gfx_state &state) { render_font *ui_font = mui.get_font(); int dev = state.gfxset.devindex; int set = state.gfxset.set; ui_gfx_info &info = state.gfxdev[dev]; device_gfx_interface &interface = *info.interface; gfx_element &gfx = *interface.gfx(set); float fullwidth, fullheight; float cellwidth, cellheight; float chwidth, chheight; float titlewidth; //float cellaspect; float x0, y0; render_bounds cellboxbounds; render_bounds boxbounds; int cellboxwidth, cellboxheight; int targwidth = mui.machine().render().ui_target().width(); int targheight = mui.machine().render().ui_target().height(); int cellxpix, cellypix; int xcells, ycells; int pixelscale = 0; int x, y, skip; char title[100]; // add a half character padding for the box chheight = mui.get_line_height(); chwidth = ui_font->char_width(chheight, mui.machine().render().ui_aspect(), '0'); boxbounds.x0 = 0.0f + 0.5f * chwidth; boxbounds.x1 = 1.0f - 0.5f * chwidth; boxbounds.y0 = 0.0f + 0.5f * chheight; boxbounds.y1 = 1.0f - 0.5f * chheight; // the character cell box bounds starts a half character in from the box cellboxbounds = boxbounds; cellboxbounds.x0 += 0.5f * chwidth; cellboxbounds.x1 -= 0.5f * chwidth; cellboxbounds.y0 += 0.5f * chheight; cellboxbounds.y1 -= 0.5f * chheight; // add space on the left for 5 characters of text, plus a half character of padding cellboxbounds.x0 += 5.5f * chwidth; // add space on the top for a title, a half line of padding, a header, and another half line cellboxbounds.y0 += 3.0f * chheight; // convert back to pixels cellboxwidth = (cellboxbounds.x1 - cellboxbounds.x0) * (float)targwidth; cellboxheight = (cellboxbounds.y1 - cellboxbounds.y0) * (float)targheight; // compute the number of source pixels in a cell cellxpix = 1 + ((info.rotate[set] & ORIENTATION_SWAP_XY) ? gfx.height() : gfx.width()); cellypix = 1 + ((info.rotate[set] & ORIENTATION_SWAP_XY) ? gfx.width() : gfx.height()); // compute the largest pixel scale factor that still fits xcells = info.columns[set]; while (xcells > 1) { pixelscale = (cellboxwidth / xcells) / cellxpix; if (pixelscale != 0) break; xcells--; } info.columns[set] = xcells; // worst case, we need a pixel scale of 1 pixelscale = MAX(1, pixelscale); // in the Y direction, we just display as many as we can ycells = cellboxheight / (pixelscale * cellypix); // now determine the actual cellbox size cellboxwidth = MIN(cellboxwidth, xcells * pixelscale * cellxpix); cellboxheight = MIN(cellboxheight, ycells * pixelscale * cellypix); // compute the size of a single cell at this pixel scale factor, as well as the aspect ratio cellwidth = (cellboxwidth / (float)xcells) / (float)targwidth; cellheight = (cellboxheight / (float)ycells) / (float)targheight; //cellaspect = cellwidth / cellheight; // working from the new width/height, recompute the boxbounds fullwidth = (float)cellboxwidth / (float)targwidth + 6.5f * chwidth; fullheight = (float)cellboxheight / (float)targheight + 4.0f * chheight; // recompute boxbounds from this boxbounds.x0 = (1.0f - fullwidth) * 0.5f; boxbounds.x1 = boxbounds.x0 + fullwidth; boxbounds.y0 = (1.0f - fullheight) * 0.5f; boxbounds.y1 = boxbounds.y0 + fullheight; // figure out the title and expand the outer box to fit sprintf(title, "'%s' %d/%d %dx%d COLOR %X", interface.device().tag(), set, info.setcount - 1, gfx.width(), gfx.height(), info.color[set]); titlewidth = ui_font->string_width(chheight, mui.machine().render().ui_aspect(), title); x0 = 0.0f; if (boxbounds.x1 - boxbounds.x0 < titlewidth + chwidth) x0 = boxbounds.x0 - (0.5f - 0.5f * (titlewidth + chwidth)); // go ahead and draw the outer box now mui.draw_outlined_box(container, boxbounds.x0 - x0, boxbounds.y0, boxbounds.x1 + x0, boxbounds.y1, UI_GFXVIEWER_BG_COLOR); // draw the title x0 = 0.5f - 0.5f * titlewidth; y0 = boxbounds.y0 + 0.5f * chheight; for (x = 0; title[x] != 0; x++) { container->add_char(x0, y0, chheight, mui.machine().render().ui_aspect(), rgb_t::white, *ui_font, title[x]); x0 += ui_font->char_width(chheight, mui.machine().render().ui_aspect(), title[x]); } // draw the top column headers skip = (int)(chwidth / cellwidth); for (x = 0; x < xcells; x += 1 + skip) { x0 = boxbounds.x0 + 6.0f * chwidth + (float)x * cellwidth; y0 = boxbounds.y0 + 2.0f * chheight; container->add_char(x0 + 0.5f * (cellwidth - chwidth), y0, chheight, mui.machine().render().ui_aspect(), rgb_t::white, *ui_font, "0123456789ABCDEF"[x & 0xf]); // if we're skipping, draw a point between the character and the box to indicate which // one it's referring to if (skip != 0) container->add_point(x0 + 0.5f * cellwidth, 0.5f * (y0 + chheight + boxbounds.y0 + 3.5f * chheight), UI_LINE_WIDTH, rgb_t::white, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); } // draw the side column headers skip = (int)(chheight / cellheight); for (y = 0; y < ycells; y += 1 + skip) // only display if there is data to show if (info.offset[set] + y * xcells < gfx.elements()) { char buffer[10]; // if we're skipping, draw a point between the character and the box to indicate which // one it's referring to x0 = boxbounds.x0 + 5.5f * chwidth; y0 = boxbounds.y0 + 3.5f * chheight + (float)y * cellheight; if (skip != 0) container->add_point(0.5f * (x0 + boxbounds.x0 + 6.0f * chwidth), y0 + 0.5f * cellheight, UI_LINE_WIDTH, rgb_t::white, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); // draw the row header sprintf(buffer, "%5X", info.offset[set] + y * xcells); for (x = 4; x >= 0; x--) { x0 -= ui_font->char_width(chheight, mui.machine().render().ui_aspect(), buffer[x]); container->add_char(x0, y0 + 0.5f * (cellheight - chheight), chheight, mui.machine().render().ui_aspect(), rgb_t::white, *ui_font, buffer[x]); } } // update the bitmap gfxset_update_bitmap(mui.machine(), state, xcells, ycells, gfx); // add the final quad container->add_quad(boxbounds.x0 + 6.0f * chwidth, boxbounds.y0 + 3.5f * chheight, boxbounds.x0 + 6.0f * chwidth + (float)cellboxwidth / (float)targwidth, boxbounds.y0 + 3.5f * chheight + (float)cellboxheight / (float)targheight, rgb_t::white, state.texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); // handle keyboard navigation before drawing gfxset_handle_keys(mui.machine(), state, xcells, ycells); }