|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.