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