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

1.1     ! root        1: /* w_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: Tcl_HashTable MapCmds;
        !            66: 
        !            67: 
        !            68: extern Tk_ConfigSpec TileViewConfigSpecs[];
        !            69: 
        !            70: 
        !            71: Ink *NewInk();
        !            72: 
        !            73: 
        !            74: MapCmdconfigure(VIEW_ARGS)
        !            75: {
        !            76:   int result = TCL_OK;
        !            77: 
        !            78:   if (argc == 2) {
        !            79:     result = Tk_ConfigureInfo(interp, view->tkwin, TileViewConfigSpecs,
        !            80:                              (char *) view, (char *) NULL, 0);
        !            81:   } else if (argc == 3) {
        !            82:     result = Tk_ConfigureInfo(interp, view->tkwin, TileViewConfigSpecs,
        !            83:                              (char *) view, argv[2], 0);
        !            84:   } else {
        !            85:     result = ConfigureTileView(interp, view, argc-2, argv+2,
        !            86:                               TK_CONFIG_ARGV_ONLY);
        !            87:   }
        !            88:   return result;
        !            89: }
        !            90: 
        !            91: MapCmdposition(VIEW_ARGS)
        !            92: {
        !            93:   if ((argc != 2) && (argc != 4)) {
        !            94:     return TCL_ERROR;
        !            95:   }
        !            96:   if (argc == 4) {
        !            97:     if ((Tcl_GetInt(interp, argv[2], &view->w_x) != TCL_OK)
        !            98:        || (Tcl_GetInt(interp, argv[3], &view->w_y) != TCL_OK)) {
        !            99:       return TCL_ERROR;
        !           100:     }
        !           101:   }
        !           102:   sprintf(interp->result, "%d %d", view->w_x, view->w_y);
        !           103:   return TCL_OK;
        !           104: }
        !           105: 
        !           106: MapCmdsize(VIEW_ARGS)
        !           107: {
        !           108:   if ((argc != 2) && (argc != 4)) {
        !           109:     return TCL_ERROR;
        !           110:   }
        !           111:   if (argc == 4) {
        !           112:     int w, h;
        !           113: 
        !           114:     if (Tcl_GetInt(interp, argv[2], &w) != TCL_OK) {
        !           115:       return TCL_ERROR;
        !           116:     }
        !           117:     if (Tcl_GetInt(interp, argv[3], &h) != TCL_OK) {
        !           118:       return TCL_ERROR;
        !           119:     }
        !           120:     view->w_width = w;
        !           121:     view->w_height = h;
        !           122:   }
        !           123:   sprintf(interp->result, "%d %d", view->w_width, view->w_height);
        !           124:   return TCL_OK;
        !           125: }
        !           126: 
        !           127: MapCmdMapState(VIEW_ARGS)
        !           128: {
        !           129:   int state;
        !           130: 
        !           131:   if ((argc != 2) && (argc != 3)) {
        !           132:     return TCL_ERROR;
        !           133:   }
        !           134: 
        !           135:   if (argc == 3) {
        !           136:     if ((Tcl_GetInt(interp, argv[2], &state) != TCL_OK) ||
        !           137:        (state < 0) || (state >= NMAPS)) {
        !           138:       return TCL_ERROR;
        !           139:     }
        !           140: 
        !           141:     DoSetMapState(view, state); Kick();
        !           142:   }
        !           143: 
        !           144:   sprintf(interp->result, "%d", view->map_state);
        !           145:   return TCL_OK;
        !           146: }
        !           147: 
        !           148: MapCmdShowEditors(VIEW_ARGS)
        !           149: {
        !           150:   int val;
        !           151: 
        !           152:   if ((argc != 2) && (argc != 3)) {
        !           153:     return TCL_ERROR;
        !           154:   }
        !           155: 
        !           156:   if (argc == 3) {
        !           157:     if (Tcl_GetInt(interp, argv[2], &val) != TCL_OK) {
        !           158:       return TCL_ERROR;
        !           159:     }
        !           160: 
        !           161:     view->show_editors = val;
        !           162:   }
        !           163: 
        !           164:   sprintf(interp->result, "%d", view->show_editors);
        !           165:   return TCL_OK;
        !           166: }
        !           167: 
        !           168: MapCmdPanStart(VIEW_ARGS)
        !           169: {
        !           170:   int x, y, left, right, top, bottom, width, height;
        !           171:   SimView *ed;
        !           172: 
        !           173:   if (argc != 4) {
        !           174:     return TCL_ERROR;
        !           175:   }
        !           176: 
        !           177:   if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK) ||
        !           178:       (Tcl_GetInt(interp, argv[3], &y) != TCL_OK)) {
        !           179:     return TCL_ERROR;
        !           180:   }
        !           181: 
        !           182:   for (ed = sim->editor; ed != NULL; ed = ed->next) {
        !           183:     if ((ed->x != view->x) || (ed->show_me == 0))
        !           184:       continue;
        !           185: 
        !           186:     width = ed->w_width;
        !           187:     height = ed->w_height;
        !           188:     left = ed->pan_x - (width / 2);
        !           189:     top = ed->pan_y - (height / 2);
        !           190:     right = left + width;
        !           191:     bottom = top + height;
        !           192: 
        !           193:     left = left * 3 / 16 - 4;
        !           194:     top = top * 3 / 16 - 4;
        !           195:     right = right * 3 / 16 + 4;
        !           196:     bottom = bottom * 3 / 16 + 4;
        !           197: 
        !           198:     if ((x >= left) && (x <= right) &&
        !           199:        (y >= top) && (y <= bottom)) {
        !           200:       goto gotit;
        !           201:     }
        !           202:   }
        !           203: 
        !           204: gotit:
        !           205:   view->last_x = x;
        !           206:   view->last_y = y;
        !           207:   view->track_info = (char *)ed;
        !           208:   return TCL_OK;
        !           209: }
        !           210: 
        !           211: MapCmdPanTo(VIEW_ARGS)
        !           212: {
        !           213:   int x, y, dx, dy;
        !           214:   SimView *ed;
        !           215: 
        !           216:   if (argc != 4) {
        !           217:     return TCL_ERROR;
        !           218:   }
        !           219: 
        !           220:   if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK) ||
        !           221:       (Tcl_GetInt(interp, argv[3], &y) != TCL_OK)) {
        !           222:     return TCL_ERROR;
        !           223:   }
        !           224: 
        !           225:   if ((ed = (SimView *)view->track_info) != NULL) {
        !           226:     dx = x - view->last_x;
        !           227:     dy = y - view->last_y;
        !           228:     if (dx || dy) {
        !           229:       view->last_x = x;
        !           230:       view->last_y = y;
        !           231:       dx = dx * 16 / 3;
        !           232:       dy = dy * 16 / 3;
        !           233: 
        !           234:       ed->skip = 0;
        !           235:       DoPanBy(ed, dx, dy); Kick();
        !           236:     }
        !           237:   }
        !           238:   return TCL_OK;
        !           239: }
        !           240: 
        !           241: MapCmdVisible(VIEW_ARGS)
        !           242: {
        !           243:   int visible;
        !           244: 
        !           245:   if ((argc != 2) && (argc != 3)) {
        !           246:     return TCL_ERROR;
        !           247:   }
        !           248: 
        !           249:   if (argc == 3) {
        !           250:     if ((Tcl_GetInt(interp, argv[2], &visible) != TCL_OK) ||
        !           251:        (visible < 0) || (visible > 1)) {
        !           252:       return TCL_ERROR;
        !           253:     }
        !           254: 
        !           255:     visible = visible && Tk_IsMapped(view->tkwin);
        !           256:     view->visible = visible;
        !           257:   }
        !           258: 
        !           259:   sprintf(interp->result, "%d", view->visible);
        !           260:   return TCL_OK;
        !           261: }
        !           262: 
        !           263: MapCmdViewAt(VIEW_ARGS)
        !           264: {
        !           265:   int x, y;
        !           266: 
        !           267:   if (argc != 4) {
        !           268:     return TCL_ERROR;
        !           269:   }
        !           270: 
        !           271:   if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK) ||
        !           272:       (x < 0) || (x >= WORLD_X) ||
        !           273:       (Tcl_GetInt(interp, argv[3], &y) != TCL_OK) ||
        !           274:       (y < 0) || (y >= WORLD_Y)) {
        !           275:     return TCL_ERROR;
        !           276:   }
        !           277: 
        !           278:   sprintf(interp->result, "Sorry Not Implemented Yet"); /* XXX */
        !           279:   return TCL_OK;
        !           280: }
        !           281: 
        !           282: 
        !           283: map_command_init()
        !           284: {
        !           285:   int new;
        !           286:   extern int TileViewCmd(CLIENT_ARGS);
        !           287: 
        !           288:   Tcl_CreateCommand(tk_mainInterp, "mapview", TileViewCmd,
        !           289:                    (ClientData)MainWindow, (void (*)()) NULL);
        !           290: 
        !           291:   Tcl_InitHashTable(&MapCmds, TCL_STRING_KEYS);
        !           292: 
        !           293: #define MAP_CMD(name) HASHED_CMD(Map, name)
        !           294: 
        !           295:   MAP_CMD(configure);
        !           296:   MAP_CMD(position);
        !           297:   MAP_CMD(size);
        !           298:   MAP_CMD(MapState);
        !           299:   MAP_CMD(ShowEditors);
        !           300:   MAP_CMD(PanStart);
        !           301:   MAP_CMD(PanTo);
        !           302:   MAP_CMD(Visible);
        !           303:   MAP_CMD(ViewAt);
        !           304: }
        !           305: 
        !           306: 
        !           307: int
        !           308: DoMapCmd(CLIENT_ARGS)
        !           309: {
        !           310:   SimView *view = (SimView *) clientData;
        !           311:   Tcl_HashEntry *ent;
        !           312:   int result = TCL_OK;
        !           313:   int (*cmd)();
        !           314: 
        !           315:   if (argc < 2) {
        !           316:     return TCL_ERROR;
        !           317:   }
        !           318: 
        !           319:   if (ent = Tcl_FindHashEntry(&MapCmds, argv[1])) {
        !           320:     cmd = (int (*)())ent->clientData;
        !           321:     Tk_Preserve((ClientData) view);
        !           322:     result = cmd(view, interp, argc, argv);
        !           323:     Tk_Release((ClientData) view);
        !           324:   } else {
        !           325:     Tcl_AppendResult(interp, "unknown command name: \"",
        !           326:                     argv[0], " ", argv[1], "\".", (char *) NULL);
        !           327:     result = TCL_ERROR;
        !           328:   }
        !           329:   return result;
        !           330: }
        !           331: 
        !           332: 
        !           333: /*************************************************************************/
        !           334: 
        !           335: DoNewMap(SimView *view)
        !           336: {
        !           337:   sim->maps++; view->next = sim->map; sim->map = view;
        !           338: /* NewMap = 1; */
        !           339:   view->invalid = 1;
        !           340: }
        !           341: 
        !           342: 
        !           343: int DoUpdateMap(SimView *view)
        !           344: {
        !           345:   int dx, dy, i;
        !           346: 
        !           347:   view->updates++;
        !           348: 
        !           349: // fprintf(stderr, "UpdateMaps sim_skips %d skips %d skip %d visible %d\n", sim_skips, view->skips, view->skip, view->visible);
        !           350: 
        !           351:   if (!view->visible) {
        !           352:     return 0;
        !           353:   }
        !           354: 
        !           355:   if ((!ShakeNow) &&
        !           356:       (!view->update) &&
        !           357:       (sim_skips ||
        !           358:        view->skips)) {
        !           359:     if (sim_skips) {
        !           360:       if (sim_skip > 0) {
        !           361:        return 0;
        !           362:       }
        !           363:     } else {
        !           364:       if (view->skip > 0) {
        !           365:        --view->skip;
        !           366:        return 0;
        !           367:       } else {
        !           368:        view->skip = view->skips;
        !           369:       }
        !           370:     }
        !           371:   }
        !           372: 
        !           373:   view->update = 0;
        !           374:   view->skip = 0;
        !           375: 
        !           376: //  view->invalid = 1;
        !           377: 
        !           378:   if (view->invalid || NewMap || ShakeNow) {
        !           379: 
        !           380:     view->invalid = 0;
        !           381: 
        !           382:     switch (view->type) {
        !           383: 
        !           384:     case X_Mem_View:
        !           385:       MemDrawMap(view);
        !           386:       break;
        !           387: 
        !           388:     case X_Wire_View:
        !           389:       WireDrawMap(view);
        !           390:       break;
        !           391:     }
        !           392: 
        !           393:   }
        !           394: 
        !           395:   /* XXX: don't do this stuff if just redrawing overlay */
        !           396: 
        !           397:   for (dx = dy = i = 0; i < ShakeNow; i++) {
        !           398:     dx += Rand(16) - 8;
        !           399:     dy += Rand(16) - 8;
        !           400:   }
        !           401: 
        !           402:   XCopyArea(view->x->dpy, view->pixmap, view->pixmap2, view->x->gc,
        !           403:            dx, dy, view->w_width, view->w_height, 0, 0);
        !           404:   DrawMapInk(view);
        !           405: 
        !           406:   /* XXX: do this if just redrawing overlay */
        !           407: 
        !           408:   XCopyArea(view->x->dpy, view->pixmap2,
        !           409:            Tk_WindowId(view->tkwin), view->x->gc,
        !           410:            0, 0, view->w_width, view->w_height, 0, 0);
        !           411: 
        !           412:   if (view->show_editors) {
        !           413:     DrawMapEditorViews(view);
        !           414:   }
        !           415: 
        !           416:   return 1;
        !           417: }
        !           418: 
        !           419: 
        !           420: DrawMapEditorViews(SimView *view)
        !           421: {
        !           422:   Pixmap pm = Tk_WindowId(view->tkwin);
        !           423:   struct SimView *ed;
        !           424:   int left, right, top, bottom, width, height;
        !           425:   int mine;
        !           426: 
        !           427:   XSetLineAttributes(view->x->dpy, view->x->gc, 1,
        !           428:                     LineSolid, CapButt, JoinBevel);
        !           429: 
        !           430:   for (ed = sim->editor; ed != NULL; ed = ed->next) {
        !           431:     if ((ed->x != view->x) || (ed->show_me == 0))
        !           432:       continue;
        !           433: 
        !           434:     width = ed->w_width;
        !           435:     height = ed->w_height;
        !           436:     left = ed->pan_x - (width / 2);
        !           437:     top = ed->pan_y - (height / 2);
        !           438:     right = left + width;
        !           439:     bottom = top + height;
        !           440: 
        !           441:     left = left * 3 / 16;
        !           442:     top = top * 3 / 16;
        !           443:     right = right * 3 / 16;
        !           444:     bottom = bottom * 3 / 16;
        !           445:     width = right - left;
        !           446:     height = bottom - top;
        !           447: 
        !           448:     XSetForeground(view->x->dpy, view->x->gc,
        !           449:                   view->pixels[COLOR_WHITE]);
        !           450:     XDrawRectangle(view->x->dpy, pm, view->x->gc,
        !           451:                   left - 3, top - 3, width + 3, height + 3);
        !           452: 
        !           453:     XSetForeground(view->x->dpy, view->x->gc,
        !           454:                   view->pixels[COLOR_BLACK]);
        !           455:     XDrawRectangle(view->x->dpy, pm, view->x->gc,
        !           456:                   left - 1, top - 1, width + 3, height + 3);
        !           457: 
        !           458:     XSetForeground(view->x->dpy, view->x->gc,
        !           459:                   view->pixels[COLOR_YELLOW]);
        !           460:     XDrawRectangle(view->x->dpy, pm, view->x->gc,
        !           461:                   left - 2, top - 2, width + 3, height + 3);
        !           462:   }
        !           463: }
        !           464: 
        !           465: 
        !           466: /* 
        !           467:  * Sending the whole image is 108108 bytes.
        !           468:  * Sending points is 4.4 bytes per point.
        !           469:  * One image is as big as 24570 points.
        !           470:  * But we have to sort these dang things.
        !           471:  */
        !           472: 
        !           473: #define MAX_PIX 256
        !           474: int max_pix = MAX_PIX;
        !           475: 
        !           476: struct Pix {
        !           477:   long color;
        !           478:   short x, y;
        !           479: };
        !           480: 
        !           481: struct Pix pix[MAX_PIX];
        !           482: 
        !           483: 
        !           484: CompareColor(struct Pix *p1, struct Pix *p2)
        !           485: {
        !           486:   register char c1 = p1->color, c2 = p2->color;
        !           487: 
        !           488:   if (c1 == c2)
        !           489:     return (0);
        !           490:   return ((c1 < c2) ? -1 : 1);
        !           491: }
        !           492: 
        !           493: 
        !           494: WireDrawMap(SimView *view)
        !           495: {
        !           496:   int different, x, y, i, last, pts;
        !           497:   unsigned char *old, *new;
        !           498:   XPoint *points;
        !           499: 
        !           500:   if (!view->x->color) {
        !           501:     MemDrawMap(view);
        !           502:     return;
        !           503:   }
        !           504: 
        !           505:   memcpy(view->other_data, view->data, view->line_bytes * view->m_height); /* XXX: handle depth */
        !           506:   MemDrawMap(view);
        !           507: 
        !           508:   old = view->other_data; new = view->data; /* XXX: handle depth */
        !           509:   different = 0;
        !           510: 
        !           511:   /* Scan the pixels that have changed */
        !           512:   for (y = 0; y < view->m_height; y++) {
        !           513:     for (x = 0; x < view->m_width; x++) {
        !           514:       if (old[x] != new[x]) {
        !           515:        if (different >= max_pix) {
        !           516:          /* Wow, lots of the pixels have changed.
        !           517:             Maybe we ought to just do it the hard way. */ 
        !           518:          XPutImage(view->x->dpy, view->pixmap, view->x->gc, view->image, 
        !           519:                    0, 0, 0, 0, view->m_width, view->m_height);
        !           520:          return;
        !           521:        }
        !           522:        pix[different].color = new[x];
        !           523:        pix[different].x = x;
        !           524:        pix[different].y = y;
        !           525:        different++;
        !           526:       }
        !           527:     }
        !           528:     old += view->line_bytes; new += view->line_bytes; /* XXX: handle depth */
        !           529:   }
        !           530: 
        !           531:   /* Whew, the images are identical! */
        !           532:   if (different == 0)
        !           533:     return;
        !           534: 
        !           535: #if 1
        !           536: 
        !           537:   /* Always draw the whole pixmap, for now. */
        !           538:   XPutImage(view->x->dpy, view->pixmap, view->x->gc, view->image, 
        !           539:            0, 0, 0, 0, view->m_width, view->m_height);
        !           540: 
        !           541: #else
        !           542: 
        !           543:   /* TODO: Fix this. I disabled this incremental drawing code for now since it seems to be buggy. */
        !           544: 
        !           545:   /* Sort the changed pixels by their color */
        !           546:   qsort(pix, different, sizeof (struct Pix), (int (*)())CompareColor);
        !           547: 
        !           548:   /* Draw the points of each color that have changed */
        !           549:   points = (XPoint *)malloc(sizeof (XPoint) * different);
        !           550:   last = 0; pts = 0;
        !           551:   for (i = 0; i <= different; i++) {
        !           552:     if ((i == different) ||
        !           553:        (pix[i].color != pix[last].color)) {
        !           554:       XSetForeground(view->x->dpy, view->x->gc, pix[last].color);
        !           555:       XDrawPoints(view->x->dpy, view->pixmap, view->x->gc,
        !           556:                  points, pts, CoordModeOrigin);
        !           557:       if (i == different)
        !           558:        break;
        !           559:       pts = 0;
        !           560:       last = i;
        !           561:     }
        !           562:     points[pts].x = pix[i].x;
        !           563:     points[pts].y = pix[i].y;
        !           564:     pts++;
        !           565:   }
        !           566:   free(points);
        !           567: 
        !           568: #endif
        !           569: 
        !           570: }
        !           571: 
        !           572: 
        !           573: DrawMapInk(SimView *view)
        !           574: {
        !           575:   Pixmap pm = view->pixmap2;
        !           576:   SimView *v;
        !           577:   Ink *ink, *ink2 = NewInk();
        !           578:   int i, X, Y, x, y;
        !           579: 
        !           580:   XSetLineAttributes(view->x->dpy, view->x->gc, 0,
        !           581:                     LineSolid, CapButt, JoinBevel);
        !           582: 
        !           583:   for (ink = sim->overlay; ink != NULL; ink = ink->next) {
        !           584:     X = ink->x; x = (X * 3) >>4;
        !           585:     Y = ink->y; y = (Y * 3) >>4;
        !           586:     
        !           587:     if (ink->length <= 1) {
        !           588:       XSetForeground(view->x->dpy, view->x->gc,
        !           589:                     view->pixels[ink->color]);
        !           590:       XFillArc(view->x->dpy, pm, view->x->gc,
        !           591:               ink->x - 1, ink->y - 1, 1, 1, 0, 360 * 64);
        !           592:     } else {
        !           593:       StartInk(ink2, x, y);
        !           594: 
        !           595:       for (i = 1; i < ink->length; i++) {
        !           596:        X += ink->points[i].x; x = (X * 3) >>4;
        !           597:        Y += ink->points[i].y; y = (Y * 3) >>4;
        !           598:        AddInk(ink2, x, y);
        !           599:       }
        !           600: 
        !           601:       XSetForeground(view->x->dpy, view->x->gc,
        !           602:                     view->pixels[ink->color]);
        !           603:       XDrawLines(view->x->dpy, pm, view->x->gc,
        !           604:                 ink2->points, ink2->length, CoordModePrevious);
        !           605:     }
        !           606:   }
        !           607: 
        !           608:   FreeInk(ink2);
        !           609: }
        !           610: 
        !           611: 

unix.superglobalmegacorp.com

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