Evdev joystick plugin
[lsnes.git] / generic / controllerdata.hpp
blobc42b6e5c891f7c9fc622393744f5ca8d93dba767
1 #ifndef _controllerdata__hpp__included__
2 #define _controllerdata__hpp__included__
4 #include <vector>
5 #include <stdexcept>
7 #define ENCODE_SPECIAL_NO_OUTPUT 0xFFFFFFFFU
9 /**
10 * What version to write as control version?
12 #define WRITE_CONTROL_VERSION 0
13 /**
14 * System control: Frame sync flag
16 #define CONTROL_FRAME_SYNC 0
17 /**
18 * System control: System reset button
20 #define CONTROL_SYSTEM_RESET 1
21 /**
22 * High part of cycle count for system reset (multiplier 10000).
24 #define CONTROL_SYSTEM_RESET_CYCLES_HI 2
25 /**
26 * Low part of cycle count for system reset (multiplier 1).
28 #define CONTROL_SYSTEM_RESET_CYCLES_LO 3
29 /**
30 * Number of system controls.
32 #define MAX_SYSTEM_CONTROLS 4
33 /**
34 * SNES has 2 controller ports.
36 #define MAX_PORTS 2
37 /**
38 * Multitap can connect 4 controllers to a single port.
40 #define MAX_CONTROLLERS_PER_PORT 4
41 /**
42 * Ordinary gamepad has 12 buttons/axis total (more than anything else supported).
44 #define CONTROLLER_CONTROLS 12
45 /**
46 * The total number of controls (currently 100).
48 #define TOTAL_CONTROLS (MAX_SYSTEM_CONTROLS + MAX_PORTS * CONTROLLER_CONTROLS * MAX_CONTROLLERS_PER_PORT)
50 struct controls_t;
52 /**
53 * Decoders
55 class cdecode
57 public:
58 /**
59 * This is type of functions that perform decoding of port fields.
61 * parameter port: The number of port to decode.
62 * parameter line: The line to decode from.
63 * parameter pos: Position on the line to start from.
64 * parameter controls: Buffer to place the read controls to.
65 * returns: End of fields (end of string or on '|') or start of next field (otherwise).
66 * throws std::bad_alloc: Not enough memory.
67 * throws std::runtime_error: Bad input.
69 typedef size_t (*fn_t)(unsigned port, const std::string& line, size_t pos, short* controls);
71 /**
72 * This is a decoder for the system field. Note that this is not compatible with fn_t as parameters are diffrent.
74 * parameter port: The number of port to decode.
75 * parameter line: The line to decode from.
76 * parameter pos: Position on the line to start from.
77 * parameter controls: Buffer to place the read controls to.
78 * parameter version: The version of control structure to read.
79 * returns: End of fields or start of next field.
80 * throws std::bad_alloc: Not enough memory.
81 * throws std::runtime_error: Bad input.
83 static size_t system(const std::string& line, size_t pos, short* controls, unsigned version)
84 throw(std::bad_alloc, std::runtime_error);
86 /**
87 * This is a port decoder for port type none (see fn_t).
89 static size_t none(unsigned port, const std::string& line, size_t pos, short* controls)
90 throw(std::bad_alloc, std::runtime_error);
92 /**
93 * This is a port decoder for port type gamepad (see fn_t).
95 static size_t gamepad(unsigned port, const std::string& line, size_t pos, short* controls)
96 throw(std::bad_alloc, std::runtime_error);
98 /**
99 * This is a port decoder for port type multitap (see fn_t).
101 static size_t multitap(unsigned port, const std::string& line, size_t pos, short* controls)
102 throw(std::bad_alloc, std::runtime_error);
105 * This is a port decoder for port type mouse (see fn_t).
107 static size_t mouse(unsigned port, const std::string& line, size_t pos, short* controls)
108 throw(std::bad_alloc, std::runtime_error);
111 * This is a port decoder for port type superscope (see fn_t).
113 static size_t superscope(unsigned port, const std::string& line, size_t pos, short* controls)
114 throw(std::bad_alloc, std::runtime_error);
117 * This is a port decoder for port type justifier (see fn_t).
119 static size_t justifier(unsigned port, const std::string& line, size_t pos, short* controls)
120 throw(std::bad_alloc, std::runtime_error);
123 * This is a port decoder for port type justifiers (see fn_t).
125 static size_t justifiers(unsigned port, const std::string& line, size_t pos, short* controls)
126 throw(std::bad_alloc, std::runtime_error);
130 * Encoders
132 class cencode
134 public:
136 * This is the type of functions that perform encoding of port fields.
138 * parameter port: To number of port to encode.
139 * parameter buffer: Buffer to store the encoded data to.
140 * parameter pos: Position to start writing to.
141 * parameter controls: Buffer to read the controls from.
142 * returns: Position after written data, or ENCODE_SPECIAL_NO_OUTPUT if one wants no output, suppressing even the
143 * field terminator.
144 * throws std::bad_alloc: Not enough memory.
146 typedef size_t (*fn_t)(unsigned port, char* buffer, size_t pos, const short* controls);
149 * This is encoder for the system field. Note that the parameters are bit diffrent and this can't be put into fn_t.
151 * parameter buffer: Buffer to store the encoded data to.
152 * parameter pos: Position to start writing to.
153 * parameter controls: Buffer to read the controls from.
154 * returns: Position after written data, or ENCODE_SPECIAL_NO_OUTPUT if one wants no output, suppressing even the
155 * field terminator.
156 * throws std::bad_alloc: Not enough memory.
158 static size_t system(char* buffer, size_t pos, const short* controls) throw(std::bad_alloc);
161 * This is a port encoder for port type none. See fn_t.
163 static size_t none(unsigned port, char* buffer, size_t pos, const short* controls) throw(std::bad_alloc);
166 * This is a port encoder for port type gamepad. See fn_t.
168 static size_t gamepad(unsigned port, char* buffer, size_t pos, const short* controls) throw(std::bad_alloc);
171 * This is a port encoder for port type multitap. See fn_t.
173 static size_t multitap(unsigned port, char* buffer, size_t pos, const short* controls) throw(std::bad_alloc);
176 * This is a port encoder for port type mouse. See fn_t.
178 static size_t mouse(unsigned port, char* buffer, size_t pos, const short* controls) throw(std::bad_alloc);
181 * This is a port encoder for port type superscope. See fn_t.
183 static size_t superscope(unsigned port, char* buffer, size_t pos, const short* controls) throw(std::bad_alloc);
186 * This is a port encoder for port type justifier. See fn_t.
188 static size_t justifier(unsigned port, char* buffer, size_t pos, const short* controls) throw(std::bad_alloc);
191 * This is a port encoder for port type justifiers. See fn_t.
193 static size_t justifiers(unsigned port, char* buffer, size_t pos, const short* controls) throw(std::bad_alloc);
197 * This structure holds controls for single (sub)frame or instant of time.
199 struct controls_t
202 * Creates new controls structure. All buttons are released and all axes are 0 (neutral).
204 * parameter sync: If true, write 1 (pressed) to frame sync subfield, else write 0 (released). Default false.
206 explicit controls_t(bool sync = false) throw();
209 * This constructor takes in a line of input, port decoders and system field version and decodes the controls.
211 * parameter line: The line to decode.
212 * parameter decoders: The decoders for each port.
213 * parameter version: Version for the system field.
214 * throws std::bad_alloc: Not enough memory.
215 * throws std::runtime_error: Invalid input line.
217 controls_t(const std::string& line, const std::vector<cdecode::fn_t>& decoders, unsigned version)
218 throw(std::bad_alloc, std::runtime_error);
220 * This method takes in port encoders and encodes the controls.
222 * parameter encoders: The encoders for each port.
223 * returns: The encoded controls.
224 * throws std::bad_alloc: Not enough memory.
226 std::string tostring(const std::vector<cencode::fn_t>& encoders) const throw(std::bad_alloc);
229 * This method takes in controller (port, controller, control) tuple and returns reference to the value of that
230 * control.
232 * parameter port: The port number
233 * parameter controller: The controller number within that port.
234 * parameter control: The control number within that controller.
235 * returns: Reference to control value.
236 * throws std::logic_error: port, controller or control is invalid.
238 const short& operator()(unsigned port, unsigned controller, unsigned control) const throw(std::logic_error);
241 * This method takes in control index and returns reference to the value of that control.
243 * parameter control: The control index number.
244 * returns: Reference to control value.
245 * throws std::logic_error: control index is invalid.
247 const short& operator()(unsigned control) const throw(std::logic_error);
250 * This method takes in controller (port, controller, control) tuple and returns reference to the value of that
251 * control.
253 * parameter port: The port number
254 * parameter controller: The controller number within that port.
255 * parameter control: The control number within that controller.
256 * returns: Reference to control value.
257 * throws std::logic_error: port, controller or control is invalid.
259 short& operator()(unsigned port, unsigned controller, unsigned control) throw(std::logic_error);
262 * This method takes in control index and returns reference to the value of that control.
264 * parameter control: The control index number.
265 * returns: Reference to control value.
266 * throws std::logic_error: control index is invalid.
268 short& operator()(unsigned control) throw(std::logic_error);
271 * Perform XOR per-control.
273 * parameter other: The othe field to XOR with.
274 * returns: The XOR result.
276 controls_t operator^(controls_t other) throw();
279 * This field contains the raw controller data. Avoid manipulating directly.
281 short controls[TOTAL_CONTROLS];
284 * Equality
286 bool operator==(const controls_t& c) const throw();
290 * This enumeration gives the type of port.
292 enum porttype_t
295 * No device
297 PT_NONE = 0, //Nothing connected to port.
299 * Gamepad
301 PT_GAMEPAD = 1,
303 * Multitap (with 4 gamepads connected)
305 PT_MULTITAP = 2,
307 * Mouse
309 PT_MOUSE = 3,
311 * Superscope (only allowed for port 2).
313 PT_SUPERSCOPE = 4,
315 * Justifier (only allowed for port 2).
317 PT_JUSTIFIER = 5,
319 * 2 Justifiers (only allowed for port 2).
321 PT_JUSTIFIERS = 6,
323 * Number of controller types.
325 PT_LAST_CTYPE = 6,
327 * Invalid controller type.
329 PT_INVALID = PT_LAST_CTYPE + 1
333 * This enumeration gives the type of device.
335 enum devicetype_t
338 * No device
340 DT_NONE = 0,
342 * Gamepad (note that multitap controllers are gamepads)
344 DT_GAMEPAD = 1,
346 * Mouse
348 DT_MOUSE = 3,
350 * Superscope
352 DT_SUPERSCOPE = 4,
354 * Justifier (note that justifiers is two of these).
356 DT_JUSTIFIER = 5
360 * Information about port type.
362 struct port_type
365 * Name of type.
367 const char* name;
369 * Decoder function.
371 cdecode::fn_t decoder;
373 * Encoder function.
375 cencode::fn_t encoder;
377 * Port type value.
379 porttype_t ptype;
381 * Number of devices.
383 unsigned devices;
385 * Type of each connected device.
387 devicetype_t dtype;
389 * True if valid for port1&2, false if valid for only for port 2.
391 bool valid_port1;
393 * BSNES controller type ID.
395 unsigned bsnes_type;
397 * Lookup port type by name.
399 * parameter name: Name of the port type to look up.
400 * parameter port2: True if controller is for port 2, false if for port 1.
401 * returns: The port type structure
402 * throws std::bad_alloc: Not enough memory.
403 * throws std::runtime_error: Invalid port type.
405 static const port_type& lookup(const std::string& name, bool port2 = true) throw(std::bad_alloc,
406 std::runtime_error);
411 * Information about port types, index by port type value (porttype_t).
413 extern port_type port_types[];
416 * This method takes in controller (port, controller, control) tuple and returns the system index corresponding to
417 * that control.
419 * parameter port: The port number
420 * parameter controller: The controller number within that port.
421 * parameter control: The control number within that controller.
422 * returns: The control index.
423 * throws std::logic_error: port, controller or control is invalid.
425 unsigned ccindex2(unsigned port, unsigned controller, unsigned control) throw(std::logic_error);
427 #endif