Get rid of porttype_t and devicetype_t

This commit is contained in:
Ilari Liusvaara 2012-07-08 12:57:22 +03:00
parent 767b9719c2
commit e27d4374dc
17 changed files with 312 additions and 325 deletions

View file

@ -61,73 +61,6 @@
*/
#define MAX_ANALOG 3
/**
* This enumeration gives the type of port.
*/
enum porttype_t
{
/**
* No device
*/
PT_NONE = 0, //Nothing connected to port.
/**
* Gamepad
*/
PT_GAMEPAD = 1,
/**
* Multitap (with 4 gamepads connected)
*/
PT_MULTITAP = 2,
/**
* Mouse
*/
PT_MOUSE = 3,
/**
* Superscope (only allowed for port 2).
*/
PT_SUPERSCOPE = 4,
/**
* Justifier (only allowed for port 2).
*/
PT_JUSTIFIER = 5,
/**
* 2 Justifiers (only allowed for port 2).
*/
PT_JUSTIFIERS = 6,
/**
* Number of controller types.
*/
PT_LAST_CTYPE = 6,
/**
* Invalid controller type.
*/
PT_INVALID = PT_LAST_CTYPE + 1
};
/**
* This enumeration gives the type of device.
*/
enum devicetype_t
{
/**
* No device
*/
DT_NONE = 0,
/**
* Gamepad (note that multitap controllers are gamepads)
*/
DT_GAMEPAD = 1,
/**
* Mouse
*/
DT_MOUSE = 2,
/**
* Lightgun
*/
DT_LIGHTGUN = 3,
};
/**
* Is not field terminator.
*
@ -212,14 +145,6 @@ inline short unserialize_short(const unsigned char* buf)
*/
struct porttype_info
{
/**
* Look up information about port type.
*
* Parameter p: The port type.
* Returns: Infor about port type.
* Throws std::runtime_error: Invalid port type.
*/
static const porttype_info& lookup(porttype_t p) throw(std::runtime_error);
/**
* Look up information about port type.
*
@ -227,16 +152,28 @@ struct porttype_info
* Returns: Infor about port type.
* Throws std::runtime_error: Invalid port type.
*/
static const porttype_info& lookup(const std::string& p) throw(std::runtime_error);
static porttype_info& lookup(const std::string& p) throw(std::runtime_error);
/**
* Get set of all available port types.
*/
static std::set<porttype_info*> get_all();
/**
* Get some default port type.
*/
static porttype_info& default_type();
/**
* Get port default type.
*/
static porttype_info& port_default(unsigned port);
/**
* Register port type.
*
* Parameter ptype: Type value for port type.
* Parameter pname: The name of port type.
* Parameter hname: Human-readable name of the port type.
* Parameter psize: The size of storage for this type.
* Throws std::bad_alloc: Not enough memory.
*/
porttype_info(porttype_t ptype, const std::string& pname, size_t psize) throw(std::bad_alloc);
porttype_info(const std::string& pname, const std::string& hname, size_t psize) throw(std::bad_alloc);
/**
* Unregister port type.
*/
@ -289,12 +226,22 @@ struct porttype_info
*/
size_t (*deserialize)(unsigned char* buffer, const char* textbuf);
/**
* Return device type for given index.
* Get device flags for given index.
*
* Parameter idx: The index of controller.
* Returns: The type of device.
* Returns: The device flags.
* Bit 0: Present.
* Bit 1: Has absolute analog axes 0 and 1.
* Bit 2: Has relative analog axes 0 and 1.
*/
devicetype_t (*devicetype)(unsigned idx);
unsigned (*deviceflags)(unsigned idx);
/**
* Is the device legal for port?
*
* Parameter port: Port to query.
* Returns: Nonzero if legal, zero if illegal.
*/
int (*legal)(unsigned port);
/**
* Number of controllers connected to this port.
*/
@ -313,6 +260,12 @@ struct porttype_info
* Parameter port: Port to set to.
*/
void (*set_core_controller)(unsigned port);
/**
* Does the controller exist?
*
* Parameter controller: Controller number.
*/
bool is_present(unsigned controller) const throw();
/**
* Does the controller have analog function?
*
@ -326,9 +279,9 @@ struct porttype_info
*/
bool is_mouse(unsigned controller) const throw();
/**
* Port type value.
* Human-readable name.
*/
porttype_t value;
std::string hname;
/**
* Number of bytes it takes to store this.
*/
@ -337,6 +290,10 @@ struct porttype_info
* Name of port type.
*/
std::string name;
/**
* Name of controller.
*/
std::string ctrlname;
private:
porttype_info(const porttype_info&);
porttype_info& operator=(const porttype_info&);
@ -477,7 +434,7 @@ public:
*
* Throws std::runtime_error: Invalid port type.
*/
controller_frame(porttype_t p1, porttype_t p2) throw(std::runtime_error);
controller_frame(porttype_info& p1, porttype_info& p2) throw(std::runtime_error);
/**
* Create subframe of controls with specified controller types and specified memory.
*
@ -487,7 +444,7 @@ public:
*
* Throws std::runtime_error: Invalid port type or NULL memory.
*/
controller_frame(unsigned char* memory, porttype_t p1 = PT_GAMEPAD, porttype_t p2 = PT_NONE)
controller_frame(unsigned char* memory, porttype_info& p1, porttype_info& p2)
throw(std::runtime_error);
/**
* Copy construct a frame. The memory will be dedicated.
@ -509,9 +466,9 @@ public:
* Parameter port: Number of port.
* Returns: The type of port.
*/
porttype_t get_port_type(unsigned port) throw()
porttype_info& get_port_type(unsigned port) throw()
{
return (port < MAX_PORTS) ? types[port] : PT_NONE;
return (port < MAX_PORTS) ? *types[port] : porttype_info::default_type();
}
/**
* Get blank dedicated frame of same port types.
@ -520,7 +477,7 @@ public:
*/
controller_frame blank_frame() throw()
{
return controller_frame(types[0], types[1]);
return controller_frame(*types[0], *types[1]);
}
/**
* Set type of port. Input for that port is zeroized.
@ -529,7 +486,7 @@ public:
* Parameter type: The new type.
* Throws std::runtime_error: Bad port type or non-dedicated memory.
*/
void set_port_type(unsigned port, porttype_t ptype) throw(std::runtime_error);
void set_port_type(unsigned port, porttype_info& ptype) throw(std::runtime_error);
/**
* Check that types match.
*
@ -654,7 +611,7 @@ public:
void axis(unsigned pcid, unsigned ctrl, short x) throw()
{
unsigned port = (pcid / MAX_CONTROLLERS_PER_PORT) % MAX_PORTS;
pinfo[port]->write(backing + offsets[port], pcid % MAX_CONTROLLERS_PER_PORT, ctrl, x);
types[port]->write(backing + offsets[port], pcid % MAX_CONTROLLERS_PER_PORT, ctrl, x);
}
/**
* Set axis/button value.
@ -676,7 +633,7 @@ public:
short axis(unsigned pcid, unsigned ctrl) throw()
{
unsigned port = (pcid / MAX_CONTROLLERS_PER_PORT) % MAX_PORTS;
return pinfo[port]->read(backing + offsets[port], pcid % MAX_CONTROLLERS_PER_PORT, ctrl);
return types[port]->read(backing + offsets[port], pcid % MAX_CONTROLLERS_PER_PORT, ctrl);
}
/**
@ -698,18 +655,18 @@ public:
void display(unsigned pcid, char* buf) throw()
{
unsigned port = (pcid / MAX_CONTROLLERS_PER_PORT) % MAX_PORTS;
return pinfo[port]->display(backing + offsets[port], pcid % MAX_CONTROLLERS_PER_PORT, buf);
return types[port]->display(backing + offsets[port], pcid % MAX_CONTROLLERS_PER_PORT, buf);
}
/**
* Get device type.
* Is device present?
*
* Parameter pcid: Physical controller id.
* Returns: Device type.
* Returns: True if present, false if not.
*/
devicetype_t devicetype(unsigned pcid) throw()
bool is_present(unsigned pcid) throw()
{
unsigned port = (pcid / MAX_CONTROLLERS_PER_PORT) % MAX_PORTS;
return pinfo[port]->devicetype(pcid % MAX_CONTROLLERS_PER_PORT);
return types[port]->is_present(pcid % MAX_CONTROLLERS_PER_PORT);
}
/**
* Deserialize frame from text format.
@ -724,7 +681,7 @@ public:
if(buf[offset] == '|')
offset++;
for(size_t i = 0; i < MAX_PORTS; i++) {
size_t s = pinfo[i]->deserialize(backing + offsets[i], buf + offset);
size_t s = types[i]->deserialize(backing + offsets[i], buf + offset);
if(s != DESERIALIZE_SPECIAL_BLANK) {
offset += s;
if(buf[offset] == '|')
@ -742,7 +699,7 @@ public:
size_t offset = 0;
offset += system_serialize(backing, buf);
for(size_t i = 0; i < MAX_PORTS; i++)
offset += pinfo[i]->serialize(backing + offsets[i], buf + offset);
offset += types[i]->serialize(backing + offsets[i], buf + offset);
buf[offset++] = '\0';
}
/**
@ -789,7 +746,7 @@ public:
int button_id(unsigned pcid, unsigned lbid)
{
unsigned port = (pcid / MAX_CONTROLLERS_PER_PORT) % MAX_PORTS;
return pinfo[port]->button_id(pcid % MAX_CONTROLLERS_PER_PORT, lbid);
return types[port]->button_id(pcid % MAX_CONTROLLERS_PER_PORT, lbid);
}
/**
* Does the specified controller have analog function.
@ -799,7 +756,7 @@ public:
bool is_analog(unsigned pcid)
{
unsigned port = (pcid / MAX_CONTROLLERS_PER_PORT) % MAX_PORTS;
return pinfo[port]->is_analog(pcid % MAX_CONTROLLERS_PER_PORT);
return types[port]->is_analog(pcid % MAX_CONTROLLERS_PER_PORT);
}
/**
* Does the specified controller have mouse-type function.
@ -809,18 +766,17 @@ public:
bool is_mouse(unsigned pcid)
{
unsigned port = (pcid / MAX_CONTROLLERS_PER_PORT) % MAX_PORTS;
return pinfo[port]->is_mouse(pcid % MAX_CONTROLLERS_PER_PORT);
return types[port]->is_mouse(pcid % MAX_CONTROLLERS_PER_PORT);
}
private:
size_t totalsize;
unsigned char memory[MAXIMUM_CONTROLLER_FRAME_SIZE];
unsigned char* backing;
porttype_t types[MAX_PORTS];
porttype_info* types[MAX_PORTS];
size_t offsets[MAX_PORTS];
const porttype_info* pinfo[MAX_PORTS];
static size_t system_serialize(const unsigned char* buffer, char* textbuf);
static size_t system_deserialize(unsigned char* buffer, const char* textbuf);
void set_types(const porttype_t* tarr);
void set_types(porttype_info** tarr);
};
/**
@ -829,6 +785,10 @@ private:
class controller_frame_vector
{
public:
/**
* Construct new controller frame vector.
*/
controller_frame_vector() throw(std::runtime_error);
/**
* Construct new controller frame vector.
*
@ -836,8 +796,7 @@ public:
* Parameter p2: Type of port 2.
* Throws std::runtime_error: Illegal port types.
*/
controller_frame_vector(enum porttype_t p1 = PT_INVALID, enum porttype_t p2 = PT_INVALID)
throw(std::runtime_error);
controller_frame_vector(porttype_info& p1, porttype_info& p2) throw(std::runtime_error);
/**
* Destroy controller frame vector
*/
@ -864,13 +823,13 @@ public:
* Parameter p2: Type of port 2.
* Throws std::runtime_error: Illegal port types.
*/
void clear(enum porttype_t p1, enum porttype_t p2) throw(std::runtime_error);
void clear(porttype_info& p1, porttype_info& p2) throw(std::runtime_error);
/**
* Blank vector.
*/
void clear() throw()
{
clear(types[0], types[1]);
clear(*types[0], *types[1]);
}
/**
* Get number of subframes.
@ -896,7 +855,7 @@ public:
cache_page = &pages[page];
cache_page_num = page;
}
return controller_frame(cache_page->content + pageoffset, types[0], types[1]);
return controller_frame(cache_page->content + pageoffset, *types[0], *types[1]);
}
/**
* Append a subframe.
@ -957,7 +916,7 @@ public:
*/
controller_frame blank_frame(bool sync)
{
controller_frame c(types[0], types[1]);
controller_frame c(*types[0], *types[1]);
c.sync(sync);
return c;
}
@ -971,7 +930,7 @@ private:
size_t frames_per_page;
size_t frame_size;
size_t frames;
porttype_t types[MAX_PORTS];
porttype_info* types[MAX_PORTS];
size_t cache_page_num;
page* cache_page;
std::map<size_t, page> pages;
@ -1016,12 +975,12 @@ public:
*/
bool acid_is_mouse(unsigned acid) throw();
/**
* Look up device type type of given pcid.
* Is given pcid present?
*
* Parameter pcid: The physical controller id.
* Returns: The type of device.
* Returns: True if present, false if not.
*/
devicetype_t pcid_to_type(unsigned pcid) throw();
bool pcid_present(unsigned pcid) throw();
/**
* Set type of port.
*
@ -1030,7 +989,7 @@ public:
* Parameter set_core: If true, set the core port type too, otherwise don't do that.
* Throws std::runtime_error: Illegal port type.
*/
void set_port(unsigned port, porttype_t ptype, bool set_core) throw(std::runtime_error);
void set_port(unsigned port, porttype_info& ptype, bool set_core) throw(std::runtime_error);
/**
* Get status of current controls (with autohold/autofire factored in).
*
@ -1142,6 +1101,10 @@ public:
* Returns: The physical button id, or -1 if no such button.
*/
int button_id(unsigned pcid, unsigned lbid) throw();
/**
* TODO: Document.
*/
bool is_present(unsigned pcid) throw();
/**
* TODO: Document.
*/
@ -1151,8 +1114,7 @@ public:
*/
bool is_mouse(unsigned pcid) throw();
private:
const porttype_info* porttypeinfo[MAX_PORTS];
porttype_t porttypes[MAX_PORTS];
porttype_info* porttypes[MAX_PORTS];
int analog_indices[MAX_ANALOG];
bool analog_mouse[MAX_ANALOG];
controller_frame _input;
@ -1284,7 +1246,7 @@ inline size_t generic_port_deserialize(unsigned char* buffer, const char* textbu
}
template<unsigned mask>
inline bool generic_port_legal(unsigned port) throw()
inline int generic_port_legal(unsigned port) throw()
{
if(port >= CHAR_BIT * sizeof(unsigned))
port = CHAR_BIT * sizeof(unsigned) - 1;
@ -1294,10 +1256,10 @@ inline bool generic_port_legal(unsigned port) throw()
/**
* Generic port type function.
*/
template<unsigned controllers, devicetype_t dtype>
inline devicetype_t generic_port_devicetype(unsigned idx) throw()
template<unsigned controllers, unsigned flags>
inline unsigned generic_port_deviceflags(unsigned idx) throw()
{
return (idx < controllers) ? dtype : DT_NONE;
return (idx < controllers) ? flags : 0;
}
#endif

View file

@ -41,6 +41,8 @@ uint32_t get_snes_cpu_rate();
uint32_t get_snes_apu_rate();
//Get the core identifier.
std::string get_core_identifier();
//Get the default controller type for specified port.
std::string get_core_default_port(unsigned port);
//Do basic core initialization (to get it to stable state).
void do_basic_core_init();
//Get set of SRAMs.

View file

@ -51,11 +51,11 @@ struct moviefile
/**
* What's in port #1?
*/
porttype_t port1;
porttype_info* port1;
/**
* What's in port #2?
*/
porttype_t port2;
porttype_info* port2;
/**
* Emulator Core version string.
*/

View file

@ -251,6 +251,14 @@ void core_install_handler()
SNES::system.init();
}
std::string get_core_default_port(unsigned port)
{
if(port == 0)
return "gamepad";
else
return "none";
}
void core_uninstall_handler()
{
SNES::interface = old;

View file

@ -25,14 +25,16 @@ namespace
struct porttype_invalid : public porttype_info
{
porttype_invalid() : porttype_info(PT_INVALID, "invalid-port-type", 0)
porttype_invalid() : porttype_info("invalid-port-type", "invalid-port-type", 0)
{
write = NULL;
read = NULL;
display = NULL;
serialize = NULL;
deserialize = NULL;
devicetype = generic_port_devicetype<0, DT_NONE>;
legal = NULL;
deviceflags = generic_port_deviceflags<0, 0>;
ctrlname = "";
controllers = 0;
set_core_controller = set_core_controller_illegal;
}
@ -45,14 +47,16 @@ namespace
struct porttype_gamepad : public porttype_info
{
porttype_gamepad() : porttype_info(PT_GAMEPAD, "gamepad", generic_port_size<1, 0, 12>())
porttype_gamepad() : porttype_info("gamepad", "Gamepad", generic_port_size<1, 0, 12>())
{
write = generic_port_write<1, 0, 12>;
read = generic_port_read<1, 0, 12>;
display = generic_port_display<1, 0, 12, 0>;
serialize = generic_port_serialize<1, 0, 12, 0>;
deserialize = generic_port_deserialize<1, 0, 12>;
devicetype = generic_port_devicetype<1, DT_GAMEPAD>;
legal = generic_port_legal<3>;
deviceflags = generic_port_deviceflags<1, 1>;
ctrlname = "gamepad";
controllers = 1;
set_core_controller = set_core_controller_gamepad;
}
@ -65,14 +69,16 @@ namespace
struct porttype_justifier : public porttype_info
{
porttype_justifier() : porttype_info(PT_JUSTIFIER, "justifier", generic_port_size<1, 2, 2>())
porttype_justifier() : porttype_info("justifier", "Justifier", generic_port_size<1, 2, 2>())
{
write = generic_port_write<1, 2, 2>;
read = generic_port_read<1, 2, 2>;
display = generic_port_display<1, 2, 2, 12>;
serialize = generic_port_serialize<1, 2, 2, 12>;
deserialize = generic_port_deserialize<1, 2, 2>;
devicetype = generic_port_devicetype<1, DT_LIGHTGUN>;
legal = generic_port_legal<2>;
deviceflags = generic_port_deviceflags<1, 3>;
ctrlname = "justifier";
controllers = 1;
set_core_controller = set_core_controller_justifier;
}
@ -85,14 +91,16 @@ namespace
struct porttype_justifiers : public porttype_info
{
porttype_justifiers() : porttype_info(PT_JUSTIFIERS, "justifiers", generic_port_size<2, 2, 2>())
porttype_justifiers() : porttype_info("justifiers", "2 Justifiers", generic_port_size<2, 2, 2>())
{
write = generic_port_write<2, 2, 2>;
read = generic_port_read<2, 2, 2>;
display = generic_port_display<2, 2, 2, 0>;
serialize = generic_port_serialize<2, 2, 2, 12>;
deserialize = generic_port_deserialize<2, 2, 2>;
devicetype = generic_port_devicetype<2, DT_LIGHTGUN>;
legal = generic_port_legal<2>;
deviceflags = generic_port_deviceflags<2, 3>;
ctrlname = "justifier";
controllers = 2;
set_core_controller = set_core_controller_justifiers;
}
@ -105,14 +113,16 @@ namespace
struct porttype_mouse : public porttype_info
{
porttype_mouse() : porttype_info(PT_MOUSE, "mouse", generic_port_size<1, 2, 2>())
porttype_mouse() : porttype_info("mouse", "Mouse", generic_port_size<1, 2, 2>())
{
write = generic_port_write<1, 2, 2>;
read = generic_port_read<1, 2, 2>;
display = generic_port_display<1, 2, 2, 0>;
serialize = generic_port_serialize<1, 2, 2, 12>;
deserialize = generic_port_deserialize<1, 2, 2>;
devicetype = generic_port_devicetype<1, DT_MOUSE>;
legal = generic_port_legal<3>;
deviceflags = generic_port_deviceflags<1, 5>;
ctrlname = "mouse";
controllers = 1;
set_core_controller = set_core_controller_mouse;
}
@ -125,14 +135,16 @@ namespace
struct porttype_multitap : public porttype_info
{
porttype_multitap() : porttype_info(PT_MULTITAP, "multitap", generic_port_size<4, 0, 12>())
porttype_multitap() : porttype_info("multitap", "Multitap", generic_port_size<4, 0, 12>())
{
write = generic_port_write<4, 0, 12>;
read = generic_port_read<4, 0, 12>;
display = generic_port_display<4, 0, 12, 0>;
serialize = generic_port_serialize<4, 0, 12, 0>;
deserialize = generic_port_deserialize<4, 0, 12>;
devicetype = generic_port_devicetype<4, DT_GAMEPAD>;
legal = generic_port_legal<3>;
deviceflags = generic_port_deviceflags<4, 1>;
ctrlname = "multitap";
controllers = 4;
set_core_controller = set_core_controller_multitap;
}
@ -145,14 +157,16 @@ namespace
struct porttype_none : public porttype_info
{
porttype_none() : porttype_info(PT_NONE, "none", generic_port_size<0, 0, 0>())
porttype_none() : porttype_info("none", "None", generic_port_size<0, 0, 0>())
{
write = generic_port_write<0, 0, 0>;
read = generic_port_read<0, 0, 0>;
display = generic_port_display<0, 0, 0, 0>;
serialize = generic_port_serialize<0, 0, 0, 0>;
deserialize = generic_port_deserialize<0, 0, 0>;
devicetype = generic_port_devicetype<0, DT_GAMEPAD>;
legal = generic_port_legal<3>;
deviceflags = generic_port_deviceflags<0, 0>;
ctrlname = "";
controllers = 0;
set_core_controller = set_core_controller_none;
}
@ -165,14 +179,15 @@ namespace
struct porttype_superscope : public porttype_info
{
porttype_superscope() : porttype_info(PT_SUPERSCOPE, "superscope", generic_port_size<1, 2, 4>())
porttype_superscope() : porttype_info("superscope", "Super Scope", generic_port_size<1, 2, 4>())
{
write = generic_port_write<1, 2, 4>;
read = generic_port_read<1, 2, 4>;
display = generic_port_display<1, 2, 4, 0>;
serialize = generic_port_serialize<1, 2, 4, 14>;
deserialize = generic_port_deserialize<1, 2, 4>;
devicetype = generic_port_devicetype<1, DT_LIGHTGUN>;
legal = generic_port_legal<2>;
ctrlname = "superscope";
controllers = 1;
set_core_controller = set_core_controller_superscope;
}
@ -190,22 +205,18 @@ namespace
}
}
const porttype_info& porttype_info::lookup(porttype_t p) throw(std::runtime_error)
porttype_info& porttype_info::lookup(const std::string& p) throw(std::runtime_error)
{
get_invalid_port_type();
for(auto i : porttypes())
if(p == i->value)
if(p == i->name && i->legal)
return *i;
throw std::runtime_error("Bad port type");
}
const porttype_info& porttype_info::lookup(const std::string& p) throw(std::runtime_error)
porttype_info& porttype_info::port_default(unsigned port)
{
get_invalid_port_type();
for(auto i : porttypes())
if(p == i->name && i->value != PT_INVALID)
return *i;
throw std::runtime_error("Bad port type");
return lookup(get_core_default_port(port));
}
porttype_info::~porttype_info() throw()
@ -213,23 +224,43 @@ porttype_info::~porttype_info() throw()
porttypes().erase(this);
}
porttype_info::porttype_info(porttype_t ptype, const std::string& pname, size_t psize) throw(std::bad_alloc)
porttype_info::porttype_info(const std::string& pname, const std::string& _hname, size_t psize) throw(std::bad_alloc)
{
value = ptype;
name = pname;
hname = _hname;
storage_size = psize;
porttypes().insert(this);
}
porttype_info& porttype_info::default_type()
{
return get_invalid_port_type();
}
std::set<porttype_info*> porttype_info::get_all()
{
std::set<porttype_info*> p;
for(auto i : porttypes())
if(i->legal)
p.insert(i);
return p;
}
bool porttype_info::is_present(unsigned controller) const throw()
{
unsigned d = deviceflags(controller);
return ((d & 1) != 0);
}
bool porttype_info::is_analog(unsigned controller) const throw()
{
devicetype_t d = devicetype(controller);
return (d == DT_MOUSE || d == DT_LIGHTGUN);
unsigned d = deviceflags(controller);
return ((d & 1) != 0) && ((d & 6) != 0);
}
bool porttype_info::is_mouse(unsigned controller) const throw()
{
return (devicetype(controller) == DT_MOUSE);
return ((deviceflags(controller) & 5) == 5);
}
pollcounter_vector::pollcounter_vector() throw()
@ -327,23 +358,23 @@ bool pollcounter_vector::check(const std::vector<uint32_t>& mem) throw()
}
controller_frame::controller_frame(porttype_t p1, porttype_t p2) throw(std::runtime_error)
controller_frame::controller_frame(porttype_info& p1, porttype_info& p2) throw(std::runtime_error)
{
memset(memory, 0, sizeof(memory));
backing = memory;
types[0] = p1;
types[1] = p2;
types[0] = &p1;
types[1] = &p2;
set_types(types);
}
controller_frame::controller_frame(unsigned char* mem, porttype_t p1, porttype_t p2) throw(std::runtime_error)
controller_frame::controller_frame(unsigned char* mem, porttype_info& p1, porttype_info& p2) throw(std::runtime_error)
{
if(!mem)
throw std::runtime_error("NULL backing memory not allowed");
memset(memory, 0, sizeof(memory));
backing = mem;
types[0] = p1;
types[1] = p2;
types[0] = &p1;
types[1] = &p2;
set_types(types);
}
@ -351,17 +382,17 @@ controller_frame::controller_frame(const controller_frame& obj) throw()
{
memset(memory, 0, sizeof(memory));
backing = memory;
set_types(obj.types);
set_types(const_cast<porttype_info**>(obj.types));
memcpy(backing, obj.backing, totalsize);
}
controller_frame& controller_frame::operator=(const controller_frame& obj) throw(std::runtime_error)
{
set_types(obj.types);
set_types(const_cast<porttype_info**>(obj.types));
memcpy(backing, obj.backing, totalsize);
}
void controller_frame::set_types(const porttype_t* tarr)
void controller_frame::set_types(porttype_info** tarr)
{
for(unsigned i = 0; i < MAX_PORTS; i++) {
if(memory != backing && types[i] != tarr[i])
@ -371,8 +402,7 @@ void controller_frame::set_types(const porttype_t* tarr)
for(unsigned i = 0; i < MAX_PORTS; i++) {
offsets[i] = offset;
types[i] = tarr[i];
pinfo[i] = &porttype_info::lookup(tarr[i]);
offset += pinfo[i]->storage_size;
offset += types[i]->storage_size;
}
totalsize = offset;
}
@ -432,14 +462,14 @@ size_t controller_frame_vector::count_frames() throw()
return ret;
}
void controller_frame_vector::clear(enum porttype_t p1, enum porttype_t p2) throw(std::runtime_error)
void controller_frame_vector::clear(porttype_info& p1, porttype_info& p2) throw(std::runtime_error)
{
controller_frame check(p1, p2);
frame_size = check.size();
frames_per_page = CONTROLLER_PAGE_SIZE / frame_size;
frames = 0;
types[0] = p1;
types[1] = p2;
types[0] = &p1;
types[1] = &p2;
clear_cache();
pages.clear();
}
@ -450,14 +480,19 @@ controller_frame_vector::~controller_frame_vector() throw()
cache_page = NULL;
}
controller_frame_vector::controller_frame_vector(enum porttype_t p1, enum porttype_t p2) throw(std::runtime_error)
controller_frame_vector::controller_frame_vector() throw(std::runtime_error)
{
clear(porttype_info::default_type(), porttype_info::default_type());
}
controller_frame_vector::controller_frame_vector(porttype_info& p1, porttype_info& p2) throw(std::runtime_error)
{
clear(p1, p2);
}
void controller_frame_vector::append(controller_frame frame) throw(std::bad_alloc, std::runtime_error)
{
controller_frame check(types[0], types[1]);
controller_frame check(*types[0], *types[1]);
if(!check.types_match(frame))
throw std::runtime_error("controller_frame_vector::append: Type mismatch");
if(frames % frames_per_page == 0) {
@ -471,13 +506,13 @@ void controller_frame_vector::append(controller_frame frame) throw(std::bad_allo
cache_page_num = page;
cache_page = &pages[page];
}
controller_frame(cache_page->content + offset, types[0], types[1]) = frame;
controller_frame(cache_page->content + offset, *types[0], *types[1]) = frame;
frames++;
}
controller_frame_vector::controller_frame_vector(const controller_frame_vector& vector) throw(std::bad_alloc)
{
clear(vector.types[0], vector.types[1]);
clear(*vector.types[0], *vector.types[1]);
*this = vector;
}
@ -609,27 +644,26 @@ controller_frame::controller_frame() throw()
backing = memory;
for(unsigned i = 0; i < MAX_PORTS; i++) {
offsets[i] = SYSTEM_BYTES;
types[i] = PT_INVALID;
pinfo[i] = NULL;
types[i] = &porttype_info::default_type();
}
totalsize = SYSTEM_BYTES;
}
void controller_frame::set_port_type(unsigned port, porttype_t ptype) throw(std::runtime_error)
void controller_frame::set_port_type(unsigned port, porttype_info& ptype) throw(std::runtime_error)
{
char tmp[MAXIMUM_CONTROLLER_FRAME_SIZE] = {0};
if(memory != backing)
throw std::runtime_error("Can't set port type on non-dedicated controller frame");
if(port >= MAX_PORTS)
return;
const porttype_info* newpinfo[MAX_PORTS];
porttype_info* newpinfo[MAX_PORTS];
size_t newoffsets[MAX_PORTS];
size_t offset = SYSTEM_BYTES;
for(size_t i = 0; i < MAX_PORTS; i++) {
if(i != port)
newpinfo[i] = pinfo[i];
newpinfo[i] = types[i];
else
newpinfo[i] = &porttype_info::lookup(ptype);
newpinfo[i] = &ptype;
newoffsets[i] = offset;
if(newpinfo[i])
offset += newpinfo[i]->storage_size;
@ -637,8 +671,7 @@ void controller_frame::set_port_type(unsigned port, porttype_t ptype) throw(std:
memcpy(tmp + newoffsets[i], backing + offsets[i], newpinfo[i]->storage_size);
}
memcpy(memory, tmp, MAXIMUM_CONTROLLER_FRAME_SIZE);
types[port] = ptype;
pinfo[port] = newpinfo[port];
types[port] = &ptype;
for(size_t i = 0; i < MAX_PORTS; i++)
offsets[i] = newoffsets[i];
totalsize = offset;
@ -651,17 +684,16 @@ controller_state::controller_state() throw()
analog_mouse[i] = false;
}
for(size_t i = 0; i < MAX_PORTS; i++) {
porttypes[i] = PT_INVALID;
porttypeinfo[i] = NULL;
porttypes[i] = &porttype_info::default_type();
}
}
int controller_state::lcid_to_pcid(unsigned lcid) throw()
{
if(!porttypeinfo[0] || !porttypeinfo[1])
if(!porttypes[0] || !porttypes[1])
return -1;
unsigned p1devs = porttypeinfo[0]->controllers;
unsigned p2devs = porttypeinfo[1]->controllers;
unsigned p1devs = porttypes[0]->controllers;
unsigned p2devs = porttypes[1]->controllers;
if(lcid >= p1devs + p2devs)
return -1;
//Exceptional: If p1 is none, map all to p2.
@ -693,14 +725,6 @@ bool controller_state::acid_is_mouse(unsigned acid) throw()
}
devicetype_t controller_state::pcid_to_type(unsigned pcid) throw()
{
size_t port = pcid / MAX_CONTROLLERS_PER_PORT;
if(port >= MAX_PORTS)
return DT_NONE;
return porttypeinfo[port]->devicetype(pcid % MAX_CONTROLLERS_PER_PORT);
}
controller_frame controller_state::get(uint64_t framenum) throw()
{
if(_autofire.size())
@ -776,18 +800,18 @@ int controller_state::button_id(unsigned pcid, unsigned lbid) throw()
size_t port = pcid / MAX_CONTROLLERS_PER_PORT;
if(port >= MAX_PORTS)
return -1;
return porttypeinfo[port]->button_id(pcid % MAX_CONTROLLERS_PER_PORT, lbid);
return porttypes[port]->button_id(pcid % MAX_CONTROLLERS_PER_PORT, lbid);
}
void controller_state::set_port(unsigned port, porttype_t ptype, bool set_core) throw(std::runtime_error)
void controller_state::set_port(unsigned port, porttype_info& ptype, bool set_core) throw(std::runtime_error)
{
if(port >= MAX_PORTS)
throw std::runtime_error("Port number invalid");
const porttype_info* info = &porttype_info::lookup(ptype);
porttype_info* info = &ptype;
if(set_core)
info->set_core_controller(port);
porttype_t oldtype = porttypes[port];
if(oldtype != ptype) {
porttype_info* oldtype = porttypes[port];
if(oldtype != &ptype) {
_input.set_port_type(port, ptype);
_autohold.set_port_type(port, ptype);
_committed.set_port_type(port, ptype);
@ -795,27 +819,19 @@ void controller_state::set_port(unsigned port, porttype_t ptype, bool set_core)
//The old autofire pattern no longer applies.
_autofire.clear();
}
porttypes[port] = ptype;
porttypeinfo[port] = info;
porttypes[port] = &ptype;
int i = 0;
for(unsigned j = 0; j < MAX_ANALOG; j++)
analog_indices[j] = -1;
for(unsigned j = 0; j < MAX_PORTS * MAX_CONTROLLERS_PER_PORT; j++) {
if(!porttypeinfo[j / MAX_CONTROLLERS_PER_PORT])
if(!porttypes[j / MAX_CONTROLLERS_PER_PORT])
continue;
devicetype_t d = porttypeinfo[j / MAX_CONTROLLERS_PER_PORT]->devicetype(j % MAX_CONTROLLERS_PER_PORT);
switch(d) {
case DT_NONE:
case DT_GAMEPAD:
break;
case DT_MOUSE:
if(porttypes[j / MAX_CONTROLLERS_PER_PORT]->is_mouse(j % MAX_CONTROLLERS_PER_PORT)) {
analog_mouse[i] = true;
analog_indices[i++] = j;
break;
case DT_LIGHTGUN:
} else if(porttypes[j / MAX_CONTROLLERS_PER_PORT]->is_analog(j % MAX_CONTROLLERS_PER_PORT)) {
analog_mouse[i] = false;
analog_indices[i++] = j;
break;
}
if(i == MAX_ANALOG)
break;
@ -846,6 +862,11 @@ controller_frame controller_state::commit(controller_frame controls) throw()
return _committed;
}
bool controller_state::is_present(unsigned pcid) throw()
{
return _input.is_present(pcid);
}
bool controller_state::is_analog(unsigned pcid) throw()
{
return _input.is_analog(pcid);

View file

@ -250,16 +250,13 @@ void update_movie_state()
c = movb.get_movie().get_controls();
else
c = controls.get_committed();
for(unsigned i = 0; i < 8; i++) {
for(unsigned i = 0; i < MAX_LOGICAL_CONTROLLERS; i++) {
unsigned pindex = controls.lcid_to_pcid(i);
devicetype_t dtype = controls.pcid_to_type(pindex);
if(dtype == DT_NONE)
if(!controls.is_present(pindex))
continue;
char buffer[MAX_DISPLAY_LENGTH];
c.display(pindex, buffer);
char y[3] = {'P', 0, 0};
y[1] = 49 + i;
_status.set(y, buffer);
_status.set((stringfmt() << "P" << (i + 1)).str(), buffer);
}
}

View file

@ -361,13 +361,13 @@ void do_load_state(struct moviefile& _movie, int lmode)
if(will_load_state) {
//Load the savestate and movie state.
//Set the core ports in order to avoid port state being reinitialized when loading.
controls.set_port(0, _movie.port1, true);
controls.set_port(1, _movie.port2, true);
controls.set_port(0, *_movie.port1, true);
controls.set_port(1, *_movie.port2, true);
load_core_state(_movie.savestate);
} else {
load_sram(_movie.movie_sram);
controls.set_port(0, _movie.port1, true);
controls.set_port(1, _movie.port2, true);
controls.set_port(0, *_movie.port1, true);
controls.set_port(1, *_movie.port2, true);
_movie.rtc_second = _movie.movie_rtc_second;
_movie.rtc_subsecond = _movie.movie_rtc_subsecond;
}

View file

@ -195,7 +195,7 @@ void write_authors_file(zip_writer& w, std::vector<std::pair<std::string, std::s
}
}
void write_input(zip_writer& w, controller_frame_vector& input, porttype_t port1, porttype_t port2)
void write_input(zip_writer& w, controller_frame_vector& input)
throw(std::bad_alloc, std::runtime_error)
{
std::ostream& m = w.create_file("input");
@ -214,8 +214,8 @@ void write_input(zip_writer& w, controller_frame_vector& input, porttype_t port1
}
}
void read_input(zip_reader& r, controller_frame_vector& input, porttype_t port1, porttype_t port2, unsigned version)
throw(std::bad_alloc, std::runtime_error)
void read_input(zip_reader& r, controller_frame_vector& input, unsigned version) throw(std::bad_alloc,
std::runtime_error)
{
controller_frame tmp = input.blank_frame(false);
std::istream& m = r["input"];
@ -280,13 +280,15 @@ void write_pollcounters(zip_writer& w, const std::string& file, const std::vecto
}
}
porttype_t parse_controller_type(const std::string& type, bool port) throw(std::bad_alloc, std::runtime_error)
porttype_info& parse_controller_type(const std::string& type, unsigned port) throw(std::bad_alloc, std::runtime_error)
{
try {
const porttype_info& i = porttype_info::lookup(type);
return i.value;
porttype_info& i = porttype_info::lookup(type);
if(!i.legal || !(i.legal(port)))
throw 42;
return i;
} catch(...) {
throw std::runtime_error(std::string("Illegal port") + (port ? "2" : "1") + " device '" + type + "'");
(stringfmt() << "Illegal port " << (port + 1) << " device '" << type << "'").throwex();
}
}
@ -295,8 +297,8 @@ moviefile::moviefile() throw(std::bad_alloc)
{
force_corrupt = false;
gametype = GT_INVALID;
port1 = PT_INVALID;
port2 = PT_INVALID;
port1 = &porttype_info::default_type();
port2 = &porttype_info::default_type();
coreversion = "";
projectid = "";
rerecords = "0";
@ -327,13 +329,13 @@ moviefile::moviefile(const std::string& movie) throw(std::bad_alloc, std::runtim
} catch(std::exception& e) {
throw std::runtime_error("Illegal game type '" + tmp + "'");
}
tmp = "gamepad";
tmp = porttype_info::port_default(0).name;
read_linefile(r, "port1", tmp, true);
port1 = porttype_info::lookup(tmp).value;
tmp = "none";
port1 = &porttype_info::lookup(tmp);
tmp = porttype_info::port_default(1).name;
read_linefile(r, "port2", tmp, true);
port2 = porttype_info::lookup(tmp).value;
input.clear(port1, port2);
port2 = &porttype_info::lookup(tmp);
input.clear(*port1, *port2);
read_linefile(r, "gamename", gamename, true);
read_linefile(r, "projectid", projectid);
rerecords = read_rrdata(r, c_rrdata);
@ -380,17 +382,17 @@ moviefile::moviefile(const std::string& movie) throw(std::bad_alloc, std::runtim
if(name.length() >= 10 && name.substr(0, 10) == "moviesram.")
movie_sram[name.substr(10)] = read_raw_file(r, name);
read_authors_file(r, authors);
read_input(r, input, port1, port2, 0);
read_input(r, input, 0);
}
void moviefile::save(const std::string& movie, unsigned compression) throw(std::bad_alloc, std::runtime_error)
{
zip_writer w(movie, compression);
write_linefile(w, "gametype", gtype::tostring(gametype));
if(port1 != PT_GAMEPAD)
write_linefile(w, "port1", porttype_info::lookup(port1).name);
if(port2 != PT_NONE)
write_linefile(w, "port2", porttype_info::lookup(port2).name);
if(port1->name != porttype_info::port_default(0).name)
write_linefile(w, "port1", port1->name);
if(port2->name != porttype_info::port_default(1).name)
write_linefile(w, "port2", port2->name);
write_linefile(w, "gamename", gamename, true);
write_linefile(w, "systemid", "lsnes-rr1");
write_linefile(w, "controlsversion", "0");
@ -422,7 +424,7 @@ void moviefile::save(const std::string& movie, unsigned compression) throw(std::
write_numeric_file(w, "savetime.subsecond", rtc_subsecond);
}
write_authors_file(w, authors);
write_input(w, input, port1, port2);
write_input(w, input);
w.commit();
}

View file

@ -331,8 +331,11 @@ void framebuffer<X>::copy_from(framebuffer_raw& scr, size_t hscale, size_t vscal
{
typename framebuffer<X>::element_t decbuf[DECBUF_SIZE];
if(!scr.fmt)
throw std::runtime_error("Source screen has invalid pixel format");
if(!scr.fmt) {
for(size_t y = 0; y < height; y++)
memset(rowptr(y), 0, sizeof(typename framebuffer<X>::element_t) * width);
return;
}
if(scr.fmt != current_fmt || active_rshift != auxpal.rshift || active_gshift != auxpal.gshift ||
active_bshift != auxpal.bshift) {
scr.fmt->set_palette(auxpal, active_rshift, active_gshift, active_bshift);

View file

@ -64,26 +64,13 @@ namespace
unsigned controller = get_numeric_argument<unsigned>(LS, 1, fname.c_str());
auto& m = get_movie();
controller_frame f = m.read_subframe(m.get_current_frame(), 0);
porttype_t p = f.get_port_type(controller / MAX_CONTROLLERS_PER_PORT);
const porttype_info& i = porttype_info::lookup(p);
if(i.controllers <= controller % MAX_CONTROLLERS_PER_PORT)
porttype_info& p = f.get_port_type(controller / MAX_CONTROLLERS_PER_PORT);
if(p.controllers <= controller % MAX_CONTROLLERS_PER_PORT)
lua_pushnil(LS);
else if(p == PT_NONE)
else if(p.ctrlname == "")
lua_pushnil(LS);
else if(p == PT_GAMEPAD)
lua_pushstring(LS, "gamepad");
else if(p == PT_MULTITAP)
lua_pushstring(LS, "gamepad");
else if(p == PT_MOUSE)
lua_pushstring(LS, "mouse");
else if(p == PT_SUPERSCOPE)
lua_pushstring(LS, "superscope");
else if(p == PT_JUSTIFIER)
lua_pushstring(LS, "justifier");
else if(p == PT_JUSTIFIERS)
lua_pushstring(LS, "justifier");
else
lua_pushstring(LS, "unknown");
lua_pushstring(LS, p.ctrlname.c_str());
return 1;
});

View file

@ -1,4 +1,5 @@
#include "core/misc.hpp"
#include "fonts/wrapper.hpp"
#include "platform/sdl/platform.hpp"
#include <cstdint>
@ -183,18 +184,25 @@ namespace
for(auto si : s) {
uint32_t old_x = pos_x;
uint32_t old_y = pos_y;
auto g = find_glyph(si, pos_x, pos_y, 0, pos_x, pos_y);
auto g = main_font.get_glyph(si);
if(si == 9)
pos_x = (pos_x + 63) / 64 * 64;
else if(si == 10) {
pos_x = 0;
pos_y += 16;
} else
pos_x += (g.wide ? 16 : 8);
uint32_t mw = maxwidth - old_x;
if(maxwidth < old_x)
mw = 0;
if(mw > g.first)
mw = g.first;
if(mw > (g.wide ? 16 : 8))
mw = (g.wide ? 16 : 8);
uint8_t* cbase = base + (y + old_y) * yo + (x + old_x) * xo;
if(g.second == NULL)
draw_blank_glyph(cbase, pitch, pbytes, g.first, mw, color,
if(g.data == NULL)
draw_blank_glyph(cbase, pitch, pbytes, (g.wide ? 16 : 8), mw, color,
(c == hilite_pos) ? hilite_mode : 0);
else
draw_glyph(cbase, pitch, pbytes, g.second, g.first, mw, color,
draw_glyph(cbase, pitch, pbytes, g.data, (g.wide ? 16 : 8), mw, color,
(c == hilite_pos) ? hilite_mode : 0);
c++;
}

View file

@ -25,8 +25,8 @@
struct moviefile generate_movie_template(std::vector<std::string> cmdline, loaded_rom& r)
{
struct moviefile movie;
movie.port1 = PT_GAMEPAD;
movie.port2 = PT_NONE;
movie.port1 = &porttype_info::port_default(0);
movie.port2 = &porttype_info::port_default(1);
movie.coreversion = bsnes_core_version;
movie.projectid = get_random_hexstring(40);
movie.gametype = gtype::togametype(r.rtype, r.region);
@ -42,9 +42,9 @@ struct moviefile generate_movie_template(std::vector<std::string> cmdline, loade
if(o.length() >= 9 && o.substr(0, 9) == "--prefix=")
movie.prefix = sanitize_prefix(o.substr(9));
if(o.length() >= 8 && o.substr(0, 8) == "--port1=")
movie.port1 = porttype_info::lookup(o.substr(8)).value;
movie.port1 = &porttype_info::lookup(o.substr(8));
if(o.length() >= 8 && o.substr(0, 8) == "--port2=")
movie.port2 = porttype_info::lookup(o.substr(8)).value;
movie.port2 = &porttype_info::lookup(o.substr(8));
if(o.length() >= 11 && o.substr(0, 11) == "--gamename=")
movie.gamename = o.substr(11);
if(o.length() >= 9 && o.substr(0, 9) == "--author=") {
@ -61,7 +61,7 @@ struct moviefile generate_movie_template(std::vector<std::string> cmdline, loade
throw std::runtime_error("Bad RTC subsecond value (range is 0-3462619485019)");
}
}
movie.input.clear(movie.port1, movie.port2);
movie.input.clear(*movie.port1, *movie.port2);
return movie;
}

View file

@ -1,4 +1,5 @@
#include "core/framebuffer.hpp"
#include "fonts/wrapper.hpp"
#include "platform/sdl/platform.hpp"
void statusarea_model::paint(SDL_Surface* surf, uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint32_t color,
@ -112,9 +113,17 @@ void paint_modal_dialog(SDL_Surface* surf, const std::string& text, bool confirm
int32_t y = 0;
auto s2 = decode_utf8(rtext);
for(auto i : s2) {
auto g = find_glyph(i, x, y, 0, x, y);
if(x + g.first > text_w)
text_w = static_cast<uint32_t>(x + g.first);
auto g = main_font.get_glyph(i);
if(i == 9)
x = (x + 63) / 64 * 64;
else if(i == 10) {
x = 0;
y += 16;
} else {
x += (g.wide ? 16 : 8);
}
if(x + (g.wide ? 16 : 8) > text_w)
text_w = static_cast<uint32_t>(x + (g.wide ? 16 : 8));
if(y + 16 > static_cast<int32_t>(text_h))
text_h = static_cast<uint32_t>(y + 16);
}
@ -311,8 +320,8 @@ namespace
void screen_model::repaint_full() throw()
{
render_framebuffer();
uint32_t current_w = main_screen.width;
uint32_t current_h = main_screen.height;
uint32_t current_w = main_screen.get_width();
uint32_t current_h = main_screen.get_height();
if(!surf || old_screen_w != current_w || old_screen_h != current_h) {
layout.real_width = current_w;
layout.real_height = current_h;
@ -363,8 +372,8 @@ void screen_model::repaint_modal() throw()
void screen_model::_repaint_screen() throw()
{
render_framebuffer();
uint32_t current_w = main_screen.width;
uint32_t current_h = main_screen.height;
uint32_t current_w = main_screen.get_width();
uint32_t current_h = main_screen.get_height();
//Optimize for case where the screen is not resized.
{
SDL_LockSurface(surf);

View file

@ -354,8 +354,8 @@ bool lsnes_app::OnInit()
messages << "BSNES version: " << bsnes_core_version << std::endl;
messages << "lsnes version: lsnes rr" << lsnes_version << std::endl;
controls.set_port(0, PT_NONE, false);
controls.set_port(1, PT_NONE, false);
controls.set_port(0, porttype_info::port_default(0), false);
controls.set_port(1, porttype_info::port_default(1), false);
std::string cfgpath = get_config_path();
messages << "Saving per-user data to: " << get_config_path() << std::endl;

View file

@ -219,7 +219,7 @@ namespace
class controller_autohold_menu : public wxMenu
{
public:
controller_autohold_menu(unsigned lid, enum devicetype_t dtype);
controller_autohold_menu(unsigned lid);
void change_type();
bool is_dummy();
void on_select(wxCommandEvent& e);
@ -272,7 +272,7 @@ namespace
autohold_menu* ahmenu;
};
controller_autohold_menu::controller_autohold_menu(unsigned lid, enum devicetype_t dtype)
controller_autohold_menu::controller_autohold_menu(unsigned lid)
{
modal_pause_holder hld;
our_lid = lid;
@ -347,7 +347,7 @@ namespace
for(unsigned i = 0; i < MAX_LOGICAL_CONTROLLERS; i++) {
std::ostringstream str;
str << "Controller #&" << (i + 1);
menus[i] = new controller_autohold_menu(i, DT_NONE);
menus[i] = new controller_autohold_menu(i);
entries[i] = AppendSubMenu(menus[i], towxstring(str.str()));
entries[i]->Enable(!menus[i]->is_dummy());
}

View file

@ -54,23 +54,27 @@ void patching_done(struct loaded_rom& rom, wxWindow* modwin);
namespace
{
porttype_t get_controller_type(const std::string& s)
porttype_info& get_controller_type(const std::string& s)
{
if(s == CNAME_NONE)
return PT_NONE;
if(s == CNAME_GAMEPAD)
return PT_GAMEPAD;
if(s == CNAME_MULTITAP)
return PT_MULTITAP;
if(s == CNAME_MOUSE)
return PT_MOUSE;
if(s == CNAME_SUPERSCOPE)
return PT_SUPERSCOPE;
if(s == CNAME_JUSTIFIER)
return PT_JUSTIFIER;
if(s == CNAME_JUSTIFIERS)
return PT_JUSTIFIERS;
return PT_INVALID;
auto types = porttype_info::get_all();
for(auto i : types)
if(s == i->hname)
return *i;
return porttype_info::default_type();
}
void load_cchoices(std::vector<wxString>& cc, unsigned port, unsigned& dfltidx)
{
cc.clear();
porttype_info& dflt = porttype_info::port_default(port);
dfltidx = 0;
auto types = porttype_info::get_all();
for(auto i : types)
if(i->legal && i->legal(port)) {
cc.push_back(towxstring(i->hname));
if(i == &dflt)
dfltidx = cc.size() - 1;
}
}
struct loaded_slot& get_rom_slot(struct loaded_rom& rom, unsigned index)
@ -806,14 +810,8 @@ wxwin_project::wxwin_project(loaded_rom& rom)
wxMINIMIZE_BOX | wxSYSTEM_MENU | wxCAPTION | wxCLIP_CHILDREN | wxCLOSE_BOX)
{
our_rom = &rom;
wxString cchoices[CONTROLLERTYPES];
cchoices[0] = wxT(CNAME_NONE);
cchoices[1] = wxT(CNAME_GAMEPAD);
cchoices[2] = wxT(CNAME_MULTITAP);
cchoices[3] = wxT(CNAME_MOUSE);
cchoices[4] = wxT(CNAME_SUPERSCOPE);
cchoices[5] = wxT(CNAME_JUSTIFIER);
cchoices[6] = wxT(CNAME_JUSTIFIERS);
std::vector<wxString> cchoices;
unsigned dfltidx;
std::set<std::string> sram_set = get_sram_set();
@ -855,11 +853,13 @@ wxwin_project::wxwin_project(loaded_rom& rom)
//Controllertypes/Gamename/initRTC/SRAMs.
wxFlexGridSizer* mainblock = new wxFlexGridSizer(5 + sram_set.size(), 2, 0, 0);
mainblock->Add(new wxStaticText(new_panel, wxID_ANY, wxT("Controller 1 Type:")), 0, wxGROW);
mainblock->Add(controller1type = new wxComboBox(new_panel, wxID_ANY, cchoices[1], wxDefaultPosition,
wxDefaultSize, CONTROLLERTYPES, cchoices, wxCB_READONLY), 0, wxGROW);
load_cchoices(cchoices, 0, dfltidx);
mainblock->Add(controller1type = new wxComboBox(new_panel, wxID_ANY, cchoices[dfltidx], wxDefaultPosition,
wxDefaultSize, cchoices.size(), &cchoices[0], wxCB_READONLY), 0, wxGROW);
load_cchoices(cchoices, 1, dfltidx);
mainblock->Add(new wxStaticText(new_panel, wxID_ANY, wxT("Controller 2 Type:")), 0, wxGROW);
mainblock->Add(controller2type = new wxComboBox(new_panel, wxID_ANY, cchoices[0], wxDefaultPosition,
wxDefaultSize, CONTROLLERTYPES, cchoices, wxCB_READONLY), 0, wxGROW);
mainblock->Add(controller2type = new wxComboBox(new_panel, wxID_ANY, cchoices[dfltidx], wxDefaultPosition,
wxDefaultSize, cchoices.size(), &cchoices[0], wxCB_READONLY), 0, wxGROW);
mainblock->Add(new wxStaticText(new_panel, wxID_ANY, wxT("Initial RTC value:")), 0, wxGROW);
wxFlexGridSizer* initrtc = new wxFlexGridSizer(1, 3, 0, 0);
initrtc->Add(rtc_sec = new wxTextCtrl(new_panel, wxID_ANY, wxT("1000000000"), wxDefaultPosition,
@ -1029,8 +1029,8 @@ struct moviefile wxwin_project::make_movie()
moviefile f;
f.force_corrupt = false;
f.gametype = gtype::togametype(our_rom->rtype, our_rom->region);
f.port1 = get_controller_type(tostdstring(controller1type->GetValue()));
f.port2 = get_controller_type(tostdstring(controller2type->GetValue()));
f.port1 = &get_controller_type(tostdstring(controller1type->GetValue()));
f.port2 = &get_controller_type(tostdstring(controller2type->GetValue()));
f.coreversion = bsnes_core_version;
f.gamename = tostdstring(projectname->GetValue());
f.prefix = sanitize_prefix(tostdstring(prefix->GetValue()));
@ -1058,7 +1058,7 @@ struct moviefile wxwin_project::make_movie()
f.movie_rtc_subsecond = f.rtc_subsecond = boost::lexical_cast<int64_t>(tostdstring(rtc_subsec->GetValue()));
if(f.movie_rtc_subsecond < 0)
throw std::runtime_error("RTC subsecond must be positive");
f.input.clear(f.port1, f.port2);
f.input.clear(*f.port1, *f.port2);
return f;
}

View file

@ -23,18 +23,6 @@ std::string name_region(rom_region r)
return "Unknown";
}
std::string name_porttype(porttype_t r)
{
if(r == PT_NONE) return "No device";
if(r == PT_GAMEPAD) return "Gamepad";
if(r == PT_MULTITAP) return "Multitap";
if(r == PT_MOUSE) return "Mouse";
if(r == PT_SUPERSCOPE) return "Super Scope";
if(r == PT_JUSTIFIER) return "Justifier";
if(r == PT_JUSTIFIERS) return "2 Justifiers";
return "Unknown";
}
std::string escape_string(std::string x)
{
std::ostringstream out;
@ -64,8 +52,8 @@ int main(int argc, char** argv)
rom_region reg = gtype::toromregion(m.gametype);
std::cout << "Console: " << name_romtype(rtype) << std::endl;
std::cout << "Region: " << name_region(reg) << std::endl;
std::cout << "Port #1: " << name_porttype(m.port1) << std::endl;
std::cout << "Port #2: " << name_porttype(m.port2) << std::endl;
std::cout << "Port #1: " << m.port1->hname << std::endl;
std::cout << "Port #2: " << m.port2->hname << std::endl;
std::cout << "Used emulator core: " << escape_string(m.coreversion) << std::endl;
if(m.gamename != "")
std::cout << "Game name: " << escape_string(m.gamename) << std::endl;