CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/Core/Debugger/WebSocket/InputBroadcaster.cpp
Views: 1401
1
// Copyright (c) 2018- PPSSPP Project.
2
3
// This program is free software: you can redistribute it and/or modify
4
// it under the terms of the GNU General Public License as published by
5
// the Free Software Foundation, version 2.0 or later versions.
6
7
// This program is distributed in the hope that it will be useful,
8
// but WITHOUT ANY WARRANTY; without even the implied warranty of
9
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
// GNU General Public License 2.0 for more details.
11
12
// A copy of the GPL 2.0 should have been included with the program.
13
// If not, see http://www.gnu.org/licenses/
14
15
// Official git repository and contact information can be found at
16
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
17
18
#include <unordered_map>
19
#include "Core/Debugger/WebSocket/InputBroadcaster.h"
20
#include "Core/Debugger/WebSocket/InputSubscriber.h"
21
#include "Core/Debugger/WebSocket/WebSocketUtils.h"
22
#include "Core/HLE/sceCtrl.h"
23
#include "Core/HW/Display.h"
24
25
// Button press state change (input.buttons)
26
//
27
// Sent unexpectedly with these properties:
28
// - buttons: an object with button names as keys and bool press state as values.
29
// - changed: same as buttons, but only including changed states.
30
//
31
// See input.buttons.send in InputSubscriber for button names.
32
33
// Analog position change (input.analog)
34
//
35
// Sent unexpectedly with these properties:
36
// - stick: "left" or "right".
37
// - x: number between -1.0 and 1.0, representing horizontal position in a square.
38
// - y: number between -1.0 and 1.0, representing vertical position in a square.
39
40
std::string InputBroadcaster::Analog::Event(const char *stick) {
41
JsonWriter j;
42
j.begin();
43
j.writeString("event", "input.analog");
44
j.writeString("stick", stick);
45
j.writeFloat("x", x);
46
j.writeFloat("y", y);
47
j.end();
48
return j.str();
49
}
50
51
static std::string ButtonsEvent(uint32_t lastButtons, uint32_t newButtons) {
52
uint32_t pressed = newButtons & ~lastButtons;
53
uint32_t released = ~newButtons & lastButtons;
54
55
JsonWriter j;
56
j.begin();
57
j.writeString("event", "input.buttons");
58
j.pushDict("buttons");
59
for (auto it : WebSocketInputButtonLookup()) {
60
j.writeBool(it.first, (newButtons & it.second) != 0);
61
}
62
j.pop();
63
j.pushDict("changed");
64
for (auto it : WebSocketInputButtonLookup()) {
65
if (pressed & it.second) {
66
j.writeBool(it.first, true);
67
} else if (released & it.second) {
68
j.writeBool(it.first, false);
69
}
70
}
71
j.pop();
72
j.end();
73
return j.str();
74
}
75
76
void InputBroadcaster::Broadcast(net::WebSocketServer *ws) {
77
int counter = __DisplayGetNumVblanks();
78
if (lastCounter_ == counter)
79
return;
80
lastCounter_ = counter;
81
82
uint32_t newButtons = __CtrlPeekButtons();
83
if (newButtons != lastButtons_) {
84
ws->Send(ButtonsEvent(lastButtons_, newButtons));
85
lastButtons_ = newButtons;
86
}
87
88
Analog newAnalog;
89
__CtrlPeekAnalog(CTRL_STICK_LEFT, &newAnalog.x, &newAnalog.y);
90
if (!lastAnalog_[0].Equals(newAnalog)) {
91
ws->Send(newAnalog.Event("left"));
92
lastAnalog_[0].x = newAnalog.x;
93
lastAnalog_[0].y = newAnalog.y;
94
}
95
96
__CtrlPeekAnalog(CTRL_STICK_RIGHT, &newAnalog.x, &newAnalog.y);
97
if (!lastAnalog_[1].Equals(newAnalog)) {
98
ws->Send(newAnalog.Event("right"));
99
lastAnalog_[1].x = newAnalog.x;
100
lastAnalog_[1].y = newAnalog.y;
101
}
102
}
103
104