diff options
-rw-r--r-- | main-sdl.c | 761 |
1 files changed, 392 insertions, 369 deletions
@@ -34,97 +34,98 @@ enum { | |||
34 | int g_harfe_connected = 0; | 34 | int g_harfe_connected = 0; |
35 | int g_harfe_fd = -1; | 35 | int g_harfe_fd = -1; |
36 | 36 | ||
37 | static int g_up_pressed = 0, g_down_pressed = 0; | ||
38 | |||
37 | static char * | 39 | static char * |
38 | find_harfe() | 40 | find_harfe() |
39 | { | 41 | { |
40 | // Device name should be a cu.device | 42 | // Device name should be a cu.device |
41 | // followed by the letter HAR somewhere | 43 | // followed by the letter HAR somewhere |
42 | // e.g. /dev /cu.usbmodemHAR1 | 44 | // e.g. /dev /cu.usbmodemHAR1 |
43 | DIR * dev = opendir("/dev/"); | 45 | DIR * dev = opendir("/dev/"); |
44 | struct dirent *dp; | 46 | struct dirent *dp; |
45 | char *harfe = 0; | 47 | char *harfe = 0; |
46 | 48 | ||
47 | if (!dev) | 49 | if (!dev) |
48 | return 0; | 50 | return 0; |
49 | 51 | ||
50 | while ((dp = readdir(dev)) != NULL) { | 52 | while ((dp = readdir(dev)) != NULL) { |
51 | size_t len = dp->d_namlen; | 53 | size_t len = dp->d_namlen; |
52 | char *name = dp->d_name; | 54 | char *name = dp->d_name; |
53 | int i; | 55 | int i; |
54 | |||
55 | if (len < 6 || name[0] != 'c' || name[1] != 'u' || name[2] != '.') | ||
56 | continue; | ||
57 | |||
58 | for (i = 0; i < len - 3; ++i) | ||
59 | if (name[i] == 'H' && name[i + 1] == 'A' && name[i + 2] == 'R' ) { | ||
60 | if ((harfe = calloc(1, 5 + len + 1))) { | ||
61 | sprintf(harfe, "/dev/"); | ||
62 | memcpy(harfe + 5, name, len); | ||
63 | } | ||
64 | break; | ||
65 | } | ||
66 | } | ||
67 | closedir(dev); | ||
68 | 56 | ||
69 | return harfe; | 57 | if (len < 6 || name[0] != 'c' || name[1] != 'u' || name[2] != '.') |
58 | continue; | ||
59 | |||
60 | for (i = 0; i < len - 3; ++i) | ||
61 | if (name[i] == 'H' && name[i + 1] == 'A' && name[i + 2] == 'R' ) { | ||
62 | if ((harfe = calloc(1, 5 + len + 1))) { | ||
63 | sprintf(harfe, "/dev/"); | ||
64 | memcpy(harfe + 5, name, len); | ||
65 | } | ||
66 | break; | ||
67 | } | ||
68 | } | ||
69 | closedir(dev); | ||
70 | |||
71 | return harfe; | ||
70 | } | 72 | } |
71 | 73 | ||
72 | int | 74 | int |
73 | set_interface_attribs(int fd, int speed, int parity) | 75 | set_interface_attribs(int fd, int speed, int parity) |
74 | { | 76 | { |
75 | struct termios tty; | 77 | struct termios tty; |
76 | 78 | ||
77 | memset(&tty, 0, sizeof tty); | 79 | memset(&tty, 0, sizeof tty); |
78 | if (tcgetattr(fd, &tty) != 0) | 80 | if (tcgetattr(fd, &tty) != 0) |
79 | return -1; | 81 | return -1; |
80 | cfsetospeed(&tty, speed); | 82 | cfsetospeed(&tty, speed); |
81 | cfsetispeed(&tty, speed); | 83 | cfsetispeed(&tty, speed); |
82 | 84 | ||
83 | tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; | 85 | tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; |
84 | tty.c_iflag &= ~IGNBRK; | 86 | tty.c_iflag &= ~IGNBRK; |
85 | tty.c_lflag = 0; | 87 | tty.c_lflag = 0; |
86 | tty.c_oflag = 0; | 88 | tty.c_oflag = 0; |
87 | tty.c_cc[VMIN] = 0; | 89 | tty.c_cc[VMIN] = 0; |
88 | tty.c_cc[VTIME] = 5; | 90 | tty.c_cc[VTIME] = 5; |
89 | 91 | ||
90 | tty.c_iflag &= ~(IXON | IXOFF | IXANY); | 92 | tty.c_iflag &= ~(IXON | IXOFF | IXANY); |
91 | 93 | ||
92 | tty.c_cflag |= (CLOCAL | CREAD); | 94 | tty.c_cflag |= (CLOCAL | CREAD); |
93 | 95 | ||
94 | tty.c_cflag &= ~(PARENB | PARODD); | 96 | tty.c_cflag &= ~(PARENB | PARODD); |
95 | tty.c_cflag |= parity; | 97 | tty.c_cflag |= parity; |
96 | tty.c_cflag &= ~CSTOPB; | 98 | tty.c_cflag &= ~CSTOPB; |
97 | tty.c_cflag &= ~CRTSCTS; | 99 | tty.c_cflag &= ~CRTSCTS; |
98 | 100 | ||
99 | if (tcsetattr(fd, TCSANOW, &tty) != 0) | 101 | if (tcsetattr(fd, TCSANOW, &tty) != 0) |
100 | return -1; | 102 | return -1; |
101 | return 0; | 103 | return 0; |
102 | } | 104 | } |
103 | 105 | ||
104 | void | 106 | void |
105 | set_blocking(int fd, int should_block) | 107 | set_blocking(int fd, int should_block) |
106 | { | 108 | { |
107 | struct termios tty; | 109 | struct termios tty; |
108 | 110 | ||
109 | memset(&tty, 0, sizeof tty); | 111 | memset(&tty, 0, sizeof tty); |
110 | if (tcgetattr(fd, &tty) != 0) | 112 | if (tcgetattr(fd, &tty) != 0) |
111 | return; | 113 | return; |
112 | 114 | ||
113 | tty.c_cc[VMIN] = should_block ? 1 : 0; | 115 | tty.c_cc[VMIN] = should_block ? 1 : 0; |
114 | tty.c_cc[VTIME] = 5; | 116 | tty.c_cc[VTIME] = 5; |
115 | 117 | ||
116 | if (tcsetattr(fd, TCSANOW, &tty) != 0) | 118 | if (tcsetattr(fd, TCSANOW, &tty) != 0) |
117 | return; | 119 | return; |
118 | } | 120 | } |
119 | 121 | ||
120 | |||
121 | uint32_t | 122 | uint32_t |
122 | now() | 123 | now() |
123 | { | 124 | { |
124 | struct timeval now; | 125 | struct timeval now; |
125 | 126 | ||
126 | gettimeofday(&now, (struct timezone *)NULL); | 127 | gettimeofday(&now, (struct timezone *)NULL); |
127 | return now.tv_sec * 1000 + now.tv_usec / 1000; /* in ms */ | 128 | return now.tv_sec * 1000 + now.tv_usec / 1000; /* in ms */ |
128 | } | 129 | } |
129 | 130 | ||
130 | static uint32_t g_last_avg; | 131 | static uint32_t g_last_avg; |
@@ -133,158 +134,158 @@ static int g_events; | |||
133 | static void | 134 | static void |
134 | harfe_worker(void) | 135 | harfe_worker(void) |
135 | { | 136 | { |
136 | LPoint p[4]; | 137 | LPoint p[4]; |
137 | char text[256], *lineend; | 138 | char text[256], *lineend; |
138 | int fd, i, text_fill = 0, consumed, running = 1; | 139 | int fd, i, text_fill = 0, consumed, running = 1; |
139 | uint32_t ptime; | 140 | uint32_t ptime; |
140 | 141 | ||
141 | char *portname = find_harfe(); | 142 | char *portname = find_harfe(); |
142 | 143 | ||
143 | if (!portname) { | 144 | if (!portname) { |
144 | printf("Can't find harfe serial device..."); | 145 | printf("Can't find harfe serial device..."); |
145 | return; | 146 | return; |
146 | } | 147 | } |
147 | g_harfe_fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC); | 148 | g_harfe_fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC); |
148 | if (g_harfe_fd < 0) { | 149 | if (g_harfe_fd < 0) { |
149 | free(portname); | ||
150 | printf("Can't connect to harfe..."); | ||
151 | return; | ||
152 | } | ||
153 | set_interface_attribs(g_harfe_fd, B115200, 0); | ||
154 | set_blocking(g_harfe_fd, 0); | ||
155 | |||
156 | printf("Connection to harfe established at %s.\n", portname); | ||
157 | free(portname); | 150 | free(portname); |
158 | g_harfe_connected = 1; | 151 | printf("Can't connect to harfe..."); |
159 | 152 | return; | |
160 | /* Get remote config (if any) */ | 153 | } |
161 | config_reset(); | 154 | set_interface_attribs(g_harfe_fd, B115200, 0); |
162 | write(g_harfe_fd, "S2\n", 3); | 155 | set_blocking(g_harfe_fd, 0); |
163 | usleep(50); | 156 | |
164 | g_importing_config = 1; | 157 | printf("Connection to harfe established at %s.\n", portname); |
165 | write(g_harfe_fd, "I\n", 2); | 158 | free(portname); |
166 | 159 | g_harfe_connected = 1; | |
167 | while (running) { | 160 | |
168 | while (text_fill < sizeof(text) && !memchr(text, '\n', text_fill)) { | 161 | /* Get remote config (if any) */ |
169 | ssize_t b = read(g_harfe_fd, text + text_fill, sizeof(text) - text_fill); | 162 | config_reset(); |
170 | 163 | write(g_harfe_fd, "S2\n", 3); | |
171 | if ((b < 0) && (errno != EAGAIN)) { | 164 | usleep(50); |
172 | printf("Connection to harfe lost..."); | 165 | g_importing_config = 1; |
173 | running = 0; | 166 | write(g_harfe_fd, "I\n", 2); |
174 | close(g_harfe_fd); | 167 | |
175 | g_harfe_fd = -1; | 168 | while (running) { |
176 | break; | 169 | while (text_fill < sizeof(text) && !memchr(text, '\n', text_fill)) { |
177 | } | 170 | ssize_t b = read(g_harfe_fd, text + text_fill, sizeof(text) - text_fill); |
178 | text_fill += b; | 171 | |
179 | } | 172 | if ((b < 0) && (errno != EAGAIN)) { |
180 | 173 | printf("Connection to harfe lost..."); | |
181 | //Overlong line, drop it and try to resync | 174 | running = 0; |
182 | if (text_fill == sizeof(text)) { | 175 | close(g_harfe_fd); |
183 | text_fill = 0; | 176 | g_harfe_fd = -1; |
184 | continue; | 177 | break; |
185 | } | 178 | } |
179 | text_fill += b; | ||
180 | } | ||
186 | 181 | ||
187 | // find and remove newline and cf | 182 | //Overlong line, drop it and try to resync |
188 | if (!(lineend = memchr(text, '\n', text_fill))) | 183 | if (text_fill == sizeof(text)) { |
189 | continue; | 184 | text_fill = 0; |
190 | 185 | continue; | |
191 | *lineend = 0; | 186 | } |
192 | if (text_fill && lineend[-1] == '\r') | ||
193 | lineend[-1] = 0; | ||
194 | printf( "%s\n", text ); | ||
195 | |||
196 | if (g_importing_config) { | ||
197 | if (!strcmp(text, "-- DONE")) { | ||
198 | g_importing_config = 0; | ||
199 | g_config_source = source_harfe; | ||
200 | } else | ||
201 | config_handle_line(text); | ||
202 | } else { | ||
203 | |||
204 | 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); | ||
205 | |||
206 | ptime = now(); | ||
207 | for (i = 0; i < num_points / 2; ++i) { | ||
208 | // printf("%04d:%04d\n", p[i].x, p[i].y); | ||
209 | |||
210 | if (!g_calibration_running) | ||
211 | engine_handle_point(p + i, ptime); | ||
212 | else | ||
213 | calib_handle_point(p + i, ptime); | ||
214 | } | ||
215 | if (num_points > 1 || *text == '-') | ||
216 | ++g_events; | ||
217 | } | ||
218 | 187 | ||
219 | consumed = lineend - text + 1; | 188 | // find and remove newline and cf |
220 | memmove(text, lineend + 1, text_fill - consumed); | 189 | if (!(lineend = memchr(text, '\n', text_fill))) |
221 | text_fill -= consumed; | 190 | continue; |
191 | |||
192 | *lineend = 0; | ||
193 | if (text_fill && lineend[-1] == '\r') | ||
194 | lineend[-1] = 0; | ||
195 | printf( "%s\n", text ); | ||
196 | |||
197 | if (g_importing_config) { | ||
198 | if (!strcmp(text, "-- DONE")) { | ||
199 | g_importing_config = 0; | ||
200 | g_config_source = source_harfe; | ||
201 | } else | ||
202 | config_handle_line(text); | ||
203 | } else { | ||
204 | |||
205 | 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); | ||
206 | |||
207 | ptime = now(); | ||
208 | for (i = 0; i < num_points / 2; ++i) { | ||
209 | // printf("%04d:%04d\n", p[i].x, p[i].y); | ||
210 | |||
211 | if (!g_calibration_running) | ||
212 | engine_handle_point(p + i, ptime); | ||
213 | else | ||
214 | calib_handle_point(p + i, ptime); | ||
215 | } | ||
216 | if (num_points > 1 || *text == '-') | ||
217 | ++g_events; | ||
222 | } | 218 | } |
223 | return; | 219 | |
220 | consumed = lineend - text + 1; | ||
221 | memmove(text, lineend + 1, text_fill - consumed); | ||
222 | text_fill -= consumed; | ||
223 | } | ||
224 | return; | ||
224 | } | 225 | } |
226 | |||
225 | static void * | 227 | static void * |
226 | worker(void *args) | 228 | worker(void *args) |
227 | { | 229 | { |
228 | while (1) { | 230 | while (1) { |
229 | harfe_worker(); | 231 | harfe_worker(); |
230 | g_harfe_connected = 0; | 232 | g_harfe_connected = 0; |
231 | printf(" retrying in 5 seconds.\n"); | 233 | printf(" retrying in 5 seconds.\n"); |
232 | sleep(5); | 234 | sleep(5); |
233 | } | 235 | } |
234 | } | 236 | } |
235 | 237 | ||
236 | static void | 238 | static void |
237 | config_parse(char *config_file) | 239 | config_parse(char *config_file) |
238 | { | 240 | { |
239 | FILE *fh = fopen(config_file, "r"); | 241 | FILE *fh = fopen(config_file, "r"); |
240 | char line_in[512]; | 242 | char line_in[512]; |
241 | 243 | ||
242 | if (!fh) { | 244 | if (!fh) { |
243 | fprintf(stderr, "Couldn't open config file %s, exiting.\n", config_file); | 245 | fprintf(stderr, "Couldn't open config file %s, exiting.\n", config_file); |
244 | exit(1); | 246 | exit(1); |
245 | } | 247 | } |
246 | config_reset(); | 248 | config_reset(); |
247 | while (!feof(fh)) { | 249 | while (!feof(fh)) { |
248 | char *line = fgets(line_in, sizeof(line_in), fh); | 250 | char *line = fgets(line_in, sizeof(line_in), fh); |
249 | 251 | ||
250 | if (!line) | 252 | if (!line) |
251 | continue; | 253 | continue; |
252 | if (config_handle_line(line)) | 254 | if (config_handle_line(line)) |
253 | exit(1); | 255 | exit(1); |
254 | } | 256 | } |
255 | 257 | ||
256 | fclose(fh); | 258 | fclose(fh); |
257 | g_config_source = source_file; | 259 | g_config_source = source_file; |
258 | } | 260 | } |
259 | 261 | ||
260 | void config_save() { | 262 | void config_save() { |
261 | const char *homeDir = getenv("HOME"); | 263 | const char *homeDir = getenv("HOME"); |
262 | char savefile[512], date[32], confdump[512]; | 264 | char savefile[512], date[32], confdump[512]; |
263 | time_t t = time(NULL); | 265 | time_t t = time(NULL); |
264 | struct tm *tmp = localtime(&t); | 266 | struct tm *tmp = localtime(&t); |
265 | int i, fd; | 267 | int i, fd; |
266 | size_t len; | 268 | size_t len; |
267 | 269 | ||
268 | if (!homeDir) { | 270 | if (!homeDir) { |
269 | struct passwd* pwd = getpwuid(getuid()); | 271 | struct passwd* pwd = getpwuid(getuid()); |
270 | if (pwd) | 272 | if (pwd) |
271 | homeDir = (const char*)pwd->pw_dir; | 273 | homeDir = (const char*)pwd->pw_dir; |
272 | } | 274 | } |
273 | strftime(date, sizeof(date), "%Y-%m-%d-%H-%M-%S", tmp); | 275 | strftime(date, sizeof(date), "%Y-%m-%d-%H-%M-%S", tmp); |
274 | snprintf( savefile, sizeof(savefile), "%s/Laserharfe-%s.cfg", homeDir, date); | 276 | snprintf( savefile, sizeof(savefile), "%s/Laserharfe-%s.cfg", homeDir, date); |
275 | fd = open(savefile, O_WRONLY | O_CREAT | O_TRUNC, 0644); | 277 | fd = open(savefile, O_WRONLY | O_CREAT | O_TRUNC, 0644); |
276 | 278 | ||
277 | len = config_dumpglobals( confdump, sizeof(confdump)); | 279 | len = config_dumpglobals( confdump, sizeof(confdump)); |
280 | write(fd, confdump, len ); | ||
281 | for (i=0; i<g_string_count; ++i) { | ||
282 | len = config_dumpstring(i, confdump, sizeof(confdump)); | ||
278 | write(fd, confdump, len ); | 283 | write(fd, confdump, len ); |
279 | for (i=0; i<g_string_count; ++i) { | 284 | } |
280 | len = config_dumpstring(i, confdump, sizeof(confdump)); | 285 | close(fd); |
281 | write(fd, confdump, len ); | ||
282 | } | ||
283 | close(fd); | ||
284 | |||
285 | snprintf(savefile, sizeof(savefile), "Config saved to your home directory at %s/Laserharfe-%s.cfg", homeDir, date); | ||
286 | display_messagebox("Config saved", savefile); | ||
287 | 286 | ||
287 | snprintf(savefile, sizeof(savefile), "Config saved to your home directory at %s/Laserharfe-%s.cfg", homeDir, date); | ||
288 | display_messagebox("Config saved", savefile); | ||
288 | } | 289 | } |
289 | 290 | ||
290 | void config_import() { | 291 | void config_import() { |
@@ -298,207 +299,229 @@ void config_import() { | |||
298 | } | 299 | } |
299 | 300 | ||
300 | void config_export() { | 301 | void config_export() { |
301 | size_t len; | 302 | size_t len; |
302 | char confdump[512]; | 303 | char confdump[512]; |
303 | int i; | 304 | int i; |
304 | if (!g_harfe_connected) { | 305 | if (!g_harfe_connected) { |
305 | display_messagebox( "Not connected", "Can't write config if Harfe is not connected."); | 306 | display_messagebox( "Not connected", "Can't write config if Harfe is not connected."); |
306 | return; | 307 | return; |
307 | } | 308 | } |
308 | if ((int)g_config_source < 2) { | 309 | if ((int)g_config_source < 2) { |
309 | display_messagebox( "No changes", "Config is unchanged. Won't write config to Harfe."); | 310 | display_messagebox( "No changes", "Config is unchanged. Won't write config to Harfe."); |
310 | return; | 311 | return; |
311 | } | 312 | } |
312 | write(g_harfe_fd, "E\n", 2); | 313 | write(g_harfe_fd, "E\n", 2); |
313 | len = config_dumpglobals( confdump, sizeof(confdump)); | 314 | len = config_dumpglobals( confdump, sizeof(confdump)); |
315 | write(g_harfe_fd, confdump, len ); | ||
316 | for (i=0; i<g_string_count; ++i) { | ||
317 | len = config_dumpstring(i, confdump, sizeof(confdump)); | ||
314 | write(g_harfe_fd, confdump, len ); | 318 | write(g_harfe_fd, confdump, len ); |
315 | for (i=0; i<g_string_count; ++i) { | 319 | usleep(1000); |
316 | len = config_dumpstring(i, confdump, sizeof(confdump)); | 320 | } |
317 | write(g_harfe_fd, confdump, len ); | 321 | write(g_harfe_fd, "-- DONE\n", 8); /* End dump marker */ |
318 | usleep(1000); | 322 | write(g_harfe_fd, "W\n", 2); /* Remote write to SD */ |
319 | } | 323 | g_config_source = source_harfe; |
320 | write(g_harfe_fd, "-- DONE\n", 8); /* End dump marker */ | ||
321 | write(g_harfe_fd, "W\n", 2); /* Remote write to SD */ | ||
322 | g_config_source = source_harfe; | ||
323 | } | 324 | } |
324 | 325 | ||
325 | void | 326 | void |
326 | handle_keydown(SDL_Event *ev) { | 327 | handle_keydown(SDL_Event *ev) { |
328 | switch (ev->key.keysym.scancode) { | ||
329 | case SDL_SCANCODE_RETURN: | ||
330 | menu_setmode(1, 1); | ||
331 | break; | ||
332 | case SDL_SCANCODE_ESCAPE: | ||
333 | if (g_importing_config) { | ||
334 | g_importing_config = 0; | ||
335 | config_reset(); | ||
336 | } | ||
337 | calib_stop(); | ||
338 | menu_setmode(6, 0); | ||
339 | break; | ||
340 | case SDL_SCANCODE_UP: | ||
341 | if (ev->key.repeat || !g_up_pressed++) | ||
342 | engine_change_selected(1); | ||
343 | break; | ||
344 | case SDL_SCANCODE_DOWN: | ||
345 | if (ev->key.repeat || !g_down_pressed++) | ||
346 | engine_change_selected(-1); | ||
347 | break; | ||
348 | case SDL_SCANCODE_0: | ||
349 | engine_select_config(sel_none); | ||
350 | break; | ||
351 | case SDL_SCANCODE_1: | ||
352 | engine_select_config(sel_min_y); | ||
353 | break; | ||
354 | case SDL_SCANCODE_2: | ||
355 | engine_select_config(sel_max_y); | ||
356 | break; | ||
357 | case SDL_SCANCODE_3: | ||
358 | engine_select_config(sel_2_oct); | ||
359 | break; | ||
360 | case SDL_SCANCODE_4: | ||
361 | engine_select_config(sel_3_oct_bottom); | ||
362 | break; | ||
363 | case SDL_SCANCODE_5: | ||
364 | engine_select_config(sel_3_oct_top); | ||
365 | break; | ||
366 | case SDL_SCANCODE_C: | ||
367 | if (g_calibration_running) { | ||
368 | calib_fetch(); | ||
369 | menu_setmode(1<<3, 0); | ||
370 | } else { | ||
371 | calib_init(); | ||
372 | menu_setmode(0, 3); | ||
373 | } | ||
374 | break; | ||
375 | case SDL_SCANCODE_E: | ||
376 | config_export(); | ||
377 | break; | ||
378 | case SDL_SCANCODE_I: | ||
379 | config_import(); | ||
380 | break; | ||
381 | case SDL_SCANCODE_L: | ||
382 | config_parse("config_midi"); | ||
383 | break; | ||
384 | case SDL_SCANCODE_M: | ||
385 | if (g_harfe_connected && (g_harfe_fd != -1)) { | ||
386 | fprintf( stderr, "MIDIing on %d\n", g_harfe_fd ); | ||
387 | write(g_harfe_fd, "ME20020\nM824C00\n", 16); | ||
388 | } | ||
389 | break; | ||
390 | case SDL_SCANCODE_Q: | ||
391 | config_reset(); | ||
392 | break; | ||
393 | case SDL_SCANCODE_R: | ||
394 | if (g_calibration_running) | ||
395 | calib_init(); | ||
396 | break; | ||
397 | case SDL_SCANCODE_S: | ||
398 | config_save(); | ||
399 | break; | ||
400 | case SDL_SCANCODE_W: | ||
401 | fprintf( stderr, "write remote config\n" ); | ||
402 | write(g_harfe_fd, "W\n", 2); | ||
403 | break; | ||
404 | case SDL_SCANCODE_X: | ||
405 | config_reverse_strings(); | ||
406 | break; | ||
407 | case SDL_SCANCODE_Y: | ||
408 | config_flip_y(); | ||
409 | break; | ||
410 | case SDL_SCANCODE_NONUSBACKSLASH: | ||
411 | menu_setmode(2,2); | ||
412 | break; | ||
413 | #ifdef CALIB_DEBUG | ||
414 | case SDL_SCANCODE_SPACE: | ||
415 | if (g_calibration_running) | ||
416 | calib_next(10); | ||
417 | break; | ||
418 | #endif | ||
419 | default: | ||
420 | break; | ||
421 | } /* endswitch */ | ||
327 | 422 | ||
423 | /* Handle the ugly German keyboard <> key mapping */ | ||
424 | if (ev->key.keysym.sym == SDLK_GREATER) | ||
425 | menu_setmode(2,2); | ||
328 | } | 426 | } |
329 | 427 | ||
330 | int | 428 | int |
331 | main(int argc, char **argv) | 429 | main(int argc, char **argv) |
332 | { | 430 | { |
333 | SDL_Event ev; | 431 | SDL_Event ev; |
334 | int i, counter = 0; | 432 | int i, counter = 0; |
335 | pthread_t thread_id; | 433 | pthread_t thread_id; |
336 | uint32_t runtime; | 434 | uint32_t runtime; |
337 | static int last_click_x, last_click_y, last_mouse_event; | 435 | static int last_click_x, last_click_y, last_mouse_event; |
338 | static int g_up_pressed = 0, g_down_pressed = 0; | ||
339 | 436 | ||
340 | display_init(SCREEN_WIDTH, SCREEN_HEIGHT, HARFE_WIDTH, HARFE_HEIGHT); | 437 | display_init(SCREEN_WIDTH, SCREEN_HEIGHT, HARFE_WIDTH, HARFE_HEIGHT); |
341 | engine_init(); | 438 | engine_init(); |
342 | // config_parse("config_midi"); | ||
343 | 439 | ||
344 | pthread_create(&thread_id, NULL, worker, NULL); | 440 | pthread_create(&thread_id, NULL, worker, NULL); |
345 | 441 | ||
346 | /* | 442 | /* |
347 | E - Export config to Harfe (with implicite write to SD) | 443 | E - Export config to Harfe (with implicite write to SD) |
348 | I - Import config from Harfe | 444 | I - Import config from Harfe |
349 | W - Write config on Harfe to SD (no implicite Transfer) | 445 | W - Write config on Harfe to SD (no implicite Transfer) |
350 | 446 | ||
351 | S - Save config to local file | 447 | S - Save config to local file |
352 | L - Load config from local default (config_midi) | 448 | L - Load config from local default (config_midi) |
353 | 449 | ||
354 | Y - Invert String order | 450 | Y - Invert String order |
355 | X - Invert Octave order | 451 | X - Invert Octave order |
356 | 452 | ||
357 | Q - Reset local Config | 453 | Q - Reset local Config |
358 | C - Start calibration | 454 | C - Start calibration |
359 | M - Play MIDI C through Harfe | 455 | M - Play MIDI C through Harfe |
360 | */ | 456 | */ |
361 | 457 | ||
362 | /* Spin and let call back do all the work */ | 458 | /* Spin and let call back do all the work */ |
363 | while (1) { | 459 | while (1) { |
364 | SDL_WaitEventTimeout(&ev, 10); | 460 | SDL_WaitEventTimeout(&ev, 10); |
365 | switch (ev.type) { | 461 | switch (ev.type) { |
366 | case SDL_QUIT: | 462 | case SDL_QUIT: |
367 | exit(0); | 463 | exit(0); |
368 | case SDL_KEYUP: | 464 | case SDL_KEYUP: |
369 | if (ev.key.keysym.scancode == SDL_SCANCODE_UP) g_up_pressed = 0; | 465 | if (ev.key.keysym.scancode == SDL_SCANCODE_UP) g_up_pressed = 0; |
370 | if (ev.key.keysym.scancode == SDL_SCANCODE_DOWN) g_down_pressed = 0; | 466 | if (ev.key.keysym.scancode == SDL_SCANCODE_DOWN) g_down_pressed = 0; |
371 | break; | 467 | break; |
372 | case SDL_KEYDOWN: | 468 | case SDL_KEYDOWN: |
373 | if ( ev.key.keysym.scancode == SDL_SCANCODE_0) | 469 | handle_keydown(&ev); |
374 | engine_select_config(sel_none); | 470 | break; |
375 | if ( ev.key.keysym.scancode == SDL_SCANCODE_1) | 471 | case SDL_MOUSEMOTION: |
376 | engine_select_config(sel_min_y); | 472 | if (ev.motion.state & SDL_BUTTON_LMASK) { |
377 | if ( ev.key.keysym.scancode == SDL_SCANCODE_2) | 473 | LPoint p = { display_scale_screen_to_harfe(ev.motion.x), 768 - display_scale_screen_to_harfe(ev.motion.y) }; |
378 | engine_select_config(sel_max_y); | 474 | engine_handle_point(&p, now()); |
379 | if ( ev.key.keysym.scancode == SDL_SCANCODE_3) | 475 | } |
380 | engine_select_config(sel_2_oct); | 476 | break; |
381 | if ( ev.key.keysym.scancode == SDL_SCANCODE_4) | 477 | case SDL_MOUSEBUTTONDOWN: |
382 | engine_select_config(sel_3_oct_bottom); | 478 | { |
383 | if ( ev.key.keysym.scancode == SDL_SCANCODE_5) | 479 | LPoint p = { display_scale_screen_to_harfe(ev.button.x), 768 - display_scale_screen_to_harfe(ev.button.y) }; |
384 | engine_select_config(sel_3_oct_top); | 480 | if (menu_test_mouse_down(ev.button.x, ev.button.y)) |
385 | 481 | engine_handle_point(&p, now()); | |
386 | if ( ev.key.keysym.scancode == SDL_SCANCODE_UP) | 482 | } |
387 | if ( ev.key.repeat || ! g_up_pressed++) | 483 | break; |
388 | engine_change_selected(1); | 484 | case SDL_MOUSEBUTTONUP: |
389 | if ( ev.key.keysym.scancode == SDL_SCANCODE_DOWN) | 485 | { |
390 | if ( ev.key.repeat || ! g_down_pressed++) | 486 | LPoint p = { display_scale_screen_to_harfe(ev.button.x), 768 - display_scale_screen_to_harfe(ev.button.y) }; |
391 | engine_change_selected(-1); | 487 | menu_handle_button_up(ev.button.x, ev.button.y); |
392 | 488 | } | |
393 | if ( ev.key.keysym.scancode == SDL_SCANCODE_S) | ||
394 | config_save(); | ||
395 | if (ev.key.keysym.scancode == SDL_SCANCODE_W) { | ||
396 | fprintf( stderr, "write remote config\n" ); | ||
397 | write(g_harfe_fd, "W\n", 2); | ||
398 | } | ||
399 | if (ev.key.keysym.scancode == SDL_SCANCODE_I) | ||
400 | config_import(); | ||
401 | if (ev.key.keysym.scancode == SDL_SCANCODE_Q) | ||
402 | config_reset(); | ||
403 | if (ev.key.keysym.scancode == SDL_SCANCODE_L) | ||
404 | config_parse("config_midi"); | ||
405 | if (ev.key.keysym.scancode == SDL_SCANCODE_X) | ||
406 | config_reverse_strings(); | ||
407 | if (ev.key.keysym.scancode == SDL_SCANCODE_Y) { | ||
408 | g_midi_three_octave_split_inverse ^= 1; | ||
409 | g_config_source = source_edit; | ||
410 | } | ||
411 | #ifdef CALIB_DEBUG | ||
412 | if ( ev.key.keysym.scancode == SDL_SCANCODE_SPACE) | ||
413 | if (g_calibration_running) | ||
414 | calib_next(10); | ||
415 | #endif | ||
416 | if ( ev.key.keysym.scancode == SDL_SCANCODE_RETURN) | ||
417 | menu_setmode(1, 1); | ||
418 | if ( ev.key.keysym.scancode == SDL_SCANCODE_ESCAPE) { | ||
419 | if (g_importing_config) { | ||
420 | g_importing_config = 0; | ||
421 | config_reset(); | ||
422 | } | ||
423 | calib_stop(); | ||
424 | menu_setmode(6, 0); | ||
425 | } | ||
426 | if ( ev.key.keysym.sym == SDLK_GREATER || ev.key.keysym.scancode == SDL_SCANCODE_NONUSBACKSLASH) { | ||
427 | menu_setmode(2,2); | ||
428 | } | ||
429 | if ( ev.key.keysym.scancode == SDL_SCANCODE_R) { | ||
430 | if (g_calibration_running) | ||
431 | calib_init(); | ||
432 | } | ||
433 | if ( ev.key.keysym.scancode == SDL_SCANCODE_C) { | ||
434 | if (g_calibration_running) { | ||
435 | calib_fetch(); | ||
436 | menu_setmode(1<<3, 0); | ||
437 | } else { | ||
438 | calib_init(); | ||
439 | menu_setmode(0, 3); | ||
440 | } | ||
441 | } | ||
442 | if ( ev.key.keysym.scancode == SDL_SCANCODE_E) | ||
443 | config_export(); | ||
444 | if ( ev.key.keysym.scancode == SDL_SCANCODE_M) { | ||
445 | fprintf( stderr, "MIDIing on %d\n", g_harfe_fd ); | ||
446 | if (g_harfe_connected && (g_harfe_fd != -1)) | ||
447 | write(g_harfe_fd, "ME20020\nM824C00\n", 16); | ||
448 | } | ||
449 | break; | ||
450 | case SDL_MOUSEMOTION: | ||
451 | if (ev.motion.state & SDL_BUTTON_LMASK) | ||
452 | { | ||
453 | LPoint p = { display_scale_screen_to_harfe(ev.motion.x), 768 - display_scale_screen_to_harfe(ev.motion.y) }; | ||
454 | engine_handle_point(&p, now()); | ||
455 | } | ||
456 | break; | ||
457 | case SDL_MOUSEBUTTONDOWN: | ||
458 | { | ||
459 | LPoint p = { display_scale_screen_to_harfe(ev.button.x), 768 - display_scale_screen_to_harfe(ev.button.y) }; | ||
460 | if (menu_test_mouse_down(ev.button.x, ev.button.y)) | ||
461 | engine_handle_point(&p, now()); | ||
462 | } | ||
463 | break; | ||
464 | case SDL_MOUSEBUTTONUP: | ||
465 | { | ||
466 | LPoint p = { display_scale_screen_to_harfe(ev.button.x), 768 - display_scale_screen_to_harfe(ev.button.y) }; | ||
467 | menu_handle_button_up(ev.button.x, ev.button.y); | ||
468 | } | ||
469 | |||
470 | break; | ||
471 | case SDL_DROPFILE: { | ||
472 | char t[512]; | ||
473 | int ret; | ||
474 | snprintf( t, sizeof(t), "Do you want to import config file %s?\n", ev.drop.file); | ||
475 | if ((ret= display_messagebox_yesno("Import Laserharfe config", t))) | ||
476 | config_parse(ev.drop.file); | ||
477 | printf( "Dropped: %s (%d)\n", ev.drop.file, ret ); | ||
478 | break; | ||
479 | } | ||
480 | 489 | ||
490 | break; | ||
491 | case SDL_DROPFILE: | ||
492 | { | ||
493 | char t[512]; | ||
494 | int ret; | ||
495 | snprintf( t, sizeof(t), "Do you want to import config file %s?\n", ev.drop.file); | ||
496 | if ((ret= display_messagebox_yesno("Import Laserharfe config", t))) | ||
497 | config_parse(ev.drop.file); | ||
498 | printf( "Dropped: %s (%d)\n", ev.drop.file, ret ); | ||
499 | break; | ||
481 | } | 500 | } |
482 | if (!g_calibration_running || !g_importing_config) | 501 | default: |
483 | engine_checksilence(now()); | 502 | break; |
503 | } | ||
484 | 504 | ||
485 | runtime = now(); | 505 | if (!g_calibration_running || !g_importing_config) |
486 | if (runtime - g_lastredraw > 30) { | 506 | engine_checksilence(now()); |
487 | g_lastredraw = runtime; | ||
488 | 507 | ||
489 | if (!g_calibration_running) | 508 | runtime = now(); |
490 | engine_redraw(); | 509 | if (runtime - g_lastredraw > 30) { |
491 | else | 510 | g_lastredraw = runtime; |
492 | calib_redraw(); | 511 | |
512 | if (!g_calibration_running) | ||
513 | engine_redraw(); | ||
514 | else | ||
515 | calib_redraw(); | ||
493 | 516 | ||
494 | } | ||
495 | if (runtime / 1000 - g_last_avg > 10) { | ||
496 | if (g_events) | ||
497 | printf("avg: %i\n", g_events / 10); | ||
498 | g_events = 0; | ||
499 | g_last_avg = runtime / 1000; | ||
500 | } | ||
501 | } | 517 | } |
518 | if (runtime / 1000 - g_last_avg > 10) { | ||
519 | if (g_events) | ||
520 | printf("avg: %i\n", g_events / 10); | ||
521 | g_events = 0; | ||
522 | g_last_avg = runtime / 1000; | ||
523 | } | ||
524 | } | ||
502 | 525 | ||
503 | return 0; | 526 | return 0; |
504 | } | 527 | } |