Annotation of micropolis/src/sim/w_editor.c, revision 1.1.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.