From http://www.jwz.org/xscreensaver/xscreensaver-5.18.tar.gz
[xscreensaver] / hacks / glx / sonar-sim.c
1 /* sonar, Copyright (c) 1998-2012 Jamie Zawinski and Stephen Martin
2  *
3  * Permission to use, copy, modify, distribute, and sell this software and its
4  * documentation for any purpose is hereby granted without fee, provided that
5  * the above copyright notice appear in all copies and that both that
6  * copyright notice and this permission notice appear in supporting
7  * documentation.  No representations are made about the suitability of this
8  * software for any purpose.  It is provided "as is" without express or 
9  * implied warranty.
10  *
11  * This implements the "simulation" sensor for sonar.
12  */
13
14 #include "screenhackI.h"
15 #include "sonar.h"
16
17 typedef struct {
18   const char *team_a_name;
19   const char *team_b_name;
20   int team_a_count;
21   int team_b_count;
22   sonar_bogie *targets;
23   Bool debug_p;
24 } sim_data;
25
26
27 static void
28 sim_free_data (sonar_sensor_data *ssd, void *closure)
29 {
30   sim_data *sd = (sim_data *) closure;
31   free (sd);
32 }
33
34 static void
35 sim_free_bogie_data (sonar_sensor_data *ssd, void *closure)
36 {
37   free (closure);
38 }
39
40
41 /* Return an updated (moved) copy of the bogies.
42  */
43 static sonar_bogie *
44 sim_scan (sonar_sensor_data *ssd)
45 {
46   sim_data *sd = (sim_data *) ssd->closure;
47   sonar_bogie *b, *b2, *list = 0;
48   double scale = 0.01;
49   for (b = sd->targets; b; b = b->next)
50     {
51       b->r  += scale * (0.5 - frand(1.0));
52       b->th += scale * (0.5 - frand(1.0));
53       while (b->r < 0.2) b->r += scale * 0.1;
54       while (b->r > 0.9) b->r -= scale * 0.1;
55
56       b2 = sonar_copy_bogie (ssd, b);
57       b2->next = list;
58       list = b2;
59     }
60   return list;
61 }
62
63
64 static void
65 make_bogies (sonar_sensor_data *ssd)
66 {
67   sim_data *sd = (sim_data *) ssd->closure;
68   int i, j;
69
70   for (j = 0; j <= 1; j++)
71     for (i = 0; i < (j ? sd->team_a_count : sd->team_b_count); i++)
72       {
73         sonar_bogie *b = (sonar_bogie *) calloc (1, sizeof(*b));
74         const char *name = (j ? sd->team_a_name : sd->team_b_name);
75         b->name = (char *) malloc (strlen(name) + 10);
76         sprintf (b->name, "%s%03d", name, i+1);
77         b->r = 0.3 + frand(0.5);
78         b->th = frand (M_PI*2);
79         b->next = sd->targets;
80         sd->targets = b;
81         if (sd->debug_p)
82           fprintf (stderr, "%s: %s: %5.2f %5.2f\n", progname,
83                    b->name, b->r, b->th);
84       }
85 }
86
87
88 sonar_sensor_data *
89 sonar_init_simulation (Display *dpy, char **error_ret, char **desc_ret,
90                        const char *team_a_name, const char *team_b_name,
91                        int team_a_count, int team_b_count,
92                        Bool debug_p)
93 {
94   sonar_sensor_data *ssd = (sonar_sensor_data *) calloc (1, sizeof(*ssd));
95   sim_data *sd = (sim_data *) calloc (1, sizeof(*sd));
96
97   sd->team_a_name  = team_a_name;
98   sd->team_b_name  = team_b_name;
99   sd->team_a_count = team_a_count;
100   sd->team_b_count = team_b_count;
101   sd->debug_p      = debug_p;
102
103   ssd->closure       = sd;
104   ssd->scan_cb       = sim_scan;
105   ssd->free_data_cb  = sim_free_data;
106   ssd->free_bogie_cb = sim_free_bogie_data;
107
108   make_bogies (ssd);
109
110   return ssd;
111 }
112