5 * Copyright (C) 2003, 2007, 2008, 2009 Thomas Perl <thp@thpinfo.com>
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,
36 static InputDevice devices
[MAX_INPUT_DEVICES
];
37 static int devices_count
;
43 void init_input(TennixArchive
& tnxar
)
47 SDL_JoystickEventState(SDL_ENABLE
);
49 /* keyboard presets */
50 devices
[devices_count
].type
= INPUT_TYPE_KEYBOARD
;
51 devices
[devices_count
].up_key
= 'w';
52 devices
[devices_count
].down_key
= 's';
53 devices
[devices_count
].input_keys
[INPUT_KEY_HIT
]= 'd';
54 devices
[devices_count
].input_keys
[INPUT_KEY_TOPSPIN
] = 'e';
55 devices
[devices_count
].input_keys
[INPUT_KEY_SMASH
] = 'f';
56 devices
[devices_count
].icon
= GR_INPUT_KEYBOARD_WS
;
57 devices
[devices_count
].exclusive_to_player
= 1;
58 strcpy(devices
[devices_count
].name
, "Keyboard (WS/DEF)");
61 /* keyboard presets */
62 devices
[devices_count
].type
= INPUT_TYPE_KEYBOARD
;
63 devices
[devices_count
].up_key
= 'o';
64 devices
[devices_count
].down_key
= 'l';
65 devices
[devices_count
].input_keys
[INPUT_KEY_HIT
]= 'k';
66 devices
[devices_count
].input_keys
[INPUT_KEY_TOPSPIN
] = 'i';
67 devices
[devices_count
].input_keys
[INPUT_KEY_SMASH
] = 'j';
68 devices
[devices_count
].icon
= GR_INPUT_KEYBOARD_OL
;
69 devices
[devices_count
].exclusive_to_player
= 2;
70 strcpy(devices
[devices_count
].name
, "Keyboard (OL/KIJ)");
73 /* keyboard presets */
74 devices
[devices_count
].type
= INPUT_TYPE_KEYBOARD
;
75 devices
[devices_count
].up_key
= SDLK_UP
;
76 devices
[devices_count
].down_key
= SDLK_DOWN
;
77 devices
[devices_count
].input_keys
[INPUT_KEY_HIT
]= SDLK_SPACE
;
78 devices
[devices_count
].input_keys
[INPUT_KEY_TOPSPIN
] = SDLK_LCTRL
;
79 devices
[devices_count
].input_keys
[INPUT_KEY_SMASH
] = SDLK_LALT
;
80 devices
[devices_count
].icon
= GR_INPUT_KEYBOARD_ARROWS
;
81 strcpy(devices
[devices_count
].name
, "Keyboard (arrows)");
85 devices
[devices_count
].type
= INPUT_TYPE_MOUSE
;
86 devices
[devices_count
].input_keys
[INPUT_KEY_HIT
]= SDL_BUTTON(1);
87 devices
[devices_count
].input_keys
[INPUT_KEY_TOPSPIN
] = SDL_BUTTON(2);
88 devices
[devices_count
].input_keys
[INPUT_KEY_SMASH
] = SDL_BUTTON(3);
89 devices
[devices_count
].icon
= GR_INPUT_MOUSE
;
90 strcpy(devices
[devices_count
].name
, "Mouse");
94 devices
[devices_count
].type
= INPUT_TYPE_NETWORK
;
95 devices
[devices_count
].icon
= GR_INPUT_AI
; /* FIXME - network icon! */
96 strcpy(devices
[devices_count
].name
, "Network player");
100 n
= SDL_NumJoysticks();
101 for (x
=0; x
<n
&& devices_count
<MAX_INPUT_DEVICES
; x
++) {
102 strcpy(devices
[devices_count
].name
, SDL_JoystickName(x
));
103 devices
[devices_count
].type
= INPUT_TYPE_JOYSTICK
;
104 devices
[devices_count
].joystick
= SDL_JoystickOpen(x
);
105 devices
[devices_count
].x_axis
= 0;
106 devices
[devices_count
].y_axis
= 0;
107 devices
[devices_count
].input_keys
[INPUT_KEY_HIT
]= 0;
108 devices
[devices_count
].input_keys
[INPUT_KEY_TOPSPIN
] = 1;
109 devices
[devices_count
].input_keys
[INPUT_KEY_SMASH
] = 2;
110 devices
[devices_count
].icon
= GR_INPUT_GAMEPAD
;
115 /* This will init Python and load all available bots */
116 tennixpy_init(tnxar
);
124 SDL_JoystickEventState(SDL_IGNORE
);
126 for (i
=0; i
<devices_count
; i
++) {
127 if (devices
[i
].type
== INPUT_TYPE_JOYSTICK
) {
128 SDL_JoystickClose(devices
[i
].joystick
);
130 } else if (devices
[i
].type
== INPUT_TYPE_AI_PYTHON
) {
131 tennixpy_unregister_bot(&(devices
[i
]));
144 input_pack_axis(float v
)
146 static const float min
= -1.2;
147 static const float max
= 1.2;
148 tnx_assert(v
>= min
&& v
< max
);
149 return (Uint8
)((1U<<7) * (v
-min
) / (max
-min
));
153 input_unpack_axis(Uint8 v
)
155 static const float min
= -1.2;
156 static const float max
= 1.2;
157 tnx_assert(v
< (1U<<7));
158 return v
* (max
-min
) / (1U<<7) + min
;
162 InputDevice
* find_input_devices(unsigned int* count
)
164 *count
= devices_count
;
168 void input_device_join_game(InputDevice
* device
, void* gamestate
, int player_id
)
170 if (device
== NULL
) {
171 /* player is a c-style bot with no device attached */
174 fprintf(stderr
, "Input Device %s joins the game\n", device
->name
);
176 if (device
->type
== INPUT_TYPE_AI_PYTHON
) {
177 tennixpy_create_bot(device
, (GameState
*)gamestate
, player_id
);
182 void input_device_part_game(InputDevice
* device
)
184 if (device
== NULL
) {
185 /* player is a c-style bot with no device attached */
189 if (device
->type
== INPUT_TYPE_AI_PYTHON
) {
190 tennixpy_destroy_bot(device
);
193 fprintf(stderr
, "Input Device %s leaves the game\n", device
->name
);
196 const char* input_device_get_name(InputDevice
* d
)
201 float input_device_get_axis(InputDevice
* d
, unsigned const char axis
) {
209 if (d
->type
== INPUT_TYPE_KEYBOARD
) {
210 keystate
= SDL_GetKeyState(NULL
);
211 if (axis
== INPUT_AXIS_X
) {
212 result
= 1.0*keystate
[d
->right_key
] + -1.0*keystate
[d
->left_key
];
214 result
= 1.0*keystate
[d
->down_key
] + -1.0*keystate
[d
->up_key
];
216 } else if (d
->type
== INPUT_TYPE_JOYSTICK
) {
217 if (axis
== INPUT_AXIS_X
) {
218 result
= JOYSTICK_PERCENTIZE(SDL_JoystickGetAxis(d
->joystick
, d
->x_axis
*2));
220 result
= JOYSTICK_PERCENTIZE(SDL_JoystickGetAxis(d
->joystick
, 1+d
->y_axis
*2));
222 } else if (d
->type
== INPUT_TYPE_MOUSE
) {
223 //mb = SDL_GetMouseState(&d->mx, &d->my);
224 if (axis
== INPUT_AXIS_X
) {
225 /* Not x-movement yet (PLAYER_MOVE_X is not defined!) */
226 /*if (std::abs(d->mx - d->player_x) > PLAYER_MOVE_X) {
227 if (d->mx > d->player_x) {
229 } else if (d->mx < d->player_x) {
234 if (std::abs(d
->my
- d
->player_y
) > PLAYER_MOVE_Y
) {
235 if (d
->my
> d
->player_y
) {
237 } else if (d
->my
< d
->player_y
) {
243 } else if (d
->type
== INPUT_TYPE_AI_PYTHON
) {
244 result
= tennixpy_bot_get_axis(d
, axis
);
246 } else if (d
->type
== INPUT_TYPE_NETWORK
) {
247 if (axis
== INPUT_AXIS_X
) {
248 result
= input_unpack_axis(d
->net
.x
);
249 } else if (axis
== INPUT_AXIS_Y
) {
250 result
= input_unpack_axis(d
->net
.y
);
253 tnx_assert(0/*unimplemented*/);
256 net_value
= input_pack_axis(result
);
257 if (axis
== INPUT_AXIS_X
) {
258 d
->net
.x
= net_value
;
259 } else if (axis
== INPUT_AXIS_Y
) {
260 d
->net
.y
= net_value
;
266 char input_device_get_key(InputDevice
* d
, unsigned const char key
) {
271 if (d
->type
== INPUT_TYPE_KEYBOARD
) {
272 result
= SDL_GetKeyState(NULL
)[d
->input_keys
[key
]];
273 } else if (d
->type
== INPUT_TYPE_JOYSTICK
) {
274 result
= SDL_JoystickGetButton(d
->joystick
, d
->input_keys
[key
]);
275 } else if (d
->type
== INPUT_TYPE_MOUSE
) {
276 mb
= SDL_GetMouseState(NULL
, NULL
);
277 result
= (mb
& d
->input_keys
[key
]) != 0;
279 } else if (d
->type
== INPUT_TYPE_AI_PYTHON
) {
280 result
= tennixpy_bot_get_key(d
, key
);
282 } else if (d
->type
== INPUT_TYPE_NETWORK
) {
283 result
= (d
->net
.keys
& (1<<key
));
285 tnx_assert(0/*unimplemented*/);
288 /* Update the input device's NetworkInputData struct */
290 d
->net
.keys
|= (1<<key
);
292 d
->net
.keys
&= ~(1<<key
);
302 tnx_assert(devices_count
< MAX_INPUT_DEVICES
);
303 return &(devices
[devices_count
++]);