1 // -----------------------------------------------------------------------
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
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.
18 // THIS PARTICULAR GAME, KBALL DOES NOT NEED BUTTONS, SO IS DISABLED IN INTERACTIVE CONFIGURATION!
19 // -----------------------------------------------------------------------
23 int CController::controller_count
= 0;
25 CController::CController()
28 this->use_keyboard
= TRUE
; // want to use keyboard input? (default=true)
29 this->set_default_keyboard();
32 this->joy_num
= 0; // wich joystick to use? 0..num_joysticks (default=0)
33 this->use_joystick
= FALSE
;
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
53 key_val
[1] = KEY_DOWN
;
54 key_val
[2] = KEY_LEFT
;
55 key_val
[3] = KEY_RIGHT
;
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!
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
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
;
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
;
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
;
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
)
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
);
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
)
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
);
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
);
249 while (keypressed()) readkey();
251 textout_ex(screen
, font
, "-- Keyboard configuration--", 0, y
, color
,-1);
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;
293 textout_ex(screen
, font
, "Done. Press any key... ", 0, y
+=h
*2, color
,-1);
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
);
304 while (keypressed()) readkey();
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);
314 textout_ex(screen
, font
, "-- Joystick configuration--", 0, y
, color
,-1);
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
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
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);
370 textout_ex(screen
, font
, "Done. Press any key... ", 0, y
+=h
*2, color
,-1);
375 void CController::interactive_configuration_mouse(FONT
*font
, int color
)
377 int y
= 100, h
= text_height(font
);
380 while (keypressed()) readkey();
382 textout_ex(screen
, font
, "--Mouse configuration--", 0, y
, color
,-1);
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);