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