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