]> icculus.org git repositories - btb/d2x.git/blob - main/kconfig.c
missed this in ee8b69c359dd08d2d0d2fadbdf9da71e117b600c
[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         /*
966         gr_setcolor( BM_XRGB(0, 0, 0) );
967         gr_rect(close_x, close_y, close_x + close_size, close_y + close_size);
968         gr_setcolor( BM_XRGB(21, 21, 21) );
969         gr_rect(close_x + LHX(1), close_y + LHX(1), close_x + close_size - LHX(1), close_y + close_size - LHX(1));
970         */
971 #endif
972
973         grd_curcanv->cv_font = GAME_FONT;
974         gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
975
976         #ifndef MACINTOSH
977         gr_string( 0x8000, LHY(20), TXT_KCONFIG_STRING_1 );
978         #else
979         gr_string( 0x8000, LHY(20), "Enter changes, ctrl-d deletes, ctrl-r resets defaults, ESC exits");
980         #endif
981         gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
982         if ( items == kc_keyboard )     {
983                 gr_set_fontcolor( BM_XRGB(31,27,6), -1 );
984                 gr_setcolor( BM_XRGB(31,27,6) );
985                 
986                 gr_scanline( LHX(98), LHX(106), LHY(42) );
987                 gr_scanline( LHX(120), LHX(128), LHY(42) );
988                 gr_pixel( LHX(98), LHY(43) );                                           
989                 gr_pixel( LHX(98), LHY(44) );                                           
990                 gr_pixel( LHX(128), LHY(43) );                                          
991                 gr_pixel( LHX(128), LHY(44) );                                          
992                 
993                 gr_string( LHX(109), LHY(40), "OR" );
994
995                 gr_scanline( LHX(253), LHX(261), LHY(42) );
996                 gr_scanline( LHX(274), LHX(283), LHY(42) );
997                 gr_pixel( LHX(253), LHY(43) );                                          
998                 gr_pixel( LHX(253), LHY(44) );                                          
999                 gr_pixel( LHX(283), LHY(43) );                                          
1000                 gr_pixel( LHX(283), LHY(44) );                                          
1001
1002                 gr_string( LHX(264), LHY(40), "OR" );
1003
1004         } if ( items == kc_joystick )   {
1005                 gr_set_fontcolor( BM_XRGB(31,27,6), -1 );
1006                 gr_setcolor( BM_XRGB(31,27,6) );
1007                 gr_scanline( LHX(18), LHX(135), LHY(37) );
1008                 gr_scanline( LHX(181), LHX(294), LHY(37) );
1009                 gr_scanline( LHX(18), LHX(144), LHY(119+18) );
1010                 gr_scanline( LHX(174), LHX(294), LHY(119+18) );
1011                 gr_string( 0x8000, LHY(35), TXT_BUTTONS );
1012                 gr_string( 0x8000,LHY(117+18), TXT_AXES );
1013                 gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
1014                 gr_string( LHX(81), LHY(137+8), TXT_AXIS );
1015                 gr_string( LHX(111), LHY(137+8), TXT_INVERT );
1016                 gr_string( LHX(230), LHY(137+8), TXT_AXIS );
1017                 gr_string( LHX(260), LHY(137+8), TXT_INVERT );
1018         } else if ( items == kc_mouse ) {
1019                 gr_set_fontcolor( BM_XRGB(31,27,6), -1 );
1020                 gr_setcolor( BM_XRGB(31,27,6) );
1021                 gr_scanline( LHX(18), LHX(135), LHY(37) );
1022                 gr_scanline( LHX(181), LHX(294), LHY(37) );
1023                 gr_scanline( LHX(18), LHX(144), LHY(119+5) );
1024                 gr_scanline( LHX(174), LHX(294), LHY(119+5) );
1025                 gr_string( 0x8000, LHY(35), TXT_BUTTONS );
1026                 gr_string( 0x8000,LHY(117+5), TXT_AXES );
1027                 gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
1028                 gr_string( LHX(169), LHY(129), TXT_AXIS );
1029                 gr_string( LHX(199), LHY(129), TXT_INVERT );
1030         }
1031         else if ( items == kc_d2x )
1032         {
1033                 gr_set_fontcolor( BM_XRGB(31,27,6), -1 );
1034                 gr_setcolor( BM_XRGB(31,27,6) );
1035
1036                 gr_string(LHX( 94), LHY(40), "KB");
1037                 gr_string(LHX(121), LHY(40), "JOY");
1038         }
1039
1040         for (i=0; i<nitems; i++ )       {
1041                 kc_drawitem( &items[i], 0 );
1042         }
1043
1044         citem = 0;
1045         kc_drawitem( &items[citem], 1 );
1046
1047         newmenu_show_cursor();
1048
1049 #ifdef NEWMENU_MOUSE
1050         mouse_state = omouse_state = 0;
1051 #endif
1052
1053         while(1)                {
1054         //      Windows addendum to allow for kconfig input.
1055                 gr_update();
1056
1057                 //see if redbook song needs to be restarted
1058                 songs_check_redbook_repeat();
1059
1060                 k = key_inkey();
1061
1062 #ifdef NEWMENU_MOUSE
1063                 omouse_state = mouse_state;
1064                 mouse_state = mouse_button_state(0);
1065 #endif
1066
1067                 if ( !time_stopped ) {
1068                         #ifdef NETWORK
1069                         if (multi_menu_poll() == -1)
1070                                 k = -2;
1071                         #endif
1072                 }
1073                 ocitem = citem;
1074                 switch( k )     {
1075                 case KEY_BACKSP:
1076                         Int3();
1077                         break;
1078                 case KEY_COMMAND+KEY_SHIFTED+KEY_3:
1079                 case KEY_PRINT_SCREEN:
1080                         save_screen_shot(0);
1081                         break;                                                  
1082                 case KEY_CTRLED+KEY_D:
1083                         items[citem].value = 255;
1084                         kc_drawitem( &items[citem], 1 );
1085                         break;
1086                 case KEY_CTRLED+KEY_R:  
1087                         if ( items==kc_keyboard )       {
1088                                 for (i=0; i<NUM_KEY_CONTROLS; i++ )             {
1089                                         items[i].value=default_kconfig_settings[0][i];
1090                                         kc_drawitem( &items[i], 0 );
1091                                 }
1092                         } else if ( items==kc_d2x ) {
1093                                 for(i=0;i<NUM_D2X_CONTROLS;i++)
1094                                 {
1095                                         items[i].value=default_kconfig_d2x_settings[i];
1096                                         kc_drawitem( &items[i], 0 );
1097                                 }
1098                         } else {
1099                                 #ifdef MACINTOSH
1100                           // hack for firebire and mousestick default controls since I made
1101                           // them the same control type -- dumb dumb dumb
1102                                 if (joy_have_firebird())
1103                                         for (i=0; i<NUM_OTHER_CONTROLS; i++ )   {
1104                                                 items[i].value = default_firebird_settings[i];
1105                                                 kc_drawitem( &items[i], 0 );
1106                                         }
1107                                 else if (joy_have_mousestick())
1108                                         for (i=0; i<NUM_OTHER_CONTROLS; i++ )   {
1109                                                 items[i].value = default_mousestick_settings[i];
1110                                                 kc_drawitem( &items[i], 0 );
1111                                         }
1112                                 else
1113                                 #endif  // note link to above else
1114                                         for (i=0; i<NUM_OTHER_CONTROLS; i++ )   {
1115                                                 items[i].value = default_kconfig_settings[Config_control_type][i];
1116                                                 kc_drawitem( &items[i], 0 );
1117                                         }
1118                         }
1119                         kc_drawitem( &items[citem], 1 );
1120                         break;
1121                 case KEY_DELETE:
1122                         items[citem].value=255;
1123                         kc_drawitem( &items[citem], 1 );
1124                         break;
1125                 case KEY_UP:            
1126                 case KEY_PAD8:
1127 #ifdef TABLE_CREATION
1128                         if (items[citem].u==-1) items[citem].u=find_next_item_up( items,nitems, citem);
1129 #endif
1130                         citem = items[citem].u; 
1131                         break;
1132                 
1133                 case KEY_DOWN:  
1134                 case KEY_PAD2:
1135 #ifdef TABLE_CREATION
1136                         if (items[citem].d==-1) items[citem].d=find_next_item_down( items,nitems, citem);
1137 #endif
1138                         citem = items[citem].d; 
1139                         break;
1140                 case KEY_LEFT:  
1141                 case KEY_PAD4:
1142 #ifdef TABLE_CREATION
1143                         if (items[citem].l==-1) items[citem].l=find_next_item_left( items,nitems, citem);
1144 #endif
1145                         citem = items[citem].l; 
1146                         break;
1147                 case KEY_RIGHT:         
1148                 case KEY_PAD6:
1149 #ifdef TABLE_CREATION
1150                         if (items[citem].r==-1) items[citem].r=find_next_item_right( items,nitems, citem);
1151 #endif
1152                         citem = items[citem].r; 
1153                         break;
1154                 case KEY_ENTER: 
1155                 case KEY_PADENTER:      
1156                         switch( items[citem].type )     {
1157                         case BT_KEY:            kc_change_key( &items[citem] ); break;
1158                         case BT_MOUSE_BUTTON:   kc_change_mousebutton( &items[citem] ); break;
1159                         case BT_MOUSE_AXIS:     kc_change_mouseaxis( &items[citem] ); break;
1160                         case BT_JOY_BUTTON:     kc_change_joybutton( &items[citem] ); break;
1161                         case BT_JOY_AXIS:       kc_change_joyaxis( &items[citem] ); break;
1162                         case BT_INVERT:         kc_change_invert( &items[citem] ); break;
1163                         }
1164                         break;
1165                 //the following case added by WraithX on 11/22/00 to work around the weird joystick bug...
1166                 case KEY_SPACEBAR:
1167                         switch(items[citem].type)
1168                         {
1169                         case BT_JOY_AXIS:
1170                                 kc_next_joyaxis(&items[citem]);
1171                                 break;
1172                         }
1173                         break;
1174                 //end addition by WraithX
1175                 case -2:        
1176                 case KEY_ESC:
1177                         grd_curcanv->cv_font    = save_font;
1178
1179                         gr_set_current_canvas( save_canvas );
1180                         keyd_repeat = old_keyd_repeat;
1181                         game_flush_inputs();
1182                         newmenu_hide_cursor();
1183                         if (time_stopped)
1184                                 start_time();
1185                         return;
1186 #ifdef TABLE_CREATION
1187                 case KEY_DEBUGGED+KEY_F12:      {
1188                         FILE * fp;
1189                         for (i=0; i<NUM_KEY_CONTROLS; i++ )     {
1190                                 kc_keyboard[i].u = find_next_item_up( kc_keyboard,NUM_KEY_CONTROLS, i);
1191                                 kc_keyboard[i].d = find_next_item_down( kc_keyboard,NUM_KEY_CONTROLS, i);
1192                                 kc_keyboard[i].l = find_next_item_left( kc_keyboard,NUM_KEY_CONTROLS, i);
1193                                 kc_keyboard[i].r = find_next_item_right( kc_keyboard,NUM_KEY_CONTROLS, i);
1194                         }
1195                         for (i=0; i<NUM_OTHER_CONTROLS; i++ )   {
1196                                 kc_joystick[i].u = find_next_item_up( kc_joystick,NUM_OTHER_CONTROLS, i);
1197                                 kc_joystick[i].d = find_next_item_down( kc_joystick,NUM_OTHER_CONTROLS, i);
1198                                 kc_joystick[i].l = find_next_item_left( kc_joystick,NUM_OTHER_CONTROLS, i);
1199                                 kc_joystick[i].r = find_next_item_right( kc_joystick,NUM_OTHER_CONTROLS, i);
1200                         }
1201                         for (i=0; i<NUM_OTHER_CONTROLS; i++ )   {
1202                                 kc_mouse[i].u = find_next_item_up( kc_mouse,NUM_OTHER_CONTROLS, i);
1203                                 kc_mouse[i].d = find_next_item_down( kc_mouse,NUM_OTHER_CONTROLS, i);
1204                                 kc_mouse[i].l = find_next_item_left( kc_mouse,NUM_OTHER_CONTROLS, i);
1205                                 kc_mouse[i].r = find_next_item_right( kc_mouse,NUM_OTHER_CONTROLS, i);
1206                         }
1207                         fp = fopen( "kconfig.cod", "wt" );
1208
1209                         fprintf( fp, "ubyte default_kconfig_settings[CONTROL_MAX_TYPES][MAX_CONTROLS] = {\n" );
1210                         for (i=0; i<CONTROL_MAX_TYPES; i++ )    {
1211                                 int j;
1212                                 fprintf( fp, "{0x%x", kconfig_settings[i][0] );
1213                                 for (j=1; j<MAX_CONTROLS; j++ )
1214                                         fprintf( fp, ",0x%x", kconfig_settings[i][j] );
1215                                 fprintf( fp, "},\n" );
1216                         }
1217                         fprintf( fp, "};\n" );
1218                 
1219                         fprintf( fp, "\nkc_item kc_keyboard[NUM_KEY_CONTROLS] = {\n" );
1220                         for (i=0; i<NUM_KEY_CONTROLS; i++ )     {
1221                                 fprintf( fp, "\t{ %2d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%c%s%c, %s, 255 },\n", 
1222                                         kc_keyboard[i].id, kc_keyboard[i].x, kc_keyboard[i].y, kc_keyboard[i].w1, kc_keyboard[i].w2,
1223                                         kc_keyboard[i].u, kc_keyboard[i].d, kc_keyboard[i].l, kc_keyboard[i].r,
1224                                         34, kc_keyboard[i].text, 34, btype_text[kc_keyboard[i].type] );
1225                         }
1226                         fprintf( fp, "};" );
1227
1228                         fprintf( fp, "\nkc_item kc_joystick[NUM_OTHER_CONTROLS] = {\n" );
1229                         for (i=0; i<NUM_OTHER_CONTROLS; i++ )   {
1230                                 if (kc_joystick[i].type == BT_JOY_BUTTON)
1231                                         fprintf( fp, "\t{ %2d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%c%s%c, %s, 255 },\n", 
1232                                                 kc_joystick[i].id, kc_joystick[i].x, kc_joystick[i].y, kc_joystick[i].w1, kc_joystick[i].w2,
1233                                                 kc_joystick[i].u, kc_joystick[i].d, kc_joystick[i].l, kc_joystick[i].r,
1234                                                 34, kc_joystick[i].text, 34, btype_text[kc_joystick[i].type] );
1235                 else
1236                                         fprintf( fp, "\t{ %2d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%c%s%c, %s, 255 },\n", 
1237                                                 kc_joystick[i].id, kc_joystick[i].x, kc_joystick[i].y, kc_joystick[i].w1, kc_joystick[i].w2,
1238                                                 kc_joystick[i].u, kc_joystick[i].d, kc_joystick[i].l, kc_joystick[i].r,
1239                                                 34, kc_joystick[i].text, 34, btype_text[kc_joystick[i].type] );
1240                         }
1241                         fprintf( fp, "};" );
1242
1243                         fprintf( fp, "\nkc_item kc_mouse[NUM_OTHER_CONTROLS] = {\n" );
1244                         for (i=0; i<NUM_OTHER_CONTROLS; i++ )   {
1245                                 fprintf( fp, "\t{ %2d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%c%s%c, %s, 255 },\n", 
1246                                         kc_mouse[i].id, kc_mouse[i].x, kc_mouse[i].y, kc_mouse[i].w1, kc_mouse[i].w2,
1247                                         kc_mouse[i].u, kc_mouse[i].d, kc_mouse[i].l, kc_mouse[i].r,
1248                                         34, kc_mouse[i].text, 34, btype_text[kc_mouse[i].type] );
1249                         }
1250                         fprintf( fp, "};" );
1251
1252                         fclose(fp);
1253
1254                         }
1255                         break;
1256 #endif
1257                 }
1258
1259 #ifdef NEWMENU_MOUSE
1260                 if ( (mouse_state && !omouse_state) || (mouse_state && omouse_state) ) {
1261                         int item_height;
1262                         
1263                         mouse_get_pos(&mx, &my);
1264                         for (i=0; i<nitems; i++ )       {
1265                                 item_height = get_item_height( &items[i] );
1266                                 x1 = grd_curcanv->cv_bitmap.bm_x + LHX(items[i].x) + LHX(items[i].w1);
1267                                 x2 = x1 + LHX(items[i].w2);
1268                                 y1 = grd_curcanv->cv_bitmap.bm_y + LHY(items[i].y);
1269                                 y2 = y1 + LHX(item_height);
1270                                 if (((mx > x1) && (mx < x2)) && ((my > y1) && (my < y2))) {
1271                                         citem = i;
1272                                         break;
1273                                 }
1274                         }
1275                 }
1276                 else if ( !mouse_state && omouse_state ) {
1277                         int item_height;
1278                         
1279                         mouse_get_pos(&mx, &my);
1280                         item_height = get_item_height( &items[citem] );
1281                         x1 = grd_curcanv->cv_bitmap.bm_x + LHX(items[citem].x) + LHX(items[citem].w1);
1282                         x2 = x1 + LHX(items[citem].w2);
1283                         y1 = grd_curcanv->cv_bitmap.bm_y + LHY(items[citem].y);
1284                         y2 = y1 + LHY(item_height);
1285                         if (((mx > x1) && (mx < x2)) && ((my > y1) && (my < y2))) {
1286                                 newmenu_hide_cursor();
1287                                 switch( items[citem].type )     {
1288                                 case BT_KEY:                            kc_change_key( &items[citem] ); break;
1289                                 case BT_MOUSE_BUTTON:   kc_change_mousebutton( &items[citem] ); break;
1290                                 case BT_MOUSE_AXIS:             kc_change_mouseaxis( &items[citem] ); break;
1291                                 case BT_JOY_BUTTON:             kc_change_joybutton( &items[citem] ); break;
1292                                 case BT_JOY_AXIS:               kc_change_joyaxis( &items[citem] ); break;
1293                                 case BT_INVERT:                         kc_change_invert( &items[citem] ); break;
1294                                 }
1295                                 newmenu_show_cursor();
1296                         } else {
1297                                 x1 = grd_curcanv->cv_bitmap.bm_x + close_x + LHX(1);
1298                                 x2 = x1 + close_size - LHX(1);
1299                                 y1 = grd_curcanv->cv_bitmap.bm_y + close_y + LHX(1);
1300                                 y2 = y1 + close_size - LHX(1);
1301                                 if ( ((mx > x1) && (mx < x2)) && ((my > y1) && (my < y2)) ) {
1302                                         grd_curcanv->cv_font    = save_font;
1303                                         gr_set_current_canvas( save_canvas );
1304                                         keyd_repeat = old_keyd_repeat;
1305                                         game_flush_inputs();
1306                                         newmenu_hide_cursor();
1307                                         if (time_stopped)
1308                                                 start_time();
1309                                         return;
1310                                 }
1311                         }
1312
1313                 }
1314 #endif // NEWMENU_MOUSE
1315
1316                 if (ocitem!=citem)      {
1317                         newmenu_hide_cursor();
1318                         kc_drawitem( &items[ocitem], 0 );
1319                         kc_drawitem( &items[citem], 1 );
1320                         newmenu_show_cursor();
1321                 }
1322         }
1323 }
1324
1325
1326 void kc_drawitem( kc_item *item, int is_current )
1327 {
1328         int x, w, h, aw;
1329         char btext[16];
1330
1331         if (is_current)
1332                 gr_set_fontcolor( BM_XRGB(20,20,29), -1 );
1333         else
1334                 gr_set_fontcolor( BM_XRGB(15,15,24), -1 );
1335    gr_string( LHX(item->x), LHY(item->y), item->text );
1336
1337         if (item->value==255) {
1338                 strcpy( btext, "" );
1339         } else {
1340                 switch( item->type )    {
1341                         case BT_KEY:
1342                                 strncpy( btext, key_text[item->value], 10 ); break;
1343                         case BT_MOUSE_BUTTON:
1344                                 #ifndef MACINTOSH
1345                                 //strncpy( btext, Text_string[mousebutton_text[item->value]], 10 ); break;
1346                                 strncpy( btext, (item->value <= 3)?Text_string[mousebutton_text[item->value]]:mousebutton_textra[item->value-3], 10 ); break;
1347                                 #else
1348                                 strncpy( btext, mousebutton_text[item->value], 10 ); break;
1349                                 #endif
1350                         case BT_MOUSE_AXIS:
1351                                 strncpy( btext, Text_string[mouseaxis_text[item->value]], 10 ); break;
1352                         case BT_JOY_BUTTON:
1353 #ifdef USE_LINUX_JOY
1354                                 sprintf(btext, "J%d B%d", j_button[item->value].joydev, j_Get_joydev_button_number(item->value));
1355 #elif defined(SDL_INPUT)
1356                                 if (joybutton_text[item->value])
1357                                         strncpy(btext, joybutton_text[item->value], 10);
1358                                 else
1359                                         sprintf(btext, "BTN%2d", item->value + 1);
1360 #else
1361 # ifndef MACINTOSH
1362                                 if ( joybutton_text[item->value] !=-1 )
1363                                         strncpy( btext, Text_string[ joybutton_text[item->value]  ], 10 );
1364                                 else
1365                                         sprintf( btext, "BTN%d", item->value );
1366 # else
1367                                 strncpy( btext, joy_btn_name( item->value ), 10);
1368                                 if (btext == NULL)
1369                                         sprintf( btext, "BTN%d", item->value );
1370 # endif
1371 #endif
1372                                 break;
1373                         case BT_JOY_AXIS:
1374 #ifdef USE_LINUX_JOY
1375                                 sprintf(btext, "J%d A%d", j_axis[item->value].joydev, j_Get_joydev_axis_number(item->value));
1376 #elif defined(SDL_INPUT)
1377                                 if (joyaxis_text[item->value])
1378                                         strncpy(btext, joyaxis_text[item->value], 10);
1379                                 else
1380                                         sprintf(btext, "AXIS%2d", item->value + 1);
1381 #else
1382                                 strncpy(btext, Text_string[joyaxis_text[item->value]], 10);
1383 #endif
1384                                 break;
1385                         case BT_INVERT:
1386                                 strncpy( btext, Text_string[invert_text[item->value]], 10 ); break;
1387                 }
1388         }
1389         if (item->w1) {
1390                 gr_get_string_size(btext, &w, &h, &aw  );
1391
1392                 if (is_current)
1393                         gr_setcolor( BM_XRGB(21,0,24) );
1394                 else
1395                         gr_setcolor( BM_XRGB(16,0,19) );
1396                 gr_urect( LHX(item->w1+item->x), LHY(item->y-1), LHX(item->w1+item->x+item->w2), LHY(item->y)+h );
1397                 
1398                 gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
1399
1400                 x = LHX(item->w1+item->x)+((LHX(item->w2)-w)/2);
1401         
1402                 gr_string( x, LHY(item->y), btext );
1403         }
1404 }
1405
1406
1407 static int looper=0;
1408
1409 void kc_drawquestion( kc_item *item )
1410 {
1411         int c, x, w, h, aw;
1412
1413         gr_get_string_size("?", &w, &h, &aw  );
1414
1415         c = BM_XRGB(21,0,24);
1416
1417         //@@gr_setcolor( gr_fade_table[fades[looper]*256+c] );
1418         gr_setcolor(BM_XRGB(21*fades[looper]/31,0,24*fades[looper]/31));
1419         looper++;
1420         if (looper>63) looper=0;
1421
1422         gr_urect( LHX(item->w1+item->x), LHY(item->y-1), LHX(item->w1+item->x+item->w2), LHY(item->y)+h );
1423         
1424         gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
1425
1426         x = LHX(item->w1+item->x)+((LHX(item->w2)-w)/2);
1427    
1428         gr_string( x, LHY(item->y), "?" );
1429 gr_update();
1430 }
1431
1432 void kc_change_key( kc_item * item )
1433 {
1434         int i,n,f,k;
1435         ubyte keycode;
1436
1437         gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
1438         
1439         gr_string( 0x8000, LHY(INFO_Y), TXT_PRESS_NEW_KEY );
1440
1441         game_flush_inputs();
1442         keycode=255;
1443         k=255;
1444         
1445         while( (k!=KEY_ESC) && (keycode==255) ) 
1446         {                               
1447                 #ifdef NETWORK
1448                 if ((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME) && (!Endlevel_sequence))
1449                         multi_menu_poll();
1450                 #endif
1451 //              if ( Game_mode & GM_MULTI )
1452 //                      GameLoop( 0, 0 );                               // Continue
1453                 k = key_inkey();
1454                 timer_delay(f0_1/10);
1455                 kc_drawquestion( item );
1456         
1457                 for (i=0; i<256; i++ )  {
1458                         if (keyd_pressed[i] && (strlen(key_text[i])>0)) {
1459                                 f = 0;
1460                                 for (n=0; n<sizeof(system_keys); n++ )
1461                                         if ( system_keys[n] == i )
1462                                                 f=1;
1463                                 if (!f) 
1464                                         keycode=i;
1465                         }
1466                 }
1467         }
1468
1469         if (k!=KEY_ESC) {
1470                 for (i=0; i<Num_items; i++ )    {
1471                         n = item - All_items;
1472                         if ( (i!=n) && (All_items[i].type==BT_KEY) && (All_items[i].value==keycode) )           {
1473                                 All_items[i].value = 255;
1474                                 kc_drawitem( &All_items[i], 0 );
1475                         }
1476                 }
1477                 item->value = keycode;
1478         }
1479         kc_drawitem( item, 1 );
1480
1481         gr_set_fontcolor( BM_XRGB(28,28,28), BM_XRGB(0,0,0) );
1482
1483         nm_restore_background( 0, LHY(INFO_Y), LHX(310), grd_curcanv->cv_font->ft_h );
1484
1485         game_flush_inputs();
1486
1487 }
1488
1489 void kc_change_joybutton( kc_item * item )
1490 {
1491         int n,i,k;
1492         ubyte code;
1493
1494         gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
1495         
1496         gr_string( 0x8000, LHY(INFO_Y), TXT_PRESS_NEW_JBUTTON );
1497
1498         game_flush_inputs();
1499         code=255;
1500         k=255;
1501         
1502         while( (k!=KEY_ESC) && (code==255))     
1503         {                               
1504                 #ifdef NETWORK
1505                 if ((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME) && (!Endlevel_sequence))
1506                         multi_menu_poll();
1507                 #endif
1508 //              if ( Game_mode & GM_MULTI )
1509 //                      GameLoop( 0, 0 );                               // Continue
1510                 k = key_inkey();
1511                 timer_delay(f0_1/10);
1512
1513                 if (k == KEY_PRINT_SCREEN)
1514                         save_screen_shot(0);
1515
1516                 kc_drawquestion( item );
1517
1518 #ifdef MACINTOSH
1519                 code = joy_do_buttons();
1520 #endif
1521                 
1522 #if !defined(MACINTOSH)
1523                 if (Config_control_type==CONTROL_THRUSTMASTER_FCS)      {
1524                         int axis[4];
1525                         joystick_read_raw_axis( JOY_ALL_AXIS, axis );
1526                         kconfig_read_fcs( axis[3] );
1527                         if ( joy_get_button_state(7) ) code = 7;
1528                         if ( joy_get_button_state(11) ) code = 11;
1529                         if ( joy_get_button_state(15) ) code = 15;
1530                         if ( joy_get_button_state(19) ) code = 19;
1531                         for (i=0; i<4; i++ )    {
1532                                 if ( joy_get_button_state(i) )
1533                                         code = i;
1534                         }
1535                 } else if (Config_control_type==CONTROL_FLIGHTSTICK_PRO) {
1536                         for (i=4; i<20; i++ )   {
1537                                 if ( joy_get_button_state(i)  ) {
1538                                         code = i;
1539                                         mprintf(( 0, "JB: %d\n", code ));
1540                                 }
1541                         }
1542                 } else {
1543                         for (i = 0; i < JOY_MAX_BUTTONS; i++)
1544                         {
1545                                 if ( joy_get_button_state(i) )
1546                                         code = i;
1547                         }
1548                 }
1549 #endif
1550         }
1551         if (code!=255)  {
1552                 for (i=0; i<Num_items; i++ )    {
1553                         n = item - All_items;
1554                         if ( (i!=n) && (All_items[i].type==BT_JOY_BUTTON) && (All_items[i].value==code) ) {
1555                                 All_items[i].value = 255;
1556                                 kc_drawitem( &All_items[i], 0 );
1557                         }
1558                 }
1559                 item->value = code;
1560         }
1561         kc_drawitem( item, 1 );
1562         nm_restore_background( 0, LHY(INFO_Y), LHX(310), grd_curcanv->cv_font->ft_h );
1563         game_flush_inputs();
1564 }
1565
1566 void kc_change_mousebutton( kc_item * item )
1567 {
1568         int n,i,b,k;
1569         ubyte code;
1570
1571         gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
1572         
1573         gr_string( 0x8000, LHY(INFO_Y), TXT_PRESS_NEW_MBUTTON );
1574
1575         game_flush_inputs();
1576         code=255;
1577         k=255;
1578         
1579         while( (k!=KEY_ESC) && (code==255))     
1580         {                               
1581                 #ifdef NETWORK
1582                 if ((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME) && (!Endlevel_sequence))
1583                         multi_menu_poll();
1584                 #endif
1585 //              if ( Game_mode & GM_MULTI )
1586 //                      GameLoop( 0, 0 );                               // Continue
1587                 k = key_inkey();
1588                 timer_delay(f0_1/10);
1589
1590                 if (k == KEY_PRINT_SCREEN)
1591                         save_screen_shot(0);
1592
1593                 kc_drawquestion( item );
1594
1595                 b = mouse_get_btns();
1596                 for (i = 0; i < 16; i++ ) {
1597                         if ( b & (1<<i) )       
1598                                 code = i;
1599                 }
1600         }
1601         if (code!=255)  {
1602                 for (i=0; i<Num_items; i++ )    {
1603                         n = item - All_items;
1604                         if ( (i!=n) && (All_items[i].type==BT_MOUSE_BUTTON) && (All_items[i].value==code) )             {
1605                                 All_items[i].value = 255;
1606                                 kc_drawitem( &All_items[i], 0 );
1607                         }
1608                 }
1609                 item->value = code;
1610         }
1611         kc_drawitem( item, 1 );
1612         nm_restore_background( 0, LHY(INFO_Y), LHX(310), grd_curcanv->cv_font->ft_h );
1613         game_flush_inputs();
1614
1615 }
1616
1617
1618 // 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
1619 void kc_next_joyaxis(kc_item *item)
1620 {
1621         int n, i, k, max, tries;
1622         ubyte code = 0;
1623
1624         k = 255;
1625         n = 0;
1626         i = 0;
1627
1628         // I modelled this ifdef after the code in the kc_change_joyaxis method.
1629         // So, if somethin's not workin here, it might not be workin there either.
1630         max = JOY_MAX_AXES;
1631         tries = 1;
1632         code = (item->value + 1) % max;
1633
1634         if (code != 255)
1635         {
1636                 for (i = 0; i < Num_items; i++)
1637                 {
1638                         n = item - All_items;
1639                         if ((i != n) && (All_items[i].type == BT_JOY_AXIS) && (All_items[i].value == code))
1640                         {
1641                                 if (tries > max)
1642                                         return; // all axes allocated already
1643                                 i = -1; // -1 so the i++ will push back to 0
1644                                 code = (item->value + ++tries) % max; // try next axis
1645                         }//end if
1646                 }//end for
1647
1648                 item->value = code;
1649         }//end if
1650
1651         kc_drawitem(item, 1);
1652         nm_restore_background(0, LHY(INFO_Y), LHX(310), grd_curcanv->cv_font->ft_h);
1653         game_flush_inputs();
1654
1655 }//method kc_next_joyaxis
1656 //end addition by WraithX
1657
1658
1659 void kc_change_joyaxis( kc_item * item )
1660 {
1661         int axis[JOY_MAX_AXES];
1662         int old_axis[JOY_MAX_AXES];
1663         int numaxis = joy_num_axes;
1664         int n,i,k;
1665         ubyte code;
1666
1667         gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
1668         
1669         gr_string( 0x8000, LHY(INFO_Y), TXT_MOVE_NEW_JOY_AXIS );
1670
1671         game_flush_inputs();
1672         code=255;
1673         k=255;
1674
1675         joystick_read_raw_axis( JOY_ALL_AXIS, old_axis );
1676
1677         while( (k!=KEY_ESC) && (code==255))     
1678         {                               
1679                 #ifdef NETWORK
1680                 if ((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME) && (!Endlevel_sequence))
1681                         multi_menu_poll();
1682                 #endif
1683 //              if ( Game_mode & GM_MULTI )
1684 //                      GameLoop( 0, 0 );                               // Continue
1685                 k = key_inkey();
1686                 timer_delay(f0_1/10);
1687
1688                 if (k == KEY_PRINT_SCREEN)
1689                         save_screen_shot(0);
1690
1691                 kc_drawquestion( item );
1692
1693                 joystick_read_raw_axis( JOY_ALL_AXIS, axis );
1694
1695                 for (i=0; i<numaxis; i++ )      {
1696 #if defined (MACINTOSH)
1697                         if ( abs(axis[i]-old_axis[i])>100 )
1698 #else
1699                         if ( abs(axis[i]-old_axis[i])>200 )
1700 #endif
1701                         {
1702                                 code = i;
1703                                 con_printf(CON_DEBUG, "Axis Movement detected: Axis %i\n", i);
1704                         }
1705                         //old_axis[i] = axis[i];
1706                 }
1707                 for (i=0; i<Num_items; i++ )    
1708                  {
1709                         n = item - All_items;
1710                         if ( (i!=n) && (All_items[i].type==BT_JOY_AXIS) && (All_items[i].value==code) ) 
1711                                 code = 255;
1712                  }
1713         
1714         }
1715         if (code!=255)  {
1716                 for (i=0; i<Num_items; i++ )    {
1717                         n = item - All_items;
1718                         if ( (i!=n) && (All_items[i].type==BT_JOY_AXIS) && (All_items[i].value==code) ) {
1719                                 All_items[i].value = 255;
1720                                 kc_drawitem( &All_items[i], 0 );
1721                         }
1722                 }
1723
1724                 item->value = code;                                      
1725         }
1726         kc_drawitem( item, 1 );
1727         nm_restore_background( 0, LHY(INFO_Y), LHX(310), grd_curcanv->cv_font->ft_h );
1728         game_flush_inputs();
1729
1730 }
1731
1732 void kc_change_mouseaxis( kc_item * item )
1733 {
1734         int i,n,k;
1735         ubyte code;
1736         int dx,dy;
1737 #ifdef SDL_INPUT
1738         int dz;
1739 #endif
1740
1741         gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
1742         
1743         gr_string( 0x8000, LHY(INFO_Y), TXT_MOVE_NEW_MSE_AXIS );
1744
1745         game_flush_inputs();
1746         code=255;
1747         k=255;
1748
1749         mouse_get_delta( &dx, &dy );
1750
1751         while( (k!=KEY_ESC) && (code==255))     
1752         {                               
1753                 #ifdef NETWORK
1754                 if ((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME) && (!Endlevel_sequence))
1755                         multi_menu_poll();
1756                 #endif
1757 //              if ( Game_mode & GM_MULTI )
1758 //                      GameLoop( 0, 0 );                               // Continue
1759                 k = key_inkey();
1760                 timer_delay(f0_1/10);
1761
1762                 if (k == KEY_PRINT_SCREEN)
1763                         save_screen_shot(0);
1764
1765                 kc_drawquestion( item );
1766
1767 #ifdef SDL_INPUT
1768                 mouse_get_delta_z( &dx, &dy, &dz );
1769 #else
1770                 mouse_get_delta( &dx, &dy );
1771 #endif
1772                 if ( abs(dx)>20 ) code = 0;
1773                 if ( abs(dy)>20 ) code = 1;
1774 #ifdef SDL_INPUT
1775                 if ( abs(dz)>20 ) code = 2;
1776 #endif
1777         }
1778         if (code!=255)  {
1779                 for (i=0; i<Num_items; i++ )    {
1780                         n = item - All_items;
1781                         if ( (i!=n) && (All_items[i].type==BT_MOUSE_AXIS) && (All_items[i].value==code) )               {
1782                                 All_items[i].value = 255;
1783                                 kc_drawitem( &All_items[i], 0 );
1784                         }
1785                 }
1786                 item->value = code;
1787         }
1788         kc_drawitem( item, 1 );
1789         nm_restore_background( 0, LHY(INFO_Y), LHX(310), grd_curcanv->cv_font->ft_h );
1790         game_flush_inputs();
1791
1792 }
1793
1794
1795 void kc_change_invert( kc_item * item )
1796 {
1797         game_flush_inputs();
1798
1799         if (item->value)
1800                 item->value = 0;
1801         else 
1802                 item->value = 1;
1803
1804         kc_drawitem( item, 1 );
1805
1806 }
1807
1808 #include "screens.h"
1809
1810 void kconfig(int n, char * title)
1811 {
1812         int i, j;
1813         grs_bitmap *save_bm;
1814
1815         set_screen_mode( SCREEN_MENU );
1816
1817         kc_set_controls();
1818
1819         //save screen
1820         save_bm = gr_create_bitmap( grd_curcanv->cv_bitmap.bm_w, grd_curcanv->cv_bitmap.bm_h );
1821         Assert( save_bm != NULL );
1822         
1823         gr_bm_bitblt(grd_curcanv->cv_bitmap.bm_w, grd_curcanv->cv_bitmap.bm_w, 
1824                                         0, 0, 0, 0, &grd_curcanv->cv_bitmap, save_bm );
1825
1826         switch(n)       {
1827         case 0:kconfig_sub( kc_keyboard, NUM_KEY_CONTROLS, title );break;
1828         case 1:kconfig_sub( kc_joystick, NUM_OTHER_CONTROLS, title );break;
1829         case 2:kconfig_sub( kc_mouse, NUM_OTHER_CONTROLS, title ); break;
1830         case 3:kconfig_sub( kc_superjoy, NUM_OTHER_CONTROLS, title); break;
1831         case 4:kconfig_sub( kc_d2x, NUM_D2X_CONTROLS, title ); break;
1832         default:
1833                 Int3();
1834                 return;
1835         }
1836
1837         //restore screen
1838         gr_bitmap(0, 0, save_bm);
1839         gr_free_bitmap(save_bm);
1840
1841 #if 0 // set_screen_mode always calls this later... right?
1842         reset_cockpit();                //force cockpit redraw next time
1843 #endif
1844
1845         // Update save values...
1846         
1847         for (i=0; i<NUM_KEY_CONTROLS; i++ )     
1848                 kconfig_settings[0][i] = kc_keyboard[i].value;
1849
1850         for (j=0; j<256; j++)
1851                 if (key_binding(j)) {
1852                         for (i = 0; i < NUM_KEY_CONTROLS; i++)
1853                                 if (!stricmp(key_binding(j), kc_bind_text[i])) {
1854                                         cmd_appendf("unbind %s", key_text[j]);
1855                                         break;
1856                                 }
1857                         for (i = 0; i < NUM_D2X_CONTROLS; i++)
1858                                 if (kc_d2x[i].type == BT_KEY && !stricmp(key_binding(j), kc_d2x[i].text)) {
1859                                         cmd_appendf("unbind %s", key_text[j]);
1860                                         break;
1861                                 }
1862                 }
1863
1864         for (i=0; i<NUM_KEY_CONTROLS; i++ )
1865                 if (kc_keyboard[i].value != 255)
1866                         cmd_appendf("bind %s \"%s\"", key_text[kc_keyboard[i].value], kc_bind_text[i]);
1867
1868         for (i = 0; i < NUM_D2X_CONTROLS; i++)
1869                 if (kc_d2x[i].type == BT_KEY && kc_d2x[i].value != 255)
1870                         cmd_appendf("bind %s \"%s\"", key_text[kc_d2x[i].value], kc_d2x[i].text);
1871
1872         while (cmd_queue_process())
1873                 ;
1874
1875         if ( (Config_control_type>0) && (Config_control_type<5)) { 
1876                 for (i=0; i<NUM_OTHER_CONTROLS; i++ )   
1877                         kconfig_settings[Config_control_type][i] = kc_joystick[i].value;
1878         } else if (Config_control_type > 4) {
1879                 for (i=0; i<NUM_OTHER_CONTROLS; i++ )   
1880                         kconfig_settings[Config_control_type][i] = kc_mouse[i].value;
1881         }
1882 }
1883
1884
1885 void kconfig_read_fcs( int raw_axis )
1886 {
1887         int raw_button, button, axis_min[4], axis_center[4], axis_max[4];
1888
1889         if (Config_control_type!=CONTROL_THRUSTMASTER_FCS) return;
1890
1891         joy_get_cal_vals(axis_min, axis_center, axis_max);
1892
1893         if ( axis_max[3] > 1 )
1894                 raw_button = (raw_axis*100)/axis_max[3];
1895         else
1896                 raw_button = 0;
1897
1898         if ( raw_button > 88 )
1899                 button = 0;
1900         else if ( raw_button > 63 )
1901                 button = 7;
1902         else if ( raw_button > 39 )
1903                 button = 11;
1904         else if ( raw_button > 15 )
1905                 button = 15;
1906         else    
1907                 button = 19;
1908
1909         kconfig_set_fcs_button( 19, button );
1910         kconfig_set_fcs_button( 15, button );
1911         kconfig_set_fcs_button( 11, button );
1912         kconfig_set_fcs_button( 7, button );
1913 }
1914                 
1915
1916 void kconfig_set_fcs_button( int btn, int button )
1917 {
1918         int state,time_down,upcount,downcount;
1919         state = time_down = upcount = downcount = 0;
1920
1921         if ( joy_get_button_state(btn) ) {
1922                 if ( btn==button )      {
1923                         state = 1;
1924                         time_down = FrameTime;
1925                 } else {
1926                         upcount=1;
1927                 }
1928         } else {
1929                 if ( btn==button )      {
1930                         state = 1;
1931                         time_down = FrameTime;
1932                         downcount=1;
1933                 } else {
1934                         upcount=1;
1935                 }
1936         }                               
1937                         
1938         joy_set_btn_values( btn, state, time_down, downcount, upcount );
1939                                         
1940 }
1941
1942
1943
1944 fix Last_angles_p = 0;
1945 fix Last_angles_b = 0;
1946 fix Last_angles_h = 0;
1947 ubyte Last_angles_read = 0;
1948
1949 extern int                      VR_sensitivity;
1950                                                 
1951 int VR_sense_range[3] = { 25, 50, 75 };
1952
1953 #if 0 //ndef MACINTOSH
1954 read_head_tracker()
1955 {
1956         fix yaw, pitch, roll;
1957         int buttons;
1958
1959 //------ read vfx1 helmet --------
1960         if (vfx1_installed) {
1961                 vfx_get_data(&yaw,&pitch,&roll,&buttons);
1962         } else if (iglasses_headset_installed)  {
1963                 iglasses_read_headset( &yaw, &pitch, &roll );
1964         } else if (Victor_headset_installed)   {
1965                 victor_read_headset_filtered( &yaw, &pitch, &roll );
1966         } else {
1967                 return;
1968         }
1969
1970         Use_player_head_angles = 0;
1971         if ( Last_angles_read ) {
1972                 fix yaw1 = yaw;
1973                 
1974                 yaw1 = yaw;
1975                 if ( (Last_angles_h < (F1_0/4) ) && (yaw > ((F1_0*3)/4) ) )     
1976                         yaw1 -= F1_0;
1977                 else if ( (yaw < (F1_0/4) ) && (Last_angles_h > ((F1_0*3)/4) ) )        
1978                         yaw1 += F1_0;
1979         
1980                 Controls.pitch_time     += fixmul((pitch- Last_angles_p)*VR_sense_range[VR_sensitivity],FrameTime);
1981                 Controls.heading_time+= fixmul((yaw1 -  Last_angles_h)*VR_sense_range[VR_sensitivity],FrameTime);
1982                 Controls.bank_time      += fixmul((roll - Last_angles_b)*VR_sense_range[VR_sensitivity],FrameTime);
1983         }
1984         Last_angles_read = 1;
1985         Last_angles_p = pitch;
1986         Last_angles_h = yaw;
1987         Last_angles_b = roll;
1988 }
1989 #endif
1990
1991 #define PH_SCALE        8
1992
1993 #ifndef __MSDOS__
1994 #define JOYSTICK_READ_TIME      (F1_0/40)               //      Read joystick at 40 Hz.
1995 #else
1996 #define JOYSTICK_READ_TIME      (F1_0/10)               //      Read joystick at 10 Hz.
1997 #endif
1998
1999 fix     LastReadTime = 0;
2000
2001 fix     joy_axis[JOY_MAX_AXES];
2002
2003 ubyte                   kc_use_external_control = 0;
2004 ubyte                   kc_enable_external_control = 0;
2005 ubyte                   kc_external_intno = 0;
2006 ext_control_info        *kc_external_control = NULL;
2007 char                    *kc_external_name = NULL;
2008 ubyte                   kc_external_version = 0;
2009 extern int Automap_active;
2010
2011 void kconfig_init_external_controls(int intno, int address)
2012 {
2013         int i;
2014         kc_external_intno = intno;
2015         kc_external_control     = (ext_control_info *)address;
2016         kc_use_external_control = 1;
2017         kc_enable_external_control  = 1;
2018
2019         i = FindArg ( "-xname" );
2020         if ( i )        
2021                 kc_external_name = Args[i+1];
2022         else
2023                 kc_external_name = "External Controller";
2024
2025    for (i=0;i<strlen (kc_external_name);i++)
2026     if (kc_external_name[i]=='_')
2027           kc_external_name[i]=' '; 
2028
2029         i = FindArg ( "-xver" );
2030         if ( i )
2031                 kc_external_version = atoi(Args[i+1]);
2032         
2033         printf( "%s int: 0x%x, data: 0x%p, ver:%d\n", kc_external_name, kc_external_intno, kc_external_control, kc_external_version );
2034
2035 }
2036
2037 #if !defined(MACINTOSH)
2038 /*void kconfig_read_external_controls()
2039 {
2040         union REGS r;
2041
2042         if ( !kc_enable_external_control && !CybermouseActive) 
2043                 return;
2044
2045         if ( kc_external_version == 0 ) 
2046                 memset( kc_external_control, 0, sizeof(control_info) );
2047         else if ( kc_external_version > 0 )     {
2048                 memset( kc_external_control, 0, sizeof(control_info)+sizeof(vms_angvec) + 64 );
2049                 if ( kc_external_version > 1 ) {
2050                         // Write ship pos and angles to external controls...
2051                         ubyte *temp_ptr = (ubyte *)kc_external_control;
2052                         vms_vector *ship_pos;
2053                         vms_matrix *ship_orient;
2054                         memset( kc_external_control, 0, sizeof(control_info)+sizeof(vms_angvec) + 64 + sizeof(vms_vector)+sizeof(vms_matrix) );
2055                         temp_ptr += sizeof(control_info)+sizeof(vms_angvec) + 64;
2056                         ship_pos = (vms_vector *)temp_ptr;
2057                         temp_ptr += sizeof(vms_vector);
2058                         ship_orient = (vms_matrix *)temp_ptr;
2059                         // Fill in ship postion...
2060                         *ship_pos = Objects[Players[Player_num].objnum].pos;
2061                         // Fill in ship orientation...
2062                         *ship_orient = Objects[Players[Player_num].objnum].orient;
2063                 }
2064         }
2065
2066         if ( Automap_active )                    // (If in automap...)
2067                 kc_external_control->automap_state = 1;
2068         memset(&r,0,sizeof(r));
2069
2070    if (!CybermouseActive)
2071         int386 ( kc_external_intno, &r, &r);            // Read external info...
2072 //      else
2073   //            ReadOWL (kc_external_control);
2074
2075         if ( Player_num > -1 )  {
2076                 Objects[Players[Player_num].objnum].mtype.phys_info.flags &= (~PF_TURNROLL);    // Turn off roll when turning
2077                 Objects[Players[Player_num].objnum].mtype.phys_info.flags &= (~PF_LEVELLING);   // Turn off leveling to nearest side.
2078                 Auto_leveling_on = 0;
2079
2080                 if ( kc_external_version > 0 ) {                
2081                         vms_matrix tempm, ViewMatrix;
2082                         vms_angvec * Kconfig_abs_movement;
2083                         char * oem_message;
2084         
2085                         Kconfig_abs_movement = (vms_angvec *)((uint)kc_external_control + sizeof(control_info));
2086         
2087                         if ( Kconfig_abs_movement->p || Kconfig_abs_movement->b || Kconfig_abs_movement->h )    {
2088                                 vm_angles_2_matrix(&tempm,Kconfig_abs_movement);
2089                                 vm_matrix_x_matrix(&ViewMatrix,&Objects[Players[Player_num].objnum].orient,&tempm);
2090                                 Objects[Players[Player_num].objnum].orient = ViewMatrix;                
2091                         }
2092                         oem_message = (char *)((uint)Kconfig_abs_movement + sizeof(vms_angvec));
2093                         if (oem_message[0] != '\0' )
2094                                 HUD_init_message( oem_message );
2095                 }
2096         }
2097
2098         Controls.pitch_time += fixmul(kc_external_control->pitch_time,FrameTime);                                               
2099         Controls.vertical_thrust_time += fixmul(kc_external_control->vertical_thrust_time,FrameTime);
2100         Controls.heading_time += fixmul(kc_external_control->heading_time,FrameTime);
2101         Controls.sideways_thrust_time += fixmul(kc_external_control->sideways_thrust_time ,FrameTime);
2102         Controls.bank_time += fixmul(kc_external_control->bank_time ,FrameTime);
2103         Controls.forward_thrust_time += fixmul(kc_external_control->forward_thrust_time ,FrameTime);
2104         Controls.rear_view_down_count += kc_external_control->rear_view_down_count;     
2105         Controls.rear_view_down_state |= kc_external_control->rear_view_down_state;     
2106         Controls.fire_primary_down_count += kc_external_control->fire_primary_down_count;
2107         Controls.fire_primary_state |= kc_external_control->fire_primary_state;
2108         Controls.fire_secondary_state |= kc_external_control->fire_secondary_state;
2109         Controls.fire_secondary_down_count += kc_external_control->fire_secondary_down_count;
2110         Controls.fire_flare_down_count += kc_external_control->fire_flare_down_count;
2111         Controls.drop_bomb_down_count += kc_external_control->drop_bomb_down_count;     
2112         Controls.automap_down_count += kc_external_control->automap_down_count;
2113         Controls.automap_state |= kc_external_control->automap_state;
2114 } */
2115 #endif
2116
2117
2118 fix Next_toggle_time[3]={0,0,0};
2119
2120 int allowed_to_toggle(int i)
2121 {
2122   //used for keeping tabs of when its ok to toggle headlight,primary,and secondary
2123  
2124         if (Next_toggle_time[i] > GameTime)
2125                 if (Next_toggle_time[i] < GameTime + (F1_0/8))  //      In case time is bogus, never wait > 1 second.
2126                         return 0;
2127
2128         Next_toggle_time[i] = GameTime + (F1_0/8);
2129
2130         return 1;
2131 }
2132
2133
2134 void controls_read_all()
2135 {
2136         int i;
2137         int slide_on, bank_on;
2138         int dx, dy;
2139 #ifdef SDL_INPUT
2140         int dz;
2141 #endif
2142         int idx, idy;
2143         fix ctime;
2144         fix mouse_axis[3] = {0,0,0};
2145         int raw_joy_axis[JOY_MAX_AXES];
2146         int mouse_buttons;
2147         fix kp, kh;
2148         ubyte channel_masks;
2149         int use_mouse, use_joystick;
2150
2151         mouse_buttons=0;
2152         use_mouse=0;
2153
2154         {
2155                 fix temp = Controls.heading_time;
2156                 fix temp1 = Controls.pitch_time;
2157                 memset( &Controls, 0, sizeof(control_info) );
2158                 Controls.heading_time = temp;
2159                 Controls.pitch_time = temp1;
2160         }
2161         slide_on = 0;
2162         bank_on = 0;
2163
2164         ctime = timer_get_fixed_seconds();
2165
2166         //---------  Read Joystick -----------
2167 #ifndef MACINTOSH
2168         if ( (LastReadTime + JOYSTICK_READ_TIME > ctime) && (Config_control_type!=CONTROL_THRUSTMASTER_FCS) ) {
2169 # ifndef __MSDOS__
2170                 if ((ctime < 0) && (LastReadTime >= 0))
2171 # else
2172                 if ((ctime < 0) && (LastReadTime > 0))
2173 # endif
2174                         LastReadTime = ctime;
2175                 use_joystick=1;
2176         } else if ((Config_control_type>0) && (Config_control_type<5) ) {
2177                 LastReadTime = ctime;
2178                 channel_masks = joystick_read_raw_axis( JOY_ALL_AXIS, raw_joy_axis );
2179
2180                 for (i = 0; i < joy_num_axes; i++)
2181                 {
2182 #ifndef SDL_INPUT
2183                         if (channel_masks&(1<<i))       {
2184 #endif
2185                                 int joy_null_value = 10;
2186
2187                                 if ( (i==3) && (Config_control_type==CONTROL_THRUSTMASTER_FCS) )        {
2188                                         kconfig_read_fcs( raw_joy_axis[i] );
2189                                 } else {
2190                                         raw_joy_axis[i] = joy_get_scaled_reading( raw_joy_axis[i], i );
2191         
2192                                         if (kc_joystick[23].value==i)           // If this is the throttle
2193                                                 joy_null_value = 20;            // Then use a larger dead-zone
2194         
2195                                         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 if (raw_joy_axis[i] < -joy_null_value)
2198                                           raw_joy_axis[i] = ((raw_joy_axis[i]+joy_null_value)*128)/(128-joy_null_value);
2199                                         else
2200                                           raw_joy_axis[i] = 0;
2201                                         joy_axis[i]     = (raw_joy_axis[i]*FrameTime)/128;      
2202                                 }
2203 #ifndef SDL_INPUT
2204                         } else {
2205                                 joy_axis[i] = 0;
2206                         }
2207 #endif
2208                 }       
2209                 use_joystick=1;
2210         } else {
2211                 for (i = 0; i < joy_num_axes; i++)
2212                         joy_axis[i] = 0;
2213                 use_joystick=0;
2214         }
2215 #else   // MACINTOSH
2216         //---------  Read Joystick -----------
2217         if ((Config_control_type>0) && (Config_control_type<5) ) {
2218                 channel_masks = joystick_read_raw_axis( JOY_ALL_AXIS, raw_joy_axis );
2219                 for (i=0; i<4; i++ )    {
2220                         if (channel_masks&(1<<i))       {
2221                                 int joy_null_value = 10;
2222
2223                                 raw_joy_axis[i] = joy_get_scaled_reading( raw_joy_axis[i], i );
2224
2225                                 if (kc_joystick[23].value==i)           // If this is the throttle
2226                                         joy_null_value = 20;                            // Then use a larger dead-zone
2227
2228                                 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 if (raw_joy_axis[i] < -joy_null_value)
2231                                         raw_joy_axis[i] = ((raw_joy_axis[i]+joy_null_value)*128)/(128-joy_null_value);
2232                                 else
2233                                         raw_joy_axis[i] = 0;
2234                                 joy_axis[i]     = (raw_joy_axis[i]*FrameTime)/128;      
2235                         } else {
2236                                 joy_axis[i] = 0;
2237                         }
2238                 }       
2239                 use_joystick=1;
2240         } else {
2241                 for (i=0; i<4; i++ )
2242                         joy_axis[i] = 0;
2243                 use_joystick=0;
2244         }
2245 #endif          // ifndef MACINTOSH
2246
2247         if (Config_control_type==5 && !CybermouseActive) {
2248                 //---------  Read Mouse -----------
2249 #ifdef SDL_INPUT
2250                 mouse_get_delta_z( &dx, &dy, &dz );
2251 #else
2252                 mouse_get_delta( &dx, &dy );
2253 #endif
2254                 mouse_axis[0] = (dx*FrameTime)/35;
2255                 mouse_axis[1] = (dy*FrameTime)/25;
2256 #ifdef SDL_INPUT
2257                 mouse_axis[2] = (dz*FrameTime);
2258 #endif
2259                 mouse_buttons = mouse_get_btns();
2260                 //mprintf(( 0, "Mouse %d,%d b:%d, 0x%x\n", mouse_axis[0], mouse_axis[1], mouse_buttons, FrameTime ));
2261                 use_mouse=1;
2262         } else if (Config_control_type==6 && !CybermouseActive) {
2263                 //---------  Read Cyberman -----------
2264                 mouse_get_cyberman_pos(&idx,&idy );
2265                 mouse_axis[0] = (idx*FrameTime)/128;
2266                 mouse_axis[1] = (idy*FrameTime)/128;
2267                 mouse_buttons = mouse_get_btns();
2268                 use_mouse=1;
2269         } else if (CybermouseActive) {
2270 //              ReadOWL (kc_external_control);
2271 //              CybermouseAdjust();
2272         } else {
2273                 mouse_axis[0] = 0;
2274                 mouse_axis[1] = 0;
2275                 mouse_buttons = 0;
2276                 use_mouse=0;
2277         }
2278
2279 //------------- Read slide_on -------------
2280         
2281         // From console...
2282         slide_on |= console_control_state(CONCNTL_STRAFE);
2283
2284         // From joystick...
2285         if ((use_joystick)&&(kc_joystick[5].value<255)) slide_on |= joy_get_button_state( kc_joystick[5].value );
2286         // From mouse...
2287         if ((use_mouse)&&(kc_mouse[5].value<255)) slide_on |= mouse_buttons & (1<<kc_mouse[5].value);
2288
2289 //------------- Read bank_on ---------------
2290
2291         // From console...
2292         bank_on |= console_control_state(CONCNTL_BANK);
2293
2294         // From joystick...
2295         if ( (use_joystick)&&(kc_joystick[10].value < 255 )) bank_on |= joy_get_button_state( kc_joystick[10].value );
2296         // From mouse...
2297         if ( (use_mouse)&&(kc_mouse[10].value < 255 )) bank_on |= mouse_buttons & (1<<kc_mouse[10].value);
2298
2299 //------------ Read pitch_time -----------
2300         if ( !slide_on )        {
2301                 // mprintf((0, "pitch: %7.3f %7.3f: %7.3f\n", f2fl(k4), f2fl(k6), f2fl(Controls.heading_time)));
2302                 kp = 0;
2303
2304                 // From console...
2305                 kp += console_control_down_time(CONCNTL_LOOKDOWN) / (PH_SCALE * 2);
2306                 kp -= console_control_down_time(CONCNTL_LOOKUP) / (PH_SCALE * 2);
2307
2308                 // From Cyberman...
2309                 if ((use_mouse)&&(Config_control_type==CONTROL_CYBERMAN))       {
2310                         kp += mouse_button_down_time(MB_PITCH_FORWARD)/(PH_SCALE*2);
2311                         kp -= mouse_button_down_time(MB_PITCH_BACKWARD)/(PH_SCALE*2);
2312                 }
2313         
2314                 if (kp == 0)
2315                         Controls.pitch_time = 0;
2316                 else if (kp > 0) {
2317                         if (Controls.pitch_time < 0)
2318                                 Controls.pitch_time = 0;
2319                 } else // kp < 0
2320                         if (Controls.pitch_time > 0)
2321                                 Controls.pitch_time = 0;
2322                 Controls.pitch_time += kp;
2323         
2324                 // From joystick...
2325                 if ( (use_joystick)&&(kc_joystick[13].value < 255 ))    {
2326                         if ( !kc_joystick[14].value )           // If not inverted...
2327                                 Controls.pitch_time -= (joy_axis[kc_joystick[13].value]*Config_joystick_sensitivity)/8;
2328                         else
2329                                 Controls.pitch_time += (joy_axis[kc_joystick[13].value]*Config_joystick_sensitivity)/8;
2330                 }
2331         
2332                 // From mouse...
2333                 //mprintf(( 0, "UM: %d, PV: %d\n", use_mouse, kc_mouse[13].value ));
2334                 if ( (use_mouse)&&(kc_mouse[13].value < 255) )  {
2335                         if ( !kc_mouse[14].value )              // If not inverted...
2336                                 Controls.pitch_time -= (mouse_axis[kc_mouse[13].value]*Config_joystick_sensitivity)/8;
2337                         else
2338                                 Controls.pitch_time += (mouse_axis[kc_mouse[13].value]*Config_joystick_sensitivity)/8;
2339                 }
2340         } else {
2341                 Controls.pitch_time = 0;
2342         }
2343
2344
2345 // the following "if" added by WraithX, 4/14/00
2346 // done so that dead players can't move
2347 if (!Player_is_dead)
2348 {
2349 //----------- Read vertical_thrust_time -----------------
2350
2351         if ( slide_on ) {
2352                 // From console...
2353                 Controls.vertical_thrust_time += console_control_down_time(CONCNTL_LOOKDOWN);
2354                 Controls.vertical_thrust_time -= console_control_down_time(CONCNTL_LOOKUP);
2355
2356                 // From Cyberman...
2357                 if ((use_mouse)&&(Config_control_type==CONTROL_CYBERMAN))       {
2358                         Controls.vertical_thrust_time -= mouse_button_down_time(MB_PITCH_FORWARD);
2359                         Controls.vertical_thrust_time += mouse_button_down_time(MB_PITCH_BACKWARD);
2360                 }
2361         
2362                 // From joystick...
2363                 if ((use_joystick)&&( kc_joystick[13].value < 255 ))    {
2364                         if ( !kc_joystick[14].value )           // If not inverted...
2365                                 Controls.vertical_thrust_time += joy_axis[kc_joystick[13].value];
2366                         else
2367                                 Controls.vertical_thrust_time -= joy_axis[kc_joystick[13].value];
2368                 }
2369         
2370                 // From mouse...
2371                 if ( (use_mouse)&&(kc_mouse[13].value < 255 ))  {
2372                         if ( !kc_mouse[14].value )              // If not inverted...
2373                                 Controls.vertical_thrust_time -= mouse_axis[kc_mouse[13].value];
2374                         else
2375                                 Controls.vertical_thrust_time += mouse_axis[kc_mouse[13].value];
2376                 }
2377         }
2378
2379         // From console...
2380         Controls.vertical_thrust_time += console_control_down_time(CONCNTL_MOVEUP);
2381         Controls.vertical_thrust_time -= console_control_down_time(CONCNTL_MOVEDOWN);
2382
2383         // From joystick...
2384         if ((use_joystick)&&( kc_joystick[19].value < 255 ))    {
2385                 if ( !kc_joystick[20].value )           // If not inverted...
2386                         Controls.vertical_thrust_time += joy_axis[kc_joystick[19].value];
2387                 else
2388                         Controls.vertical_thrust_time -= joy_axis[kc_joystick[19].value];
2389         }
2390
2391         // From joystick buttons
2392         if ( (use_joystick)&&(kc_joystick[8].value < 255 )) Controls.vertical_thrust_time += joy_get_button_down_time( kc_joystick[8].value );
2393         if ( (use_joystick)&&(kc_joystick[9].value < 255 )) Controls.vertical_thrust_time -= joy_get_button_down_time( kc_joystick[9].value );
2394
2395         // From mouse buttons
2396         if ( (use_mouse)&&(kc_mouse[8].value < 255 )) Controls.vertical_thrust_time += mouse_button_down_time( kc_mouse[8].value );
2397         if ( (use_mouse)&&(kc_mouse[9].value < 255 )) Controls.vertical_thrust_time -= mouse_button_down_time( kc_mouse[9].value );
2398
2399         // From mouse...
2400         if ( (use_mouse)&&(kc_mouse[19].value < 255 ))  {
2401                 if ( !kc_mouse[20].value )              // If not inverted...
2402                         Controls.vertical_thrust_time += mouse_axis[kc_mouse[19].value];
2403                 else
2404                         Controls.vertical_thrust_time -= mouse_axis[kc_mouse[19].value];
2405         }
2406
2407         // From Cyberman...
2408         if ((use_mouse)&&(Config_control_type==CONTROL_CYBERMAN))       {
2409                 Controls.vertical_thrust_time += mouse_button_down_time(MB_Z_UP)/2;
2410                 Controls.vertical_thrust_time -= mouse_button_down_time(MB_Z_DOWN)/2;
2411         }
2412 }// end "if" added by WraithX
2413
2414 //---------- Read heading_time -----------
2415
2416         if (!slide_on && !bank_on)      {
2417                 //mprintf((0, "heading: %7.3f %7.3f: %7.3f\n", f2fl(k4), f2fl(k6), f2fl(Controls.heading_time)));
2418                 kh = 0;
2419
2420                 // From console...
2421                 kh -= console_control_down_time(CONCNTL_LEFT) / PH_SCALE;
2422                 kh += console_control_down_time(CONCNTL_RIGHT) / PH_SCALE;
2423
2424                 // From Cyberman...
2425                 if ((use_mouse)&&(Config_control_type==CONTROL_CYBERMAN))       {
2426                         kh -= mouse_button_down_time(MB_HEAD_LEFT)/PH_SCALE;
2427                         kh += mouse_button_down_time(MB_HEAD_RIGHT)/PH_SCALE;
2428                 }
2429         
2430                 if (kh == 0)
2431                         Controls.heading_time = 0;
2432                 else if (kh > 0) {
2433                         if (Controls.heading_time < 0)
2434                                 Controls.heading_time = 0;
2435                 } else // kh < 0
2436                         if (Controls.heading_time > 0)
2437                                 Controls.heading_time = 0;
2438                 Controls.heading_time += kh;
2439
2440                 // From joystick...
2441                 if ( (use_joystick)&&(kc_joystick[15].value < 255 ))    {
2442                         if ( !kc_joystick[16].value )           // If not inverted...
2443                                 Controls.heading_time += (joy_axis[kc_joystick[15].value]*Config_joystick_sensitivity)/8;
2444                         else
2445                                 Controls.heading_time -= (joy_axis[kc_joystick[15].value]*Config_joystick_sensitivity)/8;
2446                 }
2447         
2448                 // From mouse...
2449                 if ( (use_mouse)&&(kc_mouse[15].value < 255 ))  {
2450                         if ( !kc_mouse[16].value )              // If not inverted...
2451                                 Controls.heading_time += (mouse_axis[kc_mouse[15].value]*Config_joystick_sensitivity)/8;
2452                         else
2453                                 Controls.heading_time -= (mouse_axis[kc_mouse[15].value]*Config_joystick_sensitivity)/8;
2454                 }
2455         } else {
2456                 Controls.heading_time = 0;
2457         }
2458
2459 // the following "if" added by WraithX, 4/14/00
2460 // done so that dead players can't move
2461 if (!Player_is_dead)
2462 {
2463 //----------- Read sideways_thrust_time -----------------
2464
2465         if ( slide_on ) {
2466                 // From console...
2467                 Controls.sideways_thrust_time -= console_control_down_time(CONCNTL_LEFT);
2468                 Controls.sideways_thrust_time += console_control_down_time(CONCNTL_RIGHT);
2469
2470                 // From joystick...
2471                 if ( (use_joystick)&&(kc_joystick[15].value < 255 ))    {
2472                         if ( !kc_joystick[16].value )           // If not inverted...
2473                                 Controls.sideways_thrust_time += joy_axis[kc_joystick[15].value];
2474                         else
2475                                 Controls.sideways_thrust_time -= joy_axis[kc_joystick[15].value];
2476                 }
2477                 
2478                 // From cyberman
2479                 if ((use_mouse)&&(Config_control_type==CONTROL_CYBERMAN))       {
2480                         Controls.sideways_thrust_time -= mouse_button_down_time(MB_HEAD_LEFT);
2481                         Controls.sideways_thrust_time += mouse_button_down_time(MB_HEAD_RIGHT);
2482                 }
2483         
2484                 // From mouse...
2485                 if ( (use_mouse)&&(kc_mouse[15].value < 255 ))  {
2486                         if ( !kc_mouse[16].value )              // If not inverted...
2487                                 Controls.sideways_thrust_time += mouse_axis[kc_mouse[15].value];
2488                         else
2489                                 Controls.sideways_thrust_time -= mouse_axis[kc_mouse[15].value];
2490                 }
2491         }
2492
2493         // From console...
2494         Controls.sideways_thrust_time -= console_control_down_time(CONCNTL_MOVELEFT);
2495         Controls.sideways_thrust_time += console_control_down_time(CONCNTL_MOVERIGHT);
2496
2497         // From joystick...
2498         if ( (use_joystick)&&(kc_joystick[17].value < 255 ))    {
2499                 if ( !kc_joystick[18].value )           // If not inverted...
2500                         Controls.sideways_thrust_time -= joy_axis[kc_joystick[17].value];
2501                 else
2502                         Controls.sideways_thrust_time += joy_axis[kc_joystick[17].value];
2503         }
2504
2505         // From joystick buttons
2506         if ( (use_joystick)&&(kc_joystick[6].value < 255 )) Controls.sideways_thrust_time -= joy_get_button_down_time( kc_joystick[6].value );
2507         if ( (use_joystick)&&(kc_joystick[7].value < 255 )) Controls.sideways_thrust_time += joy_get_button_down_time( kc_joystick[7].value );
2508
2509         // From mouse buttons
2510         if ( (use_mouse)&&(kc_mouse[6].value < 255 )) Controls.sideways_thrust_time -= mouse_button_down_time( kc_mouse[6].value );
2511         if ( (use_mouse)&&(kc_mouse[7].value < 255 )) Controls.sideways_thrust_time += mouse_button_down_time( kc_mouse[7].value );
2512
2513         // From mouse...
2514         if ( (use_mouse)&&(kc_mouse[17].value < 255 ))  {
2515                 if ( !kc_mouse[18].value )              // If not inverted...
2516                         Controls.sideways_thrust_time += mouse_axis[kc_mouse[17].value];
2517                 else
2518                         Controls.sideways_thrust_time -= mouse_axis[kc_mouse[17].value];
2519         }
2520 }// end "if" added by WraithX
2521
2522 //----------- Read bank_time -----------------
2523
2524         if ( bank_on )  {
2525                 // From console...
2526                 Controls.bank_time -= console_control_down_time(CONCNTL_LEFT);
2527                 Controls.bank_time += console_control_down_time(CONCNTL_RIGHT);
2528
2529                 // From Cyberman...
2530                 if ((use_mouse)&&(Config_control_type==CONTROL_CYBERMAN))       {
2531                         Controls.bank_time -= mouse_button_down_time(MB_HEAD_LEFT);
2532                         Controls.bank_time += mouse_button_down_time(MB_HEAD_RIGHT);
2533                 }
2534
2535                 // From joystick...
2536                 if ( (use_joystick)&&(kc_joystick[15].value < 255) )    {
2537                         if ( !kc_joystick[16].value )           // If not inverted...
2538                                 Controls.bank_time -= (joy_axis[kc_joystick[15].value]*Config_joystick_sensitivity)/8;
2539                         else
2540                                 Controls.bank_time += (joy_axis[kc_joystick[15].value]*Config_joystick_sensitivity)/8;
2541                 }
2542         
2543                 // From mouse...
2544                 if ( (use_mouse)&&(kc_mouse[15].value < 255 ))  {
2545                         if ( !kc_mouse[16].value )              // If not inverted...
2546                                 Controls.bank_time += (mouse_axis[kc_mouse[15].value]*Config_joystick_sensitivity)/8;
2547                         else
2548                                 Controls.bank_time -= (mouse_axis[kc_mouse[15].value]*Config_joystick_sensitivity)/8;
2549                 }
2550         }
2551
2552         // From console...
2553         Controls.bank_time += console_control_down_time(CONCNTL_BANKLEFT);
2554         Controls.bank_time -= console_control_down_time(CONCNTL_BANKRIGHT);
2555
2556         // From joystick...
2557         if ( (use_joystick)&&(kc_joystick[21].value < 255) )    {
2558                 if ( !kc_joystick[22].value )           // If not inverted...
2559                         Controls.bank_time -= joy_axis[kc_joystick[21].value];
2560                 else
2561                         Controls.bank_time += joy_axis[kc_joystick[21].value];
2562         }
2563
2564         // From joystick buttons
2565         if ( (use_joystick)&&(kc_joystick[11].value < 255 )) Controls.bank_time += joy_get_button_down_time( kc_joystick[11].value );
2566         if ( (use_joystick)&&(kc_joystick[12].value < 255 )) Controls.bank_time -= joy_get_button_down_time( kc_joystick[12].value );
2567
2568         // From mouse buttons
2569         if ( (use_mouse)&&(kc_mouse[11].value < 255 )) Controls.bank_time += mouse_button_down_time( kc_mouse[11].value );
2570         if ( (use_mouse)&&(kc_mouse[12].value < 255 )) Controls.bank_time -= mouse_button_down_time( kc_mouse[12].value );
2571
2572         // From mouse...
2573         if ( (use_mouse)&&(kc_mouse[21].value < 255 ))  {
2574                 if ( !kc_mouse[22].value )              // If not inverted...
2575                         Controls.bank_time += mouse_axis[kc_mouse[21].value];
2576                 else
2577                         Controls.bank_time -= mouse_axis[kc_mouse[21].value];
2578         }
2579
2580         // From Cyberman
2581         if ((use_mouse)&&(Config_control_type==CONTROL_CYBERMAN))       {
2582                 Controls.bank_time += mouse_button_down_time(MB_BANK_LEFT);
2583                 Controls.bank_time -= mouse_button_down_time(MB_BANK_RIGHT);
2584         }
2585
2586 // the following "if" added by WraithX, 4/14/00
2587 // done so that dead players can't move
2588 if (!Player_is_dead)
2589 {
2590 //----------- Read forward_thrust_time -------------
2591
2592         // From console...
2593         Controls.forward_thrust_time += console_control_down_time(CONCNTL_FORWARD);
2594         Controls.forward_thrust_time -= console_control_down_time(CONCNTL_BACK);
2595
2596         // From joystick...
2597         if ( (use_joystick)&&(kc_joystick[23].value < 255 ))    {
2598                 if ( !kc_joystick[24].value )           // If not inverted...
2599                         Controls.forward_thrust_time -= joy_axis[kc_joystick[23].value];
2600                 else
2601                         Controls.forward_thrust_time += joy_axis[kc_joystick[23].value];
2602         }
2603
2604         // From joystick buttons
2605         if ( (use_joystick)&&(kc_joystick[2].value < 255 )) Controls.forward_thrust_time += joy_get_button_down_time( kc_joystick[2].value );
2606         if ( (use_joystick)&&(kc_joystick[3].value < 255 )) Controls.forward_thrust_time -= joy_get_button_down_time( kc_joystick[3].value );
2607
2608         // From mouse...
2609         if ( (use_mouse)&&(kc_mouse[23].value < 255 ))  {
2610                 if ( !kc_mouse[24].value )              // If not inverted...
2611                         Controls.forward_thrust_time -= mouse_axis[kc_mouse[23].value];
2612                 else
2613                         Controls.forward_thrust_time += mouse_axis[kc_mouse[23].value];
2614         }
2615
2616         // From mouse buttons
2617         if ( (use_mouse)&&(kc_mouse[2].value < 255 )) Controls.forward_thrust_time += mouse_button_down_time( kc_mouse[2].value );
2618         if ( (use_mouse)&&(kc_mouse[3].value < 255 )) Controls.forward_thrust_time -= mouse_button_down_time( kc_mouse[3].value );
2619
2620 //----------- Read afterburner_state -------------
2621
2622         // From console...
2623         Controls.afterburner_state |= console_control_state(CONCNTL_LEFT);
2624
2625         if ( (use_mouse)&&(kc_mouse[27].value < 255 )) Controls.afterburner_state |= mouse_button_state(kc_mouse[27].value);
2626
2627         if ( (use_joystick)&&(kc_joystick[27].value < 255 )) Controls.afterburner_state |= joy_get_button_state(kc_joystick[27].value);
2628
2629 //-------Read headlight key--------------------------
2630
2631         // From console...
2632         Controls.headlight_count += console_control_down_count(CONCNTL_HEADLIGHT);
2633
2634                   if ((use_joystick)&&(kc_joystick[30].value < 255 )) 
2635                Controls.headlight_count+=joy_get_button_down_cnt(kc_joystick[30].value);
2636
2637 //--------Read Cycle Primary Key------------------
2638
2639         // From console...
2640         Controls.cycle_primary_count += console_control_down_count(CONCNTL_CYCLE);
2641
2642              if ((use_joystick)&&(kc_joystick[28].value < 255 )) 
2643          Controls.cycle_primary_count+=joy_get_button_down_cnt(kc_joystick[28].value);
2644
2645
2646 //--------Read Cycle Secondary Key------------------
2647
2648         // From console...
2649         Controls.cycle_secondary_count += console_control_down_count(CONCNTL_CYCLE2);
2650
2651              if ((use_joystick)&&(kc_joystick[29].value < 255 )) 
2652                         Controls.cycle_secondary_count=joy_get_button_down_cnt(kc_joystick[29].value);
2653
2654 //--------Read Toggle Bomb key----------------------
2655
2656         // From console...
2657         if (console_control_down_count(CONCNTL_TOGGLEBOMB))
2658          {
2659           int bomb = Secondary_last_was_super[PROXIMITY_INDEX]?PROXIMITY_INDEX:SMART_MINE_INDEX;
2660
2661                          if (!Players[Player_num].secondary_ammo[PROXIMITY_INDEX] &&
2662                                   !Players[Player_num].secondary_ammo[SMART_MINE_INDEX])
2663                            {
2664                                  digi_play_sample_once( SOUND_BAD_SELECTION, F1_0 );
2665                                  HUD_init_message ("No bombs available!");
2666                                 }
2667                          else
2668                                 {       
2669                                  if (Players[Player_num].secondary_ammo[bomb]==0)
2670                                         {
2671                                          digi_play_sample_once( SOUND_BAD_SELECTION, F1_0 );
2672                                          HUD_init_message ("No %s available!",(bomb==SMART_MINE_INDEX)?"Smart mines":"Proximity bombs");
2673                                         }
2674                                   else
2675                                         {
2676                                Secondary_last_was_super[PROXIMITY_INDEX]=!Secondary_last_was_super[PROXIMITY_INDEX];
2677                                          digi_play_sample_once( SOUND_GOOD_SELECTION_SECONDARY, F1_0 );
2678                                         }
2679                                 }
2680                         }
2681           
2682 //---------Read Energy->Shield key----------
2683
2684         // From console...
2685         if ((Players[Player_num].flags & PLAYER_FLAGS_CONVERTER) && console_control_state(CONCNTL_NRGSHIELD))
2686                 transfer_energy_to_shield(console_control_down_time(CONCNTL_NRGSHIELD));
2687
2688 //----------- Read fire_primary_down_count
2689
2690         // From console...
2691         Controls.fire_primary_down_count += console_control_down_count(CONCNTL_ATTACK);
2692
2693         if ((use_joystick)&&(kc_joystick[0].value < 255 )) Controls.fire_primary_down_count += joy_get_button_down_cnt(kc_joystick[0].value);
2694         if ((use_mouse)&&(kc_mouse[0].value < 255 )) Controls.fire_primary_down_count += mouse_button_down_count(kc_mouse[0].value);
2695
2696 //----------- Read fire_primary_state
2697
2698         // From console...
2699         Controls.fire_primary_state |= console_control_state(CONCNTL_ATTACK);
2700
2701         if ((use_joystick)&&(kc_joystick[0].value < 255 )) Controls.fire_primary_state |= joy_get_button_state(kc_joystick[0].value);
2702         if ((use_mouse)&&(kc_mouse[0].value < 255) ) Controls.fire_primary_state |= mouse_button_state(kc_mouse[0].value);
2703
2704 //----------- Read fire_secondary_down_count
2705
2706         // From console...
2707         Controls.fire_secondary_down_count += console_control_down_count(CONCNTL_ATTACK2);
2708
2709         if ((use_joystick)&&(kc_joystick[1].value < 255 )) Controls.fire_secondary_down_count += joy_get_button_down_cnt(kc_joystick[1].value);
2710         if ((use_mouse)&&(kc_mouse[1].value < 255 )) Controls.fire_secondary_down_count += mouse_button_down_count(kc_mouse[1].value);
2711
2712 //----------- Read fire_secondary_state
2713
2714         // From console...
2715         Controls.fire_secondary_state |= console_control_state(CONCNTL_ATTACK2);
2716
2717         if ((use_joystick)&&(kc_joystick[1].value < 255 )) Controls.fire_secondary_state |= joy_get_button_state(kc_joystick[1].value);
2718         if ((use_mouse)&&(kc_mouse[1].value < 255) ) Controls.fire_secondary_state |= mouse_button_state(kc_mouse[1].value);
2719
2720 //----------- Read fire_flare_down_count
2721
2722         // From console...
2723         Controls.fire_flare_down_count += console_control_down_count(CONCNTL_FLARE);
2724
2725         if ((use_joystick)&&(kc_joystick[4].value < 255 )) Controls.fire_flare_down_count += joy_get_button_down_cnt(kc_joystick[4].value);
2726         if ((use_mouse)&&(kc_mouse[4].value < 255 )) Controls.fire_flare_down_count += mouse_button_down_count(kc_mouse[4].value);
2727
2728 //----------- Read drop_bomb_down_count
2729
2730         // From console...
2731         Controls.drop_bomb_down_count += console_control_down_count(CONCNTL_BOMB);
2732
2733         if ((use_joystick)&&(kc_joystick[26].value < 255 )) Controls.drop_bomb_down_count += joy_get_button_down_cnt(kc_joystick[26].value);
2734         if ((use_mouse)&&(kc_mouse[26].value < 255 )) Controls.drop_bomb_down_count += mouse_button_down_count(kc_mouse[26].value);
2735
2736 //----------- Read rear_view_down_count
2737
2738         // From console...
2739         Controls.rear_view_down_count += console_control_down_count(CONCNTL_REARVIEW);
2740
2741         if ((use_joystick)&&(kc_joystick[25].value < 255 )) Controls.rear_view_down_count += joy_get_button_down_cnt(kc_joystick[25].value);
2742         if ((use_mouse)&&(kc_mouse[25].value < 255 )) Controls.rear_view_down_count += mouse_button_down_count(kc_mouse[25].value);
2743
2744 //----------- Read rear_view_down_state
2745
2746         // From console...
2747         Controls.rear_view_down_state |= console_control_state(CONCNTL_REARVIEW);
2748
2749         if ((use_joystick)&&(kc_joystick[25].value < 255 )) Controls.rear_view_down_state |= joy_get_button_state(kc_joystick[25].value);
2750         if ((use_mouse)&&(kc_mouse[25].value < 255 )) Controls.rear_view_down_state |= mouse_button_state(kc_mouse[25].value);
2751
2752 }//end "if" added by WraithX
2753
2754 //----------- Read automap_down_count
2755
2756         // From console...
2757         Controls.automap_down_count += console_control_down_count(CONCNTL_AUTOMAP);
2758
2759 //----------- Read automap_state
2760
2761         // From console...
2762         Controls.automap_state |= console_control_state(CONCNTL_AUTOMAP);
2763
2764 //----------- Read stupid-cruise-control-type of throttle.
2765         {
2766                 // From console...
2767                 Cruise_speed += console_control_down_time(CONCNTL_CRUISEUP);
2768                 Cruise_speed -= console_control_down_time(CONCNTL_CRUISEDOWN);
2769
2770                 // From console...
2771                 if (console_control_down_count(CONCNTL_CRUISEOFF))
2772                         Cruise_speed = 0;
2773
2774                 if (Cruise_speed > i2f(100) ) Cruise_speed = i2f(100);
2775                 if (Cruise_speed < 0 ) Cruise_speed = 0;
2776         
2777                 if (Controls.forward_thrust_time==0)
2778                         Controls.forward_thrust_time = fixmul(Cruise_speed,FrameTime)/100;
2779         }
2780
2781 #if !defined(MACINTOSH)
2782         //read_head_tracker();
2783
2784         // Read external controls
2785         // if (kc_use_external_control || CybermouseActive)
2786         //      kconfig_read_external_controls();
2787 #endif
2788
2789 //----------- Clamp values between -FrameTime and FrameTime
2790         if (FrameTime > F1_0 )
2791                 mprintf( (1, "Bogus frame time of %.2f seconds\n", f2fl(FrameTime) ));
2792
2793         if (Controls.pitch_time > FrameTime/2 ) Controls.pitch_time = FrameTime/2;
2794         if (Controls.vertical_thrust_time > FrameTime ) Controls.vertical_thrust_time = FrameTime;
2795         if (Controls.heading_time > FrameTime ) Controls.heading_time = FrameTime;
2796         if (Controls.sideways_thrust_time > FrameTime ) Controls.sideways_thrust_time = FrameTime;
2797         if (Controls.bank_time > FrameTime ) Controls.bank_time = FrameTime;
2798         if (Controls.forward_thrust_time > FrameTime ) Controls.forward_thrust_time = FrameTime;
2799 //      if (Controls.afterburner_time > FrameTime ) Controls.afterburner_time = FrameTime;
2800
2801         if (Controls.pitch_time < -FrameTime/2 ) Controls.pitch_time = -FrameTime/2;
2802         if (Controls.vertical_thrust_time < -FrameTime ) Controls.vertical_thrust_time = -FrameTime;
2803         if (Controls.heading_time < -FrameTime ) Controls.heading_time = -FrameTime;
2804         if (Controls.sideways_thrust_time < -FrameTime ) Controls.sideways_thrust_time = -FrameTime;
2805         if (Controls.bank_time < -FrameTime ) Controls.bank_time = -FrameTime;
2806         if (Controls.forward_thrust_time < -FrameTime ) Controls.forward_thrust_time = -FrameTime;
2807 //      if (Controls.afterburner_time < -FrameTime ) Controls.afterburner_time = -FrameTime;
2808
2809
2810 //--------- Don't do anything if in debug mode
2811         #ifndef RELEASE
2812         if ( keyd_pressed[KEY_DELETE] ) {
2813                 memset( &Controls, 0, sizeof(control_info) );
2814         }
2815         #endif
2816 }
2817
2818
2819 void reset_cruise(void)
2820 {
2821         Cruise_speed=0;
2822 }
2823
2824
2825 void kc_set_controls()
2826 {
2827         int i, j;
2828
2829 #if 0
2830         for (i=0; i<NUM_KEY_CONTROLS; i++ )     
2831                 kc_keyboard[i].value = kconfig_settings[0][i];
2832 #else
2833
2834         for (i=0; i<NUM_KEY_CONTROLS; i++ )
2835                 kc_keyboard[i].value = 255;
2836
2837         for (j=0; j<256; j++)
2838                 if (key_binding(j)) {
2839                         for (i=0; i<NUM_KEY_CONTROLS; i++ )
2840                                 if (kc_keyboard[i].value == 255
2841                                         && !stricmp(key_binding(j), kc_bind_text[i])) {
2842                                         kc_keyboard[i].value = j;
2843                                         break;
2844                                 }
2845                 }
2846 #endif
2847
2848         if ( (Config_control_type>0) && (Config_control_type<5)) {
2849                 for (i=0; i<NUM_OTHER_CONTROLS; i++ ) {
2850                         kc_joystick[i].value = kconfig_settings[Config_control_type][i];
2851                         if (kc_joystick[i].type == BT_INVERT )  {
2852                                 if (kc_joystick[i].value!=1)
2853                                         kc_joystick[i].value    = 0;
2854                                 kconfig_settings[Config_control_type][i] = kc_joystick[i].value;
2855                         }
2856                 }
2857         } else if (Config_control_type > 4) {
2858                 for (i=0; i<NUM_OTHER_CONTROLS; i++ )   {
2859                         kc_mouse[i].value = kconfig_settings[Config_control_type][i];
2860                         if (kc_mouse[i].type == BT_INVERT )     {
2861                                 if (kc_mouse[i].value!=1)
2862                                         kc_mouse[i].value       = 0;
2863                                 kconfig_settings[Config_control_type][i] = kc_mouse[i].value;
2864                         }
2865                 }
2866         }
2867
2868         for (i=0; i<NUM_D2X_CONTROLS; i++ )
2869                 if (kc_d2x[i].type == BT_KEY)
2870                         for(j = 0; j < 256; j++)
2871                                 if (key_binding(j) && !stricmp(key_binding(j), kc_d2x[i].text)) {
2872                                         kc_d2x[i].value = j;
2873                                         break;
2874                                 }
2875 }
2876
2877 #if 0 //ndef MACINTOSH  // no mac support for vr headset
2878
2879 void kconfig_center_headset()
2880 {
2881         if (vfx1_installed)
2882                 vfx_center_headset();
2883 //      } else if (iglasses_headset_installed)  {
2884 //      } else if (Victor_headset_installed)   {
2885 //      } else {
2886 //      }
2887
2888 }
2889
2890 #endif  // end of #ifndef MACINTOSH for kconfig_center_headset
2891
2892 void CybermouseAdjust ()
2893  {
2894 /*      if ( Player_num > -1 )  {
2895                 Objects[Players[Player_num].objnum].mtype.phys_info.flags &= (~PF_TURNROLL);    // Turn off roll when turning
2896                 Objects[Players[Player_num].objnum].mtype.phys_info.flags &= (~PF_LEVELLING);   // Turn off leveling to nearest side.
2897                 Auto_leveling_on = 0;
2898
2899                 if ( kc_external_version > 0 ) {                
2900                         vms_matrix tempm, ViewMatrix;
2901                         vms_angvec * Kconfig_abs_movement;
2902                         char * oem_message;
2903         
2904                         Kconfig_abs_movement = (vms_angvec *)((uint)kc_external_control + sizeof(control_info));
2905         
2906                         if ( Kconfig_abs_movement->p || Kconfig_abs_movement->b || Kconfig_abs_movement->h )    {
2907                                 vm_angles_2_matrix(&tempm,Kconfig_abs_movement);
2908                                 vm_matrix_x_matrix(&ViewMatrix,&Objects[Players[Player_num].objnum].orient,&tempm);
2909                                 Objects[Players[Player_num].objnum].orient = ViewMatrix;                
2910                         }
2911                         oem_message = (char *)((uint)Kconfig_abs_movement + sizeof(vms_angvec));
2912                         if (oem_message[0] != '\0' )
2913                                 HUD_init_message( oem_message );
2914                 }
2915         }*/
2916
2917         Controls.pitch_time += fixmul(kc_external_control->pitch_time,FrameTime);                                               
2918         Controls.vertical_thrust_time += fixmul(kc_external_control->vertical_thrust_time,FrameTime);
2919         Controls.heading_time += fixmul(kc_external_control->heading_time,FrameTime);
2920         Controls.sideways_thrust_time += fixmul(kc_external_control->sideways_thrust_time ,FrameTime);
2921         Controls.bank_time += fixmul(kc_external_control->bank_time ,FrameTime);
2922         Controls.forward_thrust_time += fixmul(kc_external_control->forward_thrust_time ,FrameTime);
2923 //      Controls.rear_view_down_count += kc_external_control->rear_view_down_count;     
2924 //      Controls.rear_view_down_state |= kc_external_control->rear_view_down_state;     
2925         Controls.fire_primary_down_count += kc_external_control->fire_primary_down_count;
2926         Controls.fire_primary_state |= kc_external_control->fire_primary_state;
2927         Controls.fire_secondary_state |= kc_external_control->fire_secondary_state;
2928         Controls.fire_secondary_down_count += kc_external_control->fire_secondary_down_count;
2929         Controls.fire_flare_down_count += kc_external_control->fire_flare_down_count;
2930         Controls.drop_bomb_down_count += kc_external_control->drop_bomb_down_count;     
2931 //      Controls.automap_down_count += kc_external_control->automap_down_count;
2932 //      Controls.automap_state |= kc_external_control->automap_state;
2933   } 
2934
2935 char GetKeyValue (char key)
2936   {
2937         mprintf ((0,"Returning %c!\n",kc_keyboard[(int)key].value));
2938         return (kc_keyboard[(int)key].value);
2939   }
2940
2941 #if !defined(MACINTOSH)
2942
2943
2944 extern object *obj_find_first_of_type (int);
2945 void kconfig_read_external_controls()
2946 {
2947         //union REGS r;
2948    int i;
2949
2950         if ( !kc_enable_external_control ) return;
2951
2952         if ( kc_external_version == 0 ) 
2953                 memset( kc_external_control, 0, sizeof(ext_control_info));
2954         else if ( kc_external_version > 0 )     {
2955         
2956                 if (kc_external_version>=4)
2957                         memset( kc_external_control, 0, sizeof(advanced_ext_control_info));
2958       else if (kc_external_version>0)     
2959                         memset( kc_external_control, 0, sizeof(ext_control_info)+sizeof(vms_angvec) + 64 );
2960                 else if (kc_external_version>2)
2961                         memset( kc_external_control, 0, sizeof(ext_control_info)+sizeof(vms_angvec) + 64 + sizeof(vms_vector) + sizeof(vms_matrix) +4 );
2962
2963                 if ( kc_external_version > 1 ) {
2964                         // Write ship pos and angles to external controls...
2965                         ubyte *temp_ptr = (ubyte *)kc_external_control;
2966                         vms_vector *ship_pos;
2967                         vms_matrix *ship_orient;
2968                         memset( kc_external_control, 0, sizeof(ext_control_info)+sizeof(vms_angvec) + 64 + sizeof(vms_vector)+sizeof(vms_matrix) );
2969                         temp_ptr += sizeof(ext_control_info) + sizeof(vms_angvec) + 64;
2970                         ship_pos = (vms_vector *)temp_ptr;
2971                         temp_ptr += sizeof(vms_vector);
2972                         ship_orient = (vms_matrix *)temp_ptr;
2973                         // Fill in ship postion...
2974                         *ship_pos = Objects[Players[Player_num].objnum].pos;
2975                         // Fill in ship orientation...
2976                         *ship_orient = Objects[Players[Player_num].objnum].orient;
2977                 }
2978     if (kc_external_version>=4)
2979           {
2980            advanced_ext_control_info *temp_ptr=(advanced_ext_control_info *)kc_external_control;
2981  
2982       temp_ptr->headlight_state=(Players[Player_num].flags & PLAYER_FLAGS_HEADLIGHT_ON);
2983                 temp_ptr->primary_weapon_flags=Players[Player_num].primary_weapon_flags;
2984                 temp_ptr->secondary_weapon_flags=Players[Player_num].secondary_weapon_flags;
2985       temp_ptr->current_primary_weapon=Primary_weapon;
2986       temp_ptr->current_secondary_weapon=Secondary_weapon;
2987
2988       temp_ptr->current_guidebot_command=Escort_goal_object;
2989
2990            temp_ptr->force_vector=ExtForceVec;
2991                 temp_ptr->force_matrix=ExtApplyForceMatrix;
2992            for (i=0;i<3;i++)
2993        temp_ptr->joltinfo[i]=ExtJoltInfo[i];  
2994       for (i=0;i<2;i++)
2995                    temp_ptr->x_vibrate_info[i]=ExtXVibrateInfo[i];
2996                 temp_ptr->x_vibrate_clear=ExtXVibrateClear;
2997            temp_ptr->game_status=ExtGameStatus;
2998    
2999       memset ((void *)&ExtForceVec,0,sizeof(vms_vector));
3000       memset ((void *)&ExtApplyForceMatrix,0,sizeof(vms_matrix));
3001       
3002       for (i=0;i<3;i++)
3003                  ExtJoltInfo[i]=0;
3004       for (i=0;i<2;i++)
3005                  ExtXVibrateInfo[i]=0;
3006       ExtXVibrateClear=0;
3007      }
3008         }
3009
3010         if ( Automap_active )                   // (If in automap...)
3011                 kc_external_control->automap_state = 1;
3012         //memset(&r,0,sizeof(r));
3013
3014   #if 0
3015  
3016         int386 ( kc_external_intno, &r, &r);            // Read external info...
3017
3018   #endif 
3019
3020         if ( Player_num > -1 )  {
3021                 Objects[Players[Player_num].objnum].mtype.phys_info.flags &= (~PF_TURNROLL);    // Turn off roll when turning
3022                 Objects[Players[Player_num].objnum].mtype.phys_info.flags &= (~PF_LEVELLING);   // Turn off leveling to nearest side.
3023                 Auto_leveling_on = 0;
3024
3025                 if ( kc_external_version > 0 ) {                
3026                         vms_matrix tempm, ViewMatrix;
3027                         vms_angvec * Kconfig_abs_movement;
3028                         char * oem_message;
3029         
3030                         Kconfig_abs_movement = (vms_angvec *)((uint)kc_external_control + sizeof(ext_control_info));
3031         
3032                         if ( Kconfig_abs_movement->p || Kconfig_abs_movement->b || Kconfig_abs_movement->h )    {
3033                                 vm_angles_2_matrix(&tempm,Kconfig_abs_movement);
3034                                 vm_matrix_x_matrix(&ViewMatrix,&Objects[Players[Player_num].objnum].orient,&tempm);
3035                                 Objects[Players[Player_num].objnum].orient = ViewMatrix;                
3036                         }
3037                         oem_message = (char *)((uint)Kconfig_abs_movement + sizeof(vms_angvec));
3038                         if (oem_message[0] != '\0' )
3039                                 HUD_init_message( oem_message );
3040                 }
3041         }
3042
3043         Controls.pitch_time += fixmul(kc_external_control->pitch_time,FrameTime);                                               
3044         Controls.vertical_thrust_time += fixmul(kc_external_control->vertical_thrust_time,FrameTime);
3045         Controls.heading_time += fixmul(kc_external_control->heading_time,FrameTime);
3046         Controls.sideways_thrust_time += fixmul(kc_external_control->sideways_thrust_time ,FrameTime);
3047         Controls.bank_time += fixmul(kc_external_control->bank_time ,FrameTime);
3048         Controls.forward_thrust_time += fixmul(kc_external_control->forward_thrust_time ,FrameTime);
3049         Controls.rear_view_down_count += kc_external_control->rear_view_down_count;     
3050         Controls.rear_view_down_state |= kc_external_control->rear_view_down_state;     
3051         Controls.fire_primary_down_count += kc_external_control->fire_primary_down_count;
3052         Controls.fire_primary_state |= kc_external_control->fire_primary_state;
3053         Controls.fire_secondary_state |= kc_external_control->fire_secondary_state;
3054         Controls.fire_secondary_down_count += kc_external_control->fire_secondary_down_count;
3055         Controls.fire_flare_down_count += kc_external_control->fire_flare_down_count;
3056         Controls.drop_bomb_down_count += kc_external_control->drop_bomb_down_count;     
3057         Controls.automap_down_count += kc_external_control->automap_down_count;
3058         Controls.automap_state |= kc_external_control->automap_state;
3059         
3060    if (kc_external_version>=3)
3061          {
3062                 ubyte *temp_ptr = (ubyte *)kc_external_control;
3063                 temp_ptr += (sizeof(ext_control_info) + sizeof(vms_angvec) + 64 + sizeof(vms_vector) + sizeof (vms_matrix));
3064   
3065            if (*(temp_ptr))
3066                  Controls.cycle_primary_count=(*(temp_ptr));
3067            if (*(temp_ptr+1))
3068                  Controls.cycle_secondary_count=(*(temp_ptr+1));
3069
3070                 if (*(temp_ptr+2))
3071                  Controls.afterburner_state=(*(temp_ptr+2));
3072                 if (*(temp_ptr+3))
3073                  Controls.headlight_count=(*(temp_ptr+3));
3074          }
3075    if (kc_external_version>=4)
3076          {
3077      int i;
3078           advanced_ext_control_info *temp_ptr=(advanced_ext_control_info *)kc_external_control;
3079      
3080      for (i=0;i<128;i++)
3081            if (temp_ptr->keyboard[i])
3082                         key_putkey (i);
3083
3084      if (temp_ptr->Reactor_blown)
3085       {
3086        if (Game_mode & GM_MULTI)
3087                     net_destroy_controlcen (obj_find_first_of_type (OBJ_CNTRLCEN));
3088                  else
3089                          do_controlcen_destroyed_stuff(obj_find_first_of_type (OBJ_CNTRLCEN));
3090            }
3091     }
3092   
3093 }
3094 #endif
3095