|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.