]> icculus.org git repositories - taylor/freespace2.git/blob - src/gamehelp/contexthelp.cpp
Initial revision
[taylor/freespace2.git] / src / gamehelp / contexthelp.cpp
1 /*
2  * $Logfile: /Freespace2/code/GameHelp/ContextHelp.cpp $
3  * $Revision$
4  * $Date$
5  * $Author$
6  *
7  * Functions to drive the context-sensitive help 
8  *
9  * $Log$
10  * Revision 1.1  2002/05/03 03:28:09  root
11  * Initial revision
12  *
13  * 
14  * 16    8/22/99 4:22p Jefff
15  * removed 2nd tech room overlay stuff
16  * 
17  * 15    8/09/99 5:54p Jefff
18  * tech room overlay changes
19  * 
20  * 14    7/27/99 7:18p Jefff
21  * fixed a debug function for adjsuting overlays in-game
22  * 
23  * 13    7/20/99 1:49p Dave
24  * Peter Drake build. Fixed some release build warnings.
25  * 
26  * 12    7/16/99 10:07a Jefff
27  * Removed legacy bitmap overlay code
28  * 
29  * 11    7/16/99 10:04a Jefff
30  * 
31  * 10    7/15/99 9:20a Andsager
32  * FS2_DEMO initial checkin
33  * 
34  * 9     7/11/99 6:40p Jefff
35  * 
36  * 8     7/08/99 6:25p Jefff
37  * got new help system working
38  * 
39  * 7     6/03/99 10:15p Dave
40  * Put in temporary main hall screen.
41  * 
42  * 6     3/25/99 8:32p Neilk
43  * temporary barracks help removal
44  * 
45  * 5     2/15/99 9:37a Dave
46  * Removed infinite loop from context help parse code.
47  * 
48  * 4     2/11/99 4:05p Neilk
49  * Temporary checkin
50  * 
51  * 3     1/29/99 2:37p Neilk
52  * foundation for a new help system
53  * 
54  * 2     10/07/98 10:52a Dave
55  * Initial checkin.
56  * 
57  * 1     10/07/98 10:48a Dave
58  * 
59  * 92    5/06/98 11:49p Lawrance
60  * Add help overlay for command brief
61  * 
62  * 91    5/05/98 1:49a Lawrance
63  * Add in missing help overlays
64  * 
65  * 90    4/25/98 2:00p Dave
66  * Installed a bunch of multiplayer context help screens. Reworked ingame
67  * join ship select screen. Fix places where network timestamps get hosed.
68  * 
69  * 89    4/20/98 12:03a Lawrance
70  * make gray help shader lighter
71  * 
72  * 88    4/11/98 7:59p Lawrance
73  * Add support for help overlays
74  * 
75  * 87    3/12/98 5:36p John
76  * Took out any unused shaders.  Made shader code take rgbc instead of
77  * matrix and vector since noone used it like a matrix and it would have
78  * been impossible to do in hardware.   Made Glide implement a basic
79  * shader for online help.  
80  * 
81  * 86    3/09/98 9:55p Lawrance
82  * split off gameplay help, rip out obsolete code
83  * 
84  * 85    3/05/98 11:15p Hoffoss
85  * Changed non-game key checking to use game_check_key() instead of
86  * game_poll().
87  * 
88  * 84    2/28/98 9:47p Lawrance
89  * Fix couple of typos
90  * 
91  * 83    2/28/98 7:02p Lawrance
92  * overhaul on-line help
93  * 
94 */
95 #include <string.h>
96 #include <setjmp.h>
97
98 #include "contexthelp.h"
99 #include "gamesequence.h"
100 #include "freespace.h"
101 #include "mainhallmenu.h"
102 #include "key.h"
103 #include "bmpman.h"
104 #include "2d.h"
105 #include "timer.h"
106 #include "math.h"
107 #include "mouse.h"
108 #include "controlsconfig.h"
109 #include "techmenu.h"
110 #include "parselo.h"
111 #include "localize.h"
112 #include "alphacolors.h"
113
114
115 ////////////////////////////////////////////////////////////////////
116 // private function prototypes / structs
117 ////////////////////////////////////////////////////////////////////
118 void parse_helptbl();
119 void help_overlay_blit(int overlay_id);
120 void help_overlay_init();
121
122
123 typedef struct {
124         int x_begin, y_begin, x_end, y_end;
125 } help_line;
126
127 typedef struct {
128         vector vtx[HELP_MAX_PLINE_VERTICES];
129         vector *pvtx[HELP_MAX_PLINE_VERTICES];
130         int vtxcount;
131 } help_pline;
132
133 typedef struct {
134         int x_coord, y_coord;
135         char* string;
136 } help_text;
137
138 typedef struct {
139         int x_coord, y_coord;
140 } help_left_bracket;
141
142 typedef struct {
143         int x_coord, y_coord;
144 } help_right_bracket;
145
146 typedef struct {
147         help_pline                              plinelist[GR_NUM_RESOLUTIONS][HELP_MAX_ITEM];
148         help_text                               textlist[GR_NUM_RESOLUTIONS][HELP_MAX_ITEM];
149         help_left_bracket               lbracketlist[GR_NUM_RESOLUTIONS][HELP_MAX_ITEM];
150         help_right_bracket      rbracketlist[GR_NUM_RESOLUTIONS][HELP_MAX_ITEM];
151         int plinecount;
152         int textcount;
153         int lbracketcount;
154         int rbracketcount;
155 } help_overlay;
156
157 // new help.tbl file way
158 char *help_overlay_section_names[MAX_HELP_OVERLAYS] = {
159         "$ship",                                        // ship_help
160         "$weapon",                              // weapon_help
161         "$briefing",                    // briefing
162         "$main",                                        //      main help overlay
163         "$barracks",                    // barracks
164         "$control",                             // control help
165         "$debrief",                             // debrief help
166         "$multicreate",         // multicreate help
167         "$multistart",                  // multistart help
168         "$multijoin",                   // multijoin help
169         "$main2",                               // main help overlay2
170         "$hotkey",                              // hotkey help
171         "$campaign",                    // campaign help
172         "$simulator",                   //      simulator help
173         "$tech",                                        // tech help
174         "$command"                              // command help
175 };
176
177 ////////////////////////////////////////////////////////////////////
178 // Game-wide globals
179 ////////////////////////////////////////////////////////////////////
180 shader Grey_shader;
181
182 ////////////////////////////////////////////////////////////////////
183 // Module globals
184 ////////////////////////////////////////////////////////////////////
185 static int help_left_bracket_bitmap;
186 static int help_right_bracket_bitmap;
187 static help_overlay help_overlaylist[MAX_HELP_OVERLAYS];
188
189 static int current_helpid = -1;         // the currently active overlay_id, only really used for the debug console funxions
190 int Help_overlay_flags;
191 static int Source_game_state;                   // state from where F1 was pressed
192
193 ////////////////////////////////////////////////////////////////////
194 // Public Functions
195 ////////////////////////////////////////////////////////////////////
196
197
198 // query whether a help overlay is active (ie being displayed)
199 int help_overlay_active(int overlay_id)
200 {
201         Assert(overlay_id >= 0 && overlay_id < MAX_HELP_OVERLAYS);
202         return Help_overlay_flags & (1<<overlay_id);
203 }
204
205 // stop displaying a help overlay
206 void help_overlay_set_state(int overlay_id, int state)
207 {
208         Assert(overlay_id >= 0 && overlay_id < MAX_HELP_OVERLAYS);
209
210         if ( state > 0 ) {
211                 Help_overlay_flags |= (1<<overlay_id);
212                 current_helpid = overlay_id;
213         } else {
214                 Help_overlay_flags &= ~(1<<overlay_id);
215                 //current_helpid = -1;
216         }
217
218 }
219
220 // load in the bitmap for a help overlay
221 // FIXME - leftover from the old bitmap overlay days - prune this out sometime
222 void help_overlay_load(int overlay_id)
223 {
224         return;
225
226
227 // unload a bitmap of a help overlay
228 // FIXME - leftover from the old bitmap overlay days - prune this out sometime
229 void help_overlay_unload(int overlay_id)
230 {
231         return; 
232 }
233
234 // maybe blit a bitmap of a help overlay to the screen
235 void help_overlay_maybe_blit(int overlay_id)
236 {
237         Assert(overlay_id >= 0 && overlay_id < MAX_HELP_OVERLAYS);
238
239         if ( Help_overlay_flags & (1<<overlay_id) ) {
240                 context_help_grey_screen();
241                 help_overlay_blit(overlay_id);                          
242         }
243 }
244
245 // reset the flags for the help overlays
246 void help_overlay_reset_all()
247 {
248         Help_overlay_flags = 0;
249 }
250
251 // Set up Grey_shader, which is used game-wide to grey out background when using help overlays
252 void create_grey_shader()
253 {
254         float tmp,c;
255
256         tmp = 0.4f/3.0f;
257
258         // The c matrix brightens everything a bit.
259 //      c = 0.125f;
260         c = 0.110f;
261
262         gr_create_shader( &Grey_shader, tmp, tmp, tmp, c );
263 }
264
265 // called at game startup to init all help related data
266 void context_help_init() 
267 {
268         create_grey_shader();
269         help_overlay_reset_all();
270         help_overlay_init();
271 }
272
273 void context_help_grey_screen()
274 {
275         gr_set_shader(&Grey_shader);
276         gr_shade(0,0,gr_screen.clip_width, gr_screen.clip_height);
277 }
278
279 // launch_context_help() will switch to a context sensitive help state
280 void launch_context_help()
281 {
282         // look at the state the game was in when F1 was pressed
283         Source_game_state = gameseq_get_state();
284
285         switch (Source_game_state) {
286
287                 case GS_STATE_MAIN_MENU:
288 #if !defined(PRESS_TOUR_BUILD) && !defined(PD_BUILD)
289                         int main_hall_num;
290                         main_hall_num = (main_hall_id() == 0) ? MH_OVERLAY : MH2_OVERLAY;
291                         if ( !help_overlay_active(main_hall_num) ) {
292                                 help_overlay_set_state(main_hall_num, 1);
293                         }
294                         else {
295                                 help_overlay_set_state(main_hall_num, 0);
296                         }
297 #endif
298                         break;
299
300                 case GS_STATE_GAME_PLAY:
301                 case GS_STATE_GAME_PAUSED:
302                 case GS_STATE_TRAINING_PAUSED:
303                         gameseq_post_event(GS_EVENT_GAMEPLAY_HELP);
304                         break;
305
306                 case GS_STATE_BRIEFING:
307                         if ( !help_overlay_active(BR_OVERLAY) ) {
308                                 help_overlay_set_state(BR_OVERLAY, 1);
309                         }
310                         else {
311                                 help_overlay_set_state(BR_OVERLAY, 0);
312                         }
313                         break;
314
315                 case GS_STATE_SHIP_SELECT:
316                         if ( !help_overlay_active(SS_OVERLAY) ) {
317                                 help_overlay_set_state(SS_OVERLAY, 1);
318                         }
319                         else {
320                                 help_overlay_set_state(SS_OVERLAY, 0);
321                         }
322                         break;
323
324                 case GS_STATE_WEAPON_SELECT:
325                         if ( !help_overlay_active(WL_OVERLAY) ) {
326                                 help_overlay_set_state(WL_OVERLAY, 1);
327                         }
328                         else {
329                                 help_overlay_set_state(WL_OVERLAY, 0);
330                         }
331                         break;
332
333                 case GS_STATE_BARRACKS_MENU:
334                         if ( !help_overlay_active(BARRACKS_OVERLAY) ) {
335                                 help_overlay_set_state(BARRACKS_OVERLAY, 1);
336                         }
337                         else {
338                                 help_overlay_set_state(BARRACKS_OVERLAY, 0);
339                         }
340                         break;
341
342                 case GS_STATE_CONTROL_CONFIG:
343                         if ( !help_overlay_active(CONTROL_CONFIG_OVERLAY) ) {
344                                 help_overlay_set_state(CONTROL_CONFIG_OVERLAY, 1);
345                         }
346                         else {
347                                 help_overlay_set_state(CONTROL_CONFIG_OVERLAY, 0);
348                         }
349                         break;
350
351                 case GS_STATE_DEBRIEF:
352                         if ( !help_overlay_active(DEBRIEFING_OVERLAY) ) {
353                                 help_overlay_set_state(DEBRIEFING_OVERLAY, 1);
354                         }
355                         else {
356                                 help_overlay_set_state(DEBRIEFING_OVERLAY, 0);
357                         }
358                         break;
359
360                 case GS_STATE_MULTI_HOST_SETUP:
361                         if ( !help_overlay_active(MULTI_CREATE_OVERLAY) ) {
362                                 help_overlay_set_state(MULTI_CREATE_OVERLAY, 1);
363                         }
364                         else {
365                                 help_overlay_set_state(MULTI_CREATE_OVERLAY, 0);
366                         }
367                         break;
368
369                 case GS_STATE_MULTI_START_GAME:
370                         if ( !help_overlay_active(MULTI_START_OVERLAY) ) {
371                                 help_overlay_set_state(MULTI_START_OVERLAY, 1);
372                         }
373                         else {
374                                 help_overlay_set_state(MULTI_START_OVERLAY, 0);
375                         }
376                         break;
377
378                 case GS_STATE_MULTI_JOIN_GAME:
379                         if ( !help_overlay_active(MULTI_JOIN_OVERLAY) ) {
380                                 help_overlay_set_state(MULTI_JOIN_OVERLAY, 1);
381                         }
382                         else {
383                                 help_overlay_set_state(MULTI_JOIN_OVERLAY, 0);
384                         }
385                         break;
386
387                 case GS_STATE_HOTKEY_SCREEN:
388                         if ( !help_overlay_active(HOTKEY_OVERLAY) ) {
389                                 help_overlay_set_state(HOTKEY_OVERLAY, 1);
390                         }
391                         else {
392                                 help_overlay_set_state(HOTKEY_OVERLAY, 0);
393                         }
394                         break;
395
396                 case GS_STATE_CAMPAIGN_ROOM:
397                         if ( !help_overlay_active(CAMPAIGN_ROOM_OVERLAY) ) {
398                                 help_overlay_set_state(CAMPAIGN_ROOM_OVERLAY, 1);
399                         }
400                         else {
401                                 help_overlay_set_state(CAMPAIGN_ROOM_OVERLAY, 0);
402                         }
403                         break;
404
405                 case GS_STATE_SIMULATOR_ROOM:
406                         if ( !help_overlay_active(SIM_ROOM_OVERLAY) ) {
407                                 help_overlay_set_state(SIM_ROOM_OVERLAY, 1);
408                         }
409                         else {
410                                 help_overlay_set_state(SIM_ROOM_OVERLAY, 0);
411                         }
412                         break;
413
414                 case GS_STATE_TECH_MENU: {                              
415                         if ( !help_overlay_active(TECH_ROOM_OVERLAY) ) {
416                                 help_overlay_set_state(TECH_ROOM_OVERLAY, 1);
417                         }
418                         else {
419                                 help_overlay_set_state(TECH_ROOM_OVERLAY, 0);
420                         }
421                         break;
422                 }
423
424                 case GS_STATE_CMD_BRIEF:
425                         if ( !help_overlay_active(CMD_BRIEF_OVERLAY) ) {
426                                 help_overlay_set_state(CMD_BRIEF_OVERLAY, 1);
427                         }
428                         else {
429                                 help_overlay_set_state(CMD_BRIEF_OVERLAY, 0);
430                         }
431                         break;
432
433                 default:
434                         nprintf(("Warning","WARNING ==> There is no context help available for state %s\n", GS_state_text[Source_game_state-1]));
435                         break;
436
437         } // end switch
438 }
439
440
441 // Called once at the beginning of the game to load help bitmaps & data
442 void help_overlay_init() 
443 {
444         // load right_bracket bitmap
445         help_right_bracket_bitmap = bm_load("right_bracket");
446         if(help_right_bracket_bitmap < 0){
447                 // we failed to load the bitmap - this is very bad
448                 Int3();
449         }
450
451         // load left_bracket bitmap
452         help_left_bracket_bitmap = bm_load("left_bracket");
453         if(help_left_bracket_bitmap < 0){
454                 // we failed to load the bitmap - this is very bad
455                 Int3();
456         }
457
458         // parse help.tbl
459         parse_helptbl();
460 }
461
462
463 // parses help.tbl and populates help_overlaylist[]
464 void parse_helptbl()
465 {
466         int overlay_id, currcount;
467         char buf[HELP_MAX_STRING_LENGTH + 1];
468         int i;
469
470         // open localization
471         lcl_ext_open();
472         
473         read_file_text(HELP_OVERLAY_FILENAME);
474
475         // for each overlay...
476         for (overlay_id=0; overlay_id<MAX_HELP_OVERLAYS; overlay_id++) {
477
478                 reset_parse();
479                 skip_to_string(help_overlay_section_names[overlay_id]);
480
481                 // clear out counters in the overlay struct
482                 help_overlaylist[overlay_id].plinecount = 0;
483                 help_overlaylist[overlay_id].textcount = 0;
484                 help_overlaylist[overlay_id].rbracketcount = 0;
485                 help_overlaylist[overlay_id].lbracketcount = 0;
486                 
487                 // read in all elements for this overlay
488                 while (!(check_for_string("$end")))  {
489
490                         if (optional_string("+pline")) {
491
492                                 currcount = help_overlaylist[overlay_id].plinecount;
493                                 int a, b;               // temp vars to read in int before cast to float;
494
495                                 if (currcount < HELP_MAX_ITEM) {
496                                         // read number of pline vertices
497                                         stuff_int(&help_overlaylist[overlay_id].plinelist[GR_640][currcount].vtxcount);         // note that it is read into GR_640
498                                         // help_overlaylist[overlay_id].plinelist[GR_1024][currcount].vtxcount = help_overlaylist[overlay_id].plinelist[GR_640][currcount].vtxcount;                    // set equal to 1024 version vertex count to prevent bugs
499                                         Assert(help_overlaylist[overlay_id].plinelist[GR_640][currcount].vtxcount <= HELP_MAX_PLINE_VERTICES);
500                                         // get 640x480 vertex coordinates
501                                         for (i=0; i<help_overlaylist[overlay_id].plinelist[GR_640][currcount].vtxcount; i++) {
502                                                 stuff_int(&a);
503                                                 stuff_int(&b);
504                                                 help_overlaylist[overlay_id].plinelist[GR_640][currcount].vtx[i].x = (float)a;
505                                                 help_overlaylist[overlay_id].plinelist[GR_640][currcount].vtx[i].y = (float)b;
506                                                 help_overlaylist[overlay_id].plinelist[GR_640][currcount].vtx[i].z = 0.0f;
507                                                 help_overlaylist[overlay_id].plinelist[GR_640][currcount].pvtx[i] = &help_overlaylist[overlay_id].plinelist[GR_640][currcount].vtx[i];
508                                         }
509                                         // get 1024x768 vertex coordinates
510                                         for (i=0; i<help_overlaylist[overlay_id].plinelist[GR_640][currcount].vtxcount; i++) {
511                                                 stuff_int(&a);
512                                                 stuff_int(&b);
513                                                 help_overlaylist[overlay_id].plinelist[GR_1024][currcount].vtx[i].x = (float)a;
514                                                 help_overlaylist[overlay_id].plinelist[GR_1024][currcount].vtx[i].y = (float)b;
515                                                 help_overlaylist[overlay_id].plinelist[GR_1024][currcount].vtx[i].z = 0.0f;
516                                                 help_overlaylist[overlay_id].plinelist[GR_1024][currcount].pvtx[i] = &help_overlaylist[overlay_id].plinelist[GR_1024][currcount].vtx[i];
517                                         }
518                                 }
519
520                                 //mprintf(("Found pline - start location (%f,%f), end location (%f,%f)\n", help_overlaylist[overlay_id].plinelist[GR_640][currcount].vtx[0].x, help_overlaylist[overlay_id].plinelist[GR_640][currcount].vtx[0].y, help_overlaylist[overlay_id].plinelist[GR_640][currcount].vtx[2].x, help_overlaylist[overlay_id].plinelist[GR_640][currcount].vtx[2].y));
521                                 help_overlaylist[overlay_id].plinecount++;
522
523                         } else if (optional_string("+text")) {
524
525                                 currcount = help_overlaylist[overlay_id].textcount;
526
527                                 if (currcount < HELP_MAX_ITEM) {
528                                         // get 640x480 coordinates
529                                         stuff_int(&(help_overlaylist[overlay_id].textlist[GR_640][currcount].x_coord));
530                                         stuff_int(&(help_overlaylist[overlay_id].textlist[GR_640][currcount].y_coord));
531                                         // get 1024x768 coordinates
532                                         stuff_int(&(help_overlaylist[overlay_id].textlist[GR_1024][currcount].x_coord));
533                                         stuff_int(&(help_overlaylist[overlay_id].textlist[GR_1024][currcount].y_coord));
534
535                                         // get string (always use the GR_640 one)
536                                         stuff_string(buf, F_MESSAGE, NULL);
537                                         help_overlaylist[overlay_id].textlist[GR_640][currcount].string = strdup(buf);
538
539                                         //mprintf(("Found text %d on overlay %d - location (%d,%d) @ 640x480 :: location (%d,%d) @ 1024x768\n", currcount, overlay_id, help_overlaylist[overlay_id].textlist[GR_640][currcount].x_coord, help_overlaylist[overlay_id].textlist[GR_640][currcount].y_coord, help_overlaylist[overlay_id].textlist[GR_1024][currcount].x_coord, help_overlaylist[overlay_id].textlist[GR_1024][currcount].x_coord));
540                                         help_overlaylist[overlay_id].textcount++;
541                                 }
542
543                         } else if (optional_string("+right_bracket")) {
544
545                                 currcount = help_overlaylist[overlay_id].rbracketcount;
546
547                                 if (currcount < HELP_MAX_ITEM) {
548                                         // get 640x480 coordinates
549                                         stuff_int(&(help_overlaylist[overlay_id].rbracketlist[GR_640][currcount].x_coord));
550                                         stuff_int(&(help_overlaylist[overlay_id].rbracketlist[GR_640][currcount].y_coord));
551                                         // get 1024x768 coordinates
552                                         stuff_int(&(help_overlaylist[overlay_id].rbracketlist[GR_1024][currcount].x_coord));
553                                         stuff_int(&(help_overlaylist[overlay_id].rbracketlist[GR_1024][currcount].y_coord));
554
555                                         //mprintf(("Found rbracket %d on overlay %d - location (%d,%d) @ 640x480 :: location (%d,%d) @ 1024x768\n", currcount, overlay_id, help_overlaylist[overlay_id].rbracketlist[GR_640][currcount].x_coord, help_overlaylist[overlay_id].rbracketlist[GR_640][currcount].y_coord, help_overlaylist[overlay_id].rbracketlist[GR_1024][currcount].x_coord, help_overlaylist[overlay_id].rbracketlist[GR_1024][currcount].y_coord));
556                                         help_overlaylist[overlay_id].rbracketcount++;
557                                 }
558
559                         } else if (optional_string("+left_bracket")) {
560
561                                 currcount = help_overlaylist[overlay_id].lbracketcount;
562
563                                 if (currcount < HELP_MAX_ITEM) {
564                                         // get 640x480 coordinates
565                                         stuff_int(&(help_overlaylist[overlay_id].lbracketlist[GR_640][currcount].x_coord));
566                                         stuff_int(&(help_overlaylist[overlay_id].lbracketlist[GR_640][currcount].y_coord));
567                                         // get 1024x768 coordinates
568                                         stuff_int(&(help_overlaylist[overlay_id].lbracketlist[GR_1024][currcount].x_coord));
569                                         stuff_int(&(help_overlaylist[overlay_id].lbracketlist[GR_1024][currcount].y_coord));
570
571                                         //mprintf(("Found lbracket %d on overlay %d - location (%d,%d) @ 640x480 :: location (%d,%d) @ 1024x768\n", currcount, overlay_id, help_overlaylist[overlay_id].lbracketlist[GR_640][currcount].x_coord, help_overlaylist[overlay_id].lbracketlist[GR_640][currcount].y_coord, help_overlaylist[overlay_id].lbracketlist[GR_1024][currcount].x_coord, help_overlaylist[overlay_id].lbracketlist[GR_1024][currcount].y_coord));
572                                         help_overlaylist[overlay_id].lbracketcount++;
573                                 }
574
575                         } else {
576                                 // help.tbl is corrupt
577                                 Assert(0);
578
579                         }               // end if
580
581                 }               // end while
582         }               // end for
583
584         // close localization
585         lcl_ext_close();
586 }
587
588
589
590 // draw overlay on the screen
591 void help_overlay_blit(int overlay_id) 
592 {
593         int idx, width, height;
594         int plinecount = help_overlaylist[overlay_id].plinecount;
595         int textcount = help_overlaylist[overlay_id].textcount;
596         int rbracketcount = help_overlaylist[overlay_id].rbracketcount;
597         int lbracketcount = help_overlaylist[overlay_id].lbracketcount;
598
599         Assert(overlay_id >= 0 && overlay_id < MAX_HELP_OVERLAYS);
600
601         // this draws each line of help text with white on black text (use the GR_640 index for the string)
602         for (idx = 0; idx < textcount; idx++) {
603                 gr_set_color_fast(&Color_black);
604                 gr_get_string_size(&width, &height, help_overlaylist[overlay_id].textlist[GR_640][idx].string, strlen(help_overlaylist[overlay_id].textlist[GR_640][idx].string));
605                 gr_rect(help_overlaylist[overlay_id].textlist[gr_screen.res][idx].x_coord-2*HELP_PADDING, help_overlaylist[overlay_id].textlist[gr_screen.res][idx].y_coord-3*HELP_PADDING, width+4*HELP_PADDING, height+4*HELP_PADDING);
606                 gr_set_color_fast(&Color_bright_white);
607                 gr_printf(help_overlaylist[overlay_id].textlist[gr_screen.res][idx].x_coord, help_overlaylist[overlay_id].textlist[gr_screen.res][idx].y_coord, help_overlaylist[overlay_id].textlist[GR_640][idx].string);
608         }
609
610         // this draws each right bracket
611         for (idx = 0; idx < rbracketcount; idx++) {
612                 gr_set_bitmap(help_right_bracket_bitmap);
613                 gr_bitmap(help_overlaylist[overlay_id].rbracketlist[gr_screen.res][idx].x_coord, help_overlaylist[overlay_id].rbracketlist[gr_screen.res][idx].y_coord);
614         }
615
616         // this draws each left bracket
617         for (idx = 0; idx < lbracketcount; idx++) {
618                 gr_set_bitmap(help_left_bracket_bitmap);
619                 gr_bitmap(help_overlaylist[overlay_id].lbracketlist[gr_screen.res][idx].x_coord, help_overlaylist[overlay_id].lbracketlist[gr_screen.res][idx].y_coord);
620         }       
621
622         // this draws each 2d line for the help screen
623         //gr_set_color_fast(&Color_yellow);
624         gr_set_color(255, 255, 0);
625         for (idx = 0; idx<plinecount; idx++) {
626                 gr_pline_special(help_overlaylist[overlay_id].plinelist[gr_screen.res][idx].pvtx        , help_overlaylist[overlay_id].plinelist[GR_640][idx].vtxcount, HELP_PLINE_THICKNESS);
627         }
628 }
629
630
631 // --------------------------------------------------
632 // DEBUGGING STUFF
633 // --------------------------------------------------
634
635 DCF(help_reload, "Reloads help overlay data from help.tbl")
636 {
637         if (Dc_command) {
638                 parse_helptbl();
639         }
640
641         if (Dc_help)    {
642                 dc_printf( "Usage: sample\nCrashes your machine.\n" );
643         }
644
645         if (Dc_status)  {
646                 dc_printf( "Yes, my master." );
647         }
648 }
649
650 int h_textnum=0, h_amt=0, h_vtx = 0;
651
652 void nudgetext_x(int textnum, int amount)
653 {
654         help_overlaylist[current_helpid].textlist[gr_screen.res][textnum].x_coord += amount;
655 }
656 void nudgetext_y(int textnum, int amount)
657 {
658         help_overlaylist[current_helpid].textlist[gr_screen.res][textnum].y_coord += amount;
659 }
660 void nudgepline_x(int plinenum, int plinevert, int amount)
661 {
662         help_overlaylist[current_helpid].plinelist[gr_screen.res][plinenum].vtx[plinevert].x += amount;
663 }
664 void nudgepline_y(int plinenum, int plinevert, int amount)
665 {
666         help_overlaylist[current_helpid].plinelist[gr_screen.res][plinenum].vtx[plinevert].y += amount;
667 }
668 void nudgerbracket_x(int num, int amount)
669 {
670         help_overlaylist[current_helpid].rbracketlist[gr_screen.res][num].x_coord += amount;
671 }
672 void nudgerbracket_y(int num, int amount)
673 {
674         help_overlaylist[current_helpid].rbracketlist[gr_screen.res][num].y_coord += amount;
675 }
676 void nudgelbracket_x(int num, int amount)
677 {
678         help_overlaylist[current_helpid].lbracketlist[gr_screen.res][num].x_coord += amount;
679 }
680 void nudgelbracket_y(int num, int amount)
681 {
682         help_overlaylist[current_helpid].lbracketlist[gr_screen.res][num].y_coord += amount;
683 }
684 void showtextpos(int textnum)
685 {
686         dc_printf("text %d is now located at (%d, %d)", textnum, help_overlaylist[current_helpid].textlist[gr_screen.res][textnum].x_coord, help_overlaylist[current_helpid].textlist[gr_screen.res][textnum].y_coord );
687 }
688 void showrbracketpos(int num)
689 {
690         dc_printf("rbracket %d is now located at (%d, %d)", num, help_overlaylist[current_helpid].rbracketlist[gr_screen.res][num].x_coord, help_overlaylist[current_helpid].rbracketlist[gr_screen.res][num].y_coord );
691 }
692 void showlbracketpos(int num)
693 {
694         dc_printf("lbracket %d on overlay %d is now located at (%d, %d)", num, current_helpid, help_overlaylist[current_helpid].lbracketlist[gr_screen.res][num].x_coord, help_overlaylist[current_helpid].lbracketlist[gr_screen.res][num].y_coord );
695 }
696 void showplinepos(int plinenum)
697 {
698         int i;
699         dc_printf("pline %d on overlay %d vertices are now ", plinenum, current_helpid, help_overlaylist[current_helpid].textlist[gr_screen.res][plinenum].y_coord );
700         for (i=0; i<help_overlaylist[current_helpid].plinelist[GR_640][plinenum].vtxcount; i++)
701         {
702                 dc_printf("(%3.0f %3.0f) ", help_overlaylist[current_helpid].plinelist[gr_screen.res][plinenum].vtx[i].x, help_overlaylist[current_helpid].plinelist[gr_screen.res][plinenum].vtx[i].y);
703         }
704 }
705
706 DCF(help_nudgetext_x, "Use to visually position overlay text.")
707 {
708         if (Dc_command) {
709                 dc_get_arg(ARG_INT);
710                 if(Dc_arg_type & ARG_INT){
711                          h_textnum = Dc_arg_int;                
712                 }
713                 dc_get_arg(ARG_INT);
714                 if(Dc_arg_type & ARG_INT){
715                          h_amt = Dc_arg_int;            
716                 }
717                 nudgetext_x(h_textnum, h_amt);
718         }
719
720         if (Dc_help)    {
721                 dc_printf( "Usage: sample\nCrashes your machine.\n" );
722         }
723
724         if (Dc_status)  {
725                 showtextpos(h_textnum);
726         }
727 }
728
729 DCF(help_nudgetext_y, "Use to visually position overlay text.")
730 {
731         if (Dc_command) {
732                 dc_get_arg(ARG_INT);
733                 if(Dc_arg_type & ARG_INT){
734                          h_textnum = Dc_arg_int;                
735                 }
736                 dc_get_arg(ARG_INT);
737                 if(Dc_arg_type & ARG_INT){
738                          h_amt = Dc_arg_int;            
739                 }
740                 nudgetext_y(h_textnum, h_amt);
741         }
742
743         if (Dc_help)    {
744                 dc_printf( "Usage: sample\nCrashes your machine.\n" );
745         }
746
747         if (Dc_status)  {
748                 showtextpos(h_textnum);
749         }
750 }
751
752 DCF(help_nudgepline_x, "Use to visually position overlay polylines.")
753 {
754         if (Dc_command) {
755                 dc_get_arg(ARG_INT);
756                 if(Dc_arg_type & ARG_INT){
757                          h_textnum = Dc_arg_int;                
758                 }
759                 dc_get_arg(ARG_INT);
760                 if(Dc_arg_type & ARG_INT){
761                          h_vtx = Dc_arg_int;            
762                 }
763                 dc_get_arg(ARG_INT);
764                 if(Dc_arg_type & ARG_INT){
765                          h_amt = Dc_arg_int;            
766                 }
767                 nudgepline_x(h_textnum, h_vtx, h_amt);
768         }
769
770         if (Dc_help)    {
771                 dc_printf( "Usage: help_nudgepline [pline_number] [vertex_number] [distance]\n" );
772         }
773
774         if (Dc_status)  {
775                 showplinepos(h_textnum);
776         }
777 }
778
779
780 DCF(help_nudgepline_y, "Use to visually position overlay polylines.")
781 {
782         if (Dc_command) {
783                 dc_get_arg(ARG_INT);
784                 if(Dc_arg_type & ARG_INT){
785                          h_textnum = Dc_arg_int;                
786                 }
787                 dc_get_arg(ARG_INT);
788                 if(Dc_arg_type & ARG_INT){
789                          h_vtx = Dc_arg_int;            
790                 }
791                 dc_get_arg(ARG_INT);
792                 if(Dc_arg_type & ARG_INT){
793                          h_amt = Dc_arg_int;            
794                 }
795                 nudgepline_y(h_textnum, h_vtx, h_amt);
796         }
797
798         if (Dc_help)    {
799                 dc_printf( "Usage: help_nudgepline [pline_number] [vertex_number] [distance]\n" );
800         }
801
802         if (Dc_status)  {
803                 showplinepos(h_textnum);
804         }
805 }
806
807
808 DCF(help_nudgerbracket_x, "Use to visually position overlay right bracket.")
809 {
810         if (Dc_command) {
811                 dc_get_arg(ARG_INT);
812                 if(Dc_arg_type & ARG_INT){
813                          h_textnum = Dc_arg_int;                
814                 }
815                 dc_get_arg(ARG_INT);
816                 if(Dc_arg_type & ARG_INT){
817                          h_amt = Dc_arg_int;            
818                 }
819                 nudgerbracket_x(h_textnum, h_amt);
820         }
821
822         if (Dc_help)    {
823                 dc_printf( "Usage: help_nudgerbracket_x [num] [amount]\n" );
824         }
825
826         if (Dc_status)  {
827                 showrbracketpos(h_textnum);
828         }
829 }
830
831 DCF(help_nudgerbracket_y, "Use to visually position overlay right bracket.")
832 {
833         if (Dc_command) {
834                 dc_get_arg(ARG_INT);
835                 if(Dc_arg_type & ARG_INT){
836                          h_textnum = Dc_arg_int;                
837                 }
838                 dc_get_arg(ARG_INT);
839                 if(Dc_arg_type & ARG_INT){
840                          h_amt = Dc_arg_int;            
841                 }
842                 nudgerbracket_y(h_textnum, h_amt);
843         }
844
845         if (Dc_help)    {
846                 dc_printf( "Usage: help_nudgerbracket_y [num] [amount]\n" );
847         }
848
849         if (Dc_status)  {
850                 showrbracketpos(h_textnum);
851         }
852 }
853
854
855
856
857 DCF(help_nudgelbracket_x, "Use to visually position overlay left bracket.")
858 {
859         if (Dc_command) {
860                 dc_get_arg(ARG_INT);
861                 if(Dc_arg_type & ARG_INT){
862                          h_textnum = Dc_arg_int;                
863                 }
864                 dc_get_arg(ARG_INT);
865                 if(Dc_arg_type & ARG_INT){
866                          h_amt = Dc_arg_int;            
867                 }
868                 nudgelbracket_x(h_textnum, h_amt);
869         }
870
871         if (Dc_help)    {
872                 dc_printf( "Usage: help_nudgelbracket_x [num] [amount]\n" );
873         }
874
875         if (Dc_status)  {
876                 showlbracketpos(h_textnum);
877         }
878 }
879
880 DCF(help_nudgelbracket_y, "Use to visually position overlay left bracket.")
881 {
882         if (Dc_command) {
883                 dc_get_arg(ARG_INT);
884                 if(Dc_arg_type & ARG_INT){
885                          h_textnum = Dc_arg_int;                
886                 }
887                 dc_get_arg(ARG_INT);
888                 if(Dc_arg_type & ARG_INT){
889                          h_amt = Dc_arg_int;            
890                 }
891                 nudgelbracket_y(h_textnum, h_amt);
892         }
893
894         if (Dc_help)    {
895                 dc_printf( "Usage: help_nudgelbracket_y [num] [amount]\n" );
896         }
897
898         if (Dc_status)  {
899                 showlbracketpos(h_textnum);
900         }
901 }