Skip to content

Commit b9fc443

Browse files
committed
Read controller colors.
1 parent 534f132 commit b9fc443

File tree

8 files changed

+178
-33
lines changed

8 files changed

+178
-33
lines changed

ClientSource/Connection/PABotBase.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* Pokemon Automation Bot Base
22
*
3-
* From: https://github.com/PokemonAutomation/Arduino-Source
3+
* From: https://github.com/PokemonAutomation/
44
*
55
*/
66

@@ -329,13 +329,15 @@ uint64_t PABotBase::oldest_live_seqnum() const{
329329
return oldest;
330330
}
331331

332-
template <typename Params>
332+
template <typename Params, bool variable_length>
333333
void PABotBase::process_ack_request(BotBaseMessage message){
334334
auto scope_check = m_sanitizer.check_scope();
335335

336-
if (message.body.size() != sizeof(Params)){
337-
m_sniffer->log("Ignoring message with invalid size.");
338-
return;
336+
if constexpr (!variable_length){
337+
if (message.body.size() != sizeof(Params)){
338+
m_sniffer->log("Ignoring message with invalid size.");
339+
return;
340+
}
339341
}
340342
const Params* params = (const Params*)message.body.c_str();
341343
seqnum_t seqnum = params->seqnum;
@@ -502,6 +504,9 @@ void PABotBase::on_recv_message(BotBaseMessage message){
502504
case PABB_MSG_ACK_REQUEST_I32:
503505
process_ack_request<pabb_MsgAckRequestI32>(std::move(message));
504506
return;
507+
case PABB_MSG_ACK_REQUEST_DATA:
508+
process_ack_request<pabb_MsgAckRequestData, true>(std::move(message));
509+
return;
505510
case PABB_MSG_ERROR_INVALID_TYPE:{
506511
if (message.body.size() != sizeof(pabb_MsgInfoInvalidType)){
507512
m_sniffer->log("Ignoring message with invalid size.");

ClientSource/Connection/PABotBase.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* Pokemon Automation Bot Base
22
*
3-
* From: https://github.com/PokemonAutomation/Arduino-Source
3+
* From: https://github.com/PokemonAutomation/
44
*
55
* This is the main PABotBase class.
66
*
@@ -123,8 +123,10 @@ class PABotBase : public BotBaseController, private PABotBaseConnection{
123123

124124
uint64_t oldest_live_seqnum() const;
125125

126-
template <typename Params> void process_ack_request(BotBaseMessage message);
127-
template <typename Params> void process_ack_command(BotBaseMessage message);
126+
template <typename Params, bool variable_length = false>
127+
void process_ack_request(BotBaseMessage message);
128+
template <typename Params>
129+
void process_ack_command(BotBaseMessage message);
128130

129131
template <typename Params> void process_command_finished(BotBaseMessage message);
130132
virtual void on_recv_message(BotBaseMessage message) override;

ClientSource/Libraries/MessageConverter.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* Message Pretty Printing
22
*
3-
* From: https://github.com/PokemonAutomation/Arduino-Source
3+
* From: https://github.com/PokemonAutomation/
44
*
55
*/
66

@@ -184,6 +184,24 @@ int register_message_converters_framework_acks(){
184184
return ss.str();
185185
}
186186
);
187+
register_message_converter(
188+
PABB_MSG_ACK_REQUEST_DATA,
189+
[](const std::string& body){
190+
std::ostringstream ss;
191+
ss << "PABB_MSG_ACK_REQUEST_DATA - ";
192+
// if (body.size() != sizeof(pabb_MsgAckRequestI32)){ ss << "(invalid size)" << std::endl; return ss.str(); }
193+
const auto* params = (const pabb_MsgAckRequestI32*)body.c_str();
194+
ss << "seqnum = " << (uint64_t)params->seqnum;
195+
ss << ", bytes = " << body.size() - sizeof(seqnum_t);
196+
ss << ", data =";
197+
static const char HEX_DIGITS[] = "0123456789abcdef";
198+
for (size_t c = sizeof(seqnum_t); c < body.size(); c++){
199+
uint8_t byte = body[c];
200+
ss << " " << HEX_DIGITS[(byte >> 4)] << " " << HEX_DIGITS[byte & 15];
201+
}
202+
return ss.str();
203+
}
204+
);
187205
return 0;
188206
}
189207
int register_message_converters_framework_requests(){

Common/Cpp/Options/ColorOption.cpp

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@ ColorCell::ColorCell(const ColorCell& x)
1717
{}
1818
ColorCell::ColorCell(
1919
LockMode lock_while_running,
20-
bool allow_alpha,
20+
bool has_alpha,
2121
uint32_t default_value, uint32_t current_value
2222
)
2323
: ConfigOption(lock_while_running)
24-
, m_allow_alpha(allow_alpha)
24+
, m_has_alpha(has_alpha)
2525
, m_default_value(default_value)
2626
, m_current_value(current_value)
2727
{
28-
if (!m_allow_alpha){
28+
if (!m_has_alpha){
2929
m_default_value &= 0x00ffffff;
3030
m_current_value &= 0x00ffffff;
3131
}
@@ -34,30 +34,37 @@ uint32_t ColorCell::default_value() const{
3434
return m_default_value;
3535
}
3636
std::string ColorCell::to_str() const{
37+
return color_to_str(*this, m_has_alpha);
38+
}
39+
std::string ColorCell::color_to_str(uint32_t color, bool has_alpha){
3740
static const char HEX_DIGITS[] = "0123456789ABCDEF";
38-
std::string str(6, '0');
39-
uint32_t x = *this;
40-
str[0] = HEX_DIGITS[(x >> 20) & 0xf];
41-
str[1] = HEX_DIGITS[(x >> 16) & 0xf];
42-
str[2] = HEX_DIGITS[(x >> 12) & 0xf];
43-
str[3] = HEX_DIGITS[(x >> 8) & 0xf];
44-
str[4] = HEX_DIGITS[(x >> 4) & 0xf];
45-
str[5] = HEX_DIGITS[(x >> 0) & 0xf];
41+
std::string str;
42+
size_t c = 0;
43+
if (has_alpha){
44+
str[c++] += HEX_DIGITS[(color >> 28) & 0xf];
45+
str[c++] += HEX_DIGITS[(color >> 24) & 0xf];
46+
}
47+
str[c++] += HEX_DIGITS[(color >> 20) & 0xf];
48+
str[c++] += HEX_DIGITS[(color >> 16) & 0xf];
49+
str[c++] += HEX_DIGITS[(color >> 12) & 0xf];
50+
str[c++] += HEX_DIGITS[(color >> 8) & 0xf];
51+
str[c++] += HEX_DIGITS[(color >> 4) & 0xf];
52+
str[c++] += HEX_DIGITS[(color >> 0) & 0xf];
4653
return str;
4754
}
4855
ColorCell::operator uint32_t() const{
4956
return m_current_value.load(std::memory_order_relaxed);
5057
}
5158
void ColorCell::set(uint32_t x){
52-
if (!m_allow_alpha){
59+
if (!m_has_alpha){
5360
x &= 0x00ffffff;
5461
}
5562
if (x != m_current_value.exchange(x, std::memory_order_relaxed)){
5663
report_value_changed(this);
5764
}
5865
}
5966
void ColorCell::set(const std::string& str){
60-
size_t max_digits = m_allow_alpha ? 8 : 6;
67+
size_t max_digits = m_has_alpha ? 8 : 6;
6168

6269
uint32_t x = 0;
6370
size_t count = 0;
@@ -95,7 +102,7 @@ void ColorCell::set(const std::string& str){
95102

96103
break;
97104
}
98-
if (!m_allow_alpha){
105+
if (!m_has_alpha){
99106
x &= 0x00ffffff;
100107
}
101108
set(x);

Common/Cpp/Options/ColorOption.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,13 @@ class ColorCell : public ConfigOption{
1919
ColorCell(const ColorCell& x);
2020
ColorCell(
2121
LockMode lock_while_running,
22-
bool allow_alpha,
22+
bool has_alpha,
2323
uint32_t default_value, uint32_t current_value
2424
);
2525

2626
uint32_t default_value() const;
2727
std::string to_str() const;
28+
static std::string color_to_str(uint32_t color, bool has_alpha);
2829

2930
operator uint32_t() const;
3031
void set(uint32_t x);
@@ -38,7 +39,7 @@ class ColorCell : public ConfigOption{
3839

3940

4041
private:
41-
bool m_allow_alpha;
42+
bool m_has_alpha;
4243
uint32_t m_default_value;
4344
std::atomic<uint32_t> m_current_value;
4445
};

Common/NintendoSwitch/NintendoSwitch_Protocol_ESP32.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ typedef struct{
5353
#define PABB_MSG_ESP32_REQUEST_STATUS 0x50
5454
typedef struct{
5555
seqnum_t seqnum;
56-
} PABB_PACK pabb_esp32_RequestStatus;
56+
} PABB_PACK pabb_esp32_request_status;
5757

5858

5959
#if 0
@@ -67,13 +67,18 @@ typedef struct{
6767

6868

6969

70-
#define PABB_MSG_ESP32_GET_COLORS 0x64
71-
#define PABB_MSG_ESP32_SET_COLORS 0x65
70+
#define PABB_MSG_ESP32_REQUEST_GET_COLORS 0x64
71+
typedef struct{
72+
seqnum_t seqnum;
73+
uint32_t controller_type;
74+
} PABB_PACK pabb_esp32_get_colors;
75+
76+
#define PABB_MSG_ESP32_REQUEST_SET_COLORS 0x65
7277
typedef struct{
7378
seqnum_t seqnum;
7479
uint32_t controller_type;
7580
ControllerColors colors;
76-
} PABB_PACK pabb_esp32_colors;
81+
} PABB_PACK pabb_esp32_set_colors;
7782

7883

7984
#define PABB_MSG_ESP32_CONTROLLER_STATE_BUTTONS 0xa0

SerialPrograms/Source/NintendoSwitch/Controllers/SerialPABotBase/NintendoSwitch_SerialPABotBase_WirelessController.cpp

Lines changed: 108 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,17 @@
88
#include "Common/Cpp/PrettyPrint.h"
99
#include "Common/Cpp/Concurrency/ReverseLockGuard.h"
1010
#include "Common/NintendoSwitch/NintendoSwitch_Protocol_ESP32.h"
11+
#include "Common/PokemonSwSh/PokemonProgramIDs.h"
1112
#include "ClientSource/Libraries/MessageConverter.h"
1213
#include "ClientSource/Connection/BotBaseMessage.h"
1314
#include "CommonFramework/GlobalSettingsPanel.h"
1415
#include "CommonFramework/Options/Environment/ThemeSelectorOption.h"
1516
#include "NintendoSwitch_SerialPABotBase_WirelessController.h"
1617

18+
//#include <iostream>
19+
//using std::cout;
20+
//using std::endl;
21+
1722
namespace PokemonAutomation{
1823
namespace NintendoSwitch{
1924

@@ -32,6 +37,7 @@ SerialPABotBase_WirelessController::SerialPABotBase_WirelessController(
3237
controller_type,
3338
connection
3439
)
40+
, m_controller_type(controller_type)
3541
, m_stopping(false)
3642
, m_status_thread(&SerialPABotBase_WirelessController::status_thread, this)
3743
{}
@@ -57,7 +63,7 @@ void SerialPABotBase_WirelessController::stop(){
5763

5864
class SerialPABotBase_WirelessController::MessageControllerStatus : public BotBaseRequest{
5965
public:
60-
pabb_esp32_RequestStatus params;
66+
pabb_esp32_request_status params;
6167
MessageControllerStatus()
6268
: BotBaseRequest(false)
6369
{
@@ -67,6 +73,19 @@ class SerialPABotBase_WirelessController::MessageControllerStatus : public BotBa
6773
return BotBaseMessage(PABB_MSG_ESP32_REQUEST_STATUS, params);
6874
}
6975
};
76+
class SerialPABotBase_WirelessController::MessageControllerColors : public BotBaseRequest{
77+
public:
78+
pabb_esp32_get_colors params;
79+
MessageControllerColors(uint32_t controller_type)
80+
: BotBaseRequest(false)
81+
{
82+
params.seqnum = 0;
83+
params.controller_type = controller_type;
84+
}
85+
virtual BotBaseMessage message() const override{
86+
return BotBaseMessage(PABB_MSG_ESP32_REQUEST_GET_COLORS, params);
87+
}
88+
};
7089
class SerialPABotBase_WirelessController::MessageControllerState : public BotBaseRequest{
7190
public:
7291
pabb_esp32_report30 params;
@@ -93,8 +112,31 @@ int register_message_converters_ESP32(){
93112
}
94113
std::ostringstream ss;
95114
ss << "ESP32_controller_status() - ";
96-
if (body.size() != sizeof(pabb_esp32_RequestStatus)){ ss << "(invalid size)" << std::endl; return ss.str(); }
97-
const auto* params = (const pabb_esp32_RequestStatus*)body.c_str();
115+
if (body.size() != sizeof(pabb_esp32_request_status)){ ss << "(invalid size)" << std::endl; return ss.str(); }
116+
const auto* params = (const pabb_esp32_request_status*)body.c_str();
117+
ss << "seqnum = " << (uint64_t)params->seqnum;
118+
return ss.str();
119+
}
120+
);
121+
register_message_converter(
122+
PABB_MSG_ESP32_REQUEST_GET_COLORS,
123+
[](const std::string& body){
124+
std::ostringstream ss;
125+
ss << "pabb_esp32_get_colors() - ";
126+
if (body.size() != sizeof(pabb_esp32_get_colors)){ ss << "(invalid size)" << std::endl; return ss.str(); }
127+
const auto* params = (const pabb_esp32_get_colors*)body.c_str();
128+
ss << "seqnum = " << (uint64_t)params->seqnum;
129+
ss << ", controller = " << (uint64_t)params->controller_type;
130+
return ss.str();
131+
}
132+
);
133+
register_message_converter(
134+
PABB_MSG_ESP32_REQUEST_SET_COLORS,
135+
[](const std::string& body){
136+
std::ostringstream ss;
137+
ss << "pabb_esp32_set_colors() - ";
138+
if (body.size() != sizeof(pabb_esp32_set_colors)){ ss << "(invalid size)" << std::endl; return ss.str(); }
139+
const auto* params = (const pabb_esp32_set_colors*)body.c_str();
98140
ss << "seqnum = " << (uint64_t)params->seqnum;
99141
return ss.str();
100142
}
@@ -154,6 +196,68 @@ void SerialPABotBase_WirelessController::status_thread(){
154196
constexpr std::chrono::milliseconds PERIOD(1000);
155197
std::atomic<WallClock> last_ack(current_time());
156198

199+
// Read controller colors.
200+
std::string color_html;
201+
#if 1
202+
try{
203+
m_logger.log("Reading Controller Colors...");
204+
uint32_t controller_id = PABB_CID_NONE;
205+
switch (m_controller_type){
206+
case ControllerType::NintendoSwitch_WirelessProController:
207+
controller_id = PABB_CID_NINTENDO_SWITCH_WIRELESS_PRO_CONTROLLER;
208+
break;
209+
case ControllerType::NintendoSwitch_LeftJoycon:
210+
controller_id = PABB_CID_NINTENDO_SWITCH_LEFT_JOYCON;
211+
break;
212+
case ControllerType::NintendoSwitch_RightJoycon:
213+
controller_id = PABB_CID_NINTENDO_SWITCH_RIGHT_JOYCON;
214+
break;
215+
default:;
216+
}
217+
BotBaseMessage response = m_serial->issue_request_and_wait(
218+
MessageControllerColors(controller_id),
219+
&m_scope
220+
);
221+
ControllerColors colors{};
222+
if (response.body.size() == sizeof(seqnum_t) + sizeof(ControllerColors)){
223+
memcpy(&colors, response.body.data() + sizeof(seqnum_t), sizeof(ControllerColors));
224+
}else{
225+
m_logger.log(
226+
"Invalid response size to PABB_MSG_ESP32_GET_COLORS: body = " + std::to_string(response.body.size()),
227+
COLOR_RED
228+
);
229+
m_handle.set_status_line1("Error: See log for more information.", COLOR_RED);
230+
return;
231+
}
232+
m_logger.log("Reading Controller Colors... Done");
233+
234+
switch (m_controller_type){
235+
case ControllerType::NintendoSwitch_WirelessProController:{
236+
Color left(colors.left_grip[0], colors.left_grip[1], colors.left_grip[2]);
237+
Color body(colors.body[0], colors.body[1], colors.body[2]);
238+
Color right(colors.right_grip[0], colors.right_grip[1], colors.right_grip[2]);
239+
color_html += html_color_text("&#x2b24;", left);
240+
color_html += " " + html_color_text("&#x2b24;", body);
241+
color_html += " " + html_color_text("&#x2b24;", right);
242+
break;
243+
}
244+
case ControllerType::NintendoSwitch_LeftJoycon:
245+
case ControllerType::NintendoSwitch_RightJoycon:{
246+
Color body(colors.body[0], colors.body[1], colors.body[2]);
247+
color_html = html_color_text("&#x2b24;", body);
248+
break;
249+
}
250+
default:;
251+
}
252+
253+
}catch (Exception& e){
254+
e.log(m_logger);
255+
m_handle.set_status_line1("Error: See log for more information.", COLOR_RED);
256+
return;
257+
}
258+
#endif
259+
260+
157261
std::thread watchdog([&, this]{
158262
WallClock next_ping = current_time();
159263
while (true){
@@ -212,6 +316,7 @@ void SerialPABotBase_WirelessController::status_thread(){
212316
? html_color_text("Yes", theme_friendly_darkblue())
213317
: html_color_text("No", COLOR_RED)
214318
);
319+
str += " - " + color_html;
215320

216321
m_handle.set_status_line1(str);
217322
}catch (OperationCancelledException&){

0 commit comments

Comments
 (0)