2006-03-20 17:12:09 +00:00
/*
THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
SOFTWARE CORPORATION ( " PARALLAX " ) . PARALLAX , IN DISTRIBUTING THE CODE TO
END - USERS , AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN , GRANTS A
ROYALTY - FREE , PERPETUAL LICENSE TO SUCH END - USERS FOR USE BY SUCH END - USERS
IN USING , DISPLAYING , AND CREATING DERIVATIVE WORKS THEREOF , SO LONG AS
SUCH USE , DISPLAY OR CREATION IS FOR NON - COMMERCIAL , ROYALTY OR REVENUE
FREE PURPOSES . IN NO EVENT SHALL THE END - USER USE THE COMPUTER CODE
CONTAINED HEREIN FOR REVENUE - BEARING PURPOSES . THE END - USER UNDERSTANDS
AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE .
COPYRIGHT 1993 - 1999 PARALLAX SOFTWARE CORPORATION . ALL RIGHTS RESERVED .
*/
/*
*
* Inferno main menu .
*
*/
# include <stdio.h>
# include <string.h>
# include "menu.h"
# include "inferno.h"
# include "game.h"
# include "gr.h"
# include "key.h"
2011-01-02 11:25:51 +00:00
# include "mouse.h"
2006-03-20 17:12:09 +00:00
# include "iff.h"
# include "u_mem.h"
2012-07-07 18:35:06 +00:00
# include "dxxerror.h"
2006-03-20 17:12:09 +00:00
# include "bm.h"
# include "screens.h"
# include "joy.h"
# include "vecmat.h"
# include "effects.h"
# include "slew.h"
# include "gamemine.h"
# include "gamesave.h"
# include "palette.h"
# include "args.h"
# include "newdemo.h"
# include "timer.h"
# include "sounds.h"
# include "gameseq.h"
# include "text.h"
# include "gamefont.h"
# include "newmenu.h"
# include "scores.h"
# include "playsave.h"
# include "kconfig.h"
# include "titles.h"
# include "credits.h"
# include "texmap.h"
# include "polyobj.h"
# include "state.h"
# include "mission.h"
# include "songs.h"
2010-10-14 09:50:11 +00:00
# ifdef USE_SDLMIXER
2010-08-27 14:09:19 +00:00
# include "jukebox.h" // for jukebox_exts
2010-10-14 09:50:11 +00:00
# endif
2006-03-20 17:12:09 +00:00
# include "config.h"
# include "movie.h"
# include "gamepal.h"
# include "gauges.h"
# include "powerup.h"
# include "strutil.h"
2009-11-29 16:46:13 +00:00
# include "multi.h"
2012-11-02 17:35:57 +00:00
# include "vers_id.h"
2009-11-29 16:46:13 +00:00
# ifdef USE_UDP
# include "net_udp.h"
2009-11-24 09:48:53 +00:00
# endif
2006-03-20 17:12:09 +00:00
# ifdef EDITOR
# include "editor/editor.h"
2010-12-21 03:35:50 +00:00
# include "editor/kdefs.h"
2006-03-20 17:12:09 +00:00
# endif
2011-01-16 00:50:42 +00:00
# ifdef OGL
# include "ogl_init.h"
# endif
2006-03-20 17:12:09 +00:00
2008-10-28 17:58:54 +00:00
// Menu IDs...
enum MENUS
{
MENU_NEW_GAME = 0 ,
MENU_GAME ,
MENU_EDITOR ,
MENU_VIEW_SCORES ,
MENU_QUIT ,
MENU_LOAD_GAME ,
MENU_SAVE_GAME ,
MENU_DEMO_PLAY ,
MENU_CONFIG ,
MENU_REJOIN_NETGAME ,
MENU_DIFFICULTY ,
MENU_HELP ,
MENU_NEW_PLAYER ,
2011-09-13 23:15:32 +00:00
# if defined(USE_UDP)
2009-05-03 12:31:30 +00:00
MENU_MULTIPLAYER ,
# endif
2008-10-28 17:58:54 +00:00
MENU_SHOW_CREDITS ,
MENU_ORDER_INFO ,
2009-05-03 12:31:30 +00:00
2009-11-29 16:46:13 +00:00
# ifdef USE_UDP
2009-11-24 09:48:53 +00:00
MENU_START_UDP_NETGAME ,
MENU_JOIN_MANUAL_UDP_NETGAME ,
MENU_JOIN_LIST_UDP_NETGAME ,
2009-11-29 16:46:13 +00:00
# endif
2011-07-20 12:44:49 +00:00
# ifndef RELEASE
MENU_SANDBOX
# endif
2008-10-28 17:58:54 +00:00
} ;
2006-03-20 17:12:09 +00:00
//ADD_ITEM("Start netgame...", MENU_START_NETGAME, -1 );
//ADD_ITEM("Send net message...", MENU_SEND_NET_MESSAGE, -1 );
# 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)
2010-03-27 03:24:14 +00:00
static window * menus [ 16 ] = { NULL } ;
2010-03-18 02:49:02 +00:00
2006-03-20 17:12:09 +00:00
// Function Prototypes added after LINTING
2010-04-03 08:35:56 +00:00
int do_option ( int select ) ;
2010-03-18 07:02:38 +00:00
int do_new_game_menu ( void ) ;
2009-11-24 09:48:53 +00:00
void do_multi_player_menu ( ) ;
2011-07-20 12:44:49 +00:00
# ifndef RELEASE
void do_sandbox_menu ( ) ;
# endif
2010-07-31 12:09:38 +00:00
extern void newmenu_free_background ( ) ;
2008-03-23 13:03:42 +00:00
extern void ReorderPrimary ( ) ;
extern void ReorderSecondary ( ) ;
2006-03-20 17:12:09 +00:00
2010-03-18 02:49:02 +00:00
// Hide all menus
2010-03-30 03:47:51 +00:00
int hide_menus ( void )
2010-03-18 02:49:02 +00:00
{
window * wind ;
int i ;
2010-06-14 08:13:16 +00:00
2010-03-27 08:00:53 +00:00
if ( menus [ 0 ] )
2010-03-30 03:47:51 +00:00
return 0 ; // there are already hidden menus
2010-03-27 03:24:14 +00:00
2010-03-18 02:49:02 +00:00
for ( i = 0 ; ( i < 15 ) & & ( wind = window_get_front ( ) ) ; i + + )
{
menus [ i ] = wind ;
window_set_visible ( wind , 0 ) ;
}
2010-06-14 08:13:16 +00:00
2010-03-18 02:49:02 +00:00
Assert ( window_get_front ( ) = = NULL ) ;
menus [ i ] = NULL ;
2010-06-14 08:13:16 +00:00
2010-03-30 03:47:51 +00:00
return 1 ;
2010-03-18 02:49:02 +00:00
}
// Show all menus, with the front one shown first
// This makes sure EVENT_WINDOW_ACTIVATED is only sent to that window
void show_menus ( void )
{
int i ;
2010-06-14 08:13:16 +00:00
2010-03-18 02:49:02 +00:00
for ( i = 0 ; ( i < 16 ) & & menus [ i ] ; i + + )
2010-03-27 03:24:14 +00:00
if ( window_exists ( menus [ i ] ) )
window_set_visible ( menus [ i ] , 1 ) ;
menus [ 0 ] = NULL ;
2010-03-18 02:49:02 +00:00
}
2010-02-07 12:10:52 +00:00
//pairs of chars describing ranges
char playername_allowed_chars [ ] = " azAZ09__-- " ;
int MakeNewPlayerFile ( int allow_abort )
{
int x ;
2011-06-06 19:19:38 +00:00
char filename [ PATH_MAX ] ;
2010-02-07 12:10:52 +00:00
newmenu_item m ;
char text [ CALLSIGN_LEN + 9 ] = " " ;
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
strncpy ( text , Players [ Player_num ] . callsign , CALLSIGN_LEN ) ;
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
try_again :
m . type = NM_TYPE_INPUT ; m . text_len = CALLSIGN_LEN ; m . text = text ;
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
Newmenu_allowed_chars = playername_allowed_chars ;
x = newmenu_do ( NULL , TXT_ENTER_PILOT_NAME , 1 , & m , NULL , NULL ) ;
Newmenu_allowed_chars = NULL ;
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
if ( x < 0 ) {
if ( allow_abort ) return 0 ;
goto try_again ;
}
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
if ( text [ 0 ] = = 0 ) //null string
goto try_again ;
2010-06-14 08:13:16 +00:00
2012-05-18 23:36:43 +00:00
d_strlwr ( text ) ;
2010-06-14 08:13:16 +00:00
2011-06-06 19:19:38 +00:00
memset ( filename , ' \0 ' , PATH_MAX ) ;
snprintf ( filename , PATH_MAX , GameArg . SysUsePlayersDir ? " Players/%s.plr " : " %s.plr " , text ) ;
2010-06-14 08:13:16 +00:00
2011-06-01 07:59:55 +00:00
if ( PHYSFSX_exists ( filename , 0 ) )
2010-02-07 12:10:52 +00:00
{
nm_messagebox ( NULL , 1 , TXT_OK , " %s '%s' %s " , TXT_PLAYER , text , TXT_ALREADY_EXISTS ) ;
goto try_again ;
}
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
if ( ! new_player_config ( ) )
goto try_again ; // They hit Esc during New player config
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
strncpy ( Players [ Player_num ] . callsign , text , CALLSIGN_LEN ) ;
2012-05-18 23:36:43 +00:00
d_strlwr ( Players [ Player_num ] . callsign ) ;
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
write_player_file ( ) ;
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
return 1 ;
}
void delete_player_saved_games ( char * name ) ;
int player_menu_keycommand ( listbox * lb , d_event * event )
{
char * * items = listbox_get_items ( lb ) ;
int citem = listbox_get_citem ( lb ) ;
2010-06-14 08:13:16 +00:00
2011-01-14 09:51:13 +00:00
switch ( event_key_get ( event ) )
2010-02-07 12:10:52 +00:00
{
case KEY_CTRLED + KEY_D :
if ( citem > 0 )
{
int x = 1 ;
x = nm_messagebox ( NULL , 2 , TXT_YES , TXT_NO , " %s %s? " , TXT_DELETE_PILOT , items [ citem ] + ( ( items [ citem ] [ 0 ] = = ' $ ' ) ? 1 : 0 ) ) ;
if ( x = = 0 ) {
char * p ;
2011-04-22 15:14:29 +00:00
char plxfile [ PATH_MAX ] , efffile [ PATH_MAX ] , ngpfile [ PATH_MAX ] ;
2010-02-07 12:10:52 +00:00
int ret ;
char name [ PATH_MAX ] ;
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
p = items [ citem ] + strlen ( items [ citem ] ) ;
* p = ' . ' ;
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
strcpy ( name , GameArg . SysUsePlayersDir ? " Players/ " : " " ) ;
strcat ( name , items [ citem ] ) ;
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
ret = ! PHYSFS_delete ( name ) ;
* p = 0 ;
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
if ( ! ret )
{
delete_player_saved_games ( items [ citem ] ) ;
// delete PLX file
sprintf ( plxfile , GameArg . SysUsePlayersDir ? " Players/%.8s.plx " : " %.8s.plx " , items [ citem ] ) ;
2011-06-01 07:59:55 +00:00
if ( PHYSFSX_exists ( plxfile , 0 ) )
2010-02-07 12:10:52 +00:00
PHYSFS_delete ( plxfile ) ;
// delete EFF file
sprintf ( efffile , GameArg . SysUsePlayersDir ? " Players/%.8s.eff " : " %.8s.eff " , items [ citem ] ) ;
2011-06-01 07:59:55 +00:00
if ( PHYSFSX_exists ( efffile , 0 ) )
2010-02-07 12:10:52 +00:00
PHYSFS_delete ( efffile ) ;
2011-04-22 15:14:29 +00:00
// delete NGP file
sprintf ( ngpfile , GameArg . SysUsePlayersDir ? " Players/%.8s.ngp " : " %.8s.ngp " , items [ citem ] ) ;
2011-06-01 07:59:55 +00:00
if ( PHYSFSX_exists ( ngpfile , 0 ) )
2011-04-22 15:14:29 +00:00
PHYSFS_delete ( ngpfile ) ;
2010-02-07 12:10:52 +00:00
}
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
if ( ret )
nm_messagebox ( NULL , 1 , TXT_OK , " %s %s %s " , TXT_COULDNT , TXT_DELETE_PILOT , items [ citem ] + ( ( items [ citem ] [ 0 ] = = ' $ ' ) ? 1 : 0 ) ) ;
else
listbox_delete_item ( lb , citem ) ;
}
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
return 1 ;
}
break ;
}
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
return 0 ;
}
int player_menu_handler ( listbox * lb , d_event * event , char * * list )
{
char * * items = listbox_get_items ( lb ) ;
int citem = listbox_get_citem ( lb ) ;
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
switch ( event - > type )
{
case EVENT_KEY_COMMAND :
return player_menu_keycommand ( lb , event ) ;
break ;
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
case EVENT_NEWMENU_SELECTED :
if ( citem < 0 )
return 0 ; // shouldn't happen
else if ( citem = = 0 )
{
// They selected 'create new pilot'
return ! MakeNewPlayerFile ( 1 ) ;
}
else
{
strncpy ( Players [ Player_num ] . callsign , items [ citem ] + ( ( items [ citem ] [ 0 ] = = ' $ ' ) ? 1 : 0 ) , CALLSIGN_LEN ) ;
2012-05-18 23:36:43 +00:00
d_strlwr ( Players [ Player_num ] . callsign ) ;
2010-02-07 12:10:52 +00:00
}
break ;
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
case EVENT_WINDOW_CLOSE :
if ( read_player_file ( ) ! = EZERO )
return 1 ; // abort close!
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
WriteConfigFile ( ) ; // Update lastplr
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
PHYSFS_freeList ( list ) ;
d_free ( items ) ;
break ;
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
default :
break ;
}
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
return 0 ;
}
//Inputs the player's name, without putting up the background screen
int RegisterPlayer ( )
{
char * * m ;
char * * f ;
char * * list ;
2012-07-22 23:17:54 +00:00
static const char * const types [ ] = { " .plr " , NULL } ;
2010-02-07 12:10:52 +00:00
int i = 0 , NumItems ;
int citem = 0 ;
int allow_abort_flag = 1 ;
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
if ( Players [ Player_num ] . callsign [ 0 ] = = 0 )
{
if ( GameCfg . LastPlayer [ 0 ] = = 0 )
2010-06-23 12:57:28 +00:00
{
strncpy ( Players [ Player_num ] . callsign , " player " , CALLSIGN_LEN ) ;
2010-02-07 12:10:52 +00:00
allow_abort_flag = 0 ;
2010-06-23 12:57:28 +00:00
}
else
{
// Read the last player's name from config file, not lastplr.txt
strncpy ( Players [ Player_num ] . callsign , GameCfg . LastPlayer , CALLSIGN_LEN ) ;
}
2010-02-07 12:10:52 +00:00
}
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
list = PHYSFSX_findFiles ( GameArg . SysUsePlayersDir ? " Players/ " : " " , types ) ;
if ( ! list )
return 0 ; // memory error
if ( ! * list )
{
MakeNewPlayerFile ( 0 ) ; // make a new player without showing listbox
PHYSFS_freeList ( list ) ;
return 0 ;
}
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
for ( NumItems = 0 ; list [ NumItems ] ! = NULL ; NumItems + + ) { }
NumItems + + ; // for TXT_CREATE_NEW
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
MALLOC ( m , char * , NumItems ) ;
if ( m = = NULL )
{
PHYSFS_freeList ( list ) ;
return 0 ;
}
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
m [ i + + ] = TXT_CREATE_NEW ;
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
for ( f = list ; * f ! = NULL ; f + + )
{
char * p ;
2010-06-14 08:13:16 +00:00
2011-07-13 21:26:43 +00:00
if ( strlen ( * f ) > FILENAME_LEN - 1 | | strlen ( * f ) < 5 ) // sorry guys, can only have up to eight chars for the player name
{
NumItems - - ;
continue ;
}
2010-02-07 12:10:52 +00:00
m [ i + + ] = * f ;
p = strchr ( * f , ' . ' ) ;
if ( p )
* p = ' \0 ' ; // chop the .plr
2011-07-13 21:26:43 +00:00
}
if ( NumItems < = 1 ) // so it seems all plr files we found were too long. funny. let's make a real player
{
MakeNewPlayerFile ( 0 ) ; // make a new player without showing listbox
PHYSFS_freeList ( list ) ;
return 0 ;
2010-02-07 12:10:52 +00:00
}
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
// Sort by name, except the <Create New Player> string
2010-09-26 13:15:20 +00:00
qsort ( & m [ 1 ] , NumItems - 1 , sizeof ( char * ) , ( int ( * ) ( const void * , const void * ) ) string_array_sort_func ) ;
2010-02-07 12:10:52 +00:00
for ( i = 0 ; i < NumItems ; i + + )
2012-05-18 23:36:43 +00:00
if ( ! d_stricmp ( Players [ Player_num ] . callsign , m [ i ] ) )
2010-02-07 12:10:52 +00:00
citem = i ;
newmenu_listbox1 ( TXT_SELECT_PILOT , NumItems , m , allow_abort_flag , citem , ( int ( * ) ( listbox * , d_event * , void * ) ) player_menu_handler , list ) ;
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
return 1 ;
}
2010-04-03 10:16:53 +00:00
// Draw Copyright and Version strings
void draw_copyright ( )
{
gr_set_current_canvas ( NULL ) ;
gr_set_curfont ( GAME_FONT ) ;
gr_set_fontcolor ( BM_XRGB ( 6 , 6 , 6 ) , - 1 ) ;
2013-01-03 16:23:24 +00:00
gr_string ( 0x8000 , SHEIGHT - LINE_SPACING , TXT_COPYRIGHT ) ;
2010-04-03 10:16:53 +00:00
gr_set_fontcolor ( BM_XRGB ( 25 , 0 , 0 ) , - 1 ) ;
2013-01-03 16:23:24 +00:00
gr_string ( 0x8000 , SHEIGHT - ( LINE_SPACING * 2 ) , DESCENT_VERSION ) ;
2010-04-03 10:16:53 +00:00
}
2006-03-20 17:12:09 +00:00
//returns the number of demo files on the disk
int newdemo_count_demos ( ) ;
// ------------------------------------------------------------------------
2010-01-27 09:11:47 +00:00
int main_menu_handler ( newmenu * menu , d_event * event , int * menu_choice )
2006-03-20 17:12:09 +00:00
{
2010-04-03 08:35:56 +00:00
newmenu_item * items = newmenu_get_items ( menu ) ;
2006-03-20 17:12:09 +00:00
2010-01-27 09:11:47 +00:00
switch ( event - > type )
2008-01-13 13:27:58 +00:00
{
2010-01-27 09:11:47 +00:00
case EVENT_WINDOW_ACTIVATED :
2010-04-03 08:35:56 +00:00
load_palette ( MENU_PALETTE , 0 , 1 ) ; //get correct palette
2010-06-14 08:13:16 +00:00
2010-01-27 09:11:47 +00:00
if ( Players [ Player_num ] . callsign [ 0 ] = = 0 )
RegisterPlayer ( ) ;
else
2010-12-10 23:18:17 +00:00
keyd_time_when_last_pressed = timer_query ( ) ; // .. 20 seconds from now!
2010-01-27 09:11:47 +00:00
break ;
2010-06-14 08:13:16 +00:00
2010-01-27 09:11:47 +00:00
case EVENT_KEY_COMMAND :
// Don't allow them to hit ESC in the main menu.
2011-01-14 09:51:13 +00:00
if ( event_key_get ( event ) = = KEY_ESC )
2010-01-30 03:24:19 +00:00
return 1 ;
2010-05-03 08:22:50 +00:00
break ;
2010-06-14 08:13:16 +00:00
2011-01-02 11:25:51 +00:00
case EVENT_MOUSE_BUTTON_DOWN :
case EVENT_MOUSE_BUTTON_UP :
// Don't allow mousebutton-closing in main menu.
2011-01-14 09:51:13 +00:00
if ( event_mouse_get_button ( event ) = = MBTN_RIGHT )
2011-01-02 11:25:51 +00:00
return 1 ;
break ;
2010-01-27 09:11:47 +00:00
case EVENT_IDLE :
2011-07-02 22:09:30 +00:00
if ( keyd_time_when_last_pressed + i2f ( 25 ) < timer_query ( ) | | GameArg . SysAutoDemo )
2010-01-27 09:11:47 +00:00
{
int n_demos ;
n_demos = newdemo_count_demos ( ) ;
2011-07-02 20:59:03 +00:00
keyd_time_when_last_pressed = timer_query ( ) ; // Reset timer so that disk won't thrash if no demos.
2010-06-14 08:13:16 +00:00
2010-01-27 09:11:47 +00:00
if ( ( ( d_rand ( ) % ( n_demos + 1 ) ) = = 0 ) & & ! GameArg . SysAutoDemo )
{
2006-03-20 17:12:09 +00:00
# ifdef OGL
2010-01-27 09:11:47 +00:00
Screen_mode = - 1 ;
2006-03-20 17:12:09 +00:00
# endif
2010-03-18 02:49:02 +00:00
init_subtitles ( " intro.tex " ) ;
2010-01-27 09:11:47 +00:00
PlayMovie ( " intro.mve " , 0 ) ;
2010-03-18 02:49:02 +00:00
close_subtitles ( ) ;
2010-01-27 09:11:47 +00:00
songs_play_song ( SONG_TITLE , 1 ) ;
set_screen_mode ( SCREEN_MENU ) ;
}
else
{
newdemo_start_playback ( NULL ) ; // Randomly pick a file, assume native endian (crashes if not)
if ( Newdemo_state = = ND_STATE_PLAYBACK )
2010-04-03 08:35:56 +00:00
return 0 ;
2010-01-27 09:11:47 +00:00
}
2006-03-20 17:12:09 +00:00
}
2010-01-27 09:11:47 +00:00
break ;
2010-06-14 08:13:16 +00:00
2010-04-03 10:16:53 +00:00
case EVENT_NEWMENU_DRAW :
draw_copyright ( ) ;
break ;
2010-06-14 08:13:16 +00:00
2010-04-03 08:35:56 +00:00
case EVENT_NEWMENU_SELECTED :
return do_option ( menu_choice [ newmenu_get_citem ( menu ) ] ) ;
break ;
2010-06-14 08:13:16 +00:00
2010-04-03 08:35:56 +00:00
case EVENT_WINDOW_CLOSE :
d_free ( menu_choice ) ;
d_free ( items ) ;
break ;
2010-06-14 08:13:16 +00:00
2010-01-27 09:11:47 +00:00
default :
break ;
2006-03-20 17:12:09 +00:00
}
2010-01-07 14:49:07 +00:00
2010-01-30 03:24:19 +00:00
return 0 ;
2006-03-20 17:12:09 +00:00
}
2009-05-03 12:31:30 +00:00
// -----------------------------------------------------------------------------
// Create the main menu.
2006-03-20 17:12:09 +00:00
void create_main_menu ( newmenu_item * m , int * menu_choice , int * callers_num_options )
{
2009-05-03 12:31:30 +00:00
int num_options ;
2006-03-20 17:12:09 +00:00
# ifndef DEMO_ONLY
num_options = 0 ;
ADD_ITEM ( TXT_NEW_GAME , MENU_NEW_GAME , KEY_N ) ;
ADD_ITEM ( TXT_LOAD_GAME , MENU_LOAD_GAME , KEY_L ) ;
2011-09-13 23:15:32 +00:00
# if defined(USE_UDP)
2006-03-20 17:12:09 +00:00
ADD_ITEM ( TXT_MULTIPLAYER_ , MENU_MULTIPLAYER , - 1 ) ;
# endif
ADD_ITEM ( TXT_OPTIONS_ , MENU_CONFIG , - 1 ) ;
ADD_ITEM ( TXT_CHANGE_PILOTS , MENU_NEW_PLAYER , unused ) ;
ADD_ITEM ( TXT_VIEW_DEMO , MENU_DEMO_PLAY , 0 ) ;
ADD_ITEM ( TXT_VIEW_SCORES , MENU_VIEW_SCORES , KEY_V ) ;
2011-06-01 07:59:55 +00:00
if ( PHYSFSX_exists ( " orderd2.pcx " , 1 ) ) /* SHAREWARE */
2006-03-20 17:12:09 +00:00
ADD_ITEM ( TXT_ORDERING_INFO , MENU_ORDER_INFO , - 1 ) ;
ADD_ITEM ( TXT_CREDITS , MENU_SHOW_CREDITS , - 1 ) ;
# endif
ADD_ITEM ( TXT_QUIT , MENU_QUIT , KEY_Q ) ;
# ifndef RELEASE
2009-05-03 12:31:30 +00:00
if ( ! ( Game_mode & GM_MULTI ) ) {
2006-03-20 17:12:09 +00:00
//m[num_options].type=NM_TYPE_TEXT;
//m[num_options++].text=" Debug options:";
# ifdef EDITOR
ADD_ITEM ( " Editor " , MENU_EDITOR , KEY_E ) ;
# endif
}
2011-07-20 12:44:49 +00:00
ADD_ITEM ( " SANDBOX " , MENU_SANDBOX , - 1 ) ;
2006-03-20 17:12:09 +00:00
# endif
* callers_num_options = num_options ;
}
//returns number of item chosen
2010-06-14 08:13:16 +00:00
int DoMenu ( )
2006-03-20 17:12:09 +00:00
{
2010-04-03 08:35:56 +00:00
int * menu_choice ;
newmenu_item * m ;
2006-03-20 17:12:09 +00:00
int num_options = 0 ;
2010-04-03 08:35:56 +00:00
MALLOC ( menu_choice , int , 25 ) ;
if ( ! menu_choice )
return - 1 ;
MALLOC ( m , newmenu_item , 25 ) ;
if ( ! m )
{
d_free ( menu_choice ) ;
return - 1 ;
}
2010-01-30 22:49:43 +00:00
2010-04-03 08:35:56 +00:00
memset ( menu_choice , 0 , sizeof ( int ) * 25 ) ;
memset ( m , 0 , sizeof ( newmenu_item ) * 25 ) ;
2009-05-03 12:31:30 +00:00
2010-02-07 04:34:21 +00:00
create_main_menu ( m , menu_choice , & num_options ) ; // may have to change, eg, maybe selected pilot and no save games.
2010-06-23 11:44:12 +00:00
newmenu_do3 ( " " , NULL , num_options , m , ( int ( * ) ( newmenu * , d_event * , void * ) ) main_menu_handler , menu_choice , 0 , Menu_pcx_name ) ;
2006-03-20 17:12:09 +00:00
2010-04-03 08:35:56 +00:00
return 0 ;
2006-03-20 17:12:09 +00:00
}
2009-05-03 12:31:30 +00:00
extern void show_order_form ( void ) ; // John didn't want this in inferno.h so I just externed it.
2006-03-20 17:12:09 +00:00
//returns flag, true means quit menu
2010-06-14 08:13:16 +00:00
int do_option ( int select )
2006-03-20 17:12:09 +00:00
{
switch ( select ) {
case MENU_NEW_GAME :
2010-03-18 07:02:38 +00:00
select_mission ( 0 , " New Game \n \n Select mission " , do_new_game_menu ) ;
2006-03-20 17:12:09 +00:00
break ;
case MENU_GAME :
break ;
case MENU_DEMO_PLAY :
2010-02-07 12:10:52 +00:00
select_demo ( ) ;
2006-03-20 17:12:09 +00:00
break ;
case MENU_LOAD_GAME :
state_restore_all ( 0 , 0 , NULL ) ;
break ;
# ifdef EDITOR
case MENU_EDITOR :
2012-04-17 09:37:15 +00:00
if ( ! Current_mission )
{
create_new_mine ( ) ;
SetPlayerFromCurseg ( ) ;
}
2010-06-14 08:13:16 +00:00
2010-04-03 08:35:56 +00:00
hide_menus ( ) ;
2012-03-19 05:49:19 +00:00
init_editor ( ) ;
2006-03-20 17:12:09 +00:00
break ;
# endif
case MENU_VIEW_SCORES :
2010-02-08 04:10:21 +00:00
scores_view ( NULL , - 1 ) ;
2006-03-20 17:12:09 +00:00
break ;
# if 1 //def SHAREWARE
case MENU_ORDER_INFO :
show_order_form ( ) ;
break ;
# endif
case MENU_QUIT :
# ifdef EDITOR
if ( ! SafetyCheck ( ) ) break ;
# endif
2010-04-03 08:35:56 +00:00
return 0 ;
2006-03-20 17:12:09 +00:00
case MENU_NEW_PLAYER :
2010-04-04 09:41:53 +00:00
RegisterPlayer ( ) ;
2006-03-20 17:12:09 +00:00
break ;
2009-11-29 16:46:13 +00:00
# ifdef USE_UDP
2009-11-24 09:48:53 +00:00
case MENU_START_UDP_NETGAME :
multi_protocol = MULTI_PROTO_UDP ;
2010-04-04 09:41:53 +00:00
select_mission ( 1 , TXT_MULTI_MISSION , net_udp_setup_game ) ;
2009-11-24 09:48:53 +00:00
break ;
case MENU_JOIN_MANUAL_UDP_NETGAME :
multi_protocol = MULTI_PROTO_UDP ;
net_udp_manual_join_game ( ) ;
break ;
case MENU_JOIN_LIST_UDP_NETGAME :
multi_protocol = MULTI_PROTO_UDP ;
2010-06-29 16:41:08 +00:00
net_udp_list_join_game ( ) ;
2009-11-24 09:48:53 +00:00
break ;
2009-11-29 16:46:13 +00:00
# endif
2011-09-13 23:15:32 +00:00
# if defined(USE_UDP)
2006-03-20 17:12:09 +00:00
case MENU_MULTIPLAYER :
do_multi_player_menu ( ) ;
break ;
2009-11-29 16:46:13 +00:00
# endif
2006-03-20 17:12:09 +00:00
case MENU_CONFIG :
do_options_menu ( ) ;
break ;
case MENU_SHOW_CREDITS :
2008-10-16 17:27:02 +00:00
credits_show ( NULL ) ;
2006-03-20 17:12:09 +00:00
break ;
2011-07-20 12:44:49 +00:00
# ifndef RELEASE
case MENU_SANDBOX :
do_sandbox_menu ( ) ;
break ;
# endif
2006-03-20 17:12:09 +00:00
default :
Error ( " Unknown option %d in do_option " , select ) ;
break ;
}
2010-04-03 08:35:56 +00:00
return 1 ; // stay in main menu unless quitting
2006-03-20 17:12:09 +00:00
}
2009-12-08 11:01:36 +00:00
void delete_player_saved_games ( char * name )
{
int i ;
2011-02-09 11:58:32 +00:00
char filename [ PATH_MAX ] ;
2010-06-14 08:13:16 +00:00
2009-12-08 11:01:36 +00:00
for ( i = 0 ; i < 10 ; i + + )
{
2011-02-09 11:58:32 +00:00
snprintf ( filename , PATH_MAX , GameArg . SysUsePlayersDir ? " Players/%s.sg%x " : " %s.sg%x " , name , i ) ;
PHYSFS_delete ( filename ) ;
snprintf ( filename , PATH_MAX , GameArg . SysUsePlayersDir ? " Players/%s.mg%x " : " %s.mg%x " , name , i ) ;
2009-12-08 11:01:36 +00:00
PHYSFS_delete ( filename ) ;
}
}
2010-02-07 12:10:52 +00:00
int demo_menu_keycommand ( listbox * lb , d_event * event )
2009-12-08 11:01:36 +00:00
{
2010-01-07 14:49:07 +00:00
char * * items = listbox_get_items ( lb ) ;
int citem = listbox_get_citem ( lb ) ;
2010-06-14 08:13:16 +00:00
2011-01-14 09:51:13 +00:00
switch ( event_key_get ( event ) )
2009-12-08 11:01:36 +00:00
{
case KEY_CTRLED + KEY_D :
2010-02-07 12:10:52 +00:00
if ( citem > = 0 )
2009-12-08 11:01:36 +00:00
{
int x = 1 ;
2010-02-07 12:10:52 +00:00
x = nm_messagebox ( NULL , 2 , TXT_YES , TXT_NO , " %s %s? " , TXT_DELETE_DEMO , items [ citem ] + ( ( items [ citem ] [ 0 ] = = ' $ ' ) ? 1 : 0 ) ) ;
if ( x = = 0 )
{
2009-12-08 11:01:36 +00:00
int ret ;
char name [ PATH_MAX ] ;
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
strcpy ( name , DEMO_DIR ) ;
2010-01-07 14:49:07 +00:00
strcat ( name , items [ citem ] ) ;
2010-06-14 08:13:16 +00:00
2009-12-08 11:01:36 +00:00
ret = ! PHYSFS_delete ( name ) ;
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
if ( ret )
nm_messagebox ( NULL , 1 , TXT_OK , " %s %s %s " , TXT_COULDNT , TXT_DELETE_DEMO , items [ citem ] + ( ( items [ citem ] [ 0 ] = = ' $ ' ) ? 1 : 0 ) ) ;
2010-01-07 14:49:07 +00:00
else
listbox_delete_item ( lb , citem ) ;
2009-12-08 11:01:36 +00:00
}
2010-06-14 08:13:16 +00:00
2010-01-07 14:49:07 +00:00
return 1 ;
2009-12-08 11:01:36 +00:00
}
break ;
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
case KEY_CTRLED + KEY_C :
2009-12-08 11:01:36 +00:00
{
int x = 1 ;
char bakname [ PATH_MAX ] ;
2010-06-14 08:13:16 +00:00
2009-12-08 11:01:36 +00:00
// Get backup name
2010-02-07 12:10:52 +00:00
change_filename_extension ( bakname , items [ citem ] + ( ( items [ citem ] [ 0 ] = = ' $ ' ) ? 1 : 0 ) , DEMO_BACKUP_EXT ) ;
2009-12-08 11:01:36 +00:00
x = nm_messagebox ( NULL , 2 , TXT_YES , TXT_NO , " Are you sure you want to \n "
" swap the endianness of \n "
" %s? If the file is \n "
" already endian native, D1X \n "
" will likely crash. A backup \n "
2010-02-07 12:10:52 +00:00
" %s will be created " , items [ citem ] + ( ( items [ citem ] [ 0 ] = = ' $ ' ) ? 1 : 0 ) , bakname ) ;
2010-01-07 14:49:07 +00:00
if ( ! x )
newdemo_swap_endian ( items [ citem ] ) ;
2010-06-14 08:13:16 +00:00
2010-01-07 14:49:07 +00:00
return 1 ;
2009-12-08 11:01:36 +00:00
}
break ;
}
2010-06-14 08:13:16 +00:00
2010-02-06 05:21:45 +00:00
return 0 ;
}
2010-02-07 12:10:52 +00:00
int demo_menu_handler ( listbox * lb , d_event * event , void * userdata )
2010-02-06 05:21:45 +00:00
{
char * * items = listbox_get_items ( lb ) ;
int citem = listbox_get_citem ( lb ) ;
2010-02-07 12:10:52 +00:00
userdata = userdata ;
2010-06-14 08:13:16 +00:00
2010-02-06 05:21:45 +00:00
switch ( event - > type )
{
case EVENT_KEY_COMMAND :
2010-02-07 12:10:52 +00:00
return demo_menu_keycommand ( lb , event ) ;
2010-02-06 05:21:45 +00:00
break ;
2010-06-14 08:13:16 +00:00
2010-02-06 05:21:45 +00:00
case EVENT_NEWMENU_SELECTED :
if ( citem < 0 )
return 0 ; // shouldn't happen
2010-02-07 12:10:52 +00:00
newdemo_start_playback ( items [ citem ] ) ;
2010-04-02 05:24:47 +00:00
return 1 ; // stay in demo selector
2010-06-14 08:13:16 +00:00
2010-02-06 05:21:45 +00:00
case EVENT_WINDOW_CLOSE :
2010-02-07 12:10:52 +00:00
PHYSFS_freeList ( items ) ;
2010-02-06 05:21:45 +00:00
break ;
2010-06-14 08:13:16 +00:00
2010-02-06 05:21:45 +00:00
default :
break ;
}
2009-12-08 11:01:36 +00:00
2010-01-07 14:49:07 +00:00
return 0 ;
2009-12-08 11:01:36 +00:00
}
2010-02-07 12:10:52 +00:00
int select_demo ( void )
2009-12-08 11:01:36 +00:00
{
2010-02-07 12:10:52 +00:00
char * * list ;
2012-07-22 23:17:54 +00:00
static const char * const types [ ] = { DEMO_EXT , NULL } ;
2010-02-07 12:10:52 +00:00
int NumItems ;
2010-06-14 08:13:16 +00:00
2010-02-07 12:10:52 +00:00
list = PHYSFSX_findFiles ( DEMO_DIR , types ) ;
if ( ! list )
2009-12-08 11:01:36 +00:00
return 0 ; // memory error
2010-02-07 12:10:52 +00:00
if ( ! * list )
2009-12-08 11:01:36 +00:00
{
nm_messagebox ( NULL , 1 , TXT_OK , " %s %s \n %s " , TXT_NO_DEMO_FILES , TXT_USE_F5 , TXT_TO_CREATE_ONE ) ;
2010-02-07 12:10:52 +00:00
PHYSFS_freeList ( list ) ;
2009-12-08 11:01:36 +00:00
return 0 ;
2010-06-14 08:13:16 +00:00
}
2010-02-07 12:10:52 +00:00
for ( NumItems = 0 ; list [ NumItems ] ! = NULL ; NumItems + + ) { }
2009-12-08 11:01:36 +00:00
2010-02-07 12:10:52 +00:00
// Sort by name
2010-09-26 13:15:20 +00:00
qsort ( list , NumItems , sizeof ( char * ) , ( int ( * ) ( const void * , const void * ) ) string_array_sort_func ) ;
2009-12-08 11:01:36 +00:00
2010-02-07 12:10:52 +00:00
newmenu_listbox1 ( TXT_SELECT_DEMO , NumItems , list , 1 , 0 , demo_menu_handler , NULL ) ;
2010-06-14 08:13:16 +00:00
2009-12-08 11:01:36 +00:00
return 1 ;
}
2006-03-20 17:12:09 +00:00
int do_difficulty_menu ( )
{
int s ;
newmenu_item m [ 5 ] ;
m [ 0 ] . type = NM_TYPE_MENU ; m [ 0 ] . text = MENU_DIFFICULTY_TEXT ( 0 ) ;
m [ 1 ] . type = NM_TYPE_MENU ; m [ 1 ] . text = MENU_DIFFICULTY_TEXT ( 1 ) ;
m [ 2 ] . type = NM_TYPE_MENU ; m [ 2 ] . text = MENU_DIFFICULTY_TEXT ( 2 ) ;
m [ 3 ] . type = NM_TYPE_MENU ; m [ 3 ] . text = MENU_DIFFICULTY_TEXT ( 3 ) ;
m [ 4 ] . type = NM_TYPE_MENU ; m [ 4 ] . text = MENU_DIFFICULTY_TEXT ( 4 ) ;
2010-01-07 14:49:07 +00:00
s = newmenu_do1 ( NULL , TXT_DIFFICULTY_LEVEL , NDL , m , NULL , NULL , Difficulty_level ) ;
2006-03-20 17:12:09 +00:00
2009-05-03 12:31:30 +00:00
if ( s > - 1 ) {
2006-03-20 17:12:09 +00:00
if ( s ! = Difficulty_level )
{
2008-04-13 00:28:36 +00:00
PlayerCfg . DefaultDifficulty = s ;
2006-03-20 17:12:09 +00:00
write_player_file ( ) ;
}
Difficulty_level = s ;
return 1 ;
}
return 0 ;
}
2010-03-18 07:02:38 +00:00
int do_new_game_menu ( )
2006-03-20 17:12:09 +00:00
{
int new_level_num , player_highest_level ;
new_level_num = 1 ;
2011-05-15 23:46:26 +00:00
# ifdef NDEBUG
2006-03-20 17:12:09 +00:00
player_highest_level = get_highest_level ( ) ;
if ( player_highest_level > Last_level )
2011-05-15 23:46:26 +00:00
# endif
2006-03-20 17:12:09 +00:00
player_highest_level = Last_level ;
if ( player_highest_level > 1 ) {
newmenu_item m [ 4 ] ;
char info_text [ 80 ] ;
char num_text [ 10 ] ;
int choice ;
int n_items ;
2011-05-15 23:46:26 +00:00
int valid = 0 ;
2006-03-20 17:12:09 +00:00
2011-05-15 23:46:26 +00:00
while ( ! valid )
{
sprintf ( info_text , " %s %d " , TXT_START_ANY_LEVEL , player_highest_level ) ;
2006-03-20 17:12:09 +00:00
2011-05-15 23:46:26 +00:00
m [ 0 ] . type = NM_TYPE_TEXT ; m [ 0 ] . text = info_text ;
m [ 1 ] . type = NM_TYPE_INPUT ; m [ 1 ] . text_len = 10 ; m [ 1 ] . text = num_text ;
n_items = 2 ;
2006-03-20 17:12:09 +00:00
2011-05-15 23:46:26 +00:00
strcpy ( num_text , " 1 " ) ;
2006-03-20 17:12:09 +00:00
2011-05-15 23:46:26 +00:00
choice = newmenu_do ( NULL , TXT_SELECT_START_LEV , n_items , m , NULL , NULL ) ;
2006-03-20 17:12:09 +00:00
2011-05-15 23:46:26 +00:00
if ( choice = = - 1 | | m [ 1 ] . text [ 0 ] = = 0 )
return 0 ;
2006-03-20 17:12:09 +00:00
2011-05-15 23:46:26 +00:00
new_level_num = atoi ( m [ 1 ] . text ) ;
2006-03-20 17:12:09 +00:00
2011-05-15 23:46:26 +00:00
if ( ! ( new_level_num > 0 & & new_level_num < = player_highest_level ) ) {
m [ 0 ] . text = TXT_ENTER_TO_CONT ;
nm_messagebox ( NULL , 1 , TXT_OK , TXT_INVALID_LEVEL ) ;
valid = 0 ;
}
else
valid = 1 ;
2006-03-20 17:12:09 +00:00
}
}
2007-09-28 22:44:04 +00:00
2008-04-13 00:28:36 +00:00
Difficulty_level = PlayerCfg . DefaultDifficulty ;
2006-03-20 17:12:09 +00:00
if ( ! do_difficulty_menu ( ) )
2010-03-18 07:02:38 +00:00
return 0 ;
2006-03-20 17:12:09 +00:00
StartNewGame ( new_level_num ) ;
2010-03-18 07:02:38 +00:00
return 1 ; // exit mission listbox
}
2010-01-17 14:42:59 +00:00
void do_sound_menu ( ) ;
void input_config ( ) ;
void change_res ( ) ;
2011-01-10 15:12:04 +00:00
void graphics_config ( ) ;
2010-01-17 14:42:59 +00:00
void do_misc_menu ( ) ;
2010-01-07 14:49:07 +00:00
int options_menuset ( newmenu * menu , d_event * event , void * userdata )
2006-03-20 17:12:09 +00:00
{
2010-01-17 14:42:59 +00:00
switch ( event - > type )
2006-03-20 17:12:09 +00:00
{
2010-02-01 06:55:38 +00:00
case EVENT_NEWMENU_CHANGED :
2010-01-17 14:42:59 +00:00
break ;
2010-06-14 08:13:16 +00:00
2010-01-17 14:42:59 +00:00
case EVENT_NEWMENU_SELECTED :
switch ( newmenu_get_citem ( menu ) )
{
case 0 : do_sound_menu ( ) ; break ;
case 2 : input_config ( ) ; break ;
2011-01-10 15:12:04 +00:00
case 4 : change_res ( ) ; break ;
case 5 : graphics_config ( ) ; break ;
case 7 : ReorderPrimary ( ) ; break ;
case 8 : ReorderSecondary ( ) ; break ;
case 9 : do_misc_menu ( ) ; break ;
2010-01-17 14:42:59 +00:00
}
2010-01-30 03:24:19 +00:00
return 1 ; // stay in menu until escape
break ;
2010-06-14 08:13:16 +00:00
2010-01-20 05:10:32 +00:00
case EVENT_WINDOW_CLOSE :
2010-04-04 09:41:53 +00:00
{
newmenu_item * items = newmenu_get_items ( menu ) ;
d_free ( items ) ;
2010-01-17 14:42:59 +00:00
write_player_file ( ) ;
break ;
2010-04-04 09:41:53 +00:00
}
2010-06-14 08:13:16 +00:00
2010-01-30 03:24:19 +00:00
default :
break ;
2006-03-20 17:12:09 +00:00
}
2010-10-10 10:48:24 +00:00
userdata = userdata ; //kill warning
2010-06-14 08:13:16 +00:00
2010-01-30 03:24:19 +00:00
return 0 ;
2006-03-20 17:12:09 +00:00
}
2008-10-19 12:53:30 +00:00
int gcd ( int a , int b )
2006-03-20 17:12:09 +00:00
{
2008-10-19 12:53:30 +00:00
if ( ! b )
2010-06-14 08:13:16 +00:00
return a ;
2008-10-19 12:53:30 +00:00
return gcd ( b , a % b ) ;
2006-03-20 17:12:09 +00:00
}
void change_res ( )
{
2010-06-24 09:29:11 +00:00
u_int32_t modes [ 50 ] , new_mode = 0 ;
2011-05-15 23:46:26 +00:00
int i = 0 , mc = 0 , num_presets = 0 , citem = - 1 , opt_cval = - 1 , opt_fullscr = - 1 ;
2010-06-24 09:29:11 +00:00
num_presets = gr_list_modes ( modes ) ;
{
2010-10-10 10:48:24 +00:00
newmenu_item m [ 50 + 8 ] ;
char restext [ 50 ] [ 12 ] , crestext [ 12 ] , casptext [ 12 ] ;
2010-06-24 09:29:11 +00:00
for ( i = 0 ; i < = num_presets - 1 ; i + + )
{
snprintf ( restext [ mc ] , sizeof ( restext [ mc ] ) , " %ix%i " , SM_W ( modes [ i ] ) , SM_H ( modes [ i ] ) ) ;
m [ mc ] . type = NM_TYPE_RADIO ;
m [ mc ] . text = restext [ mc ] ;
m [ mc ] . value = ( ( citem = = - 1 ) & & ( Game_screen_mode = = modes [ i ] ) & & GameCfg . AspectY = = SM_W ( modes [ i ] ) / gcd ( SM_W ( modes [ i ] ) , SM_H ( modes [ i ] ) ) & & GameCfg . AspectX = = SM_H ( modes [ i ] ) / gcd ( SM_W ( modes [ i ] ) , SM_H ( modes [ i ] ) ) ) ;
m [ mc ] . group = 0 ;
2006-03-20 17:12:09 +00:00
if ( m [ mc ] . value )
2010-06-24 09:29:11 +00:00
citem = mc ;
mc + + ;
}
2008-10-19 12:53:30 +00:00
2010-06-24 09:29:11 +00:00
m [ mc ] . type = NM_TYPE_TEXT ; m [ mc ] . text = " " ; mc + + ; // little space for overview
// the fields for custom resolution and aspect
opt_cval = mc ;
m [ mc ] . type = NM_TYPE_RADIO ; m [ mc ] . text = " use custom values " ; m [ mc ] . value = ( citem = = - 1 ) ; m [ mc ] . group = 0 ; mc + + ;
2008-10-19 12:53:30 +00:00
m [ mc ] . type = NM_TYPE_TEXT ; m [ mc ] . text = " resolution: " ; mc + + ;
2010-06-24 09:29:11 +00:00
snprintf ( crestext , sizeof ( crestext ) , " %ix%i " , SM_W ( Game_screen_mode ) , SM_H ( Game_screen_mode ) ) ;
m [ mc ] . type = NM_TYPE_INPUT ; m [ mc ] . text = crestext ; m [ mc ] . text_len = 11 ; modes [ mc ] = 0 ; mc + + ;
2008-04-06 20:23:28 +00:00
m [ mc ] . type = NM_TYPE_TEXT ; m [ mc ] . text = " aspect: " ; mc + + ;
2010-06-24 09:29:11 +00:00
snprintf ( casptext , sizeof ( casptext ) , " %ix%i " , GameCfg . AspectY , GameCfg . AspectX ) ;
m [ mc ] . type = NM_TYPE_INPUT ; m [ mc ] . text = casptext ; m [ mc ] . text_len = 11 ; modes [ mc ] = 0 ; mc + + ;
m [ mc ] . type = NM_TYPE_TEXT ; m [ mc ] . text = " " ; mc + + ; // little space for overview
// fullscreen
opt_fullscr = mc ;
m [ mc ] . type = NM_TYPE_CHECK ; m [ mc ] . text = " Fullscreen " ; m [ mc ] . value = gr_check_fullscreen ( ) ; mc + + ;
2008-04-06 20:23:28 +00:00
2008-10-19 12:53:30 +00:00
// create the menu
2010-06-24 09:29:11 +00:00
newmenu_do1 ( NULL , " Screen Resolution " , mc , m , NULL , NULL , 0 ) ;
2008-10-19 12:53:30 +00:00
// menu is done, now do what we need to do
2006-08-30 18:12:04 +00:00
2010-06-24 09:29:11 +00:00
// check which resolution field was selected
for ( i = 0 ; i < = mc ; i + + )
if ( ( m [ i ] . type = = NM_TYPE_RADIO ) & & ( m [ i ] . group = = 0 ) & & ( m [ i ] . value = = 1 ) )
break ;
2008-10-19 12:53:30 +00:00
// now check for fullscreen toggle and apply if necessary
2010-06-24 09:29:11 +00:00
if ( m [ opt_fullscr ] . value ! = gr_check_fullscreen ( ) )
2006-03-20 17:12:09 +00:00
gr_toggle_fullscreen ( ) ;
2010-06-24 09:29:11 +00:00
if ( i = = opt_cval ) // set custom resolution and aspect
2006-03-20 17:12:09 +00:00
{
2010-06-24 09:29:11 +00:00
u_int32_t cmode = Game_screen_mode , casp = Game_screen_mode ;
if ( ! strchr ( crestext , ' x ' ) )
2006-03-20 17:12:09 +00:00
return ;
2008-10-19 12:53:30 +00:00
2010-06-24 09:29:11 +00:00
cmode = SM ( atoi ( crestext ) , atoi ( strchr ( crestext , ' x ' ) + 1 ) ) ;
if ( SM_W ( cmode ) < 320 | | SM_H ( cmode ) < 200 ) // oh oh - the resolution is too small. Revert!
2008-10-19 12:53:30 +00:00
{
nm_messagebox ( TXT_WARNING , 1 , " OK " , " Entered resolution is too small. \n Reverting ... " ) ;
2010-06-24 09:29:11 +00:00
cmode = new_mode ;
2008-10-19 12:53:30 +00:00
}
2010-06-24 09:29:11 +00:00
casp = cmode ;
if ( strchr ( casptext , ' x ' ) ) // we even have a custom aspect set up
2008-10-19 12:53:30 +00:00
{
2010-06-24 09:29:11 +00:00
casp = SM ( atoi ( casptext ) , atoi ( strchr ( casptext , ' x ' ) + 1 ) ) ;
2008-10-19 12:53:30 +00:00
}
2010-06-24 09:29:11 +00:00
GameCfg . AspectY = SM_W ( casp ) / gcd ( SM_W ( casp ) , SM_H ( casp ) ) ;
GameCfg . AspectX = SM_H ( casp ) / gcd ( SM_W ( casp ) , SM_H ( casp ) ) ;
new_mode = cmode ;
2006-03-20 17:12:09 +00:00
}
2010-06-24 09:29:11 +00:00
else if ( i > = 0 & & i < num_presets ) // set preset resolution
2006-03-20 17:12:09 +00:00
{
2010-06-24 09:29:11 +00:00
new_mode = modes [ i ] ;
GameCfg . AspectY = SM_W ( new_mode ) / gcd ( SM_W ( new_mode ) , SM_H ( new_mode ) ) ;
GameCfg . AspectX = SM_H ( new_mode ) / gcd ( SM_W ( new_mode ) , SM_H ( new_mode ) ) ;
2006-03-20 17:12:09 +00:00
}
2008-10-19 12:53:30 +00:00
// clean up and apply everything
2010-07-31 12:09:38 +00:00
newmenu_free_background ( ) ;
2007-07-26 23:57:29 +00:00
set_screen_mode ( SCREEN_MENU ) ;
2010-06-24 09:29:11 +00:00
if ( new_mode ! = Game_screen_mode )
2011-01-16 01:09:47 +00:00
{
2010-06-24 09:29:11 +00:00
gr_set_mode ( new_mode ) ;
2011-01-16 01:09:47 +00:00
Game_screen_mode = new_mode ;
if ( Game_wind ) // shortly activate Game_wind so it's canvas will align to new resolution. really minor glitch but whatever
{
d_event event ;
WINDOW_SEND_EVENT ( Game_wind , EVENT_WINDOW_ACTIVATED ) ;
WINDOW_SEND_EVENT ( Game_wind , EVENT_WINDOW_DEACTIVATED ) ;
}
}
2012-05-26 22:24:57 +00:00
game_init_render_buffers ( SM_W ( Game_screen_mode ) , SM_H ( Game_screen_mode ) ) ;
2010-06-24 09:29:11 +00:00
}
2006-03-20 17:12:09 +00:00
}
2010-12-28 18:11:10 +00:00
void input_config_sensitivity ( )
{
2012-06-01 09:53:59 +00:00
newmenu_item m [ 33 ] ;
int i = 0 , nitems = 0 , keysens = 0 , joysens = 0 , joydead = 0 , mousesens = 0 , mousefsdead ;
m [ nitems ] . type = NM_TYPE_TEXT ; m [ nitems ] . text = " Keyboard Sensitivity: " ; nitems + + ;
keysens = nitems ;
m [ nitems ] . type = NM_TYPE_SLIDER ; m [ nitems ] . text = TXT_TURN_LR ; m [ nitems ] . value = PlayerCfg . KeyboardSens [ 0 ] ; m [ nitems ] . min_value = 0 ; m [ nitems ] . max_value = 16 ; nitems + + ;
m [ nitems ] . type = NM_TYPE_SLIDER ; m [ nitems ] . text = TXT_PITCH_UD ; m [ nitems ] . value = PlayerCfg . KeyboardSens [ 1 ] ; m [ nitems ] . min_value = 0 ; m [ nitems ] . max_value = 16 ; nitems + + ;
m [ nitems ] . type = NM_TYPE_SLIDER ; m [ nitems ] . text = TXT_SLIDE_LR ; m [ nitems ] . value = PlayerCfg . KeyboardSens [ 2 ] ; m [ nitems ] . min_value = 0 ; m [ nitems ] . max_value = 16 ; nitems + + ;
m [ nitems ] . type = NM_TYPE_SLIDER ; m [ nitems ] . text = TXT_SLIDE_UD ; m [ nitems ] . value = PlayerCfg . KeyboardSens [ 3 ] ; m [ nitems ] . min_value = 0 ; m [ nitems ] . max_value = 16 ; nitems + + ;
m [ nitems ] . type = NM_TYPE_SLIDER ; m [ nitems ] . text = TXT_BANK_LR ; m [ nitems ] . value = PlayerCfg . KeyboardSens [ 4 ] ; m [ nitems ] . min_value = 0 ; m [ nitems ] . max_value = 16 ; nitems + + ;
m [ nitems ] . type = NM_TYPE_TEXT ; m [ nitems ] . text = " " ; nitems + + ;
2010-12-28 18:11:10 +00:00
m [ nitems ] . type = NM_TYPE_TEXT ; m [ nitems ] . text = " Joystick Sensitivity: " ; nitems + + ;
joysens = nitems ;
m [ nitems ] . type = NM_TYPE_SLIDER ; m [ nitems ] . text = TXT_TURN_LR ; m [ nitems ] . value = PlayerCfg . JoystickSens [ 0 ] ; m [ nitems ] . min_value = 0 ; m [ nitems ] . max_value = 16 ; nitems + + ;
m [ nitems ] . type = NM_TYPE_SLIDER ; m [ nitems ] . text = TXT_PITCH_UD ; m [ nitems ] . value = PlayerCfg . JoystickSens [ 1 ] ; m [ nitems ] . min_value = 0 ; m [ nitems ] . max_value = 16 ; nitems + + ;
m [ nitems ] . type = NM_TYPE_SLIDER ; m [ nitems ] . text = TXT_SLIDE_LR ; m [ nitems ] . value = PlayerCfg . JoystickSens [ 2 ] ; m [ nitems ] . min_value = 0 ; m [ nitems ] . max_value = 16 ; nitems + + ;
m [ nitems ] . type = NM_TYPE_SLIDER ; m [ nitems ] . text = TXT_SLIDE_UD ; m [ nitems ] . value = PlayerCfg . JoystickSens [ 3 ] ; m [ nitems ] . min_value = 0 ; m [ nitems ] . max_value = 16 ; nitems + + ;
m [ nitems ] . type = NM_TYPE_SLIDER ; m [ nitems ] . text = TXT_BANK_LR ; m [ nitems ] . value = PlayerCfg . JoystickSens [ 4 ] ; m [ nitems ] . min_value = 0 ; m [ nitems ] . max_value = 16 ; nitems + + ;
2011-09-26 18:22:38 +00:00
m [ nitems ] . type = NM_TYPE_SLIDER ; m [ nitems ] . text = TXT_THROTTLE ; m [ nitems ] . value = PlayerCfg . JoystickSens [ 5 ] ; m [ nitems ] . min_value = 0 ; m [ nitems ] . max_value = 16 ; nitems + + ;
2010-12-28 18:11:10 +00:00
m [ nitems ] . type = NM_TYPE_TEXT ; m [ nitems ] . text = " " ; nitems + + ;
m [ nitems ] . type = NM_TYPE_TEXT ; m [ nitems ] . text = " Joystick Deadzone: " ; nitems + + ;
joydead = nitems ;
m [ nitems ] . type = NM_TYPE_SLIDER ; m [ nitems ] . text = TXT_TURN_LR ; m [ nitems ] . value = PlayerCfg . JoystickDead [ 0 ] ; m [ nitems ] . min_value = 0 ; m [ nitems ] . max_value = 16 ; nitems + + ;
m [ nitems ] . type = NM_TYPE_SLIDER ; m [ nitems ] . text = TXT_PITCH_UD ; m [ nitems ] . value = PlayerCfg . JoystickDead [ 1 ] ; m [ nitems ] . min_value = 0 ; m [ nitems ] . max_value = 16 ; nitems + + ;
m [ nitems ] . type = NM_TYPE_SLIDER ; m [ nitems ] . text = TXT_SLIDE_LR ; m [ nitems ] . value = PlayerCfg . JoystickDead [ 2 ] ; m [ nitems ] . min_value = 0 ; m [ nitems ] . max_value = 16 ; nitems + + ;
m [ nitems ] . type = NM_TYPE_SLIDER ; m [ nitems ] . text = TXT_SLIDE_UD ; m [ nitems ] . value = PlayerCfg . JoystickDead [ 3 ] ; m [ nitems ] . min_value = 0 ; m [ nitems ] . max_value = 16 ; nitems + + ;
m [ nitems ] . type = NM_TYPE_SLIDER ; m [ nitems ] . text = TXT_BANK_LR ; m [ nitems ] . value = PlayerCfg . JoystickDead [ 4 ] ; m [ nitems ] . min_value = 0 ; m [ nitems ] . max_value = 16 ; nitems + + ;
2011-09-26 18:22:38 +00:00
m [ nitems ] . type = NM_TYPE_SLIDER ; m [ nitems ] . text = TXT_THROTTLE ; m [ nitems ] . value = PlayerCfg . JoystickDead [ 5 ] ; m [ nitems ] . min_value = 0 ; m [ nitems ] . max_value = 16 ; nitems + + ;
2010-12-28 18:11:10 +00:00
m [ nitems ] . type = NM_TYPE_TEXT ; m [ nitems ] . text = " " ; nitems + + ;
m [ nitems ] . type = NM_TYPE_TEXT ; m [ nitems ] . text = " Mouse Sensitivity: " ; nitems + + ;
mousesens = nitems ;
m [ nitems ] . type = NM_TYPE_SLIDER ; m [ nitems ] . text = TXT_TURN_LR ; m [ nitems ] . value = PlayerCfg . MouseSens [ 0 ] ; m [ nitems ] . min_value = 0 ; m [ nitems ] . max_value = 16 ; nitems + + ;
m [ nitems ] . type = NM_TYPE_SLIDER ; m [ nitems ] . text = TXT_PITCH_UD ; m [ nitems ] . value = PlayerCfg . MouseSens [ 1 ] ; m [ nitems ] . min_value = 0 ; m [ nitems ] . max_value = 16 ; nitems + + ;
m [ nitems ] . type = NM_TYPE_SLIDER ; m [ nitems ] . text = TXT_SLIDE_LR ; m [ nitems ] . value = PlayerCfg . MouseSens [ 2 ] ; m [ nitems ] . min_value = 0 ; m [ nitems ] . max_value = 16 ; nitems + + ;
m [ nitems ] . type = NM_TYPE_SLIDER ; m [ nitems ] . text = TXT_SLIDE_UD ; m [ nitems ] . value = PlayerCfg . MouseSens [ 3 ] ; m [ nitems ] . min_value = 0 ; m [ nitems ] . max_value = 16 ; nitems + + ;
m [ nitems ] . type = NM_TYPE_SLIDER ; m [ nitems ] . text = TXT_BANK_LR ; m [ nitems ] . value = PlayerCfg . MouseSens [ 4 ] ; m [ nitems ] . min_value = 0 ; m [ nitems ] . max_value = 16 ; nitems + + ;
2011-09-26 18:22:38 +00:00
m [ nitems ] . type = NM_TYPE_SLIDER ; m [ nitems ] . text = TXT_THROTTLE ; m [ nitems ] . value = PlayerCfg . MouseSens [ 5 ] ; m [ nitems ] . min_value = 0 ; m [ nitems ] . max_value = 16 ; nitems + + ;
2011-01-04 10:43:37 +00:00
m [ nitems ] . type = NM_TYPE_TEXT ; m [ nitems ] . text = " " ; nitems + + ;
m [ nitems ] . type = NM_TYPE_TEXT ; m [ nitems ] . text = " Mouse FlightSim Deadzone: " ; nitems + + ;
mousefsdead = nitems ;
m [ nitems ] . type = NM_TYPE_SLIDER ; m [ nitems ] . text = " X/Y " ; m [ nitems ] . value = PlayerCfg . MouseFSDead ; m [ nitems ] . min_value = 0 ; m [ nitems ] . max_value = 16 ; nitems + + ;
2010-12-28 18:11:10 +00:00
newmenu_do1 ( NULL , " SENSITIVITY & DEADZONE " , nitems , m , NULL , NULL , 1 ) ;
2011-09-26 18:22:38 +00:00
for ( i = 0 ; i < = 5 ; i + + )
2010-12-28 18:11:10 +00:00
{
2012-06-01 09:53:59 +00:00
if ( i < 5 )
PlayerCfg . KeyboardSens [ i ] = m [ keysens + i ] . value ;
2010-12-28 18:11:10 +00:00
PlayerCfg . JoystickSens [ i ] = m [ joysens + i ] . value ;
PlayerCfg . JoystickDead [ i ] = m [ joydead + i ] . value ;
PlayerCfg . MouseSens [ i ] = m [ mousesens + i ] . value ;
}
2011-01-04 10:43:37 +00:00
PlayerCfg . MouseFSDead = m [ mousefsdead ] . value ;
2010-12-28 18:11:10 +00:00
}
2011-04-22 11:01:38 +00:00
static int opt_ic_usejoy = 0 , opt_ic_usemouse = 0 , opt_ic_confkey = 0 , opt_ic_confjoy = 0 , opt_ic_confmouse = 0 , opt_ic_confweap = 0 , opt_ic_mouseflightsim = 0 , opt_ic_joymousesens = 0 , opt_ic_grabinput = 0 , opt_ic_mousefsgauge = 0 , opt_ic_help0 = 0 , opt_ic_help1 = 0 , opt_ic_help2 = 0 ;
2010-12-28 18:11:10 +00:00
int input_config_menuset ( newmenu * menu , d_event * event , void * userdata )
2008-02-24 14:41:27 +00:00
{
2010-01-07 14:49:07 +00:00
newmenu_item * items = newmenu_get_items ( menu ) ;
2010-01-17 14:42:59 +00:00
int citem = newmenu_get_citem ( menu ) ;
2008-02-24 14:41:27 +00:00
2010-01-07 14:49:07 +00:00
userdata = userdata ;
2008-02-24 14:41:27 +00:00
2010-01-17 14:42:59 +00:00
switch ( event - > type )
{
2010-02-01 06:55:38 +00:00
case EVENT_NEWMENU_CHANGED :
2010-12-28 18:11:10 +00:00
if ( citem = = opt_ic_usejoy )
( items [ citem ] . value ) ? ( PlayerCfg . ControlType | = CONTROL_USING_JOYSTICK ) : ( PlayerCfg . ControlType & = ~ CONTROL_USING_JOYSTICK ) ;
if ( citem = = opt_ic_usemouse )
( items [ citem ] . value ) ? ( PlayerCfg . ControlType | = CONTROL_USING_MOUSE ) : ( PlayerCfg . ControlType & = ~ CONTROL_USING_MOUSE ) ;
2011-01-04 10:43:37 +00:00
if ( citem = = opt_ic_mouseflightsim )
PlayerCfg . MouseFlightSim = 0 ;
if ( citem = = opt_ic_mouseflightsim + 1 )
PlayerCfg . MouseFlightSim = 1 ;
2010-12-28 18:11:10 +00:00
if ( citem = = opt_ic_grabinput )
GameCfg . Grabinput = items [ citem ] . value ;
2011-01-04 10:43:37 +00:00
if ( citem = = opt_ic_mousefsgauge )
2011-01-10 15:12:04 +00:00
PlayerCfg . MouseFSIndicator = items [ citem ] . value ;
2010-01-17 14:42:59 +00:00
break ;
2010-06-14 08:13:16 +00:00
2010-01-17 14:42:59 +00:00
case EVENT_NEWMENU_SELECTED :
2010-12-28 18:11:10 +00:00
if ( citem = = opt_ic_confkey )
kconfig ( 0 , " KEYBOARD " ) ;
if ( citem = = opt_ic_confjoy )
kconfig ( 1 , " JOYSTICK " ) ;
if ( citem = = opt_ic_confmouse )
kconfig ( 2 , " MOUSE " ) ;
if ( citem = = opt_ic_confweap )
kconfig ( 3 , " WEAPON KEYS " ) ;
if ( citem = = opt_ic_joymousesens )
input_config_sensitivity ( ) ;
if ( citem = = opt_ic_help0 )
show_help ( ) ;
if ( citem = = opt_ic_help1 )
show_netgame_help ( ) ;
if ( citem = = opt_ic_help2 )
show_newdemo_help ( ) ;
2010-01-30 03:24:19 +00:00
return 1 ; // stay in menu
break ;
2010-06-14 08:13:16 +00:00
2010-01-17 14:42:59 +00:00
default :
2010-01-30 03:24:19 +00:00
break ;
2008-02-24 14:41:27 +00:00
}
2010-06-14 08:13:16 +00:00
2010-01-30 03:24:19 +00:00
return 0 ;
2008-02-24 14:41:27 +00:00
}
void input_config ( )
{
2011-04-22 11:01:38 +00:00
newmenu_item m [ 20 ] ;
2010-12-28 18:11:10 +00:00
int nitems = 0 ;
opt_ic_usejoy = nitems ;
m [ nitems ] . type = NM_TYPE_CHECK ; m [ nitems ] . text = " USE JOYSTICK " ; m [ nitems ] . value = ( PlayerCfg . ControlType & CONTROL_USING_JOYSTICK ) ; nitems + + ;
opt_ic_usemouse = nitems ;
m [ nitems ] . type = NM_TYPE_CHECK ; m [ nitems ] . text = " USE MOUSE " ; m [ nitems ] . value = ( PlayerCfg . ControlType & CONTROL_USING_MOUSE ) ; nitems + + ;
m [ nitems ] . type = NM_TYPE_TEXT ; m [ nitems ] . text = " " ; nitems + + ;
opt_ic_confkey = nitems ;
m [ nitems ] . type = NM_TYPE_MENU ; m [ nitems ] . text = " CUSTOMIZE KEYBOARD " ; nitems + + ;
opt_ic_confjoy = nitems ;
m [ nitems ] . type = NM_TYPE_MENU ; m [ nitems ] . text = " CUSTOMIZE JOYSTICK " ; nitems + + ;
opt_ic_confmouse = nitems ;
m [ nitems ] . type = NM_TYPE_MENU ; m [ nitems ] . text = " CUSTOMIZE MOUSE " ; nitems + + ;
opt_ic_confweap = nitems ;
m [ nitems ] . type = NM_TYPE_MENU ; m [ nitems ] . text = " CUSTOMIZE WEAPON KEYS " ; nitems + + ;
m [ nitems ] . type = NM_TYPE_TEXT ; m [ nitems ] . text = " " ; nitems + + ;
2011-01-04 10:43:37 +00:00
m [ nitems ] . type = NM_TYPE_TEXT ; m [ nitems ] . text = " MOUSE CONTROL TYPE: " ; nitems + + ;
opt_ic_mouseflightsim = nitems ;
m [ nitems ] . type = NM_TYPE_RADIO ; m [ nitems ] . text = " normal " ; m [ nitems ] . value = ! PlayerCfg . MouseFlightSim ; m [ nitems ] . group = 0 ; nitems + + ;
m [ nitems ] . type = NM_TYPE_RADIO ; m [ nitems ] . text = " FlightSim " ; m [ nitems ] . value = PlayerCfg . MouseFlightSim ; m [ nitems ] . group = 0 ; nitems + + ;
m [ nitems ] . type = NM_TYPE_TEXT ; m [ nitems ] . text = " " ; nitems + + ;
2010-12-28 18:11:10 +00:00
opt_ic_joymousesens = nitems ;
m [ nitems ] . type = NM_TYPE_MENU ; m [ nitems ] . text = " SENSITIVITY & DEADZONE " ; nitems + + ;
m [ nitems ] . type = NM_TYPE_TEXT ; m [ nitems ] . text = " " ; nitems + + ;
opt_ic_grabinput = nitems ;
2010-12-30 22:36:41 +00:00
m [ nitems ] . type = NM_TYPE_CHECK ; m [ nitems ] . text = " Keep Keyboard/Mouse focus " ; m [ nitems ] . value = GameCfg . Grabinput ; nitems + + ;
2011-01-04 10:43:37 +00:00
opt_ic_mousefsgauge = nitems ;
2011-01-10 15:12:04 +00:00
m [ nitems ] . type = NM_TYPE_CHECK ; m [ nitems ] . text = " Mouse FlightSim Indicator " ; m [ nitems ] . value = PlayerCfg . MouseFSIndicator ; nitems + + ;
2010-12-28 18:11:10 +00:00
m [ nitems ] . type = NM_TYPE_TEXT ; m [ nitems ] . text = " " ; nitems + + ;
opt_ic_help0 = nitems ;
m [ nitems ] . type = NM_TYPE_MENU ; m [ nitems ] . text = " GAME SYSTEM KEYS " ; nitems + + ;
opt_ic_help1 = nitems ;
m [ nitems ] . type = NM_TYPE_MENU ; m [ nitems ] . text = " NETGAME SYSTEM KEYS " ; nitems + + ;
opt_ic_help2 = nitems ;
m [ nitems ] . type = NM_TYPE_MENU ; m [ nitems ] . text = " DEMO SYSTEM KEYS " ; nitems + + ;
newmenu_do1 ( NULL , TXT_CONTROLS , nitems , m , input_config_menuset , NULL , 3 ) ;
2008-02-24 14:41:27 +00:00
}
2011-01-10 15:12:04 +00:00
void reticle_config ( )
2009-05-03 12:31:30 +00:00
{
2011-01-10 15:12:04 +00:00
# ifdef OGL
newmenu_item m [ 18 ] ;
# else
newmenu_item m [ 17 ] ;
# endif
int nitems = 0 , i , opt_ret_type , opt_ret_rgba , opt_ret_size ;
m [ nitems ] . type = NM_TYPE_TEXT ; m [ nitems ] . text = " Reticle Type: " ; nitems + + ;
opt_ret_type = nitems ;
m [ nitems ] . type = NM_TYPE_RADIO ; m [ nitems ] . text = " Classic " ; m [ nitems ] . value = 0 ; m [ nitems ] . group = 0 ; nitems + + ;
# ifdef OGL
m [ nitems ] . type = NM_TYPE_RADIO ; m [ nitems ] . text = " Classic Reboot " ; m [ nitems ] . value = 0 ; m [ nitems ] . group = 0 ; nitems + + ;
# endif
m [ nitems ] . type = NM_TYPE_RADIO ; m [ nitems ] . text = " None " ; m [ nitems ] . value = 0 ; m [ nitems ] . group = 0 ; nitems + + ;
m [ nitems ] . type = NM_TYPE_RADIO ; m [ nitems ] . text = " X " ; m [ nitems ] . value = 0 ; m [ nitems ] . group = 0 ; nitems + + ;
m [ nitems ] . type = NM_TYPE_RADIO ; m [ nitems ] . text = " Dot " ; m [ nitems ] . value = 0 ; m [ nitems ] . group = 0 ; nitems + + ;
m [ nitems ] . type = NM_TYPE_RADIO ; m [ nitems ] . text = " Circle " ; m [ nitems ] . value = 0 ; m [ nitems ] . group = 0 ; nitems + + ;
m [ nitems ] . type = NM_TYPE_RADIO ; m [ nitems ] . text = " Cross V1 " ; m [ nitems ] . value = 0 ; m [ nitems ] . group = 0 ; nitems + + ;
m [ nitems ] . type = NM_TYPE_RADIO ; m [ nitems ] . text = " Cross V2 " ; m [ nitems ] . value = 0 ; m [ nitems ] . group = 0 ; nitems + + ;
m [ nitems ] . type = NM_TYPE_RADIO ; m [ nitems ] . text = " Angle " ; m [ nitems ] . value = 0 ; m [ nitems ] . group = 0 ; nitems + + ;
m [ nitems ] . type = NM_TYPE_TEXT ; m [ nitems ] . text = " " ; nitems + + ;
m [ nitems ] . type = NM_TYPE_TEXT ; m [ nitems ] . text = " Reticle Color: " ; nitems + + ;
opt_ret_rgba = nitems ;
m [ nitems ] . type = NM_TYPE_SLIDER ; m [ nitems ] . text = " Red " ; m [ nitems ] . value = ( PlayerCfg . ReticleRGBA [ 0 ] / 2 ) ; m [ nitems ] . min_value = 0 ; m [ nitems ] . max_value = 16 ; nitems + + ;
m [ nitems ] . type = NM_TYPE_SLIDER ; m [ nitems ] . text = " Green " ; m [ nitems ] . value = ( PlayerCfg . ReticleRGBA [ 1 ] / 2 ) ; m [ nitems ] . min_value = 0 ; m [ nitems ] . max_value = 16 ; nitems + + ;
m [ nitems ] . type = NM_TYPE_SLIDER ; m [ nitems ] . text = " Blue " ; m [ nitems ] . value = ( PlayerCfg . ReticleRGBA [ 2 ] / 2 ) ; m [ nitems ] . min_value = 0 ; m [ nitems ] . max_value = 16 ; nitems + + ;
m [ nitems ] . type = NM_TYPE_SLIDER ; m [ nitems ] . text = " Alpha " ; m [ nitems ] . value = ( PlayerCfg . ReticleRGBA [ 3 ] / 2 ) ; m [ nitems ] . min_value = 0 ; m [ nitems ] . max_value = 16 ; nitems + + ;
m [ nitems ] . type = NM_TYPE_TEXT ; m [ nitems ] . text = " " ; nitems + + ;
opt_ret_size = nitems ;
m [ nitems ] . type = NM_TYPE_SLIDER ; m [ nitems ] . text = " Reticle Size: " ; m [ nitems ] . value = PlayerCfg . ReticleSize ; m [ nitems ] . min_value = 0 ; m [ nitems ] . max_value = 4 ; nitems + + ;
2009-05-03 12:31:30 +00:00
2011-01-10 15:12:04 +00:00
i = PlayerCfg . ReticleType ;
# ifndef OGL
if ( i > 1 ) i - - ;
# endif
m [ opt_ret_type + i ] . value = 1 ;
newmenu_do1 ( NULL , " Reticle Options " , nitems , m , NULL , NULL , 1 ) ;
# ifdef OGL
for ( i = 0 ; i < 9 ; i + + )
if ( m [ i + opt_ret_type ] . value )
PlayerCfg . ReticleType = i ;
# else
for ( i = 0 ; i < 8 ; i + + )
if ( m [ i + opt_ret_type ] . value )
PlayerCfg . ReticleType = i ;
if ( PlayerCfg . ReticleType > 1 ) PlayerCfg . ReticleType + + ;
# endif
for ( i = 0 ; i < 4 ; i + + )
PlayerCfg . ReticleRGBA [ i ] = ( m [ i + opt_ret_rgba ] . value * 2 ) ;
PlayerCfg . ReticleSize = m [ opt_ret_size ] . value ;
}
2011-04-07 20:32:51 +00:00
int opt_gr_texfilt , opt_gr_movietexfilt , opt_gr_brightness , opt_gr_reticlemenu , opt_gr_alphafx , opt_gr_dynlightcolor , opt_gr_vsync , opt_gr_multisample , opt_gr_fpsindi ;
2011-01-10 15:12:04 +00:00
int graphics_config_menuset ( newmenu * menu , d_event * event , void * userdata )
{
newmenu_item * items = newmenu_get_items ( menu ) ;
int citem = newmenu_get_citem ( menu ) ;
userdata = userdata ;
switch ( event - > type )
{
case EVENT_NEWMENU_CHANGED :
2011-01-17 04:38:32 +00:00
if ( citem = = opt_gr_texfilt + 3
# ifdef OGL
& & ogl_maxanisotropy < = 1.0
# endif
)
2011-01-16 00:50:42 +00:00
{
nm_messagebox ( TXT_ERROR , 1 , TXT_OK , " Anisotropic Filtering not \n supported by your hardware/driver. " ) ;
items [ opt_gr_texfilt + 3 ] . value = 0 ;
items [ opt_gr_texfilt + 2 ] . value = 1 ;
}
2011-01-10 15:12:04 +00:00
if ( citem = = opt_gr_brightness )
gr_palette_set_gamma ( items [ citem ] . value ) ;
break ;
case EVENT_NEWMENU_SELECTED :
if ( citem = = opt_gr_reticlemenu )
reticle_config ( ) ;
return 1 ; // stay in menu
break ;
default :
break ;
}
return 0 ;
}
void graphics_config ( )
{
# ifdef OGL
2011-04-07 20:32:51 +00:00
newmenu_item m [ 14 ] ;
2011-01-14 09:51:13 +00:00
int i = 0 ;
2011-01-10 15:12:04 +00:00
# else
2011-02-14 21:27:07 +00:00
newmenu_item m [ 3 ] ;
2011-01-10 15:12:04 +00:00
# endif
2011-01-14 09:51:13 +00:00
int nitems = 0 ;
2011-01-10 15:12:04 +00:00
# ifdef OGL
2011-01-16 00:50:42 +00:00
m [ nitems ] . type = NM_TYPE_TEXT ; m [ nitems ] . text = " Texture Filtering: " ; nitems + + ;
2011-01-10 15:12:04 +00:00
opt_gr_texfilt = nitems ;
m [ nitems ] . type = NM_TYPE_RADIO ; m [ nitems ] . text = " None (Classical) " ; m [ nitems ] . value = 0 ; m [ nitems ] . group = 0 ; nitems + + ;
m [ nitems ] . type = NM_TYPE_RADIO ; m [ nitems ] . text = " Bilinear " ; m [ nitems ] . value = 0 ; m [ nitems ] . group = 0 ; nitems + + ;
m [ nitems ] . type = NM_TYPE_RADIO ; m [ nitems ] . text = " Trilinear " ; m [ nitems ] . value = 0 ; m [ nitems ] . group = 0 ; nitems + + ;
2011-01-16 00:50:42 +00:00
m [ nitems ] . type = NM_TYPE_RADIO ; m [ nitems ] . text = " Anisotropic " ; m [ nitems ] . value = 0 ; m [ nitems ] . group = 0 ; nitems + + ;
2011-01-10 15:12:04 +00:00
opt_gr_movietexfilt = nitems ;
m [ nitems ] . type = NM_TYPE_CHECK ; m [ nitems ] . text = " Movie Filter " ; m [ nitems ] . value = GameCfg . MovieTexFilt ; nitems + + ;
m [ nitems ] . type = NM_TYPE_TEXT ; m [ nitems ] . text = " " ; nitems + + ;
# endif
opt_gr_brightness = nitems ;
m [ nitems ] . type = NM_TYPE_SLIDER ; m [ nitems ] . text = TXT_BRIGHTNESS ; m [ nitems ] . value = gr_palette_get_gamma ( ) ; m [ nitems ] . min_value = 0 ; m [ nitems ] . max_value = 16 ; nitems + + ;
opt_gr_reticlemenu = nitems ;
m [ nitems ] . type = NM_TYPE_MENU ; m [ nitems ] . text = " Reticle Options " ; nitems + + ;
# ifdef OGL
opt_gr_alphafx = nitems ;
2011-02-23 16:46:39 +00:00
m [ nitems ] . type = NM_TYPE_CHECK ; m [ nitems ] . text = " Transparency Effects " ; m [ nitems ] . value = PlayerCfg . AlphaEffects ; nitems + + ;
2011-04-07 20:32:51 +00:00
opt_gr_dynlightcolor = nitems ;
m [ nitems ] . type = NM_TYPE_CHECK ; m [ nitems ] . text = " Colored Dynamic Light " ; m [ nitems ] . value = PlayerCfg . DynLightColor ; nitems + + ;
2011-01-10 15:12:04 +00:00
opt_gr_vsync = nitems ;
m [ nitems ] . type = NM_TYPE_CHECK ; m [ nitems ] . text = " VSync " ; m [ nitems ] . value = GameCfg . VSync ; nitems + + ;
opt_gr_multisample = nitems ;
m [ nitems ] . type = NM_TYPE_CHECK ; m [ nitems ] . text = " 4x multisampling " ; m [ nitems ] . value = GameCfg . Multisample ; nitems + + ;
2011-02-14 21:27:07 +00:00
# endif
opt_gr_fpsindi = nitems ;
m [ nitems ] . type = NM_TYPE_CHECK ; m [ nitems ] . text = " FPS Counter " ; m [ nitems ] . value = GameCfg . FPSIndicator ; nitems + + ;
# ifdef OGL
2011-01-10 15:12:04 +00:00
m [ opt_gr_texfilt + GameCfg . TexFilt ] . value = 1 ;
# endif
newmenu_do1 ( NULL , " Graphics Options " , nitems , m , graphics_config_menuset , NULL , 1 ) ;
# ifdef OGL
if ( GameCfg . VSync ! = m [ opt_gr_vsync ] . value | | GameCfg . Multisample ! = m [ opt_gr_multisample ] . value )
nm_messagebox ( NULL , 1 , TXT_OK , " To apply VSync or 4x Multisample \n you need to restart the program " ) ;
2011-01-16 00:50:42 +00:00
for ( i = 0 ; i < = 3 ; i + + )
2011-01-10 15:12:04 +00:00
if ( m [ i + opt_gr_texfilt ] . value )
GameCfg . TexFilt = i ;
GameCfg . MovieTexFilt = m [ opt_gr_movietexfilt ] . value ;
2011-02-23 16:46:39 +00:00
PlayerCfg . AlphaEffects = m [ opt_gr_alphafx ] . value ;
2011-04-07 20:32:51 +00:00
PlayerCfg . DynLightColor = m [ opt_gr_dynlightcolor ] . value ;
2011-01-10 15:12:04 +00:00
GameCfg . VSync = m [ opt_gr_vsync ] . value ;
GameCfg . Multisample = m [ opt_gr_multisample ] . value ;
# endif
GameCfg . GammaLevel = m [ opt_gr_brightness ] . value ;
2011-02-14 21:27:07 +00:00
GameCfg . FPSIndicator = m [ opt_gr_fpsindi ] . value ;
2011-01-10 15:12:04 +00:00
# ifdef OGL
gr_set_attributes ( ) ;
gr_set_mode ( Game_screen_mode ) ;
# endif
2009-05-03 12:31:30 +00:00
}
2010-10-10 10:48:24 +00:00
# if PHYSFS_VER_MAJOR >= 2
2010-08-27 14:09:19 +00:00
typedef struct browser
{
char * title ; // The title - needed for making another listbox when changing directory
int ( * when_selected ) ( void * userdata , const char * filename ) ; // What to do when something chosen
void * userdata ; // Whatever you want passed to when_selected
char * * list ; // All menu items
char * list_buf ; // Buffer for menu item text: hopefully reduces memory fragmentation this way
2012-07-22 23:17:54 +00:00
const char * const * ext_list ; // List of file extensions we're looking for (if looking for a music file many types are possible)
2010-08-27 14:09:19 +00:00
int select_dir ; // Allow selecting the current directory (e.g. for Jukebox level song directory)
int num_files ; // Number of list items found (including parent directory and current directory if selectable)
int max_files ; // How many entries we can have before having to grow the array
int max_buf ; // How much text we can have before having to grow the buffer
char view_path [ PATH_MAX ] ; // The absolute path we're currently looking at
int new_path ; // Whether the view_path is a new searchpath, if so, remove it when finished
} browser ;
void list_dir_el ( browser * b , const char * origdir , const char * fname )
{
char * ext ;
2012-07-22 23:17:54 +00:00
const char * const * i = NULL ;
2010-08-27 14:09:19 +00:00
ext = strrchr ( fname , ' . ' ) ;
if ( ext )
2012-05-18 23:36:43 +00:00
for ( i = b - > ext_list ; * i ! = NULL & & d_stricmp ( ext , * i ) ; i + + ) { } // see if the file is of a type we want
2010-08-27 14:09:19 +00:00
2010-08-27 21:16:43 +00:00
if ( ( ! strcmp ( ( PHYSFS_getRealDir ( fname ) = = NULL ? " " : PHYSFS_getRealDir ( fname ) ) , b - > view_path ) ) & & ( PHYSFS_isDirectory ( fname ) | | ( ext & & * i ) )
2010-08-27 14:09:19 +00:00
# if defined(__MACH__) && defined(__APPLE__)
2012-05-18 23:36:43 +00:00
& & d_stricmp ( fname , " Volumes " ) // this messes things up, use '..' instead
2010-08-27 14:09:19 +00:00
# endif
)
2010-09-26 13:15:20 +00:00
string_array_add ( & b - > list , & b - > list_buf , & b - > num_files , & b - > max_files , & b - > max_buf , fname ) ;
2010-08-27 14:09:19 +00:00
}
int list_directory ( browser * b )
{
2010-09-26 13:15:20 +00:00
if ( ! string_array_new ( & b - > list , & b - > list_buf , & b - > num_files , & b - > max_files , & b - > max_buf ) )
2010-08-27 14:09:19 +00:00
return 0 ;
strcpy ( b - > list_buf , " .. " ) ; // go to parent directory
b - > list [ b - > num_files + + ] = b - > list_buf ;
if ( b - > select_dir )
{
b - > list [ b - > num_files ] = b - > list [ b - > num_files - 1 ] + strlen ( b - > list [ b - > num_files - 1 ] ) + 1 ;
strcpy ( b - > list [ b - > num_files + + ] , " <this directory> " ) ; // choose the directory being viewed
}
PHYSFS_enumerateFilesCallback ( " " , ( PHYSFS_EnumFilesCallback ) list_dir_el , b ) ;
2010-09-26 13:15:20 +00:00
string_array_tidy ( & b - > list , & b - > list_buf , & b - > num_files , & b - > max_files , & b - > max_buf , 1 + ( b - > select_dir ? 1 : 0 ) ,
2010-08-27 14:09:19 +00:00
# ifdef __LINUX__
2010-09-26 13:15:20 +00:00
strcmp
2010-08-27 14:09:19 +00:00
# else
2012-05-18 23:36:43 +00:00
d_stricmp
2010-08-27 14:09:19 +00:00
# endif
2010-09-26 13:15:20 +00:00
) ;
2010-08-27 14:09:19 +00:00
return 1 ;
}
2012-07-22 23:17:54 +00:00
static int select_file_recursive ( char * title , const char * orig_path , const char * const * ext_list , int select_dir , int ( * when_selected ) ( void * userdata , const char * filename ) , void * userdata ) ;
2010-08-27 14:09:19 +00:00
int select_file_handler ( listbox * menu , d_event * event , browser * b )
{
char newpath [ PATH_MAX ] ;
char * * list = listbox_get_items ( menu ) ;
int citem = listbox_get_citem ( menu ) ;
const char * sep = PHYSFS_getDirSeparator ( ) ;
2010-08-27 20:32:05 +00:00
memset ( newpath , 0 , sizeof ( char ) * PATH_MAX ) ;
2010-08-27 14:09:19 +00:00
switch ( event - > type )
{
2010-08-31 13:25:45 +00:00
# ifdef _WIN32
case EVENT_KEY_COMMAND :
{
2011-01-14 09:51:13 +00:00
if ( event_key_get ( event ) = = KEY_CTRLED + KEY_D )
2010-08-31 13:25:45 +00:00
{
newmenu_item * m ;
char * text = NULL ;
int rval = 0 ;
MALLOC ( text , char , 2 ) ;
MALLOC ( m , newmenu_item , 1 ) ;
snprintf ( text , sizeof ( char ) * PATH_MAX , " c " ) ;
m - > type = NM_TYPE_INPUT ; m - > text_len = 3 ; m - > text = text ;
rval = newmenu_do ( NULL , " Enter drive letter " , 1 , m , NULL , NULL ) ;
text [ 1 ] = ' \0 ' ;
snprintf ( newpath , sizeof ( char ) * PATH_MAX , " %s:%s " , text , sep ) ;
if ( ! rval & & strlen ( text ) )
{
select_file_recursive ( b - > title , newpath , b - > ext_list , b - > select_dir , b - > when_selected , b - > userdata ) ;
// close old box.
event - > type = EVENT_WINDOW_CLOSED ;
window_close ( listbox_get_window ( menu ) ) ;
}
d_free ( text ) ;
d_free ( m ) ;
return 0 ;
}
break ;
}
# endif
2010-08-27 14:09:19 +00:00
case EVENT_NEWMENU_SELECTED :
strcpy ( newpath , b - > view_path ) ;
if ( citem = = 0 ) // go to parent dir
{
char * p ;
if ( ( p = strstr ( & newpath [ strlen ( newpath ) - strlen ( sep ) ] , sep ) ) )
if ( p ! = strstr ( newpath , sep ) ) // if this isn't the only separator (i.e. it's not about to look at the root)
* p = 0 ;
p = newpath + strlen ( newpath ) - 1 ;
while ( ( p > newpath ) & & strncmp ( p , sep , strlen ( sep ) ) ) // make sure full separator string is matched (typically is)
p - - ;
if ( p = = strstr ( newpath , sep ) ) // Look at root directory next, if not already
{
# if defined(__MACH__) && defined(__APPLE__)
2012-05-18 23:36:43 +00:00
if ( ! d_stricmp ( p , " /Volumes " ) )
2010-08-27 14:09:19 +00:00
return 1 ;
# endif
if ( p [ strlen ( sep ) ] ! = ' \0 ' )
p [ strlen ( sep ) ] = ' \0 ' ;
else
{
# if defined(__MACH__) && defined(__APPLE__)
// For Mac OS X, list all active volumes if we leave the root
strcpy ( newpath , " /Volumes " ) ;
# else
return 1 ;
# endif
}
}
else
* p = ' \0 ' ;
}
else if ( citem = = 1 & & b - > select_dir )
return ! ( * b - > when_selected ) ( b - > userdata , " " ) ;
else
{
if ( strncmp ( & newpath [ strlen ( newpath ) - strlen ( sep ) ] , sep , strlen ( sep ) ) )
{
strncat ( newpath , sep , PATH_MAX - 1 - strlen ( newpath ) ) ;
newpath [ PATH_MAX - 1 ] = ' \0 ' ;
}
strncat ( newpath , list [ citem ] , PATH_MAX - 1 - strlen ( newpath ) ) ;
newpath [ PATH_MAX - 1 ] = ' \0 ' ;
}
if ( ( citem = = 0 ) | | PHYSFS_isDirectory ( list [ citem ] ) )
{
// If it fails, stay in this one
return ! select_file_recursive ( b - > title , newpath , b - > ext_list , b - > select_dir , b - > when_selected , b - > userdata ) ;
}
return ! ( * b - > when_selected ) ( b - > userdata , list [ citem ] ) ;
break ;
case EVENT_WINDOW_CLOSE :
if ( b - > new_path )
PHYSFS_removeFromSearchPath ( b - > view_path ) ;
if ( list )
d_free ( list ) ;
if ( b - > list_buf )
d_free ( b - > list_buf ) ;
d_free ( b ) ;
break ;
default :
break ;
}
return 0 ;
}
2012-07-22 23:17:54 +00:00
static int select_file_recursive ( char * title , const char * orig_path , const char * const * ext_list , int select_dir , int ( * when_selected ) ( void * userdata , const char * filename ) , void * userdata )
2010-08-27 14:09:19 +00:00
{
browser * b ;
const char * sep = PHYSFS_getDirSeparator ( ) ;
char * p ;
2011-04-18 12:32:36 +00:00
char new_path [ PATH_MAX ] ;
2010-08-27 14:09:19 +00:00
MALLOC ( b , browser , 1 ) ;
if ( ! b )
return 0 ;
b - > title = title ;
b - > when_selected = when_selected ;
b - > userdata = userdata ;
b - > ext_list = ext_list ;
b - > select_dir = select_dir ;
b - > num_files = b - > max_files = 0 ;
b - > view_path [ 0 ] = ' \0 ' ;
b - > new_path = 1 ;
2011-04-18 12:32:36 +00:00
// Check for a PhysicsFS path first, saves complication!
2011-06-01 07:59:55 +00:00
if ( orig_path & & strncmp ( orig_path , sep , strlen ( sep ) ) & & PHYSFSX_exists ( orig_path , 0 ) )
2011-04-18 12:32:36 +00:00
{
PHYSFSX_getRealPath ( orig_path , new_path ) ;
orig_path = new_path ;
}
2010-08-27 14:09:19 +00:00
// Set the viewing directory to orig_path, or some parent of it
2010-08-28 02:46:54 +00:00
if ( orig_path )
2010-08-27 14:09:19 +00:00
{
2010-08-28 02:46:54 +00:00
// Must make this an absolute path for directory browsing to work properly
2010-08-31 13:25:45 +00:00
# ifdef _WIN32
2010-08-28 02:46:54 +00:00
if ( ! ( isalpha ( orig_path [ 0 ] ) & & ( orig_path [ 1 ] = = ' : ' ) ) ) // drive letter prompt (e.g. "C:"
# elif defined(macintosh)
if ( orig_path [ 0 ] = = ' : ' )
# else
if ( orig_path [ 0 ] ! = ' / ' )
# endif
{
strncpy ( b - > view_path , PHYSFS_getBaseDir ( ) , PATH_MAX - 1 ) ; // current write directory must be set to base directory
b - > view_path [ PATH_MAX - 1 ] = ' \0 ' ;
# ifdef macintosh
orig_path + + ; // go past ':'
# endif
strncat ( b - > view_path , orig_path , PATH_MAX - 1 - strlen ( b - > view_path ) ) ;
b - > view_path [ PATH_MAX - 1 ] = ' \0 ' ;
}
else
{
strncpy ( b - > view_path , orig_path , PATH_MAX - 1 ) ;
b - > view_path [ PATH_MAX - 1 ] = ' \0 ' ;
}
2010-08-27 14:09:19 +00:00
p = b - > view_path + strlen ( b - > view_path ) - 1 ;
2010-11-21 11:55:35 +00:00
b - > new_path = PHYSFSX_isNewPath ( b - > view_path ) ;
2010-08-27 14:09:19 +00:00
while ( ! PHYSFS_addToSearchPath ( b - > view_path , 0 ) )
{
while ( ( p > b - > view_path ) & & strncmp ( p , sep , strlen ( sep ) ) )
p - - ;
* p = ' \0 ' ;
if ( p = = b - > view_path )
break ;
2010-11-21 11:55:35 +00:00
b - > new_path = PHYSFSX_isNewPath ( b - > view_path ) ;
2010-08-27 14:09:19 +00:00
}
}
// Set to user directory if we couldn't find a searchpath
if ( ! b - > view_path [ 0 ] )
{
strncpy ( b - > view_path , PHYSFS_getUserDir ( ) , PATH_MAX - 1 ) ;
b - > view_path [ PATH_MAX - 1 ] = ' \0 ' ;
2010-11-21 11:55:35 +00:00
b - > new_path = PHYSFSX_isNewPath ( b - > view_path ) ;
2010-08-27 14:09:19 +00:00
if ( ! PHYSFS_addToSearchPath ( b - > view_path , 0 ) )
{
d_free ( b ) ;
return 0 ;
}
}
if ( ! list_directory ( b ) )
{
d_free ( b ) ;
return 0 ;
}
2012-05-14 10:20:30 +00:00
return newmenu_listbox1 ( title , b - > num_files , b - > list , 1 , 0 , ( int ( * ) ( listbox * , d_event * , void * ) ) select_file_handler , b ) ! = NULL ;
2010-08-27 14:09:19 +00:00
}
2010-10-10 10:48:24 +00:00
# define PATH_HEADER_TYPE NM_TYPE_MENU
# define BROWSE_TXT " (browse...)"
# else
2012-07-22 23:17:54 +00:00
static int select_file_recursive ( char * title , const char * orig_path , const char * const * ext_list , int select_dir , int ( * when_selected ) ( void * userdata , const char * filename ) , void * userdata )
2010-10-10 10:48:24 +00:00
{
return 0 ;
}
# define PATH_HEADER_TYPE NM_TYPE_TEXT
# define BROWSE_TXT
# endif
2011-01-20 11:17:30 +00:00
int opt_sm_digivol = - 1 , opt_sm_musicvol = - 1 , opt_sm_revstereo = - 1 , opt_sm_mtype0 = - 1 , opt_sm_mtype1 = - 1 , opt_sm_mtype2 = - 1 , opt_sm_mtype3 = - 1 , opt_sm_redbook_playorder = - 1 , opt_sm_mtype3_lmpath = - 1 , opt_sm_mtype3_lmplayorder1 = - 1 , opt_sm_mtype3_lmplayorder2 = - 1 , opt_sm_mtype3_lmplayorder3 = - 1 , opt_sm_cm_mtype3_file1_b = - 1 , opt_sm_cm_mtype3_file1 = - 1 , opt_sm_cm_mtype3_file2_b = - 1 , opt_sm_cm_mtype3_file2 = - 1 , opt_sm_cm_mtype3_file3_b = - 1 , opt_sm_cm_mtype3_file3 = - 1 , opt_sm_cm_mtype3_file4_b = - 1 , opt_sm_cm_mtype3_file4 = - 1 , opt_sm_cm_mtype3_file5_b = - 1 , opt_sm_cm_mtype3_file5 = - 1 ;
2010-06-14 08:13:16 +00:00
2009-03-03 12:55:27 +00:00
void set_extmusic_volume ( int volume ) ;
2006-03-20 17:12:09 +00:00
2010-08-27 14:09:19 +00:00
int get_absolute_path ( char * full_path , const char * rel_path )
{
PHYSFSX_getRealPath ( rel_path , full_path ) ;
return 1 ;
}
2010-10-14 09:50:11 +00:00
# ifdef USE_SDLMIXER
2010-08-27 14:09:19 +00:00
# define SELECT_SONG(t, s) select_file_recursive(t, GameCfg.CMMiscMusic[s], jukebox_exts, 0, (int (*)(void *, const char *))get_absolute_path, GameCfg.CMMiscMusic[s])
2010-10-14 09:50:11 +00:00
# endif
2010-08-27 14:09:19 +00:00
2010-01-07 14:49:07 +00:00
int sound_menuset ( newmenu * menu , d_event * event , void * userdata )
2006-03-20 17:12:09 +00:00
{
2010-01-07 14:49:07 +00:00
newmenu_item * items = newmenu_get_items ( menu ) ;
2010-02-26 08:42:44 +00:00
int citem = newmenu_get_citem ( menu ) ;
2010-06-14 08:13:16 +00:00
//int nitems = newmenu_get_nitems(menu);
2010-02-26 08:42:44 +00:00
int replay = 0 ;
int rval = 0 ;
2010-01-07 14:49:07 +00:00
2010-02-01 06:55:38 +00:00
switch ( event - > type )
{
case EVENT_NEWMENU_CHANGED :
2010-06-14 08:13:16 +00:00
if ( citem = = opt_sm_digivol )
2010-02-01 06:55:38 +00:00
{
2010-06-14 08:13:16 +00:00
GameCfg . DigiVolume = items [ citem ] . value ;
digi_set_digi_volume ( ( GameCfg . DigiVolume * 32768 ) / 8 ) ;
digi_play_sample_once ( SOUND_DROP_BOMB , F1_0 ) ;
}
else if ( citem = = opt_sm_musicvol )
{
GameCfg . MusicVolume = items [ citem ] . value ;
songs_set_volume ( GameCfg . MusicVolume ) ;
}
else if ( citem = = opt_sm_revstereo )
{
GameCfg . ReverseStereo = items [ citem ] . value ;
}
else if ( citem = = opt_sm_mtype0 )
{
GameCfg . MusicType = MUSIC_TYPE_NONE ;
replay = 1 ;
}
else if ( citem = = opt_sm_mtype1 )
{
GameCfg . MusicType = MUSIC_TYPE_BUILTIN ;
replay = 1 ;
}
else if ( citem = = opt_sm_mtype2 )
{
GameCfg . MusicType = MUSIC_TYPE_REDBOOK ;
replay = 1 ;
}
2010-10-14 09:50:11 +00:00
# ifdef USE_SDLMIXER
2010-06-14 08:13:16 +00:00
else if ( citem = = opt_sm_mtype3 )
{
GameCfg . MusicType = MUSIC_TYPE_CUSTOM ;
replay = 1 ;
}
2010-10-14 09:50:11 +00:00
# endif
2010-06-14 08:13:16 +00:00
else if ( citem = = opt_sm_redbook_playorder )
{
GameCfg . OrigTrackOrder = items [ citem ] . value ;
replay = ( Game_wind ! = NULL ) ;
}
2010-10-14 09:50:11 +00:00
# ifdef USE_SDLMIXER
2010-06-14 08:13:16 +00:00
else if ( citem = = opt_sm_mtype3_lmplayorder1 )
{
GameCfg . CMLevelMusicPlayOrder = MUSIC_CM_PLAYORDER_CONT ;
replay = ( Game_wind ! = NULL ) ;
}
else if ( citem = = opt_sm_mtype3_lmplayorder2 )
{
2010-08-17 14:59:57 +00:00
GameCfg . CMLevelMusicPlayOrder = MUSIC_CM_PLAYORDER_LEVEL ;
2010-06-14 08:13:16 +00:00
replay = ( Game_wind ! = NULL ) ;
2010-02-01 06:55:38 +00:00
}
2011-01-20 11:17:30 +00:00
else if ( citem = = opt_sm_mtype3_lmplayorder3 )
{
GameCfg . CMLevelMusicPlayOrder = MUSIC_CM_PLAYORDER_RAND ;
replay = ( Game_wind ! = NULL ) ;
}
2010-10-14 09:50:11 +00:00
# endif
2010-02-01 06:55:38 +00:00
break ;
2010-06-14 08:13:16 +00:00
2010-02-26 08:42:44 +00:00
case EVENT_NEWMENU_SELECTED :
2010-10-14 09:50:11 +00:00
# ifdef USE_SDLMIXER
2010-08-27 14:09:19 +00:00
if ( citem = = opt_sm_mtype3_lmpath )
{
2012-07-22 23:17:54 +00:00
static const char * const ext_list [ ] = { " .m3u " , NULL } ; // select a directory or M3U playlist
2010-08-31 13:25:45 +00:00
select_file_recursive (
# ifndef _WIN32
2010-09-26 13:15:20 +00:00
" Select directory or \n M3U playlist to \n play level music from " ,
2010-08-31 13:25:45 +00:00
# else
2010-09-26 13:15:20 +00:00
" Select directory or \n M3U playlist to \n play level music from. \n CTRL-D to change drive " ,
2010-08-31 13:25:45 +00:00
# endif
2010-08-27 14:09:19 +00:00
GameCfg . CMLevelMusicPath , ext_list , 1 , // look in current music path for ext_list files and allow directory selection
( int ( * ) ( void * , const char * ) ) get_absolute_path , GameCfg . CMLevelMusicPath ) ; // just copy the absolute path
}
else if ( citem = = opt_sm_cm_mtype3_file1_b )
2010-08-31 13:25:45 +00:00
# ifndef _WIN32
2010-08-27 14:09:19 +00:00
SELECT_SONG ( " Select main menu music " , SONG_TITLE ) ;
2010-08-31 13:25:45 +00:00
# else
SELECT_SONG ( " Select main menu music. \n CTRL-D to change drive " , SONG_TITLE ) ;
# endif
2010-08-27 14:09:19 +00:00
else if ( citem = = opt_sm_cm_mtype3_file2_b )
2010-08-31 13:25:45 +00:00
# ifndef _WIN32
2010-08-27 14:09:19 +00:00
SELECT_SONG ( " Select briefing music " , SONG_BRIEFING ) ;
2010-08-31 13:25:45 +00:00
# else
SELECT_SONG ( " Select briefing music. \n CTRL-D to change drive " , SONG_BRIEFING ) ;
# endif
2010-08-27 14:09:19 +00:00
else if ( citem = = opt_sm_cm_mtype3_file3_b )
2010-08-31 13:25:45 +00:00
# ifndef _WIN32
2010-08-27 14:09:19 +00:00
SELECT_SONG ( " Select credits music " , SONG_CREDITS ) ;
2010-08-31 13:25:45 +00:00
# else
SELECT_SONG ( " Select credits music. \n CTRL-D to change drive " , SONG_CREDITS ) ;
# endif
2010-08-27 14:09:19 +00:00
else if ( citem = = opt_sm_cm_mtype3_file4_b )
2010-08-31 13:25:45 +00:00
# ifndef _WIN32
2010-08-27 14:09:19 +00:00
SELECT_SONG ( " Select escape sequence music " , SONG_ENDLEVEL ) ;
2010-08-31 13:25:45 +00:00
# else
SELECT_SONG ( " Select escape sequence music. \n CTRL-D to change drive " , SONG_ENDLEVEL ) ;
# endif
2010-08-27 14:09:19 +00:00
else if ( citem = = opt_sm_cm_mtype3_file5_b )
2010-08-31 13:25:45 +00:00
# ifndef _WIN32
2010-08-27 14:09:19 +00:00
SELECT_SONG ( " Select game ending music " , SONG_ENDGAME ) ;
2010-08-31 13:25:45 +00:00
# else
SELECT_SONG ( " Select game ending music. \n CTRL-D to change drive " , SONG_ENDGAME ) ;
# endif
2010-10-14 09:50:11 +00:00
# endif
2010-02-26 08:42:44 +00:00
rval = 1 ; // stay in menu
break ;
2010-06-14 08:13:16 +00:00
2010-02-26 08:42:44 +00:00
case EVENT_WINDOW_CLOSE :
d_free ( items ) ;
break ;
2010-06-14 08:13:16 +00:00
2010-02-01 06:55:38 +00:00
default :
break ;
2006-03-20 17:12:09 +00:00
}
2010-02-26 08:42:44 +00:00
if ( replay )
{
2010-06-14 08:13:16 +00:00
songs_uninit ( ) ;
2010-02-26 08:42:44 +00:00
if ( Game_wind )
2010-06-14 08:13:16 +00:00
songs_play_level_song ( Current_level_num , 0 ) ;
2010-02-26 08:42:44 +00:00
else
songs_play_song ( SONG_TITLE , 1 ) ;
}
2010-06-14 08:13:16 +00:00
2010-02-01 06:55:38 +00:00
userdata = userdata ;
2006-03-20 17:12:09 +00:00
2010-02-26 08:42:44 +00:00
return rval ;
2006-03-20 17:12:09 +00:00
}
2008-05-07 14:02:01 +00:00
# ifdef USE_SDLMIXER
2011-01-20 11:17:30 +00:00
# define SOUND_MENU_NITEMS 33
2010-06-14 08:13:16 +00:00
# else
# ifdef _WIN32
# define SOUND_MENU_NITEMS 11
2008-05-07 14:02:01 +00:00
# else
2010-06-14 08:13:16 +00:00
# define SOUND_MENU_NITEMS 10
# endif
2008-05-07 14:02:01 +00:00
# endif
2009-05-03 12:31:30 +00:00
2010-02-26 08:42:44 +00:00
void do_sound_menu ( )
{
newmenu_item * m ;
int nitems = 0 ;
2010-06-14 08:13:16 +00:00
char old_CMLevelMusicPath [ PATH_MAX + 1 ] , old_CMMiscMusic0 [ PATH_MAX + 1 ] ;
2009-05-03 12:31:30 +00:00
2010-06-14 08:13:16 +00:00
memset ( old_CMLevelMusicPath , 0 , sizeof ( char ) * ( PATH_MAX + 1 ) ) ;
2012-06-01 10:46:03 +00:00
snprintf ( old_CMLevelMusicPath , sizeof ( old_CMLevelMusicPath ) , " %s " , GameCfg . CMLevelMusicPath ) ;
2010-06-14 08:13:16 +00:00
memset ( old_CMMiscMusic0 , 0 , sizeof ( char ) * ( PATH_MAX + 1 ) ) ;
2012-06-01 10:46:03 +00:00
snprintf ( old_CMMiscMusic0 , sizeof ( old_CMMiscMusic0 ) , " %s " , GameCfg . CMMiscMusic [ SONG_TITLE ] ) ;
2009-05-03 12:31:30 +00:00
2010-02-26 08:42:44 +00:00
MALLOC ( m , newmenu_item , SOUND_MENU_NITEMS ) ;
if ( ! m )
return ;
2009-05-03 12:31:30 +00:00
2010-06-14 08:13:16 +00:00
opt_sm_digivol = nitems ;
m [ nitems ] . type = NM_TYPE_SLIDER ; m [ nitems ] . text = TXT_FX_VOLUME ; m [ nitems ] . value = GameCfg . DigiVolume ; m [ nitems ] . min_value = 0 ; m [ nitems + + ] . max_value = 8 ;
opt_sm_musicvol = nitems ;
m [ nitems ] . type = NM_TYPE_SLIDER ; m [ nitems ] . text = " music volume " ; m [ nitems ] . value = GameCfg . MusicVolume ; m [ nitems ] . min_value = 0 ; m [ nitems + + ] . max_value = 8 ;
opt_sm_revstereo = nitems ;
m [ nitems ] . type = NM_TYPE_CHECK ; m [ nitems ] . text = TXT_REVERSE_STEREO ; m [ nitems + + ] . value = GameCfg . ReverseStereo ;
m [ nitems ] . type = NM_TYPE_TEXT ; m [ nitems + + ] . text = " " ;
m [ nitems ] . type = NM_TYPE_TEXT ; m [ nitems + + ] . text = " music type: " ;
opt_sm_mtype0 = nitems ;
m [ nitems ] . type = NM_TYPE_RADIO ; m [ nitems ] . text = " no music " ; m [ nitems ] . value = ( GameCfg . MusicType = = MUSIC_TYPE_NONE ) ; m [ nitems ] . group = 0 ; nitems + + ;
# if defined(USE_SDLMIXER) || defined(_WIN32)
opt_sm_mtype1 = nitems ;
2010-08-17 14:59:57 +00:00
m [ nitems ] . type = NM_TYPE_RADIO ; m [ nitems ] . text = " built-in/addon music " ; m [ nitems ] . value = ( GameCfg . MusicType = = MUSIC_TYPE_BUILTIN ) ; m [ nitems ] . group = 0 ; nitems + + ;
2010-06-14 08:13:16 +00:00
# endif
opt_sm_mtype2 = nitems ;
m [ nitems ] . type = NM_TYPE_RADIO ; m [ nitems ] . text = " cd music " ; m [ nitems ] . value = ( GameCfg . MusicType = = MUSIC_TYPE_REDBOOK ) ; m [ nitems ] . group = 0 ; nitems + + ;
2008-05-24 08:59:35 +00:00
# ifdef USE_SDLMIXER
2010-06-14 08:13:16 +00:00
opt_sm_mtype3 = nitems ;
2010-08-17 14:59:57 +00:00
m [ nitems ] . type = NM_TYPE_RADIO ; m [ nitems ] . text = " jukebox " ; m [ nitems ] . value = ( GameCfg . MusicType = = MUSIC_TYPE_CUSTOM ) ; m [ nitems ] . group = 0 ; nitems + + ;
2010-06-14 08:13:16 +00:00
# endif
m [ nitems ] . type = NM_TYPE_TEXT ; m [ nitems + + ] . text = " " ;
2010-10-14 09:50:11 +00:00
# ifdef USE_SDLMIXER
2010-08-25 00:40:55 +00:00
m [ nitems ] . type = NM_TYPE_TEXT ; m [ nitems + + ] . text = " cd music / jukebox options: " ;
2010-10-14 09:50:11 +00:00
# else
m [ nitems ] . type = NM_TYPE_TEXT ; m [ nitems + + ] . text = " cd music options: " ;
# endif
2010-06-14 08:13:16 +00:00
opt_sm_redbook_playorder = nitems ;
m [ nitems ] . type = NM_TYPE_CHECK ; m [ nitems ] . text = " force descent ][ cd track order " ; m [ nitems + + ] . value = GameCfg . OrigTrackOrder ;
# ifdef USE_SDLMIXER
m [ nitems ] . type = NM_TYPE_TEXT ; m [ nitems + + ] . text = " " ;
2010-08-17 14:59:57 +00:00
m [ nitems ] . type = NM_TYPE_TEXT ; m [ nitems + + ] . text = " jukebox options: " ;
2010-06-14 08:13:16 +00:00
opt_sm_mtype3_lmpath = nitems ;
2010-10-29 23:29:58 +00:00
m [ nitems ] . type = PATH_HEADER_TYPE ; m [ nitems + + ] . text = " path for level music " BROWSE_TXT ;
2010-06-14 08:13:16 +00:00
m [ nitems ] . type = NM_TYPE_INPUT ; m [ nitems ] . text = GameCfg . CMLevelMusicPath ; m [ nitems + + ] . text_len = NM_MAX_TEXT_LEN - 1 ;
2010-08-17 14:59:57 +00:00
m [ nitems ] . type = NM_TYPE_TEXT ; m [ nitems + + ] . text = " " ;
2010-06-14 08:13:16 +00:00
m [ nitems ] . type = NM_TYPE_TEXT ; m [ nitems + + ] . text = " level music play order: " ;
opt_sm_mtype3_lmplayorder1 = nitems ;
m [ nitems ] . type = NM_TYPE_RADIO ; m [ nitems ] . text = " continuously " ; m [ nitems ] . value = ( GameCfg . CMLevelMusicPlayOrder = = MUSIC_CM_PLAYORDER_CONT ) ; m [ nitems ] . group = 1 ; nitems + + ;
opt_sm_mtype3_lmplayorder2 = nitems ;
2010-08-17 14:59:57 +00:00
m [ nitems ] . type = NM_TYPE_RADIO ; m [ nitems ] . text = " one track per level " ; m [ nitems ] . value = ( GameCfg . CMLevelMusicPlayOrder = = MUSIC_CM_PLAYORDER_LEVEL ) ; m [ nitems ] . group = 1 ; nitems + + ;
2010-06-14 08:13:16 +00:00
2011-01-20 11:17:30 +00:00
opt_sm_mtype3_lmplayorder3 = nitems ;
m [ nitems ] . type = NM_TYPE_RADIO ; m [ nitems ] . text = " random " ; m [ nitems ] . value = ( GameCfg . CMLevelMusicPlayOrder = = MUSIC_CM_PLAYORDER_RAND ) ; m [ nitems ] . group = 1 ; nitems + + ;
2010-08-17 14:59:57 +00:00
m [ nitems ] . type = NM_TYPE_TEXT ; m [ nitems + + ] . text = " " ;
2010-06-14 08:13:16 +00:00
m [ nitems ] . type = NM_TYPE_TEXT ; m [ nitems + + ] . text = " non-level music: " ;
2010-08-27 14:09:19 +00:00
opt_sm_cm_mtype3_file1_b = nitems ;
2010-10-10 10:48:24 +00:00
m [ nitems ] . type = PATH_HEADER_TYPE ; m [ nitems + + ] . text = " main menu " BROWSE_TXT ;
2010-06-14 08:13:16 +00:00
opt_sm_cm_mtype3_file1 = nitems ;
m [ nitems ] . type = NM_TYPE_INPUT ; m [ nitems ] . text = GameCfg . CMMiscMusic [ SONG_TITLE ] ; m [ nitems + + ] . text_len = NM_MAX_TEXT_LEN - 1 ;
2010-08-27 14:09:19 +00:00
opt_sm_cm_mtype3_file2_b = nitems ;
2010-10-10 10:48:24 +00:00
m [ nitems ] . type = PATH_HEADER_TYPE ; m [ nitems + + ] . text = " briefing " BROWSE_TXT ;
2010-06-14 08:13:16 +00:00
opt_sm_cm_mtype3_file2 = nitems ;
m [ nitems ] . type = NM_TYPE_INPUT ; m [ nitems ] . text = GameCfg . CMMiscMusic [ SONG_BRIEFING ] ; m [ nitems + + ] . text_len = NM_MAX_TEXT_LEN - 1 ;
2010-08-27 14:09:19 +00:00
opt_sm_cm_mtype3_file3_b = nitems ;
2010-10-10 10:48:24 +00:00
m [ nitems ] . type = PATH_HEADER_TYPE ; m [ nitems + + ] . text = " credits " BROWSE_TXT ;
2010-06-14 08:13:16 +00:00
opt_sm_cm_mtype3_file3 = nitems ;
m [ nitems ] . type = NM_TYPE_INPUT ; m [ nitems ] . text = GameCfg . CMMiscMusic [ SONG_CREDITS ] ; m [ nitems + + ] . text_len = NM_MAX_TEXT_LEN - 1 ;
2010-09-26 14:22:55 +00:00
opt_sm_cm_mtype3_file4_b = nitems ;
2010-10-10 10:48:24 +00:00
m [ nitems ] . type = PATH_HEADER_TYPE ; m [ nitems + + ] . text = " escape sequence " BROWSE_TXT ;
2010-09-26 14:22:55 +00:00
opt_sm_cm_mtype3_file4 = nitems ;
m [ nitems ] . type = NM_TYPE_INPUT ; m [ nitems ] . text = GameCfg . CMMiscMusic [ SONG_ENDLEVEL ] ; m [ nitems + + ] . text_len = NM_MAX_TEXT_LEN - 1 ;
2010-08-27 14:09:19 +00:00
opt_sm_cm_mtype3_file5_b = nitems ;
2010-10-10 10:48:24 +00:00
m [ nitems ] . type = PATH_HEADER_TYPE ; m [ nitems + + ] . text = " game ending " BROWSE_TXT ;
2010-06-14 08:13:16 +00:00
opt_sm_cm_mtype3_file5 = nitems ;
m [ nitems ] . type = NM_TYPE_INPUT ; m [ nitems ] . text = GameCfg . CMMiscMusic [ SONG_ENDGAME ] ; m [ nitems + + ] . text_len = NM_MAX_TEXT_LEN - 1 ;
2008-05-24 08:59:35 +00:00
# endif
2010-06-14 08:13:16 +00:00
2010-02-26 08:42:44 +00:00
Assert ( nitems = = SOUND_MENU_NITEMS ) ;
2010-06-14 08:13:16 +00:00
2010-02-26 08:42:44 +00:00
newmenu_do1 ( NULL , " Sound Effects & Music " , nitems , m , sound_menuset , NULL , 0 ) ;
2010-06-14 08:13:16 +00:00
# ifdef USE_SDLMIXER
if ( ( ( Game_wind ! = NULL ) & & strcmp ( old_CMLevelMusicPath , GameCfg . CMLevelMusicPath ) ) | | ( ( Game_wind = = NULL ) & & strcmp ( old_CMMiscMusic0 , GameCfg . CMMiscMusic [ SONG_TITLE ] ) ) )
{
songs_uninit ( ) ;
if ( Game_wind )
songs_play_level_song ( Current_level_num , 0 ) ;
else
songs_play_song ( SONG_TITLE , 1 ) ;
}
# endif
2008-04-13 00:28:36 +00:00
}
2006-03-20 17:12:09 +00:00
# define ADD_CHECK(n,txt,v) do { m[n].type=NM_TYPE_CHECK; m[n].text=txt; m[n].value=v;} while (0)
2008-04-13 00:28:36 +00:00
void do_misc_menu ( )
2006-03-20 17:12:09 +00:00
{
2013-04-08 13:04:28 +00:00
newmenu_item m [ 14 ] ;
2006-03-20 17:12:09 +00:00
int i = 0 ;
do {
2008-04-13 00:28:36 +00:00
ADD_CHECK ( 0 , " Ship auto-leveling " , PlayerCfg . AutoLeveling ) ;
2011-01-10 15:12:04 +00:00
ADD_CHECK ( 1 , " Missile view " , PlayerCfg . MissileViewEnabled ) ;
ADD_CHECK ( 2 , " Headlight on when picked up " , PlayerCfg . HeadlightActiveDefault ) ;
ADD_CHECK ( 3 , " Show guided missile in main display " , PlayerCfg . GuidedInBigWindow ) ;
ADD_CHECK ( 4 , " Escort robot hot keys " , PlayerCfg . EscortHotKeys ) ;
ADD_CHECK ( 5 , " Persistent Debris " , PlayerCfg . PersistentDebris ) ;
ADD_CHECK ( 6 , " Screenshots w/o HUD " , PlayerCfg . PRShot ) ;
ADD_CHECK ( 7 , " Movie Subtitles " , GameCfg . MovieSubtitles ) ;
2012-05-10 12:39:26 +00:00
ADD_CHECK ( 8 , " No redundant pickup messages " , PlayerCfg . NoRedundancy ) ;
ADD_CHECK ( 9 , " Show Player chat only (Multi) " , PlayerCfg . MultiMessages ) ;
ADD_CHECK ( 10 , " No Rankings (Multi) " , PlayerCfg . NoRankings ) ;
2011-05-20 10:23:28 +00:00
ADD_CHECK ( 11 , " Free Flight controls in Automap " , PlayerCfg . AutomapFreeFlight ) ;
2012-05-10 12:39:26 +00:00
ADD_CHECK ( 12 , " No Weapon Autoselect when firing " , PlayerCfg . NoFireAutoselect ) ;
2013-04-08 13:04:28 +00:00
ADD_CHECK ( 13 , " Only Cycle Autoselect Weapons " , PlayerCfg . CycleAutoselectOnly ) ;
2008-04-13 00:28:36 +00:00
2010-01-07 14:49:07 +00:00
i = newmenu_do1 ( NULL , " Misc Options " , sizeof ( m ) / sizeof ( * m ) , m , NULL , NULL , i ) ;
2010-06-14 08:13:16 +00:00
2012-05-10 12:39:26 +00:00
PlayerCfg . AutoLeveling = m [ 0 ] . value ;
PlayerCfg . MissileViewEnabled = m [ 1 ] . value ;
PlayerCfg . HeadlightActiveDefault = m [ 2 ] . value ;
PlayerCfg . GuidedInBigWindow = m [ 3 ] . value ;
PlayerCfg . EscortHotKeys = m [ 4 ] . value ;
PlayerCfg . PersistentDebris = m [ 5 ] . value ;
PlayerCfg . PRShot = m [ 6 ] . value ;
GameCfg . MovieSubtitles = m [ 7 ] . value ;
PlayerCfg . NoRedundancy = m [ 8 ] . value ;
PlayerCfg . MultiMessages = m [ 9 ] . value ;
PlayerCfg . NoRankings = m [ 10 ] . value ;
PlayerCfg . AutomapFreeFlight = m [ 11 ] . value ;
PlayerCfg . NoFireAutoselect = m [ 12 ] . value ;
2013-04-08 13:04:28 +00:00
PlayerCfg . CycleAutoselectOnly = m [ 13 ] . value ;
2006-03-20 17:12:09 +00:00
} while ( i > - 1 ) ;
}
2011-09-13 23:15:32 +00:00
# if defined(USE_UDP)
2010-04-04 09:41:53 +00:00
static int multi_player_menu_handler ( newmenu * menu , d_event * event , int * menu_choice )
{
newmenu_item * items = newmenu_get_items ( menu ) ;
switch ( event - > type )
{
case EVENT_NEWMENU_SELECTED :
// stay in multiplayer menu, even after having played a game
return do_option ( menu_choice [ newmenu_get_citem ( menu ) ] ) ;
2010-06-14 08:13:16 +00:00
2010-04-04 09:41:53 +00:00
case EVENT_WINDOW_CLOSE :
d_free ( menu_choice ) ;
d_free ( items ) ;
break ;
2010-06-14 08:13:16 +00:00
2010-04-04 09:41:53 +00:00
default :
break ;
}
2010-06-14 08:13:16 +00:00
2010-04-04 09:41:53 +00:00
return 0 ;
}
2006-03-20 17:12:09 +00:00
void do_multi_player_menu ( )
{
2010-04-04 09:41:53 +00:00
int * menu_choice ;
newmenu_item * m ;
int num_options = 0 ;
2006-03-20 17:12:09 +00:00
2011-09-13 23:15:32 +00:00
MALLOC ( menu_choice , int , 3 ) ;
2010-04-04 09:41:53 +00:00
if ( ! menu_choice )
return ;
2010-06-14 08:13:16 +00:00
2011-09-13 23:15:32 +00:00
MALLOC ( m , newmenu_item , 3 ) ;
2010-04-04 09:41:53 +00:00
if ( ! m )
{
d_free ( menu_choice ) ;
return ;
}
2006-03-20 17:12:09 +00:00
2009-11-29 16:46:13 +00:00
# ifdef USE_UDP
2010-03-18 07:02:38 +00:00
m [ num_options ] . type = NM_TYPE_MENU ; m [ num_options ] . text = " HOST GAME " ; menu_choice [ num_options ] = MENU_START_UDP_NETGAME ; num_options + + ;
2011-04-05 00:24:34 +00:00
# ifdef USE_TRACKER
m [ num_options ] . type = NM_TYPE_MENU ; m [ num_options ] . text = " FIND LAN/ONLINE GAMES " ; menu_choice [ num_options ] = MENU_JOIN_LIST_UDP_NETGAME ; num_options + + ;
# else
2010-03-18 07:02:38 +00:00
m [ num_options ] . type = NM_TYPE_MENU ; m [ num_options ] . text = " FIND LAN GAMES " ; menu_choice [ num_options ] = MENU_JOIN_LIST_UDP_NETGAME ; num_options + + ;
2011-04-05 00:24:34 +00:00
# endif
2010-03-18 07:02:38 +00:00
m [ num_options ] . type = NM_TYPE_MENU ; m [ num_options ] . text = " JOIN GAME MANUALLY " ; menu_choice [ num_options ] = MENU_JOIN_MANUAL_UDP_NETGAME ; num_options + + ;
2009-11-29 16:46:13 +00:00
# endif
2009-11-24 09:48:53 +00:00
2010-06-23 11:44:12 +00:00
newmenu_do3 ( NULL , TXT_MULTIPLAYER , num_options , m , ( int ( * ) ( newmenu * , d_event * , void * ) ) multi_player_menu_handler , menu_choice , 0 , NULL ) ;
2006-03-20 17:12:09 +00:00
}
2009-11-29 16:46:13 +00:00
# endif
2008-04-13 00:28:36 +00:00
void do_options_menu ( )
{
2010-04-04 09:41:53 +00:00
newmenu_item * m ;
2010-06-14 08:13:16 +00:00
2011-01-10 15:12:04 +00:00
MALLOC ( m , newmenu_item , 10 ) ;
2010-04-04 09:41:53 +00:00
if ( ! m )
return ;
2008-04-13 00:28:36 +00:00
2010-01-17 14:42:59 +00:00
m [ 0 ] . type = NM_TYPE_MENU ; m [ 0 ] . text = " Sound effects & music... " ;
m [ 1 ] . type = NM_TYPE_TEXT ; m [ 1 ] . text = " " ;
m [ 2 ] . type = NM_TYPE_MENU ; m [ 2 ] . text = TXT_CONTROLS_ ;
m [ 3 ] . type = NM_TYPE_TEXT ; m [ 3 ] . text = " " ;
2011-01-10 15:12:04 +00:00
m [ 4 ] . type = NM_TYPE_MENU ; m [ 4 ] . text = " Screen resolution... " ;
m [ 5 ] . type = NM_TYPE_MENU ; m [ 5 ] . text = " Graphics Options... " ;
2010-01-17 14:42:59 +00:00
m [ 6 ] . type = NM_TYPE_TEXT ; m [ 6 ] . text = " " ;
2011-01-10 15:12:04 +00:00
m [ 7 ] . type = NM_TYPE_MENU ; m [ 7 ] . text = " Primary autoselect ordering... " ;
m [ 8 ] . type = NM_TYPE_MENU ; m [ 8 ] . text = " Secondary autoselect ordering... " ;
m [ 9 ] . type = NM_TYPE_MENU ; m [ 9 ] . text = " Misc Options... " ;
2008-04-13 00:28:36 +00:00
2010-04-04 09:41:53 +00:00
// Fall back to main event loop
// Allows clean closing and re-opening when resolution changes
2011-01-10 15:12:04 +00:00
newmenu_do3 ( NULL , TXT_OPTIONS , 10 , m , options_menuset , NULL , 0 , NULL ) ;
2008-04-13 00:28:36 +00:00
}
2011-07-20 12:44:49 +00:00
# ifndef RELEASE
int polygon_models_viewer_handler ( window * wind , d_event * event )
{
static int view_idx = 0 ;
int key = 0 ;
static vms_angvec ang ;
switch ( event - > type )
{
case EVENT_WINDOW_ACTIVATED :
gr_use_palette_table ( " groupa.256 " ) ;
key_toggle_repeat ( 1 ) ;
view_idx = 0 ;
ang . p = ang . b = 0 ;
2012-05-14 15:13:27 +00:00
ang . h = F0_5 - 1 ;
2011-07-20 12:44:49 +00:00
break ;
case EVENT_KEY_COMMAND :
key = event_key_get ( event ) ;
switch ( key )
{
case KEY_ESC :
window_close ( wind ) ;
break ;
case KEY_SPACEBAR :
view_idx + + ;
if ( view_idx > = N_polygon_models ) view_idx = 0 ;
break ;
case KEY_BACKSP :
view_idx - - ;
if ( view_idx < 0 ) view_idx = N_polygon_models - 1 ;
break ;
case KEY_A :
ang . h - = 100 ;
break ;
case KEY_D :
ang . h + = 100 ;
break ;
case KEY_W :
ang . p - = 100 ;
break ;
case KEY_S :
ang . p + = 100 ;
break ;
case KEY_Q :
ang . b - = 100 ;
break ;
case KEY_E :
ang . b + = 100 ;
break ;
case KEY_R :
ang . p = ang . b = 0 ;
2012-05-14 15:13:27 +00:00
ang . h = F0_5 - 1 ;
2011-07-20 12:44:49 +00:00
break ;
default :
break ;
}
return 1 ;
case EVENT_WINDOW_DRAW :
timer_delay ( F1_0 / 60 ) ;
draw_model_picture ( view_idx , & ang ) ;
gr_set_curfont ( GAME_FONT ) ;
gr_set_fontcolor ( BM_XRGB ( 255 , 255 , 255 ) , - 1 ) ;
gr_printf ( FSPACX ( 1 ) , FSPACY ( 1 ) , " ESC: leave \n SPACE/BACKSP: next/prev model (%i/%i) \n A/D: rotate y \n W/S: rotate x \n Q/E: rotate z \n R: reset orientation " , view_idx , N_polygon_models - 1 ) ;
break ;
case EVENT_WINDOW_CLOSE :
load_palette ( MENU_PALETTE , 0 , 1 ) ;
key_toggle_repeat ( 0 ) ;
break ;
default :
break ;
}
return 0 ;
}
void polygon_models_viewer ( )
{
window * wind = window_create ( & grd_curscreen - > sc_canvas , 0 , 0 , SWIDTH , SHEIGHT , ( int ( * ) ( window * , d_event * , void * ) ) polygon_models_viewer_handler , NULL ) ;
if ( ! wind )
{
d_event event = { EVENT_WINDOW_CLOSE } ;
polygon_models_viewer_handler ( NULL , & event ) ;
return ;
}
while ( window_exists ( wind ) )
event_process ( ) ;
}
int gamebitmaps_viewer_handler ( window * wind , d_event * event )
{
static int view_idx = 0 ;
int key = 0 ;
# ifdef OGL
float scale = 1.0 ;
# endif
bitmap_index bi ;
grs_bitmap * bm ;
extern int Num_bitmap_files ;
switch ( event - > type )
{
case EVENT_WINDOW_ACTIVATED :
gr_use_palette_table ( " groupa.256 " ) ;
key_toggle_repeat ( 1 ) ;
view_idx = 0 ;
break ;
case EVENT_KEY_COMMAND :
key = event_key_get ( event ) ;
switch ( key )
{
case KEY_ESC :
window_close ( wind ) ;
break ;
case KEY_SPACEBAR :
view_idx + + ;
if ( view_idx > = Num_bitmap_files ) view_idx = 0 ;
break ;
case KEY_BACKSP :
view_idx - - ;
if ( view_idx < 0 ) view_idx = Num_bitmap_files - 1 ;
break ;
default :
break ;
}
return 1 ;
case EVENT_WINDOW_DRAW :
bi . index = view_idx ;
bm = & GameBitmaps [ view_idx ] ;
timer_delay ( F1_0 / 60 ) ;
PIGGY_PAGE_IN ( bi ) ;
gr_clear_canvas ( BM_XRGB ( 0 , 0 , 0 ) ) ;
# ifdef OGL
scale = ( bm - > bm_w > bm - > bm_h ) ? ( SHEIGHT / bm - > bm_w ) * 0.8 : ( SHEIGHT / bm - > bm_h ) * 0.8 ;
ogl_ubitmapm_cs ( ( SWIDTH / 2 ) - ( bm - > bm_w * scale / 2 ) , ( SHEIGHT / 2 ) - ( bm - > bm_h * scale / 2 ) , bm - > bm_w * scale , bm - > bm_h * scale , bm , - 1 , F1_0 ) ;
# else
gr_bitmap ( ( SWIDTH / 2 ) - ( bm - > bm_w / 2 ) , ( SHEIGHT / 2 ) - ( bm - > bm_h / 2 ) , bm ) ;
# endif
gr_set_curfont ( GAME_FONT ) ;
gr_set_fontcolor ( BM_XRGB ( 255 , 255 , 255 ) , - 1 ) ;
gr_printf ( FSPACX ( 1 ) , FSPACY ( 1 ) , " ESC: leave \n SPACE/BACKSP: next/prev bitmap (%i/%i) " , view_idx , Num_bitmap_files - 1 ) ;
break ;
case EVENT_WINDOW_CLOSE :
load_palette ( MENU_PALETTE , 0 , 1 ) ;
key_toggle_repeat ( 0 ) ;
break ;
default :
break ;
}
return 0 ;
}
void gamebitmaps_viewer ( )
{
window * wind = window_create ( & grd_curscreen - > sc_canvas , 0 , 0 , SWIDTH , SHEIGHT , ( int ( * ) ( window * , d_event * , void * ) ) gamebitmaps_viewer_handler , NULL ) ;
if ( ! wind )
{
d_event event = { EVENT_WINDOW_CLOSE } ;
gamebitmaps_viewer_handler ( NULL , & event ) ;
return ;
}
while ( window_exists ( wind ) )
event_process ( ) ;
}
int sandbox_menuset ( newmenu * menu , d_event * event , void * userdata )
{
switch ( event - > type )
{
case EVENT_NEWMENU_CHANGED :
break ;
case EVENT_NEWMENU_SELECTED :
switch ( newmenu_get_citem ( menu ) )
{
case 0 : polygon_models_viewer ( ) ; break ;
case 1 : gamebitmaps_viewer ( ) ; break ;
}
return 1 ; // stay in menu until escape
break ;
case EVENT_WINDOW_CLOSE :
{
newmenu_item * items = newmenu_get_items ( menu ) ;
d_free ( items ) ;
break ;
}
default :
break ;
}
userdata = userdata ; //kill warning
return 0 ;
}
void do_sandbox_menu ( )
{
newmenu_item * m ;
MALLOC ( m , newmenu_item , 2 ) ;
if ( ! m )
return ;
m [ 0 ] . type = NM_TYPE_MENU ; m [ 0 ] . text = " Polygon_models viewer " ;
m [ 1 ] . type = NM_TYPE_MENU ; m [ 1 ] . text = " GameBitmaps viewer " ;
newmenu_do3 ( NULL , " Coder's sandbox " , 2 , m , sandbox_menuset , NULL , 0 , NULL ) ;
}
# endif