|
|
1.1 ! root 1: /* mapgener.c ! 2: * ! 3: * Micropolis, Unix Version. This game was released for the Unix platform ! 4: * in or about 1990 and has been modified for inclusion in the One Laptop ! 5: * Per Child program. Copyright (C) 1989 - 2007 Electronic Arts Inc. If ! 6: * you need assistance with this program, you may contact: ! 7: * http://wiki.laptop.org/go/Micropolis or email [email protected]. ! 8: * ! 9: * This program is free software: you can redistribute it and/or modify ! 10: * it under the terms of the GNU General Public License as published by ! 11: * the Free Software Foundation, either version 3 of the License, or (at ! 12: * your option) any later version. ! 13: * ! 14: * This program is distributed in the hope that it will be useful, but ! 15: * WITHOUT ANY WARRANTY; without even the implied warranty of ! 16: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 17: * General Public License for more details. You should have received a ! 18: * copy of the GNU General Public License along with this program. If ! 19: * not, see <http://www.gnu.org/licenses/>. ! 20: * ! 21: * ADDITIONAL TERMS per GNU GPL Section 7 ! 22: * ! 23: * No trademark or publicity rights are granted. This license does NOT ! 24: * give you any right, title or interest in the trademark SimCity or any ! 25: * other Electronic Arts trademark. You may not distribute any ! 26: * modification of this program using the trademark SimCity or claim any ! 27: * affliation or association with Electronic Arts Inc. or its employees. ! 28: * ! 29: * Any propagation or conveyance of this program must include this ! 30: * copyright notice and these terms. ! 31: * ! 32: * If you convey this program (or any modifications of it) and assume ! 33: * contractual liability for the program to recipients of it, you agree ! 34: * to indemnify Electronic Arts for any liability that those contractual ! 35: * assumptions impose on Electronic Arts. ! 36: * ! 37: * You may not misrepresent the origins of this program; modified ! 38: * versions of the program must be marked as such and not identified as ! 39: * the original program. ! 40: * ! 41: * This disclaimer supplements the one included in the General Public ! 42: * License. TO THE FULLEST EXTENT PERMISSIBLE UNDER APPLICABLE LAW, THIS ! 43: * PROGRAM IS PROVIDED TO YOU "AS IS," WITH ALL FAULTS, WITHOUT WARRANTY ! 44: * OF ANY KIND, AND YOUR USE IS AT YOUR SOLE RISK. THE ENTIRE RISK OF ! 45: * SATISFACTORY QUALITY AND PERFORMANCE RESIDES WITH YOU. ELECTRONIC ARTS ! 46: * DISCLAIMS ANY AND ALL EXPRESS, IMPLIED OR STATUTORY WARRANTIES, ! 47: * INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY, SATISFACTORY QUALITY, ! 48: * FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT OF THIRD PARTY ! 49: * RIGHTS, AND WARRANTIES (IF ANY) ARISING FROM A COURSE OF DEALING, ! 50: * USAGE, OR TRADE PRACTICE. ELECTRONIC ARTS DOES NOT WARRANT AGAINST ! 51: * INTERFERENCE WITH YOUR ENJOYMENT OF THE PROGRAM; THAT THE PROGRAM WILL ! 52: * MEET YOUR REQUIREMENTS; THAT OPERATION OF THE PROGRAM WILL BE ! 53: * UNINTERRUPTED OR ERROR-FREE, OR THAT THE PROGRAM WILL BE COMPATIBLE ! 54: * WITH THIRD PARTY SOFTWARE OR THAT ANY ERRORS IN THE PROGRAM WILL BE ! 55: * CORRECTED. NO ORAL OR WRITTEN ADVICE PROVIDED BY ELECTRONIC ARTS OR ! 56: * ANY AUTHORIZED REPRESENTATIVE SHALL CREATE A WARRANTY. SOME ! 57: * JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF OR LIMITATIONS ON IMPLIED ! 58: * WARRANTIES OR THE LIMITATIONS ON THE APPLICABLE STATUTORY RIGHTS OF A ! 59: * CONSUMER, SO SOME OR ALL OF THE ABOVE EXCLUSIONS AND LIMITATIONS MAY ! 60: * NOT APPLY TO YOU. ! 61: */ ! 62: ! 63: /* Micropolis simulator code. Copyright 1988, 1989 Maxis, Will Wright */ ! 64: ! 65: #include "sim.h" ! 66: ! 67: #define TRUE 1 ! 68: #define FALSE 0 ! 69: #define WORLD_X 120 ! 70: #define WORLD_Y 100 ! 71: #define RIVER 2 ! 72: #define REDGE 3 ! 73: #define CHANNEL 4 ! 74: #define WOODS 37 ! 75: #define BL 4096 ! 76: #define BN 8192 ! 77: #define BLN BL+BN ! 78: ! 79: static int XStart, YStart; ! 80: static int Dir, LastDir; ! 81: ! 82: /* trash values for GRand() */ ! 83: static int GRanArray[5] = { 1018,4521,202,419,3 }; ! 84: ! 85: far GenerateMap() ! 86: { ! 87: GRanArray[0] = TickCount(); /* This is the only machine-specific call */ ! 88: /* It inits GRand() w/ clockcount(long) */ ! 89: ! 90: if (!(GRand(10))) { /* 1 in 3 chance that island is generated */ ! 91: MakeIsland(); ! 92: return; ! 93: } ! 94: ClearMap(); /* else make river map */ ! 95: GetRandStart(); ! 96: DoRivers(); ! 97: MakeLakes(); ! 98: SmoothRiver(); ! 99: DoTrees(); ! 100: } ! 101: ! 102: near ClearMap() ! 103: { ! 104: register int x, y; ! 105: ! 106: for (x=0; x<WORLD_X; x++) ! 107: for (y=0; y<WORLD_Y; y++) ! 108: Map[x][y] = 0; ! 109: } ! 110: ! 111: #define RADIUS 18 ! 112: ! 113: near MakeIsland() ! 114: { ! 115: register int x,y,z; ! 116: ! 117: for (x=0; x<WORLD_X; x++) ! 118: for (y=0; y<WORLD_Y; y++) ! 119: Map[x][y] = RIVER; ! 120: for (x=5; x<WORLD_X-5; x++) ! 121: for (y=5; y<WORLD_Y-5; y++) ! 122: Map[x][y] = 0; ! 123: for (x=0; x<WORLD_X-5; x+=2) { ! 124: MapX= x ; ! 125: MapY= EGRand(RADIUS); ! 126: BRivPlop(); ! 127: MapY= 90-EGRand(RADIUS); ! 128: BRivPlop(); ! 129: MapY= 0; ! 130: SRivPlop(); ! 131: MapY= 94; ! 132: SRivPlop(); ! 133: } ! 134: for (y=0; y<WORLD_Y-5; y+=2) { ! 135: MapY= y ; ! 136: MapX= EGRand(RADIUS); ! 137: BRivPlop(); ! 138: MapX= 110-EGRand(RADIUS); ! 139: BRivPlop(); ! 140: MapX= 0; ! 141: SRivPlop(); ! 142: MapX= 114; ! 143: SRivPlop(); ! 144: } ! 145: SmoothRiver(); ! 146: DoTrees(); ! 147: } ! 148: ! 149: near MakeLakes() ! 150: { ! 151: int Lim1, Lim2, t, z; ! 152: register int x, y; ! 153: ! 154: Lim1 = GRand(10); ! 155: for (t = 0; t < Lim1; t++) { ! 156: x = GRand(99) + 10; ! 157: y = GRand(80) + 10; ! 158: Lim2 = GRand(12)+2; ! 159: for (z = 0; z < Lim2; z++) { ! 160: MapX = x - 6 + GRand(12); ! 161: MapY = y - 6 + GRand(12); ! 162: if (GRand(4)) SRivPlop(); ! 163: else BRivPlop(); ! 164: } ! 165: } ! 166: } ! 167: ! 168: near GetRandStart() ! 169: { ! 170: XStart = 40 + GRand(40); ! 171: YStart = 33 + GRand(33); ! 172: MapX = XStart; ! 173: MapY = YStart; ! 174: } ! 175: ! 176: near DoTrees() ! 177: { ! 178: int Amount,x,xloc,yloc; ! 179: ! 180: Amount = GRand(100)+50; ! 181: for (x=0; x<Amount; x++) { ! 182: xloc = GRand(119); ! 183: yloc = GRand(99); ! 184: TreeSplash(xloc,yloc); ! 185: } ! 186: SmoothTrees(); ! 187: SmoothTrees(); ! 188: } ! 189: ! 190: near TreeSplash(xloc,yloc) ! 191: int xloc,yloc; ! 192: { ! 193: int Dis, Dir; ! 194: register int xoff, yoff,z; ! 195: ! 196: Dis = GRand(150)+50; ! 197: MapX = xloc; ! 198: MapY = yloc; ! 199: for (z=0; z<Dis; z++) { ! 200: Dir = GRand(7); ! 201: MoveMap(Dir); ! 202: if (!(TestBounds(MapX,MapY))) return; ! 203: if (Map[MapX][MapY] == 0) Map[MapX][MapY] = WOODS+ BLN; ! 204: } ! 205: } ! 206: ! 207: far SmoothRiver() ! 208: { ! 209: static int DX[4] = {-1, 0, 1, 0}; ! 210: static int DY[4] = { 0, 1, 0,-1}; ! 211: static int REdTab[16] = { 13+BL,13+BL,17+BL,15+BL,5+BL,2,19+BL, ! 212: 17+BL,9+BL,11+BL,2,13+BL,7+BL,9+BL,5+BL,2}; ! 213: int bitindex, z,Xtem,Ytem; ! 214: register int temp,MapX,MapY; ! 215: ! 216: for (MapX = 0; MapX < WORLD_X; MapX++) ! 217: for (MapY = 0; MapY < WORLD_Y; MapY++) ! 218: if (Map[MapX][MapY] == REDGE) { ! 219: bitindex = 0; ! 220: for (z=0; z<4; z++) { ! 221: bitindex = bitindex << 1; ! 222: Xtem = MapX + DX[z]; ! 223: Ytem = MapY + DY[z]; ! 224: if (TestBounds(Xtem, Ytem)) ! 225: if ( Map[Xtem][Ytem]) bitindex++; ! 226: } ! 227: temp = REdTab[bitindex & 15]; ! 228: if ((temp != 2) && (GRand(1))) temp++; ! 229: Map[MapX][MapY] = temp; ! 230: } ! 231: } ! 232: ! 233: far SmoothTrees() ! 234: { ! 235: static int DX[4] = {-1, 0, 1, 0}; ! 236: static int DY[4] = { 0, 1, 0,-1}; ! 237: static int TEdTab[16] = {0,0,0,34,0,0,36,35,0,32,0,33,30,31,29,37}; ! 238: int bitindex, z,Xtem,Ytem; ! 239: register int temp,MapX,MapY; ! 240: ! 241: for (MapX = 0; MapX < WORLD_X; MapX++) ! 242: for (MapY = 0; MapY < WORLD_Y; MapY++) ! 243: if ((Map[MapX][MapY] & BLN) == BLN) { ! 244: bitindex = 0; ! 245: for (z=0; z<4; z++) { ! 246: bitindex = bitindex << 1; ! 247: Xtem = MapX + DX[z]; ! 248: Ytem = MapY + DY[z]; ! 249: if (TestBounds(Xtem, Ytem)) ! 250: if (Map[Xtem][Ytem] & BN) bitindex++; ! 251: ! 252: } ! 253: temp = TEdTab[bitindex & 15]; ! 254: if (temp) { ! 255: if (temp != 37) ! 256: if ((MapX+MapY) & 1) ! 257: temp = temp-8; ! 258: Map[MapX][MapY] = temp+BLN; ! 259: } ! 260: else Map[MapX][MapY] = temp; ! 261: } ! 262: } ! 263: ! 264: near DoRivers() ! 265: { ! 266: ! 267: LastDir = GRand(3); ! 268: Dir = LastDir; ! 269: DoBRiv(); ! 270: MapX = XStart; ! 271: MapY = YStart; ! 272: LastDir = LastDir ^ 4; ! 273: Dir = LastDir; ! 274: DoBRiv(); ! 275: MapX = XStart; ! 276: MapY = YStart; ! 277: LastDir = GRand(3); ! 278: DoSRiv(); ! 279: } ! 280: ! 281: near DoBRiv() ! 282: { ! 283: int temp, count; ! 284: ! 285: count = 0; ! 286: while (TestBounds (MapX+4, MapY+4)) { ! 287: BRivPlop(); ! 288: if (GRand(10) > 4) Dir++; ! 289: if (GRand(10) > 4) Dir--; ! 290: if (!(GRand(10))) Dir = LastDir; ! 291: MoveMap (Dir); ! 292: } ! 293: } ! 294: ! 295: near DoSRiv() ! 296: { ! 297: int temp; ! 298: ! 299: while (TestBounds (MapX+3, MapY+3)) { ! 300: SRivPlop(); ! 301: if (GRand(10) > 5) Dir++; ! 302: if (GRand(10) > 5) Dir--; ! 303: if (!(GRand(12))) Dir = LastDir; ! 304: MoveMap (Dir); ! 305: } ! 306: } ! 307: ! 308: near MoveMap (dir) ! 309: int dir; ! 310: { ! 311: static int DirTab[2][8] ={ { 0, 1, 1, 1, 0, -1, -1, -1}, ! 312: {-1,-1, 0, 1, 1, 1, 0, -1} }; ! 313: dir = dir & 7; ! 314: MapX += DirTab[0][dir]; ! 315: MapY += DirTab[1][dir]; ! 316: } ! 317: ! 318: ! 319: ! 320: ! 321: near BRivPlop() ! 322: { ! 323: static int BRMatrix[9][9] ={ ! 324: {0,0,0,3,3,3,0,0,0}, ! 325: {0,0,3,2,2,2,3,0,0}, ! 326: {0,3,2,2,2,2,2,3,0}, ! 327: {3,2,2,2,2,2,2,2,3}, ! 328: {3,2,2,2,4,2,2,2,3}, ! 329: {3,2,2,2,2,2,2,2,3}, ! 330: {0,3,2,2,2,2,2,3,0}, ! 331: {0,0,3,2,2,2,3,0,0}, ! 332: {0,0,0,3,3,3,0,0,0} }; ! 333: int x, y; ! 334: ! 335: for (x=0; x<9; x++) ! 336: for (y=0; y<9; y++) ! 337: PutOnMap (BRMatrix[y][x], x, y); ! 338: } ! 339: ! 340: near SRivPlop() ! 341: { ! 342: static int SRMatrix[6][6] ={ ! 343: {0,0,3,3,0,0}, ! 344: {0,3,2,2,3,0}, ! 345: {3,2,2,2,2,3}, ! 346: {3,2,2,2,2,3}, ! 347: {0,3,2,2,3,0}, ! 348: {0,0,3,3,0,0} }; ! 349: int x, y; ! 350: ! 351: for (x=0; x<6; x++) ! 352: for (y=0; y<6; y++) ! 353: PutOnMap (SRMatrix[y][x], x, y); ! 354: } ! 355: ! 356: near PutOnMap (Mchar, Xoff, Yoff) ! 357: int Mchar, Xoff, Yoff; ! 358: { ! 359: register int Xloc, Yloc, temp; ! 360: ! 361: if (Mchar == 0) return; ! 362: Xloc = MapX + Xoff; ! 363: Yloc = MapY + Yoff; ! 364: if (TestBounds (Xloc, Yloc) == FALSE) return (FALSE); ! 365: if (temp = Map [Xloc][Yloc]) { ! 366: temp = temp & 1023; ! 367: if (temp == RIVER) ! 368: if (Mchar != CHANNEL) ! 369: return (FALSE); ! 370: if (temp == CHANNEL) return (FALSE); ! 371: } ! 372: Map [Xloc][Yloc] = Mchar; ! 373: } ! 374: ! 375: far TestBounds(x, y) ! 376: register int x, y; ! 377: { ! 378: if ((( x >= 0) && (x < WORLD_X)) && (( y >= 0) && (y < WORLD_Y))) ! 379: return (TRUE); ! 380: return (FALSE); ! 381: } ! 382: ! 383: ! 384: ! 385: near EGRand(limit) ! 386: int limit; ! 387: { ! 388: int x,z; ! 389: ! 390: z= GRand(limit); ! 391: x= GRand(limit); ! 392: if (z < x) return(z); ! 393: return(x); ! 394: } ! 395: ! 396: #define RANMASK 32767 ! 397: ! 398: near GRand(range) /* stupid but works */ ! 399: int range; ! 400: { ! 401: register x, newv, divisor; ! 402: ! 403: divisor = RANMASK/ (range+1); ! 404: newv = 0; ! 405: for (x=4; x!=0; x--) ! 406: newv += (GRanArray[x] = GRanArray[x-1]); ! 407: GRanArray[0] = newv; ! 408: x = (newv & RANMASK) / divisor; ! 409: if (x > range) return(range); ! 410: return(x); ! 411: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.