diff --git a/ControllerPatcher.cpp b/ControllerPatcher.cpp
index bc580e6..be98ed1 100644
--- a/ControllerPatcher.cpp
+++ b/ControllerPatcher.cpp
@@ -457,6 +457,7 @@ void ControllerPatcher::startNetworkServer(){
void ControllerPatcher::stopNetworkServer(){
UDPServer::destroyInstance();
+ UDPClient::destroyInstance();
TCPServer::destroyInstance();
}
diff --git a/ControllerPatcher.hpp b/ControllerPatcher.hpp
index 826baed..d2364f6 100644
--- a/ControllerPatcher.hpp
+++ b/ControllerPatcher.hpp
@@ -38,6 +38,7 @@
#include "./config/ConfigValues.hpp"
#include "network/TCPServer.hpp"
#include "network/UDPServer.hpp"
+#include "network/UDPClient.hpp"
#include "dynamic_libs/sys_functions.h"
#include "dynamic_libs/syshid_functions.h"
diff --git a/network/TCPServer.cpp b/network/TCPServer.cpp
index 2e4f856..07f65af 100644
--- a/network/TCPServer.cpp
+++ b/network/TCPServer.cpp
@@ -15,6 +15,7 @@
* along with this program. If not, see .
****************************************************************************/
#include "TCPServer.hpp"
+#include "UDPClient.hpp"
#include
#include
#include
@@ -317,8 +318,13 @@ void TCPServer::DoTCPThreadInternal(){
**/
clientfd = ret = accept(sockfd, (sockaddr *)&(sock_addr), &len);
+
if(ret == -1){ ErrorHandling(); break;}
log_printf("TCPServer::DoTCPThreadInternal(line %d): TCP Connection accepted! Sending my protocol version: %d (0x%02X)\n",__LINE__, (WIIU_CP_TCP_HANDSHAKE - WIIU_CP_TCP_HANDSHAKE_VERSION_1)+1,WIIU_CP_TCP_HANDSHAKE);
+
+ gUDPClientip = sock_addr.sin_addr.s_addr;
+ UDPClient::createInstance();
+
s32 ret;
ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_HANDSHAKE); //Hey I'm a WiiU console!
if(ret < 0){ log_printf("TCPServer::DoTCPThreadInternal(line %d): Error sendbyte: %02X\n",__LINE__,WIIU_CP_TCP_HANDSHAKE); ErrorHandling(); break;}
@@ -355,10 +361,13 @@ void TCPServer::DoTCPThreadInternal(){
clientfd = -1;
}while(0);
log_printf("TCPServer::DoTCPThreadInternal(line %d): Connection closed\n",__LINE__);
+ gUDPClientip = 0;
+ UDPClient::destroyInstance();
TCPServer::DetachAndDelete(); //Clear connected controller
CloseSockets();
continue;
}
+
}
void TCPServer::DoTCPThread(ControllerPatcherThread *thread, void *arg){
diff --git a/network/TCPServer.hpp b/network/TCPServer.hpp
index a089bac..4ddbc6a 100644
--- a/network/TCPServer.hpp
+++ b/network/TCPServer.hpp
@@ -21,13 +21,14 @@
#include "dynamic_libs/socket_functions.h"
#include "utils/logger.h"
-#define WIIU_CP_TCP_HANDSHAKE WIIU_CP_TCP_HANDSHAKE_VERSION_2
+#define WIIU_CP_TCP_HANDSHAKE WIIU_CP_TCP_HANDSHAKE_VERSION_3
#define WIIU_CP_TCP_HANDSHAKE_VERSION_MIN WIIU_CP_TCP_HANDSHAKE_VERSION_1
-#define WIIU_CP_TCP_HANDSHAKE_VERSION_MAX WIIU_CP_TCP_HANDSHAKE_VERSION_2
+#define WIIU_CP_TCP_HANDSHAKE_VERSION_MAX WIIU_CP_TCP_HANDSHAKE_VERSION_3
#define WIIU_CP_TCP_HANDSHAKE_VERSION_1 0x12
#define WIIU_CP_TCP_HANDSHAKE_VERSION_2 0x13
+#define WIIU_CP_TCP_HANDSHAKE_VERSION_3 0x14
#define WIIU_CP_TCP_HANDSHAKE_ABORT 0x30
diff --git a/network/UDPClient.cpp b/network/UDPClient.cpp
new file mode 100644
index 0000000..e9d2009
--- /dev/null
+++ b/network/UDPClient.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+ * Copyright (C) 2016,2017 Maschell
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ ****************************************************************************/
+#include "UDPClient.hpp"
+#include
+#include
+#include
+#define MAX_UDP_SIZE 0x578
+
+UDPClient * UDPClient::instance = NULL;
+
+UDPClient::UDPClient(u32 ip, s32 port){
+ sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (sockfd < 0)
+ return;
+
+ struct sockaddr_in connect_addr;
+ memset(&connect_addr, 0, sizeof(connect_addr));
+ connect_addr.sin_family = AF_INET;
+ connect_addr.sin_port = port;
+ connect_addr.sin_addr.s_addr = ip;
+
+ if(connect(sockfd, (struct sockaddr*)&connect_addr, sizeof(connect_addr)) < 0)
+ {
+ socketclose(sockfd);
+ sockfd = -1;
+ }
+}
+
+UDPClient::~UDPClient(){
+ if (this->sockfd != -1){
+ socketclose(sockfd);
+ }
+ if(HID_DEBUG) log_printf("UDPClient::~UDPClient(line %d): Thread has been closed\n",__LINE__);
+}
+
+bool UDPClient::sendData(char * data,s32 length){
+ if(sockfd < 0 || data == 0 || length < 0 || gUsedProtocolVersion < WIIU_CP_TCP_HANDSHAKE_VERSION_3){
+ return false;
+ }
+ if(length > 1400) length = 1400;
+
+ s32 ret = send(sockfd, data, length, 0);
+ return (ret >= 0);
+}
diff --git a/network/UDPClient.hpp b/network/UDPClient.hpp
new file mode 100644
index 0000000..e975cdb
--- /dev/null
+++ b/network/UDPClient.hpp
@@ -0,0 +1,70 @@
+/****************************************************************************
+ * Copyright (C) 2016,2017 Maschell
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ ****************************************************************************/
+#ifndef _UDPCLIENT_WINDOW_H_
+#define _UDPCLIENT_WINDOW_H_
+
+#include
+
+#include "../ControllerPatcher.hpp"
+#include "../patcher/ControllerPatcherHID.hpp"
+#include "../utils/CPRetainVars.hpp"
+#include "dynamic_libs/socket_functions.h"
+#include "utils/logger.h"
+
+#define DEFAULT_UDP_CLIENT_PORT 8114
+
+class UDPClient{
+ friend class ControllerPatcher;
+ friend class ControllerPatcherHID;
+ friend class TCPServer;
+public:
+
+private:
+ static UDPClient *getInstance() {
+ if(instance == NULL){
+ createInstance();
+ }
+ return instance;
+ }
+
+
+ static UDPClient *createInstance() {
+ if(instance != NULL){
+ destroyInstance();
+ }
+ instance = new UDPClient(gUDPClientip,DEFAULT_UDP_CLIENT_PORT);
+
+ return getInstance();
+ }
+
+ static void destroyInstance() {
+ if(instance != NULL){
+ delete instance;
+ instance = NULL;
+ }
+ }
+
+ UDPClient(u32 ip,s32 port);
+ ~UDPClient();
+ bool sendData(char * data, s32 length);
+
+ volatile s32 sockfd = -1;
+ struct sockaddr_in addr;
+ static UDPClient *instance;
+};
+
+#endif //_UDPClient_WINDOW_H_
diff --git a/patcher/ControllerPatcherDefs.h b/patcher/ControllerPatcherDefs.h
index 728b59b..ddc305f 100644
--- a/patcher/ControllerPatcherDefs.h
+++ b/patcher/ControllerPatcherDefs.h
@@ -232,6 +232,7 @@ typedef struct _my_cb_user{
u32 pads_per_device; /**< Number of maximum pads of this device */
u8 pad_slot; /**< number of the pad that will be used */
u8 rumblestatus[HID_MAX_PADS_COUNT]; /**< Current status of the device rumble */
+ u8 rumbleForce[HID_MAX_PADS_COUNT];
}my_cb_user;
/**
diff --git a/patcher/ControllerPatcherHID.cpp b/patcher/ControllerPatcherHID.cpp
index 1e1b840..17ed39d 100644
--- a/patcher/ControllerPatcherHID.cpp
+++ b/patcher/ControllerPatcherHID.cpp
@@ -508,18 +508,40 @@ void ControllerPatcherHID::HIDGCRumble(u32 handle,my_cb_user *usr){
}
void ControllerPatcherHID::HIDRumble(u32 handle,my_cb_user *usr,u32 pad){
+ if(usr == NULL || pad > HID_MAX_PADS_COUNT) return;
+
s32 rumblechanged = 0;
HID_Data * data_ptr = &(gHID_Devices[usr->slotdata.deviceslot].pad_data[pad]);
if(data_ptr->rumbleActive != usr->rumblestatus[pad]){
usr->rumblestatus[pad] = data_ptr->rumbleActive;
rumblechanged = 1;
}
- if(rumblechanged){
+ usr->rumbleForce[pad]--;
+ if(rumblechanged || usr->rumbleForce[pad] <= 0){
+ //log_printf("Rumble: %d %d\n",usr->rumblestatus[pad],usr->rumbleForce[pad]);
+ //Seding to the network client!
+ char bytes[6];
+
+ s32 i = 0;
+ bytes[i++] = 0x01;
+ bytes[i++] = (handle >> 24) & 0xFF;
+ bytes[i++] = (handle >> 16) & 0xFF;
+ bytes[i++] = (handle >> 8) & 0xFF;
+ bytes[i++] = handle & 0xFF;
+ bytes[i++] = usr->rumblestatus[pad];
+
+ UDPClient * instance = UDPClient::getInstance();
+ if(instance != NULL){
+ instance->sendData(bytes,6);
+ }
+
+
if(usr->slotdata.hidmask == gHID_LIST_DS3){
HIDDS3Rumble(handle,usr,usr->rumblestatus[pad]);
}else{
// Not implemented for other devices =(
}
+ usr->rumbleForce[pad] = 10;
}
}
diff --git a/utils/CPRetainVars.cpp b/utils/CPRetainVars.cpp
index b1fa62f..1878def 100644
--- a/utils/CPRetainVars.cpp
+++ b/utils/CPRetainVars.cpp
@@ -59,4 +59,7 @@ u8 gUsedProtocolVersion __attribute__((section(".data"))) = WIIU_CP_TCP_HANDSHA
wpad_connect_callback_t gConnectCallback[4] __attribute__((section(".data")));
wpad_extension_callback_t gExtensionCallback[4] __attribute__((section(".data")));
-u8 gCallbackCooldown __attribute__((section(".data"))) = 0;
+u8 gCallbackCooldown __attribute__((section(".data"))) = 0;
+
+u32 gUDPClientip __attribute__((section(".data"))) = 0;
+
diff --git a/utils/CPRetainVars.hpp b/utils/CPRetainVars.hpp
index f894ac3..0dd7944 100644
--- a/utils/CPRetainVars.hpp
+++ b/utils/CPRetainVars.hpp
@@ -63,5 +63,7 @@ extern wpad_connect_callback_t gConnectCallback[4];
extern wpad_extension_callback_t gExtensionCallback[4];
extern u8 gCallbackCooldown;
+extern u32 gUDPClientip;
+
#endif // CP_RETAINS_VARS_H_