Core: Handle paths with non-ASCII characters

This commit is contained in:
zilmar 2024-10-10 18:01:10 +10:30
parent 7aa77a3840
commit a2e479a705
9 changed files with 160 additions and 128 deletions

View File

@ -1,4 +1,5 @@
#include "DynamicLibrary.h" #include "DynamicLibrary.h"
#include "StdString.h"
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
#else #else
@ -15,7 +16,7 @@ DynLibHandle DynamicLibraryOpen(const char * pccLibraryPath, bool ShowErrors)
} }
#ifdef _WIN32 #ifdef _WIN32
UINT LastErrorMode = SetErrorMode(ShowErrors ? 0 : SEM_FAILCRITICALERRORS); UINT LastErrorMode = SetErrorMode(ShowErrors ? 0 : SEM_FAILCRITICALERRORS);
DynLibHandle Lib = (DynLibHandle)LoadLibraryA(pccLibraryPath); DynLibHandle Lib = (DynLibHandle)LoadLibrary(stdstr(pccLibraryPath).ToUTF16().c_str());
SetErrorMode(LastErrorMode); SetErrorMode(LastErrorMode);
#else #else
DynLibHandle Lib = (DynLibHandle)dlopen(pccLibraryPath, RTLD_NOW); DynLibHandle Lib = (DynLibHandle)dlopen(pccLibraryPath, RTLD_NOW);

View File

