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