/** * @brief Would be like "dofile" from the base Lua lib. */ static int cli_script( lua_State *L ) { const char *fname; char buf[PATH_MAX], *bbuf; int n; /* Handle parameters. */ fname = luaL_optstring(L, 1, NULL); n = lua_gettop(L); /* Try to find the file if it exists. */ if (nfile_fileExists(fname)) nsnprintf( buf, sizeof(buf), "%s", fname ); else { bbuf = strdup( naev_binary() ); nsnprintf( buf, sizeof(buf), "%s/%s", nfile_dirname( bbuf ), fname ); free(bbuf); } /* Do the file. */ if (luaL_loadfile(L, buf) != 0) lua_error(L); /* Return the stuff. */ lua_call(L, 0, LUA_MULTRET); return lua_gettop(L) - n; }
/** * @brief Dumps ammo data to CSV. */ void dout_csvAmmo( const char *path ) { Outfit *o, *o_all; int i, j, n, l; SDL_RWops *rw; char buf[ 1024 ]; char *ai; Damage *dmg; /* File to output to. */ rw = SDL_RWFromFile( path, "w" ); if (rw == NULL) { WARN("Unable to open '%s' for writing: %s", path, SDL_GetError()); return; } /* Write "header" */ l = nsnprintf( buf, sizeof(buf), "name,type,license," "mass,price," "duration,resist,ai," "speed,turn,thrust,energy," "penetration,dtype,dmg,disable\n" ); SDL_RWwrite( rw, buf, l, 1 ); o_all = outfit_getAll( &n ); for (i=0; i<n; i++) { o = &o_all[i]; /* Only handle ammo. */ if (!outfit_isAmmo(o)) continue; dmg = &o->u.blt.dmg; /* Get AI name, in lower case. */ ai = strdup( outfit_getAmmoAI(o) ); for (j=0; j<(int)strlen(ai); j++) ai[j] = tolower(ai[j]); l = nsnprintf( buf, sizeof(buf), "%s,%s,%s," "%f,%"CREDITS_PRI"," "%f,%f,%s," "%f,%f,%f,%f," "%f,%s,%f,%f\n", o->name, outfit_getType(o), o->license, o->mass, o->price, o->u.amm.duration, o->u.amm.resist * 100, ai, o->u.amm.speed, o->u.amm.turn * 180 / M_PI, o->u.amm.thrust, o->u.amm.energy, dmg->penetration * 100, dtype_damageTypeToStr(dmg->type), dmg->damage, dmg->disable ); free(ai); SDL_RWwrite( rw, buf, l, 1 ); } /* Close file. */ SDL_RWclose( rw ); }
/** * @brief Checks if should add the refuel button and does if needed. */ void land_checkAddRefuel (void) { char buf[ECON_CRED_STRLEN], cred[ECON_CRED_STRLEN]; unsigned int w; /* Check to see if fuel conditions are met. */ if (!planet_hasService(land_planet, PLANET_SERVICE_REFUEL)) { if (!widget_exists( land_windows[0], "txtRefuel" )) window_addText( land_windows[0], -20, 20 + (LAND_BUTTON_HEIGHT + 20) + 20, 200, gl_defFont.h, 1, "txtRefuel", &gl_defFont, &cBlack, "No refueling services." ); return; } /* Full fuel. */ if (player.p->fuel >= player.p->fuel_max) { if (widget_exists( land_windows[0], "btnRefuel" )) window_destroyWidget( land_windows[0], "btnRefuel" ); if (widget_exists( land_windows[0], "txtRefuel" )) window_destroyWidget( land_windows[0], "txtRefuel" ); return; } /* Autorefuel. */ if (conf.autorefuel) { spaceport_refuel( land_windows[0], "btnRefuel" ); w = land_getWid( LAND_WINDOW_EQUIPMENT ); if (w > 0) equipment_updateShips( w, NULL ); /* Must update counter. */ if (player.p->fuel >= player.p->fuel_max) return; } /* Just enable button if it exists. */ if (widget_exists( land_windows[0], "btnRefuel" )) { window_enableButton( land_windows[0], "btnRefuel"); credits2str( cred, player.p->credits, 2 ); nsnprintf( buf, sizeof(buf), "Credits: %s", cred ); window_modifyText( land_windows[0], "txtRefuel", buf ); } /* Else create it. */ else { /* Refuel button. */ credits2str( cred, refuel_price(), 2 ); nsnprintf( buf, sizeof(buf), "Refuel %s", cred ); window_addButton( land_windows[0], -20, 20 + (LAND_BUTTON_HEIGHT + 20), LAND_BUTTON_WIDTH,LAND_BUTTON_HEIGHT, "btnRefuel", buf, spaceport_refuel ); /* Player credits. */ credits2str( cred, player.p->credits, 2 ); nsnprintf( buf, sizeof(buf), "Credits: %s", cred ); window_addText( land_windows[0], -20, 20 + 2*(LAND_BUTTON_HEIGHT + 20), LAND_BUTTON_WIDTH, gl_smallFont.h, 1, "txtRefuel", &gl_smallFont, &cBlack, buf ); } /* Make sure player can click it. */ if (!player_hasCredits( refuel_price() )) window_disableButton( land_windows[0], "btnRefuel" ); }
/** * @brief Gets Naev's cache path (for cached data such as generated textures) * * @return The xdg cache path. */ const char* nfile_cachePath (void) { char *path; if (naev_cachePath[0] == '\0') { #if HAS_UNIX path = xdgGetRelativeHome( "XDG_CACHE_HOME", "/.cache" ); if (path == NULL) { WARN("$XDG_CACHE_HOME isn't set, using current directory."); path = strdup("."); } nsnprintf( naev_cachePath, PATH_MAX, "%s/naev/", path ); if (path != NULL) { free (path); } #elif HAS_WIN32 path = SDL_getenv("APPDATA"); if (path == NULL) { WARN("%%APPDATA%% isn't set, using current directory."); path = "."; } nsnprintf( naev_cachePath, PATH_MAX, "%s/naev/", path ); #else #error "Feature needs implementation on this Operating System for Naev to work." #endif } return naev_cachePath; }
/** * @brief Dumps ship data to csv. */ void dship_csv( const char *path ) { Ship *s, *s_all; int i, n, l; SDL_RWops *rw; char buf[ 1024 ]; /* File to output to. */ rw = SDL_RWFromFile( path, "w" ); if (rw == NULL) { WARN("Unable to open '%s' for writing: %s", path, SDL_GetError()); return; } /* Write "header" */ l = nsnprintf( buf, sizeof(buf), "name,class,base_type,price,license,fabricator," "thrust,turn,speed," "crew,mass,cpu,fuel,cargo," "absorb," "armour,armour_regen," "shield,shield_regen," "energy,energy_regen," "slot weapon,slot utility,slot structure\n" ); SDL_RWwrite( rw, buf, l, 1 ); s_all = ship_getAll( &n ); for (i=0; i<n; i++) { s = &s_all[i]; l = nsnprintf( buf, sizeof(buf), "%s,%s,%s,%"CREDITS_PRI",%s,%s," "%f,%f,%f," "%d,%f,%f,%d,%f," "%f," "%f,%f," "%f,%f," "%f,%f," "%d,%d,%d\n", s->name, ship_class(s), s->base_type, s->price, s->license, s->fabricator, s->thrust, s->turn*180./M_PI, s->speed, s->crew, s->mass, s->cpu, s->fuel, s->cap_cargo, s->dmg_absorb*100, s->armour, s->armour_regen, s->shield, s->shield_regen, s->energy, s->energy_regen, s->outfit_nweapon, s->outfit_nutility, s->outfit_nstructure ); SDL_RWwrite( rw, buf, l, 1 ); } /* Close file. */ SDL_RWclose( rw ); }
/** * @brief Dumps the bolt weapon data to csv. */ void dout_csvBolt( const char *path ) { Outfit *o, *o_all; int i, n, l; SDL_RWops *rw; char buf[ 1024 ]; Damage *dmg; /* File to output to. */ rw = SDL_RWFromFile( path, "w" ); if (rw == NULL) { WARN("Unable to open '%s' for writing: %s", path, SDL_GetError()); return; } /* Write "header" */ l = nsnprintf( buf, sizeof(buf), "name,type,slot,license," "mass,price," "delay,speed,range,falloff," "lockon,energy,heatup,cpu," "track,swivel," "penetrate,dtype,damage,disable\n" ); SDL_RWwrite( rw, buf, l, 1 ); o_all = outfit_getAll( &n ); for (i=0; i<n; i++) { o = &o_all[i]; /* Only handle bolt weapons. */ if (!outfit_isBolt(o)) continue; dmg = &o->u.blt.dmg; l = nsnprintf( buf, sizeof(buf), "%s,%s,%s,%s," "%f,%"CREDITS_PRI"," "%f,%f,%f,%f," "%f,%f,%f,%f," "%f,%f," "%f,%s,%f,%f\n", o->name, outfit_getType(o), outfit_slotName(o), o->license, o->mass, o->price, o->u.blt.delay*1000., o->u.blt.speed, o->u.blt.range, o->u.blt.falloff, o->u.blt.ew_lockon, o->u.blt.energy, o->u.blt.heatup, o->u.blt.cpu, o->u.blt.track, o->u.blt.swivel * 180. / M_PI, dmg->penetration*100, dtype_damageTypeToStr(dmg->type), dmg->damage, dmg->disable ); SDL_RWwrite( rw, buf, l, 1 ); } /* Close file. */ SDL_RWclose( rw ); }
/** * @brief Player death menu, appears when player got creamed. */ void menu_death (void) { unsigned int wid; char path[PATH_MAX]; wid = window_create( "Death", -1, -1, DEATH_WIDTH, DEATH_HEIGHT ); window_onClose( wid, menu_death_close ); /* Allow the player to continue if the savegame exists, if not, propose to restart */ nsnprintf(path, PATH_MAX, "%ssaves/%s.ns", nfile_dataPath(), player.name); if (!player_isTut() && nfile_fileExists(path)) window_addButtonKey( wid, 20, 20 + BUTTON_HEIGHT*2 + 20*2, BUTTON_WIDTH, BUTTON_HEIGHT, "btnContinue", _("Continue"), menu_death_continue, SDLK_c ); else window_addButtonKey( wid, 20, 20 + BUTTON_HEIGHT*2 + 20*2, BUTTON_WIDTH, BUTTON_HEIGHT, "btnRestart", _("Restart"), menu_death_restart, SDLK_r ); window_addButtonKey( wid, 20, 20 + (BUTTON_HEIGHT+20), BUTTON_WIDTH, BUTTON_HEIGHT, "btnMain", _("Main Menu"), menu_death_main, SDLK_m ); window_addButtonKey( wid, 20, 20, BUTTON_WIDTH, BUTTON_HEIGHT, "btnExit", _("Exit Game"), menu_exit, SDLK_x ); menu_Open(MENU_DEATH); /* Makes it all look cooler since everything still goes on. */ unpause_game(); }
/** * @brief Dumps ships and their standard ship stats to CSV. */ void dship_csvStat( const char *path ) { Ship *s, *s_all; int i, n, l; SDL_RWops *rw; char buf[1024]; /* File to output to. */ rw = SDL_RWFromFile( path, "w" ); if (rw == NULL) { WARN("Unable to open '%s' for writing: %s", path, SDL_GetError()); return; } /* Write header. */ strncpy(buf, "name,", sizeof(buf)); l = 5; l += ss_csv( NULL, &buf[l], sizeof(buf) - l ); SDL_RWwrite( rw, buf, l, 1 ); s_all = ship_getAll( &n ); for (i=0; i<n; i++) { s = &s_all[i]; /* Prepend name. */ l = nsnprintf( buf, sizeof(buf), "%s,", s->name ); l += ss_csv( &(s->stats_array), &buf[l], sizeof(buf) - l ); SDL_RWwrite( rw, buf, l, 1 ); } /* Close file. */ SDL_RWclose( rw ); }
/** * @brief Loads the nebulae from file. * * @param file Path of the nebula to load. Relative to base directory. * @return A SDL surface with the nebula. */ static SDL_Surface* loadNebula( const char* file ) { char file_path[PATH_MAX]; SDL_Surface* sur; SDL_RWops *rw; npng_t *npng; /* loads the file */ nsnprintf(file_path, PATH_MAX, "%s"NEBULA_PATH"%s", nfile_cachePath(), file ); rw = SDL_RWFromFile( file_path, "rb" );; if (rw == NULL) { WARN("Unable to create rwops from Nebula image: %s", file); return NULL; } npng = npng_open( rw ); if (npng == NULL) { WARN("Unable to open Nebula image: %s", file); SDL_RWclose( rw ); return NULL; } sur = npng_readSurface( npng, 0, 1 ); npng_close( npng ); SDL_RWclose( rw ); if (sur == NULL) { WARN("Unable to load Nebula image: %s", file); return NULL; } return sur; }
/** * @brief Updates the mission list. * @param wid Window of the mission computer. * @param str Unused. */ static void misn_update( unsigned int wid, char* str ) { (void) str; char *active_misn; Mission* misn; char txt[256], *buf; /* Clear computer markers. */ space_clearComputerMarkers(); /* Update date stuff. */ buf = ntime_pretty( 0, 2 ); nsnprintf( txt, sizeof(txt), "%s\n%d Tons", buf, player.p->cargo_free ); free(buf); window_modifyText( wid, "txtDate", txt ); active_misn = toolkit_getList( wid, "lstMission" ); if (strcmp(active_misn,"No Missions")==0) { window_modifyText( wid, "txtReward", "None" ); window_modifyText( wid, "txtDesc", "There are no missions available here." ); window_disableButton( wid, "btnAcceptMission" ); return; } misn = &mission_computer[ toolkit_getListPos( wid, "lstMission" ) ]; mission_sysComputerMark( misn ); if (misn->markers != NULL) map_center( system_getIndex( misn->markers[0].sys )->name ); window_modifyText( wid, "txtReward", misn->reward ); window_modifyText( wid, "txtDesc", misn->desc ); window_enableButton( wid, "btnAcceptMission" ); }
/** * @brief Backup a file, if it exists. * * @param path printf formatted string pointing to the file to backup. * @return 0 on success, or if file does not exist, -1 on error. */ int nfile_backupIfExists( const char* path, ... ) { char file[PATH_MAX]; va_list ap; char backup[PATH_MAX]; FILE *f_in, *f_out; char buf[ 8*1024 ]; size_t lr, lw; if (path == NULL) return -1; va_start(ap, path); vsnprintf(file, PATH_MAX, path, ap); va_end(ap); if (!nfile_fileExists(file)) return 0; nsnprintf(backup, PATH_MAX, "%s.backup", file); /* Open files. */ f_in = fopen( file, "rb" ); f_out = fopen( backup, "wb" ); if ((f_in==NULL) || (f_out==NULL)) { WARN( "Failure to create back up of '%s': %s", file, strerror(errno) ); if (f_in!=NULL) fclose(f_in); return -1; } /* Copy data over. */ do { lr = fread( buf, 1, sizeof(buf), f_in ); if (ferror(f_in)) goto err; else if (!lr) { if (feof(f_in)) break; goto err; } lw = fwrite( buf, 1, lr, f_out ); if (ferror(f_out) || (lr != lw)) goto err; } while (lr > 0); /* Close files. */ fclose( f_in ); fclose( f_out ); return 0; err: WARN( "Failure to create back up of '%s': %s", file, strerror(errno) ); fclose( f_in ); fclose( f_out ); return -1; }
/** * @brief Adds the "Buy Local Map" button if needed. */ void land_checkAddMap (void) { char buf[ECON_CRED_STRLEN], cred[ECON_CRED_STRLEN]; Outfit *o; /* Maps are only offered if the planet provides fuel. */ if (!planet_hasService(land_planet, PLANET_SERVICE_REFUEL)) return; o = outfit_get( LOCAL_MAP_NAME ); if (o == NULL) { WARN("Outfit '%s' does not exist!", LOCAL_MAP_NAME); return; } /* Just enable button if it exists. */ if (widget_exists( land_windows[0], "btnMap" )) window_enableButton( land_windows[0], "btnMap"); /* Else create it. */ else { /* Refuel button. */ credits2str( cred, o->price, 2 ); nsnprintf( buf, sizeof(buf), "Buy Local Map (%s)", cred ); window_addButtonKey( land_windows[0], -20, 20 + (LAND_BUTTON_HEIGHT + 20), LAND_BUTTON_WIDTH,LAND_BUTTON_HEIGHT, "btnMap", buf, spaceport_buyMap, SDLK_b ); } /* Make sure player can click it. */ if (!outfit_canBuy(LOCAL_MAP_NAME, land_planet)) window_disableButtonSoft( land_windows[0], "btnMap" ); }
/** * @brief Adds an NPC. * * @usage npc_id = evt.npcAdd( "my_func", "Mr. Test", "none", "A test." ) -- Creates an NPC. * * @luaparam func Name of the function to run when approaching, gets passed the npc_id when called. * @luaparam name Name of the NPC * @luaparam portrait Portrait to use for the NPC (from GFX_PATH/portraits/). * @luaparam desc Description associated to the NPC. * @luaparam priority Optional priority argument (defaults to 5, highest is 0, lowest is 10). * @luareturn The ID of the NPC to pass to npcRm. * @luafunc npcAdd( func, name, portrait, desc, priority ) */ static int evt_npcAdd( lua_State *L ) { unsigned int id; int priority; const char *func, *name, *gfx, *desc; char portrait[PATH_MAX]; Event_t *cur_event; /* Handle parameters. */ func = luaL_checkstring(L, 1); name = luaL_checkstring(L, 2); gfx = luaL_checkstring(L, 3); desc = luaL_checkstring(L, 4); /* Optional priority. */ if (lua_gettop(L) > 4) priority = luaL_checkint( L, 5 ); else priority = 5; /* Set path. */ nsnprintf( portrait, PATH_MAX, GFX_PATH"portraits/%s.png", gfx ); cur_event = event_getFromLua(L); /* Add npc. */ id = npc_add_event( cur_event->id, func, name, priority, portrait, desc ); /* Return ID. */ if (id > 0) { lua_pushnumber( L, id ); return 1; } return 0; }
/** * @brief Updates the quantity counter for the outfits. * * @param wid Window to update counters of. */ void outfits_updateQuantities( unsigned int wid ) { Outfit **outfits, *o; int noutfits; char **quantity; int len, owned; int i; /* Get outfits. */ outfits = tech_getOutfit( land_planet->tech, &noutfits ); if (noutfits <= 0) return; quantity = malloc(sizeof(char*)*noutfits); for (i=0; i<noutfits; i++) { o = outfits[i]; owned = player_outfitOwned(o); len = owned / 10 + 4; if (owned >= 1) { quantity[i] = malloc( len ); nsnprintf( quantity[i], len, "%d", owned ); } else quantity[i] = NULL; } free(outfits); toolkit_setImageArrayQuantity( wid, "iarOutfits", quantity ); }
/** * @brief Dumps launcher data to CSV. */ void dout_csvLauncher( const char *path ) { Outfit *o, *o_all; int i, n, l; SDL_RWops *rw; char buf[ 1024 ]; /* File to output to. */ rw = SDL_RWFromFile( path, "w" ); if (rw == NULL) { WARN("Unable to open '%s' for writing: %s", path, SDL_GetError()); return; } /* Write "header" */ l = nsnprintf( buf, sizeof(buf), "name,type,slot,size," "license,mass,price,cpu," "delay,ammo_name,amount," "lockon,ew_target,arc\n" ); SDL_RWwrite( rw, buf, l, 1 ); o_all = outfit_getAll( &n ); for (i=0; i<n; i++) { o = &o_all[i]; /* Only handle launchers. */ if (!outfit_isLauncher(o)) continue; l = nsnprintf( buf, sizeof(buf), "%s,%s,%s,%s," "%s,%f,%"CREDITS_PRI",%f," "%f,%s,%d," "%f,%f,%f\n", o->name, outfit_getType(o), outfit_slotName(o), outfit_slotSize(o), o->license, o->mass, o->price, o->cpu, o->u.lau.delay, o->u.lau.ammo_name, o->u.lau.amount, o->u.lau.lockon, o->u.lau.ew_target, o->u.lau.arc * 180 / M_PI ); SDL_RWwrite( rw, buf, l, 1 ); } /* Close file. */ SDL_RWclose( rw ); }
/** * @brief Generates an filled circle texture. * * @param radius Radius of the circle to generate. * @return The tetxure containing the generated circle. */ static glTexture *gl_genCircle( int radius ) { int i,j,k, n,m; SDL_Surface *sur; uint8_t *pix, *buf; int h, w; double a; char name[PATH_MAX]; /* Calculate parameters. */ w = 2*radius+1; h = 2*radius+1; /* Create the surface. */ sur = SDL_CreateRGBSurface( SDL_SWSURFACE, w, h, 32, RGBAMASK ); pix = sur->pixels; /* Generate the circle. */ SDL_LockSurface( sur ); /* Create temporary buffer to draw circle in. */ k = 3; buf = malloc( (h*k) * (w*k) ); for (i=0; i<k*h; i++) { for (j=0; j<k*w; j++) { if (pow2(i-k*radius)+pow2(j-k*radius) < pow2(k*radius)) buf[ i*k*w + j] = 0xFF; } } /* Draw the circle with filter. */ for (i=0; i<h; i++) { for (j=0; j<w; j++) { /* Calculate blur. */ a = 0.; for (n=0; n<k; n++) for (m=0; m<k; m++) a += buf[ (i*k+n)*k*w + (j*k+m) ]; a /= k*k; /* Set pixel. */ pix[i*sur->pitch + j*4 + 0] = 0xFF; pix[i*sur->pitch + j*4 + 1] = 0xFF; pix[i*sur->pitch + j*4 + 2] = 0xFF; pix[i*sur->pitch + j*4 + 3] = (uint8_t)a; } } /* Clean up. */ free(buf); SDL_UnlockSurface( sur ); /* Return texture. */ nsnprintf( name, sizeof(name), "gencircle%d", radius ); return gl_loadImagePad( name, sur, OPENGL_TEX_MIPMAPS, sur->w, sur->h, 1, 1, 1 ); }
/** * @brief Updates the commodity window. * @param wid Window to update. * @param str Unused. */ static void commodity_update( unsigned int wid, char* str ) { (void)str; char buf[PATH_MAX]; char *comname; Commodity *com; comname = toolkit_getList( wid, "lstGoods" ); if ((comname==NULL) || (strcmp( comname, "None" )==0)) { nsnprintf( buf, PATH_MAX, "NA Tons\n" "NA Credits/Ton\n" "\n" "NA Tons\n" ); window_modifyText( wid, "txtDInfo", buf ); window_modifyText( wid, "txtDesc", "No outfits available." ); window_disableButton( wid, "btnCommodityBuy" ); window_disableButton( wid, "btnCommoditySell" ); return; } com = commodity_get( comname ); /* modify text */ nsnprintf( buf, PATH_MAX, "%d Tons\n" "%"CREDITS_PRI" Credits/Ton\n" "\n" "%d Tons\n", pilot_cargoOwned( player.p, comname ), planet_commodityPrice( land_planet, com ), pilot_cargoFree(player.p)); window_modifyText( wid, "txtDInfo", buf ); window_modifyText( wid, "txtDesc", com->description ); /* Button enabling/disabling */ if (commodity_canBuy( comname )) window_enableButton( wid, "btnCommodityBuy" ); else window_disableButtonSoft( wid, "btnCommodityBuy" ); if (commodity_canSell( comname )) window_enableButton( wid, "btnCommoditySell" ); else window_disableButtonSoft( wid, "btnCommoditySell" ); }
/** * @brief Generates error dialogues used by several landing tabs. * @param fmt String with printf-like formatting */ void land_errDialogueBuild( const char *fmt, ... ) { va_list ap; if (fmt == NULL) return; else { /* get the message */ va_start(ap, fmt); vsnprintf(errorreason, 512, fmt, ap); va_end(ap); } if (errorlist_ptr == NULL) /* Initialize on first run. */ errorappend = nsnprintf( errorlist, sizeof(errorlist), "%s", errorreason ); else /* Append newest error to the existing list. */ nsnprintf( &errorlist[errorappend], sizeof(errorlist)-errorappend, "\n%s", errorreason ); errorlist_ptr = errorlist; }
/** * @brief Renames all the currently selected systems. */ static void uniedit_renameSys (void) { int i, j; char *name, *oldName, *newName; StarSystem *sys; for (i=0; i<uniedit_nsys; i++) { sys = uniedit_sys[i]; /* Get name. */ name = dialogue_input( "Rename Star System", 1, 32, "What do you want to rename \er%s\e0?", sys->name ); /* Keep current name. */ if (name == NULL) continue; /* Try again. */ if (uniedit_checkName( name )) { free(name); i--; continue; } /* Change the name. */ oldName = malloc((14+strlen(sys->name))); nsnprintf(oldName,14+strlen(sys->name),"dat/ssys/%s.xml", uniedit_nameFilter(sys->name) ); newName = malloc(14+strlen(name)); nsnprintf(newName,14+strlen(name),"dat/ssys/%s.xml", uniedit_nameFilter(name) ); nfile_rename(oldName,newName); free(oldName); free(newName); free(sys->name); sys->name = name; if (conf.devautosave) { dsys_saveSystem(sys); /* Re-save adjacent systems. */ for (j=0; j<sys->njumps; j++) dsys_saveSystem( sys->jumps[j].target ); } } }
/** * @brief Sets the selected system text. */ static void uniedit_selectText (void) { int i, l; char buf[1024]; StarSystem *sys; int hasPresence; l = 0; for (i=0; i<uniedit_nsys; i++) { l += nsnprintf( &buf[l], sizeof(buf)-l, "%s%s", uniedit_sys[i]->name, (i == uniedit_nsys-1) ? "" : ", " ); } if (l == 0) uniedit_deselect(); else { window_modifyText( uniedit_wid, "txtSelected", buf ); /* Presence text. */ if (uniedit_nsys == 1) { sys = uniedit_sys[0]; buf[0] = '\0'; hasPresence = 0; l = 0; for (i=0; i < sys->npresence ; i++) { /* Must have presence. */ if (sys->presence[i].value <= 0) continue; hasPresence = 1; /* Use map grey instead of default neutral colour */ l += nsnprintf( &buf[l], sizeof(buf)-l, "%s\e0%s: %.0f", (l==0)?"":"\n", faction_name(sys->presence[i].faction), sys->presence[i].value); } if (hasPresence == 0) nsnprintf( buf, sizeof(buf), "None" ); window_modifyText( uniedit_wid, "txtPresence", buf ); } else
/** * @brief Gets the time in a pretty human readable format filling a preset buffer. * * @param[out] str Buffer to use. * @param max Maximum length of the buffer (recommended 64). * @param t Time to print (in STU), if 0 it'll use the current time. * @param d Number of digits to use. * @return The time in a human readable format (must free). */ void ntime_prettyBuf( char *str, int max, ntime_t t, int d ) { ntime_t nt; int scu, stp, stu; if (t==0) nt = naev_time; else nt = t; /* UST (Universal Synchronized Time) - unit is STU (Synchronized Time Unit) */ scu = ntime_getSCU( nt ); stp = ntime_getSTP( nt ); stu = ntime_getSTU( nt ); if ((scu==0) && (stp==0)) /* only STU */ nsnprintf( str, max, "%04d STU", stu ); else if ((scu==0) || (d==0)) nsnprintf( str, max, "%.*f STP", d, stp + 0.0001 * stu ); else /* UST format */ nsnprintf( str, max, "UST %d:%.*f", scu, d, stp + 0.0001 * stu ); }
/** * @brief Updates the ship stuff. */ static void ship_update( unsigned int wid ) { char buf[1024], *hyp_delay; int cargo, len; cargo = pilot_cargoUsed( player.p ) + pilot_cargoFree( player.p ); hyp_delay = ntime_pretty( pilot_hyperspaceDelay( player.p ), 2 ); len = nsnprintf( buf, sizeof(buf), _("%s\n" "%s\n" "%s\n" "%d\n" "\n" "%d teraflops\n" "%.0f tonnes\n" "%s average\n" "%.0f kN/tonne\n" "%.0f m/s (max %.0f m/s)\n" "%.0f deg/s\n" "\n" "%.0f%%\n" /* Absorbption */ "%.0f / %.0f MJ (%.1f MW)\n" /* Shield */ "%.0f / %.0f MJ (%.1f MW)\n" /* Armour */ "%.0f / %.0f MJ (%.1f MW)\n" /* Energy */ "%d / %d tonnes\n" "%.0f / %.0f units (%d jumps)\n" "\n"), /* Generic */ player.p->name, player.p->ship->name, ship_class(player.p->ship), (int)floor(player.p->crew), player.p->cpu_max, /* Movement. */ player.p->solid->mass, hyp_delay, player.p->thrust / player.p->solid->mass, player.p->speed, solid_maxspeed( player.p->solid, player.p->speed, player.p->thrust ), player.p->turn*180./M_PI, /* Health. */ player.p->dmg_absorb * 100., player.p->shield, player.p->shield_max, player.p->shield_regen, player.p->armour, player.p->armour_max, player.p->armour_regen, player.p->energy, player.p->energy_max, player.p->energy_regen, pilot_cargoUsed( player.p ), cargo, player.p->fuel, player.p->fuel_max, pilot_getJumps(player.p)); equipment_shipStats( &buf[len], sizeof(buf)-len, player.p, 1 ); window_modifyText( wid, "txtDDesc", buf ); free( hyp_delay ); }
/** * @brief Gets all the outfits in nice text form. * * @param pilot Pilot to get the outfits from. * @@return A list of all the outfits in a nice form. */ char* pilot_getOutfits( const Pilot* pilot ) { int i; char *buf; int p, len; len = 1024; buf = malloc(len); buf[0] = '\0'; p = 0; for (i=1; i<pilot->noutfits; i++) { if (pilot->outfits[i]->outfit == NULL) continue; p += nsnprintf( &buf[p], len-p, (p==0) ? "%s" : ", %s", pilot->outfits[i]->outfit->name ); } if (p==0) p += nsnprintf( &buf[p], len-p, "None" ); return buf; }
/** * @brief Renames all the currently selected systems. */ static void uniedit_renameSys (void) { int i; char *name, *oldName, *newName; StarSystem *sys; for (i=0; i<uniedit_nsys; i++) { sys = uniedit_sys[i]; /* Get name. */ name = dialogue_input( "Rename Star System", 1, 32, "What do you want to rename \er%s\e0?", sys->name ); /* Keep current name. */ if (name == NULL) continue; /* Try again. */ if (uniedit_checkName( name )) { free(name); i--; continue; } /* Change the name. */ oldName = malloc((16+strlen(sys->name))*sizeof(char)); nsnprintf(oldName,15+strlen(sys->name),"dat/ssys/%s.xml",sys->name); newName = malloc((16+strlen(name))*sizeof(char)); nsnprintf(newName,15+strlen(name),"dat/ssys/%s.xml",name); nfile_rename(oldName,newName); free(oldName); free(newName); free(sys->name); sys->name = name; dsys_saveSystem(sys); } }
/** * @brief Renders the commodity buying modifier. * @param bx Base X position to render at. * @param by Base Y position to render at. * @param w Width to render at. * @param h Height to render at. */ static void commodity_renderMod( double bx, double by, double w, double h, void *data ) { (void) data; (void) h; int q; char buf[8]; q = commodity_getMod(); if (q != commodity_mod) { commodity_update( land_getWid(LAND_WINDOW_COMMODITY), NULL ); commodity_mod = q; } nsnprintf( buf, 8, "%dx", q ); gl_printMid( &gl_smallFont, w, bx, by, &cBlack, buf ); }
/** * @brief Gets Naev's data path (for user data such as saves and screenshots) * * @return The xdg data path. */ const char* nfile_dataPath (void) { char *path; if (naev_dataPath[0] == '\0') { /* Global override is set. */ if (conf.datapath) { nsnprintf( naev_dataPath, PATH_MAX, "%s/", conf.datapath ); return naev_dataPath; } #if HAS_UNIX path = xdgGetRelativeHome( "XDG_DATA_HOME", "/.local/share" ); if (path == NULL) { WARN("$XDG_DATA_HOME isn't set, using current directory."); path = strdup("."); } nsnprintf( naev_dataPath, PATH_MAX, "%s/naev/", path ); if (path != NULL) { free (path); } #elif HAS_WIN32 path = SDL_getenv("APPDATA"); if (path == NULL) { WARN("%%APPDATA%% isn't set, using current directory."); path = "."; } nsnprintf( naev_dataPath, PATH_MAX, "%s/naev/", path ); #else #error "Feature needs implementation on this Operating System for Naev to work." #endif } return naev_dataPath; }
int pilot_reportSpaceworthy( Pilot *p, char buf[], int bufSize ) { int pos = 0; int ret = 0; /* Core Slots */ SPACEWORTHY_CHECK( !pilot_slotsCheckRequired(p), "Not All Core Slots are equipped\n" ); /* CPU. */ SPACEWORTHY_CHECK( p->cpu < 0, "Insufficient CPU\n" ); /* Movement. */ SPACEWORTHY_CHECK( p->thrust < 0, "Insufficient Thrust\n" ); SPACEWORTHY_CHECK( p->speed < 0, "Insufficient Speed\n" ); SPACEWORTHY_CHECK( p->turn < 0, "Insufficient Turn\n" ); /* Health. */ SPACEWORTHY_CHECK( p->armour < 0., "Insufficient Armour\n" ); SPACEWORTHY_CHECK( p->armour_regen < 0., "Insufficient Armour Regeneration\n" ); SPACEWORTHY_CHECK( p->shield < 0., "Insufficient Shield\n" ); SPACEWORTHY_CHECK( p->shield_regen < 0., "Insufficient Shield Regeneration\n" ); SPACEWORTHY_CHECK( p->energy_max < 0., "Insufficient Energy\n" ); SPACEWORTHY_CHECK( p->energy_regen < 0., "Insufficient Energy Regeneration\n" ); /* Misc. */ SPACEWORTHY_CHECK( p->fuel_max < 0., "Insufficient Fuel Maximum\n" ); SPACEWORTHY_CHECK( p->fuel_consumption < 0., "Insufficient Fuel Consumption\n" ); SPACEWORTHY_CHECK( p->cargo_free < 0, "Insufficient Free Cargo Space\n" ); /*buffer is full, lets write that there is more then what's copied */ if (pos > bufSize-1) { buf[bufSize-4]='.'; buf[bufSize-3]='.'; buf[bufSize-2]='.'; /* buf[bufSize-1]='\0'; already done for us */ } else { if (pos == 0) /*string is empty so no errors encountered */ nsnprintf( buf, bufSize, "Spaceworthy"); else /*string is not empty, so trunc the last newline */ buf[pos-1]='\0'; } return ret; }
/** * @brief Opens a dialogue window with an ok button, a fixed message and an image. * * @param caption Window title. * @param msg Message to display. * @param width Width of the image. Negative uses image width. * @param height Height of the image. Negative uses image height. */ void dialogue_msgImgRaw( const char* caption, const char *msg, const char *img, int width, int height ) { int w, h, img_width, img_height; glFont* font; unsigned int msg_wid; int done; glTexture *gfx; char buf[PATH_MAX]; /* Get the desired texture */ /* IMPORTANT : texture must not be freed here, it will be freed when the widget closes */ nsnprintf( buf, sizeof(buf), "%s%s", GFX_PATH, img ); gfx = gl_newImage( buf, 0 ); /* Find the popup's dimensions from text and image */ img_width = (width < 0) ? gfx->w : width; img_height = (height < 0) ? gfx->h : height; font = dialogue_getSize( caption, msg, &w, &h ); if (h < img_width) { h = img_width; } /* Create the window */ msg_wid = window_create( caption, -1, -1, img_width + w, 110 + h ); window_setData( msg_wid, &done ); /* Add the text box */ window_addText( msg_wid, img_width+40, -40, w-40, h, 0, "txtMsg", font, &cBlack, msg ); /* Add a placeholder rectangle for the image */ window_addRect( msg_wid, 20, -40, img_width, img_height, "rctGFX", &cGrey10, 1 ); /* Actually add the texture in the rectangle */ window_addImage( msg_wid, 20, -40, img_width, img_height, "ImgGFX", gfx, 0 ); /* Add the OK button */ window_addButton( msg_wid, (img_width+w -50)/2, 20, 50, 30, "btnOK", "OK", dialogue_close ); dialogue_open++; toolkit_loop( &done ); }
/** * @brief Saves a nebula. * * @param map Nebula map to save. * @param w Width of nebula map. * @param h Height of nebula map. * @param file Path to save into. * @return 0 on success. */ static int saveNebula( float *map, const uint32_t w, const uint32_t h, const char* file ) { char file_path[PATH_MAX]; SDL_Surface* sur; int ret; /* fix surface */ sur = nebu_surfaceFromNebulaMap( map, w, h ); /* save */ nsnprintf(file_path, PATH_MAX, "%s"NEBULA_PATH"%s", nfile_cachePath(), file ); ret = SDL_SavePNG( sur, file_path ); /* cleanup */ SDL_FreeSurface( sur ); return ret; }
/** * @brief Sets the message for an omsg. */ static void omsg_setMsg( omsg_t *omsg, const char *msg ) { int i, l, n, s, m; glFont *font; /* Clean up after old stuff. */ if (omsg->msg != NULL) { for (i=0; i<omsg->nlines; i++) free( omsg->msg[i] ); free( omsg->msg ); omsg->msg = 0; omsg->nlines = 0; } /* Create data. */ l = strlen( msg ); font = omsg_getFont( omsg->font ); /* First pass size. */ n = 0; m = 0; while (n < l) { s = gl_printWidthForText( font, &msg[n], omsg_center_w ); n += s+1; m++; } /* Avoid zero-length malloc. */ if (m == 0) return; /* Second pass allocate. */ omsg->msg = malloc( m * sizeof(char*) ); omsg->nlines = m; n = 0; m = 0; while (n < l) { s = gl_printWidthForText( font, &msg[n], omsg_center_w ); omsg->msg[m] = malloc( s+1 ); nsnprintf( omsg->msg[m], s+1, "%s", &msg[n] ); m++; n += s+1; } }