diff --git a/Makefile b/Makefile index e054a13..88c4de3 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CC=cc -CFLAGS=-g `pkg-config --cflags efl ecore elementary` `sdl2-config --cflags` `curl-config --cflags` -LDFLAGS=`pkg-config --libs efl ecore elementary` `sdl2-config --libs` `curl-config --libs` -lcjson +CFLAGS=-g `pkg-config --cflags efl ecore elementary libusb-1.0` `sdl2-config --cflags` `curl-config --cflags` +LDFLAGS=`pkg-config --libs efl ecore elementary libusb-1.0` `sdl2-config --libs` `curl-config --libs` -lcjson OBJS=main.o replay.o home.o input.o minilauncher4slippi: $(OBJS) diff --git a/input.c b/input.c index 6e1037f..1cd3688 100644 --- a/input.c +++ b/input.c @@ -1,13 +1,20 @@ #include #include +#include #include "input.h" Ecore_Event_Key* ev = NULL; int event_ready = 0; static SDL_GameController* gamepad; -extern Evas_Object* win, *mainer, *_tab_curr, *tab_scroller; +extern Evas_Object* win, *mainer, *_tab_curr; void _launch_slippi_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED); float y_mod = 0.0f; +//static libusb_device* gcadapter; + + +static libusb_device_handle* gcadapter = NULL; +int gc_endpoint_in; +int gc_endpoint_out; void free_ev(void* that, void* who_even_cares EINA_UNUSED) @@ -20,17 +27,18 @@ Eina_Bool _scroll_loop_cb(void* data) { int x, y, w, h; - elm_scroller_region_get(tab_scroller, &x, &y, &w, &h); + elm_scroller_region_get(mainer, &x, &y, &w, &h); y += y_mod; - elm_scroller_region_show(tab_scroller, x, y, w, h); + elm_scroller_region_show(mainer, x, y, w, h); return EINA_TRUE; } void -input_sdl_init_thread() +input_init_threads() { - ecore_timer_add(.005, _scroll_loop_cb, NULL); - Ecore_Thread* thread = ecore_thread_run(_input_sdl_setup_thread, NULL, NULL, NULL); + //ecore_timer_add(.005, _scroll_loop_cb, NULL); + ecore_thread_run(_input_sdl_setup_thread, NULL, NULL, NULL); + ecore_thread_run(_input_gcadapter_setup_thread, NULL, NULL, NULL); } static void @@ -61,7 +69,7 @@ input_sdl_eventloop(Ecore_Thread *thread) int deadzone = 3000; float r_y = SDL_GameControllerGetAxis(gamepad, SDL_CONTROLLER_AXIS_RIGHTY); - if (abs(r_y) > deadzone) + if (fabsf(r_y) > deadzone) { y_mod = r_y / 4000; } @@ -144,9 +152,143 @@ input_sdl_setup() } } +// https://github.com/nekobbbbbbit/Ishiiruka/blob/slippi/Source/Core/InputCommon/GCAdapter.cpp +static void +input_gcadapter_eventloop(Ecore_Thread *thread) +{ +} + +void +input_gcadapter_setup() +{ + libusb_device** devs; + size_t len; + int ret; + libusb_init(NULL); + len = libusb_get_device_list(NULL, &devs); + + if (len < 0) { + libusb_exit(NULL); + return; + } + + + for (int i = 0; devs[i]; i++) + { + libusb_device* dev = devs[i]; + struct libusb_device_descriptor desc; + libusb_get_device_descriptor(dev, &desc); + if (desc.idVendor == 0x057e && desc.idProduct == 0x0337) + { + printf("Found gamecube controller with vendor 0x0%X and product 0x0%X!\n", + desc.idVendor, desc.idProduct); + //gcadapter = dev; + libusb_open(dev, &gcadapter); + if ((ret = libusb_kernel_driver_active(gcadapter, 0)) == 1) + { + // Slippi Ishiiruka temp patch: A fix is underway for Dolphin-emu, but this is workaround + // on said systems. Only on FreeBSD systems, not the other BSD's I think +#ifndef __FreeBSD__ + if ((ret = libusb_detach_kernel_driver(gcadapter, 0)) && ret != LIBUSB_ERROR_NOT_SUPPORTED) + { + ERROR_LOG(SERIALINTERFACE, "libusb_detach_kernel_driver failed with error: %d", ret); + } +#endif + ret = 0; // Need to work around. + } + + // This call makes Nyko-brand (and perhaps other) adapters work. + // However it returns LIBUSB_ERROR_PIPE with Mayflash adapters. + + const int transfer = libusb_control_transfer(gcadapter, 0x21, 11, 0x0001, 0, NULL, 0, 1000); + if (transfer < 0) + ; + + if (ret != 0 && ret != LIBUSB_ERROR_NOT_SUPPORTED) + { + puts("Porbably bad."); + return; + } + else if ((ret = libusb_claim_interface(gcadapter, 0))) { + puts("Something happened. Check GCAdapter permissions."); + } + else { + puts("And we're hooked!"); + + // Now do more shit. We're way too nested :^) + libusb_config_descriptor *config = NULL; + libusb_get_config_descriptor(dev, 0, &config); + for (int ic = 0; ic < config->bNumInterfaces; ic++) + { + const libusb_interface *interfaceContainer = &config->interface[ic]; + for (int i = 0; i < interfaceContainer->num_altsetting; i++) + { + const libusb_interface_descriptor *interface = &interfaceContainer->altsetting[i]; + for (int e = 0; e < interface->bNumEndpoints; e++) + { + const libusb_endpoint_descriptor *endpoint = &interface->endpoint[e]; + if (endpoint->bEndpointAddress & LIBUSB_ENDPOINT_IN) + gc_endpoint_in = endpoint->bEndpointAddress; + else + gc_endpoint_out = endpoint->bEndpointAddress; + } + } + } + + printf("in:0x%X out:0x%X\n", gc_endpoint_in, gc_endpoint_out); + + int tmp; + unsigned char payload = 0x13; + ret = libusb_interrupt_transfer(gcadapter, gc_endpoint_out, &payload, + sizeof(payload), &tmp, 32); + + sleep(1); + + float z = 120; + while (1) + { + ret = libusb_interrupt_transfer(gcadapter, gc_endpoint_out, &payload, + sizeof(payload), &tmp, 32); + z += 0.001; + unsigned char rumble[] = {0x11,z,z,z,z}; + + ret = libusb_interrupt_transfer(gcadapter, gc_endpoint_out, rumble, sizeof(rumble), &tmp, 32); + printf("%d byte\n", tmp); + if (ret) + { + printf("Error\n"); + } + //sleep(1); + unsigned char rumbles[] = {0x11,0,0,0,0}; + + ret = libusb_interrupt_transfer(gcadapter, gc_endpoint_out, rumbles, sizeof(rumbles), &tmp, 32); + printf("%d byte\n", tmp); + if (ret) + { + printf("Error\n"); + } + //sleep(1); + } + + // END... + } + } + } + + //libusb_free_device_list(devs, 1); +} + + void _input_sdl_setup_thread(void *data, Ecore_Thread *thread) { - input_sdl_setup(); - input_sdl_eventloop(thread); + //input_sdl_setup(); + //input_sdl_eventloop(thread); +} + +void +_input_gcadapter_setup_thread(void *data, Ecore_Thread *thread) +{ + //input_gcadapter_setup(); + //input_gcadapter_eventloop(thread); } diff --git a/input.h b/input.h index 848f280..33d1562 100644 --- a/input.h +++ b/input.h @@ -3,12 +3,18 @@ #include void -input_sdl_setup(); +input_init_threads(); void -input_sdl_init_thread(); +input_sdl_setup(); void _input_sdl_setup_thread(); +void +input_gcadapter_setup(); + +void +_input_gcadapter_setup_thread(void *data, Ecore_Thread *thread); + #endif /* INPUT_H */ diff --git a/main.c b/main.c index b535564..9e5c03c 100644 --- a/main.c +++ b/main.c @@ -3,6 +3,7 @@ #include #include #include +#include #include "replay.h" #include "home.h" #ifndef NO_SDL_INPUT @@ -317,9 +318,7 @@ elm_main(int argc, char **argv) printf("[Current config] %s, %s, %s\n", game_path, dolphin_emu_file, dolphin_replay_file); // Setup input -#ifndef NO_SDL_INPUT - input_sdl_init_thread(); -#endif + input_init_threads(); elm_run();