// license:BSD-3-Clause // copyright-holders:Nicola Salmoria, Aaron Giles, Nathan Woods, Vas Crabb /*************************************************************************** ui/selmenu.h MAME system/software selection menu. ***************************************************************************/ #ifndef MAME_FRONTEND_UI_SELMENU_H #define MAME_FRONTEND_UI_SELMENU_H #pragma once #include "ui/menu.h" #include #include #include #include struct ui_software_info; namespace ui { class machine_static_info; class menu_select_launch : public menu { public: virtual ~menu_select_launch() override; protected: static constexpr std::size_t MAX_ICONS_RENDER = 128; static constexpr std::size_t MAX_VISIBLE_SEARCH = 200; // tab navigation enum class focused_menu { MAIN, LEFT, RIGHTTOP, RIGHTBOTTOM }; struct texture_and_bitmap { template texture_and_bitmap(T &&tex) : texture(std::forward(tex)) { } texture_and_bitmap(texture_and_bitmap &&that) = default; texture_and_bitmap &operator=(texture_and_bitmap &&that) = default; texture_ptr texture; bitmap_argb32 bitmap; }; template > using texture_lru = util::lru_cache_map; class system_flags { public: system_flags(machine_static_info const &info); system_flags(system_flags const &) = default; system_flags(system_flags &&) = default; system_flags &operator=(system_flags const &) = default; system_flags &operator=(system_flags &&) = default; ::machine_flags::type machine_flags() const { return m_machine_flags; } device_t::feature_type unemulated_features() const { return m_unemulated_features; } device_t::feature_type imperfect_features() const { return m_imperfect_features; } bool has_keyboard() const { return m_has_keyboard; } bool has_analog() const { return m_has_analog; } rgb_t status_color() const { return m_status_color; } private: ::machine_flags::type m_machine_flags; device_t::feature_type m_unemulated_features; device_t::feature_type m_imperfect_features; bool m_has_keyboard; bool m_has_analog; rgb_t m_status_color; }; class reselect_last { public: static std::string const &driver() { return s_driver; } static std::string const &software() { return s_software; } static std::string const &swlist() { return s_swlist; } static void reselect(bool value) { s_reselect = value; } static bool get() { return s_reselect; } static void reset(); static void set_driver(std::string const &name); static void set_driver(game_driver const &driver) { set_driver(driver.name); } static void set_software(game_driver const &driver, ui_software_info const &swinfo); private: static std::string s_driver, s_software, s_swlist; static bool s_reselect; }; menu_select_launch(mame_ui_manager &mui, render_container &container, bool is_swlist); focused_menu get_focus() const { return m_focus; } void set_focus(focused_menu focus) { m_focus = focus; } void next_image_view(); void previous_image_view(); bool dismiss_error(); void set_error(reset_options ropt, std::string &&message); system_flags const &get_system_flags(game_driver const &driver); void launch_system(game_driver const &driver) { launch_system(ui(), driver, nullptr, nullptr, nullptr); } void launch_system(game_driver const &driver, ui_software_info const &swinfo) { launch_system(ui(), driver, &swinfo, nullptr, nullptr); } void launch_system(game_driver const &driver, ui_software_info const &swinfo, std::string const &part) { launch_system(ui(), driver, &swinfo, &part, nullptr); } virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override; // handlers virtual void inkey_export() = 0; void inkey_dats(); // draw arrow void draw_common_arrow(float origx1, float origy1, float origx2, float origy2, int current, int dmin, int dmax, float title); void draw_info_arrow(int ub, float origx1, float origx2, float oy1, float line_height, float text_size, float ud_arrow_width); bool draw_error_text(); template float draw_left_panel( typename Filter::type current, std::map const &filters, float x1, float y1, float x2, float y2); // icon helpers void check_for_icons(char const *listname); std::string make_icon_paths(char const *listname) const; bool scale_icon(bitmap_argb32 &&src, texture_and_bitmap &dst) const; // forcing refresh void set_switch_image() { m_switch_image = true; } template bool select_bios(T const &driver, bool inlist); bool select_part(software_info const &info, ui_software_info const &ui_info); void *get_selection_ptr() const { void *const selected_ref(get_selection_ref()); return (uintptr_t(selected_ref) > skip_main_items) ? selected_ref : m_prev_selected; } int m_available_items; int skip_main_items; void *m_prev_selected; int m_total_lines; int m_topline_datsview; int m_filter_highlight; std::string m_search; private: using bitmap_vector = std::vector; using texture_ptr_vector = std::vector; using s_parts = std::unordered_map; using s_bios = std::vector>; class software_parts; class bios_selection; class cache { public: cache(running_machine &machine); ~cache(); bitmap_argb32 &snapx_bitmap() { return *m_snapx_bitmap; } render_texture *snapx_texture() { return m_snapx_texture.get(); } bool snapx_driver_is(game_driver const *value) const { return m_snapx_driver == value; } bool snapx_software_is(ui_software_info const *software) const { return m_snapx_software == software; } void set_snapx_driver(game_driver const *value) { m_snapx_driver = value; } void set_snapx_software(ui_software_info const *software) { m_snapx_software = software; } bitmap_argb32 &no_avail_bitmap() { return m_no_avail_bitmap; } render_texture *star_texture() { return m_star_texture.get(); } bitmap_vector const &toolbar_bitmap() { return m_toolbar_bitmap; } bitmap_vector const &sw_toolbar_bitmap() { return m_sw_toolbar_bitmap; } texture_ptr_vector const &toolbar_texture() { return m_toolbar_texture; } texture_ptr_vector const &sw_toolbar_texture() { return m_sw_toolbar_texture; } private: bitmap_ptr m_snapx_bitmap; texture_ptr m_snapx_texture; game_driver const *m_snapx_driver; ui_software_info const *m_snapx_software; bitmap_argb32 m_no_avail_bitmap; bitmap_argb32 m_star_bitmap; texture_ptr m_star_texture; bitmap_vector m_toolbar_bitmap; bitmap_vector m_sw_toolbar_bitmap; texture_ptr_vector m_toolbar_texture; texture_ptr_vector m_sw_toolbar_texture; }; using cache_ptr = std::shared_ptr; using cache_ptr_map = std::map; using flags_cache = util::lru_cache_map; void reset_pressed() { m_pressed = false; m_repeat = 0; } bool mouse_pressed() const { return (osd_ticks() >= m_repeat); } void set_pressed(); bool snapx_valid() const { return m_cache->snapx_bitmap().valid(); } // draw left panel virtual float draw_left_panel(float x1, float y1, float x2, float y2) = 0; float draw_collapsed_left_panel(float x1, float y1, float x2, float y2); // draw infos void infos_render(float x1, float y1, float x2, float y2); virtual void general_info(const game_driver *driver, std::string &buffer) = 0; // get selected software and/or driver virtual void get_selection(ui_software_info const *&software, game_driver const *&driver) const = 0; virtual bool accept_search() const { return true; } void select_prev() { if (!m_prev_selected) { set_selected_index(0); } else { for (int x = 0; x < item_count(); ++x) { if (item(x).ref == m_prev_selected) { set_selected_index(x); break; } } } } void rotate_focus(int dir); void draw_toolbar(float x1, float y1, float x2, float y2); void draw_star(float x0, float y0); void draw_icon(int linenum, void *selectedref, float x1, float y1); virtual render_texture *get_icon_texture(int linenum, void *selectedref) = 0; void get_title_search(std::string &title, std::string &search); // handle keys virtual void handle_keys(uint32_t flags, int &iptkey) override; // handle mouse virtual void handle_events(uint32_t flags, event &ev) override; // live search active? virtual bool menu_has_search_active() override { return !m_search.empty(); } // draw game list virtual void draw(uint32_t flags) override; // draw right panel void draw_right_panel(float origx1, float origy1, float origx2, float origy2); float draw_right_box_title(float x1, float y1, float x2, float y2); // images render void arts_render(float origx1, float origy1, float origx2, float origy2); std::string arts_render_common(float origx1, float origy1, float origx2, float origy2); void arts_render_images(bitmap_argb32 &&bitmap, float origx1, float origy1, float origx2, float origy2); void draw_snapx(float origx1, float origy1, float origx2, float origy2); // text for main top/bottom panels virtual void make_topbox_text(std::string &line0, std::string &line1, std::string &line2) const = 0; virtual std::string make_driver_description(game_driver const &driver) const = 0; virtual std::string make_software_description(ui_software_info const &software) const = 0; // filter navigation virtual void filter_selected() = 0; static void launch_system(mame_ui_manager &mui, game_driver const &driver, ui_software_info const *swinfo, std::string const *part, int const *bios); static bool select_part(mame_ui_manager &mui, render_container &container, software_info const &info, ui_software_info const &ui_info); static bool has_multiple_bios(ui_software_info const &swinfo, s_bios &biosname); static bool has_multiple_bios(game_driver const &driver, s_bios &biosname); // cleanup function static void exit(running_machine &machine); bool m_ui_error; std::string m_error_text; game_driver const *m_info_driver; ui_software_info const *m_info_software; int m_info_view; std::vector m_items_list; std::string m_info_buffer; cache_ptr m_cache; bool m_is_swlist; focused_menu m_focus; bool m_pressed; // mouse button held down osd_ticks_t m_repeat; int m_right_visible_lines; // right box lines bool m_has_icons; bool m_switch_image; bool m_default_image; uint8_t m_image_view; flags_cache m_flags; static std::mutex s_cache_guard; static cache_ptr_map s_caches; }; } // namespace ui #endif // MAME_FRONTEND_UI_SELMENU_H