Mercurial > repos > blastem
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 } |