home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / x / volume14 / xantfarm / part01 / xantfarm.c < prev    next >
C/C++ Source or Header  |  1991-10-25  |  31KB  |  1,236 lines

  1. /* xantfarm - Insect world - build it up, tear it down.
  2. **
  3. ** Copyright (C) 1991 by Jef Poskanzer
  4. **
  5. ** Permission to use, copy, modify, and distribute this software and its
  6. ** documentation for any purpose and without fee is hereby granted, provided
  7. ** that the above copyright notice appear in all copies and that both that
  8. ** copyright notice and this permission notice appear in supporting
  9. ** documentation.  This software is provided "as is" without express or
  10. ** implied warranty.
  11. */
  12.  
  13. #ifndef lint
  14. static char rcsid[] =
  15.     "@(#) $Header: xantfarm.c,v 1.8 91/10/16 21:39:24 jef Exp $";
  16. #endif
  17.  
  18. #include <stdio.h>
  19. #include <sys/types.h>
  20. #include <sys/ioctl.h>
  21. #include <sys/time.h>
  22.  
  23. #include <X11/X.h>
  24. #include <X11/Xlib.h>
  25. #include <X11/Xutil.h>
  26. #include <X11/Xatom.h>
  27.  
  28. /* Add fd_set definitions, in case the system doesn't have them. */
  29. #ifndef FD_SET
  30. #define NFDBITS        32
  31. #define FD_SETSIZE    32
  32. #define FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
  33. #define FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
  34. #define FD_ISSET(n, p)    ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
  35. #define FD_ZERO(p)    bzero((char *)(p), sizeof(*(p)))
  36. #endif
  37.  
  38. /* Sand bitmap. */
  39. #define sand_width 4
  40. #define sand_height 4
  41. static char sand_bits[] = {0x0a,0x05,0x0a,0x05};
  42.  
  43. /* Ant bitmaps. */
  44. #define ant_ld0_width 12
  45. #define ant_ld0_height 4
  46. static char ant_ld0_bits[] = {0x03,0x00,0xec,0x07,0xff,0x07,0x20,0x09};
  47. #define ant_ld1_width 12
  48. #define ant_ld1_height 4
  49. static char ant_ld1_bits[] = {0x03,0x00,0xec,0x07,0xff,0x07,0x90,0x04};
  50. #define ant_lu0_width 12
  51. #define ant_lu0_height 4
  52. static char ant_lu0_bits[] = {0x20,0x09,0xff,0x07,0xec,0x07,0x03,0x00};
  53. #define ant_lu1_width 12
  54. #define ant_lu1_height 4
  55. static char ant_lu1_bits[] = {0x90,0x04,0xff,0x07,0xec,0x07,0x03,0x00};
  56. #define ant_rd0_width 12
  57. #define ant_rd0_height 4
  58. static char ant_rd0_bits[] = {0x00,0x0c,0x7e,0x03,0xfe,0x0f,0x49,0x00};
  59. #define ant_rd1_width 12
  60. #define ant_rd1_height 4
  61. static char ant_rd1_bits[] = {0x00,0x0c,0x7e,0x03,0xfe,0x0f,0x92,0x00};
  62. #define ant_ru0_width 12
  63. #define ant_ru0_height 4
  64. static char ant_ru0_bits[] = {0x49,0x00,0xfe,0x0f,0x7e,0x03,0x00,0x0c};
  65. #define ant_ru1_width 12
  66. #define ant_ru1_height 4
  67. static char ant_ru1_bits[] = {0x92,0x00,0xfe,0x0f,0x7e,0x03,0x00,0x0c};
  68. #define ant_ur0_width 4
  69. #define ant_ur0_height 12
  70. static char ant_ur0_bits[] = {
  71.     0x05,0x05,0x06,0x06,0x04,0x0e,0x06,0x06,0x0e,0x06,0x06,0x08};
  72. #define ant_ur1_width 4
  73. #define ant_ur1_height 12
  74. static char ant_ur1_bits[] = {
  75.     0x05,0x05,0x06,0x06,0x0c,0x06,0x06,0x0e,0x06,0x06,0x0e,0x00};
  76. #define ant_ul0_width 4
  77. #define ant_ul0_height 12
  78. static char ant_ul0_bits[] = {
  79.     0x0a,0x0a,0x06,0x06,0x02,0x07,0x06,0x06,0x07,0x06,0x06,0x01};
  80. #define ant_ul1_width 4
  81. #define ant_ul1_height 12
  82. static char ant_ul1_bits[] = {
  83.     0x0a,0x0a,0x06,0x06,0x03,0x06,0x06,0x07,0x06,0x06,0x07,0x00};
  84. #define ant_dr0_width 4
  85. #define ant_dr0_height 12
  86. static char ant_dr0_bits[] = {
  87.     0x08,0x06,0x06,0x0e,0x06,0x06,0x0e,0x04,0x06,0x06,0x05,0x05};
  88. #define ant_dr1_width 4
  89. #define ant_dr1_height 12
  90. static char ant_dr1_bits[] = {
  91.     0x00,0x0e,0x06,0x06,0x0e,0x06,0x06,0x0c,0x06,0x06,0x05,0x05};
  92. #define ant_dl0_width 4
  93. #define ant_dl0_height 12
  94. static char ant_dl0_bits[] = {
  95.     0x01,0x06,0x06,0x07,0x06,0x06,0x07,0x02,0x06,0x06,0x0a,0x0a};
  96. #define ant_dl1_width 4
  97. #define ant_dl1_height 12
  98. static char ant_dl1_bits[] = {
  99.     0x00,0x07,0x06,0x06,0x07,0x06,0x06,0x03,0x06,0x06,0x0a,0x0a};
  100. #define antc_ld0_width 12
  101. #define antc_ld0_height 4
  102. static char antc_ld0_bits[] = {0x03,0x00,0xed,0x07,0xff,0x07,0x20,0x09};
  103. #define antc_ld1_width 12
  104. #define antc_ld1_height 4
  105. static char antc_ld1_bits[] = {0x03,0x00,0xed,0x07,0xff,0x07,0x90,0x04};
  106. #define antc_lu0_width 12
  107. #define antc_lu0_height 4
  108. static char antc_lu0_bits[] = {0x20,0x09,0xff,0x07,0xed,0x07,0x03,0x00};
  109. #define antc_lu1_width 12
  110. #define antc_lu1_height 4
  111. static char antc_lu1_bits[] = {0x90,0x04,0xff,0x07,0xed,0x07,0x03,0x00};
  112. #define antc_rd0_width 12
  113. #define antc_rd0_height 4
  114. static char antc_rd0_bits[] = {0x00,0x0c,0x7e,0x0b,0xfe,0x0f,0x49,0x00};
  115. #define antc_rd1_width 12
  116. #define antc_rd1_height 4
  117. static char antc_rd1_bits[] = {0x00,0x0c,0x7e,0x0b,0xfe,0x0f,0x92,0x00};
  118. #define antc_ru0_width 12
  119. #define antc_ru0_height 4
  120. static char antc_ru0_bits[] = {0x49,0x00,0xfe,0x0f,0x7e,0x0b,0x00,0x0c};
  121. #define antc_ru1_width 12
  122. #define antc_ru1_height 4
  123. static char antc_ru1_bits[] = {0x92,0x00,0xfe,0x0f,0x7e,0x0b,0x00,0x0c};
  124. #define antc_ur0_width 4
  125. #define antc_ur0_height 12
  126. static char antc_ur0_bits[] = {
  127.     0x07,0x05,0x06,0x06,0x04,0x0e,0x06,0x06,0x0e,0x06,0x06,0x08};
  128. #define antc_ur1_width 4
  129. #define antc_ur1_height 12
  130. static char antc_ur1_bits[] = {
  131.     0x07,0x05,0x06,0x06,0x0c,0x06,0x06,0x0e,0x06,0x06,0x0e,0x00};
  132. #define antc_ul0_width 4
  133. #define antc_ul0_height 12
  134. static char antc_ul0_bits[] = {
  135.     0x0e,0x0a,0x06,0x06,0x02,0x07,0x06,0x06,0x07,0x06,0x06,0x01};
  136. #define antc_ul1_width 4
  137. #define antc_ul1_height 12
  138. static char antc_ul1_bits[] = {
  139.     0x0e,0x0a,0x06,0x06,0x03,0x06,0x06,0x07,0x06,0x06,0x07,0x00};
  140. #define antc_dr0_width 4
  141. #define antc_dr0_height 12
  142. static char antc_dr0_bits[] = {
  143.     0x08,0x06,0x06,0x0e,0x06,0x06,0x0e,0x04,0x06,0x06,0x05,0x07};
  144. #define antc_dr1_width 4
  145. #define antc_dr1_height 12
  146. static char antc_dr1_bits[] = {
  147.     0x00,0x0e,0x06,0x06,0x0e,0x06,0x06,0x0c,0x06,0x06,0x05,0x07};
  148. #define antc_dl0_width 4
  149. #define antc_dl0_height 12
  150. static char antc_dl0_bits[] = {
  151.     0x01,0x06,0x06,0x07,0x06,0x06,0x07,0x02,0x06,0x06,0x0a,0x0e};
  152. #define antc_dl1_width 4
  153. #define antc_dl1_height 12
  154. static char antc_dl1_bits[] = {
  155.     0x00,0x07,0x06,0x06,0x07,0x06,0x06,0x03,0x06,0x06,0x0a,0x0e};
  156.  
  157.  
  158. /* Definitions. */
  159.  
  160. #define RANDOM_DIG_PROB 200        /* dig down while wandering */
  161. #define RANDOM_DROP_PROB 200        /* drop while wandering */
  162. #define RANDOM_TURN_PROB 200        /* turn while wandering */
  163. #define CONCAVE_BELOW_DIG_PROB 10    /* dig a concave corner below ground*/
  164. #define CONVEX_ABOVE_DROP_PROB 10    /* drop at convex corner above ground */
  165. #define CALM_PROB 100            /* calm down from a panic */
  166.  
  167. #define COMPACT 15        /* this depth of sand turns to dirt */
  168. #define DIRT_START_FRAC 0.666666
  169.  
  170. #define GRID_SIZE sand_width
  171. #define ANT_GRIDS ( ant_lu0_width / GRID_SIZE )
  172.  
  173. /* The three elements. */
  174. #define E_AIR 0
  175. #define E_DIRT 1
  176. #define E_SAND 2
  177.  
  178. typedef struct ant_struct {
  179.     int x, y;
  180.     int dir;
  181.     int behavior;
  182.     int timer;
  183.     int phase;
  184.     } ant;
  185.  
  186. /* The eight directions. */
  187. #define D_LEFT_DOWN 0
  188. #define D_LEFT_UP 1
  189. #define D_RIGHT_DOWN 2
  190. #define D_RIGHT_UP 3
  191. #define D_UP_RIGHT 4
  192. #define D_UP_LEFT 5
  193. #define D_DOWN_RIGHT 6
  194. #define D_DOWN_LEFT 7
  195. #define N_DIRS 8
  196. #define N_ALTPIXMAPS 2
  197.  
  198. /* The three behaviors. */
  199. #define B_WANDERING 0
  200. #define B_CARRYING 1
  201. #define B_PANIC 2
  202.  
  203. /* Timing factors for the three behaviors. */
  204. #define T_WANDERING 4
  205. #define T_CARRYING 5
  206. #define T_PANIC 1
  207.  
  208. typedef struct falling_sand_struct {
  209.     int x, y;
  210.     int active;
  211.     } falling_sand;
  212.  
  213.  
  214.  
  215. /* Externals. */
  216.  
  217. extern char* malloc();
  218. extern char* realloc();
  219. extern long time();
  220. extern long random();
  221.  
  222.  
  223. /* Forward routines. */
  224.  
  225. static void x_init();
  226. static Window VirtualRootWindowOfScreen();
  227. static void ant_init();
  228. static void main_loop();
  229. static void expose();
  230. static void paint_run();
  231. static void poke();
  232. static void invalidate();
  233. static void invalidate_ant();
  234. static void cleanup();
  235.  
  236. static void moveants();
  237. static void move();
  238. static void turn();
  239. static int legal_dir();
  240. static int try_dig();
  241. static void loosen_neighbors();
  242. static void loosen_one();
  243. static void drop();
  244. static void behave();
  245. static void sand_fall();
  246.  
  247.  
  248. /* Variables. */
  249.  
  250. static char* argv0;
  251.  
  252. static Display* display;
  253. static Screen* screen;
  254. static Window root;
  255. static int root_w, root_h, root_d;
  256. static unsigned long foreground, background;
  257. static GC airgc;
  258. static GC sandgc;
  259. static Pixmap sand_pixmap;
  260. static GC antgc;
  261. static char* ant_bits[N_DIRS][N_ALTPIXMAPS] = {
  262.     ant_ld0_bits, ant_ld1_bits, ant_lu0_bits, ant_lu1_bits,
  263.     ant_rd0_bits, ant_rd1_bits, ant_ru0_bits, ant_ru1_bits,
  264.     ant_ur0_bits, ant_ur1_bits, ant_ul0_bits, ant_ul1_bits,
  265.     ant_dr0_bits, ant_dr1_bits, ant_dl0_bits, ant_dl1_bits };
  266. static char* antc_bits[N_DIRS][N_ALTPIXMAPS] = {
  267.     antc_ld0_bits, antc_ld1_bits, antc_lu0_bits, antc_lu1_bits,
  268.     antc_rd0_bits, antc_rd1_bits, antc_ru0_bits, antc_ru1_bits,
  269.     antc_ur0_bits, antc_ur1_bits, antc_ul0_bits, antc_ul1_bits,
  270.     antc_dr0_bits, antc_dr1_bits, antc_dl0_bits, antc_dl1_bits };
  271. static int ant_width[N_DIRS] = {
  272.     ant_ld0_width, ant_lu0_width, ant_rd0_width, ant_ru0_width,
  273.     ant_ur0_width, ant_ul0_width, ant_dr0_width, ant_dl0_width };
  274. static int ant_height[N_DIRS] = {
  275.     ant_ld0_height, ant_lu0_height, ant_rd0_height, ant_ru0_height,
  276.     ant_ur0_height, ant_ul0_height, ant_dr0_height, ant_dl0_height };
  277. static Pixmap ant_pixmap[N_DIRS][N_ALTPIXMAPS];
  278. static Pixmap antc_pixmap[N_DIRS][N_ALTPIXMAPS];
  279. static int num_exposerects, max_exposerects;
  280. static XRectangle* exposerects;
  281.  
  282. static int cycles;
  283. static int world_w, world_h;
  284. static int surface;
  285. static unsigned char** world;
  286. static ant* ants;
  287. static int num_ants;
  288. static int dx[N_DIRS] = { -1, -1, 1, 1, 0, 0, 0, 0 };
  289. static int dy[N_DIRS] = { 0, 0, 0, 0, -1, -1, 1, 1 };
  290. static int foot_dir[N_DIRS] = {
  291.     D_DOWN_RIGHT, D_UP_RIGHT, D_DOWN_LEFT, D_UP_LEFT,
  292.     D_RIGHT_DOWN, D_LEFT_DOWN, D_RIGHT_UP, D_LEFT_UP };
  293. static int back_dir[N_DIRS] = {
  294.     D_UP_LEFT, D_DOWN_LEFT, D_UP_RIGHT, D_DOWN_RIGHT,
  295.     D_LEFT_UP, D_RIGHT_UP, D_LEFT_DOWN, D_RIGHT_DOWN };
  296. #define D_LEFT_DOWN 0
  297. #define D_LEFT_UP 1
  298. #define D_RIGHT_DOWN 2
  299. #define D_RIGHT_UP 3
  300. #define D_UP_RIGHT 4
  301. #define D_UP_LEFT 5
  302. #define D_DOWN_RIGHT 6
  303. #define D_DOWN_LEFT 7
  304. static int num_falling_sands, max_falling_sands;
  305. static falling_sand* falling_sands;
  306.  
  307.  
  308. /* Routines. */
  309.  
  310. void
  311. main( argc, argv )
  312.     int argc;
  313.     char* argv[];
  314.     {
  315.     int printpid;
  316.     char* display_name;
  317.     int synchronous;
  318.     int pid, tty;
  319.  
  320.     /* Parse args. */
  321.     argv0 = argv[0];
  322.     num_ants = 10;
  323.     cycles = 15;
  324.     printpid = 0;
  325.     display_name = (char*) 0;
  326.     synchronous = 0;
  327.     for( ; ; )
  328.     {
  329.     if ( argc >= 3 && strcmp( argv[1], "-n" ) == 0 )
  330.         {
  331.         ++argv; --argc;
  332.         num_ants = atoi( argv[1] );
  333.         if ( num_ants <= 0 )
  334.         goto usage;
  335.         ++argv; --argc;
  336.         continue;
  337.         }
  338.     if ( argc >= 3 && strcmp( argv[1], "-c" ) == 0 )
  339.         {
  340.         ++argv; --argc;
  341.         cycles = atoi( argv[1] );
  342.         if ( cycles < 0 )
  343.         goto usage;
  344.         ++argv; --argc;
  345.         continue;
  346.         }
  347.     if ( argc >= 2 && strcmp( argv[1], "-i" ) == 0 )
  348.         {
  349.         ++argv; --argc;
  350.         printpid = 1;
  351.         continue;
  352.         }
  353.     if ( argc >= 3 && (
  354.            strcmp( argv[1], "-display" ) == 0 ||
  355.            strcmp( argv[1], "-displa" ) == 0 ||
  356.            strcmp( argv[1], "-displ" ) == 0 ||
  357.            strcmp( argv[1], "-disp" ) == 0 ||
  358.            strcmp( argv[1], "-dis" ) == 0 ||
  359.            strcmp( argv[1], "-di" ) == 0 ||
  360.            strcmp( argv[1], "-d" ) == 0 ) )
  361.         {
  362.         ++argv; --argc;
  363.         display_name = argv[1];
  364.         ++argv; --argc;
  365.         continue;
  366.         }
  367.     if ( argc >= 2 && (
  368.            strcmp( argv[1], "-sync" ) == 0 ||
  369.            strcmp( argv[1], "-syn" ) == 0 ||
  370.            strcmp( argv[1], "-sy" ) == 0 ||
  371.            strcmp( argv[1], "-s" ) == 0 ) )
  372.         {
  373.         ++argv; --argc;
  374.         synchronous = 1;
  375.         continue;
  376.         }
  377.     break;
  378.     }
  379.  
  380.     if ( argc > 1 )
  381.     {
  382. usage:
  383.     (void) fprintf(
  384.         stderr, "usage: %s [-n num] [-c cycles] [-i] [-display name]\n", argv0 );
  385.     exit( 1 );
  386.     }
  387.  
  388.     /* Initialize the random number generator. */
  389.     srandom( (int) ( time( (long*) 0 ) ^ getpid() ) );
  390.  
  391.     /* Set up X stuff. */
  392.     x_init( display_name, synchronous );
  393.  
  394.     /* Create the ant world. */
  395.     ant_init();
  396.  
  397.     /* Fork, if necessary. */
  398.     if ( printpid )
  399.     {
  400.     pid = fork();
  401.     if ( pid < 0 )
  402.         {
  403.         perror( "fork" );
  404.         exit( 1 );
  405.         }
  406.     else if ( pid > 0 )
  407.         {
  408.         /* Parent just exits. */
  409.         exit( 0 );
  410.         }
  411.     (void) printf( "%d\n", getpid() );
  412.     (void) fflush( stdout );
  413.  
  414.     /* Go stealth (ditch our controlling tty). */
  415.     tty = open( "/dev/tty", 0 );
  416.     if ( tty < 0 )
  417.         {
  418.         (void) fprintf( stderr, "%s: ", argv0 );
  419.         perror( "/dev/tty open" );
  420.         exit( 1 );
  421.         }
  422.     else
  423.         {
  424.         if ( ioctl( tty, TIOCNOTTY, 0 ) < 0 )
  425.         {
  426.         (void) fprintf( stderr, "%s: ", argv0 );
  427.         perror( "TIOCNOTTY ioctl" );
  428.         exit( 1 );
  429.         }
  430.         (void) close( tty );
  431.         }
  432.     }
  433.  
  434.     /* Main loop. */
  435.     main_loop();
  436.  
  437.     /*NOTREACHED*/
  438.     }
  439.  
  440. static void
  441. x_init( display_name, synchronous )
  442.     char* display_name;
  443.     int synchronous;
  444.     {
  445.     int i, j;
  446.  
  447.     display = XOpenDisplay( display_name );
  448.     if ( display == (Display*) 0 )
  449.     {
  450.     (void) fprintf(
  451.         stderr, "%s: can't open display \"%s\"\n", argv0,
  452.         XDisplayName( display_name ) );
  453.     exit( 1 );
  454.     }
  455.     if ( synchronous )
  456.     XSynchronize( display, 1 );
  457.     screen = DefaultScreenOfDisplay( display );
  458.     root = VirtualRootWindowOfScreen( screen );
  459.     root_w = WidthOfScreen( screen );
  460.     root_h = HeightOfScreen( screen );
  461.     root_d = DefaultDepthOfScreen( screen );
  462.     foreground = BlackPixelOfScreen( screen );
  463.     background = WhitePixelOfScreen( screen );
  464.     /* Air is all white, so its GC should paint white. */
  465.     airgc = XCreateGC( display, root, 0, (XGCValues*) 0 );
  466.     XSetForeground( display, airgc, background );
  467.     XSetBackground( display, airgc, foreground );
  468.     /* Sand is a pixmap, so its GC tiles. */
  469.     sandgc = XCreateGC( display, root, 0, (XGCValues*) 0 );
  470.     XSetForeground( display, sandgc, foreground );
  471.     XSetBackground( display, sandgc, background );
  472.     XSetFillStyle( display, sandgc, FillTiled );
  473.     sand_pixmap = XCreatePixmapFromBitmapData(
  474.     display, root, sand_bits, sand_width, sand_height,
  475.     foreground, background, root_d );
  476.     XSetTile( display, sandgc, sand_pixmap );
  477.     /* Ants paint black through a clipping bitmap. */
  478.     antgc = XCreateGC( display, root, 0, (XGCValues*) 0 );
  479.     XSetForeground( display, antgc, foreground );
  480.     XSetBackground( display, antgc, background );
  481.     for ( i = 0; i < N_DIRS; ++i )
  482.     for ( j = 0; j < N_ALTPIXMAPS; ++j )
  483.         {
  484.         ant_pixmap[i][j] = XCreateBitmapFromData(
  485.         display, root, ant_bits[i][j], ant_width[i], ant_height[i] );
  486.         antc_pixmap[i][j] = XCreateBitmapFromData(
  487.         display, root, antc_bits[i][j], ant_width[i], ant_height[i] );
  488.         }
  489.     num_exposerects = max_exposerects = 0;
  490.     }
  491.  
  492. /* From vroot.h by Andreas Stolcke. */
  493. static Window
  494. VirtualRootWindowOfScreen( screen )
  495.     Screen* screen;
  496.     {
  497.     static Screen* save_screen = (Screen*) 0;
  498.     static Window root = (Window) 0;
  499.  
  500.     if ( screen != save_screen )
  501.     {
  502.     Display* dpy = DisplayOfScreen( screen );
  503.     Atom __SWM_VROOT = None;
  504.     int i;
  505.     Window rootReturn, parentReturn;
  506.     Window* children;
  507.     unsigned int numChildren;
  508.  
  509.     root = RootWindowOfScreen( screen );
  510.  
  511.     /* Go look for a virtual root. */
  512.     __SWM_VROOT = XInternAtom( dpy, "__SWM_VROOT", False );
  513.     if ( XQueryTree(
  514.          dpy, root, &rootReturn, &parentReturn, &children,
  515.          &numChildren ) )
  516.         {
  517.         for ( i = 0; i < numChildren; ++i)
  518.         {
  519.         Atom actual_type;
  520.         int actual_format;
  521.         unsigned long nitems, bytesafter;
  522.         Window* newRoot = (Window*) 0;
  523.  
  524.         if ( XGetWindowProperty(
  525.              dpy, children[i], __SWM_VROOT, 0, 1, False, XA_WINDOW,
  526.              &actual_type, &actual_format, &nitems, &bytesafter,
  527.              (unsigned char**) &newRoot ) == Success && newRoot )
  528.             {
  529.             root = *newRoot;
  530.             break;
  531.             }
  532.         }
  533.         if ( children )
  534.         XFree( (char*) children );
  535.         }
  536.  
  537.     save_screen = screen;
  538.     }
  539.  
  540.     return root;
  541.     }
  542.  
  543. static void
  544. ant_init()
  545.     {
  546.     int x, y, a;
  547.  
  548.     world_w = root_w / GRID_SIZE;
  549.     world_h = root_h / GRID_SIZE;
  550.     world = (unsigned char**) malloc(
  551.     (unsigned) ( world_h * sizeof(unsigned char*) ) );
  552.     if ( world == (unsigned char**) 0 )
  553.     {
  554.     (void) fprintf( stderr, "%s: out of memory\n", argv0 );
  555.     exit( 1 );
  556.     }
  557.     for ( y = 0; y < world_h; ++y )
  558.     {
  559.     world[y] = (unsigned char*) malloc(
  560.         (unsigned) ( world_w * sizeof(unsigned char) ) );
  561.     if ( world[y] == (unsigned char*) 0 )
  562.         {
  563.         (void) fprintf( stderr, "%s: out of memory\n", argv0 );
  564.         exit( 1 );
  565.         }
  566.     }
  567.     surface = world_h * ( 1.0 - DIRT_START_FRAC );
  568.     for ( y = 0; y < surface; ++y )
  569.     for ( x = 0; x < world_w; ++x )
  570.         world[y][x] = E_AIR;
  571.     for ( ; y < world_h; ++y )
  572.     for ( x = 0; x < world_w; ++x )
  573.         world[y][x] = E_DIRT;
  574.     ants = (ant*) malloc( (unsigned) ( num_ants * sizeof(ant) ) );
  575.     if ( ants == (ant*) 0 )
  576.     {
  577.     (void) fprintf( stderr, "%s: out of memory\n", argv0 );
  578.     exit( 1 );
  579.     }
  580.     for ( a = 0; a < num_ants; ++a )
  581.     {
  582.     ants[a].x = random() % world_w;
  583.     ants[a].y = surface - 1;
  584.     ants[a].dir = random() % 2 == 1 ? D_LEFT_DOWN : D_RIGHT_DOWN;
  585.     behave( a, B_WANDERING, T_WANDERING );
  586.     ants[a].phase = 0;
  587.     }
  588.     num_falling_sands = max_falling_sands = 0;
  589.     }
  590.  
  591. static void
  592. main_loop()
  593.     {
  594.     int fd, i;
  595.     fd_set fds;
  596.     struct timeval timeout;
  597.     XEvent ev;
  598.  
  599.     XSelectInput( display, root, ExposureMask | PointerMotionMask );
  600.     invalidate( 0, 0, world_w, world_h );
  601.     FD_ZERO( &fds );
  602.     fd = ConnectionNumber( display );
  603.     for (;;)
  604.     {
  605.     if ( num_exposerects != 0 )
  606.         {
  607.         for ( i = 0; i < num_exposerects; ++i )
  608.         expose(
  609.             exposerects[i].x, exposerects[i].y,
  610.             (int) exposerects[i].width, (int) exposerects[i].height );
  611.         num_exposerects = 0;
  612.         continue;
  613.         }
  614.     if ( cycles != 0 && XPending( display ) == 0 )
  615.         {
  616.         /* No X events to handle, so wait for a while. */
  617.         FD_SET( fd, &fds );
  618.         timeout.tv_sec = 1 / cycles;
  619.         timeout.tv_usec = 1000000L / cycles;
  620.         (void) select( fd + 1, &fds, (int*) 0, (int*) 0, &timeout );
  621.         }
  622.     if ( XPending( display ) == 0 )
  623.         {
  624.         /* Still no X events, so let's move. */
  625.         moveants();
  626.         if ( num_falling_sands > 0 )
  627.         sand_fall();
  628.         continue;
  629.         }
  630.     /* Now there are X events. */
  631.     XNextEvent( display, &ev );
  632.     switch ( ev.type )
  633.         {
  634.         case Expose:
  635.         expose(
  636.         ev.xexpose.x, ev.xexpose.y,
  637.         ev.xexpose.width, ev.xexpose.height );
  638.         break;
  639.  
  640.         case MotionNotify:
  641.         poke( ev.xmotion.x, ev.xmotion.y );
  642.         break;
  643.         }
  644.     }
  645.     }
  646.  
  647. static void
  648. expose( ex, ey, ew, eh )
  649.     int ex, ey, ew, eh;
  650.     {
  651.     int x0, y0, x1, y1, x, y, a, d, ax, ay;
  652.     int run_start, run_count, run_type;
  653.  
  654.     /* Convert to ant world coordinates. */
  655.     x0 = ex / GRID_SIZE;
  656.     if ( x0 < 0 ) x0 = 0;
  657.     y0 = ey / GRID_SIZE;
  658.     if ( y0 < 0 ) y0 = 0;
  659.     x1 = ( ex + ew - 1 ) / GRID_SIZE;
  660.     if ( x1 >= world_w ) x1 = world_w - 1;
  661.     y1 = ( ey + eh - 1 ) / GRID_SIZE;
  662.     if ( y1 >= world_h ) y1 = world_h - 1;
  663.  
  664.     /* Paint the ant world. */
  665.     for ( y = y0; y <= y1; ++y )
  666.     {
  667.     /* Collect up a run of identical elements, so we can paint them
  668.     ** all at once and save oodles of cycles.
  669.     */
  670.     run_start = x0;
  671.     run_count = 1;
  672.     run_type = world[y][x0];
  673.     for ( x = x0 + 1; x <= x1; ++x )
  674.         {
  675.         if ( world[y][x] == run_type )
  676.         ++run_count;
  677.         else
  678.         {
  679.         paint_run( run_start, run_count, run_type, y );
  680.         run_start = x;
  681.         run_count = 1;
  682.         run_type = world[y][x];
  683.         }
  684.         }
  685.     if ( run_count > 0 )
  686.         paint_run( run_start, run_count, run_type, y );
  687.     }
  688.  
  689.     /* Now paint any ants in the exposed area. */
  690.     for ( a = 0; a < num_ants; ++a )
  691.     {
  692.     if ( ants[a].x + ANT_GRIDS / 2 >= x0 &&
  693.          ants[a].x - ANT_GRIDS / 2 <= x1 &&
  694.          ants[a].y + ANT_GRIDS / 2 >= y0 &&
  695.          ants[a].y - ANT_GRIDS / 2 <= y1 )
  696.         {
  697.         d = ants[a].dir;
  698.         ax = ants[a].x * GRID_SIZE - ant_width[d] / 2 + GRID_SIZE / 2;
  699.         ay = ants[a].y * GRID_SIZE - ant_height[d] / 2 + GRID_SIZE / 2;
  700.         if ( ants[a].behavior == B_CARRYING )
  701.         XSetClipMask( display, antgc, antc_pixmap[d][ants[a].phase] );
  702.         else
  703.         XSetClipMask( display, antgc, ant_pixmap[d][ants[a].phase] );
  704.         XSetClipOrigin( display, antgc, ax, ay );
  705.         XFillRectangle(
  706.         display, root, antgc, ax, ay, ant_width[d], ant_height[d] );
  707.         }
  708.     }
  709.     }
  710.  
  711. static void
  712. paint_run( run_start, run_count, run_type, y )
  713.     int run_start, run_count, run_type, y;
  714.     {
  715.     switch ( run_type )
  716.     {
  717.     case E_AIR:
  718.     XFillRectangle(
  719.         display, root, airgc, run_start * GRID_SIZE, y * GRID_SIZE,
  720.         run_count * GRID_SIZE, GRID_SIZE );
  721.     break;
  722.  
  723.     case E_DIRT:
  724.     /* Dirt shows as the default root pattern. */
  725.     XClearArea(
  726.         display, root, run_start * GRID_SIZE, y * GRID_SIZE,
  727.         run_count * GRID_SIZE, GRID_SIZE, False );
  728.     break;
  729.  
  730.     case E_SAND:
  731.     XFillRectangle(
  732.         display, root, sandgc, run_start * GRID_SIZE, y * GRID_SIZE,
  733.         run_count * GRID_SIZE, GRID_SIZE );
  734.     break;
  735.     }
  736.     }
  737.  
  738. static void
  739. poke( px, py )
  740.     int px, py;
  741.     {
  742.     int x, y, a, nx, ny;
  743.  
  744.     x = px / GRID_SIZE;
  745.     y = py / GRID_SIZE;
  746.     for ( a = 0; a < num_ants; ++a )
  747.     {
  748.     if ( x >= ants[a].x - ANT_GRIDS / 2 && x <= ants[a].x + ANT_GRIDS / 2 &&
  749.          y >= ants[a].y - ANT_GRIDS / 2 && y <= ants[a].y + ANT_GRIDS / 2 )
  750.         {
  751.         if ( ants[a].behavior == B_CARRYING )
  752.         drop( a );
  753.         nx = ants[a].x + random() % 3 - 1;
  754.         ny = ants[a].y + random() % 3 - 1;
  755.         if ( nx < 0 ) nx = 0;
  756.         if ( ny < 0 ) ny = 0;
  757.         if ( nx >= world_w ) nx = world_w - 1;
  758.         if ( ny >= world_h ) ny = world_h - 1;
  759.         invalidate_ant( a );
  760.         ants[a].x = nx;
  761.         ants[a].y = ny;
  762.         ants[a].dir = random() % N_DIRS;
  763.         invalidate_ant( a );
  764.         behave( a, B_PANIC, T_PANIC );
  765.         }
  766.     }
  767.     }
  768.  
  769. static void
  770. invalidate( x, y, w, h )
  771.     int x, y, w, h;
  772.     {
  773.     int i, ex, ey, ew, eh;;
  774.  
  775.     x *= GRID_SIZE;
  776.     y *= GRID_SIZE;
  777.     w *= GRID_SIZE;
  778.     h *= GRID_SIZE;
  779.  
  780.     /* Check if this rectangle intersects an existing one. */
  781.     for ( i = 0; i < num_exposerects; ++i )
  782.     {
  783.     ex = exposerects[i].x;
  784.     ey = exposerects[i].y;
  785.     ew = exposerects[i].width;
  786.     eh = exposerects[i].height;
  787.     if ( x < ex + ew && ex < x + w && y < ey + eh && ey < y + h )
  788.         {
  789.         /* Found an intersection - merge them. */
  790.         if ( x + w > ex + ew )
  791.         exposerects[i].width = ew = x + w - ex;
  792.         if ( y + h > ey + eh )
  793.         exposerects[i].height = eh = y + h - ey;
  794.         if ( x < ex )
  795.         {
  796.         exposerects[i].width = ex + ew - x;
  797.         exposerects[i].x = x;
  798.         }
  799.         if ( y < ey )
  800.         {
  801.         exposerects[i].height = ey + eh - y;
  802.         exposerects[i].y = y;
  803.         }
  804.         return;
  805.         }
  806.     }
  807.  
  808.     /* Nope, add a new XRectangle. */
  809.     if ( num_exposerects == max_exposerects )
  810.     {
  811.     if ( max_exposerects == 0 )
  812.         {
  813.         max_exposerects = 20;
  814.         exposerects = (XRectangle*) malloc(
  815.         (unsigned) ( max_exposerects * sizeof(XRectangle) ) );
  816.         }
  817.     else
  818.         {
  819.         max_exposerects *= 2;
  820.         exposerects = (XRectangle*) realloc(
  821.         (char*) exposerects,
  822.         (unsigned) ( max_exposerects * sizeof(XRectangle) ) );
  823.         }
  824.     if ( exposerects == (XRectangle*) 0 )
  825.         {
  826.         (void) fprintf( stderr, "%s: out of memory\n", argv0 );
  827.         exit( 1 );
  828.         }
  829.     }
  830.     exposerects[num_exposerects].x = x;
  831.     exposerects[num_exposerects].y = y;
  832.     exposerects[num_exposerects].width = w;
  833.     exposerects[num_exposerects].height = h;
  834.     ++num_exposerects;
  835.     }
  836.  
  837. static void
  838. invalidate_ant( a )
  839.     int a;
  840.     {
  841.     invalidate(
  842.     ants[a].x - ANT_GRIDS / 2, ants[a].y - ANT_GRIDS / 2,
  843.     ANT_GRIDS, ANT_GRIDS );
  844.     }
  845.  
  846. static void
  847. cleanup()
  848.     {
  849.     int i, j;
  850.  
  851.     XFreePixmap( display, sand_pixmap );
  852.     for ( i = 0; i < N_DIRS; ++i )
  853.     for ( j = 0; j < N_ALTPIXMAPS; ++j )
  854.         {
  855.         XFreePixmap( display, ant_pixmap[i][j] );
  856.         XFreePixmap( display, antc_pixmap[i][j] );
  857.         }
  858.     XFreeGC( display, airgc );
  859.     XFreeGC( display, sandgc );
  860.     XFreeGC( display, antgc );
  861.     XCloseDisplay( display );
  862.     }
  863.  
  864. static void
  865. moveants()
  866.     {
  867.     int a, x, y, fx, fy;
  868.  
  869.     for ( a = 0; a < num_ants; ++a )
  870.     {
  871.     --ants[a].timer;
  872.     if ( ants[a].timer <= 0 )
  873.         {
  874.         ants[a].phase = ( ants[a].phase + 1 ) % N_ALTPIXMAPS;
  875.  
  876.         /* Gravity check. */
  877.         x = ants[a].x;
  878.         y = ants[a].y;
  879.         fx = x + dx[foot_dir[ants[a].dir]];
  880.         fy = y + dy[foot_dir[ants[a].dir]];
  881.         if ( fx >= 0 && fx < world_w && fy >= 0 && fy < world_h &&
  882.          world[fy][fx] == E_AIR )
  883.         {
  884.         /* Whoops, whatever we were walking on disappeared. */
  885.         if ( y + 1 < world_h && world[y + 1][x] == E_AIR )
  886.             {
  887.             invalidate_ant( a );
  888.             ants[a].y = y + 1;
  889.             invalidate_ant( a );
  890.             }
  891.         else
  892.             /* Can't fall?  Try turning. */
  893.             turn( a );
  894.         }
  895.         else
  896.         {
  897.         /* Ok, the ant gets to do something. */
  898.         switch ( ants[a].behavior )
  899.             {
  900.             case B_WANDERING:
  901.             if ( random() % RANDOM_DIG_PROB == 0 )
  902.             (void) try_dig( a, 0 );
  903.             else if ( random() % RANDOM_TURN_PROB == 0 )
  904.             turn( a );
  905.             else
  906.             {
  907.             behave( a, B_WANDERING, T_WANDERING );
  908.             move( a );
  909.             }
  910.             break;
  911.  
  912.             case B_CARRYING:
  913.             if ( random() % RANDOM_DROP_PROB == 0 )
  914.             drop( a );
  915.             else
  916.             {
  917.             behave( a, B_CARRYING, T_CARRYING );
  918.             move( a );
  919.             }
  920.             break;
  921.  
  922.             case B_PANIC:
  923.             if ( random() % CALM_PROB == 0 )
  924.             {
  925.             behave( a, B_WANDERING, T_WANDERING );
  926.             }
  927.             else
  928.             {
  929.             behave( a, B_PANIC, T_PANIC );
  930.             move( a );
  931.             }
  932.             break;
  933.             }
  934.         }
  935.         }
  936.     }
  937.     }
  938.  
  939. static void
  940. move( a )
  941.     int a;
  942.     {
  943.     int x, y, i, d, nx, ny, fx, fy;
  944.  
  945.     x = ants[a].x;
  946.     y = ants[a].y;
  947.     d = ants[a].dir;
  948.     nx = x + dx[d];
  949.     ny = y + dy[d];
  950.  
  951.     if ( nx < 0 || nx >= world_w || ny < 0 || ny >= world_h )
  952.     {
  953.     /* Hit an edge.  Turn. */
  954.     turn( a );
  955.     return;
  956.     }
  957.  
  958.     if ( world[ny][nx] != E_AIR )
  959.     {
  960.     /* Hit dirt or sand.  Dig? */
  961.     if ( ants[a].behavior == B_WANDERING && ants[a].y >= surface &&
  962.          random() % CONCAVE_BELOW_DIG_PROB == 0 )
  963.         /* Yes, try digging. */
  964.         (void) try_dig( a, 1 );
  965.     else
  966.         /* Nope, no digging.  Turn. */
  967.         turn( a );
  968.     return;
  969.     }
  970.  
  971.     /* We can move forward.  But first, check footing. */
  972.     fx = nx + dx[foot_dir[d]];
  973.     fy = ny + dy[foot_dir[d]];
  974.     if ( fx >= 0 && fx < world_w && fy >= 0 && fy < world_h &&
  975.      world[fy][fx] == E_AIR )
  976.     {
  977.     /* Whoops, we're over air.  Move into the air and turn towards
  978.     ** the feet.  But first, see if we should drop.
  979.     */
  980.     if ( ants[a].behavior == B_CARRYING && ants[a].y < surface &&
  981.          random() % CONVEX_ABOVE_DROP_PROB == 0 )
  982.         drop( a );
  983.     nx = fx;
  984.     ny = fy;
  985.     ants[a].dir = foot_dir[d];
  986.     }
  987.  
  988.     /* Ok. */
  989.     invalidate_ant( a );
  990.     ants[a].x = nx;
  991.     ants[a].y = ny;
  992.     invalidate_ant( a );
  993.     }
  994.  
  995. static void
  996. turn( a )
  997.     int a;
  998.     {
  999.     int n, d;
  1000.     int ok_dirs[N_DIRS];
  1001.  
  1002.     /* First check if turning "up" is ok. */
  1003.     d = back_dir[ants[a].dir];
  1004.     if ( legal_dir( a, d ) )
  1005.     ants[a].dir = d;
  1006.     else
  1007.     {
  1008.     /* Make a list of the legal directions. */
  1009.     n = 0;
  1010.     for ( d = 0; d < N_DIRS; ++d )
  1011.         {
  1012.         if ( d != ants[a].dir && legal_dir( a, d ) )
  1013.         {
  1014.         ok_dirs[n] = d;
  1015.         ++n;
  1016.         }
  1017.         }
  1018.     
  1019.     if ( n != 0 )
  1020.         {
  1021.         /* Choose a random legal direction. */
  1022.         ants[a].dir = ok_dirs[random() % n];
  1023.         }
  1024.     else
  1025.         {
  1026.         /* No legal directions to turn?  Trapped!  If we're carrying,
  1027.         ** drop, then turn randomly.  Perhaps we can dig ourselves out.
  1028.         */
  1029.         if ( ants[a].behavior == B_CARRYING )
  1030.         drop( a );
  1031.         ants[a].dir = random() % N_DIRS;
  1032.         }
  1033.     }
  1034.     invalidate_ant( a );
  1035.     }
  1036.  
  1037. static int
  1038. legal_dir( a, d )
  1039.     int a, d;
  1040.     {
  1041.     int nx, ny;
  1042.  
  1043.     /* Check that there's air ahead. */
  1044.     nx = ants[a].x + dx[d];
  1045.     ny = ants[a].y + dy[d];
  1046.     if ( nx < 0 || nx >= world_w || ny < 0 || ny >= world_h ||
  1047.      world[ny][nx] != E_AIR )
  1048.     return 0;
  1049.  
  1050.     /* Check that there's solid footing. */
  1051.     nx = ants[a].x + dx[foot_dir[d]];
  1052.     ny = ants[a].y + dy[foot_dir[d]];
  1053.     if ( nx >= 0 && nx < world_w && ny >= 0 && ny < world_h &&
  1054.      world[ny][nx] == E_AIR )
  1055.     return 0;
  1056.  
  1057.     return 1;
  1058.     }
  1059.  
  1060. static int
  1061. try_dig( a, forward )
  1062.     int a, forward;
  1063.     {
  1064.     int x, y;
  1065.  
  1066.     if ( forward )
  1067.     {
  1068.     x = ants[a].x + dx[ants[a].dir];
  1069.     y = ants[a].y + dy[ants[a].dir];
  1070.     }
  1071.     else
  1072.     {
  1073.     x = ants[a].x + dx[foot_dir[ants[a].dir]];
  1074.     y = ants[a].y + dy[foot_dir[ants[a].dir]];
  1075.     }
  1076.  
  1077.     if ( x >= 0 && x < world_w && y >= 0 && y < world_h &&
  1078.      world[y][x] != E_AIR )
  1079.     {
  1080.     world[y][x] = E_AIR;
  1081.     invalidate( x, y, 1, 1 );
  1082.     loosen_neighbors( x, y );
  1083.     behave( a, B_CARRYING, T_CARRYING );
  1084.     return 1;
  1085.     }
  1086.     else
  1087.     return 0;
  1088.     }
  1089.  
  1090. static void
  1091. loosen_neighbors( xc, yc )
  1092.     int xc, yc;
  1093.     {
  1094.     int x, y;
  1095.  
  1096.     for ( y = yc + 1; y >= yc - 1; --y )
  1097.     for ( x = xc - 1; x <= xc + 1; ++x )
  1098.         if ( x >= 0 && x < world_w && y >= 0 && y < world_h &&
  1099.          world[y][x] == E_SAND )
  1100.         loosen_one( x, y );
  1101.     }
  1102.  
  1103. static void
  1104. loosen_one( x, y )
  1105.     int x, y;
  1106.     {
  1107.     int i;
  1108.  
  1109.     /* Check if there's already loose sand at this location. */
  1110.     for ( i = 0; i < num_falling_sands; ++i )
  1111.     if ( falling_sands[i].active &&
  1112.          x == falling_sands[i].x && y == falling_sands[i].y )
  1113.         return;
  1114.  
  1115.     /* Check if there's room to store the new sand. */
  1116.     if ( num_falling_sands == max_falling_sands )
  1117.     {
  1118.     if ( max_falling_sands == 0 )
  1119.         {
  1120.         max_falling_sands = 20;
  1121.         falling_sands = (falling_sand*) malloc(
  1122.         (unsigned) ( max_falling_sands * sizeof(falling_sand) ) );
  1123.         }
  1124.     else
  1125.         {
  1126.         max_falling_sands *= 2;
  1127.         falling_sands = (falling_sand*) realloc(
  1128.         (char*) falling_sands,
  1129.         (unsigned) ( max_falling_sands * sizeof(falling_sand) ) );
  1130.         }
  1131.     if ( falling_sands == (falling_sand*) 0 )
  1132.         {
  1133.         (void) fprintf( stderr, "%s: out of memory\n", argv0 );
  1134.         exit( 1 );
  1135.         }
  1136.     }
  1137.  
  1138.     /* Add it. */
  1139.     falling_sands[num_falling_sands].x = x;
  1140.     falling_sands[num_falling_sands].y = y;
  1141.     falling_sands[num_falling_sands].active = 1;
  1142.     ++num_falling_sands;
  1143.     }
  1144.  
  1145. static void
  1146. drop( a )
  1147.     int a;
  1148.     {
  1149.     world[ants[a].y][ants[a].x] = E_SAND;
  1150.     invalidate( ants[a].x, ants[a].y, 1, 1 );
  1151.     loosen_one( ants[a].x, ants[a].y );
  1152.     behave( a, B_WANDERING, T_WANDERING );
  1153.     }
  1154.  
  1155. static void
  1156. behave( a, behavior, timer )
  1157.     int a, behavior, timer;
  1158.     {
  1159.     ants[a].behavior = behavior;
  1160.     ants[a].timer = 3 * timer / 4 + random() % timer / 2;
  1161.     }
  1162.  
  1163. static void
  1164. sand_fall()
  1165.     {
  1166.     int i, x, y, gotone, tipl, tipr;
  1167.  
  1168.     gotone = 0;
  1169.     for ( i = 0; i < num_falling_sands; ++i )
  1170.     if ( falling_sands[i].active )
  1171.     {
  1172.     gotone = 1;
  1173.     x = falling_sands[i].x;
  1174.     y = falling_sands[i].y;
  1175.     if ( y + 1 >= world_h )
  1176.         {
  1177.         /* Hit bottom - done falling and no compaction possible. */
  1178.         falling_sands[i].active = 0;
  1179.         continue;
  1180.         }
  1181.  
  1182.     /* Drop the sand onto the next lower sand or dirt. */
  1183.     if ( world[y + 1][x] == E_AIR )
  1184.         {
  1185.         falling_sands[i].y = y + 1;
  1186.         world[y][x] = E_AIR;
  1187.         world[falling_sands[i].y][falling_sands[i].x] = E_SAND;
  1188.         invalidate( x, y, 1, 1 );
  1189.         invalidate( falling_sands[i].x, falling_sands[i].y, 1, 1 );
  1190.         loosen_neighbors( x, y );
  1191.         continue;
  1192.         }
  1193.     
  1194.     /* Tip over an edge? */
  1195.     tipl = ( x - 1 >= 0 && world[y + 1][x - 1] == E_AIR &&
  1196.          y + 2 < world_h && world[y + 2][x - 1] == E_AIR );
  1197.     tipr = ( x + 1 < world_w && world[y + 1][x + 1] == E_AIR &&
  1198.          y + 2 < world_h && world[y + 2][x + 1] == E_AIR );
  1199.     if ( tipl || tipr )
  1200.         {
  1201.         if ( tipl && tipr )
  1202.         {
  1203.         if ( random() % 2 == 0 )
  1204.             falling_sands[i].x = x - 1;
  1205.         else
  1206.             falling_sands[i].x = x + 1;
  1207.         }
  1208.         else if ( tipl )
  1209.         falling_sands[i].x = x - 1;
  1210.         else if ( tipr )
  1211.         falling_sands[i].x = x + 1;
  1212.         falling_sands[i].y = y + 1;
  1213.         world[y][x] = E_AIR;
  1214.         world[falling_sands[i].y][falling_sands[i].x] = E_SAND;
  1215.         invalidate( x, y, 1, 1 );
  1216.         invalidate( falling_sands[i].x, falling_sands[i].y, 1, 1 );
  1217.         loosen_neighbors( x, y );
  1218.         continue;
  1219.         }
  1220.  
  1221.     /* Found the final resting place. */
  1222.     falling_sands[i].active = 0;
  1223.  
  1224.     /* Compact sand into dirt. */
  1225.     for ( i = 0; y + 1 < world_h && world[y+1][x] == E_SAND; ++y, ++i )
  1226.         ;
  1227.     if ( i >= COMPACT )
  1228.         {
  1229.         world[y][x] = E_DIRT;
  1230.         invalidate( x, y, 1, 1 );
  1231.         }
  1232.     }
  1233.     if ( ! gotone )
  1234.     num_falling_sands = 0;
  1235.     }
  1236.