// g27led_v2.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include #include #define BUFFER_SIZE 512 // Receive buffer size (basically maximum packet size in UDP). #define HOST "127.0.0.1" // Host to connect to. #define PORT 30000 // Port to connect to the host through. #define FIRST_LEDS_ON 4000.00f #define REDLINE_LEDS 8000.00f // Include Logitech headers #include "Include/LogiWheel.h" #include "Include/LogiControllerInput.h" // Define types used by InSim. typedef unsigned char byte; typedef unsigned short word; typedef struct { int X, Y, Z; } Vec; typedef struct { float X, Y, Z; } Vector; // Include InSim header. #include "Include/insim.h" using namespace LogitechSteeringWheel; using namespace LogitechControllerInput; // Declare variables for the Logitech Wheel Wheel* g_wheel; ControllerInput* g_controllerInput; // Declare RPM variable too float inRpm = 0; // Level of debbuging, passed by external argument // 0 = Default, no verbosity // 1 = Print what RPM are we getting from OutGauge // 2 = Confirm that LED data is being sent to wheel // 3 = As 2, but send data only to devices that are of type LG_DEVICE_TYPE_WHEEL int debugLevel = 0; bool bePrecise = FALSE; // More than one Logitech wheel can be connected. We have to take care of all of them. int wheelIdx = 0; int initInSimConnection(); void processOutGaugePacket(const OutGaugePack packet); CString printErrorMsgBox(HRESULT hrHes, bool showErrBox); bool isAcceptableDevice(int wheelIdx, bool bePrecise); int _tmain(int argc, char** argv) { if(argc > 1) { int debugArg = atoi(argv[1]); if((debugArg >= 0) && (debugArg < 4)) { debugLevel = debugArg; } } if (debugLevel == 3) { bePrecise = TRUE; } //Bit of a hack, we need the HWND of LFS's window //so let's get it by finding it's window. FindWindow //method returns HWND of a window it finds. HWND hLfsWin = FindWindow(L"LFS", NULL); //Exit if no LFS window was found., if(hLfsWin == NULL) { CString errMsg = "Cannot find active LFS instance.\nMake sure LFS is running."; MessageBox(NULL, errMsg, NULL, NULL); std::cout << "Bailing out" << std::endl; return EXIT_FAILURE; } //Initialize the wheel input g_controllerInput = new ControllerInput(hLfsWin, TRUE); g_wheel = new Wheel(g_controllerInput); g_controllerInput->Update(); g_wheel->Update(); //We've done all we need, so let's connect to LFS's OutGauge and //start doing our job:) std::wcout << "Init completeted, connecting to LFS" << std::endl; //Connect to InSim int retState = initInSimConnection(); return retState; } int initInSimConnection() { // Initialise WinSock version 2.2. WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { WSACleanup(); std::wcerr << "Error: Failed to init WinSock" << std::endl; return EXIT_FAILURE; } // Create UDP socket. SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (sock == INVALID_SOCKET) { WSACleanup(); std::wcerr << "Error: Could not create socket." << std::endl; return EXIT_FAILURE; } // Bind to receive UDP packets. sockaddr_in saddr; saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = inet_addr(HOST); saddr.sin_port = htons(PORT); if (bind(sock, (sockaddr *)&saddr, sizeof(sockaddr)) == SOCKET_ERROR) { closesocket(sock); WSACleanup(); std::wcerr << "Error: Could not connect to LFS" << std::endl; return EXIT_FAILURE; } std::wcout << "Connection established, recieving data" << std::endl; // Packet receive loop. char recvbuf[BUFFER_SIZE]; memset(recvbuf, 0, sizeof(recvbuf)); // Set recvbuf to zero. int bytes = 0; do { bytes = recv(sock, recvbuf, BUFFER_SIZE, 0); if (bytes > 0) { processOutGaugePacket((OutGaugePack &)recvbuf); } else if (bytes == 0) std::wcerr << "Error: Lost connection to LFS" << std::endl; else std::wcerr << "Error: " << WSAGetLastError() << std::endl; } while (bytes > 0); // Cleanup and exit. closesocket(sock); WSACleanup(); delete g_wheel; delete g_controllerInput; return EXIT_SUCCESS; } void processOutGaugePacket(const OutGaugePack packet) { inRpm = packet.RPM; if (debugLevel > 0) { std::wcout << "Current RPM is: " << inRpm << std::endl; } g_controllerInput->Update(); g_wheel->Update(); for(wheelIdx = 0; wheelIdx < LogitechSteeringWheel::LG_MAX_CONTROLLERS; wheelIdx++) { if(isAcceptableDevice(wheelIdx, bePrecise)) { //Print whether the data has been sent if (debugLevel >= 2) { HRESULT hrRes = g_wheel->PlayLeds(wheelIdx, inRpm, FIRST_LEDS_ON, REDLINE_LEDS); std::wcout << "RPM data sent to device ID = " << wheelIdx << " with HRESULT = " << printErrorMsgBox(hrRes, FALSE).GetBuffer(0) << std::endl; continue; } g_wheel->PlayLeds(wheelIdx, inRpm, FIRST_LEDS_ON, REDLINE_LEDS); } } } CString printErrorMsgBox(HRESULT hrRes, bool showErrBox) { CString errMsg; switch(hrRes) { case S_OK: errMsg = L"S_OK"; break; case E_ABORT: errMsg = L"E_ABORT"; break; case E_ACCESSDENIED: errMsg = L"E_ACCESSDENIED"; break; case E_FAIL: errMsg = L"E_FAIL"; break; case E_HANDLE: errMsg = L"E_HANDLE"; break; case E_INVALIDARG: errMsg = L"E_INVALIDARG"; break; case E_NOINTERFACE: errMsg = L"E_NOINTERFACE"; break; case E_NOTIMPL: errMsg = L"E_NOTIMPL"; break; case E_OUTOFMEMORY: errMsg = L"E_OUTOFMEMORY"; break; case E_POINTER: errMsg = L"E_POINTER"; break; case E_UNEXPECTED: errMsg = L"E_UNEXPECTED"; break; default: unsigned int errCode = hrRes; printf("%x", errCode); } if(showErrBox) { MessageBox(NULL, errMsg, NULL, NULL); } return errMsg; } //Checks the state od a device and returns TRUE if device is OK to use //If bePrecise argument is TRUE, returns TRUE only if the device is of type LG_DEVICE_TYPE_WHEEL bool isAcceptableDevice(int wheelIdx, bool bePrecise) { if(bePrecise == FALSE) { return g_wheel->IsConnected(wheelIdx); } else { return g_wheel->IsConnected(wheelIdx, LG_DEVICE_TYPE_WHEEL); } }