diff options
| author | erdgeist <erdgeist@bauklotz.fritz.box> | 2018-04-04 02:34:53 +0200 | 
|---|---|---|
| committer | erdgeist <erdgeist@bauklotz.fritz.box> | 2018-04-04 02:34:53 +0200 | 
| commit | dea7682dce1b3334119d8879257929c38bafa445 (patch) | |
| tree | bcfb1f3b5245299ac0418d019c2039e4061e0976 | |
| parent | 06c3fd419a6caa564deac48231df381cd13db738 (diff) | |
Clean up key down handler
| -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 | } | 
