]> git.zerfleddert.de Git - micropolis/blob - src/sim/w_con.c
Makefile: Micropolis build fixes for recent macOS
[micropolis] / src / sim / w_con.c
1 /* w_con.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 void _FixSingle(int x, int y, short *TileAdrPtr);
65 void _FixZone(int x, int y, short *TileAdrPtr);
66 int _LayDoze(int x, int y, short *TileAdrPtr);
67 int _LayRoad(int x, int y, short *TileAdrPtr);
68 int _LayRail(int x, int y, short *TileAdrPtr);
69 int _LayWire(int x, int y, short *TileAdrPtr);
70
71
72 short _RoadTable[16] = {
73 66, 67, 66, 68,
74 67, 67, 69, 73,
75 66, 71, 66, 72,
76 70, 75, 74, 76
77 };
78
79 short _RailTable[16] = {
80 226, 227, 226, 228,
81 227, 227, 229, 233,
82 226, 231, 226, 232,
83 230, 235, 234, 236
84 };
85
86 short _WireTable[16] = {
87 210, 211, 210, 212,
88 211, 211, 213, 217,
89 210, 215, 210, 216,
90 214, 219, 218, 220
91 };
92
93
94 #define NeutralizeRoad(Tile) \
95 if (((Tile &= LOMASK) >= 64) && \
96 ((Tile & LOMASK) <= 207)) { \
97 Tile = (Tile & 0x000F) + 64; \
98 }
99
100
101 /* comefrom: check3Border check4Border check5Border processWand */
102 int
103 ConnecTile(short x, short y, short *TileAdrPtr, short Command)
104 {
105 short Tile;
106 int result = 1;
107
108 /* make sure the array subscripts are in bounds */
109 if (!TestBounds(x, y)) {
110 return (0);
111 }
112
113 /* AutoDoze */
114 if ((Command >= 2) && (Command <= 4)) {
115
116 if ((autoBulldoze != 0) &&
117 (TotalFunds > 0) &&
118 ((Tile = (*TileAdrPtr)) & BULLBIT)) {
119 NeutralizeRoad(Tile);
120 /* Maybe this should check BULLBIT instead of checking tile values? */
121 if (((Tile >= TINYEXP) && (Tile <= LASTTINYEXP)) ||
122 ((Tile < 64) && (Tile != 0))) {
123 Spend(1);
124 (*TileAdrPtr) = 0;
125 }
126 }
127 }
128
129 switch (Command) {
130
131 case 0: /* Fix zone */
132 _FixZone(x, y, TileAdrPtr);
133 break;
134
135 case 1: /* Doze zone */
136 result = _LayDoze(x, y, TileAdrPtr);
137 _FixZone(x, y, TileAdrPtr);
138 break;
139
140 case 2: /* Lay Road */
141 result = _LayRoad(x, y, TileAdrPtr);
142 _FixZone(x, y, TileAdrPtr);
143 break;
144
145 case 3: /* Lay Rail */
146 result = _LayRail(x, y, TileAdrPtr);
147 _FixZone(x, y, TileAdrPtr);
148 break;
149
150 case 4: /* Lay Wire */
151 result = _LayWire(x, y, TileAdrPtr);
152 _FixZone(x, y, TileAdrPtr);
153 break;
154
155 }
156
157 return result;
158 }
159
160 /* comefrom: ConnecTile */
161 int
162 _LayDoze(int x, int y, short *TileAdrPtr)
163 {
164 short Tile;
165
166 if (!(TotalFunds)) {
167 return -2; /* no mas dinero. */
168 }
169
170 Tile = (*TileAdrPtr);
171
172 if (!(Tile & BULLBIT)) {
173 return 0; /* Check dozeable bit. */
174 }
175
176 NeutralizeRoad(Tile);
177
178 switch (Tile) {
179 case HBRIDGE:
180 case VBRIDGE:
181 case BRWV:
182 case BRWH:
183 case HBRDG0:
184 case HBRDG1:
185 case HBRDG2:
186 case HBRDG3:
187 case VBRDG0:
188 case VBRDG1:
189 case VBRDG2:
190 case VBRDG3:
191 case HPOWER:
192 case VPOWER:
193 case HRAIL:
194 case VRAIL: /* Dozing over water, replace with water. */
195 (*TileAdrPtr) = RIVER;
196 break;
197
198 default: /* Dozing on land, replace with land. Simple, eh? */
199 (*TileAdrPtr) = DIRT;
200 break;
201 }
202
203 Spend(1); /* Costs $1.00....*/
204 return 1;
205 }
206
207
208 /* comefrom: ConnecTile */
209 int
210 _LayRoad(int x, int y, short *TileAdrPtr)
211 {
212 short Tile;
213 int cost = 10;
214
215 if (TotalFunds < 10) {
216 return -2;
217 }
218
219 Tile = (*TileAdrPtr) & LOMASK;
220
221 switch (Tile) {
222
223 case DIRT:
224 (*TileAdrPtr) = ROADS | BULLBIT | BURNBIT;
225 break;
226
227 case RIVER: /* Road on Water */
228 case REDGE:
229 case CHANNEL: /* Check how to build bridges, if possible. */
230 if (TotalFunds < 50) {
231 return -2;
232 }
233
234 cost = 50;
235
236 if (x < (WORLD_X - 1)) {
237 Tile = TileAdrPtr[WORLD_Y];
238 NeutralizeRoad(Tile);
239 if ((Tile == VRAILROAD) ||
240 (Tile == HBRIDGE) ||
241 ((Tile >= ROADS) &&
242 (Tile <= HROADPOWER))) {
243 (*TileAdrPtr) = HBRIDGE | BULLBIT;
244 break;
245 }
246 }
247
248 if (x > 0) {
249 Tile = TileAdrPtr[-WORLD_Y];
250 NeutralizeRoad(Tile);
251 if ((Tile == VRAILROAD) ||
252 (Tile == HBRIDGE) ||
253 ((Tile >= ROADS) &&
254 (Tile <= INTERSECTION))) {
255 (*TileAdrPtr) = HBRIDGE | BULLBIT;
256 break;
257 }
258 }
259
260 if (y < (WORLD_Y - 1)) {
261 Tile = TileAdrPtr[1];
262 NeutralizeRoad(Tile);
263 if ((Tile == HRAILROAD) ||
264 (Tile == VROADPOWER) ||
265 ((Tile >= VBRIDGE) &&
266 (Tile <= INTERSECTION))) {
267 (*TileAdrPtr) = VBRIDGE | BULLBIT;
268 break;
269 }
270 }
271
272 if (y > 0) {
273 Tile = TileAdrPtr[-1];
274 NeutralizeRoad(Tile);
275 if ((Tile == HRAILROAD) ||
276 (Tile == VROADPOWER) ||
277 ((Tile >= VBRIDGE) &&
278 (Tile <= INTERSECTION))) {
279 (*TileAdrPtr) = VBRIDGE | BULLBIT;
280 break;
281 }
282 }
283
284 /* Can't do road... */
285 return 0;
286
287 case LHPOWER: /* Road on power */
288 (*TileAdrPtr) = VROADPOWER | CONDBIT | BURNBIT | BULLBIT;
289 break;
290
291 case LVPOWER: /* Road on power #2 */
292 (*TileAdrPtr) = HROADPOWER | CONDBIT | BURNBIT | BULLBIT;
293 break;
294
295 case LHRAIL: /* Road on rail */
296 (*TileAdrPtr) = HRAILROAD | BURNBIT | BULLBIT;
297 break;
298
299 case LVRAIL: /* Road on rail #2 */
300 (*TileAdrPtr) = VRAILROAD | BURNBIT | BULLBIT;
301 break;
302
303 default: /* Can't do road */
304 return 0;
305
306 }
307
308 Spend(cost);
309
310 return 1;
311 }
312
313
314 /* comefrom: ConnecTile */
315 int
316 _LayRail(int x, int y, short *TileAdrPtr)
317 {
318 short Tile;
319 int cost = 20;
320
321 if (TotalFunds < 20) {
322 return -2;
323 }
324
325 Tile = (*TileAdrPtr) & LOMASK;
326 NeutralizeRoad(Tile);
327
328 switch (Tile) {
329 case 0: /* Rail on Dirt */
330 (*TileAdrPtr) = 226 | BULLBIT | BURNBIT;
331 break;
332
333 case 2: /* Rail on Water */
334 case 3:
335 case 4: /* Check how to build underwater tunnel, if possible. */
336 if (TotalFunds < 100) {
337 return -2;
338 }
339 cost = 100;
340
341 if (x < (WORLD_X - 1)) {
342 Tile = TileAdrPtr[WORLD_Y];
343 NeutralizeRoad(Tile);
344 if ((Tile == 221) || (Tile == 224) || ((Tile >= 226) && (Tile <= 237))) {
345 (*TileAdrPtr) = 224 | BULLBIT;
346 break;
347 }
348 }
349
350 if (x > 0) {
351 Tile = TileAdrPtr[-WORLD_Y];
352 NeutralizeRoad(Tile);
353 if ((Tile == 221) || (Tile == 224) || ((Tile > 225) && (Tile < 238))) {
354 (*TileAdrPtr) = 224 | BULLBIT;
355 break;
356 }
357 }
358
359 if (y < (WORLD_Y - 1)) {
360 Tile = TileAdrPtr[1];
361 NeutralizeRoad(Tile);
362 if ((Tile == 222) || (Tile == 238) || ((Tile > 224) && (Tile < 237))) {
363 (*TileAdrPtr) = 225 | BULLBIT;
364 break;
365 }
366 }
367
368 if (y > 0) {
369 Tile = TileAdrPtr[-1];
370 NeutralizeRoad(Tile);
371 if ((Tile == 222) || (Tile == 238) || ((Tile > 224) && (Tile < 237))) {
372 (*TileAdrPtr) = 225 | BULLBIT;
373 break;
374 }
375 }
376
377 /* Can't do rail... */
378 return 0;
379
380 case 210: /* Rail on power */
381 (*TileAdrPtr) = 222 | CONDBIT | BURNBIT | BULLBIT;
382 break;
383
384 case 211: /* Rail on power #2 */
385 (*TileAdrPtr) = 221 | CONDBIT | BURNBIT | BULLBIT;
386 break;
387
388 case 66: /* Rail on road */
389 (*TileAdrPtr) = 238 | BURNBIT | BULLBIT;
390 break;
391
392 case 67: /* Rail on road #2 */
393 (*TileAdrPtr) = 237 | BURNBIT | BULLBIT;
394 break;
395
396 default: /* Can't do rail */
397 return 0;
398 }
399
400 Spend(cost);
401 return 1;
402 }
403
404
405 /* comefrom: ConnecTile */
406 int
407 _LayWire(int x, int y, short *TileAdrPtr)
408 {
409 short Tile;
410 int cost = 5;
411
412 if (TotalFunds < 5) {
413 return -2;
414 }
415
416 Tile = (*TileAdrPtr) & LOMASK;
417 NeutralizeRoad(Tile);
418
419 switch (Tile) {
420 case 0: /* Wire on Dirt */
421 (*TileAdrPtr) = 210 | CONDBIT | BURNBIT | BULLBIT;
422 break;
423
424 case 2: /* Wire on Water */
425 case 3:
426 case 4: /* Check how to lay underwater wire, if possible. */
427 if (TotalFunds < 25)
428 return -2;
429 cost = 25;
430
431 if (x < (WORLD_X - 1)) {
432 Tile = TileAdrPtr[WORLD_Y];
433 if (Tile & CONDBIT) {
434 NeutralizeRoad(Tile);
435 if ((Tile != 77) && (Tile != 221) && (Tile != 208)) {
436 (*TileAdrPtr) = 209 | CONDBIT | BULLBIT;
437 break;
438 }
439 }
440 }
441
442 if (x > 0) {
443 Tile = TileAdrPtr[-WORLD_Y];
444 if (Tile & CONDBIT) {
445 NeutralizeRoad(Tile);
446 if ((Tile != 77) && (Tile != 221) && (Tile != 208)) {
447 (*TileAdrPtr) = 209 | CONDBIT | BULLBIT;
448 break;
449 }
450 }
451 }
452
453 if (y < (WORLD_Y - 1)) {
454 Tile = TileAdrPtr[1];
455 if (Tile & CONDBIT) {
456 NeutralizeRoad(Tile);
457 if ((Tile != 78) && (Tile != 222) && (Tile != 209)) {
458 (*TileAdrPtr) = 208 | CONDBIT | BULLBIT;
459 break;
460 }
461 }
462 }
463
464 if (y > 0) {
465 Tile = TileAdrPtr[-1];
466 if (Tile & CONDBIT) {
467 NeutralizeRoad(Tile);
468 if ((Tile != 78) && (Tile != 222) && (Tile != 209)) {
469 (*TileAdrPtr) = 208 | CONDBIT | BULLBIT;
470 break;
471 }
472 }
473 }
474
475 /* Can't do wire... */
476 return 0;
477
478 case 66: /* Wire on Road */
479 (*TileAdrPtr) = 77 | CONDBIT | BURNBIT | BULLBIT;
480 break;
481
482 case 67: /* Wire on Road #2 */
483 (*TileAdrPtr) = 78 | CONDBIT | BURNBIT | BULLBIT;
484 break;
485
486 case 226: /* Wire on rail */
487 (*TileAdrPtr) = 221 | CONDBIT | BURNBIT | BULLBIT;
488 break;
489
490 case 227: /* Wire on rail #2 */
491 (*TileAdrPtr) = 222 | CONDBIT | BURNBIT | BULLBIT;
492 break;
493
494 default: /* Can't do wire */
495 return 0;
496 }
497
498 Spend(cost);
499 return 1;
500 }
501
502
503 /* comefrom: ConnecTile */
504 void
505 _FixZone(int x, int y, short *TileAdrPtr)
506 {
507 _FixSingle(x,y, &TileAdrPtr[0]);
508
509 if (y > 0) {
510 _FixSingle(x, y-1, &TileAdrPtr[-1]);
511 }
512
513 if (x < (WORLD_X - 1)) {
514 _FixSingle(x+1, y, &TileAdrPtr[WORLD_Y]);
515 }
516
517 if (y < (WORLD_Y - 1)) {
518 _FixSingle(x, y+1, &TileAdrPtr[1]);
519 }
520
521 if (x > 0) {
522 _FixSingle(x-1, y, &TileAdrPtr[-WORLD_Y]);
523 }
524
525 }
526
527
528 /* comefrom: _FixZone */
529 void
530 _FixSingle(int x, int y, short *TileAdrPtr)
531 {
532 short Tile;
533 short adjTile = 0;
534
535 Tile = (*TileAdrPtr) & LOMASK;
536 NeutralizeRoad(Tile);
537 if ((Tile >= 66) && (Tile <= 76)) { /* Cleanup Road */
538
539 if (y > 0) {
540 Tile = TileAdrPtr[-1];
541 NeutralizeRoad(Tile);
542 if (((Tile == 237) || ((Tile >= 64) && (Tile <= 78))) &&
543 (Tile != 77) && (Tile != 238) && (Tile != 64))
544 adjTile |= 0x0001;
545 }
546
547 if (x < (WORLD_X - 1)) {
548 Tile = TileAdrPtr[WORLD_Y];
549 NeutralizeRoad(Tile);
550 if (((Tile == 238) || ((Tile >= 64) && (Tile <= 78))) &&
551 (Tile != 78) && (Tile != 237) && (Tile != 65))
552 adjTile |= 0x0002;
553 }
554
555 if (y < (WORLD_Y - 1)) {
556 Tile = TileAdrPtr[1];
557 NeutralizeRoad(Tile);
558 if (((Tile == 237) || ((Tile >= 64) && (Tile <= 78))) &&
559 (Tile != 77) && (Tile != 238) && (Tile != 64))
560 adjTile |= 0x0004;
561 }
562
563 if (x > 0) {
564 Tile = TileAdrPtr[-WORLD_Y];
565 NeutralizeRoad(Tile);
566 if (((Tile == 238) || ((Tile >= 64) && (Tile <= 78))) &&
567 (Tile != 78) && (Tile != 237) && (Tile != 65))
568 adjTile |= 0x0008;
569 }
570
571 (*TileAdrPtr) = _RoadTable[adjTile] | BULLBIT | BURNBIT;
572 return;
573 }
574
575 if ((Tile >= 226) && (Tile <= 236)) { /* Cleanup Rail */
576
577 if (y > 0) {
578 Tile = TileAdrPtr[-1];
579 NeutralizeRoad(Tile);
580 if ((Tile >= 221) && (Tile <= 238) &&
581 (Tile != 221) && (Tile != 237) && (Tile != 224))
582 adjTile |= 0x0001;
583 }
584
585 if (x < (WORLD_X - 1)) {
586 Tile = TileAdrPtr[WORLD_Y];
587 NeutralizeRoad(Tile);
588 if ((Tile >= 221) && (Tile <= 238) &&
589 (Tile != 222) && (Tile != 238) && (Tile != 225))
590 adjTile |= 0x0002;
591 }
592
593 if (y < (WORLD_Y - 1)) {
594 Tile = TileAdrPtr[1];
595 NeutralizeRoad(Tile);
596 if ((Tile >= 221) && (Tile <= 238) &&
597 (Tile != 221) && (Tile != 237) && (Tile != 224))
598 adjTile |= 0x0004;
599 }
600
601 if (x > 0) {
602 Tile = TileAdrPtr[-WORLD_Y];
603 NeutralizeRoad(Tile);
604 if ((Tile >= 221) && (Tile <= 238) &&
605 (Tile != 222) && (Tile != 238) && (Tile != 225))
606 adjTile |= 0x0008;
607 }
608
609 (*TileAdrPtr) = _RailTable[adjTile] | BULLBIT | BURNBIT;
610 return;
611 }
612
613 if ((Tile >= 210) && (Tile <= 220)) { /* Cleanup Wire */
614
615 if (y > 0) {
616 Tile = TileAdrPtr[-1];
617 if (Tile & CONDBIT) {
618 NeutralizeRoad(Tile);
619 if ((Tile != 209) && (Tile != 78) && (Tile != 222))
620 adjTile |= 0x0001;
621 }
622 }
623
624 if (x < (WORLD_X - 1)) {
625 Tile = TileAdrPtr[WORLD_Y];
626 if (Tile & CONDBIT) {
627 NeutralizeRoad(Tile);
628 if ((Tile != 208) && (Tile != 77) && (Tile != 221))
629 adjTile |= 0x0002;
630 }
631 }
632
633 if (y < (WORLD_Y - 1)) {
634 Tile = TileAdrPtr[1];
635 if (Tile & CONDBIT) {
636 NeutralizeRoad(Tile);
637 if ((Tile != 209) && (Tile != 78) && (Tile != 222))
638 adjTile |= 0x0004;
639 }
640 }
641
642 if (x > 0) {
643 Tile = TileAdrPtr[-WORLD_Y];
644 if (Tile & CONDBIT) {
645 NeutralizeRoad(Tile);
646 if ((Tile != 208) && (Tile != 77) && (Tile != 221))
647 adjTile |= 0x0008;
648 }
649 }
650
651 (*TileAdrPtr) = _WireTable[adjTile] | BULLBIT | BURNBIT | CONDBIT;
652 return;
653 }
654 }
655
Impressum, Datenschutz