Mercurial > repos > blastem
comparison io.c @ 1326:071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 21 Apr 2017 23:35:32 -0700 |
parents | a719e2c98b54 |
children | 040c5600e2d9 |
comparison
equal
deleted
inserted
replaced
1325:58bfbed6cdb5 | 1326:071e761bcdcf |
---|---|
492 break; | 492 break; |
493 case UI_SOFT_RESET: | 493 case UI_SOFT_RESET: |
494 current_system->soft_reset(current_system); | 494 current_system->soft_reset(current_system); |
495 break; | 495 break; |
496 case UI_SCREENSHOT: { | 496 case UI_SCREENSHOT: { |
497 char *screenshot_base = tern_find_path(config, "ui\0screenshot_path\0").ptrval; | 497 char *screenshot_base = tern_find_path(config, "ui\0screenshot_path\0", TVAL_PTR).ptrval; |
498 if (!screenshot_base) { | 498 if (!screenshot_base) { |
499 screenshot_base = "$HOME"; | 499 screenshot_base = "$HOME"; |
500 } | 500 } |
501 tern_node *vars = tern_insert_ptr(NULL, "HOME", get_home_dir()); | 501 tern_node *vars = tern_insert_ptr(NULL, "HOME", get_home_dir()); |
502 vars = tern_insert_ptr(vars, "EXEDIR", get_exe_dir()); | 502 vars = tern_insert_ptr(vars, "EXEDIR", get_exe_dir()); |
503 screenshot_base = replace_vars(screenshot_base, vars, 1); | 503 screenshot_base = replace_vars(screenshot_base, vars, 1); |
504 tern_free(vars); | 504 tern_free(vars); |
505 time_t now = time(NULL); | 505 time_t now = time(NULL); |
506 struct tm local_store; | 506 struct tm local_store; |
507 char fname_part[256]; | 507 char fname_part[256]; |
508 char *template = tern_find_path(config, "ui\0screenshot_template\0").ptrval; | 508 char *template = tern_find_path(config, "ui\0screenshot_template\0", TVAL_PTR).ptrval; |
509 if (!template) { | 509 if (!template) { |
510 template = "blastem_%c.ppm"; | 510 template = "blastem_%c.ppm"; |
511 } | 511 } |
512 strftime(fname_part, sizeof(fname_part), template, localtime_r(&now, &local_store)); | 512 strftime(fname_part, sizeof(fname_part), template, localtime_r(&now, &local_store)); |
513 char const *parts[] = {screenshot_base, PATH_SEP, fname_part}; | 513 char const *parts[] = {screenshot_base, PATH_SEP, fname_part}; |
874 | 874 |
875 void setup_io_devices(tern_node * config, rom_info *rom, sega_io *io) | 875 void setup_io_devices(tern_node * config, rom_info *rom, sega_io *io) |
876 { | 876 { |
877 current_io = io; | 877 current_io = io; |
878 io_port * ports = current_io->ports; | 878 io_port * ports = current_io->ports; |
879 tern_node *io_nodes = tern_get_node(tern_find_path(config, "io\0devices\0")); | 879 tern_node *io_nodes = tern_find_path(config, "io\0devices\0", TVAL_NODE).ptrval; |
880 char * io_1 = rom->port1_override ? rom->port1_override : tern_find_ptr(io_nodes, "1"); | 880 char * io_1 = rom->port1_override ? rom->port1_override : io_nodes ? tern_find_ptr(io_nodes, "1") : NULL; |
881 char * io_2 = rom->port2_override ? rom->port2_override : tern_find_ptr(io_nodes, "2"); | 881 char * io_2 = rom->port2_override ? rom->port2_override : io_nodes ? tern_find_ptr(io_nodes, "2") : NULL; |
882 char * io_ext = rom->ext_override ? rom->ext_override : tern_find_ptr(io_nodes, "ext"); | 882 char * io_ext = rom->ext_override ? rom->ext_override : io_nodes ? tern_find_ptr(io_nodes, "ext") : NULL; |
883 | 883 |
884 process_device(io_1, ports); | 884 process_device(io_1, ports); |
885 process_device(io_2, ports+1); | 885 process_device(io_2, ports+1); |
886 process_device(io_ext, ports+2); | 886 process_device(io_ext, ports+2); |
887 | 887 |
899 for (int i = 0; i < 3; i++) | 899 for (int i = 0; i < 3; i++) |
900 { | 900 { |
901 #ifndef _WIN32 | 901 #ifndef _WIN32 |
902 if (ports[i].device_type == IO_SEGA_PARALLEL) | 902 if (ports[i].device_type == IO_SEGA_PARALLEL) |
903 { | 903 { |
904 char *pipe_name = tern_find_path(config, "io\0parallel_pipe\0").ptrval; | 904 char *pipe_name = tern_find_path(config, "io\0parallel_pipe\0", TVAL_PTR).ptrval; |
905 if (!pipe_name) | 905 if (!pipe_name) |
906 { | 906 { |
907 warning("IO port %s is configured to use the sega parallel board, but no paralell_pipe is set!\n", io_name(i)); | 907 warning("IO port %s is configured to use the sega parallel board, but no paralell_pipe is set!\n", io_name(i)); |
908 ports[i].device_type = IO_NONE; | 908 ports[i].device_type = IO_NONE; |
909 } else { | 909 } else { |
925 } | 925 } |
926 } | 926 } |
927 } | 927 } |
928 } | 928 } |
929 } else if (ports[i].device_type == IO_GENERIC) { | 929 } else if (ports[i].device_type == IO_GENERIC) { |
930 char *sock_name = tern_find_path(config, "io\0socket\0").ptrval; | 930 char *sock_name = tern_find_path(config, "io\0socket\0", TVAL_PTR).ptrval; |
931 if (!sock_name) | 931 if (!sock_name) |
932 { | 932 { |
933 warning("IO port %s is configured to use generic IO, but no socket is set!\n", io_name(i)); | 933 warning("IO port %s is configured to use generic IO, but no socket is set!\n", io_name(i)); |
934 ports[i].device_type = IO_NONE; | 934 ports[i].device_type = IO_NONE; |
935 } else { | 935 } else { |
1011 tern_node *padbuttons; | 1011 tern_node *padbuttons; |
1012 tern_node *mousebuttons; | 1012 tern_node *mousebuttons; |
1013 int mouseidx; | 1013 int mouseidx; |
1014 } pmb_state; | 1014 } pmb_state; |
1015 | 1015 |
1016 void process_mouse_button(char *buttonstr, tern_val value, void *data) | 1016 void process_mouse_button(char *buttonstr, tern_val value, uint8_t valtype, void *data) |
1017 { | 1017 { |
1018 pmb_state *state = data; | 1018 pmb_state *state = data; |
1019 int buttonnum = atoi(buttonstr); | 1019 int buttonnum = atoi(buttonstr); |
1020 if (buttonnum < 1 || buttonnum > MAX_MOUSE_BUTTONS) { | 1020 if (buttonnum < 1 || buttonnum > MAX_MOUSE_BUTTONS) { |
1021 warning("Mouse button %s is out of the supported range of 1-8\n", buttonstr); | 1021 warning("Mouse button %s is out of the supported range of 1-8\n", buttonstr); |
1022 return; | 1022 return; |
1023 } | 1023 } |
1024 if (valtype != TVAL_PTR) { | |
1025 warning("Mouse button %s is not a scalar value!\n", buttonstr); | |
1026 return; | |
1027 } | |
1024 buttonnum--; | 1028 buttonnum--; |
1025 int ui_func, devicenum, button; | 1029 int ui_func, devicenum, button; |
1026 int bindtype = parse_binding_target(value.ptrval, state->padbuttons, state->mousebuttons, &ui_func, &devicenum, &button); | 1030 int bindtype = parse_binding_target(value.ptrval, state->padbuttons, state->mousebuttons, &ui_func, &devicenum, &button); |
1027 switch (bindtype) | 1031 switch (bindtype) |
1028 { | 1032 { |
1043 } | 1047 } |
1044 mice[state->mouseidx].buttons[buttonnum].bind_type = bindtype; | 1048 mice[state->mouseidx].buttons[buttonnum].bind_type = bindtype; |
1045 | 1049 |
1046 } | 1050 } |
1047 | 1051 |
1048 void process_mouse(char *mousenum, tern_val value, void *data) | 1052 void process_mouse(char *mousenum, tern_val value, uint8_t valtype, void *data) |
1049 { | 1053 { |
1050 tern_node **buttonmaps = data; | 1054 tern_node **buttonmaps = data; |
1051 tern_node *mousedef = tern_get_node(value); | 1055 if (valtype != TVAL_NODE) { |
1056 warning("Binding for mouse %s is a scalar!\n", mousenum); | |
1057 return; | |
1058 } | |
1059 tern_node *mousedef = value.ptrval; | |
1052 tern_node *padbuttons = buttonmaps[0]; | 1060 tern_node *padbuttons = buttonmaps[0]; |
1053 tern_node *mousebuttons = buttonmaps[1]; | 1061 tern_node *mousebuttons = buttonmaps[1]; |
1054 | 1062 |
1055 if (!mousedef) { | |
1056 warning("Binding for mouse %s is a scalar!\n", mousenum); | |
1057 return; | |
1058 } | |
1059 int mouseidx = atoi(mousenum); | 1063 int mouseidx = atoi(mousenum); |
1060 if (mouseidx < 0 || mouseidx >= MAX_MICE) { | 1064 if (mouseidx < 0 || mouseidx >= MAX_MICE) { |
1061 warning("Mouse numbers must be between 0 and %d, but %d is not\n", MAX_MICE, mouseidx); | 1065 warning("Mouse numbers must be between 0 and %d, but %d is not\n", MAX_MICE, mouseidx); |
1062 return; | 1066 return; |
1063 } | 1067 } |
1072 mice[mouseidx].bind_type = bindtype; | 1076 mice[mouseidx].bind_type = bindtype; |
1073 } else { | 1077 } else { |
1074 warning("Mouse motion can't be bound to target %s\n", motion); | 1078 warning("Mouse motion can't be bound to target %s\n", motion); |
1075 } | 1079 } |
1076 } | 1080 } |
1077 tern_node *buttons = tern_get_node(tern_find_path(mousedef, "buttons\0\0")); | 1081 tern_node *buttons = tern_find_path(mousedef, "buttons\0\0", TVAL_NODE).ptrval; |
1078 if (buttons) { | 1082 if (buttons) { |
1079 pmb_state state = {padbuttons, mousebuttons, mouseidx}; | 1083 pmb_state state = {padbuttons, mousebuttons, mouseidx}; |
1080 tern_foreach(buttons, process_mouse_button, &state); | 1084 tern_foreach(buttons, process_mouse_button, &state); |
1081 } | 1085 } |
1082 } | 1086 } |
1085 int padnum; | 1089 int padnum; |
1086 tern_node *padbuttons; | 1090 tern_node *padbuttons; |
1087 tern_node *mousebuttons; | 1091 tern_node *mousebuttons; |
1088 } pad_button_state; | 1092 } pad_button_state; |
1089 | 1093 |
1090 void process_pad_button(char *key, tern_val val, void *data) | 1094 void process_pad_button(char *key, tern_val val, uint8_t valtype, void *data) |
1091 { | 1095 { |
1092 pad_button_state *state = data; | 1096 pad_button_state *state = data; |
1093 int hostpadnum = state->padnum; | 1097 int hostpadnum = state->padnum; |
1094 int ui_func, padnum, button; | 1098 int ui_func, padnum, button; |
1099 if (valtype != TVAL_PTR) { | |
1100 warning("Pad button %s has a non-scalar value\n", key); | |
1101 return; | |
1102 } | |
1095 int bindtype = parse_binding_target(val.ptrval, state->padbuttons, state->mousebuttons, &ui_func, &padnum, &button); | 1103 int bindtype = parse_binding_target(val.ptrval, state->padbuttons, state->mousebuttons, &ui_func, &padnum, &button); |
1096 char *end; | 1104 char *end; |
1097 long hostbutton = strtol(key, &end, 10); | 1105 long hostbutton = strtol(key, &end, 10); |
1098 if (*end) { | 1106 if (*end) { |
1099 //key is not a valid base 10 integer | 1107 //key is not a valid base 10 integer |
1127 } else if (bindtype == BIND_UI) { | 1135 } else if (bindtype == BIND_UI) { |
1128 bind_button_ui(hostpadnum, hostbutton, ui_func, button); | 1136 bind_button_ui(hostpadnum, hostbutton, ui_func, button); |
1129 } | 1137 } |
1130 } | 1138 } |
1131 | 1139 |
1132 void process_pad_axis(char *key, tern_val val, void *data) | 1140 void process_pad_axis(char *key, tern_val val, uint8_t valtype, void *data) |
1133 { | 1141 { |
1134 key = strdup(key); | 1142 key = strdup(key); |
1135 pad_button_state *state = data; | 1143 pad_button_state *state = data; |
1136 int hostpadnum = state->padnum; | 1144 int hostpadnum = state->padnum; |
1137 int ui_func, padnum, button; | 1145 int ui_func, padnum, button; |
1146 if (valtype != TVAL_PTR) { | |
1147 warning("Mapping for axis %s has a non-scalar value", key); | |
1148 return; | |
1149 } | |
1138 int bindtype = parse_binding_target(val.ptrval, state->padbuttons, state->mousebuttons, &ui_func, &padnum, &button); | 1150 int bindtype = parse_binding_target(val.ptrval, state->padbuttons, state->mousebuttons, &ui_func, &padnum, &button); |
1139 char *modifier = strchr(key, '.'); | 1151 char *modifier = strchr(key, '.'); |
1140 int positive = 1; | 1152 int positive = 1; |
1141 if (modifier) { | 1153 if (modifier) { |
1142 *modifier = 0; | 1154 *modifier = 0; |
1224 void handle_joy_added(int joystick) | 1236 void handle_joy_added(int joystick) |
1225 { | 1237 { |
1226 if (joystick > MAX_JOYSTICKS) { | 1238 if (joystick > MAX_JOYSTICKS) { |
1227 return; | 1239 return; |
1228 } | 1240 } |
1229 tern_node * pads = tern_get_node(tern_find_path(config, "bindings\0pads\0")); | 1241 tern_node * pads = tern_find_path(config, "bindings\0pads\0", TVAL_NODE).ptrval; |
1230 if (pads) { | 1242 if (pads) { |
1231 char numstr[11]; | 1243 char numstr[11]; |
1232 sprintf(numstr, "%d", joystick); | 1244 sprintf(numstr, "%d", joystick); |
1233 tern_node * pad = tern_find_ptr(pads, numstr); | 1245 tern_node * pad = tern_find_node(pads, numstr); |
1234 if (pad) { | 1246 if (pad) { |
1235 tern_node * dpad_node = tern_find_ptr(pad, "dpads"); | 1247 tern_node * dpad_node = tern_find_node(pad, "dpads"); |
1236 if (dpad_node) { | 1248 if (dpad_node) { |
1237 for (int dpad = 0; dpad < 10; dpad++) | 1249 for (int dpad = 0; dpad < 10; dpad++) |
1238 { | 1250 { |
1239 numstr[0] = dpad + '0'; | 1251 numstr[0] = dpad + '0'; |
1240 numstr[1] = 0; | 1252 numstr[1] = 0; |
1241 tern_node * pad_dpad = tern_find_ptr(dpad_node, numstr); | 1253 tern_node * pad_dpad = tern_find_node(dpad_node, numstr); |
1242 char * dirs[] = {"up", "down", "left", "right"}; | 1254 char * dirs[] = {"up", "down", "left", "right"}; |
1243 int dirnums[] = {RENDER_DPAD_UP, RENDER_DPAD_DOWN, RENDER_DPAD_LEFT, RENDER_DPAD_RIGHT}; | 1255 int dirnums[] = {RENDER_DPAD_UP, RENDER_DPAD_DOWN, RENDER_DPAD_LEFT, RENDER_DPAD_RIGHT}; |
1244 for (int dir = 0; dir < sizeof(dirs)/sizeof(dirs[0]); dir++) { | 1256 for (int dir = 0; dir < sizeof(dirs)/sizeof(dirs[0]); dir++) { |
1245 char * target = tern_find_ptr(pad_dpad, dirs[dir]); | 1257 char * target = tern_find_ptr(pad_dpad, dirs[dir]); |
1246 if (target) { | 1258 if (target) { |
1253 } | 1265 } |
1254 } | 1266 } |
1255 } | 1267 } |
1256 } | 1268 } |
1257 } | 1269 } |
1258 tern_node *button_node = tern_find_ptr(pad, "buttons"); | 1270 tern_node *button_node = tern_find_node(pad, "buttons"); |
1259 if (button_node) { | 1271 if (button_node) { |
1260 pad_button_state state = { | 1272 pad_button_state state = { |
1261 .padnum = joystick, | 1273 .padnum = joystick, |
1262 .padbuttons = get_pad_buttons(), | 1274 .padbuttons = get_pad_buttons(), |
1263 .mousebuttons = get_mouse_buttons() | 1275 .mousebuttons = get_mouse_buttons() |
1264 }; | 1276 }; |
1265 tern_foreach(button_node, process_pad_button, &state); | 1277 tern_foreach(button_node, process_pad_button, &state); |
1266 } | 1278 } |
1267 tern_node *axes_node = tern_find_ptr(pad, "axes"); | 1279 tern_node *axes_node = tern_find_node(pad, "axes"); |
1268 if (axes_node) { | 1280 if (axes_node) { |
1269 pad_button_state state = { | 1281 pad_button_state state = { |
1270 .padnum = joystick, | 1282 .padnum = joystick, |
1271 .padbuttons = get_pad_buttons(), | 1283 .padbuttons = get_pad_buttons(), |
1272 .mousebuttons = get_mouse_buttons() | 1284 .mousebuttons = get_mouse_buttons() |
1345 | 1357 |
1346 tern_node *padbuttons = get_pad_buttons(); | 1358 tern_node *padbuttons = get_pad_buttons(); |
1347 | 1359 |
1348 tern_node *mousebuttons = get_mouse_buttons(); | 1360 tern_node *mousebuttons = get_mouse_buttons(); |
1349 | 1361 |
1350 tern_node * keys = tern_get_node(tern_find_path(config, "bindings\0keys\0")); | 1362 tern_node * keys = tern_find_path(config, "bindings\0keys\0", TVAL_NODE).ptrval; |
1351 process_keys(keys, special, padbuttons, mousebuttons, NULL); | 1363 process_keys(keys, special, padbuttons, mousebuttons, NULL); |
1352 char numstr[] = "00"; | 1364 char numstr[] = "00"; |
1353 tern_node * pads = tern_get_node(tern_find_path(config, "bindings\0pads\0")); | 1365 tern_node * pads = tern_find_path(config, "bindings\0pads\0", TVAL_NODE).ptrval; |
1354 if (pads) { | 1366 if (pads) { |
1355 for (int i = 0; i < MAX_JOYSTICKS; i++) | 1367 for (int i = 0; i < MAX_JOYSTICKS; i++) |
1356 { | 1368 { |
1357 | 1369 |
1358 if (i < 10) { | 1370 if (i < 10) { |
1364 } | 1376 } |
1365 | 1377 |
1366 } | 1378 } |
1367 } | 1379 } |
1368 memset(mice, 0, sizeof(mice)); | 1380 memset(mice, 0, sizeof(mice)); |
1369 tern_node * mice = tern_get_node(tern_find_path(config, "bindings\0mice\0")); | 1381 tern_node * mice = tern_find_path(config, "bindings\0mice\0", TVAL_NODE).ptrval; |
1370 if (mice) { | 1382 if (mice) { |
1371 tern_node *buttonmaps[2] = {padbuttons, mousebuttons}; | 1383 tern_node *buttonmaps[2] = {padbuttons, mousebuttons}; |
1372 tern_foreach(mice, process_mouse, buttonmaps); | 1384 tern_foreach(mice, process_mouse, buttonmaps); |
1373 } | 1385 } |
1374 tern_node * speed_nodes = tern_get_node(tern_find_path(config, "clocks\0speeds\0")); | 1386 tern_node * speed_nodes = tern_find_path(config, "clocks\0speeds\0", TVAL_NODE).ptrval; |
1375 speeds = malloc(sizeof(uint32_t)); | 1387 speeds = malloc(sizeof(uint32_t)); |
1376 speeds[0] = 100; | 1388 speeds[0] = 100; |
1377 process_speeds(speed_nodes, NULL); | 1389 process_speeds(speed_nodes, NULL); |
1378 for (int i = 0; i < num_speeds; i++) | 1390 for (int i = 0; i < num_speeds; i++) |
1379 { | 1391 { |