]> icculus.org git repositories - btb/d2x.git/blob - main/menu.c
Added hotkeys to toggle fullscreen mode
[btb/d2x.git] / main / menu.c
1 /*
2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
11 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
12 */
13
14 /*
15  * $Source: /cvs/cvsroot/d2x/main/menu.c,v $
16  * $Revision: 1.7 $
17  * $Author: bradleyb $
18  * $Date: 2002-02-13 10:39:21 $
19  *
20  * Inferno main menu.
21  *
22  * $Log: not supported by cvs2svn $
23  *
24  */
25
26 #ifdef HAVE_CONFIG_H
27 #include <conf.h>
28 #endif
29
30 #ifdef WINDOWS
31 #include "desw.h"
32 #endif
33
34 #include <stdio.h>
35 #include <string.h>
36
37 #include "pa_enabl.h"                   //$$POLY_ACC
38
39 #include "menu.h"
40 #include "inferno.h"
41 #include "game.h"
42 #include "gr.h"
43 #include "key.h"
44 #include "iff.h"
45 #include "u_mem.h"
46 #include "error.h"
47 #include "bm.h"
48 #include "screens.h"
49 #include "mono.h"
50 #include "joy.h"
51 #include "vecmat.h"
52 #include "effects.h"
53 #include "slew.h"
54 #include "gamemine.h"
55 #include "gamesave.h"
56 #include "palette.h"
57 #include "args.h"
58 #include "newdemo.h"
59 #include "timer.h"
60 #include "sounds.h"
61 #include "gameseq.h"
62 #include "text.h"
63 #include "gamefont.h"
64 #include "newmenu.h"
65 #ifdef NETWORK
66 #include "network.h"
67 #endif
68 #include "scores.h"
69 #include "joydefs.h"
70 #include "modem.h"
71 #include "playsave.h"
72 #include "multi.h"
73 #include "kconfig.h"
74 #include "titles.h"
75 #include "credits.h"
76 #include "texmap.h"
77 #include "polyobj.h"
78 #include "state.h"
79 #include "mission.h"
80 #include "songs.h"
81 #include "config.h"
82 #include "movie.h"
83 #include "gamepal.h"
84 #include "gauges.h"
85 #include "powerup.h"
86 #include "strutil.h"
87 #include "reorder.h"
88 #include "ipx.h"
89
90 #ifdef MACINTOSH
91         #include "resource.h"
92         #include "isp.h"
93         #include <Dialogs.h>
94 #endif
95
96 #ifdef EDITOR
97 #include "editor/editor.h"
98 #endif
99
100 #if defined(POLY_ACC)
101 #include "poly_acc.h"
102 #endif
103
104 //char *menu_difficulty_text[] = { "Trainee", "Rookie", "Fighter", "Hotshot", "Insane" };
105 //char *menu_detail_text[] = { "Lowest", "Low", "Medium", "High", "Highest", "", "Custom..." };
106
107 #define MENU_NEW_GAME            0
108 #define MENU_GAME                               1 
109 #define MENU_EDITOR                                     2
110 #define MENU_VIEW_SCORES                        3
111 #define MENU_QUIT                4
112 #define MENU_LOAD_GAME                          5
113 #define MENU_SAVE_GAME                          6
114 #define MENU_DEMO_PLAY                          8
115 #define MENU_LOAD_LEVEL                         9
116 #if 0 // original D2 definitions
117 #define MENU_START_IPX_NETGAME                  10
118 #define MENU_JOIN_IPX_NETGAME                   11
119 #else
120 #define MENU_START_NETGAME                      10
121 #define MENU_JOIN_NETGAME                       11
122 #endif
123 #define MENU_CONFIG                             13
124 #define MENU_REJOIN_NETGAME                     14
125 #define MENU_DIFFICULTY                         15
126 #define MENU_START_SERIAL                       18
127 #define MENU_HELP                               19
128 #define MENU_NEW_PLAYER                         20
129 #ifdef NETWORK
130 #define MENU_MULTIPLAYER                        21
131 #endif
132 #define MENU_STOP_MODEM                         22
133 #define MENU_SHOW_CREDITS                       23
134 #define MENU_ORDER_INFO                         24
135 #define MENU_PLAY_SONG                          25
136 #ifdef NETWORK
137 #if 0 // original D2 definitions
138 #define MENU_START_TCP_NETGAME                  26
139 #define MENU_JOIN_TCP_NETGAME                   27
140 #define MENU_START_APPLETALK_NETGAME                    28
141 #define MENU_JOIN_APPLETALK_NETGAME                             30
142 #else
143 #define MENU_IPX_MULTIPLAYER                    26
144 #define MENU_KALI_MULTIPLAYER                   27
145 #define MENU_IP_MULTIPLAYER                     28
146 #define MENU_IP_SERV_CONNECT                    29
147 #define MENU_MANUAL_IP_JOIN                     30
148 #endif
149 #endif
150
151 //ADD_ITEM("Start netgame...", MENU_START_NETGAME, -1 );
152 //ADD_ITEM("Send net message...", MENU_SEND_NET_MESSAGE, -1 );
153
154 #define ADD_ITEM(t,value,key)  do { m[num_options].type=NM_TYPE_MENU; m[num_options].text=t; menu_choice[num_options]=value;num_options++; } while (0)
155
156 //unused - extern int last_joy_time;               //last time the joystick was used
157 #ifndef NDEBUG
158 extern int Speedtest_on;
159 #else
160 #define Speedtest_on 0
161 #endif
162
163 void do_sound_menu();
164 void do_toggles_menu();
165
166 ubyte do_auto_demo = 1;                 // Flag used to enable auto demo starting in main menu.
167 int Player_default_difficulty; // Last difficulty level chosen by the player
168 int Auto_leveling_on = 1;
169 int Guided_in_big_window = 0;
170 int Menu_draw_copyright = 0;
171 int EscortHotKeys=1;
172
173 // Function Prototypes added after LINTING
174 void do_option(int select);
175 void do_detail_level_menu_custon(void);
176 void do_multi_player_menu(void);
177 void do_ipx_multi_player_menu();
178 void do_kali_multi_player_menu();
179 void do_ip_multi_player_menu();
180 void do_ip_manual_join_menu();
181 void do_ip_serv_connect_menu();
182 void do_detail_level_menu_custom(void);
183 void do_new_game_menu(void);
184
185 //returns the number of demo files on the disk
186 int newdemo_count_demos();
187 extern ubyte Version_major,Version_minor;
188
189 // ------------------------------------------------------------------------
190 void autodemo_menu_check(int nitems, newmenu_item * items, int *last_key, int citem )
191 {
192         int curtime;
193
194         nitems = nitems;
195         items=items;
196         citem = citem;
197
198         //draw copyright message
199         if ( Menu_draw_copyright )              {
200                 int w,h,aw;
201
202                 Menu_draw_copyright = 0;
203                 WINDOS( dd_gr_set_current_canvas(NULL),
204                                         gr_set_current_canvas(NULL));
205                 gr_set_curfont(GAME_FONT);
206                 gr_set_fontcolor(BM_XRGB(6,6,6),-1);
207
208                 gr_get_string_size("V2.2", &w, &h, &aw );
209         
210                 WIN(DDGRLOCK(dd_grd_curcanv));
211                         gr_printf(0x8000,grd_curcanv->cv_bitmap.bm_h-GAME_FONT->ft_h-2,TXT_COPYRIGHT);
212                         #ifdef MACINTOSH        // print out fix level as well if it exists
213                                 if (Version_fix != 0)
214                                 {
215                                         gr_get_string_size("V2.2.2", &w, &h, &aw );
216                                         gr_printf(grd_curcanv->cv_bitmap.bm_w-w-2,
217                                                           grd_curcanv->cv_bitmap.bm_h-GAME_FONT->ft_h-2,
218                                                           "V%d.%d.%d",
219                                                           Version_major,Version_minor,Version_fix);
220                                 }
221                                 else
222                                 {
223                                         gr_printf(grd_curcanv->cv_bitmap.bm_w-w-2,
224                                                           grd_curcanv->cv_bitmap.bm_h-GAME_FONT->ft_h-2,
225                                                           "V%d.%d",
226                                                           Version_major,Version_minor);
227                                 }
228                         #else
229                                 gr_printf(grd_curcanv->cv_bitmap.bm_w-w-2,grd_curcanv->cv_bitmap.bm_h-GAME_FONT->ft_h-2,"V%d.%d",Version_major,Version_minor);
230                         #endif
231
232                 #ifdef SANTA            //say this is hoard version
233                 if (HoardEquipped()) {
234                         gr_set_curfont(MEDIUM2_FONT);
235                         gr_printf(MenuHires?495:00,MenuHires?88:44,"Vertigo");
236                 }
237                 #endif
238
239                 WIN(DDGRUNLOCK(dd_grd_curcanv));
240         }
241         
242         // Don't allow them to hit ESC in the main menu.
243         if (*last_key==KEY_ESC) *last_key = 0;
244
245         if ( do_auto_demo )     {
246                 curtime = timer_get_approx_seconds();
247                 //if ( ((keyd_time_when_last_pressed+i2f(20)) < curtime) && ((last_joy_time+i2f(20)) < curtime) && (!Speedtest_on)  ) {
248                 #ifndef MACINTOSH               // for now only!!!!
249                 if ( ((keyd_time_when_last_pressed+i2f(25)) < curtime) && (!Speedtest_on)  ) {
250                 #else
251                 if ( (keyd_time_when_last_pressed+i2f(40)) < curtime ) {
252                 #endif
253                         int n_demos;
254
255                         n_demos = newdemo_count_demos();
256
257 try_again:;
258
259                         if ((d_rand() % (n_demos+1)) == 0)
260                         {
261                                 #if !defined(SHAREWARE) && !defined(NMOVIES)
262                                         #ifdef WINDOWS
263                                         mouse_set_mode(1);                              //re-enable centering mode
264                                         HideCursorW();
265                                         #endif
266                                         PlayMovie("intro.mve",0);
267                                         songs_play_song(SONG_TITLE,1);
268                                         *last_key = -3; //exit menu to force redraw even if not going to game mode. -3 tells menu system not to restore
269                                         set_screen_mode(SCREEN_MENU);
270                                         #ifdef WINDOWS
271                                         mouse_set_mode(0);                              //disenable centering mode
272                                         ShowCursorW();
273                                         #endif
274                                 #endif // end of ifndef shareware
275                         }
276                         else {
277                                 WIN(HideCursorW());
278                                 keyd_time_when_last_pressed = curtime;                  // Reset timer so that disk won't thrash if no demos.
279                                 newdemo_start_playback(NULL);           // Randomly pick a file
280                                 if (Newdemo_state == ND_STATE_PLAYBACK) {
281                                         Function_mode = FMODE_GAME;
282                                         *last_key = -3; //exit menu to get into game mode. -3 tells menu system not to restore
283                                 }
284                                 else
285                                         goto try_again; //keep trying until we get a demo that works
286                         }
287                 }
288         }
289 }
290
291 //static int First_time = 1;
292 static int main_menu_choice = 0;
293
294 //      -----------------------------------------------------------------------------
295 //      Create the main menu.
296 void create_main_menu(newmenu_item *m, int *menu_choice, int *callers_num_options)
297 {
298         int     num_options;
299
300         #ifndef DEMO_ONLY
301         num_options = 0;
302
303         set_screen_mode (SCREEN_MENU);
304
305         ADD_ITEM(TXT_NEW_GAME,MENU_NEW_GAME,KEY_N);
306
307         ADD_ITEM(TXT_LOAD_GAME,MENU_LOAD_GAME,KEY_L);
308
309 #ifdef NETWORK
310         ADD_ITEM(TXT_MULTIPLAYER_,MENU_MULTIPLAYER,-1);
311 #endif
312
313         ADD_ITEM(TXT_OPTIONS_, MENU_CONFIG, -1 );
314         ADD_ITEM(TXT_CHANGE_PILOTS,MENU_NEW_PLAYER,unused);
315         ADD_ITEM(TXT_VIEW_DEMO,MENU_DEMO_PLAY,0);
316         ADD_ITEM(TXT_VIEW_SCORES,MENU_VIEW_SCORES,KEY_V);
317         #ifdef SHAREWARE
318         ADD_ITEM(TXT_ORDERING_INFO,MENU_ORDER_INFO,-1);
319         #endif
320         ADD_ITEM(TXT_CREDITS,MENU_SHOW_CREDITS,-1);
321         #endif
322         ADD_ITEM(TXT_QUIT,MENU_QUIT,KEY_Q);
323
324         #ifndef RELEASE
325         if (!(Game_mode & GM_MULTI ))   {
326                 //m[num_options].type=NM_TYPE_TEXT;
327                 //m[num_options++].text=" Debug options:";
328
329                 ADD_ITEM("  Load level...",MENU_LOAD_LEVEL ,KEY_N);
330                 #ifdef EDITOR
331                 ADD_ITEM("  Editor", MENU_EDITOR, KEY_E);
332                 #endif
333         }
334
335         //ADD_ITEM( "  Play song", MENU_PLAY_SONG, -1 );
336         #endif
337
338         *callers_num_options = num_options;
339 }
340
341 //returns number of item chosen
342 int DoMenu() 
343 {
344         int menu_choice[25];
345         newmenu_item m[25];
346         int num_options = 0;
347
348         load_palette(MENU_PALETTE,0,1);         //get correct palette
349
350         if ( Players[Player_num].callsign[0]==0 )       {
351                 RegisterPlayer();
352                 return 0;
353         }
354         
355         if ((Game_mode & GM_SERIAL) || (Game_mode & GM_MODEM)) {
356                 do_option(MENU_START_SERIAL);
357                 return 0;
358         }
359
360         create_main_menu(m, menu_choice, &num_options);
361
362         do {
363                 keyd_time_when_last_pressed = timer_get_fixed_seconds();                // .. 20 seconds from now!
364                 if (main_menu_choice < 0 )      main_menu_choice = 0;           
365                 Menu_draw_copyright = 1;
366                 main_menu_choice = newmenu_do2( "", NULL, num_options, m, autodemo_menu_check, main_menu_choice, Menu_pcx_name);
367                 if ( main_menu_choice > -1 ) do_option(menu_choice[main_menu_choice]);
368                 create_main_menu(m, menu_choice, &num_options); //      may have to change, eg, maybe selected pilot and no save games.
369         } while( Function_mode==FMODE_MENU );
370
371 //      if (main_menu_choice != -2)
372 //              do_auto_demo = 0;               // No more auto demos
373         if ( Function_mode==FMODE_GAME )        
374                 gr_palette_fade_out( gr_palette, 32, 0 );
375
376         return main_menu_choice;
377 }
378
379 extern void show_order_form(void);      // John didn't want this in inferno.h so I just externed it.
380
381 #ifdef WINDOWS
382 #undef TXT_SELECT_DEMO
383 #define TXT_SELECT_DEMO "Select Demo\n<Ctrl-D> or Right-click\nto delete"
384 #endif
385
386 //returns flag, true means quit menu
387 void do_option ( int select) 
388 {
389         switch (select) {
390                 case MENU_NEW_GAME:
391                         do_new_game_menu();
392                         break;
393                 case MENU_GAME:
394                         break;
395                 case MENU_DEMO_PLAY:
396                         { 
397                                 char demo_file[16];
398                                 if (newmenu_get_filename( TXT_SELECT_DEMO, "demos/*.dem", demo_file, 1 ))     {
399                                         newdemo_start_playback(demo_file);
400                                 }
401                         }
402                         break;
403                 case MENU_LOAD_GAME:
404                         state_restore_all(0, 0, NULL);
405                         break;
406                 #ifdef EDITOR
407                 case MENU_EDITOR:
408                         Function_mode = FMODE_EDITOR;
409                         init_cockpit();
410                         break;
411                 #endif
412                 case MENU_VIEW_SCORES:
413                         gr_palette_fade_out( gr_palette,32,0 );
414                         scores_view(-1);
415                         break;
416                 #ifdef SHAREWARE
417                 case MENU_ORDER_INFO:
418                         show_order_form();
419                         break;
420                 #endif
421                 case MENU_QUIT:
422                         #ifdef EDITOR
423                         if (! SafetyCheck()) break;
424                         #endif
425                         gr_palette_fade_out( gr_palette,32,0);
426                         Function_mode = FMODE_EXIT;
427                         break;
428                 case MENU_NEW_PLAYER:
429                         RegisterPlayer();               //1 == allow escape out of menu
430                         break;
431
432                 case MENU_HELP:
433                         do_show_help();
434                         break;
435
436                 #ifndef RELEASE
437
438                 case MENU_PLAY_SONG:    {
439                                 int i;
440                                 char * m[MAX_NUM_SONGS];
441
442                                 for (i=0;i<Num_songs;i++) {
443                                         m[i] = Songs[i].filename;
444                                 }
445                                 i = newmenu_listbox( "Select Song", Num_songs, m, 1, NULL );
446
447                                 if ( i > -1 )   {
448                                         songs_play_song( i, 0 );
449                                 }
450                         }
451                         break;
452                 case MENU_LOAD_LEVEL: {
453                         newmenu_item m;
454                         char text[10]="";
455                         int new_level_num;
456
457                         m.type=NM_TYPE_INPUT; m.text_len = 10; m.text = text;
458
459                         newmenu_do( NULL, "Enter level to load", 1, &m, NULL );
460
461                         new_level_num = atoi(m.text);
462
463                         if (new_level_num!=0 && new_level_num>=Last_secret_level && new_level_num<=Last_level)  {
464                                 gr_palette_fade_out( gr_palette, 32, 0 );
465                                 StartNewGame(new_level_num);
466                         }
467
468                         break;
469                 }
470                 #endif
471
472
473                 case MENU_START_NETGAME: //MENU_START_IPX_NETGAME:
474 #ifdef NETWORK
475                         load_mission(0);
476                         #ifdef MACINTOSH
477                         Network_game_type = IPX_GAME;
478                         #endif
479 //                      WIN(ipx_create_read_thread());
480                         network_start_game();
481 #endif
482                         break;
483
484                 case MENU_JOIN_NETGAME: //MENU_JOIN_IPX_NETGAME:
485 #ifdef NETWORK
486                         load_mission(0);
487                         #ifdef MACINTOSH
488                         Network_game_type = IPX_GAME;
489                         #endif
490 //                      WIN(ipx_create_read_thread());
491                         network_join_game();
492 #endif
493                         break;
494
495 #ifdef NETWORK
496 #ifdef MACINTOSH
497                 case MENU_START_APPLETALK_NETGAME:
498                         load_mission(0);
499                         #ifdef MACINTOSH
500                         Network_game_type = APPLETALK_GAME;
501                         #endif
502                         network_start_game();
503                         break;
504
505                 case MENU_JOIN_APPLETALK_NETGAME:
506                         load_mission(0);
507                         #ifdef MACINTOSH
508                         Network_game_type = APPLETALK_GAME;
509                         #endif
510                         network_join_game();
511                         break;
512 #endif
513                 
514 #if 0
515                 case MENU_START_TCP_NETGAME:
516                 case MENU_JOIN_TCP_NETGAME:
517                         nm_messagebox (TXT_SORRY,1,TXT_OK,"Not available in shareware version!");
518                         // DoNewIPAddress();
519                         break;
520 #endif
521                   
522                 case MENU_IPX_MULTIPLAYER:
523                         do_ipx_multi_player_menu();
524                         break;
525                 case MENU_KALI_MULTIPLAYER:
526                         do_kali_multi_player_menu();
527                         break;
528 #if 1 //def SUPPORTS_NET_IP
529                 case MENU_IP_MULTIPLAYER:
530                         do_ip_multi_player_menu();
531                         break;
532                 case MENU_IP_SERV_CONNECT:
533                         do_ip_serv_connect_menu();
534                         break;
535                 case MENU_MANUAL_IP_JOIN:
536                         do_ip_manual_join_menu();
537                         break;
538 #endif
539
540                 case MENU_START_SERIAL:
541                         com_main_menu();
542                         break;
543                 case MENU_MULTIPLAYER:
544                         do_multi_player_menu();
545                         break;
546 #endif //NETWORK
547                 case MENU_CONFIG:
548                         do_options_menu();
549                         break;
550                 case MENU_SHOW_CREDITS:
551                         gr_palette_fade_out( gr_palette,32,0);
552                         songs_stop_all();
553                         credits_show(NULL); 
554                         break;
555                 default:
556                         Error("Unknown option %d in do_option",select);
557                         break;
558         }
559
560 }
561
562 int do_difficulty_menu()
563 {
564         int s;
565         newmenu_item m[5];
566
567         m[0].type=NM_TYPE_MENU; m[0].text=MENU_DIFFICULTY_TEXT(0);
568         m[1].type=NM_TYPE_MENU; m[1].text=MENU_DIFFICULTY_TEXT(1);
569         m[2].type=NM_TYPE_MENU; m[2].text=MENU_DIFFICULTY_TEXT(2);
570         m[3].type=NM_TYPE_MENU; m[3].text=MENU_DIFFICULTY_TEXT(3);
571         m[4].type=NM_TYPE_MENU; m[4].text=MENU_DIFFICULTY_TEXT(4);
572
573         s = newmenu_do1( NULL, TXT_DIFFICULTY_LEVEL, NDL, m, NULL, Difficulty_level);
574
575         if (s > -1 )    {
576                 if (s != Difficulty_level)
577                 {       
578                         Player_default_difficulty = s;
579                         write_player_file();
580                 }
581                 Difficulty_level = s;
582                 mprintf((0, "%s %s %i\n", TXT_DIFFICULTY_LEVEL, TXT_SET_TO, Difficulty_level));
583                 return 1;
584         }
585         return 0;
586 }
587
588 int     Max_debris_objects, Max_objects_onscreen_detailed;
589 int     Max_linear_depth_objects;
590
591 byte    Object_complexity=2, Object_detail=2;
592 byte    Wall_detail=2, Wall_render_depth=2, Debris_amount=2, SoundChannels = 2;
593
594 byte    Render_depths[NUM_DETAIL_LEVELS-1] =                        { 6,  9, 12, 15, 50};
595 byte    Max_perspective_depths[NUM_DETAIL_LEVELS-1] =               { 1,  2,  3,  5,  8};
596 byte    Max_linear_depths[NUM_DETAIL_LEVELS-1] =                    { 3,  5,  7, 10, 50};
597 byte    Max_linear_depths_objects[NUM_DETAIL_LEVELS-1] =            { 1,  2,  3,  7, 20};
598 byte    Max_debris_objects_list[NUM_DETAIL_LEVELS-1] =              { 2,  4,  7, 10, 15};
599 byte    Max_objects_onscreen_detailed_list[NUM_DETAIL_LEVELS-1] =   { 2,  4,  7, 10, 15};
600 byte    Smts_list[NUM_DETAIL_LEVELS-1] =                            { 2,  4,  8, 16, 50};   //      threshold for models to go to lower detail model, gets multiplied by obj->size
601 byte    Max_sound_channels[NUM_DETAIL_LEVELS-1] =                   { 2,  4,  8, 12, 16};
602
603 //      -----------------------------------------------------------------------------
604 //      Set detail level based stuff.
605 //      Note: Highest detail level (detail_level == NUM_DETAIL_LEVELS-1) is custom detail level.
606 void set_detail_level_parameters(int detail_level)
607 {
608         Assert((detail_level >= 0) && (detail_level < NUM_DETAIL_LEVELS));
609
610         if (detail_level < NUM_DETAIL_LEVELS-1) {
611                 Render_depth = Render_depths[detail_level];
612                 Max_perspective_depth = Max_perspective_depths[detail_level];
613                 Max_linear_depth = Max_linear_depths[detail_level];
614                 Max_linear_depth_objects = Max_linear_depths_objects[detail_level];
615
616                 Max_debris_objects = Max_debris_objects_list[detail_level];
617                 Max_objects_onscreen_detailed = Max_objects_onscreen_detailed_list[detail_level];
618
619                 Simple_model_threshhold_scale = Smts_list[detail_level];
620
621                 digi_set_max_channels( Max_sound_channels[ detail_level ] );
622
623                 //      Set custom menu defaults.
624                 Object_complexity = detail_level;
625                 Wall_render_depth = detail_level;
626                 Object_detail = detail_level;
627                 Wall_detail = detail_level;
628                 Debris_amount = detail_level;
629                 SoundChannels = detail_level;
630
631 #if defined(POLY_ACC)
632
633                 #ifdef MACINTOSH
634                         if (detail_level < 2)
635                         {
636                                 pa_set_filtering(0);
637                         }
638                         else if (detail_level < 4)
639                         {
640                                 pa_set_filtering(1);
641                         }
642                         else if (detail_level == 4)
643                         {
644                                 pa_set_filtering(2);
645                         }
646                 #else
647                         pa_filter_mode = detail_level;
648                 #endif
649 #endif
650
651         }
652 }
653
654 //      -----------------------------------------------------------------------------
655 void do_detail_level_menu(void)
656 {
657         int s;
658         newmenu_item m[7];
659
660         m[0].type=NM_TYPE_MENU; m[0].text=MENU_DETAIL_TEXT(0);
661         m[1].type=NM_TYPE_MENU; m[1].text=MENU_DETAIL_TEXT(1);
662         m[2].type=NM_TYPE_MENU; m[2].text=MENU_DETAIL_TEXT(2);
663         m[3].type=NM_TYPE_MENU; m[3].text=MENU_DETAIL_TEXT(3);
664         m[4].type=NM_TYPE_MENU; m[4].text=MENU_DETAIL_TEXT(4);
665         m[5].type=NM_TYPE_TEXT; m[5].text="";
666         m[6].type=NM_TYPE_MENU; m[6].text=MENU_DETAIL_TEXT(5);
667
668         s = newmenu_do1( NULL, TXT_DETAIL_LEVEL , NDL+2, m, NULL, Detail_level);
669
670         if (s > -1 )    {
671                 switch (s)      {
672                         case 0:
673                         case 1:
674                         case 2:
675                         case 3:
676                         case 4:
677                                 Detail_level = s;
678                                 mprintf((0, "Detail level set to %i\n", Detail_level));
679                                 set_detail_level_parameters(Detail_level);
680                                 break;
681                         case 6:
682                                 Detail_level = 5;
683                                 do_detail_level_menu_custom();
684                                 break;
685                 }
686         }
687
688 }
689
690 //      -----------------------------------------------------------------------------
691 void do_detail_level_menu_custom_menuset(int nitems, newmenu_item * items, int *last_key, int citem )
692 {
693         nitems = nitems;
694         *last_key = *last_key;
695         citem = citem;
696
697         Object_complexity = items[0].value;
698         Object_detail = items[1].value;
699         Wall_detail = items[2].value;
700         Wall_render_depth = items[3].value;
701         Debris_amount = items[4].value;
702         SoundChannels = items[5].value;
703 #if defined(POLY_ACC)
704         pa_filter_mode = items[6].value;
705 #endif
706
707 }
708
709 void set_custom_detail_vars(void)
710 {
711         Render_depth = Render_depths[Wall_render_depth];
712
713         Max_perspective_depth = Max_perspective_depths[Wall_detail];
714         Max_linear_depth = Max_linear_depths[Wall_detail];
715
716         Max_debris_objects = Max_debris_objects_list[Debris_amount];
717
718         Max_objects_onscreen_detailed = Max_objects_onscreen_detailed_list[Object_complexity];
719         Simple_model_threshhold_scale = Smts_list[Object_complexity];
720         Max_linear_depth_objects = Max_linear_depths_objects[Object_detail];
721
722         digi_set_max_channels( Max_sound_channels[ SoundChannels ] );
723         
724 }
725
726 #define DL_MAX  10
727
728 //      -----------------------------------------------------------------------------
729
730 void do_detail_level_menu_custom(void)
731 {
732         int     count;
733         int     s=0;
734         newmenu_item m[DL_MAX];
735         #if defined(POLY_ACC)
736         int filtering_id;
737         #endif
738
739         do {
740                 count = 0;
741                 m[count].type = NM_TYPE_SLIDER;
742                 m[count].text = TXT_OBJ_COMPLEXITY;
743                 m[count].value = Object_complexity;
744                 m[count].min_value = 0;
745                 m[count++].max_value = NDL-1;
746
747                 m[count].type = NM_TYPE_SLIDER;
748                 m[count].text = TXT_OBJ_DETAIL;
749                 m[count].value = Object_detail;
750                 m[count].min_value = 0;
751                 m[count++].max_value = NDL-1;
752
753                 m[count].type = NM_TYPE_SLIDER;
754                 m[count].text = TXT_WALL_DETAIL;
755                 m[count].value = Wall_detail;
756                 m[count].min_value = 0;
757                 m[count++].max_value = NDL-1;
758
759                 m[count].type = NM_TYPE_SLIDER;
760                 m[count].text = TXT_WALL_RENDER_DEPTH;
761                 m[count].value = Wall_render_depth;
762                 m[count].min_value = 0;
763                 m[count++].max_value = NDL-1;
764
765                 m[count].type = NM_TYPE_SLIDER;
766                 m[count].text= TXT_DEBRIS_AMOUNT;
767                 m[count].value = Debris_amount;
768                 m[count].min_value = 0;
769                 m[count++].max_value = NDL-1;
770
771                 m[count].type = NM_TYPE_SLIDER;
772                 m[count].text= TXT_SOUND_CHANNELS;
773                 m[count].value = SoundChannels;
774                 m[count].min_value = 0;
775                 m[count++].max_value = NDL-1;
776
777                 #if defined(POLY_ACC)
778                 MAC( if(PAEnabled){ )
779                         filtering_id = count;
780                         m[count].type = NM_TYPE_SLIDER;
781                         m[count].text= "FILTERING";
782                         m[count].value = pa_filter_mode;
783                         m[count].min_value = 0;
784                         #ifdef MACINTOSH
785                         m[count++].max_value = 2;
786                         #else
787                         m[count++].max_value = NDL-1;
788                         #endif
789                 MAC(})
790                 #endif
791
792                 m[count].type = NM_TYPE_TEXT;
793                 m[count++].text= TXT_LO_HI;
794
795                 Assert(count < DL_MAX);
796
797                 s = newmenu_do1( NULL, TXT_DETAIL_CUSTOM, count, m, do_detail_level_menu_custom_menuset, s);
798         } while (s > -1);
799
800         set_custom_detail_vars();
801
802         #if defined(MACINTOSH) && defined(POLY_ACC)
803         if ( PAEnabled )
804                 pa_set_filtering( m[filtering_id].value );
805         #endif
806 }
807
808 #ifndef MACINTOSH
809 int Default_display_mode=0;
810 int Current_display_mode=0;
811 #else
812 int Default_display_mode=1;
813 int Current_display_mode=1;
814 #endif
815
816 extern int MenuHiresAvailable;
817
818 typedef struct {
819         int     VGA_mode;
820         short   w,h;
821         short   render_method;
822         short   flags;
823 } dmi;
824
825 dmi display_mode_info[7] = {
826                 #ifdef WINDOWS
827                         {SM95_320x200x8X, 320, 200, VR_NONE, VRF_ALLOW_COCKPIT},
828                         {SM95_640x480x8, 640, 480, VR_NONE, VRF_COMPATIBLE_MENUS+VRF_ALLOW_COCKPIT},
829                         {SM95_640x400x8, 640, 400, VR_NONE, VRF_COMPATIBLE_MENUS }, 
830                         {SM95_800x600x8, 800, 600, VR_NONE, VRF_COMPATIBLE_MENUS },
831                         {SM95_1024x768x8, 1024, 768, VR_NONE, VRF_COMPATIBLE_MENUS }, 
832                 #else
833                         {SM(320,200),    320,   200, VR_NONE, VRF_ALLOW_COCKPIT+VRF_COMPATIBLE_MENUS}, 
834                         {SM(640,480),    640, 480, VR_NONE, VRF_COMPATIBLE_MENUS+VRF_ALLOW_COCKPIT},
835                         {SM(320,400),    320, 400, VR_NONE, VRF_USE_PAGING},
836                         {SM(640,400),    640, 400, VR_NONE, VRF_COMPATIBLE_MENUS}, 
837                         {SM(800,600),    800, 600, VR_NONE, VRF_COMPATIBLE_MENUS}, 
838                         {SM(1024,768),  1024,   768, VR_NONE, VRF_COMPATIBLE_MENUS},    
839                         {SM(1280,1024),1280,1024, VR_NONE, VRF_COMPATIBLE_MENUS}, 
840                 #endif
841 };
842  
843 WIN(extern int DD_Emulation);
844
845
846 void set_display_mode(int mode)
847 {
848         dmi *dmi;
849
850         if ((Current_display_mode == -1)||(VR_render_mode != VR_NONE))  //special VR mode
851                 return;                                                         //...don't change
852
853         #if !defined(MACINTOSH) && !defined(WINDOWS)
854         if (mode >= 5 && !FindArg("-superhires"))
855                 mode = 4;
856         #endif
857
858         if (!MenuHiresAvailable && (mode != 2))
859                 mode = 0;
860
861 #ifndef WINDOWS
862
863         if (gr_check_mode(display_mode_info[mode].VGA_mode) != 0)               //can't do mode
864                 #ifndef MACINTOSH
865                 mode = 0;
866                 #else
867                 mode = 1;
868                 #endif
869
870         Current_display_mode = mode;
871 #else
872         if (mode == 2) mode = 3;                                        // 320x400 -> 640x400.
873         Current_display_mode = mode;
874         if (mode >= 3) mode--;                                          // Match to Windows dmi.
875         if (DDCheckMode(display_mode_info[mode].VGA_mode)) {
876                 if (Platform_system == WINNT_PLATFORM || DD_Emulation) mode = 1;
877                 else mode = 0;
878                 Current_display_mode = mode;
879         }
880 #endif
881
882         dmi = &display_mode_info[mode];
883
884         if (Current_display_mode != -1) {
885
886                 game_init_render_buffers(dmi->VGA_mode,dmi->w,dmi->h,dmi->render_method,dmi->flags);
887                 Default_display_mode = Current_display_mode;
888         }
889
890         Screen_mode = -1;               //force screen reset
891 }
892
893 #ifdef MACINTOSH        // use Mac version of do_screen_res_menu
894
895 void do_screen_res_menu()
896 {
897         #define N_SCREENRES_ITEMS 6
898         
899         newmenu_item m[N_SCREENRES_ITEMS];
900         int citem, i, n_items, odisplay_mode, result;
901
902         if ((Current_display_mode == -1)||(VR_render_mode != VR_NONE))          //special VR mode
903         {                               
904                 nm_messagebox(TXT_SORRY, 1, TXT_OK, 
905                                 "You may not change screen\n"
906                                 "resolution when VR modes enabled.");
907                 return;
908         }
909
910         m[0].type=NM_TYPE_TEXT;  m[0].value=0; m[0].text="Modes w/ Cockpit:";
911         m[1].type=NM_TYPE_RADIO; m[1].value=0; m[1].group=0; m[1].text=" 640x480";
912         m[2].type=NM_TYPE_TEXT;  m[2].value=0; m[2].text="Modes w/o Cockpit:";
913         m[3].type=NM_TYPE_RADIO; m[3].value=0; m[3].group=0; m[3].text=" 800x600";
914 //      m[4].type=NM_TYPE_RADIO; m[4].value=0; m[4].group=0; m[4].text=" 1024x768";
915 //      m[5].type=NM_TYPE_RADIO; m[5].value=0; m[5].group=0; m[5].text=" 1280x1024";
916         n_items = 4;
917
918         odisplay_mode = VGA_current_mode;
919         citem = Current_display_mode;
920         if (Current_display_mode >= 2)
921                 citem--;
922
923         if (citem >= n_items)
924                 citem = n_items-1;
925
926         m[citem].value = 1;
927
928         newmenu_do1( NULL, "Select screen mode", n_items, m, NULL, citem);
929
930         for (i=0;i<n_items;i++)
931                 if (m[i].value)
932                         break;
933         if (i >= 3)
934                 i++;
935
936 #ifdef SHAREWARE
937         if (i > 1)
938                 nm_messagebox(TXT_SORRY, 1, TXT_OK, 
939                         "High resolution modes are\n"
940                         "only available in the\n"
941                         "Commercial version of Descent 2.");
942         return;
943 #else
944         result = vga_check_mode(display_mode_info[i].VGA_mode);
945         
946         if (result) {
947                 nm_messagebox(TXT_SORRY, 1, TXT_OK, 
948                                 "Cannot set requested\n"
949                                 "mode on this video card.");
950                 return;
951         }
952         
953         set_display_mode(i);
954         reset_cockpit();
955 #endif
956
957 }
958
959 #else   // PC version of do_screen_res_menu is below
960
961 void do_screen_res_menu()
962 {
963 #ifdef GR_SUPPORTS_FULLSCREEN_TOGGLE
964 #define N_SCREENRES_ITEMS 10
965         int fullscreenc;
966 #else
967         #define N_SCREENRES_ITEMS 9
968 #endif
969         newmenu_item m[N_SCREENRES_ITEMS];
970         int citem;
971         int i;
972         int n_items;
973
974         if ((Current_display_mode == -1)||(VR_render_mode != VR_NONE)) {                                //special VR mode
975                 nm_messagebox(TXT_SORRY, 1, TXT_OK, 
976                                 "You may not change screen\n"
977                                 "resolution when VR modes enabled.");
978                 return;
979         }
980
981         m[0].type=NM_TYPE_TEXT;  m[0].value=0;                            m[0].text="Modes w/ Cockpit:";
982         
983 #ifdef WINDOWS
984         if (Platform_system == WINNT_PLATFORM || DD_Emulation) {
985                 m[1].type=NM_TYPE_TEXT; m[1].value=0; m[1].text=" 320x200 N/A";
986         } else
987 #endif
988                 //NOTE LINK TO ABOVE IF
989                 m[1].type=NM_TYPE_RADIO; m[1].value=0; m[1].group=0; m[1].text=" 320x200";
990
991         m[2].type=NM_TYPE_RADIO; m[2].value=0; m[2].group=0; m[2].text=" 640x480";
992         m[3].type=NM_TYPE_TEXT;  m[3].value=0;                                    m[3].text="Modes w/o Cockpit:";
993 #ifdef WINDOWS
994         m[4].type=NM_TYPE_RADIO; m[4].value=0; m[4].group=0; m[4].text=" 640x400";
995         m[5].type=NM_TYPE_RADIO; m[5].value=0; m[5].group=0; m[5].text=" 800x600";
996 //      m[6].type=NM_TYPE_RADIO; m[6].value=0; m[6].group=0; m[6].text=" 1024x768";
997         n_items = 6;
998 #else
999         m[4].type=NM_TYPE_RADIO; m[4].value=0; m[4].group=0; m[4].text=" 320x400";
1000         m[5].type=NM_TYPE_RADIO; m[5].value=0; m[5].group=0; m[5].text=" 640x400";
1001         m[6].type=NM_TYPE_RADIO; m[6].value=0; m[6].group=0; m[6].text=" 800x600";
1002         n_items = 7;
1003         if (FindArg("-superhires")) {
1004                 m[7].type=NM_TYPE_RADIO; m[7].value=0; m[7].group=0; m[7].text=" 1024x768";
1005                 m[8].type=NM_TYPE_RADIO; m[8].value=0; m[8].group=0; m[8].text=" 1280x1024";
1006                 n_items += 2;
1007         }
1008 #endif
1009
1010 #ifdef GR_SUPPORTS_FULLSCREEN_TOGGLE
1011         m[n_items].type = NM_TYPE_CHECK; m[n_items].text = "Fullscreen";
1012         m[n_items].value = gr_check_fullscreen();
1013         fullscreenc=n_items++;
1014 #endif
1015
1016         citem = Current_display_mode+1;
1017         
1018 #ifdef WINDOWS
1019         if (citem == 3) citem++;                                // if 320x400 in DOS, make it look like 640x400
1020 #else
1021         if (Current_display_mode >= 2)
1022                 citem++;
1023 #endif
1024
1025         if (citem >= n_items)
1026                 citem = n_items-1;
1027
1028         m[citem].value = 1;
1029
1030         newmenu_do1( NULL, "Select screen mode", n_items, m, NULL, citem);
1031
1032 #ifdef GR_SUPPORTS_FULLSCREEN_TOGGLE
1033         if (m[fullscreenc].value != gr_check_fullscreen()){
1034             gr_toggle_fullscreen();
1035         }
1036 #endif
1037
1038         for (i=0;i<n_items;i++)
1039                 if (m[i].value)
1040                         break;
1041
1042 #ifndef WINDOWS                                                                 // if i >= 4 keep it that way since we skip 320x400
1043         if (i >= 4)
1044                 i--;
1045 #endif
1046
1047         i--;
1048
1049 #ifndef WINDOWS
1050         if (((i != 0) && (i != 2) && !MenuHiresAvailable) || gr_check_mode(display_mode_info[i].VGA_mode)) {
1051                 nm_messagebox(TXT_SORRY, 1, TXT_OK, 
1052                                 "Cannot set requested\n"
1053                                 "mode on this video card.");
1054                 return;
1055         }
1056 #else
1057         if (i >= 3) 
1058                 result = DDCheckMode(display_mode_info[i-1].VGA_mode);
1059         else 
1060                 result = DDCheckMode(display_mode_info[i].VGA_mode);
1061
1062         if (result) {
1063                 nm_messagebox(TXT_SORRY, 1, TXT_OK, 
1064                                 "Mode not supported by your\n"
1065                                 "DirectDraw driver.\n", 
1066                                 "Using default mode for gameplay.\n");
1067                 return;
1068         }
1069
1070 #endif
1071         #ifdef SHAREWARE
1072                 if (i != 0)
1073                         nm_messagebox(TXT_SORRY, 1, TXT_OK, 
1074                                 "High resolution modes are\n"
1075                                 "only available in the\n"
1076                                 "Commercial version of Descent 2.");
1077                 return;
1078         #else
1079                 if (i != Current_display_mode)
1080                         set_display_mode(i);
1081         #endif
1082
1083 }
1084 #endif  // end of PC version of do_screen_res_menu()
1085
1086
1087
1088 void do_new_game_menu()
1089 {
1090         int new_level_num,player_highest_level;
1091
1092 #ifndef SHAREWARE
1093         int n_missions;
1094
1095         n_missions = build_mission_list(0);
1096
1097         if (n_missions > 1) {
1098                 int new_mission_num,i, default_mission;
1099                 char * m[MAX_MISSIONS];
1100
1101                 default_mission = 0;
1102                 for (i=0;i<n_missions;i++) {
1103                         m[i] = Mission_list[i].mission_name;
1104                         if ( !stricmp( m[i], config_last_mission ) )    
1105                                 default_mission = i;
1106                 }
1107
1108                 new_mission_num = newmenu_listbox1( "New Game\n\nSelect mission", n_missions, m, 1, default_mission, NULL );
1109
1110                 if (new_mission_num == -1)
1111                         return;         //abort!
1112
1113                 strcpy(config_last_mission, m[new_mission_num]  );
1114                 
1115                 if (!load_mission(new_mission_num)) {
1116                         nm_messagebox( NULL, 1, TXT_OK, "Error in Mission file"); 
1117                         return;
1118                 }
1119         }
1120 #endif
1121
1122         new_level_num = 1;
1123
1124         player_highest_level = get_highest_level();
1125
1126         if (player_highest_level > Last_level)
1127                 player_highest_level = Last_level;
1128
1129         if (player_highest_level > 1) {
1130                 newmenu_item m[4];
1131                 char info_text[80];
1132                 char num_text[10];
1133                 int choice;
1134                 int n_items;
1135
1136 try_again:
1137                 sprintf(info_text,"%s %d",TXT_START_ANY_LEVEL, player_highest_level);
1138
1139                 m[0].type=NM_TYPE_TEXT; m[0].text = info_text;
1140                 m[1].type=NM_TYPE_INPUT; m[1].text_len = 10; m[1].text = num_text;
1141                 n_items = 2;
1142
1143                 #ifdef WINDOWS
1144                 m[2].type = NM_TYPE_TEXT; m[2].text = "";
1145                 m[3].type = NM_TYPE_MENU; m[3].text = "          Ok";
1146                 n_items = 4;
1147                 #endif
1148
1149                 strcpy(num_text,"1");
1150
1151                 choice = newmenu_do( NULL, TXT_SELECT_START_LEV, n_items, m, NULL );
1152
1153                 if (choice==-1 || m[1].text[0]==0)
1154                         return;
1155
1156                 new_level_num = atoi(m[1].text);
1157
1158                 if (!(new_level_num>0 && new_level_num<=player_highest_level)) {
1159                         m[0].text = TXT_ENTER_TO_CONT;
1160                         nm_messagebox( NULL, 1, TXT_OK, TXT_INVALID_LEVEL); 
1161                         goto try_again;
1162                 }
1163         }
1164
1165         Difficulty_level = Player_default_difficulty;
1166
1167         if (!do_difficulty_menu())
1168                 return;
1169
1170         gr_palette_fade_out( gr_palette, 32, 0 );
1171         StartNewGame(new_level_num);
1172
1173 }
1174
1175 extern void GameLoop(int, int );
1176
1177 extern int Redbook_enabled;
1178
1179 void options_menuset(int nitems, newmenu_item * items, int *last_key, int citem )
1180 {
1181         if ( citem==5)
1182         {
1183                 gr_palette_set_gamma(items[5].value);
1184         }
1185
1186         nitems++;               //kill warning
1187         last_key++;             //kill warning
1188 }
1189
1190 void do_options_menu()
1191 {
1192    newmenu_item m[12];
1193         int i = 0;
1194
1195         do {
1196                 m[ 0].type = NM_TYPE_MENU;   m[ 0].text="Sound effects & music...";
1197                 m[ 1].type = NM_TYPE_TEXT;   m[ 1].text="";
1198                 #if defined(MACINTOSH) && defined(APPLE_DEMO)
1199                 m [2].type = NM_TYPE_TEXT;   m[ 2].text="";
1200                 #else
1201                 m[ 2].type = NM_TYPE_MENU;   m[ 2].text=TXT_CONTROLS_;
1202                 #endif
1203         #ifdef WINDOWS
1204                 m[ 3].type = NM_TYPE_MENU;   m[ 3].text="INVOKE JOYSTICK CONTROL PANEL";
1205         #else
1206                 m[ 3].type = NM_TYPE_MENU;   m[ 3].text=TXT_CAL_JOYSTICK;
1207         #endif
1208                 m[ 4].type = NM_TYPE_TEXT;   m[ 4].text="";
1209
1210 #if defined(POLY_ACC)
1211         #ifdef MACINTOSH
1212
1213                 if ( !PAEnabled )
1214                 {
1215                         m[5].type               = NM_TYPE_SLIDER;
1216                         m[5].text               = TXT_BRIGHTNESS;
1217                         m[5].value              = gr_palette_get_gamma();
1218                         m[5].min_value  = 0;
1219                         m[5].max_value  = 8; 
1220                 }
1221                 else
1222                 {
1223                         m[ 5].type = NM_TYPE_TEXT;   m[ 5].text="";
1224                 }
1225         
1226         #else
1227                 m[ 5].type = NM_TYPE_TEXT;   m[ 5].text="";
1228         #endif
1229 #else
1230                 m[ 5].type = NM_TYPE_SLIDER; m[ 5].text=TXT_BRIGHTNESS; m[5].value=gr_palette_get_gamma();m[5].min_value=0; m[5].max_value=8; 
1231 #endif
1232
1233
1234 #ifdef PA_3DFX_VOODOO
1235                 m[ 6].type = NM_TYPE_TEXT;   m[ 6].text="";
1236 #else
1237                 m[ 6].type = NM_TYPE_MENU;   m[ 6].text=TXT_DETAIL_LEVELS;
1238 #endif
1239
1240 #if defined(POLY_ACC)
1241                 m[ 7].type = NM_TYPE_TEXT;   m[ 7].text="";
1242 #else
1243                 #ifdef MACINTOSH
1244                         if ( gConfigInfo.mChangeResolution && !PAEnabled )
1245                         {
1246                                 m[ 7].type = NM_TYPE_MENU;   m[ 7].text="Screen resolution...";
1247                         }
1248                         else    // for when we are on a mac and no resolution switching allowed
1249                         {
1250                                 m[ 7].type = NM_TYPE_TEXT;   m[ 7].text="";
1251                         }
1252                 #else   // for PC's
1253                         m[ 7].type = NM_TYPE_MENU;   m[ 7].text="Screen resolution...";
1254                 #endif  // end of #ifdef macintosh
1255
1256 #endif
1257
1258                 m[ 8].type = NM_TYPE_TEXT;   m[ 8].text="";
1259                 m[ 9].type = NM_TYPE_MENU;   m[ 9].text="Primary autoselect ordering...";
1260                 m[10].type = NM_TYPE_MENU;   m[10].text="Secondary autoselect ordering...";
1261                 m[11].type = NM_TYPE_MENU;   m[11].text="Toggles...";
1262                                 
1263                 i = newmenu_do1( NULL, TXT_OPTIONS, sizeof(m)/sizeof(*m), m, options_menuset, i );
1264                         
1265                 switch(i)       {
1266                         case  0: do_sound_menu();                       break;
1267                         case  2: joydefs_config();                      break;
1268                         case  3: joydefs_calibrate();           break;
1269                         case  6: do_detail_level_menu();        break;
1270                         case  7: do_screen_res_menu();          break;
1271                         case  9: ReorderPrimary();                      break;
1272                         case 10: ReorderSecondary();            break;
1273                         case 11: do_toggles_menu();                     break;
1274                 }
1275
1276         } while( i>-1 );
1277
1278         write_player_file();
1279 }
1280
1281 extern int Redbook_playing;
1282 void set_redbook_volume(int volume);
1283
1284 WIN(extern int RBCDROM_State);
1285 WIN(static BOOL windigi_driver_off=FALSE);
1286
1287 void sound_menuset(int nitems, newmenu_item * items, int *last_key, int citem )
1288 {
1289         nitems=nitems;          
1290         *last_key = *last_key;
1291
1292         if ( Config_digi_volume != items[0].value )     {
1293                 Config_digi_volume = items[0].value;
1294
1295                 #ifdef WINDOWS
1296                         if (windigi_driver_off) {
1297                                 digi_midi_wait();
1298                                 digi_init_digi();
1299                                 Sleep(500);
1300                                 windigi_driver_off = FALSE;
1301                         }
1302                 #endif                  
1303                 
1304                 #ifndef MACINTOSH
1305                         digi_set_digi_volume( (Config_digi_volume*32768)/8 );
1306                 #else
1307                         digi_set_digi_volume( (Config_digi_volume*256)/8 );
1308                 #endif
1309                 digi_play_sample_once( SOUND_DROP_BOMB, F1_0 );
1310         }
1311
1312 #ifdef WINDOWS
1313         if (!wmidi_support_volchange()) {
1314                 if (!items[1].value && Config_midi_volume) {
1315                         Config_midi_volume = 0;
1316                         digi_set_midi_volume(0);
1317                         digi_play_midi_song( NULL, NULL, NULL, 0 );
1318                 }
1319                 else if (Config_midi_volume == 0 && items[1].value) {
1320                         digi_set_midi_volume(64);
1321                         Config_midi_volume = 4;
1322                 }
1323         }
1324         else     // LINK TO BELOW IF
1325 #endif
1326         if (Config_midi_volume != items[1].value )   {
1327                 Config_midi_volume = items[1].value;
1328                 #ifdef WINDOWS
1329                         if (!windigi_driver_off) {
1330                                 Sleep(200);
1331                                 digi_close_digi();
1332                                 Sleep(100);
1333                                 windigi_driver_off = TRUE;
1334                         }
1335                 #endif
1336                 #ifndef MACINTOSH
1337                         digi_set_midi_volume( (Config_midi_volume*128)/8 );
1338                 #else
1339                         digi_set_midi_volume( (Config_midi_volume*256)/8 );
1340                 #endif
1341         }
1342 #ifdef MACINTOSH
1343         if (Config_master_volume != items[3].value ) {
1344                 Config_master_volume = items[3].value;
1345                 digi_set_master_volume( Config_master_volume );
1346                 digi_play_sample_once( SOUND_DROP_BOMB, F1_0 );
1347         }
1348 #endif
1349
1350         // don't enable redbook for a non-apple demo version of the shareware demo
1351         #if !defined(SHAREWARE) || ( defined(SHAREWARE) && defined(APPLE_DEMO) )
1352                 
1353         if (Config_redbook_volume != items[2].value )   {
1354                 Config_redbook_volume = items[2].value;
1355                 set_redbook_volume(Config_redbook_volume);
1356         }
1357
1358         if (items[4].value != (Redbook_playing!=0)) {
1359
1360                 if (items[4].value && FindArg("-noredbook")) {
1361                         nm_messagebox (TXT_SORRY,1,TXT_OK,"Redbook audio has been disabled\non the command line");
1362                         items[4].value = 0;
1363                         items[4].redraw = 1;
1364                 }
1365                 else {
1366                         Redbook_enabled = items[4].value;
1367
1368                         mprintf((1, "Redbook_enabled = %d\n", Redbook_enabled));
1369
1370                         if (Function_mode == FMODE_MENU)
1371                                 songs_play_song(SONG_TITLE,1);
1372                         else if (Function_mode == FMODE_GAME)
1373                                 songs_play_level_song( Current_level_num );
1374                         else
1375                                 Int3();
1376
1377                         if (items[4].value && !Redbook_playing) {
1378                         #ifdef WINDOWS
1379                                 if (RBCDROM_State == -1) 
1380                                         nm_messagebox (TXT_SORRY,1,TXT_OK,"Cannot start CD Music.\nAnother application is\nusing the CD player.\n");
1381                                 else // link to next code line!
1382                         #endif
1383                                 nm_messagebox (TXT_SORRY,1,TXT_OK,"Cannot start CD Music.  Insert\nyour Descent II CD and try again");
1384                                 items[4].value = 0;
1385                                 items[4].redraw = 1;
1386                         }
1387
1388                         items[1].type = (Redbook_playing?NM_TYPE_TEXT:NM_TYPE_SLIDER);
1389                         items[1].redraw = 1;
1390                         items[2].type = (Redbook_playing?NM_TYPE_SLIDER:NM_TYPE_TEXT);
1391                         items[2].redraw = 1;
1392
1393                 }
1394         }
1395
1396         #endif
1397
1398         citem++;                //kill warning
1399 }
1400
1401 void do_sound_menu()
1402 {
1403    newmenu_item m[6];
1404         int i = 0;
1405
1406  #ifdef WINDOWS
1407         extern BOOL DIGIDriverInit;
1408         if (!DIGIDriverInit) windigi_driver_off = TRUE;
1409         else windigi_driver_off = FALSE;
1410  #endif
1411
1412         do {
1413                 m[ 0].type = NM_TYPE_SLIDER; m[ 0].text=TXT_FX_VOLUME; m[0].value=Config_digi_volume;m[0].min_value=0; m[0].max_value=8; 
1414                 m[ 1].type = (Redbook_playing?NM_TYPE_TEXT:NM_TYPE_SLIDER); m[ 1].text="MIDI music volume"; m[1].value=Config_midi_volume;m[1].min_value=0; m[1].max_value=8; 
1415
1416         #ifdef WINDOWS
1417                 if (!wmidi_support_volchange() && !Redbook_playing) {
1418                         m[1].type = NM_TYPE_CHECK; 
1419                         m[1].text = "MIDI MUSIC";
1420                         if (Config_midi_volume) m[1].value = 1;
1421                 }
1422         #endif
1423
1424                 #ifdef SHAREWARE
1425                         m[ 2].type = NM_TYPE_TEXT; m[ 2].text="";
1426                         m[ 3].type = NM_TYPE_TEXT; m[ 3].text="";
1427                         m[ 4].type = NM_TYPE_TEXT; m[ 4].text="";
1428                         #ifdef MACINTOSH
1429                                 m[ 3].type = NM_TYPE_SLIDER; m[ 3].text="Sound Manager Volume"; m[3].value=Config_master_volume;m[3].min_value=0; m[3].max_value=8; 
1430                 
1431                                 #ifdef APPLE_DEMO
1432                                         m[ 2].type = (Redbook_playing?NM_TYPE_SLIDER:NM_TYPE_TEXT); m[ 2].text="CD music volume"; m[2].value=Config_redbook_volume;m[2].min_value=0; m[2].max_value=8;
1433                                         m[ 4].type = NM_TYPE_CHECK;  m[ 4].text="CD Music (Redbook) enabled"; m[4].value=(Redbook_playing!=0);
1434                                 #endif
1435                 
1436                         #endif
1437
1438                 #else           // ifdef SHAREWARE
1439                         m[ 2].type = (Redbook_playing?NM_TYPE_SLIDER:NM_TYPE_TEXT); m[ 2].text="CD music volume"; m[2].value=Config_redbook_volume;m[2].min_value=0; m[2].max_value=8;
1440
1441                         #ifndef MACINTOSH
1442                                 m[ 3].type = NM_TYPE_TEXT; m[ 3].text="";
1443                         #else
1444                                 m[ 3].type = NM_TYPE_SLIDER; m[ 3].text="Sound Manager Volume"; m[3].value=Config_master_volume;m[3].min_value=0; m[3].max_value=8; 
1445                         #endif
1446                 
1447                         m[ 4].type = NM_TYPE_CHECK;  m[ 4].text="CD Music (Redbook) enabled"; m[4].value=(Redbook_playing!=0);
1448                 #endif
1449         
1450                 m[ 5].type = NM_TYPE_CHECK;  m[ 5].text=TXT_REVERSE_STEREO; m[5].value=Config_channels_reversed; 
1451                                 
1452                 i = newmenu_do1( NULL, "Sound Effects & Music", sizeof(m)/sizeof(*m), m, sound_menuset, i );
1453
1454                 Redbook_enabled = m[4].value;
1455                 Config_channels_reversed = m[5].value;
1456
1457         } while( i>-1 );
1458
1459 #ifdef WINDOWS
1460         if (windigi_driver_off) {
1461                 digi_midi_wait();
1462                 Sleep(500);
1463                 digi_init_digi();
1464                 windigi_driver_off=FALSE;
1465         }
1466 #endif
1467
1468
1469         if ( Config_midi_volume < 1 )   {
1470                 #ifndef MACINTOSH
1471                         digi_play_midi_song( NULL, NULL, NULL, 0 );
1472                 #else
1473                         digi_play_midi_song(-1, 0);
1474                 #endif
1475         }
1476
1477 }
1478
1479
1480 extern int Automap_always_hires;
1481
1482 #define ADD_CHECK(n,txt,v)  do { m[n].type=NM_TYPE_CHECK; m[n].text=txt; m[n].value=v;} while (0)
1483
1484 void do_toggles_menu()
1485 {
1486 #ifndef MACINTOSH
1487 #if defined(POLY_ACC)
1488         #define N_TOGGLE_ITEMS 6        // get rid of automap hi-res.
1489 #else
1490         #define N_TOGGLE_ITEMS 7
1491 #endif
1492 #else
1493         #define N_TOGGLE_ITEMS 7
1494 #endif
1495         newmenu_item m[N_TOGGLE_ITEMS];
1496         int i = 0;
1497
1498         do {
1499                 #if defined(MACINTOSH) && defined(USE_ISP)
1500                         if (ISpEnabled())
1501                         {
1502                                 m[0].type = NM_TYPE_TEXT; m[0].text = "";
1503                         }
1504                         else
1505                         {
1506                                 ADD_CHECK(0, "Ship auto-leveling", Auto_leveling_on);
1507                         }
1508                 #else 
1509                         ADD_CHECK(0, "Ship auto-leveling", Auto_leveling_on);
1510                 #endif
1511                 ADD_CHECK(1, "Show reticle", Reticle_on);
1512                 ADD_CHECK(2, "Missile view", Missile_view_enabled);
1513                 ADD_CHECK(3, "Headlight on when picked up", Headlight_active_default );
1514                 ADD_CHECK(4, "Show guided missile in main display", Guided_in_big_window );
1515                 ADD_CHECK(5, "Escort robot hot keys",EscortHotKeys);
1516                 #ifdef MACINTOSH
1517                         if ( !PAEnabled ) {
1518                                 ADD_CHECK(6, "Pixel Double", Scanline_double);
1519                         }
1520                 #else
1521 #if !defined(POLY_ACC)
1522                         ADD_CHECK(6, "Always show HighRes Automap", min(MenuHiresAvailable,Automap_always_hires));
1523 #endif
1524                 #endif
1525                 //when adding more options, change N_TOGGLE_ITEMS above
1526
1527                 #ifdef MACINTOSH
1528                 if ( PAEnabled )                // when doing RAVE, no pixel doubling
1529                         i = newmenu_do1( NULL, "Toggles", N_TOGGLE_ITEMS-1, m, NULL, i );
1530                 else
1531                 #endif          // note link to if
1532                         i = newmenu_do1( NULL, "Toggles", N_TOGGLE_ITEMS, m, NULL, i );
1533                         
1534                 Auto_leveling_on                        = m[0].value;
1535                 Reticle_on                                      = m[1].value;
1536                 Missile_view_enabled            = m[2].value;
1537                 Headlight_active_default        = m[3].value;
1538                 Guided_in_big_window            = m[4].value;
1539                 EscortHotKeys                           = m[5].value;
1540
1541
1542                 #ifdef MACINTOSH
1543                         if ( !PAEnabled )
1544                                 Scanline_double = m[6].value;
1545                 #else
1546 #if !defined(POLY_ACC)
1547                         if (MenuHiresAvailable)
1548                                 Automap_always_hires = m[6].value;
1549                         else if (m[6].value)
1550                                 nm_messagebox(TXT_SORRY,1,"OK","High Resolution modes are\nnot available on this video card");
1551 #endif
1552                 #endif
1553
1554         } while( i>-1 );
1555
1556 }
1557
1558 #ifdef NETWORK
1559 void do_multi_player_menu()
1560 {
1561         int menu_choice[4];
1562         newmenu_item m[4];
1563         int choice = 0, num_options = 0;
1564         int old_game_mode;
1565
1566         do {
1567                 old_game_mode = Game_mode;
1568                 num_options = 0;
1569
1570                 ADD_ITEM("IPX", MENU_IPX_MULTIPLAYER, -1 );
1571 #if 1 //def SUPPORTS_NET_IP
1572                 ADD_ITEM("udp/ip", MENU_IP_MULTIPLAYER, -1 );
1573 #endif
1574 #ifdef __linux__
1575                 ADD_ITEM("Kalinix", MENU_KALI_MULTIPLAYER, -1 );
1576 #endif
1577                 ADD_ITEM(TXT_MODEM_GAME, MENU_START_SERIAL, -1);
1578
1579                 choice = newmenu_do1( NULL, TXT_MULTIPLAYER, num_options, m, NULL, choice );
1580
1581                 if ( choice > -1 )
1582                         do_option(menu_choice[choice]);
1583
1584                 if (old_game_mode != Game_mode)
1585                         break;          // leave menu
1586
1587         } while( choice > -1 );
1588
1589 }
1590
1591 void do_ipx_multi_player_menu()
1592 {
1593         int menu_choice[5];
1594         newmenu_item m[5];
1595         int choice = 0, num_options = 0;
1596         int old_game_mode;
1597
1598         if (ipx_set_driver("ipx")) return;
1599
1600         do {
1601 //              WIN(ipx_destroy_read_thread());
1602
1603                 old_game_mode = Game_mode;
1604                 num_options = 0;
1605
1606                 ADD_ITEM(TXT_START_IPX_NET_GAME, MENU_START_NETGAME, -1 );
1607                 ADD_ITEM(TXT_JOIN_IPX_NET_GAME, MENU_JOIN_NETGAME, -1 );
1608                 //ADD_ITEM(TXT_START_IPX_NET_GAME, MENU_START_IPX_NETGAME, -1 );
1609                 //ADD_ITEM(TXT_JOIN_IPX_NET_GAME, MENU_JOIN_IPX_NETGAME, -1 );
1610                 //ADD_ITEM(TXT_START_TCP_NET_GAME, MENU_START_TCP_NETGAME, -1 );
1611                 //ADD_ITEM(TXT_JOIN_TCP_NET_GAME, MENU_JOIN_TCP_NETGAME, -1 );
1612
1613         #ifdef MACINTOSH
1614                 ADD_ITEM("Start Appletalk Netgame", MENU_START_APPLETALK_NETGAME, -1 );
1615                 ADD_ITEM("Join Appletalk Netgame\n", MENU_JOIN_APPLETALK_NETGAME, -1 );
1616         #endif
1617
1618                 choice = newmenu_do1( NULL, TXT_MULTIPLAYER, num_options, m, NULL, choice );
1619                 
1620                 if ( choice > -1 )      
1621                         do_option(menu_choice[choice]);
1622         
1623                 if (old_game_mode != Game_mode)
1624                         break;          // leave menu
1625
1626         } while( choice > -1 );
1627
1628 }
1629
1630 void do_kali_multi_player_menu()
1631 {
1632 #ifdef __linux__
1633         int menu_choice[3];
1634         newmenu_item m[3];
1635         int choice = 0, num_options = 0;
1636         int old_game_mode;
1637
1638         if (ipx_set_driver("kali"))return;
1639
1640         do {
1641                 old_game_mode = Game_mode;
1642                 num_options = 0;
1643
1644                 ADD_ITEM(TXT_START_IPX_NET_GAME, MENU_START_NETGAME, -1 );
1645                 ADD_ITEM(TXT_JOIN_IPX_NET_GAME, MENU_JOIN_NETGAME, -1 );
1646
1647                 choice = newmenu_do1( NULL, TXT_MULTIPLAYER, num_options, m, NULL, choice );
1648                 
1649                 if ( choice > -1 )      
1650                         do_option(menu_choice[choice]);
1651         
1652                 if (old_game_mode != Game_mode)
1653                         break;          // leave menu
1654
1655         } while( choice > -1 );
1656 #endif
1657 }
1658
1659 #if 1 //def SUPPORTS_NET_IP
1660
1661 int ip_connect_manual(char *addr);
1662 void do_ip_manual_join_menu()
1663 {
1664         int menu_choice[3];
1665         newmenu_item m[3];
1666         int choice = 0, num_options = 0;
1667         int old_game_mode;
1668         char buf[128]="";
1669
1670         do {
1671                 old_game_mode = Game_mode;
1672                 num_options = 0;
1673
1674                 m[num_options].type = NM_TYPE_INPUT; m[num_options].text=buf; m[num_options].text_len=128;menu_choice[num_options]=-1; num_options++;
1675
1676                 choice = newmenu_do1( NULL, TXT_MULTIPLAYER, num_options, m, NULL, choice );
1677
1678                 if ( choice > -1 ){
1679                         ip_connect_manual(buf);
1680 //                      do_option(menu_choice[choice]);
1681                 }
1682
1683                 if (old_game_mode != Game_mode)
1684                         break;          // leave menu
1685         } while( choice > -1 );
1686 }
1687
1688 void do_ip_serv_connect_menu()
1689 {
1690         int menu_choice[3];
1691         newmenu_item m[3];
1692         int choice = 0, num_options = 0;
1693         int old_game_mode;
1694
1695         return;
1696         do {
1697                 old_game_mode = Game_mode;
1698                 num_options = 0;
1699
1700                 ADD_ITEM("Connect to game list server",MENU_IP_SERV_CONNECT, -1 );
1701                 ADD_ITEM(TXT_START_TCP_NET_GAME, MENU_START_NETGAME, -1 );
1702                 ADD_ITEM(TXT_JOIN_TCP_NET_GAME, MENU_MANUAL_IP_JOIN, -1 );
1703
1704                 choice = newmenu_do1( NULL, TXT_MULTIPLAYER, num_options, m, NULL, choice );
1705                 
1706                 if ( choice > -1 )      
1707                         do_option(menu_choice[choice]);
1708         
1709                 if (old_game_mode != Game_mode)
1710                         break;          // leave menu
1711
1712         } while( choice > -1 );
1713
1714 }
1715
1716 void do_ip_multi_player_menu()
1717 {
1718         int menu_choice[3];
1719         newmenu_item m[3];
1720         int choice = 0, num_options = 0;
1721         int old_game_mode;
1722
1723         if (ipx_set_driver("ip"))return;
1724
1725         do {
1726                 old_game_mode = Game_mode;
1727                 num_options = 0;
1728
1729                 ADD_ITEM("Connect to game list server",MENU_IP_SERV_CONNECT, -1 );
1730                 ADD_ITEM(TXT_START_TCP_NET_GAME, MENU_START_NETGAME, -1 );
1731                 ADD_ITEM(TXT_JOIN_TCP_NET_GAME, MENU_MANUAL_IP_JOIN, -1 );
1732
1733                 choice = newmenu_do1( NULL, TXT_MULTIPLAYER, num_options, m, NULL, choice );
1734
1735                 if ( choice > -1 )
1736                         do_option(menu_choice[choice]);
1737
1738                 if (old_game_mode != Game_mode)
1739                         break;          // leave menu
1740
1741         } while( choice > -1 );
1742
1743 }
1744
1745 #endif
1746 #endif //NETWORK
1747
1748 void DoNewIPAddress ()
1749  {
1750   newmenu_item m[4];
1751   char IPText[30];
1752   int choice;
1753
1754   m[0].type=NM_TYPE_TEXT; m[0].text = "Enter an address or hostname:";
1755   m[1].type=NM_TYPE_INPUT; m[1].text_len = 50; m[1].text = IPText;
1756   IPText[0]=0;
1757
1758   choice = newmenu_do( NULL, "Join a TCPIP game", 2, m, NULL );
1759
1760   if (choice==-1 || m[1].text[0]==0)
1761    return;
1762
1763   nm_messagebox (TXT_SORRY,1,TXT_OK,"That address is not valid!");
1764  }
1765
1766
1767   
1768