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
31 #define JOY_MIN -32768
32 #define JOY_THRESH 1000
34 static input NoInput
= {NO_INPUT
, INVALID_BUTTON
, 0};
35 static input SkipInput
= {SKIP_INPUT
, INVALID_BUTTON
, 0};
36 static input EndOfProgram
= {END_OF_PROGRAM
, INVALID_BUTTON
, 0};
38 static SDL_Event last_event
;
40 /* controller mappings */
45 enum input_button button
;
49 struct key_map
* key_maps
= NULL
;
58 enum input_button button
[2];
60 struct axis_map
* next
;
62 struct axis_map
* axis_maps
= NULL
;
69 enum input_button button
;
71 struct jbutton_map
* next
;
73 struct jbutton_map
* jbutton_maps
= NULL
;
76 struct key_map
* kmfind(SDLKey sym
){
77 struct key_map
* ptr
= key_maps
;
87 struct axis_map
* amfind(Uint8 joystick
, Uint8 axis
){
88 struct axis_map
* ptr
= axis_maps
;
90 if(ptr
->joystick
== joystick
&& ptr
->axis
== axis
)
98 struct jbutton_map
* jmfind(Uint8 joystick
, Uint8 jbutton
){
99 struct jbutton_map
* ptr
= jbutton_maps
;
101 if(ptr
->joystick
== joystick
&& ptr
->jbutton
== jbutton
)
111 enum input_type
kmtype(Uint8 type
){
113 case SDL_KEYDOWN
: return BUTTON_PRESS
;
114 case SDL_KEYUP
: return BUTTON_RELEASE
;
116 report_error("input map_key: invalid SDL event type\n");
117 return INVALID_INPUT
;
121 enum input_type
jmtype(Uint8 type
){
123 case SDL_JOYBUTTONDOWN
: return BUTTON_PRESS
;
124 case SDL_JOYBUTTONUP
: return BUTTON_RELEASE
;
126 report_error("input map_jbutton: invalid SDL event type\n");
127 return INVALID_INPUT
;
131 enum input_button
ambutton(int state
, struct axis_map
* am
){
133 case -1: return am
->button
[0];
134 case 1: return am
->button
[1];
136 report_error("input axis_motion: axis state 0 does not imply a button\n");
137 return INVALID_BUTTON
;
139 report_error("input axis_motion: invalid axis state (%d)\n", state
);
140 return INVALID_BUTTON
;
144 input
map_key(SDL_Event
* e
){
145 SDLKey sym
= e
->key
.keysym
.sym
;
146 struct key_map
* km
= kmfind(sym
);
149 in
.type
= kmtype(e
->type
);
150 in
.player
= km
->player
;
151 in
.button
= km
->button
;
155 in
.type
= kmtype(e
->type
);
157 in
.button
= NONDESCRIPT_BUTTON
;
162 input
map_jbutton(SDL_Event
* e
){
163 Uint8 which
= e
->jbutton
.which
;
164 Uint8 jbutton
= e
->jbutton
.button
;
165 struct jbutton_map
* jm
= jmfind(which
, jbutton
);
169 in
.type
= jmtype(e
->type
);
170 in
.player
= jm
->player
;
171 in
.button
= jm
->button
;
175 in
.type
= jmtype(e
->type
);
177 in
.button
= NONDESCRIPT_BUTTON
;
182 int axis_state(Sint16 x
){
183 if(x
< -JOY_THRESH
) return -1;
184 else if(x
> JOY_THRESH
) return 1;
188 input
axis_motion(Sint16 value
, struct axis_map
* am
){
189 int state0
= axis_state(am
->last_value
);
190 int state1
= axis_state(value
);
191 int diff
= state1
- state0
;
196 set a flag in the am which tells get_input
198 note that without this fix, it wont get stuck,
199 the input system will just be slightly inconsistent*/
200 report_error("input axis_motion: (FIXME) joystick almost got stuck\n");
206 else if(state0
!= 0){
207 in
.type
= BUTTON_RELEASE
;
208 in
.player
= am
->player
;
209 in
.button
= ambutton(state0
, am
);
212 else{ /*(state1 != 0)*/
213 in
.type
= BUTTON_PRESS
;
214 in
.player
= am
->player
;
215 in
.button
= ambutton(state1
, am
);
220 input
map_jaxis(SDL_Event
* e
){
221 Uint8 which
= e
->jaxis
.which
;
222 Uint8 axis
= e
->jaxis
.axis
;
223 Sint16 value
= e
->jaxis
.value
;
224 struct axis_map
* am
= amfind(which
, axis
);
226 return axis_motion(value
, am
);
235 void kmadd(int player
, enum input_button button
, SDLKey sym
){
236 struct key_map
* km
= malloc(sizeof(struct key_map
));
237 struct key_map
* ptr
= key_maps
;;
248 while(ptr
->next
) ptr
= ptr
->next
;
259 while(SDL_PollEvent(&e
) != 0){
266 case SDL_JOYBUTTONDOWN
:
267 case SDL_JOYBUTTONUP
:
268 return map_jbutton(&e
);
270 case SDL_JOYAXISMOTION
:
272 if(in
.type
== SKIP_INPUT
)
286 void remap_last_input(enum input_button button
, int player
){
287 SDL_Event e
= last_event
;
291 kmadd(player
, button
, e
.key
.keysym
.sym
);
293 case SDL_JOYBUTTONDOWN
:
294 case SDL_JOYBUTTONUP
:
295 //jmadd(player, button, e.jbutton.button);
297 case SDL_JOYAXISMOTION
:
305 void input_init(const char* filename
){
306 /* set up mappings */
310 kmadd(0, LEFT_BUTTON
, SDLK_a
);
311 kmadd(0, RIGHT_BUTTON
, SDLK_d
);
312 kmadd(0, UP_BUTTON
, SDLK_w
);
313 kmadd(0, DOWN_BUTTON
, SDLK_s
);
315 kmadd(0, JUMP_BUTTON
, SDLK_k
);
316 kmadd(0, FIRE_BUTTON
, SDLK_j
);
317 kmadd(0, INVENTORY_BUTTON
, SDLK_i
);
318 kmadd(0, SPECIAL_BUTTON
, SDLK_l
);
320 kmadd(0, L_BUTTON
, SDLK_u
);
321 kmadd(0, R_BUTTON
, SDLK_o
);
323 kmadd(0, START_BUTTON
, SDLK_q
);
324 kmadd(0, SELECT_BUTTON
, SDLK_e
);
326 kmadd(0, ESCAPE_KEY
, SDLK_ESCAPE
);
327 kmadd(0, PAUSE_KEY
, SDLK_PAUSE
);
330 void save_input(const char* filename
){
335 const char* input_str(input in
){
337 case START_BUTTON
: return "START";
338 case SELECT_BUTTON
: return "SELECT";
339 case L_BUTTON
: return "L";
340 case R_BUTTON
: return "R";
342 case LEFT_BUTTON
: return "LEFT";
343 case RIGHT_BUTTON
: return "RIGHT";
344 case UP_BUTTON
: return "UP";
345 case DOWN_BUTTON
: return "DOWN";
347 case FIRE_BUTTON
: return "FIRE";
348 case JUMP_BUTTON
: return "JUMP";
349 case INVENTORY_BUTTON
: return "INVENTORY";
350 case SPECIAL_BUTTON
: return "SPECIAL";
352 case ESCAPE_KEY
: return "ESCAPE";
353 case PAUSE_KEY
: return "PAUSE";
354 case INVALID_BUTTON
: return "INVALID";
355 case NONDESCRIPT_BUTTON
: return "NONDESCRIPT";
356 default: return "ERROR";