comparison io.c @ 897:b9564fb88a5a

WIP support for mega mouse
author Michael Pavone <pavone@retrodev.com>
date Wed, 25 Nov 2015 20:32:20 -0800
parents bc127fa1f800
children 0e5f9d6135be
comparison
equal deleted inserted replaced
896:74cc31040521 897:b9564fb88a5a
68 typedef struct { 68 typedef struct {
69 keybinding bindings[4]; 69 keybinding bindings[4];
70 uint8_t state; 70 uint8_t state;
71 } joydpad; 71 } joydpad;
72 72
73 typedef struct {
74 io_port *port;
75 uint8_t mode;
76 } mousebinding;
77
73 keybinding * bindings[256]; 78 keybinding * bindings[256];
74 keybinding * joybindings[MAX_JOYSTICKS]; 79 keybinding * joybindings[MAX_JOYSTICKS];
75 joydpad * joydpads[MAX_JOYSTICKS]; 80 joydpad * joydpads[MAX_JOYSTICKS];
81 mousebinding *mice[MAX_MICE];
76 const uint8_t dpadbits[] = {RENDER_DPAD_UP, RENDER_DPAD_DOWN, RENDER_DPAD_LEFT, RENDER_DPAD_RIGHT}; 82 const uint8_t dpadbits[] = {RENDER_DPAD_UP, RENDER_DPAD_DOWN, RENDER_DPAD_LEFT, RENDER_DPAD_RIGHT};
77 83
78 void bind_key(int keycode, uint8_t bind_type, uint8_t subtype_a, uint8_t subtype_b, uint8_t value) 84 void bind_key(int keycode, uint8_t bind_type, uint8_t subtype_a, uint8_t subtype_b, uint8_t value)
79 { 85 {
80 int bucket = keycode >> 8 & 0xFF; 86 int bucket = keycode >> 8 & 0xFF;
333 handle_binding_down(dpad->bindings + i); 339 handle_binding_down(dpad->bindings + i);
334 } else if(newup & dpadbits[i]) { 340 } else if(newup & dpadbits[i]) {
335 handle_binding_up(dpad->bindings + i); 341 handle_binding_up(dpad->bindings + i);
336 } 342 }
337 } 343 }
344 }
345
346 void handle_mouse_moved(int mouse, uint16_t x, uint16_t y)
347 {
348 printf("mouse motion: %d - (%d, %d)\n", mouse, x, y);
349 if (mouse >= MAX_MICE || !mice[mouse]) {
350 return;
351 }
352
338 } 353 }
339 354
340 int parse_binding_target(char * target, tern_node * padbuttons, int * ui_out, int * padnum_out, int * padbutton_out) 355 int parse_binding_target(char * target, tern_node * padbuttons, int * ui_out, int * padnum_out, int * padbutton_out)
341 { 356 {
342 int gpadslen = strlen("gamepads."); 357 int gpadslen = strlen("gamepads.");
484 { 499 {
485 return; 500 return;
486 } 501 }
487 502
488 const int gamepad_len = strlen("gamepad"); 503 const int gamepad_len = strlen("gamepad");
489 if (!memcmp(device_type, "gamepad", gamepad_len)) 504 const int mouse_len = strlen("mouse");
505 if (!strncmp(device_type, "gamepad", gamepad_len))
490 { 506 {
491 if ( 507 if (
492 (device_type[gamepad_len] != '3' && device_type[gamepad_len] != '6') 508 (device_type[gamepad_len] != '3' && device_type[gamepad_len] != '6')
493 || device_type[gamepad_len+1] != '.' || device_type[gamepad_len+2] < '1' 509 || device_type[gamepad_len+1] != '.' || device_type[gamepad_len+2] < '1'
494 || device_type[gamepad_len+2] > '8' || device_type[gamepad_len+3] != 0 510 || device_type[gamepad_len+2] > '8' || device_type[gamepad_len+3] != 0
500 port->device_type = IO_GAMEPAD3; 516 port->device_type = IO_GAMEPAD3;
501 } else { 517 } else {
502 port->device_type = IO_GAMEPAD6; 518 port->device_type = IO_GAMEPAD6;
503 } 519 }
504 port->device.pad.gamepad_num = device_type[gamepad_len+2] - '1'; 520 port->device.pad.gamepad_num = device_type[gamepad_len+2] - '1';
521 } else if(!strncmp(device_type, "mouse", mouse_len)) {
522 //TODO: do something with mouse number
523 port->device_type = IO_MOUSE;
505 } else if(!strcmp(device_type, "sega_parallel")) { 524 } else if(!strcmp(device_type, "sega_parallel")) {
506 port->device_type = IO_SEGA_PARALLEL; 525 port->device_type = IO_SEGA_PARALLEL;
507 port->device.stream.data_fd = -1; 526 port->device.stream.data_fd = -1;
508 port->device.stream.listen_fd = -1; 527 port->device.stream.listen_fd = -1;
509 } else if(!strcmp(device_type, "generic")) { 528 } else if(!strcmp(device_type, "generic")) {
768 } 787 }
769 } 788 }
770 } 789 }
771 790
772 #define TH 0x40 791 #define TH 0x40
792 #define TR 0x20
773 #define TH_TIMEOUT 56000 793 #define TH_TIMEOUT 56000
774 794
775 void io_adjust_cycles(io_port * port, uint32_t current_cycle, uint32_t deduction) 795 void io_adjust_cycles(io_port * port, uint32_t current_cycle, uint32_t deduction)
776 { 796 {
777 /*uint8_t control = pad->control | 0x80; 797 /*uint8_t control = pad->control | 0x80;
909 port->device.pad.timeout_cycle = current_cycle + TH_TIMEOUT; 929 port->device.pad.timeout_cycle = current_cycle + TH_TIMEOUT;
910 } 930 }
911 } 931 }
912 port->output = value; 932 port->output = value;
913 break; 933 break;
934 case IO_MOUSE:
935 if ((port->control & (TH|TR)) == (TH|TR)) {
936 if (!(value & TH) && (value & TR) != (port->output & TR)) {
937 port->device.mouse.tr_counter++;
938 }
939 } else {
940 port->device.mouse.tr_counter = 0;
941 }
942 port->output = value;
943 break;
914 #ifndef _WIN32 944 #ifndef _WIN32
915 case IO_GENERIC: 945 case IO_GENERIC:
916 wait_for_connection(port); 946 wait_for_connection(port);
917 port->input[IO_STATE] = IO_WRITE_PENDING; 947 port->input[IO_STATE] = IO_WRITE_PENDING;
918 port->output = value; 948 port->output = value;
936 { 966 {
937 input = port->input[th ? GAMEPAD_TH1 : GAMEPAD_TH0]; 967 input = port->input[th ? GAMEPAD_TH1 : GAMEPAD_TH0];
938 if (!th) { 968 if (!th) {
939 input |= 0xC; 969 input |= 0xC;
940 } 970 }
971 //controller output is logically inverted
972 input = ~input;
941 break; 973 break;
942 } 974 }
943 case IO_GAMEPAD6: 975 case IO_GAMEPAD6:
944 { 976 {
945 if (current_cycle >= port->device.pad.timeout_cycle) { 977 if (current_cycle >= port->device.pad.timeout_cycle) {
961 input = port->input[GAMEPAD_TH0] & 0x30; 993 input = port->input[GAMEPAD_TH0] & 0x30;
962 } else { 994 } else {
963 input = port->input[GAMEPAD_TH0] | 0xC; 995 input = port->input[GAMEPAD_TH0] | 0xC;
964 } 996 }
965 } 997 }
998 //controller output is logically inverted
999 input = ~input;
1000 break;
1001 }
1002 case IO_MOUSE:
1003 {
1004 uint8_t tr = control & port->output & TR;
1005 if (th) {
1006 if (tr) {
1007 input = 0x10;
1008 } else {
1009 input = 0;
1010 }
1011 } else {
1012 int deltax = port->device.mouse.cur_x - port->device.mouse.last_read_x;
1013 int deltay = port->device.mouse.cur_y - port->device.mouse.last_read_y;
1014 switch (port->device.mouse.tr_counter)
1015 {
1016 case 0:
1017 input = 0xB;
1018 break;
1019 case 1:
1020 case 2:
1021 input = 0xF;
1022 break;
1023 case 3:
1024 input = 0;
1025 if (deltay > 255 || deltay < -255) {
1026 input |= 8;
1027 }
1028 if (deltax > 255 || deltax < -255) {
1029 input |= 4;
1030 }
1031 if (deltay < 0) {
1032 input |= 2;
1033 }
1034 if (deltax < 0) {
1035 input |= 1;
1036 }
1037 break;
1038 case 4:
1039 input = port->input[0];
1040 break;
1041 case 5:
1042 input = abs(deltax) >> 4 & 0xF;
1043 break;
1044 case 6:
1045 input = abs(deltax) & 0xF;
1046 break;
1047 case 7:
1048 input = abs(deltay) >> 4 & 0xF;
1049 break;
1050 case 8:
1051 input = abs(deltay) & 0xF;
1052 //need to figure out when this actually happens
1053 port->device.mouse.last_read_x = port->device.mouse.cur_x;
1054 port->device.mouse.last_read_y = port->device.mouse.cur_y;
1055 break;
1056 default:
1057 //need to test what happens here
1058 input = 0;
1059 break;
1060 }
1061 input |= tr >> 1;
1062 }
966 break; 1063 break;
967 } 1064 }
968 #ifndef _WIN32 1065 #ifndef _WIN32
969 case IO_SEGA_PARALLEL: 1066 case IO_SEGA_PARALLEL:
970 if (!th) 1067 if (!th)
971 { 1068 {
972 service_pipe(port); 1069 service_pipe(port);
973 } 1070 }
974 input = ~port->input[th ? IO_TH1 : IO_TH0]; 1071 input = port->input[th ? IO_TH1 : IO_TH0];
975 break; 1072 break;
976 case IO_GENERIC: 1073 case IO_GENERIC:
977 if (port->input[IO_TH0] & 0x80 && port->input[IO_STATE] == IO_WRITTEN) 1074 if (port->input[IO_TH0] & 0x80 && port->input[IO_STATE] == IO_WRITTEN)
978 { 1075 {
979 //device requested a blocking read after writes 1076 //device requested a blocking read after writes
980 port->input[IO_STATE] = IO_READ_PENDING; 1077 port->input[IO_STATE] = IO_READ_PENDING;
981 } 1078 }
982 service_socket(port); 1079 service_socket(port);
983 input = ~port->input[IO_TH0]; 1080 input = port->input[IO_TH0];
984 break; 1081 break;
985 #endif 1082 #endif
986 default: 1083 default:
987 input = 0; 1084 input = 0xFF;
988 break; 1085 break;
989 } 1086 }
990 uint8_t value = ((~input) & (~control)) | (port->output & control); 1087 uint8_t value = (input & (~control)) | (port->output & control);
991 /*if (port->input[GAMEPAD_TH0] || port->input[GAMEPAD_TH1]) { 1088 /*if (port->input[GAMEPAD_TH0] || port->input[GAMEPAD_TH1]) {
992 printf ("value: %X\n", value); 1089 printf ("value: %X\n", value);
993 }*/ 1090 }*/
994 return value; 1091 return value;
995 } 1092 }