Extern references in library/controller-data.hpp are no-no
[lsnes.git] / include / core / controllerframe.hpp
blobc69dc7656c2dbcd60c0745bf3cb135fbe5f9422f
1 #ifndef _controllerframe__hpp__included__
2 #define _controllerframe__hpp__included__
4 #include <cstring>
5 #include <climits>
6 #include <cstdio>
7 #include <cstdlib>
8 #include <cstdio>
9 #include <cstdint>
10 #include <sstream>
11 #include <iomanip>
12 #include <iostream>
13 #include <stdexcept>
14 #include <string>
15 #include <vector>
16 #include <map>
17 #include <list>
18 #include "library/controller-data.hpp"
20 /**
21 * Analog indices.
23 #define MAX_ANALOG 3
26 /**
27 * Controllers state.
29 class controller_state
31 public:
32 /**
33 * Constructor.
35 controller_state() throw();
36 /**
37 * Convert lcid (Logical Controller ID) into pcid (Physical Controler ID).
39 * Parameter lcid: The logical controller ID.
40 * Return: The physical controller ID, or <-1, -1> if no such controller exists.
42 std::pair<int, int> lcid_to_pcid(unsigned lcid) throw();
43 /**
44 * Lookup (port,controller) pair corresponding to given legacy pcid.
46 * Parameter pcid: The legacy pcid.
47 * Returns: The controller index, or <-1, -1> if no such thing exists.
48 * Note: Even if this does return a valid index, it still may not exist.
50 std::pair<int, int> legacy_pcid_to_pair(unsigned pcid) throw();
51 /**
52 * Convert acid (Analog Controller ID) into pcid.
54 * Parameter acid: The analog controller ID.
55 * Return: The physical controller ID, or <-1,-1> if no such controller exists.
57 std::pair<int, int> acid_to_pcid(unsigned acid) throw();
58 /**
59 * Is given acid a mouse?
61 * Parameter acid: The analog controller ID.
62 * Returns: True if given acid is mouse, false otherwise.
64 bool acid_is_mouse(unsigned acid) throw();
65 /**
66 * Is given pcid present?
68 * Parameter port: The port.
69 * Parameter controller: The controller.
70 * Returns: True if present, false if not.
72 bool pcid_present(unsigned port, unsigned controller) throw();
73 /**
74 * Set types of ports.
76 * Parameter ptype: The new types for ports.
77 * Parameter set_core: If true, set the core port types too, otherwise don't do that.
78 * Throws std::runtime_error: Illegal port type.
80 void set_ports(const port_type_set& ptype, bool set_core) throw(std::runtime_error);
81 /**
82 * Get status of current controls (with autohold/autofire factored in).
84 * Parameter framenum: Number of current frame (for evaluating autofire).
85 * Returns: The current controls.
87 controller_frame get(uint64_t framenum) throw();
88 /**
89 * Commit given controls (autohold/autofire is factored in).
91 * Parameter framenum: Number of current frame (for evaluating autofire).
92 * Returns: The committed controls.
94 controller_frame commit(uint64_t framenum) throw();
95 /**
96 * Commit given controls (autohold/autofire is ignored).
98 * Parameter controls: The controls to commit
99 * Returns: The committed controls.
101 controller_frame commit(controller_frame controls) throw();
103 * Get status of committed controls.
104 * Returns: The committed controls.
106 controller_frame get_committed() throw();
108 * Get blank frame.
110 controller_frame get_blank() throw();
112 * Send analog input to given controller.
114 * Parameter port: The port to send input to.
115 * Parameter controller: The controller to send input to.
116 * Parameter x: The x coordinate to send.
117 * Parameter y: The x coordinate to send.
119 void analog(unsigned port, unsigned controller, int x, int y) throw();
121 * Manipulate autohold.
123 * Parameter port: The port.
124 * Parameter controller: The controller.
125 * Parameter pbid: The physical button ID to manipulate.
126 * Parameter newstate: The new state for autohold.
128 void autohold2(unsigned port, unsigned controller, unsigned pbid, bool newstate) throw();
130 * Query autohold.
132 * Parameter port: The port.
133 * Parameter controller: The controller.
134 * Parameter pbid: The physical button ID to query.
135 * Returns: The state of autohold.
137 bool autohold2(unsigned port, unsigned controller, unsigned pbid) throw();
139 * Reset all frame holds.
141 void reset_framehold() throw();
143 * Manipulate hold for frame.
145 * Parameter port: The port.
146 * Parameter controller: The controller.
147 * Parameter pbid: The physical button ID to manipulate.
148 * Parameter newstate: The new state for framehold.
150 void framehold2(unsigned port, unsigned controller, unsigned pbid, bool newstate) throw();
152 * Query hold for frame.
154 * Parameter port: The port.
155 * Parameter controller: The controller.
156 * Parameter pbid: The physical button ID to query.
157 * Returns: The state of framehold.
159 bool framehold2(unsigned port, unsigned controller, unsigned pbid) throw();
161 * Manipulate button.
163 * Parameter port: The port.
164 * Parameter controller: The controller.
165 * Parameter pbid: The physical button ID to manipulate.
166 * Parameter newstate: The new state for button.
168 void button2(unsigned port, unsigned controller, unsigned pbid, bool newstate) throw();
170 * Query button.
172 * Parameter port: The port.
173 * Parameter controller: The controller.
174 * Parameter pbid: The physical button ID to query.
175 * Returns: The state of button.
177 bool button2(unsigned port, unsigned controller, unsigned pbid) throw();
179 * Set autofire pattern.
181 * Parameter pattern: The new pattern.
182 * Throws std::bad_alloc: Not enough memory.
184 void autofire(std::vector<controller_frame> pattern) throw(std::bad_alloc);
186 * Get physical button ID for physical controller ID and logical button ID.
188 * Parameter port: The port.
189 * Parameter controller: The controller.
190 * Parameter lbid: Logical button id.
191 * Returns: The physical button id, or -1 if no such button.
193 int button_id(unsigned port, unsigned controller, unsigned lbid) throw();
195 * TODO: Document.
197 bool is_present(unsigned port, unsigned controller) throw();
199 * TODO: Document.
201 bool is_analog(unsigned port, unsigned controller) throw();
203 * TODO: Document.
205 bool is_mouse(unsigned port, unsigned controller) throw();
206 private:
207 const port_type_set* types;
208 std::pair<int, int> analog_indices[MAX_ANALOG];
209 bool analog_mouse[MAX_ANALOG];
210 controller_frame _input;
211 controller_frame _autohold;
212 controller_frame _framehold;
213 controller_frame _committed;
214 std::vector<controller_frame> _autofire;
217 extern const char* button_symbols;
218 extern const char* controller_names[];
221 * Generic port display function.
223 template<unsigned controllers, unsigned analog_axis, unsigned buttons, unsigned sidx>
224 inline void generic_port_display(const unsigned char* buffer, unsigned idx, char* buf) throw()
226 if(idx > controllers) {
227 buf[0] = '\0';
228 return;
230 size_t ptr = 0;
231 for(unsigned i = 0; i < analog_axis; i++) {
232 uint16_t a = buffer[2 * idx * analog_axis + 2 * i];
233 uint16_t b = buffer[2 * idx * analog_axis + 2 * i + 1];
234 ptr += sprintf(buf + ptr, "%i ", static_cast<short>(256 * a + b));
236 for(unsigned i = 0; i < buttons; i++) {
237 size_t bit = 16 * controllers * analog_axis + idx * buttons + i;
238 buf[ptr++] = ((buffer[bit / 8] & (1 << (bit % 8))) != 0) ? button_symbols[i + sidx] : '-';
240 buf[ptr] = '\0';
244 * Generic port controller name function.
246 template<unsigned controllers, unsigned nameindex>
247 inline const char* generic_controller_name(unsigned controller)
249 if(controller >= controllers)
250 return NULL;
251 return controller_names[nameindex];
255 * Generic port serialization function.
257 template<unsigned controllers, unsigned analog_axis, unsigned buttons, unsigned sidx>
258 inline size_t generic_port_serialize(const unsigned char* buffer, char* textbuf) throw()
260 size_t ptr = 0;
261 for(unsigned j = 0; j < controllers; j++) {
262 textbuf[ptr++] = '|';
263 for(unsigned i = 0; i < buttons; i++) {
264 size_t bit = 16 * controllers * analog_axis + j * buttons + i;
265 textbuf[ptr++] = ((buffer[bit / 8] & (1 << (bit % 8))) != 0) ? button_symbols[i + sidx] : '.';
267 for(unsigned i = 0; i < analog_axis; i++) {
268 uint16_t a = buffer[2 * j * analog_axis + 2 * i];
269 uint16_t b = buffer[2 * j * analog_axis + 2 * i + 1];
270 ptr += sprintf(textbuf + ptr, " %i", static_cast<short>(256 * a + b));
273 return ptr;
276 #endif