whitespace
[btb/d2x.git] / main / kconfig.c
1 /* $Id: kconfig.c,v 1.17 2003-02-27 22:07:21 btb Exp $ */
2 /*
3 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
4 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
5 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
6 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
7 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
8 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
9 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
10 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
11 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
12 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
13 */
14
15 #ifdef HAVE_CONFIG_H
16 #include <conf.h>
17 #endif
18
19 /*
20  *
21  * Routines to configure keyboard, joystick, etc..
22  *
23  * Old Log:
24  * Revision 1.18  1995/10/29  20:14:10  allender
25  * don't read mouse 30x/sec.  Still causes problems -- left with
26  * exposure at > 60 frame/s
27  *
28  * Revision 1.17  1995/10/27  14:16:35  allender
29  * don't set lastreadtime when doing mouse stuff if we didn't
30  * read mouse this frame
31  *
32  * Revision 1.16  1995/10/24  18:10:22  allender
33  * get mouse stuff working right this time?
34  *
35  * Revision 1.15  1995/10/23  14:50:50  allender
36  * corrected values for control type in kc_set_controls
37  *
38  * Revision 1.14  1995/10/21  16:36:54  allender
39  * fix up mouse read time
40  *
41  * Revision 1.13  1995/10/20  00:46:53  allender
42  * fix up mouse reading problem
43  *
44  * Revision 1.12  1995/10/19  13:36:38  allender
45  * mouse support in kconfig screens
46  *
47  * Revision 1.11  1995/10/18  21:06:06  allender
48  * removed Int3 in cruise stuff -- was in there for debugging and
49  * now not needed
50  *
51  * Revision 1.10  1995/10/17  13:12:47  allender
52  * fixed config menus so buttons don't get configured
53  *
54  * Revision 1.9  1995/10/15  23:07:55  allender
55  * added return key as second button for primary fire
56  *
57  * Revision 1.8  1995/09/05  08:49:47  allender
58  * change 'PADRTN' label to 'ENTER'
59  *
60  * Revision 1.7  1995/09/01  15:38:22  allender
61  * took out cap of reading controls max 25 times/sec
62  *
63  * Revision 1.6  1995/09/01  13:33:59  allender
64  * erase all old text
65  *
66  * Revision 1.5  1995/08/18  10:20:55  allender
67  * keep controls reading to 25 times/s max so fast
68  * frame rates don't mess up control reading
69  *
70  * Revision 1.4  1995/07/28  15:43:13  allender
71  * make mousebutton control primary fire
72  *
73  * Revision 1.3  1995/07/26  17:04:32  allender
74  * new defaults and make joystick main button work correctly
75  *
76  * Revision 1.2  1995/07/17  08:51:03  allender
77  * fixed up configuration menus to look right
78  *
79  * Revision 1.1  1995/05/16  15:26:56  allender
80  * Initial revision
81  *
82  * Revision 2.11  1995/08/23  16:08:04  john
83  * Added version 2 of external controls that passes the ship
84  * position and orientation the drivers.
85  *
86  * Revision 2.10  1995/07/07  16:48:01  john
87  * Fixed bug with new interface.
88  *
89  * Revision 2.9  1995/07/03  15:02:32  john
90  * Added new version of external controls for Cybermouse absolute position.
91  *
92  * Revision 2.8  1995/06/30  12:30:28  john
93  * Added -Xname command line.
94  *
95  * Revision 2.7  1995/03/30  16:36:56  mike
96  * text localization.
97  *
98  * Revision 2.6  1995/03/21  14:39:31  john
99  * Ifdef'd out the NETWORK code.
100  *
101  * Revision 2.5  1995/03/16  10:53:07  john
102  * Move VFX center to Shift+Z instead of Enter because
103  * it conflicted with toggling HUD on/off.
104  *
105  * Revision 2.4  1995/03/10  13:47:24  john
106  * Added head tracking sensitivity.
107  *
108  * Revision 2.3  1995/03/09  18:07:06  john
109  * Fixed bug with iglasses tracking not "centering" right.
110  * Made VFX have bright headlight lighting.
111  *
112  * Revision 2.2  1995/03/08  15:32:39  john
113  * Made VictorMaxx head tracking use Greenleaf code.
114  *
115  * Revision 2.1  1995/03/06  15:23:31  john
116  * New screen techniques.
117  *
118  * Revision 2.0  1995/02/27  11:29:26  john
119  * New version 2.0, which has no anonymous unions, builds with
120  * Watcom 10.0, and doesn't require parsing BITMAPS.TBL.
121  *
122  * Revision 1.105  1995/02/22  14:11:58  allender
123  * remove anonymous unions from object structure
124  *
125  * Revision 1.104  1995/02/13  12:01:56  john
126  * Fixed bug with buggin not mmaking player faster.
127  *
128  * Revision 1.103  1995/02/09  22:00:46  john
129  * Added i-glasses tracking.
130  *
131  * Revision 1.102  1995/01/24  21:25:47  john
132  * Fixed bug with slide/bank on not working with
133  * Cyberman heading.,
134  *
135  * Revision 1.101  1995/01/24  16:09:56  john
136  * Fixed bug with Wingman extreme customize text overwriting title.
137  *
138  * Revision 1.100  1995/01/24  12:37:46  john
139  * Made Esc exit key define menu.
140  *
141  * Revision 1.99  1995/01/23  23:54:43  matt
142  * Made keypad enter work
143  *
144  * Revision 1.98  1995/01/23  16:42:00  john
145  * Made the external controls always turn banking off, leveling off
146  * and passed automap state thru to the tsr.
147  *
148  * Revision 1.97  1995/01/12  11:41:33  john
149  * Added external control reading.
150  *
151  * Revision 1.96  1995/01/05  10:43:58  mike
152  * Handle case when timer_get_fixed_seconds() goes negative.  Happens at 9.1
153  * hours.  Previously, joystick would stop functioning.  Now will work.
154  *
155  * Revision 1.95  1994/12/29  11:17:38  john
156  * Took out some warnings and mprintf.
157  *
158  * Revision 1.94  1994/12/29  11:07:41  john
159  * Fixed Thrustmaster and Logitech Wingman extreme
160  * Hat by reading the y2 axis during the center stage
161  * of the calibration, and using 75, 50, 27, and 3 %
162  * as values for the 4 positions.
163  *
164  * Revision 1.93  1994/12/27  12:16:20  john
165  * Fixed bug with slide on not working with joystick or mouse buttons.
166  *
167  * Revision 1.92  1994/12/20  10:34:15  john
168  * Made sensitivity work for mouse & joystick and made
169  * it only affect, pitch, heading, and roll.
170  *
171  * Revision 1.91  1994/12/16  00:11:23  matt
172  * Made delete key act normally when debug out
173  *
174  * Revision 1.90  1994/12/14  17:41:15  john
175  * Added more buttons so that  Yoke would work.
176  *
177  * Revision 1.89  1994/12/13  17:25:35  allender
178  * Added Assert for bogus time for joystick reading.
179  *
180  * Revision 1.88  1994/12/13  14:48:01  john
181  * Took out some debugging mprintf's
182  *
183  *
184  * Revision 1.87  1994/12/13  14:43:02  john
185  * Took out the code in kconfig to build direction array.
186  * Called kc_set_controls after selecting a new control type.
187  *
188  * Revision 1.86  1994/12/13  01:11:32  john
189  * Fixed bug with message clearing overwriting
190  * right border.
191  *
192  * Revision 1.85  1994/12/12  00:35:58  john
193  * Added or thing for keys.
194  *
195  * Revision 1.84  1994/12/09  17:08:06  john
196  * Made mouse a bit less sensitive.
197  *
198  * Revision 1.83  1994/12/09  16:04:00  john
199  * Increased mouse sensitivity.
200  *
201  * Revision 1.82  1994/12/09  00:41:26  mike
202  * fix hang in automap print screen
203  *
204  * Revision 1.81  1994/12/08  11:50:37  john
205  * Made strcpy only copy corect number of chars,.
206  *
207  * Revision 1.80  1994/12/07  16:16:06  john
208  * Added command to check to see if a joystick axes has been used.
209  *
210  * Revision 1.79  1994/12/07  14:52:28  yuan
211  * Localization 492
212  *
213  * Revision 1.78  1994/12/07  13:37:40  john
214  * Made the joystick thrust work in reverse.
215  *
216  * Revision 1.77  1994/12/07  11:28:24  matt
217  * Did a little localization support
218  *
219  * Revision 1.76  1994/12/04  12:30:03  john
220  * Made the Thrustmaster stick read every frame, not every 10 frames,
221  * because it uses analog axis as buttons.
222  *
223  * Revision 1.75  1994/12/03  22:35:25  yuan
224  * Localization 412
225  *
226  * Revision 1.74  1994/12/03  15:39:24  john
227  * Made numeric keypad move in conifg.
228  *
229  * Revision 1.73  1994/12/01  16:23:39  john
230  * Fixed include mistake.
231  *
232  * Revision 1.72  1994/12/01  16:07:57  john
233  * Fixed bug that disabled joystick in automap because it used gametime, which is
234  * paused during automap. Fixed be used timer_Get_fixed_seconds instead of GameTime.
235  *
236  * Revision 1.71  1994/12/01  12:30:49  john
237  * Made Ctrl+D delete, not Ctrl+E
238  *
239  * Revision 1.70  1994/12/01  11:52:52  john
240  * Added default values for GamePad.
241  *
242  * Revision 1.69  1994/11/30  00:59:12  mike
243  * optimizations.
244  *
245  * Revision 1.68  1994/11/29  03:45:50  john
246  * Added joystick sensitivity; Added sound channels to detail menu.  Removed -maxchannels
247  * command line arg.
248  *
249  * Revision 1.67  1994/11/27  23:13:44  matt
250  * Made changes for new mprintf calling convention
251  *
252  * Revision 1.66  1994/11/27  19:52:12  matt
253  * Made screen shots work in a few more places
254  *
255  * Revision 1.65  1994/11/22  16:54:50  mike
256  * autorepeat on missiles.
257  *
258  * Revision 1.64  1994/11/21  11:16:17  rob
259  * Changed calls to GameLoop to calls to multi_menu_poll and changed
260  * conditions under which they are called.
261  *
262  * Revision 1.63  1994/11/19  15:14:48  mike
263  * remove unused code and data
264  *
265  * Revision 1.62  1994/11/18  23:37:56  john
266  * Changed some shorts to ints.
267  *
268  * Revision 1.61  1994/11/17  13:36:35  rob
269  * Added better network hook in kconfig menu.
270  *
271  * Revision 1.60  1994/11/14  20:09:13  john
272  * Made Tab be default for automap.
273  *
274  * Revision 1.59  1994/11/13  16:34:07  matt
275  * Fixed victormaxx angle conversions
276  *
277  * Revision 1.58  1994/11/12  14:47:05  john
278  * Added support for victor head tracking.
279  *
280  * Revision 1.57  1994/11/08  15:14:55  john
281  * Added more calls so net doesn't die in net game.
282  *
283  * Revision 1.56  1994/11/07  14:01:07  john
284  * Changed the gamma correction sequencing.
285  *
286  * Revision 1.55  1994/11/01  16:40:08  john
287  * Added Gamma correction.
288  *
289  * Revision 1.54  1994/10/25  23:09:26  john
290  * Made the automap key configurable.
291  *
292  * Revision 1.53  1994/10/25  13:11:59  john
293  * Made keys the way Adam speced 'em for final game.
294  *
295  * Revision 1.52  1994/10/24  17:44:22  john
296  * Added stereo channel reversing.
297  *
298  * Revision 1.51  1994/10/22  13:23:18  john
299  * Made default rear view key be R.
300  *
301  * Revision 1.50  1994/10/22  13:20:09  john
302  * Took out toggle primary/secondary weapons.  Fixed black
303  * background for 'axes' and 'buttons' text.
304  *
305  * Revision 1.49  1994/10/21  15:20:15  john
306  * Made PrtScr do screen dump, not F2.
307  *
308  * Revision 1.48  1994/10/21  13:41:36  john
309  * Allowed F2 to screen dump.
310  *
311  * Revision 1.47  1994/10/17  13:07:05  john
312  * Moved the descent.cfg info into the player config file.
313  *
314  * Revision 1.46  1994/10/14  15:30:22  john
315  * Added Cyberman default positions.
316  *
317  * Revision 1.45  1994/10/14  15:24:54  john
318  * Made Cyberman work with config.
319  *
320  * Revision 1.44  1994/10/14  12:46:04  john
321  * Added the ability to reset all to default.
322  *
323  * Revision 1.43  1994/10/14  12:18:31  john
324  * Made mouse invert axis always be 0 or 1.
325  *
326  * Revision 1.42  1994/10/14  12:16:03  john
327  * Changed code so that by doing DEL+F12 saves the current kconfig
328  * values as default. Added support for drop_bomb key.  Took out
329  * unused slots for keyboard.  Made keyboard use control_type of 0
330  * save slots.
331  *
332  * Revision 1.41  1994/10/13  21:27:02  john
333  * Made axis invert value always be 0 or 1.
334  *
335  * Revision 1.40  1994/10/13  20:18:15  john
336  * Added some more system keys, such as F? and CAPSLOCK.
337  *
338  * Revision 1.39  1994/10/13  19:22:29  john
339  * Added separate config saves for different devices.
340  * Made all the devices work together better, such as mice won't
341  * get read when you're playing with the joystick.
342  *
343  * Revision 1.38  1994/10/13  15:41:57  mike
344  * Remove afterburner.
345  *
346  */
347
348 #ifdef RCS
349 static char rcsid[] = "$Id: kconfig.c,v 1.17 2003-02-27 22:07:21 btb Exp $";
350 #endif
351
352 #ifdef WINDOWS
353 #include "desw.h"
354 #endif
355
356 #include <stdio.h>
357 #include <stdlib.h>
358 #include <string.h>
359 #include <stdarg.h>
360 #include <ctype.h>
361
362 #include "pa_enabl.h"                   //$$POLY_ACC
363 #include "error.h"
364 #include "pstypes.h"
365 #include "gr.h"
366 #include "mono.h"
367 #include "key.h"
368 #include "palette.h"
369 #include "game.h"
370 #include "gamefont.h"
371 #include "iff.h"
372 #include "u_mem.h"
373 #include "joy.h"
374 #include "mouse.h"
375 #include "kconfig.h"
376 #include "gauges.h"
377 #include "joydefs.h"
378 #include "songs.h"
379 #include "render.h"
380 #include "digi.h"
381 #include "newmenu.h"
382 #include "endlevel.h"
383 #include "multi.h"
384 #include "timer.h"
385 #include "text.h"
386 #include "player.h"
387 #include "menu.h"
388 #include "automap.h"
389 #include "args.h"
390 #include "lighting.h"
391 #include "ai.h"
392 #include "cntrlcen.h"
393 #if defined (TACTILE)
394  #include "tactile.h"
395 #endif
396
397 #if defined(POLY_ACC)
398 #include "poly_acc.h"
399 #endif
400
401 #include "collide.h"
402
403 #ifdef __unix__
404 #include "joystick.h"
405 #endif
406
407 ubyte ExtGameStatus=1;
408
409 vms_vector ExtForceVec;
410 vms_matrix ExtApplyForceMatrix;
411
412 int ExtJoltInfo[3]={0,0,0};
413 int ExtXVibrateInfo[2]={0,0};
414 int ExtYVibrateInfo[2]={0,0};
415 ubyte ExtXVibrateClear=0;
416 ubyte ExtYVibrateClear=0;
417
418 #define TABLE_CREATION 1
419
420 // Array used to 'blink' the cursor while waiting for a keypress.
421 byte fades[64] = { 1,1,1,2,2,3,4,4,5,6,8,9,10,12,13,15,16,17,19,20,22,23,24,26,27,28,28,29,30,30,31,31,31,31,31,30,30,29,28,28,27,26,24,23,22,20,19,17,16,15,13,12,10,9,8,6,5,4,4,3,2,2,1,1 };
422
423 //char * invert_text[2] = { "N", "Y" };
424 //char * joybutton_text[28] = { "BTN 1", "BTN 2", "BTN 3", "BTN 4", "", "TRIG", "LEFT", "HAT \81", "RIGHT", "", "", "HAT \80", "MID", "", "", "HAT \7f", "", "", "", "HAT \82", "TRIG", "LEFT", "RIGHT", "", "UP","DOWN","LEFT", "RIGHT" };
425 //char * joyaxis_text[4] = { "X1", "Y1", "X2", "Y2" };
426 //char * mouseaxis_text[2] = { "L/R", "F/B" };
427 //char * mousebutton_text[3] = { "Left", "Right", "Mid" };
428
429 int invert_text[2] = { TNUM_N, TNUM_Y };
430
431 #ifdef WINDOWS
432         int joybutton_text[28] = 
433         { TNUM_BTN_1, TNUM_BTN_2, TNUM_BTN_3, TNUM_BTN_4,
434           -1, -1, -1, -1,
435           -1, -1, -1, -1,
436           -1, -1, -1, -1,
437           TNUM_HAT_L, TNUM_HAT_R, TNUM_HAT_U, TNUM_HAT_D,
438           -1, -1, -1, -1,
439           -1, -1, -1, -1
440         };
441         int joyaxis_text[7] = { TNUM_X1, TNUM_Y1, TNUM_Z1, TNUM_UN, TNUM_P1,TNUM_R1,TNUM_YA1 };
442 #else
443         int joybutton_text[28] = 
444         { TNUM_BTN_1, TNUM_BTN_2, TNUM_BTN_3, TNUM_BTN_4,
445           -1, TNUM_TRIG, TNUM_LEFT, TNUM_HAT_L,
446          TNUM_RIGHT, -1, TNUM_HAT2_D, TNUM_HAT_R,
447          TNUM_MID, -1, TNUM_HAT2_R, TNUM_HAT_U,
448          TNUM_HAT2_L, -1, TNUM_HAT2_U, TNUM_HAT_D,
449          TNUM_TRIG, TNUM_LEFT, TNUM_RIGHT, -1, 
450          TNUM_UP, TNUM_DOWN, TNUM_LEFT, TNUM_RIGHT };
451
452         int joyaxis_text[7] = { TNUM_X1, TNUM_Y1, TNUM_Z1, TNUM_UN, TNUM_P1,TNUM_R1,TNUM_YA1 };
453 //      int joyaxis_text[4] = { TNUM_X1, TNUM_Y1, TNUM_X2, TNUM_Y2 };
454 #endif
455         
456 int mouseaxis_text[3] = { TNUM_L_R, TNUM_F_B, TNUM_Z1 };
457 #ifndef MACINTOSH
458 int mousebutton_text[3] = { TNUM_LEFT, TNUM_RIGHT, TNUM_MID };
459 char * mousebutton_textra[13] = { "M4", "M5", "M6", "M7", "M8", "M9", "M10","M11","M12","M13","M14","M15","M16" };//text for buttons above 3. -MPM
460 #else
461 char *mousebutton_text[3] = { "Btn", "", "" };          // only one silly mouse button on the mac
462 #endif
463
464 #ifdef MACINTOSH
465 char * key_text[256] = {         
466 "","S","D","F","H","G","Z","X","C","V","","B","Q", "W", "E", "R",
467 "Y","T","1","2","3","4","6","5","=","9","7","-", "8", "0", "]", "O",
468 "U","[","I","P","RET","L","J","'","K", ";", "\\", ",", "/", "N", "M", ".",
469 "TAB","SPC","`","DEL","","ESC","","APL","SHIFT","CAPSL","OPTN","CTRL","","","","A",
470 "","PAD.","","PAD*","","PAD+","","NMLCK","","","","PAD/","ENTER","","PAD-","",
471 "","PAD=","PAD0","PAD1","PAD2","PAD3","PAD4","PAD5","PAD6","PAD7","","PAD8","PAD9","","","",
472 "F5","F6","F7","","F8","F9","","F11","","F13","","F14","","F10","","F12",
473 "","PAUSE","HELP","HOME","PGUP","DEL","","END","F2","","F1","LARW","RARW","DARW","UARW","",
474 "","","","","","","","","","","","","","","","",
475 "","","","","","","","","","","","","","","","",
476 "","","","","","","","","","","","","","","","",
477 "","","","","","","","","","","","","","","","",
478 "","","","","","","","","","","","","","","","",
479 "","","","","","","","","","","","","","","","",
480 "","","","","","","","","","","","","","","","",
481 "","","","","","","","","","","","","","","",""};
482 #else
483 #if !defined OGL && !defined SDL_INPUT
484 char * key_text[256] = {         \
485 "","ESC","1","2","3","4","5","6","7","8","9","0","-",                   \
486 "=","BSPC","TAB","Q","W","E","R","T","Y","U","I","O",                           \
487 "P","[","]","\83","LCTRL","A","S","D","F",        \
488 "G","H","J","K","L",";","'","`",        \
489 "LSHFT","\\","Z","X","C","V","B","N","M",",",      \
490 ".","/","RSHFT","PAD*","LALT","SPC",      \
491 "CPSLK","F1","F2","F3","F4","F5","F6","F7","F8","F9",        \
492 "F10","NMLCK","SCLK","PAD7","PAD8","PAD9","PAD-",   \
493 "PAD4","PAD5","PAD6","PAD+","PAD1","PAD2","PAD3","PAD0", \
494 "PAD.","","","","F11","F12","","","","","","","","","",         \
495 "","","","","","","","","","","","","","","","","","","","",     \
496 "","","","","","","","","","","","","","","","","","","","",     \
497 "","","","","","","","","","","","","","","","","","",           \
498 "PAD\83","RCTRL","","","","","","","","","","","","","", \
499 "","","","","","","","","","","PAD/","","","RALT","",      \
500 "","","","","","","","","","","","","","HOME","\82","PGUP",     \
501 "","\81","","\7f","","END","\80","PGDN","INS",       \
502 "DEL","","","","","","","","","","","","","","","","","",     \
503 "","","","","","","","","","","","","","","","","","","","",     \
504 "","","","","","","" };
505 #endif /* OGL */
506 #endif
507
508 ubyte system_keys[] = { KEY_ESC, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11, KEY_F12, KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_0, KEY_MINUS, KEY_EQUAL, KEY_PRINT_SCREEN };
509
510 //extern void GameLoop(int, int );
511
512 extern void transfer_energy_to_shield(fix);
513 extern void CyclePrimary(),CycleSecondary(),InitMarkerInput();
514 extern ubyte DefiningMarkerMessage;
515 extern char CybermouseActive;
516
517 #ifdef WINDOWS
518 extern int joydefsw_do_button();
519 extern int joydefsw_do_winjoybutton(int *axis);
520 extern joydefsw_win_joyselect(char *title);
521 #endif
522
523 control_info Controls;
524
525 fix Cruise_speed=0;
526
527 // macros for drawing lo/hi res kconfig screens (see scores.c as well)
528
529 #define LHX(x)          ((x)*(MenuHires?2:1))
530 #define LHY(y)          ((y)*(MenuHires?2.4:1))
531
532
533 #define BT_KEY                          0
534 #define BT_MOUSE_BUTTON         1
535 #define BT_MOUSE_AXIS           2
536 #define BT_JOY_BUTTON           3
537 #define BT_JOY_AXIS                     4
538 #define BT_INVERT                               5
539
540 char *btype_text[] = { "BT_KEY", "BT_MOUSE_BUTTON", "BT_MOUSE_AXIS", "BT_JOY_BUTTON", "BT_JOY_AXIS", "BT_INVERT" };
541
542 #define INFO_Y 28
543
544 typedef struct kc_item {
545         short id;                               // The id of this item
546         short x, y;                             
547         short w1;
548         short w2;
549         short u,d,l,r;
550         //short text_num1;
551         char *text;
552         ubyte type;
553         ubyte value;            // what key,button,etc
554 } kc_item;
555
556 int Num_items=28;
557 kc_item *All_items;
558
559 ubyte kconfig_settings[CONTROL_MAX_TYPES][MAX_CONTROLS];
560
561 //----------- WARNING!!!!!!! -------------------------------------------
562 // THESE NEXT FOUR BLOCKS OF DATA ARE GENERATED BY PRESSING DEL+F12 WHEN
563 // IN THE KEYBOARD CONFIG SCREEN.  BASICALLY, THAT PROCEDURE MODIFIES THE
564 // U,D,L,R FIELDS OF THE ARRAYS AND DUMPS THE NEW ARRAYS INTO KCONFIG.COD
565 //-------------------------------------------------------------------------
566 /*ubyte default_kconfig_settings[CONTROL_MAX_TYPES][MAX_CONTROLS] = {
567 {0xc8,0x48,0xd0,0x50,0xcb,0x4b,0xcd,0x4d,0x38,0xff,0xff,0x4f,0xff,0x51,0xff,0x4a,0xff,0x4e,0xff,0xff,0x10,0x47,0x12,0x49,0x1d,0x9d,0x39,0xff,0x21,0xff,0x1e,0xff,0x2c,0xff,0x30,0xff,0x13,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf,0xff,0x1f,0xff,0x33,0xff,0x34,0xff,0x23,0xff,0x14,0xff,0xff,0xff,0x0,0x0},
568 {0x0,0x1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1,0x0,0x0,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
569 {0x5,0xc,0xff,0xff,0xff,0xff,0x7,0xf,0x13,0xb,0xff,0x6,0x8,0x1,0x0,0x0,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
570 {0x0,0x1,0xff,0xff,0x2,0xff,0x7,0xf,0x13,0xb,0xff,0xff,0xff,0x1,0x0,0x0,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0xff,0xff,0x3,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
571 {0x3,0x0,0x1,0x2,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1,0x0,0x0,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
572 {0x0,0x1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1,0x0,0x0,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
573 {0x0,0x1,0xff,0xff,0x2,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
574 };*/                                                                              
575
576 #ifndef MACINTOSH
577 ubyte default_kconfig_settings[CONTROL_MAX_TYPES][MAX_CONTROLS] = {
578 {0xc8,0x48,0xd0,0x50,0xcb,0x4b,0xcd,0x4d,0x38,0xff,0xff,0x4f,0xff,0x51,0xff,0x4a,0xff,0x4e,0xff,0xff,0x10,0x47,0x12,0x49,0x1d,0x9d,0x39,0xff,0x21,0xff,0x1e,0xff,0x2c,0xff,0x30,0xff,0x13,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf,0xff,0x1f,0xff,0x33,0xff,0x34,0xff,0x23,0xff,0x14,0xff,0xff,0xff,0x0,0x0},
579 {0x0,0x1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1,0x0,0x0,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0,0x0,0x0,0x0},
580 {0x5,0xc,0xff,0xff,0xff,0xff,0x7,0xf,0x13,0xb,0xff,0x6,0x8,0x1,0x0,0x0,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0,0x0},
581 {0x0,0x1,0xff,0xff,0x2,0xff,0x7,0xf,0x13,0xb,0xff,0xff,0xff,0x1,0x0,0x0,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0x3,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0,0x0,0x0,0x0,0x0},
582 {0x3,0x0,0x1,0x2,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1,0x0,0x0,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0,0x0,0x0,0x0,0x0},
583 {0x0,0x1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1,0x0,0x0,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0,0x0,0x0,0x0,0x0},
584 {0x0,0x1,0xff,0xff,0x2,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0,0x0,0x0,0x0},
585 #ifdef WINDOWS
586 {0x0,0x1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1,0x0,0x0,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0,0x0,0x0,0x0},
587 #endif
588 };
589
590
591
592 kc_item kc_keyboard[NUM_KEY_CONTROLS] = {
593         {  0, 15, 49, 71, 26, 55,  2, 55,  1,"Pitch forward", BT_KEY, 255 },
594         {  1, 15, 49,100, 26, 50,  3,  0, 24,"Pitch forward", BT_KEY, 255 },
595         {  2, 15, 57, 71, 26,  0,  4, 25,  3,"Pitch backward", BT_KEY, 255 },
596         {  3, 15, 57,100, 26,  1,  5,  2, 26,"Pitch backward", BT_KEY, 255 },
597         {  4, 15, 65, 71, 26,  2,  6, 27,  5,"Turn left", BT_KEY, 255 },
598         {  5, 15, 65,100, 26,  3,  7,  4, 28,"Turn left", BT_KEY, 255 },
599         {  6, 15, 73, 71, 26,  4,  8, 29,  7,"Turn right", BT_KEY, 255 },
600         {  7, 15, 73,100, 26,  5,  9,  6, 34,"Turn right", BT_KEY, 255 },
601         {  8, 15, 85, 71, 26,  6, 10, 35,  9,"Slide on", BT_KEY, 255 },
602         {  9, 15, 85,100, 26,  7, 11,  8, 36,"Slide on", BT_KEY, 255 },
603         { 10, 15, 93, 71, 26,  8, 12, 37, 11,"Slide left", BT_KEY, 255 },
604         { 11, 15, 93,100, 26,  9, 13, 10, 44,"Slide left", BT_KEY, 255 },
605         { 12, 15,101, 71, 26, 10, 14, 45, 13,"Slide right", BT_KEY, 255 },
606         { 13, 15,101,100, 26, 11, 15, 12, 30,"Slide right", BT_KEY, 255 },
607         { 14, 15,109, 71, 26, 12, 16, 31, 15,"Slide up", BT_KEY, 255 },
608         { 15, 15,109,100, 26, 13, 17, 14, 32,"Slide up", BT_KEY, 255 },
609         { 16, 15,117, 71, 26, 14, 18, 33, 17,"Slide down", BT_KEY, 255 },
610         { 17, 15,117,100, 26, 15, 19, 16, 46,"Slide down", BT_KEY, 255 },
611         { 18, 15,129, 71, 26, 16, 20, 47, 19,"Bank on", BT_KEY, 255 },
612         { 19, 15,129,100, 26, 17, 21, 18, 38,"Bank on", BT_KEY, 255 },
613         { 20, 15,137, 71, 26, 18, 22, 39, 21,"Bank left", BT_KEY, 255 },
614         { 21, 15,137,100, 26, 19, 23, 20, 40,"Bank left", BT_KEY, 255 },
615         { 22, 15,145, 71, 26, 20, 48, 41, 23,"Bank right", BT_KEY, 255 },
616         { 23, 15,145,100, 26, 21, 49, 22, 42,"Bank right", BT_KEY, 255 },
617         { 24,158, 49, 83, 26, 51, 26,  1, 25,"Fire primary", BT_KEY, 255 },
618         { 25,158, 49,112, 26, 54, 27, 24,  2,"Fire primary", BT_KEY, 255 },
619         { 26,158, 57, 83, 26, 24, 28,  3, 27,"Fire secondary", BT_KEY, 255 },
620         { 27,158, 57,112, 26, 25, 29, 26,  4,"Fire secondary", BT_KEY, 255 },
621         { 28,158, 65, 83, 26, 26, 34,  5, 29,"Fire flare", BT_KEY, 255 },
622         { 29,158, 65,112, 26, 27, 35, 28,  6,"Fire flare", BT_KEY, 255 },
623         { 30,158,105, 83, 26, 44, 32, 13, 31,"Accelerate", BT_KEY, 255 },
624         { 31,158,105,112, 26, 45, 33, 30, 14,"Accelerate", BT_KEY, 255 },
625         { 32,158,113, 83, 26, 30, 46, 15, 33,"reverse", BT_KEY, 255 },
626         { 33,158,113,112, 26, 31, 47, 32, 16,"reverse", BT_KEY, 255 },
627         { 34,158, 73, 83, 26, 28, 36,  7, 35,"Drop Bomb", BT_KEY, 255 },
628         { 35,158, 73,112, 26, 29, 37, 34,  8,"Drop Bomb", BT_KEY, 255 },
629         { 36,158, 85, 83, 26, 34, 44,  9, 37,"REAR VIEW", BT_KEY, 255 },
630         { 37,158, 85,112, 26, 35, 45, 36, 10,"REAR VIEW", BT_KEY, 255 },
631         { 38,158,133, 83, 26, 46, 40, 19, 39,"Cruise Faster", BT_KEY, 255 },
632         { 39,158,133,112, 26, 47, 41, 38, 20,"Cruise Faster", BT_KEY, 255 },
633         { 40,158,141, 83, 26, 38, 42, 21, 41,"Cruise Slower", BT_KEY, 255 },
634         { 41,158,141,112, 26, 39, 43, 40, 22,"Cruise Slower", BT_KEY, 255 },
635         { 42,158,149, 83, 26, 40, 52, 23, 43,"Cruise Off", BT_KEY, 255 },
636         { 43,158,149,112, 26, 41, 53, 42, 48,"Cruise Off", BT_KEY, 255 },
637         { 44,158, 93, 83, 26, 36, 30, 11, 45,"Automap", BT_KEY, 255 },
638         { 45,158, 93,112, 26, 37, 31, 44, 12,"Automap", BT_KEY, 255 },
639         { 46,158,121, 83, 26, 32, 38, 17, 47,"Afterburner", BT_KEY, 255 },
640         { 47,158,121,112, 26, 33, 39, 46, 18,"Afterburner", BT_KEY, 255 },
641         { 48, 15,161, 71, 26, 22, 50, 43, 49,"Cycle Primary", BT_KEY, 255 },
642         { 49, 15,161,100, 26, 23, 51, 48, 52,"Cycle Primary", BT_KEY, 255 },
643         { 50, 15,169, 71, 26, 48,  1, 53, 51,"Cycle Second", BT_KEY, 255 },
644         { 51, 15,169,100, 26, 49, 24, 50, 54,"Cycle Second", BT_KEY, 255 },
645         { 52,158,163, 83, 26, 42, 54, 49, 53,"Headlight", BT_KEY, 255 },
646         { 53,158,163,112, 26, 43, 55, 52, 50,"Headlight", BT_KEY, 255 },
647         { 54,158,171, 83, 26, 52, 56, 51, 55,"Energy->Shield", BT_KEY, 255 },
648         { 55,158,171,112, 26, 53,  0, 54,  0,"Energy->Shield", BT_KEY, 255 },
649    { 56,158,179,83,  26, 54,  0, 0,  0, "Toggle Bomb",  BT_KEY,255},
650 };
651 kc_item kc_joystick[NUM_OTHER_CONTROLS] = {
652         {  0, 25, 46, 85, 26, 15,  1, 24,  5,"Fire primary", BT_JOY_BUTTON, 255 },
653         {  1, 25, 54, 85, 26,  0,  4,  5,  6,"Fire secondary", BT_JOY_BUTTON, 255 },
654         {  2, 25, 85, 85, 26, 26,  3,  9, 10,"Accelerate", BT_JOY_BUTTON, 255 },
655         {  3, 25, 93, 85, 26,  2, 25, 10, 11,"reverse", BT_JOY_BUTTON, 255 },
656         {  4, 25, 62, 85, 26,  1, 26,  6,  7,"Fire flare", BT_JOY_BUTTON, 255 },
657         {  5,180, 46, 79, 26, 23,  6,  0,  1,"Slide on", BT_JOY_BUTTON, 255 },
658         {  6,180, 54, 79, 26,  5,  7,  1,  4,"Slide left", BT_JOY_BUTTON, 255 },
659         {  7,180, 62, 79, 26,  6,  8,  4, 26,"Slide right", BT_JOY_BUTTON, 255 },
660         {  8,180, 70, 79, 26,  7,  9, 26,  9,"Slide up", BT_JOY_BUTTON, 255 },
661         {  9,180, 78, 79, 26,  8, 10,  8,  2,"Slide down", BT_JOY_BUTTON, 255 },
662         { 10,180, 90, 79, 26,  9, 11,  2,  3,"Bank on", BT_JOY_BUTTON, 255 },
663         { 11,180, 98, 79, 26, 10, 12,  3, 12,"Bank left", BT_JOY_BUTTON, 255 },
664         { 12,180,106, 79, 26, 11, 28, 11, 25,"Bank right", BT_JOY_BUTTON, 255 },
665         { 13, 22,154, 51, 26, 24, 15, 30, 14,"Pitch U/D", BT_JOY_AXIS, 255 },
666         { 14, 22,154, 99,  8, 30, 16, 13, 17,"Pitch U/D", BT_INVERT, 255 },
667         { 15, 22,162, 51, 26, 13,  0, 18, 16,"Turn L/R", BT_JOY_AXIS, 255 },
668         { 16, 22,162, 99,  8, 14, 17, 15, 19,"Turn L/R", BT_INVERT, 255 },
669         { 17,164,154, 58, 26, 16, 19, 14, 18,"Slide L/R", BT_JOY_AXIS, 255 },
670         { 18,164,154,106,  8, 29, 20, 17, 15,"Slide L/R", BT_INVERT, 255 },
671         { 19,164,162, 58, 26, 17, 21, 16, 20,"Slide U/D", BT_JOY_AXIS, 255 },
672         { 20,164,162,106,  8, 18, 22, 19, 21,"Slide U/D", BT_INVERT, 255 },
673         { 21,164,172, 58, 26, 19, 23, 20, 22,"Bank L/R", BT_JOY_AXIS, 255 },
674         { 22,164,172,106,  8, 20, 24, 21, 23,"Bank L/R", BT_INVERT, 255 },
675         { 23,164,180, 58, 26, 21,  5, 22, 24,"throttle", BT_JOY_AXIS, 255 },
676         { 24,164,180,106,  8, 22, 13, 23,  0,"throttle", BT_INVERT, 255 },
677         { 25, 25,109, 85, 26,  3, 27, 12, 28,"REAR VIEW", BT_JOY_BUTTON, 255 },
678         { 26, 25, 70, 85, 26,  4,  2,  7,  8,"Drop Bomb", BT_JOY_BUTTON, 255 },
679         { 27, 25,117, 85, 26, 25, 30, 28, 29,"Afterburner", BT_JOY_BUTTON, 255 },
680         { 28,180,114, 79, 26, 12, 29, 25, 27,"Cycle Primary", BT_JOY_BUTTON, 255 },
681         { 29,180,122, 79, 26, 28, 18, 27, 30,"Cycle Secondary", BT_JOY_BUTTON, 255 },
682         { 30, 25,125, 85, 26, 27, 14, 29, 13,"Headlight", BT_JOY_BUTTON, 255 },
683 };
684 kc_item kc_superjoy[NUM_OTHER_CONTROLS] = {
685         {  0, 25, 46, 85, 26, 15,  1, 24,  5,"Fire primary", BT_JOY_BUTTON, 255 },
686         {  1, 25, 54, 85, 26,  0,  4,  5,  6,"Fire secondary", BT_JOY_BUTTON, 255 },
687         {  2, 25, 85, 85, 26, 26,  3,  9, 10,"Accelerate", BT_JOY_BUTTON, 255 },
688         {  3, 25, 93, 85, 26,  2, 25, 10, 11,"reverse", BT_JOY_BUTTON, 255 },
689         {  4, 25, 62, 85, 26,  1, 26,  6,  7,"Fire flare", BT_JOY_BUTTON, 255 },
690         {  5,180, 46, 79, 26, 23,  6,  0,  1,"Slide on", BT_JOY_BUTTON, 255 },
691         {  6,180, 54, 79, 26,  5,  7,  1,  4,"Slide left", BT_JOY_BUTTON, 255 },
692         {  7,180, 62, 79, 26,  6,  8,  4, 26,"Slide right", BT_JOY_BUTTON, 255 },
693         {  8,180, 70, 79, 26,  7,  9, 26,  9,"Slide up", BT_JOY_BUTTON, 255 },
694         {  9,180, 78, 79, 26,  8, 10,  8,  2,"Slide down", BT_JOY_BUTTON, 255 },
695         { 10,180, 90, 79, 26,  9, 11,  2,  3,"Bank on", BT_JOY_BUTTON, 255 },
696         { 11,180, 98, 79, 26, 10, 12,  3, 12,"Bank left", BT_JOY_BUTTON, 255 },
697         { 12,180,106, 79, 26, 11, 28, 11, 25,"Bank right", BT_JOY_BUTTON, 255 },
698         { 13, 22,154, 51, 26, 24, 15, 30, 14,"Pitch U/D", BT_JOY_AXIS, 255 },
699         { 14, 22,154, 99,  8, 30, 16, 13, 17,"Pitch U/D", BT_INVERT, 255 },
700         { 15, 22,162, 51, 26, 13,  0, 18, 16,"Turn L/R", BT_JOY_AXIS, 255 },
701         { 16, 22,162, 99,  8, 14, 17, 15, 19,"Turn L/R", BT_INVERT, 255 },
702         { 17,164,154, 58, 26, 16, 19, 14, 18,"Slide L/R", BT_JOY_AXIS, 255 },
703         { 18,164,154,106,  8, 29, 20, 17, 15,"Slide L/R", BT_INVERT, 255 },
704         { 19,164,162, 58, 26, 17, 21, 16, 20,"Slide U/D", BT_JOY_AXIS, 255 },
705         { 20,164,162,106,  8, 18, 22, 19, 21,"Slide U/D", BT_INVERT, 255 },
706         { 21,164,172, 58, 26, 19, 23, 20, 22,"Bank L/R", BT_JOY_AXIS, 255 },
707         { 22,164,172,106,  8, 20, 24, 21, 23,"Bank L/R", BT_INVERT, 255 },
708         { 23,164,180, 58, 26, 21,  5, 22, 24,"throttle", BT_JOY_AXIS, 255 },
709         { 24,164,180,106,  8, 22, 13, 23,  0,"throttle", BT_INVERT, 255 },
710         { 25, 25,109, 85, 26,  3, 27, 12, 28,"REAR VIEW", BT_JOY_BUTTON, 255 },
711         { 26, 25, 70, 85, 26,  4,  2,  7,  8,"Drop Bomb", BT_JOY_BUTTON, 255 },
712         { 27, 25,117, 85, 26, 25, 30, 28, 29,"Afterburner", BT_JOY_BUTTON, 255 },
713         { 28,180,114, 79, 26, 12, 29, 25, 27,"Cycle Primary", BT_JOY_BUTTON, 255 },
714         { 29,180,122, 79, 26, 28, 18, 27, 30,"Cycle Secondary", BT_JOY_BUTTON, 255 },
715         { 30, 25,125, 85, 26, 27, 14, 29, 13,"Headlight", BT_JOY_BUTTON, 255 },
716 };
717
718 kc_item kc_mouse[NUM_OTHER_CONTROLS] = {
719         {  0, 25, 46, 85, 26, 12,  1, 24,  5,"Fire primary", BT_MOUSE_BUTTON, 255 },
720         {  1, 25, 54, 85, 26,  0,  4,  5,  6,"Fire secondary", BT_MOUSE_BUTTON, 255 },
721         {  2, 25, 85, 85, 26, 26,  3,  9, 10,"Accelerate", BT_MOUSE_BUTTON, 255 },
722         {  3, 25, 93, 85, 26,  2, 25, 10, 11,"reverse", BT_MOUSE_BUTTON, 255 },
723         {  4, 25, 62, 85, 26,  1, 26,  6,  7,"Fire flare", BT_MOUSE_BUTTON, 255 },
724         {  5,180, 46, 59, 26, 24,  6,  0,  1,"Slide on", BT_MOUSE_BUTTON, 255 },
725         {  6,180, 54, 59, 26,  5,  7,  1,  4,"Slide left", BT_MOUSE_BUTTON, 255 },
726         {  7,180, 62, 59, 26,  6,  8,  4, 26,"Slide right", BT_MOUSE_BUTTON, 255 },
727         {  8,180, 70, 59, 26,  7,  9, 26,  9,"Slide up", BT_MOUSE_BUTTON, 255 },
728         {  9,180, 78, 59, 26,  8, 10,  8,  2,"Slide down", BT_MOUSE_BUTTON, 255 },
729         { 10,180, 90, 59, 26,  9, 11,  2,  3,"Bank on", BT_MOUSE_BUTTON, 255 },
730         { 11,180, 98, 59, 26, 10, 12,  3, 12,"Bank left", BT_MOUSE_BUTTON, 255 },
731         { 12,180,106, 59, 26, 11,  0, 11, 25,"Bank right", BT_MOUSE_BUTTON, 255 },
732         { 13,103,138, 58, 26, 27, 15, 25, 14,"Pitch U/D", BT_MOUSE_AXIS, 255 },
733         { 14,103,138,106,  8, 23, 16, 13, 15,"Pitch U/D", BT_INVERT, 255 },
734         { 15,103,146, 58, 26, 13, 17, 14, 16,"Turn L/R", BT_MOUSE_AXIS, 255 },
735         { 16,103,146,106,  8, 14, 18, 15, 17,"Turn L/R", BT_INVERT, 255 },
736         { 17,103,154, 58, 26, 15, 19, 16, 18,"Slide L/R", BT_MOUSE_AXIS, 255 },
737         { 18,103,154,106,  8, 16, 20, 17, 19,"Slide L/R", BT_INVERT, 255 },
738         { 19,103,162, 58, 26, 17, 21, 18, 20,"Slide U/D", BT_MOUSE_AXIS, 255 },
739         { 20,103,162,106,  8, 18, 22, 19, 21,"Slide U/D", BT_INVERT, 255 },
740         { 21,103,170, 58, 26, 19, 23, 20, 22,"Bank L/R", BT_MOUSE_AXIS, 255 },
741         { 22,103,170,106,  8, 20, 24, 21, 23,"Bank L/R", BT_INVERT, 255 },
742         { 23,103,182, 58, 26, 21, 14, 22, 24,"throttle", BT_MOUSE_AXIS, 255 },
743         { 24,103,182,106,  8, 22,  5, 23,  0,"throttle", BT_INVERT, 255 },
744         { 25, 25,109, 85, 26,  3, 27, 12, 13,"REAR VIEW", BT_MOUSE_BUTTON, 255 },
745         { 26, 25, 70, 85, 26,  4,  2,  7,  8,"Drop Bomb", BT_MOUSE_BUTTON, 255 },
746         { 27, 25,117, 85, 26, 25, 13, 25, 13,"Afterburner", BT_MOUSE_BUTTON, 255 },
747 };
748
749 #else           // ifndef MACINTOSH (following are macintosh controls)
750
751 ubyte default_kconfig_settings[CONTROL_MAX_TYPES][MAX_CONTROLS] = {
752 {0x5b,0x7e,0x54,0x7d,0x56,0x7b,0x58,0x7c,0x3a,0xff,0xff,0x53,0xff,0x55,0xff,0x4e,0xff,0x45,0xff,0xff,0xc,0x59,0xe,0x5c,0x3b,0x24,0x31,0xff,0x3,0xff,0x3f,0xff,0x6,0xff,0xb,0xff,0xf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x30,0xff,0x1,0xff,0x2b,0xff,0x2f,0xff,0x4,0xff,0x11,0xff,0xff,0xff,0x0,0x0},
753 {0x0,0x1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1,0x0,0x0,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0,0x0,0x0,0x0},
754 {0x0,0x3,0xff,0xff,0xff,0xff,0xb,0xc,0x9,0xa,0xff,0x1,0x2,0x1,0x0,0x0,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0,0x0},
755 {0x5,0x4,0xff,0xff,0x6,0xff,0x3,0x2,0x0,0x1,0xff,0x8,0xa,0x1,0x0,0x0,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0x3,0x1,0xb,0x7,0xd,0xe,0xf,0xc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0,0x0,0x0,0x0,0x0},
756 {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1,0x0,0x0,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0,0x0,0x0,0x0,0x0},
757 {0x0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1,0x0,0x0,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0,0x0,0x0,0x0,0x0},
758 {0x0,0x1,0xff,0xff,0x2,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0,0x0,0x0,0x0},
759 };
760
761 ubyte default_firebird_settings[MAX_CONTROLS] =
762 {0x0,0x1,0xff,0xff,0x2,0xff,0x4,0x6,0x5,0x7,0xff,0xb,0xc,0x1,0x0,0x0,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0x03,0x0,0xff,0x3,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0,0x0,0x0,0x0,0x0};
763
764 ubyte default_mousestick_settings[MAX_CONTROLS] =
765 {0x2,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3,0x4,0x1,0x0,0x0,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0,0x0,0x0,0x0,0x0};
766
767 kc_item kc_keyboard[NUM_KEY_CONTROLS] = {
768         {  0, 15, 49, 71, 26, 55,  2, 55,  1,"Pitch forward", BT_KEY, 255 },
769         {  1, 15, 49,100, 26, 50,  3,  0, 24,"Pitch forward", BT_KEY, 255 },
770         {  2, 15, 57, 71, 26,  0,  4, 25,  3,"Pitch backward", BT_KEY, 255 },
771         {  3, 15, 57,100, 26,  1,  5,  2, 26,"Pitch backward", BT_KEY, 255 },
772         {  4, 15, 65, 71, 26,  2,  6, 27,  5,"Turn left", BT_KEY, 255 },
773         {  5, 15, 65,100, 26,  3,  7,  4, 28,"Turn left", BT_KEY, 255 },
774         {  6, 15, 73, 71, 26,  4,  8, 29,  7,"Turn right", BT_KEY, 255 },
775         {  7, 15, 73,100, 26,  5,  9,  6, 34,"Turn right", BT_KEY, 255 },
776         {  8, 15, 85, 71, 26,  6, 10, 35,  9,"Slide on", BT_KEY, 255 },
777         {  9, 15, 85,100, 26,  7, 11,  8, 36,"Slide on", BT_KEY, 255 },
778         { 10, 15, 93, 71, 26,  8, 12, 37, 11,"Slide left", BT_KEY, 255 },
779         { 11, 15, 93,100, 26,  9, 13, 10, 44,"Slide left", BT_KEY, 255 },
780         { 12, 15,101, 71, 26, 10, 14, 45, 13,"Slide right", BT_KEY, 255 },
781         { 13, 15,101,100, 26, 11, 15, 12, 30,"Slide right", BT_KEY, 255 },
782         { 14, 15,109, 71, 26, 12, 16, 31, 15,"Slide up", BT_KEY, 255 },
783         { 15, 15,109,100, 26, 13, 17, 14, 32,"Slide up", BT_KEY, 255 },
784         { 16, 15,117, 71, 26, 14, 18, 33, 17,"Slide down", BT_KEY, 255 },
785         { 17, 15,117,100, 26, 15, 19, 16, 46,"Slide down", BT_KEY, 255 },
786         { 18, 15,129, 71, 26, 16, 20, 47, 19,"Bank on", BT_KEY, 255 },
787         { 19, 15,129,100, 26, 17, 21, 18, 38,"Bank on", BT_KEY, 255 },
788         { 20, 15,137, 71, 26, 18, 22, 39, 21,"Bank left", BT_KEY, 255 },
789         { 21, 15,137,100, 26, 19, 23, 20, 40,"Bank left", BT_KEY, 255 },
790         { 22, 15,145, 71, 26, 20, 48, 41, 23,"Bank right", BT_KEY, 255 },
791         { 23, 15,145,100, 26, 21, 49, 22, 42,"Bank right", BT_KEY, 255 },
792         { 24,158, 49, 83, 26, 51, 26,  1, 25,"Fire primary", BT_KEY, 255 },
793         { 25,158, 49,112, 26, 54, 27, 24,  2,"Fire primary", BT_KEY, 255 },
794         { 26,158, 57, 83, 26, 24, 28,  3, 27,"Fire secondary", BT_KEY, 255 },
795         { 27,158, 57,112, 26, 25, 29, 26,  4,"Fire secondary", BT_KEY, 255 },
796         { 28,158, 65, 83, 26, 26, 34,  5, 29,"Fire flare", BT_KEY, 255 },
797         { 29,158, 65,112, 26, 27, 35, 28,  6,"Fire flare", BT_KEY, 255 },
798         { 30,158,105, 83, 26, 44, 32, 13, 31,"Accelerate", BT_KEY, 255 },
799         { 31,158,105,112, 26, 45, 33, 30, 14,"Accelerate", BT_KEY, 255 },
800         { 32,158,113, 83, 26, 30, 46, 15, 33,"reverse", BT_KEY, 255 },
801         { 33,158,113,112, 26, 31, 47, 32, 16,"reverse", BT_KEY, 255 },
802         { 34,158, 73, 83, 26, 28, 36,  7, 35,"Drop Bomb", BT_KEY, 255 },
803         { 35,158, 73,112, 26, 29, 37, 34,  8,"Drop Bomb", BT_KEY, 255 },
804         { 36,158, 85, 83, 26, 34, 44,  9, 37,"REAR VIEW", BT_KEY, 255 },
805         { 37,158, 85,112, 26, 35, 45, 36, 10,"REAR VIEW", BT_KEY, 255 },
806         { 38,158,133, 83, 26, 46, 40, 19, 39,"Cruise Faster", BT_KEY, 255 },
807         { 39,158,133,112, 26, 47, 41, 38, 20,"Cruise Faster", BT_KEY, 255 },
808         { 40,158,141, 83, 26, 38, 42, 21, 41,"Cruise Slower", BT_KEY, 255 },
809         { 41,158,141,112, 26, 39, 43, 40, 22,"Cruise Slower", BT_KEY, 255 },
810         { 42,158,149, 83, 26, 40, 52, 23, 43,"Cruise Off", BT_KEY, 255 },
811         { 43,158,149,112, 26, 41, 53, 42, 48,"Cruise Off", BT_KEY, 255 },
812         { 44,158, 93, 83, 26, 36, 30, 11, 45,"Automap", BT_KEY, 255 },
813         { 45,158, 93,112, 26, 37, 31, 44, 12,"Automap", BT_KEY, 255 },
814         { 46,158,121, 83, 26, 32, 38, 17, 47,"Afterburner", BT_KEY, 255 },
815         { 47,158,121,112, 26, 33, 39, 46, 18,"Afterburner", BT_KEY, 255 },
816         { 48, 15,161, 71, 26, 22, 50, 43, 49,"Cycle Primary", BT_KEY, 255 },
817         { 49, 15,161,100, 26, 23, 51, 48, 52,"Cycle Primary", BT_KEY, 255 },
818         { 50, 15,169, 71, 26, 48,  1, 53, 51,"Cycle Second", BT_KEY, 255 },
819         { 51, 15,169,100, 26, 49, 24, 50, 54,"Cycle Second", BT_KEY, 255 },
820         { 52,158,163, 83, 26, 42, 54, 49, 53,"Headlight", BT_KEY, 255 },
821         { 53,158,163,112, 26, 43, 55, 52, 50,"Headlight", BT_KEY, 255 },
822         { 54,158,171, 83, 26, 52, 25, 51, 55,"Energy->Shield", BT_KEY, 255 },
823         { 55,158,171,112, 26, 53,  0, 54,  0,"Energy->Shield", BT_KEY, 255 },
824 };
825 kc_item kc_joystick[NUM_OTHER_CONTROLS] = {
826         {  0, 25, 46, 85, 28, 15,  1, 24,  5,"Fire primary", BT_JOY_BUTTON, 255 },
827         {  1, 25, 54, 85, 28,  0,  4,  5,  6,"Fire secondary", BT_JOY_BUTTON, 255 },
828         {  2, 25, 85, 85, 28, 26,  3,  9, 10,"Accelerate", BT_JOY_BUTTON, 255 },
829         {  3, 25, 93, 85, 28,  2, 25, 10, 11,"reverse", BT_JOY_BUTTON, 255 },
830         {  4, 25, 62, 85, 28,  1, 26,  6,  7,"Fire flare", BT_JOY_BUTTON, 255 },
831         {  5,180, 46, 79, 28, 23,  6,  0,  1,"Slide on", BT_JOY_BUTTON, 255 },
832         {  6,180, 54, 79, 28,  5,  7,  1,  4,"Slide left", BT_JOY_BUTTON, 255 },
833         {  7,180, 62, 79, 28,  6,  8,  4, 26,"Slide right", BT_JOY_BUTTON, 255 },
834         {  8,180, 70, 79, 28,  7,  9, 26,  9,"Slide up", BT_JOY_BUTTON, 255 },
835         {  9,180, 78, 79, 28,  8, 10,  8,  2,"Slide down", BT_JOY_BUTTON, 255 },
836         { 10,180, 90, 79, 28,  9, 11,  2,  3,"Bank on", BT_JOY_BUTTON, 255 },
837         { 11,180, 98, 79, 28, 10, 12,  3, 12,"Bank left", BT_JOY_BUTTON, 255 },
838         { 12,180,106, 79, 28, 11, 28, 11, 25,"Bank right", BT_JOY_BUTTON, 255 },
839         { 13, 22,154, 51, 26, 24, 15, 30, 14,"Pitch U/D", BT_JOY_AXIS, 255 },
840         { 14, 22,154, 99,  8, 30, 16, 13, 17,"Pitch U/D", BT_INVERT, 255 },
841         { 15, 22,162, 51, 26, 13,  0, 18, 16,"Turn L/R", BT_JOY_AXIS, 255 },
842         { 16, 22,162, 99,  8, 14, 17, 15, 19,"Turn L/R", BT_INVERT, 255 },
843         { 17,164,154, 58, 26, 16, 19, 14, 18,"Slide L/R", BT_JOY_AXIS, 255 },
844         { 18,164,154,106,  8, 29, 20, 17, 15,"Slide L/R", BT_INVERT, 255 },
845         { 19,164,162, 58, 26, 17, 21, 16, 20,"Slide U/D", BT_JOY_AXIS, 255 },
846         { 20,164,162,106,  8, 18, 22, 19, 21,"Slide U/D", BT_INVERT, 255 },
847         { 21,164,172, 58, 26, 19, 23, 20, 22,"Bank L/R", BT_JOY_AXIS, 255 },
848         { 22,164,172,106,  8, 20, 24, 21, 23,"Bank L/R", BT_INVERT, 255 },
849         { 23,164,180, 58, 26, 21,  5, 22, 24,"throttle", BT_JOY_AXIS, 255 },
850         { 24,164,180,106,  8, 22, 13, 23,  0,"throttle", BT_INVERT, 255 },
851         { 25, 25,109, 85, 28,  3, 27, 12, 28,"REAR VIEW", BT_JOY_BUTTON, 255 },
852         { 26, 25, 70, 85, 28,  4,  2,  7,  8,"Drop Bomb", BT_JOY_BUTTON, 255 },
853         { 27, 25,117, 85, 28, 25, 30, 28, 29,"Afterburner", BT_JOY_BUTTON, 255 },
854         { 28,180,114, 79, 28, 12, 29, 25, 27,"Cycle Primary", BT_JOY_BUTTON, 255 },
855         { 29,180,122, 79, 28, 28, 18, 27, 30,"Cycle Secondary", BT_JOY_BUTTON, 255 },
856         { 30, 25,125, 85, 28, 27, 14, 29, 13,"Headlight", BT_JOY_BUTTON, 255 },
857 };
858 kc_item kc_superjoy[NUM_OTHER_CONTROLS] = {
859         {  0, 25, 46, 85, 26, 15,  1, 24,  5,"Fire primary", BT_JOY_BUTTON, 255 },
860         {  1, 25, 54, 85, 26,  0,  4,  5,  6,"Fire secondary", BT_JOY_BUTTON, 255 },
861         {  2, 25, 85, 85, 26, 26,  3,  9, 10,"Accelerate", BT_JOY_BUTTON, 255 },
862         {  3, 25, 93, 85, 26,  2, 25, 10, 11,"reverse", BT_JOY_BUTTON, 255 },
863         {  4, 25, 62, 85, 26,  1, 26,  6,  7,"Fire flare", BT_JOY_BUTTON, 255 },
864         {  5,180, 46, 79, 26, 23,  6,  0,  1,"Slide on", BT_JOY_BUTTON, 255 },
865         {  6,180, 54, 79, 26,  5,  7,  1,  4,"Slide left", BT_JOY_BUTTON, 255 },
866         {  7,180, 62, 79, 26,  6,  8,  4, 26,"Slide right", BT_JOY_BUTTON, 255 },
867         {  8,180, 70, 79, 26,  7,  9, 26,  9,"Slide up", BT_JOY_BUTTON, 255 },
868         {  9,180, 78, 79, 26,  8, 10,  8,  2,"Slide down", BT_JOY_BUTTON, 255 },
869         { 10,180, 90, 79, 26,  9, 11,  2,  3,"Bank on", BT_JOY_BUTTON, 255 },
870         { 11,180, 98, 79, 26, 10, 12,  3, 12,"Bank left", BT_JOY_BUTTON, 255 },
871         { 12,180,106, 79, 26, 11, 28, 11, 25,"Bank right", BT_JOY_BUTTON, 255 },
872         { 13, 22,154, 51, 26, 24, 15, 30, 14,"Pitch U/D", BT_JOY_AXIS, 255 },
873         { 14, 22,154, 99,  8, 30, 16, 13, 17,"Pitch U/D", BT_INVERT, 255 },
874         { 15, 22,162, 51, 26, 13,  0, 18, 16,"Turn L/R", BT_JOY_AXIS, 255 },
875         { 16, 22,162, 99,  8, 14, 17, 15, 19,"Turn L/R", BT_INVERT, 255 },
876         { 17,164,154, 58, 26, 16, 19, 14, 18,"Slide L/R", BT_JOY_AXIS, 255 },
877         { 18,164,154,106,  8, 29, 20, 17, 15,"Slide L/R", BT_INVERT, 255 },
878         { 19,164,162, 58, 26, 17, 21, 16, 20,"Slide U/D", BT_JOY_AXIS, 255 },
879         { 20,164,162,106,  8, 18, 22, 19, 21,"Slide U/D", BT_INVERT, 255 },
880         { 21,164,172, 58, 26, 19, 23, 20, 22,"Bank L/R", BT_JOY_AXIS, 255 },
881         { 22,164,172,106,  8, 20, 24, 21, 23,"Bank L/R", BT_INVERT, 255 },
882         { 23,164,180, 58, 26, 21,  5, 22, 24,"throttle", BT_JOY_AXIS, 255 },
883         { 24,164,180,106,  8, 22, 13, 23,  0,"throttle", BT_INVERT, 255 },
884         { 25, 25,109, 85, 26,  3, 27, 12, 28,"REAR VIEW", BT_JOY_BUTTON, 255 },
885         { 26, 25, 70, 85, 26,  4,  2,  7,  8,"Drop Bomb", BT_JOY_BUTTON, 255 },
886         { 27, 25,117, 85, 26, 25, 30, 28, 29,"Afterburner", BT_JOY_BUTTON, 255 },
887         { 28,180,114, 79, 26, 12, 29, 25, 27,"Cycle Primary", BT_JOY_BUTTON, 255 },
888         { 29,180,122, 79, 26, 28, 18, 27, 30,"Cycle Secondary", BT_JOY_BUTTON, 255 },
889         { 30, 25,125, 85, 26, 27, 14, 29, 13,"Headlight", BT_JOY_BUTTON, 255 },
890 };
891
892 kc_item kc_mouse[NUM_OTHER_CONTROLS] = {
893         {  0, 25, 46, 85, 26, 28,  1, 28,  5,"Fire primary", BT_MOUSE_BUTTON, 255 },
894         {  1, 25, 54, 85, 26,  0,  4,  5,  6,"Fire secondary", BT_MOUSE_BUTTON, 255 },
895         {  2, 25, 85, 85, 26, 26,  3,  9, 10,"Accelerate", BT_MOUSE_BUTTON, 255 },
896         {  3, 25, 93, 85, 26,  2, 25, 10, 11,"reverse", BT_MOUSE_BUTTON, 255 },
897         {  4, 25, 62, 85, 26,  1, 26,  6,  7,"Fire flare", BT_MOUSE_BUTTON, 255 },
898         {  5,180, 46, 59, 26, 24,  6,  0,  1,"Slide on", BT_MOUSE_BUTTON, 255 },
899         {  6,180, 54, 59, 26,  5,  7,  1,  4,"Slide left", BT_MOUSE_BUTTON, 255 },
900         {  7,180, 62, 59, 26,  6,  8,  4, 26,"Slide right", BT_MOUSE_BUTTON, 255 },
901         {  8,180, 70, 59, 26,  7,  9, 26,  9,"Slide up", BT_MOUSE_BUTTON, 255 },
902         {  9,180, 78, 59, 26,  8, 10,  8,  2,"Slide down", BT_MOUSE_BUTTON, 255 },
903         { 10,180, 90, 59, 26,  9, 11,  2,  3,"Bank on", BT_MOUSE_BUTTON, 255 },
904         { 11,180, 98, 59, 26, 10, 12,  3, 12,"Bank left", BT_MOUSE_BUTTON, 255 },
905         { 12,180,106, 59, 26, 11, 28, 11, 25,"Bank right", BT_MOUSE_BUTTON, 255 },
906         { 13,103,138, 58, 26, 27, 15, 27, 14,"Pitch U/D", BT_MOUSE_AXIS, 255 },
907         { 14,103,138,106,  8, 23, 16, 13, 15,"Pitch U/D", BT_INVERT, 255 },
908         { 15,103,146, 58, 26, 13, 17, 14, 16,"Turn L/R", BT_MOUSE_AXIS, 255 },
909         { 16,103,146,106,  8, 14, 18, 15, 17,"Turn L/R", BT_INVERT, 255 },
910         { 17,103,154, 58, 26, 15, 19, 16, 18,"Slide L/R", BT_MOUSE_AXIS, 255 },
911         { 18,103,154,106,  8, 16, 20, 17, 19,"Slide L/R", BT_INVERT, 255 },
912         { 19,103,162, 58, 26, 17, 21, 18, 20,"Slide U/D", BT_MOUSE_AXIS, 255 },
913         { 20,103,162,106,  8, 18, 22, 19, 21,"Slide U/D", BT_INVERT, 255 },
914         { 21,103,170, 58, 26, 19, 23, 20, 22,"Bank L/R", BT_MOUSE_AXIS, 255 },
915         { 22,103,170,106,  8, 20, 24, 21, 23,"Bank L/R", BT_INVERT, 255 },
916         { 23,103,182, 58, 26, 21, 14, 22, 24,"throttle", BT_MOUSE_AXIS, 255 },
917         { 24,103,182,106,  8, 22,  5, 23, 28,"throttle", BT_INVERT, 255 },
918         { 25, 25,109, 85, 26,  3, 27, 12, 27,"REAR VIEW", BT_MOUSE_BUTTON, 255 },
919         { 26, 25, 70, 85, 26,  4,  2,  7,  8,"Drop Bomb", BT_MOUSE_BUTTON, 255 },
920         { 27, 25,117, 85, 26, 25, 13, 25, 13,"Afterburner", BT_MOUSE_BUTTON, 255 },
921 };
922
923 #endif
924
925 void kc_drawitem( kc_item *item, int is_current );
926 void kc_change_key( kc_item * item );
927 void kc_change_joybutton( kc_item * item );
928 void kc_change_mousebutton( kc_item * item );
929 void kc_change_joyaxis( kc_item * item );
930 void kc_change_mouseaxis( kc_item * item );
931 void kc_change_invert( kc_item * item );
932 void kconfig_read_fcs( int raw_axis );
933 void kconfig_set_fcs_button( int btn, int button );
934 void kconfig_read_external_controls( void );
935
936 int kconfig_is_axes_used(int axis)
937 {
938         int i;
939         for (i=0; i<NUM_OTHER_CONTROLS; i++ )   {
940                 if (( kc_joystick[i].type == BT_JOY_AXIS ) && (kc_joystick[i].value == axis ))
941                         return 1;
942         }
943         return 0;
944 }
945
946 #ifdef TABLE_CREATION
947 int find_item_at( kc_item * items, int nitems, int x, int y )
948 {
949         int i;
950         
951         for (i=0; i<nitems; i++ )       {
952                 if ( ((items[i].x+items[i].w1)==x) && (items[i].y==y))
953                         return i;
954         }
955         return -1;
956 }
957
958 int find_next_item_up( kc_item * items, int nitems, int citem )
959 {
960         int x, y, i;
961
962         y = items[citem].y;
963         x = items[citem].x+items[citem].w1;
964         
965         do {    
966                 y--;
967                 if ( y < 0 ) {
968                         y = grd_curcanv->cv_bitmap.bm_h-1;
969                         x--;
970                         if ( x < 0 ) {
971                                 x = grd_curcanv->cv_bitmap.bm_w-1;
972                         }
973                 }
974                 i = find_item_at( items, nitems, x, y );
975         } while ( i < 0 );
976         
977         return i;
978 }
979
980 int find_next_item_down( kc_item * items, int nitems, int citem )
981 {
982         int x, y, i;
983
984         y = items[citem].y;
985         x = items[citem].x+items[citem].w1;
986         
987         do {    
988                 y++;
989                 if ( y > grd_curcanv->cv_bitmap.bm_h-1 ) {
990                         y = 0;
991                         x++;
992                         if ( x > grd_curcanv->cv_bitmap.bm_w-1 ) {
993                                 x = 0;
994                         }
995                 }
996                 i = find_item_at( items, nitems, x, y );
997         } while ( i < 0 );
998         
999         return i;
1000 }
1001
1002 int find_next_item_right( kc_item * items, int nitems, int citem )
1003 {
1004         int x, y, i;
1005
1006         y = items[citem].y;
1007         x = items[citem].x+items[citem].w1;
1008         
1009         do {    
1010                 x++;
1011                 if ( x > grd_curcanv->cv_bitmap.bm_w-1 ) {
1012                         x = 0;
1013                         y++;
1014                         if ( y > grd_curcanv->cv_bitmap.bm_h-1 ) {
1015                                 y = 0;
1016                         }
1017                 }
1018                 i = find_item_at( items, nitems, x, y );
1019         } while ( i < 0 );
1020         
1021         return i;
1022 }
1023
1024 int find_next_item_left( kc_item * items, int nitems, int citem )
1025 {
1026         int x, y, i;
1027
1028         y = items[citem].y;
1029         x = items[citem].x+items[citem].w1;
1030         
1031         do {    
1032                 x--;
1033                 if ( x < 0 ) {
1034                         x = grd_curcanv->cv_bitmap.bm_w-1;
1035                         y--;
1036                         if ( y < 0 ) {
1037                                 y = grd_curcanv->cv_bitmap.bm_h-1;
1038                         }
1039                 }
1040                 i = find_item_at( items, nitems, x, y );
1041         } while ( i < 0 );
1042         
1043         return i;
1044 }
1045 #endif
1046
1047 #if defined(MACINTOSH) || defined(WINDOWS)
1048 int get_item_height(kc_item *item)
1049 {
1050         int w, h, aw;
1051         char btext[10];
1052
1053         if (item->value==255) {
1054                 sprintf( btext, "" );
1055         } else {
1056                 switch( item->type )    {
1057                         case BT_KEY:
1058                                 strncpy( btext, key_text[item->value], 10 ); break;
1059                         case BT_MOUSE_BUTTON:
1060                         #ifdef WINDOWS
1061                                 strncpy( btext, Text_string[mousebutton_text[item->value]], 10); break;
1062                         #else
1063                                 strncpy( btext, mousebutton_text[item->value], 10 ); break;
1064                         #endif
1065                         case BT_MOUSE_AXIS:
1066                                 strncpy( btext, Text_string[mouseaxis_text[item->value]], 10 ); break;
1067                         case BT_JOY_BUTTON:
1068                                 if ( joybutton_text[item->value] !=-1 )
1069                                         strncpy( btext, Text_string[ joybutton_text[item->value]  ], 10 );
1070                                 else
1071                                         sprintf( btext, "BTN%d", item->value );
1072                                 break;
1073                         case BT_JOY_AXIS:
1074                                 strncpy( btext, Text_string[joyaxis_text[item->value]], 10 ); break;
1075                         case BT_INVERT:
1076                                 strncpy( btext, Text_string[invert_text[item->value]], 10 ); break;
1077                 }
1078         }
1079         gr_get_string_size(btext, &w, &h, &aw  );
1080
1081         return h;
1082 }
1083 #endif
1084
1085 void kconfig_sub(kc_item * items,int nitems, char * title)
1086 {
1087 WINDOS(
1088         dd_grs_canvas * save_canvas,
1089         grs_canvas * save_canvas
1090 );
1091         grs_font * save_font;
1092         int old_keyd_repeat;
1093         #if defined(MACINTOSH) || defined(WINDOWS) 
1094         int mouse_state, omouse_state, mx, my, x1, x2, y1, y2;
1095         int close_x, close_y, close_size;
1096         #endif
1097
1098         int i,k,ocitem,citem;
1099         int time_stopped = 0;
1100 WIN(char *old_bg_pcx);
1101
1102 WIN(old_bg_pcx = _SCRContext.bkg_filename);
1103 WIN(DEFINE_SCREEN(NULL));
1104
1105         All_items = items;
1106         Num_items = nitems;
1107
1108         if (!((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME) && (!Endlevel_sequence)) )
1109         {
1110                 time_stopped = 1;
1111                 stop_time();
1112         }
1113
1114 //      if (Config_control_type == CONTROL_WINJOYSTICK) {
1115 //              WINDOS(
1116 //                      joydefsw_win_joyselect(title2); title = title2,
1117 //                      Int3()
1118 //              );                                                                                              // Get Samir...
1119 //      }
1120
1121 WINDOS(
1122         save_canvas = dd_grd_curcanv,
1123         save_canvas = grd_curcanv
1124 );
1125
1126
1127 WINDOS(
1128         dd_gr_set_current_canvas(NULL),
1129         gr_set_current_canvas(NULL)
1130 );              
1131         save_font = grd_curcanv->cv_font;
1132
1133 #ifdef WINDOWS
1134 KConfigPaint:
1135 #endif
1136         game_flush_inputs();
1137         old_keyd_repeat = keyd_repeat;
1138         keyd_repeat = 1;
1139
1140         //gr_clear_canvas( BM_XRGB(0,0,0) );
1141
1142         nm_draw_background(0,0,grd_curcanv->cv_bitmap.bm_w, grd_curcanv->cv_bitmap.bm_h );
1143    gr_palette_load (gr_palette);
1144
1145         grd_curcanv->cv_font = MEDIUM3_FONT;
1146
1147 WIN(DDGRLOCK(dd_grd_curcanv));  
1148         {
1149                 char * p;
1150                 p = strchr( title, '\n' );
1151                 if ( p ) *p = 32;
1152                 gr_string( 0x8000, LHY(8), title );
1153                 if ( p ) *p = '\n';
1154         }
1155
1156
1157 //      if ( items == kc_keyboard )     {
1158 //              gr_string( 0x8000, 8, "Keyboard" );
1159 //      } else if ( items == kc_joystick )      {
1160 //              gr_string( 0x8000, 8, "Joysticks" );
1161 //      } else if ( items == kc_mouse ) {
1162 //              gr_string( 0x8000, 8, "Mouse" );
1163 //      }
1164
1165 #if defined(MACINTOSH) || defined(WINDOWS)
1166         close_x = close_y = 15;
1167         close_size = 10;
1168         gr_setcolor( BM_XRGB(0, 0, 0) );
1169         gr_rect(close_x, close_y, close_x + close_size, close_y + close_size);
1170         gr_setcolor( BM_XRGB(21, 21, 21) );
1171         gr_rect( close_x + 2, close_y + 2, close_x + close_size - 2, close_y + close_size -2 );
1172         #endif
1173
1174         grd_curcanv->cv_font = GAME_FONT;
1175         gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
1176
1177         #ifndef MACINTOSH
1178         gr_string( 0x8000, LHY(20), TXT_KCONFIG_STRING_1 );
1179         #else
1180         gr_string( 0x8000, LHY(20), "Enter changes, ctrl-d deletes, ctrl-r resets defaults, ESC exits");
1181         #endif
1182         gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
1183         if ( items == kc_keyboard )     {
1184                 gr_set_fontcolor( BM_XRGB(31,27,6), -1 );
1185                 gr_setcolor( BM_XRGB(31,27,6) );
1186                 
1187                 gr_scanline( LHX(98), LHX(106), LHY(42) );
1188                 gr_scanline( LHX(120), LHX(128), LHY(42) );
1189                 gr_pixel( LHX(98), LHY(43) );                                           
1190                 gr_pixel( LHX(98), LHY(44) );                                           
1191                 gr_pixel( LHX(128), LHY(43) );                                          
1192                 gr_pixel( LHX(128), LHY(44) );                                          
1193                 
1194                 gr_string( LHX(109), LHY(40), "OR" );
1195
1196                 gr_scanline( LHX(253), LHX(261), LHY(42) );
1197                 gr_scanline( LHX(274), LHX(283), LHY(42) );
1198                 gr_pixel( LHX(253), LHY(43) );                                          
1199                 gr_pixel( LHX(253), LHY(44) );                                          
1200                 gr_pixel( LHX(283), LHY(43) );                                          
1201                 gr_pixel( LHX(283), LHY(44) );                                          
1202
1203                 gr_string( LHX(264), LHY(40), "OR" );
1204
1205         } if ( items == kc_joystick )   {
1206                 gr_set_fontcolor( BM_XRGB(31,27,6), -1 );
1207                 gr_setcolor( BM_XRGB(31,27,6) );
1208                 gr_scanline( LHX(18), LHX(135), LHY(37) );
1209                 gr_scanline( LHX(181), LHX(294), LHY(37) );
1210                 gr_scanline( LHX(18), LHX(144), LHY(119+18) );
1211                 gr_scanline( LHX(174), LHX(294), LHY(119+18) );
1212                 gr_string( 0x8000, LHY(35), TXT_BUTTONS );
1213                 gr_string( 0x8000,LHY(117+18), TXT_AXES );
1214                 gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
1215                 gr_string( LHX(81), LHY(137+8), TXT_AXIS );
1216                 gr_string( LHX(111), LHY(137+8), TXT_INVERT );
1217                 gr_string( LHX(222), LHY(137+8), TXT_AXIS );
1218                 gr_string( LHX(252), LHY(137+8), TXT_INVERT );
1219         } else if ( items == kc_mouse ) {
1220                 gr_set_fontcolor( BM_XRGB(31,27,6), -1 );
1221                 gr_setcolor( BM_XRGB(31,27,6) );
1222                 gr_scanline( LHX(18), LHX(135), LHY(37) );
1223                 gr_scanline( LHX(181), LHX(294), LHY(37) );
1224                 gr_scanline( LHX(18), LHX(144), LHY(119+5) );
1225                 gr_scanline( LHX(174), LHX(294), LHY(119+5) );
1226                 gr_string( 0x8000, LHY(35), TXT_BUTTONS );
1227                 gr_string( 0x8000,LHY(117+5), TXT_AXES );
1228                 gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
1229                 gr_string( LHX(169), LHY(129), TXT_AXIS );
1230                 gr_string( LHX(199), LHY(129), TXT_INVERT );
1231         }
1232 WIN(DDGRUNLOCK(dd_grd_curcanv));        
1233
1234         for (i=0; i<nitems; i++ )       {
1235                 kc_drawitem( &items[i], 0 );
1236         }
1237
1238         citem = 0;
1239         kc_drawitem( &items[citem], 1 );
1240         
1241         WIN(ShowCursorW());
1242         MAC(show_cursor();)
1243
1244 #if defined(MACINTOSH) || defined(WINDOWS) 
1245         mouse_state = omouse_state = 0;
1246 #endif
1247
1248         while(1)                {
1249         //      Windows addendum to allow for kconfig input.
1250         #ifdef WINDOWS
1251                 {
1252                         MSG msg;
1253
1254                         DoMessageStuff(&msg);
1255
1256                         if (_RedrawScreen) {
1257                                 _RedrawScreen = FALSE;
1258
1259                                 dd_gr_set_current_canvas(NULL); 
1260
1261                                 goto KConfigPaint;
1262                         }
1263
1264                         DDGRRESTORE;
1265                 }
1266         #endif
1267                 gr_update();
1268
1269                 //see if redbook song needs to be restarted
1270                 songs_check_redbook_repeat();
1271
1272                 k = key_inkey();
1273                 
1274 #if defined(MACINTOSH) || defined(WINDOWS)
1275                 omouse_state = mouse_state;
1276                 mouse_state = mouse_button_state(0);
1277 #endif
1278                 
1279                 if ( !time_stopped ) {
1280                         #ifdef NETWORK
1281                         if (multi_menu_poll() == -1)
1282                                 k = -2;
1283                         #endif
1284                 }
1285                 ocitem = citem;
1286                 switch( k )     {
1287                 case KEY_BACKSP:
1288                         Int3();
1289                         break;
1290                 MAC(case KEY_COMMAND+KEY_SHIFTED+KEY_3:)
1291                 case KEY_PRINT_SCREEN:
1292                         save_screen_shot(0);
1293                         break;                                                  
1294                 case KEY_CTRLED+KEY_D:
1295                         items[citem].value = 255;
1296                         kc_drawitem( &items[citem], 1 );
1297                         break;
1298                 case KEY_CTRLED+KEY_R:  
1299                         if ( items==kc_keyboard )       {
1300                                 for (i=0; i<NUM_KEY_CONTROLS; i++ )             {
1301                                         items[i].value=default_kconfig_settings[0][i];
1302                                         kc_drawitem( &items[i], 0 );
1303                                 }
1304                         } else {
1305                                 #ifdef MACINTOSH
1306                           // hack for firebire and mousestick default controls since I made
1307                           // them the same control type -- dumb dumb dumb
1308                                 if (joy_have_firebird())
1309                                         for (i=0; i<NUM_OTHER_CONTROLS; i++ )   {
1310                                                 items[i].value = default_firebird_settings[i];
1311                                                 kc_drawitem( &items[i], 0 );
1312                                         }
1313                                 else if (joy_have_mousestick())
1314                                         for (i=0; i<NUM_OTHER_CONTROLS; i++ )   {
1315                                                 items[i].value = default_mousestick_settings[i];
1316                                                 kc_drawitem( &items[i], 0 );
1317                                         }
1318                                 else
1319                                 #endif  // note link to above else
1320                                         for (i=0; i<NUM_OTHER_CONTROLS; i++ )   {
1321                                                 items[i].value = default_kconfig_settings[Config_control_type][i];
1322                                                 kc_drawitem( &items[i], 0 );
1323                                         }
1324                         }
1325                         kc_drawitem( &items[citem], 1 );
1326                         break;
1327                 case KEY_DELETE:
1328                         items[citem].value=255;
1329                         kc_drawitem( &items[citem], 1 );
1330                         break;
1331                 case KEY_UP:            
1332                 case KEY_PAD8:
1333 #ifdef TABLE_CREATION
1334                         if (items[citem].u==-1) items[citem].u=find_next_item_up( items,nitems, citem);
1335 #endif
1336                         citem = items[citem].u; 
1337                         break;
1338                 
1339                 case KEY_DOWN:  
1340                 case KEY_PAD2:
1341 #ifdef TABLE_CREATION
1342                         if (items[citem].d==-1) items[citem].d=find_next_item_down( items,nitems, citem);
1343 #endif
1344                         citem = items[citem].d; 
1345                         break;
1346                 case KEY_LEFT:  
1347                 case KEY_PAD4:
1348 #ifdef TABLE_CREATION
1349                         if (items[citem].l==-1) items[citem].l=find_next_item_left( items,nitems, citem);
1350 #endif
1351                         citem = items[citem].l; 
1352                         break;
1353                 case KEY_RIGHT:         
1354                 case KEY_PAD6:
1355 #ifdef TABLE_CREATION
1356                         if (items[citem].r==-1) items[citem].r=find_next_item_right( items,nitems, citem);
1357 #endif
1358                         citem = items[citem].r; 
1359                         break;
1360                 case KEY_ENTER: 
1361                 case KEY_PADENTER:      
1362                         switch( items[citem].type )     {
1363                         case BT_KEY:            kc_change_key( &items[citem] ); break;
1364                         case BT_MOUSE_BUTTON:   kc_change_mousebutton( &items[citem] ); break;
1365                         case BT_MOUSE_AXIS:     kc_change_mouseaxis( &items[citem] ); break;
1366                         case BT_JOY_BUTTON:     kc_change_joybutton( &items[citem] ); break;
1367                         case BT_JOY_AXIS:       kc_change_joyaxis( &items[citem] ); break;
1368                         case BT_INVERT:         kc_change_invert( &items[citem] ); break;
1369                         }
1370                         break;
1371                 case -2:        
1372                 case KEY_ESC:
1373                         grd_curcanv->cv_font    = save_font;
1374
1375                 WIN(DEFINE_SCREEN(old_bg_pcx));
1376
1377                 WINDOS(
1378                         dd_gr_set_current_canvas(save_canvas),
1379                         gr_set_current_canvas( save_canvas )
1380                 );                      
1381                         keyd_repeat = old_keyd_repeat;
1382                         game_flush_inputs();
1383                         WIN( HideCursorW());
1384                         MAC( hide_cursor(); )
1385                         if (time_stopped)
1386                                 start_time();
1387                         return;
1388 #ifdef TABLE_CREATION
1389                 case KEY_DEBUGGED+KEY_F12:      {
1390                         FILE * fp;
1391                         for (i=0; i<NUM_KEY_CONTROLS; i++ )     {
1392                                 kc_keyboard[i].u = find_next_item_up( kc_keyboard,NUM_KEY_CONTROLS, i);
1393                                 kc_keyboard[i].d = find_next_item_down( kc_keyboard,NUM_KEY_CONTROLS, i);
1394                                 kc_keyboard[i].l = find_next_item_left( kc_keyboard,NUM_KEY_CONTROLS, i);
1395                                 kc_keyboard[i].r = find_next_item_right( kc_keyboard,NUM_KEY_CONTROLS, i);
1396                         }
1397                         for (i=0; i<NUM_OTHER_CONTROLS; i++ )   {
1398                                 kc_joystick[i].u = find_next_item_up( kc_joystick,NUM_OTHER_CONTROLS, i);
1399                                 kc_joystick[i].d = find_next_item_down( kc_joystick,NUM_OTHER_CONTROLS, i);
1400                                 kc_joystick[i].l = find_next_item_left( kc_joystick,NUM_OTHER_CONTROLS, i);
1401                                 kc_joystick[i].r = find_next_item_right( kc_joystick,NUM_OTHER_CONTROLS, i);
1402                         }
1403                         for (i=0; i<NUM_OTHER_CONTROLS; i++ )   {
1404                                 kc_mouse[i].u = find_next_item_up( kc_mouse,NUM_OTHER_CONTROLS, i);
1405                                 kc_mouse[i].d = find_next_item_down( kc_mouse,NUM_OTHER_CONTROLS, i);
1406                                 kc_mouse[i].l = find_next_item_left( kc_mouse,NUM_OTHER_CONTROLS, i);
1407                                 kc_mouse[i].r = find_next_item_right( kc_mouse,NUM_OTHER_CONTROLS, i);
1408                         }
1409                         fp = fopen( "kconfig.cod", "wt" );
1410
1411                         fprintf( fp, "ubyte default_kconfig_settings[CONTROL_MAX_TYPES][MAX_CONTROLS] = {\n" );
1412                         for (i=0; i<CONTROL_MAX_TYPES; i++ )    {
1413                                 int j;
1414                                 fprintf( fp, "{0x%x", kconfig_settings[i][0] );
1415                                 for (j=1; j<MAX_CONTROLS; j++ )
1416                                         fprintf( fp, ",0x%x", kconfig_settings[i][j] );
1417                                 fprintf( fp, "},\n" );
1418                         }
1419                         fprintf( fp, "};\n" );
1420                 
1421                         fprintf( fp, "\nkc_item kc_keyboard[NUM_KEY_CONTROLS] = {\n" );
1422                         for (i=0; i<NUM_KEY_CONTROLS; i++ )     {
1423                                 fprintf( fp, "\t{ %2d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%c%s%c, %s, 255 },\n", 
1424                                         kc_keyboard[i].id, kc_keyboard[i].x, kc_keyboard[i].y, kc_keyboard[i].w1, kc_keyboard[i].w2,
1425                                         kc_keyboard[i].u, kc_keyboard[i].d, kc_keyboard[i].l, kc_keyboard[i].r,
1426                                         34, kc_keyboard[i].text, 34, btype_text[kc_keyboard[i].type] );
1427                         }
1428                         fprintf( fp, "};" );
1429
1430                         fprintf( fp, "\nkc_item kc_joystick[NUM_OTHER_CONTROLS] = {\n" );
1431                         for (i=0; i<NUM_OTHER_CONTROLS; i++ )   {
1432                                 if (kc_joystick[i].type == BT_JOY_BUTTON)
1433                                         fprintf( fp, "\t{ %2d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%c%s%c, %s, 255 },\n", 
1434                                                 kc_joystick[i].id, kc_joystick[i].x, kc_joystick[i].y, kc_joystick[i].w1, kc_joystick[i].w2,
1435                                                 kc_joystick[i].u, kc_joystick[i].d, kc_joystick[i].l, kc_joystick[i].r,
1436                                                 34, kc_joystick[i].text, 34, btype_text[kc_joystick[i].type] );
1437                 else
1438                                         fprintf( fp, "\t{ %2d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%c%s%c, %s, 255 },\n", 
1439                                                 kc_joystick[i].id, kc_joystick[i].x, kc_joystick[i].y, kc_joystick[i].w1, kc_joystick[i].w2,
1440                                                 kc_joystick[i].u, kc_joystick[i].d, kc_joystick[i].l, kc_joystick[i].r,
1441                                                 34, kc_joystick[i].text, 34, btype_text[kc_joystick[i].type] );
1442                         }
1443                         fprintf( fp, "};" );
1444
1445                         fprintf( fp, "\nkc_item kc_mouse[NUM_OTHER_CONTROLS] = {\n" );
1446                         for (i=0; i<NUM_OTHER_CONTROLS; i++ )   {
1447                                 fprintf( fp, "\t{ %2d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%c%s%c, %s, 255 },\n", 
1448                                         kc_mouse[i].id, kc_mouse[i].x, kc_mouse[i].y, kc_mouse[i].w1, kc_mouse[i].w2,
1449                                         kc_mouse[i].u, kc_mouse[i].d, kc_mouse[i].l, kc_mouse[i].r,
1450                                         34, kc_mouse[i].text, 34, btype_text[kc_mouse[i].type] );
1451                         }
1452                         fprintf( fp, "};" );
1453
1454                         fclose(fp);
1455
1456                         }
1457                         break;
1458 #endif
1459                 }
1460
1461         #if defined (MACINTOSH) || defined(WINDOWS)
1462                 if ( (mouse_state && !omouse_state) || (mouse_state && omouse_state) ) {
1463                         int item_height;
1464                         
1465                         mouse_get_pos(&mx, &my);
1466                         for (i=0; i<nitems; i++ )       {
1467                                 item_height = get_item_height( &items[i] );
1468                                 x1 = grd_curcanv->cv_bitmap.bm_x + LHX(items[i].x) + LHX(items[i].w1);
1469                                 x2 = x1 + LHX(items[i].w2);
1470                                 y1 = grd_curcanv->cv_bitmap.bm_y + LHY(items[i].y);
1471                                 y2 = y1 + LHX(item_height);
1472                                 if (((mx > x1) && (mx < x2)) && ((my > y1) && (my < y2))) {
1473                                         citem = i;
1474                                         break;
1475                                 }
1476                         }
1477                 }
1478                 else if ( !mouse_state && omouse_state ) {
1479                         int item_height;
1480                         
1481                         mouse_get_pos(&mx, &my);
1482                         item_height = get_item_height( &items[citem] );
1483                         x1 = grd_curcanv->cv_bitmap.bm_x + LHX(items[citem].x) + LHX(items[citem].w1);
1484                         x2 = x1 + LHX(items[citem].w2);
1485                         y1 = grd_curcanv->cv_bitmap.bm_y + LHY(items[citem].y);
1486                         y2 = y1 + LHY(item_height);
1487                         if (((mx > x1) && (mx < x2)) && ((my > y1) && (my < y2))) {
1488                                 WIN(HideCursorW());
1489                                 MAC(hide_cursor();)
1490                                 switch( items[citem].type )     {
1491                                 case BT_KEY:                            kc_change_key( &items[citem] ); break;
1492                                 case BT_MOUSE_BUTTON:   kc_change_mousebutton( &items[citem] ); break;
1493                                 case BT_MOUSE_AXIS:             kc_change_mouseaxis( &items[citem] ); break;
1494                                 case BT_JOY_BUTTON:             kc_change_joybutton( &items[citem] ); break;
1495                                 case BT_JOY_AXIS:               kc_change_joyaxis( &items[citem] ); break;
1496                                 case BT_INVERT:                         kc_change_invert( &items[citem] ); break;
1497                                 }
1498                                 MAC(show_cursor();)
1499                                 WIN(ShowCursorW());
1500                         } else {
1501                                 x1 = grd_curcanv->cv_bitmap.bm_x + close_x + 2;
1502                                 x2 = x1 + close_size - 2;
1503                                 y1 = grd_curcanv->cv_bitmap.bm_y + close_y + 2;
1504                                 y2 = y1 + close_size - 2;
1505                                 if ( ((mx > x1) && (mx < x2)) && ((my > y1) && (my < y2)) ) {
1506                                         grd_curcanv->cv_font    = save_font;
1507                                         WINDOS(dd_gr_set_current_canvas( save_canvas ),
1508                                                         gr_set_current_canvas( save_canvas ));
1509                                         keyd_repeat = old_keyd_repeat;
1510                                         game_flush_inputs();
1511                                         WIN(HideCursorW());
1512                                         MAC(hide_cursor();)
1513                                         if (time_stopped)
1514                                                 start_time();
1515                                         return;
1516                                 }
1517                         }
1518
1519                 }
1520                 #endif          // MACINTOSH WINDOWS
1521                 
1522                 if (ocitem!=citem)      {
1523                         MAC(hide_cursor();)
1524                         WIN(HideCursorW());
1525                         kc_drawitem( &items[ocitem], 0 );
1526                         kc_drawitem( &items[citem], 1 );
1527                         WIN(ShowCursorW());
1528                         MAC(show_cursor();)
1529                 }
1530         }
1531 }
1532
1533
1534 void kc_drawitem( kc_item *item, int is_current )
1535 {
1536         int x, w, h, aw;
1537         char btext[16];
1538 //      PA_DFX (pa_set_frontbuffer_current());
1539 WIN(DDGRLOCK(dd_grd_curcanv));
1540
1541         if (is_current)
1542                 gr_set_fontcolor( BM_XRGB(20,20,29), -1 );
1543         else
1544                 gr_set_fontcolor( BM_XRGB(15,15,24), -1 );
1545    gr_string( LHX(item->x), LHY(item->y), item->text );
1546 WIN(DDGRUNLOCK(dd_grd_curcanv));
1547
1548         if (item->value==255) {
1549                 strcpy( btext, "" );
1550         } else {
1551                 switch( item->type )    {
1552                         case BT_KEY:
1553                                 strncpy( btext, key_text[item->value], 10 ); break;
1554                         case BT_MOUSE_BUTTON:
1555                                 #ifndef MACINTOSH
1556                                 //strncpy( btext, Text_string[mousebutton_text[item->value]], 10 ); break;
1557                                 strncpy( btext, (item->value <= 3)?Text_string[mousebutton_text[item->value]]:mousebutton_textra[item->value-3], 10 ); break;
1558                                 #else
1559                                 strncpy( btext, mousebutton_text[item->value], 10 ); break;
1560                                 #endif
1561                         case BT_MOUSE_AXIS:
1562                                 strncpy( btext, Text_string[mouseaxis_text[item->value]], 10 ); break;
1563                         case BT_JOY_BUTTON:
1564 #ifndef MACINTOSH
1565         #ifdef WINDOWS
1566                                 if (joybutton_text[item->value] != -1) 
1567                                         strncpy( btext, Text_string[ joybutton_text[item->value]  ], 10 );
1568                                 else 
1569                                         sprintf( btext, "BTN%2d", item->value+1 );
1570         #else   
1571                                 if ( joybutton_text[item->value] !=-1 )
1572                                         strncpy( btext, Text_string[ joybutton_text[item->value]  ], 10 );
1573                                 else
1574                                         sprintf( btext, "BTN%d", item->value );
1575         #endif
1576 #else
1577                                 strncpy( btext, joy_btn_name( item->value ), 10);
1578                                 if (btext == NULL)
1579                                         sprintf( btext, "BTN%d", item->value );
1580 #endif
1581                                 break;
1582                         case BT_JOY_AXIS:
1583                                 strncpy( btext, Text_string[joyaxis_text[item->value]], 10 ); break;
1584                         case BT_INVERT:
1585                                 strncpy( btext, Text_string[invert_text[item->value]], 10 ); break;
1586                 }
1587         }
1588         if (item->w1) {
1589         WIN(DDGRLOCK(dd_grd_curcanv));
1590                 gr_get_string_size(btext, &w, &h, &aw  );
1591
1592                 if (is_current)
1593                         gr_setcolor( BM_XRGB(21,0,24) );
1594                 else
1595                         gr_setcolor( BM_XRGB(16,0,19) );
1596                 gr_urect( LHX(item->w1+item->x), LHY(item->y-1), LHX(item->w1+item->x+item->w2), LHY(item->y)+h );
1597                 
1598                 gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
1599
1600                 x = LHX(item->w1+item->x)+((LHX(item->w2)-w)/2);
1601         
1602                 gr_string( x, LHY(item->y), btext );
1603 //              PA_DFX (pa_set_backbuffer_current());
1604
1605         WIN(DDGRUNLOCK(dd_grd_curcanv));
1606         }
1607 }
1608
1609
1610 static int looper=0;
1611
1612 void kc_drawquestion( kc_item *item )
1613 {
1614         int c, x, w, h, aw;
1615
1616 WIN(DDGRLOCK(dd_grd_curcanv));  
1617   // PA_DFX (pa_set_frontbuffer_current());
1618
1619         gr_get_string_size("?", &w, &h, &aw  );
1620
1621         c = BM_XRGB(21,0,24);
1622
1623         //@@gr_setcolor( gr_fade_table[fades[looper]*256+c] );
1624         gr_setcolor(BM_XRGB(21*fades[looper]/31,0,24*fades[looper]/31));
1625         looper++;
1626         if (looper>63) looper=0;
1627
1628         gr_urect( LHX(item->w1+item->x), LHY(item->y-1), LHX(item->w1+item->x+item->w2), LHY(item->y)+h );
1629         
1630         gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
1631
1632         x = LHX(item->w1+item->x)+((LHX(item->w2)-w)/2);
1633    
1634         gr_string( x, LHY(item->y), "?" );
1635 //      PA_DFX (pa_set_backbuffer_current());
1636 WIN(DDGRUNLOCK(dd_grd_curcanv));
1637 gr_update();
1638 }
1639
1640 void kc_change_key( kc_item * item )
1641 {
1642         int i,n,f,k;
1643         ubyte keycode;
1644
1645 WIN(DDGRLOCK(dd_grd_curcanv));
1646         gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
1647         
1648         gr_string( 0x8000, LHY(INFO_Y), TXT_PRESS_NEW_KEY );
1649 WIN(DDGRUNLOCK(dd_grd_curcanv));        
1650
1651         game_flush_inputs();
1652         keycode=255;
1653         k=255;
1654         
1655         while( (k!=KEY_ESC) && (keycode==255) ) 
1656         {                               
1657         #ifdef WINDOWS
1658                 {
1659                         MSG msg;
1660
1661                         DoMessageStuff(&msg);
1662                         DDGRRESTORE;
1663                 
1664                 }
1665         #endif
1666
1667                 #ifdef NETWORK
1668                 if ((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME) && (!Endlevel_sequence))
1669                         multi_menu_poll();
1670                 #endif
1671 //              if ( Game_mode & GM_MULTI )
1672 //                      GameLoop( 0, 0 );                               // Continue
1673                 k = key_inkey();
1674                 timer_delay(f0_1/10);
1675                 kc_drawquestion( item );
1676         
1677                 for (i=0; i<256; i++ )  {
1678                         if (keyd_pressed[i] && (strlen(key_text[i])>0)) {
1679                                 f = 0;
1680                                 for (n=0; n<sizeof(system_keys); n++ )
1681                                         if ( system_keys[n] == i )
1682                                                 f=1;
1683                                 if (!f) 
1684                                         keycode=i;
1685                         }
1686                 }
1687         }
1688
1689         if (k!=KEY_ESC) {
1690                 for (i=0; i<Num_items; i++ )    {
1691                         n = item - All_items;
1692                         if ( (i!=n) && (All_items[i].type==BT_KEY) && (All_items[i].value==keycode) )           {
1693                                 All_items[i].value = 255;
1694                                 kc_drawitem( &All_items[i], 0 );
1695                         }
1696                 }
1697                 item->value = keycode;
1698         }
1699         kc_drawitem( item, 1 );
1700
1701 WIN(DDGRLOCK(dd_grd_curcanv));
1702         gr_set_fontcolor( BM_XRGB(28,28,28), BM_XRGB(0,0,0) );
1703 WIN(DDGRUNLOCK(dd_grd_curcanv));
1704
1705         nm_restore_background( 0, LHY(INFO_Y), LHX(310), grd_curcanv->cv_font->ft_h );
1706
1707         game_flush_inputs();
1708
1709 }
1710
1711 void kc_change_joybutton( kc_item * item )
1712 {
1713         int n,i,k;
1714         ubyte code;
1715
1716 WIN(DDGRLOCK(dd_grd_curcanv));
1717         gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
1718         
1719         gr_string( 0x8000, LHY(INFO_Y), TXT_PRESS_NEW_JBUTTON );
1720 WIN(DDGRUNLOCK(dd_grd_curcanv));        
1721
1722         game_flush_inputs();
1723         code=255;
1724         k=255;
1725         
1726         while( (k!=KEY_ESC) && (code==255))     
1727         {                               
1728         #ifdef WINDOWS
1729                 {
1730                         MSG msg;
1731                         DoMessageStuff(&msg);
1732                         DDGRRESTORE;
1733                 }
1734         #endif
1735
1736                 #ifdef NETWORK
1737                 if ((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME) && (!Endlevel_sequence))
1738                         multi_menu_poll();
1739                 #endif
1740 //              if ( Game_mode & GM_MULTI )
1741 //                      GameLoop( 0, 0 );                               // Continue
1742                 k = key_inkey();
1743                 timer_delay(f0_1/10);
1744
1745                 if (k == KEY_PRINT_SCREEN)
1746                         save_screen_shot(0);
1747
1748                 kc_drawquestion( item );
1749
1750                 WIN(code = joydefsw_do_button());
1751                 
1752 #ifdef MACINTOSH
1753                 code = joy_do_buttons();
1754 #endif
1755                 
1756 #if !defined(WINDOWS) && !defined(MACINTOSH)
1757                 if (Config_control_type==CONTROL_THRUSTMASTER_FCS)      {
1758                         int axis[4];
1759                         joystick_read_raw_axis( JOY_ALL_AXIS, axis );
1760                         kconfig_read_fcs( axis[3] );
1761                         if ( joy_get_button_state(7) ) code = 7;
1762                         if ( joy_get_button_state(11) ) code = 11;
1763                         if ( joy_get_button_state(15) ) code = 15;
1764                         if ( joy_get_button_state(19) ) code = 19;
1765                         for (i=0; i<4; i++ )    {
1766                                 if ( joy_get_button_state(i) )
1767                                         code = i;
1768                         }
1769                 } else if (Config_control_type==CONTROL_FLIGHTSTICK_PRO) {
1770                         for (i=4; i<20; i++ )   {
1771                                 if ( joy_get_button_state(i)  ) {
1772                                         code = i;
1773                                         mprintf(( 0, "JB: %d\n", code ));
1774                                 }
1775                         }
1776                 } else {
1777                         for (i=0; i<MAX_BUTTONS; i++ )  {
1778                                 if ( joy_get_button_state(i) )
1779                                         code = i;
1780                         }
1781                 }
1782 #endif
1783         }
1784         if (code!=255)  {
1785                 for (i=0; i<Num_items; i++ )    {
1786                         n = item - All_items;
1787                         if ( (i!=n) && (All_items[i].type==BT_JOY_BUTTON) && (All_items[i].value==code) ) {
1788                                 All_items[i].value = 255;
1789                                 kc_drawitem( &All_items[i], 0 );
1790                         }
1791                 }
1792                 item->value = code;
1793         }
1794         kc_drawitem( item, 1 );
1795         nm_restore_background( 0, LHY(INFO_Y), LHX(310), grd_curcanv->cv_font->ft_h );
1796         game_flush_inputs();
1797 }
1798
1799 void kc_change_mousebutton( kc_item * item )
1800 {
1801         int n,i,b,k;
1802         ubyte code;
1803
1804 WIN(DDGRLOCK(dd_grd_curcanv));
1805         gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
1806         
1807         gr_string( 0x8000, LHY(INFO_Y), TXT_PRESS_NEW_MBUTTON );
1808 WIN(DDGRUNLOCK(dd_grd_curcanv));        
1809
1810
1811         game_flush_inputs();
1812         code=255;
1813         k=255;
1814         
1815         while( (k!=KEY_ESC) && (code==255))     
1816         {                               
1817         #ifdef WINDOWS
1818                 {
1819                         MSG msg;
1820                         DoMessageStuff(&msg);
1821                         DDGRRESTORE;
1822                 }
1823         #endif
1824
1825                 #ifdef NETWORK
1826                 if ((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME) && (!Endlevel_sequence))
1827                         multi_menu_poll();
1828                 #endif
1829 //              if ( Game_mode & GM_MULTI )
1830 //                      GameLoop( 0, 0 );                               // Continue
1831                 k = key_inkey();
1832                 timer_delay(f0_1/10);
1833
1834                 if (k == KEY_PRINT_SCREEN)
1835                         save_screen_shot(0);
1836
1837                 kc_drawquestion( item );
1838
1839                 b = mouse_get_btns();
1840                 for (i = 0; i < 16; i++ ) {
1841                         if ( b & (1<<i) )       
1842                                 code = i;
1843                 }
1844         }
1845         if (code!=255)  {
1846                 for (i=0; i<Num_items; i++ )    {
1847                         n = item - All_items;
1848                         if ( (i!=n) && (All_items[i].type==BT_MOUSE_BUTTON) && (All_items[i].value==code) )             {
1849                                 All_items[i].value = 255;
1850                                 kc_drawitem( &All_items[i], 0 );
1851                         }
1852                 }
1853                 item->value = code;
1854         }
1855         kc_drawitem( item, 1 );
1856         nm_restore_background( 0, LHY(INFO_Y), LHX(310), grd_curcanv->cv_font->ft_h );
1857         game_flush_inputs();
1858
1859 }
1860
1861 void kc_change_joyaxis( kc_item * item )
1862 {
1863 #ifdef __unix__
1864         int axis[MAX_AXES];
1865         int old_axis[MAX_AXES];
1866 #else
1867         int axis[JOY_NUM_AXES];
1868         int old_axis[JOY_NUM_AXES];
1869 #endif
1870         int n,i,k;
1871         ubyte code;
1872    WINDOS (
1873          int numaxis=7,
1874          int numaxis=6
1875         );
1876
1877 WIN(DDGRLOCK(dd_grd_curcanv));
1878         gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
1879         
1880         gr_string( 0x8000, LHY(INFO_Y), TXT_MOVE_NEW_JOY_AXIS );
1881 WIN(DDGRUNLOCK(dd_grd_curcanv));        
1882
1883         game_flush_inputs();
1884         code=255;
1885         k=255;
1886
1887         WINDOS(
1888                 joystick_read_raw_axis( JOY_ALL_AXIS+JOY_EXT_AXIS, old_axis ),
1889                 joystick_read_raw_axis( JOY_ALL_AXIS, old_axis )
1890         );
1891
1892         while( (k!=KEY_ESC) && (code==255))     
1893         {                               
1894         #ifdef WINDOWS
1895                 {
1896                         MSG msg;
1897                         DoMessageStuff(&msg);
1898                         DDGRRESTORE;
1899                 }
1900         #endif
1901
1902                 #ifdef NETWORK
1903                 if ((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME) && (!Endlevel_sequence))
1904                         multi_menu_poll();
1905                 #endif
1906 //              if ( Game_mode & GM_MULTI )
1907 //                      GameLoop( 0, 0 );                               // Continue
1908                 k = key_inkey();
1909                 timer_delay(f0_1/10);
1910
1911                 if (k == KEY_PRINT_SCREEN)
1912                         save_screen_shot(0);
1913
1914                 kc_drawquestion( item );
1915
1916                 WINDOS(
1917                         joystick_read_raw_axis( JOY_ALL_AXIS+JOY_EXT_AXIS, axis ),
1918                         joystick_read_raw_axis( JOY_ALL_AXIS, axis )
1919                 );
1920                 
1921                 for (i=0; i<numaxis; i++ )      {
1922 #if defined (MACINTOSH)
1923                         if ( abs(axis[i]-old_axis[i])>100 )     {
1924 #elif defined(WINDOWS)
1925                         if ( abs(axis[i]-old_axis[i])>1024 )    {
1926 #else 
1927                         if ( abs(axis[i]-old_axis[i])>200 )     {
1928 #endif
1929                                 code = i;
1930                                 con_printf(CON_DEBUG, "Axis Movement detected: Axis %i\n", i);
1931                         }
1932                         //old_axis[i] = axis[i];
1933                 }
1934                 for (i=0; i<Num_items; i++ )    
1935                  {
1936                         n = item - All_items;
1937                         if ( (i!=n) && (All_items[i].type==BT_JOY_AXIS) && (All_items[i].value==code) ) 
1938                                 code = 255;
1939                  }
1940         
1941         }
1942         if (code!=255)  {
1943                 for (i=0; i<Num_items; i++ )    {
1944                         n = item - All_items;
1945                         if ( (i!=n) && (All_items[i].type==BT_JOY_AXIS) && (All_items[i].value==code) ) {
1946                                 All_items[i].value = 255;
1947                                 kc_drawitem( &All_items[i], 0 );
1948                         }
1949                 }
1950
1951                 item->value = code;                                      
1952         }
1953         kc_drawitem( item, 1 );
1954         nm_restore_background( 0, LHY(INFO_Y), LHX(310), grd_curcanv->cv_font->ft_h );
1955         game_flush_inputs();
1956
1957 }
1958
1959 void kc_change_mouseaxis( kc_item * item )
1960 {
1961         int i,n,k;
1962         ubyte code;
1963         int dx,dy;
1964 #ifdef SDL_INPUT
1965         int dz;
1966 #endif
1967
1968 WIN(DDGRLOCK(dd_grd_curcanv));
1969         gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
1970         
1971         gr_string( 0x8000, LHY(INFO_Y), TXT_MOVE_NEW_MSE_AXIS );
1972 WIN(DDGRUNLOCK(dd_grd_curcanv));        
1973
1974         game_flush_inputs();
1975         code=255;
1976         k=255;
1977
1978         mouse_get_delta( &dx, &dy );
1979
1980         while( (k!=KEY_ESC) && (code==255))     
1981         {                               
1982         #ifdef WINDOWS
1983                 {
1984                         MSG msg;
1985                         DoMessageStuff(&msg);
1986                         DDGRRESTORE;
1987                 }
1988         #endif
1989
1990                 #ifdef NETWORK
1991                 if ((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME) && (!Endlevel_sequence))
1992                         multi_menu_poll();
1993                 #endif
1994 //              if ( Game_mode & GM_MULTI )
1995 //                      GameLoop( 0, 0 );                               // Continue
1996                 k = key_inkey();
1997                 timer_delay(f0_1/10);
1998
1999                 if (k == KEY_PRINT_SCREEN)
2000                         save_screen_shot(0);
2001
2002                 kc_drawquestion( item );
2003
2004 #ifdef SDL_INPUT
2005                 mouse_get_delta_z( &dx, &dy, &dz );
2006 #else
2007                 mouse_get_delta( &dx, &dy );
2008 #endif
2009                 if ( abs(dx)>20 ) code = 0;
2010                 if ( abs(dy)>20 ) code = 1;
2011 #ifdef SDL_INPUT
2012                 if ( abs(dz)>20 ) code = 2;
2013 #endif
2014         }
2015         if (code!=255)  {
2016                 for (i=0; i<Num_items; i++ )    {
2017                         n = item - All_items;
2018                         if ( (i!=n) && (All_items[i].type==BT_MOUSE_AXIS) && (All_items[i].value==code) )               {
2019                                 All_items[i].value = 255;
2020                                 kc_drawitem( &All_items[i], 0 );
2021                         }
2022                 }
2023                 item->value = code;
2024         }
2025         kc_drawitem( item, 1 );
2026         nm_restore_background( 0, LHY(INFO_Y), LHX(310), grd_curcanv->cv_font->ft_h );
2027         game_flush_inputs();
2028
2029 }
2030
2031
2032 void kc_change_invert( kc_item * item )
2033 {
2034         game_flush_inputs();
2035
2036         if (item->value)
2037                 item->value = 0;
2038         else 
2039                 item->value = 1;
2040
2041         kc_drawitem( item, 1 );
2042
2043 }
2044
2045 #include "screens.h"
2046
2047 extern void gr_bm_bitblt(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest);
2048
2049 void kconfig(int n, char * title)
2050 {
2051         int i;
2052         grs_bitmap *save_bm;
2053
2054         set_screen_mode( SCREEN_MENU );
2055
2056         kc_set_controls();
2057
2058         //save screen
2059         WIN(mouse_set_mode(0));
2060         WIN(dd_gr_set_current_canvas(NULL));
2061         
2062 #if defined(POLY_ACC)
2063         save_bm = gr_create_bitmap2( grd_curcanv->cv_bitmap.bm_w, grd_curcanv->cv_bitmap.bm_h, grd_curcanv->cv_bitmap.bm_type, NULL );
2064 #else
2065         save_bm = gr_create_bitmap( grd_curcanv->cv_bitmap.bm_w, grd_curcanv->cv_bitmap.bm_h );
2066 #endif
2067         Assert( save_bm != NULL );
2068         
2069         WIN(DDGRLOCK(dd_grd_curcanv));
2070                 gr_bm_bitblt(grd_curcanv->cv_bitmap.bm_w, grd_curcanv->cv_bitmap.bm_w, 
2071                                                  0, 0, 0, 0, &grd_curcanv->cv_bitmap, save_bm );
2072         WIN(DDGRUNLOCK(dd_grd_curcanv));
2073
2074         switch(n)       {
2075         case 0:kconfig_sub( kc_keyboard, NUM_KEY_CONTROLS, title );break;
2076         case 1:kconfig_sub( kc_joystick, NUM_OTHER_CONTROLS, title );break;
2077         case 2:kconfig_sub( kc_mouse, NUM_OTHER_CONTROLS, title ); break;
2078         case 3:kconfig_sub( kc_superjoy, NUM_OTHER_CONTROLS, title); break;
2079         default:
2080                 Int3();
2081                 return;
2082         }
2083
2084         //restore screen
2085         WIN(mouse_set_mode(1));
2086         WIN(dd_gr_set_current_canvas(NULL));
2087         WIN(DDGRLOCK(dd_grd_curcanv));
2088                 gr_bitmap(0, 0, save_bm);
2089         WIN(DDGRUNLOCK(dd_grd_curcanv));
2090         gr_free_bitmap(save_bm);
2091
2092         reset_cockpit();                //force cockpit redraw next time
2093
2094         // Update save values...
2095         
2096         for (i=0; i<NUM_KEY_CONTROLS; i++ )     
2097                 kconfig_settings[0][i] = kc_keyboard[i].value;
2098
2099         if ( (Config_control_type>0) && (Config_control_type<5)) { 
2100                 for (i=0; i<NUM_OTHER_CONTROLS; i++ )   
2101                         kconfig_settings[Config_control_type][i] = kc_joystick[i].value;
2102         } else if (Config_control_type>4 && Config_control_type<CONTROL_WINJOYSTICK) {
2103                 for (i=0; i<NUM_OTHER_CONTROLS; i++ )   
2104                         kconfig_settings[Config_control_type][i] = kc_mouse[i].value;
2105         }
2106         else if (Config_control_type == CONTROL_WINJOYSTICK) {
2107                 for (i=0; i<NUM_OTHER_CONTROLS; i++ )   
2108                         kconfig_settings[Config_control_type][i] = kc_superjoy[i].value;
2109         }
2110 }
2111
2112
2113 void kconfig_read_fcs( int raw_axis )
2114 {
2115         int raw_button, button, axis_min[4], axis_center[4], axis_max[4];
2116
2117         if (Config_control_type!=CONTROL_THRUSTMASTER_FCS) return;
2118
2119         joy_get_cal_vals(axis_min, axis_center, axis_max);
2120
2121         if ( axis_max[3] > 1 )
2122                 raw_button = (raw_axis*100)/axis_max[3];
2123         else
2124                 raw_button = 0;
2125
2126         if ( raw_button > 88 )
2127                 button = 0;
2128         else if ( raw_button > 63 )
2129                 button = 7;
2130         else if ( raw_button > 39 )
2131                 button = 11;
2132         else if ( raw_button > 15 )
2133                 button = 15;
2134         else    
2135                 button = 19;
2136
2137         kconfig_set_fcs_button( 19, button );
2138         kconfig_set_fcs_button( 15, button );
2139         kconfig_set_fcs_button( 11, button );
2140         kconfig_set_fcs_button( 7, button );
2141 }
2142                 
2143
2144 void kconfig_set_fcs_button( int btn, int button )
2145 {
2146         int state,time_down,upcount,downcount;
2147         state = time_down = upcount = downcount = 0;
2148
2149         if ( joy_get_button_state(btn) ) {
2150                 if ( btn==button )      {
2151                         state = 1;
2152                         time_down = FrameTime;
2153                 } else {
2154                         upcount=1;
2155                 }
2156         } else {
2157                 if ( btn==button )      {
2158                         state = 1;
2159                         time_down = FrameTime;
2160                         downcount=1;
2161                 } else {
2162                         upcount=1;
2163                 }
2164         }                               
2165                         
2166         joy_set_btn_values( btn, state, time_down, downcount, upcount );
2167                                         
2168 }
2169
2170
2171
2172 fix Last_angles_p = 0;
2173 fix Last_angles_b = 0;
2174 fix Last_angles_h = 0;
2175 ubyte Last_angles_read = 0;
2176
2177 extern int                      VR_sensitivity;
2178                                                 
2179 int VR_sense_range[3] = { 25, 50, 75 };
2180
2181 #if 0 //ndef MACINTOSH
2182 read_head_tracker()
2183 {
2184 #ifndef WINDOWS
2185
2186         fix yaw, pitch, roll;
2187         int buttons;
2188
2189 //------ read vfx1 helmet --------
2190         if (vfx1_installed) {
2191                 vfx_get_data(&yaw,&pitch,&roll,&buttons);
2192         } else if (iglasses_headset_installed)  {
2193                 iglasses_read_headset( &yaw, &pitch, &roll );
2194         } else if (Victor_headset_installed)   {
2195                 victor_read_headset_filtered( &yaw, &pitch, &roll );
2196         } else {
2197                 return;
2198         }
2199
2200         Use_player_head_angles = 0;
2201         if ( Last_angles_read ) {
2202                 fix yaw1 = yaw;
2203                 
2204                 yaw1 = yaw;
2205                 if ( (Last_angles_h < (F1_0/4) ) && (yaw > ((F1_0*3)/4) ) )     
2206                         yaw1 -= F1_0;
2207                 else if ( (yaw < (F1_0/4) ) && (Last_angles_h > ((F1_0*3)/4) ) )        
2208                         yaw1 += F1_0;
2209         
2210                 Controls.pitch_time     += fixmul((pitch- Last_angles_p)*VR_sense_range[VR_sensitivity],FrameTime);
2211                 Controls.heading_time+= fixmul((yaw1 -  Last_angles_h)*VR_sense_range[VR_sensitivity],FrameTime);
2212                 Controls.bank_time      += fixmul((roll - Last_angles_b)*VR_sense_range[VR_sensitivity],FrameTime);
2213         }
2214         Last_angles_read = 1;
2215         Last_angles_p = pitch;
2216         Last_angles_h = yaw;
2217         Last_angles_b = roll;
2218 #endif
2219 }
2220 #endif
2221
2222 #define PH_SCALE        8
2223
2224 #ifdef WINDOWS
2225 #define JOYSTICK_READ_TIME      (F1_0/40)               //      Read joystick at 40 Hz.
2226 #else
2227 #define JOYSTICK_READ_TIME      (F1_0/10)               //      Read joystick at 10 Hz.
2228 #endif
2229
2230 fix     LastReadTime = 0;
2231
2232 fix     joy_axis[7];
2233
2234 ubyte                   kc_use_external_control = 0;
2235 ubyte                           kc_enable_external_control = 0;
2236 ubyte                   kc_external_intno = 0;
2237 ext_control_info        *kc_external_control = NULL;
2238 ubyte                           *kc_external_name = NULL;
2239 ubyte                           kc_external_version = 0;
2240 extern int Automap_active;
2241
2242 void kconfig_init_external_controls(int intno, int address)
2243 {
2244         int i;
2245         kc_external_intno = intno;
2246         kc_external_control     = (ext_control_info *)address;
2247         kc_use_external_control = 1;
2248         kc_enable_external_control  = 1;
2249
2250         i = FindArg ( "-xname" );
2251         if ( i )        
2252                 kc_external_name = Args[i+1];
2253         else
2254                 kc_external_name = "External Controller";
2255
2256    for (i=0;i<strlen (kc_external_name);i++)
2257     if (kc_external_name[i]=='_')
2258           kc_external_name[i]=' '; 
2259
2260         i = FindArg ( "-xver" );
2261         if ( i )
2262                 kc_external_version = atoi(Args[i+1]);
2263         
2264         printf( "%s int: 0x%x, data: 0x%p, ver:%d\n", kc_external_name, kc_external_intno, kc_external_control, kc_external_version );
2265
2266 }
2267
2268 #if !defined(MACINTOSH)
2269 /*void kconfig_read_external_controls()
2270 {
2271         union REGS r;
2272
2273         if ( !kc_enable_external_control && !CybermouseActive) 
2274                 return;
2275
2276         if ( kc_external_version == 0 ) 
2277                 memset( kc_external_control, 0, sizeof(control_info) );
2278         else if ( kc_external_version > 0 )     {
2279                 memset( kc_external_control, 0, sizeof(control_info)+sizeof(vms_angvec) + 64 );
2280                 if ( kc_external_version > 1 ) {
2281                         // Write ship pos and angles to external controls...
2282                         ubyte *temp_ptr = (ubyte *)kc_external_control;
2283                         vms_vector *ship_pos;
2284                         vms_matrix *ship_orient;
2285                         memset( kc_external_control, 0, sizeof(control_info)+sizeof(vms_angvec) + 64 + sizeof(vms_vector)+sizeof(vms_matrix) );
2286                         temp_ptr += sizeof(control_info)+sizeof(vms_angvec) + 64;
2287                         ship_pos = (vms_vector *)temp_ptr;
2288                         temp_ptr += sizeof(vms_vector);
2289                         ship_orient = (vms_matrix *)temp_ptr;
2290                         // Fill in ship postion...
2291                         *ship_pos = Objects[Players[Player_num].objnum].pos;
2292                         // Fill in ship orientation...
2293                         *ship_orient = Objects[Players[Player_num].objnum].orient;
2294                 }
2295         }
2296
2297         if ( Automap_active )                    // (If in automap...)
2298                 kc_external_control->automap_state = 1;
2299         memset(&r,0,sizeof(r));
2300
2301 #ifndef WINDOWS
2302   
2303    if (!CybermouseActive)
2304         int386 ( kc_external_intno, &r, &r);            // Read external info...
2305 //      else
2306   //            ReadOWL (kc_external_control);
2307
2308 #endif
2309
2310         if ( Player_num > -1 )  {
2311                 Objects[Players[Player_num].objnum].mtype.phys_info.flags &= (~PF_TURNROLL);    // Turn off roll when turning
2312                 Objects[Players[Player_num].objnum].mtype.phys_info.flags &= (~PF_LEVELLING);   // Turn off leveling to nearest side.
2313                 Auto_leveling_on = 0;
2314
2315                 if ( kc_external_version > 0 ) {                
2316                         vms_matrix tempm, ViewMatrix;
2317                         vms_angvec * Kconfig_abs_movement;
2318                         char * oem_message;
2319         
2320                         Kconfig_abs_movement = (vms_angvec *)((uint)kc_external_control + sizeof(control_info));
2321         
2322                         if ( Kconfig_abs_movement->p || Kconfig_abs_movement->b || Kconfig_abs_movement->h )    {
2323                                 vm_angles_2_matrix(&tempm,Kconfig_abs_movement);
2324                                 vm_matrix_x_matrix(&ViewMatrix,&Objects[Players[Player_num].objnum].orient,&tempm);
2325                                 Objects[Players[Player_num].objnum].orient = ViewMatrix;                
2326                         }
2327                         oem_message = (char *)((uint)Kconfig_abs_movement + sizeof(vms_angvec));
2328                         if (oem_message[0] != '\0' )
2329                                 HUD_init_message( oem_message );
2330                 }
2331         }
2332
2333         Controls.pitch_time += fixmul(kc_external_control->pitch_time,FrameTime);                                               
2334         Controls.vertical_thrust_time += fixmul(kc_external_control->vertical_thrust_time,FrameTime);
2335         Controls.heading_time += fixmul(kc_external_control->heading_time,FrameTime);
2336         Controls.sideways_thrust_time += fixmul(kc_external_control->sideways_thrust_time ,FrameTime);
2337         Controls.bank_time += fixmul(kc_external_control->bank_time ,FrameTime);
2338         Controls.forward_thrust_time += fixmul(kc_external_control->forward_thrust_time ,FrameTime);
2339         Controls.rear_view_down_count += kc_external_control->rear_view_down_count;     
2340         Controls.rear_view_down_state |= kc_external_control->rear_view_down_state;     
2341         Controls.fire_primary_down_count += kc_external_control->fire_primary_down_count;
2342         Controls.fire_primary_state |= kc_external_control->fire_primary_state;
2343         Controls.fire_secondary_state |= kc_external_control->fire_secondary_state;
2344         Controls.fire_secondary_down_count += kc_external_control->fire_secondary_down_count;
2345         Controls.fire_flare_down_count += kc_external_control->fire_flare_down_count;
2346         Controls.drop_bomb_down_count += kc_external_control->drop_bomb_down_count;     
2347         Controls.automap_down_count += kc_external_control->automap_down_count;
2348         Controls.automap_state |= kc_external_control->automap_state;
2349 } */
2350 #endif
2351
2352 #ifdef WINDOWS
2353 void controls_read_all_win()
2354 {
2355         int i;
2356         int slide_on, bank_on;
2357         int dx, dy;
2358         fix ctime;
2359         fix mouse_axis[2];
2360         int raw_joy_axis[7];
2361         int mouse_buttons;
2362         fix k0, k1, k2, k3, kp;
2363         fix k4, k5, k6, k7, kh;
2364         ubyte channel_masks;
2365         int use_mouse, use_joystick;
2366         int speed_factor=1;
2367
2368         if (Game_turbo_mode)
2369                 speed_factor = 2;
2370         
2371         {
2372                 fix temp = Controls.heading_time;
2373                 fix temp1 = Controls.pitch_time;
2374                 memset( &Controls, 0, sizeof(control_info) );
2375                 Controls.heading_time = temp;
2376                 Controls.pitch_time = temp1;
2377         }
2378         slide_on = 0;
2379         bank_on = 0;
2380
2381         ctime = timer_get_fixed_seconds();
2382
2383 //      DO JOYSTICK (X,Y,Z  R,U,V)
2384 //      ----------------------------------------------------------------------------
2385         if ( (LastReadTime + JOYSTICK_READ_TIME) > ctime ) {
2386                 if ((ctime < 0) && (LastReadTime > 0))
2387                         LastReadTime = ctime;
2388                 use_joystick=1;
2389         } else if ((Config_control_type==CONTROL_WINJOYSTICK)) {
2390                 LastReadTime = ctime;
2391                 channel_masks = joystick_read_raw_axis( JOY_ALL_AXIS+JOY_EXT_AXIS, raw_joy_axis );
2392
2393                 for (i=0; i<7; i++ )    {
2394                         if (channel_masks&(1<<i))       {
2395                                 int joy_null_value = 28;
2396
2397                         // DO POV if joystick has a hat.
2398                         //      --------------------------------------------------------------------
2399                                 if (i == 3) {
2400                                         joydefsw_do_winjoybutton(raw_joy_axis);
2401                                 }
2402                                 else {
2403                                 // DO AXIS
2404                                 //      --------------------------------------------------------------------    
2405                                 //      mprintf((0, "(%d)=%d,", i, raw_joy_axis[i]));
2406                                         raw_joy_axis[i] = joy_get_scaled_reading( raw_joy_axis[i], i );
2407                                 //      mprintf((0, "%d  ",raw_joy_axis[i]));
2408                                 //      if (i%2) mprintf((0,"\n"));
2409
2410         
2411                                         if (kc_superjoy[23].value==i)           // If this is the throttle
2412                                                 joy_null_value = 32;                            // Then use a larger dead-zone
2413         
2414                                         if (raw_joy_axis[i] > (joy_null_value-2)) 
2415                                                 raw_joy_axis[i] = ((raw_joy_axis[i]-joy_null_value)*128)/(128-joy_null_value);
2416                                         else if (raw_joy_axis[i] < -(joy_null_value+2))
2417                                                 raw_joy_axis[i] = ((raw_joy_axis[i]+joy_null_value)*128)/(128-joy_null_value);
2418                                         else
2419                                                 raw_joy_axis[i] = 0;
2420                                         joy_axis[i]     = (raw_joy_axis[i]*FrameTime)/128;      
2421                                 }
2422                         } else {
2423                                 joy_axis[i] = 0;
2424                         }
2425                 }       
2426                 use_joystick=1;
2427
2428         } else {
2429                 for (i=0; i<6; i++ )
2430                         joy_axis[i] = 0;
2431                 use_joystick=0;
2432         }
2433
2434 //      DO MOUSE 
2435 //      ----------------------------------------------------------------------------
2436         if (Config_control_type==5) {
2437                 mouse_get_delta( &dx, &dy );
2438                 mouse_axis[0] = (dx*FrameTime)/35;
2439                 mouse_axis[1] = (dy*FrameTime)/25;
2440                 mouse_buttons = mouse_get_btns();
2441                 //mprintf(( 0, "Mouse %d,%d b:%d, 0x%x\n", mouse_axis[0], mouse_axis[1], mouse_buttons, FrameTime ));
2442                 use_mouse=1;
2443    } else {
2444                 mouse_axis[0] = 0;
2445                 mouse_axis[1] = 0;
2446                 mouse_buttons = 0;
2447                 use_mouse=0;
2448         }
2449
2450 //------------- Read slide_on -------------
2451         
2452         // From keyboard...
2453         if ( kc_keyboard[8].value < 255 ) slide_on |= keyd_pressed[ kc_keyboard[8].value ];
2454         if ( kc_keyboard[9].value < 255 ) slide_on |= keyd_pressed[ kc_keyboard[9].value ];
2455         // From joystick...
2456         if ((use_joystick)&&(kc_superjoy[5].value<255)) slide_on |= joy_get_button_state( kc_superjoy[5].value );
2457         // From mouse...
2458         if ((use_mouse)&&(kc_mouse[5].value<255)) slide_on |= mouse_buttons & (1<<kc_mouse[5].value);
2459
2460 //------------- Read bank_on ---------------
2461
2462         // From keyboard...
2463         if ( kc_keyboard[18].value < 255 ) bank_on |= keyd_pressed[ kc_keyboard[18].value ];
2464         if ( kc_keyboard[19].value < 255 ) bank_on |= keyd_pressed[ kc_keyboard[19].value ];
2465         // From joystick...
2466         if ( (use_joystick)&&(kc_superjoy[10].value < 255 )) bank_on |= joy_get_button_state( kc_superjoy[10].value );
2467         // From mouse...
2468         if ( (use_mouse)&&(kc_mouse[10].value < 255 )) bank_on |= mouse_buttons & (1<<kc_mouse[10].value);
2469
2470 //------------ Read pitch_time -----------
2471         if ( !slide_on )        {
2472                 // mprintf((0, "pitch: %7.3f %7.3f: %7.3f\n", f2fl(k4), f2fl(k6), f2fl(Controls.heading_time)));
2473                 kp = 0;
2474                 k0 = speed_factor*key_down_time( kc_keyboard[0].value )/2;      // Divide by two since we want pitch to go slower
2475                 k1 = speed_factor*key_down_time( kc_keyboard[1].value )/2;
2476                 k2 = speed_factor*key_down_time( kc_keyboard[2].value )/2;
2477                 k3 = speed_factor*key_down_time( kc_keyboard[3].value )/2;
2478
2479                 // From keyboard...
2480                 if ( kc_keyboard[0].value < 255 ) kp += k0/PH_SCALE;
2481                 if ( kc_keyboard[1].value < 255 ) kp += k1/PH_SCALE;
2482                 if ( kc_keyboard[2].value < 255 ) kp -= k2/PH_SCALE;
2483                 if ( kc_keyboard[3].value < 255 ) kp -= k3/PH_SCALE;
2484
2485                 // From Cyberman...
2486                 if ((use_mouse)&&(Config_control_type==CONTROL_CYBERMAN))       {
2487                         kp += mouse_button_down_time(MB_PITCH_FORWARD)/(PH_SCALE*2);
2488                         kp -= mouse_button_down_time(MB_PITCH_BACKWARD)/(PH_SCALE*2);
2489                 }
2490         
2491                 if (kp == 0)
2492                         Controls.pitch_time = 0;
2493                 else if (kp > 0) {
2494                         if (Controls.pitch_time < 0)
2495                                 Controls.pitch_time = 0;
2496                 } else // kp < 0
2497                         if (Controls.pitch_time > 0)
2498                                 Controls.pitch_time = 0;
2499                 Controls.pitch_time += kp;
2500         
2501                 // From joystick...
2502                 if ( (use_joystick)&&(kc_superjoy[13].value < 255 ))    {
2503                         if ( !kc_superjoy[14].value )           // If not inverted...
2504                                 Controls.pitch_time -= (joy_axis[kc_superjoy[13].value]*Config_joystick_sensitivity)/8;
2505                         else
2506                                 Controls.pitch_time += (joy_axis[kc_superjoy[13].value]*Config_joystick_sensitivity)/8;
2507                 }
2508         
2509                 // From mouse...
2510                 //mprintf(( 0, "UM: %d, PV: %d\n", use_mouse, kc_mouse[13].value ));
2511                 if ( (use_mouse)&&(kc_mouse[13].value < 255) )  {
2512                         if ( !kc_mouse[14].value )              // If not inverted...
2513                                 Controls.pitch_time -= (mouse_axis[kc_mouse[13].value]*Config_joystick_sensitivity)/8;
2514                         else
2515                                 Controls.pitch_time += (mouse_axis[kc_mouse[13].value]*Config_joystick_sensitivity)/8;
2516                 }
2517         } else {
2518                 Controls.pitch_time = 0;
2519         }
2520
2521
2522 //----------- Read vertical_thrust_time -----------------
2523
2524         if ( slide_on ) {
2525                 k0 = speed_factor*key_down_time( kc_keyboard[0].value );
2526                 k1 = speed_factor*key_down_time( kc_keyboard[1].value );
2527                 k2 = speed_factor*key_down_time( kc_keyboard[2].value );
2528                 k3 = speed_factor*key_down_time( kc_keyboard[3].value );
2529
2530                 // From keyboard...
2531                 if ( kc_keyboard[0].value < 255 ) Controls.vertical_thrust_time += k0;
2532                 if ( kc_keyboard[1].value < 255 ) Controls.vertical_thrust_time += k1;
2533                 if ( kc_keyboard[2].value < 255 ) Controls.vertical_thrust_time -= k2;
2534                 if ( kc_keyboard[3].value < 255 ) Controls.vertical_thrust_time -= k3;
2535
2536                 // From Cyberman...
2537                 if ((use_mouse)&&(Config_control_type==CONTROL_CYBERMAN))       {
2538                         Controls.vertical_thrust_time -= mouse_button_down_time(MB_PITCH_FORWARD);
2539                         Controls.vertical_thrust_time += mouse_button_down_time(MB_PITCH_BACKWARD);
2540                 }
2541         
2542                 // From joystick...
2543                 if ((use_joystick)&&( kc_superjoy[13].value < 255 ))    {
2544                         if ( !kc_superjoy[14].value )           // If not inverted...
2545                                 Controls.vertical_thrust_time += joy_axis[kc_superjoy[13].value];
2546                         else
2547                                 Controls.vertical_thrust_time -= joy_axis[kc_superjoy[13].value];
2548                 }
2549         
2550                 // From mouse...
2551                 if ( (use_mouse)&&(kc_mouse[13].value < 255 ))  {
2552                         if ( !kc_mouse[14].value )              // If not inverted...
2553                                 Controls.vertical_thrust_time -= mouse_axis[kc_mouse[13].value];
2554                         else
2555                                 Controls.vertical_thrust_time += mouse_axis[kc_mouse[13].value];
2556                 }
2557         }
2558
2559         // From keyboard...
2560         if ( kc_keyboard[14].value < 255 ) Controls.vertical_thrust_time += speed_factor*key_down_time( kc_keyboard[14].value );
2561         if ( kc_keyboard[15].value < 255 ) Controls.vertical_thrust_time += speed_factor*key_down_time( kc_keyboard[15].value );
2562         if ( kc_keyboard[16].value < 255 ) Controls.vertical_thrust_time -= speed_factor*key_down_time( kc_keyboard[16].value );
2563         if ( kc_keyboard[17].value < 255 ) Controls.vertical_thrust_time -= speed_factor*key_down_time( kc_keyboard[17].value );
2564         
2565         // From joystick...
2566         if ((use_joystick)&&( kc_superjoy[19].value < 255 ))    {
2567                 if ( !kc_superjoy[20].value )           // If not inverted...
2568                         Controls.vertical_thrust_time += joy_axis[kc_superjoy[19].value];
2569                 else
2570                         Controls.vertical_thrust_time -= joy_axis[kc_superjoy[19].value];
2571         }
2572
2573         // From joystick buttons
2574         if ( (use_joystick)&&(kc_superjoy[8].value < 255 )) Controls.vertical_thrust_time += joy_get_button_down_time( kc_superjoy[8].value );
2575         if ( (use_joystick)&&(kc_superjoy[9].value < 255 )) Controls.vertical_thrust_time -= joy_get_button_down_time( kc_superjoy[9].value );
2576
2577         // From mouse buttons
2578         if ( (use_mouse)&&(kc_mouse[8].value < 255 )) Controls.vertical_thrust_time += mouse_button_down_time( kc_mouse[8].value );
2579         if ( (use_mouse)&&(kc_mouse[9].value < 255 )) Controls.vertical_thrust_time -= mouse_button_down_time( kc_mouse[9].value );
2580
2581         // From mouse...
2582         if ( (use_mouse)&&(kc_mouse[19].value < 255 ))  {
2583                 if ( !kc_mouse[20].value )              // If not inverted...
2584                         Controls.vertical_thrust_time += mouse_axis[kc_mouse[19].value];
2585                 else
2586                         Controls.vertical_thrust_time -= mouse_axis[kc_mouse[19].value];
2587         }
2588
2589         // From Cyberman...
2590         if ((use_mouse)&&(Config_control_type==CONTROL_CYBERMAN))       {
2591                 Controls.vertical_thrust_time += mouse_button_down_time(MB_Z_UP)/2;
2592                 Controls.vertical_thrust_time -= mouse_button_down_time(MB_Z_DOWN)/2;
2593         }
2594
2595 //---------- Read heading_time -----------
2596
2597         if (!slide_on && !bank_on)      {
2598                 //mprintf((0, "heading: %7.3f %7.3f: %7.3f\n", f2fl(k4), f2fl(k6), f2fl(Controls.heading_time)));
2599                 kh = 0;
2600                 k4 = speed_factor*key_down_time( kc_keyboard[4].value );
2601                 k5 = speed_factor*key_down_time( kc_keyboard[5].value );
2602                 k6 = speed_factor*key_down_time( kc_keyboard[6].value );
2603                 k7 = speed_factor*key_down_time( kc_keyboard[7].value );
2604
2605                 // From keyboard...
2606                 if ( kc_keyboard[4].value < 255 ) kh -= k4/PH_SCALE;
2607                 if ( kc_keyboard[5].value < 255 ) kh -= k5/PH_SCALE;
2608                 if ( kc_keyboard[6].value < 255 ) kh += k6/PH_SCALE;
2609                 if ( kc_keyboard[7].value < 255 ) kh += k7/PH_SCALE;
2610
2611                 // From Cyberman...
2612                 if ((use_mouse)&&(Config_control_type==CONTROL_CYBERMAN))       {
2613                         kh -= mouse_button_down_time(MB_HEAD_LEFT)/PH_SCALE;
2614                         kh += mouse_button_down_time(MB_HEAD_RIGHT)/PH_SCALE;
2615                 }
2616         
2617                 if (kh == 0)
2618                         Controls.heading_time = 0;
2619                 else if (kh > 0) {
2620                         if (Controls.heading_time < 0)
2621                                 Controls.heading_time = 0;
2622                 } else // kh < 0
2623                         if (Controls.heading_time > 0)
2624                                 Controls.heading_time = 0;
2625                 Controls.heading_time += kh;
2626
2627                 // From joystick...
2628                 if ( (use_joystick)&&(kc_superjoy[15].value < 255 ))    {
2629                         if ( !kc_superjoy[16].value )           // If not inverted...
2630                                 Controls.heading_time += (joy_axis[kc_superjoy[15].value]*Config_joystick_sensitivity)/8;
2631                         else
2632                                 Controls.heading_time -= (joy_axis[kc_superjoy[15].value]*Config_joystick_sensitivity)/8;
2633                 }
2634         
2635                 // From mouse...
2636                 if ( (use_mouse)&&(kc_mouse[15].value < 255 ))  {
2637                         if ( !kc_mouse[16].value )              // If not inverted...
2638                                 Controls.heading_time += (mouse_axis[kc_mouse[15].value]*Config_joystick_sensitivity)/8;
2639                         else
2640                                 Controls.heading_time -= (mouse_axis[kc_mouse[15].value]*Config_joystick_sensitivity)/8;
2641                 }
2642         } else {
2643                 Controls.heading_time = 0;
2644         }
2645
2646 //----------- Read sideways_thrust_time -----------------
2647
2648         if ( slide_on ) {
2649                 k0 = speed_factor*key_down_time( kc_keyboard[4].value );
2650                 k1 = speed_factor*key_down_time( kc_keyboard[5].value );
2651                 k2 = speed_factor*key_down_time( kc_keyboard[6].value );
2652                 k3 = speed_factor*key_down_time( kc_keyboard[7].value );
2653
2654                 // From keyboard...
2655                 if ( kc_keyboard[4].value < 255 ) Controls.sideways_thrust_time -= k0;
2656                 if ( kc_keyboard[5].value < 255 ) Controls.sideways_thrust_time -= k1;
2657                 if ( kc_keyboard[6].value < 255 ) Controls.sideways_thrust_time += k2;
2658                 if ( kc_keyboard[7].value < 255 ) Controls.sideways_thrust_time += k3;
2659         
2660                 // From joystick...
2661                 if ( (use_joystick)&&(kc_superjoy[15].value < 255 ))    {
2662                         if ( !kc_superjoy[16].value )           // If not inverted...
2663                                 Controls.sideways_thrust_time += joy_axis[kc_superjoy[15].value];
2664                         else
2665                                 Controls.sideways_thrust_time -= joy_axis[kc_superjoy[15].value];
2666                 }
2667                 
2668                 // From cyberman
2669                 if ((use_mouse)&&(Config_control_type==CONTROL_CYBERMAN))       {
2670                         Controls.sideways_thrust_time -= mouse_button_down_time(MB_HEAD_LEFT);
2671                         Controls.sideways_thrust_time += mouse_button_down_time(MB_HEAD_RIGHT);
2672                 }
2673         
2674                 // From mouse...
2675                 if ( (use_mouse)&&(kc_mouse[15].value < 255 ))  {
2676                         if ( !kc_mouse[16].value )              // If not inverted...
2677                                 Controls.sideways_thrust_time += mouse_axis[kc_mouse[15].value];
2678                         else
2679                                 Controls.sideways_thrust_time -= mouse_axis[kc_mouse[15].value];
2680                 }
2681         }
2682
2683         // From keyboard...
2684         if ( kc_keyboard[10].value < 255 ) Controls.sideways_thrust_time -= speed_factor*key_down_time( kc_keyboard[10].value );
2685         if ( kc_keyboard[11].value < 255 ) Controls.sideways_thrust_time -= speed_factor*key_down_time( kc_keyboard[11].value );
2686         if ( kc_keyboard[12].value < 255 ) Controls.sideways_thrust_time += speed_factor*key_down_time( kc_keyboard[12].value );
2687         if ( kc_keyboard[13].value < 255 ) Controls.sideways_thrust_time += speed_factor*key_down_time( kc_keyboard[13].value );
2688         
2689         // From joystick...
2690         if ( (use_joystick)&&(kc_superjoy[17].value < 255 ))    {
2691                 if ( !kc_superjoy[18].value )           // If not inverted...
2692                         Controls.sideways_thrust_time -= joy_axis[kc_superjoy[17].value];
2693                 else
2694                         Controls.sideways_thrust_time += joy_axis[kc_superjoy[17].value];
2695         }
2696
2697         // From joystick buttons
2698         if ( (use_joystick)&&(kc_superjoy[6].value < 255 )) Controls.sideways_thrust_time -= joy_get_button_down_time( kc_superjoy[6].value );
2699         if ( (use_joystick)&&(kc_superjoy[7].value < 255 )) Controls.sideways_thrust_time += joy_get_button_down_time( kc_superjoy[7].value );
2700
2701         // From mouse buttons
2702         if ( (use_mouse)&&(kc_mouse[6].value < 255 )) Controls.sideways_thrust_time -= mouse_button_down_time( kc_mouse[6].value );
2703         if ( (use_mouse)&&(kc_mouse[7].value < 255 )) Controls.sideways_thrust_time += mouse_button_down_time( kc_mouse[7].value );
2704
2705         // From mouse...
2706         if ( (use_mouse)&&(kc_mouse[17].value < 255 ))  {
2707                 if ( !kc_mouse[18].value )              // If not inverted...
2708                         Controls.sideways_thrust_time += mouse_axis[kc_mouse[17].value];
2709                 else
2710                         Controls.sideways_thrust_time -= mouse_axis[kc_mouse[17].value];
2711         }
2712
2713 //----------- Read bank_time -----------------
2714
2715         if ( bank_on )  {
2716                 k0 = speed_factor*key_down_time( kc_keyboard[4].value );
2717                 k1 = speed_factor*key_down_time( kc_keyboard[5].value );
2718                 k2 = speed_factor*key_down_time( kc_keyboard[6].value );
2719                 k3 = speed_factor*key_down_time( kc_keyboard[7].value );
2720
2721                 // From keyboard...
2722                 if ( kc_keyboard[4].value < 255 ) Controls.bank_time += k0;
2723                 if ( kc_keyboard[5].value < 255 ) Controls.bank_time += k1;
2724                 if ( kc_keyboard[6].value < 255 ) Controls.bank_time -= k2;
2725                 if ( kc_keyboard[7].value < 255 ) Controls.bank_time -= k3;
2726
2727                 // From Cyberman...
2728                 if ((use_mouse)&&(Config_control_type==CONTROL_CYBERMAN))       {
2729                         Controls.bank_time -= mouse_button_down_time(MB_HEAD_LEFT);
2730                         Controls.bank_time += mouse_button_down_time(MB_HEAD_RIGHT);
2731                 }
2732
2733                 // From joystick...
2734                 if ( (use_joystick)&&(kc_superjoy[15].value < 255) )    {
2735                         if ( !kc_superjoy[16].value )           // If not inverted...
2736                                 Controls.bank_time -= (joy_axis[kc_superjoy[15].value]*Config_joystick_sensitivity)/8;
2737                         else
2738                                 Controls.bank_time += (joy_axis[kc_superjoy[15].value]*Config_joystick_sensitivity)/8;
2739                 }
2740         
2741                 // From mouse...
2742                 if ( (use_mouse)&&(kc_mouse[15].value < 255 ))  {
2743                         if ( !kc_mouse[16].value )              // If not inverted...
2744                                 Controls.bank_time += (mouse_axis[kc_mouse[15].value]*Config_joystick_sensitivity)/8;
2745                         else
2746                                 Controls.bank_time -= (mouse_axis[kc_mouse[15].value]*Config_joystick_sensitivity)/8;
2747                 }
2748         }
2749
2750         // From keyboard...
2751         if ( kc_keyboard[20].value < 255 ) Controls.bank_time += speed_factor*key_down_time( kc_keyboard[20].value );
2752         if ( kc_keyboard[21].value < 255 ) Controls.bank_time += speed_factor*key_down_time( kc_keyboard[21].value );
2753         if ( kc_keyboard[22].value < 255 ) Controls.bank_time -= speed_factor*key_down_time( kc_keyboard[22].value );
2754         if ( kc_keyboard[23].value < 255 ) Controls.bank_time -= speed_factor*key_down_time( kc_keyboard[23].value );
2755
2756         // From joystick...
2757         if ( (use_joystick)&&(kc_superjoy[21].value < 255) )    {
2758                 if ( !kc_superjoy[22].value )           // If not inverted...
2759                         Controls.bank_time -= joy_axis[kc_superjoy[21].value];
2760                 else
2761                         Controls.bank_time += joy_axis[kc_superjoy[21].value];
2762         }
2763
2764         // From joystick buttons
2765         if ( (use_joystick)&&(kc_superjoy[11].value < 255 )) Controls.bank_time += joy_get_button_down_time( kc_superjoy[11].value );
2766         if ( (use_joystick)&&(kc_superjoy[12].value < 255 )) Controls.bank_time -= joy_get_button_down_time( kc_superjoy[12].value );
2767
2768         // From mouse buttons
2769         if ( (use_mouse)&&(kc_mouse[11].value < 255 )) Controls.bank_time += mouse_button_down_time( kc_mouse[11].value );
2770         if ( (use_mouse)&&(kc_mouse[12].value < 255 )) Controls.bank_time -= mouse_button_down_time( kc_mouse[12].value );
2771
2772         // From mouse...
2773         if ( (use_mouse)&&(kc_mouse[21].value < 255 ))  {
2774                 if ( !kc_mouse[22].value )              // If not inverted...
2775                         Controls.bank_time += mouse_axis[kc_mouse[21].value];
2776                 else
2777                         Controls.bank_time -= mouse_axis[kc_mouse[21].value];
2778         }
2779
2780         // From Cyberman
2781         if ((use_mouse)&&(Config_control_type==CONTROL_CYBERMAN))       {
2782                 Controls.bank_time += mouse_button_down_time(MB_BANK_LEFT);
2783                 Controls.bank_time -= mouse_button_down_time(MB_BANK_RIGHT);
2784         }
2785
2786 //----------- Read forward_thrust_time -------------
2787
2788         // From keyboard...
2789         if ( kc_keyboard[30].value < 255 ) Controls.forward_thrust_time += speed_factor*key_down_time( kc_keyboard[30].value );
2790         if ( kc_keyboard[31].value < 255 ) Controls.forward_thrust_time += speed_factor*key_down_time( kc_keyboard[31].value );
2791         if ( kc_keyboard[32].value < 255 ) Controls.forward_thrust_time -= speed_factor*key_down_time( kc_keyboard[32].value );
2792         if ( kc_keyboard[33].value < 255 ) Controls.forward_thrust_time -= speed_factor*key_down_time( kc_keyboard[33].value );
2793
2794         // From joystick...
2795         if ( (use_joystick)&&(kc_superjoy[23].value < 255 ))    {
2796                 if ( !kc_superjoy[24].value )           // If not inverted...
2797                         Controls.forward_thrust_time -= joy_axis[kc_superjoy[23].value];
2798                 else
2799                         Controls.forward_thrust_time += joy_axis[kc_superjoy[23].value];
2800         }
2801
2802         // From joystick buttons
2803         if ( (use_joystick)&&(kc_superjoy[2].value < 255 )) Controls.forward_thrust_time += joy_get_button_down_time( kc_superjoy[2].value );
2804         if ( (use_joystick)&&(kc_superjoy[3].value < 255 )) Controls.forward_thrust_time -= joy_get_button_down_time( kc_superjoy[3].value );
2805
2806         // From mouse...
2807         if ( (use_mouse)&&(kc_mouse[23].value < 255 ))  {
2808                 if ( !kc_mouse[24].value )              // If not inverted...
2809                         Controls.forward_thrust_time -= mouse_axis[kc_mouse[23].value];
2810                 else
2811                         Controls.forward_thrust_time += mouse_axis[kc_mouse[23].value];
2812         }
2813
2814         // From mouse buttons
2815         if ( (use_mouse)&&(kc_mouse[2].value < 255 )) Controls.forward_thrust_time += mouse_button_down_time( kc_mouse[2].value );
2816         if ( (use_mouse)&&(kc_mouse[3].value < 255 )) Controls.forward_thrust_time -= mouse_button_down_time( kc_mouse[3].value );
2817
2818 //----------- Read afterburner_state -------------
2819
2820         // From keyboard...
2821         if ( kc_keyboard[46].value < 255 ) Controls.afterburner_state |= keyd_pressed[kc_keyboard[46].value];
2822         if ( kc_keyboard[47].value < 255 ) Controls.afterburner_state |= keyd_pressed[kc_keyboard[47].value];
2823
2824         if ( (use_mouse)&&(kc_mouse[27].value < 255 )) Controls.afterburner_state |= mouse_button_state(kc_mouse[27].value);
2825
2826         if ( (use_joystick)&&(kc_superjoy[27].value < 255 )) Controls.afterburner_state |= joy_get_button_state(kc_superjoy[27].value);
2827
2828 //-------Read headlight key--------------------------
2829         if (kc_keyboard[52].value < 255 )
2830                    Controls.headlight_count=key_down_count(kc_keyboard[52].value);
2831         if (kc_keyboard[53].value < 255 )
2832                    Controls.headlight_count=key_down_count(kc_keyboard[53].value);
2833                   if ((use_joystick)&&(kc_superjoy[30].value < 255 )) 
2834          Controls.headlight_count=joy_get_button_down_cnt(kc_superjoy[30].value);
2835                  
2836 //--------Read Cycle Primary Key------------------
2837
2838                   if (kc_keyboard[48].value<255)
2839                          Controls.cycle_primary_count=key_down_count(kc_keyboard[48].value);
2840                   if (kc_keyboard[49].value<255)
2841                         Controls.cycle_primary_count+=key_down_count(kc_keyboard[49].value);
2842              if ((use_joystick)&&(kc_superjoy[28].value < 255 )) 
2843          Controls.cycle_primary_count+=joy_get_button_down_cnt(kc_superjoy[28].value);
2844
2845 //--------Read Cycle Secondary Key------------------
2846
2847                   if (kc_keyboard[50].value<255)
2848                          Controls.cycle_secondary_count=key_down_count(kc_keyboard[50].value);
2849                   if (kc_keyboard[51].value<255)
2850                         Controls.cycle_secondary_count+=key_down_count(kc_keyboard[51].value);
2851              if ((use_joystick)&&(kc_superjoy[29].value < 255 )) 
2852                         Controls.cycle_secondary_count=joy_get_button_down_cnt(kc_superjoy[29].value);
2853
2854 //--------Read Toggle Bomb key----------------------
2855
2856                   if (kc_keyboard[56].value<255 && key_down_count(kc_keyboard[56].value))
2857          {
2858           int bomb = Secondary_last_was_super[PROXIMITY_INDEX]?PROXIMITY_INDEX:SMART_MINE_INDEX;
2859
2860                          if (!Players[Player_num].secondary_ammo[PROXIMITY_INDEX] &&
2861                                   !Players[Player_num].secondary_ammo[SMART_MINE_INDEX])
2862                            {
2863                                  digi_play_sample_once( SOUND_BAD_SELECTION, F1_0 );
2864                                  HUD_init_message ("No bombs available!");
2865                                 }
2866                          else
2867                                 {       
2868                                  if (Players[Player_num].secondary_ammo[bomb]==0)
2869                                         {
2870                                          digi_play_sample_once( SOUND_BAD_SELECTION, F1_0 );
2871                                          HUD_init_message ("No %s available!",(bomb==SMART_MINE_INDEX)?"Smart mines":"Proximity bombs");
2872                                         }
2873                                   else
2874                                         {
2875                                Secondary_last_was_super[PROXIMITY_INDEX]=!Secondary_last_was_super[PROXIMITY_INDEX];
2876                                          digi_play_sample_once( SOUND_GOOD_SELECTION_SECONDARY, F1_0 );
2877                                         }
2878                                 }
2879                         }
2880           
2881 //---------Read Energy->Shield key----------
2882
2883         if ((Players[Player_num].flags & PLAYER_FLAGS_CONVERTER) && keyd_pressed[kc_keyboard[54].value])
2884                 transfer_energy_to_shield(key_down_time(kc_keyboard[54].value));
2885         if ((Players[Player_num].flags & PLAYER_FLAGS_CONVERTER) && keyd_pressed[kc_keyboard[55].value])
2886                 transfer_energy_to_shield(key_down_time(kc_keyboard[55].value));
2887
2888 //----------- Read fire_primary_down_count
2889         if (kc_keyboard[24].value < 255 ) Controls.fire_primary_down_count += key_down_count(kc_keyboard[24].value);
2890         if (kc_keyboard[25].value < 255 ) Controls.fire_primary_down_count += key_down_count(kc_keyboard[25].value);
2891         if ((use_joystick)&&(kc_superjoy[0].value < 255 )) Controls.fire_primary_down_count += joy_get_button_down_cnt(kc_superjoy[0].value);
2892         if ((use_mouse)&&(kc_mouse[0].value < 255 )) Controls.fire_primary_down_count += mouse_button_down_count(kc_mouse[0].value);
2893
2894 //----------- Read fire_primary_state
2895         if (kc_keyboard[24].value < 255 ) Controls.fire_primary_state |= keyd_pressed[kc_keyboard[24].value];
2896         if (kc_keyboard[25].value < 255 ) Controls.fire_primary_state |= keyd_pressed[kc_keyboard[25].value];
2897         if ((use_joystick)&&(kc_superjoy[0].value < 255 )) Controls.fire_primary_state |= joy_get_button_state(kc_superjoy[0].value);
2898         if ((use_mouse)&&(kc_mouse[0].value < 255) ) Controls.fire_primary_state |= mouse_button_state(kc_mouse[0].value);
2899
2900 //----------- Read fire_secondary_down_count
2901         if (kc_keyboard[26].value < 255 ) Controls.fire_secondary_down_count += key_down_count(kc_keyboard[26].value);
2902         if (kc_keyboard[27].value < 255 ) Controls.fire_secondary_down_count += key_down_count(kc_keyboard[27].value);
2903         if ((use_joystick)&&(kc_superjoy[1].value < 255 )) Controls.fire_secondary_down_count += joy_get_button_down_cnt(kc_superjoy[1].value);
2904         if ((use_mouse)&&(kc_mouse[1].value < 255 )) Controls.fire_secondary_down_count += mouse_button_down_count(kc_mouse[1].value);
2905
2906 //----------- Read fire_secondary_state
2907         if (kc_keyboard[26].value < 255 ) Controls.fire_secondary_state |= keyd_pressed[kc_keyboard[26].value];
2908         if (kc_keyboard[27].value < 255 ) Controls.fire_secondary_state |= keyd_pressed[kc_keyboard[27].value];
2909         if ((use_joystick)&&(kc_superjoy[1].value < 255 )) Controls.fire_secondary_state |= joy_get_button_state(kc_superjoy[1].value);
2910         if ((use_mouse)&&(kc_mouse[1].value < 255) ) Controls.fire_secondary_state |= mouse_button_state(kc_mouse[1].value);
2911
2912 //----------- Read fire_flare_down_count
2913         if (kc_keyboard[28].value < 255 ) Controls.fire_flare_down_count += key_down_count(kc_keyboard[28].value);
2914         if (kc_keyboard[29].value < 255 ) Controls.fire_flare_down_count += key_down_count(kc_keyboard[29].value);
2915         if ((use_joystick)&&(kc_superjoy[4].value < 255 )) Controls.fire_flare_down_count += joy_get_button_down_cnt(kc_superjoy[4].value);
2916         if ((use_mouse)&&(kc_mouse[4].value < 255 )) Controls.fire_flare_down_count += mouse_button_down_count(kc_mouse[4].value);
2917
2918 //----------- Read drop_bomb_down_count
2919         if (kc_keyboard[34].value < 255 ) Controls.drop_bomb_down_count += key_down_count(kc_keyboard[34].value);
2920         if (kc_keyboard[35].value < 255 ) Controls.drop_bomb_down_count += key_down_count(kc_keyboard[35].value);
2921         if ((use_joystick)&&(kc_superjoy[26].value < 255 )) Controls.drop_bomb_down_count += joy_get_button_down_cnt(kc_superjoy[26].value);
2922         if ((use_mouse)&&(kc_mouse[26].value < 255 )) Controls.drop_bomb_down_count += mouse_button_down_count(kc_mouse[26].value);
2923
2924 //----------- Read rear_view_down_count
2925         if (kc_keyboard[36].value < 255 ) Controls.rear_view_down_count += key_down_count(kc_keyboard[36].value);
2926         if (kc_keyboard[37].value < 255 ) Controls.rear_view_down_count += key_down_count(kc_keyboard[37].value);
2927         if ((use_joystick)&&(kc_superjoy[25].value < 255 )) Controls.rear_view_down_count += joy_get_button_down_cnt(kc_superjoy[25].value);
2928         if ((use_mouse)&&(kc_mouse[25].value < 255 )) Controls.rear_view_down_count += mouse_button_down_count(kc_mouse[25].value);
2929
2930 //----------- Read rear_view_down_state
2931         if (kc_keyboard[36].value < 255 ) Controls.rear_view_down_state |= keyd_pressed[kc_keyboard[36].value];
2932         if (kc_keyboard[37].value < 255 ) Controls.rear_view_down_state |= keyd_pressed[kc_keyboard[37].value];
2933         if ((use_joystick)&&(kc_superjoy[25].value < 255 )) Controls.rear_view_down_state |= joy_get_button_state(kc_superjoy[25].value);
2934         if ((use_mouse)&&(kc_mouse[25].value < 255 )) Controls.rear_view_down_state |= mouse_button_state(kc_mouse[25].value);
2935
2936 //----------- Read automap_down_count
2937         if (kc_keyboard[44].value < 255 ) Controls.automap_down_count += key_down_count(kc_keyboard[44].value);
2938         if (kc_keyboard[45].value < 255 ) Controls.automap_down_count += key_down_count(kc_keyboard[45].value);
2939
2940 //----------- Read automap_state
2941         if (kc_keyboard[44].value < 255 ) Controls.automap_state |= keyd_pressed[kc_keyboard[44].value];
2942         if (kc_keyboard[45].value < 255 ) Controls.automap_state |= keyd_pressed[kc_keyboard[45].value];
2943
2944 //----------- Read stupid-cruise-control-type of throttle.
2945         {
2946                 if ( kc_keyboard[38].value < 255 ) Cruise_speed += fixdiv(speed_factor*key_down_time(kc_keyboard[38].value)*5,FrameTime);
2947                 if ( kc_keyboard[39].value < 255 ) Cruise_speed += fixdiv(speed_factor*key_down_time(kc_keyboard[39].value)*5,FrameTime);
2948                 if ( kc_keyboard[40].value < 255 ) Cruise_speed -= fixdiv(speed_factor*key_down_time(kc_keyboard[40].value)*5,FrameTime);
2949                 if ( kc_keyboard[41].value < 255 ) Cruise_speed -= fixdiv(speed_factor*key_down_time(kc_keyboard[41].value)*5,FrameTime);
2950                 if ( (kc_keyboard[42].value < 255) && (key_down_count(kc_keyboard[42].value)) )
2951                         Cruise_speed = 0;
2952                 if ( (kc_keyboard[43].value < 255) && (key_down_count(kc_keyboard[43].value)) )
2953                         Cruise_speed = 0;
2954         
2955                 if (Cruise_speed > i2f(100) ) Cruise_speed = i2f(100);
2956                 if (Cruise_speed < 0 ) Cruise_speed = 0;
2957         
2958                 if (Controls.forward_thrust_time==0)
2959                         Controls.forward_thrust_time = fixmul(Cruise_speed,FrameTime)/100;
2960         }
2961
2962         //read_head_tracker();
2963
2964         // Read external controls
2965         if (kc_use_external_control || CybermouseActive)
2966                 kconfig_read_external_controls();
2967
2968 //----------- Clamp values between -FrameTime and FrameTime
2969         if (FrameTime > F1_0 )
2970                 mprintf( (1, "Bogus frame time of %.2f seconds\n", f2fl(FrameTime) ));
2971
2972         if (Controls.pitch_time > FrameTime/2 ) Controls.pitch_time = FrameTime/2;
2973         if (Controls.vertical_thrust_time > FrameTime ) Controls.vertical_thrust_time = FrameTime;
2974         if (Controls.heading_time > FrameTime ) Controls.heading_time = FrameTime;
2975         if (Controls.sideways_thrust_time > FrameTime ) Controls.sideways_thrust_time = FrameTime;
2976         if (Controls.bank_time > FrameTime ) Controls.bank_time = FrameTime;
2977         if (Controls.forward_thrust_time > FrameTime ) Controls.forward_thrust_time = FrameTime;
2978 //      if (Controls.afterburner_time > FrameTime ) Controls.afterburner_time = FrameTime;
2979
2980         if (Controls.pitch_time < -FrameTime/2 ) Controls.pitch_time = -FrameTime/2;
2981         if (Controls.vertical_thrust_time < -FrameTime ) Controls.vertical_thrust_time = -FrameTime;
2982         if (Controls.heading_time < -FrameTime ) Controls.heading_time = -FrameTime;
2983         if (Controls.sideways_thrust_time < -FrameTime ) Controls.sideways_thrust_time = -FrameTime;
2984         if (Controls.bank_time < -FrameTime ) Controls.bank_time = -FrameTime;
2985         if (Controls.forward_thrust_time < -FrameTime ) Controls.forward_thrust_time = -FrameTime;
2986 //      if (Controls.afterburner_time < -FrameTime ) Controls.afterburner_time = -FrameTime;
2987
2988
2989 //--------- Don't do anything if in debug mode
2990         #ifndef RELEASE
2991         if ( keyd_pressed[KEY_DELETE] ) {
2992                 memset( &Controls, 0, sizeof(control_info) );
2993         }
2994         #endif
2995 }
2996 #else
2997
2998
2999 fix Next_toggle_time[3]={0,0,0};
3000
3001 int allowed_to_toggle(int i)
3002 {
3003   //used for keeping tabs of when its ok to toggle headlight,primary,and secondary
3004  
3005         if (Next_toggle_time[i] > GameTime)
3006                 if (Next_toggle_time[i] < GameTime + (F1_0/8))  //      In case time is bogus, never wait > 1 second.
3007                         return 0;
3008
3009         Next_toggle_time[i] = GameTime + (F1_0/8);
3010
3011         return 1;
3012 }
3013
3014
3015
3016 void controls_read_all()
3017 {
3018         int i;
3019         int slide_on, bank_on;
3020         int dx, dy;
3021 #ifdef SDL_INPUT
3022         int dz;
3023 #endif
3024         int idx, idy;
3025         fix ctime;
3026         fix mouse_axis[3] = {0,0,0};
3027 #ifdef __unix__
3028         int raw_joy_axis[MAX_AXES];
3029 #else
3030         int raw_joy_axis[JOY_NUM_AXES];
3031 #endif
3032         int mouse_buttons;
3033         fix k0, k1, k2, k3, kp;
3034         fix k4, k5, k6, k7, kh;
3035         ubyte channel_masks;
3036         int use_mouse, use_joystick;
3037         int speed_factor=1;
3038
3039         mouse_buttons=0;
3040         use_mouse=0;
3041
3042         if (Game_turbo_mode)
3043                 speed_factor = 2;
3044         
3045         {
3046                 fix temp = Controls.heading_time;
3047                 fix temp1 = Controls.pitch_time;
3048                 memset( &Controls, 0, sizeof(control_info) );
3049                 Controls.heading_time = temp;
3050                 Controls.pitch_time = temp1;
3051         }
3052         slide_on = 0;
3053         bank_on = 0;
3054
3055         ctime = timer_get_fixed_seconds();
3056
3057         //---------  Read Joystick -----------
3058 #ifndef MACINTOSH
3059         if ( (LastReadTime + JOYSTICK_READ_TIME > ctime) && (Config_control_type!=CONTROL_THRUSTMASTER_FCS) ) {
3060                 if ((ctime < 0) && (LastReadTime > 0))
3061                         LastReadTime = ctime;
3062                 use_joystick=1;
3063         } else if ((Config_control_type>0) && (Config_control_type<5) ) {
3064                 LastReadTime = ctime;
3065                 channel_masks = joystick_read_raw_axis( JOY_ALL_AXIS, raw_joy_axis );
3066                 
3067                 for (i=0; i<6; i++ )    {
3068 #ifndef SDL_INPUT
3069                         if (channel_masks&(1<<i))       {
3070 #endif
3071                                 int joy_null_value = 10;
3072
3073                                 if ( (i==3) && (Config_control_type==CONTROL_THRUSTMASTER_FCS) )        {
3074                                         kconfig_read_fcs( raw_joy_axis[i] );
3075                                 } else {
3076                                         raw_joy_axis[i] = joy_get_scaled_reading( raw_joy_axis[i], i );
3077         
3078                                         if (kc_joystick[23].value==i)           // If this is the throttle
3079                                                 joy_null_value = 20;            // Then use a larger dead-zone
3080         
3081                                         if (raw_joy_axis[i] > joy_null_value) 
3082                                           raw_joy_axis[i] = ((raw_joy_axis[i]-joy_null_value)*128)/(128-joy_null_value);
3083                                         else if (raw_joy_axis[i] < -joy_null_value)
3084                                           raw_joy_axis[i] = ((raw_joy_axis[i]+joy_null_value)*128)/(128-joy_null_value);
3085                                         else
3086                                           raw_joy_axis[i] = 0;
3087                                         joy_axis[i]     = (raw_joy_axis[i]*FrameTime)/128;      
3088                                 }
3089 #ifndef SDL_INPUT
3090                         } else {
3091                                 joy_axis[i] = 0;
3092                         }
3093 #endif
3094                 }       
3095                 use_joystick=1;
3096         } else {
3097                 for (i=0; i<4; i++ )
3098                         joy_axis[i] = 0;
3099                 use_joystick=0;
3100         }
3101 #else   // MACINTOSH
3102         //---------  Read Joystick -----------
3103         if ((Config_control_type>0) && (Config_control_type<5) ) {
3104                 channel_masks = joystick_read_raw_axis( JOY_ALL_AXIS, raw_joy_axis );
3105                 for (i=0; i<4; i++ )    {
3106                         if (channel_masks&(1<<i))       {
3107                                 int joy_null_value = 10;
3108
3109                                 raw_joy_axis[i] = joy_get_scaled_reading( raw_joy_axis[i], i );
3110
3111                                 if (kc_joystick[23].value==i)           // If this is the throttle
3112                                         joy_null_value = 20;                            // Then use a larger dead-zone
3113
3114                                 if (raw_joy_axis[i] > joy_null_value) 
3115                                         raw_joy_axis[i] = ((raw_joy_axis[i]-joy_null_value)*128)/(128-joy_null_value);
3116                                 else if (raw_joy_axis[i] < -joy_null_value)
3117                                         raw_joy_axis[i] = ((raw_joy_axis[i]+joy_null_value)*128)/(128-joy_null_value);
3118                                 else
3119                                         raw_joy_axis[i] = 0;
3120                                 joy_axis[i]     = (raw_joy_axis[i]*FrameTime)/128;      
3121                         } else {
3122                                 joy_axis[i] = 0;
3123                         }
3124                 }       
3125                 use_joystick=1;
3126         } else {
3127                 for (i=0; i<4; i++ )
3128                         joy_axis[i] = 0;
3129                 use_joystick=0;
3130         }
3131 #endif          // ifndef MACINTOSH
3132
3133         if (Config_control_type==5 && !CybermouseActive) {
3134                 //---------  Read Mouse -----------
3135 #ifdef SDL_INPUT
3136                 mouse_get_delta_z( &dx, &dy, &dz );
3137 #else
3138                 mouse_get_delta( &dx, &dy );
3139 #endif
3140                 mouse_axis[0] = (dx*FrameTime)/35;
3141                 mouse_axis[1] = (dy*FrameTime)/25;
3142 #ifdef SDL_INPUT
3143                 mouse_axis[2] = (dz*FrameTime);
3144 #endif
3145                 mouse_buttons = mouse_get_btns();
3146                 //mprintf(( 0, "Mouse %d,%d b:%d, 0x%x\n", mouse_axis[0], mouse_axis[1], mouse_buttons, FrameTime ));
3147                 use_mouse=1;
3148         } else if (Config_control_type==6 && !CybermouseActive) {
3149                 //---------  Read Cyberman -----------
3150                 mouse_get_cyberman_pos(&idx,&idy );
3151                 mouse_axis[0] = (idx*FrameTime)/128;
3152                 mouse_axis[1] = (idy*FrameTime)/128;
3153                 mouse_buttons = mouse_get_btns();
3154                 use_mouse=1;
3155         } else if (CybermouseActive) {
3156 //              ReadOWL (kc_external_control);
3157 //              CybermouseAdjust();
3158         } else {
3159                 mouse_axis[0] = 0;
3160                 mouse_axis[1] = 0;
3161                 mouse_buttons = 0;
3162                 use_mouse=0;
3163         }
3164
3165 //------------- Read slide_on -------------
3166         
3167         // From keyboard...
3168         if ( kc_keyboard[8].value < 255 ) slide_on |= keyd_pressed[ kc_keyboard[8].value ];
3169         if ( kc_keyboard[9].value < 255 ) slide_on |= keyd_pressed[ kc_keyboard[9].value ];
3170         // From joystick...
3171         if ((use_joystick)&&(kc_joystick[5].value<255)) slide_on |= joy_get_button_state( kc_joystick[5].value );
3172         // From mouse...
3173         if ((use_mouse)&&(kc_mouse[5].value<255)) slide_on |= mouse_buttons & (1<<kc_mouse[5].value);
3174
3175 //------------- Read bank_on ---------------
3176
3177         // From keyboard...
3178         if ( kc_keyboard[18].value < 255 ) bank_on |= keyd_pressed[ kc_keyboard[18].value ];
3179         if ( kc_keyboard[19].value < 255 ) bank_on |= keyd_pressed[ kc_keyboard[19].value ];
3180         // From joystick...
3181         if ( (use_joystick)&&(kc_joystick[10].value < 255 )) bank_on |= joy_get_button_state( kc_joystick[10].value );
3182         // From mouse...
3183         if ( (use_mouse)&&(kc_mouse[10].value < 255 )) bank_on |= mouse_buttons & (1<<kc_mouse[10].value);
3184
3185 //------------ Read pitch_time -----------
3186         if ( !slide_on )        {
3187                 // mprintf((0, "pitch: %7.3f %7.3f: %7.3f\n", f2fl(k4), f2fl(k6), f2fl(Controls.heading_time)));
3188                 kp = 0;
3189                 k0 = speed_factor*key_down_time( kc_keyboard[0].value )/2;      // Divide by two since we want pitch to go slower
3190                 k1 = speed_factor*key_down_time( kc_keyboard[1].value )/2;
3191                 k2 = speed_factor*key_down_time( kc_keyboard[2].value )/2;
3192                 k3 = speed_factor*key_down_time( kc_keyboard[3].value )/2;
3193
3194                 // From keyboard...
3195                 if ( kc_keyboard[0].value < 255 ) kp += k0/PH_SCALE;
3196                 if ( kc_keyboard[1].value < 255 ) kp += k1/PH_SCALE;
3197                 if ( kc_keyboard[2].value < 255 ) kp -= k2/PH_SCALE;
3198                 if ( kc_keyboard[3].value < 255 ) kp -= k3/PH_SCALE;
3199
3200                 // From Cyberman...
3201                 if ((use_mouse)&&(Config_control_type==CONTROL_CYBERMAN))       {
3202                         kp += mouse_button_down_time(MB_PITCH_FORWARD)/(PH_SCALE*2);
3203                         kp -= mouse_button_down_time(MB_PITCH_BACKWARD)/(PH_SCALE*2);
3204                 }
3205         
3206                 if (kp == 0)