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