]> git.zerfleddert.de Git - micropolis/blame - src/sim/g_smmaps.c
Optimize redrawing so that the mouse is more responsive, from Marc Espie.
[micropolis] / src / sim / g_smmaps.c
CommitLineData
6a5fa4e0
MG
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
65int 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
99c730ea 87#define LE_ROW1_8(n) \
6a5fa4e0
MG
88 l = mem[n]; \
89 image[0] = l; \
90 image[1] = l >>8; \
91 image[2] = l >>16; \
92 image += lineBytes;
93
99c730ea 94#define LE_ROW1_16(n) \
6a5fa4e0
MG
95 memcpy((char *)image, ((char *)mem) + (n * 4 * 2), (3 * 2)); \
96 image += lineBytes;
97
99c730ea 98#define LE_ROW1_24(n) \
6a5fa4e0
MG
99 memcpy((char *)image, ((char *)mem) + (n * 4 * 3), (3 * 3)); \
100 image += lineBytes;
101
99c730ea 102#define LE_ROW1_32(n) \
6a5fa4e0
MG
103 memcpy((char *)image, ((char *)mem) + (n * 4 * 4), (3 * 4)); \
104 image += lineBytes;
105
99c730ea 106#define BE_ROW1_8(n) \
6a5fa4e0
MG
107 l = mem[n]; \
108 image[0] = l >>24; \
109 image[1] = l >>16; \
110 image[2] = l >>8; \
111 image += lineBytes;
112
99c730ea 113#define BE_ROW1_16(n) \
6a5fa4e0
MG
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
99c730ea 120#define BE_ROW1_24(n) \
6a5fa4e0
MG
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
99c730ea 127#define BE_ROW1_32(n) \
6a5fa4e0
MG
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
99c730ea
MG
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)
6a5fa4e0 143
efad9d6d 144#define ROW3_8 if (view->x->needs_swap) { BE_ROW3_8 } else { LE_ROW3_8 }
42be101d
MG
145#define ROW3_16 LE_ROW3_16
146#define ROW3_24 LE_ROW3_24
147#define ROW3_32 LE_ROW3_32
6a5fa4e0
MG
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: \
6a5fa4e0
MG
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
175void drawAll(SimView *view)
176{
177 DRAW_BEGIN
178 DRAW_END
179}
180
181
182void drawRes(SimView *view)
183{
184 DRAW_BEGIN
185 if (tile > 422)
186 tile = 0;
187 DRAW_END
188}
189
190
191void 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
201void 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
213void 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
230void 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;
2d56c40c
MG
298 p = (unsigned short *)image;
299 if (view->x->x_big_endian) {
300 p[0] = p[1] = p[2] = ((pix & 0xff) << 8) | ((pix & 0xff00) >> 8);
301 } else {
302 p[0] = p[1] = p[2] = pix;
303 }
6a5fa4e0 304 image += lineBytes;
2d56c40c
MG
305 p = (unsigned short *)image;
306 if (view->x->x_big_endian) {
307 p[0] = p[1] = p[2] = ((pix & 0xff) << 8) | ((pix & 0xff00) >> 8);
308 } else {
309 p[0] = p[1] = p[2] = pix;
310 }
6a5fa4e0 311 image += lineBytes;
2d56c40c
MG
312 p = (unsigned short *)image;
313 if (view->x->x_big_endian) {
314 p[0] = p[1] = p[2] = ((pix & 0xff) << 8) | ((pix & 0xff00) >> 8);
315 } else {
316 p[0] = p[1] = p[2] = pix;
317 }
6a5fa4e0
MG
318 image += lineBytes;
319 }
320 break;
321
322 case 24:
323 case 32:
324 {
325 int x, y;
326 for (y = 0; y < 3; y++) {
327 unsigned char *img =
328 image;
329 for (x = 0; x < 4; x++) {
2d56c40c
MG
330 if (view->x->x_big_endian) {
331 if (pixelBytes == 4) {
332 img++;
333 } // if
334 *(img++) = (pix >> 16) & 0xff;
335 *(img++) = (pix >> 8) & 0xff;
336 *(img++) = (pix >> 0) & 0xff;
337 } else {
338 *(img++) = (pix >> 0) & 0xff;
339 *(img++) = (pix >> 8) & 0xff;
340 *(img++) = (pix >> 16) & 0xff;
341 if (pixelBytes == 4) {
342 img++;
343 } // if
344 }
6a5fa4e0
MG
345 } // for x
346 image += lineBytes;
347 } // for y
348 }
349 break;
350
351 default:
352 assert(0); /* Undefined depth */
353 break;
354
355 }
356 }
357 }
358 }
359}
360
361
362int dynamicFilter(int col, int row)
363{
364 int r, c, x;
365
366 r = row >>1;
367 c = col >>1;
368
369 if (((DynamicData[0] > DynamicData[1]) ||
370 ((x = PopDensity[c][r]) >= DynamicData[0]) &&
371 (x <= DynamicData[1])) &&
372 ((DynamicData[2] > DynamicData[3]) ||
373 ((x = RateOGMem[c>>2][r>>2]) >= ((2 * DynamicData[2]) - 256)) &&
374 (x <= ((2 * DynamicData[3]) - 256))) &&
375 ((DynamicData[4] > DynamicData[5]) ||
376 ((x = TrfDensity[c][r]) >= DynamicData[4]) &&
377 (x <= DynamicData[5])) &&
378 ((DynamicData[6] > DynamicData[7]) ||
379 ((x = PollutionMem[c][r]) >= DynamicData[6]) &&
380 (x <= DynamicData[7])) &&
381 ((DynamicData[8] > DynamicData[9]) ||
382 ((x = CrimeMem[c][r]) >= DynamicData[8]) &&
383 (x <= DynamicData[9])) &&
384 ((DynamicData[10] > DynamicData[11]) ||
385 ((x = LandValueMem[c][r]) >= DynamicData[10]) &&
386 (x <= DynamicData[11])) &&
387 ((DynamicData[12] > DynamicData[13]) ||
388 ((x = PoliceMapEffect[c>>2][r>>2]) >= DynamicData[12]) &&
389 (x <= DynamicData[13])) &&
390 ((DynamicData[14] > DynamicData[15]) ||
391 ((x = FireRate[c>>2][r>>2]) >= DynamicData[14]) &&
392 (x <= DynamicData[15]))) {
393 return 1;
394 } else {
395 return 0;
396 } // if
397}
398
399
400void drawDynamic(SimView *view)
401{
402 DRAW_BEGIN
403 if (tile > 63) {
404 if (!dynamicFilter(col, row)) {
405 tile = 0;
406 } // if
407 } // if
408 DRAW_END
409}
410
411
Impressum, Datenschutz