1 #ifndef _controllerdata__hpp__included__
2 #define _controllerdata__hpp__included__
7 #define ENCODE_SPECIAL_NO_OUTPUT 0xFFFFFFFFU
10 * What version to write as control version?
12 #define WRITE_CONTROL_VERSION 0
14 * System control: Frame sync flag
16 #define CONTROL_FRAME_SYNC 0
18 * System control: System reset button
20 #define CONTROL_SYSTEM_RESET 1
22 * High part of cycle count for system reset (multiplier 10000).
24 #define CONTROL_SYSTEM_RESET_CYCLES_HI 2
26 * Low part of cycle count for system reset (multiplier 1).
28 #define CONTROL_SYSTEM_RESET_CYCLES_LO 3
30 * Number of system controls.
32 #define MAX_SYSTEM_CONTROLS 4
34 * SNES has 2 controller ports.
38 * Multitap can connect 4 controllers to a single port.
40 #define MAX_CONTROLLERS_PER_PORT 4
42 * Ordinary gamepad has 12 buttons/axis total (more than anything else supported).
44 #define CONTROLLER_CONTROLS 12
46 * The total number of controls (currently 100).
48 #define TOTAL_CONTROLS (MAX_SYSTEM_CONTROLS + MAX_PORTS * CONTROLLER_CONTROLS * MAX_CONTROLLERS_PER_PORT)
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
);
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
);
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
);
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
);
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
);
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
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
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.
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
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
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
];
286 bool operator==(const controls_t
& c
) const throw();
290 * This enumeration gives the type of port.
297 PT_NONE
= 0, //Nothing connected to port.
303 * Multitap (with 4 gamepads connected)
311 * Superscope (only allowed for port 2).
315 * Justifier (only allowed for port 2).
319 * 2 Justifiers (only allowed for port 2).
323 * Number of controller types.
327 * Invalid controller type.
329 PT_INVALID
= PT_LAST_CTYPE
+ 1
333 * This enumeration gives the type of device.
342 * Gamepad (note that multitap controllers are gamepads)
354 * Justifier (note that justifiers is two of these).
360 * Information about port type.
371 cdecode::fn_t decoder
;
375 cencode::fn_t encoder
;
385 * Type of each connected device.
389 * True if valid for port1&2, false if valid for only for port 2.
393 * BSNES controller type ID.
397 * Lookup port type by name.
399 static const port_type
& lookup(const std::string
& name
, bool port2
= true) throw(std::bad_alloc
,
405 * Information about port types, index by port type value (porttype_t).
407 extern port_type port_types
[];
410 * This method takes in controller (port, controller, control) tuple and returns the system index corresponding to
413 * parameter port: The port number
414 * parameter controller: The controller number within that port.
415 * parameter control: The control number within that controller.
416 * returns: The control index.
417 * throws std::logic_error: port, controller or control is invalid.
419 unsigned ccindex2(unsigned port
, unsigned controller
, unsigned control
) throw(std::logic_error
);