|
|
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.