+// timers for rock generation.
+float rtimers[4];
+
+uint32_t nrocks;
+float nrocks_timer;
+float nrocks_inc_ticks = 2*60*20/(F_ROCKS-I_ROCKS);
+
+// constants for rock generation.
+#define KH (32*20) // 32 s for a speed=1 rock to cross the screen horizontally.
+#define KV (24*20) // 24 s for a speed=1 rock to cross the screen vertically.
+#define RDX 2.5 // range for rock dx values (+/-)
+#define RDY 2.5 // range for rock dy values (+/-)
+
+static inline struct rock_struct **
+bucket(int x, int y, int p)
+{
+ int b = (1+x/grid_size) + bw*(1+y/grid_size);
+ return &rock_buckets[p][b];
+}
+
+void
+init_buckets(void)
+{
+ bw = (XSIZE+2*grid_size-1) / grid_size;
+ bh = (YSIZE+2*grid_size-1) / grid_size;
+ n_buckets = bw * bh;
+
+ rock_buckets[0] = malloc(n_buckets * sizeof(struct rock_struct *));
+ rock_buckets[1] = malloc(n_buckets * sizeof(struct rock_struct *));
+ if(!rock_buckets[0] || !rock_buckets[1]) {
+ fprintf(stderr, "Can't allocate rock buckets.\n");
+ exit(1);
+ }
+ p = 0;
+}
+
+void
+transfer_rock(struct rock_struct *r, struct rock_struct **from, struct rock_struct **to)
+{
+ *from = r->next;
+ r->next = *to;
+ *to = r;
+}
+
+void
+reset_rocks(void)
+{
+ int i;
+
+ for(i=0; i<MAXROCKS; i++) rocks[i].image = NULL;
+ rocks[0].next = NULL; free_rocks = &rocks[MAXROCKS-1];
+ for(i = 1; i<MAXROCKS; i++) rocks[i].next = &rocks[i-1];
+ for(i = 0; i<n_buckets; i++) {
+ rock_buckets[0][i] = NULL;
+ rock_buckets[1][i] = NULL;
+ }