Annotation of micropolis/src/sim/sim.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.