1 /*
2 * eval.cc
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 #include "state_button.h"
9 #include "capturer.h"
10 #include "binaural_drones.h"
11 #include "console.h"
12 #include "din.h"
13 #include "ui_list.h"
14 #include "fractaliser.h"
15 #include "keyboard_keyboard.h"
16 #include "main.h"
17 #include "mondrian.h"
18 #include "oscilloscope.h"
19 #include "recorder.h"
20 #include "tcl_interp.h"
21 #include "authors_note.h"
22 
add()23 state_button* capturer_t::add () {
24 #ifdef __EVALUATION__
25 	if (ncaps == 1) {
26 		cons << RED << "Can add more mouse captures in the Licensed Version of DIN Is Noise" << eol;
27 		return 0;
28 	}
29 #endif
30 	state_button* sb = new state_button;
31 	sb->set_pos (sbx, sby);
32 	sbx += state_button::SIZE2;
33 	title.add_child (sb);
34 	caps.push_back (sb);
35 	++ncaps;
36 	return sb;
37 }
38 
i_binaural_drones()39 i_binaural_drones::i_binaural_drones () : wav ("binaural-drones-waveform.crv"), waved ("binaural-drones-waveform.ed"), fdrcrv ("fader.crv"), hlp ("binaural-drones.hlp") {
40 
41 #ifdef __EVALUATION__
42 		name = "binaural-drones [Evaluation Version]";
43 #else
44 		name = "binaural-drones";
45 #endif
46 	wavlis.sb = this;
47 	waved.add (&wav, &wavlis);
48   extern curve_library wav_lib;
49 	waved.attach_library (&wav_lib);
50 	prev_mousex = prev_mousey = 0;
51 	vol_fader.sol (&fdrcrv);
52 	pitch_fader.sol (&fdrcrv);
53 	abort = 0;
54   inst = 1;
55 }
56 
57 
din(cmdlist & cl)58 din::din (cmdlist& cl) :
59 wave ("microtonal-keyboard-waveform.crv"),
60 waved ("microtonal-keyboard-waveform.ed"),
61 wavlis (wave_listener::MICROTONAL_KEYBOARD),
62 win (0, 0, view.xmax, view.ymax),
63 drone_wave ("drone.crv"),
64 droneed ("drone.ed"),
65 dronelis (wave_listener::DRONE),
66 fm ("fm", "fm.crv"),
67 am ("am", "am.crv"),
68 moded ("modulation.ed"),
69 am_delta (0.01f, 1),
70 gatr ("gr", "gater.crv"),
71 gated ("gater.ed"),
72 gatlib ("gater-patterns.lib"),
73 helptext ("din.hlp")
74 //wand0 (-1, -1)
75 {
76 #ifdef __EVALUATION__
77 		name = "microtonal-keyboard [Evaluation Version]";
78 #else
79 		name = "microtonal-keyboard";
80 #endif
81 
82     prev_mousex = prev_mousey = delta_mousex = delta_mousey = 0;
83     win_mousex = win_mousey = prev_win_mousex = prev_win_mousey = 0;
84 		tonex = toney = 0;
85 
86     current_range = 0;
87 
88     adding = 0;
89 
90     wanding = 0;
91 
92     moving_drones = 0;
93 
94     rising = falling = 0;
95 
96     n_dvap = 0;
97     dvap = 0;
98     dcol = 0;
99 
100     dap = 0;
101     n_dap = 0;
102 
103     num_drones = 0;
104 
105 		create_drone_pend = 0;
106 
107 		static const int cap = 1024;
108     selected_drones.reserve (cap);
109 
110 		scaleinfo.scl = this;
111 
112 		fdr_gater_prev_amount = 0;
113 
114 		p_am_delta = &am_delta;
115 		am_delta.depth = 0.01f;
116 
117 		rvec.reserve (cap);
118 		svec.reserve (cap);
119 		xforming = NONE;
120 
121 		num_selected_drones = num_browsed_drones = 0;
122 
123 		ptr_scaleinfo = &all_notes;
124 
125 		nstepz = 0;
126 		con_pts = 0;
127 		con_clr = 0;
128 		con_size = 0;
129 		totcon = 0;
130 		_2totcon = 0;
131 		ec = 0;
132 
133     inst = 1;
134 
135     dinfo.cen.lis = this;
136 
137 		/*butt = 50;
138 		inter_butt = butt / 4.0;
139 		ring.x = win_mousex;
140 		ring.y = win_mousey;
141 		ring.r = 5 * butt;
142 		butting = 0;*/
143 
144 }
145 
chuck()146 void din::chuck () {
147 	if (num_selected_drones > 1) {
148 #ifdef __EVALUATION__
149     if (num_selected_drones > 3) {
150       cons << RED << "Chuck with more than 3 drones possible in the Licensed Version of DIN Is Noise" << eol;
151       return;
152     }
153 #endif
154     int yes = 1;
155     drone* sun = selected_drones[0];
156     sun->chuck.set (yes, 0);
157     drone* planet = 0;
158 		for (int i = 1; i < num_selected_drones; ++i) {
159       sun->trail.set (0);
160       planet = selected_drones[i];
161       planet->chuck.set (yes, sun);
162       sun->chuck.sat = planet;
163       planet->chuck.sat = 0;
164       planet->chuck.calc (planet);
165       sun = planet;
166     }
167     planet->trail.set (10000);
168     cons << GREEN << "Chucked " << num_selected_drones << " drones" << eol;
169   } else {
170 		cons << RED_A2D << eol;
171   }
172 }
173 
create_drone_pendulum()174 void din::create_drone_pendulum () {
175 
176 #ifdef __EVALUATION__
177 	cons << RED << "Can create drone pendulums only in the Licensed Version of DIN Is Noise" << eol;
178 	return;
179 #endif
180 
181 	int o = dinfo.drone_pend.orient;
182   int no = !o;
183 	double along[] = {rgn.width, rgn.height};
184   int num_drones = dinfo.drone_pend.n;
185 
186 	CLEAR_SELECTED_DRONES
187 
188 	double xl [] = {double(rgn.left), double(rgn.midx)};
189 	double yl [] = {double((rgn.bottom + rgn.top) / 2.0), double(rgn.bottom)};
190 	double x = xl [o], y = yl [o];
191 	double* xy [] = {&x, &y};
192 	double& xyo = *xy[o];
193 	double depths [] = {double(rgn.top - rgn.midy), double(rgn.right - rgn.midx)};
194 	double depth = depths[o];
195 
196   int nd1 = num_drones - 1;
197   double spacing = along[o] * 1.0 / nd1;
198 	double _1bylast = 1.0 / nd1;
199 	double a = 0.0f, da = _1bylast;
200   float obpm = 0.0f;
201 	for (int i = 0; i < num_drones; ++i) {
202 		get_color::data.p = i * _1bylast;
203 		drone* pd = add_drone (x, y);
204 		drone& d = *pd;
205     if (!dinfo.seloncre) {
206 		  d.sel = 1;
207 		  selected_drones.push_back (pd);
208     }
209 		d.mod.active = 1;
210 		mod_params* mods [] = {&d.mod.am, &d.mod.fm};
211 		mod_params& mod = *mods[o];
212 		mod.depth = warp_depth (a) * depth;
213     obpm = warp_bpm (a) * dinfo.drone_pend.bpm;
214 		mod.bv.set_bpm (obpm);
215     mods[no]->bv.set_bpm (obpm);
216 		a += da;
217 		xyo += spacing;
218 	}
219 
220   if (!dinfo.seloncre) print_selected_drones ();
221 
222 	drone_pendulum_group* grp = new drone_pendulum_group (o, depth, selected_drones, num_selected_drones);
223 	drone_pendulums.push_back (grp);
224 
225 	uis.dpeu.bpm.set_value (dinfo.drone_pend.bpm);
226 	uis.dpeu.depth.set_value (depth);
227 
228 	cons << GREEN << "Created a drone pendulum of " << num_drones << " drones." << eol;
229 
230 }
231 
create_drone_mesh()232 void din::create_drone_mesh () {
233 	mkb_selector.mesh = 0;
234 #ifdef __EVALUATION__
235 	if (mkb_selector.rowcol > 4) {
236 		cons << RED << "Can only create a 2 x 2 drone mesh with the Evaluation Version oF DIN Is Noise" << eol;
237 		return;
238 	}
239 #endif
240 	mkb_selector.orderer = mkb_selector.orderers [dinfo.mesh_vars.order];
241 	mkb_selector.order_order ();
242 	amd.triggert = dinfo.mesh_vars.duration * 1.0f / mkb_selector.rowcol;
243 	amd.i = 0;
244 	amd.j = mkb_selector.cols;
245 
246   CLEAR_SELECTED_DRONES
247 	amd.start ();
248 
249 }
250 
change_range_note(int i,int d)251 void din::change_range_note (int i, int d) {
252 #ifdef __EVALUATION__
253 	cons << RED << "Change Left/Right Note/Octave is available in the Licensed Version of DIN Is Noise" << eol;
254 	return;
255 #endif
256 	int cn = dinfo.change_note;
257 	scale_info& si = *ptr_scaleinfo;
258 
259 	range& sr = ranges [dinfo.sel_range];
260 	if (cn)
261 		sr.change_note (i, d, si);
262 	else
263 		sr.change_octave (i, d, si);
264 
265 	int ri, rj;
266 	ri = rj = dinfo.sel_range;
267 	if (i) {
268 		int srr = dinfo.sel_range + 1;
269 		if (srr < num_ranges) {
270 			range& rsrr = ranges [srr];
271 			if (cn)
272 				rsrr.change_note (0, d, si);
273 			else
274 				rsrr.change_octave (0, d, si);
275 			ri = dinfo.sel_range; rj = srr;
276 		}
277 	} else {
278 		int srl = dinfo.sel_range - 1;
279 		if (srl > -1) {
280 			range& rsrl = ranges [srl];
281 			if (cn)
282 				rsrl.change_note (1, d, si);
283 			else
284 				rsrl.change_octave (1, d, si);
285 			ri = srl; rj = dinfo.sel_range;
286 		}
287 	}
288 
289 	if (ri == rj)
290 		refresh_drones (ri);
291 	else
292 		refresh_drones (ri, rj);
293 
294 	note& L = sr.notes[0];
295 	note& R = sr.notes[1];
296 	sprintf (BUFFER, "Left Note = %s @ %0.3f Hz, Right Note = %s @ %0.3f Hz, Hz/pixel = %0.3f", L.name.c_str(), L.hz, R.name.c_str(), R.hz, sr.hz_per_pix ());
297 	cons << YELLOW << BUFFER << eol;
298 
299 }
300 
connect_drones()301 int din::connect_drones () {
302 
303 	if (num_selected_drones < 2) {
304 		cons << RED_A2D << eol;
305 		return 0;
306 	}
307 
308 #ifdef __EVALUATION__
309 	#define MAX_CONN 4
310 	if (num_selected_drones > MAX_CONN) {
311 		cons << RED << "Can only connect upto " << MAX_CONN << " drones in the Evaluation Version of DIN Is Noise" << eol;
312 		return 0;
313 	}
314 #endif
315 
316 	if (nstepz == 0) {
317 		cons << RED << "Bad Steps value, please check Menu > Drone Tools > Steps" << eol;
318 		return 0;
319 	}
320 
321 	for (int s = 0; s < nstepz; ++s) {
322 		int ds = stepz[s];
323 		for (int i = 0, j = 0; i < num_selected_drones; ++i) {
324 			j = i + ds;
325 			if (MENU.cb_conn_wrap.state) j %= num_selected_drones;
326 			if (j < num_selected_drones) {
327 				drone* pdi = selected_drones[i];
328 				drone& di = *pdi;
329 				drone* pdj = selected_drones[j];
330 				drone& dj = *pdj;
331 				if (can_connect (pdi, pdj)) {
332 					double m = magnitude (pdi->cx, pdi->cy, pdj->cx, pdj->cy);
333 					di.connections.push_back (pdj);
334 					dj.connections.push_back (pdi);
335 					di.mags.push_back (m);
336 					dj.mags.push_back (m);
337 					++di.nconn;
338 					++dj.nconn;
339 					totcon += 2;
340 				}
341 			}
342 		}
343 	}
344 
345 	_2totcon = 2 * totcon;
346 	alloc_conns ();
347 
348   if (MENU.trackcon.state) {
349     int last = num_selected_drones - 1;
350     drone* pld = selected_drones [last];
351     drone *pdi = 0, *pdj = 0;
352     for (int i = 0, j = 1; i < last; ++i, ++j) {
353       pdi = selected_drones [i];
354       pdj = selected_drones [j];
355       push_back (trackers, pdi);
356       pdi->tracking = drone::POINT;
357       pdi->tracked_drone = pdj;
358     }
359     pld->tracking = drone::USE;
360     pld->tracked_drone = pdi;
361     push_back (trackers, pld);
362   }
363 
364 	return 1;
365 
366 }
367 
apply(multi_curve & crv)368 int fractaliser::apply (multi_curve& crv) {
369 #ifdef __EVALUATION__
370 	cons << RED << "Can apply plugins only in the Licensed Version of DIN Is Noise" << eol;
371 	return 0;
372 #endif
373   render ();
374   int npts = points.size ();
375   if (npts == 0) return 0;
376   crv.clear (0);
377 	if (change_curve_name) crv.set_name (ss.str());
378 
379 	typedef std::list< point<float> >::iterator points_list_iterator;
380 	points_list_iterator lti = left_tangents.begin (), rti = right_tangents.begin ();
381   for (int i = 0; i < npts; ++i) {
382     point<float>& p = points[i];
383     point<float>& lt = *lti++;
384     point<float>& rt = *rti++;
385     crv.add_vertex (p.x, p.y);
386     crv.add_left_tangent (lt.x, lt.y);
387     crv.add_right_tangent (rt.x, rt.y);
388   }
389   if (shapeform) crv.shapeform = 1;
390   crv.evaluate ();
391   return 1;
392 }
393 
keyboard_keyboard()394 keyboard_keyboard::keyboard_keyboard () :
395 wave ("keyboard-keyboard-waveform.crv"), waved ("keyboard-keyboard-waveform.ed"), wavlis (wave_listener::KEYBOARD_KEYBOARD),
396 attackcrv ("attack.crv"), decaycrv ("decay.crv"),
397 attacked ("attack.ed"), decayed ("decay.ed"),
398 helptext ("keyboard-keyboard.hlp"), velcrv ("velocity.crv"),
399 veled ("velocity.ed"), vellib ("velocity.lib")
400 {
401 #ifdef __EVALUATION__
402 		name = "keyboard-keyboard [Evaluation Version]";
403 #else
404 		name = "keyboard-keyboard";
405 #endif
406   last_mousex = last_mousey = -1;
407   num_triggered_notes = 0;
408 	scaleinfo.scl = this;
409 	show_nearby_notes = 0;
410 
411 	fname = "keyboard-keyboard.settings";
412 	ifstream file ((user_data_dir + fname).c_str (), ios::in);
413 	if (!file) {
414 		dlog << "!!! couldnt load: " << fname << endl;
415 	} else {
416 		string ignore;
417 		file >> ignore >> show_nearby_notes;
418 		file >> ignore >> ATTACK_TIME;
419 		file >> ignore >> DECAY_TIME;
420 		file >> ignore >> NOTE_VOLUME;
421 		file >> ignore >> PITCH_BEND;
422 		file >> ignore >> trig_what;
423 		PITCH_BEND_PER_PIXEL = 0.01f * PITCH_BEND;
424 	}
425 
426   inst = 1;
427 
428 }
429 
430 
431 extern const char* INSTRUMENTS [];
432 extern const char* INSTRUMENTS_SHORT [];
433 extern const int NUM_INSTRUMENTS, LAST_INSTRUMENT;
434 extern int CURRENT_INSTRUMENT;
435 extern string INSTRUMENT;
436 extern instrument* INSTRUMENT_PTR [];
437 extern checkbutton* LAST_TABS [];
438 extern oscilloscope scope;
439 
load_instrument(instrument * inst)440 void load_instrument (instrument* inst) {
441 
442   if (inst == 0) inst = get_current_instrument ();
443 
444   MENU.b_microtonal_keyboard.turn_off (DONT_CALL_LISTENER);
445   MENU.b_keyboard_keyboard.turn_off (DONT_CALL_LISTENER);
446   MENU.b_mondrian.turn_off (DONT_CALL_LISTENER);
447 	MENU.b_binaural_drones.turn_off (DONT_CALL_LISTENER);
448 
449   if (inst == &keybd2) {
450     MENU.b_keyboard_keyboard.turn_on ();
451 		MENU.next_tab = MENUP.cb_instrument;
452     CURRENT_INSTRUMENT = 0;
453   } else if (inst == &din0) {
454     CURRENT_INSTRUMENT = 1;
455     MENU.b_microtonal_keyboard.turn_on ();
456 		checkbutton* pcb = LAST_TABS [CURRENT_INSTRUMENT];
457 		if (pcb) {
458       MENU.next_tab = pcb;
459     } else {
460       if (din0.num_selected_drones)
461         MENU.next_tab = MENUP.cb_mkb_drone_params;
462       else
463         MENU.next_tab = MENUP.cb_mkb_voice;
464     }
465   } else if (inst == &mondrian0) {
466     CURRENT_INSTRUMENT = 2;
467     MENU.b_mondrian.turn_on ();
468     MENU.cb_instrument.turn_on ();
469 		checkbutton* pcb = LAST_TABS [CURRENT_INSTRUMENT];
470 		if (pcb) MENU.next_tab = pcb; else MENU.next_tab = MENUP.cb_mon_tools;
471   } else /*if (inst == &binaural_drones0)*/ {
472     CURRENT_INSTRUMENT = 3;
473 		MENU.b_binaural_drones.turn_on ();
474 		MENU.cb_instrument.turn_on ();
475 		checkbutton* pcb = LAST_TABS [CURRENT_INSTRUMENT];
476 		if (pcb) MENU.next_tab = pcb; else MENU.next_tab = MENUP.cb_binaural_drones_tools;
477 	}
478 
479   scope.load_current_instrument ();
480   MENU.scol.setup ();
481 
482 	MENU.next_tab_instr = inst;
483 	uis.set_current (inst);
484   MENU.hide_editors ();
485   MENU.show_editors (inst);
486 
487 #ifdef __EVALUATION__
488 	if (dynamic_cast<ui*>(inst) != &anote)
489 #endif
490 
491   MENU.setup_tabs (inst);
492 
493   setup_plugin_labels ();
494 	cons ("setup-editors");
495   uis.update_bottom_line ();
496 
497 }
498 
499 extern string VERSION_NUMBER;
500 extern string LOCATION;
501 extern string APP_NAME;
502 
make_app_name()503 void make_app_name () {
504 	#ifdef __EVALUATION__
505 		APP_NAME = "DIN Is Noise " + VERSION_NUMBER + " | EVALUATION VERSION";
506 	#elif defined __LICENSED__
507 		APP_NAME = "DIN Is Noise " + VERSION_NUMBER + " | LICENSED VERSION";
508 	#endif
509 }
510 
clicked(button & b)511 void range_mod_lis::clicked (button& b) {
512 	if (&b == MENUP.b_rm_start_all) {
513 #ifdef __EVALUATION__
514 		cons << RED << "Range modulation available only on the Licensed Version of DIN Is Noise" << eol;
515 		return;
516 #endif
517 		din0.set_ran_mod (1);
518 	} else if (&b == MENUP.b_rm_stop_all) {
519 		din0.set_ran_mod (0);
520 	} else if (&b == MENUP.b_rm_toggle) {
521 #ifdef __EVALUATION__
522 		cons << RED << "Range modulation available only on the Licensed Version of DIN Is Noise" << eol;
523 		return;
524 #endif
525 		din0.toggle_ran_mod ();
526 	} else if (&b == MENUP.b_rm_pause_resume) {
527 #ifdef __EVALUATION__
528 		cons << RED << "Range modulation available only on the Licensed Version of DIN Is Noise" << eol;
529 		return;
530 #endif
531 		din0.pause_resume_ran_mod ();
532 	} else {
533 		din0.dinfo.sel_range = din0.current_range;
534 		MENU.load_range (din0.dinfo.sel_range);
535 	}
536 }
537 
changed(checkbutton & cb)538 void range_mod_lis::changed (checkbutton& cb) {
539 
540 	if (&cb == MENUP.cb_mod_ran) {
541 #ifdef __EVALUATION__
542 		cons << RED << "Range modulation available only on the Licensed Version of DIN Is Noise" << eol;
543 		cb.set_state (!cb.state, 0);
544 		return;
545 #endif
546 		modulator& srm = din0.ranges[din0.dinfo.sel_range].mod;
547 		int& a = srm.active;
548 		if (a) a *= cb.state; else a = cb.state;
549 	} else
550 		din0.dinfo.mark_sel_range = cb.state;
551 }
552 
clicked(button & b)553 void recording_listener::clicked (button& b) {
554 	if (&b == MENUP.b_clear_record) {
555 		recorder0.clear ();
556 		uis.cb_record.set_text ("Record");
557 		MENU.cb_record.set_text ("Record");
558 		if (MENU.show) MENU.toggle ();
559 	} else {
560 #ifdef __EVALUATION__
561 		cons << RED << "Can save recordings only in the Licensed Version of DIN Is Noise" << eol;
562 		return;
563 #endif
564 		recorder0.start_saving ();
565 	}
566 }
567 
568 
clicked(button & b)569 void binaural_drones_listener::clicked (button& b) {
570 
571 	if (&b == MENUP.bbd_select_all) {
572 		MENU.il_binaural_drones.select (1); // 1 == all
573 	} else if (&b == MENUP.bbd_select_none) {
574 		MENU.il_binaural_drones.select (0); // 0 == none
575 		MENU.il_binaural_drones.last = 0;
576 	} else if (&b == MENUP.bbd_invert_select) {
577 		MENU.il_binaural_drones.invert_select ();
578 		if (MENU.il_binaural_drones.num_selected() == 0) MENU.il_binaural_drones.last = 0;
579 	} else if (&b == MENUP.bbd_select2) {
580 		if (select_rule == ID) {
581 			tokenizer tv (MENU.bdf_value.text);
582 			int s, e, i; tv >> s >> e >> i;
583 			--s; --e;  // bcos starts at 1 on ui :(
584 			clamp (0, s, MENU.il_binaural_drones.n);
585 			clamp (0, e, MENU.il_binaural_drones.n);
586 			clamp (1, i, MENU.il_binaural_drones.n);
587 			sprintf (BUFFER, "wrap-get-nums %d %d %d", s, e, i);
588 		} else {
589 			const char* get [] = {"left", "right", "separation", "volume"};
590 			const char* op [] = {"==", ">=", "<=", "<>"};
591 			sprintf (BUFFER, "filter-binaurals %s %s %s", get[select_what], op[select_rule], MENU.bdf_value.text.c_str());
592 		}
593 		interpreter (BUFFER);
594 		tokenizer tz (interpreter.result);
595 		if (!MENU.il_binaural_drones.select_these (tz)) cons << RED << "No matching binaural drone pairs found!" << eol;
596 	}
597 
598 	if (binaural_drones0.busy ()) {
599 		cons << RED << "Still executing your command, please wait or ESC to abort" << YELLOW << eol;
600 		return;
601 	}
602 
603 	binaural_drones0.separation = MENU.sp_bd_separation.f_value;
604 	binaural_drones0.master_volume = (float)MENU.lf_master_volume.fld / 100.0f;
605 	binaural_drones0.pairs = MENU.sp_bd_pairs.f_value;
606 	binaural_drones0.close_octave = MENU.cb_close_octave.state;
607 	binaural_drones0.resize_separation = MENU.cb_resize_separation.state;
608 
609 	const char* selerr = "Please select some binaural drone pairs";
610 	if (&b == MENUP.b_create_binaurals_on_notes) {
611 
612 #ifdef __EVALUATION__
613 	cons << RED << "Available only in the Licensed Version of DIN Is Noise" << eol;
614 	return;
615 #endif
616 
617 		cons << YELLOW << "Creating binaural drones [fading in], please wait" << eol;
618 		float tonic;
619 		if (binaural_drones0.keynote == i_binaural_drones::START_PITCH)
620 			tonic = binaural_drones0.starting_pitch;
621 		else
622 			tonic = get_tonic (&binaural_drones0);
623 		string intervals;
624 		vector<string>& notes = binaural_drones0.scaleinfo.notes;
625 		int j = notes.size (); if (binaural_drones0.close_octave == 0) --j;
626 		for (int i = 0; i < j; ++i) intervals = intervals + notes[i] + " ";
627 		stringstream cmd;
628 		cmd << "create-binaurals-on-notes " << tonic << ' ' << binaural_drones0.separation << " {" << intervals << "}" << ' ' << binaural_drones0.resize_separation;
629 		interpreter (cmd.str());
630 		MENU.changed (MENU.cb_binaural_drones_edit);
631 	} else if (&b == MENUP.b_create_binaurals_from_pitch) {
632 
633 #ifdef __EVALUATION__
634 	if (binaural_drones0.num_binaural_drones || binaural_drones0.pairs > 1) {
635 		cons << RED << "Can create > 1 binaural drone pair in the Licensed Version of DIN Is Noise" << eol;
636 		return;
637 	}
638 #endif
639 
640 		cons << YELLOW << "Creating binaural drones [fading in], please wait" << eol;
641 		string start_pitch = MENU.lf_bd_start_pitch.fld.text;
642 		string spacing = MENU.lf_bd_spacing.fld.text;
643 		sprintf (BUFFER, "create-binaurals-from-pitch %f %f %d %f", binaural_drones0.starting_pitch, binaural_drones0.separation, binaural_drones0.pairs, binaural_drones0.spacing);
644 		interpreter (BUFFER);
645 		MENU.changed (MENU.cb_binaural_drones_edit);
646 	} else if (&b == MENUP.bbd_sync) {
647 		if (MENU.il_binaural_drones.num_selected ()) {
648 			cons << YELLOW << "Syncing (fade-out + sync + fade-in) : please wait or ESC to abort" << eol;
649 			interpreter ("sync-selected-binaurals");
650 		} else {
651 			cons << RED << selerr << eol;
652 		}
653 	} else if (&b == MENUP.bbd_delete) {
654 		if (MENU.il_binaural_drones.num_selected ()) {
655 			cons << YELLOW << "Deleting (after fade-out) : please wait or ESC to abort" << eol;
656 			interpreter ("delete-selected-binaurals");
657 		} else {
658 			cons << RED << selerr << eol;
659 		}
660 	} else if (&b == MENUP.bd_modulate_up) {
661 		if (MENU.il_binaural_drones.num_selected ()) {
662 			cons << YELLOW << "Modulating up: please wait or ESC to abort" << eol;
663 			sprintf (BUFFER, "modulate-selected-binaurals %f", binaural_drones0.modulation_amount);
664 			interpreter (BUFFER);
665 		} else {
666 			cons << RED << selerr << eol;
667 		}
668 	} else if (&b == MENUP.bd_modulate_down) {
669 		if (MENU.il_binaural_drones.num_selected ()) {
670 			cons << YELLOW << "Modulating down: please wait or ESC to abort" << eol;
671 			sprintf (BUFFER, "modulate-selected-binaurals %f", 1.0f / binaural_drones0.modulation_amount);
672 			interpreter (BUFFER);
673 		} else {
674 			cons << RED << selerr << eol;
675 		}
676 	} else if (&b == MENUP.bbd_flip) {
677 		if (MENU.il_binaural_drones.num_selected ()) {
678 			for (int i = 0; i < MENU.il_binaural_drones.n; ++i) {
679 				if (MENU.il_binaural_drones.items[i].sel) {
680 					binaural_drone* bi = binaural_drones0.binaural_drones[i];
681 					float r_hz = bi->l_hz, l_hz = bi->r_hz;
682 					bi->set_hz (binaural_drone::LEFT, l_hz);
683 					bi->set_hz (binaural_drone::RIGHT, r_hz);
684 				}
685 			}
686 			binaural_drones0.pitch_fader.start ("Pitch flip");
687 			cons << YELLOW << "Flipping Hz: please wait or ESC to abort" << eol;
688 			interpreter ("flip-selected-binaurals");
689 		} else {
690 			cons << RED << selerr << eol;
691 		}
692 	}
693 }
694 
695 
load_settings(ifstream & file)696 void mondrian::load_settings  (ifstream& file) {
697 
698   std::string ignore;
699 
700 #ifdef __EVALUATION__
701 		name = "Mondrian [Evaluation Version]";
702 #else
703 		name = "Mondrian";
704 #endif
705 
706   float l, b, r,  t;
707   file >> ignore >> l >> b >> r >> t;
708   win.set (l, b, r, t);
709 
710   file >> ignore >> win_chunk.x >> win_chunk.y;
711   file >> ignore >> obj_chunk.x >> obj_chunk.y;
712 
713   win_per_obj (win_chunk.x / obj_chunk.x, win_chunk.y / obj_chunk.y);
714   obj_per_win (obj_chunk.x / win_chunk.x , obj_chunk.y / win_chunk.y);
715 
716   file >> ignore >> win_resolution;
717   float dummy1 = 0, dummy2 = 0;
718   win2obj (win_resolution, dummy1, obj_resolution, dummy2);
719 
720 	file >> ignore >> label_hz_vol;
721 	file >> ignore >> min_voices;
722 	file >> ignore >> auto_del_rect.active;
723 	file >> ignore >> auto_del_rect.triggert;
724 	file >> ignore >> auto_split_rect.active;
725 	file >> ignore >> auto_split_rect.triggert;
726 	file >> ignore >> auto_split_orient;
727 	file >> ignore >> auto_split_at;
728 	file >> ignore >> split_leaf;
729 	file >> ignore >> delete_leaf;
730 	file >> ignore >> mondrian::min_split_size;
731 	file >> ignore >> draw__boxes;
732 	file >> ignore >> draw_ball.position;
733 	file >> ignore >> draw_ball.heading;
734 	file >> ignore >> draw__notes;
735 	file >> ignore >> label_notes;
736 	file >> ignore >> fill_boxes;
737 	file >> ignore >> num_boxes;
738 	file >> ignore >> added_ball_type;
739 	file >> ignore >> cursor;
740 	file >> ignore >> auto_adjust_voices;
741 	file >> ignore >> slit::HALF_SIZE;
742 	file >> ignore >> MENU.cb_turn_sync.state;
743 	file >> ignore >> MENU.cb_speed_sync.state;
744 	MENU.cb_turn_sync.set_state (MENU.cb_turn_sync.state);
745 	MENU.cb_speed_sync.set_state (MENU.cb_speed_sync.state);
746 
747 }
748 
749 
750 extern float MIN_TIME;
751 extern int can_wheel ();
752 extern int IPS;
753 
handle_input()754 int mondrian::handle_input () {
755 
756   if (moving_balls) move_balls (win.mousex - win.mousex_prev, win.mousey - win.mousey_prev);
757 	if (editing_slit) slit_lip.edit (); else
758 	if (editing_edge) set_edge (hit, edge, win.mousex, win.mousey);
759 
760   if (lmb) {
761 		if (lmb_clicked == 0) {
762 			if (stop_moving_balls ());
763 			else if (stop_editing_slit ());
764 			else if (stop_editing_edge ());
765 			else if (try_slitting ());
766 			else {
767 				finding f; find (root, win.mousex, win.mousey, f);
768 				hit = f.found;
769 				if (hit) { // box hit
770 					box<float>& bf = hit->extents;
771 					edge = bf.get_edge_hit (win.mousex, win.mousey, gutter2);
772 					if (edge != edge::NONE) { // edge hit
773 						// slit hit?
774 						slit_lip.slitt = 0;
775 						float* curs [rect::nedges] = {&win.mousex, &win.mousey, &win.mousex, &win.mousey};
776 						slit_lip.cur = curs[edge];
777 						if (get_slit_lip (slit_lip, hit, edge, *slit_lip.cur)) { // slit hit!
778 							float* prevs [rect::nedges] = {&win.mousex_prev, &win.mousey_prev, &win.mousex_prev, &win.mousey_prev};
779 							slit_lip.prev = prevs[edge];
780 							toggle_flag (editing_slit, "Just move mouse to edit slit. ESC to stop."); // edit this slit
781 						} else toggle_flag (editing_edge, "Just move mouse to move edge. ESC or click to stop."); // edit this edge
782 						mon_selector.abort ();
783 					}
784 				}
785 			}
786 		}
787 
788 		if (adding_balls) { // user is adding balls
789       if (started_making_ball == 0) {
790         started_making_ball = 1;
791         new_ball = new ball (added_ball_type);
792         new_ball->set_velocity (1.0f, 1.0f);
793 				mon_selector.abort ();
794       } else {
795 				float dx, dy;
796 				win.diff_mouse (dx, dy);
797 				if (dx == 0 && dy == 0); else new_ball->set_velocity (dx, dy);
798 				new_ball->x = win.mousex;
799 				new_ball->y = win.mousey;
800       }
801     }
802 
803 		lmb_clicked = 1;
804 
805   } else {
806 		lmb_clicked = 0;
807 		if (new_ball) {
808 			new_ball->frozen = 0;
809 			finding f; find (root, new_ball->x, new_ball->y, f);
810 #ifdef __EVALUATION__
811 			if (num_balls) {
812 				cons << RED << "Can create more balls in the Licensed Version of DIN Is Noise" << eol;
813 				f.found = 0;
814 			}
815 #endif
816 			if (f.found) {
817 				new_ball->R = f.found;
818 				f.found->balls.push_back (new_ball);
819 				balls.push_back (new_ball);
820 				browse.clear ();
821 				clear_selected<ball> (selected_balls, num_selected_balls);
822 				new_ball->select = 1;
823 				selected_balls.push_back (new_ball);
824 				++num_selected_balls;
825 				++num_balls;
826 				after_selection ();
827 			} else
828 				delete new_ball;
829 
830 			started_making_ball = 0;
831     	new_ball = 0;
832 		}
833   }
834 
835 	static const double reptf = 1./7, repts = 1./48.;
836 	double repts1 = 1./IPS;
837 
838 	// octave shift
839   if (keypressed (SDLK_z)) {if (!modulate_balls (-1)) modulate_down ();}
840   else if (keypressed (SDLK_x)) {if (!modulate_balls (1)) modulate_up ();}
841 
842   // split box
843   if (keypressed (SDLK_r)) { // vertically
844     if (recting ()) ; else {
845       if (SHIFT)
846         multi_split_rect (split::VERTICAL); // vertically at notes
847       else if (CTRL)
848         multi_split_rect (num_boxes, split::VERTICAL); // vertically make num_boxes
849       else
850         split_rect (split::VERTICAL, win.mousex); // into 2 new boxes
851     }
852 	}
853   else if (keypressed (SDLK_f)) { // horizontally
854     if (recting ()) ; else {
855       if (SHIFT)
856         multi_split_rect (split::HORIZONTAL); // horizontally at notes
857       else if (CTRL)
858         multi_split_rect (num_boxes, split::HORIZONTAL); // horizontally make num_boxes
859       else
860         split_rect (split::HORIZONTAL, win.mousey); // into 2 new boxes
861     }
862 	}
863 	else if (keypressed (SDLK_t)) {
864     if (recting ()) ; else {
865       if (SHIFT || CTRL)
866         make_nxn_grid (); // make grid of num_boxes x num_boxes
867       else
868         make_note_grid (); // make note grid
869     }
870 	}
871 
872 	if (keypressed(SDLK_RETURN)) toggle_triggered_sound ();
873 
874 	// change ball speed
875 	static const float delta_speed = 0.25;
876   if (keypressedd (SDLK_LEFTBRACKET)) change_speed (MENU.sp_mondrian_change_speed, -delta_speed);
877   else if (keypressedd (SDLK_RIGHTBRACKET)) change_speed (MENU.sp_mondrian_change_speed, delta_speed);
878 
879 	// change ball attack & decay time
880 	if (keypressedd (SDLK_SEMICOLON, reptf, repts)) {
881 		if (SHIFT) {
882 			delta_attack_time -= MIN_TIME;
883 			if (delta_attack_time < MIN_TIME) delta_attack_time = MIN_TIME;
884       sprintf (BUFFER, "delta attack time = %0.3f secs", delta_attack_time);
885       cons << BUFFER << eol;
886 		} else
887 			--MENU.sp_mondrian_change_attack_time;
888 	}
889 	else if (keypressedd (SDLK_QUOTE, reptf, repts)) {
890     if (SHIFT) {
891       delta_attack_time += MIN_TIME;
892       sprintf (BUFFER, "delta attack time = %0.3f secs", delta_attack_time);
893       cons << BUFFER << eol;
894     } else
895       ++MENU.sp_mondrian_change_attack_time;
896 	}
897 	else if (keypressedd (SDLK_COMMA, reptf, repts)) {
898      if (SHIFT) {
899        delta_decay_time -= MIN_TIME;
900        if (delta_decay_time < MIN_TIME) delta_decay_time = MIN_TIME;
901        sprintf (BUFFER, "delta decay time = %0.3f secs", delta_decay_time);
902        cons << BUFFER << eol;
903      } else
904        --MENU.sp_mondrian_change_decay_time;
905 	}
906 	else if (keypressedd (SDLK_PERIOD, reptf, repts)) {
907       if (SHIFT) {
908         delta_decay_time += MIN_TIME;
909         sprintf (BUFFER, "delta decay time = %0.3f secs", delta_decay_time);
910         cons << BUFFER << eol;
911       } else
912         ++MENU.sp_mondrian_change_decay_time;
913 	}
914 
915 	// change ball course
916 	if (keypressedd (SDLK_o, reptf, repts1)) {
917 		if (CTRL)
918 			toggle_auto_rotate (1); // always change anti-clockwise
919 		else  if (SHIFT) {
920 			change_ball_dtheta (-1);
921 		}
922 		else
923 			rotate_velocity (+1);
924 	} else if (keypressedd (SDLK_p, reptf, repts1)) {
925 		if (CTRL)
926 			toggle_auto_rotate (-1); // always change clockwise
927 		else if (SHIFT) {
928 			change_ball_dtheta (+1);
929 		}
930 		else
931 			rotate_velocity (-1); // rotate velocity vector clockwise
932 	}
933 
934 	// ball / slit selection
935   if (keypressed (SDLK_l)) {
936     select_all_targets ();
937   } else if (keypressed (SDLK_i)) {
938     if (SHIFT)
939 			MENU.cb_label_hz_vol.toggle (); // label pitch/volume of triggered notes
940 		else
941 			invert_selected_targets ();
942 	} else if (keypressed (SDLK_k)) { // box
943 		select_box_targets ();
944 	} else if (keypressed (SDLK_n)) {
945 		clear_selected_targets ();
946 	}
947 
948   // ball browsing
949   if (keypressedd (SDLK_LEFT)) browse_ball (-1); // MENU.bolis.picked (MENU.ol_browse_balls.option, -1);
950   else if (keypressedd (SDLK_RIGHT)) browse_ball (+1); // MENU.bolis.picked (MENU.ol_browse_balls.option, +1);
951 
952   // freeze/thaw balls
953   if (keypressed (SDLK_SPACE)) {
954 		list<ball*>& balls = get_balls ();
955 		if (SHIFT) freeze_balls (balls);
956 		else if (CTRL) thaw_balls (balls);
957 		else freeze_thaw_balls (balls);
958 	}
959 
960 	if (keypressed (SDLK_j)) flip_velocity (); // flip ball velocity ie flips ball direction
961 
962 	if (keypressedd (SDLK_KP_PLUS, reptf, repts)) ++MENU.sp_mondrian_change_slit_size;
963 	else if (keypressedd (SDLK_KP_MINUS, reptf, repts)) --MENU.sp_mondrian_change_slit_size;
964 
965 	if (keypressedd (SDLK_MINUS, reptf, repts)) --MENU.sp_mondrian_change_trail_size;
966 	else if (keypressedd (SDLK_EQUALS, reptf, repts)) ++MENU.sp_mondrian_change_trail_size;
967 
968   if (keypressed (SDLK_b)) {
969 		if (SHIFT) do_add_balls (ball::WRECKER);
970 		else if (CTRL) do_add_balls (ball::HEALER);
971 		else do_add_balls (); // add bouncers
972 	}
973 
974   if (keypressed (SDLK_m)) do_move_balls (); // move balls
975 	if (keypressed (SDLK_c)) delete_selected_targets ();
976 
977 	if (keypressedd (SDLK_y)) change_min_voices (-1);
978 	else if (keypressedd (SDLK_u)) change_min_voices (+1);
979 
980 	if (keypressed (SDLK_F9)) remove_slits_on_current_edge ();
981 	else if (keypressed (SDLK_F10)) remove_slits_on_current_box ();
982 	else if (keypressed (SDLK_F11)) remove_slits_on_boxes_with_balls ();
983 	else if (keypressed (SDLK_F12)) remove_all_slits ();
984 
985 	if (keypressed (SDLK_F3)) toggle_balls_type (ball::WRECKER);
986 	else if (keypressed (SDLK_F4)) toggle_balls_type (ball::HEALER);
987 	else if (keypressed (SDLK_F5)) toggle_balls_type (ball::BOUNCER);
988 	else if (keypressed (SDLK_F6)) switch_balls_type ();
989 	else if (keypressed (SDLK_F7)) select_type (ball::WRECKER);
990 	else if (keypressed (SDLK_F8)) select_type (ball::HEALER);
991 
992 	if (keypressed (SDLK_v)) {
993     if (recting()) ; else {
994       if (SHIFT) delete_all_rects = !delete_all_rects;
995       else
996         delete_current_rect ();
997     }
998 	}
999 
1000 	if (keypressed (SDLK_g)) {
1001 		MENU.monl.picked (MENU.ol_selection_targets.option, +1);
1002 		if (sel_tar == SELECT_BALLS)
1003 			cons << GREEN << "Selection target: balls" << eol;
1004 		else
1005 			cons << GREEN << "Selection target: slits" << eol;
1006 	}
1007 
1008 	if (keypressed (SDLK_h)) toggle_slit_anim ();
1009 
1010   if (!mouse_slider0.active) {
1011     if (keypressedd (SDLK_9)) {
1012         if (SHIFT) --MENU.sp_mondrian_change_note_poly_radius; else --MENU.sp_mondrian_change_note_poly_points;
1013     } else if (keypressedd (SDLK_0)) {
1014       if (SHIFT) ++MENU.sp_mondrian_change_note_poly_radius; else ++MENU.sp_mondrian_change_note_poly_points;
1015     }
1016   }
1017 
1018 	if (keypressed (SDLK_SLASH)) {if (!mouse_slider0.active) start_slitting ();}
1019 	else if (keypressedd (SDLK_INSERT)) ++MENU.sp_mondrian_change_slit_anim_time;
1020 	else if (keypressedd (SDLK_DELETE)) --MENU.sp_mondrian_change_slit_anim_time;
1021 
1022   if (keypressed (SDLK_F1)) _help ();
1023 
1024 	// movement
1025 	if (can_wheel ()) do_zoom (-wheel * zoom);
1026 	double pan_rept = window::PAN_REPEAT, zoom_rept = window::ZOOM_REPEAT;
1027 	if  (keypressedd (SDLK_a, pan_rept, pan_rept)) do_panx (-pan);
1028 	else if (keypressedd (SDLK_d, pan_rept, pan_rept)) do_panx (+pan);
1029 	else if (keypressedd (SDLK_w, pan_rept, pan_rept)) do_pany (+pan);
1030 	else if (keypressedd (SDLK_s, pan_rept, pan_rept)) do_pany (-pan);
1031 
1032   if (!mouse_slider0.active) {
1033     if (keypressedd (SDLK_q, zoom_rept, zoom_rept)) do_zoom (+zoom); // zoom out
1034     else if (keypressedd (SDLK_e, zoom_rept, zoom_rept)) do_zoom (-zoom);  // zoom in
1035   }
1036 
1037   return 1;
1038 }
1039 
clone_ball(ball * b)1040 void mondrian::clone_ball (ball* b) {
1041 #ifdef __EVALUATION__
1042       if (num_balls) cons << RED << "Can clone balls in the Licensed Version of DIN Is Noise" << eol;
1043       return;
1044 #endif
1045   ball* cb = new ball;
1046   b->clone_this (cb);
1047   locate_ball (cb);
1048   balls.push_back (cb);
1049   ++num_balls;
1050 }
1051 
apply(multi_curve & crv)1052 int plugin::apply (multi_curve& crv) {
1053 
1054 #ifdef __EVALUATION__
1055 	cons << RED << "Can apply plugins only in the Licensed Version of DIN Is Noise" << eol;
1056 	return 0;
1057 #endif
1058 
1059   int n = points.size ();
1060   if (n == 0) return 0;
1061 
1062   crv.clear (0);
1063 
1064 	for (int i = 0; i < n; ++i) {
1065     point<float>& p = points[i];
1066     crv.add_vertex (p.x, p.y);
1067     crv.add_left_tangent (p.x, p.y);
1068     crv.add_right_tangent (p.x, p.y);
1069 	}
1070 
1071   if (shapeform)
1072 		crv.set_shapeform (1);
1073 	else
1074 		crv.evaluate ();
1075 
1076 	CRVED->set_curve_style ();
1077 
1078   return 1;
1079 
1080 }
1081 
add(hit_t & h)1082 state_button* point_modulator::add (hit_t& h) {
1083 #ifdef __EVALUATION__
1084 	if (nlst == 1) {
1085 		cons << RED << "Can add more point modulators in the Licensed Version of DIN Is Noise" << eol;
1086 		return 0;
1087 	}
1088 #endif
1089 	on_lst (_desel);
1090 	state_button* sb = new state_button;
1091 	sb->set_pos (sbx, sby);
1092 	sbx += state_button::SIZE2;
1093 	title.add_child (sb);
1094 	const float bpm = 5.0f;
1095 	mod_dat md (h, sb, bpm);
1096 	lst.push_back (md);
1097 	++nlst;
1098 	sb->set_listener (this);
1099 	sb->set_state (1);
1100 
1101 	set_title ();
1102 	return sb;
1103 }
1104 
1105 
handle_input()1106 int ui_list::handle_input () {
1107 
1108   // handle quit
1109   //
1110   #ifdef __MACOSX_CORE__
1111   if (keydown (SDLK_LMETA) && keypressed (SDLK_q)) { // command key + q  on mac os x
1112     quit = IMMEDIATE;
1113     return 1;
1114   }
1115 	#else
1116 	if (ALT && keypressed (SDLK_F4)) { // alt + f4 on windows & linux
1117     quit = IMMEDIATE;
1118 		return 1;
1119 	}
1120 	#endif
1121 
1122 
1123   // handle widgets
1124 	//
1125   basic_editor::hide_cursor = mouse_slider0.active;
1126 	if (widget::focus) { // handle input of widget with focus
1127 		widget::focus->handle_input ();
1128 		return 1;
1129 	} else {
1130 		vector<widget*> widgets = widgets_of [current];
1131 		for (vector<widget*>::size_type i = 0, j = widgets.size (); i < j; ++i) {
1132 			widget* wi = widgets[i];
1133 			if (wi->visible && wi->enabled) {
1134 				wi->handle_input ();
1135 				if (widget::focus) return 1;
1136 			}
1137 		}
1138 	}
1139 
1140 	// toggle menu
1141 	//
1142 	#ifdef __EVALUATION__
1143 		if (current != &anote) { // no menu on author's note
1144 	#endif
1145 		if (rmb) {
1146 			if (!rmb_clicked) {
1147 				rmb_clicked = 1;
1148 				if (escape_from_things ());
1149 				else main_menu.toggle ();
1150 			}
1151 		} else rmb_clicked = 0;
1152 	#ifdef __EVALUATION__
1153 	}
1154 	#endif
1155 
1156   // handle current screen
1157   current->handle_input ();
1158 
1159   if (keypressed (SDLK_BACKQUOTE)) { // flip to last screen
1160     if (prev) {
1161       if (prev->ed) load_editor (prev);
1162       else if (prev->inst) load_instrument (dynamic_cast<instrument*>(prev));
1163       else set_current (prev); // settings screen for now
1164     }
1165   }
1166 
1167   if (mouse_slider0.active == 0) {
1168     if (keypressed (SDLK_1)) { // switch instrument
1169       if (current->inst) goto_next_instrument (); // else back to current instrument
1170       load_instrument ();
1171     } else { // load editors attached to keys 2 - 8
1172       for (int i = 0; i < MAX_EDITORS; ++i) {
1173         if (keypressed (key[i])) {
1174           ui* edi = ed[i];
1175           if (edi) load_editor (edi);
1176         }
1177       }
1178     }
1179   }
1180 
1181 	/*if (keypressed(SDLK_RETURN)) {
1182     if (alt_down ()) { // clear recording
1183 			main_menu.recl.clicked (main_menu.b_clear_record);
1184     } else if (CTRL) { // start recording
1185 			if (cb_record.state == 0) cb_record.turn_on (); else cb_record.turn_off ();
1186     }
1187 	}*/
1188 
1189 	if (keypressed (SDLK_F2)) {
1190 		if (UI_OFF) turn_on_ui (); else turn_off_ui ();
1191 	}
1192 
1193 	if (keypressed (SDLK_PAUSE)) {
1194 		scope.visible = !scope.visible;
1195 		main_menu.cb_scope.set_state (scope.visible, 0);
1196 	}
1197 
1198 	if (keypressed (SDLK_MENU)) main_menu.mbl.clicked (main_menu.b_menu);
1199 
1200   if (keypressed (SDLK_ESCAPE)) {
1201     if (UI_OFF) turn_on_ui ();
1202     else if ( escape_from_things() ) ;
1203 		else { // ask to press esc again to really quit
1204 			esc:
1205 			if (esct == -1) {
1206 				cons << console::red << "Press ESC again to quit" << eol;
1207 				esct = ui_clk();
1208 			} else {
1209 				double dt = ui_clk() - esct;
1210 				if (dt > 1.0) { // 1 sec timeout
1211 					esct = -1;
1212 					goto esc;
1213 				} else if (quit != TRY) try_quit ();
1214 			}
1215 		}
1216   }
1217 
1218   return 1;
1219 
1220 }
1221 
1222 extern ui* SCREENS [];
setup()1223 void ui_list::setup () {
1224 
1225 	// all screens
1226 	int nscreens = 40;
1227 	uis.resize (nscreens);
1228 	uis[0] = 0;
1229 	ui** si = SCREENS;
1230 	for (int i = 1; i < nscreens; ++i, ++si) uis[i] = *si;
1231 
1232 	// bottom line
1233   int dirs [] = {arrow_button::left, arrow_button::right, arrow_button::up, arrow_button::down};
1234   arrow_button* scrl [] = {&ab_scroll_left, &ab_scroll_right, &ab_scroll_up, &ab_scroll_down};
1235   for (int i = 0; i < 4; ++i) {
1236     arrow_button* si = scrl[i];
1237     si->set_dir (dirs[i]);
1238     si->set_size (12);
1239     si->set_listener (&sal);
1240     si->click_repeat = 1;
1241     si->first_repeat_time = 0.005;
1242     si->subsequent_repeat_time = 0.015;
1243   }
1244 
1245   cb_voice.set_listener (&vlis);
1246   cb_voice.colorize (0);
1247 
1248   cb_gater.set_listener (&glis);
1249   cb_gater.colorize (0);
1250 
1251   cb_delay.set_listener (&dlis);
1252   cb_delay.colorize (0);
1253 
1254   cb_compress.set_listener (&clis);
1255 
1256   b_settings.set_listener (&slis);
1257 
1258 	cb_record.set_listener (&main_menu.recl);
1259 
1260 	sp_voices.set ("Voices", 1, 1, MILLION, &vov, 0);
1261 	sp_attack_time.set ("Attack time", 0.1f, 0.0f, MILLION, &atv, 0);
1262 	sp_decay_time.set ("Decay time", 0.1f, 0.0f, MILLION, &dkv, 0);
1263 	sp_pitch_bend.set ("Hz/Pixel", 0.01f, 0.0f, MILLION, &pbl, 0);
1264 	sp_octave_shift_bpm.set ("BPM", 1, 0.0f, MILLION, &osl, 0);
1265 
1266 	cb_show_nearby_notes.set_listener (&pbl);
1267 	cb_show_nearby_notes.turn_off ();
1268 
1269   // waveform display
1270   //
1271   l_waveform_display.set_text ("Waveform");
1272 
1273   ab_prev_wav.set_dir (arrow_button::left);
1274   ab_prev_wav.set_listener (&wdl);
1275   ab_next_wav.set_dir (arrow_button::right);
1276   ab_next_wav.set_listener (&wdl);
1277 
1278   ab_prev_wav.click_repeat = ab_next_wav.click_repeat = 1;
1279   ab_prev_wav.first_repeat_time = ab_next_wav.first_repeat_time = 0.33;
1280   ab_prev_wav.subsequent_repeat_time = ab_next_wav.subsequent_repeat_time = 1/20.;
1281 
1282   cd_waveform_display.set_size (96, 96);
1283   cd_waveform_display.crv = &keybd2.wave; // keyboard-keyboard's waveform
1284   cd_waveform_display.calc_bbox ();
1285 
1286 	// octave shift
1287   l_octave_shift.set_text ("Octave Shift");
1288   ab_octave_down.set_dir (arrow_button::left);
1289   ab_octave_down.set_listener (&osl);
1290   ab_octave_up.set_dir (arrow_button::right);
1291   ab_octave_up.set_listener (&osl);
1292 	int arrow_size = 24;
1293   ab_octave_up.set_size (arrow_size);
1294   ab_octave_down.set_size (arrow_size);
1295 	b_abort_octave_shift.set_text ("Abort");
1296 	b_abort_octave_shift.set_listener (&main_menu.aosl);
1297 
1298 	// keys trigger? notes or noise
1299 	ol_trig_what.set_listener (&twl);
1300 
1301 	DEFINE_PARAMETERS
1302   widget_load ("d_parameters", pw, npars);
1303 	for (int i = 1; i < npars; ++i) {
1304 		d_parameters.add_child (pw[i]);
1305 		//pw[i]->set_moveable(1);
1306 	}
1307 
1308 	d_parameters.set_name ("Parameters");
1309 	d_parameters.set_moveable (1);
1310 
1311   ab_parameters.set_listener (&pal);
1312 
1313   cb_voice.set_state (din0.dinfo.voice);
1314   cb_gater.set_state (din0.dinfo.gater);
1315   cb_delay.set_state (din0.dinfo.delay);
1316   cb_compress.set_state (din0.dinfo.compress);
1317 
1318 	cb_show_pitch_volume_board.set_listener (&spvl);
1319 	cb_show_pitch_volume_drones.set_listener (&spvl);
1320 
1321 #ifdef __EVALUATION__
1322   anote.setup ();
1323 #endif
1324 
1325   plugin__browser.setup ();
1326   settings_scr.setup ();
1327   main_menu.setup ();
1328 
1329 }
1330 
nagscr()1331 void nagscr () {
1332 	#ifdef __EVALUATION__
1333 		cons.clear ();
1334 		uis.set_current (&anote); // nag screen :(
1335 	#elif defined __LICENSED__
1336   	load_instrument (); // open with last used instrument
1337 	#endif
1338 }
1339 
startwanding()1340 void drone_commands_listener::startwanding () {
1341   int* flags [] = {&din0.adding, &din0.wanding};
1342   static const char* mesg [] = {"Click to add drones, ESC or Right Click to stop", "Just move mouse to add drones, ESC or Right Click to stop"};
1343   din0.adding = din0.wanding = 0;
1344   *flags[din0.dinfo.wand] = 1;
1345 #ifdef __EVALUATION__
1346   if (din0.wanding) {
1347     din0.wanding = 0;
1348     cons << RED << "Wand only available in the Licensed Version of DIN Is Noise" << eol;
1349     return;
1350   }
1351 #endif
1352   cons << GREEN << mesg[din0.dinfo.wand] << eol;
1353 }
1354 
clicked(button & b)1355 void drone_commands_listener::clicked (button& b) {
1356 	int toggle = 1;
1357   if (&b == MENUP.ol_add_wand.option) startwanding (); else
1358 	if (&b == MENUP.b_delete_drones) din0.delete_selected_drones (); else
1359 	if (&b == MENUP.b_select_all_drones) {toggle = 0; din0.select_all_drones ();} else
1360   if (&b == MENUP.b_launch_drones) din0.make_launchers (); else
1361 	if (&b == MENUP.b_orbit_selected_drones) din0.orbit_selected_drones (); else
1362 	if (&b == MENUP.b_freeze_drones) din0.freeze_drones (); else
1363 	if (&b == MENUP.b_thaw_drones) din0.thaw_drones (); else
1364 	if (&b == MENUP.b_select_launchers) {toggle = 0; din0.select_launchers (); } else
1365 	if (&b == MENUP.b_set_targets) din0.set_targets (); else
1366 	if (&b == MENUP.b_select_attractors) {toggle = 0; din0.select_attractors (); } else
1367 	if (&b == MENUP.b_select_attractees) {toggle = 0; din0.select_attractees (); } else
1368 	if (&b == MENUP.b_stop_launching_drones) din0.destroy_launchers (); else
1369 	if (&b == MENUP.b_invert_drone_selection) {toggle = 0; din0.invert_selected_drones();} else
1370   if (&b == MENUP.b_track_drones) din0.make_trackers (); else
1371 	if (&b == MENUP.b_select_tracked_drones) {toggle = 0; din0.select_tracked_drones (); } else
1372 	if (&b == MENUP.ol_create_this.option) din0.toggle_create_this (); else
1373 	if (&b == MENUP.b_clear_targets) din0.clear_targets(); else
1374 	if (&b == MENUP.b_flip_rows_cols) {
1375 		int r = MENU.sp_mesh_rows.f_value, c = MENU.sp_mesh_cols.f_value;
1376 		MENU.sp_mesh_rows.set_value (c);
1377 		MENU.sp_mesh_cols.set_value (r);
1378 		din0.dinfo.rows = c;
1379 		din0.dinfo.cols = r;
1380 		mkb_selector.set_mesh (din0.meshh.create, din0.dinfo.rows, din0.dinfo.cols);
1381 		MENU.picked (MENU.ol_mesh_point.option, 0);
1382 		toggle = 0;
1383 	}
1384 	if (toggle) MENU.toggle ();
1385 }
1386