Everything: Get rid of wx entirely from the Qt build

This commit is contained in:
Connor McLaughlin 2022-05-20 00:46:33 +10:00 committed by refractionpcsx2
parent 893b3c629d
commit ea051c6d5f
137 changed files with 2249 additions and 1914 deletions

View File

@ -4,11 +4,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
VisualStudioVersion = 17.0.31606.5
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3rdparty", "3rdparty", "{78EBE642-7A4D-4EA7-86BE-5639C6646C38}"
ProjectSection(SolutionItems) = preProject
3rdparty\svn_readme.txt = 3rdparty\svn_readme.txt
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{2D6F0A62-A247-4CCF-947F-FCD54BE16103}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pcsx2-qt", "pcsx2-qt\pcsx2-qt.vcxproj", "{2A016F21-87AE-4154-8271-1F57E91408E9}"
EndProject
@ -16,14 +11,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SoundTouch", "3rdparty\soun
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "3rdparty\zlib\zlib.vcxproj", "{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bin2cpp", "tools\bin2cpp\bin2c.vcxproj", "{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libjpeg", "3rdparty\libjpeg\libjpeg.vcxproj", "{BC236261-77E8-4567-8D09-45CD02965EB6}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wx30_config", "3rdparty\wxwidgets3.0\build\msw\wx30_config.vcxproj", "{01F4CE10-2CFB-41A8-B41F-E54337868A1D}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wx30_base", "3rdparty\wxwidgets3.0\build\msw\wx30_base.vcxproj", "{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpng", "3rdparty\libpng\projects\vstudio\libpng\libpng.vcxproj", "{D6973076-9317-4EF2-A0B8-B7A18AC0713E}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "baseclasses", "3rdparty\baseclasses\baseclasses.vcxproj", "{27F17499-A372-4408-8AFA-4F9F4584FBD3}"
@ -112,18 +101,6 @@ Global
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Release AVX2|x64.Build.0 = Release|x64
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Release|x64.ActiveCfg = Release|x64
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Release|x64.Build.0 = Release|x64
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Debug AVX2|x64.ActiveCfg = Debug|x64
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Debug AVX2|x64.Build.0 = Debug|x64
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Debug|x64.ActiveCfg = Debug|x64
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Debug|x64.Build.0 = Debug|x64
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Devel AVX2|x64.ActiveCfg = Devel|x64
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Devel AVX2|x64.Build.0 = Devel|x64
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Devel|x64.ActiveCfg = Devel|x64
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Devel|x64.Build.0 = Devel|x64
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Release AVX2|x64.ActiveCfg = Release|x64
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Release AVX2|x64.Build.0 = Release|x64
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Release|x64.ActiveCfg = Release|x64
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Release|x64.Build.0 = Release|x64
{BC236261-77E8-4567-8D09-45CD02965EB6}.Debug AVX2|x64.ActiveCfg = Debug|x64
{BC236261-77E8-4567-8D09-45CD02965EB6}.Debug AVX2|x64.Build.0 = Debug|x64
{BC236261-77E8-4567-8D09-45CD02965EB6}.Debug|x64.ActiveCfg = Debug|x64
@ -136,30 +113,6 @@ Global
{BC236261-77E8-4567-8D09-45CD02965EB6}.Release AVX2|x64.Build.0 = Release|x64
{BC236261-77E8-4567-8D09-45CD02965EB6}.Release|x64.ActiveCfg = Release|x64
{BC236261-77E8-4567-8D09-45CD02965EB6}.Release|x64.Build.0 = Release|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Debug AVX2|x64.ActiveCfg = Debug|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Debug AVX2|x64.Build.0 = Debug|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Debug|x64.ActiveCfg = Debug|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Debug|x64.Build.0 = Debug|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Devel AVX2|x64.ActiveCfg = Devel|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Devel AVX2|x64.Build.0 = Devel|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Devel|x64.ActiveCfg = Devel|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Devel|x64.Build.0 = Devel|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Release AVX2|x64.ActiveCfg = Release|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Release AVX2|x64.Build.0 = Release|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Release|x64.ActiveCfg = Release|x64
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Release|x64.Build.0 = Release|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug AVX2|x64.ActiveCfg = Debug|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug AVX2|x64.Build.0 = Debug|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug|x64.ActiveCfg = Debug|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug|x64.Build.0 = Debug|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Devel AVX2|x64.ActiveCfg = Devel|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Devel AVX2|x64.Build.0 = Devel|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Devel|x64.ActiveCfg = Devel|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Devel|x64.Build.0 = Devel|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release AVX2|x64.ActiveCfg = Release|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release AVX2|x64.Build.0 = Release|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release|x64.ActiveCfg = Release|x64
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release|x64.Build.0 = Release|x64
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug AVX2|x64.ActiveCfg = Debug|x64
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug AVX2|x64.Build.0 = Debug|x64
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug|x64.ActiveCfg = Debug|x64
@ -419,10 +372,7 @@ Global
GlobalSection(NestedProjects) = preSolution
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213} = {2D6F0A62-A247-4CCF-947F-FCD54BE16103}
{BC236261-77E8-4567-8D09-45CD02965EB6} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
{01F4CE10-2CFB-41A8-B41F-E54337868A1D} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
{D6973076-9317-4EF2-A0B8-B7A18AC0713E} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
{27F17499-A372-4408-8AFA-4F9F4584FBD3} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
{12728250-16EC-4DC6-94D7-E21DD88947F8} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}

View File

@ -84,35 +84,37 @@ int main()
}
")
function(WX_vs_SDL)
file(WRITE "${CMAKE_BINARY_DIR}/wx_sdl.c" "${wx_sdl_c_code}")
enable_language(C)
if (NOT PCSX2_CORE)
function(WX_vs_SDL)
file(WRITE "${CMAKE_BINARY_DIR}/wx_sdl.c" "${wx_sdl_c_code}")
enable_language(C)
try_compile(
wx_linked_to_sdl
"${CMAKE_BINARY_DIR}"
"${CMAKE_BINARY_DIR}/wx_sdl.c"
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${wxWidgets_INCLUDE_DIRS}"
LINK_LIBRARIES "${wxWidgets_LIBRARIES}"
COPY_FILE "${CMAKE_BINARY_DIR}/wx_sdl"
)
try_compile(
wx_linked_to_sdl
"${CMAKE_BINARY_DIR}"
"${CMAKE_BINARY_DIR}/wx_sdl.c"
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${wxWidgets_INCLUDE_DIRS}"
LINK_LIBRARIES "${wxWidgets_LIBRARIES}"
COPY_FILE "${CMAKE_BINARY_DIR}/wx_sdl"
)
if (NOT wx_linked_to_sdl)
return()
endif()
if (NOT wx_linked_to_sdl)
return()
endif()
execute_process(
COMMAND ldd "${CMAKE_BINARY_DIR}/wx_sdl"
COMMAND grep -c SDL2
OUTPUT_VARIABLE sdl2_count
)
execute_process(
COMMAND ldd "${CMAKE_BINARY_DIR}/wx_sdl"
COMMAND grep -c SDL2
OUTPUT_VARIABLE sdl2_count
)
if (SDL2_API AND sdl2_count STREQUAL "0")
message(FATAL_ERROR "wxWidgets is linked to SDL1.2. Please use -DSDL2_API=FALSE.")
elseif (NOT SDL2_API AND NOT sdl2_count STREQUAL "0")
message(FATAL_ERROR "wxWidgets is linked to SDL2. Please use -DSDL2_API=TRUE")
endif()
endfunction()
if (SDL2_API AND sdl2_count STREQUAL "0")
message(FATAL_ERROR "wxWidgets is linked to SDL1.2. Please use -DSDL2_API=FALSE.")
elseif (NOT SDL2_API AND NOT sdl2_count STREQUAL "0")
message(FATAL_ERROR "wxWidgets is linked to SDL2. Please use -DSDL2_API=TRUE")
endif()
endfunction()
endif()
function(GCC7_BUG)
# try_run doesn't work when cross-compiling is enabled. It is completely silly in our case

View File

