2 * Copyright (C) Volition, Inc. 1999. All rights reserved.
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
10 * $Logfile: /Freespace2/code/MenuUI/SnazzyUI.cpp $
15 * Code to drive the Snazzy User Interface
18 * Revision 1.4 2004/09/20 01:31:44 theoddone33
21 * Revision 1.3 2002/06/09 04:41:22 relnev
22 * added copyright header
24 * Revision 1.2 2002/05/07 03:16:46 theoddone33
25 * The Great Newline Fix
27 * Revision 1.1.1.1 2002/05/03 03:28:09 root
31 * 7 7/16/99 1:49p Dave
32 * 8 bit aabitmaps. yay.
34 * 6 12/18/98 1:13a Dave
35 * Rough 1024x768 support for Direct3D. Proper detection and usage through
38 * 5 11/30/98 1:07p Dave
39 * 16 bit conversion, first run.
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.
45 * 3 10/13/98 9:28a Dave
46 * Started neatening up freespace.h. Many variables renamed and
47 * reorganized. Added AlphaColors.[h,cpp]
49 * 2 10/07/98 10:53a Dave
52 * 1 10/07/98 10:49a Dave
54 * 57 4/09/98 5:51p Lawrance
55 * Be able to disable sounds for certain menus
57 * 56 4/08/98 10:18a John
58 * Made version and snazzy info all render as white in all screen modes.
60 * 55 3/18/98 12:11p John
61 * redid some string externalization
63 * 54 3/05/98 11:15p Hoffoss
64 * Changed non-game key checking to use game_check_key() instead of
67 * 53 2/22/98 4:17p John
68 * More string externalization classification... 190 left to go!
70 * 52 2/03/98 11:52p Lawrance
71 * call snazzy_flush() from game_flush()
73 * 51 1/20/98 2:23p Dave
74 * Removed optimized build warnings. 99% done with ingame join fixes.
76 * 50 1/10/98 12:47a Lawrance
77 * rip out hud config text drawing
79 * 49 12/23/97 5:28p Hoffoss
80 * Made enter key act the same as clicking the mouse button in main hall
83 * 48 11/19/97 8:36p Dave
84 * Removed references to MainMenu.h
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
90 * 46 9/07/97 10:06p Lawrance
91 * let snazzy code keep track of mouse status
93 * 45 8/11/97 9:48p Lawrance
94 * don't poll keyboard if not requested
96 * 44 6/11/97 1:13p John
97 * Started fixing all the text colors in the game.
99 * 43 6/05/97 10:19a Lawrance
100 * before playing a sound, ensure it is valid
102 * 42 6/05/97 1:07a Lawrance
103 * changes to support sound interface
105 * 41 4/23/97 5:19p Lawrance
106 * split up misc sounds into: gamewide, ingame, and interface
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
112 * 39 3/31/97 5:45p Lawrance
113 * supporting changes to allow multiple streamed audio files
115 * 38 3/19/97 5:53p Lawrance
116 * integrating new Misc_sounds[] array (replaces old Game_sounds
119 * 37 3/01/97 2:13p Lawrance
120 * made to work with new cfile changes
122 * 36 2/25/97 11:11a Lawrance
123 * adding more functionality needed for ship selection screen
125 * 35 2/05/97 10:35a Lawrance
126 * supporting spooled music at menus, briefings, credits etc.
128 * 34 1/22/97 11:01a John
129 * Added code to stream wav files in during menus.
131 * 33 1/20/97 7:58p John
132 * Fixed some link errors with testcode.
134 * 32 1/13/97 5:36p Lawrance
135 * integrating new Game_sounds structure for general game sounds
137 * 31 1/07/97 6:56p Lawrance
140 * 30 12/10/96 4:18p Lawrance
141 * added snazzy_menu_close() call and integrated with existing menus
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
147 * 28 12/08/96 1:57a Lawrance
148 * integrating hud configuration
150 * 27 11/26/96 10:13a Allender
151 * fixed code to properly get text from the region
153 * 26 11/21/96 7:14p Lawrance
154 * converted menu code to use a file (menu.tbl) to get the data for the
157 * 25 11/15/96 2:14p Lawrance
158 * improved comments, removed some unnecssary #includes and code
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.
164 * 23 11/13/96 4:02p Lawrance
165 * complete over-haul of the menu system and the states associated with
168 * 22 11/13/96 10:30a John
169 * Added code to call game_poll instead of key_inkey.
171 * 21 11/13/96 8:32a Lawrance
172 * streamlined menu code
174 * 20 11/12/96 12:20p John
176 * 19 11/12/96 12:20p John
179 * 18 11/11/96 4:03p Lawrance
181 * 17 11/08/96 10:00a Lawrance
183 * 16 11/06/96 8:54a Lawrance
184 * added revision templates, made more efficient
196 #include "pcxutils.h"
198 #include "optionsmenu.h" // need the #defines for the menu choices
199 #include "techmenu.h" // need the #defines for the menu choices
200 #include "trainingmenu.h" // need the #defines for the menu choices
203 #include "snazzyui.h"
205 #include "hudconfig.h"
206 #include "gamesequence.h"
210 #include "freespace.h"
211 #include "alphacolors.h"
212 #include "localize.h"
215 static int Snazzy_mouse_left_was_down;
219 Snazzy_mouse_left_was_down = 0;
222 void snazzy_menu_init()
229 // This function will return an identifier that matches the region of the
230 // image the mouse pointer is currently over. The function works by working
233 // 1. An image that is displayed to the player
234 // 2. A second image, not seen, which has masks for certain areas of image 1
236 // The idea is to read the mouse, and determine if the mouse pointer is currently
237 // over one of these regions. Since these regions may be many different colors,
238 // the mask is checked instead, since the regions are always a uniform color
240 // The action parameter is used to return whether the region is clicked on or simply
241 // has the mouse over it. The #defines SNAZZY_OVER and SNAZZY_CLICKED are used.
243 // The purpose of the key_in parameter is to allow the caller to determine if any
244 // keys are pressed while within the snazzy_menu_do(). It is an optional parameter.
247 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)
249 int i, k, x, y, offset;
250 int choice = -1, mouse_on_choice = -1;
253 SDL_assert(data != NULL);
254 SDL_assert(num_regions > 0);
255 SDL_assert(regions != NULL);
257 gr_reset_clip(); // don't remove
258 mouse_get_pos( &x, &y );
260 // boundary conditions
261 if((y > mask_h - 1) || (x > mask_w - 1)){
264 // check the pixel value under the mouse
265 offset = y * mask_w + x;
266 pixel_value = *(data + (offset));
273 k = game_check_key();
275 *key = k; // pass keypress back to caller
278 // if (mouse_down_count(MOUSE_LEFT_BUTTON) ) {
279 if ( !mouse_down(MOUSE_LEFT_BUTTON) && Snazzy_mouse_left_was_down ) {
280 //if (pixel_value >= 0) // always true
281 //nprintf(("Alan", "pixel val: %d\n", pixel_value));
282 for (i=0; i < num_regions; i++) {
283 if (pixel_value == regions[i].mask) {
284 choice = regions[i].mask;
285 if ( regions[i].click_sound != -1 ) {
286 snd_play( &Snds_iface[regions[i].click_sound], 0.0f );
294 choice = ESC_PRESSED;
299 int key_text = tolower(key_get_text_input());
300 for (i=0; i<num_regions; i++) {
301 if ( !regions[i].key )
303 if ( tolower(regions[i].key) == key_text ) {
304 choice = regions[i].mask;
305 if ( regions[i].click_sound != -1 ) {
306 snd_play( &Snds_iface[regions[i].click_sound], 0.0f );
316 //if (pixel_value >= 0) { // always true
317 for (i=0; i<num_regions; i++) {
318 if (pixel_value == regions[i].mask) {
319 mouse_on_choice = regions[i].mask;
325 gr_set_color_fast(&Color_white);
326 gr_set_font( FONT1 );
328 if ((mouse_on_choice >= 0) && (mouse_on_choice <= (num_regions)) && (i >=0)) {
329 gr_printf( 0x8000, 450, regions[i].text );
332 if ( mouse_down(MOUSE_LEFT_BUTTON) ){
333 Snazzy_mouse_left_was_down = 1;
335 Snazzy_mouse_left_was_down = 0;
338 if ( choice > -1 || choice == ESC_PRESSED ) {
339 *action = SNAZZY_CLICKED;
343 if ( mouse_on_choice > -1 ) {
344 *action = SNAZZY_OVER;
345 return mouse_on_choice;
351 // add_region() will set up a menu region
356 void snazzy_menu_add_region(MENU_REGION* region, const char* text, int mask, int key, int click_sound)
360 SDL_strlcpy(region->text, text, SDL_arraysize(region->text));
361 region->click_sound = click_sound;
366 // read_menu_tbl() will parse through menu.tbl and store the different menu region data
371 void read_menu_tbl(const char* menu_name, char* bkg_filename, const int max_bkg_len, char* mask_filename, const int max_mask_len, MENU_REGION* regions, int* num_regions, int play_sound)
376 //char music_filename[128];
378 char seps[] = NOX(" ,\t");
387 fp = cfopen( NOX("menu.tbl"), "rt" );
389 Error(LOCATION, "menu.tbl could not be opened\n");
391 // close localization
398 while (cfgets(tmp_line, 132, fp)) {
399 p1 = SDL_strchr(tmp_line,'\n'); if (p1) *p1 = '\0';
400 p1 = SDL_strchr(tmp_line,';'); if (p1) *p1 = '\0';
401 p1 = p3 = SDL_strchr( tmp_line, '[' );
403 if (p3 && state == 1) {
404 // close localization
413 p2 = SDL_strchr( tmp_line, ']' );
415 if (!SDL_strcasecmp( ++p1, menu_name )) state = 1;
423 // parse a region line
424 p1 = SDL_strchr( tmp_line, '\"' );
426 p2 = SDL_strchr( tmp_line+1, '\"' );
428 nprintf(("Warning","Error parsing menu file\n"));
430 // close localization
436 SDL_strlcpy(regions[*num_regions].text, ++p1, SDL_arraysize(regions[0].text));
439 // get the tokens mask number
440 token = strtok( p2, seps );
441 regions[*num_regions].mask = atoi(token);
443 // get the hot key character
444 token = strtok( NULL, seps );
445 regions[*num_regions].key = token[0];
447 // stuff default click sound (not in menu.tbl)
449 regions[*num_regions].click_sound = SND_IFACE_MOUSE_CLICK;
451 regions[*num_regions].click_sound = -1;
454 *num_regions = *num_regions + 1;
458 // get the menu filenames
460 // Establish string and get the first token
461 token = strtok( tmp_line, seps );
464 // store the background filename
465 SDL_strlcpy(bkg_filename, token, max_bkg_len);
467 // get the mask filename
468 token = strtok( NULL, seps );
469 SDL_strlcpy(mask_filename, token, max_mask_len);
476 // close localization
480 // snazzy_menu_close() is called when the menu using a snazzy interface is exited
484 void snazzy_menu_close()