Annotation of micropolis/src/sim/terrain/terra.c, revision 1.1

1.1     ! root        1: /* terra.c:  Terrain editor
        !             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: 
        !            63: /* terra.c     -       terrain editor for Sim City
        !            64:                                        by Paul Schmidt, 1989
        !            65:                                        Raxsoft, Inc.
        !            66:                                        1194 Spring Valley Commons
        !            67:                                        Livermore, CA 94550
        !            68:                                        (415) 449-9079
        !            69: */
        !            70: 
        !            71: #include "..\sim\sim.h"
        !            72: #include "..\gr\menu.h"
        !            73: #include "..\gr\grdef.h"
        !            74: #include "..\terra\tmenu.h"
        !            75: #include "..\ed\eddef.h"
        !            76: #include "..\ed\edext.h"
        !            77: #include <setjmp.h>
        !            78: #include <dos.h>
        !            79: #include <stdio.h>
        !            80: #include <fcntl.h>
        !            81: #include <sys\types.h>
        !            82: #include <sys\stat.h>
        !            83: #include <direct.h>
        !            84: 
        !            85: char *GSaveRect();
        !            86: 
        !            87: extern MOUSESTATE near mouse_state;
        !            88: extern FILE *demoFP;
        !            89: extern char realMouseFlag;
        !            90: 
        !            91: extern long lastEvent, TickCount();            /* from ..\sim\main.c */
        !            92: extern long policeFund, fireFund, transFund;
        !            93: 
        !            94: char CreateWithIsland;
        !            95: 
        !            96: #define UMaps 4
        !            97: #define URecs 5000
        !            98: int UndoMapBuffer1[WORLD_X*WORLD_Y];
        !            99: int UndoMapBuffer2[WORLD_X*WORLD_Y];
        !           100: int UndoMapBuffer3[WORLD_X*WORLD_Y];
        !           101: int UndoMapBuffer4[WORLD_X*WORLD_Y];
        !           102: int *UndoMap[UMaps]={UndoMapBuffer1,UndoMapBuffer2,UndoMapBuffer3,UndoMapBuffer4};             /* maps for fill undos */
        !           103: int UndoMaps;          /* number of occupied undo maps */
        !           104: struct {
        !           105:        char x,y;               /* coordinate of undo */
        !           106:        int val;                        /* cell value */
        !           107: } UndoRec[URecs];              /* putdown undos */
        !           108: int UndoHead=0,UndoTail=0;
        !           109: 
        !           110: char fillState=0;                      /* flag telling if fill mode is on or off */
        !           111: 
        !           112: int treeLevel=50;              /* level for tree creation */
        !           113: int lakeLevel=50;              /* level for lake creation */
        !           114: int curvLevel=50;              /* level for river curviness */
        !           115: 
        !           116: /* ========================================================== */
        !           117: 
        !           118: void ClearUndo()               /* clear all undo records */
        !           119: {
        !           120:        UndoMaps=UndoHead=UndoTail=0;           /* kill undo pointers */
        !           121:        DrawAllEdIcons(UPDATE);         /* update undo icon */
        !           122: }
        !           123: 
        !           124: void AddUndo(pos)              /* add undo record */
        !           125: Point pos;             /* position to add to undo */
        !           126: {
        !           127: 
        !           128:        if(pos.h != -1 || pos.v != -1) {                /* if they're not setting to undo the entire map */
        !           129:                if(pos.h > WORLD_X || pos.v > WORLD_Y || pos.h < 0 || pos.v < 0) {              /* if out of bounds */
        !           130:                        return;         /* do nothing */
        !           131:                }
        !           132:        }
        !           133:        if(pos.h == -1 && pos.v == -1) {                /* if undo entire map */
        !           134:                register int tem;               /* temporary counter */
        !           135:                register int x,y;               /* temporary coordinates */
        !           136: 
        !           137:                if(UndoMaps == UMaps) {         /* if there are already five undo maps */
        !           138:                        while(UndoRec[UndoTail].x != -1 || UndoRec[UndoTail].y != -1) {         /* until we find the last map undo */
        !           139:                                UndoTail=Bound(0,UndoTail+1,URecs-1);           /* move tail */
        !           140:                        }
        !           141:                        UndoTail=Bound(0,UndoTail+1,URecs-1);           /* move tail to kill the last map */
        !           142:                        UndoMaps--;
        !           143:                        for(tem=0;tem < UndoMaps;tem++) {               /* for each map */
        !           144:                                for(x=0;x < WORLD_X*WORLD_Y;x++) {
        !           145:                                        *(UndoMap[tem]+x)=*(UndoMap[tem+1]+x);
        !           146:                                }
        !           147:                        }
        !           148:                }
        !           149:                for(x=0;x < WORLD_X*WORLD_Y;x++) {
        !           150:                        *(UndoMap[UndoMaps]+x)=*((int*)Map+x);          /* save current map */
        !           151:                }
        !           152:                UndoMaps++;             /* one more map saved */
        !           153:        }
        !           154:        UndoRec[UndoHead].x=pos.h;              /* set x and y position */
        !           155:        UndoRec[UndoHead].y=pos.v;
        !           156:        UndoRec[UndoHead].val=Map[pos.h][pos.v];                /* set map value */
        !           157:        UndoHead=Bound(0,UndoHead+1,URecs-1);           /* move head */
        !           158:        if(UndoHead == UndoTail) {              /* if we pushed the tail up */
        !           159:                UndoTail=Bound(0,UndoTail+1,URecs-1);           /* move tail */
        !           160:        }
        !           161: }
        !           162: 
        !           163: void Undo()            /* undo one map operation */
        !           164: {
        !           165:        register int x,y;
        !           166: 
        !           167:        if(UndoHead == UndoTail) {              /* if there's nothing to undo */
        !           168:                MakeSound(7);           /* bad sound */
        !           169:                return;         /* do nothing */
        !           170:        }
        !           171:        UndoHead=Bound(0,UndoHead-1,URecs-1);           /* set new head */
        !           172:        if(UndoRec[UndoHead].x == -1) {         /* if the entire map changed */
        !           173:                register int tem;               /* temporary counter */
        !           174:                register int x,y;               /* temporary coordinates */
        !           175: 
        !           176:                for(x=0;x < WORLD_X*WORLD_Y;x++) {
        !           177:                        *((int*)Map+x)=*(UndoMap[UndoMaps-1]+x);                /* set undo map */
        !           178:                }
        !           179:                UndoMaps--;             /* one less map */
        !           180:        } else {
        !           181:                Map[UndoRec[UndoHead].x][UndoRec[UndoHead].y]=UndoRec[UndoHead].val;            /* set old value */
        !           182:        }
        !           183: 
        !           184:        UpdateOurMaps();                /* update big and small maps */
        !           185: }
        !           186: 
        !           187: /* ======================================================================== */
        !           188: 
        !           189: DoEvent()
        !           190: {
        !           191: 
        !           192:        int object;
        !           193:        EVENT event;
        !           194: 
        !           195: #if DEBUG && 0
        !           196:        PrintLock("DoEvent - get event ");
        !           197: #endif
        !           198:        GetMouseEvent(&event);
        !           199:        object=event.object;
        !           200: #if DEBUG && 0
        !           201:        PrintLock("DoEvent ");
        !           202: #endif
        !           203: 
        !           204:        switch(object&0xff00)
        !           205:        {
        !           206:                case 0: DoMenu(object);
        !           207:                                break;
        !           208:                case 0x100:
        !           209:                                DoEdEvent(&event);
        !           210:                                break;
        !           211:                case 0x200:
        !           212:                                DoKeyDown(object);
        !           213:                                break;
        !           214:                case 0x300:
        !           215:                                MenuEvent(&event);
        !           216:                                break;
        !           217:                case 0x400:
        !           218:                                DoMapEvent(&event);
        !           219:                                break;
        !           220:                case 0x600:
        !           221:                                DoScreen(&event);
        !           222:                                break;
        !           223:        }
        !           224: }
        !           225: 
        !           226: UpdateOurSmallMap()            /* update small map */
        !           227: {
        !           228:        register int tem;               /* temporary counter */
        !           229:        
        !           230:        MouseHide();            /* hide mouse */
        !           231:        DrawSmallMap();         /* updates small map */
        !           232:        for(tem=0;tem < WORLD_X*WORLD_Y;tem++) {
        !           233:                *((int*)lastSmallMap+tem)=(*((int*)Map+tem))&LOMASK;            /* copy map */
        !           234:        }
        !           235:        MouseShow();            /* show mouse */
        !           236: }
        !           237: 
        !           238: UpdateOurMaps()                /* update edit and map widnows */
        !           239: {
        !           240:        UpdateMapCursorOff();           /* turn off map cursor */
        !           241:        MouseHide();            /* hide mouse */
        !           242:        DrawBigMap();           /* updates large map */
        !           243:        MouseShow();            /* show mouse */
        !           244:        UpdateOurSmallMap();
        !           245:        DrawAllEdIcons(UPDATE);         /* update icons */
        !           246:        UpdateMapCursorOn();            /* turn map cursor on */
        !           247: }
        !           248: 
        !           249: /* ======================================================================== */
        !           250: DoMenu(itemNum)
        !           251: int itemNum;
        !           252: {
        !           253:        static char far *popGameLevelStrs[]={"Easy","Medium","Hard",NULL};
        !           254:        int cur_windowActive;           /* current active window */
        !           255:        register int x,y;               /* temporary integers */
        !           256:        Rect msgBox;
        !           257:        Rect msgRect;
        !           258:        char *savePtr;          /* pointer to saved rectangle */
        !           259:        int smoothFlag;
        !           260:        long tmpFunds;
        !           261:        int virginCity=YES;
        !           262: 
        !           263:        switch(itemNum)
        !           264:        {
        !           265: /*             case MNUSCNO:
        !           266: /*                                     /* Load a scenario - if it fails we need to redraw the */
        !           267: /*                                     /* screen */
        !           268: /*                             if (!LoadScenario()) {
        !           269: /*                                     InitWindows();
        !           270: /*                             } else {
        !           271: /*                                     ClearUndo();            /* clear undo records */
        !           272: /*                             }
        !           273: /*                             SelectNewWindow(EDWINDOW);              /* enable edit window */
        !           274: /*                             SelectNewWindow(MAPWINDOW);             /* enable map window */
        !           275: /*                             break;          /**/
        !           276:                case MNUQUIT:
        !           277:                                if (Verify("EXIT"))
        !           278:                                        Quit("Micropolis Terrain Editor");
        !           279:                                break;
        !           280:                case MNU_SoundToggle:           /* sound on/off */
        !           281:                                userSoundOn^=YES;
        !           282: sso:
        !           283:                                ShowSelectedOptions();
        !           284:                                break;
        !           285:                case MNUABOUT:
        !           286:                                DoAbout();
        !           287:                                break;
        !           288:                case MNULOAD:
        !           289:                                if (LoadGame(NULL,NO))
        !           290:                                        virginCity=NO;
        !           291:                                SelectNewWindow(EDWINDOW);              /* enable edit window */
        !           292:                                SelectNewWindow(MAPWINDOW);             /* enable map window */
        !           293:                                ClearUndo();            /* clear undo records */
        !           294:                                break;
        !           295:                case MNUSAVE:
        !           296:                                SaveGame(lastFileName);
        !           297:                                break;
        !           298:                case MNUSVAS:
        !           299:                                SaveGame(NULL);
        !           300:                                break;
        !           301:                case MNUNEW: /* Start new game */
        !           302:                                if (Verify("NEW GAME")) {
        !           303:                                        totalFunds=20000L;
        !           304:                                        NewGame(NO);
        !           305:                                        transFund=policeFund=fireFund=65535L;
        !           306:                                        CityTax=7;
        !           307:                                        virginCity=YES;
        !           308:                                        ClearUndo();            /* clear undo records */
        !           309:                                }
        !           310:                                SelectNewWindow(EDWINDOW);              /* enable edit window */
        !           311:                                SelectNewWindow(MAPWINDOW);             /* enable map window */
        !           312:                                break;
        !           313:                case MNUPRINT:
        !           314:                                PrintCity();
        !           315:                                break;
        !           316:                case MNU_SmoothTrees:
        !           317:                        smoothFlag=1;
        !           318:                        goto dosmooth;
        !           319:                case MNU_ClearMap:              /* if map is to be cleared */
        !           320:                        AddUndo(-1,-1);         /* save map */
        !           321:                        rax_ClearMap();         /* clear map (..\sim\mapgener.c) */
        !           322:                        GameLevel=0;            /* assume game is easy */
        !           323:                        goto updateBoth;
        !           324:                        break;
        !           325:                case MNU_ClearUnnatural:                /* if unnatural objects are to be cleared */
        !           326:                        AddUndo(-1,-1);         /* save map */
        !           327:                        for(x=0;x < WORLD_X;x++) {
        !           328:                                for(y=0;y < WORLD_Y;y++) {
        !           329:                                        if((Map[x][y]&LOMASK) > 37) {           /* get rid of everything unnatural */
        !           330:                                                Map[x][y]=0;            /* turn it into dirt */
        !           331:                                        }
        !           332:                                }
        !           333:                        }
        !           334: updateBoth:
        !           335:                        UpdateOurMaps();                /* update both windows */
        !           336:                        break;
        !           337:                case MNU_GenerateRandom:                /* if random map is to be generated */
        !           338:                        if(SetTerrainParameters()) {            /* allow user to set terrain generation parameters */
        !           339:                                CenterRect(&msgBox, 20, 5);
        !           340:                                msgRect=*AdjRect(&msgBox);
        !           341:                                savePtr=GSaveRect(&msgRect);            /* save rectangle */
        !           342:                                GRectFill(&msgRect, WHITE|PWHITE);
        !           343:                                GSetAttrib(DGREEN, DGREEN, PBLACK);
        !           344:                                GRectOutline(&msgRect, 4);
        !           345:                                GSetAttrib(LGREEN, LGREEN, PMGREY);
        !           346:                                GRectOutline(&msgRect, 2);
        !           347:                                GSetAttrib(DBLUE, WHITE, PWHITE|PINV);
        !           348:                                CenterPrint(&msgBox, msgBox.top+2, "Now terraforming");
        !           349: 
        !           350:                                AddUndo(-1,-1);         /* save map */
        !           351:                                rax_ClearMap();                                 /* make river map */
        !           352:                                rax_GetRandStart();
        !           353:                                if(CreateWithIsland) {          /* if we're creating an island */
        !           354:                                        rax_MakeIsland();               /* make an island */
        !           355:                                }
        !           356:                                if(curvLevel) {         /* if we're supposedly creating an island */
        !           357:                                        rax_DoRivers();         /* create river */
        !           358:                                }
        !           359:                                if(lakeLevel) {         /* if there are to be lakes */
        !           360:                                        rax_MakeLakes();                /* add lakes */
        !           361:                                }
        !           362:                                rax_SmoothRiver();              /* smooth out river */
        !           363:                                if(treeLevel) {         /* if we're creating a woodsy terrain */
        !           364:                                        rax_DoTrees();          /* add trees */
        !           365:                                }
        !           366:                                rax_SmoothTrees();              /* smooth trees */
        !           367:                                rax_SmoothTrees();              /* smooth trees */
        !           368: 
        !           369:                                GRestoreRect(&msgRect,savePtr);         /* restore rectangle */
        !           370:                                MapX=MapY=0;
        !           371:                                goto updateBoth;
        !           372:                        }
        !           373:                        break;
        !           374:                case MNU_SmoothRiver:           /* if water is to be smoothed */
        !           375:                        smoothFlag=2;
        !           376:                        goto dosmooth;
        !           377:                case MNU_SmoothBoth:            /* if both are to be smoothed */
        !           378:                        smoothFlag=3;                   /* Both */
        !           379: dosmooth:
        !           380:                        CenterRect(&msgBox, 16, 5);
        !           381:                        msgRect=*AdjRect(&msgBox);
        !           382:                        savePtr=GSaveRect(&msgRect);            /* save rectangle */
        !           383:                        GRectFill(&msgRect, WHITE|PWHITE);
        !           384:                        GSetAttrib(DGREEN, DGREEN, PBLACK);
        !           385:                        GRectOutline(&msgRect, 4);
        !           386:                        GSetAttrib(LGREEN, LGREEN, PMGREY);
        !           387:                        GRectOutline(&msgRect, 2);
        !           388:                        GSetAttrib(DBLUE, WHITE, PWHITE|PINV);
        !           389:                        CenterPrint(&msgBox, msgBox.top+2, "Smoothing...");
        !           390: 
        !           391:                        AddUndo(-1,-1);         /* save map */
        !           392:                        if (smoothFlag & 2)     /* If water smooth flag set */
        !           393:                        {
        !           394:                                rax_WaterEdges();               /* make sure water edges are ok */
        !           395:                                rax_SmoothRiver();
        !           396:                        }
        !           397:                        if (smoothFlag & 1)
        !           398:                        {
        !           399:                                rax_SmoothTrees();
        !           400:                                rax_SmoothTrees();
        !           401:                        }
        !           402: 
        !           403:                        GRestoreRect(&msgRect,savePtr);         /* restore rectangle */
        !           404:                        goto updateBoth;
        !           405: 
        !           406:                case MNU_RandomIsland:          /* if random Island toggle */
        !           407:                        CreateWithIsland^=1;            /* toggle state of flag */
        !           408:                        ShowSelectedOptions();          /* update menu flag status */
        !           409:                        break;
        !           410: 
        !           411:                case MNU_GameLevel:             /* if game level */
        !           412: /*                     GameLevel++;            /* add one for PopUpMenuBox */
        !           413: /*                     PopUpMenuBox(&GameLevel, popGameLevelStrs);
        !           414: /*                     GameLevel--;            /**/
        !           415:                        
        !           416:                        tmpFunds=totalFunds;    /* Don't alter the amount of funds! */
        !           417:                        ChooseGameLevel();              /* get city name & level from user */
        !           418:                        if (!virginCity)
        !           419:                                totalFunds=tmpFunds;
        !           420:                        NewName();              /* set the name of the city */
        !           421:                        break;
        !           422:                case MNU_GameYear:              /* if game year */
        !           423:                        SetGameYear();          /* allow user to set the game year */
        !           424:                        break;
        !           425: 
        !           426:                case MNU_EditWindow:            /* if edit window */
        !           427:                        SelectNewWindow(EDWINDOW);              /* bring the edit window to the foreground */
        !           428:                        break;
        !           429:                case MNU_MapWindow:             /* if map window */
        !           430:                        SelectNewWindow(MAPWINDOW);             /* bring the map window to the foreground */
        !           431:                        break;
        !           432: 
        !           433:                default:
        !           434:                        /* unimplemented option */
        !           435:                        break;
        !           436:        }
        !           437: }
        !           438: 
        !           439: long messageTime;
        !           440: 
        !           441: DoEdEvent(ePtr)
        !           442: EVENT *ePtr;
        !           443: {
        !           444:        int object;
        !           445: 
        !           446:        object=ePtr->object&0xff;
        !           447: 
        !           448:        if (object & 0xf0)
        !           449:        {       /* Must be an icon */
        !           450:                SetWandState(object&0xf, YES);
        !           451:        }
        !           452:        switch (object)
        !           453:        {       
        !           454:                case 0: DoEdMapEvent(ePtr);
        !           455:                                break;
        !           456:                case 2: DoMoveWindow(ePtr, edWinList);
        !           457:                                break;
        !           458:                case 8: ResizeEdWindow(ePtr);
        !           459:                                break;
        !           460:        }
        !           461: }
        !           462: 
        !           463: /* ======================================================================== */
        !           464: DoMapEvent(ePtr)
        !           465: EVENT *ePtr;
        !           466: {
        !           467:        int object;
        !           468: 
        !           469:        object=ePtr->object&0xff;
        !           470: 
        !           471:        {
        !           472:                switch (object)
        !           473:                {       case 0: DoMapWindowEvent(ePtr);         /* move locus of edit window */
        !           474:                                        break;
        !           475:                        case 2: DoMoveMap(ePtr);                /* move window */
        !           476:                                        break;
        !           477:                }
        !           478:        }
        !           479: }
        !           480: 
        !           481: void EditTerra()               /* main program entry point */
        !           482: {
        !           483:        int updateWait=0, updateWait2=0;
        !           484: 
        !           485:        CreateWithIsland=0;
        !           486:        ShowSelectedOptions();          /* update menu flag status */
        !           487:        GameLevel=0;            /* assume game is easy */
        !           488:        totalFunds=20000L;
        !           489:        transFund=policeFund=fireFund=65535L;
        !           490:        CityTax=7;
        !           491: 
        !           492:        EnableMenus();          /* make sure menus are enabled */
        !           493:        for (;;)
        !           494:        {
        !           495:                long lastMapCursor;             /* time value for map window cursor flashing */
        !           496: 
        !           497:                if (WaitedEnough(&lastMapCursor,2))
        !           498:                {               /* if we should flash the map cursor */
        !           499:                        UpdateMapCursor();              /* update the map cursor */
        !           500:                }
        !           501: 
        !           502: 
        !           503:                if (!menuActive)                /* if no menus are active */
        !           504:                {
        !           505:                        char moveFlag;
        !           506:                        if (CheckKeyState(CNTRLSCAN))   /* Is the control key hit? */
        !           507:                        {
        !           508:                                int dx, dy;
        !           509:                                dx=joyMoveX;
        !           510:                                dy=joyMoveY;
        !           511:                                
        !           512:                                if (CheckKeyState(HOMESCAN))    /* Home arrow */
        !           513:                                {       dx--; dy--;
        !           514:                                }
        !           515:                                if (CheckKeyState(PGUPSCAN))    /* PgUp arrow */
        !           516:                                {       dx++; dy--;
        !           517:                                }
        !           518:                                if (CheckKeyState(ENDSCAN))     /* End arrow */
        !           519:                                {       dx--; dy++;
        !           520:                                }
        !           521:                                if (CheckKeyState(PGDNSCAN))    /* PgDn arrow */
        !           522:                                {       dx++; dy++;
        !           523:                                }
        !           524:                                if (CheckKeyState(RIGHTSCAN))   /* Right arrow */
        !           525:                                        dx++;
        !           526:                                if (CheckKeyState(LEFTSCAN))    /* Left arrow */
        !           527:                                        dx--;
        !           528:                                if (CheckKeyState(UPSCAN))      /* Up arrow */
        !           529:                                        dy--;
        !           530:                                if (CheckKeyState(DOWNSCAN))    /* Down arrow */
        !           531:                                        dy++;
        !           532:                                if (dx || dy)
        !           533:                                {
        !           534:                                        DisableMenus();
        !           535:                                        freeze=YES;
        !           536:                                        EdScroll(dx,dy);
        !           537:                                        freeze=NO;
        !           538:                                }
        !           539:                        }
        !           540:                        if (!ScrollLock())
        !           541:                        {
        !           542: moveagn:
        !           543:                                moveFlag=NO;
        !           544:                                if (mouse_state.x <= 1)
        !           545:                                {       
        !           546:                                        if (MapX > 0)
        !           547:                                        {
        !           548:                                                MapX--;
        !           549:                                                moveFlag=YES;
        !           550:                                        }
        !           551:                                } else if (mouse_state.x >= screenWidth-6)
        !           552:                                {
        !           553:                                        if (MapX+edWinWid < WORLD_X)
        !           554:                                        {
        !           555:                                                MapX++;
        !           556:                                                moveFlag=YES;
        !           557:                                        }
        !           558:                                }
        !           559:                                if (mouse_state.y < 1 )
        !           560:                                {
        !           561:                                        if (MapY > 0)
        !           562:                                        {
        !           563:                                                MapY--;
        !           564:                                                moveFlag=YES;
        !           565:                                        }
        !           566:                                }
        !           567:                                else if (mouse_state.y >= screenHeight-6)
        !           568:                                {
        !           569:                                        if (MapY+edWinLen < WORLD_Y)
        !           570:                                        {
        !           571:                                                MapY++;
        !           572:                                                moveFlag=YES;
        !           573:                                        }
        !           574:                                }
        !           575: 
        !           576:                                if (moveFlag == YES)
        !           577:                                {       
        !           578:                                        DisableMenus(); /* locks to current process */
        !           579:                                        newMapFlags[CYMAP]=0;
        !           580:                                        DrawBigMap();
        !           581: #if 0
        !           582:                                        DrawObjects();
        !           583: #endif
        !           584:                                        EnableMenus();
        !           585:                                        goto moveagn;
        !           586:                                }
        !           587: 
        !           588:                        }                /* End of "if (!ScrollLock" */
        !           589:                }       /* End if if (!menuActive) */
        !           590:                if (KBHit() || CheckMouseEvents())              /* if an event happened */
        !           591:                {
        !           592:                        DisableMenus();
        !           593:                        while(KBHit())
        !           594:                        {       DoKey();
        !           595:                        }
        !           596:                        while (CheckMouseEvents())
        !           597:                        {       DoEvent();
        !           598:                        }
        !           599:                        lastEvent=TickCount();
        !           600:                }
        !           601:                if (simSpeed == 0)
        !           602:                {
        !           603:                        if (WaitedEnough(&updateWait, 18*3))
        !           604:                        {               DisableMenus();
        !           605:                                        UpdateEdWindow();
        !           606:                        }
        !           607:                }
        !           608: #if DEBUGINI
        !           609:        OutStr("\nMAIN: re-enable");
        !           610: #endif
        !           611: 
        !           612:                EnableMenus();  /* Make sure the menus are enabled */
        !           613:                copyOK=YES;
        !           614: #if DEBUGINI
        !           615:        OutStr("\nMAIN: copyok, pass");
        !           616: #endif
        !           617:                Pass();
        !           618:                copyOK=NO;
        !           619: #if DEBUGINI
        !           620:        OutStr("\nMAIN: copy not OK");
        !           621: #endif
        !           622:        }
        !           623: }
        !           624: 
        !           625: SetGameYear()          /* get game year */
        !           626: {
        !           627:        Rect verBox;
        !           628:        static char *label="Enter Game Year:";          /* label for window */
        !           629: 
        !           630:        char dateBuffer[10];            /* buffer for date */
        !           631:        EVENT event;
        !           632:        char *savePtr;
        !           633:        int len, x, y, i,c, optLens[8];
        !           634:        Rect tmpBox;
        !           635:        Size strSize;
        !           636:        const char **optPtr;
        !           637:        int posIndex=(-1);
        !           638:        long tmpTime;
        !           639: 
        !           640:        FlushKeys();
        !           641: 
        !           642:        CenterRect(&verBox,18,5);
        !           643: 
        !           644:        tmpBox=*AdjRect(&verBox);
        !           645:        savePtr=GSaveRect(&tmpBox);
        !           646: 
        !           647:        GRectFill(&tmpBox,BUDGFC+PMGREY);
        !           648:        GSetAttrib(BUDGBC,BUDGBC,PWHITE);
        !           649:        GRectOutline(&tmpBox, 4);
        !           650:                                /* Outline outline in BLACK */
        !           651:        GSetAttrib(BLACK,BLACK,PBLACK);
        !           652:        GRectOutline(&tmpBox,1);
        !           653:        GSetAttrib(BUDGBC,BUDGFC,PINV|PWHITE);
        !           654:        PrintRectLines(&verBox,verBox.top,label);
        !           655:        i=20;
        !           656:        x=verBox.left+i;
        !           657:        y=verBox.bottom-2;
        !           658:        GSetAttrib(BUDGBC,BUDBOXC,PINV|PWHITE);
        !           659: 
        !           660: /*     GSetAttrib(BUDGBC,BUDBOXC,0); */
        !           661: /*     TempFullScreenCursor(); */
        !           662: 
        !           663:        sprintf(dateBuffer,"%4d",(CityTime/48)+1900);           /* set date */
        !           664:        GetStrSetNum(); /* Numbers only */
        !           665:        GetStrn(verBox.left+6,verBox.top+3,dateBuffer,5,1);             /* allow user to edit the date and set eos */
        !           666:        GetStrSetAll(); /* allow any alphnum input */
        !           667:        if(strlen(dateBuffer) == 4) {           /* if they entered a good date */
        !           668:                tmpTime=(atoi(dateBuffer)-1900)*48L;            /* set new date */
        !           669:                if (tmpTime > 0)
        !           670:                        CityTime=tmpTime;
        !           671:        } else {                /* if not the correct length */
        !           672:                MakeSound(7);           /* this should be CANTSND for bad date */
        !           673:        }
        !           674:        for(i=0;i < 100;i++) {          /* kill any and all events */
        !           675:                GetMouseEvent(&event);          /* get event */
        !           676:        }
        !           677: /*     RemoveTempCursor(); */
        !           678:        GRestoreRect(&tmpBox,savePtr);
        !           679:        DoDate();               /* update the date in the edit window */
        !           680: }
        !           681: 
        !           682: int PSBound(a,n,b)             /* return number between a and b */
        !           683: {
        !           684:        if(n < a) n=a;
        !           685:        if(n > b) n=b;
        !           686:        return n;
        !           687: }
        !           688: 
        !           689: /* here is the concept for SetTerrainParameters():
        !           690: ZDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD?
        !           691: 3                                    3
        !           692: 3    Terrain Creation Parameters     3
        !           693: 3                                    3
        !           694: 3    Number     Number     River     3
        !           695: 3   of Trees   of Lakes  Curviness   3
        !           696: 3                                    3
        !           697: 3    xxx%     xxx%     xxx%    3
        !           698: 3                                    3
        !           699: 3  ZDDDDDDDD?            ZDDDDDDDD?  3
        !           700: 3  3   Go   3            3 Cancel 3  3
        !           701: 3  @DDDDDDDDY            @DDDDDDDDY  3
        !           702: @DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDY
        !           703: */
        !           704: SetTerrainParameters()         /* allow user to set up terrain grneration parameters */
        !           705: {
        !           706:        char *savePtr;          /* pointer to saved screen data */
        !           707:        char temStr[20];                /* temporary string for percentages */
        !           708:        EVENT event;            /* temporary event */
        !           709:        int atButton=0;         /* current button we're at */
        !           710:        int buttonDown=0;               /* flag telling if mouse button is down */
        !           711:        int goFlag=0;           /* flag telling if terrain is to be generated */
        !           712:        long startTime;         /* temporary timer value */
        !           713:        int tem;                /* temporary counter */
        !           714:        int x,y;                /* temporary positions */
        !           715:        Rect wRect;             /* rectangle showing extents of window */
        !           716:        Rect tmpRect;           /* temporary rectangle for adjusted window rectangle */
        !           717:        Point buttonPos[8];             /* positions of buttons */
        !           718: 
        !           719:        FlushKeys();            /* do something...flush keyboard buffer? */
        !           720: 
        !           721:        CenterRect(&wRect,36,10);               /* center our window */
        !           722: 
        !           723:        tmpRect=*AdjRect(&wRect);
        !           724:        savePtr=GSaveRect(&tmpRect);
        !           725: 
        !           726:        GRectFill(&tmpRect,BUDGFC+PMGREY);
        !           727:        GSetAttrib(BUDGBC,BUDGBC,PWHITE);
        !           728:        GRectOutline(&tmpRect,4);
        !           729:                                /* Outline outline in BLACK */
        !           730:        GSetAttrib(BLACK,BLACK,PBLACK);
        !           731:        GRectOutline(&tmpRect,1);
        !           732:        GSetAttrib(BUDGBC,BUDGFC,PINV|PWHITE);
        !           733:        PrintRectLines(&wRect,wRect.top,"Terrain Creation Parameters");
        !           734:        x=(wRect.left+2)*8;
        !           735:        y=(wRect.top+2)*fontHeight;
        !           736:        GPPrintf(x+(1*8),y+(1*fontHeight)-3," Number     Number     River  ");
        !           737:        GPPrintf(x+(1*8),y+(2*fontHeight)-3,"of Trees   of Lakes  Curviness");
        !           738: 
        !           739:        buttonPos[0].h=wRect.left+3;            /* positions of buttons */
        !           740:        buttonPos[1].h=wRect.left+10;
        !           741:        buttonPos[2].h=wRect.left+14;
        !           742:        buttonPos[3].h=wRect.left+21;
        !           743:        buttonPos[4].h=wRect.left+25;
        !           744:        buttonPos[5].h=wRect.left+32;
        !           745:        for(tem=0;tem < 6;tem++) {
        !           746:                buttonPos[tem].v=wRect.top+5;           /* set vertical position */
        !           747:        }
        !           748:        buttonPos[6].h=wRect.left+3;
        !           749:        buttonPos[7].h=wRect.left+25;
        !           750:        buttonPos[6].v=buttonPos[7].v=wRect.top+8;
        !           751: 
        !           752:        GSetAttrib(BUDGBC,BUDBOXC,PINV|PWHITE);
        !           753:        for(tem=0;tem < 3;tem++) {              /* for each set of value buttons */
        !           754:                AddTextButton(buttonPos[tem*2],"",0x800+tem*2);                /* add button */
        !           755:                AddTextButton(buttonPos[tem*2+1],"",0x801+tem*2);              /* add button */
        !           756:        }
        !           757:        AddTextButton(buttonPos[6],"   Go   ",0x806);           /* add 'go' button */
        !           758:        AddTextButton(buttonPos[7]," Cancel ",0x807);           /* add 'cancel' button */
        !           759: 
        !           760:                /* output initial values */
        !           761:        GSetAttrib(BUDGBC,BUDGFC,PINV|PWHITE);
        !           762:        sprintf(temStr,"%3d%%%%",treeLevel);            /* get string for tree level */
        !           763:        GPPrintf(x+(3*8),y+(3*fontHeight),temStr);              /* output string */
        !           764:        sprintf(temStr,"%3d%%%%",lakeLevel);            /* get string for lake level */
        !           765:        GPPrintf(x+(14*8),y+(3*fontHeight),temStr);             /* output string */
        !           766:        sprintf(temStr,"%3d%%%%",curvLevel);            /* get string for curviness level */
        !           767:        GPPrintf(x+(25*8),y+(3*fontHeight),temStr);             /* output string */
        !           768: 
        !           769: /*     GSetAttrib(BUDGBC,BUDBOXC,0); */
        !           770:        TempFullScreenCursor();         /* give us a cursor */
        !           771: 
        !           772:        while(1) {              /* until break */
        !           773:                if(0) {         /* never unless below code calls it */
        !           774: repos:
        !           775:                        SetMouseAtButton(atButton+0x800);
        !           776:                }
        !           777:                while (KBHit())         /* Clear any keys pressed */
        !           778:                {       
        !           779:                        switch (GetECH())
        !           780:                        {       case 27:                /* if escape */
        !           781:                                case 'C':               /* (or 'cancel') */
        !           782:                                case 'c':
        !           783:                                        goFlag=0;               /* don't create random terrain */
        !           784:                                        goto xit;
        !           785:                                case 13:                /* if carriage return */
        !           786:                                case 'G':               /* (or 'go') */
        !           787:                                case 'g':
        !           788:                                        goFlag=1;               /* create random terrain */
        !           789:                                        goto xit;
        !           790:                                case '+':       atButton=((atButton+1) % 8);            /* for each button */
        !           791:                                                        goto repos;
        !           792:                                case '-':
        !           793:                                                        atButton=(atButton)?(atButton-1):7;
        !           794:                                                        goto repos;
        !           795:                        }
        !           796:                }
        !           797:                if(CheckMouseEvents()) {                /* if there's an activity */
        !           798:                        GetMouseEvent(&event);          /* get event */
        !           799: downAgain:
        !           800:                        switch(event.object) {          /* get event id */
        !           801:                                case 0x800:             /* if - trees */
        !           802:                                        treeLevel=PSBound(0,treeLevel-1,100);
        !           803:                                        goto updateValues;              /* update values */
        !           804:                                case 0x801:             /* if + trees */
        !           805:                                        treeLevel=PSBound(0,treeLevel+1,100);
        !           806:                                        goto updateValues;              /* update values */
        !           807:                                case 0x802:             /* if - lakes */
        !           808:                                        lakeLevel=PSBound(0,lakeLevel-1,100);
        !           809:                                        goto updateValues;              /* update values */
        !           810:                                case 0x803:             /* if + lakes */
        !           811:                                        lakeLevel=PSBound(0,lakeLevel+1,100);
        !           812:                                        goto updateValues;              /* update values */
        !           813:                                case 0x804:             /* if - curviness */
        !           814:                                        curvLevel=PSBound(0,curvLevel-1,100);
        !           815:                                        goto updateValues;              /* update values */
        !           816:                                case 0x805:             /* if + curviness */
        !           817:                                        curvLevel=PSBound(0,curvLevel+1,100);
        !           818:                                        goto updateValues;              /* update values */
        !           819:                                case 0x806:             /* if 'go' */
        !           820:                                        goFlag=1;               /* return flag telling to create terrain */
        !           821:                                        break;
        !           822:                                case 0x807:             /* if 'cancel' */
        !           823:                                        goFlag=0;               /* return flag telling to create terrain */
        !           824:                                        break;
        !           825:                        }
        !           826:                        if(0) {         /* only if above code calls us */
        !           827: updateValues:
        !           828:                                RemoveTempCursor();             /* remove cursor from screen */
        !           829:                                GSetAttrib(BUDGBC,BUDGFC,PINV|PWHITE);
        !           830:                                sprintf(temStr,"%3d%%%%",treeLevel);            /* get string for tree level */
        !           831:                                GPPrintf(x+(3*8),y+(3*fontHeight),temStr);              /* output string */
        !           832:                                sprintf(temStr,"%3d%%%%",lakeLevel);            /* get string for lake level */
        !           833:                                GPPrintf(x+(14*8),y+(3*fontHeight),temStr);             /* output string */
        !           834:                                sprintf(temStr,"%3d%%%%",curvLevel);            /* get string for curviness level */
        !           835:                                GPPrintf(x+(25*8),y+(3*fontHeight),temStr);             /* output string */
        !           836:                                TempFullScreenCursor();         /* put cursor back */
        !           837:                                if(!buttonDown) {               /* if button was not down */
        !           838:                                        buttonDown=1;           /* set button down flag */
        !           839:                                        startTime=TickCount();          /* get current time */
        !           840:                                        while(StillDown()) {            /* while a button is down */
        !           841:                                                if(TickCount()-startTime > 5) {         /* if autorepeat is up */
        !           842:                                                        goto downAgain;
        !           843:                                                }
        !           844:                                        }
        !           845:                                        buttonDown=0;           /* button is no longer down */
        !           846:                                } else {                /* if button is already down */
        !           847:                                        if(StillDown()) {               /* if button is still down */
        !           848:                                                startTime=TickCount();          /* get current time */
        !           849:                                                while(startTime == TickCount()) ;               /* wait for 1/18th of a second */
        !           850:                                                goto downAgain;
        !           851:                                        }
        !           852:                                        buttonDown=0;           /* no button is down */
        !           853:                                }
        !           854:                        }
        !           855:                        if(event.object == 0x806 || event.object == 0x807) {            /* if one of the exit buttons */
        !           856: xit:
        !           857:                                break;          /* exit loop */
        !           858:                        }
        !           859:                }
        !           860:        }
        !           861: 
        !           862:        for(tem=0x800;tem <= 0x809;tem++) {             /* remove buttons from hot list */
        !           863:                DelButtonHot(tem);
        !           864:        }
        !           865:        RemoveTempCursor();             /* remove our cursor */
        !           866:        GRestoreRect(&tmpRect,savePtr);
        !           867:        return goFlag;          /* return flag telling if terrain is to be created */
        !           868: }

unix.superglobalmegacorp.com

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