Sync filesystem.h/path.h

This commit is contained in:
Connor McLaughlin 2022-07-08 21:57:06 +10:00
parent f89529015c
commit d2ca454576
50 changed files with 1395 additions and 1861 deletions

View File

@ -2,6 +2,7 @@ add_executable(common-tests
bitutils_tests.cpp
event_tests.cpp
file_system_tests.cpp
path_tests.cpp
rectangle_tests.cpp
)

View File

@ -6,6 +6,7 @@
<ClCompile Include="bitutils_tests.cpp" />
<ClCompile Include="event_tests.cpp" />
<ClCompile Include="file_system_tests.cpp" />
<ClCompile Include="path_tests.cpp" />
<ClCompile Include="rectangle_tests.cpp" />
</ItemGroup>
<ItemGroup>
@ -19,9 +20,7 @@
<PropertyGroup Label="Globals">
<ProjectGuid>{EA2B9C7A-B8CC-42F9-879B-191A98680C10}</ProjectGuid>
</PropertyGroup>
<Import Project="..\..\dep\msvc\vsprops\ConsoleApplication.props" />
<Import Project="..\common\common.props" />
<ItemDefinitionGroup>
<ClCompile>

View File

@ -6,5 +6,6 @@
<ClCompile Include="event_tests.cpp" />
<ClCompile Include="bitutils_tests.cpp" />
<ClCompile Include="file_system_tests.cpp" />
<ClCompile Include="path_tests.cpp" />
</ItemGroup>
</Project>

View File

@ -1,25 +1,3 @@
#include "common/file_system.h"
#include <gtest/gtest.h>
TEST(FileSystem, IsAbsolutePath)
{
#ifdef _WIN32
ASSERT_TRUE(FileSystem::IsAbsolutePath("C:\\"));
ASSERT_TRUE(FileSystem::IsAbsolutePath("C:\\Path"));
ASSERT_TRUE(FileSystem::IsAbsolutePath("C:\\Path\\Subdirectory"));
ASSERT_TRUE(FileSystem::IsAbsolutePath("C:/"));
ASSERT_TRUE(FileSystem::IsAbsolutePath("C:/Path"));
ASSERT_TRUE(FileSystem::IsAbsolutePath("C:/Path/Subdirectory"));
ASSERT_FALSE(FileSystem::IsAbsolutePath(""));
ASSERT_FALSE(FileSystem::IsAbsolutePath("C:"));
ASSERT_FALSE(FileSystem::IsAbsolutePath("Path"));
ASSERT_FALSE(FileSystem::IsAbsolutePath("Path/Subdirectory"));
#else
ASSERT_TRUE(FileSystem::IsAbsolutePath("/"));
ASSERT_TRUE(FileSystem::IsAbsolutePath("/path"));
ASSERT_TRUE(FileSystem::IsAbsolutePath("/path/subdirectory"));
ASSERT_FALSE(FileSystem::IsAbsolutePath(""));
ASSERT_FALSE(FileSystem::IsAbsolutePath("path"));
ASSERT_FALSE(FileSystem::IsAbsolutePath("path/subdirectory"));
#endif
}

View File

