77#include < QUdpSocket>
88#include < QTimer>
99#include < QFormLayout>
10+ #include < QVBoxLayout>
1011#include < QLineEdit>
12+ #include < QPushButton>
1113#include < QCheckBox>
1214#include < QDialog>
15+ #include < QMouseEvent>
16+ #include < QCloseEvent>
17+
18+ #include < algorithm>
19+
20+ #define CPAD_BOUND 0x5d0
21+
22+ #define TOUCH_SCREEN_WIDTH 320
23+ #define TOUCH_SCREEN_HEIGHT 240
1324
1425typedef uint32_t u32 ;
1526typedef uint16_t u16 ;
@@ -18,8 +29,12 @@ typedef uint8_t u8;
1829double lx = 0.0 , ly = 0.0 ;
1930double rx = 0.0 , ry = 0.0 ;
2031QGamepadManager::GamepadButtons buttons = 0 ;
32+ u32 specialButtons = 0 ;
2133QString ipAddress;
22- int yAxisMultiplicator = 1 ;
34+ int yAxisMultiplier = 1 ;
35+
36+ bool touchScreenPressed;
37+ QPoint touchScreenPosition;
2338
2439void sendFrame (void )
2540{
@@ -45,25 +60,44 @@ void sendFrame(void)
4560 hidPad &= ~(1 << i);
4661 }
4762
48- u32 touchState = 0x2000000 ;
49- u32 circleState = 0x7ff7ff ;
50- u16 x = ( u16 )(lx * 0x5d0 + 0x800 ) ;
51- u16 y = ( u16 )(ly * 0x5d0 + 0x800 ) ;
63+ specialButtons |= (buttons & ( 1 << QGamepadManager::ButtonGuide)) ? 1 : 0 ;
64+
65+ u32 touchScreenState = 0x2000000 ;
66+ u32 circlePadState = 0x7ff7ff ;
5267
5368 if (lx != 0.0 || ly != 0.0 )
54- circleState = ((u32 ) y << 12 ) | (u32 )x;
69+ {
70+ u32 x = (u32 )(lx * CPAD_BOUND + 0x800 );
71+ u32 y = (u32 )(ly * CPAD_BOUND + 0x800 );
72+ x = x >= 0xfff ? 0xfff : x;
73+ y = y >= 0xfff ? 0xfff : y;
5574
56- QByteArray ba (12 , 0 );
57- qToLittleEndian (hidPad, (uchar *)ba.data ());
58- qToLittleEndian (touchState, (uchar *)ba.data () + 4 );
59- qToLittleEndian (circleState, (uchar *)ba.data () + 8 );
75+ circlePadState = (y << 12 ) | x;
76+ }
6077
78+ if (touchScreenPressed)
79+ {
80+ u32 x = (u32 )(0xfff * std::min (std::max (0 , touchScreenPosition.x ()), TOUCH_SCREEN_WIDTH)) / TOUCH_SCREEN_WIDTH;
81+ u32 y = (u32 )(0xfff * std::min (std::max (0 , touchScreenPosition.y ()), TOUCH_SCREEN_HEIGHT)) / TOUCH_SCREEN_HEIGHT;
82+ touchScreenState = (1 << 24 ) | (y << 12 ) | x;
83+ }
84+
85+ u32 extraButtons = 0 ; // unk
86+ u32 cpadProState = 0 ; // unk
87+
88+ QByteArray ba (24 , 0 );
89+ qToLittleEndian (hidPad, (uchar *)ba.data ());
90+ qToLittleEndian (touchScreenState, (uchar *)ba.data () + 4 );
91+ qToLittleEndian (circlePadState, (uchar *)ba.data () + 8 );
92+ qToLittleEndian (extraButtons, (uchar *)ba.data () + 12 );
93+ qToLittleEndian (cpadProState, (uchar *)ba.data () + 16 );
94+ qToLittleEndian (specialButtons, (uchar *)ba.data () + 20 );
6195 QUdpSocket ().writeDatagram (ba, QHostAddress (ipAddress), 4950 );
6296}
6397
6498struct GamepadMonitor : public QObject {
6599
66- GamepadMonitor (QObject *parent = Q_NULLPTR ) : QObject(parent)
100+ GamepadMonitor (QObject *parent = nullptr ) : QObject(parent)
67101 {
68102 connect (QGamepadManager::instance (), &QGamepadManager::gamepadButtonPressEvent, this ,
69103 [](int deviceId, QGamepadManager::GamepadButton button, double value)
@@ -92,7 +126,7 @@ struct GamepadMonitor : public QObject {
92126 lx = value;
93127 break ;
94128 case QGamepadManager::AxisLeftY:
95- ly = yAxisMultiplicator * -value; // for some reason qt inverts this
129+ ly = yAxisMultiplier * -value; // for some reason qt inverts this
96130 break ;
97131 default : break ;
98132 }
@@ -102,14 +136,44 @@ struct GamepadMonitor : public QObject {
102136};
103137
104138struct TouchScreen : public QDialog {
105- TouchScreen (QWidget *parent = Q_NULLPTR) : QDialog(parent)
139+ TouchScreen (QWidget *parent = nullptr ) : QDialog(parent)
140+ {
141+ this ->setFixedSize (TOUCH_SCREEN_WIDTH, TOUCH_SCREEN_HEIGHT);
142+ this ->setWindowFlags (Qt::CustomizeWindowHint | Qt::WindowTitleHint);
143+ this ->setWindowTitle (tr (" InputRedirectionClient-Qt - Touch screen" ));
144+ }
145+
146+ void mousePressEvent (QMouseEvent *ev)
106147 {
107- this ->setFixedSize (320 , 240 );
148+ if (ev->button () == Qt::LeftButton)
149+ {
150+ touchScreenPressed = true ;
151+ touchScreenPosition = ev->pos ();
152+ sendFrame ();
153+ }
154+ }
155+
156+ void mouseMoveEvent (QMouseEvent *ev)
157+ {
158+ if (touchScreenPressed && (ev->buttons () & Qt::LeftButton))
159+ {
160+ touchScreenPosition = ev->pos ();
161+ sendFrame ();
162+ }
163+ }
164+
165+ void mouseReleaseEvent (QMouseEvent *ev)
166+ {
167+ if (ev->button () == Qt::LeftButton)
168+ {
169+ touchScreenPressed = false ;
170+ sendFrame ();
171+ }
108172 }
109173};
110174
111175struct FrameTimer : public QTimer {
112- FrameTimer (QObject *parent = Q_NULLPTR ) : QTimer(parent)
176+ FrameTimer (QObject *parent = nullptr ) : QTimer(parent)
113177 {
114178 connect (this , &QTimer::timeout, this ,
115179 [](void )
@@ -123,21 +187,32 @@ struct FrameTimer : public QTimer {
123187class Widget : public QWidget
124188{
125189private:
126- QFormLayout *layout;
190+ QVBoxLayout *layout;
191+ QFormLayout *formLayout;
127192 QLineEdit *addrLineEdit;
128193 QCheckBox *invertYCheckbox;
194+ QPushButton *homeButton, *powerButton, *longPowerButton;
129195 TouchScreen *touchScreen;
130196public:
131- Widget (QWidget *parent = Q_NULLPTR ) : QWidget(parent)
197+ Widget (QWidget *parent = nullptr ) : QWidget(parent)
132198 {
199+ layout = new QVBoxLayout (this );
200+
133201 addrLineEdit = new QLineEdit (this );
134202 invertYCheckbox = new QCheckBox (this );
135- layout = new QFormLayout (this );
203+ formLayout = new QFormLayout;
204+
205+ formLayout->addRow (tr (" IP &address" ), addrLineEdit);
206+ formLayout->addRow (tr (" &Invert Y axis" ), invertYCheckbox);
136207
137- layout->addRow (tr (" IP &address" ), addrLineEdit);
138- layout->addRow (tr (" &Invert Y axis" ), invertYCheckbox);
208+ homeButton = new QPushButton (tr (" &HOME" ), this );
209+ powerButton = new QPushButton (tr (" &POWER" ), this );
210+ longPowerButton = new QPushButton (tr (" POWER (&long)" ), this );
139211
140- this ->setLayout (layout);
212+ layout->addLayout (formLayout);
213+ layout->addWidget (homeButton);
214+ layout->addWidget (powerButton);
215+ layout->addWidget (longPowerButton);
141216
142217 connect (addrLineEdit, &QLineEdit::textChanged, this ,
143218 [](const QString &text)
@@ -151,16 +226,76 @@ class Widget : public QWidget
151226 switch (state)
152227 {
153228 case Qt::Unchecked:
154- yAxisMultiplicator = 1 ;
229+ yAxisMultiplier = 1 ;
155230 break ;
156231 case Qt::Checked:
157- yAxisMultiplicator = -1 ;
232+ yAxisMultiplier = -1 ;
158233 break ;
159234 default : break ;
160235 }
161236 });
162237
163- touchScreen = new TouchScreen (this ); // TODO: fix this
238+ connect (homeButton, &QPushButton::pressed, this ,
239+ [](void )
240+ {
241+ specialButtons |= 1 ;
242+ sendFrame ();
243+ });
244+
245+ connect (homeButton, &QPushButton::released, this ,
246+ [](void )
247+ {
248+ specialButtons &= ~1 ;
249+ sendFrame ();
250+ });
251+
252+ connect (powerButton, &QPushButton::pressed, this ,
253+ [](void )
254+ {
255+ specialButtons |= 2 ;
256+ sendFrame ();
257+ });
258+
259+ connect (powerButton, &QPushButton::released, this ,
260+ [](void )
261+ {
262+ specialButtons &= ~2 ;
263+ sendFrame ();
264+ });
265+
266+ connect (longPowerButton, &QPushButton::pressed, this ,
267+ [](void )
268+ {
269+ specialButtons |= 4 ;
270+ sendFrame ();
271+ });
272+
273+ connect (longPowerButton, &QPushButton::released, this ,
274+ [](void )
275+ {
276+ specialButtons &= ~4 ;
277+ sendFrame ();
278+ });
279+
280+ touchScreen = new TouchScreen (nullptr );
281+ this ->setWindowTitle (tr (" InputRedirectionClient-Qt" ));
282+ }
283+
284+ void show (void )
285+ {
286+ QWidget::show ();
287+ touchScreen->show ();
288+ }
289+
290+ void closeEvent (QCloseEvent *ev)
291+ {
292+ touchScreen->close ();
293+ ev->accept ();
294+ }
295+
296+ virtual ~Widget (void )
297+ {
298+ delete touchScreen;
164299 }
165300
166301};
0 commit comments