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