2 Cantaveria - action adventure platform game
3 Copyright (C) 2009 2010 Evan Rinehart
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to
18 The Free Software Foundation, Inc.
19 51 Franklin Street, Fifth Floor
20 Boston, MA 02110-1301, USA
22 evanrinehart@gmail.com
27 the input module is an interface to the low level input system
28 plus a mapper from low level input events to abstract game inputs.
29 it has several functions:
30 * generate the next available input, if possible
31 * save and load input maps
32 * remap abstract event to last low level event
33 * convert abstract input to string form
44 #define JOY_MIN -32768
45 #define JOY_THRESH 1000
47 static input NoInput
= {NO_INPUT
, INVALID_BUTTON
, 0};
48 static input SkipInput
= {SKIP_INPUT
, INVALID_BUTTON
, 0};
49 static input EndOfProgram
= {END_OF_PROGRAM
, INVALID_BUTTON
, 0};
51 static SDL_Event last_event
;
53 /* controller mappings */
58 enum input_button button
;
62 struct key_map
* key_maps
= NULL
;
71 enum input_button button
[2];
73 struct axis_map
* next
;
75 struct axis_map
* axis_maps
= NULL
;
82 enum input_button button
;
84 struct jbutton_map
* next
;
86 struct jbutton_map
* jbutton_maps
= NULL
;
89 struct key_map
* kmfind(SDLKey sym
){
90 struct key_map
* ptr
= key_maps
;
100 struct axis_map
* amfind(Uint8 joystick
, Uint8 axis
){
101 struct axis_map
* ptr
= axis_maps
;
103 if(ptr
->joystick
== joystick
&& ptr
->axis
== axis
)
111 struct jbutton_map
* jmfind(Uint8 joystick
, Uint8 jbutton
){
112 struct jbutton_map
* ptr
= jbutton_maps
;
114 if(ptr
->joystick
== joystick
&& ptr
->jbutton
== jbutton
)
124 enum input_type
kmtype(Uint8 type
){
126 case SDL_KEYDOWN
: return BUTTON_PRESS
;
127 case SDL_KEYUP
: return BUTTON_RELEASE
;
129 error_msg("input map_key: invalid SDL event type\n");
130 return INVALID_INPUT
;
134 enum input_type
jmtype(Uint8 type
){
136 case SDL_JOYBUTTONDOWN
: return BUTTON_PRESS
;
137 case SDL_JOYBUTTONUP
: return BUTTON_RELEASE
;
139 error_msg("input map_jbutton: invalid SDL event type\n");
140 return INVALID_INPUT
;
144 enum input_button
ambutton(int state
, struct axis_map
* am
){
146 case -1: return am
->button
[0];
147 case 1: return am
->button
[1];
149 error_msg("input axis_motion: axis state 0 does not imply a button\n");
150 return INVALID_BUTTON
;
152 error_msg("input axis_motion: invalid axis state (%d)\n", state
);
153 return INVALID_BUTTON
;
157 input
map_key(SDL_Event
* e
){
158 SDLKey sym
= e
->key
.keysym
.sym
;
159 struct key_map
* km
= kmfind(sym
);
162 in
.type
= kmtype(e
->type
);
163 in
.player
= km
->player
;
164 in
.button
= km
->button
;
168 in
.type
= kmtype(e
->type
);
170 in
.button
= NONDESCRIPT_BUTTON
;
175 input
map_jbutton(SDL_Event
* e
){
176 Uint8 which
= e
->jbutton
.which
;
177 Uint8 jbutton
= e
->jbutton
.button
;
178 struct jbutton_map
* jm
= jmfind(which
, jbutton
);
182 in
.type
= jmtype(e
->type
);
183 in
.player
= jm
->player
;
184 in
.button
= jm
->button
;
188 in
.type
= jmtype(e
->type
);
190 in
.button
= NONDESCRIPT_BUTTON
;
195 int axis_state(Sint16 x
){
196 if(x
< -JOY_THRESH
) return -1;
197 else if(x
> JOY_THRESH
) return 1;
201 input
axis_motion(Sint16 value
, struct axis_map
* am
){
202 int state0
= axis_state(am
->last_value
);
203 int state1
= axis_state(value
);
204 int diff
= state1
- state0
;
209 set a flag in the am which tells get_input
211 note that without this fix, it wont get stuck,
212 the input system will just be slightly inconsistent*/
213 error_msg("input axis_motion: (FIXME) joystick almost got stuck\n");
219 else if(state0
!= 0){
220 in
.type
= BUTTON_RELEASE
;
221 in
.player
= am
->player
;
222 in
.button
= ambutton(state0
, am
);
225 else{ /*(state1 != 0)*/
226 in
.type
= BUTTON_PRESS
;
227 in
.player
= am
->player
;
228 in
.button
= ambutton(state1
, am
);
233 input
map_jaxis(SDL_Event
* e
){
234 Uint8 which
= e
->jaxis
.which
;
235 Uint8 axis
= e
->jaxis
.axis
;
236 Sint16 value
= e
->jaxis
.value
;
237 struct axis_map
* am
= amfind(which
, axis
);
239 return axis_motion(value
, am
);
248 void kmadd(int player
, enum input_button button
, SDLKey sym
){
249 struct key_map
* km
= malloc(sizeof(struct key_map
));
250 struct key_map
* ptr
= key_maps
;;
261 while(ptr
->next
) ptr
= ptr
->next
;
272 while(SDL_PollEvent(&e
) != 0){
279 case SDL_JOYBUTTONDOWN
:
280 case SDL_JOYBUTTONUP
:
281 return map_jbutton(&e
);
283 case SDL_JOYAXISMOTION
:
285 if(in
.type
== SKIP_INPUT
)
299 void remap_last_input(enum input_button button
, int player
){
300 SDL_Event e
= last_event
;
304 kmadd(player
, button
, e
.key
.keysym
.sym
);
306 case SDL_JOYBUTTONDOWN
:
307 case SDL_JOYBUTTONUP
:
308 //jmadd(player, button, e.jbutton.button);
310 case SDL_JOYAXISMOTION
:
318 void input_init(const char* filename
){
319 /* set up mappings */
323 kmadd(0, LEFT_BUTTON
, SDLK_a
);
324 kmadd(0, RIGHT_BUTTON
, SDLK_d
);
325 kmadd(0, UP_BUTTON
, SDLK_w
);
326 kmadd(0, DOWN_BUTTON
, SDLK_s
);
328 kmadd(0, JUMP_BUTTON
, SDLK_k
);
329 kmadd(0, FIRE_BUTTON
, SDLK_j
);
330 kmadd(0, INVENTORY_BUTTON
, SDLK_i
);
331 kmadd(0, SPECIAL_BUTTON
, SDLK_l
);
333 kmadd(0, L_BUTTON
, SDLK_u
);
334 kmadd(0, R_BUTTON
, SDLK_o
);
336 kmadd(0, START_BUTTON
, SDLK_q
);
337 kmadd(0, SELECT_BUTTON
, SDLK_e
);
339 kmadd(0, ESCAPE_KEY
, SDLK_ESCAPE
);
340 kmadd(0, PAUSE_KEY
, SDLK_PAUSE
);
343 void save_input(const char* filename
){
348 const char* input_str(input in
){
350 case START_BUTTON
: return "START";
351 case SELECT_BUTTON
: return "SELECT";
352 case L_BUTTON
: return "L";
353 case R_BUTTON
: return "R";
355 case LEFT_BUTTON
: return "LEFT";
356 case RIGHT_BUTTON
: return "RIGHT";
357 case UP_BUTTON
: return "UP";
358 case DOWN_BUTTON
: return "DOWN";
360 case FIRE_BUTTON
: return "FIRE";
361 case JUMP_BUTTON
: return "JUMP";
362 case INVENTORY_BUTTON
: return "INVENTORY";
363 case SPECIAL_BUTTON
: return "SPECIAL";
365 case ESCAPE_KEY
: return "ESCAPE";
366 case PAUSE_KEY
: return "PAUSE";
367 case INVALID_BUTTON
: return "INVALID";
368 case NONDESCRIPT_BUTTON
: return "NONDESCRIPT";
369 default: return "ERROR";
374 void print_last_raw(char* buf
, int size
){
375 SDL_Event e
= last_event
;
381 SDL_GetKeyName(e
.key
.keysym
.sym
)
385 case SDL_JOYBUTTONDOWN
:
386 case SDL_JOYBUTTONUP
:
395 case SDL_JOYAXISMOTION
:
405 snprintf(buf
, size
, "???");