fix modifier problems (like NumLock) by ignoring hateMods
[micropolis] / src / sim / g_smmaps.c
1 /* g_smmaps.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 int DynamicData[32];
66
67
68 #define DRAW_BEGIN \
69   int col, row; \
70   unsigned short tile; \
71   short *mp; \
72   unsigned char *imageBase; \
73   unsigned char *image; \
74   unsigned QUAD *mem; \
75   unsigned QUAD l; \
76   int lineBytes = view->line_bytes8; \
77   int pixelBytes = view->pixel_bytes; \
78   mp = &Map[0][0]; \
79   imageBase = view->x->color ? view->data : view->data8; \
80   for (col = 0; col < WORLD_X; col++) { \
81     image = imageBase + (3 * pixelBytes * col); \
82     for (row = 0; row < WORLD_Y; row++) { \
83       tile = *(mp++) & LOMASK; \
84       if (tile >= TILE_COUNT) tile -= TILE_COUNT;
85
86
87 #define LE_ROW1_8(n) \
88       l = mem[n]; \
89       image[0] = l; \
90       image[1] = l >>8; \
91       image[2] = l >>16; \
92       image += lineBytes;
93
94 #define LE_ROW1_16(n) \
95       memcpy((char *)image, ((char *)mem) + (n * 4 * 2), (3 * 2)); \
96       image += lineBytes;
97
98 #define LE_ROW1_24(n) \
99       memcpy((char *)image, ((char *)mem) + (n * 4 * 3), (3 * 3)); \
100       image += lineBytes;
101
102 #define LE_ROW1_32(n) \
103       memcpy((char *)image, ((char *)mem) + (n * 4 * 4), (3 * 4)); \
104       image += lineBytes;
105
106 #define BE_ROW1_8(n) \
107       l = mem[n]; \
108       image[0] = l >>24; \
109       image[1] = l >>16; \
110       image[2] = l >>8; \
111       image += lineBytes;
112
113 #define BE_ROW1_16(n) \
114       l = mem[n]; /* XXX: WRONG. handle depth */ \
115       image[0] = l >>24; \
116       image[1] = l >>16; \
117       image[2] = l >>8; \
118       image += lineBytes;
119
120 #define BE_ROW1_24(n) \
121       l = mem[n]; /* XXX: WRONG. handle depth */ \
122       image[0] = l >>24; \
123       image[1] = l >>16; \
124       image[2] = l >>8; \
125       image += lineBytes;
126
127 #define BE_ROW1_32(n) \
128       l = mem[n]; /* XXX: WRONG. handle depth */ \
129       image[0] = l >>24; \
130       image[1] = l >>16; \
131       image[2] = l >>8; \
132       image += lineBytes;
133
134 #define LE_ROW3_8 LE_ROW1_8(0) LE_ROW1_8(1) LE_ROW1_8(2)
135 #define LE_ROW3_16 LE_ROW1_16(0) LE_ROW1_16(1) LE_ROW1_16(2)
136 #define LE_ROW3_24 LE_ROW1_24(0) LE_ROW1_24(1) LE_ROW1_24(2)
137 #define LE_ROW3_32 LE_ROW1_32(0) LE_ROW1_32(1) LE_ROW1_32(2)
138
139 #define BE_ROW3_8 BE_ROW1_8(0) BE_ROW1_8(1) BE_ROW1_8(2)
140 #define BE_ROW3_16 BE_ROW1_16(0) BE_ROW1_16(1) BE_ROW1_16(2)
141 #define BE_ROW3_24 BE_ROW1_24(0) BE_ROW1_24(1) BE_ROW1_24(2)
142 #define BE_ROW3_32 BE_ROW1_32(0) BE_ROW1_32(1) BE_ROW1_32(2)
143
144 #define ROW3_8 if (view->x->needs_swap) { BE_ROW3_8 } else { LE_ROW3_8 }
145 #define ROW3_16 LE_ROW3_16
146 #define ROW3_24 LE_ROW3_24
147 #define ROW3_32 LE_ROW3_32
148
149 #define ROW3 \
150           switch (view->x->depth) { \
151                 case 1: \
152                 case 8: \
153                   ROW3_8 \
154                   break; \
155                 case 15: \
156                 case 16: \
157                   ROW3_16 \
158                   break; \
159                 case 24: \
160                 case 32: \
161                   ROW3_32 \
162                   break; \
163                 default: \
164                   assert(0); /* Undefined depth */ \
165                   break; \
166           }
167
168 #define DRAW_END \
169       mem = (unsigned QUAD *)&view->smalltiles[tile * 4 * 4 * pixelBytes]; \
170       ROW3 \
171     } \
172   }
173
174
175 void drawAll(SimView *view)
176 {
177   DRAW_BEGIN
178   DRAW_END
179 }
180
181
182 void drawRes(SimView *view)
183 {
184   DRAW_BEGIN
185     if (tile > 422)
186       tile = 0;
187   DRAW_END
188 }
189
190
191 void drawCom(SimView *view)
192 {
193   DRAW_BEGIN
194     if ((tile > 609) ||
195         ((tile >= 232) && (tile < 423)))
196       tile = 0;
197   DRAW_END
198 }
199
200
201 void drawInd(SimView *view)
202 {
203   DRAW_BEGIN
204     if (((tile >= 240) && (tile <= 611)) ||
205         ((tile >= 693) && (tile <= 851)) ||
206         ((tile >= 860) && (tile <= 883)) ||
207         (tile >= 932))
208       tile = 0;
209   DRAW_END
210 }
211
212
213 void drawLilTransMap(SimView *view)
214 {
215   DRAW_BEGIN
216     if ((tile >= 240) ||
217         ((tile >= 207) && tile <= 220) ||
218         (tile == 223))
219       tile = 0;
220   DRAW_END
221 }
222
223
224 /* color pixel values */
225 #define UNPOWERED       COLOR_LIGHTBLUE
226 #define POWERED         COLOR_RED
227 #define CONDUCTIVE      COLOR_LIGHTGRAY
228
229
230 void drawPower(SimView *view)
231 {
232   short col, row;
233   unsigned short tile;
234   short *mp;
235   unsigned char *image, *imageBase;
236   unsigned QUAD *mem;
237   unsigned QUAD l;
238   int lineBytes = view->line_bytes8;
239   int pixelBytes = view->pixel_bytes;
240
241   int pix;
242   int powered, unpowered, conductive;
243
244   if (view->x->color) {
245     powered = view->pixels[POWERED];
246     unpowered = view->pixels[UNPOWERED];
247     conductive = view->pixels[CONDUCTIVE];
248   } else {
249     powered = 255;
250     unpowered = 0;
251     conductive = 127;
252   }
253
254   mp = &Map[0][0];
255   imageBase = view->x->color ? view->data : view->data8;
256
257   for (col = 0; col < WORLD_X; col++) {
258     image = imageBase + (3 * pixelBytes * col);
259     for (row = 0; row < WORLD_Y; row++) {
260       tile = *(mp++);
261
262       if ((tile & LOMASK) >= TILE_COUNT) tile -= TILE_COUNT;
263
264       if ((unsigned short)(tile & LOMASK) <= (unsigned short)63) {
265                 tile &= LOMASK;
266                 pix = -1;
267       } else if (tile & ZONEBIT) {
268                 pix = (tile & PWRBIT) ? powered : unpowered;
269       } else {
270                 if (tile & CONDBIT) {
271                   pix = conductive;
272                 } else {
273                   tile = 0;
274                   pix = -1;
275                 }
276       }
277
278       if (pix < 0) {
279                 mem = (unsigned QUAD *)&view->smalltiles[tile * 4 * 4 * pixelBytes];
280                 ROW3
281       } else {
282                 switch (view->x->depth) {
283
284                 case 1:
285                 case 8:
286                   image[0] = image[1] = image[2] = pix;
287                   image += lineBytes;
288                   image[0] = image[1] = image[2] = pix;
289                   image += lineBytes;
290                   image[0] = image[1] = image[2] = pix;
291                   image += lineBytes;
292                   break;
293
294                 case 15:
295                 case 16:
296                   { 
297                         unsigned short *p;
298                         p = (short *)image;
299                         p[0] = p[1] = p[2] = pix;
300                         image += lineBytes;
301                         p = (short *)image;
302                         p[0] = p[1] = p[2] = pix;
303                         image += lineBytes;
304                         p = (short *)image;
305                         p[0] = p[1] = p[2] = pix;
306                         image += lineBytes;
307                   }
308                   break;
309
310                 case 24:
311                 case 32:
312                   { 
313                         int x, y;
314                         for (y = 0; y < 3; y++) {
315                           unsigned char *img =
316                                 image;
317                           for (x = 0; x < 4; x++) {
318                                 *(img++) = (pix >> 0) & 0xff;
319                                 *(img++) = (pix >> 8) & 0xff;
320                                 *(img++) = (pix >> 16) & 0xff;
321                                 if (pixelBytes == 4) {
322                                   img++;
323                                 } // if
324                           } // for x
325                           image += lineBytes;
326                         } // for y
327                   }
328                   break;
329
330                 default:
331                   assert(0); /* Undefined depth */
332                   break;
333
334                 }
335       }
336     }
337   }
338 }
339
340
341 int dynamicFilter(int col, int row)
342 {
343   int r, c, x;
344
345   r = row >>1;
346   c = col >>1;
347
348   if (((DynamicData[0] > DynamicData[1]) ||
349        ((x = PopDensity[c][r])                  >= DynamicData[0]) &&
350        (x                                                               <= DynamicData[1])) &&
351       ((DynamicData[2] > DynamicData[3]) ||
352        ((x = RateOGMem[c>>2][r>>2])             >= ((2 * DynamicData[2]) - 256)) &&
353        (x                                                               <= ((2 * DynamicData[3]) - 256))) &&
354       ((DynamicData[4] > DynamicData[5]) ||
355        ((x = TrfDensity[c][r])                  >= DynamicData[4]) &&
356        (x                                                               <= DynamicData[5])) &&
357       ((DynamicData[6] > DynamicData[7]) ||
358        ((x = PollutionMem[c][r])                >= DynamicData[6]) &&
359        (x                                                               <= DynamicData[7])) &&
360       ((DynamicData[8] > DynamicData[9]) ||
361        ((x = CrimeMem[c][r])                    >= DynamicData[8]) &&
362        (x                                                               <= DynamicData[9])) &&
363       ((DynamicData[10] > DynamicData[11]) ||
364        ((x = LandValueMem[c][r])                >= DynamicData[10]) &&
365        (x                                                               <= DynamicData[11])) &&
366       ((DynamicData[12] > DynamicData[13]) ||
367        ((x = PoliceMapEffect[c>>2][r>>2]) >= DynamicData[12]) &&
368        (x                                                               <= DynamicData[13])) &&
369       ((DynamicData[14] > DynamicData[15]) ||
370        ((x = FireRate[c>>2][r>>2])              >= DynamicData[14]) &&
371        (x                                                               <= DynamicData[15]))) {
372     return 1;
373   } else {
374     return 0;
375   } // if
376 }
377
378
379 void drawDynamic(SimView *view)
380 {
381   DRAW_BEGIN
382     if (tile > 63) {
383       if (!dynamicFilter(col, row)) {
384         tile = 0;
385       } // if
386     } // if
387   DRAW_END
388 }
389
390