|
|
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.