1 #include "engine/declarations.h"
2
3 #include "declarations_app.h"
4 #include "elements.h"
5 #include "star.h"
6
7
8
star_create(struct galaxy * ga,unsigned long b)9 int star_create(struct galaxy *ga, unsigned long b) {
10 struct star *s;
11
12 if((ga->sa[b] = malloc(sizeof(struct star))) == NULL) {
13 LOGWARN(
14 ERROR_SLIGHT, SUBSYSTEM,
15 _("Failed to allocate %lu bytes of memory"),
16 (unsigned long) sizeof(struct star)
17 );
18
19 return(-1);
20 }
21
22 s = ga->sa[b];
23
24 s->id = b;
25 s->pd = ga->id;
26
27 s->planets = 0;
28 s->created = 0;
29 s->fusion = 0.0;
30 s->solarsize = 0.0;
31
32 (void) star_create_comp(s);
33 (void) star_create_spec(s);
34 (void) star_create_draw(s);
35
36 if(star_create_name(s) != 0) return(-1);
37 if(star_create_nick(s) != 0) return(-1);
38
39 s->pa = NULL;
40
41 s->solar = NULL;
42 s->solar_t = 0;
43
44 return(0);
45 }
46
star_create_neutron(struct galaxy * ga,unsigned long b)47 int star_create_neutron(struct galaxy *ga, unsigned long b) {
48 struct star *s;
49
50 if((ga->sa[b] = malloc(sizeof(struct star))) == NULL) {
51 LOGWARN(
52 ERROR_SLIGHT, SUBSYSTEM,
53 _("Failed to allocate %lu bytes of memory"),
54 (unsigned long) sizeof(struct star)
55 );
56
57 return(-1);
58 }
59
60 s = ga->sa[b];
61
62 s->id = b;
63 s->pd = ga->id;
64
65 s->planets = 0;
66 s->created = 0;
67 s->fusion = 0.0;
68 s->solarsize = 0.0;
69
70 (void) star_create_comp_neutron(s);
71 (void) star_create_spec_neutron(s);
72 (void) star_create_draw(s);
73
74 if(star_create_name(s) != 0) return(-1);
75 if(star_create_nick(s) != 0) return(-1);
76
77 s->pa = NULL;
78
79 s->solar = NULL;
80 s->solar_t = 0;
81
82 return(0);
83 }
84
star_create_blackhole(struct galaxy * ga,unsigned long b)85 int star_create_blackhole(struct galaxy *ga, unsigned long b) {
86 struct star *s;
87
88 if((ga->sa[b] = malloc(sizeof(struct star))) == NULL) {
89 LOGWARN(
90 ERROR_SLIGHT, SUBSYSTEM,
91 _("Failed to allocate %lu bytes of memory"),
92 (unsigned long) sizeof(struct star)
93 );
94
95 return(-1);
96 }
97
98 s = ga->sa[b];
99
100 s->id = b;
101 s->pd = ga->id;
102
103 s->planets = 0;
104 s->created = 0;
105 s->fusion = 0.0;
106 s->solarsize = 0.0;
107
108 (void) star_create_comp_blackhole(s);
109 (void) star_create_spec_blackhole(s);
110 (void) star_create_draw(s);
111
112 if(star_create_name(s) != 0) return(-1);
113 if(star_create_nick(s) != 0) return(-1);
114
115 s->pa = NULL;
116
117 s->solar = NULL;
118 s->solar_t = 0;
119
120 return(0);
121 }
122
star_create_comp(struct star * sa)123 static void star_create_comp(struct star *sa) {
124 /* Largest percentage of total mass -order */
125 struct star_cont sc[] = {
126 { STAR_COMP_HELIUM_MIN, STAR_COMP_HELIUM_MAX, &sa->sc.helium },
127 { STAR_COMP_OXYGEN_MIN, STAR_COMP_OXYGEN_MAX, &sa->sc.oxygen },
128 { STAR_COMP_CARBON_MIN, STAR_COMP_CARBON_MAX, &sa->sc.carbon },
129 { STAR_COMP_NITROGEN_MIN, STAR_COMP_NITROGEN_MAX, &sa->sc.nitrogen },
130 { STAR_COMP_SILICON_MIN, STAR_COMP_SILICON_MAX, &sa->sc.silicon },
131 { STAR_COMP_MAGNESIUM_MIN, STAR_COMP_MAGNESIUM_MAX, &sa->sc.magnesium },
132 { STAR_COMP_NEON_MIN, STAR_COMP_NEON_MAX, &sa->sc.neon },
133 { STAR_COMP_IRON_MIN, STAR_COMP_IRON_MAX, &sa->sc.iron },
134 { STAR_COMP_SULFUR_MIN, STAR_COMP_SULFUR_MAX, &sa->sc.sulfur },
135
136 { 0, 0, NULL }
137 };
138
139 sa->sc.hydrogen = 100.0 - star_create_comp_op(sc);
140 }
141
star_create_comp_neutron(struct star * sa)142 static void star_create_comp_neutron(struct star *sa) {
143 /* Content of neutron star is solid iron here, as nobody knows for sure */
144 sa->sc.carbon = 0.0;
145 sa->sc.helium = 0.0;
146 sa->sc.hydrogen = 0.0;
147 sa->sc.iron = 100.0;
148 sa->sc.magnesium = 0.0;
149 sa->sc.neon = 0.0;
150 sa->sc.nitrogen = 0.0;
151 sa->sc.oxygen = 0.0;
152 sa->sc.silicon = 0.0;
153 sa->sc.sulfur = 0.0;
154 }
155
star_create_comp_blackhole(struct star * sa)156 static void star_create_comp_blackhole(struct star *sa) {
157 /* Content of black hole is not known, they say that it does not contain any kind of information */
158 sa->sc.carbon = 0.0;
159 sa->sc.helium = 0.0;
160 sa->sc.hydrogen = 0.0;
161 sa->sc.iron = 0.0;
162 sa->sc.magnesium = 0.0;
163 sa->sc.neon = 0.0;
164 sa->sc.nitrogen = 0.0;
165 sa->sc.oxygen = 0.0;
166 sa->sc.silicon = 0.0;
167 sa->sc.sulfur = 0.0;
168 }
169
star_create_comp_op(struct star_cont * s)170 static float star_create_comp_op(struct star_cont *s) {
171 unsigned int i, t;
172 float c, d;
173
174 c = 0.0;
175
176 for(i = 0; ; i++) {
177 if(s[i].c == NULL) break;
178
179 t = s[i].b - s[i].a;
180 t = maths_rand(t) + s[i].a;
181
182 d = (((float) t / 100000.0) / 100.0) * (100.0 - c);
183
184 *s[i].c = d;
185
186 c += d;
187 }
188
189 return(c);
190 }
191
star_create_spec(struct star * sa)192 static void star_create_spec(struct star *sa) {
193 sa->ss.bm = (double) maths_rand(140 - -5); /* Star mean Bt magnitude (-0.5 - 14.0) */
194 sa->ss.bm = (sa->ss.bm + -5.0) / 100.0;
195
196 sa->ss.vm = (double) maths_rand(140 - -5); /* Star mean Vt magnitude (-0.5 - 14.0) */
197 sa->ss.vm = (sa->ss.vm + -5.0) / 100.0;
198
199 sa->ss.jm = (double) maths_rand(140 - -14); /* Star magnitude in Johnson V (-1.44 - 14.0) */
200 sa->ss.jm = (sa->ss.jm + -14.0) / 100.0;
201
202 sa->ss.bv = (double) maths_rand(2400 - -315); /* Star BtVt index (-0.315 - 2.4) (sa->ss.bm - sa->ss.vm) */
203 sa->ss.bv = maths_btvt_to_bv((sa->ss.bv + -315.0) / 1000.0);
204
205 sa->ss.parallax = (double) maths_rand(7720 - 1); /* Star trigonometric parallax (0.1 - 772.0) */
206 sa->ss.parallax = (sa->ss.parallax + 10.0) / 100.0;
207
208 sa->ss.magnitude = maths_amag_by_vmag_distance(sa->ss.jm, maths_parsec_by_parallax(sa->ss.parallax));
209 sa->ss.temperature = maths_bv_to_temperature(sa->ss.bv);
210 sa->ss.radius = maths_radius_by_amag_temperature(sa->ss.magnitude, sa->ss.temperature) / 1000.0;
211 sa->ss.luminance = maths_luminance_by_radius_temperature(sa->ss.radius, sa->ss.temperature) * 1000000.0;
212
213 sa->ss.mass = (double) (sa->ss.radius / STAR_SUN_RADIUS_KM) * STAR_SUN_MASS_KG;
214 sa->ss.area = (double) (sa->ss.radius * sa->ss.radius) * CONST_PI_4;
215 sa->ss.volume = (double) (sa->ss.radius * sa->ss.radius * sa->ss.radius) * CONST_VOLUME_SP;
216
217 (void) star_create_spec_spectral(sa, sa->ss.bv);
218 (void) star_create_spec_type(sa, sa->ss.magnitude, sa->ss.temperature);
219 (void) star_create_spec_flat(sa);
220
221 /* Energy is calculated what core produces (10%), hence 0.1 */
222 sa->ss.energy = (double) 0.007 * 0.1 * sa->ss.mass * (STAR_SOL * STAR_SOL);
223
224 sa->ss.lifetime = sa->ss.energy / sa->ss.luminance;
225 sa->ss.lifetime *= 1.0 / CONST_SECS_YEAR; /* Convert seconds to years */
226 sa->ss.lifetime /= 1000000.0; /* Convert years to millions */
227
228 sa->ss.centripetal = (sa->ss.rotation * sa->ss.rotation) / (sa->ss.radius * 1000.0);
229
230 sa->ss.acceleration = (sa->ss.mass * CONST_GRAVITY) / ((sa->ss.radius * 1000.0) * (sa->ss.radius * 1000.0));
231 sa->ss.acceleration -= sa->ss.centripetal;
232
233 sa->ss.velocity = sqrtf((float) (CONST_GRAVITY_2 * (sa->ss.mass / 1000.0)) / sa->ss.radius);
234 sa->ss.velocity /= 1000.0; /* Convert to meters */
235
236 (void) color_bv_to_rgba(&sa->ss.rgb, sa->ss.bv, sa->ss.vm);
237 }
238
star_create_spec_spectral(struct star * sa,double b)239 static void star_create_spec_spectral(struct star *sa, double b) {
240 unsigned int i;
241 double d;
242 char *r;
243
244 d = 9999.0;
245 r = " ";
246
247 for(i = 0; ; i++) {
248 if(star_spectral[i].s == NULL) break;
249 if(fabs(b - star_spectral[i].c) < d) {
250 d = fabs(b - star_spectral[i].c);
251 r = star_spectral[i].s;
252 }
253 }
254
255 (void) memcpy((void *) sa->spectral, (const void *) r, sizeof(sa->spectral));
256 }
257
star_create_spec_type(struct star * sa,double a,double k)258 static void star_create_spec_type(struct star *sa, double a, double k) {
259 /* Generate star class */
260 if(k > 33000.0) sa->class = STAR_CLASS_O;
261 else if(k > 10000.0) sa->class = STAR_CLASS_B;
262 else if(k > 7500.0) sa->class = STAR_CLASS_A;
263 else if(k > 6000.0) sa->class = STAR_CLASS_F;
264 else if(k > 5200.0) sa->class = STAR_CLASS_G;
265 else if(k > 3700.0) sa->class = STAR_CLASS_K;
266 else if(k > 2400.0) sa->class = STAR_CLASS_M;
267 else if(k > 1300.0) sa->class = STAR_CLASS_L;
268 else if(k > 500.0) sa->class = STAR_CLASS_T;
269 else sa->class = STAR_CLASS_Y;
270
271 /* Generate star type */
272 if(a > 15.0) sa->type = STAR_TYPE_DWARF_BROWN;
273 else if(a > 10.0) sa->type = STAR_TYPE_DWARF_RED;
274 else if(a > 5.0) sa->type = STAR_TYPE_DWARF_WHITE;
275 else if(a > 0.0) sa->type = STAR_TYPE_GIANT_SUB;
276 else if(a > -5.0) sa->type = STAR_TYPE_GIANT;
277 else if(a > -10.0) sa->type = STAR_TYPE_GIANT_SUPER;
278 else sa->type = STAR_TYPE_GIANT_HYPER;
279 }
280
star_create_spec_flat(struct star * sa)281 static void star_create_spec_flat(struct star *sa) {
282 unsigned int a, b;
283 double c, r;
284
285 /* Rotation speed has 20% tolerance, hence / 5 */
286 a = star_flat[sa->class] - (star_flat[sa->class] / 5);
287 b = star_flat[sa->class] + (star_flat[sa->class] / 5);
288
289 a *= 36000;
290 b *= 36000;
291
292 sa->ss.rotation = (double) (maths_rand(b - a) + a) / 1000.0;
293
294 r = sa->ss.radius * 1000.0; /* Convert radius to meters */
295 c = sa->ss.rotation / r; /* Star angular velocity */
296
297 sa->ss.flattening = 1.25 * (((c * c) * (r * r * r)) / (CONST_GRAVITY * sa->ss.mass));
298
299 sa->ss.radius_e = sa->ss.radius * (1.0 + 2.0 * sa->ss.flattening / 3.0);
300 sa->ss.radius_p = sa->ss.radius * (1.0 - 2.0 * sa->ss.flattening / 3.0);
301 }
302
star_create_spec_neutron(struct star * sa)303 static void star_create_spec_neutron(struct star *sa) {
304 double d;
305
306 sa->ss.bm = 0.0;
307 sa->ss.vm = 0.0;
308 sa->ss.jm = 0.0;
309 sa->ss.bv = 0.0;
310
311 sa->ss.parallax = 0.0;
312
313 /* Neutron star mass is from 1 to 5 times of the sun */
314 d = (double) (maths_rand(4000000) + 1000000);
315 d /= 1000000.0;
316
317 sa->ss.mass = d * STAR_SUN_MASS_KG;
318
319 /* Neutron star radius is from 10 to 30 kilometers */
320 d = (double) (maths_rand(20000000) + 10000000);
321 d /= 1000000.0;
322
323 sa->ss.radius = d;
324
325 sa->ss.area = (double) (sa->ss.radius * sa->ss.radius) * CONST_PI_4;
326 sa->ss.volume = (double) (sa->ss.radius * sa->ss.radius * sa->ss.radius) * CONST_VOLUME_SP;
327
328 sa->ss.magnitude = (double) (maths_rand(20000) + 20000);
329 sa->ss.magnitude /= 1000.0;
330
331 sa->ss.temperature = (double) maths_rand(1000000) + 100000.0;
332 sa->ss.luminance = maths_luminance_by_radius_temperature(sa->ss.radius, sa->ss.temperature) * 1000000.0;
333
334 (void) star_create_spec_neutron_type(sa);
335 (void) star_create_spec_flat(sa);
336
337 sa->ss.energy = (double) 0.007 * sa->ss.mass * (STAR_SOL * STAR_SOL);
338
339 sa->ss.lifetime = sa->ss.energy / sa->ss.luminance;
340 sa->ss.lifetime *= 1.0 / CONST_SECS_YEAR; /* Convert seconds to years */
341 sa->ss.lifetime /= 1000000.0; /* Convert years to millions */
342
343 sa->ss.centripetal = (sa->ss.rotation * sa->ss.rotation) / (sa->ss.radius * 1000.0);
344
345 sa->ss.acceleration = (sa->ss.mass * CONST_GRAVITY) / ((sa->ss.radius * 1000.0) * (sa->ss.radius * 1000.0));
346 sa->ss.acceleration -= sa->ss.centripetal;
347
348 sa->ss.velocity = sqrtf((float) (CONST_GRAVITY_2 * (sa->ss.mass / 1000.0)) / sa->ss.radius);
349 sa->ss.velocity /= 1000.0; /* Convert to meters */
350
351 sa->ss.rgb.pixel.r = 255;
352 sa->ss.rgb.pixel.g = 255;
353 sa->ss.rgb.pixel.b = 255;
354 sa->ss.rgb.pixel.a = 255;
355 }
356
star_create_spec_neutron_type(struct star * sa)357 static void star_create_spec_neutron_type(struct star *sa) {
358 unsigned int k;
359
360 k = maths_rand(100);
361
362 /* This neutron star is possibly pulsar or magnetar (25% chance out of 100 for each) */
363 if(k < 25) sa->class = STAR_CLASS_NEUTRON_PULSAR;
364 else if(k < 50) sa->class = STAR_CLASS_NEUTRON_MAGNETAR;
365 else sa->class = STAR_CLASS_NEUTRON_NEUTRON;
366
367 sa->type = STAR_TYPE_NEUTRON;
368 }
369
star_create_spec_blackhole(struct star * sa)370 static void star_create_spec_blackhole(struct star *sa) {
371 double d;
372
373 sa->ss.bm = 0.0;
374 sa->ss.vm = 0.0;
375 sa->ss.jm = 0.0;
376 sa->ss.bv = 0.0;
377
378 sa->ss.parallax = 0.0;
379
380 d = (double) (maths_rand(1000000) + 1);
381 d /= (double) (maths_rand(10) + 1);
382
383 sa->ss.mass = d * STAR_SUN_MASS_KG;
384
385 sa->ss.radius = (double) ((2.0 * CONST_GRAVITY) * sa->ss.mass) / (STAR_SOL * STAR_SOL);
386 sa->ss.radius /= 1000.0; /* Convert to kilometers */
387
388 sa->ss.radius_e = sa->ss.radius;
389 sa->ss.radius_p = sa->ss.radius;
390
391 sa->ss.area = (double) (sa->ss.radius * sa->ss.radius) * CONST_PI_4;
392 sa->ss.volume = (double) (sa->ss.radius * sa->ss.radius * sa->ss.radius) * CONST_VOLUME_SP;
393
394 sa->ss.acceleration = (float) 1.0 / sa->ss.mass;
395 sa->ss.acceleration *= STAR_SOL * STAR_SOL * STAR_SOL * STAR_SOL;
396 sa->ss.acceleration /= 4.0 * CONST_GRAVITY;
397
398 sa->ss.velocity = sqrtf((float) (CONST_GRAVITY_2 * (sa->ss.mass / 1000.0)) / sa->ss.radius);
399 sa->ss.velocity /= 1000.0; /* Convert to meters */
400
401 sa->ss.temperature = (double) 1.0 / sa->ss.mass;
402 sa->ss.temperature *= CONST_HBAR * (STAR_SOL * STAR_SOL * STAR_SOL);
403 sa->ss.temperature /= 8.0 * CONST_KBAR * CONST_PI * CONST_GRAVITY;
404
405 sa->ss.luminance = (double) 1.0 / (sa->ss.mass * sa->ss.mass);
406 sa->ss.luminance *= CONST_HBAR * (STAR_SOL * STAR_SOL * STAR_SOL * STAR_SOL * STAR_SOL * STAR_SOL);
407 sa->ss.luminance /= 15360.0 * CONST_PI * (CONST_GRAVITY * CONST_GRAVITY);
408
409 sa->ss.lifetime = (double) (sa->ss.mass * sa->ss.mass * sa->ss.mass);
410 sa->ss.lifetime *= 5120 * CONST_PI * (CONST_GRAVITY * CONST_GRAVITY);
411 sa->ss.lifetime /= CONST_HBAR * (STAR_SOL * STAR_SOL * STAR_SOL * STAR_SOL);
412
413 sa->ss.magnitude = (double) 1e9;
414
415 sa->ss.energy = (double) 0.007 * sa->ss.mass * (STAR_SOL * STAR_SOL);
416
417 sa->ss.rotation = 0.0;
418 sa->ss.flattening = 0.0;
419
420 sa->ss.centripetal = 0.0;
421
422 (void) star_create_spec_blackhole_type(sa, sa->ss.mass);
423
424 sa->ss.rgb.pixel.r = STAR_DRAW_LIGHT_BLACKHOLE_RED;
425 sa->ss.rgb.pixel.g = STAR_DRAW_LIGHT_BLACKHOLE_GREEN;
426 sa->ss.rgb.pixel.b = STAR_DRAW_LIGHT_BLACKHOLE_BLUE;
427 sa->ss.rgb.pixel.a = 255;
428 }
429
star_create_spec_blackhole_type(struct star * sa,double k)430 static void star_create_spec_blackhole_type(struct star *sa, double k) {
431 double d;
432
433 d = k / STAR_SUN_MASS_KG;
434
435 if(d > 100000.0) sa->class = STAR_CLASS_BLACKHOLE_SUPERMASSIVE;
436 else if(d > 5000.0) sa->class = STAR_CLASS_BLACKHOLE_INTERMEDIATE;
437 else if(d > 20.0) sa->class = STAR_CLASS_BLACKHOLE_STELLAR;
438 else sa->class = STAR_CLASS_BLACKHOLE_MICRO;
439
440 sa->type = STAR_TYPE_BLACKHOLE;
441 }
442
star_create_draw(struct star * sa)443 static void star_create_draw(struct star *sa) {
444 sa->sd.p_w = STAR_DRAW_PREVIEW_WIDTH;
445 sa->sd.p_h = STAR_DRAW_PREVIEW_HEIGHT;
446
447 sa->sd.c = maths_rand(STAR_DRAW_NOISE_SEED);
448
449 sa->sd.ca = 0;
450
451 sa->sd.p_t = 0;
452 sa->sd.p_p = NULL;
453
454 sa->sd.cc_p = NULL;
455 sa->sd.cp_p = NULL;
456
457 (void) memset((void *) &sa->sd.cp, 0, sizeof(sa->sd.cp));
458 (void) memset((void *) &sa->sd.cp_f, 0, sizeof(sa->sd.cp_f));
459
460 (void) memset((void *) &sa->sd.cc_s, 0, sizeof(sa->sd.cc_s));
461 (void) memset((void *) &sa->sd.cp_s, 0, sizeof(sa->sd.cp_s));
462 }
463
star_create_name(struct star * sa)464 static int star_create_name(struct star *sa) {
465 char n[STAR_NAME_LEN_MAX];
466
467 /* Generate star name (PARENT_ID-STAR_ID-CLASS-TYPE) */
468 (void) snprintf(n, sizeof(n), "%s-%lu-%lu-%u-%u", star_name_p, sa->pd, sa->id, sa->class, sa->type);
469
470 sa->name_t = strnlen(n, sizeof(n) - sizeof(char));
471
472 if((sa->name = malloc((size_t) sa->name_t + (sizeof(char) * 4))) == NULL) {
473 LOGWARN(
474 ERROR_SLIGHT, SUBSYSTEM,
475 _("Failed to allocate %lu bytes of memory"),
476 (unsigned long) (sa->name_t + sizeof(char))
477 );
478
479 return(-1);
480 }
481
482 (void) memcpy((void *) sa->name, (const void *) n, sa->name_t);
483
484 sa->name[sa->name_t] = 0;
485 sa->name[sa->name_t + 1] = 0;
486 sa->name[sa->name_t + 2] = 0;
487 sa->name[sa->name_t + 3] = 0;
488
489 return(0);
490 }
491
star_create_nick(struct star * sa)492 static int star_create_nick(struct star *sa) {
493 sa->nick = NULL;
494 sa->nick_t = 0;
495
496 return(0);
497 }
498
star_create_solar(struct galaxy * ga,unsigned long b)499 int star_create_solar(struct galaxy *ga, unsigned long b) {
500 char *e, *f;
501
502 char n[STAR_NAME_LEN_MAX];
503
504 struct star *s;
505
506 s = ga->sa[b];
507
508 /* Generate solar system name (ID-PARENT_ID-STAR_ID-COUNTER) */
509 e = star_solar_name_a[maths_rand(STAR_SOLAR_NAME_A)];
510 f = star_solar_name_a[maths_rand(STAR_SOLAR_NAME_A)];
511
512 (void) snprintf(n, sizeof(n), _("%s%s-%lu-%lu-%lu system"), e, f, s->pd, s->id, ga->solars++);
513
514 n[0] = (char) toupper((int) n[0]);
515 n[1] = (char) toupper((int) n[1]);
516
517 s->solar_t = strnlen(n, sizeof(n) - sizeof(char));
518
519 if((s->solar = malloc((size_t) s->solar_t + (sizeof(char) * 4))) == NULL) {
520 LOGWARN(
521 ERROR_SLIGHT, SUBSYSTEM,
522 _("Failed to allocate %lu bytes of memory"),
523 (unsigned long) (s->solar_t + sizeof(char))
524 );
525
526 return(-1);
527 }
528
529 (void) memcpy((void *) s->solar, (const void *) n, s->solar_t);
530
531 s->solar[s->solar_t] = 0;
532 s->solar[s->solar_t + 1] = 0;
533 s->solar[s->solar_t + 2] = 0;
534 s->solar[s->solar_t + 3] = 0;
535
536 return(0);
537 }
538
star_create_spot(struct galaxy * ga,unsigned long b)539 void star_create_spot(struct galaxy *ga, unsigned long b) {
540 double i, d, e, g, u, v, x, y, z;
541
542 struct star *s;
543
544 s = ga->sa[b];
545
546 /* Gaussian curve is from 0.0 to 0.4 */
547 d = -5.0;
548 e = -(d) / (double) ga->stars;
549
550 d += e * (double) b;
551
552 g = maths_gaussian_dens(d);
553
554 /* Which galaxy arm we are on (z = 2 * pi = whole round) */
555 z = (CONST_PI * 2.0) / (double) ga->gs.arms;
556 z *= b % ga->gs.arms;
557
558 i = ga->gs.steps * (double) b;
559
560 /* Randomness increases a bit towards the galaxy arm tail */
561 u = maths_gaussian_rand(g, ga->gs.sigma) * ga->gs.dispersion * (i + 1.0);
562 v = maths_gaussian_rand(g, ga->gs.sigma) * ga->gs.dispersion * (i + 1.0);
563
564 x = (sin(i + z) * i) * ga->gs.radius;
565 y = (sin(i + z + (CONST_PI / 2.0))) * (i + (CONST_PI / 2.0)) * ga->gs.radius;
566
567 switch(b % 4) {
568 case 0:
569 x -= u;
570 y += v;
571
572 break;
573 case 1:
574 x -= u;
575 y -= v;
576
577 break;
578 case 2:
579 x += u;
580 y -= v;
581
582 break;
583 default:
584 x += u;
585 y += v;
586
587 break;
588 }
589
590 s->sp.x = x * CONST_LY_KM;
591 s->sp.y = y * CONST_LY_KM;
592 s->sp.z = 0.0;
593
594 /* Update galaxy dimensions */
595 if(s->sp.x < ga->gd_a.x) ga->gd_a.x = s->sp.x;
596 if(s->sp.y < ga->gd_a.y) ga->gd_a.y = s->sp.y;
597 if(s->sp.z < ga->gd_a.z) ga->gd_a.z = s->sp.z;
598
599 if(s->sp.x > ga->gd_b.x) ga->gd_b.x = s->sp.x;
600 if(s->sp.y > ga->gd_b.y) ga->gd_b.y = s->sp.y;
601 if(s->sp.z > ga->gd_b.z) ga->gd_b.z = s->sp.z;
602
603 /* Initial velocity of star makes galaxy to swirl */
604 d = 1.0 + (maths_rand(10) / 10.0);
605 e = (double) (1.0 / (maths_rand(10) + 1));
606
607 x = (s->sp.x * cos(d) - s->sp.y * sin(d)) / (CONST_LY_KM / 2.0 * e);
608 y = (s->sp.x * sin(d) + s->sp.y * cos(d)) / (CONST_LY_KM / 2.0 * e);
609
610 s->sv.x = x;
611 s->sv.y = y;
612 s->sv.z = 0.0;
613 }
614
star_create_spot_blackhole(struct galaxy * ga,unsigned long b)615 void star_create_spot_blackhole(struct galaxy *ga, unsigned long b) {
616 struct star *s;
617
618 s = ga->sa[b];
619
620 /* Black hole sits at the center of the galaxy */
621 s->sp.x = 0.0;
622 s->sp.y = 0.0;
623 s->sp.z = 0.0;
624
625 s->sv.x = 0.0;
626 s->sv.y = 0.0;
627 s->sv.z = 0.0;
628 }
629
star_free(struct star * sa)630 void star_free(struct star *sa) {
631 unsigned long i;
632
633 if(sa != NULL) {
634 (void) star_live_free(sa);
635 (void) star_preview_free(sa);
636
637 if(sa->name != NULL) (void) free(sa->name);
638 if(sa->nick != NULL) (void) free(sa->nick);
639 if(sa->solar != NULL) (void) free(sa->solar);
640
641 for(i = 0; i < sa->created; i++) (void) planet_free(sa->pa[i]);
642
643 (void) free(sa);
644 }
645 }
646
star_image(struct star * sa,char * d,int m)647 void star_image(struct star *sa, char *d, int m) {
648 char *s;
649
650 char n[CONFIG_LINE_LENGTH];
651
652 size_t t;
653
654 t = CONFIG_PATH_LENGTH;
655
656 if((s = malloc(t + sizeof(char))) == NULL) {
657 LOGWARN(
658 ERROR_SLIGHT, SUBSYSTEM,
659 _("Failed to allocate %lu bytes of memory"),
660 (unsigned long) (t + sizeof(char))
661 );
662
663 return;
664 }
665
666 if(sa->nick != NULL) {
667 (void) snprintf(
668 s, t,
669 "%s%cstar_%s_%s.%s",
670 d, CONFIG_PATH_DELIM, sa->name, sa->nick, (char *) image_get_suffix_by_type(m)
671 );
672 }
673 else {
674 (void) snprintf(
675 s, t,
676 "%s%cstar_%s.%s",
677 d, CONFIG_PATH_DELIM, sa->name, (char *) image_get_suffix_by_type(m)
678 );
679 }
680
681 if(star_preview_create(sa, sa->sd.p_w, sa->sd.p_h, 1.5) != 0) {
682 (void) free(s);
683
684 return;
685 }
686
687 (void) image_write_32(sa->sd.p_p, (unsigned int) sa->sd.p_w, (unsigned int) sa->sd.p_h, s, m);
688
689 (void) snprintf(
690 n, sizeof(n),
691 "Star image saved to %s",
692 s);
693
694 (void) universe_set_message(n);
695
696 (void) free(s);
697 }
698
star_preview(struct star * sa,unsigned int h,int x,int y)699 void star_preview(struct star *sa, unsigned int h, int x, int y) {
700 if(star_preview_create(sa, sa->sd.p_w, sa->sd.p_h, 1.5) != 0) return;
701
702 sa->sd.cp.sx = 0;
703 sa->sd.cp.sy = 0;
704 sa->sd.cp.dx = x;
705 sa->sd.cp.dy = y;
706 sa->sd.cp.c.width = (unsigned int) sa->sd.p_w;
707 sa->sd.cp.c.height = (unsigned int) sa->sd.p_h;
708 sa->sd.cp.s.width = (unsigned int) sa->sd.p_w;
709 sa->sd.cp.s.height = (unsigned int) sa->sd.p_h;
710 sa->sd.cp.p = sa->sd.p_p;
711
712 (void) gui_draw_copy_alpha(h, &sa->sd.cp);
713 }
714
star_preview_create(struct star * sa,int w,int h,double u)715 static int star_preview_create(struct star *sa, int w, int h, double u) {
716 double d;
717
718 struct position g;
719 struct pixel_rgb_8 s;
720 struct pixel_rgba_8 a;
721
722 if(sa->sd.p_p != NULL) return(0);
723 if(star_preview_create_op(sa, w, h) != 0) return(-1);
724
725 /* Calculate percentage difference of equatorial and polar radius */
726 d = fabs(sa->ss.radius_e - sa->ss.radius_p);
727 d /= fabs(sa->ss.radius_e + sa->ss.radius_p) / 2.0;
728 d *= 100.0;
729
730 if((sa->sd.ca = draw_sphere_matte_noise_2d_cache(w, h, u, 100.0, 100.0 - d, sa->sd.c, 0.15)) == 0) {
731 (void) star_preview_free(sa);
732
733 return(-1);
734 }
735
736 g.x = STAR_DRAW_LIGHT_X;
737 g.y = STAR_DRAW_LIGHT_Y;
738 g.z = STAR_DRAW_LIGHT_Z;
739
740 a.pixel.p = sa->ss.rgb.pixel.p;
741
742 switch(sa->type) {
743 case STAR_TYPE_BLACKHOLE:
744 s.r = STAR_DRAW_LIGHT_BLACKHOLE_RED;
745 s.g = STAR_DRAW_LIGHT_BLACKHOLE_GREEN;
746 s.b = STAR_DRAW_LIGHT_BLACKHOLE_BLUE;
747
748 break;
749 case STAR_TYPE_NEUTRON:
750 s.r = STAR_DRAW_LIGHT_NEUTRON_RED;
751 s.g = STAR_DRAW_LIGHT_NEUTRON_GREEN;
752 s.b = STAR_DRAW_LIGHT_NEUTRON_BLUE;
753
754 break;
755 default:
756 s.r = STAR_DRAW_LIGHT_DEFAULT_RED;
757 s.g = STAR_DRAW_LIGHT_DEFAULT_GREEN;
758 s.b = STAR_DRAW_LIGHT_DEFAULT_BLUE;
759
760 break;
761 }
762
763 (void) draw_sphere_blur(sa->sd.p_p, &a, &s, &g, 0.5, 2.0, sa->sd.ca);
764
765 return(0);
766 }
767
star_preview_create_op(struct star * sa,int w,int h)768 static int star_preview_create_op(struct star *sa, int w, int h) {
769 sa->sd.p_t = (w * h) * sizeof(struct pixel_rgba_8);
770
771 if((sa->sd.p_p = malloc(sa->sd.p_t)) == NULL) {
772 LOGWARN(
773 ERROR_SLIGHT, SUBSYSTEM,
774 _("Failed to allocate %lu bytes of memory"),
775 (unsigned long) sa->sd.p_t
776 );
777
778 return(-1);
779 }
780
781 (void) memset((void *) sa->sd.p_p, 0, sa->sd.p_t);
782
783 return(0);
784 }
785
star_preview_free(struct star * sa)786 void star_preview_free(struct star *sa) {
787 if(sa->sd.p_p != NULL) {
788 (void) free(sa->sd.p_p);
789
790 sa->sd.p_t = 0;
791 sa->sd.p_p = NULL;
792 }
793
794 if(sa->sd.ca != 0) {
795 (void) draw_sphere_cache_delete(sa->sd.ca);
796
797 sa->sd.ca = 0;
798 }
799 }
800
star_run(struct star * sa)801 void star_run(struct star *sa) {
802 unsigned long i;
803 double d;
804
805 struct planet *p;
806
807 /* Calculate position for orbiting planets */
808 for(i = 0; i < sa->planets; i++) {
809 p = sa->pa[i];
810 d = CONST_PI_2 * p->distance;
811
812 /* One iteration to position is one second as speed is orbital velocity in km/s */
813 p->position += p->ps.speed * clock_get_multiplier();
814
815 if(p->position > d) p->position -= d;
816
817 p->angle = maths_map(p->position, 0.0, d, 0.0, 360.0);
818 }
819
820 /* Simulate nuclear fusion */
821 (void) star_run_burn(sa);
822 }
823
star_run_burn(struct star * sa)824 static void star_run_burn(struct star *sa) {
825 double d, e;
826
827 char n[CONFIG_LINE_LENGTH];
828
829 if(sa->type == STAR_TYPE_NEUTRON || sa->type == STAR_TYPE_BLACKHOLE) return;
830
831 e = clock_get_ticks();
832
833 /* Simulate nuclear fusion only once per stretching year */
834 if(e - sa->fusion < CONST_SECS_YEAR) return;
835
836 sa->fusion = e;
837
838 /* Once the core is completely helium, star is gone for good */
839 if(sa->sc.hydrogen > 0.0) {
840 d = sa->sc.hydrogen / sa->ss.lifetime;
841
842 sa->sc.hydrogen -= d;
843 sa->sc.helium += d;
844 }
845
846 d = 0.000001;
847
848 /* If nuclear fusion has ended, convert star to neutron star or black hole */
849 if((sa->ss.lifetime -= d) < d) {
850 sa->planets = 0;
851 sa->solarsize = 0.0;
852
853 (void) star_preview_free(sa);
854
855 /* Mass is calculated what core weights (10%), hence 0.1 */
856 if(sa->ss.mass * 0.1 < STAR_SUN_MASS_KG * 3.0) {
857 (void) snprintf(
858 n, sizeof(n),
859 "%s %s collapsed to neutron star%c%c%c%c",
860 star_type[sa->type], sa->name, 0, 0, 0, 0);
861
862 (void) star_create_comp_neutron(sa);
863 (void) star_create_spec_neutron(sa);
864 }
865 else {
866 (void) snprintf(
867 n, sizeof(n),
868 "%s %s collapsed to black hole%c%c%c%c",
869 star_type[sa->type], sa->name, 0, 0, 0, 0);
870
871 (void) star_create_comp_blackhole(sa);
872 (void) star_create_spec_blackhole(sa);
873 }
874
875 (void) universe_set_message(n);
876 }
877 }
878
star_live(unsigned long a,unsigned long b,double u,double v,double s,unsigned int h)879 void star_live(unsigned long a, unsigned long b, double u, double v, double s, unsigned int h) {
880 unsigned int x, y, w;
881 unsigned long i;
882 double e, z;
883
884 struct star *sa;
885 struct planet *p;
886
887 struct position o;
888
889 if((sa = universe_get_star_by_id(a, b)) == NULL) return;
890
891 if(sa->planets == 0) {
892 (void) star_live_title(sa, h);
893 (void) star_preview(sa, h,
894 (window_get_active_width(h) / 2) - (STAR_DRAW_PREVIEW_WIDTH / 2),
895 (window_get_active_height(h) / 2) - (STAR_DRAW_PREVIEW_HEIGHT / 2));
896
897 return;
898 }
899
900 if(star_live_op(sa) != 0) return;
901
902 x = window_get_active_width(h);
903 y = window_get_active_height(h);
904
905 w = VALUE_MIN2(x, y) - 1;
906
907 x /= 2;
908 y /= 2;
909
910 /* Set zoom factor */
911 s = maths_clamp(s, 0.0, STAR_LIVE_ZOOM_STEPS - 0.1);
912 z = sa->solarsize / STAR_LIVE_ZOOM_STEPS;
913
914 for(i = 0; i < sa->planets; i++) {
915 p = sa->pa[i];
916
917 (void) coords_angle_distance_to_position(p->angle, p->distance, &o);
918
919 /* Apply zooming */
920 e = sa->solarsize - (z * s);
921
922 sa->sd.cp_p[i].x = maths_map(o.x, 0.0, e, 0.0, (double) w) + x + u;
923 sa->sd.cp_p[i].y = maths_map(o.y, 0.0, e, 0.0, (double) w) + y + v;
924 sa->sd.cp_p[i].p.pixel.p = p->ps.rgb.pixel.p;
925
926 sa->sd.cc_p[i].x = sa->sd.cp_p[i].x;
927 sa->sd.cc_p[i].y = sa->sd.cp_p[i].y;
928 sa->sd.cc_p[i].n = 4;
929 sa->sd.cc_p[i].r = 10;
930 sa->sd.cc_p[i].f = 0.0;
931 sa->sd.cc_p[i].d = 360.0;
932 sa->sd.cc_p[i].p.pixel.p = p->ps.rgb.pixel.p;
933 }
934
935 sa->sd.cc_s.c = (unsigned int) sa->planets;
936 sa->sd.cc_s.p = sa->sd.cc_p;
937
938 sa->sd.cp_s.c = (unsigned int) sa->planets;
939 sa->sd.cp_s.p = sa->sd.cp_p;
940
941 sa->sd.cl_p[0].x1 = x + u;
942 sa->sd.cl_p[0].y1 = y + v - 10;
943 sa->sd.cl_p[0].x2 = sa->sd.cl_p[0].x1;
944 sa->sd.cl_p[0].y2 = sa->sd.cl_p[0].y1 + 20;
945 sa->sd.cl_p[0].p.pixel.p = sa->ss.rgb.pixel.p;
946 sa->sd.cl_p[1].x1 = x + u - 10;
947 sa->sd.cl_p[1].y1 = y + v;
948 sa->sd.cl_p[1].x2 = sa->sd.cl_p[1].x1 + 20;
949 sa->sd.cl_p[1].y2 = sa->sd.cl_p[1].y1;
950 sa->sd.cl_p[1].p.pixel.p = sa->sd.cl_p[0].p.pixel.p;
951
952 (void) star_preview(sa, h, 0, window_get_active_height(h) - STAR_DRAW_PREVIEW_HEIGHT);
953
954 (void) gui_draw_line_aa(h, &sa->sd.cl_p[0]);
955 (void) gui_draw_line_aa(h, &sa->sd.cl_p[1]);
956
957 (void) gui_draw_circles_aa(h, &sa->sd.cc_s);
958 (void) gui_draw_subpixels(h, &sa->sd.cp_s);
959
960 (void) star_live_title(sa, h);
961 }
962
star_live_op(struct star * sa)963 static int star_live_op(struct star *sa) {
964 size_t t;
965
966 if(sa->sd.cc_p == NULL) {
967 t = sizeof(struct circle_2) * sa->planets;
968
969 if((sa->sd.cc_p = malloc(t)) == NULL) {
970 LOGWARN(
971 ERROR_SLIGHT, SUBSYSTEM,
972 _("Failed to allocate %lu bytes of memory"),
973 (unsigned long) t
974 );
975
976 return(-1);
977 }
978
979 (void) memset((void *) sa->sd.cc_p, 0, t);
980 }
981
982 if(sa->sd.cp_p == NULL) {
983 t = sizeof(struct subpoint_2) * sa->planets;
984
985 if((sa->sd.cp_p = malloc(t)) == NULL) {
986 LOGWARN(
987 ERROR_SLIGHT, SUBSYSTEM,
988 _("Failed to allocate %lu bytes of memory"),
989 (unsigned long) t
990 );
991
992 return(-1);
993 }
994
995 (void) memset((void *) sa->sd.cp_p, 0, t);
996 }
997
998 return(0);
999 }
1000
star_live_title(struct star * sa,unsigned int h)1001 static void star_live_title(struct star *sa, unsigned int h) {
1002 char n[CONFIG_LINE_LENGTH];
1003
1004 struct pixel_rgb_8 p;
1005
1006 if(sa->sd.cp_f[0] == 0) {
1007 if((sa->sd.cp_f[0] = fonts_open("share/detroit/fonts/NotoSans-Italic.ttf", 18, 0)) == 0) return;
1008 }
1009
1010 (void) memset((void *) n, 0, sizeof(n));
1011
1012 if(sa->type == STAR_TYPE_NEUTRON || sa->type == STAR_TYPE_BLACKHOLE) {
1013 (void) snprintf(
1014 n, sizeof(n),
1015 "%s %s, class %s%c%c%c%c",
1016 star_type[sa->type], sa->name, star_class[sa->class], 0, 0, 0, 0
1017 );
1018 }
1019 else {
1020 if(sa->spectral[0] != ' ') {
1021 (void) snprintf(
1022 n, sizeof(n),
1023 "%s %s, class %s, spectral class %c%c, %lu planets%c%c%c%c",
1024 star_type[sa->type], sa->name, star_class[sa->class],
1025 sa->spectral[0], sa->spectral[1], sa->planets, 0, 0, 0, 0
1026 );
1027 }
1028 }
1029
1030 p.r = 255;
1031 p.g = 215;
1032 p.b = 105;
1033
1034 (void) fonts_render(sa->sd.cp_f[0], "UTF-8", n, str_len(n, STRING_ASCII), &p, 0);
1035
1036 sa->sd.cp_t[0].x = 10;
1037 sa->sd.cp_t[0].y = 10;
1038
1039 sa->sd.cp_t[0].f = sa->sd.cp_f[0];
1040
1041 (void) gui_draw_text(h, &sa->sd.cp_t[0]);
1042 }
1043
star_live_free(struct star * sa)1044 void star_live_free(struct star *sa) {
1045 unsigned long i;
1046
1047 for(i = 0; i < sizeof(sa->sd.cp_f) / sizeof(sa->sd.cp_f[0]); i++) {
1048 (void) fonts_close(sa->sd.cp_f[i]);
1049 }
1050
1051 if(sa->sd.cc_p != NULL) {
1052 (void) free(sa->sd.cc_p);
1053
1054 sa->sd.cc_p = NULL;
1055 }
1056
1057 if(sa->sd.cp_p != NULL) {
1058 (void) free(sa->sd.cp_p);
1059
1060 sa->sd.cp_p = NULL;
1061 }
1062 }
1063
star_live_closest(unsigned long a,unsigned long b,double u,double v)1064 unsigned long star_live_closest(unsigned long a, unsigned long b, double u, double v) {
1065 unsigned long i, r;
1066 double e, f;
1067
1068 struct star *sa;
1069
1070 struct position p, q;
1071
1072 if((sa = universe_get_star_by_id(a, b)) == NULL) return(0);
1073
1074 r = 0;
1075 f = sa->solarsize * 2.0;
1076
1077 q.x = u;
1078 q.y = v;
1079
1080 for(i = 0; i < (unsigned long) sa->sd.cp_s.c; i++) {
1081 p.x = sa->sd.cp_p[i].x;
1082 p.y = sa->sd.cp_p[i].y;
1083
1084 e = coords_difference_2d(&p, &q);
1085
1086 if(e < f) {
1087 f = e;
1088 r = i + 1;
1089 }
1090 }
1091
1092 return(r);
1093 }
1094
star_get_name(unsigned long a,unsigned long b)1095 char *star_get_name(unsigned long a, unsigned long b) {
1096 struct star *sa;
1097
1098 if((sa = universe_get_star_by_id(a, b)) == NULL) return(NULL);
1099
1100 return(sa->name);
1101 }
1102
star_get_nick(unsigned long a,unsigned long b)1103 char *star_get_nick(unsigned long a, unsigned long b) {
1104 struct star *sa;
1105
1106 if((sa = universe_get_star_by_id(a, b)) == NULL) return(NULL);
1107
1108 return(sa->nick);
1109 }
1110
star_get_ordinary(struct star * sa)1111 int star_get_ordinary(struct star *sa) {
1112 int r;
1113
1114 switch(sa->type) {
1115 case STAR_TYPE_NEUTRON:
1116 case STAR_TYPE_BLACKHOLE:
1117 r = IS_NO;
1118
1119 break;
1120 default:
1121 r = IS_YES;
1122
1123 break;
1124 }
1125
1126 return(r);
1127 }
1128
star_print_catalog(struct star * sa)1129 int star_print_catalog(struct star *sa) {
1130 int r;
1131
1132 char n;
1133
1134 r = catalog_entry_open();
1135
1136 r += catalog_entry_item_save((void *) &sa->id, sizeof(sa->id));
1137 r += catalog_entry_item_save((void *) &sa->pd, sizeof(sa->pd));
1138
1139 r += catalog_entry_item_save((void *) &sa->planets, sizeof(sa->planets));
1140 r += catalog_entry_item_save((void *) &sa->solarsize, sizeof(sa->solarsize));
1141
1142 r += catalog_entry_item_save((void *) &sa->class, sizeof(sa->class));
1143 r += catalog_entry_item_save((void *) &sa->type, sizeof(sa->type));
1144
1145 r += catalog_entry_item_save((void *) &sa->spectral, sizeof(sa->spectral));
1146
1147 /* Star position and velocity */
1148 r += catalog_entry_item_save((void *) &sa->sp.x, sizeof(sa->sp.x));
1149 r += catalog_entry_item_save((void *) &sa->sp.y, sizeof(sa->sp.y));
1150 r += catalog_entry_item_save((void *) &sa->sp.z, sizeof(sa->sp.z));
1151
1152 r += catalog_entry_item_save((void *) &sa->sv.x, sizeof(sa->sv.x));
1153 r += catalog_entry_item_save((void *) &sa->sv.y, sizeof(sa->sv.y));
1154 r += catalog_entry_item_save((void *) &sa->sv.z, sizeof(sa->sv.z));
1155
1156 /* Star composition */
1157 r += catalog_entry_item_save((void *) &sa->sc.carbon, sizeof(sa->sc.carbon));
1158 r += catalog_entry_item_save((void *) &sa->sc.helium, sizeof(sa->sc.helium));
1159 r += catalog_entry_item_save((void *) &sa->sc.hydrogen, sizeof(sa->sc.hydrogen));
1160 r += catalog_entry_item_save((void *) &sa->sc.iron, sizeof(sa->sc.iron));
1161 r += catalog_entry_item_save((void *) &sa->sc.magnesium, sizeof(sa->sc.magnesium));
1162 r += catalog_entry_item_save((void *) &sa->sc.neon, sizeof(sa->sc.neon));
1163 r += catalog_entry_item_save((void *) &sa->sc.nitrogen, sizeof(sa->sc.nitrogen));
1164 r += catalog_entry_item_save((void *) &sa->sc.oxygen, sizeof(sa->sc.oxygen));
1165 r += catalog_entry_item_save((void *) &sa->sc.silicon, sizeof(sa->sc.silicon));
1166 r += catalog_entry_item_save((void *) &sa->sc.sulfur, sizeof(sa->sc.sulfur));
1167
1168 /* Star specs */
1169 r += catalog_entry_item_save((void *) &sa->ss.bm, sizeof(sa->ss.bm));
1170 r += catalog_entry_item_save((void *) &sa->ss.vm, sizeof(sa->ss.vm));
1171 r += catalog_entry_item_save((void *) &sa->ss.jm, sizeof(sa->ss.jm));
1172 r += catalog_entry_item_save((void *) &sa->ss.bv, sizeof(sa->ss.bv));
1173
1174 r += catalog_entry_item_save((void *) &sa->ss.parallax, sizeof(sa->ss.parallax));
1175
1176 r += catalog_entry_item_save((void *) &sa->ss.radius, sizeof(sa->ss.radius));
1177 r += catalog_entry_item_save((void *) &sa->ss.radius_e, sizeof(sa->ss.radius_e));
1178 r += catalog_entry_item_save((void *) &sa->ss.radius_p, sizeof(sa->ss.radius_p));
1179 r += catalog_entry_item_save((void *) &sa->ss.magnitude, sizeof(sa->ss.magnitude));
1180 r += catalog_entry_item_save((void *) &sa->ss.temperature, sizeof(sa->ss.temperature));
1181 r += catalog_entry_item_save((void *) &sa->ss.luminance, sizeof(sa->ss.luminance));
1182
1183 r += catalog_entry_item_save((void *) &sa->ss.mass, sizeof(sa->ss.mass));
1184 r += catalog_entry_item_save((void *) &sa->ss.area, sizeof(sa->ss.area));
1185 r += catalog_entry_item_save((void *) &sa->ss.volume, sizeof(sa->ss.volume));
1186 r += catalog_entry_item_save((void *) &sa->ss.energy, sizeof(sa->ss.energy));
1187 r += catalog_entry_item_save((void *) &sa->ss.lifetime, sizeof(sa->ss.lifetime));
1188
1189 r += catalog_entry_item_save((void *) &sa->ss.rotation, sizeof(sa->ss.rotation));
1190 r += catalog_entry_item_save((void *) &sa->ss.flattening, sizeof(sa->ss.flattening));
1191
1192 r += catalog_entry_item_save((void *) &sa->ss.centripetal, sizeof(sa->ss.centripetal));
1193 r += catalog_entry_item_save((void *) &sa->ss.acceleration, sizeof(sa->ss.acceleration));
1194 r += catalog_entry_item_save((void *) &sa->ss.velocity, sizeof(sa->ss.velocity));
1195
1196 r += catalog_entry_item_save((void *) &sa->ss.rgb, sizeof(sa->ss.rgb));
1197
1198 /* Star drawing variables */
1199 r += catalog_entry_item_save((void *) &sa->sd.p_w, sizeof(sa->sd.p_w));
1200 r += catalog_entry_item_save((void *) &sa->sd.p_h, sizeof(sa->sd.p_h));
1201
1202 r += catalog_entry_item_save((void *) &sa->sd.c, sizeof(sa->sd.c));
1203
1204 /* Star name */
1205 n = 0;
1206
1207 if(sa->name != NULL) r += catalog_entry_item_save((void *) sa->name, sa->name_t + sizeof(char));
1208 else r += catalog_entry_item_save((void *) &n, sizeof(n));
1209
1210 if(sa->nick != NULL) r += catalog_entry_item_save((void *) sa->nick, sa->nick_t + sizeof(char));
1211 else r += catalog_entry_item_save((void *) &n, sizeof(n));
1212
1213 if(sa->solar != NULL) r += catalog_entry_item_save((void *) sa->solar, sa->solar_t + sizeof(char));
1214 else r += catalog_entry_item_save((void *) &n, sizeof(n));
1215
1216 return(r);
1217 }
1218
star_render(unsigned int h,unsigned long a,unsigned long b)1219 void star_render(unsigned int h, unsigned long a, unsigned long b) {
1220 struct star *sa;
1221
1222 if((sa = universe_get_star_by_id(a, b)) == NULL) return;
1223
1224 (void) star_preview(sa, h, 0, 0);
1225 }
1226
star_store(unsigned long a,unsigned long b,char * s)1227 void star_store(unsigned long a, unsigned long b, char *s) {
1228 struct star *sa;
1229
1230 if((sa = universe_get_star_by_id(a, b)) == NULL) return;
1231
1232 (void) star_image(sa, s, IMAGE_FORMAT_TGA);
1233 }
1234
star_print(unsigned long a,unsigned long b)1235 void star_print(unsigned long a, unsigned long b) {
1236 struct star *sa;
1237
1238 if((sa = universe_get_star_by_id(a, b)) == NULL) return;
1239
1240 (void) star_print_human(sa);
1241 }
1242
star_print_human(struct star * sa)1243 void star_print_human(struct star *sa) {
1244 (void) fprintf(stdout, _("* %s %s, class %s"), star_type[sa->type], sa->name, star_class[sa->class]);
1245
1246 if(sa->type != STAR_TYPE_NEUTRON && sa->type != STAR_TYPE_BLACKHOLE) {
1247 if(sa->spectral[0] != ' ') (void) fprintf(stdout, _(", spectral class %c%c"), sa->spectral[0], sa->spectral[1]);
1248 }
1249
1250 if(sa->planets != 0) {
1251 (void) fprintf(stdout, _(", %s with %lu planets"), sa->solar, sa->planets);
1252 }
1253
1254 (void) fprintf(stdout, "%c%c", CONFIG_LINE_FEED, CONFIG_LINE_FEED);
1255
1256 (void) fprintf(stdout, _(" absolute magnitude......... %g%c"), sa->ss.magnitude, CONFIG_LINE_FEED);
1257 (void) fprintf(stdout, _(" luminance.................. %g watts%c"), sa->ss.luminance, CONFIG_LINE_FEED);
1258 (void) fprintf(stdout, _(" temperature................ %g kelvin%c"), sa->ss.temperature, CONFIG_LINE_FEED);
1259 (void) fprintf(stdout, _(" %g celsius%c"), maths_kelvin_to_celsius(sa->ss.temperature), CONFIG_LINE_FEED);
1260 (void) fprintf(stdout, _(" %g fahrenheit%c"), maths_kelvin_to_fahrenheit(sa->ss.temperature), CONFIG_LINE_FEED);
1261 (void) fprintf(stdout, "%c", CONFIG_LINE_FEED);
1262
1263 (void) fprintf(stdout, _(" mean radius................ %g kilometers%c"), sa->ss.radius, CONFIG_LINE_FEED);
1264 (void) fprintf(stdout, _(" equatorial radius.......... %g kilometers%c"), sa->ss.radius_e, CONFIG_LINE_FEED);
1265 (void) fprintf(stdout, _(" polar radius............... %g kilometers%c"), sa->ss.radius_p, CONFIG_LINE_FEED);
1266 (void) fprintf(stdout, _(" rotation velocity.......... %g meters per second%c"), sa->ss.rotation, CONFIG_LINE_FEED);
1267 (void) fprintf(stdout, _(" flattening................. %g%c"), sa->ss.flattening, CONFIG_LINE_FEED);
1268 (void) fprintf(stdout, "%c", CONFIG_LINE_FEED);
1269
1270 (void) fprintf(stdout, _(" mass....................... %g kilograms%c"), sa->ss.mass, CONFIG_LINE_FEED);
1271 (void) fprintf(stdout, _(" area....................... %g square kilometers%c"), sa->ss.area, CONFIG_LINE_FEED);
1272 (void) fprintf(stdout, _(" volume..................... %g cubic kilometers%c"), sa->ss.volume, CONFIG_LINE_FEED);
1273 (void) fprintf(stdout, "%c", CONFIG_LINE_FEED);
1274
1275 (void) fprintf(stdout, _(" energy..................... %g joules%c"), sa->ss.energy, CONFIG_LINE_FEED);
1276 (void) fprintf(stdout, _(" lifetime................... %g million years%c"), sa->ss.lifetime, CONFIG_LINE_FEED);
1277 (void) fprintf(stdout, "%c", CONFIG_LINE_FEED);
1278
1279 (void) fprintf(stdout, _(" centripetal acceleration... %g meters per second%c"), sa->ss.centripetal, CONFIG_LINE_FEED);
1280 (void) fprintf(stdout, _(" gravity acceleration....... %g meters per second%c"), sa->ss.acceleration, CONFIG_LINE_FEED);
1281 (void) fprintf(stdout, _(" escape velocity............ %g kilometers per second%c"), sa->ss.velocity, CONFIG_LINE_FEED);
1282 (void) fprintf(stdout, "%c", CONFIG_LINE_FEED);
1283
1284 if(sa->type != STAR_TYPE_BLACKHOLE) {
1285 (void) fprintf(stdout, _(" color...................... %d/%d/%d/%d in RGBA (0-255)%c"), sa->ss.rgb.pixel.r, sa->ss.rgb.pixel.g, sa->ss.rgb.pixel.b, sa->ss.rgb.pixel.a, CONFIG_LINE_FEED);
1286 (void) fprintf(stdout, "%c", CONFIG_LINE_FEED);
1287 }
1288
1289 if(sa->type != STAR_TYPE_NEUTRON && sa->type != STAR_TYPE_BLACKHOLE) {
1290 (void) fprintf(stdout, _(" chemical composition percentages%c"), CONFIG_LINE_FEED);
1291 (void) fprintf(stdout, "%c", CONFIG_LINE_FEED);
1292
1293 (void) star_print_human_op(sa, _(ELEMENT_CARBON_ELEMENT_NAME), ELEMENT_CARBON_STANDARD_STATE, ELEMENT_CARBON_TEMP_MELTING, ELEMENT_CARBON_TEMP_BOILING, sa->sc.carbon);
1294 (void) star_print_human_op(sa, _(ELEMENT_HELIUM_ELEMENT_NAME), ELEMENT_HELIUM_STANDARD_STATE, ELEMENT_HELIUM_TEMP_MELTING, ELEMENT_HELIUM_TEMP_BOILING, sa->sc.helium);
1295 (void) star_print_human_op(sa, _(ELEMENT_HYDROGEN_ELEMENT_NAME), ELEMENT_HYDROGEN_STANDARD_STATE, ELEMENT_HYDROGEN_TEMP_MELTING, ELEMENT_HYDROGEN_TEMP_BOILING, sa->sc.hydrogen);
1296 (void) star_print_human_op(sa, _(ELEMENT_IRON_ELEMENT_NAME), ELEMENT_IRON_STANDARD_STATE, ELEMENT_IRON_TEMP_MELTING, ELEMENT_IRON_TEMP_BOILING, sa->sc.iron);
1297 (void) star_print_human_op(sa, _(ELEMENT_MAGNESIUM_ELEMENT_NAME), ELEMENT_MAGNESIUM_STANDARD_STATE, ELEMENT_MAGNESIUM_TEMP_MELTING, ELEMENT_MAGNESIUM_TEMP_BOILING, sa->sc.magnesium);
1298 (void) star_print_human_op(sa, _(ELEMENT_NEON_ELEMENT_NAME), ELEMENT_NEON_STANDARD_STATE, ELEMENT_NEON_TEMP_MELTING, ELEMENT_NEON_TEMP_BOILING, sa->sc.neon);
1299 (void) star_print_human_op(sa, _(ELEMENT_NITROGEN_ELEMENT_NAME), ELEMENT_NITROGEN_STANDARD_STATE, ELEMENT_NITROGEN_TEMP_MELTING, ELEMENT_NITROGEN_TEMP_BOILING, sa->sc.nitrogen);
1300 (void) star_print_human_op(sa, _(ELEMENT_OXYGEN_ELEMENT_NAME), ELEMENT_OXYGEN_STANDARD_STATE, ELEMENT_OXYGEN_TEMP_MELTING, ELEMENT_OXYGEN_TEMP_BOILING, sa->sc.oxygen);
1301 (void) star_print_human_op(sa, _(ELEMENT_SILICON_ELEMENT_NAME), ELEMENT_SILICON_STANDARD_STATE, ELEMENT_SILICON_TEMP_MELTING, ELEMENT_SILICON_TEMP_BOILING, sa->sc.silicon);
1302 (void) star_print_human_op(sa, _(ELEMENT_SULFUR_ELEMENT_NAME), ELEMENT_SULFUR_STANDARD_STATE, ELEMENT_SULFUR_TEMP_MELTING, ELEMENT_SULFUR_TEMP_BOILING, sa->sc.sulfur);
1303
1304 (void) fprintf(stdout, "%c", CONFIG_LINE_FEED);
1305 }
1306 }
1307
star_print_human_op(struct star * a,char * s,int e,float m,float b,float c)1308 static void star_print_human_op(struct star *a, char *s, int e, float m, float b, float c) {
1309 char *x, *y, *z;
1310
1311 size_t i, t;
1312
1313 char n[STAR_NAME_LEN_MAX];
1314
1315 switch(e) {
1316 case ELEMENT_STATE_GAS:
1317 x = _(ELEMENT_STATE_GAS_GAS);
1318 y = _(ELEMENT_STATE_GAS_LIQUID);
1319 z = _(ELEMENT_STATE_GAS_ICE);
1320
1321 break;
1322 case ELEMENT_STATE_LIQUID:
1323 x = _(ELEMENT_STATE_LIQUID_VAPOR);
1324 y = _(ELEMENT_STATE_LIQUID_LIQUID);
1325 z = _(ELEMENT_STATE_LIQUID_ICE);
1326
1327 break;
1328 case ELEMENT_STATE_SOLID:
1329 x = _(ELEMENT_STATE_SOLID_VAPOR);
1330 y = _(ELEMENT_STATE_SOLID_MOLTEN);
1331 z = _(ELEMENT_STATE_SOLID_SOLID);
1332
1333 break;
1334 default:
1335 x = "";
1336 y = "";
1337 z = "";
1338
1339 break;
1340 }
1341
1342 if(a->ss.temperature >= b) {
1343 (void) snprintf(n, sizeof(n), "%s, %s", s, x);
1344 }
1345 else if(a->ss.temperature >= m) {
1346 (void) snprintf(n, sizeof(n), "%s, %s", s, y);
1347 }
1348 else {
1349 (void) snprintf(n, sizeof(n), "%s, %s", s, z);
1350 }
1351
1352 (void) fprintf(stdout, " %s", n);
1353
1354 t = str_len(n, STRING_ASCII);
1355
1356 if(t < 26) {
1357 for(i = 0; i < 26 - t; i++) (void) fprintf(stdout, ".");
1358 }
1359
1360 (void) fprintf(stdout, " %f%c", c, CONFIG_LINE_FEED);
1361 }
1362