libOpenWinControls
Multiplatform open-source library to interact with the dual-mode controller in GPD devices
Loading...
Searching...
No Matches
ControllerV2.h
1/*
2 * This file is part of libOpenWinControls.
3 * Copyright (C) 2026 kylon
4 *
5 * libOpenWinControls is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * libOpenWinControls is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18#pragma once
19
20#include "Controller.h"
21#include "../include/BackButtonMode.h"
23
24namespace OWC {
29 class OWC_EXPORT ControllerV2 final: public Controller {
30 private:
31 enum struct CMD: int {
32 Init1 = 0x21,
33 Init2 = 0x2b,
34 Version = 0x41,
35 Read = 0x44,
36 Write = 0x43,
37 Checksum = 0x27,
38 Cmd25 = 0x25,
39 FlashLock = 0x29,
40 FlashUnlock = 0x2a,
41 EndCmd = 0x22
42 };
43
44 static constexpr uint8_t resetBuf[] = {0x4b, 0x00, 0x4a, 0x00, 0x4e, 0x00, 0x4d, 0x00, 0x28, 0x00, 0x2b, 0x00, 0x29, 0x00, 0x2c, 0x00, 0x2a, 0x00, 0x15, 0x00, 0x1e, 0x00, 0xeb, 0x00, 0xea, 0x00, 0xec, 0x00, 0xed, 0x00, 0xe1, 0x00, 0x08, 0x00, 0x1a, 0x00, 0x16, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x80, 0x02, 0x80, 0x03, 0x80, 0x04, 0x80, 0x05, 0x80, 0x06, 0x80, 0x07, 0x80, 0x08, 0x80, 0x09, 0x80, 0x0a, 0x80, 0x0b, 0x80, 0x0c, 0x80, 0x0d, 0x80, 0x0e, 0x80, 0x0f, 0x80, 0x10, 0x80, 0x11, 0x80, 0x12, 0x80, 0x13, 0x80, 0x14, 0x80, 0x15, 0x80, 0x16, 0x80, 0x17, 0x80, 0x18, 0x80, 0x19, 0x80, 0x1a, 0x80, 0x1b, 0x80, 0x1c, 0x80, 0x1d, 0x80, 0x1e, 0x80, 0x1f, 0x80, 0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
45 static constexpr uint8_t init1Packet[] = {0xa2, 0xa3, 0xa0, 0xa1, 0xa6, 0xa7, 0xa4, 0xa5, 0xba, 0xbb, 0xb8, 0xb9, 0xbe, 0xbf, 0xbc, 0xbd, 0xb2, 0xb3, 0xb0, 0xb1, 0xb6, 0xb7, 0xb4, 0xb5, 0x8a, 0x8b, 0x88, 0x89, 0x8e, 0x8f, 0x8c, 0x8d, 0x82, 0x83, 0x80, 0x81, 0x86, 0x87, 0x84, 0x85, 0x9a, 0x9b, 0x98, 0x99, 0x9e, 0x9f, 0x9c, 0x9d, 0x92, 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95};
46 static constexpr uint8_t Init2Packet[] = {0xd0, 0x07, 0x00, 0x00};
47 static constexpr size_t init1PacketSz = sizeof(init1Packet);
48 static constexpr size_t Init2PacketSz = sizeof(Init2Packet);
49 static constexpr int configBufLen = 1024;
50 static constexpr int configHeaderSz = 12;
51 uint8_t *configBuf = nullptr;
52 uint8_t *configData = nullptr; // handle to data
53 int8_t *configDataI8 = nullptr; // alias
54 uint16_t *configDataU16 = nullptr; // alias
55
56 [[nodiscard]] bool sendInit1Request() const;
57 [[nodiscard]] bool sendInit2Request() const;
58 [[nodiscard]] bool sendCmd25Request() const;
59 [[nodiscard]] bool memWriteConfig() const;
60 [[nodiscard]] bool flashConfig() const;
61 void prepareSendBuffer(CMD cmd, int bytesCount = 0) const;
62 [[nodiscard]] bool isCmdRejected() const;
63 [[nodiscard]] bool isValidRespPacket() const;
64 [[nodiscard]] bool isChecksumValid() const;
65 [[nodiscard]] int getBackButtonModeIdx(int num) const;
66 [[nodiscard]] int getBackButtonKeyPos(int num, int slot) const;
67
68 protected:
69 [[nodiscard]] int getVID() const override { return 0x2f24; }
70 [[nodiscard]] int getPID() const override { return 0x137; }
71
72 public:
77 explicit ControllerV2(int controllerFeatures = 0);
78 ~ControllerV2() override;
79
80 [[nodiscard]] int getControllerType() const override { return 2; }
81
86 [[nodiscard]] EmulationMode getEmulationMode() const;
87
95 void setBackButtonActiveSlots(int num, uint8_t count) const;
96
104 [[nodiscard]] int getBackButtonActiveSlots(int num) const;
105
114 void setBackButtonHoldTime(int num, int slot, int timeMs) const;
115
124 [[nodiscard]] int getBackButtonHoldTime(int num, int slot) const;
125
126 [[nodiscard]] bool readVersion() override;
127 [[nodiscard]] bool readConfig() override;
128 [[nodiscard]] bool writeConfig() const override;
129 [[nodiscard]] bool writeConfigMem() const override;
130 [[nodiscard]] bool resetConfig() const override;
131 [[nodiscard]] bool setButton(Button btn, const std::string &key) const override;
132 [[nodiscard]] std::string getButton(Button btn) const override;
133 void setBackButtonMode(int num, BackButtonMode mode) const;
134 [[nodiscard]] BackButtonMode getBackButtonMode(int num) const;
135 [[nodiscard]] bool setBackButton(int num, int slot, const std::string &key) const override;
136 [[nodiscard]] std::string getBackButton(int num, int slot) const override;
137 void setBackButtonStartTime(int num, int slot, int timeMs) const override;
138 [[nodiscard]] int getBackButtonStartTime(int num, int slot) const override;
139 void setRumble(RumbleMode mode) const override;
140 [[nodiscard]] RumbleMode getRumbleMode() const override;
141 void setLedMode(LedMode mode) const override;
142 [[nodiscard]] LedMode getLedMode() const override;
143 void setLedColor(int r, int g, int b) const override;
144 [[nodiscard]] std::tuple<int, int, int> getLedColor() const override;
145 void setAnalogCenter(int center, bool left) const override;
146 [[nodiscard]] int getAnalogCenter(bool left) const override;
147 void setAnalogBoundary(int boundary, bool left) const override;
148 [[nodiscard]] int getAnalogBoundary(bool left) const override;
149 };
150}
Button
enum to refer to a physical button and its mode
Definition Button.h:28
EmulationMode
controller emulation mode
Definition EmulationMode.h:28
LedMode
led mode
Definition LedMode.h:28
RumbleMode
vibration intensity
Definition RumbleMode.h:28
int getControllerType() const override
int value of the controller class version
Definition ControllerV2.h:80
ControllerV2(int controllerFeatures=0)
create a new ControllerV2 controller
Definition ControllerV2.cpp:29