19#include "physfsrwops.h"
30#include "background.h"
35#include "damagetype.h"
38#include "difficulty.h"
52#include "map_overlay.h"
53#include "map_system.h"
61#include "nlua_colour.h"
78#include "player_autonav.h"
91#include "threadpool.h"
96#define VERSION_FILE "VERSION"
121static int load_force_render = 0;
122static unsigned int load_last_render = 0;
123static SDL_mutex *load_mutex;
132static void load_all(
void );
166int main(
int argc,
char **argv )
168 char conf_file_path[
PATH_MAX], **search_path;
173 memset( debug_flags, 0, DEBUG_FLAGS_MAX );
176 env_detect( argc, argv );
181 if ( PHYSFS_init( env.argv0 ) == 0 ) {
183 snprintf( buf,
sizeof( buf ),
"PhysicsFS initialization failed: %s",
184 PHYSFS_getErrorByCode( PHYSFS_getLastErrorCode() ) );
185#if SDL_VERSION_ATLEAST( 3, 0, 0 )
186 SDL_ShowSimpleMessageBox( SDL_MESSAGEBOX_ERROR,
187 _(
"Naev Critical Error" ), buf,
193 PHYSFS_permitSymbolicLinks( 1 );
201 WARN( _(
"Failed to parse version string '%s'!" ),
naev_version( 0 ) );
207 if ( env.isAppImage )
208 LOG(
"AppImage detected. Running from: %s", env.appdir );
210 DEBUG(
"AppImage not detected." );
214 if ( SDL_Init( 0 ) ) {
216 snprintf( buf,
sizeof( buf ), _(
"Unable to initialize SDL: %s" ),
218#if SDL_VERSION_ATLEAST( 3, 0, 0 )
219 SDL_ShowSimpleMessageBox( SDL_MESSAGEBOX_ERROR,
220 _(
"Naev Critical Error" ), buf,
226 starttime = SDL_GetTicks();
237 SDL_setenv(
"SDL_VIDEO_X11_WMCLASS",
APPNAME, 0 );
241 if ( SDL_InitSubSystem( SDL_INIT_VIDEO ) < 0 ) {
242 WARN( _(
"Unable to initialize SDL Video: %s" ), SDL_GetError() );
262 conf_loadConfigPath();
269 snprintf( conf_file_path,
sizeof( conf_file_path ),
"%s" CONF_FILE,
272 conf_loadConfig( conf_file_path );
273 conf_parseCLI( argc, argv );
280 LOG( _(
"Loaded configuration: %s" ), conf_file_path );
281 search_path = PHYSFS_getSearchPath();
282 LOG(
"%s", _(
"Read locations, searched in order:" ) );
283 for (
char **p = search_path; *p != NULL; p++ )
285 PHYSFS_freeList( search_path );
288 LOG( _(
"Write location: %s\n" ), PHYSFS_getWriteDir() );
291 if ( conf.fpu_except )
297 snprintf( buf,
sizeof( buf ), _(
"Failed to load module start data." ) );
298#if SDL_VERSION_ATLEAST( 3, 0, 0 )
299 SDL_ShowSimpleMessageBox( SDL_MESSAGEBOX_ERROR,
300 _(
"Naev Critical Error" ), buf,
320 snprintf( buf,
sizeof( buf ),
321 _(
"Initializing video output failed, exiting…" ) );
322#if SDL_VERSION_ATLEAST( 3, 0, 0 )
323 SDL_ShowSimpleMessageBox( SDL_MESSAGEBOX_ERROR,
324 _(
"Naev Critical Error" ), buf,
329 exit( EXIT_FAILURE );
337 FONT_PATH_PREFIX, 0 );
339 FONT_PATH_PREFIX, 0 );
341 FONT_PATH_PREFIX, 0 );
349 last_t = SDL_GetPerformanceCounter();
354 if ( ( conf.joystick_ind >= 0 ) || ( conf.joystick_nam != NULL ) ) {
356 WARN( _(
"Error initializing joystick input" ) );
357 if ( conf.joystick_nam !=
360 WARN( _(
"Failure to open any joystick, falling back to default "
364 free( conf.joystick_nam );
365 }
else if ( conf.joystick_ind >= 0 )
367 WARN( _(
"Failure to open any joystick, falling back to default "
376 if ( conf.nosound ) {
377 LOG( _(
"Sound is disabled!" ) );
382 WARN( _(
"Problem setting up sound!" ) );
411 LOG( _(
"Reached main menu in %.3f s" ),
412 (
double)( SDL_GetTicks() - starttime ) / 1000. );
414 LOG( _(
"Reached main menu" ) );
415 NTracingMessageL( _(
"Reached main menu" ) );
425 while ( SDL_PollEvent( &event ) )
433 if ( !conf.translation_warning_seen && conf.language == NULL ) {
437 if ( coverage < 0.8 ) {
438 conf.translation_warning_seen = 1;
440 _(
"Incomplete Translation" ),
441 _(
"%s is partially translated (%.0f%%) into your language (%s),"
442 " but the remaining text will be English. Language settings"
443 " are available in the \"%s\" screen." ),
444 APPNAME, 100. * coverage, language, _(
"Options" ) );
449 if ( conf.lastversion == NULL ||
451 free( conf.lastversion );
454 _(
"Welcome to Naev" ),
455 _(
"Welcome to Naev version %s, and thank you for playing! We hope you"
456 " enjoy this game and all it has to offer. This is a passion"
457 " project developed exclusively by volunteers and it gives us all"
458 " great joy to know that there are others who love this game as"
460 " Of course, please note that this is an incomplete game. You"
461 " will encounter dead ends to storylines, missing storylines, and"
462 " possibly even some bugs, although we try to keep those to a"
463 " minimum of course. So be prepared for some rough edges for the"
464 " time being. That said, we are working on this game every day and"
465 " hope to one day finish this massive project on our hands."
466 " Perhaps you could become one of us, who knows?\n"
467 " For more information about the game and its development"
468 " state, take a look at naev.org; it has all the relevant links."
469 " And again, thank you for playing!" ),
475 while ( !
quit && SDL_PollEvent( &event ) ) {
476 if ( event.type == SDL_QUIT ) {
477 SDL_FlushEvent( SDL_QUIT );
483 }
else if ( event.type == SDL_WINDOWEVENT &&
484 event.window.event == SDL_WINDOWEVENT_RESIZED ) {
496 conf_saveConfig( conf_file_path );
564 load_mutex = SDL_CreateMutex();
565 load_env = nlua_newEnv(
"loadscreen" );
577 WARN( _(
"Something went wrong when loading Lua libraries for '%s'!" ),
578 LOADSCREEN_DATA_PATH );
581 char *buf =
ndata_read( LOADSCREEN_DATA_PATH, &bufsize );
582 if ( nlua_dobufenv(
load_env, buf, bufsize, LOADSCREEN_DATA_PATH ) != 0 ) {
583 WARN( _(
"Error loading file: %s\n"
585 "Most likely Lua file has improper syntax, please check" ),
586 LOADSCREEN_DATA_PATH, lua_tostring(
naevL, -1 ) );
598 unsigned int t = SDL_GetTicks();
600 SDL_mutexP( load_mutex );
602 if ( !load_force_render && ( t - load_last_render ) < 100 )
606 SDL_mutexV( load_mutex );
610void naev_doRenderLoadscreen(
void )
612 SDL_mutexP( load_mutex );
613 load_last_render = SDL_GetTicks();
616 glClearColor( 0., 0., 0., 1. );
617 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
618 glClearColor( 0., 0., 0., 0. );
622 if ( nlua_pcall(
load_env, 0, 0 ) ) {
623 WARN( _(
"Loadscreen '%s': '%s'" ),
"render", lua_tostring(
naevL, -1 ) );
633 load_force_render = 0;
634 SDL_mutexV( load_mutex );
643 naev_doRenderLoadscreen();
656 lua_pushnumber(
naevL, done );
657 lua_pushstring(
naevL, msg );
658 if ( nlua_pcall(
load_env, 2, 0 ) ) {
659 WARN( _(
"Loadscreen '%s': '%s'" ),
"update", lua_tostring(
naevL, -1 ) );
664 load_force_render = 1;
674 SDL_DestroyMutex( load_mutex );
680#define LOADING_STAGES 17.
683 NTracingFrameMarkStart(
"load_all" );
694 _(
"Loading Special Effects…" ) );
745 WARN( _(
"Too many loading stages, please increase LOADING_STAGES" ) );
757 NTracingFrameMarkEnd(
"load_all" );
797 NTracingZone( _ctx, 1 );
801 Uint64 t = SDL_GetPerformanceCounter();
803 (double)( t -
last_t ) / (double)SDL_GetPerformanceFrequency();
817 }
else if ( !nested ) {
843 if ( !conf.vsync && conf.fps_max != 0 ) {
844#if !SDL_VERSION_ATLEAST( 3, 0, 0 ) && HAS_POSIX
847 const double fps_max = 1. / (double)conf.fps_max;
848 Uint64 t = SDL_GetPerformanceCounter();
850 (double)( t -
last_t ) / (double)SDL_GetPerformanceFrequency();
851 double delay = fps_max - dt;
853#if SDL_VERSION_ATLEAST( 3, 0, 0 )
854 SDL_DelayNS( delay * 1e9 );
856 ts.tv_sec = floor( delay );
857 ts.tv_nsec = fmod( delay, 1. ) * 1e9;
858 nanosleep( &ts, NULL );
860 SDL_Delay( (
unsigned int)round( delay * 1000. ) );
868 NTracingZoneEnd( _ctx );
878 SDL_GL_GetDrawableSize(
gl_screen.window, &w, &h );
918 render_all( 0., 0. );
922 load_force_render = 1;
928void naev_toggleFullscreen(
void )
938 last_t = SDL_GetPerformanceCounter();
958 double dt_mod_base = 1.;
969 if ( conf.fps_show ) {
974 if ( (
player.p != NULL ) && !player_isFlag( PLAYER_DESTROYED ) &&
975 !player_isFlag( PLAYER_CREATING ) ) {
978 if (
dt_mod != dt_mod_base )
1007 NTracingZone( _ctx, 1 );
1012 NTracingZoneEnd( _ctx );
1017 double nf, microdt, accumdt;
1026 for (
int i = 0; i < n; i++ ) {
1046 NTracingZoneEnd( _ctx );
1058 NTracingZone( _ctx, 1 );
1060 double real_update = dt /
dt_mod;
1091 NTracingZoneName( _ctx_hook,
"hooks[update]", 1 );
1095 h[0].
type = HOOK_PARAM_NUMBER;
1097 h[1].
type = HOOK_PARAM_NUMBER;
1098 h[1].
u.
num = real_update;
1099 h[2].
type = HOOK_PARAM_SENTINEL;
1102 NTracingZoneEnd( _ctx_hook );
1108 NTracingZoneEnd( _ctx );
1120 rw = PHYSFSRWOPS_openRead( GFX_PATH
"icon.webp" );
1122 WARN( _(
"Icon (icon.webp) not found!" ) );
1127 WARN( _(
"Unable to load icon.webp!" ) );
1133 SDL_SetWindowTitle(
gl_screen.window, buf );
1138static int binary_comparison(
int x,
int y )
1156 if ( semver_parse( version, &sv ) ) {
1157 WARN( _(
"Failed to parse version string '%s'!" ), version );
1161 if ( ( res = 3 * binary_comparison(
version_binary.major, sv.major ) ) ==
1163 if ( ( res = 2 * binary_comparison(
version_binary.minor, sv.minor ) ) ==
1180 if ( semver_parse( version, &sv_version ) ) {
1181 WARN( _(
"Failed to parse version string '%s'!" ), version );
1184 if ( semver_parse( target, &sv_target ) ) {
1185 WARN( _(
"Failed to parse version string '%s'!" ), target );
1189 res = semver_compare( sv_version, sv_target );
1190 semver_free( &sv_target );
1191 semver_free( &sv_version );
1200 const SDL_version *linked;
1201 SDL_version compiled;
1202 unsigned int version_linked, version_compiled;
1205 SDL_VERSION( &compiled );
1207 SDL_GetVersion( &ll );
1209 DEBUG( _(
"SDL: %d.%d.%d [compiled: %d.%d.%d]" ), linked->major,
1210 linked->minor, linked->patch, compiled.major, compiled.minor,
1213 (void)compiled.patch;
1217 version_linked = linked->major * 100 + linked->minor;
1218 version_compiled = compiled.major * 100 + compiled.minor;
1221 if ( version_linked > version_compiled )
1222 WARN( _(
"SDL is newer than compiled version" ) );
1223 if ( version_linked < version_compiled )
1224 WARN( _(
"SDL is older than compiled version." ) );
void ai_exit(void)
Cleans up global AI.
int ai_load(void)
Initializes the AI stuff which is basically Lua.
int background_init(void)
Initializes the background system.
void background_initDust(int n)
Initializes background dust.
void background_free(void)
Cleans up and frees memory after the backgrounds.
int background_load(const char *name)
Loads a background script by name.
void cam_update(double dt)
Updates the camera.
void commodity_free(void)
Frees all the loaded commodities.
int commodity_load(void)
Loads all the commodity data.
void cond_exit(void)
Destroys the conditional subsystem.
int cond_init(void)
Initializes the conditional subsystem.
void cli_exit(void)
Destroys the CLI environment.
int cli_init(void)
Initializes the CLI environment.
int dtype_load(void)
Loads the dtype stack.
void dtype_free(void)
Frees the dtype stack.
void debug_sigInit(void)
Sets up the back-tracing signal handler.
void debug_enableLeakSanitizer(void)
Does nothing. Calling this tells our debug scripts to stop tracing.
void debug_sigClose(void)
Closes the back-tracing signal handler.
void debug_enableFPUExcept(void)
Enables FPU exceptions. Artificially limited to Linux until link issues are figured out.
void dialogue_msg(const char *caption, const char *fmt,...)
Opens a dialogue window with an ok button and a message.
void economy_destroy(void)
Destroys the economy.
int effect_load(void)
Loads all the effects.
void effect_exit(void)
Gets rid of all the effects.
void events_exit(void)
Exits the event subsystem.
int events_load(void)
Loads all the events.
int factions_load(void)
Loads up all the factions from the data file.
void factions_free(void)
Frees the factions.
int gl_printMidRaw(const glFont *ft_font, int width, double x, double y, const glColour *c, double outlineR, const char *text)
Displays text centered in position and width.
void gl_print(const glFont *ft_font, const double x, const double y, const glColour *c, const char *fmt,...)
Prints text on screen like printf.
void gl_freeFont(glFont *font)
Frees a loaded font. Caution: its glFontStash still has a slot in avail_fonts. At the time of writing...
int gl_fontInit(glFont *font, const char *fname, const unsigned int h, const char *prefix, unsigned int flags)
Initializes a font.
void gl_fontExit(void)
Frees all resources associated with the font system. This also resets font ID tracking,...
void gettext_exit(void)
Free resources associated with the translation system. This invalidates previously returned pointers ...
double gettext_languageCoverage(const char *lang)
Return the fraction of strings which have a translation into the given language.
void gettext_setLanguage(const char *lang)
Set the translation language.
const char * gettext_getLanguage(void)
Gets the active (primary) translation language. Even in case of a complex locale, this will be the na...
void gettext_init(void)
Initialize the translation system. There's no presumption that PhysicsFS is available,...
int gui_init(void)
Initializes the GUI system.
void gui_free(void)
Frees the gui stuff.
void gui_reload(void)
Reloads the GUI.
int hooks_runParam(const char *stack, const HookParam *param)
Runs all the hooks of stack.
void hook_exclusionEnd(double dt)
Ends exclusion zone and runs all the queued hooks.
int hooks_run(const char *stack)
Runs all the hooks of stack.
void hook_exclusionStart(void)
Starts the hook exclusion zone, this makes hooks queue until exclusion is done.
int joystick_get(const char *namjoystick)
Gets the joystick index by name.
int joystick_init(void)
Initializes the joystick subsystem.
int joystick_use(int indjoystick)
Makes the game use a joystick by index.
void joystick_exit(void)
Exits the joystick subsystem.
void land_exit(void)
Exits all the landing stuff.
void load_free(void)
Frees loaded save stuff.
void log_clean(void)
Deletes useless (empty) log files from the current session.
void log_init(void)
Sets up the logging subsystem. (Calling this ensures logging output is preserved until we have a plac...
void log_redirect(void)
Sets up redirection of stdout and stderr to files. PhysicsFS must be initialized for this to work.
void missions_free(void)
Frees all the mission data.
int missions_load(void)
Loads all the mission data.
int music_choose(const char *situation)
Actually runs the music stuff, based on situation.
void music_exit(void)
Exits the music subsystem.
void naev_renderLoadscreen(void)
Renders the loadscreen if necessary.
int naev_versionCompare(const char *version)
Compares the version against the current naev version.
static SDL_Surface * naev_icon
static void fps_init(void)
Initializes the fps engine.
void update_routine(double dt, int dohooks)
Actually runs the updates.
int naev_shouldRenderLoadscreen(void)
Whether or not we want to render the loadscreen.
static void loadscreen_unload(void)
Frees the loading screen.
static void print_SDLversion(void)
Prints the SDL version to console.
static void unload_all(void)
Unloads all data, simplifies main().
void fps_display(double dt)
Displays FPS on the screen.
void naev_quit(void)
Flags naev to quit.
double fps_current(void)
Gets the current FPS.
#define LOADING_STAGES
Loads all the data, makes main() simpler.
void naev_resize(void)
Wrapper for gl_resize that handles non-GL reinitialization.
int naev_versionCompareTarget(const char *version, const char *target)
Does a comparison with a specific target.
int naev_isQuit(void)
Get if Naev is trying to quit.
static void window_caption(void)
Sets the window caption.
static void loadscreen_update(double done, const char *msg)
Renders the load screen with message.
static void loadscreen_load(void)
Loads a loading screen.
static semver_t version_binary
void main_loop(int nested)
Split main loop from main() for secondary loop hack in toolkit.c.
double naev_getrealdt(void)
Gets the last delta-tick.
static void update_all(int dohooks)
Updates the game itself (player flying around and friends).
void fps_setPos(double x, double y)
Sets the position to display the FPS.
Header file with generic functions and naev-specifics.
const char * naev_version(int long_version)
Returns the version in a human readable string.
void ndata_setupReadDirs(void)
Sets up the PhysicsFS search path.
void ndata_setupWriteDir(void)
Gets Naev's data path (for user data such as saves and screenshots)
void * ndata_read(const char *path, size_t *filesize)
Reads a file from the ndata (will be NUL terminated).
void nebu_exit(void)
Cleans up the nebu subsystem.
int nebu_resize(void)
Handles a screen s.
int nebu_init(void)
Initializes the nebula.
void news_exit(void)
Kills the old news thread.
const char * nfile_configPath(void)
Gets Naev's config path (for user preferences such as conf.lua)
int nfile_dirMakeExist(const char *path)
Creates a directory if it doesn't exist.
const char * nfile_cachePath(void)
Gets Naev's cache path (for cached data such as generated textures)
int nlua_loadStandard(nlua_env env)
Loads the standard Naev Lua API.
void nlua_resize(void)
Propagates a resize event to all the environments forcibly.
int nlua_loadCol(nlua_env env)
Loads the colour library.
int nlua_loadData(nlua_env env)
Loads the data library.
int nlua_loadFile(nlua_env env)
Loads the file library.
int nlua_loadGFX(nlua_env env)
Loads the graphics library.
int nlua_loadNaev(nlua_env env)
Loads the Naev Lua library.
int nlua_loadRnd(nlua_env env)
Loads the Random Number Lua library.
int nlua_loadTex(nlua_env env)
Loads the texture library.
void var_cleanup(void)
Cleans up all the mission variables.
int nlua_loadVector(nlua_env env)
Loads the vector metatable.
void npc_clear(void)
Cleans up the spaceport bar NPC.
void ntime_update(double dt)
Updatse the time based on realtime.
void gl_resize(void)
Handles a window resize and resets gl_screen parameters.
void gl_exit(void)
Cleans up OpenGL, the works.
int gl_init(unsigned int extra_flags)
Initializes SDL/OpenGL and the works.
int opt_setVideoMode(int w, int h, int fullscreen, int confirm)
Applies new video-mode options.
void opt_resize(void)
Handles resize events for the options menu.
int outfit_load(void)
Loads all the outfits.
int outfit_mapParse(void)
Parses all the maps.
void outfit_free(void)
Frees the outfit stack.
int outfit_loadPost(void)
Loads all the outfits legality.
void pilots_updatePurge(void)
Purges pilots set for deletion.
void pilots_init(void)
Initializes pilot stuff.
void pilots_update(double dt)
Updates all the pilots.
void pilots_free(void)
Frees the pilot stack.
void player_cleanup(void)
Cleans up player stuff like player_stack.
double player_dt_default(void)
Returns the player's total default time delta based on time dilation stuff.
int player_init(void)
Initializes player stuff.
void player_updateAutonav(double dt)
Updates the player's autonav.
int plugin_check(void)
Checks to see if the plugins are self-declared compatible with Naev.
void plugin_exit(void)
Exits the plugin stuff.
void rng_init(void)
Initializes the random subsystem.
void safelanes_destroy(void)
Shuts down the safelanes system.
void safelanes_init(void)
Initializes the safelanes system.
int ships_load(void)
Loads all the ships in the data files.
void ships_free(void)
Frees all the ships.
void sp_cleanup(void)
Cleans up after the slot properties.
int sp_load(void)
Initializes the slot properties.
void sound_exit(void)
Cleans up after the sound subsytem.
int sound_update(double dt)
Updates the sounds removing obsolete ones and such.
int sound_init(void)
Initializes the sound subsystem.
void space_update(double dt, double real_dt)
Controls fleet spawning.
void space_exit(void)
Cleans up the system.
void space_checkLand(void)
Handles landing if necessary.
int space_load(void)
Loads the entire universe into ram - pretty big feat eh?
int space_loadLua(void)
initializes the Lua for all the spobs.
void spfx_free(void)
Frees the spfx stack.
int spfx_load(void)
Loads the spfx stack.
void spfx_update(const double dt, const double real_dt)
Updates all the spfx.
void start_cleanup(void)
Cleans up after the module start data.
int start_load(void)
Loads the module start data.
const char * start_name(void)
Gets the module name.
The actual hook parameter.
union HookParam::@114305201244257020071001257133270030317263020235 u
void tech_free(void)
Cleans up after the tech stuff.
int tech_load(void)
Loads the tech information.
int diff_init(void)
Loads available universe diffs.
void diff_exit(void)
Clean up after diffs.
void weapons_update(double dt)
Updates all the weapons.
void weapons_updatePurge(void)
Purges unnecessary weapons.
void weapons_updateCollide(double dt)
Handles weapon collisions.
void weapon_exit(void)
Destroys all the weapons and frees it all.
void weapon_init(void)
Initializes the weapon stuff.