summaryrefslogblamecommitdiffstatshomepage
path: root/src/frontend/mame/ui/selmenu.h
blob: e3d532e9cc33336608bcd9949ec1855269356473 (plain) (tree)
1
2
3
4
5
6
7
8
9
                       
                                                                          






                                                                            












                                  

                        
              


                          






                                               

                                                              



                               





                           













                                                                                   











                                                                                                    

                                                                    
                                                                     




                                                              

                                                       
                                                       

          



















                                                                                                    
                                                                                              


                                                               

                                   
 


                                                                  

                                                                        



                                                                                                                                                                        

                                                                                                                              
                   

                                        
 



                                                                                                                                      

                               



                                                                                             

                                                                







                                                                            


                                                                                     





                                                                                                    

                                      

                                     

                                       
                             

        
                                                         

                                                            


                                                                     

                             
 





                                                

                                                                                 




                                                                                                                       
                                                                              

                                                                               

                                                                                        



                                                                                               




                                                          

                                                          

                                                       

                                                            

                                                             



                                                                     
                                                                                   




                                                                        

                                                                            

                                                                                  
                                                                                
 
                     

                                                                                      


                                                                                                            
                                                           



                                     
                                              


                    
                                                              
                         
                                                                   
                                 
                                                              




                                              
                                   


                                                                  

                                                                                     



                                                                       
                                                                       

                       
                                                                       
 


                                                                                    
                         
                                                   
 

                                                                                      
                                                                           
 


                                                                                               
                                                                                                                

                                                                                




                                                                                                            


                                           




                                                                                                                                                             


                                                   
                               







                                                     


                                            
                                                                                 

                                         

                                                                          



                                                
                                        






                                              
                                    
// 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 <map>
#include <memory>
#include <mutex>
#include <vector>


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 <typename T>
		texture_and_bitmap(T &&tex) : texture(std::forward<T>(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 <typename Key, typename Compare = std::less<Key> >
	using texture_lru = util::lru_cache_map<Key, texture_and_bitmap, Compare>;

	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 <typename Filter>
	float draw_left_panel(
			typename Filter::type current,
			std::map<typename Filter::type, typename Filter::ptr> 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 <typename T> 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<bitmap_argb32>;
	using texture_ptr_vector = std::vector<texture_ptr>;

	using s_parts = std::unordered_map<std::string, std::string>;
	using s_bios = std::vector<std::pair<std::string, int>>;

	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<cache>;
	using cache_ptr_map = std::map<running_machine *, cache_ptr>;

	using flags_cache = util::lru_cache_map<game_driver const *, system_flags>;

	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<std::string>    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