|
|
1.1 ! root 1: /* s_scan.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: /* Map Updates */ ! 66: ! 67: ! 68: short NewMap; ! 69: short NewMapFlags[NMAPS]; ! 70: short CCx, CCy, CCx2, CCy2; ! 71: short PolMaxX, PolMaxY; ! 72: short CrimeMaxX, CrimeMaxY; ! 73: QUAD DonDither = 0; ! 74: ! 75: ! 76: /* comefrom: Simulate SpecialInit */ ! 77: FireAnalysis(void) /* Make firerate map from firestation map */ ! 78: { ! 79: register x,y; ! 80: ! 81: SmoothFSMap(); ! 82: SmoothFSMap(); ! 83: SmoothFSMap(); ! 84: for (x = 0; x < SmX; x++) ! 85: for (y = 0; y < SmY; y++) ! 86: FireRate[x][y] = FireStMap[x][y]; ! 87: ! 88: NewMapFlags[DYMAP] = NewMapFlags[FIMAP] = 1; ! 89: } ! 90: ! 91: ! 92: /* comefrom: Simulate SpecialInit */ ! 93: PopDenScan(void) /* sets: PopDensity, , , ComRate */ ! 94: { ! 95: QUAD Xtot, Ytot, Ztot; ! 96: register short x, y, z; ! 97: ! 98: ClrTemArray(); ! 99: Xtot = 0; ! 100: Ytot = 0; ! 101: Ztot = 0; ! 102: for (x = 0; x < WORLD_X; x++) ! 103: for (y = 0; y < WORLD_Y; y++) { ! 104: z = Map[x][y]; ! 105: if (z & ZONEBIT) { ! 106: z = z & LOMASK; ! 107: SMapX = x; ! 108: SMapY = y; ! 109: z = GetPDen(z) <<3; ! 110: if (z > 254) ! 111: z = 254; ! 112: tem[x >>1][y >>1] = z; ! 113: Xtot += x; ! 114: Ytot += y; ! 115: Ztot++; ! 116: } ! 117: } ! 118: DoSmooth(); /* T1 -> T2 */ ! 119: DoSmooth2(); /* T2 -> T1 */ ! 120: DoSmooth(); /* T1 -> T2 */ ! 121: ! 122: for (x = 0; x < HWLDX; x++) ! 123: for (y = 0; y < HWLDY; y++) ! 124: PopDensity[x][y] = tem2[x][y] <<1; ! 125: ! 126: DistIntMarket(); /* set ComRate w/ (/ComMap) */ ! 127: ! 128: if (Ztot) { /* Find Center of Mass for City */ ! 129: CCx = Xtot / Ztot; ! 130: CCy = Ytot / Ztot; ! 131: } else { ! 132: CCx = HWLDX; /* if pop=0 center of Map is CC */ ! 133: CCy = HWLDY; ! 134: } ! 135: CCx2 = CCx >>1; ! 136: CCy2 = CCy >>1; ! 137: NewMapFlags[DYMAP] = NewMapFlags[PDMAP] = NewMapFlags[RGMAP] = 1; ! 138: } ! 139: ! 140: ! 141: /* comefrom: PopDenScan */ ! 142: GetPDen(int Ch9) ! 143: { ! 144: register int pop; ! 145: ! 146: if (Ch9 == FREEZ) { ! 147: pop = DoFreePop(Ch9); ! 148: return (pop); ! 149: } ! 150: if (Ch9 < COMBASE) { ! 151: pop = RZPop(Ch9); ! 152: return (pop); ! 153: } ! 154: if (Ch9 < INDBASE) { ! 155: pop = (CZPop(Ch9) <<3); ! 156: return (pop); ! 157: } ! 158: if (Ch9 < PORTBASE) { ! 159: pop = (IZPop(Ch9) <<3); ! 160: return (pop); ! 161: } ! 162: return (0); ! 163: } ! 164: ! 165: ! 166: /* comefrom: Simulate SpecialInit */ ! 167: PTLScan(void) /* Does pollution, terrain, land value */ ! 168: { ! 169: QUAD ptot, LVtot; ! 170: register int x, y, z, dis; ! 171: int Plevel, LVflag, loc, zx, zy, Mx, My, pnum, LVnum, pmax; ! 172: ! 173: for (x = 0; x < QWX; x++) ! 174: for (y = 0; y < QWY; y++) ! 175: Qtem[x][y] = 0; ! 176: LVtot = 0; ! 177: LVnum = 0; ! 178: for (x = 0; x < HWLDX; x++) ! 179: for (y = 0; y < HWLDY; y++) { ! 180: Plevel = 0; ! 181: LVflag = 0; ! 182: zx = x <<1; ! 183: zy = y <<1; ! 184: for (Mx = zx; Mx <= zx + 1; Mx++) ! 185: for (My = zy; My <= zy + 1; My++) { ! 186: if (loc = (Map[Mx][My] & LOMASK)) { ! 187: if (loc < RUBBLE) { ! 188: Qtem[x >>1][y >>1] += 15; /* inc terrainMem */ ! 189: continue; ! 190: } ! 191: Plevel += GetPValue(loc); ! 192: if (loc >= ROADBASE) ! 193: LVflag++; ! 194: } ! 195: } ! 196: /* XXX ??? ! 197: if (Plevel < 0) ! 198: Plevel = 250; ! 199: */ ! 200: if (Plevel > 255) ! 201: Plevel = 255; ! 202: tem[x][y] = Plevel; ! 203: if (LVflag) { /* LandValue Equation */ ! 204: dis = 34 - GetDisCC(x, y); ! 205: dis = dis <<2; ! 206: dis += (TerrainMem[x >>1][y >>1] ); ! 207: dis -= (PollutionMem[x][y]); ! 208: if (CrimeMem[x][y] > 190) dis -= 20; ! 209: if (dis > 250) dis = 250; ! 210: if (dis < 1) dis = 1; ! 211: LandValueMem[x][y] = dis; ! 212: LVtot += dis; ! 213: LVnum++; ! 214: } else ! 215: LandValueMem[x][y] = 0; ! 216: } ! 217: ! 218: if (LVnum) ! 219: LVAverage = LVtot / LVnum; ! 220: else ! 221: LVAverage = 0; ! 222: ! 223: DoSmooth(); ! 224: DoSmooth2(); ! 225: pmax = 0; ! 226: pnum = 0; ! 227: ptot = 0; ! 228: for (x = 0; x < HWLDX; x++) { ! 229: for (y = 0; y < HWLDY; y++) { ! 230: z = tem[x][y]; ! 231: PollutionMem[x][y] = z; ! 232: if (z) { /* get pollute average */ ! 233: pnum++; ! 234: ptot += z; ! 235: /* find max pol for monster */ ! 236: if ((z > pmax) || ! 237: ((z == pmax) && (!(Rand16() & 3)))) { ! 238: pmax = z; ! 239: PolMaxX = x <<1; ! 240: PolMaxY = y <<1; ! 241: } ! 242: } ! 243: } ! 244: } ! 245: if (pnum) ! 246: PolluteAverage = ptot / pnum; ! 247: else ! 248: PolluteAverage = 0; ! 249: ! 250: SmoothTerrain(); ! 251: ! 252: NewMapFlags[DYMAP] = NewMapFlags[PLMAP] = NewMapFlags[LVMAP] = 1; ! 253: } ! 254: ! 255: ! 256: /* comefrom: PTLScan */ ! 257: GetPValue(int loc) ! 258: { ! 259: if (loc < POWERBASE) { ! 260: if (loc >= HTRFBASE) return (/* 25 */ 75); /* heavy traf */ ! 261: if (loc >= LTRFBASE) return (/* 10 */ 50); /* light traf */ ! 262: if (loc < ROADBASE) { ! 263: if (loc > FIREBASE) return (/* 60 */ 90); ! 264: /* XXX: Why negative pollution from radiation? */ ! 265: if (loc >= RADTILE) return (/* -40 */ 255); /* radioactivity */ ! 266: } ! 267: return (0); ! 268: } ! 269: if (loc <= LASTIND) return (0); ! 270: if (loc < PORTBASE) return (50); /* Ind */ ! 271: if (loc <= LASTPOWERPLANT) return (/* 60 */ 100); /* prt, aprt, cpp */ ! 272: return (0); ! 273: } ! 274: ! 275: ! 276: /* comefrom: PTLScan DistIntMarket */ ! 277: GetDisCC(int x, int y) ! 278: { ! 279: short xdis, ydis, z; ! 280: ! 281: if (x > CCx2) ! 282: xdis = x - CCx2; ! 283: else ! 284: xdis = CCx2 - x; ! 285: ! 286: if (y > CCy2) ! 287: ydis = y - CCy2; ! 288: else ! 289: ydis = CCy2 - y; ! 290: ! 291: z = (xdis + ydis); ! 292: if (z > 32) ! 293: return (32); ! 294: else ! 295: return (z); ! 296: } ! 297: ! 298: ! 299: /* comefrom: Simulate SpecialInit */ ! 300: CrimeScan(void) ! 301: { ! 302: short numz; ! 303: QUAD totz; ! 304: register short x, y, z; ! 305: short cmax; ! 306: ! 307: SmoothPSMap(); ! 308: SmoothPSMap(); ! 309: SmoothPSMap(); ! 310: totz = 0; ! 311: numz = 0; ! 312: cmax = 0; ! 313: for (x = 0; x < HWLDX; x++) ! 314: for (y = 0; y < HWLDY; y++) { ! 315: if (z = LandValueMem[x][y]) { ! 316: ++numz; ! 317: z = 128 - z; ! 318: z += PopDensity[x][y]; ! 319: if (z > 300) z = 300; ! 320: z -= PoliceMap[x >>2][y >>2]; ! 321: if (z > 250) z = 250; ! 322: if (z < 0) z = 0; ! 323: CrimeMem[x][y] = z; ! 324: totz += z; ! 325: if ((z > cmax) || ! 326: ((z == cmax) && (!(Rand16() & 3)))) { ! 327: cmax = z; ! 328: CrimeMaxX = x <<1; ! 329: CrimeMaxY = y <<1; ! 330: } ! 331: } else { ! 332: CrimeMem[x][y] = 0; ! 333: } ! 334: } ! 335: if (numz) ! 336: CrimeAverage = totz / numz; ! 337: else ! 338: CrimeAverage = 0; ! 339: for (x = 0; x < SmX; x++) ! 340: for (y = 0; y < SmY; y++) ! 341: PoliceMapEffect[x][y] = PoliceMap[x][y]; ! 342: NewMapFlags[DYMAP] = NewMapFlags[CRMAP] = NewMapFlags[POMAP] = 1; ! 343: } ! 344: ! 345: ! 346: /* comefrom: PTLScan */ ! 347: SmoothTerrain(void) ! 348: { ! 349: if (DonDither & 1) { ! 350: register int x, y = 0, z = 0, dir = 1; ! 351: ! 352: for (x = 0; x < QWX; x++) { ! 353: for (; y != QWY && y != -1; y += dir) { ! 354: z += Qtem[(x == 0) ? x : (x - 1)][y] + ! 355: Qtem[(x == (QWX - 1)) ? x : (x + 1)][y] + ! 356: Qtem[x][(y == 0) ? (0) : (y - 1)] + ! 357: Qtem[x][(y == (QWY - 1)) ? y : (y + 1)] + ! 358: (Qtem[x][y] <<2); ! 359: TerrainMem[x][y] = (unsigned char)(((unsigned)z) >>3); ! 360: z &= 0x7; ! 361: } ! 362: dir = -dir; ! 363: y += dir; ! 364: } ! 365: } else { ! 366: register short x,y,z; ! 367: ! 368: for (x = 0; x < QWX; x++) ! 369: for (y = 0; y < QWY; y++) { ! 370: z = 0; ! 371: if (x > 0) z += Qtem[x - 1][y]; ! 372: if (x < (QWX - 1)) z += Qtem[x + 1][y]; ! 373: if (y > 0) z += Qtem[x][y - 1]; ! 374: if (y < (QWY - 1)) z += Qtem[x][y + 1]; ! 375: TerrainMem[x][y] = (unsigned char)((z >>2) + Qtem[x][y]) >>1; ! 376: } ! 377: } ! 378: } ! 379: ! 380: /* comefrom: PopDenScan */ ! 381: DoSmooth (void) /* smooths data in tem[x][y] into tem2[x][y] */ ! 382: { ! 383: if (DonDither & 2) { ! 384: register int x, y = 0, z = 0, dir = 1; ! 385: ! 386: for (x = 0; x < HWLDX; x++) { ! 387: for (; y != HWLDY && y != -1; y += dir) { ! 388: /* ! 389: z += tem[(x == 0) ? x : (x - 1)][y] + ! 390: tem[(x == (HWLDX - 1)) ? x : (x + 1)][y] + ! 391: tem[x][(y == 0) ? (0) : (y - 1)] + ! 392: tem[x][(y == (HWLDY - 1)) ? y : (y + 1)] + ! 393: tem[x][y]; ! 394: tem2[x][y] = (unsigned char)(((unsigned int)z) >>2); ! 395: z &= 0x3; ! 396: */ ! 397: z += tem[(x == 0) ? x : (x - 1)][y] + ! 398: tem[(x == (HWLDX - 1)) ? x : (x + 1)][y] + ! 399: tem[x][(y == 0) ? (0) : (y - 1)] + ! 400: tem[x][(y == (HWLDY - 1)) ? y : (y + 1)] + ! 401: tem[x][y]; ! 402: tem2[x][y] = (unsigned char)(((unsigned int)z) >>2); ! 403: z &= 3; ! 404: } ! 405: dir = -dir; ! 406: y += dir; ! 407: } ! 408: } else { ! 409: register short x,y,z; ! 410: ! 411: for (x = 0; x < HWLDX; x++) { ! 412: for (y = 0; y < HWLDY; y++) { ! 413: z = 0; ! 414: if (x > 0) z += tem[x - 1][y]; ! 415: if (x < (HWLDX - 1)) z += tem[x + 1][y]; ! 416: if (y > 0) z += tem[x][y - 1]; ! 417: if (y < (HWLDY - 1)) z += tem[x][y + 1]; ! 418: z = (z + tem[x][y]) >>2; ! 419: if (z > 255) z = 255; ! 420: tem2[x][y] = (unsigned char)z; ! 421: } ! 422: } ! 423: } ! 424: } ! 425: ! 426: ! 427: /* comefrom: PopDenScan */ ! 428: DoSmooth2 (void) /* smooths data in tem2[x][y] into tem[x][y] */ ! 429: { ! 430: if (DonDither & 4) { ! 431: register int x, y = 0, z = 0, dir = 1; ! 432: ! 433: for (x = 0; x < HWLDX; x++) { ! 434: for (; y != HWLDY && y != -1; y += dir) { ! 435: /* ! 436: z += tem2[(x == 0) ? x : (x - 1)][y] + ! 437: tem2[(x == (HWLDX - 1)) ? x : (x + 1)][y] + ! 438: tem2[x][(y == 0) ? (0) : (y - 1)] + ! 439: tem2[x][(y == (HWLDY - 1)) ? y : (y + 1)] + ! 440: tem2[x][y]; ! 441: tem[x][y] = (unsigned char)(z >>2); ! 442: z &= 0x3; ! 443: */ ! 444: z += tem2[(x == 0) ? x : (x - 1)][y] + ! 445: tem2[(x == (HWLDX - 1)) ? x : (x + 1)][y] + ! 446: tem2[x][(y == 0) ? (0) : (y - 1)] + ! 447: tem2[x][(y == (HWLDY - 1)) ? y : (y + 1)] + ! 448: tem2[x][y]; ! 449: tem[x][y] = (unsigned char)(((unsigned char)z) >>2); ! 450: z &= 3; ! 451: } ! 452: dir = -dir; ! 453: y += dir; ! 454: } ! 455: } else { ! 456: register short x,y,z; ! 457: ! 458: for (x = 0; x < HWLDX; x++) { ! 459: for (y = 0; y < HWLDY; y++) { ! 460: z = 0; ! 461: if (x > 0) z += tem2[x - 1][y]; ! 462: if (x < (HWLDX - 1)) z += tem2[x + 1][y]; ! 463: if (y > 0) z += tem2[x][y - 1]; ! 464: if (y < (HWLDY - 1)) z += tem2[x][y + 1]; ! 465: z = (z + tem2[x][y]) >>2; ! 466: if (z > 255) z = 255; ! 467: tem[x][y] = (unsigned char)z; ! 468: } ! 469: } ! 470: } ! 471: } ! 472: ! 473: ! 474: /* comefrom: PopDenScan */ ! 475: ClrTemArray(void) ! 476: { ! 477: register short x, y, z; ! 478: ! 479: z = 0; ! 480: for (x = 0; x < HWLDX; x++) ! 481: for (y = 0; y < HWLDY; y++) ! 482: tem[x][y] = z; ! 483: } ! 484: ! 485: ! 486: /* comefrom: FireAnalysis */ ! 487: SmoothFSMap(void) ! 488: { ! 489: register short x, y, edge; ! 490: ! 491: for (x = 0; x < SmX; x++) ! 492: for (y = 0; y < SmY; y++) { ! 493: edge = 0; ! 494: if (x) edge += FireStMap[x - 1][y]; ! 495: if (x < (SmX - 1)) edge += FireStMap[x + 1][y]; ! 496: if (y) edge += FireStMap[x][y - 1]; ! 497: if (y < (SmY - 1)) edge += FireStMap[x][y + 1]; ! 498: edge = (edge >>2) + FireStMap[x][y]; ! 499: STem[x][y] = edge >>1; ! 500: } ! 501: for (x = 0; x < SmX; x++) ! 502: for (y = 0; y < SmY; y++) ! 503: FireStMap[x][y] = STem[x][y]; ! 504: } ! 505: ! 506: ! 507: /* comefrom: CrimeScan */ ! 508: SmoothPSMap(void) ! 509: { ! 510: register x, y, edge; ! 511: ! 512: for (x = 0; x < SmX; x++) ! 513: for (y = 0; y < SmY; y++) { ! 514: edge = 0; ! 515: if (x) edge += PoliceMap[x - 1][y]; ! 516: if (x < (SmX - 1)) edge += PoliceMap[x + 1][y]; ! 517: if (y) edge += PoliceMap[x][y - 1]; ! 518: if (y < (SmY - 1)) edge += PoliceMap[x][y + 1]; ! 519: edge = (edge >>2) + PoliceMap[x][y]; ! 520: STem[x][y] = edge >>1; ! 521: } ! 522: for (x = 0; x < SmX; x++) ! 523: for (y = 0; y < SmY; y++) ! 524: PoliceMap[x][y] = STem[x][y]; ! 525: } ! 526: ! 527: ! 528: /* comefrom: PopDenScan */ ! 529: DistIntMarket(void) ! 530: { ! 531: register short x, y, z; ! 532: ! 533: for (x = 0; x < SmX; x++) ! 534: for (y = 0; y < SmY; y++) { ! 535: z = GetDisCC(x <<2,y <<2); ! 536: z = z <<2; ! 537: z = 64 - z; ! 538: ComRate[x][y] = z; ! 539: } ! 540: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.