partial gamecube support

This commit is contained in:
Nekobit 2023-09-10 23:12:45 -04:00
parent 5136ee13e5
commit ebcdccd9a7
4 changed files with 163 additions and 16 deletions

View File

@ -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)

160
input.c
View File

@ -1,13 +1,20 @@
#include <Ecore.h>
#include <Elementary.h>
#include <libusb.h>
#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);
}

10
input.h
View File

@ -3,12 +3,18 @@
#include <SDL2/SDL.h>
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 */

5
main.c
View File

@ -3,6 +3,7 @@
#include <Ecore.h>
#include <Efl_Ui.h>
#include <Elementary.h>
#include <libusb.h>
#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();