naev 0.12.5
dev_system.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
10#include <stdlib.h> /* qsort */
11
12#include "naev.h"
14
15#include <libgen.h>
16
17#include "dev_system.h"
18
19#include "array.h"
20#include "conf.h"
21#include "nebula.h"
22#include "nxml.h"
23#include "space.h"
24
25/*
26 * Prototypes.
27 */
28static int dsys_compSpob( const void *spob1, const void *spob2 );
29static int dsys_compJump( const void *jmp1, const void *jmp2 );
30
38static int dsys_compSpob( const void *spob1, const void *spob2 )
39{
40 const Spob *p1, *p2;
41 p1 = *(const Spob **)spob1;
42 p2 = *(const Spob **)spob2;
43 return strcmp( p1->name, p2->name );
44}
45
53static int dsys_compVirtualSpob( const void *spob1, const void *spob2 )
54{
55 const VirtualSpob *va1, *va2;
56 va1 = *(const VirtualSpob **)spob1;
57 va2 = *(const VirtualSpob **)spob2;
58 return strcmp( va1->name, va2->name );
59}
60
68static int dsys_compJump( const void *jmp1, const void *jmp2 )
69{
70 const JumpPoint *jp1, *jp2;
71 jp1 = *(const JumpPoint **)jmp1;
72 jp2 = *(const JumpPoint **)jmp2;
73 return strcmp( jp1->target->name, jp2->target->name );
74}
75
82int dsys_saveSystem( StarSystem *sys )
83{
84 xmlDocPtr doc;
85 xmlTextWriterPtr writer;
86 const Spob **sorted_spobs;
87 const VirtualSpob **sorted_virtualspobs;
88 const JumpPoint **sorted_jumps;
89 char *file;
90 int ret = 0;
91
92 if ( conf.dev_data_dir == NULL ) {
93 WARN( _( "%s is not set!" ), "conf.dev_data_dir" );
94 return -1;
95 }
96
97 /* Reconstruct jumps so jump pos are updated. */
99
100 /* Create the writer. */
101 writer = xmlNewTextWriterDoc( &doc, 0 );
102 if ( writer == NULL ) {
103 WARN( _( "testXmlwriterDoc: Error creating the xml writer" ) );
104 return -1;
105 }
106
107 /* Set the writer parameters. */
108 xmlw_setParams( writer );
109
110 /* Start writer. */
111 xmlw_start( writer );
112 xmlw_startElem( writer, "ssys" );
113
114 /* Attributes. */
115 xmlw_attr( writer, "name", "%s", sys->name );
116
117 /* General. */
118 xmlw_startElem( writer, "general" );
119 if ( sys->background != NULL )
120 xmlw_elem( writer, "background", "%s", sys->background );
121 if ( sys->map_shader != NULL )
122 xmlw_elem( writer, "map_shader", "%s", sys->map_shader );
123 if ( sys->features != NULL )
124 xmlw_elem( writer, "features", "%s", sys->features );
125 xmlw_elem( writer, "radius", "%f", sys->radius );
126 xmlw_elem( writer, "spacedust", "%d", sys->spacedust );
127 xmlw_elem( writer, "interference", "%f", sys->interference );
128 if ( ( sys->nebu_density > 0. ) ||
129 ( sys_isFlag( sys, SYSTEM_NEBULATRAIL ) ) ) {
130 xmlw_startElem( writer, "nebula" );
131 if ( sys->nebu_volatility > 0. )
132 xmlw_attr( writer, "volatility", "%f", sys->nebu_volatility );
133 if ( fabs( sys->nebu_hue * 360.0 - NEBULA_DEFAULT_HUE ) > DOUBLE_TOL )
134 xmlw_attr( writer, "hue", "%f", sys->nebu_hue * 360.0 );
135 if ( ( sys->nebu_density <= 0. ) &&
136 sys_isFlag( sys, SYSTEM_NEBULATRAIL ) )
137 xmlw_attr( writer, "trails", "%d", 1 );
138 if ( sys_isFlag( sys, SYSTEM_HIDENEBULADAMAGE ) )
139 xmlw_attr( writer, "hidenebuladamage", "%d", 1 );
140 xmlw_str( writer, "%f", sys->nebu_density );
141 xmlw_endElem( writer ); /* "nebula" */
142 }
143 if ( sys_isFlag( sys, SYSTEM_NOLANES ) )
144 xmlw_elemEmpty( writer, "nolanes" );
145 xmlw_endElem( writer ); /* "general" */
146
147 /* Position. */
148 xmlw_startElem( writer, "pos" );
149 xmlw_attr( writer, "x", "%f", sys->pos.x );
150 xmlw_attr( writer, "y", "%f", sys->pos.y );
151 xmlw_endElem( writer ); /* "pos" */
152
153 /* Sort spobs. */
154 sorted_spobs = malloc( sizeof( Spob * ) * array_size( sys->spobs ) );
155 memcpy( sorted_spobs, sys->spobs,
156 sizeof( Spob * ) * array_size( sys->spobs ) );
157 qsort( sorted_spobs, array_size( sys->spobs ), sizeof( Spob * ),
159
160 /* Sort virtual spobs. */
161 sorted_virtualspobs =
162 malloc( sizeof( VirtualSpob * ) * array_size( sys->spobs_virtual ) );
163 memcpy( sorted_virtualspobs, sys->spobs_virtual,
164 sizeof( VirtualSpob * ) * array_size( sys->spobs_virtual ) );
165 qsort( sorted_virtualspobs, array_size( sys->spobs_virtual ),
166 sizeof( VirtualSpob * ), dsys_compVirtualSpob );
167
168 /* Write spobs and clean up. */
169 xmlw_startElem( writer, "spobs" );
170 for ( int i = 0; i < array_size( sys->spobs ); i++ )
171 xmlw_elem( writer, "spob", "%s", sorted_spobs[i]->name );
172 for ( int i = 0; i < array_size( sys->spobs_virtual ); i++ )
173 xmlw_elem( writer, "spob_virtual", "%s", sorted_virtualspobs[i]->name );
174 xmlw_endElem( writer ); /* "spobs" */
175 free( sorted_spobs );
176 free( sorted_virtualspobs );
177
178 /* Jumps. */
179 sorted_jumps = malloc( sizeof( JumpPoint * ) * array_size( sys->jumps ) );
180 for ( int i = 0; i < array_size( sys->jumps ); i++ )
181 sorted_jumps[i] = &sys->jumps[i];
182 qsort( sorted_jumps, array_size( sys->jumps ), sizeof( JumpPoint * ),
184 xmlw_startElem( writer, "jumps" );
185 for ( int i = 0; i < array_size( sys->jumps ); i++ ) {
186 const JumpPoint *jp = sorted_jumps[i];
187 xmlw_startElem( writer, "jump" );
188 xmlw_attr( writer, "target", "%s", jp->target->name );
189 /* Position. */
190 if ( !jp_isFlag( jp, JP_AUTOPOS ) ) {
191 xmlw_startElem( writer, "pos" );
192 xmlw_attr( writer, "x", "%f", jp->pos.x );
193 xmlw_attr( writer, "y", "%f", jp->pos.y );
194 xmlw_endElem( writer ); /* "pos" */
195 } else
196 xmlw_elemEmpty( writer, "autopos" );
197 /* Radius and misc properties. */
198 if ( jp->radius != 200. )
199 xmlw_elem( writer, "radius", "%f", jp->radius );
200 /* More flags. */
201 if ( jp_isFlag( jp, JP_HIDDEN ) )
202 xmlw_elemEmpty( writer, "hidden" );
203 if ( jp_isFlag( jp, JP_EXITONLY ) )
204 xmlw_elemEmpty( writer, "exitonly" );
205 if ( jp_isFlag( jp, JP_NOLANES ) )
206 xmlw_elemEmpty( writer, "nolanes" );
207 xmlw_elem( writer, "hide", "%f", jp->hide );
208 xmlw_endElem( writer ); /* "jump" */
209 }
210 xmlw_endElem( writer ); /* "jumps" */
211 free( sorted_jumps );
212
213 /* Asteroids. */
214 if ( array_size( sys->asteroids ) > 0 ||
215 array_size( sys->astexclude ) > 0 ) {
216 xmlw_startElem( writer, "asteroids" );
217 for ( int i = 0; i < array_size( sys->asteroids ); i++ ) {
218 const AsteroidAnchor *ast = &sys->asteroids[i];
219 xmlw_startElem( writer, "asteroid" );
220 if ( ast->label != NULL )
221 xmlw_attr_raw( writer, "label", ast->label );
222
223 /* Type Groups */
224 for ( int j = 0; j < array_size( ast->groups ); j++ )
225 xmlw_elem( writer, "group", "%s", ast->groups[j]->name );
226
227 /* Radius */
228 xmlw_elem( writer, "radius", "%f", ast->radius );
229
230 /* Position */
231 xmlw_startElem( writer, "pos" );
232 xmlw_attr( writer, "x", "%f", ast->pos.x );
233 xmlw_attr( writer, "y", "%f", ast->pos.y );
234 xmlw_endElem( writer ); /* "pos" */
235
236 /* Misc. properties. */
237 if ( ast->density != ASTEROID_DEFAULT_DENSITY )
238 xmlw_elem( writer, "density", "%f", ast->density );
239 if ( ast->maxspeed != ASTEROID_DEFAULT_MAXSPEED )
240 xmlw_elem( writer, "maxspeed", "%f", ast->maxspeed );
241 if ( ast->accel != ASTEROID_DEFAULT_ACCEL )
242 xmlw_elem( writer, "accel", "%f", ast->accel );
243 xmlw_endElem( writer ); /* "asteroid" */
244 }
245 for ( int i = 0; i < array_size( sys->astexclude ); i++ ) {
246 const AsteroidExclusion *aexcl = &sys->astexclude[i];
247 xmlw_startElem( writer, "exclusion" );
248 if ( aexcl->label != NULL )
249 xmlw_attr_raw( writer, "label", aexcl->label );
250
251 /* Radius */
252 xmlw_elem( writer, "radius", "%f", aexcl->radius );
253
254 /* Position */
255 xmlw_startElem( writer, "pos" );
256 xmlw_attr( writer, "x", "%f", aexcl->pos.x );
257 xmlw_attr( writer, "y", "%f", aexcl->pos.y );
258 xmlw_endElem( writer ); /* "pos" */
259 xmlw_endElem( writer ); /* "exclusion" */
260 }
261 xmlw_endElem( writer ); /* "asteroids" */
262 }
263
264 if ( sys->stats != NULL ) {
265 xmlw_startElem( writer, "stats" );
266 ss_listToXML( writer, sys->stats );
267 xmlw_endElem( writer ); /* "stats" */
268 }
269
270 if ( array_size( sys->tags ) > 0 ) {
271 xmlw_startElem( writer, "tags" );
272 for ( int i = 0; i < array_size( sys->tags ); i++ )
273 xmlw_elem( writer, "tag", "%s", sys->tags[i] );
274 xmlw_endElem( writer ); /* "tags" */
275 }
276
277 xmlw_endElem( writer );
278 xmlw_done( writer );
279
280 /* No need for writer anymore. */
281 xmlFreeTextWriter( writer );
282
283 /* Write data. */
284 char path[PATH_MAX];
285 snprintf( path, sizeof( path ), "%s", sys->filename );
286 const char *filename = basename( path );
287 SDL_asprintf( &file, "%s/ssys/%s", conf.dev_data_dir, filename );
288 if ( xmlSaveFileEnc( file, doc, "UTF-8" ) < 0 ) {
289 WARN( "Failed writing '%s'!", file );
290 ret = -1;
291 }
292
293 /* Clean up. */
294 xmlFreeDoc( doc );
295 free( file );
296
297 return ret;
298}
299
305int dsys_saveAll( void )
306{
307 StarSystem *sys = system_getAll();
308
309 /* Write systems. */
310 int ret = 0;
311 for ( int i = 0; i < array_size( sys ); i++ )
312 ret |= dsys_saveSystem( &sys[i] );
313
314 return ret;
315}
Provides macros to work with dynamic arrays.
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
Definition array.h:179
static int dsys_compVirtualSpob(const void *spob1, const void *spob2)
Compare function for spob qsort.
Definition dev_system.c:53
int dsys_saveSystem(StarSystem *sys)
Saves a star system.
Definition dev_system.c:82
int dsys_saveAll(void)
Saves all the star systems.
Definition dev_system.c:305
static int dsys_compSpob(const void *spob1, const void *spob2)
Compare function for spob qsort.
Definition dev_system.c:38
static int dsys_compJump(const void *jmp1, const void *jmp2)
Function for qsorting jumppoints.
Definition dev_system.c:68
Header file with generic functions and naev-specifics.
#define PATH_MAX
Definition naev.h:57
void xmlw_setParams(xmlTextWriterPtr writer)
Sets up the standard xml write parameters.
Definition nxml.c:59
int ss_listToXML(xmlTextWriterPtr writer, const ShipStatList *ll)
Creatse a shipstat list element from an xml node.
Definition shipstats.c:404
StarSystem * system_getAll(void)
Gets an array (array.h) of all star systems.
Definition space.c:925
void system_reconstructJumps(StarSystem *sys)
Reconstructs the jumps for a single system.
Definition space.c:2958
Represents an asteroid field anchor.
Definition asteroid.h:111
double radius
Definition asteroid.h:118
double density
Definition asteroid.h:115
double maxspeed
Definition asteroid.h:123
Asteroid * asteroids
Definition asteroid.h:116
AsteroidTypeGroup ** groups
Definition asteroid.h:120
Represents an asteroid exclusion zone.
Definition asteroid.h:136
Represents a Space Object (SPOB), including and not limited to planets, stations, wormholes,...
Definition space.h:102
char * name
Definition space.h:105
Basically modifies system parameters without creating any real objects.
Definition space.h:91
char * name
Definition space.h:92
double y
Definition vec2.h:47
double x
Definition vec2.h:46