Skip to content

Instantly share code, notes, and snippets.

@lpe234
Created January 3, 2025 09:31
Show Gist options
  • Save lpe234/9c5a2118a7fa0349b69d03e87683df46 to your computer and use it in GitHub Desktop.
Save lpe234/9c5a2118a7fa0349b69d03e87683df46 to your computer and use it in GitHub Desktop.
X56 H.O.T.A.S. SDL2 Reader
/*
* 解析GUID 获取VID和PID
*
* GUID: 030017173807000021a2000000000000
* VID: 0738
* PID: A221
* 返回值: (VID, PID) 大写
*/
pub fn parse_guid(guid_str: &str) -> (String, String) {
let vid = format!("{}{}", &guid_str[10..12], &guid_str[8..10]);
let pid = format!("{}{}", &guid_str[18..20], &guid_str[16..18]);
(vid.to_uppercase(), pid.to_uppercase())
}
#[cfg(test)]
mod test {
#[test]
fn test_parse_guid() {
let guid = super::parse_guid("03003187380700002122000000000000");
assert_eq!(guid, ("0738".to_string(), "2221".to_string()));
}
}
#include <SDL.h>
#include <iostream>
#include <string>
#include <vector>
void logJoystickInfo(SDL_Joystick *joystick) {
if (!joystick) return;
std::cout << "Joystick Name: " << SDL_JoystickName(joystick) << std::endl;
std::cout << "Number of Axes: " << SDL_JoystickNumAxes(joystick) << std::endl;
std::cout << "Number of Buttons: " << SDL_JoystickNumButtons(joystick) << std::endl;
std::cout << "Number of Hats: " << SDL_JoystickNumHats(joystick) << std::endl;
std::cout << "\n";
}
int main(int argc, char *argv[]) {
if (SDL_Init(SDL_INIT_JOYSTICK) < 0) {
std::cerr << "Failed to initialize SDL: " << SDL_GetError() << std::endl;
return 1;
}
const int joystickCount = SDL_NumJoysticks();
if (joystickCount == 0) {
std::cerr << "No joysticks connected!" << std::endl;
SDL_Quit();
return 1;
}
std::vector<SDL_Joystick *> x56Joysticks;
// Search for X56 joystick
for (int i = 0; i < joystickCount; ++i) {
const char *name = SDL_JoystickNameForIndex(i);
if (name && std::string(name).find("X-56") != std::string::npos) {
if (SDL_Joystick *joystick = SDL_JoystickOpen(i)) {
std::cout << "X56 joystick connected!" << std::endl;
logJoystickInfo(joystick);
x56Joysticks.push_back(joystick);
}
}
}
if (x56Joysticks.empty()) {
std::cerr << "X56 joystick not found!" << std::endl;
SDL_Quit();
return 1;
}
// Event loop to read joystick input
SDL_Event event;
bool running = true;
while (running) {
//while (SDL_PollEvent(&event)) {
while (SDL_WaitEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
running = false;
break;
case SDL_JOYAXISMOTION:
std::cout << "Axis " << static_cast<int>(event.jaxis.axis) << " moved to " << event.jaxis.value <<
std::endl;
break;
case SDL_JOYBUTTONDOWN:
std::cout << event.jbutton.which << " Button " << static_cast<int>(event.jbutton.button) << " pressed" <<
std::endl;
break;
case SDL_JOYBUTTONUP:
std::cout << "Button " << static_cast<int>(event.jbutton.button) << " released" << std::endl;
break;
case SDL_JOYDEVICEADDED:
std::cout << "Device " << event.jdevice.which << " added" << std::endl;
break;
case SDL_JOYDEVICEREMOVED:
std::cout << "Device " << event.jdevice.which << " removed" << std::endl;
break;
default:
break;
}
}
//SDL_Delay(10); // Add a small delay to prevent high CPU usage
}
// clean
for (const auto js: x56Joysticks) {
SDL_JoystickClose(js);
}
SDL_Quit();
return 0;
}
use sdl2::joystick::{Guid, Joystick};
use sdl2::JoystickSubsystem;
mod utils;
pub struct JoyDevice {
pub id: u32,
pub name: String,
pub guid: Guid,
pub joystick: Joystick,
}
impl JoyDevice {
pub fn new(joystick: Joystick) -> Self {
Self {
id: joystick.instance_id(),
name: joystick.name(),
guid: joystick.guid(),
joystick,
}
}
}
// 读取游戏设备
fn read_joy_device(ins_id: u32, js: &JoystickSubsystem) -> JoyDevice {
if let Ok(joystick) = js.open(ins_id) {
JoyDevice::new(joystick)
} else {
panic!("Failed to open joystick ID {}", ins_id);
}
}
// 设备GUID
const GUIDS: &[&str] = &[
"03003187380700002122000000000000", // 摇杆
"030017173807000021a2000000000000", // 油门
];
fn main() -> Result<(), String> {
let sdl_context = sdl2::init()?;
let joystick_subsystem = sdl_context.joystick()?;
// 存储所有的游戏设备
let mut joysticks: Vec<JoyDevice> = Vec::new();
let mut event_pump = sdl_context.event_pump()?;
for event in event_pump.wait_iter() {
use sdl2::event::Event;
match event {
Event::JoyAxisMotion {
which,
axis_idx,
value,
..
} => {
println!("Device {}: Axis {} moved to {}", which, axis_idx, value);
}
Event::JoyButtonDown {
which, button_idx, ..
} => {
println!("Device {}: Button {} pressed", which, button_idx);
}
Event::JoyButtonUp {
which, button_idx, ..
} => {
println!("Device {}: Button {} released", which, button_idx);
}
Event::JoyHatMotion {
which,
hat_idx,
state,
..
} => {
println!("Device {}: Hat {} moved to {:?}", which, hat_idx, state);
}
Event::JoyDeviceRemoved { which, .. } => {
joysticks.iter().for_each(|joy| {
if joy.id == which {
println!("Device ({}){} removed", joy.id, joy.name);
}
});
joysticks.retain(|joy: &JoyDevice| joy.id != which);
}
Event::JoyDeviceAdded { which, .. } => {
let joy_device = read_joy_device(which, &joystick_subsystem);
if GUIDS.contains(&joy_device.guid.to_string().as_str()) {
println!("Device ({}){} added", joy_device.id, joy_device.name);
joysticks.push(joy_device);
}
}
Event::Quit { .. } => break,
// 其他事件
oe => {
println!("Other event: {:?}", oe);
}
}
}
Ok(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment