From cc011859fd6c9928f664700ffe9f2ab564645131 Mon Sep 17 00:00:00 2001 From: ackimixs Date: Tue, 14 May 2024 22:54:06 +0200 Subject: [PATCH] initial commit --- .gitignore | 49 ++++++++++++++++++ CMakeLists.txt | 18 +++++++ GameControllerHandler.cpp | 1 + GameControllerHandler.h | 101 ++++++++++++++++++++++++++++++++++++++ main.cpp | 35 +++++++++++++ utils.h | 38 ++++++++++++++ 6 files changed, 242 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 GameControllerHandler.cpp create mode 100644 GameControllerHandler.h create mode 100644 main.cpp create mode 100644 utils.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..edfc3f9 --- /dev/null +++ b/.gitignore @@ -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 \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..6902ce9 --- /dev/null +++ b/CMakeLists.txt @@ -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) \ No newline at end of file diff --git a/GameControllerHandler.cpp b/GameControllerHandler.cpp new file mode 100644 index 0000000..86b3f98 --- /dev/null +++ b/GameControllerHandler.cpp @@ -0,0 +1 @@ +#include "GameControllerHandler.h" diff --git a/GameControllerHandler.h b/GameControllerHandler.h new file mode 100644 index 0000000..e77a56b --- /dev/null +++ b/GameControllerHandler.h @@ -0,0 +1,101 @@ +#pragma once + +#include +#include + +#include + +#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(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(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; +}; diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..7cd1bf3 --- /dev/null +++ b/main.cpp @@ -0,0 +1,35 @@ +#include "GameControllerHandler.h" + +#include +#include +#include + +std::atomic 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; +} diff --git a/utils.h b/utils.h new file mode 100644 index 0000000..5062974 --- /dev/null +++ b/utils.h @@ -0,0 +1,38 @@ +#pragma once +#include +#include + +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 split(const std::string& str, const std::string& delimiter) { + std::vector 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; + } +} \ No newline at end of file