mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-09-14 16:47:15 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e0abded5a3 | ||
|
|
7392b3b965 | ||
|
|
c22fccbbc9 | ||
|
|
a05bb033ec | ||
|
|
1cd4392170 | ||
|
|
9b37fc68a1 | ||
|
|
a7ed3190e0 | ||
|
|
489778cf6d | ||
|
|
112cc226b7 |
@@ -13376,13 +13376,6 @@ which produces much nicer sound during fast-forward/slowdown.</source>
|
||||
<source>Spin GPU During Readbacks is enabled, but calibrated timestamps are unavailable. This might be really slow.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../pcsx2/GS/Renderers/DX11/D3D.cpp" line="389"/>
|
||||
<source>The Vulkan graphics API was automatically selected, but no compatible devices were found.
|
||||
You should update all graphics drivers in your system, including any integrated GPUs
|
||||
to use the Vulkan renderer.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../pcsx2/MTGS.cpp" line="1002"/>
|
||||
<source>Switching to Software Renderer...</source>
|
||||
|
||||
+16
-11
@@ -523,6 +523,21 @@ void GSEndCapture()
|
||||
g_gs_renderer->EndCapture();
|
||||
}
|
||||
|
||||
void GSToggleVideoCapture()
|
||||
{
|
||||
if (!g_gs_renderer)
|
||||
return;
|
||||
|
||||
if (GSCapture::IsCapturing())
|
||||
{
|
||||
g_gs_renderer->EndCapture();
|
||||
return;
|
||||
}
|
||||
|
||||
std::string filename(fmt::format("{}.{}", GSGetBaseVideoFilename(), GSConfig.CaptureContainer));
|
||||
g_gs_renderer->BeginCapture(std::move(filename));
|
||||
}
|
||||
|
||||
void GSPresentCurrentFrame()
|
||||
{
|
||||
g_gs_renderer->PresentCurrentFrame();
|
||||
@@ -1217,17 +1232,7 @@ BEGIN_HOTKEY_LIST(g_gs_hotkeys){"Screenshot", TRANSLATE_NOOP("Hotkeys", "Graphic
|
||||
[](s32 pressed) {
|
||||
if (!pressed)
|
||||
{
|
||||
if (GSCapture::IsCapturing())
|
||||
{
|
||||
MTGS::RunOnGSThread([]() { g_gs_renderer->EndCapture(); });
|
||||
MTGS::WaitGS(false, false, false);
|
||||
return;
|
||||
}
|
||||
|
||||
MTGS::RunOnGSThread([]() {
|
||||
std::string filename(fmt::format("{}.{}", GSGetBaseVideoFilename(), GSConfig.CaptureContainer));
|
||||
g_gs_renderer->BeginCapture(std::move(filename));
|
||||
});
|
||||
MTGS::RunOnGSThread(&GSToggleVideoCapture);
|
||||
|
||||
// Sync GS thread. We want to start adding audio at the same time as video.
|
||||
MTGS::WaitGS(false, false, false);
|
||||
|
||||
@@ -81,6 +81,7 @@ void GSDumpSavedMetrics();
|
||||
bool GSIsSavingMetrics();
|
||||
bool GSBeginCapture(std::string filename);
|
||||
void GSEndCapture();
|
||||
void GSToggleVideoCapture();
|
||||
void GSPresentCurrentFrame();
|
||||
void GSThrottlePresentation();
|
||||
void GSGameChanged();
|
||||
|
||||
@@ -1359,8 +1359,9 @@ void GSState::DumpTransferImages()
|
||||
transfer.rect.x, transfer.rect.y, transfer.rect.z, transfer.rect.w);
|
||||
}
|
||||
|
||||
m_mem.SaveBMP(filename, transfer.blit.DBP, transfer.blit.DBW, transfer.blit.DPSM,
|
||||
transfer.rect.width(), transfer.rect.height(), transfer.rect.x, transfer.rect.y);
|
||||
if (!transfer.was_hardware_only)
|
||||
m_mem.SaveBMP(filename, transfer.blit.DBP, transfer.blit.DBW, transfer.blit.DPSM,
|
||||
transfer.rect.width(), transfer.rect.height(), transfer.rect.x, transfer.rect.y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2932,11 +2933,12 @@ void GSState::Write(const u8* mem, int len)
|
||||
m_draw_transfers.pop_back();
|
||||
transfer.rect = transfer.rect.runion(r);
|
||||
transfer.draw = s_n;
|
||||
transfer.was_hardware_only = false;
|
||||
m_draw_transfers.push_back(transfer);
|
||||
}
|
||||
else
|
||||
{
|
||||
const GSUploadQueue new_transfer = {blit, s_n, r, EEGS_TransferType::EE_to_GS};
|
||||
const GSUploadQueue new_transfer = {blit, s_n, r, EEGS_TransferType::EE_to_GS, false};
|
||||
m_draw_transfers.push_back(new_transfer);
|
||||
}
|
||||
|
||||
@@ -3131,11 +3133,12 @@ void GSState::Move()
|
||||
m_draw_transfers.pop_back();
|
||||
transfer.rect = transfer.rect.runion(r);
|
||||
transfer.draw = s_n;
|
||||
transfer.was_hardware_only = false;
|
||||
m_draw_transfers.push_back(transfer);
|
||||
}
|
||||
else
|
||||
{
|
||||
const GSUploadQueue new_transfer = {m_env.BITBLTBUF, s_n, r, EEGS_TransferType::GS_to_GS};
|
||||
const GSUploadQueue new_transfer = {m_env.BITBLTBUF, s_n, r, EEGS_TransferType::GS_to_GS, false};
|
||||
m_draw_transfers.push_back(new_transfer);
|
||||
}
|
||||
|
||||
|
||||
@@ -269,6 +269,7 @@ public:
|
||||
u64 draw;
|
||||
GSVector4i rect;
|
||||
EEGS_TransferType transfer_type;
|
||||
bool was_hardware_only;
|
||||
};
|
||||
|
||||
enum NoGapsType
|
||||
|
||||
@@ -2364,6 +2364,23 @@ void GSRendererHW::Move()
|
||||
if (g_texture_cache->Move(m_env.BITBLTBUF.SBP, m_env.BITBLTBUF.SBW, m_env.BITBLTBUF.SPSM, sx, sy,
|
||||
m_env.BITBLTBUF.DBP, m_env.BITBLTBUF.DBW, m_env.BITBLTBUF.DPSM, dx, dy, w, h))
|
||||
{
|
||||
// Store the transfer for preloading new RT's.
|
||||
if ((m_draw_transfers.size() > 0 && m_env.BITBLTBUF.DBP == m_draw_transfers.back().blit.DBP && m_draw_transfers.back().transfer_type == EEGS_TransferType::GS_to_GS))
|
||||
{
|
||||
// Same BP, let's update the rect.
|
||||
GSUploadQueue transfer = m_draw_transfers.back();
|
||||
m_draw_transfers.pop_back();
|
||||
transfer.rect = transfer.rect.runion(GSVector4i(dx, dy, dx + w, dy + h));
|
||||
transfer.draw = s_n;
|
||||
transfer.was_hardware_only = true;
|
||||
m_draw_transfers.push_back(transfer);
|
||||
}
|
||||
else
|
||||
{
|
||||
const GSUploadQueue new_transfer = {m_env.BITBLTBUF, s_n, GSVector4i(dx, dy, dx + w, dy + h), EEGS_TransferType::GS_to_GS, true};
|
||||
m_draw_transfers.push_back(new_transfer);
|
||||
}
|
||||
|
||||
m_env.TRXDIR.XDIR = 3;
|
||||
// Handled entirely in TC, no need to update local memory.
|
||||
return;
|
||||
@@ -10321,6 +10338,7 @@ bool GSRendererHW::TryGSMemClear(bool no_rt, bool preserve_rt, bool invalidate_r
|
||||
clear_queue.blit.DBP = m_cached_ctx.FRAME.Block();
|
||||
clear_queue.blit.DBW = m_cached_ctx.FRAME.FBW;
|
||||
clear_queue.blit.DPSM = m_cached_ctx.FRAME.PSM;
|
||||
clear_queue.was_hardware_only = false;
|
||||
m_draw_transfers.push_back(clear_queue);
|
||||
}
|
||||
else
|
||||
@@ -10351,6 +10369,7 @@ bool GSRendererHW::TryGSMemClear(bool no_rt, bool preserve_rt, bool invalidate_r
|
||||
clear_queue.blit.DBP = m_cached_ctx.ZBUF.Block();
|
||||
clear_queue.blit.DBW = m_cached_ctx.FRAME.FBW;
|
||||
clear_queue.blit.DPSM = m_cached_ctx.ZBUF.PSM;
|
||||
clear_queue.was_hardware_only = false;
|
||||
m_draw_transfers.push_back(clear_queue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -570,6 +570,7 @@ bool GSRendererHWFunctions::SwPrimRender(GSRendererHW& hw, bool invalidate_tc, b
|
||||
uq.blit.DPSM = hw.m_cached_ctx.FRAME.PSM;
|
||||
uq.draw = GSState::s_n;
|
||||
uq.rect = bbox;
|
||||
uq.was_hardware_only = false;
|
||||
hw.m_draw_transfers.push_back(uq);
|
||||
}
|
||||
|
||||
|
||||
@@ -4105,6 +4105,12 @@ GSTextureCache::Target* GSTextureCache::LookupDisplayTarget(GIFRegTEX0 TEX0, con
|
||||
if (last_draw - iter->draw > 500)
|
||||
break;
|
||||
|
||||
if (iter->was_hardware_only)
|
||||
{
|
||||
++iter;
|
||||
continue;
|
||||
}
|
||||
|
||||
const u32 transfer_end = GSLocalMemory::GetUnwrappedEndBlockAddress(iter->blit.DBP, iter->blit.DBW, iter->blit.DPSM, iter->rect);
|
||||
|
||||
// If the format, and location doesn't overlap
|
||||
@@ -5653,6 +5659,8 @@ bool GSTextureCache::ShuffleMove(u32 BP, u32 BW, u32 PSM, int sx, int sy, int dx
|
||||
if (read_ba || !write_rg)
|
||||
tgt->UnscaleRTAlpha();
|
||||
|
||||
tgt->Update();
|
||||
|
||||
GSHWDrawConfig& config = GSRendererHW::GetInstance()->BeginHLEHardwareDraw(tgt->m_texture, nullptr, tgt->m_scale, tgt->m_texture, tgt->m_scale, bbox);
|
||||
config.colormask.wrgba = (write_rg ? (1 | 2) : (4 | 8));
|
||||
config.ps.process_ba = read_ba ? 1 : 0;
|
||||
@@ -5734,6 +5742,15 @@ bool GSTextureCache::PageMove(u32 SBP, u32 DBP, u32 BW, u32 PSM, int sx, int sy,
|
||||
return false;
|
||||
}
|
||||
|
||||
// We don't want to copy "old" data that the game has overwritten with writes,
|
||||
// so flush any overlapping dirty area.
|
||||
// We pass that this is an invalidation to the translate function just to get a rough rect, we don't care if it's slightly for an overlap check.
|
||||
stgt->UpdateIfDirtyIntersects(TranslateAlignedRectByPage(stgt, SBP, PSM, BW, GSVector4i(sx, sy, sx + w, sy + h), true));
|
||||
|
||||
// The main point of HW moves is so GPU data can get used as sources. If we don't flush all writes,
|
||||
// we're not going to be able to use it as a source.
|
||||
dtgt->Update();
|
||||
|
||||
// Need to offset based on the target's actual BP.
|
||||
const u32 real_src_offset = ((SBP - stgt->m_TEX0.TBP0) / GS_BLOCKS_PER_PAGE) + src_page_offset;
|
||||
const u32 real_dst_offset = ((DBP - dtgt->m_TEX0.TBP0) / GS_BLOCKS_PER_PAGE) + dst_page_offset;
|
||||
|
||||
@@ -1215,9 +1215,15 @@ std::string GameList::FormatTimestamp(std::time_t timestamp)
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef _WIN32
|
||||
wchar_t buf[128];
|
||||
std::wcsftime(buf, std::size(buf), L"%x", &ttime);
|
||||
ret = StringUtil::WideStringToUTF8String(buf);
|
||||
#else
|
||||
char buf[128];
|
||||
std::strftime(buf, std::size(buf), "%x", &ttime);
|
||||
ret.assign(buf);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "CDVD/CDVDcommon.h"
|
||||
#include "GS/Renderers/Common/GSDevice.h"
|
||||
#include "GS/Renderers/Common/GSTexture.h"
|
||||
#include "GS/GSCapture.h"
|
||||
#include "Achievements.h"
|
||||
#include "CDVD/CDVDdiscReader.h"
|
||||
#include "GameList.h"
|
||||
@@ -58,8 +59,15 @@ TinyString FullscreenUI::TimeToPrintableString(time_t t)
|
||||
#endif
|
||||
|
||||
TinyString ret;
|
||||
#ifdef _WIN32
|
||||
wchar_t buf[65];
|
||||
pxAssert(std::size(buf) == ret.buffer_size());
|
||||
std::wcsftime(buf, std::size(buf), L"%c", <);
|
||||
ret.assign(StringUtil::WideStringToUTF8String(buf));
|
||||
#else
|
||||
std::strftime(ret.data(), ret.buffer_size(), "%c", <);
|
||||
ret.update_size();
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1309,9 +1317,16 @@ void FullscreenUI::DrawLandingTemplate(ImVec2* menu_pos, ImVec2* menu_size)
|
||||
#else
|
||||
localtime_r(&utc_time_t, &tm_local);
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
wchar_t buf[256];
|
||||
std::wcsftime(buf, std::size(buf), L"%X", &tm_local);
|
||||
heading_str.assign(StringUtil::WideStringToUTF8String(buf));
|
||||
#else
|
||||
char buf[256];
|
||||
std::strftime(buf, sizeof(buf), "%X", &tm_local);
|
||||
std::strftime(buf, std::size(buf), "%X", &tm_local);
|
||||
heading_str.assign(buf);
|
||||
#endif
|
||||
|
||||
const ImVec2 time_size = heading_font.first->CalcTextSizeA(heading_font.second, FLT_MAX, 0.0f, heading_str.c_str());
|
||||
time_pos = ImVec2(heading_size.x - LayoutScale(LAYOUT_MENU_BUTTON_X_PADDING) - time_size.x,
|
||||
@@ -1668,7 +1683,7 @@ void FullscreenUI::DrawPauseMenu(MainWindowType type)
|
||||
ImVec2(10.0f, 10.0f), ImGuiWindowFlags_NoBackground))
|
||||
{
|
||||
static constexpr u32 submenu_item_count[] = {
|
||||
11, // None
|
||||
12, // None
|
||||
4, // Exit
|
||||
3, // Achievements
|
||||
};
|
||||
@@ -1769,6 +1784,16 @@ void FullscreenUI::DrawPauseMenu(MainWindowType type)
|
||||
ClosePauseMenu();
|
||||
}
|
||||
|
||||
const bool is_capturing = GSCapture::IsCapturing();
|
||||
const bool can_start_capture = GSConfig.EnableVideoCapture || GSConfig.EnableAudioCapture;
|
||||
if (ActiveButton(is_capturing ? FSUI_ICONSTR(ICON_FA_VIDEO_SLASH, "Stop Recording") :
|
||||
FSUI_ICONSTR(ICON_FA_VIDEO, "Start Recording"),
|
||||
false, is_capturing || can_start_capture))
|
||||
{
|
||||
GSToggleVideoCapture();
|
||||
ClosePauseMenu();
|
||||
}
|
||||
|
||||
if (ActiveButton(GSIsHardwareRenderer() ? (FSUI_ICONSTR(ICON_FA_PAINTBRUSH, "Switch To Software Renderer")) :
|
||||
(FSUI_ICONSTR(ICON_FA_PAINTBRUSH, "Switch To Hardware Renderer")),
|
||||
false))
|
||||
|
||||
@@ -426,6 +426,7 @@ namespace FullscreenUI
|
||||
void SetSettingsChanged(SettingsInterface* bsi);
|
||||
bool GetEffectiveBoolSetting(SettingsInterface* bsi, const char* section, const char* key, bool default_value);
|
||||
s32 GetEffectiveIntSetting(SettingsInterface* bsi, const char* section, const char* key, s32 default_value);
|
||||
std::string GetEffectiveStringSetting(SettingsInterface* bsi, const char* section, const char* key, const char* default_value);
|
||||
void DoCopyGameSettings();
|
||||
void DoClearGameSettings();
|
||||
void ResetControllerSettings();
|
||||
@@ -466,6 +467,10 @@ namespace FullscreenUI
|
||||
void DrawStringListSetting(SettingsInterface* bsi, const char* title, const char* summary, const char* section, const char* key,
|
||||
const char* default_value, SettingInfo::GetOptionsCallback options_callback, bool enabled = true,
|
||||
float height = ImGuiFullscreen::LAYOUT_MENU_BUTTON_HEIGHT, std::pair<ImFont*, float> font = g_large_font, std::pair<ImFont*, float> summary_font = g_medium_font);
|
||||
void DrawStringListSetting(SettingsInterface* bsi, const char* title, const char* summary, const char* section, const char* key,
|
||||
const char* default_value, const std::vector<std::pair<std::string, std::string>>& items, bool enabled = true,
|
||||
std::vector<std::string> dependent_keys = {},
|
||||
float height = ImGuiFullscreen::LAYOUT_MENU_BUTTON_HEIGHT, std::pair<ImFont*, float> font = g_large_font, std::pair<ImFont*, float> summary_font = g_medium_font);
|
||||
void DrawIPAddressSetting(SettingsInterface* bsi, const char* title, const char* summary, const char* section, const char* key,
|
||||
const char* default_value, bool enabled = true, float height = ImGuiFullscreen::LAYOUT_MENU_BUTTON_HEIGHT,
|
||||
std::pair<ImFont*, float> font = g_large_font, std::pair<ImFont*, float> summary_font = g_medium_font,
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "GS/Renderers/Common/GSDevice.h"
|
||||
#include "GS/Renderers/Common/GSTexture.h"
|
||||
#include "GS/GSCapture.h"
|
||||
#include "GS/GSUtil.h"
|
||||
#include "Achievements.h"
|
||||
#include "GameList.h"
|
||||
@@ -240,6 +241,19 @@ s32 FullscreenUI::GetEffectiveIntSetting(SettingsInterface* bsi, const char* sec
|
||||
return Host::Internal::GetBaseSettingsLayer()->GetIntValue(section, key, default_value);
|
||||
}
|
||||
|
||||
std::string FullscreenUI::GetEffectiveStringSetting(
|
||||
SettingsInterface* bsi, const char* section, const char* key, const char* default_value)
|
||||
{
|
||||
if (IsEditingGameSettings(bsi))
|
||||
{
|
||||
std::optional<std::string> value = bsi->GetOptionalStringValue(section, key, std::nullopt);
|
||||
if (value.has_value())
|
||||
return value.value();
|
||||
}
|
||||
|
||||
return Host::Internal::GetBaseSettingsLayer()->GetStringValue(section, key, default_value);
|
||||
}
|
||||
|
||||
void FullscreenUI::DrawInputBindingButton(
|
||||
SettingsInterface* bsi, InputBindingInfo::Type type, const char* section, const char* name, const char* display_name, const char* icon_name, bool show_type)
|
||||
{
|
||||
@@ -1279,6 +1293,84 @@ void FullscreenUI::DrawStringListSetting(SettingsInterface* bsi, const char* tit
|
||||
}
|
||||
}
|
||||
|
||||
void FullscreenUI::DrawStringListSetting(SettingsInterface* bsi, const char* title, const char* summary, const char* section,
|
||||
const char* key, const char* default_value, const std::vector<std::pair<std::string, std::string>>& items, bool enabled,
|
||||
std::vector<std::string> dependent_keys, float height, std::pair<ImFont*, float> font, std::pair<ImFont*, float> summary_font)
|
||||
{
|
||||
const bool game_settings = IsEditingGameSettings(bsi);
|
||||
const std::optional<SmallString> value(
|
||||
bsi->GetOptionalSmallStringValue(section, key, (game_settings || !default_value) ? std::nullopt : std::optional<const char*>(default_value)));
|
||||
|
||||
const char* display_value = value.has_value() ? FSUI_CSTR("Unknown") : FSUI_CSTR("Use Global Setting");
|
||||
size_t current_index = items.size();
|
||||
|
||||
if (value.has_value())
|
||||
{
|
||||
for (size_t i = 0; i < items.size(); i++)
|
||||
{
|
||||
if (value.value() == items[i].first)
|
||||
{
|
||||
current_index = i;
|
||||
display_value = items[i].second.c_str();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (MenuButtonWithValue(title, summary, display_value, enabled, height, font, summary_font))
|
||||
{
|
||||
std::vector<std::string> option_values;
|
||||
option_values.reserve(items.size());
|
||||
ImGuiFullscreen::ChoiceDialogOptions cd_options;
|
||||
cd_options.reserve(items.size() + 1);
|
||||
|
||||
if (game_settings)
|
||||
cd_options.emplace_back(FSUI_STR("Use Global Setting"), !value.has_value());
|
||||
|
||||
for (size_t i = 0; i < items.size(); i++)
|
||||
{
|
||||
option_values.push_back(items[i].first);
|
||||
cd_options.emplace_back(items[i].second, (value.has_value() && i == current_index));
|
||||
}
|
||||
|
||||
OpenChoiceDialog(title, false, std::move(cd_options),
|
||||
[game_settings, section = std::string(section), key = std::string(key),
|
||||
dependent_keys = std::move(dependent_keys),
|
||||
default_value = default_value ? std::string(default_value) : std::string(),
|
||||
option_values = std::move(option_values)](s32 index, const std::string& title, bool checked) {
|
||||
if (index >= 0)
|
||||
{
|
||||
auto lock = Host::GetSettingsLock();
|
||||
SettingsInterface* bsi = GetEditingSettingsInterface(game_settings);
|
||||
const std::string old_value = GetEffectiveStringSetting(bsi, section.c_str(), key.c_str(), default_value.c_str());
|
||||
const std::optional<std::string> new_value = (game_settings && index == 0) ?
|
||||
std::nullopt :
|
||||
std::optional<std::string>(option_values[index - (game_settings ? 1 : 0)]);
|
||||
|
||||
if (new_value.has_value())
|
||||
bsi->SetStringValue(section.c_str(), key.c_str(), new_value->c_str());
|
||||
else
|
||||
bsi->DeleteValue(section.c_str(), key.c_str());
|
||||
|
||||
if (!dependent_keys.empty() && old_value != GetEffectiveStringSetting(bsi, section.c_str(), key.c_str(), default_value.c_str()))
|
||||
{
|
||||
for (const std::string& dep_key : dependent_keys)
|
||||
{
|
||||
if (!dep_key.empty())
|
||||
{
|
||||
bsi->SetStringValue(section.c_str(), dep_key.c_str(), "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SetSettingsChanged(bsi);
|
||||
}
|
||||
|
||||
CloseChoiceDialog();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void FullscreenUI::DrawFloatListSetting(SettingsInterface* bsi, const char* title, const char* summary, const char* section,
|
||||
const char* key, float default_value, const char* const* options, const float* option_values, size_t option_count,
|
||||
bool translate_options, bool enabled, float height, std::pair<ImFont*, float> font, std::pair<ImFont*, float> summary_font)
|
||||
@@ -3034,14 +3126,6 @@ void FullscreenUI::DrawGraphicsSettingsPage(SettingsInterface* bsi, bool show_ad
|
||||
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_TV, "Disable Interlace Offset"),
|
||||
FSUI_CSTR("Disables interlacing offset which may reduce blurring in some situations."), "EmuCore/GS",
|
||||
"disable_interlace_offset", false);
|
||||
DrawIntListSetting(bsi, FSUI_ICONSTR(ICON_FA_ARROWS_UP_DOWN_LEFT_RIGHT, "Screenshot Resolution"), FSUI_CSTR("Determines the resolution at which screenshots will be saved."),
|
||||
"EmuCore/GS", "ScreenshotSize", static_cast<int>(GSScreenshotSize::WindowResolution), s_screenshot_sizes,
|
||||
std::size(s_screenshot_sizes), true);
|
||||
DrawIntListSetting(bsi, FSUI_ICONSTR(ICON_FA_PHOTO_FILM, "Screenshot Format"), FSUI_CSTR("Selects the format which will be used to save screenshots."),
|
||||
"EmuCore/GS", "ScreenshotFormat", static_cast<int>(GSScreenshotFormat::PNG), s_screenshot_formats, std::size(s_screenshot_formats),
|
||||
true);
|
||||
DrawIntRangeSetting(bsi, FSUI_ICONSTR(ICON_FA_GAUGE, "Screenshot Quality"), FSUI_CSTR("Selects the quality at which screenshots will be compressed."),
|
||||
"EmuCore/GS", "ScreenshotQuality", 90, 1, 100, FSUI_CSTR("%d%%"));
|
||||
DrawIntRangeSetting(bsi, FSUI_ICONSTR(ICON_FA_ARROW_RIGHT_ARROW_LEFT, "Vertical Stretch"), FSUI_CSTR("Increases or decreases the virtual picture size vertically."),
|
||||
"EmuCore/GS", "StretchY", 100, 10, 300, FSUI_CSTR("%d%%"));
|
||||
DrawIntRectSetting(bsi, FSUI_ICONSTR(ICON_FA_CROP, "Crop"), FSUI_CSTR("Crops the image, while respecting aspect ratio."), "EmuCore/GS", "CropLeft", 0,
|
||||
@@ -3362,6 +3446,117 @@ void FullscreenUI::DrawGraphicsSettingsPage(SettingsInterface* bsi, bool show_ad
|
||||
s_tv_shaders, std::size(s_tv_shaders), true);
|
||||
}
|
||||
|
||||
MenuHeading(FSUI_CSTR("Media Capture"));
|
||||
|
||||
DrawIntListSetting(bsi, FSUI_ICONSTR(ICON_FA_ARROWS_UP_DOWN_LEFT_RIGHT, "Screenshot Resolution"), FSUI_CSTR("Determines the resolution at which screenshots will be saved."),
|
||||
"EmuCore/GS", "ScreenshotSize", static_cast<int>(GSScreenshotSize::WindowResolution), s_screenshot_sizes,
|
||||
std::size(s_screenshot_sizes), true);
|
||||
DrawIntListSetting(bsi, FSUI_ICONSTR(ICON_FA_PHOTO_FILM, "Screenshot Format"), FSUI_CSTR("Selects the format which will be used to save screenshots."),
|
||||
"EmuCore/GS", "ScreenshotFormat", static_cast<int>(GSScreenshotFormat::PNG), s_screenshot_formats, std::size(s_screenshot_formats),
|
||||
true);
|
||||
DrawIntRangeSetting(bsi, FSUI_ICONSTR(ICON_FA_GAUGE, "Screenshot Quality"), FSUI_CSTR("Selects the quality at which screenshots will be compressed."),
|
||||
"EmuCore/GS", "ScreenshotQuality", 90, 1, 100, FSUI_CSTR("%d%%"));
|
||||
|
||||
static const std::vector<std::pair<std::string, std::string>> s_capture_container_options = []() {
|
||||
std::vector<std::pair<std::string, std::string>> options;
|
||||
for (const char** container = Pcsx2Config::GSOptions::CaptureContainers; *container; container++)
|
||||
options.emplace_back(*container, StringUtil::toUpper(*container));
|
||||
return options;
|
||||
}();
|
||||
DrawStringListSetting(bsi, FSUI_ICONSTR(ICON_FA_BOX_ARCHIVE, "Container Format"),
|
||||
FSUI_CSTR("Selects the media container file format for recordings."), "EmuCore/GS", "CaptureContainer",
|
||||
Pcsx2Config::GSOptions::DEFAULT_CAPTURE_CONTAINER, s_capture_container_options, true,
|
||||
{"VideoCaptureCodec", "AudioCaptureCodec", "VideoCaptureFormat"});
|
||||
|
||||
const bool enable_video_capture = GetEffectiveBoolSetting(bsi, "EmuCore/GS", "EnableVideoCapture", true);
|
||||
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_VIDEO, "Capture Video"),
|
||||
FSUI_CSTR("Includes video in recordings."), "EmuCore/GS", "EnableVideoCapture", true);
|
||||
|
||||
const std::string container = GetEffectiveStringSetting(
|
||||
bsi, "EmuCore/GS", "CaptureContainer", Pcsx2Config::GSOptions::DEFAULT_CAPTURE_CONTAINER);
|
||||
|
||||
static std::string s_last_capture_container;
|
||||
static std::vector<std::pair<std::string, std::string>> s_video_codec_list_cache;
|
||||
static std::vector<std::pair<std::string, std::string>> s_audio_codec_list_cache;
|
||||
static bool s_capture_lists_initialized = false;
|
||||
|
||||
if (!s_capture_lists_initialized || s_last_capture_container != container)
|
||||
{
|
||||
s_last_capture_container = container;
|
||||
s_capture_lists_initialized = true;
|
||||
|
||||
s_video_codec_list_cache.clear();
|
||||
s_video_codec_list_cache.emplace_back("", FSUI_STR("Default"));
|
||||
for (const auto& codec : GSCapture::GetVideoCodecList(container.c_str()))
|
||||
s_video_codec_list_cache.emplace_back(codec.first, codec.first);
|
||||
|
||||
s_audio_codec_list_cache.clear();
|
||||
s_audio_codec_list_cache.emplace_back("", FSUI_STR("Default"));
|
||||
for (const auto& codec : GSCapture::GetAudioCodecList(container.c_str()))
|
||||
s_audio_codec_list_cache.emplace_back(codec.first, codec.first);
|
||||
}
|
||||
|
||||
DrawStringListSetting(bsi, FSUI_ICONSTR(ICON_FA_FILM, "Video Codec"),
|
||||
FSUI_CSTR("Selects the video codec used for recordings. If unsure, leave this set to Default."),
|
||||
"EmuCore/GS", "VideoCaptureCodec", "", s_video_codec_list_cache, enable_video_capture, {"VideoCaptureFormat"});
|
||||
|
||||
const std::string codec = GetEffectiveStringSetting(bsi, "EmuCore/GS", "VideoCaptureCodec", "");
|
||||
|
||||
static std::string s_last_capture_codec;
|
||||
static std::vector<std::pair<std::string, std::string>> s_video_format_list_cache;
|
||||
static bool s_format_list_initialized = false;
|
||||
|
||||
if (!s_format_list_initialized || s_last_capture_codec != codec)
|
||||
{
|
||||
s_last_capture_codec = codec;
|
||||
s_format_list_initialized = true;
|
||||
|
||||
s_video_format_list_cache.clear();
|
||||
s_video_format_list_cache.emplace_back("", FSUI_STR("Default"));
|
||||
if (!codec.empty())
|
||||
{
|
||||
for (const auto& [id, name] : GSCapture::GetVideoFormatList(codec.c_str()))
|
||||
s_video_format_list_cache.emplace_back(fmt::to_string(id), name);
|
||||
}
|
||||
}
|
||||
|
||||
DrawStringListSetting(bsi, FSUI_ICONSTR(ICON_FA_IMAGE, "Video Format"),
|
||||
FSUI_CSTR("Selects the pixel format used for recordings. Unsupported formats fall back to a format supported by the codec."),
|
||||
"EmuCore/GS", "VideoCaptureFormat", "", s_video_format_list_cache, enable_video_capture);
|
||||
|
||||
DrawIntSpinBoxSetting(bsi, FSUI_ICONSTR(ICON_FA_GAUGE, "Video Bitrate"),
|
||||
FSUI_CSTR("Sets the video bitrate. Higher bitrates generally improve quality but increase file size."),
|
||||
"EmuCore/GS", "VideoCaptureBitrate", Pcsx2Config::GSOptions::DEFAULT_VIDEO_CAPTURE_BITRATE, 100, 200000, 500,
|
||||
FSUI_CSTR("%d kbps"), enable_video_capture);
|
||||
|
||||
const bool video_auto_resolution = GetEffectiveBoolSetting(bsi, "EmuCore/GS", "VideoCaptureAutoResolution", true);
|
||||
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_ARROWS_UP_DOWN_LEFT_RIGHT, "Automatic Resolution"),
|
||||
FSUI_CSTR("When checked, the video capture resolution will follow the internal resolution of the running game."),
|
||||
"EmuCore/GS", "VideoCaptureAutoResolution", true, enable_video_capture);
|
||||
|
||||
DrawIntSpinBoxSetting(bsi, FSUI_ICONSTR(ICON_FA_ARROWS_LEFT_RIGHT, "Video Capture Width"),
|
||||
FSUI_CSTR("Sets the recording width when Automatic Resolution is disabled."),
|
||||
"EmuCore/GS", "VideoCaptureWidth", Pcsx2Config::GSOptions::DEFAULT_VIDEO_CAPTURE_WIDTH, 320, 32768, 16,
|
||||
FSUI_CSTR("%dpx"), enable_video_capture && !video_auto_resolution);
|
||||
|
||||
DrawIntSpinBoxSetting(bsi, FSUI_ICONSTR(ICON_FA_ARROWS_UP_DOWN, "Video Capture Height"),
|
||||
FSUI_CSTR("Sets the recording height when Automatic Resolution is disabled."),
|
||||
"EmuCore/GS", "VideoCaptureHeight", Pcsx2Config::GSOptions::DEFAULT_VIDEO_CAPTURE_HEIGHT, 240, 32768, 16,
|
||||
FSUI_CSTR("%dpx"), enable_video_capture && !video_auto_resolution);
|
||||
|
||||
const bool enable_audio_capture = GetEffectiveBoolSetting(bsi, "EmuCore/GS", "EnableAudioCapture", true);
|
||||
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_VOLUME_HIGH, "Capture Audio"),
|
||||
FSUI_CSTR("Includes audio in recordings."), "EmuCore/GS", "EnableAudioCapture", true);
|
||||
|
||||
DrawStringListSetting(bsi, FSUI_ICONSTR(ICON_FA_HEADPHONES, "Audio Codec"),
|
||||
FSUI_CSTR("Selects the audio codec used for recordings. If unsure, leave this set to Default."),
|
||||
"EmuCore/GS", "AudioCaptureCodec", "", s_audio_codec_list_cache, enable_audio_capture);
|
||||
|
||||
DrawIntSpinBoxSetting(bsi, FSUI_ICONSTR(ICON_FA_GAUGE, "Audio Bitrate"),
|
||||
FSUI_CSTR("Sets the audio bitrate."),
|
||||
"EmuCore/GS", "AudioCaptureBitrate", Pcsx2Config::GSOptions::DEFAULT_AUDIO_CAPTURE_BITRATE, 16, 2048, 16,
|
||||
FSUI_CSTR("%d kbps"), enable_audio_capture);
|
||||
|
||||
static constexpr const char* s_gsdump_compression[] = {
|
||||
FSUI_NSTR("Uncompressed"),
|
||||
FSUI_NSTR("LZMA (xz)"),
|
||||
|
||||
@@ -123,8 +123,10 @@ void Pad::LoadConfig(const SettingsInterface& si)
|
||||
|
||||
const float axis_deadzone = si.GetFloatValue(section.c_str(), "Deadzone", Pad::DEFAULT_STICK_DEADZONE);
|
||||
const float axis_scale = si.GetFloatValue(section.c_str(), "AxisScale", Pad::DEFAULT_STICK_SCALE);
|
||||
const bool use_diagonal_scale_correction = si.GetBoolValue(section.c_str(), "UseDiagonalScaleCorrection", Pad::DEFAULT_USE_DIAGONAL_SCALE_CORRECTION);
|
||||
const float button_deadzone = si.GetFloatValue(section.c_str(), "ButtonDeadzone", Pad::DEFAULT_BUTTON_DEADZONE);
|
||||
pad->SetAxisScale(axis_deadzone, axis_scale);
|
||||
pad->SetDiagonalScaleCorrection(use_diagonal_scale_correction);
|
||||
pad->SetButtonDeadzone(button_deadzone);
|
||||
|
||||
if (ci->vibration_caps != Pad::VibrationCapabilities::NoVibration)
|
||||
|
||||
@@ -43,6 +43,7 @@ public: // Public members
|
||||
virtual void SetRawAnalogs(const std::tuple<u8, u8> left, const std::tuple<u8, u8> right) = 0;
|
||||
virtual void SetRawPressureButton(u32 index, const std::tuple<bool, u8> value) = 0;
|
||||
virtual void SetAxisScale(float deadzone, float scale) = 0;
|
||||
virtual void SetDiagonalScaleCorrection(bool enabled) = 0;
|
||||
virtual float GetVibrationScale(u32 motor) const = 0;
|
||||
virtual void SetVibrationScale(u32 motor, float scale) = 0;
|
||||
virtual float GetPressureModifier() const = 0;
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
|
||||
#include "IconsPromptFont.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
static const InputBindingInfo s_bindings[] = {
|
||||
// clang-format off
|
||||
{"Up", TRANSLATE_NOOP("Pad", "D-Pad Up"), ICON_PF_DPAD_UP, InputBindingInfo::Type::Button, PadDualshock2::Inputs::PAD_UP, GenericInputBinding::DPadUp},
|
||||
@@ -62,9 +65,14 @@ static const SettingInfo s_settings[] = {
|
||||
"0.00", "0.00", "1.00", "0.01", TRANSLATE_NOOP("Pad", "%.0f%%"), nullptr, nullptr, 100.0f},
|
||||
{SettingInfo::Type::Float, "AxisScale", TRANSLATE_NOOP("Pad", "Analog Sensitivity"),
|
||||
TRANSLATE_NOOP("Pad",
|
||||
"Sets the analog stick axis scaling factor. A value between 130% and 140% is recommended when using recent "
|
||||
"controllers, e.g. DualShock 4, Xbox One Controller."),
|
||||
"Sets the analog stick axis scaling factor. Modern controllers with square pickup zones, e.g. DualShock 4, Xbox One "
|
||||
"have better diagonal inputs at a range between 130-140%, but this will cause axes to reach max input early."),
|
||||
"1.33", "0.01", "2.00", "0.01", TRANSLATE_NOOP("Pad", "%.0f%%"), nullptr, nullptr, 100.0f},
|
||||
{SettingInfo::Type::Boolean, "UseDiagonalScaleCorrection", TRANSLATE_NOOP("Pad", "Use Diagonal Scale Correction"),
|
||||
TRANSLATE_NOOP("Pad",
|
||||
"Transforms analog stick pickup zone from a square to a circle, allows for full input at diagonals without also scaling the X and Y axes. "
|
||||
"Ideal for modern controllers with square pickup zones, e.g. DualShock 4, Xbox One. Setting Analog Sensitivity to 100% is recommended with this setting."),
|
||||
"false", "", "", "", TRANSLATE_NOOP("Pad", "%.0f%%"), nullptr, nullptr, 0.0f},
|
||||
{SettingInfo::Type::Float, "LargeMotorScale", TRANSLATE_NOOP("Pad", "Large Motor Vibration Scale"),
|
||||
TRANSLATE_NOOP("Pad", "Increases or decreases the intensity of low frequency vibration sent by the game."),
|
||||
"1.00", "0.00", "2.00", "0.01", TRANSLATE_NOOP("Pad", "%.0f%%"), nullptr, nullptr, 100.0f},
|
||||
@@ -576,14 +584,48 @@ void PadDualshock2::Set(u32 index, float value)
|
||||
if (index <= Inputs::PAD_L_LEFT)
|
||||
{
|
||||
// Left Stick
|
||||
this->analogs.lx = this->analogs.lxInvert ? MERGE(Inputs::PAD_L_LEFT, Inputs::PAD_L_RIGHT) : MERGE(Inputs::PAD_L_RIGHT, Inputs::PAD_L_LEFT);
|
||||
this->analogs.ly = this->analogs.lyInvert ? MERGE(Inputs::PAD_L_UP, Inputs::PAD_L_DOWN) : MERGE(Inputs::PAD_L_DOWN, Inputs::PAD_L_UP);
|
||||
const u8 combinedX = this->analogs.lxInvert ? MERGE(Inputs::PAD_L_LEFT, Inputs::PAD_L_RIGHT) : MERGE(Inputs::PAD_L_RIGHT, Inputs::PAD_L_LEFT);
|
||||
const u8 combinedY = this->analogs.lyInvert ? MERGE(Inputs::PAD_L_UP, Inputs::PAD_L_DOWN) : MERGE(Inputs::PAD_L_DOWN, Inputs::PAD_L_UP);
|
||||
|
||||
if (this->useDiagonalScaleCorrection)
|
||||
{
|
||||
const float normalizedX = (combinedX - 127.5) / 127.5f;
|
||||
const float normalizedY = (combinedY - 127.5) / 127.5f;
|
||||
const float magnitude = std::sqrt((normalizedX * normalizedX) + (normalizedY * normalizedY));
|
||||
const float max = std::max(std::abs(normalizedX), std::abs(normalizedY));
|
||||
const float scaledX = (normalizedX / max) * std::min(magnitude, 1.0f);
|
||||
const float scaledY = (normalizedY / max) * std::min(magnitude, 1.0f);
|
||||
this->analogs.lx = (scaledX * 127.5) + 127.5;
|
||||
this->analogs.ly = (scaledY * 127.5) + 127.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->analogs.lx = combinedX;
|
||||
this->analogs.ly = combinedY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Right Stick
|
||||
this->analogs.rx = this->analogs.rxInvert ? MERGE(Inputs::PAD_R_LEFT, Inputs::PAD_R_RIGHT) : MERGE(Inputs::PAD_R_RIGHT, Inputs::PAD_R_LEFT);
|
||||
this->analogs.ry = this->analogs.ryInvert ? MERGE(Inputs::PAD_R_UP, Inputs::PAD_R_DOWN) : MERGE(Inputs::PAD_R_DOWN, Inputs::PAD_R_UP);
|
||||
const u8 combinedX = this->analogs.rxInvert ? MERGE(Inputs::PAD_R_LEFT, Inputs::PAD_R_RIGHT) : MERGE(Inputs::PAD_R_RIGHT, Inputs::PAD_R_LEFT);
|
||||
const u8 combinedY = this->analogs.ryInvert ? MERGE(Inputs::PAD_R_UP, Inputs::PAD_R_DOWN) : MERGE(Inputs::PAD_R_DOWN, Inputs::PAD_R_UP);
|
||||
|
||||
if (this->useDiagonalScaleCorrection)
|
||||
{
|
||||
const float normalizedX = (combinedX - 127.5) / 127.5f;
|
||||
const float normalizedY = (combinedY - 127.5) / 127.5f;
|
||||
const float magnitude = std::sqrt((normalizedX * normalizedX) + (normalizedY * normalizedY));
|
||||
const float max = std::max(std::abs(normalizedX), std::abs(normalizedY));
|
||||
const float scaledX = (normalizedX / max) * std::min(magnitude, 1.0f);
|
||||
const float scaledY = (normalizedY / max) * std::min(magnitude, 1.0f);
|
||||
this->analogs.rx = (scaledX * 127.5) + 127.5;
|
||||
this->analogs.ry = (scaledY * 127.5) + 127.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->analogs.rx = combinedX;
|
||||
this->analogs.ry = combinedY;
|
||||
}
|
||||
}
|
||||
#undef MERGE
|
||||
|
||||
@@ -739,6 +781,11 @@ void PadDualshock2::SetAxisScale(float deadzone, float scale)
|
||||
this->axisScale = scale;
|
||||
}
|
||||
|
||||
void PadDualshock2::SetDiagonalScaleCorrection(bool enabled)
|
||||
{
|
||||
this->useDiagonalScaleCorrection = enabled;
|
||||
}
|
||||
|
||||
float PadDualshock2::GetVibrationScale(u32 motor) const
|
||||
{
|
||||
return this->vibrationScale[motor];
|
||||
|
||||
@@ -72,6 +72,8 @@ private:
|
||||
std::array<u8, VIBRATION_MOTORS> vibrationMotors = {};
|
||||
float axisScale = 1.0f;
|
||||
float axisDeadzone = 0.0f;
|
||||
// Determines if inputs from the host should be corrected from square pickup zone to circular
|
||||
bool useDiagonalScaleCorrection = false;
|
||||
std::array<float, 2> vibrationScale = {1.0f, 1.0f};
|
||||
// When the pressure modifier binding is activated, this is multiplied against
|
||||
// all values in pressures, to artificially reduce pressures and give players
|
||||
@@ -140,6 +142,7 @@ public:
|
||||
void SetRawAnalogs(const std::tuple<u8, u8> left, const std::tuple<u8, u8> right) override;
|
||||
void SetRawPressureButton(u32 index, const std::tuple<bool, u8> value) override;
|
||||
void SetAxisScale(float deadzone, float scale) override;
|
||||
void SetDiagonalScaleCorrection(bool enabled) override;
|
||||
float GetVibrationScale(u32 motor) const override;
|
||||
void SetVibrationScale(u32 motor, float scale) override;
|
||||
float GetPressureModifier() const override;
|
||||
|
||||
@@ -338,6 +338,10 @@ void PadGuitar::SetAxisScale(float deadzone, float scale)
|
||||
this->whammyAxisScale = scale;
|
||||
}
|
||||
|
||||
void PadGuitar::SetDiagonalScaleCorrection(bool enabled)
|
||||
{
|
||||
}
|
||||
|
||||
float PadGuitar::GetVibrationScale(u32 motor) const
|
||||
{
|
||||
return 0;
|
||||
|
||||
@@ -69,6 +69,7 @@ public:
|
||||
void SetRawAnalogs(const std::tuple<u8, u8> left, const std::tuple<u8, u8> right) override;
|
||||
void SetRawPressureButton(u32 index, const std::tuple<bool, u8> value) override;
|
||||
void SetAxisScale(float deadzone, float scale) override;
|
||||
void SetDiagonalScaleCorrection(bool enabled) override;
|
||||
float GetVibrationScale(u32 motor) const override;
|
||||
void SetVibrationScale(u32 motor, float scale) override;
|
||||
float GetPressureModifier() const override;
|
||||
|
||||
@@ -376,6 +376,10 @@ void PadJogcon::SetAxisScale(float deadzone, float scale)
|
||||
this->dialScale = scale;
|
||||
}
|
||||
|
||||
void PadJogcon::SetDiagonalScaleCorrection(bool enabled)
|
||||
{
|
||||
}
|
||||
|
||||
float PadJogcon::GetVibrationScale(u32 motor) const
|
||||
{
|
||||
return this->vibrationScale[motor];
|
||||
|
||||
@@ -99,6 +99,7 @@ public:
|
||||
void SetRawAnalogs(const std::tuple<u8, u8> left, const std::tuple<u8, u8> right) override;
|
||||
void SetRawPressureButton(u32 index, const std::tuple<bool, u8> value) override;
|
||||
void SetAxisScale(float deadzone, float scale) override;
|
||||
void SetDiagonalScaleCorrection(bool enabled) override;
|
||||
float GetVibrationScale(u32 motor) const override;
|
||||
void SetVibrationScale(u32 motor, float scale) override;
|
||||
float GetPressureModifier() const override;
|
||||
|
||||
@@ -375,6 +375,10 @@ void PadNegcon::SetAxisScale(float deadzone, float scale)
|
||||
this->twistScale = scale;
|
||||
}
|
||||
|
||||
void PadNegcon::SetDiagonalScaleCorrection(bool enabled)
|
||||
{
|
||||
}
|
||||
|
||||
float PadNegcon::GetVibrationScale(u32 motor) const
|
||||
{
|
||||
return this->vibrationScale[motor];
|
||||
|
||||
@@ -111,6 +111,7 @@ public:
|
||||
void SetRawAnalogs(const std::tuple<u8, u8> left, const std::tuple<u8, u8> right) override;
|
||||
void SetRawPressureButton(u32 index, const std::tuple<bool, u8> value) override;
|
||||
void SetAxisScale(float deadzone, float scale) override;
|
||||
void SetDiagonalScaleCorrection(bool enabled) override;
|
||||
float GetVibrationScale(u32 motor) const override;
|
||||
void SetVibrationScale(u32 motor, float scale) override;
|
||||
float GetPressureModifier() const override;
|
||||
|
||||
@@ -46,6 +46,11 @@ void PadNotConnected::SetAxisScale(float deadzone, float scale)
|
||||
|
||||
}
|
||||
|
||||
void PadNotConnected::SetDiagonalScaleCorrection(bool enabled)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
float PadNotConnected::GetVibrationScale(u32 motor) const
|
||||
{
|
||||
return 0;
|
||||
|
||||
@@ -17,6 +17,7 @@ public:
|
||||
void SetRawAnalogs(const std::tuple<u8, u8> left, const std::tuple<u8, u8> right) override;
|
||||
void SetRawPressureButton(u32 index, const std::tuple<bool, u8> value) override;
|
||||
void SetAxisScale(float deadzone, float scale) override;
|
||||
void SetDiagonalScaleCorrection(bool enabled) override;
|
||||
float GetVibrationScale(u32 motor) const override;
|
||||
void SetVibrationScale(u32 motor, float scale) override;
|
||||
float GetPressureModifier() const override;
|
||||
|
||||
@@ -410,6 +410,10 @@ void PadPopn::SetAxisScale(float deadzone, float scale)
|
||||
{
|
||||
}
|
||||
|
||||
void PadPopn::SetDiagonalScaleCorrection(bool enabled)
|
||||
{
|
||||
}
|
||||
|
||||
float PadPopn::GetVibrationScale(u32 motor) const
|
||||
{
|
||||
return 0;
|
||||
|
||||
@@ -96,6 +96,7 @@ public:
|
||||
void SetRawAnalogs(const std::tuple<u8, u8> left, const std::tuple<u8, u8> right) override;
|
||||
void SetRawPressureButton(u32 index, const std::tuple<bool, u8> value) override;
|
||||
void SetAxisScale(float deadzone, float scale) override;
|
||||
void SetDiagonalScaleCorrection(bool enabled) override;
|
||||
float GetVibrationScale(u32 motor) const override;
|
||||
void SetVibrationScale(u32 motor, float scale) override;
|
||||
float GetPressureModifier() const override;
|
||||
|
||||
@@ -101,6 +101,7 @@ namespace Pad
|
||||
// Default stick deadzone/sensitivity.
|
||||
static constexpr float DEFAULT_STICK_DEADZONE = 0.0f;
|
||||
static constexpr float DEFAULT_STICK_SCALE = 1.33f;
|
||||
static constexpr float DEFAULT_USE_DIAGONAL_SCALE_CORRECTION = false;
|
||||
static constexpr float DEFAULT_MOTOR_SCALE = 1.0f;
|
||||
static constexpr float DEFAULT_PRESSURE_MODIFIER = 0.5f;
|
||||
static constexpr float DEFAULT_BUTTON_DEADZONE = 0.0f;
|
||||
|
||||
Reference in New Issue
Block a user