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

1.1     ! root        1: /* w_graph.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: short NewGraph = 0;
        !            66: short AllMax;
        !            67: unsigned char *History10[HISTORIES];
        !            68: unsigned char *History120[HISTORIES];
        !            69: int HistoryInitialized = 0;
        !            70: short Graph10Max, Graph120Max;
        !            71: Tcl_HashTable GraphCmds;
        !            72: int GraphUpdateTime = 100;
        !            73: 
        !            74: 
        !            75: #define DEF_GRAPH_FONT "-Adobe-Helvetica-Bold-R-Normal-*-140-*"
        !            76: #define DEF_GRAPH_BG_COLOR     "#b0b0b0"
        !            77: #define DEF_GRAPH_BG_MONO      "#ffffff"
        !            78: #define DEF_GRAPH_BORDER_WIDTH "0"
        !            79: #define DEF_GRAPH_RELIEF       "flat"
        !            80: 
        !            81: Tk_ConfigSpec GraphConfigSpecs[] = {
        !            82:     {TK_CONFIG_FONT, "-font", (char *) NULL, (char *) NULL,
        !            83:        DEF_GRAPH_FONT, Tk_Offset(SimGraph, fontPtr), 0},
        !            84:     {TK_CONFIG_BORDER, "-background", "background", "Background",
        !            85:        DEF_GRAPH_BG_COLOR, Tk_Offset(SimGraph, border),
        !            86:        TK_CONFIG_COLOR_ONLY},
        !            87:     {TK_CONFIG_BORDER, "-background", "background", "Background",
        !            88:        DEF_GRAPH_BG_MONO, Tk_Offset(SimGraph, border),
        !            89:        TK_CONFIG_MONO_ONLY},
        !            90:     {TK_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
        !            91:        DEF_GRAPH_BORDER_WIDTH, Tk_Offset(SimGraph, borderWidth), 0},
        !            92:     {TK_CONFIG_RELIEF, "-relief", "relief", "Relief",
        !            93:        DEF_GRAPH_RELIEF, Tk_Offset(SimGraph, relief), 0},
        !            94:     {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
        !            95:        (char *) NULL, 0, 0}
        !            96:   };
        !            97: 
        !            98: 
        !            99: XDisplay *FindXDisplay();
        !           100: 
        !           101: 
        !           102: static void
        !           103: DisplaySimGraph(ClientData clientData)
        !           104: {
        !           105:   SimGraph *graph = (SimGraph *) clientData;
        !           106:   Tk_Window tkwin = graph->tkwin;
        !           107:   Pixmap pm = None;
        !           108:   Drawable d;
        !           109: 
        !           110:   graph->flags &= ~VIEW_REDRAW_PENDING;
        !           111: 
        !           112: //fprintf(stderr, "DisplaySimGraph token %d\n", graph->draw_graph_token);
        !           113: 
        !           114:   assert(graph->draw_graph_token != 0);
        !           115: 
        !           116:   if (graph->draw_graph_token != 0) {
        !           117: //    Tk_DeleteTimerHandler(graph->draw_graph_token);
        !           118:     graph->draw_graph_token = 0;
        !           119:   }
        !           120: 
        !           121:   if (graph->visible && (tkwin != NULL) && Tk_IsMapped(tkwin)) {
        !           122:     DoUpdateGraph(graph);
        !           123:   }
        !           124: }
        !           125: 
        !           126: 
        !           127: void
        !           128: DestroySimGraph(ClientData clientData)
        !           129: {
        !           130:   SimGraph *graph = (SimGraph *) clientData;
        !           131: 
        !           132:   DestroyGraph(graph);
        !           133: }
        !           134: 
        !           135: 
        !           136: EventuallyRedrawGraph(SimGraph *graph)
        !           137: {
        !           138:   if (!(graph->flags & VIEW_REDRAW_PENDING)) {
        !           139:     assert(graph->draw_graph_token == 0);
        !           140:     if (graph->draw_graph_token == 0) {
        !           141:       graph->draw_graph_token =
        !           142:        Tk_CreateTimerHandler(
        !           143:          GraphUpdateTime,
        !           144:          DisplaySimGraph,
        !           145:          (ClientData) graph);
        !           146:       graph->flags |= VIEW_REDRAW_PENDING;
        !           147: //fprintf(stderr, "EventuallyRedrawGraph token %d\n", graph->draw_graph_token);
        !           148:     }
        !           149:   }
        !           150: }
        !           151: 
        !           152: 
        !           153: void
        !           154: SimGraphEventProc(ClientData clientData, XEvent *eventPtr)
        !           155: {
        !           156:   SimGraph *graph = (SimGraph *) clientData;
        !           157: 
        !           158:   if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) {
        !           159:     graph->visible = 1;
        !           160:     EventuallyRedrawGraph(graph);
        !           161:   } else if (eventPtr->type == MapNotify) {
        !           162:     graph->visible = 1;
        !           163:   } else if (eventPtr->type == UnmapNotify) {
        !           164:     graph->visible = 0;
        !           165:   } else if (eventPtr->type == VisibilityNotify) {
        !           166:     if (eventPtr->xvisibility.state == VisibilityFullyObscured)
        !           167:       graph->visible = 0;
        !           168:     else
        !           169:       graph->visible = 1;
        !           170:   } else if (eventPtr->type == ConfigureNotify) {
        !           171:     DoResizeGraph(graph,
        !           172:                  eventPtr->xconfigure.width,
        !           173:                  eventPtr->xconfigure.height);
        !           174:     EventuallyRedrawGraph(graph);
        !           175:   } else if (eventPtr->type == DestroyNotify) {
        !           176:     Tcl_DeleteCommand(graph->interp, Tk_PathName(graph->tkwin));
        !           177:     graph->tkwin = NULL;
        !           178:     if (graph->flags & VIEW_REDRAW_PENDING) {
        !           179: //fprintf(stderr, "SimGraphEventProc Destroy token %d\n", graph->draw_graph_token);
        !           180:       assert(graph->draw_graph_token != 0);
        !           181:       if (graph->draw_graph_token != 0) {
        !           182:        Tk_DeleteTimerHandler(graph->draw_graph_token);
        !           183:        graph->draw_graph_token = 0;
        !           184:       }
        !           185:       graph->flags &= ~VIEW_REDRAW_PENDING;
        !           186:     }
        !           187:    Tk_EventuallyFree((ClientData) graph, DestroySimGraph);
        !           188:   }
        !           189: }
        !           190: 
        !           191: 
        !           192: int GraphCmdconfigure(GRAPH_ARGS)
        !           193: {
        !           194:   int result = TCL_OK;
        !           195: 
        !           196:   if (argc == 2) {
        !           197:     result = Tk_ConfigureInfo(interp, graph->tkwin, GraphConfigSpecs,
        !           198:                              (char *) graph, (char *) NULL, 0);
        !           199:   } else if (argc == 3) {
        !           200:     result = Tk_ConfigureInfo(interp, graph->tkwin, GraphConfigSpecs,
        !           201:                              (char *) graph, argv[2], 0);
        !           202:   } else {
        !           203:     result = ConfigureSimGraph(interp, graph, argc-2, argv+2,
        !           204:                            TK_CONFIG_ARGV_ONLY);
        !           205:   }
        !           206:   return TCL_OK;
        !           207: }
        !           208: 
        !           209: 
        !           210: int GraphCmdposition(GRAPH_ARGS)
        !           211: {
        !           212:   int result = TCL_OK;
        !           213: 
        !           214:     if ((argc != 2) && (argc != 4)) {
        !           215:       return TCL_ERROR;
        !           216:     }
        !           217:     if (argc == 4) {
        !           218:       if ((Tcl_GetInt(interp, argv[2], &graph->w_x) != TCL_OK)
        !           219:          || (Tcl_GetInt(interp, argv[3], &graph->w_y) != TCL_OK)) {
        !           220:        return TCL_ERROR;
        !           221:       }
        !           222:     }
        !           223:     sprintf(interp->result, "%d %d", graph->w_x, graph->w_y);
        !           224:     return TCL_OK;
        !           225: }
        !           226: 
        !           227: 
        !           228: int GraphCmdsize(GRAPH_ARGS)
        !           229: {
        !           230:   if ((argc != 2) && (argc != 4)) {
        !           231:     return TCL_ERROR;
        !           232:   }
        !           233:   if (argc == 4) {
        !           234:     int w, h;
        !           235:     
        !           236:     if (Tcl_GetInt(interp, argv[2], &w) != TCL_OK) {
        !           237:       return TCL_ERROR;
        !           238:     }
        !           239:     if (Tcl_GetInt(interp, argv[3], &h) != TCL_OK) {
        !           240:       return TCL_ERROR;
        !           241:     }
        !           242:     graph->w_width = w;
        !           243:     graph->w_height = h;
        !           244:   }
        !           245:   sprintf(interp->result, "%d %d", graph->w_width, graph->w_height);
        !           246:   return TCL_OK;
        !           247: }
        !           248: 
        !           249: 
        !           250: int GraphCmdVisible(GRAPH_ARGS)
        !           251: {
        !           252:   int visible;
        !           253: 
        !           254:   if ((argc != 2) && (argc != 3)) {
        !           255:     Tcl_AppendResult(interp, "wrong # args", (char *) NULL);
        !           256:     return TCL_ERROR;
        !           257:   }
        !           258: 
        !           259:   if (argc == 3) {
        !           260:     if ((Tcl_GetInt(interp, argv[2], &visible) != TCL_OK) ||
        !           261:        (visible < 0) || (visible > 1)) {
        !           262:       Tcl_AppendResult(interp, " bogus args", (char *) NULL);
        !           263:       return TCL_ERROR;
        !           264:     }
        !           265: 
        !           266:     graph->visible = visible;
        !           267:   }
        !           268: 
        !           269:   sprintf(interp->result, "%d", graph->visible);
        !           270: 
        !           271:   return TCL_OK;
        !           272: }
        !           273: 
        !           274: 
        !           275: int GraphCmdRange(GRAPH_ARGS)
        !           276: {
        !           277:   int range;
        !           278: 
        !           279:   if ((argc != 2) && (argc != 3)) {
        !           280:     Tcl_AppendResult(interp, "wrong # args", (char *) NULL);
        !           281:     return TCL_ERROR;
        !           282:   }
        !           283: 
        !           284:   if (argc == 3) {
        !           285:     if ((Tcl_GetInt(interp, argv[2], &range) != TCL_OK) ||
        !           286:        ((range != 10) && (range != 120))) {
        !           287:       Tcl_AppendResult(interp, " bogus args", (char *) NULL);
        !           288:       return TCL_ERROR;
        !           289:     }
        !           290: 
        !           291:     graph->range = range;
        !           292:     NewGraph = 1;
        !           293:   }
        !           294: 
        !           295:   sprintf(interp->result, "%d", graph->range);
        !           296: 
        !           297:   return TCL_OK;
        !           298: }
        !           299: 
        !           300: 
        !           301: int GraphCmdMask(GRAPH_ARGS)
        !           302: {
        !           303:   int mask;
        !           304: 
        !           305:   if ((argc != 2) && (argc != 3)) {
        !           306:     Tcl_AppendResult(interp, "wrong # args", (char *) NULL);
        !           307:     return TCL_ERROR;
        !           308:   }
        !           309: 
        !           310:   if (argc == 3) {
        !           311:     if ((Tcl_GetInt(interp, argv[2], &mask) != TCL_OK) ||
        !           312:        (mask < 0) || (mask > 63)) {
        !           313:       Tcl_AppendResult(interp, " bogus args", (char *) NULL);
        !           314:       return TCL_ERROR;
        !           315:     }
        !           316: 
        !           317:     graph->mask = mask;
        !           318:     NewGraph = 1;
        !           319:   }
        !           320: 
        !           321:   sprintf(interp->result, "%d", graph->mask);
        !           322: 
        !           323:   return TCL_OK;
        !           324: }
        !           325: 
        !           326: 
        !           327: int
        !           328: DoGraphCmd(CLIENT_ARGS)
        !           329: {
        !           330:   SimGraph *graph = (SimGraph *) clientData;
        !           331:   Tcl_HashEntry *ent;
        !           332:   int result = TCL_OK;
        !           333:   int (*cmd)();
        !           334: 
        !           335:   if (argc < 2) {
        !           336:     return TCL_ERROR;
        !           337:   }
        !           338: 
        !           339:   if (ent = Tcl_FindHashEntry(&GraphCmds, argv[1])) {
        !           340:     cmd = (int (*)())ent->clientData;
        !           341:     Tk_Preserve((ClientData) graph);
        !           342:     result = cmd(graph, interp, argc, argv);
        !           343:     Tk_Release((ClientData) graph);
        !           344:   } else {
        !           345:     Tcl_AppendResult(interp, "unknown command name: \"",
        !           346:                     argv[0], " ", argv[1], "\".", (char *) NULL);
        !           347:     result = TCL_ERROR;
        !           348:   }
        !           349:   return result;
        !           350: }
        !           351: 
        !           352: 
        !           353: int
        !           354: GraphViewCmd(CLIENT_ARGS)
        !           355: {
        !           356:   SimGraph *graph;
        !           357:   Tk_Window tkwin = (Tk_Window) clientData;
        !           358: 
        !           359:   if (argc < 2) {
        !           360:     Tcl_AppendResult(interp, "wrong # args:  should be \"",
        !           361:                     argv[0], " pathName ?options?\"", (char *) NULL);
        !           362:     return TCL_ERROR;
        !           363:   }
        !           364: 
        !           365:   tkwin = Tk_CreateWindowFromPath(interp, tkwin,
        !           366:                                  argv[1], (char *) NULL);
        !           367:   if (tkwin == NULL) {
        !           368:     return TCL_ERROR;
        !           369:   }
        !           370: 
        !           371:   graph = (SimGraph *)ckalloc(sizeof (SimGraph));
        !           372: 
        !           373:   graph->tkwin = tkwin;
        !           374:   graph->interp = interp;
        !           375:   graph->flags = 0;
        !           376:   
        !           377:   Tk_SetClass(graph->tkwin, "GraphView");
        !           378:   Tk_CreateEventHandler(graph->tkwin,
        !           379:                        VisibilityChangeMask |
        !           380:                        ExposureMask |
        !           381:                        StructureNotifyMask,
        !           382:                        SimGraphEventProc, (ClientData) graph);
        !           383:   Tcl_CreateCommand(interp, Tk_PathName(graph->tkwin),
        !           384:                    DoGraphCmd, (ClientData) graph, (void (*)()) NULL);
        !           385: 
        !           386: /*
        !           387:   Tk_MakeWindowExist(graph->tkwin);
        !           388: */
        !           389:   
        !           390:   if (getenv("XSYNCHRONIZE") != NULL) {
        !           391:     XSynchronize(Tk_Display(tkwin), 1);
        !           392:   }
        !           393: 
        !           394:   InitNewGraph(graph);
        !           395:   DoNewGraph(graph);
        !           396: 
        !           397:   if (ConfigureSimGraph(interp, graph, argc-2, argv+2, 0) != TCL_OK) {
        !           398:     /* XXX: destroy graph */
        !           399:     Tk_DestroyWindow(graph->tkwin);
        !           400:     return TCL_ERROR;
        !           401:   }
        !           402: 
        !           403:   interp->result = Tk_PathName(graph->tkwin);
        !           404:   return TCL_OK;
        !           405: }
        !           406: 
        !           407: 
        !           408: int
        !           409: ConfigureSimGraph(Tcl_Interp *interp, SimGraph *graph,
        !           410:                  int argc, char **argv, int flags)
        !           411: {
        !           412:   if (Tk_ConfigureWidget(interp, graph->tkwin, GraphConfigSpecs,
        !           413:                         argc, argv, (char *) graph, flags) != TCL_OK) {
        !           414:     return TCL_ERROR;
        !           415:   }
        !           416:   
        !           417:   Tk_SetBackgroundFromBorder(graph->tkwin, graph->border);
        !           418: 
        !           419:   EventuallyRedrawGraph(graph);
        !           420:   return TCL_OK;
        !           421: }
        !           422: 
        !           423: 
        !           424: 
        !           425: 
        !           426: char *HistName[] = {
        !           427:   "Residential", "Commercial", "Industrial",
        !           428:   "Cash Flow", "Crime", "Pollution"
        !           429: };
        !           430: 
        !           431: unsigned char HistColor[] = {
        !           432:   COLOR_LIGHTGREEN, COLOR_DARKBLUE, COLOR_YELLOW,
        !           433:   COLOR_DARKGREEN, COLOR_RED, COLOR_OLIVE
        !           434: };
        !           435: 
        !           436: 
        !           437: graph_command_init()
        !           438: {
        !           439:   int new;
        !           440: 
        !           441:   Tcl_CreateCommand(tk_mainInterp, "graphview", GraphViewCmd,
        !           442:                    (ClientData)MainWindow, (void (*)()) NULL);
        !           443: 
        !           444:   Tcl_InitHashTable(&GraphCmds, TCL_STRING_KEYS);
        !           445: 
        !           446: #define GRAPH_CMD(name) HASHED_CMD(Graph, name)
        !           447: 
        !           448:   GRAPH_CMD(configure);
        !           449:   GRAPH_CMD(position);
        !           450:   GRAPH_CMD(size);
        !           451:   GRAPH_CMD(Visible);
        !           452:   GRAPH_CMD(Range);
        !           453:   GRAPH_CMD(Mask);
        !           454: }
        !           455: 
        !           456: 
        !           457: 
        !           458: void
        !           459: drawMonth(short *hist, unsigned char *s, float scale)
        !           460: {
        !           461:   register short val;
        !           462:   register short x;
        !           463: 
        !           464:   for (x = 0; x < 120; x++) {
        !           465:     val = hist[x] * scale;
        !           466:     if (val < 0) val = 0;
        !           467:     if (val > 255) val = 255;
        !           468:     s[119 - x] = val;
        !           469:   }
        !           470: }
        !           471: 
        !           472: 
        !           473: void
        !           474: doAllGraphs(void)
        !           475: {
        !           476:   float scaleValue;
        !           477: 
        !           478:   AllMax = 0;
        !           479:   if (ResHisMax > AllMax) AllMax = ResHisMax;
        !           480:   if (ComHisMax > AllMax) AllMax = ComHisMax;
        !           481:   if (IndHisMax > AllMax) AllMax = IndHisMax;
        !           482:   if (AllMax <= 128) AllMax = 0;
        !           483: 
        !           484:   if (AllMax) {
        !           485:     scaleValue = 128.0 / AllMax;
        !           486:   } else {
        !           487:     scaleValue = 1.0;
        !           488:   }
        !           489: 
        !           490:   // scaleValue = 0.5; // XXX
        !           491: 
        !           492:   drawMonth(ResHis, History10[RES_HIST], scaleValue);
        !           493:   drawMonth(ComHis, History10[COM_HIST], scaleValue);
        !           494:   drawMonth(IndHis, History10[IND_HIST], scaleValue);
        !           495:   drawMonth(MoneyHis, History10[MONEY_HIST], 1.0);
        !           496:   drawMonth(CrimeHis, History10[CRIME_HIST], 1.0);
        !           497:   drawMonth(PollutionHis, History10[POLLUTION_HIST], 1.0);
        !           498: 
        !           499:   AllMax = 0;
        !           500:   if (Res2HisMax > AllMax) AllMax = Res2HisMax;
        !           501:   if (Com2HisMax > AllMax) AllMax = Com2HisMax;
        !           502:   if (Ind2HisMax > AllMax) AllMax = Ind2HisMax;
        !           503:   if (AllMax <= 128) AllMax = 0;
        !           504: 
        !           505:   if (AllMax) {
        !           506:     scaleValue = 128.0 / AllMax;
        !           507:   } else {
        !           508:     scaleValue = 1.0;
        !           509:   }
        !           510: 
        !           511:   // scaleValue = 0.5; // XXX
        !           512: 
        !           513:   drawMonth(ResHis + 120, History120[RES_HIST], scaleValue);
        !           514:   drawMonth(ComHis + 120, History120[COM_HIST], scaleValue);
        !           515:   drawMonth(IndHis + 120, History120[IND_HIST], scaleValue);
        !           516:   drawMonth(MoneyHis + 120, History120[MONEY_HIST], 1.0);
        !           517:   drawMonth(CrimeHis + 120, History120[CRIME_HIST], 1.0);
        !           518:   drawMonth(PollutionHis + 120, History120[POLLUTION_HIST], 1.0);
        !           519: }
        !           520: 
        !           521: 
        !           522: void
        !           523: ChangeCensus(void)
        !           524: {
        !           525:   CensusChanged = 1;
        !           526: }
        !           527: 
        !           528: 
        !           529: void
        !           530: graphDoer(void)
        !           531: {
        !           532:   SimGraph *graph;
        !           533: 
        !           534:   if (CensusChanged) {
        !           535:     doAllGraphs();
        !           536:     NewGraph = 1;
        !           537:     CensusChanged = 0;
        !           538:   }
        !           539: 
        !           540:   if (NewGraph) {
        !           541:     for (graph = sim->graph; graph != NULL; graph = graph->next) {
        !           542:       EventuallyRedrawGraph(graph);
        !           543:     }
        !           544:     NewGraph = 0;
        !           545:   }
        !           546: }
        !           547: 
        !           548: 
        !           549: void
        !           550: initGraphs(void)
        !           551: {
        !           552:   int i;
        !           553:   SimGraph *graph;
        !           554: 
        !           555:   for (graph = sim->graph; graph != NULL; graph = graph->next) {
        !           556:     graph->range = 10;
        !           557:     graph->mask = ALL_HISTORIES;
        !           558:   }
        !           559: 
        !           560:   if (!HistoryInitialized) {
        !           561:     HistoryInitialized = 1;
        !           562:     for (i = 0; i < HISTORIES; i++) {
        !           563:       History10[i] = (unsigned char *)ckalloc(120);
        !           564:       History120[i] = (unsigned char *)ckalloc(120);
        !           565:     }
        !           566:   }
        !           567: }
        !           568: 
        !           569: 
        !           570: /* comefrom: InitWillStuff */
        !           571: InitGraphMax(void)
        !           572: {
        !           573:   register x;
        !           574: 
        !           575:   ResHisMax = 0;
        !           576:   ComHisMax = 0;
        !           577:   IndHisMax = 0;
        !           578:   for (x = 118; x >= 0; x--) {
        !           579:     if (ResHis[x] > ResHisMax) ResHisMax = ResHis[x];
        !           580:     if (ComHis[x] > ComHisMax) ComHisMax = ComHis[x];
        !           581:     if (IndHis[x] > IndHisMax) IndHisMax = IndHis[x];
        !           582:     if (ResHis[x] < 0) ResHis[x] = 0;
        !           583:     if (ComHis[x] < 0) ComHis[x] = 0;
        !           584:     if (IndHis[x] < 0) IndHis[x] = 0;
        !           585:   }
        !           586:   Graph10Max = ResHisMax;
        !           587:   if (ComHisMax > Graph10Max) Graph10Max = ComHisMax;
        !           588:   if (IndHisMax > Graph10Max) Graph10Max = IndHisMax;
        !           589: 
        !           590:   Res2HisMax = 0;
        !           591:   Com2HisMax = 0;
        !           592:   Ind2HisMax = 0;
        !           593:   for (x = 238; x >= 120; x--) {
        !           594:     if (ResHis[x] > Res2HisMax) Res2HisMax = ResHis[x];
        !           595:     if (ComHis[x] > Com2HisMax) Com2HisMax = ComHis[x];
        !           596:     if (IndHis[x] > Ind2HisMax) Ind2HisMax = IndHis[x];
        !           597:     if (ResHis[x] < 0) ResHis[x] = 0;
        !           598:     if (ComHis[x] < 0) ComHis[x] = 0;
        !           599:     if (IndHis[x] < 0) IndHis[x] = 0;
        !           600:   }
        !           601:   Graph120Max = Res2HisMax;
        !           602:   if (Com2HisMax > Graph120Max) Graph120Max = Com2HisMax;
        !           603:   if (Ind2HisMax > Graph120Max) Graph120Max = Ind2HisMax;
        !           604: }
        !           605: 
        !           606: 
        !           607: InitNewGraph(SimGraph *graph)
        !           608: {
        !           609:   int d = 8;
        !           610:   struct XDisplay *xd;
        !           611: 
        !           612:   graph->next = NULL;
        !           613:   graph->range = 10;
        !           614:   graph->mask = ALL_HISTORIES;
        !           615: 
        !           616: /* This stuff was initialized in our caller (GraphCmd) */
        !           617: /*  graph->tkwin = NULL; */
        !           618: /*  graph->interp = NULL; */
        !           619: /*  graph->flags = 0; */
        !           620: 
        !           621:   graph->x = NULL;
        !           622:   graph->visible = 0;
        !           623:   graph->w_x = graph->w_y = 0;
        !           624:   graph->w_width = graph->w_height = 0;
        !           625:   graph->pixmap = None;
        !           626:   graph->pixels = NULL;
        !           627:   graph->fontPtr = NULL;
        !           628:   graph->border = NULL;
        !           629:   graph->borderWidth = 0;
        !           630:   graph->relief = TK_RELIEF_FLAT;
        !           631:   graph->draw_graph_token = 0;
        !           632: //fprintf(stderr, "InitNewGraph token %d\n", graph->draw_graph_token);
        !           633: 
        !           634:   graph->x = FindXDisplay(graph->tkwin);
        !           635:   IncRefDisplay(graph->x);
        !           636: 
        !           637:   graph->pixels = graph->x->pixels;
        !           638:   graph->fontPtr = NULL;
        !           639: 
        !           640:   DoResizeGraph(graph, 16, 16);
        !           641: }
        !           642: 
        !           643: 
        !           644: DestroyGraph(SimGraph *graph)
        !           645: {
        !           646:   SimGraph **gp;
        !           647: 
        !           648:   for (gp = &sim->graph;
        !           649:        (*gp) != NULL;
        !           650:        gp = &((*gp)->next)) {
        !           651:     if ((*gp) == graph) {
        !           652:       (*gp) = graph->next;
        !           653:       sim->graphs--;
        !           654:       break;
        !           655:     }
        !           656:   }
        !           657: 
        !           658:   if (graph->pixmap != None) {
        !           659:     XFreePixmap(graph->x->dpy, graph->pixmap);
        !           660:     graph->pixmap = None;
        !           661:   }
        !           662: 
        !           663:   DecRefDisplay(graph->x);
        !           664: 
        !           665:   ckfree((char *) graph);
        !           666: }
        !           667: 
        !           668: 
        !           669: DoResizeGraph(SimGraph *graph, int w, int h)
        !           670: {
        !           671:   int resize = 0;
        !           672: 
        !           673:   graph->w_width = w; graph->w_height = h;
        !           674: 
        !           675:   if (graph->pixmap != None) {
        !           676:     XFreePixmap(graph->x->dpy, graph->pixmap);
        !           677:     graph->pixmap = None;
        !           678:   }
        !           679:   graph->pixmap = XCreatePixmap(graph->x->dpy, graph->x->root,
        !           680:                                w, h, graph->x->depth);
        !           681:   if (graph->pixmap == None) {
        !           682:     fprintf(stderr,
        !           683:            "Sorry, Micropolis can't create a pixmap on X display \"%s\".\n",
        !           684:            graph->x->display);
        !           685:     sim_exit(1); // Just sets tkMustExit and ExitReturn
        !           686:     return;
        !           687:   }
        !           688: }
        !           689: 
        !           690: 
        !           691: DoNewGraph(SimGraph *graph)
        !           692: {
        !           693:   sim->graphs++; graph->next = sim->graph; sim->graph = graph;
        !           694: 
        !           695:   NewGraph = 1;
        !           696: }
        !           697: 
        !           698: 
        !           699: #define BORDER 5
        !           700: 
        !           701: DoUpdateGraph(SimGraph *graph)
        !           702: {
        !           703:   Display *dpy;
        !           704:   GC gc;
        !           705:   Pixmap pm;
        !           706:   int *pix;
        !           707:   unsigned char **hist;
        !           708:   int w, h, mask, i, j, x, y;
        !           709:   XPoint points[121];
        !           710:   int year = (CityTime / 48) + StartingYear;
        !           711:   int month = (CityTime / 4) % 12;
        !           712:   int do_top_labels = 0;
        !           713:   int do_right_labels = 0;
        !           714:   int top_label_height = 30;
        !           715:   int right_label_width = 65;
        !           716:   int tx, ty;
        !           717:   float sx, sy;
        !           718: 
        !           719:   if (!graph->visible) {
        !           720:     return;
        !           721:   }
        !           722: 
        !           723:   if (graph->range == 10) {
        !           724:     hist = History10;
        !           725:   } else {
        !           726:     hist = History120;
        !           727:   }
        !           728: 
        !           729:   dpy = graph->x->dpy;
        !           730:   gc = graph->x->gc;
        !           731:   pm = graph->pixmap;
        !           732:   pix = graph->pixels;
        !           733: 
        !           734:   w = graph->w_width;
        !           735:   h = graph->w_height;
        !           736: 
        !           737:   XSetFont(graph->x->dpy, graph->x->gc, graph->fontPtr->fid);
        !           738:   XSetLineAttributes(dpy, gc, 3, LineSolid, CapButt, JoinBevel);
        !           739:   if (graph->x->color) {
        !           740:     XSetForeground(dpy, gc, pix[COLOR_LIGHTGRAY]);
        !           741:   } else {
        !           742:     XSetForeground(dpy, gc, pix[COLOR_WHITE]);
        !           743:   }
        !           744:   XFillRectangle(dpy, pm, gc, 0, 0, w, h);
        !           745: 
        !           746:   tx = BORDER; ty = BORDER;
        !           747: 
        !           748:   if ((w -= (2 * BORDER)) < 1) w = 1;
        !           749:   if ((h -= (2 * BORDER)) < 1) h = 1;
        !           750: 
        !           751:   if (w > (4 * right_label_width)) {
        !           752:     w -= right_label_width;
        !           753:     do_right_labels = 1;
        !           754:   }
        !           755: 
        !           756:   if (do_right_labels &&
        !           757:       (h > (3 * top_label_height))) {
        !           758:     ty += top_label_height;
        !           759:     h -= top_label_height;
        !           760:     do_top_labels = 1;
        !           761:   }
        !           762: 
        !           763:   sx = ((float)w) / 120.0; sy = ((float)h) / 256.0;
        !           764: 
        !           765:   mask = graph->mask;
        !           766:   for (i = 0; i < HISTORIES; i++, mask >>= 1, hist++) {
        !           767:     if (mask & 1) {
        !           768:       int fg = COLOR_WHITE;
        !           769:       int bg = COLOR_BLACK;
        !           770:       Pixmap stipple = None;
        !           771: 
        !           772:       for (j = 0; j < 120; j++) {
        !           773:        x = tx + (j * sx);
        !           774:        y = ty + ((int)(h - (((float)(*hist)[j]) * sy)));
        !           775:        points[j].x = x; points[j].y = y;
        !           776:       }
        !           777:       x = tx + (j * sx);
        !           778:       points[j].x = x; points[j].y = y;
        !           779: 
        !           780:       if (graph->x->color) {
        !           781:        XSetForeground(dpy, gc, pix[HistColor[i]]);
        !           782:       } else {
        !           783:        switch (i) {
        !           784:        case 0: /* res */
        !           785:          stipple = graph->x->gray50_stipple;
        !           786:          break;
        !           787:        case 1: /* com */
        !           788:          stipple = graph->x->gray25_stipple;
        !           789:          break;
        !           790:        case 2: /* ind */
        !           791:          stipple = graph->x->gray75_stipple;
        !           792:          break;
        !           793:        case 3: /* cash */
        !           794:          fg = COLOR_BLACK;
        !           795:          break;
        !           796:        case 4: /* crime */
        !           797:          stipple = graph->x->horiz_stipple;
        !           798:          break;
        !           799:        case 5: /* pol */
        !           800:          stipple = graph->x->vert_stipple;
        !           801:          break;
        !           802:        }
        !           803:        if (stipple != None) {
        !           804:          XSetStipple(graph->x->dpy, gc, stipple);
        !           805:          XSetTSOrigin(graph->x->dpy, gc, 0, 0);
        !           806:          XSetForeground(graph->x->dpy, gc, pix[fg]);
        !           807:          XSetBackground(graph->x->dpy, gc, pix[bg]);
        !           808:          XSetFillStyle(graph->x->dpy, gc, FillOpaqueStippled);
        !           809:        } else {
        !           810:          XSetForeground(graph->x->dpy, gc, pix[fg]);
        !           811:        }
        !           812:       }
        !           813: 
        !           814:       XDrawLines(dpy, pm, gc, points, 121, CoordModeOrigin);
        !           815: 
        !           816:       if (!graph->x->color && (stipple != None)) {
        !           817:        XSetFillStyle(graph->x->dpy, gc, FillSolid);
        !           818:       }
        !           819: 
        !           820:       if (do_right_labels) {
        !           821:        if (graph->x->color) {
        !           822:          XSetForeground(dpy, gc, pix[HistColor[i]]);
        !           823:          XDrawString(graph->x->dpy, pm, graph->x->gc,
        !           824:                      x + 4, y + 5,
        !           825:                      HistName[i], strlen(HistName[i]));
        !           826:          XDrawString(graph->x->dpy, pm, graph->x->gc,
        !           827:                      x + 5, y + 4,
        !           828:                      HistName[i], strlen(HistName[i]));
        !           829: 
        !           830:          XSetForeground(dpy, gc, pix[COLOR_BLACK]);
        !           831:          XDrawString(graph->x->dpy, pm, graph->x->gc,
        !           832:                      x + 5, y + 5,
        !           833:                      HistName[i], strlen(HistName[i]));
        !           834:        } else {
        !           835:          XSetForeground(dpy, gc, pix[COLOR_BLACK]);
        !           836:          XDrawString(graph->x->dpy, pm, graph->x->gc,
        !           837:                      x + 5, y + 5,
        !           838:                      HistName[i], strlen(HistName[i]));
        !           839:        }
        !           840:       }
        !           841:     }
        !           842:   }
        !           843: 
        !           844:   XSetLineAttributes(dpy, gc, 1, LineSolid, CapButt, JoinMiter);
        !           845: 
        !           846:   XSetForeground(dpy, gc, pix[COLOR_BLACK]);
        !           847:   XDrawLine(dpy, pm, gc, tx, ty - 1, tx + w, ty - 1);
        !           848:   XDrawLine(dpy, pm, gc, tx, ty + h, tx + w, ty + h);
        !           849: 
        !           850:   if (graph->range == 10) {
        !           851:     for (x = 120 - month; x >= 0; x -= 12) {
        !           852:       int xx, yy;
        !           853:       xx = tx + (x * sx);
        !           854:       XDrawLine(dpy, pm, gc, xx, ty - 1, xx, ty + h);
        !           855:       if (do_top_labels) {
        !           856:        char buf[256];
        !           857: 
        !           858:        sprintf(buf, "%d", year--);
        !           859:        xx = tx + (x * sx) + 2;
        !           860:        yy = ty - ((year & 1) ? 4 : 20);
        !           861:        XDrawString(graph->x->dpy, pm, graph->x->gc,
        !           862:                    xx, yy, buf, strlen(buf));
        !           863:       }
        !           864:     }
        !           865:   } else {
        !           866:     int past;
        !           867: 
        !           868:     sx /= 10;
        !           869:     past = 10 * (year % 10);
        !           870:     year /= 10;
        !           871: 
        !           872:     for (x = 1200 - past; x >= 0; x -= 120) {
        !           873:       int xx, yy;
        !           874:       xx = tx + (x * sx);
        !           875:       XDrawLine(dpy, pm, gc, xx, ty - 1, xx, ty + h);
        !           876:       if (do_top_labels) {
        !           877:        char buf[256];
        !           878: 
        !           879:        sprintf(buf, "%d0", year--);
        !           880: 
        !           881:        xx = tx + (x * sx) + 2;
        !           882:        yy = ty - ((year & 1) ? 4 : 20);
        !           883:        XDrawString(graph->x->dpy, pm, graph->x->gc,
        !           884:                    xx, yy, buf, strlen(buf));
        !           885:       }
        !           886:     }
        !           887:   }
        !           888: 
        !           889:   XCopyArea(graph->x->dpy, graph->pixmap,
        !           890:            Tk_WindowId(graph->tkwin), graph->x->gc,
        !           891:            0, 0, graph->w_width, graph->w_height, 0, 0);
        !           892: }
        !           893: 
        !           894: 

unix.superglobalmegacorp.com

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