Add support for marshalling GameState + packed values
[tennix.git] / input.c
blob73e3069810c03d0fc011370d6e7498029da07f73
2 /**
4 * Tennix! SDL Port
5 * Copyright (C) 2003, 2007, 2008, 2009 Thomas Perl <thp@thpinfo.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20 * MA 02110-1301, USA.
22 **/
24 #include <string.h>
26 #include "tennix.h"
27 #include "graphics.h"
28 #include "game.h"
29 #include "input.h"
30 #include "util.h"
32 static InputDevice devices[MAX_INPUT_DEVICES];
33 static int devices_count;
35 #ifdef TENNIX_PYTHON
36 #include "tennixpy.h"
37 #endif
39 void init_input()
41 int n, x;
43 SDL_JoystickEventState(SDL_ENABLE);
45 #ifndef MAEMO
46 /* keyboard presets */
47 devices[devices_count].type = INPUT_TYPE_KEYBOARD;
48 devices[devices_count].up_key = 'w';
49 devices[devices_count].down_key = 's';
50 devices[devices_count].input_keys[INPUT_KEY_HIT]= 'd';
51 devices[devices_count].input_keys[INPUT_KEY_TOPSPIN] = 'e';
52 devices[devices_count].input_keys[INPUT_KEY_SMASH] = 'f';
53 devices[devices_count].icon = GR_INPUT_KEYBOARD_WS;
54 devices[devices_count].exclusive_to_player = 1;
55 strcpy(devices[devices_count].name, "Keyboard (WS/DEF)");
56 devices_count++;
58 /* keyboard presets */
59 devices[devices_count].type = INPUT_TYPE_KEYBOARD;
60 devices[devices_count].up_key = 'o';
61 devices[devices_count].down_key = 'l';
62 devices[devices_count].input_keys[INPUT_KEY_HIT]= 'k';
63 devices[devices_count].input_keys[INPUT_KEY_TOPSPIN] = 'i';
64 devices[devices_count].input_keys[INPUT_KEY_SMASH] = 'j';
65 devices[devices_count].icon = GR_INPUT_KEYBOARD_OL;
66 devices[devices_count].exclusive_to_player = 2;
67 strcpy(devices[devices_count].name, "Keyboard (OL/KIJ)");
68 devices_count++;
69 #endif
71 /* keyboard presets */
72 devices[devices_count].type = INPUT_TYPE_KEYBOARD;
73 devices[devices_count].up_key = SDLK_UP;
74 devices[devices_count].down_key = SDLK_DOWN;
75 devices[devices_count].input_keys[INPUT_KEY_HIT]= SDLK_SPACE;
76 devices[devices_count].input_keys[INPUT_KEY_TOPSPIN] = SDLK_LCTRL;
77 devices[devices_count].input_keys[INPUT_KEY_SMASH] = SDLK_LALT;
78 #ifdef MAEMO
79 devices[devices_count].icon = GR_INPUT_MAEMO_DPAD;
80 strcpy(devices[devices_count].name, "D-Pad");
81 devices[devices_count].input_keys[INPUT_KEY_HIT]= SDLK_RETURN;
82 /* FIXME: No TOPSPIN and SMASH keys on Maemo yet with d-pad */
83 #else
84 devices[devices_count].icon = GR_INPUT_KEYBOARD_ARROWS;
85 strcpy(devices[devices_count].name, "Keyboard (arrows)");
86 #endif
87 devices_count++;
89 /* mouse */
90 devices[devices_count].type = INPUT_TYPE_MOUSE;
91 devices[devices_count].input_keys[INPUT_KEY_HIT]= SDL_BUTTON(1);
92 devices[devices_count].input_keys[INPUT_KEY_TOPSPIN] = SDL_BUTTON(2);
93 devices[devices_count].input_keys[INPUT_KEY_SMASH] = SDL_BUTTON(3);
94 #ifdef MAEMO
95 devices[devices_count].icon = GR_INPUT_TOUCHSCREEN;
96 strcpy(devices[devices_count].name, "Touchscreen");
97 #else
98 devices[devices_count].icon = GR_INPUT_MOUSE;
99 strcpy(devices[devices_count].name, "Mouse");
100 #endif
101 devices_count++;
103 /* joysticks */
104 n = SDL_NumJoysticks();
105 for (x=0; x<n && devices_count<MAX_INPUT_DEVICES; x++) {
106 strcpy(devices[devices_count].name, SDL_JoystickName(x));
107 devices[devices_count].type = INPUT_TYPE_JOYSTICK;
108 devices[devices_count].joystick = SDL_JoystickOpen(x);
109 devices[devices_count].x_axis = 0;
110 devices[devices_count].y_axis = 0;
111 devices[devices_count].input_keys[INPUT_KEY_HIT]= 0;
112 devices[devices_count].input_keys[INPUT_KEY_TOPSPIN] = 1;
113 devices[devices_count].input_keys[INPUT_KEY_SMASH] = 2;
114 devices[devices_count].icon = GR_INPUT_GAMEPAD;
115 devices_count++;
118 #ifdef TENNIX_PYTHON
119 /* This will init Python and load all available bots */
120 tennixpy_init();
121 #endif
125 void uninit_input()
127 int i;
128 SDL_JoystickEventState(SDL_IGNORE);
130 for (i=0; i<devices_count; i++) {
131 if (devices[i].type == INPUT_TYPE_JOYSTICK) {
132 SDL_JoystickClose(devices[i].joystick);
133 #ifdef TENNIX_PYTHON
134 } else if (devices[i].type == INPUT_TYPE_AI_PYTHON) {
135 tennixpy_unregister_bot(devices[i].py_bot_class);
136 #endif
140 #ifdef TENNIX_PYTHON
141 tennixpy_uninit();
142 #endif
144 devices_count = 0;
148 InputDevice* find_input_devices(unsigned int* count)
150 *count = devices_count;
151 return devices;
154 void input_device_join_game(InputDevice* device, void* gamestate, int player_id)
156 if (device == NULL) {
157 /* player is a c-style bot with no device attached */
158 return;
160 fprintf(stderr, "Input Device %s joins the game\n", device->name);
161 #ifdef TENNIX_PYTHON
162 if (device->type == INPUT_TYPE_AI_PYTHON) {
163 device->py_bot = tennixpy_create_bot(device->py_bot_class, (GameState*)gamestate, player_id);
165 #endif
168 void input_device_part_game(InputDevice* device)
170 if (device == NULL) {
171 /* player is a c-style bot with no device attached */
172 return;
174 #ifdef TENNIX_PYTHON
175 if (device->type == INPUT_TYPE_AI_PYTHON) {
176 tennixpy_destroy_bot(device->py_bot);
177 device->py_bot = NULL;
179 #endif
180 fprintf(stderr, "Input Device %s leaves the game\n", device->name);
183 const char* input_device_get_name(InputDevice* d)
185 return d->name;
188 float input_device_get_axis(InputDevice* d, unsigned const char axis) {
189 Uint8 *keystate;
190 Uint8 mb;
192 SDL_PumpEvents();
194 if (d->type == INPUT_TYPE_KEYBOARD) {
195 keystate = SDL_GetKeyState(NULL);
196 if (axis == INPUT_AXIS_X) {
197 return 1.0*keystate[d->right_key] + -1.0*keystate[d->left_key];
198 } else {
199 return 1.0*keystate[d->down_key] + -1.0*keystate[d->up_key];
201 } else if (d->type == INPUT_TYPE_JOYSTICK) {
202 if (axis == INPUT_AXIS_X) {
203 return JOYSTICK_PERCENTIZE(SDL_JoystickGetAxis(d->joystick, d->x_axis*2));
204 } else {
205 return JOYSTICK_PERCENTIZE(SDL_JoystickGetAxis(d->joystick, 1+d->y_axis*2));
207 } else if (d->type == INPUT_TYPE_MOUSE) {
208 mb = SDL_GetMouseState(&d->mx, &d->my);
209 if (axis == INPUT_AXIS_X) {
210 /* Not x-movement yet (PLAYER_MOVE_X is not defined!) */
211 /*if (fabsf(d->mx - d->player_x) > PLAYER_MOVE_X) {
212 if (d->mx > d->player_x) {
213 return 1.0;
214 } else if (d->mx < d->player_x) {
215 return -1.0;
218 } else {
219 if (fabsf(d->my - d->player_y) > PLAYER_MOVE_Y) {
220 if (d->my > d->player_y) {
221 return 1.0;
222 } else if (d->my < d->player_y) {
223 return -1.0;
227 #ifdef TENNIX_PYTHON
228 } else if (d->type == INPUT_TYPE_AI_PYTHON) {
229 return tennixpy_bot_get_axis(d->py_bot, axis);
230 #endif
231 } else {
232 /* unimplemented */
234 return 0.0;
237 char input_device_get_key(InputDevice* d, unsigned const char key) {
238 Uint8 mb;
239 SDL_PumpEvents();
241 if (d->type == INPUT_TYPE_KEYBOARD) {
242 return SDL_GetKeyState(NULL)[d->input_keys[key]];
243 } else if (d->type == INPUT_TYPE_JOYSTICK) {
244 return SDL_JoystickGetButton(d->joystick, d->input_keys[key]);
245 } else if (d->type == INPUT_TYPE_MOUSE) {
246 mb = SDL_GetMouseState(NULL, NULL);
247 return (mb & d->input_keys[key]) != 0;
248 #ifdef TENNIX_PYTHON
249 } else if (d->type == INPUT_TYPE_AI_PYTHON) {
250 return tennixpy_bot_get_key(d->py_bot, key);
251 #endif
252 } else {
253 /* unimplemented */
255 return 0;
259 #ifdef TENNIX_PYTHON
261 void input_add_python_bot(PyObject* bot_class)
263 if (devices_count < MAX_INPUT_DEVICES) {
264 devices[devices_count].type = INPUT_TYPE_AI_PYTHON;
265 devices[devices_count].icon = GR_INPUT_AI;
266 devices[devices_count].py_bot_class = bot_class;
267 tennixpy_get_bot_name(bot_class, devices[devices_count].name, INPUT_DEVICE_NAME_MAX);
268 fprintf(stderr, " %s", devices[devices_count].name);
269 devices_count++;
270 } else {
271 fprintf(stderr, "Warning: Cannot add any more Python bots.\n");
272 /* We carry a ref of bot_class, so give it up here */
273 tennixpy_unregister_bot(bot_class);
277 #endif