1 | /*****************************************************************************\ |
2 | Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. |
3 | This file is licensed under the Snes9x License. |
4 | For further information, consult the LICENSE file in the root directory. |
5 | \*****************************************************************************/ |
6 | |
7 | #ifndef _CONTROLS_H_ |
8 | #define _CONTROLS_H_ |
9 | |
10 | #define S9xNoMapping 0 |
11 | #define S9xButtonJoypad 1 |
12 | #define S9xButtonMouse 2 |
13 | #define S9xButtonSuperscope 3 |
14 | #define S9xButtonJustifier 4 |
15 | #define S9xButtonCommand 5 |
16 | #define S9xButtonMulti 6 |
17 | #define S9xButtonMacsRifle 7 |
18 | #define S9xAxisJoypad 8 |
19 | #define S9xPointer 9 |
20 | |
21 | #define S9xButtonPseudopointer 254 |
22 | #define S9xAxisPseudopointer 253 |
23 | #define S9xAxisPseudobuttons 252 |
24 | |
25 | // These are automatically kicked out to the S9xHandlePortCommand function. |
26 | // If your port wants to define port-specific commands or whatever, use these values for the s9xcommand_t type field. |
27 | |
28 | #define S9xButtonPort 251 |
29 | #define S9xAxisPort 250 |
30 | #define S9xPointerPort 249 |
31 | |
32 | #define S9xBadMapping 255 |
33 | #define InvalidControlID ((uint32) -1) |
34 | |
35 | // S9xButtonPseudopointer and S9xAxisPseudopointer will report pointer motion using IDs PseudoPointerBase through PseudoPointerBase+7. |
36 | // S9xAxisPseudopointer command types. S9xAxisPseudobuttons will report buttons with IDs PseudoButtonBase to PseudoButtonBase+255. |
37 | |
38 | #define PseudoPointerBase (InvalidControlID - 8) |
39 | #define PseudoButtonBase (PseudoPointerBase - 256) |
40 | |
41 | typedef struct |
42 | { |
43 | uint8 type; |
44 | uint8 multi_press:2; |
45 | uint8 button_norpt:1; |
46 | |
47 | union |
48 | { |
49 | union |
50 | { |
51 | struct |
52 | { |
53 | uint8 idx:3; // Pad number 0-7 |
54 | uint8 toggle:1; // If set, toggle turbo/sticky for the button |
55 | uint8 turbo:1; // If set, be a 'turbo' button |
56 | uint8 sticky:1; // If set, toggle button state (on/turbo or off) when pressed and do nothing on release |
57 | uint16 buttons; // Which buttons to actuate. Use SNES_*_MASK constants from snes9x.h |
58 | } joypad; |
59 | |
60 | struct |
61 | { |
62 | uint8 idx:1; // Mouse number 0-1 |
63 | uint8 left:1; // buttons |
64 | uint8 right:1; |
65 | } mouse; |
66 | |
67 | struct |
68 | { |
69 | uint8 fire:1; |
70 | uint8 cursor:1; |
71 | uint8 turbo:1; |
72 | uint8 pause:1; |
73 | uint8 aim_offscreen:1; // Pretend we're pointing the gun offscreen (ignore the pointer) |
74 | } scope; |
75 | |
76 | struct |
77 | { |
78 | uint8 idx:3; // Pseudo-pointer number 0-7 |
79 | uint8 speed_type:2; // 0=variable, 1=slow, 2=med, 3=fast |
80 | int8 UD:2; // -1=up, 1=down, 0=no vertical motion |
81 | int8 LR:2; // -1=left, 1=right, 0=no horizontal motion |
82 | } pointer; |
83 | |
84 | struct |
85 | { |
86 | uint8 idx:1; // Justifier number 0-1 |
87 | uint8 trigger:1; // buttons |
88 | uint8 start:1; |
89 | uint8 aim_offscreen:1; // Pretend we're pointing the gun offscreen (ignore the pointer) |
90 | } justifier; |
91 | |
92 | struct |
93 | { |
94 | uint8 trigger:1; |
95 | } macsrifle; |
96 | |
97 | int32 multi_idx; |
98 | uint16 command; |
99 | } button; |
100 | |
101 | union |
102 | { |
103 | struct |
104 | { |
105 | uint8 idx:3; // Pad number 0-7 |
106 | uint8 invert:1; // 1 = positive is Left/Up/Y/X/L |
107 | uint8 axis:3; // 0=Left/Right, 1=Up/Down, 2=Y/A, 3=X/B, 4=L/R |
108 | uint8 threshold; // (threshold+1)/256% deflection is a button press |
109 | } joypad; |
110 | |
111 | struct |
112 | { |
113 | uint8 idx:3; // Pseudo-pointer number 0-7 |
114 | uint8 speed_type:2; // 0=variable, 1=slow, 2=med, 3=fast |
115 | uint8 invert:1; // 1 = invert axis, so positive is up/left |
116 | uint8 HV:1; // 0=horizontal, 1=vertical |
117 | } pointer; |
118 | |
119 | struct |
120 | { |
121 | uint8 threshold; // (threshold+1)/256% deflection is a button press |
122 | uint8 negbutton; // Button ID for negative deflection |
123 | uint8 posbutton; // Button ID for positive deflection |
124 | } button; |
125 | } axis; |
126 | |
127 | struct // Which SNES-pointers to control with this pointer |
128 | { |
129 | uint16 aim_mouse0:1; |
130 | uint16 aim_mouse1:1; |
131 | uint16 aim_scope:1; |
132 | uint16 aim_justifier0:1; |
133 | uint16 aim_justifier1:1; |
134 | uint16 aim_macsrifle:1; |
135 | } pointer; |
136 | |
137 | uint8 port[4]; |
138 | }; |
139 | } s9xcommand_t; |
140 | |
141 | // Starting out... |
142 | |
143 | void S9xUnmapAllControls (void); |
144 | |
145 | // Setting which controllers are plugged in. |
146 | |
147 | enum controllers |
148 | { |
149 | CTL_NONE, // all ids ignored |
150 | CTL_JOYPAD, // use id1 to specify 0-7 |
151 | CTL_MOUSE, // use id1 to specify 0-1 |
152 | CTL_SUPERSCOPE, |
153 | CTL_JUSTIFIER, // use id1: 0=one justifier, 1=two justifiers |
154 | CTL_MP5, // use id1-id4 to specify pad 0-7 (or -1) |
155 | CTL_MACSRIFLE |
156 | }; |
157 | |
158 | void S9xSetController (int port, enum controllers controller, int8 id1, int8 id2, int8 id3, int8 id4); // port=0-1 |
159 | void S9xGetController (int port, enum controllers *controller, int8 *id1, int8 *id2, int8 *id3, int8 *id4); |
160 | void S9xReportControllers (void); |
161 | |
162 | // Call this when you're done with S9xSetController, or if you change any of the controller Settings.*Master flags. |
163 | // Returns true if something was disabled. |
164 | |
165 | bool S9xVerifyControllers (void); |
166 | |
167 | // Functions for translation s9xcommand_t's into strings, and vice versa. |
168 | // free() the returned string after you're done with it. |
169 | |
170 | char * S9xGetCommandName (s9xcommand_t command); |
171 | s9xcommand_t S9xGetCommandT (const char *name); |
172 | |
173 | // Returns an array of strings naming all the snes9x commands. |
174 | // Note that this is only the strings for S9xButtonCommand! |
175 | // The idea is that this would be used for a pull-down list in a config GUI. DO NOT free() the returned value. |
176 | |
177 | const char ** S9xGetAllSnes9xCommands (void); |
178 | |
179 | // Generic mapping functions |
180 | |
181 | s9xcommand_t S9xGetMapping (uint32 id); |
182 | void S9xUnmapID (uint32 id); |
183 | |
184 | // Button mapping functions. |
185 | // If a button is mapped with poll=TRUE, then S9xPollButton will be called whenever snes9x feels a need for that mapping. |
186 | // Otherwise, snes9x will assume you will call S9xReportButton() whenever the button state changes. |
187 | // S9xMapButton() will fail and return FALSE if mapping.type isn't an S9xButton* type. |
188 | |
189 | bool S9xMapButton (uint32 id, s9xcommand_t mapping, bool poll); |
190 | void S9xReportButton (uint32 id, bool pressed); |
191 | |
192 | // Pointer mapping functions. |
193 | // If a pointer is mapped with poll=TRUE, then S9xPollPointer will be called whenever snes9x feels a need for that mapping. |
194 | // Otherwise, snes9x will assume you will call S9xReportPointer() whenever the pointer position changes. |
195 | // S9xMapPointer() will fail and return FALSE if mapping.type isn't an S9xPointer* type. |
196 | |
197 | // Note that position [0,0] is considered the upper-left corner of the 'screen', |
198 | // and either [255,223] or [255,239] is the lower-right. |
199 | // Note that the SNES mouse doesn't aim at a particular point, |
200 | // so the SNES's idea of where the mouse pointer is will probably differ from your OS's idea. |
201 | |
202 | bool S9xMapPointer (uint32 id, s9xcommand_t mapping, bool poll); |
203 | void S9xReportPointer (uint32 id, int16 x, int16 y); |
204 | |
205 | // Axis mapping functions. |
206 | // If an axis is mapped with poll=TRUE, then S9xPollAxis will be called whenever snes9x feels a need for that mapping. |
207 | // Otherwise, snes9x will assume you will call S9xReportAxis() whenever the axis deflection changes. |
208 | // S9xMapAxis() will fail and return FALSE if mapping.type isn't an S9xAxis* type. |
209 | |
210 | // Note that value is linear -32767 through 32767 with 0 being no deflection. |
211 | // If your axis reports differently you should transform the value before passing it to S9xReportAxis(). |
212 | |
213 | bool S9xMapAxis (uint32 id, s9xcommand_t mapping, bool poll); |
214 | void S9xReportAxis (uint32 id, int16 value); |
215 | |
216 | // Do whatever the s9xcommand_t says to do. |
217 | // If cmd.type is a button type, data1 should be TRUE (non-0) or FALSE (0) to indicate whether the 'button' is pressed or released. |
218 | // If cmd.type is an axis, data1 holds the deflection value. |
219 | // If cmd.type is a pointer, data1 and data2 are the positions of the pointer. |
220 | |
221 | void S9xApplyCommand (s9xcommand_t cmd, int16 data1, int16 data2); |
222 | |
223 | ////////// |
224 | // These functions are called by snes9x into your port, so each port should implement them. |
225 | |
226 | // If something was mapped with poll=TRUE, these functions will be called when snes9x needs the button/axis/pointer state. |
227 | // Fill in the reference options as appropriate. |
228 | |
229 | bool S9xPollButton (uint32 id, bool *pressed); |
230 | bool S9xPollPointer (uint32 id, int16 *x, int16 *y); |
231 | bool S9xPollAxis (uint32 id, int16 *value); |
232 | |
233 | // These are called when snes9x tries to apply a command with a S9x*Port type. |
234 | // data1 and data2 are filled in like S9xApplyCommand. |
235 | |
236 | void S9xHandlePortCommand (s9xcommand_t cmd, int16 data1, int16 data2); |
237 | |
238 | // Called before already-read SNES joypad data is being used by the game if your port defines SNES_JOY_READ_CALLBACKS. |
239 | |
240 | #ifdef SNES_JOY_READ_CALLBACKS |
241 | void S9xOnSNESPadRead (void); |
242 | #endif |
243 | |
244 | // These are for your use. |
245 | |
246 | s9xcommand_t S9xGetPortCommandT (const char *name); |
247 | char * S9xGetPortCommandName (s9xcommand_t command); |
248 | void S9xSetupDefaultKeymap (void); |
249 | bool8 S9xMapInput (const char *name, s9xcommand_t *cmd); |
250 | |
251 | ////////// |
252 | // These functions are called from snes9x into this subsystem. No need to use them from a port. |
253 | |
254 | // Use when resetting snes9x. |
255 | |
256 | void S9xControlsReset (void); |
257 | void S9xControlsSoftReset (void); |
258 | |
259 | // Use when writing to $4016. |
260 | |
261 | void S9xSetJoypadLatch (bool latch); |
262 | |
263 | // Use when reading $4016/7 (JOYSER0 and JOYSER1). |
264 | |
265 | uint8 S9xReadJOYSERn (int n); |
266 | |
267 | // End-Of-Frame processing. Sets gun latch variables and tries to draw crosshairs |
268 | |
269 | void S9xControlEOF (void); |
270 | |
271 | // Functions and a structure for snapshot. |
272 | |
273 | struct SControlSnapshot |
274 | { |
275 | uint8 ver; |
276 | uint8 port1_read_idx[2]; |
277 | uint8 dummy1[4]; // for future expansion |
278 | uint8 port2_read_idx[2]; |
279 | uint8 dummy2[4]; |
280 | uint8 mouse_speed[2]; |
281 | uint8 justifier_select; |
282 | uint8 dummy3[8]; |
283 | bool8 pad_read, pad_read_last; |
284 | uint8 internal[60]; // yes, we need to save this! |
285 | uint8 internal_macs[5]; |
286 | }; |
287 | |
288 | void S9xControlPreSaveState (struct SControlSnapshot *s); |
289 | void S9xControlPostLoadState (struct SControlSnapshot *s); |
290 | |
291 | #endif |
292 | |