@ -1,4 +1,5 @@
#include "File.h" #include "File.h"
#include "StdString.h"
#include "path.h" #include "path.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -122,7 +123,7 @@ bool CFile::Open(const char * lpszFileName, uint32_t nOpenFlags)
} }
// Attempt file creation // Attempt file creation
HANDLE hFile = ::CreateFileA(lpszFileName, dwAccess, dwShareMode, &sa, dwCreateFlag, FILE_ATTRIBUTE_NORMAL, nullptr); HANDLE hFile = ::CreateFile(stdstr(lpszFileName).ToUTF16().c_str(), dwAccess, dwShareMode, &sa, dwCreateFlag, FILE_ATTRIBUTE_NORMAL, nullptr);
if (hFile == INVALID_HANDLE_VALUE) if (hFile == INVALID_HANDLE_VALUE)
{ //#define ERROR_PATH_NOT_FOUND 3L { //#define ERROR_PATH_NOT_FOUND 3L
//ULONG err = GetLastError(); //ULONG err = GetLastError();
@ -235,7 +236,9 @@ bool CFile::Flush()
return ::FlushFileBuffers(m_hFile) != 0; return ::FlushFileBuffers(m_hFile) != 0;
#else #else
fflush((FILE *)m_hFile); fflush((FILE *)m_hFile);
#ifndef WIN32
fsync(fileno((FILE *)m_hFile)); fsync(fileno((FILE *)m_hFile));
#endif
return true; return true;
#endif #endif
} }
@ -268,6 +271,49 @@ bool CFile::Write(const void * lpBuf, uint32_t nCount)
return true; return true;
} }
bool CFile::ReadInterger(int32_t & Value)
{
#ifdef USE_WINDOWS_API
LARGE_INTEGER CurrentPos;
LARGE_INTEGER Zero = {0};
if (!SetFilePointerEx(m_hFile, Zero, &CurrentPos, FILE_CURRENT))
{
return false;
}
char buffer[256];
DWORD bytesRead = 0;
if (!::ReadFile(m_hFile, buffer, sizeof(buffer) - 1, &bytesRead, nullptr) || bytesRead == 0)
{
return false;
}
buffer[bytesRead] = '\0';
int CharsRead = 0;
int Number;
sscanf(buffer, "%d%n", &Number, &CharsRead);
LARGE_INTEGER NewPos;
NewPos.QuadPart = CurrentPos.QuadPart + CharsRead;
if (!SetFilePointerEx(m_hFile, NewPos, NULL, FILE_BEGIN))
{
return false;
}
if (CharsRead == 0)
{
return false;
}
Value = Number;
return true;
#else
va_list args;
va_start(args, Format);
int Result = vfscanf((FILE *)m_hFile, "%d", args);
va_end(args);
return Result != 0;
#endif
}
uint32_t CFile::Read(void * lpBuf, uint32_t nCount) uint32_t CFile::Read(void * lpBuf, uint32_t nCount)
{ {
if (nCount == 0) if (nCount == 0)

View File

@ -62,6 +62,7 @@ public:
virtual uint32_t GetLength() const; virtual uint32_t GetLength() const;
virtual uint32_t Read(void * lpBuf, uint32_t nCount); virtual uint32_t Read(void * lpBuf, uint32_t nCount);
virtual bool ReadInterger(int32_t & Value);
virtual bool Write(const void * lpBuf, uint32_t nCount); virtual bool Write(const void * lpBuf, uint32_t nCount);
virtual bool Flush(); virtual bool Flush();

View File

@ -871,15 +871,16 @@ void CPath::UpDirectory(std::string * pLastDirectory /*= nullptr*/)
void CPath::CurrentDirectory() void CPath::CurrentDirectory()
{ {
char buff_path[260];
memset(buff_path, 0, sizeof(buff_path));
Empty(); Empty();
#ifdef _WIN32 #ifdef _WIN32
::GetCurrentDirectoryA(sizeof(buff_path), buff_path); wchar_t buff_path[260];
SetDriveDirectory(buff_path); memset(buff_path, 0, sizeof(buff_path));
::GetCurrentDirectory(sizeof(buff_path), buff_path);
SetDriveDirectory(stdstr().FromUTF16(buff_path).c_str());
#else #else
char buff_path[260];
memset(buff_path, 0, sizeof(buff_path));
getcwd(buff_path, sizeof(buff_path)); getcwd(buff_path, sizeof(buff_path));
SetDirectory(buff_path); SetDirectory(buff_path);
#endif #endif
@ -890,12 +891,10 @@ void CPath::CurrentDirectory()
#ifdef _WIN32 #ifdef _WIN32
void CPath::Module(void * hInstance) void CPath::Module(void * hInstance)
{ {
char buff_path[MAX_PATH]; wchar_t buff_path[MAX_PATH];
memset(buff_path, 0, sizeof(buff_path)); memset(buff_path, 0, sizeof(buff_path));
GetModuleFileName((HINSTANCE)hInstance, buff_path, MAX_PATH);
GetModuleFileNameA((HINSTANCE)hInstance, buff_path, MAX_PATH); m_strPath = stdstr().FromUTF16(buff_path);
m_strPath = buff_path;
} }
// Task: Set path to the name of current module // Task: Set path to the name of current module
@ -954,8 +953,8 @@ bool CPath::DirectoryExists() const
TestPath.UpDirectory(&DirName); TestPath.UpDirectory(&DirName);
TestPath.SetNameExtension(DirName.c_str()); TestPath.SetNameExtension(DirName.c_str());
WIN32_FIND_DATAA FindData; WIN32_FIND_DATA FindData;
HANDLE hFindFile = FindFirstFileA((const char *)TestPath, &FindData); // Find anything HANDLE hFindFile = FindFirstFile(stdstr((const char *)TestPath).ToUTF16().c_str(), &FindData); // Find anything
bool res = (hFindFile != INVALID_HANDLE_VALUE); bool res = (hFindFile != INVALID_HANDLE_VALUE);
if (hFindFile != nullptr) // Make sure we close the search if (hFindFile != nullptr) // Make sure we close the search
@ -982,8 +981,8 @@ bool CPath::DirectoryExists() const
bool CPath::Exists() const bool CPath::Exists() const
{ {
#ifdef _WIN32 #ifdef _WIN32
WIN32_FIND_DATAA FindData; WIN32_FIND_DATA FindData;
HANDLE hFindFile = FindFirstFileA(m_strPath.c_str(), &FindData); HANDLE hFindFile = FindFirstFile(stdstr(m_strPath).ToUTF16().c_str(), &FindData);
bool bSuccess = (hFindFile != INVALID_HANDLE_VALUE); bool bSuccess = (hFindFile != INVALID_HANDLE_VALUE);
if (hFindFile != nullptr) // Make sure we close the search if (hFindFile != nullptr) // Make sure we close the search
@ -1002,21 +1001,23 @@ bool CPath::Exists() const
bool CPath::SelectFile(void * hwndOwner, const char * InitialDir, const char * FileFilter, bool FileMustExist) bool CPath::SelectFile(void * hwndOwner, const char * InitialDir, const char * FileFilter, bool FileMustExist)
{ {
CPath CurrentDir(CURRENT_DIRECTORY); CPath CurrentDir(CURRENT_DIRECTORY);
std::wstring FileFilterW = stdstr(FileFilter).ToUTF16();
std::wstring InitialDirW = stdstr(InitialDir).ToUTF16();
OPENFILENAMEA openfilename; OPENFILENAME openfilename;
char FileName[MAX_PATH]; wchar_t FileName[MAX_PATH];
memset(&FileName, 0, sizeof(FileName)); memset(&FileName, 0, sizeof(FileName));
memset(&openfilename, 0, sizeof(openfilename)); memset(&openfilename, 0, sizeof(openfilename));
openfilename.lStructSize = sizeof(openfilename); openfilename.lStructSize = sizeof(openfilename);
openfilename.hwndOwner = (HWND)hwndOwner; openfilename.hwndOwner = (HWND)hwndOwner;
openfilename.lpstrFilter = FileFilter; openfilename.lpstrFilter = FileFilterW.c_str();
openfilename.lpstrFile = FileName; openfilename.lpstrFile = FileName;
openfilename.lpstrInitialDir = InitialDir; openfilename.lpstrInitialDir = InitialDirW.c_str();
openfilename.nMaxFile = MAX_PATH; openfilename.nMaxFile = MAX_PATH;
openfilename.Flags = OFN_HIDEREADONLY | (FileMustExist ? OFN_FILEMUSTEXIST : 0); openfilename.Flags = OFN_HIDEREADONLY | (FileMustExist ? OFN_FILEMUSTEXIST : 0);
bool res = GetOpenFileNameA(&openfilename) != 0; bool res = GetOpenFileName(&openfilename) != 0;
if (CPath(CURRENT_DIRECTORY) != CurrentDir) if (CPath(CURRENT_DIRECTORY) != CurrentDir)
{ {
CurrentDir.ChangeDirectory(); CurrentDir.ChangeDirectory();
@ -1025,7 +1026,7 @@ bool CPath::SelectFile(void * hwndOwner, const char * InitialDir, const char * F
{ {
return false; return false;
} }
m_strPath = FileName; m_strPath = stdstr().FromUTF16(FileName);
cleanPathString(m_strPath); cleanPathString(m_strPath);
return true; return true;
} }
@ -1037,7 +1038,8 @@ bool CPath::SelectFile(void * hwndOwner, const char * InitialDir, const char * F
bool CPath::Delete(bool bEvenIfReadOnly) const bool CPath::Delete(bool bEvenIfReadOnly) const
{ {
#ifdef _WIN32 #ifdef _WIN32
uint32_t dwAttr = ::GetFileAttributesA(m_strPath.c_str()); std::wstring FilePath = stdstr(m_strPath).ToUTF16();
uint32_t dwAttr = ::GetFileAttributes(FilePath.c_str());
if (dwAttr == (uint32_t)-1) if (dwAttr == (uint32_t)-1)
{ {
// File does not exist // File does not exist
@ -1050,8 +1052,8 @@ bool CPath::Delete(bool bEvenIfReadOnly) const
return false; return false;
} }
SetFileAttributesA(m_strPath.c_str(), FILE_ATTRIBUTE_NORMAL); SetFileAttributes(FilePath.c_str(), FILE_ATTRIBUTE_NORMAL);
return DeleteFileA(m_strPath.c_str()) != 0; return DeleteFile(FilePath.c_str()) != 0;
#else #else
return unlink(m_strPath.c_str()) == 0; return unlink(m_strPath.c_str()) == 0;
#endif #endif
@ -1093,7 +1095,7 @@ bool CPath::CopyTo(const char * lpcszTargetFile, bool bOverwrite)
// CopyFile will set the target's attributes to the same as // CopyFile will set the target's attributes to the same as
// the source after copying // the source after copying
return CopyFileA(m_strPath.c_str(), lpcszTargetFile, !bOverwrite) != 0; return CopyFile(stdstr(m_strPath).ToUTF16().c_str(), stdstr(lpcszTargetFile).ToUTF16().c_str(), !bOverwrite) != 0;
#else #else
bool res = true; bool res = true;
@ -1206,7 +1208,7 @@ bool CPath::MoveTo(const char * lpcszTargetFile, bool bOverwrite)
} }
} }
return MoveFileA(m_strPath.c_str(), lpcszTargetFile) != 0; return MoveFile(stdstr(m_strPath).ToUTF16().c_str(), stdstr(lpcszTargetFile).ToUTF16().c_str()) != 0;
#else #else
return false; return false;
#endif #endif
@ -1261,8 +1263,8 @@ bool CPath::FindFirst(uint32_t dwAttributes /*= FIND_ATTRIBUTE_FILES*/)
BOOL bWantSubdirectory = (BOOL)(FIND_ATTRIBUTE_SUBDIR & dwAttributes); BOOL bWantSubdirectory = (BOOL)(FIND_ATTRIBUTE_SUBDIR & dwAttributes);
// Finding first candidate file // Finding first candidate file
WIN32_FIND_DATAA FindData; WIN32_FIND_DATA FindData;
m_hFindFile = FindFirstFileA(m_strPath.c_str(), &FindData); m_hFindFile = FindFirstFile(stdstr(m_strPath).ToUTF16().c_str(), &FindData);
bGotFile = (m_hFindFile != INVALID_HANDLE_VALUE); bGotFile = (m_hFindFile != INVALID_HANDLE_VALUE);
while (bGotFile) while (bGotFile)
@ -1277,7 +1279,7 @@ bool CPath::FindFirst(uint32_t dwAttributes /*= FIND_ATTRIBUTE_FILES*/)
if ((FIND_ATTRIBUTE_SUBDIR & FindData.dwFileAttributes) != 0) if ((FIND_ATTRIBUTE_SUBDIR & FindData.dwFileAttributes) != 0)
StripTrailingBackslash(m_strPath); StripTrailingBackslash(m_strPath);
SetNameExtension(FindData.cFileName); SetNameExtension(stdstr().FromUTF16(FindData.cFileName).c_str());
if ((FIND_ATTRIBUTE_SUBDIR & FindData.dwFileAttributes) != 0) if ((FIND_ATTRIBUTE_SUBDIR & FindData.dwFileAttributes) != 0)
EnsureTrailingBackslash(m_strPath); EnsureTrailingBackslash(m_strPath);
@ -1285,7 +1287,7 @@ bool CPath::FindFirst(uint32_t dwAttributes /*= FIND_ATTRIBUTE_FILES*/)
// Not found a match, get another // Not found a match, get another
LABEL_GetAnother: LABEL_GetAnother:
bGotFile = FindNextFileA(m_hFindFile, &FindData); bGotFile = FindNextFile(m_hFindFile, &FindData);
} }
#else #else
std::string Directory, Name, Extension; std::string Directory, Name, Extension;
@ -1316,8 +1318,8 @@ bool CPath::FindNext()
return false; return false;
} }
WIN32_FIND_DATAA FindData; WIN32_FIND_DATA FindData;
while (FindNextFileA(m_hFindFile, &FindData) != false) while (FindNextFile(m_hFindFile, &FindData) != false)
{ // while(FindNext(...)) { // while(FindNext(...))
if (AttributesMatch(m_dwFindFileAttributes, FindData.dwFileAttributes)) if (AttributesMatch(m_dwFindFileAttributes, FindData.dwFileAttributes))
{ // if(AttributesMatch(...) { // if(AttributesMatch(...)
@ -1332,7 +1334,7 @@ bool CPath::FindNext()
{ {
SetNameExtension(""); SetNameExtension("");
} }
AppendDirectory(FindData.cFileName); AppendDirectory(stdstr().FromUTF16(FindData.cFileName).c_str());
} }
else else
{ {
@ -1342,7 +1344,7 @@ bool CPath::FindNext()
// Found a directory // Found a directory
UpDirectory(); UpDirectory();
} }
SetNameExtension(FindData.cFileName); SetNameExtension(stdstr().FromUTF16(FindData.cFileName).c_str());
} }
if ((_A_SUBDIR & FindData.dwFileAttributes) == _A_SUBDIR) if ((_A_SUBDIR & FindData.dwFileAttributes) == _A_SUBDIR)
{ {
@ -1413,7 +1415,7 @@ bool CPath::ChangeDirectory()
std::string DriveDirectory; std::string DriveDirectory;
GetDriveDirectory(DriveDirectory); GetDriveDirectory(DriveDirectory);
return SetCurrentDirectoryA(DriveDirectory.c_str()) != 0; return SetCurrentDirectory(stdstr(DriveDirectory).ToUTF16().c_str()) != 0;
#else #else
std::string Dir; std::string Dir;
GetDirectory(Dir); GetDirectory(Dir);
@ -1490,9 +1492,9 @@ bool CPath::DirectoryCreate(bool bCreateIntermediates /*= TRUE*/)
GetDriveDirectory(PathText); GetDriveDirectory(PathText);
StripTrailingBackslash(PathText); StripTrailingBackslash(PathText);
WriteTrace(TracePath, TraceDebug, "Create %s", PathText.c_str()); WriteTrace(TracePath, TraceDebug, "Create %s", PathText.c_str());
bSuccess = ::CreateDirectoryA(PathText.c_str(), nullptr) != 0; bSuccess = ::CreateDirectory(stdstr(PathText).ToUTF16().c_str(), nullptr) != 0;
#else #else
GetDirectory(PathText); GetDirectory(PathText);7
StripTrailingBackslash(PathText); StripTrailingBackslash(PathText);
WriteTrace(TracePath, TraceDebug, "Create %s", PathText.c_str()); WriteTrace(TracePath, TraceDebug, "Create %s", PathText.c_str());
bSuccess = mkdir(PathText.c_str(), S_IRWXU) == 0; bSuccess = mkdir(PathText.c_str(), S_IRWXU) == 0;

View File

@ -589,7 +589,6 @@ CLanguage::~CLanguage()
bool CLanguage::LoadCurrentStrings(void) bool CLanguage::LoadCurrentStrings(void)
{ {
// Clear all the current strings loaded
m_CurrentStrings.clear(); m_CurrentStrings.clear();
if (g_Settings->LoadBool(Debugger_DebugLanguage)) if (g_Settings->LoadBool(Debugger_DebugLanguage))
@ -601,7 +600,6 @@ bool CLanguage::LoadCurrentStrings(void)
LanguageList LangList = GetLangList(); LanguageList LangList = GetLangList();
stdstr Filename; stdstr Filename;
// Find the file name of the current language
for (LanguageList::iterator Language = LangList.begin(); Language != LangList.end(); Language++) for (LanguageList::iterator Language = LangList.begin(); Language != LangList.end(); Language++)
{ {
if (g_Lang->IsCurrentLang(*Language)) if (g_Lang->IsCurrentLang(*Language))
@ -616,30 +614,31 @@ bool CLanguage::LoadCurrentStrings(void)
return false; return false;
} }
// Process the file CFile File(Filename.c_str(), CFileBase::modeRead);
FILE * file = fopen(Filename.c_str(), "rb"); if (!File.IsOpen())
if (file == nullptr)
{ {
return false; return false;
} }
// Search for UTF8 file marker
uint8_t utf_bom[3]; uint8_t utf_bom[3];
if (fread(&utf_bom, sizeof(utf_bom), 1, file) != 1 || if (!File.Read(&utf_bom, sizeof(utf_bom)) ||
utf_bom[0] != 0xEF || utf_bom[0] != 0xEF ||
utf_bom[1] != 0xBB || utf_bom[1] != 0xBB ||
utf_bom[2] != 0xBF) utf_bom[2] != 0xBF)
{ {
fclose(file);
return false; return false;
} }
// String for (;;)
while (!feof(file))
{ {
m_CurrentStrings.insert(GetNextLangString(file)); LANG_STR LangStr = GetNextLangString(File);
if (LangStr.first == 0)
{
break;
} }
fclose(file); m_CurrentStrings.insert(LangStr);
}
m_LanguageLoaded = true; m_LanguageLoaded = true;
return true; return true;
} }
@ -657,8 +656,7 @@ LanguageList & CLanguage::GetLangList(void)
{ {
do do
{ {
LanguageFile File; // We temporally store the values in here to add to the list LanguageFile File;
File.Filename = (const std::string &)LanguageFiles; File.Filename = (const std::string &)LanguageFiles;
File.LanguageName = GetLangString(LanguageFiles, LANGUAGE_NAME); File.LanguageName = GetLangString(LanguageFiles, LANGUAGE_NAME);
@ -666,8 +664,6 @@ LanguageList & CLanguage::GetLangList(void)
{ {
continue; continue;
} }
// Get the name of the language from inside the file
m_LanguageList.push_back(File); m_LanguageList.push_back(File);
} while (LanguageFiles.FindNext()); } while (LanguageFiles.FindNext());
} }
@ -704,38 +700,38 @@ const std::string & CLanguage::GetString(LanguageStringID StringID)
std::string CLanguage::GetLangString(const char * FileName, LanguageStringID ID) std::string CLanguage::GetLangString(const char * FileName, LanguageStringID ID)
{ {
FILE * file = fopen(FileName, "rb"); CFile file;
if (file == nullptr) if (!file.Open(FileName, CFileBase::modeRead))
{ {
return ""; return "";
} }
// Search for UTF8 file marker // Search for UTF8 file marker
uint8_t utf_bom[3]; uint8_t utf_bom[3];
if (fread(&utf_bom, sizeof(utf_bom), 1, file) != 1 || if (!file.Read(&utf_bom, sizeof(utf_bom)) ||
utf_bom[0] != 0xEF || utf_bom[0] != 0xEF ||
utf_bom[1] != 0xBB || utf_bom[1] != 0xBB ||
utf_bom[2] != 0xBF) utf_bom[2] != 0xBF)
{ {
fclose(file);
return ""; return "";
} }
// String for (;;)
while (!feof(file))
{ {
LANG_STR String = GetNextLangString(file); LANG_STR String = GetNextLangString(file);
if (String.first == ID) if (String.first == ID)
{ {
fclose(file);
return String.second; return String.second;
} }
if (String.first == 0)
{
break;
}
} }
fclose(file);
return ""; return "";
} }
LANG_STR CLanguage::GetNextLangString(void * OpenFile) LANG_STR CLanguage::GetNextLangString(CFile & File)
{ {
enum enum
{ {
@ -744,56 +740,47 @@ LANG_STR CLanguage::GetNextLangString(void * OpenFile)
int32_t StringID; int32_t StringID;
char szString[MAX_STRING_LEN]; // Temporarily store the string from the file char szString[MAX_STRING_LEN]; // Temporarily store the string from the file
FILE * file = (FILE *)OpenFile;
//while(token!='#' && !feof(file)) { fread(&token, 1, 1, file); }
if (feof(file))
{
return LANG_STR(0, "");
}
// Search for token number
char token = 0; char token = 0;
while (token != '#' && !feof(file)) while (token != '#')
{ {
fread(&token, 1, 1, file); if (!File.Read(&token, 1))
}
if (feof(file))
{ {
return LANG_STR(0, ""); return LANG_STR(0, "");
} }
// Get StringID after token
fscanf(file, "%d", &StringID);
// Search for token number
while (token != '#' && !feof(file))
{
fread(&token, 1, 1, file);
} }
if (feof(file)) if (!File.ReadInterger(StringID))
{ {
StringID = EMPTY_STRING;
return LANG_STR(0, ""); return LANG_STR(0, "");
} }
token = 0;
// Search for start of string '"' while (token != '#')
while (token != '"' && !feof(file))
{ {
fread(&token, 1, 1, file); if (!File.Read(&token, 1))
}
if (feof(file))
{ {
StringID = EMPTY_STRING;
return LANG_STR(0, ""); return LANG_STR(0, "");
} }
}
while (token != '"')
{
if (!File.Read(&token, 1))
{
return LANG_STR(0, "");
}
}
int32_t pos = 0; int32_t pos = 0;
fread(&token, 1, 1, file); if (!File.Read(&token, 1))
while (token != '"' && !feof(file)) {
return LANG_STR(0, "");
}
while (token != '"')
{ {
szString[pos++] = token; szString[pos++] = token;
fread(&token, 1, 1, file); if (!File.Read(&token, 1))
{
return LANG_STR(0, "");
}
if (pos == MAX_STRING_LEN - 2) if (pos == MAX_STRING_LEN - 2)
{ {
token = '"'; token = '"';

View File

@ -6,6 +6,8 @@
#include <stdint.h> #include <stdint.h>
#include <string> #include <string>
class CFile;
typedef std::map<int32_t, std::string, std::less<int32_t>> LANG_STRINGS; typedef std::map<int32_t, std::string, std::less<int32_t>> LANG_STRINGS;
typedef LANG_STRINGS::value_type LANG_STR; typedef LANG_STRINGS::value_type LANG_STR;
@ -51,7 +53,7 @@ private:
LanguageList m_LanguageList; LanguageList m_LanguageList;
std::string GetLangString(const char * FileName, LanguageStringID ID); std::string GetLangString(const char * FileName, LanguageStringID ID);
LANG_STR GetNextLangString(void * OpenFile); LANG_STR GetNextLangString(CFile & File);
void LoadDefaultStrings(void); void LoadDefaultStrings(void);
bool m_LanguageLoaded; bool m_LanguageLoaded;

View File

@ -222,41 +222,40 @@ void CMainMenu::OnScreenShot(void)
void CMainMenu::OnSaveAs(HWND hWnd) void CMainMenu::OnSaveAs(HWND hWnd)
{ {
char drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT]; char Directory[255];
char Directory[255], SaveFile[255]; wchar_t SaveFileString[255];
OPENFILENAMEA openfilename; OPENFILENAME openfilename;
memset(&SaveFile, 0, sizeof(SaveFile)); memset(&SaveFileString, 0, sizeof(SaveFileString));
memset(&openfilename, 0, sizeof(openfilename)); memset(&openfilename, 0, sizeof(openfilename));
UISettingsLoadStringVal(Directory_LastSave, Directory, sizeof(Directory)); UISettingsLoadStringVal(Directory_LastSave, Directory, sizeof(Directory));
std::wstring InitialDirectory = stdstr((const char *)(CPath(Directory,"").NormalizePath(CPath(CPath::MODULE_DIRECTORY)))).ToUTF16();
openfilename.lStructSize = sizeof(openfilename); openfilename.lStructSize = sizeof(openfilename);
openfilename.hwndOwner = (HWND)hWnd; openfilename.hwndOwner = (HWND)hWnd;
openfilename.lpstrFilter = "Project64 saves (*.zip, *.pj)\0*.pj?;*.pj;*.zip;"; openfilename.lpstrFilter = L"Project64 saves (*.zip, *.pj)\0*.pj?;*.pj;*.zip;";
openfilename.lpstrFile = SaveFile; openfilename.lpstrFile = SaveFileString;
openfilename.lpstrInitialDir = Directory; openfilename.lpstrInitialDir = InitialDirectory.c_str();
openfilename.nMaxFile = MAX_PATH; openfilename.nMaxFile = MAX_PATH;
openfilename.Flags = OFN_HIDEREADONLY; openfilename.Flags = OFN_HIDEREADONLY;
g_BaseSystem->ExternalEvent(SysEvent_PauseCPU_SaveGame); g_BaseSystem->ExternalEvent(SysEvent_PauseCPU_SaveGame);
if (GetSaveFileNameA(&openfilename)) if (GetSaveFileName(&openfilename))
{ {
_splitpath(SaveFile, drive, dir, fname, ext); CPath SaveFile(stdstr().FromUTF16(SaveFileString));
if (_stricmp(ext, ".pj") == 0 || _stricmp(ext, ".zip") == 0) std::string ext = SaveFile.GetExtension();
if (_stricmp(ext.c_str(), "pj") == 0 || _stricmp(ext.c_str(), "zip") == 0)
{ {
_makepath(SaveFile, drive, dir, fname, nullptr); SaveFile.SetExtension("");
_splitpath(SaveFile, drive, dir, fname, ext); ext = SaveFile.GetExtension();
if (_stricmp(ext, ".pj") == 0) if (_stricmp(ext.c_str(), "pj") == 0)
{ {
_makepath(SaveFile, drive, dir, fname, nullptr); SaveFile.SetExtension("");
} }
} }
g_Settings->SaveString(GameRunning_InstantSaveFile, SaveFile); g_Settings->SaveString(GameRunning_InstantSaveFile, (const char *)SaveFile);
UISettingsSaveString(Directory_LastSave, SaveFile.GetDriveDirectory());
char SaveDir[MAX_PATH];
_makepath(SaveDir, drive, dir, nullptr, nullptr);
UISettingsSaveString(Directory_LastSave, SaveDir);
g_BaseSystem->ExternalEvent(SysEvent_SaveMachineState); g_BaseSystem->ExternalEvent(SysEvent_SaveMachineState);
} }
g_BaseSystem->ExternalEvent(SysEvent_ResumeCPU_SaveGame); g_BaseSystem->ExternalEvent(SysEvent_ResumeCPU_SaveGame);

View File

@ -289,21 +289,15 @@ void CRomBrowser::RomAddedToList(int32_t ListPos)
void CRomBrowser::RomListReset(void) void CRomBrowser::RomListReset(void)
{ {
WriteTrace(TraceUserInterface, TraceDebug, "1");
ListView_DeleteAllItems(m_hRomList); ListView_DeleteAllItems(m_hRomList);
WriteTrace(TraceUserInterface, TraceDebug, "2");
InvalidateRect(m_hRomList, nullptr, TRUE); InvalidateRect(m_hRomList, nullptr, TRUE);
Sleep(100); Sleep(100);
WriteTrace(TraceUserInterface, TraceDebug, "3");
m_LastRom = UISettingsLoadStringIndex(File_RecentGameFileIndex, 0); m_LastRom = UISettingsLoadStringIndex(File_RecentGameFileIndex, 0);
if (m_WatchRomDir != g_Settings->LoadStringVal(RomList_GameDir)) if (m_WatchRomDir != stdstr(g_Settings->LoadStringVal(RomList_GameDir)).ToUTF16())
{ {
WriteTrace(TraceUserInterface, TraceDebug, "4");
WatchThreadStop(); WatchThreadStop();
WriteTrace(TraceUserInterface, TraceDebug, "5");
WatchThreadStart(); WatchThreadStart();
WriteTrace(TraceUserInterface, TraceDebug, "6");
} }
} }
@ -1301,14 +1295,14 @@ void CRomBrowser::WatchRomDirChanged(CRomBrowser * _this)
{ {
try try
{ {
_this->m_WatchRomDir = g_Settings->LoadStringVal(RomList_GameDir); _this->m_WatchRomDir = stdstr(g_Settings->LoadStringVal(RomList_GameDir)).ToUTF16();
if (_this->RomDirNeedsRefresh()) if (_this->RomDirNeedsRefresh())
{ {
_this->RomDirChanged(); _this->RomDirChanged();
} }
HANDLE hChange[] = { HANDLE hChange[] = {
_this->m_WatchStopEvent, _this->m_WatchStopEvent,
FindFirstChangeNotificationA(_this->m_WatchRomDir.c_str(), g_Settings->LoadBool(RomList_GameDirRecursive), FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_SIZE), FindFirstChangeNotification(_this->m_WatchRomDir.c_str(), g_Settings->LoadBool(RomList_GameDirRecursive), FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_SIZE),
}; };
for (;;) for (;;)
{ {

View File

@ -198,5 +198,5 @@ private:
static std::string m_UnknownGoodName; static std::string m_UnknownGoodName;
HBRUSH_MAP m_Brushes; HBRUSH_MAP m_Brushes;
std::string m_LastRom; std::string m_LastRom;
stdstr m_WatchRomDir; std::wstring m_WatchRomDir;
}; };