2006-03-20 17:12:09 +00:00
/*
2014-06-01 17:55:23 +00:00
* Portions of this file are copyright Rebirth contributors and licensed as
* described in COPYING . txt .
* Portions of this file are copyright Parallax Software and licensed
* according to the Parallax license below .
* See COPYING . txt for license details .
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 . c : Entry point of program ( main procedure )
*
* After main initializes everything , most of the time is spent in the loop
2010-04-04 01:31:48 +00:00
* while ( window_get_front ( ) )
2006-03-20 17:12:09 +00:00
* In this loop , the main menu is brought up first .
*
* main ( ) for Inferno
*
*/
2015-11-24 04:05:35 +00:00
extern const char copyright [ ] ;
const
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_I)
char copyright [ ] = " DESCENT COPYRIGHT (C) 1994,1995 PARALLAX SOFTWARE CORPORATION " ;
# elif defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
char copyright [ ] = " DESCENT II COPYRIGHT (C) 1994-1996 PARALLAX SOFTWARE CORPORATION " ;
2013-03-03 01:03:33 +00:00
# endif
2006-03-20 17:12:09 +00:00
2018-12-30 00:43:58 +00:00
# include "dxxsconf.h"
2006-03-20 17:12:09 +00:00
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <limits.h>
2013-06-30 02:22:56 +00:00
# include <SDL.h>
2006-03-20 17:12:09 +00:00
# ifdef __unix__
# include <unistd.h>
# include <sys/stat.h>
# include <sys/types.h>
# endif
2016-07-21 01:43:23 +00:00
# include <cctype>
2016-09-13 11:34:32 +00:00
# include <locale>
2006-03-20 17:12:09 +00:00
# include "pstypes.h"
# include "strutil.h"
# include "console.h"
# include "gr.h"
# include "key.h"
# include "3d.h"
# include "bm.h"
# include "inferno.h"
2012-07-07 18:35:06 +00:00
# include "dxxerror.h"
2015-07-25 23:10:45 +00:00
# include "player.h"
2006-03-20 17:12:09 +00:00
# include "game.h"
# include "u_mem.h"
# include "screens.h"
# include "texmap.h"
# include "texmerge.h"
# include "menu.h"
# include "digi.h"
# include "palette.h"
# include "args.h"
# include "titles.h"
# include "text.h"
2007-12-29 14:18:49 +00:00
# include "gauges.h"
2006-03-20 17:12:09 +00:00
# include "gamefont.h"
# include "kconfig.h"
# include "newmenu.h"
# include "config.h"
# include "multi.h"
# include "songs.h"
# include "gameseq.h"
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
# include "gamepal.h"
# include "movie.h"
2013-03-03 01:03:33 +00:00
# endif
2006-10-21 09:23:52 +00:00
# include "playsave.h"
2007-02-10 23:19:21 +00:00
# include "collide.h"
2007-04-04 10:24:03 +00:00
# include "newdemo.h"
2007-07-14 22:36:04 +00:00
# include "joy.h"
2017-11-01 02:01:20 +00:00
# if !DXX_USE_OGL
2006-03-20 17:12:09 +00:00
# include "../texmap/scanline.h" //for select_tmap -MM
2017-11-01 02:01:20 +00:00
# endif
2009-05-22 10:53:14 +00:00
# include "event.h"
2010-04-02 05:01:08 +00:00
# include "rbaudio.h"
2016-10-09 17:35:03 +00:00
# if DXX_WORDS_NEED_ALIGNMENT
2014-10-10 02:43:14 +00:00
# include <sys/prctl.h>
# endif
2016-09-11 18:49:16 +00:00
# if DXX_USE_EDITOR
2018-12-30 00:43:58 +00:00
# include "messagebox.h"
2006-03-20 17:12:09 +00:00
# include "editor/editor.h"
# include "editor/kdefs.h"
# include "ui.h"
# endif
# include "vers_id.h"
2016-09-11 18:49:15 +00:00
# if DXX_USE_UDP
2011-06-30 23:00:59 +00:00
# include "net_udp.h"
# endif
2016-03-19 19:08:10 +00:00
# include "dsx-ns.h"
2014-07-05 16:48:12 +00:00
2020-05-17 23:35:26 +00:00
# if DXX_USE_SDLIMAGE
# include <SDL_image.h>
# endif
2017-08-26 19:47:51 +00:00
# if DXX_USE_SDLMIXER
# include <SDL_mixer.h>
# endif
2015-12-13 18:00:49 +00:00
namespace dsx {
2015-12-05 22:57:25 +00:00
2006-03-20 17:12:09 +00:00
int Screen_mode = - 1 ; //game screen or editor screen?
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_I)
2020-08-10 03:45:13 +00:00
uint8_t HiresGFXAvailable ;
2013-03-03 01:03:33 +00:00
int MacHog = 0 ; // using a Mac hogfile?
# endif
2006-03-20 17:12:09 +00:00
//read help from a file & print to screen
2013-10-27 22:00:14 +00:00
static void print_commandline_help ( )
2006-03-20 17:12:09 +00:00
{
2016-01-09 16:38:10 +00:00
# define DXX_COMMAND_LINE_HELP_FMT(FMT,...) FMT
# define DXX_COMMAND_LINE_HELP_ARG(FMT,...) , ## __VA_ARGS__
2006-10-18 12:53:34 +00:00
2016-01-09 16:38:10 +00:00
# define DXX_if_defined_placeholder1 ,
# define DXX_if_defined_unwrap(A,...) A, ## __VA_ARGS__
# define DXX_if_defined(V,F) DXX_if_defined2(V,F)
# define DXX_if_defined2(V,F) DXX_if_defined3(DXX_if_defined_placeholder##V, F)
# define DXX_if_defined3(V,F) DXX_if_defined4(F, V 1, 0)
# define DXX_if_defined4(F,_,V,...) DXX_if_defined5_##V(F)
# define DXX_if_defined5_0(F)
# define DXX_if_defined5_1(F) DXX_if_defined_unwrap F
2016-09-11 18:49:15 +00:00
# define DXX_if_defined_01(V,F) DXX_if_defined4(F,,V)
2006-10-18 12:53:34 +00:00
2016-01-09 16:38:10 +00:00
# define DXX_COMMAND_LINE_HELP_unix(V) DXX_if_defined(__unix__, (V))
# define DXX_COMMAND_LINE_HELP_D1(V) DXX_if_defined(DXX_BUILD_DESCENT_I, (V))
# define DXX_COMMAND_LINE_HELP_D2(V) DXX_if_defined(DXX_BUILD_DESCENT_II, (V))
# define DXX_STRINGIZE2(X) #X
# define DXX_STRINGIZE(X) DXX_STRINGIZE2(X)
2006-10-18 12:53:34 +00:00
2016-09-24 18:06:11 +00:00
# if DXX_USE_OGL
2016-01-09 16:38:10 +00:00
# define DXX_COMMAND_LINE_HELP_OGL(V) V
# define DXX_COMMAND_LINE_HELP_SDL(V)
# else
# define DXX_COMMAND_LINE_HELP_OGL(V)
# define DXX_COMMAND_LINE_HELP_SDL(V) V
2013-03-03 01:03:33 +00:00
# endif
2006-10-18 12:53:34 +00:00
2016-01-09 16:38:10 +00:00
# define DXX_COMMAND_LINE_HELP(VERB) \
VERB ( " \n System Options: \n \n " ) \
VERB ( " -nonicefps Don't free CPU-cycles \n " ) \
VERB ( " -maxfps <n> Set maximum framerate to <n> \n \t \t \t \t (default: " DXX_STRINGIZE ( MAXIMUM_FPS ) " , available: " DXX_STRINGIZE ( MINIMUM_FPS ) " - " DXX_STRINGIZE ( MAXIMUM_FPS ) " ) \n " ) \
VERB ( " -hogdir <s> set shared data directory to <s> \n " ) \
DXX_COMMAND_LINE_HELP_unix ( \
VERB ( " -nohogdir don't try to use shared data directory \n " ) \
) \
VERB ( " -add-missions-dir <s> Add contents of location <s> to the missions directory \n " ) \
VERB ( " -use_players_dir Put player files and saved games in Players subdirectory \n " ) \
VERB ( " -lowmem Lowers animation detail for better performance with \n \t \t \t \t low memory \n " ) \
VERB ( " -pilot <s> Select pilot <s> automatically \n " ) \
VERB ( " -auto-record-demo Start recording on level entry \n " ) \
VERB ( " -record-demo-format Set demo name automatically \n " ) \
VERB ( " -autodemo Start in demo mode \n " ) \
VERB ( " -window Run the game in a window \n " ) \
VERB ( " -noborders Don't show borders in window mode \n " ) \
DXX_COMMAND_LINE_HELP_D1 ( \
VERB ( " -notitles Skip title screens \n " ) \
) \
DXX_COMMAND_LINE_HELP_D2 ( \
VERB ( " -nomovies Don't play movies \n " ) \
) \
VERB ( " \n Controls: \n \n " ) \
VERB ( " -nocursor Hide mouse cursor \n " ) \
VERB ( " -nomouse Deactivate mouse \n " ) \
VERB ( " -nojoystick Deactivate joystick \n " ) \
VERB ( " -nostickykeys Make CapsLock and NumLock non-sticky \n " ) \
VERB ( " \n Sound: \n \n " ) \
VERB ( " -nosound Disables sound output \n " ) \
VERB ( " -nomusic Disables music output \n " ) \
DXX_COMMAND_LINE_HELP_D2 ( \
VERB ( " -sound11k Use 11KHz sounds \n " ) \
) \
2016-09-11 18:49:15 +00:00
DXX_if_defined_01 ( DXX_USE_SDLMIXER , ( \
2016-01-09 16:38:10 +00:00
VERB ( " -nosdlmixer Disable Sound output via SDL_mixer \n " ) \
) ) \
VERB ( " \n Graphics: \n \n " ) \
VERB ( " -lowresfont Force use of low resolution fonts \n " ) \
DXX_COMMAND_LINE_HELP_D2 ( \
VERB ( " -lowresgraphics Force use of low resolution graphics \n " ) \
VERB ( " -lowresmovies Play low resolution movies if available (for slow machines) \n " ) \
) \
DXX_COMMAND_LINE_HELP_OGL ( \
VERB ( " -gl_fixedfont Don't scale fonts to current resolution \n " ) \
VERB ( " -gl_syncmethod <n> OpenGL sync method (default: %i) \n " , OGL_SYNC_METHOD_DEFAULT ) \
VERB ( " 0: Disabled \n " ) \
VERB ( " 1: Fence syncs, limit GPU latency to at most one frame \n " ) \
VERB ( " 2: Like 1, but sleep during sync to reduce CPU load \n " ) \
VERB ( " 3: Immediately sync after buffer swap \n " ) \
VERB ( " 4: Immediately sync after buffer swap \n " ) \
2018-04-22 15:49:16 +00:00
VERB ( " 5: Auto: if VSync is enabled and ARB_sync is supported, use mode 2, otherwise mode 0 \n " ) \
2016-01-09 16:38:10 +00:00
VERB ( " -gl_syncwait <n> Wait interval (ms) for sync mode 2 (default: " DXX_STRINGIZE ( OGL_SYNC_WAIT_DEFAULT ) " ) \n " ) \
2016-08-29 15:07:30 +00:00
VERB ( " -gl_darkedges Re-enable dark edges around filtered textures (as present in earlier versions of the engine) \n " ) \
2016-01-09 16:38:10 +00:00
) \
2016-10-08 23:24:22 +00:00
DXX_if_defined_01 ( DXX_USE_UDP , ( \
2016-01-09 16:38:10 +00:00
VERB ( " \n Multiplayer: \n \n " ) \
VERB ( " -udp_hostaddr <s> Use IP address/Hostname <s> for manual game joining \n \t \t \t \t (default: %s) \n " , UDP_MANUAL_ADDR_DEFAULT ) \
2017-10-14 17:10:30 +00:00
VERB ( " -udp_hostport <n> Use UDP port <n> for manual game joining (default: %hu) \n " , UDP_PORT_DEFAULT ) \
VERB ( " -udp_myport <n> Set my own UDP port to <n> (default: %hu) \n " , UDP_PORT_DEFAULT ) \
2016-10-08 23:24:22 +00:00
DXX_if_defined_01 ( DXX_USE_TRACKER , ( \
VERB ( " -no-tracker Disable tracker (unless overridden by later -tracker_hostaddr) \n " ) \
2016-01-09 16:38:10 +00:00
VERB ( " -tracker_hostaddr <n> Address of tracker server to register/query games to/from \n \t \t \t \t (default: %s) \n " , TRACKER_ADDR_DEFAULT ) \
2017-10-14 17:10:30 +00:00
VERB ( " -tracker_hostport <n> Port of tracker server to register/query games to/from \n \t \t \t \t (default: %hu) \n " , TRACKER_PORT_DEFAULT ) \
2016-01-09 16:38:10 +00:00
) ) \
) ) \
DXX_if_defined ( EDITOR , ( \
VERB ( " \n Editor: \n \n " ) \
DXX_COMMAND_LINE_HELP_D1 ( \
VERB ( " -nobm Don't load BITMAPS.TBL and BITMAPS.BIN - use internal data \n " ) \
) \
DXX_COMMAND_LINE_HELP_D2 ( \
VERB ( " -autoload <s> Autoload level <s> in the editor \n " ) \
VERB ( " -macdata Read and write Mac data files in editor (swap colors) \n " ) \
VERB ( " -hoarddata Make the Hoard ham file from some files, then exit \n " ) \
) \
) ) \
VERB ( " \n Debug (use only if you know what you're doing): \n \n " ) \
VERB ( " -debug Enable debugging output. \n " ) \
VERB ( " -verbose Enable verbose output. \n " ) \
VERB ( " -safelog Write gamelog.txt unbuffered. \n \t \t \t \t Use to keep helpful output to trace program crashes. \n " ) \
VERB ( " -norun Bail out after initialization \n " ) \
VERB ( " -no-grab Never grab keyboard/mouse \n " ) \
VERB ( " -renderstats Enable renderstats info by default \n " ) \
VERB ( " -text <s> Specify alternate .tex file \n " ) \
VERB ( " -showmeminfo Show memory statistics \n " ) \
VERB ( " -nodoublebuffer Disable Doublebuffering \n " ) \
VERB ( " -bigpig Use uncompressed RLE bitmaps \n " ) \
VERB ( " -16bpp Use 16Bpp instead of 32Bpp \n " ) \
DXX_COMMAND_LINE_HELP_OGL ( \
VERB ( " -gl_oldtexmerge Use old texmerge, uses more ram, but might be faster \n " ) \
VERB ( " -gl_intensity4_ok <n> Override DbgGlIntensity4Ok (default: 1) \n " ) \
VERB ( " -gl_luminance4_alpha4_ok <n> Override DbgGlLuminance4Alpha4Ok (default: 1) \n " ) \
VERB ( " -gl_rgba2_ok <n> Override DbgGlRGBA2Ok (default: 1) \n " ) \
VERB ( " -gl_readpixels_ok <n> Override DbgGlReadPixelsOk (default: 1) \n " ) \
VERB ( " -gl_gettexlevelparam_ok <n> Override DbgGlGetTexLevelParamOk (default: 1) \n " ) \
) \
DXX_COMMAND_LINE_HELP_SDL ( \
2016-08-30 11:15:55 +00:00
VERB ( " -tmap <s> Select texmapper <s> to use \n \t \t \t \t (default: c, available: c, fp, quad) \n " ) \
2016-01-09 16:38:10 +00:00
VERB ( " -hwsurface Use SDL HW Surface \n " ) \
VERB ( " -asyncblit Use queued blits over SDL. Can speed up rendering \n " ) \
) \
VERB ( " \n Help: \n \n " ) \
VERB ( " -help, -h, -?, ? View this help screen \n " ) \
VERB ( " \n \n " ) \
2007-07-18 20:13:17 +00:00
2016-01-09 16:38:10 +00:00
printf ( DXX_COMMAND_LINE_HELP ( DXX_COMMAND_LINE_HELP_FMT ) DXX_COMMAND_LINE_HELP ( DXX_COMMAND_LINE_HELP_ARG ) ) ;
2006-03-20 17:12:09 +00:00
}
2010-07-25 01:22:44 +00:00
int Quitting = 0 ;
2010-04-04 01:31:48 +00:00
2015-12-05 22:57:25 +00:00
}
2015-12-13 18:00:49 +00:00
namespace dcx {
2015-12-05 22:57:25 +00:00
2010-04-02 05:01:08 +00:00
// Default event handler for everything except the editor
2016-10-27 08:36:24 +00:00
window_event_result standard_handler ( const d_event & event )
2010-04-02 05:01:08 +00:00
{
int key ;
2010-06-14 08:13:16 +00:00
2010-07-25 01:22:44 +00:00
if ( Quitting )
{
window * wind = window_get_front ( ) ;
if ( ! wind )
2016-10-27 08:36:24 +00:00
return window_event_result : : ignored ; // finished quitting
2010-07-25 01:22:44 +00:00
if ( wind = = Game_wind )
{
Quitting = 0 ;
2020-12-19 16:13:26 +00:00
const auto choice = nm_messagebox_str ( menu_title { nullptr } , nm_messagebox_tie ( TXT_YES , TXT_NO ) , menu_subtitle { TXT_ABORT_GAME } ) ;
2010-07-25 01:22:44 +00:00
if ( choice ! = 0 )
2016-10-27 08:36:24 +00:00
return window_event_result : : handled ; // aborted quitting
2010-07-25 01:22:44 +00:00
else
2010-11-30 22:45:10 +00:00
{
2015-12-24 04:01:27 +00:00
CGameArg . SysAutoDemo = false ;
2010-07-25 01:22:44 +00:00
Quitting = 1 ;
2010-11-30 22:45:10 +00:00
}
2010-07-25 01:22:44 +00:00
}
// Close front window, let the code flow continue until all windows closed or quit cancelled
2012-04-09 12:41:47 +00:00
if ( ! window_close ( wind ) )
2016-10-27 08:36:24 +00:00
{
2012-04-09 12:41:47 +00:00
Quitting = 0 ;
2016-10-27 08:36:24 +00:00
return window_event_result : : handled ;
}
2010-07-25 01:22:44 +00:00
2016-10-27 08:36:24 +00:00
return window_event_result : : deleted ; // tell the event system we deleted some window
2010-07-25 01:22:44 +00:00
}
2014-10-04 21:47:13 +00:00
switch ( event . type )
2010-04-02 05:01:08 +00:00
{
case EVENT_MOUSE_BUTTON_DOWN :
case EVENT_MOUSE_BUTTON_UP :
// No window selecting
// We stay with the current one until it's closed/hidden or another one is made
// Not the case for the editor
break ;
2010-06-14 08:13:16 +00:00
2010-04-02 05:01:08 +00:00
case EVENT_KEY_COMMAND :
2011-01-14 09:51:13 +00:00
key = event_key_get ( event ) ;
2010-06-14 08:13:16 +00:00
2010-04-02 05:01:08 +00:00
switch ( key )
{
2018-06-16 04:13:37 +00:00
# if DXX_USE_SCREENSHOT
2010-04-02 05:01:08 +00:00
# ifdef macintosh
case KEY_COMMAND + KEY_SHIFTED + KEY_3 :
# endif
case KEY_PRINT_SCREEN :
{
2017-11-05 20:49:08 +00:00
gr_set_default_canvas ( ) ;
2010-04-02 05:01:08 +00:00
save_screen_shot ( 0 ) ;
2016-10-27 08:36:24 +00:00
return window_event_result : : handled ;
2010-04-02 05:01:08 +00:00
}
2018-06-16 04:13:37 +00:00
# endif
2010-06-14 08:13:16 +00:00
2010-04-02 05:01:08 +00:00
case KEY_ALTED + KEY_ENTER :
case KEY_ALTED + KEY_PADENTER :
2013-01-08 16:29:23 +00:00
if ( Game_wind )
2020-08-28 00:18:45 +00:00
if ( window_get_front ( ) = = Game_wind )
2016-10-27 08:36:24 +00:00
return window_event_result : : ignored ;
2010-04-02 05:01:08 +00:00
gr_toggle_fullscreen ( ) ;
2018-07-28 23:22:58 +00:00
# if SDL_MAJOR_VERSION == 2
{
/* Hack to force the canvas to adjust to the new
* dimensions . Without this , the canvas
* continues to use the old window size until
* the hack of calling ` init_cockpit ` from
* ` game_handler ` fixes the dimensions . If the
* window became bigger , the game fails to draw
* in the full new area . If the window became
* smaller , part of the game is outside the
* cropped area .
*
* If the automap is open , the view is still
* wrong , since the automap uses its own private
* canvas . That will need to be fixed
* separately . Ideally , the whole window
* system would be reworked to provide a general
* notification to every interested canvas when
* the top level window resizes .
*/
auto sm = Screen_mode ;
Screen_mode = SCREEN_GAME ;
init_cockpit ( ) ;
Screen_mode = sm ;
}
# endif
2016-10-27 08:36:24 +00:00
return window_event_result : : handled ;
2010-06-14 08:13:16 +00:00
2010-04-02 05:01:08 +00:00
# if defined(__APPLE__) || defined(macintosh)
case KEY_COMMAND + KEY_Q :
// Alt-F4 already taken, too bad
2010-07-25 01:22:44 +00:00
Quitting = 1 ;
2016-10-27 08:36:24 +00:00
return window_event_result : : handled ;
2010-04-02 05:01:08 +00:00
# endif
2011-01-16 10:55:31 +00:00
case KEY_SHIFTED + KEY_ESC :
2020-10-12 03:28:26 +00:00
con_showup ( Controls ) ;
2016-10-27 08:36:24 +00:00
return window_event_result : : handled ;
2010-04-02 05:01:08 +00:00
}
break ;
2010-06-14 08:13:16 +00:00
2011-07-16 14:02:22 +00:00
case EVENT_WINDOW_DRAW :
2010-04-02 05:01:08 +00:00
case EVENT_IDLE :
//see if redbook song needs to be restarted
2018-07-14 17:23:15 +00:00
# if DXX_USE_SDL_REDBOOK_AUDIO
2010-04-02 05:01:08 +00:00
RBACheckFinishedHook ( ) ;
2018-07-14 17:23:15 +00:00
# endif
2016-10-27 08:36:24 +00:00
return window_event_result : : handled ;
2010-06-14 08:13:16 +00:00
2010-04-04 01:31:48 +00:00
case EVENT_QUIT :
2016-09-11 18:49:16 +00:00
# if DXX_USE_EDITOR
2012-04-09 12:41:47 +00:00
if ( SafetyCheck ( ) )
# endif
Quitting = 1 ;
2016-10-27 08:36:24 +00:00
return window_event_result : : handled ;
2010-04-04 01:31:48 +00:00
2010-04-02 05:01:08 +00:00
default :
break ;
}
2010-06-14 08:13:16 +00:00
2016-10-27 08:36:24 +00:00
return window_event_result : : ignored ;
2010-04-02 05:01:08 +00:00
}
2019-07-07 22:00:02 +00:00
# if DXX_HAVE_POISON
d_interface_unique_state : : d_interface_unique_state ( )
{
DXX_MAKE_VAR_UNDEFINED ( PilotName ) ;
}
# endif
2019-07-07 22:00:02 +00:00
void d_interface_unique_state : : update_window_title ( )
{
# if SDL_MAJOR_VERSION == 1
2019-07-22 00:51:01 +00:00
if ( ! PilotName [ 0u ] )
2019-07-07 22:00:02 +00:00
SDL_WM_SetCaption ( DESCENT_VERSION , DXX_SDL_WINDOW_CAPTION ) ;
else
{
const char * const pilot = PilotName ;
std : : array < char , 80 > wm_caption_name , wm_caption_iconname ;
snprintf ( wm_caption_name . data ( ) , wm_caption_name . size ( ) , " %s: %s " , DESCENT_VERSION , pilot ) ;
snprintf ( wm_caption_iconname . data ( ) , wm_caption_iconname . size ( ) , " %s: %s " , DXX_SDL_WINDOW_CAPTION , pilot ) ;
SDL_WM_SetCaption ( wm_caption_name . data ( ) , wm_caption_iconname . data ( ) ) ;
}
# endif
}
2015-12-05 22:57:25 +00:00
}
2015-12-13 18:00:49 +00:00
namespace dsx {
2015-12-05 22:57:25 +00:00
2006-03-20 17:12:09 +00:00
# define PROGNAME argv[0]
2016-10-21 02:16:47 +00:00
# define DXX_RENAME_IDENTIFIER2(I,N) I##$##N
# define DXX_RENAME_IDENTIFIER(I,N) DXX_RENAME_IDENTIFIER2(I,N)
# define argc DXX_RENAME_IDENTIFIER(argc_gc, DXX_git_commit)
2019-12-29 22:24:20 +00:00
# define argv DXX_RENAME_IDENTIFIER(argv_gd$b32, DXX_git_describe)
2006-03-20 17:12:09 +00:00
2013-03-03 01:03:33 +00:00
// DESCENT by Parallax Software
2006-03-20 17:12:09 +00:00
// DESCENT II by Parallax Software
2013-03-03 01:03:33 +00:00
// (varies based on preprocessor options)
2006-03-20 17:12:09 +00:00
// Descent Main
2015-12-05 22:57:25 +00:00
static int main ( int argc , char * argv [ ] )
2006-03-20 17:12:09 +00:00
{
2015-01-28 03:42:53 +00:00
if ( ! PHYSFSX_init ( argc , argv ) )
return 1 ;
2008-04-06 20:23:28 +00:00
con_init ( ) ; // Initialise the console
2006-03-20 17:12:09 +00:00
2009-05-31 07:20:26 +00:00
setbuf ( stdout , NULL ) ; // unbuffered output via printf
2010-11-26 12:15:56 +00:00
# ifdef _WIN32
freopen ( " CON " , " w " , stdout ) ;
freopen ( " CON " , " w " , stderr ) ;
# endif
2009-05-31 07:20:26 +00:00
2015-11-24 04:05:35 +00:00
if ( CGameArg . SysShowCmdHelp ) {
2010-11-22 13:19:37 +00:00
print_commandline_help ( ) ;
return ( 0 ) ;
}
2016-07-21 01:43:22 +00:00
printf ( " \n Type '%s -help' for a list of command-line options. \n \n " , PROGNAME ) ;
2010-11-22 13:19:37 +00:00
2010-11-26 11:50:18 +00:00
PHYSFSX_listSearchPathContent ( ) ;
2010-11-28 12:08:29 +00:00
2010-11-26 11:50:18 +00:00
if ( ! PHYSFSX_checkSupportedArchiveTypes ( ) )
return ( 0 ) ;
2008-05-01 21:40:34 +00:00
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_I)
if ( ! PHYSFSX_contfile_init ( " descent.hog " , 1 ) )
# define DXX_NAME_NUMBER "1"
# define DXX_HOGFILE_NAMES "descent.hog"
# elif defined(DXX_BUILD_DESCENT_II)
if ( ! PHYSFSX_contfile_init ( " descent2.hog " , 1 ) & & ! PHYSFSX_contfile_init ( " d2demo.hog " , 1 ) )
2013-03-30 02:45:23 +00:00
# define DXX_NAME_NUMBER "2"
# define DXX_HOGFILE_NAMES "descent2.hog or d2demo.hog"
2013-03-03 01:03:33 +00:00
# endif
{
2008-01-19 00:55:54 +00:00
# if defined(__unix__) && !defined(__APPLE__)
2013-03-30 02:45:23 +00:00
# define DXX_HOGFILE_PROGRAM_DATA_DIRECTORY \
" \t $HOME/.d " DXX_NAME_NUMBER " x-rebirth \n " \
2018-05-17 02:49:15 +00:00
DXX_HOGFILE_SHAREPATH_INDENTED
2019-01-20 05:36:56 +00:00
# if DXX_USE_SHAREPATH
2018-05-17 02:49:15 +00:00
# define DXX_HOGFILE_SHAREPATH_INDENTED \
2018-09-14 02:20:55 +00:00
" \t " DXX_SHAREPATH " \n "
2006-03-20 17:12:09 +00:00
# else
2018-05-17 02:49:15 +00:00
# define DXX_HOGFILE_SHAREPATH_INDENTED
# endif
2020-09-09 07:28:51 +00:00
# elif (defined(__APPLE__) && defined(__MACH__))
2020-09-09 07:23:14 +00:00
# define DXX_HOGFILE_PROGRAM_DATA_DIRECTORY \
" \t ~/Library/Preferences/D " DXX_NAME_NUMBER " X Rebirth \n "
2018-05-17 02:49:15 +00:00
# else
2013-03-30 02:45:23 +00:00
# define DXX_HOGFILE_PROGRAM_DATA_DIRECTORY \
" \t Directory containing D " DXX_NAME_NUMBER " X \n "
2006-03-20 17:12:09 +00:00
# endif
2010-09-17 10:44:21 +00:00
# if (defined(__APPLE__) && defined(__MACH__)) || defined(macintosh)
2013-03-30 02:45:23 +00:00
# define DXX_HOGFILE_APPLICATION_BUNDLE \
2010-09-17 10:44:21 +00:00
" \t In 'Resources' inside the application bundle \n "
2013-03-30 02:45:23 +00:00
# else
# define DXX_HOGFILE_APPLICATION_BUNDLE ""
2010-09-17 10:44:21 +00:00
# endif
2013-03-30 02:45:23 +00:00
# define DXX_MISSING_HOGFILE_ERROR_TEXT \
" Could not find a valid hog file ( " DXX_HOGFILE_NAMES " ) \n Possible locations are: \n " \
DXX_HOGFILE_PROGRAM_DATA_DIRECTORY \
2019-08-25 17:06:34 +00:00
" \t In a subdirectory called 'data' \n " \
2013-03-30 02:45:23 +00:00
DXX_HOGFILE_APPLICATION_BUNDLE \
" Or use the -hogdir option to specify an alternate location. "
2015-10-09 02:46:11 +00:00
UserError ( DXX_MISSING_HOGFILE_ERROR_TEXT ) ;
2007-07-26 23:57:29 +00:00
}
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_I)
switch ( PHYSFSX_fsize ( " descent.hog " ) )
{
case D1_MAC_SHARE_MISSION_HOGSIZE :
case D1_MAC_MISSION_HOGSIZE :
MacHog = 1 ; // used for fonts and the Automap
break ;
}
# endif
2006-03-20 17:12:09 +00:00
load_text ( ) ;
//print out the banner title
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_I)
2013-12-07 00:47:27 +00:00
con_printf ( CON_NORMAL , " %s %s " , DESCENT_VERSION , g_descent_build_datetime ) ; // D1X version
2017-12-05 05:29:55 +00:00
con_puts ( CON_NORMAL , " This is a MODIFIED version of Descent, based on " BASED_VERSION " . " ) ;
2019-06-20 04:02:27 +00:00
con_puts ( CON_NORMAL , TXT_COPYRIGHT ) ;
con_puts ( CON_NORMAL , TXT_TRADEMARK ) ;
2017-12-05 05:29:55 +00:00
con_puts ( CON_NORMAL , " Copyright (C) 2005-2013 Christian Beckhaeuser, 2013-2017 Kp " ) ;
2013-03-03 01:03:33 +00:00
# elif defined(DXX_BUILD_DESCENT_II)
2013-12-07 00:47:27 +00:00
con_printf ( CON_NORMAL , " %s%s %s " , DESCENT_VERSION , PHYSFSX_exists ( MISSION_DIR " d2x.hog " , 1 ) ? " Vertigo Enhanced " : " " , g_descent_build_datetime ) ; // D2X version
2017-12-05 05:29:55 +00:00
con_puts ( CON_NORMAL , " This is a MODIFIED version of Descent 2, based on " BASED_VERSION " . " ) ;
2019-06-20 04:02:27 +00:00
con_puts ( CON_NORMAL , TXT_COPYRIGHT ) ;
con_puts ( CON_NORMAL , TXT_TRADEMARK ) ;
2017-12-05 05:29:55 +00:00
con_puts ( CON_NORMAL , " Copyright (C) 1999 Peter Hawkins, 2002 Bradley Bell, 2005-2013 Christian Beckhaeuser, 2013-2017 Kp " ) ;
2013-03-03 01:03:33 +00:00
# endif
2006-03-20 17:12:09 +00:00
2015-10-18 21:01:21 +00:00
if ( CGameArg . DbgVerbose )
2017-08-26 19:47:51 +00:00
{
{
PHYSFS_Version vc , vl ;
PHYSFS_VERSION ( & vc ) ;
PHYSFS_getLinkedVersion ( & vl ) ;
con_printf ( CON_VERBOSE , " D " DXX_NAME_NUMBER " X-Rebirth built with PhysFS %u.%u.%u; loaded with PhysFS %u.%u.%u " , vc . major , vc . minor , vc . patch , vl . major , vl . minor , vl . patch ) ;
}
{
SDL_version vc ;
SDL_VERSION ( & vc ) ;
2018-03-03 18:47:23 +00:00
# if SDL_MAJOR_VERSION == 1
2017-08-26 19:47:51 +00:00
const auto vl = SDL_Linked_Version ( ) ;
2018-03-03 18:47:23 +00:00
# else
SDL_version vlv ;
const auto vl = & vlv ;
SDL_GetVersion ( vl ) ;
# endif
2017-08-26 19:47:51 +00:00
con_printf ( CON_VERBOSE , " D " DXX_NAME_NUMBER " X-Rebirth built with libSDL %u.%u.%u; loaded with libSDL %u.%u.%u " , vc . major , vc . minor , vc . patch , vl - > major , vl - > minor , vl - > patch ) ;
}
2020-05-17 23:35:26 +00:00
# if DXX_USE_SDLIMAGE
{
SDL_version vc ;
SDL_IMAGE_VERSION ( & vc ) ;
const auto vl = IMG_Linked_Version ( ) ;
con_printf ( CON_VERBOSE , " D " DXX_NAME_NUMBER " X-Rebirth built with SDL_image %u.%u.%u; loaded with SDL_image %u.%u.%u " , vc . major , vc . minor , vc . patch , vl - > major , vl - > minor , vl - > patch ) ;
}
# endif
2017-08-26 19:47:51 +00:00
# if DXX_USE_SDLMIXER
{
SDL_version vc ;
SDL_MIXER_VERSION ( & vc ) ;
const auto vl = Mix_Linked_Version ( ) ;
con_printf ( CON_VERBOSE , " D " DXX_NAME_NUMBER " X-Rebirth built with SDL_mixer %u.%u.%u; loaded with SDL_mixer %u.%u.%u " , vc . major , vc . minor , vc . patch , vl - > major , vl - > minor , vl - > patch ) ;
}
# endif
2015-02-13 03:27:28 +00:00
con_puts ( CON_VERBOSE , TXT_VERBOSE_1 ) ;
2017-08-26 19:47:51 +00:00
}
2010-11-22 13:19:37 +00:00
ReadConfigFile ( ) ;
PHYSFSX_addArchiveContent ( ) ;
2006-03-20 17:12:09 +00:00
2020-01-06 01:25:35 +00:00
const auto & & arch_atexit_result = arch_init ( ) ;
2020-01-18 22:43:19 +00:00
/* This variable exists for the side effects that occur when it is
* destroyed . clang - 9 fails to recognize those side effects as a
* " use " and warns that the variable is unused . Cast it to void to
* create a " use " to suppress the warning .
*/
( void ) arch_atexit_result ;
2006-03-20 17:12:09 +00:00
2017-11-01 02:01:20 +00:00
# if !DXX_USE_OGL
2015-12-24 04:01:28 +00:00
select_tmap ( CGameArg . DbgTexMap ) ;
2006-03-20 17:12:09 +00:00
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
Lighting_on = 1 ;
2017-11-01 02:01:21 +00:00
# endif
2013-03-03 01:03:33 +00:00
# endif
2006-03-20 17:12:09 +00:00
2017-12-05 05:29:55 +00:00
con_puts ( CON_VERBOSE , " Going into graphics mode... " ) ;
2019-07-07 22:00:02 +00:00
# if DXX_USE_OGL
2018-07-28 23:22:58 +00:00
gr_set_mode_from_window_size ( ) ;
2019-07-07 22:00:02 +00:00
# else
gr_set_mode ( Game_screen_mode ) ;
# endif
2007-08-16 09:16:53 +00:00
2006-03-20 17:12:09 +00:00
// Load the palette stuff. Returns non-zero if error.
2017-12-05 05:29:55 +00:00
con_puts ( CON_DEBUG , " Initializing palette system... " ) ;
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_I)
gr_use_palette_table ( " PALETTE.256 " ) ;
# elif defined(DXX_BUILD_DESCENT_II)
2007-06-11 15:54:09 +00:00
gr_use_palette_table ( D2_DEFAULT_PALETTE ) ;
2013-03-03 01:03:33 +00:00
# endif
2006-03-20 17:12:09 +00:00
2017-12-05 05:29:55 +00:00
con_puts ( CON_DEBUG , " Initializing font system... " ) ;
2006-03-20 17:12:09 +00:00
gamefont_init ( ) ; // must load after palette data loaded.
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2017-12-05 05:29:55 +00:00
con_puts ( CON_DEBUG , " Initializing movie libraries... " ) ;
2006-03-20 17:12:09 +00:00
init_movies ( ) ; //init movie libraries
2013-03-03 01:03:33 +00:00
# endif
2006-03-20 17:12:09 +00:00
2007-03-03 18:27:55 +00:00
show_titles ( ) ;
2006-03-20 17:12:09 +00:00
2007-08-08 18:07:21 +00:00
set_screen_mode ( SCREEN_MENU ) ;
2016-12-08 03:32:06 +00:00
# ifdef DEBUG_MEMORY_ALLOCATIONS
/* Memdebug runs before global destructors, so it incorrectly
* reports as leaked any allocations that would be freed by a global
* destructor . This local will force the newmenu globals to be
* reset before memdebug scans , which prevents memdebug falsely
* reporting them as leaked .
*
* External tools , such as Valgrind , know to run global destructors
* before checking for leaks , so this hack is only necessary when
* memdebug is used .
*/
struct hack_free_global_backgrounds
{
~ hack_free_global_backgrounds ( )
{
newmenu_free_background ( ) ;
}
} ;
hack_free_global_backgrounds hack_free_global_background ;
# endif
2007-08-08 18:07:21 +00:00
2017-12-05 05:29:55 +00:00
con_puts ( CON_DEBUG , " Doing gamedata_init... " ) ;
2008-02-11 12:12:57 +00:00
gamedata_init ( ) ;
2006-03-20 17:12:09 +00:00
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2016-09-11 18:49:16 +00:00
# if DXX_USE_EDITOR
2007-07-18 20:13:17 +00:00
if ( GameArg . EdiSaveHoardData ) {
2006-10-02 13:29:04 +00:00
save_hoard_data ( ) ;
2006-03-20 17:12:09 +00:00
exit ( 1 ) ;
}
# endif
2013-03-03 01:03:33 +00:00
# endif
2006-03-20 17:12:09 +00:00
2015-12-24 04:01:28 +00:00
if ( CGameArg . DbgNoRun )
2006-03-20 17:12:09 +00:00
return ( 0 ) ;
2017-12-05 05:29:55 +00:00
con_puts ( CON_DEBUG , " Initializing texture caching system... " ) ;
2016-11-19 17:24:52 +00:00
texmerge_init ( ) ; // 10 cache bitmaps
2006-03-20 17:12:09 +00:00
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2010-06-14 08:13:16 +00:00
piggy_init_pigfile ( " groupa.pig " ) ; //get correct pigfile
2013-03-03 01:03:33 +00:00
# endif
2007-10-29 21:40:49 +00:00
2017-12-05 05:29:55 +00:00
con_puts ( CON_DEBUG , " Running game... " ) ;
2006-03-20 17:12:09 +00:00
init_game ( ) ;
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_I)
key_flush ( ) ;
# endif
2006-10-10 09:53:58 +00:00
{
2019-07-07 22:00:02 +00:00
InterfaceUniqueState . PilotName . fill ( 0 ) ;
2015-12-24 04:01:26 +00:00
if ( ! CGameArg . SysPilot . empty ( ) )
2006-10-10 09:53:58 +00:00
{
2016-07-21 01:43:22 +00:00
char filename [ sizeof ( PLAYER_DIRECTORY_TEXT ) + CALLSIGN_LEN + 4 ] ;
2010-06-14 08:13:16 +00:00
2016-07-22 02:25:17 +00:00
/* Step over the literal PLAYER_DIRECTORY_TEXT when it is
* present . Point at & filename [ 0 ] when
* PLAYER_DIRECTORY_TEXT is absent .
*/
const auto b = & filename [ - CGameArg . SysUsePlayersDir ] ;
2015-12-24 04:01:26 +00:00
snprintf ( filename , sizeof ( filename ) , PLAYER_DIRECTORY_STRING ( " %.12s " ) , CGameArg . SysPilot . c_str ( ) ) ;
2016-07-21 01:43:23 +00:00
/* The pilot name is never used after this. Clear it to
* free the allocated memory , if any .
*/
CGameArg . SysPilot . clear ( ) ;
2016-07-22 02:25:17 +00:00
auto p = b ;
for ( const auto & facet = std : : use_facet < std : : ctype < char > > ( std : : locale : : classic ( ) ) ; char & c = * p ; + + p )
2015-12-24 04:01:26 +00:00
{
2016-07-21 01:43:23 +00:00
c = facet . tolower ( static_cast < uint8_t > ( c ) ) ;
2006-10-18 12:53:34 +00:00
}
2016-07-22 02:25:17 +00:00
auto j = p - filename ;
2014-07-05 03:32:08 +00:00
if ( j < sizeof ( filename ) - 4 & & ( j < = 4 | | strcmp ( & filename [ j - 4 ] , " .plr " ) ) ) // if player hasn't specified .plr extension in argument, add it
{
strcpy ( & filename [ j ] , " .plr " ) ;
j + = 4 ;
}
2011-06-01 07:59:55 +00:00
if ( PHYSFSX_exists ( filename , 0 ) )
2006-10-10 09:53:58 +00:00
{
2019-07-07 22:00:02 +00:00
InterfaceUniqueState . PilotName . copy ( b , std : : distance ( b , & filename [ j - 4 ] ) ) ;
2019-07-07 22:00:02 +00:00
InterfaceUniqueState . update_window_title ( ) ;
2006-10-10 09:53:58 +00:00
read_player_file ( ) ;
WriteConfigFile ( ) ;
}
}
}
2006-03-20 17:12:09 +00:00
2013-03-03 01:03:33 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2016-09-11 18:49:16 +00:00
# if DXX_USE_EDITOR
2015-03-22 18:49:20 +00:00
if ( ! GameArg . EdiAutoLoad . empty ( ) ) {
2014-12-20 04:36:11 +00:00
/* Any number >= FILENAME_LEN works */
2015-03-22 18:49:20 +00:00
Level_names [ 0 ] . copy_if ( GameArg . EdiAutoLoad . c_str ( ) , GameArg . EdiAutoLoad . size ( ) ) ;
2010-02-07 04:34:21 +00:00
LoadLevel ( 1 , 1 ) ;
}
2010-04-04 01:31:48 +00:00
else
2013-03-03 01:03:33 +00:00
# endif
2008-04-06 20:23:28 +00:00
# endif
2010-04-04 01:31:48 +00:00
{
2020-08-06 03:47:56 +00:00
Game_mode = { } ;
2010-04-04 01:31:48 +00:00
DoMenu ( ) ;
}
2009-05-21 12:16:39 +00:00
2010-04-04 01:31:48 +00:00
while ( window_get_front ( ) )
2009-05-21 12:16:39 +00:00
// Send events to windows and the default handler
2010-04-04 01:31:48 +00:00
event_process ( ) ;
2012-03-19 05:49:19 +00:00
// Tidy up - avoids a crash on exit
{
window * wind ;
show_menus ( ) ;
while ( ( wind = window_get_front ( ) ) )
window_close ( wind ) ;
}
2006-03-20 17:12:09 +00:00
WriteConfigFile ( ) ;
2017-12-05 05:29:55 +00:00
con_puts ( CON_DEBUG , " Cleanup... " ) ;
2008-11-14 16:56:40 +00:00
close_game ( ) ;
texmerge_close ( ) ;
gamedata_close ( ) ;
gamefont_close ( ) ;
2014-07-20 22:13:25 +00:00
Current_mission . reset ( ) ;
2010-08-15 06:57:51 +00:00
PHYSFSX_removeArchiveContent ( ) ;
2007-12-23 00:51:59 +00:00
2006-03-20 17:12:09 +00:00
return ( 0 ) ; //presumably successful exit
}
2015-12-05 22:57:25 +00:00
}
int main ( int argc , char * argv [ ] )
{
2016-01-09 16:38:11 +00:00
mem_init ( ) ;
2016-10-09 17:35:03 +00:00
# if DXX_WORDS_NEED_ALIGNMENT
2016-01-09 16:38:11 +00:00
prctl ( PR_SET_UNALIGN , PR_UNALIGN_NOPRINT , 0 , 0 , 0 ) ;
# endif
2018-12-30 00:43:58 +00:00
# if defined(WIN32) || defined(__APPLE__) || defined(__MACH__)
# if DXX_USE_EDITOR
2016-01-09 16:38:11 +00:00
set_warn_func ( msgbox_warning ) ;
2017-04-22 21:23:56 +00:00
# endif
# ifdef WIN32
void d_set_exception_handler ( ) ;
d_set_exception_handler ( ) ;
2018-12-30 00:43:58 +00:00
# endif
2016-01-09 16:38:11 +00:00
# endif
2015-12-05 22:57:25 +00:00
return dsx : : main ( argc , argv ) ;
}
2016-10-21 02:16:47 +00:00
# undef argv
# undef argc