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

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

unix.superglobalmegacorp.com

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