feat: add poll rate display in GC Adapter config (#7)

for some reason i'm seeing 250hz readings every now and then instead of 500hz

also adds reduced rate warning, i'm not in love with the implentation, but it works well enough
This commit is contained in:
Nikhil Narayana 2023-10-13 09:41:26 -07:00 committed by GitHub
commit 9eca21b273
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 88 additions and 1 deletions

View file

@ -6,6 +6,7 @@
#include <QCheckBox>
#include <QDialogButtonBox>
#include <QLabel>
#include <QTimer>
#include <QVBoxLayout>
#include "Core/Config/MainSettings.h"
@ -36,18 +37,24 @@ void GCPadWiiUConfigDialog::CreateLayout()
m_layout = new QVBoxLayout();
m_status_label = new QLabel();
m_poll_rate_label = new QLabel();
m_rumble = new QCheckBox(tr("Enable Rumble"));
m_simulate_bongos = new QCheckBox(tr("Simulate DK Bongos"));
m_button_box = new QDialogButtonBox(QDialogButtonBox::Ok);
UpdateAdapterStatus();
UpdatePollRate();
m_poll_rate_timer = new QTimer(this);
auto callback = [this] { QueueOnObject(this, &GCPadWiiUConfigDialog::UpdateAdapterStatus); };
GCAdapter::SetAdapterCallback(callback);
m_layout->addWidget(m_status_label);
m_layout->addWidget(m_poll_rate_label);
m_layout->addWidget(m_rumble);
m_layout->addWidget(m_simulate_bongos);
// slippi change: no need to let users turn on bongos
// m_layout->addWidget(m_simulate_bongos);
m_layout->addWidget(m_button_box);
setLayout(m_layout);
@ -55,6 +62,8 @@ void GCPadWiiUConfigDialog::CreateLayout()
void GCPadWiiUConfigDialog::ConnectWidgets()
{
connect(m_poll_rate_timer, &QTimer::timeout, this, &GCPadWiiUConfigDialog::UpdatePollRate);
m_poll_rate_timer->start(1500);
connect(m_rumble, &QCheckBox::toggled, this, &GCPadWiiUConfigDialog::SaveSettings);
connect(m_simulate_bongos, &QCheckBox::toggled, this, &GCPadWiiUConfigDialog::SaveSettings);
connect(m_button_box, &QDialogButtonBox::accepted, this, &GCPadWiiUConfigDialog::accept);
@ -83,6 +92,13 @@ void GCPadWiiUConfigDialog::UpdateAdapterStatus()
m_rumble->setEnabled(detected);
m_simulate_bongos->setEnabled(detected);
m_poll_rate_label->setHidden(!detected);
}
void GCPadWiiUConfigDialog::UpdatePollRate()
{
QString poll_rate_text = tr("Poll Rate: %1 hz").arg(1000.0 / GCAdapter::ReadRate());
m_poll_rate_label->setText(poll_rate_text);
}
void GCPadWiiUConfigDialog::LoadSettings()

View file

@ -9,6 +9,7 @@ class QCheckBox;
class QLabel;
class QDialogButtonBox;
class QVBoxLayout;
class QTimer;
class GCPadWiiUConfigDialog final : public QDialog
{
@ -26,11 +27,14 @@ private:
private:
void UpdateAdapterStatus();
void UpdatePollRate();
int m_port;
QVBoxLayout* m_layout;
QLabel* m_status_label;
QLabel* m_poll_rate_label;
QTimer* m_poll_rate_timer;
QDialogButtonBox* m_button_box;
// Checkboxes

View file

@ -161,6 +161,11 @@ static std::optional<size_t> s_config_callback_id = std::nullopt;
static bool s_is_adapter_wanted = false;
static std::array<bool, SerialInterface::MAX_SI_CHANNELS> s_config_rumble_enabled{};
// slippi change: for poll rate display
static u64 s_consecutive_slow_transfers = 0;
static double s_read_rate = 0.0;
// slippi change: for poll rate display
static void ReadThreadFunc()
{
Common::SetCurrentThreadName("GCAdapter Read Thread");
@ -197,15 +202,41 @@ static void ReadThreadFunc()
// Reset rumble once on initial reading
ResetRumble();
// slippi change: for poll rate display
s_read_rate = 0.0;
while (s_read_adapter_thread_running.IsSet())
{
#if GCADAPTER_USE_LIBUSB_IMPLEMENTATION
std::array<u8, CONTROLER_INPUT_PAYLOAD_EXPECTED_SIZE> input_buffer;
int payload_size = 0;
// slippi change: for poll rate display
std::chrono::high_resolution_clock::time_point start =
std::chrono::high_resolution_clock::now();
const int error =
libusb_interrupt_transfer(s_handle, s_endpoint_in, input_buffer.data(),
int(input_buffer.size()), &payload_size, USB_TIMEOUT_MS);
// slippi change: for poll rate display
std::chrono::high_resolution_clock::time_point now = std::chrono::high_resolution_clock::now();
double elapsed_ms =
std::chrono::duration_cast<std::chrono::nanoseconds>(now - start).count() / 1000000.0;
if (elapsed_ms > 15.0)
{
s_consecutive_slow_transfers++;
}
else
{
s_consecutive_slow_transfers = 0;
}
s_read_rate = elapsed_ms;
// slippi change: for poll rate display
if (error != LIBUSB_SUCCESS)
{
ERROR_LOG_FMT(CONTROLLERINTERFACE, "Read: libusb_interrupt_transfer failed: {}",
@ -469,6 +500,18 @@ void StopScanThread()
}
}
// slippi change: for poll rate display
bool IsReadingAtReducedRate()
{
return s_consecutive_slow_transfers > 80;
}
double ReadRate()
{
return s_read_rate;
}
// slippi change: for poll rate display
static void Setup()
{
#if GCADAPTER_USE_LIBUSB_IMPLEMENTATION

View file

@ -18,6 +18,11 @@ void SetAdapterCallback(std::function<void(void)> func);
void StartScanThread();
void StopScanThread();
// slippi change: for poll rate display
bool IsReadingAtReducedRate();
double ReadRate();
// slippi change: for poll rate display
// Buttons have PAD_GET_ORIGIN set on new connection
// Netplay and CSIDevice_GCAdapter make use of this.
GCPadStatus Input(int chan);

View file

@ -11,6 +11,8 @@
#include "Core/Config/NetplaySettings.h"
#include "Core/Movie.h"
#include "InputCommon/GCAdapter.h"
#include "VideoCommon/AbstractGfx.h"
#include "VideoCommon/AbstractPipeline.h"
#include "VideoCommon/AbstractShader.h"
@ -321,6 +323,23 @@ void OnScreenUI::DrawDebugText()
const std::string profile_output = Common::Profiler::ToString();
if (!profile_output.empty())
ImGui::TextUnformatted(profile_output.c_str());
// SLIPPITODO: make this cleaner
if (GCAdapter::IsReadingAtReducedRate())
{
ImGui::TextWrapped(
"Your GameCube Controller Adapter is reading inputs at a reduced rate.\n"
"You can still play normally but you will experience higher input lag.\n"
"This indicates a potential hardware issue.\n"
"\n"
"Go to the Dolphin -> Controllers page, click 'Configure' next to your "
"controller's port, then check what your pollrate is."
"\n"
"If it is considerably lower than 125 hz, keep trying different USB ports until it "
"is around 125 hz."
"\n"
"For more help, please ask in the official Slippi Discord server.");
}
}
void OnScreenUI::Finalize()