|
|
1.1 root 1: /* g_map.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 [email protected].
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: #define VAL_NONE 0
66: #define VAL_LOW 1
67: #define VAL_MEDIUM 2
68: #define VAL_HIGH 3
69: #define VAL_VERYHIGH 4
70: #define VAL_PLUS 5
71: #define VAL_VERYPLUS 6
72: #define VAL_MINUS 7
73: #define VAL_VERYMINUS 8
74:
75: short valMap[] = {
76: -1, COLOR_LIGHTGRAY, COLOR_YELLOW, COLOR_ORANGE, COLOR_RED,
77: COLOR_DARKGREEN, COLOR_LIGHTGREEN, COLOR_ORANGE, COLOR_YELLOW
78: };
79:
80: short valGrayMap[] = {
81: -1, 31, 127, 191, 255,
82: 223, 255, 31, 0
83: };
84:
85:
86: int (*mapProcs[NMAPS])();
87:
88: int drawAll(SimView *view);
89: int drawRes(SimView *view);
90: int drawCom(SimView *view);
91: int drawInd(SimView *view);
92: int drawPower(SimView *view);
93: int drawLilTransMap(SimView *view);
94: int drawPopDensity(SimView *view);
95: int drawRateOfGrowth(SimView *view);
96: int drawTrafMap(SimView *view);
97: int drawPolMap(SimView *view);
98: int drawCrimeMap(SimView *view);
99: int drawLandMap(SimView *view);
100: int drawFireRadius(SimView *view);
101: int drawPoliceRadius(SimView *view);
102: int drawDynamic(SimView *view);
103:
104:
105: short GetCI(short x)
106: {
107: if (x < 50) return(VAL_NONE);
108: if (x < 100) return(VAL_LOW);
109: if (x < 150) return(VAL_MEDIUM);
110: if (x < 200) return(VAL_HIGH);
111: return(VAL_VERYHIGH);
112: }
113:
114:
115: drawPopDensity(SimView *view)
116: {
117: short x, y;
118:
119: drawAll(view);
120: for (x = 0; x < HWLDX; x++) {
121: for (y = 0; y < HWLDY; y++) {
122: maybeDrawRect(view, GetCI(PopDensity[x][y]),
123: x * 6, y * 6, 6, 6);
124: }
125: }
126: }
127:
128:
129: drawRateOfGrowth(SimView *view)
130: {
131: short x, y;
132:
133: drawAll(view);
134: for (x = 0; x < SmX; x++) {
135: for (y = 0; y < SmY; y++) {
136: short val, z = RateOGMem[x][y];
137:
138: if (z > 100) val = VAL_VERYPLUS;
139: else {
140: if (z > 20) val = VAL_PLUS;
141: else {
142: if (z < -100) val = VAL_VERYMINUS;
143: else {
144: if (z < -20) val = VAL_MINUS;
145: else val = VAL_NONE;
146: }
147: }
148: }
149: maybeDrawRect(view, val,
150: x * 24, y * 24, 24, 24);
151: }
152: }
153: }
154:
155:
156: drawTrafMap(SimView *view)
157: {
158: short x;
159: short y;
160:
161: drawLilTransMap(view);
162:
163: for (x = 0; x < HWLDX; x++) {
164: for (y = 0; y < HWLDY; y++) {
165: maybeDrawRect(view, GetCI(TrfDensity[x][y]),
166: x * 6, y * 6, 6, 6);
167: }
168: }
169: }
170:
171:
172: drawPolMap(SimView *view)
173: {
174: short x, y;
175:
176: drawAll(view);
177:
178: for (x = 0; x < HWLDX; x++) {
179: for (y = 0; y < HWLDY; y++) {
180: maybeDrawRect(view, GetCI(10 + PollutionMem[x][y]),
181: x * 6, y * 6, 6, 6);
182: }
183: }
184: }
185:
186:
187: drawCrimeMap(SimView *view)
188: {
189: short x, y;
190:
191: drawAll(view);
192:
193: for (x = 0; x < HWLDX; x++) {
194: for (y = 0; y < HWLDY; y++) {
195: maybeDrawRect(view, GetCI(CrimeMem[x][y]),
196: x * 6, y * 6, 6, 6);
197: }
198: }
199: }
200:
201:
202: drawLandMap(SimView *view)
203: {
204: short x, y;
205:
206: drawAll(view);
207:
208: for (x = 0; x < HWLDX; x++) {
209: for (y = 0; y < HWLDY; y++) {
210: maybeDrawRect(view, GetCI(LandValueMem[x][y]),
211: x * 6, y * 6, 6, 6);
212: }
213: }
214: }
215:
216:
217: drawFireRadius(SimView *view)
218: {
219: short x, y;
220:
221: drawAll(view);
222: for (x = 0; x < SmY; x++) {
223: for (y = 0; y < SmY; y++) {
224: maybeDrawRect(view, GetCI(FireRate[x][y]),
225: x * 24, y * 24, 24, 24);
226: }
227: }
228: }
229:
230:
231: drawPoliceRadius(SimView *view)
232: {
233: short x, y;
234:
235: drawAll(view);
236: for (x = 0; x < SmX; x++) {
237: for (y = 0; y < SmY; y++) {
238: maybeDrawRect(view, GetCI(PoliceMapEffect[x][y]),
239: x * 24, y * 24, 24, 24);
240: }
241: }
242: }
243:
244:
245: setUpMapProcs(void)
246: {
247: mapProcs[ALMAP] = drawAll;
248: mapProcs[REMAP] = drawRes;
249: mapProcs[COMAP] = drawCom;
250: mapProcs[INMAP] = drawInd;
251: mapProcs[PRMAP] = drawPower;
252: mapProcs[RDMAP] = drawLilTransMap;
253: mapProcs[PDMAP] = drawPopDensity;
254: mapProcs[RGMAP] = drawRateOfGrowth;
255: mapProcs[TDMAP] = drawTrafMap;
256: mapProcs[PLMAP] = drawPolMap;
257: mapProcs[CRMAP] = drawCrimeMap;
258: mapProcs[LVMAP] = drawLandMap;
259: mapProcs[FIMAP] = drawFireRadius;
260: mapProcs[POMAP] = drawPoliceRadius;
261: mapProcs[DYMAP] = drawDynamic;
262: }
263:
264:
265: MemDrawMap(SimView *view)
266: {
267: (*mapProcs[view->map_state])(view);
268: if (!view->x->color) {
269: ditherMap(view);
270: XSetForeground(view->x->dpy, view->x->gc, view->pixels[COLOR_BLACK]);
271: XSetBackground(view->x->dpy, view->x->gc, view->pixels[COLOR_WHITE]);
272: XPutImage(view->x->dpy, view->pixmap, view->x->gc, view->image,
273: 0, 0, 0, 0, view->m_width, view->m_height);
274: }
275: }
276:
277:
278: ditherMap(SimView *view)
279: {
280: int i, x, y, width, height;
281: int err, pixel1, pixel8;
282: int line_bytes1 = view->line_bytes;
283: int line_bytes8 = view->line_bytes8;
284: unsigned char *image1 = view->data;
285: unsigned char *image8 = view->data8;
286: int *errors;
287:
288: width = view->m_width; height = view->m_height;
289:
290: errors = (int *)malloc(sizeof(int) * (width));
291:
292: for (i = 0; i < width; i++)
293: errors[i] = (Rand16() & 15) - 7;
294:
295: err = (Rand16() & 15) - 7;
296:
297: for (y = 0; y < height; y += 2) {
298: unsigned char *i1 = image1;
299: unsigned char *i8 = image8;
300:
301: image1 += line_bytes1;
302: image8 += line_bytes8;
303:
304: for (x = 0; x < width; x += 8) {
305: pixel1 = 0;
306: for (i = 0; i < 8; i++) {
307: pixel1 <<= 1;
308: pixel8 = *(i8++) + err + errors[x + i];
309: if (pixel8 > 127) {
310: err = pixel8 - 255;
311: } else {
312: pixel1 |= 1;
313: err = pixel8;
314: }
315: errors[x + i] = err/2;
316: err = err/2;
317: }
318: *(i1++) = pixel1;
319: }
320:
321: i1 = image1 + (width / 8) - 1;
322: i8 = image8 + width - 1;
323:
324: image1 += line_bytes1;
325: image8 += line_bytes8;
326:
327: for (x = width - 8; x >= 0; x -= 8) {
328: pixel1 = 0;
329: for (i = 7; i >= 0; i--) {
330: pixel1 >>= 1;
331: pixel8 = *(i8--) + err + errors[x + i];
332: if (pixel8 > 127) {
333: err = pixel8 - 255;
334: } else {
335: pixel1 |= 128;
336: err = pixel8;
337: }
338: errors[x + i] = err/2;
339: err = err/2;
340: }
341: *(i1--) = pixel1;
342: }
343: }
344:
345: free(errors);
346: }
347:
348:
349: maybeDrawRect(SimView *view, int val,
350: int x, int y, int w, int h)
351: {
352: if (val == VAL_NONE) return;
353:
354: if (view->x->color) {
355: drawRect(view, view->pixels[valMap[val]], 0, x, y, w, h);
356: } else {
357: drawRect(view, valGrayMap[val], 1, x, y, w, h);
358: }
359: }
360:
361:
362: drawRect(SimView *view, int pixel, int solid,
363: int x, int y, int w, int h)
364: {
365: int W = view->m_width, H = view->m_height;
366:
367: if (x < 0) {
368: if ((w += x) < 0) w = 0;
369: x = 0;
370: } else if (x > W) {
371: x = 0; w = 0;
372: }
373: if (x + w > W) {
374: w = W - x;
375: }
376: if (y < 0) {
377: if ((h += y) < 0) h = 0;
378: y = 0;
379: } else if (y > H) {
380: y = 0; h = 0;
381: }
382: if (y + h > H) {
383: h = H - y;
384: }
385:
386: if (w && h) {
387: int i, j, stipple = (x ^ y) & 1;
388: unsigned char *data =
389: view->x->color ? view->data : view->data8;
390:
391: /* In the case of black and white, we use an 8 bit buffer and dither it. */
392: int pixelBytes =
393: view->x->color ? view->pixel_bytes : 1;
394: QUAD line =
395: view->x->color ? view->line_bytes : view->line_bytes8;
396:
397: unsigned char *image =
398: &(data[(line * y) + (x * pixelBytes)]);
399:
400: switch (pixelBytes) {
401:
402: case 1:
403: {
404: unsigned char *data =
405: view->data8;
406: unsigned char *image =
407: &data[(line * y) + (x * pixelBytes)];
408:
409: if (solid) {
410: for (i = h; i > 0; i--) {
411: for (j = w; j > 0; j--) {
412: *image = pixel;
413: image++;
414: }
415: image += line - w;
416: }
417: } else {
418: for (i = h; i > 0; i--) {
419: for (j = w; j > 0; j--) {
420: if (stipple++ & 1)
421: *image = pixel;
422: image++;
423: }
424: if (!(w & 1))
425: stipple++;
426: image += line - w;
427: }
428: }
429: }
430: break;
431:
432: case 2:
433: {
434: unsigned short *data =
435: (unsigned short *)view->data;
436: unsigned short *image;
437: line >>= 1; /* Convert from byte offset to short offset */
438: image =
439: &data[(line * y) + x];
440:
441: if (solid) {
442: for (i = h; i > 0; i--) {
443: for (j = w; j > 0; j--) {
444: *image = pixel;
445: image++;
446: }
447: image += line - w;
448: }
449: } else {
450: for (i = h; i > 0; i--) {
451: for (j = w; j > 0; j--) {
452: if (stipple++ & 1)
453: *image = pixel;
454: image++;
455: }
456: if (!(w & 1))
457: stipple++;
458: image += line - w;
459: }
460: }
461: }
462: break;
463:
464: case 3:
465: case 4:
466: {
467: unsigned char *data =
468: (unsigned char *)view->data;
469: unsigned char *image;
470: int bitmapPad = view->x->small_tile_image->bitmap_pad;
471: int rowBytes = view->x->small_tile_image->bytes_per_line;
472: line = rowBytes >> 1; /* Convert from byte offset to short offset */
473: image =
474: &data[(line * y) + x];
475:
476: if (solid) {
477: for (i = h; i > 0; i--) {
478: for (j = w; j > 0; j--) {
479: *(image++) = (pixel >> 0) & 0xff;
480: *(image++) = (pixel >> 8) & 0xff;
481: *(image++) = (pixel >> 16) & 0xff;
482: if (bitmapPad == 32) {
483: image++;
484: }
485: }
486: image += line - w;
487: }
488: } else {
489: for (i = h; i > 0; i--) {
490: for (j = w; j > 0; j--) {
491: if (stipple++ & 1) {
492: *(image++) = (pixel >> 0) & 0xff;
493: *(image++) = (pixel >> 8) & 0xff;
494: *(image++) = (pixel >> 16) & 0xff;
495: if (bitmapPad == 32) {
496: image++;
497: }
498: }
499: }
500: if (!(w & 1)) {
501: stipple++;
502: }
503: image += line - w;
504: }
505: }
506: }
507: break;
508:
509: default:
510: assert(0); /* Undefined depth */
511: break;
512: }
513:
514: }
515: }
516:
517:
518:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.