]> icculus.org git repositories - taylor/freespace2.git/blob - src/menuui/snazzyui.cpp
const-char warning fixes
[taylor/freespace2.git] / src / menuui / snazzyui.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/MenuUI/SnazzyUI.cpp $
11  * $Revision$
12  * $Date$
13  * $Author$
14  *
15  *  Code to drive the Snazzy User Interface
16  *
17  * $Log$
18  * Revision 1.4  2004/09/20 01:31:44  theoddone33
19  * GCC 3.4 fixes.
20  *
21  * Revision 1.3  2002/06/09 04:41:22  relnev
22  * added copyright header
23  *
24  * Revision 1.2  2002/05/07 03:16:46  theoddone33
25  * The Great Newline Fix
26  *
27  * Revision 1.1.1.1  2002/05/03 03:28:09  root
28  * Initial import.
29  *
30  * 
31  * 7     7/16/99 1:49p Dave
32  * 8 bit aabitmaps. yay.
33  * 
34  * 6     12/18/98 1:13a Dave
35  * Rough 1024x768 support for Direct3D. Proper detection and usage through
36  * the launcher.
37  * 
38  * 5     11/30/98 1:07p Dave
39  * 16 bit conversion, first run.
40  * 
41  * 4     10/23/98 3:51p Dave
42  * Full support for tstrings.tbl and foreign languages. All that remains
43  * is to make it active in Fred.
44  * 
45  * 3     10/13/98 9:28a Dave
46  * Started neatening up freespace.h. Many variables renamed and
47  * reorganized. Added AlphaColors.[h,cpp]
48  * 
49  * 2     10/07/98 10:53a Dave
50  * Initial checkin.
51  * 
52  * 1     10/07/98 10:49a Dave
53  * 
54  * 57    4/09/98 5:51p Lawrance
55  * Be able to disable sounds for certain menus
56  * 
57  * 56    4/08/98 10:18a John
58  * Made version and snazzy info all render as white in all screen modes.
59  * 
60  * 55    3/18/98 12:11p John
61  * redid some string externalization
62  * 
63  * 54    3/05/98 11:15p Hoffoss
64  * Changed non-game key checking to use game_check_key() instead of
65  * game_poll().
66  * 
67  * 53    2/22/98 4:17p John
68  * More string externalization classification... 190 left to go!
69  * 
70  * 52    2/03/98 11:52p Lawrance
71  * call snazzy_flush() from game_flush()
72  * 
73  * 51    1/20/98 2:23p Dave
74  * Removed optimized build warnings. 99% done with ingame join fixes.
75  * 
76  * 50    1/10/98 12:47a Lawrance
77  * rip out hud config text drawing
78  * 
79  * 49    12/23/97 5:28p Hoffoss
80  * Made enter key act the same as clicking the mouse button in main hall
81  * screen.
82  * 
83  * 48    11/19/97 8:36p Dave
84  * Removed references to MainMenu.h
85  * 
86  * 47    11/11/97 4:57p Dave
87  * Put in support for single vs. multiplayer pilots. Began work on
88  * multiplayer campaign saving. Put in initial player select screen
89  * 
90  * 46    9/07/97 10:06p Lawrance
91  * let snazzy code keep track of mouse status
92  * 
93  * 45    8/11/97 9:48p Lawrance
94  * don't poll keyboard if not requested 
95  * 
96  * 44    6/11/97 1:13p John
97  * Started fixing all the text colors in the game.
98  * 
99  * 43    6/05/97 10:19a Lawrance
100  * before playing a sound, ensure it is valid
101  * 
102  * 42    6/05/97 1:07a Lawrance
103  * changes to support sound interface
104  * 
105  * 41    4/23/97 5:19p Lawrance
106  * split up misc sounds into: gamewide, ingame, and interface
107  * 
108  * 40    4/18/97 2:54p Lawrance
109  * sounds now have a default volume, when playing, pass a scaling factor
110  * not the actual volume
111  * 
112  * 39    3/31/97 5:45p Lawrance
113  * supporting changes to allow multiple streamed audio files
114  * 
115  * 38    3/19/97 5:53p Lawrance
116  * integrating new Misc_sounds[] array (replaces old Game_sounds
117  * structure)
118  * 
119  * 37    3/01/97 2:13p Lawrance
120  * made to work with new cfile changes
121  * 
122  * 36    2/25/97 11:11a Lawrance
123  * adding more functionality needed for ship selection screen
124  * 
125  * 35    2/05/97 10:35a Lawrance
126  * supporting spooled music at menus, briefings, credits etc.
127  * 
128  * 34    1/22/97 11:01a John
129  * Added code to stream wav files in during menus.
130  * 
131  * 33    1/20/97 7:58p John
132  * Fixed some link errors with testcode.
133  * 
134  * 32    1/13/97 5:36p Lawrance
135  * integrating new Game_sounds structure for general game sounds
136  * 
137  * 31    1/07/97 6:56p Lawrance
138  * adding sound hooks
139  * 
140  * 30    12/10/96 4:18p Lawrance
141  * added snazzy_menu_close() call and integrated with existing menus
142  * 
143  * 29    12/09/96 2:53p Lawrance
144  * fixed bug where both the snazzy code and ui code were reading the
145  * keyboard, and the keypress from the snazzy code was being lost
146  * 
147  * 28    12/08/96 1:57a Lawrance
148  * integrating hud configuration
149  * 
150  * 27    11/26/96 10:13a Allender
151  * fixed code to properly get text from the region
152  * 
153  * 26    11/21/96 7:14p Lawrance
154  * converted menu code to use a file (menu.tbl) to get the data for the
155  * menu
156  * 
157  * 25    11/15/96 2:14p Lawrance
158  * improved comments, removed some unnecssary #includes and code
159  * 
160  * 24    11/15/96 12:09p John
161  * Added new UI code.  Made mouse not return Enter when you click it.
162  * Changed the doSnazzyUI function and names to be snazzy_menu_xxx.   
163  * 
164  * 23    11/13/96 4:02p Lawrance
165  * complete over-haul of the menu system and the states associated with
166  * them
167  * 
168  * 22    11/13/96 10:30a John
169  * Added code to call game_poll instead of key_inkey.
170  * 
171  * 21    11/13/96 8:32a Lawrance
172  * streamlined menu code
173  * 
174  * 20    11/12/96 12:20p John
175  * 
176  * 19    11/12/96 12:20p John
177  * added game pol
178  * 
179  * 18    11/11/96 4:03p Lawrance
180  * 
181  * 17    11/08/96 10:00a Lawrance
182  * 
183  * 16    11/06/96 8:54a Lawrance
184  * added revision templates, made more efficient
185  *
186  * $NoKeywords: $
187  *
188 */
189
190
191 #include <stdlib.h>
192
193 #include "pstypes.h"
194 #include "2d.h"
195 #include "pcxutils.h"
196 #include "key.h"
197 #include "optionsmenu.h"        // need the #defines for the menu choices
198 #include "techmenu.h"           // need the #defines for the menu choices
199 #include "trainingmenu.h"       // need the #defines for the menu choices
200 #include "font.h"
201 #include "mouse.h"
202 #include "snazzyui.h"
203 #include "cfile.h"
204 #include "hudconfig.h"
205 #include "gamesequence.h"
206 #include "hud.h"
207 #include "sound.h"
208 #include "gamesnd.h"
209 #include "freespace.h"
210 #include "alphacolors.h"
211 #include "localize.h"
212
213
214 extern int ascii_table[];
215 extern int shifted_ascii_table[];
216
217 static int Snazzy_mouse_left_was_down;
218
219 void snazzy_flush()
220 {
221         Snazzy_mouse_left_was_down = 0;
222 }
223
224 void snazzy_menu_init()
225 {
226         game_flush();
227 }
228
229 // snazzy_menu_do()
230 //
231 // This function will return an identifier that matches the region of the
232 // image the mouse pointer is currently over.  The function works by working
233 // with two images
234 //
235 // 1. An image that is displayed to the player
236 // 2. A second image, not seen, which has masks for certain areas of image 1
237 //
238 // The idea is to read the mouse, and determine if the mouse pointer is currently
239 // over one of these regions.  Since these regions may be many different colors,
240 // the mask is checked instead, since the regions are always a uniform color
241 //
242 //      The action parameter is used to return whether the region is clicked on or simply
243 // has the mouse over it.  The #defines SNAZZY_OVER and SNAZZY_CLICKED are used.
244 //
245 // The purpose of the key_in parameter is to allow the caller to determine if any
246 // keys are pressed while within the snazzy_menu_do().  It is an optional parameter.
247 // 
248
249 int snazzy_menu_do(ubyte *data, int mask_w, int mask_h, int num_regions, MENU_REGION *regions, int *action, int poll_key, int *key)
250 {
251         int i, k, x, y, offset;
252         int choice = -1, mouse_on_choice = -1;
253         ubyte pixel_value;
254
255         Assert(data != NULL);
256         Assert(num_regions > 0);
257         Assert(regions != NULL);
258         
259         gr_reset_clip();  // don't remove
260         mouse_get_pos( &x, &y );
261
262         // boundary conditions
263         if((y > mask_h - 1) || (x > mask_w - 1)){
264                 pixel_value = 0;
265         } else {
266                 // check the pixel value under the mouse
267                 offset = y * mask_w + x;
268                 pixel_value = *(data + (offset));
269         }
270
271         *action = -1;
272
273         k = 0;
274         if ( poll_key ) {
275                 k = game_check_key();
276                 if (key)
277                         *key = k;  // pass keypress back to caller
278         }
279
280 //      if (mouse_down_count(MOUSE_LEFT_BUTTON) )       {
281         if ( !mouse_down(MOUSE_LEFT_BUTTON) && Snazzy_mouse_left_was_down ) {
282                 //if (pixel_value >= 0) // always true
283                         //nprintf(("Alan", "pixel val: %d\n", pixel_value));
284                         for (i=0; i < num_regions; i++) {
285                                 if (pixel_value == regions[i].mask) {
286                                         choice = regions[i].mask;
287                                         if ( regions[i].click_sound != -1 ) {
288                                                 snd_play( &Snds_iface[regions[i].click_sound], 0.0f );
289                                         }
290                                 }
291                         }       // end for
292         }
293
294         switch ( k ) {
295                 case KEY_ESC:
296                         choice = ESC_PRESSED;
297                         break;
298
299                 default:
300                         if ( k )
301                                 for (i=0; i<num_regions; i++) {
302                                         if ( !regions[i].key )
303                                                 continue;
304                                         if (ascii_table[k] == regions[i].key || shifted_ascii_table[k] == regions[i].key) {
305                                                 choice = regions[i].mask;
306                                                 if ( regions[i].click_sound != -1 ) {
307                                                         snd_play( &Snds_iface[regions[i].click_sound], 0.0f );
308                                                 }
309                                         }
310                         }       // end for
311
312                         break;
313
314         } // end switch
315
316         i = -1;
317         //if (pixel_value >= 0) {       // always true
318                 for (i=0; i<num_regions; i++) {
319                         if (pixel_value == regions[i].mask) {
320                                 mouse_on_choice = regions[i].mask;      
321                                 break;
322                         }
323                 }       // end for
324         //}
325
326         gr_set_color_fast(&Color_white);
327         gr_set_font( FONT1 );
328
329         if ((mouse_on_choice >= 0) && (mouse_on_choice <= (num_regions)) && (i >=0)) {
330                 gr_printf( 0x8000, 450, regions[i].text );
331         }
332
333         if ( mouse_down(MOUSE_LEFT_BUTTON) ){
334                 Snazzy_mouse_left_was_down = 1;
335         } else {
336                 Snazzy_mouse_left_was_down = 0;
337         }
338         
339         if ( choice > -1 || choice == ESC_PRESSED ) {
340                 *action = SNAZZY_CLICKED;
341                 return choice;
342         }
343
344         if ( mouse_on_choice > -1 ) {
345                 *action = SNAZZY_OVER;
346                 return mouse_on_choice;
347         }
348
349         return -1;
350 }
351
352 // add_region() will set up a menu region
353 //
354 //
355 //
356
357 void snazzy_menu_add_region(MENU_REGION* region, const char* text, int mask, int key, int click_sound)
358 {
359         region->mask = mask;
360         region->key = key;
361         strcpy(region->text, text);
362         region->click_sound = click_sound;
363 }
364  
365
366
367 // read_menu_tbl() will parse through menu.tbl and store the different menu region data
368 //
369 //
370 //
371
372 void read_menu_tbl(const char* menu_name, char* bkg_filename, char* mask_filename, MENU_REGION* regions, int* num_regions, int play_sound)
373 {
374         CFILE* fp;
375         int state=0;
376         char* p1, *p2, *p3;
377         //char music_filename[128];
378
379         char seps[]   = NOX(" ,\t");
380         char *token;
381         char tmp_line[132];
382
383         *num_regions=0;
384
385         // open localization
386         lcl_ext_open();
387
388         fp = cfopen( NOX("menu.tbl"), "rt" );
389         if (fp == NULL) {
390                 Error(LOCATION, "menu.tbl could not be opened\n");
391
392                 // close localization
393                 lcl_ext_close();
394
395                 return;
396         }
397
398
399         while (cfgets(tmp_line, 132, fp)) {
400                 p1 = strchr(tmp_line,'\n'); if (p1) *p1 = '\0';
401                 p1 = strchr(tmp_line,';'); if (p1) *p1 = '\0';
402                 p1 = p3 = strchr( tmp_line, '[' );
403
404                 if (p3 && state == 1) { 
405                         // close localization
406                         lcl_ext_close();
407
408                         cfclose(fp);
409                         return;
410                 }
411                 
412                 if ( p1 || p3)  {
413                         if (!state)     {
414                                 p2 = strchr( tmp_line, ']' );
415                                 if (p2) *p2 = 0;
416                                 if (!stricmp( ++p1, menu_name )) state = 1;
417                         } else {
418                                 cfclose(fp);
419                                 break;
420                         }
421                 } else if (state) {
422                         
423                 
424                         // parse a region line
425                         p1 = strchr( tmp_line, '\"' );
426                         if (p1) {
427                                 p2 = strchr( tmp_line+1, '\"' );
428                                 if (!p2) {
429                                         nprintf(("Warning","Error parsing menu file\n"));
430
431                                         // close localization
432                                         lcl_ext_close();
433
434                                         return;
435                                 }
436                                 *p2 = 0;
437                                 strcpy(regions[*num_regions].text,++p1);
438                                 p2++;
439
440                                 // get the tokens mask number
441                                 token = strtok( p2, seps );
442                                 regions[*num_regions].mask = atoi(token);
443                                 
444                                 // get the hot key character
445                                 token = strtok( NULL, seps );
446                                 regions[*num_regions].key = token[0];
447
448                                 // stuff default click sound (not in menu.tbl)
449                                 if ( play_sound ) {
450                                         regions[*num_regions].click_sound = SND_IFACE_MOUSE_CLICK;
451                                 } else {
452                                         regions[*num_regions].click_sound = -1;
453                                 }
454
455                                 *num_regions = *num_regions + 1;
456
457                         }
458                                 else {
459                                 // get the menu filenames
460
461                                 // Establish string and get the first token
462                                 token = strtok( tmp_line, seps );
463                                 if ( token != NULL )
464                                 {
465                                         // store the background filename
466                                         strcpy(bkg_filename, token);
467
468                                         // get the mask filename
469                                         token = strtok( NULL, seps );
470                                         strcpy(mask_filename, token);
471                                 }
472                         }
473                 }
474         }       
475         cfclose(fp);
476         
477         // close localization
478         lcl_ext_close();
479 }
480
481 // snazzy_menu_close() is called when the menu using a snazzy interface is exited
482 //
483 //
484
485 void snazzy_menu_close()
486 {
487         game_flush();
488 }
489