@ -14,7 +14,9 @@ if (WIN32)
add_subdirectory(3rdparty/pthreads4w EXCLUDE_FROM_ALL)
add_subdirectory(3rdparty/soundtouch EXCLUDE_FROM_ALL)
add_subdirectory(3rdparty/wil EXCLUDE_FROM_ALL)
add_subdirectory(3rdparty/wxwidgets3.0 EXCLUDE_FROM_ALL)
if (NOT PCSX2_CORE)
add_subdirectory(3rdparty/wxwidgets3.0 EXCLUDE_FROM_ALL)
endif()
add_subdirectory(3rdparty/xz EXCLUDE_FROM_ALL)
add_subdirectory(3rdparty/D3D12MemAlloc EXCLUDE_FROM_ALL)
else()
@ -37,74 +39,76 @@ else()
find_package(PNG REQUIRED)
find_package(Vtune)
# Does not require the module (allow to compile non-wx plugins)
# Force the unicode build (the variable is only supported on cmake 2.8.3 and above)
# Warning do not put any double-quote for the argument...
# set(wxWidgets_CONFIG_OPTIONS --unicode=yes --debug=yes) # In case someone want to debug inside wx
#
# Fedora uses an extra non-standard option ... Arch must be the first option.
# They do uname -m if missing so only fix for cross compilations.
# http://pkgs.fedoraproject.org/cgit/wxGTK.git/plain/wx-config
if(Fedora AND CMAKE_CROSSCOMPILING)
set(wxWidgets_CONFIG_OPTIONS --arch ${PCSX2_TARGET_ARCHITECTURES} --unicode=yes)
else()
set(wxWidgets_CONFIG_OPTIONS --unicode=yes)
endif()
if(NOT PCSX2_CORE)
# Does not require the module (allow to compile non-wx plugins)
# Force the unicode build (the variable is only supported on cmake 2.8.3 and above)
# Warning do not put any double-quote for the argument...
# set(wxWidgets_CONFIG_OPTIONS --unicode=yes --debug=yes) # In case someone want to debug inside wx
#
# Fedora uses an extra non-standard option ... Arch must be the first option.
# They do uname -m if missing so only fix for cross compilations.
# http://pkgs.fedoraproject.org/cgit/wxGTK.git/plain/wx-config
if(Fedora AND CMAKE_CROSSCOMPILING)
set(wxWidgets_CONFIG_OPTIONS --arch ${PCSX2_TARGET_ARCHITECTURES} --unicode=yes)
else()
set(wxWidgets_CONFIG_OPTIONS --unicode=yes)
endif()
# I'm removing the version check, because it excludes newer versions and requires specifically 3.0.
#list(APPEND wxWidgets_CONFIG_OPTIONS --version=3.0)
# I'm removing the version check, because it excludes newer versions and requires specifically 3.0.
#list(APPEND wxWidgets_CONFIG_OPTIONS --version=3.0)
# The wx version must be specified so a mix of gtk2 and gtk3 isn't used
# as that can cause compile errors.
if(GTK2_API AND NOT APPLE)
list(APPEND wxWidgets_CONFIG_OPTIONS --toolkit=gtk2)
elseif(NOT APPLE)
list(APPEND wxWidgets_CONFIG_OPTIONS --toolkit=gtk3)
endif()
# The wx version must be specified so a mix of gtk2 and gtk3 isn't used
# as that can cause compile errors.
if(GTK2_API AND NOT APPLE)
list(APPEND wxWidgets_CONFIG_OPTIONS --toolkit=gtk2)
elseif(NOT APPLE)
list(APPEND wxWidgets_CONFIG_OPTIONS --toolkit=gtk3)
endif()
# wx2.8 => /usr/bin/wx-config-2.8
# lib32-wx2.8 => /usr/bin/wx-config32-2.8
# wx3.0 => /usr/bin/wx-config-3.0
# I'm going to take a wild guess and predict this:
# lib32-wx3.0 => /usr/bin/wx-config32-3.0
# FindwxWidgets only searches for wx-config.
if(CMAKE_CROSSCOMPILING)
# May need to fix the filenames for lib32-wx3.0.
if(${PCSX2_TARGET_ARCHITECTURES} MATCHES "i386")
if (Fedora AND EXISTS "/usr/bin/wx-config-3.0")
# wx2.8 => /usr/bin/wx-config-2.8
# lib32-wx2.8 => /usr/bin/wx-config32-2.8
# wx3.0 => /usr/bin/wx-config-3.0
# I'm going to take a wild guess and predict this:
# lib32-wx3.0 => /usr/bin/wx-config32-3.0
# FindwxWidgets only searches for wx-config.
if(CMAKE_CROSSCOMPILING)
# May need to fix the filenames for lib32-wx3.0.
if(${PCSX2_TARGET_ARCHITECTURES} MATCHES "i386")
if (Fedora AND EXISTS "/usr/bin/wx-config-3.0")
set(wxWidgets_CONFIG_EXECUTABLE "/usr/bin/wx-config-3.0")
endif()
if (EXISTS "/usr/bin/wx-config32")
set(wxWidgets_CONFIG_EXECUTABLE "/usr/bin/wx-config32")
endif()
if (EXISTS "/usr/bin/wx-config32-3.0")
set(wxWidgets_CONFIG_EXECUTABLE "/usr/bin/wx-config32-3.0")
endif()
endif()
else()
if (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
set(wxWidgets_CONFIG_EXECUTABLE "/usr/local/bin/wxgtk3u-3.0-config")
endif()
if(EXISTS "/usr/bin/wx-config-3.2")
set(wxWidgets_CONFIG_EXECUTABLE "/usr/bin/wx-config-3.2")
endif()
if(EXISTS "/usr/bin/wx-config-3.1")
set(wxWidgets_CONFIG_EXECUTABLE "/usr/bin/wx-config-3.1")
endif()
if(EXISTS "/usr/bin/wx-config-3.0")
set(wxWidgets_CONFIG_EXECUTABLE "/usr/bin/wx-config-3.0")
endif()
if (EXISTS "/usr/bin/wx-config32")
set(wxWidgets_CONFIG_EXECUTABLE "/usr/bin/wx-config32")
if(EXISTS "/usr/bin/wx-config")
set(wxWidgets_CONFIG_EXECUTABLE "/usr/bin/wx-config")
endif()
if (EXISTS "/usr/bin/wx-config32-3.0")
set(wxWidgets_CONFIG_EXECUTABLE "/usr/bin/wx-config32-3.0")
if(NOT GTK2_API AND EXISTS "/usr/bin/wx-config-gtk3")
set(wxWidgets_CONFIG_EXECUTABLE "/usr/bin/wx-config-gtk3")
endif()
endif()
else()
if (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
set(wxWidgets_CONFIG_EXECUTABLE "/usr/local/bin/wxgtk3u-3.0-config")
endif()
if(EXISTS "/usr/bin/wx-config-3.2")
set(wxWidgets_CONFIG_EXECUTABLE "/usr/bin/wx-config-3.2")
endif()
if(EXISTS "/usr/bin/wx-config-3.1")
set(wxWidgets_CONFIG_EXECUTABLE "/usr/bin/wx-config-3.1")
endif()
if(EXISTS "/usr/bin/wx-config-3.0")
set(wxWidgets_CONFIG_EXECUTABLE "/usr/bin/wx-config-3.0")
endif()
if(EXISTS "/usr/bin/wx-config")
set(wxWidgets_CONFIG_EXECUTABLE "/usr/bin/wx-config")
endif()
if(NOT GTK2_API AND EXISTS "/usr/bin/wx-config-gtk3")
set(wxWidgets_CONFIG_EXECUTABLE "/usr/bin/wx-config-gtk3")
endif()
endif()
find_package(wxWidgets REQUIRED base core adv)
include(${wxWidgets_USE_FILE})
make_imported_target_if_missing(wxWidgets::all wxWidgets)
find_package(wxWidgets REQUIRED base core adv)
include(${wxWidgets_USE_FILE})
make_imported_target_if_missing(wxWidgets::all wxWidgets)
endif()
find_package(ZLIB REQUIRED)
@ -189,7 +193,9 @@ endif()
#----------------------------------------
include(ApiValidation)
WX_vs_SDL()
if(NOT PCSX2_CORE)
WX_vs_SDL()
endif()
# Blacklist bad GCC
if(GCC_VERSION VERSION_EQUAL "7.0" OR GCC_VERSION VERSION_EQUAL "7.1")

View File

@ -21,7 +21,6 @@ target_sources(common PRIVATE
FileSystem.cpp
Misc.cpp
MD5Digest.cpp
PathUtils.cpp
PrecompiledHeader.cpp
Perf.cpp
ProgressCallback.cpp
@ -261,7 +260,6 @@ target_link_libraries(common PRIVATE
)
target_link_libraries(common PUBLIC
wxWidgets::all
fmt::fmt
)

View File

@ -14,6 +14,7 @@
*/
#include "FileSystem.h"
#include "Path.h"
#include "Assertions.h"
#include "Console.h"
#include "StringUtil.h"
@ -21,6 +22,7 @@
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <limits>
#ifdef __APPLE__
#include <mach-o/dyld.h>
@ -33,12 +35,10 @@
#endif
#if defined(_WIN32)
#include "RedtapeWindows.h"
#include <winioctl.h>
#include <shlobj.h>
// We can't guarantee that windows.h isn't included before here, so we have to undef.
#undef min
#undef max
#if defined(_UWP)
#include <fcntl.h>
#include <io.h>
@ -87,7 +87,50 @@ static inline bool FileSystemCharacterIsSane(char c, bool StripSlashes)
return true;
}
void FileSystem::SanitizeFileName(char* Destination, u32 cbDestination, const char* FileName, bool StripSlashes /* = true */)
template<typename T>
static inline void PathAppendString(std::string& dst, const T& src)
{
if (dst.capacity() < (dst.length() + src.length()))
dst.reserve(dst.length() + src.length());
bool last_separator = (!dst.empty() && dst.back() == FS_OSPATH_SEPARATOR_CHARACTER);
size_t index = 0;
#ifdef _WIN32
// special case for UNC paths here
if (dst.empty() && src.length() >= 3 && src[0] == '\\' && src[1] == '\\' && src[2] != '\\')
{
dst.append("\\\\");
index = 2;
}
#endif
for (; index < src.length(); index++)
{
const char ch = src[index];
#ifdef _WIN32
// convert forward slashes to backslashes
if (ch == '\\' || ch == '/')
#else
if (ch == '/')
#endif
{
if (last_separator)
continue;
last_separator = true;
dst.push_back(FS_OSPATH_SEPARATOR_CHARACTER);
}
else
{
last_separator = false;
dst.push_back(ch);
}
}
}
void Path::SanitizeFileName(char* Destination, u32 cbDestination, const char* FileName, bool StripSlashes /* = true */)
{
u32 i;
u32 fileNameLength = static_cast<u32>(std::strlen(FileName));
@ -112,7 +155,7 @@ void FileSystem::SanitizeFileName(char* Destination, u32 cbDestination, const ch
}
}
void FileSystem::SanitizeFileName(std::string& Destination, bool StripSlashes /* = true*/)
void Path::SanitizeFileName(std::string& Destination, bool StripSlashes /* = true*/)
{
const std::size_t len = Destination.length();
for (std::size_t i = 0; i < len; i++)
@ -122,26 +165,129 @@ void FileSystem::SanitizeFileName(std::string& Destination, bool StripSlashes /*
}
}
bool FileSystem::IsAbsolutePath(const std::string_view& path)
bool Path::IsAbsolute(const std::string_view& path)
{
#ifdef _WIN32
return (path.length() >= 3 && ((path[0] >= 'A' && path[0] <= 'Z') || (path[0] >= 'a' && path[0] <= 'z')) &&
path[1] == ':' && (path[2] == '/' || path[2] == '\\'));
path[1] == ':' && (path[2] == '/' || path[2] == '\\')) || (path.length() >= 3 && path[0] == '\\' && path[1] == '\\');
#else
return (path.length() >= 1 && path[0] == '/');
#endif
}
std::string_view FileSystem::GetExtension(const std::string_view& path)
std::string Path::ToNativePath(const std::string_view& path)
{
std::string ret;
PathAppendString(ret, path);
// remove trailing slashes
if (ret.length() > 1)
{
while (ret.back() == FS_OSPATH_SEPARATOR_CHARACTER)
ret.pop_back();
}
return ret;
}
void Path::ToNativePath(std::string* path)
{
*path = Path::ToNativePath(*path);
}
std::string Path::Canonicalize(const std::string_view& path)
{
std::vector<std::string_view> components = Path::SplitNativePath(path);
std::vector<std::string_view> new_components;
new_components.reserve(components.size());
for (const std::string_view& component : components)
{
if (component == ".")
{
// current directory, so it can be skipped, unless it's the only component
if (components.size() == 1)
new_components.push_back(std::move(component));
}
else if (component == "..")
{
// parent directory, pop one off if we're not at the beginning, otherwise preserve.
if (!new_components.empty())
new_components.pop_back();
else
new_components.push_back(std::move(component));
}
else
{
// anything else, preserve
new_components.push_back(std::move(component));
}
}
return Path::JoinNativePath(new_components);
}
void Path::Canonicalize(std::string* path)
{
*path = Canonicalize(*path);
}
std::string Path::MakeRelative(const std::string_view& path, const std::string_view& relative_to)
{
// simple algorithm, we just work on the components. could probably be better, but it'll do for now.
std::vector<std::string_view> path_components(SplitNativePath(path));
std::vector<std::string_view> relative_components(SplitNativePath(relative_to));
std::vector<std::string_view> new_components;
// both must be absolute paths
if (Path::IsAbsolute(path) && Path::IsAbsolute(relative_to))
{
// find the number of same components
size_t num_same = 0;
for (size_t i = 0; i < path_components.size() && i < relative_components.size(); i++)
{
if (path_components[i] == relative_components[i])
num_same++;
else
break;
}
// we need at least one same component
if (num_same > 0)
{
// from the relative_to directory, back up to the start of the common components
const size_t num_ups = relative_components.size() - num_same;
for (size_t i = 0; i < num_ups; i++)
new_components.emplace_back("..");
// and add the remainder of the path components
for (size_t i = num_same; i < path_components.size(); i++)
new_components.push_back(std::move(path_components[i]));
}
else
{
// no similarity
new_components = std::move(path_components);
}
}
else
{
// not absolute
new_components = std::move(path_components);
}
return JoinNativePath(new_components);
}
std::string_view Path::GetExtension(const std::string_view& path)
{
const std::string_view::size_type pos = path.rfind('.');
if (pos == std::string_view::npos)
return path;
return path.substr(pos + 1);
return std::string_view();
else
return path.substr(pos + 1);
}
std::string_view FileSystem::StripExtension(const std::string_view& path)
std::string_view Path::StripExtension(const std::string_view& path)
{
const std::string_view::size_type pos = path.rfind('.');
if (pos == std::string_view::npos)
@ -150,7 +296,7 @@ std::string_view FileSystem::StripExtension(const std::string_view& path)
return path.substr(0, pos);
}
std::string FileSystem::ReplaceExtension(const std::string_view& path, const std::string_view& new_extension)
std::string Path::ReplaceExtension(const std::string_view& path, const std::string_view& new_extension)
{
const std::string_view::size_type pos = path.rfind('.');
if (pos == std::string_view::npos)
@ -183,10 +329,10 @@ static std::string_view::size_type GetLastSeperatorPosition(const std::string_vi
std::string FileSystem::GetDisplayNameFromPath(const std::string_view& path)
{
return std::string(GetFileNameFromPath(path));
return std::string(Path::GetFileName(path));
}
std::string_view FileSystem::GetPathDirectory(const std::string_view& path)
std::string_view Path::GetDirectory(const std::string_view& path)
{
const std::string::size_type pos = GetLastSeperatorPosition(path, false);
if (pos == std::string_view::npos)
@ -195,7 +341,7 @@ std::string_view FileSystem::GetPathDirectory(const std::string_view& path)
return path.substr(0, pos);
}
std::string_view FileSystem::GetFileNameFromPath(const std::string_view& path)
std::string_view Path::GetFileName(const std::string_view& path)
{
const std::string_view::size_type pos = GetLastSeperatorPosition(path, true);
if (pos == std::string_view::npos)
@ -204,9 +350,9 @@ std::string_view FileSystem::GetFileNameFromPath(const std::string_view& path)
return path.substr(pos);
}
std::string_view FileSystem::GetFileTitleFromPath(const std::string_view& path)
std::string_view Path::GetFileTitle(const std::string_view& path)
{
const std::string_view filename(GetFileNameFromPath(path));
const std::string_view filename(GetFileName(path));
const std::string::size_type pos = filename.rfind('.');
if (pos == std::string_view::npos)
return filename;
@ -214,7 +360,86 @@ std::string_view FileSystem::GetFileTitleFromPath(const std::string_view& path)
return filename.substr(0, pos);
}
std::vector<std::string_view> FileSystem::SplitWindowsPath(const std::string_view& path)
std::string Path::ChangeFileName(const std::string_view& path, const std::string_view& new_filename)
{
std::string ret;
PathAppendString(ret, path);
const std::string_view::size_type pos = GetLastSeperatorPosition(ret, true);
if (pos == std::string_view::npos)
{
ret.clear();
PathAppendString(ret, new_filename);
}
else
{
if (!new_filename.empty())
{
ret.erase(pos);
PathAppendString(ret, new_filename);
}
else
{
ret.erase(pos - 1);
}
}
return ret;
}
void Path::ChangeFileName(std::string* path, const std::string_view& new_filename)
{
*path = ChangeFileName(*path, new_filename);
}
std::string Path::AppendDirectory(const std::string_view& path, const std::string_view& new_dir)
{
std::string ret;
if (!new_dir.empty())
{
const std::string_view::size_type pos = GetLastSeperatorPosition(path, true);
ret.reserve(path.length() + new_dir.length() + 1);
if (pos != std::string_view::npos)
PathAppendString(ret, path.substr(0, pos));
while (!ret.empty() && ret.back() == FS_OSPATH_SEPARATOR_CHARACTER)
ret.pop_back();
if (!ret.empty())
ret += FS_OSPATH_SEPARATOR_CHARACTER;
PathAppendString(ret, new_dir);
if (pos != std::string_view::npos)
{
const std::string_view filepart(path.substr(pos));
if (!filepart.empty())
{
ret += FS_OSPATH_SEPARATOR_CHARACTER;
PathAppendString(ret, filepart);
}
}
else if (!path.empty())
{
ret += FS_OSPATH_SEPARATOR_CHARACTER;
PathAppendString(ret, path);
}
}
else
{
PathAppendString(ret, path);
}
return ret;
}
void Path::AppendDirectory(std::string* path, const std::string_view& new_dir)
{
*path = AppendDirectory(*path, new_dir);
}
std::vector<std::string_view> Path::SplitWindowsPath(const std::string_view& path)
{
std::vector<std::string_view> parts;
@ -242,9 +467,48 @@ std::vector<std::string_view> FileSystem::SplitWindowsPath(const std::string_vie
return parts;
}
std::vector<std::string_view> FileSystem::SplitNativePath(const std::string_view& path)
std::string Path::JoinWindowsPath(const std::vector<std::string_view>& components)
{
return StringUtil::SplitString(path, FS_OSPATH_SEPARATOR_CHARACTER, true);
return StringUtil::JoinString(components.begin(), components.end(), '\\');
}
std::vector<std::string_view> Path::SplitNativePath(const std::string_view& path)
{
#ifdef _WIN32
return SplitWindowsPath(path);
#else
std::vector<std::string_view> parts;
std::string::size_type start = 0;
std::string::size_type pos = 0;
while (pos < path.size())
{
if (path[pos] != '/')
{
pos++;
continue;
}
// skip consecutive separators
// for unix, we create an empty element at the beginning when it's an absolute path
// that way, when it's re-joined later, we preserve the starting slash.
if (pos != start || pos == 0)
parts.push_back(path.substr(start, pos - start));
pos++;
start = pos;
}
if (start != pos)
parts.push_back(path.substr(start));
return parts;
#endif
}
std::string Path::JoinNativePath(const std::vector<std::string_view>& components)
{
return StringUtil::JoinString(components.begin(), components.end(), FS_OSPATH_SEPARATOR_CHARACTER);
}
std::vector<std::string> FileSystem::GetRootDirectoryList()
@ -297,7 +561,7 @@ std::vector<std::string> FileSystem::GetRootDirectoryList()
return results;
}
std::string FileSystem::BuildRelativePath(const std::string_view& filename, const std::string_view& new_filename)
std::string Path::BuildRelativePath(const std::string_view& filename, const std::string_view& new_filename)
{
std::string new_string;
@ -308,10 +572,21 @@ std::string FileSystem::BuildRelativePath(const std::string_view& filename, cons
return new_string;
}
std::string FileSystem::JoinPath(const std::string_view& base, const std::string_view& next)
std::string Path::Combine(const std::string_view& base, const std::string_view& next)
{
// TODO: Rewrite this natively when wxDirName is dropped.
return Path::CombineStdString(base, next);
std::string ret;
ret.reserve(base.length() + next.length() + 1);
PathAppendString(ret, base);
while (!ret.empty() && ret.back() == FS_OSPATH_SEPARATOR_CHARACTER)
ret.pop_back();
ret += FS_OSPATH_SEPARATOR_CHARACTER;
PathAppendString(ret, next);
while (!ret.empty() && ret.back() == FS_OSPATH_SEPARATOR_CHARACTER)
ret.pop_back();
return ret;
}
#ifdef _UWP
@ -631,6 +906,49 @@ bool FileSystem::RecursiveDeleteDirectory(const char* path)
return DeleteDirectory(path);
}
bool FileSystem::CopyFilePath(const char* source, const char* destination, bool replace)
{
#ifndef _WIN32
// TODO: There's technically a race here between checking and opening the file..
// But fopen doesn't specify any way to say "don't create if it exists"...
if (!replace && FileExists(destination))
return false;
auto in_fp = OpenManagedCFile(source, "rb");
if (!in_fp)
return false;
auto out_fp = OpenManagedCFile(destination, "wb");
if (!out_fp)
return false;
u8 buf[4096];
while (!std::feof(in_fp.get()))
{
size_t bytes_in = std::fread(buf, 1, sizeof(buf), in_fp.get());
if ((bytes_in == 0 && !std::feof(in_fp.get())) ||
(bytes_in > 0 && std::fwrite(buf, 1, bytes_in, out_fp.get()) != bytes_in))
{
out_fp.reset();
DeleteFilePath(destination);
return false;
}
}
if (std::fflush(out_fp.get()) != 0)
{
out_fp.reset();
DeleteFilePath(destination);
return false;
}
return true;
#else
return CopyFileW(StringUtil::UTF8StringToWideString(source).c_str(),
StringUtil::UTF8StringToWideString(destination).c_str(), !replace);
#endif
}
#ifdef _WIN32
static u32 TranslateWin32Attributes(u32 Win32Attributes)
@ -783,6 +1101,7 @@ static u32 RecursiveFindFiles(const char* origin_path, const char* parent_path,
outData.FileName = utf8_filename;
}
outData.CreationTime = ConvertFileTimeToUnixTime(wfd.ftCreationTime);
outData.ModificationTime = ConvertFileTimeToUnixTime(wfd.ftLastWriteTime);
outData.Size = (static_cast<u64>(wfd.nFileSizeHigh) << 32) | static_cast<u64>(wfd.nFileSizeLow);
@ -904,6 +1223,7 @@ bool FileSystem::StatFile(const char* path, FILESYSTEM_STAT_DATA* sd)
// fill in the stat data
sd->Attributes = TranslateWin32Attributes(bhfi.dwFileAttributes);
sd->CreationTime = ConvertFileTimeToUnixTime(bhfi.ftCreationTime);
sd->ModificationTime = ConvertFileTimeToUnixTime(bhfi.ftLastWriteTime);
sd->Size = static_cast<s64>(((u64)bhfi.nFileSizeHigh) << 32 | (u64)bhfi.nFileSizeLow);
return true;
@ -913,6 +1233,7 @@ bool FileSystem::StatFile(const char* path, FILESYSTEM_STAT_DATA* sd)
return false;
sd->Attributes = TranslateWin32Attributes(fad.dwFileAttributes);
sd->CreationTime = ConvertFileTimeToUnixTime(fad.ftCreationTime);
sd->ModificationTime = ConvertFileTimeToUnixTime(fad.ftLastWriteTime);
sd->Size = static_cast<s64>(((u64)fad.nFileSizeHigh) << 32 | (u64)fad.nFileSizeLow);
return true;
@ -930,6 +1251,7 @@ bool FileSystem::StatFile(std::FILE* fp, FILESYSTEM_STAT_DATA* sd)
return false;
// parse attributes
sd->CreationTime = st.st_ctime;
sd->ModificationTime = st.st_mtime;
sd->Attributes = 0;
if ((st.st_mode & _S_IFMT) == _S_IFDIR)
@ -988,6 +1310,37 @@ bool FileSystem::DirectoryExists(const char* path)
return false;
}
bool FileSystem::DirectoryIsEmpty(const char* path)
{
std::wstring wpath(StringUtil::UTF8StringToWideString(path));
wpath += L"\\*";
WIN32_FIND_DATAW wfd;
#ifndef _UWP
HANDLE hFind = FindFirstFileW(wpath.c_str(), &wfd);
#else
HANDLE hFind = FindFirstFileExFromAppW(wpath.c_str(), FindExInfoBasic, &wfd, FindExSearchNameMatch, nullptr, 0);
#endif
if (hFind == INVALID_HANDLE_VALUE)
return true;
do
{
if (wfd.cFileName[0] == L'.')
{
if (wfd.cFileName[1] == L'\0' || (wfd.cFileName[1] == L'.' && wfd.cFileName[2] == L'\0'))
continue;
}
FindClose(hFind);
return false;
} while (FindNextFileW(hFind, &wfd));
FindClose(hFind);
return true;
}
bool FileSystem::CreateDirectoryPath(const char* Path, bool Recursive)
{
const std::wstring wpath(StringUtil::UTF8StringToWideString(Path));
@ -1317,6 +1670,7 @@ static u32 RecursiveFindFiles(const char* OriginPath, const char* ParentPath, co
}
outData.Size = static_cast<u64>(sDir.st_size);
outData.CreationTime = sDir.st_ctime;
outData.ModificationTime = sDir.st_mtime;
// match the filename
@ -1400,6 +1754,7 @@ bool FileSystem::StatFile(const char* path, FILESYSTEM_STAT_DATA* sd)
return false;
// parse attributes
sd->CreationTime = sysStatData.st_ctime;
sd->ModificationTime = sysStatData.st_mtime;
sd->Attributes = 0;
if (S_ISDIR(sysStatData.st_mode))
@ -1432,6 +1787,7 @@ bool FileSystem::StatFile(std::FILE* fp, FILESYSTEM_STAT_DATA* sd)
return false;
// parse attributes
sd->CreationTime = sysStatData.st_ctime;
sd->ModificationTime = sysStatData.st_mtime;
sd->Attributes = 0;
if (S_ISDIR(sysStatData.st_mode))
@ -1491,6 +1847,30 @@ bool FileSystem::DirectoryExists(const char* path)
return false;
}
bool FileSystem::DirectoryIsEmpty(const char* path)
{
DIR* pDir = opendir(path);
if (pDir == nullptr)
return true;
// iterate results
struct dirent* pDirEnt;
while ((pDirEnt = readdir(pDir)) != nullptr)
{
if (pDirEnt->d_name[0] == '.')
{
if (pDirEnt->d_name[1] == '\0' || (pDirEnt->d_name[1] == '.' && pDirEnt->d_name[2] == '\0'))
continue;
}
closedir(pDir);
return false;
}
closedir(pDir);
return true;
}
bool FileSystem::CreateDirectoryPath(const char* path, bool recursive)
{
// has a path

View File

@ -50,6 +50,7 @@ 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;
@ -57,6 +58,7 @@ struct FILESYSTEM_STAT_DATA
struct FILESYSTEM_FIND_DATA
{
std::time_t CreationTime; // actually inode change time on linux
std::time_t ModificationTime;
std::string FileName;
s64 Size;
@ -65,49 +67,11 @@ struct FILESYSTEM_FIND_DATA
namespace FileSystem
{
using FindResultsArray = std::vector<FILESYSTEM_FIND_DATA>;
/// 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 JoinPath(const std::string_view& base, const std::string_view& next);
/// 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 IsAbsolutePath(const std::string_view& path);
/// 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 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);
/// Splits a path into its components, handling both Windows and Unix separators.
std::vector<std::string_view> SplitWindowsPath(const std::string_view& path);
/// Splits a path into its components, only handling native separators.
std::vector<std::string_view> SplitNativePath(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();
@ -127,6 +91,9 @@ namespace FileSystem
/// Directory exists?
bool DirectoryExists(const char* path);
/// Directory does not contain any files?
bool DirectoryIsEmpty(const char* path);
/// Delete file
bool DeleteFilePath(const char* path);
@ -166,6 +133,9 @@ namespace FileSystem
/// 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();

View File

@ -17,226 +17,68 @@
#include "common/Pcsx2Defs.h"
#include <wx/filename.h>
#include <string>
#include <string_view>
#include <vector>
#include "ghc/filesystem.h"
namespace fs = ghc::filesystem;
#define g_MaxPath 255 // 255 is safer with antiquated Win32 ASCII APIs.
// --------------------------------------------------------------------------------------
// wxDirName
// --------------------------------------------------------------------------------------
class wxDirName : protected wxFileName
{
public:
explicit wxDirName(const wxFileName& src)
{
Assign(src.GetPath(), wxEmptyString);
}
wxDirName()
: wxFileName()
{
}
wxDirName(const wxDirName& src)
: wxFileName(src)
{
}
explicit wxDirName(const char* src) { Assign(wxString(src, wxMBConvUTF8())); }
explicit wxDirName(const wxString& src) { Assign(src); }
// ------------------------------------------------------------------------
void Assign(const wxString& volume, const wxString& path)
{
wxFileName::Assign(volume, path, wxEmptyString);
}
void Assign(const wxString& path)
{
wxFileName::Assign(path, wxEmptyString);
}
void Assign(const wxDirName& path)
{
wxFileName::Assign(path);
}
void Clear() { wxFileName::Clear(); }
wxCharBuffer ToUTF8() const { return GetPath().ToUTF8(); }
wxCharBuffer ToAscii() const { return GetPath().ToAscii(); }
wxString ToString() const { return GetPath(); }
// ------------------------------------------------------------------------
bool IsWritable() const { return IsDirWritable(); }
bool IsReadable() const { return IsDirReadable(); }
bool Exists() const { return DirExists(); }
bool FileExists() const { return wxFileName::FileExists(); }
bool IsOk() const { return wxFileName::IsOk(); }
bool IsRelative() const { return wxFileName::IsRelative(); }
bool IsAbsolute() const { return wxFileName::IsAbsolute(); }
bool SameAs(const wxDirName& filepath) const
{
return wxFileName::SameAs(filepath);
}
//Returns true if the file is somewhere inside this directory (and both file and directory are not relative).
bool IsContains(const wxFileName& file) const
{
if (this->IsRelative() || file.IsRelative())
return false;
wxFileName f(file);
while (1)
{
if (this->SameAs(wxDirName(f.GetPath())))
return true;
if (f.GetDirCount() == 0)
return false;
f.RemoveLastDir();
}
return false;
}
bool IsContains(const wxDirName& dir) const
{
return IsContains((wxFileName)dir);
}
//Auto relative works as follows:
// 1. if either base or subject are relative, return subject (should never be used with relative paths).
// 2. else if subject is somewhere inside base folder, then result is subject relative to base.
// 3. (windows only, implicitly) else if subject is on the same driveletter as base, result is absolute path of subject without the driveletter.
// 4. else, result is absolute path of subject.
//
// returns ok if both this and base are absolute paths.
static wxString MakeAutoRelativeTo(const wxFileName _subject, const wxString& pathbase)
{
wxFileName subject(_subject);
wxDirName base(pathbase);
if (base.IsRelative() || subject.IsRelative())
return subject.GetFullPath();
wxString bv(base.GetVolume());
bv.MakeUpper();
wxString sv(subject.GetVolume());
sv.MakeUpper();
if (base.IsContains(subject))
{
subject.MakeRelativeTo(base.GetFullPath());
}
else if (base.HasVolume() && subject.HasVolume() && bv == sv)
{
wxString unusedVolume;
wxString pathSansVolume;
subject.SplitVolume(subject.GetFullPath(), &unusedVolume, &pathSansVolume);
subject = pathSansVolume;
}
//implicit else: this stays fully absolute
return subject.GetFullPath();
}
static wxString MakeAutoRelativeTo(const wxDirName subject, const wxString& pathbase)
{
return MakeAutoRelativeTo(wxFileName(subject), pathbase);
}
// Returns the number of sub folders in this directory path
size_t GetCount() const { return GetDirCount(); }
// ------------------------------------------------------------------------
wxFileName Combine(const wxFileName& right) const;
wxDirName Combine(const wxDirName& right) const;
// removes the lastmost directory from the path
void RemoveLast() { wxFileName::RemoveDir(GetCount() - 1); }
wxDirName& Normalize(int flags = wxPATH_NORM_ALL, const wxString& cwd = wxEmptyString);
wxDirName& MakeRelativeTo(const wxString& pathBase = wxEmptyString);
wxDirName& MakeAbsolute(const wxString& cwd = wxEmptyString);
// ------------------------------------------------------------------------
void AssignCwd(const wxString& volume = wxEmptyString) { wxFileName::AssignCwd(volume); }
bool SetCwd() { return wxFileName::SetCwd(); }
// wxWidgets is missing the const qualifier for this one! Shame!
void Rmdir() const;
bool Mkdir() const;
// ------------------------------------------------------------------------
wxDirName& operator=(const wxDirName& dirname)
{
Assign(dirname);
return *this;
}
wxDirName& operator=(const wxString& dirname)
{
Assign(dirname);
return *this;
}
wxDirName& operator=(const char* dirname)
{
Assign(wxString(dirname, wxMBConvUTF8()));
return *this;
}
wxFileName operator+(const wxFileName& right) const { return Combine(right); }
wxDirName operator+(const wxDirName& right) const { return Combine(right); }
wxFileName operator+(const wxString& right) const { return Combine(wxFileName(right)); }
wxFileName operator+(const char* right) const { return Combine(wxFileName(wxString(right, wxMBConvUTF8()))); }
bool operator==(const wxDirName& filename) const { return SameAs(filename); }
bool operator!=(const wxDirName& filename) const { return !SameAs(filename); }
bool operator==(const wxFileName& filename) const { return SameAs(wxDirName(filename)); }
bool operator!=(const wxFileName& filename) const { return !SameAs(wxDirName(filename)); }
// compare with a filename string interpreted as a native file name
bool operator==(const wxString& filename) const { return SameAs(wxDirName(filename)); }
bool operator!=(const wxString& filename) const { return !SameAs(wxDirName(filename)); }
const wxFileName& GetFilename() const { return *this; }
wxFileName& GetFilename() { return *this; }
};
// --------------------------------------------------------------------------------------
// Path Namespace
// --------------------------------------------------------------------------------------
// Cross-platform utilities for manipulation of paths and filenames. Mostly these fall
// back on wxWidgets APIs internally, but are still helpful because some of wx's file stuff
// has minor glitches, or requires sloppy wxFileName typecasting.
//
namespace Path
{
extern bool IsRelative(const wxString& path);
extern s64 GetFileSize(const wxString& path);
/// Converts any forward slashes to backslashes on Win32.
std::string ToNativePath(const std::string_view& path);
void ToNativePath(std::string* path);
extern wxString Normalize(const wxString& srcpath);
extern wxString Normalize(const wxDirName& srcpath);
extern wxString MakeAbsolute(const wxString& srcpath);
/// Builds a path relative to the specified file
std::string BuildRelativePath(const std::string_view& filename, const std::string_view& new_filename);
extern wxString Combine(const wxString& srcPath, const wxString& srcFile);
extern wxString Combine(const wxDirName& srcPath, const wxFileName& srcFile);
extern wxString Combine(const wxString& srcPath, const wxDirName& srcFile);
extern std::string CombineStdString(const wxDirName& srcPath, const std::string_view& srcFile);
extern std::string CombineStdString(const std::string_view& srcPath, const std::string_view& srcFile);
extern wxString ReplaceExtension(const wxString& src, const wxString& ext);
extern wxString ReplaceFilename(const wxString& src, const wxString& newfilename);
extern wxString GetFilename(const wxString& src);
extern wxString GetDirectory(const wxString& src);
extern wxString GetFilenameWithoutExt(const wxString& src);
extern wxString GetRootDirectory(const wxString& src);
extern fs::path FromWxString(const wxString& path);
/// 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

@ -31,5 +31,6 @@
#include <VersionHelpers.h>
#include <ShTypes.h>
#include <timeapi.h>
#include <tchar.h>
#endif

View File

@ -223,6 +223,14 @@ namespace StringUtil
return newStr;
}
std::string toUpper(const std::string_view& input)
{
std::string newStr;
std::transform(input.begin(), input.end(), std::back_inserter(newStr),
[](unsigned char c) { return std::toupper(c); });
return newStr;
}
bool compareNoCase(const std::string_view& str1, const std::string_view& str2)
{
if (str1.length() != str2.length())
@ -304,6 +312,21 @@ namespace StringUtil
return res;
}
std::string ReplaceAll(const std::string_view& subject, const std::string_view& search, const std::string_view& replacement)
{
std::string ret(subject);
if (!ret.empty())
{
std::string::size_type start_pos = 0;
while ((start_pos = ret.find(search, start_pos)) != std::string::npos)
{
ret.replace(start_pos, search.length(), replacement);
start_pos += replacement.length();
}
}
return ret;
}
bool ParseAssignmentString(const std::string_view& str, std::string_view* key, std::string_view* value)
{
const std::string_view::size_type pos = str.find('=');
@ -342,6 +365,7 @@ namespace StringUtil
}
}
#ifdef _WIN32
std::wstring UTF8StringToWideString(const std::string_view& str)
{
std::wstring ret;
@ -353,7 +377,6 @@ namespace StringUtil
bool UTF8StringToWideString(std::wstring& dest, const std::string_view& str)
{
#ifdef _WIN32
int wlen = MultiByteToWideChar(CP_UTF8, 0, str.data(), static_cast<int>(str.length()), nullptr, 0);
if (wlen < 0)
return false;
@ -363,22 +386,6 @@ namespace StringUtil
return false;
return true;
#else
// This depends on wxString, which isn't great. But hopefully we won't need any wide strings outside
// of windows once wx is gone anyway.
if (str.empty())
{
dest.clear();
return true;
}
const wxString wxstr(wxString::FromUTF8(str.data(), str.length()));
if (wxstr.IsEmpty())
return false;
dest = wxstr.ToStdWstring();
return true;
#endif
}
std::string WideStringToUTF8String(const std::wstring_view& str)
@ -392,7 +399,6 @@ namespace StringUtil
bool WideStringToUTF8String(std::string& dest, const std::wstring_view& str)
{
#ifdef _WIN32
int mblen = WideCharToMultiByte(CP_UTF8, 0, str.data(), static_cast<int>(str.length()), nullptr, 0, nullptr, nullptr);
if (mblen < 0)
return false;
@ -405,24 +411,8 @@ namespace StringUtil
}
return true;
#else
// This depends on wxString, which isn't great. But hopefully we won't need any wide strings outside
// of windows once wx is gone anyway.
if (str.empty())
{
dest.clear();
return true;
}
const wxString wxstr(str.data(), str.data() + str.length());
if (wxstr.IsEmpty())
return false;
const auto buf = wxstr.ToUTF8();
dest.assign(buf.data(), buf.length());
return true;
#endif
}
#endif
std::string U128ToString(const u128& u)
{

View File

@ -33,9 +33,6 @@
#include <sstream>
#endif
// TODO: Remove me once wx is gone.
#include <wx/string.h>
namespace StringUtil
{
/// Constructs a std::string from a format string.
@ -143,25 +140,25 @@ namespace StringUtil
std::string EncodeHex(const u8* data, int length);
/// starts_with from C++20
static inline bool StartsWith(const std::string_view& str, const char* prefix)
static inline bool StartsWith(const std::string_view& str, const std::string_view& prefix)
{
return (str.compare(0, std::strlen(prefix), prefix) == 0);
return (str.compare(0, prefix.length(), prefix) == 0);
}
static inline bool EndsWith(const std::string_view& str, const char* suffix)
static inline bool EndsWith(const std::string_view& str, const std::string_view& suffix)
{
const std::size_t suffix_length = std::strlen(suffix);
const std::size_t suffix_length = suffix.length();
return (str.length() >= suffix_length && str.compare(str.length() - suffix_length, suffix_length, suffix) == 0);
}
/// StartsWith/EndsWith variants which aren't case sensitive.
static inline bool StartsWithNoCase(const std::string_view& str, const char* prefix)
static inline bool StartsWithNoCase(const std::string_view& str, const std::string_view& prefix)
{
return (Strncasecmp(str.data(), prefix, std::strlen(prefix)) == 0);
return (!str.empty() && Strncasecmp(str.data(), prefix.data(), prefix.length()) == 0);
}
static inline bool EndsWithNoCase(const std::string_view& str, const char* suffix)
static inline bool EndsWithNoCase(const std::string_view& str, const std::string_view& suffix)
{
const std::size_t suffix_length = std::strlen(suffix);
return (str.length() >= suffix_length && Strncasecmp(str.data() + (str.length() - suffix_length), suffix, suffix_length) == 0);
const std::size_t suffix_length = suffix.length();
return (str.length() >= suffix_length && Strncasecmp(str.data() + (str.length() - suffix_length), suffix.data(), suffix_length) == 0);
}
/// Strip whitespace from the start/end of the string.
@ -171,6 +168,35 @@ namespace StringUtil
/// Splits a string based on a single character delimiter.
std::vector<std::string_view> SplitString(const std::string_view& str, char delimiter, bool skip_empty = true);
/// Joins a string together using the specified delimiter.
template<typename T>
static inline std::string JoinString(const T& start, const T& end, char delimiter)
{
std::string ret;
for (auto it = start; it != end; ++it)
{
if (it != start)
ret += delimiter;
ret.append(*it);
}
return ret;
}
template <typename T>
static inline std::string JoinString(const T& start, const T& end, const std::string_view& delimiter)
{
std::string ret;
for (auto it = start; it != end; ++it)
{
if (it != start)
ret.append(delimiter);
ret.append(*it);
}
return ret;
}
/// Replaces all instances of search in subject with replacement.
std::string ReplaceAll(const std::string_view& subject, const std::string_view& search, const std::string_view& replacement);
/// Parses an assignment string (Key = Value) into its two components.
bool ParseAssignmentString(const std::string_view& str, std::string_view* key, std::string_view* value);
@ -218,28 +244,11 @@ namespace StringUtil
}
std::string toLower(const std::string_view& str);
std::string toUpper(const std::string_view& str);
bool compareNoCase(const std::string_view& str1, const std::string_view& str2);
std::vector<std::string> splitOnNewLine(const std::string& str);
/// Converts a wxString to a UTF-8 std::string.
static inline std::string wxStringToUTF8String(const wxString& str)
{
const wxScopedCharBuffer buf(str.ToUTF8());
return std::string(buf.data(), buf.length());
}
/// Converts a UTF-8 std::string to a wxString.
static inline wxString UTF8StringToWxString(const std::string_view& str)
{
return wxString::FromUTF8(str.data(), str.length());
}
/// Converts a UTF-8 std::string to a wxString.
static inline wxString UTF8StringToWxString(const std::string& str)
{
return wxString::FromUTF8(str.data(), str.length());
}
#ifdef _WIN32
/// Converts the specified UTF-8 string to a wide string.
std::wstring UTF8StringToWideString(const std::string_view& str);
bool UTF8StringToWideString(std::wstring& dest, const std::string_view& str);
@ -247,6 +256,7 @@ namespace StringUtil
/// Converts the specified wide string to a UTF-8 string.
std::string WideStringToUTF8String(const std::wstring_view& str);
bool WideStringToUTF8String(std::string& dest, const std::wstring_view& str);
#endif
/// Converts unsigned 128-bit data to string.
std::string U128ToString(const u128& u);

View File

@ -82,7 +82,6 @@
<ClCompile Include="Vulkan\Texture.cpp" />
<ClCompile Include="Vulkan\Util.cpp" />
<ClCompile Include="WindowInfo.cpp" />
<ClCompile Include="PathUtils.cpp" />
<ClCompile Include="Perf.cpp" />
<ClCompile Include="PrecompiledHeader.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
@ -204,12 +203,9 @@
<ProjectReference Include="..\3rdparty\glslang\glslang.vcxproj">
<Project>{ef6834a9-11f3-4331-bc34-21b325abb180}</Project>
</ProjectReference>
<ProjectReference Include="..\3rdparty\wxwidgets3.0\build\msw\wx30_base.vcxproj">
<Project>{3fcc50c2-81e9-5db2-b8d8-2129427568b1}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup>
</Project>
</Project>

View File

@ -49,9 +49,6 @@
<ClCompile Include="Misc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="PathUtils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Perf.cpp">
<Filter>Source Files</Filter>
</ClCompile>

View File

@ -15,19 +15,24 @@
#ifndef _WIN32
#include "common/emitter/cpudetect_internal.h"
#include <wx/thread.h>
#include <unistd.h>
// Note: Apparently this solution is Linux/Solaris only.
// FreeBSD/OsX need something far more complicated (apparently)
void x86capabilities::CountLogicalCores()
{
#ifdef __linux__
// Note : GetCPUCount uses sysconf( _SC_NPROCESSORS_ONLN ) internally, which can return 1
// if sysconf info isn't available (a long standing linux bug). There are no fallbacks or
// alternatives, apparently.
LogicalCores = wxThread::GetCPUCount();
LogicalCores = sysconf(_SC_NPROCESSORS_ONLN);
#else
LogicalCores = 1;
#endif
}
// Not implemented yet for linux (see cpudetect_internal.h for details)
SingleCoreAffinity::SingleCoreAffinity() = default;
SingleCoreAffinity::~SingleCoreAffinity() = default;
#endif
#endif

View File

@ -10,7 +10,7 @@
<ItemDefinitionGroup>
<ClCompile>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(SolutionDir);$(SolutionDir)\3rdparty\wxWidgets3.0\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>__WIN32__;WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;WINVER=0x0603;_WIN32_WINNT=0x0603;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StructMemberAlignment>16Bytes</StructMemberAlignment>
<FunctionLevelLinking>true</FunctionLevelLinking>

View File

@ -666,7 +666,7 @@ HostDisplay* EmuThread::acquireHostDisplay(HostDisplay::RenderAPI api)
return nullptr;
}
if (!s_host_display->InitializeRenderDevice(StringUtil::wxStringToUTF8String(EmuFolders::Cache.ToString()), false) ||
if (!s_host_display->InitializeRenderDevice(EmuFolders::Cache, false) ||
!ImGuiManager::Initialize())
{
Console.Error("Failed to initialize device/imgui");

View File

@ -17,6 +17,7 @@
#include "GameListModel.h"
#include "common/FileSystem.h"
#include "common/Path.h"
#include "common/StringUtil.h"
#include <QtCore/QDate>
#include <QtCore/QDateTime>
@ -201,7 +202,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()));
}
@ -240,7 +241,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()));
}
@ -415,8 +416,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);
@ -474,7 +475,7 @@ void GameListModel::loadCommonImages()
for (u32 i = 1; i < GameList::CompatibilityRatingCount; i++)
m_compatibiliy_pixmaps[i].load(QStringLiteral(":/icons/star-%1.png").arg(i - 1));
m_placeholder_pixmap.load(QString::fromStdString(Path::CombineStdString(EmuFolders::Resources, "cover-placeholder.png")));
m_placeholder_pixmap.load(QString::fromStdString(Path::Combine(EmuFolders::Resources, "cover-placeholder.png")));
}
void GameListModel::setColumnDisplayNames()

View File

@ -1143,7 +1143,7 @@ void MainWindow::startupUpdateCheck()
void MainWindow::onToolsOpenDataDirectoryTriggered()
{
const QString path(QtUtils::WxStringToQString(EmuFolders::DataRoot.ToString()));
const QString path(QString::fromStdString(EmuFolders::DataRoot));
QtUtils::OpenURL(this, QUrl::fromLocalFile(path));
}

View File

@ -30,6 +30,7 @@
#include "common/Console.h"
#include "common/CrashHandler.h"
#include "common/FileSystem.h"
#include "common/Path.h"
#include "common/SettingsWrapper.h"
#include "common/StringUtil.h"
@ -108,20 +109,19 @@ void QtHost::Shutdown()
bool QtHost::SetCriticalFolders()
{
std::string program_path(FileSystem::GetProgramPath());
EmuFolders::AppRoot = wxDirName(wxFileName(StringUtil::UTF8StringToWxString(program_path)));
EmuFolders::AppRoot = Path::Canonicalize(Path::GetDirectory(FileSystem::GetProgramPath()));
SetResourcesDirectory();
SetDataDirectory();
// allow SetDataDirectory() to change settings directory (if we want to split config later on)
if (!EmuFolders::Settings.IsOk())
EmuFolders::Settings = EmuFolders::DataRoot.Combine(wxDirName(L"inis"));
if (EmuFolders::Settings.empty())
EmuFolders::Settings = Path::Combine(EmuFolders::DataRoot, "inis");
// Write crash dumps to the data directory, since that'll be accessible for certain.
CrashHandler::SetWriteDirectory(EmuFolders::DataRoot.ToUTF8().data());
CrashHandler::SetWriteDirectory(EmuFolders::DataRoot);
// the resources directory should exist, bail out if not
if (!EmuFolders::Resources.Exists())
if (!FileSystem::DirectoryExists(EmuFolders::Resources.c_str()))
{
QMessageBox::critical(nullptr, QStringLiteral("Error"),
QStringLiteral("Resources directory is missing, your installation is incomplete."));
@ -134,17 +134,17 @@ bool QtHost::SetCriticalFolders()
bool QtHost::ShouldUsePortableMode()
{
// Check whether portable.ini exists in the program directory.
return FileSystem::FileExists(Path::CombineStdString(EmuFolders::AppRoot, "portable.ini").c_str());
return FileSystem::FileExists(Path::Combine(EmuFolders::AppRoot, "portable.ini").c_str());
}
void QtHost::SetResourcesDirectory()
{
#ifndef __APPLE__
// On Windows/Linux, these are in the binary directory.
EmuFolders::Resources = EmuFolders::AppRoot.Combine(wxDirName(L"resources"));
EmuFolders::Resources = Path::Combine(EmuFolders::AppRoot, "resources");
#else
// On macOS, this is in the bundle resources directory.
EmuFolders::Resources = EmuFolders::AppRoot.Combine(wxDirName("../Resources"));
EmuFolders::Resources = Path::Canonicalize(Path::Combine(EmuFolders::AppRoot, "../Resources"));
#endif
}
@ -162,16 +162,16 @@ void QtHost::SetDataDirectory()
if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_Documents, 0, NULL, &documents_directory)))
{
if (std::wcslen(documents_directory) > 0)
EmuFolders::DataRoot = wxDirName(Path::Combine(wxString(documents_directory), L"PCSX2"));
EmuFolders::DataRoot = Path::Combine(StringUtil::WideStringToUTF8String(documents_directory), "PCSX2");
CoTaskMemFree(documents_directory);
}
#elif defined(__linux__)
// Check for $HOME/PCSX2 first, for legacy installs.
const char* home_dir = getenv("HOME");
const std::string legacy_dir(home_dir ? Path::CombineStdString(home_dir, "PCSX2") : std::string());
const std::string legacy_dir(home_dir ? Path::Combine(home_dir, "PCSX2") : std::string());
if (!legacy_dir.empty() && FileSystem::DirectoryExists(legacy_dir.c_str()))
{
EmuFolders::DataRoot = wxDirName(StringUtil::UTF8StringToWxString(legacy_dir));
EmuFolders::DataRoot = std::move(legacy_dir);
}
else
{
@ -179,31 +179,31 @@ void QtHost::SetDataDirectory()
const char* xdg_config_home = getenv("XDG_CONFIG_HOME");
if (xdg_config_home && xdg_config_home[0] == '/' && FileSystem::DirectoryExists(xdg_config_home))
{
EmuFolders::DataRoot = wxDirName(StringUtil::UTF8StringToWxString(Path::CombineStdString(xdg_config_home, "PCSX2")));
EmuFolders::DataRoot = Path::Combine(xdg_config_home, "PCSX2");
}
else if (!legacy_dir.empty())
{
// fall back to the legacy PCSX2-in-home.
EmuFolders::DataRoot = wxDirName(StringUtil::UTF8StringToWxString(legacy_dir));
EmuFolders::DataRoot = std::move(legacy_dir);
}
}
#elif defined(__APPLE__)
static constexpr char MAC_DATA_DIR[] = "Library/Application Support/PCSX2";
const char* home_dir = getenv("HOME");
if (home_dir)
EmuFolders::DataRoot = wxDirName(StringUtil::UTF8StringToWxString(Path::CombineStdString(home_dir, MAC_DATA_DIR)));
EmuFolders::DataRoot = Path::Combine(home_dir, MAC_DATA_DIR);
#endif
// make sure it exists
if (EmuFolders::DataRoot.IsOk() && !EmuFolders::DataRoot.Exists())
if (!EmuFolders::DataRoot.empty() && !FileSystem::DirectoryExists(EmuFolders::DataRoot.c_str()))
{
// we're in trouble if we fail to create this directory... but try to hobble on with portable
if (!EmuFolders::DataRoot.Mkdir())
EmuFolders::DataRoot.Clear();
if (!FileSystem::CreateDirectoryPath(EmuFolders::DataRoot.c_str(), false))
EmuFolders::DataRoot.clear();
}
// couldn't determine the data directory? fallback to portable.
if (!EmuFolders::DataRoot.IsOk())
if (EmuFolders::DataRoot.empty())
EmuFolders::DataRoot = EmuFolders::AppRoot;
}
@ -220,7 +220,7 @@ bool QtHost::InitializeConfig()
if (!SetCriticalFolders())
return false;
const std::string path(Path::CombineStdString(EmuFolders::Settings, "PCSX2.ini"));
const std::string path(Path::Combine(EmuFolders::Settings, "PCSX2.ini"));
s_base_settings_interface = std::make_unique<INISettingsInterface>(std::move(path));
Host::Internal::SetBaseSettingsLayer(s_base_settings_interface.get());
@ -437,7 +437,7 @@ QString QtHost::GetAppConfigSuffix()
std::optional<std::vector<u8>> Host::ReadResourceFile(const char* filename)
{
const std::string path(Path::CombineStdString(EmuFolders::Resources, filename));
const std::string path(Path::Combine(EmuFolders::Resources, filename));
std::optional<std::vector<u8>> ret(FileSystem::ReadBinaryFile(path.c_str()));
if (!ret.has_value())
Console.Error("Failed to read resource file '%s'", filename);
@ -446,7 +446,7 @@ std::optional<std::vector<u8>> Host::ReadResourceFile(const char* filename)
std::optional<std::string> Host::ReadResourceFileToString(const char* filename)
{
const std::string path(Path::CombineStdString(EmuFolders::Resources, filename));
const std::string path(Path::Combine(EmuFolders::Resources, filename));
std::optional<std::string> ret(FileSystem::ReadFileToString(path.c_str()));
if (!ret.has_value())
Console.Error("Failed to read resource file to string '%s'", filename);

View File

@ -690,15 +690,4 @@ namespace QtUtils
{
return str.empty() ? QString() : QString::fromUtf8(str.data(), str.size());
}
wxString QStringToWxString(const QString& str)
{
return wxString(str.toStdWString());
}
QString WxStringToQString(const wxString& str)
{
return QString::fromStdWString(str.ToStdWstring());
}
} // namespace QtUtils

View File

@ -34,9 +34,6 @@ class QVariant;
class QWidget;
class QUrl;
// TODO: Get rid of wx interoperability later on.
#include <wx/string.h>
namespace QtUtils
{
/// Marks an action as the "default" - i.e. makes the text bold.
@ -79,8 +76,4 @@ namespace QtUtils
/// Converts a std::string_view to a QString safely.
QString StringViewToQString(const std::string_view& str);
// TODO: Get rid of wx interoperability later on.
wxString QStringToWxString(const QString& str);
QString WxStringToQString(const wxString& str);
} // namespace QtUtils

View File

@ -105,7 +105,7 @@ void BIOSSettingsWidget::openSearchDirectory()
void BIOSSettingsWidget::updateSearchDirectory()
{
// this will generate a full path
m_ui.searchDirectory->setText(QtUtils::WxStringToQString(EmuFolders::Bios.ToString()));
m_ui.searchDirectory->setText(QString::fromStdString(EmuFolders::Bios));
}
void BIOSSettingsWidget::listRefreshed(const QVector<BIOSInfo>& items)

View File

@ -16,6 +16,7 @@
#include "PrecompiledHeader.h"
#include "common/FileSystem.h"
#include "common/Path.h"
#include "common/StringUtil.h"
#include <QtWidgets/QMessageBox>
@ -127,7 +128,7 @@ void CreateMemoryCardDialog::createCard()
#ifdef _WIN32
if (m_ui.ntfsCompression->isChecked() && m_type == MemoryCardType::File)
{
const std::string fullPath(Path::CombineStdString(EmuFolders::MemoryCards, nameStr));
const std::string fullPath(Path::Combine(EmuFolders::MemoryCards, nameStr));
FileSystem::SetPathCompression(fullPath.c_str(), true);
}
#endif

View File

@ -605,21 +605,21 @@ void DEV9SettingsWidget::onHddFileEdit()
{
//Check if file exists, if so set HddSize to correct value
//GHC uses UTF8 on all platforms
fs::path hddPath(m_ui.hddFile->text().toUtf8().constData());
ghc::filesystem::path hddPath(m_ui.hddFile->text().toUtf8().constData());
if (hddPath.empty())
return;
if (hddPath.is_relative())
{
fs::path path(EmuFolders::Settings.ToString().wx_str());
ghc::filesystem::path path(EmuFolders::Settings);
hddPath = path / hddPath;
}
if (!fs::exists(hddPath))
if (!ghc::filesystem::exists(hddPath))
return;
const uintmax_t size = fs::file_size(hddPath);
const uintmax_t size = ghc::filesystem::file_size(hddPath);
const u32 sizeSectors = (size / 512);
const int sizeGB = size / 1024 / 1024 / 1024;
@ -655,7 +655,7 @@ void DEV9SettingsWidget::onHddSizeSpin(int i)
void DEV9SettingsWidget::onHddCreateClicked()
{
//Do the thing
fs::path hddPath(m_ui.hddFile->text().toUtf8().constData());
ghc::filesystem::path hddPath(m_ui.hddFile->text().toUtf8().constData());
u64 sizeBytes = (u64)m_dialog->getEffectiveIntValue("DEV9/Hdd", "HddSizeSectors", 0) * 512;
if (sizeBytes == 0 || hddPath.empty())
@ -669,11 +669,11 @@ void DEV9SettingsWidget::onHddCreateClicked()
if (hddPath.is_relative())
{
//Note, EmuFolders is still wx strings
fs::path path(EmuFolders::Settings.ToString().wx_str());
ghc::filesystem::path path(EmuFolders::Settings);
hddPath = path / hddPath;
}
if (fs::exists(hddPath))
if (ghc::filesystem::exists(hddPath))
{
//GHC uses UTF8 on all platforms
QMessageBox::StandardButton selection =
@ -685,7 +685,7 @@ void DEV9SettingsWidget::onHddCreateClicked()
if (selection == QMessageBox::No)
return;
else
fs::remove(hddPath);
ghc::filesystem::remove(hddPath);
}
HddCreateQt hddCreator(this);

View File

@ -16,6 +16,7 @@
#include "PrecompiledHeader.h"
#include "common/FileSystem.h"
#include "common/Path.h"
#include "common/StringUtil.h"
#include "pcsx2/Frontend/GameList.h"
#include "pcsx2/Frontend/INISettingsInterface.h"
@ -427,13 +428,13 @@ void SettingsDialog::openGamePropertiesDialog(const GameList::Entry* game, u32 c
}
std::unique_ptr<INISettingsInterface> sif =
std::make_unique<INISettingsInterface>(Path::CombineStdString(EmuFolders::GameSettings, StringUtil::StdStringFromFormat("%08X.ini", crc)));
std::make_unique<INISettingsInterface>(Path::Combine(EmuFolders::GameSettings, StringUtil::StdStringFromFormat("%08X.ini", crc)));
if (FileSystem::FileExists(sif->GetFileName().c_str()))
sif->Load();
const QString window_title(tr("%1 [%2]")
.arg(game ? QtUtils::StringViewToQString(game->title) : QStringLiteral("<UNKNOWN>"))
.arg(QtUtils::StringViewToQString(FileSystem::GetFileNameFromPath(sif->GetFileName()))));
.arg(QtUtils::StringViewToQString(Path::GetFileName(sif->GetFileName()))));
SettingsDialog* dialog = new SettingsDialog(std::move(sif), game, crc);
dialog->setWindowTitle(window_title);

View File

@ -79,16 +79,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ResourceCompile Include="$(SolutionDir)3rdparty\wxwidgets3.0\include\wx\msw\wx.rc">
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\wxwidgets3.0\$(PlatformName);$(SolutionDir)3rdparty\wxwidgets3.0\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
<ResourceCompile Include="..\pcsx2\PCSX2.rc" />
<ResourceCompile Include="..\pcsx2\GS\GS.rc" />
<ResourceCompile Include="..\pcsx2\PAD\Windows\PAD.rc" />
<ResourceCompile Include="..\pcsx2\SPU2\Windows\SPU2.rc" />
<ResourceCompile Include="..\pcsx2\USB\usb-pad\dx\versionproxy.rc" />
<ResourceCompile Include="..\pcsx2\USB\usb-pad\raw\raw-config.rc" />
<ResourceCompile Include="..\pcsx2\USB\Win32\USBDialog.rc" />
<ResourceCompile Include="..\pcsx2\windows\wxResources.rc" />
</ItemGroup>
<ItemGroup>
@ -110,9 +101,6 @@
<ProjectReference Include="$(SolutionDir)3rdparty\soundtouch\SoundTouch.vcxproj">
<Project>{e9b51944-7e6d-4bcd-83f2-7bbd5a46182d}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)3rdparty\wxwidgets3.0\build\msw\wx30_base.vcxproj">
<Project>{3fcc50c2-81e9-5db2-b8d8-2129427568b1}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)3rdparty\xz\liblzma.vcxproj">
<Project>{12728250-16ec-4dc6-94d7-e21dd88947f8}</Project>
</ProjectReference>
@ -123,10 +111,6 @@
<Project>{2f6c0388-20cb-4242-9f6c-a6ebb6a83f47}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)tools\bin2cpp\bin2c.vcxproj">
<Project>{677b7d11-d5e1-40b3-88b1-9a4df83d2213}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)3rdparty\jpgd\jpgd.vcxproj">
<Project>{ed2f21fd-0a36-4a8f-9b90-e7d92a2acb63}</Project>
</ProjectReference>

View File

@ -15,30 +15,9 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="$(SolutionDir)3rdparty\wxwidgets3.0\include\wx\msw\wx.rc">
<Filter>Resources</Filter>
</ResourceCompile>
<ResourceCompile Include="..\pcsx2\GS\GS.rc">
<Filter>Resources</Filter>
</ResourceCompile>
<ResourceCompile Include="..\pcsx2\PAD\Windows\PAD.rc">
<Filter>Resources</Filter>
</ResourceCompile>
<ResourceCompile Include="..\pcsx2\PCSX2.rc">
<Filter>Resources</Filter>
</ResourceCompile>
<ResourceCompile Include="..\pcsx2\USB\usb-pad\raw\raw-config.rc">
<Filter>Resources</Filter>
</ResourceCompile>
<ResourceCompile Include="..\pcsx2\SPU2\Windows\SPU2.rc">
<Filter>Resources</Filter>
</ResourceCompile>
<ResourceCompile Include="..\pcsx2\USB\Win32\USBDialog.rc">
<Filter>Resources</Filter>
</ResourceCompile>
<ResourceCompile Include="..\pcsx2\USB\usb-pad\dx\versionproxy.rc">
<Filter>Resources</Filter>
</ResourceCompile>
<ResourceCompile Include="..\pcsx2\windows\wxResources.rc">
<Filter>Resources</Filter>
</ResourceCompile>

View File

@ -19,11 +19,12 @@
#include "IopHw.h"
#include "IopDma.h"
#include <cctype>
#include <ctime>
#include <memory>
#include <ctype.h>
#include <wx/datetime.h>
#include "common/FileSystem.h"
#include "common/Path.h"
#include "common/StringUtil.h"
#include "common/Threading.h"
@ -128,7 +129,7 @@ static int mg_BIToffset(u8* buffer)
static void cdvdGetMechaVer(u8* ver)
{
std::string mecfile(FileSystem::ReplaceExtension(BiosPath, "mec"));
std::string mecfile(Path::ReplaceExtension(BiosPath, "mec"));
auto fp = FileSystem::OpenManagedCFile(mecfile.c_str(), "rb");
if (!fp || FileSystem::FSize64(fp.get()) < 4)
{
@ -188,7 +189,7 @@ static void cdvdCreateNewNVM(std::FILE* fp)
static void cdvdNVM(u8* buffer, int offset, size_t bytes, bool read)
{
std::string nvmfile(FileSystem::ReplaceExtension(BiosPath, "nvm"));
std::string nvmfile(Path::ReplaceExtension(BiosPath, "nvm"));
auto fp = FileSystem::OpenManagedCFile(nvmfile.c_str(), "r+b");
if (!fp || FileSystem::FSize64(fp.get()) < 1024)
{
@ -852,28 +853,25 @@ void cdvdReset()
cdvd.RTC.year = 20;
}
else
#endif
{
// CDVD internally uses GMT+9. If you think the time's wrong, you're wrong.
// Set up your time zone and winter/summer in the BIOS. No PS2 BIOS I know of features automatic DST.
wxDateTime curtime(wxDateTime::GetTimeNow());
cdvd.RTC.second = (u8)curtime.GetSecond();
cdvd.RTC.minute = (u8)curtime.GetMinute();
cdvd.RTC.hour = (u8)curtime.GetHour(wxDateTime::GMT9);
cdvd.RTC.day = (u8)curtime.GetDay(wxDateTime::GMT9);
cdvd.RTC.month = (u8)curtime.GetMonth(wxDateTime::GMT9) + 1; // WX returns Jan as "0"
cdvd.RTC.year = (u8)(curtime.GetYear(wxDateTime::GMT9) - 2000);
}
const std::time_t utc_time = std::time(nullptr);
const std::time_t gmt9_time = (utc_time + (60 * 60 * 9));
struct tm curtime = {};
#ifdef _MSC_VER
gmtime_s(&curtime, &gmt9_time);
#else
// CDVD internally uses GMT+9. If you think the time's wrong, you're wrong.
// Set up your time zone and winter/summer in the BIOS. No PS2 BIOS I know of features automatic DST.
wxDateTime curtime(wxDateTime::GetTimeNow());
cdvd.RTC.second = (u8)curtime.GetSecond();
cdvd.RTC.minute = (u8)curtime.GetMinute();
cdvd.RTC.hour = (u8)curtime.GetHour(wxDateTime::GMT9);
cdvd.RTC.day = (u8)curtime.GetDay(wxDateTime::GMT9);
cdvd.RTC.month = (u8)curtime.GetMonth(wxDateTime::GMT9) + 1; // WX returns Jan as "0"
cdvd.RTC.year = (u8)(curtime.GetYear(wxDateTime::GMT9) - 2000);
gmtime_r(&gmt9_time, &curtime);
#endif
cdvd.RTC.second = (u8)curtime.tm_sec;
cdvd.RTC.minute = (u8)curtime.tm_min;
cdvd.RTC.hour = (u8)curtime.tm_hour;
cdvd.RTC.day = (u8)curtime.tm_mday;
cdvd.RTC.month = (u8)curtime.tm_mon + 1; // WX returns Jan as "0"
cdvd.RTC.year = (u8)(curtime.tm_year - 100); // offset from 2000
}
g_GameStarted = false;
g_GameLoading = false;

View File

@ -18,13 +18,8 @@
#define ENABLE_TIMESTAMPS
#ifdef _WIN32
#include <wx/msw/wrapwin.h>
#endif
#include <ctype.h>
#include <time.h>
#include <wx/datetime.h>
#include <exception>
#include <memory>
@ -35,6 +30,7 @@
#include "common/Assertions.h"
#include "common/Exceptions.h"
#include "common/FileSystem.h"
#include "common/Path.h"
#include "common/StringUtil.h"
#include "DebugTools/SymbolMap.h"
#include "Config.h"
@ -381,7 +377,7 @@ bool DoCDVDopen()
return true;
}
std::string somepick(FileSystem::StripExtension(FileSystem::GetDisplayNameFromPath(m_SourceFilename[CurrentSourceType])));
std::string somepick(Path::StripExtension(FileSystem::GetDisplayNameFromPath(m_SourceFilename[CurrentSourceType])));
//FWIW Disc serial availability doesn't seem reliable enough, sometimes it's there and sometime it's just null
//Shouldn't the serial be available all time? Potentially need to look into Elfreloadinfo() reliability
//TODO: Add extra fallback case for CRC.
@ -393,14 +389,20 @@ bool DoCDVDopen()
if (EmuConfig.CurrentBlockdump.empty())
EmuConfig.CurrentBlockdump = FileSystem::GetWorkingDirectory();
std::string temp(Path::CombineStdString(EmuConfig.CurrentBlockdump, somepick));
std::string temp(Path::Combine(EmuConfig.CurrentBlockdump, somepick));
#ifdef ENABLE_TIMESTAMPS
wxDateTime curtime(wxDateTime::GetTimeNow());
std::time_t curtime_t = std::time(nullptr);
struct tm curtime = {};
#ifdef _MSC_VER
localtime_s(&curtime, &curtime_t);
#else
localtime_r(&curtime_t, &curtime);
#endif
temp += StringUtil::StdStringFromFormat(" (%04d-%02d-%02d %02d-%02d-%02d)",
curtime.GetYear(), curtime.GetMonth(), curtime.GetDay(),
curtime.GetHour(), curtime.GetMinute(), curtime.GetSecond());
curtime.tm_year + 1900, curtime.tm_mon + 1, curtime.tm_mday,
curtime.tm_hour, curtime.tm_min, curtime.tm_sec);
#endif
temp += ".dump";

View File

@ -18,6 +18,7 @@
#include "common/Assertions.h"
#include "common/FileSystem.h"
#include "common/Path.h"
#include "common/StringUtil.h"
ChdFileReader::~ChdFileReader()
@ -87,12 +88,12 @@ bool ChdFileReader::Open2(std::string fileName)
}
bool found_parent = false;
dirname = FileSystem::GetPathDirectory(chds[chd_depth]);
dirname = Path::GetDirectory(chds[chd_depth]);
if (FileSystem::FindFiles(dirname.c_str(), "*.*", FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES, &results))
{
for (const FILESYSTEM_FIND_DATA& fd : results)
{
const std::string_view extension(FileSystem::GetExtension(fd.FileName));
const std::string_view extension(Path::GetExtension(fd.FileName));
if (extension.empty() || StringUtil::Strncasecmp(extension.data(), "chd", 3) != 0)
continue;

View File

@ -14,9 +14,9 @@
*/
#include "PrecompiledHeader.h"
#include <wx/stdpaths.h>
#include <fstream>
#include "common/FileSystem.h"
#include "common/Path.h"
#include "common/StringUtil.h"
#include "Config.h"
#include "ChunksCache.h"
@ -104,7 +104,8 @@ static void WriteIndexToFile(Access* index, const char* filename)
}
}
static wxString INDEX_TEMPLATE_KEY(L"$(f)");
static constexpr char* INDEX_TEMPLATE_KEY = "$(f)";
// template:
// must contain one and only one instance of '$(f)' (without the quotes)
// if if !canEndWithKey -> must not end with $(f)
@ -114,34 +115,33 @@ static wxString INDEX_TEMPLATE_KEY(L"$(f)");
// then it's relative to base (not to cwd)
// No checks are performed if the result file name can be created.
// If this proves useful, we can move it into Path:: . Right now there's no need.
static wxString ApplyTemplate(const std::string& name, const wxDirName& base,
static std::string ApplyTemplate(const std::string& name, const std::string& base,
const std::string& fileTemplate, const std::string& filename,
bool canEndWithKey)
{
wxString tem(StringUtil::UTF8StringToWxString(fileTemplate));
wxString key = INDEX_TEMPLATE_KEY;
tem = tem.Trim(true).Trim(false); // both sides
// both sides
std::string trimmedTemplate(StringUtil::StripWhitespace(fileTemplate));
size_t first = tem.find(key);
if (first == wxString::npos // not found
|| first != tem.rfind(key) // more than one instance
|| !canEndWithKey && first == tem.length() - key.length())
std::string::size_type first = trimmedTemplate.find(INDEX_TEMPLATE_KEY);
if (first == std::string::npos // not found
|| first != trimmedTemplate.rfind(INDEX_TEMPLATE_KEY) // more than one instance
|| !canEndWithKey && first == trimmedTemplate.length() - std::strlen(INDEX_TEMPLATE_KEY))
{
Console.Error("Invalid %s template '%s'.\n"
"Template must contain exactly one '%s' and must not end with it. Abotring.",
name.c_str(), tem.ToUTF8().data(), key.ToUTF8().data());
return L"";
name.c_str(), trimmedTemplate.c_str(), INDEX_TEMPLATE_KEY);
return {};
}
wxString fname(StringUtil::UTF8StringToWxString(filename));
std::string fname(filename);
if (first > 0)
fname = Path::GetFilename(fname); // without path
fname = Path::GetFileName(fname); // without path
tem.Replace(key, fname);
StringUtil::ReplaceAll(trimmedTemplate, INDEX_TEMPLATE_KEY, fname);
if (first > 0)
tem = Path::Combine(base, tem); // ignores appRoot if tem is absolute
trimmedTemplate = Path::Combine(base, trimmedTemplate); // ignores appRoot if tem is absolute
return tem;
return trimmedTemplate;
}
/*
@ -173,6 +173,7 @@ static void TestTemplate(const wxDirName &base, const wxString &fname, bool canE
static std::string iso2indexname(const std::string& isoname)
{
#if 0
#ifndef PCSX2_CORE
//testTemplate(isoname);
wxDirName appRoot = // TODO: have only one of this in PCSX2. Right now have few...
@ -182,6 +183,11 @@ static std::string iso2indexname(const std::string& isoname)
#endif
//TestTemplate(appRoot, isoname, false);
return StringUtil::wxStringToUTF8String(ApplyTemplate("gzip index", appRoot, EmuConfig.GzipIsoIndexTemplate, isoname, false));
#else
//FIXME
abort();
return {};
#endif
}
GzippedFileReader::GzippedFileReader(void)

View File

@ -22,6 +22,7 @@
#include "common/Assertions.h"
#include "common/Exceptions.h"
#include "common/FileSystem.h"
#include "common/Path.h"
#include "common/StringUtil.h"
#include <memory>
@ -176,7 +177,7 @@ IsoFileDescriptor IsoDirectory::FindFile(const std::string_view& filePath) const
// wxWidgets DOS-style parser should work fine for ISO 9660 path names. Only practical difference
// is case sensitivity, and that won't matter for path splitting.
std::vector<std::string_view> parts(FileSystem::SplitWindowsPath(filePath));
std::vector<std::string_view> parts(Path::SplitWindowsPath(filePath));
IsoFileDescriptor info;
const IsoDirectory* dir = this;
std::unique_ptr<IsoDirectory> deleteme;

View File

@ -227,7 +227,6 @@ set(pcsx2Headers
MemoryCardFolder.h
MemoryTypes.h
Patch.h
PathDefs.h
PCSX2Base.h
PerformanceMetrics.h
PrecompiledHeader.h
@ -812,7 +811,6 @@ endif()
if(PCSX2_CORE)
list(APPEND pcsx2SPU2Headers
SPU2/Host/CfgHelpers.cpp
SPU2/Host/Config.cpp
SPU2/Host/ConfigDebug.cpp
SPU2/Host/ConfigSoundTouch.cpp
@ -1117,6 +1115,7 @@ set(pcsx2GuiSources
gui/DriveList.cpp
gui/ExecutorThread.cpp
gui/FastFormatString.cpp
gui/FileUtils.cpp
gui/FrameForGS.cpp
gui/GlobalCommands.cpp
gui/IniInterface.cpp
@ -1140,6 +1139,7 @@ set(pcsx2GuiSources
gui/Panels/PathsPanel.cpp
gui/Panels/SpeedhacksPanel.cpp
gui/Panels/VideoPanel.cpp
gui/PathUtils.cpp
gui/PersistentThread.cpp
gui/pxCheckBox.cpp
gui/pxRadioPanel.cpp
@ -1193,6 +1193,7 @@ set(pcsx2GuiHeaders
gui/IsoDropTarget.h
gui/MainFrame.h
gui/MSWstuff.h
gui/PathDefs.h
gui/Panels/ConfigurationPanels.h
gui/Panels/LogOptionsPanels.h
gui/Panels/MemoryCardPanels.h
@ -1208,6 +1209,7 @@ set(pcsx2GuiHeaders
gui/SysThreads.h
gui/ThreadingDialogs.h
gui/ThreadingDialogs.cpp
gui/wxDirName.h
gui/wxGuiTools.h
gui/wxSettingsInterface.h
)
@ -1387,10 +1389,6 @@ set(pcsx2RecordingVirtualPadResources
set(pcsx2SystemHeaders
System/RecTypes.h)
# Utilities sources
set(pcsx2UtilitiesSources
Utilities/FileUtils.cpp)
# Windows sources
set(pcsx2WindowsSources
CDVD/Windows/DriveUtility.cpp
@ -1518,7 +1516,6 @@ target_sources(PCSX2 PRIVATE
${pcsx2ps2Sources}
${pcsx2ps2Headers}
${pcsx2SystemHeaders}
${pcsx2UtilitiesSources}
)
# gui sources when not doing a qt build
@ -1602,7 +1599,6 @@ target_link_libraries(PCSX2_FLAGS INTERFACE
ryml
chdr-static
libzip::zip
wxWidgets::all
ZLIB::ZLIB
PkgConfig::SOUNDTOUCH
PkgConfig::SAMPLERATE
@ -1616,6 +1612,10 @@ if(PCSX2_CORE)
target_link_libraries(PCSX2_FLAGS INTERFACE
simpleini
)
else()
target_link_libraries(PCSX2_FLAGS INTERFACE
wxWidgets::all
)
endif()
if(WIN32)

View File

@ -17,7 +17,6 @@
#include "common/emitter/tools.h"
#include "common/General.h"
#include "common/Path.h"
#include <string>
class SettingsInterface;
@ -964,7 +963,7 @@ struct Pcsx2Config
HostFs : 1;
// uses automatic ntfs compression when creating new memory cards (Win32 only)
#ifdef __WXMSW__
#ifdef _WIN32
bool McdCompressNTFS;
#endif
BITFIELD_END
@ -1001,9 +1000,8 @@ struct Pcsx2Config
void LoadSave(SettingsWrapper& wrap);
void LoadSaveMemcards(SettingsWrapper& wrap);
// TODO: Make these std::string when we remove wxFile...
std::string FullpathToBios() const;
wxString FullpathToMcd(uint slot) const;
std::string FullpathToMcd(uint slot) const;
bool MultitapEnabled(uint port) const;
@ -1024,22 +1022,22 @@ extern Pcsx2Config EmuConfig;
namespace EmuFolders
{
extern wxDirName AppRoot;
extern wxDirName DataRoot;
extern wxDirName Settings;
extern wxDirName Bios;
extern wxDirName Snapshots;
extern wxDirName Savestates;
extern wxDirName MemoryCards;
extern wxDirName Langs;
extern wxDirName Logs;
extern wxDirName Cheats;
extern wxDirName CheatsWS;
extern wxDirName Resources;
extern wxDirName Cache;
extern wxDirName Covers;
extern wxDirName GameSettings;
extern wxDirName Textures;
extern std::string AppRoot;
extern std::string DataRoot;
extern std::string Settings;
extern std::string Bios;
extern std::string Snapshots;
extern std::string Savestates;
extern std::string MemoryCards;
extern std::string Langs;
extern std::string Logs;
extern std::string Cheats;
extern std::string CheatsWS;
extern std::string Resources;
extern std::string Cache;
extern std::string Covers;
extern std::string GameSettings;
extern std::string Textures;
// Assumes that AppRoot and DataRoot have been initialized.
void SetDefaults();

View File

@ -22,6 +22,8 @@
#include <condition_variable>
#include <fstream>
#include "ghc/filesystem.h"
#include "common/Path.h"
#include "DEV9/SimpleQueue.h"
@ -154,7 +156,7 @@ private:
public:
ATA();
int Open(fs::path hddPath);
int Open(ghc::filesystem::path hddPath);
void Close();
void ATA_HardReset();

View File

@ -30,7 +30,7 @@ ATA::ATA()
ResetEnd(true);
}
int ATA::Open(fs::path hddPath)
int ATA::Open(ghc::filesystem::path hddPath)
{
readBufferLen = 256 * 512;
readBuffer = new u8[readBufferLen];
@ -38,7 +38,7 @@ int ATA::Open(fs::path hddPath)
CreateHDDinfo(EmuConfig.DEV9.HddSizeSectors);
//Open File
if (!fs::exists(hddPath))
if (!ghc::filesystem::exists(hddPath))
{
#ifndef PCSX2_CORE
HddCreateWx hddCreator;
@ -52,7 +52,7 @@ int ATA::Open(fs::path hddPath)
return -1;
#endif
}
hddImage = fs::fstream(hddPath, std::ios::in | std::ios::out | std::ios::binary);
hddImage = ghc::filesystem::fstream(hddPath, std::ios::in | std::ios::out | std::ios::binary);
//Store HddImage size for later check
hddImage.seekg(0, std::ios::end);

View File

@ -26,19 +26,19 @@ void HddCreate::Start()
Cleanup();
}
void HddCreate::WriteImage(fs::path hddPath, u64 reqSizeBytes)
void HddCreate::WriteImage(ghc::filesystem::path hddPath, u64 reqSizeBytes)
{
constexpr int buffsize = 4 * 1024;
u8 buff[buffsize] = {0}; //4kb
if (fs::exists(hddPath))
if (ghc::filesystem::exists(hddPath))
{
errored.store(true);
SetError();
return;
}
std::fstream newImage = fs::fstream(hddPath, std::ios::out | std::ios::binary);
std::fstream newImage = ghc::filesystem::fstream(hddPath, std::ios::out | std::ios::binary);
if (newImage.fail())
{
@ -55,7 +55,7 @@ void HddCreate::WriteImage(fs::path hddPath, u64 reqSizeBytes)
if (newImage.fail())
{
newImage.close();
fs::remove(filePath);
ghc::filesystem::remove(filePath);
errored.store(true);
SetError();
return;
@ -77,7 +77,7 @@ void HddCreate::WriteImage(fs::path hddPath, u64 reqSizeBytes)
if (newImage.fail())
{
newImage.close();
fs::remove(filePath);
ghc::filesystem::remove(filePath);
errored.store(true);
SetError();
return;
@ -91,7 +91,7 @@ void HddCreate::WriteImage(fs::path hddPath, u64 reqSizeBytes)
if (newImage.fail())
{
newImage.close();
fs::remove(filePath);
ghc::filesystem::remove(filePath);
errored.store(true);
SetError();
return;
@ -107,7 +107,7 @@ void HddCreate::WriteImage(fs::path hddPath, u64 reqSizeBytes)
if (canceled.load())
{
newImage.close();
fs::remove(filePath);
ghc::filesystem::remove(filePath);
errored.store(true);
SetError();
return;

View File

@ -20,10 +20,12 @@
#include "common/Path.h"
#include "ghc/filesystem.h"
class HddCreate
{
public:
fs::path filePath;
ghc::filesystem::path filePath;
u64 neededSize;
std::atomic_bool errored{false};
@ -48,5 +50,5 @@ protected:
void SetCanceled();
private:
void WriteImage(fs::path hddPath, u64 reqSizeBytes);
void WriteImage(ghc::filesystem::path hddPath, u64 reqSizeBytes);
};

View File

@ -422,7 +422,7 @@ void DEV9configure()
if (hddPath.is_relative())
{
//GHC uses UTF8 on all platforms
fs::path path(EmuFolders::Settings.ToString().wx_str());
ghc::filesystem::path path(EmuFolders::Settings);
hddPath = path / hddPath;
}

View File

@ -16,6 +16,7 @@
#include "PrecompiledHeader.h"
#include "common/Assertions.h"
#include "common/StringUtil.h"
#ifdef _WIN32
#include "common/RedtapeWindows.h"
@ -94,17 +95,21 @@ int mapping;
bool isRunning = false;
fs::path GetHDDPath()
ghc::filesystem::path GetHDDPath()
{
//GHC uses UTF8 on all platforms
fs::path hddPath(EmuConfig.DEV9.HddFile);
ghc::filesystem::path hddPath(EmuConfig.DEV9.HddFile);
if (hddPath.empty())
EmuConfig.DEV9.HddEnable = false;
if (hddPath.is_relative())
{
fs::path path(EmuFolders::Settings.ToString().wx_str());
#ifdef _WIN32
ghc::filesystem::path path(StringUtil::UTF8StringToWideString(EmuFolders::Settings));
#else
ghc::filesystem::path path(EmuFolders::Settings);
#endif
hddPath = path / hddPath;
}
@ -206,7 +211,7 @@ s32 DEV9open()
#endif
DevCon.WriteLn("DEV9: open r+: %s", EmuConfig.DEV9.HddFile.c_str());
fs::path hddPath = GetHDDPath();
ghc::filesystem::path hddPath = GetHDDPath();
if (EmuConfig.DEV9.HddEnable)
{
@ -1070,7 +1075,7 @@ void DEV9CheckChanges(const Pcsx2Config& old_config)
//Hdd
//Hdd Validate Path
fs::path hddPath = GetHDDPath();
ghc::filesystem::path hddPath = GetHDDPath();
//Hdd Compare with old config
if (EmuConfig.DEV9.HddEnable)

View File

@ -15,6 +15,7 @@
#include "PrecompiledHeader.h"
#include "common/StringUtil.h"
#include "ghc/filesystem.h"
#include <wx/fileconf.h>
@ -38,7 +39,7 @@
void SaveDnsHosts()
{
#ifndef PCSX2_CORE
std::unique_ptr<wxFileConfig> hini(OpenFileConfig(EmuFolders::Settings.Combine(wxString("DEV9Hosts.ini")).GetFullPath()));
std::unique_ptr<wxFileConfig> hini(OpenFileConfig(StringUtil::UTF8StringToWxString(Path::Combine(EmuFolders::Settings, "DEV9Hosts.ini"))));
#else
std::unique_ptr<wxFileConfig> hini(new wxFileConfig(wxEmptyString, wxEmptyString, EmuFolders::Settings.Combine(wxString("DEV9Hosts.ini")).GetFullPath(), wxEmptyString, wxCONFIG_USE_RELATIVE_PATH));
#endif
@ -68,7 +69,7 @@ void SaveDnsHosts()
void LoadDnsHosts()
{
wxFileName iniPath = EmuFolders::Settings.Combine(wxString("DEV9Hosts.ini"));
wxFileName iniPath = StringUtil::UTF8StringToWxString(Path::Combine(EmuFolders::Settings, "DEV9Hosts.ini"));
config.EthHosts.clear();
//If no file exists, create one to provide an example config
if (!iniPath.FileExists())

View File

@ -20,7 +20,7 @@
#include "Memory.h"
extern FILE *emuLog;
extern wxString emuLogName;
extern std::string emuLogName;
extern char* disVU0MicroUF(u32 code, u32 pc);
extern char* disVU0MicroLF(u32 code, u32 pc);

View File

@ -280,21 +280,21 @@ union tDMAC_QUEUE
bool empty() const { return (_u16 == 0); }
};
static __fi const wxChar* ChcrName(u32 addr)
static __fi const char* ChcrName(u32 addr)
{
switch (addr)
{
case D0_CHCR: return L"Vif 0";
case D1_CHCR: return L"Vif 1";
case D2_CHCR: return L"GIF";
case D3_CHCR: return L"Ipu 0";
case D4_CHCR: return L"Ipu 1";
case D5_CHCR: return L"Sif 0";
case D6_CHCR: return L"Sif 1";
case D7_CHCR: return L"Sif 2";
case D8_CHCR: return L"SPR 0";
case D9_CHCR: return L"SPR 1";
default: return L"???";
case D0_CHCR: return "Vif 0";
case D1_CHCR: return "Vif 1";
case D2_CHCR: return "GIF";
case D3_CHCR: return "Ipu 0";
case D4_CHCR: return "Ipu 1";
case D5_CHCR: return "Sif 0";
case D6_CHCR: return "Sif 1";
case D7_CHCR: return "Sif 2";
case D8_CHCR: return "SPR 0";
case D9_CHCR: return "SPR 1";
default: return "???";
}
}

View File

@ -24,6 +24,7 @@
#include "Config.h"
#include "common/FileSystem.h"
#include "common/Path.h"
#include "fmt/core.h"
@ -210,8 +211,8 @@ void iDumpBlock(u32 ee_pc, u32 ee_size, uptr x86_pc, u32 x86_size)
DbgCon.WriteLn( Color_Gray, "dump block %x:%x (x86:0x%x)", ee_pc, ee_end, x86_pc );
EmuFolders::Logs.Mkdir();
std::string dump_filename(Path::CombineStdString(EmuFolders::Logs, fmt::format("R5900dump_{:.8X}:{:.8X}.txt", ee_pc, ee_end) ));
FileSystem::CreateDirectoryPath(EmuFolders::Logs.c_str(), false);
std::string dump_filename(Path::Combine(EmuFolders::Logs, fmt::format("R5900dump_{:.8X}:{:.8X}.txt", ee_pc, ee_end) ));
std::FILE* eff = FileSystem::OpenCFile(dump_filename.c_str(), "w");
if (!eff)
return;
@ -251,7 +252,7 @@ void iDumpBlock(u32 ee_pc, u32 ee_size, uptr x86_pc, u32 x86_size)
// handy but slow solution (system call)
#ifdef __linux__
std::string obj_filename(Path::CombineStdString(EmuFolders::Logs, "objdump_tmp.o"));
std::string obj_filename(Path::Combine(EmuFolders::Logs, "objdump_tmp.o"));
std::FILE* objdump = FileSystem::OpenCFile(obj_filename.c_str(), "wb");
if (!objdump)
return;
@ -278,8 +279,8 @@ void iDumpBlock( int startpc, u8 * ptr )
DbgCon.WriteLn( Color_Gray, "dump1 %x:%x, %x", startpc, pc, cpuRegs.cycle );
EmuFolders::Logs.Mkdir();
std::FILE* eff = FileSystem::OpenCFile(Path::CombineStdString(EmuFolders::Logs, fmt::format("R5900dump{:.8X}.txt", startpc)).c_str(), "w");
FileSystem::CreateDirectoryPath(EmuFolders::Logs.c_str(), false);
std::FILE* eff = FileSystem::OpenCFile(Path::Combine(EmuFolders::Logs, fmt::format("R5900dump{:.8X}.txt", startpc)).c_str(), "w");
if (!eff)
return;

View File

@ -25,6 +25,7 @@
#include "common/Assertions.h"
#include "common/Console.h"
#include "common/StringUtil.h"
#include "common/RedtapeWindows.h"
#include "Config.h"

View File

@ -20,6 +20,7 @@
#include "common/Assertions.h"
#include "common/Console.h"
#include "common/FileSystem.h"
#include "common/Path.h"
#include "common/ProgressCallback.h"
#include "common/StringUtil.h"
#include <algorithm>
@ -161,7 +162,7 @@ bool GameList::GetElfListEntry(const std::string& path, GameList::Entry* entry)
const std::string display_name(FileSystem::GetDisplayNameFromPath(path));
entry->path = path;
entry->serial.clear();
entry->title = FileSystem::StripExtension(display_name);
entry->title = Path::StripExtension(display_name);
entry->region = Region::Other;
entry->total_size = static_cast<u64>(file_size);
entry->type = EntryType::ELF;
@ -231,7 +232,7 @@ bool GameList::GetIsoListEntry(const std::string& path, GameList::Entry* entry)
}
else
{
entry->title = FileSystem::GetFileTitleFromPath(path);
entry->title = Path::GetFileTitle(path);
entry->region = Region::Other;
}
@ -358,7 +359,7 @@ bool GameList::LoadEntriesFromCache(std::FILE* stream)
static std::string GetCacheFilename()
{
return Path::CombineStdString(EmuFolders::Cache, "gamelist.cache");
return Path::Combine(EmuFolders::Cache, "gamelist.cache");
}
void GameList::LoadCache()
@ -680,13 +681,13 @@ 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_view file_title(Path::GetFileTitle(path));
if (!file_title.empty() && title != file_title)
{
std::string cover_filename(file_title);
cover_filename += extension;
cover_path = Path::CombineStdString(EmuFolders::Covers, cover_filename);
cover_path = Path::Combine(EmuFolders::Covers, cover_filename);
if (FileSystem::FileExists(cover_path.c_str()))
return cover_path;
}
@ -695,7 +696,7 @@ std::string GameList::GetCoverImagePath(const std::string& path, const std::stri
if (!title.empty())
{
const std::string cover_filename(title + extension);
cover_path = Path::CombineStdString(EmuFolders::Covers, cover_filename);
cover_path = Path::Combine(EmuFolders::Covers, cover_filename);
if (FileSystem::FileExists(cover_path.c_str()))
return cover_path;
}
@ -704,7 +705,7 @@ std::string GameList::GetCoverImagePath(const std::string& path, const std::stri
if (!serial.empty())
{
const std::string cover_filename(serial + extension);
cover_path = Path::CombineStdString(EmuFolders::Covers, cover_filename);
cover_path = Path::Combine(EmuFolders::Covers, cover_filename);
if (FileSystem::FileExists(cover_path.c_str()))
return cover_path;
}
@ -729,5 +730,5 @@ std::string GameList::GetNewCoverImagePathForEntry(const Entry* entry, const cha
}
const std::string cover_filename(entry->title + extension);
return Path::CombineStdString(EmuFolders::Covers, cover_filename);
return Path::Combine(EmuFolders::Covers, cover_filename);
}

View File

@ -30,6 +30,8 @@
#include "GSLzma.h"
#include "common/Console.h"
#include "common/FileSystem.h"
#include "common/Path.h"
#include "common/StringUtil.h"
#include "pcsx2/Config.h"
#include "pcsx2/Counters.h"
@ -648,7 +650,7 @@ void GSgetStats(std::string& info)
{
const double fps = GetVerticalFrequency();
const double fillrate = pm.Get(GSPerfMon::Fillrate);
info = format("%s SW | %d S | %d P | %d D | %.2f U | %.2f D | %.2f mpps",
info = StringUtil::StdStringFromFormat("%s SW | %d S | %d P | %d D | %.2f U | %.2f D | %.2f mpps",
api_name,
(int)pm.Get(GSPerfMon::SyncPoint),
(int)pm.Get(GSPerfMon::Prim),
@ -659,13 +661,13 @@ void GSgetStats(std::string& info)
}
else if (GSConfig.Renderer == GSRendererType::Null)
{
info = format("%s Null", api_name);
info = StringUtil::StdStringFromFormat("%s Null", api_name);
}
else
{
if (GSConfig.TexturePreloading == TexturePreloadingLevel::Full)
{
info = format("%s HW | HC: %d MB | %d P | %d D | %d DC | %d B | %d RB | %d TC | %d TU",
info = StringUtil::StdStringFromFormat("%s HW | HC: %d MB | %d P | %d D | %d DC | %d B | %d RB | %d TC | %d TU",
api_name,
(int)std::ceil(GSRendererHW::GetInstance()->GetTextureCache()->GetHashCacheMemoryUsage() / 1048576.0f),
(int)pm.Get(GSPerfMon::Prim),
@ -678,7 +680,7 @@ void GSgetStats(std::string& info)
}
else
{
info = format("%s HW | %d P | %d D | %d DC | %d B | %d RB | %d TC | %d TU",
info = StringUtil::StdStringFromFormat("%s HW | %d P | %d D | %d DC | %d B | %d RB | %d TC | %d TU",
api_name,
(int)pm.Get(GSPerfMon::Prim),
(int)pm.Get(GSPerfMon::Draw),
@ -989,6 +991,8 @@ void fifo_free(void* ptr, size_t size, size_t repeat)
#else
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
void* vmalloc(size_t size, bool code)
@ -1106,7 +1110,7 @@ bool GSApp::WriteIniString(const char* lpAppName, const char* lpKeyName, const c
m_configuration_map[key] = value;
// Save config to a file
FILE* f = px_fopen(lpFileName, "w");
FILE* f = FileSystem::OpenCFile(lpFileName, "w");
if (f == NULL)
return false; // FIXME print a nice message
@ -1427,7 +1431,7 @@ void GSApp::BuildConfigurationMap(const char* lpFileName)
// Load config from file
#ifdef _WIN32
std::ifstream file(convert_utf8_to_utf16(lpFileName));
std::ifstream file(StringUtil::UTF8StringToWideString(lpFileName));
#else
std::ifstream file(lpFileName);
#endif
@ -1467,8 +1471,7 @@ void GSApp::SetConfigDir()
// we need to initialize the ini folder later at runtime than at theApp init, as
// core settings aren't populated yet, thus we do populate it if needed either when
// opening GS settings or init -- govanify
wxString iniName(L"GS.ini");
m_ini = EmuFolders::Settings.Combine(iniName).GetFullPath().ToUTF8();
m_ini = Path::Combine(EmuFolders::Settings, "GS.ini");
}
std::string GSApp::GetConfigS(const char* entry)

View File

@ -18,6 +18,7 @@
#include "GSPng.h"
#include "GSUtil.h"
#include "GSExtra.h"
#include "common/StringUtil.h"
#ifdef _WIN32
@ -524,7 +525,7 @@ bool GSCapture::BeginCapture(float fps, GSVector2i recommendedResolution, float
m_src.query<IGSSource>()->DeliverNewSegment();
m_capturing = true;
filename = convert_utf16_to_utf8(dlg.m_filename.erase(dlg.m_filename.length() - 3, 3) + L"wav");
filename = StringUtil::WideStringToUTF8String(dlg.m_filename.erase(dlg.m_filename.length() - 3, 3) + L"wav");
return true;
#elif defined(__unix__)
// Note I think it doesn't support multiple depth creation
@ -569,7 +570,7 @@ bool GSCapture::DeliverFrame(const void* bits, int pitch, bool rgba)
#elif defined(__unix__)
std::string out_file = m_out_dir + format("/frame.%010d.png", m_frame);
std::string out_file = m_out_dir + StringUtil::StdStringFromFormat("/frame.%010d.png", m_frame);
//GSPng::Save(GSPng::RGB_PNG, out_file, (u8*)bits, m_size.x, m_size.y, pitch, m_compression_level);
m_workers[m_frame % m_threads]->Push(std::make_shared<GSPng::Transaction>(GSPng::RGB_PNG, out_file, static_cast<const u8*>(bits), m_size.x, m_size.y, pitch, m_compression_level));

View File

@ -17,6 +17,7 @@
#include "GSCrc.h"
#include "GSExtra.h"
#include "GS.h"
#include "common/StringUtil.h"
const CRC::Game CRC::m_games[] =
{
@ -346,7 +347,7 @@ std::string ToLower(std::string str)
// E.g. Disable hacks for these CRCs: CrcHacksExclusions=0x0F0C4A9C, 0x0EE5646B, 0x7ACF7E03
bool IsCrcExcluded(std::string exclusionList, u32 crc)
{
std::string target = format("0x%08x", crc);
std::string target = StringUtil::StdStringFromFormat("0x%08x", crc);
exclusionList = ToLower(exclusionList);
return exclusionList.find(target) != std::string::npos || exclusionList.find("all") != std::string::npos;
}

View File

@ -18,25 +18,6 @@
#include "GSVector.h"
#include "pcsx2/Config.h"
#ifdef _WIN32
#include "common/RedtapeWindows.h"
inline std::string convert_utf16_to_utf8(const std::wstring& utf16_string)
{
const int size = WideCharToMultiByte(CP_UTF8, 0, utf16_string.c_str(), utf16_string.size(), nullptr, 0, nullptr, nullptr);
std::string converted_string(size, 0);
WideCharToMultiByte(CP_UTF8, 0, utf16_string.c_str(), utf16_string.size(), converted_string.data(), converted_string.size(), nullptr, nullptr);
return converted_string;
}
inline std::wstring convert_utf8_to_utf16(const std::string& utf8_string)
{
int size = MultiByteToWideChar(CP_UTF8, 0, utf8_string.c_str(), -1, nullptr, 0);
std::vector<wchar_t> converted_string(size);
MultiByteToWideChar(CP_UTF8, 0, utf8_string.c_str(), -1, converted_string.data(), converted_string.size());
return {converted_string.data()};
}
#endif
/// Like `memcmp(&a, &b, sizeof(T)) == 0` but faster
template <typename T>
__forceinline bool BitEqual(const T& a, const T& b)
@ -95,16 +76,6 @@ __forceinline bool BitEqual(const T& a, const T& b)
return eqb;
}
// _wfopen has to be used on Windows for pathnames containing non-ASCII characters.
inline FILE* px_fopen(const std::string& filename, const std::string& mode)
{
#ifdef _WIN32
return _wfopen(convert_utf8_to_utf16(filename).c_str(), convert_utf8_to_utf16(mode).c_str());
#else
return fopen(filename.c_str(), mode.c_str());
#endif
}
#ifdef ENABLE_ACCURATE_BUFFER_EMULATION
static const GSVector2i default_rt_size(2048, 2048);
#else
@ -150,8 +121,6 @@ static constexpr int MAXIMUM_TEXTURE_MIPMAP_LEVELS = 7;
extern const std::string root_sw;
extern const std::string root_hw;
extern std::string format(const char* fmt, ...);
extern void* vmalloc(size_t size, bool code);
extern void vmfree(void* ptr, size_t size);

View File

@ -16,6 +16,7 @@
#include "PrecompiledHeader.h"
#include "GSPng.h"
#include "GSExtra.h"
#include "common/FileSystem.h"
#include <zlib.h>
#include <png.h>
@ -50,7 +51,7 @@ namespace GSPng
const int offset = first_image ? 0 : pixel[fmt].bytes_per_pixel_out;
const int bytes_per_pixel_out = first_image ? pixel[fmt].bytes_per_pixel_out : bytes_per_pixel_in - offset;
FILE* fp = px_fopen(file, "wb");
FILE* fp = FileSystem::OpenCFile(file.c_str(), "wb");
if (fp == nullptr)
return false;

View File

@ -17,9 +17,11 @@
#include "GSState.h"
#include "GSGL.h"
#include "GSUtil.h"
#include "common/StringUtil.h"
#include <algorithm> // clamp
#include <cfloat> // FLT_MAX
#include <fstream>
#include <iomanip> // Dump Verticles
int GSState::s_n = 0;
@ -1855,7 +1857,7 @@ void GSState::Read(u8* mem, int len)
if (s_dump && s_save && s_n >= s_saven)
{
std::string s = m_dump_root + format(
std::string s = m_dump_root + StringUtil::StdStringFromFormat(
"%05d_read_%05x_%d_%d_%d_%d_%d_%d.bmp",
s_n, (int)m_env.BITBLTBUF.SBP, (int)m_env.BITBLTBUF.SBW, (int)m_env.BITBLTBUF.SPSM,
r.left, r.top, r.right, r.bottom);

View File

@ -17,8 +17,7 @@
#include "GS.h"
#include "GSExtra.h"
#include "GSUtil.h"
#include <locale>
#include <codecvt>
#include "common/StringUtil.h"
#ifdef _WIN32
#include <VersionHelpers.h>
@ -239,7 +238,7 @@ std::string GStempdir()
#ifdef _WIN32
wchar_t path[MAX_PATH + 1];
GetTempPath(MAX_PATH, path);
return convert_utf16_to_utf8(path);
return StringUtil::WideStringToUTF8String(path);
#else
return "/tmp";
#endif

View File

@ -485,7 +485,7 @@ void GSRenderer::VSync(u32 field, bool registers_written)
if (s_dump && s_n >= s_saven)
{
m_regs->Dump(root_sw + format("%05d_f%lld_gs_reg.txt", s_n, g_perfmon.GetFrame()));
m_regs->Dump(root_sw + StringUtil::StdStringFromFormat("%05d_f%lld_gs_reg.txt", s_n, g_perfmon.GetFrame()));
}
const int fb_sprite_blits = g_perfmon.GetDisplayFramebufferSpriteBlits();
@ -585,17 +585,17 @@ void GSRenderer::VSync(u32 field, bool registers_written)
Host::AddKeyedOSDMessage("GSDump", fmt::format("Saving {0} GS dump {1} to '{2}'",
(m_dump_frames == 1) ? "single frame" : "multi-frame", compression_str,
FileSystem::GetFileNameFromPath(m_dump->GetPath())), 10.0f);
Path::GetFileName(m_dump->GetPath())), 10.0f);
}
if (GSTexture* t = g_gs_device->GetCurrent())
{
const std::string path(m_snapshot + ".png");
const std::string_view filename(FileSystem::GetFileNameFromPath(path));
const std::string_view filename(Path::GetFileName(path));
if (t->Save(path))
{
Host::AddKeyedOSDMessage("GSScreenshot",
fmt::format("Screenshot saved to '{}'.", FileSystem::GetFileNameFromPath(path)), 10.0f);
fmt::format("Screenshot saved to '{}'.", Path::GetFileName(path)), 10.0f);
}
else
{
@ -610,7 +610,7 @@ void GSRenderer::VSync(u32 field, bool registers_written)
const bool last = (m_dump_frames == 0);
if (m_dump->VSync(field, last, m_regs))
{
Host::AddKeyedOSDMessage("GSDump", fmt::format("Saved GS dump to '{}'.", FileSystem::GetFileNameFromPath(m_dump->GetPath())), 10.0f);
Host::AddKeyedOSDMessage("GSDump", fmt::format("Saved GS dump to '{}'.", Path::GetFileName(m_dump->GetPath())), 10.0f);
m_dump.reset();
}
else if (!last)
@ -680,19 +680,19 @@ void GSRenderer::QueueSnapshot(const std::string& path, u32 gsdump_frames)
// append the game serial and title
if (std::string name(GetDumpName()); !name.empty())
{
FileSystem::SanitizeFileName(name);
Path::SanitizeFileName(name);
m_snapshot += '_';
m_snapshot += name;
}
if (std::string serial(GetDumpSerial()); !serial.empty())
{
FileSystem::SanitizeFileName(serial);
Path::SanitizeFileName(serial);
m_snapshot += '_';
m_snapshot += serial;
}
// prepend snapshots directory
m_snapshot = Path::CombineStdString(EmuFolders::Snapshots, m_snapshot);
m_snapshot = Path::Combine(EmuFolders::Snapshots, m_snapshot);
}
// this is really gross, but wx we get the snapshot request after shift...

View File

@ -91,8 +91,7 @@ bool GSDevice11::Create(HostDisplay* display)
if (!GSConfig.DisableShaderCache)
{
if (!m_shader_cache.Open(StringUtil::wxStringToUTF8String(EmuFolders::Cache.ToString()),
m_dev->GetFeatureLevel(), SHADER_VERSION, GSConfig.UseDebugDevice))
if (!m_shader_cache.Open(EmuFolders::Cache, m_dev->GetFeatureLevel(), SHADER_VERSION, GSConfig.UseDebugDevice))
{
Console.Warning("Shader cache failed to open.");
}

View File

@ -128,8 +128,7 @@ bool GSDevice12::Create(HostDisplay* display)
if (!GSConfig.DisableShaderCache)
{
if (!m_shader_cache.Open(StringUtil::wxStringToUTF8String(EmuFolders::Cache.ToString()),
g_d3d12_context->GetFeatureLevel(), SHADER_VERSION, GSConfig.UseDebugDevice))
if (!m_shader_cache.Open(EmuFolders::Cache, g_d3d12_context->GetFeatureLevel(), SHADER_VERSION, GSConfig.UseDebugDevice))
{
Console.Warning("Shader cache failed to open.");
}

View File

@ -18,6 +18,7 @@
#include "GSTextureReplacements.h"
#include "GS/GSGL.h"
#include "Host.h"
#include "common/StringUtil.h"
GSRendererHW::GSRendererHW()
: GSRenderer()
@ -299,7 +300,7 @@ GSTexture* GSRendererHW::GetOutput(int i, int& y_offset)
{
if (s_savef && s_n >= s_saven)
{
t->Save(m_dump_root + format("%05d_f%lld_fr%d_%05x_%s.bmp", s_n, g_perfmon.GetFrame(), i, (int)TEX0.TBP0, psm_str(TEX0.PSM)));
t->Save(m_dump_root + StringUtil::StdStringFromFormat("%05d_f%lld_fr%d_%05x_%s.bmp", s_n, g_perfmon.GetFrame(), i, (int)TEX0.TBP0, psm_str(TEX0.PSM)));
}
}
#endif
@ -322,7 +323,7 @@ GSTexture* GSRendererHW::GetFeedbackOutput()
#ifdef ENABLE_OGL_DEBUG
if (s_dump && s_savef && s_n >= s_saven)
t->Save(m_dump_root + format("%05d_f%lld_fr%d_%05x_%s.bmp", s_n, g_perfmon.GetFrame(), 3, (int)TEX0.TBP0, psm_str(TEX0.PSM)));
t->Save(m_dump_root + StringUtil::StdStringFromFormat("%05d_f%lld_fr%d_%05x_%s.bmp", s_n, g_perfmon.GetFrame(), 3, (int)TEX0.TBP0, psm_str(TEX0.PSM)));
#endif
return t;
@ -1215,13 +1216,13 @@ void GSRendererHW::Draw()
std::string s;
// Dump Register state
s = format("%05d_context.txt", s_n);
s = StringUtil::StdStringFromFormat("%05d_context.txt", s_n);
m_env.Dump(m_dump_root + s);
m_context->Dump(m_dump_root + s);
// Dump vertices
s = format("%05d_vertex.txt", s_n);
s = StringUtil::StdStringFromFormat("%05d_vertex.txt", s_n);
DumpVertices(m_dump_root + s);
}
if (IsBadFrame())
@ -1633,7 +1634,7 @@ void GSRendererHW::Draw()
if (s_savet && s_n >= s_saven && m_src)
{
s = format("%05d_f%lld_itex_%05x_%s_%d%d_%02x_%02x_%02x_%02x.dds",
s = StringUtil::StdStringFromFormat("%05d_f%lld_itex_%05x_%s_%d%d_%02x_%02x_%02x_%02x.dds",
s_n, frame, (int)context->TEX0.TBP0, psm_str(context->TEX0.PSM),
(int)context->CLAMP.WMS, (int)context->CLAMP.WMT,
(int)context->CLAMP.MINU, (int)context->CLAMP.MAXU,
@ -1643,7 +1644,7 @@ void GSRendererHW::Draw()
if (m_src->m_palette)
{
s = format("%05d_f%lld_itpx_%05x_%s.dds", s_n, frame, context->TEX0.CBP, psm_str(context->TEX0.CPSM));
s = StringUtil::StdStringFromFormat("%05d_f%lld_itpx_%05x_%s.dds", s_n, frame, context->TEX0.CBP, psm_str(context->TEX0.CPSM));
m_src->m_palette->Save(m_dump_root + s);
}
@ -1651,7 +1652,7 @@ void GSRendererHW::Draw()
if (s_save && s_n >= s_saven)
{
s = format("%05d_f%lld_rt0_%05x_%s.bmp", s_n, frame, context->FRAME.Block(), psm_str(context->FRAME.PSM));
s = StringUtil::StdStringFromFormat("%05d_f%lld_rt0_%05x_%s.bmp", s_n, frame, context->FRAME.Block(), psm_str(context->FRAME.PSM));
if (rt_tex)
rt_tex->Save(m_dump_root + s);
@ -1659,7 +1660,7 @@ void GSRendererHW::Draw()
if (s_savez && s_n >= s_saven)
{
s = format("%05d_f%lld_rz0_%05x_%s.bmp", s_n, frame, context->ZBUF.Block(), psm_str(context->ZBUF.PSM));
s = StringUtil::StdStringFromFormat("%05d_f%lld_rz0_%05x_%s.bmp", s_n, frame, context->ZBUF.Block(), psm_str(context->ZBUF.PSM));
if (ds_tex)
ds_tex->Save(m_dump_root + s);
@ -1796,7 +1797,7 @@ void GSRendererHW::Draw()
if (s_save && s_n >= s_saven)
{
s = format("%05d_f%lld_rt1_%05x_%s.bmp", s_n, frame, context->FRAME.Block(), psm_str(context->FRAME.PSM));
s = StringUtil::StdStringFromFormat("%05d_f%lld_rt1_%05x_%s.bmp", s_n, frame, context->FRAME.Block(), psm_str(context->FRAME.PSM));
if (rt_tex)
rt_tex->Save(m_dump_root + s);
@ -1804,7 +1805,7 @@ void GSRendererHW::Draw()
if (s_savez && s_n >= s_saven)
{
s = format("%05d_f%lld_rz1_%05x_%s.bmp", s_n, frame, context->ZBUF.Block(), psm_str(context->ZBUF.PSM));
s = StringUtil::StdStringFromFormat("%05d_f%lld_rz1_%05x_%s.bmp", s_n, frame, context->ZBUF.Block(), psm_str(context->ZBUF.PSM));
if (ds_tex)
ds_tex->Save(m_dump_root + s);

View File

@ -17,6 +17,7 @@
#include "common/Align.h"
#include "common/FileSystem.h"
#include "common/Path.h"
#include "common/StringUtil.h"
#include "common/ScopedGuard.h"
@ -42,7 +43,7 @@ static constexpr LoaderDefinition s_loaders[] = {
GSTextureReplacements::ReplacementTextureLoader GSTextureReplacements::GetLoader(const std::string_view& filename)
{
const std::string_view extension(FileSystem::GetExtension(filename));
const std::string_view extension(Path::GetExtension(filename));
if (extension.empty())
return nullptr;

View File

@ -209,7 +209,7 @@ std::optional<TextureName> GSTextureReplacements::ParseReplacementName(const std
std::string GSTextureReplacements::GetGameTextureDirectory()
{
return Path::CombineStdString(EmuFolders::Textures, s_current_serial);
return Path::Combine(EmuFolders::Textures, s_current_serial);
}
std::string GSTextureReplacements::GetDumpFilename(const TextureName& name, u32 level)
@ -223,15 +223,15 @@ std::string GSTextureReplacements::GetDumpFilename(const TextureName& name, u32
{
// create both dumps and replacements
if (!FileSystem::CreateDirectoryPath(game_dir.c_str(), false) ||
!FileSystem::EnsureDirectoryExists(Path::CombineStdString(game_dir, "dumps").c_str(), false) ||
!FileSystem::EnsureDirectoryExists(Path::CombineStdString(game_dir, "replacements").c_str(), false))
!FileSystem::EnsureDirectoryExists(Path::Combine(game_dir, "dumps").c_str(), false) ||
!FileSystem::EnsureDirectoryExists(Path::Combine(game_dir, "replacements").c_str(), false))
{
// if it fails to create, we're not going to be able to use it anyway
return ret;
}
}
const std::string game_subdir(Path::CombineStdString(game_dir, TEXTURE_DUMP_SUBDIRECTORY_NAME));
const std::string game_subdir(Path::Combine(game_dir, TEXTURE_DUMP_SUBDIRECTORY_NAME));
if (name.HasPalette())
{
@ -239,7 +239,7 @@ std::string GSTextureReplacements::GetDumpFilename(const TextureName& name, u32
(level > 0) ?
StringUtil::StdStringFromFormat(TEXTURE_FILENAME_CLUT_FORMAT_STRING "-mip%u.png", name.TEX0Hash, name.CLUTHash, name.bits, level) :
StringUtil::StdStringFromFormat(TEXTURE_FILENAME_CLUT_FORMAT_STRING ".png", name.TEX0Hash, name.CLUTHash, name.bits));
ret = Path::CombineStdString(game_subdir, filename);
ret = Path::Combine(game_subdir, filename);
}
else
{
@ -247,7 +247,7 @@ std::string GSTextureReplacements::GetDumpFilename(const TextureName& name, u32
(level > 0) ?
StringUtil::StdStringFromFormat(TEXTURE_FILENAME_FORMAT_STRING "-mip%u.png", name.TEX0Hash, name.bits, level) :
StringUtil::StdStringFromFormat(TEXTURE_FILENAME_FORMAT_STRING ".png", name.TEX0Hash, name.bits));
ret = Path::CombineStdString(game_subdir, filename);
ret = Path::Combine(game_subdir, filename);
}
return ret;
@ -306,7 +306,7 @@ void GSTextureReplacements::ReloadReplacementMap()
if (s_current_serial.empty() || !GSConfig.LoadTextureReplacements)
return;
const std::string replacement_dir(Path::CombineStdString(GetGameTextureDirectory(), TEXTURE_REPLACEMENT_SUBDIRECTORY_NAME));
const std::string replacement_dir(Path::Combine(GetGameTextureDirectory(), TEXTURE_REPLACEMENT_SUBDIRECTORY_NAME));
FileSystem::FindResultsArray files;
if (!FileSystem::FindFiles(replacement_dir.c_str(), "*", FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES | FILESYSTEM_FIND_RECURSIVE, &files))
@ -316,7 +316,7 @@ void GSTextureReplacements::ReloadReplacementMap()
for (FILESYSTEM_FIND_DATA& fd : files)
{
// file format we can handle?
filename = FileSystem::GetFileNameFromPath(fd.FileName);
filename = Path::GetFileName(fd.FileName);
if (!GetLoader(filename))
continue;
@ -595,7 +595,7 @@ void GSTextureReplacements::DumpTexture(const GSTextureCache::HashCacheKey& hash
if (filename.empty() || FileSystem::FileExists(filename.c_str()))
return;
const std::string_view title(FileSystem::GetFileTitleFromPath(filename));
const std::string_view title(Path::GetFileTitle(filename));
DevCon.WriteLn("Dumping %ux%u texture '%.*s'.", name.Width(), name.Height(), static_cast<int>(title.size()), title.data());
// compute width/height

View File

@ -206,7 +206,7 @@ bool GSDeviceOGL::Create(HostDisplay* display)
if (!theApp.GetConfigB("disable_shader_cache"))
{
if (!m_shader_cache.Open(false, StringUtil::wxStringToUTF8String(EmuFolders::Cache.ToString()), SHADER_VERSION))
if (!m_shader_cache.Open(false, EmuFolders::Cache, SHADER_VERSION))
Console.Warning("Shader cache failed to open.");
}
else
@ -369,7 +369,7 @@ bool GSDeviceOGL::Create(HostDisplay* display)
{
const char* name = shaderName(static_cast<ShaderConvert>(i));
const std::string macro_sel = (static_cast<ShaderConvert>(i) == ShaderConvert::RGBA_TO_8I) ?
format("#define PS_SCALE_FACTOR %d\n", GSConfig.UpscaleMultiplier) :
StringUtil::StdStringFromFormat("#define PS_SCALE_FACTOR %d\n", GSConfig.UpscaleMultiplier) :
std::string();
const std::string ps(GetShaderSource(name, GL_FRAGMENT_SHADER, m_shader_common_header, *shader, macro_sel));
if (!m_shader_cache.GetProgram(&m_convert.ps[i], m_convert.vs, {}, ps))
@ -408,7 +408,7 @@ bool GSDeviceOGL::Create(HostDisplay* display)
for (size_t i = 0; i < std::size(m_merge_obj.ps); i++)
{
const std::string ps(GetShaderSource(format("ps_main%d", i), GL_FRAGMENT_SHADER, m_shader_common_header, *shader, {}));
const std::string ps(GetShaderSource(StringUtil::StdStringFromFormat("ps_main%d", i), GL_FRAGMENT_SHADER, m_shader_common_header, *shader, {}));
if (!m_shader_cache.GetProgram(&m_merge_obj.ps[i], m_convert.vs, {}, ps))
return false;
m_merge_obj.ps[i].SetFormattedName("Merge pipe %zu", i);
@ -431,7 +431,7 @@ bool GSDeviceOGL::Create(HostDisplay* display)
for (size_t i = 0; i < std::size(m_interlace.ps); i++)
{
const std::string ps(GetShaderSource(format("ps_main%d", i), GL_FRAGMENT_SHADER, m_shader_common_header, *shader, {}));
const std::string ps(GetShaderSource(StringUtil::StdStringFromFormat("ps_main%d", i), GL_FRAGMENT_SHADER, m_shader_common_header, *shader, {}));
if (!m_shader_cache.GetProgram(&m_interlace.ps[i], m_convert.vs, {}, ps))
return false;
m_interlace.ps[i].SetFormattedName("Merge pipe %zu", i);
@ -1020,11 +1020,11 @@ std::string GSDeviceOGL::GetVSSource(VSSelector sel)
Console.WriteLn("Compiling new vertex shader with selector 0x%" PRIX64, sel.key);
#endif
std::string macro = format("#define VS_INT_FST %d\n", sel.int_fst)
+ format("#define VS_IIP %d\n", sel.iip)
+ format("#define VS_POINT_SIZE %d\n", sel.point_size);
std::string macro = StringUtil::StdStringFromFormat("#define VS_INT_FST %d\n", sel.int_fst)
+ StringUtil::StdStringFromFormat("#define VS_IIP %d\n", sel.iip)
+ StringUtil::StdStringFromFormat("#define VS_POINT_SIZE %d\n", sel.point_size);
if (sel.point_size)
macro += format("#define VS_POINT_SIZE_VALUE %d\n", GSConfig.UpscaleMultiplier);
macro += StringUtil::StdStringFromFormat("#define VS_POINT_SIZE_VALUE %d\n", GSConfig.UpscaleMultiplier);
std::string src = GenGlslHeader("vs_main", GL_VERTEX_SHADER, macro);
src += m_shader_common_header;
@ -1038,9 +1038,9 @@ std::string GSDeviceOGL::GetGSSource(GSSelector sel)
Console.WriteLn("Compiling new geometry shader with selector 0x%" PRIX64, sel.key);
#endif
std::string macro = format("#define GS_POINT %d\n", sel.point)
+ format("#define GS_LINE %d\n", sel.line)
+ format("#define GS_IIP %d\n", sel.iip);
std::string macro = StringUtil::StdStringFromFormat("#define GS_POINT %d\n", sel.point)
+ StringUtil::StdStringFromFormat("#define GS_LINE %d\n", sel.line)
+ StringUtil::StdStringFromFormat("#define GS_IIP %d\n", sel.iip);
std::string src = GenGlslHeader("gs_main", GL_GEOMETRY_SHADER, macro);
src += m_shader_common_header;
@ -1054,52 +1054,52 @@ std::string GSDeviceOGL::GetPSSource(const PSSelector& sel)
Console.WriteLn("Compiling new pixel shader with selector 0x%" PRIX64 "%08X", sel.key_hi, sel.key_lo);
#endif
std::string macro = format("#define PS_FST %d\n", sel.fst)
+ format("#define PS_WMS %d\n", sel.wms)
+ format("#define PS_WMT %d\n", sel.wmt)
+ format("#define PS_AEM_FMT %d\n", sel.aem_fmt)
+ format("#define PS_PAL_FMT %d\n", sel.pal_fmt)
+ format("#define PS_DFMT %d\n", sel.dfmt)
+ format("#define PS_DEPTH_FMT %d\n", sel.depth_fmt)
+ format("#define PS_CHANNEL_FETCH %d\n", sel.channel)
+ format("#define PS_URBAN_CHAOS_HLE %d\n", sel.urban_chaos_hle)
+ format("#define PS_TALES_OF_ABYSS_HLE %d\n", sel.tales_of_abyss_hle)
+ format("#define PS_TEX_IS_FB %d\n", sel.tex_is_fb)
+ format("#define PS_INVALID_TEX0 %d\n", sel.invalid_tex0)
+ format("#define PS_AEM %d\n", sel.aem)
+ format("#define PS_TFX %d\n", sel.tfx)
+ format("#define PS_TCC %d\n", sel.tcc)
+ format("#define PS_ATST %d\n", sel.atst)
+ format("#define PS_FOG %d\n", sel.fog)
+ format("#define PS_CLR_HW %d\n", sel.clr_hw)
+ format("#define PS_FBA %d\n", sel.fba)
+ format("#define PS_LTF %d\n", sel.ltf)
+ format("#define PS_AUTOMATIC_LOD %d\n", sel.automatic_lod)
+ format("#define PS_MANUAL_LOD %d\n", sel.manual_lod)
+ format("#define PS_COLCLIP %d\n", sel.colclip)
+ format("#define PS_DATE %d\n", sel.date)
+ format("#define PS_TCOFFSETHACK %d\n", sel.tcoffsethack)
+ format("#define PS_POINT_SAMPLER %d\n", sel.point_sampler)
+ format("#define PS_BLEND_A %d\n", sel.blend_a)
+ format("#define PS_BLEND_B %d\n", sel.blend_b)
+ format("#define PS_BLEND_C %d\n", sel.blend_c)
+ format("#define PS_BLEND_D %d\n", sel.blend_d)
+ format("#define PS_IIP %d\n", sel.iip)
+ format("#define PS_SHUFFLE %d\n", sel.shuffle)
+ format("#define PS_READ_BA %d\n", sel.read_ba)
+ format("#define PS_WRITE_RG %d\n", sel.write_rg)
+ format("#define PS_FBMASK %d\n", sel.fbmask)
+ format("#define PS_HDR %d\n", sel.hdr)
+ format("#define PS_DITHER %d\n", sel.dither)
+ format("#define PS_ZCLAMP %d\n", sel.zclamp)
+ format("#define PS_BLEND_MIX %d\n", sel.blend_mix)
+ format("#define PS_PABE %d\n", sel.pabe)
+ format("#define PS_SCANMSK %d\n", sel.scanmsk)
+ format("#define PS_SCALE_FACTOR %d\n", GSConfig.UpscaleMultiplier)
+ format("#define PS_NO_COLOR %d\n", sel.no_color)
+ format("#define PS_NO_COLOR1 %d\n", sel.no_color1)
+ format("#define PS_NO_ABLEND %d\n", sel.no_ablend)
+ format("#define PS_ONLY_ALPHA %d\n", sel.only_alpha)
std::string macro = StringUtil::StdStringFromFormat("#define PS_FST %d\n", sel.fst)
+ StringUtil::StdStringFromFormat("#define PS_WMS %d\n", sel.wms)
+ StringUtil::StdStringFromFormat("#define PS_WMT %d\n", sel.wmt)
+ StringUtil::StdStringFromFormat("#define PS_AEM_FMT %d\n", sel.aem_fmt)
+ StringUtil::StdStringFromFormat("#define PS_PAL_FMT %d\n", sel.pal_fmt)
+ StringUtil::StdStringFromFormat("#define PS_DFMT %d\n", sel.dfmt)
+ StringUtil::StdStringFromFormat("#define PS_DEPTH_FMT %d\n", sel.depth_fmt)
+ StringUtil::StdStringFromFormat("#define PS_CHANNEL_FETCH %d\n", sel.channel)
+ StringUtil::StdStringFromFormat("#define PS_URBAN_CHAOS_HLE %d\n", sel.urban_chaos_hle)
+ StringUtil::StdStringFromFormat("#define PS_TALES_OF_ABYSS_HLE %d\n", sel.tales_of_abyss_hle)
+ StringUtil::StdStringFromFormat("#define PS_TEX_IS_FB %d\n", sel.tex_is_fb)
+ StringUtil::StdStringFromFormat("#define PS_INVALID_TEX0 %d\n", sel.invalid_tex0)
+ StringUtil::StdStringFromFormat("#define PS_AEM %d\n", sel.aem)
+ StringUtil::StdStringFromFormat("#define PS_TFX %d\n", sel.tfx)
+ StringUtil::StdStringFromFormat("#define PS_TCC %d\n", sel.tcc)
+ StringUtil::StdStringFromFormat("#define PS_ATST %d\n", sel.atst)
+ StringUtil::StdStringFromFormat("#define PS_FOG %d\n", sel.fog)
+ StringUtil::StdStringFromFormat("#define PS_CLR_HW %d\n", sel.clr_hw)
+ StringUtil::StdStringFromFormat("#define PS_FBA %d\n", sel.fba)
+ StringUtil::StdStringFromFormat("#define PS_LTF %d\n", sel.ltf)
+ StringUtil::StdStringFromFormat("#define PS_AUTOMATIC_LOD %d\n", sel.automatic_lod)
+ StringUtil::StdStringFromFormat("#define PS_MANUAL_LOD %d\n", sel.manual_lod)
+ StringUtil::StdStringFromFormat("#define PS_COLCLIP %d\n", sel.colclip)
+ StringUtil::StdStringFromFormat("#define PS_DATE %d\n", sel.date)
+ StringUtil::StdStringFromFormat("#define PS_TCOFFSETHACK %d\n", sel.tcoffsethack)
+ StringUtil::StdStringFromFormat("#define PS_POINT_SAMPLER %d\n", sel.point_sampler)
+ StringUtil::StdStringFromFormat("#define PS_BLEND_A %d\n", sel.blend_a)
+ StringUtil::StdStringFromFormat("#define PS_BLEND_B %d\n", sel.blend_b)
+ StringUtil::StdStringFromFormat("#define PS_BLEND_C %d\n", sel.blend_c)
+ StringUtil::StdStringFromFormat("#define PS_BLEND_D %d\n", sel.blend_d)
+ StringUtil::StdStringFromFormat("#define PS_IIP %d\n", sel.iip)
+ StringUtil::StdStringFromFormat("#define PS_SHUFFLE %d\n", sel.shuffle)
+ StringUtil::StdStringFromFormat("#define PS_READ_BA %d\n", sel.read_ba)
+ StringUtil::StdStringFromFormat("#define PS_WRITE_RG %d\n", sel.write_rg)
+ StringUtil::StdStringFromFormat("#define PS_FBMASK %d\n", sel.fbmask)
+ StringUtil::StdStringFromFormat("#define PS_HDR %d\n", sel.hdr)
+ StringUtil::StdStringFromFormat("#define PS_DITHER %d\n", sel.dither)
+ StringUtil::StdStringFromFormat("#define PS_ZCLAMP %d\n", sel.zclamp)
+ StringUtil::StdStringFromFormat("#define PS_BLEND_MIX %d\n", sel.blend_mix)
+ StringUtil::StdStringFromFormat("#define PS_PABE %d\n", sel.pabe)
+ StringUtil::StdStringFromFormat("#define PS_SCANMSK %d\n", sel.scanmsk)
+ StringUtil::StdStringFromFormat("#define PS_SCALE_FACTOR %d\n", GSConfig.UpscaleMultiplier)
+ StringUtil::StdStringFromFormat("#define PS_NO_COLOR %d\n", sel.no_color)
+ StringUtil::StdStringFromFormat("#define PS_NO_COLOR1 %d\n", sel.no_color1)
+ StringUtil::StdStringFromFormat("#define PS_NO_ABLEND %d\n", sel.no_ablend)
+ StringUtil::StdStringFromFormat("#define PS_ONLY_ALPHA %d\n", sel.only_alpha)
;
std::string src = GenGlslHeader("ps_main", GL_FRAGMENT_SHADER, macro);
@ -1122,7 +1122,7 @@ bool GSDeviceOGL::DownloadTexture(GSTexture* src, const GSVector4i& rect, GSText
// Copy a sub part of texture (same as below but force a conversion)
void GSDeviceOGL::BlitRect(GSTexture* sTex, const GSVector4i& r, const GSVector2i& dsize, bool at_origin, bool linear)
{
GL_PUSH(format("CopyRectConv from %d", static_cast<GSTextureOGL*>(sTex)->GetID()).c_str());
GL_PUSH(StringUtil::StdStringFromFormat("CopyRectConv from %d", static_cast<GSTextureOGL*>(sTex)->GetID()).c_str());
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
// NOTE: This previously used glCopyTextureSubImage2D(), but this appears to leak memory in

View File

@ -16,6 +16,7 @@
#include "PrecompiledHeader.h"
#include "GSRendererSW.h"
#include "GS/GSGL.h"
#include "common/StringUtil.h"
#define LOG 0
@ -169,7 +170,7 @@ GSTexture* GSRendererSW::GetOutput(int i, int& y_offset)
{
if (s_savef && s_n >= s_saven)
{
m_texture[i]->Save(m_dump_root + format("%05d_f%lld_fr%d_%05x_%s.bmp", s_n, g_perfmon.GetFrame(), i, (int)DISPFB.Block(), psm_str(DISPFB.PSM)));
m_texture[i]->Save(m_dump_root + StringUtil::StdStringFromFormat("%05d_f%lld_fr%d_%05x_%s.bmp", s_n, g_perfmon.GetFrame(), i, (int)DISPFB.Block(), psm_str(DISPFB.PSM)));
}
}
}
@ -339,13 +340,13 @@ void GSRendererSW::Draw()
if (s_n >= s_saven)
{
// Dump Register state
s = format("%05d_context.txt", s_n);
s = StringUtil::StdStringFromFormat("%05d_context.txt", s_n);
m_env.Dump(m_dump_root + s);
m_context->Dump(m_dump_root + s);
// Dump vertices
s = format("%05d_vertex.txt", s_n);
s = StringUtil::StdStringFromFormat("%05d_vertex.txt", s_n);
DumpVertices(m_dump_root + s);
}
}
@ -471,11 +472,11 @@ void GSRendererSW::Draw()
if (texture_shuffle)
{
// Dump the RT in 32 bits format. It helps to debug texture shuffle effect
s = format("%05d_f%lld_itexraw_%05x_32bits.bmp", s_n, frame, (int)m_context->TEX0.TBP0);
s = StringUtil::StdStringFromFormat("%05d_f%lld_itexraw_%05x_32bits.bmp", s_n, frame, (int)m_context->TEX0.TBP0);
m_mem.SaveBMP(m_dump_root + s, m_context->TEX0.TBP0, m_context->TEX0.TBW, 0, 1 << m_context->TEX0.TW, 1 << m_context->TEX0.TH);
}
s = format("%05d_f%lld_itexraw_%05x_%s.bmp", s_n, frame, (int)m_context->TEX0.TBP0, psm_str(m_context->TEX0.PSM));
s = StringUtil::StdStringFromFormat("%05d_f%lld_itexraw_%05x_%s.bmp", s_n, frame, (int)m_context->TEX0.TBP0, psm_str(m_context->TEX0.PSM));
m_mem.SaveBMP(m_dump_root + s, m_context->TEX0.TBP0, m_context->TEX0.TBW, m_context->TEX0.PSM, 1 << m_context->TEX0.TW, 1 << m_context->TEX0.TH);
}
@ -485,17 +486,17 @@ void GSRendererSW::Draw()
if (texture_shuffle)
{
// Dump the RT in 32 bits format. It helps to debug texture shuffle effect
s = format("%05d_f%lld_rt0_%05x_32bits.bmp", s_n, frame, m_context->FRAME.Block());
s = StringUtil::StdStringFromFormat("%05d_f%lld_rt0_%05x_32bits.bmp", s_n, frame, m_context->FRAME.Block());
m_mem.SaveBMP(m_dump_root + s, m_context->FRAME.Block(), m_context->FRAME.FBW, 0, GetFrameRect().width(), 512);
}
s = format("%05d_f%lld_rt0_%05x_%s.bmp", s_n, frame, m_context->FRAME.Block(), psm_str(m_context->FRAME.PSM));
s = StringUtil::StdStringFromFormat("%05d_f%lld_rt0_%05x_%s.bmp", s_n, frame, m_context->FRAME.Block(), psm_str(m_context->FRAME.PSM));
m_mem.SaveBMP(m_dump_root + s, m_context->FRAME.Block(), m_context->FRAME.FBW, m_context->FRAME.PSM, GetFrameRect().width(), 512);
}
if (s_savez && s_n >= s_saven)
{
s = format("%05d_f%lld_rz0_%05x_%s.bmp", s_n, frame, m_context->ZBUF.Block(), psm_str(m_context->ZBUF.PSM));
s = StringUtil::StdStringFromFormat("%05d_f%lld_rz0_%05x_%s.bmp", s_n, frame, m_context->ZBUF.Block(), psm_str(m_context->ZBUF.PSM));
m_mem.SaveBMP(m_dump_root + s, m_context->ZBUF.Block(), m_context->FRAME.FBW, m_context->ZBUF.PSM, GetFrameRect().width(), 512);
}
@ -509,17 +510,17 @@ void GSRendererSW::Draw()
if (texture_shuffle)
{
// Dump the RT in 32 bits format. It helps to debug texture shuffle effect
s = format("%05d_f%lld_rt1_%05x_32bits.bmp", s_n, frame, m_context->FRAME.Block());
s = StringUtil::StdStringFromFormat("%05d_f%lld_rt1_%05x_32bits.bmp", s_n, frame, m_context->FRAME.Block());
m_mem.SaveBMP(m_dump_root + s, m_context->FRAME.Block(), m_context->FRAME.FBW, 0, GetFrameRect().width(), 512);
}
s = format("%05d_f%lld_rt1_%05x_%s.bmp", s_n, frame, m_context->FRAME.Block(), psm_str(m_context->FRAME.PSM));
s = StringUtil::StdStringFromFormat("%05d_f%lld_rt1_%05x_%s.bmp", s_n, frame, m_context->FRAME.Block(), psm_str(m_context->FRAME.PSM));
m_mem.SaveBMP(m_dump_root + s, m_context->FRAME.Block(), m_context->FRAME.FBW, m_context->FRAME.PSM, GetFrameRect().width(), 512);
}
if (s_savez && s_n >= s_saven)
{
s = format("%05d_f%lld_rz1_%05x_%s.bmp", s_n, frame, m_context->ZBUF.Block(), psm_str(m_context->ZBUF.PSM));
s = StringUtil::StdStringFromFormat("%05d_f%lld_rz1_%05x_%s.bmp", s_n, frame, m_context->ZBUF.Block(), psm_str(m_context->ZBUF.PSM));
m_mem.SaveBMP(m_dump_root + s, m_context->ZBUF.Block(), m_context->FRAME.FBW, m_context->ZBUF.PSM, GetFrameRect().width(), 512);
}
@ -607,14 +608,14 @@ void GSRendererSW::Sync(int reason)
if (s_save)
{
s = format("%05d_f%lld_rt1_%05x_%s.bmp", s_n, g_perfmon.GetFrame(), m_context->FRAME.Block(), psm_str(m_context->FRAME.PSM));
s = StringUtil::StdStringFromFormat("%05d_f%lld_rt1_%05x_%s.bmp", s_n, g_perfmon.GetFrame(), m_context->FRAME.Block(), psm_str(m_context->FRAME.PSM));
m_mem.SaveBMP(m_dump_root + s, m_context->FRAME.Block(), m_context->FRAME.FBW, m_context->FRAME.PSM, GetFrameRect().width(), 512);
}
if (s_savez)
{
s = format("%05d_f%lld_zb1_%05x_%s.bmp", s_n, g_perfmon.GetFrame(), m_context->ZBUF.Block(), psm_str(m_context->ZBUF.PSM));
s = StringUtil::StdStringFromFormat("%05d_f%lld_zb1_%05x_%s.bmp", s_n, g_perfmon.GetFrame(), m_context->ZBUF.Block(), psm_str(m_context->ZBUF.PSM));
m_mem.SaveBMP(m_dump_root + s, m_context->ZBUF.Block(), m_context->FRAME.FBW, m_context->ZBUF.PSM, GetFrameRect().width(), 512);
}
@ -1571,7 +1572,7 @@ void GSRendererSW::SharedData::UpdateSource()
{
const GIFRegTEX0& TEX0 = g_gs_renderer->GetTex0Layer(i);
s = format("%05d_f%lld_itex%d_%05x_%s.bmp", g_gs_renderer->s_n, frame, i, TEX0.TBP0, psm_str(TEX0.PSM));
s = StringUtil::StdStringFromFormat("%05d_f%lld_itex%d_%05x_%s.bmp", g_gs_renderer->s_n, frame, i, TEX0.TBP0, psm_str(TEX0.PSM));
m_tex[i].t->Save(root_sw + s);
}
@ -1582,7 +1583,7 @@ void GSRendererSW::SharedData::UpdateSource()
t->Update(GSVector4i(0, 0, 256, 1), global.clut, sizeof(u32) * 256);
s = format("%05d_f%lld_itexp_%05x_%s.bmp", g_gs_renderer->s_n, frame, (int)g_gs_renderer->m_context->TEX0.CBP, psm_str(g_gs_renderer->m_context->TEX0.CPSM));
s = StringUtil::StdStringFromFormat("%05d_f%lld_itexp_%05x_%s.bmp", g_gs_renderer->s_n, frame, (int)g_gs_renderer->m_context->TEX0.CBP, psm_str(g_gs_renderer->m_context->TEX0.CPSM));
t->Save(root_sw + s);

View File

@ -17,6 +17,7 @@
#include "GS.h"
#include "GSCaptureDlg.h"
#include "GS/GSExtra.h"
#include "common/StringUtil.h"
#include <commdlg.h>
// Ideally this belongs in WIL, but CAUUID is used by a *single* COM function in WinAPI.
@ -57,7 +58,7 @@ GSCaptureDlg::GSCaptureDlg()
{
m_width = theApp.GetConfigI("CaptureWidth");
m_height = theApp.GetConfigI("CaptureHeight");
m_filename = convert_utf8_to_utf16(theApp.GetConfigS("CaptureFileName"));
m_filename = StringUtil::UTF8StringToWideString(theApp.GetConfigS("CaptureFileName"));
}
int GSCaptureDlg::GetSelCodec(Codec& c)
@ -118,7 +119,7 @@ void GSCaptureDlg::OnInit()
m_codecs.clear();
const std::wstring selected = convert_utf8_to_utf16(theApp.GetConfigS("CaptureVideoCodecDisplayName"));
const std::wstring selected = StringUtil::UTF8StringToWideString(theApp.GetConfigS("CaptureVideoCodecDisplayName"));
ComboBoxAppend(IDC_CODECS, "Uncompressed", 0, true);
ComboBoxAppend(IDC_COLORSPACE, "YUY2", 0, true);
@ -244,10 +245,10 @@ bool GSCaptureDlg::OnCommand(HWND hWnd, UINT id, UINT code)
theApp.SetConfig("CaptureWidth", m_width);
theApp.SetConfig("CaptureHeight", m_height);
theApp.SetConfig("CaptureFileName", convert_utf16_to_utf8(m_filename).c_str());
theApp.SetConfig("CaptureFileName", StringUtil::WideStringToUTF8String(m_filename).c_str());
if (ris != 2)
theApp.SetConfig("CaptureVideoCodecDisplayName", convert_utf16_to_utf8(c.DisplayName).c_str());
theApp.SetConfig("CaptureVideoCodecDisplayName", StringUtil::WideStringToUTF8String(c.DisplayName).c_str());
else
theApp.SetConfig("CaptureVideoCodecDisplayName", "");
break;

View File

@ -16,6 +16,7 @@
#pragma once
#include "GSSetting.h"
#include "common/RedtapeWindows.h"
class GSDialog
{

View File

@ -653,7 +653,7 @@ static __ri bool ipuPACK(tIPU_CMD_CSC csc)
ipu_cmd.pos[1] = 0;
}
return TRUE;
return true;
}
static void ipuSETTH(u32 val)

View File

@ -27,6 +27,14 @@
#include "ghc/filesystem.h"
#include "common/FileSystem.h"
#include <fcntl.h>
#ifdef _WIN32
#include <io.h>
#else
#include <unistd.h>
#endif
#if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG)
#define S_ISREG(m) (((m)&S_IFMT) == S_IFREG)
#endif

View File

@ -17,7 +17,6 @@
#include "Common.h"
#include <list>
#include <wx/datetime.h>
#include "common/ScopedGuard.h"
#include "common/StringUtil.h"

View File

@ -35,7 +35,6 @@ BIOS
*/
#include "PrecompiledHeader.h"
#include <wx/file.h>
#include "IopHw.h"
#include "GS.h"

View File

@ -16,10 +16,8 @@
#include "PrecompiledHeader.h"
#include "common/FileSystem.h"
#include "common/SafeArray.inl"
#include "common/Path.h"
#include "common/StringUtil.h"
#include <wx/file.h>
#include <wx/dir.h>
#include <wx/stopwatch.h>
#include <array>
#include <chrono>
@ -35,7 +33,6 @@
#include "fmt/core.h"
#include <wx/ffile.h>
#include <map>
static const int MCD_SIZE = 1024 * 8 * 16; // Legacy PSX card default size
@ -91,67 +88,73 @@ static u32 CalculateECC(u8* buf)
return column_parity | (line_parity_0 << 8) | (line_parity_1 << 16);
}
static bool ConvertNoECCtoRAW(wxString file_in, wxString file_out)
static bool ConvertNoECCtoRAW(const char* file_in, const char* file_out)
{
bool result = false;
wxFFile fin(file_in, "rb");
auto fin = FileSystem::OpenManagedCFile(file_in, "rb");
if (!fin)
return false;
if (fin.IsOpened())
auto fout = FileSystem::OpenManagedCFile(file_out, "wb");
if (!fout)
return false;
const s64 size = FileSystem::FSize64(fin.get());
u8 buffer[512];
for (s64 i = 0; i < (size / 512); i++)
{
wxFFile fout(file_out, "wb");
if (fout.IsOpened())
if (std::fread(buffer, sizeof(buffer), 1, fin.get()) != 1 ||
std::fwrite(buffer, sizeof(buffer), 1, fout.get()) != 1)
{
u8 buffer[512];
size_t size = fin.Length();
for (size_t i = 0; i < (size / 512); i++)
{
fin.Read(buffer, 512);
fout.Write(buffer, 512);
for (int j = 0; j < 4; j++)
{
u32 checksum = CalculateECC(&buffer[j * 128]);
fout.Write(&checksum, 3);
}
fout.Write("\0\0\0\0", 4);
}
result = true;
return false;
}
for (int j = 0; j < 4; j++)
{
u32 checksum = CalculateECC(&buffer[j * 128]);
if (std::fwrite(&checksum, 3, 1, fout.get()) != 1)
return false;
}
u32 nullbytes = 0;
if (std::fwrite(&nullbytes, sizeof(nullbytes), 1, fout.get()) != 1)
return false;
}
return result;
if (std::fflush(fout.get()) != 0)
return false;
return true;
}
static bool ConvertRAWtoNoECC(wxString file_in, wxString file_out)
static bool ConvertRAWtoNoECC(const char* file_in, const char* file_out)
{
bool result = false;
wxFFile fout(file_out, "wb");
auto fin = FileSystem::OpenManagedCFile(file_in, "rb");
if (!fin)
return false;
if (fout.IsOpened())
auto fout = FileSystem::OpenManagedCFile(file_out, "wb");
if (!fout)
return false;
const s64 size = FileSystem::FSize64(fin.get());
u8 buffer[512];
u8 checksum[16];
for (s64 i = 0; i < (size / 528); i++)
{
wxFFile fin(file_in, "rb");
if (fin.IsOpened())
if (std::fread(buffer, sizeof(buffer), 1, fin.get()) != 1 ||
std::fwrite(buffer, sizeof(buffer), 1, fout.get()) != 1 ||
std::fread(checksum, sizeof(checksum), 1, fin.get()) != 1)
{
u8 buffer[512];
size_t size = fin.Length();
for (size_t i = 0; i < (size / 528); i++)
{
fin.Read(buffer, 512);
fout.Write(buffer, 512);
fin.Read(buffer, 16);
}
result = true;
return false;
}
}
return result;
if (std::fflush(fout.get()) != 0)
return false;
return true;
}
// --------------------------------------------------------------------------------------
@ -162,7 +165,8 @@ static bool ConvertRAWtoNoECC(wxString file_in, wxString file_out)
class FileMemoryCard
{
protected:
wxFFile m_file[8];
std::FILE* m_file[8];
std::string m_filenames[8];
u8 m_effeffs[528 * 16];
SafeArray<u8> m_currentdata;
u64 m_chksum[8];
@ -188,14 +192,8 @@ public:
u64 GetCRC(uint slot);
protected:
bool Seek(wxFFile& f, u32 adr);
bool Create(const wxString& mcdFile, uint sizeInMB);
std::string GetDisabledMessage(uint slot) const
{
return fmt::format("The PS2-slot {} has been automatically disabled. You can correct the problem\nand re-enable it at any time using Config:Memory cards from the main menu.", slot //TODO: translate internal slot index to human-readable slot description
);
}
bool Seek(std::FILE* f, u32 adr);
bool Create(const char* mcdFile, uint sizeInMB);
};
uint FileMcd_GetMtapPort(uint slot)
@ -276,6 +274,8 @@ void FileMemoryCard::Open()
{
for (int slot = 0; slot < 8; ++slot)
{
m_filenames[slot] = {};
if (FileMcd_IsMultitapSlot(slot))
{
if (!EmuConfig.MultitapPort0_Enabled && (FileMcd_GetMtapPort(slot) == 0))
@ -284,46 +284,43 @@ void FileMemoryCard::Open()
continue;
}
wxFileName fname(EmuConfig.FullpathToMcd(slot));
wxString str(fname.GetFullPath());
std::string fname(EmuConfig.FullpathToMcd(slot));
std::string_view str(fname);
bool cont = false;
if (fname.GetFullName().IsEmpty())
if (fname.empty())
{
str = L"[empty filename]";
str = "[empty filename]";
cont = true;
}
if (!EmuConfig.Mcd[slot].Enabled)
{
str = L"[disabled]";
str = "[disabled]";
cont = true;
}
if (EmuConfig.Mcd[slot].Type != MemoryCardType::File)
{
str = L"[is not memcard file]";
str = "[is not memcard file]";
cont = true;
}
Console.WriteLn(cont ? Color_Gray : Color_Green, "McdSlot %u [File]: %s", slot, StringUtil::wxStringToUTF8String(str).c_str());
Console.WriteLn(cont ? Color_Gray : Color_Green, "McdSlot %u [File]: %.*s", slot,
static_cast<int>(str.size()), str.data());
if (cont)
continue;
const wxULongLong fsz = fname.GetSize();
if ((fsz == 0) || (fsz == wxInvalidSize))
if (FileSystem::GetPathFileSize(fname.c_str()) <= 0)
{
// FIXME : Ideally this should prompt the user for the size of the
// memory card file they would like to create, instead of trying to
// create one automatically.
if (!Create(str, 8))
if (!Create(fname.c_str(), 8))
{
#ifndef PCSX2_CORE
Msgbox::Alert(
wxString::Format(_("Could not create a memory card: \n\n%s\n\n"), str.c_str()) +
StringUtil::UTF8StringToWxString(GetDisabledMessage(slot)));
#endif
Host::ReportFormattedErrorAsync("Memory Card", "Could not create a memory card: \n\n%s\n\n",
fname.c_str());
}
}
@ -331,38 +328,43 @@ void FileMemoryCard::Open()
// (8MB, 256Mb, formatted, unformatted, etc ...)
#ifdef _WIN32
FileSystem::SetPathCompression(StringUtil::wxStringToUTF8String(str).c_str(), EmuConfig.McdCompressNTFS);
FileSystem::SetPathCompression(fname.c_str(), EmuConfig.McdCompressNTFS);
#endif
if (str.EndsWith(".bin"))
if (StringUtil::EndsWith(fname, ".bin"))
{
wxString newname = str + "x";
if (!ConvertNoECCtoRAW(str, newname))
std::string newname(fname + "x");
if (!ConvertNoECCtoRAW(fname.c_str(), newname.c_str()))
{
Console.Error("Could convert memory card: %s", str.ToUTF8().data());
wxRemoveFile(newname);
Console.Error("Could convert memory card: %s", fname.c_str());
FileSystem::DeleteFilePath(newname.c_str());
continue;
}
str = newname;
// store the original filename
m_file[slot] = FileSystem::OpenCFile(newname.c_str(), "r+b");
}
else
{
m_file[slot] = FileSystem::OpenCFile(fname.c_str(), "r+b");
}
if (!m_file[slot].Open(str.c_str(), L"r+b"))
if (!m_file[slot])
{
// Translation note: detailed description should mention that the memory card will be disabled
// for the duration of this session.
#ifndef PCSX2_CORE
Msgbox::Alert(
wxString::Format(_("Access denied to memory card: \n\n%s\n\n"), str.c_str()) +
StringUtil::UTF8StringToWxString(GetDisabledMessage(slot)));
#endif
Host::ReportFormattedErrorAsync("Memory Card", "Access denied to memory card: \n\n%s\n\n"
"The PS2-slot %d has been automatically disabled. You can correct the problem\nand re-enable it at any time using Config:Memory cards from the main menu.",
fname.c_str(), slot);
}
else // Load checksum
{
m_ispsx[slot] = m_file[slot].Length() == 0x20000;
m_filenames[slot] = std::move(fname);
m_ispsx[slot] = FileSystem::FSize64(m_file[slot]) == 0x20000;
m_chkaddr = 0x210;
if (!m_ispsx[slot] && !!m_file[slot].Seek(m_chkaddr))
m_file[slot].Read(&m_chksum[slot], 8);
if (!m_ispsx[slot] && FileSystem::FSeek64(m_file[slot], m_chkaddr, SEEK_SET) == 0)
std::fread(&m_chksum[slot], sizeof(m_chksum[slot]), 1, m_file[slot]);
}
}
}
@ -371,29 +373,31 @@ void FileMemoryCard::Close()
{
for (int slot = 0; slot < 8; ++slot)
{
if (m_file[slot].IsOpened())
if (!m_file[slot])
continue;
// Store checksum
if (!m_ispsx[slot] && FileSystem::FSeek64(m_file[slot], m_chkaddr, SEEK_SET) == 0)
std::fwrite(&m_chksum[slot], sizeof(m_chksum[slot]), 1, m_file[slot]);
std::fclose(m_file[slot]);
m_file[slot] = nullptr;
if (StringUtil::EndsWith(m_filenames[slot], ".bin"))
{
// Store checksum
if (!m_ispsx[slot] && !!m_file[slot].Seek(m_chkaddr))
m_file[slot].Write(&m_chksum[slot], 8);
m_file[slot].Close();
if (m_file[slot].GetName().EndsWith(".binx"))
{
wxString name = m_file[slot].GetName();
wxString name_old = name.SubString(0, name.Last('.')) + "bin";
if (ConvertRAWtoNoECC(name, name_old))
wxRemoveFile(name);
}
const std::string name_in(m_filenames[slot] + 'x');
if (ConvertRAWtoNoECC(name_in.c_str(), m_filenames[slot].c_str()))
FileSystem::DeleteFilePath(name_in.c_str());
}
m_filenames[slot] = {};
}
}
// Returns FALSE if the seek failed (is outside the bounds of the file).
bool FileMemoryCard::Seek(wxFFile& f, u32 adr)
bool FileMemoryCard::Seek(std::FILE* f, u32 adr)
{
const u32 size = f.Length();
const s64 size = FileSystem::FSize64(f);
// If anyone knows why this filesize logic is here (it appears to be related to legacy PSX
// cards, perhaps hacked support for some special emulator-specific memcard formats that
@ -410,23 +414,23 @@ bool FileMemoryCard::Seek(wxFFile& f, u32 adr)
// perform sanity checks here?
}
return f.Seek(adr + offset);
return (FileSystem::FSeek64(f, adr + offset, SEEK_SET) == 0);
}
// returns FALSE if an error occurred (either permission denied or disk full)
bool FileMemoryCard::Create(const wxString& mcdFile, uint sizeInMB)
bool FileMemoryCard::Create(const char* mcdFile, uint sizeInMB)
{
//int enc[16] = {0x77,0x7f,0x7f,0x77,0x7f,0x7f,0x77,0x7f,0x7f,0x77,0x7f,0x7f,0,0,0,0};
Console.WriteLn("(FileMcd) Creating new %uMB memory card: %s", sizeInMB, mcdFile.ToUTF8().data());
Console.WriteLn("(FileMcd) Creating new %uMB memory card: %s", sizeInMB, mcdFile);
wxFFile fp(mcdFile, L"wb");
if (!fp.IsOpened())
auto fp = FileSystem::OpenManagedCFile(mcdFile, "wb");
if (!fp)
return false;
for (uint i = 0; i < (MC2_MBSIZE * sizeInMB) / sizeof(m_effeffs); i++)
{
if (fp.Write(m_effeffs, sizeof(m_effeffs)) == 0)
if (std::fwrite(m_effeffs, sizeof(m_effeffs), 1, fp.get()) != 1)
return false;
}
return true;
@ -434,7 +438,7 @@ bool FileMemoryCard::Create(const wxString& mcdFile, uint sizeInMB)
s32 FileMemoryCard::IsPresent(uint slot)
{
return m_file[slot].IsOpened();
return m_file[slot] != nullptr;
}
void FileMemoryCard::GetSizeInfo(uint slot, McdSizeInfo& outways)
@ -443,8 +447,8 @@ void FileMemoryCard::GetSizeInfo(uint slot, McdSizeInfo& outways)
outways.EraseBlockSizeInSectors = 16; // 0x0010
outways.Xor = 18; // 0x12, XOR 02 00 00 10
if (pxAssert(m_file[slot].IsOpened()))
outways.McdSizeInSectors = m_file[slot].Length() / (outways.SectorSize + outways.EraseBlockSizeInSectors);
if (pxAssert(m_file[slot]))
outways.McdSizeInSectors = static_cast<u32>(FileSystem::FSize64(m_file[slot])) / (outways.SectorSize + outways.EraseBlockSizeInSectors);
else
outways.McdSizeInSectors = 0x4000;
@ -459,8 +463,8 @@ bool FileMemoryCard::IsPSX(uint slot)
s32 FileMemoryCard::Read(uint slot, u8* dest, u32 adr, int size)
{
wxFFile& mcfp(m_file[slot]);
if (!mcfp.IsOpened())
std::FILE* mcfp = m_file[slot];
if (!mcfp)
{
DevCon.Error("(FileMcd) Ignoring attempted read from disabled slot.");
memset(dest, 0, size);
@ -468,14 +472,14 @@ s32 FileMemoryCard::Read(uint slot, u8* dest, u32 adr, int size)
}
if (!Seek(mcfp, adr))
return 0;
return mcfp.Read(dest, size) != 0;
return std::fread(dest, size, 1, mcfp) == 1;
}
s32 FileMemoryCard::Save(uint slot, const u8* src, u32 adr, int size)
{
wxFFile& mcfp(m_file[slot]);
std::FILE* mcfp = m_file[slot];
if (!mcfp.IsOpened())
if (!mcfp)
{
DevCon.Error("(FileMcd) Ignoring attempted save/write to disabled slot.");
return 1;
@ -492,7 +496,7 @@ s32 FileMemoryCard::Save(uint slot, const u8* src, u32 adr, int size)
if (!Seek(mcfp, adr))
return 0;
m_currentdata.MakeRoomFor(size);
mcfp.Read(m_currentdata.GetPtr(), size);
std::fread(m_currentdata.GetPtr(), size, 1, mcfp);
for (int i = 0; i < size; i++)
@ -518,18 +522,16 @@ s32 FileMemoryCard::Save(uint slot, const u8* src, u32 adr, int size)
if (!Seek(mcfp, adr))
return 0;
int status = mcfp.Write(m_currentdata.GetPtr(), size);
if (status)
if (std::fwrite(m_currentdata.GetPtr(), size, 1, mcfp) == 1)
{
static auto last = std::chrono::time_point<std::chrono::system_clock>();
std::chrono::duration<float> elapsed = std::chrono::system_clock::now() - last;
if (elapsed > std::chrono::seconds(5))
{
wxString name, ext;
wxFileName::SplitPath(m_file[slot].GetName(), NULL, NULL, &name, &ext);
Host::AddOSDMessage(StringUtil::StdStringFromFormat("Memory Card %s written.", (const char*)(name + "." + ext).c_str()), 10.0f);
const std::string_view filename(Path::GetFileName(m_filenames[slot]));
Host::AddKeyedFormattedOSDMessage(StringUtil::StdStringFromFormat("MemoryCardSave%u", slot), 10.0f,
"Memory Card %.*s written.", static_cast<int>(filename.size()), static_cast<const char*>(filename.data()));
last = std::chrono::system_clock::now();
}
return 1;
@ -540,9 +542,8 @@ s32 FileMemoryCard::Save(uint slot, const u8* src, u32 adr, int size)
s32 FileMemoryCard::EraseBlock(uint slot, u32 adr)
{
wxFFile& mcfp(m_file[slot]);
if (!mcfp.IsOpened())
std::FILE* mcfp = m_file[slot];
if (!mcfp)
{
DevCon.Error("MemoryCard: Ignoring erase for disabled slot.");
return 1;
@ -550,13 +551,13 @@ s32 FileMemoryCard::EraseBlock(uint slot, u32 adr)
if (!Seek(mcfp, adr))
return 0;
return mcfp.Write(m_effeffs, sizeof(m_effeffs)) != 0;
return std::fwrite(m_effeffs, sizeof(m_effeffs), 1, mcfp) == 1;
}
u64 FileMemoryCard::GetCRC(uint slot)
{
wxFFile& mcfp(m_file[slot]);
if (!mcfp.IsOpened())
std::FILE* mcfp = m_file[slot];
if (!mcfp)
return 0;
u64 retval = 0;
@ -566,14 +567,20 @@ u64 FileMemoryCard::GetCRC(uint slot)
if (!Seek(mcfp, 0))
return 0;
const s64 mcfpsize = FileSystem::FSize64(mcfp);
if (mcfpsize < 0)
return 0;
// Process the file in 4k chunks. Speeds things up significantly.
u64 buffer[528 * 8]; // use 528 (sector size), ensures even divisibility
const uint filesize = mcfp.Length() / sizeof(buffer);
const uint filesize = static_cast<uint>(mcfpsize) / sizeof(buffer);
for (uint i = filesize; i; --i)
{
mcfp.Read(&buffer, sizeof(buffer));
if (std::fread(buffer, sizeof(buffer), 1, mcfp) != 1)
return 0;
for (uint t = 0; t < std::size(buffer); ++t)
retval ^= buffer[t];
}
@ -616,15 +623,9 @@ void FileMcd_EmuOpen()
{
MemoryCardType type = MemoryCardType::File; // default to file if we can't find anything at the path so it gets auto-generated
const wxString path = EmuConfig.FullpathToMcd(slot);
if (wxFileExists(path))
{
type = MemoryCardType::File;
}
else if (wxDirExists(path))
{
const std::string path(EmuConfig.FullpathToMcd(slot));
if (FileSystem::DirectoryExists(path.c_str()))
type = MemoryCardType::Folder;
}
EmuConfig.Mcd[slot].Type = type;
}
@ -760,7 +761,7 @@ void FileMcd_NextFrame(uint port, uint slot)
}
}
bool FileMcd_ReIndex(uint port, uint slot, const wxString& filter)
bool FileMcd_ReIndex(uint port, uint slot, const std::string& filter)
{
const uint combinedSlot = FileMcd_ConvertToSlot(port, slot);
switch (EmuConfig.Mcd[combinedSlot].Type)
@ -780,50 +781,6 @@ bool FileMcd_ReIndex(uint port, uint slot, const wxString& filter)
// Library API Implementations
// --------------------------------------------------------------------------------------
//Tests if a string is a valid name for a new file within a specified directory.
//returns true if:
// - the file name has a minimum length of minNumCharacters chars (default is 5 chars: at least 1 char + '.' + 3-chars extension)
// and - the file name is within the basepath directory (doesn't contain .. , / , \ , etc)
// and - file name doesn't already exist
// and - can be created on current system (it is actually created and deleted for this test).
bool isValidNewFilename(wxString filenameStringToTest, wxDirName atBasePath, wxString& out_errorMessage, uint minNumCharacters)
{
if (filenameStringToTest.Length() < 1 || filenameStringToTest.Length() < minNumCharacters)
{
out_errorMessage = _("File name empty or too short");
return false;
}
if ((atBasePath + wxFileName(filenameStringToTest)).GetFullPath() != (atBasePath + wxFileName(filenameStringToTest).GetFullName()).GetFullPath())
{
out_errorMessage = _("File name outside of required directory");
return false;
}
if (wxFileExists((atBasePath + wxFileName(filenameStringToTest)).GetFullPath()))
{
out_errorMessage = _("File name already exists");
return false;
}
if (wxDirExists((atBasePath + wxFileName(filenameStringToTest)).GetFullPath()))
{
out_errorMessage = _("File name already exists");
return false;
}
wxFile fp;
if (!fp.Create((atBasePath + wxFileName(filenameStringToTest)).GetFullPath()))
{
out_errorMessage = _("The Operating-System prevents this file from being created");
return false;
}
fp.Close();
wxRemoveFile((atBasePath + wxFileName(filenameStringToTest)).GetFullPath());
out_errorMessage = L"[OK - New file name is valid]"; //shouldn't be displayed on success, hence not translatable.
return true;
}
static MemoryCardFileType GetMemoryCardFileTypeFromSize(s64 size)
{
if (size == (8 * MC2_MBSIZE))
@ -842,7 +799,7 @@ static MemoryCardFileType GetMemoryCardFileTypeFromSize(s64 size)
static bool IsMemoryCardFolder(const std::string& path)
{
const std::string superblock_path(Path::CombineStdString(path, s_folder_mem_card_id_file));
const std::string superblock_path(Path::Combine(path, s_folder_mem_card_id_file));
return FileSystem::FileExists(superblock_path.c_str());
}
@ -867,7 +824,7 @@ static bool IsMemoryCardFormatted(const std::string& path)
std::vector<AvailableMcdInfo> FileMcd_GetAvailableCards(bool include_in_use_cards)
{
std::vector<FILESYSTEM_FIND_DATA> files;
FileSystem::FindFiles(EmuFolders::MemoryCards.ToUTF8(), "*",
FileSystem::FindFiles(EmuFolders::MemoryCards.c_str(), "*",
FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_FOLDERS | FILESYSTEM_FIND_HIDDEN_FILES, &files);
std::vector<AvailableMcdInfo> mcds;
@ -875,7 +832,7 @@ std::vector<AvailableMcdInfo> FileMcd_GetAvailableCards(bool include_in_use_card
for (FILESYSTEM_FIND_DATA& fd : files)
{
std::string basename(FileSystem::GetFileNameFromPath(fd.FileName));
std::string basename(Path::GetFileName(fd.FileName));
if (!include_in_use_cards)
{
bool in_use = false;
@ -919,7 +876,7 @@ std::optional<AvailableMcdInfo> FileMcd_GetCardInfo(const std::string_view& name
std::optional<AvailableMcdInfo> ret;
std::string basename(name);
std::string path(Path::CombineStdString(EmuFolders::MemoryCards, basename));
std::string path(Path::Combine(EmuFolders::MemoryCards, basename));
FILESYSTEM_STAT_DATA sd;
if (!FileSystem::StatFile(path.c_str(), &sd))
@ -949,7 +906,7 @@ std::optional<AvailableMcdInfo> FileMcd_GetCardInfo(const std::string_view& name
bool FileMcd_CreateNewCard(const std::string_view& name, MemoryCardType type, MemoryCardFileType file_type)
{
const std::string full_path(Path::CombineStdString(EmuFolders::MemoryCards, name));
const std::string full_path(Path::Combine(EmuFolders::MemoryCards, name));
if (type == MemoryCardType::Folder)
{
@ -962,7 +919,7 @@ bool FileMcd_CreateNewCard(const std::string_view& name, MemoryCardType type, Me
}
// write the superblock
auto fp = FileSystem::OpenManagedCFile(Path::CombineStdString(full_path, s_folder_mem_card_id_file).c_str(), "wb");
auto fp = FileSystem::OpenManagedCFile(Path::Combine(full_path, s_folder_mem_card_id_file).c_str(), "wb");
if (!fp)
{
Host::ReportFormattedErrorAsync("Memory Card Creation Failed", "Failed to write memory card folder superblock '%s'.", full_path.c_str());
@ -1038,8 +995,8 @@ bool FileMcd_CreateNewCard(const std::string_view& name, MemoryCardType type, Me
bool FileMcd_RenameCard(const std::string_view& name, const std::string_view& new_name)
{
const std::string name_path(Path::CombineStdString(EmuFolders::MemoryCards, name));
const std::string new_name_path(Path::CombineStdString(EmuFolders::MemoryCards, new_name));
const std::string name_path(Path::Combine(EmuFolders::MemoryCards, name));
const std::string new_name_path(Path::Combine(EmuFolders::MemoryCards, new_name));
FILESYSTEM_STAT_DATA sd, new_sd;
if (!FileSystem::StatFile(name_path.c_str(), &sd) || FileSystem::StatFile(new_name_path.c_str(), &new_sd))
@ -1063,7 +1020,7 @@ bool FileMcd_RenameCard(const std::string_view& name, const std::string_view& ne
bool FileMcd_DeleteCard(const std::string_view& name)
{
const std::string name_path(Path::CombineStdString(EmuFolders::MemoryCards, name));
const std::string name_path(Path::Combine(EmuFolders::MemoryCards, name));
FILESYSTEM_STAT_DATA sd;
if (!FileSystem::StatFile(name_path.c_str(), &sd))

View File

@ -44,8 +44,6 @@ extern uint FileMcd_GetMtapSlot(uint slot);
extern bool FileMcd_IsMultitapSlot(uint slot);
//extern wxFileName FileMcd_GetSimpleName(uint slot);
extern std::string FileMcd_GetDefaultName(uint slot);
extern bool isValidNewFilename(wxString filenameStringToTest, wxDirName atBasePath, wxString& out_errorMessage, uint minNumCharacters = 5);
uint FileMcd_ConvertToSlot(uint port, uint slot);
void FileMcd_EmuOpen();
@ -58,7 +56,7 @@ s32 FileMcd_Save(uint port, uint slot, const u8* src, u32 adr, int size);
s32 FileMcd_EraseBlock(uint port, uint slot, u32 adr);
u64 FileMcd_GetCRC(uint port, uint slot);
void FileMcd_NextFrame(uint port, uint slot);
bool FileMcd_ReIndex(uint port, uint slot, const wxString& filter);
bool FileMcd_ReIndex(uint port, uint slot, const std::string& filter);
std::vector<AvailableMcdInfo> FileMcd_GetAvailableCards(bool include_in_use_cards);
std::optional<AvailableMcdInfo> FileMcd_GetCardInfo(const std::string_view& name);

File diff suppressed because it is too large Load Diff

View File

@ -15,10 +15,9 @@
#pragma once
#include <wx/file.h>
#include <wx/dir.h>
#include <wx/ffile.h>
#include <map>
#include <string>
#include <string_view>
#include <vector>
#include "Config.h"
@ -64,61 +63,9 @@ struct MemoryCardFileEntryDateTime
u8 month;
u16 year;
static MemoryCardFileEntryDateTime FromWxDateTime(const wxDateTime& time)
{
MemoryCardFileEntryDateTime t;
static MemoryCardFileEntryDateTime FromTime(time_t time);
if (time.IsValid())
{
wxDateTime::Tm tm = time.GetTm(wxDateTime::GMT9);
t.unused = 0;
t.second = tm.sec;
t.minute = tm.min;
t.hour = tm.hour;
t.day = tm.mday;
t.month = tm.mon + 1;
t.year = tm.year;
}
else
{
t.unused = 0;
t.second = 0;
t.minute = 0;
t.hour = 0;
t.day = 0;
t.month = 0;
t.year = 0;
}
return t;
}
static MemoryCardFileEntryDateTime FromTime(time_t time)
{
// TODO: When wx is gone, this will have to be handled differently; for now, rely on wx
return FromWxDateTime(wxDateTime(time));
}
wxDateTime ToWxDateTime() const
{
wxDateTime::Tm tm;
tm.sec = this->second;
tm.min = this->minute;
tm.hour = this->hour;
tm.mday = this->day;
tm.mon = (wxDateTime::Month)(this->month - 1);
tm.year = this->year;
wxDateTime time(tm);
return time.FromTimezone(wxDateTime::GMT9);
}
time_t ToTime() const
{
// TODO: When wx is gone, this will have to be handled differently; for now, rely on wx
return ToWxDateTime().GetTicks();
}
time_t ToTime() const;
bool operator==(const MemoryCardFileEntryDateTime& other) const
{
@ -228,7 +175,7 @@ struct MemoryCardFileMetadataReference
u32 consecutiveCluster;
// returns true if filename was modified and metadata containing the actual filename should be written
bool GetPath(wxFileName* fileName) const;
bool GetPath(std::string* fileName) const;
// gives the internal memory card file system path, not to be used for writes to the host file system
void GetInternalPath(std::string* fileName) const;
@ -237,7 +184,8 @@ struct MemoryCardFileMetadataReference
struct MemoryCardFileHandleStructure
{
MemoryCardFileMetadataReference* fileRef;
wxFFile* fileHandle;
std::string hostFilePath;
std::FILE* fileHandle;
};
// --------------------------------------------------------------------------------------
@ -255,9 +203,9 @@ public:
~FileAccessHelper();
// Get an already opened file if possible, or open a new one and remember it
wxFFile* ReOpen(const wxFileName& folderName, MemoryCardFileMetadataReference* fileRef, bool writeMetadata = false);
std::FILE* ReOpen(const std::string_view& folderName, MemoryCardFileMetadataReference* fileRef, bool writeMetadata = false);
// Close all open files that start with the given path, so either a file if a filename is given or all files in a directory and its subdirectories when a directory is given
void CloseMatching(const wxString& path);
void CloseMatching(const std::string_view& path);
// Close all open files
void CloseAll();
// Flush the written data of all open files to the file system
@ -270,19 +218,19 @@ public:
// returns true if any changes were made
static bool CleanMemcardFilename(char* name);
static void WriteIndex(wxFileName folderName, MemoryCardFileEntry* const entry, MemoryCardFileMetadataReference* const parent);
static void WriteIndex(const std::string& baseFolderName, MemoryCardFileEntry* const entry, MemoryCardFileMetadataReference* const parent);
private:
// helper function for CleanMemcardFilename()
static bool CleanMemcardFilenameEndDotOrSpace(char* name, size_t length);
// Open a new file and remember it for later
wxFFile* Open(const wxFileName& folderName, MemoryCardFileMetadataReference* fileRef, bool writeMetadata = false);
std::FILE* Open(const std::string_view& folderName, MemoryCardFileMetadataReference* fileRef, bool writeMetadata = false);
// Close a file and delete its handle
// If entry is given, it also attempts to set the created and modified timestamps of the file according to the entry
void CloseFileHandle(wxFFile* file, const MemoryCardFileEntry* entry = nullptr);
void CloseFileHandle(std::FILE*& file, const MemoryCardFileEntry* entry = nullptr);
void WriteMetadata(wxFileName folderName, const MemoryCardFileMetadataReference* fileRef);
void WriteMetadata(const std::string_view& folderName, const MemoryCardFileMetadataReference* fileRef);
};
// --------------------------------------------------------------------------------------
@ -357,7 +305,7 @@ protected:
FileAccessHelper m_lastAccessedFile;
// path to the folder that contains the files of this memory card
wxFileName m_folderName;
std::string m_folderName;
// PS2 memory card slot this card is inserted into
uint m_slot;
@ -369,7 +317,7 @@ protected:
// currently active filter settings
bool m_filteringEnabled;
wxString m_filteringString;
std::string m_filteringString;
public:
FolderMemoryCard();
@ -379,16 +327,16 @@ public:
void Unlock();
// Initialize & Load Memory Card with values configured in the Memory Card Manager
void Open(const bool enableFiltering, const wxString& filter);
void Open(const bool enableFiltering, std::string filter);
// Initialize & Load Memory Card with provided custom values
void Open(const wxString& fullPath, const Pcsx2Config::McdOptions& mcdOptions, const u32 sizeInClusters, const bool enableFiltering, const wxString& filter, bool simulateFileWrites = false);
void Open(std::string fullPath, const Pcsx2Config::McdOptions& mcdOptions, const u32 sizeInClusters, const bool enableFiltering, std::string filter, bool simulateFileWrites = false);
// Close the memory card and flush changes to the file system. Set flush to false to not store changes.
void Close(bool flush = true);
// Closes and reopens card with given filter options if they differ from the current ones (returns true),
// or does nothing if they match already (returns false).
// Does nothing and returns false when called on a closed memory card.
bool ReIndex(bool enableFiltering, const wxString& filter);
bool ReIndex(bool enableFiltering, const std::string& filter);
s32 IsPresent() const;
void GetSizeInfo(McdSizeInfo& outways) const;
@ -413,12 +361,12 @@ public:
static void CalculateECC(u8* ecc, const u8* data);
void WriteToFile(const wxString& filename);
void WriteToFile(const std::string& filename);
protected:
struct EnumeratedFileEntry
{
wxString m_fileName; // TODO: Replace with std::string
std::string m_fileName;
time_t m_timeCreated;
time_t m_timeModified;
bool m_isFile;
@ -457,14 +405,14 @@ protected:
// - originalDirCount: the point in fileName where to insert the found folder path, usually fileName->GetDirCount()
// - outClusterNumber: the cluster's sequential number of the file will be written to this pointer,
// which can be used to calculate the in-file offset of the address being accessed
MemoryCardFileEntry* GetFileEntryFromFileDataCluster(const u32 currentCluster, const u32 searchCluster, wxFileName* fileName, const size_t originalDirCount, u32* outClusterNumber);
MemoryCardFileEntry* GetFileEntryFromFileDataCluster(const u32 currentCluster, const u32 searchCluster, std::string* fileName, const size_t originalDirCount, u32* outClusterNumber);
// loads files and folders from the host file system if a superblock exists in the root directory
// - sizeInClusters: total memory card size in clusters, 0 for default
// - enableFiltering: if set to true, only folders whose name contain the filter string are loaded
// - filter: can include multiple filters by separating them with "/"
void LoadMemoryCardData(const u32 sizeInClusters, const bool enableFiltering, const wxString& filter);
void LoadMemoryCardData(const u32 sizeInClusters, const bool enableFiltering, const std::string& filter);
// creates the FAT and indirect FAT
void CreateFat();
@ -500,17 +448,17 @@ protected:
// - dirPath: the full path to the directory in the host file system
// - parent: pointer to the parent dir's quick-access reference element
// - enableFiltering and filter: filter loaded contents, see LoadMemoryCardData()
bool AddFolder(MemoryCardFileEntry* const dirEntry, const wxString& dirPath, MemoryCardFileMetadataReference* parent = nullptr, const bool enableFiltering = false, const wxString& filter = L"");
bool AddFolder(MemoryCardFileEntry* const dirEntry, const std::string& dirPath, MemoryCardFileMetadataReference* parent = nullptr, const bool enableFiltering = false, const std::string_view& filter = "");
// adds a file in the host file sytem to the memory card
// - dirEntry: the entry of the directory in the parent directory, or the root "." entry
// - dirPath: the full path to the directory containing the file in the host file system
// - fileName: the name of the file, without path
// - parent: pointer to the parent dir's quick-access reference element
bool AddFile(MemoryCardFileEntry* const dirEntry, const wxString& dirPath, const EnumeratedFileEntry& fileEntry, MemoryCardFileMetadataReference* parent = nullptr);
bool AddFile(MemoryCardFileEntry* const dirEntry, const std::string& dirPath, const EnumeratedFileEntry& fileEntry, MemoryCardFileMetadataReference* parent = nullptr);
// calculates the amount of clusters a directory would use up if put into a memory card
u32 CalculateRequiredClustersOfDirectory(const wxString& dirPath) const;
u32 CalculateRequiredClustersOfDirectory(const std::string& dirPath) const;
// adds a file to the quick-access dictionary, so it can be accessed more efficiently (ie, without searching through the entire file system) later
@ -549,7 +497,7 @@ protected:
void FlushFileEntries();
// flush a directory's file entries and all its subdirectories to the internal data
void FlushFileEntries(const u32 dirCluster, const u32 remainingFiles, const wxString& dirPath = L"", MemoryCardFileMetadataReference* parent = nullptr);
void FlushFileEntries(const u32 dirCluster, const u32 remainingFiles, const std::string& dirPath = {}, MemoryCardFileMetadataReference* parent = nullptr);
// "delete" (prepend '_pcsx2_deleted_' to) any files that exist in oldFileEntries but no longer exist in m_fileEntryDict
// also calls RemoveUnchangedDataFromCache() since both operate on comparing with the old file entires
@ -559,7 +507,7 @@ protected:
// - newCluster: Current directory dotdir cluster of the new entries.
// - newFileCount: Number of file entries in the new directory.
// - dirPath: Path to the current directory relative to the root of the memcard. Must be identical for both entries.
void FlushDeletedFilesAndRemoveUnchangedDataFromCache(const std::vector<MemoryCardFileEntryTreeNode>& oldFileEntries, const u32 newCluster, const u32 newFileCount, const wxString& dirPath);
void FlushDeletedFilesAndRemoveUnchangedDataFromCache(const std::vector<MemoryCardFileEntryTreeNode>& oldFileEntries, const u32 newCluster, const u32 newFileCount, const std::string& dirPath);
// try and remove unchanged data from m_cache
// oldEntry and newEntry should be equivalent entries found by FindEquivalent()
@ -577,23 +525,16 @@ protected:
void SetTimeLastReadToNow();
void SetTimeLastWrittenToNow();
void AttemptToRecreateIndexFile(fs::path directory) const;
void AttemptToRecreateIndexFile(const std::string& directory) const;
std::string GetDisabledMessage(uint slot) const
{
return fmt::format("The PS2-slot {} has been automatically disabled. You can correct the problem\nand re-enable it at any time using Config:Memory cards from the main menu.", slot //TODO: translate internal slot index to human-readable slot description
);
}
std::string GetCardFullMessage(const std::string_view& filePath) const
{
return fmt::format("(FolderMcd) Memory Card is full, could not add: {}", filePath);
}
std::string GetDisabledMessage(uint slot) const;
std::string GetCardFullMessage(const std::string& filePath) const;
// get the list of files (and their timestamps) in directory ordered as specified by the index file
// for legacy entries without an entry in the index file, order is unspecified and should not be relied on
std::vector<EnumeratedFileEntry> GetOrderedFiles(const wxString& dirPath) const;
std::vector<EnumeratedFileEntry> GetOrderedFiles(const std::string& dirPath) const;
void DeleteFromIndex(const wxString& filePath, const wxString& entry) const;
void DeleteFromIndex(const std::string& filePath, const std::string_view& entry) const;
};
// --------------------------------------------------------------------------------------
@ -609,7 +550,7 @@ protected:
// stores the specifics of the current filtering settings, so they can be
// re-applied automatically when memory cards are reloaded
bool m_enableFiltering = true;
wxString m_lastKnownFilter = L"";
std::string m_lastKnownFilter;
public:
FolderMemoryCardAggregator();
@ -628,5 +569,5 @@ public:
s32 EraseBlock(uint slot, u32 adr);
u64 GetCRC(uint slot);
void NextFrame(uint slot);
bool ReIndex(uint slot, const bool enableFiltering, const wxString& filter);
bool ReIndex(uint slot, const bool enableFiltering, const std::string& filter);
};

View File

@ -16,21 +16,25 @@
#include "PrecompiledHeader.h"
#include "AsyncFileReader.h"
#include "common/Assertions.h"
#include "common/FileSystem.h"
#include "common/Path.h"
#include "common/StringUtil.h"
// Tests for a filename extension in both upper and lower case, if the filesystem happens
// to be case-sensitive.
bool pxFileExists_WithExt( const wxFileName& filename, const wxString& ext )
static bool pxFileExists_WithExt( const std::string& filename, const std::string& ext )
{
wxFileName part1 = filename;
part1.SetExt( ext.Lower() );
std::string temp(Path::ReplaceExtension(filename, StringUtil::toLower(ext)));
if (FileSystem::FileExists(temp.c_str()))
return true;
if (part1.FileExists()) return true;
if (!wxFileName::IsCaseSensitive()) return false;
#if defined(_WIN32) || defined(__DARWIN__)
temp = Path::ReplaceExtension(filename, StringUtil::toUpper(ext));
if (FileSystem::FileExists(temp.c_str()))
return true;
#endif
part1.SetExt( ext.Upper() );
return part1.FileExists();
return false;
}
AsyncFileReader* MultipartFileReader::DetectMultipart(AsyncFileReader* reader)
@ -69,9 +73,11 @@ MultipartFileReader::~MultipartFileReader(void)
void MultipartFileReader::FindParts()
{
wxFileName nameparts( StringUtil::UTF8StringToWxString(m_filename) );
wxString curext( nameparts.GetExt() );
wxChar prefixch = wxTolower(curext[0]);
std::string curext(Path::GetExtension(m_filename));
if (curext.empty())
return;
char prefixch = std::tolower(curext[0]);
// Multi-part rules!
// * The first part can either be the proper extension (ISO, MDF, etc) or the numerical
@ -81,18 +87,18 @@ void MultipartFileReader::FindParts()
uint i = 0;
if ((curext.Length() == 3) && (curext[1] == L'0') && (curext[2] == L'0'))
if ((curext.length() == 3) && (curext[1] == '0') && (curext[2] == '0'))
{
// First file is an OO, so skip 0 in the loop below:
i = 1;
}
wxString extbuf = wxString::Format(L"%c%02u", prefixch, i );
nameparts.SetExt( extbuf );
std::string extbuf(StringUtil::StdStringFromFormat("%c%02u", prefixch, i));
std::string nameparts(Path::ReplaceExtension(m_filename, extbuf));
if (!pxFileExists_WithExt(nameparts, extbuf))
return;
DevCon.WriteLn( Color_Blue, "isoFile: multi-part %s detected...", curext.Upper().ToUTF8().data() );
DevCon.WriteLn( Color_Blue, "isoFile: multi-part %s detected...", StringUtil::toUpper(curext).c_str() );
ConsoleIndentScope indent;
int bsize = m_parts[0].reader->GetBlockSize();
@ -102,17 +108,15 @@ void MultipartFileReader::FindParts()
for (; i < MaxParts; ++i)
{
extbuf = wxString::Format(L"%c%02u", prefixch, i );
nameparts.SetExt( extbuf );
extbuf = StringUtil::StdStringFromFormat("%c%02u", prefixch, i );
nameparts = Path::ReplaceExtension(m_filename, extbuf);
if (!pxFileExists_WithExt(nameparts, extbuf))
break;
Part* thispart = m_parts + m_numparts;
AsyncFileReader* thisreader = thispart->reader = new FlatFileReader();
wxString name = nameparts.GetFullPath();
thisreader->Open(StringUtil::wxStringToUTF8String(name));
thisreader->Open(nameparts);
thisreader->SetBlockSize(bsize);
thispart->start = blocks;
@ -124,7 +128,7 @@ void MultipartFileReader::FindParts()
DevCon.WriteLn( Color_Blue, "\tblocks %u - %u in: %s",
thispart->start, thispart->end,
nameparts.GetFullPath().ToUTF8().data()
nameparts.c_str()
);
++m_numparts;

View File

@ -17,6 +17,7 @@
#include "Global.h"
#include "Device.h"
#include "keyboard.h"
#include "common/Path.h"
#ifdef __APPLE__
#include <Carbon/Carbon.h>
#endif
@ -60,8 +61,7 @@ void PADSaveConfig()
{
FILE* f;
wxString iniName(L"PAD.ini");
const std::string iniFile = std::string(EmuFolders::Settings.Combine(iniName).GetFullPath()); // default path, just in case
const std::string iniFile = Path::Combine(EmuFolders::Settings, "PAD.ini"); // default path, just in case
f = fopen(iniFile.c_str(), "w");
if (f == NULL)
{
@ -97,8 +97,7 @@ void PADLoadConfig()
g_conf.init();
wxString iniName(L"PAD.ini");
const std::string iniFile = std::string(EmuFolders::Settings.Combine(iniName).GetFullPath()); // default path, just in case
const std::string iniFile = Path::Combine(EmuFolders::Settings, "PAD.ini"); // default path, just in case
f = fopen(iniFile.c_str(), "r");
if (f == nullptr)
{

View File

@ -14,6 +14,8 @@
*/
#include "PrecompiledHeader.h"
#include "common/RedtapeWindows.h"
#include "Global.h"
#include "DeviceEnumerator.h"
#include "KeyboardQueue.h"

View File

@ -21,6 +21,7 @@
#include <wx/log.h>
#include <wx/filename.h>
#include "common/Console.h"
#include "common/RedtapeWindows.h"
#include <stdio.h>
#include <assert.h>

View File

@ -16,6 +16,9 @@
#include "PrecompiledHeader.h"
#include "Global.h"
#include "common/Path.h"
#include "common/StringUtil.h"
#include "resource_pad.h"
#include "InputManager.h"
#include "PADConfig.h"
@ -335,8 +338,7 @@ void PADsetSettingsDir(const char* dir)
//swprintf_s( iniFileUSB, L"%S", (dir==NULL) ? "inis" : dir );
//uint targlen = MultiByteToWideChar(CP_ACP, 0, dir, -1, NULL, 0);
wxString iniName = "PAD.ini";
StrCpyNW(iniFileUSB, EmuFolders::Settings.Combine(iniName).GetFullPath(), std::size(iniFileUSB));
StrCpyNW(iniFileUSB, StringUtil::UTF8StringToWideString(Path::Combine(EmuFolders::Settings, "PAD.ini")).c_str(), std::size(iniFileUSB));
createIniDir = false;

View File

@ -10,9 +10,11 @@
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
* If not, see <http://www.gnu.org/licenses/>.4
*/
#include "common/RedtapeWindows.h"
#define EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES 1
/* Need this to let window be subclassed multiple times but still clean up nicely.

View File

@ -18,12 +18,12 @@
#define _PC_ // disables MIPS opcode macros.
#include "common/FileSystem.h"
#include "common/Path.h"
#include "common/StringUtil.h"
#include "common/ZipHelpers.h"
#include "Config.h"
#include "Patch.h"
#include "PathDefs.h"
#include <memory>
#include <sstream>
@ -165,29 +165,29 @@ int LoadPatchesFromZip(const std::string& crc, const u8* zip_data, size_t zip_da
// This routine loads patches from *.pnach files
// Returns number of patches loaded
// Note: does not reset previously loaded patches (use ForgetLoadedPatches() for that)
int LoadPatchesFromDir(const std::string& crc, const wxDirName& folder, const char* friendly_name, bool show_error_when_missing)
int LoadPatchesFromDir(const std::string& crc, const std::string& folder, const char* friendly_name, bool show_error_when_missing)
{
if (!folder.Exists())
if (!FileSystem::DirectoryExists(folder.c_str()))
{
Console.WriteLn(Color_Red, "The %s folder ('%s') is inaccessible. Skipping...", friendly_name, folder.ToUTF8().data());
Console.WriteLn(Color_Red, "The %s folder ('%s') is inaccessible. Skipping...", friendly_name, folder.c_str());
return 0;
}
FileSystem::FindResultsArray files;
FileSystem::FindFiles(folder.ToUTF8(), StringUtil::StdStringFromFormat("*.pnach", crc.c_str()).c_str(),
FileSystem::FindFiles(folder.c_str(), StringUtil::StdStringFromFormat("*.pnach", crc.c_str()).c_str(),
FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES, &files);
if (show_error_when_missing && files.empty())
{
PatchesCon->WriteLn(Color_Gray, "Not found %s file: %s" FS_OSPATH_SEPARATOR_STR "%s.pnach",
friendly_name, folder.ToUTF8().data(), crc.c_str());
friendly_name, folder.c_str(), crc.c_str());
}
int total_loaded = 0;
for (const FILESYSTEM_FIND_DATA& fd : files)
{
const std::string_view name(FileSystem::GetFileNameFromPath(fd.FileName));
const std::string_view name(Path::GetFileName(fd.FileName));
if (name.length() < crc.length() || StringUtil::Strncasecmp(name.data(), crc.c_str(), crc.size()) != 0)
continue;

View File

@ -38,6 +38,7 @@
#include "common/Pcsx2Defs.h"
#include "SysForwardDefs.h"
#include "GameDatabase.h"
#include <string>
#include <string_view>
enum patch_cpu_type {
@ -108,7 +109,7 @@ namespace PatchFunc
// - do not reset/unload previously loaded patches (use ForgetLoadedPatches() for that)
// - do not actually patch the emulation memory (that happens at ApplyLoadedPatches(...) )
extern int LoadPatchesFromString(const std::string& patches);
extern int LoadPatchesFromDir(const std::string& crc, const wxDirName& folder, const char* friendly_name, bool show_error_when_missing);
extern int LoadPatchesFromDir(const std::string& crc, const std::string& folder, const char* friendly_name, bool show_error_when_missing);
extern int LoadPatchesFromZip(const std::string& crc, const u8* zip_data, size_t zip_data_size);
// Patches the emulation memory by applying all the loaded patches with a specific place value.

View File

@ -15,8 +15,8 @@
#include "PrecompiledHeader.h"
#include <wx/fileconf.h>
#include "common/FileSystem.h"
#include "common/Path.h"
#include "common/SettingsInterface.h"
#include "common/SettingsWrapper.h"
#include "common/StringUtil.h"
@ -33,22 +33,22 @@
namespace EmuFolders
{
wxDirName AppRoot;
wxDirName DataRoot;
wxDirName Settings;
wxDirName Bios;
wxDirName Snapshots;
wxDirName Savestates;
wxDirName MemoryCards;
wxDirName Langs;
wxDirName Logs;
wxDirName Cheats;
wxDirName CheatsWS;
wxDirName Resources;
wxDirName Cache;
wxDirName Covers;
wxDirName GameSettings;
wxDirName Textures;
std::string AppRoot;
std::string DataRoot;
std::string Settings;
std::string Bios;
std::string Snapshots;
std::string Savestates;
std::string MemoryCards;
std::string Langs;
std::string Logs;
std::string Cheats;
std::string CheatsWS;
std::string Resources;
std::string Cache;
std::string Covers;
std::string GameSettings;
std::string Textures;
} // namespace EmuFolders
void TraceLogFilters::LoadSave(SettingsWrapper& wrap)
@ -1127,13 +1127,13 @@ std::string Pcsx2Config::FullpathToBios() const
{
std::string ret;
if (!BaseFilenames.Bios.empty())
ret = Path::CombineStdString(EmuFolders::Bios, BaseFilenames.Bios);
ret = Path::Combine(EmuFolders::Bios, BaseFilenames.Bios);
return ret;
}
wxString Pcsx2Config::FullpathToMcd(uint slot) const
std::string Pcsx2Config::FullpathToMcd(uint slot) const
{
return Path::Combine(EmuFolders::MemoryCards, StringUtil::UTF8StringToWxString(Mcd[slot].Filename));
return Path::Combine(EmuFolders::MemoryCards, Mcd[slot].Filename);
}
bool Pcsx2Config::operator==(const Pcsx2Config& right) const
@ -1212,27 +1212,25 @@ void Pcsx2Config::CopyConfig(const Pcsx2Config& cfg)
void EmuFolders::SetDefaults()
{
Bios = DataRoot.Combine(wxDirName("bios"));
Snapshots = DataRoot.Combine(wxDirName("snaps"));
Savestates = DataRoot.Combine(wxDirName("sstates"));
MemoryCards = DataRoot.Combine(wxDirName("memcards"));
Logs = DataRoot.Combine(wxDirName("logs"));
Cheats = DataRoot.Combine(wxDirName("cheats"));
CheatsWS = DataRoot.Combine(wxDirName("cheats_ws"));
Covers = DataRoot.Combine(wxDirName("covers"));
GameSettings = DataRoot.Combine(wxDirName("gamesettings"));
Cache = DataRoot.Combine(wxDirName("cache"));
Textures = DataRoot.Combine(wxDirName("textures"));
Bios = Path::Combine(DataRoot, "bios");
Snapshots = Path::Combine(DataRoot, "snaps");
Savestates = Path::Combine(DataRoot, "sstates");
MemoryCards = Path::Combine(DataRoot, "memcards");
Logs = Path::Combine(DataRoot, "logs");
Cheats = Path::Combine(DataRoot, "cheats");
CheatsWS = Path::Combine(DataRoot, "cheats_ws");
Covers = Path::Combine(DataRoot, "covers");
GameSettings = Path::Combine(DataRoot, "gamesettings");
Cache = Path::Combine(DataRoot, "cache");
Textures = Path::Combine(DataRoot, "textures");
}
static wxDirName LoadPathFromSettings(SettingsInterface& si, const wxDirName& root, const char* name, const char* def)
static std::string LoadPathFromSettings(SettingsInterface& si, const std::string& root, const char* name, const char* def)
{
std::string value = si.GetStringValue("Folders", name, def);
wxDirName ret(StringUtil::UTF8StringToWxString(value));
if (!ret.IsAbsolute())
ret = root.Combine(ret);
return ret;
if (!Path::IsAbsolute(value))
value = Path::Combine(root, value);
return value;
}
void EmuFolders::LoadConfig(SettingsInterface& si)
@ -1249,47 +1247,46 @@ void EmuFolders::LoadConfig(SettingsInterface& si)
Cache = LoadPathFromSettings(si, DataRoot, "Cache", "cache");
Textures = LoadPathFromSettings(si, DataRoot, "Textures", "textures");
Console.WriteLn("BIOS Directory: %s", Bios.ToString().c_str().AsChar());
Console.WriteLn("Snapshots Directory: %s", Snapshots.ToString().c_str().AsChar());
Console.WriteLn("Savestates Directory: %s", Savestates.ToString().c_str().AsChar());
Console.WriteLn("MemoryCards Directory: %s", MemoryCards.ToString().c_str().AsChar());
Console.WriteLn("Logs Directory: %s", Logs.ToString().c_str().AsChar());
Console.WriteLn("Cheats Directory: %s", Cheats.ToString().c_str().AsChar());
Console.WriteLn("CheatsWS Directory: %s", CheatsWS.ToString().c_str().AsChar());
Console.WriteLn("Covers Directory: %s", Covers.ToString().c_str().AsChar());
Console.WriteLn("Game Settings Directory: %s", GameSettings.ToString().c_str().AsChar());
Console.WriteLn("Cache Directory: %s", Cache.ToString().c_str().AsChar());
Console.WriteLn("Textures Directory: %s", Textures.ToString().c_str().AsChar());
Console.WriteLn("BIOS Directory: %s", Bios.c_str());
Console.WriteLn("Snapshots Directory: %s", Snapshots.c_str());
Console.WriteLn("Savestates Directory: %s", Savestates.c_str());
Console.WriteLn("MemoryCards Directory: %s", MemoryCards.c_str());
Console.WriteLn("Logs Directory: %s", Logs.c_str());
Console.WriteLn("Cheats Directory: %s", Cheats.c_str());
Console.WriteLn("CheatsWS Directory: %s", CheatsWS.c_str());
Console.WriteLn("Covers Directory: %s", Covers.c_str());
Console.WriteLn("Game Settings Directory: %s", GameSettings.c_str());
Console.WriteLn("Cache Directory: %s", Cache.c_str());
Console.WriteLn("Textures Directory: %s", Textures.c_str());
}
void EmuFolders::Save(SettingsInterface& si)
{
// convert back to relative
const wxString datarel(DataRoot.ToString());
si.SetStringValue("Folders", "Bios", wxDirName::MakeAutoRelativeTo(Bios, datarel).c_str());
si.SetStringValue("Folders", "Snapshots", wxDirName::MakeAutoRelativeTo(Snapshots, datarel).c_str());
si.SetStringValue("Folders", "Savestates", wxDirName::MakeAutoRelativeTo(Savestates, datarel).c_str());
si.SetStringValue("Folders", "MemoryCards", wxDirName::MakeAutoRelativeTo(MemoryCards, datarel).c_str());
si.SetStringValue("Folders", "Logs", wxDirName::MakeAutoRelativeTo(Logs, datarel).c_str());
si.SetStringValue("Folders", "Cheats", wxDirName::MakeAutoRelativeTo(Cheats, datarel).c_str());
si.SetStringValue("Folders", "CheatsWS", wxDirName::MakeAutoRelativeTo(CheatsWS, datarel).c_str());
si.SetStringValue("Folders", "Cache", wxDirName::MakeAutoRelativeTo(Cache, datarel).c_str());
si.SetStringValue("Folders", "Textures", wxDirName::MakeAutoRelativeTo(Textures, datarel).c_str());
si.SetStringValue("Folders", "Bios", Path::MakeRelative(Bios, DataRoot).c_str());
si.SetStringValue("Folders", "Snapshots", Path::MakeRelative(Snapshots, DataRoot).c_str());
si.SetStringValue("Folders", "Savestates", Path::MakeRelative(Savestates, DataRoot).c_str());
si.SetStringValue("Folders", "MemoryCards", Path::MakeRelative(MemoryCards, DataRoot).c_str());
si.SetStringValue("Folders", "Logs", Path::MakeRelative(Logs, DataRoot).c_str());
si.SetStringValue("Folders", "Cheats", Path::MakeRelative(Cheats, DataRoot).c_str());
si.SetStringValue("Folders", "CheatsWS", Path::MakeRelative(CheatsWS, DataRoot).c_str());
si.SetStringValue("Folders", "Cache", Path::MakeRelative(Cache, DataRoot).c_str());
si.SetStringValue("Folders", "Textures", Path::MakeRelative(Textures, DataRoot).c_str());
}
bool EmuFolders::EnsureFoldersExist()
{
bool result = Bios.Mkdir();
result = Settings.Mkdir() && result;
result = Snapshots.Mkdir() && result;
result = Savestates.Mkdir() && result;
result = MemoryCards.Mkdir() && result;
result = Logs.Mkdir() && result;
result = Cheats.Mkdir() && result;
result = CheatsWS.Mkdir() && result;
result = Covers.Mkdir() && result;
result = GameSettings.Mkdir() && result;
result = Cache.Mkdir() && result;
result = Textures.Mkdir() && result;
bool result = FileSystem::CreateDirectoryPath(Bios.c_str(), false);
result = FileSystem::CreateDirectoryPath(Settings.c_str(), false) && result;
result = FileSystem::CreateDirectoryPath(Snapshots.c_str(), false) && result;
result = FileSystem::CreateDirectoryPath(Savestates.c_str(), false) && result;
result = FileSystem::CreateDirectoryPath(MemoryCards.c_str(), false) && result;
result = FileSystem::CreateDirectoryPath(Logs.c_str(), false) && result;
result = FileSystem::CreateDirectoryPath(Cheats.c_str(), false) && result;
result = FileSystem::CreateDirectoryPath(CheatsWS.c_str(), false) && result;
result = FileSystem::CreateDirectoryPath(Covers.c_str(), false) && result;
result = FileSystem::CreateDirectoryPath(GameSettings.c_str(), false) && result;
result = FileSystem::CreateDirectoryPath(Cache.c_str(), false) && result;
result = FileSystem::CreateDirectoryPath(Textures.c_str(), false) && result;
return result;
}

View File

@ -141,7 +141,7 @@ __ri void cpuException(u32 code, u32 bd)
if(cpuRegs.CP0.n.Status.b.ERL == 0)
{
//Error Level 0-1
errLevel2 = FALSE;
errLevel2 = false;
checkStatus = (cpuRegs.CP0.n.Status.b.BEV == 0); // for TLB/general exceptions
if (((code & 0x7C) >= 0x8) && ((code & 0x7C) <= 0xC))
@ -154,7 +154,7 @@ __ri void cpuException(u32 code, u32 bd)
else
{
//Error Level 2
errLevel2 = TRUE;
errLevel2 = true;
checkStatus = (cpuRegs.CP0.n.Status.b.DEV == 0); // for perf/debug exceptions
Console.Error("*PCSX2* FIX ME: Level 2 cpuException");

View File

@ -1,75 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "common/StringUtil.h"
#include "SPU2/Host/Config.h"
#include "SPU2/Host/Dialogs.h"
#include "HostSettings.h"
bool CfgReadBool(const wchar_t* Section, const wchar_t* Name, bool Default)
{
return Host::GetBoolSettingValue(StringUtil::WideStringToUTF8String(Section).c_str(),
StringUtil::WideStringToUTF8String(Name).c_str(), Default);
}
int CfgReadInt(const wchar_t* Section, const wchar_t* Name, int Default)
{
return Host::GetIntSettingValue(StringUtil::WideStringToUTF8String(Section).c_str(),
StringUtil::WideStringToUTF8String(Name).c_str(), Default);
}
float CfgReadFloat(const wchar_t* Section, const wchar_t* Name, float Default)
{
return Host::GetFloatSettingValue(StringUtil::WideStringToUTF8String(Section).c_str(),
StringUtil::WideStringToUTF8String(Name).c_str(), Default);
}
void CfgReadStr(const wchar_t* Section, const wchar_t* Name, wchar_t* Data, int DataSize, const wchar_t* Default)
{
const std::wstring res(StringUtil::UTF8StringToWideString(
Host::GetStringSettingValue(
StringUtil::WideStringToUTF8String(Section).c_str(),
StringUtil::WideStringToUTF8String(Name).c_str(),
StringUtil::WideStringToUTF8String(Default).c_str())));
std::wcsncpy(Data, res.c_str(), DataSize);
Data[DataSize - 1] = 0;
}
void CfgReadStr(const wchar_t* Section, const wchar_t* Name, wxString& Data, const wchar_t* Default)
{
Data = StringUtil::UTF8StringToWxString(
Host::GetStringSettingValue(
StringUtil::WideStringToUTF8String(Section).c_str(),
StringUtil::WideStringToUTF8String(Name).c_str(),
StringUtil::WideStringToUTF8String(Default).c_str()));
}
void CfgWriteBool(const wchar_t* Section, const wchar_t* Name, bool Value)
{
}
void CfgWriteInt(const wchar_t* Section, const wchar_t* Name, int Value)
{
}
void CfgWriteFloat(const wchar_t* Section, const wchar_t* Name, float Value)
{
}
void CfgWriteStr(const wchar_t* Section, const wchar_t* Name, const wxString& Data)
{
}

View File

@ -97,7 +97,7 @@ void ReadSettings()
VolumeAdjustLFE = powf(10, VolumeAdjustLFEdb / 10);
const std::string modname(Host::GetStringSettingValue("SPU2/Output", "OutputModule", "cubeb"));
OutputModule = FindOutputModuleById(StringUtil::UTF8StringToWideString(modname).c_str()); // Find the driver index of this module...
OutputModule = FindOutputModuleById(modname.c_str()); // Find the driver index of this module...
SndOutLatencyMS = Host::GetIntSettingValue("SPU2/Output", "Latency", 100);
SynchMode = Host::GetIntSettingValue("SPU2/Output", "SynchMode", 0);

View File

@ -17,7 +17,6 @@
#define CONFIG_H_INCLUDED
#include <string>
#include <wx/fileconf.h>
extern bool DebugEnabled;

View File

@ -61,17 +61,17 @@ void CfgSetLogDir(const char* dir)
FILE* OpenBinaryLog(const char* logfile)
{
return FileSystem::OpenCFile(Path::CombineStdString(EmuFolders::Logs, logfile).c_str(), "wb");
return FileSystem::OpenCFile(Path::Combine(EmuFolders::Logs, logfile).c_str(), "wb");
}
FILE* OpenLog(const char* logfile)
{
return FileSystem::OpenCFile(Path::CombineStdString(EmuFolders::Logs, logfile).c_str(), "w");
return FileSystem::OpenCFile(Path::Combine(EmuFolders::Logs, logfile).c_str(), "w");
}
FILE* OpenDump(const char* logfile)
{
return FileSystem::OpenCFile(Path::CombineStdString(EmuFolders::Logs, logfile).c_str(), "w");
return FileSystem::OpenCFile(Path::Combine(EmuFolders::Logs, logfile).c_str(), "w");
}
namespace DebugConfig

View File

@ -18,41 +18,7 @@
#include "PrecompiledHeader.h"
#include "Dialogs.h"
#include <cstring>
#if !defined(PCSX2_CORE) && (defined(__unix__) || defined(__APPLE__))
#include <wx/wx.h>
void SysMessage(const char* fmt, ...)
{
va_list list;
char msg[512];
va_start(list, fmt);
vsprintf(msg, fmt, list);
va_end(list);
if (msg[strlen(msg) - 1] == '\n')
msg[strlen(msg) - 1] = 0;
wxMessageDialog dialog(nullptr, msg, "Info", wxOK);
dialog.ShowModal();
}
void SysMessage(const wchar_t* fmt, ...)
{
va_list list;
va_start(list, fmt);
wxString msg;
msg.PrintfV(fmt, list);
va_end(list);
wxMessageDialog dialog(nullptr, msg, "Info", wxOK);
dialog.ShowModal();
}
#else
#include <wx/string.h>
#include <cstdarg>
void SysMessage(const char* fmt, ...)
{
@ -62,19 +28,6 @@ void SysMessage(const char* fmt, ...)
va_end(list);
}
void SysMessage(const wchar_t* fmt, ...)
{
va_list list;
va_start(list, fmt);
wxString msg;
msg.PrintfV(fmt, list);
va_end(list);
fprintf(stderr, "%s\n", msg.ToStdString().c_str());
}
#endif
void DspUpdate()
{
}

View File

@ -19,8 +19,6 @@
#include "SPU2/Global.h"
#include "SPU2/Config.h"
#include <wx/string.h>
namespace DebugConfig
{
extern void ReadSettings();
@ -29,14 +27,4 @@ namespace DebugConfig
extern void CfgSetSettingsDir(const char* dir);
extern void CfgSetLogDir(const char* dir);
extern bool CfgReadBool(const wchar_t* Section, const wchar_t* Name, bool Default);
extern void CfgReadStr(const wchar_t* Section, const wchar_t* Name, wxString& Data, const wchar_t* Default);
extern int CfgReadInt(const wchar_t* Section, const wchar_t* Name, int Default);
extern float CfgReadFloat(const wchar_t* Section, const wchar_t* Name, float Default);
extern void CfgWriteBool(const wchar_t* Section, const wchar_t* Name, bool Value);
extern void CfgWriteInt(const wchar_t* Section, const wchar_t* Name, int Value);
extern void CfgWriteFloat(const wchar_t* Section, const wchar_t* Name, float Value);
extern void CfgWriteStr(const wchar_t* Section, const wchar_t* Name, const wxString& Data);
#endif

View File

@ -17,6 +17,8 @@
#include "Config.h"
#include "Dialogs.h"
#include "pcsx2/Config.h"
#include "common/Path.h"
#include "gui/StringHelpers.h"
#include <wx/fileconf.h>
wxFileConfig* spuConfig = nullptr;
@ -27,7 +29,7 @@ void initIni()
{
if (!pathSet)
{
path = EmuFolders::Settings.Combine(path).GetFullPath();
path = StringUtil::UTF8StringToWxString(Path::Combine(EmuFolders::Settings, "SPU2.ini"));
pathSet = true;
}
if (spuConfig == nullptr)
@ -43,7 +45,7 @@ void setIni(const wchar_t* Section)
void CfgSetSettingsDir(const char* dir)
{
FileLog("CfgSetSettingsDir(%s)\n", dir);
path = Path::Combine((dir == nullptr) ? wxString(L"inis") : wxString::FromUTF8(dir), L"SPU2.ini");
path = StringUtil::UTF8StringToWxString(Path::Combine((dir == nullptr) ? std::string("inis") : std::string(dir), "SPU2.ini"));
pathSet = true;
}

View File

@ -17,6 +17,7 @@
#include "SPU2/Global.h"
#include "Dialogs.h"
#include "Config.h"
#include "gui/StringHelpers.h"
#if defined(__unix__) || defined(__APPLE__)
#include <SDL.h>
@ -108,8 +109,8 @@ void ReadSettings()
#endif
wxString temp;
CfgReadStr(L"OUTPUT", L"Output_Module", temp, defaultModule->GetIdent());
OutputModule = FindOutputModuleById(temp.c_str()); // Find the driver index of this module...
CfgReadStr(L"OUTPUT", L"Output_Module", temp, StringUtil::UTF8StringToWxString(defaultModule->GetIdent()).wc_str());
OutputModule = FindOutputModuleById(temp.ToUTF8()); // Find the driver index of this module...
SndOutLatencyMS = CfgReadInt(L"OUTPUT", L"Latency", 100);
SynchMode = CfgReadInt(L"OUTPUT", L"Synch_Mode", 0);

View File

@ -18,6 +18,8 @@
#include "Dialogs.h"
#include "Config.h"
#include "pcsx2/Config.h"
#include "gui/StringHelpers.h"
#include "gui/wxDirName.h"
#include "common/FileSystem.h"
#include "common/StringUtil.h"
#include "common/Path.h"
@ -64,32 +66,17 @@ void CfgSetLogDir(const char* dir)
FILE* OpenBinaryLog(const char* logfile)
{
return FileSystem::OpenCFile(Path::CombineStdString(EmuFolders::Logs, logfile).c_str(), "wb");
return FileSystem::OpenCFile(Path::Combine(EmuFolders::Logs, logfile).c_str(), "wb");
}
FILE* OpenLog(const char* logfile)
{
return FileSystem::OpenCFile(Path::CombineStdString(EmuFolders::Logs, logfile).c_str(), "w");
return FileSystem::OpenCFile(Path::Combine(EmuFolders::Logs, logfile).c_str(), "w");
}
FILE* OpenDump(const char* logfile)
{
return FileSystem::OpenCFile(Path::CombineStdString(EmuFolders::Logs, logfile).c_str(), "w");
}
FILE* OpenBinaryLog(const wxString& logfile)
{
return wxFopen(Path::Combine(LogsFolder, logfile), L"wb");
}
FILE* OpenLog(const wxString& logfile)
{
return wxFopen(Path::Combine(LogsFolder, logfile), L"w");
}
FILE* OpenDump(const wxString& logfile)
{
return wxFopen(Path::Combine(DumpsFolder, logfile), L"w");
return FileSystem::OpenCFile(Path::Combine(EmuFolders::Logs, logfile).c_str(), "w");
}
namespace DebugConfig

View File

@ -55,14 +55,14 @@ public:
void SetPaused(bool paused) override {}
int GetEmptySampleCount() override { return 0; }
const wchar_t* GetIdent() const override
const char* GetIdent() const override
{
return L"nullout";
return "nullout";
}
const wchar_t* GetLongName() const override
const char* GetLongName() const override
{
return L"No Sound (Emulate SPU2 only)";
return "No Sound (Emulate SPU2 only)";
}
};
@ -81,12 +81,12 @@ SndOutModule* mods[] =
nullptr // signals the end of our list
};
int FindOutputModuleById(const wchar_t* omodid)
int FindOutputModuleById(const char* omodid)
{
int modcnt = 0;
while (mods[modcnt] != nullptr)
{
if (wcscmp(mods[modcnt]->GetIdent(), omodid) == 0)
if (std::strcmp(mods[modcnt]->GetIdent(), omodid) == 0)
break;
++modcnt;
}

View File

@ -32,7 +32,7 @@ static const int SndOutVolumeShift32 = 16 - SndOutVolumeShift; // shift up, not
// is too problematic. :)
extern int SampleRate;
extern int FindOutputModuleById(const wchar_t* omodid);
extern int FindOutputModuleById(const char* omodid);
// Implemented in Config.cpp
extern float VolumeAdjustFL;
@ -636,11 +636,11 @@ public:
// Returns a unique identification string for this driver.
// (usually just matches the driver's cpp filename)
virtual const wchar_t* GetIdent() const = 0;
virtual const char* GetIdent() const = 0;
// Returns the long name / description for this driver.
// (for use in configuration screen)
virtual const wchar_t* GetLongName() const = 0;
virtual const char* GetLongName() const = 0;
virtual bool Init() = 0;
virtual void Close() = 0;

View File

@ -23,10 +23,20 @@
#include "Global.h"
#include "SndOut.h"
#ifdef PCSX2_CORE
#include "HostSettings.h"
#else
#include "gui/StringHelpers.h"
extern bool CfgReadBool(const wchar_t* Section, const wchar_t* Name, bool Default);
extern int CfgReadInt(const wchar_t* Section, const wchar_t* Name, int Default);
extern void CfgReadStr(const wchar_t* Section, const wchar_t* Name, wxString& Data, const wchar_t* Default);
#endif
class Cubeb : public SndOutModule
{
private:
@ -343,18 +353,19 @@ public:
return playedSinceLastTime;
}
const wchar_t* GetIdent() const override
const char* GetIdent() const override
{
return L"cubeb";
return "cubeb";
}
const wchar_t* GetLongName() const override
const char* GetLongName() const override
{
return L"Cubeb (Cross-platform)";
return "Cubeb (Cross-platform)";
}
void ReadSettings()
{
#ifndef PCSX2_CORE
m_SuggestedLatencyMinimal = CfgReadBool(L"Cubeb", L"MinimalSuggestedLatency", false);
m_SuggestedLatencyMS = std::clamp(CfgReadInt(L"Cubeb", L"ManualSuggestedLatencyMS", MINIMUM_LATENCY_MS), MINIMUM_LATENCY_MS, MAXIMUM_LATENCY_MS);
@ -362,6 +373,11 @@ public:
wxString backend;
CfgReadStr(L"Cubeb", L"BackendName", backend, L"");
m_Backend = StringUtil::wxStringToUTF8String(backend);
#else
m_SuggestedLatencyMinimal = Host::GetBoolSettingValue("Cubeb", "MinimalSuggestedLatency", false);
m_SuggestedLatencyMS = std::clamp(Host::GetIntSettingValue("Cubeb", "ManualSuggestedLatencyMS", MINIMUM_LATENCY_MS), MINIMUM_LATENCY_MS, MAXIMUM_LATENCY_MS);
m_Backend = Host::GetStringSettingValue("Cubeb", "BackendName", "");
#endif
}
};

View File

@ -16,7 +16,7 @@
#include "PrecompiledHeader.h"
#include "Global.h"
#include "SoundTouch.h"
#include <wx/datetime.h>
#include "common/Timer.h"
#include <algorithm>
#include <cmath>
@ -246,15 +246,15 @@ void SndBuffer::UpdateTempoChangeSoundTouch2()
if (MsgOverruns())
{
static int iters = 0;
static wxDateTime last = wxDateTime::UNow();
wxDateTime unow = wxDateTime::UNow();
wxTimeSpan delta = unow.Subtract(last);
static u64 last = 0;
if (delta.GetMilliseconds() > 1000)
const u64 now = Common::Timer::GetCurrentValue();
if (Common::Timer::ConvertValueToSeconds(now - last) > 1.0f)
{ //report buffers state and tempo adjust every second
ConLog("buffers: %4d ms (%3.0f%%), tempo: %f, comp: %2.3f, iters: %d, (N-IPS:%d -> avg:%d, minokc:%d, div:%d) reset:%d\n",
(int)(data / 48), (double)(100.0 * bufferFullness / baseTargetFullness), (double)tempoAdjust, (double)(dynamicTargetFullness / baseTargetFullness), iters, (int)targetIPS, AVERAGING_WINDOW, hys_min_ok_count, compensationDivider, gRequestStretcherReset);
last = unow;
last = now;
iters = 0;
}
iters++;

View File

@ -17,6 +17,8 @@
#include "Config.h"
#include "SPU2/Global.h"
#include "Dialogs.h"
#include "common/StringUtil.h"
#include "gui/StringHelpers.h"
void SysMessage(const char* fmt, ...)
{
@ -54,7 +56,7 @@ void initIni()
{
if (!pathSet)
{
CfgFile = EmuFolders::Settings.Combine(CfgFile).GetFullPath();
CfgFile = StringUtil::UTF8StringToWxString(Path::Combine(EmuFolders::Settings, "SPU2.ini"));
pathSet = true;
}
}

View File

@ -16,6 +16,7 @@
#include "PrecompiledHeader.h"
#include "SPU2/Global.h"
#include "Dialogs.h"
#include "common/StringUtil.h"
#ifdef PCSX2_DEVBUILD
static const int LATENCY_MAX = 3000;
@ -117,10 +118,10 @@ void ReadSettings()
// Let's use xaudio2 until this is sorted (rama).
// CfgReadStr(L"OUTPUT", L"Output_Module", omodid, 127, PortaudioOut->GetIdent());
CfgReadStr(L"OUTPUT", L"Output_Module", omodid, 127, XAudio2Out->GetIdent());
CfgReadStr(L"OUTPUT", L"Output_Module", omodid, 127, StringUtil::UTF8StringToWideString(XAudio2Out->GetIdent()).c_str());
// Find the driver index of this module:
OutputModule = FindOutputModuleById(omodid);
OutputModule = FindOutputModuleById(StringUtil::WideStringToUTF8String(omodid).c_str());
CfgReadStr(L"DSP PLUGIN", L"Filename", dspPlugin, 255, L"");
dspPluginModule = CfgReadInt(L"DSP PLUGIN", L"ModuleNum", 0);
@ -342,7 +343,7 @@ BOOL CALLBACK ConfigProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
int modidx = 0;
while (mods[modidx] != nullptr)
{
swprintf_s(temp, 72, L"%d - %s", modidx, mods[modidx]->GetLongName());
swprintf_s(temp, 72, L"%d - %s", modidx, StringUtil::UTF8StringToWideString(mods[modidx]->GetLongName()).c_str());
SendDialogMsg(hWnd, IDC_OUTPUT, CB_ADDSTRING, 0, (LPARAM)temp);
++modidx;
}

View File

@ -20,6 +20,8 @@
#include "common/FileSystem.h"
#include "common/StringUtil.h"
#include "common/Path.h"
#include "gui/StringHelpers.h"
#include "gui/wxDirName.h"
bool DebugEnabled = false;
@ -68,17 +70,17 @@ void CfgSetLogDir(const char* dir)
FILE* OpenBinaryLog(const char* logfile)
{
return FileSystem::OpenCFile(Path::CombineStdString(EmuFolders::Logs, logfile).c_str(), "wb");
return FileSystem::OpenCFile(Path::Combine(EmuFolders::Logs, logfile).c_str(), "wb");
}
FILE* OpenLog(const char* logfile)
{
return FileSystem::OpenCFile(Path::CombineStdString(EmuFolders::Logs, logfile).c_str(), "w");
return FileSystem::OpenCFile(Path::Combine(EmuFolders::Logs, logfile).c_str(), "w");
}
FILE* OpenDump(const char* logfile)
{
return FileSystem::OpenCFile(Path::CombineStdString(EmuFolders::Logs, logfile).c_str(), "w");
return FileSystem::OpenCFile(Path::Combine(EmuFolders::Logs, logfile).c_str(), "w");
}
namespace DebugConfig

View File

@ -360,14 +360,14 @@ public:
m_paused = paused;
}
const wchar_t* GetIdent() const override
const char* GetIdent() const override
{
return L"xaudio2";
return "xaudio2";
}
const wchar_t* GetLongName() const override
const char* GetLongName() const override
{
return L"XAudio 2 (Recommended)";
return "XAudio 2 (Recommended)";
}
} static XA2;

View File

@ -18,6 +18,7 @@
#include "SaveState.h"
#include "common/FileSystem.h"
#include "common/Path.h"
#include "common/SafeArray.inl"
#include "common/ScopedGuard.h"
#include "common/StringUtil.h"
@ -128,7 +129,7 @@ std::string SaveStateBase::GetSavestateFolder(int slot, bool isSavingOrLoading)
}
}
return Path::CombineStdString(dir, StringUtil::StdStringFromFormat("%s (%s).%02d.p2s",
return Path::Combine(dir, StringUtil::StdStringFromFormat("%s (%s).%02d.p2s",
serialName.c_str(), CRCvalue.c_str(), slot));
}
#endif

View File

@ -15,6 +15,8 @@
#pragma once
#include <vector>
#include "System.h"
#include "common/Exceptions.h"

View File

@ -23,6 +23,8 @@
#include "sio_internal.h"
#include "PAD/Gamepad.h"
#include "common/Timer.h"
#ifndef DISABLE_RECORDING
# include "Recording/InputRecording.h"
#endif
@ -609,12 +611,11 @@ SIO_WRITE memcardInit()
//minimum tries reached. start counting millisec timeout.
if(numTimesAccessed == FORCED_MCD_EJECTION_MIN_TRIES)
mcd->ForceEjection_Timestamp = wxDateTime::UNow();
mcd->ForceEjection_Timestamp = Common::Timer::GetCurrentValue();
if(numTimesAccessed > FORCED_MCD_EJECTION_MIN_TRIES)
{
wxTimeSpan delta = wxDateTime::UNow().Subtract(mcd->ForceEjection_Timestamp);
if(delta.GetMilliseconds() >= FORCED_MCD_EJECTION_MAX_MS_AFTER_MIN_TRIES)
if(Common::Timer::ConvertValueToMilliseconds(Common::Timer::GetCurrentValue() - mcd->ForceEjection_Timestamp) >= FORCED_MCD_EJECTION_MAX_MS_AFTER_MIN_TRIES)
{
DevCon.Warning( "Auto-eject: Timeout reached after mcd was accessed %d times [port:%d, slot:%d]", numTimesAccessed, sio.GetPort(), sio.GetSlot());
mcd->ForceEjection_Timeout = 0; //Done. on next sio access the card will be seen as inserted.
@ -1006,7 +1007,7 @@ void sioNextFrame() {
}
}
void sioSetGameSerial( const wxString& serial ) {
void sioSetGameSerial( const std::string& serial ) {
for ( uint port = 0; port < 2; ++port ) {
for ( uint slot = 0; slot < 4; ++slot ) {
if ( mcds[port][slot].ReIndex( serial ) ) {

Some files were not shown because too many files have changed in this diff Show More