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