diff --git a/Common/Input/InputState.cpp b/Common/Input/InputState.cpp index 67c2b6415a..143f95e5fd 100644 --- a/Common/Input/InputState.cpp +++ b/Common/Input/InputState.cpp @@ -76,3 +76,13 @@ int GetAnalogYDirection(int deviceId) { return configured->second; return 0; } + +void InputMapping::FormatDebug(char *buffer, size_t bufSize) const { + if (IsAxis()) { + int direction; + int axis = Axis(&direction); + snprintf(buffer, bufSize, "Device: %d Axis: %d (%d)", deviceId, axis, direction); + } else { + snprintf(buffer, bufSize, "Device: %d Key: %d", deviceId, keyCode); + } +} diff --git a/Common/Input/InputState.h b/Common/Input/InputState.h index 1801191097..b1e30acefa 100644 --- a/Common/Input/InputState.h +++ b/Common/Input/InputState.h @@ -136,6 +136,8 @@ public: if (keyCode != other.keyCode) return false; return true; } + + void FormatDebug(char *buffer, size_t bufSize) const; }; enum { diff --git a/Core/Config.h b/Core/Config.h index 18d991a48a..17c5197a97 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -276,9 +276,11 @@ public: std::string sThemeName; + // These aren't saved, just for instant debugging. bool bLogFrameDrops; bool bShowDebugStats; bool bShowAudioDebug; + bool bShowControlDebug; bool bShowGpuProfile; // Analog stick tilting diff --git a/Core/ControlMapper.cpp b/Core/ControlMapper.cpp index ee512bc988..5877a2ba63 100644 --- a/Core/ControlMapper.cpp +++ b/Core/ControlMapper.cpp @@ -1,7 +1,9 @@ #include +#include #include "Common/Math/math_util.h" #include "Common/TimeUtil.h" +#include "Common/StringUtils.h" #include "Common/Log.h" #include "Core/HLE/sceCtrl.h" @@ -31,6 +33,11 @@ static int GetOppositeVKey(int vkey) { } } +static bool IsAxisVKey(int vkey) { + // Little hacky but works, of course. + return GetOppositeVKey(vkey) != 0; +} + static bool IsUnsignedMapping(int vkey) { return vkey == VIRTKEY_SPEED_ANALOG; } @@ -131,6 +138,8 @@ void ControlMapper::SetPSPAxis(int device, int stick, char axis, float value) { history_[stick][axisId] = value; float x, y; ConvertAnalogStick(history_[stick][0], history_[stick][1], &x, &y); + converted_[stick][0] = x; + converted_[stick][1] = y; setPSPAnalog_(stick, x, y); } } @@ -207,7 +216,6 @@ bool ControlMapper::UpdatePSPState(const InputMapping &changedMapping) { // mapping which gets a little hacky. float threshold = 1.0f; bool touchedByMapping = false; - bool zeroOpposite = false; float value = 0.0f; for (auto &mapping : inputMappings) { if (mapping == changedMapping) { @@ -242,7 +250,6 @@ bool ControlMapper::UpdatePSPState(const InputMapping &changedMapping) { value += iter->second; } } else { - zeroOpposite = true; value += iter->second; } } else { @@ -268,14 +275,6 @@ bool ControlMapper::UpdatePSPState(const InputMapping &changedMapping) { virtKeys_[i] = value; } - if (zeroOpposite) { - // For analog stick events, always zero the "opposite" when we get a valid value. - // Otherwise, lingering small values can create strange offsets when summing up later. - int opposite = GetOppositeVKey(vkId); - if (opposite) { - virtKeys_[i] = 0.0f; - } - } if (!bPrevValue && bValue) { // INFO_LOG(G3D, "vkeyon %s", KeyMap::GetVirtKeyName(vkId)); onVKey(vkId, true); @@ -319,22 +318,20 @@ bool ControlMapper::Key(const KeyInput &key, bool *pauseTrigger) { void ControlMapper::Axis(const AxisInput &axis) { std::lock_guard guard(mutex_); - if (axis.value > 0) { + if (axis.value >= 0.0f) { InputMapping mapping(axis.deviceId, axis.axisId, 1); + InputMapping opposite(axis.deviceId, axis.axisId, -1); curInput_[mapping] = axis.value; + curInput_[opposite] = 0.0f; UpdatePSPState(mapping); - } else if (axis.value < 0) { + UpdatePSPState(opposite); + } else if (axis.value < 0.0f) { InputMapping mapping(axis.deviceId, axis.axisId, -1); + InputMapping opposite(axis.deviceId, axis.axisId, 1); curInput_[mapping] = -axis.value; + curInput_[opposite] = 0.0f; UpdatePSPState(mapping); - } else if (axis.value == 0.0f) { // Threshold? - // Both directions! Prevents sticking for digital input devices that are axises (like HAT) - InputMapping mappingPositive(axis.deviceId, axis.axisId, 1); - InputMapping mappingNegative(axis.deviceId, axis.axisId, -1); - curInput_[mappingPositive] = 0.0f; - curInput_[mappingNegative] = 0.0f; - UpdatePSPState(mappingPositive); - UpdatePSPState(mappingNegative); + UpdatePSPState(opposite); } } @@ -381,7 +378,7 @@ void ControlMapper::onVKeyAnalog(int deviceId, int vkey, float value) { // with the opposite value too. int stick = 0; int axis = 'X'; - int opposite = GetOppositeVKey(vkey); + int oppositeVKey = GetOppositeVKey(vkey); float sign = 1.0f; switch (vkey) { case VIRTKEY_AXIS_X_MIN: sign = -1.0f; break; @@ -397,8 +394,12 @@ void ControlMapper::onVKeyAnalog(int deviceId, int vkey, float value) { onVKeyAnalog_(vkey, value); return; } - if (opposite != 0) { - value -= virtKeys_[opposite - VIRTKEY_FIRST]; + if (oppositeVKey != 0) { + float oppVal = virtKeys_[oppositeVKey - VIRTKEY_FIRST]; + if (oppVal != 0.0f) { + value -= oppVal; + // NOTICE_LOG(SCECTRL, "Reducing %f by %f (from %08x : %s)", value, oppVal, oppositeVKey, KeyMap::GetPspButtonName(oppositeVKey).c_str()); + } } SetPSPAxis(deviceId, stick, axis, sign * value); } @@ -429,3 +430,20 @@ void ControlMapper::onVKey(int vkey, bool down) { break; } } + +void ControlMapper::GetDebugString(char *buffer, size_t bufSize) const { + std::stringstream str; + for (auto iter : curInput_) { + char temp[256]; + iter.first.FormatDebug(temp, sizeof(temp)); + str << temp << ": " << iter.second << std::endl; + } + for (int i = 0; i < ARRAY_SIZE(virtKeys_); i++) { + int vkId = VIRTKEY_FIRST + i; + if ((vkId >= VIRTKEY_AXIS_X_MIN && vkId <= VIRTKEY_AXIS_Y_MAX) || vkId == VIRTKEY_ANALOG_LIGHTLY) { + str << KeyMap::GetPspButtonName(vkId) << ": " << virtKeys_[i] << std::endl; + } + } + str << "Lstick: " << converted_[0][0] << ", " << converted_[0][1] << std::endl; + truncate_cpy(buffer, bufSize, str.str().c_str()); +} diff --git a/Core/ControlMapper.h b/Core/ControlMapper.h index 878e2eade9..f0fae812c9 100644 --- a/Core/ControlMapper.h +++ b/Core/ControlMapper.h @@ -33,6 +33,8 @@ public: // virtual key codes, though not analog mappings. void PSPKey(int deviceId, int pspKeyCode, int flags); + void GetDebugString(char *buffer, size_t bufSize) const; + private: bool UpdatePSPState(const InputMapping &changedMapping); @@ -47,6 +49,7 @@ private: int lastNonDeadzoneDeviceID_[2]{}; float history_[2][2]{}; + float converted_[2][2]{}; // for debug display // Mappable auto-rotation. Useful for keyboard/dpad->analog in a few games. bool autoRotatingAnalogCW_ = false; diff --git a/Core/KeyMap.cpp b/Core/KeyMap.cpp index a7742296bc..52f907ed8e 100644 --- a/Core/KeyMap.cpp +++ b/Core/KeyMap.cpp @@ -424,9 +424,10 @@ const KeyMap_IntStrPair psp_button_names[] = { }; static std::string FindName(int key, const KeyMap_IntStrPair list[], size_t size) { - for (size_t i = 0; i < size; i++) + for (size_t i = 0; i < size; i++) { if (list[i].key == key) return list[i].name; + } return StringFromFormat("%02x?", key); } diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index 170cb99414..16c562187c 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -107,7 +107,14 @@ void DevMenuScreen::CreatePopupContents(UI::ViewGroup *parent) { items->Add(new Choice(dev->T("Toggle Freeze")))->OnClick.Handle(this, &DevMenuScreen::OnFreezeFrame); items->Add(new Choice(dev->T("Dump next frame to log")))->OnClick.Handle(this, &DevMenuScreen::OnDumpFrame); - items->Add(new Choice(dev->T("Toggle Audio Debug")))->OnClick.Handle(this, &DevMenuScreen::OnToggleAudioDebug); + items->Add(new Choice(dev->T("Toggle Audio Debug")))->OnClick.Add([](UI::EventParams &) { + g_Config.bShowAudioDebug = !g_Config.bShowAudioDebug; + return UI::EVENT_DONE; + }); + items->Add(new Choice(dev->T("Toggle Control Debug")))->OnClick.Add([](UI::EventParams &) { + g_Config.bShowControlDebug = !g_Config.bShowControlDebug; + return UI::EVENT_DONE; + }); #ifdef USE_PROFILER items->Add(new CheckBox(&g_Config.bShowFrameProfiler, dev->T("Frame Profiler"), "")); #endif @@ -123,11 +130,6 @@ void DevMenuScreen::CreatePopupContents(UI::ViewGroup *parent) { } } -UI::EventReturn DevMenuScreen::OnToggleAudioDebug(UI::EventParams &e) { - g_Config.bShowAudioDebug = !g_Config.bShowAudioDebug; - return UI::EVENT_DONE; -} - UI::EventReturn DevMenuScreen::OnResetLimitedLogging(UI::EventParams &e) { Reporting::ResetCounts(); return UI::EVENT_DONE; diff --git a/UI/DevScreens.h b/UI/DevScreens.h index 0a871b56fc..a582d7951a 100644 --- a/UI/DevScreens.h +++ b/UI/DevScreens.h @@ -45,7 +45,6 @@ protected: UI::EventReturn OnFreezeFrame(UI::EventParams &e); UI::EventReturn OnDumpFrame(UI::EventParams &e); UI::EventReturn OnDeveloperTools(UI::EventParams &e); - UI::EventReturn OnToggleAudioDebug(UI::EventParams &e); UI::EventReturn OnResetLimitedLogging(UI::EventParams &e); private: diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index d7c1102c04..8707215c47 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -1337,6 +1337,23 @@ static void DrawAudioDebugStats(UIContext *ctx, const Bounds &bounds) { ctx->RebindTexture(); } +static void DrawControlDebug(UIContext *ctx, const ControlMapper &mapper, const Bounds &bounds) { + FontID ubuntu24("UBUNTU24"); + + char statbuf[4096] = { 0 }; + mapper.GetDebugString(statbuf, sizeof(statbuf)); + // System_AudioGetDebugStats(statbuf, sizeof(statbuf)); + + ctx->Flush(); + ctx->BindFontTexture(); + ctx->Draw()->SetFontScale(0.5f, 0.5f); + ctx->Draw()->DrawTextRect(ubuntu24, statbuf, bounds.x + 11, bounds.y + 31, bounds.w - 20, bounds.h - 30, 0xc0000000, FLAG_DYNAMIC_ASCII); + ctx->Draw()->DrawTextRect(ubuntu24, statbuf, bounds.x + 10, bounds.y + 30, bounds.w - 20, bounds.h - 30, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII); + ctx->Draw()->SetFontScale(1.0f, 1.0f); + ctx->Flush(); + ctx->RebindTexture(); +} + static void DrawFPS(UIContext *ctx, const Bounds &bounds) { FontID ubuntu24("UBUNTU24"); float vps, fps, actual_fps; @@ -1549,7 +1566,7 @@ bool EmuScreen::hasVisibleUI() { if (g_Config.bEnableCardboardVR || g_Config.bEnableNetworkChat) return true; // Debug UI. - if (g_Config.bShowDebugStats || g_Config.bShowDeveloperMenu || g_Config.bShowAudioDebug || g_Config.bShowFrameProfiler) + if (g_Config.bShowDebugStats || g_Config.bShowDeveloperMenu || g_Config.bShowAudioDebug || g_Config.bShowFrameProfiler || g_Config.bShowControlDebug) return true; // Exception information. @@ -1583,20 +1600,26 @@ void EmuScreen::renderUI() { root_->Draw(*ctx); } - if (g_Config.bShowDebugStats && !invalid_) { - DrawDebugStats(ctx, ctx->GetLayoutBounds()); - } + if (!invalid_) { + if (g_Config.bShowDebugStats) { + DrawDebugStats(ctx, ctx->GetLayoutBounds()); + } - if (g_Config.bShowAudioDebug && !invalid_) { - DrawAudioDebugStats(ctx, ctx->GetLayoutBounds()); - } + if (g_Config.bShowAudioDebug) { + DrawAudioDebugStats(ctx, ctx->GetLayoutBounds()); + } - if (g_Config.iShowStatusFlags && !invalid_) { - DrawFPS(ctx, ctx->GetLayoutBounds()); - } + if (g_Config.iShowStatusFlags) { + DrawFPS(ctx, ctx->GetLayoutBounds()); + } - if (g_Config.bDrawFrameGraph && !invalid_) { - DrawFrameTimes(ctx, ctx->GetLayoutBounds()); + if (g_Config.bDrawFrameGraph) { + DrawFrameTimes(ctx, ctx->GetLayoutBounds()); + } + + if (g_Config.bShowControlDebug) { + DrawControlDebug(ctx, controlMapper_, ctx->GetLayoutBounds()); + } } #if !PPSSPP_PLATFORM(UWP) && !PPSSPP_PLATFORM(SWITCH)