navegando por internet, consegui un codigo en C++ que permite, que a travez de un socket tcp que se conecta directamente con una consola WII , la PC pueda leer el mando de GAMECUBE, WII, etc... osea cualquier mando que le funcione a la wii ok?
resulta que el codigo es un ejemplo, en el cual se configuro que los botones funcionaran como TECLAS VIRTUALES, usando un comando virtual keyboard, algo asi...
El control actualmente hace esto =
A = VK_Return
B = VK_Escape
X = VK_X
Y = VK_Y
L = VK_L
R = VK_R
Z = VK_Z
Start = VK_Enter
DpadUP = VK_UP
DpadDown = VK_DOWN
DpadLeft = VK_Left
DpadRight = VK_Right
pero no se configuro los Analogo del control, en el codigo viene definido los analogos como GamecubeAnalogX, AnalogY.... pero no se como mapear el control ( asignarles una tecla o una funcion como una letra del teclado o un input de joystick... no se si me explico) ....
en si lo que necesito es que me ayuden a mapear el control que quede algo asi...
GAMECUBE INPUT
A = Joy.1
B = Joy.2
X = Joy.3
Y = Joy.4
L = Joy.5
R = Joy.6
START = Joy.7
DpadUP = Joy.8
DpadDown = Joy.9
DpadLeft = Joy.10
DpadRight = Joy.11
AnalogX = Joy.X
AnalogY = Joy.y
Analog2X = Joy.2X
Analog2Y =Joy.2Y
Osea quiero que el control sea reconocido como un JOYSTICK para juegos.
Lo mas dificil ya esta, ya estableci conexion con el control, pero me hace falta mapearlo, algun crack que sepa como hacer esto? o que me ayude con alguna orientacion o guia de como lograr mapear el control al 100%? porfavor se los agradeceria en el alma.
Aqui les dejo el codigo (el cual corri y probe en Dev C++ y funciona sin problemas)
Código:
#define _WIN32_WINNT 0x0501
#pragma comment(lib,"Ws2_32.lib")
#include <iostream>
#include <stdio.h>
#include <process.h>
#include <winsock2.h>
#include <windows.h>
#include <stdint.h>
using namespace std;
// Fenster-Name
char * AppName = "StepMania";
// Applikationspfad
char * AppPath = "StepMania.exe";
// Endian Rotator for 32bit Values
#define ENDIAN_ROTATE_32(a) (((a & 0xFF) << 24) | ((a & 0xFF00) << 8) | ((a & 0xFF0000) >> 8) | ((a & 0xFF000000) >> 24))
// Wiimote Button Mappings
#define WPAD_BUTTON_2 0x0001
#define WPAD_BUTTON_1 0x0002
#define WPAD_BUTTON_B 0x0004
#define WPAD_BUTTON_A 0x0008
#define WPAD_BUTTON_MINUS 0x0010
#define WPAD_BUTTON_HOME 0x0080
#define WPAD_BUTTON_LEFT 0x0100
#define WPAD_BUTTON_RIGHT 0x0200
#define WPAD_BUTTON_DOWN 0x0400
#define WPAD_BUTTON_UP 0x0800
#define WPAD_BUTTON_PLUS 0x1000
// Nunchuk Button Mappings
#define WPAD_NUNCHUK_BUTTON_Z (0x0001<<16)
#define WPAD_NUNCHUK_BUTTON_C (0x0002<<16)
// Classic Controller Button Mappings
#define WPAD_CLASSIC_BUTTON_UP (0x0001<<16)
#define WPAD_CLASSIC_BUTTON_LEFT (0x0002<<16)
#define WPAD_CLASSIC_BUTTON_ZR (0x0004<<16)
#define WPAD_CLASSIC_BUTTON_X (0x0008<<16)
#define WPAD_CLASSIC_BUTTON_A (0x0010<<16)
#define WPAD_CLASSIC_BUTTON_Y (0x0020<<16)
#define WPAD_CLASSIC_BUTTON_B (0x0040<<16)
#define WPAD_CLASSIC_BUTTON_ZL (0x0080<<16)
#define WPAD_CLASSIC_BUTTON_FULL_R (0x0200<<16)
#define WPAD_CLASSIC_BUTTON_PLUS (0x0400<<16)
#define WPAD_CLASSIC_BUTTON_HOME (0x0800<<16)
#define WPAD_CLASSIC_BUTTON_MINUS (0x1000<<16)
#define WPAD_CLASSIC_BUTTON_FULL_L (0x2000<<16)
#define WPAD_CLASSIC_BUTTON_DOWN (0x4000<<16)
#define WPAD_CLASSIC_BUTTON_RIGHT (0x8000<<16)
// Guitar Hero Guitar Button Mappings
#define WPAD_GUITAR_HERO_3_BUTTON_STRUM_UP (0x0001<<16)
#define WPAD_GUITAR_HERO_3_BUTTON_YELLOW (0x0008<<16)
#define WPAD_GUITAR_HERO_3_BUTTON_GREEN (0x0010<<16)
#define WPAD_GUITAR_HERO_3_BUTTON_BLUE (0x0020<<16)
#define WPAD_GUITAR_HERO_3_BUTTON_RED (0x0040<<16)
#define WPAD_GUITAR_HERO_3_BUTTON_ORANGE (0x0080<<16)
#define WPAD_GUITAR_HERO_3_BUTTON_PLUS (0x0400<<16)
#define WPAD_GUITAR_HERO_3_BUTTON_MINUS (0x1000<<16)
#define WPAD_GUITAR_HERO_3_BUTTON_STRUM_DOWN (0x4000<<16)
// Gamecube Controller Button Mappings
#define PAD_BUTTON_LEFT 0x0001
#define PAD_BUTTON_RIGHT 0x0002
#define PAD_BUTTON_DOWN 0x0004
#define PAD_BUTTON_UP 0x0008
#define PAD_TRIGGER_Z 0x0010
#define PAD_TRIGGER_R 0x0020
#define PAD_TRIGGER_L 0x0040
#define PAD_BUTTON_A 0x0100
#define PAD_BUTTON_B 0x0200
#define PAD_BUTTON_X 0x0400
#define PAD_BUTTON_Y 0x0800
#define PAD_BUTTON_MENU 0x1000
#define PAD_BUTTON_START 0x1000
// Button Structure
#pragma pack(1)
typedef struct {
// Structure Size (for backwards compatiblity)
uint32_t size;
// Freshly pressed Wiimote buttons
uint32_t wiiDown[4];
// Released Wiimote buttons
uint32_t wiiUp[4];
// Lingering pressed Wiimote buttons
uint32_t wiiHeld[4];
// Battery Percentage of Wiimotes
uint8_t wiiBattery[4];
// Freshly pressed Gamecube buttons
uint32_t gcDown[4];
// Released Gamecube buttons
uint32_t gcUp[4];
// Lingering pressed Gamecube buttons
uint32_t gcHeld[4];
// Gamecube Analog Stick X-Values
uint8_t gcAnalogX[4];
// Gamecube Analog Stick Y-Values
uint8_t gcAnalogY[4];
// Gamecube Sub-Analog Stick X-Values
uint8_t gcSubAnalogX[4];
// Gamecube Sub-Analog Stick Y-Values
uint8_t gcSubAnalogY[4];
} ButtonCollection;
#pragma pack()
// Taste in gedrückt Status versetzen
void PressKey(char c)
{
INPUT ip;
ip.type = INPUT_KEYBOARD;
ip.ki.wScan = 0;
ip.ki.time = 0;
ip.ki.dwExtraInfo = 0;
//Virtual Keycodes funktionieren mit DirectInput nicht
//ip.ki.wVk = c;
//ip.ki.dwFlags = 0;
ip.ki.wScan = c;
ip.ki.dwFlags = KEYEVENTF_SCANCODE;
SendInput(1, &ip, sizeof(INPUT));
}
// Taste aus gedrückt Status befreien
void ReleaseKey(char c)
{
INPUT ip;
ip.type = INPUT_KEYBOARD;
ip.ki.wScan = 0;
ip.ki.time = 0;
ip.ki.dwExtraInfo = 0;
//Virtual Keycodes funktionieren mit DirectInput nicht
//ip.ki.wVk = c;
//ip.ki.dwFlags = KEYEVENTF_KEYUP;
ip.ki.wScan = c;
ip.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;
SendInput(1, &ip, sizeof(INPUT));
}
// Textzeichen abschicken
void Sendchar(char c)
{
INPUT ip;
ip.type = INPUT_KEYBOARD;
ip.ki.wScan = 0;
ip.ki.time = 0;
ip.ki.dwExtraInfo = 0;
//ip.ki.wVk = c;
ip.ki.wScan = c;
ip.ki.dwFlags = KEYEVENTF_SCANCODE; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
ip.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;
SendInput(1, &ip, sizeof(INPUT));
Sleep(1);
}
// Text abschicken
void SendText(char*text)
{
for(uint32_t i = 0; i < strlen(text); i++)
{
Sendchar(text[i]);
}
}
// Zahl abschicken
void SendInt(int number)
{
char buff[32];
memset(buff,0,32);
_itoa(number, buff, 10);
SendText(buff);
}
// Fensterauflistung durchführen und Fenster schließen
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
DWORD wndPid;
char Title[1024];
GetWindowThreadProcessId(hwnd, &wndPid);
GetWindowTextA(hwnd,Title,1024);
if(wndPid == (DWORD)lParam && strlen(Title) != 0)
{
// Fenster ist noch offen
PostMessage(hwnd, WM_CLOSE, 0, 0);
return false;
}
else
{
return true;
}
}
// Prozess starten
void startProcess(DWORD * processPid, char * mProcess)
{
BOOL bWorked;
STARTUPINFOA suInfo;
PROCESS_INFORMATION procInfo;
memset(&suInfo, 0, sizeof(suInfo));
suInfo.cb = sizeof(suInfo);
bWorked = CreateProcessA(mProcess, NULL, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &suInfo, &procInfo);
*processPid = procInfo.dwProcessId;
}
// Prozess beenden
void killProcess(DWORD processPid)
{
Sleep(100);
HANDLE ps = OpenProcess(SYNCHRONIZE | PROCESS_TERMINATE, FALSE, processPid);
EnumWindows(EnumWindowsProc, processPid);
CloseHandle(ps);
}
// Einstiegspunkt
int main(int argc, char * argv[])
{
// Initialize WSA
WSADATA WsaDat;
if(WSAStartup(MAKEWORD(2,2),&WsaDat) != 0)
{
printf("Winsock couldn't be initialized!\n");
WSACleanup();
return -1;
}
// Socket erzeugen
SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(serverSocket == SOCKET_ERROR)
{
printf("Socket couldn't be created!\n");
WSACleanup();
return -2;
}
// Socket Adressstruktur
SOCKADDR_IN sockAddr;
sockAddr.sin_family = AF_INET;
sockAddr.sin_addr.s_addr = INADDR_ANY;
sockAddr.sin_port = htons(23993);
// Socket an Adresse binden
if(bind(serverSocket, (SOCKADDR*)(&sockAddr), sizeof(sockAddr)) == SOCKET_ERROR)
{
printf("Socket couldn't be bound to port 23993!\n");
WSACleanup();
return -3;
}
// Socket in den Listening Modus schalten
listen(serverSocket, 1);
// Button Eingabe Socket
SOCKET buttonSocket = SOCKET_ERROR;
// Accept Schleife
while(buttonSocket == SOCKET_ERROR)
{
printf("Waiting for ButtonCast / Wii...\n");
buttonSocket = accept(serverSocket, NULL, NULL);
}
// Verbindung aufgebaut
printf("Connected to ButtonCast!\n");
// Prozess ID
DWORD processPID = 0;
// Kind-Prozess starten
startProcess(&processPID, AppPath);
// Hauptfenster
HWND windowHandle = NULL;
// Fenster finden
printf("Waiting for StepMania...\n");
while(windowHandle == NULL)
{
windowHandle = FindWindowA(0, AppName);
Sleep(1000);
}
// Akkumulationsbuffer
uint32_t bufferSize = 0;
uint8_t * buffer = NULL;
// Empfangsbuffer
uint32_t recvBufferSize = 0;
uint8_t recvBuffer[1024];
// Bearbeitungsschleife
while(true)
{
// Daten empfangen
recvBufferSize = recv(buttonSocket, (char *)recvBuffer, sizeof(recvBuffer), 0);
// Verbindung gekappt
if(recvBufferSize <= 0)
{
printf("Lost ButtonCast connectivity!\n");
break;
}
// Daten erfolgreich empfangen
else
{
// Datenbuffer allozieren
uint8_t * newBuffer = (uint8_t *)malloc(bufferSize + recvBufferSize);
// Allozierung fehlgeschlagen
if(newBuffer == NULL)
{
printf("Out of memory error occured!\n");
break;
}
// Vorhandene Daten kopieren
if(bufferSize > 0 && buffer != NULL)
{
memcpy(newBuffer, buffer, bufferSize);
free(buffer);
}
// Neue Daten anhängen
memcpy(newBuffer + bufferSize, recvBuffer, recvBufferSize);
// Bufferdaten aktualisieren
buffer = newBuffer;
bufferSize += recvBufferSize;
}
// Genug Informationen für einen Button Frame vorhanden
while(bufferSize >= sizeof(ButtonCollection))
{
// Button Frame casten
ButtonCollection * buttonFrame = (ButtonCollection *)buffer;
// Fenster in den Vordergrund drängen
SetForegroundWindow(windowHandle);
// Spieler 1 Gamecube Controller Button losgelassen
if(buttonFrame->gcUp[0] != 0)
{
// Button-Bitfeld kopieren
uint32_t buttons = ENDIAN_ROTATE_32(buttonFrame->gcUp[0]);
// Links
if(buttons & PAD_BUTTON_LEFT)
{
ReleaseKey(MapVirtualKey(VK_LEFT, MAPVK_VK_TO_VSC));
printf("Left Release\n");
}
// Rechts
if(buttons & PAD_BUTTON_RIGHT)
{
ReleaseKey(MapVirtualKey(VK_RIGHT, MAPVK_VK_TO_VSC));
printf("Right Release\n");
}
// Runter
if(buttons & PAD_BUTTON_DOWN)
{
ReleaseKey(MapVirtualKey(VK_DOWN, MAPVK_VK_TO_VSC));
printf("Down Release\n");
}
// Rauf
if(buttons & PAD_BUTTON_UP)
{
ReleaseKey(MapVirtualKey(VK_UP, MAPVK_VK_TO_VSC));
printf("Up Release\n");
}
// A-Button
if(buttons & PAD_BUTTON_A)
{
ReleaseKey(MapVirtualKey(VK_RETURN, MAPVK_VK_TO_VSC));
printf("A Release\n");
}
// B-Button
if(buttons & PAD_BUTTON_B)
{
ReleaseKey(MapVirtualKey(VK_ESCAPE, MAPVK_VK_TO_VSC));
printf("B Release\n");
}
// X-Button
if(buttons & PAD_BUTTON_X)
{
ReleaseKey(MapVirtualKey('X', MAPVK_VK_TO_VSC));
printf("X Release\n");
}
// Y-Button
if(buttons & PAD_BUTTON_Y)
{
ReleaseKey(MapVirtualKey('Y', MAPVK_VK_TO_VSC));
printf("Y Release\n");
}
// Start Button (Plus Button auf der Konami Dancemat)
if(buttons & PAD_BUTTON_START)
{
ReleaseKey(MapVirtualKey('S', MAPVK_VK_TO_VSC));
printf("Start Release\n");
}
// Z-Button (Minus Button auf der Konami Dancemat)
if(buttons & PAD_TRIGGER_Z)
{
ReleaseKey(MapVirtualKey('Z', MAPVK_VK_TO_VSC));
printf("Z Release\n");
}
// Rechte Schultertaste
if(buttons & PAD_TRIGGER_R)
{
ReleaseKey(MapVirtualKey('R', MAPVK_VK_TO_VSC));
printf("R Release\n");
}
// Linke Schultertaste
if(buttons & PAD_TRIGGER_L)
{
ReleaseKey(MapVirtualKey('L', MAPVK_VK_TO_VSC));
printf("L Release\n");
}
}
// Spieler 1 Gamecube Controller Button gedrückt
if(buttonFrame->gcDown[0] != 0)
{
// Button-Bitfeld kopieren
uint32_t buttons = ENDIAN_ROTATE_32(buttonFrame->gcDown[0]);
// Links
if(buttons & PAD_BUTTON_LEFT)
{
PressKey(MapVirtualKey(VK_LEFT, MAPVK_VK_TO_VSC));
printf("Left Press\n");
}
// Rechts
if(buttons & PAD_BUTTON_RIGHT)
{
PressKey(MapVirtualKey(VK_RIGHT, MAPVK_VK_TO_VSC));
printf("Right Press\n");
}
// Runter
if(buttons & PAD_BUTTON_DOWN)
{
PressKey(MapVirtualKey(VK_DOWN, MAPVK_VK_TO_VSC));
printf("Down Press\n");
}
// Rauf
if(buttons & PAD_BUTTON_UP)
{
PressKey(MapVirtualKey(VK_UP, MAPVK_VK_TO_VSC));
printf("Up Press\n");
}
// A-Button
if(buttons & PAD_BUTTON_A)
{
PressKey(MapVirtualKey(VK_RETURN, MAPVK_VK_TO_VSC));
printf("A Press\n");
}
// B-Button
if(buttons & PAD_BUTTON_B)
{
PressKey(MapVirtualKey(VK_ESCAPE, MAPVK_VK_TO_VSC));
printf("B Press\n");
}
// X-Button
if(buttons & PAD_BUTTON_X)
{
PressKey(MapVirtualKey('X', MAPVK_VK_TO_VSC));
printf("X Release\n");
}
// Y-Button
if(buttons & PAD_BUTTON_Y)
{
PressKey(MapVirtualKey('Y', MAPVK_VK_TO_VSC));
printf("Y Release\n");
}
// Start Button (Plus Button auf der Konami Dancemat)
if(buttons & PAD_BUTTON_START)
{
PressKey(MapVirtualKey('S', MAPVK_VK_TO_VSC));
printf("Start Release\n");
}
// Z-Button (Minus Button auf der Konami Dancemat)
if(buttons & PAD_TRIGGER_Z)
{
PressKey(MapVirtualKey('Z', MAPVK_VK_TO_VSC));
printf("Z Release\n");
}
// Rechte Schultertaste
if(buttons & PAD_TRIGGER_R)
{
PressKey(MapVirtualKey('R', MAPVK_VK_TO_VSC));
printf("R Release\n");
}
// Linke Schultertaste
if(buttons & PAD_TRIGGER_L)
{
PressKey(MapVirtualKey('L', MAPVK_VK_TO_VSC));
printf("L Release\n");
}
}
// Datenbuffer allozieren
uint8_t * newBuffer = (uint8_t *)malloc(bufferSize - sizeof(ButtonCollection));
// Allozierung erfolgreich
if(newBuffer != NULL)
{
// Vorhandene Daten kopieren
memcpy(newBuffer, buffer + sizeof(ButtonCollection), bufferSize - sizeof(ButtonCollection));
// Alten Buffer freigeben
free(buffer);
// Bufferstatus aktualisieren
buffer = newBuffer;
bufferSize -= sizeof(ButtonCollection);
}
}
}
// Prozess beenden
killProcess(processPID);
}