1 /* ---------------------------------------------------------------------- *
2 * ldsvguts.c
3 * This file is part of lincity.
4 * Lincity is copyright (c) I J Peters 1995-1997, (c) Greg Sharp 1997-2001.
5 * ---------------------------------------------------------------------- */
6 #include "lcconfig.h"
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include "lcstring.h"
10 #include "lcintl.h"
11 #include "screen.h"
12 #include "mouse.h"
13 #include "module_buttons.h"
14 #include "stats.h"
15
16 #include <fcntl.h>
17 #include <sys/types.h>
18
19 #if defined (TIME_WITH_SYS_TIME)
20 #include <time.h>
21 #include <sys/time.h>
22 #else
23 #if defined (HAVE_SYS_TIME_H)
24 #include <sys/time.h>
25 #else
26 #include <time.h>
27 #endif
28 #endif
29
30 #if defined (WIN32)
31 #include <winsock.h>
32 #include <io.h>
33 #include <direct.h>
34 #include <process.h>
35 #endif
36
37 #ifdef __EMX__
38 #define chown(x,y,z)
39 #endif
40
41 #if defined (HAVE_DIRENT_H)
42 #include <dirent.h>
43 #define NAMLEN(dirent) strlen((dirent)->d_name)
44 #else
45 #define dirent direct
46 #define NAMLEN(dirent) (dirent)->d_namlen
47 #if defined (HAVE_SYS_NDIR_H)
48 #include <sys/ndir.h>
49 #endif
50 #if defined (HAVE_SYS_DIR_H)
51 #include <sys/dir.h>
52 #endif
53 #if defined (HAVE_NDIR_H)
54 #include <ndir.h>
55 #endif
56 #endif
57
58 #include <ctype.h>
59 #include "common.h"
60 #ifdef LC_X11
61 #include <X11/cursorfont.h>
62 #endif
63 #include "lctypes.h"
64 #include "lin-city.h"
65 #include "cliglobs.h"
66 #include "engglobs.h"
67 #include "fileutil.h"
68 #include "power.h"
69 #include "pbar.h"
70 #include "stats.h"
71
72 #if defined (WIN32) && !defined (NDEBUG)
73 #define START_FAST_SPEED 1
74 #define SKIP_OPENING_SCENE 1
75 #endif
76
77 #define SI_BLACK 252
78 #define SI_RED 253
79 #define SI_GREEN 254
80 #define SI_YELLOW 255
81
82 #define MP_SANITY_CHECK 1
83
84 /* ---------------------------------------------------------------------- *
85 * Private Fn Prototypes
86 * ---------------------------------------------------------------------- */
87 void dump_screen (void);
88 int verify_city (char *cname);
89
90 /* ---------------------------------------------------------------------- *
91 * Private Global Variables
92 * ---------------------------------------------------------------------- */
93
94 char save_names[10][42];
95
96 /* ---------------------------------------------------------------------- *
97 * Public functions
98 * ---------------------------------------------------------------------- */
99 void
remove_scene(char * cname)100 remove_scene (char *cname)
101 {
102 char *s;
103 int l;
104 if ((l = strlen (cname)) < 2) /* Thanks to Chris J. Kiick */
105 return;
106
107 if ((s = (char *) malloc (lc_save_dir_len + l + 16)) == 0)
108 malloc_failure ();
109 sprintf (s, "%s%c%s", lc_save_dir, PATH_SLASH, cname);
110 remove (s);
111 free (s);
112 }
113
114 void
save_city_raw(char * cname)115 save_city_raw (char *cname)
116 {
117 int x, y, z, q, n, p;
118 #if defined (WIN32)
119 FILE *ofile = fopen (cname, "wb");
120 #else
121 FILE *ofile = fopen (cname, "w");
122 #endif
123 if (ofile == NULL) {
124 printf (_("Save file <%s> - "), cname);
125 do_error (_("Can't open save file!"));
126 }
127
128 fprintf (ofile, "%d\n", (int) VERSION_INT);
129 q = sizeof (Map_Point_Info);
130 prog_box (_("Saving scene"), 0);
131 check_endian ();
132 for (x = 0; x < WORLD_SIDE_LEN; x++) {
133 for (y = 0; y < WORLD_SIDE_LEN; y++) {
134 for (z = 0; z < sizeof(int); z++) {
135 n = *(((unsigned char *) &MP_INFO(x,y).population) + z);
136 fprintf (ofile, "%d\n", n);
137 }
138 for (z = 0; z < sizeof(int); z++) {
139 n = *(((unsigned char *) &MP_INFO(x,y).flags) + z);
140 fprintf (ofile, "%d\n", n);
141 }
142 for (z = 0; z < sizeof(unsigned short); z++) {
143 n = *(((unsigned char *) &MP_INFO(x,y).coal_reserve) + z);
144 fprintf (ofile, "%d\n", n);
145 }
146 for (z = 0; z < sizeof(unsigned short); z++) {
147 n = *(((unsigned char *) &MP_INFO(x,y).ore_reserve) + z);
148 fprintf (ofile, "%d\n", n);
149 }
150 for (z = 0; z < sizeof(int); z++) {
151 n = *(((unsigned char *) &MP_INFO(x,y).int_1) + z);
152 fprintf (ofile, "%d\n", n);
153 }
154 for (z = 0; z < sizeof(int); z++) {
155 n = *(((unsigned char *) &MP_INFO(x,y).int_2) + z);
156 fprintf (ofile, "%d\n", n);
157 }
158 for (z = 0; z < sizeof(int); z++) {
159 n = *(((unsigned char *) &MP_INFO(x,y).int_3) + z);
160 fprintf (ofile, "%d\n", n);
161 }
162 for (z = 0; z < sizeof(int); z++) {
163 n = *(((unsigned char *) &MP_INFO(x,y).int_4) + z);
164 fprintf (ofile, "%d\n", n);
165 }
166 for (z = 0; z < sizeof(int); z++) {
167 n = *(((unsigned char *) &MP_INFO(x,y).int_5) + z);
168 fprintf (ofile, "%d\n", n);
169 }
170 for (z = 0; z < sizeof(int); z++) {
171 n = *(((unsigned char *) &MP_INFO(x,y).int_6) + z);
172 fprintf (ofile, "%d\n", n);
173 }
174 for (z = 0; z < sizeof(int); z++) {
175 n = *(((unsigned char *) &MP_INFO(x,y).int_7) + z);
176 fprintf (ofile, "%d\n", n);
177 }
178 fprintf (ofile, "%d\n", (int) MP_POL(x,y));
179 fprintf (ofile, "%d\n", (int) MP_TYPE(x,y));
180 }
181 prog_box ("", (90 * x) / WORLD_SIDE_LEN);
182 }
183 check_endian (); /* we have to put the byte order back. */
184
185 fprintf (ofile, "%d\n", main_screen_originx);
186 fprintf (ofile, "%d\n", main_screen_originy);
187 fprintf (ofile, "%d\n", total_time);
188 for (x = 0; x < MAX_NUMOF_SUBSTATIONS; x++)
189 {
190 fprintf (ofile, "%d\n", substationx[x]);
191 fprintf (ofile, "%d\n", substationy[x]);
192 }
193 prog_box ("", 92);
194 fprintf (ofile, "%d\n", numof_substations);
195 for (x = 0; x < MAX_NUMOF_MARKETS; x++)
196 {
197 fprintf (ofile, "%d\n", marketx[x]);
198 fprintf (ofile, "%d\n", markety[x]);
199 }
200 prog_box ("", 94);
201 fprintf (ofile, "%d\n", numof_markets);
202 fprintf (ofile, "%d\n", people_pool);
203 fprintf (ofile, "%d\n", total_money);
204 fprintf (ofile, "%d\n", income_tax_rate);
205 fprintf (ofile, "%d\n", coal_tax_rate);
206 fprintf (ofile, "%d\n", dole_rate);
207 fprintf (ofile, "%d\n", transport_cost_rate);
208 fprintf (ofile, "%d\n", goods_tax_rate);
209 fprintf (ofile, "%d\n", export_tax);
210 fprintf (ofile, "%d\n", export_tax_rate);
211 fprintf (ofile, "%d\n", import_cost);
212 fprintf (ofile, "%d\n", import_cost_rate);
213 fprintf (ofile, "%d\n", tech_level);
214 fprintf (ofile, "%d\n", tpopulation);
215 fprintf (ofile, "%d\n", tstarving_population);
216 fprintf (ofile, "%d\n", tunemployed_population);
217 fprintf (ofile, "%d\n", 0); /* waste_goods is obsolete */
218 fprintf (ofile, "%d\n", power_made);
219 fprintf (ofile, "%d\n", power_used);
220 fprintf (ofile, "%d\n", coal_made);
221 fprintf (ofile, "%d\n", coal_used);
222 fprintf (ofile, "%d\n", goods_made);
223 fprintf (ofile, "%d\n", goods_used);
224 fprintf (ofile, "%d\n", ore_made);
225 fprintf (ofile, "%d\n", ore_used);
226 fprintf (ofile, "%d\n", 0); /* Removed diff_old_population, version 1.12 */
227
228 prog_box ("", 96);
229 /* Changed, version 1.12 */
230 fprintf (ofile, "%d\n", monthgraph_size);
231 for (x = 0; x < monthgraph_size; x++) {
232 fprintf (ofile, "%d\n", monthgraph_pop[x]);
233 fprintf (ofile, "%d\n", monthgraph_starve[x]);
234 fprintf (ofile, "%d\n", monthgraph_nojobs[x]);
235 fprintf (ofile, "%d\n", monthgraph_ppool[x]);
236 #if defined (commentout)
237 fprintf (ofile, "%d\n", diffgraph_power[x]);
238 fprintf (ofile, "%d\n", diffgraph_coal[x]);
239 fprintf (ofile, "%d\n", diffgraph_goods[x]);
240 fprintf (ofile, "%d\n", diffgraph_ore[x]);
241 fprintf (ofile, "%d\n", diffgraph_population[x]);
242 #endif
243 }
244 prog_box ("", 98);
245 fprintf (ofile, "%d\n", rockets_launched);
246 fprintf (ofile, "%d\n", rockets_launched_success);
247 fprintf (ofile, "%d\n", coal_survey_done);
248 for (x = 0; x < PBAR_DATA_SIZE; x++)
249 for (p = 0; p < NUM_PBARS; p++)
250 fprintf(ofile, "%d\n", pbars[p].data[x]);
251
252 prog_box ("", 99);
253
254 for (p = 0; p < NUM_PBARS; p++) {
255 fprintf(ofile, "%d\n", pbars[p].oldtot);
256 fprintf(ofile, "%d\n", pbars[p].diff);
257 }
258
259 fprintf (ofile, "%d\n", cheat_flag);
260 fprintf (ofile, "%d\n", total_pollution_deaths);
261 fprintf (ofile, "%f\n", pollution_deaths_history);
262 fprintf (ofile, "%d\n", total_starve_deaths);
263 fprintf (ofile, "%f\n", starve_deaths_history);
264 fprintf (ofile, "%d\n", total_unemployed_years);
265 fprintf (ofile, "%f\n", unemployed_history);
266 fprintf (ofile, "%d\n", max_pop_ever);
267 fprintf (ofile, "%d\n", total_evacuated);
268 fprintf (ofile, "%d\n", total_births);
269 for (x = 0; x < NUMOF_MODULES; x++)
270 fprintf (ofile, "%d\n", module_help_flag[x]);
271 fprintf (ofile, "%d\n", 0); /* dummy values */
272
273 fprintf (ofile, "%d\n", 0); /* backward compatibility */
274
275 if (strlen (given_scene) > 1)
276 fprintf (ofile, "%s\n", given_scene);
277 else
278 fprintf (ofile, "dummy\n"); /* 1 */
279
280 fprintf (ofile, "%d\n", highest_tech_level); /* 2 */
281
282 fprintf (ofile, "sust %d %d %d %d %d %d %d %d %d %d\n"
283 ,sust_dig_ore_coal_count, sust_port_count
284 ,sust_old_money_count, sust_old_population_count
285 ,sust_old_tech_count, sust_fire_count
286 ,sust_old_money, sust_old_population, sust_old_tech
287 ,sustain_flag); /* 3 */
288
289 fprintf (ofile, "dummy\n"); /* 4 */
290
291 fprintf (ofile, "dummy\n"); /* 5 */
292
293 fprintf (ofile, "dummy\n"); /* 6 */
294
295 fprintf (ofile, "dummy\n"); /* 7 */
296
297 fprintf (ofile, "dummy\n"); /* 8 */
298
299 fprintf (ofile, "dummy\n"); /* 9 */
300
301 fprintf (ofile, "dummy\n"); /* 10 */
302
303 fclose (ofile);
304 prog_box ("", 100);
305 }
306
307
308 void
save_city(char * cname)309 save_city (char *cname)
310 {
311 char *s, *s2, *s3, *s4;
312 int l;
313
314 if ((l = strlen (cname)) < 2)
315 return;
316 if ((s = (char *) malloc (lc_save_dir_len + l + 16)) == 0)
317 malloc_failure ();
318 if ((s2 = (char *) malloc (lc_save_dir_len + l + 32)) == 0)
319 malloc_failure ();
320 if ((s3 = (char *) malloc ((lc_save_dir_len + l) * 2 + 32)) == 0)
321 malloc_failure ();
322 if ((s4 = (char *) malloc ((lc_save_dir_len + l) * 2 + 32)) == 0)
323 malloc_failure ();
324
325 sprintf (s, "%s%c%s", lc_save_dir, PATH_SLASH, cname);
326 sprintf (s2, "%s%c%s", lc_save_dir, PATH_SLASH, "tmp-save");
327 sprintf (s3, "gzip -f %s", s2);
328 sprintf (s4, "mv %s.gz %s", s2, s);
329
330 #if defined (WIN32)
331 save_city_raw (s);
332 #else
333 save_city_raw (s2);
334 if (system (s3) != 0)
335 do_error ("gzip failed while in save_city");
336 if (system (s4) != 0)
337 do_error ("mv failed while in save_city");
338 #endif
339
340 free (s);
341 free (s2);
342 free (s3);
343 free (s4);
344 }
345
346 void
load_city(char * cname)347 load_city (char *cname)
348 {
349 unsigned long q;
350 int i, x, y, z, n, p, ver;
351 int num_pbars, pbar_data_size;
352 int pbar_tmp;
353 int dummy;
354 FILE *ofile;
355 char s[256];
356 if ((ofile = fopen_read_gzipped (cname)) == NULL) {
357 printf (_("Can't open <%s> (gzipped)"), cname);
358 do_error ("Can't open it!");
359 }
360 fscanf (ofile, "%d", &ver);
361 if (ver < MIN_LOAD_VERSION) {
362 ok_dial_box ("too-old.mes", BAD, 0L);
363 fclose_read_gzipped (ofile);
364 return;
365 }
366
367 init_pbars();
368 num_pbars = NUM_PBARS;
369 pbar_data_size = PBAR_DATA_SIZE;
370
371 init_inventory();
372
373 print_time_for_year();
374 q = (unsigned long) sizeof (Map_Point_Info);
375 prog_box (_("Loading scene"), 0);
376
377 for (x = 0; x < WORLD_SIDE_LEN; x++) {
378 for (y = 0; y < WORLD_SIDE_LEN; y++) {
379 for (z = 0; z < sizeof(int); z++) {
380 fscanf (ofile, "%d", &n);
381 *(((unsigned char *) &MP_INFO(x,y).population) + z) = n;
382 }
383 for (z = 0; z < sizeof(int); z++) {
384 fscanf (ofile, "%d", &n);
385 *(((unsigned char *) &MP_INFO(x,y).flags) + z) = n;
386 }
387 for (z = 0; z < sizeof(unsigned short); z++) {
388 fscanf (ofile, "%d", &n);
389 *(((unsigned char *) &MP_INFO(x,y).coal_reserve) + z) = n;
390 }
391 for (z = 0; z < sizeof(unsigned short); z++) {
392 fscanf (ofile, "%d", &n);
393 *(((unsigned char *) &MP_INFO(x,y).ore_reserve) + z) = n;
394 }
395 for (z = 0; z < sizeof(int); z++) {
396 fscanf (ofile, "%d", &n);
397 *(((unsigned char *) &MP_INFO(x,y).int_1) + z) = n;
398 }
399 for (z = 0; z < sizeof(int); z++) {
400 fscanf (ofile, "%d", &n);
401 *(((unsigned char *) &MP_INFO(x,y).int_2) + z) = n;
402 }
403 for (z = 0; z < sizeof(int); z++) {
404 fscanf (ofile, "%d", &n);
405 *(((unsigned char *) &MP_INFO(x,y).int_3) + z) = n;
406 }
407 for (z = 0; z < sizeof(int); z++) {
408 fscanf (ofile, "%d", &n);
409 *(((unsigned char *) &MP_INFO(x,y).int_4) + z) = n;
410 }
411 for (z = 0; z < sizeof(int); z++) {
412 fscanf (ofile, "%d", &n);
413 *(((unsigned char *) &MP_INFO(x,y).int_5) + z) = n;
414 }
415 for (z = 0; z < sizeof(int); z++) {
416 fscanf (ofile, "%d", &n);
417 *(((unsigned char *) &MP_INFO(x,y).int_6) + z) = n;
418 }
419 for (z = 0; z < sizeof(int); z++) {
420 fscanf (ofile, "%d", &n);
421 *(((unsigned char *) &MP_INFO(x,y).int_7) + z) = n;
422 }
423 fscanf (ofile, "%d", &n);
424 MP_POL(x,y) = (unsigned short) n;
425 fscanf (ofile, "%d", &n);
426 MP_TYPE(x,y) = (short) n;
427
428 if (get_group_of_type(MP_TYPE(x,y)) == GROUP_MARKET)
429 inventory(x,y);
430 }
431 if (((93 * x) / WORLD_SIDE_LEN) % 3 == 0)
432 prog_box ("", (93 * x) / WORLD_SIDE_LEN);
433 }
434 check_endian ();
435 set_map_groups ();
436
437 fscanf (ofile, "%d", &main_screen_originx);
438 fscanf (ofile, "%d", &main_screen_originy);
439 if (main_screen_originx > WORLD_SIDE_LEN - scr.main_win.w / 16 - 1)
440 main_screen_originx = WORLD_SIDE_LEN - scr.main_win.w / 16 - 1;
441
442 if (main_screen_originy > WORLD_SIDE_LEN - scr.main_win.h / 16 - 1)
443 main_screen_originy = WORLD_SIDE_LEN - scr.main_win.h / 16 - 1;
444
445 fscanf (ofile, "%d", &total_time);
446 if (ver <= MM_MS_C_VER)
447 i = OLD_MAX_NUMOF_SUBSTATIONS;
448 else
449 i = MAX_NUMOF_SUBSTATIONS;
450 for (x = 0; x < i; x++)
451 {
452 fscanf (ofile, "%d", &substationx[x]);
453 fscanf (ofile, "%d", &substationy[x]);
454 }
455 prog_box ("", 92);
456 fscanf (ofile, "%d", &numof_substations);
457 if (ver <= MM_MS_C_VER)
458 i = OLD_MAX_NUMOF_MARKETS;
459 else
460 i = MAX_NUMOF_MARKETS;
461 for (x = 0; x < i; x++)
462 {
463 fscanf (ofile, "%d", &marketx[x]);
464 fscanf (ofile, "%d", &markety[x]);
465 }
466 prog_box ("", 94);
467 fscanf (ofile, "%d", &numof_markets);
468 fscanf (ofile, "%d", &people_pool);
469 fscanf (ofile, "%d", &total_money);
470 fscanf (ofile, "%d", &income_tax_rate);
471 fscanf (ofile, "%d", &coal_tax_rate);
472 fscanf (ofile, "%d", &dole_rate);
473 fscanf (ofile, "%d", &transport_cost_rate);
474 fscanf (ofile, "%d", &goods_tax_rate);
475 fscanf (ofile, "%d", &export_tax);
476 fscanf (ofile, "%d", &export_tax_rate);
477 fscanf (ofile, "%d", &import_cost);
478 fscanf (ofile, "%d", &import_cost_rate);
479 fscanf (ofile, "%d", &tech_level);
480 if (tech_level > MODERN_WINDMILL_TECH)
481 modern_windmill_flag = 1;
482 fscanf (ofile, "%d", &tpopulation);
483 fscanf (ofile, "%d", &tstarving_population);
484 fscanf (ofile, "%d", &tunemployed_population);
485 fscanf (ofile, "%d", &x); /* waste_goods obsolete */
486 fscanf (ofile, "%d", &power_made);
487 fscanf (ofile, "%d", &power_used);
488 fscanf (ofile, "%d", &coal_made);
489 fscanf (ofile, "%d", &coal_used);
490 fscanf (ofile, "%d", &goods_made);
491 fscanf (ofile, "%d", &goods_used);
492 fscanf (ofile, "%d", &ore_made);
493 fscanf (ofile, "%d", &ore_used);
494 fscanf (ofile, "%d", &dummy); /* &diff_old_population */
495
496 /* Update variables calculated from those above */
497 housed_population = tpopulation / NUMOF_DAYS_IN_MONTH;
498
499 prog_box ("", 96);
500 /* Get size of monthgraph array */
501 if (ver <= MG_C_VER) {
502 i = 120;
503 } else {
504 fscanf (ofile, "%d", &i);
505 }
506 for (x = 0; x < i; x++) {
507 /* If more entries in file than will fit on screen,
508 then we need to skip past them. */
509 if (x >= monthgraph_size) {
510 fscanf (ofile, "%d", &dummy); /* &monthgraph_pop[x] */
511 fscanf (ofile, "%d", &dummy); /* &monthgraph_starve[x] */
512 fscanf (ofile, "%d", &dummy); /* &monthgraph_nojobs[x] */
513 fscanf (ofile, "%d", &dummy); /* &monthgraph_ppool[x] */
514 } else {
515 fscanf (ofile, "%d", &monthgraph_pop[x]);
516 fscanf (ofile, "%d", &monthgraph_starve[x]);
517 fscanf (ofile, "%d", &monthgraph_nojobs[x]);
518 fscanf (ofile, "%d", &monthgraph_ppool[x]);
519 }
520 /* If our save file is old, skip past obsolete diffgraph entries */
521 if (ver <= MG_C_VER) {
522 fscanf (ofile, "%d", &dummy); /* &diffgraph_power[x] */
523 fscanf (ofile, "%d", &dummy); /* &diffgraph_coal[x] */
524 fscanf (ofile, "%d", &dummy); /* &diffgraph_goods[x] */
525 fscanf (ofile, "%d", &dummy); /* &diffgraph_ore[x] */
526 fscanf (ofile, "%d", &dummy); /* &diffgraph_population[x] */
527 }
528 }
529 /* If screen bigger than number of entries in file, pad with zeroes */
530 while (x < monthgraph_size) {
531 monthgraph_pop[x] = 0;
532 monthgraph_starve[x] = 0;
533 monthgraph_nojobs[x] = 0;
534 monthgraph_ppool[x] = 0;
535 x++;
536 }
537 prog_box ("", 98);
538 fscanf (ofile, "%d", &rockets_launched);
539 fscanf (ofile, "%d", &rockets_launched_success);
540 fscanf (ofile, "%d", &coal_survey_done);
541
542 for (x = 0; x < pbar_data_size; x++) {
543 for (p = 0; p < num_pbars; p++) {
544 fscanf (ofile, "%d", &(pbar_tmp));
545 update_pbar(p,pbar_tmp,1);
546 /* fscanf (ofile, "%d", &(pbars[p].data[x])); */
547 }
548 }
549
550 for (p = 0; p < num_pbars; p++)
551 pbars[p].data_size = pbar_data_size;
552
553 prog_box ("", 99);
554
555 for (p = 0; p < num_pbars; p++) {
556 fscanf (ofile, "%d", &(pbars[p].oldtot));
557 fscanf (ofile, "%d", &(pbars[p].diff));
558 }
559
560
561 fscanf (ofile, "%d", &cheat_flag);
562 fscanf (ofile, "%d", &total_pollution_deaths);
563 fscanf (ofile, "%f", &pollution_deaths_history);
564 fscanf (ofile, "%d", &total_starve_deaths);
565 fscanf (ofile, "%f", &starve_deaths_history);
566 fscanf (ofile, "%d", &total_unemployed_years);
567 fscanf (ofile, "%f", &unemployed_history);
568 fscanf (ofile, "%d", &max_pop_ever);
569 fscanf (ofile, "%d", &total_evacuated);
570 fscanf (ofile, "%d", &total_births);
571 for (x = 0; x < NUMOF_MODULES; x++)
572 fscanf (ofile, "%d", &(module_help_flag[x]));
573 fscanf (ofile, "%d", &x); /* just dummy reads */
574 fscanf (ofile, "%d", &x); /* for backwards compatibility. */
575
576 /* 10 dummy strings, for missed out things, have been put in save. */
577 /* Input from this point uses them. */
578 /* XXX: WCK: Huh? Missed out things? */
579
580 fscanf (ofile, "%128s", given_scene);
581 if (strncmp (given_scene, "dummy", 5) == 0 || strlen (given_scene) < 3)
582 given_scene[0] = 0;
583 fscanf (ofile, "%128s", s);
584 if (strncmp (given_scene, "dummy", 5) != 0)
585 sscanf (s, "%d", &highest_tech_level);
586 else
587 highest_tech_level = 0;
588 fgets (s, 80, ofile); /* this is the CR */
589
590 fgets (s, 80, ofile);
591 if (sscanf (s, "sust %d %d %d %d %d %d %d %d %d %d"
592 ,&sust_dig_ore_coal_count, &sust_port_count
593 ,&sust_old_money_count, &sust_old_population_count
594 ,&sust_old_tech_count, &sust_fire_count
595 ,&sust_old_money, &sust_old_population, &sust_old_tech
596 ,&sustain_flag) == 10)
597 {
598 sust_dig_ore_coal_tip_flag = sust_port_flag = 1;
599 /* GCS FIX: Check after loading file if screen is drawn OK */
600 /* draw_sustainable_window (); */
601 }
602 else
603 sustain_flag = sust_dig_ore_coal_count = sust_port_count
604 = sust_old_money_count = sust_old_population_count
605 = sust_old_tech_count = sust_fire_count
606 = sust_old_money = sust_old_population = sust_old_tech = 0;
607 fclose_read_gzipped (ofile);
608
609 numof_shanties = count_groups (GROUP_SHANTY);
610 numof_communes = count_groups (GROUP_COMMUNE);
611 prog_box ("", 100);
612
613 /* set up the university intake. */
614 x = count_groups (GROUP_UNIVERSITY);
615 if (x > 0) {
616 university_intake_rate
617 = (count_groups (GROUP_SCHOOL) * 20) / x;
618 if (university_intake_rate > 100)
619 university_intake_rate = 100;
620 }
621 else
622 university_intake_rate = 50;
623 for (x = 0; x < WORLD_SIDE_LEN; x++)
624 {
625 for (y = 0; y < WORLD_SIDE_LEN; y++)
626 {
627 update_tech_dep (x, y);
628 }
629 }
630
631 unhighlight_module_button (selected_module);
632 selected_module = sbut[7]; /* 7 is track. Watch out though! */
633 highlight_module_button (selected_module);
634 set_selected_module (CST_TRACK_LR);
635
636 print_total_money ();
637 reset_animation_times ();
638 map_power_grid (); /* WCK: Is this safe to do here? */
639 }
640
641 void
load_saved_city(char * s)642 load_saved_city (char *s)
643 {
644 char *cname = (char *) malloc (strlen (lc_save_dir) + strlen (s) + 2);
645 sprintf (cname, "%s%c%s", lc_save_dir, PATH_SLASH, s);
646 load_city (cname);
647 free (cname);
648 }
649
650 void
reset_animation_times(void)651 reset_animation_times (void)
652 {
653 int x, y;
654 for (y = 0; y < WORLD_SIDE_LEN; y++)
655 for (x = 0; x < WORLD_SIDE_LEN; x++) {
656 if (MP_GROUP_IS_RESIDENCE(x,y))
657 MP_INFO(x,y).int_3 = 0;
658 else if (MP_GROUP(x,y) == GROUP_WINDMILL)
659 MP_INFO(x,y).int_4 = 0;
660 else if (MP_GROUP(x,y) == GROUP_BLACKSMITH)
661 MP_INFO(x,y).int_4 = 0;
662 else if (MP_GROUP(x,y) == GROUP_MILL)
663 MP_INFO(x,y).int_4 = 0;
664 else if (MP_GROUP(x,y) == GROUP_POTTERY)
665 MP_INFO(x,y).int_4 = 0;
666 else if (MP_GROUP(x,y) == GROUP_CRICKET)
667 MP_INFO(x,y).int_4 = 0;
668 else if (MP_GROUP(x,y) == GROUP_FIRESTATION)
669 MP_INFO(x,y).int_4 = 0;
670 else if (MP_GROUP(x,y) == GROUP_FIRE)
671 {
672 MP_INFO(x,y).int_1 = 0;
673 MP_INFO(x,y).int_3 = 0;
674 }
675 else if (MP_GROUP(x,y) == GROUP_COMMUNE)
676 MP_INFO(x,y).int_1 = 0;
677 else if (MP_GROUP(x,y) == GROUP_ROCKET)
678 MP_INFO(x,y).int_5 = 0;
679 else if (MP_GROUP(x,y) == GROUP_INDUSTRY_H)
680 MP_INFO(x,y).int_6 = 0;
681 else if (MP_GROUP(x,y) == GROUP_INDUSTRY_L)
682 MP_INFO(x,y).int_7 = 0;
683 }
684 }
685
686 /* Returns 1 if the city is proper version */
687 int
verify_city(char * cname)688 verify_city (char *cname)
689 {
690 FILE* fp;
691 char* s;
692 int v;
693
694 if (strlen(cname) == 0) {
695 return 0;
696 }
697 if ((s = (char *) malloc (lc_save_dir_len + strlen(cname) + 2)) == 0)
698 malloc_failure ();
699 sprintf (s, "%s%c%s", lc_save_dir, PATH_SLASH, cname);
700 if (!file_exists(s)) {
701 free (s);
702 return 0;
703 }
704 fp = fopen_read_gzipped (s);
705 if (fp == NULL) {
706 v = 0;
707 } else if (1 != fscanf (fp, "%d", &v)) {
708 v = 0;
709 }
710 fclose_read_gzipped (fp);
711 free (s);
712 return v == VERSION_INT;
713 }
714
715 #ifdef MP_SANITY_CHECK
716 void
sanity_check(void)717 sanity_check (void)
718 {
719 static int flag = 0;
720 int x, y, xx, yy;
721 for (x = 0; x < WORLD_SIDE_LEN; x++)
722 for (y = 0; y < WORLD_SIDE_LEN; y++) {
723 if (MP_TYPE(x,y) == CST_USED) {
724 xx = MP_INFO(x,y).int_1;
725 yy = MP_INFO(x,y).int_2;
726 if (xx < (x - 4) || yy < (y - 4) || xx > x || yy > y ||
727 xx < 0 || xx > WORLD_SIDE_LEN ||
728 yy < 0 || yy > WORLD_SIDE_LEN) {
729 printf ("Sanity failed at %d %d, points to %d %d\n", x, y, xx, yy);
730 if (flag == 0)
731 yn_dial_box ("MP sanity check error",
732 "Please mail lincity-users@lists.sourceforge.net",
733 "telling me what you just did.",
734 "Do you think I'll find this bug?");
735 flag = 1;
736 }
737 }
738 }
739 }
740 #endif
741
742
743 void
check_endian(void)744 check_endian (void)
745 {
746 static int flag = 0;
747 char *cs;
748 int t, x, y;
749 t = 0;
750 cs = (char *) &t;
751 *cs = 1;
752 if (t == 1) /* little endian */
753 return;
754 printf ("t=%x\n", t);
755 if (flag == 0) {
756 flag = 1;
757 }
758 for (y = 0; y < WORLD_SIDE_LEN; y++) {
759 for (x = 0; x < WORLD_SIDE_LEN; x++) {
760 eswap32 (&(MP_INFO(x,y).population));
761 eswap32 (&(MP_INFO(x,y).flags));
762 if (sizeof (short) == 2) {
763 eswap16 (&(MP_INFO(x,y).coal_reserve));
764 eswap16 (&(MP_INFO(x,y).ore_reserve));
765 } else if (sizeof (short) == 4) {
766 eswap32 ((int *) &(MP_INFO(x,y).coal_reserve));
767 eswap32 ((int *) &(MP_INFO(x,y).ore_reserve));
768 } else {
769 printf ("Strange size (%d) for short, please mail me.\n",
770 sizeof (short));
771 }
772 eswap32 (&(MP_INFO(x,y).int_1));
773 eswap32 (&(MP_INFO(x,y).int_2));
774 eswap32 (&(MP_INFO(x,y).int_3));
775 eswap32 (&(MP_INFO(x,y).int_4));
776 eswap32 (&(MP_INFO(x,y).int_5));
777 eswap32 (&(MP_INFO(x,y).int_6));
778 eswap32 (&(MP_INFO(x,y).int_7));
779 }
780 }
781 }
782
783 void
eswap32(int * i)784 eswap32 (int *i)
785 {
786 char *cs, c1, c2, c3, c4;
787 cs = (char *) i;
788 c1 = *cs;
789 c2 = *(cs + 1);
790 c3 = *(cs + 2);
791 c4 = *(cs + 3);
792 *(cs++) = c4;
793 *(cs++) = c3;
794 *(cs++) = c2;
795 *cs = c1;
796 }
797
798 void
eswap16(unsigned short * i)799 eswap16 (unsigned short *i)
800 {
801 char *cs, c1, c2;
802 cs = (char *) i;
803 c1 = *cs;
804 c2 = *(cs + 1);
805 *(cs++) = c2;
806 *cs = c1;
807 }
808