]> icculus.org git repositories - btb/d2x.git/blob - main/kconfig.c
explicit casts
[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 // macros for drawing lo/hi res kconfig screens (see scores.c as well)
137
138 #define LHX(x)          ((x)*(MenuHires?2:1))
139 #define LHY(y)          ((y)*(MenuHires?2.4:1))
140
141
142 #define BT_KEY                          0
143 //#define BT_MOUSE_BUTTON       1
144 #define BT_MOUSE_AXIS           2
145 //#define BT_JOY_BUTTON                 3
146 #define BT_JOY_AXIS                     4
147 #define BT_INVERT                               5
148
149 char *btype_text[] = { "BT_KEY", "BT_MOUSE_BUTTON", "BT_MOUSE_AXIS", "BT_JOY_BUTTON", "BT_JOY_AXIS", "BT_INVERT" };
150
151 #define INFO_Y 28
152
153 typedef struct kc_item {
154         short id;                               // The id of this item
155         short x, y;                             
156         short w1;
157         short w2;
158         short u,d,l,r;
159         //short text_num1;
160         char *text;
161         ubyte type;
162         ubyte value;            // what key,button,etc
163 } kc_item;
164
165 int Num_items=28;
166 kc_item *All_items;
167
168
169 //----------- WARNING!!!!!!! -------------------------------------------
170 // THESE NEXT FOUR BLOCKS OF DATA ARE GENERATED BY PRESSING DEL+F12 WHEN
171 // IN THE KEYBOARD CONFIG SCREEN.  BASICALLY, THAT PROCEDURE MODIFIES THE
172 // U,D,L,R FIELDS OF THE ARRAYS AND DUMPS THE NEW ARRAYS INTO KCONFIG.COD
173 //-------------------------------------------------------------------------
174
175 kc_item kc_keyboard[NUM_KEY_CONTROLS] = {
176         {  0, 15, 49, 71, 26, 55,  2, 55,  1,"Pitch forward", BT_KEY, 255 },
177         {  1, 15, 49,100, 26, 50,  3,  0, 24,"Pitch forward", BT_KEY, 255 },
178         {  2, 15, 57, 71, 26,  0,  4, 25,  3,"Pitch backward", BT_KEY, 255 },
179         {  3, 15, 57,100, 26,  1,  5,  2, 26,"Pitch backward", BT_KEY, 255 },
180         {  4, 15, 65, 71, 26,  2,  6, 27,  5,"Turn left", BT_KEY, 255 },
181         {  5, 15, 65,100, 26,  3,  7,  4, 28,"Turn left", BT_KEY, 255 },
182         {  6, 15, 73, 71, 26,  4,  8, 29,  7,"Turn right", BT_KEY, 255 },
183         {  7, 15, 73,100, 26,  5,  9,  6, 34,"Turn right", BT_KEY, 255 },
184         {  8, 15, 85, 71, 26,  6, 10, 35,  9,"Slide on", BT_KEY, 255 },
185         {  9, 15, 85,100, 26,  7, 11,  8, 36,"Slide on", BT_KEY, 255 },
186         { 10, 15, 93, 71, 26,  8, 12, 37, 11,"Slide left", BT_KEY, 255 },
187         { 11, 15, 93,100, 26,  9, 13, 10, 44,"Slide left", BT_KEY, 255 },
188         { 12, 15,101, 71, 26, 10, 14, 45, 13,"Slide right", BT_KEY, 255 },
189         { 13, 15,101,100, 26, 11, 15, 12, 30,"Slide right", BT_KEY, 255 },
190         { 14, 15,109, 71, 26, 12, 16, 31, 15,"Slide up", BT_KEY, 255 },
191         { 15, 15,109,100, 26, 13, 17, 14, 32,"Slide up", BT_KEY, 255 },
192         { 16, 15,117, 71, 26, 14, 18, 33, 17,"Slide down", BT_KEY, 255 },
193         { 17, 15,117,100, 26, 15, 19, 16, 46,"Slide down", BT_KEY, 255 },
194         { 18, 15,129, 71, 26, 16, 20, 47, 19,"Bank on", BT_KEY, 255 },
195         { 19, 15,129,100, 26, 17, 21, 18, 38,"Bank on", BT_KEY, 255 },
196         { 20, 15,137, 71, 26, 18, 22, 39, 21,"Bank left", BT_KEY, 255 },
197         { 21, 15,137,100, 26, 19, 23, 20, 40,"Bank left", BT_KEY, 255 },
198         { 22, 15,145, 71, 26, 20, 48, 41, 23,"Bank right", BT_KEY, 255 },
199         { 23, 15,145,100, 26, 21, 49, 22, 42,"Bank right", BT_KEY, 255 },
200         { 24,158, 49, 83, 26, 51, 26,  1, 25,"Fire primary", BT_KEY, 255 },
201         { 25,158, 49,112, 26, 54, 27, 24,  2,"Fire primary", BT_KEY, 255 },
202         { 26,158, 57, 83, 26, 24, 28,  3, 27,"Fire secondary", BT_KEY, 255 },
203         { 27,158, 57,112, 26, 25, 29, 26,  4,"Fire secondary", BT_KEY, 255 },
204         { 28,158, 65, 83, 26, 26, 34,  5, 29,"Fire flare", BT_KEY, 255 },
205         { 29,158, 65,112, 26, 27, 35, 28,  6,"Fire flare", BT_KEY, 255 },
206         { 30,158,105, 83, 26, 44, 32, 13, 31,"Accelerate", BT_KEY, 255 },
207         { 31,158,105,112, 26, 45, 33, 30, 14,"Accelerate", BT_KEY, 255 },
208         { 32,158,113, 83, 26, 30, 46, 15, 33,"reverse", BT_KEY, 255 },
209         { 33,158,113,112, 26, 31, 47, 32, 16,"reverse", BT_KEY, 255 },
210         { 34,158, 73, 83, 26, 28, 36,  7, 35,"Drop Bomb", BT_KEY, 255 },
211         { 35,158, 73,112, 26, 29, 37, 34,  8,"Drop Bomb", BT_KEY, 255 },
212         { 36,158, 85, 83, 26, 34, 44,  9, 37,"REAR VIEW", BT_KEY, 255 },
213         { 37,158, 85,112, 26, 35, 45, 36, 10,"REAR VIEW", BT_KEY, 255 },
214         { 38,158,133, 83, 26, 46, 40, 19, 39,"Cruise Faster", BT_KEY, 255 },
215         { 39,158,133,112, 26, 47, 41, 38, 20,"Cruise Faster", BT_KEY, 255 },
216         { 40,158,141, 83, 26, 38, 42, 21, 41,"Cruise Slower", BT_KEY, 255 },
217         { 41,158,141,112, 26, 39, 43, 40, 22,"Cruise Slower", BT_KEY, 255 },
218         { 42,158,149, 83, 26, 40, 52, 23, 43,"Cruise Off", BT_KEY, 255 },
219         { 43,158,149,112, 26, 41, 53, 42, 48,"Cruise Off", BT_KEY, 255 },
220         { 44,158, 93, 83, 26, 36, 30, 11, 45,"Automap", BT_KEY, 255 },
221         { 45,158, 93,112, 26, 37, 31, 44, 12,"Automap", BT_KEY, 255 },
222         { 46,158,121, 83, 26, 32, 38, 17, 47,"Afterburner", BT_KEY, 255 },
223         { 47,158,121,112, 26, 33, 39, 46, 18,"Afterburner", BT_KEY, 255 },
224         { 48, 15,161, 71, 26, 22, 50, 43, 49,"Cycle Primary", BT_KEY, 255 },
225         { 49, 15,161,100, 26, 23, 51, 48, 52,"Cycle Primary", BT_KEY, 255 },
226         { 50, 15,169, 71, 26, 48,  1, 53, 51,"Cycle Second", BT_KEY, 255 },
227         { 51, 15,169,100, 26, 49, 24, 50, 54,"Cycle Second", BT_KEY, 255 },
228         { 52,158,163, 83, 26, 42, 54, 49, 53,"Headlight", BT_KEY, 255 },
229         { 53,158,163,112, 26, 43, 55, 52, 50,"Headlight", BT_KEY, 255 },
230         { 54,158,171, 83, 26, 52, 56, 51, 55,"Energy->Shield", BT_KEY, 255 },
231         { 55,158,171,112, 26, 53,  0, 54,  0,"Energy->Shield", BT_KEY, 255 },
232         { 56,158,179, 83, 26, 54,  0,  0,  0,"Toggle Bomb", BT_KEY, 255 },
233 };
234
235 char *kc_key_bind_text[NUM_KEY_CONTROLS] = {
236         "+lookdown",    "+lookdown",
237         "+lookup",      "+lookup",
238         "+left",        "+left",
239         "+right",       "+right",
240         "+strafe",      "+strafe",
241         "+moveleft",    "+moveleft",
242         "+moveright",   "+moveright",
243         "+moveup",      "+moveup",
244         "+movedown",    "+movedown",
245         "+bank",        "+bank",
246         "+bankleft",    "+bankleft",
247         "+bankright",   "+bankright",
248         "+attack",      "+attack",
249         "+attack2",     "+attack2",
250         "flare",        "flare",
251         "+forward",     "+forward",
252         "+back",        "+back",
253         "bomb",         "bomb",
254         "+rearview",    "+rearview",
255         "+cruiseup",    "+cruiseup",
256         "+cruisedown",  "+cruisedown",
257         "+cruiseoff",   "+cruiseoff",
258         "+automap",     "+automap",
259         "+afterburner", "+afterburner",
260         "cycle",        "cycle",
261         "cycle2",       "cycle2",
262         "headlight",    "headlight",
263         "+nrgshield",   "+nrgshield",
264         "togglebomb",
265 };
266
267 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};
268
269 kc_item kc_other[NUM_OTHER_CONTROLS] = {
270         {  0, 22,138, 51, 40, 23,  2, 23,  1,"Pitch U/D", BT_JOY_AXIS, 255 },
271         {  1, 22,138, 99,  8, 10,  3,  0, 12,"Pitch U/D", BT_INVERT, 255 },
272         {  2, 22,146, 51, 40,  0,  4, 13,  3,"Turn L/R", BT_JOY_AXIS, 255 },
273         {  3, 22,146, 99,  8,  1,  5,  2, 14,"Turn L/R", BT_INVERT, 255 },
274         {  4, 22,154, 51, 40,  2,  6, 15,  5,"Slide L/R", BT_JOY_AXIS, 255 },
275         {  5, 22,154, 99,  8,  3,  7,  4, 16,"Slide L/R", BT_INVERT, 255 },
276         {  6, 22,162, 51, 40,  4,  8, 17,  7,"Slide U/D", BT_JOY_AXIS, 255 },
277         {  7, 22,162, 99,  8,  5,  9,  6, 18,"Slide U/D", BT_INVERT, 255 },
278         {  8, 22,170, 51, 40,  6, 10, 19,  9,"Bank L/R", BT_JOY_AXIS, 255 },
279         {  9, 22,170, 99,  8,  7, 11,  8, 20,"Bank L/R", BT_INVERT, 255 },
280         { 10, 22,182, 51, 40,  8,  1, 21, 11,"throttle", BT_JOY_AXIS, 255 },
281         { 11, 22,182, 99,  8,  9, 12, 10, 22,"throttle", BT_INVERT, 255 },
282         { 12,182,138, 51, 40, 11, 14,  1, 13,"Pitch U/D", BT_MOUSE_AXIS, 255 },
283         { 13,182,138, 99,  8, 22, 15, 12,  2,"Pitch U/D", BT_INVERT, 255 },
284         { 14,182,146, 51, 40, 12, 16,  3, 15,"Turn L/R", BT_MOUSE_AXIS, 255 },
285         { 15,182,146, 99,  8, 13, 17, 14,  4,"Turn L/R", BT_INVERT, 255 },
286         { 16,182,154, 51, 40, 14, 18,  5, 17,"Slide L/R", BT_MOUSE_AXIS, 255 },
287         { 17,182,154, 99,  8, 15, 19, 16,  6,"Slide L/R", BT_INVERT, 255 },
288         { 18,182,162, 51, 40, 16, 20,  7, 19,"Slide U/D", BT_MOUSE_AXIS, 255 },
289         { 19,182,162, 99,  8, 17, 21, 18,  8,"Slide U/D", BT_INVERT, 255 },
290         { 20,182,170, 51, 40, 18, 22,  9, 21,"Bank L/R", BT_MOUSE_AXIS, 255 },
291         { 21,182,170, 99,  8, 19, 23, 20, 10,"Bank L/R", BT_INVERT, 255 },
292         { 22,182,182, 51, 40, 20, 13, 11, 23,"throttle", BT_MOUSE_AXIS, 255 },
293         { 23,182,182, 99,  8, 21,  0, 22,  0,"throttle", BT_INVERT, 255 },
294 };
295
296 kc_axis_map kc_other_axismap[NUM_OTHER_CONTROLS] = {
297         AXIS_PITCH,     AXIS_NONE,
298         AXIS_TURN,      AXIS_NONE,
299         AXIS_LEFTRIGHT, AXIS_NONE,
300         AXIS_UPDOWN,    AXIS_NONE,
301         AXIS_BANK,      AXIS_NONE,
302         AXIS_THROTTLE,  AXIS_NONE,
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 };
310
311 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};
312
313 kc_item kc_d2x[NUM_D2X_CONTROLS] = {
314 //        id,x,y,w1,w2,u,d,l,r,text_num1,type,value
315         {  0, 15, 49, 71, 26, 19,  2, 27,  1,"WEAPON 1", BT_KEY, 255 },
316         {  1, 15, 49,100, 26, 18,  3,  0,  2,"WEAPON 1", BT_KEY, 255 },
317         {  2, 15, 57, 71, 26,  0,  4,  1,  3,"WEAPON 2", BT_KEY, 255 },
318         {  3, 15, 57,100, 26,  1,  5,  2,  4,"WEAPON 2", BT_KEY, 255 },
319         {  4, 15, 65, 71, 26,  2,  6,  3,  5,"WEAPON 3", BT_KEY, 255 },
320         {  5, 15, 65,100, 26,  3,  7,  4,  6,"WEAPON 3", BT_KEY, 255 },
321         {  6, 15, 73, 71, 26,  4,  8,  5,  7,"WEAPON 4", BT_KEY, 255 },
322         {  7, 15, 73,100, 26,  5,  9,  6,  8,"WEAPON 4", BT_KEY, 255 },
323         {  8, 15, 81, 71, 26,  6, 10,  7,  9,"WEAPON 5", BT_KEY, 255 },
324         {  9, 15, 81,100, 26,  7, 11,  8, 10,"WEAPON 5", BT_KEY, 255 },
325         { 10, 15, 89, 71, 26,  8, 12,  9, 11,"WEAPON 6", BT_KEY, 255 },
326         { 11, 15, 89,100, 26,  9, 13, 10, 12,"WEAPON 6", BT_KEY, 255 },
327         { 12, 15, 97, 71, 26, 10, 14, 11, 13,"WEAPON 7", BT_KEY, 255 },
328         { 13, 15, 97,100, 26, 11, 15, 12, 14,"WEAPON 7", BT_KEY, 255 },
329         { 14, 15,105, 71, 26, 12, 16, 13, 15,"WEAPON 8", BT_KEY, 255 },
330         { 15, 15,105,100, 26, 13, 17, 14, 16,"WEAPON 8", BT_KEY, 255 },
331         { 16, 15,113, 71, 26, 14, 18, 15, 17,"WEAPON 9", BT_KEY, 255 },
332         { 17, 15,113,100, 26, 15, 19, 16, 18,"WEAPON 9", BT_KEY, 255 },
333         { 18, 15,121, 71, 26, 16,  1, 17, 19,"WEAPON 0", BT_KEY, 255 },
334         { 19, 15,121,100, 26, 17,  0, 18,  0,"WEAPON 0", BT_KEY, 255 },
335         //{ 20, 15,131, 71, 26, 18, 22, 19, 21, "CYC PRIMARY", BT_KEY, 255},
336         //{ 21, 15,131,100, 26, 19, 23, 20, 22, "CYC PRIMARY", BT_KEY, 255},
337         //{ 22, 15,139, 71, 26, 20, 24, 21, 23, "CYC SECONDARY", BT_KEY, 255},
338         //{ 23, 15,139,100, 26, 21, 25, 22, 24, "CYC SECONDARY", BT_KEY, 255},
339         //{ 24,  8,147, 78, 26, 22, 26, 23, 25, "TOGGLE_PRIM AUTO", BT_KEY, 255},
340         //{ 25,  8,147,107, 26, 23, 27, 24, 26, "TOGGLE_PRIM_AUTO", BT_KEY, 255},
341         //{ 26,  8,155, 78, 26, 24,  1, 25, 27, "TOGGLE SEC AUTO", BT_KEY, 255},
342         //{ 27,  8,155,107, 26, 25,  0, 26,  0, "TOGGLE SEC AUTO", BT_KEY, 255},
343 };
344
345 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};
346
347
348 void kc_drawitem( kc_item *item, int is_current );
349 void kc_change_key( kc_item * item );
350 void kc_next_joyaxis(kc_item *item);  //added by WraithX on 11/22/00
351 void kc_change_joyaxis( kc_item * item );
352 void kc_change_mouseaxis( kc_item * item );
353 void kc_change_invert( kc_item * item );
354
355 int kconfig_is_axes_used(int axis)
356 {
357         int i;
358         for (i=0; i<NUM_OTHER_CONTROLS; i++ )   {
359                 if (( kc_other[i].type == BT_JOY_AXIS ) && (kc_other[i].value == axis ))
360                         return 1;
361         }
362         return 0;
363 }
364
365 #ifdef TABLE_CREATION
366 int find_item_at( kc_item * items, int nitems, int x, int y )
367 {
368         int i;
369         
370         for (i=0; i<nitems; i++ )       {
371                 if ( ((items[i].x+items[i].w1)==x) && (items[i].y==y))
372                         return i;
373         }
374         return -1;
375 }
376
377 int find_next_item_up( kc_item * items, int nitems, int citem )
378 {
379         int x, y, i;
380
381         y = items[citem].y;
382         x = items[citem].x+items[citem].w1;
383         
384         do {    
385                 y--;
386                 if ( y < 0 ) {
387                         y = grd_curcanv->cv_bitmap.bm_h-1;
388                         x--;
389                         if ( x < 0 ) {
390                                 x = grd_curcanv->cv_bitmap.bm_w-1;
391                         }
392                 }
393                 i = find_item_at( items, nitems, x, y );
394         } while ( i < 0 );
395         
396         return i;
397 }
398
399 int find_next_item_down( kc_item * items, int nitems, int citem )
400 {
401         int x, y, i;
402
403         y = items[citem].y;
404         x = items[citem].x+items[citem].w1;
405         
406         do {    
407                 y++;
408                 if ( y > grd_curcanv->cv_bitmap.bm_h-1 ) {
409                         y = 0;
410                         x++;
411                         if ( x > grd_curcanv->cv_bitmap.bm_w-1 ) {
412                                 x = 0;
413                         }
414                 }
415                 i = find_item_at( items, nitems, x, y );
416         } while ( i < 0 );
417         
418         return i;
419 }
420
421 int find_next_item_right( kc_item * items, int nitems, int citem )
422 {
423         int x, y, i;
424
425         y = items[citem].y;
426         x = items[citem].x+items[citem].w1;
427         
428         do {    
429                 x++;
430                 if ( x > grd_curcanv->cv_bitmap.bm_w-1 ) {
431                         x = 0;
432                         y++;
433                         if ( y > grd_curcanv->cv_bitmap.bm_h-1 ) {
434                                 y = 0;
435                         }
436                 }
437                 i = find_item_at( items, nitems, x, y );
438         } while ( i < 0 );
439         
440         return i;
441 }
442
443 int find_next_item_left( kc_item * items, int nitems, int citem )
444 {
445         int x, y, i;
446
447         y = items[citem].y;
448         x = items[citem].x+items[citem].w1;
449         
450         do {    
451                 x--;
452                 if ( x < 0 ) {
453                         x = grd_curcanv->cv_bitmap.bm_w-1;
454                         y--;
455                         if ( y < 0 ) {
456                                 y = grd_curcanv->cv_bitmap.bm_h-1;
457                         }
458                 }
459                 i = find_item_at( items, nitems, x, y );
460         } while ( i < 0 );
461         
462         return i;
463 }
464 #endif
465
466 #ifdef NEWMENU_MOUSE
467 int get_item_height(kc_item *item)
468 {
469         int w, h, aw;
470         char btext[10];
471
472         if (item->value==255) {
473                 strcpy(btext, "");
474         } else {
475                 switch( item->type )    {
476                         case BT_KEY:
477                                 strncpy( btext, key_text[item->value], 10 ); break;
478                         case BT_MOUSE_AXIS:
479                                 strncpy( btext, Text_string[mouseaxis_text[item->value]], 10 ); break;
480                         case BT_JOY_AXIS:
481 #ifdef USE_LINUX_JOY
482                                 sprintf( btext, "J%d A%d", j_axis[item->value].joydev, j_Get_joydev_axis_number (item->value) );
483 #elif defined(SDL_INPUT)
484                                 if (joyaxis_text[item->value])
485                                         strncpy(btext, joyaxis_text[item->value], 10);
486                                 else
487                                         sprintf(btext, "AXIS%2d", item->value + 1);
488 #else
489                                 strncpy(btext, Text_string[joyaxis_text[item->value]], 10);
490 #endif
491                                 break;
492                         case BT_INVERT:
493                                 strncpy( btext, Text_string[invert_text[item->value]], 10 ); break;
494                 }
495         }
496         gr_get_string_size(btext, &w, &h, &aw  );
497
498         return h;
499 }
500 #endif
501
502 void kconfig_sub(kc_item * items,int nitems, char * title)
503 {
504         grs_canvas * save_canvas;
505         grs_font * save_font;
506         int old_keyd_repeat;
507 #ifdef NEWMENU_MOUSE
508         int mouse_state, omouse_state, mx, my, x1, x2, y1, y2;
509         int close_x, close_y, close_size;
510 #endif
511
512         int i,k,ocitem,citem;
513         int time_stopped = 0;
514
515         All_items = items;
516         Num_items = nitems;
517
518         if (!((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME) && (!Endlevel_sequence)) )
519         {
520                 time_stopped = 1;
521                 stop_time();
522         }
523
524         save_canvas = grd_curcanv;
525
526
527         gr_set_current_canvas(NULL);
528         save_font = grd_curcanv->cv_font;
529
530         game_flush_inputs();
531         old_keyd_repeat = keyd_repeat;
532         keyd_repeat = 1;
533
534         //gr_clear_canvas( BM_XRGB(0,0,0) );
535
536         nm_draw_background(0, 0, grd_curcanv->cv_bitmap.bm_w - 1, grd_curcanv->cv_bitmap.bm_h - 1);
537    gr_palette_load (gr_palette);
538
539         grd_curcanv->cv_font = MEDIUM3_FONT;
540
541         {
542                 char * p;
543                 p = strchr( title, '\n' );
544                 if ( p ) *p = 32;
545                 gr_string( 0x8000, LHY(8), title );
546                 if ( p ) *p = '\n';
547         }
548
549
550 //      if ( items == kc_keyboard )     {
551 //              gr_string( 0x8000, 8, "Keyboard" );
552 //      } else if ( items == kc_other ) {
553 //              gr_string( 0x8000, 8, "Others" );
554 //      }
555
556 #ifdef NEWMENU_MOUSE
557         close_x = close_y = MenuHires?15:7;
558         close_size = MenuHires?10:5;
559         /*
560         gr_setcolor( BM_XRGB(0, 0, 0) );
561         gr_rect(close_x, close_y, close_x + close_size, close_y + close_size);
562         gr_setcolor( BM_XRGB(21, 21, 21) );
563         gr_rect(close_x + LHX(1), close_y + LHX(1), close_x + close_size - LHX(1), close_y + close_size - LHX(1));
564         */
565 #endif
566
567         grd_curcanv->cv_font = GAME_FONT;
568         gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
569
570         gr_string( 0x8000, LHY(20), TXT_KCONFIG_STRING_1 );
571         gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
572         if ( items == kc_keyboard )     {
573                 gr_set_fontcolor( BM_XRGB(31,27,6), -1 );
574                 gr_setcolor( BM_XRGB(31,27,6) );
575                 
576                 gr_scanline( LHX(98), LHX(106), LHY(42) );
577                 gr_scanline( LHX(120), LHX(128), LHY(42) );
578                 gr_pixel( LHX(98), LHY(43) );                                           
579                 gr_pixel( LHX(98), LHY(44) );                                           
580                 gr_pixel( LHX(128), LHY(43) );                                          
581                 gr_pixel( LHX(128), LHY(44) );                                          
582                 
583                 gr_string( LHX(109), LHY(40), "OR" );
584
585                 gr_scanline( LHX(253), LHX(261), LHY(42) );
586                 gr_scanline( LHX(274), LHX(283), LHY(42) );
587                 gr_pixel( LHX(253), LHY(43) );                                          
588                 gr_pixel( LHX(253), LHY(44) );                                          
589                 gr_pixel( LHX(283), LHY(43) );                                          
590                 gr_pixel( LHX(283), LHY(44) );                                          
591
592                 gr_string( LHX(264), LHY(40), "OR" );
593
594         } if ( items == kc_other )      {
595                 gr_set_fontcolor( BM_XRGB(31,27,6), -1 );
596                 gr_setcolor( BM_XRGB(31,27,6) );
597                 gr_scanline( LHX(18), LHX(60), LHY(119+5) );
598                 gr_scanline( LHX(102), LHX(144), LHY(119+5) );
599                 gr_string( LHX(63), LHY(117+5), TXT_CONTROL_JOYSTICK );
600                 gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
601                 gr_string( LHX(84), LHY(129), TXT_AXIS );
602                 gr_string( LHX(110), LHY(129), TXT_INVERT );
603
604                 gr_set_fontcolor( BM_XRGB(31,27,6), -1 );
605                 gr_setcolor( BM_XRGB(31,27,6) );
606                 gr_scanline( LHX(178), LHX(226), LHY(119+5) );
607                 gr_scanline( LHX(256), LHX(304), LHY(119+5) );
608                 gr_string( LHX(229), LHY(117+5), TXT_CONTROL_MOUSE );
609                 gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
610                 gr_string( LHX(244), LHY(129), TXT_AXIS );
611                 gr_string( LHX(270), LHY(129), TXT_INVERT );
612         }
613         else if ( items == kc_d2x )
614         {
615                 gr_set_fontcolor( BM_XRGB(31,27,6), -1 );
616                 gr_setcolor( BM_XRGB(31,27,6) );
617
618                 gr_scanline( LHX(98), LHX(106), LHY(42) );
619                 gr_scanline( LHX(120), LHX(128), LHY(42) );
620                 gr_pixel( LHX(98), LHY(43) );
621                 gr_pixel( LHX(98), LHY(44) );
622                 gr_pixel( LHX(128), LHY(43) );
623                 gr_pixel( LHX(128), LHY(44) );
624
625                 gr_string(LHX(109), LHY(40), "OR");
626         }
627
628         for (i=0; i<nitems; i++ )       {
629                 kc_drawitem( &items[i], 0 );
630         }
631
632         citem = 0;
633         while(items[citem].id == -1)
634                 citem++;
635         kc_drawitem( &items[citem], 1 );
636
637         newmenu_show_cursor();
638
639 #ifdef NEWMENU_MOUSE
640         mouse_state = omouse_state = 0;
641 #endif
642
643         while(1)                {
644         //      Windows addendum to allow for kconfig input.
645                 gr_update();
646
647                 //see if redbook song needs to be restarted
648                 songs_check_redbook_repeat();
649
650                 k = key_inkey();
651
652 #ifdef NEWMENU_MOUSE
653                 omouse_state = mouse_state;
654                 mouse_state = mouse_button_state(0);
655 #endif
656
657                 if ( !time_stopped ) {
658                         #ifdef NETWORK
659                         if (multi_menu_poll() == -1)
660                                 k = -2;
661                         #endif
662                 }
663                 ocitem = citem;
664                 switch( k )     {
665                 case KEY_BACKSP:
666                         Int3();
667                         break;
668                 case KEY_COMMAND+KEY_SHIFTED+KEY_3:
669                 case KEY_PRINT_SCREEN:
670                         save_screen_shot(0);
671                         break;                                                  
672                 case KEY_CTRLED+KEY_D:
673                         items[citem].value = 255;
674                         kc_drawitem( &items[citem], 1 );
675                         break;
676                 case KEY_CTRLED+KEY_R:  
677                         if ( items == kc_keyboard )
678                                 for (i = 0; i < NUM_KEY_CONTROLS; i++) {
679                                         items[i].value = default_kc_keyboard_settings[i];
680                                         kc_drawitem( &items[i], 0 );
681                                 }
682                         else if ( items == kc_other )
683                                 for (i = 0; i < NUM_OTHER_CONTROLS; i++) {
684                                         items[i].value = default_kc_other_settings[i];
685                                         kc_drawitem( &items[i], 0 );
686                                 }
687                         else if ( items == kc_d2x )
688                                 for (i = 0; i < NUM_D2X_CONTROLS; i++)
689                                 {
690                                         items[i].value = default_kc_d2x_settings[i];
691                                         kc_drawitem( &items[i], 0 );
692                                 }
693                         kc_drawitem( &items[citem], 1 );
694                         break;
695                 case KEY_DELETE:
696                         items[citem].value=255;
697                         kc_drawitem( &items[citem], 1 );
698                         break;
699                 case KEY_UP:            
700                 case KEY_PAD8:
701 #ifdef TABLE_CREATION
702                         if (items[citem].u==-1) items[citem].u=find_next_item_up( items,nitems, citem);
703 #endif
704                         citem = items[citem].u; 
705                         break;
706                 
707                 case KEY_DOWN:  
708                 case KEY_PAD2:
709 #ifdef TABLE_CREATION
710                         if (items[citem].d==-1) items[citem].d=find_next_item_down( items,nitems, citem);
711 #endif
712                         citem = items[citem].d; 
713                         break;
714                 case KEY_LEFT:  
715                 case KEY_PAD4:
716 #ifdef TABLE_CREATION
717                         if (items[citem].l==-1) items[citem].l=find_next_item_left( items,nitems, citem);
718 #endif
719                         citem = items[citem].l; 
720                         break;
721                 case KEY_RIGHT:         
722                 case KEY_PAD6:
723 #ifdef TABLE_CREATION
724                         if (items[citem].r==-1) items[citem].r=find_next_item_right( items,nitems, citem);
725 #endif
726                         citem = items[citem].r; 
727                         break;
728                 case KEY_ENTER: 
729                 case KEY_PADENTER:      
730                         switch( items[citem].type )     {
731                         case BT_KEY:            kc_change_key( &items[citem] ); break;
732                         case BT_MOUSE_AXIS:     kc_change_mouseaxis( &items[citem] ); break;
733                         case BT_JOY_AXIS:       kc_change_joyaxis( &items[citem] ); break;
734                         case BT_INVERT:         kc_change_invert( &items[citem] ); break;
735                         }
736                         break;
737                 //the following case added by WraithX on 11/22/00 to work around the weird joystick bug...
738                 case KEY_SPACEBAR:
739                         switch(items[citem].type)
740                         {
741                         case BT_JOY_AXIS:
742                                 kc_next_joyaxis(&items[citem]);
743                                 break;
744                         }
745                         break;
746                 //end addition by WraithX
747                 case -2:        
748                 case KEY_ESC:
749                         grd_curcanv->cv_font    = save_font;
750
751                         gr_set_current_canvas( save_canvas );
752                         keyd_repeat = old_keyd_repeat;
753                         game_flush_inputs();
754                         newmenu_hide_cursor();
755                         if (time_stopped)
756                                 start_time();
757                         return;
758 #ifdef TABLE_CREATION
759                 case KEY_DEBUGGED+KEY_SHIFTED+KEY_2:
760                 case KEY_DEBUGGED+KEY_F12:      {
761                         FILE * fp;
762                         int j;
763
764                         for (i=0; i<NUM_KEY_CONTROLS; i++ )     {
765                                 kc_keyboard[i].u = find_next_item_up( kc_keyboard,NUM_KEY_CONTROLS, i);
766                                 kc_keyboard[i].d = find_next_item_down( kc_keyboard,NUM_KEY_CONTROLS, i);
767                                 kc_keyboard[i].l = find_next_item_left( kc_keyboard,NUM_KEY_CONTROLS, i);
768                                 kc_keyboard[i].r = find_next_item_right( kc_keyboard,NUM_KEY_CONTROLS, i);
769                         }
770                         for (i=0; i<NUM_OTHER_CONTROLS; i++ )   {
771                                 kc_other[i].u = find_next_item_up( kc_other,NUM_OTHER_CONTROLS, i);
772                                 kc_other[i].d = find_next_item_down( kc_other,NUM_OTHER_CONTROLS, i);
773                                 kc_other[i].l = find_next_item_left( kc_other,NUM_OTHER_CONTROLS, i);
774                                 kc_other[i].r = find_next_item_right( kc_other,NUM_OTHER_CONTROLS, i);
775                         }
776                         fp = stderr; //fopen( "kconfig.cod", "wt" );
777
778                         fprintf( fp, "kc_item kc_keyboard[NUM_KEY_CONTROLS] = {\n" );
779                         for (i=0; i<NUM_KEY_CONTROLS; i++ )     {
780                                 fprintf( fp, "\t{ %2d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%c%s%c, %s, 255 },\n", 
781                                         kc_keyboard[i].id, kc_keyboard[i].x, kc_keyboard[i].y, kc_keyboard[i].w1, kc_keyboard[i].w2,
782                                         kc_keyboard[i].u, kc_keyboard[i].d, kc_keyboard[i].l, kc_keyboard[i].r,
783                                         34, kc_keyboard[i].text, 34, btype_text[kc_keyboard[i].type] );
784                         }
785                         fprintf( fp, "};\n\n" );
786                         fprintf( fp, "ubyte default_kc_keyboard_settings[MAX_CONTROLS] = " );
787                         fprintf( fp, "{0x%x", kc_keyboard[0].value );
788                         for (j = 1; j < MAX_CONTROLS; j++)
789                                 fprintf( fp, ",0x%x", kc_keyboard[j].value );
790                         fprintf( fp, "};\n\n" );
791
792                         fprintf( fp, "kc_item kc_other[NUM_OTHER_CONTROLS] = {\n" );
793                         for (i=0; i<NUM_OTHER_CONTROLS; i++ )   {
794                                 fprintf( fp, "\t{ %2d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%c%s%c, %s, 255 },\n",
795                                         kc_other[i].id, kc_other[i].x, kc_other[i].y, kc_other[i].w1, kc_other[i].w2,
796                                         kc_other[i].u, kc_other[i].d, kc_other[i].l, kc_other[i].r,
797                                         34, kc_other[i].text, 34, btype_text[kc_other[i].type] );
798                         }
799                         fprintf( fp, "};\n\n" );
800                         fprintf( fp, "ubyte default_kc_other_settings[MAX_CONTROLS] = " );
801                         fprintf( fp, "{0x%x", kc_other[0].value );
802                         for (j = 1; j < MAX_CONTROLS; j++)
803                                 fprintf( fp, ",0x%x", kc_other[j].value );
804                         fprintf( fp, "};\n" );
805
806                         fprintf( fp, "kc_item kc_d2x[NUM_D2X_CONTROLS] = {\n" );
807                         for (i=0; i<NUM_D2X_CONTROLS; i++ )     {
808                                 fprintf( fp, "\t{ %2d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%c%s%c, %s, 255 },\n",
809                                                 kc_d2x[i].id, kc_d2x[i].x, kc_d2x[i].y, kc_d2x[i].w1, kc_d2x[i].w2,
810                                                 kc_d2x[i].u, kc_d2x[i].d, kc_d2x[i].l, kc_d2x[i].r,
811                                                 34, kc_d2x[i].text, 34, btype_text[kc_d2x[i].type] );
812                         }
813                         fprintf( fp, "};\n\n" );
814                         fprintf( fp, "ubyte default_kc_d2x_settings[MAX_CONTROLS] = " );
815                         fprintf( fp, "{0x%x", kc_d2x[0].value );
816                         for (j = 1; j < MAX_CONTROLS; j++)
817                                 fprintf( fp, ",0x%x", kc_d2x[j].value );
818                         fprintf( fp, "};\n" );
819
820                         fclose(fp);
821
822                         }
823                         break;
824 #endif
825                 }
826
827 #ifdef NEWMENU_MOUSE
828                 if ( (mouse_state && !omouse_state) || (mouse_state && omouse_state) ) {
829                         int item_height;
830                         
831                         mouse_get_pos(&mx, &my);
832                         for (i=0; i<nitems; i++ )       {
833                                 item_height = get_item_height( &items[i] );
834                                 x1 = grd_curcanv->cv_bitmap.bm_x + LHX(items[i].x) + LHX(items[i].w1);
835                                 x2 = x1 + LHX(items[i].w2);
836                                 y1 = grd_curcanv->cv_bitmap.bm_y + LHY(items[i].y);
837                                 y2 = y1 + LHX(item_height);
838                                 if (((mx > x1) && (mx < x2)) && ((my > y1) && (my < y2))) {
839                                         citem = i;
840                                         break;
841                                 }
842                         }
843                 }
844                 else if ( !mouse_state && omouse_state ) {
845                         int item_height;
846                         
847                         mouse_get_pos(&mx, &my);
848                         item_height = get_item_height( &items[citem] );
849                         x1 = grd_curcanv->cv_bitmap.bm_x + LHX(items[citem].x) + LHX(items[citem].w1);
850                         x2 = x1 + LHX(items[citem].w2);
851                         y1 = grd_curcanv->cv_bitmap.bm_y + LHY(items[citem].y);
852                         y2 = y1 + LHY(item_height);
853                         if (((mx > x1) && (mx < x2)) && ((my > y1) && (my < y2))) {
854                                 newmenu_hide_cursor();
855                                 switch( items[citem].type )     {
856                                 case BT_KEY:                            kc_change_key( &items[citem] ); break;
857                                 case BT_MOUSE_AXIS:             kc_change_mouseaxis( &items[citem] ); break;
858                                 case BT_JOY_AXIS:               kc_change_joyaxis( &items[citem] ); break;
859                                 case BT_INVERT:                         kc_change_invert( &items[citem] ); break;
860                                 }
861                                 newmenu_show_cursor();
862                         } else {
863                                 x1 = grd_curcanv->cv_bitmap.bm_x + close_x + LHX(1);
864                                 x2 = x1 + close_size - LHX(1);
865                                 y1 = grd_curcanv->cv_bitmap.bm_y + close_y + LHX(1);
866                                 y2 = y1 + close_size - LHX(1);
867                                 if ( ((mx > x1) && (mx < x2)) && ((my > y1) && (my < y2)) ) {
868                                         grd_curcanv->cv_font    = save_font;
869                                         gr_set_current_canvas( save_canvas );
870                                         keyd_repeat = old_keyd_repeat;
871                                         game_flush_inputs();
872                                         newmenu_hide_cursor();
873                                         if (time_stopped)
874                                                 start_time();
875                                         return;
876                                 }
877                         }
878
879                 }
880 #endif // NEWMENU_MOUSE
881
882                 if (ocitem!=citem)      {
883                         newmenu_hide_cursor();
884                         kc_drawitem( &items[ocitem], 0 );
885                         kc_drawitem( &items[citem], 1 );
886                         newmenu_show_cursor();
887                 }
888         }
889 }
890
891
892 void kc_drawitem( kc_item *item, int is_current )
893 {
894         int x, w, h, aw;
895         char btext[16];
896
897         if (is_current)
898                 gr_set_fontcolor( BM_XRGB(20,20,29), -1 );
899         else
900                 gr_set_fontcolor( BM_XRGB(15,15,24), -1 );
901    gr_string( LHX(item->x), LHY(item->y), item->text );
902
903         if (item->value==255) {
904                 strcpy( btext, "" );
905         } else {
906                 switch( item->type )    {
907                         case BT_KEY:
908                                 strncpy( btext, key_text[item->value], 10 ); break;
909                         case BT_MOUSE_AXIS:
910                                 strncpy( btext, Text_string[mouseaxis_text[item->value]], 10 ); break;
911                         case BT_JOY_AXIS:
912 #ifdef USE_LINUX_JOY
913                                 sprintf(btext, "J%d A%d", j_axis[item->value].joydev, j_Get_joydev_axis_number(item->value));
914 #elif defined(SDL_INPUT)
915                                 if (joyaxis_text[item->value])
916                                         strncpy(btext, joyaxis_text[item->value], 10);
917                                 else
918                                         sprintf(btext, "AXIS%2d", item->value + 1);
919 #else
920                                 strncpy(btext, Text_string[joyaxis_text[item->value]], 10);
921 #endif
922                                 break;
923                         case BT_INVERT:
924                                 strncpy( btext, Text_string[invert_text[item->value]], 10 ); break;
925                 }
926         }
927         if (item->w1) {
928                 gr_get_string_size(btext, &w, &h, &aw  );
929
930                 if (is_current)
931                         gr_setcolor( BM_XRGB(21,0,24) );
932                 else
933                         gr_setcolor( BM_XRGB(16,0,19) );
934                 gr_urect( LHX(item->w1+item->x), LHY(item->y-1), LHX(item->w1+item->x+item->w2), LHY(item->y)+h );
935                 
936                 gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
937
938                 x = LHX(item->w1+item->x)+((LHX(item->w2)-w)/2);
939         
940                 gr_string( x, LHY(item->y), btext );
941         }
942 }
943
944
945 static int looper=0;
946
947 void kc_drawquestion( kc_item *item )
948 {
949         int c, x, w, h, aw;
950
951         gr_get_string_size("?", &w, &h, &aw  );
952
953         c = BM_XRGB(21,0,24);
954
955         //@@gr_setcolor( gr_fade_table[fades[looper]*256+c] );
956         gr_setcolor(BM_XRGB(21*fades[looper]/31,0,24*fades[looper]/31));
957         looper++;
958         if (looper>63) looper=0;
959
960         gr_urect( LHX(item->w1+item->x), LHY(item->y-1), LHX(item->w1+item->x+item->w2), LHY(item->y)+h );
961         
962         gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
963
964         x = LHX(item->w1+item->x)+((LHX(item->w2)-w)/2);
965    
966         gr_string( x, LHY(item->y), "?" );
967 gr_update();
968 }
969
970 void kc_change_key( kc_item * item )
971 {
972         int i,n,f,k;
973         ubyte keycode;
974
975         gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
976         
977         gr_string( 0x8000, LHY(INFO_Y), TXT_PRESS_NEW_KEY );
978
979         game_flush_inputs();
980         keycode=255;
981         k=255;
982         
983         while( (k!=KEY_ESC) && (keycode==255) ) 
984         {                               
985                 #ifdef NETWORK
986                 if ((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME) && (!Endlevel_sequence))
987                         multi_menu_poll();
988                 #endif
989 //              if ( Game_mode & GM_MULTI )
990 //                      GameLoop( 0, 0 );                               // Continue
991                 k = key_inkey();
992                 timer_delay(f0_1/10);
993                 kc_drawquestion( item );
994         
995                 for (i=0; i<256; i++ )  {
996                         if (keyd_pressed[i] && (strlen(key_text[i])>0)) {
997                                 f = 0;
998                                 for (n=0; n<sizeof(system_keys); n++ )
999                                         if ( system_keys[n] == i )
1000                                                 f=1;
1001                                 if (!f) 
1002                                         keycode=i;
1003                         }
1004                 }
1005         }
1006
1007         if (k!=KEY_ESC) {
1008                 for (i=0; i<Num_items; i++ )    {
1009                         n = (int)(item - All_items);
1010                         if ( (i!=n) && (All_items[i].type==BT_KEY) && (All_items[i].value==keycode) )           {
1011                                 All_items[i].value = 255;
1012                                 kc_drawitem( &All_items[i], 0 );
1013                         }
1014                 }
1015                 item->value = keycode;
1016         }
1017         kc_drawitem( item, 1 );
1018
1019         gr_set_fontcolor( BM_XRGB(28,28,28), BM_XRGB(0,0,0) );
1020
1021         nm_restore_background( 0, LHY(INFO_Y), LHX(310), grd_curcanv->cv_font->ft_h );
1022
1023         game_flush_inputs();
1024
1025 }
1026
1027
1028 // 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
1029 void kc_next_joyaxis(kc_item *item)
1030 {
1031         int n, i, k, max, tries;
1032         ubyte code = 0;
1033
1034         k = 255;
1035         n = 0;
1036         i = 0;
1037
1038         // I modelled this ifdef after the code in the kc_change_joyaxis method.
1039         // So, if somethin's not workin here, it might not be workin there either.
1040         max = JOY_MAX_AXES;
1041         tries = 1;
1042         code = (item->value + 1) % max;
1043
1044         if (code != 255)
1045         {
1046                 for (i = 0; i < Num_items; i++)
1047                 {
1048                         n = (int)(item - All_items);
1049                         if ((i != n) && (All_items[i].type == BT_JOY_AXIS) && (All_items[i].value == code))
1050                         {
1051                                 if (tries > max)
1052                                         return; // all axes allocated already
1053                                 i = -1; // -1 so the i++ will push back to 0
1054                                 code = (item->value + ++tries) % max; // try next axis
1055                         }//end if
1056                 }//end for
1057
1058                 item->value = code;
1059         }//end if
1060
1061         kc_drawitem(item, 1);
1062         nm_restore_background(0, LHY(INFO_Y), LHX(310), grd_curcanv->cv_font->ft_h);
1063         game_flush_inputs();
1064
1065 }//method kc_next_joyaxis
1066 //end addition by WraithX
1067
1068
1069 void kc_change_joyaxis( kc_item * item )
1070 {
1071         int axis[JOY_MAX_AXES];
1072         int old_axis[JOY_MAX_AXES];
1073         int numaxis = joy_num_axes;
1074         int n,i,k;
1075         ubyte code;
1076
1077         gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
1078         
1079         gr_string( 0x8000, LHY(INFO_Y), TXT_MOVE_NEW_JOY_AXIS );
1080
1081         game_flush_inputs();
1082         code=255;
1083         k=255;
1084
1085         joystick_read_raw_axis( JOY_ALL_AXIS, old_axis );
1086
1087         while( (k!=KEY_ESC) && (code==255))     
1088         {                               
1089                 #ifdef NETWORK
1090                 if ((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME) && (!Endlevel_sequence))
1091                         multi_menu_poll();
1092                 #endif
1093 //              if ( Game_mode & GM_MULTI )
1094 //                      GameLoop( 0, 0 );                               // Continue
1095                 k = key_inkey();
1096                 timer_delay(f0_1/10);
1097
1098                 if (k == KEY_PRINT_SCREEN)
1099                         save_screen_shot(0);
1100
1101                 kc_drawquestion( item );
1102
1103                 joystick_read_raw_axis( JOY_ALL_AXIS, axis );
1104
1105                 for (i=0; i<numaxis; i++ )      {
1106                         if ( abs(axis[i]-old_axis[i])>100 )
1107                         {
1108                                 code = i;
1109                                 con_printf(CON_DEBUG, "Axis Movement detected: Axis %i\n", i);
1110                         }
1111                         //old_axis[i] = axis[i];
1112                 }
1113                 for (i=0; i<Num_items; i++ )    
1114                  {
1115                         n = (int)(item - All_items);
1116                         if ( (i!=n) && (All_items[i].type==BT_JOY_AXIS) && (All_items[i].value==code) ) 
1117                                 code = 255;
1118                  }
1119         
1120         }
1121         if (code!=255)  {
1122                 for (i=0; i<Num_items; i++ )    {
1123                         n = (int)(item - All_items);
1124                         if ( (i!=n) && (All_items[i].type==BT_JOY_AXIS) && (All_items[i].value==code) ) {
1125                                 All_items[i].value = 255;
1126                                 kc_drawitem( &All_items[i], 0 );
1127                         }
1128                 }
1129
1130                 item->value = code;                                      
1131         }
1132         kc_drawitem( item, 1 );
1133         nm_restore_background( 0, LHY(INFO_Y), LHX(310), grd_curcanv->cv_font->ft_h );
1134         game_flush_inputs();
1135
1136 }
1137
1138 void kc_change_mouseaxis( kc_item * item )
1139 {
1140         int i,n,k;
1141         ubyte code;
1142         int dx, dy, dz;
1143
1144         gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
1145         
1146         gr_string( 0x8000, LHY(INFO_Y), TXT_MOVE_NEW_MSE_AXIS );
1147
1148         game_flush_inputs();
1149         code=255;
1150         k=255;
1151
1152         mouse_get_delta( &dx, &dy, &dz );
1153
1154         while( (k!=KEY_ESC) && (code==255))     
1155         {                               
1156                 #ifdef NETWORK
1157                 if ((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME) && (!Endlevel_sequence))
1158                         multi_menu_poll();
1159                 #endif
1160 //              if ( Game_mode & GM_MULTI )
1161 //                      GameLoop( 0, 0 );                               // Continue
1162                 k = key_inkey();
1163                 timer_delay(f0_1/10);
1164
1165                 if (k == KEY_PRINT_SCREEN)
1166                         save_screen_shot(0);
1167
1168                 kc_drawquestion( item );
1169
1170                 mouse_get_delta( &dx, &dy, &dz );
1171                 if ( abs(dx)>20 ) code = 0;
1172                 if ( abs(dy)>20 ) code = 1;
1173                 if ( abs(dz)>20 ) code = 2;
1174         }
1175         if (code!=255)  {
1176                 for (i=0; i<Num_items; i++ )    {
1177                         n = (int)(item - All_items);
1178                         if ( (i!=n) && (All_items[i].type==BT_MOUSE_AXIS) && (All_items[i].value==code) )               {
1179                                 All_items[i].value = 255;
1180                                 kc_drawitem( &All_items[i], 0 );
1181                         }
1182                 }
1183                 item->value = code;
1184         }
1185         kc_drawitem( item, 1 );
1186         nm_restore_background( 0, LHY(INFO_Y), LHX(310), grd_curcanv->cv_font->ft_h );
1187         game_flush_inputs();
1188
1189 }
1190
1191
1192 void kc_change_invert( kc_item * item )
1193 {
1194         game_flush_inputs();
1195
1196         if (item->value)
1197                 item->value = 0;
1198         else 
1199                 item->value = 1;
1200
1201         kc_drawitem( item, 1 );
1202
1203 }
1204
1205 #include "screens.h"
1206
1207 void kconfig(int n, char * title)
1208 {
1209         int i, j;
1210         grs_bitmap *save_bm;
1211
1212         set_screen_mode( SCREEN_MENU );
1213
1214         kc_set_controls();
1215
1216         //save screen
1217         save_bm = gr_create_bitmap( grd_curcanv->cv_bitmap.bm_w, grd_curcanv->cv_bitmap.bm_h );
1218         Assert( save_bm != NULL );
1219         
1220         gr_bm_bitblt(grd_curcanv->cv_bitmap.bm_w, grd_curcanv->cv_bitmap.bm_w, 
1221                                         0, 0, 0, 0, &grd_curcanv->cv_bitmap, save_bm );
1222
1223         switch(n)       {
1224         case 0:kconfig_sub( kc_keyboard, NUM_KEY_CONTROLS, title );break;
1225         case 1:kconfig_sub( kc_other, NUM_OTHER_CONTROLS, title );break;
1226         case 2:kconfig_sub( kc_d2x, NUM_D2X_CONTROLS, title ); break;
1227         default:
1228                 Int3();
1229                 return;
1230         }
1231
1232         //restore screen
1233         gr_bitmap(0, 0, save_bm);
1234         gr_free_bitmap(save_bm);
1235
1236 #if 0 // set_screen_mode always calls this later... right?
1237         reset_cockpit();                //force cockpit redraw next time
1238 #endif
1239
1240         // Update save values...
1241         
1242         for (j=0; j<256; j++)
1243                 if (key_binding(j)) {
1244                         for (i = 0; i < NUM_KEY_CONTROLS; i++)
1245                                 if (!stricmp(key_binding(j), kc_key_bind_text[i])) {
1246                                         cmd_appendf("unbind %s", key_text[j]);
1247                                         break;
1248                                 }
1249                         for (i = 0; i < NUM_D2X_CONTROLS; i++)
1250                                 if (kc_d2x[i].type == BT_KEY && !stricmp(key_binding(j), kc_d2x[i].text)) {
1251                                         cmd_appendf("unbind %s", key_text[j]);
1252                                         break;
1253                                 }
1254                 }
1255
1256         for (i=0; i<NUM_KEY_CONTROLS; i++ )
1257                 if (kc_keyboard[i].value != 255)
1258                         cmd_appendf("bind %s \"%s\"", key_text[kc_keyboard[i].value], kc_key_bind_text[i]);
1259
1260         for (i = 0; i < NUM_D2X_CONTROLS; i++)
1261                 if (kc_d2x[i].value != 255)
1262                         cmd_appendf("bind %s \"%s\"", key_text[kc_d2x[i].value], kc_d2x[i].text);
1263
1264         for (i = 0; i < 6; i++) {
1265                 cvar_setint(&joy_advaxes[i], AXIS_NONE);
1266                 cvar_setint(&joy_invert[i], 0);
1267         }
1268         for (i = 0; i < 3; i++) {
1269                 cvar_setint(&mouse_axes[i], AXIS_NONE);
1270                 cvar_setint(&mouse_invert[i], 0);
1271         }
1272         for (i = 0; i < NUM_OTHER_CONTROLS; i++) {
1273                 if (kc_other[i].type == BT_JOY_AXIS && kc_other[i].value != 255) {
1274                         cvar_setint(&joy_advaxes[kc_other[i].value], kc_other_axismap[i]);
1275                         cvar_setint(&joy_invert[kc_other[i].value], kc_other[i+1].value);
1276                 }
1277                 if (kc_other[i].type == BT_MOUSE_AXIS && kc_other[i].value != 255) {
1278                         cvar_setint(&mouse_axes[kc_other[i].value], kc_other_axismap[i]);
1279                         cvar_setint(&mouse_invert[kc_other[i].value], kc_other[i+1].value);
1280                 }
1281         }
1282
1283         cmd_queue_process();
1284 }
1285
1286
1287 fix Last_angles_p = 0;
1288 fix Last_angles_b = 0;
1289 fix Last_angles_h = 0;
1290 ubyte Last_angles_read = 0;
1291
1292 extern int                      VR_sensitivity;
1293                                                 
1294 int VR_sense_range[3] = { 25, 50, 75 };
1295
1296 #if 0 // unused
1297 read_head_tracker()
1298 {
1299         fix yaw, pitch, roll;
1300         int buttons;
1301
1302 //------ read vfx1 helmet --------
1303         if (vfx1_installed) {
1304                 vfx_get_data(&yaw,&pitch,&roll,&buttons);
1305         } else if (iglasses_headset_installed)  {
1306                 iglasses_read_headset( &yaw, &pitch, &roll );
1307         } else if (Victor_headset_installed)   {
1308                 victor_read_headset_filtered( &yaw, &pitch, &roll );
1309         } else {
1310                 return;
1311         }
1312
1313         Use_player_head_angles = 0;
1314         if ( Last_angles_read ) {
1315                 fix yaw1 = yaw;
1316                 
1317                 yaw1 = yaw;
1318                 if ( (Last_angles_h < (F1_0/4) ) && (yaw > ((F1_0*3)/4) ) )     
1319                         yaw1 -= F1_0;
1320                 else if ( (yaw < (F1_0/4) ) && (Last_angles_h > ((F1_0*3)/4) ) )        
1321                         yaw1 += F1_0;
1322         
1323                 Controls.pitch_time     += fixmul((pitch- Last_angles_p)*VR_sense_range[VR_sensitivity],FrameTime);
1324                 Controls.heading_time+= fixmul((yaw1 -  Last_angles_h)*VR_sense_range[VR_sensitivity],FrameTime);
1325                 Controls.bank_time      += fixmul((roll - Last_angles_b)*VR_sense_range[VR_sensitivity],FrameTime);
1326         }
1327         Last_angles_read = 1;
1328         Last_angles_p = pitch;
1329         Last_angles_h = yaw;
1330         Last_angles_b = roll;
1331 }
1332 #endif
1333
1334
1335 void kc_set_controls()
1336 {
1337         int i, j;
1338
1339         for (i=0; i<NUM_KEY_CONTROLS; i++ )
1340                 kc_keyboard[i].value = 255;
1341
1342         for (i=0; i<NUM_OTHER_CONTROLS; i++ ) {
1343                 if (kc_other[i].type == BT_INVERT)
1344                         kc_other[i].value = 0;
1345                 else
1346                         kc_other[i].value = 255;
1347         }
1348
1349         for (i=0; i<NUM_D2X_CONTROLS; i++ )
1350                 kc_d2x[i].value = 255;
1351
1352         for (j = 0; j < 256; j++)
1353                 if (key_binding(j)) {
1354                         for (i = 0; i < NUM_KEY_CONTROLS; i++)
1355                                 if (kc_keyboard[i].value == 255
1356                                         && !stricmp(key_binding(j), kc_key_bind_text[i])) {
1357                                         kc_keyboard[i].value = j;
1358                                         break;
1359                                 }
1360                 }
1361
1362         for(j = 0; j < 256; j++)
1363                 if (key_binding(j)) {
1364                         for (i = 0; i < NUM_D2X_CONTROLS; i++)
1365                                 if (kc_d2x[i].value == 255
1366                                         && !stricmp(key_binding(j), kc_d2x[i].text)) {
1367                                         kc_d2x[i].value = j;
1368                                         break;
1369                                 }
1370                 }
1371
1372         for (i = 0; i < 6; i++) {
1373                 int inv = joy_invert[i].intval;
1374                 switch (joy_advaxes[i].intval) {
1375                         case AXIS_PITCH:     kc_other[ 0].value = i; kc_other[ 1].value = inv; break;
1376                         case AXIS_TURN:      kc_other[ 2].value = i; kc_other[ 3].value = inv; break;
1377                         case AXIS_LEFTRIGHT: kc_other[ 4].value = i; kc_other[ 5].value = inv; break;
1378                         case AXIS_UPDOWN:    kc_other[ 6].value = i; kc_other[ 7].value = inv; break;
1379                         case AXIS_BANK:      kc_other[ 8].value = i; kc_other[ 9].value = inv; break;
1380                         case AXIS_THROTTLE:  kc_other[10].value = i; kc_other[11].value = inv; break;
1381                         case AXIS_NONE:      break;
1382                         default:
1383                                 Int3();
1384                                 break;
1385                 }
1386         }
1387
1388         for (i = 0; i < 3; i++) {
1389                 int inv = mouse_invert[i].intval;
1390                 switch (mouse_axes[i].intval) {
1391                         case AXIS_PITCH:     kc_other[12].value = i; kc_other[13].value = inv; break;
1392                         case AXIS_TURN:      kc_other[14].value = i; kc_other[15].value = inv; break;
1393                         case AXIS_LEFTRIGHT: kc_other[16].value = i; kc_other[17].value = inv; break;
1394                         case AXIS_UPDOWN:    kc_other[18].value = i; kc_other[19].value = inv; break;
1395                         case AXIS_BANK:      kc_other[20].value = i; kc_other[21].value = inv; break;
1396                         case AXIS_THROTTLE:  kc_other[22].value = i; kc_other[23].value = inv; break;
1397                         case AXIS_NONE:      break;
1398                         default:
1399                                 Int3();
1400                                 break;
1401                 }
1402         }
1403 }
1404
1405 #if 0 // no mac support for vr headset
1406
1407 void kconfig_center_headset()
1408 {
1409         if (vfx1_installed)
1410                 vfx_center_headset();
1411 //      } else if (iglasses_headset_installed)  {
1412 //      } else if (Victor_headset_installed)   {
1413 //      } else {
1414 //      }
1415
1416 }
1417
1418 #endif // end of #if for kconfig_center_headset