|
|
1.1 ! root 1: /* g_cam.c ! 2: * ! 3: * Micropolis, Unix Version. This game was released for the Unix platform ! 4: * in or about 1990 and has been modified for inclusion in the One Laptop ! 5: * Per Child program. Copyright (C) 1989 - 2007 Electronic Arts Inc. If ! 6: * you need assistance with this program, you may contact: ! 7: * http://wiki.laptop.org/go/Micropolis or email [email protected]. ! 8: * ! 9: * This program is free software: you can redistribute it and/or modify ! 10: * it under the terms of the GNU General Public License as published by ! 11: * the Free Software Foundation, either version 3 of the License, or (at ! 12: * your option) any later version. ! 13: * ! 14: * This program is distributed in the hope that it will be useful, but ! 15: * WITHOUT ANY WARRANTY; without even the implied warranty of ! 16: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 17: * General Public License for more details. You should have received a ! 18: * copy of the GNU General Public License along with this program. If ! 19: * not, see <http://www.gnu.org/licenses/>. ! 20: * ! 21: * ADDITIONAL TERMS per GNU GPL Section 7 ! 22: * ! 23: * No trademark or publicity rights are granted. This license does NOT ! 24: * give you any right, title or interest in the trademark SimCity or any ! 25: * other Electronic Arts trademark. You may not distribute any ! 26: * modification of this program using the trademark SimCity or claim any ! 27: * affliation or association with Electronic Arts Inc. or its employees. ! 28: * ! 29: * Any propagation or conveyance of this program must include this ! 30: * copyright notice and these terms. ! 31: * ! 32: * If you convey this program (or any modifications of it) and assume ! 33: * contractual liability for the program to recipients of it, you agree ! 34: * to indemnify Electronic Arts for any liability that those contractual ! 35: * assumptions impose on Electronic Arts. ! 36: * ! 37: * You may not misrepresent the origins of this program; modified ! 38: * versions of the program must be marked as such and not identified as ! 39: * the original program. ! 40: * ! 41: * This disclaimer supplements the one included in the General Public ! 42: * License. TO THE FULLEST EXTENT PERMISSIBLE UNDER APPLICABLE LAW, THIS ! 43: * PROGRAM IS PROVIDED TO YOU "AS IS," WITH ALL FAULTS, WITHOUT WARRANTY ! 44: * OF ANY KIND, AND YOUR USE IS AT YOUR SOLE RISK. THE ENTIRE RISK OF ! 45: * SATISFACTORY QUALITY AND PERFORMANCE RESIDES WITH YOU. ELECTRONIC ARTS ! 46: * DISCLAIMS ANY AND ALL EXPRESS, IMPLIED OR STATUTORY WARRANTIES, ! 47: * INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY, SATISFACTORY QUALITY, ! 48: * FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT OF THIRD PARTY ! 49: * RIGHTS, AND WARRANTIES (IF ANY) ARISING FROM A COURSE OF DEALING, ! 50: * USAGE, OR TRADE PRACTICE. ELECTRONIC ARTS DOES NOT WARRANT AGAINST ! 51: * INTERFERENCE WITH YOUR ENJOYMENT OF THE PROGRAM; THAT THE PROGRAM WILL ! 52: * MEET YOUR REQUIREMENTS; THAT OPERATION OF THE PROGRAM WILL BE ! 53: * UNINTERRUPTED OR ERROR-FREE, OR THAT THE PROGRAM WILL BE COMPATIBLE ! 54: * WITH THIRD PARTY SOFTWARE OR THAT ANY ERRORS IN THE PROGRAM WILL BE ! 55: * CORRECTED. NO ORAL OR WRITTEN ADVICE PROVIDED BY ELECTRONIC ARTS OR ! 56: * ANY AUTHORIZED REPRESENTATIVE SHALL CREATE A WARRANTY. SOME ! 57: * JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF OR LIMITATIONS ON IMPLIED ! 58: * WARRANTIES OR THE LIMITATIONS ON THE APPLICABLE STATUTORY RIGHTS OF A ! 59: * CONSUMER, SO SOME OR ALL OF THE ABOVE EXCLUSIONS AND LIMITATIONS MAY ! 60: * NOT APPLY TO YOU. ! 61: */ ! 62: #include "sim.h" ! 63: ! 64: ! 65: #ifdef CAM ! 66: ! 67: ! 68: Can * ! 69: new_can(int w, int h, Byte *mem, int line_bytes) ! 70: { ! 71: Can *can = (Can *)malloc(sizeof(Can)); ! 72: ! 73: can->width = w; ! 74: can->height = h; ! 75: can->line_bytes = line_bytes; ! 76: can->mem = mem; ! 77: ! 78: return (can); ! 79: } ! 80: ! 81: ! 82: Cam * ! 83: new_cam(SimCam *scam, int x, int y, int w, int h, int dx, int dy, vf func) ! 84: { ! 85: Cam *cam = (Cam *)malloc(sizeof(Cam)); ! 86: int ww, hh; ! 87: ! 88: cam->x = x; ! 89: cam->y = y; ! 90: cam->ideal_width = w; ! 91: cam->ideal_height = h; ! 92: w = (w + 1) & ~1; ! 93: h = (h + 1) & ~1; ! 94: ww = w + 2; ! 95: hh = h + 2; ! 96: cam->width = w; ! 97: cam->height = h; ! 98: cam->back = new_can(ww, hh, (Byte *)malloc(ww * hh), ww); ! 99: cam->front = new_can(w, h, ! 100: (Byte *)scam->data + x + (y * scam->line_bytes), ! 101: scam->line_bytes); ! 102: cam->neighborhood = func; ! 103: cam->rule = NULL; ! 104: cam->rule_size = 0; ! 105: cam->phase = 0; ! 106: cam->wrap = 3; ! 107: cam->frob = -1; ! 108: cam->steps = 1; ! 109: cam->dx = dx; ! 110: cam->dy = dy; ! 111: cam->gx = 0; ! 112: cam->gy = 0; ! 113: cam->dragging = 0; ! 114: cam->set_x = -1; ! 115: cam->set_y = -1; ! 116: cam->set_width = -1; ! 117: cam->set_height = -1; ! 118: cam->set_x0 = -1; ! 119: cam->set_y0 = -1; ! 120: cam->set_x1 = -1; ! 121: cam->set_y1 = -1; ! 122: cam->name = NULL; ! 123: cam->next = scam->cam_list; ! 124: scam->cam_list = cam; ! 125: scam->cam_count++; ! 126: ! 127: return (cam); ! 128: } ! 129: ! 130: ! 131: scam_randomize(SimCam *scam) ! 132: { ! 133: u_char *data = scam->data; ! 134: int line_bytes = scam->line_bytes; ! 135: int pixels = line_bytes * scam->w_height; ! 136: int i; ! 137: ! 138: for (i = 0; i < pixels; i++) { ! 139: *data = (char)(Rand16() >>4); ! 140: data++; ! 141: } ! 142: } ! 143: ! 144: ! 145: cam_randomize(Cam *cam) ! 146: { ! 147: int x, y, w, h, lb; ! 148: Byte *image; ! 149: ! 150: w = cam->width; ! 151: h = cam->height; ! 152: lb = cam->front->line_bytes; ! 153: image = cam->front->mem; ! 154: ! 155: for (y = 0; y < h; y++, image += lb) { ! 156: for (x = 0; x < w; x++) { ! 157: image[x] = (char)(Rand16() >> 4); ! 158: } ! 159: } ! 160: } ! 161: ! 162: ! 163: cam_do_rule(SimCam *scam, Cam *cam) ! 164: { ! 165: Byte *back, *front; ! 166: int frontline, backline; ! 167: int w, h; ! 168: int steps = cam->steps; ! 169: int step; ! 170: ! 171: back = cam->back->mem; ! 172: backline = cam->back->line_bytes; ! 173: ! 174: front = cam->front->mem; ! 175: frontline = cam->front->line_bytes; ! 176: ! 177: w = cam->width; ! 178: h = cam->height; ! 179: ! 180: for (step=0; step < steps; step++) { ! 181: int x, y; ! 182: Byte *p = back + backline + 1, ! 183: *f = front; ! 184: /* ! 185: * Copy wrapping edges from front=>back: ! 186: * ! 187: * 0 ff f0 f1 ... fe ff f0 ! 188: * ! 189: * 1 0f 00 01 ... 0e 0f 00 ! 190: * 2 1f 10 11 ... 1e 1f 10 ! 191: * .. .. .. .. .. .. ! 192: * ef e0 e1 ... ee ef e0 ! 193: * h ff f0 f1 ... fe ff f0 ! 194: * ! 195: * h+1 0f 00 01 ... 0e 0f 00 ! 196: * ! 197: * wrap value: effect: ! 198: * 0 no effect ! 199: * 1 copy front=>back, no wrap ! 200: * 2 no copy, wrap edges ! 201: * 3 copy front=>back, wrap edges ! 202: * 4 copy front=>back, same edges ! 203: * 5 copy edges from screen ! 204: */ ! 205: ! 206: switch (cam->wrap) { ! 207: ! 208: case 0: ! 209: break; ! 210: ! 211: case 1: ! 212: for (y=0; y<h; y++) { ! 213: memcpy(p, f, w); ! 214: p += backline; ! 215: f += frontline; ! 216: } ! 217: break; ! 218: ! 219: case 2: ! 220: for (y=0; y<h; y++) { ! 221: p[-1] = p[w-1]; ! 222: p[w] = p[0]; ! 223: p += backline; ! 224: f += frontline; ! 225: } ! 226: memcpy(back, back + backline*h, backline); ! 227: memcpy(back + backline*(h+1), back + backline, backline); ! 228: break; ! 229: ! 230: case 3: ! 231: for (y=0; y<h; y++) { ! 232: memcpy(p, f, w); ! 233: p[-1] = p[w-1]; ! 234: p[w] = p[0]; ! 235: p += backline; ! 236: f += frontline; ! 237: } ! 238: memcpy(back, back + backline*h, backline); ! 239: memcpy(back + backline*(h+1), back + backline, backline); ! 240: break; ! 241: ! 242: case 4: ! 243: for (y=0; y<h; y++) { ! 244: memcpy(p, f, w); ! 245: p[-1] = p[0]; ! 246: p[w] = p[w-1]; ! 247: p += backline; ! 248: f += frontline; ! 249: } ! 250: memcpy(back + (backline * (h + 1)), back + backline*h, backline); ! 251: memcpy(back, back + backline, backline); ! 252: break; ! 253: ! 254: case 5: ! 255: { int left = (cam->x == 0) ? 1 : 0; ! 256: int right = (cam->x + cam->front->width == scam->w_width) ? 1 : 0; ! 257: int top = (cam->y == 0) ? 1 : 0; ! 258: int bottom = (cam->y + cam->front->height == scam->w_height) ? 1 : 0; ! 259: ! 260: if (!left && !right && !top && !bottom) { ! 261: p = back; ! 262: f = front - 1 - frontline; ! 263: for (y=-1; y<=h; y++) { ! 264: memcpy(p, f, w + 2); ! 265: p += backline; ! 266: f += frontline; ! 267: } ! 268: } else { ! 269: p = back + backline + 1; ! 270: f = front; ! 271: ! 272: p[-1 - backline] = f[left - 1 - (top ? 0 : frontline)]; ! 273: memcpy(p - backline, f, w); ! 274: p[w - backline] = f[w - right - (top ? 0 : frontline)]; ! 275: ! 276: for (y=0; y<h; y++) { ! 277: p[-1] = f[left - 1]; ! 278: memcpy(p, f, w); ! 279: p[w] = f[w - right]; ! 280: p += backline; ! 281: f += frontline; ! 282: } ! 283: } ! 284: } ! 285: break; ! 286: ! 287: } ! 288: ! 289: cam_slide(scam, cam); ! 290: ! 291: (*cam->neighborhood)(cam); ! 292: cam->phase = !cam->phase; ! 293: ! 294: cam_update(scam, cam); ! 295: ! 296: cam_adjust(scam, cam); ! 297: } /* for step */ ! 298: } ! 299: ! 300: ! 301: cam_slide(SimCam *scam, Cam *cam) ! 302: { ! 303: int x = cam->x; ! 304: int y = cam->y; ! 305: int last_x = x; ! 306: int last_y = y; ! 307: int width = cam->width; ! 308: int height = cam->height; ! 309: int dx = cam->dx; ! 310: int dy = cam->dy; ! 311: int dragging = cam->dragging; ! 312: int bounce = 0; ! 313: int dagnabit = 0; ! 314: ! 315: if (dragging || ! 316: (cam->set_x >= 0) || ! 317: (cam->set_y >= 0)) { ! 318: if (cam->set_x >= 0) { ! 319: x = cam->set_x; ! 320: cam->set_x = -1; ! 321: } ! 322: if (cam->set_y >= 0) { ! 323: y = cam->set_y; ! 324: cam->set_y = -1; ! 325: } ! 326: } else { ! 327: x += dx; ! 328: y += dy; ! 329: } ! 330: ! 331: if (x < 0) { ! 332: x = 0; ! 333: if (!dragging) { ! 334: dx = ABS(dx); ! 335: bounce = 1; ! 336: } ! 337: } else if ((x + width) > scam->w_width) { ! 338: x = scam->w_width - width; ! 339: if (!dragging) { ! 340: dx = -ABS(dx); ! 341: bounce = 1; ! 342: } ! 343: } ! 344: ! 345: if (y < 0) { ! 346: y = 0; ! 347: if (!dragging) { ! 348: dy = ABS(dy); ! 349: bounce = 1; ! 350: } ! 351: else { ! 352: dagnabit = 1; ! 353: printf("dagnabit\n"); ! 354: } ! 355: } else if ((y + height) > scam->w_height) { ! 356: y = scam->w_height - height; ! 357: if (!dragging) { ! 358: dy = -ABS(dy); ! 359: bounce = 1; ! 360: } ! 361: } ! 362: ! 363: if (dragging) { ! 364: dx = x - last_x; ! 365: dy = y - last_y; ! 366: } else { ! 367: if (bounce) { ! 368: cam->frob = (Rand16() & 15) * ((cam->frob > 0) ? -1 : 1); ! 369: } ! 370: } ! 371: ! 372: cam->x = x; ! 373: cam->y = y; ! 374: cam->front->mem = (Byte *)scam->data + x + (scam->line_bytes * y); ! 375: cam->dx = dx + cam->gx; ! 376: cam->dy = dy + cam->gy; ! 377: if (dagnabit) { ! 378: printf("x %d y %d dx %d dy %d\n", cam->x, cam->y, cam->dx, cam->dy); ! 379: } ! 380: } ! 381: ! 382: ! 383: cam_update(SimCam *scam, Cam *cam) ! 384: { ! 385: if (scam->x->shared) { ! 386: XShmPutImage(scam->x->dpy, Tk_WindowId(scam->tkwin), scam->x->gc, ! 387: scam->image, cam->x, cam->y, ! 388: cam->x, cam->y, cam->width, cam->height, ! 389: False); ! 390: } else { ! 391: XPutImage(scam->x->dpy, Tk_WindowId(scam->tkwin), scam->x->gc, ! 392: scam->image, cam->x, cam->y, ! 393: cam->x, cam->y, cam->width, cam->height); ! 394: } ! 395: } ! 396: ! 397: ! 398: cam_adjust(SimCam *scam, Cam *cam) ! 399: { ! 400: int x0 = cam->set_x0; ! 401: int y0 = cam->set_y0; ! 402: int x1 = cam->set_x1; ! 403: int y1 = cam->set_y1; ! 404: int width = cam->set_width; ! 405: int height = cam->set_height; ! 406: int min_size = 8; ! 407: int tmp; ! 408: ! 409: if ((x0 >= 0) || ! 410: (y0 >= 0) || ! 411: (x1 >= 0) || ! 412: (y1 >= 0) || ! 413: (width > 0) || ! 414: (height > 0)) { ! 415: if (x0 < 0) x0 = cam->x; ! 416: if (y0 < 0) y0 = cam->y; ! 417: if (x1 < 0) x1 = cam->x + cam->ideal_width; ! 418: if (y1 < 0) y1 = cam->y + cam->ideal_height; ! 419: if (width > 0) x1 = x0 + width; ! 420: if (height > 0) y1 = y0 + height; ! 421: ! 422: cam->set_width = cam->set_height = ! 423: cam->set_x0 = cam->set_y0 = ! 424: cam->set_x1 = cam->set_y1 = -1; ! 425: ! 426: if (x0 > x1) { ! 427: tmp = x0; x0 = x1; x1 = tmp; ! 428: } ! 429: ! 430: if (y0 > y1) { ! 431: tmp = y0; y0 = y1; y1 = tmp; ! 432: } ! 433: ! 434: if (x0 < 0) x0 = 0; ! 435: if (y0 < 0) y0 = 0; ! 436: if (x0 > scam->w_width - min_size) x0 = scam->w_width - min_size; ! 437: if (y0 > scam->w_height - min_size) x0 = scam->w_height - min_size; ! 438: if (x1 < x0 + min_size) x1 = x0 + min_size; ! 439: if (y1 < y0 + min_size) y1 = y0 + min_size; ! 440: if (x1 > scam->w_width) x1 = scam->w_width; ! 441: if (y1 > scam->w_height) y1 = scam->w_height; ! 442: ! 443: cam->x = x0; ! 444: cam->y = y0; ! 445: cam->ideal_width = x1 - x0; ! 446: cam->ideal_height = y1 - y0; ! 447: cam->width = cam->ideal_width & ~1; ! 448: cam->height = cam->ideal_height & ~1; ! 449: cam->front->mem = (Byte *)scam->data + x0 + (y0 * scam->line_bytes); ! 450: cam->front->width = cam->width; ! 451: cam->front->height = cam->height; ! 452: free(cam->back->mem); ! 453: cam->back->mem = (Byte *)malloc((cam->width + 2) * (cam->height + 2)); ! 454: cam->back->width = cam->width + 2; ! 455: cam->back->height = cam->height + 2; ! 456: cam->back->line_bytes = cam->back->width; ! 457: } ! 458: } ! 459: ! 460: ! 461: void ! 462: n_moore_a(Cam *cam) ! 463: { ! 464: /* 0 1 2 3 4 5 6 7 8 9 */ ! 465: /* c c' se sw ne nw e w s n */ ! 466: /* 0x1 0x2 0x4 0x8 0x10 0x20 0x40 0x80 0x100 0x200 */ ! 467: ! 468: #define MOORE_A ( \ ! 469: ((NORTHWEST&1)<<5) | ((NORTH&1)<<9) |((NORTHEAST&1)<<4) | \ ! 470: ((WEST&1)<<7) | (CENTER&3) | ((EAST&1)<<6) | \ ! 471: ((SOUTHWEST&1)<<3) | ((SOUTH&1)<<8) |((SOUTHEAST&1)<<2) \ ! 472: ) ! 473: ! 474: CAM_TABLE_LOOP(MOORE_A) ! 475: } ! 476: ! 477: ! 478: void ! 479: n_moore_ab(Cam *cam) ! 480: { ! 481: /* 0 1 2 3 4 5 6 7 8 9 10 11 */ ! 482: /* c c' se sw ne nw e w s n &c &c' */ ! 483: /* 0x1 0x2 0x4 0x8 0x10 0x20 0x40 0x80 0x100 0x200 0x400 0x800 */ ! 484: ! 485: #define MOORE_AB (MOORE_A | ((CENTER&12)<<8)) ! 486: ! 487: CAM_TABLE_LOOP(MOORE_AB) ! 488: } ! 489: ! 490: ! 491: void ! 492: n_vonn_neumann(Cam *cam) ! 493: { ! 494: /* 0 1 2 3 4 5 6 7 8 9 */ ! 495: /* c c' e' w' s' n' e w s n */ ! 496: /* 0x1 0x2 0x4 0x8 0x10 0x20 0x40 0x80 0x100 0x200 */ ! 497: ! 498: #define VON_NEUMANN ( \ ! 499: (CENTER&3) | \ ! 500: ((EAST&1)<<6) | ((EAST&2)<<1) | \ ! 501: ((WEST&1)<<7) | ((WEST&2)<<2) | \ ! 502: ((SOUTH&1)<<8) | ((SOUTH&2)<<3) | \ ! 503: ((NORTH&1)<<9) | ((NORTH&2)<<4) \ ! 504: ) ! 505: ! 506: CAM_TABLE_LOOP(VON_NEUMANN) ! 507: } ! 508: ! 509: ! 510: void ! 511: n_margolis(Cam *cam) ! 512: { ! 513: register Byte i; ! 514: ! 515: /* 0 1 2 3 4 5 6 7 8 9 */ ! 516: /* c c' cw ccw opp cw' ccw' opp' */ ! 517: /* 0x1 0x2 0x4 0x8 0x10 0x20 0x40 0x80 0x100 0x200 */ ! 518: ! 519: #define MARGOLIS_ODD ( \ ! 520: (CENTER & 3) | \ ! 521: (i=(x&1 ? (y&1 ? (EAST) : (NORTH)) \ ! 522: : (y&1 ? (SOUTH) : (WEST))), \ ! 523: (((i&1)<<2) | ((i&2)<<4))) | \ ! 524: (i=(x&1 ? (y&1 ? (SOUTH) : (EAST)) \ ! 525: : (y&1 ? (WEST) : (NORTH))), \ ! 526: (((i&1)<<3) | ((i&2)<<5))) | \ ! 527: (i=(x&1 ? (y&1 ? (SOUTHEAST):(NORTHEAST)) \ ! 528: : (y&1 ? (SOUTHWEST):(NORTHWEST))), \ ! 529: (((i&1)<<4) | ((i&2)<<6))) \ ! 530: ) ! 531: ! 532: #define MARGOLIS_EVEN ( \ ! 533: (CENTER & 3) | \ ! 534: (i=(x&1 ? (y&1 ? (WEST) : (SOUTH)) \ ! 535: : (y&1 ? (NORTH) : (EAST))), \ ! 536: (((i&1)<<2) | ((i&2)<<4))) | \ ! 537: (i=(x&1 ? (y&1 ? (NORTH) : (WEST)) \ ! 538: : (y&1 ? (EAST) : (SOUTH))), \ ! 539: (((i&1)<<3) | ((i&2)<<5))) | \ ! 540: (i=(x&1 ? (y&1 ? (NORTHWEST) : (SOUTHWEST)) \ ! 541: : (y&1 ? (NORTHEAST) : (SOUTHEAST))), \ ! 542: (((i&1)<<4) | ((i&2)<<6))) \ ! 543: ) ! 544: ! 545: if (cam->phase) { ! 546: CAM_TABLE_LOOP(MARGOLIS_ODD) ! 547: } else { ! 548: CAM_TABLE_LOOP(MARGOLIS_EVEN) ! 549: } ! 550: } ! 551: ! 552: ! 553: void ! 554: n_margolis_ph(Cam *cam) ! 555: { ! 556: register Byte i; ! 557: ! 558: /* 0 1 2 3 4 5 6 7 8 9 */ ! 559: /* c c' cw ccw opp cw' ccw' opp' pha pha' */ ! 560: /* 0x1 0x2 0x4 0x8 0x10 0x20 0x40 0x80 0x100 0x200 */ ! 561: ! 562: #define MARGOLIS_ODD_PH (MARGOLIS_ODD | 0x100) ! 563: #define MARGOLIS_EVEN_PH (MARGOLIS_EVEN | 0x200) ! 564: ! 565: if (cam->phase) { ! 566: CAM_TABLE_LOOP(MARGOLIS_ODD_PH) ! 567: } else { ! 568: CAM_TABLE_LOOP(MARGOLIS_EVEN_PH) ! 569: } ! 570: } ! 571: ! 572: ! 573: void ! 574: n_margolis_hv(Cam *cam) ! 575: { ! 576: register Byte i; ! 577: ! 578: /* 0 1 2 3 4 5 6 7 8 9 */ ! 579: /* c c' cw ccw opp cw' ccw' opp' horz vert */ ! 580: /* 0x1 0x2 0x4 0x8 0x10 0x20 0x40 0x80 0x100 0x200 */ ! 581: ! 582: #define MARGOLIS_ODD_HV (MARGOLIS_ODD | ((x&1)<<8) | ((y&1)<<9)) ! 583: #define MARGOLIS_EVEN_HV (MARGOLIS_EVEN | ((x&1)<<8) | ((y&1)<<9)) ! 584: ! 585: if (cam->phase) { ! 586: CAM_TABLE_LOOP(MARGOLIS_ODD_HV) ! 587: } else { ! 588: CAM_TABLE_LOOP(MARGOLIS_EVEN_HV) ! 589: } ! 590: } ! 591: ! 592: ! 593: void ! 594: n_life(Cam *cam) ! 595: { ! 596: int s; ! 597: ! 598: #define LIFE ( \ ! 599: ((CENTER&1) ? (((s = SUM8) == 2) || (s == 3)) \ ! 600: : (SUM8 == 3)) | \ ! 601: (CENTER<<1) \ ! 602: ) ! 603: ! 604: CAM_LOOP(LIFE) ! 605: } ! 606: ! 607: ! 608: void ! 609: n_brain(Cam *cam) ! 610: { ! 611: int s; ! 612: ! 613: #define BRAIN ( \ ! 614: (((((s = CENTER)&3) == 0) && (SUM8 == 2)) ? 1 : 0) | \ ! 615: (s<<1) \ ! 616: ) ! 617: ! 618: CAM_LOOP(BRAIN) ! 619: } ! 620: ! 621: ! 622: void ! 623: n_heat(Cam *cam) ! 624: { ! 625: int frob = cam->frob; ! 626: ! 627: #define HEAT ( \ ! 628: ((QUAD)(NORTHWEST + NORTH + NORTHEAST + \ ! 629: WEST + EAST + \ ! 630: SOUTHWEST + SOUTH + SOUTHEAST + frob)) >> 3 \ ! 631: ) ! 632: ! 633: CAM_LOOP(HEAT) ! 634: } ! 635: ! 636: ! 637: void ! 638: n_dheat(Cam *cam) ! 639: { ! 640: int frob = cam->frob; ! 641: int last = 0; ! 642: ! 643: #define DHEAT \ ! 644: last += NORTHWEST + NORTH + NORTHEAST + \ ! 645: WEST + frob + EAST + \ ! 646: SOUTHWEST + SOUTH + SOUTHEAST; \ ! 647: *front = last >> 3; \ ! 648: last &= 7; ! 649: CAM_LOOP_BODY(DHEAT) ! 650: ! 651: } ! 652: ! 653: ! 654: void ! 655: n_lheat(Cam *cam) ! 656: { ! 657: int frob = cam->frob; ! 658: ! 659: #define LHEAT ( \ ! 660: ((QUAD)(NORTH + WEST + EAST + SOUTH + frob)) >> 2 \ ! 661: ) ! 662: ! 663: CAM_LOOP(LHEAT) ! 664: } ! 665: ! 666: ! 667: void ! 668: n_ldheat(Cam *cam) ! 669: { ! 670: int frob = cam->frob; ! 671: int last; /* I meant to do that! */ ! 672: ! 673: #define LDHEAT ( \ ! 674: ((last = (QUAD)(NORTH + WEST + EAST + SOUTH + frob \ ! 675: + (last&0x03))), last >> 2) \ ! 676: ) ! 677: ! 678: CAM_LOOP(LDHEAT) ! 679: } ! 680: ! 681: ! 682: void ! 683: n_abdheat(Cam *cam) ! 684: { ! 685: int frob = cam->frob; ! 686: int lasta = 0, lastb = 0; /* I meant to do that! */ ! 687: ! 688: #define YUM(x) (((QUAD)(x))&0x0f) ! 689: #define YUK(x) (((QUAD)(x))&0xf0) ! 690: ! 691: #define ABDHEAT ( \ ! 692: (lasta = (QUAD)(YUM(NORTHWEST) + YUM(NORTH) + YUM(NORTHEAST) + \ ! 693: YUM(WEST) + YUM(EAST) + \ ! 694: YUM(SOUTHWEST) + YUM(SOUTH) + YUM(SOUTHEAST) + \ ! 695: frob + (lasta&0x07))), \ ! 696: (lastb = (QUAD)(YUK(NORTHWEST) + YUK(NORTH) + YUK(NORTHEAST) + \ ! 697: YUK(WEST) + YUK(EAST) + \ ! 698: YUK(SOUTHWEST) + YUK(SOUTH) + YUK(SOUTHEAST) + \ ! 699: (frob<<4) + (lastb&0x70))), \ ! 700: (((lasta>>3)&0x0f) | ((lastb>>3)&0xf0)) \ ! 701: ) ! 702: ! 703: CAM_LOOP(ABDHEAT) ! 704: } ! 705: ! 706: ! 707: void ! 708: n_abcdheat(Cam *cam) ! 709: { ! 710: int last; ! 711: int frob = cam->frob; ! 712: ! 713: CAM_LOOP(HEAT) ! 714: } ! 715: ! 716: ! 717: void ! 718: n_edheat(Cam *cam) ! 719: { ! 720: int frob = cam->frob; ! 721: int last = 0; ! 722: ! 723: #define EDHEAT ( \ ! 724: (last = (QUAD)(YUM(NORTHWEST) + YUM(NORTH) + YUM(NORTHEAST) + \ ! 725: YUM(WEST) + YUM(EAST) + \ ! 726: YUM(SOUTHWEST) + YUM(SOUTH) + YUM(SOUTHEAST) + \ ! 727: frob + (last&0x07))), \ ! 728: (((last>>3)&0x0f) | ((CENTER<<4)&0xf0)) \ ! 729: ) ! 730: ! 731: CAM_LOOP(EDHEAT) ! 732: } ! 733: ! 734: ! 735: int ranch(QUAD l0, QUAD l1, QUAD l2) ! 736: { ! 737: int s = SUM8; ! 738: int v = SUM9p(1); ! 739: int o = 0; ! 740: ! 741: o = (CENTER&4)<<1; ! 742: ! 743: if (v < 4 || v == 5) { ! 744: o |= 0x04; ! 745: } else { ! 746: } ! 747: ! 748: return (o); ! 749: } ! 750: ! 751: ! 752: void ! 753: n_ranch(Cam *cam) ! 754: { ! 755: #define RANCH ranch(l0, l1, l2) ! 756: ! 757: CAM_LOOP(RANCH) ! 758: } ! 759: ! 760: ! 761: void ! 762: n_anneal(Cam *cam) ! 763: { ! 764: int s; ! 765: ! 766: #define ANNEAL ( \ ! 767: ((s = SUM9) > 5) || (s == 4) \ ! 768: ) ! 769: CAM_LOOP(ANNEAL) ! 770: } ! 771: ! 772: ! 773: void ! 774: n_anneal4(Cam *cam) ! 775: { ! 776: int s; ! 777: ! 778: #define ANNEAL4 ( \ ! 779: ((((s = SUM9p(0)) > 5) || (s == 4)) ? 1 : 0) | \ ! 780: ((((s = SUM9p(1)) > 5) || (s == 4)) ? 2 : 0) | \ ! 781: ((((s = SUM9p(2)) > 5) || (s == 4)) ? 4 : 0) | \ ! 782: ((((s = SUM9p(3)) > 5) || (s == 4)) ? 8 : 0) | \ ! 783: (CENTER << 4) \ ! 784: ) ! 785: CAM_LOOP(ANNEAL4) ! 786: } ! 787: ! 788: ! 789: void ! 790: n_anneal8(Cam *cam) ! 791: { ! 792: int s; ! 793: ! 794: #define ANNEAL8 ( \ ! 795: ((((s = SUM9p(0)) > 5) || (s == 4)) ? 1 : 0) | \ ! 796: ((((s = SUM9p(1)) > 5) || (s == 4)) ? 2 : 0) | \ ! 797: ((((s = SUM9p(2)) > 5) || (s == 4)) ? 4 : 0) | \ ! 798: ((((s = SUM9p(3)) > 5) || (s == 4)) ? 8 : 0) | \ ! 799: ((((s = SUM9p(4)) > 5) || (s == 4)) ? 16 : 0) | \ ! 800: ((((s = SUM9p(5)) > 5) || (s == 4)) ? 32 : 0) | \ ! 801: ((((s = SUM9p(6)) > 5) || (s == 4)) ? 64 : 0) | \ ! 802: ((((s = SUM9p(7)) > 5) || (s == 4)) ? 128 : 0) \ ! 803: ) ! 804: CAM_LOOP(ANNEAL8) ! 805: } ! 806: ! 807: ! 808: void ! 809: n_eco(Cam *cam) ! 810: { ! 811: int s; ! 812: ! 813: #define ANTILIFE ( \ ! 814: ((CENTER&1) ? (SUM8 != 5) \ ! 815: : (((s = SUM8) != 5) && (s != 6))) | \ ! 816: (CENTER<<1) \ ! 817: ) ! 818: ! 819: #define ECO ( \ ! 820: (((s = SUM9p(7)) > 5) || (s == 4) ? 128 : 0) | \ ! 821: ((CENTER&128) ? ((ANTILIFE)&127) : ((BRAIN)&127)) \ ! 822: ) ! 823: CAM_LOOP(ECO) ! 824: } ! 825: ! 826: ! 827: void ! 828: n_torben(Cam *cam) ! 829: { ! 830: int s; ! 831: ! 832: /* 0 0 0 1 0 1 0 1 1 1 */ ! 833: ! 834: #define TORBEN ( \ ! 835: (CENTER << 1) | ((((s = SUM9) > 6) || (s == 5) || (s == 3)) ? 1 : 0) \ ! 836: ) ! 837: CAM_LOOP(TORBEN) ! 838: } ! 839: ! 840: ! 841: void ! 842: n_torben2(Cam *cam) ! 843: { ! 844: int s; ! 845: ! 846: ! 847: /* 0 0 0 1 0 1 0 1 1 1 */ ! 848: /* 0 0 1 0 1 0 1 0 1 1 */ ! 849: #define TORBEN2 ( \ ! 850: TORBEN | (CENTER <<1) \ ! 851: ) ! 852: CAM_LOOP(TORBEN2) ! 853: } ! 854: ! 855: ! 856: void ! 857: n_torben3(Cam *cam) ! 858: { ! 859: int s; ! 860: ! 861: /* 0 0 0 1 1 0 0 1 1 1 */ ! 862: ! 863: #define TORBEN3 ( \ ! 864: ((s = SUM9) > 6) || (s == 3) || (s == 4) \ ! 865: ) ! 866: CAM_LOOP(TORBEN3) ! 867: } ! 868: ! 869: ! 870: void ! 871: n_torben4(Cam *cam) ! 872: { ! 873: int s; ! 874: ! 875: ! 876: /* 0 0 0 1 0 1 0 1 1 1 */ ! 877: /* 0 0 1 0 1 0 1 0 1 1 */ ! 878: #define TORBEN4 ( \ ! 879: TORBEN3 | (CENTER <<1) \ ! 880: ) ! 881: CAM_LOOP(TORBEN4) ! 882: } ! 883: ! 884: ! 885: void ! 886: n_ball(Cam *cam) ! 887: { ! 888: char p = (cam->phase ? 1 : 0); ! 889: int x, y, r = Rand16(); ! 890: int backline = cam->back->line_bytes, ! 891: frontline = cam->front->line_bytes; ! 892: Byte *back = cam->back->mem, ! 893: *front = cam->front->mem; ! 894: ! 895: if (!p) { ! 896: back += 1 + backline; ! 897: } ! 898: ! 899: for (y = p + (cam->height >>1); y > 0; y--) { ! 900: for (x = p + (cam->width >>1); x > 0; x--) { ! 901: Byte nw = back[0], ne = back[1], ! 902: sw = back[backline], se = back[backline+1]; ! 903: ! 904: r += nw + ne + sw + sw; r >>= 1; ! 905: ! 906: switch ((nw&1) + (ne&1) + (sw&1) + (se&1)) { ! 907: case 0: ! 908: case 3: ! 909: case 4: ! 910: /* same */ ! 911: back[0] = nw; back[1] = ne; ! 912: back[backline] = sw; back[backline+1] = se; ! 913: break; ! 914: case 1: ! 915: /* reflect */ ! 916: back[0] = se; back[1] = sw; ! 917: back[backline] = ne; back[backline+1] = nw; ! 918: break; ! 919: case 2: ! 920: /* turn */ ! 921: switch (((nw&1) <<3) | ((ne&1) <<2) | ((sw&1) <<1) | (se&1)) { ! 922: case 6: ! 923: case 9: ! 924: if (r&1) { ! 925: /* clockwise */ ! 926: back[0] = sw; back[1] = nw; ! 927: back[backline] = se; back[backline+1] = ne; ! 928: } else { ! 929: /* counterclockwise */ ! 930: back[0] = ne; back[1] = se; ! 931: back[backline] = nw; back[backline+1] = sw; ! 932: } ! 933: default: ! 934: back[0] = nw; back[1] = ne; ! 935: back[backline] = sw; back[backline+1] = se; ! 936: break; ! 937: } ! 938: break; ! 939: } ! 940: ! 941: back += 2; ! 942: } ! 943: back += backline + backline - cam->width - (2*p); ! 944: } ! 945: back = cam->back->mem + backline + 1, ! 946: front = cam->front->mem; ! 947: ! 948: for (y = cam->height; y > 0; y--) { ! 949: memcpy(front, back, cam->width); ! 950: back += backline; ! 951: front += frontline; ! 952: } ! 953: } ! 954: ! 955: ! 956: void ! 957: n_logic(Cam *cam) ! 958: { ! 959: char p = (cam->phase ? 1 : 0); ! 960: int x, y; ! 961: int backline = cam->back->line_bytes, ! 962: frontline = cam->front->line_bytes; ! 963: Byte tmp; ! 964: Byte *back = cam->back->mem, ! 965: *front = cam->front->mem; ! 966: ! 967: /* bit 8 is center' */ ! 968: /* bit 7 is center */ ! 969: ! 970: if (cam->phase) { ! 971: back += 1 + backline; ! 972: front += 1 + frontline; ! 973: } ! 974: ! 975: for (y = cam->height >>1; y > 0; y--) { ! 976: for (x = cam->width >>1; x > 0; x--) { ! 977: Byte nw = back[0], ne = back[1], ! 978: sw = back[backline], se = back[backline+1]; ! 979: ! 980: switch (((nw&128) >>4) | ((ne&128) >>5) | ! 981: ((sw&128) >>6) | ((se&128) >>7)) { ! 982: case 0: ! 983: break; ! 984: ! 985: case 1: ! 986: break; ! 987: ! 988: case 2: ! 989: break; ! 990: ! 991: case 3: ! 992: break; ! 993: ! 994: case 4: ! 995: break; ! 996: ! 997: case 5: ! 998: break; ! 999: ! 1000: case 6: ! 1001: break; ! 1002: ! 1003: case 7: ! 1004: break; ! 1005: ! 1006: case 8: ! 1007: break; ! 1008: ! 1009: case 9: ! 1010: break; ! 1011: ! 1012: case 10: ! 1013: break; ! 1014: ! 1015: case 11: ! 1016: break; ! 1017: ! 1018: case 12: ! 1019: break; ! 1020: ! 1021: case 13: ! 1022: break; ! 1023: ! 1024: case 14: ! 1025: break; ! 1026: ! 1027: case 15: ! 1028: tmp = nw; nw = se; se = tmp; ! 1029: tmp = sw; ne = sw; sw = tmp; ! 1030: break; ! 1031: ! 1032: } ! 1033: ! 1034: back += 2; front += 2; ! 1035: } ! 1036: back += backline + backline - cam->width; ! 1037: front += frontline + frontline - cam->width; ! 1038: } ! 1039: ! 1040: back = cam->back->mem + backline + 1, ! 1041: front = cam->front->mem; ! 1042: ! 1043: for (y = cam->height; y > 0; y--) { ! 1044: memcpy(front, back, cam->width); ! 1045: back += backline; ! 1046: front += frontline; ! 1047: } ! 1048: } ! 1049: ! 1050: ! 1051: void ! 1052: n_party(Cam *cam) ! 1053: { ! 1054: #define PARTY (CENTER ^ NORTH ^ SOUTH ^ EAST ^ WEST) ! 1055: CAM_LOOP(PARTY) ! 1056: } ! 1057: ! 1058: ! 1059: vf neighborhoods[] = { ! 1060: /* 0 1 2 3 */ ! 1061: &n_moore_a, &n_moore_a, &n_moore_ab, &n_vonn_neumann, ! 1062: /* 4 5 6 */ ! 1063: &n_margolis, &n_margolis_ph, &n_margolis_hv, ! 1064: /* 7 8 9 10 11 12 */ ! 1065: &n_life, &n_brain, &n_heat, &n_dheat, &n_lheat, &n_ldheat, ! 1066: /* 13 14 15 16 17 */ ! 1067: &n_ranch, &n_anneal, &n_anneal4, &n_anneal8, &n_eco, ! 1068: /* 18 19 20 21 22 */ ! 1069: &n_abdheat, &n_edheat, &n_abcdheat, &n_torben, &n_torben2, ! 1070: /* 23 24 25 26 27 */ ! 1071: &n_torben3, &n_torben4, &n_ball, &n_logic, &n_party ! 1072: }; ! 1073: ! 1074: ! 1075: cam_set_neighborhood(Cam *cam, int code) ! 1076: { ! 1077: cam->neighborhood = neighborhoods[code]; ! 1078: } ! 1079: ! 1080: ! 1081: cam_load_rule(Cam *cam, char *filename) ! 1082: { ! 1083: FILE *fp; ! 1084: QUAD magic, neighborhood, rule_size; ! 1085: Byte *rule; ! 1086: ! 1087: if ((fp = fopen(filename, "r")) == NULL) { ! 1088: fprintf(stderr, "cam: Can't open rule file \"%s\"\n", filename); ! 1089: return; ! 1090: } ! 1091: ! 1092: /* XXX: Make this byte order independent!!! */ ! 1093: ! 1094: #if defined(MSDOS) || defined(OSF1) || defined(IS_INTEL) ! 1095: ! 1096: #define SWAPQUAD(x) ((x = ((x <<24) & 0xff000000) | \ ! 1097: ((x <<8) & 0x00ff0000) | \ ! 1098: ((x >>8) & 0x0000ff00) | \ ! 1099: ((x >>24) & 0x000000ff)), 0) ! 1100: ! 1101: #else ! 1102: ! 1103: #define SWAPQUAD(x) 0 ! 1104: ! 1105: #endif ! 1106: ! 1107: if ((fread(&magic, 1, sizeof(QUAD), fp) != sizeof(QUAD)) || ! 1108: SWAPQUAD(magic) || ! 1109: (magic != 0xcac0cac0) || ! 1110: (fread(&neighborhood, 1, sizeof(QUAD), fp) != sizeof(QUAD)) || ! 1111: SWAPQUAD(neighborhood) || ! 1112: (fread(&rule_size, 1, sizeof(QUAD), fp) != sizeof(QUAD)) || ! 1113: SWAPQUAD(rule_size) || ! 1114: ((rule = (Byte *)malloc(rule_size)) == NULL) || ! 1115: (fread(rule, 1, rule_size, fp) != rule_size)) { ! 1116: fprintf(stderr, "cam: Bad rule file \"%s\"\n", filename); ! 1117: fclose(fp); ! 1118: return; ! 1119: } ! 1120: ! 1121: fclose(fp); ! 1122: if (cam->rule != NULL) ! 1123: free(cam->rule); ! 1124: cam->rule = rule; ! 1125: cam->rule_size = rule_size; ! 1126: cam_set_neighborhood(cam, neighborhood); ! 1127: } ! 1128: ! 1129: ! 1130: Cam * ! 1131: find_cam(SimCam *scam, int x, int y) ! 1132: { ! 1133: Cam *cam; ! 1134: ! 1135: for (cam = scam->cam_list; cam != NULL; cam = cam->next) { ! 1136: if ((x >= cam->x) && ! 1137: (y >= cam->y) && ! 1138: (x < cam->x + cam->width) && ! 1139: (y < cam->y + cam->height)) { ! 1140: break; ! 1141: } ! 1142: } ! 1143: ! 1144: return cam; ! 1145: } ! 1146: ! 1147: ! 1148: Cam * ! 1149: find_cam_by_name(SimCam *scam, char *name) ! 1150: { ! 1151: Cam *cam; ! 1152: ! 1153: for (cam = scam->cam_list; cam != NULL; cam = cam->next) { ! 1154: if ((cam->name != NULL) && ! 1155: (strcmp(name, cam->name) == 0)) { ! 1156: return cam; ! 1157: } ! 1158: } ! 1159: ! 1160: return NULL; ! 1161: } ! 1162: ! 1163: ! 1164: Cam * ! 1165: get_cam_number(SimCam *scam, int i) ! 1166: { ! 1167: Cam *cam; ! 1168: ! 1169: for (cam = scam->cam_list; ! 1170: (i != 0) && (cam != NULL); ! 1171: (i--), (cam = cam->next)) ; ! 1172: ! 1173: return cam; ! 1174: } ! 1175: ! 1176: ! 1177: cam_layout(SimCam *scam) ! 1178: { ! 1179: int x, y, gap, border, maxwidth, lastmax; ! 1180: Cam *cam; ! 1181: ! 1182: border = 8; ! 1183: gap = 8; ! 1184: x = border; y = border; ! 1185: maxwidth = lastmax = gap; ! 1186: ! 1187: for (cam = scam->cam_list; cam != NULL; cam = cam->next) { ! 1188: cam->dx = 0; cam->dy = 0; ! 1189: if (cam->width > maxwidth) { ! 1190: lastmax = maxwidth; ! 1191: maxwidth = cam->width; ! 1192: } ! 1193: if (y + cam->height + border > scam->w_height) { ! 1194: y = border; x = x + maxwidth + gap; ! 1195: maxwidth = lastmax = gap; ! 1196: } ! 1197: if ((x + cam->width > scam->w_width) || ! 1198: (y + cam->height > scam->w_height)) { ! 1199: cam->x = 0; cam->y = 0; ! 1200: cam->front->mem = (Byte *)scam->data; ! 1201: maxwidth = lastmax; ! 1202: } else { ! 1203: cam->x = x; cam->y = y; ! 1204: cam->front->mem = ! 1205: scam->data + x + (scam->line_bytes * y); ! 1206: y = y + cam->height + gap; ! 1207: } ! 1208: } ! 1209: } ! 1210: ! 1211: ! 1212: init_scam(SimCam *scam) ! 1213: { ! 1214: scam_randomize(scam); ! 1215: } ! 1216: ! 1217: ! 1218: handle_scam(SimCam *scam) ! 1219: { ! 1220: Cam *cam; ! 1221: ! 1222: for (cam = scam->cam_list; cam != NULL; cam = cam->next) { ! 1223: cam_do_rule(scam, cam); ! 1224: } ! 1225: } ! 1226: ! 1227: ! 1228: #endif /* CAM */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.