home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / main / kconfig.c < prev    next >
Text File  |  1998-06-08  |  81KB  |  2,277 lines

  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-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  12. */
  13. /*
  14.  * $Source: f:/miner/source/main/rcs/kconfig.c $
  15.  * $Revision: 2.11 $
  16.  * $Author: john $
  17.  * $Date: 1995/08/23 16:08:04 $
  18.  * 
  19.  * Routines to configure keyboard, joystick, etc..
  20.  * 
  21.  * $Log: kconfig.c $
  22.  * Revision 2.11  1995/08/23  16:08:04  john
  23.  * Added version 2 of external controls that passes the ship
  24.  * position and orientation the drivers.
  25.  * 
  26.  * Revision 2.10  1995/07/07  16:48:01  john
  27.  * Fixed bug with new interface.
  28.  * 
  29.  * Revision 2.9  1995/07/03  15:02:32  john
  30.  * Added new version of external controls for Cybermouse absolute position.
  31.  * 
  32.  * Revision 2.8  1995/06/30  12:30:28  john
  33.  * Added -Xname command line.
  34.  * 
  35.  * Revision 2.7  1995/03/30  16:36:56  mike
  36.  * text localization.
  37.  * 
  38.  * Revision 2.6  1995/03/21  14:39:31  john
  39.  * Ifdef'd out the NETWORK code.
  40.  * 
  41.  * Revision 2.5  1995/03/16  10:53:07  john
  42.  * Move VFX center to Shift+Z instead of Enter because
  43.  * it conflicted with toggling HUD on/off.
  44.  * 
  45.  * Revision 2.4  1995/03/10  13:47:24  john
  46.  * Added head tracking sensitivity.
  47.  * 
  48.  * Revision 2.3  1995/03/09  18:07:06  john
  49.  * Fixed bug with iglasses tracking not "centering" right.
  50.  * Made VFX have bright headlight lighting.
  51.  * 
  52.  * Revision 2.2  1995/03/08  15:32:39  john
  53.  * Made VictorMaxx head tracking use Greenleaf code.
  54.  * 
  55.  * Revision 2.1  1995/03/06  15:23:31  john
  56.  * New screen techniques.
  57.  * 
  58.  * Revision 2.0  1995/02/27  11:29:26  john
  59.  * New version 2.0, which has no anonymous unions, builds with
  60.  * Watcom 10.0, and doesn't require parsing BITMAPS.TBL.
  61.  * 
  62.  * Revision 1.105  1995/02/22  14:11:58  allender
  63.  * remove anonymous unions from object structure
  64.  * 
  65.  * Revision 1.104  1995/02/13  12:01:56  john
  66.  * Fixed bug with buggin not mmaking player faster.
  67.  * 
  68.  * Revision 1.103  1995/02/09  22:00:46  john
  69.  * Added i-glasses tracking.
  70.  * 
  71.  * Revision 1.102  1995/01/24  21:25:47  john
  72.  * Fixed bug with slide/bank on not working with
  73.  * Cyberman heading.,
  74.  * 
  75.  * Revision 1.101  1995/01/24  16:09:56  john
  76.  * Fixed bug with Wingman extreme customize text overwriting title.
  77.  * 
  78.  * Revision 1.100  1995/01/24  12:37:46  john
  79.  * Made Esc exit key define menu.
  80.  * 
  81.  * Revision 1.99  1995/01/23  23:54:43  matt
  82.  * Made keypad enter work
  83.  * 
  84.  * Revision 1.98  1995/01/23  16:42:00  john
  85.  * Made the external controls always turn banking off, leveling off
  86.  * and passed automap state thru to the tsr.
  87.  * 
  88.  * Revision 1.97  1995/01/12  11:41:33  john
  89.  * Added external control reading.
  90.  * 
  91.  * Revision 1.96  1995/01/05  10:43:58  mike
  92.  * Handle case when timer_get_fixed_seconds() goes negative.  Happens at 9.1
  93.  * hours.  Previously, joystick would stop functioning.  Now will work.
  94.  * 
  95.  * Revision 1.95  1994/12/29  11:17:38  john
  96.  * Took out some warnings and mprintf.
  97.  * 
  98.  * Revision 1.94  1994/12/29  11:07:41  john
  99.  * Fixed Thrustmaster and Logitech Wingman extreme
  100.  * Hat by reading the y2 axis during the center stage
  101.  * of the calibration, and using 75, 50, 27, and 3 %
  102.  * as values for the 4 positions.
  103.  * 
  104.  * Revision 1.93  1994/12/27  12:16:20  john
  105.  * Fixed bug with slide on not working with joystick or mouse buttons.
  106.  * 
  107.  * Revision 1.92  1994/12/20  10:34:15  john
  108.  * Made sensitivity work for mouse & joystick and made
  109.  * it only affect, pitch, heading, and roll.
  110.  * 
  111.  * Revision 1.91  1994/12/16  00:11:23  matt
  112.  * Made delete key act normally when debug out
  113.  * 
  114.  * Revision 1.90  1994/12/14  17:41:15  john
  115.  * Added more buttons so that  Yoke would work.
  116.  * 
  117.  * Revision 1.89  1994/12/13  17:25:35  allender
  118.  * Added Assert for bogus time for joystick reading.
  119.  * 
  120.  * Revision 1.88  1994/12/13  14:48:01  john
  121.  * Took out some debugging mprintf's
  122.  * 
  123.  * 
  124.  * Revision 1.87  1994/12/13  14:43:02  john
  125.  * Took out the code in kconfig to build direction array.
  126.  * Called kc_set_controls after selecting a new control type.
  127.  * 
  128.  * Revision 1.86  1994/12/13  01:11:32  john
  129.  * Fixed bug with message clearing overwriting 
  130.  * right border.
  131.  * 
  132.  * Revision 1.85  1994/12/12  00:35:58  john
  133.  * Added or thing for keys.
  134.  * 
  135.  * Revision 1.84  1994/12/09  17:08:06  john
  136.  * Made mouse a bit less sensitive.
  137.  * 
  138.  * Revision 1.83  1994/12/09  16:04:00  john
  139.  * Increased mouse sensitivity.
  140.  * 
  141.  * Revision 1.82  1994/12/09  00:41:26  mike
  142.  * fix hang in automap print screen
  143.  * 
  144.  * Revision 1.81  1994/12/08  11:50:37  john
  145.  * Made strcpy only copy corect number of chars,.
  146.  * 
  147.  * Revision 1.80  1994/12/07  16:16:06  john
  148.  * Added command to check to see if a joystick axes has been used.
  149.  * 
  150.  * Revision 1.79  1994/12/07  14:52:28  yuan
  151.  * Localization 492
  152.  * 
  153.  * Revision 1.78  1994/12/07  13:37:40  john
  154.  * Made the joystick thrust work in reverse.
  155.  * 
  156.  * Revision 1.77  1994/12/07  11:28:24  matt
  157.  * Did a little localization support
  158.  * 
  159.  * Revision 1.76  1994/12/04  12:30:03  john
  160.  * Made the Thrustmaster stick read every frame, not every 10 frames,
  161.  * because it uses analog axis as buttons.
  162.  * 
  163.  * Revision 1.75  1994/12/03  22:35:25  yuan
  164.  * Localization 412
  165.  * 
  166.  * Revision 1.74  1994/12/03  15:39:24  john
  167.  * Made numeric keypad move in conifg.
  168.  * 
  169.  * Revision 1.73  1994/12/01  16:23:39  john
  170.  * Fixed include mistake.
  171.  * 
  172.  * Revision 1.72  1994/12/01  16:07:57  john
  173.  * Fixed bug that disabled joystick in automap because it used gametime, which is
  174.  * paused during automap. Fixed be used timer_Get_fixed_seconds instead of GameTime.
  175.  * 
  176.  * Revision 1.71  1994/12/01  12:30:49  john
  177.  * Made Ctrl+D delete, not Ctrl+E
  178.  * 
  179.  * Revision 1.70  1994/12/01  11:52:52  john
  180.  * Added default values for GamePad.
  181.  * 
  182.  * Revision 1.69  1994/11/30  00:59:12  mike
  183.  * optimizations.
  184.  * 
  185.  * Revision 1.68  1994/11/29  03:45:50  john
  186.  * Added joystick sensitivity; Added sound channels to detail menu.  Removed -maxchannels
  187.  * command line arg.
  188.  * 
  189.  * Revision 1.67  1994/11/27  23:13:44  matt
  190.  * Made changes for new mprintf calling convention
  191.  * 
  192.  * Revision 1.66  1994/11/27  19:52:12  matt
  193.  * Made screen shots work in a few more places
  194.  * 
  195.  * Revision 1.65  1994/11/22  16:54:50  mike
  196.  * autorepeat on missiles.
  197.  * 
  198.  * Revision 1.64  1994/11/21  11:16:17  rob
  199.  * Changed calls to GameLoop to calls to multi_menu_poll and changed
  200.  * conditions under which they are called.
  201.  * 
  202.  * Revision 1.63  1994/11/19  15:14:48  mike
  203.  * remove unused code and data
  204.  * 
  205.  * Revision 1.62  1994/11/18  23:37:56  john
  206.  * Changed some shorts to ints.
  207.  * 
  208.  * Revision 1.61  1994/11/17  13:36:35  rob
  209.  * Added better network hook in kconfig menu.
  210.  * 
  211.  * Revision 1.60  1994/11/14  20:09:13  john
  212.  * Made Tab be default for automap.
  213.  * 
  214.  * Revision 1.59  1994/11/13  16:34:07  matt
  215.  * Fixed victormaxx angle conversions
  216.  * 
  217.  * Revision 1.58  1994/11/12  14:47:05  john
  218.  * Added support for victor head tracking.
  219.  * 
  220.  * Revision 1.57  1994/11/08  15:14:55  john
  221.  * Added more calls so net doesn't die in net game.
  222.  * 
  223.  * Revision 1.56  1994/11/07  14:01:07  john
  224.  * Changed the gamma correction sequencing.
  225.  * 
  226.  * Revision 1.55  1994/11/01  16:40:08  john
  227.  * Added Gamma correction.
  228.  * 
  229.  * Revision 1.54  1994/10/25  23:09:26  john
  230.  * Made the automap key configurable.
  231.  * 
  232.  * Revision 1.53  1994/10/25  13:11:59  john
  233.  * Made keys the way Adam speced 'em for final game.
  234.  * 
  235.  * Revision 1.52  1994/10/24  17:44:22  john
  236.  * Added stereo channel reversing.
  237.  * 
  238.  * Revision 1.51  1994/10/22  13:23:18  john
  239.  * Made default rear view key be R.
  240.  * 
  241.  * Revision 1.50  1994/10/22  13:20:09  john
  242.  * Took out toggle primary/secondary weapons.  Fixed black
  243.  * background for 'axes' and 'buttons' text.
  244.  * 
  245.  * Revision 1.49  1994/10/21  15:20:15  john
  246.  * Made PrtScr do screen dump, not F2.
  247.  * 
  248.  * Revision 1.48  1994/10/21  13:41:36  john
  249.  * Allowed F2 to screen dump.
  250.  * 
  251.  * Revision 1.47  1994/10/17  13:07:05  john
  252.  * Moved the descent.cfg info into the player config file.
  253.  * 
  254.  * Revision 1.46  1994/10/14  15:30:22  john
  255.  * Added Cyberman default positions.
  256.  * 
  257.  * Revision 1.45  1994/10/14  15:24:54  john
  258.  * Made Cyberman work with config.
  259.  * 
  260.  * Revision 1.44  1994/10/14  12:46:04  john
  261.  * Added the ability to reset all to default.
  262.  * 
  263.  * Revision 1.43  1994/10/14  12:18:31  john
  264.  * Made mouse invert axis always be 0 or 1.
  265.  * 
  266.  * Revision 1.42  1994/10/14  12:16:03  john
  267.  * Changed code so that by doing DEL+F12 saves the current kconfig
  268.  * values as default. Added support for drop_bomb key.  Took out
  269.  * unused slots for keyboard.  Made keyboard use control_type of 0
  270.  * save slots.
  271.  * 
  272.  * Revision 1.41  1994/10/13  21:27:02  john
  273.  * Made axis invert value always be 0 or 1.
  274. n * 
  275.  * Revision 1.40  1994/10/13  20:18:15  john
  276.  * Added some more system keys, such as F? and CAPSLOCK.
  277.  * 
  278.  * Revision 1.39  1994/10/13  19:22:29  john
  279.  * Added separate config saves for different devices.
  280.  * Made all the devices work together better, such as mice won't
  281.  * get read when you're playing with the joystick.
  282.  * 
  283.  * Revision 1.38  1994/10/13  15:41:57  mike
  284.  * Remove afterburner.
  285.  * 
  286.  */
  287.  
  288.  
  289. #pragma off (unreferenced)
  290. static char rcsid[] = "$Id: kconfig.c 2.11 1995/08/23 16:08:04 john Exp $";
  291. #pragma on (unreferenced)
  292.  
  293. #include <stdio.h>
  294. #include <stdlib.h>
  295. #include <string.h>
  296. #include <dos.h>
  297. #include <io.h>
  298. #include <stdarg.h>
  299. #include <ctype.h>
  300.  
  301. #include "error.h"
  302. #include "types.h"
  303. #include "gr.h"
  304. #include "mono.h"
  305. #include "key.h"
  306. #include "palette.h"
  307. #include "game.h"
  308. #include "gamefont.h"
  309. #include "iff.h"
  310. #include "mem.h"
  311. #include "joy.h"
  312. #include "mouse.h"
  313. #include "kconfig.h"
  314. #include "gauges.h"
  315. #include "joydefs.h"
  316. #include "vfx1.h"
  317. #include "render.h"
  318. #include "arcade.h"
  319. #include "digi.h"
  320. #include "newmenu.h"
  321. #include "victor.h"
  322. #include "endlevel.h"
  323. #include "multi.h"
  324. #include "timer.h"
  325. #include "text.h"
  326. #include "player.h"
  327. #include "menu.h"
  328. #include "iglasses.h"
  329. #include "args.h"
  330.  
  331. //#define TABLE_CREATION 1
  332.  
  333. int     sense_function1=0;    
  334. int      vfx1_installed=0;
  335. int     SenseStatus1( void );
  336.  
  337. // Array used to 'blink' the cursor while waiting for a keypress.
  338. 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 };
  339.  
  340. //char * invert_text[2] = { "N", "Y" };
  341. //char * joybutton_text[28] = { "BTN 1", "BTN 2", "BTN 3", "BTN 4", "", "TRIG", "LEFT", "HAT ", "RIGHT", "", "", "HAT €", "MID", "", "", "HAT ", "", "", "", "HAT ‚", "TRIG", "LEFT", "RIGHT", "", "UP","DOWN","LEFT", "RIGHT" };
  342. //char * joyaxis_text[4] = { "X1", "Y1", "X2", "Y2" };
  343. //char * mouseaxis_text[2] = { "L/R", "F/B" };
  344. //char * mousebutton_text[3] = { "Left", "Right", "Mid" };
  345.  
  346. int invert_text[2] = { TNUM_N, TNUM_Y };
  347. int joybutton_text[28] = 
  348. { TNUM_BTN_1, TNUM_BTN_2, TNUM_BTN_3, TNUM_BTN_4,
  349.   -1, TNUM_TRIG, TNUM_LEFT, TNUM_HAT_L,
  350.  TNUM_RIGHT, -1, TNUM_HAT2_D, TNUM_HAT_R,
  351.  TNUM_MID, -1, TNUM_HAT2_R, TNUM_HAT_U,
  352.  TNUM_HAT2_L, -1, TNUM_HAT2_U, TNUM_HAT_D,
  353.  TNUM_TRIG, TNUM_LEFT, TNUM_RIGHT, -1, 
  354.   TNUM_UP, TNUM_DOWN, TNUM_LEFT, TNUM_RIGHT };
  355. int joyaxis_text[4] = { TNUM_X1, TNUM_Y1, TNUM_X2, TNUM_Y2 };
  356. int mouseaxis_text[2] = { TNUM_L_R, TNUM_F_B };
  357. int mousebutton_text[3] = { TNUM_LEFT, TNUM_RIGHT, TNUM_MID };
  358.  
  359. char * key_text[256] = {         \
  360. "","ESC","1","2","3","4","5","6","7","8","9","0","-",             \
  361. "=","BSPC","TAB","Q","W","E","R","T","Y","U","I","O",                \
  362. "P","[","]","ƒ","LCTRL","A","S","D","F",        \
  363. "G","H","J","K","L",";","'","`",        \
  364. "LSHFT","\\","Z","X","C","V","B","N","M",",",      \
  365. ".","/","RSHFT","PAD*","LALT","SPC",      \
  366. "CPSLK","F1","F2","F3","F4","F5","F6","F7","F8","F9",        \
  367. "F10","NMLCK","SCLK","PAD7","PAD8","PAD9","PAD-",   \
  368. "PAD4","PAD5","PAD6","PAD+","PAD1","PAD2","PAD3","PAD0", \
  369. "PAD.","","","","F11","F12","","","","","","","","","",         \
  370. "","","","","","","","","","","","","","","","","","","","",     \
  371. "","","","","","","","","","","","","","","","","","","","",     \
  372. "","","","","","","","","","","","","","","","","","",           \
  373. "PADƒ","RCTRL","","","","","","","","","","","","","", \
  374. "","","","","","","","","","","PAD/","","","RALT","",      \
  375. "","","","","","","","","","","","","","HOME","‚","PGUP",     \
  376. "","","","","","END","€","PGDN","INS",       \
  377. "DEL","","","","","","","","","","","","","","","","","",     \
  378. "","","","","","","","","","","","","","","","","","","","",     \
  379. "","","","","","","" };
  380.  
  381. 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 };
  382.  
  383. //extern void GameLoop(int, int );
  384.  
  385. control_info Controls;
  386.  
  387. ubyte Config_digi_volume = 16;
  388. ubyte Config_midi_volume = 16;
  389. ubyte Config_control_type = 0;
  390. ubyte Config_channels_reversed = 0;
  391. ubyte Config_joystick_sensitivity = 8;
  392.  
  393. fix Cruise_speed=0;
  394.  
  395. #define BT_KEY                 0
  396. #define BT_MOUSE_BUTTON     1
  397. #define BT_MOUSE_AXIS        2
  398. #define BT_JOY_BUTTON         3
  399. #define BT_JOY_AXIS            4
  400. #define BT_INVERT                5
  401.  
  402. char *btype_text[] = { "BT_KEY", "BT_MOUSE_BUTTON", "BT_MOUSE_AXIS", "BT_JOY_BUTTON", "BT_JOY_AXIS", "BT_INVERT" };
  403.  
  404. #define INFO_Y 28
  405.  
  406. typedef struct kc_item {
  407.     short id;                // The id of this item
  408.     short x, y;                
  409.     short w1;
  410.     short w2;
  411.     short u,d,l,r;
  412.     short text_num1;
  413.     ubyte type;
  414.     ubyte value;        // what key,button,etc
  415. } kc_item;
  416.  
  417. int Num_items=23;
  418. kc_item *All_items;
  419.  
  420. ubyte kconfig_settings[CONTROL_MAX_TYPES][MAX_CONTROLS];
  421.  
  422. //----------- WARNING!!!!!!! -------------------------------------------
  423. // THESE NEXT FOUR BLOCKS OF DATA ARE GENERATED BY PRESSING DEL+F12 WHEN
  424. // IN THE KEYBOARD CONFIG SCREEN.  BASICALLY, THAT PROCEDURE MODIFIES THE
  425. // U,D,L,R FIELDS OF THE ARRAYS AND DUMPS THE NEW ARRAYS INTO KCONFIG.COD
  426. //-------------------------------------------------------------------------
  427.  
  428. ubyte default_kconfig_settings[CONTROL_MAX_TYPES][MAX_CONTROLS] = {
  429. {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,0xff,0xff,0xff,0xff},
  430. {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},
  431. {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},
  432. {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,0x3,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
  433. {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},
  434. {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},
  435. {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},
  436. };
  437.  
  438. kc_item kc_keyboard[NUM_KEY_CONTROLS] = {
  439.     {  0, 15, 49, 71, 26, 43,  2, 23,  1,TNUM_PITCH_FORWARD, BT_KEY, 255 },
  440.     {  1, 15, 49,100, 26, 22,  3,  0, 24,TNUM_PITCH_FORWARD, BT_KEY, 255 },
  441.     {  2, 15, 57, 71, 26,  0,  4, 25,  3,TNUM_PITCH_BACKWARD, BT_KEY, 255 },
  442.     {  3, 15, 57,100, 26,  1,  5,  2, 26,TNUM_PITCH_BACKWARD, BT_KEY, 255 },
  443.     {  4, 15, 65, 71, 26,  2,  6, 27,  5,TNUM_TURN_LEFT, BT_KEY, 255 },
  444.     {  5, 15, 65,100, 26,  3,  7,  4, 28,TNUM_TURN_LEFT, BT_KEY, 255 },
  445.     {  6, 15, 73, 71, 26,  4,  8, 29,  7,TNUM_TURN_RIGHT, BT_KEY, 255 },
  446.     {  7, 15, 73,100, 26,  5,  9,  6, 34,TNUM_TURN_RIGHT, BT_KEY, 255 },
  447.     {  8, 15, 85, 71, 26,  6, 10, 35,  9,TNUM_SLIDE_ON, BT_KEY, 255 },
  448.     {  9, 15, 85,100, 26,  7, 11,  8, 36,TNUM_SLIDE_ON, BT_KEY, 255 },
  449.     { 10, 15, 93, 71, 26,  8, 12, 37, 11,TNUM_SLIDE_LEFT, BT_KEY, 255 },
  450.     { 11, 15, 93,100, 26,  9, 13, 10, 44,TNUM_SLIDE_LEFT, BT_KEY, 255 },
  451.     { 12, 15,101, 71, 26, 10, 14, 45, 13,TNUM_SLIDE_RIGHT, BT_KEY, 255 },
  452.     { 13, 15,101,100, 26, 11, 15, 12, 30,TNUM_SLIDE_RIGHT, BT_KEY, 255 },
  453.     { 14, 15,109, 71, 26, 12, 16, 31, 15,TNUM_SLIDE_UP, BT_KEY, 255 },
  454.     { 15, 15,109,100, 26, 13, 17, 14, 32,TNUM_SLIDE_UP, BT_KEY, 255 },
  455.     { 16, 15,117, 71, 26, 14, 18, 33, 17,TNUM_SLIDE_DOWN, BT_KEY, 255 },
  456.     { 17, 15,117,100, 26, 15, 19, 16, 38,TNUM_SLIDE_DOWN, BT_KEY, 255 },
  457.     { 18, 15,129, 71, 26, 16, 20, 39, 19,TNUM_BANK_ON, BT_KEY, 255 },
  458.     { 19, 15,129,100, 26, 17, 21, 18, 40,TNUM_BANK_ON, BT_KEY, 255 },
  459.     { 20, 15,137, 71, 26, 18, 22, 41, 21,TNUM_BANK_LEFT, BT_KEY, 255 },
  460.     { 21, 15,137,100, 26, 19, 23, 20, 42,TNUM_BANK_LEFT, BT_KEY, 255 },
  461.     { 22, 15,145, 71, 26, 20,  1, 43, 23,TNUM_BANK_RIGHT, BT_KEY, 255 },
  462.     { 23, 15,145,100, 26, 21, 24, 22,  0,TNUM_BANK_RIGHT, BT_KEY, 255 },
  463.     { 24,158, 49, 83, 26, 23, 26,  1, 25,TNUM_FIRE_PRIMARY, BT_KEY, 255 },
  464.     { 25,158, 49,112, 26, 42, 27, 24,  2,TNUM_FIRE_PRIMARY, BT_KEY, 255 },
  465.     { 26,158, 57, 83, 26, 24, 28,  3, 27,TNUM_FIRE_SECONDARY, BT_KEY, 255 },
  466.     { 27,158, 57,112, 26, 25, 29, 26,  4,TNUM_FIRE_SECONDARY, BT_KEY, 255 },
  467.     { 28,158, 65, 83, 26, 26, 34,  5, 29,TNUM_FIRE_FLARE, BT_KEY, 255 },
  468.     { 29,158, 65,112, 26, 27, 35, 28,  6,TNUM_FIRE_FLARE, BT_KEY, 255 },
  469.     { 30,158,105, 83, 26, 44, 32, 13, 31,TNUM_ACCELERATE, BT_KEY, 255 },
  470.     { 31,158,105,112, 26, 45, 33, 30, 14,TNUM_ACCELERATE, BT_KEY, 255 },
  471.     { 32,158,113, 83, 26, 30, 38, 15, 33,TNUM_REVERSE, BT_KEY, 255 },
  472.     { 33,158,113,112, 26, 31, 39, 32, 16,TNUM_REVERSE, BT_KEY, 255 },
  473.     { 34,158, 73, 83, 26, 28, 36,  7, 35,TNUM_DROP_BOMB, BT_KEY, 255 },
  474.     { 35,158, 73,112, 26, 29, 37, 34,  8,TNUM_DROP_BOMB, BT_KEY, 255 },
  475.     { 36,158, 85, 83, 26, 34, 44,  9, 37,TNUM_REAR_VIEW, BT_KEY, 255 },
  476.     { 37,158, 85,112, 26, 35, 45, 36, 10,TNUM_REAR_VIEW, BT_KEY, 255 },
  477.     { 38,158,125, 83, 26, 32, 40, 17, 39,TNUM_CRUISE_FASTER, BT_KEY, 255 },
  478.     { 39,158,125,112, 26, 33, 41, 38, 18,TNUM_CRUISE_FASTER, BT_KEY, 255 },
  479.     { 40,158,133, 83, 26, 38, 42, 19, 41,TNUM_CRUISE_SLOWER, BT_KEY, 255 },
  480.     { 41,158,133,112, 26, 39, 43, 40, 20,TNUM_CRUISE_SLOWER, BT_KEY, 255 },
  481.     { 42,158,141, 83, 26, 40, 25, 21, 43,TNUM_CRUISE_OFF, BT_KEY, 255 },
  482.     { 43,158,141,112, 26, 41,  0, 42, 22,TNUM_CRUISE_OFF, BT_KEY, 255 },
  483.     { 44,158, 93, 83, 26, 36, 30, 11, 45,TNUM_AUTOMAP, BT_KEY, 255 },
  484.     { 45,158, 93,112, 26, 37, 31, 44, 12,TNUM_AUTOMAP, BT_KEY, 255 },
  485. };
  486. kc_item kc_joystick[NUM_OTHER_CONTROLS] = {
  487.     {  0, 25, 46, 85, 26, 15,  1, 24,  5,TNUM_FIRE_PRIMARY, BT_JOY_BUTTON, 255 },
  488.     {  1, 25, 54, 85, 26,  0,  4,  5,  6,TNUM_FIRE_SECONDARY, BT_JOY_BUTTON, 255 },
  489.     {  2, 25, 85, 85, 26, 26,  3,  9, 10,TNUM_ACCELERATE, BT_JOY_BUTTON, 255 },
  490.     {  3, 25, 93, 85, 26,  2, 25, 10, 11,TNUM_REVERSE, BT_JOY_BUTTON, 255 },
  491.     {  4, 25, 62, 85, 26,  1, 26,  6,  7,TNUM_FIRE_FLARE, BT_JOY_BUTTON, 255 },
  492.     {  5,180, 46, 59, 26, 23,  6,  0,  1,TNUM_SLIDE_ON, BT_JOY_BUTTON, 255 },
  493.     {  6,180, 54, 59, 26,  5,  7,  1,  4,TNUM_SLIDE_LEFT, BT_JOY_BUTTON, 255 },
  494.     {  7,180, 62, 59, 26,  6,  8,  4, 26,TNUM_SLIDE_RIGHT, BT_JOY_BUTTON, 255 },
  495.     {  8,180, 70, 59, 26,  7,  9, 26,  9,TNUM_SLIDE_UP, BT_JOY_BUTTON, 255 },
  496.     {  9,180, 78, 59, 26,  8, 10,  8,  2,TNUM_SLIDE_DOWN, BT_JOY_BUTTON, 255 },
  497.     { 10,180, 90, 59, 26,  9, 11,  2,  3,TNUM_BANK_ON, BT_JOY_BUTTON, 255 },
  498.     { 11,180, 98, 59, 26, 10, 12,  3, 12,TNUM_BANK_LEFT, BT_JOY_BUTTON, 255 },
  499.     { 12,180,106, 59, 26, 11, 18, 11, 25,TNUM_BANK_RIGHT, BT_JOY_BUTTON, 255 },
  500.     { 13, 22,146, 51, 26, 24, 15, 25, 14,TNUM_PITCH_UD, BT_JOY_AXIS, 255 },
  501.     { 14, 22,146, 99,  8, 25, 16, 13, 17,TNUM_PITCH_UD, BT_INVERT, 255 },
  502.     { 15, 22,154, 51, 26, 13,  0, 18, 16,TNUM_TURN_LR, BT_JOY_AXIS, 255 },
  503.     { 16, 22,154, 99,  8, 14, 17, 15, 19,TNUM_TURN_LR, BT_INVERT, 255 },
  504.     { 17,164,146, 58, 26, 16, 19, 14, 18,TNUM_SLIDE_LR, BT_JOY_AXIS, 255 },
  505.     { 18,164,146,106,  8, 12, 20, 17, 15,TNUM_SLIDE_LR, BT_INVERT, 255 },
  506.     { 19,164,154, 58, 26, 17, 21, 16, 20,TNUM_SLIDE_UD, BT_JOY_AXIS, 255 },
  507.     { 20,164,154,106,  8, 18, 22, 19, 21,TNUM_SLIDE_UD, BT_INVERT, 255 },
  508.     { 21,164,162, 58, 26, 19, 23, 20, 22,TNUM_BANK_LR, BT_JOY_AXIS, 255 },
  509.     { 22,164,162,106,  8, 20, 24, 21, 23,TNUM_BANK_LR, BT_INVERT, 255 },
  510.     { 23,164,174, 58, 26, 21,  5, 22, 24,TNUM_THROTTLE, BT_JOY_AXIS, 255 },
  511.     { 24,164,174,106,  8, 22, 13, 23,  0,TNUM_THROTTLE, BT_INVERT, 255 },
  512.     { 25, 25,109, 85, 26,  3, 14, 12, 13,TNUM_REAR_VIEW, BT_JOY_BUTTON, 255 },
  513.     { 26, 25, 70, 85, 26,  4,  2,  7,  8,TNUM_DROP_BOMB, BT_JOY_BUTTON, 255 },
  514. };
  515. kc_item kc_mouse[NUM_OTHER_CONTROLS] = {
  516.     {  0, 25, 46, 85, 26, 12,  1, 24,  5,TNUM_FIRE_PRIMARY, BT_MOUSE_BUTTON, 255 },
  517.     {  1, 25, 54, 85, 26,  0,  4,  5,  6,TNUM_FIRE_SECONDARY, BT_MOUSE_BUTTON, 255 },
  518.     {  2, 25, 85, 85, 26, 26,  3,  9, 10,TNUM_ACCELERATE, BT_MOUSE_BUTTON, 255 },
  519.     {  3, 25, 93, 85, 26,  2, 25, 10, 11,TNUM_REVERSE, BT_MOUSE_BUTTON, 255 },
  520.     {  4, 25, 62, 85, 26,  1, 26,  6,  7,TNUM_FIRE_FLARE, BT_MOUSE_BUTTON, 255 },
  521.     {  5,180, 46, 59, 26, 24,  6,  0,  1,TNUM_SLIDE_ON, BT_MOUSE_BUTTON, 255 },
  522.     {  6,180, 54, 59, 26,  5,  7,  1,  4,TNUM_SLIDE_LEFT, BT_MOUSE_BUTTON, 255 },
  523.     {  7,180, 62, 59, 26,  6,  8,  4, 26,TNUM_SLIDE_RIGHT, BT_MOUSE_BUTTON, 255 },
  524.     {  8,180, 70, 59, 26,  7,  9, 26,  9,TNUM_SLIDE_UP, BT_MOUSE_BUTTON, 255 },
  525.     {  9,180, 78, 59, 26,  8, 10,  8,  2,TNUM_SLIDE_DOWN, BT_MOUSE_BUTTON, 255 },
  526.     { 10,180, 90, 59, 26,  9, 11,  2,  3,TNUM_BANK_ON, BT_MOUSE_BUTTON, 255 },
  527.     { 11,180, 98, 59, 26, 10, 12,  3, 12,TNUM_BANK_LEFT, BT_MOUSE_BUTTON, 255 },
  528.     { 12,180,106, 59, 26, 11,  0, 11, 25,TNUM_BANK_RIGHT, BT_MOUSE_BUTTON, 255 },
  529.     { 13,103,138, 58, 26, 25, 15, 25, 14,TNUM_PITCH_UD, BT_MOUSE_AXIS, 255 },
  530.     { 14,103,138,106,  8, 23, 16, 13, 15,TNUM_PITCH_UD, BT_INVERT, 255 },
  531.     { 15,103,146, 58, 26, 13, 17, 14, 16,TNUM_TURN_LR, BT_MOUSE_AXIS, 255 },
  532.     { 16,103,146,106,  8, 14, 18, 15, 17,TNUM_TURN_LR, BT_INVERT, 255 },
  533.     { 17,103,154, 58, 26, 15, 19, 16, 18,TNUM_SLIDE_LR, BT_MOUSE_AXIS, 255 },
  534.     { 18,103,154,106,  8, 16, 20, 17, 19,TNUM_SLIDE_LR, BT_INVERT, 255 },
  535.     { 19,103,162, 58, 26, 17, 21, 18, 20,TNUM_SLIDE_UD, BT_MOUSE_AXIS, 255 },
  536.     { 20,103,162,106,  8, 18, 22, 19, 21,TNUM_SLIDE_UD, BT_INVERT, 255 },
  537.     { 21,103,170, 58, 26, 19, 23, 20, 22,TNUM_BANK_LR, BT_MOUSE_AXIS, 255 },
  538.     { 22,103,170,106,  8, 20, 24, 21, 23,TNUM_BANK_LR, BT_INVERT, 255 },
  539.     { 23,103,182, 58, 26, 21, 14, 22, 24,TNUM_THROTTLE, BT_MOUSE_AXIS, 255 },
  540.     { 24,103,182,106,  8, 22,  5, 23,  0,TNUM_THROTTLE, BT_INVERT, 255 },
  541.     { 25, 25,109, 85, 26,  3, 13, 12, 13,TNUM_REAR_VIEW, BT_MOUSE_BUTTON, 255 },
  542.     { 26, 25, 70, 85, 26,  4,  2,  7,  8,TNUM_DROP_BOMB, BT_MOUSE_BUTTON, 255 },
  543. };
  544.  
  545. int kconfig_is_axes_used(int axis)
  546. {
  547.     int i;
  548.     for (i=0; i<NUM_OTHER_CONTROLS; i++ )    {
  549.         if (( kc_joystick[i].type == BT_JOY_AXIS ) && (kc_joystick[i].value == axis ))
  550.             return 1;
  551.     }
  552.     return 0;
  553. }
  554.  
  555. #ifdef TABLE_CREATION
  556. int find_item_at( kc_item * items, int nitems, int x, int y )
  557. {
  558.     int i;
  559.     
  560.     for (i=0; i<nitems; i++ )    {
  561.         if ( ((items[i].x+items[i].w1)==x) && (items[i].y==y))
  562.             return i;
  563.     }
  564.     return -1;
  565. }
  566.  
  567. int find_next_item_up( kc_item * items, int nitems, int citem )
  568. {
  569.     int x, y, i;
  570.  
  571.     y = items[citem].y;
  572.     x = items[citem].x+items[citem].w1;
  573.     
  574.     do {    
  575.         y--;
  576.         if ( y < 0 ) {
  577.             y = grd_curcanv->cv_bitmap.bm_h-1;
  578.             x--;
  579.             if ( x < 0 ) {
  580.                 x = grd_curcanv->cv_bitmap.bm_w-1;
  581.             }
  582.         }
  583.         i = find_item_at( items, nitems, x, y );
  584.     } while ( i < 0 );
  585.     
  586.     return i;
  587. }
  588.  
  589. int find_next_item_down( kc_item * items, int nitems, int citem )
  590. {
  591.     int x, y, i;
  592.  
  593.     y = items[citem].y;
  594.     x = items[citem].x+items[citem].w1;
  595.     
  596.     do {    
  597.         y++;
  598.         if ( y > grd_curcanv->cv_bitmap.bm_h-1 ) {
  599.             y = 0;
  600.             x++;
  601.             if ( x > grd_curcanv->cv_bitmap.bm_w-1 ) {
  602.                 x = 0;
  603.             }
  604.         }
  605.         i = find_item_at( items, nitems, x, y );
  606.     } while ( i < 0 );
  607.     
  608.     return i;
  609. }
  610.  
  611. int find_next_item_right( kc_item * items, int nitems, int citem )
  612. {
  613.     int x, y, i;
  614.  
  615.     y = items[citem].y;
  616.     x = items[citem].x+items[citem].w1;
  617.     
  618.     do {    
  619.         x++;
  620.         if ( x > grd_curcanv->cv_bitmap.bm_w-1 ) {
  621.             x = 0;
  622.             y++;
  623.             if ( y > grd_curcanv->cv_bitmap.bm_h-1 ) {
  624.                 y = 0;
  625.             }
  626.         }
  627.         i = find_item_at( items, nitems, x, y );
  628.     } while ( i < 0 );
  629.     
  630.     return i;
  631. }
  632.  
  633. int find_next_item_left( kc_item * items, int nitems, int citem )
  634. {
  635.     int x, y, i;
  636.  
  637.     y = items[citem].y;
  638.     x = items[citem].x+items[citem].w1;
  639.     
  640.     do {    
  641.         x--;
  642.         if ( x < 0 ) {
  643.             x = grd_curcanv->cv_bitmap.bm_w-1;
  644.             y--;
  645.             if ( y < 0 ) {
  646.                 y = grd_curcanv->cv_bitmap.bm_h-1;
  647.             }
  648.         }
  649.         i = find_item_at( items, nitems, x, y );
  650.     } while ( i < 0 );
  651.     
  652.     return i;
  653. }
  654. #endif
  655.  
  656.  
  657.  
  658. void kconfig_sub(kc_item * items,int nitems, char * title)
  659. {
  660.     grs_canvas * save_canvas;
  661.     grs_font * save_font;
  662.     int old_keyd_repeat;
  663.  
  664.     int i,k,ocitem,citem;
  665.     int time_stopped = 0;
  666.  
  667.  
  668.     All_items = items;
  669.     Num_items = nitems;
  670.  
  671.     if (!((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME) && (!Endlevel_sequence)) )
  672.     {
  673.         time_stopped = 1;
  674.         stop_time();
  675.     }
  676.  
  677.     save_canvas = grd_curcanv;
  678.     gr_set_current_canvas( NULL );            
  679.     save_font = grd_curcanv->cv_font;
  680.     game_flush_inputs();
  681.     old_keyd_repeat = keyd_repeat;
  682.     keyd_repeat = 1;
  683.  
  684.     //gr_clear_canvas( BM_XRGB(0,0,0) );
  685.  
  686.     nm_draw_background(0,0,grd_curcanv->cv_bitmap.bm_w, grd_curcanv->cv_bitmap.bm_h );
  687.  
  688.     grd_curcanv->cv_font = Gamefonts[GFONT_MEDIUM_3];
  689.  
  690.     {
  691.         char * p;
  692.         p = strchr( title, '\n' );
  693.         if ( p ) *p = 32;
  694.         gr_string( 0x8000, 8, title );
  695.         if ( p ) *p = '\n';
  696.     }
  697.  
  698.  
  699. //    if ( items == kc_keyboard )    {
  700. //        gr_string( 0x8000, 8, "Keyboard" );
  701. //    } else if ( items == kc_joystick )    {
  702. //        gr_string( 0x8000, 8, "Joysticks" );
  703. //    } else if ( items == kc_mouse )    {
  704. //        gr_string( 0x8000, 8, "Mouse" );
  705. //    }
  706.  
  707.     grd_curcanv->cv_font = GAME_FONT;
  708.     gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
  709.  
  710.     gr_string( 0x8000, 20, TXT_KCONFIG_STRING_1 );
  711.     gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
  712.     if ( items == kc_keyboard )    {
  713.         gr_set_fontcolor( BM_XRGB(31,27,6), -1 );
  714.         gr_setcolor( BM_XRGB(31,27,6) );
  715.         
  716.         gr_scanline( 98, 106, 42 );
  717.         gr_scanline( 120, 128, 42 );
  718.         gr_pixel( 98, 43 );                        
  719.         gr_pixel( 98, 44 );                        
  720.         gr_pixel( 128, 43 );                        
  721.         gr_pixel( 128, 44 );                        
  722.         
  723.         gr_string( 109, 40, "OR" );
  724.  
  725.         gr_scanline( 253, 261, 42 );
  726.         gr_scanline( 274, 283, 42 );
  727.         gr_pixel( 253, 43 );                        
  728.         gr_pixel( 253, 44 );                        
  729.         gr_pixel( 283, 43 );                        
  730.         gr_pixel( 283, 44 );                        
  731.  
  732.         gr_string( 264, 40, "OR" );
  733.  
  734.     } if ( items == kc_joystick )    {
  735.         gr_set_fontcolor( BM_XRGB(31,27,6), -1 );
  736.         gr_setcolor( BM_XRGB(31,27,6) );
  737.         gr_scanline( 18, 135, 37 );
  738.         gr_scanline( 181, 294, 37 );
  739.         gr_scanline( 18, 144, 119+10 );
  740.         gr_scanline( 174, 294, 119+10 );
  741.         gr_string( 0x8000, 35, TXT_BUTTONS );
  742.         gr_string( 0x8000,117+10, TXT_AXES );
  743.         gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
  744.         gr_string( 81, 137, TXT_AXIS );
  745.         gr_string( 111, 137, TXT_INVERT );
  746.         gr_string( 222, 137, TXT_AXIS );
  747.         gr_string( 252, 137, TXT_INVERT );
  748.     } else if ( items == kc_mouse )    {
  749.         gr_set_fontcolor( BM_XRGB(31,27,6), -1 );
  750.         gr_setcolor( BM_XRGB(31,27,6) );
  751.         gr_scanline( 18, 135, 37 );
  752.         gr_scanline( 181, 294, 37 );
  753.         gr_scanline( 18, 144, 119+5 );
  754.         gr_scanline( 174, 294, 119+5 );
  755.         gr_string( 0x8000, 35, TXT_BUTTONS );
  756.         gr_string( 0x8000,117+5, TXT_AXES );
  757.         gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
  758.         gr_string( 169, 129, TXT_AXIS );
  759.         gr_string( 199, 129, TXT_INVERT );
  760.     }
  761.     
  762.     for (i=0; i<nitems; i++ )    {
  763.         kc_drawitem( &items[i], 0 );
  764.     }
  765.  
  766.     citem = 0;
  767.     kc_drawitem( &items[citem], 1 );
  768.  
  769.     while(1)        {
  770.         k = key_inkey();
  771.         if ( !time_stopped ) {
  772.             #ifdef NETWORK
  773.             if (multi_menu_poll() == -1)
  774.                 k = -2;
  775.             #endif
  776.         }
  777.         ocitem = citem;
  778.         switch( k )    {
  779.         case KEY_BACKSP:
  780.             Int3();
  781.             break;
  782.         case KEY_PRINT_SCREEN:
  783.             save_screen_shot(0);
  784.             break;                            
  785.         case KEY_CTRLED+KEY_D:
  786.             items[citem].value = 255;
  787.             kc_drawitem( &items[citem], 1 );
  788.             break;
  789.         case KEY_CTRLED+KEY_R:    
  790.             if ( items==kc_keyboard )    {
  791.                 for (i=0; i<NUM_KEY_CONTROLS; i++ )        {
  792.                     items[i].value=default_kconfig_settings[0][i];
  793.                     kc_drawitem( &items[i], 0 );
  794.                 }
  795.             } else {
  796.                 for (i=0; i<NUM_OTHER_CONTROLS; i++ )    {
  797.                     items[i].value = default_kconfig_settings[Config_control_type][i];
  798.                     kc_drawitem( &items[i], 0 );
  799.                 }
  800.             }
  801.             kc_drawitem( &items[citem], 1 );
  802.             break;
  803.         case KEY_UP:         
  804.         case KEY_PAD8:
  805. #ifdef TABLE_CREATION
  806.             if (items[citem].u==-1) items[citem].u=find_next_item_up( items,nitems, citem);
  807. #endif
  808.             citem = items[citem].u; 
  809.             break;
  810.         case KEY_DOWN:     
  811.         case KEY_PAD2:
  812. #ifdef TABLE_CREATION
  813.             if (items[citem].d==-1) items[citem].d=find_next_item_down( items,nitems, citem);
  814. #endif
  815.             citem = items[citem].d; 
  816.             break;
  817.         case KEY_LEFT:     
  818.         case KEY_PAD4:
  819. #ifdef TABLE_CREATION
  820.             if (items[citem].l==-1) items[citem].l=find_next_item_left( items,nitems, citem);
  821. #endif
  822.             citem = items[citem].l; 
  823.             break;
  824.         case KEY_RIGHT:     
  825.         case KEY_PAD6:
  826. #ifdef TABLE_CREATION
  827.             if (items[citem].r==-1) items[citem].r=find_next_item_right( items,nitems, citem);
  828. #endif
  829.             citem = items[citem].r; 
  830.             break;
  831.         case KEY_ENTER:    
  832.         case KEY_PADENTER:    
  833.             switch( items[citem].type )    {
  834.             case BT_KEY:                kc_change_key( &items[citem] ); break;
  835.             case BT_MOUSE_BUTTON:    kc_change_mousebutton( &items[citem] ); break;
  836.             case BT_MOUSE_AXIS:         kc_change_mouseaxis( &items[citem] ); break;
  837.             case BT_JOY_BUTTON:         kc_change_joybutton( &items[citem] ); break;
  838.             case BT_JOY_AXIS:         kc_change_joyaxis( &items[citem] ); break;
  839.             case BT_INVERT:             kc_change_invert( &items[citem] ); break;
  840.             }
  841.             break;
  842.         case -2:    
  843.         case KEY_ESC:
  844.             grd_curcanv->cv_font    = save_font;
  845.             gr_set_current_canvas( save_canvas );            
  846.             keyd_repeat = old_keyd_repeat;
  847.             game_flush_inputs();
  848.             if (time_stopped)
  849.                 start_time();
  850.             return;
  851. #ifdef TABLE_CREATION
  852.         case KEY_DEBUGGED+KEY_F12:    {
  853.             FILE * fp;
  854.             for (i=0; i<NUM_KEY_CONTROLS; i++ )    {
  855.                 kc_keyboard[i].u = find_next_item_up( kc_keyboard,NUM_KEY_CONTROLS, i);
  856.                 kc_keyboard[i].d = find_next_item_down( kc_keyboard,NUM_KEY_CONTROLS, i);
  857.                 kc_keyboard[i].l = find_next_item_left( kc_keyboard,NUM_KEY_CONTROLS, i);
  858.                 kc_keyboard[i].r = find_next_item_right( kc_keyboard,NUM_KEY_CONTROLS, i);
  859.             }
  860.             for (i=0; i<NUM_OTHER_CONTROLS; i++ )    {
  861.                 kc_joystick[i].u = find_next_item_up( kc_joystick,NUM_OTHER_CONTROLS, i);
  862.                 kc_joystick[i].d = find_next_item_down( kc_joystick,NUM_OTHER_CONTROLS, i);
  863.                 kc_joystick[i].l = find_next_item_left( kc_joystick,NUM_OTHER_CONTROLS, i);
  864.                 kc_joystick[i].r = find_next_item_right( kc_joystick,NUM_OTHER_CONTROLS, i);
  865.             }
  866.             for (i=0; i<NUM_OTHER_CONTROLS; i++ )    {
  867.                 kc_mouse[i].u = find_next_item_up( kc_mouse,NUM_OTHER_CONTROLS, i);
  868.                 kc_mouse[i].d = find_next_item_down( kc_mouse,NUM_OTHER_CONTROLS, i);
  869.                 kc_mouse[i].l = find_next_item_left( kc_mouse,NUM_OTHER_CONTROLS, i);
  870.                 kc_mouse[i].r = find_next_item_right( kc_mouse,NUM_OTHER_CONTROLS, i);
  871.             }
  872.             fp = fopen( "kconfig.cod", "wt" );
  873.  
  874.             fprintf( fp, "ubyte default_kconfig_settings[CONTROL_MAX_TYPES][MAX_CONTROLS] = {\n" );
  875.             for (i=0; i<CONTROL_MAX_TYPES; i++ )    {
  876.                 int j;
  877.                 fprintf( fp, "{0x%x", kconfig_settings[i][0] );
  878.                 for (j=1; j<MAX_CONTROLS; j++ )
  879.                     fprintf( fp, ",0x%x", kconfig_settings[i][j] );
  880.                 fprintf( fp, "},\n" );
  881.             }
  882.             fprintf( fp, "};\n" );
  883.         
  884.             fprintf( fp, "\nkc_item kc_keyboard[NUM_KEY_CONTROLS] = {\n" );
  885.             for (i=0; i<NUM_KEY_CONTROLS; i++ )    {
  886.                 fprintf( fp, "\t{ %2d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%c%s%c, %s, 255 },\n", 
  887.                     kc_keyboard[i].id, kc_keyboard[i].x, kc_keyboard[i].y, kc_keyboard[i].w1, kc_keyboard[i].w2,
  888.                     kc_keyboard[i].u, kc_keyboard[i].d, kc_keyboard[i].l, kc_keyboard[i].r,
  889.                     34, Text_string[kc_keyboard[i].text_num1], 34, btype_text[kc_keyboard[i].type] );
  890.             }
  891.             fprintf( fp, "};" );
  892.  
  893.             fprintf( fp, "\nkc_item kc_joystick[NUM_OTHER_CONTROLS] = {\n" );
  894.             for (i=0; i<NUM_OTHER_CONTROLS; i++ )    {
  895.                 fprintf( fp, "\t{ %2d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%c%s%c, %s, 255 },\n", 
  896.                     kc_joystick[i].id, kc_joystick[i].x, kc_joystick[i].y, kc_joystick[i].w1, kc_joystick[i].w2,
  897.                     kc_joystick[i].u, kc_joystick[i].d, kc_joystick[i].l, kc_joystick[i].r,
  898.                     34, Text_string[kc_joystick[i].text_num1], 34, btype_text[kc_joystick[i].type] );
  899.             }
  900.             fprintf( fp, "};" );
  901.  
  902.             fprintf( fp, "\nkc_item kc_mouse[NUM_OTHER_CONTROLS] = {\n" );
  903.             for (i=0; i<NUM_OTHER_CONTROLS; i++ )    {
  904.                 fprintf( fp, "\t{ %2d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%c%s%c, %s, 255 },\n", 
  905.                     kc_mouse[i].id, kc_mouse[i].x, kc_mouse[i].y, kc_mouse[i].w1, kc_mouse[i].w2,
  906.                     kc_mouse[i].u, kc_mouse[i].d, kc_mouse[i].l, kc_mouse[i].r,
  907.                     34, Text_string[kc_mouse[i].text_num1], 34, btype_text[kc_mouse[i].type] );
  908.             }
  909.             fprintf( fp, "};" );
  910.  
  911.             fclose(fp);
  912.  
  913.             }
  914.             break;
  915. #endif
  916.         }
  917.         if (ocitem!=citem)    {
  918.             kc_drawitem( &items[ocitem], 0 );
  919.             kc_drawitem( &items[citem], 1 );
  920.         }
  921.     }
  922. }
  923.  
  924.  
  925. void kc_drawitem( kc_item *item, int is_current )
  926. {
  927.     int x, w, h, aw;
  928.     char btext[10];
  929.  
  930.     if (is_current)
  931.         gr_set_fontcolor( BM_XRGB(20,20,29), -1 );
  932.     else
  933.         gr_set_fontcolor( BM_XRGB(15,15,24), -1 );
  934.     gr_string( item->x, item->y, Text_string[item->text_num1] );
  935.  
  936.     if (item->value==255) {
  937.         sprintf( btext, "" );
  938.     } else {
  939.         switch( item->type )    {
  940.             case BT_KEY:
  941.                 strncpy( btext, key_text[item->value], 10 ); break;
  942.             case BT_MOUSE_BUTTON:
  943.                 strncpy( btext, Text_string[mousebutton_text[item->value]], 10 ); break;
  944.             case BT_MOUSE_AXIS:
  945.                 strncpy( btext, Text_string[mouseaxis_text[item->value]], 10 ); break;
  946.             case BT_JOY_BUTTON:
  947.                 if ( joybutton_text[item->value] !=-1 )
  948.                     strncpy( btext, Text_string[ joybutton_text[item->value]  ], 10 );
  949.                 else
  950.                     sprintf( btext, "BTN%d", item->value );
  951.                 break;
  952.             case BT_JOY_AXIS:
  953.                 strncpy( btext, Text_string[joyaxis_text[item->value]], 10 ); break;
  954.             case BT_INVERT:
  955.                 strncpy( btext, Text_string[invert_text[item->value]], 10 ); break;
  956.         }
  957.     }
  958.     gr_get_string_size(btext, &w, &h, &aw  );
  959.  
  960.     if (is_current)
  961.         gr_setcolor( BM_XRGB(21,0,24) );
  962.     else
  963.         gr_setcolor( BM_XRGB(16,0,19) );
  964.     gr_urect( item->w1+item->x, item->y-1, item->w1+item->x+item->w2, item->y+h );
  965.     
  966.     gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
  967.  
  968.     x = item->w1+item->x+((item->w2-w)/2);
  969.  
  970.     gr_string( x, item->y, btext );
  971. }
  972.  
  973.  
  974. static int looper=0;
  975.  
  976. void kc_drawquestion( kc_item *item )
  977. {
  978.     int c, x, w, h, aw;
  979.     
  980.     gr_get_string_size("?", &w, &h, &aw  );
  981.  
  982.     c = BM_XRGB(21,0,24);
  983.  
  984.     gr_setcolor( gr_fade_table[fades[looper]*256+c] );
  985.     looper++;
  986.     if (looper>63) looper=0;
  987.  
  988.     gr_urect( item->w1+item->x, item->y-1, item->w1+item->x+item->w2, item->y+h );
  989.     
  990.     gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
  991.  
  992.     x = item->w1+item->x+((item->w2-w)/2);
  993.  
  994.     gr_string( x, item->y, "?" );
  995. }
  996.  
  997. void kc_change_key( kc_item * item )
  998. {
  999.     int i,n,f,k;
  1000.     ubyte keycode;
  1001.  
  1002.     gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
  1003.     
  1004.     gr_string( 0x8000, INFO_Y, TXT_PRESS_NEW_KEY );
  1005.     
  1006.     game_flush_inputs();
  1007.     keycode=255;
  1008.     k=255;
  1009.     while( (k!=KEY_ESC) && (keycode==255) )    {                
  1010.         #ifdef NETWORK
  1011.         if ((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME) && (!Endlevel_sequence))
  1012.             multi_menu_poll();
  1013.         #endif
  1014. //        if ( Game_mode & GM_MULTI )
  1015. //            GameLoop( 0, 0 );                // Continue
  1016.         k = key_inkey();
  1017.         delay(10);
  1018.         kc_drawquestion( item );
  1019.     
  1020.         for (i=0; i<256; i++ )    {
  1021.             if (keyd_pressed[i] && (strlen(key_text[i])>0))    {
  1022.                 f = 0;
  1023.                 for (n=0; n<sizeof(system_keys); n++ )
  1024.                     if ( system_keys[n] == i )
  1025.                         f=1;
  1026.                 if (!f)    
  1027.                     keycode=i;
  1028.             }
  1029.         }
  1030.     }
  1031.  
  1032.     if (k!=KEY_ESC)    {
  1033.         for (i=0; i<Num_items; i++ )    {
  1034.             n = item - All_items;
  1035.             if ( (i!=n) && (All_items[i].type==BT_KEY) && (All_items[i].value==keycode) )        {
  1036.                 All_items[i].value = 255;
  1037.                 kc_drawitem( &All_items[i], 0 );
  1038.             }
  1039.         }
  1040.         item->value = keycode;
  1041.     }
  1042.     kc_drawitem( item, 1 );
  1043.     gr_set_fontcolor( BM_XRGB(28,28,28), BM_XRGB(0,0,0) );
  1044.  
  1045.     nm_restore_background( 0, INFO_Y, 310, grd_curcanv->cv_font->ft_h );
  1046.  
  1047.     game_flush_inputs();
  1048.  
  1049. }
  1050.  
  1051. void kc_change_joybutton( kc_item * item )
  1052. {
  1053.     int n,i,k;
  1054.     ubyte code;
  1055.  
  1056.     gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
  1057.     
  1058.     gr_string( 0x8000, INFO_Y, TXT_PRESS_NEW_JBUTTON );
  1059.     
  1060.     game_flush_inputs();
  1061.     code=255;
  1062.     k=255;
  1063.     while( (k!=KEY_ESC) && (code==255))    {                
  1064.         #ifdef NETWORK
  1065.         if ((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME) && (!Endlevel_sequence))
  1066.             multi_menu_poll();
  1067.         #endif
  1068. //        if ( Game_mode & GM_MULTI )
  1069. //            GameLoop( 0, 0 );                // Continue
  1070.         k = key_inkey();
  1071.         delay(10);
  1072.  
  1073.         if (k == KEY_PRINT_SCREEN)
  1074.             save_screen_shot(0);
  1075.  
  1076.         kc_drawquestion( item );
  1077.  
  1078.         if (Config_control_type==CONTROL_THRUSTMASTER_FCS)    {
  1079.             int axis[4];
  1080.             joystick_read_raw_axis( JOY_ALL_AXIS, axis );
  1081.             kconfig_read_fcs( axis[3] );
  1082.             if ( joy_get_button_state(7) ) code = 7;
  1083.             if ( joy_get_button_state(11) ) code = 11;
  1084.             if ( joy_get_button_state(15) ) code = 15;
  1085.             if ( joy_get_button_state(19) ) code = 19;
  1086.             for (i=0; i<4; i++ )    {
  1087.                 if ( joy_get_button_state(i) )
  1088.                     code = i;
  1089.             }
  1090.         } else if (Config_control_type==CONTROL_FLIGHTSTICK_PRO) {
  1091.             for (i=4; i<20; i++ )    {
  1092.                 if ( joy_get_button_state(i)  )    {
  1093.                     code = i;
  1094.                     mprintf(( 0, "JB: %d\n", code ));
  1095.                 }
  1096.             }
  1097.         } else {
  1098.             for (i=0; i<4; i++ )    {
  1099.                 if ( joy_get_button_state(i) )
  1100.                     code = i;
  1101.             }
  1102.         }
  1103.     }
  1104.     if (code!=255)    {
  1105.         for (i=0; i<Num_items; i++ )    {
  1106.             n = item - All_items;
  1107.             if ( (i!=n) && (All_items[i].type==BT_JOY_BUTTON) && (All_items[i].value==code) )        {
  1108.                 All_items[i].value = 255;
  1109.                 kc_drawitem( &All_items[i], 0 );
  1110.             }
  1111.         }
  1112.         item->value = code;
  1113.     }
  1114.     kc_drawitem( item, 1 );
  1115.     nm_restore_background( 0, INFO_Y, 310, grd_curcanv->cv_font->ft_h );
  1116.     game_flush_inputs();
  1117. }
  1118.  
  1119. void kc_change_mousebutton( kc_item * item )
  1120. {
  1121.     int n,i,b,k;
  1122.     ubyte code;
  1123.  
  1124.     gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
  1125.     
  1126.     gr_string( 0x8000, INFO_Y, TXT_PRESS_NEW_MBUTTON );
  1127.     
  1128.     game_flush_inputs();
  1129.     code=255;
  1130.     k=255;
  1131.     while( (k!=KEY_ESC) && (code==255))    {                
  1132.         #ifdef NETWORK
  1133.         if ((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME) && (!Endlevel_sequence))
  1134.             multi_menu_poll();
  1135.         #endif
  1136. //        if ( Game_mode & GM_MULTI )
  1137. //            GameLoop( 0, 0 );                // Continue
  1138.         k = key_inkey();
  1139.         delay(10);
  1140.  
  1141.         if (k == KEY_PRINT_SCREEN)
  1142.             save_screen_shot(0);
  1143.  
  1144.         kc_drawquestion( item );
  1145.  
  1146.         b = mouse_get_btns();
  1147.         for (i=0; i<3; i++ )    {
  1148.             if ( b & (1<<i) )    
  1149.                 code = i;
  1150.         }
  1151.     }
  1152.     if (code!=255)    {
  1153.         for (i=0; i<Num_items; i++ )    {
  1154.             n = item - All_items;
  1155.             if ( (i!=n) && (All_items[i].type==BT_MOUSE_BUTTON) && (All_items[i].value==code) )        {
  1156.                 All_items[i].value = 255;
  1157.                 kc_drawitem( &All_items[i], 0 );
  1158.             }
  1159.         }
  1160.         item->value = code;
  1161.     }
  1162.     kc_drawitem( item, 1 );
  1163.     nm_restore_background( 0, INFO_Y, 310, grd_curcanv->cv_font->ft_h );
  1164.     game_flush_inputs();
  1165.  
  1166. }
  1167.  
  1168. void kc_change_joyaxis( kc_item * item )
  1169. {
  1170.     int axis[4];
  1171.     int old_axis[4];
  1172.     int n,i,k;
  1173.     ubyte code;
  1174.  
  1175.     gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
  1176.     
  1177.     gr_string( 0x8000, INFO_Y, TXT_MOVE_NEW_JOY_AXIS );
  1178.     
  1179.     game_flush_inputs();
  1180.     code=255;
  1181.     k=255;
  1182.  
  1183.     joystick_read_raw_axis( JOY_ALL_AXIS, old_axis );
  1184.  
  1185.     while( (k!=KEY_ESC) && (code==255))    {                
  1186.         #ifdef NETWORK
  1187.         if ((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME) && (!Endlevel_sequence))
  1188.             multi_menu_poll();
  1189.         #endif
  1190. //        if ( Game_mode & GM_MULTI )
  1191. //            GameLoop( 0, 0 );                // Continue
  1192.         k = key_inkey();
  1193.         delay(10);
  1194.  
  1195.         if (k == KEY_PRINT_SCREEN)
  1196.             save_screen_shot(0);
  1197.  
  1198.         kc_drawquestion( item );
  1199.  
  1200.         joystick_read_raw_axis( JOY_ALL_AXIS, axis );
  1201.         
  1202.         for (i=0; i<4; i++ )    {
  1203.               if ( abs(axis[i]-old_axis[i])>20 )    {
  1204.                 code = i;
  1205.             }
  1206.             old_axis[i] = axis[i];
  1207.         }
  1208.     }
  1209.     if (code!=255)    {
  1210.         for (i=0; i<Num_items; i++ )    {
  1211.             n = item - All_items;
  1212.             if ( (i!=n) && (All_items[i].type==BT_JOY_AXIS) && (All_items[i].value==code) )        {
  1213.                 All_items[i].value = 255;
  1214.                 kc_drawitem( &All_items[i], 0 );
  1215.             }
  1216.         }
  1217.  
  1218.         item->value = code;                     
  1219.     }
  1220.     kc_drawitem( item, 1 );
  1221.     nm_restore_background( 0, INFO_Y, 310, grd_curcanv->cv_font->ft_h );
  1222.     game_flush_inputs();
  1223.  
  1224. }
  1225.  
  1226. void kc_change_mouseaxis( kc_item * item )
  1227. {
  1228.     int i,n,k;
  1229.     ubyte code;
  1230.     int dx,dy;
  1231.  
  1232.     gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
  1233.     
  1234.     gr_string( 0x8000, INFO_Y, TXT_MOVE_NEW_MSE_AXIS );
  1235.     
  1236.     game_flush_inputs();
  1237.     code=255;
  1238.     k=255;
  1239.  
  1240.     mouse_get_delta( &dx, &dy );
  1241.  
  1242.     while( (k!=KEY_ESC) && (code==255))    {                
  1243.         #ifdef NETWORK
  1244.         if ((Game_mode & GM_MULTI) && (Function_mode == FMODE_GAME) && (!Endlevel_sequence))
  1245.             multi_menu_poll();
  1246.         #endif
  1247. //        if ( Game_mode & GM_MULTI )
  1248. //            GameLoop( 0, 0 );                // Continue
  1249.         k = key_inkey();
  1250.         delay(10);
  1251.  
  1252.         if (k == KEY_PRINT_SCREEN)
  1253.             save_screen_shot(0);
  1254.  
  1255.         kc_drawquestion( item );
  1256.  
  1257.         mouse_get_delta( &dx, &dy );
  1258.         if ( abs(dx)>20 ) code = 0;
  1259.         if ( abs(dy)>20 )    code = 1;
  1260.     }
  1261.     if (code!=255)    {
  1262.         for (i=0; i<Num_items; i++ )    {
  1263.             n = item - All_items;
  1264.             if ( (i!=n) && (All_items[i].type==BT_MOUSE_AXIS) && (All_items[i].value==code) )        {
  1265.                 All_items[i].value = 255;
  1266.                 kc_drawitem( &All_items[i], 0 );
  1267.             }
  1268.         }
  1269.         item->value = code;
  1270.     }
  1271.     kc_drawitem( item, 1 );
  1272.     nm_restore_background( 0, INFO_Y, 310, grd_curcanv->cv_font->ft_h );
  1273.     game_flush_inputs();
  1274.  
  1275. }
  1276.  
  1277.  
  1278. void kc_change_invert( kc_item * item )
  1279. {
  1280.     game_flush_inputs();
  1281.  
  1282.     if (item->value)
  1283.         item->value = 0;
  1284.     else 
  1285.         item->value = 1;
  1286.  
  1287.     kc_drawitem( item, 1 );
  1288.  
  1289. }
  1290.  
  1291. #include "screens.h"
  1292.  
  1293. void kconfig(int n, char * title)
  1294. {
  1295.     int i;
  1296.     set_screen_mode( SCREEN_MENU );
  1297.  
  1298.     kc_set_controls();
  1299.  
  1300.     switch(n)    {
  1301.     case 0:kconfig_sub( kc_keyboard, NUM_KEY_CONTROLS, title );break;
  1302.     case 1:kconfig_sub( kc_joystick, NUM_OTHER_CONTROLS, title );break;
  1303.     case 2:kconfig_sub( kc_mouse, NUM_OTHER_CONTROLS, title ); break;
  1304.     default:
  1305.         Int3();
  1306.         return;
  1307.     }
  1308.  
  1309.     reset_cockpit();        //force cockpit redraw next time
  1310.  
  1311.     // Update save values...
  1312.     
  1313.     for (i=0; i<NUM_KEY_CONTROLS; i++ )    
  1314.         kconfig_settings[0][i] = kc_keyboard[i].value;
  1315.  
  1316.     if ( (Config_control_type>0) && (Config_control_type<5))    {
  1317.         for (i=0; i<NUM_OTHER_CONTROLS; i++ )    
  1318.             kconfig_settings[Config_control_type][i] = kc_joystick[i].value;
  1319.     } else if (Config_control_type>4) {
  1320.         for (i=0; i<NUM_OTHER_CONTROLS; i++ )    
  1321.             kconfig_settings[Config_control_type][i] = kc_mouse[i].value;
  1322.     }
  1323.  
  1324. }
  1325.  
  1326.  
  1327. void kconfig_read_fcs( int raw_axis )
  1328. {
  1329.     int raw_button, button, axis_min[4], axis_center[4], axis_max[4];
  1330.  
  1331.     if (Config_control_type!=CONTROL_THRUSTMASTER_FCS) return;
  1332.  
  1333.     joy_get_cal_vals(axis_min, axis_center, axis_max);
  1334.  
  1335.     if ( axis_max[3] > 1 )
  1336.         raw_button = (raw_axis*100)/axis_max[3];
  1337.     else
  1338.         raw_button = 0;
  1339.  
  1340.     if ( raw_button > 88 )
  1341.         button = 0;
  1342.     else if ( raw_button > 63 )
  1343.         button = 7;
  1344.     else if ( raw_button > 39 )
  1345.         button = 11;
  1346.     else if ( raw_button > 15 )
  1347.         button = 15;
  1348.     else    
  1349.         button = 19;
  1350.  
  1351.     kconfig_set_fcs_button( 19, button );
  1352.     kconfig_set_fcs_button( 15, button );
  1353.     kconfig_set_fcs_button( 11, button );
  1354.     kconfig_set_fcs_button( 7, button );
  1355. }
  1356.         
  1357.  
  1358. void kconfig_set_fcs_button( int btn, int button )
  1359. {
  1360.     int state,time_down,upcount,downcount;
  1361.     state = time_down = upcount = downcount = 0;
  1362.  
  1363.     if ( joy_get_button_state(btn) ) {
  1364.         if ( btn==button )    {
  1365.             state = 1;
  1366.             time_down = FrameTime;
  1367.         } else {
  1368.             upcount=1;
  1369.         }
  1370.     } else {
  1371.         if ( btn==button )    {
  1372.             state = 1;
  1373.             time_down = FrameTime;
  1374.             downcount=1;
  1375.         } else {
  1376.             upcount=1;
  1377.         }
  1378.     }                
  1379.             
  1380.     joy_set_btn_values( btn, state, time_down, downcount, upcount );
  1381.                     
  1382. }
  1383.  
  1384.  
  1385.  
  1386. fix Last_angles_p = 0;
  1387. fix Last_angles_b = 0;
  1388. fix Last_angles_h = 0;
  1389. ubyte Last_angles_read = 0;
  1390.  
  1391. extern int            VR_sensitivity;
  1392.                         
  1393. int VR_sense_range[3] = { 25, 50, 75 };
  1394.  
  1395. read_head_tracker()
  1396. {
  1397.     fix yaw, pitch, roll;
  1398.     int buttons;
  1399. //------ read vfx1 helmet --------
  1400.     if (vfx1_installed) {
  1401.         SenseGetData( sense_function1, DCHTD,&yaw,&pitch, &roll, &buttons);
  1402.     } else if (iglasses_headset_installed)    {
  1403.         iglasses_read_headset( &yaw, &pitch, &roll );
  1404.     } else if (Victor_headset_installed)   {
  1405.         victor_read_headset_filtered( &yaw, &pitch, &roll );
  1406.     } else {
  1407.         return;
  1408.     }
  1409.  
  1410.     Use_player_head_angles = 0;
  1411.     if ( Last_angles_read )    {
  1412.         fix yaw1 = yaw;
  1413.         
  1414.         yaw1 = yaw;
  1415.         if ( (Last_angles_h < (F1_0/4) ) && (yaw > ((F1_0*3)/4) ) )    
  1416.             yaw1 -= F1_0;
  1417.         else if ( (yaw < (F1_0/4) ) && (Last_angles_h > ((F1_0*3)/4) ) )    
  1418.             yaw1 += F1_0;
  1419.     
  1420.         Controls.pitch_time    += fixmul((pitch- Last_angles_p)*VR_sense_range[VR_sensitivity],FrameTime);
  1421.         Controls.heading_time+= fixmul((yaw1 -  Last_angles_h)*VR_sense_range[VR_sensitivity],FrameTime);
  1422.         Controls.bank_time    += fixmul((roll - Last_angles_b)*VR_sense_range[VR_sensitivity],FrameTime);
  1423.     }
  1424.     Last_angles_read = 1;
  1425.     Last_angles_p = pitch;
  1426.     Last_angles_h = yaw;
  1427.     Last_angles_b = roll;
  1428. }
  1429.  
  1430. #define    PH_SCALE    8
  1431. #define    JOYSTICK_READ_TIME    (F1_0/10)        //    Read joystick at 10 Hz.
  1432. fix    LastReadTime = 0;
  1433.  
  1434. fix    joy_axis[4];
  1435.  
  1436. ubyte             kc_use_external_control = 0;
  1437. ubyte                kc_enable_external_control = 1;
  1438. ubyte             kc_external_intno = 0;
  1439. control_info    *kc_external_control = NULL;
  1440. ubyte                *kc_external_name = NULL;
  1441. ubyte                kc_external_version = 0;
  1442.  
  1443. void kconfig_init_external_controls(int intno, int address)
  1444. {
  1445.     int i;
  1446.     kc_external_intno = intno;
  1447.     kc_external_control    = (control_info *)address;
  1448.     kc_use_external_control = 1;
  1449.     kc_enable_external_control  = 1;
  1450.  
  1451.     i = FindArg( "-xname" );
  1452.     if ( i )    
  1453.         kc_external_name = Args[i+1];
  1454.     else
  1455.         kc_external_name = "External Controller";
  1456.  
  1457.     i = FindArg( "-xver" );
  1458.     if ( i )
  1459.         kc_external_version = atoi(Args[i+1]);
  1460.     
  1461.     printf( "%s int: 0x%x, data: 0x%x, ver:%d\n", kc_external_name, kc_external_intno, kc_external_control, kc_external_version );
  1462.  
  1463. }
  1464.  
  1465. void kconfig_read_external_controls()
  1466. {
  1467.     union REGS r;
  1468.  
  1469.     if ( !kc_enable_external_control ) return;
  1470.  
  1471.     if ( kc_external_version == 0 ) 
  1472.         memset( kc_external_control, 0, sizeof(control_info) );
  1473.     else if ( kc_external_version > 0 )     {
  1474.         memset( kc_external_control, 0, sizeof(control_info)+sizeof(vms_angvec) + 64 );
  1475.         if ( kc_external_version > 1 ) {
  1476.             // Write ship pos and angles to external controls...
  1477.             ubyte *temp_ptr = (ubyte *)kc_external_control;
  1478.             vms_vector *ship_pos;
  1479.             vms_matrix *ship_orient;
  1480.             memset( kc_external_control, 0, sizeof(control_info)+sizeof(vms_angvec) + 64 + sizeof(vms_vector)+sizeof(vms_matrix) );
  1481.             temp_ptr += sizeof(control_info)+sizeof(vms_angvec) + 64;
  1482.             ship_pos = (vms_vector *)temp_ptr;
  1483.             temp_ptr += sizeof(vms_vector);
  1484.             ship_orient = (vms_matrix *)temp_ptr;
  1485.             // Fill in ship postion...
  1486.             *ship_pos = Objects[Players[Player_num].objnum].pos;
  1487.             // Fill in ship orientation...
  1488.             *ship_orient = Objects[Players[Player_num].objnum].orient;
  1489.         }
  1490.     }
  1491.  
  1492.     if ( grd_curscreen->sc_mode != SM_320x200C )            // (If in automap...)
  1493.         kc_external_control->automap_state = 1;
  1494.     memset(&r,0,sizeof(r));
  1495.  
  1496.     int386 ( kc_external_intno, &r, &r);        // Read external info...
  1497.  
  1498.     if ( Player_num > -1 )    {
  1499.         Objects[Players[Player_num].objnum].mtype.phys_info.flags &= (~PF_TURNROLL);    // Turn off roll when turning
  1500.         Objects[Players[Player_num].objnum].mtype.phys_info.flags &= (~PF_LEVELLING);    // Turn off leveling to nearest side.
  1501.         Auto_leveling_on = 0;
  1502.  
  1503.         if ( kc_external_version > 0 ) {        
  1504.             vms_matrix tempm, ViewMatrix;
  1505.             vms_angvec * Kconfig_abs_movement;
  1506.             char * oem_message;
  1507.     
  1508.             Kconfig_abs_movement = (vms_angvec *)((uint)kc_external_control + sizeof(control_info));
  1509.     
  1510.             if ( Kconfig_abs_movement->p || Kconfig_abs_movement->b || Kconfig_abs_movement->h )    {
  1511.                 vm_angles_2_matrix(&tempm,Kconfig_abs_movement);
  1512.                 vm_matrix_x_matrix(&ViewMatrix,&Objects[Players[Player_num].objnum].orient,&tempm);
  1513.                 Objects[Players[Player_num].objnum].orient = ViewMatrix;        
  1514.             }
  1515.             oem_message = (char *)((uint)Kconfig_abs_movement + sizeof(vms_angvec));
  1516.             if (oem_message[0] != '\0' )
  1517.                 HUD_init_message( oem_message );
  1518.         }
  1519.     }
  1520.  
  1521.  
  1522.  
  1523.     Controls.pitch_time += fixmul(kc_external_control->pitch_time,FrameTime);                        
  1524.     Controls.vertical_thrust_time += fixmul(kc_external_control->vertical_thrust_time,FrameTime);
  1525.     Controls.heading_time += fixmul(kc_external_control->heading_time,FrameTime);
  1526.     Controls.sideways_thrust_time += fixmul(kc_external_control->sideways_thrust_time ,FrameTime);
  1527.     Controls.bank_time += fixmul(kc_external_control->bank_time ,FrameTime);
  1528.     Controls.forward_thrust_time += fixmul(kc_external_control->forward_thrust_time ,FrameTime);
  1529.     Controls.rear_view_down_count += kc_external_control->rear_view_down_count;    
  1530.     Controls.rear_view_down_state |= kc_external_control->rear_view_down_state;    
  1531.     Controls.fire_primary_down_count += kc_external_control->fire_primary_down_count;
  1532.     Controls.fire_primary_state |= kc_external_control->fire_primary_state;
  1533.     Controls.fire_secondary_state |= kc_external_control->fire_secondary_state;
  1534.     Controls.fire_secondary_down_count += kc_external_control->fire_secondary_down_count;
  1535.     Controls.fire_flare_down_count += kc_external_control->fire_flare_down_count;
  1536.     Controls.drop_bomb_down_count += kc_external_control->drop_bomb_down_count;    
  1537.     Controls.automap_down_count += kc_external_control->automap_down_count;
  1538.     Controls.automap_state |= kc_external_control->automap_state;
  1539. }
  1540.  
  1541. void controls_read_all()
  1542. {
  1543.     int i;
  1544.     int slide_on, bank_on;
  1545.     int dx, dy;
  1546.     int idx, idy;
  1547.     fix ctime;
  1548.     fix mouse_axis[2];
  1549.     int raw_joy_axis[4];
  1550.     int mouse_buttons;
  1551.     fix k0, k1, k2, k3, kp;
  1552.     fix k4, k5, k6, k7, kh;
  1553.     ubyte channel_masks;
  1554.     int use_mouse, use_joystick;
  1555.     int speed_factor=1;
  1556.  
  1557.     if (Game_turbo_mode)
  1558.         speed_factor = 2;
  1559.     
  1560.     if (Arcade_mode)    {
  1561.         arcade_read_controls();
  1562.         return;
  1563.     }
  1564.  
  1565.     {
  1566.         fix temp = Controls.heading_time;
  1567.         fix temp1 = Controls.pitch_time;
  1568.         memset( &Controls, 0, sizeof(control_info) );
  1569.         Controls.heading_time = temp;
  1570.         Controls.pitch_time = temp1;
  1571.     }
  1572.     slide_on = 0;
  1573.     bank_on = 0;
  1574.  
  1575.     ctime = timer_get_fixed_seconds();
  1576.  
  1577.     //---------  Read Joystick -----------
  1578.     if ( (LastReadTime + JOYSTICK_READ_TIME > ctime) && (Config_control_type!=CONTROL_THRUSTMASTER_FCS) ) {
  1579.         if ((ctime < 0) && (LastReadTime > 0))
  1580.             LastReadTime = ctime;
  1581.         use_joystick=1;
  1582.     } else if ((Config_control_type>0) && (Config_control_type<5) ) {
  1583.         LastReadTime = ctime;
  1584.         channel_masks = joystick_read_raw_axis( JOY_ALL_AXIS, raw_joy_axis );
  1585.         
  1586.         for (i=0; i<4; i++ )    {
  1587.             if (channel_masks&(1<<i))    {
  1588.                 int joy_null_value = 10;
  1589.  
  1590.                 if ( (i==3) && (Config_control_type==CONTROL_THRUSTMASTER_FCS) )    {
  1591.                     kconfig_read_fcs( raw_joy_axis[i] );
  1592.                 } else {
  1593.                     raw_joy_axis[i] = joy_get_scaled_reading( raw_joy_axis[i], i );
  1594.     
  1595.                     if (kc_joystick[23].value==i)        // If this is the throttle
  1596.                         joy_null_value = 20;                // Then use a larger dead-zone
  1597.     
  1598.                     if (raw_joy_axis[i] > joy_null_value) 
  1599.                         raw_joy_axis[i] = ((raw_joy_axis[i]-joy_null_value)*128)/(128-joy_null_value);
  1600.                       else if (raw_joy_axis[i] < -joy_null_value)
  1601.                         raw_joy_axis[i] = ((raw_joy_axis[i]+joy_null_value)*128)/(128-joy_null_value);
  1602.                     else
  1603.                         raw_joy_axis[i] = 0;
  1604.                     joy_axis[i]    = (raw_joy_axis[i]*FrameTime)/128;    
  1605.                 }
  1606.             } else {
  1607.                 joy_axis[i] = 0;
  1608.             }
  1609.         }    
  1610.         use_joystick=1;
  1611.     } else {
  1612.         for (i=0; i<4; i++ )
  1613.             joy_axis[i] = 0;
  1614.         use_joystick=0;
  1615.     }
  1616.  
  1617.     if (Config_control_type==5 ) {
  1618.         //---------  Read Mouse -----------
  1619.         mouse_get_delta( &dx, &dy );
  1620.         mouse_axis[0] = (dx*FrameTime)/35;
  1621.         mouse_axis[1] = (dy*FrameTime)/25;
  1622.         mouse_buttons = mouse_get_btns();
  1623.         //mprintf(( 0, "Mouse %d,%d b:%d, 0x%x\n", mouse_axis[0], mouse_axis[1], mouse_buttons, FrameTime ));
  1624.         use_mouse=1;
  1625.     } else if (Config_control_type==6 ) {
  1626.         //---------  Read Cyberman -----------
  1627.         mouse_get_cyberman_pos(&idx,&idy );
  1628.         mouse_axis[0] = (idx*FrameTime)/128;
  1629.         mouse_axis[1] = (idy*FrameTime)/128;
  1630.         mouse_buttons = mouse_get_btns();
  1631.         use_mouse=1;
  1632.     } else {
  1633.         mouse_axis[0] = 0;
  1634.         mouse_axis[1] = 0;
  1635.         mouse_buttons = 0;
  1636.         use_mouse=0;
  1637.     }
  1638.  
  1639.  
  1640. //------------- Read slide_on -------------
  1641.     
  1642.     // From keyboard...
  1643.     if ( kc_keyboard[8].value < 255 ) slide_on |= keyd_pressed[ kc_keyboard[8].value ];
  1644.     if ( kc_keyboard[9].value < 255 ) slide_on |= keyd_pressed[ kc_keyboard[9].value ];
  1645.     // From joystick...
  1646.     if ((use_joystick)&&(kc_joystick[5].value<255)) slide_on |= joy_get_button_state( kc_joystick[5].value );
  1647.     // From mouse...
  1648.     if ((use_mouse)&&(kc_mouse[5].value<255)) slide_on |= mouse_buttons & (1<<kc_mouse[5].value);
  1649.  
  1650. //------------- Read bank_on ---------------
  1651.  
  1652.     // From keyboard...
  1653.     if ( kc_keyboard[18].value < 255 ) bank_on |= keyd_pressed[ kc_keyboard[18].value ];
  1654.     if ( kc_keyboard[19].value < 255 ) bank_on |= keyd_pressed[ kc_keyboard[19].value ];
  1655.     // From joystick...
  1656.     if ( (use_joystick)&&(kc_joystick[10].value < 255 )) bank_on |= joy_get_button_state( kc_joystick[10].value );
  1657.     // From mouse...
  1658.     if ( (use_mouse)&&(kc_mouse[10].value < 255 )) bank_on |= mouse_buttons & (1<<kc_mouse[10].value);
  1659.  
  1660. //------------ Read pitch_time -----------
  1661.     if ( !slide_on )    {
  1662.         // mprintf((0, "pitch: %7.3f %7.3f: %7.3f\n", f2fl(k4), f2fl(k6), f2fl(Controls.heading_time)));
  1663.         kp = 0;
  1664.         k0 = speed_factor*key_down_time( kc_keyboard[0].value )/2;    // Divide by two since we want pitch to go slower
  1665.         k1 = speed_factor*key_down_time( kc_keyboard[1].value )/2;
  1666.         k2 = speed_factor*key_down_time( kc_keyboard[2].value )/2;
  1667.         k3 = speed_factor*key_down_time( kc_keyboard[3].value )/2;
  1668.  
  1669.         // From keyboard...
  1670.         if ( kc_keyboard[0].value < 255 ) kp += k0/PH_SCALE;
  1671.         if ( kc_keyboard[1].value < 255 ) kp += k1/PH_SCALE;
  1672.         if ( kc_keyboard[2].value < 255 ) kp -= k2/PH_SCALE;
  1673.         if ( kc_keyboard[3].value < 255 ) kp -= k3/PH_SCALE;
  1674.  
  1675.         // From Cyberman...
  1676.         if ((use_mouse)&&(Config_control_type==CONTROL_CYBERMAN))    {
  1677.             kp += mouse_button_down_time(MB_PITCH_FORWARD)/(PH_SCALE*2);
  1678.             kp -= mouse_button_down_time(MB_PITCH_BACKWARD)/(PH_SCALE*2);
  1679.         }
  1680.     
  1681.         if (kp == 0)
  1682.             Controls.pitch_time = 0;
  1683.         else if (kp > 0) {
  1684.             if (Controls.pitch_time < 0)
  1685.                 Controls.pitch_time = 0;
  1686.         } else // kp < 0
  1687.             if (Controls.pitch_time > 0)
  1688.                 Controls.pitch_time = 0;
  1689.         Controls.pitch_time += kp;
  1690.     
  1691.         // From joystick...
  1692.         if ( (use_joystick)&&(kc_joystick[13].value < 255 ))    {
  1693.             if ( !kc_joystick[14].value )        // If not inverted...
  1694.                 Controls.pitch_time -= (joy_axis[kc_joystick[13].value]*Config_joystick_sensitivity)/8;
  1695.             else
  1696.                 Controls.pitch_time += (joy_axis[kc_joystick[13].value]*Config_joystick_sensitivity)/8;
  1697.         }
  1698.     
  1699.         // From mouse...
  1700.         //mprintf(( 0, "UM: %d, PV: %d\n", use_mouse, kc_mouse[13].value ));
  1701.         if ( (use_mouse)&&(kc_mouse[13].value < 255) )    {
  1702.             if ( !kc_mouse[14].value )        // If not inverted...
  1703.                 Controls.pitch_time -= (mouse_axis[kc_mouse[13].value]*Config_joystick_sensitivity)/8;
  1704.             else
  1705.                 Controls.pitch_time += (mouse_axis[kc_mouse[13].value]*Config_joystick_sensitivity)/8;
  1706.         }
  1707.     } else {
  1708.         Controls.pitch_time = 0;
  1709.     }
  1710.  
  1711.  
  1712. //----------- Read vertical_thrust_time -----------------
  1713.  
  1714.     if ( slide_on )    {
  1715.         k0 = speed_factor*key_down_time( kc_keyboard[0].value );
  1716.         k1 = speed_factor*key_down_time( kc_keyboard[1].value );
  1717.         k2 = speed_factor*key_down_time( kc_keyboard[2].value );
  1718.         k3 = speed_factor*key_down_time( kc_keyboard[3].value );
  1719.  
  1720.         // From keyboard...
  1721.         if ( kc_keyboard[0].value < 255 ) Controls.vertical_thrust_time += k0;
  1722.         if ( kc_keyboard[1].value < 255 ) Controls.vertical_thrust_time += k1;
  1723.         if ( kc_keyboard[2].value < 255 ) Controls.vertical_thrust_time -= k2;
  1724.         if ( kc_keyboard[3].value < 255 ) Controls.vertical_thrust_time -= k3;
  1725.  
  1726.         // From Cyberman...
  1727.         if ((use_mouse)&&(Config_control_type==CONTROL_CYBERMAN))    {
  1728.             Controls.vertical_thrust_time -= mouse_button_down_time(MB_PITCH_FORWARD);
  1729.             Controls.vertical_thrust_time += mouse_button_down_time(MB_PITCH_BACKWARD);
  1730.         }
  1731.     
  1732.         // From joystick...
  1733.         if ((use_joystick)&&( kc_joystick[13].value < 255 ))    {
  1734.             if ( !kc_joystick[14].value )        // If not inverted...
  1735.                 Controls.vertical_thrust_time += joy_axis[kc_joystick[13].value];
  1736.             else
  1737.                 Controls.vertical_thrust_time -= joy_axis[kc_joystick[13].value];
  1738.         }
  1739.     
  1740.         // From mouse...
  1741.         if ( (use_mouse)&&(kc_mouse[13].value < 255 ))    {
  1742.             if ( !kc_mouse[14].value )        // If not inverted...
  1743.                 Controls.vertical_thrust_time -= mouse_axis[kc_mouse[13].value];
  1744.             else
  1745.                 Controls.vertical_thrust_time += mouse_axis[kc_mouse[13].value];
  1746.         }
  1747.     }
  1748.  
  1749.     // From keyboard...
  1750.     if ( kc_keyboard[14].value < 255 ) Controls.vertical_thrust_time += speed_factor*key_down_time( kc_keyboard[14].value );
  1751.     if ( kc_keyboard[15].value < 255 ) Controls.vertical_thrust_time += speed_factor*key_down_time( kc_keyboard[15].value );
  1752.     if ( kc_keyboard[16].value < 255 ) Controls.vertical_thrust_time -= speed_factor*key_down_time( kc_keyboard[16].value );
  1753.     if ( kc_keyboard[17].value < 255 ) Controls.vertical_thrust_time -= speed_factor*key_down_time( kc_keyboard[17].value );
  1754.     
  1755.     // From joystick...
  1756.     if ((use_joystick)&&( kc_joystick[19].value < 255 ))    {
  1757.         if ( !kc_joystick[20].value )        // If not inverted...
  1758.             Controls.vertical_thrust_time += joy_axis[kc_joystick[19].value];
  1759.         else
  1760.             Controls.vertical_thrust_time -= joy_axis[kc_joystick[19].value];
  1761.     }
  1762.  
  1763.     // From joystick buttons
  1764.     if ( (use_joystick)&&(kc_joystick[8].value < 255 )) Controls.vertical_thrust_time += joy_get_button_down_time( kc_joystick[8].value );
  1765.     if ( (use_joystick)&&(kc_joystick[9].value < 255 )) Controls.vertical_thrust_time -= joy_get_button_down_time( kc_joystick[9].value );
  1766.  
  1767.     // From mouse buttons
  1768.     if ( (use_mouse)&&(kc_mouse[8].value < 255 )) Controls.vertical_thrust_time += mouse_button_down_time( kc_mouse[8].value );
  1769.     if ( (use_mouse)&&(kc_mouse[9].value < 255 )) Controls.vertical_thrust_time -= mouse_button_down_time( kc_mouse[9].value );
  1770.  
  1771.     // From mouse...
  1772.     if ( (use_mouse)&&(kc_mouse[19].value < 255 ))    {
  1773.         if ( !kc_mouse[20].value )        // If not inverted...
  1774.             Controls.vertical_thrust_time += mouse_axis[kc_mouse[19].value];
  1775.         else
  1776.             Controls.vertical_thrust_time -= mouse_axis[kc_mouse[19].value];
  1777.     }
  1778.  
  1779.     // From Cyberman...
  1780.     if ((use_mouse)&&(Config_control_type==CONTROL_CYBERMAN))    {
  1781.         Controls.vertical_thrust_time += mouse_button_down_time(MB_Z_UP)/2;
  1782.         Controls.vertical_thrust_time -= mouse_button_down_time(MB_Z_DOWN)/2;
  1783.     }
  1784.  
  1785. //---------- Read heading_time -----------
  1786.  
  1787.     if (!slide_on && !bank_on)    {
  1788.         //mprintf((0, "heading: %7.3f %7.3f: %7.3f\n", f2fl(k4), f2fl(k6), f2fl(Controls.heading_time)));
  1789.         kh = 0;
  1790.         k4 = speed_factor*key_down_time( kc_keyboard[4].value );
  1791.         k5 = speed_factor*key_down_time( kc_keyboard[5].value );
  1792.         k6 = speed_factor*key_down_time( kc_keyboard[6].value );
  1793.         k7 = speed_factor*key_down_time( kc_keyboard[7].value );
  1794.  
  1795.         // From keyboard...
  1796.         if ( kc_keyboard[4].value < 255 ) kh -= k4/PH_SCALE;
  1797.         if ( kc_keyboard[5].value < 255 ) kh -= k5/PH_SCALE;
  1798.         if ( kc_keyboard[6].value < 255 ) kh += k6/PH_SCALE;
  1799.         if ( kc_keyboard[7].value < 255 ) kh += k7/PH_SCALE;
  1800.  
  1801.         // From Cyberman...
  1802.         if ((use_mouse)&&(Config_control_type==CONTROL_CYBERMAN))    {
  1803.             kh -= mouse_button_down_time(MB_HEAD_LEFT)/PH_SCALE;
  1804.             kh += mouse_button_down_time(MB_HEAD_RIGHT)/PH_SCALE;
  1805.         }
  1806.     
  1807.         if (kh == 0)
  1808.             Controls.heading_time = 0;
  1809.         else if (kh > 0) {
  1810.             if (Controls.heading_time < 0)
  1811.                 Controls.heading_time = 0;
  1812.         } else // kh < 0
  1813.             if (Controls.heading_time > 0)
  1814.                 Controls.heading_time = 0;
  1815.         Controls.heading_time += kh;
  1816.  
  1817.         // From joystick...
  1818.         if ( (use_joystick)&&(kc_joystick[15].value < 255 ))    {
  1819.             if ( !kc_joystick[16].value )        // If not inverted...
  1820.                 Controls.heading_time += (joy_axis[kc_joystick[15].value]*Config_joystick_sensitivity)/8;
  1821.             else
  1822.                 Controls.heading_time -= (joy_axis[kc_joystick[15].value]*Config_joystick_sensitivity)/8;
  1823.         }
  1824.     
  1825.         // From mouse...
  1826.         if ( (use_mouse)&&(kc_mouse[15].value < 255 ))    {
  1827.             if ( !kc_mouse[16].value )        // If not inverted...
  1828.                 Controls.heading_time += (mouse_axis[kc_mouse[15].value]*Config_joystick_sensitivity)/8;
  1829.             else
  1830.                 Controls.heading_time -= (mouse_axis[kc_mouse[15].value]*Config_joystick_sensitivity)/8;
  1831.         }
  1832.     } else {
  1833.         Controls.heading_time = 0;
  1834.     }
  1835.  
  1836. //----------- Read sideways_thrust_time -----------------
  1837.  
  1838.     if ( slide_on )    {
  1839.         k0 = speed_factor*key_down_time( kc_keyboard[4].value );
  1840.         k1 = speed_factor*key_down_time( kc_keyboard[5].value );
  1841.         k2 = speed_factor*key_down_time( kc_keyboard[6].value );
  1842.         k3 = speed_factor*key_down_time( kc_keyboard[7].value );
  1843.  
  1844.         // From keyboard...
  1845.         if ( kc_keyboard[4].value < 255 ) Controls.sideways_thrust_time -= k0;
  1846.         if ( kc_keyboard[5].value < 255 ) Controls.sideways_thrust_time -= k1;
  1847.         if ( kc_keyboard[6].value < 255 ) Controls.sideways_thrust_time += k2;
  1848.         if ( kc_keyboard[7].value < 255 ) Controls.sideways_thrust_time += k3;
  1849.     
  1850.         // From joystick...
  1851.         if ( (use_joystick)&&(kc_joystick[15].value < 255 ))    {
  1852.             if ( !kc_joystick[16].value )        // If not inverted...
  1853.                 Controls.sideways_thrust_time += joy_axis[kc_joystick[15].value];
  1854.             else
  1855.                 Controls.sideways_thrust_time -= joy_axis[kc_joystick[15].value];
  1856.         }
  1857.         
  1858.         // From cyberman
  1859.         if ((use_mouse)&&(Config_control_type==CONTROL_CYBERMAN))    {
  1860.             Controls.sideways_thrust_time -= mouse_button_down_time(MB_HEAD_LEFT);
  1861.             Controls.sideways_thrust_time += mouse_button_down_time(MB_HEAD_RIGHT);
  1862.         }
  1863.     
  1864.         // From mouse...
  1865.         if ( (use_mouse)&&(kc_mouse[15].value < 255 ))    {
  1866.             if ( !kc_mouse[16].value )        // If not inverted...
  1867.                 Controls.sideways_thrust_time += mouse_axis[kc_mouse[15].value];
  1868.             else
  1869.                 Controls.sideways_thrust_time -= mouse_axis[kc_mouse[15].value];
  1870.         }
  1871.     }
  1872.  
  1873.     // From keyboard...
  1874.     if ( kc_keyboard[10].value < 255 ) Controls.sideways_thrust_time -= speed_factor*key_down_time( kc_keyboard[10].value );
  1875.     if ( kc_keyboard[11].value < 255 ) Controls.sideways_thrust_time -= speed_factor*key_down_time( kc_keyboard[11].value );
  1876.     if ( kc_keyboard[12].value < 255 ) Controls.sideways_thrust_time += speed_factor*key_down_time( kc_keyboard[12].value );
  1877.     if ( kc_keyboard[13].value < 255 ) Controls.sideways_thrust_time += speed_factor*key_down_time( kc_keyboard[13].value );
  1878.     
  1879.     // From joystick...
  1880.     if ( (use_joystick)&&(kc_joystick[17].value < 255 ))    {
  1881.         if ( !kc_joystick[18].value )        // If not inverted...
  1882.             Controls.sideways_thrust_time -= joy_axis[kc_joystick[17].value];
  1883.         else
  1884.             Controls.sideways_thrust_time += joy_axis[kc_joystick[17].value];
  1885.     }
  1886.  
  1887.     // From joystick buttons
  1888.     if ( (use_joystick)&&(kc_joystick[6].value < 255 )) Controls.sideways_thrust_time -= joy_get_button_down_time( kc_joystick[6].value );
  1889.     if ( (use_joystick)&&(kc_joystick[7].value < 255 )) Controls.sideways_thrust_time += joy_get_button_down_time( kc_joystick[7].value );
  1890.  
  1891.     // From mouse buttons
  1892.     if ( (use_mouse)&&(kc_mouse[6].value < 255 )) Controls.sideways_thrust_time -= mouse_button_down_time( kc_mouse[6].value );
  1893.     if ( (use_mouse)&&(kc_mouse[7].value < 255 )) Controls.sideways_thrust_time += mouse_button_down_time( kc_mouse[7].value );
  1894.  
  1895.     // From mouse...
  1896.     if ( (use_mouse)&&(kc_mouse[17].value < 255 ))    {
  1897.         if ( !kc_mouse[18].value )        // If not inverted...
  1898.             Controls.sideways_thrust_time += mouse_axis[kc_mouse[17].value];
  1899.         else
  1900.             Controls.sideways_thrust_time -= mouse_axis[kc_mouse[17].value];
  1901.     }
  1902.  
  1903. //----------- Read bank_time -----------------
  1904.  
  1905.     if ( bank_on )    {
  1906.         k0 = speed_factor*key_down_time( kc_keyboard[4].value );
  1907.         k1 = speed_factor*key_down_time( kc_keyboard[5].value );
  1908.         k2 = speed_factor*key_down_time( kc_keyboard[6].value );
  1909.         k3 = speed_factor*key_down_time( kc_keyboard[7].value );
  1910.  
  1911.         // From keyboard...
  1912.         if ( kc_keyboard[4].value < 255 ) Controls.bank_time += k0;
  1913.         if ( kc_keyboard[5].value < 255 ) Controls.bank_time += k1;
  1914.         if ( kc_keyboard[6].value < 255 ) Controls.bank_time -= k2;
  1915.         if ( kc_keyboard[7].value < 255 ) Controls.bank_time -= k3;
  1916.  
  1917.         // From Cyberman...
  1918.         if ((use_mouse)&&(Config_control_type==CONTROL_CYBERMAN))    {
  1919.             Controls.bank_time -= mouse_button_down_time(MB_HEAD_LEFT);
  1920.             Controls.bank_time += mouse_button_down_time(MB_HEAD_RIGHT);
  1921.         }
  1922.  
  1923.         // From joystick...
  1924.         if ( (use_joystick)&&(kc_joystick[15].value < 255) )    {
  1925.             if ( !kc_joystick[16].value )        // If not inverted...
  1926.                 Controls.bank_time -= (joy_axis[kc_joystick[15].value]*Config_joystick_sensitivity)/8;
  1927.             else
  1928.                 Controls.bank_time += (joy_axis[kc_joystick[15].value]*Config_joystick_sensitivity)/8;
  1929.         }
  1930.     
  1931.         // From mouse...
  1932.         if ( (use_mouse)&&(kc_mouse[15].value < 255 ))    {
  1933.             if ( !kc_mouse[16].value )        // If not inverted...
  1934.                 Controls.bank_time += (mouse_axis[kc_mouse[15].value]*Config_joystick_sensitivity)/8;
  1935.             else
  1936.                 Controls.bank_time -= (mouse_axis[kc_mouse[15].value]*Config_joystick_sensitivity)/8;
  1937.         }
  1938.     }
  1939.  
  1940.     // From keyboard...
  1941.     if ( kc_keyboard[20].value < 255 ) Controls.bank_time += speed_factor*key_down_time( kc_keyboard[20].value );
  1942.     if ( kc_keyboard[21].value < 255 ) Controls.bank_time += speed_factor*key_down_time( kc_keyboard[21].value );
  1943.     if ( kc_keyboard[22].value < 255 ) Controls.bank_time -= speed_factor*key_down_time( kc_keyboard[22].value );
  1944.     if ( kc_keyboard[23].value < 255 ) Controls.bank_time -= speed_factor*key_down_time( kc_keyboard[23].value );
  1945.  
  1946.     // From joystick...
  1947.     if ( (use_joystick)&&(kc_joystick[21].value < 255) )    {
  1948.         if ( !kc_joystick[22].value )        // If not inverted...
  1949.             Controls.bank_time -= joy_axis[kc_joystick[21].value];
  1950.         else
  1951.             Controls.bank_time += joy_axis[kc_joystick[21].value];
  1952.     }
  1953.  
  1954.     // From joystick buttons
  1955.     if ( (use_joystick)&&(kc_joystick[11].value < 255 )) Controls.bank_time += joy_get_button_down_time( kc_joystick[11].value );
  1956.     if ( (use_joystick)&&(kc_joystick[12].value < 255 )) Controls.bank_time -= joy_get_button_down_time( kc_joystick[12].value );
  1957.  
  1958.     // From mouse buttons
  1959.     if ( (use_mouse)&&(kc_mouse[11].value < 255 )) Controls.bank_time += mouse_button_down_time( kc_mouse[11].value );
  1960.     if ( (use_mouse)&&(kc_mouse[12].value < 255 )) Controls.bank_time -= mouse_button_down_time( kc_mouse[12].value );
  1961.  
  1962.     // From mouse...
  1963.     if ( (use_mouse)&&(kc_mouse[21].value < 255 ))    {
  1964.         if ( !kc_mouse[22].value )        // If not inverted...
  1965.             Controls.bank_time += mouse_axis[kc_mouse[21].value];
  1966.         else
  1967.             Controls.bank_time -= mouse_axis[kc_mouse[21].value];
  1968.     }
  1969.  
  1970.     // From Cyberman
  1971.     if ((use_mouse)&&(Config_control_type==CONTROL_CYBERMAN))    {
  1972.         Controls.bank_time += mouse_button_down_time(MB_BANK_LEFT);
  1973.         Controls.bank_time -= mouse_button_down_time(MB_BANK_RIGHT);
  1974.     }
  1975.  
  1976. //----------- Read forward_thrust_time -------------
  1977.  
  1978.     // From keyboard...
  1979.     if ( kc_keyboard[30].value < 255 ) Controls.forward_thrust_time += speed_factor*key_down_time( kc_keyboard[30].value );
  1980.     if ( kc_keyboard[31].value < 255 ) Controls.forward_thrust_time += speed_factor*key_down_time( kc_keyboard[31].value );
  1981.     if ( kc_keyboard[32].value < 255 ) Controls.forward_thrust_time -= speed_factor*key_down_time( kc_keyboard[32].value );
  1982.     if ( kc_keyboard[33].value < 255 ) Controls.forward_thrust_time -= speed_factor*key_down_time( kc_keyboard[33].value );
  1983.  
  1984.     // From joystick...
  1985.     if ( (use_joystick)&&(kc_joystick[23].value < 255 ))    {
  1986.         if ( !kc_joystick[24].value )        // If not inverted...
  1987.             Controls.forward_thrust_time -= joy_axis[kc_joystick[23].value];
  1988.         else
  1989.             Controls.forward_thrust_time += joy_axis[kc_joystick[23].value];
  1990.     }
  1991.  
  1992.     // From joystick buttons
  1993.     if ( (use_joystick)&&(kc_joystick[2].value < 255 )) Controls.forward_thrust_time += joy_get_button_down_time( kc_joystick[2].value );
  1994.     if ( (use_joystick)&&(kc_joystick[3].value < 255 )) Controls.forward_thrust_time -= joy_get_button_down_time( kc_joystick[3].value );
  1995.  
  1996.     // From mouse...
  1997.     if ( (use_mouse)&&(kc_mouse[23].value < 255 ))    {
  1998.         if ( !kc_mouse[24].value )        // If not inverted...
  1999.             Controls.forward_thrust_time -= mouse_axis[kc_mouse[23].value];
  2000.         else
  2001.             Controls.forward_thrust_time += mouse_axis[kc_mouse[23].value];
  2002.     }
  2003.  
  2004.     // From mouse buttons
  2005.     if ( (use_mouse)&&(kc_mouse[2].value < 255 )) Controls.forward_thrust_time += mouse_button_down_time( kc_mouse[2].value );
  2006.     if ( (use_mouse)&&(kc_mouse[3].value < 255 )) Controls.forward_thrust_time -= mouse_button_down_time( kc_mouse[3].value );
  2007.  
  2008. //----------- Read fire_primary_down_count
  2009.     if (kc_keyboard[24].value < 255 ) Controls.fire_primary_down_count += key_down_count(kc_keyboard[24].value);
  2010.     if (kc_keyboard[25].value < 255 ) Controls.fire_primary_down_count += key_down_count(kc_keyboard[25].value);
  2011.     if ((use_joystick)&&(kc_joystick[0].value < 255 )) Controls.fire_primary_down_count += joy_get_button_down_cnt(kc_joystick[0].value);
  2012.     if ((use_mouse)&&(kc_mouse[0].value < 255 )) Controls.fire_primary_down_count += mouse_button_down_count(kc_mouse[0].value);
  2013.  
  2014. //----------- Read fire_primary_state
  2015.     if (kc_keyboard[24].value < 255 ) Controls.fire_primary_state |= keyd_pressed[kc_keyboard[24].value];
  2016.     if (kc_keyboard[25].value < 255 ) Controls.fire_primary_state |= keyd_pressed[kc_keyboard[25].value];
  2017.     if ((use_joystick)&&(kc_joystick[0].value < 255 )) Controls.fire_primary_state |= joy_get_button_state(kc_joystick[0].value);
  2018.     if ((use_mouse)&&(kc_mouse[0].value < 255) ) Controls.fire_primary_state |= mouse_button_state(kc_mouse[0].value);
  2019.  
  2020. //----------- Read fire_secondary_down_count
  2021.     if (kc_keyboard[26].value < 255 ) Controls.fire_secondary_down_count += key_down_count(kc_keyboard[26].value);
  2022.     if (kc_keyboard[27].value < 255 ) Controls.fire_secondary_down_count += key_down_count(kc_keyboard[27].value);
  2023.     if ((use_joystick)&&(kc_joystick[1].value < 255 )) Controls.fire_secondary_down_count += joy_get_button_down_cnt(kc_joystick[1].value);
  2024.     if ((use_mouse)&&(kc_mouse[1].value < 255 )) Controls.fire_secondary_down_count += mouse_button_down_count(kc_mouse[1].value);
  2025.  
  2026. //----------- Read fire_secondary_state
  2027.     if (kc_keyboard[26].value < 255 ) Controls.fire_secondary_state |= keyd_pressed[kc_keyboard[26].value];
  2028.     if (kc_keyboard[27].value < 255 ) Controls.fire_secondary_state |= keyd_pressed[kc_keyboard[27].value];
  2029.     if ((use_joystick)&&(kc_joystick[1].value < 255 )) Controls.fire_secondary_state |= joy_get_button_state(kc_joystick[1].value);
  2030.     if ((use_mouse)&&(kc_mouse[1].value < 255) ) Controls.fire_secondary_state |= mouse_button_state(kc_mouse[1].value);
  2031.  
  2032. //----------- Read fire_flare_down_count
  2033.     if (kc_keyboard[28].value < 255 ) Controls.fire_flare_down_count += key_down_count(kc_keyboard[28].value);
  2034.     if (kc_keyboard[29].value < 255 ) Controls.fire_flare_down_count += key_down_count(kc_keyboard[29].value);
  2035.     if ((use_joystick)&&(kc_joystick[4].value < 255 )) Controls.fire_flare_down_count += joy_get_button_down_cnt(kc_joystick[4].value);
  2036.     if ((use_mouse)&&(kc_mouse[4].value < 255 )) Controls.fire_flare_down_count += mouse_button_down_count(kc_mouse[4].value);
  2037.  
  2038. //----------- Read drop_bomb_down_count
  2039.     if (kc_keyboard[34].value < 255 ) Controls.drop_bomb_down_count += key_down_count(kc_keyboard[34].value);
  2040.     if (kc_keyboard[35].value < 255 ) Controls.drop_bomb_down_count += key_down_count(kc_keyboard[35].value);
  2041.     if ((use_joystick)&&(kc_joystick[26].value < 255 )) Controls.drop_bomb_down_count += joy_get_button_down_cnt(kc_joystick[26].value);
  2042.     if ((use_mouse)&&(kc_mouse[26].value < 255 )) Controls.drop_bomb_down_count += mouse_button_down_count(kc_mouse[26].value);
  2043.  
  2044. //----------- Read rear_view_down_count
  2045.     if (kc_keyboard[36].value < 255 ) Controls.rear_view_down_count += key_down_count(kc_keyboard[36].value);
  2046.     if (kc_keyboard[37].value < 255 ) Controls.rear_view_down_count += key_down_count(kc_keyboard[37].value);
  2047.     if ((use_joystick)&&(kc_joystick[25].value < 255 )) Controls.rear_view_down_count += joy_get_button_down_cnt(kc_joystick[25].value);
  2048.     if ((use_mouse)&&(kc_mouse[25].value < 255 )) Controls.rear_view_down_count += mouse_button_down_count(kc_mouse[25].value);
  2049.  
  2050. //----------- Read rear_view_down_state
  2051.     if (kc_keyboard[36].value < 255 ) Controls.rear_view_down_state |= keyd_pressed[kc_keyboard[36].value];
  2052.     if (kc_keyboard[37].value < 255 ) Controls.rear_view_down_state |= keyd_pressed[kc_keyboard[37].value];
  2053.     if ((use_joystick)&&(kc_joystick[25].value < 255 )) Controls.rear_view_down_state |= joy_get_button_state(kc_joystick[25].value);
  2054.     if ((use_mouse)&&(kc_mouse[25].value < 255 )) Controls.rear_view_down_state |= mouse_button_state(kc_mouse[25].value);
  2055.  
  2056. //----------- Read automap_down_count
  2057.     if (kc_keyboard[44].value < 255 ) Controls.automap_down_count += key_down_count(kc_keyboard[44].value);
  2058.     if (kc_keyboard[45].value < 255 ) Controls.automap_down_count += key_down_count(kc_keyboard[45].value);
  2059.  
  2060. //----------- Read automap_state
  2061.     if (kc_keyboard[44].value < 255 ) Controls.automap_state |= keyd_pressed[kc_keyboard[44].value];
  2062.     if (kc_keyboard[45].value < 255 ) Controls.automap_state |= keyd_pressed[kc_keyboard[45].value];
  2063.  
  2064. //----------- Read stupid-cruise-control-type of throttle.
  2065.     {
  2066.         if ( kc_keyboard[38].value < 255 ) Cruise_speed += fixdiv(speed_factor*key_down_time(kc_keyboard[38].value)*5,FrameTime);
  2067.         if ( kc_keyboard[39].value < 255 ) Cruise_speed += fixdiv(speed_factor*key_down_time(kc_keyboard[39].value)*5,FrameTime);
  2068.         if ( kc_keyboard[40].value < 255 ) Cruise_speed -= fixdiv(speed_factor*key_down_time(kc_keyboard[40].value)*5,FrameTime);
  2069.         if ( kc_keyboard[41].value < 255 ) Cruise_speed -= fixdiv(speed_factor*key_down_time(kc_keyboard[41].value)*5,FrameTime);
  2070.         if ( (kc_keyboard[42].value < 255) && (key_down_count(kc_keyboard[42].value)) )
  2071.             Cruise_speed = 0;
  2072.         if ( (kc_keyboard[43].value < 255) && (key_down_count(kc_keyboard[43].value)) )
  2073.             Cruise_speed = 0;
  2074.     
  2075.         if (Cruise_speed > i2f(100) ) Cruise_speed = i2f(100);
  2076.         if (Cruise_speed < 0 ) Cruise_speed = 0;
  2077.     
  2078.         if (Controls.forward_thrust_time==0)
  2079.             Controls.forward_thrust_time = fixmul(Cruise_speed,FrameTime)/100;
  2080.     }
  2081.  
  2082.     read_head_tracker();
  2083.  
  2084.     // Read external controls
  2085.     if (kc_use_external_control)
  2086.         kconfig_read_external_controls();
  2087.  
  2088. //----------- Clamp values between -FrameTime and FrameTime
  2089.     if (FrameTime > F1_0 )
  2090.         mprintf( (1, "Bogus frame time of %.2f seconds\n", f2fl(FrameTime) ));
  2091.  
  2092.     if (Controls.pitch_time > FrameTime/2 ) Controls.pitch_time = FrameTime/2;
  2093.     if (Controls.vertical_thrust_time > FrameTime ) Controls.vertical_thrust_time = FrameTime;
  2094.     if (Controls.heading_time > FrameTime ) Controls.heading_time = FrameTime;
  2095.     if (Controls.sideways_thrust_time > FrameTime ) Controls.sideways_thrust_time = FrameTime;
  2096.     if (Controls.bank_time > FrameTime ) Controls.bank_time = FrameTime;
  2097.     if (Controls.forward_thrust_time > FrameTime ) Controls.forward_thrust_time = FrameTime;
  2098. //    if (Controls.afterburner_time > FrameTime ) Controls.afterburner_time = FrameTime;
  2099.  
  2100.     if (Controls.pitch_time < -FrameTime/2 ) Controls.pitch_time = -FrameTime/2;
  2101.     if (Controls.vertical_thrust_time < -FrameTime ) Controls.vertical_thrust_time = -FrameTime;
  2102.     if (Controls.heading_time < -FrameTime ) Controls.heading_time = -FrameTime;
  2103.     if (Controls.sideways_thrust_time < -FrameTime ) Controls.sideways_thrust_time = -FrameTime;
  2104.     if (Controls.bank_time < -FrameTime ) Controls.bank_time = -FrameTime;
  2105.     if (Controls.forward_thrust_time < -FrameTime ) Controls.forward_thrust_time = -FrameTime;
  2106. //    if (Controls.afterburner_time < -FrameTime ) Controls.afterburner_time = -FrameTime;
  2107.  
  2108.  
  2109. //--------- Don't do anything if in debug mode
  2110.     #ifndef NDEBUG
  2111.     if ( keyd_pressed[KEY_DELETE] )    {
  2112.         memset( &Controls, 0, sizeof(control_info) );
  2113.     }
  2114.     #endif
  2115. }
  2116.  
  2117. void reset_cruise(void)
  2118. {
  2119.     Cruise_speed=0;
  2120. }
  2121.  
  2122.  
  2123. void kc_set_controls()
  2124. {
  2125.     int i;
  2126.  
  2127.     for (i=0; i<NUM_KEY_CONTROLS; i++ )    
  2128.         kc_keyboard[i].value = kconfig_settings[0][i];
  2129.  
  2130.     if ( (Config_control_type>0) && (Config_control_type<5))    {
  2131.         for (i=0; i<NUM_OTHER_CONTROLS; i++ ) {
  2132.             kc_joystick[i].value = kconfig_settings[Config_control_type][i];
  2133.             if (kc_joystick[i].type == BT_INVERT )    {
  2134.                 if (kc_joystick[i].value!=1)
  2135.                     kc_joystick[i].value    = 0;
  2136.                 kconfig_settings[Config_control_type][i] = kc_joystick[i].value;
  2137.             }
  2138.         }
  2139.     } else if (Config_control_type>4) {
  2140.         for (i=0; i<NUM_OTHER_CONTROLS; i++ )    {
  2141.             kc_mouse[i].value = kconfig_settings[Config_control_type][i];
  2142.             if (kc_mouse[i].type == BT_INVERT )    {
  2143.                 if (kc_mouse[i].value!=1)
  2144.                     kc_mouse[i].value    = 0;
  2145.                 kconfig_settings[Config_control_type][i] = kc_mouse[i].value;
  2146.             }
  2147.         }
  2148.     }
  2149. }
  2150.  
  2151.  
  2152. int SenseStatus1( void )
  2153. {
  2154.     union  REGS     regs;
  2155.     struct SREGS    sregs;
  2156.     int function, result, i;
  2157.  
  2158.     for( i=MIN_SENSE_FUNCTION; i <= MAX_SENSE_FUNCTION; i++ )    {
  2159.         result    = i;
  2160.         result   |= (SENSE_DRIVER_STATUS << 8);
  2161.         function  = SENSE_DRIVER_STATUS;
  2162.         function |= (i << 8);        
  2163.         memset( ®s, 0, sizeof(regs));
  2164.         memset( &sregs, 0, sizeof(sregs));
  2165.         regs.x.ecx = 0;
  2166.         regs.x.edx = 0;
  2167.         regs.x.ebx = 0;
  2168.         regs.x.eax = function;
  2169.         int386( SENSE_VECTOR, ®s, ®s );
  2170.         
  2171.         if( regs.x.eax == result )
  2172.             return( function & 0xFF00 );
  2173.     }
  2174.     
  2175.     return( 0 );
  2176. }
  2177.  
  2178. int SenseGetData( int function, int cls, fix *yaw, fix *pitch, fix *roll, int *buttons )
  2179. {
  2180.     union  REGS     regs;
  2181.     struct SREGS    sregs;
  2182.     memset( ®s, 0, sizeof(regs));
  2183.     memset( &sregs, 0, sizeof(sregs));
  2184.     regs.x.eax = function | GET_DEVICE_DATA;
  2185.     regs.x.ebx = 1 | (cls << 8);
  2186.  
  2187.     int386x( SENSE_VECTOR, ®s, ®s, &sregs);
  2188.     
  2189.     *yaw     = (short)(regs.x.ebx & 0xffff);
  2190.     *pitch   = (short)(regs.x.ecx & 0xffff);
  2191.     *roll    = (short)(regs.x.edx & 0xffff);
  2192.     *yaw *= -1;
  2193.     *pitch *= -1;
  2194.     *roll *= -1;
  2195.     *buttons = regs.x.eax & 0x00FF;
  2196.     
  2197.     return( (int)(regs.x.eax >> 8) );
  2198. }
  2199.  
  2200. //--unused-- int SenseSetVideo( int function, int cls, int mode )
  2201. //--unused-- {
  2202. //--unused--     union  REGS     regs;
  2203. //--unused--     struct SREGS    sregs;
  2204. //--unused--     memset( ®s, 0, sizeof(regs));
  2205. //--unused--     memset( &sregs, 0, sizeof(sregs));
  2206. //--unused--     regs.x.eax = function | SET_DEVICE_DATA;
  2207. //--unused--     regs.x.ebx = 1 | (cls << 8);
  2208. //--unused--     regs.x.ecx = mode;
  2209. //--unused-- 
  2210. //--unused--     int386x( SENSE_VECTOR, ®s, ®s, &sregs);
  2211. //--unused--     
  2212. //--unused--     return( (int)(regs.x.eax >> 8) );
  2213. //--unused-- }
  2214.  
  2215. void kconfig_center_headset()
  2216. {
  2217.     if (vfx1_installed)
  2218.         SenseSetZero( sense_function1, DCHTD );                    
  2219. //    } else if (iglasses_headset_installed)    {
  2220. //    } else if (Victor_headset_installed)   {
  2221. //    } else {
  2222. //    }
  2223.  
  2224. }
  2225.  
  2226. int SenseSetZero( int function, int cls )
  2227. {
  2228.     union  REGS     regs;
  2229.     struct SREGS    sregs;
  2230.     memset( ®s, 0, sizeof(regs));
  2231.     memset( &sregs, 0, sizeof(sregs));
  2232.     regs.x.eax = function | SET_ZERO;
  2233.     regs.x.ebx = 1 | (cls << 8);
  2234.  
  2235.     int386x( SENSE_VECTOR, ®s, ®s, &sregs);
  2236.     
  2237.     return( (int)(regs.x.eax >> 8) );
  2238. }
  2239.  
  2240. //--unused-- int SenseReSetZero( int function, int cls )
  2241. //--unused-- {
  2242. //--unused--     union  REGS     regs;
  2243. //--unused--     struct SREGS    sregs;
  2244. //--unused--     memset( ®s, 0, sizeof(regs));
  2245. //--unused--     memset( &sregs, 0, sizeof(sregs));
  2246. //--unused--     regs.x.eax = function | RESET_ZERO;
  2247. //--unused--     regs.x.ebx = 1 | (cls << 8);
  2248. //--unused-- 
  2249. //--unused--     int386x( SENSE_VECTOR, ®s, ®s, &sregs);
  2250. //--unused--     
  2251. //--unused--     return( (int)(regs.x.eax >> 8) );
  2252. //--unused-- }
  2253.  
  2254. void kconfig_sense_init()
  2255. {
  2256.     int ret;
  2257.     fix htd_y,htd_p,htd_r;
  2258.     int htd_b;
  2259.  
  2260.     sense_function1 = SenseStatus1();
  2261. //    printf("Sense installed %x\n", sense_function1 );
  2262.  
  2263.     if(sense_function1)    {
  2264.         ret = SenseGetData( sense_function1,DCHTD,&htd_y,&htd_p,&htd_r,&htd_b);
  2265.         if (!ret)    {
  2266.             vfx1_installed = 1;
  2267.             printf("%s\n", TXT_USING_VFX1 );
  2268.         } else {
  2269.             printf("%s\n", TXT_VFX1_ERROR1);
  2270.         }
  2271.     } else {
  2272.         printf( TXT_VFX1_ERROR2 );
  2273.     }
  2274. }
  2275.  
  2276. 
  2277.