1 /* -copyright-
2 #-#
3 #-# xsnow: let it snow on your desktop
4 #-# Copyright (C) 1984,1988,1990,1993-1995,2000-2001 Rick Jansen
5 #-# 2019,2020,2021 Willem Vermin
6 #-#
7 #-# This program is free software: you can redistribute it and/or modify
8 #-# it under the terms of the GNU General Public License as published by
9 #-# the Free Software Foundation, either version 3 of the License, or
10 #-# (at your option) any later version.
11 #-#
12 #-# This program is distributed in the hope that it will be useful,
13 #-# but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 #-# GNU General Public License for more details.
16 #-#
17 #-# You should have received a copy of the GNU General Public License
18 #-# along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #-#
20 */
21
22 #include <stdio.h>
23 #include <gtk/gtk.h>
24 #include <stdlib.h>
25
26 #include "wind.h"
27 #include "utils.h"
28 #include "debug.h"
29 #include "flags.h"
30 #include "windows.h"
31 #include "clocks.h"
32 #include "xsnow.h"
33
34 #define NOTACTIVE \
35 (Flags.BirdsOnly || !WorkspaceActive())
36
37
38 static void SetWhirl(void);
39 static void SetWindTimer(void);
40 static int do_wind(void *);
41 static int do_newwind(void *);
42
wind_init()43 void wind_init()
44 {
45 SetWhirl();
46 SetWindTimer();
47 add_to_mainloop(PRIORITY_DEFAULT, time_newwind, do_newwind );
48 add_to_mainloop(PRIORITY_DEFAULT, time_wind, do_wind );
49 }
50
wind_ui()51 void wind_ui()
52 {
53 UIDO(NoWind, global.Wind = 0; global.NewWind = 0;);
54 UIDO(WhirlFactor, SetWhirl(););
55 UIDO(WindTimer, SetWindTimer(););
56 if(Flags.WindNow)
57 {
58 Flags.WindNow = 0;
59 global.Wind = 2;
60 P("Gust: %d\n",Flags.Changes);
61 }
62 }
63
draw_wind()64 void draw_wind()
65 {
66 // Nothing to draw
67 }
68
do_newwind(void * d)69 int do_newwind(void *d)
70 {
71 P("newwind\n");
72 if (Flags.Done)
73 return FALSE;
74 if (NOTACTIVE)
75 return TRUE;
76 //
77 // the speed of newwind is pixels/second
78 // at steady Wind, eventually all flakes get this speed.
79 //
80 if(Flags.NoWind) return TRUE;
81 static double t0 = -1;
82 if (t0<0)
83 {
84 t0 = wallclock();
85 return TRUE;
86 }
87
88 float r;
89 switch (global.Wind)
90 {
91 case(0):
92 default:
93 r = drand48()*global.Whirl;
94 global.NewWind += r - global.Whirl/2;
95 if(global.NewWind > global.WindMax) global.NewWind = global.WindMax;
96 if(global.NewWind < -global.WindMax) global.NewWind = -global.WindMax;
97 break;
98 case(1):
99 global.NewWind = global.Direction*0.6*global.Whirl;
100 break;
101 case(2):
102 global.NewWind = global.Direction*1.2*global.Whirl;
103 break;
104 }
105 return TRUE;
106 (void)d;
107 }
108
do_wind(void * d)109 int do_wind(void *d)
110 {
111 P("wind\n");
112 if (Flags.Done)
113 return FALSE;
114 if (NOTACTIVE)
115 return TRUE;
116 if(Flags.NoWind) return TRUE;
117 static int first = 1;
118 static double prevtime;
119
120 double TNow = wallclock();
121 if (first)
122 {
123 prevtime = TNow;;
124 first = 0;
125 }
126
127 // on the average, this function will do something
128 // after WindTimer secs
129
130 if ((TNow - prevtime) < 2*global.WindTimer*drand48()) return TRUE;
131
132 prevtime = TNow;
133
134 if(drand48() > 0.65) // Now for some of Rick's magic:
135 {
136 if(drand48() > 0.4)
137 global.Direction = 1;
138 else
139 global.Direction = -1;
140 global.Wind = 2;
141 global.WindTimer = 5;
142 // next time, this function will be active
143 // after on average 5 secs
144 }
145 else
146 {
147 if(global.Wind == 2)
148 {
149 global.Wind = 1;
150 global.WindTimer = 3;
151 // next time, this function will be active
152 // after on average 3 secs
153 }
154 else
155 {
156 global.Wind = 0;
157 global.WindTimer = global.WindTimerStart;
158 // next time, this function will be active
159 // after on average WindTimerStart secs
160 }
161 }
162 return TRUE;
163 (void)d;
164 }
165
SetWhirl()166 void SetWhirl()
167 {
168 global.Whirl = 0.01*Flags.WhirlFactor*WHIRL;
169 }
170
SetWindTimer()171 void SetWindTimer()
172 {
173 global.WindTimerStart = Flags.WindTimer;
174 if (global.WindTimerStart < 3)
175 global.WindTimerStart = 3;
176 global.WindTimer = global.WindTimerStart;
177 }
178