|
|
1.1 root 1: /* sim.c
2: *
3: * Micropolis, Unix Version. This game was released for the Unix platform
4: * in or about 1990 and has been modified for inclusion in the One Laptop
5: * Per Child program. Copyright (C) 1989 - 2007 Electronic Arts Inc. If
6: * you need assistance with this program, you may contact:
7: * http://wiki.laptop.org/go/Micropolis or email [email protected].
8: *
9: * This program is free software: you can redistribute it and/or modify
10: * it under the terms of the GNU General Public License as published by
11: * the Free Software Foundation, either version 3 of the License, or (at
12: * your option) any later version.
13: *
14: * This program is distributed in the hope that it will be useful, but
15: * WITHOUT ANY WARRANTY; without even the implied warranty of
16: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17: * General Public License for more details. You should have received a
18: * copy of the GNU General Public License along with this program. If
19: * not, see <http://www.gnu.org/licenses/>.
20: *
21: * ADDITIONAL TERMS per GNU GPL Section 7
22: *
23: * No trademark or publicity rights are granted. This license does NOT
24: * give you any right, title or interest in the trademark SimCity or any
25: * other Electronic Arts trademark. You may not distribute any
26: * modification of this program using the trademark SimCity or claim any
27: * affliation or association with Electronic Arts Inc. or its employees.
28: *
29: * Any propagation or conveyance of this program must include this
30: * copyright notice and these terms.
31: *
32: * If you convey this program (or any modifications of it) and assume
33: * contractual liability for the program to recipients of it, you agree
34: * to indemnify Electronic Arts for any liability that those contractual
35: * assumptions impose on Electronic Arts.
36: *
37: * You may not misrepresent the origins of this program; modified
38: * versions of the program must be marked as such and not identified as
39: * the original program.
40: *
41: * This disclaimer supplements the one included in the General Public
42: * License. TO THE FULLEST EXTENT PERMISSIBLE UNDER APPLICABLE LAW, THIS
43: * PROGRAM IS PROVIDED TO YOU "AS IS," WITH ALL FAULTS, WITHOUT WARRANTY
44: * OF ANY KIND, AND YOUR USE IS AT YOUR SOLE RISK. THE ENTIRE RISK OF
45: * SATISFACTORY QUALITY AND PERFORMANCE RESIDES WITH YOU. ELECTRONIC ARTS
46: * DISCLAIMS ANY AND ALL EXPRESS, IMPLIED OR STATUTORY WARRANTIES,
47: * INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY, SATISFACTORY QUALITY,
48: * FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT OF THIRD PARTY
49: * RIGHTS, AND WARRANTIES (IF ANY) ARISING FROM A COURSE OF DEALING,
50: * USAGE, OR TRADE PRACTICE. ELECTRONIC ARTS DOES NOT WARRANT AGAINST
51: * INTERFERENCE WITH YOUR ENJOYMENT OF THE PROGRAM; THAT THE PROGRAM WILL
52: * MEET YOUR REQUIREMENTS; THAT OPERATION OF THE PROGRAM WILL BE
53: * UNINTERRUPTED OR ERROR-FREE, OR THAT THE PROGRAM WILL BE COMPATIBLE
54: * WITH THIRD PARTY SOFTWARE OR THAT ANY ERRORS IN THE PROGRAM WILL BE
55: * CORRECTED. NO ORAL OR WRITTEN ADVICE PROVIDED BY ELECTRONIC ARTS OR
56: * ANY AUTHORIZED REPRESENTATIVE SHALL CREATE A WARRANTY. SOME
57: * JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF OR LIMITATIONS ON IMPLIED
58: * WARRANTIES OR THE LIMITATIONS ON THE APPLICABLE STATUTORY RIGHTS OF A
59: * CONSUMER, SO SOME OR ALL OF THE ABOVE EXCLUSIONS AND LIMITATIONS MAY
60: * NOT APPLY TO YOU.
61: */
62: #include "sim.h"
63:
64:
65: /* Sim City */
66:
67: char *MicropolisVersion = "4.0";
68: Sim *sim = NULL;
69: int sim_loops = 0;
70: int sim_delay = 50;
71: int sim_skips = 0;
72: int sim_skip = 0;
73: int sim_paused = 0;
74: int sim_paused_speed = 3;
75: int sim_tty = 0;
76: #ifdef CAM
77: int sim_just_cam = 0;
78: #endif
79: int heat_steps = 0;
80: int heat_flow = -7;
81: int heat_rule = 0;
82: int heat_wrap = 3;
83: struct timeval start_time, now_time, beat_time, last_now_time;
84: char *CityFileName = NULL;
85: int Startup = 0;
86: int StartupGameLevel = 0;
87: char *StartupName = NULL;
88: int WireMode = 0;
89: int MultiPlayerMode = 0;
90: int SugarMode = 0;
91: int TilesAnimated = 0;
92: int DoAnimation = 1;
93: int DoMessages = 1;
94: int DoNotices = 1;
95: char *Displays = NULL;
96: char *FirstDisplay = NULL;
97: int ExitReturn = 0;
98:
99:
100: sim_exit(int val)
101: {
102: tkMustExit = 1;
103: ExitReturn = val;
104: }
105:
106:
107: sim_really_exit(int val)
108: {
109: DoStopMicropolis();
110:
111: exit(val);
112: }
113:
114:
115: #define COPY(FROM, TO) \
116: TO = ckalloc(strlen(FROM) + 1); \
117: strcpy(TO, FROM);
118:
119:
120: #define TESTDIR(DIR, NAME) \
121: if ((stat(DIR, &statbuf) == -1) || \
122: !(S_ISDIR(statbuf.st_mode))) { \
123: fprintf(stderr, \
124: "Can't find the directory \"%s\"!\n", DIR); \
125: fprintf(stderr, \
126: "The environment variable \"%s\" should name a directory.\n", \
127: NAME); \
128: lost = 1; \
129: }
130:
131:
132: void
133: env_init(void)
134: {
135: char dir[256];
136: char *s;
137: struct stat statbuf;
138: int lost = 0;
139:
140: if ((s = getenv("SIMHOME")) == NULL) {
141: s = ".";
142: }
143: COPY(s, HomeDir);
144: TESTDIR(HomeDir, "$SIMHOME");
145:
146: sprintf(dir, "%s/res/", HomeDir);
147: COPY(dir, ResourceDir);
148: TESTDIR(ResourceDir, "$SIMHOME/res");
149:
150: { extern char *TCL_Library, *TK_Library;
151: TCL_Library = TK_Library = ResourceDir;
152: }
153:
154: if (lost) {
155: fprintf(stderr,
156: "Please check the environment or reinstall Micropolis and try again! Sorry!\n");
157: sim_exit(1); // Just sets tkMustExit and ExitReturn
158: return;
159: }
160:
161: gettimeofday(&now_time, NULL);
162: last_now_time = now_time;
163: }
164:
165:
166: void
167: sim_init(void)
168: {
169: gettimeofday(&start_time, NULL);
170: gettimeofday(&beat_time, NULL);
171:
172: signal_init();
173:
174: UserSoundOn = 1;
175: MustUpdateOptions = 1;
176: HaveLastMessage = 0;
177: ScenarioID = 0;
178: StartingYear = 1900;
179: tileSynch = 0x01;
180: sim_skips = sim_skip = 0;
181: autoGo = 1;
182: CityTax = 7;
183: CityTime = 50;
184: NoDisasters = 0;
185: PunishCnt = 0;
186: autoBulldoze = 1;
187: autoBudget = 1;
188: MesNum = 0;
189: LastMesTime = 0;
190: flagBlink = 1;
191: SimSpeed = 3;
192: ChangeEval();
193: MessagePort = 0;
194: MesX = 0;
195: MesY = 0;
196: sim_paused = 0;
197: sim_loops = 0;
198: InitSimLoad = 2;
199: tkMustExit = 0;
200: ExitReturn = 0;
201:
202: InitializeSound();
203: initMapArrays();
204: initGraphs();
205: InitFundingLevel();
206: #if 0
207: loadObjectData();
208: #endif
209: setUpMapProcs();
210: StopEarthquake();
211: ResetMapState();
212: ResetEditorState();
213: ClearMap();
214: InitWillStuff();
215: SetFunds(5000);
216: SetGameLevelFunds(StartupGameLevel);
217: setSpeed(0);
218: setSkips(0);
219: }
220:
221:
222: int triedToBailOnce = 0;
223:
224: void
225: SignalExitHandler()
226: {
227: if (triedToBailOnce) {
228: exit(-1);
229: } else {
230: triedToBailOnce = 1;
231: fprintf(stderr, "\nMicropolis has been terminated by a signal.\n");
232: fprintf(stderr, "Pick a window -- you're leaving!\n\n");
233: fflush(stderr);
234: sim_really_exit(-1);
235: }
236: }
237:
238:
239: signal_init()
240: {
241: signal(SIGHUP, (void (*)())SignalExitHandler);
242: signal(SIGINT, (void (*)())SignalExitHandler);
243: signal(SIGQUIT, (void (*)())SignalExitHandler);
244: signal(SIGTERM, (void (*)())SignalExitHandler);
245: }
246:
247:
248: void
249: sim_update()
250: {
251: gettimeofday(&now_time, NULL);
252:
253: flagBlink = (now_time.tv_usec < 500000) ? 1 : -1;
254:
255: if (SimSpeed && !heat_steps) {
256: TilesAnimated = 0;
257: }
258:
259: sim_update_editors();
260:
261: sim_update_maps();
262: sim_update_graphs();
263: sim_update_budgets();
264: sim_update_evaluations();
265:
266: UpdateFlush();
267: }
268:
269:
270: sim_update_editors(void)
271: {
272: SimView *view;
273:
274: for (view = sim->editor; view != NULL; view = view->next) {
275: #if 1
276: CancelRedrawView(view);
277: view->invalid = 1;
278: DoUpdateEditor(view);
279: #else
280: EventuallyRedrawView(view);
281: #endif
282: }
283:
284: DoUpdateHeads();
285: }
286:
287:
288: sim_update_maps(void)
289: {
290: SimView *view;
291: int i;
292:
293: for (view = sim->map; view != NULL; view = view->next) {
294: int mustUpdateMap =
295: NewMapFlags[view->map_state] || NewMap || ShakeNow;
296: if (mustUpdateMap) {
297: view->invalid = 1;
298: }
299: if (view->invalid) {
300: #if 1
301: if (mustUpdateMap) {
302: //fprintf(stderr, "sim_update_maps mustUpdateMap\n");
303: // view->skip = 0;
304: }
305: if (DoUpdateMap(view)) {
306: // CancelRedrawView(view);
307: // view->invalid = 1;
308: }
309: #else
310: EventuallyRedrawView(view);
311: #endif
312: }
313: }
314:
315: NewMap = 0;
316: for (i = 0; i < NMAPS; i++) {
317: NewMapFlags[i] = 0;
318: }
319: }
320:
321:
322: sim_update_graphs(void)
323: {
324: graphDoer();
325: }
326:
327:
328: sim_update_budgets(void)
329: {
330: if ((sim_skips != 0) &&
331: (sim_skip != 0)) {
332: return;
333: }
334:
335: UpdateBudgetWindow();
336: }
337:
338:
339: sim_update_evaluations(void)
340: {
341: if ((sim_skips != 0) &&
342: (sim_skip != 0)) {
343: return;
344: }
345:
346: scoreDoer();
347: }
348:
349:
350: #ifdef CAM
351:
352: sim_update_cams(void)
353: {
354: SimCam *scam;
355:
356: if ((sim_skips != 0) &&
357: (sim_skip != 0)) {
358: return;
359: }
360:
361: for (scam = sim->scam; scam != NULL; scam = scam->next) {
362: CancelRedrawView(scam);
363: scam->invalid = 1;
364: handle_scam(scam);
365: }
366: }
367:
368: #endif /* CAM */
369:
370:
371: short *CellSrc = NULL;
372: short *CellDst = NULL;
373:
374: #define SRCCOL (WORLD_Y + 2)
375: #define DSTCOL WORLD_Y
376:
377: #define CLIPPER_LOOP_BODY(CODE) \
378: src = CellSrc; dst = CellDst; \
379: for (x = 0; x < WORLD_X;) { \
380: short nw, n, ne, w, c, e, sw, s, se; \
381: \
382: src = CellSrc + (x * SRCCOL); dst = CellDst + (x * DSTCOL); \
383: w = src[0]; c = src[SRCCOL]; e = src[2 * SRCCOL]; \
384: sw = src[1]; s = src[SRCCOL + 1]; se = src[(2 * SRCCOL) + 1]; \
385: \
386: for (y = 0; y < WORLD_Y; y++) { \
387: nw = w; w = sw; sw = src[2]; \
388: n = c; c = s; s = src[SRCCOL + 2]; \
389: ne = e; e = se; se = src[(2 * SRCCOL) + 2]; \
390: { CODE } \
391: src++; dst++; \
392: } \
393: x++; /* src += SRCCOL - 3; dst += DSTCOL - 1; */ \
394: src = CellSrc + ((x + 1) * SRCCOL) - 3; dst = CellDst + ((x + 1) * DSTCOL) - 1; \
395: \
396: nw = src[1]; n = src[SRCCOL + 1]; ne = src[(2 * SRCCOL) + 1]; \
397: w = src[2]; c = src[SRCCOL + 2]; e = src[(2 * SRCCOL) + 2]; \
398: \
399: for (y = WORLD_Y - 1; y >= 0; y--) { \
400: sw = w; w = nw; nw = src[0]; \
401: s = c; c = n; n = src[SRCCOL]; \
402: se = e; e = ne; ne = src[2 * SRCCOL]; \
403: { CODE } \
404: src--; dst--; \
405: } \
406: x++; /* src += SRCCOL + 3; dst += DSTCOL + 1; */ \
407: }
408:
409: void
410: sim_heat(void)
411: {
412: int x, y, l, r, u, d;
413: static int a = 0;
414: short *src, *dst;
415: register int fl = heat_flow;
416:
417: if (CellSrc == NULL) {
418: CellSrc = (short *)ckalloc((WORLD_X + 2) * (WORLD_Y + 2) * sizeof (short));
419: CellDst = &Map[0][0];
420: }
421:
422: src = CellSrc + SRCCOL + 1;
423: dst = CellDst;
424:
425: /*
426: * Copy wrapping edges:
427: *
428: * 0 ff f0 f1 ... fe ff f0
429: *
430: * 1 0f 00 01 ... 0e 0f 00
431: * 2 1f 10 11 ... 1e 1f 10
432: * .. .. .. .. .. ..
433: * ef e0 e1 ... ee ef e0
434: * h ff f0 f1 ... fe ff f0
435: *
436: * h+1 0f 00 01 ... 0e 0f 00
437: *
438: * wrap value: effect:
439: * 0 no effect
440: * 1 copy future=>past, no wrap
441: * 2 no copy, wrap edges
442: * 3 copy future=>past, wrap edges
443: * 4 copy future=>past, same edges
444: */
445:
446: switch (heat_wrap) {
447: case 0:
448: break;
449: case 1:
450: for (x = 0; x < WORLD_X; x++) {
451: memcpy(src, dst, WORLD_Y * sizeof (short));
452: src += SRCCOL;
453: dst += DSTCOL;
454: }
455: break;
456: case 2:
457: for (x = 0; x < WORLD_X; x++) {
458: src[-1] = src[WORLD_Y - 1];
459: src[WORLD_Y] = src[0];
460: src += SRCCOL;
461: dst += DSTCOL;
462: }
463: memcpy(CellSrc,CellSrc + (SRCCOL * WORLD_X),
464: SRCCOL * sizeof (short));
465: memcpy(CellSrc + SRCCOL * (WORLD_X + 1), CellSrc + SRCCOL,
466: SRCCOL * sizeof (short));
467: break;
468: case 3:
469: for (x = 0; x < WORLD_X; x++) {
470: memcpy(src, dst, WORLD_Y * sizeof (short));
471: src[-1] = src[WORLD_Y - 1];
472: src[WORLD_Y] = src[0];
473: src += SRCCOL;
474: dst += DSTCOL;
475: }
476: memcpy(CellSrc, CellSrc + (SRCCOL * WORLD_X),
477: SRCCOL * sizeof (short));
478: memcpy(CellSrc + SRCCOL * (WORLD_X + 1), CellSrc + SRCCOL,
479: SRCCOL * sizeof (short));
480: break;
481: case 4:
482: src[0] = dst[0];
483: src[1 + WORLD_Y] = dst[WORLD_Y - 1];
484: src[(1 + WORLD_X) * SRCCOL] = dst[(WORLD_X - 1) * DSTCOL];
485: src[((2 + WORLD_X) * SRCCOL) - 1] = dst[(WORLD_X * WORLD_Y) - 1];
486: for (x = 0; x < WORLD_X; x++) {
487: memcpy(src, dst, WORLD_Y * sizeof (short));
488: src[-1] = src[0];
489: src[WORLD_Y] = src[WORLD_Y - 1];
490: src += SRCCOL;
491: dst += DSTCOL;
492: }
493: memcpy(CellSrc + (SRCCOL * (WORLD_X + 1)), CellSrc + (SRCCOL * WORLD_X),
494: SRCCOL * sizeof (short));
495: memcpy(CellSrc, CellSrc + SRCCOL,
496: SRCCOL * sizeof (short));
497: break;
498: }
499:
500:
501: switch (heat_rule) {
502:
503: case 0:
504: #define HEAT \
505: a += nw + n + ne + w + e + sw + s + se + fl; \
506: dst[0] = ((a >> 3) & LOMASK) | \
507: (ANIMBIT | BURNBIT | BULLBIT); \
508: a &= 7;
509:
510: CLIPPER_LOOP_BODY(HEAT);
511: break;
512:
513: case 1:
514: #define ECOMASK 0x3fc
515: #define ECO \
516: c -= fl; n -= fl; s -= fl; e -= fl; w -= fl; \
517: ne -= fl; nw -= fl; se -= fl; sw -= fl; \
518: \
519: /* anneal */ \
520: { int sum = (c&1) + (n&1) + (s&1) + (e&1) + (w&1) + \
521: (ne&1) + (nw&1) + (se&1) + (sw&1), cell; \
522: if (((sum > 5) || (sum == 4))) { \
523: /* brian's brain */ \
524: cell = ((c <<1) & (0x3fc)) | \
525: (((((c >>1)&3) == 0) && \
526: (((n&2) + (s&2) + (e&2) + (w&2) + \
527: (ne&2) + (nw&2) + (se&2) + (sw&2)) == (2 <<1)) \
528: ) ? 2 : 0) | \
529: 1; \
530: } else { \
531: /* anti-life */ \
532: sum = ((n&2) + (s&2) + (e&2) + (w&2) + \
533: (ne&2) + (nw&2) + (se&2) + (sw&2)) >>1; \
534: cell = (((c ^ 2) <<1) & ECOMASK) | \
535: ((c&2) ? ((sum != 5) ? 2 : 0) \
536: : (((sum != 5) && (sum != 6)) ? 2 : 0)); \
537: } \
538: dst[0] = ((fl + cell) & LOMASK) | \
539: (ANIMBIT | BURNBIT | BULLBIT); \
540: } \
541: c += fl; n += fl; s += fl; e += fl; w += fl; \
542: ne += fl; nw += fl; se += fl; sw += fl;
543:
544: CLIPPER_LOOP_BODY(ECO);
545: break;
546: }
547: }
548:
549:
550: void
551: sim_timeout_loop(short doSim)
552: {
553: if (SimSpeed) {
554: sim_loop(doSim);
555: }
556: DoTimeoutListen();
557: }
558:
559:
560: sim_loop(int doSim)
561: {
562: #ifdef CAM
563: if (!sim_just_cam) {
564: #endif
565: if (heat_steps) {
566: int j;
567:
568: for (j = 0; j < heat_steps; j++) {
569: sim_heat();
570: }
571:
572: MoveObjects();
573: /*
574: InvalidateMaps();
575: */
576: NewMap = 1;
577: } else {
578: if (doSim) {
579: SimFrame();
580: }
581: MoveObjects();
582: }
583:
584: sim_loops++;
585: sim_update();
586: #ifdef CAM
587: } else {
588: sim_update_cams();
589: UpdateFlush();
590: DoTimeoutListen();
591: }
592: #endif
593: }
594:
595:
596: int
597: MatchArg(char *arg, char *pat)
598: {
599: while (*pat && *arg) {
600: if (tolower(*arg) != tolower(*pat)) {
601: if (*pat == '_') {
602: pat++;
603: continue;
604: }
605: return (0);
606: }
607: arg++; pat++;
608: }
609: return (*arg == '\0');
610: }
611:
612:
613: int
614: main(int argc, char *argv[])
615: {
616: int c, errflg = 0;
617: extern int isatty();
618:
619: printf("Welcome to X11 Multi Player Micropolis version %s by Will Wright, Don Hopkins.\n",
620: MicropolisVersion);
621: printf("Copyright (C) 2002 by Electronic Arts, Maxis. All rights reserved.\n");
622:
623: while (!errflg &&
624: !tkMustExit &&
625: (c = getopt(argc, argv, "tcwmSR:gs:l:")) != -1) {
626: switch (c) {
627:
628: case 't': /* TTY mode */
629: sim_tty = isatty(0);
630: break;
631:
632: case 'c': /* Create Own Colormap */
633: { extern int TK_CreateColormap;
634: TK_CreateColormap = 1;
635: }
636: break;
637:
638: case 'w': /* Wire Mode (don't use shared memory) */
639: WireMode = 1;
640: break;
641:
642: case 'm': /* Multi Player Mode */
643: MultiPlayerMode = 1;
644: break;
645:
646: case 'S': /* Sugar Mode */
647: SugarMode = 1;
648: break;
649:
650: case 'R': /* Root Window ID */
651: c = atoi(optarg);
652: if (c) {
653: tk_RootWindow = c;
654: } else {
655: errflg = 1;
656: }
657: break;
658:
659: case 'g': /* Generate New Terrain */
660: if (Startup) {
661: errflg = 1;
662: } else {
663: Startup = -1;
664: }
665: break;
666:
667: case 'l': /* Level */
668: c = atoi(optarg);
669: if (!c) {
670: if (MatchArg(optarg, "easy")) {
671: c = 1;
672: } else if (MatchArg(optarg, "medium")) {
673: c = 2;
674: } else if (MatchArg(optarg, "hard")) {
675: c = 3;
676: }
677: }
678: if ((c < 1) || (c > 3)) {
679: errflg = 1;
680: } else {
681: StartupGameLevel = c - 1;
682: }
683: break;
684:
685: case 's': /* Scenario <name> */
686: if (Startup)
687: errflg++;
688: else {
689: c = atoi(optarg);
690: if (!c) {
691: if (MatchArg(optarg, "Dullsville")) {
692: c = 1;
693: } else if (MatchArg(optarg, "San_Francisco")) {
694: c = 2;
695: } else if (MatchArg(optarg, "Hamburg")) {
696: c = 3;
697: } else if (MatchArg(optarg, "Bern")) {
698: c = 4;
699: } else if (MatchArg(optarg, "Tokyo")) {
700: c = 5;
701: } else if (MatchArg(optarg, "Detroit")) {
702: c = 6;
703: } else if (MatchArg(optarg, "Boston")) {
704: c = 7;
705: } else if (MatchArg(optarg, "Rio_de_Janeiro")) {
706: c = 8;
707: }
708: }
709: if ((c < 1) || (c > 8)) {
710: errflg = 1;
711: } else {
712: Startup = c;
713: }
714: }
715: break;
716:
717: case 'd': /* Display <name> */
718: { char *d = Displays;
719:
720: if (d == NULL) {
721: Displays = malloc(strlen(optarg) + 3);
722: sprintf(Displays, "{%s}", optarg);
723:
724: if (strchr(optarg, ':') != NULL) {
725: FirstDisplay = malloc(strlen(optarg) + 1);
726: strcpy(FirstDisplay, optarg);
727: } else {
728: FirstDisplay = malloc(strlen(optarg) + 3);
729: sprintf(FirstDisplay, "%s:0", optarg);
730: }
731: } else {
732: /* Implicitly set multi player mode if multiple displays given. */
733: MultiPlayerMode = 1;
734: Displays = malloc(strlen(Displays) + strlen(optarg) + 4);
735: sprintf(Displays, "%s {%s}", d, optarg);
736: free(d);
737: }
738: }
739: break;
740:
741: case '?':
742: errflg++;
743: break;
744: }
745: }
746:
747: if (!errflg &&
748: !tkMustExit) {
749: if ((Startup == -1) ||
750: (Startup == -2)) {
751: /* Generate New City */
752: if ((optind != argc) && (optind != argc - 1)) {
753: errflg = 1;
754: } else {
755: if (optind == argc - 1)
756: StartupName = argv[optind];
757: }
758: } else if (Startup > 0) {
759: /* Scenario */
760: } else if (optind == argc - 1) {
761: /* Load City */
762: Startup = -2;
763: StartupName = argv[optind];
764: } else if (optind == argc) {
765: /* No arguments */
766: } else {
767: errflg = 1;
768: }
769: }
770:
771: if (errflg) {
772: fprintf(stderr,
773: "usage: %s\n", argv[0]);
774: fprintf(stderr,
775: " [-s(cenario) number|name]\n");
776: fprintf(stderr,
777: " [-g(enerate random map and start playing)\n");
778: fprintf(stderr,
779: " [-l(evel) number|name]\n");
780: fprintf(stderr,
781: " [-w(ire mode: use X11 networking without shared memory)]\n");
782: fprintf(stderr,
783: " [-t(ty mode: interactive TCL session on stdin/stdout)]\n");
784: fprintf(stderr,
785: " [-c(olormap mode: create own X11 colormap on 8 bit screens)]\n");
786: fprintf(stderr,
787: " [-S(ugar mode: enable OLPC Sugar user interface integration)]\n");
788: fprintf(stderr,
789: " [-m(ulti player mode: enable adding multiple players via X11)]\n");
790: fprintf(stderr,
791: " [NewCityName]\n");
792: fprintf(stderr,
793: " [SavedFileName.city]\n");
794: fprintf(stderr,
795: "The game level and NewCityName argument are optional, and only apply when\n");
796: fprintf(stderr,
797: "starting a new city or generating new terrain.\n");
798: fprintf(stderr,
799: "Game levels include: 1: Easy, 2: Medium, 3: Hard\n");
800: fprintf(stderr,
801: "Scenarios include: 1: Dullsville, 2: San_Francisco, 3: Hamburg, 4: Bern,\n");
802: fprintf(stderr,
803: " 5: Tokyo, 6: Detroit, 7: Boston, 8: Rio_de_Janeiro\n");
804: fflush(stderr);
805: sim_exit(0); // Just sets tkMustExit and ExitReturn
806: }
807:
808: if ((!tkMustExit) &&
809: (Displays == NULL)) {
810: char *d = getenv("DISPLAY");
811:
812: if (d == NULL) d = ":0";
813:
814: Displays = malloc(strlen(d) + 3);
815: sprintf(Displays, "{%s}", d);
816: if (strchr(d, ':') != NULL) {
817: FirstDisplay = malloc(strlen(d) + 1);
818: strcpy(FirstDisplay, d);
819: } else {
820: FirstDisplay = malloc(strlen(d) + 3);
821: sprintf(FirstDisplay, "%s:0", d);
822: }
823: }
824:
825: if (!tkMustExit) {
826: env_init();
827: }
828:
829: if (!tkMustExit) {
830: tk_main();
831: }
832:
833: exit (ExitReturn);
834: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.