worm.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* $XConsortium: worm.c /main/3 1995/11/02 16:09:04 rswiston $ */
  24. /*
  25. */
  26. /* *
  27. * (c) Copyright 1993, 1994 Hewlett-Packard Company *
  28. * (c) Copyright 1993, 1994 International Business Machines Corp. *
  29. * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
  30. * (c) Copyright 1993, 1994 Novell, Inc. *
  31. */
  32. /*-
  33. * worm.c - draw wiggly worms.
  34. *
  35. * Copyright (c) 1991 by Patrick J. Naughton.
  36. *
  37. * See dtscreen.c for copying information.
  38. *
  39. * Revision History:
  40. * 27-Sep-91: got rid of all malloc calls since there were no calls to free().
  41. * 25-Sep-91: Integrated into X11R5 contrib dtscreen.
  42. *
  43. * Adapted from a concept in the Dec 87 issue of Scientific American.
  44. *
  45. * SunView version: Brad Taylor (brad@sun.com)
  46. * X11 version: Dave Lemke (lemke@ncd.com)
  47. * xlock version: Boris Putanec (bp@cs.brown.edu)
  48. *
  49. * This code is a static memory pig... like almost 200K... but as contributed
  50. * it leaked at a massive rate, so I made everything static up front... feel
  51. * free to contribute the proper memory management code.
  52. *
  53. */
  54. #include "dtscreen.h"
  55. #include <math.h>
  56. #include <stdlib.h>
  57. #define MAXCOLORS 64
  58. #define MAXWORMS 64
  59. #define CIRCSIZE 2
  60. #define MAXWORMLEN 50
  61. #define PI 3.14159265358979323844
  62. #define SEGMENTS 36
  63. static int sintab[SEGMENTS];
  64. static int costab[SEGMENTS];
  65. static int init_table = 0;
  66. typedef struct {
  67. int xcirc[MAXWORMLEN];
  68. int ycirc[MAXWORMLEN];
  69. int dir;
  70. int tail;
  71. int x;
  72. int y;
  73. } wormstuff;
  74. typedef struct {
  75. int xsize;
  76. int ysize;
  77. int wormlength;
  78. int monopix;
  79. int nc;
  80. int nw;
  81. wormstuff worm[MAXWORMS];
  82. XRectangle rects[MAXCOLORS][MAXWORMS];
  83. int size[MAXCOLORS];
  84. } wormstruct;
  85. #if !defined(CSRG_BASED) && !defined(sun) && !defined(__linux__)
  86. int
  87. round(float x)
  88. {
  89. return ((int) floor((double) x));
  90. }
  91. #endif
  92. void
  93. worm_doit(perwindow *pwin, wormstruct *wp, int which, unsigned long color)
  94. {
  95. wormstuff *ws = &wp->worm[which];
  96. int x, y;
  97. ws->tail++;
  98. if (ws->tail == wp->wormlength)
  99. ws->tail = 0;
  100. x = ws->xcirc[ws->tail];
  101. y = ws->ycirc[ws->tail];
  102. XClearArea(dsp, pwin->w, x, y, CIRCSIZE, CIRCSIZE, False);
  103. if (random() & 1) {
  104. ws->dir = (ws->dir + 1) % SEGMENTS;
  105. } else {
  106. ws->dir = (ws->dir + SEGMENTS - 1) % SEGMENTS;
  107. }
  108. x = (ws->x + costab[ws->dir] + wp->xsize) % wp->xsize;
  109. y = (ws->y + sintab[ws->dir] + wp->ysize) % wp->ysize;
  110. ws->xcirc[ws->tail] = x;
  111. ws->ycirc[ws->tail] = y;
  112. ws->x = x;
  113. ws->y = y;
  114. wp->rects[color][wp->size[color]].x = x;
  115. wp->rects[color][wp->size[color]].y = y;
  116. wp->size[color]++;
  117. }
  118. void
  119. initworm(perwindow *pwin)
  120. {
  121. int i, j;
  122. wormstruct *wp;
  123. XWindowAttributes xwa;
  124. if (pwin->data) free(pwin->data);
  125. pwin->data = (void *)malloc(sizeof(wormstruct));
  126. memset(pwin->data, '\0', sizeof(wormstruct));
  127. wp = (wormstruct *)pwin->data;
  128. wp->nc = pwin->perscreen->npixels;
  129. if (wp->nc > MAXCOLORS)
  130. wp->nc = MAXCOLORS;
  131. wp->nw = batchcount;
  132. if (wp->nw > MAXWORMS)
  133. wp->nw = MAXWORMS;
  134. if (!init_table) {
  135. init_table = 1;
  136. for (i = 0; i < SEGMENTS; i++) {
  137. sintab[i] = round(CIRCSIZE * sin(i * 2 * PI / SEGMENTS));
  138. costab[i] = round(CIRCSIZE * cos(i * 2 * PI / SEGMENTS));
  139. }
  140. }
  141. XGetWindowAttributes(dsp, pwin->w, &xwa);
  142. wp->xsize = xwa.width;
  143. wp->ysize = xwa.height;
  144. if (xwa.width < 100) {
  145. wp->monopix = BlackPixelOfScreen(pwin->perscreen->screen);
  146. wp->wormlength = MAXWORMLEN / 10;
  147. } else {
  148. wp->monopix = WhitePixelOfScreen(pwin->perscreen->screen);
  149. wp->wormlength = MAXWORMLEN;
  150. }
  151. for (i = 0; i < wp->nc; i++) {
  152. for (j = 0; j < wp->nw / wp->nc + 1; j++) {
  153. wp->rects[i][j].width = CIRCSIZE;
  154. wp->rects[i][j].height = CIRCSIZE;
  155. }
  156. }
  157. memset(wp->size, '\0', wp->nc * sizeof(int));
  158. for (i = 0; i < wp->nw; i++) {
  159. for (j = 0; j < wp->wormlength; j++) {
  160. wp->worm[i].xcirc[j] = wp->xsize / 2;
  161. wp->worm[i].ycirc[j] = wp->ysize / 2;
  162. }
  163. wp->worm[i].dir = (unsigned) random() % SEGMENTS;
  164. wp->worm[i].tail = 0;
  165. wp->worm[i].x = wp->xsize / 2;
  166. wp->worm[i].y = wp->ysize / 2;
  167. }
  168. XClearWindow(dsp, pwin->w);
  169. }
  170. void
  171. drawworm(perwindow *pwin)
  172. {
  173. int i;
  174. wormstruct *wp = (wormstruct *)pwin->data;
  175. unsigned int wcolor;
  176. static unsigned int chromo = 0;
  177. memset(wp->size, '\0', wp->nc * sizeof(int));
  178. for (i = 0; i < wp->nw; i++) {
  179. if (!mono && wp->nc > 2) {
  180. wcolor = (i + chromo) % wp->nc;
  181. worm_doit(pwin, wp, i, wcolor);
  182. } else
  183. worm_doit(pwin, wp, i, 0);
  184. }
  185. if (!mono && wp->nc > 2) {
  186. for (i = 0; i < wp->nc; i++) {
  187. XSetForeground(dsp, pwin->gc, pwin->perscreen->pixels[i]);
  188. XFillRectangles(dsp, pwin->w, pwin->gc, wp->rects[i],
  189. wp->size[i]);
  190. }
  191. } else {
  192. XSetForeground(dsp, pwin->gc, wp->monopix);
  193. XFillRectangles(dsp, pwin->w, pwin->gc, wp->rects[0],
  194. wp->size[0]);
  195. }
  196. if (++chromo == wp->nc)
  197. chromo = 0;
  198. }