Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mouse refactor, restore smoothing #18551

Merged
merged 6 commits into from
Dec 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions Common/GPU/Vulkan/thin3d_vulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,26 @@ class VKContext : public DrawContext {
}
return list;
}
std::vector<std::string> GetPresentModeList(const char *currentMarkerString) const override {
std::vector<std::string> list;
for (auto mode : vulkan_->GetAvailablePresentModes()) {
std::string str = VulkanPresentModeToString(mode);
if (mode == vulkan_->GetPresentMode()) {
str += std::string(" (") + currentMarkerString + ")";
}
list.push_back(str);
}
return list;
}
std::vector<std::string> GetSurfaceFormatList() const override {
std::vector<std::string> list;
for (auto &format : vulkan_->SurfaceFormats()) {
std::string str = StringFromFormat("%s : %s", VulkanFormatToString(format.format), VulkanColorSpaceToString(format.colorSpace));
list.push_back(str);
}
return list;
}

uint32_t GetSupportedShaderLanguages() const override {
return (uint32_t)ShaderLanguage::GLSL_VULKAN;
}
Expand Down
2 changes: 2 additions & 0 deletions Common/GPU/thin3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -698,6 +698,8 @@ class DrawContext {
virtual std::vector<std::string> GetFeatureList() const { return std::vector<std::string>(); }
virtual std::vector<std::string> GetExtensionList(bool device, bool enabledOnly) const { return std::vector<std::string>(); }
virtual std::vector<std::string> GetDeviceList() const { return std::vector<std::string>(); }
virtual std::vector<std::string> GetPresentModeList(const char *currentMarkerString) const { return std::vector<std::string>(); }
virtual std::vector<std::string> GetSurfaceFormatList() const { return std::vector<std::string>(); }

// Describes the primary shader language that this implementation prefers.
const ShaderLanguageDesc &GetShaderLanguageDesc() {
Expand Down
2 changes: 0 additions & 2 deletions Common/Render/ManagedTexture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,6 @@ Draw::Texture *CreateTextureFromFileData(Draw::DrawContext *draw, const uint8_t
}

Draw::Texture *CreateTextureFromFile(Draw::DrawContext *draw, const char *filename, ImageFileType type, bool generateMips) {
INFO_LOG(SYSTEM, "CreateTextureFromFile(%s)", filename);
size_t fileSize;
uint8_t *buffer = g_VFS.ReadFile(filename, &fileSize);
if (!buffer) {
Expand Down Expand Up @@ -203,7 +202,6 @@ Draw::Texture *ManagedTexture::GetTexture() {
ManagedTexture::ManagedTexture(Draw::DrawContext *draw, std::string_view filename, ImageFileType type, bool generateMips)
: draw_(draw), filename_(filename), type_(type), generateMips_(generateMips)
{
INFO_LOG(SYSTEM, "ManagedTexture::ManagedTexture (%s)", filename_.c_str());
StartLoadTask();
}

Expand Down
2 changes: 2 additions & 0 deletions Common/UI/Context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "Common/Render/Text/draw_text.h"
#include "Common/Render/ManagedTexture.h"
#include "Common/Log.h"
#include "Common/TimeUtil.h"
#include "Common/LogReporting.h"

UIContext::UIContext() {
Expand Down Expand Up @@ -44,6 +45,7 @@ void UIContext::setUIAtlas(const std::string &name) {
}

void UIContext::BeginFrame() {
frameStartTime_ = time_now_d();
if (!uitexture_ || UIAtlas_ != lastUIAtlas_) {
uitexture_ = CreateTextureFromFile(draw_, UIAtlas_.c_str(), ImageFileType::ZIM, false);
lastUIAtlas_ = UIAtlas_;
Expand Down
4 changes: 4 additions & 0 deletions Common/UI/Context.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ class UIContext {
void RebindTexture() const;
void BindFontTexture() const;

double FrameStartTime() const { return frameStartTime_; }

// TODO: Support transformed bounds using stencil
void PushScissor(const Bounds &bounds);
void PopScissor();
Expand Down Expand Up @@ -119,6 +121,8 @@ class UIContext {
Draw::DrawContext *draw_ = nullptr;
Bounds bounds_;

double frameStartTime_ = 0.0;

float fontScaleX_ = 1.0f;
float fontScaleY_ = 1.0f;
UI::FontStyle *fontStyle_ = nullptr;
Expand Down
97 changes: 86 additions & 11 deletions Core/TiltEventProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

#include <algorithm>
#include <cmath>
#include <mutex>

#include "Common/Math/math_util.h"
#include "Common/Math/lin/vec3.h"
#include "Common/Math/lin/matrix4x4.h"
#include "Common/Log.h"
#include "Common/System/Display.h"

#include "Core/Config.h"
#include "Core/ConfigValues.h"
Expand All @@ -32,6 +34,8 @@ void GenerateDPadEvent(int digitalX, int digitalY);
void GenerateActionButtonEvent(int digitalX, int digitalY);
void GenerateTriggerButtonEvent(int digitalX, int digitalY);

}

// deadzone is normalized - 0 to 1
// sensitivity controls how fast the deadzone reaches max value
inline float ApplyDeadzoneAxis(float x, float deadzone) {
Expand All @@ -49,32 +53,35 @@ inline float ApplyDeadzoneAxis(float x, float deadzone) {
}
}

inline void ApplyDeadzoneXY(float tiltX, float tiltY, float *adjustedTiltX, float *adjustedTiltY, float deadzone, bool circular) {

inline void ApplyDeadzoneXY(float x, float y, float *adjustedX, float *adjustedY, float deadzone, bool circular) {
if (circular) {
if (tiltX == 0.0f && tiltY == 0.0f) {
*adjustedTiltX = 0.0f;
*adjustedTiltY = 0.0f;
if (x == 0.0f && y == 0.0f) {
*adjustedX = 0.0f;
*adjustedY = 0.0f;
return;
}

float magnitude = sqrtf(tiltX * tiltX + tiltY * tiltY);
float magnitude = sqrtf(x * x + y * y);
if (magnitude <= deadzone + 0.00001f) {
*adjustedTiltX = 0.0f;
*adjustedTiltY = 0.0f;
*adjustedX = 0.0f;
*adjustedY = 0.0f;
return;
}

float factor = 1.0f / (1.0f - deadzone);
float newMagnitude = (magnitude - deadzone) * factor;

*adjustedTiltX = (tiltX / magnitude) * newMagnitude;
*adjustedTiltY = (tiltY / magnitude) * newMagnitude;
*adjustedX = (x / magnitude) * newMagnitude;
*adjustedY = (y / magnitude) * newMagnitude;
} else {
*adjustedTiltX = ApplyDeadzoneAxis(tiltX, deadzone);
*adjustedTiltY = ApplyDeadzoneAxis(tiltY, deadzone);
*adjustedX = ApplyDeadzoneAxis(x, deadzone);
*adjustedY = ApplyDeadzoneAxis(y, deadzone);
}
}

namespace TiltEventProcessor {

// Also clamps to -1.0..1.0.
// This applies a (circular if desired) inverse deadzone.
inline void ApplyInverseDeadzone(float x, float y, float *outX, float *outY, float inverseDeadzone, bool circular) {
Expand Down Expand Up @@ -301,3 +308,71 @@ void ResetTiltEvents() {
}

} // namespace TiltEventProcessor

namespace MouseEventProcessor {

// Technically, we may be OK without a mutex here.
// But, the cost isn't high.
std::mutex g_mouseMutex;

float g_mouseDeltaXAccum = 0;
float g_mouseDeltaYAccum = 0;

float g_mouseDeltaX;
float g_mouseDeltaY;

void DecayMouse(double now) {
g_mouseDeltaX = g_mouseDeltaXAccum;
g_mouseDeltaY = g_mouseDeltaYAccum;

const float decay = g_Config.fMouseSmoothing;

static double lastTime = 0.0f;
if (lastTime == 0.0) {
lastTime = now;
return;
}
double dt = now - lastTime;
lastTime = now;

// Decay the mouse deltas. We do an approximation of the old polling.
// Should be able to use a smooth exponential here, when I get around to doing
// the math.
static double accumDt = 0.0;
accumDt += dt;
const double oldPollInterval = 1.0 / 250.0; // See Windows "PollControllers".
while (accumDt > oldPollInterval) {
accumDt -= oldPollInterval;
g_mouseDeltaXAccum *= decay;
g_mouseDeltaYAccum *= decay;
}
}

void ProcessDelta(double now, float dx, float dy) {
std::unique_lock<std::mutex> lock(g_mouseMutex);

// Accumulate mouse deltas, for some kind of smoothing.
g_mouseDeltaXAccum += dx;
g_mouseDeltaYAccum += dy;

DecayMouse(now);
}

void MouseDeltaToAxes(double now, float *mx, float *my) {
std::unique_lock<std::mutex> lock(g_mouseMutex);

float scaleFactor_x = g_display.dpi_scale_x * 0.1 * g_Config.fMouseSensitivity;
float scaleFactor_y = g_display.dpi_scale_y * 0.1 * g_Config.fMouseSensitivity;

DecayMouse(now);

// TODO: Make configurable.
float mouseDeadZone = 0.1f;

float outX = clamp_value(g_mouseDeltaX * scaleFactor_x, -1.0f, 1.0f);
float outY = clamp_value(g_mouseDeltaY * scaleFactor_y, -1.0f, 1.0f);

ApplyDeadzoneXY(outX, outY, mx, my, mouseDeadZone, true);
}

} // namespace
7 changes: 7 additions & 0 deletions Core/TiltEventProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,10 @@ extern float rawTiltAnalogX;
extern float rawTiltAnalogY;

} // namespace

namespace MouseEventProcessor {

void ProcessDelta(double now, float dx, float dy);
void MouseDeltaToAxes(double now, float *mx, float *my);

} // namespace
Loading