Scoping out API
This commit is contained in:
@@ -1,6 +1,34 @@
|
||||
cmake_minimum_required(VERSION 3.30)
|
||||
project(jstick)
|
||||
cmake_minimum_required(VERSION 3.18...3.30)
|
||||
project(jstick
|
||||
VERSION 1.0
|
||||
LANGUAGES CXX)
|
||||
|
||||
|
||||
if (PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR)
|
||||
message(FATAL_ERROR "In-source builds are not allowed")
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
add_executable(jstick main.cpp)
|
||||
file(GLOB_RECURSE jstick_HEADERS "include/*.hpp")
|
||||
file(GLOB_RECURSE jstick_SRC "src/*.cpp")
|
||||
|
||||
include_directories("include")
|
||||
|
||||
if (UNIX)
|
||||
add_library(jstick SHARED ${jstick_SRC})
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
add_library(jstick STATIC ${jstick_SRC})
|
||||
endif()
|
||||
|
||||
target_include_directories(jstick PUBLIC ${jstick_SOURCE_DIR}/include)
|
||||
|
||||
install(TARGETS ${PROJECT_NAME} DESTINATION lib/${PROJECT_NAME})
|
||||
|
||||
install(FILES ${jstick_HEADERS} DESTINATION include/${PROJECT_NAME})
|
||||
|
||||
add_executable(jstick-test main.cpp)
|
||||
|
||||
target_link_libraries(jstick-test ${PROJECT_NAME})
|
35
include/jstick.hpp
Normal file
35
include/jstick.hpp
Normal file
@@ -0,0 +1,35 @@
|
||||
/// jstick - Dead Simple Game Controller Input Wrapper
|
||||
/// Developed and maintained by Josh O'Leary @ Redacted Software
|
||||
/// (c) 2025 redacted.cc
|
||||
/// This work is dedicated to the public domain.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace jstick {
|
||||
|
||||
//Event<int> JoystickConnected;
|
||||
//Event<int> JoystickDisconnected;
|
||||
//Event<JoystickButton> ButtonPressed;
|
||||
//Event<JoystickButton> ButtonReleased;
|
||||
//Event<int, JoystickAxis> AxisMoved;
|
||||
|
||||
|
||||
struct Joystick {
|
||||
int handle;
|
||||
|
||||
};
|
||||
|
||||
struct JoystickAxis {
|
||||
float x;
|
||||
float y;
|
||||
};
|
||||
|
||||
/// Checks the device files for a joystick with the given handle.
|
||||
/// @return True if the joystick device file exists.
|
||||
bool JoystickDetected(int jsHandle = 0);
|
||||
bool HasActiveJoystick();
|
||||
bool InitJoystick(int jsHandle = 0);
|
||||
int NumJoysticksDetected();
|
||||
void JoystickServiceUpdate();
|
||||
void ReadEventLoop();
|
||||
}
|
@@ -1,6 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
|
||||
void jstick_read_events();
|
106
src/jstick.cpp
Normal file
106
src/jstick.cpp
Normal file
@@ -0,0 +1,106 @@
|
||||
#include <jstick.hpp>
|
||||
|
||||
#include <linux/joystick.h>
|
||||
#include <cstddef>
|
||||
#include <cstdio>
|
||||
#include <format>
|
||||
#include <filesystem>
|
||||
#include <unistd.h>
|
||||
#include <bits/fs_fwd.h>
|
||||
|
||||
int js_handle;
|
||||
bool js_connected;
|
||||
|
||||
struct axis_state {
|
||||
short x, y;
|
||||
};
|
||||
|
||||
/// Reads a joystick event from the joystick device.
|
||||
/// @returns 0 on success. Otherwise -1 is returned.
|
||||
int read_event(int fd, struct js_event *event) {
|
||||
ssize_t bytes;
|
||||
|
||||
bytes = read(fd, event, sizeof(*event));
|
||||
|
||||
if (bytes == sizeof(*event))
|
||||
return 0;
|
||||
|
||||
/// Error, could not read full event.
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
bool jstick::JoystickDetected(int jsHandle) {
|
||||
return std::filesystem::exists(std::format("/dev/input/js{}", jsHandle));
|
||||
}
|
||||
|
||||
int jstick::NumJoysticksDetected() {
|
||||
int max = 4;
|
||||
for (int i = 0; i < max; i++) {
|
||||
if (!JoystickDetected(i))
|
||||
return i;
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void jstick::JoystickServiceUpdate() {
|
||||
bool has = JoystickDetected();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void ProcessButtonEvent(uint8_t button_index, bool value) {
|
||||
|
||||
}
|
||||
|
||||
void ProcessAxisEvent(uint8_t axis, short x, short y) {
|
||||
|
||||
}
|
||||
|
||||
/// Keeps track of the current axis state.
|
||||
/// @note This function assumes that axes are numbered starting from 0, and that
|
||||
/// the X axis is an even number, and the Y axis is an odd number. However, this
|
||||
/// is usually a safe assumption.
|
||||
/// @returns the axis that the event indicated.
|
||||
size_t get_axis_state(struct js_event *event, struct axis_state axes[3])
|
||||
{
|
||||
size_t axis = event->number / 2;
|
||||
|
||||
if (axis < 3)
|
||||
{
|
||||
if (event->number % 2 == 0)
|
||||
axes[axis].x = event->value;
|
||||
else
|
||||
axes[axis].y = event->value;
|
||||
}
|
||||
|
||||
return axis;
|
||||
}
|
||||
|
||||
struct js_event event;
|
||||
struct axis_state axes[3] = {0};
|
||||
size_t axis;
|
||||
|
||||
void jstick::ReadEventLoop() {
|
||||
|
||||
while (read_event(js_handle, &event) == 0) {
|
||||
switch (event.type) {
|
||||
case JS_EVENT_BUTTON:
|
||||
ProcessButtonEvent(event.number, event.value ? true : false);
|
||||
break;
|
||||
case JS_EVENT_AXIS:
|
||||
axis = get_axis_state(&event, axes);
|
||||
if (axis < 3)
|
||||
ProcessAxisEvent(axis, axes[axis].x, axes[axis].y);
|
||||
break;
|
||||
case JS_EVENT_INIT:
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user