1 /* ---------------------------------------------------------------------- *
2  * main.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 <signal.h>
10 #include "lcstring.h"
11 #include "cliglobs.h"
12 #include "lchelp.h"
13 #include "dialbox.h"
14 #include <mps.h>
15 
16 /* this is for OS/2 - RVI */
17 #ifdef __EMX__
18 #include <sys/select.h>
19 #include <X11/Xlibint.h>      /* required for __XOS2RedirRoot */
20 #define chown(x,y,z)
21 /* #define OS2_DEFAULT_LIBDIR "/XFree86/lib/X11/lincity" */
22 /* This was moved to fileutil.c */
23 #endif
24 
25 #include <sys/types.h>
26 #include <fcntl.h>
27 
28 #if defined (WIN32)
29 #include <winsock.h>
30 #include <io.h>
31 #include <direct.h>
32 #include <process.h>
33 #endif
34 
35 #include <time.h>
36 
37 #include <ctype.h>
38 #include "common.h"
39 #ifdef LC_X11
40 #include <X11/cursorfont.h>
41 #include <lcx11.h>
42 #endif
43 
44 #include "lctypes.h"
45 #include "lin-city.h"
46 #include "cliglobs.h"
47 #include "engglobs.h"
48 #include "timer.h"
49 #include "ldsvgui.h"
50 #include "simulate.h"
51 #include "mouse.h"
52 #include "pixmap.h"
53 #include "screen.h"
54 #include "lcintl.h"
55 #include "engine.h"
56 #include "module_buttons.h"
57 #include "fileutil.h"
58 
59 #if defined (WIN32) && !defined (NDEBUG)
60 #define START_FAST_SPEED 1
61 //#define SKIP_OPENING_SCENE 1
62 #endif
63 
64 #define SI_BLACK 252
65 #define SI_RED 253
66 #define SI_GREEN 254
67 #define SI_YELLOW 255
68 
69 #define DEBUG_KEYS 1
70 
71 /* ---------------------------------------------------------------------- *
72  * Private Fn Prototypes
73  * ---------------------------------------------------------------------- */
74 void dump_screen (void);
75 void verify_package (void);
76 char* current_month (int current_time);
77 int current_year (int current_time);
78 void process_keystrokes (int key);
79 int execute_timestep (void);
80 
81 /* ---------------------------------------------------------------------- *
82  * Private Global Variables
83  * ---------------------------------------------------------------------- */
84 #if defined (commentout)          /* Moved to fileutil.c */
85 #if defined (WIN32)
86 char LIBDIR[_MAX_PATH];
87 #elif defined (__EMX__)
88 #ifdef LIBDIR
89 #undef LIBDIR   /* yes, I know I shouldn't ;-) */
90 #endif
91 /* GCS: Presumably I can do this, right? */
92 #if defined (commentout)
93 char LIBDIR[256];
94 #endif
95 char LIBDIR[LC_PATH_MAX];
96 #endif
97 #endif
98 
99 extern char *lc_save_dir;
100 extern char *lc_temp_file;
101 extern char save_names[10][42];
102 
103 #ifdef CS_PROFILE
104 int prof_countdown = PROFILE_COUNTDOWN;
105 #endif
106 
107 
108 /* ---------------------------------------------------------------------- *
109  * Public Functions
110  * ---------------------------------------------------------------------- */
111 #if !defined (WIN32)
112 int
main(int argc,char * argv[])113 main (int argc, char *argv[])
114 {
115     return lincity_main (argc, argv);
116 }
117 #endif
118 
119 void
lincity_set_locale(void)120 lincity_set_locale (void)
121 {
122     char* locale = NULL;
123     char* localem = NULL;
124 #if defined (WIN32)
125 #define MAX_LANG_BUF 1024
126     char* language = NULL;
127     char language_buf[MAX_LANG_BUF];
128 #endif
129 
130 #if defined (ENABLE_NLS)
131 #if defined (WIN32)
132     /* Some special stoopid way of setting locale for microsoft gettext */
133     language = getenv ("LANGUAGE");
134     if (language) {
135 	debug_printf ("Environment variable LANGUAGE is %s\n", language);
136 	snprintf (language_buf, MAX_LANG_BUF, "LANGUAGE=%s", language);
137 	gettext_putenv(language_buf);
138     } else {
139 	debug_printf ("Environment variable LANGUAGE not set.\n");
140     }
141 #else
142     locale = setlocale (LC_ALL, "");
143     debug_printf ("Setting entire locale to %s\n", locale);
144     locale = setlocale (LC_MESSAGES, "");
145     debug_printf ("Setting messages locale to %s\n", locale);
146     localem = setlocale (LC_MESSAGES, NULL);
147     debug_printf ("Query locale is %s\n", localem);
148 #endif
149 #endif /* ENABLE_NLS */
150     return;
151 }
152 
153 int
lincity_main(int argc,char * argv[])154 lincity_main (int argc, char *argv[])
155 {
156 #if defined (LC_X11)
157     char *geometry = NULL;
158 #endif
159 
160 #if defined (SVGALIB)
161     int q;
162     vga_init ();
163 #endif
164 
165 #if !defined (WIN32)
166     signal (SIGPIPE, SIG_IGN);    /* broken pipes are ignored. */
167 #endif
168 
169     /* Initialize some global variables */
170     //make_dir_ok_flag = 1;
171     main_screen_originx = 1;
172     main_screen_originy = 1;
173     given_scene[0] = 0;
174     quit_flag = network_flag = load_flag = save_flag
175 	    = prefs_flag = cheat_flag = monument_bul_flag
176 	    = river_bul_flag = shanty_bul_flag;
177     prefs_drawn_flag = 0;
178     kmouse_val = 8;
179 
180 #ifdef LC_X11
181     borderx = 0;
182     bordery = 0;
183     parse_xargs (argc, argv, &geometry);
184 #endif
185 
186     /* I18n */
187     lincity_set_locale ();
188 
189     /* Set up the paths to certain files and directories */
190     init_path_strings ();
191 
192     /* Make sure that things are installed where they should be */
193     verify_package ();
194 
195     /* Make sure the save directory exists */
196     check_savedir ();
197 
198     /* Load preferences */
199     load_lincityrc ();
200 
201 #ifndef CS_PROFILE
202 #ifdef SEED_RAND
203     srand (time (0));
204 #endif
205 #endif
206 
207 #ifdef LC_X11
208 #if defined (commentout)
209     borderx = 0;
210     bordery = 0;
211     parse_xargs (argc, argv, &geometry);
212 #endif
213     Create_Window (geometry);
214     pirate_cursor = XCreateFontCursor (display.dpy, XC_pirate);
215 #elif defined (WIN32)
216     /* Deal with all outstanding messages */
217     ProcessPendingEvents ();
218 #else
219     parse_args (argc, argv);
220     q = vga_setmode (G640x480x256);
221     gl_setcontextvga (G640x480x256);
222 #endif
223 
224 #if defined (WIN32) || defined (LC_X11)
225     initialize_pixmap ();
226 #endif
227 
228     init_fonts ();
229 
230 #if defined (SKIP_OPENING_SCENE)
231     skip_splash_screen = 1;
232 #endif
233     if (!skip_splash_screen) {
234 	load_start_image ();
235     }
236 
237 #ifdef LC_X11
238     unlock_window_size ();
239 #endif
240 
241     Fgl_setfont (8, 8, main_font);
242     Fgl_setfontcolors (TEXT_BG_COLOUR, TEXT_FG_COLOUR);
243 
244     initialize_geometry (&scr);
245 
246 #if defined (SVGALIB)
247     set_vga_mode ();
248 #endif
249 
250     initialize_monthgraph ();
251     init_mouse_registry ();
252     init_mini_map_mouse ();
253     mps_init();
254 
255 #ifdef LC_X11
256     x_key_value = 0;
257 #elif defined (WIN32)
258     RefreshScreen ();
259 #endif
260     setcustompalette ();
261     draw_background ();
262     prog_box (_("Loading the game"), 1);
263     init_types ();
264     init_modules();
265     init_mappoint_array ();
266     initialize_tax_rates ();
267     prog_box ("", 95);
268     mouse_hide_count = 0;
269     suppress_ok_buttons = 0;
270     prog_box ("", 100);
271 #ifdef USE_PIXMAPS
272     prog_box (_("Creating pixmaps"), 1);
273     init_pixmaps ();
274     prog_box ("", 100);
275 #endif
276     //draw_normal_mouse (1, 1);
277 #if defined (LC_X11)
278     init_x_mouse ();
279 #endif
280     init_timer_buttons();
281     mouse_initialized = 1;
282     //set_selected_module (CST_TRACK_LR);
283     screen_setup ();
284 
285     /* Main loop! */
286     client_main_loop ();
287 
288 #if defined (SVGALIB)
289     mouse_close ();
290     vga_setmode (TEXT);
291 #endif
292 
293     print_results ();
294 
295 #if defined (WIN32) || defined (LC_X11)
296     free_pixmap ();
297 #endif
298 
299 #if defined (WIN32)
300     return 0;
301 #else
302     exit (0);
303 #endif
304 }
305 
306 void
client_main_loop(void)307 client_main_loop (void)
308 {
309     int quit = 0;
310 
311     /* Set up the game */
312     reset_start_time ();
313 
314     update_avail_modules (0);
315 
316     screen_full_refresh ();
317 
318     if (no_init_help == 0) {
319 	block_help_exit = 1;
320 	help_flag = 1;
321 #if defined (commentout)
322 	if (make_dir_ok_flag) {
323 	    activate_help ("ask-dir.hlp");
324 	    make_dir_ok_flag = 0;
325 	} else {
326 	    activate_help ("opening.hlp");
327 	}
328 #endif
329 	activate_help ("opening.hlp");
330     }
331 
332     /* Set speed */
333 #if defined (CS_PROFILE) || defined (START_FAST_SPEED)
334     select_fast ();
335 #else
336     select_medium ();
337 #endif
338     /* Main Loop */
339     do {
340 	int key;
341 
342 	/* Get timestamp for this iteration */
343 	get_real_time();
344 
345 	/* Process events */
346 #if defined (LC_X11)
347 	call_event ();
348 	key = x_key_value;
349 	x_key_value = 0;
350 #elif defined (WIN32)
351 	call_event ();
352 	key = GetKeystroke ();
353 #else
354 	mouse_update ();
355 	key = vga_getkey ();
356 #endif
357 	/* nothing happened if key == 0 XXX: right? */
358 	/* GCS: I'm not sure */
359 	if (key != 0) {
360             process_keystrokes (key);
361 	}
362 	/* Simulate the timestep */
363 	quit = execute_timestep ();
364     } while (quit == 0);
365 }
366 
367 void
process_keystrokes(int key)368 process_keystrokes (int key)
369 {
370 
371 #if defined (commentout)	/* KBR 10/14/2002 - Cleanup MSVC warning */
372     int retval;
373 #endif
374 
375     switch (key)
376     {
377     case 0: printf("dead!"); return;
378     case ' ':   /* Space */
379     case 10:    /* Linefeed/Return */
380     case 13:    /* Enter */
381     case 127:   /* Backspace */
382 	if (key == 127) {
383 	    cs_mouse_handler (LC_MOUSE_RIGHTBUTTON | LC_MOUSE_PRESS,
384 			      0, 0);
385 	    cs_mouse_handler (LC_MOUSE_RIGHTBUTTON | LC_MOUSE_RELEASE,
386 			      0, 0);
387 	} else {
388 	    cs_mouse_handler (LC_MOUSE_LEFTBUTTON | LC_MOUSE_PRESS,
389 			      0, 0);
390 	    cs_mouse_handler (LC_MOUSE_LEFTBUTTON | LC_MOUSE_RELEASE,
391 			      0, 0);
392 	}
393 	if (help_flag) {
394 	    draw_help_page ("return-2");
395 	}
396 	if (prefs_flag) {
397 	    close_prefs_screen ();
398 	    refresh_main_screen ();
399 	}
400 	break;
401 
402 #if defined (SVGALIB)
403     case 91:
404 	{
405 	    int w = vga_getkey ();
406 	    switch (w)
407 	    {
408 	    case ('A'):
409 		cs_mouse_handler (0, 0, -kmouse_val);
410 		break;
411 	    case ('B'):
412 		cs_mouse_handler (0, 0, kmouse_val);
413 		break;
414 	    case ('C'):
415 		cs_mouse_handler (0, kmouse_val, 0);
416 		break;
417 	    case ('D'):
418 		cs_mouse_handler (0, -kmouse_val, 0);
419 		break;
420 	    }
421 	}
422 	break;
423 #endif
424 
425 #if defined (WIN32) || defined (LC_X11)
426     case 1:
427 	/* Scroll left */
428 	if (x_key_shifted) {
429 	    adjust_main_origin (main_screen_originx - RIGHT_MOUSE_MOVE_VAL,
430 				main_screen_originy,
431 				TRUE);
432 	} else {
433 	    adjust_main_origin (main_screen_originx - 1,
434 				main_screen_originy,
435 				TRUE);
436 	}
437 	break;
438 
439     case 2:
440 	/* Scroll down */
441 	if (x_key_shifted) {
442 	    adjust_main_origin (main_screen_originx,
443 				main_screen_originy + RIGHT_MOUSE_MOVE_VAL,
444 				TRUE);
445 	} else {
446 	    adjust_main_origin (main_screen_originx,
447 				main_screen_originy + 1,
448 				TRUE);
449 	}
450 	break;
451 
452     case 3:
453 	/* Scroll up */
454 	if (x_key_shifted) {
455 	    adjust_main_origin (main_screen_originx,
456 				main_screen_originy - RIGHT_MOUSE_MOVE_VAL,
457 				TRUE);
458 	} else {
459 	    adjust_main_origin (main_screen_originx,
460 				main_screen_originy - 1,
461 				TRUE);
462 	}
463 	break;
464 
465     case 4:
466 	/* Scroll right */
467 	if (x_key_shifted) {
468 	    adjust_main_origin (main_screen_originx + RIGHT_MOUSE_MOVE_VAL,
469 				main_screen_originy,
470 				TRUE);
471 	} else {
472 	    adjust_main_origin (main_screen_originx + 1,
473 				main_screen_originy,
474 				TRUE);
475 	}
476 	break;
477 #endif
478 
479     case 'P':
480     case 'p':
481 	select_pause ();
482 	break;
483 
484 #ifdef DEBUG_KEYS
485     case 'e':
486 	if (cheat () != 0)
487 	    people_pool += 100;
488 	break;
489 
490     case 'd':
491 	if (cheat () != 0)
492 	    dump_screen ();
493 	break;
494 
495     case 'D':
496 	/*	dump_tcore (); */
497 	break;
498 
499     case 't':
500 	if (cheat () != 0)
501 	    tech_level += 1000;
502 	break;
503 
504     case 'T':
505 	if (cheat () != 0)
506 	    tech_level += 10000;
507 	break;
508 
509     case 'm':
510 	if (cheat () != 0)
511 	    adjust_money(1000000);
512 	break;
513 #endif
514 
515     case 'f':
516 	do_random_fire (-1, -1, 1);
517 	break;
518 
519     case 'L':
520     case 'l':
521 	load_flag = 1;
522 	break;
523 
524     case 'H':
525     case 'h':
526 	activate_help ("index.hlp");
527 	break;
528 
529 	/* Escape Key */
530 #ifdef LC_X11
531     case 27:
532 #else
533     case 5:
534 #endif
535 	if (help_flag) {
536 	    /* exit help */
537 	    draw_help_page("return-2");
538 	} else if (prefs_flag) {
539 	    close_prefs_screen();
540 	    refresh_main_screen ();
541 	} else {
542 	    activate_help ("menu.hlp");
543 	}
544 	break;
545 
546     case 'S':
547     case 's':
548 	save_flag = 1;
549 	break;
550 
551     case 'v':
552     case 'V':
553 	/* Toggle overlay */
554 	rotate_main_screen();
555 	break;
556 
557     case 'o':
558     case 'O':
559 	prefs_flag = 1;
560 	break;
561 
562     case 'r':
563         window_results();
564 	break;
565 
566     case 'q':
567     case 'Q':
568 	quit_flag = 1;
569 	break;
570 
571     } /* end switch on keystroke */
572 }
573 
574 /* The "guts" of main loop is here. */
575 int
execute_timestep(void)576 execute_timestep (void)
577 {
578     static int next_time_step = 0;
579     int real_quit_flag = 0;
580 
581     if (market_cb_flag == 0 && help_flag == 0
582 	&& port_cb_flag == 0 && prefs_flag == 0)
583     {
584 
585 	if ((real_time < next_time_step || pause_flag || mt_flag)
586 	    && save_flag == 0 && load_flag == 0)
587 	{
588 	    if ((let_one_through == 0) || mt_flag)
589 	    {
590 		lc_usleep (1);
591 		return 0;
592 	    }
593 	    else
594 		let_one_through = 0;
595 	}
596 
597 	if (slow_flag)
598 	    next_time_step = real_time + (SLOW_TIME_FOR_YEAR
599 					  * 1000 / NUMOF_DAYS_IN_YEAR);
600 	else if (fast_flag)
601 	    next_time_step = real_time + (FAST_TIME_FOR_YEAR
602 					  * 1000 / NUMOF_DAYS_IN_YEAR);
603 	else if (med_flag)
604 	    next_time_step = real_time + (MED_TIME_FOR_YEAR
605 					  * 1000 / NUMOF_DAYS_IN_YEAR);
606 
607 	do_time_step ();
608 
609 #ifdef CS_PROFILE
610 	if (--prof_countdown <= 0)
611 	    real_quit_flag = 1;
612 #endif
613 
614 	update_main_screen (0);
615 
616 	/* XXX: Shouldn't the rest be handled in update_main_screen()? */
617 	/* GCS: No, I don't think so.  These remaining items are
618 		outside of the main screen */
619 
620 	print_stats ();
621 
622 	if (market_cb_flag)
623 	    draw_market_cb ();
624 	else if (port_cb_flag)	/* else- can't have both */
625 	    draw_port_cb ();
626     }
627     else /* if game is "stalled" */
628     {
629 	if (market_cb_flag != 0 && market_cb_drawn_flag == 0)
630 	    draw_market_cb ();
631 	if (port_cb_flag != 0 && port_cb_drawn_flag == 0)
632 	    draw_port_cb ();
633 #if defined (SVGALIB)
634 	mouse_update ();
635 #endif
636     }
637 
638 #if defined (NETWORK_ENABLE)
639     if (network_flag != 0) {
640 	do_network_screen ();
641 	network_flag = 0;
642 	let_one_through = 1;	/* if we are paused we need */
643     }			        /* this to redraw the screen */
644 #endif
645 
646     if (prefs_flag != 0 && prefs_drawn_flag == 0) {
647 	do_prefs_screen ();
648 	let_one_through = 1;	/* if we are paused we need */
649     }			        /* this to redraw the screen */
650 
651     if (load_flag != 0) {
652 #if defined (WIN32)
653 	DisableWindowsMenuItems ();
654 #endif
655 	if (help_flag == 0)	/* block loading when in help */
656 	    do_load_city ();
657 	load_flag = 0;
658 	let_one_through = 1;	/* if we are paused we need */
659     }			        /* this to redraw the screen */
660 
661     else if (save_flag != 0) {
662 #if defined (WIN32)
663 	DisableWindowsMenuItems ();
664 #endif
665 	if (help_flag == 0)
666 	    do_save_city ();
667 	save_flag = 0;
668 	let_one_through = 1;
669     }
670 
671     else if (quit_flag != 0) {
672 #if defined (WIN32)
673 	DisableWindowsMenuItems ();
674 #endif
675 	if (yn_dial_box (_("Quit The Game?")
676 			 ,_("Do you really want to quit?")
677 			 ,_("If you want to save the game select NO.")
678 			 ,""     /* GCS: This can't be translated!. */
679 			 ) != 0)
680 	    real_quit_flag = 1;
681 	else
682 	    quit_flag = 0;
683     }
684 
685     if (help_flag != 0)
686 	lc_usleep (1);
687 
688 #if defined (commentout)
689     if (make_dir_ok_flag)
690 	make_savedir ();	/* sorry a bit crude :( */
691 #endif
692     return real_quit_flag;
693 }
694 
695 void
do_error(char * s)696 do_error (char *s)
697 {
698 #if defined (LC_X11) || defined (WIN32)
699     HandleError (s, FATAL);
700 #else
701     vga_setmode (TEXT);
702     printf ("%s\n", s);
703     exit (1);
704 #endif
705 }
706 
707 int
cheat(void)708 cheat (void)
709 {
710     if (cheat_flag != 0)
711 	return (1);
712     /* TRANSLATORS: Test mode is like using "cheat codes" */
713     if (yn_dial_box (_("TEST"), _("You have pressed a test key"),
714 		     _("You will only see this message once"),
715 		     _("Do you really want to play in test mode..."))!= 0)
716     {
717 	cheat_flag = 1;
718 	print_time_for_year(); /* Displays TEST MODE or not */
719 	return (1);
720     }
721     return (0);
722 }
723 
724 int
compile_results(void)725 compile_results (void)
726 {
727     char *s;
728     FILE *outf;
729     int group_count[NUM_OF_GROUPS];
730 
731     if ((s = (char *) malloc (lc_save_dir_len + strlen (LC_SAVE_DIR)
732 			      + strlen (RESULTS_FILENAME) + 64)) == 0)
733 	malloc_failure ();
734 
735     sprintf (s, "%s%c%s", lc_save_dir, PATH_SLASH, RESULTS_FILENAME);
736 
737     count_all_groups (group_count);
738     if ((outf = fopen (s, "w")) == 0)
739     {
740 	printf (_("Unable to open %s\n"), RESULTS_FILENAME);
741 	free (s);
742 	return (0);
743     }
744     if (cheat_flag)
745 	fprintf (outf, _("----- IN TEST MODE -------\n"));
746     fprintf (outf, _("Game statistics from LinCity Version %s\n"), VERSION);
747     if (strlen (given_scene) > 3)
748 	fprintf (outf, _("Initial loaded scene - %s\n"), given_scene);
749     if (sustain_flag)
750 	fprintf (outf, _("Economy is sustainable\n"));
751     fprintf (outf, _("Population  %d  of which  %d  are not housed.\n")
752 	     ,housed_population + people_pool, people_pool);
753     fprintf (outf,
754 	     _("Max population %d  Number evacuated %d Total births %d\n")
755 	     ,max_pop_ever, total_evacuated, total_births);
756     fprintf (outf,
757 	     _(" Date  %s %04d   Money %8d   Tech-level %5.1f (%5.1f)\n"),
758 	     current_month(total_time), current_year(total_time), total_money,
759 	     (float) tech_level * 100.0 / MAX_TECH_LEVEL,
760 	     (float) highest_tech_level * 100.0 / MAX_TECH_LEVEL);
761     fprintf (outf,
762 	     _(" Deaths by starvation %7d   History %8.3f\n"),
763 	     total_starve_deaths, starve_deaths_history);
764     fprintf (outf,
765 	     _("Deaths from pollution %7d   History %8.3f\n"),
766 	     total_pollution_deaths, pollution_deaths_history);
767     fprintf (outf, _("Years of unemployment %7d   History %8.3f\n"),
768 	     total_unemployed_years, unemployed_history);
769     fprintf (outf, _("Rockets launched %2d  Successful launches %2d\n"),
770 	     rockets_launched, rockets_launched_success);
771     fprintf (outf, "\n");
772     fprintf (outf, _("    Residences %4d         Markets %4d            Farms %4d\n"),
773 	     group_count[GROUP_RESIDENCE_LL] +
774 	     group_count[GROUP_RESIDENCE_ML] +
775 	     group_count[GROUP_RESIDENCE_HL] +
776 	     group_count[GROUP_RESIDENCE_LH] +
777 	     group_count[GROUP_RESIDENCE_MH] +
778 	     group_count[GROUP_RESIDENCE_HH],
779 	     group_count[GROUP_MARKET],
780 	     group_count[GROUP_ORGANIC_FARM]);
781     fprintf (outf, _("        Tracks %4d           Roads %4d             Rail %4d\n")
782 	     ,group_count[GROUP_TRACK], group_count[GROUP_ROAD]
783 	     ,group_count[GROUP_RAIL]);
784     fprintf (outf, _("     Potteries %4d     Blacksmiths %4d            Mills %4d\n")
785 	     ,group_count[GROUP_POTTERY], group_count[GROUP_BLACKSMITH]
786 	     ,group_count[GROUP_MILL]);
787     fprintf (outf, _("     Monuments %4d         Schools %4d     Universities %4d\n")
788 	     ,group_count[GROUP_MONUMENT], group_count[GROUP_SCHOOL]
789 	     ,group_count[GROUP_UNIVERSITY]);
790     fprintf (outf, _(" Fire stations %4d           Parks %4d     Cricket gnds %4d\n")
791 	     ,group_count[GROUP_FIRESTATION], group_count[GROUP_PARKLAND]
792 	     ,group_count[GROUP_CRICKET]);
793     fprintf (outf, _("    Coal mines %4d       Ore mines %4d         Communes %4d\n")
794 	     ,group_count[GROUP_COALMINE], group_count[GROUP_OREMINE]
795 	     ,group_count[GROUP_COMMUNE]);
796     fprintf (outf, _("     Windmills %4d     Coal powers %4d     Solar powers %4d\n"),
797 	     group_count[GROUP_WINDMILL],
798 	     group_count[GROUP_COAL_POWER],
799 	     group_count[GROUP_SOLAR_POWER]);
800     fprintf (outf, _("   Substations %4d     Power lines %4d            Ports %4d\n")
801 	     ,group_count[GROUP_SUBSTATION], group_count[GROUP_POWER_LINE]
802 	     ,group_count[GROUP_PORT]);
803     fprintf (outf, _("    Light inds %4d      Heavy inds %4d        Recyclers %4d\n")
804 	     ,group_count[GROUP_INDUSTRY_L], group_count[GROUP_INDUSTRY_H]
805 	     ,group_count[GROUP_RECYCLE]);
806     fprintf (outf, _("Health centres %4d            Tips %4d         Shanties %4d\n"),
807 	     group_count[GROUP_HEALTH], group_count[GROUP_TIP],
808 	     group_count[GROUP_SHANTY]);
809     fclose (outf);
810     free (s);
811     return (1);
812 }
813 
814 
815 void
print_results(void)816 print_results (void)
817 {
818 #if !defined (WIN32)		/* GCS FIX: How should I do this? */
819     char *s;
820     if (compile_results () == 0)
821 	return;
822     if ((s = (char *) malloc (lc_save_dir_len + strlen (LC_SAVE_DIR)
823 			      + strlen (RESULTS_FILENAME) + 64)) == 0)
824 	malloc_failure ();
825 
826     strcpy (s, "cat ");
827     strcat (s, lc_save_dir);
828     strcat (s, "/");
829     strcat (s, RESULTS_FILENAME);
830     printf ("\n");
831     system (s);
832     printf ("\n");
833 #endif
834 }
835 
836 #if defined (commentout)
mail_results(void)837 void mail_results(void)
838 {
839     char s[256];
840     if (compile_results()==0)
841 	return;
842     strcpy(s,"mail -s 'LinCity results' lc-results@floot.demon.co.uk < ");
843     strcat(s,getenv("HOME"));
844     strcat(s,"/");
845     strcat(s,LC_SAVE_DIR);
846     strcat(s,"/");
847     strcat(s,RESULTS_FILENAME);
848     system(s);
849 }
850 #endif
851 
852 void
window_results(void)853 window_results (void)
854 {
855     char *s;
856     if (compile_results () == 0)
857 	return;
858     if ((s = (char *) malloc (lc_save_dir_len + strlen (LC_SAVE_DIR)
859 			      + strlen (RESULTS_FILENAME) + 64)) == 0)
860 	malloc_failure ();
861     sprintf (s, "%s%c%s", lc_save_dir, PATH_SLASH, RESULTS_FILENAME);
862     ok_dial_box (s, RESULTS, 0L);
863 }
864 
865