载入中...
搜索中...
未找到
EventSink.cpp
浏览该文件的文档.
1// Translates SDL joystick and game-controller events into engine messages, and
2// keeps the module's device table in sync on hotplug.
3//
4// This lived in the SDL event pump, which therefore had to know about the
5// Joystick module and its Pad type. Owning it here removes that edge.
6
7#include "common/Capability.h"
8#include "common/Module.h"
9#include "event/Event.h"
11#include "joystick/Joystick.h"
12#include "joystick/Pad.h"
13
14#include <SDL2/SDL_events.h>
15#include <SDL2/SDL_gamecontroller.h>
16
17#include <cmath>
18
20namespace {
21
24
26int64_t axisMilli(int16_t raw) {
27 return static_cast<int64_t>(std::lround(clampAxis(raw / 32768.0f) * 1000.0f));
28}
29
30class JoystickEventSink : public eve::event::IPlatformEventSink {
31public:
32 Message *translatePlatformEvent(const void *nativeEvent) override {
33 const auto &e = *static_cast<const SDL_Event *>(nativeEvent);
34 auto *joy = eve::ModuleManager::getInstance<Joystick>("Joystick");
35 if (!joy) return nullptr;
36
37 switch (e.type) {
38 case SDL_JOYDEVICEADDED: {
39 auto *pad = joy->addJoystick(e.jdevice.which);
40 if (!pad) return nullptr;
41 return new Message("joystickadded",
42 {Variant::makeInt(pad->getID()),
43 Variant::makeString(pad->getName()),
44 Variant::makeInt(pad->isGamepad() ? 1 : 0)});
45 }
46 case SDL_JOYDEVICEREMOVED: {
47 auto *pad = joy->getJoystickFromID(e.jdevice.which);
48 if (!pad) return nullptr;
49 const int id = pad->getID();
50 const std::string name = pad->getName();
51 joy->removeJoystick(pad);
52 return new Message("joystickremoved",
53 {Variant::makeInt(id), Variant::makeString(name)});
54 }
55 case SDL_JOYBUTTONDOWN:
56 case SDL_JOYBUTTONUP: {
57 auto *pad = joy->getJoystickFromID(e.jbutton.which);
58 if (!pad) return nullptr;
59 return new Message(
60 e.type == SDL_JOYBUTTONDOWN ? "joystickpressed" : "joystickreleased",
61 {Variant::makeInt(pad->getID()), Variant::makeInt(e.jbutton.button)});
62 }
63 case SDL_JOYAXISMOTION: {
64 auto *pad = joy->getJoystickFromID(e.jaxis.which);
65 if (!pad) return nullptr;
66 return new Message("joystickaxis",
67 {Variant::makeInt(pad->getID()), Variant::makeInt(e.jaxis.axis),
68 Variant::makeInt(axisMilli(e.jaxis.value))});
69 }
70 case SDL_JOYHATMOTION: {
71 auto *pad = joy->getJoystickFromID(e.jhat.which);
72 if (!pad) return nullptr;
73 return new Message("joystickhat",
74 {Variant::makeInt(pad->getID()), Variant::makeInt(e.jhat.hat),
75 Variant::makeString(pad->getHat(e.jhat.hat))});
76 }
77 case SDL_CONTROLLERBUTTONDOWN:
78 case SDL_CONTROLLERBUTTONUP: {
79 auto *pad = joy->getJoystickFromID(e.cbutton.which);
80 if (!pad) return nullptr;
81 const char *btn = SDL_GameControllerGetStringForButton(
82 static_cast<SDL_GameControllerButton>(e.cbutton.button));
83 return new Message(
84 e.type == SDL_CONTROLLERBUTTONDOWN ? "gamepadpressed" : "gamepadreleased",
85 {Variant::makeInt(pad->getID()), Variant::makeString(btn ? btn : "")});
86 }
87 case SDL_CONTROLLERAXISMOTION: {
88 auto *pad = joy->getJoystickFromID(e.caxis.which);
89 if (!pad) return nullptr;
90 const char *axis = SDL_GameControllerGetStringForAxis(
91 static_cast<SDL_GameControllerAxis>(e.caxis.axis));
92 return new Message("gamepadaxis", {Variant::makeInt(pad->getID()),
93 Variant::makeString(axis ? axis : ""),
94 Variant::makeInt(axisMilli(e.caxis.value))});
95 }
96 default:
97 return nullptr;
98 }
99 }
100};
101
102struct Register {
103 Register() {
104 static JoystickEventSink sink;
107 }
108} g_register;
109
110} // namespace
111} // namespace eve::joystick::sdl
const char * name
Definition RockMesh.cpp:21
A named event carrying an ordered list of Variant payloads. Pushed messages are heap-allocated; the q...
Definition Event.h:56
I * query()
Definition Capability.h:77
float clampAxis(float x)
Definition Joystick.cpp:14