]> git.zerfleddert.de Git - micropolis/blob - src/sim/s_scan.c
20a7d62044dff0b4e67db61aaf228a51f17961e7
[micropolis] / src / sim / s_scan.c
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 micropolis@laptop.org.
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 }
Impressum, Datenschutz