Skip to content

Commit

Permalink
feat: add poll rate display in GC Adapter config (#7)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
NikhilNarayana authored Oct 13, 2023
1 parent 6c7a93d commit 9eca21b
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 1 deletion.
18 changes: 17 additions & 1 deletion Source/Core/DolphinQt/Config/Mapping/GCPadWiiUConfigDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <QCheckBox>
#include <QDialogButtonBox>
#include <QLabel>
#include <QTimer>
#include <QVBoxLayout>

#include "Core/Config/MainSettings.h"
Expand Down Expand Up @@ -36,25 +37,33 @@ 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);
}

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);
Expand Down Expand Up @@ -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()
Expand Down
4 changes: 4 additions & 0 deletions Source/Core/DolphinQt/Config/Mapping/GCPadWiiUConfigDialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class QCheckBox;
class QLabel;
class QDialogButtonBox;
class QVBoxLayout;
class QTimer;

class GCPadWiiUConfigDialog final : public QDialog
{
Expand All @@ -26,11 +27,14 @@ class GCPadWiiUConfigDialog final : public QDialog

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
Expand Down
43 changes: 43 additions & 0 deletions Source/Core/InputCommon/GCAdapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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: {}",
Expand Down Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions Source/Core/InputCommon/GCAdapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
19 changes: 19 additions & 0 deletions Source/Core/VideoCommon/OnScreenUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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()
Expand Down

0 comments on commit 9eca21b

Please sign in to comment.