Annotation of micropolis/src/sim/s_fileio.c, revision 1.1.1.1

1.1       root        1: /* s_fileio.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: #if defined(MSDOS) || defined(OSF1) || defined(IS_INTEL)
                     66: 
                     67: #define SWAP_SHORTS(a,b)       _swap_shorts(a,b)
                     68: #define SWAP_LONGS(a,b)                _swap_longs(a,b)
                     69: #define HALF_SWAP_LONGS(a,b)   _half_swap_longs(a,b)
                     70: 
                     71: static void
                     72: _swap_shorts(short *buf, int len)
                     73: {
                     74:   int i;
                     75: 
                     76:   /* Flip bytes in each short! */
                     77:   for (i = 0; i < len; i++) {  
                     78:     *buf = ((*buf & 0xFF) <<8) | ((*buf &0xFF00) >>8);
                     79:     buf++;
                     80:   }
                     81: }
                     82: 
                     83: static void
                     84: _swap_longs(long *buf, int len)
                     85: {
                     86:   int i;
                     87: 
                     88:   /* Flip bytes in each long! */
                     89:   for (i = 0; i < len; i++) {  
                     90:     long l = *buf;
                     91:     *buf =
                     92:       ((l & 0x000000ff) << 24) |
                     93:       ((l & 0x0000ff00) << 8) |
                     94:       ((l & 0x00ff0000) >> 8) |
                     95:       ((l & 0xff000000) >> 24);
                     96:     buf++;
                     97:   }
                     98: }
                     99: 
                    100: static void
                    101: _half_swap_longs(long *buf, int len)
                    102: {
                    103:   int i;
                    104: 
                    105:   /* Flip bytes in each long! */
                    106:   for (i = 0; i < len; i++) {  
                    107:     long l = *buf;
                    108:     *buf =
                    109:       ((l & 0x0000ffff) << 16) |
                    110:       ((l & 0xffff0000) >> 16);
                    111:     buf++;
                    112:   }
                    113: }
                    114: 
                    115: #else
                    116: 
                    117: #define SWAP_SHORTS(a, b)
                    118: #define SWAP_LONGS(a, b)
                    119: #define HALF_SWAP_LONGS(a, b)
                    120: 
                    121: #endif
                    122: 
                    123: 
                    124: static int
                    125: _load_short(short *buf, int len, FILE *f)
                    126: {
                    127:   if (fread(buf, sizeof(short), len, f) != len)
                    128:      return 0;
                    129: 
                    130:   SWAP_SHORTS(buf, len);       /* to intel */
                    131: 
                    132:   return 1;
                    133: }
                    134: 
                    135: 
                    136: static int
                    137: _load_long(long *buf, int len, FILE *f)
                    138: {
                    139:   if (fread(buf, sizeof(long), len, f) != len)
                    140:      return 0;
                    141: 
                    142:   SWAP_LONGS(buf, len);        /* to intel */
                    143: 
                    144:   return 1;
                    145: }
                    146: 
                    147: 
                    148: static int
                    149: _save_short(short *buf, int len, FILE *f)
                    150: {
                    151: 
                    152:   SWAP_SHORTS(buf, len);       /* to MAC */
                    153: 
                    154:   if (fwrite(buf, sizeof(short), len, f) != len)
                    155:      return 0;
                    156: 
                    157:   SWAP_SHORTS(buf, len);       /* back to intel */
                    158: 
                    159:   return 1;
                    160: }
                    161: 
                    162: 
                    163: static int
                    164: _save_long(long *buf, int len, FILE *f)
                    165: {
                    166: 
                    167:   SWAP_LONGS(buf, len);        /* to MAC */
                    168: 
                    169:   if (fwrite(buf, sizeof(long), len, f) != len)
                    170:      return 0;
                    171: 
                    172:   SWAP_LONGS(buf, len);        /* back to intel */
                    173: 
                    174:   return 1;
                    175: }
                    176: 
                    177: 
                    178: static
                    179: int 
                    180: _load_file(char *filename, char *dir)
                    181: {
                    182:   FILE *f;
                    183:   char path[512];
                    184:   QUAD size;
                    185: 
                    186: #ifdef MSDOS
                    187:   if (dir != NULL) {
                    188:     sprintf(path, "%s\\%s", dir, filename);
                    189:     filename = path;
                    190:   }
                    191:   if ((f = fopen(filename, "rb")) == NULL) {
                    192:     return 0;
                    193:   }
                    194: #else
                    195:   if (dir != NULL) {
                    196:     sprintf(path, "%s/%s", dir, filename);
                    197:     filename = path;
                    198:   }
                    199:   if ((f = fopen(filename, "r")) == NULL) {
                    200:     return (0);
                    201:   }
                    202: #endif
                    203: 
                    204:   fseek(f, 0L, SEEK_END);
                    205:   size = ftell(f);
                    206:   fseek(f, 0L, SEEK_SET);
                    207: 
                    208:   switch (size) {
                    209:   case 27120: /* Normal city */
                    210:     break;
                    211: 
                    212:   case 99120: /* 2x2 city */
                    213:     break;
                    214: 
                    215:   case 219120: /* 3x3 city */
                    216:     break;
                    217: 
                    218:   default:
                    219:     return (0);
                    220:   }
                    221: 
                    222:   if ((_load_short(ResHis, HISTLEN / 2, f) == 0) ||
                    223:       (_load_short(ComHis, HISTLEN / 2, f) == 0) ||
                    224:       (_load_short(IndHis, HISTLEN / 2, f) == 0) ||
                    225:       (_load_short(CrimeHis, HISTLEN / 2, f) == 0) ||
                    226:       (_load_short(PollutionHis, HISTLEN / 2, f) == 0) ||
                    227:       (_load_short(MoneyHis, HISTLEN / 2, f) == 0) ||
                    228:       (_load_short(MiscHis, MISCHISTLEN / 2, f) == 0) ||
                    229:       (_load_short((&Map[0][0]), WORLD_X * WORLD_Y, f) < 0)) {
                    230: 
                    231:     /* TODO:  report error */
                    232:     fclose(f);
                    233:     return(0);
                    234:   }
                    235: 
                    236:   fclose(f);
                    237:   return(1);
                    238: }
                    239: 
                    240: 
                    241: int loadFile(char *filename)
                    242: {
                    243:   long l;
                    244: 
                    245:   if (_load_file(filename, NULL) == 0)
                    246:     return(0);
                    247: 
                    248:   /* total funds is a long.....    MiscHis is array of shorts */
                    249:   /* total funds is being put in the 50th & 51th word of MiscHis */
                    250:   /* find the address, cast the ptr to a lontPtr, take contents */
                    251: 
                    252:   l = *(QUAD *)(MiscHis + 50);
                    253:   HALF_SWAP_LONGS(&l, 1);
                    254:   SetFunds(l);
                    255: 
                    256:   l = *(QUAD *)(MiscHis + 8);
                    257:   HALF_SWAP_LONGS(&l, 1);
                    258:   CityTime = l;
                    259: 
                    260:   autoBulldoze = MiscHis[52];  /* flag for autoBulldoze */
                    261:   autoBudget = MiscHis[53];    /* flag for autoBudget */
                    262:   autoGo = MiscHis[54];                /* flag for autoGo */
                    263:   UserSoundOn = MiscHis[55];   /* flag for the sound on/off */
                    264:   CityTax = MiscHis[56];
                    265:   SimSpeed = MiscHis[57];
                    266:   //  sim_skips = sim_skip = 0;
                    267:   ChangeCensus();
                    268:   MustUpdateOptions = 1;
                    269: 
                    270:   /* yayaya */
                    271: 
                    272:   l = *(QUAD *)(MiscHis + 58);
                    273:   HALF_SWAP_LONGS(&l, 1);
                    274:   policePercent = l / 65536.0;
                    275: 
                    276:   l = *(QUAD *)(MiscHis + 60);
                    277:   HALF_SWAP_LONGS(&l, 1);
                    278:   firePercent = l / 65536.0;
                    279: 
                    280:   l = *(QUAD *)(MiscHis + 62);
                    281:   HALF_SWAP_LONGS(&l, 1);
                    282:   roadPercent = l / 65536.0;
                    283: 
                    284:   policePercent = (*(QUAD*)(MiscHis + 58)) / 65536.0;  /* and 59 */
                    285:   firePercent = (*(QUAD*)(MiscHis + 60)) / 65536.0;    /* and 61 */
                    286:   roadPercent =(*(QUAD*)(MiscHis + 62)) / 65536.0;     /* and 63 */
                    287: 
                    288:   if (CityTime < 0)
                    289:     CityTime = 0;
                    290:   if ((CityTax > 20) || (CityTax < 0))
                    291:     CityTax = 7;
                    292:   if ((SimSpeed < 0) || (SimSpeed > 3))
                    293:     SimSpeed = 3;
                    294: 
                    295:   setSpeed(SimSpeed);
                    296:   setSkips(0);
                    297: 
                    298:   InitFundingLevel();
                    299: 
                    300:   /* set the scenario id to 0 */
                    301:   InitWillStuff();
                    302:   ScenarioID = 0;
                    303:   InitSimLoad = 1;
                    304:   DoInitialEval = 0;
                    305:   DoSimInit();
                    306:   InvalidateEditors();
                    307:   InvalidateMaps();
                    308: 
                    309:   return (1);
                    310: }
                    311: 
                    312: 
                    313: int saveFile(char *filename)
                    314: {
                    315:   long l;
                    316:   FILE *f;
                    317: 
                    318: #ifdef MSDOS
                    319:   if ((f = fopen(filename, "wb")) == NULL) {
                    320: #else
                    321:   if ((f = fopen(filename, "w")) == NULL) {
                    322: #endif
                    323:     /* TODO: report error */
                    324:     return(0);
                    325:   }
                    326: 
                    327:   /* total funds is a long.....    MiscHis is array of ints */
                    328:   /* total funds is bien put in the 50th & 51th word of MiscHis */
                    329:   /* find the address, cast the ptr to a lontPtr, take contents */
                    330: 
                    331:   l = TotalFunds;
                    332:   HALF_SWAP_LONGS(&l, 1);
                    333:   (*(QUAD *)(MiscHis + 50)) = l;
                    334: 
                    335:   l = CityTime;
                    336:   HALF_SWAP_LONGS(&l, 1);
                    337:   (*(QUAD *)(MiscHis + 8)) = l;
                    338: 
                    339:   MiscHis[52] = autoBulldoze;  /* flag for autoBulldoze */
                    340:   MiscHis[53] = autoBudget;    /* flag for autoBudget */
                    341:   MiscHis[54] = autoGo;                /* flag for autoGo */
                    342:   MiscHis[55] = UserSoundOn;   /* flag for the sound on/off */
                    343:   MiscHis[57] = SimSpeed;
                    344:   MiscHis[56] = CityTax;       /* post release */
                    345: 
                    346:   /* yayaya */
                    347: 
                    348:   l = (int)(policePercent * 65536);
                    349:   HALF_SWAP_LONGS(&l, 1);
                    350:   (*(QUAD *)(MiscHis + 58)) = l;
                    351: 
                    352:   l = (int)(firePercent * 65536);
                    353:   HALF_SWAP_LONGS(&l, 1);
                    354:   (*(QUAD *)(MiscHis + 60)) = l;
                    355: 
                    356:   l = (int)(roadPercent * 65536);
                    357:   HALF_SWAP_LONGS(&l, 1);
                    358:   (*(QUAD *)(MiscHis + 62)) = l;
                    359: 
                    360:   if ((_save_short(ResHis, HISTLEN / 2, f) == 0) ||
                    361:       (_save_short(ComHis, HISTLEN / 2, f) == 0) ||
                    362:       (_save_short(IndHis, HISTLEN / 2, f) == 0) ||
                    363:       (_save_short(CrimeHis, HISTLEN / 2, f) == 0) ||
                    364:       (_save_short(PollutionHis, HISTLEN / 2, f) == 0) ||
                    365:       (_save_short(MoneyHis, HISTLEN / 2, f) == 0) ||
                    366:       (_save_short(MiscHis, MISCHISTLEN / 2, f) == 0) ||
                    367:       (_save_short((&Map[0][0]), WORLD_X * WORLD_Y, f) < 0)) {
                    368: 
                    369:     /* TODO:  report error */
                    370:     fclose(f);
                    371:     return(0);
                    372:   }
                    373: 
                    374:   fclose(f);
                    375:   return(1);
                    376: }
                    377: 
                    378: 
                    379: LoadScenario(short s)
                    380: {
                    381:   char *name, *fname;
                    382: 
                    383:   if (CityFileName != NULL) {
                    384:     ckfree(CityFileName);
                    385:     CityFileName = NULL;
                    386:   }
                    387: 
                    388:   SetGameLevel(0);
                    389: 
                    390:   if ((s < 1) || (s > 8)) s = 1;
                    391: 
                    392:   switch (s) {
                    393:   case 1:
                    394:     name = "Dullsville";
                    395:     fname = "snro.111";
                    396:     ScenarioID = 1;
                    397:     CityTime = ((1900 - 1900) * 48) + 2;
                    398:     SetFunds(5000);
                    399:     break;
                    400:   case 2:
                    401:     name = "San Francisco";
                    402:     fname = "snro.222";
                    403:     ScenarioID = 2;
                    404:     CityTime = ((1906 - 1900) * 48) + 2;
                    405:     SetFunds(20000);
                    406:     break;
                    407:   case 3:
                    408:     name = "Hamburg";
                    409:     fname = "snro.333";
                    410:     ScenarioID = 3;
                    411:     CityTime = ((1944 - 1900) * 48) + 2;
                    412:     SetFunds(20000);
                    413:     break;
                    414:   case 4:
                    415:     name = "Bern";
                    416:     fname = "snro.444";
                    417:     ScenarioID = 4;
                    418:     CityTime = ((1965 - 1900) * 48) + 2;
                    419:     SetFunds(20000);
                    420:     break;
                    421:   case 5:
                    422:     name = "Tokyo";
                    423:     fname = "snro.555";
                    424:     ScenarioID = 5;
                    425:     CityTime = ((1957 - 1900) * 48) + 2;
                    426:     SetFunds(20000);
                    427:     break;
                    428:   case 6:
                    429:     name = "Detroit";
                    430:     fname = "snro.666";
                    431:     ScenarioID = 6;
                    432:     CityTime = ((1972 - 1900) * 48) + 2;
                    433:     SetFunds(20000);
                    434:     break;
                    435:   case 7:
                    436:     name = "Boston";
                    437:     fname = "snro.777";
                    438:     ScenarioID = 7;
                    439:     CityTime = ((2010 - 1900) * 48) + 2;
                    440:     SetFunds(20000);
                    441:     break;
                    442:   case 8:
                    443:     name = "Rio de Janeiro";
                    444:     fname = "snro.888";
                    445:     ScenarioID = 8;
                    446:     CityTime = ((2047 - 1900) * 48) + 2;
                    447:     SetFunds(20000);
                    448:     break;
                    449:   }
                    450: 
                    451:   setAnyCityName(name);
                    452:   //  sim_skips = sim_skip = 0;
                    453:   InvalidateMaps();
                    454:   InvalidateEditors();
                    455:   setSpeed(3);
                    456:   CityTax = 7;
                    457:   gettimeofday(&start_time, NULL);
                    458: 
                    459:   _load_file(fname, ResourceDir);
                    460: 
                    461:   InitWillStuff();
                    462:   InitFundingLevel();
                    463:   UpdateFunds();
                    464:   InvalidateEditors();
                    465:   InvalidateMaps();
                    466:   InitSimLoad = 1;
                    467:   DoInitialEval = 0;
                    468:   DoSimInit();
                    469:   DidLoadScenario();
                    470:   Kick();
                    471: }
                    472: 
                    473: 
                    474: DidLoadScenario()
                    475: {
                    476:   Eval("UIDidLoadScenario");
                    477: }
                    478: 
                    479: 
                    480: int LoadCity(char *filename)
                    481: {
                    482:   char *cp;
                    483:   char msg[256];
                    484: 
                    485:   if (loadFile(filename)) {
                    486:     if (CityFileName != NULL)
                    487:       ckfree(CityFileName);
                    488:     CityFileName = (char *)ckalloc(strlen(filename) + 1);
                    489:     strcpy(CityFileName, filename);
                    490: 
                    491:     if (cp = (char *)rindex(filename, '.'))
                    492:       *cp = 0;
                    493: #ifdef MSDOS
                    494:     if (cp = (char *)rindex(filename, '\\'))
                    495: #else
                    496:     if (cp = (char *)rindex(filename, '/'))
                    497: #endif
                    498:       cp++;
                    499:     else
                    500:       cp = filename;
                    501:     filename = (char *)ckalloc(strlen(cp) + 1);
                    502:     strcpy(filename, cp);
                    503:     setCityName(filename);
                    504:     gettimeofday(&start_time, NULL);
                    505: 
                    506:     InvalidateMaps();
                    507:     InvalidateEditors();
                    508:     DidLoadCity();
                    509:     return (1);
                    510:   } else {
                    511:     sprintf(msg, "Unable to load a city from the file named \"%s\". %s",
                    512:            filename ? filename : "(null)",
                    513:            errno ? strerror(errno) : "");
                    514:     DidntLoadCity(msg);
                    515:     return (0);
                    516:   }
                    517: }
                    518: 
                    519: 
                    520: DidLoadCity()
                    521: {
                    522:   Eval("UIDidLoadCity");
                    523: }
                    524: 
                    525: 
                    526: DidntLoadCity(char *msg)
                    527: {
                    528:   char buf[1024];
                    529:   sprintf(buf, "UIDidntLoadCity {%s}", msg);
                    530:   Eval(buf);
                    531: }
                    532: 
                    533: 
                    534: SaveCity()
                    535: {
                    536:   char msg[256];
                    537: 
                    538:   if (CityFileName == NULL) {
                    539:     DoSaveCityAs();
                    540:   } else {
                    541:     if (saveFile(CityFileName))
                    542:       DidSaveCity();
                    543:     else {
                    544:       sprintf(msg, "Unable to save the city to the file named \"%s\". %s",
                    545:              CityFileName ? CityFileName : "(null)",
                    546:              errno ? strerror(errno) : "");
                    547:       DidntSaveCity(msg);
                    548:     }
                    549:   }
                    550: }
                    551: 
                    552: 
                    553: DoSaveCityAs()
                    554: {
                    555:   Eval("UISaveCityAs");
                    556: }
                    557: 
                    558: 
                    559: DidSaveCity()
                    560: {
                    561:   Eval("UIDidSaveCity");
                    562: }
                    563: 
                    564: 
                    565: DidntSaveCity(char *msg)
                    566: {
                    567:   char buf[1024];
                    568:   sprintf(buf, "UIDidntSaveCity {%s}", msg);
                    569:   Eval(buf);
                    570: }
                    571: 
                    572: 
                    573: SaveCityAs(char *filename)
                    574: {
                    575:   char msg[256];
                    576:   char *cp;
                    577: 
                    578:   if (CityFileName != NULL)
                    579:     ckfree(CityFileName);
                    580:   CityFileName = (char *)ckalloc(strlen(filename) + 1);
                    581:   strcpy(CityFileName, filename);
                    582: 
                    583:   if (saveFile(CityFileName)) {
                    584:     if (cp = (char *)rindex(filename, '.'))
                    585:       *cp = 0;
                    586: #ifdef MSDOS
                    587:     if (cp = (char *)rindex(filename, '\\'))
                    588: #else
                    589:     if (cp = (char *)rindex(filename, '/'))
                    590: #endif
                    591:       cp++;
                    592:     else
                    593:       cp = filename;
                    594:     filename = (char *)ckalloc(strlen(cp) + 1);
                    595:     strcpy(filename, cp);
                    596:     setCityName(cp);
                    597:     DidSaveCity();
                    598:   } else {
                    599:     sprintf(msg, "Unable to save the city to the file named \"%s\". %s",
                    600:            CityFileName ? CityFileName : "(null)",
                    601:            errno ? strerror(errno) : "");
                    602:     DidntSaveCity(msg);
                    603:   }
                    604: }
                    605: 
                    606: 

unix.superglobalmegacorp.com

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