]>
git.zerfleddert.de Git - micropolis/blob - src/sim/g_cam.c
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 micropolis@laptop.org.
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.
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/>.
21 * ADDITIONAL TERMS per GNU GPL Section 7
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.
29 * Any propagation or conveyance of this program must include this
30 * copyright notice and these terms.
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.
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.
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
69 new_can(int w
, int h
, Byte
*mem
, int line_bytes
)
71 Can
*can
= (Can
*)malloc(sizeof(Can
));
75 can
->line_bytes
= line_bytes
;
83 new_cam(SimCam
*scam
, int x
, int y
, int w
, int h
, int dx
, int dy
, vf func
)
85 Cam
*cam
= (Cam
*)malloc(sizeof(Cam
));
91 cam
->ideal_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
),
102 cam
->neighborhood
= func
;
117 cam
->set_height
= -1;
123 cam
->next
= scam
->cam_list
;
124 scam
->cam_list
= cam
;
131 scam_randomize(SimCam
*scam
)
133 u_char
*data
= scam
->data
;
134 int line_bytes
= scam
->line_bytes
;
135 int pixels
= line_bytes
* scam
->w_height
;
138 for (i
= 0; i
< pixels
; i
++) {
139 *data
= (char)(Rand16() >>4);
145 cam_randomize(Cam
*cam
)
152 lb
= cam
->front
->line_bytes
;
153 image
= cam
->front
->mem
;
155 for (y
= 0; y
< h
; y
++, image
+= lb
) {
156 for (x
= 0; x
< w
; x
++) {
157 image
[x
] = (char)(Rand16() >> 4);
163 cam_do_rule(SimCam
*scam
, Cam
*cam
)
166 int frontline
, backline
;
168 int steps
= cam
->steps
;
171 back
= cam
->back
->mem
;
172 backline
= cam
->back
->line_bytes
;
174 front
= cam
->front
->mem
;
175 frontline
= cam
->front
->line_bytes
;
180 for (step
=0; step
< steps
; step
++) {
182 Byte
*p
= back
+ backline
+ 1,
185 * Copy wrapping edges from front=>back:
187 * 0 ff f0 f1 ... fe ff f0
189 * 1 0f 00 01 ... 0e 0f 00
190 * 2 1f 10 11 ... 1e 1f 10
192 * ef e0 e1 ... ee ef e0
193 * h ff f0 f1 ... fe ff f0
195 * h+1 0f 00 01 ... 0e 0f 00
197 * wrap value: 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
212 for (y
=0; y
<h
; y
++) {
220 for (y
=0; y
<h
; y
++) {
226 memcpy(back
, back
+ backline
*h
, backline
);
227 memcpy(back
+ backline
*(h
+1), back
+ backline
, backline
);
231 for (y
=0; y
<h
; y
++) {
238 memcpy(back
, back
+ backline
*h
, backline
);
239 memcpy(back
+ backline
*(h
+1), back
+ backline
, backline
);
243 for (y
=0; y
<h
; y
++) {
250 memcpy(back
+ (backline
* (h
+ 1)), back
+ backline
*h
, backline
);
251 memcpy(back
, back
+ backline
, backline
);
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;
260 if (!left
&& !right
&& !top
&& !bottom
) {
262 f
= front
- 1 - frontline
;
263 for (y
=-1; y
<=h
; y
++) {
269 p
= back
+ backline
+ 1;
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
)];
276 for (y
=0; y
<h
; y
++) {
289 cam_slide(scam
, cam
);
291 (*cam
->neighborhood
)(cam
);
292 cam
->phase
= !cam
->phase
;
294 cam_update(scam
, cam
);
296 cam_adjust(scam
, cam
);
301 cam_slide(SimCam
*scam
, Cam
*cam
)
307 int width
= cam
->width
;
308 int height
= cam
->height
;
311 int dragging
= cam
->dragging
;
318 if (cam
->set_x
>= 0) {
322 if (cam
->set_y
>= 0) {
337 } else if ((x
+ width
) > scam
->w_width
) {
338 x
= scam
->w_width
- width
;
353 printf("dagnabit\n");
355 } else if ((y
+ height
) > scam
->w_height
) {
356 y
= scam
->w_height
- height
;
368 cam
->frob
= (Rand16() & 15) * ((cam
->frob
> 0) ? -1 : 1);
374 cam
->front
->mem
= (Byte
*)scam
->data
+ x
+ (scam
->line_bytes
* y
);
375 cam
->dx
= dx
+ cam
->gx
;
376 cam
->dy
= dy
+ cam
->gy
;
378 printf("x %d y %d dx %d dy %d\n", cam
->x
, cam
->y
, cam
->dx
, cam
->dy
);
383 cam_update(SimCam
*scam
, Cam
*cam
)
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
,
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
);
398 cam_adjust(SimCam
*scam
, Cam
*cam
)
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
;
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
;
422 cam
->set_width
= cam
->set_height
=
423 cam
->set_x0
= cam
->set_y0
=
424 cam
->set_x1
= cam
->set_y1
= -1;
427 tmp
= x0
; x0
= x1
; x1
= tmp
;
431 tmp
= y0
; y0
= y1
; y1
= tmp
;
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
;
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
;
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 */
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) \
474 CAM_TABLE_LOOP(MOORE_A
)
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 */
485 #define MOORE_AB (MOORE_A | ((CENTER&12)<<8))
487 CAM_TABLE_LOOP(MOORE_AB
)
492 n_vonn_neumann(Cam
*cam
)
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 */
498 #define VON_NEUMANN ( \
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) \
506 CAM_TABLE_LOOP(VON_NEUMANN
)
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 */
519 #define MARGOLIS_ODD ( \
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))) \
532 #define MARGOLIS_EVEN ( \
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))) \
546 CAM_TABLE_LOOP(MARGOLIS_ODD
)
548 CAM_TABLE_LOOP(MARGOLIS_EVEN
)
554 n_margolis_ph(Cam
*cam
)
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 */
562 #define MARGOLIS_ODD_PH (MARGOLIS_ODD | 0x100)
563 #define MARGOLIS_EVEN_PH (MARGOLIS_EVEN | 0x200)
566 CAM_TABLE_LOOP(MARGOLIS_ODD_PH
)
568 CAM_TABLE_LOOP(MARGOLIS_EVEN_PH
)
574 n_margolis_hv(Cam
*cam
)
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 */
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))
586 CAM_TABLE_LOOP(MARGOLIS_ODD_HV
)
588 CAM_TABLE_LOOP(MARGOLIS_EVEN_HV
)
599 ((CENTER&1) ? (((s = SUM8) == 2) || (s == 3)) \
614 (((((s = CENTER)&3) == 0) && (SUM8 == 2)) ? 1 : 0) | \
625 int frob
= cam
->frob
;
628 ((QUAD)(NORTHWEST + NORTH + NORTHEAST + \
630 SOUTHWEST + SOUTH + SOUTHEAST + frob)) >> 3 \
640 int frob
= cam
->frob
;
644 last += NORTHWEST + NORTH + NORTHEAST + \
645 WEST + frob + EAST + \
646 SOUTHWEST + SOUTH + SOUTHEAST; \
647 *front = last >> 3; \
657 int frob
= cam
->frob
;
660 ((QUAD)(NORTH + WEST + EAST + SOUTH + frob)) >> 2 \
670 int frob
= cam
->frob
;
671 int last
; /* I meant to do that! */
674 ((last = (QUAD)(NORTH + WEST + EAST + SOUTH + frob \
675 + (last&0x03))), last >> 2) \
685 int frob
= cam
->frob
;
686 int lasta
= 0, lastb
= 0; /* I meant to do that! */
688 #define YUM(x) (((QUAD)(x))&0x0f)
689 #define YUK(x) (((QUAD)(x))&0xf0)
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)) \
711 int frob
= cam
->frob
;
720 int frob
= cam
->frob
;
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)) \
735 int ranch(QUAD l0
, QUAD l1
, QUAD l2
)
743 if (v
< 4 || v
== 5) {
755 #define RANCH ranch(l0, l1, l2)
767 ((s = SUM9) > 5) || (s == 4) \
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) | \
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) \
814 ((CENTER&1) ? (SUM8 != 5) \
815 : (((s = SUM8) != 5) && (s != 6))) | \
820 (((s = SUM9p(7)) > 5) || (s == 4) ? 128 : 0) | \
821 ((CENTER&128) ? ((ANTILIFE)&127) : ((BRAIN)&127)) \
832 /* 0 0 0 1 0 1 0 1 1 1 */
835 (CENTER << 1) | ((((s = SUM9) > 6) || (s == 5) || (s == 3)) ? 1 : 0) \
847 /* 0 0 0 1 0 1 0 1 1 1 */
848 /* 0 0 1 0 1 0 1 0 1 1 */
850 TORBEN | (CENTER <<1) \
861 /* 0 0 0 1 1 0 0 1 1 1 */
864 ((s = SUM9) > 6) || (s == 3) || (s == 4) \
876 /* 0 0 0 1 0 1 0 1 1 1 */
877 /* 0 0 1 0 1 0 1 0 1 1 */
879 TORBEN3 | (CENTER <<1) \
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
;
896 back
+= 1 + backline
;
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];
904 r
+= nw
+ ne
+ sw
+ sw
; r
>>= 1;
906 switch ((nw
&1) + (ne
&1) + (sw
&1) + (se
&1)) {
911 back
[0] = nw
; back
[1] = ne
;
912 back
[backline
] = sw
; back
[backline
+1] = se
;
916 back
[0] = se
; back
[1] = sw
;
917 back
[backline
] = ne
; back
[backline
+1] = nw
;
921 switch (((nw
&1) <<3) | ((ne
&1) <<2) | ((sw
&1) <<1) | (se
&1)) {
926 back
[0] = sw
; back
[1] = nw
;
927 back
[backline
] = se
; back
[backline
+1] = ne
;
929 /* counterclockwise */
930 back
[0] = ne
; back
[1] = se
;
931 back
[backline
] = nw
; back
[backline
+1] = sw
;
934 back
[0] = nw
; back
[1] = ne
;
935 back
[backline
] = sw
; back
[backline
+1] = se
;
943 back
+= backline
+ backline
- cam
->width
- (2*p
);
945 back
= cam
->back
->mem
+ backline
+ 1,
946 front
= cam
->front
->mem
;
948 for (y
= cam
->height
; y
> 0; y
--) {
949 memcpy(front
, back
, cam
->width
);
959 char p
= (cam
->phase
? 1 : 0);
961 int backline
= cam
->back
->line_bytes
,
962 frontline
= cam
->front
->line_bytes
;
964 Byte
*back
= cam
->back
->mem
,
965 *front
= cam
->front
->mem
;
967 /* bit 8 is center' */
968 /* bit 7 is center */
971 back
+= 1 + backline
;
972 front
+= 1 + frontline
;
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];
980 switch (((nw
&128) >>4) | ((ne
&128) >>5) |
981 ((sw
&128) >>6) | ((se
&128) >>7)) {
1028 tmp
= nw
; nw
= se
; se
= tmp
;
1029 tmp
= sw
; ne
= sw
; sw
= tmp
;
1034 back
+= 2; front
+= 2;
1036 back
+= backline
+ backline
- cam
->width
;
1037 front
+= frontline
+ frontline
- cam
->width
;
1040 back
= cam
->back
->mem
+ backline
+ 1,
1041 front
= cam
->front
->mem
;
1043 for (y
= cam
->height
; y
> 0; y
--) {
1044 memcpy(front
, back
, cam
->width
);
1054 #define PARTY (CENTER ^ NORTH ^ SOUTH ^ EAST ^ WEST)
1059 vf neighborhoods
[] = {
1061 &n_moore_a
, &n_moore_a
, &n_moore_ab
, &n_vonn_neumann
,
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
1075 cam_set_neighborhood(Cam
*cam
, int code
)
1077 cam
->neighborhood
= neighborhoods
[code
];
1081 cam_load_rule(Cam
*cam
, char *filename
)
1084 QUAD magic
, neighborhood
, rule_size
;
1088 if ((fp
= fopen(filename
, "r")) == NULL
) {
1089 fprintf(stderr
, "cam: Can't open rule file \"%s\"\n", filename
);
1094 #define SWAPQUAD(x) ((x = ((x <<24) & 0xff000000) | \
1095 ((x <<8) & 0x00ff0000) | \
1096 ((x >>8) & 0x0000ff00) | \
1097 ((x >>24) & 0x000000ff)), 0)
1099 /* XXX: Make this byte order independent!!! */
1100 if ((*(unsigned char*) (&test
))) {
1101 if ((fread(&magic
, 1, sizeof(QUAD
), fp
) != sizeof(QUAD
)) ||
1103 (magic
!= 0xcac0cac0) ||
1104 (fread(&neighborhood
, 1, sizeof(QUAD
), fp
) != sizeof(QUAD
)) ||
1105 SWAPQUAD(neighborhood
) ||
1106 (fread(&rule_size
, 1, sizeof(QUAD
), fp
) != sizeof(QUAD
)) ||
1107 SWAPQUAD(rule_size
) ||
1108 ((rule
= (Byte
*)malloc(rule_size
)) == NULL
) ||
1109 (fread(rule
, 1, rule_size
, fp
) != rule_size
)) {
1110 fprintf(stderr
, "cam: Bad rule file \"%s\"\n", filename
);
1115 if ((fread(&magic
, 1, sizeof(QUAD
), fp
) != sizeof(QUAD
)) ||
1116 (magic
!= 0xcac0cac0) ||
1117 (fread(&neighborhood
, 1, sizeof(QUAD
), fp
) != sizeof(QUAD
)) ||
1118 (fread(&rule_size
, 1, sizeof(QUAD
), fp
) != sizeof(QUAD
)) ||
1119 ((rule
= (Byte
*)malloc(rule_size
)) == NULL
) ||
1120 (fread(rule
, 1, rule_size
, fp
) != rule_size
)) {
1121 fprintf(stderr
, "cam: Bad rule file \"%s\"\n", filename
);
1128 if (cam
->rule
!= NULL
)
1131 cam
->rule_size
= rule_size
;
1132 cam_set_neighborhood(cam
, neighborhood
);
1137 find_cam(SimCam
*scam
, int x
, int y
)
1141 for (cam
= scam
->cam_list
; cam
!= NULL
; cam
= cam
->next
) {
1142 if ((x
>= cam
->x
) &&
1144 (x
< cam
->x
+ cam
->width
) &&
1145 (y
< cam
->y
+ cam
->height
)) {
1155 find_cam_by_name(SimCam
*scam
, char *name
)
1159 for (cam
= scam
->cam_list
; cam
!= NULL
; cam
= cam
->next
) {
1160 if ((cam
->name
!= NULL
) &&
1161 (strcmp(name
, cam
->name
) == 0)) {
1171 get_cam_number(SimCam
*scam
, int i
)
1175 for (cam
= scam
->cam_list
;
1176 (i
!= 0) && (cam
!= NULL
);
1177 (i
--), (cam
= cam
->next
)) ;
1183 cam_layout(SimCam
*scam
)
1185 int x
, y
, gap
, border
, maxwidth
, lastmax
;
1190 x
= border
; y
= border
;
1191 maxwidth
= lastmax
= gap
;
1193 for (cam
= scam
->cam_list
; cam
!= NULL
; cam
= cam
->next
) {
1194 cam
->dx
= 0; cam
->dy
= 0;
1195 if (cam
->width
> maxwidth
) {
1197 maxwidth
= cam
->width
;
1199 if (y
+ cam
->height
+ border
> scam
->w_height
) {
1200 y
= border
; x
= x
+ maxwidth
+ gap
;
1201 maxwidth
= lastmax
= gap
;
1203 if ((x
+ cam
->width
> scam
->w_width
) ||
1204 (y
+ cam
->height
> scam
->w_height
)) {
1205 cam
->x
= 0; cam
->y
= 0;
1206 cam
->front
->mem
= (Byte
*)scam
->data
;
1209 cam
->x
= x
; cam
->y
= y
;
1211 scam
->data
+ x
+ (scam
->line_bytes
* y
);
1212 y
= y
+ cam
->height
+ gap
;
1218 init_scam(SimCam
*scam
)
1220 scam_randomize(scam
);
1224 handle_scam(SimCam
*scam
)
1228 for (cam
= scam
->cam_list
; cam
!= NULL
; cam
= cam
->next
) {
1229 cam_do_rule(scam
, cam
);