#ifndef _controller__hpp__included__ #define _controller__hpp__included__ #include #include #include "library/dispatch.hpp" struct project_info; struct controller_state; struct port_controller; struct port_type; struct emu_framebuffer; struct emulator_dispatch; struct lua_state; struct core_core; namespace keyboard { class invbind; } namespace keyboard { class ctrlrkey; } namespace keyboard { class mapper; } namespace keyboard { class keyboard; } class button_mapping { public: struct controller_bind { std::string cclass; unsigned number; std::string name; int mode; //0 => Button, 1 => Axis pair, 2 => Single axis. bool xrel; bool yrel; unsigned control1; unsigned control2; //Axis only, UINT_MAX if not valid. int16_t rmin; int16_t rmax; bool centered; }; struct active_bind { unsigned port; unsigned controller; struct controller_bind bind; }; struct controller_triple { std::string cclass; unsigned port; unsigned controller; bool operator<(const struct controller_triple& t) const throw() { if(cclass < t.cclass) return true; if(cclass > t.cclass) return false; if(port < t.port) return true; if(port > t.port) return false; if(controller < t.controller) return true; if(controller > t.controller) return false; return false; } bool operator==(const struct controller_triple& t) const throw() { return (cclass == t.cclass && port == t.port && controller == t.controller); } }; /** * Ctor. */ button_mapping(controller_state& _controls, keyboard::mapper& mapper, keyboard::keyboard& keyboard, emu_framebuffer& fbuf, emulator_dispatch& _dispatch, lua_state& _lua2); /** * Dtor. */ ~button_mapping(); /** * Reread active buttons. */ void reread(); /** * Reinitialize buttons. */ void reinit(); /** * Load macros. */ void load(controller_state& ctrlstate); /** * Load macros (from project). */ void load(controller_state& ctrlstate, project_info& pinfo); /** * Cleanup memory used. */ void cleanup(); /** * Lookup button by name. */ std::pair byname(const std::string& name); /** * Map of button keys. */ std::map button_keys; /** * Do button/axis action. */ void do_action(const std::string& name, short state, int mode); void do_analog_action(const std::string& a); void do_autofire_action(const std::string& a, int mode); private: void promote_key(keyboard::ctrlrkey& k); void add_button(const std::string& name, const controller_bind& binding); void process_controller(port_controller& controller, unsigned number); void process_controller(std::map& allocated, std::map& assigned, port_controller& controller, unsigned port, unsigned number_in_port); void process_port(std::map& allocated, std::map& assigned, unsigned port, port_type& ptype); void init(); bool check_button_active(const std::string& name); void do_button_action(const std::string& name, short newstate, int mode); void send_analog(const std::string& name, int32_t x, int32_t y); std::map macro_binds; std::map macro_binds2; std::map all_buttons; std::map active_buttons; std::map added_keys; std::set cores_done; controller_state& controls; keyboard::mapper& mapper; keyboard::keyboard& keyboard; emu_framebuffer& fbuf; emulator_dispatch& edispatch; lua_state& lua2; struct dispatch::target<> ncore; }; #endif