|
|
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.