Store user data in $HOME
[kball.git] / src / control.cpp
blobf4dba51781ff55f6cde2cb4d8ecc0d02c5ba80c2
1 // -----------------------------------------------------------------------
2 // Controller wrapper
3 // control.cpp
4 // -----------------------------------------------------------------------
5 // This class handles a generic controller.
6 // Simulates a 8 way gamepad with 6 buttons using keyboard,joystick,mouse
7 // By Kronoman - In loving memory of my father
8 // Copyright (c) 2003 - This file released under the MIT license
9 // 08-NOV-2003
11 // ** NOTE **
12 // Modified 04-MAR-2004 to add customize control interface.
13 // This class is arcane, I have a better implementation.
15 // We will use this in this game, in future games, we will use the new implementation.
17 // **** NOTICE ****
18 // THIS PARTICULAR GAME, KBALL DOES NOT NEED BUTTONS, SO IS DISABLED IN INTERACTIVE CONFIGURATION!
19 // -----------------------------------------------------------------------
21 #include "control.h"
23 int CController::controller_count = 0;
25 CController::CController()
27 // keyboard stuff
28 this->use_keyboard = TRUE; // want to use keyboard input? (default=true)
29 this->set_default_keyboard();
31 // joystick stuff
32 this->joy_num = 0; // wich joystick to use? 0..num_joysticks (default=0)
33 this->use_joystick = FALSE;
35 // mouse stuff
36 this->use_mouse = TRUE; // use mouse input? (default=true)
37 this->mouse_sens = 10; // square of 'dead' until mouse movement is detected; (default 10)
39 this->controller_id = CController::controller_count;
40 CController::controller_count++;
43 CController::~CController()
45 CController::controller_count--;
48 // sets the default keyboard configuration
49 void CController::set_default_keyboard()
51 // keys to input: 0..3= up,down,left,right | 4..7= reserved | 8..13= buttons | 14= reserved
52 key_val[0] = KEY_UP;
53 key_val[1] = KEY_DOWN;
54 key_val[2] = KEY_LEFT;
55 key_val[3] = KEY_RIGHT;
57 key_val[8] = KEY_A;
58 key_val[9] = KEY_S;
59 key_val[10] = KEY_D;
60 key_val[11] = KEY_Z;
61 key_val[12] = KEY_X;
62 key_val[13] = KEY_C;
65 // this function is used to configure the keyboard
66 void CController::set_keyboard_par(int value, int index)
68 if ((index < 0) || (index > 14)) return; // error :P
70 this->key_val[index] = value;
73 void CController::set_use_keyboard(bool use)
75 this->use_keyboard = use;
78 void CController::set_mouse_sens(int s)
80 this->mouse_sens = abs(s);
83 void CController::set_use_mouse(bool use)
85 this->use_mouse = use;
88 void CController::set_joystick_number(int n)
90 if (n > num_joysticks-1) return; // error, that joystick is not there!
92 this->joy_num = n;
95 void CController::set_use_joystick(bool use)
97 this->use_joystick = use;
101 // This is the main function
102 // This actually does the input from hardware
103 // and returns the bitmask acording to action
104 int CController::do_input_poll()
106 int ret = KC_NONE; // return value
107 static int old_mouse_z = -666; // mouse_z last call, special flag = -666, means dirty
109 // keyboard
110 if (this->use_keyboard)
112 if (keyboard_needs_poll()) poll_keyboard();
114 if (key[key_val[0]]) ret |= KC_UP;
115 if (key[key_val[1]]) ret |= KC_DOWN;
116 if (key[key_val[2]]) ret |= KC_LEFT;
117 if (key[key_val[3]]) ret |= KC_RIGHT;
119 if (key[key_val[8]]) ret |= KC_BTN1;
120 if (key[key_val[9]]) ret |= KC_BTN2;
121 if (key[key_val[10]]) ret |= KC_BTN3;
122 if (key[key_val[11]]) ret |= KC_BTN4;
123 if (key[key_val[12]]) ret |= KC_BTN5;
124 if (key[key_val[13]]) ret |= KC_BTN6;
127 // mouse
128 if (this->use_mouse)
130 int mickeyx = 0; int mickeyy = 0;
132 if (mouse_needs_poll()) poll_mouse();
134 get_mouse_mickeys(&mickeyx, &mickeyy);
136 if (mickeyx < -mouse_sens) ret |= KC_LEFT;
137 if (mickeyx > mouse_sens) ret |= KC_RIGHT;
139 if (mickeyy < -mouse_sens) ret |= KC_UP;
140 if (mickeyy > mouse_sens) ret |= KC_DOWN;
142 if (mouse_b & 1) ret |= KC_BTN1;
143 if (mouse_b & 2) ret |= KC_BTN2;
144 if (mouse_b & 4) ret |= KC_BTN3;
146 // also mouse_z is used, up = btn4, down = btn5, sadly I can't do yet button 6
147 if (old_mouse_z != -666)
149 if (mouse_z < old_mouse_z) ret |= KC_BTN4;
150 if (mouse_z > old_mouse_z) ret |= KC_BTN5;
152 old_mouse_z = mouse_z;
155 // joystick
156 if (use_joystick)
158 poll_joystick(); // needed
160 // digital joystick input
161 if (joy[joy_num].stick[0].axis[0].d1) ret |= KC_LEFT;
162 if (joy[joy_num].stick[0].axis[0].d2) ret |= KC_RIGHT;
164 if (joy[joy_num].stick[0].axis[1].d1) ret |= KC_UP;
165 if (joy[joy_num].stick[0].axis[1].d2) ret |= KC_DOWN;
167 if (joy[joy_num].num_buttons > 0)
168 if (joy[joy_num].button[0].b) ret |= KC_BTN1;
170 if (joy[joy_num].num_buttons > 1)
171 if (joy[joy_num].button[1].b) ret |= KC_BTN2;
173 if (joy[joy_num].num_buttons > 2)
174 if (joy[joy_num].button[2].b) ret |= KC_BTN3;
176 if (joy[joy_num].num_buttons > 3)
177 if (joy[joy_num].button[3].b) ret |= KC_BTN4;
179 if (joy[joy_num].num_buttons > 4)
180 if (joy[joy_num].button[4].b) ret |= KC_BTN5;
182 if (joy[joy_num].num_buttons > 5)
183 if (joy[joy_num].button[5].b) ret |= KC_BTN6;
186 return ret;
190 int CController::get_keyboard_par(int value, int index)
192 if ((index < 0) || (index > 14)) return -1; // error :P
194 return this->key_val[index];
198 void CController::save_configuration_of_controller(char *cfg_section)
200 char str[256];
202 // how can I save a bool? is this the correct way?
203 set_config_int(cfg_section, "use_keyboard", (int)this->use_keyboard);
204 set_config_int(cfg_section, "use_joystick", (int)this->use_joystick);
205 set_config_int(cfg_section, "use_mouse", (int)this->use_mouse);
207 // save keys
208 for (int i=0; i < 15; i++)
210 usprintf(str,"key_val_%d",i);
211 set_config_int(cfg_section, str, this->key_val[i]);
214 // save joystick number
215 set_config_int(cfg_section, "joy_num", this->joy_num);
217 set_config_int(cfg_section, "mouse_sens", this->mouse_sens);
221 void CController::load_configuration_of_controller(char *cfg_section)
223 char str[256];
225 // is this the correct way?
226 this->use_keyboard = (bool)get_config_int(cfg_section, "use_keyboard", (int)this->use_keyboard);
227 this->use_joystick = (bool)get_config_int(cfg_section, "use_joystick", (int)this->use_joystick);
228 this->use_mouse = (bool)get_config_int(cfg_section, "use_mouse", (int)this->use_mouse);
230 // get keys
231 for (int i=0; i < 15; i++)
233 usprintf(str,"key_val_%d",i);
234 this->key_val[i] = get_config_int(cfg_section, str, this->key_val[i]);
237 this->joy_num = get_config_int(cfg_section, "joy_num", this->joy_num);
239 this->mouse_sens = get_config_int(cfg_section, "mouse_sens", this->mouse_sens);
242 // interactive configuration of controller (really LAME interface with user... improve it! :P)
243 void CController::interactive_configuration_keyboard(FONT *font, int color)
245 int y = 100, h = text_height(font);
247 clear_keybuf();
248 rest(10);
249 while (keypressed()) readkey();
251 textout_ex(screen, font, "-- Keyboard configuration--", 0, y, color,-1);
253 y+=h;
255 textout_ex(screen, font, "Press key for 'UP'", 0, y+=h, color,-1);
256 key_val[0] = readkey() >> 8;
258 textout_ex(screen, font, "Press key for 'DOWN' ", 0, y+=h, color,-1);
259 key_val[1] = readkey() >> 8;
261 textout_ex(screen, font, "Press key for 'LEFT' ", 0, y+=h, color,-1);
262 key_val[2] = readkey() >> 8;
264 textout_ex(screen, font, "Press key for 'RIGHT' ", 0, y+=h, color,-1);
265 key_val[3] = readkey() >> 8;
267 // DEBUG -- DEBUG -- THIS PARTICULAR GAME, KBALL DOES NOT NEED BUTTONS, SO THIS IS DISABLED
268 #ifdef THIS_IS_DISABLED_FOR_THIS_GAME
270 textout_ex(screen, font, "Press key for 'BUTTON 1' ", 0, y+=h, color,-1);
271 key_val[8] = readkey() >> 8;
273 textout_ex(screen, font, "Press key for 'BUTTON 2' ", 0, y+=h, color,-1);
274 key_val[9] = readkey() >> 8;
276 textout_ex(screen, font, "Press key for 'BUTTON 3' ", 0, y+=h, color,-1);
277 key_val[10] = readkey() >> 8;
279 textout_ex(screen, font, "Press key for 'BUTTON 4' ", 0, y+=h, color,-1);
280 key_val[11] = readkey() >> 8;
282 textout_ex(screen, font, "Press key for 'BUTTON 5' ", 0, y+=h, color,-1);
283 key_val[12] = readkey() >> 8;
285 textout_ex(screen, font, "Press key for 'BUTTON 6' ", 0, y+=h, color,-1);
286 key_val[13] = readkey() >> 8;
288 #endif
290 clear_keybuf();
291 rest(10);
293 textout_ex(screen, font, "Done. Press any key... ", 0, y+=h*2, color,-1);
294 readkey();
295 // done
298 // interactive configuration of controller (really LAME interface with user... improve it! :P)
299 void CController::interactive_configuration_joystick(FONT *font, int color)
301 int y = 100, h = text_height(font);
303 clear_keybuf();
304 while (keypressed()) readkey();
306 if (!num_joysticks)
308 textout_ex(screen, font, "-- Error: Joystick not found! --", 0, y, makecol(255,0,0),-1);
309 textout_ex(screen, font, "Press any key...", 0, y+=h, color,-1);
310 readkey();
311 return;
314 textout_ex(screen, font, "-- Joystick configuration--", 0, y, color,-1);
316 y+=h;
318 if (num_joysticks > 1)
320 textprintf_ex(screen, font, 0, y+=h, color,-1, "You have %d joysticks", num_joysticks);
321 textprintf_ex(screen, font, 0, y+=h, color,-1, "Wich one to use? (Press number 1..%d)", num_joysticks);
323 char tmp = (readkey() & 0xff); // take ASCII code
325 joy_num = 0; // default
327 if (tmp == '1') joy_num = 0;
328 if (tmp == '2') joy_num = 1;
329 if (tmp == '3') joy_num = 2;
330 if (tmp == '4') joy_num = 3;
331 // although Allegro driver currently supports up to 4 controllers, we let room to grow in future
332 if (tmp == '5') joy_num = 4;
333 if (tmp == '6') joy_num = 5;
334 if (tmp == '7') joy_num = 6;
335 if (tmp == '8') joy_num = 7;
336 if (tmp == '9') joy_num = 8;
338 if (joy_num > num_joysticks) joy_num = 0; // default
340 else
342 joy_num = 0;
345 textprintf_ex(screen, font, 0, y+=h, color, -1,"We will use joystick number %d", joy_num+1);
347 // calibrate joystick if needed, although not needed, because we use digital input
348 AL_CONST char *msg;
349 while (joy[joy_num].flags & JOYFLAG_CALIBRATE)
351 msg = calibrate_joystick_name(joy_num);
353 textout_ex(screen, font, msg, 0, y+=h, color,-1);
354 textout_ex(screen, font, "And press any key.", 0, y+=h, color,-1);
356 if ((readkey()&0xFF) == 27) return;
358 if (calibrate_joystick(0) != 0)
360 textout_ex(screen, font, "Error calibrating joystick!", 0, y+=h, makecol(255,0,0),-1);
361 textout_ex(screen, font, "Press any key...", 0, y+=h, color,-1);
362 readkey();
363 return;
367 clear_keybuf();
368 rest(10);
370 textout_ex(screen, font, "Done. Press any key... ", 0, y+=h*2, color,-1);
371 readkey();
372 // done
375 void CController::interactive_configuration_mouse(FONT *font, int color)
377 int y = 100, h = text_height(font);
379 clear_keybuf();
380 while (keypressed()) readkey();
382 textout_ex(screen, font, "--Mouse configuration--", 0, y, color,-1);
384 y+=h;
386 textout_ex(screen, font, "Press a key number from 1..9 to choose sensitiviness", 0, y+=h, color,-1);
387 textout_ex(screen, font, "1 = minimum to 9 = maximum", 0, y+=h, color,-1);
389 textout_ex(screen, font, "Any other key to cancel.", 0, y+=h, color,-1);
390 char ret = (readkey() & 0xff); // take ASCII code
392 if (ret == '1') mouse_sens = 40;
393 if (ret == '2') mouse_sens = 30;
394 if (ret == '3') mouse_sens = 25;
395 if (ret == '4') mouse_sens = 20;
396 if (ret == '5') mouse_sens = 15;
397 if (ret == '6') mouse_sens = 10;
398 if (ret == '7') mouse_sens = 5;
399 if (ret == '8') mouse_sens = 1;
400 if (ret == '9') mouse_sens = 0;
402 textout_ex(screen, font, "Done. Press any key... ", 0, y+=h, color,-1);
403 clear_keybuf();
404 rest(10);
405 readkey();
406 // done