@ -0,0 +1,225 @@
#include "common/path.h"
#include "common/types.h"
#include <gtest/gtest.h>
TEST(FileSystem, ToNativePath)
{
ASSERT_EQ(Path::ToNativePath(""), "");
#ifdef _WIN32
ASSERT_EQ(Path::ToNativePath("foo"), "foo");
ASSERT_EQ(Path::ToNativePath("foo\\"), "foo");
ASSERT_EQ(Path::ToNativePath("foo\\\\bar"), "foo\\bar");
ASSERT_EQ(Path::ToNativePath("foo\\bar"), "foo\\bar");
ASSERT_EQ(Path::ToNativePath("foo\\bar\\baz"), "foo\\bar\\baz");
ASSERT_EQ(Path::ToNativePath("foo\\bar/baz"), "foo\\bar\\baz");
ASSERT_EQ(Path::ToNativePath("foo/bar/baz"), "foo\\bar\\baz");
ASSERT_EQ(Path::ToNativePath("foo/🙃bar/b🙃az"), "foo\\🙃bar\\b🙃az");
ASSERT_EQ(Path::ToNativePath("\\\\foo\\bar\\baz"), "\\\\foo\\bar\\baz");
#else
ASSERT_EQ(Path::ToNativePath("foo"), "foo");
ASSERT_EQ(Path::ToNativePath("foo/"), "foo");
ASSERT_EQ(Path::ToNativePath("foo//bar"), "foo/bar");
ASSERT_EQ(Path::ToNativePath("foo/bar"), "foo/bar");
ASSERT_EQ(Path::ToNativePath("foo/bar/baz"), "foo/bar/baz");
ASSERT_EQ(Path::ToNativePath("/foo/bar/baz"), "/foo/bar/baz");
#endif
}
TEST(FileSystem, IsAbsolute)
{
ASSERT_FALSE(Path::IsAbsolute(""));
ASSERT_FALSE(Path::IsAbsolute("foo"));
ASSERT_FALSE(Path::IsAbsolute("foo/bar"));
ASSERT_FALSE(Path::IsAbsolute("foo/b🙃ar"));
#ifdef _WIN32
ASSERT_TRUE(Path::IsAbsolute("C:\\foo/bar"));
ASSERT_TRUE(Path::IsAbsolute("C://foo\\bar"));
ASSERT_FALSE(Path::IsAbsolute("\\foo/bar"));
ASSERT_TRUE(Path::IsAbsolute("\\\\foo\\bar\\baz"));
ASSERT_TRUE(Path::IsAbsolute("C:\\"));
ASSERT_TRUE(Path::IsAbsolute("C:\\Path"));
ASSERT_TRUE(Path::IsAbsolute("C:\\Path\\Subdirectory"));
ASSERT_TRUE(Path::IsAbsolute("C:/"));
ASSERT_TRUE(Path::IsAbsolute("C:/Path"));
ASSERT_TRUE(Path::IsAbsolute("C:/Path/Subdirectory"));
ASSERT_FALSE(Path::IsAbsolute(""));
ASSERT_FALSE(Path::IsAbsolute("C:"));
ASSERT_FALSE(Path::IsAbsolute("Path"));
ASSERT_FALSE(Path::IsAbsolute("Path/Subdirectory"));
#else
ASSERT_TRUE(Path::IsAbsolute("/foo/bar"));
ASSERT_TRUE(Path::IsAbsolute("/"));
ASSERT_TRUE(Path::IsAbsolute("/path"));
ASSERT_TRUE(Path::IsAbsolute("/path/subdirectory"));
ASSERT_FALSE(Path::IsAbsolute(""));
ASSERT_FALSE(Path::IsAbsolute("path"));
ASSERT_FALSE(Path::IsAbsolute("path/subdirectory"));
#endif
}
TEST(FileSystem, Canonicalize)
{
ASSERT_EQ(Path::Canonicalize(""), Path::ToNativePath(""));
ASSERT_EQ(Path::Canonicalize("foo/bar/../baz"), Path::ToNativePath("foo/baz"));
ASSERT_EQ(Path::Canonicalize("foo/bar/./baz"), Path::ToNativePath("foo/bar/baz"));
ASSERT_EQ(Path::Canonicalize("foo/./bar/./baz"), Path::ToNativePath("foo/bar/baz"));
ASSERT_EQ(Path::Canonicalize("foo/bar/../baz/../foo"), Path::ToNativePath("foo/foo"));
ASSERT_EQ(Path::Canonicalize("foo/bar/../baz/./foo"), Path::ToNativePath("foo/baz/foo"));
ASSERT_EQ(Path::Canonicalize("./foo"), Path::ToNativePath("foo"));
ASSERT_EQ(Path::Canonicalize("../foo"), Path::ToNativePath("../foo"));
ASSERT_EQ(Path::Canonicalize("foo/b🙃ar/../b🙃az/./foo"), Path::ToNativePath("foo/b🙃az/foo"));
ASSERT_EQ(
Path::Canonicalize(
"ŻąłóРстуぬねのはen🍪⟑η∏☉ⴤ∩₲ ₱⟑♰⫳🐱/b🙃az/../foo"),
Path::ToNativePath("ŻąłóРстуぬねのはen🍪⟑η∏☉ⴤ∩₲ ₱⟑♰⫳🐱/foo"));
#ifdef _WIN32
ASSERT_EQ(Path::Canonicalize("C:\\foo\\bar\\..\\baz\\.\\foo"), "C:\\foo\\baz\\foo");
ASSERT_EQ(Path::Canonicalize("C:/foo\\bar\\..\\baz\\.\\foo"), "C:\\foo\\baz\\foo");
ASSERT_EQ(Path::Canonicalize("foo\\bar\\..\\baz\\.\\foo"), "foo\\baz\\foo");
ASSERT_EQ(Path::Canonicalize("foo\\bar/..\\baz/.\\foo"), "foo\\baz\\foo");
ASSERT_EQ(Path::Canonicalize("\\\\foo\\bar\\baz/..\\foo"), "\\\\foo\\bar\\foo");
#else
ASSERT_EQ(Path::Canonicalize("/foo/bar/../baz/./foo"), "/foo/baz/foo");
#endif
}
TEST(FileSystem, Combine)
{
ASSERT_EQ(Path::Combine("", ""), Path::ToNativePath(""));
ASSERT_EQ(Path::Combine("foo", "bar"), Path::ToNativePath("foo/bar"));
ASSERT_EQ(Path::Combine("foo/bar", "baz"), Path::ToNativePath("foo/bar/baz"));
ASSERT_EQ(Path::Combine("foo/bar", "../baz"), Path::ToNativePath("foo/bar/../baz"));
ASSERT_EQ(Path::Combine("foo/bar/", "/baz/"), Path::ToNativePath("foo/bar/baz"));
ASSERT_EQ(Path::Combine("foo//bar", "baz/"), Path::ToNativePath("foo/bar/baz"));
ASSERT_EQ(Path::Combine("foo//ba🙃r", "b🙃az/"), Path::ToNativePath("foo/ba🙃r/b🙃az"));
#ifdef _WIN32
ASSERT_EQ(Path::Combine("C:\\foo\\bar", "baz"), "C:\\foo\\bar\\baz");
ASSERT_EQ(Path::Combine("\\\\server\\foo\\bar", "baz"), "\\\\server\\foo\\bar\\baz");
ASSERT_EQ(Path::Combine("foo\\bar", "baz"), "foo\\bar\\baz");
ASSERT_EQ(Path::Combine("foo\\bar\\", "baz"), "foo\\bar\\baz");
ASSERT_EQ(Path::Combine("foo/bar\\", "\\baz"), "foo\\bar\\baz");
ASSERT_EQ(Path::Combine("\\\\foo\\bar", "baz"), "\\\\foo\\bar\\baz");
#else
ASSERT_EQ(Path::Combine("/foo/bar", "baz"), "/foo/bar/baz");
#endif
}
TEST(FileSystem, AppendDirectory)
{
ASSERT_EQ(Path::AppendDirectory("foo/bar", "baz"), Path::ToNativePath("foo/baz/bar"));
ASSERT_EQ(Path::AppendDirectory("", "baz"), Path::ToNativePath("baz"));
ASSERT_EQ(Path::AppendDirectory("", ""), Path::ToNativePath(""));
ASSERT_EQ(Path::AppendDirectory("foo/bar", "🙃"), Path::ToNativePath("foo/🙃/bar"));
#ifdef _WIN32
ASSERT_EQ(Path::AppendDirectory("foo\\bar", "baz"), "foo\\baz\\bar");
ASSERT_EQ(Path::AppendDirectory("\\\\foo\\bar", "baz"), "\\\\foo\\baz\\bar");
#else
ASSERT_EQ(Path::AppendDirectory("/foo/bar", "baz"), "/foo/baz/bar");
#endif
}
TEST(FileSystem, MakeRelative)
{
ASSERT_EQ(Path::MakeRelative("", ""), Path::ToNativePath(""));
ASSERT_EQ(Path::MakeRelative("foo", ""), Path::ToNativePath("foo"));
ASSERT_EQ(Path::MakeRelative("", "foo"), Path::ToNativePath(""));
ASSERT_EQ(Path::MakeRelative("foo", "bar"), Path::ToNativePath("foo"));
#ifdef _WIN32
#define A "C:\\"
#else
#define A "/"
#endif
ASSERT_EQ(Path::MakeRelative(A "foo", A "bar"), Path::ToNativePath("../foo"));
ASSERT_EQ(Path::MakeRelative(A "foo/bar", A "foo"), Path::ToNativePath("bar"));
ASSERT_EQ(Path::MakeRelative(A "foo/bar", A "foo/baz"), Path::ToNativePath("../bar"));
ASSERT_EQ(Path::MakeRelative(A "foo/b🙃ar", A "foo/b🙃az"), Path::ToNativePath("../b🙃ar"));
ASSERT_EQ(Path::MakeRelative(A "f🙃oo/b🙃ar", A "f🙃oo/b🙃az"), Path::ToNativePath("../b🙃ar"));
ASSERT_EQ(
Path::MakeRelative(A "ŻąłóРстуぬねのはen🍪⟑η∏☉ⴤ∩₲ ₱⟑♰⫳🐱/b🙃ar",
A "ŻąłóРстуぬねのはen🍪⟑η∏☉ⴤ∩₲ ₱⟑♰⫳🐱/b🙃az"),
Path::ToNativePath("../b🙃ar"));
#undef A
#ifdef _WIN32
ASSERT_EQ(Path::MakeRelative("\\\\foo\\bar\\baz\\foo", "\\\\foo\\bar\\baz"), "foo");
ASSERT_EQ(Path::MakeRelative("\\\\foo\\bar\\foo", "\\\\foo\\bar\\baz"), "..\\foo");
ASSERT_EQ(Path::MakeRelative("\\\\foo\\bar\\foo", "\\\\other\\bar\\foo"), "\\\\foo\\bar\\foo");
#endif
}
TEST(FileSystem, GetExtension)
{
ASSERT_EQ(Path::GetExtension("foo"), "");
ASSERT_EQ(Path::GetExtension("foo.txt"), "txt");
ASSERT_EQ(Path::GetExtension("foo.t🙃t"), "t🙃t");
ASSERT_EQ(Path::GetExtension("foo."), "");
ASSERT_EQ(Path::GetExtension("a/b/foo.txt"), "txt");
ASSERT_EQ(Path::GetExtension("a/b/foo"), "");
}
TEST(FileSystem, GetFileName)
{
ASSERT_EQ(Path::GetFileName(""), "");
ASSERT_EQ(Path::GetFileName("foo"), "foo");
ASSERT_EQ(Path::GetFileName("foo.txt"), "foo.txt");
ASSERT_EQ(Path::GetFileName("foo"), "foo");
ASSERT_EQ(Path::GetFileName("foo/bar/."), ".");
ASSERT_EQ(Path::GetFileName("foo/bar/baz"), "baz");
ASSERT_EQ(Path::GetFileName("foo/bar/baz.txt"), "baz.txt");
#ifdef _WIN32
ASSERT_EQ(Path::GetFileName("foo/bar\\baz"), "baz");
ASSERT_EQ(Path::GetFileName("foo\\bar\\baz.txt"), "baz.txt");
#endif
}
TEST(FileSystem, GetFileTitle)
{
ASSERT_EQ(Path::GetFileTitle(""), "");
ASSERT_EQ(Path::GetFileTitle("foo"), "foo");
ASSERT_EQ(Path::GetFileTitle("foo.txt"), "foo");
ASSERT_EQ(Path::GetFileTitle("foo/bar/."), "");
ASSERT_EQ(Path::GetFileTitle("foo/bar/baz"), "baz");
ASSERT_EQ(Path::GetFileTitle("foo/bar/baz.txt"), "baz");
#ifdef _WIN32
ASSERT_EQ(Path::GetFileTitle("foo/bar\\baz"), "baz");
ASSERT_EQ(Path::GetFileTitle("foo\\bar\\baz.txt"), "baz");
#endif
}
TEST(FileSystem, GetDirectory)
{
ASSERT_EQ(Path::GetDirectory(""), "");
ASSERT_EQ(Path::GetDirectory("foo"), "");
ASSERT_EQ(Path::GetDirectory("foo.txt"), "");
ASSERT_EQ(Path::GetDirectory("foo/bar/."), "foo/bar");
ASSERT_EQ(Path::GetDirectory("foo/bar/baz"), "foo/bar");
ASSERT_EQ(Path::GetDirectory("foo/bar/baz.txt"), "foo/bar");
#ifdef _WIN32
ASSERT_EQ(Path::GetDirectory("foo\\bar\\baz"), "foo\\bar");
ASSERT_EQ(Path::GetDirectory("foo\\bar/baz.txt"), "foo\\bar");
#endif
}
TEST(FileSystem, ChangeFileName)
{
ASSERT_EQ(Path::ChangeFileName("", ""), Path::ToNativePath(""));
ASSERT_EQ(Path::ChangeFileName("", "bar"), Path::ToNativePath("bar"));
ASSERT_EQ(Path::ChangeFileName("bar", ""), Path::ToNativePath(""));
ASSERT_EQ(Path::ChangeFileName("foo/bar", ""), Path::ToNativePath("foo"));
ASSERT_EQ(Path::ChangeFileName("foo/", "bar"), Path::ToNativePath("foo/bar"));
ASSERT_EQ(Path::ChangeFileName("foo/bar", "baz"), Path::ToNativePath("foo/baz"));
ASSERT_EQ(Path::ChangeFileName("foo//bar", "baz"), Path::ToNativePath("foo/baz"));
ASSERT_EQ(Path::ChangeFileName("foo//bar.txt", "baz.txt"), Path::ToNativePath("foo/baz.txt"));
ASSERT_EQ(Path::ChangeFileName("foo//ba🙃r.txt", "ba🙃z.txt"), Path::ToNativePath("foo/ba🙃z.txt"));
#ifdef _WIN32
ASSERT_EQ(Path::ChangeFileName("foo/bar", "baz"), "foo\\baz");
ASSERT_EQ(Path::ChangeFileName("foo//bar\\foo", "baz"), "foo\\bar\\baz");
ASSERT_EQ(Path::ChangeFileName("\\\\foo\\bar\\foo", "baz"), "\\\\foo\\bar\\baz");
#else
ASSERT_EQ(Path::ChangeFileName("/foo/bar", "baz"), "/foo/baz");
#endif
}

View File

