mirror of
https://github.com/neoStudiosLCE/neoLegacy.git
synced 2026-05-21 22:55:04 +00:00
fix: controller cursor speed no longer scales with framerate
When framerate was uncapped (vsync off, high-end hardware), the controller cursor in the inventory and creative menus moved way too fast. Basically unusable unless you switched to the dpad. The cursor update was tied to how often the screen redraws, so the faster the game ran, the faster the cursor flew. Now the cursor moves a smaller distance per frame at higher framerates, so the actual on-screen speed stays the same whether you're at 60 FPS or 600 FPS. While fixing this I also found an old workaround that was rounding the cursor position to whole pixels every frame and nudging it by 1 pixel to keep it from getting stuck. That nudge was pointing the wrong way on the vertical axis, which made up/down movement feel broken once the per-frame distance got small. Removed the rounding and the nudge. The cursor can now hold a fractional position between frames, and the part of the code that actually draws the cursor still snaps it to whole pixels on screen. Fixes #3
This commit is contained in:
@@ -29,6 +29,7 @@ IUIScene_AbstractContainerMenu::IUIScene_AbstractContainerMenu()
|
||||
m_pointerPos.y = 0.0f;
|
||||
m_bPointerDrivenByMouse = false;
|
||||
|
||||
m_iLastMouseTickTimeNs = -1;
|
||||
}
|
||||
|
||||
IUIScene_AbstractContainerMenu::~IUIScene_AbstractContainerMenu()
|
||||
@@ -266,6 +267,21 @@ void IUIScene_AbstractContainerMenu::UpdateTooltips()
|
||||
|
||||
void IUIScene_AbstractContainerMenu::onMouseTick()
|
||||
{
|
||||
// Frame-rate independent cursor input, normalized to a 60Hz reference frame.
|
||||
const int64_t kRefFrameNs = 1000000000LL / 60;
|
||||
const int64_t kMinDeltaNs = 1000000LL;
|
||||
const int64_t kMaxDeltaNs = 100000000LL;
|
||||
int64_t iNowNs = System::nanoTime();
|
||||
float fFrameScale = 1.0f;
|
||||
if ( m_iLastMouseTickTimeNs > 0 )
|
||||
{
|
||||
int64_t iDeltaNs = iNowNs - m_iLastMouseTickTimeNs;
|
||||
if ( iDeltaNs < kMinDeltaNs ) iDeltaNs = kMinDeltaNs;
|
||||
if ( iDeltaNs > kMaxDeltaNs ) iDeltaNs = kMaxDeltaNs;
|
||||
fFrameScale = static_cast<float>(iDeltaNs) / static_cast<float>(kRefFrameNs);
|
||||
}
|
||||
m_iLastMouseTickTimeNs = iNowNs;
|
||||
|
||||
Minecraft *pMinecraft = Minecraft::GetInstance();
|
||||
if( pMinecraft->localgameModes[getPad()] != nullptr)
|
||||
{
|
||||
@@ -422,10 +438,10 @@ void IUIScene_AbstractContainerMenu::onMouseTick()
|
||||
// The SD/splitscreen scenes are approximately 0.6 times the size of the fullscreen on
|
||||
if(!RenderManager.IsHiDef() || app.GetLocalPlayerCount() > 1) fInputScale *= 0.6f;
|
||||
|
||||
fInputX *= fInputScale;
|
||||
fInputY *= fInputScale;
|
||||
fInputX *= fInputScale * fFrameScale;
|
||||
fInputY *= fInputScale * fFrameScale;
|
||||
|
||||
#ifdef USE_POINTER_ACCEL
|
||||
#ifdef USE_POINTER_ACCEL
|
||||
m_fPointerAccelX += fInputX / 50.0f;
|
||||
m_fPointerAccelY += fInputY / 50.0f;
|
||||
|
||||
@@ -1269,36 +1285,8 @@ void IUIScene_AbstractContainerMenu::onMouseTick()
|
||||
vPointerPos.x -= m_fPointerImageOffsetX;
|
||||
vPointerPos.y -= m_fPointerImageOffsetY;
|
||||
|
||||
// Update pointer position.
|
||||
// 4J-PB - do not allow sub pixel positions or we get broken lines in box edges
|
||||
|
||||
// problem here when sensitivity is low - we'll be moving a sub pixel size, so it'll clamp, and we'll never move. In that case, move 1 pixel
|
||||
if(fInputDirX!=0.0f)
|
||||
{
|
||||
if(fInputDirX==1.0f)
|
||||
{
|
||||
vPointerPos.x+=0.999999f;
|
||||
}
|
||||
else
|
||||
{
|
||||
vPointerPos.x-=0.999999f;
|
||||
}
|
||||
}
|
||||
|
||||
if(fInputDirY!=0.0f)
|
||||
{
|
||||
if(fInputDirY==1.0f)
|
||||
{
|
||||
vPointerPos.y+=0.999999f;
|
||||
}
|
||||
else
|
||||
{
|
||||
vPointerPos.y-=0.999999f;
|
||||
}
|
||||
}
|
||||
|
||||
vPointerPos.x = static_cast<float>(floor(vPointerPos.x + 0.5f));
|
||||
vPointerPos.y = static_cast<float>(floor(vPointerPos.y + 0.5f));
|
||||
// Keep sub-pixel float state so deltas <1px accumulate across frames; the renderer
|
||||
// truncates to integer pixels when emitting the Iggy mouse event.
|
||||
m_pointerPos = vPointerPos;
|
||||
|
||||
adjustPointerForSafeZone();
|
||||
|
||||
@@ -145,6 +145,8 @@ protected:
|
||||
|
||||
int m_iConsectiveInputTicks;
|
||||
|
||||
int64_t m_iLastMouseTickTimeNs;
|
||||
|
||||
// Used for detecting quick "taps" in a direction, should jump cursor to next slot.
|
||||
enum ETapState
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user