mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-04-20 19:44:57 +00:00
Merge branch 'master' of https://github.com/MarioPartyNetplay/Dolphin-MPN
This commit is contained in:
commit
89d176fd8b
31 changed files with 316 additions and 191 deletions
|
@ -1320,12 +1320,8 @@ c24e6288 00000006
|
|||
e2000001 80008000
|
||||
*Battle Minigames do not count towards the Mini-Game Star.
|
||||
|
||||
$Minigame - Battle Games - Can Replace 1VS3 or 2VS2 Minigames [Tabitha]
|
||||
0421E51C 60000000
|
||||
0421E520 60000000
|
||||
|
||||
$Minigame - Battle Games - Coins Taken is based off of Progress [Tabitha]
|
||||
C221E520 0000001A
|
||||
C221E520 0000001D
|
||||
3DC08029 89EE151D
|
||||
3A000001 7DEF8214
|
||||
3A000005 7DEF83D6
|
||||
|
@ -1351,6 +1347,9 @@ C221E520 0000001A
|
|||
3E603AA0 62730000
|
||||
3F808022 639C124C
|
||||
927C0000 48000004
|
||||
3A600000 3B800000
|
||||
39C00000 39E00000
|
||||
3A000000 3A400000
|
||||
2C000000 00000000
|
||||
*Battle minigames take coins dependent on the progress of the game.
|
||||
*(1/5 = 5), (2/5 = 10), (3/5 = 20), (4/5 = 30), (5/5 = 50)
|
||||
|
@ -1730,4 +1729,4 @@ c204a98c 00000002
|
|||
7c9f2378 7ca50e70
|
||||
60000000 00000000
|
||||
*Game runs at 30Hz but still feel like 60FPS. Great for people with bad PCs
|
||||
*Can break certain minigames
|
||||
*Can break certain minigames
|
||||
|
|
|
@ -124,7 +124,7 @@ class Settings : Closeable {
|
|||
const val SECTION_INI_DSP = "DSP"
|
||||
const val SECTION_LOGGER_LOGS = "Logs"
|
||||
const val SECTION_LOGGER_OPTIONS = "Options"
|
||||
const val SECTION_GFX_HARDWARE = "Settings"
|
||||
const val SECTION_GFX_HARDWARE = "Hardware"
|
||||
const val SECTION_GFX_SETTINGS = "Settings"
|
||||
const val SECTION_GFX_ENHANCEMENTS = "Enhancements"
|
||||
const val SECTION_GFX_COLOR_CORRECTION = "ColorCorrection"
|
||||
|
|
|
@ -34,6 +34,7 @@ add_library(common
|
|||
Config/Enums.h
|
||||
Config/Layer.cpp
|
||||
Config/Layer.h
|
||||
Contains.h
|
||||
CPUDetect.h
|
||||
Crypto/AES.cpp
|
||||
Crypto/AES.h
|
||||
|
|
61
Source/Core/Common/Contains.h
Normal file
61
Source/Core/Common/Contains.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
// Copyright 2025 Dolphin Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
namespace Common
|
||||
{
|
||||
struct ContainsFn
|
||||
{
|
||||
template <std::input_iterator I, std::sentinel_for<I> S, class T, class Proj = std::identity>
|
||||
requires std::indirect_binary_predicate < std::ranges::equal_to, std::projected<I, Proj>,
|
||||
const T* > constexpr bool operator()(I first, S last, const T& value, Proj proj = {}) const
|
||||
{
|
||||
return std::ranges::find(std::move(first), last, value, std::move(proj)) != last;
|
||||
}
|
||||
|
||||
template <std::ranges::input_range R, class T, class Proj = std::identity>
|
||||
requires std::indirect_binary_predicate < std::ranges::equal_to,
|
||||
std::projected<std::ranges::iterator_t<R>, Proj>,
|
||||
const T* > constexpr bool operator()(R&& r, const T& value, Proj proj = {}) const
|
||||
{
|
||||
return (*this)(std::ranges::begin(r), std::ranges::end(r), value, std::move(proj));
|
||||
}
|
||||
};
|
||||
|
||||
struct ContainsSubrangeFn
|
||||
{
|
||||
template <std::forward_iterator I1, std::sentinel_for<I1> S1, std::forward_iterator I2,
|
||||
std::sentinel_for<I2> S2, class Pred = std::ranges::equal_to,
|
||||
class Proj1 = std::identity, class Proj2 = std::identity>
|
||||
requires std::indirectly_comparable<I1, I2, Pred, Proj1, Proj2>
|
||||
constexpr bool operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {},
|
||||
Proj1 proj1 = {}, Proj2 proj2 = {}) const
|
||||
{
|
||||
return !std::ranges::search(std::move(first1), std::move(last1), std::move(first2),
|
||||
std::move(last2), std::move(pred), std::move(proj1),
|
||||
std::move(proj2))
|
||||
.empty();
|
||||
}
|
||||
|
||||
template <std::ranges::forward_range R1, std::ranges::forward_range R2,
|
||||
class Pred = std::ranges::equal_to, class Proj1 = std::identity,
|
||||
class Proj2 = std::identity>
|
||||
requires std::indirectly_comparable<std::ranges::iterator_t<R1>, std::ranges::iterator_t<R2>,
|
||||
Pred, Proj1, Proj2>
|
||||
constexpr bool operator()(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {},
|
||||
Proj2 proj2 = {}) const
|
||||
{
|
||||
return (*this)(std::ranges::begin(r1), std::ranges::end(r1), std::ranges::begin(r2),
|
||||
std::ranges::end(r2), std::move(pred), std::move(proj1), std::move(proj2));
|
||||
}
|
||||
};
|
||||
|
||||
// TODO C++23: Replace with std::ranges::contains.
|
||||
inline constexpr ContainsFn Contains{};
|
||||
// TODO C++23: Replace with std::ranges::contains_subrange.
|
||||
inline constexpr ContainsSubrangeFn ContainsSubrange{};
|
||||
} // namespace Common
|
|
@ -11,6 +11,7 @@
|
|||
#include <fmt/ranges.h>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Contains.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/StringUtil.h"
|
||||
|
||||
|
@ -105,9 +106,8 @@ bool IsTitlePath(const std::string& path, std::optional<FromWhichRoot> from, u64
|
|||
|
||||
static bool IsIllegalCharacter(char c)
|
||||
{
|
||||
static constexpr auto illegal_chars = {'\"', '*', '/', ':', '<', '>', '?', '\\', '|', '\x7f'};
|
||||
return static_cast<unsigned char>(c) <= 0x1F ||
|
||||
std::find(illegal_chars.begin(), illegal_chars.end(), c) != illegal_chars.end();
|
||||
static constexpr char illegal_chars[] = {'\"', '*', '/', ':', '<', '>', '?', '\\', '|', '\x7f'};
|
||||
return static_cast<unsigned char>(c) <= 0x1F || Common::Contains(illegal_chars, c);
|
||||
}
|
||||
|
||||
std::string EscapeFileName(const std::string& filename)
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "Common/Assert.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Contains.h"
|
||||
#include "Common/StringUtil.h"
|
||||
#include "Core/Host.h"
|
||||
#include "DiscIO/Enums.h"
|
||||
|
@ -38,17 +39,13 @@ static std::optional<DiscIO::Language> TryParseLanguage(const std::string& local
|
|||
// Special handling of Chinese due to its two writing systems
|
||||
if (split_locale[0] == "zh")
|
||||
{
|
||||
const auto locale_contains = [&split_locale](std::string_view str) {
|
||||
return std::find(split_locale.cbegin(), split_locale.cend(), str) != split_locale.cend();
|
||||
};
|
||||
|
||||
if (locale_contains("Hans"))
|
||||
if (Common::Contains(split_locale, "Hans"))
|
||||
return DiscIO::Language::SimplifiedChinese;
|
||||
if (locale_contains("Hant"))
|
||||
if (Common::Contains(split_locale, "Hant"))
|
||||
return DiscIO::Language::TraditionalChinese;
|
||||
|
||||
// Mainland China and Singapore use simplified characters
|
||||
if (locale_contains("CN") || locale_contains("SG"))
|
||||
if (Common::Contains(split_locale, "CN") || Common::Contains(split_locale, "SG"))
|
||||
return DiscIO::Language::SimplifiedChinese;
|
||||
else
|
||||
return DiscIO::Language::TraditionalChinese;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <algorithm>
|
||||
#include <array>
|
||||
|
||||
#include "Common/Contains.h"
|
||||
#include "Core/Config/WiimoteSettings.h"
|
||||
|
||||
namespace ConfigLoaders
|
||||
|
@ -15,8 +16,7 @@ bool IsSettingSaveable(const Config::Location& config_location)
|
|||
static constexpr std::array systems_not_saveable = {Config::System::GCPad, Config::System::WiiPad,
|
||||
Config::System::GCKeyboard};
|
||||
|
||||
if (std::find(begin(systems_not_saveable), end(systems_not_saveable), config_location.system) ==
|
||||
end(systems_not_saveable))
|
||||
if (!Common::Contains(systems_not_saveable, config_location.system))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <chrono>
|
||||
#include <regex>
|
||||
|
||||
#include "Common/Contains.h"
|
||||
#include "Common/Event.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/Debugger/PPCDebugInterface.h"
|
||||
|
@ -254,12 +255,9 @@ HitType CodeTrace::TraceLogic(const TraceOutput& current_instr, bool first_hit)
|
|||
// The reg_itr will be used later for erasing.
|
||||
auto reg_itr = std::ranges::find(m_reg_autotrack, instr.reg0);
|
||||
const bool match_reg123 =
|
||||
(!instr.reg1.empty() && std::find(m_reg_autotrack.begin(), m_reg_autotrack.end(),
|
||||
instr.reg1) != m_reg_autotrack.end()) ||
|
||||
(!instr.reg2.empty() && std::find(m_reg_autotrack.begin(), m_reg_autotrack.end(),
|
||||
instr.reg2) != m_reg_autotrack.end()) ||
|
||||
(!instr.reg3.empty() && std::find(m_reg_autotrack.begin(), m_reg_autotrack.end(),
|
||||
instr.reg3) != m_reg_autotrack.end());
|
||||
(!instr.reg1.empty() && Common::Contains(m_reg_autotrack, instr.reg1)) ||
|
||||
(!instr.reg2.empty() && Common::Contains(m_reg_autotrack, instr.reg2)) ||
|
||||
(!instr.reg3.empty() && Common::Contains(m_reg_autotrack, instr.reg3));
|
||||
const bool match_reg0 = reg_itr != m_reg_autotrack.end();
|
||||
|
||||
if (!match_reg0 && !match_reg123 && !mem_hit)
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <fmt/format.h>
|
||||
|
||||
#include "Common/Align.h"
|
||||
#include "Common/Contains.h"
|
||||
#include "Common/GekkoDisassembler.h"
|
||||
#include "Common/StringUtil.h"
|
||||
|
||||
|
@ -253,7 +254,7 @@ Common::Debug::Threads PPCDebugInterface::GetThreads(const Core::CPUThreadGuard&
|
|||
const auto insert_threads = [&guard, &threads, &visited_addrs](u32 addr, auto get_next_addr) {
|
||||
while (addr != 0 && PowerPC::MMU::HostIsRAMAddress(guard, addr))
|
||||
{
|
||||
if (std::find(visited_addrs.begin(), visited_addrs.end(), addr) != visited_addrs.end())
|
||||
if (Common::Contains(visited_addrs, addr))
|
||||
break;
|
||||
visited_addrs.push_back(addr);
|
||||
auto thread = std::make_unique<Core::Debug::OSThreadView>(guard, addr);
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "Common/ChunkFile.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Contains.h"
|
||||
#include "Common/Event.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/IOFile.h"
|
||||
|
@ -261,9 +262,7 @@ static int GetEmptySlot(const std::vector<SlotWithTimestamp>& used_slots)
|
|||
{
|
||||
for (int i = 1; i <= (int)NUM_STATES; i++)
|
||||
{
|
||||
const auto it = std::find_if(used_slots.begin(), used_slots.end(),
|
||||
[i](const SlotWithTimestamp& slot) { return slot.slot == i; });
|
||||
if (it == used_slots.end())
|
||||
if (!Common::Contains(used_slots, i, &SlotWithTimestamp::slot))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <array>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "Common/Contains.h"
|
||||
#include "Common/IniFile.h"
|
||||
#include "Common/StringUtil.h"
|
||||
|
||||
|
@ -86,10 +87,7 @@ static void LoadPatchSection(const Common::IniFile& ini)
|
|||
static bool IsWC24Channel()
|
||||
{
|
||||
const auto& sconfig = SConfig::GetInstance();
|
||||
const auto found =
|
||||
std::find(s_wc24_channels.begin(), s_wc24_channels.end(), sconfig.GetTitleID());
|
||||
|
||||
return found != s_wc24_channels.end();
|
||||
return Common::Contains(s_wc24_channels, sconfig.GetTitleID());
|
||||
}
|
||||
|
||||
static void LoadPatches()
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "Common/Align.h"
|
||||
#include "Common/Assert.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Contains.h"
|
||||
#include "Common/EnumUtils.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/HttpRequest.h"
|
||||
|
@ -590,10 +591,8 @@ UpdateResult OnlineSystemUpdater::InstallTitleFromNUS(const std::string& prefix_
|
|||
const UpdateResult import_result = [&]() {
|
||||
for (const IOS::ES::Content& content : tmd.first.GetContents())
|
||||
{
|
||||
const bool is_already_installed = std::find_if(stored_contents.begin(), stored_contents.end(),
|
||||
[&content](const auto& stored_content) {
|
||||
return stored_content.id == content.id;
|
||||
}) != stored_contents.end();
|
||||
const bool is_already_installed =
|
||||
Common::Contains(stored_contents, content.id, &IOS::ES::Content::id);
|
||||
|
||||
// Do skip what is already installed on the NAND.
|
||||
if (is_already_installed)
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "Common/CPUDetect.h"
|
||||
#include "Common/CommonPaths.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Contains.h"
|
||||
#include "Common/Crypto/SHA1.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/Hash.h"
|
||||
|
@ -143,11 +144,8 @@ RedumpVerifier::DownloadStatus RedumpVerifier::DownloadDatfile(const std::string
|
|||
if (File::Exists(output_path))
|
||||
return DownloadStatus::FailButOldCacheAvailable;
|
||||
|
||||
const std::string system_not_available_message = "System \"" + system + "\" doesn't exist.";
|
||||
const bool system_not_available_match =
|
||||
result->end() != std::search(result->begin(), result->end(),
|
||||
system_not_available_message.begin(),
|
||||
system_not_available_message.end());
|
||||
Common::ContainsSubrange(*result, "System \"" + system + "\" doesn't exist.");
|
||||
return system_not_available_match ? DownloadStatus::SystemNotAvailable : DownloadStatus::Fail;
|
||||
}
|
||||
|
||||
|
@ -453,21 +451,18 @@ std::vector<Partition> VolumeVerifier::CheckPartitions()
|
|||
types.emplace_back(*type);
|
||||
}
|
||||
|
||||
if (std::find(types.cbegin(), types.cend(), PARTITION_UPDATE) == types.cend())
|
||||
if (!Common::Contains(types, PARTITION_UPDATE))
|
||||
AddProblem(Severity::Low, Common::GetStringT("The update partition is missing."));
|
||||
|
||||
const bool has_data_partition =
|
||||
std::find(types.cbegin(), types.cend(), PARTITION_DATA) != types.cend();
|
||||
const bool has_data_partition = Common::Contains(types, PARTITION_DATA);
|
||||
if (!m_is_datel && !has_data_partition)
|
||||
AddProblem(Severity::High, Common::GetStringT("The data partition is missing."));
|
||||
|
||||
const bool has_channel_partition =
|
||||
std::find(types.cbegin(), types.cend(), PARTITION_CHANNEL) != types.cend();
|
||||
const bool has_channel_partition = Common::Contains(types, PARTITION_CHANNEL);
|
||||
if (ShouldHaveChannelPartition() && !has_channel_partition)
|
||||
AddProblem(Severity::Medium, Common::GetStringT("The channel partition is missing."));
|
||||
|
||||
const bool has_install_partition =
|
||||
std::find(types.cbegin(), types.cend(), PARTITION_INSTALL) != types.cend();
|
||||
const bool has_install_partition = Common::Contains(types, PARTITION_INSTALL);
|
||||
if (ShouldHaveInstallPartition() && !has_install_partition)
|
||||
AddProblem(Severity::High, Common::GetStringT("The install partition is missing."));
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
<ClInclude Include="Common\Config\ConfigInfo.h" />
|
||||
<ClInclude Include="Common\Config\Enums.h" />
|
||||
<ClInclude Include="Common\Config\Layer.h" />
|
||||
<ClInclude Include="Common\Contains.h" />
|
||||
<ClInclude Include="Common\CPUDetect.h" />
|
||||
<ClInclude Include="Common\Crypto\AES.h" />
|
||||
<ClInclude Include="Common\Crypto\bn.h" />
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// Copyright 2017 Dolphin Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include <QFont>
|
||||
|
||||
#include "DolphinQt/Config/ConfigControls/ConfigSlider.h"
|
||||
|
@ -24,14 +26,58 @@ ConfigSlider::ConfigSlider(int minimum, int maximum, const Config::Info<int>& se
|
|||
connect(this, &ConfigSlider::valueChanged, this, &ConfigSlider::Update);
|
||||
}
|
||||
|
||||
ConfigSlider::ConfigSlider(std::vector<int> tick_values, const Config::Info<int>& setting,
|
||||
Config::Layer* layer)
|
||||
: ConfigControl(Qt::Horizontal, setting.GetLocation(), layer), m_setting(setting),
|
||||
m_tick_values(std::move(tick_values))
|
||||
{
|
||||
assert(!m_tick_values.empty());
|
||||
setMinimum(0);
|
||||
setMaximum(static_cast<int>(m_tick_values.size() - 1));
|
||||
setPageStep(1);
|
||||
setTickPosition(QSlider::TicksBelow);
|
||||
OnConfigChanged();
|
||||
|
||||
connect(this, &ConfigSlider::valueChanged, this, &ConfigSlider::Update);
|
||||
}
|
||||
|
||||
void ConfigSlider::Update(int value)
|
||||
{
|
||||
SaveValue(m_setting, value);
|
||||
if (!m_tick_values.empty())
|
||||
{
|
||||
if (value >= 0 && static_cast<size_t>(value) < m_tick_values.size())
|
||||
SaveValue(m_setting, m_tick_values[static_cast<size_t>(value)]);
|
||||
}
|
||||
else
|
||||
{
|
||||
SaveValue(m_setting, value);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigSlider::OnConfigChanged()
|
||||
{
|
||||
setValue(ReadValue(m_setting));
|
||||
if (!m_tick_values.empty())
|
||||
{
|
||||
// re-enable in case it was disabled
|
||||
setEnabled(true);
|
||||
|
||||
const int config_value = ReadValue(m_setting);
|
||||
for (size_t i = 0; i < m_tick_values.size(); ++i)
|
||||
{
|
||||
if (m_tick_values[i] == config_value)
|
||||
{
|
||||
setValue(static_cast<int>(i));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// if we reach here than none of the options matched, disable the slider
|
||||
setEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
setValue(ReadValue(m_setting));
|
||||
}
|
||||
}
|
||||
|
||||
ConfigSliderLabel::ConfigSliderLabel(const QString& text, ConfigSlider* slider)
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <QLabel>
|
||||
#include <QPointer>
|
||||
|
||||
|
@ -19,6 +21,11 @@ public:
|
|||
ConfigSlider(int minimum, int maximum, const Config::Info<int>& setting, Config::Layer* layer,
|
||||
int tick = 0);
|
||||
|
||||
// Generates a slider with tick_values.size() ticks. Each tick corresponds to the integer at that
|
||||
// index in the vector.
|
||||
ConfigSlider(std::vector<int> tick_values, const Config::Info<int>& setting,
|
||||
Config::Layer* layer);
|
||||
|
||||
void Update(int value);
|
||||
|
||||
protected:
|
||||
|
@ -26,6 +33,9 @@ protected:
|
|||
|
||||
private:
|
||||
const Config::Info<int> m_setting;
|
||||
|
||||
// Mappings for slider ticks to config values. Identity mapping is assumed if this is empty.
|
||||
std::vector<int> m_tick_values;
|
||||
};
|
||||
|
||||
class ConfigSliderLabel final : public QLabel
|
||||
|
|
|
@ -25,23 +25,18 @@
|
|||
HacksWidget::HacksWidget(GraphicsWindow* parent)
|
||||
{
|
||||
CreateWidgets();
|
||||
LoadSettings();
|
||||
ConnectWidgets();
|
||||
AddDescriptions();
|
||||
|
||||
connect(parent, &GraphicsWindow::BackendChanged, this, &HacksWidget::OnBackendChanged);
|
||||
OnBackendChanged(QString::fromStdString(Config::Get(Config::MAIN_GFX_BACKEND)));
|
||||
connect(&Settings::Instance(), &Settings::ConfigChanged, this, &HacksWidget::LoadSettings);
|
||||
connect(m_gpu_texture_decoding, &QCheckBox::toggled, [this, parent] {
|
||||
SaveSettings();
|
||||
emit parent->UseGPUTextureDecodingChanged();
|
||||
});
|
||||
connect(m_gpu_texture_decoding, &QCheckBox::toggled,
|
||||
[this, parent] { emit parent->UseGPUTextureDecodingChanged(); });
|
||||
}
|
||||
|
||||
HacksWidget::HacksWidget(GameConfigWidget* parent, Config::Layer* layer) : m_game_layer(layer)
|
||||
{
|
||||
CreateWidgets();
|
||||
LoadSettings();
|
||||
ConnectWidgets();
|
||||
AddDescriptions();
|
||||
}
|
||||
|
@ -73,18 +68,15 @@ void HacksWidget::CreateWidgets()
|
|||
auto* texture_cache_layout = new QGridLayout();
|
||||
texture_cache_box->setLayout(texture_cache_layout);
|
||||
|
||||
m_accuracy = new ToolTipSlider(Qt::Horizontal);
|
||||
m_accuracy->setMinimum(0);
|
||||
m_accuracy->setMaximum(2);
|
||||
m_accuracy->setPageStep(1);
|
||||
m_accuracy->setTickPosition(QSlider::TicksBelow);
|
||||
m_accuracy =
|
||||
new ConfigSlider({0, 512, 128}, Config::GFX_SAFE_TEXTURE_CACHE_COLOR_SAMPLES, m_game_layer);
|
||||
m_gpu_texture_decoding = new ConfigBool(tr("GPU Texture Decoding"),
|
||||
Config::GFX_ENABLE_GPU_TEXTURE_DECODING, m_game_layer);
|
||||
|
||||
auto* safe_label = new QLabel(tr("Safe"));
|
||||
safe_label->setAlignment(Qt::AlignRight);
|
||||
|
||||
m_accuracy_label = new QLabel(tr("Accuracy:"));
|
||||
m_accuracy_label = new ConfigSliderLabel(tr("Accuracy:"), m_accuracy);
|
||||
|
||||
texture_cache_layout->addWidget(m_accuracy_label, 0, 0);
|
||||
texture_cache_layout->addWidget(safe_label, 0, 1);
|
||||
|
@ -158,7 +150,6 @@ void HacksWidget::OnBackendChanged(const QString& backend_name)
|
|||
|
||||
void HacksWidget::ConnectWidgets()
|
||||
{
|
||||
connect(m_accuracy, &QSlider::valueChanged, [this](int) { SaveSettings(); });
|
||||
connect(m_store_efb_copies, &QCheckBox::stateChanged,
|
||||
[this](int) { UpdateDeferEFBCopiesEnabled(); });
|
||||
connect(m_store_xfb_copies, &QCheckBox::stateChanged,
|
||||
|
@ -169,65 +160,6 @@ void HacksWidget::ConnectWidgets()
|
|||
[this](int) { UpdateSkipPresentingDuplicateFramesEnabled(); });
|
||||
}
|
||||
|
||||
void HacksWidget::LoadSettings()
|
||||
{
|
||||
const QSignalBlocker blocker(m_accuracy);
|
||||
auto samples = Config::Get(Config::GFX_SAFE_TEXTURE_CACHE_COLOR_SAMPLES);
|
||||
|
||||
// Re-enable the slider in case it was disabled because of a custom value
|
||||
m_accuracy->setEnabled(true);
|
||||
|
||||
int slider_pos = 0;
|
||||
|
||||
switch (samples)
|
||||
{
|
||||
case 512:
|
||||
slider_pos = 1;
|
||||
break;
|
||||
case 128:
|
||||
slider_pos = 2;
|
||||
break;
|
||||
case 0:
|
||||
slider_pos = 0;
|
||||
break;
|
||||
// Custom values, ought not to be touched
|
||||
default:
|
||||
m_accuracy->setEnabled(false);
|
||||
}
|
||||
|
||||
m_accuracy->setValue(slider_pos);
|
||||
|
||||
QFont bf = m_accuracy_label->font();
|
||||
|
||||
bf.setBold(Config::GetActiveLayerForConfig(Config::GFX_SAFE_TEXTURE_CACHE_COLOR_SAMPLES) !=
|
||||
Config::LayerType::Base);
|
||||
|
||||
m_accuracy_label->setFont(bf);
|
||||
}
|
||||
|
||||
void HacksWidget::SaveSettings()
|
||||
{
|
||||
int slider_pos = m_accuracy->value();
|
||||
|
||||
if (m_accuracy->isEnabled())
|
||||
{
|
||||
int samples = 0;
|
||||
switch (slider_pos)
|
||||
{
|
||||
case 0:
|
||||
samples = 0;
|
||||
break;
|
||||
case 1:
|
||||
samples = 512;
|
||||
break;
|
||||
case 2:
|
||||
samples = 128;
|
||||
}
|
||||
|
||||
Config::SetBaseOrCurrent(Config::GFX_SAFE_TEXTURE_CACHE_COLOR_SAMPLES, samples);
|
||||
}
|
||||
}
|
||||
|
||||
void HacksWidget::AddDescriptions()
|
||||
{
|
||||
static const char TR_SKIP_EFB_CPU_ACCESS_DESCRIPTION[] = QT_TR_NOOP(
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include <QWidget>
|
||||
|
||||
class ConfigBool;
|
||||
class ConfigSlider;
|
||||
class ConfigSliderLabel;
|
||||
class GameConfigWidget;
|
||||
class GraphicsWindow;
|
||||
class QLabel;
|
||||
|
@ -24,9 +26,6 @@ public:
|
|||
HacksWidget(GameConfigWidget* parent, Config::Layer* layer);
|
||||
|
||||
private:
|
||||
void LoadSettings();
|
||||
void SaveSettings();
|
||||
|
||||
void OnBackendChanged(const QString& backend_name);
|
||||
|
||||
// EFB
|
||||
|
@ -36,8 +35,8 @@ private:
|
|||
ConfigBool* m_defer_efb_copies;
|
||||
|
||||
// Texture Cache
|
||||
QLabel* m_accuracy_label;
|
||||
ToolTipSlider* m_accuracy;
|
||||
ConfigSliderLabel* m_accuracy_label;
|
||||
ConfigSlider* m_accuracy;
|
||||
ConfigBool* m_gpu_texture_decoding;
|
||||
|
||||
// External Framebuffer
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <QToolBar>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "Common/Contains.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/IniFile.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
|
@ -482,10 +483,7 @@ void BreakpointWidget::OnContextMenu(const QPoint& pos)
|
|||
if (!is_memory_breakpoint)
|
||||
{
|
||||
const auto& inst_breakpoints = m_system.GetPowerPC().GetBreakPoints().GetBreakPoints();
|
||||
const auto bp_iter =
|
||||
std::find_if(inst_breakpoints.begin(), inst_breakpoints.end(),
|
||||
[bp_address](const auto& bp) { return bp.address == bp_address; });
|
||||
if (bp_iter == inst_breakpoints.end())
|
||||
if (!Common::Contains(inst_breakpoints, bp_address, &TBreakPoint::address))
|
||||
return;
|
||||
|
||||
menu->addAction(tr("Show in Code"), [this, bp_address] { emit ShowCode(bp_address); });
|
||||
|
@ -498,10 +496,7 @@ void BreakpointWidget::OnContextMenu(const QPoint& pos)
|
|||
else
|
||||
{
|
||||
const auto& memory_breakpoints = m_system.GetPowerPC().GetMemChecks().GetMemChecks();
|
||||
const auto mb_iter =
|
||||
std::find_if(memory_breakpoints.begin(), memory_breakpoints.end(),
|
||||
[bp_address](const auto& bp) { return bp.start_address == bp_address; });
|
||||
if (mb_iter == memory_breakpoints.end())
|
||||
if (!Common::Contains(memory_breakpoints, bp_address, &TMemCheck::start_address))
|
||||
return;
|
||||
|
||||
menu->addAction(tr("Show in Memory"), [this, bp_address] { emit ShowMemory(bp_address); });
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include <QUrl>
|
||||
|
||||
#include "Common/CommonPaths.h"
|
||||
#include "Common/Contains.h"
|
||||
#include "Common/FileUtil.h"
|
||||
|
||||
#include "Core/Config/MainSettings.h"
|
||||
|
@ -805,8 +806,7 @@ bool GameList::AddShortcutToDesktop()
|
|||
// Sanitize the string by removing all characters that cannot be used in NTFS file names
|
||||
std::erase_if(game_name, [](char ch) {
|
||||
static constexpr char illegal_characters[] = {'<', '>', ':', '\"', '/', '\\', '|', '?', '*'};
|
||||
return std::find(std::begin(illegal_characters), std::end(illegal_characters), ch) !=
|
||||
std::end(illegal_characters);
|
||||
return Common::Contains(illegal_characters, ch);
|
||||
});
|
||||
|
||||
std::wstring desktop_path = std::wstring(desktop.get()) + UTF8ToTStr("\\" + game_name + ".lnk");
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "Common/Contains.h"
|
||||
#include "Core/NetPlayClient.h"
|
||||
#include "Core/NetPlayServer.h"
|
||||
|
||||
|
@ -108,7 +109,7 @@ void ChunkedProgressDialog::show(const QString& title, const u64 data_size,
|
|||
|
||||
for (const auto* player : client->GetPlayers())
|
||||
{
|
||||
if (std::find(players.begin(), players.end(), player->pid) == players.end())
|
||||
if (!Common::Contains(players, player->pid))
|
||||
continue;
|
||||
|
||||
m_progress_bars[player->pid] = new QProgressBar;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "AudioCommon/AudioCommon.h"
|
||||
|
||||
#include "Common/Config/Config.h"
|
||||
#include "Common/Contains.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/StringUtil.h"
|
||||
|
||||
|
@ -297,7 +298,7 @@ void Settings::AddPath(const QString& qpath)
|
|||
std::string path = qpath.toStdString();
|
||||
std::vector<std::string> paths = Config::GetIsoPaths();
|
||||
|
||||
if (std::find(paths.begin(), paths.end(), path) != paths.end())
|
||||
if (Common::Contains(paths, path))
|
||||
return;
|
||||
|
||||
paths.emplace_back(path);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <jni.h>
|
||||
|
||||
#include "Common/Assert.h"
|
||||
#include "Common/Contains.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "Common/StringUtil.h"
|
||||
|
||||
|
@ -1132,8 +1133,7 @@ Java_org_dolphinemu_dolphinemu_features_input_model_ControllerInterface_notifySe
|
|||
|
||||
for (ciface::Core::Device::Input* input : device->Inputs())
|
||||
{
|
||||
const std::string input_name = input->GetName();
|
||||
if (std::find(axis_names.begin(), axis_names.end(), input_name) != axis_names.end())
|
||||
if (Common::Contains(axis_names, input->GetName()))
|
||||
{
|
||||
auto casted_input = static_cast<ciface::Android::AndroidSensorAxis*>(input);
|
||||
casted_input->NotifyIsSuspended(static_cast<bool>(suspended));
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <mz_os.h>
|
||||
|
||||
#include "Common/CommonPaths.h"
|
||||
#include "Common/Contains.h"
|
||||
#include "Common/FileSearch.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/IOFile.h"
|
||||
|
@ -181,8 +182,7 @@ bool ResourcePack::Install(const std::string& path)
|
|||
bool provided_by_other_pack = false;
|
||||
for (const auto& pack : GetHigherPriorityPacks(*this))
|
||||
{
|
||||
if (std::find(pack->GetTextures().begin(), pack->GetTextures().end(), texture) !=
|
||||
pack->GetTextures().end())
|
||||
if (Common::Contains(pack->GetTextures(), texture))
|
||||
{
|
||||
provided_by_other_pack = true;
|
||||
break;
|
||||
|
@ -246,9 +246,7 @@ bool ResourcePack::Uninstall(const std::string& path)
|
|||
// Check if a higher priority pack already provides a given texture, don't delete it
|
||||
for (const auto& pack : GetHigherPriorityPacks(*this))
|
||||
{
|
||||
if (::ResourcePack::IsInstalled(*pack) &&
|
||||
std::find(pack->GetTextures().begin(), pack->GetTextures().end(), texture) !=
|
||||
pack->GetTextures().end())
|
||||
if (::ResourcePack::IsInstalled(*pack) && Common::Contains(pack->GetTextures(), texture))
|
||||
{
|
||||
provided_by_other_pack = true;
|
||||
break;
|
||||
|
@ -261,9 +259,7 @@ bool ResourcePack::Uninstall(const std::string& path)
|
|||
// Check if a lower priority pack provides a given texture - if so, install it.
|
||||
for (auto& pack : lower)
|
||||
{
|
||||
if (::ResourcePack::IsInstalled(*pack) &&
|
||||
std::find(pack->GetTextures().rbegin(), pack->GetTextures().rend(), texture) !=
|
||||
pack->GetTextures().rend())
|
||||
if (::ResourcePack::IsInstalled(*pack) && Common::Contains(pack->GetTextures(), texture))
|
||||
{
|
||||
pack->Install(path);
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "Common/Contains.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "Common/StringUtil.h"
|
||||
#include "Core/Config/MainSettings.h"
|
||||
|
@ -244,7 +245,7 @@ void XRRConfiguration::AddResolutions(std::vector<std::string>& resos)
|
|||
std::string(screenResources->modes[k].name) +
|
||||
(interlaced ? "i" : "");
|
||||
// Only add unique resolutions
|
||||
if (std::find(resos.begin(), resos.end(), strRes) == resos.end())
|
||||
if (!Common::Contains(resos, strRes))
|
||||
{
|
||||
resos.push_back(strRes);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "Common/Assert.h"
|
||||
#include "Common/CommonFuncs.h"
|
||||
#include "Common/Contains.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "Common/MsgHandler.h"
|
||||
|
||||
|
@ -243,31 +244,24 @@ bool SwapChain::SelectPresentMode()
|
|||
&mode_count, present_modes.data());
|
||||
ASSERT(res == VK_SUCCESS);
|
||||
|
||||
// Checks if a particular mode is supported, if it is, returns that mode.
|
||||
auto CheckForMode = [&present_modes](VkPresentModeKHR check_mode) {
|
||||
auto it = std::find_if(present_modes.begin(), present_modes.end(),
|
||||
[check_mode](VkPresentModeKHR mode) { return check_mode == mode; });
|
||||
return it != present_modes.end();
|
||||
};
|
||||
|
||||
// If vsync is enabled, use VK_PRESENT_MODE_FIFO_KHR.
|
||||
// This check should not fail with conforming drivers, as the FIFO present mode is mandated by
|
||||
// the specification (VK_KHR_swapchain). In case it isn't though, fall through to any other mode.
|
||||
if (m_vsync_enabled && CheckForMode(VK_PRESENT_MODE_FIFO_KHR))
|
||||
if (m_vsync_enabled && Common::Contains(present_modes, VK_PRESENT_MODE_FIFO_KHR))
|
||||
{
|
||||
m_present_mode = VK_PRESENT_MODE_FIFO_KHR;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Prefer screen-tearing, if possible, for lowest latency.
|
||||
if (CheckForMode(VK_PRESENT_MODE_IMMEDIATE_KHR))
|
||||
if (Common::Contains(present_modes, VK_PRESENT_MODE_IMMEDIATE_KHR))
|
||||
{
|
||||
m_present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Use optimized-vsync above vsync.
|
||||
if (CheckForMode(VK_PRESENT_MODE_MAILBOX_KHR))
|
||||
if (Common::Contains(present_modes, VK_PRESENT_MODE_MAILBOX_KHR))
|
||||
{
|
||||
m_present_mode = VK_PRESENT_MODE_MAILBOX_KHR;
|
||||
return true;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "Common/Assert.h"
|
||||
#include "Common/CommonFuncs.h"
|
||||
#include "Common/Contains.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "Common/MsgHandler.h"
|
||||
#include "Common/StringUtil.h"
|
||||
|
@ -170,15 +171,12 @@ bool VulkanContext::CheckValidationLayerAvailablility()
|
|||
res = vkEnumerateInstanceLayerProperties(&layer_count, layer_list.data());
|
||||
ASSERT(res == VK_SUCCESS);
|
||||
|
||||
bool supports_validation_layers =
|
||||
std::find_if(layer_list.begin(), layer_list.end(), [](const auto& it) {
|
||||
return strcmp(it.layerName, VALIDATION_LAYER_NAME) == 0;
|
||||
}) != layer_list.end();
|
||||
bool supports_validation_layers = Common::Contains(
|
||||
layer_list, std::string_view{VALIDATION_LAYER_NAME}, &VkLayerProperties::layerName);
|
||||
|
||||
bool supports_debug_utils =
|
||||
std::find_if(extension_list.begin(), extension_list.end(), [](const auto& it) {
|
||||
return strcmp(it.extensionName, VK_EXT_DEBUG_UTILS_EXTENSION_NAME) == 0;
|
||||
}) != extension_list.end();
|
||||
Common::Contains(extension_list, std::string_view{VK_EXT_DEBUG_UTILS_EXTENSION_NAME},
|
||||
&VkExtensionProperties::extensionName);
|
||||
|
||||
if (!supports_debug_utils && supports_validation_layers)
|
||||
{
|
||||
|
@ -197,9 +195,8 @@ bool VulkanContext::CheckValidationLayerAvailablility()
|
|||
extension_list.data());
|
||||
ASSERT(res == VK_SUCCESS);
|
||||
supports_debug_utils =
|
||||
std::find_if(extension_list.begin(), extension_list.end(), [](const auto& it) {
|
||||
return strcmp(it.extensionName, VK_EXT_DEBUG_UTILS_EXTENSION_NAME) == 0;
|
||||
}) != extension_list.end();
|
||||
Common::Contains(extension_list, std::string_view{VK_EXT_DEBUG_UTILS_EXTENSION_NAME},
|
||||
&VkExtensionProperties::extensionName);
|
||||
}
|
||||
|
||||
// Check for both VK_EXT_debug_utils and VK_LAYER_KHRONOS_validation
|
||||
|
@ -330,16 +327,10 @@ bool VulkanContext::SelectInstanceExtensions(std::vector<const char*>* extension
|
|||
|
||||
auto AddExtension = [&](const char* name, bool required) {
|
||||
bool extension_supported =
|
||||
std::find_if(available_extension_list.begin(), available_extension_list.end(),
|
||||
[&](const VkExtensionProperties& properties) {
|
||||
return !strcmp(name, properties.extensionName);
|
||||
}) != available_extension_list.end();
|
||||
extension_supported =
|
||||
extension_supported ||
|
||||
std::find_if(validation_layer_extension_list.begin(), validation_layer_extension_list.end(),
|
||||
[&](const VkExtensionProperties& properties) {
|
||||
return !strcmp(name, properties.extensionName);
|
||||
}) != validation_layer_extension_list.end();
|
||||
Common::Contains(available_extension_list, std::string_view{name},
|
||||
&VkExtensionProperties::extensionName) ||
|
||||
Common::Contains(validation_layer_extension_list, std::string_view{name},
|
||||
&VkExtensionProperties::extensionName);
|
||||
|
||||
if (extension_supported)
|
||||
{
|
||||
|
@ -648,10 +639,8 @@ bool VulkanContext::SelectDeviceExtensions(bool enable_surface)
|
|||
INFO_LOG_FMT(VIDEO, "Available extension: {}", extension_properties.extensionName);
|
||||
|
||||
auto AddExtension = [&](const char* name, bool required) {
|
||||
if (std::find_if(available_extension_list.begin(), available_extension_list.end(),
|
||||
[&](const VkExtensionProperties& properties) {
|
||||
return !strcmp(name, properties.extensionName);
|
||||
}) != available_extension_list.end())
|
||||
if (Common::Contains(available_extension_list, std::string_view{name},
|
||||
&VkExtensionProperties::extensionName))
|
||||
{
|
||||
INFO_LOG_FMT(VIDEO, "Enabling extension: {}", name);
|
||||
m_device_extensions.push_back(name);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <array>
|
||||
#include <variant>
|
||||
|
||||
#include "Common/Contains.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "Common/VariantUtil.h"
|
||||
|
||||
|
@ -20,7 +21,7 @@ bool IsQualifier(std::string_view value)
|
|||
static constexpr std::array<std::string_view, 7> qualifiers = {
|
||||
"attribute", "const", "highp", "lowp", "mediump", "uniform", "varying",
|
||||
};
|
||||
return std::find(qualifiers.begin(), qualifiers.end(), value) != qualifiers.end();
|
||||
return Common::Contains(qualifiers, value);
|
||||
}
|
||||
|
||||
bool IsBuiltInMacro(std::string_view value)
|
||||
|
@ -28,7 +29,7 @@ bool IsBuiltInMacro(std::string_view value)
|
|||
static constexpr std::array<std::string_view, 5> built_in = {
|
||||
"__LINE__", "__FILE__", "__VERSION__", "GL_core_profile", "GL_compatibility_profile",
|
||||
};
|
||||
return std::find(built_in.begin(), built_in.end(), value) != built_in.end();
|
||||
return Common::Contains(built_in, value);
|
||||
}
|
||||
|
||||
std::vector<std::string> GlobalConflicts(std::string_view source)
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "Common/ChunkFile.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Contains.h"
|
||||
#include "Common/EnumMap.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "Common/MathUtil.h"
|
||||
|
@ -585,8 +586,7 @@ void VertexManagerBase::Flush()
|
|||
const auto cache_entry = g_texture_cache->Load(TextureInfo::FromStage(i));
|
||||
if (cache_entry)
|
||||
{
|
||||
if (std::find(texture_names.begin(), texture_names.end(),
|
||||
cache_entry->texture_info_name) == texture_names.end())
|
||||
if (!Common::Contains(texture_names, cache_entry->texture_info_name))
|
||||
{
|
||||
texture_names.push_back(cache_entry->texture_info_name);
|
||||
texture_units.push_back(i);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "Common/CPUDetect.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Contains.h"
|
||||
#include "Common/StringUtil.h"
|
||||
|
||||
#include "Core/CPUThreadConfigCallback.h"
|
||||
|
@ -214,8 +215,7 @@ void VideoConfig::VerifyValidity()
|
|||
if (iAdapter < 0 || iAdapter > ((int)backend_info.Adapters.size() - 1))
|
||||
iAdapter = 0;
|
||||
|
||||
if (std::find(backend_info.AAModes.begin(), backend_info.AAModes.end(), iMultisamples) ==
|
||||
backend_info.AAModes.end())
|
||||
if (!Common::Contains(backend_info.AAModes, iMultisamples))
|
||||
iMultisamples = 1;
|
||||
|
||||
if (stereo_mode != StereoMode::Off)
|
||||
|
|
|
@ -81,3 +81,114 @@ TEST(StringUtil, GetEscapedHtml)
|
|||
EXPECT_EQ(Common::GetEscapedHtml("&<>'\""), "&<>'"");
|
||||
EXPECT_EQ(Common::GetEscapedHtml("&&&"), "&&&");
|
||||
}
|
||||
|
||||
TEST(StringUtil, SplitPath)
|
||||
{
|
||||
std::string path;
|
||||
std::string filename;
|
||||
std::string extension;
|
||||
EXPECT_TRUE(SplitPath("/usr/lib/some_file.txt", &path, &filename, &extension));
|
||||
EXPECT_EQ(path, "/usr/lib/");
|
||||
EXPECT_EQ(filename, "some_file");
|
||||
EXPECT_EQ(extension, ".txt");
|
||||
}
|
||||
|
||||
TEST(StringUtil, SplitPathNullOutputPathAllowed)
|
||||
{
|
||||
std::string filename;
|
||||
std::string extension;
|
||||
EXPECT_TRUE(SplitPath("/usr/lib/some_file.txt", /*path=*/nullptr, &filename, &extension));
|
||||
EXPECT_EQ(filename, "some_file");
|
||||
EXPECT_EQ(extension, ".txt");
|
||||
}
|
||||
|
||||
TEST(StringUtil, SplitPathNullOutputFilenameAllowed)
|
||||
{
|
||||
std::string path;
|
||||
std::string extension;
|
||||
EXPECT_TRUE(SplitPath("/usr/lib/some_file.txt", &path, /*filename=*/nullptr, &extension));
|
||||
EXPECT_EQ(path, "/usr/lib/");
|
||||
EXPECT_EQ(extension, ".txt");
|
||||
}
|
||||
|
||||
TEST(StringUtil, SplitPathNullOutputExtensionAllowed)
|
||||
{
|
||||
std::string path;
|
||||
std::string filename;
|
||||
EXPECT_TRUE(SplitPath("/usr/lib/some_file.txt", &path, &filename, /*extension=*/nullptr));
|
||||
EXPECT_EQ(path, "/usr/lib/");
|
||||
EXPECT_EQ(filename, "some_file");
|
||||
}
|
||||
|
||||
TEST(StringUtil, SplitPathReturnsFalseIfFullPathIsEmpty)
|
||||
{
|
||||
std::string path;
|
||||
std::string filename;
|
||||
std::string extension;
|
||||
EXPECT_FALSE(SplitPath(/*full_path=*/"", &path, &filename, &extension));
|
||||
EXPECT_EQ(path, "");
|
||||
EXPECT_EQ(filename, "");
|
||||
EXPECT_EQ(extension, "");
|
||||
}
|
||||
|
||||
TEST(StringUtil, SplitPathNoPath)
|
||||
{
|
||||
std::string path;
|
||||
std::string filename;
|
||||
std::string extension;
|
||||
EXPECT_TRUE(SplitPath("some_file.txt", &path, &filename, &extension));
|
||||
EXPECT_EQ(path, "");
|
||||
EXPECT_EQ(filename, "some_file");
|
||||
EXPECT_EQ(extension, ".txt");
|
||||
}
|
||||
|
||||
TEST(StringUtil, SplitPathNoFileName)
|
||||
{
|
||||
std::string path;
|
||||
std::string filename;
|
||||
std::string extension;
|
||||
EXPECT_TRUE(SplitPath("/usr/lib/.txt", &path, &filename, &extension));
|
||||
EXPECT_EQ(path, "/usr/lib/");
|
||||
EXPECT_EQ(filename, "");
|
||||
EXPECT_EQ(extension, ".txt");
|
||||
}
|
||||
|
||||
TEST(StringUtil, SplitPathNoExtension)
|
||||
{
|
||||
std::string path;
|
||||
std::string filename;
|
||||
std::string extension;
|
||||
EXPECT_TRUE(SplitPath("/usr/lib/some_file", &path, &filename, &extension));
|
||||
EXPECT_EQ(path, "/usr/lib/");
|
||||
EXPECT_EQ(filename, "some_file");
|
||||
EXPECT_EQ(extension, "");
|
||||
}
|
||||
|
||||
TEST(StringUtil, SplitPathDifferentPathLengths)
|
||||
{
|
||||
std::string path;
|
||||
std::string filename;
|
||||
std::string extension;
|
||||
EXPECT_TRUE(SplitPath("/usr/some_file.txt", &path, &filename, &extension));
|
||||
EXPECT_EQ(path, "/usr/");
|
||||
EXPECT_EQ(filename, "some_file");
|
||||
EXPECT_EQ(extension, ".txt");
|
||||
|
||||
EXPECT_TRUE(SplitPath("/usr/lib/foo/some_file.txt", &path, &filename, &extension));
|
||||
EXPECT_EQ(path, "/usr/lib/foo/");
|
||||
EXPECT_EQ(filename, "some_file");
|
||||
EXPECT_EQ(extension, ".txt");
|
||||
}
|
||||
|
||||
TEST(StringUtil, SplitPathBackslashesNotRecognizedAsSeparators)
|
||||
{
|
||||
std::string path;
|
||||
std::string filename;
|
||||
std::string extension;
|
||||
EXPECT_TRUE(SplitPath("\\usr\\some_file.txt", &path, &filename, &extension));
|
||||
EXPECT_EQ(path, "");
|
||||
EXPECT_EQ(filename, "\\usr\\some_file");
|
||||
EXPECT_EQ(extension, ".txt");
|
||||
}
|
||||
|
||||
// TODO: add `SplitPath` test coverage for paths containing Windows drives, e.g., "C:".
|
||||
|
|
Loading…
Add table
Reference in a new issue