@ -69,6 +69,7 @@ add_library(common
memory_arena.h
page_fault_handler.cpp
page_fault_handler.h
path.h
platform.h
pbp_types.h
progress_callback.cpp
@ -87,8 +88,6 @@ add_library(common
thirdparty/thread_pool.h
timer.cpp
timer.h
timestamp.cpp
timestamp.h
types.h
vulkan/builders.cpp
vulkan/builders.h

View File

@ -2,6 +2,7 @@
#include "assert.h"
#include "file_system.h"
#include "log.h"
#include "path.h"
#include "string_util.h"
#include <array>
Log_SetChannel(CDImage);
@ -293,7 +294,7 @@ std::string CDImage::GetMetadata(const std::string_view& type) const
if (type == "title")
{
const std::string display_name(FileSystem::GetDisplayNameFromPath(m_filename));
result = FileSystem::StripExtension(display_name);
result = Path::StripExtension(display_name);
}
return result;

View File

@ -303,7 +303,7 @@ bool CDImageCHD::HasNonStandardSubchannel() const
CDImage::PrecacheResult CDImageCHD::Precache(ProgressCallback* progress)
{
const std::string_view title(FileSystem::GetFileNameFromPath(m_filename));
const std::string_view title(FileSystem::GetDisplayNameFromPath(m_filename));
progress->SetFormattedStatusText("Precaching %.*s...", static_cast<int>(title.size()), title.data());
progress->SetProgressRange(100);

View File

@ -5,6 +5,7 @@
#include "error.h"
#include "file_system.h"
#include "log.h"
#include "path.h"
#include <algorithm>
#include <cerrno>
#include <cinttypes>
@ -88,15 +89,14 @@ bool CDImageCueSheet::OpenAndParse(const char* filename, Common::Error* error)
}
if (track_file_index == m_files.size())
{
const std::string track_full_filename(!FileSystem::IsAbsolutePath(track_filename) ?
FileSystem::BuildRelativePath(m_filename, track_filename) :
track_filename);
const std::string track_full_filename(
!Path::IsAbsolute(track_filename) ? Path::BuildRelativePath(m_filename, track_filename) : track_filename);
std::FILE* track_fp = FileSystem::OpenCFile(track_full_filename.c_str(), "rb");
if (!track_fp && track_file_index == 0)
{
// many users have bad cuesheets, or they're renamed the files without updating the cuesheet.
// so, try searching for a bin with the same name as the cue, but only for the first referenced file.
const std::string alternative_filename(FileSystem::ReplaceExtension(filename, "bin"));
const std::string alternative_filename(Path::ReplaceExtension(filename, "bin"));
track_fp = FileSystem::OpenCFile(alternative_filename.c_str(), "rb");
if (track_fp)
{

View File

@ -4,10 +4,11 @@
#include "error.h"
#include "file_system.h"
#include "log.h"
#include "path.h"
#include <algorithm>
#include <cerrno>
#include <sstream>
#include <map>
#include <sstream>
Log_SetChannel(CDImageMemory);
class CDImageM3u : public CDImage
@ -88,9 +89,9 @@ bool CDImageM3u::Open(const char* path, Common::Error* error)
Entry entry;
std::string entry_filename(line.begin() + start_offset, line.begin() + end_offset + 1);
entry.title = FileSystem::GetFileTitleFromPath(entry_filename);
if (!FileSystem::IsAbsolutePath(entry_filename))
entry.filename = FileSystem::BuildRelativePath(path, entry_filename);
entry.title = Path::GetFileTitle(entry_filename);
if (!Path::IsAbsolute(entry_filename))
entry.filename = Path::BuildRelativePath(path, entry_filename);
else
entry.filename = std::move(entry_filename);
@ -154,7 +155,7 @@ std::string CDImageM3u::GetSubImageMetadata(u32 index, const std::string_view& t
if (type == "title")
return m_entries[index].title;
else if (type == "file_title")
return std::string(FileSystem::GetFileTitleFromPath(m_entries[index].filename));
return std::string(Path::GetFileTitle(m_entries[index].filename));
return CDImage::GetSubImageMetadata(index, type);
}

View File

@ -4,6 +4,7 @@
#include "error.h"
#include "file_system.h"
#include "log.h"
#include "path.h"
#include <algorithm>
#include <cerrno>
#include <map>
@ -80,7 +81,7 @@ bool CDImageMds::OpenAndParse(const char* filename, Common::Error* error)
return false;
}
std::string mdf_filename(FileSystem::ReplaceExtension(filename, "mdf"));
std::string mdf_filename(Path::ReplaceExtension(filename, "mdf"));
m_mdf_file = FileSystem::OpenCFile(mdf_filename.c_str(), "rb");
if (!m_mdf_file)
{

View File

@ -3,6 +3,7 @@
#include "cd_subchannel_replacement.h"
#include "file_system.h"
#include "log.h"
#include "path.h"
#include <algorithm>
#include <cerrno>
Log_SetChannel(CDImageMemory);
@ -109,7 +110,7 @@ bool CDImageMemory::CopyImage(CDImage* image, ProgressCallback* progress)
m_filename = image->GetFileName();
m_lba_count = image->GetLBACount();
m_sbi.LoadSBI(FileSystem::ReplaceExtension(m_filename, "sbi").c_str());
m_sbi.LoadSBI(Path::ReplaceExtension(m_filename, "sbi").c_str());
return Seek(1, Position{0, 0, 0});
}

View File

@ -4,6 +4,7 @@
#include "error.h"
#include "file_system.h"
#include "log.h"
#include "path.h"
#include "pbp_types.h"
#include "string.h"
#include "string_util.h"
@ -674,12 +675,12 @@ bool CDImagePBP::OpenDisc(u32 index, Common::Error* error)
if (m_disc_offsets.size() > 1)
{
std::string sbi_path(FileSystem::StripExtension(m_filename));
std::string sbi_path(Path::StripExtension(m_filename));
sbi_path += TinyString::FromFormat("_%u.sbi", index + 1);
m_sbi.LoadSBI(sbi_path.c_str());
}
else
m_sbi.LoadSBI(FileSystem::ReplaceExtension(m_filename, "sbi").c_str());
m_sbi.LoadSBI(Path::ReplaceExtension(m_filename, "sbi").c_str());
m_current_disc = index;
return Seek(1, Position{0, 0, 0});

View File

@ -1,6 +1,7 @@
#include "cd_subchannel_replacement.h"
#include "file_system.h"
#include "log.h"
#include "path.h"
#include <algorithm>
#include <memory>
Log_SetChannel(CDSubChannelReplacement);
@ -85,7 +86,7 @@ bool CDSubChannelReplacement::LoadSBI(const char* path)
bool CDSubChannelReplacement::LoadSBIFromImagePath(const char* image_path)
{
return LoadSBI(FileSystem::ReplaceExtension(image_path, "sbi").c_str());
return LoadSBI(Path::ReplaceExtension(image_path, "sbi").c_str());
}
void CDSubChannelReplacement::AddReplacementSubChannelQ(u32 lba, const CDImage::SubChannelQ& subq)

View File

@ -34,6 +34,7 @@
<ClInclude Include="gl\context_wgl.h">
<ExcludedFromBuild Condition="'$(Platform)'=='ARM' Or '$(Platform)'=='ARM64' Or '$(BuildingForUWP)'=='true'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="gl\loader.h" />
<ClInclude Include="gl\program.h" />
<ClInclude Include="gl\shader_cache.h" />
<ClInclude Include="gl\stream_buffer.h" />
@ -55,6 +56,7 @@
<ClInclude Include="make_array.h" />
<ClInclude Include="md5_digest.h" />
<ClInclude Include="null_audio_stream.h" />
<ClInclude Include="path.h" />
<ClInclude Include="pbp_types.h" />
<ClInclude Include="platform.h" />
<ClInclude Include="progress_callback.h" />
@ -71,7 +73,6 @@
<ExcludedFromBuild Condition="'$(BuildingForUWP)'=='true'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="timer.h" />
<ClInclude Include="timestamp.h" />
<ClInclude Include="types.h" />
<ClInclude Include="cd_xa.h" />
<ClInclude Include="minizip_helpers.h" />
@ -91,6 +92,7 @@
<ClInclude Include="win32_progress_callback.h">
<ExcludedFromBuild Condition="'$(BuildingForUWP)'=='true'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="windows_headers.h" />
<ClInclude Include="window_info.h" />
</ItemGroup>
<ItemGroup>
@ -161,7 +163,6 @@
<ExcludedFromBuild Condition="'$(BuildingForUWP)'=='true'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="timer.cpp" />
<ClCompile Include="timestamp.cpp" />
<ClCompile Include="vulkan\builders.cpp" />
<ClCompile Include="vulkan\context.cpp" />
<ClCompile Include="vulkan\loader.cpp" />

View File

@ -39,7 +39,6 @@
<ClInclude Include="string.h" />
<ClInclude Include="byte_stream.h" />
<ClInclude Include="timer.h" />
<ClInclude Include="timestamp.h" />
<ClInclude Include="assert.h" />
<ClInclude Include="align.h" />
<ClInclude Include="file_system.h" />
@ -143,6 +142,11 @@
<ClInclude Include="vulkan\loader.h">
<Filter>vulkan</Filter>
</ClInclude>
<ClInclude Include="path.h" />
<ClInclude Include="windows_headers.h" />
<ClInclude Include="gl\loader.h">
<Filter>gl</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="jit_code_buffer.cpp" />
@ -179,7 +183,6 @@
<ClCompile Include="string.cpp" />
<ClCompile Include="byte_stream.cpp" />
<ClCompile Include="log.cpp" />
<ClCompile Include="timestamp.cpp" />
<ClCompile Include="timer.cpp" />
<ClCompile Include="assert.cpp" />
<ClCompile Include="file_system.cpp" />

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,12 @@
#pragma once
#include "timestamp.h"
#include "types.h"
#include <cstdio>
#include <ctime>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include <sys/stat.h>
#include <vector>
#ifdef _WIN32
#define FS_OSPATH_SEPARATOR_CHARACTER '\\'
@ -36,177 +35,104 @@ enum FILESYSTEM_FIND_FLAGS
struct FILESYSTEM_STAT_DATA
{
std::time_t CreationTime; // actually inode change time on linux
std::time_t ModificationTime;
s64 Size;
u32 Attributes;
Timestamp ModificationTime;
u64 Size;
};
struct FILESYSTEM_FIND_DATA
{
std::time_t CreationTime; // actually inode change time on linux
std::time_t ModificationTime;
std::string FileName;
Timestamp ModificationTime;
s64 Size;
u32 Attributes;
u64 Size;
};
struct FILESYSTEM_CHANGE_NOTIFY_DATA
{
String DirectoryPath;
bool RecursiveWatch;
void* pSystemData;
};
namespace FileSystem {
using FindResultsArray = std::vector<FILESYSTEM_FIND_DATA>;
#ifdef __ANDROID__
/// Sets the instance for the FileHelpers Java class, used for storage access framework
/// file access on Android.
void SetAndroidFileHelper(void* jvm, void* env, void* object);
#endif
class ChangeNotifier
{
public:
enum ChangeEvent
{
ChangeEvent_FileAdded = (1 << 0),
ChangeEvent_FileRemoved = (1 << 1),
ChangeEvent_FileModified = (1 << 2),
ChangeEvent_RenamedOldName = (1 << 3),
ChangeEvent_RenamedNewName = (1 << 4),
};
struct ChangeInfo
{
const char* Path;
u32 Event;
};
public:
virtual ~ChangeNotifier();
const String& GetDirectoryPath() const { return m_directoryPath; }
const bool GetRecursiveWatch() const { return m_recursiveWatch; }
typedef void (*EnumerateChangesCallback)(const ChangeInfo* pChangeInfo, void* pUserData);
virtual void EnumerateChanges(EnumerateChangesCallback callback, void* pUserData) = 0;
private:
template<typename CALLBACK_TYPE>
static void EnumerateChangesTrampoline(const ChangeInfo* pChangeInfo, void* pUserData)
{
CALLBACK_TYPE* pRealCallback = reinterpret_cast<CALLBACK_TYPE*>(pUserData);
(*pRealCallback)(pChangeInfo);
}
public:
template<typename CALLBACK_TYPE>
void EnumerateChanges(CALLBACK_TYPE callback)
{
CALLBACK_TYPE* pCallback = &callback;
EnumerateChanges(&ChangeNotifier::EnumerateChangesTrampoline<CALLBACK_TYPE>, reinterpret_cast<void*>(pCallback));
}
protected:
ChangeNotifier(const String& directoryPath, bool recursiveWatch);
String m_directoryPath;
bool m_recursiveWatch;
};
// create a change notifier
std::unique_ptr<ChangeNotifier> CreateChangeNotifier(const char* path, bool recursiveWatch);
// canonicalize a path string (i.e. replace .. with actual folder name, etc), if OS path is used, on windows, the
// separators will be \, otherwise /
void CanonicalizePath(char* Destination, u32 cbDestination, const char* Path, bool OSPath = true);
void CanonicalizePath(String& Destination, const char* Path, bool OSPath = true);
void CanonicalizePath(String& Destination, bool OSPath = true);
void CanonicalizePath(std::string& path, bool OSPath = true);
// translates the specified path into a string compatible with the hosting OS
void BuildOSPath(char* Destination, u32 cbDestination, const char* Path);
void BuildOSPath(String& Destination, const char* Path);
void BuildOSPath(String& Destination);
// builds a path relative to the specified file
std::string BuildRelativePath(const std::string_view& filename, const std::string_view& new_filename);
// sanitizes a filename for use in a filesystem.
void SanitizeFileName(char* Destination, u32 cbDestination, const char* FileName, bool StripSlashes = true);
void SanitizeFileName(String& Destination, const char* FileName, bool StripSlashes = true);
void SanitizeFileName(String& Destination, bool StripSlashes = true);
void SanitizeFileName(std::string& Destination, bool StripSlashes = true);
/// Returns true if the specified path is an absolute path (C:\Path on Windows or /path on Unix).
bool IsAbsolutePath(const std::string_view& path);
/// Removes the extension of a filename.
std::string_view StripExtension(const std::string_view& path);
/// Replaces the extension of a filename with another.
std::string ReplaceExtension(const std::string_view& path, const std::string_view& new_extension);
/// Returns the display name of a filename. Usually this is the same as the path, except on Android
/// where it resolves a content URI to its name.
/// Returns the display name of a filename. Usually this is the same as the path.
std::string GetDisplayNameFromPath(const std::string_view& path);
/// Returns the directory component of a filename.
std::string_view GetPathDirectory(const std::string_view& path);
/// Returns the filename component of a filename.
std::string_view GetFileNameFromPath(const std::string_view& path);
/// Returns the file title (less the extension and path) from a filename.
std::string_view GetFileTitleFromPath(const std::string_view& path);
/// Returns a list of "root directories" (i.e. root/home directories on Linux, drive letters on Windows).
std::vector<std::string> GetRootDirectoryList();
// search for files
bool FindFiles(const char* Path, const char* Pattern, u32 Flags, FindResultsArray* pResults);
/// Search for files
bool FindFiles(const char* path, const char* pattern, u32 flags, FindResultsArray* results);
// stat file
bool StatFile(const char* Path, FILESYSTEM_STAT_DATA* pStatData);
/// Stat file
bool StatFile(const char* path, struct stat* st);
bool StatFile(std::FILE* fp, struct stat* st);
bool StatFile(const char* path, FILESYSTEM_STAT_DATA* pStatData);
bool StatFile(std::FILE* fp, FILESYSTEM_STAT_DATA* pStatData);
s64 GetPathFileSize(const char* path);
// file exists?
bool FileExists(const char* Path);
/// File exists?
bool FileExists(const char* path);
// directory exists?
bool DirectoryExists(const char* Path);
/// Directory exists?
bool DirectoryExists(const char* path);
// delete file
bool DeleteFile(const char* Path);
/// Directory does not contain any files?
bool DirectoryIsEmpty(const char* path);
// rename file
/// Delete file
bool DeleteFile(const char* path);
/// Rename file
bool RenamePath(const char* OldPath, const char* NewPath);
/// open files
using ManagedCFilePtr = std::unique_ptr<std::FILE, void (*)(std::FILE*)>;
ManagedCFilePtr OpenManagedCFile(const char* filename, const char* mode);
std::FILE* OpenCFile(const char* filename, const char* mode);
int FSeek64(std::FILE* fp, s64 offset, int whence);
s64 FTell64(std::FILE* fp);
s64 FSize64(std::FILE* fp);
int OpenFDFile(const char* filename, int flags, int mode);
/// Sharing modes for OpenSharedCFile().
enum class FileShareMode
{
DenyReadWrite, /// Exclusive access.
DenyWrite, /// Other processes can read from this file.
DenyRead, /// Other processes can write to this file.
DenyNone, /// Other processes can read and write to this file.
};
/// Opens a file in shareable mode (where other processes can access it concurrently).
/// Only has an effect on Windows systems.
ManagedCFilePtr OpenManagedSharedCFile(const char* filename, const char* mode, FileShareMode share_mode);
std::FILE* OpenSharedCFile(const char* filename, const char* mode, FileShareMode share_mode);
std::optional<std::vector<u8>> ReadBinaryFile(const char* filename);
std::optional<std::vector<u8>> ReadBinaryFile(std::FILE* fp);
std::optional<std::string> ReadFileToString(const char* filename);
std::optional<std::string> ReadFileToString(std::FILE* fp);
bool WriteBinaryFile(const char* filename, const void* data, size_t data_length);
bool WriteFileToString(const char* filename, const std::string_view& sv);
bool WriteStringToFile(const char* filename, const std::string_view& sv);
// creates a directory in the local filesystem
// if the directory already exists, the return value will be true.
// if Recursive is specified, all parent directories will be created
// if they do not exist.
bool CreateDirectory(const char* Path, bool Recursive);
/// creates a directory in the local filesystem
/// if the directory already exists, the return value will be true.
/// if Recursive is specified, all parent directories will be created
/// if they do not exist.
bool CreateDirectory(const char* path, bool recursive);
// deletes a directory in the local filesystem
// if the directory has files, unless the recursive flag is set, it will fail
bool DeleteDirectory(const char* Path, bool Recursive);
/// Creates a directory if it doesn't already exist.
/// Returns false if it does not exist and creation failed.
bool EnsureDirectoryExists(const char* path, bool recursive);
/// Removes a directory.
bool DeleteDirectory(const char* path);
/// Recursively removes a directory and all subdirectories/files.
bool RecursiveDeleteDirectory(const char* path);
/// Copies one file to another, optionally replacing it if it already exists.
bool CopyFilePath(const char* source, const char* destination, bool replace);
/// Returns the path to the current executable.
std::string GetProgramPath();
@ -217,4 +143,9 @@ std::string GetWorkingDirectory();
/// Sets the current working directory. Returns true if successful.
bool SetWorkingDirectory(const char* path);
/// Enables/disables NTFS compression on a file or directory.
/// Does not apply the compression flag recursively if called for a directory.
/// Does nothing and returns false on non-Windows platforms.
bool SetPathCompression(const char* path, bool enable);
}; // namespace FileSystem

View File

@ -1,6 +1,6 @@
#include "context.h"
#include "../log.h"
#include "glad.h"
#include "loader.h"
#include <cstdlib>
#ifdef __APPLE__
#include <stdlib.h>

View File

@ -1,6 +1,6 @@
#pragma once
#include "context.h"
#include <glad.h>
#include "loader.h"
#if defined(__APPLE__) && defined(__OBJC__)
#import <AppKit/AppKit.h>

View File

@ -1,7 +1,7 @@
#include "context_agl.h"
#include "../assert.h"
#include "../log.h"
#include "glad.h"
#include "loader.h"
#include <dlfcn.h>
Log_SetChannel(GL::ContextAGL);

View File

@ -1,11 +1,11 @@
#include "context_wgl.h"
#include "../assert.h"
#include "../log.h"
#include "glad.h"
#include "glad_wgl.h"
#include "loader.h"
Log_SetChannel(GL::ContextWGL);
// TODO: get rid of this
#include "glad_wgl.h"
#pragma comment(lib, "opengl32.lib")
static void* GetProcAddressCallback(const char* name)

View File

@ -1,7 +1,7 @@
#pragma once
#include "../windows_headers.h"
#include "context.h"
#include <glad.h>
#include "loader.h"
namespace GL {

8
src/common/gl/loader.h Normal file
View File

@ -0,0 +1,8 @@
#pragma once
// Fix glad.h including windows.h
#ifdef _WIN32
#include "../windows_headers.h"
#endif
#include "glad.h"

View File

@ -1,6 +1,6 @@
#pragma once
#include "../types.h"
#include "glad.h"
#include "loader.h"
#include <string_view>
#include <vector>

View File

@ -1,6 +1,6 @@
#pragma once
#include "../types.h"
#include <glad.h>
#include "loader.h"
#include <memory>
#include <tuple>
#include <vector>

View File

@ -1,6 +1,6 @@
#pragma once
#include "../types.h"
#include <glad.h>
#include "loader.h"
namespace GL {
class Texture

68
src/common/path.h Normal file
View File

@ -0,0 +1,68 @@
#pragma once
#include "types.h"
#include <string>
#include <string_view>
#include <vector>
namespace Path {
/// Converts any forward slashes to backslashes on Win32.
std::string ToNativePath(const std::string_view& path);
void ToNativePath(std::string* path);
/// Builds a path relative to the specified file
std::string BuildRelativePath(const std::string_view& filename, const std::string_view& new_filename);
/// Joins path components together, producing a new path.
std::string Combine(const std::string_view& base, const std::string_view& next);
/// Removes all .. and . components from a path.
std::string Canonicalize(const std::string_view& path);
void Canonicalize(std::string* path);
/// Sanitizes a filename for use in a filesystem.
void SanitizeFileName(char* Destination, u32 cbDestination, const char* FileName, bool StripSlashes /* = true */);
void SanitizeFileName(std::string& Destination, bool StripSlashes = true);
/// Returns true if the specified path is an absolute path (C:\Path on Windows or /path on Unix).
bool IsAbsolute(const std::string_view& path);
/// Makes the specified path relative to another (e.g. /a/b/c, /a/b -> ../c).
/// Both paths must be relative, otherwise this function will just return the input path.
std::string MakeRelative(const std::string_view& path, const std::string_view& relative_to);
/// Returns a view of the extension of a filename.
std::string_view GetExtension(const std::string_view& path);
/// Removes the extension of a filename.
std::string_view StripExtension(const std::string_view& path);
/// Replaces the extension of a filename with another.
std::string ReplaceExtension(const std::string_view& path, const std::string_view& new_extension);
/// Returns the directory component of a filename.
std::string_view GetDirectory(const std::string_view& path);
/// Returns the filename component of a filename.
std::string_view GetFileName(const std::string_view& path);
/// Returns the file title (less the extension and path) from a filename.
std::string_view GetFileTitle(const std::string_view& path);
/// Changes the filename in a path.
std::string ChangeFileName(const std::string_view& path, const std::string_view& new_filename);
void ChangeFileName(std::string* path, const std::string_view& new_filename);
/// Appends a directory to a path.
std::string AppendDirectory(const std::string_view& path, const std::string_view& new_dir);
void AppendDirectory(std::string* path, const std::string_view& new_dir);
/// Splits a path into its components, handling both Windows and Unix separators.
std::vector<std::string_view> SplitWindowsPath(const std::string_view& path);
std::string JoinWindowsPath(const std::vector<std::string_view>& components);
/// Splits a path into its components, only handling native separators.
std::vector<std::string_view> SplitNativePath(const std::string_view& path);
std::string JoinNativePath(const std::vector<std::string_view>& components);
} // namespace Path

View File

@ -1,331 +0,0 @@
#include "timestamp.h"
#include <cstring>
#include <ctime>
#include <tuple>
#if defined(_WIN32)
static void UnixTimeToSystemTime(time_t t, LPSYSTEMTIME pst);
static time_t SystemTimeToUnixTime(const SYSTEMTIME* pst);
#endif
Timestamp::Timestamp()
{
#if defined(_WIN32)
m_value.wYear = 1970;
m_value.wMonth = 1;
m_value.wDayOfWeek = 0;
m_value.wDay = 1;
m_value.wHour = 0;
m_value.wMinute = 0;
m_value.wSecond = 0;
m_value.wMilliseconds = 0;
#else
m_value.tv_sec = 0;
m_value.tv_usec = 0;
#endif
}
Timestamp::Timestamp(const Timestamp& copy)
{
#if defined(_WIN32)
std::memcpy(&m_value, &copy.m_value, sizeof(m_value));
#else
std::memcpy(&m_value, &copy.m_value, sizeof(m_value));
#endif
}
double Timestamp::DifferenceInSeconds(Timestamp& other) const
{
#if defined(_WIN32)
FILETIME lft, rft;
SystemTimeToFileTime(&m_value, &lft);
SystemTimeToFileTime(&other.m_value, &rft);
u64 lval = ((u64)lft.dwHighDateTime) << 32 | (u64)lft.dwLowDateTime;
u64 rval = ((u64)rft.dwHighDateTime) << 32 | (u64)rft.dwLowDateTime;
s64 diff = ((s64)lval - (s64)rval);
return double(diff / 10000000ULL) + (double(diff % 10000000ULL) / 10000000.0);
#else
return (double)(m_value.tv_sec - other.m_value.tv_sec) +
(((double)(m_value.tv_usec - other.m_value.tv_usec)) / 1000000.0);
#endif
}
s64 Timestamp::DifferenceInSecondsInt(Timestamp& other) const
{
#if defined(_WIN32)
FILETIME lft, rft;
SystemTimeToFileTime(&m_value, &lft);
SystemTimeToFileTime(&other.m_value, &rft);
u64 lval = ((u64)lft.dwHighDateTime) << 32 | (u64)lft.dwLowDateTime;
u64 rval = ((u64)rft.dwHighDateTime) << 32 | (u64)rft.dwLowDateTime;
s64 diff = ((s64)lval - (s64)rval);
return diff / 10000000ULL;
#else
return static_cast<s64>(m_value.tv_sec - other.m_value.tv_sec);
#endif
}
Timestamp::UnixTimestampValue Timestamp::AsUnixTimestamp() const
{
#if defined(_WIN32)
return (UnixTimestampValue)SystemTimeToUnixTime(&m_value);
#else
return (UnixTimestampValue)m_value.tv_sec;
#endif
}
Timestamp::ExpandedTime Timestamp::AsExpandedTime() const
{
ExpandedTime et;
#if defined(_WIN32)
et.Year = m_value.wYear;
et.Month = m_value.wMonth;
et.DayOfMonth = m_value.wDay;
et.DayOfWeek = m_value.wDayOfWeek;
et.Hour = m_value.wHour;
et.Minute = m_value.wMinute;
et.Second = m_value.wSecond;
et.Milliseconds = m_value.wMilliseconds;
#else
struct tm t;
time_t unixTime = (time_t)m_value.tv_sec;
gmtime_r(&unixTime, &t);
et.Year = t.tm_year + 1900;
et.Month = t.tm_mon + 1;
et.DayOfMonth = t.tm_mday;
et.DayOfWeek = t.tm_wday;
et.Hour = t.tm_hour;
et.Minute = t.tm_min;
et.Second = t.tm_sec;
et.Milliseconds = m_value.tv_usec / 1000;
#endif
return et;
}
void Timestamp::SetNow()
{
#if defined(_WIN32)
GetSystemTime(&m_value);
#else
gettimeofday(&m_value, NULL);
#endif
}
void Timestamp::SetUnixTimestamp(UnixTimestampValue value)
{
#if defined(_WIN32)
UnixTimeToSystemTime((time_t)value, &m_value);
#else
m_value.tv_sec = (time_t)value;
m_value.tv_usec = 0;
#endif
}
void Timestamp::SetExpandedTime(const ExpandedTime& value)
{
#if defined(_WIN32)
// bit of a hacky way to fill in the missing fields
SYSTEMTIME st;
st.wYear = (WORD)value.Year;
st.wMonth = (WORD)value.Month;
st.wDay = (WORD)value.DayOfMonth;
st.wDayOfWeek = (WORD)0;
st.wHour = (WORD)value.Hour;
st.wMinute = (WORD)value.Minute;
st.wSecond = (WORD)value.Second;
st.wMilliseconds = (WORD)value.Milliseconds;
FILETIME ft;
SystemTimeToFileTime(&st, &ft);
FileTimeToSystemTime(&ft, &m_value);
#else
struct tm t;
std::memset(&t, 0, sizeof(t));
t.tm_sec = value.Second;
t.tm_min = value.Minute;
t.tm_hour = value.Hour;
t.tm_mday = value.DayOfMonth;
t.tm_mon = value.Month - 1;
t.tm_year = value.Year - 1900;
time_t unixTime = mktime(&t);
SetUnixTimestamp((UnixTimestampValue)unixTime);
#endif
}
String Timestamp::ToString(const char* format) const
{
SmallString destination;
ToString(destination, format);
return String(destination);
}
void Timestamp::ToString(String& destination, const char* format) const
{
time_t unixTime = (time_t)AsUnixTimestamp();
tm localTime;
#if defined(_WIN32)
localtime_s(&localTime, &unixTime);
#else
localtime_r(&unixTime, &localTime);
#endif
char buffer[256];
strftime(buffer, countof(buffer) - 1, format, &localTime);
buffer[countof(buffer) - 1] = 0;
destination.Clear();
destination.AppendString(buffer);
}
Timestamp Timestamp::Now()
{
Timestamp t;
t.SetNow();
return t;
}
Timestamp Timestamp::FromUnixTimestamp(UnixTimestampValue value)
{
Timestamp t;
t.SetUnixTimestamp(value);
return t;
}
Timestamp Timestamp::FromExpandedTime(const ExpandedTime& value)
{
Timestamp t;
t.SetExpandedTime(value);
return t;
}
bool Timestamp::operator==(const Timestamp& other) const
{
#if defined(_WIN32)
return std::memcmp(&m_value, &other.m_value, sizeof(m_value)) == 0;
#else
return std::memcmp(&m_value, &other.m_value, sizeof(m_value)) == 0;
#endif
}
bool Timestamp::operator!=(const Timestamp& other) const
{
return !operator==(other);
}
bool Timestamp::operator<(const Timestamp& other) const
{
#if defined(_WIN32)
return std::tie(m_value.wYear, m_value.wMonth, m_value.wDay, m_value.wHour, m_value.wMinute, m_value.wSecond,
m_value.wMilliseconds) < std::tie(other.m_value.wYear, other.m_value.wMonth, other.m_value.wDay,
other.m_value.wHour, other.m_value.wMinute, other.m_value.wSecond,
other.m_value.wMilliseconds);
#else
return std::tie(m_value.tv_sec, m_value.tv_usec) < std::tie(other.m_value.tv_sec, other.m_value.tv_usec);
#endif
}
bool Timestamp::operator<=(const Timestamp& other) const
{
#if defined(_WIN32)
return std::tie(m_value.wYear, m_value.wMonth, m_value.wDay, m_value.wHour, m_value.wMinute, m_value.wSecond,
m_value.wMilliseconds) <= std::tie(other.m_value.wYear, other.m_value.wMonth, other.m_value.wDay,
other.m_value.wHour, other.m_value.wMinute, other.m_value.wSecond,
other.m_value.wMilliseconds);
#else
return std::tie(m_value.tv_sec, m_value.tv_usec) <= std::tie(other.m_value.tv_sec, other.m_value.tv_usec);
#endif
}
bool Timestamp::operator>(const Timestamp& other) const
{
#if defined(_WIN32)
return std::tie(m_value.wYear, m_value.wMonth, m_value.wDay, m_value.wHour, m_value.wMinute, m_value.wSecond,
m_value.wMilliseconds) > std::tie(other.m_value.wYear, other.m_value.wMonth, other.m_value.wDay,
other.m_value.wHour, other.m_value.wMinute, other.m_value.wSecond,
other.m_value.wMilliseconds);
#else
return std::tie(m_value.tv_sec, m_value.tv_usec) > std::tie(other.m_value.tv_sec, other.m_value.tv_usec);
#endif
}
bool Timestamp::operator>=(const Timestamp& other) const
{
#if defined(_WIN32)
return std::tie(m_value.wYear, m_value.wMonth, m_value.wDay, m_value.wHour, m_value.wMinute, m_value.wSecond,
m_value.wMilliseconds) >= std::tie(other.m_value.wYear, other.m_value.wMonth, other.m_value.wDay,
other.m_value.wHour, other.m_value.wMinute, other.m_value.wSecond,
other.m_value.wMilliseconds);
#else
return std::tie(m_value.tv_sec, m_value.tv_usec) >= std::tie(other.m_value.tv_sec, other.m_value.tv_usec);
#endif
}
Timestamp& Timestamp::operator=(const Timestamp& other)
{
#if defined(_WIN32)
std::memcpy(&m_value, &other.m_value, sizeof(m_value));
#else
std::memcpy(&m_value, &other.m_value, sizeof(m_value));
#endif
return *this;
}
#if defined(_WIN32)
// https://docs.microsoft.com/en-us/windows/win32/sysinfo/converting-a-time-t-value-to-a-file-time
static void UnixTimeToFileTime(time_t t, LPFILETIME pft)
{
ULARGE_INTEGER time_value;
time_value.QuadPart = (t * 10000000LL) + 116444736000000000LL;
pft->dwLowDateTime = time_value.LowPart;
pft->dwHighDateTime = time_value.HighPart;
}
static void UnixTimeToSystemTime(time_t t, LPSYSTEMTIME pst)
{
FILETIME ft;
UnixTimeToFileTime(t, &ft);
FileTimeToSystemTime(&ft, pst);
}
static time_t FileTimeToUnixTime(const FILETIME* pft)
{
LONGLONG ll = ((LONGLONG)pft->dwHighDateTime) << 32 | (LONGLONG)pft->dwLowDateTime;
ll -= 116444736000000000ULL;
ll /= 10000000ULL;
return (time_t)ll;
}
static time_t SystemTimeToUnixTime(const SYSTEMTIME* pst)
{
FILETIME ft;
SystemTimeToFileTime(pst, &ft);
return FileTimeToUnixTime(&ft);
}
FILETIME Timestamp::AsFileTime()
{
FILETIME ft;
SystemTimeToFileTime(&m_value, &ft);
return ft;
}
void Timestamp::SetWindowsFileTime(const FILETIME* pFileTime)
{
FileTimeToSystemTime(pFileTime, &m_value);
}
Timestamp Timestamp::FromWindowsFileTime(const FILETIME* pFileTime)
{
Timestamp ts;
ts.SetWindowsFileTime(pFileTime);
return ts;
}
#endif

View File

@ -1,75 +0,0 @@
#pragma once
#include "types.h"
#include "string.h"
#if defined(_WIN32)
#include "windows_headers.h"
#else
#include <sys/time.h>
#endif
class Timestamp
{
public:
using UnixTimestampValue = u64;
struct ExpandedTime
{
u32 Year; // 0-...
u32 Month; // 1-12
u32 DayOfMonth; // 1-31
u32 DayOfWeek; // 0-6, starting at Sunday
u32 Hour; // 0-23
u32 Minute; // 0-59
u32 Second; // 0-59
u32 Milliseconds; // 0-999
};
public:
Timestamp();
Timestamp(const Timestamp& copy);
// readers
UnixTimestampValue AsUnixTimestamp() const;
ExpandedTime AsExpandedTime() const;
// calculators
double DifferenceInSeconds(Timestamp& other) const;
s64 DifferenceInSecondsInt(Timestamp& other) const;
// setters
void SetNow();
void SetUnixTimestamp(UnixTimestampValue value);
void SetExpandedTime(const ExpandedTime& value);
// string conversion
String ToString(const char* format) const;
void ToString(String& destination, const char* format) const;
// creators
static Timestamp Now();
static Timestamp FromUnixTimestamp(UnixTimestampValue value);
static Timestamp FromExpandedTime(const ExpandedTime& value);
// windows-specific
#ifdef _WIN32
FILETIME AsFileTime();
void SetWindowsFileTime(const FILETIME* pFileTime);
static Timestamp FromWindowsFileTime(const FILETIME* pFileTime);
#endif
// operators
bool operator==(const Timestamp& other) const;
bool operator!=(const Timestamp& other) const;
bool operator<(const Timestamp& other) const;
bool operator<=(const Timestamp& other) const;
bool operator>(const Timestamp& other) const;
bool operator>=(const Timestamp& other) const;
Timestamp& operator=(const Timestamp& other);
private:
#if defined(_WIN32)
SYSTEMTIME m_value;
#else
struct timeval m_value;
#endif
};

View File

@ -356,7 +356,7 @@ bool ShaderCache::FlushPipelineCache()
// Save disk writes if it hasn't changed, think of the poor SSDs.
FILESYSTEM_STAT_DATA sd;
if (!FileSystem::StatFile(m_pipeline_cache_filename.c_str(), &sd) || sd.Size != static_cast<u64>(data_size))
if (!FileSystem::StatFile(m_pipeline_cache_filename.c_str(), &sd) || sd.Size != static_cast<s64>(data_size))
{
Log_InfoPrintf("Writing %zu bytes to '%s'", data_size, m_pipeline_cache_filename.c_str());
if (!FileSystem::WriteBinaryFile(m_pipeline_cache_filename.c_str(), data.data(), data.size()))

View File

@ -5,10 +5,10 @@
#include "common/http_downloader.h"
#include "common/log.h"
#include "common/md5_digest.h"
#include "common/path.h"
#include "common/platform.h"
#include "common/state_wrapper.h"
#include "common/string_util.h"
#include "common/timestamp.h"
#include "core/bios.h"
#include "core/bus.h"
#include "core/cpu_core.h"
@ -30,6 +30,10 @@
Log_SetChannel(Cheevos);
#ifdef WITH_RAINTEGRATION
// RA_Interface ends up including windows.h, with its silly macros.
#ifdef _WIN32
#include "common/windows_headers.h"
#endif
#include "RA_Interface.h"
#endif
@ -711,16 +715,16 @@ std::string Cheevos::GetBadgeImageFilename(const char* badge_name, bool locked,
{
if (!cache_path)
{
return StringUtil::StdStringFromFormat("%s%s.png", badge_name, locked ? "_lock" : "");
return fmt::format("%s%s.png", badge_name, locked ? "_lock" : "");
}
else
{
// well, this comes from the internet.... :)
SmallString clean_name(badge_name);
FileSystem::SanitizeFileName(clean_name);
std::string clean_name(badge_name);
Path::SanitizeFileName(clean_name);
return g_host_interface->GetUserDirectoryRelativePath("cache" FS_OSPATH_SEPARATOR_STR
"achievement_badge" FS_OSPATH_SEPARATOR_STR "%s%s.png",
clean_name.GetCharArray(), locked ? "_lock" : "");
clean_name.c_str(), locked ? "_lock" : "");
}
}

View File

@ -1,9 +1,9 @@
#pragma once
#include "common/gl/loader.h"
#include "common/gl/program.h"
#include "common/gl/shader_cache.h"
#include "common/gl/stream_buffer.h"
#include "common/gl/texture.h"
#include "glad.h"
#include "gpu_hw.h"
#include "texture_replacements.h"
#include <array>

View File

@ -1,7 +1,6 @@
#include "gpu_hw_shadergen.h"
#include "common/assert.h"
#include <cstdio>
#include <glad.h>
GPU_HW_ShaderGen::GPU_HW_ShaderGen(HostDisplay::RenderAPI render_api, u32 resolution_scale, u32 multisamples,
bool per_sample_shading, bool true_color, bool scaled_dithering,

View File

@ -6,6 +6,7 @@
#include "common/file_system.h"
#include "common/image.h"
#include "common/log.h"
#include "common/path.h"
#include "common/string_util.h"
#include "controller.h"
#include "cpu_code_cache.h"
@ -34,7 +35,7 @@ HostInterface::HostInterface()
g_host_interface = this;
// we can get the program directory at construction time
m_program_directory = FileSystem::GetPathDirectory(FileSystem::GetProgramPath());
m_program_directory = Path::GetDirectory(FileSystem::GetProgramPath());
}
HostInterface::~HostInterface()
@ -896,7 +897,7 @@ void HostInterface::SetUserDirectoryToProgramDirectory()
if (program_path.empty())
Panic("Failed to get program path.");
std::string program_directory(FileSystem::GetPathDirectory(program_path));
std::string program_directory(Path::GetDirectory(program_path));
if (program_directory.empty())
Panic("Program path is not valid");

View File

@ -4,8 +4,9 @@
#include "IconsFontAwesome5.h"
#include "common/assert.h"
#include "common/easing.h"
#include "common/lru_cache.h"
#include "common/file_system.h"
#include "common/lru_cache.h"
#include "common/path.h"
#include "common/string.h"
#include "common/string_util.h"
#include "common/timer.h"
@ -999,7 +1000,6 @@ static ImGuiID s_enum_choice_button_id = 0;
static s32 s_enum_choice_button_value = 0;
static bool s_enum_choice_button_set = false;
bool EnumChoiceButtonImpl(const char* title, const char* summary, s32* value_pointer,
const char* (*to_display_name_function)(s32 value, void* opaque), void* opaque, u32 count,
bool enabled, float height, ImFont* font, ImFont* summary_font)
@ -1221,7 +1221,7 @@ static void PopulateFileSelectorItems()
if (sep_pos != std::string::npos)
{
parent_path = s_file_selector_current_directory.substr(0, sep_pos);
FileSystem::CanonicalizePath(parent_path, true);
Path::Canonicalize(&parent_path);
}
s_file_selector_items.emplace_back(ICON_FA_FOLDER_OPEN " <Parent Directory>", std::move(parent_path), false);

View File

@ -2,6 +2,7 @@
#include "common/byte_stream.h"
#include "common/file_system.h"
#include "common/log.h"
#include "common/path.h"
#include "common/shiftjis.h"
#include "common/state_wrapper.h"
#include "common/string_util.h"
@ -655,7 +656,8 @@ static bool ImportSaveWithDirectoryFrame(DataArray* data, const char* filename,
static bool ImportRawSave(DataArray* data, const char* filename, const FILESYSTEM_STAT_DATA& sd)
{
std::string save_name(FileSystem::GetFileTitleFromPath(filename));
const std::string display_name(FileSystem::GetDisplayNameFromPath(filename));
std::string save_name(Path::GetFileTitle(filename));
if (save_name.length() == 0)
{
Log_ErrorPrintf("Invalid filename: '%s'", filename);

View File

@ -3,6 +3,7 @@
#include "common/assert.h"
#include "common/file_system.h"
#include "common/log.h"
#include "common/path.h"
#include "system.h"
#include "zlib.h"
#include <cctype>
@ -182,7 +183,7 @@ static bool LoadLibraryPSF(const char* path, bool use_pc_sp, u32 depth = 0)
std::optional<std::string> lib_name(file.GetTagString("_lib"));
if (lib_name.has_value())
{
const std::string lib_path(FileSystem::BuildRelativePath(path, lib_name.value()));
const std::string lib_path(Path::BuildRelativePath(path, lib_name.value()));
Log_InfoPrintf("Loading main parent PSF '%s'", lib_path.c_str());
// We should use the initial SP/PC from the **first** parent lib.
@ -214,7 +215,7 @@ static bool LoadLibraryPSF(const char* path, bool use_pc_sp, u32 depth = 0)
if (!lib_name.has_value())
break;
const std::string lib_path(FileSystem::BuildRelativePath(path, lib_name.value()));
const std::string lib_path(Path::BuildRelativePath(path, lib_name.value()));
Log_InfoPrintf("Loading parent PSF '%s'", lib_path.c_str());
if (!LoadLibraryPSF(lib_path.c_str(), false, depth + 1))
{

View File

@ -1,13 +1,14 @@
#include "shadergen.h"
#include "common/assert.h"
#include "common/gl/loader.h"
#include "common/log.h"
#include <cstdio>
#include <cstring>
#include <glad.h>
Log_SetChannel(ShaderGen);
ShaderGen::ShaderGen(HostDisplay::RenderAPI render_api, bool supports_dual_source_blend)
: m_render_api(render_api), m_glsl(render_api != HostDisplay::RenderAPI::D3D11 && render_api != HostDisplay::RenderAPI::D3D12),
: m_render_api(render_api),
m_glsl(render_api != HostDisplay::RenderAPI::D3D11 && render_api != HostDisplay::RenderAPI::D3D12),
m_supports_dual_source_blend(supports_dual_source_blend), m_use_glsl_interface_blocks(false)
{
if (m_glsl)

View File

@ -9,9 +9,9 @@
#include "common/iso_reader.h"
#include "common/log.h"
#include "common/make_array.h"
#include "common/path.h"
#include "common/state_wrapper.h"
#include "common/string_util.h"
#include "common/timestamp.h"
#include "controller.h"
#include "cpu_code_cache.h"
#include "cpu_core.h"
@ -705,8 +705,8 @@ std::unique_ptr<CDImage> OpenCDImage(const char* path, Common::Error* error, boo
if (check_for_patches)
{
const std::string ppf_filename(FileSystem::BuildRelativePath(
path, FileSystem::ReplaceExtension(FileSystem::GetDisplayNameFromPath(path), "ppf")));
const std::string ppf_filename(
Path::BuildRelativePath(path, Path::ReplaceExtension(FileSystem::GetDisplayNameFromPath(path), "ppf")));
if (FileSystem::FileExists(ppf_filename.c_str()))
{
media = CDImage::OverlayPPFPatch(ppf_filename.c_str(), std::move(media));
@ -1754,7 +1754,7 @@ static bool LoadEXEToRAM(const char* filename, bool patch_bios)
bool LoadEXE(const char* filename)
{
const std::string libps_path(FileSystem::BuildRelativePath(filename, "libps.exe"));
const std::string libps_path(Path::BuildRelativePath(filename, "libps.exe"));
if (!libps_path.empty() && FileSystem::FileExists(libps_path.c_str()) && !LoadEXEToRAM(libps_path.c_str(), false))
{
Log_ErrorPrintf("Failed to load libps.exe from '%s'", libps_path.c_str());
@ -1951,7 +1951,7 @@ static std::unique_ptr<MemoryCard> GetMemoryCardForSlot(u32 slot, MemoryCardType
case MemoryCardType::PerGameFileTitle:
{
const std::string display_name(FileSystem::GetDisplayNameFromPath(s_running_game_path));
const std::string_view file_title(FileSystem::GetFileTitleFromPath(display_name));
const std::string_view file_title(Path::GetFileTitle(display_name));
if (file_title.empty())
{
g_host_interface->AddFormattedOSDMessage(

View File

@ -1,5 +1,6 @@
#include "gamelistmodel.h"
#include "common/file_system.h"
#include "common/path.h"
#include "common/string_util.h"
#include "core/system.h"
#include <QtCore/QDate>
@ -182,7 +183,7 @@ QVariant GameListModel::data(const QModelIndex& index, int role) const
case Column_FileTitle:
{
const std::string_view file_title(FileSystem::GetFileTitleFromPath(ge.path));
const std::string_view file_title(Path::GetFileTitle(ge.path));
return QString::fromUtf8(file_title.data(), static_cast<int>(file_title.length()));
}
@ -248,7 +249,7 @@ QVariant GameListModel::data(const QModelIndex& index, int role) const
case Column_FileTitle:
{
const std::string_view file_title(FileSystem::GetFileTitleFromPath(ge.path));
const std::string_view file_title(Path::GetFileTitle(ge.path));
return QString::fromUtf8(file_title.data(), static_cast<int>(file_title.length()));
}
@ -427,8 +428,8 @@ bool GameListModel::lessThan(const QModelIndex& left_index, const QModelIndex& r
case Column_FileTitle:
{
const std::string_view file_title_left(FileSystem::GetFileTitleFromPath(left.path));
const std::string_view file_title_right(FileSystem::GetFileTitleFromPath(right.path));
const std::string_view file_title_left(Path::GetFileTitle(left.path));
const std::string_view file_title_right(Path::GetFileTitle(right.path));
if (file_title_left == file_title_right)
return titlesLessThan(left_row, right_row);

View File

@ -4,6 +4,7 @@
#include "common/byte_stream.h"
#include "common/file_system.h"
#include "common/log.h"
#include "common/path.h"
#include "common/string_util.h"
#include "core/cheats.h"
#include "core/controller.h"
@ -1153,7 +1154,7 @@ void QtHostInterface::populateGameListContextMenu(const GameListEntry* entry, QW
{
const std::string display_name(FileSystem::GetDisplayNameFromPath(entry->path));
paths[i] = QString::fromStdString(GetGameMemoryCardPath(
MemoryCard::SanitizeGameTitleForFileName(FileSystem::GetFileTitleFromPath(display_name)).c_str(), i));
MemoryCard::SanitizeGameTitleForFileName(Path::GetFileTitle(display_name)).c_str(), i));
}
break;
default:

View File

@ -4,6 +4,7 @@
#include "common/byte_stream.h"
#include "common/file_system.h"
#include "common/log.h"
#include "common/path.h"
#include "common/string_util.h"
#include "core/system.h"
#include "frontend-common/game_database.h"
@ -105,7 +106,7 @@ void RegTestHostInterface::GetGameInfo(const char* path, CDImage* image, std::st
*code = System::GetGameCodeForImage(image, true);
}
*title = FileSystem::GetFileTitleFromPath(path);
*title = Path::GetFileTitle(path);
}
void RegTestHostInterface::OnRunningGameChanged(const std::string& path, CDImage* image, const std::string& game_code,
@ -204,7 +205,7 @@ void RegTestHostInterface::LoadGameSettingsDatabase()
return;
}
const std::string data(FileSystem::ReadStreamToString(stream.get()));
const std::string data(ByteStream::ReadStreamToString(stream.get()));
if (data.empty() || !s_game_settings_db.Load(data))
{
Log_ErrorPrintf("Failed to load game settings database from '%s'. This could cause compatibility issues.", path);
@ -238,7 +239,7 @@ std::string RegTestHostInterface::GetBIOSDirectory()
std::unique_ptr<ByteStream> RegTestHostInterface::OpenPackageFile(const char* path, u32 flags)
{
std::string full_path(GetProgramDirectoryRelativePath("%s", path));
return ByteStream_OpenFileStream(full_path.c_str(), flags);
return ByteStream::OpenFile(full_path.c_str(), flags);
}
bool RegTestHostInterface::AcquireHostDisplay()

View File

@ -6,6 +6,7 @@
#include "common/crash_handler.h"
#include "common/file_system.h"
#include "common/log.h"
#include "common/path.h"
#include "common/string_util.h"
#include "controller_interface.h"
#include "core/cdrom.h"
@ -3074,7 +3075,7 @@ void CommonHostInterface::RenameCurrentSaveStateToBackup(const char* filename)
if (!FileSystem::FileExists(filename))
return;
const std::string backup_filename(FileSystem::ReplaceExtension(filename, "bak"));
const std::string backup_filename(Path::ReplaceExtension(filename, "bak"));
if (!FileSystem::RenamePath(filename, backup_filename.c_str()))
{
Log_ErrorPrintf("Failed to rename save state backup '%s'", backup_filename.c_str());
@ -3094,8 +3095,7 @@ std::vector<CommonHostInterface::SaveStateInfo> CommonHostInterface::GetAvailabl
if (!FileSystem::StatFile(path.c_str(), &sd))
return;
si.push_back(SaveStateInfo{std::move(path), static_cast<std::time_t>(sd.ModificationTime.AsUnixTimestamp()),
static_cast<s32>(slot), global});
si.push_back(SaveStateInfo{std::move(path), sd.ModificationTime, static_cast<s32>(slot), global});
};
if (game_code && std::strlen(game_code) > 0)
@ -3120,7 +3120,7 @@ std::optional<CommonHostInterface::SaveStateInfo> CommonHostInterface::GetSaveSt
if (!FileSystem::StatFile(path.c_str(), &sd))
return std::nullopt;
return SaveStateInfo{std::move(path), static_cast<std::time_t>(sd.ModificationTime.AsUnixTimestamp()), slot, global};
return SaveStateInfo{std::move(path), sd.ModificationTime, slot, global};
}
std::optional<CommonHostInterface::ExtendedSaveStateInfo>
@ -3193,7 +3193,7 @@ CommonHostInterface::GetExtendedSaveStateInfo(const char* game_code, s32 slot)
return std::nullopt;
ssi->path = std::move(path);
ssi->timestamp = sd.ModificationTime.AsUnixTimestamp();
ssi->timestamp = sd.ModificationTime;
ssi->slot = slot;
ssi->global = global;
@ -3650,7 +3650,8 @@ void CommonHostInterface::GetGameInfo(const char* path, CDImage* image, std::str
*code = System::GetGameCodeForImage(image, true);
}
*title = FileSystem::GetFileTitleFromPath(path);
const std::string display_name(FileSystem::GetDisplayNameFromPath(path));
*title = Path::GetFileTitle(display_name);
}
bool CommonHostInterface::SaveResumeSaveState()

View File

@ -6,6 +6,7 @@
#include "common/file_system.h"
#include "common/log.h"
#include "common/make_array.h"
#include "common/path.h"
#include "common/string.h"
#include "common/string_util.h"
#include "common_host_interface.h"
@ -688,7 +689,7 @@ static void DoChangeDiscFromFile()
};
OpenFileSelector(ICON_FA_COMPACT_DISC " Select Disc Image", false, std::move(callback), GetDiscImageFilters(),
std::string(FileSystem::GetPathDirectory(System::GetMediaFileName())));
std::string(Path::GetDirectory(System::GetMediaFileName())));
}
static void DoChangeDisc()
@ -1120,7 +1121,7 @@ static bool SettingInfoButton(const SettingInfo& si, const char* section)
CloseFileSelector();
};
OpenFileSelector(si.visible_name, false, std::move(callback), ImGuiFullscreen::FileSelectorFilters(),
std::string(FileSystem::GetPathDirectory(std::move(value))));
std::string(Path::GetDirectory(std::move(value))));
}
return false;
@ -2604,7 +2605,7 @@ void DrawQuickMenu(MainWindowType type)
SmallString subtitle;
if (!code.empty())
subtitle.Format("%s - ", code.c_str());
subtitle.AppendString(FileSystem::GetFileNameFromPath(System::GetRunningPath()));
subtitle.AppendString(Path::GetFileTitle(System::GetRunningPath()));
const ImVec2 title_size(
g_large_font->CalcTextSizeA(g_large_font->FontSize, std::numeric_limits<float>::max(), -1.0f, title.c_str()));
@ -3092,7 +3093,7 @@ void DrawGameListWindow()
else
summary.Format("%s - %s - ", entry->code.c_str(), Settings::GetDiscRegionName(entry->region));
summary.AppendString(FileSystem::GetFileNameFromPath(entry->path));
summary.AppendString(Path::GetFileName(entry->path));
ImGui::GetWindowDrawList()->AddImage(cover_texture->GetHandle(), bb.Min, bb.Min + image_size, ImVec2(0.0f, 0.0f),
ImVec2(1.0f, 1.0f), IM_COL32(255, 255, 255, 255));

View File

@ -6,6 +6,7 @@
#include "common/iso_reader.h"
#include "common/log.h"
#include "common/make_array.h"
#include "common/path.h"
#include "common/progress_callback.h"
#include "common/string_util.h"
#include "core/bios.h"
@ -91,7 +92,7 @@ bool GameList::GetExeListEntry(const std::string& path, GameListEntry* entry)
const std::string display_name(FileSystem::GetDisplayNameFromPath(path));
entry->code.clear();
entry->title = FileSystem::StripExtension(display_name);
entry->title = Path::StripExtension(display_name);
entry->region = BIOS::GetPSExeDiscRegion(header);
entry->total_size = ZeroExtend64(file_size);
entry->type = GameListEntryType::PSExe;
@ -133,7 +134,7 @@ bool GameList::GetPsfListEntry(const std::string& path, GameListEntry* entry)
else
{
const std::string display_name(FileSystem::GetDisplayNameFromPath(path));
entry->title += FileSystem::StripExtension(display_name);
entry->title += Path::StripExtension(display_name);
}
return true;
@ -160,9 +161,11 @@ bool GameList::GetGameListEntry(const std::string& path, GameListEntry* entry)
GameDatabaseEntry dbentry;
if (!m_database.GetEntryForDisc(cdi.get(), &dbentry))
{
const std::string display_name(FileSystem::GetDisplayNameFromPath(path));
// no game code, so use the filename title
entry->code = System::GetGameCodeForImage(cdi.get(), true);
entry->title = FileSystem::GetFileTitleFromPath(path);
entry->title = Path::GetFileTitle(display_name);
entry->compatibility_rating = GameListCompatibilityRating::Unknown;
entry->release_date = 0;
entry->min_players = 0;
@ -492,20 +495,19 @@ void GameList::ScanDirectory(const char* path, bool recursive, ProgressCallback*
if (!IsScannableFilename(ffd.FileName) || IsPathExcluded(ffd.FileName) || GetEntryForPath(ffd.FileName.c_str()))
continue;
const u64 modified_time = ffd.ModificationTime.AsUnixTimestamp();
if (AddFileFromCache(ffd.FileName, modified_time))
if (AddFileFromCache(ffd.FileName, ffd.ModificationTime))
continue;
// ownership of fp is transferred
progress->SetFormattedStatusText("Scanning '%s'...", FileSystem::GetDisplayNameFromPath(ffd.FileName).c_str());
ScanFile(std::move(ffd.FileName), modified_time);
ScanFile(std::move(ffd.FileName), ffd.ModificationTime);
}
progress->SetProgressValue(static_cast<u32>(files.size()));
progress->PopState();
}
bool GameList::AddFileFromCache(const std::string& path, u64 timestamp)
bool GameList::AddFileFromCache(const std::string& path, std::time_t timestamp)
{
if (std::any_of(m_entries.begin(), m_entries.end(),
[&path](const GameListEntry& other) { return other.path == path; }))
@ -515,14 +517,14 @@ bool GameList::AddFileFromCache(const std::string& path, u64 timestamp)
}
GameListEntry entry;
if (!GetGameListEntryFromCache(path, &entry) || entry.last_modified_time != timestamp)
if (!GetGameListEntryFromCache(path, &entry) || entry.last_modified_time != static_cast<u64>(timestamp))
return false;
m_entries.push_back(std::move(entry));
return true;
}
bool GameList::ScanFile(std::string path, u64 timestamp)
bool GameList::ScanFile(std::string path, std::time_t timestamp)
{
Log_DevPrintf("Scanning '%s'...", path.c_str());
@ -531,7 +533,7 @@ bool GameList::ScanFile(std::string path, u64 timestamp)
return false;
entry.path = std::move(path);
entry.last_modified_time = timestamp;
entry.last_modified_time = static_cast<u64>(timestamp);
if (m_cache_write_stream || OpenCacheForWriting())
{
@ -1078,7 +1080,8 @@ std::string GameList::GetCoverImagePath(const std::string& path, const std::stri
for (const char* extension : extensions)
{
// use the file title if it differs (e.g. modded games)
const std::string_view file_title(FileSystem::GetFileTitleFromPath(path));
const std::string display_name(FileSystem::GetDisplayNameFromPath(path));
const std::string_view file_title(Path::GetFileTitle(display_name));
if (!file_title.empty() && title != file_title)
{
cover_path.Clear();

View File

@ -3,6 +3,7 @@
#include "core/types.h"
#include "game_database.h"
#include "game_settings.h"
#include <ctime>
#include <memory>
#include <optional>
#include <string>
@ -152,8 +153,8 @@ private:
bool GetGameListEntry(const std::string& path, GameListEntry* entry);
bool GetGameListEntryFromCache(const std::string& path, GameListEntry* entry);
void ScanDirectory(const char* path, bool recursive, ProgressCallback* progress);
bool AddFileFromCache(const std::string& path, u64 timestamp);
bool ScanFile(std::string path, u64 timestamp);
bool AddFileFromCache(const std::string& path, std::time_t timestamp);
bool ScanFile(std::string path, std::time_t timestamp);
void LoadCache();
bool LoadEntriesFromCache(ByteStream* stream);

View File

@ -76,7 +76,7 @@
#endif
// GL includes
#include <glad.h>
#include "common/gl/loader.h"
// OpenGL Data
static char g_GlslVersionString[32] = "";

View File

@ -1,14 +1,6 @@
#pragma once
// GLAD has to come first so that Qt doesn't pull in the system GL headers, which are incompatible with glad.
#include <glad.h>
// Hack to prevent Apple's glext.h headers from getting included via qopengl.h, since we still want to use glad.
#ifdef __APPLE__
#define __glext_h_
#endif
#include "common/gl/context.h"
#include "common/gl/loader.h"
#include "common/gl/program.h"
#include "common/gl/stream_buffer.h"
#include "common/gl/texture.h"

View File

@ -1,7 +1,6 @@
#include "save_state_selector_ui.h"
#include "common/log.h"
#include "common/string_util.h"
#include "common/timestamp.h"
#include "core/host_display.h"
#include "core/system.h"
#include "fmt/chrono.h"