summaryrefslogtreecommitdiff
path: root/main-sdl.c
diff options
context:
space:
mode:
Diffstat (limited to 'main-sdl.c')
-rw-r--r--main-sdl.c245
1 files changed, 215 insertions, 30 deletions
diff --git a/main-sdl.c b/main-sdl.c
index 687e5c7..6bc3970 100644
--- a/main-sdl.c
+++ b/main-sdl.c
@@ -10,22 +10,31 @@
10#include <termios.h> 10#include <termios.h>
11#include <unistd.h> 11#include <unistd.h>
12#include <dirent.h> 12#include <dirent.h>
13#include <pwd.h>
13 14
14#include <SDL2/SDL.h> 15#include <SDL2/SDL.h>
15#include "display.h" 16#include "display.h"
16#include "config.h" 17#include "config.h"
17#include "engine.h" 18#include "engine.h"
19#include "calib.h"
18 20
19/*** 21/***
20 Global config and status values 22 Global config and status values
21 ***/ 23 ***/
22 24
23/* Window width and height */ 25/* Window width and height */
24// const int g_width = 1024, g_height = 768; 26enum {
25const int g_width = 800, g_height = 600; 27 HARFE_WIDTH = 1024,
28 HARFE_HEIGHT = 768,
29 SCREEN_WIDTH = 800,
30 SCREEN_HEIGHT = 600
31};
26 32
27int g_harfe_connected = 0; 33int g_harfe_connected = 0;
28int g_harfe_fd = -1; 34int g_harfe_fd = -1;
35int g_importing_config = 0;
36ConfigSource g_config_source = source_none;
37int g_calibration_running = 0;
29 38
30static char * 39static char *
31find_harfe() 40find_harfe()
@@ -150,6 +159,13 @@ harfe_worker(void)
150 free(portname); 159 free(portname);
151 g_harfe_connected = 1; 160 g_harfe_connected = 1;
152 161
162 /* Get remote config (if any) */
163 config_reset();
164 write(g_harfe_fd, "S2\n", 3);
165 usleep(50);
166 g_importing_config = 1;
167 write(g_harfe_fd, "I\n", 2);
168
153 while (running) { 169 while (running) {
154 while (text_fill < sizeof(text) && !memchr(text, '\n', text_fill)) { 170 while (text_fill < sizeof(text) && !memchr(text, '\n', text_fill)) {
155 ssize_t b = read(g_harfe_fd, text + text_fill, sizeof(text) - text_fill); 171 ssize_t b = read(g_harfe_fd, text + text_fill, sizeof(text) - text_fill);
@@ -178,15 +194,29 @@ harfe_worker(void)
178 if (text_fill && lineend[-1] == '\r') 194 if (text_fill && lineend[-1] == '\r')
179 lineend[-1] = 0; 195 lineend[-1] = 0;
180printf( "%s\n", text ); 196printf( "%s\n", text );
181 int num_points = sscanf(text, "%04d:%04d %04d:%04d %04d:%04d %04d:%04d", &p[0].x, &p[0].y, &p[1].x, &p[1].y, &p[2].x, &p[2].y, &p[3].x, &p[3].y);
182 197
183 ptime = now(); 198 if (g_importing_config) {
184 for (i = 0; i < num_points / 2; ++i) { 199 if (!strcmp(text, "-- DONE")) {
200 g_importing_config = 0;
201 g_config_source = source_harfe;
202 } else
203 config_handle_line(text);
204 } else {
205
206 int num_points = sscanf(text, "%04d:%04d %04d:%04d %04d:%04d %04d:%04d", &p[0].x, &p[0].y, &p[1].x, &p[1].y, &p[2].x, &p[2].y, &p[3].x, &p[3].y);
207
208 ptime = now();
209 for (i = 0; i < num_points / 2; ++i) {
185 // printf("%04d:%04d\n", p[i].x, p[i].y); 210 // printf("%04d:%04d\n", p[i].x, p[i].y);
186 engine_handle_point(p + i, ptime); 211
187 } 212 if (!g_calibration_running)
188 if (num_points > 1 || *text == '-') 213 engine_handle_point(p + i, ptime);
214 else
215 calib_handle_point(p + i, ptime);
216 }
217 if (num_points > 1 || *text == '-')
189 ++g_events; 218 ++g_events;
219 }
190 220
191 consumed = lineend - text + 1; 221 consumed = lineend - text + 1;
192 memmove(text, lineend + 1, text_fill - consumed); 222 memmove(text, lineend + 1, text_fill - consumed);
@@ -226,6 +256,36 @@ config_parse(char *config_file)
226 } 256 }
227 257
228 fclose(fh); 258 fclose(fh);
259 g_config_source = source_file;
260}
261
262static void
263calib_fetch() {
264 int default_notes[] = { 60, 62, 64, 65, 67, 69, 71, 72, 74, 76, 77, 79, 81, 83 };
265 int i, result_count;
266 LLine *result = calib_get_results(&result_count);
267
268 config_reset();
269 g_string_count = result_count;
270
271 g_min_y = 0; g_max_y = 1024;
272
273 for (i=0; i<g_string_count; ++i) {
274 LLine *l = result + i;
275
276 if (l->p0.y > g_min_y)
277 g_min_y = l->p0.y;
278 if (l->p1.y < g_max_y)
279 g_max_y = l->p1.y;
280
281 g_string_conf[i].line = *l;
282 g_string_conf[i].mode = midi_three_octaves;
283 g_string_conf[i].channel = i;
284 g_string_conf[i].note = default_notes[i];
285 g_string_conf[i].modifier = pitch_bend_up;
286 }
287
288 g_config_source = source_edit;
229} 289}
230 290
231int 291int
@@ -236,48 +296,153 @@ main(int argc, char **argv)
236 pthread_t thread_id; 296 pthread_t thread_id;
237 uint32_t runtime; 297 uint32_t runtime;
238 static int last_click_x, last_click_y, last_mouse_event; 298 static int last_click_x, last_click_y, last_mouse_event;
299 static int g_up_pressed = 0, g_down_pressed = 0;
239 300
240 display_init(g_width, g_height); 301 display_init(SCREEN_WIDTH, SCREEN_HEIGHT, HARFE_WIDTH, HARFE_HEIGHT);
241 engine_init(); 302 engine_init();
242 config_parse("config_midi"); 303// config_parse("config_midi");
243 304
244 pthread_create(&thread_id, NULL, worker, NULL); 305 pthread_create(&thread_id, NULL, worker, NULL);
245 306
307/*
308 E - Export config to Harfe (with implicite write to SD)
309 I - Import config from Harfe
310 W - Write config on Harfe to SD (no implicite Transfer)
311
312 S - Save config to local file
313 L - Load config from local default (config_midi)
314
315 Y - Invert String order
316
317 Q - Reset local Config
318 C - Start calibration
319 M - Play MIDI C through Harfe
320*/
321
246 /* Spin and let call back do all the work */ 322 /* Spin and let call back do all the work */
247 while (1) { 323 while (1) {
248 SDL_WaitEventTimeout(&ev, 10); 324 SDL_WaitEventTimeout(&ev, 10);
249 switch (ev.type) { 325 switch (ev.type) {
250 case SDL_QUIT: 326 case SDL_QUIT:
251 exit(0); 327 exit(0);
252 case SDL_KEYDOWN: 328 case SDL_KEYUP:
329 if (ev.key.keysym.scancode == SDL_SCANCODE_UP) g_up_pressed = 0;
330 if (ev.key.keysym.scancode == SDL_SCANCODE_DOWN) g_down_pressed = 0;
331 break;
332 case SDL_KEYDOWN:
253/* 333/*
254 if( ev.key.keysym.sym >= SDLK_1 && ev.key.keysym.sym <= SDLK_9 ) 334 if ( ev.key.keysym.sym >= SDLK_1 && ev.key.keysym.sym <= SDLK_9 )
255 engine_select_string( ev.key.keysym.sym - SDLK_1 ); 335 engine_select_string( ev.key.keysym.sym - SDLK_1 );
256 if( ev.key.keysym.sym == SDLK_BACKSPACE || ev.key.keysym.sym == SDLK_DELETE ) 336 if ( ev.key.keysym.sym == SDLK_BACKSPACE || ev.key.keysym.sym == SDLK_DELETE )
257 engine_delete_selected_string( ); 337 engine_delete_selected_string( );
258 if( ev.key.keysym.sym == SDLK_d ) { 338 if ( ev.key.keysym.sym == SDLK_d ) {
259 g_stringsdescending = 1 - g_stringsdescending; 339 g_stringsdescending = 1 - g_stringsdescending;
260 printf( "String order (left to right) is now %sscending.\n", g_stringsdescending ? "de" : "a" ); 340 printf( "String order (left to right) is now %sscending.\n", g_stringsdescending ? "de" : "a" );
261 } 341 }
262*/ 342*/
263 if( ev.key.keysym.scancode == SDL_SCANCODE_R) { 343 if ( ev.key.keysym.scancode == SDL_SCANCODE_0)
264 fprintf( stderr, "re-read config\n" ); 344 engine_select_config(sel_none);
265 write(g_harfe_fd, "R\n", 2); 345 if ( ev.key.keysym.scancode == SDL_SCANCODE_1)
346 engine_select_config(sel_min_y);
347 if ( ev.key.keysym.scancode == SDL_SCANCODE_2)
348 engine_select_config(sel_max_y);
349 if ( ev.key.keysym.scancode == SDL_SCANCODE_3)
350 engine_select_config(sel_2_oct);
351 if ( ev.key.keysym.scancode == SDL_SCANCODE_4)
352 engine_select_config(sel_3_oct_top);
353 if ( ev.key.keysym.scancode == SDL_SCANCODE_5)
354 engine_select_config(sel_3_oct_bottom);
355
356 if ( ev.key.keysym.scancode == SDL_SCANCODE_UP && ! g_up_pressed++)
357 engine_change_selected(1);
358 if ( ev.key.keysym.scancode == SDL_SCANCODE_DOWN && ! g_down_pressed++)
359 engine_change_selected(-1);
360
361 if ( ev.key.keysym.scancode == SDL_SCANCODE_S) { /* export locally */
362 const char *homeDir = getenv("HOME");
363 char savefile[512], date[32], confdump[512];
364 time_t t = time(NULL);
365 struct tm *tmp = localtime(&t);
366 int fd;
367 size_t len;
368
369 if (!homeDir) {
370 struct passwd* pwd = getpwuid(getuid());
371 if (pwd)
372 homeDir = (const char*)pwd->pw_dir;
373 }
374 strftime(date, sizeof(date), "%Y-%m-%d-%H-%M-%S", tmp);
375 snprintf( savefile, sizeof(savefile), "%s/Laserharfe-%s.cfg", homeDir, date);
376 fd = open(savefile, O_WRONLY | O_CREAT | O_TRUNC, 0644);
377
378 len = config_dumpglobals( confdump, sizeof(confdump));
379 write(fd, confdump, len );
380 for (i=0; i<g_string_count; ++i) {
381 len = config_dumpstring(i, confdump, sizeof(confdump));
382 write(fd, confdump, len );
383 }
384 close(fd);
385 }
386 if (ev.key.keysym.scancode == SDL_SCANCODE_W) {
387 fprintf( stderr, "write remote config\n" );
388 write(g_harfe_fd, "W\n", 2);
389 }
390 if (ev.key.keysym.scancode == SDL_SCANCODE_I) {
391 fprintf( stderr, "dump config\n" );
392 config_reset();
393 g_importing_config = 1;
394 write(g_harfe_fd, "I\n", 2);
395 }
396 if (ev.key.keysym.scancode == SDL_SCANCODE_Q)
397 config_reset();
398 if (ev.key.keysym.scancode == SDL_SCANCODE_L)
399 config_parse("config_midi");
400 if (ev.key.keysym.scancode == SDL_SCANCODE_Y) {
401 for (i=0; i<g_string_count/2; ++i) {
402 LLine temp = g_string_conf[i].line;
403 g_string_conf[i].line = g_string_conf[g_string_count-i-1].line;
404 g_string_conf[g_string_count-i-1].line = temp;
405 }
406 g_config_source = source_edit;
407 }
408 if (ev.key.keysym.scancode == SDL_SCANCODE_X) {
409 g_midi_three_octave_split_inverse ^= 1;
410 g_config_source = source_edit;
266 } 411 }
267 if( ev.key.keysym.scancode == SDL_SCANCODE_D) { 412#ifdef CALIB_DEBUG
268 fprintf( stderr, "Dumping\n" ); 413 if ( ev.key.keysym.scancode == SDL_SCANCODE_SPACE)
269 write(g_harfe_fd, "D\n", 2); 414 if (g_calibration_running)
415 calib_next(10);
416#endif
417 if ( ev.key.keysym.scancode == SDL_SCANCODE_C) {
418 if (g_calibration_running)
419 calib_fetch();
420 else
421 calib_init();
422 g_calibration_running = 1 - g_calibration_running;
270 } 423 }
271 if( ev.key.keysym.scancode == SDL_SCANCODE_C) { 424 if ( ev.key.keysym.scancode == SDL_SCANCODE_E) {
272 char confdump[512]; 425 char confdump[512];
273 config_dumpglobals( confdump, sizeof(confdump)); 426 if (!g_harfe_connected) {
274 fputs( confdump, stderr); 427 display_messagebox( "Not connected", "Can't write config if Harfe is not connected.");
428 break;
429 }
430 if ((int)g_config_source < 2) {
431 display_messagebox( "No changes", "Config is unchanged. Won't write config to Harfe.");
432 break;
433 }
434 write(g_harfe_fd, "E\n", 2);
435 size_t len = config_dumpglobals( confdump, sizeof(confdump));
436 write(g_harfe_fd, confdump, len );
275 for (i=0; i<g_string_count; ++i) { 437 for (i=0; i<g_string_count; ++i) {
276 config_dumpstring(i, confdump, sizeof(confdump)); 438 len = config_dumpstring(i, confdump, sizeof(confdump));
277 fputs( confdump, stderr); 439 write(g_harfe_fd, confdump, len );
278 } 440 }
441 write(g_harfe_fd, "-- DONE\n", 8); /* End dump marker */
442 write(g_harfe_fd, "W\n", 2); /* Remote write to SD */
443 g_config_source = source_harfe;
279 } 444 }
280 if( ev.key.keysym.scancode == SDL_SCANCODE_M) { 445 if ( ev.key.keysym.scancode == SDL_SCANCODE_M) {
281 fprintf( stderr, "MIDIing on %d\n", g_harfe_fd ); 446 fprintf( stderr, "MIDIing on %d\n", g_harfe_fd );
282 if (g_harfe_connected && (g_harfe_fd != -1)) 447 if (g_harfe_connected && (g_harfe_fd != -1))
283 write(g_harfe_fd, "ME20020\nM824C00\n", 16); 448 write(g_harfe_fd, "ME20020\nM824C00\n", 16);
@@ -285,20 +450,40 @@ main(int argc, char **argv)
285 break; 450 break;
286 case SDL_MOUSEBUTTONDOWN: 451 case SDL_MOUSEBUTTONDOWN:
287/* 452/*
288 if( ( g_last_mouse_event / 1000 ) != ( engine_now( ) / 1000 ) || ev.button.x != last_click_x || ev.button.y != last_click_y ) 453 if ( ( g_last_mouse_event / 1000 ) != ( engine_now( ) / 1000 ) || ev.button.x != last_click_x || ev.button.y != last_click_y )
289 engine_process_mouse( ev.button.x, ev.button.y ); 454 engine_process_mouse( ev.button.x, ev.button.y );
290 last_click_x = ev.button.x; 455 last_click_x = ev.button.x;
291 last_click_y = ev.button.y; 456 last_click_y = ev.button.y;
292 last_mouse_event = engine_now( ); 457 last_mouse_event = engine_now( );
293*/ 458*/
459 {
460 LPoint p = { display_scale_screen_to_harfe(ev.button.x), 768 - display_scale_screen_to_harfe(ev.button.y) };
461 engine_handle_point(&p, now());
462 }
294 break; 463 break;
464 case SDL_DROPFILE: { // In case if dropped file
465 char t[512];
466 int ret;
467 snprintf( t, sizeof(t), "Do you want to import config file %s?\n", ev.drop.file);
468 if ((ret= display_messagebox_yesno("Import Laserharfe config", t)))
469 config_parse(ev.drop.file);
470 printf( "Dropped: %s (%d)\n", ev.drop.file, ret );
471 break;
472 }
473
295 } 474 }
475 if (!g_calibration_running || !g_importing_config)
476 engine_checksilence(now());
296 477
297 engine_checksilence(now());
298 runtime = now(); 478 runtime = now();
299 if (runtime - g_lastredraw > 30) { 479 if (runtime - g_lastredraw > 30 && !g_importing_config) {
300 g_lastredraw = runtime; 480 g_lastredraw = runtime;
301 engine_redraw(); 481
482 if (!g_calibration_running)
483 engine_redraw();
484 else
485 calib_redraw();
486
302 } 487 }
303 if (runtime / 1000 - g_last_avg > 10) { 488 if (runtime / 1000 - g_last_avg > 10) {
304 printf("avg: %i\n", g_events / 10); 489 printf("avg: %i\n", g_events / 10);