Works (except it crashes when Brokenithm is out of focus)

pull/1/head
beerpsi 2023-12-30 23:50:42 +07:00
parent cd5503d380
commit 2da8f0a699
3 changed files with 65 additions and 36 deletions

View File

@ -8,6 +8,16 @@ set(CMAKE_CXX_STANDARD 17)
set(CMAKE_C_COMPILER "gcc") set(CMAKE_C_COMPILER "gcc")
set(CMAKE_CXX_COMPILER "g++") set(CMAKE_CXX_COMPILER "g++")
include(CheckIPOSupported)
check_ipo_supported(RESULT supported OUTPUT error)
if (supported)
message(STATUS "IPO / LTO enabled")
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
else()
message(STATUS "IPO / LTO not supported: <${error}>")
endif()
link_directories(src) link_directories(src)
add_library(chuniio_brokenithm SHARED src/chuniio.c add_library(chuniio_brokenithm SHARED src/chuniio.c
src/chuniio.h src/chuniio.h
@ -20,4 +30,4 @@ add_library(chuniio_brokenithm SHARED src/chuniio.c
set_target_properties(chuniio_brokenithm PROPERTIES PREFIX "") set_target_properties(chuniio_brokenithm PROPERTIES PREFIX "")
set_target_properties(chuniio_brokenithm PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32 -Wl,--allow-multiple-definition") set_target_properties(chuniio_brokenithm PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32 -Wl,--allow-multiple-definition")
target_link_libraries(chuniio_brokenithm "-static-libgcc -Wl,-Bstatic -limobiledevice-1.0 -lssl -lcrypto -lplist-2.0 -lusbmuxd-2.0 -lwinpthread -Wl,-Bdynamic -lws2_32 -lcrypt32 -liphlpapi") target_link_libraries(chuniio_brokenithm "-static-libgcc -Wl,-Bstatic -limobiledevice-1.0 -lssl -lcrypto -lplist-2.0 -lusbmuxd-2.0 -lpthread -Wl,-Bdynamic -lws2_32 -lcrypt32 -liphlpapi")

View File

@ -291,11 +291,13 @@ unsigned int __stdcall android_input_recv_thread_proc(void *v) {
const int read = recv(sHost, buffer + recv_len, 4 - recv_len, 0); const int read = recv(sHost, buffer + recv_len, 4 - recv_len, 0);
if (read == -1) { if (read == -1) {
if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) { int error = WSAGetLastError();
if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN || error == WSAETIMEDOUT) {
continue; continue;
} }
print_err("[INFO] Device disconnected!\n"); print_err("[INFO] Device disconnected (could not read data, errno %d, os error %ld)\n", errno, error);
ctx->connected = false; ctx->connected = false;
ctx->exit_flag = true; ctx->exit_flag = true;
break; break;
@ -311,11 +313,13 @@ unsigned int __stdcall android_input_recv_thread_proc(void *v) {
const int read = recv(sHost, buffer + recv_len, packet_len - recv_len, 0); const int read = recv(sHost, buffer + recv_len, packet_len - recv_len, 0);
if (read == -1) { if (read == -1) {
if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) { int error = WSAGetLastError();
if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN || error == WSAETIMEDOUT) {
continue; continue;
} }
print_err("[INFO] Device disconnected!\n"); print_err("[INFO] Device disconnected (could not read data, errno %d, os error %ld)\n", errno, error);
ctx->connected = false; ctx->connected = false;
ctx->exit_flag = true; ctx->exit_flag = true;
break; break;
@ -410,6 +414,8 @@ unsigned int __stdcall android_input_recv_thread_proc(void *v) {
} }
} }
free(ctx);
return 0; return 0;
} }
@ -428,7 +434,7 @@ unsigned int __stdcall server_thread_proc(void* ctx) {
android_thread_ctx args = { android_thread_ctx args = {
.sock = sock, .sock = sock,
.exit_flag = false, .exit_flag = false,
.connected = true, .connected = false,
.last_input_packet_id = 0, .last_input_packet_id = 0,
.memory = memory, .memory = memory,
}; };
@ -466,16 +472,15 @@ unsigned int __stdcall server_thread_proc(void* ctx) {
print_err("[INFO] Device %s:%d connected.\n", user_address, user_socket.sin_port); print_err("[INFO] Device %s:%d connected.\n", user_address, user_socket.sin_port);
} }
android_thread_ctx args = { android_thread_ctx* args = malloc(sizeof(android_thread_ctx));
.sock = acc_socket, args->sock = acc_socket;
.exit_flag = false, args->exit_flag = false;
.connected = true, args->connected = true;
.last_input_packet_id = 0, args->last_input_packet_id = 0,
.memory = memory, args->memory = memory;
};
_beginthreadex(NULL, 0, android_led_broadcast_thread_proc, &args, 0, NULL); _beginthreadex(NULL, 0, android_led_broadcast_thread_proc, args, 0, NULL);
_beginthreadex(NULL, 0, android_input_recv_thread_proc, &args, 0, NULL); _beginthreadex(NULL, 0, android_input_recv_thread_proc, args, 0, NULL);
} }
#pragma clang diagnostic pop #pragma clang diagnostic pop
} }
@ -597,9 +602,14 @@ unsigned int __stdcall ios_input_recv_thread_proc(void *v) {
} }
print_err("[INFO] Device disconnected."); print_err("[INFO] Device disconnected.");
idevice_disconnect(ctx->connection); idevice_disconnect(ctx->connection);
free(ctx->connection); ctx->connection = NULL;
idevice_free(ctx->device); idevice_free(ctx->device);
free(ctx);
return 0;
} }
unsigned int __stdcall connect_device(void* v) { unsigned int __stdcall connect_device(void* v) {
@ -614,7 +624,8 @@ unsigned int __stdcall connect_device(void* v) {
if ((status = idevice_connect(ctx->device, 24864, &ctx->connection))) { if ((status = idevice_connect(ctx->device, 24864, &ctx->connection))) {
print_err("[ERROR] Connection failed: %d, retrying in 5 seconds\n", status); print_err("[ERROR] Connection failed: %d, retrying in 5 seconds\n", status);
free(ctx->connection);
ctx->connection = NULL;
idevice_free(ctx->device); idevice_free(ctx->device);
Sleep(5000); Sleep(5000);
@ -629,21 +640,28 @@ unsigned int __stdcall connect_device(void* v) {
if ((status = idevice_connection_receive(ctx->connection, buf, 4, &read))) { if ((status = idevice_connection_receive(ctx->connection, buf, 4, &read))) {
print_err("[ERROR] Receiving data failed: %d\n", status); print_err("[ERROR] Receiving data failed: %d\n", status);
idevice_disconnect(ctx->connection); idevice_disconnect(ctx->connection);
free(ctx->connection); ctx->connection = NULL;
idevice_free(ctx->device); idevice_free(ctx->device);
return 1; return 1;
} }
if (memcmp(buf, "\x03WEL", 4) != 0) { if (memcmp(buf, "\x03WEL", 4) != 0) {
print_err("[ERROR] Client sent invalid data\n"); print_err("[ERROR] Client sent invalid data\n");
idevice_disconnect(ctx->connection); idevice_disconnect(ctx->connection);
free(ctx->connection); ctx->connection = NULL;
idevice_free(ctx->device); idevice_free(ctx->device);
return 1; return 1;
} }
print_err("[INFO] Connected to device\n"); print_err("[INFO] Connected to device\n");
ctx->exit_flag = false;
_beginthreadex(NULL, 0, ios_input_recv_thread_proc, ctx, 0, NULL); _beginthreadex(NULL, 0, ios_input_recv_thread_proc, ctx, 0, NULL);
_beginthreadex(NULL, 0, ios_led_broadcast_thread_proc, ctx, 0, NULL); _beginthreadex(NULL, 0, ios_led_broadcast_thread_proc, ctx, 0, NULL);
@ -657,13 +675,14 @@ void device_event_callback(const idevice_event_t* event, void* user_data) {
case IDEVICE_DEVICE_ADD: case IDEVICE_DEVICE_ADD:
print_err("[INFO] iDevice added, udid: %s\n", event->udid); print_err("[INFO] iDevice added, udid: %s\n", event->udid);
ios_thread_ctx args = { ios_thread_ctx* args = malloc(sizeof(ios_thread_ctx));
.exit_flag = false, args->exit_flag = false;
.memory = memory, args->memory = memory;
}; args->device = NULL;
args->connection = NULL;
memcpy(args->remote_udid, event->udid, strlen(event->udid));
memcpy(args.remote_udid, event->udid, strlen(event->udid)); _beginthreadex(NULL, 0, connect_device, args, 0, NULL);
_beginthreadex(NULL, 0, connect_device, &args, 0, NULL);
break; break;
case IDEVICE_DEVICE_REMOVE: case IDEVICE_DEVICE_REMOVE:
print_err("[INFO] iDevice removed, udid: %s\n", event->udid); print_err("[INFO] iDevice removed, udid: %s\n", event->udid);
@ -710,7 +729,7 @@ HRESULT server_start() {
print_err("[ERROR] Subscribing for iDevice events failed: %d\n", status); print_err("[ERROR] Subscribing for iDevice events failed: %d\n", status);
return E_FAIL; return E_FAIL;
} else { } else {
print_err("[INFO] Waiting for iDevices..."); print_err("[INFO] Waiting for iDevices...\n");
} }
return S_OK; return S_OK;

View File

@ -24,7 +24,7 @@ enum {
The latest API version as of this writing is 0x0101. */ The latest API version as of this writing is 0x0101. */
uint16_t chuni_io_get_api_version(); uint16_t __declspec(dllexport) chuni_io_get_api_version();
/* Initialize JVS-based input. This function will be called before any other /* Initialize JVS-based input. This function will be called before any other
chuni_io_jvs_*() function calls. Errors returned from this function will chuni_io_jvs_*() function calls. Errors returned from this function will
@ -36,7 +36,7 @@ uint16_t chuni_io_get_api_version();
Minimum API version: 0x0100 */ Minimum API version: 0x0100 */
HRESULT chuni_io_jvs_init(); HRESULT __declspec(dllexport) chuni_io_jvs_init();
/* Poll JVS input. /* Poll JVS input.
@ -60,7 +60,7 @@ HRESULT chuni_io_jvs_init();
Minimum API version: 0x0100 Minimum API version: 0x0100
Latest API version: 0x0101 */ Latest API version: 0x0101 */
void chuni_io_jvs_poll(uint8_t *opbtn, uint8_t *beams); void __declspec(dllexport) chuni_io_jvs_poll(uint8_t *opbtn, uint8_t *beams);
/* Read the current state of the coin counter. This value should be incremented /* Read the current state of the coin counter. This value should be incremented
for every coin detected by the coin acceptor mechanism. This count does not for every coin detected by the coin acceptor mechanism. This count does not
@ -68,7 +68,7 @@ void chuni_io_jvs_poll(uint8_t *opbtn, uint8_t *beams);
Minimum API version: 0x0100 */ Minimum API version: 0x0100 */
void chuni_io_jvs_read_coin_counter(uint16_t *total); void __declspec(dllexport) chuni_io_jvs_read_coin_counter(uint16_t *total);
/* Initialize touch slider emulation. This function will be called before any /* Initialize touch slider emulation. This function will be called before any
@ -80,7 +80,7 @@ void chuni_io_jvs_read_coin_counter(uint16_t *total);
Minimum API version: 0x0100 */ Minimum API version: 0x0100 */
HRESULT chuni_io_slider_init(void); HRESULT __declspec(dllexport) chuni_io_slider_init(void);
/* Chunithm touch slider layout: /* Chunithm touch slider layout:
@ -116,7 +116,7 @@ typedef void (*chuni_io_slider_callback_t)(const uint8_t *state);
Minimum API version: 0x0100 */ Minimum API version: 0x0100 */
void chuni_io_slider_start(void *callback); void __declspec(dllexport) chuni_io_slider_start(void *callback);
/* Stop polling the slider. You must cease to invoke the input callback before /* Stop polling the slider. You must cease to invoke the input callback before
returning from this function. returning from this function.
@ -131,7 +131,7 @@ void chuni_io_slider_start(void *callback);
Minimum API version: 0x0100 */ Minimum API version: 0x0100 */
void chuni_io_slider_stop(void); void __declspec(dllexport) chuni_io_slider_stop(void);
/* Update the RGB lighting on the slider. A pointer to an array of 32 * 3 = 96 /* Update the RGB lighting on the slider. A pointer to an array of 32 * 3 = 96
bytes is supplied. The illuminated areas on the touch slider are some bytes is supplied. The illuminated areas on the touch slider are some
@ -140,7 +140,7 @@ void chuni_io_slider_stop(void);
Minimum API version: 0x0100 */ Minimum API version: 0x0100 */
void chuni_io_slider_set_leds(const uint8_t *rgb); void __declspec(dllexport) chuni_io_slider_set_leds(const uint8_t *rgb);
/* Initialize LED emulation. This function will be called before any /* Initialize LED emulation. This function will be called before any
other chuni_io_led_*() function calls. other chuni_io_led_*() function calls.
@ -151,7 +151,7 @@ void chuni_io_slider_set_leds(const uint8_t *rgb);
Minimum API version: 0x0102 */ Minimum API version: 0x0102 */
HRESULT chuni_io_led_init(void); HRESULT __declspec(dllexport) chuni_io_led_init(void);
/* Update the RGB LEDs. rgb is a pointer to an array of up to 63 * 3 = 189 bytes. /* Update the RGB LEDs. rgb is a pointer to an array of up to 63 * 3 = 189 bytes.
@ -167,6 +167,6 @@ HRESULT chuni_io_led_init(void);
Minimum API version: 0x0102 */ Minimum API version: 0x0102 */
void chuni_io_led_set_colors(uint8_t board, uint8_t *rgb); void __declspec(dllexport) chuni_io_led_set_colors(uint8_t board, uint8_t *rgb);
#endif //CHUNIIO_BROKENITHM_CHUNIIO_H #endif //CHUNIIO_BROKENITHM_CHUNIIO_H