-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathkeypadservice.cpp
More file actions
154 lines (129 loc) · 3.72 KB
/
keypadservice.cpp
File metadata and controls
154 lines (129 loc) · 3.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#include <string>
#include <stdexcept>
#include <exception>
#include <consolelogger.h>
#include <filelogger.h>
#include <settings.h>
#include <keymapping.h>
#include <keybindconverter.h>
#if PLATFORM_LINUX
#include <linuxjoystick.h>
#include <linuxkeyboard.h>
#include <csignal>
#elif PLATFORM_WINDOWS
#include <windowsjoystick.h>
#include <windowskeyboard.h>
#include <windows.h>
#endif
#define safe_delete(ptr) if(ptr) { delete ptr; ptr = NULL; }
#define MAX_CONNECT_ATTEMPTS 5
// Forward-declared method signatures
KeyMapping buildKeyMap(std::string fileLocation);
Joystick* createJoystick(MessageLogger* pLogger, const Settings* pSettings);
Keyboard* createKeyboard(MessageLogger* pLogger, const Settings* pSettings);
void sleep(int sleepMs);
void setupSignalHandler();
// Globals
bool isRunning = true;
std::string settingsFileLocation = "service_settings.txt";
#if PLATFORM_WINDOWS
BOOL WINAPI signalHandler(DWORD signal) { if (signal == CTRL_C_EVENT || signal == CTRL_CLOSE_EVENT) { isRunning = false; return TRUE; } return FALSE; }
#elif PLATFORM_LINUX
void signalHandler(int signalNum) { isRunning = false; }
#endif
int main (int argc, char** argv) {
Keyboard* pKeyboard = NULL;
Joystick* pJoystick = NULL;
ConsoleLogger logger;
setupSignalHandler();
try {
Settings settings(settingsFileLocation.c_str());
settings.load();
std::string fileLocation = settings.getValue("keybindings_location");
KeyMapping keyMap = buildKeyMap(fileLocation);
pKeyboard = createKeyboard(&logger, &settings);
pJoystick = createJoystick(&logger, &settings);
pJoystick->buttonPressed = [&](ControllerButton btn) {
pKeyboard->sendKeyPress(keyMap.getKeyboardButtonFor(btn));
};
pJoystick->buttonReleased = [&](ControllerButton btn) {
pKeyboard->sendKeyRelease(keyMap.getKeyboardButtonFor(btn));
};
int connectAttempts = 0;
pJoystick->connect();
while (isRunning) {
if (!pJoystick->isActive() && connectAttempts < MAX_CONNECT_ATTEMPTS) {
pJoystick->connect();
++connectAttempts;
continue;
}
if (!pJoystick->isActive() && connectAttempts >= MAX_CONNECT_ATTEMPTS) {
throw std::runtime_error("Joystick connect attempt threshold met.");
}
connectAttempts = 0;
pJoystick->fillState();
sleep(25);
}
}
catch (std::exception& ex) {
logger.log(ex.what());
}
catch (...) {
logger.log("Unknown exception occurred");
}
safe_delete(pJoystick);
safe_delete(pKeyboard);
return 0;
}
void setupSignalHandler() {
#if PLATFORM_WINDOWS
SetConsoleCtrlHandler(signalHandler, TRUE);
#elif PLATFORM_LINUX
signal(SIGHUP, signalHandler);
signal(SIGINT, signalHandler);
#endif
}
Joystick* createJoystick(MessageLogger* pLogger, const Settings* pSettings) {
#if PLATFORM_WINDOWS
return new WindowsJoystick(pLogger);
#elif PLATFORM_LINUX
return new LinuxJoystick(pLogger, pSettings->getValue("joystick_port"));
#else
throw std::runtime_error("Unsupported platform");
#endif
}
Keyboard* createKeyboard(MessageLogger* pLogger, const Settings* pSettings) {
#if PLATFORM_WINDOWS
return new WindowsKeyboard(pLogger);
#elif PLATFORM_LINUX
return new LinuxKeyboard(pLogger, pSettings->getValue("keyboard_port"));
#else
throw std::runtime_error("Unsupported platform");
#endif
}
void sleep(int sleepMs) {
#if PLATFORM_WINDOWS
Sleep(sleepMs);
#elif PLATFORM_LINUX
usleep(sleepMs);
#endif
}
KeyMapping buildKeyMap(std::string fileLocation) {
KeyMapping keyMap = {};
ifstream inFile(fileLocation);
if (!inFile) {
std::string msg = "Unable to load '";
msg.append(fileLocation);
msg.append("'");
throw std::runtime_error(msg.c_str());
}
std::string line;
while (getline(inFile, line)) {
if (line.length() == 0) {
continue;
}
KeyBind bind = KeyBindConverter::toKeyBind(line);
keyMap.addBinding(bind);
}
return keyMap;
}