1 #include "engine/declarations.h"
2
3 #include "declarations_app.h"
4 #include "universe.h"
5
6
7
universe_init(void)8 int universe_init(void) {
9 (void) universe_set_message("");
10
11 if((sp = malloc(sizeof(struct universe))) == NULL) {
12 LOGWARN(
13 ERROR_SLIGHT, SUBSYSTEM,
14 _("Failed to allocate %lu bytes of memory"),
15 (unsigned long) sizeof(struct universe)
16 );
17
18 return(-1);
19 }
20
21 if(universe_create_random() != 0) {
22 (void) universe_free();
23
24 return(-1);
25 }
26
27 return(0);
28 }
29
universe_free(void)30 void universe_free(void) {
31 unsigned long i;
32
33 if(sp != NULL) {
34 for(i = 0; i < sp->galaxies; i++) (void) galaxy_free(sp->ga[i]);
35
36 (void) free(sp);
37
38 sp = NULL;
39 }
40 }
41
universe_run(void)42 void universe_run(void) {
43 unsigned long a, b, c, d;
44
45 struct tm tv;
46
47 struct galaxy *ga;
48 struct star *sa;
49 struct planet *pa, *ca;
50
51 (void) timer_get_date_by_time(&tv, (time_t) round(clock_get_ticks()));
52 #if defined(__sun__)
53 (void) snprintf(
54 dt, sizeof(dt),
55 "%d.%d.%d %.2d:%.2d",
56 tv.tm_mday, tv.tm_mon + 1, tv.tm_year + 1900,
57 tv.tm_hour, tv.tm_min);
58 #else
59 (void) snprintf(
60 dt, sizeof(dt),
61 "%d.%d.%d %s %.2d:%.2d",
62 tv.tm_mday, tv.tm_mon + 1, tv.tm_year + 1900, tv.tm_zone,
63 tv.tm_hour, tv.tm_min);
64 #endif
65 for(a = 0; a < sp->galaxies; a++) {
66 ga = sp->ga[a];
67
68 (void) galaxy_run(ga);
69
70 for(b = 0; b < ga->stars; b++) {
71 sa = ga->sa[b];
72
73 (void) star_run(sa);
74
75 for(c = 0; c < sa->planets; c++) {
76 pa = sa->pa[c];
77
78 (void) planet_run(pa);
79
80 for(d = 0; d < pa->satellites; d++) {
81 ca = pa->ca[d];
82
83 (void) planet_run(ca);
84 }
85 }
86 }
87 }
88 }
89
universe_set_message(char * s)90 void universe_set_message(char *s) {
91 (void) snprintf(ms, sizeof(ms), "%s", s);
92
93 ++mc;
94 }
95
universe_chk_message(void)96 unsigned int universe_chk_message(void) {
97 return(mc);
98 }
99
universe_get_message(void)100 char *universe_get_message(void) {
101 return(ms);
102 }
103
universe_get_date(void)104 char *universe_get_date(void) {
105 return(dt);
106 }
107
universe_get_galaxy_by_id(unsigned long a)108 struct galaxy *universe_get_galaxy_by_id(unsigned long a) {
109 if(a > sp->galaxies) {
110 return(NULL);
111 }
112
113 return(sp->ga[a]);
114 }
115
universe_get_star_by_id(unsigned long a,unsigned long b)116 struct star *universe_get_star_by_id(unsigned long a, unsigned long b) {
117 if(a > sp->galaxies || b > sp->ga[a]->stars) {
118 return(NULL);
119 }
120
121 return(sp->ga[a]->sa[b]);
122 }
123
universe_get_planet_by_id(unsigned long a,unsigned long b,unsigned long c)124 struct planet *universe_get_planet_by_id(unsigned long a, unsigned long b, unsigned long c) {
125 if(a > sp->galaxies || b > sp->ga[a]->stars || c > sp->ga[a]->sa[b]->planets || sp->ga[a]->sa[b]->planets == 0) {
126 return(NULL);
127 }
128
129 return(sp->ga[a]->sa[b]->pa[c]);
130 }
131
universe_get_satellite_by_id(unsigned long a,unsigned long b,unsigned long c,unsigned long d)132 struct planet *universe_get_satellite_by_id(unsigned long a, unsigned long b, unsigned long c, unsigned long d) {
133 if(a > sp->galaxies || b > sp->ga[a]->stars || c > sp->ga[a]->sa[b]->planets || d > sp->ga[a]->sa[b]->pa[c]->satellites || sp->ga[a]->sa[b]->pa[c]->satellites == 0) {
134 return(NULL);
135 }
136
137 return(sp->ga[a]->sa[b]->pa[c]->ca[d]);
138 }
139
universe_create_random(void)140 static int universe_create_random(void) {
141 unsigned long a;
142
143 sp->id = 0;
144 sp->galaxies = UNIVERSE_GALAXIES_PER_SPACE;
145
146 if((sp->ga = malloc(sizeof(struct galaxy *) * sp->galaxies)) == NULL) {
147 LOGWARN(
148 ERROR_SLIGHT, SUBSYSTEM,
149 _("Failed to allocate %lu bytes of memory"),
150 (unsigned long (sizeof(struct galaxy *) * sp->galaxies)
151 );
152
153 return(-1);
154 }
155
156 /* Populate universe */
157 for(a = 0; a < sp->galaxies; a++) {
158 if(galaxy_create(sp, a) != 0) return(-1);
159 if(universe_create_random_stars(sp->ga[a]) != 0) return(-1);
160 }
161
162 return(0);
163 }
164
165 static int universe_create_random_stars(struct galaxy *ga) {
166 unsigned long b;
167
168 if(ga->stars > UNIVERSE_STARS_PER_GALAXY_MAX) {
169 (void) flush_error();
170
171 LOGWARN(
172 ERROR_NOERROR, SUBSYSTEM,
173 _("Star count %lu exceeds star limit of %u, limiting star count to %u"),
174 ga->stars, (unsigned int) UNIVERSE_STARS_PER_GALAXY_MAX, (unsigned int) UNIVERSE_STARS_PER_GALAXY_MAX
175 );
176
177 ga->stars = UNIVERSE_STARS_PER_GALAXY_MAX;
178 }
179
180 if((ga->sa = malloc(sizeof(struct star *) * ga->stars)) == NULL) {
181 LOGWARN(
182 ERROR_SLIGHT, SUBSYSTEM,
183 _("Failed to allocate %lu bytes of memory"),
184 (unsigned long) (sizeof(struct star *) * ga->stars)
185 );
186
187 return(-1);
188 }
189
190 LOGINFO(
191 ERROR_NOERROR, SUBSYSTEM,
192 _("Generating %lu solar systems, this may take a while"),
193 ga->stars
194 );
195
196 /* First star is always a black hole at the center of the galaxy */
197 if(star_create_blackhole(ga, 0) != 0) return(-1);
198
199 (void) star_create_spot_blackhole(ga, 0);
200
201 for(b = 1; b < ga->stars; b++) {
202 switch(maths_rand(1000)) {
203 case 1:
204 if(star_create_blackhole(ga, b) != 0) return(-1);
205
206 break;
207 case 2:
208 case 3:
209 case 4:
210 if(star_create_neutron(ga, b) != 0) return(-1);
211
212 break;
213 default:
214 if(star_create(ga, b) != 0) return(-1);
215 if(universe_create_random_planets(ga, b) != 0) return(-1);
216
217 break;
218 }
219
220 (void) star_create_spot(ga, b);
221 }
222
223 return(0);
224 }
225
226 static int universe_create_random_planets(struct galaxy *ga, unsigned long b) {
227 unsigned long c;
228
229 /* Create planets for parent star only if star is lucky enough (50% out of 100) */
230 if(maths_rand(100) > 50) return(0);
231
232 ga->sa[b]->planets = UNIVERSE_PLANETS_PER_STAR_MAX - UNIVERSE_PLANETS_PER_STAR_MIN;
233 ga->sa[b]->planets = (unsigned long) maths_rand((unsigned int) ga->sa[b]->planets) + UNIVERSE_PLANETS_PER_STAR_MIN;
234
235 ga->sa[b]->created = ga->sa[b]->planets;
236
237 if((ga->sa[b]->pa = malloc(sizeof(struct planet *) * ga->sa[b]->planets)) == NULL) {
238 LOGWARN(
239 ERROR_SLIGHT, SUBSYSTEM,
240 _("Failed to allocate %lu bytes of memory"),
241 (unsigned long) (sizeof(struct planet *) * ga->sa[b]->planets)
242 );
243
244 return(-1);
245 }
246
247 /* Parent star is a center of solar system now because it has planets */
248 if(star_create_solar(ga, b) != 0) return(-1);
249
250 for(c = 0; c < ga->sa[b]->planets; c++) {
251 if(planet_create(ga->sa[b], c) != 0) return(-1);
252 if(universe_create_random_satellites(ga->sa[b], c) != 0) return(-1);
253 }
254
255 return(0);
256 }
257
258 static int universe_create_random_satellites(struct star *sa, unsigned long c) {
259 unsigned long d;
260
261 /* Create satellites for parent planet if planet is lucky enough (75% out of 100) */
262 if(maths_rand(100) > 75) return(0);
263
264 sa->pa[c]->satellites = UNIVERSE_COMPS_PER_PLANET_MAX - UNIVERSE_COMPS_PER_PLANET_MIN;
265 sa->pa[c]->satellites = (unsigned long) maths_rand((unsigned int) sa->pa[c]->satellites) + UNIVERSE_COMPS_PER_PLANET_MIN;
266
267 if((sa->pa[c]->ca = malloc(sizeof(struct planet *) * sa->pa[c]->satellites)) == NULL) {
268 LOGWARN(
269 ERROR_SLIGHT, SUBSYSTEM,
270 _("Failed to allocate %lu bytes of memory"),
271 (unsigned long) (sizeof(struct planet *) * sa->pa[c]->satellites)
272 );
273
274 return(-1);
275 }
276
277 for(d = 0; d < sa->pa[c]->satellites; d++) {
278 if(planet_satellite_create(sa, c, d) != 0) return(-1);
279 }
280
281 return(0);
282 }
283
284 static void universe_print_human(void) {
285 (void) fprintf(stdout, _("$ Universe %lu, with %lu galaxies%c"), sp->id, sp->galaxies, CONFIG_LINE_FEED);
286 (void) fprintf(stdout, "%c", CONFIG_LINE_FEED);
287 }
288
289 static void universe_header_print_human(void) {
290 (void) fprintf(stdout, _("# This is %s version %s human-readable catalog%c"), APPLICATION_NAME, APPLICATION_VERSION, CONFIG_LINE_FEED);
291 (void) fprintf(stdout, "%c", CONFIG_LINE_FEED);
292 }
293