mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-11-22 09:22:18 -05:00
[579] Add simulated input lag option (#1438)
* [579] Add simulated input lag option * Continue to clear buffer when inputs are blocked * Changes from feedback
This commit is contained in:
parent
55e79cd9d2
commit
f712068a17
@ -80,6 +80,7 @@ namespace Ship {
|
|||||||
if (backend->GetGuid() == "Auto") {
|
if (backend->GetGuid() == "Auto") {
|
||||||
for (const auto& device : physicalDevices) {
|
for (const auto& device : physicalDevices) {
|
||||||
if(shouldBlockGameInput && device->GetGuid() != "Keyboard") {
|
if(shouldBlockGameInput && device->GetGuid() != "Keyboard") {
|
||||||
|
device->Read(nullptr, i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
device->Read(&pad[i], i);
|
device->Read(&pad[i], i);
|
||||||
@ -87,6 +88,7 @@ namespace Ship {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(shouldBlockGameInput && backend->GetGuid() != "Keyboard") {
|
if(shouldBlockGameInput && backend->GetGuid() != "Keyboard") {
|
||||||
|
backend->Read(nullptr, i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
backend->Read(&pad[i], i);
|
backend->Read(&pad[i], i);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "Controller.h"
|
#include "Controller.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include "Cvar.h"
|
||||||
#if __APPLE__
|
#if __APPLE__
|
||||||
#include <SDL_events.h>
|
#include <SDL_events.h>
|
||||||
#else
|
#else
|
||||||
@ -21,58 +22,67 @@ namespace Ship {
|
|||||||
void Controller::Read(OSContPad* pad, int32_t virtualSlot) {
|
void Controller::Read(OSContPad* pad, int32_t virtualSlot) {
|
||||||
ReadFromSource(virtualSlot);
|
ReadFromSource(virtualSlot);
|
||||||
|
|
||||||
|
OSContPad padToBuffer = { 0 };
|
||||||
|
|
||||||
#ifndef __WIIU__
|
#ifndef __WIIU__
|
||||||
SDL_PumpEvents();
|
SDL_PumpEvents();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Button Inputs
|
// Button Inputs
|
||||||
pad->button |= getPressedButtons(virtualSlot) & 0xFFFF;
|
padToBuffer.button |= getPressedButtons(virtualSlot) & 0xFFFF;
|
||||||
|
|
||||||
// Stick Inputs
|
// Stick Inputs
|
||||||
if (getLeftStickX(virtualSlot) == 0) {
|
if (getLeftStickX(virtualSlot) == 0) {
|
||||||
if (getPressedButtons(virtualSlot) & BTN_STICKLEFT) {
|
if (getPressedButtons(virtualSlot) & BTN_STICKLEFT) {
|
||||||
pad->stick_x = -128;
|
padToBuffer.stick_x = -128;
|
||||||
} else if (getPressedButtons(virtualSlot) & BTN_STICKRIGHT) {
|
} else if (getPressedButtons(virtualSlot) & BTN_STICKRIGHT) {
|
||||||
pad->stick_x = 127;
|
padToBuffer.stick_x = 127;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pad->stick_x = getLeftStickX(virtualSlot);
|
padToBuffer.stick_x = getLeftStickX(virtualSlot);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getLeftStickY(virtualSlot) == 0) {
|
if (getLeftStickY(virtualSlot) == 0) {
|
||||||
if (getPressedButtons(virtualSlot) & BTN_STICKDOWN) {
|
if (getPressedButtons(virtualSlot) & BTN_STICKDOWN) {
|
||||||
pad->stick_y = -128;
|
padToBuffer.stick_y = -128;
|
||||||
} else if (getPressedButtons(virtualSlot) & BTN_STICKUP) {
|
} else if (getPressedButtons(virtualSlot) & BTN_STICKUP) {
|
||||||
pad->stick_y = 127;
|
padToBuffer.stick_y = 127;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pad->stick_y = getLeftStickY(virtualSlot);
|
padToBuffer.stick_y = getLeftStickY(virtualSlot);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stick Inputs
|
// Stick Inputs
|
||||||
if (getRightStickX(virtualSlot) == 0) {
|
if (getRightStickX(virtualSlot) == 0) {
|
||||||
if (getPressedButtons(virtualSlot) & BTN_VSTICKLEFT) {
|
if (getPressedButtons(virtualSlot) & BTN_VSTICKLEFT) {
|
||||||
pad->right_stick_x = -128;
|
padToBuffer.right_stick_x = -128;
|
||||||
} else if (getPressedButtons(virtualSlot) & BTN_VSTICKRIGHT) {
|
} else if (getPressedButtons(virtualSlot) & BTN_VSTICKRIGHT) {
|
||||||
pad->right_stick_x = 127;
|
padToBuffer.right_stick_x = 127;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pad->right_stick_x = getRightStickX(virtualSlot);
|
padToBuffer.right_stick_x = getRightStickX(virtualSlot);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getRightStickY(virtualSlot) == 0) {
|
if (getRightStickY(virtualSlot) == 0) {
|
||||||
if (getPressedButtons(virtualSlot) & BTN_VSTICKDOWN) {
|
if (getPressedButtons(virtualSlot) & BTN_VSTICKDOWN) {
|
||||||
pad->right_stick_y = -128;
|
padToBuffer.right_stick_y = -128;
|
||||||
} else if (getPressedButtons(virtualSlot) & BTN_VSTICKUP) {
|
} else if (getPressedButtons(virtualSlot) & BTN_VSTICKUP) {
|
||||||
pad->right_stick_y = 127;
|
padToBuffer.right_stick_y = 127;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pad->right_stick_y = getRightStickY(virtualSlot);
|
padToBuffer.right_stick_y = getRightStickY(virtualSlot);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gyro
|
// Gyro
|
||||||
pad->gyro_x = getGyroX(virtualSlot);
|
padToBuffer.gyro_x = getGyroX(virtualSlot);
|
||||||
pad->gyro_y = getGyroY(virtualSlot);
|
padToBuffer.gyro_y = getGyroY(virtualSlot);
|
||||||
|
|
||||||
|
padBuffer.push_front(padToBuffer);
|
||||||
|
*pad = padBuffer[std::min(padBuffer.size(), (size_t)CVar_GetS32("gSimulatedInputLag", 0))];
|
||||||
|
|
||||||
|
while (padBuffer.size() > 6) {
|
||||||
|
padBuffer.pop_back();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::SetButtonMapping(int32_t virtualSlot, int32_t n64Button, int32_t dwScancode) {
|
void Controller::SetButtonMapping(int32_t virtualSlot, int32_t n64Button, int32_t dwScancode) {
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <queue>
|
||||||
#include "UltraController.h"
|
#include "UltraController.h"
|
||||||
#include "ControllerAttachment.h"
|
#include "ControllerAttachment.h"
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
@ -84,5 +85,6 @@ namespace Ship {
|
|||||||
|
|
||||||
std::unordered_map<int32_t, std::shared_ptr<DeviceProfile>> profiles;
|
std::unordered_map<int32_t, std::shared_ptr<DeviceProfile>> profiles;
|
||||||
std::unordered_map<int32_t, std::shared_ptr<Buttons>> ButtonData = {};
|
std::unordered_map<int32_t, std::shared_ptr<Buttons>> ButtonData = {};
|
||||||
|
std::deque<OSContPad> padBuffer;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -504,6 +504,11 @@ namespace GameMenuBar {
|
|||||||
UIWidgets::EnhancementSliderFloat("Input Scale: %.1f", "##Input", "gInputScale", 1.0f, 3.0f, "", 1.0f, false);
|
UIWidgets::EnhancementSliderFloat("Input Scale: %.1f", "##Input", "gInputScale", 1.0f, 3.0f, "", 1.0f, false);
|
||||||
UIWidgets::Tooltip("Sets the on screen size of the displayed inputs from the Show Inputs setting");
|
UIWidgets::Tooltip("Sets the on screen size of the displayed inputs from the Show Inputs setting");
|
||||||
ImGui::PopItemWidth();
|
ImGui::PopItemWidth();
|
||||||
|
UIWidgets::Spacer(0);
|
||||||
|
ImGui::PushItemWidth(ImGui::GetWindowSize().x - 20.0f);
|
||||||
|
UIWidgets::EnhancementSliderInt("Simulated Input Lag: %d frames", "##SimulatedInputLag", "gSimulatedInputLag", 0, 6, "", 0, false);
|
||||||
|
UIWidgets::Tooltip("Buffers your inputs to be executed a specified amount of frames later");
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
|
@ -483,10 +483,7 @@ static void RunFrame()
|
|||||||
|
|
||||||
Graph_StartFrame();
|
Graph_StartFrame();
|
||||||
|
|
||||||
// TODO: Workaround for rumble being too long. Implement os thread functions.
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
PadMgr_ThreadEntry(&gPadMgr);
|
PadMgr_ThreadEntry(&gPadMgr);
|
||||||
}
|
|
||||||
|
|
||||||
Graph_Update(&runFrameContext.gfxCtx, runFrameContext.gameState);
|
Graph_Update(&runFrameContext.gfxCtx, runFrameContext.gameState);
|
||||||
ticksB = GetPerfCounter();
|
ticksB = GetPerfCounter();
|
||||||
|
@ -331,6 +331,9 @@ void PadMgr_HandleRetraceMsg(PadMgr* padMgr) {
|
|||||||
}
|
}
|
||||||
padMgr->validCtrlrsMask = mask;
|
padMgr->validCtrlrsMask = mask;
|
||||||
|
|
||||||
|
// TODO: Workaround for rumble being too long. Implement os thread functions.
|
||||||
|
// Game logic runs at 20hz but input thread runs at 60 hertz, so we call this 3 times
|
||||||
|
for (i = 0; i < 3; i++) {
|
||||||
/* if (gFaultStruct.msgId) {
|
/* if (gFaultStruct.msgId) {
|
||||||
PadMgr_RumbleStop(padMgr);
|
PadMgr_RumbleStop(padMgr);
|
||||||
} else */ if (padMgr->rumbleOffFrames > 0) {
|
} else */ if (padMgr->rumbleOffFrames > 0) {
|
||||||
@ -342,6 +345,7 @@ void PadMgr_HandleRetraceMsg(PadMgr* padMgr) {
|
|||||||
PadMgr_RumbleControl(padMgr);
|
PadMgr_RumbleControl(padMgr);
|
||||||
--padMgr->rumbleOnFrames;
|
--padMgr->rumbleOnFrames;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PadMgr_HandlePreNMI(PadMgr* padMgr) {
|
void PadMgr_HandlePreNMI(PadMgr* padMgr) {
|
||||||
|
Loading…
Reference in New Issue
Block a user