home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / main / menu.c < prev    next >
Text File  |  1998-06-08  |  23KB  |  843 lines

  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-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  12. */
  13. /*
  14.  * $Source: f:/miner/source/main/rcs/menu.c $
  15.  * $Revision: 2.5 $
  16.  * $Author: john $
  17.  * $Date: 1995/10/07 13:19:09 $
  18.  *
  19.  * Inferno main menu.
  20.  *
  21.  * 
  22.  *
  23.  */
  24.  
  25. #pragma off (unreferenced)
  26. static char rcsid[] = "$Id: menu.c 2.5 1995/10/07 13:19:09 john Exp $";
  27. #pragma on (unreferenced)
  28.  
  29. #include <time.h>
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include <ctype.h>
  34. #include <stdarg.h>
  35. #include <conio.h>
  36. #include <dos.h>
  37. #include <errno.h>
  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 "mem.h"
  46. #include "error.h"
  47. #include "bm.h"
  48. #include "screens.h"
  49. #include "mono.h"
  50. #include "cflib.h"
  51. #include "joy.h"
  52. #include "vecmat.h"
  53. #include "effects.h"
  54. #include "slew.h"
  55. #include "gamemine.h"
  56. #include "gamesave.h"
  57. #include "palette.h"
  58. #include "args.h"
  59. #include "newdemo.h"
  60. #include "timer.h"
  61. #include "sounds.h"
  62. #include "gameseq.h"
  63. #include "text.h"
  64. #include "gamefont.h"
  65. #include "newmenu.h"
  66. #include "network.h"
  67. #include "scores.h"
  68. #include "joydefs.h"
  69. #include "modem.h"
  70. #include "playsave.h"
  71. #include "multi.h"
  72. #include "kconfig.h"
  73. #include "titles.h"
  74. #include "credits.h"
  75. #include "texmap.h"
  76. #include "polyobj.h"
  77. #include "state.h"
  78. #include "mission.h"
  79. #include "songs.h"
  80. #include "config.h"
  81.  
  82. #ifdef EDITOR
  83. #include "editor\editor.h"
  84. #endif
  85.  
  86. //char *menu_difficulty_text[] = { "Trainee", "Rookie", "Fighter", "Hotshot", "Insane" };
  87. //char *menu_detail_text[] = { "Lowest", "Low", "Medium", "High", "Highest", "", "Custom..." };
  88.  
  89. #define MENU_NEW_GAME            0
  90. #define MENU_GAME                      1 
  91. #define MENU_EDITOR                    2
  92. #define MENU_VIEW_SCORES            3
  93. #define MENU_QUIT                4
  94. #define MENU_LOAD_GAME                5
  95. #define MENU_SAVE_GAME                6
  96. #define MENU_DEMO_PLAY                8
  97. #define MENU_LOAD_LEVEL                9
  98. #define MENU_START_NETGAME            10
  99. #define MENU_JOIN_NETGAME            11
  100. #define MENU_CONFIG                    13
  101. #define MENU_REJOIN_NETGAME        14
  102. #define MENU_DIFFICULTY                15
  103. #define MENU_START_SERIAL            18
  104. #define MENU_HELP                        19
  105. #define MENU_NEW_PLAYER                20
  106. #define MENU_MULTIPLAYER            21
  107. #define MENU_STOP_MODEM                22
  108. #define MENU_SHOW_CREDITS            23
  109. #define MENU_ORDER_INFO                24
  110. #define MENU_PLAY_SONG                25
  111.  
  112. //ADD_ITEM("Start netgame...", MENU_START_NETGAME, -1 );
  113. //ADD_ITEM("Send net message...", MENU_SEND_NET_MESSAGE, -1 );
  114.  
  115. #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)
  116.  
  117. extern int last_joy_time;        //last time the joystick was used
  118. #ifndef NDEBUG
  119. extern int speedtest_on;
  120. #else
  121. #define speedtest_on 0
  122. #endif
  123.  
  124. ubyte do_auto_demo = 1;            // Flag used to enable auto demo starting in main menu.
  125. int Player_default_difficulty; // Last difficulty level chosen by the player
  126. int Auto_leveling_on = 0;
  127. int Menu_draw_copyright = 0;
  128.  
  129. void autodemo_menu_check(int nitems, newmenu_item * items, int *last_key, int citem )
  130. {
  131.     int curtime;
  132.  
  133.     nitems = nitems;
  134.     items=items;
  135.     citem = citem;
  136.  
  137.     //draw copyright message
  138.     if ( Menu_draw_copyright )        {
  139.         Menu_draw_copyright = 0;
  140.         gr_set_current_canvas(NULL);
  141.         gr_set_curfont(GAME_FONT);
  142.         gr_set_fontcolor(BM_XRGB(6,6,6),-1);
  143.         gr_printf(0x8000,grd_curcanv->cv_bitmap.bm_h-GAME_FONT->ft_h-2,TXT_COPYRIGHT);
  144.     }
  145.     
  146.     // Don't allow them to hit ESC in the main menu.
  147.     if (*last_key==KEY_ESC) *last_key = 0;
  148.  
  149.     if ( do_auto_demo )    {
  150.         curtime = timer_get_approx_seconds();
  151.         //if ( ((keyd_time_when_last_pressed+i2f(20)) < curtime) && ((last_joy_time+i2f(20)) < curtime) && (!speedtest_on)  ) {
  152.         if ( ((keyd_time_when_last_pressed+i2f(45)) < curtime) && (!speedtest_on)  ) {
  153.             keyd_time_when_last_pressed = curtime;            // Reset timer so that disk won't thrash if no demos.
  154.             newdemo_start_playback(NULL);        // Randomly pick a file
  155.             if (Newdemo_state == ND_STATE_PLAYBACK)    {
  156.                 Function_mode = FMODE_GAME;
  157.                 *last_key = -2;                                  
  158.             }
  159.         }
  160.     }
  161. }
  162.  
  163. //static int First_time = 1;
  164. static int main_menu_choice = 0;
  165.  
  166. //    -----------------------------------------------------------------------------
  167. //    Create the main menu.
  168. void create_main_menu(newmenu_item *m, int *menu_choice, int *callers_num_options)
  169. {
  170.     int    num_options;
  171.  
  172.     #ifndef DEMO_ONLY
  173.     num_options = 0;
  174.  
  175. //    //    Move down to allow for space to display "Destination Saturn"
  176. //    if (Saturn) {
  177. //        int    i;
  178. //
  179. //        for (i=0; i<4; i++)
  180. //            ADD_ITEM("", 0, -1);
  181. //
  182. //        if (First_time) {
  183. //            main_menu_choice = 4;
  184. //            First_time = 0;
  185. //        }
  186. //    }
  187.  
  188.     ADD_ITEM(TXT_NEW_GAME,MENU_NEW_GAME,KEY_N);
  189.  
  190. #ifdef SHAREWARE
  191.     if (get_game_list(NULL)>0)
  192. #endif
  193.  
  194.       ADD_ITEM(TXT_LOAD_GAME,MENU_LOAD_GAME,KEY_L);
  195.  
  196.     ADD_ITEM(TXT_MULTIPLAYER_,MENU_MULTIPLAYER,-1);
  197.  
  198.     ADD_ITEM(TXT_OPTIONS_, MENU_CONFIG, -1 );
  199.     ADD_ITEM(TXT_CHANGE_PILOTS,MENU_NEW_PLAYER,unused);
  200.     ADD_ITEM(TXT_VIEW_DEMO,MENU_DEMO_PLAY,0);
  201.     ADD_ITEM(TXT_VIEW_SCORES,MENU_VIEW_SCORES,KEY_V);
  202.     #ifdef SHAREWARE
  203.     ADD_ITEM(TXT_ORDERING_INFO,MENU_ORDER_INFO,-1);
  204.     #endif
  205.     ADD_ITEM(TXT_CREDITS,MENU_SHOW_CREDITS,-1);
  206.     #endif
  207.     ADD_ITEM(TXT_QUIT,MENU_QUIT,KEY_Q);
  208.  
  209.     #ifndef RELEASE
  210.     if (!(Game_mode & GM_MULTI ))    {
  211.         //m[num_options].type=NM_TYPE_TEXT;
  212.         //m[num_options++].text=" Debug options:";
  213.  
  214.         ADD_ITEM("  Load level...",MENU_LOAD_LEVEL ,KEY_N);
  215.         #ifdef EDITOR
  216.         ADD_ITEM("  Editor", MENU_EDITOR, KEY_E);
  217.         #endif
  218.     }
  219.  
  220.     ADD_ITEM( "  Play song", MENU_PLAY_SONG, -1 );
  221.     #endif
  222.  
  223.     *callers_num_options = num_options;
  224. }
  225.  
  226. //returns number of item chosen
  227. int DoMenu() 
  228. {
  229.     int menu_choice[25];
  230.     newmenu_item m[25];
  231.     int num_options = 0;
  232.  
  233.     if ( Players[Player_num].callsign[0]==0 )    {
  234.         RegisterPlayer();
  235.         return 0;
  236.     }
  237.     
  238.     if ((Game_mode & GM_SERIAL) || (Game_mode & GM_MODEM)) {
  239.         do_option(MENU_START_SERIAL);
  240.         return 0;
  241.     }
  242.  
  243.     create_main_menu(m, menu_choice, &num_options);
  244.  
  245.     do {
  246.         keyd_time_when_last_pressed = timer_get_fixed_seconds();        // .. 20 seconds from now!
  247.         if (main_menu_choice < 0 )    main_menu_choice = 0;        
  248.         Menu_draw_copyright = 1;
  249.         main_menu_choice = newmenu_do2( "", NULL, num_options, m, autodemo_menu_check, main_menu_choice, Menu_pcx_name);
  250.         if ( main_menu_choice > -1 ) do_option(menu_choice[main_menu_choice]);
  251.         create_main_menu(m, menu_choice, &num_options);    //    may have to change, eg, maybe selected pilot and no save games.
  252.     } while( Function_mode==FMODE_MENU );
  253.  
  254. //    if (main_menu_choice != -2)
  255. //        do_auto_demo = 0;        // No more auto demos
  256.     if ( Function_mode==FMODE_GAME )    
  257.         gr_palette_fade_out( gr_palette, 32, 0 );
  258.  
  259.     return main_menu_choice;
  260. }
  261.  
  262. extern void show_order_form(void);    // John didn't want this in inferno.h so I just externed it.
  263.  
  264. //returns flag, true means quit menu
  265. void do_option ( int select) 
  266. {
  267.     switch (select) {
  268.         case MENU_NEW_GAME:
  269.             do_new_game_menu();
  270.             break;
  271.         case MENU_GAME:
  272.             break;
  273.         case MENU_DEMO_PLAY:
  274.             { 
  275.                 char demo_file[16];
  276.                 if (newmenu_get_filename( TXT_SELECT_DEMO, "*.dem", demo_file, 1 ))    {
  277.                     newdemo_start_playback(demo_file);
  278.                 }
  279.             }
  280.             break;
  281.         case MENU_LOAD_GAME:
  282. #ifdef SHAREWARE
  283.             do_load_game_menu();
  284. #else
  285.             state_restore_all(0);    
  286. #endif
  287.             break;
  288.         #ifdef EDITOR
  289.         case MENU_EDITOR:
  290.             Function_mode = FMODE_EDITOR;
  291.             init_cockpit();
  292.             break;
  293.         #endif
  294.         case MENU_VIEW_SCORES:
  295.             gr_palette_fade_out( gr_palette,32,0 );
  296.             scores_view(-1);
  297.             break;
  298.         #ifdef SHAREWARE
  299.         case MENU_ORDER_INFO:
  300.             show_order_form();
  301.             break;
  302.         #endif
  303.         case MENU_QUIT:
  304.             #ifdef EDITOR
  305.             if (! SafetyCheck()) break;
  306.             #endif
  307.             gr_palette_fade_out( gr_palette,32,0);
  308.             Function_mode = FMODE_EXIT;
  309.             break;
  310.         case MENU_NEW_PLAYER:
  311.             RegisterPlayer();        //1 == allow escape out of menu
  312.             break;
  313.  
  314.         case MENU_HELP:
  315.             do_show_help();
  316.             break;
  317.  
  318.         #ifndef RELEASE
  319.  
  320.         case MENU_PLAY_SONG:    {
  321.                 int i;
  322.                 char * m[MAX_SONGS];
  323.  
  324.                 for (i=0;i<MAX_SONGS;i++) {
  325.                     m[i] = Songs[i].filename;
  326.                 }
  327.                 i = newmenu_listbox( "Select Song", MAX_SONGS, m, 1, NULL );
  328.  
  329.                 if ( i > -1 )    {
  330.                     songs_play_song( i, 0 );
  331.                 }
  332.             }
  333.             break;
  334.         case MENU_LOAD_LEVEL: {
  335.             newmenu_item m;
  336.             char text[10]="";
  337.             int new_level_num;
  338.  
  339.             m.type=NM_TYPE_INPUT; m.text_len = 10; m.text = text;
  340.  
  341.             newmenu_do( NULL, "Enter level to load", 1, &m, NULL );
  342.  
  343.             new_level_num = atoi(m.text);
  344.  
  345.             if (new_level_num!=0 && new_level_num>=Last_secret_level && new_level_num<=Last_level)    {
  346.                 gr_palette_fade_out( gr_palette, 32, 0 );
  347.                 StartNewGame(new_level_num);
  348.             }
  349.  
  350.             break;
  351.         }
  352.         #endif
  353.  
  354.  
  355.         case MENU_START_NETGAME:
  356. #ifdef NETWORK
  357. //temp!
  358.             load_mission(0);
  359.             network_start_game();
  360. #endif
  361.             break;
  362.         case MENU_JOIN_NETGAME:
  363. //temp!
  364. #ifdef NETWORK
  365.             load_mission(0);
  366.             network_join_game();
  367. #endif
  368.             break;
  369.         case MENU_START_SERIAL:
  370.             #ifdef NETWORK
  371.             com_main_menu();
  372.             #endif
  373.             break;
  374.         case MENU_MULTIPLAYER:
  375.             do_multi_player_menu();
  376.             break;
  377.         case MENU_CONFIG:
  378.             do_options_menu();
  379.             break;
  380.         case MENU_SHOW_CREDITS:
  381.             gr_palette_fade_out( gr_palette,32,0);
  382.             credits_show();    
  383.             break;
  384.         default:
  385.             Error("Unknown option %d in do_option",select);
  386.             break;
  387.         }
  388.  
  389. }
  390.  
  391. int do_difficulty_menu()
  392. {
  393.     int s;
  394.     newmenu_item m[5];
  395.  
  396.     m[0].type=NM_TYPE_MENU; m[0].text=MENU_DIFFICULTY_TEXT(0);
  397.     m[1].type=NM_TYPE_MENU; m[1].text=MENU_DIFFICULTY_TEXT(1);
  398.     m[2].type=NM_TYPE_MENU; m[2].text=MENU_DIFFICULTY_TEXT(2);
  399.     m[3].type=NM_TYPE_MENU; m[3].text=MENU_DIFFICULTY_TEXT(3);
  400.     m[4].type=NM_TYPE_MENU; m[4].text=MENU_DIFFICULTY_TEXT(4);
  401.  
  402.     s = newmenu_do1( NULL, TXT_DIFFICULTY_LEVEL, NDL, m, NULL, Difficulty_level);
  403.  
  404.     if (s > -1 )    {
  405.         if (s != Difficulty_level)
  406.         {    
  407.             Player_default_difficulty = s;
  408.             write_player_file();
  409.         }
  410.         Difficulty_level = s;
  411.         mprintf((0, "%s %s %i\n", TXT_DIFFICULTY_LEVEL, TXT_SET_TO, Difficulty_level));
  412.         return 1;
  413.     }
  414.     return 0;
  415. }
  416.  
  417. int    Max_debris_objects, Max_objects_onscreen_detailed;
  418. int    Max_linear_depth_objects;
  419.  
  420. byte    Object_complexity=2, Object_detail=2;
  421. byte    Wall_detail=2, Wall_render_depth=2, Debris_amount=2, SoundChannels = 2;
  422.  
  423. byte    Render_depths[NUM_DETAIL_LEVELS-1] =                                { 6,  9, 12, 15, 20};
  424. byte    Max_perspective_depths[NUM_DETAIL_LEVELS-1] =                    { 1,  2,  3,  5,  8};
  425. byte    Max_linear_depths[NUM_DETAIL_LEVELS-1] =                            { 3,  5,  7, 10, 17};
  426. byte    Max_linear_depths_objects[NUM_DETAIL_LEVELS-1] =                { 1,  2,  3,  5, 12};
  427. byte    Max_debris_objects_list[NUM_DETAIL_LEVELS-1] =                    { 2,  4,  7, 10, 15};
  428. byte    Max_objects_onscreen_detailed_list[NUM_DETAIL_LEVELS-1] =    { 2,  4,  7, 10, 15};
  429. 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
  430. byte    Max_sound_channels[NUM_DETAIL_LEVELS-1] =                            { 2,  4,  8, 12, 16};
  431.  
  432. //    -----------------------------------------------------------------------------
  433. //    Set detail level based stuff.
  434. //    Note: Highest detail level (detail_level == NUM_DETAIL_LEVELS-1) is custom detail level.
  435. void set_detail_level_parameters(int detail_level)
  436. {
  437.     Assert((detail_level >= 0) && (detail_level < NUM_DETAIL_LEVELS));
  438.  
  439.     if (detail_level < NUM_DETAIL_LEVELS-1) {
  440.         Render_depth = Render_depths[detail_level];
  441.         Max_perspective_depth = Max_perspective_depths[detail_level];
  442.         Max_linear_depth = Max_linear_depths[detail_level];
  443.         Max_linear_depth_objects = Max_linear_depths_objects[detail_level];
  444.  
  445.         Max_debris_objects = Max_debris_objects_list[detail_level];
  446.         Max_objects_onscreen_detailed = Max_objects_onscreen_detailed_list[detail_level];
  447.  
  448.         Simple_model_threshhold_scale = Smts_list[detail_level];
  449.  
  450.         digi_set_max_channels( Max_sound_channels[ detail_level ] );
  451.  
  452.         //    Set custom menu defaults.
  453.         Object_complexity = detail_level;
  454.         Wall_render_depth = detail_level;
  455.         Object_detail = detail_level;
  456.         Wall_detail = detail_level;
  457.         Debris_amount = detail_level;
  458.         SoundChannels = detail_level;
  459.  
  460.     }
  461. }
  462.  
  463. //    -----------------------------------------------------------------------------
  464. void do_detail_level_menu(void)
  465. {
  466.     int s;
  467.     newmenu_item m[7];
  468.  
  469.     m[0].type=NM_TYPE_MENU; m[0].text=MENU_DETAIL_TEXT(0);
  470.     m[1].type=NM_TYPE_MENU; m[1].text=MENU_DETAIL_TEXT(1);
  471.     m[2].type=NM_TYPE_MENU; m[2].text=MENU_DETAIL_TEXT(2);
  472.     m[3].type=NM_TYPE_MENU; m[3].text=MENU_DETAIL_TEXT(3);
  473.     m[4].type=NM_TYPE_MENU; m[4].text=MENU_DETAIL_TEXT(4);
  474.     m[5].type=NM_TYPE_TEXT; m[5].text="";
  475.     m[6].type=NM_TYPE_MENU; m[6].text=MENU_DETAIL_TEXT(5);
  476.  
  477.     s = newmenu_do1( NULL, TXT_DETAIL_LEVEL , NDL+2, m, NULL, Detail_level);
  478.  
  479.     if (s > -1 )    {
  480.         switch (s)    {
  481.             case 0:
  482.             case 1:
  483.             case 2:
  484.             case 3:
  485.             case 4:
  486.                 Detail_level = s;
  487.                 mprintf((0, "Detail level set to %i\n", Detail_level));
  488.                 set_detail_level_parameters(Detail_level);
  489.                 break;
  490.             case 6:
  491.                 Detail_level = 5;
  492.                 do_detail_level_menu_custom();
  493.                 break;
  494.         }
  495.     }
  496.  
  497. }
  498.  
  499. //    -----------------------------------------------------------------------------
  500. void do_detail_level_menu_custom_menuset(int nitems, newmenu_item * items, int *last_key, int citem )
  501. {
  502.     nitems = nitems;
  503.     *last_key = *last_key;
  504.     citem = citem;
  505.  
  506.     Object_complexity = items[0].value;
  507.     Object_detail = items[1].value;
  508.     Wall_detail = items[2].value;
  509.     Wall_render_depth = items[3].value;
  510.     Debris_amount = items[4].value;
  511.     SoundChannels = items[5].value;
  512.  
  513. }
  514.  
  515. void set_custom_detail_vars(void)
  516. {
  517.     Render_depth = Render_depths[Wall_render_depth];
  518.  
  519.     Max_perspective_depth = Max_perspective_depths[Wall_detail];
  520.     Max_linear_depth = Max_linear_depths[Wall_detail];
  521.  
  522.     Max_debris_objects = Max_debris_objects_list[Debris_amount];
  523.  
  524.     Max_objects_onscreen_detailed = Max_objects_onscreen_detailed_list[Object_complexity];
  525.     Simple_model_threshhold_scale = Smts_list[Object_complexity];
  526.     Max_linear_depth_objects = Max_linear_depths_objects[Object_detail];
  527.  
  528.     digi_set_max_channels( Max_sound_channels[ SoundChannels ] );
  529. }
  530.  
  531. //    -----------------------------------------------------------------------------
  532. void do_detail_level_menu_custom(void)
  533. {
  534.     int    s=0;
  535.     newmenu_item m[7];
  536.  
  537.     do {
  538.         m[0].type = NM_TYPE_SLIDER;
  539.         m[0].text = TXT_OBJ_COMPLEXITY;
  540.         m[0].value = Object_complexity;
  541.         m[0].min_value = 0;
  542.         m[0].max_value = NDL-1;
  543.  
  544.         m[1].type = NM_TYPE_SLIDER;
  545.         m[1].text = TXT_OBJ_DETAIL;
  546.         m[1].value = Object_detail;
  547.         m[1].min_value = 0;
  548.         m[1].max_value = NDL-1;
  549.  
  550.         m[2].type = NM_TYPE_SLIDER;
  551.         m[2].text = TXT_WALL_DETAIL;
  552.         m[2].value = Wall_detail;
  553.         m[2].min_value = 0;
  554.         m[2].max_value = NDL-1;
  555.  
  556.         m[3].type = NM_TYPE_SLIDER;
  557.         m[3].text = TXT_WALL_RENDER_DEPTH;
  558.         m[3].value = Wall_render_depth;
  559.         m[3].min_value = 0;
  560.         m[3].max_value = NDL-1;
  561.  
  562.         m[4].type = NM_TYPE_SLIDER;
  563.         m[4].text= TXT_DEBRIS_AMOUNT;
  564.         m[4].value = Debris_amount;
  565.         m[4].min_value = 0;
  566.         m[4].max_value = NDL-1;
  567.  
  568.         m[5].type = NM_TYPE_SLIDER;
  569.         m[5].text= TXT_SOUND_CHANNELS;
  570.         m[5].value = SoundChannels;
  571.         m[5].min_value = 0;
  572.         m[5].max_value = NDL-1;
  573.  
  574.         m[6].type = NM_TYPE_TEXT;
  575.         m[6].text= TXT_LO_HI;
  576.  
  577.         s = newmenu_do1( NULL, TXT_DETAIL_CUSTOM, 7, m, do_detail_level_menu_custom_menuset, s);
  578.     } while (s > -1);
  579.  
  580.     set_custom_detail_vars();
  581. }
  582.  
  583. do_new_game_menu()
  584. {
  585.     int n_missions,new_level_num,player_highest_level;
  586.  
  587. #ifndef SHAREWARE
  588.     n_missions = build_mission_list(0);
  589.  
  590.     if (n_missions > 1) {
  591.         int new_mission_num,i, default_mission;
  592.         char * m[MAX_MISSIONS];
  593.  
  594.         default_mission = 0;
  595.         for (i=0;i<n_missions;i++) {
  596.             m[i] = Mission_list[i].mission_name;
  597.             if ( !stricmp( m[i], config_last_mission ) )    
  598.                 default_mission = i;
  599.         }
  600.  
  601.         new_mission_num = newmenu_listbox1( "New Game\n\nSelect mission", n_missions, m, 1, default_mission, NULL );
  602.  
  603.         if (new_mission_num == -1)
  604.             return;        //abort!
  605.  
  606.         strcpy(config_last_mission, m[new_mission_num]  );
  607.         
  608.         if (!load_mission(new_mission_num)) {
  609.             nm_messagebox( NULL, 1, TXT_OK, "Error in Mission file"); 
  610.             return;
  611.         }
  612.     }
  613. #endif
  614.  
  615.     new_level_num = 1;
  616.  
  617.     player_highest_level = get_highest_level();
  618.  
  619.     if (player_highest_level > Last_level)
  620.         player_highest_level = Last_level;
  621.  
  622.     if (player_highest_level > 1) {
  623.         newmenu_item m[2];
  624.         char info_text[80];
  625.         char num_text[10];
  626.         int choice;
  627.  
  628. try_again:
  629.         sprintf(info_text,"%s %d",TXT_START_ANY_LEVEL, player_highest_level);
  630.  
  631.         m[0].type=NM_TYPE_TEXT; m[0].text = info_text;
  632.         m[1].type=NM_TYPE_INPUT; m[1].text_len = 10; m[1].text = num_text;
  633.  
  634.         strcpy(num_text,"1");
  635.  
  636.         choice = newmenu_do( NULL, TXT_SELECT_START_LEV, 2, &m, NULL );
  637.  
  638.         if (choice==-1 || m[1].text[0]==0)
  639.             return;
  640.  
  641.         new_level_num = atoi(m[1].text);
  642.  
  643.         if (!(new_level_num>0 && new_level_num<=player_highest_level)) {
  644.             m[0].text = TXT_ENTER_TO_CONT;
  645.             nm_messagebox( NULL, 1, TXT_OK, TXT_INVALID_LEVEL); 
  646.             goto try_again;
  647.         }
  648.     }
  649.  
  650.     Difficulty_level = Player_default_difficulty;
  651.  
  652.     if (!do_difficulty_menu())
  653.         return;
  654.  
  655.     gr_palette_fade_out( gr_palette, 32, 0 );
  656.  
  657. #ifdef PSX_BUILD_TOOLS
  658.     {
  659.         int i;
  660.         for (i=Last_secret_level; i<=Last_level; i++ )    {
  661.             if ( i!=0 )    
  662.                 StartNewGame(i);
  663.         }        
  664.     }
  665. #endif
  666.  
  667.     StartNewGame(new_level_num);
  668.  
  669. }
  670.  
  671. do_load_game_menu()
  672. {
  673.     newmenu_item m[N_SAVE_SLOTS];
  674.     char *saved_text[N_SAVE_SLOTS];
  675.     int i,choice;
  676.  
  677.     get_game_list(saved_text);
  678.  
  679.     for (i=0;i<N_SAVE_SLOTS;i++) {
  680.  
  681.         if (saved_text[i][0]) {
  682.             m[i].type = NM_TYPE_MENU;
  683.             m[i].text = saved_text[i];
  684.         }
  685.         else {
  686.             m[i].type = NM_TYPE_TEXT;
  687.             m[i].text = TXT_EMPTY;
  688.         }
  689.     }
  690.  
  691.     choice = newmenu_do( NULL, TXT_LOAD_GAME, N_SAVE_SLOTS, m, NULL );
  692.  
  693.     if (choice != -1) {
  694.         int ret;
  695.  
  696.         if ((ret=load_player_game(choice)) == EZERO)
  697.             ResumeSavedGame(Players[Player_num].level);
  698.         else {
  699.             newmenu_item m1[3];
  700.  
  701.             m1[0].type = NM_TYPE_TEXT;  m1[0].text = strerror(ret);
  702.             m1[1].type = NM_TYPE_TEXT;  m1[1].text = "";
  703.             m1[2].type = NM_TYPE_TEXT;  m1[2].text = TXT_ENTER_TO_CONT;
  704.  
  705.             newmenu_do( NULL, TXT_ERR_LOADING_GAME, 3, m1, NULL );
  706.  
  707.         }
  708.     }
  709. }
  710.  
  711. do_save_game_menu()
  712. {
  713.     newmenu_item m[N_SAVE_SLOTS];
  714.     char *saved_text_ptrs[N_SAVE_SLOTS];
  715.     char menu_text[N_SAVE_SLOTS][GAME_NAME_LEN+1];        //+1 for terminating zero
  716.     int i,choice;
  717.  
  718.     get_game_list(saved_text_ptrs);
  719.  
  720.     for (i=0;i<N_SAVE_SLOTS;i++) {
  721.  
  722.         strcpy(menu_text[i],saved_text_ptrs[i]);
  723.  
  724.         m[i].type = NM_TYPE_INPUT_MENU;
  725.         m[i].text_len = GAME_NAME_LEN;
  726.         m[i].text = menu_text[i];
  727.  
  728.         if (!menu_text[i][0])
  729.             strcpy(menu_text[i],TXT_EMPTY);
  730.  
  731.     }
  732.  
  733.     choice = newmenu_do( NULL, TXT_SAVE_GAME_SLOTS, N_SAVE_SLOTS, m, NULL );
  734.  
  735.     if (choice != -1) {
  736.         int ret;
  737.  
  738.         if ((ret=save_player_game(choice,m[choice].text)) != EZERO)
  739.             nm_messagebox( NULL,1, TXT_CONTINUE,"%s\n%s\n\n", TXT_SAVE_ERROR, strerror(ret));
  740.     }
  741.  
  742. }
  743.  
  744. extern void GameLoop(int, int );
  745.  
  746. void joydef_menuset(int nitems, newmenu_item * items, int *last_key, int citem )
  747. {
  748.     nitems=nitems;        
  749.     *last_key = *last_key;
  750.  
  751.     if ( citem==4)    {
  752.         gr_palette_set_gamma(items[4].value);
  753.     }
  754.  
  755.     if ( Config_digi_volume != items[0].value )    {
  756.         Config_digi_volume = items[0].value;
  757.         digi_set_digi_volume( (Config_digi_volume*32768)/8 );
  758.         digi_play_sample_once( SOUND_DROP_BOMB, F1_0 );
  759.     }
  760.  
  761.     if (Config_midi_volume != items[1].value )    {
  762.         Config_midi_volume = items[1].value;
  763.         digi_set_midi_volume( (Config_midi_volume*128)/8 );
  764.     }
  765. }
  766.  
  767. //this change was made in DESCENT.TEX, but since we're not including that
  768. //file in the v1.1 update, we're making the change in the code here also
  769. #ifdef SHAREWARE
  770. #undef    TXT_JOYS_SENSITIVITY
  771. #define    TXT_JOYS_SENSITIVITY "Joystick/Mouse\nSensitivity"
  772. #endif
  773.  
  774. void do_options_menu()
  775. {
  776.     newmenu_item m[13];
  777.     int i = 0;
  778.  
  779.     do {
  780.         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; 
  781.         m[1].type = NM_TYPE_SLIDER; m[1].text=TXT_MUSIC_VOLUME; m[1].value=Config_midi_volume;m[1].min_value=0; m[1].max_value=8; 
  782.         m[2].type = NM_TYPE_CHECK; m[2].text=TXT_REVERSE_STEREO; m[2].value=Config_channels_reversed; 
  783.         m[3].type = NM_TYPE_TEXT; m[3].text="";
  784.         m[4].type = NM_TYPE_SLIDER; m[4].text=TXT_BRIGHTNESS; m[4].value=gr_palette_get_gamma();m[4].min_value=0; m[4].max_value=8; 
  785.         m[5].type = NM_TYPE_TEXT; m[5].text="";
  786.         m[6].type = NM_TYPE_MENU; m[6].text=TXT_CONTROLS_;
  787.         m[7].type = NM_TYPE_MENU; m[7].text=TXT_DETAIL_LEVELS;
  788.         m[8].type = NM_TYPE_MENU; m[8].text=TXT_CAL_JOYSTICK;
  789.         m[9].type = NM_TYPE_TEXT; m[9].text="";
  790.         m[10].type = NM_TYPE_SLIDER; m[10].text=TXT_JOYS_SENSITIVITY; m[10].value=Config_joystick_sensitivity; m[10].min_value =0; m[10].max_value = 8;
  791.         m[11].type = NM_TYPE_TEXT; m[11].text="";
  792.         m[12].type = NM_TYPE_CHECK; m[12].text="Ship auto-leveling"; m[12].value=Auto_leveling_on; 
  793.                 
  794.         i = newmenu_do1( NULL, TXT_OPTIONS, 13, m, joydef_menuset, i );
  795.             
  796.         switch(i)    {
  797.             case 6: joydefs_config();             break;
  798.             case 7: do_detail_level_menu();    break;
  799.             case 8: joydefs_calibrate();        break;
  800.         }
  801.  
  802.         Config_channels_reversed = m[2].value;
  803.         Config_joystick_sensitivity = m[10].value;
  804.         Auto_leveling_on = m[12].value;
  805.     } while( i>-1 );
  806.  
  807.     if ( Config_midi_volume < 1 )    {
  808.         digi_play_midi_song( NULL, NULL, NULL, 0 );
  809.     }
  810.  
  811.     write_player_file();
  812. }
  813.  
  814. void do_multi_player_menu()
  815. {
  816.     int menu_choice[3];
  817.     newmenu_item m[3];
  818.     int choice = 0, num_options = 0;
  819.     int old_game_mode;
  820.  
  821.     do {
  822.         old_game_mode = Game_mode;
  823.         num_options = 0;
  824.  
  825.         ADD_ITEM(TXT_START_NET_GAME, MENU_START_NETGAME, -1 );
  826.         ADD_ITEM(TXT_JOIN_NET_GAME, MENU_JOIN_NETGAME, -1 );
  827.         ADD_ITEM(TXT_MODEM_GAME, MENU_START_SERIAL, -1);
  828.  
  829.         choice = newmenu_do1( NULL, TXT_MULTIPLAYER, num_options, m, NULL, choice );
  830.         
  831.         if ( choice > -1 )    
  832.             do_option(menu_choice[choice]);
  833.     
  834.         if (old_game_mode != Game_mode)
  835.             break;        // leave menu
  836.  
  837.     } while( choice > -1 );
  838.  
  839. }
  840.  
  841.  
  842. 
  843.