1 | /* -*- Mode: C; tab-width: 4 -*- */ |
---|
2 | /* demon --- David Griffeath's cellular automata */ |
---|
3 | |
---|
4 | #if 0 |
---|
5 | static const char sccsid[] = "@(#)demon.c 5.00 2000/11/01 xlockmore"; |
---|
6 | #endif |
---|
7 | |
---|
8 | /*- |
---|
9 | * Copyright (c) 1995 by David Bagley. |
---|
10 | * |
---|
11 | * Permission to use, copy, modify, and distribute this software and its |
---|
12 | * documentation for any purpose and without fee is hereby granted, |
---|
13 | * provided that the above copyright notice appear in all copies and that |
---|
14 | * both that copyright notice and this permission notice appear in |
---|
15 | * supporting documentation. |
---|
16 | * |
---|
17 | * This file is provided AS IS with no warranties of any kind. The author |
---|
18 | * shall have no liability with respect to the infringement of copyrights, |
---|
19 | * trade secrets or any patents by this file or any part thereof. In no |
---|
20 | * event will the author be liable for any lost revenue or profits or |
---|
21 | * other special, indirect and consequential damages. |
---|
22 | * |
---|
23 | * Revision History: |
---|
24 | * 01-Nov-2000: Allocation checks |
---|
25 | * 10-May-1997: Compatible with xscreensaver |
---|
26 | * 16-Apr-1997: -neighbors 3, 9 (not sound mathematically), 12, and 8 added |
---|
27 | * 30-May-1996: Ron Hitchens <ron@idiom.com> |
---|
28 | * Fixed memory management that caused leaks |
---|
29 | * 14-Apr-1996: -neighbors 6 runtime-time option added |
---|
30 | * 21-Aug-1995: Coded from A.K. Dewdney's "Computer Recreations", Scientific |
---|
31 | * American Magazine" Aug 1989 pp 102-105. Also very similar |
---|
32 | * to hodgepodge machine described in A.K. Dewdney's "Computer |
---|
33 | * Recreations", Scientific American Magazine" Aug 1988 |
---|
34 | * pp 104-107. Also used life.c as a guide. |
---|
35 | */ |
---|
36 | |
---|
37 | /*- |
---|
38 | * A cellular universe of 4 phases debris, droplets, defects, and demons. |
---|
39 | */ |
---|
40 | |
---|
41 | /*- |
---|
42 | Grid Number of Neighbors |
---|
43 | ---- ------------------ |
---|
44 | Square 4 or 8 |
---|
45 | Hexagon 6 |
---|
46 | Triangle 3, 9, or 12 |
---|
47 | */ |
---|
48 | |
---|
49 | #ifdef STANDALONE |
---|
50 | #define MODE_demon |
---|
51 | #define PROGCLASS "Demon" |
---|
52 | #define HACK_INIT init_demon |
---|
53 | #define HACK_DRAW draw_demon |
---|
54 | #define demon_opts xlockmore_opts |
---|
55 | #define DEFAULTS "*delay: 50000 \n" \ |
---|
56 | "*count: 0 \n" \ |
---|
57 | "*cycles: 1000 \n" \ |
---|
58 | "*size: -7 \n" \ |
---|
59 | "*ncolors: 64 \n" \ |
---|
60 | "*neighbors: 0 \n" |
---|
61 | #define UNIFORM_COLORS |
---|
62 | #include "xlockmore.h" /* in xscreensaver distribution */ |
---|
63 | #else /* STANDALONE */ |
---|
64 | #include "xlock.h" /* in xlockmore distribution */ |
---|
65 | |
---|
66 | #endif /* STANDALONE */ |
---|
67 | #include "automata.h" |
---|
68 | |
---|
69 | #ifdef MODE_demon |
---|
70 | |
---|
71 | /*- |
---|
72 | * neighbors of 0 randomizes it between 3, 4, 6, 8, 9, and 12. |
---|
73 | */ |
---|
74 | #define DEF_NEIGHBORS "0" /* choose random value */ |
---|
75 | |
---|
76 | static int neighbors; |
---|
77 | |
---|
78 | static XrmOptionDescRec opts[] = |
---|
79 | { |
---|
80 | {(char *) "-neighbors", (char *) ".demon.neighbors", XrmoptionSepArg, (caddr_t) NULL} |
---|
81 | }; |
---|
82 | |
---|
83 | static argtype vars[] = |
---|
84 | { |
---|
85 | {(caddr_t *) & neighbors, (char *) "neighbors", (char *) "Neighbors", (char *) DEF_NEIGHBORS, t_Int} |
---|
86 | }; |
---|
87 | static OptionStruct desc[] = |
---|
88 | { |
---|
89 | {(char *) "-neighbors num", (char *) "squares 4 or 8, hexagons 6, triangles 3, 9 or 12"} |
---|
90 | }; |
---|
91 | |
---|
92 | ModeSpecOpt demon_opts = |
---|
93 | {sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc}; |
---|
94 | |
---|
95 | #ifdef USE_MODULES |
---|
96 | ModStruct demon_description = |
---|
97 | {"demon", "init_demon", "draw_demon", "release_demon", |
---|
98 | "refresh_demon", "init_demon", (char *) NULL, &demon_opts, |
---|
99 | 50000, 0, 1000, -7, 64, 1.0, "", |
---|
100 | "Shows Griffeath's cellular automata", 0, NULL}; |
---|
101 | |
---|
102 | #endif |
---|
103 | |
---|
104 | #define DEMONBITS(n,w,h)\ |
---|
105 | if ((dp->pixmaps[dp->init_bits]=\ |
---|
106 | XCreatePixmapFromBitmapData(display,window,(char *)n,w,h,1,0,1))==None){\ |
---|
107 | free_demon(display,dp); return;} else {dp->init_bits++;} |
---|
108 | |
---|
109 | #define REDRAWSTEP 2000 /* How many cells to draw per cycle */ |
---|
110 | #define MINSTATES 2 |
---|
111 | #define MINGRIDSIZE 24 |
---|
112 | #define MINSIZE 4 |
---|
113 | #define NEIGHBORKINDS 6 |
---|
114 | |
---|
115 | /* Singly linked list */ |
---|
116 | typedef struct _CellList { |
---|
117 | XPoint pt; |
---|
118 | struct _CellList *next; |
---|
119 | } CellList; |
---|
120 | |
---|
121 | typedef struct { |
---|
122 | int generation; |
---|
123 | int xs, ys; |
---|
124 | int xb, yb; |
---|
125 | int nrows, ncols; |
---|
126 | int width, height; |
---|
127 | int states; |
---|
128 | int state; |
---|
129 | int redrawing, redrawpos; |
---|
130 | int *ncells; |
---|
131 | CellList **cellList; |
---|
132 | unsigned char *oldcell, *newcell; |
---|
133 | int neighbors; |
---|
134 | int init_bits; |
---|
135 | GC stippledGC; |
---|
136 | Pixmap pixmaps[NUMSTIPPLES - 1]; |
---|
137 | union { |
---|
138 | XPoint hexagon[6]; |
---|
139 | XPoint triangle[2][3]; |
---|
140 | } shape; |
---|
141 | } demonstruct; |
---|
142 | |
---|
143 | static char plots[2][NEIGHBORKINDS] = |
---|
144 | { |
---|
145 | {3, 4, 6, 8, 9, 12}, /* Neighborhoods */ |
---|
146 | {12, 16, 18, 20, 22, 24} /* Number of states */ |
---|
147 | }; |
---|
148 | |
---|
149 | static demonstruct *demons = (demonstruct *) NULL; |
---|
150 | |
---|
151 | static void |
---|
152 | drawcell(ModeInfo * mi, int col, int row, unsigned char state) |
---|
153 | { |
---|
154 | demonstruct *dp = &demons[MI_SCREEN(mi)]; |
---|
155 | GC gc; |
---|
156 | |
---|
157 | if (!state) { |
---|
158 | XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_BLACK_PIXEL(mi)); |
---|
159 | gc = MI_GC(mi); |
---|
160 | } else if (MI_NPIXELS(mi) >= NUMSTIPPLES) { |
---|
161 | XSetForeground(MI_DISPLAY(mi), MI_GC(mi), |
---|
162 | MI_PIXEL(mi, (((int) state - 1) * MI_NPIXELS(mi) / |
---|
163 | (dp->states - 1)) % MI_NPIXELS(mi))); |
---|
164 | gc = MI_GC(mi); |
---|
165 | } else { |
---|
166 | XGCValues gcv; |
---|
167 | |
---|
168 | gcv.stipple = dp->pixmaps[(state - 1) % (NUMSTIPPLES - 1)]; |
---|
169 | gcv.foreground = MI_WHITE_PIXEL(mi); |
---|
170 | gcv.background = MI_BLACK_PIXEL(mi); |
---|
171 | XChangeGC(MI_DISPLAY(mi), dp->stippledGC, |
---|
172 | GCStipple | GCForeground | GCBackground, &gcv); |
---|
173 | gc = dp->stippledGC; |
---|
174 | } |
---|
175 | if (dp->neighbors == 6) { |
---|
176 | int ccol = 2 * col + !(row & 1), crow = 2 * row; |
---|
177 | |
---|
178 | dp->shape.hexagon[0].x = dp->xb + ccol * dp->xs; |
---|
179 | dp->shape.hexagon[0].y = dp->yb + crow * dp->ys; |
---|
180 | if (dp->xs == 1 && dp->ys == 1) |
---|
181 | XDrawPoint(MI_DISPLAY(mi), MI_WINDOW(mi), |
---|
182 | gc, dp->shape.hexagon[0].x, dp->shape.hexagon[0].y); |
---|
183 | else |
---|
184 | XFillPolygon(MI_DISPLAY(mi), MI_WINDOW(mi), gc, |
---|
185 | dp->shape.hexagon, 6, Convex, CoordModePrevious); |
---|
186 | } else if (dp->neighbors == 4 || dp->neighbors == 8) { |
---|
187 | XFillRectangle(MI_DISPLAY(mi), MI_WINDOW(mi), gc, |
---|
188 | dp->xb + dp->xs * col, dp->yb + dp->ys * row, |
---|
189 | dp->xs - (dp->xs > 3), dp->ys - (dp->ys > 3)); |
---|
190 | } else { /* TRI */ |
---|
191 | int orient = (col + row) % 2; /* O left 1 right */ |
---|
192 | |
---|
193 | dp->shape.triangle[orient][0].x = dp->xb + col * dp->xs; |
---|
194 | dp->shape.triangle[orient][0].y = dp->yb + row * dp->ys; |
---|
195 | if (dp->xs <= 3 || dp->ys <= 3) |
---|
196 | XDrawPoint(MI_DISPLAY(mi), MI_WINDOW(mi), gc, |
---|
197 | ((orient) ? -1 : 1) + dp->shape.triangle[orient][0].x, |
---|
198 | dp->shape.triangle[orient][0].y); |
---|
199 | else { |
---|
200 | if (orient) |
---|
201 | dp->shape.triangle[orient][0].x += (dp->xs / 2 - 1); |
---|
202 | else |
---|
203 | dp->shape.triangle[orient][0].x -= (dp->xs / 2 - 1); |
---|
204 | XFillPolygon(MI_DISPLAY(mi), MI_WINDOW(mi), gc, |
---|
205 | dp->shape.triangle[orient], 3, Convex, CoordModePrevious); |
---|
206 | |
---|
207 | } |
---|
208 | } |
---|
209 | } |
---|
210 | |
---|
211 | static Bool |
---|
212 | addtolist(ModeInfo * mi, int col, int row, unsigned char state) |
---|
213 | { |
---|
214 | demonstruct *dp = &demons[MI_SCREEN(mi)]; |
---|
215 | CellList *current; |
---|
216 | |
---|
217 | current = dp->cellList[state]; |
---|
218 | if ((dp->cellList[state] = (CellList *) |
---|
219 | malloc(sizeof (CellList))) == NULL) { |
---|
220 | return False; |
---|
221 | } |
---|
222 | dp->cellList[state]->pt.x = col; |
---|
223 | dp->cellList[state]->pt.y = row; |
---|
224 | dp->cellList[state]->next = current; |
---|
225 | dp->ncells[state]++; |
---|
226 | return True; |
---|
227 | } |
---|
228 | |
---|
229 | #ifdef DEBUG |
---|
230 | static void |
---|
231 | print_state(ModeInfo * mi, int state) |
---|
232 | { |
---|
233 | demonstruct *dp = &demons[MI_SCREEN(mi)]; |
---|
234 | CellList *locallist; |
---|
235 | int i = 0; |
---|
236 | |
---|
237 | locallist = dp->cellList[state]; |
---|
238 | (void) printf("state %d\n", state); |
---|
239 | while (locallist) { |
---|
240 | (void) printf("%d x %d, y %d\n", i, |
---|
241 | locallist->pt.x, locallist->pt.y); |
---|
242 | locallist = locallist->next; |
---|
243 | i++; |
---|
244 | } |
---|
245 | } |
---|
246 | |
---|
247 | #endif |
---|
248 | |
---|
249 | static void |
---|
250 | free_state(demonstruct * dp, int state) |
---|
251 | { |
---|
252 | CellList *current; |
---|
253 | |
---|
254 | while (dp->cellList[state]) { |
---|
255 | current = dp->cellList[state]; |
---|
256 | dp->cellList[state] = dp->cellList[state]->next; |
---|
257 | (void) free((void *) current); |
---|
258 | } |
---|
259 | dp->cellList[state] = (CellList *) NULL; |
---|
260 | if (dp->ncells != NULL) |
---|
261 | dp->ncells[state] = 0; |
---|
262 | } |
---|
263 | |
---|
264 | |
---|
265 | static void |
---|
266 | free_list(demonstruct * dp) |
---|
267 | { |
---|
268 | int state; |
---|
269 | |
---|
270 | for (state = 0; state < dp->states; state++) |
---|
271 | free_state(dp, state); |
---|
272 | (void) free((void *) dp->cellList); |
---|
273 | dp->cellList = (CellList **) NULL; |
---|
274 | } |
---|
275 | |
---|
276 | static void |
---|
277 | free_struct(demonstruct * dp) |
---|
278 | { |
---|
279 | if (dp->cellList != NULL) { |
---|
280 | free_list(dp); |
---|
281 | } |
---|
282 | if (dp->ncells != NULL) { |
---|
283 | (void) free((void *) dp->ncells); |
---|
284 | dp->ncells = (int *) NULL; |
---|
285 | } |
---|
286 | if (dp->oldcell != NULL) { |
---|
287 | (void) free((void *) dp->oldcell); |
---|
288 | dp->oldcell = (unsigned char *) NULL; |
---|
289 | } |
---|
290 | if (dp->newcell != NULL) { |
---|
291 | (void) free((void *) dp->newcell); |
---|
292 | dp->newcell = (unsigned char *) NULL; |
---|
293 | } |
---|
294 | } |
---|
295 | |
---|
296 | static void |
---|
297 | free_demon(Display *display, demonstruct *dp) |
---|
298 | { |
---|
299 | int shade; |
---|
300 | |
---|
301 | if (dp->stippledGC != None) { |
---|
302 | XFreeGC(display, dp->stippledGC); |
---|
303 | dp->stippledGC = None; |
---|
304 | } |
---|
305 | for (shade = 0; shade < dp->init_bits; shade++) { |
---|
306 | XFreePixmap(display, dp->pixmaps[shade]); |
---|
307 | } |
---|
308 | dp->init_bits = 0; |
---|
309 | free_struct(dp); |
---|
310 | } |
---|
311 | |
---|
312 | static Bool |
---|
313 | draw_state(ModeInfo * mi, int state) |
---|
314 | { |
---|
315 | demonstruct *dp = &demons[MI_SCREEN(mi)]; |
---|
316 | GC gc; |
---|
317 | XRectangle *rects; |
---|
318 | CellList *current; |
---|
319 | |
---|
320 | if (!state) { |
---|
321 | XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_BLACK_PIXEL(mi)); |
---|
322 | gc = MI_GC(mi); |
---|
323 | } else if (MI_NPIXELS(mi) >= NUMSTIPPLES) { |
---|
324 | XSetForeground(MI_DISPLAY(mi), MI_GC(mi), |
---|
325 | MI_PIXEL(mi, (((int) state - 1) * MI_NPIXELS(mi) / |
---|
326 | (dp->states - 1)) % MI_NPIXELS(mi))); |
---|
327 | gc = MI_GC(mi); |
---|
328 | } else { |
---|
329 | XGCValues gcv; |
---|
330 | |
---|
331 | gcv.stipple = dp->pixmaps[(state - 1) % (NUMSTIPPLES - 1)]; |
---|
332 | gcv.foreground = MI_WHITE_PIXEL(mi); |
---|
333 | gcv.background = MI_BLACK_PIXEL(mi); |
---|
334 | XChangeGC(MI_DISPLAY(mi), dp->stippledGC, |
---|
335 | GCStipple | GCForeground | GCBackground, &gcv); |
---|
336 | gc = dp->stippledGC; |
---|
337 | } |
---|
338 | if (dp->neighbors == 6) { /* Draw right away, slow */ |
---|
339 | current = dp->cellList[state]; |
---|
340 | while (current) { |
---|
341 | int col, row, ccol, crow; |
---|
342 | |
---|
343 | col = current->pt.x; |
---|
344 | row = current->pt.y; |
---|
345 | ccol = 2 * col + !(row & 1), crow = 2 * row; |
---|
346 | dp->shape.hexagon[0].x = dp->xb + ccol * dp->xs; |
---|
347 | dp->shape.hexagon[0].y = dp->yb + crow * dp->ys; |
---|
348 | if (dp->xs == 1 && dp->ys == 1) |
---|
349 | XDrawPoint(MI_DISPLAY(mi), MI_WINDOW(mi), |
---|
350 | gc, dp->shape.hexagon[0].x, dp->shape.hexagon[0].y); |
---|
351 | else |
---|
352 | XFillPolygon(MI_DISPLAY(mi), MI_WINDOW(mi), gc, |
---|
353 | dp->shape.hexagon, 6, Convex, CoordModePrevious); |
---|
354 | current = current->next; |
---|
355 | } |
---|
356 | } else if (dp->neighbors == 4 || dp->neighbors == 8) { |
---|
357 | /* Take advantage of XDrawRectangles */ |
---|
358 | int ncells = 0; |
---|
359 | |
---|
360 | /* Create Rectangle list from part of the cellList */ |
---|
361 | if ((rects = (XRectangle *) malloc(dp->ncells[state] * |
---|
362 | sizeof (XRectangle))) == NULL) { |
---|
363 | return False; |
---|
364 | } |
---|
365 | current = dp->cellList[state]; |
---|
366 | while (current) { |
---|
367 | rects[ncells].x = dp->xb + current->pt.x * dp->xs; |
---|
368 | rects[ncells].y = dp->yb + current->pt.y * dp->ys; |
---|
369 | rects[ncells].width = dp->xs - (dp->xs > 3); |
---|
370 | rects[ncells].height = dp->ys - (dp->ys > 3); |
---|
371 | current = current->next; |
---|
372 | ncells++; |
---|
373 | } |
---|
374 | /* Finally get to draw */ |
---|
375 | XFillRectangles(MI_DISPLAY(mi), MI_WINDOW(mi), gc, rects, ncells); |
---|
376 | /* Free up rects list and the appropriate part of the cellList */ |
---|
377 | (void) free((void *) rects); |
---|
378 | } else { /* TRI */ |
---|
379 | current = dp->cellList[state]; |
---|
380 | while (current) { |
---|
381 | int col, row, orient; |
---|
382 | |
---|
383 | col = current->pt.x; |
---|
384 | row = current->pt.y; |
---|
385 | orient = (col + row) % 2; /* O left 1 right */ |
---|
386 | dp->shape.triangle[orient][0].x = dp->xb + col * dp->xs; |
---|
387 | dp->shape.triangle[orient][0].y = dp->yb + row * dp->ys; |
---|
388 | if (dp->xs <= 3 || dp->ys <= 3) |
---|
389 | XDrawPoint(MI_DISPLAY(mi), MI_WINDOW(mi), gc, |
---|
390 | ((orient) ? -1 : 1) + dp->shape.triangle[orient][0].x, |
---|
391 | dp->shape.triangle[orient][0].y); |
---|
392 | else { |
---|
393 | if (orient) |
---|
394 | dp->shape.triangle[orient][0].x += (dp->xs / 2 - 1); |
---|
395 | else |
---|
396 | dp->shape.triangle[orient][0].x -= (dp->xs / 2 - 1); |
---|
397 | XFillPolygon(MI_DISPLAY(mi), MI_WINDOW(mi), gc, |
---|
398 | dp->shape.triangle[orient], 3, Convex, CoordModePrevious); |
---|
399 | } |
---|
400 | current = current->next; |
---|
401 | } |
---|
402 | } |
---|
403 | free_state(dp, state); |
---|
404 | XFlush(MI_DISPLAY(mi)); |
---|
405 | return True; |
---|
406 | } |
---|
407 | |
---|
408 | static void |
---|
409 | RandomSoup(ModeInfo * mi) |
---|
410 | { |
---|
411 | demonstruct *dp = &demons[MI_SCREEN(mi)]; |
---|
412 | int row, col, mrow = 0; |
---|
413 | |
---|
414 | for (row = 0; row < dp->nrows; ++row) { |
---|
415 | for (col = 0; col < dp->ncols; ++col) { |
---|
416 | dp->oldcell[col + mrow] = |
---|
417 | (unsigned char) LRAND() % ((unsigned char) dp->states); |
---|
418 | if (!addtolist(mi, col, row, dp->oldcell[col + mrow])) |
---|
419 | return; /* sparse soup */ |
---|
420 | } |
---|
421 | mrow += dp->ncols; |
---|
422 | } |
---|
423 | } |
---|
424 | |
---|
425 | void |
---|
426 | init_demon(ModeInfo * mi) |
---|
427 | { |
---|
428 | Display *display = MI_DISPLAY(mi); |
---|
429 | Window window = MI_WINDOW(mi); |
---|
430 | int size = MI_SIZE(mi), nk; |
---|
431 | demonstruct *dp; |
---|
432 | |
---|
433 | if (demons == NULL) { |
---|
434 | if ((demons = (demonstruct *) calloc(MI_NUM_SCREENS(mi), |
---|
435 | sizeof (demonstruct))) == NULL) |
---|
436 | return; |
---|
437 | } |
---|
438 | dp = &demons[MI_SCREEN(mi)]; |
---|
439 | |
---|
440 | dp->generation = 0; |
---|
441 | dp->redrawing = 0; |
---|
442 | if (MI_NPIXELS(mi) < NUMSTIPPLES) { |
---|
443 | if (dp->stippledGC == None) { |
---|
444 | XGCValues gcv; |
---|
445 | |
---|
446 | gcv.fill_style = FillOpaqueStippled; |
---|
447 | if ((dp->stippledGC = XCreateGC(display, window, |
---|
448 | GCFillStyle, &gcv)) == None) { |
---|
449 | free_demon(display, dp); |
---|
450 | return; |
---|
451 | } |
---|
452 | } |
---|
453 | if (dp->init_bits == 0) { |
---|
454 | int i; |
---|
455 | |
---|
456 | for (i = 1; i < NUMSTIPPLES; i++) { |
---|
457 | DEMONBITS(stipples[i], STIPPLESIZE, STIPPLESIZE); |
---|
458 | } |
---|
459 | } |
---|
460 | } |
---|
461 | free_struct(dp); |
---|
462 | |
---|
463 | for (nk = 0; nk < NEIGHBORKINDS; nk++) { |
---|
464 | if (neighbors == plots[0][nk]) { |
---|
465 | dp->neighbors = plots[0][nk]; |
---|
466 | break; |
---|
467 | } |
---|
468 | if (nk == NEIGHBORKINDS - 1) { |
---|
469 | nk = NRAND(NEIGHBORKINDS); |
---|
470 | dp->neighbors = plots[0][nk]; |
---|
471 | break; |
---|
472 | } |
---|
473 | } |
---|
474 | |
---|
475 | dp->states = MI_COUNT(mi); |
---|
476 | if (dp->states < -MINSTATES) |
---|
477 | dp->states = NRAND(-dp->states - MINSTATES + 1) + MINSTATES; |
---|
478 | else if (dp->states < MINSTATES) |
---|
479 | dp->states = plots[1][nk]; |
---|
480 | if ((dp->cellList = (CellList **) calloc(dp->states, |
---|
481 | sizeof (CellList *))) == NULL) { |
---|
482 | free_demon(display, dp); |
---|
483 | return; |
---|
484 | } |
---|
485 | if ((dp->ncells = (int *) calloc(dp->states, sizeof (int))) == NULL) { |
---|
486 | free_demon(display, dp); |
---|
487 | return; |
---|
488 | } |
---|
489 | |
---|
490 | dp->state = 0; |
---|
491 | |
---|
492 | dp->width = MI_WIDTH(mi); |
---|
493 | dp->height = MI_HEIGHT(mi); |
---|
494 | |
---|
495 | if (dp->neighbors == 6) { |
---|
496 | int nccols, ncrows, i; |
---|
497 | |
---|
498 | if (dp->width < 8) |
---|
499 | dp->width = 8; |
---|
500 | if (dp->height < 8) |
---|
501 | dp->height = 8; |
---|
502 | if (size < -MINSIZE) |
---|
503 | dp->ys = NRAND(MIN(-size, MAX(MINSIZE, MIN(dp->width, dp->height) / |
---|
504 | MINGRIDSIZE)) - MINSIZE + 1) + MINSIZE; |
---|
505 | else if (size < MINSIZE) { |
---|
506 | if (!size) |
---|
507 | dp->ys = MAX(MINSIZE, MIN(dp->width, dp->height) / MINGRIDSIZE); |
---|
508 | else |
---|
509 | dp->ys = MINSIZE; |
---|
510 | } else |
---|
511 | dp->ys = MIN(size, MAX(MINSIZE, MIN(dp->width, dp->height) / |
---|
512 | MINGRIDSIZE)); |
---|
513 | dp->xs = dp->ys; |
---|
514 | nccols = MAX(dp->width / dp->xs - 2, 2); |
---|
515 | ncrows = MAX(dp->height / dp->ys - 1, 4); |
---|
516 | dp->ncols = nccols / 2; |
---|
517 | dp->nrows = 2 * (ncrows / 4); |
---|
518 | dp->xb = (dp->width - dp->xs * nccols) / 2 + dp->xs / 2; |
---|
519 | dp->yb = (dp->height - dp->ys * (ncrows / 2) * 2) / 2 + dp->ys - 2; |
---|
520 | for (i = 0; i < 6; i++) { |
---|
521 | dp->shape.hexagon[i].x = (dp->xs - 1) * hexagonUnit[i].x; |
---|
522 | dp->shape.hexagon[i].y = ((dp->ys - 1) * hexagonUnit[i].y / 2) * 4 / 3; |
---|
523 | } |
---|
524 | } else if (dp->neighbors == 4 || dp->neighbors == 8) { |
---|
525 | if (size < -MINSIZE) |
---|
526 | dp->ys = NRAND(MIN(-size, MAX(MINSIZE, MIN(dp->width, dp->height) / |
---|
527 | MINGRIDSIZE)) - MINSIZE + 1) + MINSIZE; |
---|
528 | else if (size < MINSIZE) { |
---|
529 | if (!size) |
---|
530 | dp->ys = MAX(MINSIZE, MIN(dp->width, dp->height) / MINGRIDSIZE); |
---|
531 | else |
---|
532 | dp->ys = MINSIZE; |
---|
533 | } else |
---|
534 | dp->ys = MIN(size, MAX(MINSIZE, MIN(dp->width, dp->height) / |
---|
535 | MINGRIDSIZE)); |
---|
536 | dp->xs = dp->ys; |
---|
537 | dp->ncols = MAX(dp->width / dp->xs, 2); |
---|
538 | dp->nrows = MAX(dp->height / dp->ys, 2); |
---|
539 | dp->xb = (dp->width - dp->xs * dp->ncols) / 2; |
---|
540 | dp->yb = (dp->height - dp->ys * dp->nrows) / 2; |
---|
541 | } else { /* TRI */ |
---|
542 | int orient, i; |
---|
543 | |
---|
544 | if (dp->width < 2) |
---|
545 | dp->width = 2; |
---|
546 | if (dp->height < 2) |
---|
547 | dp->height = 2; |
---|
548 | if (size < -MINSIZE) |
---|
549 | dp->ys = NRAND(MIN(-size, MAX(MINSIZE, MIN(dp->width, dp->height) / |
---|
550 | MINGRIDSIZE)) - MINSIZE + 1) + MINSIZE; |
---|
551 | else if (size < MINSIZE) { |
---|
552 | if (!size) |
---|
553 | dp->ys = MAX(MINSIZE, MIN(dp->width, dp->height) / MINGRIDSIZE); |
---|
554 | else |
---|
555 | dp->ys = MINSIZE; |
---|
556 | } else |
---|
557 | dp->ys = MIN(size, MAX(MINSIZE, MIN(dp->width, dp->height) / |
---|
558 | MINGRIDSIZE)); |
---|
559 | dp->xs = (int) (1.52 * dp->ys); |
---|
560 | dp->ncols = (MAX(dp->width / dp->xs - 1, 2) / 2) * 2; |
---|
561 | dp->nrows = (MAX(dp->height / dp->ys - 1, 2) / 2) * 2; |
---|
562 | dp->xb = (dp->width - dp->xs * dp->ncols) / 2 + dp->xs / 2; |
---|
563 | dp->yb = (dp->height - dp->ys * dp->nrows) / 2 + dp->ys / 2; |
---|
564 | for (orient = 0; orient < 2; orient++) { |
---|
565 | for (i = 0; i < 3; i++) { |
---|
566 | dp->shape.triangle[orient][i].x = |
---|
567 | (dp->xs - 2) * triangleUnit[orient][i].x; |
---|
568 | dp->shape.triangle[orient][i].y = |
---|
569 | (dp->ys - 2) * triangleUnit[orient][i].y; |
---|
570 | } |
---|
571 | } |
---|
572 | } |
---|
573 | |
---|
574 | MI_CLEARWINDOW(mi); |
---|
575 | |
---|
576 | if ((dp->oldcell = (unsigned char *) |
---|
577 | malloc(dp->ncols * dp->nrows * sizeof (unsigned char))) == NULL) { |
---|
578 | free_demon(display, dp); |
---|
579 | return; |
---|
580 | } |
---|
581 | |
---|
582 | if ((dp->newcell = (unsigned char *) |
---|
583 | malloc(dp->ncols * dp->nrows * sizeof (unsigned char))) == NULL) { |
---|
584 | free_demon(display, dp); |
---|
585 | return; |
---|
586 | } |
---|
587 | |
---|
588 | RandomSoup(mi); |
---|
589 | } |
---|
590 | |
---|
591 | void |
---|
592 | draw_demon(ModeInfo * mi) |
---|
593 | { |
---|
594 | int i, j, k, l, mj = 0, ml; |
---|
595 | demonstruct *dp; |
---|
596 | |
---|
597 | if (demons == NULL) |
---|
598 | return; |
---|
599 | dp = &demons[MI_SCREEN(mi)]; |
---|
600 | if (dp->cellList == NULL) |
---|
601 | return; |
---|
602 | |
---|
603 | MI_IS_DRAWN(mi) = True; |
---|
604 | if (dp->state >= dp->states) { |
---|
605 | (void) memcpy((char *) dp->newcell, (char *) dp->oldcell, |
---|
606 | dp->ncols * dp->nrows * sizeof (unsigned char)); |
---|
607 | |
---|
608 | if (dp->neighbors == 6) { |
---|
609 | for (j = 0; j < dp->nrows; j++) { |
---|
610 | for (i = 0; i < dp->ncols; i++) { |
---|
611 | /* NE */ |
---|
612 | if (!(j & 1)) |
---|
613 | k = (i + 1 == dp->ncols) ? 0 : i + 1; |
---|
614 | else |
---|
615 | k = i; |
---|
616 | l = (!j) ? dp->nrows - 1 : j - 1; |
---|
617 | ml = l * dp->ncols; |
---|
618 | if (dp->oldcell[k + ml] == |
---|
619 | (int) (dp->oldcell[i + mj] + 1) % dp->states) |
---|
620 | dp->newcell[i + mj] = dp->oldcell[k + ml]; |
---|
621 | /* E */ |
---|
622 | k = (i + 1 == dp->ncols) ? 0 : i + 1; |
---|
623 | ml = mj; |
---|
624 | if (dp->oldcell[k + ml] == |
---|
625 | (int) (dp->oldcell[i + mj] + 1) % dp->states) |
---|
626 | dp->newcell[i + mj] = dp->oldcell[k + ml]; |
---|
627 | /* SE */ |
---|
628 | if (!(j & 1)) |
---|
629 | k = (i + 1 == dp->ncols) ? 0 : i + 1; |
---|
630 | else |
---|
631 | k = i; |
---|
632 | l = (j + 1 == dp->nrows) ? 0 : j + 1; |
---|
633 | ml = l * dp->ncols; |
---|
634 | if (dp->oldcell[k + ml] == |
---|
635 | (int) (dp->oldcell[i + mj] + 1) % dp->states) |
---|
636 | dp->newcell[i + mj] = dp->oldcell[k + ml]; |
---|
637 | /* SW */ |
---|
638 | if (j & 1) |
---|
639 | k = (!i) ? dp->ncols - 1 : i - 1; |
---|
640 | else |
---|
641 | k = i; |
---|
642 | l = (j + 1 == dp->nrows) ? 0 : j + 1; |
---|
643 | ml = l * dp->ncols; |
---|
644 | if (dp->oldcell[k + ml] == |
---|
645 | (int) (dp->oldcell[i + mj] + 1) % dp->states) |
---|
646 | dp->newcell[i + mj] = dp->oldcell[k + ml]; |
---|
647 | /* W */ |
---|
648 | k = (!i) ? dp->ncols - 1 : i - 1; |
---|
649 | ml = mj; |
---|
650 | if (dp->oldcell[k + ml] == |
---|
651 | (int) (dp->oldcell[i + mj] + 1) % dp->states) |
---|
652 | dp->newcell[i + mj] = dp->oldcell[k + ml]; |
---|
653 | /* NW */ |
---|
654 | if (j & 1) |
---|
655 | k = (!i) ? dp->ncols - 1 : i - 1; |
---|
656 | else |
---|
657 | k = i; |
---|
658 | l = (!j) ? dp->nrows - 1 : j - 1; |
---|
659 | ml = l * dp->ncols; |
---|
660 | if (dp->oldcell[k + ml] == |
---|
661 | (int) (dp->oldcell[i + mj] + 1) % dp->states) |
---|
662 | dp->newcell[i + mj] = dp->oldcell[k + ml]; |
---|
663 | } |
---|
664 | mj += dp->ncols; |
---|
665 | } |
---|
666 | } else if (dp->neighbors == 4 || dp->neighbors == 8) { |
---|
667 | for (j = 0; j < dp->nrows; j++) { |
---|
668 | for (i = 0; i < dp->ncols; i++) { |
---|
669 | /* N */ |
---|
670 | k = i; |
---|
671 | l = (!j) ? dp->nrows - 1 : j - 1; |
---|
672 | ml = l * dp->ncols; |
---|
673 | if (dp->oldcell[k + ml] == |
---|
674 | (int) (dp->oldcell[i + mj] + 1) % dp->states) |
---|
675 | dp->newcell[i + mj] = dp->oldcell[k + ml]; |
---|
676 | /* E */ |
---|
677 | k = (i + 1 == dp->ncols) ? 0 : i + 1; |
---|
678 | ml = mj; |
---|
679 | if (dp->oldcell[k + ml] == |
---|
680 | (int) (dp->oldcell[i + mj] + 1) % dp->states) |
---|
681 | dp->newcell[i + mj] = dp->oldcell[k + ml]; |
---|
682 | /* S */ |
---|
683 | k = i; |
---|
684 | l = (j + 1 == dp->nrows) ? 0 : j + 1; |
---|
685 | ml = l * dp->ncols; |
---|
686 | if (dp->oldcell[k + ml] == |
---|
687 | (int) (dp->oldcell[i + mj] + 1) % dp->states) |
---|
688 | dp->newcell[i + mj] = dp->oldcell[k + ml]; |
---|
689 | /* W */ |
---|
690 | k = (!i) ? dp->ncols - 1 : i - 1; |
---|
691 | l = j; |
---|
692 | ml = mj; |
---|
693 | if (dp->oldcell[k + ml] == |
---|
694 | (int) (dp->oldcell[i + mj] + 1) % dp->states) |
---|
695 | dp->newcell[i + mj] = dp->oldcell[k + ml]; |
---|
696 | } |
---|
697 | mj += dp->ncols; |
---|
698 | } |
---|
699 | if (dp->neighbors == 8) { |
---|
700 | mj = 0; |
---|
701 | for (j = 0; j < dp->nrows; j++) { |
---|
702 | for (i = 0; i < dp->ncols; i++) { |
---|
703 | /* NE */ |
---|
704 | k = (i + 1 == dp->ncols) ? 0 : i + 1; |
---|
705 | l = (!j) ? dp->nrows - 1 : j - 1; |
---|
706 | ml = l * dp->ncols; |
---|
707 | if (dp->oldcell[k + ml] == |
---|
708 | (int) (dp->oldcell[i + mj] + 1) % dp->states) |
---|
709 | dp->newcell[i + mj] = dp->oldcell[k + ml]; |
---|
710 | /* SE */ |
---|
711 | k = (i + 1 == dp->ncols) ? 0 : i + 1; |
---|
712 | l = (j + 1 == dp->nrows) ? 0 : j + 1; |
---|
713 | ml = l * dp->ncols; |
---|
714 | if (dp->oldcell[k + ml] == |
---|
715 | (int) (dp->oldcell[i + mj] + 1) % dp->states) |
---|
716 | dp->newcell[i + mj] = dp->oldcell[k + ml]; |
---|
717 | /* SW */ |
---|
718 | k = (!i) ? dp->ncols - 1 : i - 1; |
---|
719 | l = (j + 1 == dp->nrows) ? 0 : j + 1; |
---|
720 | ml = l * dp->ncols; |
---|
721 | if (dp->oldcell[k + ml] == |
---|
722 | (int) (dp->oldcell[i + mj] + 1) % dp->states) |
---|
723 | dp->newcell[i + mj] = dp->oldcell[k + ml]; |
---|
724 | /* NW */ |
---|
725 | k = (!i) ? dp->ncols - 1 : i - 1; |
---|
726 | l = (!j) ? dp->nrows - 1 : j - 1; |
---|
727 | ml = l * dp->ncols; |
---|
728 | if (dp->oldcell[k + ml] == |
---|
729 | (int) (dp->oldcell[i + mj] + 1) % dp->states) |
---|
730 | dp->newcell[i + mj] = dp->oldcell[k + ml]; |
---|
731 | } |
---|
732 | mj += dp->ncols; |
---|
733 | } |
---|
734 | } |
---|
735 | } else if (dp->neighbors == 3 || dp->neighbors == 9 || |
---|
736 | dp->neighbors == 12) { |
---|
737 | for (j = 0; j < dp->nrows; j++) { |
---|
738 | for (i = 0; i < dp->ncols; i++) { |
---|
739 | if ((i + j) % 2) { /* right */ |
---|
740 | /* W */ |
---|
741 | k = (!i) ? dp->ncols - 1 : i - 1; |
---|
742 | ml = mj; |
---|
743 | if (dp->oldcell[k + ml] == |
---|
744 | (int) (dp->oldcell[i + mj] + 1) % dp->states) |
---|
745 | dp->newcell[i + mj] = dp->oldcell[k + ml]; |
---|
746 | } else { /* left */ |
---|
747 | /* E */ |
---|
748 | k = (i + 1 == dp->ncols) ? 0 : i + 1; |
---|
749 | ml = mj; |
---|
750 | if (dp->oldcell[k + ml] == |
---|
751 | (int) (dp->oldcell[i + mj] + 1) % dp->states) |
---|
752 | dp->newcell[i + mj] = dp->oldcell[k + ml]; |
---|
753 | } |
---|
754 | /* N */ |
---|
755 | k = i; |
---|
756 | l = (!j) ? dp->nrows - 1 : j - 1; |
---|
757 | ml = l * dp->ncols; |
---|
758 | if (dp->oldcell[k + ml] == |
---|
759 | (int) (dp->oldcell[i + mj] + 1) % dp->states) |
---|
760 | dp->newcell[i + mj] = dp->oldcell[k + ml]; |
---|
761 | /* S */ |
---|
762 | k = i; |
---|
763 | l = (j + 1 == dp->nrows) ? 0 : j + 1; |
---|
764 | ml = l * dp->ncols; |
---|
765 | if (dp->oldcell[k + ml] == |
---|
766 | (int) (dp->oldcell[i + mj] + 1) % dp->states) |
---|
767 | dp->newcell[i + mj] = dp->oldcell[k + ml]; |
---|
768 | } |
---|
769 | mj += dp->ncols; |
---|
770 | } |
---|
771 | if (dp->neighbors == 9 || dp->neighbors == 12) { |
---|
772 | mj = 0; |
---|
773 | for (j = 0; j < dp->nrows; j++) { |
---|
774 | for (i = 0; i < dp->ncols; i++) { |
---|
775 | /* NN */ |
---|
776 | k = i; |
---|
777 | if (!j) |
---|
778 | l = dp->nrows - 2; |
---|
779 | else if (!(j - 1)) |
---|
780 | l = dp->nrows - 1; |
---|
781 | else |
---|
782 | l = j - 2; |
---|
783 | ml = l * dp->ncols; |
---|
784 | if (dp->oldcell[k + ml] == |
---|
785 | (int) (dp->oldcell[i + mj] + 1) % dp->states) |
---|
786 | dp->newcell[i + mj] = dp->oldcell[k + ml]; |
---|
787 | /* SS */ |
---|
788 | k = i; |
---|
789 | if (j + 1 == dp->nrows) |
---|
790 | l = 1; |
---|
791 | else if (j + 2 == dp->nrows) |
---|
792 | l = 0; |
---|
793 | else |
---|
794 | l = j + 2; |
---|
795 | ml = l * dp->ncols; |
---|
796 | if (dp->oldcell[k + ml] == |
---|
797 | (int) (dp->oldcell[i + mj] + 1) % dp->states) |
---|
798 | dp->newcell[i + mj] = dp->oldcell[k + ml]; |
---|
799 | /* NW */ |
---|
800 | k = (!i) ? dp->ncols - 1 : i - 1; |
---|
801 | l = (!j) ? dp->nrows - 1 : j - 1; |
---|
802 | ml = l * dp->ncols; |
---|
803 | if (dp->oldcell[k + ml] == |
---|
804 | (int) (dp->oldcell[i + mj] + 1) % dp->states) |
---|
805 | dp->newcell[i + mj] = dp->oldcell[k + ml]; |
---|
806 | /* NE */ |
---|
807 | k = (i + 1 == dp->ncols) ? 0 : i + 1; |
---|
808 | l = (!j) ? dp->nrows - 1 : j - 1; |
---|
809 | ml = l * dp->ncols; |
---|
810 | if (dp->oldcell[k + ml] == |
---|
811 | (int) (dp->oldcell[i + mj] + 1) % dp->states) |
---|
812 | dp->newcell[i + mj] = dp->oldcell[k + ml]; |
---|
813 | /* SW */ |
---|
814 | k = (!i) ? dp->ncols - 1 : i - 1; |
---|
815 | l = (j + 1 == dp->nrows) ? 0 : j + 1; |
---|
816 | ml = l * dp->ncols; |
---|
817 | if (dp->oldcell[k + ml] == |
---|
818 | (int) (dp->oldcell[i + mj] + 1) % dp->states) |
---|
819 | dp->newcell[i + mj] = dp->oldcell[k + ml]; |
---|
820 | /* SE */ |
---|
821 | k = (i + 1 == dp->ncols) ? 0 : i + 1; |
---|
822 | l = (j + 1 == dp->nrows) ? 0 : j + 1; |
---|
823 | ml = l * dp->ncols; |
---|
824 | if (dp->oldcell[k + ml] == |
---|
825 | (int) (dp->oldcell[i + mj] + 1) % dp->states) |
---|
826 | dp->newcell[i + mj] = dp->oldcell[k + ml]; |
---|
827 | } |
---|
828 | mj += dp->ncols; |
---|
829 | } |
---|
830 | if (dp->neighbors == 12) { |
---|
831 | mj = 0; |
---|
832 | for (j = 0; j < dp->nrows; j++) { |
---|
833 | for (i = 0; i < dp->ncols; i++) { |
---|
834 | if ((i + j) % 2) { /* right */ |
---|
835 | /* NNW */ |
---|
836 | k = (!i) ? dp->ncols - 1 : i - 1; |
---|
837 | if (!j) |
---|
838 | l = dp->nrows - 2; |
---|
839 | else if (!(j - 1)) |
---|
840 | l = dp->nrows - 1; |
---|
841 | else |
---|
842 | l = j - 2; |
---|
843 | ml = l * dp->ncols; |
---|
844 | if (dp->oldcell[k + ml] == |
---|
845 | (int) (dp->oldcell[i + mj] + 1) % dp->states) |
---|
846 | dp->newcell[i + mj] = dp->oldcell[k + ml]; |
---|
847 | /* SSW */ |
---|
848 | k = (!i) ? dp->ncols - 1 : i - 1; |
---|
849 | if (j + 1 == dp->nrows) |
---|
850 | l = 1; |
---|
851 | else if (j + 2 == dp->nrows) |
---|
852 | l = 0; |
---|
853 | else |
---|
854 | l = j + 2; |
---|
855 | ml = l * dp->ncols; |
---|
856 | if (dp->oldcell[k + ml] == |
---|
857 | (int) (dp->oldcell[i + mj] + 1) % dp->states) |
---|
858 | dp->newcell[i + mj] = dp->oldcell[k + ml]; |
---|
859 | /* EE */ |
---|
860 | k = (i + 1 == dp->ncols) ? 0 : i + 1; |
---|
861 | l = j; |
---|
862 | ml = mj; |
---|
863 | if (dp->oldcell[k + ml] == |
---|
864 | (int) (dp->oldcell[i + mj] + 1) % dp->states) |
---|
865 | dp->newcell[i + mj] = dp->oldcell[k + ml]; |
---|
866 | } else { /* left */ |
---|
867 | /* NNE */ |
---|
868 | k = (i + 1 == dp->ncols) ? 0 : i + 1; |
---|
869 | if (!j) |
---|
870 | l = dp->nrows - 2; |
---|
871 | else if (!(j - 1)) |
---|
872 | l = dp->nrows - 1; |
---|
873 | else |
---|
874 | l = j - 2; |
---|
875 | ml = l * dp->ncols; |
---|
876 | if (dp->oldcell[k + ml] == |
---|
877 | (int) (dp->oldcell[i + mj] + 1) % dp->states) |
---|
878 | dp->newcell[i + mj] = dp->oldcell[k + ml]; |
---|
879 | /* SSE */ |
---|
880 | k = (i + 1 == dp->ncols) ? 0 : i + 1; |
---|
881 | if (j + 1 == dp->nrows) |
---|
882 | l = 1; |
---|
883 | else if (j + 2 == dp->nrows) |
---|
884 | l = 0; |
---|
885 | else |
---|
886 | l = j + 2; |
---|
887 | ml = l * dp->ncols; |
---|
888 | if (dp->oldcell[k + ml] == |
---|
889 | (int) (dp->oldcell[i + mj] + 1) % dp->states) |
---|
890 | dp->newcell[i + mj] = dp->oldcell[k + ml]; |
---|
891 | /* WW */ |
---|
892 | k = (!i) ? dp->ncols - 1 : i - 1; |
---|
893 | l = j; |
---|
894 | ml = mj; |
---|
895 | if (dp->oldcell[k + ml] == |
---|
896 | (int) (dp->oldcell[i + mj] + 1) % dp->states) |
---|
897 | dp->newcell[i + mj] = dp->oldcell[k + ml]; |
---|
898 | } |
---|
899 | } |
---|
900 | mj += dp->ncols; |
---|
901 | } |
---|
902 | } |
---|
903 | } |
---|
904 | } |
---|
905 | mj = 0; |
---|
906 | for (j = 0; j < dp->nrows; j++) { |
---|
907 | for (i = 0; i < dp->ncols; i++) |
---|
908 | if (dp->oldcell[i + mj] != dp->newcell[i + mj]) { |
---|
909 | dp->oldcell[i + mj] = dp->newcell[i + mj]; |
---|
910 | if (!addtolist(mi, i, j, dp->oldcell[i + mj])) { |
---|
911 | free_demon(MI_DISPLAY(mi), dp); |
---|
912 | return; |
---|
913 | } |
---|
914 | } |
---|
915 | mj += dp->ncols; |
---|
916 | } |
---|
917 | if (++dp->generation > MI_CYCLES(mi)) |
---|
918 | init_demon(mi); |
---|
919 | dp->state = 0; |
---|
920 | } else { |
---|
921 | if (dp->ncells[dp->state]) |
---|
922 | if (!draw_state(mi, dp->state)) { |
---|
923 | free_demon(MI_DISPLAY(mi), dp); |
---|
924 | return; |
---|
925 | } |
---|
926 | dp->state++; |
---|
927 | } |
---|
928 | if (dp->redrawing) { |
---|
929 | for (i = 0; i < REDRAWSTEP; i++) { |
---|
930 | if (dp->oldcell[dp->redrawpos]) { |
---|
931 | drawcell(mi, dp->redrawpos % dp->ncols, dp->redrawpos / dp->ncols, |
---|
932 | dp->oldcell[dp->redrawpos]); |
---|
933 | } |
---|
934 | if (++(dp->redrawpos) >= dp->ncols * dp->nrows) { |
---|
935 | dp->redrawing = 0; |
---|
936 | break; |
---|
937 | } |
---|
938 | } |
---|
939 | } |
---|
940 | } |
---|
941 | void |
---|
942 | release_demon(ModeInfo * mi) |
---|
943 | { |
---|
944 | if (demons != NULL) { |
---|
945 | int screen; |
---|
946 | |
---|
947 | for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) |
---|
948 | free_demon(MI_DISPLAY(mi), &demons[screen]); |
---|
949 | (void) free((void *) demons); |
---|
950 | demons = (demonstruct *) NULL; |
---|
951 | } |
---|
952 | } |
---|
953 | |
---|
954 | void |
---|
955 | refresh_demon(ModeInfo * mi) |
---|
956 | { |
---|
957 | demonstruct *dp; |
---|
958 | |
---|
959 | if (demons == NULL) |
---|
960 | return; |
---|
961 | dp = &demons[MI_SCREEN(mi)]; |
---|
962 | |
---|
963 | dp->redrawing = 1; |
---|
964 | dp->redrawpos = 0; |
---|
965 | } |
---|
966 | |
---|
967 | #endif /* MODE_demon */ |
---|