initial commit

This commit is contained in:
ackimixs
2024-05-14 22:54:06 +02:00
commit cc011859fd
6 changed files with 242 additions and 0 deletions

49
.gitignore vendored Normal file
View File

@@ -0,0 +1,49 @@
### C++ template
# Prerequisites
*.d
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
*.smod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
### CMake template
CMakeLists.txt.user
CMakeCache.txt
CMakeFiles
CMakeScripts
Testing
Makefile
cmake_install.cmake
install_manifest.txt
compile_commands.json
CTestTestfile.cmake
_deps
build
cmake-build-debug
.idea

18
CMakeLists.txt Normal file
View File

@@ -0,0 +1,18 @@
cmake_minimum_required(VERSION 3.27)
project(GameController)
set(CMAKE_CXX_STANDARD 17)
find_package(SDL2 REQUIRED)
include_directories(${SDL2_INCLUDE_DIRS})
find_package(PkgConfig REQUIRED)
pkg_check_modules(TCPSocket REQUIRED TCPSocket)
add_executable(GameController
main.cpp
utils.h
GameControllerHandler.h)
target_link_libraries(GameController ${SDL2_LIBRARIES})
target_link_libraries(GameController TCPSocket)

View File

@@ -0,0 +1 @@
#include "GameControllerHandler.h"

101
GameControllerHandler.h Normal file
View File

@@ -0,0 +1,101 @@
#pragma once
#include <SDL.h>
#include <iostream>
#include <TCPSocket/TCPClient.hpp>
#include "utils.h"
class GameControllerHandler : public TCPClient {
public:
explicit GameControllerHandler(const char* ip = "127.0.0.1", int port = 8080) : TCPClient(ip, port), controller(nullptr) {}
bool init() {
if (SDL_Init(SDL_INIT_GAMECONTROLLER) != 0) {
std::cerr << "SDL initialization failed: " << SDL_GetError() << std::endl;
return false;
}
if (!SDL_IsGameController(0)) {
std::cerr << "No compatible controllers connected.\n";
return false;
}
controller = SDL_GameControllerOpen(0);
if (controller == nullptr) {
std::cerr << "Failed to open game controller: " << SDL_GetError() << std::endl;
return false;
}
return true;
}
void start() {
TCPClient::start();
std::thread t(&GameControllerHandler::handleEvents, this);
t.detach();
}
void handleEvents() {
while (running) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
running = false;
break;
case SDL_CONTROLLERAXISMOTION:
if (event.caxis.axis == SDL_CONTROLLER_AXIS_TRIGGERLEFT) {
// std::cout << "Trigger left moved to " << event.caxis.value << std::endl;
this->sendMessage("gc;strat;trigger;0," + std::to_string(event.caxis.value) + "\n");
} else if (event.caxis.axis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT) {
// std::cout << "Trigger right moved to " << event.caxis.value << std::endl;
this->sendMessage("gc;strat;trigger;1," + std::to_string(event.caxis.value) + "\n");
}
else if (event.caxis.axis == SDL_CONTROLLER_AXIS_LEFTX) {
// std::cout << "Left X axis moved to " << event.caxis.value << std::endl;
this->sendMessage("gc;strat;axis;0," + std::to_string(event.caxis.value) + "\n");
}
else if (event.caxis.axis == SDL_CONTROLLER_AXIS_LEFTY) {
std::cout << "Left Y axis moved to " << event.caxis.value << std::endl;
this->sendMessage("gc;strat;axis;1," + std::to_string(event.caxis.value) + "\n");
}
else if (event.caxis.axis == SDL_CONTROLLER_AXIS_RIGHTX) {
std::cout << "Right X axis moved to " << event.caxis.value << std::endl;
this->sendMessage("gc;strat;axis;2," + std::to_string(event.caxis.value) + "\n");
}
else if (event.caxis.axis == SDL_CONTROLLER_AXIS_RIGHTY) {
// std::cout << "Right Y axis moved to " << event.caxis.value << std::endl;
// this->sendMessage("gc;strat;axis;3," + std::to_string(event.caxis.value) + "\n");
}
break;
case SDL_CONTROLLERBUTTONDOWN:
// std::cout << "Button down " << static_cast<int>(event.cbutton.button) << std::endl;
this->sendMessage("gc;strat;button down;" + std::to_string(event.cbutton.button) + "\n");
case SDL_CONTROLLERBUTTONUP:
// std::cout << "Button up " << static_cast<int>(event.cbutton.button) << std::endl;
this->sendMessage("gc;strat;button up;" + std::to_string(event.cbutton.button) + "\n");
break;
}
}
}
}
void closeController() {
if (controller != nullptr) {
SDL_GameControllerClose(controller);
controller = nullptr;
}
}
void close() {
closeController();
}
~GameControllerHandler() {
close();
SDL_Quit();
}
private:
SDL_GameController* controller;
};

35
main.cpp Normal file
View File

@@ -0,0 +1,35 @@
#include "GameControllerHandler.h"
#include <atomic>
#include <mutex>
#include <csignal>
std::atomic<bool> shouldStop = false;
void signalHandler( int signum ) {
shouldStop = true;
}
int main(int argc, char* argv[]) {
signal(SIGINT, signalHandler);
int port = 8080;
if (argc > 1) {
port = atoi(argv[1]);
}
GameControllerHandler gameControllerHandler("127.0.0.1", port);
if (!gameControllerHandler.init()) {
return 1;
}
gameControllerHandler.start();
while (!shouldStop && !gameControllerHandler.shouldStop()) {
usleep(500'000);
}
gameControllerHandler.stop();
return 0;
}

38
utils.h Normal file
View File

@@ -0,0 +1,38 @@
#pragma once
#include <string>
#include <vector>
namespace Utils {
inline bool startWith(const std::string& str, const std::string& start)
{
return str.rfind(start, 0) == 0;
}
inline bool endsWith(const std::string& str, const std::string& end)
{
if (str.length() >= end.length())
{
return (0 == str.compare(str.length() - end.length(), end.length(), end));
}
return false;
}
inline bool contains(const std::string& str, const std::string& sub)
{
return str.find(sub) != std::string::npos;
}
inline std::vector<std::string> split(const std::string& str, const std::string& delimiter) {
std::vector<std::string> tokens;
size_t prev = 0, pos = 0;
do
{
pos = str.find(delimiter, prev);
if (pos == std::string::npos) pos = str.length();
std::string token = str.substr(prev, pos - prev);
if (!token.empty()) tokens.push_back(token);
prev = pos + delimiter.length();
} while (pos < str.length() && prev < str.length());
return tokens;
}
}