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