mirror of
https://github.com/modelec/GameController.git
synced 2026-01-18 16:47:32 +01:00
initial commit
This commit is contained in:
49
.gitignore
vendored
Normal file
49
.gitignore
vendored
Normal 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
18
CMakeLists.txt
Normal 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)
|
||||
1
GameControllerHandler.cpp
Normal file
1
GameControllerHandler.cpp
Normal file
@@ -0,0 +1 @@
|
||||
#include "GameControllerHandler.h"
|
||||
101
GameControllerHandler.h
Normal file
101
GameControllerHandler.h
Normal 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
35
main.cpp
Normal 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
38
utils.h
Normal 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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user