Faster movie loading and saving
[lsnes.git] / controllerdata.hpp
blobd5998d79bac9319d74fa3fac88e0ec98f25c10f0
1 #ifndef _controllerdata__hpp__included__
2 #define _controllerdata__hpp__included__
4 #include "fieldsplit.hpp"
5 #include <vector>
6 #include <stdexcept>
8 #define ENCODE_SPECIAL_NO_OUTPUT 0xFFFFFFFFU
10 /**
11 * What version to write as control version?
13 #define WRITE_CONTROL_VERSION 0
14 /**
15 * System control: Frame sync flag
17 #define CONTROL_FRAME_SYNC 0
18 /**
19 * System control: System reset button
21 #define CONTROL_SYSTEM_RESET 1
22 /**
23 * High part of cycle count for system reset (multiplier 10000).
25 #define CONTROL_SYSTEM_RESET_CYCLES_HI 2
26 /**
27 * Low part of cycle count for system reset (multiplier 1).
29 #define CONTROL_SYSTEM_RESET_CYCLES_LO 3
30 /**
31 * Number of system controls.
33 #define MAX_SYSTEM_CONTROLS 4
34 /**
35 * SNES has 2 controller ports.
37 #define MAX_PORTS 2
38 /**
39 * Multitap can connect 4 controllers to a single port.
41 #define MAX_CONTROLLERS_PER_PORT 4
42 /**
43 * Ordinary gamepad has 12 buttons/axis total (more than anything else supported).
45 #define CONTROLLER_CONTROLS 12
46 /**
47 * The total number of controls (currently 100).
49 #define TOTAL_CONTROLS (MAX_SYSTEM_CONTROLS + MAX_PORTS * CONTROLLER_CONTROLS * MAX_CONTROLLERS_PER_PORT)
51 struct controls_t;
53 /**
54 * Decoders
56 class cdecode
58 public:
59 /**
60 * This is type of functions that perform decoding of port fields.
62 * parameter port: The number of port to decode.
63 * parameter line: The line to decode from.
64 * parameter pos: Position on the line to start from.
65 * parameter controls: Buffer to place the read controls to.
66 * returns: End of fields (end of string or on '|') or start of next field (otherwise).
67 * throws std::bad_alloc: Not enough memory.
68 * throws std::runtime_error: Bad input.
70 typedef size_t (*fn_t)(unsigned port, const std::string& line, size_t pos, short* controls);
72 /**
73 * This is a decoder for the system field. Note that this is not compatible with fn_t as parameters are diffrent.
75 * parameter port: The number of port to decode.
76 * parameter line: The line to decode from.
77 * parameter pos: Position on the line to start from.
78 * parameter controls: Buffer to place the read controls to.
79 * parameter version: The version of control structure to read.
80 * returns: End of fields or start of next field.
81 * throws std::bad_alloc: Not enough memory.
82 * throws std::runtime_error: Bad input.
84 static size_t system(const std::string& line, size_t pos, short* controls, unsigned version)
85 throw(std::bad_alloc, std::runtime_error);
87 /**
88 * This is a port decoder for port type none (see fn_t).
90 static size_t none(unsigned port, const std::string& line, size_t pos, short* controls)
91 throw(std::bad_alloc, std::runtime_error);
93 /**
94 * This is a port decoder for port type gamepad (see fn_t).
96 static size_t gamepad(unsigned port, const std::string& line, size_t pos, short* controls)
97 throw(std::bad_alloc, std::runtime_error);
99 /**
100 * This is a port decoder for port type multitap (see fn_t).
102 static size_t multitap(unsigned port, const std::string& line, size_t pos, short* controls)
103 throw(std::bad_alloc, std::runtime_error);
106 * This is a port decoder for port type mouse (see fn_t).
108 static size_t mouse(unsigned port, const std::string& line, size_t pos, short* controls)
109 throw(std::bad_alloc, std::runtime_error);
112 * This is a port decoder for port type superscope (see fn_t).
114 static size_t superscope(unsigned port, const std::string& line, size_t pos, short* controls)
115 throw(std::bad_alloc, std::runtime_error);
118 * This is a port decoder for port type justifier (see fn_t).
120 static size_t justifier(unsigned port, const std::string& line, size_t pos, short* controls)
121 throw(std::bad_alloc, std::runtime_error);
124 * This is a port decoder for port type justifiers (see fn_t).
126 static size_t justifiers(unsigned port, const std::string& line, size_t pos, short* controls)
127 throw(std::bad_alloc, std::runtime_error);
131 * Encoders
133 class cencode
135 public:
137 * This is the type of functions that perform encoding of port fields.
139 * parameter port: To number of port to encode.
140 * parameter buffer: Buffer to store the encoded data to.
141 * parameter pos: Position to start writing to.
142 * parameter controls: Buffer to read the controls from.
143 * returns: Position after written data, or ENCODE_SPECIAL_NO_OUTPUT if one wants no output, suppressing even the
144 * field terminator.
145 * throws std::bad_alloc: Not enough memory.
147 typedef size_t (*fn_t)(unsigned port, char* buffer, size_t pos, const short* controls);
150 * This is encoder for the system field. Note that the parameters are bit diffrent and this can't be put into fn_t.
152 * parameter buffer: Buffer to store the encoded data to.
153 * parameter pos: Position to start writing to.
154 * parameter controls: Buffer to read the controls from.
155 * returns: Position after written data, or ENCODE_SPECIAL_NO_OUTPUT if one wants no output, suppressing even the
156 * field terminator.
157 * throws std::bad_alloc: Not enough memory.
159 static size_t system(char* buffer, size_t pos, const short* controls) throw(std::bad_alloc);
162 * This is a port encoder for port type none. See fn_t.
164 static size_t none(unsigned port, char* buffer, size_t pos, const short* controls) throw(std::bad_alloc);
167 * This is a port encoder for port type gamepad. See fn_t.
169 static size_t gamepad(unsigned port, char* buffer, size_t pos, const short* controls) throw(std::bad_alloc);
172 * This is a port encoder for port type multitap. See fn_t.
174 static size_t multitap(unsigned port, char* buffer, size_t pos, const short* controls) throw(std::bad_alloc);
177 * This is a port encoder for port type mouse. See fn_t.
179 static size_t mouse(unsigned port, char* buffer, size_t pos, const short* controls) throw(std::bad_alloc);
182 * This is a port encoder for port type superscope. See fn_t.
184 static size_t superscope(unsigned port, char* buffer, size_t pos, const short* controls) throw(std::bad_alloc);
187 * This is a port encoder for port type justifier. See fn_t.
189 static size_t justifier(unsigned port, char* buffer, size_t pos, const short* controls) throw(std::bad_alloc);
192 * This is a port encoder for port type justifiers. See fn_t.
194 static size_t justifiers(unsigned port, char* buffer, size_t pos, const short* controls) throw(std::bad_alloc);
198 * This structure holds controls for single (sub)frame or instant of time.
200 struct controls_t
203 * Creates new controls structure. All buttons are released and all axes are 0 (neutral).
205 * parameter sync: If true, write 1 (pressed) to frame sync subfield, else write 0 (released). Default false.
207 explicit controls_t(bool sync = false) throw();
210 * This constructor takes in a line of input, port decoders and system field version and decodes the controls.
212 * parameter line: The line to decode.
213 * parameter decoders: The decoders for each port.
214 * parameter version: Version for the system field.
215 * throws std::bad_alloc: Not enough memory.
216 * throws std::runtime_error: Invalid input line.
218 controls_t(const std::string& line, const std::vector<cdecode::fn_t>& decoders, unsigned version)
219 throw(std::bad_alloc, std::runtime_error);
221 * This method takes in port encoders and encodes the controls.
223 * parameter encoders: The encoders for each port.
224 * returns: The encoded controls.
225 * throws std::bad_alloc: Not enough memory.
227 std::string tostring(const std::vector<cencode::fn_t>& encoders) const throw(std::bad_alloc);
230 * This method takes in controller (port, controller, control) tuple and returns reference to the value of that
231 * control.
233 * parameter port: The port number
234 * parameter controller: The controller number within that port.
235 * parameter control: The control number within that controller.
236 * returns: Reference to control value.
237 * throws std::logic_error: port, controller or control is invalid.
239 const short& operator()(unsigned port, unsigned controller, unsigned control) const throw(std::logic_error);
242 * This method takes in control index and returns reference to the value of that control.
244 * parameter control: The control index number.
245 * returns: Reference to control value.
246 * throws std::logic_error: control index is invalid.
248 const short& operator()(unsigned control) const throw(std::logic_error);
251 * This method takes in controller (port, controller, control) tuple and returns reference to the value of that
252 * control.
254 * parameter port: The port number
255 * parameter controller: The controller number within that port.
256 * parameter control: The control number within that controller.
257 * returns: Reference to control value.
258 * throws std::logic_error: port, controller or control is invalid.
260 short& operator()(unsigned port, unsigned controller, unsigned control) throw(std::logic_error);
263 * This method takes in control index and returns reference to the value of that control.
265 * parameter control: The control index number.
266 * returns: Reference to control value.
267 * throws std::logic_error: control index is invalid.
269 short& operator()(unsigned control) throw(std::logic_error);
272 * Perform XOR per-control.
274 * parameter other: The othe field to XOR with.
275 * returns: The XOR result.
277 controls_t operator^(controls_t other) throw();
280 * This field contains the raw controller data. Avoid manipulating directly.
282 short controls[TOTAL_CONTROLS];
285 * Equality
287 bool operator==(const controls_t& c) const throw();
291 * This enumeration gives the type of port.
293 enum porttype_t
296 * No device
298 PT_NONE = 0, //Nothing connected to port.
300 * Gamepad
302 PT_GAMEPAD = 1,
304 * Multitap (with 4 gamepads connected)
306 PT_MULTITAP = 2,
308 * Mouse
310 PT_MOUSE = 3,
312 * Superscope (only allowed for port 2).
314 PT_SUPERSCOPE = 4,
316 * Justifier (only allowed for port 2).
318 PT_JUSTIFIER = 5,
320 * 2 Justifiers (only allowed for port 2).
322 PT_JUSTIFIERS = 6,
324 * Number of controller types.
326 PT_LAST_CTYPE = 6,
328 * Invalid controller type.
330 PT_INVALID = PT_LAST_CTYPE + 1
334 * This enumeration gives the type of device.
336 enum devicetype_t
339 * No device
341 DT_NONE = 0,
343 * Gamepad (note that multitap controllers are gamepads)
345 DT_GAMEPAD = 1,
347 * Mouse
349 DT_MOUSE = 3,
351 * Superscope
353 DT_SUPERSCOPE = 4,
355 * Justifier (note that justifiers is two of these).
357 DT_JUSTIFIER = 5
361 * Information about port type.
363 struct port_type
366 * Name of type.
368 const char* name;
370 * Decoder function.
372 cdecode::fn_t decoder;
374 * Encoder function.
376 cencode::fn_t encoder;
378 * Port type value.
380 porttype_t ptype;
382 * Number of devices.
384 unsigned devices;
386 * Type of each connected device.
388 devicetype_t dtype;
390 * True if valid for port1&2, false if valid for only for port 2.
392 bool valid_port1;
394 * Lookup port type by name.
396 static const port_type& lookup(const std::string& name, bool port2 = true) throw(std::bad_alloc,
397 std::runtime_error);
402 * Information about port types, index by port type value (porttype_t).
404 extern port_type port_types[];
407 * This method takes in controller (port, controller, control) tuple and returns the system index corresponding to
408 * that control.
410 * parameter port: The port number
411 * parameter controller: The controller number within that port.
412 * parameter control: The control number within that controller.
413 * returns: The control index.
414 * throws std::logic_error: port, controller or control is invalid.
416 unsigned ccindex2(unsigned port, unsigned controller, unsigned control) throw(std::logic_error);
418 #endif