1 /*
2 * drone.h
3 * DIN Is Noise is copyright (c) 2006-2021 Jagannathan Sampath
4 * DIN Is Noise is released under GNU Public License 2.0
5 * For more information, please visit https://dinisnoise.org/
6 */
7 
8 #ifndef __drone__
9 #define __drone__
10 
11 #include "fader.h"
12 #include "solver.h"
13 #include "play.h"
14 #include "trail.h"
15 #include "alarm.h"
16 #include "modulator.h"
17 #include "noiser.h"
18 #include "container.h"
19 #include "vector2d.h"
20 #include "angle.h"
21 #include "autorotator.h"
22 
23 #include <string>
24 #include <map>
25 #include <ostream>
26 
27 #define RESETCHUCKTRAILS(d) if (drone::chuckt::autoresettrails) resetchucktrails(d);
28 
29 extern int TRAILSIZE;
30 extern int BOTTOM;
31 extern float DELTA_VOLUME;
32 extern float ARROW_U, ARROW_V;
33 
34 struct din;
35 struct drone;
36 
37 typedef std::list<drone*>::iterator drone_iterator;
38 
39 struct attractee {
40 	int id;
41 	drone* d;
42 	attractee (int _id = -1, drone* _d = 0) {id = _id; d = _d;}
43   bool operator== (const attractee& ae) {return (d == ae.d);}
44 };
45 
46 
47 struct drone {
48 
49   static float mastervolume;
50 
51   static int UID; // unique id
52 	int id; // this drone id
53 
54   play player;
55   solver sol;
56 
57   float step; // determines pitch (see note.h)
58 
59   float vol; // actual volume
60 
61   int range; // range number on microtonal-keyboard
62   float pos; // position in range (0 - left, 1 - right, can go < 0 & > 1 too)
63 
64   int sel; // selected?
65 
66   float cx, cy; // unmodulated position
67   float x, y; // current position
68 
69   int snap; // snap to range edge?
70   float sx; // snapped x (used for note snap)
71   int note_num; // 0 = left note, 1 = right note of range
72 
73   float dy; // height from microtonal-keyboard bottom
74 
75   float r, g, b; // color
76   void setcolor ();
77 
78   // visuals
79   //
80 	trail_t trail; // trail points
81 
82 	box<float> handle; // for picking
83   static int HANDLESIZE; // default size
84 	int handle_size;
85 
86 	struct arrowt {
87     static float U, V, K, CAP;
88 		float u, v, t;
89     int cap;
arrowtdrone::arrowt90 		arrowt () {reset ();}
91     void reset ();
92 	} arrow;
93 
94 	void calc_handle ();
95 
96   struct posafxvelt {
97     int yes; // drone position affects velocity vector?
98     point<float> pt;
99     static double minmag;
posafxveltdrone::posafxvelt100     posafxvelt() : yes(0), pt (0.0f,0.0f) {}
101   } posafxvel;
102 
103   // connections
104   static float STIFFNESS;
105   static std::map<drone*,bool> proc_conn;
106 	int nconn;
107 	std::list<drone*> connections;
108 	std::list<double> mags;
109 	enum {LINK=0, CHAIN=1};
110 	int type;
111 	drone* eval_conns ();
112   void remagconns ();
113 
114 	// states
115   enum {DEAD=0, RISING, FALLING, ACTIVE};
116   int state; // current
117   fader fdr; // for rising/falling -> fade in/out
118 
119 	int frozen; // frozen?
120   double froze_at; // time when frozen
121 	int freeze ();
122 	int thaw ();
123   void handle_time_pass ();
124 
125   //
126   // mute/unmute ; drone <> noise
127   fader gab;
128   float tovol;
129   static double gabt;
130 
131   // modulation
132   modulator mod;
133 
134 	// orbitals & rocketry
135 	//
136 	int attractor; // attractor?
137 	int orbiting; // orbiting?
138 	std::list<attractee> attractees; // list of drones attracted by this drone
139 
140 	float V; // speed
141   float vx, vy; // current velocity vector
142   float v_mult; // multiplier for velocity vector used in orbit insertion
143 
144 	float A; // acceleration
145 	float ax, ay; // acceleration unit vector
146 	float xi, yi; // interim position
147 	double insert; // time to insert into orbit
148 
149   float xv, yv; // position of velocity vector tip
150   float xa, ya; // position of acceleration vector tip
151 
152   static defvelaccel v0, a0;
153   struct autorotva {
154     autorotator v, a;
155     autorotator* arr[2];
autorotvadrone::autorotva156     autorotva () : v (v0), a (a0) {
157       arr[0] = &v;
158       arr[1] = &a;
159     }
calcdrone::autorotva160     void calc (double dt) {
161       v.calc (dt);
162       a.calc (dt);
163     }
164   } autorot;
165 
166   int gravity; // accelerated by gravity?
167 
168   struct bouncet {
169     int n;
170     int max;
171     bouncet ();
172   } bounces;
173 
174   static int anchored;
175   int launcher; // launches drones?
176   alarm_t launch_every; // alarm time in seconds
177   float dpm; // drones per minute
178   drone* launched_by;
179 
180   // targets for launchers to launch drones to
181   std::vector<drone*> targets;
182   int cur_target;
183   int num_targets;
184   void clear_targets ();
185   drone* target;
186 
187 	static double LIFETIME;
188 	double birth; // time at birth
189 	double life; // lifetime
190   int reincarnate;
191 
192   static double INSERTTIME; // time for insert into orbit
193 
194   enum {NONE, POINT, USE};
195   int tracking;
196   drone* tracked_drone; // the tracked drone
197 
198   // wanding
199   static struct wandt {
200     int dist;
201     int dist2;
wandtdrone::wandt202     wandt (int d) {set (d);}
setdrone::wandt203     void set (int d) {
204       dist = d;
205       dist2 = d * d;
206     }
207   } wand;
208 
209   enum {UNSET=0, INTERPOLATE, EMPLACE};
210   int update_pv;
211   void update_pitch_volume ();
212 
213 	drone (float bottom = 0.0f);
214 
215   static int ref;
216 	~drone();
217 
218   void set_pos (float x, float y);
219 	void set_center (float _cx, float _cy, int e = 1);
220   void move_center ();
221 
222 	void change_depth (int i, int what, float delta);
223   void change_bpm (int i, int what, float delta);
224 	void change_bpm (mod_params& mp, float delta);
225 
226   enum {DRONE, NOISE, DRONE_OR_NOISE};
227   static int IS;
228 	int is;
229   void setis ();
230 
231 	noiser nsr;
232   void setnoise ();
233 
234   enum {IMMORTAL, MORTAL, REINCARNATE};
235   static int ARE;
236 
237   // for drone <> noise conversions
238   struct fin {
239     virtual void finished (din& d, drone* pd) = 0;
240   } *finl;
241 
242   static struct drone2noise : fin {
243     void finished (din& mkb, drone* pd);
244   } dnl;
245 
246   static struct noise2drone : fin {
247     void finished (din& mkb, drone* pd);
248   } ndl;
249 
250   static fin* fins [3]; // 0 = null, 1 = drone2noise, 2 = noise2drone, init @ main.cc
251 
252   struct chuckt { // virtual geometric chuck
253 
254     static anglet apt; // angle per turn
255     static int outline; // draw outline?
256     static int autoresettrails; // auto reset trails when chuck params changed?
257 
258     int yes;
259     drone* sun; // this drone aka planet orbits around sun
260     drone* sat; // planet's satellite
261     float ux, uy; // unit vector of sun -> planet vector
262     float len; // length of sun -> planet vector
263     float speed; // angular speed, scales apt
264     float speed0; // for toggling speed, 0
265     int dir; // -1 = clockwise; +1 = clockwise
266     float cx, cy; // center b4 chucked
267 
chucktdrone::chuckt268     chuckt () {
269       yes = 0;
270       sun = sat = 0;
271       ux = uy = 0.0f;
272       len = 0.0f;
273       speed = 1.0f;
274       speed0 = 0.0f;
275       dir = 1;
276       cx = cy = 0.0f;
277     }
278 
setdrone::chuckt279     void set (int y, drone* n) {
280       yes = y;
281       sun = n;
282     }
283 
calcdrone::chuckt284     void calc (drone* planet) {
285       len = unit_vector (ux, uy, sun->cx, sun->cy, planet->cx, planet->cy);
286       if (sat) sat->chuck.calc (sat);
287     }
288 
dedrone::chuckt289     void de () {
290       if (sat) {
291         sat->chuck.sun = sun;
292         if (sun) {
293           sun->chuck.sat = sat;
294           sat->chuck.calc (sat);
295         }
296       } else {
297         if (sun) sun->chuck.sat = 0;
298       }
299       yes = 0;
300     }
301 
302     void re (drone& p);
303 
304     void print ();
305 
306     void resettrail (drone* p);
307 
308   } chuck;
309 
310 };
311 
312 std::ostream& operator<< (std::ostream& f, drone::arrowt& aw);
313 std::istream& operator>> (std::istream&, drone::arrowt& aw);
314 std::ostream& operator<< (std::ostream&, drone::chuckt& ch);
315 std::istream& operator>> (std::istream&, drone::chuckt& ch);
316 
317 struct group {
318 	int n;
319 	std::vector<drone*> drones;
groupgroup320 	group () {n = 0;}
321 	group (std::vector<drone*> mem, int n);
membergroup322 	int member (drone* d) {
323 		std::vector<drone*>::iterator db = drones.begin (), de = drones.end();
324 		if (find (db, de, d) == de) return 0; else return 1;
325 	}
removegroup326 	int remove (drone* d) {
327 		if (erase (drones, d)) {
328 			--n;
329 			return 1;
330 		}
331 		return 0;
332 	}
333 };
334 
335 struct drone_pendulum_group : group {
336 	int orient;
337 	int depth;
338 	drone_pendulum_group (int o = 0, int d = 0) { orient = o; depth = d;}
drone_pendulum_groupdrone_pendulum_group339 	drone_pendulum_group (int o, int d, std::vector<drone*> mem, int n) : group (mem, n), orient(o), depth(d)  {}
340 };
341 
342 /*struct connect {
343   int dirty;
344   drone* d1;
345   drone* d2;
346   point<float> p1, p2;
347   double mag;
348   connect (drone* _d1, drone* _d2);
349   int eval (drone** ret);
350   void draw ();
351   void align_vel ();
352 };*/
353 
354 #endif
355