summaryrefslogtreecommitdiffstatshomepage
path: root/src/frontend/mame/ui/selgame.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/frontend/mame/ui/selgame.cpp')
-rw-r--r--src/frontend/mame/ui/selgame.cpp183
1 files changed, 54 insertions, 129 deletions
diff --git a/src/frontend/mame/ui/selgame.cpp b/src/frontend/mame/ui/selgame.cpp
index c36392e8b10..aaf73703d62 100644
--- a/src/frontend/mame/ui/selgame.cpp
+++ b/src/frontend/mame/ui/selgame.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Maurizio Petrarota
+// copyright-holders:Maurizio Petrarota, Vas Crabb
/*********************************************************************
ui/selgame.cpp
@@ -12,6 +12,7 @@
#include "ui/selgame.h"
#include "ui/auditmenu.h"
+#include "ui/icorender.h"
#include "ui/inifile.h"
#include "ui/miscmenu.h"
#include "ui/optsmenu.h"
@@ -39,8 +40,6 @@
#include <mutex>
#include <thread>
-#include "ui/icorender.h" // this is inline code
-
extern const char UI_VERSION_TAG[];
@@ -220,10 +219,11 @@ menu_select_game::menu_select_game(mame_ui_manager &mui, render_container &conta
: menu_select_launch(mui, container, false)
, m_persistent_data(persistent_data::instance())
, m_icons(MAX_ICONS_RENDER)
- , m_has_icons(false)
+ , m_icon_paths()
, m_displaylist()
, m_searchlist()
, m_searched_fields(persistent_data::AVAIL_NONE)
+ , m_populated_favorites(false)
{
std::string error_string, last_filter, sub_filter;
ui_options &moptions = mui.options();
@@ -231,18 +231,8 @@ menu_select_game::menu_select_game(mame_ui_manager &mui, render_container &conta
// load drivers cache
m_persistent_data.cache_data();
- // check if there are available icons
- file_enumerator path(moptions.icons_directory());
- const osd::directory::entry *dir;
- while ((dir = path.next()) != nullptr)
- {
- std::string src(dir->name);
- if (src.find(".ico") != std::string::npos || src.find("icons") != std::string::npos)
- {
- m_has_icons = true;
- break;
- }
- }
+ // check if there are available system icons
+ check_for_icons(nullptr);
// build drivers list
if (!load_available_machines())
@@ -334,13 +324,13 @@ void menu_select_game::handle()
return;
}
- // if i have to reselect a software, force software list submenu
+ // if I have to select software, force software list submenu
if (reselect_last::get())
{
const game_driver *driver;
const ui_software_info *software;
get_selection(software, driver);
- menu::stack_push<menu_select_software>(ui(), container(), driver);
+ menu::stack_push<menu_select_software>(ui(), container(), *driver);
return;
}
@@ -397,7 +387,7 @@ void menu_select_game::handle()
case IPT_UI_SELECT:
if (get_focus() == focused_menu::MAIN)
{
- if (isfavorite())
+ if (m_populated_favorites)
inkey_select_favorite(menu_event);
else
inkey_select(menu_event);
@@ -406,7 +396,7 @@ void menu_select_game::handle()
case IPT_CUSTOM:
// handle IPT_CUSTOM (mouse right click)
- if (!isfavorite())
+ if (!m_populated_favorites)
{
menu::stack_push<menu_machine_configure>(
ui(), container(),
@@ -459,7 +449,7 @@ void menu_select_game::handle()
if (uintptr_t(menu_event->itemref) > skip_main_items)
{
favorite_manager &mfav(mame_machine_manager::instance()->favorite());
- if (!isfavorite())
+ if (!m_populated_favorites)
{
game_driver const *const driver(reinterpret_cast<game_driver const *>(menu_event->itemref));
if (!mfav.is_favorite_system(*driver))
@@ -506,16 +496,19 @@ void menu_select_game::handle()
void menu_select_game::populate(float &customtop, float &custombottom)
{
- set_redraw_icon();
+ for (auto &icon : m_icons) // TODO: why is this here? maybe better on resize or setting change?
+ icon.second.texture.reset();
+
set_switch_image();
int old_item_selected = -1;
constexpr uint32_t flags_ui = FLAG_LEFT_ARROW | FLAG_RIGHT_ARROW;
if (!isfavorite())
{
- // if search is not empty, find approximate matches
+ m_populated_favorites = false;
if (!m_search.empty())
{
+ // if search is not empty, find approximate matches
populate_search();
}
else
@@ -555,11 +548,11 @@ void menu_select_game::populate(float &customtop, float &custombottom)
else
{
// populate favorites list
+ m_populated_favorites = true;
m_search.clear();
mame_machine_manager::instance()->favorite().apply_sorted(
[this, &old_item_selected, curitem = 0] (ui_software_info const &info) mutable
{
- auto flags = flags_ui | FLAG_UI_FAVORITE;
if (info.startempty == 1)
{
if (old_item_selected == -1 && info.shortname == reselect_last::driver())
@@ -573,14 +566,14 @@ void menu_select_game::populate(float &customtop, float &custombottom)
cloneof = false;
}
- item_append(info.longname, "", (cloneof) ? (flags | FLAG_INVERT) : flags, (void *)&info);
+ item_append(info.longname, "", cloneof ? (flags_ui | FLAG_INVERT) : flags_ui, (void *)&info);
}
else
{
if (old_item_selected == -1 && info.shortname == reselect_last::driver())
old_item_selected = curitem;
item_append(info.longname, info.devicetype,
- info.parentname.empty() ? flags : (FLAG_INVERT | flags), (void *)&info);
+ info.parentname.empty() ? flags_ui : (FLAG_INVERT | flags_ui), (void *)&info);
}
curitem++;
});
@@ -792,7 +785,7 @@ void menu_select_game::inkey_select(const event *menu_event)
{
if (!swlistdev.get_info().empty())
{
- menu::stack_push<menu_select_software>(ui(), container(), driver);
+ menu::stack_push<menu_select_software>(ui(), container(), *driver);
return;
}
}
@@ -862,7 +855,7 @@ void menu_select_game::inkey_select_favorite(const event *menu_event)
{
if (!swlistdev.get_info().empty())
{
- menu::stack_push<menu_select_software>(ui(), container(), ui_swinfo->driver);
+ menu::stack_push<menu_select_software>(ui(), container(), *ui_swinfo->driver);
return;
}
}
@@ -935,7 +928,7 @@ void menu_select_game::change_info_pane(int delta)
game_driver const *drv;
ui_software_info const *soft;
get_selection(soft, drv);
- if (!isfavorite())
+ if (!m_populated_favorites)
{
if (uintptr_t(drv) > skip_main_items)
cap_delta(ui_globals::curdats_view, ui_globals::curdats_total);
@@ -1009,7 +1002,7 @@ void menu_select_game::populate_search()
m_searchlist.end(),
[] (auto const &lhs, auto const &rhs) { return lhs.first < rhs.first; });
uint32_t flags_ui = FLAG_LEFT_ARROW | FLAG_RIGHT_ARROW;
- for (int curitem = 0; (std::min)(m_searchlist.size(), std::size_t(200)) > curitem; ++curitem)
+ for (int curitem = 0; (std::min)(m_searchlist.size(), MAX_VISIBLE_SEARCH) > curitem; ++curitem)
{
game_driver const &drv(*m_searchlist[curitem].second.get().driver);
bool cloneof = strcmp(drv.parent, "0") != 0;
@@ -1176,39 +1169,31 @@ void menu_select_game::general_info(const game_driver *driver, std::string &buff
//-------------------------------------------------
-// draw icons
+// get (possibly cached) icon texture
//-------------------------------------------------
-float menu_select_game::draw_icon(int linenum, void *selectedref, float x0, float y0)
+render_texture *menu_select_game::get_icon_texture(int linenum, void *selectedref)
{
- if (!m_has_icons)
- return 0.0f;
-
- float ud_arrow_width = ui().get_line_height() * container().manager().ui_aspect(&container());
- const game_driver *driver = nullptr;
-
- if (item[0].flags & FLAG_UI_FAVORITE)
- {
- ui_software_info *soft = (ui_software_info *)selectedref;
- if (soft->startempty == 1)
- driver = soft->driver;
- }
- else
- driver = (const game_driver *)selectedref;
-
- auto x1 = x0 + ud_arrow_width;
- auto y1 = y0 + ui().get_line_height();
+ game_driver const *const driver(m_populated_favorites
+ ? reinterpret_cast<ui_software_info const *>(selectedref)->driver
+ : reinterpret_cast<game_driver const *>(selectedref));
+ assert(driver);
icon_cache::iterator icon(m_icons.find(driver));
- if ((m_icons.end() == icon) || redraw_icon())
+ if ((m_icons.end() == icon) || !icon->second.texture)
{
+ if (m_icon_paths.empty())
+ m_icon_paths = make_icon_paths(nullptr);
+
+ // allocate an entry or allocate a texture on forced redraw
if (m_icons.end() == icon)
{
- texture_ptr texture(machine().render().texture_alloc(), [&render = machine().render()] (render_texture *texture) { render.texture_free(texture); });
- icon = m_icons.emplace(
- std::piecewise_construct,
- std::forward_as_tuple(driver),
- std::forward_as_tuple(std::piecewise_construct, std::forward_as_tuple(std::move(texture)), std::tuple<>())).first;
+ icon = m_icons.emplace(driver, texture_ptr(machine().render().texture_alloc(), machine().render())).first;
+ }
+ else
+ {
+ assert(!icon->second.texture);
+ icon->second.texture.reset(machine().render().texture_alloc());
}
// set clone status
@@ -1220,83 +1205,23 @@ float menu_select_game::draw_icon(int linenum, void *selectedref, float x0, floa
cloneof = false;
}
- // get search path
- path_iterator path(ui().options().icons_directory());
- std::string curpath;
- std::string searchstr(ui().options().icons_directory());
-
- // iterate over path and add path for zipped formats
- while (path.next(curpath))
- searchstr.append(";").append(curpath.c_str()).append(PATH_SEPARATOR).append("icons");
-
bitmap_argb32 tmp;
- emu_file snapfile(searchstr.c_str(), OPEN_FLAG_READ);
- std::string fullname = std::string(driver->name).append(".ico");
- render_load_ico(tmp, snapfile, nullptr, fullname.c_str());
-
- if (!tmp.valid() && cloneof)
+ emu_file snapfile(std::string(m_icon_paths), OPEN_FLAG_READ);
+ if (snapfile.open(std::string(driver->name).append(".ico")) == osd_file::error::NONE)
{
- fullname.assign(driver->parent).append(".ico");
- render_load_ico(tmp, snapfile, nullptr, fullname.c_str());
- }
-
- bitmap_argb32 &bitmap(icon->second.second);
- if (tmp.valid())
- {
- float panel_width = x1 - x0;
- float panel_height = y1 - y0;
- auto screen_width = machine().render().ui_target().width();
- auto screen_height = machine().render().ui_target().height();
-
- if (machine().render().ui_target().orientation() & ORIENTATION_SWAP_XY)
- std::swap(screen_height, screen_width);
-
- int panel_width_pixel = panel_width * screen_width;
- int panel_height_pixel = panel_height * screen_height;
-
- // Calculate resize ratios for resizing
- auto ratioW = (float)panel_width_pixel / tmp.width();
- auto ratioH = (float)panel_height_pixel / tmp.height();
- auto dest_xPixel = tmp.width();
- auto dest_yPixel = tmp.height();
-
- if (ratioW < 1 || ratioH < 1)
- {
- // smaller ratio will ensure that the image fits in the view
- float ratio = std::min(ratioW, ratioH);
- dest_xPixel = tmp.width() * ratio;
- dest_yPixel = tmp.height() * ratio;
- }
-
- bitmap_argb32 dest_bitmap;
-
- // resample if necessary
- if (dest_xPixel != tmp.width() || dest_yPixel != tmp.height())
- {
- dest_bitmap.allocate(dest_xPixel, dest_yPixel);
- render_color color = { 1.0f, 1.0f, 1.0f, 1.0f };
- render_resample_argb_bitmap_hq(dest_bitmap, tmp, color, true);
- }
- else
- dest_bitmap = std::move(tmp);
-
- bitmap.allocate(panel_width_pixel, panel_height_pixel);
- for (int x = 0; x < dest_xPixel; x++)
- for (int y = 0; y < dest_yPixel; y++)
- bitmap.pix32(y, x) = dest_bitmap.pix32(y, x);
-
- icon->second.first->set_bitmap(bitmap, bitmap.cliprect(), TEXFORMAT_ARGB32);
+ render_load_ico_highest_detail(snapfile, tmp);
+ snapfile.close();
}
- else
+ if (!tmp.valid() && cloneof && (snapfile.open(std::string(driver->parent).append(".ico")) == osd_file::error::NONE))
{
- bitmap.reset();
+ render_load_ico_highest_detail(snapfile, tmp);
+ snapfile.close();
}
- }
- if (icon->second.second.valid())
- container().add_quad(x0, y0, x1, y1, rgb_t::white(), icon->second.first.get(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
+ scale_icon(std::move(tmp), icon->second);
+ }
- return ud_arrow_width * 1.5f;
+ return icon->second.bitmap.valid() ? icon->second.texture.get() : nullptr;
}
@@ -1305,12 +1230,12 @@ void menu_select_game::inkey_export()
std::vector<game_driver const *> list;
if (!m_search.empty())
{
- for (int curitem = 0; (std::min)(m_searchlist.size(), std::size_t(200)); ++curitem)
+ for (int curitem = 0; (std::min)(m_searchlist.size(), MAX_VISIBLE_SEARCH); ++curitem)
list.push_back(m_searchlist[curitem].second.get().driver);
}
else
{
- if (isfavorite())
+ if (m_populated_favorites)
{
// iterate over favorites
mame_machine_manager::instance()->favorite().apply(
@@ -1421,7 +1346,7 @@ float menu_select_game::draw_left_panel(float x1, float y1, float x2, float y2)
void menu_select_game::get_selection(ui_software_info const *&software, game_driver const *&driver) const
{
- if (item[0].flags & FLAG_UI_FAVORITE) // TODO: work out why this doesn't use isfavorite()
+ if (m_populated_favorites)
{
software = reinterpret_cast<ui_software_info const *>(get_selection_ptr());
driver = software ? software->driver : nullptr;
@@ -1442,7 +1367,7 @@ void menu_select_game::make_topbox_text(std::string &line0, std::string &line1,
(driver_list::total() - 1),
m_persistent_data.bios_count());
- if (isfavorite())
+ if (m_populated_favorites)
{
line1.clear();
}