]> icculus.org git repositories - taylor/freespace2.git/blob - src/io/keycontrol.cpp
make first pass at async popups
[taylor/freespace2.git] / src / io / keycontrol.cpp
1 /*
2  * Copyright (C) Volition, Inc. 1999.  All rights reserved.
3  *
4  * All source code herein is the property of Volition, Inc. You may not sell 
5  * or otherwise commercially exploit the source or things you created based on
6  * the source.
7  */
8
9 /*
10  * $Logfile: /Freespace2/code/Io/KeyControl.cpp $
11  * $Revision$
12  * $Date$
13  * $Author$
14  *
15  * Routines to read and deal with keyboard input.
16  *
17  * $Log$
18  * Revision 1.5  2003/05/25 02:30:42  taylor
19  * Freespace 1 support
20  *
21  * Revision 1.4  2002/07/28 05:05:08  relnev
22  * removed some old stuff
23  *
24  * Revision 1.3  2002/06/18 08:58:53  relnev
25  * last few struct changes
26  *
27  * Revision 1.2  2002/06/09 04:41:21  relnev
28  * added copyright header
29  *
30  * Revision 1.1.1.1  2002/05/03 03:28:09  root
31  * Initial import.
32  *
33  * 
34  * 47    9/09/99 11:40p Dave
35  * Handle an SDL_assert() in beam code. Added supernova sounds. Play the right
36  * 2 end movies properly, based upon what the player did in the mission.
37  * 
38  * 46    9/07/99 11:26p Andsager
39  * Fix "r" targeting key, making evaluate_ship_as_closest_target() and
40  * hud_target_live_turret() consider if turret is targeting player
41  * 
42  * 45    9/03/99 1:31a Dave
43  * CD checking by act. Added support to play 2 cutscenes in a row
44  * seamlessly. Fixed super low level cfile bug related to files in the
45  * root directory of a CD. Added cheat code to set campaign mission # in
46  * main hall.
47  * 
48  * 44    9/01/99 10:09a Dave
49  * Pirate bob.
50  * 
51  * 43    8/27/99 10:36a Dave
52  * Impose a 2% penalty for hitting the shield balance key.
53  * 
54  * 42    8/27/99 9:57a Dave
55  * Enabled standard cheat codes. Allow player to continue in a campaing
56  * after using cheat codes.
57  * 
58  * 41    8/26/99 9:45a Dave
59  * First pass at easter eggs and cheats.
60  * 
61  * 40    8/24/99 1:49a Dave
62  * Fixed client-side afterburner stuttering. Added checkbox for no version
63  * checking on PXO join. Made button info passing more friendly between
64  * client and server.
65  * 
66  * 39    8/22/99 5:53p Dave
67  * Scoring fixes. Added self destruct key. Put callsigns in the logfile
68  * instead of ship designations for multiplayer players.
69  * 
70  * 38    8/19/99 10:59a Dave
71  * Packet loss detection.
72  * 
73  * 37    8/18/99 12:09p Andsager
74  * Add debug if message has no anim for message.  Make messages come from
75  * wing leader.
76  * 
77  * 36    8/05/99 2:05a Dave
78  * Whee.
79  * 
80  * 35    8/01/99 12:39p Dave
81  * Added HUD contrast control key (for nebula).
82  * 
83  * 34    7/31/99 2:30p Dave
84  * Added nifty mission message debug viewing keys.
85  * 
86  * 33    7/21/99 8:10p Dave
87  * First run of supernova effect.
88  * 
89  * 32    7/15/99 4:09p Andsager
90  * Disable cheats for FS2_DEMO
91  * 
92  * 31    7/15/99 9:20a Andsager
93  * FS2_DEMO initial checkin
94  * 
95  * 30    7/07/99 3:32p Dave
96  * Oops. Forgot to remove this.
97  * 
98  * 29    7/02/99 4:31p Dave
99  * Much more sophisticated lightning support.
100  * 
101  * 28    6/10/99 3:43p Dave
102  * Do a better job of syncing text colors to HUD gauges.
103  * 
104  * 27    6/09/99 2:55p Andsager
105  * Allow multiple asteroid subtypes (of large, medium, small) and follow
106  * family.
107  * 
108  * 26    5/24/99 5:45p Dave
109  * Added detail levels to the nebula, with a decent speedup. Split nebula
110  * lightning into its own section.
111  * 
112  * 25    5/08/99 8:25p Dave
113  * Upped object pairs. First run of nebula lightning.
114  * 
115  * 24    5/05/99 9:02p Dave
116  * Fixed D3D aabitmap rendering. Spiffed up nebula effect a bit (added
117  * rotations, tweaked values, made bitmap selection more random). Fixed
118  * D3D beam weapon clipping problem. Added D3d frame dumping.
119  * 
120  * 23    5/03/99 9:07a Dave
121  * Pirate Bob. Changed beam test code a bit.
122  * 
123  * 22    4/21/99 6:15p Dave
124  * Did some serious housecleaning in the beam code. Made it ready to go
125  * for anti-fighter "pulse" weapons. Fixed collision pair creation. Added
126  * a handy macro for recalculating collision pairs for a given object.
127  * 
128  * 21    4/16/99 5:54p Dave
129  * Support for on/off style "stream" weapons. Real early support for
130  * target-painting lasers.
131  * 
132  * 20    3/31/99 8:24p Dave
133  * Beefed up all kinds of stuff, incluging beam weapons, nebula effects
134  * and background nebulae. Added per-ship non-dimming pixel colors.
135  * 
136  * 19    3/29/99 6:17p Dave
137  * More work on demo system. Got just about everything in except for
138  * blowing ships up, secondary weapons and player death/warpout.
139  * 
140  * 18    3/28/99 5:58p Dave
141  * Added early demo code. Make objects move. Nice and framerate
142  * independant, but not much else. Don't use yet unless you're me :)
143  * 
144  * 17    3/09/99 6:24p Dave
145  * More work on object update revamping. Identified several sources of
146  * unnecessary bandwidth.
147  * 
148  * 16    2/21/99 6:01p Dave
149  * Fixed standalone WSS packets. 
150  * 
151  * 15    2/21/99 1:48p Dave
152  * Some code for monitoring datarate for multiplayer in detail.
153  * 
154  * 14    1/21/99 2:06p Dave
155  * Final checkin for multiplayer testing.
156  * 
157  * 13    1/19/99 3:57p Andsager
158  * Round 2 of variables
159  * 
160  * 12    1/12/99 12:53a Dave
161  * More work on beam weapons - made collision detection very efficient -
162  * collide against all object types properly - made 3 movement types
163  * smooth. Put in test code to check for possible non-darkening pixels on
164  * object textures.
165  * 
166  * 11    1/08/99 2:08p Dave
167  * Fixed software rendering for pofview. Super early support for AWACS and
168  * beam weapons.
169  * 
170  * 10    12/06/98 2:36p Dave
171  * Drastically improved nebula fogging.
172  * 
173  * 9     12/04/98 3:37p Andsager
174  * Added comment out asteroid launcher
175  * 
176  * 8     11/19/98 4:19p Dave
177  * Put IPX sockets back in psnet. Consolidated all multiplayer config
178  * files into one.
179  * 
180  * 7     11/05/98 5:55p Dave
181  * Big pass at reducing #includes
182  * 
183  * 6     10/26/98 9:42a Dave
184  * Early flak gun support.
185  * 
186  * 5     10/20/98 1:39p Andsager
187  * Make so sparks follow animated ship submodels.  Modify
188  * ship_weapon_do_hit_stuff() and ship_apply_local_damage() to add
189  * submodel_num.  Add submodel_num to multiplayer hit packet.
190  * 
191  * 4     10/13/98 9:28a Dave
192  * Started neatening up freespace.h. Many variables renamed and
193  * reorganized. Added AlphaColors.[h,cpp]
194  * 
195  * 3     10/09/98 2:57p Dave
196  * Starting splitting up OS stuff.
197  * 
198  * 2     10/07/98 10:53a Dave
199  * Initial checkin.
200  * 
201  * 1     10/07/98 10:49a Dave
202  * 
203  * 387   6/17/98 11:02a Lawrance
204  * show what cheat code is in the comment
205  * 
206  * 386   6/09/98 5:15p Lawrance
207  * French/German localization
208  * 
209  * 385   6/09/98 10:31a Hoffoss
210  * Created index numbers for all xstr() references.  Any new xstr() stuff
211  * added from here on out should be added to the end if the list.  The
212  * current list count can be found in FreeSpace.cpp (search for
213  * XSTR_SIZE).
214  * 
215  * 384   6/01/98 11:43a John
216  * JAS & MK:  Classified all strings for localization.
217  * 
218  * 383   5/24/98 1:46p Mike
219  * Final cheat codes.
220  * 
221  * 382   5/19/98 2:20p Mike
222  * Comment out nprintf().
223  * 
224  * 381   5/19/98 12:19p Mike
225  * Cheat codes!
226  * 
227  * 380   5/19/98 11:11a Lawrance
228  * Make 'G' only target hostiles
229  * 
230  * 379   5/18/98 11:00p Mike
231  * Adding support for cheat system.
232  * 
233  * 378   5/18/98 12:41a Allender
234  * fixed subsystem problems on clients (i.e. not reporting properly on
235  * damage indicator).  Fixed ingame join problem with respawns.  minor
236  * comm menu stuff
237  * 
238  * 377   5/17/98 1:43a Dave
239  * Eradicated chatbox problems. Remove speed match for observers. Put in
240  * help screens for PXO. Fix messaging and end mission privelges. Fixed
241  * team select screen bugs. Misc UI fixes.
242  * 
243  * 376   5/15/98 8:36p Lawrance
244  * Add 'target ship that last sent transmission' target key
245  * 
246  * 375   5/14/98 11:07a Lawrance
247  * Ensure looped sounds get stopped before stopping all channels
248  * 
249  * 374   5/12/98 11:59p Dave
250  * Put in some more functionality for Parallax Online.
251  * 
252  * 373   5/11/98 5:29p Hoffoss
253  * Added mouse button mapped to joystick button support.
254  * 
255  * 372   5/08/98 10:14a Lawrance
256  * Play sound when auto-targeting gets toggled.
257  * 
258  * 371   5/04/98 9:25a Allender
259  * don't allow time compression in multiplayer
260  * 
261  * 370   4/30/98 4:43p Allender
262  * trap player obj when changing dual fire status on ship
263  * 
264  * 369   4/30/98 4:16p Peter
265  * fixes for critical button functions when a player (client) ship is dead
266  * or dying
267  * 
268  * 368   4/27/98 9:03a Dave
269  * Fixed a multiplayer sequencing bug where paused players who were in the
270  * options screen got an SDL_assert when unpausing. Removed an optimiized
271  * build warning in keycontrol. 
272  * 
273  * 367   4/26/98 4:29p Lawrance
274  * Put back time compression keys... somehow they were trashed by a later
275  * checkin.
276  * 
277  * 366   4/25/98 5:36p Mike
278  * Prevent player warpout if engine < 10%.
279  * 
280  * $NoKeywords: $
281  */
282
283 #include "pstypes.h"
284 #include "linklist.h"
285 #include "key.h"
286 #include "joy.h"
287 #include "timer.h"
288 #include "ship.h"
289 #include "player.h"
290 #include "weapon.h"
291 #include "hud.h"
292 #include "contexthelp.h"
293 #include "gamesequence.h"
294 #include "osapi.h"
295 #include "missiongoals.h"
296 #include "hud.h"
297 #include "hudtarget.h"
298 #include "optionsmenu.h"
299 #include "freespace.h"
300 #include "controlsconfig.h"
301 #include "mouse.h"
302 #include "hudets.h"
303 #include "multi.h"
304 #include "multiutil.h"
305 #include "sound.h"
306 #include "gamesnd.h"
307 #include "bmpman.h"
308 #include "hudsquadmsg.h"
309 #include "eventmusic.h"
310 #include "animplay.h"
311 #include "freespace.h"
312 #include "cmeasure.h"
313 #include "missionhotkey.h"
314 #include "afterburner.h"
315 #include "missionparse.h"
316 #include "hudescort.h"
317 #include "hudshield.h"
318 #include "multiutil.h"
319 #include "multimsgs.h"
320 #include "keycontrol.h"
321 #include "shiphit.h"
322 #include "shipfx.h"
323 #include "hud.h"
324 #include "hudobserver.h"
325 #include "missionlog.h"
326 #include "hudtargetbox.h"
327 #include "popup.h"
328 #include "objcollide.h"
329 #include "hudconfig.h"
330 #include "missioncampaign.h"
331 #include "rtvoice.h"
332 #include "multi_respawn.h"
333 #include "multi_pmsg.h"
334 #include "crypt.h"
335 #include "ui.h"
336 #include "multi_pause.h"
337 #include "multi_observer.h"
338 #include "multi_endgame.h"
339 #include "beam.h"
340 #include "neblightning.h"
341 #include "supernova.h"
342 #include "missionmessage.h"
343 #include "mainhallmenu.h"
344 #include "aigoals.h"
345 #include "localize.h"
346
347 // --------------------------------------------------------------
348 // Global to file 
349 // --------------------------------------------------------------
350
351 // --------------------------------------------------------------
352 // Externals
353 // --------------------------------------------------------------
354 typedef struct asteroid_field {
355         vector  min_bound;                                              //      Minimum range of field.
356         vector  max_bound;                                              //      Maximum range of field.
357         vector  vel;                                                            //      Average asteroid moves at this velocity.
358         float           speed;                                                  // Average speed of field
359         int             num_initial_asteroids;          //      Number of asteroids at creation.
360 } asteroid_field;
361
362 #define CHEAT_BUFFER_LEN        20
363 #define CHEATSPOT                               (CHEAT_BUFFER_LEN - 1)
364
365 char CheatBuffer[CHEAT_BUFFER_LEN+1];
366
367 #if defined(FS2_DEMO)
368         const char *Cheat_code_demo = NOX("33BE^(8]C01(:=BHt");
369 #elif defined(MAKE_FS1)
370         const char *Cheat_code_gr = NOX("BNdEgDB\\s?0XD1?0)");          // de:www.volition-inc.com
371         const char *Cheat_code = NOX("E5B?(\"=H'5UTE$o%D");                     // www.volition-inc.com
372         const char *Cheat_code_movies = NOX("iC:1C06,'00SoXyY6");               // freespacestandsalone
373 #else
374         const char *Cheat_code = NOX("33BE^(8]C01(:=BHt");                                      // www.freespace2.com
375         const char *Cheat_code_fish = NOX("bDc9y+$;#AIDRoouM");                 // vasudanswuvfishes
376         const char *Cheat_code_headz = NOX("!;:::@>F7L?@@2:@A");                        // humanheadsinside.
377         const char *Cheat_code_tooled = NOX("sipp-^rM@L!U^usjX");               // tooledworkedowned
378         const char *Cheat_code_pirate = NOX("MAP4YP[4=-2uC(yJ^");               // arrrrwalktheplank    
379         const char *Cheat_code_skip = NOX("7!ICkSI\"(8n3JesBP");                        // skipmemymissionyo
380 #endif
381                                                                                   // 666)6=N79+Z45=BE0e
382 int Tool_enabled = 0;
383
384         /*
385 #else 
386         // list of the cheat codes
387         //#ifdef INTERPLAYQA
388         // "DavidPerry" NOX("0!XZQ*K.pu");
389         // NOX("&BvWJe=a?$VP*=@2W,2Y"); // Super-secret 20 character string!
390         //NOX("STs`nHqW\\lv#KD_aCSWN"); //      solveditonceandforall (note double \\ as string contains \.
391         //XSTR:OFF
392         char *Cheat_code_in_game = NOX("///FES)P<A5=7CCB!n10"); //      www.volition-inc.com
393         char *Cheat_code_movies =  NOX("&BvWJe=a?$VP*=@2W,2Y"); // freespacestandsalone
394         char *Cheat_code_pirate = NOX("%,sPzoE>\\+_(Qs#+h-8o");                         // arrwalktheplankmatey
395         //XSTR:ON
396 #endif
397         */
398
399 int All_movies_enabled = 0;
400
401 //int Debug_allowed = 0;
402
403 //#endif
404
405 extern int AI_watch_object;
406 extern int Countermeasures_enabled;
407
408 extern fix Game_time_compression;
409
410 extern float do_subobj_hit_stuff(object *ship_obj, object *other_obj, vector *hitpos, float damage);
411
412 extern void mission_goal_mark_all_true( int type );
413
414 int Normal_key_set[] = {
415         TARGET_NEXT,
416         TARGET_PREV,
417         TARGET_NEXT_CLOSEST_HOSTILE,
418         TARGET_PREV_CLOSEST_HOSTILE,
419         TARGET_NEXT_CLOSEST_FRIENDLY,
420         TARGET_PREV_CLOSEST_FRIENDLY,
421         TARGET_TARGETS_TARGET,
422         TARGET_SHIP_IN_RETICLE,
423 #ifndef FS1_DEMO
424         TARGET_LAST_TRANMISSION_SENDER,
425 #endif
426         TARGET_CLOSEST_SHIP_ATTACKING_TARGET,
427         TARGET_CLOSEST_SHIP_ATTACKING_SELF,
428         STOP_TARGETING_SHIP,
429         TOGGLE_AUTO_TARGETING,
430         TARGET_SUBOBJECT_IN_RETICLE,
431         TARGET_PREV_SUBOBJECT,
432         TARGET_NEXT_SUBOBJECT,
433         STOP_TARGETING_SUBSYSTEM,
434
435         TARGET_NEXT_UNINSPECTED_CARGO,
436         TARGET_PREV_UNINSPECTED_CARGO,
437         TARGET_NEWEST_SHIP,
438         TARGET_NEXT_LIVE_TURRET,
439         TARGET_PREV_LIVE_TURRET,
440         TARGET_NEXT_BOMB,
441         TARGET_PREV_BOMB,
442
443         ATTACK_MESSAGE,
444         DISARM_MESSAGE,
445         DISABLE_MESSAGE,
446         ATTACK_SUBSYSTEM_MESSAGE,
447         CAPTURE_MESSAGE,
448         ENGAGE_MESSAGE,
449         FORM_MESSAGE,
450         PROTECT_MESSAGE,
451         COVER_MESSAGE,
452         WARP_MESSAGE,
453         REARM_MESSAGE,
454         IGNORE_MESSAGE,
455         SQUADMSG_MENU,
456
457         VIEW_CHASE,
458         VIEW_OTHER_SHIP,
459
460         SHOW_GOALS,
461         END_MISSION,
462
463         ADD_REMOVE_ESCORT,
464         ESCORT_CLEAR,
465         TARGET_NEXT_ESCORT_SHIP,
466
467         XFER_SHIELD,
468         XFER_LASER,
469         INCREASE_SHIELD,
470         INCREASE_WEAPON,
471         INCREASE_ENGINE,
472         DECREASE_SHIELD,
473         DECREASE_WEAPON,
474         DECREASE_ENGINE,
475 #ifndef FS1_DEMO
476         ETS_EQUALIZE,
477 #endif
478         SHIELD_EQUALIZE,
479         SHIELD_XFER_TOP,
480         SHIELD_XFER_BOTTOM,
481         SHIELD_XFER_RIGHT,
482         SHIELD_XFER_LEFT,
483
484         CYCLE_NEXT_PRIMARY,
485         CYCLE_PREV_PRIMARY,
486         CYCLE_SECONDARY,
487         CYCLE_NUM_MISSLES,
488         RADAR_RANGE_CYCLE,
489
490         MATCH_TARGET_SPEED,
491         TOGGLE_AUTO_MATCH_TARGET_SPEED,
492
493         VIEW_EXTERNAL,
494         VIEW_EXTERNAL_TOGGLE_CAMERA_LOCK,
495         LAUNCH_COUNTERMEASURE,
496         ONE_THIRD_THROTTLE,
497         TWO_THIRDS_THROTTLE,
498         PLUS_5_PERCENT_THROTTLE,
499         MINUS_5_PERCENT_THROTTLE,
500         ZERO_THROTTLE,
501         MAX_THROTTLE,
502
503         TARGET_CLOSEST_REPAIR_SHIP,
504
505         MULTI_MESSAGE_ALL,
506         MULTI_MESSAGE_FRIENDLY,
507         MULTI_MESSAGE_HOSTILE,
508         MULTI_MESSAGE_TARGET,
509         MULTI_OBSERVER_ZOOM_TO,
510
511         TIME_SPEED_UP,
512         TIME_SLOW_DOWN,
513 #ifndef MAKE_FS1
514         TOGGLE_HUD_CONTRAST,
515
516 #ifndef FS2_DEMO
517         MULTI_TOGGLE_NETINFO,
518         MULTI_SELF_DESTRUCT
519 #endif
520 #endif
521 };
522
523 int Dead_key_set[] = {
524         TARGET_NEXT,
525         TARGET_PREV,
526         TARGET_NEXT_CLOSEST_HOSTILE,
527         TARGET_PREV_CLOSEST_HOSTILE,
528         TARGET_NEXT_CLOSEST_FRIENDLY,
529         TARGET_PREV_CLOSEST_FRIENDLY,
530         TARGET_TARGETS_TARGET,
531         TARGET_CLOSEST_SHIP_ATTACKING_TARGET,
532         STOP_TARGETING_SHIP,
533         TOGGLE_AUTO_TARGETING,
534         TARGET_SUBOBJECT_IN_RETICLE,
535         TARGET_PREV_SUBOBJECT,
536         TARGET_NEXT_SUBOBJECT,
537         STOP_TARGETING_SUBSYSTEM,
538         TARGET_NEWEST_SHIP,
539         TARGET_NEXT_LIVE_TURRET,
540         TARGET_PREV_LIVE_TURRET,
541         TARGET_NEXT_BOMB,
542         TARGET_PREV_BOMB,
543
544         VIEW_CHASE,
545         VIEW_OTHER_SHIP,
546
547         SHOW_GOALS,
548
549         ADD_REMOVE_ESCORT,
550         ESCORT_CLEAR,
551         TARGET_NEXT_ESCORT_SHIP,
552         TARGET_CLOSEST_REPAIR_SHIP,     
553
554         MULTI_MESSAGE_ALL,
555         MULTI_MESSAGE_FRIENDLY,
556         MULTI_MESSAGE_HOSTILE,
557         MULTI_MESSAGE_TARGET,
558         MULTI_OBSERVER_ZOOM_TO,
559
560         TIME_SPEED_UP,
561         TIME_SLOW_DOWN
562 };
563
564 int Critical_key_set[] = {              
565         CYCLE_SECONDARY,                        
566         CYCLE_NUM_MISSLES,                      
567         INCREASE_WEAPON,                        
568         DECREASE_WEAPON,        
569         INCREASE_SHIELD,                        
570         DECREASE_SHIELD,                        
571         INCREASE_ENGINE,                        
572         DECREASE_ENGINE,                        
573 #ifndef FS1_DEMO
574         ETS_EQUALIZE,
575 #endif
576         SHIELD_EQUALIZE,                        
577         SHIELD_XFER_TOP,                        
578         SHIELD_XFER_BOTTOM,                     
579         SHIELD_XFER_LEFT,                       
580         SHIELD_XFER_RIGHT,                      
581         XFER_SHIELD,                    
582         XFER_LASER,                     
583 };
584
585 int Non_critical_key_set[] = {
586         CYCLE_NEXT_PRIMARY,             
587         CYCLE_PREV_PRIMARY,                     
588         MATCH_TARGET_SPEED,                     
589         TOGGLE_AUTO_MATCH_TARGET_SPEED,                 
590         TARGET_NEXT,    
591         TARGET_PREV,                    
592         TARGET_NEXT_CLOSEST_HOSTILE,                    
593         TARGET_PREV_CLOSEST_HOSTILE,                    
594         TOGGLE_AUTO_TARGETING,                  
595         TARGET_NEXT_CLOSEST_FRIENDLY,                   
596         TARGET_PREV_CLOSEST_FRIENDLY,                   
597         TARGET_SHIP_IN_RETICLE,                 
598 #ifndef FS1_DEMO
599         TARGET_LAST_TRANMISSION_SENDER,
600 #endif
601         TARGET_CLOSEST_REPAIR_SHIP,                     
602         TARGET_CLOSEST_SHIP_ATTACKING_TARGET,                   
603         STOP_TARGETING_SHIP,                    
604         TARGET_CLOSEST_SHIP_ATTACKING_SELF,                     
605         TARGET_TARGETS_TARGET,                  
606         TARGET_SUBOBJECT_IN_RETICLE,                    
607         TARGET_PREV_SUBOBJECT,                  
608         TARGET_NEXT_SUBOBJECT,                  
609         STOP_TARGETING_SUBSYSTEM,
610         TARGET_NEXT_BOMB,
611         TARGET_PREV_BOMB,
612         TARGET_NEXT_UNINSPECTED_CARGO,
613         TARGET_PREV_UNINSPECTED_CARGO,
614         TARGET_NEWEST_SHIP,
615         TARGET_NEXT_LIVE_TURRET,
616         TARGET_PREV_LIVE_TURRET,
617         ATTACK_MESSAGE,
618         DISARM_MESSAGE,
619         DISABLE_MESSAGE,
620         ATTACK_SUBSYSTEM_MESSAGE,
621         CAPTURE_MESSAGE,
622         ENGAGE_MESSAGE,
623    FORM_MESSAGE,
624         PROTECT_MESSAGE,
625         COVER_MESSAGE,
626         WARP_MESSAGE,
627         IGNORE_MESSAGE,
628         REARM_MESSAGE,
629         VIEW_CHASE,
630         VIEW_EXTERNAL,
631         VIEW_EXTERNAL_TOGGLE_CAMERA_LOCK,
632         VIEW_OTHER_SHIP,
633         RADAR_RANGE_CYCLE,
634         SQUADMSG_MENU,
635         SHOW_GOALS,
636         END_MISSION,
637         ADD_REMOVE_ESCORT,
638         ESCORT_CLEAR,
639         TARGET_NEXT_ESCORT_SHIP,        
640         MULTI_MESSAGE_ALL,
641         MULTI_MESSAGE_FRIENDLY,
642         MULTI_MESSAGE_HOSTILE,
643         MULTI_MESSAGE_TARGET,
644         MULTI_OBSERVER_ZOOM_TO,
645 #ifndef MAKE_FS1
646         TOGGLE_HUD_CONTRAST,
647
648 #ifndef FS2_DEMO
649         MULTI_TOGGLE_NETINFO,
650         MULTI_SELF_DESTRUCT
651 #endif
652 #endif
653 };
654
655
656 // set sizes of the key sets automatically
657 int Normal_key_set_size = sizeof(Normal_key_set) / sizeof(int);
658 int Dead_key_set_size = sizeof(Dead_key_set) / sizeof(int);
659 int Critical_key_set_size = sizeof(Critical_key_set) / sizeof(int);
660 int Non_critical_key_set_size = sizeof(Non_critical_key_set) / sizeof(int);
661
662 // --------------------------------------------------------------
663 // routine to process keys used only for debugging
664 // --------------------------------------------------------------
665 //#ifndef NDEBUG
666
667 void debug_cycle_player_ship(int delta)
668 {
669         if ( Player_obj == NULL )
670                 return;
671
672         int si_index = Ships[Player_obj->instance].ship_info_index;
673         int sanity = 0;
674         ship_info       *sip;
675         while ( TRUE ) {
676                 si_index += delta;
677                 if ( si_index > MAX_SHIP_TYPES ){
678                         si_index = 0;
679                 }
680                 if ( si_index < 0 ){
681                         si_index = MAX_SHIP_TYPES - 1;
682                 }
683                 sip = &Ship_info[si_index];
684                 if ( sip->flags & SIF_PLAYER_SHIP ){
685                         break;
686                 }
687
688                 // just in case
689                 sanity++;
690                 if ( sanity > MAX_SHIP_TYPES ){
691                         break;
692                 }
693         }
694
695         change_ship_type(Player_obj->instance, si_index);
696         HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "Player ship changed to %s", 0), Ship_info[si_index].name);                 
697 }
698
699 // cycle targeted ship to next ship in that species
700 void debug_cycle_targeted_ship(int delta)
701 {
702         object          *objp;
703         ship_info       *sip;
704         int                     si_index, species;
705         char                    name[NAME_LENGTH];
706
707         if ( Player_ai->target_objnum == -1 )
708                 return;
709
710         objp = &Objects[Player_ai->target_objnum];
711         if ( objp->type != OBJ_SHIP )
712                 return;
713
714         si_index = Ships[objp->instance].ship_info_index;
715         SDL_assert(si_index != -1 );
716         species = Ship_info[si_index].species;
717
718         int sanity = 0;
719
720         while ( TRUE ) {
721                 si_index += delta;
722                 if ( si_index > MAX_SHIP_TYPES )
723                         si_index = 0;
724                 if ( si_index < 0 )
725                         si_index = MAX_SHIP_TYPES-1;
726
727         
728                 sip = &Ship_info[si_index];
729         
730                 // if it has test in the name, jump over it
731                 SDL_strlcpy(name, sip->name, SDL_arraysize(name));
732                 SDL_strlwr(name);
733                 if ( strstr(name,NOX("test")) != NULL )
734                         continue;
735
736                 if ( sip->species == species && (sip->flags & (SIF_FIGHTER | SIF_BOMBER | SIF_TRANSPORT) ) )
737                         break;
738
739                 // just in case
740                 sanity++;
741                 if ( sanity > MAX_SHIP_TYPES )
742                         break;
743         }
744
745         change_ship_type(objp->instance, si_index);
746         HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "Changed player target to %s", 1), Ship_info[si_index].name);                       
747 }
748
749 void debug_max_secondary_weapons(object *objp)
750 {
751         int index;
752         ship *shipp = &Ships[objp->instance];
753         ship_info *sip = &Ship_info[shipp->ship_info_index];
754
755         for ( index = 0; index < MAX_SECONDARY_BANKS; index++ ) {
756                 shipp->weapons.secondary_bank_ammo[index] = sip->secondary_bank_ammo_capacity[index];
757         }
758 }
759
760 void debug_change_song(int delta)
761 {
762         char buf[256];
763         if ( event_music_next_soundtrack(delta) != -1 ) {
764                 event_music_get_soundtrack_name(buf, sizeof(buf));
765                 HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "Soundtrack changed to: %s", 2), buf);
766
767         } else {
768                 HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "Event music is not playing", 3));
769         }
770 }
771
772 //extern void set_global_ignore_object(int objnum);
773
774 extern void hud_target_asteroid();
775 extern int Framerate_delay;
776
777 extern void snd_stop_any_sound();
778
779 void process_debug_keys(int k)
780 {
781 #ifdef INTERPLAYQA
782         if ( !Debug_allowed )
783                 return;
784 #endif
785
786         // if ( (k & KEY_DEBUGGED) && (Game_mode & GM_RECORDING_DEMO) )
787                 // return;
788
789         switch (k) {
790                 case KEY_DEBUGGED + SDLK_h:
791                         hud_target_toggle_hidden_from_sensors();
792                         break;
793
794                 case KEY_DEBUGGED + SDLK_f:
795                         /*
796                         int i;
797                         for (i=0; i<NUM_HUD_GAUGES; i++) {
798                                 hud_gauge_start_flash(i);
799                         }
800                         */
801                         extern int wacky_scheme;
802                         if(wacky_scheme == 3){
803                                 wacky_scheme = 0;
804                         } else {
805                                 wacky_scheme++;
806                         }
807                         break;
808                 
809                 case KEY_DEBUGGED + KEY_ALTED + SDLK_f:
810                         Framerate_delay += 10;
811                         HUD_printf(XSTR( "Framerate delay increased to %i milliseconds per frame.", 4), Framerate_delay);
812                         break;
813
814                 case KEY_DEBUGGED + KEY_ALTED + KEY_SHIFTED + SDLK_f:
815                         Framerate_delay -= 10;
816                         if (Framerate_delay < 0)
817                                 Framerate_delay = 0;
818
819                         HUD_printf(XSTR( "Framerate delay decreased to %i milliseconds per frame.", 5), Framerate_delay);
820                         break;
821
822                 case KEY_DEBUGGED + SDLK_c:
823                 case KEY_DEBUGGED1 + SDLK_c:
824                         // hud_enemymsg_toggle();
825                         if(Player_obj->flags & OF_COLLIDES){
826                                 obj_set_flags(Player_obj, Player_obj->flags & ~(OF_COLLIDES));
827                                 HUD_sourced_printf(HUD_SOURCE_HIDDEN, "Player no longer collides");
828                         } else {
829                                 obj_set_flags(Player_obj, Player_obj->flags | OF_COLLIDES);
830                                 HUD_sourced_printf(HUD_SOURCE_HIDDEN, "Player collides");
831                         }
832                         break;
833
834                 case KEY_DEBUGGED + KEY_SHIFTED + SDLK_c:
835                 case KEY_DEBUGGED1 + KEY_SHIFTED + SDLK_c:
836                         Countermeasures_enabled = !Countermeasures_enabled;
837                         HUD_printf(XSTR( "Countermeasure firing: %s", 6), Countermeasures_enabled ? XSTR( "ENABLED", 7) : XSTR( "DISABLED", 8));
838                         break;
839
840                 case KEY_DEBUGGED + SDLK_e:
841                         gameseq_post_event(GS_EVENT_EVENT_DEBUG);
842                         break;
843
844                 case KEY_DEBUGGED + SDLK_COMMA:
845                         if ( Game_time_compression > (F1_0/4) ){                // can't compress below 0.25
846                                 Game_time_compression /= 2;
847                         }
848                         break;
849                 case KEY_DEBUGGED + SDLK_PERIOD:
850                         if ( Game_time_compression < (F1_0*8) ){
851                                 Game_time_compression *= 2;
852                         }
853                         break;
854
855                 //      Kill! the currently targeted ship.
856                 case KEY_DEBUGGED + SDLK_k:
857                 case KEY_DEBUGGED1 + SDLK_k:
858                         if (Player_ai->target_objnum != -1) {
859                                 object  *objp = &Objects[Player_ai->target_objnum];
860
861                                 switch (objp->type) {
862                                 case OBJ_SHIP:
863                                         ship_apply_local_damage( objp, Player_obj, &objp->pos, 100000.0f, MISS_SHIELDS, CREATE_SPARKS);
864                                         ship_apply_local_damage( objp, Player_obj, &objp->pos, 1.0f, MISS_SHIELDS, CREATE_SPARKS);
865                                         break;
866                                 case OBJ_WEAPON:
867                                         Weapons[objp->instance].lifeleft = 0.01f;
868                                         break;
869                                 }
870                         }
871
872                         break;
873                 
874                 // play the next mission message
875                 case KEY_DEBUGGED + SDLK_v:
876                         extern int Message_debug_index;
877                         extern int Num_messages_playing;
878                         // stop any other messages
879                         if(Num_messages_playing){
880                                 message_kill_all(1);
881                         }
882
883                         // next message
884                         if(Message_debug_index >= Num_messages - 1){
885                                 Message_debug_index = Num_builtin_messages;
886                         } else {
887                                 Message_debug_index++;
888                         }
889                         
890                         // play the message
891                         message_send_unique_to_player( Messages[Message_debug_index].name, Message_waves[Messages[Message_debug_index].wave_info.index].name, MESSAGE_SOURCE_SPECIAL, MESSAGE_PRIORITY_HIGH, 0, 0 );                    
892                         if (Messages[Message_debug_index].avi_info.index == -1) {
893                                 HUD_printf("No anim set for message \"%s\"; None will play!", Messages[Message_debug_index].name);
894                         }
895                         break;
896
897                 // play the previous mission message
898                 case KEY_DEBUGGED + KEY_SHIFTED + SDLK_v:
899                         extern int Message_debug_index;
900                         extern int Num_messages_playing;
901                         // stop any other messages
902                         if(Num_messages_playing){
903                                 message_kill_all(1);
904                         }
905
906                         // go maybe go down one
907                         if(Message_debug_index == Num_builtin_messages - 1){
908                                 Message_debug_index = Num_builtin_messages;
909                         } else if(Message_debug_index > Num_builtin_messages){
910                                 Message_debug_index--;
911                         }
912                         
913                         // play the message
914                         message_send_unique_to_player( Messages[Message_debug_index].name, Message_waves[Messages[Message_debug_index].wave_info.index].name, MESSAGE_SOURCE_SPECIAL, MESSAGE_PRIORITY_HIGH, 0, 0 );
915                         if (Messages[Message_debug_index].avi_info.index == -1) {
916                                 HUD_printf("No avi associated with this message; None will play!");
917                         }
918                         break;
919
920                 // reset to the beginning of mission messages
921                 case KEY_DEBUGGED + KEY_ALTED + SDLK_v:
922                         extern int Message_debug_index;
923                         Message_debug_index = Num_builtin_messages - 1;
924                         HUD_printf("Resetting to first mission message");
925                         break;
926
927                 //      Kill! the currently targeted ship.
928                 case KEY_DEBUGGED + KEY_ALTED + KEY_SHIFTED + SDLK_k:
929                 case KEY_DEBUGGED1 + KEY_ALTED + KEY_SHIFTED + SDLK_k:
930                         if (Player_ai->target_objnum != -1) {
931                                 object  *objp = &Objects[Player_ai->target_objnum];
932
933                                 if (objp->type == OBJ_SHIP) {
934                                         ship_apply_local_damage( objp, Player_obj, &objp->pos, Ship_info[Ships[objp->instance].ship_info_index].initial_hull_strength * 0.1f + 10.0f, MISS_SHIELDS, CREATE_SPARKS);
935                                 }
936                         }
937                         break;
938
939                         //      Kill the currently targeted subsystem.
940                 case KEY_DEBUGGED + KEY_SHIFTED + SDLK_k:
941                 case KEY_DEBUGGED1 + KEY_SHIFTED + SDLK_k:
942                         if ((Player_ai->target_objnum != -1) && (Player_ai->targeted_subsys != NULL)) {
943                                 object  *objp = &Objects[Player_ai->target_objnum];
944                                 if ( objp->type == OBJ_SHIP ) {
945                                         ship            *sp = &Ships[objp->instance];
946                                         vector  g_subobj_pos;
947
948                                         get_subsystem_world_pos(objp, Player_ai->targeted_subsys, &g_subobj_pos);
949
950                                         do_subobj_hit_stuff(objp, Player_obj, &g_subobj_pos, (float) -Player_ai->targeted_subsys->system_info->type); //100.0f);
951
952                                         if ( sp->subsys_info[SUBSYSTEM_ENGINE].current_hits <= 0.0f ) {
953                                                 mission_log_add_entry(LOG_SHIP_DISABLED, sp->ship_name, NULL );
954                                                 sp->flags |= SF_DISABLED;                               // add the disabled flag
955                                         }
956
957                                         if ( sp->subsys_info[SUBSYSTEM_TURRET].current_hits <= 0.0f ) {
958                                                 mission_log_add_entry(LOG_SHIP_DISARMED, sp->ship_name, NULL );
959                                                 // sp->flags |= SF_DISARMED;                            // add the disarmed flag
960                                         }
961                                 }
962                         }
963                         break;
964
965                 case KEY_DEBUGGED + KEY_ALTED + SDLK_k:
966                 case KEY_DEBUGGED1 + KEY_ALTED + SDLK_k:
967                         {
968                                 float   shield, integrity;
969                                 vector  pos, randvec;
970
971                                 vm_vec_rand_vec_quick(&randvec);
972                                 vm_vec_scale_add(&pos, &Player_obj->pos, &randvec, Player_obj->radius);
973                         ship_apply_local_damage(Player_obj, Player_obj, &pos, 25.0f, MISS_SHIELDS, CREATE_SPARKS);
974                         hud_get_target_strength(Player_obj, &shield, &integrity);
975                         HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "You knocked yourself down to %7.3f percent hull.\n", 9), 100.0f * integrity);
976                         break;
977                         }
978                         
979                 //      Whack down the player's shield and hull by a little more than 50%
980                 //      Select next object to be viewed by AI.
981                 case KEY_DEBUGGED + SDLK_i:
982                 case KEY_DEBUGGED1 + SDLK_i:
983                         Player_obj->flags ^= OF_INVULNERABLE;
984                         HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "You are %s", 10), Player_obj->flags & OF_INVULNERABLE ? XSTR( "now INVULNERABLE!", 11) : XSTR( "no longer invulnerable...", 12));
985                         break;
986
987                 case KEY_DEBUGGED + KEY_SHIFTED + SDLK_i:
988                 case KEY_DEBUGGED1 + KEY_SHIFTED + SDLK_i:
989                         if (Player_ai->target_objnum != -1) {
990                                 object  *objp = &Objects[Player_ai->target_objnum];
991
992                                 objp->flags ^= OF_INVULNERABLE;
993                                 HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "Player's target [%s] is %s", 13), Ships[objp->instance].ship_name, objp->flags & OF_INVULNERABLE ? XSTR( "now INVULNERABLE!", 11) : XSTR( "no longer invulnerable...", 12));
994                         }
995                         break;
996 /*
997                 case KEY_DEBUGGED + KEY_ALTED + SDLK_i:
998                         if (Player_ai->target_objnum != -1)
999                                 set_global_ignore_object(Player_ai->target_objnum);
1000                         break;
1001 */
1002
1003                 case KEY_DEBUGGED + SDLK_n:
1004                         AI_watch_object++;
1005                         HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "Spewing debug info about object #%d", 14), AI_watch_object);
1006                         break;
1007
1008                 case KEY_DEBUGGED + SDLK_o:
1009 #ifdef MAKE_FS1
1010                 case KEY_DEBUGGED1 + SDLK_o:
1011 #endif
1012                         toggle_player_object();
1013                         break;                          
1014
1015                 case KEY_DEBUGGED + KEY_SHIFTED + SDLK_o:
1016                         extern int Debug_octant;
1017                         if(Debug_octant == 7){
1018                                 Debug_octant = -1;
1019                         } else {
1020                                 Debug_octant++;
1021                         }
1022                         nprintf(("General", "Debug_octant == %d\n", Debug_octant));
1023                         break;
1024
1025 #ifndef MAKE_FS1
1026                 case KEY_DEBUGGED + SDLK_p:
1027                         supernova_start(20);
1028                         break;
1029 #endif
1030
1031                 case KEY_DEBUGGED + SDLK_w:
1032                 case KEY_DEBUGGED1 + SDLK_w:
1033                 case KEY_DEBUGGED + KEY_SHIFTED + SDLK_w:
1034                 case KEY_DEBUGGED1 + KEY_SHIFTED + SDLK_w:
1035                         // temp code for testing purposes, toggles weapon energy cheat
1036                         Weapon_energy_cheat = !Weapon_energy_cheat;
1037                         if (Weapon_energy_cheat) {
1038                                 if (k & KEY_SHIFTED)
1039                                         HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "Weapon energy and missile count will always be at full ALL SHIPS!", 15));
1040                                 else
1041                                         HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "Weapon energy and missile count will always be at full for player", 16));
1042
1043                                 debug_max_secondary_weapons(Player_obj);
1044                                 if (k & KEY_SHIFTED) {
1045                                         object  *objp;
1046
1047                                         for ( objp = GET_FIRST(&obj_used_list); objp !=END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp) )
1048                                                 if (objp->type == OBJ_SHIP)
1049                                                         debug_max_secondary_weapons(objp);
1050                                 }
1051
1052                         } else
1053                                 HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "Normal weapon energy system / missile count restored", 17));
1054
1055                         break;
1056
1057                 case KEY_DEBUGGED + SDLK_g:
1058 #ifdef MAKE_FS1
1059                 case KEY_DEBUGGED1 + SDLK_g:
1060 #endif
1061                         mission_goal_mark_all_true( PRIMARY_GOAL );
1062                         break;
1063
1064                 case KEY_DEBUGGED + SDLK_g + KEY_SHIFTED:
1065 #ifdef MAKE_FS1
1066                 case KEY_DEBUGGED1 + SDLK_g + KEY_SHIFTED:
1067 #endif
1068                         mission_goal_mark_all_true( SECONDARY_GOAL );
1069                         break;
1070
1071                 case KEY_DEBUGGED + SDLK_g + KEY_ALTED:
1072 #ifdef MAKE_FS1
1073                 case KEY_DEBUGGED1 + SDLK_g + KEY_ALTED:
1074 #endif
1075                         mission_goal_mark_all_true( BONUS_GOAL );
1076                         break;
1077
1078                 case KEY_DEBUGGED + SDLK_9: {
1079                 case KEY_DEBUGGED1 + SDLK_9:
1080                         ship* shipp;
1081
1082                         shipp = &Ships[Player_obj->instance];
1083                         shipp->weapons.secondary_bank_weapons[shipp->weapons.current_secondary_bank]++;
1084                         if ( shipp->weapons.secondary_bank_weapons[shipp->weapons.current_secondary_bank] >= Num_weapon_types )
1085                                 shipp->weapons.secondary_bank_weapons[shipp->weapons.current_secondary_bank] = First_secondary_index;
1086
1087                         HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "Secondary Weapon forced to %s", 18), Weapon_info[shipp->weapons.secondary_bank_weapons[shipp->weapons.current_secondary_bank]].name);
1088                         break;
1089                 }
1090
1091 #ifdef MAKE_FS1
1092                 case KEY_DEBUGGED + KEY_SHIFTED + SDLK_9: {
1093                 case KEY_DEBUGGED1 + KEY_SHIFTED + SDLK_9:
1094                         ship* shipp;
1095
1096                         shipp = &Ships[Player_obj->instance];
1097                         shipp->weapons.secondary_bank_weapons[shipp->weapons.current_secondary_bank]--;
1098                         if ( shipp->weapons.secondary_bank_weapons[shipp->weapons.current_secondary_bank] < 0)
1099                                 shipp->weapons.secondary_bank_weapons[shipp->weapons.current_secondary_bank] = Num_weapon_types - 1;
1100
1101                         HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "Secondary Weapon forced to %s", 18), Weapon_info[shipp->weapons.secondary_bank_weapons[shipp->weapons.current_secondary_bank]].name);
1102                         break;
1103                 }
1104 #endif
1105
1106 #if !(defined(FS2_DEMO) || defined(FS1_DEMO))
1107                 case KEY_DEBUGGED + SDLK_u: {
1108                 case KEY_DEBUGGED1 + SDLK_u:
1109                         // launch asteroid
1110                         extern asteroid_field Asteroid_field;
1111                         object *asteroid_create(asteroid_field *asfieldp, int asteroid_type, int subtype);
1112                         object *objp = asteroid_create(&Asteroid_field, 0, 0);
1113                         vector vel;
1114                         vm_vec_copy_scale(&vel, &Player_obj->orient.v.fvec, 50.0f);
1115                         objp->phys_info.vel = vel;
1116                         objp->phys_info.desired_vel = vel;
1117                         objp->pos = Player_obj->pos;
1118                         //mission_goal_mark_all_true( PRIMARY_GOAL );
1119                         break;
1120                 }
1121 #endif
1122
1123                 case KEY_DEBUGGED + SDLK_0: {
1124                 case KEY_DEBUGGED1 + SDLK_0:
1125                         ship* shipp;
1126
1127                         shipp = &Ships[Player_obj->instance];
1128                         shipp->weapons.primary_bank_weapons[shipp->weapons.current_primary_bank]++;
1129                         if ( shipp->weapons.primary_bank_weapons[shipp->weapons.current_primary_bank] >= First_secondary_index )
1130                                 shipp->weapons.primary_bank_weapons[shipp->weapons.current_primary_bank] = 0;
1131
1132                         HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "Primary Weapon forced to %s", 19), Weapon_info[shipp->weapons.primary_bank_weapons[shipp->weapons.current_primary_bank]].name);
1133                         break;
1134                 }
1135
1136                 case KEY_DEBUGGED + KEY_SHIFTED + SDLK_0: {
1137                 case KEY_DEBUGGED1 + KEY_SHIFTED + SDLK_0:
1138                         ship* shipp;
1139
1140                         shipp = &Ships[Player_obj->instance];
1141                         shipp->weapons.primary_bank_weapons[shipp->weapons.current_primary_bank]--;
1142                         if ( shipp->weapons.primary_bank_weapons[shipp->weapons.current_primary_bank] < 0)
1143                                 shipp->weapons.primary_bank_weapons[shipp->weapons.current_primary_bank] = First_secondary_index-1 ;
1144
1145                         HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "Primary Weapon forced to %s", 19), Weapon_info[shipp->weapons.primary_bank_weapons[shipp->weapons.current_primary_bank]].name);
1146                         break;
1147                 }
1148
1149                 case KEY_DEBUGGED + SDLK_j: {
1150                         int new_pattern = event_music_return_current_pattern();
1151
1152                         new_pattern++;
1153                         if ( new_pattern >= MAX_PATTERNS )
1154                                 new_pattern = 0;
1155
1156                         event_music_change_pattern(new_pattern);
1157                         break;
1158                 }
1159
1160                 case KEY_DEBUGGED + SDLK_m: {
1161                         if ( Event_music_enabled ) {
1162                                 event_music_disable();
1163                                 HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "Event music disabled", 20));
1164
1165                         } else {
1166                                 event_music_enable();
1167                                 HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "Event music enabled", 21));
1168                         }
1169
1170                         break;
1171                 }
1172
1173                 case KEY_DEBUGGED + SDLK_r: {
1174                 // case KEY_DEBUGGED1 + SDLK_r:
1175                         if (Player_ai->target_objnum != -1)
1176                                 ai_issue_rearm_request(&Objects[Player_ai->target_objnum]);
1177                         else
1178                                 ai_issue_rearm_request(Player_obj);
1179
1180                         break;
1181                 }
1182
1183                 case KEY_DEBUGGED + KEY_SHIFTED + SDLK_UP:
1184                         Game_detail_level++;
1185                         HUD_printf( XSTR( "Detail level set to %+d\n", 22), Game_detail_level );
1186                         break;
1187
1188                 case KEY_DEBUGGED + KEY_SHIFTED + SDLK_DOWN:
1189                         Game_detail_level--;
1190                         HUD_printf( XSTR( "Detail level set to %+d\n", 22), Game_detail_level );
1191                         break;
1192
1193 #ifndef NDEBUG
1194                 case KEY_DEBUGGED + KEY_SHIFTED + SDLK_t:       {
1195                         extern int Test_begin;
1196
1197                         if ( Test_begin == 1 )
1198                                 break;
1199
1200                         Test_begin = 1;
1201                         HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "Frame Rate test started", 23));
1202
1203                         break;
1204                 }
1205 #endif
1206                 case KEY_DEBUGGED + SDLK_d:
1207                         extern int OO_update_index;                     
1208
1209                         if(MULTIPLAYER_MASTER){
1210                                 do {
1211                                         OO_update_index++;
1212                                 } while((OO_update_index < (MAX_PLAYERS-1)) && !MULTI_CONNECTED(Net_players[OO_update_index]));
1213                                 if(OO_update_index >= MAX_PLAYERS-1){
1214                                         OO_update_index = -1;
1215                                 }                       
1216                         } else {
1217                                 if(OO_update_index < 0){
1218                                         OO_update_index = MY_NET_PLAYER_NUM;
1219                                 } else {
1220                                         OO_update_index = -1;
1221                                 }
1222                         }
1223                         break;
1224
1225                 // change player ship to next flyable type
1226                 case KEY_DEBUGGED + SDLK_RIGHT:
1227                         debug_cycle_player_ship(1);
1228                         break;
1229
1230                 // change player ship to previous flyable ship
1231                 case KEY_DEBUGGED + SDLK_LEFT:
1232                         debug_cycle_player_ship(-1);
1233                         break;
1234                 
1235                 // cycle target to ship
1236                 case KEY_DEBUGGED + KEY_SHIFTED + SDLK_RIGHT:
1237                         debug_cycle_targeted_ship(1);
1238                         break;
1239
1240                 // cycle target to previous ship
1241                 case KEY_DEBUGGED + KEY_SHIFTED + SDLK_LEFT:
1242                         debug_cycle_targeted_ship(-1);
1243                         break;
1244
1245                 // change species of the targeted ship
1246                 case KEY_DEBUGGED + SDLK_s: {
1247                         if ( Player_ai->target_objnum < 0 )
1248                                 break;
1249
1250                         object          *objp;
1251                         ship_info       *sip;
1252
1253                         objp = &Objects[Player_ai->target_objnum];
1254                         if ( objp->type != OBJ_SHIP )
1255                                 return;
1256
1257                         sip = &Ship_info[Ships[objp->instance].ship_info_index];
1258                         sip->species++;
1259                         if ( sip->species > SPECIES_SHIVAN )
1260                                 sip->species = 0;
1261
1262                         HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "Species of target changed to: %s", 24), Species_names[sip->species]);
1263                         break;
1264                 }
1265                         
1266                 case KEY_DEBUGGED + KEY_SHIFTED + SDLK_s:
1267                         game_increase_skill_level();
1268                         HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "Skill level set to %s.", 25), Skill_level_names(Game_skill_level));
1269                         break;
1270
1271 #ifndef MAKE_FS1
1272                 // kill all missiles
1273                 case KEY_DEBUGGED + KEY_SHIFTED + SDLK_1:
1274                         beam_test(1);
1275                         break;                          
1276                 case KEY_DEBUGGED + KEY_SHIFTED + SDLK_2:
1277                         beam_test(2);
1278                         break;          
1279                 case KEY_DEBUGGED + KEY_SHIFTED + SDLK_3:
1280                         beam_test(3);
1281                         break;                          
1282                 case KEY_DEBUGGED + KEY_SHIFTED + SDLK_4:
1283                         beam_test(4);
1284                         break;          
1285                 case KEY_DEBUGGED + KEY_SHIFTED + SDLK_5:
1286                         beam_test(5);
1287                         break;                          
1288                 case KEY_DEBUGGED + KEY_SHIFTED + SDLK_6:
1289                         beam_test(6);
1290                         break;          
1291                 case KEY_DEBUGGED + KEY_SHIFTED + SDLK_7:
1292                         beam_test(7);
1293                         break;                          
1294                 case KEY_DEBUGGED + KEY_SHIFTED + SDLK_8:
1295                         beam_test(8);
1296                         break;          
1297                 case KEY_DEBUGGED + KEY_SHIFTED + SDLK_9:
1298                         beam_test(9);
1299                         break;                          
1300
1301                 case KEY_DEBUGGED + KEY_CTRLED + SDLK_1:
1302                         beam_test_new(1);
1303                         break;                          
1304                 case KEY_DEBUGGED + KEY_CTRLED + SDLK_2:
1305                         beam_test_new(2);
1306                         break;          
1307                 case KEY_DEBUGGED + KEY_CTRLED + SDLK_3:
1308                         beam_test_new(3);
1309                         break;
1310 #endif
1311                                         
1312                 case KEY_DEBUGGED + SDLK_t: {
1313                         char buf[256];
1314                         event_music_get_info(buf, sizeof(buf));
1315                         HUD_sourced_printf(HUD_SOURCE_HIDDEN, buf);
1316                         break;
1317                 }
1318
1319                 case KEY_DEBUGGED + SDLK_UP:
1320                         debug_change_song(1);
1321                         break;
1322
1323                 case KEY_DEBUGGED + SDLK_DOWN:
1324                         debug_change_song(-1);
1325                         break;
1326
1327 #ifndef MAKE_FS1
1328                 case SDLK_KP_MINUS: {
1329                         int init_flag = 0;
1330
1331                         if ( key_pressed(SDLK_1) )      {
1332                                 init_flag = 1;
1333                                 HUD_color_red -= 4;
1334                         } 
1335
1336                         if ( key_pressed(SDLK_2) )      {
1337                                 init_flag = 1;
1338                                 HUD_color_green -= 4;
1339                         } 
1340
1341                         if ( key_pressed(SDLK_3) )      {
1342                                 init_flag = 1;
1343                                 HUD_color_blue -= 4;
1344                         } 
1345
1346                         if (init_flag)
1347                                 HUD_init_colors();
1348
1349                         break;
1350                 }
1351 #endif
1352                 
1353                 case KEY_DEBUGGED + SDLK_y:
1354                         /*
1355                         // blast a debug lightning bolt in front of the player
1356                         vector start, strike;
1357                         
1358                         vm_vec_scale_add(&start, &Player_obj->pos, &Player_obj->orient.fvec, 300.0f);
1359                         vm_vec_scale_add2(&start, &Player_obj->orient.rvec, -300.0f);
1360                         vm_vec_scale_add(&strike, &start, &Player_obj->orient.rvec, 600.0f);
1361                         nebl_bolt(DEBUG_BOLT, &start, &strike);
1362                         */
1363                         extern int tst;
1364                         tst = 2;
1365                         break;
1366
1367 #ifndef MAKE_FS1
1368                 case SDLK_KP_PLUS: {
1369                         int init_flag = 0;
1370
1371                         if ( key_pressed(SDLK_1) )      {
1372                                 init_flag = 1;
1373                                 HUD_color_red += 4;
1374                         } 
1375
1376                         if ( key_pressed(SDLK_2) )      {
1377                                 init_flag = 1;
1378                                 HUD_color_green += 4;
1379                         } 
1380
1381                         if ( key_pressed(SDLK_3) )      {
1382                                 init_flag = 1;
1383                                 HUD_color_blue += 4;
1384                         } 
1385
1386                         if (init_flag)
1387                                 HUD_init_colors();
1388
1389                         break;
1390                 }
1391 #endif
1392         }       // end switch
1393
1394 }
1395 //#endif
1396
1397 void ppsk_hotkeys(int k)
1398 {
1399
1400 #if !(defined(FS2_DEMO) || defined(FS1_DEMO))
1401
1402         // use k to check for keys that can have Shift,Ctrl,Alt,Del status
1403         int hotkey_set;
1404
1405 #ifndef NDEBUG
1406         k &= ~KEY_DEBUGGED;                     // since hitting F11 will set this bit
1407 #endif
1408
1409         switch (k) {
1410                 case SDLK_F5:
1411                 case SDLK_F6:
1412                 case SDLK_F7:
1413                 case SDLK_F8:
1414                 case SDLK_F9:
1415                 case SDLK_F10:
1416                 case SDLK_F11:
1417                 case SDLK_F12:
1418                         hotkey_set = mission_hotkey_get_set_num(k);
1419                         if ( !(Players[Player_num].flags & PLAYER_FLAGS_MSG_MODE) )
1420                                 hud_target_hotkey_select( hotkey_set );
1421                         else
1422                                 hud_squadmsg_hotkey_select( hotkey_set );
1423
1424                         break;
1425
1426                 case SDLK_F5 + KEY_SHIFTED:
1427                 case SDLK_F6 + KEY_SHIFTED:
1428                 case SDLK_F7 + KEY_SHIFTED:
1429                 case SDLK_F8 + KEY_SHIFTED:
1430                 case SDLK_F9 + KEY_SHIFTED:
1431                 case SDLK_F10 + KEY_SHIFTED:
1432                 case SDLK_F11 + KEY_SHIFTED:
1433                 case SDLK_F12 + KEY_SHIFTED:
1434                         hotkey_set = mission_hotkey_get_set_num(k&(~KEY_SHIFTED));
1435                         mprintf(("Adding to set %d\n", hotkey_set+1));
1436                         if ( Player_ai->target_objnum == -1)
1437                                 HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "No target to add/remove from set %d.", 26), hotkey_set+1);
1438                         else  {
1439                                 hud_target_hotkey_add_remove( hotkey_set, &Objects[Player_ai->target_objnum], HOTKEY_USER_ADDED);
1440                                 HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "%s added to set %d. (F%d)", 27), Ships[Objects[Player_ai->target_objnum].instance].ship_name, hotkey_set, 4+hotkey_set+1);
1441                         }
1442
1443                         break;
1444
1445                 case SDLK_F5 + KEY_SHIFTED + KEY_ALTED:
1446                 case SDLK_F6 + KEY_SHIFTED + KEY_ALTED:
1447                 case SDLK_F7 + KEY_SHIFTED + KEY_ALTED:
1448                 case SDLK_F8 + KEY_SHIFTED + KEY_ALTED:
1449                 case SDLK_F9 + KEY_SHIFTED + KEY_ALTED:
1450                 case SDLK_F10 + KEY_SHIFTED + KEY_ALTED:
1451                 case SDLK_F11 + KEY_SHIFTED + KEY_ALTED:
1452                 case SDLK_F12 + KEY_SHIFTED + KEY_ALTED:
1453                         hotkey_set = mission_hotkey_get_set_num(k & ~(KEY_SHIFTED+KEY_ALTED));
1454                         hud_target_hotkey_clear( hotkey_set );
1455                         break;
1456
1457                 case KEY_SHIFTED + SDLK_MINUS:
1458                         if ( HUD_color_alpha > HUD_COLOR_ALPHA_USER_MIN )       {
1459                                 HUD_color_alpha--;
1460                                 HUD_init_colors();
1461                         }
1462                         break;
1463 /*              case KEY_SHIFTED + SDLK_u:
1464                         {
1465                         object *debris_create(object *source_obj, int model_num, int submodel_num, vector *pos, vector *exp_center, int hull_flag, float exp_force);
1466
1467                         object *temp = debris_create(Player_obj, Ships[0].modelnum, model_get(Ships[0].modelnum)->debris_objects[0], &Player_obj->pos, &Player_obj->pos, 1, 1.0f);
1468                         if (temp) {
1469                                 temp->hull_strength = 5000.0f;
1470                                 int objnum = temp - Objects;
1471                                 vm_vec_copy_scale(&Objects[objnum].phys_info.vel, &Player_obj->orient.fvec, 30.0f);
1472                         }
1473                         }
1474                         break;
1475 */
1476
1477                 case KEY_SHIFTED + SDLK_EQUALS:
1478                         if ( HUD_color_alpha < HUD_COLOR_ALPHA_USER_MAX ) {
1479                                 HUD_color_alpha++;
1480                                 HUD_init_colors();
1481                         }
1482                         break;
1483         }       // end switch
1484
1485 #endif
1486
1487 }
1488
1489 // check keypress 'key' against a set of valid controls and mark the match in the
1490 // player's button info bitfield.  Also checks joystick controls in the set.
1491 //
1492 // key = scancode (plus modifiers).
1493 // count = total size of the list
1494 // list = list of Control_config struct action indices to check for
1495 void process_set_of_keys(int key, int count, int *list)
1496 {
1497         int i;
1498
1499         for (i=0; i<count; i++)
1500                 if (check_control(list[i], key))
1501                         button_info_set(&Player->bi, list[i]);
1502 }
1503
1504 // routine to process keys used for player ship stuff (*not* ship movement).
1505 void process_player_ship_keys(int k)
1506 {
1507         int masked_k;
1508
1509         masked_k = k & ~KEY_CTRLED;     // take out CTRL modifier only  
1510
1511         // moved this line to beginning of function since hotkeys now encompass
1512         // F5 - F12.  We can return after using F11 as a hotkey.
1513         ppsk_hotkeys(masked_k);
1514         if (key_pressed(KEY_DEBUG_KEY)){
1515                 return;
1516         }
1517
1518         // if we're in supernova mode. do nothing
1519         if(Player->control_mode == PCM_SUPERNOVA){
1520                 return;
1521         }
1522
1523         // pass the key to the squadmate messaging code.  If the messaging code took the key, then return
1524         // from here immediately since we don't want to do further key processing.
1525         if ( hud_squadmsg_read_key(k) )
1526                 return;
1527
1528         if ( Player->control_mode == PCM_NORMAL )       {
1529                 //      The following things are not legal to do while dead.
1530                 if ( !(Game_mode & GM_DEAD) ) {
1531                         process_set_of_keys(masked_k, Normal_key_set_size, Normal_key_set);
1532                 } else  {
1533                         process_set_of_keys(masked_k, Dead_key_set_size, Dead_key_set);
1534                 }
1535         } else {
1536
1537         }
1538 }
1539
1540 static void game_do_end_mission_popup_callback(int choice)
1541 {
1542 //      char    savegame_filename[_MAX_FNAME];
1543
1544         popup_done();
1545
1546         switch (choice) {
1547                 case 1:
1548                         // save the game before quitting if in campaign mode
1549                         // MWA -- 3/26/98 -- no more save/restore!!!!
1550 /*
1551                         if ( Game_mode & GM_CAMPAIGN_MODE ) {
1552                                 memset(savegame_filename, 0, _MAX_FNAME);
1553                                 mission_campaign_savefile_generate_root(savegame_filename);
1554                                 strcat(savegame_filename, NOX("svg"));
1555                                 if ( state_save_all(savegame_filename) ) {
1556                                         Int3(); // could not save this game
1557                                 }
1558                         }
1559 */
1560                         gameseq_post_event(GS_EVENT_END_GAME);
1561                         break;
1562
1563                 case 2:
1564                         gameseq_post_event(GS_EVENT_ENTER_GAME);
1565                         break;
1566
1567                 default:
1568                         break;  // do nothing
1569         }
1570
1571         game_start_time();
1572         game_flush();
1573 }
1574
1575 // Handler for when player hits 'ESC' during the game
1576 void game_do_end_mission_popup()
1577 {
1578         int     pf_flags;
1579
1580         // do the multiplayer version of this
1581         if(Game_mode & GM_MULTIPLAYER){
1582                 multi_quit_game(PROMPT_ALL);
1583         } else {
1584
1585                 // single player version....
1586                 // do housekeeping things.
1587                 game_stop_time();
1588                 game_stop_looped_sounds();
1589                 snd_stop_all();
1590
1591                 pf_flags = PF_BODY_BIG | PF_USE_AFFIRMATIVE_ICON | PF_USE_NEGATIVE_ICON;
1592                 popup_callback(game_do_end_mission_popup_callback, pf_flags, 3, POPUP_NO, XSTR( "&Yes, Quit", 28), XSTR( "Yes, &Restart", 29), XSTR( "Do you really want to end the mission?", 30));
1593         }
1594 }
1595
1596 // handle pause keypress
1597 void game_process_pause_key()
1598 {
1599         // special processing for multiplayer
1600         if (Game_mode & GM_MULTIPLAYER) {                                                       
1601                 if(Multi_pause_status){
1602                         multi_pause_request(0);
1603                 } else {
1604                         multi_pause_request(1);
1605                 }               
1606         } else {
1607                 gameseq_post_event( GS_EVENT_PAUSE_GAME );
1608         }
1609 }
1610
1611 #define WITHIN_BBOX()   do { \
1612         float scale = 2.0f; \
1613         polymodel *pm = model_get(s_check->modelnum); \
1614         collided = 0; \
1615         if(pm != NULL){ \
1616                 vector temp = new_obj->pos; \
1617                 vector gpos; \
1618                 vm_vec_sub2(&temp, &hit_check->pos); \
1619                 vm_vec_rotate(&gpos, &temp, &hit_check->orient); \
1620                 if((gpos.xyz.x >= pm->mins.xyz.x * scale) && (gpos.xyz.y >= pm->mins.xyz.y * scale) && (gpos.xyz.z >= pm->mins.xyz.z * scale) && (gpos.xyz.x <= pm->maxs.xyz.x * scale) && (gpos.xyz.y <= pm->maxs.xyz.y * scale) && (gpos.xyz.z <= pm->maxs.xyz.z * scale)) { \
1621                         collided = 1; \
1622                 } \
1623         } \
1624 } while(0)
1625
1626 #define MOVE_AWAY_BBOX() do { \
1627         polymodel *pm = model_get(s_check->modelnum); \
1628         if(pm != NULL){ \
1629                 switch((int)frand_range(0.0f, 3.9f)){ \
1630                 case 0: \
1631                         new_obj->pos.xyz.x += 200.0f; \
1632                         break; \
1633                 case 1: \
1634                         new_obj->pos.xyz.x -= 200.0f; \
1635                         break; \
1636                 case 2: \
1637                         new_obj->pos.xyz.y += 200.0f; \
1638                         break; \
1639                 case 3: \
1640                         new_obj->pos.xyz.y -= 200.0f; \
1641                         break; \
1642                 default : \
1643                         new_obj->pos.xyz.z -= 200.0f; \
1644                         break; \
1645                 } \
1646         } \
1647 } while(0)
1648
1649 // process cheat codes
1650 void game_process_cheats(int k)
1651 {
1652         int i;
1653         char *cryptstring;
1654
1655         if ( k == 0 ){
1656                 return;
1657         }
1658
1659         // no cheats in multiplayer, ever
1660         if(Game_mode & GM_MULTIPLAYER){
1661                 Cheats_enabled = 0;
1662                 return;
1663         }
1664
1665         k = key_get_text_input();
1666
1667         if ( (k < 0) || (k > 255) ) {
1668                 return;
1669         }
1670
1671         for (i = 0; i < CHEAT_BUFFER_LEN; i++){
1672                 CheatBuffer[i]=CheatBuffer[i+1];
1673         }
1674
1675         CheatBuffer[CHEATSPOT]=(char)k;
1676
1677         cryptstring=jcrypt(&CheatBuffer[CHEAT_BUFFER_LEN - CRYPT_STRING_LENGTH]);               
1678
1679 #if defined(FS2_DEMO)
1680         if ( !strcmp(Cheat_code_demo, cryptstring) ) {
1681                 HUD_printf(XSTR( "Cheats enabled.", 31));
1682                 Cheats_enabled = 1;
1683                 if (Player->flags & PLAYER_FLAGS_MSG_MODE){
1684                         hud_squadmsg_toggle();
1685                 }
1686         }
1687         
1688 #else
1689
1690 #ifdef MAKE_FS1
1691         // two possible cheat codes for FS1, German and English
1692         if (Lcl_gr) {
1693                 if( !strcmp(Cheat_code_gr, cryptstring) && !(Game_mode & GM_MULTIPLAYER)){
1694                         Cheats_enabled = 1;
1695                         HUD_printf("Cheats enabled");
1696                 }
1697         } else {
1698                 if( !strcmp(Cheat_code, cryptstring) && !(Game_mode & GM_MULTIPLAYER)){
1699                         Cheats_enabled = 1;
1700                         HUD_printf("Cheats enabled");
1701                 }
1702         }
1703 #else
1704         if( !strcmp(Cheat_code, cryptstring) && !(Game_mode & GM_MULTIPLAYER)){
1705                 Cheats_enabled = 1;
1706                 HUD_printf("Cheats enabled");
1707         }
1708 #endif
1709
1710 #ifndef MAKE_FS1
1711         if( !strcmp(Cheat_code_fish, cryptstring) ){
1712                 // only enable in the main hall
1713                 if((gameseq_get_state() == GS_STATE_MAIN_MENU) && (main_hall_id() == 1)){
1714                         extern void fishtank_start();
1715                         fishtank_start();
1716                 }
1717         }
1718         if( !strcmp(Cheat_code_headz, cryptstring) ){
1719                 main_hall_vasudan_funny();
1720         }
1721         if( !strcmp(Cheat_code_skip, cryptstring) && (gameseq_get_state() == GS_STATE_MAIN_MENU)){
1722                 extern void main_hall_campaign_cheat();
1723                 main_hall_campaign_cheat();
1724         }
1725         if( !strcmp(Cheat_code_tooled, cryptstring) && (Game_mode & GM_IN_MISSION)){
1726                 Tool_enabled = 1;
1727                 HUD_printf("Prepare to be taken to school");
1728         }
1729         if( !strcmp(Cheat_code_pirate, cryptstring) && (Game_mode & GM_IN_MISSION) && (Player_obj != NULL)){
1730                 HUD_printf(NOX("Walk the plank"));
1731                 
1732                 for(int idx=0; idx<1; idx++){
1733                         vector add = Player_obj->pos;
1734                         add.xyz.x += frand_range(-700.0f, 700.0f);
1735                         add.xyz.y += frand_range(-700.0f, 700.0f);
1736                         add.xyz.z += frand_range(-700.0f, 700.0f);
1737
1738                         int objnum = ship_create(&vmd_identity_matrix, &add, Num_ship_types - 1);
1739
1740                         if(objnum >= 0){
1741                                 int collided;
1742                                 ship_obj *moveup;
1743                                 object *hit_check;
1744                                 ship *s_check;
1745                                 object *new_obj = &Objects[objnum];
1746
1747                                 // place him
1748                                 // now make sure we're not colliding with anyone                
1749                                 do {
1750                                         collided = 0;
1751                                         moveup = GET_FIRST(&Ship_obj_list);
1752                                         while(moveup!=END_OF_LIST(&Ship_obj_list)){
1753                                                 // don't check the new_obj itself!!
1754                                                 if(moveup->objnum != objnum){
1755                                                         hit_check = &Objects[moveup->objnum];
1756                                                         SDL_assert(hit_check->type == OBJ_SHIP);
1757                                                         SDL_assert(hit_check->instance >= 0);
1758                                                         if((hit_check->type != OBJ_SHIP) || (hit_check->instance < 0)){
1759                                                                 continue;
1760                                                         }
1761                                                         s_check = &Ships[hit_check->instance];
1762                                                         
1763                                                         // just to make sure we don't get any strange magnitude errors
1764                                                         if(vm_vec_same(&hit_check->pos, &Objects[objnum].pos)){
1765                                                                 Objects[objnum].pos.xyz.x += 1.0f;
1766                                                         }
1767                                                         
1768                                                         WITHIN_BBOX();                          
1769                                                         if(collided){                                           
1770                                                                 MOVE_AWAY_BBOX();
1771                                                                 break;
1772                                                         } 
1773                                                         collided = 0;
1774                                                 }
1775                                                 moveup = GET_NEXT(moveup);
1776                                         }
1777                                 } while(collided);                                      
1778                         
1779                                 // warpin
1780                                 shipfx_warpin_start(&Objects[objnum]);
1781
1782                                 // tell him to attack                           
1783                                 // ai_add_ship_goal_player( AIG_TYPE_PLAYER_SHIP, AI_GOAL_CHASE_ANY, SM_ATTACK, NULL, &Ai_info[Ships[Objects[objnum].instance].ai_index] );
1784                         }
1785                 }
1786         }
1787 #endif  // !MAKE_FS1
1788 #endif
1789
1790 #if defined(MAKE_FS1) && !defined(FS1_DEMO)
1791         if ( !strcmp(Cheat_code_movies, cryptstring) ) {
1792                 HUD_printf(XSTR( "All movies available in Tech Room", 32));
1793                 All_movies_enabled = 1;
1794                 if (Player->flags & PLAYER_FLAGS_MSG_MODE){
1795                         hud_squadmsg_toggle();
1796                 }
1797         }
1798 #endif
1799
1800 /*
1801 //#ifdef INTERPLAYQA
1802         if ( !strcmp(Cheat_code_in_game, cryptstring) ) {
1803                 HUD_printf(XSTR( "Cheats enabled.", 31));
1804                 Cheats_enabled = 1;
1805                 if (Player->flags & PLAYER_FLAGS_MSG_MODE){
1806                         hud_squadmsg_toggle();
1807                 }
1808         } else if ( !strcmp(Cheat_code_movies, cryptstring) ) {
1809                 HUD_printf(XSTR( "All movies available in Tech Room", 32));
1810                 All_movies_enabled = 1;
1811                 if (Player->flags & PLAYER_FLAGS_MSG_MODE){
1812                         hud_squadmsg_toggle();
1813                 }
1814         } else if( !strcmp(Cheat_code_pirate, cryptstring) ){
1815                 HUD_printf(NOX("Walk the plank"));
1816                 
1817                 for(int idx=0; idx<1; idx++){
1818                         vector add;
1819                         add.x = frand_range(-1000.0f, 1000.0f);
1820                         add.y = frand_range(-1000.0f, 1000.0f);
1821                         add.z = frand_range(-1000.0f, 1000.0f);
1822
1823                         int objnum = ship_create(&vmd_identity_matrix, &add, Num_ship_types - 1);                       
1824
1825                         if(objnum >= 0){
1826                                 shipfx_warpin_start(&Objects[objnum]);
1827                         }
1828                 }
1829         }
1830 #endif
1831         */
1832 }
1833
1834 void game_process_keys()
1835 {
1836         int k;
1837
1838         button_info_clear(&Player->bi); // clear out the button info struct for the player
1839    do {
1840                 k = game_poll();                
1841         
1842                 // AL 12-10-97: Scan for keys used to leave the dead state      (don't process any)
1843                 // DB 1-13-98 : New popup code will run the game do state, so we must skip 
1844                 //              all key processing in this function, since everything should be run through the popup dialog
1845                 if ( Game_mode & GM_DEAD_BLEW_UP ) {
1846                         continue;
1847                 }
1848
1849                 game_process_cheats( k );
1850
1851                 // mwa -- 4/5/97 Moved these two function calls before the switch statement.  I don't think
1852                 // that this has adverse affect on anything and is acutally desireable because of the
1853                 // ESC key being used to quit any HUD message/input mode that might be currently in use
1854                 process_player_ship_keys(k);
1855
1856 //              #ifndef NDEBUG
1857                 process_debug_keys(k);          //      Note, also processed for cheats.
1858 //              #endif          
1859
1860                 switch (k) {
1861                         case 0:
1862                                 // No key
1863                                 break;
1864                         
1865                         case SDLK_ESCAPE:
1866                                 if ( Player->control_mode != PCM_NORMAL )       {
1867                                         if ( Player->control_mode == PCM_WARPOUT_STAGE1 )       {
1868                                                 gameseq_post_event( GS_EVENT_PLAYER_WARPOUT_STOP );
1869                                         } else {
1870                                                 // too late to abort warp out!
1871                                         }
1872                                 } else {
1873                                         // let the ESC key break out of messaging mode
1874                                         if ( Players[Player_num].flags & PLAYER_FLAGS_MSG_MODE ) {
1875                                                 hud_squadmsg_toggle();
1876                                                 break;
1877                                         }
1878
1879                                         // if in external view or chase view, go back to cockpit view
1880                                         if ( Viewer_mode & (VM_EXTERNAL|VM_CHASE|VM_OTHER_SHIP) ) {
1881                                                 Viewer_mode &= ~(VM_EXTERNAL|VM_CHASE|VM_OTHER_SHIP);
1882                                                 break;
1883                                         }
1884
1885                                         if (!(Game_mode & GM_DEAD_DIED))
1886                                                 game_do_end_mission_popup();
1887
1888                                 }
1889                                 break;
1890
1891                         case SDLK_y:
1892                                 break;
1893
1894                         case SDLK_n:
1895                                 break;                  
1896
1897                         case KEY_ALTED + KEY_SHIFTED+SDLK_j:
1898                                 // treat the current joystick position as the center position
1899                                 joy_set_cen();
1900                                 break;
1901
1902                         case KEY_DEBUGGED | SDLK_PAUSE:
1903                                 gameseq_post_event( GS_EVENT_DEBUG_PAUSE_GAME );
1904                                 break;
1905
1906                         case SDLK_PAUSE:
1907                                 game_process_pause_key();
1908                                 break;
1909                 } // end switch
1910         } while (k);
1911
1912         button_info_do(&Player->bi);    // call functions based on status of button_info bit vectors
1913 }
1914
1915 int button_function_critical(int n, net_player *p = NULL)
1916 {
1917         object *objp;
1918         player *pl;
1919         net_player *npl;
1920         int at_self;    // flag indicating the object is local (for hud messages, etc)
1921
1922         SDL_assert(n >= 0);
1923    
1924         // multiplayer clients should leave critical button bits alone and pass them to the server instead
1925         if ((Game_mode & GM_MULTIPLAYER) && !(Net_player->flags & NETINFO_FLAG_AM_MASTER)) {
1926                 // if this flag is set, we should apply the button itself (came from the server)
1927                 if (!Multi_button_info_ok){
1928                         return 0;
1929                 }
1930         }
1931
1932         // in single player mode make sure we're using the player object and the player himself, otherwise use the object and
1933         // player pertaining to the passed net_player
1934         npl = NULL;
1935         if (p == NULL) {
1936                 objp = Player_obj;
1937                 pl = Player;
1938                 if(Game_mode & GM_MULTIPLAYER){
1939                         npl = Net_player;
1940
1941                         // if we're the server in multiplayer and we're an observer, don't process our own critical button functions
1942                         if((Net_player->flags & NETINFO_FLAG_AM_MASTER) && (Net_player->flags & NETINFO_FLAG_OBSERVER)){
1943                                 return 0;
1944                         }
1945                 }
1946                 at_self = 1;
1947         } else {
1948                 objp = &Objects[p->player->objnum];
1949                 pl = p->player;
1950                 npl = p;
1951                 at_self = 0;
1952
1953                 if ( NETPLAYER_IS_DEAD(npl) || (Ships[Objects[pl->objnum].instance].flags & SF_DYING) )
1954                         return 0;
1955         }
1956         
1957         switch (n) {                            
1958                 // cycle to next secondary weapon
1959                 case CYCLE_SECONDARY:
1960                         if(at_self)
1961                                 control_used(CYCLE_SECONDARY);
1962                         
1963                         hud_gauge_popup_start(HUD_WEAPONS_GAUGE);
1964                         if (ship_select_next_secondary(objp)) {
1965                                 ship* shipp = &Ships[objp->instance];
1966                                 if ( timestamp_elapsed(shipp->weapons.next_secondary_fire_stamp[shipp->weapons.current_secondary_bank]) ) {
1967                                         shipp->weapons.next_secondary_fire_stamp[shipp->weapons.current_secondary_bank] = timestamp(250);       //      1/4 second delay until can fire
1968                                 }
1969
1970                                 // multiplayer server should maintain bank/link status here
1971                                 if((Game_mode & GM_MULTIPLAYER) && (Net_player->flags & NETINFO_FLAG_AM_MASTER)){
1972                                         SDL_assert(npl != NULL);
1973                                         multi_server_update_player_weapons(npl,shipp);                                                                          
1974                                 }                                       
1975                         }                       
1976                         break;
1977
1978                 // cycle number of missiles
1979                 case CYCLE_NUM_MISSLES:
1980                         if(at_self)
1981                                 control_used(CYCLE_NUM_MISSLES);
1982
1983                         if ( objp == Player_obj ) {
1984                                 if ( Player_ship->weapons.num_secondary_banks <= 0 ) {
1985                                         HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "This ship has no secondary weapons", 33));
1986                                         gamesnd_play_iface(SND_GENERAL_FAIL);
1987                                         break;
1988                                 }
1989                         }
1990                                         
1991                         if ( Ships[objp->instance].flags & SF_SECONDARY_DUAL_FIRE ) {           
1992                                 Ships[objp->instance].flags &= ~SF_SECONDARY_DUAL_FIRE;
1993                                 if(at_self) {
1994                                         HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "Secondary weapon set to normal fire mode", 34));
1995                                         snd_play( &Snds[SND_SECONDARY_CYCLE] );
1996                                         hud_gauge_popup_start(HUD_WEAPONS_GAUGE);
1997                                 }
1998                         } else {
1999                                 Ships[objp->instance].flags |= SF_SECONDARY_DUAL_FIRE;
2000                                 if(at_self) {
2001                                         HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "Secondary weapon set to dual fire mode", 35));
2002                                         snd_play( &Snds[SND_SECONDARY_CYCLE] );
2003                                         hud_gauge_popup_start(HUD_WEAPONS_GAUGE);
2004                                 }
2005                         }
2006
2007                         // multiplayer server should maintain bank/link status here
2008                         if((Game_mode & GM_MULTIPLAYER) && (Net_player->flags & NETINFO_FLAG_AM_MASTER)){
2009                                 SDL_assert(npl != NULL);
2010                                 multi_server_update_player_weapons(npl,&Ships[objp->instance]);                                                                         
2011                         }                                       
2012                         break;
2013
2014                 // increase weapon recharge rate
2015                 case INCREASE_WEAPON:
2016                         if(at_self)
2017                                 control_used(INCREASE_WEAPON);
2018                         increase_recharge_rate(objp, WEAPONS);
2019
2020                         // multiplayer server should maintain bank/link status here
2021                         if((Game_mode & GM_MULTIPLAYER) && (Net_player->flags & NETINFO_FLAG_AM_MASTER)){
2022                                 SDL_assert(npl != NULL);
2023                                 multi_server_update_player_weapons(npl,&Ships[objp->instance]);                                                                         
2024                         }                                       
2025                         break;
2026
2027                 // decrease weapon recharge rate
2028                 case DECREASE_WEAPON:
2029                         if(at_self)
2030                                 control_used(DECREASE_WEAPON);
2031                         decrease_recharge_rate(objp, WEAPONS);
2032
2033                         // multiplayer server should maintain bank/link status here
2034                         if((Game_mode & GM_MULTIPLAYER) && (Net_player->flags & NETINFO_FLAG_AM_MASTER)){
2035                                 SDL_assert(npl != NULL);
2036                                 multi_server_update_player_weapons(npl,&Ships[objp->instance]);                                                                         
2037                         }                                                               
2038                         break;
2039
2040                 // increase shield recharge rate
2041                 case INCREASE_SHIELD:
2042                         if(at_self)
2043                                 control_used(INCREASE_SHIELD);
2044                         increase_recharge_rate(objp, SHIELDS);
2045
2046                         // multiplayer server should maintain bank/link status here
2047                         if((Game_mode & GM_MULTIPLAYER) && (Net_player->flags & NETINFO_FLAG_AM_MASTER)){
2048                                 SDL_assert(npl != NULL);
2049                                 multi_server_update_player_weapons(npl,&Ships[objp->instance]);                                                                         
2050                         }                                                               
2051                         break;
2052
2053                 // decrease shield recharge rate
2054                 case DECREASE_SHIELD:
2055                         if(at_self)
2056                                 control_used(DECREASE_SHIELD);
2057                         decrease_recharge_rate(objp, SHIELDS);
2058
2059                         // multiplayer server should maintain bank/link status here
2060                         if((Game_mode & GM_MULTIPLAYER) && (Net_player->flags & NETINFO_FLAG_AM_MASTER)){
2061                                 SDL_assert(npl != NULL);
2062                                 multi_server_update_player_weapons(npl,&Ships[objp->instance]);                                                                         
2063                         }                                                               
2064                         break;
2065
2066                 // increase energy to engines
2067                 case INCREASE_ENGINE:
2068                         if(at_self)
2069                                 control_used(INCREASE_ENGINE);
2070                         increase_recharge_rate(objp, ENGINES);
2071
2072                         // multiplayer server should maintain bank/link status here
2073                         if((Game_mode & GM_MULTIPLAYER) && (Net_player->flags & NETINFO_FLAG_AM_MASTER)){
2074                                 SDL_assert(npl != NULL);
2075                                 multi_server_update_player_weapons(npl,&Ships[objp->instance]);                                                                         
2076                         }                                                       
2077                         break;
2078
2079                 // decrease energy to engines
2080                 case DECREASE_ENGINE:
2081                         if(at_self)
2082                         control_used(DECREASE_ENGINE);
2083                         decrease_recharge_rate(objp, ENGINES);
2084
2085                         // multiplayer server should maintain bank/link status here
2086                         if((Game_mode & GM_MULTIPLAYER) && (Net_player->flags & NETINFO_FLAG_AM_MASTER)){
2087                                 SDL_assert(npl != NULL);
2088                                 multi_server_update_player_weapons(npl,&Ships[objp->instance]);                                                                         
2089                         }                                                                               
2090                         break;
2091
2092 #ifndef FS1_DEMO
2093                 // equalize recharge rates
2094                 case ETS_EQUALIZE:
2095                         if (at_self) {
2096                         control_used(ETS_EQUALIZE);
2097                         }
2098
2099                         set_default_recharge_rates(objp);
2100                         snd_play( &Snds[SND_ENERGY_TRANS] );
2101                         // multiplayer server should maintain bank/link status here
2102                         if((Game_mode & GM_MULTIPLAYER) && (Net_player->flags & NETINFO_FLAG_AM_MASTER)){
2103                                 SDL_assert(npl != NULL);
2104                                 multi_server_update_player_weapons(npl,&Ships[objp->instance]);                                                                         
2105                         }                                                                               
2106                         break;
2107 #endif
2108
2109                 // equalize shield energy to all quadrants
2110                 case SHIELD_EQUALIZE:
2111                         if(at_self){
2112                                 control_used(SHIELD_EQUALIZE);
2113                         }
2114                         hud_shield_equalize(objp, pl);
2115                         break;
2116
2117                 // transfer shield energy to front
2118                 case SHIELD_XFER_TOP:
2119                         if(at_self){
2120                         control_used(SHIELD_XFER_TOP);
2121                         }
2122                         hud_augment_shield_quadrant(objp, 1);
2123                         break;
2124
2125                 // transfer shield energy to rear
2126                 case SHIELD_XFER_BOTTOM:
2127                         if(at_self)
2128                                 control_used(SHIELD_XFER_BOTTOM);
2129                         hud_augment_shield_quadrant(objp, 2);
2130                         break;
2131
2132                 // transfer shield energy to left
2133                 case SHIELD_XFER_LEFT:
2134                         if(at_self)
2135                                 control_used(SHIELD_XFER_LEFT);
2136                         hud_augment_shield_quadrant(objp, 3);
2137                         break;
2138                         
2139                 // transfer shield energy to right
2140                 case SHIELD_XFER_RIGHT:
2141                         if(at_self)
2142                                 control_used(SHIELD_XFER_RIGHT);
2143                         hud_augment_shield_quadrant(objp, 0);
2144                         break;
2145
2146                 // transfer energy to shield from weapons
2147                 case XFER_SHIELD:
2148                         if(at_self)
2149                                 control_used(XFER_SHIELD);
2150                         transfer_energy_to_shields(objp);
2151                         break;
2152
2153                 // transfer energy to weapons from shield
2154                 case XFER_LASER:
2155                         if(at_self)
2156                                 control_used(XFER_LASER);
2157                         transfer_energy_to_weapons(objp);
2158                         break;
2159
2160                 // following are not handled here, but we need to bypass the Int3()
2161                 case LAUNCH_COUNTERMEASURE:
2162                 case VIEW_SLEW:
2163                 case VIEW_EXTERNAL:
2164                 case VIEW_EXTERNAL_TOGGLE_CAMERA_LOCK:
2165                 case ONE_THIRD_THROTTLE:
2166                 case TWO_THIRDS_THROTTLE:
2167                 case MINUS_5_PERCENT_THROTTLE:
2168                 case PLUS_5_PERCENT_THROTTLE:
2169                 case ZERO_THROTTLE:
2170                 case MAX_THROTTLE:
2171                         return 0;
2172
2173                 default :
2174                         Int3(); // bad bad bad
2175                         break;
2176         }
2177
2178         return 1;
2179 }
2180
2181 // return !0 if the action is allowed, otherwise return 0
2182 int button_allowed(int n)
2183 {
2184         if ( hud_disabled() ) {
2185                 switch (n) {
2186                 case SHOW_GOALS:
2187                 case END_MISSION:
2188                 case CYCLE_NEXT_PRIMARY:
2189                 case CYCLE_PREV_PRIMARY:
2190                 case CYCLE_SECONDARY:
2191                 case ONE_THIRD_THROTTLE:
2192                 case TWO_THIRDS_THROTTLE:
2193                 case PLUS_5_PERCENT_THROTTLE:
2194                 case MINUS_5_PERCENT_THROTTLE:
2195                 case ZERO_THROTTLE:
2196                 case MAX_THROTTLE:
2197                         return 1;
2198                 default:
2199                         return 0;
2200                 }
2201         }
2202
2203         return 1;
2204 }
2205
2206 // execute function corresponding to action n
2207 // basically, these are actions which don't affect demo playback at all
2208 int button_function_demo_valid(int n)
2209 {
2210         // by default, we'll return "not processed". ret will get set to 1, if this is one of the keys which is always allowed, even in demo
2211         // playback.
2212         int ret = 0;
2213
2214         //      No keys, not even targeting keys, when player in death roll.  He can press keys after he blows up.
2215         if (Game_mode & GM_DEAD_DIED){
2216                 return 0;
2217         }
2218
2219         // any of these buttons are valid
2220         switch(n){
2221         case VIEW_CHASE:
2222                 control_used(VIEW_CHASE);
2223                 Viewer_mode ^= VM_CHASE;
2224                 if ( Viewer_mode & VM_CHASE ) {
2225                         Viewer_mode &= ~VM_EXTERNAL;
2226                 }
2227                 ret = 1;
2228                 break;
2229
2230         case VIEW_EXTERNAL:
2231                 control_used(VIEW_EXTERNAL);
2232                 Viewer_mode ^= VM_EXTERNAL;
2233                 Viewer_mode &= ~VM_EXTERNAL_CAMERA_LOCKED;      // reset camera lock when leave/entering external view
2234                 if ( Viewer_mode & VM_EXTERNAL ) {
2235                         Viewer_mode &= ~VM_CHASE;
2236                 }
2237                 ret = 1;
2238                 break;
2239
2240         case VIEW_EXTERNAL_TOGGLE_CAMERA_LOCK:
2241                 control_used(VIEW_EXTERNAL_TOGGLE_CAMERA_LOCK);
2242                 if ( Viewer_mode & VM_EXTERNAL ) {
2243                 Viewer_mode ^= VM_EXTERNAL_CAMERA_LOCKED;
2244                 if ( Viewer_mode & VM_EXTERNAL_CAMERA_LOCKED ) {
2245                         HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "External camera is locked, controls will move ship", 36));
2246                         } else {
2247                                 HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "External camera is free, controls will move the camera, not the ship", 37));
2248                         }
2249                 }
2250                 ret = 1;
2251                 break;
2252
2253         case VIEW_OTHER_SHIP:
2254                 control_used(VIEW_OTHER_SHIP);
2255                 if ( Player_ai->target_objnum < 0 ) {
2256                         snd_play( &Snds[SND_TARGET_FAIL] );
2257                 } else {
2258                         if ( Objects[Player_ai->target_objnum].type != OBJ_SHIP )  {
2259                                 snd_play( &Snds[SND_TARGET_FAIL] );
2260                         } else {
2261                                 Viewer_mode ^= VM_OTHER_SHIP;
2262                         }
2263                 }
2264                 ret = 1;
2265                 break;
2266
2267         case TIME_SLOW_DOWN:
2268                 if ( Game_mode & GM_NORMAL ) {
2269                         if ( Game_time_compression > F1_0) {
2270                                 Game_time_compression /= 2;
2271                         } else {
2272                                 gamesnd_play_error_beep();
2273                         }
2274                 } else {
2275                         gamesnd_play_error_beep();
2276                 }
2277                 ret = 1;
2278                 break;
2279
2280         case TIME_SPEED_UP:
2281                 if ( Game_mode & GM_NORMAL ) {
2282                         if ( Game_time_compression < (F1_0*4) ) {
2283                                 Game_time_compression *= 2;
2284                         } else {
2285                                 gamesnd_play_error_beep();
2286                         }
2287                 } else {
2288                         gamesnd_play_error_beep();
2289                 }
2290                 ret = 1;
2291                 break;
2292         }
2293
2294         // done
2295         return ret;
2296 }
2297
2298 // execute function corresponding to action n (BUTTON_ #define from KeyControl.h)
2299 int button_function(int n)
2300 {
2301         SDL_assert(n >= 0);
2302
2303         if ( !button_allowed(n) ) {
2304                 return 0;
2305         }
2306
2307         //      No keys, not even targeting keys, when player in death roll.  He can press keys after he blows up.
2308         if (Game_mode & GM_DEAD_DIED){
2309                 return 0;
2310         }
2311                 
2312         switch (n) {
2313                 // cycle to next primary weapon
2314                 case CYCLE_NEXT_PRIMARY:                        
2315                         // bogus?
2316                         if((Player_obj == NULL) || (Player_ship == NULL)){
2317                                 break;
2318                         }
2319
2320                         hud_gauge_popup_start(HUD_WEAPONS_GAUGE);
2321                         if (ship_select_next_primary(Player_obj, CYCLE_PRIMARY_NEXT)) {
2322                                 ship* shipp = Player_ship;
2323                                 shipp->weapons.next_primary_fire_stamp[shipp->weapons.current_primary_bank] = timestamp(250);   //      1/4 second delay until can fire                         
2324                                 // multiplayer server should maintain bank/link status here
2325                                 // if((Game_mode & GM_MULTIPLAYER) && (Net_player->flags & NETINFO_FLAG_AM_MASTER)){
2326 //                                      SDL_assert(npl != NULL);
2327 //                                      multi_server_update_player_weapons(npl,shipp);                                                                          
2328 //                              }                                       
2329                         }                       
2330                         break;
2331
2332                 // cycle to previous primary weapon
2333                 case CYCLE_PREV_PRIMARY:                        
2334                         // bogus?
2335                         if((Player_obj == NULL) || (Player_ship == NULL)){
2336                                 break;
2337                         }
2338
2339                         hud_gauge_popup_start(HUD_WEAPONS_GAUGE);
2340                         if (ship_select_next_primary(Player_obj, CYCLE_PRIMARY_PREV)) {
2341                                 ship* shipp = Player_ship;
2342                                 shipp->weapons.next_primary_fire_stamp[shipp->weapons.current_primary_bank] = timestamp(250);   //      1/4 second delay until can fire
2343
2344                                 // multiplayer server should maintain bank/link status here
2345                                 // if((Game_mode & GM_MULTIPLAYER) && (Net_player->flags & NETINFO_FLAG_AM_MASTER)){
2346                                         // SDL_assert(npl != NULL);
2347                                         // multi_server_update_player_weapons(npl,shipp);                                                                               
2348                                 // }                                    
2349                         }                       
2350                         break;
2351
2352                 // cycle to next secondary weapon
2353                 case CYCLE_SECONDARY:
2354                         return button_function_critical(CYCLE_SECONDARY);
2355                         break;
2356
2357                 // cycle number of missiles fired from secondary bank
2358                 case CYCLE_NUM_MISSLES:
2359          return button_function_critical(CYCLE_NUM_MISSLES);                    
2360                         break;
2361
2362                 // undefined in multiplayer for clients right now
2363                 // match target speed
2364                 case MATCH_TARGET_SPEED:                        
2365                         control_used(MATCH_TARGET_SPEED);
2366                         // If player is auto-matching, break auto-match speed
2367                         if ( Player->flags & PLAYER_FLAGS_AUTO_MATCH_SPEED ) {
2368                                 Player->flags &= ~PLAYER_FLAGS_AUTO_MATCH_SPEED;
2369                         }
2370                         player_match_target_speed();                                            
2371                         break;
2372
2373                 // undefined in multiplayer for clients right now
2374                 // toggle auto-match target speed
2375                 case TOGGLE_AUTO_MATCH_TARGET_SPEED:
2376                         // multiplayer observers can't match target speed
2377                         if((Game_mode & GM_MULTIPLAYER) && (Net_player != NULL) && ((Net_player->flags & NETINFO_FLAG_OBSERVER) || (Player_obj->type == OBJ_OBSERVER)) ){
2378                                 break;
2379                         }
2380         
2381                         Player->flags ^= PLAYER_FLAGS_AUTO_MATCH_SPEED;                 
2382                         control_used(TOGGLE_AUTO_MATCH_TARGET_SPEED);
2383                         hud_gauge_popup_start(HUD_AUTO_SPEED);
2384                         if ( Players[Player_num].flags & PLAYER_FLAGS_AUTO_MATCH_SPEED ) {
2385                                 snd_play(&Snds[SND_SHIELD_XFER_OK], 1.0f);
2386 //                              HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "Auto match target speed activated", -1));
2387                                 if ( !(Player->flags & PLAYER_FLAGS_MATCH_TARGET) ) {
2388                                         player_match_target_speed();
2389                                 }
2390                         }
2391                         else {
2392 //                              HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "Auto match target deactivated", -1));
2393                                 snd_play(&Snds[SND_SHIELD_XFER_OK], 1.0f);
2394                                 player_match_target_speed();
2395                         }                       
2396                         break;
2397
2398                 // target next
2399                 case TARGET_NEXT:
2400                         control_used(TARGET_NEXT);                      
2401                         if ( hud_sensors_ok(Player_ship) ) {
2402                                 hud_target_next();
2403                         }
2404                         break;
2405
2406                 // target previous
2407                 case TARGET_PREV:
2408                         control_used(TARGET_PREV);                      
2409                         if ( hud_sensors_ok(Player_ship) ) {
2410                                 hud_target_prev();                      
2411                         }
2412                         break;
2413
2414                 // target the next hostile target
2415                 case TARGET_NEXT_CLOSEST_HOSTILE:
2416                         control_used(TARGET_NEXT_CLOSEST_HOSTILE);                      
2417                         if (hud_sensors_ok(Player_ship)){
2418                                 hud_target_next_list();
2419                         }                       
2420                         break;
2421
2422                 // target the previous closest hostile 
2423                 case TARGET_PREV_CLOSEST_HOSTILE:
2424                         control_used(TARGET_PREV_CLOSEST_HOSTILE);                      
2425                         if (hud_sensors_ok(Player_ship)){
2426                                 hud_target_next_list(1,0);
2427                         }
2428                         break;
2429
2430                 // toggle auto-targeting
2431                 case TOGGLE_AUTO_TARGETING:
2432                         control_used(TOGGLE_AUTO_TARGETING);
2433                         hud_gauge_popup_start(HUD_AUTO_TARGET);
2434                         Players[Player_num].flags ^= PLAYER_FLAGS_AUTO_TARGETING;
2435                         if ( Players[Player_num].flags & PLAYER_FLAGS_AUTO_TARGETING ) {
2436                                 if (hud_sensors_ok(Player_ship)) {
2437                                         hud_target_closest(opposing_team_mask(Player_ship->team), -1, FALSE, TRUE );
2438                                         snd_play(&Snds[SND_SHIELD_XFER_OK], 1.0f);
2439 //                                      HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "Auto targeting activated", -1));
2440                                 } else {
2441                                         Players[Player_num].flags ^= PLAYER_FLAGS_AUTO_TARGETING;
2442                                 }
2443                         } else {
2444                                 snd_play(&Snds[SND_SHIELD_XFER_OK], 1.0f);
2445 //                              HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "Auto targeting deactivated", -1));
2446                         }
2447                         break;
2448
2449                 // target the next friendly ship
2450                 case TARGET_NEXT_CLOSEST_FRIENDLY:
2451                         control_used(TARGET_NEXT_CLOSEST_FRIENDLY);                     
2452                         if (hud_sensors_ok(Player_ship)){
2453                                 hud_target_next_list(0);
2454                         }
2455                         break;
2456
2457                 // target the closest friendly ship
2458                 case TARGET_PREV_CLOSEST_FRIENDLY:
2459                         control_used(TARGET_PREV_CLOSEST_FRIENDLY);                     
2460                         if (hud_sensors_ok(Player_ship)) {
2461                                 hud_target_next_list(0,0);
2462                         }
2463                         break;
2464
2465                 // target ship closest to center of reticle
2466                 case TARGET_SHIP_IN_RETICLE:
2467                         control_used(TARGET_SHIP_IN_RETICLE);                   
2468                         if (hud_sensors_ok(Player_ship)){
2469                                 hud_target_in_reticle_new();
2470                         }
2471                         break;
2472
2473 #ifndef FS1_DEMO
2474                 case TARGET_LAST_TRANMISSION_SENDER:
2475                         control_used(TARGET_LAST_TRANMISSION_SENDER);
2476                         if ( hud_sensors_ok(Player_ship)) {
2477                                 hud_target_last_transmit();
2478                         }
2479                         break;
2480 #endif
2481
2482                 // target the closest repair ship
2483                 case TARGET_CLOSEST_REPAIR_SHIP:
2484                         control_used(TARGET_CLOSEST_REPAIR_SHIP);
2485                         // AL: Try to find the closest repair ship coming to repair the player... if no support
2486                         //               ships are coming to rearm the player, just try for the closest repair ship
2487                         if ( hud_target_closest_repair_ship(OBJ_INDEX(Player_obj)) == 0 ) {
2488                                 if ( hud_target_closest_repair_ship() == 0 ) {
2489                                         snd_play(&Snds[SND_TARGET_FAIL]);
2490                                 }
2491                         }
2492                         break;
2493
2494                 // target the closest ship attacking current target
2495                 case TARGET_CLOSEST_SHIP_ATTACKING_TARGET:
2496                         control_used(TARGET_CLOSEST_SHIP_ATTACKING_TARGET);
2497                         if (hud_sensors_ok(Player_ship)){
2498                                 hud_target_closest(opposing_team_mask(Player_ship->team), Player_ai->target_objnum);
2499                         }
2500                         break;
2501
2502                 // stop targeting ship
2503                 case STOP_TARGETING_SHIP:
2504                         control_used(STOP_TARGETING_SHIP);
2505                         hud_cease_targeting();
2506                         break;
2507
2508                 // target closest ship that is attacking player
2509                 case TARGET_CLOSEST_SHIP_ATTACKING_SELF:
2510                         control_used(TARGET_CLOSEST_SHIP_ATTACKING_SELF);
2511                         if (hud_sensors_ok(Player_ship)){
2512                                 hud_target_closest(opposing_team_mask(Player_ship->team), OBJ_INDEX(Player_obj), TRUE, 0, 1);
2513                         }
2514                         break;
2515
2516                 // target your target's target
2517                 case TARGET_TARGETS_TARGET:
2518                         control_used(TARGET_TARGETS_TARGET);
2519                         if (hud_sensors_ok(Player_ship)){
2520                                 hud_target_targets_target();
2521                         }
2522                         break;
2523
2524                 // target ships subsystem in reticle
2525                 case TARGET_SUBOBJECT_IN_RETICLE:
2526                         control_used(TARGET_SUBOBJECT_IN_RETICLE);
2527                         if (hud_sensors_ok(Player_ship)){
2528                                 hud_target_subsystem_in_reticle();
2529                         }
2530                         break;
2531
2532                 case TARGET_PREV_SUBOBJECT:
2533                         control_used(TARGET_PREV_SUBOBJECT);
2534                         if (hud_sensors_ok(Player_ship)){
2535                                 hud_target_prev_subobject();
2536                         }
2537                         break;
2538
2539                 // target next subsystem on current target
2540                 case TARGET_NEXT_SUBOBJECT:
2541                         control_used(TARGET_NEXT_SUBOBJECT);
2542                         if (hud_sensors_ok(Player_ship)){
2543                                 hud_target_next_subobject();
2544                         }
2545                         break;
2546
2547                 // stop targeting subsystems on ship
2548                 case STOP_TARGETING_SUBSYSTEM:
2549                         control_used(STOP_TARGETING_SUBSYSTEM);
2550                         hud_cease_subsystem_targeting();
2551                         break;
2552                         
2553                 case TARGET_NEXT_BOMB:
2554                         control_used(TARGET_NEXT_BOMB);
2555                         hud_target_missile(Player_obj, 1);
2556                         break;
2557
2558                 case TARGET_PREV_BOMB:
2559                         control_used(TARGET_PREV_BOMB);
2560                         hud_target_missile(Player_obj, 0);
2561                         break;
2562
2563                 case TARGET_NEXT_UNINSPECTED_CARGO:
2564                         hud_target_uninspected_object(1);
2565                         break;
2566
2567                 case TARGET_PREV_UNINSPECTED_CARGO:
2568                         hud_target_uninspected_object(0);
2569                         break;
2570
2571                 case TARGET_NEWEST_SHIP:
2572                         hud_target_newest_ship();
2573                         break;
2574
2575                 case TARGET_NEXT_LIVE_TURRET:
2576                         hud_target_live_turret(1);
2577                         break;
2578
2579                 case TARGET_PREV_LIVE_TURRET:
2580                         hud_target_live_turret(0);
2581                         break;
2582
2583                 // wingman message: attack current target
2584                 case ATTACK_MESSAGE:
2585                         control_used(ATTACK_MESSAGE);
2586                         hud_squadmsg_shortcut( ATTACK_TARGET_ITEM );
2587                         break;
2588
2589                 // wingman message: disarm current target
2590                 case DISARM_MESSAGE:
2591                         control_used(DISARM_MESSAGE);
2592                         hud_squadmsg_shortcut( DISARM_TARGET_ITEM );
2593                         break;
2594
2595                 // wingman message: disable current target
2596                 case DISABLE_MESSAGE:
2597                         control_used(DISABLE_MESSAGE);
2598                         hud_squadmsg_shortcut( DISABLE_TARGET_ITEM );
2599                         break;
2600
2601                 // wingman message: disable current target
2602                 case ATTACK_SUBSYSTEM_MESSAGE:
2603                         control_used(ATTACK_SUBSYSTEM_MESSAGE);
2604                         hud_squadmsg_shortcut( DISABLE_SUBSYSTEM_ITEM );
2605                         break;
2606
2607                 // wingman message: capture current target
2608                 case CAPTURE_MESSAGE:
2609                         control_used(CAPTURE_MESSAGE);
2610                         hud_squadmsg_shortcut( CAPTURE_TARGET_ITEM );
2611                         break;
2612
2613                 // wingman message: engage enemy
2614                 case ENGAGE_MESSAGE:
2615                 control_used(ENGAGE_MESSAGE);
2616                         hud_squadmsg_shortcut( ENGAGE_ENEMY_ITEM );
2617                         break;
2618
2619                 // wingman message: form on my wing
2620                 case FORM_MESSAGE:
2621                         control_used(FORM_MESSAGE);
2622                         hud_squadmsg_shortcut( FORMATION_ITEM );
2623                         break;
2624
2625                 // wingman message: protect current target
2626                 case PROTECT_MESSAGE:
2627                         control_used(PROTECT_MESSAGE);
2628                         hud_squadmsg_shortcut( PROTECT_TARGET_ITEM );
2629                         break;
2630
2631                 // wingman message: cover me
2632                 case COVER_MESSAGE:
2633                         control_used(COVER_MESSAGE);
2634                         hud_squadmsg_shortcut( COVER_ME_ITEM );
2635                         break;
2636                 
2637                 // wingman message: warp out
2638                 case WARP_MESSAGE:
2639                         control_used(WARP_MESSAGE);
2640                         hud_squadmsg_shortcut( DEPART_ITEM );
2641                         break;
2642
2643                 case IGNORE_MESSAGE:
2644                         control_used(IGNORE_MESSAGE);
2645                         hud_squadmsg_shortcut( IGNORE_TARGET_ITEM );
2646                         break;
2647
2648                 // rearm message
2649                 case REARM_MESSAGE:
2650                         control_used(REARM_MESSAGE);
2651                         hud_squadmsg_rearm_shortcut();
2652                         break;
2653
2654                 // cycle to next radar range
2655                 case RADAR_RANGE_CYCLE:
2656                         control_used(RADAR_RANGE_CYCLE);
2657                         HUD_config.rp_dist++;
2658                         if ( HUD_config.rp_dist >= RR_MAX_RANGES )
2659                                 HUD_config.rp_dist = 0;
2660
2661                         HUD_sourced_printf(HUD_SOURCE_HIDDEN, XSTR( "Radar range set to %s", 38), Radar_range_text(HUD_config.rp_dist));
2662                         break;
2663
2664                 // toggle the squadmate messaging menu
2665                 case SQUADMSG_MENU:
2666                         control_used(SQUADMSG_MENU);
2667                         hud_squadmsg_toggle();                          // leave the details to the messaging code!!!
2668                         break;
2669
2670                 // show the mission goals screen
2671                 case SHOW_GOALS:
2672                         control_used(SHOW_GOALS);
2673                         gameseq_post_event( GS_EVENT_SHOW_GOALS );
2674                         break;
2675
2676                 // end the mission
2677                 case END_MISSION:
2678                         // in multiplayer, all end mission requests should go through the server
2679                         if(Game_mode & GM_MULTIPLAYER){                         
2680                                 multi_handle_end_mission_request();
2681                                 break;
2682                         }
2683
2684                         control_used(END_MISSION);
2685                         
2686                         if (collide_predict_large_ship(Player_obj, 200.0f)) {
2687                                 gamesnd_play_iface(SND_GENERAL_FAIL);
2688                                 HUD_printf(XSTR( "** WARNING ** Collision danger.  Warpout not activated.", 39));
2689                         } else if (ship_get_subsystem_strength( Player_ship, SUBSYSTEM_ENGINE ) < 0.1f) {
2690                                 gamesnd_play_iface(SND_GENERAL_FAIL);
2691                                 HUD_printf(XSTR( "Engine failure.  Cannot engage warp drive.", 40));
2692                         } else {
2693                                 gameseq_post_event( GS_EVENT_PLAYER_WARPOUT_START );
2694                         }                       
2695                         break;
2696
2697                 case ADD_REMOVE_ESCORT:
2698                         if ( Player_ai->target_objnum >= 0 ) {
2699                                 control_used(ADD_REMOVE_ESCORT);
2700                                 hud_add_remove_ship_escort(Player_ai->target_objnum);
2701                         }
2702                         break;
2703
2704                 case ESCORT_CLEAR:
2705                         control_used(ESCORT_CLEAR);
2706                         hud_escort_clear_all();
2707                         break;
2708
2709                 case TARGET_NEXT_ESCORT_SHIP:
2710                         control_used(TARGET_NEXT_ESCORT_SHIP);
2711                         hud_escort_target_next();
2712                         break;
2713
2714                 // increase weapon recharge rate
2715                 case INCREASE_WEAPON:
2716                         hud_gauge_popup_start(HUD_ETS_GAUGE);
2717                         return button_function_critical(INCREASE_WEAPON);
2718                         break;
2719
2720                 // decrease weapon recharge rate
2721                 case DECREASE_WEAPON:
2722                         hud_gauge_popup_start(HUD_ETS_GAUGE);
2723                         return button_function_critical(DECREASE_WEAPON);
2724                         break;
2725
2726                 // increase shield recharge rate
2727                 case INCREASE_SHIELD:
2728                         hud_gauge_popup_start(HUD_ETS_GAUGE);
2729                         return button_function_critical(INCREASE_SHIELD);
2730                         break;
2731
2732                 // decrease shield recharge rate
2733                 case DECREASE_SHIELD:
2734                         hud_gauge_popup_start(HUD_ETS_GAUGE);
2735                         return button_function_critical(DECREASE_SHIELD);
2736                         break;
2737
2738                 // increase energy to engines
2739                 case INCREASE_ENGINE:
2740                         hud_gauge_popup_start(HUD_ETS_GAUGE);
2741                         return button_function_critical(INCREASE_ENGINE);
2742                         break;
2743
2744                 // decrease energy to engines
2745                 case DECREASE_ENGINE:
2746                         hud_gauge_popup_start(HUD_ETS_GAUGE);
2747                         return button_function_critical(DECREASE_ENGINE);
2748                         break;
2749
2750 #ifndef FS1_DEMO
2751                 case ETS_EQUALIZE:
2752                         hud_gauge_popup_start(HUD_ETS_GAUGE);
2753                         return button_function_critical(ETS_EQUALIZE);
2754                         break;
2755 #endif
2756
2757                 // equalize shield energy to all quadrants
2758                 case SHIELD_EQUALIZE:
2759                         return button_function_critical(SHIELD_EQUALIZE);
2760                         break;
2761
2762                 // transfer shield energy to front
2763                 case SHIELD_XFER_TOP:
2764          return button_function_critical(SHIELD_XFER_TOP);
2765                         break;
2766
2767                 // transfer shield energy to rear
2768                 case SHIELD_XFER_BOTTOM:
2769                         return button_function_critical(SHIELD_XFER_BOTTOM);
2770                         break;
2771
2772                 // transfer shield energy to left
2773                 case SHIELD_XFER_LEFT:
2774                         return button_function_critical(SHIELD_XFER_LEFT);
2775                         break;
2776                 
2777                 // transfer shield energy to right
2778                 case SHIELD_XFER_RIGHT:
2779                         return button_function_critical(SHIELD_XFER_RIGHT);
2780                         break;
2781
2782                 // transfer energy to shield from weapons
2783                 case XFER_SHIELD:
2784                         return button_function_critical(XFER_SHIELD);
2785                         break;
2786
2787                 // transfer energy to weapons from shield
2788                 case XFER_LASER:
2789                         return button_function_critical(XFER_LASER);
2790                         break;
2791
2792                 // message all netplayers button
2793                 case MULTI_MESSAGE_ALL:
2794                         multi_msg_key_down(MULTI_MSG_ALL);
2795                         break;
2796
2797                 // message all friendlies button
2798                 case MULTI_MESSAGE_FRIENDLY:
2799                         multi_msg_key_down(MULTI_MSG_FRIENDLY);
2800                         break;
2801
2802                 // message all hostiles button
2803                 case MULTI_MESSAGE_HOSTILE:
2804                         multi_msg_key_down(MULTI_MSG_HOSTILE);
2805                         break;
2806
2807                 // message targeted ship (if player)
2808                 case MULTI_MESSAGE_TARGET:
2809                         multi_msg_key_down(MULTI_MSG_TARGET);
2810                         break;
2811
2812                 // if i'm an observer, zoom to my targeted object
2813                 case MULTI_OBSERVER_ZOOM_TO:
2814                         multi_obs_zoom_to_target();
2815                         break;          
2816 #ifndef MAKE_FS1
2817                 // toggle between high and low HUD contrast
2818                 case TOGGLE_HUD_CONTRAST:
2819                         gamesnd_play_iface(SND_USER_SELECT);
2820                         hud_toggle_contrast();
2821                         break;
2822
2823 #ifndef FS2_DEMO
2824                 // toggle network info
2825                 case MULTI_TOGGLE_NETINFO:
2826                         extern int Multi_display_netinfo;
2827                         Multi_display_netinfo = !Multi_display_netinfo;
2828                         break;
2829
2830                 // self destruct (multiplayer only)
2831                 case MULTI_SELF_DESTRUCT:
2832                         if(!(Game_mode & GM_MULTIPLAYER)){
2833                                 break;
2834                         }
2835
2836                         // bogus netplayer
2837                         if((Net_player == NULL) || (Net_player->player == NULL)){
2838                                 break;
2839                         }
2840
2841                         // blow myself up, if I'm the server
2842                         if(Net_player->flags & NETINFO_FLAG_AM_MASTER){
2843                                 if((Net_player->player->objnum >= 0) && (Net_player->player->objnum < MAX_OBJECTS) && 
2844                                         (Objects[Net_player->player->objnum].type == OBJ_SHIP) && (Objects[Net_player->player->objnum].instance >= 0) && (Objects[Net_player->player->objnum].instance < MAX_SHIPS)){
2845
2846                                         ship_self_destruct(&Objects[Net_player->player->objnum]);
2847                                 }
2848                         }
2849                         // otherwise send a packet to the server
2850                         else {
2851                                 send_self_destruct_packet();
2852                         }
2853                         break;
2854 #endif
2855 #endif
2856                 // following are not handled here, but we need to bypass the Int3()
2857                 case LAUNCH_COUNTERMEASURE:
2858                 case VIEW_SLEW:
2859                 case ONE_THIRD_THROTTLE:
2860                 case TWO_THIRDS_THROTTLE:
2861                 case MINUS_5_PERCENT_THROTTLE:
2862                 case PLUS_5_PERCENT_THROTTLE:
2863                 case ZERO_THROTTLE:
2864                 case MAX_THROTTLE:
2865                         return 0;
2866
2867                 default:
2868                         Int3();
2869                         break;
2870         } // end switch
2871
2872         return 1;
2873 }
2874
2875 // Call functions for when buttons are pressed
2876 void button_info_do(button_info *bi)
2877 {
2878         int i, j;
2879
2880         for (i=0; i<NUM_BUTTON_FIELDS; i++) {
2881                 if ( bi->status[i] == 0 ){
2882                         continue;
2883                 }
2884
2885                 // at least one bit is set in the status integer
2886                 for (j=0; j<32; j++) {
2887
2888                         // check if the bit is set. If button_function returns 1 (implying the action was taken), then unset the bit
2889                         if ( bi->status[i] & (1 << j) ) {
2890                                 // always process buttons which are valid for demo playback
2891                                 if(button_function_demo_valid(32 * i + j)){
2892                                         bi->status[i] &= ~(1 << j);
2893                                 }
2894                                 // other buttons
2895                                 else {
2896                                         // if we're in demo playback, always clear the bits
2897                                         if(Game_mode & GM_DEMO_PLAYBACK){
2898                                                 bi->status[i] &= ~(1 << j);
2899                                         }
2900                                         // otherwise check as normal
2901                                         else if (button_function(32 * i + j)) {
2902                                                 bi->status[i] &= ~(1 << j);                                     
2903                                         }
2904                                 }
2905                         }
2906                 }
2907         }
2908 }
2909
2910
2911 // set the bit for the corresponding action n (BUTTON_ #define from KeyControl.h)
2912 void button_info_set(button_info *bi, int n)
2913 {
2914         int field_num, bit_num;
2915         
2916         field_num = n / 32;
2917         bit_num = n % 32;
2918
2919         bi->status[field_num] |= (1 << bit_num);        
2920 }
2921
2922 // unset the bit for the corresponding action n (BUTTON_ #define from KeyControl.h)
2923 void button_info_unset(button_info *bi, int n)
2924 {
2925         int field_num, bit_num;
2926         
2927         field_num = n / 32;
2928         bit_num = n % 32;
2929
2930         bi->status[field_num] &= ~(1 << bit_num);       
2931 }
2932
2933 int button_info_query(button_info *bi, int n)
2934 {
2935         return bi->status[n / 32] & (1 << (n % 32));
2936 }
2937
2938 // clear out the button_info struct
2939 void button_info_clear(button_info *bi)
2940 {
2941         int i;
2942
2943         for (i=0; i<NUM_BUTTON_FIELDS; i++) {
2944                 bi->status[i] = 0;
2945         }
2946 }
2947
2948 // strip out all noncritical keys from the button info struct
2949 void button_strip_noncritical_keys(button_info *bi)
2950 {
2951         int idx;
2952
2953         // clear out all noncritical keys
2954         for(idx=0;idx<Non_critical_key_set_size;idx++){
2955                 button_info_unset(bi,Non_critical_key_set[idx]);
2956         }
2957 }