Rev 2110 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2108 | jag | 1 | |
964 | jag | 2 | /* |
3 | * number.cc |
||
2302 | jag | 4 | * DIN Is Noise is copyright (c) 2006-2025 Jagannathan Sampath |
1713 | jag | 5 | * DIN Is Noise is released under GNU Public License 2.0 |
1479 | jag | 6 | * For more information, please visit https://dinisnoise.org/ |
964 | jag | 7 | */ |
8 | |||
9 | |||
10 | #include "number.h" |
||
11 | #include "vector2d.h" |
||
12 | #include "ui_list.h" |
||
13 | #include "multi_curve.h" |
||
14 | #include "tcl_interp.h" |
||
15 | #include <vector> |
||
16 | #include <fstream> |
||
17 | |||
18 | using namespace std; |
||
19 | |||
20 | extern ui_list uis; |
||
21 | |||
1461 | jag | 22 | number::number () : slw (255), slh (10), sl_red (0, slw, slh), sl_green (0, slw, slh), sl_blue (0, slw, slh) { |
964 | jag | 23 | name = "Number"; |
24 | uchar = 'A'; |
||
25 | short_ = 666; |
||
26 | int_ = 1729; |
||
27 | float_ = 3.141592; |
||
28 | double_ = 2.71828183; |
||
29 | ucolor.r = 128; ucolor.g = 128; ucolor.b = 255; |
||
30 | type = CHAR; |
||
31 | make_shapeform = 1; |
||
32 | y[1]=1.0f; |
||
33 | y[0]=0.0f; |
||
34 | } |
||
35 | |||
36 | number::~number () { |
||
37 | widget_save ("d_number", ctrls); |
||
38 | save_params (); |
||
39 | } |
||
40 | |||
41 | void number::load_params () { |
||
42 | ifstream f (make_fname().c_str(), ios::in); |
||
43 | string ignore; |
||
44 | f >> ignore >> type; |
||
45 | f >> ignore; |
||
46 | slider<int>* sl [] = {&sl_red, &sl_green, &sl_blue}; |
||
47 | int s; |
||
48 | for (int i = 0; i < 3; ++i) {f >> s; sl[i]->set_val (s);} |
||
49 | f >> ignore >> double_; |
||
50 | f >> ignore >> float_; |
||
51 | f >> ignore >> int_; |
||
52 | f >> ignore >> short_; |
||
53 | f >> ignore >> uchar; |
||
54 | float v; |
||
55 | spinner<float>* sp[] = {&sp_0equals, &sp_1equals}; |
||
56 | for (int i = 0; i < 2; ++i) { |
||
57 | f >> ignore >> v; sp[i]->set_value (v); |
||
58 | y[i] = v; |
||
59 | } |
||
60 | f >> ignore >> v; sp_scale.set_value (v); |
||
61 | f >> ignore >> make_shapeform; cb_make_shapeform.set_state (make_shapeform); |
||
1476 | jag | 62 | int w; f >> ignore >> w; cb_wrap.set_state (w); |
964 | jag | 63 | } |
64 | |||
65 | void number::save_params () { |
||
66 | ofstream f (make_fname().c_str(), ios::out); |
||
67 | f << "type " << type << endl; |
||
68 | f << "color " << (int) ucolor.r << ' ' << (int) ucolor.g << ' ' << (int) ucolor.b << endl; |
||
69 | f << "double " << double_ << endl; |
||
70 | f << "float " << float_ << endl; |
||
71 | f << "int " << int_ << endl; |
||
72 | f << "short " << short_ << endl; |
||
73 | f << "char " << (char) uchar << endl; |
||
2108 | jag | 74 | f << "0_equals " << sp_0equals.value << endl; |
75 | f << "1_equals " << sp_1equals.value << endl; |
||
76 | f << "scale " << sp_scale.value << endl; |
||
964 | jag | 77 | f << "make_shapeform " << (int) cb_make_shapeform.state << endl; |
78 | f << "wrap " << (int) cb_wrap.state << endl; |
||
79 | } |
||
80 | |||
81 | void number::setup () { |
||
82 | |||
83 | plugin::setup (); |
||
84 | |||
85 | ol_bitsof.set_listener (this); |
||
86 | |||
87 | const char* const _types [] = {"char", "short", "int", "float", "double", "colour"}; |
||
88 | for (int i = 0, num_types = 6; i < num_types; ++i) types.push_back (_types[i]); |
||
89 | |||
90 | widget* _ctrls [] = {&ol_bitsof, &lf_value, &sp_1equals, &sp_0equals, &sp_scale, &cb_make_shapeform, &bd_bits, &sl_red, &sl_green, &sl_blue, &b_flip, &b_left_shift, &b_right_shift, &cb_wrap}; |
||
91 | for (int i = 0; i < 14; ++i) ctrls.push_back (_ctrls[i]); |
||
92 | num_ctrls = ctrls.size (); |
||
93 | |||
94 | button* btn [] = {&b_flip, &b_left_shift, &b_right_shift}; |
||
95 | const char* const l[] = {"Flip", "<<", ">>"}; |
||
96 | for (int i = 0; i < 3; ++i) { |
||
97 | button* bi = btn[i]; |
||
1120 | jag | 98 | bi->set_text (l[i]); |
964 | jag | 99 | bi->set_listener (this); |
100 | } |
||
1120 | jag | 101 | cb_wrap.set_text ("Rotate"); |
964 | jag | 102 | b_left_shift.click_repeat = b_right_shift.click_repeat = 1; |
103 | |||
104 | slider<int>* sl[] = {&sl_red, &sl_green, &sl_blue}; |
||
105 | for (int i = 0; i < 3; ++i) { |
||
106 | slider<int>* si = sl[i]; |
||
107 | si->set_limits (0, 255); |
||
108 | si->set_listener (this); |
||
109 | } |
||
110 | unsigned char c = 255, b = 0; |
||
111 | sl_red.set_color (c, b, b); |
||
112 | sl_green.set_color (b, c, b); |
||
113 | sl_blue.set_color (b, b, c); |
||
114 | |||
115 | lf_value.set_label ("Value"); |
||
116 | lf_value.set_listener (this); |
||
117 | |||
118 | spinner<float>* spn [] = {&sp_1equals, &sp_0equals}; |
||
119 | const char* spnl [] = {"1 = ", "0 = "}; |
||
120 | float spnv [] = {1.0f, 0.1f}; |
||
121 | for (int i = 0; i < 2; ++i) { |
||
122 | spinner<float>* spi = spn[i]; |
||
1485 | jag | 123 | spi->set (spnl[i], 0.01f, -MILLION, MILLION, this, 0); |
964 | jag | 124 | spi->set_value (spnv[i]); |
125 | } |
||
126 | |||
1120 | jag | 127 | cb_make_shapeform.set_text ("Make shapeform"); |
964 | jag | 128 | |
1485 | jag | 129 | sp_scale.set ("Scale", 0.01f, 0.0f, MILLION, this, 0); |
964 | jag | 130 | sp_scale.set_value (1.0f); |
131 | |||
132 | widget_load ("d_number", ctrls); |
||
133 | |||
134 | bd_bits.lsnr = this; |
||
135 | |||
136 | load_params (); |
||
137 | |||
138 | make_value_from_color (); |
||
139 | set_type (type); |
||
140 | |||
141 | cb_make_shapeform.set_listener (this); |
||
142 | |||
143 | } |
||
144 | |||
145 | void number::render () { |
||
146 | shapeform = cb_make_shapeform.state; |
||
147 | vector<unsigned char>& bits = bd_bits.bits; |
||
148 | int num_bits = bd_bits.num_bits; |
||
149 | points.clear (); |
||
2108 | jag | 150 | float scale = sp_scale.value; |
964 | jag | 151 | float cx = 0.5, cy = 0; |
152 | if (shapeform) { |
||
153 | extern const float TWO_PI; |
||
154 | float da = TWO_PI / num_bits, hda = da / 2.0; |
||
155 | float pa = -hda, a = 0, na = hda; |
||
156 | float cos_pa = cos(pa), sin_pa = sin(pa); |
||
157 | float cos_na, sin_na; |
||
158 | float cos_a, sin_a; |
||
159 | int pbi = -1, b0 = bits[0], bl = bits[bd_bits.last_bit]; |
||
160 | for (int i = 0; i < num_bits; ++i) { |
||
161 | int bi = bits[i]; |
||
162 | cos_a = cos(a); |
||
163 | sin_a = sin(a); |
||
164 | float R = scale * y[bi]; |
||
165 | float x = cx + R * cos_a; |
||
166 | float y = cy + R * sin_a; |
||
167 | cos_na = cos(na); |
||
168 | sin_na = sin(na); |
||
169 | float xn = cx + R * cos_na; |
||
170 | float yn = cy + R * sin_na; |
||
171 | if (bi != pbi) { |
||
172 | float xp = cx + R * cos_pa; |
||
173 | float yp = cy + R * sin_pa; |
||
174 | points.push_back (point<float>(xp,yp)); |
||
175 | } |
||
176 | cos_pa = cos_na; |
||
177 | sin_pa = sin_na; |
||
178 | points.push_back (point<float>(x, y)); |
||
179 | points.push_back (point<float>(xn, yn)); |
||
180 | a += da; |
||
181 | na += da; |
||
182 | pbi = bi; |
||
183 | } |
||
184 | if (b0 != bl) { |
||
185 | point<float>& p0 = *points.begin (); |
||
186 | points.push_back (p0); |
||
187 | } |
||
188 | } else { |
||
189 | float beat_pos = 0.0f; |
||
190 | float beat = scale / bd_bits.num_bits; |
||
191 | float half_beat = beat / 2.0; |
||
192 | point<float> p0; |
||
193 | for (int i = 0, j = bd_bits.num_bits; i < j; ++i) { |
||
194 | int bi = bits[i]; |
||
195 | points.push_back (point<float>(beat_pos, 0.0f)); |
||
196 | point<float> pi (beat_pos + half_beat, y[bi]); |
||
197 | points.push_back (pi); |
||
198 | beat_pos += beat; |
||
199 | } |
||
200 | points.push_back (point<float>(beat_pos, 0.0f)); |
||
201 | } |
||
1232 | jag | 202 | |
964 | jag | 203 | ss.clear(); ss.str(""); ss << "number_" << lf_value.fld.text; |
1232 | jag | 204 | gen_pts (); |
205 | |||
964 | jag | 206 | } |
207 | |||
208 | void number::flip () { |
||
209 | vector<unsigned char>& bits = bd_bits.bits; |
||
210 | int num_bits = bd_bits.num_bits; |
||
211 | for (int i = 0; i < num_bits; ++i) bits[i]=!bits[i]; |
||
212 | changed (bd_bits); |
||
213 | } |
||
214 | |||
215 | void number::shift (int i, int d) { |
||
216 | vector<unsigned char>& bits = bd_bits.bits; |
||
217 | int j = i; |
||
218 | int n = bd_bits.last_bit; |
||
219 | unsigned char w = bits[i]; |
||
220 | for (int m = 0; m < n; ++m) { |
||
221 | int id = i + d; |
||
222 | bits[i]=bits[id]; |
||
223 | i = id; |
||
224 | } |
||
225 | int wb = j + d * n; |
||
226 | if (cb_wrap.state) bits[wb] = w; else bits[wb] = 0; |
||
227 | changed (bd_bits); |
||
228 | } |
||
229 | |||
230 | void number::make_value_from_color () { |
||
1461 | jag | 231 | ucolor.r = sl_red (); ucolor.g = sl_green (); ucolor.b = sl_blue (); |
964 | jag | 232 | if (type == COLOR) { |
1695 | jag | 233 | ss.clear (); ss.str(""); ss << int(ucolor.r) << spc << int(ucolor.g) << spc << int(ucolor.b); |
964 | jag | 234 | lf_value.set_text (ss.str()); |
235 | bd_bits.set (&ucolor, 3); |
||
236 | } |
||
237 | bd_bits.set_color (ucolor.r, ucolor.g, ucolor.b); |
||
238 | } |
||
239 | |||
240 | void number::set_type (int t) { |
||
241 | |||
242 | type = t; |
||
243 | |||
1476 | jag | 244 | wrap<int> (CHAR, type, COLOR); |
964 | jag | 245 | |
246 | ol_bitsof.set_text (" Bits of " + types[type]); |
||
247 | |||
1476 | jag | 248 | lf_value.fld.expr = 1; |
964 | jag | 249 | if (type == COLOR) { |
250 | make_value_from_color (); |
||
1476 | jag | 251 | lf_value.fld.expr = 0; |
964 | jag | 252 | } else if (type == CHAR) { |
253 | set_value (uchar); |
||
1521 | jag | 254 | lf_value.fld.expr = 0; |
964 | jag | 255 | } else if (type == SHORT) { |
256 | set_value (short_); |
||
257 | } else if (type == INT) { |
||
258 | set_value (int_); |
||
259 | } else if (type == FLOAT) { |
||
260 | set_value (float_); |
||
261 | } else if (type == DOUBLE) { |
||
262 | set_value (double_); |
||
263 | } |
||
264 | |||
265 | do_render (); |
||
266 | |||
267 | } |
||
268 | |||
269 | extern tcl_interp interpreter; |
||
270 | |||
271 | string eval_expression (const string& e) { |
||
272 | string cmd ("expr "); cmd += e; |
||
273 | interpreter (cmd); |
||
274 | if (interpreter.result_status == TCL_OK) return interpreter.result; else return ("error"); |
||
275 | } |
||
276 | |||
277 | void eval_expression (field& f) { |
||
278 | f.set_text (eval_expression (f.text)); |
||
279 | } |
||
280 | |||
281 | void number::reverse (unsigned char* reversed, unsigned char* original, int n) { |
||
282 | for (int i = 0, j = n - 1; i < n; ++i, --j) reversed[i] = original[j]; |
||
283 | } |
||
284 | |||
285 | void number::changed (slider<int>& s) { |
||
286 | make_value_from_color (); |
||
287 | do_render (); |
||
288 | } |
||
289 | |||
290 | void number::picked (label& lbl, int dir) { |
||
291 | int t = type + dir; |
||
292 | set_type (t); |
||
293 | } |
||
294 | |||
295 | void number::changed (field& f) { |
||
296 | if (&f == &lf_value.fld) { |
||
297 | if (type == INT) { |
||
298 | eval_expression (f); |
||
2110 | jag | 299 | int_ = int (f); |
964 | jag | 300 | int int__ = int_; |
2110 | jag | 301 | set_bit_display (&int__); |
964 | jag | 302 | } else if (type == FLOAT) { |
303 | eval_expression (f); |
||
2110 | jag | 304 | float_ = float (f); |
964 | jag | 305 | float float__ = float_; |
2110 | jag | 306 | set_bit_display (&float__); |
964 | jag | 307 | } else if (type == DOUBLE) { |
308 | eval_expression (f); |
||
2110 | jag | 309 | double_ = double (f); |
964 | jag | 310 | double double__ = double_; |
2110 | jag | 311 | set_bit_display (&double__); |
964 | jag | 312 | } else if (type == CHAR) { |
313 | if (f.text.length () == 0) { |
||
314 | uchar = 'A'; |
||
315 | f.set_text (uchar); |
||
316 | } else uchar = f.text[0]; |
||
317 | unsigned char uchar_ = uchar; |
||
318 | set_bit_display (&uchar_); |
||
319 | } else if (type == SHORT) { |
||
320 | eval_expression (f); |
||
2110 | jag | 321 | short_ = short (f); |
964 | jag | 322 | short short__ = short_; |
2110 | jag | 323 | set_bit_display (&short__); |
964 | jag | 324 | } else if (type == COLOR) { |
325 | ss.clear (); ss.str(""); ss << f.text; |
||
326 | string comp[3]; |
||
327 | for (int i = 0; i < 3; ++i) { |
||
328 | string& ci = comp[i]; |
||
329 | ss >> ci; |
||
330 | ci = eval_expression (ci); |
||
331 | } |
||
332 | int sv = 0; |
||
333 | slider<int>* sld[3] = {&sl_red, &sl_green, &sl_blue}; |
||
334 | for (int i = 0; i < 3; ++i) { |
||
335 | ss.clear (); ss.str(""); ss << comp[i]; |
||
336 | ss >> sv; |
||
337 | sld[i]->set_val (sv); // set slider |
||
338 | } |
||
339 | make_value_from_color (); |
||
340 | } |
||
341 | } else if (&f == &sp_1equals.f_value) { |
||
2110 | jag | 342 | y[1] = sp_1equals.value; |
964 | jag | 343 | } else if (&f == &sp_0equals.f_value) { |
2110 | jag | 344 | y[0] = sp_0equals.value; |
964 | jag | 345 | } |
346 | do_render (); |
||
347 | } |
||
348 | |||
349 | |||
350 | void number::changed (bit_display& bd) { |
||
351 | if (type == COLOR) { |
||
352 | bd.get_color (&ucolor); |
||
353 | sl_red.set_val (ucolor.r); sl_green.set_val (ucolor.g); sl_blue.set_val (ucolor.b); |
||
354 | make_value_from_color (); |
||
355 | } else if (type == CHAR) { |
||
356 | bd.get_data (&uchar); |
||
1988 | jag | 357 | if (uchar > 31 && uchar < 127) set_value_ (uchar); |
964 | jag | 358 | } else if (type == SHORT) { |
359 | bd.get_data (&short_); |
||
360 | set_value_ (short_); |
||
361 | } else if (type == INT) { |
||
362 | bd.get_data (&int_); |
||
363 | set_value_ (int_); |
||
364 | } else if (type == FLOAT) { |
||
365 | bd.get_data (&float_); |
||
366 | set_value_ (float_); |
||
367 | } else if (type == DOUBLE) { |
||
368 | bd.get_data (&double_); |
||
369 | set_value_ (double_); |
||
370 | } |
||
371 | do_render (); |
||
372 | } |
||
373 | |||
374 | void number::changed (checkbutton& cb) { |
||
375 | if (&cb == &cb_make_shapeform) do_render (); |
||
376 | else return plugin::changed (cb); |
||
377 | } |
||
378 | |||
379 | void number::clicked (button& b) { |
||
380 | if (&b == &b_flip) { |
||
381 | flip (); |
||
382 | } else if (&b == &b_left_shift) { |
||
383 | shift (0, +1); |
||
384 | } else if (&b == &b_right_shift) { |
||
385 | shift (bd_bits.last_bit, -1); |
||
386 | } else plugin::clicked (b); |
||
387 | } |