Annotation of micropolis/src/sim/g_map.c, revision 1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.