]> icculus.org git repositories - taylor/freespace2.git/blob - src/gamehelp/gameplayhelp.cpp
const-char warning fixes
[taylor/freespace2.git] / src / gamehelp / gameplayhelp.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/GameHelp/GameplayHelp.cpp $
11  * $Revision$
12  * $Date$
13  * $Author$
14  *
15  * Module for displaying in-game help
16  *
17  * $Log$
18  * Revision 1.6  2005/03/29 02:18:47  taylor
19  * Various 64-bit platform fixes
20  * Fix compiler errors with MAKE_FS1 and fix gr_set_bitmap() too
21  * Make sure that turrets can fire at asteroids for FS1 (needed for a couple missions)
22  * Streaming audio support (big thanks to Pierre Willenbrock!!)
23  * Removed dependance on strings.tbl for FS1 since we don't actually need it now
24  *
25  * Revision 1.5  2004/09/20 01:31:44  theoddone33
26  * GCC 3.4 fixes.
27  *
28  * Revision 1.4  2003/05/25 02:30:42  taylor
29  * Freespace 1 support
30  *
31  * Revision 1.3  2002/06/09 04:41:17  relnev
32  * added copyright header
33  *
34  * Revision 1.2  2002/05/07 03:16:44  theoddone33
35  * The Great Newline Fix
36  *
37  * Revision 1.1.1.1  2002/05/03 03:28:09  root
38  * Initial import.
39  *
40  * 
41  * 8     9/08/99 2:38p Jefff
42  * sound pausing going to menu from game
43  * 
44  * 7     9/01/99 2:56p Jefff
45  * a few control key description changes
46  * 
47  * 6     7/29/99 4:43p Jefff
48  * updated for fs2 -- fixed buttons, added "press esc" text, hi-res
49  * support, the works.
50  * 
51  * 5     7/15/99 9:20a Andsager
52  * FS2_DEMO initial checkin
53  * 
54  * 4     1/30/99 5:08p Dave
55  * More new hi-res stuff.Support for nice D3D textures.
56  * 
57  * 3     10/13/98 9:28a Dave
58  * Started neatening up freespace.h. Many variables renamed and
59  * reorganized. Added AlphaColors.[h,cpp]
60  * 
61  * 2     10/07/98 10:52a Dave
62  * Initial checkin.
63  * 
64  * 1     10/07/98 10:48a Dave
65  * 
66  * 21    6/17/98 11:01a Lawrance
67  * ensure translated descriptions appear in the online help
68  * 
69  * 20    6/09/98 10:31a Hoffoss
70  * Created index numbers for all xstr() references.  Any new xstr() stuff
71  * added from here on out should be added to the end if the list.  The
72  * current list count can be found in FreeSpace.cpp (search for
73  * XSTR_SIZE).
74  * 
75  * 19    5/17/98 3:33p Lawrance
76  * Add 'target last ship to send transmission' key to online help
77  * 
78  * 18    5/15/98 8:36p Lawrance
79  * Add 'target ship that last sent transmission' target key
80  * 
81  * 17    5/09/98 4:52p Lawrance
82  * Implement padlock view (up/rear/left/right)
83  * 
84  * 16    4/27/98 10:11a Lawrance
85  * Add in disabled beep for missing buttons
86  * 
87  * 15    4/25/98 1:25p Lawrance
88  * Change screen shot key to Print Scrn
89  * 
90  * 14    4/22/98 2:50p John
91  * Made PrintScreen actually be Shift+PrintScreen.
92  * 
93  * 13    4/18/98 9:21p Lawrance
94  * show correct key binding for screen shots
95  * 
96  * 12    4/11/98 7:59p Lawrance
97  * Allow space, tab and enter to cycle through pages
98  * 
99  * 11    4/05/98 7:44p Lawrance
100  * remove obsolete 'show goals' binding
101  * 
102  * 10    4/02/98 11:40a Lawrance
103  * check for #ifdef DEMO instead of #ifdef DEMO_RELEASE
104  * 
105  * 9     4/01/98 2:22p Lawrance
106  * remove hotkey references in on-line help for demo builds
107  * 
108  * 8     3/31/98 4:57p Lawrance
109  * update text for taking a screen shot
110  * 
111  * 7     3/30/98 1:31p Lawrance
112  * Take out debug key help
113  * 
114  * 6     3/25/98 5:34p Dave
115  * First rev of multiplayer online key help.
116  * 
117  * 5     3/25/98 2:16p Dave
118  * Select random default image for newly created pilots. Fixed several
119  * multi-pause messaging bugs. Begin work on online help for multiplayer
120  * keys.
121  * 
122  * 4     3/18/98 12:03p John
123  * Marked all the new strings as externalized or not.
124  * 
125  * 3     3/16/98 5:53p Lawrance
126  * Fix bug that was causing joystick only bindings to mess up
127  * 
128  * 2     3/09/98 9:54p Lawrance
129  * integrate new art for gameplay help
130  * 
131  * 1     3/09/98 5:05p Lawrance
132  *
133  * $NoKeywords: $
134  */
135
136 #include "contexthelp.h"
137 #include "gamesequence.h"
138 #include "freespace.h"
139 #include "key.h"
140 #include "bmpman.h"
141 #include "2d.h"
142 #include "timer.h"
143 #include "math.h"
144 #include "mouse.h"
145 #include "controlsconfig.h"
146 #include "ui.h"
147 #include "gamesnd.h"
148 #include "missionscreencommon.h"
149 #include "alphacolors.h"
150 #include "beam.h"
151 #include "audiostr.h"
152
153 // text positioning constats
154 #define TITLE_Y                 35
155 #define Y_START                 70
156 #define X_OFFSET_1              70
157
158 // pixel offset for description of key from where key binding starts
159 #define KEY_DESCRIPTION_OFFSET  193     
160
161 // different gameplay help pages
162 #define GP_FIRST_SCREEN                                                                 0               // keep up to date
163
164 #define GP_HELP_BASIC_KEYS                                                              0
165 #define GP_HELP_MOVEMENT_KEYS                                                   1
166 #define GP_HELP_COMMON_TARGET_KEYS                                      2
167 #define GP_HELP_ADVANCED_TARGET_KEYS                            3
168 #define GP_HELP_MESSAGING                                                               4
169 #define GP_HELP_WEAPON_KEYS                                                     5
170 #define GP_HELP_THROTTLE_AND_ETS_KEYS                           6
171 #define GP_HELP_VIEW_KEYS                                                               7
172 #define GP_HELP_MISC_KEYS                                                               8
173 #define GP_HELP_MULTI_KEYS                                                              9
174
175 #define GP_LAST_SCREEN_SINGLE                                                   8               // keep up to date
176 #define GP_LAST_SCREEN_MULTI                                                    9               // keep up to date
177
178 // set this to GP_LAST_SCREEN_SINGLE or GP_LAST_SCREEN_MULTI based upon what game mode we're in
179 int Gp_last_screen;
180
181 #define NUM_BUTTONS                                             3
182 #define PREVIOUS_PAGE_BUTTON                    0
183 #define NEXT_PAGE_BUTTON                                1
184 #define CONTINUE_BUTTON                                 2
185
186 struct gameplay_help_buttons {
187         const char *filename;
188         int x, y;
189         int hotspot;
190         int tab;
191         int flags;
192         UI_BUTTON button;  // because we have a class inside this struct, we need the constructor below..
193
194         gameplay_help_buttons(const char *name, int x1, int y1, int h) : filename(name), x(x1), y(y1), hotspot(h) {}
195 };
196
197 static gameplay_help_buttons Buttons[GR_NUM_RESOLUTIONS][NUM_BUTTONS] = {
198 //XSTR:OFF
199         {
200 #ifdef MAKE_FS1
201                 gameplay_help_buttons("F1B_00", 71,             373,    0),             // previous
202                 gameplay_help_buttons("F1B_01", 121,    373,    1),             // next
203 //              gameplay_help_buttons("F1B_02", 447,    452,    2),             // options
204                 gameplay_help_buttons("F1B_03", 554,    411,    3),             // continue
205 #else
206                 gameplay_help_buttons("F1B_00", 15,     389,    0),
207                 gameplay_help_buttons("F1B_01", 60,     389,    1),
208                 gameplay_help_buttons("F1B_02", 574,    431,    2)
209 #endif
210         },
211         {
212                 gameplay_help_buttons("2_F1B_00",       24,     622,    0),
213                 gameplay_help_buttons("2_F1B_01",       96,     622,    1),
214                 gameplay_help_buttons("2_F1B_02",       919,    689,    2)
215         },
216 //XSTR:ON
217 };
218
219 #ifndef MAKE_FS1
220 #define GAME_HELP_NUM_TEXT              2
221
222 static UI_XSTR Game_help_text[GR_NUM_RESOLUTIONS][GAME_HELP_NUM_TEXT] = {
223         { // GR_640
224                 { "Press ESC to return to the game",    1441,   263,    389,    UI_XSTR_COLOR_GREEN, -1, NULL },
225                 { "Continue",           1069,           571,    413,    UI_XSTR_COLOR_GREEN, -1, &Buttons[gr_screen.res][CONTINUE_BUTTON].button }
226         }, 
227         { // GR_1024
228                 // not needed for FS1
229                 { "Press ESC to return to the game",    1441,   421,    622,    UI_XSTR_COLOR_GREEN, -1, NULL },
230                 { "Continue",           1069,           928,    663,    UI_XSTR_COLOR_GREEN, -1, &Buttons[gr_screen.res][CONTINUE_BUTTON].button }
231         }
232 };
233 #endif
234
235 static const char *Game_help_filename[GR_NUM_RESOLUTIONS] = {
236         "F1",
237         "2_F1"
238 };
239
240 static const char *Game_help_mask_filename[GR_NUM_RESOLUTIONS] = {
241         "F1-m",
242         "2_F1-m"
243 };
244
245 static UI_WINDOW Ui_window;
246 static int Background_bitmap;
247 static int Gameplay_help_inited = 0;
248
249 static int Current_help_page;
250
251 // generate a line for the on-line help for a control item with specified id
252 // input:       id              =>      index for control item within Control_config[]
253 //                              buf     => buffer with enough space to hold ouput string
254 char *gameplay_help_control_text(int id, char *buf)
255 {
256         int                     has_key=0, has_joy=0;
257         config_item     *ci;
258
259         ci = &Control_config[id];
260
261         if ( ci->key_id >= 0 ) {
262                 sprintf(buf, textify_scancode(ci->key_id));
263                 has_key=1;
264         }
265
266         if ( ci->joy_id >= 0 ) {
267                 if ( has_key ) {
268                         strcat(buf, XSTR( ", ", 129));
269                 }
270                 strcat(buf, Joy_button_text[ci->joy_id]);
271                 has_joy=1;
272         }
273
274         if ( !has_key && !has_joy ) {
275                 strcpy(buf, XSTR( "no binding", 130));
276         }
277
278         strcat(buf, XSTR( " - ", 131));
279         strcat(buf, ci->text);
280
281         return buf;
282 }
283
284 void gameplay_help_blit_control_line(int x, int y, int id)
285 {
286         int                     has_key=0, has_joy=0;
287         char                    buf[256];
288         config_item     *ci;
289
290         ci = &Control_config[id];
291
292         buf[0] = 0;
293
294         if ( ci->key_id >= 0 ) {
295                 sprintf(buf, textify_scancode(ci->key_id));
296                 has_key=1;
297         }
298
299         if ( ci->joy_id >= 0 ) {
300                 if ( has_key ) {
301                         strcat(buf, XSTR( ", ", 129));
302                 }
303                 strcat(buf, Joy_button_text[ci->joy_id]);
304                 has_joy=1;
305         }
306
307         if ( !has_key && !has_joy ) {
308                 strcpy(buf, XSTR( "no binding", 130));
309         }
310
311         gr_string(x,y,buf);
312
313 //      gr_string(x+KEY_DESCRIPTION_OFFSET,y,ci->text);
314         gr_string(x+KEY_DESCRIPTION_OFFSET, y, XSTR(ci->text, CONTROL_CONFIG_XSTR + id));
315 }
316
317 void gameplay_help_blit_control_line_raw(int x, int y, const char *control_text, const char *control_description)
318 {
319         gr_string(x,y,control_text);
320         gr_string(x+KEY_DESCRIPTION_OFFSET,y,control_description);
321 }
322
323 // game_play_help_set_title() will display the title for the help screen and
324 // set the font for the rest of the screen
325 void gameplay_help_set_title(const char *title)
326 {
327         int sy=TITLE_Y;
328         char buf[128];
329
330         gr_set_color_fast(&Color_bright);
331         gr_printf(0x8000,sy,title);
332         sprintf(buf, XSTR( "Page %d of %d", 132),  Current_help_page+1, Gp_last_screen+1);
333         gr_printf(0x8000,sy+gr_get_font_height()+2,buf);
334         gr_set_color_fast(&Color_normal);
335 }
336
337 // called once when the gameplay help state is entered
338 void gameplay_help_init()
339 {
340         int i;
341         gameplay_help_buttons *b;
342
343         if ( Gameplay_help_inited ) {
344                 return;
345         }
346
347         common_set_interface_palette("InterfacePalette");  // set the interface palette
348         Ui_window.create(0, 0, gr_screen.max_w, gr_screen.max_h, 0);
349         Ui_window.set_mask_bmap(Game_help_mask_filename[gr_screen.res]);
350
351         for (i=0; i<NUM_BUTTONS; i++) {
352                 b = &Buttons[gr_screen.res][i];
353
354                 b->button.create(&Ui_window, "", b->x, b->y, 60, 30, 0, 1);
355                 // set up callback for when a mouse first goes over a button
356                 b->button.set_highlight_action(common_play_highlight_sound);
357                 b->button.set_bmaps(b->filename);
358                 b->button.link_hotspot(b->hotspot);
359         }
360
361 #ifndef MAKE_FS1
362         // add all xstrs
363         for (i=0; i<GAME_HELP_NUM_TEXT; i++)
364         {
365                 Ui_window.add_XSTR(&Game_help_text[gr_screen.res][i]);
366         }
367 #endif
368
369         // set the proper last screen # based upon game mode
370         if(Game_mode & GM_MULTIPLAYER){
371                 Gp_last_screen = GP_LAST_SCREEN_MULTI;
372         } else {
373                 Gp_last_screen = GP_LAST_SCREEN_SINGLE;
374         }
375
376         // setup hotkeys so lights flash when keys are pressed
377         Buttons[gr_screen.res][CONTINUE_BUTTON].button.set_hotkey(KEY_CTRLED | KEY_ENTER);
378         Buttons[gr_screen.res][PREVIOUS_PAGE_BUTTON].button.set_hotkey(KEY_LEFT);
379         Buttons[gr_screen.res][NEXT_PAGE_BUTTON].button.set_hotkey(KEY_RIGHT);
380
381         Background_bitmap = bm_load(Game_help_filename[gr_screen.res]);
382
383         Current_help_page = GP_HELP_BASIC_KEYS;
384         Gameplay_help_inited = 1;
385 }
386
387 // called when moving to the previous help page
388 void gameplay_help_goto_prev_screen()
389 {
390         Current_help_page--;
391         if (Current_help_page < GP_FIRST_SCREEN) {
392                 Current_help_page = Gp_last_screen;
393         }
394         gamesnd_play_iface(SND_SWITCH_SCREENS);
395
396 }
397
398 // called when proceeding to the next help page
399 void gameplay_help_goto_next_screen()
400 {
401         Current_help_page++;
402         if (Current_help_page > Gp_last_screen) {
403                 Current_help_page = GP_FIRST_SCREEN;
404         }
405         gamesnd_play_iface(SND_SWITCH_SCREENS);
406 }
407
408 // called when the screen is exited
409 void gameplay_help_leave()
410 {
411         // unpause all game sounds
412         beam_unpause_sounds();
413         audiostream_unpause_all();
414
415         gameseq_post_event(GS_EVENT_PREVIOUS_STATE);
416         game_flush();
417 }
418
419 // deal with a keypress on the gameplay help screen
420 void gameplay_help_process_key(int k)
421 {
422         switch ( k ) {
423                 case KEY_ESC:
424                         gameplay_help_leave();
425                         break;
426
427                 case KEY_ENTER:
428                 case KEY_SPACEBAR:
429                 case KEY_TAB:
430                         //gameplay_help_goto_next_screen();
431                         Buttons[gr_screen.res][NEXT_PAGE_BUTTON].button.press_button();
432                         break;
433
434                 case KEY_SHIFTED | KEY_TAB:
435                         Buttons[gr_screen.res][PREVIOUS_PAGE_BUTTON].button.press_button();
436 //                      gameplay_help_goto_prev_screen();
437                         break;
438
439                 default:
440                         break;
441
442         } // end switch
443 }
444
445 // deal with buttons being pressed on the gameplay help screen
446 void gameplay_help_button_pressed(int n)
447 {
448         switch (n) {
449
450         case PREVIOUS_PAGE_BUTTON:
451                 gameplay_help_goto_prev_screen();
452                 break;
453
454         case NEXT_PAGE_BUTTON:
455                 gameplay_help_goto_next_screen();
456                 break;
457
458         case CONTINUE_BUTTON:
459                 gameplay_help_leave();
460                 gamesnd_play_iface(SND_COMMIT_PRESSED);
461                 break;
462
463         default:
464                 Int3();
465                 break;
466         }
467 }
468
469 // Draw the help text onto the screen
470 void gameplay_help_draw_text()
471 {
472         int x_offset, y_offset, separation;
473
474         separation = gr_get_font_height() + 3;
475
476         switch ( Current_help_page ) {
477
478                 case GP_HELP_BASIC_KEYS:
479                         gameplay_help_set_title(XSTR( "Basic Keys", 133));
480                         x_offset=X_OFFSET_1;
481                         y_offset=Y_START;
482
483                         y_offset += separation;
484                         gameplay_help_blit_control_line(x_offset, y_offset,END_MISSION);
485
486                         y_offset += separation;
487                         gameplay_help_blit_control_line(x_offset, y_offset,FIRE_PRIMARY);
488
489                         y_offset += separation;
490                         gameplay_help_blit_control_line(x_offset, y_offset,MAX_THROTTLE);
491
492                         y_offset += separation;
493                         gameplay_help_blit_control_line(x_offset, y_offset,ZERO_THROTTLE);
494
495                         y_offset += separation;
496                         gameplay_help_blit_control_line(x_offset, y_offset,TARGET_NEXT);
497
498                         y_offset += separation;
499                         gameplay_help_blit_control_line(x_offset, y_offset,TARGET_PREV);
500
501                         y_offset += separation;
502                         gameplay_help_blit_control_line(x_offset, y_offset,TOGGLE_AUTO_TARGETING);
503
504                         y_offset += separation;
505                         y_offset += separation;
506
507                         gr_set_color_fast(&Color_bright);
508                         gr_printf(0x8000,y_offset,XSTR( "Function Keys", 134));
509                         gr_set_color_fast(&Color_normal);
510
511                         y_offset += separation;
512                         y_offset += separation;
513
514                         gameplay_help_blit_control_line_raw(x_offset,y_offset, XSTR( "F1", 135), XSTR( "context-sensitive help", 136));
515
516                         y_offset += separation;
517                         gameplay_help_blit_control_line_raw(x_offset,y_offset, XSTR( "F2", 137), XSTR( "options screen (available anywhere in game)", 138));
518
519 #if !(defined(FS2_DEMO) || defined(FS1_DEMO))
520                         y_offset += separation;
521                         gameplay_help_blit_control_line_raw(x_offset,y_offset, XSTR( "F3", 139), XSTR( "hotkey assignment", 140));
522 #endif
523
524                         y_offset += separation;
525                         gameplay_help_blit_control_line_raw(x_offset,y_offset, XSTR( "F4", 141), XSTR( "HUD message scroll-back", 142));
526
527 #if !(defined(FS2_DEMO) || defined(FS1_DEMO))
528                         y_offset += separation;
529                         gameplay_help_blit_control_line_raw(x_offset,y_offset, XSTR( "F5...F12", 143), XSTR( "hotkeys", 144));
530 #endif
531
532                         y_offset += separation;
533                         gameplay_help_blit_control_line_raw(x_offset,y_offset, XSTR( "Shift-Esc", 145), XSTR( "quit FreeSpace 2 immediately", 146));
534
535                         break;
536
537                 case GP_HELP_MOVEMENT_KEYS:
538                         gameplay_help_set_title(XSTR( "Movement Keys", 147));
539                         x_offset=X_OFFSET_1;
540                         y_offset=Y_START;
541
542                         gameplay_help_blit_control_line(x_offset, y_offset,FORWARD_THRUST);
543
544                         y_offset += separation;
545                         gameplay_help_blit_control_line(x_offset, y_offset,MAX_THROTTLE);
546
547                         y_offset += separation;
548                         gameplay_help_blit_control_line(x_offset, y_offset,ONE_THIRD_THROTTLE);
549
550                         y_offset += separation;
551                         gameplay_help_blit_control_line(x_offset, y_offset,TWO_THIRDS_THROTTLE);
552
553                         y_offset += separation;
554                         gameplay_help_blit_control_line(x_offset, y_offset,MINUS_5_PERCENT_THROTTLE);
555
556                         y_offset += separation;
557                         gameplay_help_blit_control_line(x_offset, y_offset,PLUS_5_PERCENT_THROTTLE);
558
559                         y_offset += separation;
560                         gameplay_help_blit_control_line(x_offset, y_offset,ZERO_THROTTLE);
561
562                         y_offset += separation;
563                         gameplay_help_blit_control_line(x_offset, y_offset,AFTERBURNER);
564
565                         y_offset += separation;
566                         gameplay_help_blit_control_line(x_offset, y_offset,REVERSE_THRUST);
567
568                         y_offset += separation;
569                         gameplay_help_blit_control_line(x_offset, y_offset,PITCH_FORWARD);
570
571                         y_offset += separation;
572                         gameplay_help_blit_control_line(x_offset, y_offset,PITCH_BACK);
573
574                         y_offset += separation;
575                         gameplay_help_blit_control_line(x_offset, y_offset,YAW_LEFT);
576
577                         y_offset += separation;
578                         gameplay_help_blit_control_line(x_offset, y_offset,YAW_RIGHT);
579
580                         y_offset += separation;
581                         gameplay_help_blit_control_line(x_offset, y_offset,BANK_LEFT);
582
583                         y_offset += separation;
584                         gameplay_help_blit_control_line(x_offset, y_offset,BANK_RIGHT);
585
586                         y_offset += separation;
587                         gameplay_help_blit_control_line(x_offset, y_offset,BANK_WHEN_PRESSED);
588                         break;
589
590                 case GP_HELP_COMMON_TARGET_KEYS:
591                         gameplay_help_set_title(XSTR( "Basic Targeting Keys", 148));
592                         x_offset=X_OFFSET_1;
593                         y_offset=Y_START;
594
595                         gameplay_help_blit_control_line(x_offset, y_offset,TARGET_NEXT);
596
597                         y_offset += separation;
598                         gameplay_help_blit_control_line(x_offset, y_offset,TARGET_PREV);
599
600                         y_offset += separation;
601                         gameplay_help_blit_control_line(x_offset, y_offset,TOGGLE_AUTO_TARGETING);
602
603                         y_offset += separation;
604                         gameplay_help_blit_control_line(x_offset, y_offset,TARGET_SHIP_IN_RETICLE);
605
606                         y_offset += separation;
607                         gameplay_help_blit_control_line(x_offset, y_offset,TARGET_NEXT_CLOSEST_HOSTILE);
608
609                         y_offset += separation;
610                         gameplay_help_blit_control_line(x_offset, y_offset,TARGET_PREV_CLOSEST_HOSTILE);
611
612                         y_offset += separation;
613                         gameplay_help_blit_control_line(x_offset, y_offset,TARGET_NEXT_CLOSEST_FRIENDLY);
614
615                         y_offset += separation;
616                         gameplay_help_blit_control_line(x_offset, y_offset,TARGET_PREV_CLOSEST_FRIENDLY);
617
618                         y_offset += separation;
619                         gameplay_help_blit_control_line(x_offset, y_offset,TARGET_NEXT_SUBOBJECT);
620
621                         y_offset += separation;
622                         gameplay_help_blit_control_line(x_offset, y_offset,TARGET_PREV_SUBOBJECT);
623
624                         y_offset += separation;
625                         gameplay_help_blit_control_line(x_offset, y_offset,TARGET_SUBOBJECT_IN_RETICLE);
626
627                         y_offset += separation;
628                         gameplay_help_blit_control_line(x_offset, y_offset,MATCH_TARGET_SPEED);
629
630                         y_offset += separation;
631                         gameplay_help_blit_control_line(x_offset, y_offset,TOGGLE_AUTO_MATCH_TARGET_SPEED);
632                         break;
633
634                 case GP_HELP_ADVANCED_TARGET_KEYS:
635                         gameplay_help_set_title(XSTR( "Advanced Targeting Keys", 149));
636                         x_offset=X_OFFSET_1;
637                         y_offset=Y_START;
638
639                         gameplay_help_blit_control_line(x_offset, y_offset,TARGET_CLOSEST_SHIP_ATTACKING_SELF);
640
641                         y_offset += separation;
642                         gameplay_help_blit_control_line(x_offset, y_offset,TARGET_CLOSEST_SHIP_ATTACKING_TARGET);
643
644                         y_offset += separation;
645                         gameplay_help_blit_control_line(x_offset, y_offset,TARGET_LAST_TRANMISSION_SENDER);
646
647                         y_offset += separation;
648                         gameplay_help_blit_control_line(x_offset, y_offset,TARGET_TARGETS_TARGET);
649
650                         y_offset += separation;
651                         gameplay_help_blit_control_line(x_offset, y_offset,TARGET_NEXT_ESCORT_SHIP);
652
653                         y_offset += separation;
654                         gameplay_help_blit_control_line(x_offset, y_offset,TARGET_CLOSEST_REPAIR_SHIP);
655
656                         y_offset += separation;
657                         gameplay_help_blit_control_line(x_offset, y_offset,TARGET_NEXT_UNINSPECTED_CARGO);
658
659                         y_offset += separation;
660                         gameplay_help_blit_control_line(x_offset, y_offset,TARGET_PREV_UNINSPECTED_CARGO);
661
662                         y_offset += separation;
663                         gameplay_help_blit_control_line(x_offset, y_offset,TARGET_NEWEST_SHIP);
664
665                         y_offset += separation;
666                         gameplay_help_blit_control_line(x_offset, y_offset,TARGET_NEXT_BOMB);
667
668                         y_offset += separation;
669                         gameplay_help_blit_control_line(x_offset, y_offset,TARGET_PREV_BOMB);
670
671                         y_offset += separation;
672                         gameplay_help_blit_control_line(x_offset, y_offset,STOP_TARGETING_SHIP);
673
674                         y_offset += separation;
675                         gameplay_help_blit_control_line(x_offset, y_offset,TARGET_NEXT_LIVE_TURRET);
676
677                         y_offset += separation;
678                         gameplay_help_blit_control_line(x_offset, y_offset,TARGET_PREV_LIVE_TURRET);
679
680                         y_offset += separation;
681                         gameplay_help_blit_control_line(x_offset, y_offset,STOP_TARGETING_SUBSYSTEM);
682
683 #if !(defined(FS2_DEMO) || defined(FS1_DEMO))
684
685                         y_offset += separation;
686                         gameplay_help_blit_control_line_raw(x_offset, y_offset, XSTR( "F5...F12", 143), XSTR( "Select target assigned to that hotkey", 150));
687
688                         y_offset += separation;
689                         gameplay_help_blit_control_line_raw(x_offset, y_offset, XSTR( "Shift-F5...F12", 151), XSTR( "Add/remove target from that hotkey", 152));
690
691                         y_offset += separation;
692                         gameplay_help_blit_control_line_raw(x_offset, y_offset, XSTR( "Alt-Shift-F5...F12", 153), XSTR( "Clear that hotkey", 154));
693
694 #endif
695
696                         break;
697
698                 case GP_HELP_MESSAGING:
699                         gameplay_help_set_title(XSTR( "Messaging Keys", 155));
700                         x_offset=X_OFFSET_1;
701                         y_offset=Y_START;
702
703                         gameplay_help_blit_control_line(x_offset, y_offset,SQUADMSG_MENU);
704
705                         y_offset += separation;
706                         gameplay_help_blit_control_line(x_offset, y_offset,REARM_MESSAGE);
707
708                         y_offset += separation;
709                         gameplay_help_blit_control_line(x_offset, y_offset,ATTACK_MESSAGE);
710
711                         y_offset += separation;
712                         gameplay_help_blit_control_line(x_offset, y_offset,DISARM_MESSAGE);
713
714                         y_offset += separation;
715                         gameplay_help_blit_control_line(x_offset, y_offset,DISABLE_MESSAGE);
716
717                         y_offset += separation;
718                         gameplay_help_blit_control_line(x_offset, y_offset,CAPTURE_MESSAGE);
719
720                         y_offset += separation;
721                         gameplay_help_blit_control_line(x_offset, y_offset,ENGAGE_MESSAGE);
722
723                         y_offset += separation;
724                         gameplay_help_blit_control_line(x_offset, y_offset,FORM_MESSAGE);
725
726                         y_offset += separation;
727                         gameplay_help_blit_control_line(x_offset, y_offset,IGNORE_MESSAGE);
728
729                         y_offset += separation;
730                         gameplay_help_blit_control_line(x_offset, y_offset,PROTECT_MESSAGE);
731
732                         y_offset += separation;
733                         gameplay_help_blit_control_line(x_offset, y_offset,COVER_MESSAGE);
734
735                         y_offset += separation;
736                         gameplay_help_blit_control_line(x_offset, y_offset,WARP_MESSAGE);
737
738 #if !(defined(FS2_DEMO) || defined(FS1_DEMO))
739                         y_offset += separation;
740                         gameplay_help_blit_control_line_raw(x_offset, y_offset, XSTR( "F5...F12", 143), XSTR( "send specified order to these target(s)", 156));
741 #endif
742                         break;
743
744                 case GP_HELP_WEAPON_KEYS:
745                         gameplay_help_set_title(XSTR( "Weapon Keys", 157));
746                         x_offset=X_OFFSET_1;
747                         y_offset=Y_START;
748
749                         gameplay_help_blit_control_line(x_offset, y_offset,FIRE_PRIMARY);
750
751                         y_offset += separation;
752                         gameplay_help_blit_control_line(x_offset, y_offset,FIRE_SECONDARY);
753
754                         y_offset += separation;
755                         gameplay_help_blit_control_line(x_offset, y_offset,CYCLE_NEXT_PRIMARY);
756
757                         y_offset += separation;
758                         gameplay_help_blit_control_line(x_offset, y_offset,CYCLE_PREV_PRIMARY);
759
760                         y_offset += separation;
761                         gameplay_help_blit_control_line(x_offset, y_offset,CYCLE_SECONDARY);
762
763                         y_offset += separation;
764                         gameplay_help_blit_control_line(x_offset, y_offset,CYCLE_NUM_MISSLES);
765
766                         y_offset += separation;
767                         gameplay_help_blit_control_line(x_offset, y_offset,LAUNCH_COUNTERMEASURE);
768                         break;
769
770                 case GP_HELP_THROTTLE_AND_ETS_KEYS:
771                         gameplay_help_set_title(XSTR( "Energy Management Keys", 158));
772                         x_offset=X_OFFSET_1;
773                         y_offset=Y_START;
774
775                         gameplay_help_blit_control_line(x_offset, y_offset,SHIELD_EQUALIZE);
776
777                         y_offset += separation;
778                         gameplay_help_blit_control_line(x_offset, y_offset,SHIELD_XFER_TOP);
779
780                         y_offset += separation;
781                         gameplay_help_blit_control_line(x_offset, y_offset,SHIELD_XFER_BOTTOM);
782
783                         y_offset += separation;
784                         gameplay_help_blit_control_line(x_offset, y_offset,SHIELD_XFER_LEFT);
785
786                         y_offset += separation;
787                         gameplay_help_blit_control_line(x_offset, y_offset,SHIELD_XFER_RIGHT);
788
789                         y_offset += separation;
790                         gameplay_help_blit_control_line(x_offset, y_offset,INCREASE_WEAPON);
791
792                         y_offset += separation;
793                         gameplay_help_blit_control_line(x_offset, y_offset,DECREASE_WEAPON);
794
795                         y_offset += separation;
796                         gameplay_help_blit_control_line(x_offset, y_offset,INCREASE_SHIELD);
797
798                         y_offset += separation;
799                         gameplay_help_blit_control_line(x_offset, y_offset,DECREASE_SHIELD);
800
801                         y_offset += separation;
802                         gameplay_help_blit_control_line(x_offset, y_offset,INCREASE_ENGINE);
803
804                         y_offset += separation;
805                         gameplay_help_blit_control_line(x_offset, y_offset,DECREASE_ENGINE);
806
807                         y_offset += separation;
808                         gameplay_help_blit_control_line(x_offset, y_offset,ETS_EQUALIZE);
809 /*
810                         y_offset += separation;
811                         gameplay_help_blit_control_line(x_offset, y_offset,XFER_LASER);
812
813                         y_offset += separation;
814                         gameplay_help_blit_control_line(x_offset, y_offset,XFER_SHIELD);
815 */
816                         break;
817
818                 case GP_HELP_MISC_KEYS:
819                         gameplay_help_set_title(XSTR( "Miscellaneous Keys", 159));
820                         x_offset=X_OFFSET_1;
821                         y_offset=Y_START;
822
823                         // ending mission
824                         //
825                         y_offset += separation;
826                         gameplay_help_blit_control_line(x_offset, y_offset,END_MISSION);
827
828                         y_offset += separation;
829                         gameplay_help_blit_control_line_raw(x_offset,y_offset, XSTR( "ESC", 160), XSTR( "invoke abort mission popup", 161));
830
831                         // time compression
832                         //
833                         y_offset += separation;
834                         gameplay_help_blit_control_line(x_offset, y_offset,TIME_SPEED_UP);
835
836                         y_offset += separation;
837                         gameplay_help_blit_control_line(x_offset, y_offset,TIME_SLOW_DOWN);
838
839                         // radar keys
840                         //
841                         y_offset += separation;
842                         gameplay_help_blit_control_line(x_offset, y_offset,RADAR_RANGE_CYCLE);
843
844                         // escort view keys
845                         //
846                         y_offset += separation;
847                         gameplay_help_blit_control_line(x_offset, y_offset,ADD_REMOVE_ESCORT);
848
849                         y_offset += separation;
850                         gameplay_help_blit_control_line(x_offset, y_offset,ESCORT_CLEAR);
851
852                         // Pause, Print Screenshot
853                         y_offset += separation;
854                         gameplay_help_blit_control_line_raw(x_offset,y_offset, XSTR( "Pause", 162), XSTR( "pause game", 163));            
855
856                         y_offset += separation;
857                         gameplay_help_blit_control_line_raw(x_offset,y_offset, XSTR( "Print Scrn", 164), XSTR( "take screen shot", 165));            
858
859                         break;
860
861                 case GP_HELP_VIEW_KEYS:
862                         gameplay_help_set_title(XSTR( "View Keys", 166));
863                         x_offset=X_OFFSET_1;
864                         y_offset=Y_START;
865
866                         gameplay_help_blit_control_line(x_offset, y_offset,PADLOCK_UP);
867
868                         y_offset += separation;
869                         gameplay_help_blit_control_line(x_offset, y_offset,PADLOCK_DOWN);
870
871                         y_offset += separation;
872                         gameplay_help_blit_control_line(x_offset, y_offset,PADLOCK_LEFT);
873
874                         y_offset += separation;
875                         gameplay_help_blit_control_line(x_offset, y_offset,PADLOCK_RIGHT);
876
877                         y_offset += separation;
878                         gameplay_help_blit_control_line(x_offset, y_offset,VIEW_CHASE);
879
880                         y_offset += separation;
881                         gameplay_help_blit_control_line(x_offset, y_offset,VIEW_EXTERNAL);
882
883                         y_offset += separation;
884                         gameplay_help_blit_control_line(x_offset, y_offset,VIEW_EXTERNAL_TOGGLE_CAMERA_LOCK);
885
886                         y_offset += separation;
887                         gameplay_help_blit_control_line(x_offset, y_offset,VIEW_SLEW);
888
889                         y_offset += separation;
890                         gameplay_help_blit_control_line(x_offset, y_offset,VIEW_DIST_INCREASE);
891
892                         y_offset += separation;
893                         gameplay_help_blit_control_line(x_offset, y_offset,VIEW_DIST_DECREASE);
894
895                         y_offset += separation;
896                         gameplay_help_blit_control_line(x_offset, y_offset,VIEW_CENTER);
897
898                         y_offset += separation;
899                         gameplay_help_blit_control_line(x_offset, y_offset,VIEW_OTHER_SHIP);
900                         break;
901
902                 case GP_HELP_MULTI_KEYS:
903                         gameplay_help_set_title(XSTR( "Multiplayer Keys", 167));
904                         x_offset=X_OFFSET_1;
905                         y_offset=Y_START;
906
907                         // ingame messaging
908                         gr_set_color_fast(&Color_bright);
909                         gr_printf(0x8000,y_offset,XSTR( "Ingame messaging keys (tap for text, hold for voice)", 168));
910                         gr_set_color_fast(&Color_normal);
911                         
912                         y_offset += separation;
913                         
914                         y_offset += separation;
915                         gameplay_help_blit_control_line(x_offset, y_offset,MULTI_MESSAGE_ALL);
916
917                         y_offset += separation;
918                         gameplay_help_blit_control_line(x_offset, y_offset,MULTI_MESSAGE_FRIENDLY);
919
920                         y_offset += separation;
921                         gameplay_help_blit_control_line(x_offset, y_offset,MULTI_MESSAGE_HOSTILE);
922
923                         y_offset += separation;
924                         gameplay_help_blit_control_line(x_offset, y_offset,MULTI_MESSAGE_TARGET);
925
926                         break;
927
928         } //    end switch              
929 }
930
931 // gameplay_help_do_frame() is the function that displays help when acutally playing the game
932 void gameplay_help_do_frame(float frametime)
933 {
934         int i, k;       
935
936         // ensure the gameplay help interface has been initialized
937         if (!Gameplay_help_inited) {
938                 Int3();
939                 return;
940         }
941
942         // make sure game sounds are paused
943         beam_pause_sounds();
944         audiostream_pause_all();
945
946         k = Ui_window.process() & ~KEY_DEBUGGED;
947         gameplay_help_process_key(k);
948
949         for (i=0; i<NUM_BUTTONS; i++){
950                 if (Buttons[gr_screen.res][i].button.pressed()){
951                         gameplay_help_button_pressed(i);
952                 }
953         }
954         
955         GR_MAYBE_CLEAR_RES(Background_bitmap);
956         if (Background_bitmap >= 0) {
957                 gr_set_bitmap(Background_bitmap, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);
958                 gr_bitmap(0, 0);
959         }
960
961         Ui_window.draw();
962
963         gameplay_help_draw_text();
964         gr_flip();
965 }
966
967
968 // called once when leaving the gameplay help state
969 void gameplay_help_close()
970 {
971         if ( Gameplay_help_inited ) {
972                 if (Background_bitmap >= 0) {
973                         bm_unload(Background_bitmap);
974                 }
975
976                 Ui_window.destroy();
977                 common_free_interface_palette();                // restore game palette
978                 game_flush();
979         }
980
981         Gameplay_help_inited = 0;
982 }
983