Switch over to using TString to represent filesystem paths instead of TWideString. Fixed FileUtil not handling UTF-8 paths with Unicode characters correctly.

This commit is contained in:
Aruki 2017-05-04 15:43:25 -06:00
parent bdf0d188c3
commit e950634db2
38 changed files with 469 additions and 509 deletions

View File

@ -6,98 +6,102 @@
// These are mostly just wrappers around boost::filesystem functions. // These are mostly just wrappers around boost::filesystem functions.
using namespace boost::filesystem; using namespace boost::filesystem;
// Macro encapsulating a TString -> boost::filesystem::path conversion
// boost does not handle conversion from UTF-8 correctly so we need to do it manually
#define TO_PATH(String) path( *String.ToUTF16() )
namespace FileUtil namespace FileUtil
{ {
bool Exists(const TWideString &rkFilePath) bool Exists(const TString &rkFilePath)
{ {
return exists(*rkFilePath); return exists( TO_PATH(rkFilePath) );
} }
bool IsRoot(const TWideString& rkPath) bool IsRoot(const TString& rkPath)
{ {
// todo: is this actually a good/multiplatform way of checking for root? // todo: is this actually a good/multiplatform way of checking for root?
TWideString AbsPath = MakeAbsolute(rkPath); TString AbsPath = MakeAbsolute(rkPath);
TWideStringList Split = AbsPath.Split(L"\\/"); TStringList Split = AbsPath.Split("\\/");
return (Split.size() <= 1); return (Split.size() <= 1);
} }
bool IsFile(const TWideString& rkFilePath) bool IsFile(const TString& rkFilePath)
{ {
return is_regular_file(*rkFilePath); return is_regular_file( TO_PATH(rkFilePath) );
} }
bool IsDirectory(const TWideString& rkDirPath) bool IsDirectory(const TString& rkDirPath)
{ {
return is_directory(*rkDirPath); return is_directory( TO_PATH(rkDirPath) );
} }
bool IsAbsolute(const TWideString& rkDirPath) bool IsAbsolute(const TString& rkDirPath)
{ {
return boost::filesystem::path(*rkDirPath).is_absolute(); return boost::filesystem::path( TO_PATH(rkDirPath) ).is_absolute();
} }
bool IsRelative(const TWideString& rkDirPath) bool IsRelative(const TString& rkDirPath)
{ {
return boost::filesystem::path(*rkDirPath).is_relative(); return boost::filesystem::path( TO_PATH(rkDirPath) ).is_relative();
} }
bool IsEmpty(const TWideString& rkDirPath) bool IsEmpty(const TString& rkDirPath)
{ {
if (!IsDirectory(rkDirPath)) if (!IsDirectory(rkDirPath))
{ {
Log::Error("Non-directory path passed to IsEmpty(): " + rkDirPath.ToUTF8()); Log::Error("Non-directory path passed to IsEmpty(): " + rkDirPath);
DEBUG_BREAK; DEBUG_BREAK;
return false; return false;
} }
return is_empty(*rkDirPath); return is_empty( TO_PATH(rkDirPath) );
} }
bool MakeDirectory(const TWideString& rkNewDir) bool MakeDirectory(const TString& rkNewDir)
{ {
if (!IsValidPath(rkNewDir, true)) if (!IsValidPath(rkNewDir, true))
{ {
Log::Error("Unable to create directory because name contains illegal characters: " + rkNewDir.ToUTF8()); Log::Error("Unable to create directory because name contains illegal characters: " + rkNewDir);
return false; return false;
} }
return create_directories(*rkNewDir); return create_directories( TO_PATH(rkNewDir) );
} }
bool CopyFile(const TWideString& rkOrigPath, const TWideString& rkNewPath) bool CopyFile(const TString& rkOrigPath, const TString& rkNewPath)
{ {
if (!IsValidPath(rkNewPath, false)) if (!IsValidPath(rkNewPath, false))
{ {
Log::Error("Unable to copy file because destination name contains illegal characters: " + rkNewPath.ToUTF8()); Log::Error("Unable to copy file because destination name contains illegal characters: " + rkNewPath);
return false; return false;
} }
MakeDirectory(rkNewPath.GetFileDirectory()); MakeDirectory(rkNewPath.GetFileDirectory());
boost::system::error_code Error; boost::system::error_code Error;
copy(*rkOrigPath, *rkNewPath, Error); copy(TO_PATH(rkOrigPath), TO_PATH(rkNewPath), Error);
return (Error == boost::system::errc::success); return (Error == boost::system::errc::success);
} }
bool CopyDirectory(const TWideString& rkOrigPath, const TWideString& rkNewPath) bool CopyDirectory(const TString& rkOrigPath, const TString& rkNewPath)
{ {
if (!IsValidPath(rkNewPath, true)) if (!IsValidPath(rkNewPath, true))
{ {
Log::Error("Unable to copy directory because destination name contains illegal characters: " + rkNewPath.ToUTF8()); Log::Error("Unable to copy directory because destination name contains illegal characters: " + rkNewPath);
return false; return false;
} }
MakeDirectory(rkNewPath.GetFileDirectory()); MakeDirectory(rkNewPath.GetFileDirectory());
boost::system::error_code Error; boost::system::error_code Error;
copy_directory(*rkOrigPath, *rkNewPath, Error); copy_directory(TO_PATH(rkOrigPath), TO_PATH(rkNewPath), Error);
return (Error == boost::system::errc::success); return (Error == boost::system::errc::success);
} }
bool MoveFile(const TWideString& rkOldPath, const TWideString& rkNewPath) bool MoveFile(const TString& rkOldPath, const TString& rkNewPath)
{ {
if (!IsValidPath(rkNewPath, false)) if (!IsValidPath(rkNewPath, false))
{ {
Log::Error("Unable to move file because destination name contains illegal characters: " + rkNewPath.ToUTF8()); Log::Error("Unable to move file because destination name contains illegal characters: " + rkNewPath);
return false; return false;
} }
@ -107,11 +111,11 @@ bool MoveFile(const TWideString& rkOldPath, const TWideString& rkNewPath)
return false; return false;
} }
bool MoveDirectory(const TWideString& rkOldPath, const TWideString& rkNewPath) bool MoveDirectory(const TString& rkOldPath, const TString& rkNewPath)
{ {
if (!IsValidPath(rkNewPath, true)) if (!IsValidPath(rkNewPath, true))
{ {
Log::Error("Unable to move directory because destination name contains illegal characters: " + rkNewPath.ToUTF8()); Log::Error("Unable to move directory because destination name contains illegal characters: " + rkNewPath);
return false; return false;
} }
@ -121,13 +125,13 @@ bool MoveDirectory(const TWideString& rkOldPath, const TWideString& rkNewPath)
return false; return false;
} }
bool DeleteFile(const TWideString& rkFilePath) bool DeleteFile(const TString& rkFilePath)
{ {
if (!IsFile(rkFilePath)) return false; if (!IsFile(rkFilePath)) return false;
return remove(*rkFilePath) == 1; return remove( TO_PATH(rkFilePath) ) == 1;
} }
bool DeleteDirectory(const TWideString& rkDirPath, bool FailIfNotEmpty) bool DeleteDirectory(const TString& rkDirPath, bool FailIfNotEmpty)
{ {
// This is an extremely destructive function, be careful using it! // This is an extremely destructive function, be careful using it!
if (!IsDirectory(rkDirPath)) return false; if (!IsDirectory(rkDirPath)) return false;
@ -148,11 +152,11 @@ bool DeleteDirectory(const TWideString& rkDirPath, bool FailIfNotEmpty)
// Delete directory // Delete directory
boost::system::error_code Error; boost::system::error_code Error;
remove_all(*rkDirPath, Error); remove_all(TO_PATH(rkDirPath), Error);
return (Error == boost::system::errc::success); return (Error == boost::system::errc::success);
} }
bool ClearDirectory(const TWideString& rkDirPath) bool ClearDirectory(const TString& rkDirPath)
{ {
// This is an extremely destructive function, be careful using it! // This is an extremely destructive function, be careful using it!
if (!IsDirectory(rkDirPath)) return false; if (!IsDirectory(rkDirPath)) return false;
@ -168,7 +172,7 @@ bool ClearDirectory(const TWideString& rkDirPath)
} }
// Delete directory contents // Delete directory contents
TWideStringList DirContents; TStringList DirContents;
GetDirectoryContents(rkDirPath, DirContents, false); GetDirectoryContents(rkDirPath, DirContents, false);
for (auto It = DirContents.begin(); It != DirContents.end(); It++) for (auto It = DirContents.begin(); It != DirContents.end(); It++)
@ -181,62 +185,62 @@ bool ClearDirectory(const TWideString& rkDirPath)
Success = DeleteDirectory(*It, false); Success = DeleteDirectory(*It, false);
if (!Success) if (!Success)
Log::Error("Failed to delete filesystem object: " + TWideString(*It).ToUTF8()); Log::Error("Failed to delete filesystem object: " + TString(*It));
} }
return true; return true;
} }
u64 FileSize(const TWideString &rkFilePath) u64 FileSize(const TString &rkFilePath)
{ {
return (u64) (Exists(*rkFilePath) ? file_size(*rkFilePath) : -1); return (u64) (Exists(rkFilePath) ? file_size( TO_PATH(rkFilePath) ) : -1);
} }
u64 LastModifiedTime(const TWideString& rkFilePath) u64 LastModifiedTime(const TString& rkFilePath)
{ {
return (u64) last_write_time(*rkFilePath); return (u64) last_write_time( TO_PATH(rkFilePath) );
} }
TWideString WorkingDirectory() TString WorkingDirectory()
{ {
return boost::filesystem::current_path().string(); return boost::filesystem::current_path().string();
} }
TWideString MakeAbsolute(TWideString Path) TString MakeAbsolute(TString Path)
{ {
if (!boost::filesystem::path(*Path).has_root_name()) if (!TO_PATH(Path).has_root_name())
Path = WorkingDirectory() + L"\\" + Path; Path = WorkingDirectory() + "\\" + Path;
TWideStringList Components = Path.Split(L"/\\"); TStringList Components = Path.Split("/\\");
TWideStringList::iterator Prev; TStringList::iterator Prev;
for (TWideStringList::iterator Iter = Components.begin(); Iter != Components.end(); Iter++) for (TStringList::iterator Iter = Components.begin(); Iter != Components.end(); Iter++)
{ {
if (*Iter == L".") if (*Iter == ".")
Iter = Components.erase(Iter); Iter = Components.erase(Iter);
else if (*Iter == L"..") else if (*Iter == "..")
Iter = std::prev(Components.erase(Prev, std::next(Iter))); Iter = std::prev(Components.erase(Prev, std::next(Iter)));
Prev = Iter; Prev = Iter;
} }
TWideString Out; TString Out;
for (auto it = Components.begin(); it != Components.end(); it++) for (auto it = Components.begin(); it != Components.end(); it++)
Out += *it + L"\\"; Out += *it + "\\";
return Out; return Out;
} }
TWideString MakeRelative(const TWideString& rkPath, const TWideString& rkRelativeTo /*= WorkingDirectory()*/) TString MakeRelative(const TString& rkPath, const TString& rkRelativeTo /*= WorkingDirectory()*/)
{ {
TWideString AbsPath = MakeAbsolute(rkPath); TString AbsPath = MakeAbsolute(rkPath);
TWideString AbsRelTo = MakeAbsolute(rkRelativeTo); TString AbsRelTo = MakeAbsolute(rkRelativeTo);
TWideStringList PathComponents = AbsPath.Split(L"/\\"); TStringList PathComponents = AbsPath.Split("/\\");
TWideStringList RelToComponents = AbsRelTo.Split(L"/\\"); TStringList RelToComponents = AbsRelTo.Split("/\\");
// Find furthest common parent // Find furthest common parent
TWideStringList::iterator PathIter = PathComponents.begin(); TStringList::iterator PathIter = PathComponents.begin();
TWideStringList::iterator RelToIter = RelToComponents.begin(); TStringList::iterator RelToIter = RelToComponents.begin();
for (; PathIter != PathComponents.end() && RelToIter != RelToComponents.end(); PathIter++, RelToIter++) for (; PathIter != PathComponents.end() && RelToIter != RelToComponents.end(); PathIter++, RelToIter++)
{ {
@ -249,31 +253,31 @@ TWideString MakeRelative(const TWideString& rkPath, const TWideString& rkRelativ
return AbsPath; return AbsPath;
// Construct output path // Construct output path
TWideString Out; TString Out;
for (; RelToIter != RelToComponents.end(); RelToIter++) for (; RelToIter != RelToComponents.end(); RelToIter++)
Out += L"..\\"; Out += "..\\";
for (; PathIter != PathComponents.end(); PathIter++) for (; PathIter != PathComponents.end(); PathIter++)
Out += *PathIter + L"\\"; Out += *PathIter + "\\";
// Attempt to detect if this path is a file as opposed to a directory; if so, remove trailing backslash // Attempt to detect if this path is a file as opposed to a directory; if so, remove trailing backslash
if (PathComponents.back().Contains(L'.') && !rkPath.EndsWith(L'/') && !rkPath.EndsWith(L'\\')) if (PathComponents.back().Contains('.') && !rkPath.EndsWith('/') && !rkPath.EndsWith('\\'))
Out = Out.ChopBack(1); Out = Out.ChopBack(1);
return Out; return Out;
} }
TWideString SimplifyRelativePath(const TWideString& rkPath) TString SimplifyRelativePath(const TString& rkPath)
{ {
TWideStringList PathComponents = rkPath.Split(L"/\\"); TStringList PathComponents = rkPath.Split("/\\");
TWideStringList::iterator Iter = PathComponents.begin(); TStringList::iterator Iter = PathComponents.begin();
TWideStringList::iterator PrevIter = Iter; TStringList::iterator PrevIter = Iter;
for (auto Iter = PathComponents.begin(); Iter != PathComponents.end(); PrevIter = Iter, Iter++) for (auto Iter = PathComponents.begin(); Iter != PathComponents.end(); PrevIter = Iter, Iter++)
{ {
if (*Iter == L".." && *PrevIter != L"..") if (*Iter == ".." && *PrevIter != "..")
{ {
PrevIter = PathComponents.erase(PrevIter); PrevIter = PathComponents.erase(PrevIter);
PrevIter = PathComponents.erase(PrevIter); PrevIter = PathComponents.erase(PrevIter);
@ -282,22 +286,22 @@ TWideString SimplifyRelativePath(const TWideString& rkPath)
} }
} }
TWideString Out; TString Out;
for (auto Iter = PathComponents.begin(); Iter != PathComponents.end(); Iter++) for (auto Iter = PathComponents.begin(); Iter != PathComponents.end(); Iter++)
Out += *Iter + L'\\'; Out += *Iter + '\\';
return Out; return Out;
} }
static const wchar_t gskIllegalNameChars[] = { static const char gskIllegalNameChars[] = {
L'<', L'>', L'\"', L'/', L'\\', L'|', L'?', L'*' '<', '>', '\"', '/', '\\', '|', '?', '*'
}; };
TWideString SanitizeName(TWideString Name, bool Directory, bool RootDir /*= false*/) TString SanitizeName(TString Name, bool Directory, bool RootDir /*= false*/)
{ {
// Windows only atm // Windows only atm
if (Directory && (Name == L"." || Name == L"..")) if (Directory && (Name == "." || Name == ".."))
return Name; return Name;
// Remove illegal characters from path // Remove illegal characters from path
@ -312,7 +316,7 @@ TWideString SanitizeName(TWideString Name, bool Directory, bool RootDir /*= fals
Remove = true; Remove = true;
// For root, allow colon only as the last character of the name // For root, allow colon only as the last character of the name
else if (Chr == L':' && (!RootDir || iChr != Name.Size() - 1)) else if (Chr == ':' && (!RootDir || iChr != Name.Size() - 1))
Remove = true; Remove = true;
else else
@ -343,7 +347,7 @@ TWideString SanitizeName(TWideString Name, bool Directory, bool RootDir /*= fals
{ {
wchar_t Chr = Name[iChr]; wchar_t Chr = Name[iChr];
if (Chr == L' ' || Chr == L'.') if (Chr == ' ' || Chr == '.')
ChopNum++; ChopNum++;
else else
break; break;
@ -354,7 +358,7 @@ TWideString SanitizeName(TWideString Name, bool Directory, bool RootDir /*= fals
// Remove spaces from beginning of path // Remove spaces from beginning of path
u32 NumLeadingSpaces = 0; u32 NumLeadingSpaces = 0;
while (NumLeadingSpaces < Name.Size() && Name[NumLeadingSpaces] == L' ') while (NumLeadingSpaces < Name.Size() && Name[NumLeadingSpaces] == ' ')
NumLeadingSpaces++; NumLeadingSpaces++;
if (NumLeadingSpaces > 0) if (NumLeadingSpaces > 0)
@ -363,37 +367,40 @@ TWideString SanitizeName(TWideString Name, bool Directory, bool RootDir /*= fals
return Name; return Name;
} }
TWideString SanitizePath(TWideString Path, bool Directory) TString SanitizePath(TString Path, bool Directory)
{ {
TWideStringList Components = Path.Split(L"\\/"); TStringList Components = Path.Split("\\/");
u32 CompIdx = 0; u32 CompIdx = 0;
Path = L""; Path = "";
for (auto It = Components.begin(); It != Components.end(); It++) for (auto It = Components.begin(); It != Components.end(); It++)
{ {
TWideString Comp = *It; TString Comp = *It;
bool IsDir = Directory || CompIdx < Components.size() - 1; bool IsDir = Directory || CompIdx < Components.size() - 1;
bool IsRoot = CompIdx == 0; bool IsRoot = CompIdx == 0;
Comp = SanitizeName(Comp, IsDir, IsRoot); Comp = SanitizeName(Comp, IsDir, IsRoot);
Path += Comp; Path += Comp;
if (IsDir) Path += L'\\'; if (IsDir) Path += '\\';
CompIdx++; CompIdx++;
} }
return Path; return Path;
} }
bool IsValidName(const TWideString& rkName, bool Directory, bool RootDir /*= false*/) bool IsValidName(const TString& rkName, bool Directory, bool RootDir /*= false*/)
{ {
// Only accounting for Windows limitations right now. However, this function should // Only accounting for Windows limitations right now. However, this function should
// ideally return the same output on all platforms to ensure projects are cross compatible. // ideally return the same output on all platforms to ensure projects are cross platform.
if (rkName.IsEmpty()) if (rkName.IsEmpty())
return false; return false;
if (rkName.Size() > 255)
return false;
u32 NumIllegalChars = sizeof(gskIllegalNameChars) / sizeof(wchar_t); u32 NumIllegalChars = sizeof(gskIllegalNameChars) / sizeof(wchar_t);
if (Directory && (rkName == L"." || rkName == L"..")) if (Directory && (rkName == "." || rkName == ".."))
return true; return true;
// Check for banned characters // Check for banned characters
@ -405,7 +412,7 @@ bool IsValidName(const TWideString& rkName, bool Directory, bool RootDir /*= fal
return false; return false;
// Allow colon only on last character of root // Allow colon only on last character of root
if (Chr == L':' && (!RootDir || iChr != rkName.Size() - 1)) if (Chr == ':' && (!RootDir || iChr != rkName.Size() - 1))
return false; return false;
for (u32 iBan = 0; iBan < NumIllegalChars; iBan++) for (u32 iBan = 0; iBan < NumIllegalChars; iBan++)
@ -415,17 +422,17 @@ bool IsValidName(const TWideString& rkName, bool Directory, bool RootDir /*= fal
} }
} }
if (Directory && (rkName.Back() == L' ' || rkName.Back() == L'.')) if (Directory && (rkName.Back() == ' ' || rkName.Back() == '.'))
return false; return false;
return true; return true;
} }
bool IsValidPath(const TWideString& rkPath, bool Directory) bool IsValidPath(const TString& rkPath, bool Directory)
{ {
// Only accounting for Windows limitations right now. However, this function should // Only accounting for Windows limitations right now. However, this function should
// ideally return the same output on all platforms to ensure projects are cross compatible. // ideally return the same output on all platforms to ensure projects are cross platform.
TWideStringList Components = rkPath.Split(L"\\/"); TStringList Components = rkPath.Split("\\/");
// Validate other components // Validate other components
u32 CompIdx = 0; u32 CompIdx = 0;
@ -444,14 +451,14 @@ bool IsValidPath(const TWideString& rkPath, bool Directory)
return true; return true;
} }
void GetDirectoryContents(TWideString DirPath, TWideStringList& rOut, bool Recursive /*= true*/, bool IncludeFiles /*= true*/, bool IncludeDirs /*= true*/) void GetDirectoryContents(TString DirPath, TStringList& rOut, bool Recursive /*= true*/, bool IncludeFiles /*= true*/, bool IncludeDirs /*= true*/)
{ {
if (IsDirectory(DirPath)) if (IsDirectory(DirPath))
{ {
DirPath.Replace(L"/", L"\\"); DirPath.Replace("/", "\\");
bool IncludeAll = IncludeFiles && IncludeDirs; bool IncludeAll = IncludeFiles && IncludeDirs;
auto AddFileLambda = [IncludeFiles, IncludeDirs, IncludeAll, &rOut](std::wstring Path) -> void { auto AddFileLambda = [IncludeFiles, IncludeDirs, IncludeAll, &rOut](TString Path) -> void {
bool ShouldAddFile = IncludeAll || (IncludeFiles && IsFile(Path)) || (IncludeDirs && IsDirectory(Path)); bool ShouldAddFile = IncludeAll || (IncludeFiles && IsFile(Path)) || (IncludeDirs && IsDirectory(Path));
if (ShouldAddFile) if (ShouldAddFile)
@ -460,39 +467,31 @@ void GetDirectoryContents(TWideString DirPath, TWideStringList& rOut, bool Recur
if (Recursive) if (Recursive)
{ {
for (recursive_directory_iterator It(*DirPath); It != recursive_directory_iterator(); ++It) for (recursive_directory_iterator It( TO_PATH(DirPath) ); It != recursive_directory_iterator(); ++It)
{ {
#ifdef _WIN32 AddFileLambda( It->path().string() );
AddFileLambda( It->path().native() );
#else
AddFileLambda( TString(It->path().native()).ToUTF16().ToStdString() );
#endif
} }
} }
else else
{ {
for (directory_iterator It(*DirPath); It != directory_iterator(); ++It) for (directory_iterator It( TO_PATH(DirPath) ); It != directory_iterator(); ++It)
{ {
#ifdef _WIN32 AddFileLambda( It->path().string() );
AddFileLambda( It->path().native() );
#else
AddFileLambda( TString(It->path().native()).ToUTF16().ToStdString() );
#endif
} }
} }
} }
} }
TWideString FindFileExtension(const TWideString& rkDir, const TWideString& rkName) TString FindFileExtension(const TString& rkDir, const TString& rkName)
{ {
for (directory_iterator It(*rkDir); It != directory_iterator(); ++It) for (directory_iterator It( TO_PATH(rkDir) ); It != directory_iterator(); ++It)
{ {
TWideString Name = It->path().filename().native(); TString Name = It->path().filename().string();
if (Name.GetFileName(false) == rkName) return Name.GetFileExtension(); if (Name.GetFileName(false) == rkName) return Name.GetFileExtension();
} }
return L""; return "";
} }
} }

View File

@ -7,33 +7,33 @@
namespace FileUtil namespace FileUtil
{ {
bool Exists(const TWideString& rkFilePath); bool Exists(const TString& rkFilePath);
bool IsRoot(const TWideString& rkPath); bool IsRoot(const TString& rkPath);
bool IsFile(const TWideString& rkFilePath); bool IsFile(const TString& rkFilePath);
bool IsDirectory(const TWideString& rkDirPath); bool IsDirectory(const TString& rkDirPath);
bool IsAbsolute(const TWideString& rkDirPath); bool IsAbsolute(const TString& rkDirPath);
bool IsRelative(const TWideString& rkDirPath); bool IsRelative(const TString& rkDirPath);
bool IsEmpty(const TWideString& rkDirPath); bool IsEmpty(const TString& rkDirPath);
bool MakeDirectory(const TWideString& rkNewDir); bool MakeDirectory(const TString& rkNewDir);
bool CopyFile(const TWideString& rkOrigPath, const TWideString& rkNewPath); bool CopyFile(const TString& rkOrigPath, const TString& rkNewPath);
bool CopyDirectory(const TWideString& rkOrigPath, const TWideString& rkNewPath); bool CopyDirectory(const TString& rkOrigPath, const TString& rkNewPath);
bool MoveFile(const TWideString& rkOldPath, const TWideString& rkNewPath); bool MoveFile(const TString& rkOldPath, const TString& rkNewPath);
bool MoveDirectory(const TWideString& rkOldPath, const TWideString& rkNewPath); bool MoveDirectory(const TString& rkOldPath, const TString& rkNewPath);
bool DeleteFile(const TWideString& rkFilePath); bool DeleteFile(const TString& rkFilePath);
bool DeleteDirectory(const TWideString& rkDirPath, bool FailIfNotEmpty); // This is an extremely destructive function, be careful using it! bool DeleteDirectory(const TString& rkDirPath, bool FailIfNotEmpty); // This is an extremely destructive function, be careful using it!
bool ClearDirectory(const TWideString& rkDirPath); // This is an extremely destructive function, be careful using it! bool ClearDirectory(const TString& rkDirPath); // This is an extremely destructive function, be careful using it!
u64 FileSize(const TWideString& rkFilePath); u64 FileSize(const TString& rkFilePath);
u64 LastModifiedTime(const TWideString& rkFilePath); u64 LastModifiedTime(const TString& rkFilePath);
TWideString WorkingDirectory(); TString WorkingDirectory();
TWideString MakeAbsolute(TWideString Path); TString MakeAbsolute(TString Path);
TWideString MakeRelative(const TWideString& rkPath, const TWideString& rkRelativeTo = WorkingDirectory()); TString MakeRelative(const TString& rkPath, const TString& rkRelativeTo = WorkingDirectory());
TWideString SimplifyRelativePath(const TWideString& rkPath); TString SimplifyRelativePath(const TString& rkPath);
TWideString SanitizeName(TWideString Name, bool Directory, bool RootDir = false); TString SanitizeName(TString Name, bool Directory, bool RootDir = false);
TWideString SanitizePath(TWideString Path, bool Directory); TString SanitizePath(TString Path, bool Directory);
bool IsValidName(const TWideString& rkName, bool Directory, bool RootDir = false); bool IsValidName(const TString& rkName, bool Directory, bool RootDir = false);
bool IsValidPath(const TWideString& rkPath, bool Directory); bool IsValidPath(const TString& rkPath, bool Directory);
void GetDirectoryContents(TWideString DirPath, TWideStringList& rOut, bool Recursive = true, bool IncludeFiles = true, bool IncludeDirs = true); void GetDirectoryContents(TString DirPath, TStringList& rOut, bool Recursive = true, bool IncludeFiles = true, bool IncludeDirs = true);
TWideString FindFileExtension(const TWideString& rkDir, const TWideString& rkName); TString FindFileExtension(const TString& rkDir, const TString& rkName);
} }

View File

@ -19,7 +19,7 @@ public:
: IArchive(true, false) : IArchive(true, false)
, mOwnsStream(true) , mOwnsStream(true)
{ {
mpStream = new CFileInStream(rkFilename.ToStdString(), IOUtil::eBigEndian); mpStream = new CFileInStream(rkFilename, IOUtil::eBigEndian);
ASSERT(mpStream->IsValid()); ASSERT(mpStream->IsValid());
CSerialVersion Version(*mpStream); CSerialVersion Version(*mpStream);

View File

@ -18,7 +18,7 @@ public:
: IArchive(false, true) : IArchive(false, true)
, mOwnsStream(true) , mOwnsStream(true)
{ {
mpStream = new CFileOutStream(rkFilename.ToStdString(), IOUtil::eBigEndian); mpStream = new CFileOutStream(rkFilename, IOUtil::eBigEndian);
ASSERT(mpStream->IsValid()); ASSERT(mpStream->IsValid());
SetVersion(skCurrentArchiveVersion, FileVersion, Game); SetVersion(skCurrentArchiveVersion, FileVersion, Game);
GetVersionInfo().Write(*mpStream); GetVersionInfo().Write(*mpStream);
@ -65,8 +65,8 @@ public:
virtual void SerializePrimitive(u64& rValue) { mpStream->WriteLongLong(rValue); } virtual void SerializePrimitive(u64& rValue) { mpStream->WriteLongLong(rValue); }
virtual void SerializePrimitive(float& rValue) { mpStream->WriteFloat(rValue); } virtual void SerializePrimitive(float& rValue) { mpStream->WriteFloat(rValue); }
virtual void SerializePrimitive(double& rValue) { mpStream->WriteDouble(rValue); } virtual void SerializePrimitive(double& rValue) { mpStream->WriteDouble(rValue); }
virtual void SerializePrimitive(TString& rValue) { mpStream->WriteSizedString(rValue.ToStdString()); } virtual void SerializePrimitive(TString& rValue) { mpStream->WriteSizedString(rValue); }
virtual void SerializePrimitive(TWideString& rValue) { mpStream->WriteSizedWideString(rValue.ToStdString()); } virtual void SerializePrimitive(TWideString& rValue) { mpStream->WriteSizedWideString(rValue); }
virtual void SerializePrimitive(CFourCC& rValue) { rValue.Write(*mpStream); } virtual void SerializePrimitive(CFourCC& rValue) { rValue.Write(*mpStream); }
virtual void SerializePrimitive(CAssetID& rValue) { rValue.Write(*mpStream); } virtual void SerializePrimitive(CAssetID& rValue) { rValue.Write(*mpStream); }

View File

@ -24,7 +24,7 @@ public:
: IArchive(true, false) : IArchive(true, false)
, mOwnsStream(true) , mOwnsStream(true)
{ {
mpStream = new CFileInStream(rkFilename.ToStdString(), IOUtil::eBigEndian); mpStream = new CFileInStream(rkFilename, IOUtil::eBigEndian);
ASSERT(mpStream->IsValid()); ASSERT(mpStream->IsValid());
CSerialVersion Version(*mpStream); CSerialVersion Version(*mpStream);

View File

@ -22,7 +22,7 @@ public:
: IArchive(false, true) : IArchive(false, true)
, mOwnsStream(true) , mOwnsStream(true)
{ {
mpStream = new CFileOutStream(rkFilename.ToStdString(), IOUtil::eBigEndian); mpStream = new CFileOutStream(rkFilename, IOUtil::eBigEndian);
ASSERT(mpStream->IsValid()); ASSERT(mpStream->IsValid());
SetVersion(skCurrentArchiveVersion, FileVersion, Game); SetVersion(skCurrentArchiveVersion, FileVersion, Game);
@ -117,8 +117,8 @@ public:
virtual void SerializePrimitive(u64& rValue) { mpStream->WriteLongLong(rValue); } virtual void SerializePrimitive(u64& rValue) { mpStream->WriteLongLong(rValue); }
virtual void SerializePrimitive(float& rValue) { mpStream->WriteFloat(rValue); } virtual void SerializePrimitive(float& rValue) { mpStream->WriteFloat(rValue); }
virtual void SerializePrimitive(double& rValue) { mpStream->WriteDouble(rValue); } virtual void SerializePrimitive(double& rValue) { mpStream->WriteDouble(rValue); }
virtual void SerializePrimitive(TString& rValue) { mpStream->WriteSizedString(rValue.ToStdString()); } virtual void SerializePrimitive(TString& rValue) { mpStream->WriteSizedString(rValue); }
virtual void SerializePrimitive(TWideString& rValue) { mpStream->WriteSizedWideString(rValue.ToStdString()); } virtual void SerializePrimitive(TWideString& rValue) { mpStream->WriteSizedWideString(rValue); }
virtual void SerializePrimitive(CFourCC& rValue) { rValue.Write(*mpStream); } virtual void SerializePrimitive(CFourCC& rValue) { rValue.Write(*mpStream); }
virtual void SerializePrimitive(CAssetID& rValue) { rValue.Write(*mpStream); } virtual void SerializePrimitive(CAssetID& rValue) { rValue.Write(*mpStream); }

View File

@ -4,21 +4,6 @@
#include <locale> #include <locale>
// ************ TString ************ // ************ TString ************
TString::TString(const wchar_t* pkText)
{
*this = TWideString(pkText).ToUTF8();
}
TString::TString(const std::wstring& rkText)
{
*this = TWideString(rkText).ToUTF8();
}
TString::TString(const TWideString& rkText)
{
*this = rkText.ToUTF8();
}
TWideString TString::ToUTF16() const TWideString TString::ToUTF16() const
{ {
TWideString Out; TWideString Out;
@ -96,21 +81,6 @@ TWideString TString::ToUTF16() const
} }
// ************ TWideString ************ // ************ TWideString ************
TWideString::TWideString(const char* pkText)
{
*this = TString(pkText).ToUTF16();
}
TWideString::TWideString(const std::string& rkText)
{
*this = TString(rkText).ToUTF16();
}
TWideString::TWideString(const TString& rkText)
{
*this = rkText.ToUTF16();
}
TString TWideString::ToUTF8() const TString TWideString::ToUTF8() const
{ {
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> Convert; std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> Convert;

View File

@ -1105,15 +1105,12 @@ class TString : public TBasicString<char>
{ {
public: public:
TString() : TBasicString<char>() {} TString() : TBasicString<char>() {}
TString(size_t size) : TBasicString<char>(size) {} TString(size_t Size) : TBasicString<char>(Size) {}
TString(size_t size, char fill) : TBasicString<char>(size, fill) {} TString(size_t Size, char Fill) : TBasicString<char>(Size, Fill) {}
TString(const char* pkText) : TBasicString<char>(pkText) {} TString(const char* pkText) : TBasicString<char>(pkText) {}
TString(const char* pkText, u32 length) : TBasicString<char>(pkText, length) {} TString(const char* pkText, u32 Length) : TBasicString<char>(pkText, Length) {}
TString(const std::string& rkText) : TBasicString<char>(rkText) {} TString(const std::string& rkText) : TBasicString<char>(rkText) {}
TString(const TBasicString<char>& rkStr) : TBasicString<char>(rkStr) {} TString(const TBasicString<char>& rkStr) : TBasicString<char>(rkStr) {}
TString(const wchar_t* pkText);
TString(const std::wstring& rkText);
TString(const class TWideString& rkText);
class TWideString ToUTF16() const; class TWideString ToUTF16() const;
}; };
@ -1123,15 +1120,12 @@ class TWideString : public TBasicString<wchar_t>
{ {
public: public:
TWideString() : TBasicString<wchar_t>() {} TWideString() : TBasicString<wchar_t>() {}
TWideString(u32 size) : TBasicString<wchar_t>(size) {} TWideString(u32 Size) : TBasicString<wchar_t>(Size) {}
TWideString(u32 size, wchar_t fill) : TBasicString<wchar_t>(size, fill) {} TWideString(u32 Size, wchar_t Fill) : TBasicString<wchar_t>(Size, Fill) {}
TWideString(const wchar_t* pkText) : TBasicString<wchar_t>(pkText) {} TWideString(const wchar_t* pkText) : TBasicString<wchar_t>(pkText) {}
TWideString(const wchar_t* pkText, u32 length) : TBasicString<wchar_t>(pkText, length) {} TWideString(const wchar_t* pkText, u32 Length) : TBasicString<wchar_t>(pkText, Length) {}
TWideString(const std::wstring& rkText) : TBasicString<wchar_t>(rkText) {} TWideString(const std::wstring& rkText) : TBasicString<wchar_t>(rkText) {}
TWideString(const TBasicString<wchar_t>& rkStr) : TBasicString<wchar_t>(rkStr) {} TWideString(const TBasicString<wchar_t>& rkStr) : TBasicString<wchar_t>(rkStr) {}
TWideString(const char* pkText);
TWideString(const std::string& rkText);
TWideString(const TString& rkText);
class TString ToUTF8() const; class TString ToUTF8() const;
}; };

View File

@ -87,7 +87,7 @@ void CAudioManager::LogSoundInfo(u32 SoundID)
Log::Write("Sound ID: " + TString::HexString(SoundInfo.SoundID, 4)); Log::Write("Sound ID: " + TString::HexString(SoundInfo.SoundID, 4));
Log::Write("Define ID: " + TString::HexString(SoundInfo.DefineID, 4)); Log::Write("Define ID: " + TString::HexString(SoundInfo.DefineID, 4));
Log::Write("Audio Group: " + SoundInfo.pAudioGroup->Entry()->Name().ToUTF8()); Log::Write("Audio Group: " + SoundInfo.pAudioGroup->Entry()->Name());
Log::Write(""); Log::Write("");
} }
} }

View File

@ -20,11 +20,11 @@
#define PROCESS_SCANS 1 #define PROCESS_SCANS 1
#define PROCESS_FONTS 1 #define PROCESS_FONTS 1
void ApplyGeneratedName(CResourceEntry *pEntry, const TWideString& rkDir, const TWideString& rkName) void ApplyGeneratedName(CResourceEntry *pEntry, const TString& rkDir, const TString& rkName)
{ {
ASSERT(pEntry != nullptr); ASSERT(pEntry != nullptr);
TWideString SanitizedName = FileUtil::SanitizeName(rkName, false); TString SanitizedName = FileUtil::SanitizeName(rkName, false);
TWideString SanitizedDir = FileUtil::SanitizePath(rkDir, true); TString SanitizedDir = FileUtil::SanitizePath(rkDir, true);
if (SanitizedName.IsEmpty()) return; if (SanitizedName.IsEmpty()) return;
// trying to keep these as consistent with Retro's naming scheme as possible, and // trying to keep these as consistent with Retro's naming scheme as possible, and
@ -35,12 +35,12 @@ void ApplyGeneratedName(CResourceEntry *pEntry, const TWideString& rkDir, const
CVirtualDirectory *pNewDir = pEntry->ResourceStore()->GetVirtualDirectory(SanitizedDir, false, true); CVirtualDirectory *pNewDir = pEntry->ResourceStore()->GetVirtualDirectory(SanitizedDir, false, true);
if (pEntry->Directory() == pNewDir && pEntry->Name() == SanitizedName) return; if (pEntry->Directory() == pNewDir && pEntry->Name() == SanitizedName) return;
TWideString Name = SanitizedName; TString Name = SanitizedName;
int AppendNum = 0; int AppendNum = 0;
while (pNewDir->FindChildResource(Name, pEntry->ResourceType()) != nullptr) while (pNewDir->FindChildResource(Name, pEntry->ResourceType()) != nullptr)
{ {
Name = TWideString::Format(L"%s_%d", *SanitizedName, AppendNum); Name = TString::Format("%s_%d", *SanitizedName, AppendNum);
AppendNum++; AppendNum++;
} }
@ -67,29 +67,29 @@ void GenerateAssetNames(CGameProject *pProj)
CResourceEntry *pRes = pStore->FindEntry(rkRes.ID); CResourceEntry *pRes = pStore->FindEntry(rkRes.ID);
if (pRes) if (pRes)
ApplyGeneratedName(pRes, pPkg->Name().ToUTF16(), rkRes.Name.ToUTF16()); ApplyGeneratedName(pRes, pPkg->Name(), rkRes.Name);
} }
} }
#endif #endif
#if PROCESS_WORLDS #if PROCESS_WORLDS
// Generate world/area names // Generate world/area names
const TWideString kWorldsRoot = L"Worlds\\"; const TString kWorldsRoot = "Worlds\\";
for (TResourceIterator<eWorld> It(pStore); It; ++It) for (TResourceIterator<eWorld> It(pStore); It; ++It)
{ {
// Set world name // Set world name
CWorld *pWorld = (CWorld*) It->Load(); CWorld *pWorld = (CWorld*) It->Load();
TWideString WorldName = pWorld->Name().ToUTF16(); TString WorldName = pWorld->Name();
TWideString WorldDir = kWorldsRoot + WorldName + L'\\'; TString WorldDir = kWorldsRoot + WorldName + '\\';
TWideString WorldMasterName = L"!" + WorldName + L"_Master"; TString WorldMasterName = "!" + WorldName + "_Master";
TWideString WorldMasterDir = WorldDir + WorldMasterName + L'\\'; TString WorldMasterDir = WorldDir + WorldMasterName + '\\';
ApplyGeneratedName(*It, WorldMasterDir, WorldMasterName); ApplyGeneratedName(*It, WorldMasterDir, WorldMasterName);
// Move world stuff // Move world stuff
const TWideString WorldNamesDir = L"Strings\\Worlds\\General\\"; const TString WorldNamesDir = "Strings\\Worlds\\General\\";
const TWideString AreaNamesDir = TWideString::Format(L"Strings\\Worlds\\%s\\", *WorldName); const TString AreaNamesDir = TString::Format("Strings\\Worlds\\%s\\", *WorldName);
CModel *pSkyModel = pWorld->DefaultSkybox(); CModel *pSkyModel = pWorld->DefaultSkybox();
CStringTable *pWorldNameTable = pWorld->NameString(); CStringTable *pWorldNameTable = pWorld->NameString();
@ -107,7 +107,7 @@ void GenerateAssetNames(CGameProject *pProj)
{ {
// Move sky model // Move sky model
CResourceEntry *pSkyEntry = pSkyModel->Entry(); CResourceEntry *pSkyEntry = pSkyModel->Entry();
ApplyGeneratedName(pSkyEntry, WorldDir + L"sky\\cooked\\", WorldName + L"_" + L"sky"); ApplyGeneratedName(pSkyEntry, WorldDir + "sky\\cooked\\", WorldName + "_sky");
// Move sky textures // Move sky textures
for (u32 iSet = 0; iSet < pSkyModel->GetMatSetCount(); iSet++) for (u32 iSet = 0; iSet < pSkyModel->GetMatSetCount(); iSet++)
@ -123,7 +123,7 @@ void GenerateAssetNames(CGameProject *pProj)
CMaterialPass *pPass = pMat->Pass(iPass); CMaterialPass *pPass = pMat->Pass(iPass);
if (pPass->Texture()) if (pPass->Texture())
ApplyGeneratedName(pPass->Texture()->Entry(), WorldDir + L"sky\\sourceimages\\", pPass->Texture()->Entry()->Name()); ApplyGeneratedName(pPass->Texture()->Entry(), WorldDir + "sky\\sourceimages\\", pPass->Texture()->Entry()->Name());
} }
} }
} }
@ -138,18 +138,18 @@ void GenerateAssetNames(CGameProject *pProj)
if (pDarkWorldNameTable) if (pDarkWorldNameTable)
{ {
CResourceEntry *pDarkNameEntry = pDarkWorldNameTable->Entry(); CResourceEntry *pDarkNameEntry = pDarkWorldNameTable->Entry();
ApplyGeneratedName(pDarkNameEntry, WorldNamesDir, WorldName + L"Dark"); ApplyGeneratedName(pDarkNameEntry, WorldNamesDir, WorldName + "Dark");
} }
// Areas // Areas
for (u32 iArea = 0; iArea < pWorld->NumAreas(); iArea++) for (u32 iArea = 0; iArea < pWorld->NumAreas(); iArea++)
{ {
// Determine area name // Determine area name
TWideString AreaName = pWorld->AreaInternalName(iArea).ToUTF16(); TString AreaName = pWorld->AreaInternalName(iArea);
CAssetID AreaID = pWorld->AreaResourceID(iArea); CAssetID AreaID = pWorld->AreaResourceID(iArea);
if (AreaName.IsEmpty()) if (AreaName.IsEmpty())
AreaName = AreaID.ToString().ToUTF16(); AreaName = AreaID.ToString();
// Rename area stuff // Rename area stuff
CResourceEntry *pAreaEntry = pStore->FindEntry(AreaID); CResourceEntry *pAreaEntry = pStore->FindEntry(AreaID);
@ -173,7 +173,7 @@ void GenerateAssetNames(CGameProject *pProj)
#if PROCESS_AREAS #if PROCESS_AREAS
// Move area dependencies // Move area dependencies
TWideString AreaCookedDir = WorldDir + AreaName + L"\\cooked\\"; TString AreaCookedDir = WorldDir + AreaName + "\\cooked\\";
CGameArea *pArea = (CGameArea*) pAreaEntry->Load(); CGameArea *pArea = (CGameArea*) pAreaEntry->Load();
// Area lightmaps // Area lightmaps
@ -193,15 +193,15 @@ void GenerateAssetNames(CGameProject *pProj)
(pArea->Game() >= eCorruptionProto && pPass->Type() == "DIFF") ); (pArea->Game() >= eCorruptionProto && pPass->Type() == "DIFF") );
bool IsBloomLightmap = (pArea->Game() >= eCorruptionProto && pPass->Type() == "BLOL"); bool IsBloomLightmap = (pArea->Game() >= eCorruptionProto && pPass->Type() == "BLOL");
TWideString TexName; TString TexName;
if (IsLightmap) if (IsLightmap)
{ {
TexName = TWideString::Format(L"%s_lit_lightmap%d", *AreaName, LightmapNum); TexName = TString::Format("%s_lit_lightmap%d", *AreaName, LightmapNum);
} }
else if (IsBloomLightmap) else if (IsBloomLightmap)
{ {
TexName = TWideString::Format(L"%s_lit_lightmap_bloom%d", *AreaName, LightmapNum); TexName = TString::Format("%s_lit_lightmap_bloom%d", *AreaName, LightmapNum);
} }
if (!TexName.IsEmpty()) if (!TexName.IsEmpty())
@ -246,9 +246,9 @@ void GenerateAssetNames(CGameProject *pProj)
if (pEntry && !pEntry->IsNamed()) if (pEntry && !pEntry->IsNamed())
{ {
TWideString ScanName = Name.ToUTF16().ChopFront(4); TString ScanName = Name.ChopFront(4);
if (ScanName.EndsWith(L".SCAN", false)) if (ScanName.EndsWith(".SCAN", false))
ScanName = ScanName.ChopBack(5); ScanName = ScanName.ChopBack(5);
ApplyGeneratedName(pEntry, pEntry->DirectoryPath(), ScanName); ApplyGeneratedName(pEntry, pEntry->DirectoryPath(), ScanName);
@ -281,9 +281,9 @@ void GenerateAssetNames(CGameProject *pProj)
if (pEntry && !pEntry->IsNamed()) if (pEntry && !pEntry->IsNamed())
{ {
TWideString StringName = Name.ToUTF16().ChopBack(5); TString StringName = Name.ChopBack(5);
if (StringName.StartsWith(L"HUDMemo - ")) if (StringName.StartsWith("HUDMemo - "))
StringName = StringName.ChopFront(10); StringName = StringName.ChopFront(10);
ApplyGeneratedName(pEntry, pEntry->DirectoryPath(), StringName); ApplyGeneratedName(pEntry, pEntry->DirectoryPath(), StringName);
@ -365,7 +365,7 @@ void GenerateAssetNames(CGameProject *pProj)
CResourceEntry *pTexEntry = pLightmapTex->Entry(); CResourceEntry *pTexEntry = pLightmapTex->Entry();
if (pTexEntry->IsNamed() || pTexEntry->IsCategorized()) continue; if (pTexEntry->IsNamed() || pTexEntry->IsCategorized()) continue;
TWideString TexName = TWideString::Format(L"%s_lightmap%d", *It->Name(), LightmapNum); TString TexName = TString::Format("%s_lightmap%d", *It->Name(), LightmapNum);
ApplyGeneratedName(pTexEntry, pModel->Entry()->DirectoryPath(), TexName); ApplyGeneratedName(pTexEntry, pModel->Entry()->DirectoryPath(), TexName);
pTexEntry->SetHidden(true); pTexEntry->SetHidden(true);
LightmapNum++; LightmapNum++;
@ -380,24 +380,24 @@ void GenerateAssetNames(CGameProject *pProj)
#if PROCESS_AUDIO_GROUPS #if PROCESS_AUDIO_GROUPS
// Generate Audio Group names // Generate Audio Group names
const TWideString kAudioGrpDir = L"Audio\\"; const TString kAudioGrpDir = "Audio\\";
for (TResourceIterator<eAudioGroup> It(pStore); It; ++It) for (TResourceIterator<eAudioGroup> It(pStore); It; ++It)
{ {
CAudioGroup *pGroup = (CAudioGroup*) It->Load(); CAudioGroup *pGroup = (CAudioGroup*) It->Load();
TWideString GroupName = pGroup->GroupName().ToUTF16(); TString GroupName = pGroup->GroupName();
ApplyGeneratedName(*It, kAudioGrpDir, GroupName); ApplyGeneratedName(*It, kAudioGrpDir, GroupName);
} }
#endif #endif
#if PROCESS_AUDIO_MACROS #if PROCESS_AUDIO_MACROS
// Process audio macro/sample names // Process audio macro/sample names
const TWideString kSfxDir = L"Audio\\Uncategorized\\"; const TString kSfxDir = "Audio\\Uncategorized\\";
for (TResourceIterator<eAudioMacro> It(pStore); It; ++It) for (TResourceIterator<eAudioMacro> It(pStore); It; ++It)
{ {
CAudioMacro *pMacro = (CAudioMacro*) It->Load(); CAudioMacro *pMacro = (CAudioMacro*) It->Load();
TWideString MacroName = pMacro->MacroName().ToUTF16(); TString MacroName = pMacro->MacroName();
ApplyGeneratedName(*It, kSfxDir, MacroName); ApplyGeneratedName(*It, kSfxDir, MacroName);
for (u32 iSamp = 0; iSamp < pMacro->NumSamples(); iSamp++) for (u32 iSamp = 0; iSamp < pMacro->NumSamples(); iSamp++)
@ -407,12 +407,12 @@ void GenerateAssetNames(CGameProject *pProj)
if (pSample && !pSample->IsNamed()) if (pSample && !pSample->IsNamed())
{ {
TWideString SampleName; TString SampleName;
if (pMacro->NumSamples() == 1) if (pMacro->NumSamples() == 1)
SampleName = MacroName; SampleName = MacroName;
else else
SampleName = TWideString::Format(L"%s_%d", *MacroName, iSamp); SampleName = TString::Format("%s_%d", *MacroName, iSamp);
ApplyGeneratedName(pSample, kSfxDir, SampleName); ApplyGeneratedName(pSample, kSfxDir, SampleName);
} }
@ -428,15 +428,15 @@ void GenerateAssetNames(CGameProject *pProj)
for (; It; ++It) for (; It; ++It)
{ {
TWideString SetDir = It->DirectoryPath(); TString SetDir = It->DirectoryPath();
TWideString NewSetName; TString NewSetName;
CAnimSet *pSet = (CAnimSet*) It->Load(); CAnimSet *pSet = (CAnimSet*) It->Load();
for (u32 iChar = 0; iChar < pSet->NumCharacters(); iChar++) for (u32 iChar = 0; iChar < pSet->NumCharacters(); iChar++)
{ {
const SSetCharacter *pkChar = pSet->Character(iChar); const SSetCharacter *pkChar = pSet->Character(iChar);
TWideString CharName = pkChar->Name.ToUTF16(); TString CharName = pkChar->Name;
if (iChar == 0) NewSetName = CharName; if (iChar == 0) NewSetName = CharName;
if (pkChar->pModel) ApplyGeneratedName(pkChar->pModel->Entry(), SetDir, CharName); if (pkChar->pModel) ApplyGeneratedName(pkChar->pModel->Entry(), SetDir, CharName);
@ -449,7 +449,7 @@ void GenerateAssetNames(CGameProject *pProj)
if (pAnimDataEntry) if (pAnimDataEntry)
{ {
TWideString AnimDataName = TWideString::Format(L"%s_animdata", *CharName); TString AnimDataName = TString::Format("%s_animdata", *CharName);
ApplyGeneratedName(pAnimDataEntry, SetDir, AnimDataName); ApplyGeneratedName(pAnimDataEntry, SetDir, AnimDataName);
} }
} }
@ -460,16 +460,16 @@ void GenerateAssetNames(CGameProject *pProj)
if (rkOverlay.ModelID.IsValid() || rkOverlay.SkinID.IsValid()) if (rkOverlay.ModelID.IsValid() || rkOverlay.SkinID.IsValid())
{ {
TWideString TypeName = ( TString TypeName = (
rkOverlay.Type == eOT_Frozen ? L"frozen" : rkOverlay.Type == eOT_Frozen ? "frozen" :
rkOverlay.Type == eOT_Acid ? L"acid" : rkOverlay.Type == eOT_Acid ? "acid" :
rkOverlay.Type == eOT_Hypermode ? L"hypermode" : rkOverlay.Type == eOT_Hypermode ? "hypermode" :
rkOverlay.Type == eOT_XRay ? L"xray" : rkOverlay.Type == eOT_XRay ? "xray" :
L"" ""
); );
ASSERT(TypeName != L""); ASSERT(TypeName != "");
TWideString OverlayName = TWideString::Format(L"%s_%s", *CharName, *TypeName); TString OverlayName = TString::Format("%s_%s", *CharName, *TypeName);
if (rkOverlay.ModelID.IsValid()) if (rkOverlay.ModelID.IsValid())
{ {
@ -498,11 +498,11 @@ void GenerateAssetNames(CGameProject *pProj)
if (pAnim) if (pAnim)
{ {
ApplyGeneratedName(pAnim->Entry(), SetDir, rkPrim.Name().ToUTF16()); ApplyGeneratedName(pAnim->Entry(), SetDir, rkPrim.Name());
CAnimEventData *pEvents = pAnim->EventData(); CAnimEventData *pEvents = pAnim->EventData();
if (pEvents) if (pEvents)
ApplyGeneratedName(pEvents->Entry(), SetDir, rkPrim.Name().ToUTF16()); ApplyGeneratedName(pEvents->Entry(), SetDir, rkPrim.Name());
} }
} }
} }
@ -511,7 +511,7 @@ void GenerateAssetNames(CGameProject *pProj)
#if PROCESS_STRINGS #if PROCESS_STRINGS
// Generate string names // Generate string names
const TWideString kStringsDir = L"Strings\\Uncategorized\\"; const TString kStringsDir = "Strings\\Uncategorized\\";
for (TResourceIterator<eStringTable> It(pStore); It; ++It) for (TResourceIterator<eStringTable> It(pStore); It; ++It)
{ {
@ -530,7 +530,7 @@ void GenerateAssetNames(CGameProject *pProj)
while (Name.EndsWith(L".") || TWideString::IsWhitespace(Name.Back())) while (Name.EndsWith(L".") || TWideString::IsWhitespace(Name.Back()))
Name = Name.ChopBack(1); Name = Name.ChopBack(1);
ApplyGeneratedName(pString->Entry(), kStringsDir, Name); ApplyGeneratedName(pString->Entry(), kStringsDir, Name.ToUTF8());
} }
} }
#endif #endif
@ -541,7 +541,7 @@ void GenerateAssetNames(CGameProject *pProj)
{ {
if (It->IsNamed()) continue; if (It->IsNamed()) continue;
CScan *pScan = (CScan*) It->Load(); CScan *pScan = (CScan*) It->Load();
TWideString ScanName; TString ScanName;
if (pProj->Game() >= eEchoesDemo) if (pProj->Game() >= eEchoesDemo)
{ {
@ -562,13 +562,13 @@ void GenerateAssetNames(CGameProject *pProj)
{ {
CAssetID FrameID = pScan->GuiFrame(); CAssetID FrameID = pScan->GuiFrame();
CResourceEntry *pEntry = pStore->FindEntry(FrameID); CResourceEntry *pEntry = pStore->FindEntry(FrameID);
if (pEntry) ApplyGeneratedName(pEntry, pEntry->DirectoryPath(), L"ScanFrame"); if (pEntry) ApplyGeneratedName(pEntry, pEntry->DirectoryPath(), "ScanFrame");
for (u32 iImg = 0; iImg < 4; iImg++) for (u32 iImg = 0; iImg < 4; iImg++)
{ {
CAssetID ImageID = pScan->ScanImage(iImg); CAssetID ImageID = pScan->ScanImage(iImg);
CResourceEntry *pImgEntry = pStore->FindEntry(ImageID); CResourceEntry *pImgEntry = pStore->FindEntry(ImageID);
if (pImgEntry) ApplyGeneratedName(pImgEntry, pImgEntry->DirectoryPath(), TWideString::Format(L"%s_Image%d", *ScanName, iImg)); if (pImgEntry) ApplyGeneratedName(pImgEntry, pImgEntry->DirectoryPath(), TString::Format("%s_Image%d", *ScanName, iImg));
} }
} }
} }
@ -582,12 +582,12 @@ void GenerateAssetNames(CGameProject *pProj)
if (pFont) if (pFont)
{ {
ApplyGeneratedName(pFont->Entry(), pFont->Entry()->DirectoryPath(), pFont->FontName().ToUTF16()); ApplyGeneratedName(pFont->Entry(), pFont->Entry()->DirectoryPath(), pFont->FontName());
CTexture *pFontTex = pFont->Texture(); CTexture *pFontTex = pFont->Texture();
if (pFontTex) if (pFontTex)
ApplyGeneratedName(pFontTex->Entry(), pFont->Entry()->DirectoryPath(), pFont->Entry()->Name() + L"_tex"); ApplyGeneratedName(pFontTex->Entry(), pFont->Entry()->DirectoryPath(), pFont->Entry()->Name() + "_tex");
} }
} }
#endif #endif

View File

@ -91,8 +91,8 @@ void CAssetNameMap::CopyFromStore(CResourceStore *pStore /*= gpResourceStore*/)
CAssetID ID = It->ID(); CAssetID ID = It->ID();
ASSERT(ID.Length() == mIDLength); ASSERT(ID.Length() == mIDLength);
TWideString Name = It->Name(); TString Name = It->Name();
TWideString Directory = It->Directory()->FullPath(); TString Directory = It->Directory()->FullPath();
CFourCC Type = It->CookedExtension(); CFourCC Type = It->CookedExtension();
SAssetNameInfo NameInfo { Name, Directory, Type }; SAssetNameInfo NameInfo { Name, Directory, Type };
@ -104,12 +104,12 @@ void CAssetNameMap::CopyFromStore(CResourceStore *pStore /*= gpResourceStore*/)
while (mUsedSet.find(NewNameInfo) != mUsedSet.end()) while (mUsedSet.find(NewNameInfo) != mUsedSet.end())
{ {
NewNameInfo.Name = NameInfo.Name + L'_' + TWideString::FromInt32(NumConflicted, 0, 10); NewNameInfo.Name = NameInfo.Name + '_' + TString::FromInt32(NumConflicted, 0, 10);
NumConflicted++; NumConflicted++;
} }
TString OldPath = NameInfo.FullPath().ToUTF8(); TString OldPath = NameInfo.FullPath();
TString NewPath = NewNameInfo.FullPath().ToUTF8(); TString NewPath = NewNameInfo.FullPath();
Log::Warning("Detected name conflict when copying asset name from the resource store; renaming."); Log::Warning("Detected name conflict when copying asset name from the resource store; renaming.");
Log::Warning("\tOld Path: " + OldPath); Log::Warning("\tOld Path: " + OldPath);
Log::Warning("\tNew Path: " + NewPath); Log::Warning("\tNew Path: " + NewPath);
@ -153,7 +153,7 @@ void CAssetNameMap::PostLoadValidate()
// Verify the name/path is valid // Verify the name/path is valid
if (!CResourceStore::IsValidResourcePath(rkInfo.Directory, rkInfo.Name)) if (!CResourceStore::IsValidResourcePath(rkInfo.Directory, rkInfo.Name))
{ {
Log::Error("Invalid resource path in asset name map: " + rkInfo.Directory.ToUTF8() + rkInfo.Name.ToUTF8() + "." + rkInfo.Type.ToString()); Log::Error("Invalid resource path in asset name map: " + rkInfo.Directory + rkInfo.Name + "." + rkInfo.Type.ToString());
Iter = mMap.erase(Iter); Iter = mMap.erase(Iter);
FoundErrors = true; FoundErrors = true;
} }
@ -176,7 +176,7 @@ void CAssetNameMap::PostLoadValidate()
for (auto Iter = Dupes.begin(); Iter != Dupes.end(); Iter++) for (auto Iter = Dupes.begin(); Iter != Dupes.end(); Iter++)
{ {
const SAssetNameInfo& rkInfo = *Iter; const SAssetNameInfo& rkInfo = *Iter;
TString FullPath = rkInfo.FullPath().ToUTF8(); TString FullPath = rkInfo.FullPath();
Log::Error("\t" + FullPath); Log::Error("\t" + FullPath);
} }

View File

@ -15,13 +15,13 @@ class CAssetNameMap
{ {
struct SAssetNameInfo struct SAssetNameInfo
{ {
TWideString Name; TString Name;
TWideString Directory; TString Directory;
CFourCC Type; // This is mostly just needed to verify no name conflicts CFourCC Type; // This is mostly just needed to verify no name conflicts
TWideString FullPath() const TString FullPath() const
{ {
return Directory + Name + L'.' + Type.ToString().ToUTF16(); return Directory + Name + '.' + Type.ToString();
} }
void Serialize(IArchive& rArc) void Serialize(IArchive& rArc)

View File

@ -41,8 +41,8 @@ bool CGameExporter::Export(nod::DiscBase *pDisc, const TString& rkOutputDir, CAs
mpGameInfo = pGameInfo; mpGameInfo = pGameInfo;
mExportDir = FileUtil::MakeAbsolute(rkOutputDir); mExportDir = FileUtil::MakeAbsolute(rkOutputDir);
mDiscDir = L"Disc\\"; mDiscDir = "Disc\\";
mWorldsDirName = L"Worlds\\"; mWorldsDirName = "Worlds\\";
// Create project // Create project
FileUtil::MakeDirectory(mExportDir); FileUtil::MakeDirectory(mExportDir);
@ -98,7 +98,7 @@ bool CGameExporter::ExtractDiscData()
SCOPED_TIMER(ExtractDiscData); SCOPED_TIMER(ExtractDiscData);
// Create Disc output folder // Create Disc output folder
TWideString AbsDiscDir = mExportDir + mDiscDir; TString AbsDiscDir = mExportDir + mDiscDir;
FileUtil::MakeDirectory(AbsDiscDir); FileUtil::MakeDirectory(AbsDiscDir);
// Extract disc filesystem // Extract disc filesystem
@ -111,8 +111,8 @@ bool CGameExporter::ExtractDiscData()
if (!Success) return false; if (!Success) return false;
// Extract dol // Extract dol
mDolPath = L"boot.dol"; mDolPath = "boot.dol";
CFileOutStream DolFile(TWideString(mExportDir + mDolPath).ToUTF8().ToStdString()); CFileOutStream DolFile(mExportDir + mDolPath);
if (!DolFile.IsValid()) return false; if (!DolFile.IsValid()) return false;
std::unique_ptr<uint8_t[]> pDolBuffer = pDataPartition->getDOLBuf(); std::unique_ptr<uint8_t[]> pDolBuffer = pDataPartition->getDOLBuf();
@ -120,8 +120,8 @@ bool CGameExporter::ExtractDiscData()
DolFile.Close(); DolFile.Close();
// Extract apploader // Extract apploader
mApploaderPath = L"apploader.img"; mApploaderPath = "apploader.img";
CFileOutStream ApploaderFile(TWideString(mExportDir + mApploaderPath).ToUTF8().ToStdString()); CFileOutStream ApploaderFile(mExportDir + mApploaderPath);
if (!ApploaderFile.IsValid()) return false; if (!ApploaderFile.IsValid()) return false;
std::unique_ptr<uint8_t[]> pApploaderBuffer = pDataPartition->getApploaderBuf(); std::unique_ptr<uint8_t[]> pApploaderBuffer = pDataPartition->getApploaderBuf();
@ -134,9 +134,9 @@ bool CGameExporter::ExtractDiscData()
if (IsWii) if (IsWii)
{ {
mFilesystemAddress = 0; mFilesystemAddress = 0;
mPartitionHeaderPath = L"partition_header.bin"; mPartitionHeaderPath = "partition_header.bin";
nod::DiscWii *pDiscWii = static_cast<nod::DiscWii*>(mpDisc); nod::DiscWii *pDiscWii = static_cast<nod::DiscWii*>(mpDisc);
Success = pDiscWii->writeOutDataPartitionHeader(*(mExportDir + mPartitionHeaderPath)); Success = pDiscWii->writeOutDataPartitionHeader(*TString(mExportDir + mPartitionHeaderPath).ToUTF16());
if (!Success) return false; if (!Success) return false;
} }
else else
@ -145,23 +145,23 @@ bool CGameExporter::ExtractDiscData()
return true; return true;
} }
bool CGameExporter::ExtractDiscNodeRecursive(const nod::Node *pkNode, const TWideString& rkDir, const nod::ExtractionContext& rkContext) bool CGameExporter::ExtractDiscNodeRecursive(const nod::Node *pkNode, const TString& rkDir, const nod::ExtractionContext& rkContext)
{ {
for (nod::Node::DirectoryIterator Iter = pkNode->begin(); Iter != pkNode->end(); ++Iter) for (nod::Node::DirectoryIterator Iter = pkNode->begin(); Iter != pkNode->end(); ++Iter)
{ {
if (Iter->getKind() == nod::Node::Kind::File) if (Iter->getKind() == nod::Node::Kind::File)
{ {
TWideString FilePath = rkDir + TString(Iter->getName()).ToUTF16(); TString FilePath = rkDir + Iter->getName();
bool Success = Iter->extractToDirectory(*rkDir, rkContext); bool Success = Iter->extractToDirectory(*rkDir.ToUTF16(), rkContext);
if (!Success) return false; if (!Success) return false;
if (FilePath.GetFileExtension() == L"pak") if (FilePath.GetFileExtension() == "pak")
mPaks.push_back(FilePath); mPaks.push_back(FilePath);
} }
else else
{ {
TWideString Subdir = rkDir + TString(Iter->getName()).ToUTF16() + L"\\"; TString Subdir = rkDir + Iter->getName() + "\\";
bool Success = FileUtil::MakeDirectory(Subdir); bool Success = FileUtil::MakeDirectory(Subdir);
if (!Success) return false; if (!Success) return false;
@ -179,23 +179,22 @@ void CGameExporter::LoadPaks()
#if LOAD_PAKS #if LOAD_PAKS
SCOPED_TIMER(LoadPaks); SCOPED_TIMER(LoadPaks);
mPaks.sort([](const TWideString& rkLeft, const TWideString& rkRight) -> bool { mPaks.sort([](const TString& rkLeft, const TString& rkRight) -> bool {
return rkLeft.ToUpper() < rkRight.ToUpper(); return rkLeft.ToUpper() < rkRight.ToUpper();
}); });
for (auto It = mPaks.begin(); It != mPaks.end(); It++) for (auto It = mPaks.begin(); It != mPaks.end(); It++)
{ {
TWideString PakPath = *It; TString PakPath = *It;
TString CharPak = PakPath.ToUTF8(); CFileInStream Pak(PakPath, IOUtil::eBigEndian);
CFileInStream Pak(CharPak.ToStdString(), IOUtil::eBigEndian);
if (!Pak.IsValid()) if (!Pak.IsValid())
{ {
Log::Error("Couldn't open pak: " + CharPak); Log::Error("Couldn't open pak: " + PakPath);
continue; continue;
} }
CPackage *pPackage = new CPackage(mpProject, CharPak.GetFileName(false), FileUtil::MakeRelative(PakPath.GetFileDirectory(), mExportDir + mDiscDir)); CPackage *pPackage = new CPackage(mpProject, PakPath.GetFileName(false), FileUtil::MakeRelative(PakPath.GetFileDirectory(), mExportDir + mDiscDir));
// MP1-MP3Proto // MP1-MP3Proto
if (mGame < eCorruption) if (mGame < eCorruption)
@ -349,7 +348,7 @@ void CGameExporter::LoadPaks()
void CGameExporter::LoadResource(const SResourceInstance& rkResource, std::vector<u8>& rBuffer) void CGameExporter::LoadResource(const SResourceInstance& rkResource, std::vector<u8>& rBuffer)
{ {
CFileInStream Pak(rkResource.PakFile.ToUTF8().ToStdString(), IOUtil::eBigEndian); CFileInStream Pak(rkResource.PakFile, IOUtil::eBigEndian);
if (Pak.IsValid()) if (Pak.IsValid())
{ {
@ -533,9 +532,9 @@ void CGameExporter::ExportResource(SResourceInstance& rRes)
#if EXPORT_COOKED #if EXPORT_COOKED
// Save cooked asset // Save cooked asset
TWideString OutCookedPath = pEntry->CookedAssetPath(); TString OutCookedPath = pEntry->CookedAssetPath();
FileUtil::MakeDirectory(OutCookedPath.GetFileDirectory()); FileUtil::MakeDirectory(OutCookedPath.GetFileDirectory());
CFileOutStream Out(OutCookedPath.ToUTF8().ToStdString(), IOUtil::eBigEndian); CFileOutStream Out(OutCookedPath, IOUtil::eBigEndian);
if (Out.IsValid()) if (Out.IsValid())
Out.WriteBytes(ResourceData.data(), ResourceData.size()); Out.WriteBytes(ResourceData.data(), ResourceData.size());

View File

@ -16,38 +16,38 @@ class CGameExporter
{ {
// Project Data // Project Data
CGameProject *mpProject; CGameProject *mpProject;
TWideString mProjectPath; TString mProjectPath;
CResourceStore *mpStore; CResourceStore *mpStore;
EGame mGame; EGame mGame;
ERegion mRegion; ERegion mRegion;
TString mGameName; TString mGameName;
TString mGameID; TString mGameID;
float mBuildVersion; float mBuildVersion;
TWideString mDolPath; TString mDolPath;
TWideString mApploaderPath; TString mApploaderPath;
TWideString mPartitionHeaderPath; TString mPartitionHeaderPath;
u32 mFilesystemAddress; u32 mFilesystemAddress;
// Directories // Directories
TWideString mExportDir; TString mExportDir;
TWideString mDiscDir; TString mDiscDir;
TWideString mContentDir; TString mContentDir;
TWideString mCookedDir; TString mCookedDir;
TWideString mWorldsDirName; TString mWorldsDirName;
// Files // Files
nod::DiscBase *mpDisc; nod::DiscBase *mpDisc;
// Resources // Resources
TWideStringList mPaks; TStringList mPaks;
std::map<CAssetID, bool> mAreaDuplicateMap; std::map<CAssetID, bool> mAreaDuplicateMap;
CAssetNameMap *mpNameMap; CAssetNameMap *mpNameMap;
CGameInfo *mpGameInfo; CGameInfo *mpGameInfo;
struct SResourceInstance struct SResourceInstance
{ {
TWideString PakFile; TString PakFile;
CAssetID ResourceID; CAssetID ResourceID;
CFourCC ResourceType; CFourCC ResourceType;
u32 PakOffset; u32 PakOffset;
@ -62,11 +62,11 @@ public:
bool Export(nod::DiscBase *pDisc, const TString& rkOutputDir, CAssetNameMap *pNameMap, CGameInfo *pGameInfo); bool Export(nod::DiscBase *pDisc, const TString& rkOutputDir, CAssetNameMap *pNameMap, CGameInfo *pGameInfo);
void LoadResource(const CAssetID& rkID, std::vector<u8>& rBuffer); void LoadResource(const CAssetID& rkID, std::vector<u8>& rBuffer);
inline TWideString ProjectPath() const { return mProjectPath; } inline TString ProjectPath() const { return mProjectPath; }
protected: protected:
bool ExtractDiscData(); bool ExtractDiscData();
bool ExtractDiscNodeRecursive(const nod::Node *pkNode, const TWideString& rkDir, const nod::ExtractionContext& rkContext); bool ExtractDiscNodeRecursive(const nod::Node *pkNode, const TString& rkDir, const nod::ExtractionContext& rkContext);
void LoadPaks(); void LoadPaks();
void LoadResource(const SResourceInstance& rkResource, std::vector<u8>& rBuffer); void LoadResource(const SResourceInstance& rkResource, std::vector<u8>& rBuffer);
void ExportCookedResources(); void ExportCookedResources();

View File

@ -24,7 +24,7 @@ CGameProject::~CGameProject()
bool CGameProject::Save() bool CGameProject::Save()
{ {
mProjFileLock.Release(); mProjFileLock.Release();
TString ProjPath = ProjectPath().ToUTF8(); TString ProjPath = ProjectPath();
CXMLWriter Writer(ProjPath, "GameProject", eVer_Current, mGame); CXMLWriter Writer(ProjPath, "GameProject", eVer_Current, mGame);
Serialize(Writer); Serialize(Writer);
bool SaveSuccess = Writer.Save(); bool SaveSuccess = Writer.Save();
@ -55,7 +55,7 @@ void CGameProject::Serialize(IArchive& rArc)
if (!rArc.IsReader()) if (!rArc.IsReader())
{ {
for (u32 iPkg = 0; iPkg < mPackages.size(); iPkg++) for (u32 iPkg = 0; iPkg < mPackages.size(); iPkg++)
PackageList.push_back( mPackages[iPkg]->DefinitionPath(true).ToUTF8() ); PackageList.push_back( mPackages[iPkg]->DefinitionPath(true) );
} }
rArc << SERIAL_CONTAINER("Packages", PackageList, "Package"); rArc << SERIAL_CONTAINER("Packages", PackageList, "Package");
@ -76,9 +76,9 @@ void CGameProject::Serialize(IArchive& rArc)
for (u32 iPkg = 0; iPkg < PackageList.size(); iPkg++) for (u32 iPkg = 0; iPkg < PackageList.size(); iPkg++)
{ {
const TWideString& rkPackagePath = PackageList[iPkg]; const TString& rkPackagePath = PackageList[iPkg];
TString PackageName = TWideString(rkPackagePath.GetFileName(false)).ToUTF8(); TString PackageName = rkPackagePath.GetFileName(false);
TWideString PackageDir = rkPackagePath.GetFileDirectory(); TString PackageDir = rkPackagePath.GetFileDirectory();
CPackage *pPackage = new CPackage(this, PackageName, PackageDir); CPackage *pPackage = new CPackage(this, PackageName, PackageDir);
bool PackageLoadSuccess = pPackage->Load(); bool PackageLoadSuccess = pPackage->Load();
@ -144,14 +144,14 @@ CAssetID CGameProject::FindNamedResource(const TString& rkName) const
} }
CGameProject* CGameProject::CreateProjectForExport( CGameProject* CGameProject::CreateProjectForExport(
const TWideString& rkProjRootDir, const TString& rkProjRootDir,
EGame Game, EGame Game,
ERegion Region, ERegion Region,
const TString& rkGameID, const TString& rkGameID,
float BuildVer, float BuildVer,
const TWideString& rkDolPath, const TString& rkDolPath,
const TWideString& rkApploaderPath, const TString& rkApploaderPath,
const TWideString& rkPartitionHeaderPath, const TString& rkPartitionHeaderPath,
u32 FstAddress u32 FstAddress
) )
{ {
@ -166,20 +166,20 @@ CGameProject* CGameProject::CreateProjectForExport(
pProj->mFilesystemAddress = FstAddress; pProj->mFilesystemAddress = FstAddress;
pProj->mProjectRoot = rkProjRootDir; pProj->mProjectRoot = rkProjRootDir;
pProj->mProjectRoot.Replace(L"/", L"\\"); pProj->mProjectRoot.Replace("/", "\\");
pProj->mpResourceStore = new CResourceStore(pProj, L"Content\\", L"Cooked\\", Game); pProj->mpResourceStore = new CResourceStore(pProj, "Content\\", "Cooked\\", Game);
pProj->mpGameInfo->LoadGameInfo(Game); pProj->mpGameInfo->LoadGameInfo(Game);
pProj->mLoadSuccess = true; pProj->mLoadSuccess = true;
return pProj; return pProj;
} }
CGameProject* CGameProject::LoadProject(const TWideString& rkProjPath) CGameProject* CGameProject::LoadProject(const TString& rkProjPath)
{ {
CGameProject *pProj = new CGameProject; CGameProject *pProj = new CGameProject;
pProj->mProjectRoot = rkProjPath.GetFileDirectory(); pProj->mProjectRoot = rkProjPath.GetFileDirectory();
pProj->mProjectRoot.Replace(L"/", L"\\"); pProj->mProjectRoot.Replace("/", "\\");
TString ProjPath = rkProjPath.ToUTF8(); TString ProjPath = rkProjPath;
CXMLReader Reader(ProjPath); CXMLReader Reader(ProjPath);
if (!Reader.IsValid()) if (!Reader.IsValid())

View File

@ -20,13 +20,13 @@ class CGameProject
ERegion mRegion; ERegion mRegion;
TString mGameID; TString mGameID;
float mBuildVersion; float mBuildVersion;
TWideString mDolPath; TString mDolPath;
TWideString mApploaderPath; TString mApploaderPath;
TWideString mPartitionHeaderPath; TString mPartitionHeaderPath;
u32 mFilesystemAddress; u32 mFilesystemAddress;
TWideString mProjectRoot; TString mProjectRoot;
TWideString mResourceDBPath; TString mResourceDBPath;
std::vector<CPackage*> mPackages; std::vector<CPackage*> mPackages;
CResourceStore *mpResourceStore; CResourceStore *mpResourceStore;
CGameInfo *mpGameInfo; CGameInfo *mpGameInfo;
@ -52,7 +52,7 @@ class CGameProject
, mRegion(eRegion_Unknown) , mRegion(eRegion_Unknown)
, mGameID("000000") , mGameID("000000")
, mBuildVersion(0.f) , mBuildVersion(0.f)
, mResourceDBPath(L"ResourceDB.rdb") , mResourceDBPath("ResourceDB.rdb")
, mpResourceStore(nullptr) , mpResourceStore(nullptr)
, mLoadSuccess(true) , mLoadSuccess(true)
{ {
@ -70,27 +70,27 @@ public:
// Static // Static
static CGameProject* CreateProjectForExport( static CGameProject* CreateProjectForExport(
const TWideString& rkProjRootDir, const TString& rkProjRootDir,
EGame Game, EGame Game,
ERegion Region, ERegion Region,
const TString& rkGameID, const TString& rkGameID,
float BuildVer, float BuildVer,
const TWideString& rkDolPath, const TString& rkDolPath,
const TWideString& rkApploaderPath, const TString& rkApploaderPath,
const TWideString& rkPartitionHeaderPath, const TString& rkPartitionHeaderPath,
u32 FstAddress u32 FstAddress
); );
static CGameProject* LoadProject(const TWideString& rkProjPath); static CGameProject* LoadProject(const TString& rkProjPath);
// Directory Handling // Directory Handling
inline TWideString ProjectRoot() const { return mProjectRoot; } inline TString ProjectRoot() const { return mProjectRoot; }
inline TWideString ResourceDBPath(bool Relative) const { return Relative ? mResourceDBPath : mProjectRoot + mResourceDBPath; } inline TString ResourceDBPath(bool Relative) const { return Relative ? mResourceDBPath : mProjectRoot + mResourceDBPath; }
inline TWideString DiscDir(bool Relative) const { return Relative ? L"Disc\\" : mProjectRoot + L"Disc\\"; } inline TString DiscDir(bool Relative) const { return Relative ? "Disc\\" : mProjectRoot + "Disc\\"; }
inline TWideString CacheDir(bool Relative) const { return Relative ? L"Cache\\" : mProjectRoot + L"Cache\\"; } inline TString CacheDir(bool Relative) const { return Relative ? "Cache\\" : mProjectRoot + "Cache\\"; }
inline TWideString PackagesDir(bool Relative) const { return Relative ? L"Packages\\" : mProjectRoot + L"Packages\\"; } inline TString PackagesDir(bool Relative) const { return Relative ? "Packages\\" : mProjectRoot + "Packages\\"; }
inline TWideString ProjectPath() const { return mProjectRoot + FileUtil::SanitizeName(mProjectName.ToUTF16(), false) + L".prj"; } inline TString ProjectPath() const { return mProjectRoot + FileUtil::SanitizeName(mProjectName, false) + ".prj"; }
inline TWideString ResourceCachePath(bool Relative) const { return ResourceDBPath(Relative).GetFileDirectory() + L"ResourceCacheData.rcd"; } inline TString ResourceCachePath(bool Relative) const { return ResourceDBPath(Relative).GetFileDirectory() + "ResourceCacheData.rcd"; }
// Accessors // Accessors
inline void SetProjectName(const TString& rkName) { mProjectName = rkName; } inline void SetProjectName(const TString& rkName) { mProjectName = rkName; }

View File

@ -12,8 +12,8 @@ using namespace tinyxml2;
bool CPackage::Load() bool CPackage::Load()
{ {
TWideString DefPath = DefinitionPath(false); TString DefPath = DefinitionPath(false);
CXMLReader Reader(DefPath.ToUTF8()); CXMLReader Reader(DefPath);
if (Reader.IsValid()) if (Reader.IsValid())
{ {
@ -26,10 +26,10 @@ bool CPackage::Load()
bool CPackage::Save() bool CPackage::Save()
{ {
TWideString DefPath = DefinitionPath(false); TString DefPath = DefinitionPath(false);
FileUtil::MakeDirectory(DefPath.GetFileDirectory()); FileUtil::MakeDirectory(DefPath.GetFileDirectory());
CXMLWriter Writer(DefPath.ToUTF8(), "PackageDefinition", 0, mpProject ? mpProject->Game() : eUnknownGame); CXMLWriter Writer(DefPath, "PackageDefinition", 0, mpProject ? mpProject->Game() : eUnknownGame);
Serialize(Writer); Serialize(Writer);
return Writer.Save(); return Writer.Save();
} }
@ -68,12 +68,12 @@ void CPackage::Cook()
Log::Write(TString::FromInt32(AssetList.size(), 0, 10) + " assets in " + Name() + ".pak"); Log::Write(TString::FromInt32(AssetList.size(), 0, 10) + " assets in " + Name() + ".pak");
// Write new pak // Write new pak
TWideString PakPath = CookedPackagePath(false); TString PakPath = CookedPackagePath(false);
CFileOutStream Pak(PakPath.ToUTF8().ToStdString(), IOUtil::eBigEndian); CFileOutStream Pak(PakPath, IOUtil::eBigEndian);
if (!Pak.IsValid()) if (!Pak.IsValid())
{ {
Log::Error("Couldn't cook package " + CookedPackagePath(true).ToUTF8() + "; unable to open package for writing"); Log::Error("Couldn't cook package " + CookedPackagePath(true) + "; unable to open package for writing");
return; return;
} }
@ -89,8 +89,7 @@ void CPackage::Cook()
const SNamedResource& rkRes = *Iter; const SNamedResource& rkRes = *Iter;
rkRes.Type.Write(Pak); rkRes.Type.Write(Pak);
rkRes.ID.Write(Pak); rkRes.ID.Write(Pak);
Pak.WriteLong(rkRes.Name.Size()); Pak.WriteSizedString(rkRes.Name);
Pak.WriteString(rkRes.Name.ToStdString(), rkRes.Name.Size()); // Note: Explicitly specifying size means we don't write the terminating 0
} }
// Fill in table of contents with junk, write later // Fill in table of contents with junk, write later
@ -132,7 +131,7 @@ void CPackage::Cook()
rTocInfo.Offset = Pak.Tell(); rTocInfo.Offset = Pak.Tell();
// Load resource data // Load resource data
CFileInStream CookedAsset(pEntry->CookedAssetPath().ToStdString(), IOUtil::eBigEndian); CFileInStream CookedAsset(pEntry->CookedAssetPath(), IOUtil::eBigEndian);
ASSERT(CookedAsset.IsValid()); ASSERT(CookedAsset.IsValid());
u32 ResourceSize = CookedAsset.Size(); u32 ResourceSize = CookedAsset.Size();
@ -211,7 +210,7 @@ void CPackage::Cook()
mNeedsRecook = false; mNeedsRecook = false;
Save(); Save();
Log::Write("Finished writing " + PakPath.ToUTF8()); Log::Write("Finished writing " + PakPath);
// Update resource store in case we recooked any assets // Update resource store in case we recooked any assets
mpProject->ResourceStore()->ConditionalSaveStore(); mpProject->ResourceStore()->ConditionalSaveStore();
@ -228,8 +227,8 @@ void CPackage::CompareOriginalAssetList(const std::list<CAssetID>& rkNewList)
NewListSet.insert(*Iter); NewListSet.insert(*Iter);
// Read the original pak // Read the original pak
TWideString CookedPath = CookedPackagePath(false); TString CookedPath = CookedPackagePath(false);
CFileInStream Pak(CookedPath.ToUTF8().ToStdString(), IOUtil::eBigEndian); CFileInStream Pak(CookedPath, IOUtil::eBigEndian);
if (!Pak.IsValid() || Pak.Size() == 0) if (!Pak.IsValid() || Pak.Size() == 0)
{ {
@ -296,14 +295,14 @@ bool CPackage::ContainsAsset(const CAssetID& rkID) const
return mCachedDependencies.find(rkID) != mCachedDependencies.end(); return mCachedDependencies.find(rkID) != mCachedDependencies.end();
} }
TWideString CPackage::DefinitionPath(bool Relative) const TString CPackage::DefinitionPath(bool Relative) const
{ {
TWideString RelPath = mPakPath + mPakName.ToUTF16() + L".pkd"; TString RelPath = mPakPath + mPakName + ".pkd";
return Relative ? RelPath : mpProject->PackagesDir(false) + RelPath; return Relative ? RelPath : mpProject->PackagesDir(false) + RelPath;
} }
TWideString CPackage::CookedPackagePath(bool Relative) const TString CPackage::CookedPackagePath(bool Relative) const
{ {
TWideString RelPath = mPakPath + mPakName.ToUTF16() + L".pak"; TString RelPath = mPakPath + mPakName + ".pak";
return Relative ? RelPath : mpProject->DiscDir(false) + RelPath; return Relative ? RelPath : mpProject->DiscDir(false) + RelPath;
} }

View File

@ -24,7 +24,7 @@ class CPackage
{ {
CGameProject *mpProject; CGameProject *mpProject;
TString mPakName; TString mPakName;
TWideString mPakPath; TString mPakPath;
std::vector<SNamedResource> mResources; std::vector<SNamedResource> mResources;
bool mNeedsRecook; bool mNeedsRecook;
@ -43,7 +43,7 @@ class CPackage
public: public:
CPackage() {} CPackage() {}
CPackage(CGameProject *pProj, const TString& rkName, const TWideString& rkPath) CPackage(CGameProject *pProj, const TString& rkName, const TString& rkPath)
: mpProject(pProj) : mpProject(pProj)
, mPakName(rkName) , mPakName(rkName)
, mPakPath(rkPath) , mPakPath(rkPath)
@ -61,12 +61,12 @@ public:
void CompareOriginalAssetList(const std::list<CAssetID>& rkNewList); void CompareOriginalAssetList(const std::list<CAssetID>& rkNewList);
bool ContainsAsset(const CAssetID& rkID) const; bool ContainsAsset(const CAssetID& rkID) const;
TWideString DefinitionPath(bool Relative) const; TString DefinitionPath(bool Relative) const;
TWideString CookedPackagePath(bool Relative) const; TString CookedPackagePath(bool Relative) const;
// Accessors // Accessors
inline TString Name() const { return mPakName; } inline TString Name() const { return mPakName; }
inline TWideString Path() const { return mPakPath; } inline TString Path() const { return mPakPath; }
inline CGameProject* Project() const { return mpProject; } inline CGameProject* Project() const { return mpProject; }
inline u32 NumNamedResources() const { return mResources.size(); } inline u32 NumNamedResources() const { return mResources.size(); }
inline const SNamedResource& NamedResourceByIndex(u32 Idx) const { return mResources[Idx]; } inline const SNamedResource& NamedResourceByIndex(u32 Idx) const { return mResources[Idx]; }

View File

@ -11,7 +11,7 @@
#include <Common/Serialization/CXMLWriter.h> #include <Common/Serialization/CXMLWriter.h>
CResourceEntry::CResourceEntry(CResourceStore *pStore, const CAssetID& rkID, CResourceEntry::CResourceEntry(CResourceStore *pStore, const CAssetID& rkID,
const TWideString& rkDir, const TWideString& rkFilename, const TString& rkDir, const TString& rkFilename,
EResType Type, bool Transient /*= false*/) EResType Type, bool Transient /*= false*/)
: mpResource(nullptr) : mpResource(nullptr)
, mpStore(pStore) , mpStore(pStore)
@ -28,7 +28,7 @@ CResourceEntry::CResourceEntry(CResourceStore *pStore, const CAssetID& rkID,
if (Transient) mFlags |= eREF_Transient; if (Transient) mFlags |= eREF_Transient;
mpDirectory = mpStore->GetVirtualDirectory(rkDir, Transient, true); mpDirectory = mpStore->GetVirtualDirectory(rkDir, Transient, true);
if (mpDirectory) mpDirectory->AddChild(L"", this); if (mpDirectory) mpDirectory->AddChild("", this);
} }
CResourceEntry::~CResourceEntry() CResourceEntry::~CResourceEntry()
@ -96,9 +96,9 @@ bool CResourceEntry::HasCookedVersion() const
TString CResourceEntry::RawAssetPath(bool Relative) const TString CResourceEntry::RawAssetPath(bool Relative) const
{ {
TWideString Ext = RawExtension().ToUTF16(); TString Ext = RawExtension();
TWideString Path = mpDirectory ? mpDirectory->FullPath() : L""; TString Path = mpDirectory ? mpDirectory->FullPath() : "";
TWideString Name = mName + L"." + Ext; TString Name = mName + "." + Ext;
return ((IsTransient() || Relative) ? Path + Name : mpStore->RawDir(false) + Path + Name); return ((IsTransient() || Relative) ? Path + Name : mpStore->RawDir(false) + Path + Name);
} }
@ -109,9 +109,9 @@ TString CResourceEntry::RawExtension() const
TString CResourceEntry::CookedAssetPath(bool Relative) const TString CResourceEntry::CookedAssetPath(bool Relative) const
{ {
TWideString Ext = CookedExtension().ToString().ToUTF16(); TString Ext = CookedExtension().ToString();
TWideString Path = mpDirectory ? mpDirectory->FullPath() : L""; TString Path = mpDirectory ? mpDirectory->FullPath() : "";
TWideString Name = mName + L"." + Ext; TString Name = mName + "." + Ext;
return ((IsTransient() || Relative) ? Path + Name : mpStore->CookedDir(false) + Path + Name); return ((IsTransient() || Relative) ? Path + Name : mpStore->CookedDir(false) + Path + Name);
} }
@ -180,7 +180,7 @@ bool CResourceEntry::Save(bool SkipCacheSave /*= false*/)
// Note: We call Serialize directly for resources to avoid having a redundant resource root node in the output file. // Note: We call Serialize directly for resources to avoid having a redundant resource root node in the output file.
TString Path = RawAssetPath(); TString Path = RawAssetPath();
TString Dir = Path.GetFileDirectory(); TString Dir = Path.GetFileDirectory();
FileUtil::MakeDirectory(Dir.ToUTF16()); FileUtil::MakeDirectory(Dir);
TString SerialName = mpTypeInfo->TypeName(); TString SerialName = mpTypeInfo->TypeName();
SerialName.RemoveWhitespace(); SerialName.RemoveWhitespace();
@ -205,7 +205,7 @@ bool CResourceEntry::Save(bool SkipCacheSave /*= false*/)
if (!CookSuccess) if (!CookSuccess)
{ {
Log::Error("Failed to save resource: " + Name().ToUTF8() + "." + CookedExtension().ToString()); Log::Error("Failed to save resource: " + Name() + "." + CookedExtension().ToString());
return false; return false;
} }
} }
@ -246,7 +246,7 @@ bool CResourceEntry::Cook()
FileUtil::MakeDirectory(Dir); FileUtil::MakeDirectory(Dir);
// Attempt to open output cooked file // Attempt to open output cooked file
CFileOutStream File(Path.ToStdString(), IOUtil::eBigEndian); CFileOutStream File(Path, IOUtil::eBigEndian);
if (!File.IsValid()) if (!File.IsValid())
{ {
Log::Error("Failed to open cooked file for writing: " + Path); Log::Error("Failed to open cooked file for writing: " + Path);
@ -306,7 +306,7 @@ CResource* CResourceEntry::Load()
ASSERT(!mpResource); ASSERT(!mpResource);
if (HasCookedVersion()) if (HasCookedVersion())
{ {
CFileInStream File(CookedAssetPath().ToStdString(), IOUtil::eBigEndian); CFileInStream File(CookedAssetPath(), IOUtil::eBigEndian);
if (!File.IsValid()) if (!File.IsValid())
{ {
@ -351,7 +351,7 @@ bool CResourceEntry::Unload()
return true; return true;
} }
bool CResourceEntry::CanMoveTo(const TWideString& rkDir, const TWideString& rkName) bool CResourceEntry::CanMoveTo(const TString& rkDir, const TString& rkName)
{ {
// Transient resources can't be moved // Transient resources can't be moved
if (IsTransient()) return false; if (IsTransient()) return false;
@ -367,13 +367,13 @@ bool CResourceEntry::CanMoveTo(const TWideString& rkDir, const TWideString& rkNa
return true; return true;
} }
bool CResourceEntry::Move(const TWideString& rkDir, const TWideString& rkName) bool CResourceEntry::Move(const TString& rkDir, const TString& rkName)
{ {
if (!CanMoveTo(rkDir, rkName)) return false; if (!CanMoveTo(rkDir, rkName)) return false;
// Store old paths // Store old paths
CVirtualDirectory *pOldDir = mpDirectory; CVirtualDirectory *pOldDir = mpDirectory;
TWideString OldName = mName; TString OldName = mName;
TString OldCookedPath = CookedAssetPath(); TString OldCookedPath = CookedAssetPath();
TString OldRawPath = RawAssetPath(); TString OldRawPath = RawAssetPath();
@ -389,7 +389,7 @@ bool CResourceEntry::Move(const TWideString& rkDir, const TWideString& rkName)
TString NewCookedPath = CookedAssetPath(); TString NewCookedPath = CookedAssetPath();
TString NewRawPath = RawAssetPath(); TString NewRawPath = RawAssetPath();
Log::Write("MOVING RESOURCE: " + FileUtil::MakeRelative(OldCookedPath, mpStore->CookedDir(false)).ToUTF8() + " --> " + FileUtil::MakeRelative(NewCookedPath, mpStore->CookedDir(false)).ToUTF8()); Log::Write("MOVING RESOURCE: " + FileUtil::MakeRelative(OldCookedPath, mpStore->CookedDir(false)) + " --> " + FileUtil::MakeRelative(NewCookedPath, mpStore->CookedDir(false)));
// If the old/new paths are the same then we should have already exited as CanMoveTo() should have returned false // If the old/new paths are the same then we should have already exited as CanMoveTo() should have returned false
ASSERT(OldCookedPath != NewCookedPath && OldRawPath != NewRawPath); ASSERT(OldCookedPath != NewCookedPath && OldRawPath != NewRawPath);
@ -437,7 +437,7 @@ bool CResourceEntry::Move(const TWideString& rkDir, const TWideString& rkName)
{ {
FSMoveSuccess = pOldDir->RemoveChildResource(this); FSMoveSuccess = pOldDir->RemoveChildResource(this);
ASSERT(FSMoveSuccess == true); // this shouldn't be able to fail ASSERT(FSMoveSuccess == true); // this shouldn't be able to fail
mpDirectory->AddChild(L"", this); mpDirectory->AddChild("", this);
mpStore->ConditionalDeleteDirectory(pOldDir); mpStore->ConditionalDeleteDirectory(pOldDir);
} }
@ -459,7 +459,7 @@ bool CResourceEntry::Move(const TWideString& rkDir, const TWideString& rkName)
} }
} }
void CResourceEntry::AddToProject(const TWideString& rkDir, const TWideString& rkName) void CResourceEntry::AddToProject(const TString& rkDir, const TString& rkName)
{ {
if (mFlags.HasFlag(eREF_Transient)) if (mFlags.HasFlag(eREF_Transient))
{ {

View File

@ -34,15 +34,15 @@ class CResourceEntry
CDependencyTree *mpDependencies; CDependencyTree *mpDependencies;
CAssetID mID; CAssetID mID;
CVirtualDirectory *mpDirectory; CVirtualDirectory *mpDirectory;
TWideString mName; TString mName;
FResEntryFlags mFlags; FResEntryFlags mFlags;
mutable u64 mCachedSize; mutable u64 mCachedSize;
mutable TWideString mCachedUppercaseName; // This is used to speed up case-insensitive sorting and filtering. mutable TString mCachedUppercaseName; // This is used to speed up case-insensitive sorting and filtering.
public: public:
CResourceEntry(CResourceStore *pStore, const CAssetID& rkID, CResourceEntry(CResourceStore *pStore, const CAssetID& rkID,
const TWideString& rkDir, const TWideString& rkFilename, const TString& rkDir, const TString& rkFilename,
EResType Type, bool Transient = false); EResType Type, bool Transient = false);
~CResourceEntry(); ~CResourceEntry();
@ -63,32 +63,32 @@ public:
CResource* Load(); CResource* Load();
CResource* LoadCooked(IInputStream& rInput); CResource* LoadCooked(IInputStream& rInput);
bool Unload(); bool Unload();
bool CanMoveTo(const TWideString& rkDir, const TWideString& rkName); bool CanMoveTo(const TString& rkDir, const TString& rkName);
bool Move(const TWideString& rkDir, const TWideString& rkName); bool Move(const TString& rkDir, const TString& rkName);
void AddToProject(const TWideString& rkDir, const TWideString& rkName); void AddToProject(const TString& rkDir, const TString& rkName);
void RemoveFromProject(); void RemoveFromProject();
CGameProject* Project() const; CGameProject* Project() const;
EGame Game() const; EGame Game() const;
// Accessors // Accessors
void SetDirty() { mFlags.SetFlag(eREF_NeedsRecook); } void SetDirty() { mFlags.SetFlag(eREF_NeedsRecook); }
void SetHidden(bool Hidden) { Hidden ? mFlags.SetFlag(eREF_Hidden) : mFlags.ClearFlag(eREF_Hidden); } void SetHidden(bool Hidden) { Hidden ? mFlags.SetFlag(eREF_Hidden) : mFlags.ClearFlag(eREF_Hidden); }
inline bool IsLoaded() const { return mpResource != nullptr; } inline bool IsLoaded() const { return mpResource != nullptr; }
inline bool IsCategorized() const { return mpDirectory && mpDirectory->FullPath() != L"Uncategorized\\"; } inline bool IsCategorized() const { return mpDirectory && mpDirectory->FullPath() != "Uncategorized\\"; }
inline bool IsNamed() const { return mName != mID.ToString().ToUTF16(); } inline bool IsNamed() const { return mName != mID.ToString(); }
inline CResource* Resource() const { return mpResource; } inline CResource* Resource() const { return mpResource; }
inline CResTypeInfo* TypeInfo() const { return mpTypeInfo; } inline CResTypeInfo* TypeInfo() const { return mpTypeInfo; }
inline CResourceStore* ResourceStore() const { return mpStore; } inline CResourceStore* ResourceStore() const { return mpStore; }
inline CDependencyTree* Dependencies() const { return mpDependencies; } inline CDependencyTree* Dependencies() const { return mpDependencies; }
inline CAssetID ID() const { return mID; } inline CAssetID ID() const { return mID; }
inline CVirtualDirectory* Directory() const { return mpDirectory; } inline CVirtualDirectory* Directory() const { return mpDirectory; }
inline TWideString DirectoryPath() const { return mpDirectory->FullPath(); } inline TString DirectoryPath() const { return mpDirectory->FullPath(); }
inline TWideString Name() const { return mName; } inline TString Name() const { return mName; }
inline const TWideString& UppercaseName() const { return mCachedUppercaseName; } inline const TString& UppercaseName() const { return mCachedUppercaseName; }
inline EResType ResourceType() const { return mpTypeInfo->Type(); } inline EResType ResourceType() const { return mpTypeInfo->Type(); }
inline bool IsTransient() const { return mFlags.HasFlag(eREF_Transient); } inline bool IsTransient() const { return mFlags.HasFlag(eREF_Transient); }
inline bool IsHidden() const { return mFlags.HasFlag(eREF_Hidden); } inline bool IsHidden() const { return mFlags.HasFlag(eREF_Hidden); }
protected: protected:
CResource* InternalLoad(IInputStream& rInput); CResource* InternalLoad(IInputStream& rInput);

View File

@ -15,7 +15,7 @@ CResourceStore *gpResourceStore = nullptr;
CResourceStore *gpEditorStore = nullptr; CResourceStore *gpEditorStore = nullptr;
// Constructor for editor store // Constructor for editor store
CResourceStore::CResourceStore(const TWideString& rkDatabasePath) CResourceStore::CResourceStore(const TString& rkDatabasePath)
: mpProj(nullptr) : mpProj(nullptr)
, mGame(eUnknownGame) , mGame(eUnknownGame)
, mDatabaseDirty(false) , mDatabaseDirty(false)
@ -27,7 +27,7 @@ CResourceStore::CResourceStore(const TWideString& rkDatabasePath)
} }
// Constructor for game exporter // Constructor for game exporter
CResourceStore::CResourceStore(CGameProject *pProject, const TWideString& rkRawDir, const TWideString& rkCookedDir, EGame Game) CResourceStore::CResourceStore(CGameProject *pProject, const TString& rkRawDir, const TString& rkCookedDir, EGame Game)
: mpProj(nullptr) : mpProj(nullptr)
, mGame(Game) , mGame(Game)
, mRawDir(rkRawDir) , mRawDir(rkRawDir)
@ -67,8 +67,8 @@ void CResourceStore::SerializeResourceDatabase(IArchive& rArc)
{ {
CAssetID ID; CAssetID ID;
CResTypeInfo *pType; CResTypeInfo *pType;
TWideString Directory; TString Directory;
TWideString Name; TString Name;
void Serialize(IArchive& rArc) void Serialize(IArchive& rArc)
{ {
@ -108,7 +108,7 @@ void CResourceStore::SerializeResourceDatabase(IArchive& rArc)
bool CResourceStore::LoadResourceDatabase() bool CResourceStore::LoadResourceDatabase()
{ {
ASSERT(!mDatabasePath.IsEmpty()); ASSERT(!mDatabasePath.IsEmpty());
TString Path = DatabasePath().ToUTF8(); TString Path = DatabasePath();
if (!mpDatabaseRoot) if (!mpDatabaseRoot)
mpDatabaseRoot = new CVirtualDirectory(this); mpDatabaseRoot = new CVirtualDirectory(this);
@ -131,7 +131,7 @@ bool CResourceStore::LoadResourceDatabase()
bool CResourceStore::SaveResourceDatabase() bool CResourceStore::SaveResourceDatabase()
{ {
TString Path = DatabasePath().ToUTF8(); TString Path = DatabasePath();
CXMLWriter Writer(Path, "ResourceDB", 0, mGame); CXMLWriter Writer(Path, "ResourceDB", 0, mGame);
SerializeResourceDatabase(Writer); SerializeResourceDatabase(Writer);
bool SaveSuccess = Writer.Save(); bool SaveSuccess = Writer.Save();
@ -146,8 +146,8 @@ bool CResourceStore::SaveResourceDatabase()
bool CResourceStore::LoadCacheFile() bool CResourceStore::LoadCacheFile()
{ {
TString CachePath = CacheDataPath().ToUTF8(); TString CachePath = CacheDataPath();
CFileInStream CacheFile(CachePath.ToStdString(), IOUtil::eBigEndian); CFileInStream CacheFile(CachePath, IOUtil::eBigEndian);
if (!CacheFile.IsValid()) if (!CacheFile.IsValid())
{ {
@ -193,8 +193,8 @@ bool CResourceStore::LoadCacheFile()
bool CResourceStore::SaveCacheFile() bool CResourceStore::SaveCacheFile()
{ {
TString CachePath = CacheDataPath().ToUTF8(); TString CachePath = CacheDataPath();
CFileOutStream CacheFile(CachePath.ToStdString(), IOUtil::eBigEndian); CFileOutStream CacheFile(CachePath, IOUtil::eBigEndian);
if (!CacheFile.IsValid()) if (!CacheFile.IsValid())
{ {
@ -260,7 +260,7 @@ void CResourceStore::SetProject(CGameProject *pProj)
if (mpProj) if (mpProj)
{ {
TWideString DatabasePath = mpProj->ResourceDBPath(false); TString DatabasePath = mpProj->ResourceDBPath(false);
mDatabasePath = DatabasePath.GetFileDirectory(); mDatabasePath = DatabasePath.GetFileDirectory();
mDatabaseName = DatabasePath.GetFileName(); mDatabaseName = DatabasePath.GetFileName();
mpDatabaseRoot = new CVirtualDirectory(this); mpDatabaseRoot = new CVirtualDirectory(this);
@ -283,7 +283,7 @@ void CResourceStore::CloseProject()
for (auto Iter = mLoadedResources.begin(); Iter != mLoadedResources.end(); Iter++) for (auto Iter = mLoadedResources.begin(); Iter != mLoadedResources.end(); Iter++)
{ {
CResourceEntry *pEntry = Iter->second; CResourceEntry *pEntry = Iter->second;
Log::Write("\t" + pEntry->Name().ToUTF8() + "." + pEntry->CookedExtension().ToString()); Log::Write("\t" + pEntry->Name() + "." + pEntry->CookedExtension().ToString());
} }
ASSERT(false); ASSERT(false);
@ -312,7 +312,7 @@ void CResourceStore::CloseProject()
mGame = eUnknownGame; mGame = eUnknownGame;
} }
CVirtualDirectory* CResourceStore::GetVirtualDirectory(const TWideString& rkPath, bool Transient, bool AllowCreate) CVirtualDirectory* CResourceStore::GetVirtualDirectory(const TString& rkPath, bool Transient, bool AllowCreate)
{ {
if (rkPath.IsEmpty()) return mpDatabaseRoot; if (rkPath.IsEmpty()) return mpDatabaseRoot;
@ -367,7 +367,7 @@ CResourceEntry* CResourceStore::FindEntry(const CAssetID& rkID) const
else return Found->second; else return Found->second;
} }
CResourceEntry* CResourceStore::FindEntry(const TWideString& rkPath) const CResourceEntry* CResourceStore::FindEntry(const TString& rkPath) const
{ {
return (mpDatabaseRoot ? mpDatabaseRoot->FindChildResource(rkPath) : nullptr); return (mpDatabaseRoot ? mpDatabaseRoot->FindChildResource(rkPath) : nullptr);
} }
@ -377,7 +377,7 @@ bool CResourceStore::IsResourceRegistered(const CAssetID& rkID) const
return FindEntry(rkID) != nullptr; return FindEntry(rkID) != nullptr;
} }
CResourceEntry* CResourceStore::RegisterResource(const CAssetID& rkID, EResType Type, const TWideString& rkDir, const TWideString& rkName) CResourceEntry* CResourceStore::RegisterResource(const CAssetID& rkID, EResType Type, const TString& rkDir, const TString& rkName)
{ {
CResourceEntry *pEntry = FindEntry(rkID); CResourceEntry *pEntry = FindEntry(rkID);
@ -390,7 +390,7 @@ CResourceEntry* CResourceStore::RegisterResource(const CAssetID& rkID, EResType
} }
else else
Log::Error("Attempted to register resource that's already tracked in the database: " + rkID.ToString() + " / " + rkDir.ToUTF8() + " / " + rkName.ToUTF8()); Log::Error("Attempted to register resource that's already tracked in the database: " + rkID.ToString() + " / " + rkDir + " / " + rkName);
} }
else else
@ -403,20 +403,20 @@ CResourceEntry* CResourceStore::RegisterResource(const CAssetID& rkID, EResType
} }
else else
Log::Error("Invalid resource path, failed to register: " + rkDir.ToUTF8() + rkName.ToUTF8()); Log::Error("Invalid resource path, failed to register: " + rkDir + rkName);
} }
return pEntry; return pEntry;
} }
CResourceEntry* CResourceStore::RegisterTransientResource(EResType Type, const TWideString& rkDir /*= L""*/, const TWideString& rkFileName /*= L""*/) CResourceEntry* CResourceStore::RegisterTransientResource(EResType Type, const TString& rkDir /*= ""*/, const TString& rkFileName /*= ""*/)
{ {
CResourceEntry *pEntry = new CResourceEntry(this, CAssetID::RandomID(), rkDir, rkFileName, Type, true); CResourceEntry *pEntry = new CResourceEntry(this, CAssetID::RandomID(), rkDir, rkFileName, Type, true);
mResourceEntries[pEntry->ID()] = pEntry; mResourceEntries[pEntry->ID()] = pEntry;
return pEntry; return pEntry;
} }
CResourceEntry* CResourceStore::RegisterTransientResource(EResType Type, const CAssetID& rkID, const TWideString& rkDir /*=L ""*/, const TWideString& rkFileName /*= L""*/) CResourceEntry* CResourceStore::RegisterTransientResource(EResType Type, const CAssetID& rkID, const TString& rkDir /*=L ""*/, const TString& rkFileName /*= ""*/)
{ {
CResourceEntry *pEntry = FindEntry(rkID); CResourceEntry *pEntry = FindEntry(rkID);
@ -450,10 +450,10 @@ CResource* CResourceStore::LoadResource(const CAssetID& rkID, const CFourCC& rkT
// Note the entry may not be able to find the resource on its own (due to not knowing what game // Note the entry may not be able to find the resource on its own (due to not knowing what game
// it is) so we will attempt to open the file stream ourselves and pass it to the entry instead. // it is) so we will attempt to open the file stream ourselves and pass it to the entry instead.
TString Name = rkID.ToString(); TString Name = rkID.ToString();
CResourceEntry *pEntry = RegisterTransientResource(Type, mTransientLoadDir, Name.ToUTF16()); CResourceEntry *pEntry = RegisterTransientResource(Type, mTransientLoadDir, Name);
TString Path = mTransientLoadDir.ToUTF8() + Name + "." + rkType.ToString(); TString Path = mTransientLoadDir + Name + "." + rkType.ToString();
CFileInStream File(Path.ToStdString(), IOUtil::eBigEndian); CFileInStream File(Path, IOUtil::eBigEndian);
CResource *pRes = pEntry->LoadCooked(File); CResource *pRes = pEntry->LoadCooked(File);
if (!pRes) DeleteResourceEntry(pEntry); if (!pRes) DeleteResourceEntry(pEntry);
@ -467,7 +467,7 @@ CResource* CResourceStore::LoadResource(const CAssetID& rkID, const CFourCC& rkT
} }
} }
CResource* CResourceStore::LoadResource(const TWideString& rkPath) CResource* CResourceStore::LoadResource(const TString& rkPath)
{ {
// If this is a relative path then load via the resource DB // If this is a relative path then load via the resource DB
if (!FileUtil::IsAbsolute(rkPath)) if (!FileUtil::IsAbsolute(rkPath))
@ -477,7 +477,7 @@ CResource* CResourceStore::LoadResource(const TWideString& rkPath)
if (pEntry) if (pEntry)
{ {
// Verify extension matches the entry + load resource // Verify extension matches the entry + load resource
TString Ext = rkPath.ToUTF8().GetFileExtension(); TString Ext = rkPath.GetFileExtension();
if (!Ext.IsEmpty()) if (!Ext.IsEmpty())
{ {
@ -498,7 +498,7 @@ CResource* CResourceStore::LoadResource(const TWideString& rkPath)
} }
// Otherwise create transient entry; construct ID from string, check if resource is loaded already // Otherwise create transient entry; construct ID from string, check if resource is loaded already
TWideString Dir = FileUtil::MakeAbsolute(TWideString(rkPath.GetFileDirectory())); TString Dir = FileUtil::MakeAbsolute(rkPath.GetFileDirectory());
TString Name = rkPath.GetFileName(false); TString Name = rkPath.GetFileName(false);
CAssetID ID = (Name.IsHexString() ? Name.ToInt64() : rkPath.Hash64()); CAssetID ID = (Name.IsHexString() ? Name.ToInt64() : rkPath.Hash64());
auto Find = mLoadedResources.find(ID); auto Find = mLoadedResources.find(ID);
@ -507,22 +507,21 @@ CResource* CResourceStore::LoadResource(const TWideString& rkPath)
return Find->second->Resource(); return Find->second->Resource();
// Determine type // Determine type
TString PathUTF8 = rkPath.ToUTF8(); TString Extension = rkPath.GetFileExtension().ToUpper();
TString Extension = TString(PathUTF8).GetFileExtension().ToUpper();
EResType Type = CResTypeInfo::TypeForCookedExtension(mGame, Extension)->Type(); EResType Type = CResTypeInfo::TypeForCookedExtension(mGame, Extension)->Type();
if (Type == eInvalidResType) if (Type == eInvalidResType)
{ {
Log::Error("Unable to load resource " + PathUTF8 + "; unrecognized extension: " + Extension); Log::Error("Unable to load resource " + rkPath + "; unrecognized extension: " + Extension);
return nullptr; return nullptr;
} }
// Open file // Open file
CFileInStream File(PathUTF8.ToStdString(), IOUtil::eBigEndian); CFileInStream File(rkPath, IOUtil::eBigEndian);
if (!File.IsValid()) if (!File.IsValid())
{ {
Log::Error("Unable to load resource; couldn't open file: " + PathUTF8); Log::Error("Unable to load resource; couldn't open file: " + rkPath);
return nullptr; return nullptr;
} }
@ -683,9 +682,9 @@ void CResourceStore::ImportNamesFromPakContentsTxt(const TString& rkTxtPath, boo
CResourceEntry *pEntry = Iter->first; CResourceEntry *pEntry = Iter->first;
if (UnnamedOnly && pEntry->IsNamed()) continue; if (UnnamedOnly && pEntry->IsNamed()) continue;
TWideString Path = Iter->second.ToUTF16(); TString Path = Iter->second;
TWideString Dir = Path.GetFileDirectory(); TString Dir = Path.GetFileDirectory();
TWideString Name = Path.GetFileName(false); TString Name = Path.GetFileName(false);
if (Dir.IsEmpty()) Dir = pEntry->DirectoryPath(); if (Dir.IsEmpty()) Dir = pEntry->DirectoryPath();
pEntry->Move(Dir, Name); pEntry->Move(Dir, Name);
@ -695,12 +694,12 @@ void CResourceStore::ImportNamesFromPakContentsTxt(const TString& rkTxtPath, boo
ConditionalSaveStore(); ConditionalSaveStore();
} }
bool CResourceStore::IsValidResourcePath(const TWideString& rkPath, const TWideString& rkName) bool CResourceStore::IsValidResourcePath(const TString& rkPath, const TString& rkName)
{ {
// Path must not be an absolute path and must not go outside the project structure. // Path must not be an absolute path and must not go outside the project structure.
// Name must not be a path. // Name must not be a path.
return ( CVirtualDirectory::IsValidDirectoryPath(rkPath) && return ( CVirtualDirectory::IsValidDirectoryPath(rkPath) &&
FileUtil::IsValidName(rkName, false) && FileUtil::IsValidName(rkName, false) &&
!rkName.Contains(L'/') && !rkName.Contains('/') &&
!rkName.Contains(L'\\') ); !rkName.Contains('\\') );
} }

View File

@ -29,11 +29,11 @@ class CResourceStore
bool mCacheFileDirty; bool mCacheFileDirty;
// Directory paths // Directory paths
TWideString mDatabasePath; TString mDatabasePath;
TWideString mDatabaseName; TString mDatabaseName;
TWideString mRawDir; TString mRawDir;
TWideString mCookedDir; TString mCookedDir;
TWideString mTransientLoadDir; TString mTransientLoadDir;
enum EDatabaseVersion enum EDatabaseVersion
{ {
@ -44,8 +44,8 @@ class CResourceStore
}; };
public: public:
CResourceStore(const TWideString& rkDatabasePath); CResourceStore(const TString& rkDatabasePath);
CResourceStore(CGameProject *pProject, const TWideString& rkRawDir, const TWideString& rkCookedDir, EGame Game); CResourceStore(CGameProject *pProject, const TString& rkRawDir, const TString& rkCookedDir, EGame Game);
CResourceStore(CGameProject *pProject); CResourceStore(CGameProject *pProject);
~CResourceStore(); ~CResourceStore();
void SerializeResourceDatabase(IArchive& rArc); void SerializeResourceDatabase(IArchive& rArc);
@ -56,18 +56,18 @@ public:
void ConditionalSaveStore(); void ConditionalSaveStore();
void SetProject(CGameProject *pProj); void SetProject(CGameProject *pProj);
void CloseProject(); void CloseProject();
CVirtualDirectory* GetVirtualDirectory(const TWideString& rkPath, bool Transient, bool AllowCreate); CVirtualDirectory* GetVirtualDirectory(const TString& rkPath, bool Transient, bool AllowCreate);
void ConditionalDeleteDirectory(CVirtualDirectory *pDir); void ConditionalDeleteDirectory(CVirtualDirectory *pDir);
bool IsResourceRegistered(const CAssetID& rkID) const; bool IsResourceRegistered(const CAssetID& rkID) const;
CResourceEntry* RegisterResource(const CAssetID& rkID, EResType Type, const TWideString& rkDir, const TWideString& rkName); CResourceEntry* RegisterResource(const CAssetID& rkID, EResType Type, const TString& rkDir, const TString& rkName);
CResourceEntry* FindEntry(const CAssetID& rkID) const; CResourceEntry* FindEntry(const CAssetID& rkID) const;
CResourceEntry* FindEntry(const TWideString& rkPath) const; CResourceEntry* FindEntry(const TString& rkPath) const;
CResourceEntry* RegisterTransientResource(EResType Type, const TWideString& rkDir = L"", const TWideString& rkFileName = L""); CResourceEntry* RegisterTransientResource(EResType Type, const TString& rkDir = "", const TString& rkFileName = "");
CResourceEntry* RegisterTransientResource(EResType Type, const CAssetID& rkID, const TWideString& rkDir = L"", const TWideString& rkFileName = L""); CResourceEntry* RegisterTransientResource(EResType Type, const CAssetID& rkID, const TString& rkDir = "", const TString& rkFileName = "");
CResource* LoadResource(const CAssetID& rkID, const CFourCC& rkType); CResource* LoadResource(const CAssetID& rkID, const CFourCC& rkType);
CResource* LoadResource(const TWideString& rkPath); CResource* LoadResource(const TString& rkPath);
void TrackLoadedResource(CResourceEntry *pEntry); void TrackLoadedResource(CResourceEntry *pEntry);
void DestroyUnreferencedResources(); void DestroyUnreferencedResources();
bool DeleteResourceEntry(CResourceEntry *pEntry); bool DeleteResourceEntry(CResourceEntry *pEntry);
@ -75,23 +75,23 @@ public:
void ImportNamesFromPakContentsTxt(const TString& rkTxtPath, bool UnnamedOnly); void ImportNamesFromPakContentsTxt(const TString& rkTxtPath, bool UnnamedOnly);
static bool IsValidResourcePath(const TWideString& rkPath, const TWideString& rkName); static bool IsValidResourcePath(const TString& rkPath, const TString& rkName);
// Accessors // Accessors
inline CGameProject* Project() const { return mpProj; } inline CGameProject* Project() const { return mpProj; }
inline EGame Game() const { return mGame; } inline EGame Game() const { return mGame; }
inline TWideString DatabaseRootPath() const { return mDatabasePath; } inline TString DatabaseRootPath() const { return mDatabasePath; }
inline TWideString RawDir(bool Relative) const { return Relative ? mRawDir : mDatabasePath + mRawDir; } inline TString RawDir(bool Relative) const { return Relative ? mRawDir : mDatabasePath + mRawDir; }
inline TWideString CookedDir(bool Relative) const { return Relative ? mCookedDir : mDatabasePath + mCookedDir; } inline TString CookedDir(bool Relative) const { return Relative ? mCookedDir : mDatabasePath + mCookedDir; }
inline TWideString DatabasePath() const { return DatabaseRootPath() + mDatabaseName; } inline TString DatabasePath() const { return DatabaseRootPath() + mDatabaseName; }
inline TWideString CacheDataPath() const { return DatabaseRootPath() + L"ResourceCacheData.rcd"; } inline TString CacheDataPath() const { return DatabaseRootPath() + "ResourceCacheData.rcd"; }
inline CVirtualDirectory* RootDirectory() const { return mpDatabaseRoot; } inline CVirtualDirectory* RootDirectory() const { return mpDatabaseRoot; }
inline u32 NumTotalResources() const { return mResourceEntries.size(); } inline u32 NumTotalResources() const { return mResourceEntries.size(); }
inline u32 NumLoadedResources() const { return mLoadedResources.size(); } inline u32 NumLoadedResources() const { return mLoadedResources.size(); }
inline bool IsDirty() const { return mDatabaseDirty || mCacheFileDirty; } inline bool IsDirty() const { return mDatabaseDirty || mCacheFileDirty; }
inline void SetDatabaseDirty() { mDatabaseDirty = true; } inline void SetDatabaseDirty() { mDatabaseDirty = true; }
inline void SetCacheDataDirty() { mCacheFileDirty = true; } inline void SetCacheDataDirty() { mCacheFileDirty = true; }
}; };
extern CResourceStore *gpResourceStore; extern CResourceStore *gpResourceStore;

View File

@ -8,13 +8,13 @@ CVirtualDirectory::CVirtualDirectory(CResourceStore *pStore)
: mpParent(nullptr), mpStore(pStore) : mpParent(nullptr), mpStore(pStore)
{} {}
CVirtualDirectory::CVirtualDirectory(const TWideString& rkName, CResourceStore *pStore) CVirtualDirectory::CVirtualDirectory(const TString& rkName, CResourceStore *pStore)
: mpParent(nullptr), mName(rkName), mpStore(pStore) : mpParent(nullptr), mName(rkName), mpStore(pStore)
{ {
ASSERT(!mName.IsEmpty() && FileUtil::IsValidName(mName, true)); ASSERT(!mName.IsEmpty() && FileUtil::IsValidName(mName, true));
} }
CVirtualDirectory::CVirtualDirectory(CVirtualDirectory *pParent, const TWideString& rkName, CResourceStore *pStore) CVirtualDirectory::CVirtualDirectory(CVirtualDirectory *pParent, const TString& rkName, CResourceStore *pStore)
: mpParent(pParent), mName(rkName), mpStore(pStore) : mpParent(pParent), mName(rkName), mpStore(pStore)
{ {
ASSERT(!mName.IsEmpty() && FileUtil::IsValidName(mName, true)); ASSERT(!mName.IsEmpty() && FileUtil::IsValidName(mName, true));
@ -36,12 +36,12 @@ bool CVirtualDirectory::IsEmpty() const
return true; return true;
} }
TWideString CVirtualDirectory::FullPath() const TString CVirtualDirectory::FullPath() const
{ {
if (IsRoot()) if (IsRoot())
return L""; return "";
else else
return (mpParent && !mpParent->IsRoot() ? mpParent->FullPath() + mName + L'\\' : mName + L'\\'); return (mpParent && !mpParent->IsRoot() ? mpParent->FullPath() + mName + '\\' : mName + '\\');
} }
CVirtualDirectory* CVirtualDirectory::GetRoot() CVirtualDirectory* CVirtualDirectory::GetRoot()
@ -49,10 +49,10 @@ CVirtualDirectory* CVirtualDirectory::GetRoot()
return (mpParent ? mpParent->GetRoot() : this); return (mpParent ? mpParent->GetRoot() : this);
} }
CVirtualDirectory* CVirtualDirectory::FindChildDirectory(const TWideString& rkName, bool AllowCreate) CVirtualDirectory* CVirtualDirectory::FindChildDirectory(const TString& rkName, bool AllowCreate)
{ {
u32 SlashIdx = rkName.IndexOf(L"\\/"); u32 SlashIdx = rkName.IndexOf("\\/");
TWideString DirName = (SlashIdx == -1 ? rkName : rkName.SubString(0, SlashIdx)); TString DirName = (SlashIdx == -1 ? rkName : rkName.SubString(0, SlashIdx));
for (u32 iSub = 0; iSub < mSubdirectories.size(); iSub++) for (u32 iSub = 0; iSub < mSubdirectories.size(); iSub++)
{ {
@ -65,7 +65,7 @@ CVirtualDirectory* CVirtualDirectory::FindChildDirectory(const TWideString& rkNa
else else
{ {
TWideString Remaining = rkName.SubString(SlashIdx + 1, rkName.Size() - SlashIdx); TString Remaining = rkName.SubString(SlashIdx + 1, rkName.Size() - SlashIdx);
if (Remaining.IsEmpty()) if (Remaining.IsEmpty())
return pChild; return pChild;
@ -88,10 +88,10 @@ CVirtualDirectory* CVirtualDirectory::FindChildDirectory(const TWideString& rkNa
return nullptr; return nullptr;
} }
CResourceEntry* CVirtualDirectory::FindChildResource(const TWideString& rkPath) CResourceEntry* CVirtualDirectory::FindChildResource(const TString& rkPath)
{ {
TWideString Dir = rkPath.GetFileDirectory(); TString Dir = rkPath.GetFileDirectory();
TWideString Name = rkPath.GetFileName(); TString Name = rkPath.GetFileName();
if (!Dir.IsEmpty()) if (!Dir.IsEmpty())
{ {
@ -101,7 +101,7 @@ CResourceEntry* CVirtualDirectory::FindChildResource(const TWideString& rkPath)
else if (!Name.IsEmpty()) else if (!Name.IsEmpty())
{ {
TWideString Ext = Name.GetFileExtension(); TString Ext = Name.GetFileExtension();
EResType Type = CResTypeInfo::TypeForCookedExtension(mpStore->Game(), Ext)->Type(); EResType Type = CResTypeInfo::TypeForCookedExtension(mpStore->Game(), Ext)->Type();
return FindChildResource(Name.GetFileName(false), Type); return FindChildResource(Name.GetFileName(false), Type);
} }
@ -109,7 +109,7 @@ CResourceEntry* CVirtualDirectory::FindChildResource(const TWideString& rkPath)
return nullptr; return nullptr;
} }
CResourceEntry* CVirtualDirectory::FindChildResource(const TWideString& rkName, EResType Type) CResourceEntry* CVirtualDirectory::FindChildResource(const TString& rkName, EResType Type)
{ {
for (u32 iRes = 0; iRes < mResources.size(); iRes++) for (u32 iRes = 0; iRes < mResources.size(); iRes++)
{ {
@ -120,7 +120,7 @@ CResourceEntry* CVirtualDirectory::FindChildResource(const TWideString& rkName,
return nullptr; return nullptr;
} }
bool CVirtualDirectory::AddChild(const TWideString &rkPath, CResourceEntry *pEntry) bool CVirtualDirectory::AddChild(const TString &rkPath, CResourceEntry *pEntry)
{ {
if (rkPath.IsEmpty()) if (rkPath.IsEmpty())
{ {
@ -135,9 +135,9 @@ bool CVirtualDirectory::AddChild(const TWideString &rkPath, CResourceEntry *pEnt
else if (IsValidDirectoryPath(rkPath)) else if (IsValidDirectoryPath(rkPath))
{ {
u32 SlashIdx = rkPath.IndexOf(L"\\/"); u32 SlashIdx = rkPath.IndexOf("\\/");
TWideString DirName = (SlashIdx == -1 ? rkPath : rkPath.SubString(0, SlashIdx)); TString DirName = (SlashIdx == -1 ? rkPath : rkPath.SubString(0, SlashIdx));
TWideString Remaining = (SlashIdx == -1 ? L"" : rkPath.SubString(SlashIdx + 1, rkPath.Size() - SlashIdx)); TString Remaining = (SlashIdx == -1 ? "" : rkPath.SubString(SlashIdx + 1, rkPath.Size() - SlashIdx));
// Check if this subdirectory already exists // Check if this subdirectory already exists
CVirtualDirectory *pSubdir = nullptr; CVirtualDirectory *pSubdir = nullptr;
@ -163,7 +163,7 @@ bool CVirtualDirectory::AddChild(const TWideString &rkPath, CResourceEntry *pEnt
// As an optimization, don't recurse here. We've already verified the full path is valid, so we don't need to do it again. // As an optimization, don't recurse here. We've already verified the full path is valid, so we don't need to do it again.
// We also know none of the remaining directories already exist because this is a new, empty directory. // We also know none of the remaining directories already exist because this is a new, empty directory.
TWideStringList Components = Remaining.Split(L"/\\"); TStringList Components = Remaining.Split("/\\");
for (auto Iter = Components.begin(); Iter != Components.end(); Iter++) for (auto Iter = Components.begin(); Iter != Components.end(); Iter++)
{ {
@ -222,24 +222,24 @@ bool CVirtualDirectory::RemoveChildResource(CResourceEntry *pEntry)
} }
// ************ STATIC ************ // ************ STATIC ************
bool CVirtualDirectory::IsValidDirectoryName(const TWideString& rkName) bool CVirtualDirectory::IsValidDirectoryName(const TString& rkName)
{ {
return ( rkName != L"." && return ( rkName != "." &&
rkName != L".." && rkName != ".." &&
FileUtil::IsValidName(rkName, true) ); FileUtil::IsValidName(rkName, true) );
} }
bool CVirtualDirectory::IsValidDirectoryPath(TWideString Path) bool CVirtualDirectory::IsValidDirectoryPath(TString Path)
{ {
// Entirely empty path is valid - this refers to root // Entirely empty path is valid - this refers to root
if (Path.IsEmpty()) if (Path.IsEmpty())
return true; return true;
// One trailing slash is allowed, but will cause IsValidName to fail, so we remove it here // One trailing slash is allowed, but will cause IsValidName to fail, so we remove it here
if (Path.EndsWith(L'/') || Path.EndsWith(L'\\')) if (Path.EndsWith('/') || Path.EndsWith('\\'))
Path = Path.ChopBack(1); Path = Path.ChopBack(1);
TWideStringList Parts = Path.Split(L"/\\", true); TStringList Parts = Path.Split("/\\", true);
for (auto Iter = Parts.begin(); Iter != Parts.end(); Iter++) for (auto Iter = Parts.begin(); Iter != Parts.end(); Iter++)
{ {

View File

@ -14,33 +14,33 @@ class CVirtualDirectory
{ {
CVirtualDirectory *mpParent; CVirtualDirectory *mpParent;
CResourceStore *mpStore; CResourceStore *mpStore;
TWideString mName; TString mName;
std::vector<CVirtualDirectory*> mSubdirectories; std::vector<CVirtualDirectory*> mSubdirectories;
std::vector<CResourceEntry*> mResources; std::vector<CResourceEntry*> mResources;
public: public:
CVirtualDirectory(CResourceStore *pStore); CVirtualDirectory(CResourceStore *pStore);
CVirtualDirectory(const TWideString& rkName, CResourceStore *pStore); CVirtualDirectory(const TString& rkName, CResourceStore *pStore);
CVirtualDirectory(CVirtualDirectory *pParent, const TWideString& rkName, CResourceStore *pStore); CVirtualDirectory(CVirtualDirectory *pParent, const TString& rkName, CResourceStore *pStore);
~CVirtualDirectory(); ~CVirtualDirectory();
bool IsEmpty() const; bool IsEmpty() const;
TWideString FullPath() const; TString FullPath() const;
CVirtualDirectory* GetRoot(); CVirtualDirectory* GetRoot();
CVirtualDirectory* FindChildDirectory(const TWideString& rkName, bool AllowCreate); CVirtualDirectory* FindChildDirectory(const TString& rkName, bool AllowCreate);
CResourceEntry* FindChildResource(const TWideString& rkPath); CResourceEntry* FindChildResource(const TString& rkPath);
CResourceEntry* FindChildResource(const TWideString& rkName, EResType Type); CResourceEntry* FindChildResource(const TString& rkName, EResType Type);
bool AddChild(const TWideString& rkPath, CResourceEntry *pEntry); bool AddChild(const TString& rkPath, CResourceEntry *pEntry);
bool RemoveChildDirectory(CVirtualDirectory *pSubdir); bool RemoveChildDirectory(CVirtualDirectory *pSubdir);
bool RemoveChildResource(CResourceEntry *pEntry); bool RemoveChildResource(CResourceEntry *pEntry);
static bool IsValidDirectoryName(const TWideString& rkName); static bool IsValidDirectoryName(const TString& rkName);
static bool IsValidDirectoryPath(TWideString Path); static bool IsValidDirectoryPath(TString Path);
// Accessors // Accessors
inline CVirtualDirectory* Parent() const { return mpParent; } inline CVirtualDirectory* Parent() const { return mpParent; }
inline bool IsRoot() const { return !mpParent; } inline bool IsRoot() const { return !mpParent; }
inline TWideString Name() const { return mName; } inline TString Name() const { return mName; }
inline u32 NumSubdirectories() const { return mSubdirectories.size(); } inline u32 NumSubdirectories() const { return mSubdirectories.size(); }
inline CVirtualDirectory* SubdirectoryByIndex(u32 Index) { return mSubdirectories[Index]; } inline CVirtualDirectory* SubdirectoryByIndex(u32 Index) { return mSubdirectories[Index]; }

View File

@ -219,8 +219,8 @@ CShader* CShader::FromResourceFile(const TString& rkShaderName)
{ {
TString VertexShaderFilename = "../resources/shaders/" + rkShaderName + ".vs"; TString VertexShaderFilename = "../resources/shaders/" + rkShaderName + ".vs";
TString PixelShaderFilename = "../resources/shaders/" + rkShaderName + ".ps"; TString PixelShaderFilename = "../resources/shaders/" + rkShaderName + ".ps";
CTextInStream VertexShaderFile(VertexShaderFilename.ToStdString()); CTextInStream VertexShaderFile(VertexShaderFilename);
CTextInStream PixelShaderFile(PixelShaderFilename.ToStdString()); CTextInStream PixelShaderFile(PixelShaderFilename);
if (!VertexShaderFile.IsValid()) if (!VertexShaderFile.IsValid())
Log::Error("Couldn't load vertex shader file for " + rkShaderName); Log::Error("Couldn't load vertex shader file for " + rkShaderName);

View File

@ -83,7 +83,7 @@ public:
} }
ASSERT(ParamString.Size() == IDLength * 2); ASSERT(ParamString.Size() == IDLength * 2);
pTree->AddDependency( CAssetID::FromString(ParamString) ); pTree->AddDependency( CAssetID::FromString(ParamString.ToUTF8()) );
} }
// Image // Image
@ -129,7 +129,7 @@ public:
} }
ASSERT(Param.Size() == IDLength * 2); ASSERT(Param.Size() == IDLength * 2);
pTree->AddDependency( CAssetID::FromString(Param) ); pTree->AddDependency( CAssetID::FromString(Param.ToUTF8()) );
} }
} }
} }

View File

@ -65,7 +65,7 @@ TString CWorld::InGameName() const
if (mpWorldName) if (mpWorldName)
return mpWorldName->String("ENGL", 0).ToUTF8(); return mpWorldName->String("ENGL", 0).ToUTF8();
else else
return Entry()->Name().ToUTF8(); return Entry()->Name();
} }
TString CWorld::AreaInGameName(u32 AreaIndex) const TString CWorld::AreaInGameName(u32 AreaIndex) const

View File

@ -68,7 +68,7 @@ void CScriptCooker::WriteProperty(IProperty *pProp, bool InSingleStruct)
case eStringProperty: case eStringProperty:
{ {
TStringProperty *pStringCast = static_cast<TStringProperty*>(pProp); TStringProperty *pStringCast = static_cast<TStringProperty*>(pProp);
mpSCLY->WriteString(pStringCast->Get().ToStdString()); mpSCLY->WriteString(pStringCast->Get());
break; break;
} }

View File

@ -134,7 +134,7 @@ bool CWorldCooker::CookMLVL(CWorld *pWorld, IOutputStream& rMLVL)
rMLVL.WriteLong(ModuleNames.size()); rMLVL.WriteLong(ModuleNames.size());
for (u32 iMod = 0; iMod < ModuleNames.size(); iMod++) for (u32 iMod = 0; iMod < ModuleNames.size(); iMod++)
rMLVL.WriteString(ModuleNames[iMod].ToStdString()); rMLVL.WriteString(ModuleNames[iMod]);
rMLVL.WriteLong(ModuleLayerOffsets.size()); rMLVL.WriteLong(ModuleLayerOffsets.size());
@ -144,7 +144,7 @@ bool CWorldCooker::CookMLVL(CWorld *pWorld, IOutputStream& rMLVL)
// Internal Name // Internal Name
if (Game >= eEchoesDemo) if (Game >= eEchoesDemo)
rMLVL.WriteString(rArea.InternalName.ToStdString()); rMLVL.WriteString(rArea.InternalName);
} }
if (Game <= eCorruption) if (Game <= eCorruption)
@ -218,7 +218,7 @@ bool CWorldCooker::CookMLVL(CWorld *pWorld, IOutputStream& rMLVL)
rMLVL.WriteLong(LayerNames.size()); rMLVL.WriteLong(LayerNames.size());
for (u32 iLyr = 0; iLyr < LayerNames.size(); iLyr++) for (u32 iLyr = 0; iLyr < LayerNames.size(); iLyr++)
rMLVL.WriteString(LayerNames[iLyr].ToStdString()); rMLVL.WriteString(LayerNames[iLyr]);
// todo: Layer Saved State IDs go here for MP3/DKCR; need support for saved state IDs to implement // todo: Layer Saved State IDs go here for MP3/DKCR; need support for saved state IDs to implement
if (Game == eCorruption || Game == eReturns) if (Game == eCorruption || Game == eReturns)

View File

@ -562,7 +562,7 @@ void CAreaLoader::Decompress()
TString Source = mpMREA->GetSourceString(); TString Source = mpMREA->GetSourceString();
mpMREA = new CMemoryInStream(mpDecmpBuffer, mTotalDecmpSize, IOUtil::eBigEndian); mpMREA = new CMemoryInStream(mpDecmpBuffer, mTotalDecmpSize, IOUtil::eBigEndian);
mpMREA->SetSourceString(Source.ToStdString()); mpMREA->SetSourceString(Source);
mpSectionMgr->SetInputStream(mpMREA); mpSectionMgr->SetInputStream(mpMREA);
mHasDecompressedBuffer = true; mHasDecompressedBuffer = true;
} }

View File

@ -117,7 +117,7 @@ void CStringLoader::LoadCorruptionSTRG(IInputStream& rSTRG)
rSTRG.Seek(StringsStart + LangOffsets[iLang][iStr], SEEK_SET); rSTRG.Seek(StringsStart + LangOffsets[iLang][iStr], SEEK_SET);
rSTRG.Seek(0x4, SEEK_CUR); // Skipping string size rSTRG.Seek(0x4, SEEK_CUR); // Skipping string size
pLang->Strings[iStr] = rSTRG.ReadString(); pLang->Strings[iStr] = rSTRG.ReadString().ToUTF16();
} }
} }
} }

View File

@ -73,7 +73,7 @@ bool CEditorApplication::OpenProject(const QString& rkProjPath)
return false; return false;
// Load new project // Load new project
TWideString Path = TO_TWIDESTRING(rkProjPath); TString Path = TO_TSTRING(rkProjPath);
mpActiveProject = CGameProject::LoadProject(Path); mpActiveProject = CGameProject::LoadProject(Path);
if (mpActiveProject) if (mpActiveProject)

View File

@ -66,11 +66,11 @@ void CExportGameDialog::InitUI(QString ExportDir)
ExportDir.replace('/', '\\'); ExportDir.replace('/', '\\');
TWideString DefaultNameMapPath = CAssetNameMap::DefaultNameMapPath(mGame); TString DefaultNameMapPath = CAssetNameMap::DefaultNameMapPath(mGame);
if (!FileUtil::Exists(DefaultNameMapPath)) DefaultNameMapPath = L""; if (!FileUtil::Exists(DefaultNameMapPath)) DefaultNameMapPath = "";
TWideString DefaultGameInfoPath = CGameInfo::GetDefaultGameInfoPath(mGame); TString DefaultGameInfoPath = CGameInfo::GetDefaultGameInfoPath(mGame);
if (!FileUtil::Exists(DefaultGameInfoPath)) DefaultGameInfoPath = L""; if (!FileUtil::Exists(DefaultGameInfoPath)) DefaultGameInfoPath = "";
mpUI->OutputDirectoryLineEdit->setText(ExportDir); mpUI->OutputDirectoryLineEdit->setText(ExportDir);
mpUI->AssetNameMapLineEdit->setText(TO_QSTRING(DefaultNameMapPath)); mpUI->AssetNameMapLineEdit->setText(TO_QSTRING(DefaultNameMapPath));

View File

@ -762,11 +762,11 @@ void CModelEditorWindow::ConvertToDDS()
QString Input = QFileDialog::getOpenFileName(this, "Retro Texture (*.TXTR)", "", "*.TXTR"); QString Input = QFileDialog::getOpenFileName(this, "Retro Texture (*.TXTR)", "", "*.TXTR");
if (Input.isEmpty()) return; if (Input.isEmpty()) return;
TString TexFilename = Input.toStdString(); TString TexFilename = TO_TSTRING(Input);
TResPtr<CTexture> pTex = gpResourceStore->LoadResource(TexFilename); TResPtr<CTexture> pTex = gpResourceStore->LoadResource(TexFilename);
TString OutName = TexFilename.GetFilePathWithoutExtension() + ".dds"; TString OutName = TexFilename.GetFilePathWithoutExtension() + ".dds";
CFileOutStream Out(OutName.ToStdString(), IOUtil::eLittleEndian); CFileOutStream Out(OutName, IOUtil::eLittleEndian);
if (!Out.IsValid()) QMessageBox::warning(this, "Error", "Couldn't open output DDS!"); if (!Out.IsValid()) QMessageBox::warning(this, "Error", "Couldn't open output DDS!");
else else
@ -783,7 +783,7 @@ void CModelEditorWindow::ConvertToTXTR()
if (Input.isEmpty()) return; if (Input.isEmpty()) return;
TString TexFilename = TO_TSTRING(Input); TString TexFilename = TO_TSTRING(Input);
CTexture *pTex = CTextureDecoder::LoadDDS(CFileInStream(TexFilename.ToStdString(), IOUtil::eLittleEndian), nullptr); CTexture *pTex = CTextureDecoder::LoadDDS(CFileInStream(TexFilename, IOUtil::eLittleEndian), nullptr);
TString OutName = TexFilename.GetFilePathWithoutExtension() + ".txtr"; TString OutName = TexFilename.GetFilePathWithoutExtension() + ".txtr";
if ((pTex->TexelFormat() != eDXT1) || (pTex->NumMipMaps() > 1)) if ((pTex->TexelFormat() != eDXT1) || (pTex->NumMipMaps() > 1))
@ -791,7 +791,7 @@ void CModelEditorWindow::ConvertToTXTR()
else else
{ {
CFileOutStream Out(OutName.ToStdString(), IOUtil::eBigEndian); CFileOutStream Out(OutName, IOUtil::eBigEndian);
if (!Out.IsValid()) QMessageBox::warning(this, "Error", "Couldn't open output TXTR!"); if (!Out.IsValid()) QMessageBox::warning(this, "Error", "Couldn't open output TXTR!");
else else

View File

@ -355,7 +355,7 @@ void CResourceBrowser::OnImportNamesFromAssetNameMap()
TString Dir, Name; TString Dir, Name;
if (Map.GetNameInfo(It->ID(), Dir, Name)) if (Map.GetNameInfo(It->ID(), Dir, Name))
It->Move(Dir.ToUTF16(), Name.ToUTF16()); It->Move(Dir, Name);
} }
mpStore->ConditionalSaveStore(); mpStore->ConditionalSaveStore();
@ -404,7 +404,7 @@ void CResourceBrowser::UpdateFilter()
} }
UpdateDescriptionLabel(); UpdateDescriptionLabel();
mpProxyModel->SetSearchString( TO_TWIDESTRING(mpUI->SearchBar->text()) ); mpProxyModel->SetSearchString( TO_TSTRING(mpUI->SearchBar->text()) );
mpProxyModel->invalidate(); mpProxyModel->invalidate();
} }

View File

@ -17,7 +17,7 @@ public:
private: private:
CResourceTableModel *mpModel; CResourceTableModel *mpModel;
TWideString mSearchString; TString mSearchString;
ESortMode mSortMode; ESortMode mSortMode;
QSet<CResTypeInfo*> mTypeFilter; QSet<CResTypeInfo*> mTypeFilter;
@ -108,7 +108,7 @@ public:
} }
public slots: public slots:
void SetSearchString(const TWideString& rkString) void SetSearchString(const TString& rkString)
{ {
mSearchString = rkString.ToUpper(); mSearchString = rkString.ToUpper();
} }

View File

@ -46,7 +46,7 @@ void CLayerEditor::SetCurrentIndex(int Index)
void CLayerEditor::EditLayerName(const QString& rkName) void CLayerEditor::EditLayerName(const QString& rkName)
{ {
mpCurrentLayer->SetName(rkName.toStdString()); mpCurrentLayer->SetName(TO_TSTRING(rkName));
ui->LayerSelectComboBox->update(); ui->LayerSelectComboBox->update();
} }

View File

@ -299,9 +299,9 @@ bool CWorldEditor::SetArea(CWorld *pWorld, int AreaIndex)
QString AreaName = TO_QSTRING(mpWorld->AreaInGameName(AreaIndex)); QString AreaName = TO_QSTRING(mpWorld->AreaInGameName(AreaIndex));
if (CurrentGame() < eReturns) if (CurrentGame() < eReturns)
Log::Write("Loaded area: " + mpArea->Entry()->Name().ToUTF8() + " (" + TO_TSTRING(AreaName) + ")"); Log::Write("Loaded area: " + mpArea->Entry()->Name() + " (" + TO_TSTRING(AreaName) + ")");
else else
Log::Write("Loaded level: World " + mpWorld->Entry()->Name().ToUTF8() + " / Area " + mpArea->Entry()->Name().ToUTF8() + " (" + TO_TSTRING(AreaName) + ")"); Log::Write("Loaded level: World " + mpWorld->Entry()->Name() + " / Area " + mpArea->Entry()->Name() + " (" + TO_TSTRING(AreaName) + ")");
// Update paste action // Update paste action
OnClipboardDataModified(); OnClipboardDataModified();
@ -705,7 +705,7 @@ void CWorldEditor::UpdateOpenRecentActions()
// Remove projects that don't exist anymore // Remove projects that don't exist anymore
foreach (const QString& rkProj, RecentProjectsList) foreach (const QString& rkProj, RecentProjectsList)
{ {
if (!FileUtil::Exists( TO_TWIDESTRING(rkProj) )) if (!FileUtil::Exists( TO_TSTRING(rkProj) ))
RecentProjectsList.removeAll(rkProj); RecentProjectsList.removeAll(rkProj);
} }