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

1.1     ! root        1: /* w_editor.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 EditorCmds;
        !            66: int DoOverlay = 2;
        !            67: int BobHeight = 8;
        !            68: 
        !            69: 
        !            70: extern Tk_ConfigSpec TileViewConfigSpecs[];
        !            71: 
        !            72: 
        !            73: int EditorCmdconfigure(VIEW_ARGS)
        !            74: {
        !            75:   int result = TCL_OK;
        !            76: 
        !            77:   if (argc == 2) {
        !            78:     result = Tk_ConfigureInfo(interp, view->tkwin, TileViewConfigSpecs,
        !            79:                              (char *) view, (char *) NULL, 0);
        !            80:   } else if (argc == 3) {
        !            81:     result = Tk_ConfigureInfo(interp, view->tkwin, TileViewConfigSpecs,
        !            82:                              (char *) view, argv[2], 0);
        !            83:   } else {
        !            84:     result = ConfigureTileView(interp, view, argc-2, argv+2,
        !            85:                               TK_CONFIG_ARGV_ONLY);
        !            86:   }
        !            87:   return TCL_OK;
        !            88: }
        !            89: 
        !            90: 
        !            91: int EditorCmdposition(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: 
        !           107: int EditorCmdsize(VIEW_ARGS)
        !           108: {
        !           109:   if ((argc != 2) && (argc != 4)) {
        !           110:     return TCL_ERROR;
        !           111:   }
        !           112:   if (argc == 4) {
        !           113:     int w, h;
        !           114:     
        !           115:     if (Tcl_GetInt(interp, argv[2], &w) != TCL_OK) {
        !           116:       return TCL_ERROR;
        !           117:     }
        !           118:     if (Tcl_GetInt(interp, argv[3], &h) != TCL_OK) {
        !           119:       return TCL_ERROR;
        !           120:     }
        !           121:     view->w_width = w;
        !           122:     view->w_height = h;
        !           123:   }
        !           124:   sprintf(interp->result, "%d %d", view->w_width, view->w_height);
        !           125:   return TCL_OK;
        !           126: }
        !           127: 
        !           128: 
        !           129: int EditorCmdAutoGoto(VIEW_ARGS)
        !           130: {
        !           131:   if ((argc != 2) && (argc != 3)) {
        !           132:     return TCL_ERROR;
        !           133:   }
        !           134:   if (argc == 3) {
        !           135:     int val;
        !           136: 
        !           137:     if (Tcl_GetInt(interp, argv[2], &val) != TCL_OK) {
        !           138:       return TCL_ERROR;
        !           139:     }
        !           140:     view->auto_goto = val;
        !           141:     view->auto_going = view->auto_x_goal = view->auto_y_goal = 0;
        !           142:   }
        !           143:   sprintf(interp->result, "%d", view->auto_goto);
        !           144:   return TCL_OK;
        !           145: }
        !           146: 
        !           147: 
        !           148: int EditorCmdSound(VIEW_ARGS)
        !           149: {
        !           150:   if ((argc != 2) && (argc != 3)) {
        !           151:     return TCL_ERROR;
        !           152:   }
        !           153:   if (argc == 3) {
        !           154:     int val;
        !           155: 
        !           156:     if (Tcl_GetInt(interp, argv[2], &val) != TCL_OK) {
        !           157:       return TCL_ERROR;
        !           158:     }
        !           159:     view->sound = val;
        !           160:     view->auto_going = view->auto_x_goal = view->auto_y_goal = 0;
        !           161:   }
        !           162:   sprintf(interp->result, "%d", view->sound);
        !           163:   return TCL_OK;
        !           164: }
        !           165: 
        !           166: 
        !           167: int EditorCmdSkip(VIEW_ARGS)
        !           168: {
        !           169:   if ((argc != 2) && (argc != 3)) {
        !           170:     return TCL_ERROR;
        !           171:   }
        !           172:   if (argc == 3) {
        !           173:     int val;
        !           174: 
        !           175:     if (Tcl_GetInt(interp, argv[2], &val) != TCL_OK) {
        !           176:       return TCL_ERROR;
        !           177:     }
        !           178:     view->skip = view->skips = val; // XXX? why setting skips too?
        !           179:   }
        !           180:   sprintf(interp->result, "%d", view->skips);
        !           181:   return TCL_OK;
        !           182: }
        !           183: 
        !           184: 
        !           185: int EditorCmdUpdate(VIEW_ARGS)
        !           186: {
        !           187:   if (argc != 2) {
        !           188:     return TCL_ERROR;
        !           189:   }
        !           190:   view->skip = 0;
        !           191:   return TCL_OK;
        !           192: }
        !           193: 
        !           194: 
        !           195: int EditorCmdPan(VIEW_ARGS)
        !           196: {
        !           197:   if ((argc != 2) && (argc != 4)) {
        !           198:     return TCL_ERROR;
        !           199:   }
        !           200:   if (argc == 4) {
        !           201:     int x, y;
        !           202: 
        !           203:     if (Tcl_GetInt(interp, argv[2], &x) != TCL_OK) {
        !           204:       return TCL_ERROR;
        !           205:     }
        !           206:     if (Tcl_GetInt(interp, argv[3], &y) != TCL_OK) {
        !           207:       return TCL_ERROR;
        !           208:     }
        !           209:     DoPanTo(view, x, y); Kick();
        !           210:   }
        !           211:   sprintf(interp->result, "%d %d", view->pan_x, view->pan_y);
        !           212:   return TCL_OK;
        !           213: }
        !           214: 
        !           215: 
        !           216: int EditorCmdToolConstrain(VIEW_ARGS)
        !           217: {
        !           218:   int x = -1, y = -1, tx, ty;
        !           219: 
        !           220:   if (argc != 4) {
        !           221:     return TCL_ERROR;
        !           222:   }
        !           223: 
        !           224:   if (Tcl_GetInt(interp, argv[2], &x) != TCL_OK) {
        !           225:     return TCL_ERROR;
        !           226:   }
        !           227:   if (Tcl_GetInt(interp, argv[3], &y) != TCL_OK) {
        !           228:     return TCL_ERROR;
        !           229:   }
        !           230:   view->tool_x_const = -1; view->tool_y_const = -1;
        !           231:   ViewToTileCoords(view, x, y, &tx, &ty);
        !           232:   view->tool_x_const = (x == -1) ? -1 : tx;
        !           233:   view->tool_y_const = (y == -1) ? -1 : ty;
        !           234:   return TCL_OK;
        !           235: }
        !           236: 
        !           237: 
        !           238: int EditorCmdToolState(VIEW_ARGS)
        !           239: {
        !           240:   if ((argc != 2) && (argc != 3)) {
        !           241:     return TCL_ERROR;
        !           242:   }
        !           243:   if (argc == 3) {
        !           244:     int state;
        !           245: 
        !           246:     if (Tcl_GetInt(interp, argv[2], &state) != TCL_OK) {
        !           247:       return TCL_ERROR;
        !           248:     }
        !           249:     setWandState(view, state);
        !           250:   }
        !           251:   sprintf(interp->result, "%d", view->tool_state);
        !           252:   return TCL_OK;
        !           253: }
        !           254: 
        !           255: 
        !           256: int EditorCmdToolMode(VIEW_ARGS)
        !           257: {
        !           258:   if ((argc != 2) && (argc != 3)) {
        !           259:     return TCL_ERROR;
        !           260:   }
        !           261:   if (argc == 3) {
        !           262:     int mode;
        !           263: 
        !           264:     if (Tcl_GetInt(interp, argv[2], &mode) != TCL_OK) {
        !           265:       return TCL_ERROR;
        !           266:     }
        !           267:     view->tool_mode = mode;
        !           268:   }
        !           269:   sprintf(interp->result, "%d", view->tool_mode);
        !           270:   return TCL_OK;
        !           271: }
        !           272: 
        !           273: 
        !           274: int EditorCmdDoTool(VIEW_ARGS)
        !           275: {
        !           276:   int tool, x, y;
        !           277: 
        !           278:   if (argc != 5) {
        !           279:     return TCL_ERROR;
        !           280:   }
        !           281: 
        !           282:   if ((Tcl_GetInt(interp, argv[2], &tool) != TCL_OK) ||
        !           283:       (tool < 0) ||
        !           284:       (tool > lastState) ||
        !           285:       (Tcl_GetInt(interp, argv[3], &x) != TCL_OK) ||
        !           286:       (Tcl_GetInt(interp, argv[4], &y) != TCL_OK)) {
        !           287:     return TCL_ERROR;
        !           288:   }
        !           289: 
        !           290:   DoTool(view, tool, x, y); Kick();
        !           291:   return TCL_OK;
        !           292: }
        !           293: 
        !           294: 
        !           295: int EditorCmdToolDown(VIEW_ARGS)
        !           296: {
        !           297:   int x, y;
        !           298: 
        !           299:   if (argc != 4) {
        !           300:     return TCL_ERROR;
        !           301:   }
        !           302: 
        !           303:   if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK) ||
        !           304:       (Tcl_GetInt(interp, argv[3], &y) != TCL_OK)) {
        !           305:     return TCL_ERROR;
        !           306:   }
        !           307: 
        !           308:   ToolDown(view, x, y); Kick();
        !           309:   return TCL_OK;
        !           310: }
        !           311: 
        !           312: 
        !           313: int EditorCmdToolDrag(VIEW_ARGS)
        !           314: {
        !           315:   int x, y;
        !           316: 
        !           317:   if (argc != 4) {
        !           318:     return TCL_ERROR;
        !           319:   }
        !           320: 
        !           321:   if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK) ||
        !           322:       (Tcl_GetInt(interp, argv[3], &y) != TCL_OK)) {
        !           323:     return TCL_ERROR;
        !           324:   }
        !           325: 
        !           326:   ToolDrag(view, x, y); Kick();
        !           327:   return TCL_OK;
        !           328: }
        !           329: 
        !           330: 
        !           331: int EditorCmdToolUp(VIEW_ARGS)
        !           332: {
        !           333:   int x, y;
        !           334: 
        !           335:   if (argc != 4) {
        !           336:     return TCL_ERROR;
        !           337:   }
        !           338: 
        !           339:   if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK) ||
        !           340:       (Tcl_GetInt(interp, argv[3], &y) != TCL_OK)) {
        !           341:     return TCL_ERROR;
        !           342:   }
        !           343: 
        !           344:   ToolUp(view, x, y); Kick();
        !           345:   return TCL_OK;
        !           346: }
        !           347: 
        !           348: 
        !           349: int EditorCmdPanStart(VIEW_ARGS)
        !           350: {
        !           351:   int x, y;
        !           352: 
        !           353:   if (argc != 4) {
        !           354:     return TCL_ERROR;
        !           355:   }
        !           356: 
        !           357:   if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK) ||
        !           358:       (Tcl_GetInt(interp, argv[3], &y) != TCL_OK)) {
        !           359:     return TCL_ERROR;
        !           360:   }
        !           361: 
        !           362:   view->last_x = x;
        !           363:   view->last_y = y;
        !           364:   return TCL_OK;
        !           365: }
        !           366: 
        !           367: 
        !           368: int EditorCmdPanTo(VIEW_ARGS)
        !           369: {
        !           370:   int x, y, dx, dy;
        !           371: 
        !           372:   if (argc != 4) {
        !           373:     return TCL_ERROR;
        !           374:   }
        !           375: 
        !           376:   if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK) ||
        !           377:       (Tcl_GetInt(interp, argv[3], &y) != TCL_OK)) {
        !           378:     return TCL_ERROR;
        !           379:   }
        !           380: 
        !           381:   dx = (view->tool_x_const == -1) ? (view->last_x - x) : 0;
        !           382:   dy = (view->tool_y_const == -1) ? (view->last_y - y) : 0;
        !           383:   if (dx || dy) {
        !           384:     view->last_x = x;
        !           385:     view->last_y = y;
        !           386:     DoPanBy(view, dx, dy); Kick();
        !           387:   }
        !           388:   return TCL_OK;
        !           389: }
        !           390: 
        !           391: 
        !           392: int EditorCmdPanBy(VIEW_ARGS)
        !           393: {
        !           394:   int dx, dy;
        !           395: 
        !           396:   if (argc != 4) {
        !           397:     return TCL_ERROR;
        !           398:   }
        !           399: 
        !           400:   if ((Tcl_GetInt(interp, argv[2], &dx) != TCL_OK) ||
        !           401:       (Tcl_GetInt(interp, argv[3], &dy) != TCL_OK)) {
        !           402:     return TCL_ERROR;
        !           403:   }
        !           404: 
        !           405:   DoPanBy(view, dx, dy); Kick();
        !           406:   return TCL_OK;
        !           407: }
        !           408: 
        !           409: 
        !           410: int EditorCmdTweakCursor(VIEW_ARGS)
        !           411: {
        !           412:   int x, y;
        !           413: 
        !           414:   XWarpPointer (view->x->dpy, None, None, 0, 0, 0, 0, 0, 0);
        !           415: 
        !           416:   return TCL_OK;
        !           417: }
        !           418: 
        !           419: 
        !           420: int EditorCmdVisible(VIEW_ARGS)
        !           421: {
        !           422:   int visible;
        !           423: 
        !           424:   if ((argc != 2) && (argc != 3)) {
        !           425:     return TCL_ERROR;
        !           426:   }
        !           427: 
        !           428:   if (argc == 3) {
        !           429:     if ((Tcl_GetInt(interp, argv[2], &visible) != TCL_OK) ||
        !           430:        (visible < 0) || (visible > 1)) {
        !           431:       return TCL_ERROR;
        !           432:     }
        !           433: 
        !           434:     visible = visible && Tk_IsMapped(view->tkwin);
        !           435:     view->visible = visible;
        !           436:   }
        !           437: 
        !           438:   sprintf(interp->result, "%d", view->visible);
        !           439:   return TCL_OK;
        !           440: }
        !           441: 
        !           442: 
        !           443: int EditorCmdKeyDown(VIEW_ARGS)
        !           444: {
        !           445: 
        !           446:   if (argc != 3) {
        !           447:     return TCL_ERROR;
        !           448:   }
        !           449: 
        !           450:   doKeyDown(view, argv[2][0]);
        !           451:   return TCL_OK;
        !           452: }
        !           453: 
        !           454: 
        !           455: int EditorCmdKeyUp(VIEW_ARGS)
        !           456: {
        !           457: 
        !           458:   if (argc != 3) {
        !           459:     return TCL_ERROR;
        !           460:   }
        !           461: 
        !           462:   doKeyUp(view, argv[2][0]);
        !           463:   return TCL_OK;
        !           464: }
        !           465: 
        !           466: 
        !           467: int EditorCmdTileCoord(VIEW_ARGS)
        !           468: {
        !           469:   int x, y;
        !           470: 
        !           471:   if ((argc != 2) && (argc != 4)) {
        !           472:     return TCL_ERROR;
        !           473:   }
        !           474: 
        !           475:   if (Tcl_GetInt(interp, argv[2], &x) != TCL_OK) {
        !           476:     return TCL_ERROR;
        !           477:   }
        !           478:   if (Tcl_GetInt(interp, argv[3], &y) != TCL_OK) {
        !           479:     return TCL_ERROR;
        !           480:   }
        !           481: 
        !           482:   ViewToTileCoords(view, x, y, &x, &y);
        !           483: 
        !           484:   sprintf(interp->result, "%d %d", x, y);
        !           485:   return TCL_OK;
        !           486: }
        !           487: 
        !           488: 
        !           489: int EditorCmdChalkStart(VIEW_ARGS)
        !           490: {
        !           491:   int x, y;
        !           492: 
        !           493:   if (argc != 4) {
        !           494:     return TCL_ERROR;
        !           495:   }
        !           496: 
        !           497:   if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK) ||
        !           498:       (Tcl_GetInt(interp, argv[3], &y) != TCL_OK)) {
        !           499:     return TCL_ERROR;
        !           500:   }
        !           501: 
        !           502:   ChalkStart(view, x, y, COLOR_WHITE);
        !           503:   return TCL_OK;
        !           504: }
        !           505: 
        !           506: 
        !           507: int EditorCmdChalkTo(VIEW_ARGS)
        !           508: {
        !           509:   int x, y;
        !           510: 
        !           511:   if (argc != 4) {
        !           512:     return TCL_ERROR;
        !           513:   }
        !           514: 
        !           515:   if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK) ||
        !           516:       (Tcl_GetInt(interp, argv[3], &y) != TCL_OK)) {
        !           517:     return TCL_ERROR;
        !           518:   }
        !           519: 
        !           520:   ChalkTo(view, x, y);
        !           521:   return TCL_OK;
        !           522: }
        !           523: 
        !           524: 
        !           525: int EditorCmdAutoGoing(VIEW_ARGS)
        !           526: {
        !           527:   int flag;
        !           528: 
        !           529:   if ((argc != 2) && (argc != 3)) {
        !           530:     return TCL_ERROR;
        !           531:   }
        !           532: 
        !           533:   if (argc == 3) {
        !           534:     if ((Tcl_GetInt(interp, argv[2], &flag) != TCL_OK)) {
        !           535:       return TCL_ERROR;
        !           536:     }
        !           537: 
        !           538:     view->auto_going = flag;
        !           539:     if (view->auto_goto == -1)
        !           540:       view->auto_goto = 0;
        !           541:   }
        !           542: 
        !           543:   sprintf(interp->result, "%d", view->auto_going);
        !           544:   return TCL_OK;
        !           545: }
        !           546: 
        !           547: 
        !           548: int EditorCmdAutoSpeed(VIEW_ARGS)
        !           549: {
        !           550:   int speed;
        !           551: 
        !           552:   if ((argc != 2) && (argc != 3)) {
        !           553:     return TCL_ERROR;
        !           554:   }
        !           555: 
        !           556:   if (argc == 3) {
        !           557:     if ((Tcl_GetInt(interp, argv[2], &speed) != TCL_OK) ||
        !           558:        (speed < 1)) {
        !           559:       return TCL_ERROR;
        !           560:     }
        !           561: 
        !           562:     view->auto_speed = speed;
        !           563:   }
        !           564: 
        !           565:   sprintf(interp->result, "%d", view->auto_speed);
        !           566:   return TCL_OK;
        !           567: }
        !           568: 
        !           569: 
        !           570: int EditorCmdAutoGoal(VIEW_ARGS)
        !           571: {
        !           572:   if ((argc != 2) && (argc != 4)) {
        !           573:     return TCL_ERROR;
        !           574:   }
        !           575:   if (argc == 4) {
        !           576:     int x, y, dx, dy;
        !           577: 
        !           578:     if (Tcl_GetInt(interp, argv[2], &x) != TCL_OK) {
        !           579:       return TCL_ERROR;
        !           580:     }
        !           581:     if (Tcl_GetInt(interp, argv[3], &y) != TCL_OK) {
        !           582:       return TCL_ERROR;
        !           583:     }
        !           584:     view->auto_x_goal = x;
        !           585:     view->auto_y_goal = y;
        !           586:     /* actually go there if more than a block away */
        !           587:     dx = view->pan_x - x;
        !           588:     dy = view->pan_y - y;
        !           589:     view->auto_going = (((dx * dx) + (dy * dy)) > (64 * 64));
        !           590:     if ((view->auto_going != 0) &&
        !           591:        (view->auto_goto == 0))
        !           592:       view->auto_goto = -1;
        !           593:   }
        !           594: 
        !           595:   sprintf(interp->result, "%d %d", view->auto_x_goal, view->auto_y_goal);
        !           596:   return TCL_OK;
        !           597: }
        !           598: 
        !           599: 
        !           600: int EditorCmdSU(VIEW_ARGS)
        !           601: {
        !           602:   int su;
        !           603: 
        !           604:   if ((argc != 2) && (argc != 4)) {
        !           605:     return TCL_ERROR;
        !           606:   }
        !           607: 
        !           608:   if (argc == 4) {
        !           609:     if ((strcmp(argv[3], "xyzzy") != 0) ||
        !           610:        (Tcl_GetInt(interp, argv[2], &su) != TCL_OK)) {
        !           611:       return TCL_ERROR;
        !           612:     }
        !           613: 
        !           614:     view->super_user = su;
        !           615:   }
        !           616: 
        !           617:   sprintf(interp->result, "%d", view->super_user);
        !           618:   return TCL_OK;
        !           619: }
        !           620: 
        !           621: 
        !           622: int EditorCmdShowMe(VIEW_ARGS)
        !           623: {
        !           624:   int flag;
        !           625: 
        !           626:   if ((argc != 2) && (argc != 3)) {
        !           627:     return TCL_ERROR;
        !           628:   }
        !           629: 
        !           630:   if (argc == 3) {
        !           631:     if (Tcl_GetInt(interp, argv[2], &flag) != TCL_OK) {
        !           632:       return TCL_ERROR;
        !           633:     }
        !           634: 
        !           635:     view->show_me = flag;
        !           636:   }
        !           637: 
        !           638:   sprintf(interp->result, "%d", view->show_me);
        !           639:   return TCL_OK;
        !           640: }
        !           641: 
        !           642: 
        !           643: int EditorCmdFollow(VIEW_ARGS)
        !           644: {
        !           645:   int id;
        !           646:   SimSprite *sprite;
        !           647: 
        !           648:   if ((argc != 2) && (argc != 3)) {
        !           649:     return TCL_ERROR;
        !           650:   }
        !           651: 
        !           652:   if (argc == 3) {
        !           653:     view->follow = NULL;
        !           654:     if (argv[2][0] != '\0') {
        !           655:       for (sprite = sim->sprite; sprite != NULL; sprite = sprite->next) {
        !           656:        if (strcmp(sprite->name, argv[2]) == 0) {
        !           657:          view->follow = sprite;
        !           658:          break;
        !           659:        }
        !           660:       }
        !           661:     }
        !           662: 
        !           663:     if (view->follow != NULL) {
        !           664:       HandleAutoGoto(view);
        !           665:     }
        !           666:   }
        !           667: 
        !           668:   sprintf(interp->result, "%s",
        !           669:          (view->follow == NULL) ? "" : view->follow->name);
        !           670:   return TCL_OK;
        !           671: }
        !           672: 
        !           673: 
        !           674: int EditorCmdShowOverlay(VIEW_ARGS)
        !           675: {
        !           676:   int flag;
        !           677: 
        !           678:   if ((argc != 2) && (argc != 3)) {
        !           679:     return TCL_ERROR;
        !           680:   }
        !           681: 
        !           682:   if (argc == 3) {
        !           683:     if ((Tcl_GetInt(interp, argv[2], &flag) != TCL_OK)) {
        !           684:       return TCL_ERROR;
        !           685:     }
        !           686: 
        !           687:     view->show_overlay = flag;
        !           688:   }
        !           689: 
        !           690:   sprintf(interp->result, "%d", view->show_overlay);
        !           691:   return TCL_OK;
        !           692: }
        !           693: 
        !           694: 
        !           695: int EditorCmdOverlayMode(VIEW_ARGS)
        !           696: {
        !           697:   int flag;
        !           698: 
        !           699:   if ((argc != 2) && (argc != 3)) {
        !           700:     return TCL_ERROR;
        !           701:   }
        !           702: 
        !           703:   if (argc == 3) {
        !           704:     if ((Tcl_GetInt(interp, argv[2], &flag) != TCL_OK)) {
        !           705:       return TCL_ERROR;
        !           706:     }
        !           707: 
        !           708:     view->overlay_mode = flag;
        !           709:   }
        !           710: 
        !           711:   sprintf(interp->result, "%d", view->overlay_mode);
        !           712:   return TCL_OK;
        !           713: }
        !           714: 
        !           715: 
        !           716: int EditorCmdDynamicFilter(VIEW_ARGS)
        !           717: {
        !           718:   int val;
        !           719: 
        !           720:   if ((argc != 2) && (argc != 3)) {
        !           721:     return TCL_ERROR;
        !           722:   }
        !           723: 
        !           724:   if (argc == 3) {
        !           725:     if ((Tcl_GetInt(interp, argv[2], &val) != TCL_OK)) {
        !           726:       return TCL_ERROR;
        !           727:     }
        !           728: 
        !           729:     view->dynamic_filter = val;
        !           730:   }
        !           731: 
        !           732:   sprintf(interp->result, "%d", view->dynamic_filter);
        !           733:   return TCL_OK;
        !           734: }
        !           735: 
        !           736: 
        !           737: int EditorCmdWriteJpeg(VIEW_ARGS)
        !           738: {
        !           739:   int val;
        !           740:   char *fileName = argv[2];
        !           741: 
        !           742:   if (argc != 3) {
        !           743:     return TCL_ERROR;
        !           744:   }
        !           745:   
        !           746:   // Write a jpeg file of this view.
        !           747: 
        !           748:   return TCL_OK;
        !           749: }
        !           750: 
        !           751: 
        !           752: editor_command_init()
        !           753: {
        !           754:   int new;
        !           755:   extern int TileViewCmd(CLIENT_ARGS);
        !           756: 
        !           757:   Tcl_CreateCommand(tk_mainInterp, "editorview", TileViewCmd,
        !           758:                    (ClientData)MainWindow, (void (*)()) NULL);
        !           759: 
        !           760:   Tcl_InitHashTable(&EditorCmds, TCL_STRING_KEYS);
        !           761: 
        !           762: #define EDITOR_CMD(name) HASHED_CMD(Editor, name)
        !           763: 
        !           764:   EDITOR_CMD(configure);
        !           765:   EDITOR_CMD(position);
        !           766:   EDITOR_CMD(size);
        !           767:   EDITOR_CMD(AutoGoto);
        !           768:   EDITOR_CMD(Sound);
        !           769:   EDITOR_CMD(Skip);
        !           770:   EDITOR_CMD(Update);
        !           771:   EDITOR_CMD(Pan);
        !           772:   EDITOR_CMD(ToolConstrain);
        !           773:   EDITOR_CMD(ToolState);
        !           774:   EDITOR_CMD(ToolMode);
        !           775:   EDITOR_CMD(DoTool);
        !           776:   EDITOR_CMD(ToolDown);
        !           777:   EDITOR_CMD(ToolDrag);
        !           778:   EDITOR_CMD(ToolUp);
        !           779:   EDITOR_CMD(PanStart);
        !           780:   EDITOR_CMD(PanTo);
        !           781:   EDITOR_CMD(PanBy);
        !           782:   EDITOR_CMD(TweakCursor);
        !           783:   EDITOR_CMD(Visible);
        !           784:   EDITOR_CMD(KeyDown);
        !           785:   EDITOR_CMD(KeyUp);
        !           786:   EDITOR_CMD(TileCoord);
        !           787:   EDITOR_CMD(ChalkStart);
        !           788:   EDITOR_CMD(ChalkTo);
        !           789:   EDITOR_CMD(AutoGoing);
        !           790:   EDITOR_CMD(AutoSpeed);
        !           791:   EDITOR_CMD(AutoGoal);
        !           792:   EDITOR_CMD(SU);
        !           793:   EDITOR_CMD(ShowMe);
        !           794:   EDITOR_CMD(Follow);
        !           795:   EDITOR_CMD(ShowOverlay);
        !           796:   EDITOR_CMD(OverlayMode);
        !           797:   EDITOR_CMD(DynamicFilter);
        !           798: }
        !           799: 
        !           800: 
        !           801: int
        !           802: DoEditorCmd(CLIENT_ARGS)
        !           803: {
        !           804:   SimView *view = (SimView *) clientData;
        !           805:   Tcl_HashEntry *ent;
        !           806:   int result = TCL_OK;
        !           807:   int (*cmd)();
        !           808: 
        !           809:   if (argc < 2) {
        !           810:     return TCL_ERROR;
        !           811:   }
        !           812: 
        !           813:   if (ent = Tcl_FindHashEntry(&EditorCmds, argv[1])) {
        !           814:     cmd = (int (*)())ent->clientData;
        !           815:     Tk_Preserve((ClientData) view);
        !           816:     result = cmd(view, interp, argc, argv);
        !           817:     Tk_Release((ClientData) view);
        !           818:   } else {
        !           819:     Tcl_AppendResult(interp, "unknown command name: \"",
        !           820:                     argv[0], " ", argv[1], "\".", (char *) NULL);
        !           821:     result = TCL_ERROR;
        !           822:   }
        !           823:   return result;
        !           824: }
        !           825: 
        !           826: 
        !           827: 
        !           828: /*************************************************************************/
        !           829: 
        !           830: 
        !           831: DoNewEditor(SimView *view)
        !           832: {
        !           833:   sim->editors++; view->next = sim->editor; sim->editor = view;
        !           834:   view->invalid = 1;
        !           835: }
        !           836: 
        !           837: 
        !           838: DoUpdateEditor(SimView *view)
        !           839: {
        !           840:   int dx, dy, i;
        !           841: 
        !           842:   view->updates++;
        !           843: 
        !           844:   if (!view->visible) {
        !           845:     return;
        !           846:   }
        !           847: 
        !           848:   if ((!ShakeNow) &&
        !           849: //      (!view->invalid) &&
        !           850:       (!view->update) &&
        !           851:       (sim_skips ||
        !           852:        view->skips)) {
        !           853:     if (sim_skips) {
        !           854:       if (sim_skip > 0) {
        !           855:        return 0;
        !           856:       }
        !           857:     } else {
        !           858:       if (view->skip > 0) {
        !           859:        --view->skip;
        !           860:        return 0;
        !           861:       } else {
        !           862:        view->skip = view->skips;
        !           863:       }
        !           864:     }
        !           865:   }
        !           866: 
        !           867:   view->skips = 0;
        !           868:   view->update = 0;
        !           869: 
        !           870:   HandleAutoGoto(view);
        !           871: 
        !           872:   if (DoAnimation && SimSpeed && !heat_steps && !TilesAnimated) {
        !           873:     TilesAnimated = 1;
        !           874:     animateTiles();
        !           875:   }
        !           876: 
        !           877:   if (view->invalid) {
        !           878: 
        !           879:     switch (view->type) {
        !           880: 
        !           881:     case X_Mem_View:
        !           882:       MemDrawBeegMapRect(view, view->tile_x, view->tile_y,
        !           883:                         view->tile_width, view->tile_height);
        !           884:       break;
        !           885: 
        !           886:     case X_Wire_View:
        !           887:       WireDrawBeegMapRect(view, view->tile_x, view->tile_y,
        !           888:                          view->tile_width, view->tile_height);
        !           889:       break;
        !           890: 
        !           891:     }
        !           892: 
        !           893:     XCopyArea(view->x->dpy, view->pixmap, view->pixmap2, view->x->gc,
        !           894:              0, 0, view->screen_width, view->screen_height,
        !           895:              view->screen_x, view->screen_y);
        !           896:     DrawOutside(view);
        !           897:     if (PendingTool != -1) {
        !           898:       DrawPending(view);
        !           899:     }
        !           900:     DrawObjects(view);
        !           901:     if (view->show_overlay) {
        !           902:       DrawOverlay(view);
        !           903:     }
        !           904:   }
        !           905: 
        !           906:   for (dx = dy = i = 0; i < ShakeNow; i++) {
        !           907:     dx += Rand(16) - 8;
        !           908:     dy += Rand(16) - 8;
        !           909:   }
        !           910: 
        !           911:   XCopyArea(view->x->dpy, view->pixmap2,
        !           912:            Tk_WindowId(view->tkwin), view->x->gc,
        !           913:            0, 0, view->w_width, view->w_height, dx, dy);
        !           914: 
        !           915:   DrawCursor(view);
        !           916: 
        !           917:   view->invalid = 0;
        !           918: }
        !           919: 
        !           920: 
        !           921: HandleAutoGoto(SimView *view)
        !           922: {
        !           923:   if (view->follow != NULL) {
        !           924:     int x = view->follow->x + view->follow->x_hot,
        !           925:         y = view->follow->y + view->follow->y_hot;
        !           926: 
        !           927:     if ((x != view->pan_x) ||
        !           928:        (y != view->pan_y)) {
        !           929:       DoPanTo(view, x, y);
        !           930:     }
        !           931:   } else if (view->auto_goto &&
        !           932:             view->auto_going &&
        !           933:             (view->tool_mode == 0)) {
        !           934:     int dx, dy;
        !           935:     int panx, pany, speed;
        !           936:     double dist, sloth;
        !           937: 
        !           938:     speed = view->auto_speed;
        !           939: 
        !           940:     if (view->auto_going < 5) {
        !           941:       sloth = ((double)view->auto_going) / 5.0;
        !           942:     } else {
        !           943:       sloth = 1.0;
        !           944:     }
        !           945: 
        !           946:     dx = view->auto_x_goal - view->pan_x;
        !           947:     dy = view->auto_y_goal - view->pan_y;
        !           948: 
        !           949:     dist = sqrt((double)((dx * dx) + (dy * dy)));
        !           950: 
        !           951:     if (dist < (speed * sloth)) {
        !           952:       view->auto_going = 0;
        !           953:       if (view->auto_goto == -1)
        !           954:        view->auto_goto = 0;
        !           955:       DoPanTo(view, view->auto_x_goal, view->auto_y_goal);
        !           956:       NewMap = 1;
        !           957:       DidStopPan(view);
        !           958:     } else {
        !           959:       double atan2(), cos(), sin();
        !           960:       double direction, vx, vy;
        !           961:       double co, si;
        !           962: 
        !           963:       direction = (double)atan2((double)dy, (double)dx);
        !           964:       co = (double)cos(direction);
        !           965:       si = (double)sin(direction);
        !           966:       vx = co * (double)speed;
        !           967:       vy = si * (double)speed;
        !           968: 
        !           969:       vx *= sloth; vy *= sloth;
        !           970:       speed *= sloth;
        !           971: 
        !           972:       vx += 0.5; vy += 0.5;
        !           973: 
        !           974:       DoPanBy(view, (int)(vx), (int)(vy));
        !           975:       view->auto_going++;
        !           976:     }
        !           977:   }
        !           978: }
        !           979: 
        !           980: DrawOutside(SimView *view)
        !           981: {
        !           982:   Pixmap pm = view->pixmap2;
        !           983:   int left = (view->w_width / 2) - view->pan_x;
        !           984:   int right = left + view->i_width;
        !           985:   int top = (view->w_height / 2) - view->pan_y;
        !           986:   int bottom = top + view->i_height;
        !           987: 
        !           988:   if ((top > 0) || (bottom < view->w_height) ||
        !           989:       (left > 0) || (right < view->w_width)) {
        !           990:     if (view->x->color) {
        !           991:       XSetForeground(view->x->dpy, view->x->gc,
        !           992:                     view->pixels[COLOR_BLACK]);
        !           993:     } else {
        !           994:       XSetForeground(view->x->dpy, view->x->gc,
        !           995:                     view->pixels[COLOR_WHITE]);
        !           996:     }
        !           997: 
        !           998:     if (top > 0)
        !           999:       XFillRectangle(view->x->dpy, pm, view->x->gc,
        !          1000:                     0, 0, view->w_width, top);
        !          1001:     if (bottom < view->w_height)
        !          1002:       XFillRectangle(view->x->dpy, pm, view->x->gc,
        !          1003:                     0, bottom, view->w_width,
        !          1004:                     view->w_height - bottom);
        !          1005:     if (left > 0)
        !          1006:       XFillRectangle(view->x->dpy, pm, view->x->gc,
        !          1007:                     0, top, left, bottom - top);
        !          1008:     if (right < view->w_width)
        !          1009:       XFillRectangle(view->x->dpy, pm, view->x->gc,
        !          1010:                     right, top, view->w_width - right, bottom - top);
        !          1011:   }
        !          1012: }
        !          1013: 
        !          1014: 
        !          1015: char CursorDashes[] = { 4, 4 };
        !          1016: 
        !          1017: DrawPending(SimView *view)
        !          1018: {
        !          1019:   Pixmap pm = view->pixmap2;
        !          1020:   int left = (view->w_width / 2) - view->pan_x;
        !          1021:   int top = (view->w_height / 2) - view->pan_y;
        !          1022:   int x, y, size;
        !          1023:   char *iconname = NULL;
        !          1024: 
        !          1025:   x = (PendingX - toolOffset[PendingTool]) <<4;
        !          1026:   y = (PendingY - toolOffset[PendingTool]) <<4;
        !          1027:   size = toolSize[PendingTool] <<4;
        !          1028:   x += left; y += top;
        !          1029: 
        !          1030:   XSetStipple(view->x->dpy, view->x->gc, view->x->gray50_stipple);
        !          1031:   XSetTSOrigin(view->x->dpy, view->x->gc, 0, 0);
        !          1032:   XSetForeground(view->x->dpy, view->x->gc, view->x->pixels[COLOR_BLACK]);
        !          1033:   XSetFillStyle(view->x->dpy, view->x->gc, FillStippled);
        !          1034:   XFillRectangle(view->x->dpy, pm, view->x->gc,
        !          1035:                 x, y, size, size);
        !          1036:   XSetFillStyle(view->x->dpy, view->x->gc, FillSolid);
        !          1037: 
        !          1038:   switch (PendingTool) {
        !          1039:   case residentialState:
        !          1040:     iconname = "@images/res.xpm"; break;
        !          1041:   case commercialState:
        !          1042:     iconname = "@images/com.xpm"; break;
        !          1043:   case industrialState:
        !          1044:     iconname = "@images/ind.xpm"; break;
        !          1045:   case fireState:
        !          1046:     iconname = "@images/fire.xpm"; break;
        !          1047:   case policeState:
        !          1048:     iconname = "@images/police.xpm"; break;
        !          1049:   case stadiumState:
        !          1050:     iconname = "@images/stadium.xpm"; break;
        !          1051:   case seaportState:
        !          1052:     iconname = "@images/seaport.xpm"; break;
        !          1053:   case powerState:
        !          1054:     iconname = "@images/coal.xpm"; break;
        !          1055:   case nuclearState:
        !          1056:     iconname = "@images/nuclear.xpm"; break;
        !          1057:   case airportState:
        !          1058:     iconname = "@images/airport.xpm"; break;
        !          1059:   default:
        !          1060:     break;
        !          1061:   }
        !          1062: 
        !          1063:   if (iconname != NULL) {
        !          1064:     Pixmap icon = Tk_GetPixmap(view->interp, view->tkwin, iconname);
        !          1065:     float f;
        !          1066:     int i;
        !          1067: 
        !          1068:     gettimeofday(&now_time, NULL);
        !          1069:     f = (2 * now_time.tv_usec / 1000000.0);
        !          1070:     if (f > 1.0) f = 2.0 - f;
        !          1071:     i = (int)(f * BobHeight * (Players - Votes));
        !          1072: 
        !          1073:     if (icon != None) {
        !          1074:       XCopyArea(view->x->dpy, icon, pm, view->x->gc, 
        !          1075:                0, 0, size, size, x + i, y - i);
        !          1076:     }
        !          1077:   }
        !          1078: }
        !          1079: 
        !          1080: 
        !          1081: DrawCursor(SimView *view)
        !          1082: {
        !          1083:   Pixmap pm = Tk_WindowId(view->tkwin);
        !          1084:   int left = (view->w_width / 2) - view->pan_x;
        !          1085:   int top = (view->w_height / 2) - view->pan_y;
        !          1086:   int x, y, mode, size, offset, fg, bg, light, dark;
        !          1087:   SimView *v;
        !          1088: 
        !          1089:   for (v = sim->editor; v != NULL; v = v->next) {
        !          1090:     mode = v->tool_mode;
        !          1091:     if ((v->show_me != 0) &&
        !          1092:        ((mode == -1) || v->tool_showing)) {
        !          1093:       x = v->tool_x; y = v->tool_y;
        !          1094:       if (mode == -1) { /* pan cursor */
        !          1095: 
        !          1096:        x += left; y += top;
        !          1097: 
        !          1098:        XSetLineAttributes(view->x->dpy, view->x->gc, 3,
        !          1099:                           LineSolid, CapRound, JoinMiter);
        !          1100:        XSetForeground(view->x->dpy, view->x->gc,
        !          1101:                       view->pixels[COLOR_BLACK]);
        !          1102:        XDrawLine(view->x->dpy, pm, view->x->gc,
        !          1103:                  x - 6, y - 6, x + 6, y + 6);
        !          1104:        XDrawLine(view->x->dpy, pm, view->x->gc,
        !          1105:                  x - 6, y + 6, x + 6, y - 6);
        !          1106:        XDrawLine(view->x->dpy, pm, view->x->gc,
        !          1107:                  x - 8, y, x + 8, y);
        !          1108:        XDrawLine(view->x->dpy, pm, view->x->gc,
        !          1109:                  x, y + 8, x, y - 8);
        !          1110:        XSetLineAttributes(view->x->dpy, view->x->gc, 1,
        !          1111:                           LineSolid, CapRound, JoinMiter);
        !          1112:        XSetForeground(view->x->dpy, view->x->gc,
        !          1113:                       view->pixels[COLOR_WHITE]);
        !          1114:        XDrawLine(view->x->dpy, pm, view->x->gc,
        !          1115:                  x - 6, y - 6, x + 6, y + 6);
        !          1116:        XDrawLine(view->x->dpy, pm, view->x->gc,
        !          1117:                  x - 6, y + 6, x + 6, y - 6);
        !          1118:        XDrawLine(view->x->dpy, pm, view->x->gc,
        !          1119:                  x - 8, y, x + 8, y);
        !          1120:        XDrawLine(view->x->dpy, pm, view->x->gc,
        !          1121:                  x, y + 8, x, y - 8);
        !          1122:        XSetLineAttributes(view->x->dpy, view->x->gc, 1,
        !          1123:                           LineSolid, CapButt, JoinMiter);
        !          1124: 
        !          1125:       } else { /* edit cursor */
        !          1126: 
        !          1127:        size = toolSize[v->tool_state];
        !          1128:        fg = toolColors[v->tool_state] & 0xff;
        !          1129:        light = COLOR_WHITE;
        !          1130:        dark = COLOR_BLACK;
        !          1131:        if (mode == 1) {
        !          1132:          int temp = dark;
        !          1133:          dark = light;
        !          1134:          light = temp;
        !          1135:        }
        !          1136:        switch (v->tool_state) {
        !          1137: 
        !          1138:        case chalkState:
        !          1139:          x += left; y += top;
        !          1140:          if (mode == 1) {
        !          1141:            offset = 2;
        !          1142:          } else {
        !          1143:            offset = 0;
        !          1144: 
        !          1145:            if (view->x->color) {
        !          1146:              XSetForeground(view->x->dpy, view->x->gc,
        !          1147:                             view->pixels[COLOR_MEDIUMGRAY]);
        !          1148:              XFillArc(view->x->dpy, pm, view->x->gc,
        !          1149:                       x - 8, y + 7, 7, 7, 0, 360 * 64);
        !          1150:            } else {
        !          1151:              XSetStipple(view->x->dpy, view->x->gc,
        !          1152:                          view->x->gray50_stipple);
        !          1153:              XSetTSOrigin(view->x->dpy, view->x->gc, 0, 0);
        !          1154:              XSetForeground(view->x->dpy, view->x->gc,
        !          1155:                             view->x->pixels[COLOR_BLACK]);
        !          1156:              XSetBackground(view->x->dpy, view->x->gc,
        !          1157:                             view->x->pixels[COLOR_WHITE]);
        !          1158:              XSetFillStyle(view->x->dpy, view->x->gc, FillOpaqueStippled);
        !          1159:              XFillArc(view->x->dpy, pm, view->x->gc,
        !          1160:                       x - 8, y + 7, 7, 7, 0, 360 * 64);
        !          1161:              XSetFillStyle(view->x->dpy, view->x->gc, FillSolid);
        !          1162:            }
        !          1163:          }
        !          1164: 
        !          1165:          if (view->x->color) {
        !          1166:            XSetLineAttributes(view->x->dpy, view->x->gc, 3,
        !          1167:                               LineSolid, CapRound, JoinMiter);
        !          1168:            XSetForeground(view->x->dpy, view->x->gc,
        !          1169:                           view->pixels[COLOR_LIGHTGRAY]);
        !          1170:            XFillArc(view->x->dpy, pm, view->x->gc,
        !          1171:                     x - 6 - offset, y + 5 + offset, 7, 7, 0, 360 * 64);
        !          1172:            XDrawLine(view->x->dpy, pm, view->x->gc,
        !          1173:                      x + 13 - offset, y - 5 + offset,
        !          1174:                      x - 1 - offset, y + 9 + offset);
        !          1175:            XSetForeground(view->x->dpy, view->x->gc,
        !          1176:                           view->pixels[COLOR_WHITE]);
        !          1177:            XDrawLine(view->x->dpy, pm, view->x->gc,
        !          1178:                      x + 11 - offset, y - 7 + offset,
        !          1179:                      x - 3 - offset, y + 7 + offset);
        !          1180:            XFillArc(view->x->dpy, pm, view->x->gc,
        !          1181:                     x + 8 - offset, y - 9 + offset, 7, 7, 0, 360 * 64);
        !          1182:            XSetLineAttributes(view->x->dpy, view->x->gc, 1,
        !          1183:                               LineSolid, CapButt, JoinMiter);
        !          1184:          } else {
        !          1185:            XSetLineAttributes(view->x->dpy, view->x->gc, 3,
        !          1186:                               LineSolid, CapRound, JoinMiter);
        !          1187:            XSetStipple(view->x->dpy, view->x->gc,
        !          1188:                        view->x->gray25_stipple);
        !          1189:            XSetTSOrigin(view->x->dpy, view->x->gc, 0, 0);
        !          1190:            XSetForeground(view->x->dpy, view->x->gc,
        !          1191:                           view->x->pixels[COLOR_BLACK]);
        !          1192:            XSetBackground(view->x->dpy, view->x->gc,
        !          1193:                           view->x->pixels[COLOR_WHITE]);
        !          1194:            XSetFillStyle(view->x->dpy, view->x->gc, FillOpaqueStippled);
        !          1195:            XFillArc(view->x->dpy, pm, view->x->gc,
        !          1196:                     x - 6 - offset, y + 5 + offset, 7, 7, 0, 360 * 64);
        !          1197:            XDrawLine(view->x->dpy, pm, view->x->gc,
        !          1198:                      x + 13 - offset, y - 5 + offset,
        !          1199:                      x - 1 - offset, y + 9 + offset);
        !          1200:            XSetStipple(view->x->dpy, view->x->gc,
        !          1201:                        view->x->gray75_stipple);
        !          1202:            XDrawLine(view->x->dpy, pm, view->x->gc,
        !          1203:                      x + 11 - offset, y - 7 + offset,
        !          1204:                      x - 3 - offset, y + 7 + offset);
        !          1205:            XFillArc(view->x->dpy, pm, view->x->gc,
        !          1206:                     x + 8 - offset, y - 9 + offset, 7, 7, 0, 360 * 64);
        !          1207:            XSetLineAttributes(view->x->dpy, view->x->gc, 1,
        !          1208:                               LineSolid, CapButt, JoinMiter);
        !          1209:            XSetFillStyle(view->x->dpy, view->x->gc, FillSolid);
        !          1210:          }
        !          1211: 
        !          1212:          break;
        !          1213: 
        !          1214:        case eraserState:
        !          1215:          x += left; y += top;
        !          1216:          if (mode == 1) {
        !          1217:            offset = 0;
        !          1218:          } else {
        !          1219:            offset = 2;
        !          1220: 
        !          1221:            if (view->x->color) {
        !          1222:              XSetForeground(view->x->dpy, view->x->gc,
        !          1223:                             view->pixels[COLOR_MEDIUMGRAY]);
        !          1224:              XFillRectangle(view->x->dpy, pm, view->x->gc,
        !          1225:                       x - 8, y - 8, 16, 16);
        !          1226:            } else {
        !          1227:              XSetStipple(view->x->dpy, view->x->gc,
        !          1228:                          view->x->gray50_stipple);
        !          1229:              XSetTSOrigin(view->x->dpy, view->x->gc, 0, 0);
        !          1230:              XSetForeground(view->x->dpy, view->x->gc,
        !          1231:                             view->x->pixels[COLOR_BLACK]);
        !          1232:              XSetBackground(view->x->dpy, view->x->gc,
        !          1233:                             view->x->pixels[COLOR_WHITE]);
        !          1234:              XSetFillStyle(view->x->dpy, view->x->gc, FillOpaqueStippled);
        !          1235:              XFillRectangle(view->x->dpy, pm, view->x->gc,
        !          1236:                       x - 8, y - 8, 16, 16);
        !          1237:              XSetFillStyle(view->x->dpy, view->x->gc, FillSolid);
        !          1238:            }
        !          1239:          }
        !          1240: 
        !          1241:          if (view->x->color) {
        !          1242:            XSetForeground(view->x->dpy, view->x->gc,
        !          1243:                           view->pixels[COLOR_LIGHTGRAY]);
        !          1244:          } else {
        !          1245:            XSetStipple(view->x->dpy, view->x->gc,
        !          1246:                        view->x->gray75_stipple);
        !          1247:            XSetTSOrigin(view->x->dpy, view->x->gc, 0, 0);
        !          1248:            XSetForeground(view->x->dpy, view->x->gc,
        !          1249:                           view->x->pixels[COLOR_BLACK]);
        !          1250:            XSetBackground(view->x->dpy, view->x->gc,
        !          1251:                           view->x->pixels[COLOR_WHITE]);
        !          1252:            XSetFillStyle(view->x->dpy, view->x->gc, FillOpaqueStippled);
        !          1253:          }
        !          1254: 
        !          1255:          /* top */
        !          1256:          XDrawLine(view->x->dpy, pm, view->x->gc,
        !          1257:                    x - 8 + offset, y - 8 - offset,
        !          1258:                    x + 8 + offset, y - 8 - offset);
        !          1259:          XDrawLine(view->x->dpy, pm, view->x->gc,
        !          1260:                    x - 7 + offset, y - 7 - offset,
        !          1261:                    x + 7 + offset, y - 7 - offset);
        !          1262:          XDrawLine(view->x->dpy, pm, view->x->gc,
        !          1263:                    x - 6 + offset, y - 6 - offset,
        !          1264:                    x + 6 + offset, y - 6 - offset);
        !          1265: 
        !          1266:          /* left */
        !          1267:          XDrawLine(view->x->dpy, pm, view->x->gc,
        !          1268:                    x - 8 + offset, y - 8 - offset,
        !          1269:                    x - 8 + offset, y + 8 - offset);
        !          1270:          XDrawLine(view->x->dpy, pm, view->x->gc,
        !          1271:                    x - 7 + offset, y - 7 - offset,
        !          1272:                    x - 7 + offset, y + 7 - offset);
        !          1273:          XDrawLine(view->x->dpy, pm, view->x->gc,
        !          1274:                    x - 6 + offset, y - 6 - offset,
        !          1275:                    x - 6 + offset, y + 6 - offset);
        !          1276: 
        !          1277:          if (view->x->color) {
        !          1278:            XSetForeground(view->x->dpy, view->x->gc,
        !          1279:                           view->pixels[COLOR_BLACK]);
        !          1280:          } else {
        !          1281:            XSetFillStyle(view->x->dpy, view->x->gc, FillSolid);
        !          1282:          }
        !          1283: 
        !          1284:          /* bottom */
        !          1285:          XDrawLine(view->x->dpy, pm, view->x->gc,
        !          1286:                    x - 7 + offset, y + 7 - offset,
        !          1287:                    x + 8 + offset, y + 7 - offset);
        !          1288:          XDrawLine(view->x->dpy, pm, view->x->gc,
        !          1289:                    x - 6 + offset, y + 6 - offset,
        !          1290:                    x + 7 + offset, y + 6 - offset);
        !          1291:          XDrawLine(view->x->dpy, pm, view->x->gc,
        !          1292:                    x - 5 + offset, y + 5 - offset,
        !          1293:                    x + 6 + offset, y + 5 - offset);
        !          1294: 
        !          1295:          /* right */
        !          1296:          XDrawLine(view->x->dpy, pm, view->x->gc,
        !          1297:                    x + 7 + offset, y + 8 - offset,
        !          1298:                    x + 7 + offset, y - 7 - offset);
        !          1299:          XDrawLine(view->x->dpy, pm, view->x->gc,
        !          1300:                    x + 6 + offset, y + 7 - offset,
        !          1301:                    x + 6 + offset, y - 6 - offset);
        !          1302:          XDrawLine(view->x->dpy, pm, view->x->gc,
        !          1303:                    x + 5 + offset, y + 6 - offset,
        !          1304:                    x + 5 + offset, y - 5 - offset);
        !          1305: 
        !          1306:          if (view->x->color) {
        !          1307:            XSetForeground(view->x->dpy, view->x->gc,
        !          1308:                           view->pixels[COLOR_DARKGRAY]);
        !          1309:            XFillRectangle(view->x->dpy, pm, view->x->gc,
        !          1310:                           x - 5 + offset, y - 5 - offset, 10, 10);
        !          1311:          } else {
        !          1312:            XSetStipple(view->x->dpy, view->x->gc,
        !          1313:                        view->x->gray50_stipple);
        !          1314:            XSetForeground(view->x->dpy, view->x->gc,
        !          1315:                           view->x->pixels[COLOR_BLACK]);
        !          1316:            XSetBackground(view->x->dpy, view->x->gc,
        !          1317:                           view->x->pixels[COLOR_WHITE]);
        !          1318:            XSetFillStyle(view->x->dpy, view->x->gc, FillOpaqueStippled);
        !          1319:            XFillRectangle(view->x->dpy, pm, view->x->gc,
        !          1320:                           x - 5 + offset, y - 5 - offset, 10, 10);
        !          1321:            XSetFillStyle(view->x->dpy, view->x->gc, FillSolid);
        !          1322:          }
        !          1323: 
        !          1324:          break;
        !          1325: 
        !          1326:        default:
        !          1327:          offset = toolOffset[v->tool_state];
        !          1328: 
        !          1329:          bg = (toolColors[v->tool_state] >> 8) & 0xff;
        !          1330: 
        !          1331:          x = (x & ~15) - (offset <<4);
        !          1332:          y = (y & ~15) - (offset <<4);
        !          1333:          size <<= 4;
        !          1334:          x += left; y += top;
        !          1335: 
        !          1336:          XSetForeground(view->x->dpy, view->x->gc,
        !          1337:                         view->pixels[dark]);
        !          1338:          XDrawRectangle(view->x->dpy, pm, view->x->gc,
        !          1339:                         x - 1, y - 1, size + 4, size + 4);
        !          1340:          XDrawLine(view->x->dpy, pm, view->x->gc,
        !          1341:                    x - 3, y + size + 3,
        !          1342:                    x - 1, y + size + 3);
        !          1343:          XDrawLine(view->x->dpy, pm, view->x->gc,
        !          1344:                    x + size + 3, y - 3,
        !          1345:                    x + size + 3, y - 1);
        !          1346: 
        !          1347:          XSetForeground(view->x->dpy, view->x->gc,
        !          1348:                         view->pixels[light]);
        !          1349:          XDrawRectangle(view->x->dpy, pm, view->x->gc,
        !          1350:                         x - 4, y - 4, size + 4, size + 4);
        !          1351:          XDrawLine(view->x->dpy, pm, view->x->gc,
        !          1352:                    x - 4, y + size + 1,
        !          1353:                    x - 4, y + size + 3);
        !          1354:          XDrawLine(view->x->dpy, pm, view->x->gc,
        !          1355:                    x + size + 1, y - 4,
        !          1356:                    x + size + 3, y - 4);
        !          1357: 
        !          1358:          if (view->x->color) {
        !          1359:            if (fg == bg) {
        !          1360:              XSetForeground(view->x->dpy, view->x->gc,
        !          1361:                             view->x->pixels[fg]);
        !          1362:              XSetLineAttributes(view->x->dpy, view->x->gc, 2,
        !          1363:                                 LineSolid, CapButt, JoinMiter);
        !          1364:            } else {
        !          1365:              XSetForeground(view->x->dpy, view->x->gc,
        !          1366:                             view->x->pixels[fg]);
        !          1367:              XSetBackground(view->x->dpy, view->x->gc,
        !          1368:                             view->pixels[bg]);
        !          1369: 
        !          1370:              XSetLineAttributes(view->x->dpy, view->x->gc, 2,
        !          1371:                                 LineDoubleDash, CapButt, JoinMiter);
        !          1372:              XSetDashes(view->x->dpy, view->x->gc, 0, CursorDashes, 2);
        !          1373:            }
        !          1374:          } else {
        !          1375:            XSetStipple(view->x->dpy, view->x->gc,
        !          1376:                        view->x->gray50_stipple);
        !          1377:            XSetForeground(view->x->dpy, view->x->gc,
        !          1378:                           view->x->pixels[COLOR_BLACK]);
        !          1379:            XSetBackground(view->x->dpy, view->x->gc,
        !          1380:                           view->x->pixels[COLOR_WHITE]);
        !          1381:            XSetFillStyle(view->x->dpy, view->x->gc, FillOpaqueStippled);
        !          1382:            XSetLineAttributes(view->x->dpy, view->x->gc, 2,
        !          1383:                               LineSolid, CapButt, JoinMiter);
        !          1384:          }
        !          1385: 
        !          1386:          XDrawLine(view->x->dpy, pm, view->x->gc,
        !          1387:                    x - 2, y - 1, x - 2, y + size + 3);
        !          1388:          XDrawLine(view->x->dpy, pm, view->x->gc,
        !          1389:                    x - 1, y + size + 2, x + size + 3, y + size + 2);
        !          1390:          XDrawLine(view->x->dpy, pm, view->x->gc,
        !          1391:                    x + size + 2, y + size + 1, x + size + 2, y - 3);
        !          1392:          XDrawLine(view->x->dpy, pm, view->x->gc,
        !          1393:                    x + size + 1, y - 2, x - 3, y - 2);
        !          1394: 
        !          1395:          if (!view->x->color) {
        !          1396:            XSetFillStyle(view->x->dpy, view->x->gc, FillSolid);
        !          1397:          }
        !          1398:          XSetLineAttributes(view->x->dpy, view->x->gc, 1,
        !          1399:                             LineSolid, CapButt, JoinMiter);
        !          1400:          
        !          1401:          break;
        !          1402:        }
        !          1403:       }
        !          1404:     }
        !          1405:   }
        !          1406: }
        !          1407: 
        !          1408: 
        !          1409: TimeElapsed(struct timeval *elapsed,
        !          1410:            struct timeval *start,
        !          1411:            struct timeval *finish)
        !          1412: {
        !          1413:   int usec = finish->tv_usec - start->tv_usec;
        !          1414:   int sec = finish->tv_sec - start->tv_sec;
        !          1415: 
        !          1416:   while (usec < 0) {
        !          1417:     usec += 1000000;
        !          1418:     sec--;
        !          1419:   }
        !          1420:   elapsed->tv_usec = usec;
        !          1421:   elapsed->tv_sec = sec;
        !          1422: }
        !          1423: 
        !          1424: 
        !          1425: 
        !          1426: DrawOverlay(SimView *view)
        !          1427: {
        !          1428:   int width = view->w_width;
        !          1429:   int height = view->w_height;
        !          1430:   int left = view->pan_x - (width / 2);
        !          1431:   int top = view->pan_y - (height / 2);
        !          1432:   int right = left + width;
        !          1433:   int bottom = top + height;
        !          1434:   int showing = 0;
        !          1435:   Ink *ink;
        !          1436:   struct timeval start, finished, elapsed;
        !          1437: 
        !          1438:   for (ink = sim->overlay; ink != NULL; ink = ink->next) {
        !          1439:     if ((ink->bottom >= top) && (ink->top <= bottom) &&
        !          1440:        (ink->right >= left) && (ink->left <= right)) {
        !          1441:       showing = 1;
        !          1442:       break;
        !          1443:     }
        !          1444:   }
        !          1445: 
        !          1446:   if (!showing) return;
        !          1447: 
        !          1448: /* overlay_mode state machine:
        !          1449:    0 => overlay invalid: 
        !          1450:         draw lines to pm => 1
        !          1451:    1 => overlay stable: 
        !          1452:         sync, time draw lines to pm => 2
        !          1453:    2 => overlay stable: 
        !          1454:         draw lines to ol,
        !          1455:         sync, time clip ol to pm,
        !          1456:         lines faster? => 3,
        !          1457:        clipping faster? => 4
        !          1458:    3 => lines faster: 
        !          1459:         draw lines to pm => 3
        !          1460:    4 => clipping faster: 
        !          1461:         clip ol to pm => 4
        !          1462: */   
        !          1463: 
        !          1464:   switch (view->overlay_mode) {
        !          1465:   case 0:
        !          1466:     DrawTheOverlay(view, view->x->gc,
        !          1467:                   view->pixmap2, view->pixels[COLOR_WHITE],
        !          1468:                   top, bottom, left, right, 0);
        !          1469:     view->overlay_mode = 1;
        !          1470:     break;
        !          1471:   case 1:
        !          1472:     XSync(view->x->dpy, False);
        !          1473:     gettimeofday(&start, NULL);
        !          1474:     DrawTheOverlay(view, view->x->gc,
        !          1475:                   view->pixmap2, view->pixels[COLOR_WHITE],
        !          1476:                   top, bottom, left, right, 0);
        !          1477:     XSync(view->x->dpy, False);
        !          1478:     gettimeofday(&finished, NULL);
        !          1479:     TimeElapsed(&view->overlay_time, &start, &finished);
        !          1480:     view->overlay_mode = 2;
        !          1481:     break;
        !          1482:   case 2:
        !          1483:     XSetForeground(view->x->dpy, view->x->overlay_gc, 0);
        !          1484:     XFillRectangle(view->x->dpy, view->overlay_pixmap, view->x->overlay_gc,
        !          1485:                   0, 0, view->m_width, view->m_height);
        !          1486:     DrawTheOverlay(view, view->x->overlay_gc,
        !          1487:                   view->overlay_pixmap, 1,
        !          1488:                   top, bottom, left, right, 1);
        !          1489:     XSync(view->x->dpy, False);
        !          1490:     gettimeofday(&start, NULL);
        !          1491:     ClipTheOverlay(view);
        !          1492:     XSync(view->x->dpy, False);
        !          1493:     gettimeofday(&finished, NULL);
        !          1494:     TimeElapsed(&elapsed, &start, &finished);
        !          1495:     if ((elapsed.tv_sec > view->overlay_time.tv_sec) ||
        !          1496:        ((elapsed.tv_sec == view->overlay_time.tv_sec) &&
        !          1497:         ((elapsed.tv_usec > view->overlay_time.tv_usec)))) {
        !          1498:       view->overlay_mode = 3;
        !          1499:     } else {
        !          1500:       view->overlay_mode = 4;
        !          1501:     }
        !          1502:     break;
        !          1503:   case 3:
        !          1504:     DrawTheOverlay(view, view->x->gc,
        !          1505:                   view->pixmap2, view->pixels[COLOR_WHITE],
        !          1506:                   top, bottom, left, right, 0);
        !          1507:     break;
        !          1508:   case 4:
        !          1509:     ClipTheOverlay(view);
        !          1510:     break;
        !          1511:   }
        !          1512: }
        !          1513: 
        !          1514: 
        !          1515: DrawTheOverlay(SimView *view, GC gc, Pixmap pm, int color, 
        !          1516:               int top, int bottom, int left, int right,
        !          1517:               int onoverlay)
        !          1518: {
        !          1519:   Ink *ink;
        !          1520: 
        !          1521:   if (view->x->color) {
        !          1522:     XSetForeground(view->x->dpy, gc, color);
        !          1523:     XSetLineAttributes(view->x->dpy, gc, 3,
        !          1524:                       LineSolid, CapButt, JoinBevel);
        !          1525:   } else {
        !          1526:     if (!onoverlay) {
        !          1527:       XSetStipple(view->x->dpy, gc, view->x->gray50_stipple);
        !          1528:       XSetTSOrigin(view->x->dpy, gc, view->updates & 1, 0);
        !          1529:       XSetBackground(view->x->dpy, gc, 0);
        !          1530:       XSetFillStyle(view->x->dpy, gc, FillOpaqueStippled);
        !          1531:     }
        !          1532:     XSetForeground(view->x->dpy, gc, 1);
        !          1533:     XSetLineAttributes(view->x->dpy, gc, 3,
        !          1534:                       LineSolid, CapButt, JoinBevel);
        !          1535:   }
        !          1536:   for (ink = sim->overlay; ink != NULL; ink = ink->next) {
        !          1537:     if ((ink->bottom >= top) && (ink->top <= bottom) &&
        !          1538:        (ink->right >= left) && (ink->left <= right)) {
        !          1539:       if (ink->length <= 1) {
        !          1540:        XFillArc(view->x->dpy, pm, gc,
        !          1541:                 ink->x - 3, ink->y - 3, 6, 6, 0, 360 * 64);
        !          1542:       } else {
        !          1543:        ink->points[0].x = ink->x - left;
        !          1544:        ink->points[0].y = ink->y - top;
        !          1545:        XDrawLines(view->x->dpy, pm, gc,
        !          1546:                   ink->points, ink->length, CoordModePrevious);
        !          1547:       }
        !          1548:     }
        !          1549:   }
        !          1550:   if (!view->x->color) {
        !          1551:     XSetFillStyle(view->x->dpy, gc, FillSolid);
        !          1552:   }
        !          1553:   XSetLineAttributes(view->x->dpy, gc, 1,
        !          1554:                     LineSolid, CapButt, JoinMiter);
        !          1555: }
        !          1556: 
        !          1557: 
        !          1558: ClipTheOverlay(SimView *view)
        !          1559: {
        !          1560:   if (view->x->color) {
        !          1561:     XSetForeground(view->x->dpy, view->x->gc, view->pixels[COLOR_WHITE]);
        !          1562:     XSetFillStyle(view->x->dpy, view->x->gc, FillStippled);
        !          1563:     XSetStipple(view->x->dpy, view->x->gc, view->overlay_pixmap);
        !          1564:     XSetTSOrigin(view->x->dpy, view->x->gc, 0, 0);
        !          1565:     XFillRectangle(view->x->dpy, view->pixmap2, view->x->gc,
        !          1566:                   0, 0, view->w_width, view->w_height);
        !          1567:     XSetFillStyle(view->x->dpy, view->x->gc, FillSolid);
        !          1568:   } else {
        !          1569:     XSetStipple(view->x->dpy, view->x->gc, view->x->gray50_stipple);
        !          1570:     XSetTSOrigin(view->x->dpy, view->x->gc, view->updates & 1, 0);
        !          1571:     XSetForeground(view->x->dpy, view->x->gc, view->pixels[COLOR_WHITE]);
        !          1572:     XSetBackground(view->x->dpy, view->x->gc, view->pixels[COLOR_BLACK]);
        !          1573:     XSetFillStyle(view->x->dpy, view->x->gc, FillOpaqueStippled);
        !          1574:     XSetLineAttributes(view->x->dpy, view->x->gc, 3,
        !          1575:                       LineSolid, CapButt, JoinBevel);
        !          1576:     XSetClipOrigin(view->x->dpy, view->x->gc, 0, 0);
        !          1577:     XSetClipMask(view->x->dpy, view->x->gc, view->overlay_pixmap);
        !          1578:     XFillRectangle(view->x->dpy, view->pixmap2, view->x->gc,
        !          1579:                   0, 0, view->w_width, view->w_height);
        !          1580:     XSetFillStyle(view->x->dpy, view->x->gc, FillSolid);
        !          1581:     XSetClipMask(view->x->dpy, view->x->gc, None);
        !          1582:   }
        !          1583: }

unix.superglobalmegacorp.com

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