]> icculus.org git repositories - btb/d2x.git/blob - main/kconfig.c
get rid of unused external control and cyberman stuff
[btb/d2x.git] / main / kconfig.c
1 /*
2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
11 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
12 */
13
14 /*
15  *
16  * Routines to configure keyboard, joystick, etc..
17  *
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include <conf.h>
22 #endif
23
24 #ifdef WINDOWS
25 #include "desw.h"
26 #endif
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <stdarg.h>
32 #include <ctype.h>
33
34 #include "error.h"
35 #include "pstypes.h"
36 #include "gr.h"
37 #include "mono.h"
38 #include "key.h"
39 #include "palette.h"
40 #include "inferno.h"
41 #include "gamefont.h"
42 #include "iff.h"
43 #include "u_mem.h"
44 #include "joy.h"
45 #include "mouse.h"
46 #include "kconfig.h"
47 #include "gauges.h"
48 #include "joydefs.h"
49 #include "songs.h"
50 #include "render.h"
51 #include "digi.h"
52 #include "newmenu.h"
53 #include "endlevel.h"
54 #include "multi.h"
55 #include "timer.h"
56 #include "text.h"
57 #include "player.h"
58 #include "menu.h"
59 #include "automap.h"
60 #include "args.h"
61 #include "lighting.h"
62 #include "ai.h"
63 #include "cntrlcen.h"
64 #if defined (TACTILE)
65  #include "tactile.h"
66 #endif
67
68 #include "collide.h"
69
70 #ifdef USE_LINUX_JOY
71 #include "joystick.h"
72 #endif
73 #include "console.h"
74
75 ubyte ExtGameStatus=1;
76
77 vms_vector ExtForceVec;
78 vms_matrix ExtApplyForceMatrix;
79
80 int ExtJoltInfo[3]={0,0,0};
81 int ExtXVibrateInfo[2]={0,0};
82 int ExtYVibrateInfo[2]={0,0};
83 ubyte ExtXVibrateClear=0;
84 ubyte ExtYVibrateClear=0;
85
86 #define TABLE_CREATION 1
87
88 // Array used to 'blink' the cursor while waiting for a keypress.
89 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 };
90
91 //char * invert_text[2] = { "N", "Y" };
92 //char * joyaxis_text[4] = { "X1", "Y1", "X2", "Y2" };
93 //char * mouseaxis_text[2] = { "L/R", "F/B" };
94
95 int invert_text[2] = { TNUM_N, TNUM_Y };
96
97 #ifndef USE_LINUX_JOY
98 #if defined(SDL_INPUT)
99 char *joyaxis_text[JOY_MAX_AXES];
100 #else
101         int joyaxis_text[7] = { TNUM_X1, TNUM_Y1, TNUM_Z1, TNUM_UN, TNUM_P1,TNUM_R1,TNUM_YA1 };
102 //      int joyaxis_text[4] = { TNUM_X1, TNUM_Y1, TNUM_X2, TNUM_Y2 };
103 #endif
104 #endif
105
106 int mouseaxis_text[3] = { TNUM_L_R, TNUM_F_B, TNUM_Z1 };
107
108 #if !defined OGL && !defined SDL_INPUT
109 char * key_text[256] = {         \
110 "","ESC","1","2","3","4","5","6","7","8","9","0","-",                   \
111 "=","BSPC","TAB","Q","W","E","R","T","Y","U","I","O",                           \
112 "P","[","]","\x83","LCTRL","A","S","D","F",        \
113 "G","H","J","K","L",";","'","`",        \
114 "LSHFT","\\","Z","X","C","V","B","N","M",",",      \
115 ".","/","RSHFT","PAD*","LALT","SPC",      \
116 "CPSLK","F1","F2","F3","F4","F5","F6","F7","F8","F9",        \
117 "F10","NMLCK","SCLK","PAD7","PAD8","PAD9","PAD-",   \
118 "PAD4","PAD5","PAD6","PAD+","PAD1","PAD2","PAD3","PAD0", \
119 "PAD.","","","","F11","F12","","","","","","","","","",         \
120 "","","","","","","","","","","","","","","","","","","","",     \
121 "","","","","","","","","","","","","","","","","","","","",     \
122 "","","","","","","","","","","","","","","","","","",           \
123 "PAD\x83","RCTRL","","","","","","","","","","","","","", \
124 "","","","","","","","","","","PAD/","","","RALT","",      \
125 "","","","","","","","","","","","","","HOME","\x82","PGUP",     \
126 "","\x81","","\x7f","","END","\x80","PGDN","INS",       \
127 "DEL","","","","","","","","","","","","","","","","","",     \
128 "","","","","","","","","","","","","","","","","","","","",     \
129 "","","","","","","" };
130 #endif /* OGL */
131
132 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 };
133
134 //extern void GameLoop(int, int );
135
136 extern void transfer_energy_to_shield(fix);
137
138 control_info Controls;
139
140 fix Cruise_speed=0;
141
142 // macros for drawing lo/hi res kconfig screens (see scores.c as well)
143
144 #define LHX(x)          ((x)*(MenuHires?2:1))
145 #define LHY(y)          ((y)*(MenuHires?2.4:1))
146
147
148 #define BT_KEY                          0
149 //#define BT_MOUSE_BUTTON       1
150 #define BT_MOUSE_AXIS           2
151 //#define BT_JOY_BUTTON                 3
152 #define BT_JOY_AXIS                     4
153 #define BT_INVERT                               5
154
155 char *btype_text[] = { "BT_KEY", "BT_MOUSE_BUTTON", "BT_MOUSE_AXIS", "BT_JOY_BUTTON", "BT_JOY_AXIS", "BT_INVERT" };
156
157 #define INFO_Y 28
158
159 typedef struct kc_item {
160         short id;                               // The id of this item
161         short x, y;                             
162         short w1;
163         short w2;
164         short u,d,l,r;
165         //short text_num1;
166         char *text;
167         ubyte type;
168         ubyte value;            // what key,button,etc
169 } kc_item;
170
171 int Num_items=28;
172 kc_item *All_items;
173
174
175 //----------- WARNING!!!!!!! -------------------------------------------
176 // THESE NEXT FOUR BLOCKS OF DATA ARE GENERATED BY PRESSING DEL+F12 WHEN
177 // IN THE KEYBOARD CONFIG SCREEN.  BASICALLY, THAT PROCEDURE MODIFIES THE
178 // U,D,L,R FIELDS OF THE ARRAYS AND DUMPS THE NEW ARRAYS INTO KCONFIG.COD
179 //-------------------------------------------------------------------------
180
181 kc_item kc_keyboard[NUM_KEY_CONTROLS] = {
182         {  0, 15, 49, 71, 26, 55,  2, 55,  1,"Pitch forward", BT_KEY, 255 },
183         {  1, 15, 49,100, 26, 50,  3,  0, 24,"Pitch forward", BT_KEY, 255 },
184         {  2, 15, 57, 71, 26,  0,  4, 25,  3,"Pitch backward", BT_KEY, 255 },
185         {  3, 15, 57,100, 26,  1,  5,  2, 26,"Pitch backward", BT_KEY, 255 },
186         {  4, 15, 65, 71, 26,  2,  6, 27,  5,"Turn left", BT_KEY, 255 },
187         {  5, 15, 65,100, 26,  3,  7,  4, 28,"Turn left", BT_KEY, 255 },
188         {  6, 15, 73, 71, 26,  4,  8, 29,  7,"Turn right", BT_KEY, 255 },
189         {  7, 15, 73,100, 26,  5,  9,  6, 34,"Turn right", BT_KEY, 255 },
190         {  8, 15, 85, 71, 26,  6, 10, 35,  9,"Slide on", BT_KEY, 255 },
191         {  9, 15, 85,100, 26,  7, 11,  8, 36,"Slide on", BT_KEY, 255 },
192         { 10, 15, 93, 71, 26,  8, 12, 37, 11,"Slide left", BT_KEY, 255 },
193         { 11, 15, 93,100, 26,  9, 13, 10, 44,"Slide left", BT_KEY, 255 },
194         { 12, 15,101, 71, 26, 10, 14, 45, 13,"Slide right", BT_KEY, 255 },
195         { 13, 15,101,100, 26, 11, 15, 12, 30,"Slide right", BT_KEY, 255 },
196         { 14, 15,109, 71, 26, 12, 16, 31, 15,"Slide up", BT_KEY, 255 },
197         { 15, 15,109,100, 26, 13, 17, 14, 32,"Slide up", BT_KEY, 255 },
198         { 16, 15,117, 71, 26, 14, 18, 33, 17,"Slide down", BT_KEY, 255 },
199         { 17, 15,117,100, 26, 15, 19, 16, 46,"Slide down", BT_KEY, 255 },
200         { 18, 15,129, 71, 26, 16, 20, 47, 19,"Bank on", BT_KEY, 255 },
201         { 19, 15,129,100, 26, 17, 21, 18, 38,"Bank on", BT_KEY, 255 },
202         { 20, 15,137, 71, 26, 18, 22, 39, 21,"Bank left", BT_KEY, 255 },
203         { 21, 15,137,100, 26, 19, 23, 20, 40,"Bank left", BT_KEY, 255 },
204         { 22, 15,145, 71, 26, 20, 48, 41, 23,"Bank right", BT_KEY, 255 },
205         { 23, 15,145,100, 26, 21, 49, 22, 42,"Bank right", BT_KEY, 255 },
206         { 24,158, 49, 83, 26, 51, 26,  1, 25,"Fire primary", BT_KEY, 255 },
207         { 25,158, 49,112, 26, 54, 27, 24,  2,"Fire primary", BT_KEY, 255 },
208         { 26,158, 57, 83, 26, 24, 28,  3, 27,"Fire secondary", BT_KEY, 255 },
209         { 27,158, 57,112, 26, 25, 29, 26,  4,"Fire secondary", BT_KEY, 255 },
210         { 28,158, 65, 83, 26, 26, 34,  5, 29,"Fire flare", BT_KEY, 255 },
211         { 29,158, 65,112, 26, 27, 35, 28,  6,"Fire flare", BT_KEY, 255 },
212         { 30,158,105, 83, 26, 44, 32, 13, 31,"Accelerate", BT_KEY, 255 },
213         { 31,158,105,112, 26, 45, 33, 30, 14,"Accelerate", BT_KEY, 255 },
214         { 32,158,113, 83, 26, 30, 46, 15, 33,"reverse", BT_KEY, 255 },
215         { 33,158,113,112, 26, 31, 47, 32, 16,"reverse", BT_KEY, 255 },
216         { 34,158, 73, 83, 26, 28, 36,  7, 35,"Drop Bomb", BT_KEY, 255 },
217         { 35,158, 73,112, 26, 29, 37, 34,  8,"Drop Bomb", BT_KEY, 255 },
218         { 36,158, 85, 83, 26, 34, 44,  9, 37,"REAR VIEW", BT_KEY, 255 },
219         { 37,158, 85,112, 26, 35, 45, 36, 10,"REAR VIEW", BT_KEY, 255 },
220         { 38,158,133, 83, 26, 46, 40, 19, 39,"Cruise Faster", BT_KEY, 255 },
221         { 39,158,133,112, 26, 47, 41, 38, 20,"Cruise Faster", BT_KEY, 255 },
222         { 40,158,141, 83, 26, 38, 42, 21, 41,"Cruise Slower", BT_KEY, 255 },
223         { 41,158,141,112, 26, 39, 43, 40, 22,"Cruise Slower", BT_KEY, 255 },
224         { 42,158,149, 83, 26, 40, 52, 23, 43,"Cruise Off", BT_KEY, 255 },
225         { 43,158,149,112, 26, 41, 53, 42, 48,"Cruise Off", BT_KEY, 255 },
226         { 44,158, 93, 83, 26, 36, 30, 11, 45,"Automap", BT_KEY, 255 },
227         { 45,158, 93,112, 26, 37, 31, 44, 12,"Automap", BT_KEY, 255 },
228         { 46,158,121, 83, 26, 32, 38, 17, 47,"Afterburner", BT_KEY, 255 },
229         { 47,158,121,112, 26, 33, 39, 46, 18,"Afterburner", BT_KEY, 255 },
230         { 48, 15,161, 71, 26, 22, 50, 43, 49,"Cycle Primary", BT_KEY, 255 },
231         { 49, 15,161,100, 26, 23, 51, 48, 52,"Cycle Primary", BT_KEY, 255 },
232         { 50, 15,169, 71, 26, 48,  1, 53, 51,"Cycle Second", BT_KEY, 255 },
233         { 51, 15,169,100, 26, 49, 24, 50, 54,"Cycle Second", BT_KEY, 255 },
234         { 52,158,163, 83, 26, 42, 54, 49, 53,"Headlight", BT_KEY, 255 },
235         { 53,158,163,112, 26, 43, 55, 52, 50,"Headlight", BT_KEY, 255 },
236         { 54,158,171, 83, 26, 52, 56, 51, 55,"Energy->Shield", BT_KEY, 255 },
237         { 55,158,171,112, 26, 53,  0, 54,  0,"Energy->Shield", BT_KEY, 255 },
238         { 56,158,179, 83, 26, 54,  0,  0,  0,"Toggle Bomb", BT_KEY, 255 },
239 };
240
241 char *kc_key_bind_text[NUM_KEY_CONTROLS] = {
242         "+lookdown",    "+lookdown",
243         "+lookup",      "+lookup",
244         "+left",        "+left",
245         "+right",       "+right",
246         "+strafe",      "+strafe",
247         "+moveleft",    "+moveleft",
248         "+moveright",   "+moveright",
249         "+moveup",      "+moveup",
250         "+movedown",    "+movedown",
251         "+bank",        "+bank",
252         "+bankleft",    "+bankleft",
253         "+bankright",   "+bankright",
254         "+attack",      "+attack",
255         "+attack2",     "+attack2",
256         "flare",        "flare",
257         "+forward",     "+forward",
258         "+back",        "+back",
259         "bomb",         "bomb",
260         "+rearview",    "+rearview",
261         "+cruiseup",    "+cruiseup",
262         "+cruisedown",  "+cruisedown",
263         "+cruiseoff",   "+cruiseoff",
264         "+automap",     "+automap",
265         "+afterburner", "+afterburner",
266         "cycle",        "cycle",
267         "cycle2",       "cycle2",
268         "headlight",    "headlight",
269         "+nrgshield",   "+nrgshield",
270         "togglebomb",
271 };
272
273 ubyte default_kc_keyboard_settings[MAX_CONTROLS] = {0x48,0xc8,0x50,0xd0,0x4b,0xcb,0x4d,0xcd,0x38,0xff,0x4f,0xff,0x51,0xff,0x4a,0xff,0x4e,0xff,0x2a,0xff,0x10,0x47,0x12,0x49,0x1d,0x80,0x39,0x81,0x21,0x24,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,0x80,0x0,0x0};
274
275 kc_item kc_other[NUM_OTHER_CONTROLS] = {
276         {  0, 22,138, 51, 40, 23,  2, 23,  1,"Pitch U/D", BT_JOY_AXIS, 255 },
277         {  1, 22,138, 99,  8, 10,  3,  0, 12,"Pitch U/D", BT_INVERT, 255 },
278         {  2, 22,146, 51, 40,  0,  4, 13,  3,"Turn L/R", BT_JOY_AXIS, 255 },
279         {  3, 22,146, 99,  8,  1,  5,  2, 14,"Turn L/R", BT_INVERT, 255 },
280         {  4, 22,154, 51, 40,  2,  6, 15,  5,"Slide L/R", BT_JOY_AXIS, 255 },
281         {  5, 22,154, 99,  8,  3,  7,  4, 16,"Slide L/R", BT_INVERT, 255 },
282         {  6, 22,162, 51, 40,  4,  8, 17,  7,"Slide U/D", BT_JOY_AXIS, 255 },
283         {  7, 22,162, 99,  8,  5,  9,  6, 18,"Slide U/D", BT_INVERT, 255 },
284         {  8, 22,170, 51, 40,  6, 10, 19,  9,"Bank L/R", BT_JOY_AXIS, 255 },
285         {  9, 22,170, 99,  8,  7, 11,  8, 20,"Bank L/R", BT_INVERT, 255 },
286         { 10, 22,182, 51, 40,  8,  1, 21, 11,"throttle", BT_JOY_AXIS, 255 },
287         { 11, 22,182, 99,  8,  9, 12, 10, 22,"throttle", BT_INVERT, 255 },
288         { 12,182,138, 51, 40, 11, 14,  1, 13,"Pitch U/D", BT_MOUSE_AXIS, 255 },
289         { 13,182,138, 99,  8, 22, 15, 12,  2,"Pitch U/D", BT_INVERT, 255 },
290         { 14,182,146, 51, 40, 12, 16,  3, 15,"Turn L/R", BT_MOUSE_AXIS, 255 },
291         { 15,182,146, 99,  8, 13, 17, 14,  4,"Turn L/R", BT_INVERT, 255 },
292         { 16,182,154, 51, 40, 14, 18,  5, 17,"Slide L/R", BT_MOUSE_AXIS, 255 },
293         { 17,182,154, 99,  8, 15, 19, 16,  6,"Slide L/R", BT_INVERT, 255 },
294         { 18,182,162, 51, 40, 16, 20,  7, 19,"Slide U/D", BT_MOUSE_AXIS, 255 },
295         { 19,182,162, 99,  8, 17, 21, 18,  8,"Slide U/D", BT_INVERT, 255 },
296         { 20,182,170, 51, 40, 18, 22,  9, 21,"Bank L/R", BT_MOUSE_AXIS, 255 },
297         { 21,182,170, 99,  8, 19, 23, 20, 10,"Bank L/R", BT_INVERT, 255 },
298         { 22,182,182, 51, 40, 20, 13, 11, 23,"throttle", BT_MOUSE_AXIS, 255 },
299         { 23,182,182, 99,  8, 21,  0, 22,  0,"throttle", BT_INVERT, 255 },
300 };
301
302 kc_axis_map kc_other_axismap[NUM_OTHER_CONTROLS] = {
303         AXIS_PITCH,     AXIS_NONE,
304         AXIS_TURN,      AXIS_NONE,
305         AXIS_LEFTRIGHT, AXIS_NONE,
306         AXIS_UPDOWN,    AXIS_NONE,
307         AXIS_BANK,      AXIS_NONE,
308         AXIS_THROTTLE,  AXIS_NONE,
309         AXIS_PITCH,     AXIS_NONE,
310         AXIS_TURN,      AXIS_NONE,
311         AXIS_LEFTRIGHT, AXIS_NONE,
312         AXIS_UPDOWN,    AXIS_NONE,
313         AXIS_BANK,      AXIS_NONE,
314         AXIS_THROTTLE,  AXIS_NONE,
315 };
316
317 ubyte default_kc_other_settings[MAX_CONTROLS] = {0x1,0x0,0x0,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0x1,0x0,0x0,0x0,0xff,0x0,0xff,0x0,0xff,0x0,0x2,0x0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0x0,0xff,0x0,0x3f};
318
319 kc_item kc_d2x[NUM_D2X_CONTROLS] = {
320 //        id,x,y,w1,w2,u,d,l,r,text_num1,type,value
321         {  0, 15, 49, 71, 26, 19,  2, 27,  1,"WEAPON 1", BT_KEY, 255 },
322         {  1, 15, 49,100, 26, 18,  3,  0,  2,"WEAPON 1", BT_KEY, 255 },
323         {  2, 15, 57, 71, 26,  0,  4,  1,  3,"WEAPON 2", BT_KEY, 255 },
324         {  3, 15, 57,100, 26,  1,  5,  2,  4,"WEAPON 2", BT_KEY, 255 },
325         {  4, 15, 65, 71, 26,  2,  6,  3,  5,"WEAPON 3", BT_KEY, 255 },
326         {  5, 15, 65,100, 26,  3,  7,  4,  6,"WEAPON 3", BT_KEY, 255 },
327         {  6, 15, 73, 71, 26,  4,  8,  5,  7,"WEAPON 4", BT_KEY, 255 },
328         {  7, 15, 73,100, 26,  5,  9,  6,  8,"WEAPON 4", BT_KEY, 255 },
329         {  8, 15, 81, 71, 26,  6, 10,  7,  9,"WEAPON 5", BT_KEY, 255 },
330         {  9, 15, 81,100, 26,  7, 11,  8, 10,"WEAPON 5", BT_KEY, 255 },
331         { 10, 15, 89, 71, 26,  8, 12,  9, 11,"WEAPON 6", BT_KEY, 255 },
332         { 11, 15, 89,100, 26,  9, 13, 10, 12,"WEAPON 6", BT_KEY, 255 },
333         { 12, 15, 97, 71, 26, 10, 14, 11, 13,"WEAPON 7", BT_KEY, 255 },
334         { 13, 15, 97,100, 26, 11, 15, 12, 14,"WEAPON 7", BT_KEY, 255 },
335         { 14, 15,105, 71, 26, 12, 16, 13, 15,"WEAPON 8", BT_KEY, 255 },
336         { 15, 15,105,100, 26, 13, 17, 14, 16,"WEAPON 8", BT_KEY, 255 },
337         { 16, 15,113, 71, 26, 14, 18, 15, 17,"WEAPON 9", BT_KEY, 255 },
338         { 17, 15,113,100, 26, 15, 19, 16, 18,"WEAPON 9", BT_KEY, 255 },
339         { 18, 15,121, 71, 26, 16,  1, 17, 19,"WEAPON 0", BT_KEY, 255 },
340         { 19, 15,121,100, 26, 17,  0, 18,  0,"WEAPON 0", BT_KEY, 255 },
341         //{ 20, 15,131, 71, 26, 18, 22, 19, 21, "CYC PRIMARY", BT_KEY, 255},
342         //{ 21, 15,131,100, 26, 19, 23, 20, 22, "CYC PRIMARY", BT_KEY, 255},
343         //{ 22, 15,139, 71, 26, 20, 24, 21, 23, "CYC SECONDARY", BT_KEY, 255},
344         //{ 23, 15,139,100, 26, 21, 25, 22, 24, "CYC SECONDARY", BT_KEY, 255},
345         //{ 24,  8,147, 78, 26, 22, 26, 23, 25, "TOGGLE_PRIM AUTO", BT_KEY, 255},
346         //{ 25,  8,147,107, 26, 23, 27, 24, 26, "TOGGLE_PRIM_AUTO", BT_KEY, 255},
347         //{ 26,  8,155, 78, 26, 24,  1, 25, 27, "TOGGLE SEC AUTO", BT_KEY, 255},
348         //{ 27,  8,155,107, 26, 25,  0, 26,  0, "TOGGLE SEC AUTO", BT_KEY, 255},
349 };
350
351 ubyte default_kc_d2x_settings[MAX_CONTROLS] = {0x2,0xff,0x3,0xff,0x4,0xff,0x5,0xff,0x6,0xff,0x7,0xff,0x8,0xff,0x9,0xff,0xa,0xff,0xb,0xff,0xff,0x0,0xff,0xff,0x12,0xf,0x80,0x80,0x80,0x0,0x4,0x4,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x20,0x57,0x52,0x0,0x12,0xa2,0xa2,0xa4,0xa4,0xa4,0xa4,0xa4,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xff,0xff};
352
353
354 void kc_drawitem( kc_item *item, int is_current );
355 void kc_change_key( kc_item * item );
356 void kc_next_joyaxis(kc_item *item);  //added by WraithX on 11/22/00
357 void kc_change_joyaxis( kc_item * item );
358 void kc_change_mouseaxis( kc_item * item );
359 void kc_change_invert( kc_item * item );
360
361 int kconfig_is_axes_used(int axis)
362 {
363         int i;
364         for (i=0; i<NUM_OTHER_CONTROLS; i++ )   {
365                 if (( kc_other[i].type == BT_JOY_AXIS ) && (kc_other[i].value == axis ))
366                         return 1;
367         }
368         return 0;
369 }
370
371 #ifdef TABLE_CREATION
372 int find_item_at( kc_item * items, int nitems, int x, int y )
373 {
374         int i;
375         
376         for (i=0; i<nitems; i++ )       {
377                 if ( ((items[i].x+items[i].w1)==x) && (items[i].y==y))
378                         return i;
379         }
380         return -1;
381 }
382
383 int find_next_item_up( kc_item * items, int nitems, int citem )
384 {
385         int x, y, i;
386
387         y = items[citem].y;
388         x = items[citem].x+items[citem].w1;
389         
390         do {    
391                 y--;
392                 if ( y < 0 ) {
393                         y = grd_curcanv->cv_bitmap.bm_h-1;
394                         x--;
395                         if ( x < 0 ) {
396                                 x = grd_curcanv->cv_bitmap.bm_w-1;
397                         }
398                 }
399                 i = find_item_at( items, nitems, x, y );
400         } while ( i < 0 );
401         
402         return i;
403 }
404
405 int find_next_item_down( kc_item * items, int nitems, int citem )
406 {
407         int x, y, i;
408
409         y = items[citem].y;
410         x = items[citem].x+items[citem].w1;
411         
412         do {    
413                 y++;
414                 if ( y > grd_curcanv->cv_bitmap.bm_h-1 ) {
415                         y = 0;
416                         x++;
417                         if ( x > grd_curcanv->cv_bitmap.bm_w-1 ) {
418                                 x = 0;
419                         }
420                 }
421                 i = find_item_at( items, nitems, x, y );
422         } while ( i < 0 );
423         
424         return i;
425 }
426
427 int find_next_item_right( kc_item * items, int nitems, int citem )
428 {
429         int x, y, i;
430
431         y = items[citem].y;
432         x = items[citem].x+items[citem].w1;
433         
434         do {    
435                 x++;
436                 if ( x > grd_curcanv->cv_bitmap.bm_w-1 ) {
437                         x = 0;
438                         y++;
439                         if ( y > grd_curcanv->cv_bitmap.bm_h-1 ) {
440                                 y = 0;
441                         }
442                 }
443                 i = find_item_at( items, nitems, x, y );
444         } while ( i < 0 );
445         
446         return i;
447 }
448
449 int find_next_item_left( kc_item * items, int nitems, int citem )
450 {
451         int x, y, i;
452
453         y = items[citem].y;
454         x = items[citem].x+items[citem].w1;
455         
456         do {    
457                 x--;
458                 if ( x < 0 ) {
459                         x = grd_curcanv->cv_bitmap.bm_w-1;
460                         y--;
461                         if ( y < 0 ) {
462                                 y = grd_curcanv->cv_bitmap.bm_h-1;
463                         }
464                 }
465                 i = find_item_at( items, nitems, x, y );
466         } while ( i < 0 );
467         
468         return i;
469 }
470 #endif
471
472 #ifdef NEWMENU_MOUSE
473 int get_item_height(kc_item *item)
474 {
475         int w, h, aw;
476         char btext[10];
477
478         if (item->value==255) {
479                 strcpy(btext, "");
480         } else {
481                 switch( item->type )    {
482                         case BT_KEY:
483                                 strncpy( btext, key_text[item->value], 10 ); break;
484                         case BT_MOUSE_AXIS:
485                                 strncpy( btext, Text_string[mouseaxis_text[item->value]], 10 ); break;
486                         case BT_JOY_AXIS:
487 #ifdef USE_LINUX_JOY
488                                 sprintf( btext, "J%d A%d", j_axis[item->value].joydev, j_Get_joydev_axis_number (item->value) );
489 #elif defined(SDL_INPUT)
490                                 if (joyaxis_text[item->value])
491                                         strncpy(btext, joyaxis_text[item->value], 10);
492                                 else
493                                         sprintf(btext, "AXIS%2d", item->value + 1);
494 #else
495                                 strncpy(btext, Text_string[joyaxis_text[item->value]], 10);
496 #endif
497                                 break;
498                         case BT_INVERT:
499                                 strncpy( btext, Text_string[invert_text[item->value]], 10 ); break;
500                 }
501         }
502         gr_get_string_size(btext, &w, &h, &aw  );
503
504         return h;
505 }
506 #endif
507
508 void kconfig_sub(kc_item * items,int nitems, char * title)
509 {
510         grs_canvas * save_canvas;
511         grs_font * save_font;
512         int old_keyd_repeat;
513 #ifdef NEWMENU_MOUSE
514         int mouse_state, omouse_state, mx, my, x1, x2, y1, y2;
515         int close_x, close_y, close_size;
516 #endif
517
518         int i,k,ocitem,citem;
519         int time_stopped = 0;
520
521         All_items = items;
522         Num_items = nitems;
523
524         if (!((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME) && (!Endlevel_sequence)) )
525         {
526                 time_stopped = 1;
527                 stop_time();
528         }
529
530         save_canvas = grd_curcanv;
531
532
533         gr_set_current_canvas(NULL);
534         save_font = grd_curcanv->cv_font;
535
536         game_flush_inputs();
537         old_keyd_repeat = keyd_repeat;
538         keyd_repeat = 1;
539
540         //gr_clear_canvas( BM_XRGB(0,0,0) );
541
542         nm_draw_background(0, 0, grd_curcanv->cv_bitmap.bm_w - 1, grd_curcanv->cv_bitmap.bm_h - 1);
543    gr_palette_load (gr_palette);
544
545         grd_curcanv->cv_font = MEDIUM3_FONT;
546
547         {
548                 char * p;
549                 p = strchr( title, '\n' );
550                 if ( p ) *p = 32;
551                 gr_string( 0x8000, LHY(8), title );
552                 if ( p ) *p = '\n';
553         }
554
555
556 //      if ( items == kc_keyboard )     {
557 //              gr_string( 0x8000, 8, "Keyboard" );
558 //      } else if ( items == kc_other ) {
559 //              gr_string( 0x8000, 8, "Others" );
560 //      }
561
562 #ifdef NEWMENU_MOUSE
563         close_x = close_y = MenuHires?15:7;
564         close_size = MenuHires?10:5;
565         /*
566         gr_setcolor( BM_XRGB(0, 0, 0) );
567         gr_rect(close_x, close_y, close_x + close_size, close_y + close_size);
568         gr_setcolor( BM_XRGB(21, 21, 21) );
569         gr_rect(close_x + LHX(1), close_y + LHX(1), close_x + close_size - LHX(1), close_y + close_size - LHX(1));
570         */
571 #endif
572
573         grd_curcanv->cv_font = GAME_FONT;
574         gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
575
576         gr_string( 0x8000, LHY(20), TXT_KCONFIG_STRING_1 );
577         gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
578         if ( items == kc_keyboard )     {
579                 gr_set_fontcolor( BM_XRGB(31,27,6), -1 );
580                 gr_setcolor( BM_XRGB(31,27,6) );
581                 
582                 gr_scanline( LHX(98), LHX(106), LHY(42) );
583                 gr_scanline( LHX(120), LHX(128), LHY(42) );
584                 gr_pixel( LHX(98), LHY(43) );                                           
585                 gr_pixel( LHX(98), LHY(44) );                                           
586                 gr_pixel( LHX(128), LHY(43) );                                          
587                 gr_pixel( LHX(128), LHY(44) );                                          
588                 
589                 gr_string( LHX(109), LHY(40), "OR" );
590
591                 gr_scanline( LHX(253), LHX(261), LHY(42) );
592                 gr_scanline( LHX(274), LHX(283), LHY(42) );
593                 gr_pixel( LHX(253), LHY(43) );                                          
594                 gr_pixel( LHX(253), LHY(44) );                                          
595                 gr_pixel( LHX(283), LHY(43) );                                          
596                 gr_pixel( LHX(283), LHY(44) );                                          
597
598                 gr_string( LHX(264), LHY(40), "OR" );
599
600         } if ( items == kc_other )      {
601                 gr_set_fontcolor( BM_XRGB(31,27,6), -1 );
602                 gr_setcolor( BM_XRGB(31,27,6) );
603                 gr_scanline( LHX(18), LHX(60), LHY(119+5) );
604                 gr_scanline( LHX(102), LHX(144), LHY(119+5) );
605                 gr_string( LHX(63), LHY(117+5), TXT_CONTROL_JOYSTICK );
606                 gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
607                 gr_string( LHX(84), LHY(129), TXT_AXIS );
608                 gr_string( LHX(110), LHY(129), TXT_INVERT );
609
610                 gr_set_fontcolor( BM_XRGB(31,27,6), -1 );
611                 gr_setcolor( BM_XRGB(31,27,6) );
612                 gr_scanline( LHX(178), LHX(226), LHY(119+5) );
613                 gr_scanline( LHX(256), LHX(304), LHY(119+5) );
614                 gr_string( LHX(229), LHY(117+5), TXT_CONTROL_MOUSE );
615                 gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
616                 gr_string( LHX(244), LHY(129), TXT_AXIS );
617                 gr_string( LHX(270), LHY(129), TXT_INVERT );
618         }
619         else if ( items == kc_d2x )
620         {
621                 gr_set_fontcolor( BM_XRGB(31,27,6), -1 );
622                 gr_setcolor( BM_XRGB(31,27,6) );
623
624                 gr_scanline( LHX(98), LHX(106), LHY(42) );
625                 gr_scanline( LHX(120), LHX(128), LHY(42) );
626                 gr_pixel( LHX(98), LHY(43) );
627                 gr_pixel( LHX(98), LHY(44) );
628                 gr_pixel( LHX(128), LHY(43) );
629                 gr_pixel( LHX(128), LHY(44) );
630
631                 gr_string(LHX(109), LHY(40), "OR");
632         }
633
634         for (i=0; i<nitems; i++ )       {
635                 kc_drawitem( &items[i], 0 );
636         }
637
638         citem = 0;
639         while(items[citem].id == -1)
640                 citem++;
641         kc_drawitem( &items[citem], 1 );
642
643         newmenu_show_cursor();
644
645 #ifdef NEWMENU_MOUSE
646         mouse_state = omouse_state = 0;
647 #endif
648
649         while(1)                {
650         //      Windows addendum to allow for kconfig input.
651                 gr_update();
652
653                 //see if redbook song needs to be restarted
654                 songs_check_redbook_repeat();
655
656                 k = key_inkey();
657
658 #ifdef NEWMENU_MOUSE
659                 omouse_state = mouse_state;
660                 mouse_state = mouse_button_state(0);
661 #endif
662
663                 if ( !time_stopped ) {
664                         #ifdef NETWORK
665                         if (multi_menu_poll() == -1)
666                                 k = -2;
667                         #endif
668                 }
669                 ocitem = citem;
670                 switch( k )     {
671                 case KEY_BACKSP:
672                         Int3();
673                         break;
674                 case KEY_COMMAND+KEY_SHIFTED+KEY_3:
675                 case KEY_PRINT_SCREEN:
676                         save_screen_shot(0);
677                         break;                                                  
678                 case KEY_CTRLED+KEY_D:
679                         items[citem].value = 255;
680                         kc_drawitem( &items[citem], 1 );
681                         break;
682                 case KEY_CTRLED+KEY_R:  
683                         if ( items == kc_keyboard )
684                                 for (i = 0; i < NUM_KEY_CONTROLS; i++) {
685                                         items[i].value = default_kc_keyboard_settings[i];
686                                         kc_drawitem( &items[i], 0 );
687                                 }
688                         else if ( items == kc_other )
689                                 for (i = 0; i < NUM_OTHER_CONTROLS; i++) {
690                                         items[i].value = default_kc_other_settings[i];
691                                         kc_drawitem( &items[i], 0 );
692                                 }
693                         else if ( items == kc_d2x )
694                                 for (i = 0; i < NUM_D2X_CONTROLS; i++)
695                                 {
696                                         items[i].value = default_kc_d2x_settings[i];
697                                         kc_drawitem( &items[i], 0 );
698                                 }
699                         kc_drawitem( &items[citem], 1 );
700                         break;
701                 case KEY_DELETE:
702                         items[citem].value=255;
703                         kc_drawitem( &items[citem], 1 );
704                         break;
705                 case KEY_UP:            
706                 case KEY_PAD8:
707 #ifdef TABLE_CREATION
708                         if (items[citem].u==-1) items[citem].u=find_next_item_up( items,nitems, citem);
709 #endif
710                         citem = items[citem].u; 
711                         break;
712                 
713                 case KEY_DOWN:  
714                 case KEY_PAD2:
715 #ifdef TABLE_CREATION
716                         if (items[citem].d==-1) items[citem].d=find_next_item_down( items,nitems, citem);
717 #endif
718                         citem = items[citem].d; 
719                         break;
720                 case KEY_LEFT:  
721                 case KEY_PAD4:
722 #ifdef TABLE_CREATION
723                         if (items[citem].l==-1) items[citem].l=find_next_item_left( items,nitems, citem);
724 #endif
725                         citem = items[citem].l; 
726                         break;
727                 case KEY_RIGHT:         
728                 case KEY_PAD6:
729 #ifdef TABLE_CREATION
730                         if (items[citem].r==-1) items[citem].r=find_next_item_right( items,nitems, citem);
731 #endif
732                         citem = items[citem].r; 
733                         break;
734                 case KEY_ENTER: 
735                 case KEY_PADENTER:      
736                         switch( items[citem].type )     {
737                         case BT_KEY:            kc_change_key( &items[citem] ); break;
738                         case BT_MOUSE_AXIS:     kc_change_mouseaxis( &items[citem] ); break;
739                         case BT_JOY_AXIS:       kc_change_joyaxis( &items[citem] ); break;
740                         case BT_INVERT:         kc_change_invert( &items[citem] ); break;
741                         }
742                         break;
743                 //the following case added by WraithX on 11/22/00 to work around the weird joystick bug...
744                 case KEY_SPACEBAR:
745                         switch(items[citem].type)
746                         {
747                         case BT_JOY_AXIS:
748                                 kc_next_joyaxis(&items[citem]);
749                                 break;
750                         }
751                         break;
752                 //end addition by WraithX
753                 case -2:        
754                 case KEY_ESC:
755                         grd_curcanv->cv_font    = save_font;
756
757                         gr_set_current_canvas( save_canvas );
758                         keyd_repeat = old_keyd_repeat;
759                         game_flush_inputs();
760                         newmenu_hide_cursor();
761                         if (time_stopped)
762                                 start_time();
763                         return;
764 #ifdef TABLE_CREATION
765                 case KEY_DEBUGGED+KEY_SHIFTED+KEY_2:
766                 case KEY_DEBUGGED+KEY_F12:      {
767                         FILE * fp;
768                         int j;
769
770                         for (i=0; i<NUM_KEY_CONTROLS; i++ )     {
771                                 kc_keyboard[i].u = find_next_item_up( kc_keyboard,NUM_KEY_CONTROLS, i);
772                                 kc_keyboard[i].d = find_next_item_down( kc_keyboard,NUM_KEY_CONTROLS, i);
773                                 kc_keyboard[i].l = find_next_item_left( kc_keyboard,NUM_KEY_CONTROLS, i);
774                                 kc_keyboard[i].r = find_next_item_right( kc_keyboard,NUM_KEY_CONTROLS, i);
775                         }
776                         for (i=0; i<NUM_OTHER_CONTROLS; i++ )   {
777                                 kc_other[i].u = find_next_item_up( kc_other,NUM_OTHER_CONTROLS, i);
778                                 kc_other[i].d = find_next_item_down( kc_other,NUM_OTHER_CONTROLS, i);
779                                 kc_other[i].l = find_next_item_left( kc_other,NUM_OTHER_CONTROLS, i);
780                                 kc_other[i].r = find_next_item_right( kc_other,NUM_OTHER_CONTROLS, i);
781                         }
782                         fp = stderr; //fopen( "kconfig.cod", "wt" );
783
784                         fprintf( fp, "kc_item kc_keyboard[NUM_KEY_CONTROLS] = {\n" );
785                         for (i=0; i<NUM_KEY_CONTROLS; i++ )     {
786                                 fprintf( fp, "\t{ %2d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%c%s%c, %s, 255 },\n", 
787                                         kc_keyboard[i].id, kc_keyboard[i].x, kc_keyboard[i].y, kc_keyboard[i].w1, kc_keyboard[i].w2,
788                                         kc_keyboard[i].u, kc_keyboard[i].d, kc_keyboard[i].l, kc_keyboard[i].r,
789                                         34, kc_keyboard[i].text, 34, btype_text[kc_keyboard[i].type] );
790                         }
791                         fprintf( fp, "};\n\n" );
792                         fprintf( fp, "ubyte default_kc_keyboard_settings[MAX_CONTROLS] = " );
793                         fprintf( fp, "{0x%x", kc_keyboard[0].value );
794                         for (j = 1; j < MAX_CONTROLS; j++)
795                                 fprintf( fp, ",0x%x", kc_keyboard[j].value );
796                         fprintf( fp, "};\n\n" );
797
798                         fprintf( fp, "kc_item kc_other[NUM_OTHER_CONTROLS] = {\n" );
799                         for (i=0; i<NUM_OTHER_CONTROLS; i++ )   {
800                                 fprintf( fp, "\t{ %2d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%c%s%c, %s, 255 },\n",
801                                         kc_other[i].id, kc_other[i].x, kc_other[i].y, kc_other[i].w1, kc_other[i].w2,
802                                         kc_other[i].u, kc_other[i].d, kc_other[i].l, kc_other[i].r,
803                                         34, kc_other[i].text, 34, btype_text[kc_other[i].type] );
804                         }
805                         fprintf( fp, "};\n\n" );
806                         fprintf( fp, "ubyte default_kc_other_settings[MAX_CONTROLS] = " );
807                         fprintf( fp, "{0x%x", kc_other[0].value );
808                         for (j = 1; j < MAX_CONTROLS; j++)
809                                 fprintf( fp, ",0x%x", kc_other[j].value );
810                         fprintf( fp, "};\n" );
811
812                         fprintf( fp, "kc_item kc_d2x[NUM_D2X_CONTROLS] = {\n" );
813                         for (i=0; i<NUM_D2X_CONTROLS; i++ )     {
814                                 fprintf( fp, "\t{ %2d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%c%s%c, %s, 255 },\n",
815                                                 kc_d2x[i].id, kc_d2x[i].x, kc_d2x[i].y, kc_d2x[i].w1, kc_d2x[i].w2,
816                                                 kc_d2x[i].u, kc_d2x[i].d, kc_d2x[i].l, kc_d2x[i].r,
817                                                 34, kc_d2x[i].text, 34, btype_text[kc_d2x[i].type] );
818                         }
819                         fprintf( fp, "};\n\n" );
820                         fprintf( fp, "ubyte default_kc_d2x_settings[MAX_CONTROLS] = " );
821                         fprintf( fp, "{0x%x", kc_d2x[0].value );
822                         for (j = 1; j < MAX_CONTROLS; j++)
823                                 fprintf( fp, ",0x%x", kc_d2x[j].value );
824                         fprintf( fp, "};\n" );
825
826                         fclose(fp);
827
828                         }
829                         break;
830 #endif
831                 }
832
833 #ifdef NEWMENU_MOUSE
834                 if ( (mouse_state && !omouse_state) || (mouse_state && omouse_state) ) {
835                         int item_height;
836                         
837                         mouse_get_pos(&mx, &my);
838                         for (i=0; i<nitems; i++ )       {
839                                 item_height = get_item_height( &items[i] );
840                                 x1 = grd_curcanv->cv_bitmap.bm_x + LHX(items[i].x) + LHX(items[i].w1);
841                                 x2 = x1 + LHX(items[i].w2);
842                                 y1 = grd_curcanv->cv_bitmap.bm_y + LHY(items[i].y);
843                                 y2 = y1 + LHX(item_height);
844                                 if (((mx > x1) && (mx < x2)) && ((my > y1) && (my < y2))) {
845                                         citem = i;
846                                         break;
847                                 }
848                         }
849                 }
850                 else if ( !mouse_state && omouse_state ) {
851                         int item_height;
852                         
853                         mouse_get_pos(&mx, &my);
854                         item_height = get_item_height( &items[citem] );
855                         x1 = grd_curcanv->cv_bitmap.bm_x + LHX(items[citem].x) + LHX(items[citem].w1);
856                         x2 = x1 + LHX(items[citem].w2);
857                         y1 = grd_curcanv->cv_bitmap.bm_y + LHY(items[citem].y);
858                         y2 = y1 + LHY(item_height);
859                         if (((mx > x1) && (mx < x2)) && ((my > y1) && (my < y2))) {
860                                 newmenu_hide_cursor();
861                                 switch( items[citem].type )     {
862                                 case BT_KEY:                            kc_change_key( &items[citem] ); break;
863                                 case BT_MOUSE_AXIS:             kc_change_mouseaxis( &items[citem] ); break;
864                                 case BT_JOY_AXIS:               kc_change_joyaxis( &items[citem] ); break;
865                                 case BT_INVERT:                         kc_change_invert( &items[citem] ); break;
866                                 }
867                                 newmenu_show_cursor();
868                         } else {
869                                 x1 = grd_curcanv->cv_bitmap.bm_x + close_x + LHX(1);
870                                 x2 = x1 + close_size - LHX(1);
871                                 y1 = grd_curcanv->cv_bitmap.bm_y + close_y + LHX(1);
872                                 y2 = y1 + close_size - LHX(1);
873                                 if ( ((mx > x1) && (mx < x2)) && ((my > y1) && (my < y2)) ) {
874                                         grd_curcanv->cv_font    = save_font;
875                                         gr_set_current_canvas( save_canvas );
876                                         keyd_repeat = old_keyd_repeat;
877                                         game_flush_inputs();
878                                         newmenu_hide_cursor();
879                                         if (time_stopped)
880                                                 start_time();
881                                         return;
882                                 }
883                         }
884
885                 }
886 #endif // NEWMENU_MOUSE
887
888                 if (ocitem!=citem)      {
889                         newmenu_hide_cursor();
890                         kc_drawitem( &items[ocitem], 0 );
891                         kc_drawitem( &items[citem], 1 );
892                         newmenu_show_cursor();
893                 }
894         }
895 }
896
897
898 void kc_drawitem( kc_item *item, int is_current )
899 {
900         int x, w, h, aw;
901         char btext[16];
902
903         if (is_current)
904                 gr_set_fontcolor( BM_XRGB(20,20,29), -1 );
905         else
906                 gr_set_fontcolor( BM_XRGB(15,15,24), -1 );
907    gr_string( LHX(item->x), LHY(item->y), item->text );
908
909         if (item->value==255) {
910                 strcpy( btext, "" );
911         } else {
912                 switch( item->type )    {
913                         case BT_KEY:
914                                 strncpy( btext, key_text[item->value], 10 ); break;
915                         case BT_MOUSE_AXIS:
916                                 strncpy( btext, Text_string[mouseaxis_text[item->value]], 10 ); break;
917                         case BT_JOY_AXIS:
918 #ifdef USE_LINUX_JOY
919                                 sprintf(btext, "J%d A%d", j_axis[item->value].joydev, j_Get_joydev_axis_number(item->value));
920 #elif defined(SDL_INPUT)
921                                 if (joyaxis_text[item->value])
922                                         strncpy(btext, joyaxis_text[item->value], 10);
923                                 else
924                                         sprintf(btext, "AXIS%2d", item->value + 1);
925 #else
926                                 strncpy(btext, Text_string[joyaxis_text[item->value]], 10);
927 #endif
928                                 break;
929                         case BT_INVERT:
930                                 strncpy( btext, Text_string[invert_text[item->value]], 10 ); break;
931                 }
932         }
933         if (item->w1) {
934                 gr_get_string_size(btext, &w, &h, &aw  );
935
936                 if (is_current)
937                         gr_setcolor( BM_XRGB(21,0,24) );
938                 else
939                         gr_setcolor( BM_XRGB(16,0,19) );
940                 gr_urect( LHX(item->w1+item->x), LHY(item->y-1), LHX(item->w1+item->x+item->w2), LHY(item->y)+h );
941                 
942                 gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
943
944                 x = LHX(item->w1+item->x)+((LHX(item->w2)-w)/2);
945         
946                 gr_string( x, LHY(item->y), btext );
947         }
948 }
949
950
951 static int looper=0;
952
953 void kc_drawquestion( kc_item *item )
954 {
955         int c, x, w, h, aw;
956
957         gr_get_string_size("?", &w, &h, &aw  );
958
959         c = BM_XRGB(21,0,24);
960
961         //@@gr_setcolor( gr_fade_table[fades[looper]*256+c] );
962         gr_setcolor(BM_XRGB(21*fades[looper]/31,0,24*fades[looper]/31));
963         looper++;
964         if (looper>63) looper=0;
965
966         gr_urect( LHX(item->w1+item->x), LHY(item->y-1), LHX(item->w1+item->x+item->w2), LHY(item->y)+h );
967         
968         gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
969
970         x = LHX(item->w1+item->x)+((LHX(item->w2)-w)/2);
971    
972         gr_string( x, LHY(item->y), "?" );
973 gr_update();
974 }
975
976 void kc_change_key( kc_item * item )
977 {
978         int i,n,f,k;
979         ubyte keycode;
980
981         gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
982         
983         gr_string( 0x8000, LHY(INFO_Y), TXT_PRESS_NEW_KEY );
984
985         game_flush_inputs();
986         keycode=255;
987         k=255;
988         
989         while( (k!=KEY_ESC) && (keycode==255) ) 
990         {                               
991                 #ifdef NETWORK
992                 if ((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME) && (!Endlevel_sequence))
993                         multi_menu_poll();
994                 #endif
995 //              if ( Game_mode & GM_MULTI )
996 //                      GameLoop( 0, 0 );                               // Continue
997                 k = key_inkey();
998                 timer_delay(f0_1/10);
999                 kc_drawquestion( item );
1000         
1001                 for (i=0; i<256; i++ )  {
1002                         if (keyd_pressed[i] && (strlen(key_text[i])>0)) {
1003                                 f = 0;
1004                                 for (n=0; n<sizeof(system_keys); n++ )
1005                                         if ( system_keys[n] == i )
1006                                                 f=1;
1007                                 if (!f) 
1008                                         keycode=i;
1009                         }
1010                 }
1011         }
1012
1013         if (k!=KEY_ESC) {
1014                 for (i=0; i<Num_items; i++ )    {
1015                         n = item - All_items;
1016                         if ( (i!=n) && (All_items[i].type==BT_KEY) && (All_items[i].value==keycode) )           {
1017                                 All_items[i].value = 255;
1018                                 kc_drawitem( &All_items[i], 0 );
1019                         }
1020                 }
1021                 item->value = keycode;
1022         }
1023         kc_drawitem( item, 1 );
1024
1025         gr_set_fontcolor( BM_XRGB(28,28,28), BM_XRGB(0,0,0) );
1026
1027         nm_restore_background( 0, LHY(INFO_Y), LHX(310), grd_curcanv->cv_font->ft_h );
1028
1029         game_flush_inputs();
1030
1031 }
1032
1033
1034 // 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
1035 void kc_next_joyaxis(kc_item *item)
1036 {
1037         int n, i, k, max, tries;
1038         ubyte code = 0;
1039
1040         k = 255;
1041         n = 0;
1042         i = 0;
1043
1044         // I modelled this ifdef after the code in the kc_change_joyaxis method.
1045         // So, if somethin's not workin here, it might not be workin there either.
1046         max = JOY_MAX_AXES;
1047         tries = 1;
1048         code = (item->value + 1) % max;
1049
1050         if (code != 255)
1051         {
1052                 for (i = 0; i < Num_items; i++)
1053                 {
1054                         n = item - All_items;
1055                         if ((i != n) && (All_items[i].type == BT_JOY_AXIS) && (All_items[i].value == code))
1056                         {
1057                                 if (tries > max)
1058                                         return; // all axes allocated already
1059                                 i = -1; // -1 so the i++ will push back to 0
1060                                 code = (item->value + ++tries) % max; // try next axis
1061                         }//end if
1062                 }//end for
1063
1064                 item->value = code;
1065         }//end if
1066
1067         kc_drawitem(item, 1);
1068         nm_restore_background(0, LHY(INFO_Y), LHX(310), grd_curcanv->cv_font->ft_h);
1069         game_flush_inputs();
1070
1071 }//method kc_next_joyaxis
1072 //end addition by WraithX
1073
1074
1075 void kc_change_joyaxis( kc_item * item )
1076 {
1077         int axis[JOY_MAX_AXES];
1078         int old_axis[JOY_MAX_AXES];
1079         int numaxis = joy_num_axes;
1080         int n,i,k;
1081         ubyte code;
1082
1083         gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
1084         
1085         gr_string( 0x8000, LHY(INFO_Y), TXT_MOVE_NEW_JOY_AXIS );
1086
1087         game_flush_inputs();
1088         code=255;
1089         k=255;
1090
1091         joystick_read_raw_axis( JOY_ALL_AXIS, old_axis );
1092
1093         while( (k!=KEY_ESC) && (code==255))     
1094         {                               
1095                 #ifdef NETWORK
1096                 if ((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME) && (!Endlevel_sequence))
1097                         multi_menu_poll();
1098                 #endif
1099 //              if ( Game_mode & GM_MULTI )
1100 //                      GameLoop( 0, 0 );                               // Continue
1101                 k = key_inkey();
1102                 timer_delay(f0_1/10);
1103
1104                 if (k == KEY_PRINT_SCREEN)
1105                         save_screen_shot(0);
1106
1107                 kc_drawquestion( item );
1108
1109                 joystick_read_raw_axis( JOY_ALL_AXIS, axis );
1110
1111                 for (i=0; i<numaxis; i++ )      {
1112                         if ( abs(axis[i]-old_axis[i])>100 )
1113                         {
1114                                 code = i;
1115                                 con_printf(CON_DEBUG, "Axis Movement detected: Axis %i\n", i);
1116                         }
1117                         //old_axis[i] = axis[i];
1118                 }
1119                 for (i=0; i<Num_items; i++ )    
1120                  {
1121                         n = item - All_items;
1122                         if ( (i!=n) && (All_items[i].type==BT_JOY_AXIS) && (All_items[i].value==code) ) 
1123                                 code = 255;
1124                  }
1125         
1126         }
1127         if (code!=255)  {
1128                 for (i=0; i<Num_items; i++ )    {
1129                         n = item - All_items;
1130                         if ( (i!=n) && (All_items[i].type==BT_JOY_AXIS) && (All_items[i].value==code) ) {
1131                                 All_items[i].value = 255;
1132                                 kc_drawitem( &All_items[i], 0 );
1133                         }
1134                 }
1135
1136                 item->value = code;                                      
1137         }
1138         kc_drawitem( item, 1 );
1139         nm_restore_background( 0, LHY(INFO_Y), LHX(310), grd_curcanv->cv_font->ft_h );
1140         game_flush_inputs();
1141
1142 }
1143
1144 void kc_change_mouseaxis( kc_item * item )
1145 {
1146         int i,n,k;
1147         ubyte code;
1148         int dx, dy, dz;
1149
1150         gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
1151         
1152         gr_string( 0x8000, LHY(INFO_Y), TXT_MOVE_NEW_MSE_AXIS );
1153
1154         game_flush_inputs();
1155         code=255;
1156         k=255;
1157
1158         mouse_get_delta( &dx, &dy, &dz );
1159
1160         while( (k!=KEY_ESC) && (code==255))     
1161         {                               
1162                 #ifdef NETWORK
1163                 if ((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME) && (!Endlevel_sequence))
1164                         multi_menu_poll();
1165                 #endif
1166 //              if ( Game_mode & GM_MULTI )
1167 //                      GameLoop( 0, 0 );                               // Continue
1168                 k = key_inkey();
1169                 timer_delay(f0_1/10);
1170
1171                 if (k == KEY_PRINT_SCREEN)
1172                         save_screen_shot(0);
1173
1174                 kc_drawquestion( item );
1175
1176                 mouse_get_delta( &dx, &dy, &dz );
1177                 if ( abs(dx)>20 ) code = 0;
1178                 if ( abs(dy)>20 ) code = 1;
1179                 if ( abs(dz)>20 ) code = 2;
1180         }
1181         if (code!=255)  {
1182                 for (i=0; i<Num_items; i++ )    {
1183                         n = item - All_items;
1184                         if ( (i!=n) && (All_items[i].type==BT_MOUSE_AXIS) && (All_items[i].value==code) )               {
1185                                 All_items[i].value = 255;
1186                                 kc_drawitem( &All_items[i], 0 );
1187                         }
1188                 }
1189                 item->value = code;
1190         }
1191         kc_drawitem( item, 1 );
1192         nm_restore_background( 0, LHY(INFO_Y), LHX(310), grd_curcanv->cv_font->ft_h );
1193         game_flush_inputs();
1194
1195 }
1196
1197
1198 void kc_change_invert( kc_item * item )
1199 {
1200         game_flush_inputs();
1201
1202         if (item->value)
1203                 item->value = 0;
1204         else 
1205                 item->value = 1;
1206
1207         kc_drawitem( item, 1 );
1208
1209 }
1210
1211 #include "screens.h"
1212
1213 void kconfig(int n, char * title)
1214 {
1215         int i, j;
1216         grs_bitmap *save_bm;
1217
1218         set_screen_mode( SCREEN_MENU );
1219
1220         kc_set_controls();
1221
1222         //save screen
1223         save_bm = gr_create_bitmap( grd_curcanv->cv_bitmap.bm_w, grd_curcanv->cv_bitmap.bm_h );
1224         Assert( save_bm != NULL );
1225         
1226         gr_bm_bitblt(grd_curcanv->cv_bitmap.bm_w, grd_curcanv->cv_bitmap.bm_w, 
1227                                         0, 0, 0, 0, &grd_curcanv->cv_bitmap, save_bm );
1228
1229         switch(n)       {
1230         case 0:kconfig_sub( kc_keyboard, NUM_KEY_CONTROLS, title );break;
1231         case 1:kconfig_sub( kc_other, NUM_OTHER_CONTROLS, title );break;
1232         case 2:kconfig_sub( kc_d2x, NUM_D2X_CONTROLS, title ); break;
1233         default:
1234                 Int3();
1235                 return;
1236         }
1237
1238         //restore screen
1239         gr_bitmap(0, 0, save_bm);
1240         gr_free_bitmap(save_bm);
1241
1242 #if 0 // set_screen_mode always calls this later... right?
1243         reset_cockpit();                //force cockpit redraw next time
1244 #endif
1245
1246         // Update save values...
1247         
1248         for (j=0; j<256; j++)
1249                 if (key_binding(j)) {
1250                         for (i = 0; i < NUM_KEY_CONTROLS; i++)
1251                                 if (!stricmp(key_binding(j), kc_key_bind_text[i])) {
1252                                         cmd_appendf("unbind %s", key_text[j]);
1253                                         break;
1254                                 }
1255                         for (i = 0; i < NUM_D2X_CONTROLS; i++)
1256                                 if (kc_d2x[i].type == BT_KEY && !stricmp(key_binding(j), kc_d2x[i].text)) {
1257                                         cmd_appendf("unbind %s", key_text[j]);
1258                                         break;
1259                                 }
1260                 }
1261
1262         for (i=0; i<NUM_KEY_CONTROLS; i++ )
1263                 if (kc_keyboard[i].value != 255)
1264                         cmd_appendf("bind %s \"%s\"", key_text[kc_keyboard[i].value], kc_key_bind_text[i]);
1265
1266         for (i = 0; i < NUM_D2X_CONTROLS; i++)
1267                 if (kc_d2x[i].value != 255)
1268                         cmd_appendf("bind %s \"%s\"", key_text[kc_d2x[i].value], kc_d2x[i].text);
1269
1270         for (i = 0; i < 6; i++) {
1271                 cvar_setint(&joy_advaxes[i], AXIS_NONE);
1272                 cvar_setint(&joy_invert[i], 0);
1273         }
1274         for (i = 0; i < 3; i++) {
1275                 cvar_setint(&mouse_axes[i], AXIS_NONE);
1276                 cvar_setint(&mouse_invert[i], 0);
1277         }
1278         for (i = 0; i < NUM_OTHER_CONTROLS; i++) {
1279                 if (kc_other[i].type == BT_JOY_AXIS && kc_other[i].value != 255) {
1280                         cvar_setint(&joy_advaxes[kc_other[i].value], kc_other_axismap[i]);
1281                         cvar_setint(&joy_invert[kc_other[i].value], kc_other[i+1].value);
1282                 }
1283                 if (kc_other[i].type == BT_MOUSE_AXIS && kc_other[i].value != 255) {
1284                         cvar_setint(&mouse_axes[kc_other[i].value], kc_other_axismap[i]);
1285                         cvar_setint(&mouse_invert[kc_other[i].value], kc_other[i+1].value);
1286                 }
1287         }
1288
1289         cmd_queue_process();
1290 }
1291
1292
1293 fix Last_angles_p = 0;
1294 fix Last_angles_b = 0;
1295 fix Last_angles_h = 0;
1296 ubyte Last_angles_read = 0;
1297
1298 extern int                      VR_sensitivity;
1299                                                 
1300 int VR_sense_range[3] = { 25, 50, 75 };
1301
1302 #if 0 // unused
1303 read_head_tracker()
1304 {
1305         fix yaw, pitch, roll;
1306         int buttons;
1307
1308 //------ read vfx1 helmet --------
1309         if (vfx1_installed) {
1310                 vfx_get_data(&yaw,&pitch,&roll,&buttons);
1311         } else if (iglasses_headset_installed)  {
1312                 iglasses_read_headset( &yaw, &pitch, &roll );
1313         } else if (Victor_headset_installed)   {
1314                 victor_read_headset_filtered( &yaw, &pitch, &roll );
1315         } else {
1316                 return;
1317         }
1318
1319         Use_player_head_angles = 0;
1320         if ( Last_angles_read ) {
1321                 fix yaw1 = yaw;
1322                 
1323                 yaw1 = yaw;
1324                 if ( (Last_angles_h < (F1_0/4) ) && (yaw > ((F1_0*3)/4) ) )     
1325                         yaw1 -= F1_0;
1326                 else if ( (yaw < (F1_0/4) ) && (Last_angles_h > ((F1_0*3)/4) ) )        
1327                         yaw1 += F1_0;
1328         
1329                 Controls.pitch_time     += fixmul((pitch- Last_angles_p)*VR_sense_range[VR_sensitivity],FrameTime);
1330                 Controls.heading_time+= fixmul((yaw1 -  Last_angles_h)*VR_sense_range[VR_sensitivity],FrameTime);
1331                 Controls.bank_time      += fixmul((roll - Last_angles_b)*VR_sense_range[VR_sensitivity],FrameTime);
1332         }
1333         Last_angles_read = 1;
1334         Last_angles_p = pitch;
1335         Last_angles_h = yaw;
1336         Last_angles_b = roll;
1337 }
1338 #endif
1339
1340 #define PH_SCALE        8
1341
1342 #ifndef __MSDOS__
1343 #define JOYSTICK_READ_TIME      (F1_0/40)               //      Read joystick at 40 Hz.
1344 #else
1345 #define JOYSTICK_READ_TIME      (F1_0/10)               //      Read joystick at 10 Hz.
1346 #endif
1347
1348 fix     LastReadTime = 0;
1349
1350 fix     joy_axis[JOY_MAX_AXES];
1351
1352 extern int Automap_active;
1353
1354 fix Next_toggle_time[3]={0,0,0};
1355
1356 int allowed_to_toggle(int i)
1357 {
1358   //used for keeping tabs of when its ok to toggle headlight,primary,and secondary
1359  
1360         if (Next_toggle_time[i] > GameTime)
1361                 if (Next_toggle_time[i] < GameTime + (F1_0/8))  //      In case time is bogus, never wait > 1 second.
1362                         return 0;
1363
1364         Next_toggle_time[i] = GameTime + (F1_0/8);
1365
1366         return 1;
1367 }
1368
1369
1370 void kc_cmd_attack_on(int argc, char **argv)     { Controls.fire_primary_state = 1; Controls.fire_primary_down_count++; }
1371 void kc_cmd_attack_off(int argc, char **argv)    { Controls.fire_primary_state = 0; }
1372 void kc_cmd_attack2_on(int argc, char **argv)    { Controls.fire_secondary_state = 1; Controls.fire_secondary_down_count++; }
1373 void kc_cmd_attack2_off(int argc, char **argv)   { Controls.fire_secondary_state = 0; }
1374 void kc_cmd_rearview_on(int argc, char **argv)   { Controls.rear_view_down_state = 1; Controls.rear_view_down_count++; }
1375 void kc_cmd_rearview_off(int argc, char **argv)  { Controls.rear_view_down_state = 0; }
1376 void kc_cmd_automap_on(int argc, char **argv)    { Controls.automap_state = 1; Controls.automap_down_count++; }
1377 void kc_cmd_automap_off(int argc, char **argv)   { Controls.automap_state = 0; }
1378 void kc_cmd_afterburn_on(int argc, char **argv)  { Controls.afterburner_state = 1; }
1379 void kc_cmd_afterburn_off(int argc, char **argv) { Controls.afterburner_state = 0; }
1380 void kc_cmd_flare(int argc, char **argv)         { Controls.fire_flare_down_count++; }
1381 void kc_cmd_bomb(int argc, char **argv)          { Controls.drop_bomb_down_count++; }
1382 void kc_cmd_cycle(int argc, char **argv)         { Controls.cycle_primary_count++; }
1383 void kc_cmd_cycle2(int argc, char **argv)        { Controls.cycle_secondary_count++; }
1384 void kc_cmd_headlight(int argc, char **argv)     { Controls.headlight_count++; }
1385
1386 void kc_cmd_togglebomb(int argc, char **argv)
1387 {
1388         int bomb = Secondary_last_was_super[PROXIMITY_INDEX]?PROXIMITY_INDEX:SMART_MINE_INDEX;
1389
1390         if (!Players[Player_num].secondary_ammo[PROXIMITY_INDEX] &&
1391                 !Players[Player_num].secondary_ammo[SMART_MINE_INDEX])
1392         {
1393                 digi_play_sample_once( SOUND_BAD_SELECTION, F1_0 );
1394                 HUD_init_message ("No bombs available!");
1395         } else {
1396                 if (Players[Player_num].secondary_ammo[bomb] == 0) {
1397                         digi_play_sample_once( SOUND_BAD_SELECTION, F1_0 );
1398                         HUD_init_message("No %s available!", (bomb == SMART_MINE_INDEX)?"Smart mines":"Proximity bombs");
1399                 } else {
1400                         Secondary_last_was_super[PROXIMITY_INDEX]=!Secondary_last_was_super[PROXIMITY_INDEX];
1401                         digi_play_sample_once( SOUND_GOOD_SELECTION_SECONDARY, F1_0 );
1402                 }
1403         }
1404 }
1405
1406
1407 void kconfig_init(void)
1408 {
1409         cmd_addcommand("+attack",      kc_cmd_attack_on);
1410         cmd_addcommand("-attack",      kc_cmd_attack_off);
1411         cmd_addcommand("+attack2",     kc_cmd_attack2_on);
1412         cmd_addcommand("-attack2",     kc_cmd_attack2_off);
1413         cmd_addcommand("+rearview",    kc_cmd_rearview_on);
1414         cmd_addcommand("-rearview",    kc_cmd_rearview_off);
1415         cmd_addcommand("+automap",     kc_cmd_automap_on);
1416         cmd_addcommand("-automap",     kc_cmd_automap_off);
1417         cmd_addcommand("+afterburner", kc_cmd_afterburn_on);
1418         cmd_addcommand("-afterburner", kc_cmd_afterburn_off);
1419         cmd_addcommand("flare",        kc_cmd_flare);
1420         cmd_addcommand("bomb",         kc_cmd_bomb);
1421         cmd_addcommand("cycle",        kc_cmd_cycle);
1422         cmd_addcommand("cycle2",       kc_cmd_cycle2);
1423         cmd_addcommand("headlight",    kc_cmd_headlight);
1424         cmd_addcommand("togglebomb",   kc_cmd_togglebomb);
1425 }
1426
1427
1428 /* Preserves pitch, heading, and states */
1429 void controls_reset(void)
1430 {
1431         Controls.forward_thrust_time = 0;
1432         Controls.sideways_thrust_time = 0;
1433         Controls.vertical_thrust_time = 0;
1434         Controls.bank_time = 0;
1435         Controls.rear_view_down_count = 0;
1436         Controls.fire_primary_down_count = 0;
1437         Controls.fire_secondary_down_count = 0;
1438         Controls.fire_flare_down_count = 0;
1439         Controls.drop_bomb_down_count = 0;
1440         Controls.automap_down_count = 0;
1441         Controls.cycle_primary_count = 0;
1442         Controls.cycle_secondary_count = 0;
1443         Controls.headlight_count = 0;
1444 }
1445
1446
1447 void controls_read_all()
1448 {
1449         int i;
1450         int slide_on, bank_on;
1451         int dx, dy, dz;
1452         fix ctime;
1453         int raw_joy_axis[JOY_MAX_AXES];
1454         fix kp, kh;
1455         ubyte channel_masks;
1456         fix analog_control[7]; // indexed on kc_axis_map
1457
1458         memset(analog_control, 0, sizeof(analog_control));
1459
1460         controls_reset();
1461
1462         cmd_queue_process();
1463
1464         slide_on = 0;
1465         bank_on = 0;
1466
1467         ctime = timer_get_fixed_seconds();
1468
1469         //---------  Read Joystick -----------
1470         if ( (LastReadTime + JOYSTICK_READ_TIME > ctime) ) {
1471 # ifndef __MSDOS__
1472                 if ((ctime < 0) && (LastReadTime >= 0))
1473 # else
1474                 if ((ctime < 0) && (LastReadTime > 0))
1475 # endif
1476                         LastReadTime = ctime;
1477         } else if (Config_control_joystick.intval) {
1478                 LastReadTime = ctime;
1479                 channel_masks = joystick_read_raw_axis( JOY_ALL_AXIS, raw_joy_axis );
1480
1481                 Assert(joy_num_axes <= 6); // don't have cvar mapping above 6 yet
1482                 for (i = 0; i < joy_num_axes; i++)
1483                 {
1484 #ifndef SDL_INPUT
1485                         if (channel_masks&(1<<i))       {
1486 #endif
1487                                         int joy_null_value = f2i(Config_joystick_deadzone[joy_advaxes[i].intval-1].intval * 128);
1488
1489                                         raw_joy_axis[i] = joy_get_scaled_reading( raw_joy_axis[i], i );
1490
1491                                         if (raw_joy_axis[i] > joy_null_value) 
1492                                           raw_joy_axis[i] = ((raw_joy_axis[i]-joy_null_value)*128)/(128-joy_null_value);
1493                                         else if (raw_joy_axis[i] < -joy_null_value)
1494                                           raw_joy_axis[i] = ((raw_joy_axis[i]+joy_null_value)*128)/(128-joy_null_value);
1495                                         else
1496                                           raw_joy_axis[i] = 0;
1497                                         joy_axis[i]     = (raw_joy_axis[i]*FrameTime)/128;      
1498 #ifndef SDL_INPUT
1499                         } else {
1500                                 joy_axis[i] = 0;
1501                         }
1502 #endif
1503                 }       
1504         } else {
1505                 for (i = 0; i < joy_num_axes; i++)
1506                         joy_axis[i] = 0;
1507         }
1508
1509         if (Config_control_joystick.intval)
1510                 for (i = 0; i < 6; i++)
1511                         analog_control[joy_advaxes[i].intval] += joy_axis[i] * (joy_invert[i].intval ? -1 : 1) * Config_joystick_sensitivity[joy_advaxes[i].intval-1].value;
1512
1513         if (Config_control_mouse.intval) {
1514                 //---------  Read Mouse -----------
1515                 mouse_get_delta( &dx, &dy, &dz );
1516
1517                 analog_control[mouse_axes[0].intval] += dx * FrameTime / 35 * (mouse_invert[0].intval ? -1 : 1) * Config_mouse_sensitivity[mouse_axes[0].intval-1].value;
1518                 analog_control[mouse_axes[1].intval] += dy * FrameTime / 25 * (mouse_invert[1].intval ? -1 : 1) * Config_mouse_sensitivity[mouse_axes[1].intval-1].value;
1519                 analog_control[mouse_axes[2].intval] += dz * FrameTime      * (mouse_invert[2].intval ? -1 : 1) * Config_mouse_sensitivity[mouse_axes[2].intval-1].value;
1520         }
1521
1522 //------------- Read slide_on -------------
1523         
1524         slide_on |= console_control_state(CONCNTL_STRAFE);
1525
1526 //------------- Read bank_on ---------------
1527
1528         bank_on |= console_control_state(CONCNTL_BANK);
1529
1530 //------------ Read pitch_time -----------
1531         if ( !slide_on )        {
1532                 // mprintf((0, "pitch: %7.3f %7.3f: %7.3f\n", f2fl(k4), f2fl(k6), f2fl(Controls.heading_time)));
1533                 kp = 0;
1534
1535                 kp += console_control_down_time(CONCNTL_LOOKDOWN) / (PH_SCALE * 2);
1536                 kp -= console_control_down_time(CONCNTL_LOOKUP) / (PH_SCALE * 2);
1537
1538                 if (kp == 0)
1539                         Controls.pitch_time = 0;
1540                 else if (kp > 0) {
1541                         if (Controls.pitch_time < 0)
1542                                 Controls.pitch_time = 0;
1543                 } else // kp < 0
1544                         if (Controls.pitch_time > 0)
1545                                 Controls.pitch_time = 0;
1546                 Controls.pitch_time += kp;
1547
1548                 Controls.pitch_time -= analog_control[AXIS_PITCH];
1549
1550         } else
1551                 Controls.pitch_time = 0;
1552
1553 // the following "if" added by WraithX, 4/14/00
1554 // done so that dead players can't move
1555 if (!Player_is_dead)
1556 {
1557 //----------- Read vertical_thrust_time -----------------
1558
1559         if ( slide_on ) {
1560                 Controls.vertical_thrust_time += console_control_down_time(CONCNTL_LOOKDOWN);
1561                 Controls.vertical_thrust_time -= console_control_down_time(CONCNTL_LOOKUP);
1562                 Controls.vertical_thrust_time += analog_control[AXIS_PITCH];
1563         }
1564
1565         Controls.vertical_thrust_time += console_control_down_time(CONCNTL_MOVEUP);
1566         Controls.vertical_thrust_time -= console_control_down_time(CONCNTL_MOVEDOWN);
1567         Controls.vertical_thrust_time += analog_control[AXIS_UPDOWN];
1568
1569 }// end "if" added by WraithX
1570
1571 //---------- Read heading_time -----------
1572
1573         if (!slide_on && !bank_on)      {
1574                 //mprintf((0, "heading: %7.3f %7.3f: %7.3f\n", f2fl(k4), f2fl(k6), f2fl(Controls.heading_time)));
1575                 kh = 0;
1576
1577                 kh -= console_control_down_time(CONCNTL_LEFT) / PH_SCALE;
1578                 kh += console_control_down_time(CONCNTL_RIGHT) / PH_SCALE;
1579
1580                 if (kh == 0)
1581                         Controls.heading_time = 0;
1582                 else if (kh > 0) {
1583                         if (Controls.heading_time < 0)
1584                                 Controls.heading_time = 0;
1585                 } else // kh < 0
1586                         if (Controls.heading_time > 0)
1587                                 Controls.heading_time = 0;
1588                 Controls.heading_time += kh;
1589
1590                 Controls.heading_time += analog_control[AXIS_TURN];
1591
1592         } else
1593                 Controls.heading_time = 0;
1594
1595 // the following "if" added by WraithX, 4/14/00
1596 // done so that dead players can't move
1597 if (!Player_is_dead)
1598 {
1599 //----------- Read sideways_thrust_time -----------------
1600
1601         if ( slide_on ) {
1602                 Controls.sideways_thrust_time -= console_control_down_time(CONCNTL_LEFT);
1603                 Controls.sideways_thrust_time += console_control_down_time(CONCNTL_RIGHT);
1604                 Controls.sideways_thrust_time += analog_control[AXIS_TURN];
1605         }
1606
1607         Controls.sideways_thrust_time -= console_control_down_time(CONCNTL_MOVELEFT);
1608         Controls.sideways_thrust_time += console_control_down_time(CONCNTL_MOVERIGHT);
1609         Controls.sideways_thrust_time += analog_control[AXIS_LEFTRIGHT];
1610
1611 }// end "if" added by WraithX
1612
1613 //----------- Read bank_time -----------------
1614
1615         if ( bank_on )  {
1616                 Controls.bank_time += console_control_down_time(CONCNTL_LEFT);
1617                 Controls.bank_time -= console_control_down_time(CONCNTL_RIGHT);
1618                 Controls.bank_time -= analog_control[AXIS_TURN];
1619         }
1620
1621         Controls.bank_time += console_control_down_time(CONCNTL_BANKLEFT);
1622         Controls.bank_time -= console_control_down_time(CONCNTL_BANKRIGHT);
1623         Controls.bank_time -= analog_control[AXIS_BANK];
1624
1625 // the following "if" added by WraithX, 4/14/00
1626 // done so that dead players can't move
1627 if (!Player_is_dead)
1628 {
1629 //----------- Read forward_thrust_time -------------
1630
1631         Controls.forward_thrust_time += console_control_down_time(CONCNTL_FORWARD);
1632         Controls.forward_thrust_time -= console_control_down_time(CONCNTL_BACK);
1633         Controls.forward_thrust_time -= analog_control[AXIS_THROTTLE];
1634
1635 //---------Read Energy->Shield key----------
1636
1637         if ((Players[Player_num].flags & PLAYER_FLAGS_CONVERTER) && console_control_state(CONCNTL_NRGSHIELD))
1638                 transfer_energy_to_shield(console_control_down_time(CONCNTL_NRGSHIELD));
1639
1640 }//end "if" added by WraithX
1641 //----------- Read stupid-cruise-control-type of throttle.
1642
1643         Cruise_speed += console_control_down_time(CONCNTL_CRUISEUP);
1644         Cruise_speed -= console_control_down_time(CONCNTL_CRUISEDOWN);
1645
1646         if (console_control_down_count(CONCNTL_CRUISEOFF))
1647                 Cruise_speed = 0;
1648
1649         if (Cruise_speed > i2f(100))
1650                 Cruise_speed = i2f(100);
1651         if (Cruise_speed < 0 )
1652                 Cruise_speed = 0;
1653
1654         if (Controls.forward_thrust_time==0)
1655                 Controls.forward_thrust_time = fixmul(Cruise_speed,FrameTime)/100;
1656
1657 #if 0
1658         read_head_tracker();
1659 #endif
1660
1661 //----------- Clamp values between -FrameTime and FrameTime
1662         if (FrameTime > F1_0 )
1663                 mprintf( (1, "Bogus frame time of %.2f seconds\n", f2fl(FrameTime) ));
1664
1665         if (Controls.pitch_time         > FrameTime/2 ) Controls.pitch_time         = FrameTime/2;
1666         if (Controls.vertical_thrust_time > FrameTime ) Controls.vertical_thrust_time = FrameTime;
1667         if (Controls.heading_time         > FrameTime ) Controls.heading_time         = FrameTime;
1668         if (Controls.sideways_thrust_time > FrameTime ) Controls.sideways_thrust_time = FrameTime;
1669         if (Controls.bank_time            > FrameTime ) Controls.bank_time            = FrameTime;
1670         if (Controls.forward_thrust_time  > FrameTime ) Controls.forward_thrust_time  = FrameTime;
1671 //      if (Controls.afterburner_time     > FrameTime ) Controls.afterburner_time     = FrameTime;
1672
1673         if (Controls.pitch_time         < -FrameTime/2 ) Controls.pitch_time         = -FrameTime/2;
1674         if (Controls.vertical_thrust_time < -FrameTime ) Controls.vertical_thrust_time = -FrameTime;
1675         if (Controls.heading_time         < -FrameTime ) Controls.heading_time         = -FrameTime;
1676         if (Controls.sideways_thrust_time < -FrameTime ) Controls.sideways_thrust_time = -FrameTime;
1677         if (Controls.bank_time            < -FrameTime ) Controls.bank_time            = -FrameTime;
1678         if (Controls.forward_thrust_time  < -FrameTime ) Controls.forward_thrust_time  = -FrameTime;
1679 //      if (Controls.afterburner_time     < -FrameTime ) Controls.afterburner_time     = -FrameTime;
1680
1681
1682 //--------- Don't do anything if in debug mode
1683 #ifndef RELEASE
1684         if ( keyd_pressed[KEY_DELETE] ) {
1685                 memset( &Controls, 0, sizeof(control_info) );
1686         }
1687 #endif
1688 }
1689
1690
1691 void reset_cruise(void)
1692 {
1693         Cruise_speed=0;
1694 }
1695
1696
1697 void kc_set_controls()
1698 {
1699         int i, j;
1700
1701         for (i=0; i<NUM_KEY_CONTROLS; i++ )
1702                 kc_keyboard[i].value = 255;
1703
1704         for (i=0; i<NUM_OTHER_CONTROLS; i++ ) {
1705                 if (kc_other[i].type == BT_INVERT)
1706                         kc_other[i].value = 0;
1707                 else
1708                         kc_other[i].value = 255;
1709         }
1710
1711         for (i=0; i<NUM_D2X_CONTROLS; i++ )
1712                 kc_d2x[i].value = 255;
1713
1714         for (j = 0; j < 256; j++)
1715                 if (key_binding(j)) {
1716                         for (i = 0; i < NUM_KEY_CONTROLS; i++)
1717                                 if (kc_keyboard[i].value == 255
1718                                         && !stricmp(key_binding(j), kc_key_bind_text[i])) {
1719                                         kc_keyboard[i].value = j;
1720                                         break;
1721                                 }
1722                 }
1723
1724         for(j = 0; j < 256; j++)
1725                 if (key_binding(j)) {
1726                         for (i = 0; i < NUM_D2X_CONTROLS; i++)
1727                                 if (kc_d2x[i].value == 255
1728                                         && !stricmp(key_binding(j), kc_d2x[i].text)) {
1729                                         kc_d2x[i].value = j;
1730                                         break;
1731                                 }
1732                 }
1733
1734         for (i = 0; i < 6; i++) {
1735                 int inv = joy_invert[i].intval;
1736                 switch (joy_advaxes[i].intval) {
1737                         case AXIS_PITCH:     kc_other[ 0].value = i; kc_other[ 1].value = inv; break;
1738                         case AXIS_TURN:      kc_other[ 2].value = i; kc_other[ 3].value = inv; break;
1739                         case AXIS_LEFTRIGHT: kc_other[ 4].value = i; kc_other[ 5].value = inv; break;
1740                         case AXIS_UPDOWN:    kc_other[ 6].value = i; kc_other[ 7].value = inv; break;
1741                         case AXIS_BANK:      kc_other[ 8].value = i; kc_other[ 9].value = inv; break;
1742                         case AXIS_THROTTLE:  kc_other[10].value = i; kc_other[11].value = inv; break;
1743                         case AXIS_NONE:      break;
1744                         default:
1745                                 Int3();
1746                                 break;
1747                 }
1748         }
1749
1750         for (i = 0; i < 3; i++) {
1751                 int inv = mouse_invert[i].intval;
1752                 switch (mouse_axes[i].intval) {
1753                         case AXIS_PITCH:     kc_other[12].value = i; kc_other[13].value = inv; break;
1754                         case AXIS_TURN:      kc_other[14].value = i; kc_other[15].value = inv; break;
1755                         case AXIS_LEFTRIGHT: kc_other[16].value = i; kc_other[17].value = inv; break;
1756                         case AXIS_UPDOWN:    kc_other[18].value = i; kc_other[19].value = inv; break;
1757                         case AXIS_BANK:      kc_other[20].value = i; kc_other[21].value = inv; break;
1758                         case AXIS_THROTTLE:  kc_other[22].value = i; kc_other[23].value = inv; break;
1759                         case AXIS_NONE:      break;
1760                         default:
1761                                 Int3();
1762                                 break;
1763                 }
1764         }
1765 }
1766
1767 #if 0 // no mac support for vr headset
1768
1769 void kconfig_center_headset()
1770 {
1771         if (vfx1_installed)
1772                 vfx_center_headset();
1773 //      } else if (iglasses_headset_installed)  {
1774 //      } else if (Victor_headset_installed)   {
1775 //      } else {
1776 //      }
1777
1778 }
1779
1780 #endif // end of #if for kconfig_center_headset