Annotation of micropolis/src/sim/g_cam.c, revision 1.1

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 */

unix.superglobalmegacorp.com

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