/** * @brief Generates error dialogues used by several landing tabs. * @param name Name of the ship, outfit or commodity being acted upon. * @param type Type of action. */ int land_errDialogue( char* name, char* type ) { errorlist_ptr = NULL; if (strcmp(type,"tradeShip")==0) shipyard_canTrade( name ); else if (strcmp(type,"buyShip")==0) shipyard_canBuy( name, land_planet ); else if (strcmp(type,"swapEquipment")==0) can_swapEquipment( name ); else if (strcmp(type,"swap")==0) can_swap( name ); else if (strcmp(type,"sellShip")==0) can_sell( name ); else if (strcmp(type,"buyOutfit")==0) outfit_canBuy( name, land_planet ); else if (strcmp(type,"sellOutfit")==0) outfit_canSell( name ); else if (strcmp(type,"buyCommodity")==0) commodity_canBuy( name ); else if (strcmp(type,"sellCommodity")==0) commodity_canSell( name ); if (errorlist_ptr != NULL) { dialogue_alert( "%s", errorlist ); return 1; } return 0; }
/** * @brief Approaches a mission giver guy. * * @brief Returns 1 on destroyed, 0 on not destroyed. */ static int npc_approach_giver( NPC_t *npc ) { int i; int ret; Mission *misn; /* Make sure player can accept the mission. */ for (i=0; i<MISSION_MAX; i++) if (player_missions[i].data == NULL) break; if (i >= MISSION_MAX) { dialogue_alert("You have too many active missions."); return -1; } /* Get mission. */ misn = &npc->u.g; ret = mission_accept( misn ); if ((ret==0) || (ret==2) || (ret==-1)) { /* success in accepting the mission */ if (ret==-1) mission_cleanup( misn ); npc_free( npc ); array_erase( &npc_array, &npc[0], &npc[1] ); ret = 1; } else ret = 0; return ret; }
/** * @brief Actually loads a new game based on file. * * @param file File that contains the new game. * @return 0 on success. */ static int load_game( const char* file ) { xmlNodePtr node; xmlDocPtr doc; /* Make sure it exists. */ if (!nfile_fileExists(file)) { dialogue_alert("Savegame file seems to have been deleted."); return -1; } /* Load the XML. */ doc = xmlParseFile(file); if (doc == NULL) goto err; node = doc->xmlChildrenNode; /* base node */ if (node == NULL) goto err_doc; /* Clean up possible stuff that should be cleaned. */ player_cleanup(); diff_clear(); var_cleanup(); missions_cleanup(); events_cleanup(); /* Welcome message - must be before space_init. */ player_message( "\egWelcome to "APPNAME"!" ); player_message( "\eg v%d.%d.%d", VMAJOR, VMINOR, VREV ); /* Now begin to load. */ diff_load(node); /* Must load first to work properly. */ pfaction_load(node); /* Must be loaded before player so the messages show up properly. */ player_load(node); var_load(node); missions_loadActive(node); hook_load(node); space_sysLoad(node); /* Initialize the economy. */ economy_init(); /* Need to run takeoff hooks since player just "took off" */ hooks_run("takeoff"); player_addEscorts(); hooks_run("enter"); events_trigger( EVENT_TRIGGER_ENTER ); xmlFreeDoc(doc); xmlCleanupParser(); return 0; err_doc: xmlFreeDoc(doc); xmlCleanupParser(); err: WARN("Savegame '%s' invalid!", file); return -1; }
/** * @brief Makes sure it's sane to change ships in the equipment view. * @param shipname Ship being changed to. */ int can_swapEquipment( char* shipname ) { int failure = 0; char *loc = player_getLoc(shipname); Pilot *newship; newship = player_getShip(shipname); if (strcmp(shipname,player.p->name)==0) /* Already onboard. */ land_errDialogueBuild( "You're already onboard the %s.", shipname ); failure = 1; if (strcmp(loc,land_planet->name)) { /* Ship isn't here. */ dialogue_alert( "You must transport the ship to %s to be able to get in.", land_planet->name ); failure = 1; } if (pilot_cargoUsed(player.p) > (pilot_cargoFree(newship) + pilot_cargoUsed(newship))) { /* Current ship has too much cargo. */ land_errDialogueBuild( "You have %d tons more cargo than the new ship can hold.", pilot_cargoUsed(player.p) - pilot_cargoFree(newship), shipname ); failure = 1; } if (pilot_hasDeployed(player.p)) { /* Escorts are in space. */ land_errDialogueBuild( "You can't strand your fighters in space."); failure = 1; } return !failure; }
/** * @brief Creates a new system. */ static void uniedit_newSys( double x, double y ) { char *name; StarSystem *sys; /* Get name. */ name = dialogue_inputRaw( "New Star System Creation", 1, 32, "What do you want to name the new system?" ); /* Abort. */ if (name == NULL) { dialogue_alert( "Star System creation aborted!" ); return; } /* Make sure there is no collision. */ if (uniedit_checkName( name )) { free(name); uniedit_newSys( x, y ); return; } /* Create the system. */ sys = system_new(); sys->name = name; sys->pos.x = x; sys->pos.y = y; sys->stars = 400; sys->radius = 10000.; /* Select new system. */ uniedit_deselect(); uniedit_selectAdd( sys ); }
/** * @brief Creates a dialogue that allows the player to write a message. * * You must free the result if it's not null. * * @param title Title of the dialogue window. * @param min Minimum length of the message (must be non-zero). * @param max Maximum length of the message (must be non-zero). * @param msg Message to be displayed. * @return The message the player typed or NULL if it was cancelled. */ char* dialogue_inputRaw( const char* title, int min, int max, const char *msg ) { char *input; int h, done; /* get text height */ h = gl_printHeightRaw( &gl_smallFont, 200, msg ); /* create window */ input_dialogue.input_wid = window_create( title, -1, -1, 240, h+140 ); window_setData( input_dialogue.input_wid, &done ); window_setAccept( input_dialogue.input_wid, dialogue_inputClose ); window_setCancel( input_dialogue.input_wid, dialogue_cancel ); /* text */ window_addText( input_dialogue.input_wid, 30, -30, 200, h, 0, "txtInput", &gl_smallFont, &cDConsole, msg ); /* input */ window_addInput( input_dialogue.input_wid, 20, -50-h, 200, 20, "inpInput", max, 1, NULL ); window_setInputFilter( input_dialogue.input_wid, "inpInput", "/" ); /* Remove illegal stuff. */ /* button */ window_addButton( input_dialogue.input_wid, -20, 20, 80, 30, "btnClose", "Done", dialogue_inputClose ); /* tricky secondary loop */ dialogue_open++; done = 0; input = NULL; while ((done >= 0) && (!input || ((int)strlen(input) < min))) { /* must be longer than min */ if (input) { dialogue_alert( "Input must be at least %d character%s long!", min, (min==1) ? "s" : "" ); free(input); input = NULL; } if (toolkit_loop( &done ) != 0) /* error in loop -> quit */ return NULL; /* save the input */ if (done < 0) input = NULL; else input = strdup( window_getInput( input_dialogue.input_wid, "inpInput" ) ); } /* cleanup */ if (input != NULL) { window_destroy( input_dialogue.input_wid ); dialogue_open--; } input_dialogue.input_wid = 0; /* return the result */ return input; }
/** * @brief Buys the selected commodity. * @param wid Window buying from. * @param str Unused. */ static void commodity_buy( unsigned int wid, char* str ) { (void)str; char *comname; Commodity *com; unsigned int q; credits_t price; HookParam hparam[3]; /* Get selected. */ q = commodity_getMod(); comname = toolkit_getList( wid, "lstGoods" ); com = commodity_get( comname ); price = planet_commodityPrice( land_planet, com ); price *= q; /* Check stuff. */ if (!player_hasCredits( price )) { dialogue_alert( "Insufficient credits!" ); return; } else if (pilot_cargoFree(player.p) <= 0) { dialogue_alert( "Insufficient free space!" ); return; } /* Make the buy. */ q = pilot_cargoAdd( player.p, com, q ); player_modCredits( -price ); land_checkAddRefuel(); commodity_update(wid, NULL); /* Run hooks. */ hparam[0].type = HOOK_PARAM_STRING; hparam[0].u.str = comname; hparam[1].type = HOOK_PARAM_NUMBER; hparam[1].u.num = q; hparam[2].type = HOOK_PARAM_SENTINEL; hooks_runParam( "comm_buy", hparam ); if (land_takeoff) takeoff(1); }
/** * @brief Checks to see if a system name is already in use. * * @return 1 if system name is already in use. */ static int uniedit_checkName( char *name ) { int i; /* Avoid name collisions. */ for (i=0; i<systems_nstack; i++) { if (strcmp(name, system_getIndex(i)->name)==0) { dialogue_alert( "The Star System '%s' already exists!", name ); return 1; } } return 0; }
/** * @brief Allows the player to set a different GUI. * * @param wid Window id. * @param name of widget. */ static void info_setGui( unsigned int wid, char* str ) { (void)str; int i; char **guis; int nguis; char **gui_copy; /* Get the available GUIs. */ guis = player_guiList( &nguis ); /* In case there are none. */ if (guis == NULL) { WARN("No GUI available."); dialogue_alert( "There are no GUI available, this means something went wrong somewhere. Inform the Naev maintainer." ); return; } /* window */ wid = window_create( "Select GUI", -1, -1, SETGUI_WIDTH, SETGUI_HEIGHT ); window_setCancel( wid, setgui_close ); /* Copy GUI. */ gui_copy = malloc( sizeof(char*) * nguis ); for (i=0; i<nguis; i++) gui_copy[i] = strdup( guis[i] ); /* List */ window_addList( wid, 20, -50, SETGUI_WIDTH-BUTTON_WIDTH/2 - 60, SETGUI_HEIGHT-110, "lstGUI", gui_copy, nguis, 0, NULL ); toolkit_setList( wid, "lstGUI", gui_pick() ); /* buttons */ window_addButton( wid, -20, 20, BUTTON_WIDTH/2, BUTTON_HEIGHT, "btnBack", "Cancel", setgui_close ); window_addButton( wid, -20, 30 + BUTTON_HEIGHT, BUTTON_WIDTH/2, BUTTON_HEIGHT, "btnLoad", "Load", setgui_load ); /* Checkboxes */ window_addCheckbox( wid, 20, 20, BUTTON_WIDTH, BUTTON_HEIGHT, "chkOverride", "Override GUI", info_toggleGuiOverride, player.guiOverride ); info_toggleGuiOverride( wid, "chkOverride" ); /* default action */ window_setAccept( wid, setgui_load ); }
/** * @brief Accepts the selected mission. * @param wid Window of the mission computer. * @param str Unused. */ static void misn_accept( unsigned int wid, char* str ) { (void) str; char* misn_name; Mission* misn; int pos; int i, ret; misn_name = toolkit_getList( wid, "lstMission" ); /* Make sure you have missions. */ if (strcmp(misn_name,"No Missions")==0) return; /* Make sure player can accept the mission. */ for (i=0; i<MISSION_MAX; i++) if (player_missions[i].data == NULL) break; if (i >= MISSION_MAX) { dialogue_alert("You have too many active missions."); return; } if (dialogue_YesNo("Accept Mission", "Are you sure you want to accept this mission?")) { pos = toolkit_getListPos( wid, "lstMission" ); misn = &mission_computer[pos]; ret = mission_accept( misn ); if ((ret==0) || (ret==2) || (ret==-1)) { /* success in accepting the mission */ if (ret==-1) mission_cleanup( &mission_computer[pos] ); memmove( &mission_computer[pos], &mission_computer[pos+1], sizeof(Mission) * (mission_ncomputer-pos-1) ); mission_ncomputer--; /* Regenerate list. */ misn_genList(wid, 0); /* Add position persistancey after a mission has been accepted */ /* NOTE: toolkit_setListPos protects us from a bad position by clamping */ toolkit_setListPos( wid, "lstMission", pos-1 ); /*looks better without the -1, makes more sense with*/ } /* Reset markers. */ mission_sysMark(); } }
/** * @brief Refuels the player. * @param wid Land window. * @param str Unused. */ static void spaceport_refuel( unsigned int wid, char *str ) { (void)str; credits_t price; price = refuel_price(); if (!player_hasCredits( price )) { /* player is out of money after landing */ dialogue_alert("You seem to not have enough credits to refuel your ship." ); return; } player_modCredits( -price ); player.p->fuel = player.p->fuel_max; if (widget_exists( land_windows[0], "btnRefuel" )) { window_destroyWidget( wid, "btnRefuel" ); window_destroyWidget( wid, "txtRefuel" ); } }
/** * @brief Generates error dialogues used by several landing tabs. * @param shipname Ship being acted upon. * @param type Type of action. */ int land_errDialogue( char* shipname, char* type ) { errorlist_ptr = NULL; if (strcmp(type,"trade")==0) shipyard_canTrade( shipname ); else if (strcmp(type,"buy")==0) shipyard_canBuy( shipname ); else if (strcmp(type,"swapEquipment")==0) can_swapEquipment( shipname ); else if (strcmp(type,"swap")==0) can_swap( shipname ); else if (strcmp(type,"sell")==0) can_sell( shipname ); if (errorlist_ptr != NULL) { dialogue_alert( "%s", errorlist ); return 1; } return 0; }
/** * @brief Creates a new system. */ static void uniedit_newSys( double x, double y ) { char *name; StarSystem *sys; /* Get name. */ name = dialogue_inputRaw( "New Star System Creation", 1, 32, "What do you want to name the new system?" ); /* Abort. */ if (name == NULL) { dialogue_alert( "Star System creation aborted!" ); return; } /* Make sure there is no collision. */ if (uniedit_checkName( name )) { free(name); uniedit_newSys( x, y ); return; } /* Transform coordinates back to normal if zoomed */ x /= uniedit_zoom; y /= uniedit_zoom; /* Create the system. */ sys = system_new(); sys->name = name; sys->pos.x = x; sys->pos.y = y; sys->stars = STARS_DENSITY_DEFAULT; sys->radius = RADIUS_DEFAULT; /* Select new system. */ uniedit_deselect(); uniedit_selectAdd( sys ); if (conf.devautosave) dsys_saveSystem( sys ); }
/** * @brief Sets the fire mode. */ static void weapons_fire( unsigned int wid, char *str ) { int i, state; /* Set state. */ state = window_checkboxState( wid, str ); pilot_weapSetMode( player.p, info_eq_weaps.weapons, state ); /* Check to see if they are all fire groups. */ for (i=0; i<PILOT_WEAPON_SETS; i++) if (!pilot_weapSetModeCheck( player.p, i )) break; /* Not able to set them all to fire groups. */ if (i >= PILOT_WEAPON_SETS) { dialogue_alert( "You can not set all your weapon sets to fire groups!" ); pilot_weapSetMode( player.p, info_eq_weaps.weapons, 0 ); window_checkboxSet( wid, str, 0 ); } /* Set default if needs updating. */ pilot_weaponSetDefault( player.p ); }
/** * @brief Sets the fire mode. */ static void weapons_fire( unsigned int wid, char *str ) { int i, state, t, c; /* Set state. */ state = window_checkboxState( wid, str ); /* See how to handle. */ t = pilot_weapSetTypeCheck( player.p, info_eq_weaps.weapons ); if (t == WEAPSET_TYPE_ACTIVE) return; if (state) c = WEAPSET_TYPE_WEAPON; else c = WEAPSET_TYPE_CHANGE; pilot_weapSetType( player.p, info_eq_weaps.weapons, c ); /* Check to see if they are all fire groups. */ for (i=0; i<PILOT_WEAPON_SETS; i++) if (!pilot_weapSetTypeCheck( player.p, i )) break; /* Not able to set them all to fire groups. */ if (i >= PILOT_WEAPON_SETS) { dialogue_alert( "You can not set all your weapon sets to fire groups!" ); pilot_weapSetType( player.p, info_eq_weaps.weapons, WEAPSET_TYPE_CHANGE ); window_checkboxSet( wid, str, 0 ); } /* Set default if needs updating. */ pilot_weaponSetDefault( player.p ); /* Must regen. */ weapons_genList( wid ); }
/** * @brief Makes the player take off if landed. * * @param delay Whether or not to have time pass as if the player landed normally. */ void takeoff( int delay ) { int h; char *nt; double a, r; if (!landed) return; /* Clear queued takeoff. */ land_takeoff = 0; /* Refuel if needed. */ land_checkAddRefuel(); /* In case we had paused messy sounds. */ sound_stopAll(); /* ze music */ music_choose("takeoff"); /* to randomize the takeoff a bit */ a = RNGF() * 2. * M_PI; r = RNGF() * land_planet->radius; /* no longer authorized to land */ player_rmFlag(PLAYER_LANDACK); pilot_rmFlag(player.p,PILOT_LANDING); /* No longer landing. */ /* set player to another position with random facing direction and no vel */ player_warp( land_planet->pos.x + r * cos(a), land_planet->pos.y + r * sin(a) ); vect_pset( &player.p->solid->vel, 0., 0. ); player.p->solid->dir = RNGF() * 2. * M_PI; cam_setTargetPilot( player.p->id, 0 ); /* heal the player */ player.p->armour = player.p->armour_max; player.p->shield = player.p->shield_max; player.p->energy = player.p->energy_max; player.p->stimer = 0.; /* initialize the new space */ h = player.p->nav_hyperspace; space_init(NULL); player.p->nav_hyperspace = h; /* cleanup */ if (save_all() < 0) { /* must be before cleaning up planet */ dialogue_alert( "Failed to save game! You should exit and check the log to see what happened and then file a bug report!" ); } /* time goes by, triggers hook before takeoff */ if (delay) ntime_inc( ntime_create( 0, 1, 0 ) ); /* 1 STP */ nt = ntime_pretty( 0, 2 ); player_message("\epTaking off from %s on %s.", land_planet->name, nt); free(nt); /* Hooks and stuff. */ land_cleanup(); /* Cleanup stuff */ hooks_run("takeoff"); /* Must be run after cleanup since we don't want the missions to think we are landed. */ if (menu_isOpen(MENU_MAIN)) return; player_addEscorts(); hooks_run("enter"); if (menu_isOpen(MENU_MAIN)) return; events_trigger( EVENT_TRIGGER_ENTER ); if (menu_isOpen(MENU_MAIN)) return; player.p->ptimer = PILOT_TAKEOFF_DELAY; pilot_setFlag( player.p, PILOT_TAKEOFF ); pilot_setThrust( player.p, 0. ); pilot_setTurn( player.p, 0. ); }
/** * @brief Saves the video settings. */ static void opt_videoSave( unsigned int wid, char *str ) { (void) str; int i, j, s; char *inp, buf[16], width[16], height[16]; int w, h, f; /* Handle resolution. */ inp = window_getInput( wid, "inpRes" ); memset( width, '\0', sizeof(width) ); memset( height, '\0', sizeof(height) ); j = 0; s = 0; for (i=0; i<16; i++) { if (isdigit(inp[i])) { if (j==0) width[s++] = inp[i]; else height[s++] = inp[i]; } else { j++; s = 0; } } w = atoi(width); h = atoi(height); if ((w==0) || (h==0)) { dialogue_alert( "Height/Width invalid. Should be formatted like 1024x768." ); return; } if ((w != conf.width) || (h != conf.height)) { conf.explicit_dim = 1; conf.width = w; conf.height = h; opt_needRestart(); snprintf( buf, sizeof(buf), "%dx%d", conf.width, conf.height ); window_setInput( wid, "inpRes", buf ); } /* Fullscreen. */ f = window_checkboxState( wid, "chkFullscreen" ); if (conf.fullscreen != f) { conf.fullscreen = f; opt_needRestart(); } /* FPS. */ conf.fps_show = window_checkboxState( wid, "chkFPS" ); inp = window_getInput( wid, "inpFPS" ); conf.fps_max = atoi(inp); /* OpenGL. */ f = window_checkboxState( wid, "chkVSync" ); if (conf.vsync != f) { conf.vsync = f; opt_needRestart(); } f = window_checkboxState( wid, "chkVBO" ); if (conf.vbo != f) { conf.vbo = f; opt_needRestart(); } f = window_checkboxState( wid, "chkMipmaps" ); if (conf.mipmaps != f) { conf.mipmaps = f; opt_needRestart(); } f = window_checkboxState( wid, "chkInterpolate" ); if (conf.interpolate != f) { conf.interpolate = f; opt_needRestart(); } f = window_checkboxState( wid, "chkNPOT" ); if (conf.npot != f) { conf.npot = f; opt_needRestart(); } /* Features. */ f = window_checkboxState( wid, "chkEngineGlow" ); if (conf.engineglow != f) { conf.engineglow = f; opt_needRestart(); } }
/** * @brief The entry point of Naev. * * @param[in] argc Number of arguments. * @param[in] argv Array of argc arguments. * @return EXIT_SUCCESS on success. */ int main( int argc, char** argv ) { char buf[PATH_MAX]; /* Save the binary path. */ binary_path = strdup(argv[0]); /* Print the version */ LOG( " "APPNAME" v%s", naev_version(0) ); #ifdef GIT_COMMIT DEBUG( " git HEAD at " GIT_COMMIT ); #endif /* GIT_COMMIT */ /* Initializes SDL for possible warnings. */ SDL_Init(0); /* Initialize the threadpool */ threadpool_init(); /* Set up debug signal handlers. */ debug_sigInit(); /* Must be initialized before input_init is called. */ if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) { WARN("Unable to initialize SDL Video: %s", SDL_GetError()); return -1; } /* Get desktop dimensions. */ #if SDL_VERSION_ATLEAST(1,2,10) const SDL_VideoInfo *vidinfo = SDL_GetVideoInfo(); gl_screen.desktop_w = vidinfo->current_w; gl_screen.desktop_h = vidinfo->current_h; #else /* #elif SDL_VERSION_ATLEAST(1,2,10) */ gl_screen.desktop_w = 0; gl_screen.desktop_h = 0; #endif /* #elif SDL_VERSION_ATLEAST(1,2,10) */ /* We'll be parsing XML. */ LIBXML_TEST_VERSION xmlInitParser(); /* Input must be initialized for config to work. */ input_init(); conf_setDefaults(); /* set the default config values */ /* * Attempts to load the data path from datapath.lua * At this early point in the load process, the binary path * is the only place likely to be checked. */ conf_loadConfigPath(); /* Parse the user data path override first. */ conf_parseCLIPath( argc, argv ); /* Create the home directory if needed. */ if (nfile_dirMakeExist("%s", nfile_configPath())) WARN("Unable to create config directory '%s'", nfile_configPath()); /* Set the configuration. */ nsnprintf(buf, PATH_MAX, "%s"CONF_FILE, nfile_configPath()); #if HAS_UNIX /* TODO get rid of this cruft ASAP. */ int oldconfig = 0; if (!nfile_fileExists( buf )) { char *home, buf2[PATH_MAX]; home = SDL_getenv( "HOME" ); if (home != NULL) { nsnprintf( buf2, PATH_MAX, "%s/.naev/"CONF_FILE, home ); if (nfile_fileExists( buf2 )) oldconfig = 1; } } #endif /* HAS_UNIX */ conf_loadConfig(buf); /* Lua to parse the configuration file */ conf_parseCLI( argc, argv ); /* parse CLI arguments */ /* Enable FPU exceptions. */ #if defined(HAVE_FEENABLEEXCEPT) && defined(DEBUGGING) if (conf.fpu_except) feenableexcept( FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW ); #endif /* defined(HAVE_FEENABLEEXCEPT) && defined(DEBUGGING) */ /* Open data. */ if (ndata_open() != 0) ERR("Failed to open ndata."); /* Load the start info. */ if (start_load()) ERR("Failed to load module start data."); /* Load the data basics. */ LOG(" %s", ndata_name()); DEBUG(); /* Display the SDL Version. */ print_SDLversion(); DEBUG(); /* random numbers */ rng_init(); /* * OpenGL */ if (gl_init()) { /* initializes video output */ ERR("Initializing video output failed, exiting..."); SDL_Quit(); exit(EXIT_FAILURE); } window_caption(); gl_fontInit( NULL, NULL, conf.font_size_def ); /* initializes default font to size */ gl_fontInit( &gl_smallFont, NULL, conf.font_size_small ); /* small font */ /* Display the load screen. */ loadscreen_load(); loadscreen_render( 0., "Initializing subsystems..." ); time_ms = SDL_GetTicks(); /* * Input */ if ((conf.joystick_ind >= 0) || (conf.joystick_nam != NULL)) { if (joystick_init()) WARN("Error initializing joystick input"); if (conf.joystick_nam != NULL) { /* use the joystick name to find a joystick */ if (joystick_use(joystick_get(conf.joystick_nam))) { WARN("Failure to open any joystick, falling back to default keybinds"); input_setDefault(); } free(conf.joystick_nam); } else if (conf.joystick_ind >= 0) /* use a joystick id instead */ if (joystick_use(conf.joystick_ind)) { WARN("Failure to open any joystick, falling back to default keybinds"); input_setDefault(); } } /* * OpenAL - Sound */ if (conf.nosound) { LOG("Sound is disabled!"); sound_disabled = 1; music_disabled = 1; } if (sound_init()) WARN("Problem setting up sound!"); music_choose("load"); /* FPS stuff. */ fps_setPos( 15., (double)(gl_screen.h-15-gl_defFont.h) ); /* Misc graphics init */ if (nebu_init() != 0) { /* Initializes the nebula */ /* An error has happened */ ERR("Unable to initialize the Nebula subsystem!"); /* Weirdness will occur... */ } gui_init(); /* initializes the GUI graphics */ toolkit_init(); /* initializes the toolkit */ map_init(); /* initializes the map. */ cond_init(); /* Initialize conditional subsystem. */ cli_init(); /* Initialize console. */ /* Data loading */ load_all(); /* Generate the CSV. */ if (conf.devcsv) dev_csv(); /* Unload load screen. */ loadscreen_unload(); /* Start menu. */ menu_main(); /* Force a minimum delay with loading screen */ if ((SDL_GetTicks() - time_ms) < NAEV_INIT_DELAY) SDL_Delay( NAEV_INIT_DELAY - (SDL_GetTicks() - time_ms) ); fps_init(); /* initializes the time_ms */ #if HAS_UNIX /* Tell the player to migrate their configuration files out of ~/.naev */ /* TODO get rid of this cruft ASAP. */ if ((oldconfig) && (!conf.datapath)) { char path[PATH_MAX], *script, *home; uint32_t scriptsize; int ret; nsnprintf( path, PATH_MAX, "%s/naev-confupdate.sh", ndata_getDirname() ); home = SDL_getenv("HOME"); ret = dialogue_YesNo( "Warning", "Your configuration files are in a deprecated location and must be migrated:\n" " \er%s/.naev/\e0\n\n" "The update script can likely be found in your Naev data directory:\n" " \er%s\e0\n\n" "Would you like to run it automatically?", home, path ); /* Try to run the script. */ if (ret) { ret = -1; /* Running from ndata. */ if (ndata_getPath() != NULL) { script = ndata_read( "naev-confupdate.sh", &scriptsize ); if (script != NULL) ret = system(script); } /* Running from laid-out files or ndata_read failed. */ if ((nfile_fileExists(path)) && (ret == -1)) { script = nfile_readFile( (int*)&scriptsize, path ); if (script != NULL) ret = system(script); } /* We couldn't find the script. */ if (ret == -1) { dialogue_alert( "The update script was not found at:\n\er%s\e0\n\n" "Please locate and run it manually.", path ); } /* Restart, as the script succeeded. */ else if (!ret) { dialogue_msg( "Update Completed", "Configuration files were successfully migrated. Naev will now restart." ); execv(argv[0], argv); } else { /* I sincerely hope this else is never hit. */ dialogue_alert( "The update script encountered an error. Please exit Naev and move your config and save files manually:\n\n" "\er%s/%s\e0 =>\n \eD%s\e0\n\n" "\er%s/%s\e0 =>\n \eD%s\e0\n\n" "\er%s/%s\e0 =>\n \eD%snebula/\e0\n\n", home, ".naev/conf.lua", nfile_configPath(), home, ".naev/{saves,screenshots}/", nfile_dataPath(), home, ".naev/gen/*.png", nfile_cachePath() ); } } else {
/** * @brief Tries to set the key from an event. */ static int opt_setKeyEvent( unsigned int wid, SDL_Event *event ) { unsigned int parent; KeybindType type; int key; SDLMod mod, ev_mod; const char *str; int pos, off; /* See how to handle it. */ switch (event->type) { case SDL_KEYDOWN: key = event->key.keysym.sym; /* If control key make player hit twice. */ if (((key == SDLK_NUMLOCK) || (key == SDLK_CAPSLOCK) || (key == SDLK_SCROLLOCK) || (key == SDLK_RSHIFT) || (key == SDLK_LSHIFT) || (key == SDLK_RCTRL) || (key == SDLK_LCTRL) || (key == SDLK_RALT) || (key == SDLK_LALT) || (key == SDLK_RMETA) || (key == SDLK_LMETA) || (key == SDLK_LSUPER) || (key == SDLK_RSUPER)) && (opt_lastKeyPress != key)) { opt_lastKeyPress = key; return 0; } type = KEYBIND_KEYBOARD; if (window_checkboxState( wid, "chkAny" )) mod = NMOD_ALL; else { ev_mod = event->key.keysym.mod; mod = 0; if (ev_mod & (KMOD_LSHIFT | KMOD_RSHIFT)) mod |= NMOD_SHIFT; if (ev_mod & (KMOD_LCTRL | KMOD_RCTRL)) mod |= NMOD_CTRL; if (ev_mod & (KMOD_LALT | KMOD_RALT)) mod |= NMOD_ALT; if (ev_mod & (KMOD_LMETA | KMOD_RMETA)) mod |= NMOD_META; } /* Set key. */ opt_lastKeyPress = key; break; case SDL_JOYAXISMOTION: if (event->jaxis.value > 0) type = KEYBIND_JAXISPOS; else if (event->jaxis.value < 0) type = KEYBIND_JAXISNEG; else return 0; /* Not handled. */ key = event->jaxis.axis; mod = NMOD_ALL; break; case SDL_JOYBUTTONDOWN: type = KEYBIND_JBUTTON; key = event->jbutton.button; mod = NMOD_ALL; break; /* Not handled. */ default: return 0; } /* Warn if already bound. */ str = input_keyAlreadyBound( type, key, mod ); if ((str != NULL) && strcmp(str, opt_selectedKeybind)) dialogue_alert( "Key '%s' overlaps with key '%s' that was just set. " "You may want to correct this.", str, opt_selectedKeybind ); /* Set keybinding. */ input_setKeybind( opt_selectedKeybind, type, key, mod ); /* Close window. */ window_close( wid, NULL ); /* Update parent window. */ parent = window_getParent( wid ); pos = toolkit_getListPos( parent, "lstKeybinds" ); off = toolkit_getListOffset( parent, "lstKeybinds" ); window_destroyWidget( parent, "lstKeybinds" ); menuKeybinds_genList( parent ); toolkit_setListPos( parent, "lstKeybinds", pos ); toolkit_setListOffset( parent, "lstKeybinds", off ); return 0; }
/** * @brief Makes the player take off if landed. * * @param delay Whether or not to have time pass as if the player landed normally. */ void takeoff( int delay ) { int h; char *nt; double a, r; if (!landed) return; /* Player's ship is not able to fly. */ if (!player_canTakeoff()) { char message[512]; pilot_reportSpaceworthy( player.p, message, sizeof(message) ); dialogue_msg( "Ship not fit for flight", message ); /* Check whether the player needs rescuing. */ land_stranded(); return; } /* Clear queued takeoff. */ land_takeoff = 0; /* Refuel if needed. */ land_refuel(); /* In case we had paused messy sounds. */ sound_stopAll(); /* ze music */ music_choose("takeoff"); /* to randomize the takeoff a bit */ a = RNGF() * 2. * M_PI; r = RNGF() * land_planet->radius; /* no longer authorized to land */ player_rmFlag(PLAYER_LANDACK); pilot_rmFlag(player.p,PILOT_LANDING); /* No longer landing. */ /* set player to another position with random facing direction and no vel */ player_warp( land_planet->pos.x + r * cos(a), land_planet->pos.y + r * sin(a) ); vect_pset( &player.p->solid->vel, 0., 0. ); player.p->solid->dir = RNGF() * 2. * M_PI; cam_setTargetPilot( player.p->id, 0 ); /* heal the player */ pilot_healLanded( player.p ); /* Clear planet target. Allows for easier autonav out of the system. */ player_targetPlanetSet( -1 ); /* initialize the new space */ h = player.p->nav_hyperspace; space_init(NULL); player.p->nav_hyperspace = h; /* cleanup */ if (save_all() < 0) /* must be before cleaning up planet */ dialogue_alert( "Failed to save game! You should exit and check the log to see what happened and then file a bug report!" ); /* time goes by, triggers hook before takeoff */ if (delay) ntime_inc( ntime_create( 0, 1, 0 ) ); /* 1 STP */ nt = ntime_pretty( 0, 2 ); player_message("\epTaking off from %s on %s.", land_planet->name, nt); free(nt); /* Hooks and stuff. */ land_cleanup(); /* Cleanup stuff */ hooks_run("takeoff"); /* Must be run after cleanup since we don't want the missions to think we are landed. */ if (menu_isOpen(MENU_MAIN)) return; player_addEscorts(); hooks_run("enter"); if (menu_isOpen(MENU_MAIN)) return; events_trigger( EVENT_TRIGGER_ENTER ); missions_run( MIS_AVAIL_SPACE, -1, NULL, NULL ); if (menu_isOpen(MENU_MAIN)) return; player.p->ptimer = PILOT_TAKEOFF_DELAY; pilot_setFlag( player.p, PILOT_TAKEOFF ); pilot_setThrust( player.p, 0. ); pilot_setTurn( player.p, 0. ); }