diff --git a/source/collada/XMLFix.cpp b/source/collada/XMLFix.cpp index b40adbb3fd..2f1d67770e 100644 --- a/source/collada/XMLFix.cpp +++ b/source/collada/XMLFix.cpp @@ -166,7 +166,7 @@ void FixBrokenXML(const char* text, const char** out, size_t* outSize) Log(LOG_INFO, "Running FixBrokenXML"); size_t textSize = strlen(text); - xmlDocPtr doc = xmlParseMemory(text, textSize); + xmlDocPtr doc = xmlParseMemory(text, (int)textSize); xmlNode* root = xmlDocGetRootElement(doc); if (root && processDocument(root)) diff --git a/source/graphics/CinemaTrack.cpp b/source/graphics/CinemaTrack.cpp index 96978047c7..3107ed7257 100644 --- a/source/graphics/CinemaTrack.cpp +++ b/source/graphics/CinemaTrack.cpp @@ -52,7 +52,7 @@ CCinemaPath::CCinemaPath(const CCinemaData& data, const TNSpline& spline) DistModePtr = &CCinemaPath::EaseOutIn; break; default: - debug_printf("Cinematic mode not found for %d ", data.m_Mode); + debug_printf(L"Cinematic mode not found for %d ", data.m_Mode); break; } @@ -74,7 +74,7 @@ CCinemaPath::CCinemaPath(const CCinemaData& data, const TNSpline& spline) DistStylePtr = &CCinemaPath::EaseSine; break; default: - debug_printf("Cinematic mode not found for %d !", data.m_Style); + debug_printf(L"Cinematic mode not found for %d !", data.m_Style); break; } //UpdateDuration(); diff --git a/source/graphics/ColladaManager.cpp b/source/graphics/ColladaManager.cpp index 1bc4d1b937..06e203ae29 100644 --- a/source/graphics/ColladaManager.cpp +++ b/source/graphics/ColladaManager.cpp @@ -26,6 +26,8 @@ #include "ps/DllLoader.h" #include "ps/Filesystem.h" +#define LOG_CATEGORY L"collada" + namespace Collada { #include "collada/DLL.h" @@ -36,7 +38,7 @@ namespace void ColladaLog(int severity, const char* text) { const CLogger::ELogMethod method = severity == LOG_INFO ? CLogger::Normal : severity == LOG_WARNING ? CLogger::Warning : CLogger::Error; - LOG(method, "collada", "%s", text); + LOG(method, LOG_CATEGORY, L"%hs", text); } void ColladaOutput(void* cb_data, const char* data, unsigned int length) @@ -79,7 +81,7 @@ public: { if (! dll.LoadDLL()) { - LOG_ONCE(CLogger::Error, "collada", "Failed to load COLLADA conversion DLL"); + LOG_ONCE(CLogger::Error, LOG_CATEGORY, L"Failed to load COLLADA conversion DLL"); return false; } @@ -92,7 +94,7 @@ public: } catch (PSERROR_DllLoader&) { - LOG(CLogger::Error, "collada", "Failed to load symbols from COLLADA conversion DLL"); + LOG(CLogger::Error, LOG_CATEGORY, L"Failed to load symbols from COLLADA conversion DLL"); dll.Unload(); return false; } @@ -100,9 +102,9 @@ public: set_logger(ColladaLog); CVFSFile skeletonFile; - if (skeletonFile.Load("art/skeletons/skeletons.xml") != PSRETURN_OK) + if (skeletonFile.Load(L"art/skeletons/skeletons.xml") != PSRETURN_OK) { - LOG(CLogger::Error, "collada", "Failed to read skeleton definitions"); + LOG(CLogger::Error, LOG_CATEGORY, L"Failed to read skeleton definitions"); dll.Unload(); return false; } @@ -110,7 +112,7 @@ public: int ok = set_skeleton_definitions((const char*)skeletonFile.GetBuffer(), (int)skeletonFile.GetBufferSize()); if (ok < 0) { - LOG(CLogger::Error, "collada", "Failed to load skeleton definitions"); + LOG(CLogger::Error, LOG_CATEGORY, L"Failed to load skeleton definitions"); dll.Unload(); return false; } @@ -161,13 +163,13 @@ CColladaManager::~CColladaManager() delete m; } -VfsPath CColladaManager::GetLoadableFilename(const CStr& sourceName, FileType type) +VfsPath CColladaManager::GetLoadableFilename(const VfsPath& pathnameNoExtension, FileType type) { - const char* extn = NULL; + std::wstring extn; switch (type) { - case PMD: extn = ".pmd"; break; - case PSA: extn = ".psa"; break; + case PMD: extn = L".pmd"; break; + case PSA: extn = L".psa"; break; // no other alternatives } @@ -199,11 +201,11 @@ VfsPath CColladaManager::GetLoadableFilename(const CStr& sourceName, FileType ty // (TODO: the comments and variable names say "pmd" but actually they can // be "psa" too.) - VfsPath dae(sourceName + ".dae"); + VfsPath dae(fs::change_extension(pathnameNoExtension, L".dae")); if (! FileExists(dae)) { // No .dae - got to use the .pmd, assuming there is one - return VfsPath(sourceName + extn); + return fs::change_extension(pathnameNoExtension, extn); } // There is a .dae - see if there's an up-to-date cached copy @@ -212,7 +214,7 @@ VfsPath CColladaManager::GetLoadableFilename(const CStr& sourceName, FileType ty if (g_VFS->GetFileInfo(dae, &fileInfo) < 0) { // This shouldn't occur for any sensible reasons - LOG(CLogger::Error, "collada", "Failed to stat DAE file '%s'", dae.string().c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"Failed to stat DAE file '%ls'", dae.string().c_str()); return VfsPath(); } @@ -221,35 +223,37 @@ VfsPath CColladaManager::GetLoadableFilename(const CStr& sourceName, FileType ty // but do care about the fields not being 64-bit aligned) // (Remove the lowest bit of mtime because some things round it to a // resolution of 2 seconds) +#pragma pack(push, 1) struct { int version; int mtime; int size; } hashSource = { COLLADA_CONVERTER_VERSION, (int)fileInfo.MTime() & ~1, (int)fileInfo.Size() }; cassert(sizeof(hashSource) == sizeof(int) * 3); // no padding, because that would be bad +#pragma pack(pop) // Calculate the hash, convert to hex u32 hash = fnv_hash(static_cast(&hashSource), sizeof(hashSource)); - char hashString[9]; - sprintf(hashString, "%08x", hash); - std::string extension("_"); + wchar_t hashString[9]; + swprintf_s(hashString, ARRAY_SIZE(hashString), L"%08x", hash); + std::wstring extension(L"_"); extension += hashString; extension += extn; // realDaePath_ is "[..]/mods/whatever/art/meshes/whatever.dae" - fs::path realDaePath_; + fs::wpath realDaePath_; LibError ret = g_VFS->GetRealPath(dae, realDaePath_); debug_assert(ret == INFO::OK); - char realDaeBuf[PATH_MAX]; - path_copy(realDaeBuf, realDaePath_.string().c_str()); - const char* realDaePath = strstr(realDaeBuf, "mods/"); + wchar_t realDaeBuf[PATH_MAX]; + wcscpy_s(realDaeBuf, ARRAY_SIZE(realDaeBuf), realDaePath_.string().c_str()); + const wchar_t* realDaePath = wcsstr(realDaeBuf, L"mods/"); // cachedPmdVfsPath is "cache/mods/whatever/art/meshes/whatever_{hash}.pmd" - VfsPath cachedPmdVfsPath = VfsPath("cache/") / realDaePath; - cachedPmdVfsPath = change_extension(cachedPmdVfsPath, extension); + VfsPath cachedPmdVfsPath = VfsPath(L"cache/") / realDaePath; + cachedPmdVfsPath = fs::change_extension(cachedPmdVfsPath, extension); // If it's not in the cache, we'll have to create it first if (! FileExists(cachedPmdVfsPath)) { if (! m->Convert(dae, cachedPmdVfsPath, type)) - return ""; // failed to convert + return L""; // failed to convert } return cachedPmdVfsPath; diff --git a/source/graphics/ColladaManager.h b/source/graphics/ColladaManager.h index 34e4092158..e82f2a7b8e 100644 --- a/source/graphics/ColladaManager.h +++ b/source/graphics/ColladaManager.h @@ -35,13 +35,13 @@ public: * Returns the VFS path to a PMD/PSA file for the given source file. * Performs a (cached) conversion from COLLADA if necessary. * - * @param sourceName path and name, minus extension, of file to load. + * @param pathnameNoExtension path and name, minus extension, of file to load. * One of either "sourceName.pmd" or "sourceName.dae" should exist. * * @return full VFS path (including extension) of file to load; or empty * string if there was a problem and it could not be loaded. */ - VfsPath GetLoadableFilename(const CStr8& sourceName, FileType type); + VfsPath GetLoadableFilename(const VfsPath& pathnameNoExtension, FileType type); private: CColladaManagerImpl* m; diff --git a/source/graphics/Color.cpp b/source/graphics/Color.cpp index 254d529494..edb3259fe8 100644 --- a/source/graphics/Color.cpp +++ b/source/graphics/Color.cpp @@ -90,6 +90,6 @@ void ColorActivateFastImpl() #endif else { - debug_printf("No SSE available. Slow fallback routines will be used.\n"); + debug_printf(L"No SSE available. Slow fallback routines will be used.\n"); } } diff --git a/source/graphics/MapReader.cpp b/source/graphics/MapReader.cpp index e9f4d13056..77312a1213 100644 --- a/source/graphics/MapReader.cpp +++ b/source/graphics/MapReader.cpp @@ -45,7 +45,7 @@ #include "simulation/EntityTemplate.h" #include "simulation/EntityTemplateCollection.h" -#define LOG_CATEGORY "graphics" +#define LOG_CATEGORY L"graphics" CMapReader::CMapReader() : xml_reader(0) @@ -55,7 +55,7 @@ CMapReader::CMapReader() // LoadMap: try to load the map from given file; reinitialise the scene to new data if successful -void CMapReader::LoadMap(const char* filename, CTerrain *pTerrain_, +void CMapReader::LoadMap(const VfsPath& pathname, CTerrain *pTerrain_, CUnitManager *pUnitMan_, WaterManager* pWaterMan_, SkyManager* pSkyMan_, CLightEnv *pLightEnv_, CCamera *pCamera_, CCinemaManager* pCinema_) { @@ -69,7 +69,7 @@ void CMapReader::LoadMap(const char* filename, CTerrain *pTerrain_, pCinema = pCinema_; // [25ms] - unpacker.Read(filename, "PSMP"); + unpacker.Read(pathname, "PSMP"); // check version if (unpacker.GetVersion() < FILE_READ_VERSION) { @@ -87,8 +87,7 @@ void CMapReader::LoadMap(const char* filename, CTerrain *pTerrain_, if (unpacker.GetVersion() >= 3) { // read the corresponding XML file - filename_xml = filename; - filename_xml = filename_xml.Left(filename_xml.length()-4) + ".xml"; + filename_xml = fs::change_extension(pathname, L".xml"); RegMemFun(this, &CMapReader::ReadXML, L"CMapReader::ReadXML", 5800); } @@ -226,7 +225,7 @@ int CMapReader::ApplyData() if (unpacker.GetVersion() < 3) { - debug_warn("Old unsupported map version - objects will be missing"); + debug_warn(L"Old unsupported map version - objects will be missing"); // (GetTemplateByActor doesn't work, since entity templates are now // loaded on demand) } @@ -260,7 +259,7 @@ class CXMLReader { NONCOPYABLE(CXMLReader); public: - CXMLReader(const CStr& xml_filename, CMapReader& mapReader) + CXMLReader(const VfsPath& xml_filename, CMapReader& mapReader) : m_MapReader(mapReader) { Init(xml_filename); @@ -295,7 +294,7 @@ private: int completed_jobs, total_jobs; - void Init(const CStr& xml_filename); + void Init(const VfsPath& xml_filename); void ReadEnvironment(XMBElement parent); void ReadCamera(XMBElement parent); @@ -307,7 +306,7 @@ private: }; -void CXMLReader::Init(const CStr& xml_filename) +void CXMLReader::Init(const VfsPath& xml_filename) { // must only assign once, so do it here node_idx = entity_idx = nonentity_idx = 0; @@ -460,13 +459,13 @@ void CXMLReader::ReadEnvironment(XMBElement parent) #undef READ_COLOUR else - debug_warn("Invalid map XML data"); + debug_warn(L"Invalid map XML data"); } } } else - debug_warn("Invalid map XML data"); + debug_warn(L"Invalid map XML data"); } m_MapReader.m_LightEnv.CalculateSunDirection(); @@ -508,7 +507,7 @@ void CXMLReader::ReadCamera(XMBElement parent) CStr(attrs.GetNamedItem(at_z)).ToFloat()); } else - debug_warn("Invalid map XML data"); + debug_warn(L"Invalid map XML data"); } m_MapReader.pCamera->m_Orientation.SetXRotation(declination); @@ -596,13 +595,13 @@ void CXMLReader::ReadCinema(XMBElement parent) else if ( elementName == el_time ) data.Distance = CStr( nodeChild.GetText() ).ToFloat(); else - debug_warn("Invalid cinematic element for node child"); + debug_warn(L"Invalid cinematic element for node child"); backwardSpline.AddNode(data.Position, data.Rotation, data.Distance); } } else - debug_warn("Invalid cinematic element for path child"); + debug_warn(L"Invalid cinematic element for path child"); } @@ -612,7 +611,7 @@ void CXMLReader::ReadCinema(XMBElement parent) const std::vector& nodes = temp.GetAllNodes(); if ( nodes.empty() ) { - debug_warn("Failure loading cinematics"); + debug_warn(L"Failure loading cinematics"); return; } @@ -633,7 +632,7 @@ void CXMLReader::ReadCinema(XMBElement parent) void CXMLReader::ReadTriggers(XMBElement parent) { - MapTriggerGroup rootGroup( CStrW(L"Triggers"), CStrW(L"") ); + MapTriggerGroup rootGroup( L"Triggers", L"" ); g_TriggerManager.DestroyEngineTriggers(); ReadTriggerGroup(parent, rootGroup); } @@ -761,7 +760,7 @@ void CXMLReader::ReadTriggerGroup(XMBElement parent, MapTriggerGroup& group) { if ( effect.GetNodeName() != el_effect ) { - debug_warn("Invalid effect tag in trigger XML file"); + debug_warn(L"Invalid effect tag in trigger XML file"); return; } MapTriggerEffect mapEffect; @@ -779,7 +778,7 @@ void CXMLReader::ReadTriggerGroup(XMBElement parent, MapTriggerGroup& group) mapEffect.parameters.push_back( effectChild.GetText() ); else { - debug_warn("Invalid parameter tag in trigger XML file"); + debug_warn(L"Invalid parameter tag in trigger XML file"); return; } } @@ -787,13 +786,13 @@ void CXMLReader::ReadTriggerGroup(XMBElement parent, MapTriggerGroup& group) } } else - debug_warn("Invalid trigger node child in trigger XML file"); + debug_warn(L"Invalid trigger node child in trigger XML file"); } //Read trigger children g_TriggerManager.AddTrigger(mapGroup, mapTrigger); } else - debug_warn("Invalid group node child in XML file"); + debug_warn(L"Invalid group node child in XML file"); } //Read group children g_TriggerManager.AddGroup(mapGroup); @@ -869,12 +868,12 @@ int CXMLReader::ReadEntities(XMBElement parent, double end_time) Orientation = CStr(attrs.GetNamedItem(at_angle)).ToFloat(); } else - debug_warn("Invalid map XML data"); + debug_warn(L"Invalid map XML data"); } CEntityTemplate* base = g_EntityTemplateCollection.GetTemplate(TemplateName, g_Game->GetPlayer(PlayerID)); if (! base) - LOG(CLogger::Error, LOG_CATEGORY, "Failed to load entity template '%ls'", TemplateName.c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"Failed to load entity template '%ls'", TemplateName.c_str()); else { std::set selections; // TODO: read from file @@ -882,7 +881,7 @@ int CXMLReader::ReadEntities(XMBElement parent, double end_time) HEntity ent = g_EntityManager.Create(base, Position, Orientation, selections); if (! ent) - LOG(CLogger::Error, LOG_CATEGORY, "Failed to create entity of type '%ls'", TemplateName.c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"Failed to create entity of type '%ls'", TemplateName.c_str()); else { ent->m_actor->SetPlayerID(PlayerID); @@ -943,7 +942,7 @@ int CXMLReader::ReadNonEntities(XMBElement parent, double end_time) Orientation = CStr(attrs.GetNamedItem(at_angle)).ToFloat(); } else - debug_warn("Invalid map XML data"); + debug_warn(L"Invalid map XML data"); } std::set selections; // TODO: read from file @@ -1012,8 +1011,8 @@ int CXMLReader::ProgressiveRead() } else { - debug_printf("Invalid XML element in map file: %s\n", name.c_str()); - debug_warn("Invalid map XML data"); + debug_printf(L"Invalid XML element in map file: %ls\n", CStrW(name).c_str()); + debug_warn(L"Invalid map XML data"); } node_idx++; diff --git a/source/graphics/MapReader.h b/source/graphics/MapReader.h index 995115f0f9..92fed0fcbf 100644 --- a/source/graphics/MapReader.h +++ b/source/graphics/MapReader.h @@ -44,7 +44,7 @@ public: // constructor CMapReader(); // LoadMap: try to load the map from given file; reinitialise the scene to new data if successful - void LoadMap(const char* filename, CTerrain *pTerrain, CUnitManager *pUnitMan, + void LoadMap(const VfsPath& pathname, CTerrain *pTerrain, CUnitManager *pUnitMan, WaterManager* pWaterMan, SkyManager* pSkyMan, CLightEnv *pLightEnv, CCamera *pCamera, CCinemaManager* pCinema); @@ -95,7 +95,7 @@ private: CCamera* pCamera; CCinemaManager* pCinema; CTriggerManager* pTrigMan; - CStr filename_xml; + VfsPath filename_xml; // UnpackTerrain generator state size_t cur_terrain_tex; diff --git a/source/graphics/MapWriter.cpp b/source/graphics/MapWriter.cpp index c105cdb0c7..d47f0fdf60 100644 --- a/source/graphics/MapWriter.cpp +++ b/source/graphics/MapWriter.cpp @@ -54,7 +54,7 @@ CMapWriter::CMapWriter() /////////////////////////////////////////////////////////////////////////////////////////////////// // SaveMap: try to save the current map to the given file -void CMapWriter::SaveMap(const char* filename, CTerrain* pTerrain, +void CMapWriter::SaveMap(const VfsPath& pathname, CTerrain* pTerrain, CUnitManager* pUnitMan, WaterManager* pWaterMan, SkyManager* pSkyMan, CLightEnv* pLightEnv, CCamera* pCamera, CCinemaManager* pCinema) { @@ -64,11 +64,10 @@ void CMapWriter::SaveMap(const char* filename, CTerrain* pTerrain, PackMap(packer, pTerrain); // write it out - packer.Write(filename); + packer.Write(pathname); - CStr filename_xml (filename); - filename_xml = filename_xml.Left(filename_xml.length()-4) + ".xml"; - WriteXML(filename_xml, pUnitMan, pWaterMan, pSkyMan, pLightEnv, pCamera, pCinema); + VfsPath pathnameXML = fs::change_extension(pathname, L".xml"); + WriteXML(pathnameXML, pUnitMan, pWaterMan, pSkyMan, pLightEnv, pCamera, pCinema); } /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -173,7 +172,7 @@ void CMapWriter::PackTerrain(CFilePacker& packer, CTerrain* pTerrain) // pack tile data packer.PackRaw(&tiles[0],sizeof(STileDesc)*tiles.size()); } -void CMapWriter::WriteXML(const char* filename, +void CMapWriter::WriteXML(const VfsPath& filename, CUnitManager* pUnitMan, WaterManager* pWaterMan, SkyManager* pSkyMan, CLightEnv* pLightEnv, CCamera* pCamera, CCinemaManager* pCinema) { @@ -391,8 +390,7 @@ void CMapWriter::WriteXML(const char* filename, const std::list& groups = g_TriggerManager.GetAllTriggerGroups(); std::list rootChildren; - std::list::const_iterator root = std::find( groups.begin(), groups.end(), - CStrW(L"Triggers") ); + std::list::const_iterator root = std::find( groups.begin(), groups.end(), L"Triggers" ); if ( root == groups.end() ) { @@ -432,7 +430,7 @@ void CMapWriter::WriteTriggerGroup(XMLWriter_File& xml_file_, const MapTriggerGr if ( it2 != groupList.end() ) WriteTriggerGroup(xml_file_, *it2, groupList); else - debug_warn("Invalid trigger group ID while writing map"); + debug_warn(L"Invalid trigger group ID while writing map"); } for ( std::list::const_iterator it = group.triggers.begin(); it != group.triggers.end(); ++it ) @@ -489,8 +487,8 @@ void CMapWriter::WriteTrigger(XMLWriter_File& xml_file_, const MapTrigger& trigg paramIter != it2->parameters.end(); ++paramIter ) { CStrW paramString(*paramIter); - //paramString.Replace(CStrW(L"<"), CStrW(L"<")); - //paramString.Replace(CStrW(L">"), CStrW(L">")); + //paramString.Replace(L"<", L"<"); + //paramString.Replace(L">", L">"); XML_Setting("Parameter", paramString); } if ( it2->linkLogic == 1 ) @@ -533,18 +531,17 @@ void CMapWriter::RewriteAllMaps(CTerrain* pTerrain, CUnitManager* pUnitMan, CLightEnv* pLightEnv, CCamera* pCamera, CCinemaManager* pCinema) { VfsPaths pathnames; - (void)fs_util::GetPathnames(g_VFS, "maps/scenarios", "*.pmp", pathnames); + (void)fs_util::GetPathnames(g_VFS, L"maps/scenarios", L"*.pmp", pathnames); for (size_t i = 0; i < pathnames.size(); i++) { - const char* pathname = pathnames[i].string().c_str(); CMapReader* reader = new CMapReader; LDR_BeginRegistering(); - reader->LoadMap(pathname, pTerrain, pUnitMan, pWaterMan, pSkyMan, pLightEnv, pCamera, pCinema); + reader->LoadMap(pathnames[i], pTerrain, pUnitMan, pWaterMan, pSkyMan, pLightEnv, pCamera, pCinema); LDR_EndRegistering(); LDR_NonprogressiveLoad(); - CStr newPathname(pathname); - newPathname.Replace("scenarios/", "scenarios/new/"); + CStrW newPathname(pathnames[i].string()); + newPathname.Replace(L"scenarios/", L"scenarios/new/"); CMapWriter writer; writer.SaveMap(newPathname, pTerrain, pUnitMan, pWaterMan, pSkyMan, pLightEnv, pCamera, pCinema); } diff --git a/source/graphics/MapWriter.h b/source/graphics/MapWriter.h index c46803cd58..e19ee40123 100644 --- a/source/graphics/MapWriter.h +++ b/source/graphics/MapWriter.h @@ -43,7 +43,7 @@ public: // constructor CMapWriter(); // SaveMap: try to save the current map to the given file - void SaveMap(const char* filename, CTerrain* pTerr, CUnitManager* pUnitMan, + void SaveMap(const VfsPath& pathname, CTerrain* pTerr, CUnitManager* pUnitMan, WaterManager* pWaterMan, SkyManager* pSkyMan, CLightEnv* pLightEnv, CCamera* pCamera, CCinemaManager* pCinema); @@ -66,7 +66,7 @@ private: std::vector& tileIndices); // WriteXML: output some other data (entities, etc) in XML format - void WriteXML(const char* filename, CUnitManager* pUnitMan, WaterManager* pWaterMan, + void WriteXML(const VfsPath& pathname, CUnitManager* pUnitMan, WaterManager* pWaterMan, SkyManager* pSkyMan, CLightEnv* pLightEnv, CCamera* pCamera, CCinemaManager* pCinema); void WriteTriggerGroup(XMLWriter_File& xml_file_, const MapTriggerGroup& group, diff --git a/source/graphics/MaterialManager.cpp b/source/graphics/MaterialManager.cpp index fb7f8ef268..d020b801eb 100644 --- a/source/graphics/MaterialManager.cpp +++ b/source/graphics/MaterialManager.cpp @@ -173,7 +173,7 @@ CMaterialManager::CMaterialManager() CMaterialManager::~CMaterialManager() { - std::map::iterator iter; + std::map::iterator iter; for(iter = m_Materials.begin(); iter != m_Materials.end(); iter++) { if((*iter).second) @@ -183,20 +183,20 @@ CMaterialManager::~CMaterialManager() m_Materials.clear(); } -CMaterial &CMaterialManager::LoadMaterial(const char *file) +CMaterial& CMaterialManager::LoadMaterial(const VfsPath& pathname) { - if(!strlen(file)) + if(pathname.empty()) return NullMaterial; - std::map::iterator iter; - if((iter = m_Materials.find(std::string(file))) != m_Materials.end()) + std::map::iterator iter = m_Materials.find(pathname); + if(iter != m_Materials.end()) { if((*iter).second) return *(*iter).second; } CXeromyces xeroFile; - if(xeroFile.Load(file) != PSRETURN_OK) + if(xeroFile.Load(pathname) != PSRETURN_OK) return NullMaterial; #define EL(x) int el_##x = xeroFile.GetElementID(#x) @@ -248,25 +248,25 @@ CMaterial &CMaterialManager::LoadMaterial(const char *file) } else if(token == el_colors) { - temp = (CStr)attrs.GetNamedItem(at_diffuse); + temp = CStr(attrs.GetNamedItem(at_diffuse)); if(! temp.empty()) material->SetDiffuse(ParseColor(temp)); - temp = (CStr)attrs.GetNamedItem(at_ambient); + temp = CStr(attrs.GetNamedItem(at_ambient)); if(! temp.empty()) material->SetAmbient(ParseColor(temp)); - temp = (CStr)attrs.GetNamedItem(at_specular); + temp = CStr(attrs.GetNamedItem(at_specular)); if(! temp.empty()) material->SetSpecular(ParseColor(temp)); - temp = (CStr)attrs.GetNamedItem(at_specularpower); + temp = CStr(attrs.GetNamedItem(at_specularpower)); if(! temp.empty()) material->SetSpecularPower(ClampFloat(temp.ToFloat(), 0.0f, 1.0f)); } else if(token == el_alpha) { - temp = (CStr)attrs.GetNamedItem(at_usage); + temp = CStr(attrs.GetNamedItem(at_usage)); // Determine whether the alpha is used for basic transparency or player color if (temp == "playercolor") @@ -278,7 +278,7 @@ CMaterial &CMaterialManager::LoadMaterial(const char *file) } } - m_Materials[file] = material; + m_Materials[pathname] = material; } catch(...) { diff --git a/source/graphics/MaterialManager.h b/source/graphics/MaterialManager.h index 5dcfa20e12..0f063ad154 100644 --- a/source/graphics/MaterialManager.h +++ b/source/graphics/MaterialManager.h @@ -30,9 +30,9 @@ public: CMaterialManager(); ~CMaterialManager(); - CMaterial &LoadMaterial(const char *file); + CMaterial& LoadMaterial(const VfsPath& pathname); private: - std::map m_Materials; + std::map m_Materials; }; #endif diff --git a/source/graphics/MeshManager.cpp b/source/graphics/MeshManager.cpp index b91c68ede4..67b3a08ddc 100644 --- a/source/graphics/MeshManager.cpp +++ b/source/graphics/MeshManager.cpp @@ -25,7 +25,7 @@ #include "ps/FileIo.h" // to get access to its CError #include "ps/Profile.h" -#define LOG_CATEGORY "mesh" +#define LOG_CATEGORY L"mesh" // TODO: should this cache models while they're not actively in the game? // (Currently they'll probably be deleted when the reference count drops to 0, @@ -40,17 +40,12 @@ CMeshManager::~CMeshManager() { } -CModelDefPtr CMeshManager::GetMesh(const CStr& filename) +CModelDefPtr CMeshManager::GetMesh(const VfsPath& pathname) { - // Strip a three-letter file extension (if there is one) from the filename - CStr name; - if (filename.length() > 4 && filename[filename.length()-4] == '.') - name = filename.substr(0, filename.length()-4); - else - name = filename; + const VfsPath name = fs::change_extension(pathname, L""); // Find the mesh if it's already been loaded and cached - mesh_map::iterator iter = m_MeshMap.find(name); + mesh_map::iterator iter = m_MeshMap.find(name.string()); if (iter != m_MeshMap.end() && !iter->second.expired()) return CModelDefPtr(iter->second); @@ -60,19 +55,19 @@ CModelDefPtr CMeshManager::GetMesh(const CStr& filename) if (pmdFilename.empty()) { - LOG(CLogger::Error, LOG_CATEGORY, "Could not load mesh '%s'", filename.c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"Could not load mesh '%ls'", pathname.string().c_str()); return CModelDefPtr(); } try { CModelDefPtr model (CModelDef::Load(pmdFilename, name)); - m_MeshMap[name] = model; + m_MeshMap[name.string()] = model; return model; } catch (PSERROR_File&) { - LOG(CLogger::Error, LOG_CATEGORY, "Could not load mesh '%s'", filename.c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"Could not load mesh '%ls'", pathname.string().c_str()); return CModelDefPtr(); } } diff --git a/source/graphics/MeshManager.h b/source/graphics/MeshManager.h index 9803a1002a..078e4f1c24 100644 --- a/source/graphics/MeshManager.h +++ b/source/graphics/MeshManager.h @@ -19,6 +19,7 @@ #define INCLUDED_MESHMANAGER #include "ps/CStr.h" +#include "lib/file/vfs/vfs_path.h" #include #include @@ -35,10 +36,10 @@ public: CMeshManager(CColladaManager& colladaManager); ~CMeshManager(); - CModelDefPtr GetMesh(const CStr& filename); + CModelDefPtr GetMesh(const VfsPath& pathname); private: - typedef STL_HASH_MAP, CStr_hash_compare> mesh_map; + typedef STL_HASH_MAP, CStrW_hash_compare> mesh_map; mesh_map m_MeshMap; CColladaManager& m_ColladaManager; }; diff --git a/source/graphics/Model.cpp b/source/graphics/Model.cpp index 9118fe326e..a2f748a0a1 100644 --- a/source/graphics/Model.cpp +++ b/source/graphics/Model.cpp @@ -35,7 +35,7 @@ #include "ps/Profile.h" #include "ps/CLogger.h" -#define LOG_CATEGORY "graphics" +#define LOG_CATEGORY L"graphics" ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // Constructor @@ -213,9 +213,9 @@ void CModel::CalcAnimatedObjectBound(CSkeletonAnimDef* anim,CBound& result) ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // BuildAnimation: load raw animation frame animation from given file, and build a // animation specific to this model -CSkeletonAnim* CModel::BuildAnimation(const char* filename, const char* name, float speed, double actionpos, double actionpos2) +CSkeletonAnim* CModel::BuildAnimation(const VfsPath& pathname, const char* name, float speed, double actionpos, double actionpos2) { - CSkeletonAnimDef* def = m_SkeletonAnimManager.GetAnimation(filename); + CSkeletonAnimDef* def = m_SkeletonAnimManager.GetAnimation(pathname); if (!def) return NULL; @@ -395,7 +395,7 @@ bool CModel::SetAnimation(CSkeletonAnim* anim, bool once, float speed, CSkeleton if (anim->m_AnimDef && anim->m_AnimDef->GetNumKeys() != m_pModelDef->GetNumBones()) { // mismatch between model's skeleton and animation's skeleton - LOG(CLogger::Error, LOG_CATEGORY, "Mismatch between model's skeleton and animation's skeleton (%lu model bones != %lu animation keys)", + LOG(CLogger::Error, LOG_CATEGORY, L"Mismatch between model's skeleton and animation's skeleton (%lu model bones != %lu animation keys)", (unsigned long)m_pModelDef->GetNumBones(), (unsigned long)anim->m_AnimDef->GetNumKeys()); return false; } diff --git a/source/graphics/Model.h b/source/graphics/Model.h index 3fa895006b..7529510ef7 100644 --- a/source/graphics/Model.h +++ b/source/graphics/Model.h @@ -148,7 +148,7 @@ public: // load raw animation frame animation from given file, and build a // animation specific to this model - CSkeletonAnim* BuildAnimation(const char* filename, const char* name, float speed, double actionpos, double actionpos2); + CSkeletonAnim* BuildAnimation(const VfsPath& pathname, const char* name, float speed, double actionpos, double actionpos2); // add a prop to the model on the given point void AddProp(SPropPoint* point, CModel* model, CObjectEntry* objectentry); diff --git a/source/graphics/ModelDef.cpp b/source/graphics/ModelDef.cpp index c3dc6cd3bd..7b593b4e8a 100644 --- a/source/graphics/ModelDef.cpp +++ b/source/graphics/ModelDef.cpp @@ -92,7 +92,7 @@ CVector3D CModelDef::SkinNormal(const SModelVertex& vtx, // CModelDef Constructor CModelDef::CModelDef() : m_NumVertices(0), m_pVertices(0), m_NumFaces(0), m_pFaces(0), m_NumBones(0), m_Bones(0), - m_NumPropPoints(0), m_PropPoints(0), m_Name("[not loaded]") + m_NumPropPoints(0), m_PropPoints(0), m_Name(L"[not loaded]") { } @@ -119,7 +119,7 @@ SPropPoint* CModelDef::FindPropPoint(const char* name) const } // Load: read and return a new CModelDef initialised with data from given file -CModelDef* CModelDef::Load(const VfsPath& filename, const char* name) +CModelDef* CModelDef::Load(const VfsPath& filename, const VfsPath& name) { CFileUnpacker unpacker; diff --git a/source/graphics/ModelDef.h b/source/graphics/ModelDef.h index 777c499a10..55bab679c5 100644 --- a/source/graphics/ModelDef.h +++ b/source/graphics/ModelDef.h @@ -115,11 +115,11 @@ public: /** * Loads a PMD file. * @param filename VFS path of .pmd file to load - * @param name arbitrary name to give the model for debugging purposes + * @param name arbitrary name to give the model for debugging purposes (usually pathname) * @return the model - always non-NULL * @throw PSERROR_File if it can't load the model */ - static CModelDef* Load(const VfsPath& filename, const char* name); + static CModelDef* Load(const VfsPath& filename, const VfsPath& name); public: // accessor: get vertex data @@ -178,7 +178,7 @@ public: CModelDefRPrivate* GetRenderData(const void* key) const; // accessor: get model name (for debugging) - const CStr& GetName() const { return m_Name; } + const VfsPath& GetName() const { return m_Name; } public: // vertex data @@ -195,8 +195,7 @@ public: SPropPoint* m_PropPoints; private: - // filename - CStr m_Name; + VfsPath m_Name; // filename // renderdata shared by models of the same modeldef, // by render path diff --git a/source/graphics/ObjectBase.cpp b/source/graphics/ObjectBase.cpp index 48ddd9ac03..0d8485e9f4 100644 --- a/source/graphics/ObjectBase.cpp +++ b/source/graphics/ObjectBase.cpp @@ -29,7 +29,7 @@ #include "lib/rand.h" #include "maths/MathUtil.h" -#define LOG_CATEGORY "graphics" +#define LOG_CATEGORY L"graphics" CObjectBase::CObjectBase(CObjectManager& objectManager) : m_ObjectManager(objectManager) @@ -39,21 +39,18 @@ CObjectBase::CObjectBase(CObjectManager& objectManager) m_Properties.m_FloatOnWater = false; } -bool CObjectBase::Load(const char* filename) +bool CObjectBase::Load(const std::wstring& filename) { m_VariantGroups.clear(); - CStr filePath ("art/actors/"); - filePath += filename; + VfsPath pathname(VfsPath(L"art/actors/")/filename); CXeromyces XeroFile; - if (XeroFile.Load(filePath) != PSRETURN_OK) + if (XeroFile.Load(pathname) != PSRETURN_OK) return false; m_Name = filename; - - // Use the filename for the model's name - m_ShortName = CStr(filename).AfterLast("/").BeforeLast(".xml"); + m_ShortName = fs::basename(pathname); // Define all the elements used in the XML file #define EL(x) int el_##x = XeroFile.GetElementID(#x) @@ -86,7 +83,7 @@ bool CObjectBase::Load(const char* filename) if (root.GetNodeName() != el_actor) { - LOG(CLogger::Error, LOG_CATEGORY, "Invalid actor format (unrecognised root element '%s')", XeroFile.GetElementString(root.GetNodeName()).c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"Invalid actor format (unrecognised root element '%hs')", XeroFile.GetElementString(root.GetNodeName()).c_str()); return false; } @@ -140,10 +137,10 @@ bool CObjectBase::Load(const char* filename) int option_name = option.GetNodeName(); if (option_name == el_mesh) - currentVariant->m_ModelFilename = "art/meshes/" + CStr(option.GetText()); + currentVariant->m_ModelFilename = VfsPath(L"art/meshes")/CStrW(option.GetText()); else if (option_name == el_texture) - currentVariant->m_TextureFilename = "art/textures/skins/" + CStr(option.GetText()); + currentVariant->m_TextureFilename = VfsPath(L"art/textures/skins")/CStrW(option.GetText()); else if (option_name == el_colour) currentVariant->m_Color = option.GetText(); @@ -163,7 +160,7 @@ bool CObjectBase::Load(const char* filename) } else if (ae.Name == at_file) { - anim.m_FileName = "art/animation/" + CStr(ae.Value); + anim.m_FileName = VfsPath(L"art/animation")/CStrW(ae.Value); } else if (ae.Name == at_speed) { @@ -197,7 +194,7 @@ bool CObjectBase::Load(const char* filename) if (pe.Name == at_attachpoint) prop.m_PropPointName = pe.Value; else if (pe.Name == at_actor) - prop.m_ModelName = pe.Value; + prop.m_ModelName = CStrW(pe.Value); } currentVariant->m_Props.push_back(prop); } @@ -209,7 +206,7 @@ bool CObjectBase::Load(const char* filename) if (currentGroup->size() == 0) { - LOG(CLogger::Error, LOG_CATEGORY, "Actor group has zero variants ('%s')", filename); + LOG(CLogger::Error, LOG_CATEGORY, L"Actor group has zero variants ('%ls')", filename.c_str()); } ++currentGroup; @@ -224,7 +221,7 @@ bool CObjectBase::Load(const char* filename) } else if (child_name == el_material) { - m_Material = "art/materials/" + CStr(child.GetText()); + m_Material = VfsPath(L"art/materials")/CStrW(child.GetText()); } } @@ -246,7 +243,7 @@ std::vector CObjectBase::CalculateVariationKey(const std::vector choices; - std::multimap chosenProps; + std::multimap chosenProps; for (std::vector >::iterator grp = m_VariantGroups.begin(); grp != m_VariantGroups.end(); @@ -305,12 +302,12 @@ std::vector CObjectBase::CalculateVariationKey(const std::vector::iterator it = var.m_Props.begin(); it != var.m_Props.end(); ++it) if (! it->m_ModelName.empty()) - chosenProps.insert(make_pair(it->m_PropPointName, it->m_ModelName)); + chosenProps.insert(make_pair(it->m_PropPointName, it->m_ModelName.string())); } } // Load each prop, and add their CalculateVariationKey to our key: - for (std::multimap::iterator it = chosenProps.begin(); it != chosenProps.end(); ++it) + for (std::multimap::iterator it = chosenProps.begin(); it != chosenProps.end(); ++it) { CObjectBase* prop = m_ObjectManager.FindObjectBase(it->second); if (prop) @@ -346,7 +343,7 @@ const CObjectBase::Variation CObjectBase::BuildVariation(const std::vector& if (id >= grp->size()) { // This should be impossible - debug_warn("BuildVariation: invalid variant id"); + debug_warn(L"BuildVariation: invalid variant id"); continue; } @@ -392,7 +389,7 @@ std::set CObjectBase::CalculateRandomVariation(const std::set& initi { std::set selections = initialSelections; - std::multimap chosenProps; + std::multimap chosenProps; // Calculate a complete list of selections, so there is at least one // (and in most cases only one) per group. @@ -485,12 +482,12 @@ std::set CObjectBase::CalculateRandomVariation(const std::set& initi // and then insert the new ones: for (std::vector::iterator it = var.m_Props.begin(); it != var.m_Props.end(); ++it) if (! it->m_ModelName.empty()) - chosenProps.insert(make_pair(it->m_PropPointName, it->m_ModelName)); + chosenProps.insert(make_pair(it->m_PropPointName, it->m_ModelName.string())); } } // Load each prop, and add their required selections to ours: - for (std::multimap::iterator it = chosenProps.begin(); it != chosenProps.end(); ++it) + for (std::multimap::iterator it = chosenProps.begin(); it != chosenProps.end(); ++it) { CObjectBase* prop = m_ObjectManager.FindObjectBase(it->second); if (prop) @@ -566,7 +563,7 @@ std::vector > CObjectBase::GetVariantGroups() const { if (! props[k].m_ModelName.empty()) { - CObjectBase* prop = m_ObjectManager.FindObjectBase(props[k].m_ModelName); + CObjectBase* prop = m_ObjectManager.FindObjectBase(props[k].m_ModelName.string().c_str()); if (prop) objectsQueue.push(prop); } diff --git a/source/graphics/ObjectBase.h b/source/graphics/ObjectBase.h index d355535b82..d6c5df19af 100644 --- a/source/graphics/ObjectBase.h +++ b/source/graphics/ObjectBase.h @@ -25,6 +25,7 @@ class CObjectManager; #include #include #include +#include "lib/file/vfs/vfs_path.h" #include "ps/CStr.h" class CObjectBase @@ -39,7 +40,7 @@ public: // name of the animation - "Idle", "Run", etc CStr m_AnimName; // filename of the animation - manidle.psa, manrun.psa, etc - CStr m_FileName; + VfsPath m_FileName; // animation speed, as specified in XML actor file float m_Speed; // fraction of the way through the animation that the interesting bit(s) @@ -52,7 +53,7 @@ public: // name of the prop point to attach to - "Prop01", "Prop02", "Head", "LeftHand", etc .. CStr m_PropPointName; // name of the model file - art/actors/props/sword.xml or whatever - CStr m_ModelName; + VfsPath m_ModelName; }; struct Variant @@ -60,8 +61,8 @@ public: Variant() : m_Frequency(0) {} CStr m_VariantName; // lowercase name int m_Frequency; - CStr m_ModelFilename; - CStr m_TextureFilename; + VfsPath m_ModelFilename; + VfsPath m_TextureFilename; CStr m_Color; std::vector m_Anims; @@ -70,8 +71,8 @@ public: struct Variation { - CStr texture; - CStr model; + VfsPath texture; + VfsPath model; CStr color; std::multimap props; std::multimap anims; @@ -96,13 +97,13 @@ public: // variant names. std::vector > GetVariantGroups() const; - bool Load(const char* filename); + bool Load(const std::wstring& filename); // object name - CStr m_Name; + CStrW m_Name; // short human-readable name - CStr m_ShortName; + CStrW m_ShortName; struct { // automatically flatten terrain when applying object @@ -114,12 +115,11 @@ public: } m_Properties; // the material file - CStr m_Material; + VfsPath m_Material; private: std::vector< std::vector > m_VariantGroups; CObjectManager& m_ObjectManager; }; - #endif diff --git a/source/graphics/ObjectEntry.cpp b/source/graphics/ObjectEntry.cpp index af0b59df75..c1a2e3fe2f 100644 --- a/source/graphics/ObjectEntry.cpp +++ b/source/graphics/ObjectEntry.cpp @@ -37,7 +37,7 @@ #include -#define LOG_CATEGORY "graphics" +#define LOG_CATEGORY L"graphics" CObjectEntry::CObjectEntry(CObjectBase* base) : m_Base(base), m_Color(1.0f, 1.0f, 1.0f, 1.0f), @@ -72,7 +72,7 @@ bool CObjectEntry::BuildVariation(const std::vector >& selections str << variation.color; int r, g, b; if (! (str >> r >> g >> b)) // Any trailing data is ignored - LOG(CLogger::Error, LOG_CATEGORY, "Invalid RGB colour '%s'", variation.color.c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"Invalid RGB colour '%hs'", variation.color.c_str()); else m_Color = CColor(r/255.0f, g/255.0f, b/255.0f, 1.0f); } @@ -93,14 +93,14 @@ bool CObjectEntry::BuildVariation(const std::vector >& selections CModelDefPtr modeldef (objectManager.GetMeshManager().GetMesh(m_ModelName)); if (!modeldef) { - LOG(CLogger::Error, LOG_CATEGORY, "CObjectEntry::BuildModel(): Model %s failed to load", m_ModelName.c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"CObjectEntry::BuildModel(): Model %ls failed to load", m_ModelName.string().c_str()); return false; } // delete old model, create new delete m_Model; m_Model = new CModel(objectManager.GetSkeletonAnimManager()); - m_Model->SetTexture((const char*) m_TextureName); + m_Model->SetTexture(CTexture(m_TextureName)); m_Model->SetMaterial(g_MaterialManager.LoadMaterial(m_Base->m_Material)); m_Model->InitModel(modeldef); m_Model->SetPlayerColor(m_Color); @@ -145,7 +145,7 @@ bool CObjectEntry::BuildVariation(const std::vector >& selections { // start up idling if (! m_Model->SetAnimation(GetRandomAnimation("idle"))) - LOG(CLogger::Error, LOG_CATEGORY, "Failed to set idle animation in model \"%s\"", m_ModelName.c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"Failed to set idle animation in model \"%ls\"", m_ModelName.string().c_str()); } // build props - TODO, RC - need to fix up bounds here @@ -154,10 +154,10 @@ bool CObjectEntry::BuildVariation(const std::vector >& selections { const CObjectBase::Prop& prop = props[p]; - CObjectEntry* oe = objectManager.FindObjectVariation(prop.m_ModelName, selections); + CObjectEntry* oe = objectManager.FindObjectVariation(prop.m_ModelName.string().c_str(), selections); if (!oe) { - LOG(CLogger::Error, LOG_CATEGORY, "Failed to build prop model \"%s\" on actor \"%s\"", (const char*)prop.m_ModelName, (const char*)m_Base->m_ShortName); + LOG(CLogger::Error, LOG_CATEGORY, L"Failed to build prop model \"%ls\" on actor \"%ls\"", prop.m_ModelName.string().c_str(), m_Base->m_ShortName.c_str()); continue; } @@ -171,13 +171,13 @@ bool CObjectEntry::BuildVariation(const std::vector >& selections { CStr ppn = prop.m_PropPointName.substr(7); m_AmmunitionModel = oe->m_Model; - m_AmmunitionPoint = modeldef->FindPropPoint((const char*)ppn ); + m_AmmunitionPoint = modeldef->FindPropPoint(ppn); if (! m_AmmunitionPoint) - LOG(CLogger::Error, LOG_CATEGORY, "Failed to find matching prop point called \"%s\" in model \"%s\" for actor \"%s\"", (const char*)ppn, (const char*)m_ModelName, (const char*)m_Base->m_Name); + LOG(CLogger::Error, LOG_CATEGORY, L"Failed to find matching prop point called \"%hs\" in model \"%ls\" for actor \"%ls\"", ppn.c_str(), m_ModelName.string().c_str(), m_Base->m_Name.c_str()); } else { - SPropPoint* proppoint = modeldef->FindPropPoint((const char*) prop.m_PropPointName); + SPropPoint* proppoint = modeldef->FindPropPoint(prop.m_PropPointName.c_str()); if (proppoint) { CModel* propmodel = oe->m_Model->Clone(); @@ -185,7 +185,7 @@ bool CObjectEntry::BuildVariation(const std::vector >& selections propmodel->SetAnimation(oe->GetRandomAnimation("idle")); } else - LOG(CLogger::Error, LOG_CATEGORY, "Failed to find matching prop point called \"%s\" in model \"%s\" for actor \"%s\"", (const char*)prop.m_PropPointName, (const char*)m_ModelName, (const char*)m_Base->m_Name); + LOG(CLogger::Error, LOG_CATEGORY, L"Failed to find matching prop point called \"%hs\" in model \"%ls\" for actor \"%ls\"", prop.m_PropPointName.c_str(), m_ModelName.string().c_str(), m_Base->m_Name.c_str()); } } @@ -240,7 +240,7 @@ CSkeletonAnim* CObjectEntry::GetRandomAnimation(const CStr& animationName) size_t count = std::distance(lower, upper); if (count == 0) { -// LOG(CLogger::Warning, LOG_CATEGORY, "Failed to find animation '%s' for actor '%s'", animationName.c_str(), m_ModelName.c_str()); +// LOG(CLogger::Warning, LOG_CATEGORY, L"Failed to find animation '%hs' for actor '%ls'", animationName.c_str(), m_ModelName.c_str()); return NULL; } else diff --git a/source/graphics/ObjectEntry.h b/source/graphics/ObjectEntry.h index 075c373b84..1f4fba6265 100644 --- a/source/graphics/ObjectEntry.h +++ b/source/graphics/ObjectEntry.h @@ -28,6 +28,7 @@ struct SPropPoint; #include #include +#include "lib/file/vfs/vfs_path.h" #include "ps/CStr.h" #include "ps/Overlay.h" @@ -45,10 +46,9 @@ public: // different variations of the actor. CObjectBase* m_Base; - // texture name - CStr m_TextureName; + VfsPath m_TextureName; // model name - CStr m_ModelName; + VfsPath m_ModelName; // colour (used when doing alpha-channel colouring, but not doing player-colour) CColor m_Color; // (probable TODO: make colour a per-model thing, rather than per-objectEntry, diff --git a/source/graphics/ObjectManager.cpp b/source/graphics/ObjectManager.cpp index a27002110f..8c82fb74d4 100644 --- a/source/graphics/ObjectManager.cpp +++ b/source/graphics/ObjectManager.cpp @@ -25,7 +25,7 @@ #include "ps/Profile.h" #include "ps/Filesystem.h" -#define LOG_CATEGORY "graphics" +#define LOG_CATEGORY L"graphics" template static void delete_pair_2nd(std::pair v) @@ -62,13 +62,13 @@ CObjectManager::~CObjectManager() } -CObjectBase* CObjectManager::FindObjectBase(const char* objectname) +CObjectBase* CObjectManager::FindObjectBase(const wchar_t* objectname) { - debug_assert(strcmp(objectname, "") != 0); + debug_assert(objectname[0] != '\0'); // See if the base type has been loaded yet: - std::map::iterator it = m_ObjectBases.find(objectname); + std::map::iterator it = m_ObjectBases.find(objectname); if (it != m_ObjectBases.end()) return it->second; @@ -84,18 +84,18 @@ CObjectBase* CObjectManager::FindObjectBase(const char* objectname) else delete obj; - LOG(CLogger::Error, LOG_CATEGORY, "CObjectManager::FindObjectBase(): Cannot find object '%s'", objectname); + LOG(CLogger::Error, LOG_CATEGORY, L"CObjectManager::FindObjectBase(): Cannot find object '%ls'", objectname); return 0; } -CObjectEntry* CObjectManager::FindObject(const char* objname) +CObjectEntry* CObjectManager::FindObject(const wchar_t* objname) { std::vector > selections; // TODO - should this really be empty? return FindObjectVariation(objname, selections); } -CObjectEntry* CObjectManager::FindObjectVariation(const char* objname, const std::vector >& selections) +CObjectEntry* CObjectManager::FindObjectVariation(const wchar_t* objname, const std::vector >& selections) { CObjectBase* base = FindObjectBase(objname); @@ -177,10 +177,10 @@ static LibError GetObjectName_ThunkCb(const VfsPath& pathname, const FileInfo& U void CObjectManager::GetAllObjectNames(std::vector& names) { - (void)fs_util::ForEachFile(g_VFS, "art/actors/", GetObjectName_ThunkCb, (uintptr_t)&names, "*.xml", fs_util::DIR_RECURSIVE); + (void)fs_util::ForEachFile(g_VFS, L"art/actors/", GetObjectName_ThunkCb, (uintptr_t)&names, L"*.xml", fs_util::DIR_RECURSIVE); } void CObjectManager::GetPropObjectNames(std::vector& names) { - (void)fs_util::ForEachFile(g_VFS, "art/actors/props/", GetObjectName_ThunkCb, (uintptr_t)&names, "*.xml", fs_util::DIR_RECURSIVE); + (void)fs_util::ForEachFile(g_VFS, L"art/actors/props/", GetObjectName_ThunkCb, (uintptr_t)&names, L"*.xml", fs_util::DIR_RECURSIVE); } diff --git a/source/graphics/ObjectManager.h b/source/graphics/ObjectManager.h index c01c76d658..9c03aade11 100644 --- a/source/graphics/ObjectManager.h +++ b/source/graphics/ObjectManager.h @@ -61,12 +61,12 @@ public: void UnloadObjects(); - CObjectEntry* FindObject(const char* objname); + CObjectEntry* FindObject(const wchar_t* objname); void DeleteObject(CObjectEntry* entry); - CObjectBase* FindObjectBase(const char* objname); + CObjectBase* FindObjectBase(const wchar_t* objname); - CObjectEntry* FindObjectVariation(const char* objname, const std::vector >& selections); + CObjectEntry* FindObjectVariation(const wchar_t* objname, const std::vector >& selections); CObjectEntry* FindObjectVariation(CObjectBase* base, const std::vector >& selections); // Get all names, quite slowly. (Intended only for Atlas.) @@ -78,7 +78,7 @@ private: CSkeletonAnimManager& m_SkeletonAnimManager; std::map m_Objects; - std::map m_ObjectBases; + std::map m_ObjectBases; }; #endif diff --git a/source/graphics/ParticleEmitter.cpp b/source/graphics/ParticleEmitter.cpp index daaa7bff6d..f8f58f89e6 100644 --- a/source/graphics/ParticleEmitter.cpp +++ b/source/graphics/ParticleEmitter.cpp @@ -25,7 +25,7 @@ #include "ps/XML/Xeromyces.h" #include "ps/CLogger.h" -#define LOG_CATEGORY "particleSystem" +#define LOG_CATEGORY L"particleSystem" //forward declaration void GetValueAndVariation(CXeromyces XeroFile, XMBElement parent, CStr& value, CStr& variation); @@ -61,10 +61,10 @@ CEmitter::~CEmitter(void) delete [] m_heap; } -bool CEmitter::LoadFromXML(const CStr& filename) +bool CEmitter::LoadXml(const VfsPath& pathname) { CXeromyces XeroFile; - if (XeroFile.Load(filename) != PSRETURN_OK) + if (XeroFile.Load(pathname) != PSRETURN_OK) // Fail return false; @@ -107,11 +107,11 @@ bool CEmitter::LoadFromXML(const CStr& filename) if( root.GetNodeName() != el_Emitter ) { - LOG(CLogger::Error, LOG_CATEGORY, "CEmitter::LoadEmitterXML: XML root was not \"Emitter\" in file %s. Load failed.", filename.c_str() ); + LOG(CLogger::Error, LOG_CATEGORY, L"CEmitter::LoadEmitterXML: XML root was not \"Emitter\" in file %ls. Load failed.", pathname.string().c_str() ); return( false ); } - m_tag = CStr(filename).AfterLast("/").BeforeLast(".xml"); + m_tag = fs::basename(pathname); //TODO figure out if we need to use Type attribute to construct different emitter types, // probably have to move some of this code into a static factory method or out into ParticleEngine class @@ -152,7 +152,7 @@ bool CEmitter::LoadFromXML(const CStr& filename) else if( settingName == el_Texture ) { stringValue = settingElement.GetText(); - m_texture = new CTexture(stringValue); + m_texture = new CTexture(CStrW(stringValue)); u32 flags = 0; if(!(CRenderer::GetSingletonPtr()->LoadTexture(m_texture, flags))) return false; diff --git a/source/graphics/ParticleEmitter.h b/source/graphics/ParticleEmitter.h index 4f896df852..e66ef7d587 100644 --- a/source/graphics/ParticleEmitter.h +++ b/source/graphics/ParticleEmitter.h @@ -22,6 +22,7 @@ #ifndef INCLUDED_PARTICLEEMITTER #define INCLUDED_PARTICLEEMITTER +#include "lib/file/vfs/vfs_path.h" #include "maths/Vector3D.h" #include "ps/CStr.h" @@ -109,7 +110,7 @@ public: // note: methods are virtual and overridable so as to suit the // specific particle needs. - virtual bool LoadFromXML(const CStr& filename ); + virtual bool LoadXml(const VfsPath& pathname); virtual bool Setup() { return false; } diff --git a/source/graphics/ParticleEngine.cpp b/source/graphics/ParticleEngine.cpp index 35483117f8..2635a557de 100644 --- a/source/graphics/ParticleEngine.cpp +++ b/source/graphics/ParticleEngine.cpp @@ -76,8 +76,7 @@ void CParticleEngine::DeleteInstance() bool CParticleEngine::InitParticleSystem() { // Texture Loading - CTexture pTex; - pTex.SetName("art/textures/particles/sprite.tga"); + CTexture pTex(L"art/textures/particles/sprite.tga"); int flags = 0; if(!(g_Renderer.LoadTexture(&pTex, flags))) diff --git a/source/graphics/SkeletonAnimDef.cpp b/source/graphics/SkeletonAnimDef.cpp index 7d4ba62f84..baea05e844 100644 --- a/source/graphics/SkeletonAnimDef.cpp +++ b/source/graphics/SkeletonAnimDef.cpp @@ -117,7 +117,7 @@ CSkeletonAnimDef* CSkeletonAnimDef::Load(const VfsPath& filename) /////////////////////////////////////////////////////////////////////////////////////////// // Save: try to save anim to file -void CSkeletonAnimDef::Save(const char* filename,const CSkeletonAnimDef* anim) +void CSkeletonAnimDef::Save(const VfsPath& pathname,const CSkeletonAnimDef* anim) { CFilePacker packer(FILE_VERSION, "PSSA"); @@ -131,5 +131,5 @@ void CSkeletonAnimDef::Save(const char* filename,const CSkeletonAnimDef* anim) packer.PackRaw(anim->m_Keys,numKeys*numFrames*sizeof(Key)); // now write it - packer.Write(filename); + packer.Write(pathname); } diff --git a/source/graphics/SkeletonAnimDef.h b/source/graphics/SkeletonAnimDef.h index e5e1f35d58..8367140ff6 100644 --- a/source/graphics/SkeletonAnimDef.h +++ b/source/graphics/SkeletonAnimDef.h @@ -79,7 +79,7 @@ public: // anim I/O functions static CSkeletonAnimDef* Load(const VfsPath& filename); - static void Save(const char* filename, const CSkeletonAnimDef* anim); + static void Save(const VfsPath& pathname, const CSkeletonAnimDef* anim); public: // frame time - time between successive frames, in ms diff --git a/source/graphics/SkeletonAnimManager.cpp b/source/graphics/SkeletonAnimManager.cpp index 896cbb761d..dc9e4c958c 100644 --- a/source/graphics/SkeletonAnimManager.cpp +++ b/source/graphics/SkeletonAnimManager.cpp @@ -29,7 +29,7 @@ #include "ps/CLogger.h" #include "ps/FileIo.h" -#define LOG_CATEGORY "graphics" +#define LOG_CATEGORY L"graphics" /////////////////////////////////////////////////////////////////////////////// // CSkeletonAnimManager constructor @@ -42,7 +42,7 @@ CSkeletonAnimManager::CSkeletonAnimManager(CColladaManager& colladaManager) // CSkeletonAnimManager destructor CSkeletonAnimManager::~CSkeletonAnimManager() { - typedef std::map::iterator Iter; + typedef std::map::iterator Iter; for (Iter i = m_Animations.begin(); i != m_Animations.end(); ++i) delete i->second; } @@ -50,17 +50,12 @@ CSkeletonAnimManager::~CSkeletonAnimManager() /////////////////////////////////////////////////////////////////////////////// // GetAnimation: return a given animation by filename; return null if filename // doesn't refer to valid animation file -CSkeletonAnimDef* CSkeletonAnimManager::GetAnimation(const CStr& filename) +CSkeletonAnimDef* CSkeletonAnimManager::GetAnimation(const VfsPath& pathname) { - // Strip a three-letter file extension (if there is one) from the filename - CStr name; - if (filename.length() > 4 && filename[filename.length()-4] == '.') - name = filename.substr(0, filename.length()-4); - else - name = filename; + VfsPath name = fs::change_extension(pathname, L""); // Find if it's already been loaded - std::map::iterator iter = m_Animations.find(name); + std::map::iterator iter = m_Animations.find(name); if (iter != m_Animations.end()) return iter->second; @@ -71,7 +66,7 @@ CSkeletonAnimDef* CSkeletonAnimManager::GetAnimation(const CStr& filename) if (psaFilename.empty()) { - LOG(CLogger::Error, LOG_CATEGORY, "Could not load animation '%s'", filename.c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"Could not load animation '%ls'", pathname.string().c_str()); def = NULL; } else @@ -87,9 +82,9 @@ CSkeletonAnimDef* CSkeletonAnimManager::GetAnimation(const CStr& filename) } if (def) - LOG(CLogger::Normal, LOG_CATEGORY, "CSkeletonAnimManager::GetAnimation(%s): Loaded successfully", filename.c_str()); + LOG(CLogger::Normal, LOG_CATEGORY, L"CSkeletonAnimManager::GetAnimation(%ls): Loaded successfully", pathname.string().c_str()); else - LOG(CLogger::Error, LOG_CATEGORY, "CSkeletonAnimManager::GetAnimation(%s): Failed loading, marked file as bad", filename.c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"CSkeletonAnimManager::GetAnimation(%ls): Failed loading, marked file as bad", pathname.string().c_str()); // Add to map m_Animations[name] = def; // NULL if failed to load - we won't try loading it again diff --git a/source/graphics/SkeletonAnimManager.h b/source/graphics/SkeletonAnimManager.h index f60a5ac48f..f8dfce4a2e 100644 --- a/source/graphics/SkeletonAnimManager.h +++ b/source/graphics/SkeletonAnimManager.h @@ -24,6 +24,7 @@ #include #include +#include "lib/file/vfs/vfs_path.h" class CColladaManager; class CSkeletonAnimDef; @@ -42,13 +43,13 @@ public: // return a given animation by filename; return null if filename doesn't // refer to valid animation file - CSkeletonAnimDef* GetAnimation(const CStr8& filename); + CSkeletonAnimDef* GetAnimation(const VfsPath& pathname); private: - CSkeletonAnimDef* LoadAnimation(const char* filename); + CSkeletonAnimDef* LoadAnimation(const VfsPath& pathname); // map of all known animations. Value is NULL if it failed to load. - std::map m_Animations; + std::map m_Animations; CColladaManager& m_ColladaManager; }; diff --git a/source/graphics/Terrain.cpp b/source/graphics/Terrain.cpp index 7343e229bc..b0d8473ada 100644 --- a/source/graphics/Terrain.cpp +++ b/source/graphics/Terrain.cpp @@ -114,8 +114,8 @@ bool CTerrain::IsPassable(const CVector2D &loc/*tile space*/, HEntity entity) co CTerrainPropertiesPtr pProperties = pTexEntry->GetProperties(); if(!pProperties) { - CStr texturePath = pTexEntry->GetTexturePath(); - LOGWARNING("no properties loaded for %s\n", texturePath.c_str()); + VfsPath texturePath = pTexEntry->GetTexturePath(); + LOGWARNING(L"no properties loaded for %ls\n", texturePath.string().c_str()); return false; } return pProperties->IsPassable(entity); diff --git a/source/graphics/TerrainProperties.cpp b/source/graphics/TerrainProperties.cpp index e017f11047..a0dd592a1f 100644 --- a/source/graphics/TerrainProperties.cpp +++ b/source/graphics/TerrainProperties.cpp @@ -31,7 +31,7 @@ #include "ps/XML/Xeromyces.h" #include "ps/CLogger.h" -#define LOG_CATEGORY "graphics" +#define LOG_CATEGORY L"graphics" CTerrainProperties::CTerrainProperties(CTerrainPropertiesPtr parent): @@ -43,10 +43,10 @@ CTerrainProperties::CTerrainProperties(CTerrainPropertiesPtr parent): m_Groups = m_pParent->m_Groups; } -CTerrainPropertiesPtr CTerrainProperties::FromXML(const CTerrainPropertiesPtr& parent, const char* path) +CTerrainPropertiesPtr CTerrainProperties::FromXML(const CTerrainPropertiesPtr& parent, const VfsPath& pathname) { CXeromyces XeroFile; - if (XeroFile.Load(path) != PSRETURN_OK) + if (XeroFile.Load(pathname) != PSRETURN_OK) return CTerrainPropertiesPtr(); XMBElement root = XeroFile.GetRoot(); @@ -57,8 +57,8 @@ CTerrainPropertiesPtr CTerrainProperties::FromXML(const CTerrainPropertiesPtr& p { LOG(CLogger::Error, LOG_CATEGORY, - "TextureManager: Loading %s: Root node is not terrains (found \"%s\")", - path, + L"TextureManager: Loading %ls: Root node is not terrains (found \"%hs\")", + pathname.string().c_str(), rootName.c_str()); return CTerrainPropertiesPtr(); } @@ -76,20 +76,20 @@ CTerrainPropertiesPtr CTerrainProperties::FromXML(const CTerrainPropertiesPtr& p XMBElementList children = root.GetChildNodes(); for (int i=0; iLoadXml(child, &XeroFile, path); + ret->LoadXml(child, &XeroFile, pathname); return ret; } else { LOG(CLogger::Warning, LOG_CATEGORY, - "TerrainProperties: Loading %s: Unexpected node %s\n", - path, + L"TerrainProperties: Loading %ls: Unexpected node %hs\n", + pathname.string().c_str(), XeroFile.GetElementString(child.GetNodeName()).c_str()); // Keep reading - typos shouldn't be showstoppers } @@ -98,7 +98,7 @@ CTerrainPropertiesPtr CTerrainProperties::FromXML(const CTerrainPropertiesPtr& p return CTerrainPropertiesPtr(); } -void CTerrainProperties::LoadXml(XMBElement node, CXeromyces *pFile, const char *path) +void CTerrainProperties::LoadXml(XMBElement node, CXeromyces *pFile, const VfsPath& pathname) { #define ELMT(x) int elmt_##x = pFile->GetElementID(#x) #define ATTR(x) int attr_##x = pFile->GetAttributeID(#x) @@ -139,7 +139,7 @@ void CTerrainProperties::LoadXml(XMBElement node, CXeromyces *pFile, const char CParserLine parserLine; parser.InputTaskType("GroupList", "<_$value_,>_$value_"); - if (!parserLine.ParseString(parser, (CStr)attr.Value)) + if (!parserLine.ParseString(parser, CStr(attr.Value))) continue; m_Groups.clear(); for (size_t i=0;iGetAttributeID(#x) // Passable Attribs diff --git a/source/graphics/TerrainProperties.h b/source/graphics/TerrainProperties.h index edcf95d856..ce5171f19d 100644 --- a/source/graphics/TerrainProperties.h +++ b/source/graphics/TerrainProperties.h @@ -28,6 +28,7 @@ #define INCLUDED_TERRAINPROPERTIES #include "ps/CStr.h" +#include "lib/file/vfs/vfs_path.h" #include class CTerrainGroup; @@ -74,8 +75,8 @@ private: // Passability definitions std::vector m_Passabilities; - void ReadPassability(bool passable, XMBElement node, CXeromyces *pFile, const char *path); - void LoadXml(XMBElement node, CXeromyces *pFile, const char *path); + void ReadPassability(bool passable, XMBElement node, CXeromyces *pFile, const VfsPath& pathname); + void LoadXml(XMBElement node, CXeromyces *pFile, const VfsPath& pathname); public: CTerrainProperties(CTerrainPropertiesPtr parent); @@ -83,7 +84,7 @@ public: // Create a new object and load the XML file specified. Returns NULL upon // failure // The parent pointer may be NULL, for the "root" terrainproperties object. - static CTerrainPropertiesPtr FromXML(const CTerrainPropertiesPtr& parent, const char* path); + static CTerrainPropertiesPtr FromXML(const CTerrainPropertiesPtr& parent, const VfsPath& pathname); // Save the object to an XML file. Implement when needed! ;-) // bool WriteXML(const CStr& path); diff --git a/source/graphics/Texture.h b/source/graphics/Texture.h index 122b54d402..b43b4d71be 100644 --- a/source/graphics/Texture.h +++ b/source/graphics/Texture.h @@ -25,22 +25,22 @@ #define INCLUDED_TEXTURE #include "lib/res/handle.h" -#include "ps/CStr.h" +#include "lib/file/vfs/vfs_path.h" class CTexture { public: CTexture() : m_Handle(0) {} - CTexture(const char* name) : m_Name(name), m_Handle(0) {} + CTexture(const VfsPath& pathname) : m_Name(pathname), m_Handle(0) {} - void SetName(const char* name) { m_Name=name; } - const char* GetName() const { return (const char*) m_Name; } + void SetName(const VfsPath& pathname) { m_Name=pathname; } + const VfsPath& GetName() const { return m_Name; } Handle GetHandle() const { return m_Handle; } void SetHandle(Handle handle) { m_Handle=handle; } private: - CStr m_Name; + VfsPath m_Name; Handle m_Handle; }; diff --git a/source/graphics/TextureEntry.cpp b/source/graphics/TextureEntry.cpp index 55a6865295..501aac8134 100644 --- a/source/graphics/TextureEntry.cpp +++ b/source/graphics/TextureEntry.cpp @@ -30,13 +30,13 @@ #include "Texture.h" #include "renderer/Renderer.h" -#define LOG_CATEGORY "graphics" +#define LOG_CATEGORY L"graphics" std::map CTextureEntry::m_LoadedTextures; ///////////////////////////////////////////////////////////////////////////////////// // CTextureEntry constructor -CTextureEntry::CTextureEntry(CTerrainPropertiesPtr props, const CStr& path): +CTextureEntry::CTextureEntry(CTerrainPropertiesPtr props, const VfsPath& path): m_pProperties(props), m_Bitmap(NULL), m_Handle(-1), @@ -51,15 +51,7 @@ CTextureEntry::CTextureEntry(CTerrainPropertiesPtr props, const CStr& path): for (;it!=m_Groups.end();++it) (*it)->AddTerrain(this); - long slashPos=m_TexturePath.ReverseFind("/"); - long dotPos=m_TexturePath.ReverseFind("."); - if (slashPos == -1) - slashPos = 0; - else - slashPos++; // Skip the actual slash - if (dotPos == -1) - dotPos = (long)m_TexturePath.length(); - m_Tag = m_TexturePath.substr(slashPos, dotPos-slashPos); + m_Tag = fs::basename(m_TexturePath); } ///////////////////////////////////////////////////////////////////////////////////// @@ -81,8 +73,7 @@ CTextureEntry::~CTextureEntry() // LoadTexture: actually load the texture resource from file void CTextureEntry::LoadTexture() { - CTexture texture; - texture.SetName(m_TexturePath); + CTexture texture(m_TexturePath); if (g_Renderer.LoadTexture(&texture,GL_REPEAT)) { m_Handle=texture.GetHandle(); m_LoadedTextures[m_Handle] = this; diff --git a/source/graphics/TextureEntry.h b/source/graphics/TextureEntry.h index a6fc1e602b..81f9d4cccd 100644 --- a/source/graphics/TextureEntry.h +++ b/source/graphics/TextureEntry.h @@ -38,13 +38,12 @@ public: private: // Tag = file name stripped of path and extension (grass_dark_1) - CStr m_Tag; + CStrW m_Tag; // The property sheet used by this texture CTerrainPropertiesPtr m_pProperties; - // Path to the texture file - CStr m_TexturePath; + VfsPath m_TexturePath; void* m_Bitmap; // UI bitmap object (user data for ScEd) Handle m_Handle; // handle to GL texture data @@ -69,7 +68,7 @@ private: public: // Most of the texture's data is delay-loaded, so after the constructor has // been called, the texture entry is ready to be used. - CTextureEntry(CTerrainPropertiesPtr props, const CStr& path); + CTextureEntry(CTerrainPropertiesPtr props, const VfsPath& path); ~CTextureEntry(); CStr GetTag() const @@ -78,7 +77,7 @@ public: CTerrainPropertiesPtr GetProperties() const { return m_pProperties; } - CStr GetTexturePath() const + VfsPath GetTexturePath() const { return m_TexturePath; } void* GetBitmap() const { return m_Bitmap; } diff --git a/source/graphics/TextureManager.cpp b/source/graphics/TextureManager.cpp index 1a9ad5395e..5a2e2d7f18 100644 --- a/source/graphics/TextureManager.cpp +++ b/source/graphics/TextureManager.cpp @@ -31,7 +31,7 @@ #include "ps/CLogger.h" #include "ps/Filesystem.h" -#define LOG_CATEGORY "graphics" +#define LOG_CATEGORY L"graphics" CTextureManager::CTextureManager(): m_LastGroupIndex(0) @@ -74,7 +74,7 @@ CTextureEntry* CTextureManager::FindTexture(const CStr& tag_) return m_TextureEntries[i]; } - LOG(CLogger::Warning, LOG_CATEGORY, "TextureManager: Couldn't find terrain %s", tag.c_str()); + LOG(CLogger::Warning, LOG_CATEGORY, L"TextureManager: Couldn't find terrain %hs", tag.c_str()); return 0; } @@ -83,12 +83,12 @@ CTextureEntry* CTextureManager::FindTexture(Handle handle) return CTextureEntry::GetByHandle(handle); } -CTerrainPropertiesPtr CTextureManager::GetPropertiesFromFile(const CTerrainPropertiesPtr& props, const char* path) +CTerrainPropertiesPtr CTextureManager::GetPropertiesFromFile(const CTerrainPropertiesPtr& props, const VfsPath& pathname) { - return CTerrainProperties::FromXML(props, path); + return CTerrainProperties::FromXML(props, pathname); } -CTextureEntry *CTextureManager::AddTexture(const CTerrainPropertiesPtr& props, const CStr& path) +CTextureEntry *CTextureManager::AddTexture(const CTerrainPropertiesPtr& props, const VfsPath& path) { CTextureEntry *entry = new CTextureEntry(props, path); m_TextureEntries.push_back(entry); @@ -111,89 +111,78 @@ void CTextureManager::DeleteTexture(CTextureEntry* entry) // jw: indeed this is inefficient and RecurseDirectory should be implemented // via VFSUtil::EnumFiles, but it works fine and "only" takes 25ms for // typical maps. therefore, we'll leave it for now. -void CTextureManager::LoadTextures(const CTerrainPropertiesPtr& props, const char* dir) +void CTextureManager::LoadTextures(const CTerrainPropertiesPtr& props, const VfsPath& path) { VfsPaths pathnames; - if(fs_util::GetPathnames(g_VFS, dir, 0, pathnames) < 0) + if(fs_util::GetPathnames(g_VFS, path, 0, pathnames) < 0) return; for(size_t i = 0; i < pathnames.size(); i++) { - const char* texture_name = pathnames[i].string().c_str(); - // skip files that obviously aren't textures. // note: this loop runs for each file in dir, even .xml; // we should skip those to avoid spurious "texture load failed". // we can't use FindFile's filter param because new texture formats // may later be added and that interface doesn't support specifying // multiple extensions. - if(!tex_is_known_extension(texture_name)) + if(!tex_is_known_extension(pathnames[i])) continue; - // build name of associated xml file (i.e. replace extension) - char xml_name[PATH_MAX+5]; // add room for .XML - strcpy_s(xml_name, PATH_MAX, texture_name); - const char* ext = path_extension(texture_name); - SAFE_STRCPY(xml_name + (ext-texture_name), "xml"); - + VfsPath pathnameXML = fs::change_extension(pathnames[i], L".xml"); CTerrainPropertiesPtr myprops; // Has XML file -> attempt to load properties - if (FileExists(xml_name)) + if (FileExists(pathnameXML)) { - myprops = GetPropertiesFromFile(props, xml_name); + myprops = GetPropertiesFromFile(props, pathnameXML); if (myprops) - LOG(CLogger::Normal, LOG_CATEGORY, "CTextureManager: Successfully loaded override xml %s for texture %s", xml_name, texture_name); + LOG(CLogger::Normal, LOG_CATEGORY, L"CTextureManager: Successfully loaded override xml %ls for texture %ls", pathnameXML.string().c_str(), pathnames[i].string().c_str()); } // Error or non-existant xml file -> use parent props if (!myprops) myprops = props; - AddTexture(myprops, texture_name); + AddTexture(myprops, pathnames[i]); } } -void CTextureManager::RecurseDirectory(const CTerrainPropertiesPtr& parentProps, const char* cur_dir_path) +void CTextureManager::RecurseDirectory(const CTerrainPropertiesPtr& parentProps, const VfsPath& path) { - //LOG(CLogger::Normal, LOG_CATEGORY, "CTextureManager::RecurseDirectory(%s)", path.c_str()); + //LOG(CLogger::Normal, LOG_CATEGORY, L"CTextureManager::RecurseDirectory(%ls)", path.string().c_str()); CTerrainPropertiesPtr props; // Load terrains.xml first, if it exists - char fn[PATH_MAX]; - snprintf(fn, PATH_MAX, "%s%s", cur_dir_path, "terrains.xml"); - fn[PATH_MAX-1] = '\0'; - if (FileExists(fn)) - props = GetPropertiesFromFile(parentProps, fn); + VfsPath pathname = path/L"terrains.xml"; + if (FileExists(pathname)) + props = GetPropertiesFromFile(parentProps, pathname); // No terrains.xml, or read failures -> use parent props (i.e. if (!props) { - LOG(CLogger::Normal, LOG_CATEGORY, - "CTextureManager::RecurseDirectory(%s): no terrains.xml (or errors while loading) - using parent properties", cur_dir_path); + LOG(CLogger::Normal, LOG_CATEGORY, L"CTextureManager::RecurseDirectory(%ls): no terrains.xml (or errors while loading) - using parent properties", path.string().c_str()); props = parentProps; } // Recurse once for each subdirectory DirectoryNames subdirectoryNames; - (void)g_VFS->GetDirectoryEntries(cur_dir_path, 0, &subdirectoryNames); + (void)g_VFS->GetDirectoryEntries(path, 0, &subdirectoryNames); for (size_t i=0;i& selections, CObjectManager& objectManager) { CObjectBase* base = objectManager.FindObjectBase(actorName); diff --git a/source/graphics/Unit.h b/source/graphics/Unit.h index fb5977767d..14ec52df14 100644 --- a/source/graphics/Unit.h +++ b/source/graphics/Unit.h @@ -51,7 +51,7 @@ public: // Attempt to create a unit with the given actor, attached to an entity // (or NULL), with a set of suggested selections (with the rest being randomised). // Returns NULL on failure. - static CUnit* Create(const CStr& actorName, CEntity* entity, + static CUnit* Create(const CStrW& actorName, CEntity* entity, const std::set& selections, CObjectManager& objectManager); // destructor diff --git a/source/graphics/tests/test_MeshManager.h b/source/graphics/tests/test_MeshManager.h index 415df93b9d..1f9ab69b3e 100644 --- a/source/graphics/tests/test_MeshManager.h +++ b/source/graphics/tests/test_MeshManager.h @@ -31,24 +31,24 @@ // contains input files (it is assumed that developer's machines have // write access to those directories). note that argv0 isn't // available, so we use sys_get_executable_name. -static fs::path DataDir() +static fs::wpath DataDir() { - char path[PATH_MAX]; - TS_ASSERT_OK(sys_get_executable_name(path, ARRAY_SIZE(path))); - return fs::path(path).branch_path()/"../data"; + fs::wpath path; + TS_ASSERT_OK(sys_get_executable_name(path)); + return path.branch_path()/L"../data"; } -static fs::path MOD_PATH(DataDir()/"mods/_test.mesh"); -static fs::path CACHE_PATH(DataDir()/"_testcache"); +static fs::wpath MOD_PATH(DataDir()/L"mods/_test.mesh"); +static fs::wpath CACHE_PATH(DataDir()/L"_testcache"); -const char* srcDAE = "collada/sphere.dae"; -const char* srcPMD = "collada/sphere.pmd"; -const char* testDAE = "art/skeletons/test.dae"; -const char* testPMD = "art/skeletons/test.pmd"; -const char* testBase = "art/skeletons/test"; +const wchar_t* srcDAE = L"collada/sphere.dae"; +const wchar_t* srcPMD = L"collada/sphere.pmd"; +const wchar_t* testDAE = L"art/skeletons/test.dae"; +const wchar_t* testPMD = L"art/skeletons/test.pmd"; +const wchar_t* testBase = L"art/skeletons/test"; -const char* srcSkeletonDefs = "collada/skeletons.xml"; -const char* testSkeletonDefs = "art/skeletons/skeletons.xml"; +const wchar_t* srcSkeletonDefs = L"collada/skeletons.xml"; +const wchar_t* testSkeletonDefs = L"art/skeletons/skeletons.xml"; extern PIVFS g_VFS; @@ -69,13 +69,13 @@ class TestMeshManager : public CxxTest::TestSuite g_VFS = CreateVfs(20*MiB); - TS_ASSERT_OK(g_VFS->Mount("", MOD_PATH)); - TS_ASSERT_OK(g_VFS->Mount("collada/", DataDir()/"tests/collada")); + TS_ASSERT_OK(g_VFS->Mount(L"", MOD_PATH)); + TS_ASSERT_OK(g_VFS->Mount(L"collada/", DataDir()/L"tests/collada")); // Mount _testcache onto virtual /cache - don't use the normal cache // directory because that's full of loads of cached files from the // proper game and takes a long time to load. - TS_ASSERT_OK(g_VFS->Mount("cache/", CACHE_PATH)); + TS_ASSERT_OK(g_VFS->Mount(L"cache/", CACHE_PATH)); } void deinitVfs() @@ -85,7 +85,7 @@ class TestMeshManager : public CxxTest::TestSuite g_VFS.reset(); } - void copyFile(const char* src, const char* dst) + void copyFile(const VfsPath& src, const VfsPath& dst) { // Copy a file into the mod directory, so we can work on it: shared_ptr data; size_t size = 0; @@ -137,7 +137,7 @@ public: CModelDefPtr modeldef = meshManager->GetMesh(testPMD); TS_ASSERT(modeldef); - if (modeldef) TS_ASSERT_STR_EQUALS(modeldef->GetName(), testBase); + if (modeldef) TS_ASSERT_WSTR_EQUALS(modeldef->GetName().string(), testBase); } void test_load_pmd_without_extension() @@ -146,7 +146,7 @@ public: CModelDefPtr modeldef = meshManager->GetMesh(testBase); TS_ASSERT(modeldef); - if (modeldef) TS_ASSERT_STR_EQUALS(modeldef->GetName(), testBase); + if (modeldef) TS_ASSERT_WSTR_EQUALS(modeldef->GetName().string(), testBase); } void test_caching() @@ -166,7 +166,7 @@ public: CModelDefPtr modeldef = meshManager->GetMesh(testDAE); TS_ASSERT(modeldef); - if (modeldef) TS_ASSERT_STR_EQUALS(modeldef->GetName(), testBase); + if (modeldef) TS_ASSERT_WSTR_EQUALS(modeldef->GetName().string(), testBase); } void test_load_dae_caching() @@ -177,7 +177,7 @@ public: VfsPath daeName1 = colladaManager->GetLoadableFilename(testBase, CColladaManager::PMD); VfsPath daeName2 = colladaManager->GetLoadableFilename(testBase, CColladaManager::PMD); TS_ASSERT(!daeName1.empty()); - TS_ASSERT_STR_EQUALS(daeName1.string(), daeName2.string()); + TS_ASSERT_WSTR_EQUALS(daeName1.string(), daeName2.string()); // TODO: it'd be nice to test that it really isn't doing the DAE->PMD // conversion a second time, but there doesn't seem to be an easy way // to check that @@ -194,7 +194,7 @@ public: CModelDefPtr modeldef = meshManager->GetMesh(testDAE); TS_ASSERT(! modeldef); - TS_ASSERT_STR_CONTAINS(logger.GetOutput(), "parser error"); + TS_ASSERT_WSTR_CONTAINS(logger.GetOutput(), L"parser error"); } void test_invalid_dae() @@ -208,7 +208,7 @@ public: CModelDefPtr modeldef = meshManager->GetMesh(testDAE); TS_ASSERT(! modeldef); - TS_ASSERT_STR_CONTAINS(logger.GetOutput(), "parser error"); + TS_ASSERT_WSTR_CONTAINS(logger.GetOutput(), L"parser error"); } void test_load_nonexistent_pmd() @@ -233,7 +233,7 @@ public: void test_load_dae_bogus_material_target() { - copyFile("collada/bogus_material_target.dae", testDAE); + copyFile(L"collada/bogus_material_target.dae", testDAE); copyFile(srcSkeletonDefs, testSkeletonDefs); CModelDefPtr modeldef = meshManager->GetMesh(testDAE); diff --git a/source/gui/CButton.cpp b/source/gui/CButton.cpp index f2c05c6d65..aafa70175d 100644 --- a/source/gui/CButton.cpp +++ b/source/gui/CButton.cpp @@ -34,7 +34,7 @@ CButton::CButton() AddSetting(GUIST_float, "buffer_zone"); AddSetting(GUIST_CGUIString, "caption"); AddSetting(GUIST_int, "cell_id"); - AddSetting(GUIST_CStr, "font"); + AddSetting(GUIST_CStrW, "font"); AddSetting(GUIST_CGUISpriteInstance, "sprite"); AddSetting(GUIST_CGUISpriteInstance, "sprite_over"); AddSetting(GUIST_CGUISpriteInstance, "sprite_pressed"); @@ -63,11 +63,11 @@ void CButton::SetupText() debug_assert(m_GeneratedTexts.size()>=1); - CStr font; - if (GUI::GetSetting(this, "font", font) != PSRETURN_OK || font.empty()) + CStrW font; + if (GUI::GetSetting(this, "font", font) != PSRETURN_OK || font.empty()) // Use the default if none is specified // TODO Gee: (2004-08-14) Default should not be hard-coded, but be in styles! - font = "default"; + font = L"default"; CGUIString caption; GUI::GetSetting(this, "caption", caption); diff --git a/source/gui/CCheckBox.cpp b/source/gui/CCheckBox.cpp index 2ec8fadf7e..fbada0d05d 100644 --- a/source/gui/CCheckBox.cpp +++ b/source/gui/CCheckBox.cpp @@ -36,7 +36,7 @@ CCheckBox::CCheckBox() AddSetting(GUIST_CGUIString, "caption"); AddSetting(GUIST_int, "cell_id"); AddSetting(GUIST_bool, "checked"); - AddSetting(GUIST_CStr, "font"); + AddSetting(GUIST_CStrW, "font"); AddSetting(GUIST_CGUISpriteInstance, "sprite"); AddSetting(GUIST_CGUISpriteInstance, "sprite_over"); AddSetting(GUIST_CGUISpriteInstance, "sprite_pressed"); @@ -68,11 +68,11 @@ void CCheckBox::SetupText() debug_assert(m_GeneratedTexts.size()>=1); - CStr font; - if (GUI::GetSetting(this, "font", font) != PSRETURN_OK || font.empty()) + CStrW font; + if (GUI::GetSetting(this, "font", font) != PSRETURN_OK || font.empty()) // Use the default if none is specified // TODO Gee: (2004-08-14) Default should not be hard-coded, but be in styles! - font = "default"; + font = L"default"; float square_side; GUI::GetSetting(this, "square_side", square_side); @@ -115,12 +115,12 @@ void CCheckBox::Draw() ////////// float square_side, buffer_zone; - CStr font_name; + CStrW font_name; bool checked; int cell_id; GUI::GetSetting(this, "square_side", square_side); GUI::GetSetting(this, "buffer_zone", buffer_zone); - GUI::GetSetting(this, "font", font_name); + GUI::GetSetting(this, "font", font_name); GUI::GetSetting(this, "checked", checked); GUI::GetSetting(this, "cell_id", cell_id); diff --git a/source/gui/CDropDown.cpp b/source/gui/CDropDown.cpp index 567f9d8d78..396a5def64 100644 --- a/source/gui/CDropDown.cpp +++ b/source/gui/CDropDown.cpp @@ -35,7 +35,7 @@ CDropDown::CDropDown() : m_Open(false), m_HideScrollBar(false), m_ElementHighlig AddSetting(GUIST_float, "button_width"); AddSetting(GUIST_float, "dropdown_size"); AddSetting(GUIST_float, "dropdown_buffer"); -// AddSetting(GUIST_CStr, "font"); +// AddSetting(GUIST_CStrW, "font"); // AddSetting(GUIST_CGUISpriteInstance, "sprite"); // Background that sits around the size AddSetting(GUIST_CGUISpriteInstance, "sprite_list"); // Background of the drop down list AddSetting(GUIST_CGUISpriteInstance, "sprite2"); // Button that sits to the right diff --git a/source/gui/CGUI.cpp b/source/gui/CGUI.cpp index 90b7c66a82..0acb39406c 100644 --- a/source/gui/CGUI.cpp +++ b/source/gui/CGUI.cpp @@ -61,7 +61,7 @@ CGUI const double SELECT_DBLCLICK_RATE = 0.5; #include "ps/CLogger.h" -#define LOG_CATEGORY "gui" +#define LOG_CATEGORY L"gui" // Class for global JavaScript object @@ -94,7 +94,7 @@ InReaction CGUI::HandleEvent(const SDL_Event_* ev) IGUIObject* object = FindObjectByName(objectName); if (! object) { - LOG(CLogger::Error, LOG_CATEGORY, "Cannot find hotkeyed object '%s'", objectName.c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"Cannot find hotkeyed object '%hs'", objectName.c_str()); } else { @@ -275,7 +275,7 @@ InReaction CGUI::HandleEvent(const SDL_Event_* ev) catch (PSERROR_GUI& e) { UNUSED2(e); - debug_warn("CGUI::HandleEvent error"); + debug_warn(L"CGUI::HandleEvent error"); // TODO Gee: Handle } // JW: what's the difference between mPress and mDown? what's the code below responsible for? @@ -507,7 +507,7 @@ void CGUI::Draw() glPopMatrix(); // TODO Gee: Report error. - debug_warn("CGUI::Draw error"); + debug_warn(L"CGUI::Draw error"); return; } glPopMatrix(); @@ -548,7 +548,7 @@ void CGUI::Destroy() catch (PSERROR_GUI& e) { UNUSED2(e); - debug_warn("CGUI::Destroy error"); + debug_warn(L"CGUI::Destroy error"); // TODO Gee: Handle } @@ -967,7 +967,7 @@ void CGUI::DrawText(SGUIText &Text, const CColor &DefaultColor, } CFont* font = NULL; - CStr LastFontName; + CStrW LastFontName; for (std::vector::const_iterator it = Text.m_TextCalls.begin(); it != Text.m_TextCalls.end(); @@ -1033,20 +1033,19 @@ bool CGUI::GetPreDefinedColor(const CStr& name, CColor &Output) } } -void CGUI::ReportParseError(const char *str, ...) +void CGUI::ReportParseError(const wchar_t* str, ...) { va_list argp; - char buffer[512]; - memset(buffer,0,sizeof(buffer)); + wchar_t buffer[512]={0}; va_start(argp, str); - sys_vsnprintf(buffer, sizeof(buffer), str, argp); + sys_vswprintf(buffer, ARRAY_SIZE(buffer), str, argp); va_end(argp); // Print header if (m_Errors==0) { - LOG(CLogger::Error, LOG_CATEGORY, "*** GUI Tree Creation Errors:"); + LOG(CLogger::Error, LOG_CATEGORY, L"*** GUI Tree Creation Errors:"); } // Important, set ParseError to true @@ -1058,14 +1057,14 @@ void CGUI::ReportParseError(const char *str, ...) /** * @callgraph */ -void CGUI::LoadXmlFile(const std::string &Filename) +void CGUI::LoadXmlFile(const VfsPath& Filename) { // Reset parse error // we can later check if this has increased m_Errors = 0; CXeromyces XeroFile; - if (XeroFile.Load(Filename.c_str()) != PSRETURN_OK) + if (XeroFile.Load(Filename) != PSRETURN_OK) // Fail silently return; @@ -1102,13 +1101,13 @@ void CGUI::LoadXmlFile(const std::string &Filename) } else { - debug_warn("CGUI::LoadXmlFile error"); + debug_warn(L"CGUI::LoadXmlFile error"); // TODO Gee: Output in log } } catch (PSERROR_GUI& e) { - LOG(CLogger::Error, LOG_CATEGORY, "Errors loading GUI file %s (%d)", Filename.c_str(), e.getCode()); + LOG(CLogger::Error, LOG_CATEGORY, L"Errors loading GUI file %ls (%d)", Filename.string().c_str(), e.getCode()); return; } @@ -1133,7 +1132,7 @@ void CGUI::Xeromyces_ReadRootObjects(XMBElement Element, CXeromyces* pFile) XMBElementList children = Element.GetChildNodes(); for (int i=0; iLoadStyle(*this, argStyle); } @@ -1290,7 +1289,7 @@ void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec XMBAttribute attr = attributes.Item(i); // If value is "null", then it is equivalent as never being entered - if ((CStr)attr.Value == "null") + if (CStr(attr.Value) == "null") continue; // Ignore "type" and "style", we've already checked it @@ -1300,7 +1299,7 @@ void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec // Also the name needs some special attention if (attr.Name == attr_name) { - object->SetName((CStr)attr.Value); + object->SetName(CStr(attr.Value)); NameSet = true; continue; } @@ -1313,9 +1312,9 @@ void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec ManuallySetZ = true; // Try setting the value - if (object->SetSetting(pFile->GetAttributeString(attr.Name), (CStr)attr.Value, true) != PSRETURN_OK) + if (object->SetSetting(pFile->GetAttributeString(attr.Name), CStr(attr.Value), true) != PSRETURN_OK) { - ReportParseError("(object: %s) Can't set \"%s\" to \"%s\"", object->GetPresentableName().c_str(), pFile->GetAttributeString(attr.Name).c_str(), CStr(attr.Value).c_str()); + ReportParseError(L"(object: %hs) Can't set \"%hs\" to \"%hs\"", object->GetPresentableName().c_str(), pFile->GetAttributeString(attr.Name).c_str(), attr.Value.c_str()); // This is not a fatal error } @@ -1367,17 +1366,17 @@ void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec // Scripted element // Check for a 'file' parameter - CStr file (child.GetAttributes().GetNamedItem(attr_file)); + CStrW filename (child.GetAttributes().GetNamedItem(attr_file)); CStr code; // If there is a file, open it and use it as the code - if (! file.empty()) + if (! filename.empty()) { CVFSFile scriptfile; - if (scriptfile.Load(file) != PSRETURN_OK) + if (scriptfile.Load(filename) != PSRETURN_OK) { - LOG(CLogger::Error, LOG_CATEGORY, "Error opening action file '%s'", file.c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"Error opening action file '%ls'", filename.c_str()); throw PSERROR_GUI_JSOpenFailed(); } @@ -1385,9 +1384,9 @@ void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec } // Read the inline code (concatenating to the file code, if both are specified) - code += (CStr)child.GetText(); + code += CStr(child.GetText()); - CStr action = (CStr)child.GetAttributes().GetNamedItem(attr_on); + CStr action = CStr(child.GetAttributes().GetNamedItem(attr_on)); object->RegisterScriptHandler(action.LowerCase(), code, this); } else @@ -1395,7 +1394,7 @@ void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec // Try making the object read the tag. if (!object->HandleAdditionalChildren(child, pFile)) { - LOG(CLogger::Error, LOG_CATEGORY, "(object: %s) Reading unknown children for its type", object->GetPresentableName().c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"(object: %hs) Reading unknown children for its type", object->GetPresentableName().c_str()); } } } @@ -1408,7 +1407,7 @@ void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec // Set it automatically to 10 plus its parents if (pParent==NULL) { - debug_warn("CGUI::Xeromyces_ReadObject error"); + debug_warn(L"CGUI::Xeromyces_ReadObject error"); // TODO Gee: Report error } else @@ -1443,8 +1442,9 @@ void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec pParent->AddChild(object); } catch (PSERROR_GUI& e) - { - ReportParseError(e.what()); + { + CStrW what(e.what()); + ReportParseError(what.c_str()); } } @@ -1456,7 +1456,7 @@ void CGUI::Xeromyces_ReadScript(XMBElement Element, CXeromyces* pFile) // If there is a file specified, open and execute it if (! file.empty()) - g_ScriptingHost.RunScript(file, m_ScriptObject); + g_ScriptingHost.RunScript(CStrW(file), m_ScriptObject); // Execute inline scripts CStr code (Element.GetText()); @@ -1480,7 +1480,7 @@ void CGUI::Xeromyces_ReadSprite(XMBElement Element, CXeromyces* pFile) name = Element.GetAttributes().GetNamedItem( pFile->GetAttributeID("name") ); if (m_Sprites.find(name) != m_Sprites.end()) - LOG(CLogger::Warning, LOG_CATEGORY, "Sprite name '%s' used more than once; first definition will be discarded", (const char*)name); + LOG(CLogger::Warning, LOG_CATEGORY, L"Sprite name '%hs' used more than once; first definition will be discarded", name.c_str()); // // Read Children (the images) @@ -1510,7 +1510,7 @@ void CGUI::Xeromyces_ReadSprite(XMBElement Element, CXeromyces* pFile) } else { - debug_warn("Invalid data - DTD shouldn't allow this"); + debug_warn(L"Invalid data - DTD shouldn't allow this"); } } @@ -1556,17 +1556,14 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite if (attr_name == "texture") { - CStr TexFilename ("art/textures/ui/"); - TexFilename += attr_value; - - image.m_TextureName = TexFilename; + image.m_TextureName = VfsPath(L"art/textures/ui")/CStrW(attr_value); } else if (attr_name == "size") { CClientArea ca; if (!GUI::ParseString(attr_value, ca)) - ReportParseError("Error parsing '%s' (\"%s\")", attr_name.c_str(), attr_value.c_str()); + ReportParseError(L"Error parsing '%hs' (\"%hs\")", attr_name.c_str(), attr_value.c_str()); else image.m_Size = ca; } else @@ -1574,7 +1571,7 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite { CClientArea ca; if (!GUI::ParseString(attr_value, ca)) - ReportParseError("Error parsing '%s' (\"%s\")", attr_name.c_str(), attr_value.c_str()); + ReportParseError(L"Error parsing '%hs' (\"%hs\")", attr_name.c_str(), attr_value.c_str()); else image.m_TextureSize = ca; } else @@ -1582,7 +1579,7 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite { CRect rect; if (!GUI::ParseString(attr_value, rect)) - ReportParseError("Error parsing '%s' (\"%s\")", attr_name.c_str(), attr_value.c_str()); + ReportParseError(L"Error parsing '%hs' (\"%hs\")", attr_name.c_str(), attr_value.c_str()); else image.m_TexturePlacementInFile = rect; } else @@ -1590,7 +1587,7 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite { CSize size; if (!GUI::ParseString(attr_value, size)) - ReportParseError("Error parsing '%s' (\"%s\")", attr_name.c_str(), attr_value.c_str()); + ReportParseError(L"Error parsing '%hs' (\"%hs\")", attr_name.c_str(), attr_value.c_str()); else image.m_CellSize = size; } else @@ -1598,7 +1595,7 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite { float z_level; if (!GUI::ParseString(attr_value, z_level)) - ReportParseError("Error parsing '%s' (\"%s\")", attr_name.c_str(), attr_value.c_str()); + ReportParseError(L"Error parsing '%hs' (\"%hs\")", attr_name.c_str(), attr_value.c_str()); else image.m_DeltaZ = z_level/100.f; } else @@ -1606,7 +1603,7 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite { CColor color; if (!GUI::ParseString(attr_value, color)) - ReportParseError("Error parsing '%s' (\"%s\")", attr_name.c_str(), attr_value.c_str()); + ReportParseError(L"Error parsing '%hs' (\"%hs\")", attr_name.c_str(), attr_value.c_str()); else image.m_BackColor = color; } else @@ -1614,7 +1611,7 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite { CColor color; if (!GUI::ParseString(attr_value, color)) - ReportParseError("Error parsing '%s' (\"%s\")", attr_name.c_str(), attr_value.c_str()); + ReportParseError(L"Error parsing '%hs' (\"%hs\")", attr_name.c_str(), attr_value.c_str()); else image.m_BorderColor = color; } else @@ -1622,12 +1619,12 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite { bool b; if (!GUI::ParseString(attr_value, b)) - ReportParseError("Error parsing '%s' (\"%s\")", attr_name.c_str(), attr_value.c_str()); + ReportParseError(L"Error parsing '%hs' (\"%hs\")", attr_name.c_str(), attr_value.c_str()); else image.m_Border = b; } else { - debug_warn("Invalid data - DTD shouldn't allow this"); + debug_warn(L"Invalid data - DTD shouldn't allow this"); } } @@ -1645,7 +1642,7 @@ void CGUI::Xeromyces_ReadImage(XMBElement Element, CXeromyces* pFile, CGUISprite } else { - debug_warn("Invalid data - DTD shouldn't allow this"); + debug_warn(L"Invalid data - DTD shouldn't allow this"); } } @@ -1670,7 +1667,7 @@ void CGUI::Xeromyces_ReadEffects(XMBElement Element, CXeromyces* pFile, SGUIImag { \ CColor color; \ if (!GUI::ParseColor(attr_value, color, alpha)) \ - ReportParseError("Error parsing '%s' (\"%s\")", attr_name.c_str(), attr_value.c_str()); \ + ReportParseError(L"Error parsing '%hs' (\"%hs\")", attr_name.c_str(), attr_value.c_str()); \ else effects.m_##mem = color; \ } \ else @@ -1688,7 +1685,7 @@ void CGUI::Xeromyces_ReadEffects(XMBElement Element, CXeromyces* pFile, SGUIImag BOOL("grayscale", Greyscale) { - debug_warn("Invalid data - DTD shouldn't allow this"); + debug_warn(L"Invalid data - DTD shouldn't allow this"); } } } @@ -1755,7 +1752,7 @@ void CGUI::Xeromyces_ReadScrollBarStyle(XMBElement Element, CXeromyces* pFile) float f; if (!GUI::ParseString(attr_value, f)) { - ReportParseError("Error parsing '%s' (\"%s\")", attr_name.c_str(), attr_value.c_str()); + ReportParseError(L"Error parsing '%hs' (\"%hs\")", attr_name.c_str(), attr_value.c_str()); } scrollbar.m_Width = f; } @@ -1765,7 +1762,7 @@ void CGUI::Xeromyces_ReadScrollBarStyle(XMBElement Element, CXeromyces* pFile) float f; if (!GUI::ParseString(attr_value, f)) { - ReportParseError("Error parsing '%s' (\"%s\")", attr_name.c_str(), attr_value.c_str()); + ReportParseError(L"Error parsing '%hs' (\"%hs\")", attr_name.c_str(), attr_value.c_str()); } scrollbar.m_MinimumBarSize = f; } @@ -1840,7 +1837,7 @@ void CGUI::Xeromyces_ReadIcon(XMBElement Element, CXeromyces* pFile) { CSize size; if (!GUI::ParseString(attr_value, size)) - ReportParseError("Error parsing '%s' (\"%s\") inside .", attr_name.c_str(), attr_value.c_str()); + ReportParseError(L"Error parsing '%hs' (\"%hs\") inside .", attr_name.c_str(), attr_value.c_str()); icon.m_Size = size; } else @@ -1848,12 +1845,12 @@ void CGUI::Xeromyces_ReadIcon(XMBElement Element, CXeromyces* pFile) { int cell_id; if (!GUI::ParseString(attr_value, cell_id)) - ReportParseError("Error parsing '%s' (\"%s\") inside .", attr_name.c_str(), attr_value.c_str()); + ReportParseError(L"Error parsing '%hs' (\"%hs\") inside .", attr_name.c_str(), attr_value.c_str()); icon.m_CellID = cell_id; } else { - debug_warn("Invalid data - DTD shouldn't allow this"); + debug_warn(L"Invalid data - DTD shouldn't allow this"); } } @@ -1904,7 +1901,7 @@ void CGUI::Xeromyces_ReadColor(XMBElement Element, CXeromyces* pFile) // Try setting color to value if (!color.ParseString(value, 255.f)) { - ReportParseError("Unable to create custom color '%s'. Invalid color syntax.", name.c_str()); + ReportParseError(L"Unable to create custom color '%hs'. Invalid color syntax.", name.c_str()); } else { diff --git a/source/gui/CGUI.h b/source/gui/CGUI.h index 603233fdaf..e492e89693 100644 --- a/source/gui/CGUI.h +++ b/source/gui/CGUI.h @@ -181,7 +181,7 @@ public: * * @param Filename Name of file */ - void LoadXmlFile(const std::string &Filename); + void LoadXmlFile(const VfsPath& Filename); /** * Checks if object exists and return true or false accordingly @@ -303,7 +303,7 @@ private: * * @param str Error message */ - void ReportParseError(const char *str, ...) PRINTF_ARGS(2); + void ReportParseError(const wchar_t* str, ...) PRINTF_ARGS(2); /** * You input the name of the object type, and let's diff --git a/source/gui/CGUIScrollBarVertical.cpp b/source/gui/CGUIScrollBarVertical.cpp index 2e9b5bf1a7..4a3d964fe3 100644 --- a/source/gui/CGUIScrollBarVertical.cpp +++ b/source/gui/CGUIScrollBarVertical.cpp @@ -23,7 +23,7 @@ IGUIScrollBar #include "GUI.h" #include "ps/CLogger.h" -#define LOG_CATEGORY "gui" +#define LOG_CATEGORY L"gui" CGUIScrollBarVertical::CGUIScrollBarVertical() diff --git a/source/gui/CGUISprite.h b/source/gui/CGUISprite.h index d239e59ed8..ab29ed6251 100644 --- a/source/gui/CGUISprite.h +++ b/source/gui/CGUISprite.h @@ -80,7 +80,7 @@ struct SGUIImage SGUIImage() : m_Effects(NULL), m_Border(false), m_DeltaZ(0.f) {} // Filename of the texture - CStr m_TextureName; + VfsPath m_TextureName; // Image placement (relative to object) CClientArea m_Size; diff --git a/source/gui/CInput.cpp b/source/gui/CInput.cpp index 896f3eede5..38b76023b0 100644 --- a/source/gui/CInput.cpp +++ b/source/gui/CInput.cpp @@ -33,7 +33,7 @@ CInput #include "ps/CLogger.h" #include "ps/Globals.h" -#define LOG_CATEGORY "gui" +#define LOG_CATEGORY L"gui" //------------------------------------------------------------------- @@ -44,7 +44,7 @@ CInput::CInput() : m_iBufferPos(-1), m_iBufferPos_Tail(-1), m_SelectingText(fals AddSetting(GUIST_float, "buffer_zone"); AddSetting(GUIST_CStrW, "caption"); AddSetting(GUIST_int, "cell_id"); - AddSetting(GUIST_CStr, "font"); + AddSetting(GUIST_CStrW, "font"); AddSetting(GUIST_int, "max_length"); AddSetting(GUIST_bool, "multiline"); AddSetting(GUIST_bool, "scrollbar"); @@ -647,10 +647,10 @@ void CInput::Draw() if (GetGUI()) { - CStr font_name; + CStrW font_name; CColor color, color_selected; //CStrW caption; - GUI::GetSetting(this, "font", font_name); + GUI::GetSetting(this, "font", font_name); GUI::GetSetting(this, "textcolor", color); GUI::GetSetting(this, "textcolor_selected", color_selected); @@ -1022,15 +1022,15 @@ void CInput::Draw() void CInput::UpdateText(int from, int to_before, int to_after) { CStrW caption; - CStr font_name; + CStrW font_name; float buffer_zone; bool multiline; - GUI::GetSetting(this, "font", font_name); + GUI::GetSetting(this, "font", font_name); GUI::GetSetting(this, "caption", caption); GUI::GetSetting(this, "buffer_zone", buffer_zone); GUI::GetSetting(this, "multiline", multiline); - if (font_name == CStr()) + if (font_name == CStrW()) { // Destroy everything stored, there's no font, so there can be // no data. @@ -1428,9 +1428,9 @@ int CInput::GetMouseHoveringTextPosition() if (multiline) { - CStr font_name; + CStrW font_name; bool scrollbar; - GUI::GetSetting(this, "font", font_name); + GUI::GetSetting(this, "font", font_name); GUI::GetSetting(this, "scrollbar", scrollbar); float scroll=0.f; @@ -1580,9 +1580,9 @@ void CInput::UpdateAutoScroll() // Autoscrolling up and down if (multiline) { - CStr font_name; + CStrW font_name; bool scrollbar; - GUI::GetSetting(this, "font", font_name); + GUI::GetSetting(this, "font", font_name); GUI::GetSetting(this, "scrollbar", scrollbar); float scroll=0.f; diff --git a/source/gui/CList.cpp b/source/gui/CList.cpp index 997565d636..0234186ac0 100644 --- a/source/gui/CList.cpp +++ b/source/gui/CList.cpp @@ -36,7 +36,7 @@ CList::CList() AddSetting(GUIST_float, "buffer_zone"); //AddSetting(GUIST_CGUIString, "caption"); will it break removing this? If I know my system, then no, but test just in case TODO (Gee). - AddSetting(GUIST_CStr, "font"); + AddSetting(GUIST_CStrW, "font"); AddSetting(GUIST_bool, "scrollbar"); AddSetting(GUIST_CStr, "scrollbar_style"); AddSetting(GUIST_CGUISpriteInstance, "sprite"); @@ -74,7 +74,7 @@ void CList::SetupText() CGUIList *pList; GUI::GetSettingPointer(this, "list", pList); - //LOG(CLogger::Error, LOG_CATEGORY, "SetupText() %s", GetPresentableName().c_str()); + //LOG(CLogger::Error, LOG_CATEGORY, L"SetupText() %hs", GetPresentableName().c_str()); //debug_assert(m_GeneratedTexts.size()>=1); @@ -91,11 +91,11 @@ void CList::SetupText() } m_GeneratedTexts.clear(); - CStr font; - if (GUI::GetSetting(this, "font", font) != PSRETURN_OK || font.empty()) + CStrW font; + if (GUI::GetSetting(this, "font", font) != PSRETURN_OK || font.empty()) // Use the default if none is specified // TODO Gee: (2004-08-14) Don't define standard like this. Do it with the default style. - font = "default"; + font = L"default"; //CGUIString caption; bool scrollbar; @@ -433,7 +433,7 @@ bool CList::HandleAdditionalChildren(const XMBElement& child, CXeromyces* pFile) if (child.GetNodeName() == elmt_item) { - AddItem((CStr)child.GetText()); + AddItem(CStr(child.GetText())); return true; } diff --git a/source/gui/CText.cpp b/source/gui/CText.cpp index 75d8f42e6b..8f6a1730bd 100644 --- a/source/gui/CText.cpp +++ b/source/gui/CText.cpp @@ -34,7 +34,7 @@ CText::CText() AddSetting(GUIST_float, "buffer_zone"); AddSetting(GUIST_CGUIString, "caption"); AddSetting(GUIST_int, "cell_id"); - AddSetting(GUIST_CStr, "font"); + AddSetting(GUIST_CStrW, "font"); AddSetting(GUIST_bool, "scrollbar"); AddSetting(GUIST_CStr, "scrollbar_style"); AddSetting(GUIST_CGUISpriteInstance, "sprite"); @@ -68,11 +68,11 @@ void CText::SetupText() debug_assert(m_GeneratedTexts.size()>=1); - CStr font; - if (GUI::GetSetting(this, "font", font) != PSRETURN_OK || font.empty()) + CStrW font; + if (GUI::GetSetting(this, "font", font) != PSRETURN_OK || font.empty()) // Use the default if none is specified // TODO Gee: (2004-08-14) Don't define standard like this. Do it with the default style. - font = "default"; + font = L"default"; CGUIString caption; bool scrollbar; diff --git a/source/gui/CTooltip.cpp b/source/gui/CTooltip.cpp index de4ebceb38..51a1401d1d 100644 --- a/source/gui/CTooltip.cpp +++ b/source/gui/CTooltip.cpp @@ -29,7 +29,7 @@ CTooltip::CTooltip() // If the tooltip is an object by itself: AddSetting(GUIST_float, "buffer_zone"); AddSetting(GUIST_CGUIString, "caption"); - AddSetting(GUIST_CStr, "font"); + AddSetting(GUIST_CStrW, "font"); AddSetting(GUIST_CGUISpriteInstance, "sprite"); AddSetting(GUIST_int, "delay"); AddSetting(GUIST_CColor, "textcolor"); @@ -64,9 +64,9 @@ void CTooltip::SetupText() debug_assert(m_GeneratedTexts.size()==1); - CStr font; - if (GUI::GetSetting(this, "font", font) != PSRETURN_OK || font.empty()) - font = "default"; + CStrW font; + if (GUI::GetSetting(this, "font", font) != PSRETURN_OK || font.empty()) + font = L"default"; float buffer_zone = 0.f; GUI::GetSetting(this, "buffer_zone", buffer_zone); @@ -111,7 +111,7 @@ void CTooltip::SetupText() size.pixel.bottom = size.pixel.top + textwidth; break; default: - debug_warn("Invalid EVAlign!"); + debug_warn(L"Invalid EVAlign!"); } diff --git a/source/gui/GUIRenderer.cpp b/source/gui/GUIRenderer.cpp index f52b9e4f21..d413dfb8cb 100644 --- a/source/gui/GUIRenderer.cpp +++ b/source/gui/GUIRenderer.cpp @@ -24,7 +24,7 @@ #include "lib/tex/tex.h" #include "ps/CLogger.h" -#define LOG_CATEGORY "gui" +#define LOG_CATEGORY L"gui" using namespace GUIRenderer; @@ -104,7 +104,7 @@ public: // Otherwise, complain. else { - LOG(CLogger::Warning, "gui", "add_color effect has some components above 127 and some below -127 - colours will be clamped"); + LOG(CLogger::Warning, LOG_CATEGORY, L"add_color effect has some components above 127 and some below -127 - colours will be clamped"); m_Color = CColor(c.r+0.5f, c.g+0.5f, c.b+0.5f, c.a+0.5f); m_Method = ADD_SIGNED; } @@ -183,7 +183,7 @@ public: ; else // Oops - trying to multiply by >4 - LOG(CLogger::Warning, "gui", "multiply_color effect has a component >1020 - colours will be clamped"); + LOG(CLogger::Warning, LOG_CATEGORY, L"multiply_color effect has a component >1020 - colours will be clamped"); m_Color = CColor(c.r/4.f, c.g/4.f, c.b/4.f, c.a); m_Scale = 4; @@ -369,7 +369,7 @@ void GUIRenderer::UpdateDrawCallCache(DrawCalls &Calls, const CStr& SpriteName, if (SpriteName.substr(0, 10) == "stretched:") { SGUIImage Image; - Image.m_TextureName = "art/textures/ui/" + SpriteName.substr(10); + Image.m_TextureName = VfsPath(L"art/textures/ui")/CStrW(SpriteName.substr(10)); CClientArea ca("0 0 100% 100%"); Image.m_Size = ca; Image.m_TextureSize = ca; @@ -385,7 +385,7 @@ void GUIRenderer::UpdateDrawCallCache(DrawCalls &Calls, const CStr& SpriteName, else { // Otherwise, just complain and give up: - LOG(CLogger::Error, LOG_CATEGORY, "Trying to use a sprite that doesn't exist (\"%s\").", (const char*)SpriteName); + LOG(CLogger::Error, LOG_CATEGORY, L"Trying to use a sprite that doesn't exist (\"%hs\").", SpriteName.c_str()); return; } } @@ -414,7 +414,7 @@ void GUIRenderer::UpdateDrawCallCache(DrawCalls &Calls, const CStr& SpriteName, Handle h = ogl_tex_load(cit->m_TextureName); if (h <= 0) { - LOG(CLogger::Error, LOG_CATEGORY, "Error reading texture '%s': %ld", (const char*)cit->m_TextureName, (long)h); + LOG(CLogger::Error, LOG_CATEGORY, L"Error reading texture '%ls': %ld", cit->m_TextureName.string().c_str(), (long)h); return; } @@ -423,7 +423,7 @@ void GUIRenderer::UpdateDrawCallCache(DrawCalls &Calls, const CStr& SpriteName, int err = ogl_tex_upload(h); if (err < 0) { - LOG(CLogger::Error, LOG_CATEGORY, "Error uploading texture '%s': %d", (const char*)cit->m_TextureName, err); + LOG(CLogger::Error, LOG_CATEGORY, L"Error uploading texture '%ls': %d", cit->m_TextureName.string().c_str(), err); return; } diff --git a/source/gui/GUITooltip.cpp b/source/gui/GUITooltip.cpp index 33f8ba65ec..0482d5a98d 100644 --- a/source/gui/GUITooltip.cpp +++ b/source/gui/GUITooltip.cpp @@ -65,6 +65,8 @@ * If now > target time, switch to 'STATIONARY, NO TOOLTIP' */ +#define LOG_CATEGORY L"gui" + enum { ST_IN_MOTION, @@ -118,7 +120,7 @@ void GUITooltip::ShowTooltip(IGUIObject* obj, CPos pos, const CStr& style, CGUI* IGUIObject* tooltipobj = gui->FindObjectByName("__tooltip_"+style); if (! tooltipobj) { - LOG_ONCE(CLogger::Error, "gui", "Cannot find tooltip named '%s'", (const char*)style); + LOG_ONCE(CLogger::Error, LOG_CATEGORY, L"Cannot find tooltip named '%hs'", style.c_str()); return; } @@ -131,7 +133,7 @@ void GUITooltip::ShowTooltip(IGUIObject* obj, CPos pos, const CStr& style, CGUI* usedobj = gui->FindObjectByName(usedObjectName); if (! usedobj) { - LOG_ONCE(CLogger::Error, "gui", "Cannot find object named '%s' used by tooltip '%s'", (const char*)usedObjectName, (const char*)style); + LOG_ONCE(CLogger::Error, LOG_CATEGORY, L"Cannot find object named '%hs' used by tooltip '%hs'", usedObjectName.c_str(), style.c_str()); return; } @@ -146,20 +148,20 @@ void GUITooltip::ShowTooltip(IGUIObject* obj, CPos pos, const CStr& style, CGUI* // Store mouse position inside the CTooltip if (GUI::SetSetting(usedobj, "_mousepos", pos) != PSRETURN_OK) - debug_warn("Failed to set tooltip mouse position"); + debug_warn(L"Failed to set tooltip mouse position"); } // Retrieve object's 'tooltip' setting CStr text; if (GUI::GetSetting(obj, "tooltip", text) != PSRETURN_OK) - debug_warn("Failed to retrieve tooltip text"); // shouldn't fail + debug_warn(L"Failed to retrieve tooltip text"); // shouldn't fail // Do some minimal processing ("\n" -> newline, etc) text = text.UnescapeBackslashes(); // Set tooltip's caption if (usedobj->SetSetting("caption", text) != PSRETURN_OK) - debug_warn("Failed to set tooltip caption"); // shouldn't fail + debug_warn(L"Failed to set tooltip caption"); // shouldn't fail // Make the tooltip object regenerate its text usedobj->HandleMessage(SGUIMessage(GUIM_SETTINGS_UPDATED, "caption")); @@ -174,7 +176,7 @@ void GUITooltip::HideTooltip(const CStr& style, CGUI* gui) IGUIObject* tooltipobj = gui->FindObjectByName("__tooltip_"+style); if (! tooltipobj) { - LOG_ONCE(CLogger::Error, "gui", "Cannot find tooltip named '%s'", (const char*)style); + LOG_ONCE(CLogger::Error, LOG_CATEGORY, L"Cannot find tooltip named '%hs'", style.c_str()); return; } @@ -185,7 +187,7 @@ void GUITooltip::HideTooltip(const CStr& style, CGUI* gui) IGUIObject* usedobj = gui->FindObjectByName(usedObjectName); if (! usedobj) { - LOG_ONCE(CLogger::Error, "gui", "Cannot find object named '%s' used by tooltip '%s'", (const char*)usedObjectName, (const char*)style); + LOG_ONCE(CLogger::Error, LOG_CATEGORY, L"Cannot find object named '%hs' used by tooltip '%hs'", usedObjectName.c_str(), style.c_str()); return; } @@ -215,7 +217,7 @@ static int GetTooltipDelay(CStr& style, CGUI* gui) IGUIObject* tooltipobj = gui->FindObjectByName("__tooltip_"+style); if (! tooltipobj) { - LOG_ONCE(CLogger::Error, "gui", "Cannot find tooltip object named '%s'", (const char*)style); + LOG_ONCE(CLogger::Error, LOG_CATEGORY, L"Cannot find tooltip object named '%hs'", style.c_str()); return delay; } GUI::GetSetting(tooltipobj, "delay", delay); diff --git a/source/gui/GUItext.cpp b/source/gui/GUItext.cpp index 30dbe77ed5..f9470b3c77 100644 --- a/source/gui/GUItext.cpp +++ b/source/gui/GUItext.cpp @@ -26,7 +26,7 @@ GUI text #include "ps/Parser.h" #include -#define LOG_CATEGORY "gui" +#define LOG_CATEGORY L"gui" #include "ps/Font.h" @@ -110,7 +110,7 @@ void CGUIString::GenerateTextCall(SFeedback &Feedback, } else if (pObject) { - LOG(CLogger::Error, LOG_CATEGORY, "Trying to use an [imgleft]-tag with an undefined icon (\"%s\").", itTextChunk->m_Tags[0].m_TagValue.c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"Trying to use an [imgleft]-tag with an undefined icon (\"%hs\").", itTextChunk->m_Tags[0].m_TagValue.c_str()); } } else @@ -123,7 +123,7 @@ void CGUIString::GenerateTextCall(SFeedback &Feedback, } else if (pObject) { - LOG(CLogger::Error, LOG_CATEGORY, "Trying to use an [imgright]-tag with an undefined icon (\"%s\").", itTextChunk->m_Tags[0].m_TagValue.c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"Trying to use an [imgright]-tag with an undefined icon (\"%hs\").", itTextChunk->m_Tags[0].m_TagValue.c_str()); } } else @@ -161,7 +161,7 @@ void CGUIString::GenerateTextCall(SFeedback &Feedback, CSize displacement; // Parse the value if (!GUI::ParseString(itTextChunk->m_Tags[0].m_TagAdditionalValue, displacement)) - LOG(CLogger::Error, LOG_CATEGORY, "Error parsing 'displace' value for tag [ICON]"); + LOG(CLogger::Error, LOG_CATEGORY, L"Error parsing 'displace' value for tag [ICON]"); else SpriteCall.m_Area += displacement; } @@ -180,7 +180,7 @@ void CGUIString::GenerateTextCall(SFeedback &Feedback, } else if (pObject) { - LOG(CLogger::Error, LOG_CATEGORY, "Trying to use an [icon]-tag with an undefined icon (\"%s\").", itTextChunk->m_Tags[0].m_TagValue.c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"Trying to use an [icon]-tag with an undefined icon (\"%hs\").", itTextChunk->m_Tags[0].m_TagValue.c_str()); } } } @@ -209,14 +209,14 @@ void CGUIString::GenerateTextCall(SFeedback &Feedback, if (!GUI::ParseString(it2->m_TagValue, TextCall.m_Color)) { if (pObject) - LOG(CLogger::Error, LOG_CATEGORY, "Error parsing the value of a [color]-tag in GUI text when reading object \"%s\".", pObject->GetPresentableName().c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"Error parsing the value of a [color]-tag in GUI text when reading object \"%hs\".", pObject->GetPresentableName().c_str()); } } else if (it2->m_TagType == CGUIString::TextChunk::Tag::TAG_FONT) { // TODO Gee: (2004-08-15) Check if Font exists? - TextCall.m_Font = it2->m_TagValue; + TextCall.m_Font = CStrW(it2->m_TagValue); } } @@ -411,7 +411,7 @@ void CGUIString::SetValue(const CStrW& str) } else { - LOG(CLogger::Warning, LOG_CATEGORY, "Trying to declare an additional attribute ('%s') in a [%s]-tag, which the tag isn't accepting", str.c_str(), Str_TagType.c_str()); + LOG(CLogger::Warning, LOG_CATEGORY, L"Trying to declare an additional attribute ('%hs') in a [%hs]-tag, which the tag isn't accepting", str.c_str(), Str_TagType.c_str()); } } @@ -590,15 +590,15 @@ void CGUIString::SetValue(const CStrW& str) #if 0 for (int i=0; i<(int)m_Words.size(); ++i) { - LOG(CLogger::Normal, LOG_CATEGORY, "m_Words[%d] = %d", i, m_Words[i]); + LOG(CLogger::Normal, LOG_CATEGORY, L"m_Words[%d] = %d", i, m_Words[i]); } for (int i=0; i<(int)m_TextChunks.size(); ++i) { - LOG(CLogger::Normal, LOG_CATEGORY, "m_TextChunk[%d] = [%d,%d]", i, m_TextChunks[i].m_From, m_TextChunks[i].m_To); + LOG(CLogger::Normal, LOG_CATEGORY, L"m_TextChunk[%d] = [%d,%d]", i, m_TextChunks[i].m_From, m_TextChunks[i].m_To); for (int j=0; j<(int)m_TextChunks[i].m_Tags.size(); ++j) { - LOG(CLogger::Normal, LOG_CATEGORY, "--Tag: %d \"%s\"", (int)m_TextChunks[i].m_Tags[j].m_TagType, m_TextChunks[i].m_Tags[j].m_TagValue.c_str()); + LOG(CLogger::Normal, LOG_CATEGORY, L"--Tag: %d \"%hs\"", (int)m_TextChunks[i].m_Tags[j].m_TagType, m_TextChunks[i].m_Tags[j].m_TagValue.c_str()); } } #endif diff --git a/source/gui/GUItext.h b/source/gui/GUItext.h index 83a274bbde..bea9db92fe 100644 --- a/source/gui/GUItext.h +++ b/source/gui/GUItext.h @@ -120,7 +120,7 @@ struct SGUIText /** * Font name */ - CStr m_Font; + CStrW m_Font; /** * Settings diff --git a/source/gui/GUIutil.cpp b/source/gui/GUIutil.cpp index ccdd00e0e0..587e184b81 100644 --- a/source/gui/GUIutil.cpp +++ b/source/gui/GUIutil.cpp @@ -27,7 +27,7 @@ GUI utilities extern int g_yres; #include "ps/CLogger.h" -#define LOG_CATEGORY "gui" +#define LOG_CATEGORY L"gui" template <> @@ -317,7 +317,7 @@ PSRETURN GUI::GetSettingPointer(const IGUIObject *pObject, const CStr& Settin std::map::const_iterator it = pObject->m_Settings.find(Setting); if (it == pObject->m_Settings.end()) { - LOG(CLogger::Warning, LOG_CATEGORY, "setting %s was not found on object %s", + LOG(CLogger::Warning, LOG_CATEGORY, L"setting %hs was not found on object %hs", Setting.c_str(), pObject->GetPresentableName().c_str()); return PSRETURN_GUI_InvalidSetting; @@ -354,7 +354,7 @@ PSRETURN GUI::SetSetting(IGUIObject *pObject, const CStr& Setting, if (!pObject->SettingExists(Setting)) { - LOG(CLogger::Warning, LOG_CATEGORY, "setting %s was not found on object %s", + LOG(CLogger::Warning, LOG_CATEGORY, L"setting %hs was not found on object %hs", Setting.c_str(), pObject->GetPresentableName().c_str()); return PSRETURN_GUI_InvalidSetting; diff --git a/source/gui/IGUIObject.cpp b/source/gui/IGUIObject.cpp index c7a8f34981..e45a57f17c 100644 --- a/source/gui/IGUIObject.cpp +++ b/source/gui/IGUIObject.cpp @@ -28,7 +28,7 @@ IGUIObject #include "gui/scripting/JSInterface_GUITypes.h" #include "ps/CLogger.h" -#define LOG_CATEGORY "gui" +#define LOG_CATEGORY L"gui" extern int g_xres, g_yres; @@ -82,7 +82,7 @@ IGUIObject::~IGUIObject() #include "GUItypes.h" #undef TYPE default: - debug_warn("Invalid setting type"); + debug_warn(L"Invalid setting type"); } } } @@ -186,7 +186,7 @@ void IGUIObject::AddSetting(const EGUISettingType &Type, const CStr& Name) #include "GUItypes.h" default: - debug_warn("IGUIObject::AddSetting failed, type not recognized!"); + debug_warn(L"IGUIObject::AddSetting failed, type not recognized!"); break; } } @@ -360,7 +360,7 @@ void IGUIObject::LoadStyle(CGUI &GUIinstance, const CStr& StyleName) } else { - debug_warn("IGUIObject::LoadStyle failed"); + debug_warn(L"IGUIObject::LoadStyle failed"); } } @@ -511,7 +511,7 @@ void IGUIObject::ScriptEvent(const CStr& Action) JSBool ok = JS_CallFunctionValue(g_ScriptingHost.getContext(), jsGuiObject, OBJECT_TO_JSVAL(*it->second), 1, paramData, &result); if (!ok) { - JS_ReportError(g_ScriptingHost.getContext(), "Errors executing script action \"%s\"", Action.c_str()); + JS_ReportError(g_ScriptingHost.getContext(), "Errors executing script action \"%hs\"", Action.c_str()); } // Allow the temporary parameters to be garbage-collected @@ -563,7 +563,7 @@ bool IGUIObject::IsRootObject() const PSRETURN IGUIObject::LogInvalidSettings(const CStr8 &Setting) const { - LOG(CLogger::Warning, LOG_CATEGORY, "IGUIObject: setting %s was not found on an object", + LOG(CLogger::Warning, LOG_CATEGORY, L"IGUIObject: setting %hs was not found on an object", Setting.c_str()); return PSRETURN_GUI_InvalidSetting; } diff --git a/source/gui/IGUITextOwner.cpp b/source/gui/IGUITextOwner.cpp index 36abf7256f..6f566ffb6d 100644 --- a/source/gui/IGUITextOwner.cpp +++ b/source/gui/IGUITextOwner.cpp @@ -78,7 +78,7 @@ void IGUITextOwner::Draw(const int &index, const CColor &color, const CPos &pos, { if (index < 0 || index >= (int)m_GeneratedTexts.size()) { - debug_warn("Trying to draw a Text Index within a IGUITextOwner that doesn't exist"); + debug_warn(L"Trying to draw a Text Index within a IGUITextOwner that doesn't exist"); return; } @@ -108,7 +108,7 @@ void IGUITextOwner::CalculateTextPosition(CRect &ObjSize, CPos &TextPos, SGUITex TextPos.x = ObjSize.right - Text.m_Size.cx; break; default: - debug_warn("Broken EAlign in CButton::SetupText()"); + debug_warn(L"Broken EAlign in CButton::SetupText()"); break; } @@ -125,7 +125,7 @@ void IGUITextOwner::CalculateTextPosition(CRect &ObjSize, CPos &TextPos, SGUITex TextPos.y = ObjSize.bottom - Text.m_Size.cy; break; default: - debug_warn("Broken EVAlign in CButton::SetupText()"); + debug_warn(L"Broken EVAlign in CButton::SetupText()"); break; } } diff --git a/source/gui/MiniMap.cpp b/source/gui/MiniMap.cpp index db58975633..da6beeb624 100644 --- a/source/gui/MiniMap.cpp +++ b/source/gui/MiniMap.cpp @@ -177,7 +177,7 @@ void CMiniMap::SetCameraPos() } void CMiniMap::FireWorldClickEvent(int button, int clicks) { - //debug_printf("FireWorldClickEvent: button %d, clicks %d\n", button, clicks); + //debug_printf(L"FireWorldClickEvent: button %d, clicks %d\n", button, clicks); CPos MousePos = GetMousePos(); CVector2D Destination; diff --git a/source/gui/scripting/JSInterface_IGUIObject.cpp b/source/gui/scripting/JSInterface_IGUIObject.cpp index 768cc86100..7b488140c3 100644 --- a/source/gui/scripting/JSInterface_IGUIObject.cpp +++ b/source/gui/scripting/JSInterface_IGUIObject.cpp @@ -111,7 +111,7 @@ JSBool JSI_IGUIObject::getProperty(JSContext* cx, JSObject* obj, jsval id, jsval EGUISettingType Type; if (e->GetSettingType(propName, Type) != PSRETURN_OK) { - JS_ReportError(cx, "Invalid GUIObject property '%s'", propName.c_str()); + JS_ReportError(cx, "Invalid GUIObject property '%hs'", propName.c_str()); return JS_FALSE; } @@ -182,7 +182,7 @@ JSBool JSI_IGUIObject::getProperty(JSContext* cx, JSObject* obj, jsval id, jsval } catch (PSERROR_Scripting_ConversionFailed) { - debug_warn("Error creating size object!"); + debug_warn(L"Error creating size object!"); break; } @@ -232,7 +232,7 @@ JSBool JSI_IGUIObject::getProperty(JSContext* cx, JSObject* obj, jsval id, jsval case EAlign_Left: word = "left"; break; case EAlign_Right: word = "right"; break; case EAlign_Center: word = "center"; break; - default: debug_warn("Invalid EAlign!"); word = "error"; break; + default: debug_warn(L"Invalid EAlign!"); word = "error"; break; } *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, word)); break; @@ -248,7 +248,7 @@ JSBool JSI_IGUIObject::getProperty(JSContext* cx, JSObject* obj, jsval id, jsval case EVAlign_Top: word = "top"; break; case EVAlign_Bottom: word = "bottom"; break; case EVAlign_Center: word = "center"; break; - default: debug_warn("Invalid EVAlign!"); word = "error"; break; + default: debug_warn(L"Invalid EVAlign!"); word = "error"; break; } *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, word)); break; @@ -273,8 +273,8 @@ JSBool JSI_IGUIObject::getProperty(JSContext* cx, JSObject* obj, jsval id, jsval } default: - JS_ReportError(cx, "Setting '%s' uses an unimplemented type", propName.c_str()); - debug_warn("This shouldn't happen"); + JS_ReportError(cx, "Setting '%hs' uses an unimplemented type", propName.c_str()); + debug_assert(0); return JS_FALSE; } @@ -313,7 +313,7 @@ JSBool JSI_IGUIObject::setProperty(JSContext* cx, JSObject* obj, jsval id, jsval EGUISettingType Type; if (e->GetSettingType(propName, Type) != PSRETURN_OK) { - JS_ReportError(cx, "Invalid setting '%s'", propName.c_str()); + JS_ReportError(cx, "Invalid setting '%hs'", propName.c_str()); return JS_TRUE; } @@ -429,7 +429,7 @@ JSBool JSI_IGUIObject::setProperty(JSContext* cx, JSObject* obj, jsval id, jsval { if (e->SetSetting(propName, JS_GetStringBytes(JS_ValueToString(cx, *vp))) != PSRETURN_OK) { - JS_ReportError(cx, "Invalid value for setting '%s'", propName.c_str()); + JS_ReportError(cx, "Invalid value for setting '%hs'", propName.c_str()); return JS_FALSE; } } @@ -466,7 +466,7 @@ JSBool JSI_IGUIObject::setProperty(JSContext* cx, JSObject* obj, jsval id, jsval { if (e->SetSetting(propName, JS_GetStringBytes(JS_ValueToString(cx, *vp))) != PSRETURN_OK) { - JS_ReportError(cx, "Invalid value for setting '%s'", propName.c_str()); + JS_ReportError(cx, "Invalid value for setting '%hs'", propName.c_str()); return JS_FALSE; } } @@ -531,7 +531,7 @@ JSBool JSI_IGUIObject::setProperty(JSContext* cx, JSObject* obj, jsval id, jsval // TODO Gee: (2004-09-01) EAlign and EVAlign too. default: - JS_ReportError(cx, "Setting '%s' uses an unimplemented type", propName.c_str()); + JS_ReportError(cx, "Setting '%hs' uses an unimplemented type", propName.c_str()); break; } diff --git a/source/i18n/BufferVariable.cpp b/source/i18n/BufferVariable.cpp index e32b025774..2e340df409 100644 --- a/source/i18n/BufferVariable.cpp +++ b/source/i18n/BufferVariable.cpp @@ -136,7 +136,7 @@ bool I18n::operator== (BufferVariable& a, BufferVariable& b) case vartype_rawstring: return *static_cast(&a) == *static_cast(&b); } - debug_warn("Invalid buffer variable vartype"); + debug_warn(L"Invalid buffer variable vartype"); return false; } diff --git a/source/i18n/CLocale.cpp b/source/i18n/CLocale.cpp index c90c78b33c..b2723f4705 100644 --- a/source/i18n/CLocale.cpp +++ b/source/i18n/CLocale.cpp @@ -25,7 +25,7 @@ #include #include "ps/CLogger.h" -#define LOG_CATEGORY "i18n" +#define LOG_CATEGORY L"i18n" using namespace I18n; @@ -154,7 +154,7 @@ bool CLocale::LoadStrings(const char* data) } default: // Argh! - debug_warn("Invalid function parameter type"); + debug_warn(L"Invalid function parameter type"); } } @@ -164,7 +164,7 @@ bool CLocale::LoadStrings(const char* data) } default: // Argh! - debug_warn("Invalid translation string section type"); + debug_warn(L"Invalid translation string section type"); } } } @@ -182,19 +182,19 @@ bool CLocale::LoadFunctions(const char* data, size_t len, const char* filename) if (len < 2) { - LOG(CLogger::Error, LOG_CATEGORY, "I18n: Functions file '%s' is too short", filename); + LOG(CLogger::Error, LOG_CATEGORY, L"I18n: Functions file '%hs' is too short", filename); return false; } if (*(jschar*)data != 0xFEFF) { - LOG(CLogger::Error, LOG_CATEGORY, "I18n: Functions file '%s' has invalid Unicode format (lacking little-endian BOM)", filename); + LOG(CLogger::Error, LOG_CATEGORY, L"I18n: Functions file '%hs' has invalid Unicode format (lacking little-endian BOM)", filename); return false; } if (! Script.ExecuteCode((jschar*)(data+2), len/2, filename)) { - LOG(CLogger::Error, LOG_CATEGORY, "I18n: JS errors in functions file '%s'", filename); + LOG(CLogger::Error, LOG_CATEGORY, L"I18n: JS errors in functions file '%hs'", filename); return false; } @@ -213,7 +213,7 @@ bool CLocale::LoadDictionary(const char* data) if (dict.DictProperties.size() && PropertyCount != dict.DictProperties.size()) { - LOG(CLogger::Error, LOG_CATEGORY, "I18n: Multiple dictionary files loaded with the name ('%ls') and different properties", DictName.c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"I18n: Multiple dictionary files loaded with the name ('%ls') and different properties", DictName.c_str()); return false; // TODO: Check headings to make sure they're identical (or handle them more cleverly) } @@ -260,7 +260,7 @@ const CLocale::LookupType* CLocale::LookupWord(const Str& dictname, const Str& w std::map::const_iterator dictit = Dictionaries.find(dictname); if (dictit == Dictionaries.end()) { - LOG(CLogger::Warning, LOG_CATEGORY, "I18n: Non-loaded dictionary '%ls' accessed", dictname.c_str()); + LOG(CLogger::Warning, LOG_CATEGORY, L"I18n: Non-loaded dictionary '%ls' accessed", dictname.c_str()); return NULL; } std::map >::const_iterator wordit = dictit->second.DictWords.find(word); @@ -307,7 +307,7 @@ StringBuffer CLocale::Translate(const wchar_t* id) StringsType::iterator TransStr = Strings.find(Str(id)); if (TransStr == Strings.end()) { - LOG(CLogger::Normal, LOG_CATEGORY, "I18n: No translation found for string '%ls'", id); + LOG(CLogger::Normal, LOG_CATEGORY, L"I18n: No translation found for string '%ls'", id); // Just use the ID string directly, and remember it for the future return StringBuffer(&AddDefaultString(id), this); diff --git a/source/i18n/Interface.cpp b/source/i18n/Interface.cpp index 835dff21de..4605bf2749 100644 --- a/source/i18n/Interface.cpp +++ b/source/i18n/Interface.cpp @@ -73,7 +73,7 @@ to std::wstring. #include "CLocale.h" #include "ps/CLogger.h" -#define LOG_CATEGORY "i18n" +#define LOG_CATEGORY L"i18n" using namespace I18n; @@ -87,7 +87,7 @@ CLocale_interface* I18n::NewLocale(JSContext* cx, JSObject* scope) } catch (PSERROR_I18n& e) { - LOG(CLogger::Error, LOG_CATEGORY, "Error creating locale object ('%s')", GetErrorString(e)); + LOG(CLogger::Error, LOG_CATEGORY, L"Error creating locale object ('%hs')", GetErrorString(e)); return NULL; } } diff --git a/source/i18n/ScriptInterface.cpp b/source/i18n/ScriptInterface.cpp index 9981593128..5661a71e5b 100644 --- a/source/i18n/ScriptInterface.cpp +++ b/source/i18n/ScriptInterface.cpp @@ -23,7 +23,7 @@ #include "scripting/SpiderMonkey.h" #include "ps/CLogger.h" -#define LOG_CATEGORY "i18n" +#define LOG_CATEGORY L"i18n" using namespace I18n; @@ -340,7 +340,7 @@ const StrImW ScriptObject::CallFunction(const char* name, const std::vector& vars) jsdouble* val = JS_NewDouble(Context, ((BufferVariable_double*)vars[ID])->value); if (!val) { - debug_warn("Error creating JS double"); + debug_warn(L"Error creating JS double"); return JSVAL_NULL; } GCVal = (void*)val; @@ -453,7 +453,7 @@ jsval ScriptValueVariable::GetJsval(const std::vector& vars) JSString* val = StringConvert::wchars_to_jsstring(Context, ((BufferVariable_string*)vars[ID])->value.str()); if (!val) { - debug_warn("Error creating JS string"); + debug_warn(L"Error creating JS string"); return JSVAL_NULL; } GCVal = (void*)val; @@ -465,7 +465,7 @@ jsval ScriptValueVariable::GetJsval(const std::vector& vars) JSString* val = StringConvert::wchars_to_jsstring(Context, ((BufferVariable_rawstring*)vars[ID])->value.str()); if (!val) { - debug_warn("Error creating JS string"); + debug_warn(L"Error creating JS string"); return JSVAL_NULL; } GCVal = (void*)val; @@ -473,7 +473,7 @@ jsval ScriptValueVariable::GetJsval(const std::vector& vars) return STRING_TO_JSVAL(val); } default: - debug_warn("Invalid type"); + debug_warn(L"Invalid type"); return JSVAL_NULL; } } diff --git a/source/i18n/StringBuffer.cpp b/source/i18n/StringBuffer.cpp index 90250f3c3c..4e44a32c5e 100644 --- a/source/i18n/StringBuffer.cpp +++ b/source/i18n/StringBuffer.cpp @@ -28,7 +28,7 @@ template void delete_fn(T* v) { delete v; } #include #include "ps/CLogger.h" -#define LOG_CATEGORY "i18n" +#define LOG_CATEGORY L"i18n" using namespace I18n; @@ -44,7 +44,7 @@ I18n::StringBuffer::operator Str() if (Variables.size() != String->VarCount) { - LOG(CLogger::Error, LOG_CATEGORY, "I18n: Incorrect number of parameters passed to Translate"); + LOG(CLogger::Error, LOG_CATEGORY, L"I18n: Incorrect number of parameters passed to Translate"); // Tidy up std::for_each(Variables.begin(), Variables.end(), delete_fn); diff --git a/source/lib/app_hooks.cpp b/source/lib/app_hooks.cpp index 92c3411ec2..ec29424767 100644 --- a/source/lib/app_hooks.cpp +++ b/source/lib/app_hooks.cpp @@ -35,15 +35,16 @@ static void def_override_gl_upload_caps() } -static const char* def_get_log_dir() +static const fs::wpath& def_get_log_dir() { - static char N_log_dir[PATH_MAX]; - ONCE(\ - (void)sys_get_executable_name(N_log_dir, ARRAY_SIZE(N_log_dir));\ - /* strip app name (we only want its path) */\ - path_strip_fn(N_log_dir);\ - ); - return N_log_dir; + static fs::wpath logDir; + if(logDir.empty()) + { + fs::wpath exePathname; + (void)sys_get_executable_name(exePathname); + logDir = exePathname.branch_path(); + } + return logDir; } @@ -133,13 +134,13 @@ bool app_hook_was_redefined(size_t offset_in_struct) // (boilerplate code; hides details of how to call the app hook) //----------------------------------------------------------------------------- -void ah_override_gl_upload_caps(void) +void ah_override_gl_upload_caps() { if(ah.override_gl_upload_caps) ah.override_gl_upload_caps(); } -const char* ah_get_log_dir(void) +const fs::wpath& ah_get_log_dir() { return ah.get_log_dir(); } diff --git a/source/lib/app_hooks.h b/source/lib/app_hooks.h index f981d57314..9a1a0ee8f9 100644 --- a/source/lib/app_hooks.h +++ b/source/lib/app_hooks.h @@ -100,7 +100,7 @@ extern const wchar_t*, translate, (const wchar_t* text), (text), return) * the default implementation works but is hardwired in code and therefore * not expandable. **/ -extern void ah_override_gl_upload_caps(void); +extern void ah_override_gl_upload_caps(); /** * return path to directory into which crash dumps should be written. @@ -113,7 +113,7 @@ extern void ah_override_gl_upload_caps(void); * * @return full native path; must end with directory separator (e.g. '/'). **/ -extern const char* ah_get_log_dir(void); +extern const fs::wpath& ah_get_log_dir(); /** * gather all app-related logs/information and write it to file. @@ -174,8 +174,8 @@ extern ErrorReaction ah_display_error(const wchar_t* text, size_t flags); **/ struct AppHooks { - void (*override_gl_upload_caps)(void); - const char* (*get_log_dir)(void); + void (*override_gl_upload_caps)(); + const fs::wpath& (*get_log_dir)(); void (*bundle_logs)(FILE* f); const wchar_t* (*translate)(const wchar_t* text); void (*translate_free)(const wchar_t* text); diff --git a/source/lib/debug.cpp b/source/lib/debug.cpp index 27f62e8f4f..2f23c47490 100644 --- a/source/lib/debug.cpp +++ b/source/lib/debug.cpp @@ -27,7 +27,6 @@ #include #include "app_hooks.h" -#include "os_path.h" #include "path_util.h" #include "lib/allocators/allocators.h" // page_aligned_alloc #include "fnv_hash.h" @@ -39,16 +38,16 @@ #endif -ERROR_ASSOCIATE(ERR::SYM_NO_STACK_FRAMES_FOUND, "No stack frames found", -1); -ERROR_ASSOCIATE(ERR::SYM_UNRETRIEVABLE_STATIC, "Value unretrievable (stored in external module)", -1); -ERROR_ASSOCIATE(ERR::SYM_UNRETRIEVABLE, "Value unretrievable", -1); -ERROR_ASSOCIATE(ERR::SYM_TYPE_INFO_UNAVAILABLE, "Error getting type_info", -1); -ERROR_ASSOCIATE(ERR::SYM_INTERNAL_ERROR, "Exception raised while processing a symbol", -1); -ERROR_ASSOCIATE(ERR::SYM_UNSUPPORTED, "Symbol type not (fully) supported", -1); -ERROR_ASSOCIATE(ERR::SYM_CHILD_NOT_FOUND, "Symbol does not have the given child", -1); -ERROR_ASSOCIATE(ERR::SYM_NESTING_LIMIT, "Symbol nesting too deep or infinite recursion", -1); -ERROR_ASSOCIATE(ERR::SYM_SINGLE_SYMBOL_LIMIT, "Symbol has produced too much output", -1); -ERROR_ASSOCIATE(INFO::SYM_SUPPRESS_OUTPUT, "Symbol was suppressed", -1); +ERROR_ASSOCIATE(ERR::SYM_NO_STACK_FRAMES_FOUND, L"No stack frames found", -1); +ERROR_ASSOCIATE(ERR::SYM_UNRETRIEVABLE_STATIC, L"Value unretrievable (stored in external module)", -1); +ERROR_ASSOCIATE(ERR::SYM_UNRETRIEVABLE, L"Value unretrievable", -1); +ERROR_ASSOCIATE(ERR::SYM_TYPE_INFO_UNAVAILABLE, L"Error getting type_info", -1); +ERROR_ASSOCIATE(ERR::SYM_INTERNAL_ERROR, L"Exception raised while processing a symbol", -1); +ERROR_ASSOCIATE(ERR::SYM_UNSUPPORTED, L"Symbol type not (fully) supported", -1); +ERROR_ASSOCIATE(ERR::SYM_CHILD_NOT_FOUND, L"Symbol does not have the given child", -1); +ERROR_ASSOCIATE(ERR::SYM_NESTING_LIMIT, L"Symbol nesting too deep or infinite recursion", -1); +ERROR_ASSOCIATE(ERR::SYM_SINGLE_SYMBOL_LIMIT, L"Symbol has produced too much output", -1); +ERROR_ASSOCIATE(INFO::SYM_SUPPRESS_OUTPUT, L"Symbol was suppressed", -1); // needed when writing crashlog @@ -102,9 +101,9 @@ static const size_t MAX_TAGS = 20; static u32 tags[MAX_TAGS]; static size_t num_tags; -void debug_filter_add(const char* tag) +void debug_filter_add(const wchar_t* tag) { - const u32 hash = fnv_hash(tag); + const u32 hash = fnv_hash(tag, wcslen(tag)*sizeof(tag[0])); // make sure it isn't already in the list for(size_t i = 0; i < MAX_TAGS; i++) @@ -121,13 +120,13 @@ void debug_filter_add(const char* tag) tags[num_tags++] = hash; } -void debug_filter_remove(const char* tag) +void debug_filter_remove(const wchar_t* tag) { - const u32 hash = fnv_hash(tag); + const u32 hash = fnv_hash(tag, wcslen(tag)*sizeof(tag[0])); for(size_t i = 0; i < MAX_TAGS; i++) - // found it - if(tags[i] == hash) + { + if(tags[i] == hash) // found it { // replace with last element (avoid holes) tags[i] = tags[MAX_TAGS-1]; @@ -136,6 +135,7 @@ void debug_filter_remove(const char* tag) // can only happen once, so we're done. return; } + } } void debug_filter_clear() @@ -143,7 +143,7 @@ void debug_filter_clear() std::fill(tags, tags+MAX_TAGS, 0); } -bool debug_filter_allows(const char* text) +bool debug_filter_allows(const wchar_t* text) { size_t i; for(i = 0; ; i++) @@ -155,7 +155,7 @@ bool debug_filter_allows(const char* text) break; } - const u32 hash = fnv_hash(text, i); + const u32 hash = fnv_hash(text, i*sizeof(text[0])); // check if entry allowing this tag is found for(i = 0; i < MAX_TAGS; i++) @@ -169,19 +169,6 @@ bool debug_filter_allows(const char* text) const size_t DEBUG_PRINTF_MAX_CHARS = 1024; // refer to wdbg.cpp!debug_vsprintf before changing this #undef debug_printf // allowing #defining it out -void debug_printf(const char* fmt, ...) -{ - char buf[DEBUG_PRINTF_MAX_CHARS]; buf[ARRAY_SIZE(buf)-1] = '\0'; - - va_list ap; - va_start(ap, fmt); - const int len = vsnprintf(buf, DEBUG_PRINTF_MAX_CHARS, fmt, ap); - debug_assert(len >= 0); - va_end(ap); - - if(debug_filter_allows(buf)) - debug_puts(buf); -} void debug_printf(const wchar_t* fmt, ...) { @@ -189,18 +176,12 @@ void debug_printf(const wchar_t* fmt, ...) va_list ap; va_start(ap, fmt); - const int numChars = vswprintf(buf, DEBUG_PRINTF_MAX_CHARS, fmt, ap); + const int numChars = vswprintf_s(buf, DEBUG_PRINTF_MAX_CHARS, fmt, ap); debug_assert(numChars >= 0); va_end(ap); - char buf2[DEBUG_PRINTF_MAX_CHARS]; - - size_t bytesWritten = wcstombs(buf2, buf, DEBUG_PRINTF_MAX_CHARS); - - debug_assert(bytesWritten == (size_t)numChars); - - if(debug_filter_allows(buf2)) - debug_puts(buf2); + if(debug_filter_allows(buf)) + debug_puts(buf); } @@ -225,8 +206,9 @@ LibError debug_WriteCrashlog(const wchar_t* text) if(!cpu_CAS(&state, IDLE, BUSY)) return ERR::REENTERED; // NOWARN - OsPath path = OsPath(ah_get_log_dir())/"crashlog.txt"; - FILE* f = fopen(path.string().c_str(), "w"); + fs::wpath path = ah_get_log_dir()/L"crashlog.txt"; + fs::path path_c = path_from_wpath(path); + FILE* f = fopen(path_c.string().c_str(), "w"); if(!f) { state = FAILED; // must come before DEBUG_DISPLAY_ERROR @@ -312,8 +294,8 @@ private: // split out of debug_DisplayError because it's used by the self-test. const wchar_t* debug_BuildErrorMessage( const wchar_t* description, - const char* filename, int line, const char* func, - void* context, const char* lastFuncToSkip, + const wchar_t* filename, int line, const wchar_t* func, + void* context, const wchar_t* lastFuncToSkip, ErrorMessageMem* emm) { // rationale: see ErrorMessageMem @@ -326,7 +308,7 @@ const wchar_t* debug_BuildErrorMessage( // header if(!writer( L"%ls\r\n" - L"Location: %hs:%d (%hs)\r\n" + L"Location: %ls:%d (%ls)\r\n" L"\r\n" L"Call stack:\r\n" L"\r\n", @@ -350,9 +332,9 @@ fail: } else if(ret != INFO::OK) { - char description_buf[100] = {'?'}; + wchar_t description_buf[100] = {'?'}; if(!writer( - L"(error while dumping stack: %hs)", + L"(error while dumping stack: %ls)", error_description_r(ret, description_buf, ARRAY_SIZE(description_buf)) )) goto fail; @@ -364,16 +346,16 @@ fail: // append OS error (just in case it happens to be relevant - // it's usually still set from unrelated operations) - char description_buf[100] = "?"; + wchar_t description_buf[100] = L"?"; LibError errno_equiv = LibError_from_errno(false); if(errno_equiv != ERR::FAIL) // meaningful translation error_description_r(errno_equiv, description_buf, ARRAY_SIZE(description_buf)); - char os_error[100] = "?"; + wchar_t os_error[100] = L"?"; sys_error_description_r(0, os_error, ARRAY_SIZE(os_error)); if(!writer( L"\r\n" - L"errno = %d (%hs)\r\n" - L"OS error = %hs\r\n", + L"errno = %d (%ls)\r\n" + L"OS error = %ls\r\n", errno, description_buf, os_error )) goto fail; @@ -466,8 +448,8 @@ static ErrorReaction PerformErrorReaction(ErrorReaction er, size_t flags, u8* su } ErrorReaction debug_DisplayError(const wchar_t* description, - size_t flags, void* context, const char* lastFuncToSkip, - const char* pathname, int line, const char* func, + size_t flags, void* context, const wchar_t* lastFuncToSkip, + const wchar_t* pathname, int line, const wchar_t* func, u8* suppress) { // "suppressing" this error means doing nothing and returning ER_CONTINUE. @@ -483,17 +465,17 @@ ErrorReaction debug_DisplayError(const wchar_t* description, flags |= DE_ALLOW_SUPPRESS; // .. deal with incomplete file/line info if(!pathname || pathname[0] == '\0') - pathname = "unknown"; + pathname = L"unknown"; if(line <= 0) line = 0; if(!func || func[0] == '\0') - func = "?"; + func = L"?"; // .. _FILE__ evaluates to the full path (albeit without drive letter) // which is rather long. we only display the base name for clarity. - const char* filename = path_name_only(pathname); + const wchar_t* filename = path_name_only(pathname); // display in output window; double-click will navigate to error location. - debug_printf("%s(%d): %ls\n", filename, line, description); + debug_printf(L"%ls(%d): %ls\n", filename, line, description); ErrorMessageMem emm; const wchar_t* text = debug_BuildErrorMessage(description, filename, line, func, context, lastFuncToSkip, &emm); @@ -541,15 +523,15 @@ static bool ShouldSkipThisError(LibError err) return false; } -ErrorReaction debug_OnError(LibError err, u8* suppress, const char* file, int line, const char* func) +ErrorReaction debug_OnError(LibError err, u8* suppress, const wchar_t* file, int line, const wchar_t* func) { if(ShouldSkipThisError(err)) return ER_CONTINUE; - void* context = 0; const char* lastFuncToSkip = __func__; + void* context = 0; const wchar_t* lastFuncToSkip = __wfunc__; wchar_t buf[400]; - char err_buf[200]; error_description_r(err, err_buf, ARRAY_SIZE(err_buf)); - swprintf(buf, ARRAY_SIZE(buf), L"Function call failed: return value was %d (%hs)", err, err_buf); + wchar_t err_buf[200]; error_description_r(err, err_buf, ARRAY_SIZE(err_buf)); + swprintf_s(buf, ARRAY_SIZE(buf), L"Function call failed: return value was %d (%ls)", err, err_buf); return debug_DisplayError(buf, DE_MANUAL_BREAK, context, lastFuncToSkip, file,line,func, suppress); } @@ -567,12 +549,12 @@ static bool ShouldSkipThisAssertion() return ShouldSkipThisError(ERR::ASSERTION_FAILED); } -ErrorReaction debug_OnAssertionFailure(const char* expr, u8* suppress, const char* file, int line, const char* func) +ErrorReaction debug_OnAssertionFailure(const wchar_t* expr, u8* suppress, const wchar_t* file, int line, const wchar_t* func) { if(ShouldSkipThisAssertion()) return ER_CONTINUE; - void* context = 0; const char* lastFuncToSkip = __func__; + void* context = 0; const wchar_t* lastFuncToSkip = __wfunc__; wchar_t buf[400]; - swprintf(buf, ARRAY_SIZE(buf), L"Assertion failed: \"%hs\"", expr); + swprintf_s(buf, ARRAY_SIZE(buf), L"Assertion failed: \"%ls\"", expr); return debug_DisplayError(buf, DE_MANUAL_BREAK, context, lastFuncToSkip, file,line,func, suppress); } diff --git a/source/lib/debug.h b/source/lib/debug.h index 3e21419f36..75f8cda998 100644 --- a/source/lib/debug.h +++ b/source/lib/debug.h @@ -44,6 +44,12 @@ extern void debug_break(); #endif +// wide versions of predefined macros +#define WIDEN2(x) L ## x +#define WIDEN(x) WIDEN2(x) +#define __WFILE__ WIDEN(__FILE__) +#define __wfunc__ WIDEN(__func__) + //----------------------------------------------------------------------------- // output @@ -55,7 +61,6 @@ extern void debug_break(); * * @param format string and varargs; see printf. **/ -LIB_API void debug_printf(const char* fmt, ...) PRINTF_ARGS(1); LIB_API void debug_printf(const wchar_t* fmt, ...) WPRINTF_ARGS(1); @@ -150,7 +155,7 @@ enum ErrorReaction * @param flags: see DebugDisplayErrorFlags. * @param context, lastFuncToSkip: see debug_DumpStack. * @param file, line, func: location of the error (typically passed as - * __FILE__, __LINE__, __func__ from a macro) + * __WFILE__, __LINE__, __wfunc__ from a macro) * @param suppress pointer to a caller-allocated flag that can be used to * suppress this error. if NULL, this functionality is skipped and the * "Suppress" dialog button will be disabled. @@ -158,13 +163,13 @@ enum ErrorReaction * provides the storage. values: see DEBUG_SUPPRESS above. * @return ErrorReaction (user's choice: continue running or stop?) **/ -LIB_API ErrorReaction debug_DisplayError(const wchar_t* description, size_t flags, void* context, const char* lastFuncToSkip, const char* file, int line, const char* func, u8* suppress); +LIB_API ErrorReaction debug_DisplayError(const wchar_t* description, size_t flags, void* context, const wchar_t* lastFuncToSkip, const wchar_t* file, int line, const wchar_t* func, u8* suppress); /** * convenience version, in case the advanced parameters aren't needed. * macro instead of providing overload/default values for C compatibility. **/ -#define DEBUG_DISPLAY_ERROR(text) debug_DisplayError(text, 0, 0, "debug_DisplayError", __FILE__,__LINE__,__func__, 0) +#define DEBUG_DISPLAY_ERROR(text) debug_DisplayError(text, 0, 0, L"debug_DisplayError", __WFILE__,__LINE__,__wfunc__, 0) // @@ -194,13 +199,13 @@ LIB_API ErrorReaction debug_DisplayError(const wchar_t* description, size_t flag * in future, allow output with the given tag to proceed. * no effect if already added. **/ -LIB_API void debug_filter_add(const char* tag); +LIB_API void debug_filter_add(const wchar_t* tag); /** * in future, discard output with the given tag. * no effect if not currently added. **/ -LIB_API void debug_filter_remove(const char* tag); +LIB_API void debug_filter_remove(const wchar_t* tag); /** * clear all filter state; equivalent to debug_filter_remove for @@ -213,7 +218,7 @@ LIB_API void debug_filter_clear(); * useful for a series of debug_printfs - avoids needing to add a tag to * each of their format strings. **/ -LIB_API bool debug_filter_allows(const char* text); +LIB_API bool debug_filter_allows(const wchar_t* text); /** @@ -264,7 +269,7 @@ STMT(\ static u8 suppress__;\ if(!(expr))\ {\ - switch(debug_OnAssertionFailure(#expr, &suppress__, __FILE__, __LINE__, __func__))\ + switch(debug_OnAssertionFailure(WIDEN(#expr), &suppress__, __WFILE__, __LINE__, __wfunc__))\ {\ case ER_BREAK:\ debug_break();\ @@ -288,7 +293,7 @@ STMT(\ #define debug_warn(expr) \ STMT(\ static u8 suppress__;\ - switch(debug_OnAssertionFailure(expr, &suppress__, __FILE__, __LINE__, __func__))\ + switch(debug_OnAssertionFailure(expr, &suppress__, __WFILE__, __LINE__, __wfunc__))\ {\ case ER_BREAK:\ debug_break();\ @@ -307,7 +312,7 @@ STMT(\ #define DEBUG_WARN_ERR(err)\ STMT(\ static u8 suppress__;\ - switch(debug_OnError(err, &suppress__, __FILE__, __LINE__, __func__))\ + switch(debug_OnError(err, &suppress__, __WFILE__, __LINE__, __wfunc__))\ {\ case ER_BREAK:\ debug_break();\ @@ -329,7 +334,7 @@ STMT(\ * @param func name of the function containing it * @return ErrorReaction (user's choice: continue running or stop?) **/ -LIB_API ErrorReaction debug_OnAssertionFailure(const char* assert_expr, u8* suppress, const char* file, int line, const char* func); +LIB_API ErrorReaction debug_OnAssertionFailure(const wchar_t* assert_expr, u8* suppress, const wchar_t* file, int line, const wchar_t* func); /** * called when a DEBUG_WARN_ERR indicates an error occurred; @@ -341,7 +346,7 @@ LIB_API ErrorReaction debug_OnAssertionFailure(const char* assert_expr, u8* supp * @param func name of the function containing it * @return ErrorReaction (user's choice: continue running or stop?) **/ -LIB_API ErrorReaction debug_OnError(LibError err, u8* suppress, const char* file, int line, const char* func); +LIB_API ErrorReaction debug_OnError(LibError err, u8* suppress, const wchar_t* file, int line, const wchar_t* func); /** @@ -424,7 +429,7 @@ const size_t DBG_FILE_LEN = 100; * @return LibError; INFO::OK iff any information was successfully * retrieved and stored. **/ -LIB_API LibError debug_ResolveSymbol(void* ptr_of_interest, char* sym_name, char* file, int* line); +LIB_API LibError debug_ResolveSymbol(void* ptr_of_interest, wchar_t* sym_name, wchar_t* file, int* line); /** * write a complete stack trace (including values of local variables) into @@ -444,7 +449,7 @@ LIB_API LibError debug_ResolveSymbol(void* ptr_of_interest, char* sym_name, char * @return LibError; ERR::REENTERED if reentered via recursion or * multithreading (not allowed since static data is used). **/ -LIB_API LibError debug_DumpStack(wchar_t* buf, size_t maxChars, void* context, const char* lastFuncToSkip); +LIB_API LibError debug_DumpStack(wchar_t* buf, size_t maxChars, void* context, const wchar_t* lastFuncToSkip); //----------------------------------------------------------------------------- @@ -456,7 +461,7 @@ LIB_API LibError debug_DumpStack(wchar_t* buf, size_t maxChars, void* context, c * this can be quite slow (~1 ms)! On Windows, it uses OutputDebugString * (entails context switch), otherwise stdout+fflush (waits for IO). **/ -LIB_API void debug_puts(const char* text); +LIB_API void debug_puts(const wchar_t* text); /** * return the caller of a certain function on the call stack. @@ -467,7 +472,7 @@ LIB_API void debug_puts(const char* text); * @param context, lastFuncToSkip - see debug_DumpStack * @return address of the caller **/ -LIB_API void* debug_GetCaller(void* context, const char* lastFuncToSkip); +LIB_API void* debug_GetCaller(void* context, const wchar_t* lastFuncToSkip); /** * check if a pointer appears to be totally invalid. @@ -535,6 +540,6 @@ LIB_API void debug_FreeErrorMessage(ErrorMessageMem* emm); * fallback in case heap alloc fails. should be freed via * debug_FreeErrorMessage when no longer needed. **/ -LIB_API const wchar_t* debug_BuildErrorMessage(const wchar_t* description, const char* fn_only, int line, const char* func, void* context, const char* lastFuncToSkip, ErrorMessageMem* emm); +LIB_API const wchar_t* debug_BuildErrorMessage(const wchar_t* description, const wchar_t* fn_only, int line, const wchar_t* func, void* context, const wchar_t* lastFuncToSkip, ErrorMessageMem* emm); #endif // #ifndef INCLUDED_DEBUG diff --git a/source/lib/debug_stl.cpp b/source/lib/debug_stl.cpp index 4fb5fe0c5d..84f4d2af5d 100644 --- a/source/lib/debug_stl.cpp +++ b/source/lib/debug_stl.cpp @@ -31,32 +31,32 @@ #include "regex.h" -ERROR_ASSOCIATE(ERR::STL_CNT_UNKNOWN, "Unknown STL container type_name", -1); -ERROR_ASSOCIATE(ERR::STL_CNT_INVALID, "Container type is known but contents are invalid", -1); +ERROR_ASSOCIATE(ERR::STL_CNT_UNKNOWN, L"Unknown STL container type_name", -1); +ERROR_ASSOCIATE(ERR::STL_CNT_INVALID, L"Container type is known but contents are invalid", -1); // used in debug_stl_simplify_name. // note: strcpy is safe because replacement happens in-place and // src is longer than dst (otherwise, we wouldn't be replacing). #define REPLACE(what, with)\ - else if(!strncmp(src, (what), sizeof(what)-1))\ + else if(!wcsncmp(src, (what), ARRAY_SIZE(what)-1))\ {\ - src += sizeof(what)-1-1; /* see preincrement rationale*/\ - strcpy(dst, (with)); /* safe - see above */\ - dst += sizeof(with)-1;\ + src += ARRAY_SIZE(what)-1-1; /* see preincrement rationale*/\ + SAFE_WCSCPY(dst, (with));\ + dst += ARRAY_SIZE(with)-1;\ } #define STRIP(what)\ - else if(!strncmp(src, (what), sizeof(what)-1))\ + else if(!wcsncmp(src, (what), ARRAY_SIZE(what)-1))\ {\ - src += sizeof(what)-1-1;/* see preincrement rationale*/\ + src += ARRAY_SIZE(what)-1-1;/* see preincrement rationale*/\ } #define STRIP_NESTED(what)\ - else if(!strncmp(src, (what), sizeof(what)-1))\ + else if(!wcsncmp(src, (what), ARRAY_SIZE(what)-1))\ {\ /* remove preceding comma (if present) */\ if(src != name && src[-1] == ',')\ dst--;\ - src += sizeof(what)-1;\ + src += ARRAY_SIZE(what)-1;\ /* strip everything until trailing > is matched */\ debug_assert(nesting == 0);\ nesting = 1;\ @@ -69,19 +69,19 @@ ERROR_ASSOCIATE(ERR::STL_CNT_INVALID, "Container type is known but contents are // // see http://www.bdsoft.com/tools/stlfilt.html and // http://www.moderncppdesign.com/publications/better_template_error_messages.html -char* debug_stl_simplify_name(char* name) +wchar_t* debug_stl_simplify_name(wchar_t* name) { // used when stripping everything inside a < > to continue until // the final bracket is matched (at the original nesting level). int nesting = 0; - const char* src = name-1; // preincremented; see below. - char* dst = name; + const wchar_t* src = name-1; // preincremented; see below. + wchar_t* dst = name; // for each character: (except those skipped as parts of strings) for(;;) { - char c = *(++src); + wchar_t c = *(++src); // preincrement rationale: src++ with no further changes would // require all comparisons to subtract 1. incrementing at the // end of a loop would require a goto, instead of continue @@ -112,7 +112,7 @@ char* debug_stl_simplify_name(char* name) // start if chain (REPLACE and STRIP use else if) if(0) {} - else if(!strncmp(src, "::_Node", 7)) + else if(!wcsncmp(src, L"::_Node", 7)) { // add a space if not already preceded by one // (prevents replacing ">::_Node>" with ">>") @@ -120,29 +120,29 @@ char* debug_stl_simplify_name(char* name) *dst++ = ' '; src += 7; } - REPLACE("unsigned short", "u16") - REPLACE("unsigned int", "size_t") - REPLACE("unsigned __int64", "u64") - STRIP(",0> ") + REPLACE(L"unsigned short", L"u16") + REPLACE(L"unsigned int", L"size_t") + REPLACE(L"unsigned __int64", L"u64") + STRIP(L",0> ") // early out: all tests after this start with s, so skip them else if(c != 's') { *dst++ = c; continue; } - REPLACE("std::_List_nod", "list") - REPLACE("std::_Tree_nod", "map") - REPLACE("std::basic_string,") - STRIP("std::char_traits,") - STRIP("std::_Tmap_traits") - STRIP("std::_Tset_traits") - STRIP_NESTED("std::allocator<") - STRIP_NESTED("std::less<") - STRIP_NESTED("stdext::hash_compare<") - STRIP("std::") - STRIP("stdext::") + REPLACE(L"std::_List_nod", L"list") + REPLACE(L"std::_Tree_nod", L"map") + REPLACE(L"std::basic_string,") + STRIP(L"std::char_traits,") + STRIP(L"std::_Tmap_traits") + STRIP(L"std::_Tset_traits") + STRIP_NESTED(L"std::allocator<") + STRIP_NESTED(L"std::less<") + STRIP_NESTED(L"stdext::hash_compare<") + STRIP(L"std::") + STRIP(L"stdext::") else *dst++ = c; } @@ -594,7 +594,7 @@ template bool get_container_info(const T& t, size_t size, size_t el_siz // return number of elements and an iterator (any data it needs is stored in // it_mem, which must hold DEBUG_STL_MAX_ITERATOR_SIZE bytes). // returns 0 on success or an StlContainerError. -LibError debug_stl_get_container_info(const char* type_name, const u8* p, size_t size, +LibError debug_stl_get_container_info(const wchar_t* type_name, const u8* p, size_t size, size_t el_size, size_t* el_count, DebugStlIterator* el_iterator, void* it_mem) { #if MSC_VERSION >= 1400 diff --git a/source/lib/debug_stl.h b/source/lib/debug_stl.h index 8f58b75799..57546f1997 100644 --- a/source/lib/debug_stl.h +++ b/source/lib/debug_stl.h @@ -43,7 +43,7 @@ namespace ERR * strings. DBG_SYMBOL_LEN chars is a good measure. * @return name for convenience. **/ -extern char* debug_stl_simplify_name(char* name); +extern wchar_t* debug_stl_simplify_name(wchar_t* name); /** @@ -74,7 +74,7 @@ const size_t DEBUG_STL_MAX_ITERATOR_SIZE = 64; * at least DEBUG_STL_MAX_ITERATOR_SIZE bytes. * @return LibError (ERR::STL_*) **/ -extern LibError debug_stl_get_container_info(const char* type_name, const u8* p, size_t size, +extern LibError debug_stl_get_container_info(const wchar_t* type_name, const u8* p, size_t size, size_t el_size, size_t* el_count, DebugStlIterator* el_iterator, void* it_mem); #endif // #ifndef INCLUDED_DEBUG_STL diff --git a/source/lib/external_libraries/dbghelp_funcs.h b/source/lib/external_libraries/dbghelp_funcs.h index bb881ce55e..bfae8ed05f 100644 --- a/source/lib/external_libraries/dbghelp_funcs.h +++ b/source/lib/external_libraries/dbghelp_funcs.h @@ -3,7 +3,7 @@ FUNC(DWORD, SymGetOptions, (VOID)) FUNC(DWORD, SymSetOptions, (__in DWORD SymOptions)) FUNC(DWORD64, SymGetModuleBase64, (__in HANDLE hProcess, __in DWORD64 qwAddr)) FUNC(BOOL, SymFromAddrW, (__in HANDLE hProcess, __in DWORD64 Address, __out_opt PDWORD64 Displacement, __inout PSYMBOL_INFOW Symbol)) -FUNC(BOOL, SymGetLineFromAddr64, (__in HANDLE hProcess, __in DWORD64 qwAddr, __out PDWORD pdwDisplacement, __out PIMAGEHLP_LINE64 Line64)) +FUNC(BOOL, SymGetLineFromAddrW64, (__in HANDLE hProcess, __in DWORD64 qwAddr, __out PDWORD pdwDisplacement, __out PIMAGEHLP_LINEW64 Line64)) FUNC(PVOID, SymFunctionTableAccess64, (__in HANDLE hProcess, __in DWORD64 AddrBase)) FUNC(BOOL, SymGetTypeInfo, (__in HANDLE hProcess, __in DWORD64 ModBase, __in ULONG TypeId, __in IMAGEHLP_SYMBOL_TYPE_INFO GetType, __out PVOID pInfo)) FUNC(BOOL, SymFromIndexW, (__in HANDLE hProcess, __in ULONG64 BaseOfDll, __in DWORD Index, __inout PSYMBOL_INFOW Symbol)) diff --git a/source/lib/file/archive/archive.cpp b/source/lib/file/archive/archive.cpp index 1a926fc07d..5d0b77dce2 100644 --- a/source/lib/file/archive/archive.cpp +++ b/source/lib/file/archive/archive.cpp @@ -22,8 +22,8 @@ #include "precompiled.h" #include "archive.h" -ERROR_ASSOCIATE(ERR::ARCHIVE_UNKNOWN_FORMAT, "Unknown archive format", -1); -ERROR_ASSOCIATE(ERR::ARCHIVE_UNKNOWN_METHOD, "Unknown compression method", -1); +ERROR_ASSOCIATE(ERR::ARCHIVE_UNKNOWN_FORMAT, L"Unknown archive format", -1); +ERROR_ASSOCIATE(ERR::ARCHIVE_UNKNOWN_METHOD, L"Unknown compression method", -1); IArchiveReader::~IArchiveReader() { diff --git a/source/lib/file/archive/archive.h b/source/lib/file/archive/archive.h index 767c0df6c1..aeb157cfe0 100644 --- a/source/lib/file/archive/archive.h +++ b/source/lib/file/archive/archive.h @@ -83,7 +83,7 @@ struct IArchiveWriter * precisely because they aren't in archives, and the cache would * thrash anyway, so this is deemed acceptable. **/ - virtual LibError AddFile(const fs::path& pathname) = 0; + virtual LibError AddFile(const fs::wpath& pathname) = 0; }; typedef shared_ptr PIArchiveWriter; diff --git a/source/lib/file/archive/archive_builder.cpp b/source/lib/file/archive/archive_builder.cpp index 465c967d56..33a3c0a635 100644 --- a/source/lib/file/archive/archive_builder.cpp +++ b/source/lib/file/archive/archive_builder.cpp @@ -82,7 +82,7 @@ class IdMgr const Map::value_type item = std::make_pair(node.atom_fn, id); std::pair ret = map.insert(item); if(!ret.second) - debug_warn("atom_fn already associated with node"); + debug_warn(L"atom_fn already associated with node"); } public: @@ -105,7 +105,7 @@ public: Map::const_iterator cit = map.find(atom_fn); if(cit == map.end()) { - debug_warn("id_from_fn: not found"); + debug_warn(L"id_from_fn: not found"); return NULL_ID; } return cit->second; @@ -1060,7 +1060,7 @@ bool trace_entry_causes_io(FileCache& simulatedCache, const TraceEntry* ent) break; default: - debug_warn("unknown TraceOp"); + debug_warn(L"unknown TraceOp"); } return false; @@ -1095,7 +1095,7 @@ bool trace_entry_causes_io(FileCache& simulatedCache, const TraceEntry* ent) fileCache.Release(ent->vfsPathname); break; default: - debug_warn("unknown TraceOp"); + debug_warn(L"unknown TraceOp"); } } diff --git a/source/lib/file/archive/archive_zip.cpp b/source/lib/file/archive/archive_zip.cpp index 9824a8a5e6..5d71957fe3 100644 --- a/source/lib/file/archive/archive_zip.cpp +++ b/source/lib/file/archive/archive_zip.cpp @@ -59,9 +59,10 @@ enum ZipMethod class LFH { public: - void Init(const FileInfo& fileInfo, off_t csize, ZipMethod method, u32 checksum, const VfsPath& pathname_) + void Init(const FileInfo& fileInfo, off_t csize, ZipMethod method, u32 checksum, const fs::wpath& pathname) { - const std::string& pathnameString = pathname_.string(); + const fs::path pathname_c = path_from_wpath(pathname); + const size_t pathnameLength = pathname_c.string().length(); m_magic = lfh_magic; m_x1 = to_le16(0); @@ -71,10 +72,10 @@ public: m_crc = to_le32(checksum); m_csize = to_le32(u32_from_larger(csize)); m_usize = to_le32(u32_from_larger(fileInfo.Size())); - m_fn_len = to_le16(u16_from_larger(pathnameString.length())); + m_fn_len = to_le16(u16_from_larger(pathnameLength)); m_e_len = to_le16(0); - cpu_memcpy((char*)this + sizeof(LFH), pathnameString.c_str(), pathnameString.length()); + cpu_memcpy((char*)this + sizeof(LFH), pathname_c.string().c_str(), pathnameLength); } size_t Size() const @@ -106,9 +107,11 @@ cassert(sizeof(LFH) == 30); class CDFH { public: - void Init(const FileInfo& fileInfo, off_t ofs, off_t csize, ZipMethod method, u32 checksum, const VfsPath& pathname_, size_t slack) + void Init(const FileInfo& fileInfo, off_t ofs, off_t csize, ZipMethod method, u32 checksum, const fs::wpath& pathname, size_t slack) { - const std::string& pathnameString = pathname_.string(); + const fs::path pathname_c = path_from_wpath(pathname); + const size_t pathnameLength = pathname_c.string().length(); + m_magic = cdfh_magic; m_x1 = to_le32(0); m_flags = to_le16(0); @@ -117,21 +120,26 @@ public: m_crc = to_le32(checksum); m_csize = to_le32(u32_from_larger(csize)); m_usize = to_le32(u32_from_larger(fileInfo.Size())); - m_fn_len = to_le16(u16_from_larger(pathnameString.length())); + m_fn_len = to_le16(u16_from_larger(pathnameLength)); m_e_len = to_le16(0); m_c_len = to_le16(u16_from_larger((size_t)slack)); m_x2 = to_le32(0); m_x3 = to_le32(0); m_lfh_ofs = to_le32(u32_from_larger(ofs)); - cpu_memcpy((char*)this + sizeof(CDFH), pathnameString.c_str(), pathnameString.length()); + cpu_memcpy((char*)this + sizeof(CDFH), pathname_c.string().c_str(), pathnameLength); } - void GetPathname(std::string& pathname) const + fs::wpath Pathname() const { const size_t length = (size_t)read_le16(&m_fn_len); - const char* fn = (const char*)this + sizeof(CDFH); // not 0-terminated! - pathname = std::string(fn, length); + const char* pathname_c = (const char*)this + sizeof(CDFH); // not 0-terminated! + wchar_t pathname[PATH_MAX]; + size_t charsConverted; + const errno_t ret = mbstowcs_s(&charsConverted, pathname, pathname_c, length); + debug_assert(ret == 0); + debug_assert(charsConverted == length); + return pathname; } off_t HeaderOffset() const @@ -251,12 +259,12 @@ public: return 2u; } - virtual char LocationCode() const + virtual wchar_t LocationCode() const { return 'A'; } - virtual LibError Load(const std::string& UNUSED(name), const shared_ptr& buf, size_t size) const + virtual LibError Load(const std::wstring& UNUSED(name), const shared_ptr& buf, size_t size) const { AdjustOffset(); @@ -368,7 +376,7 @@ private: class ArchiveReader_Zip : public IArchiveReader { public: - ArchiveReader_Zip(const fs::path& pathname) + ArchiveReader_Zip(const fs::wpath& pathname) : m_file(new File(pathname, 'r')) { FileInfo fileInfo; @@ -396,16 +404,13 @@ public: if(!cdfh) WARN_RETURN(ERR::CORRUPTED); - std::string zipPathname; - cdfh->GetPathname(zipPathname); - const size_t lastSlashOfs = zipPathname.find_last_of('/'); - const size_t nameOfs = (lastSlashOfs == std::string::npos)? 0 : lastSlashOfs+1; - if(nameOfs != zipPathname.length()) // ignore paths ending in slash (i.e. representing a directory) + const fs::wpath relativePathname(cdfh->Pathname()); + const std::wstring name = relativePathname.leaf(); + if(*name.rbegin() != '/') // ignore paths ending in slash (i.e. representing a directory) { - const std::string name = zipPathname.substr(nameOfs, zipPathname.length()-nameOfs); FileInfo fileInfo(name, cdfh->USize(), cdfh->MTime()); shared_ptr archiveFile(new ArchiveFile_Zip(m_file, cdfh->HeaderOffset(), cdfh->CSize(), cdfh->Checksum(), cdfh->Method())); - cb(zipPathname, fileInfo, archiveFile, cbData); + cb(VfsPath(relativePathname.string()), fileInfo, archiveFile, cbData); } pos += cdfh->Size(); @@ -500,7 +505,7 @@ private: off_t m_fileSize; }; -PIArchiveReader CreateArchiveReader_Zip(const fs::path& archivePathname) +PIArchiveReader CreateArchiveReader_Zip(const fs::wpath& archivePathname) { return PIArchiveReader(new ArchiveReader_Zip(archivePathname)); } @@ -513,7 +518,7 @@ PIArchiveReader CreateArchiveReader_Zip(const fs::path& archivePathname) class ArchiveWriter_Zip : public IArchiveWriter { public: - ArchiveWriter_Zip(const fs::path& archivePathname) + ArchiveWriter_Zip(const fs::wpath& archivePathname) : m_file(new File(archivePathname, 'w')), m_fileSize(0) , m_unalignedWriter(new UnalignedWriter(m_file, 0)) , m_numEntries(0) @@ -538,14 +543,16 @@ public: (void)pool_destroy(&m_cdfhPool); - const fs::path pathname = m_file->Pathname(); + const fs::path pathname = path_from_wpath(m_file->Pathname()); // for truncate() m_file.reset(); m_fileSize += off_t(cd_size+sizeof(ECDR)); - truncate(pathname.external_directory_string().c_str(), m_fileSize); + + // remove padding added by UnalignedWriter + truncate(pathname.string().c_str(), m_fileSize); } - LibError AddFile(const fs::path& pathname) + LibError AddFile(const fs::wpath& pathname) { FileInfo fileInfo; RETURN_ERR(GetFileInfo(pathname, &fileInfo)); @@ -565,7 +572,6 @@ public: RETURN_ERR(file->Open(pathname, 'r')); const size_t pathnameLength = pathname.string().length(); - const VfsPath vfsPathname(pathname.string()); // choose method and the corresponding codec ZipMethod method; @@ -600,7 +606,7 @@ public: // build LFH { LFH* lfh = (LFH*)buf.get(); - lfh->Init(fileInfo, (off_t)csize, method, checksum, vfsPathname); + lfh->Init(fileInfo, (off_t)csize, method, checksum, pathname); } // append a CDFH to the central directory (in memory) @@ -611,7 +617,7 @@ public: if(!cdfh) WARN_RETURN(ERR::NO_MEM); const size_t slack = m_cdfhPool.da.pos - prev_pos - cdfhSize; - cdfh->Init(fileInfo, ofs, (off_t)csize, method, checksum, vfsPathname, slack); + cdfh->Init(fileInfo, ofs, (off_t)csize, method, checksum, pathname, slack); m_numEntries++; // write LFH, pathname and cdata to file @@ -623,21 +629,21 @@ public: } private: - static bool IsFileTypeIncompressible(const fs::path& pathname) + static bool IsFileTypeIncompressible(const fs::wpath& pathname) { - const char* extension = path_extension(pathname.string().c_str()); + const std::wstring extension = fs::extension(pathname); // file extensions that we don't want to compress - static const char* incompressibleExtensions[] = + static const wchar_t* incompressibleExtensions[] = { - "zip", "rar", - "jpg", "jpeg", "png", - "ogg", "mp3" + L".zip", L".rar", + L".jpg", L".jpeg", L".png", + L".ogg", L".mp3" }; for(size_t i = 0; i < ARRAY_SIZE(incompressibleExtensions); i++) { - if(!strcasecmp(extension, incompressibleExtensions[i])) + if(!wcscasecmp(extension.c_str(), incompressibleExtensions[i])) return true; } @@ -652,7 +658,7 @@ private: size_t m_numEntries; }; -PIArchiveWriter CreateArchiveWriter_Zip(const fs::path& archivePathname) +PIArchiveWriter CreateArchiveWriter_Zip(const fs::wpath& archivePathname) { return PIArchiveWriter(new ArchiveWriter_Zip(archivePathname)); } diff --git a/source/lib/file/archive/archive_zip.h b/source/lib/file/archive/archive_zip.h index 26f3762c5f..65ec231a80 100644 --- a/source/lib/file/archive/archive_zip.h +++ b/source/lib/file/archive/archive_zip.h @@ -24,7 +24,7 @@ #include "archive.h" -LIB_API PIArchiveReader CreateArchiveReader_Zip(const fs::path& archivePathname); -LIB_API PIArchiveWriter CreateArchiveWriter_Zip(const fs::path& archivePathname); +LIB_API PIArchiveReader CreateArchiveReader_Zip(const fs::wpath& archivePathname); +LIB_API PIArchiveWriter CreateArchiveWriter_Zip(const fs::wpath& archivePathname); #endif // #ifndef INCLUDED_ARCHIVE_ZIP diff --git a/source/lib/file/common/file_loader.h b/source/lib/file/common/file_loader.h index 9f8bbf8ff3..ce49ac11c0 100644 --- a/source/lib/file/common/file_loader.h +++ b/source/lib/file/common/file_loader.h @@ -23,9 +23,9 @@ struct IFileLoader virtual ~IFileLoader(); virtual size_t Precedence() const = 0; - virtual char LocationCode() const = 0; + virtual wchar_t LocationCode() const = 0; - virtual LibError Load(const std::string& name, const shared_ptr& buf, size_t size) const = 0; + virtual LibError Load(const std::wstring& name, const shared_ptr& buf, size_t size) const = 0; }; typedef shared_ptr PIFileLoader; diff --git a/source/lib/file/common/file_stats.cpp b/source/lib/file/common/file_stats.cpp index 6923a019e5..7c5adf3837 100644 --- a/source/lib/file/common/file_stats.cpp +++ b/source/lib/file/common/file_stats.cpp @@ -183,7 +183,7 @@ ScopedIoMonitor::~ScopedIoMonitor() timer_reset(&m_startTime); } -void ScopedIoMonitor::NotifyOfSuccess(FileIOImplentation fi, char mode, off_t size) +void ScopedIoMonitor::NotifyOfSuccess(FileIOImplentation fi, wchar_t mode, off_t size) { debug_assert(fi < FI_MAX_IDX); debug_assert(mode == 'r' || mode == 'w'); @@ -268,51 +268,51 @@ template int percent(T num, T divisor) void file_stats_dump() { - if(!debug_filter_allows("FILE_STATS|")) + if(!debug_filter_allows(L"FILE_STATS|")) return; const double KB = 1e3; const double MB = 1e6; const double ms = 1e-3; - debug_printf("--------------------------------------------------------------------------------\n"); - debug_printf("File statistics:\n"); + debug_printf(L"--------------------------------------------------------------------------------\n"); + debug_printf(L"File statistics:\n"); // note: we split the reports into several debug_printfs for clarity; // this is necessary anyway due to fixed-size buffer. debug_printf( - "\nvfs:\n" - "Total files: %lu (%g MB)\n" - "Init/mount time: %g ms\n", + L"\nvfs:\n" + L"Total files: %lu (%g MB)\n" + L"Init/mount time: %g ms\n", (unsigned long)vfs_files, vfs_size_total/MB, vfs_init_elapsed_time/ms ); debug_printf( - "\nfile:\n" - "Total names: %lu (%lu KB)\n" - "Max. concurrent: %lu; leaked: %lu.\n", + L"\nfile:\n" + L"Total names: %lu (%lu KB)\n" + L"Max. concurrent: %lu; leaked: %lu.\n", (unsigned long)unique_names, (unsigned long)(unique_name_len_total/1000), (unsigned long)open_files_max, (unsigned long)open_files_cur ); debug_printf( - "\nfile_buf:\n" - "Total buffers used: %lu (%g MB)\n" - "Max concurrent: %lu; leaked: %lu\n" - "Internal fragmentation: %d%%\n", + L"\nfile_buf:\n" + L"Total buffers used: %lu (%g MB)\n" + L"Max concurrent: %lu; leaked: %lu\n" + L"Internal fragmentation: %d%%\n", (unsigned long)extant_bufs_total, buf_size_total/MB, (unsigned long)extant_bufs_max, (unsigned long)extant_bufs_cur, percent(buf_aligned_size_total-buf_size_total, buf_size_total) ); debug_printf( - "\nfile_io:\n" - "Total user load requests: %lu (%g MB)\n" - "IO thoughput [MB/s; 0=never happened]:\n" - " lowio: R=%.3g, W=%.3g\n" - " aio: R=%.3g, W=%.3g\n" - "Average size = %g KB; seeks: %lu; total callback time: %g ms\n" - "Total data actually read from disk = %g MB\n", + L"\nfile_io:\n" + L"Total user load requests: %lu (%g MB)\n" + L"IO thoughput [MB/s; 0=never happened]:\n" + L" lowio: R=%.3g, W=%.3g\n" + L" aio: R=%.3g, W=%.3g\n" + L"Average size = %g KB; seeks: %lu; total callback time: %g ms\n" + L"Total data actually read from disk = %g MB\n", (unsigned long)user_ios, user_io_size_total/MB, #define THROUGHPUT(impl, op) (io_elapsed_time[impl][op] == 0.0)? 0.0 : (io_actual_size_total[impl][op] / io_elapsed_time[impl][op] / MB) THROUGHPUT(FI_LOWIO, FO_READ), THROUGHPUT(FI_LOWIO, FO_WRITE), @@ -322,18 +322,18 @@ void file_stats_dump() ); debug_printf( - "\nfile_cache:\n" - "Hits: %lu (%g MB); misses %lu (%g MB); ratio: %u%%\n" - "Percent of requested bytes satisfied by cache: %u%%; non-compulsory misses: %lu (%u%% of misses)\n" - "Block hits: %lu; misses: %lu; ratio: %u%%\n", + L"\nfile_cache:\n" + L"Hits: %lu (%g MB); misses %lu (%g MB); ratio: %u%%\n" + L"Percent of requested bytes satisfied by cache: %u%%; non-compulsory misses: %lu (%u%% of misses)\n" + L"Block hits: %lu; misses: %lu; ratio: %u%%\n", (unsigned long)cache_count[CR_HIT], cache_size_total[CR_HIT]/MB, (unsigned long)cache_count[CR_MISS], cache_size_total[CR_MISS]/MB, percent(cache_count[CR_HIT], cache_count[CR_HIT]+cache_count[CR_MISS]), percent(cache_size_total[CR_HIT], cache_size_total[CR_HIT]+cache_size_total[CR_MISS]), (unsigned long)conflict_misses, percent(conflict_misses, cache_count[CR_MISS]), (unsigned long)block_cache_count[CR_HIT], (unsigned long)block_cache_count[CR_MISS], percent(block_cache_count[CR_HIT], block_cache_count[CR_HIT]+block_cache_count[CR_MISS]) ); debug_printf( - "\nvfs_optimizer:\n" - "Total trace entries: %lu; repeated connections: %lu; unique files: %lu\n", + L"\nvfs_optimizer:\n" + L"Total trace entries: %lu; repeated connections: %lu; unique files: %lu\n", (unsigned long)ab_connection_attempts, (unsigned long)ab_repeated_connections, (unsigned long)(ab_connection_attempts-ab_repeated_connections) ); } diff --git a/source/lib/file/common/file_stats.h b/source/lib/file/common/file_stats.h index fea4751549..23e9b59e11 100644 --- a/source/lib/file/common/file_stats.h +++ b/source/lib/file/common/file_stats.h @@ -64,7 +64,7 @@ class ScopedIoMonitor public: ScopedIoMonitor(); ~ScopedIoMonitor(); - void NotifyOfSuccess(FileIOImplentation fi, char mode, off_t size); + void NotifyOfSuccess(FileIOImplentation fi, wchar_t mode, off_t size); private: double m_startTime; @@ -101,7 +101,7 @@ class ScopedIoMonitor public: ScopedIoMonitor() {} ~ScopedIoMonitor() {} - void NotifyOfSuccess(FileIOImplentation fi, char mode, off_t size) {} + void NotifyOfSuccess(FileIOImplentation fi, wchar_t mode, off_t size) {} }; #define stats_io_check_seek(blockId) #define stats_cb_start() diff --git a/source/lib/file/common/real_directory.cpp b/source/lib/file/common/real_directory.cpp index 39e071fbb9..28d4e7254c 100644 --- a/source/lib/file/common/real_directory.cpp +++ b/source/lib/file/common/real_directory.cpp @@ -23,7 +23,7 @@ #include "lib/file/io/io.h" -RealDirectory::RealDirectory(const fs::path& path, size_t priority, size_t flags) +RealDirectory::RealDirectory(const fs::wpath& path, size_t priority, size_t flags) : m_path(path), m_priority(priority), m_flags(flags) { } @@ -35,25 +35,27 @@ RealDirectory::RealDirectory(const fs::path& path, size_t priority, size_t flags } -/*virtual*/ char RealDirectory::LocationCode() const +/*virtual*/ wchar_t RealDirectory::LocationCode() const { return 'F'; } -/*virtual*/ LibError RealDirectory::Load(const std::string& name, const shared_ptr& buf, size_t size) const +/*virtual*/ LibError RealDirectory::Load(const std::wstring& name, const shared_ptr& buf, size_t size) const { + const fs::wpath pathname(m_path/name); + PFile file(new File); - RETURN_ERR(file->Open(m_path/name, 'r')); + RETURN_ERR(file->Open(pathname, 'r')); RETURN_ERR(io_ReadAligned(file, 0, buf.get(), size)); return INFO::OK; } -LibError RealDirectory::Store(const std::string& name, const shared_ptr& fileContents, size_t size) +LibError RealDirectory::Store(const std::wstring& name, const shared_ptr& fileContents, size_t size) { - const fs::path pathname(m_path/name); + const fs::wpath pathname(m_path/name); { PFile file(new File); @@ -65,7 +67,8 @@ LibError RealDirectory::Store(const std::string& name, const shared_ptr& fil // length. ftruncate can't be used because Windows' FILE_FLAG_NO_BUFFERING // only allows resizing to sector boundaries, so the file must first // be closed. - truncate(pathname.external_file_string().c_str(), size); + const fs::path pathname_c(path_from_wpath(pathname)); + truncate(pathname_c.string().c_str(), size); return INFO::OK; } @@ -73,12 +76,13 @@ LibError RealDirectory::Store(const std::string& name, const shared_ptr& fil void RealDirectory::Watch() { - //m_watch = CreateWatch(fs::path().external_file_string().c_str()); + const fs::wpath path;// = m_path + (void)dir_watch_Add(path, m_watch); } -PRealDirectory CreateRealSubdirectory(const PRealDirectory& realDirectory, const std::string& subdirectoryName) +PRealDirectory CreateRealSubdirectory(const PRealDirectory& realDirectory, const std::wstring& subdirectoryName) { - const fs::path path(realDirectory->Path()/subdirectoryName); + const fs::wpath path(realDirectory->Path()/subdirectoryName); return PRealDirectory(new RealDirectory(path, realDirectory->Priority(), realDirectory->Flags())); } diff --git a/source/lib/file/common/real_directory.h b/source/lib/file/common/real_directory.h index 50c1fe4a88..f987b59243 100644 --- a/source/lib/file/common/real_directory.h +++ b/source/lib/file/common/real_directory.h @@ -19,13 +19,14 @@ #define INCLUDED_REAL_DIRECTORY #include "file_loader.h" +#include "lib/sysdep/dir_watch.h" class RealDirectory : public IFileLoader { public: - RealDirectory(const fs::path& path, size_t priority, size_t flags); + RealDirectory(const fs::wpath& path, size_t priority, size_t flags); - const fs::path& Path() const + const fs::wpath& Path() const { return m_path; } @@ -42,10 +43,10 @@ public: // IFileLoader virtual size_t Precedence() const; - virtual char LocationCode() const; - virtual LibError Load(const std::string& name, const shared_ptr& buf, size_t size) const; + virtual wchar_t LocationCode() const; + virtual LibError Load(const std::wstring& name, const shared_ptr& buf, size_t size) const; - LibError Store(const std::string& name, const shared_ptr& fileContents, size_t size); + LibError Store(const std::wstring& name, const shared_ptr& fileContents, size_t size); void Watch(); @@ -56,7 +57,7 @@ private: // note: paths are relative to the root directory, so storing the // entire path instead of just the portion relative to the mount point // is not all too wasteful. - const fs::path m_path; + const fs::wpath m_path; const size_t m_priority; @@ -64,11 +65,11 @@ private: // note: watches are needed in each directory because some APIs // (e.g. FAM) cannot watch entire trees with one call. - void* m_watch; + PDirWatch m_watch; }; typedef shared_ptr PRealDirectory; -extern PRealDirectory CreateRealSubdirectory(const PRealDirectory& realDirectory, const std::string& subdirectoryName); +extern PRealDirectory CreateRealSubdirectory(const PRealDirectory& realDirectory, const std::wstring& subdirectoryName); #endif // #ifndef INCLUDED_REAL_DIRECTORY diff --git a/source/lib/file/common/tests/test_trace.h b/source/lib/file/common/tests/test_trace.h index d11eeb5776..b6f0d63b10 100644 --- a/source/lib/file/common/tests/test_trace.h +++ b/source/lib/file/common/tests/test_trace.h @@ -24,35 +24,35 @@ class TestTraceEntry : public CxxTest::TestSuite public: void test_entry() { - char buf1[1024]; - char buf2[1024]; + std::wstring buf1; + std::wstring buf2; - TraceEntry t1(TraceEntry::Load, "example.txt", 1234); + TraceEntry t1(TraceEntry::Load, L"example.txt", 1234); TS_ASSERT_EQUALS(t1.Action(), TraceEntry::Load); - TS_ASSERT_STR_EQUALS(t1.Pathname(), "example.txt"); + TS_ASSERT_WSTR_EQUALS(t1.Pathname().string(), L"example.txt"); TS_ASSERT_EQUALS(t1.Size(), (size_t)1234); - t1.EncodeAsText(buf1, sizeof(buf1)); + buf1 = t1.EncodeAsText(); // The part before the ':' is an unpredictable timestamp, // so just test the string after that point - TS_ASSERT_STR_EQUALS(strchr(buf1, ':'), ": L \"example.txt\" 1234\n"); + TS_ASSERT_WSTR_EQUALS(wcschr(buf1.c_str(), ':'), L": L \"example.txt\" 1234\n"); - TraceEntry t2(TraceEntry::Store, "example two.txt", 16777216); + TraceEntry t2(TraceEntry::Store, L"example two.txt", 16777216); TS_ASSERT_EQUALS(t2.Action(), TraceEntry::Store); - TS_ASSERT_STR_EQUALS(t2.Pathname(), "example two.txt"); + TS_ASSERT_WSTR_EQUALS(t2.Pathname().string(), L"example two.txt"); TS_ASSERT_EQUALS(t2.Size(), (size_t)16777216); - t2.EncodeAsText(buf2, sizeof(buf2)); - TS_ASSERT_STR_EQUALS(strchr(buf2, ':'), ": S \"example two.txt\" 16777216\n"); + buf2 = t2.EncodeAsText(); + TS_ASSERT_WSTR_EQUALS(wcschr(buf2.c_str(), ':'), L": S \"example two.txt\" 16777216\n"); TraceEntry t3(buf1); TS_ASSERT_EQUALS(t3.Action(), TraceEntry::Load); - TS_ASSERT_STR_EQUALS(t3.Pathname(), "example.txt"); + TS_ASSERT_WSTR_EQUALS(t3.Pathname().string(), L"example.txt"); TS_ASSERT_EQUALS(t3.Size(), (size_t)1234); TraceEntry t4(buf2); TS_ASSERT_EQUALS(t4.Action(), TraceEntry::Store); - TS_ASSERT_STR_EQUALS(t4.Pathname(), "example two.txt"); + TS_ASSERT_WSTR_EQUALS(t4.Pathname().string(), L"example two.txt"); TS_ASSERT_EQUALS(t4.Size(), (size_t)16777216); } }; diff --git a/source/lib/file/common/trace.cpp b/source/lib/file/common/trace.cpp index 47419027e3..e4da1dc137 100644 --- a/source/lib/file/common/trace.cpp +++ b/source/lib/file/common/trace.cpp @@ -25,7 +25,10 @@ #include #include "lib/allocators/pool.h" +#include "lib/bits.h" // round_up #include "lib/timer.h" // timer_Time +#include "lib/path_util.h" + /*virtual*/ ITrace::~ITrace() { @@ -35,43 +38,39 @@ //----------------------------------------------------------------------------- -TraceEntry::TraceEntry(EAction action, const char* pathname, size_t size) +TraceEntry::TraceEntry(EAction action, const fs::wpath& pathname, size_t size) : m_timestamp((float)timer_Time()) , m_action(action) -, m_pathname(strdup(pathname)) +, m_pathname(pathname) , m_size(size) { } -TraceEntry::TraceEntry(const char* text) +TraceEntry::TraceEntry(const std::wstring& text) { - char pathname[PATH_MAX] = ""; - char action; + wchar_t pathname[PATH_MAX] = L""; + wchar_t action; #if EMULATE_SECURE_CRT - #define TRACE_FORMAT "%f: %c \"%" STRINGIZE(PATH_MAX) "[^\"]\" %zd\n" /* use a macro to allow compile-time type-checking */ - const int fieldsRead = sscanf(text, TRACE_FORMAT, &m_timestamp, &action, pathname, &m_size); + #define TRACE_FORMAT L"%f: %c \"%" STRINGIZE(PATH_MAX) "[^\"]\" %zd\n" /* use a macro to allow compile-time type-checking */ + const int fieldsRead = swscanf(text.c_str(), TRACE_FORMAT, &m_timestamp, &action, pathname, &m_size); #else - #define TRACE_FORMAT "%f: %c \"%[^\"]\" %d\n" - const int fieldsRead = sscanf_s(text, TRACE_FORMAT, &m_timestamp, &action, 1, pathname, PATH_MAX, &m_size); + #define TRACE_FORMAT L"%f: %c \"%[^\"]\" %d\n" + const int fieldsRead = swscanf_s(text.c_str(), TRACE_FORMAT, &m_timestamp, &action, 1, pathname, PATH_MAX, &m_size); #endif debug_assert(fieldsRead == 4); debug_assert(action == 'L' || action == 'S'); m_action = (EAction)action; - m_pathname = strdup(pathname); + m_pathname = pathname; } -TraceEntry::~TraceEntry() +std::wstring TraceEntry::EncodeAsText() const { - SAFE_FREE(m_pathname); -} - - -void TraceEntry::EncodeAsText(char* text, size_t maxTextChars) const -{ - const char action = (char)m_action; - sprintf_s(text, maxTextChars, "%#010f: %c \"%s\" %lu\n", m_timestamp, action, m_pathname, (unsigned long)m_size); + const wchar_t action = (wchar_t)m_action; + wchar_t buf[1000]; + swprintf_s(buf, ARRAY_SIZE(buf), L"%#010f: %c \"%ls\" %lu\n", m_timestamp, action, m_pathname.string().c_str(), (unsigned long)m_size); + return buf; } @@ -85,20 +84,20 @@ public: } - virtual void NotifyLoad(const char* UNUSED(pathname), size_t UNUSED(size)) + virtual void NotifyLoad(const fs::wpath& UNUSED(pathname), size_t UNUSED(size)) { } - virtual void NotifyStore(const char* UNUSED(pathname), size_t UNUSED(size)) + virtual void NotifyStore(const fs::wpath& UNUSED(pathname), size_t UNUSED(size)) { } - virtual LibError Load(const char* UNUSED(pathname)) + virtual LibError Load(const fs::wpath& UNUSED(pathname)) { return INFO::OK; } - virtual LibError Store(const char* UNUSED(pathname)) const + virtual LibError Store(const fs::wpath& UNUSED(pathname)) const { return INFO::OK; } @@ -127,34 +126,39 @@ public: virtual ~Trace() { - TraceEntry* entries = (TraceEntry*)m_pool.da.base; - for(TraceEntry* entry = entries; entry < entries+NumEntries(); entry++) + for(size_t i = 0; i < NumEntries(); i++) + { + TraceEntry* entry = (TraceEntry*)(uintptr_t(m_pool.da.base) + i*m_pool.el_size); entry->~TraceEntry(); + } + (void)pool_destroy(&m_pool); } - virtual void NotifyLoad(const char* pathname, size_t size) + virtual void NotifyLoad(const fs::wpath& pathname, size_t size) { new(Allocate()) TraceEntry(TraceEntry::Load, pathname, size); } - virtual void NotifyStore(const char* pathname, size_t size) + virtual void NotifyStore(const fs::wpath& pathname, size_t size) { new(Allocate()) TraceEntry(TraceEntry::Store, pathname, size); } - virtual LibError Load(const char* osPathname) + virtual LibError Load(const fs::wpath& pathname) { pool_free_all(&m_pool); + const fs::path pathname_c = path_from_wpath(pathname); errno = 0; - FILE* file = fopen(osPathname, "rt"); + FILE* file = fopen(pathname_c.string().c_str(), "rt"); if(!file) return LibError_from_errno(); + for(;;) { - char text[500]; - if(!fgets(text, ARRAY_SIZE(text)-1, file)) + wchar_t text[500]; + if(!fgetws(text, ARRAY_SIZE(text)-1, file)) break; new(Allocate()) TraceEntry(text); } @@ -163,17 +167,17 @@ public: return INFO::OK; } - virtual LibError Store(const char* osPathname) const + virtual LibError Store(const fs::wpath& pathname) const { + const fs::path pathname_c = path_from_wpath(pathname); errno = 0; - FILE* file = fopen(osPathname, "at"); + FILE* file = fopen(pathname_c.string().c_str(), "at"); if(!file) return LibError_from_errno(); for(size_t i = 0; i < NumEntries(); i++) { - char text[500]; - Entries()[i].EncodeAsText(text, ARRAY_SIZE(text)); - fputs(text, file); + std::wstring text = Entries()[i].EncodeAsText(); + fputws(text.c_str(), file); } (void)fclose(file); return INFO::OK; @@ -186,7 +190,7 @@ public: virtual size_t NumEntries() const { - return m_pool.da.pos / sizeof(TraceEntry); + return m_pool.da.pos / m_pool.el_size; } private: diff --git a/source/lib/file/common/trace.h b/source/lib/file/common/trace.h index d9162cef63..3c081c015e 100644 --- a/source/lib/file/common/trace.h +++ b/source/lib/file/common/trace.h @@ -40,16 +40,15 @@ public: Store = 'S' }; - TraceEntry(EAction action, const char* pathname, size_t size); - TraceEntry(const char* textualRepresentation); - ~TraceEntry(); + TraceEntry(EAction action, const fs::wpath& pathname, size_t size); + TraceEntry(const std::wstring& text); EAction Action() const { return m_action; } - const char* Pathname() const + const fs::wpath& Pathname() const { return m_pathname; } @@ -59,7 +58,7 @@ public: return m_size; } - void EncodeAsText(char* text, size_t maxTextChars) const; + std::wstring EncodeAsText() const; private: // note: keep an eye on the class size because all instances are kept @@ -72,7 +71,7 @@ private: EAction m_action; - const char* m_pathname; + fs::wpath m_pathname; // size of file. // rationale: other applications using this trace format might not @@ -87,28 +86,28 @@ struct ITrace { virtual ~ITrace(); - virtual void NotifyLoad(const char* pathname, size_t size) = 0; - virtual void NotifyStore(const char* pathname, size_t size) = 0; + virtual void NotifyLoad(const fs::wpath& pathname, size_t size) = 0; + virtual void NotifyStore(const fs::wpath& pathname, size_t size) = 0; /** * store all entries into a file. * - * @param osPathname native (absolute) pathname + * @param pathname (native, absolute) * * note: the file format is text-based to allow human inspection and * because storing filename strings in a binary format would be a * bit awkward. **/ - virtual LibError Store(const char* osPathname) const = 0; + virtual LibError Store(const fs::wpath& pathname) const = 0; /** * load entries from file. * - * @param osPathname native (absolute) pathname + * @param pathname (native, absolute) * * replaces any existing entries. **/ - virtual LibError Load(const char* osPathname) = 0; + virtual LibError Load(const fs::wpath& osPathname) = 0; virtual const TraceEntry* Entries() const = 0; virtual size_t NumEntries() const = 0; diff --git a/source/lib/file/file.cpp b/source/lib/file/file.cpp index fa769bc5b8..563a62e94e 100644 --- a/source/lib/file/file.cpp +++ b/source/lib/file/file.cpp @@ -25,22 +25,13 @@ #include "lib/file/common/file_stats.h" -ERROR_ASSOCIATE(ERR::FILE_ACCESS, "Insufficient access rights to open file", EACCES); -ERROR_ASSOCIATE(ERR::IO, "Error during IO", EIO); - - -fs::path path_from_wpath(const fs::wpath& pathname) -{ - char pathname_c[PATH_MAX]; - size_t numConverted = wcstombs(pathname_c, pathname.file_string().c_str(), PATH_MAX); - debug_assert(numConverted < PATH_MAX); - return fs::path(pathname_c); -} +ERROR_ASSOCIATE(ERR::FILE_ACCESS, L"Insufficient access rights to open file", EACCES); +ERROR_ASSOCIATE(ERR::IO, L"Error during IO", EIO); namespace FileImpl { -LibError Open(const fs::path& pathname, char mode, int& fd) +LibError Open(const fs::wpath& pathname, wchar_t mode, int& fd) { int oflag = -1; switch(mode) @@ -60,7 +51,7 @@ LibError Open(const fs::path& pathname, char mode, int& fd) #if OS_WIN oflag |= O_BINARY_NP; #endif - fd = open(pathname.file_string().c_str(), oflag, S_IRWXO|S_IRWXU|S_IRWXG); + fd = wopen(pathname.string().c_str(), oflag, S_IRWXO|S_IRWXU|S_IRWXG); if(fd < 0) WARN_RETURN(ERR::FILE_ACCESS); @@ -79,7 +70,7 @@ void Close(int& fd) } -LibError IO(int fd, char mode, off_t ofs, u8* buf, size_t size) +LibError IO(int fd, wchar_t mode, off_t ofs, u8* buf, size_t size) { debug_assert(mode == 'r' || mode == 'w'); @@ -101,7 +92,7 @@ LibError IO(int fd, char mode, off_t ofs, u8* buf, size_t size) } -LibError Issue(aiocb& req, int fd, char mode, off_t alignedOfs, u8* alignedBuf, size_t alignedSize) +LibError Issue(aiocb& req, int fd, wchar_t mode, off_t alignedOfs, u8* alignedBuf, size_t alignedSize) { memset(&req, 0, sizeof(req)); req.aio_lio_opcode = (mode == 'w')? LIO_WRITE : LIO_READ; diff --git a/source/lib/file/file.h b/source/lib/file/file.h index fe96174af5..6d34373a97 100644 --- a/source/lib/file/file.h +++ b/source/lib/file/file.h @@ -28,14 +28,12 @@ namespace ERR const LibError IO = -110301; } -LIB_API fs::path path_from_wpath(const fs::wpath& pathname); - namespace FileImpl { - LIB_API LibError Open(const fs::path& pathname, char mode, int& fd); + LIB_API LibError Open(const fs::wpath& pathname, wchar_t mode, int& fd); LIB_API void Close(int& fd); - LIB_API LibError IO(int fd, char mode, off_t ofs, u8* buf, size_t size); - LIB_API LibError Issue(aiocb& req, int fd, char mode, off_t alignedOfs, u8* alignedBuf, size_t alignedSize); + LIB_API LibError IO(int fd, wchar_t mode, off_t ofs, u8* buf, size_t size); + LIB_API LibError Issue(aiocb& req, int fd, wchar_t mode, off_t alignedOfs, u8* alignedBuf, size_t alignedSize); LIB_API LibError WaitUntilComplete(aiocb& req, u8*& alignedBuf, size_t& alignedSize); } @@ -49,7 +47,7 @@ public: { } - LibError Open(const fs::path& pathname, char mode) + LibError Open(const fs::wpath& pathname, wchar_t mode) { RETURN_ERR(FileImpl::Open(pathname, mode, m_fd)); m_pathname = pathname; @@ -57,25 +55,12 @@ public: return INFO::OK; } - LibError Open(const fs::wpath& pathname, char mode) - { - m_pathname = path_from_wpath(pathname); - RETURN_ERR(FileImpl::Open(m_pathname, mode, m_fd)); - m_mode = mode; - return INFO::OK; - } - void Close() { FileImpl::Close(m_fd); } - File(const fs::path& pathname, char mode) - { - (void)Open(pathname, mode); - } - - File(const fs::wpath& pathname, char mode) + File(const fs::wpath& pathname, wchar_t mode) { (void)Open(pathname, mode); } @@ -85,17 +70,17 @@ public: Close(); } - const fs::path& Pathname() const + const fs::wpath& Pathname() const { return m_pathname; } - char Mode() const + wchar_t Mode() const { return m_mode; } - LibError Issue(aiocb& req, char mode, off_t alignedOfs, u8* alignedBuf, size_t alignedSize) const + LibError Issue(aiocb& req, wchar_t mode, off_t alignedOfs, u8* alignedBuf, size_t alignedSize) const { return FileImpl::Issue(req, m_fd, mode, alignedOfs, alignedBuf, alignedSize); } @@ -111,9 +96,9 @@ public: } private: - fs::path m_pathname; + fs::wpath m_pathname; int m_fd; - char m_mode; + wchar_t m_mode; }; typedef shared_ptr PFile; diff --git a/source/lib/file/file_system.cpp b/source/lib/file/file_system.cpp index 60f1869ede..653b822b33 100644 --- a/source/lib/file/file_system.cpp +++ b/source/lib/file/file_system.cpp @@ -36,18 +36,20 @@ struct DirDeleter }; // is name "." or ".."? -static bool IsDummyDirectory(const char* name) +static bool IsDummyDirectory(const wchar_t* name) { if(name[0] != '.') return false; return (name[1] == '\0' || (name[1] == '.' && name[2] == '\0')); } -LibError GetDirectoryEntries(const fs::path& path, FileInfos* files, DirectoryNames* subdirectoryNames) +LibError GetDirectoryEntries(const fs::wpath& path, FileInfos* files, DirectoryNames* subdirectoryNames) { + fs::path path_c = path_from_wpath(path); + // open directory errno = 0; - DIR* pDir = opendir(path.external_file_string().c_str()); + DIR* pDir = opendir(path_c.string().c_str()); if(!pDir) return LibError_from_errno(false); shared_ptr osDir(pDir, DirDeleter()); @@ -64,7 +66,8 @@ LibError GetDirectoryEntries(const fs::path& path, FileInfos* files, DirectoryNa return LibError_from_errno(); } - const char* name = osEnt->d_name; + wchar_t name[PATH_MAX]; + mbstowcs(name, osEnt->d_name, ARRAY_SIZE(name)); RETURN_ERR(path_component_validate(name)); // get file information (mode, size, mtime) @@ -76,8 +79,9 @@ LibError GetDirectoryEntries(const fs::path& path, FileInfos* files, DirectoryNa #else // .. call regular stat(). errno = 0; - const fs::path pathname(path/name); - if(stat(pathname.external_directory_string().c_str(), &s) != 0) + const fs::wpath pathname(path/name); + const fs::path pathname_c = path_from_wpath(pathname); + if(stat(pathname_c.string().c_str(), &s) != 0) return LibError_from_errno(); #endif @@ -89,29 +93,21 @@ LibError GetDirectoryEntries(const fs::path& path, FileInfos* files, DirectoryNa } -LibError GetFileInfo(const fs::path& pathname, FileInfo* pfileInfo) +LibError GetFileInfo(const fs::wpath& pathname, FileInfo* pfileInfo) { - char osPathname[PATH_MAX]; - path_copy(osPathname, pathname.external_directory_string().c_str()); - - // if path ends in slash, remove it (required by stat) - char* last_char = osPathname+strlen(osPathname)-1; - if(path_is_dir_sep(*last_char)) - *last_char = '\0'; - + fs::path pathname_c = path_from_wpath(pathname); errno = 0; struct stat s; memset(&s, 0, sizeof(s)); - if(stat(osPathname, &s) != 0) + if(stat(pathname_c.string().c_str(), &s) != 0) return LibError_from_errno(); - const char* name = path_name_only(osPathname); - *pfileInfo = FileInfo(name, s.st_size, s.st_mtime); + *pfileInfo = FileInfo(pathname.leaf(), s.st_size, s.st_mtime); return INFO::OK; } -LibError CreateDirectories(const fs::path& path, mode_t mode) +LibError CreateDirectories(const fs::wpath& path, mode_t mode) { if(path.empty() || fs::exists(path)) { @@ -122,17 +118,16 @@ LibError CreateDirectories(const fs::path& path, mode_t mode) RETURN_ERR(CreateDirectories(path.branch_path(), mode)); - char osPath[PATH_MAX]; - path_copy(osPath, path.external_directory_string().c_str()); + const fs::path path_c = path_from_wpath(path); errno = 0; - if(mkdir(osPath, mode) != 0) + if(mkdir(path_c.string().c_str(), mode) != 0) return LibError_from_errno(); return INFO::OK; } -LibError DeleteDirectory(const fs::path& path) +LibError DeleteDirectory(const fs::wpath& path) { // note: we have to recursively empty the directory before it can // be deleted (required by Windows and POSIX rmdir()). @@ -143,9 +138,10 @@ LibError DeleteDirectory(const fs::path& path) // delete files for(size_t i = 0; i < files.size(); i++) { - const fs::path pathname(path/files[i].Name()); + const fs::wpath pathname(path/files[i].Name()); + const fs::path pathname_c = path_from_wpath(pathname); errno = 0; - if(unlink(pathname.external_file_string().c_str()) != 0) + if(unlink(pathname_c.string().c_str()) != 0) return LibError_from_errno(); } @@ -153,8 +149,9 @@ LibError DeleteDirectory(const fs::path& path) for(size_t i = 0; i < subdirectoryNames.size(); i++) RETURN_ERR(DeleteDirectory(path/subdirectoryNames[i])); + const fs::path path_c = path_from_wpath(path); errno = 0; - if(rmdir(path.external_directory_string().c_str()) != 0) + if(rmdir(path_c.string().c_str()) != 0) return LibError_from_errno(); return INFO::OK; diff --git a/source/lib/file/file_system.h b/source/lib/file/file_system.h index 82cc1d2eec..0292bacb6a 100644 --- a/source/lib/file/file_system.h +++ b/source/lib/file/file_system.h @@ -25,12 +25,12 @@ public: { } - FileInfo(const std::string& name, off_t size, time_t mtime) + FileInfo(const std::wstring& name, off_t size, time_t mtime) : m_name(name), m_size(size), m_mtime(mtime) { } - const std::string& Name() const + const std::wstring& Name() const { return m_name; } @@ -46,26 +46,26 @@ public: } private: - std::string m_name; + std::wstring m_name; off_t m_size; time_t m_mtime; }; -extern LibError GetFileInfo(const fs::path& pathname, FileInfo* fileInfo); +extern LibError GetFileInfo(const fs::wpath& pathname, FileInfo* fileInfo); typedef std::vector FileInfos; -typedef std::vector DirectoryNames; +typedef std::vector DirectoryNames; // jw 2007-12-20: we'd love to replace this with boost::filesystem, // but basic_directory_iterator does not yet cache file_size and // last_write_time in file_status. (they each entail a stat() call, // which is unacceptably slow.) -extern LibError GetDirectoryEntries(const fs::path& path, FileInfos* files, DirectoryNames* subdirectoryNames); +extern LibError GetDirectoryEntries(const fs::wpath& path, FileInfos* files, DirectoryNames* subdirectoryNames); // same as fs::create_directories, except that mkdir is invoked with // instead of 0755. -extern LibError CreateDirectories(const fs::path& path, mode_t mode); +extern LibError CreateDirectories(const fs::wpath& path, mode_t mode); -extern LibError DeleteDirectory(const fs::path& dirPath); +extern LibError DeleteDirectory(const fs::wpath& dirPath); #endif // #ifndef INCLUDED_FILE_SYSTEM diff --git a/source/lib/file/file_system_util.cpp b/source/lib/file/file_system_util.cpp index cd6340c1a2..d600023630 100644 --- a/source/lib/file/file_system_util.cpp +++ b/source/lib/file/file_system_util.cpp @@ -32,7 +32,7 @@ namespace fs_util { -LibError GetPathnames(const PIVFS& fs, const VfsPath& path, const char* filter, VfsPaths& pathnames) +LibError GetPathnames(const PIVFS& fs, const VfsPath& path, const wchar_t* filter, VfsPaths& pathnames) { std::vector files; RETURN_ERR(fs->GetDirectoryEntries(path, &files, 0)); @@ -54,7 +54,7 @@ struct FileInfoNameLess : public std::binary_function +struct NameLess : public std::binary_function { - bool operator()(const std::string& name1, const std::string& name2) const + bool operator()(const std::wstring& name1, const std::wstring& name2) const { - return strcasecmp(name1.c_str(), name2.c_str()) < 0; + return wcscasecmp(name1.c_str(), name2.c_str()) < 0; } }; @@ -78,7 +78,7 @@ void SortDirectories(DirectoryNames& directories) } -LibError ForEachFile(const PIVFS& fs, const VfsPath& startPath, FileCallback cb, uintptr_t cbData, const char* pattern, size_t flags) +LibError ForEachFile(const PIVFS& fs, const VfsPath& startPath, FileCallback cb, uintptr_t cbData, const wchar_t* pattern, size_t flags) { debug_assert(vfs_path_IsDirectory(startPath)); @@ -93,7 +93,7 @@ LibError ForEachFile(const PIVFS& fs, const VfsPath& startPath, FileCallback cb, { const VfsPath& path = pendingDirectories.front(); - RETURN_ERR(fs->GetDirectoryEntries(path/"/", &files, &subdirectoryNames)); + RETURN_ERR(fs->GetDirectoryEntries(path/L"/", &files, &subdirectoryNames)); for(size_t i = 0; i < files.size(); i++) { @@ -126,8 +126,8 @@ void NextNumberedFilename(const PIVFS& fs, const VfsPath& pathnameFormat, size_t // add 3rd -> without this measure it would get number 1, not 3. if(nextNumber == 0) { - const std::string nameFormat = pathnameFormat.leaf(); - const VfsPath path = pathnameFormat.branch_path()/"/"; + const std::wstring nameFormat = pathnameFormat.leaf(); + const VfsPath path = pathnameFormat.branch_path()/L"/"; size_t maxNumber = 0; FileInfos files; @@ -135,7 +135,7 @@ void NextNumberedFilename(const PIVFS& fs, const VfsPath& pathnameFormat, size_t for(size_t i = 0; i < files.size(); i++) { int number; - if(sscanf(files[i].Name().c_str(), nameFormat.c_str(), &number) == 1) + if(swscanf(files[i].Name().c_str(), nameFormat.c_str(), &number) == 1) maxNumber = std::max(size_t(number), maxNumber); } @@ -149,8 +149,8 @@ void NextNumberedFilename(const PIVFS& fs, const VfsPath& pathnameFormat, size_t // we don't bother with binary search - this isn't a bottleneck. do { - char pathnameBuf[PATH_MAX]; - snprintf(pathnameBuf, PATH_MAX, pathnameFormat.string().c_str(), nextNumber++); + wchar_t pathnameBuf[PATH_MAX]; + swprintf_s(pathnameBuf, ARRAY_SIZE(pathnameBuf), pathnameFormat.string().c_str(), nextNumber++); nextPathname = VfsPath(pathnameBuf); } while(fs->GetFileInfo(nextPathname, 0) == INFO::OK); diff --git a/source/lib/file/file_system_util.h b/source/lib/file/file_system_util.h index 6fdf73c1b0..52e0e295cc 100644 --- a/source/lib/file/file_system_util.h +++ b/source/lib/file/file_system_util.h @@ -29,7 +29,7 @@ namespace fs_util { extern void SortFiles(FileInfos& files); extern void SortDirectories(DirectoryNames& directories); -extern LibError GetPathnames(const PIVFS& fs, const VfsPath& path, const char* filter, VfsPaths& pathnames); +extern LibError GetPathnames(const PIVFS& fs, const VfsPath& path, const wchar_t* filter, VfsPaths& pathnames); /** @@ -60,7 +60,7 @@ enum DirFlags * @param flags see DirFlags * @param LibError **/ -extern LibError ForEachFile(const PIVFS& fs, const VfsPath& path, FileCallback cb, uintptr_t cbData, const char* pattern = 0, size_t flags = 0); +extern LibError ForEachFile(const PIVFS& fs, const VfsPath& path, FileCallback cb, uintptr_t cbData, const wchar_t* pattern = 0, size_t flags = 0); /** diff --git a/source/lib/file/io/block_cache.cpp b/source/lib/file/io/block_cache.cpp index abf5c395db..2c5dc347c5 100644 --- a/source/lib/file/io/block_cache.cpp +++ b/source/lib/file/io/block_cache.cpp @@ -37,9 +37,9 @@ BlockId::BlockId() { } -BlockId::BlockId(const fs::path& pathname, off_t ofs) +BlockId::BlockId(const fs::wpath& pathname, off_t ofs) { - m_id = fnv_hash64(pathname.string().c_str(), pathname.string().length()); + m_id = fnv_hash64(pathname.string().c_str(), pathname.string().length()*sizeof(pathname.string()[0])); const size_t indexBits = 16; m_id <<= indexBits; const off_t blockIndex = off_t(ofs / BLOCK_SIZE); diff --git a/source/lib/file/io/block_cache.h b/source/lib/file/io/block_cache.h index 15b61c8021..92c7ff6b04 100644 --- a/source/lib/file/io/block_cache.h +++ b/source/lib/file/io/block_cache.h @@ -29,7 +29,7 @@ class BlockId { public: BlockId(); - BlockId(const fs::path& pathname, off_t ofs); + BlockId(const fs::wpath& pathname, off_t ofs); bool operator==(const BlockId& rhs) const; bool operator!=(const BlockId& rhs) const; diff --git a/source/lib/file/vfs/vfs.cpp b/source/lib/file/vfs/vfs.cpp index f9cf729608..1aeda872d7 100644 --- a/source/lib/file/vfs/vfs.cpp +++ b/source/lib/file/vfs/vfs.cpp @@ -39,7 +39,7 @@ public: { } - virtual LibError Mount(const VfsPath& mountPoint, const fs::path& path, size_t flags /* = 0 */, size_t priority /* = 0 */) + virtual LibError Mount(const VfsPath& mountPoint, const fs::wpath& path, size_t flags /* = 0 */, size_t priority /* = 0 */) { debug_assert(vfs_path_IsDirectory(mountPoint)); CreateDirectories(path, 0700); @@ -79,7 +79,7 @@ public: CHECK_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, 0, VFS_LOOKUP_ADD|VFS_LOOKUP_CREATE)); const PRealDirectory& realDirectory = directory->AssociatedDirectory(); - const std::string& name = pathname.leaf(); + const std::wstring& name = pathname.leaf(); RETURN_ERR(realDirectory->Store(name, fileContents, size)); const VfsFile file(name, size, time(0), realDirectory->Priority(), realDirectory); @@ -108,7 +108,8 @@ public: if(!isCacheHit) { VfsDirectory* directory; VfsFile* file; - CHECK_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, &file)); + if(vfs_Lookup(pathname, &m_rootDirectory, directory, &file) < 0) + debug_break(); size = file->Size(); // safely handle zero-length files @@ -150,7 +151,7 @@ public: m_rootDirectory.DisplayR(0); } - virtual LibError GetRealPath(const VfsPath& pathname, fs::path& realPathname) + virtual LibError GetRealPath(const VfsPath& pathname, fs::wpath& realPathname) { VfsDirectory* directory; CHECK_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, 0)); diff --git a/source/lib/file/vfs/vfs.h b/source/lib/file/vfs/vfs.h index 7c7261c8fc..a5ffa2fc2a 100644 --- a/source/lib/file/vfs/vfs.h +++ b/source/lib/file/vfs/vfs.h @@ -66,7 +66,7 @@ struct IVFS * if files with archive extensions are seen, their contents are added * as well. **/ - virtual LibError Mount(const VfsPath& mountPoint, const fs::path& path, size_t flags = 0, size_t priority = 0) = 0; + virtual LibError Mount(const VfsPath& mountPoint, const fs::wpath& path, size_t flags = 0, size_t priority = 0) = 0; /** * retrieve information about a file (similar to POSIX stat) @@ -129,7 +129,7 @@ struct IVFS * * this is useful when passing paths to external libraries. **/ - virtual LibError GetRealPath(const VfsPath& pathname, fs::path& path) = 0; + virtual LibError GetRealPath(const VfsPath& pathname, fs::wpath& path) = 0; }; typedef shared_ptr PIVFS; diff --git a/source/lib/file/vfs/vfs_lookup.cpp b/source/lib/file/vfs/vfs_lookup.cpp index 1f804b8e8a..b72df6d9a7 100644 --- a/source/lib/file/vfs/vfs_lookup.cpp +++ b/source/lib/file/vfs/vfs_lookup.cpp @@ -51,7 +51,7 @@ LibError vfs_Lookup(const VfsPath& pathname, VfsDirectory* startDirectory, VfsDi VfsPath::iterator it; // (used outside of loop to get filename) for(it = pathname.begin(); it != --pathname.end(); ++it) { - const std::string& subdirectoryName = *it; + const std::wstring& subdirectoryName = *it; VfsDirectory* subdirectory = directory->GetSubdirectory(subdirectoryName); if(!subdirectory) @@ -64,12 +64,13 @@ LibError vfs_Lookup(const VfsPath& pathname, VfsDirectory* startDirectory, VfsDi if(createMissingDirectories && !subdirectory->AssociatedDirectory()) { - fs::path currentPath; + fs::wpath currentPath; if(directory->AssociatedDirectory()) // (is NULL when mounting into root) currentPath = directory->AssociatedDirectory()->Path(); currentPath /= subdirectoryName; - const int ret = mkdir(currentPath.external_directory_string().c_str(), S_IRWXU); + fs::path currentPath_c = path_from_wpath(currentPath); + const int ret = mkdir(currentPath_c.external_directory_string().c_str(), S_IRWXU); if(ret == 0) { PRealDirectory realDirectory(new RealDirectory(currentPath, 0, 0)); @@ -77,7 +78,7 @@ LibError vfs_Lookup(const VfsPath& pathname, VfsDirectory* startDirectory, VfsDi } else if(errno != EEXIST) // notify of unexpected failures { - debug_printf("mkdir failed with errno=%d\n", errno); + debug_printf(L"mkdir failed with errno=%d\n", errno); debug_assert(0); } } @@ -88,8 +89,8 @@ LibError vfs_Lookup(const VfsPath& pathname, VfsDirectory* startDirectory, VfsDi if(pfile) { - const std::string& filename = *it; - debug_assert(filename != "."); // asked for file but specified directory path + const std::wstring& filename = *it; + debug_assert(filename != L"."); // asked for file but specified directory path *pfile = directory->GetFile(filename); if(!*pfile) return ERR::VFS_FILE_NOT_FOUND; // NOWARN diff --git a/source/lib/file/vfs/vfs_path.cpp b/source/lib/file/vfs/vfs_path.cpp index 8e835825c1..8a71879c70 100644 --- a/source/lib/file/vfs/vfs_path.cpp +++ b/source/lib/file/vfs/vfs_path.cpp @@ -20,5 +20,5 @@ bool vfs_path_IsDirectory(const VfsPath& pathname) { - return pathname.empty() || pathname.leaf() == "."; + return pathname.empty() || pathname.leaf() == L"."; } diff --git a/source/lib/file/vfs/vfs_path.h b/source/lib/file/vfs/vfs_path.h index a22ee87a3f..10fd3e9bf6 100644 --- a/source/lib/file/vfs/vfs_path.h +++ b/source/lib/file/vfs/vfs_path.h @@ -34,14 +34,14 @@ struct VfsPathTraits; * rationale: a distinct specialization of basic_path prevents inadvertent * assignment from other path types. **/ -typedef fs::basic_path VfsPath; +typedef fs::basic_path VfsPath; typedef std::vector VfsPaths; struct VfsPathTraits { - typedef std::string internal_string_type; - typedef std::string external_string_type; + typedef std::wstring internal_string_type; + typedef std::wstring external_string_type; static external_string_type to_external(const VfsPath&, const internal_string_type& src) { diff --git a/source/lib/file/vfs/vfs_populate.cpp b/source/lib/file/vfs/vfs_populate.cpp index 851550213a..7e02e284f6 100644 --- a/source/lib/file/vfs/vfs_populate.cpp +++ b/source/lib/file/vfs/vfs_populate.cpp @@ -84,16 +84,15 @@ private: LibError AddFiles(const FileInfos& files) const { - const fs::path path(m_realDirectory->Path()); + const fs::wpath path(m_realDirectory->Path()); for(size_t i = 0; i < files.size(); i++) { - const std::string& name = files[i].Name(); - - const char* extension = path_extension(name.c_str()); - if(strcasecmp(extension, "zip") == 0) + const fs::wpath pathname = path/files[i].Name(); + const std::wstring extension = fs::extension(pathname); + if(wcscasecmp(extension.c_str(), L"zip") == 0) { - PIArchiveReader archiveReader = CreateArchiveReader_Zip(path/name); + PIArchiveReader archiveReader = CreateArchiveReader_Zip(pathname); RETURN_ERR(archiveReader->ReadEntries(AddArchiveFile, (uintptr_t)this)); } else // regular (non-archive) file @@ -109,7 +108,7 @@ private: { // skip version control directories - this avoids cluttering the // VFS with hundreds of irrelevant files. - if(strcasecmp(subdirectoryNames[i].c_str(), ".svn") == 0) + if(wcscasecmp(subdirectoryNames[i].c_str(), L".svn") == 0) continue; VfsDirectory* subdirectory = m_directory->AddSubdirectory(subdirectoryNames[i]); diff --git a/source/lib/file/vfs/vfs_tree.cpp b/source/lib/file/vfs/vfs_tree.cpp index 64e14e857a..085361c9a4 100644 --- a/source/lib/file/vfs/vfs_tree.cpp +++ b/source/lib/file/vfs/vfs_tree.cpp @@ -30,7 +30,7 @@ //----------------------------------------------------------------------------- -VfsFile::VfsFile(const std::string& name, size_t size, time_t mtime, size_t priority, const PIFileLoader& loader) +VfsFile::VfsFile(const std::wstring& name, size_t size, time_t mtime, size_t priority, const PIFileLoader& loader) : m_name(name), m_size(size), m_mtime(mtime), m_priority(priority), m_loader(loader) { } @@ -62,12 +62,12 @@ bool VfsFile::IsSupersededBy(const VfsFile& file) const } -void VfsFile::GenerateDescription(char* text, size_t maxChars) const +void VfsFile::GenerateDescription(wchar_t* text, size_t maxChars) const { - char timestamp[25]; + wchar_t timestamp[25]; const time_t mtime = MTime(); - strftime(timestamp, ARRAY_SIZE(timestamp), "%a %b %d %H:%M:%S %Y", localtime(&mtime)); - sprintf_s(text, maxChars, "(%c; %6lu; %s)\n", m_loader->LocationCode(), (unsigned long)Size(), timestamp); + wcsftime(timestamp, ARRAY_SIZE(timestamp), L"%a %b %d %H:%M:%S %Y", localtime(&mtime)); + swprintf_s(text, maxChars, L"(%c; %6lu; %ls)\n", m_loader->LocationCode(), (unsigned long)Size(), timestamp); } @@ -87,7 +87,7 @@ VfsDirectory::VfsDirectory() VfsFile* VfsDirectory::AddFile(const VfsFile& file) { - std::pair value = std::make_pair(file.Name(), file); + std::pair value = std::make_pair(file.Name(), file); std::pair ret = m_files.insert(value); if(!ret.second) // already existed { @@ -105,15 +105,15 @@ VfsFile* VfsDirectory::AddFile(const VfsFile& file) // rationale: passing in a pre-constructed VfsDirectory and copying that into // our map would be slower and less convenient for the caller. -VfsDirectory* VfsDirectory::AddSubdirectory(const std::string& name) +VfsDirectory* VfsDirectory::AddSubdirectory(const std::wstring& name) { - std::pair value = std::make_pair(name, VfsDirectory()); + std::pair value = std::make_pair(name, VfsDirectory()); std::pair ret = m_subdirectories.insert(value); return &(*ret.first).second; } -VfsFile* VfsDirectory::GetFile(const std::string& name) +VfsFile* VfsDirectory::GetFile(const std::wstring& name) { VfsFiles::iterator it = m_files.find(name); if(it == m_files.end()) @@ -122,7 +122,7 @@ VfsFile* VfsDirectory::GetFile(const std::string& name) } -VfsDirectory* VfsDirectory::GetSubdirectory(const std::string& name) +VfsDirectory* VfsDirectory::GetSubdirectory(const std::wstring& name) { VfsSubdirectories::iterator it = m_subdirectories.find(name); if(it == m_subdirectories.end()) @@ -153,33 +153,33 @@ void VfsDirectory::GetEntries(FileInfos* files, DirectoryNames* subdirectoryName void VfsDirectory::DisplayR(size_t depth) const { - static const char indent[] = " "; + static const wchar_t indent[] = L" "; - const size_t maxNameChars = 80 - depth*(sizeof(indent)-1); - char fmt[20]; - sprintf_s(fmt, ARRAY_SIZE(fmt), "%%-%lu.%lus %%s", (unsigned long)maxNameChars, (unsigned long)maxNameChars); + const size_t maxNameChars = 80 - depth*(ARRAY_SIZE(indent)-1); + wchar_t fmt[20]; + swprintf_s(fmt, ARRAY_SIZE(fmt), L"%%-%lu.%luls %%ls", (unsigned long)maxNameChars, (unsigned long)maxNameChars); for(VfsFiles::const_iterator it = m_files.begin(); it != m_files.end(); ++it) { - const std::string& name = it->first; + const std::wstring& name = it->first; const VfsFile& file = it->second; - char description[100]; + wchar_t description[100]; file.GenerateDescription(description, ARRAY_SIZE(description)); for(size_t i = 0; i < depth+1; i++) - printf("%s", indent); - printf(fmt, name.c_str(), description); + wprintf(L"%ls", indent); + wprintf(fmt, name.c_str(), description); } for(VfsSubdirectories::const_iterator it = m_subdirectories.begin(); it != m_subdirectories.end(); ++it) { - const std::string& name = it->first; + const std::wstring& name = it->first; const VfsDirectory& directory = it->second; for(size_t i = 0; i < depth+1; i++) - printf("%s", indent); - printf("[%s/]\n", name.c_str()); + wprintf(L"%ls", indent); + wprintf(L"[%ls/]\n", name.c_str()); directory.DisplayR(depth+1); } diff --git a/source/lib/file/vfs/vfs_tree.h b/source/lib/file/vfs/vfs_tree.h index d4769037ab..c01cb7ebb4 100644 --- a/source/lib/file/vfs/vfs_tree.h +++ b/source/lib/file/vfs/vfs_tree.h @@ -31,9 +31,9 @@ class VfsFile { public: - VfsFile(const std::string& name, size_t size, time_t mtime, size_t priority, const PIFileLoader& provider); + VfsFile(const std::wstring& name, size_t size, time_t mtime, size_t priority, const PIFileLoader& provider); - const std::string& Name() const + const std::wstring& Name() const { return m_name; } @@ -51,12 +51,12 @@ public: bool IsSupersededBy(const VfsFile& file) const; // store file attributes (timestamp, location, size) in a string. - void GenerateDescription(char* text, size_t maxChars) const; + void GenerateDescription(wchar_t* text, size_t maxChars) const; LibError Load(const shared_ptr& buf) const; private: - std::string m_name; + std::wstring m_name; size_t m_size; time_t m_mtime; @@ -81,10 +81,10 @@ public: * @return address of existing or newly inserted subdirectory; remains * valid until ClearR is called (i.e. VFS is rebuilt). **/ - VfsDirectory* AddSubdirectory(const std::string& name); + VfsDirectory* AddSubdirectory(const std::wstring& name); - VfsFile* GetFile(const std::string& name); - VfsDirectory* GetSubdirectory(const std::string& name); + VfsFile* GetFile(const std::wstring& name); + VfsDirectory* GetSubdirectory(const std::wstring& name); void GetEntries(FileInfos* files, DirectoryNames* subdirectories) const; @@ -110,10 +110,10 @@ public: bool ShouldPopulate(); private: - typedef std::map VfsFiles; + typedef std::map VfsFiles; VfsFiles m_files; - typedef std::map VfsSubdirectories; + typedef std::map VfsSubdirectories; VfsSubdirectories m_subdirectories; PRealDirectory m_realDirectory; diff --git a/source/lib/lib_errors.cpp b/source/lib/lib_errors.cpp index e94535d43d..7f8b0d156a 100644 --- a/source/lib/lib_errors.cpp +++ b/source/lib/lib_errors.cpp @@ -77,18 +77,18 @@ static const LibErrorAssociation* AssociationFromErrno(errno_t errno_equivalent) } -char* error_description_r(LibError err, char* buf, size_t max_chars) +wchar_t* error_description_r(LibError err, wchar_t* buf, size_t max_chars) { // lib error const LibErrorAssociation* lea = AssociationFromLibError(err); if(lea) { - strcpy_s(buf, max_chars, lea->description); + wcscpy_s(buf, max_chars, lea->description); return buf; } // unknown - snprintf(buf, max_chars, "Unknown error (%d, 0x%X)", (int)err, (unsigned int)err); + swprintf_s(buf, max_chars, L"Unknown error (%d, 0x%X)", (int)err, (unsigned int)err); return buf; } @@ -139,55 +139,55 @@ void LibError_set_errno(LibError err) //----------------------------------------------------------------------------- // INFO::OK doesn't really need a string because calling error_description_r(0) should never happen, but go the safe route. -ERROR_ASSOCIATE(INFO::OK, "(but return value was 0 which indicates success)", -1); -ERROR_ASSOCIATE(ERR::FAIL, "Function failed (no details available)", -1); +ERROR_ASSOCIATE(INFO::OK, L"(but return value was 0 which indicates success)", -1); +ERROR_ASSOCIATE(ERR::FAIL, L"Function failed (no details available)", -1); -ERROR_ASSOCIATE(INFO::CB_CONTINUE, "Continue (not an error)", -1); -ERROR_ASSOCIATE(INFO::SKIPPED, "Skipped (not an error)", -1); -ERROR_ASSOCIATE(INFO::CANNOT_HANDLE, "Cannot handle (not an error)", -1); -ERROR_ASSOCIATE(INFO::ALL_COMPLETE, "All complete (not an error)", -1); -ERROR_ASSOCIATE(INFO::ALREADY_EXISTS, "Already exists (not an error)", -1); +ERROR_ASSOCIATE(INFO::CB_CONTINUE, L"Continue (not an error)", -1); +ERROR_ASSOCIATE(INFO::SKIPPED, L"Skipped (not an error)", -1); +ERROR_ASSOCIATE(INFO::CANNOT_HANDLE, L"Cannot handle (not an error)", -1); +ERROR_ASSOCIATE(INFO::ALL_COMPLETE, L"All complete (not an error)", -1); +ERROR_ASSOCIATE(INFO::ALREADY_EXISTS, L"Already exists (not an error)", -1); -ERROR_ASSOCIATE(ERR::LOGIC, "Logic error in code", -1); -ERROR_ASSOCIATE(ERR::TIMED_OUT, "Timed out", -1); -ERROR_ASSOCIATE(ERR::REENTERED, "Single-call function was reentered", -1); -ERROR_ASSOCIATE(ERR::CORRUPTED, "File/memory data is corrupted", -1); -ERROR_ASSOCIATE(ERR::ASSERTION_FAILED, "Assertion failed", -1); +ERROR_ASSOCIATE(ERR::LOGIC, L"Logic error in code", -1); +ERROR_ASSOCIATE(ERR::TIMED_OUT, L"Timed out", -1); +ERROR_ASSOCIATE(ERR::REENTERED, L"Single-call function was reentered", -1); +ERROR_ASSOCIATE(ERR::CORRUPTED, L"File/memory data is corrupted", -1); +ERROR_ASSOCIATE(ERR::ASSERTION_FAILED, L"Assertion failed", -1); -ERROR_ASSOCIATE(ERR::INVALID_PARAM, "Invalid function argument", EINVAL); -ERROR_ASSOCIATE(ERR::INVALID_HANDLE, "Invalid Handle (argument)", -1); -ERROR_ASSOCIATE(ERR::BUF_SIZE, "Buffer argument too small", -1); -ERROR_ASSOCIATE(ERR::AGAIN, "Try again later", -1); -ERROR_ASSOCIATE(ERR::LIMIT, "Fixed limit exceeded", -1); -ERROR_ASSOCIATE(ERR::NO_SYS, "OS doesn't provide a required API", -1); -ERROR_ASSOCIATE(ERR::NOT_IMPLEMENTED, "Feature currently not implemented", ENOSYS); -ERROR_ASSOCIATE(ERR::NOT_SUPPORTED, "Feature isn't and won't be supported", -1); -ERROR_ASSOCIATE(ERR::NO_MEM, "Not enough memory", ENOMEM); +ERROR_ASSOCIATE(ERR::INVALID_PARAM, L"Invalid function argument", EINVAL); +ERROR_ASSOCIATE(ERR::INVALID_HANDLE, L"Invalid Handle (argument)", -1); +ERROR_ASSOCIATE(ERR::BUF_SIZE, L"Buffer argument too small", -1); +ERROR_ASSOCIATE(ERR::AGAIN, L"Try again later", -1); +ERROR_ASSOCIATE(ERR::LIMIT, L"Fixed limit exceeded", -1); +ERROR_ASSOCIATE(ERR::NO_SYS, L"OS doesn't provide a required API", -1); +ERROR_ASSOCIATE(ERR::NOT_IMPLEMENTED, L"Feature currently not implemented", ENOSYS); +ERROR_ASSOCIATE(ERR::NOT_SUPPORTED, L"Feature isn't and won't be supported", -1); +ERROR_ASSOCIATE(ERR::NO_MEM, L"Not enough memory", ENOMEM); -ERROR_ASSOCIATE(ERR::_1, "Case 1", -1); -ERROR_ASSOCIATE(ERR::_2, "Case 2", -1); -ERROR_ASSOCIATE(ERR::_3, "Case 3", -1); -ERROR_ASSOCIATE(ERR::_4, "Case 4", -1); -ERROR_ASSOCIATE(ERR::_5, "Case 5", -1); -ERROR_ASSOCIATE(ERR::_6, "Case 6", -1); -ERROR_ASSOCIATE(ERR::_7, "Case 7", -1); -ERROR_ASSOCIATE(ERR::_8, "Case 8", -1); -ERROR_ASSOCIATE(ERR::_9, "Case 9", -1); -ERROR_ASSOCIATE(ERR::_11, "Case 11", -1); -ERROR_ASSOCIATE(ERR::_12, "Case 12", -1); -ERROR_ASSOCIATE(ERR::_13, "Case 13", -1); -ERROR_ASSOCIATE(ERR::_14, "Case 14", -1); -ERROR_ASSOCIATE(ERR::_15, "Case 15", -1); -ERROR_ASSOCIATE(ERR::_16, "Case 16", -1); -ERROR_ASSOCIATE(ERR::_17, "Case 17", -1); -ERROR_ASSOCIATE(ERR::_18, "Case 18", -1); -ERROR_ASSOCIATE(ERR::_19, "Case 19", -1); -ERROR_ASSOCIATE(ERR::_21, "Case 21", -1); -ERROR_ASSOCIATE(ERR::_22, "Case 22", -1); -ERROR_ASSOCIATE(ERR::_23, "Case 23", -1); -ERROR_ASSOCIATE(ERR::_24, "Case 24", -1); -ERROR_ASSOCIATE(ERR::_25, "Case 25", -1); -ERROR_ASSOCIATE(ERR::_26, "Case 26", -1); -ERROR_ASSOCIATE(ERR::_27, "Case 27", -1); -ERROR_ASSOCIATE(ERR::_28, "Case 28", -1); -ERROR_ASSOCIATE(ERR::_29, "Case 29", -1); +ERROR_ASSOCIATE(ERR::_1, L"Case 1", -1); +ERROR_ASSOCIATE(ERR::_2, L"Case 2", -1); +ERROR_ASSOCIATE(ERR::_3, L"Case 3", -1); +ERROR_ASSOCIATE(ERR::_4, L"Case 4", -1); +ERROR_ASSOCIATE(ERR::_5, L"Case 5", -1); +ERROR_ASSOCIATE(ERR::_6, L"Case 6", -1); +ERROR_ASSOCIATE(ERR::_7, L"Case 7", -1); +ERROR_ASSOCIATE(ERR::_8, L"Case 8", -1); +ERROR_ASSOCIATE(ERR::_9, L"Case 9", -1); +ERROR_ASSOCIATE(ERR::_11, L"Case 11", -1); +ERROR_ASSOCIATE(ERR::_12, L"Case 12", -1); +ERROR_ASSOCIATE(ERR::_13, L"Case 13", -1); +ERROR_ASSOCIATE(ERR::_14, L"Case 14", -1); +ERROR_ASSOCIATE(ERR::_15, L"Case 15", -1); +ERROR_ASSOCIATE(ERR::_16, L"Case 16", -1); +ERROR_ASSOCIATE(ERR::_17, L"Case 17", -1); +ERROR_ASSOCIATE(ERR::_18, L"Case 18", -1); +ERROR_ASSOCIATE(ERR::_19, L"Case 19", -1); +ERROR_ASSOCIATE(ERR::_21, L"Case 21", -1); +ERROR_ASSOCIATE(ERR::_22, L"Case 22", -1); +ERROR_ASSOCIATE(ERR::_23, L"Case 23", -1); +ERROR_ASSOCIATE(ERR::_24, L"Case 24", -1); +ERROR_ASSOCIATE(ERR::_25, L"Case 25", -1); +ERROR_ASSOCIATE(ERR::_26, L"Case 26", -1); +ERROR_ASSOCIATE(ERR::_27, L"Case 27", -1); +ERROR_ASSOCIATE(ERR::_28, L"Case 28", -1); +ERROR_ASSOCIATE(ERR::_29, L"Case 29", -1); diff --git a/source/lib/lib_errors.h b/source/lib/lib_errors.h index 062017385d..d5df132389 100644 --- a/source/lib/lib_errors.h +++ b/source/lib/lib_errors.h @@ -162,7 +162,7 @@ struct LibErrorAssociation LibError err; // must remain valid until end of program. - const char* description; + const wchar_t* description; // POSIX errno, or -1 int errno_equivalent; @@ -193,7 +193,7 @@ extern int error_AddAssociation(LibErrorAssociation*); * @param max_chars size of buffer [characters] * @return buf (allows using this function in expressions) **/ -extern char* error_description_r(LibError err, char* buf, size_t max_chars); +extern wchar_t* error_description_r(LibError err, wchar_t* buf, size_t max_chars); //----------------------------------------------------------------------------- @@ -340,8 +340,8 @@ STMT(\ STMT(\ if(!(ok))\ {\ - debug_warn("FYI: WARN_RETURN_IF_FALSE reports that a function failed."\ - "feel free to ignore or suppress this warning.");\ + debug_warn(L"FYI: WARN_RETURN_IF_FALSE reports that a function failed."\ + L"feel free to ignore or suppress this warning.");\ return ERR::FAIL;\ }\ ) @@ -357,8 +357,8 @@ STMT(\ #define WARN_IF_FALSE(ok)\ STMT(\ if(!(ok))\ - debug_warn("FYI: WARN_IF_FALSE reports that a function failed."\ - "feel free to ignore or suppress this warning.");\ + debug_warn(L"FYI: WARN_IF_FALSE reports that a function failed."\ + L"feel free to ignore or suppress this warning.");\ ) diff --git a/source/lib/ogl.cpp b/source/lib/ogl.cpp index ba0e9a3b8d..db0b6872df 100644 --- a/source/lib/ogl.cpp +++ b/source/lib/ogl.cpp @@ -262,8 +262,8 @@ static void importExtensionFunctions() static void dump_gl_error(GLenum err) { - debug_printf("OGL| "); -#define E(e) case e: debug_printf("%s\n", #e); break; + debug_printf(L"OGL| "); +#define E(e) case e: debug_printf(L"%ls\n", WIDEN(#e)); break; switch (err) { E(GL_INVALID_ENUM) @@ -273,7 +273,7 @@ static void dump_gl_error(GLenum err) E(GL_STACK_UNDERFLOW) E(GL_OUT_OF_MEMORY) E(GL_INVALID_FRAMEBUFFER_OPERATION_EXT) - default: debug_printf("Unknown GL error: %04x\n", err); break; + default: debug_printf(L"Unknown GL error: %04x\n", err); break; } #undef E } @@ -302,8 +302,8 @@ void ogl_WarnIfError() if(error_enountered) { - char msg[64]; - snprintf(msg, ARRAY_SIZE(msg), "OpenGL error(s) occurred: %04x", (int)first_error); + wchar_t msg[64]; + swprintf_s(msg, ARRAY_SIZE(msg), L"OpenGL error(s) occurred: %04x", (int)first_error); debug_printf(msg); } } @@ -344,11 +344,7 @@ bool ogl_SquelchError(GLenum err_to_ignore) } if(error_enountered) - { - char msg[64]; - snprintf(msg, ARRAY_SIZE(msg), "OpenGL error(s) occurred: %04x", (int)first_error); - debug_printf(msg); - } + debug_printf(L"OpenGL error(s) occurred: %04x\n", (int)first_error); return error_ignored; } @@ -376,11 +372,11 @@ LibError ogl_get_gfx_info() if(!vendor || !renderer || !version) WARN_RETURN(ERR::AGAIN); - snprintf(gfx_card, ARRAY_SIZE(gfx_card), "%s %s", vendor, renderer); + swprintf_s(gfx_card, ARRAY_SIZE(gfx_card), L"%hs %hs", vendor, renderer); // add "OpenGL" to differentiate this from the real driver version // (returned by platform-specific detect routines). - snprintf(gfx_drv_ver, ARRAY_SIZE(gfx_drv_ver), "OpenGL %s", version); + swprintf_s(gfx_drv_ver, ARRAY_SIZE(gfx_drv_ver), L"OpenGL %hs", version); return INFO::OK; } diff --git a/source/lib/ogl.h b/source/lib/ogl.h index 7361aeb7d1..e0a1fc1841 100644 --- a/source/lib/ogl.h +++ b/source/lib/ogl.h @@ -117,7 +117,7 @@ extern const char* ogl_HaveExtensions(int dummy, ...) SENTINEL_ARG; * @return read-only C string of unspecified length containing all * advertised extension names, separated by space. **/ -extern const char* ogl_ExtensionString(void); +extern const char* ogl_ExtensionString(); // declare extension function pointers #if OS_WIN @@ -150,7 +150,7 @@ extern const char* ogl_ExtensionString(void); * * disabled in release mode for efficiency and to avoid annoying errors. **/ -extern void ogl_WarnIfError(void); +extern void ogl_WarnIfError(); #ifdef NDEBUG # define ogl_WarnIfError() #endif @@ -185,6 +185,6 @@ extern GLint ogl_max_tex_units; /// limit on GL_TEXTUREn * * @return LibError **/ -extern LibError ogl_get_gfx_info(void); +extern LibError ogl_get_gfx_info(); #endif // #ifndef INCLUDED_OGL diff --git a/source/lib/os_path.h b/source/lib/os_path.h index 6de500c231..9b46cfcad6 100644 --- a/source/lib/os_path.h +++ b/source/lib/os_path.h @@ -14,7 +14,3 @@ * You should have received a copy of the GNU General Public License * along with 0 A.D. If not, see . */ - -typedef fs::path OsPath; -typedef fs::basic_directory_entry OsDirectoryEntry; -typedef fs::basic_directory_iterator OsDirectoryIterator; diff --git a/source/lib/path_util.cpp b/source/lib/path_util.cpp index 884c15aac2..1e77f56028 100644 --- a/source/lib/path_util.cpp +++ b/source/lib/path_util.cpp @@ -26,15 +26,15 @@ #include -ERROR_ASSOCIATE(ERR::PATH_LENGTH, "path exceeds PATH_MAX characters", ENAMETOOLONG); -ERROR_ASSOCIATE(ERR::PATH_EMPTY, "path is an empty string", -1); -ERROR_ASSOCIATE(ERR::PATH_NOT_RELATIVE, "path is not relative", -1); -ERROR_ASSOCIATE(ERR::PATH_NON_PORTABLE, "path contains OS-specific dir separator", -1); -ERROR_ASSOCIATE(ERR::PATH_NON_CANONICAL, "path contains unsupported .. or ./", -1); -ERROR_ASSOCIATE(ERR::PATH_COMPONENT_SEPARATOR, "path component contains dir separator", -1); +ERROR_ASSOCIATE(ERR::PATH_LENGTH, L"path exceeds PATH_MAX characters", ENAMETOOLONG); +ERROR_ASSOCIATE(ERR::PATH_EMPTY, L"path is an empty string", -1); +ERROR_ASSOCIATE(ERR::PATH_NOT_RELATIVE, L"path is not relative", -1); +ERROR_ASSOCIATE(ERR::PATH_NON_PORTABLE, L"path contains OS-specific dir separator", -1); +ERROR_ASSOCIATE(ERR::PATH_NON_CANONICAL, L"path contains unsupported .. or ./", -1); +ERROR_ASSOCIATE(ERR::PATH_COMPONENT_SEPARATOR, L"path component contains dir separator", -1); -bool path_is_dir_sep(char c) +bool path_is_dir_sep(wchar_t c) { // note: ideally path strings would only contain '/' or even SYS_DIR_SEP. // however, windows-specific code (e.g. the sound driver detection) @@ -63,12 +63,12 @@ static bool path_is_dir_sepw(wchar_t c) } -bool path_IsDirectory(const char* path) +bool path_IsDirectory(const wchar_t* path) { if(path[0] == '\0') // root dir return true; - const char lastChar = path[strlen(path)-1]; + const wchar_t lastChar = path[wcslen(path)-1]; if(path_is_dir_sep(lastChar)) return true; @@ -78,13 +78,13 @@ bool path_IsDirectory(const char* path) // is s2 a subpath of s1, or vice versa? // (equal counts as subpath) -bool path_is_subpath(const char* s1, const char* s2) +bool path_is_subpath(const wchar_t* s1, const wchar_t* s2) { // make sure s1 is the shorter string - if(strlen(s1) > strlen(s2)) + if(wcslen(s1) > wcslen(s2)) std::swap(s1, s2); - char c1 = 0, last_c1, c2; + wchar_t c1 = 0, last_c1, c2; for(;;) { last_c1 = c1; @@ -139,15 +139,15 @@ bool path_is_subpathw(const wchar_t* s1, const wchar_t* s2) // if path is invalid, return a descriptive error code, otherwise INFO::OK. -LibError path_validate(const char* path) +LibError path_validate(const wchar_t* path) { // disallow "/", because it would create a second 'root' (with name = ""). // root dir is "". if(path[0] == '/') WARN_RETURN(ERR::PATH_NOT_RELATIVE); - // scan each char in path string; count length. - int c = 0; // current char; used for .. detection + // scan each wchar_t in path string; count length. + int c = 0; // current wchar_t; used for .. detection size_t path_len = 0; for(;;) { @@ -180,7 +180,7 @@ LibError path_validate(const char* path) // if name is invalid, return a descriptive error code, otherwise INFO::OK. // (name is a path component, i.e. that between directory separators) -LibError path_component_validate(const char* name) +LibError path_component_validate(const wchar_t* name) { // disallow empty strings if(*name == '\0') @@ -205,9 +205,9 @@ LibError path_component_validate(const char* name) // copy path strings (provided for convenience). -void path_copy(char* dst, const char* src) +void path_copy(wchar_t* dst, const wchar_t* src) { - strcpy_s(dst, PATH_MAX, src); + wcscpy_s(dst, PATH_MAX, src); } @@ -215,10 +215,10 @@ void path_copy(char* dst, const char* src) // if necessary, a directory separator is added between the paths. // each may be empty, filenames, or full paths. // total path length (including '\0') must not exceed PATH_MAX. -void path_append(char* dst, const char* path1, const char* path2, size_t flags) +void path_append(wchar_t* dst, const wchar_t* path1, const wchar_t* path2, size_t flags) { - const size_t len1 = strlen(path1); - const size_t len2 = strlen(path2); + const size_t len1 = wcslen(path1); + const size_t len2 = wcslen(path2); size_t total_len = len1 + len2 + 1; // includes '\0' const bool no_end_slash1 = (len1 == 0 || !path_is_dir_sep(path1[len1-1])); const bool no_end_slash2 = (len2 == 0 || !path_is_dir_sep(path2[len2-1])); @@ -250,13 +250,13 @@ void path_append(char* dst, const char* path1, const char* path2, size_t flags) return; } - SAFE_STRCPY(dst, path1); + SAFE_WCSCPY(dst, path1); dst += len1; if(need_separator) *dst++ = '/'; - SAFE_STRCPY(dst, path2); + SAFE_WCSCPY(dst, path2); if(need_terminator) - SAFE_STRCPY(dst+len2, "/"); + SAFE_WCSCPY(dst+len2, L"/"); } @@ -264,25 +264,25 @@ void path_append(char* dst, const char* path1, const char* path2, size_t flags) // return pointer to the name component within path (i.e. skips over all // characters up to the last dir separator, if any). -const char* path_name_only(const char* path) +const wchar_t* path_name_only(const wchar_t* path) { - const char* slash1 = strrchr(path, '/'); - const char* slash2 = strrchr(path, '\\'); + const wchar_t* slash1 = wcsrchr(path, '/'); + const wchar_t* slash2 = wcsrchr(path, '\\'); // neither present, it's a filename only if(!slash1 && !slash2) return path; // return name, i.e. component after the last slash - const char* name = std::max(slash1, slash2)+1; + const wchar_t* name = std::max(slash1, slash2)+1; if(name[0] != '\0') // else path_component_validate would complain path_component_validate(name); return name; } // if contains a name component, it is stripped away. -void path_strip_fn(char* path) +void path_strip_fn(wchar_t* path) { - char* name = (char*)path_name_only(path); + wchar_t* name = (wchar_t*)path_name_only(path); *name = '\0'; // cut off string here debug_assert(path_IsDirectory(path)); } @@ -290,11 +290,28 @@ void path_strip_fn(char* path) // return extension of , or "" if there is none. // NOTE: does not include the period; e.g. "a.bmp" yields "bmp". -const char* path_extension(const char* fn) +const wchar_t* path_extension(const wchar_t* fn) { - const char* dot = strrchr(fn, '.'); + const wchar_t* dot = wcsrchr(fn, '.'); if(!dot) - return ""; - const char* ext = dot+1; + return L""; + const wchar_t* ext = dot+1; return ext; } + + +fs::wpath wpath_from_path(const fs::path& pathname) +{ + wchar_t pathname_w[PATH_MAX]; + const size_t numConverted = mbstowcs(pathname_w, pathname.file_string().c_str(), ARRAY_SIZE(pathname_w)); + debug_assert(numConverted < PATH_MAX); // if == PATH_MAX, result isn't zero-terminated + return fs::wpath(pathname_w); +} + +fs::path path_from_wpath(const fs::wpath& pathname) +{ + char pathname_c[PATH_MAX]; + const size_t numConverted = wcstombs(pathname_c, pathname.file_string().c_str(), ARRAY_SIZE(pathname_c)); + debug_assert(numConverted < PATH_MAX); // if == PATH_MAX, result isn't zero-terminated + return fs::path(pathname_c); +} diff --git a/source/lib/path_util.h b/source/lib/path_util.h index 96532d9d34..c83644cbd7 100644 --- a/source/lib/path_util.h +++ b/source/lib/path_util.h @@ -48,7 +48,7 @@ namespace ERR * * @return LibError (ERR::PATH_* or INFO::OK) **/ -extern LibError path_validate(const char* path); +LIB_API LibError path_validate(const wchar_t* path); /** * return appropriate code if path is invalid, otherwise continue. @@ -60,7 +60,7 @@ extern LibError path_validate(const char* path); * * @return LibError (ERR::PATH_* or INFO::OK) **/ -extern LibError path_component_validate(const char* name); +LIB_API LibError path_component_validate(const wchar_t* name); /** * is the given character a path separator character? @@ -68,14 +68,14 @@ extern LibError path_component_validate(const char* name); * @param c character to test * @return bool **/ -extern bool path_is_dir_sep(char c); +LIB_API bool path_is_dir_sep(wchar_t c); /** * is the given path(name) a directory? * * @return bool **/ -extern bool path_IsDirectory(const char* path); +LIB_API bool path_IsDirectory(const wchar_t* path); /** * is s2 a subpath of s1, or vice versa? (equal counts as subpath) @@ -83,8 +83,8 @@ extern bool path_IsDirectory(const char* path); * @param s1, s2 comparand strings * @return bool **/ -extern bool path_is_subpath(const char* s1, const char* s2); -extern bool path_is_subpathw(const wchar_t* s1, const wchar_t* s2); +LIB_API bool path_is_subpath(const wchar_t* s1, const wchar_t* s2); +LIB_API bool path_is_subpathw(const wchar_t* s1, const wchar_t* s2); /** @@ -94,7 +94,7 @@ extern bool path_is_subpathw(const wchar_t* s1, const wchar_t* s2); * and should hold PATH_MAX chars. * @param src source; should not exceed PATH_MAX chars **/ -extern void path_copy(char* dst, const char* src); +LIB_API void path_copy(wchar_t* dst, const wchar_t* src); /** * flags controlling path_append behavior @@ -117,7 +117,7 @@ enum PathAppendFlags * total resulting string must not exceed PATH_MAX chars. * @param flags see PathAppendFlags. **/ -extern void path_append(char* dst, const char* path1, const char* path2, size_t flags = 0); +LIB_API void path_append(wchar_t* dst, const wchar_t* path1, const wchar_t* path2, size_t flags = 0); /** * get the name component of a path. @@ -126,14 +126,14 @@ extern void path_append(char* dst, const char* path1, const char* path2, size_t * @param path input path. * @return pointer to name component within . **/ -extern const char* path_name_only(const char* path); +LIB_API const wchar_t* path_name_only(const wchar_t* path); /** * strip away the name component in a path. * * @param path input and output; chopped by inserting '\0'. **/ -extern void path_strip_fn(char* path); +LIB_API void path_strip_fn(wchar_t* path); // deprecated in favor of fs::branch_path /** * get filename's extension. @@ -141,6 +141,10 @@ extern void path_strip_fn(char* path); * @return pointer to extension within , or "" if there is none. * NOTE: does not include the period; e.g. "a.bmp" yields "bmp". **/ -extern const char* path_extension(const char* fn); +LIB_API const wchar_t* path_extension(const wchar_t* fn); // deprecated in favor of fs::extension + + +LIB_API fs::wpath wpath_from_path(const fs::path& pathname); +LIB_API fs::path path_from_wpath(const fs::wpath& pathname); #endif // #ifndef INCLUDED_PATH_UTIL diff --git a/source/lib/regex.cpp b/source/lib/regex.cpp index 001314a67e..892ccaf0e7 100644 --- a/source/lib/regex.cpp +++ b/source/lib/regex.cpp @@ -26,56 +26,7 @@ #include "precompiled.h" -int match_wildcard(const char* s, const char* w) -{ - if(!w) - return 1; - - // saved position in both strings, used to expand '*': - // s2 is advanced until match. - // initially 0 - we abort on mismatch before the first '*'. - const char* s2 = 0; - const char* w2 = 0; - - while(*s) - { - const int wc = *w; - if(wc == '*') - { - // wildcard string ended with * => match. - if(*++w == '\0') - return 1; - - w2 = w; - s2 = s+1; - } - // match one character - else if(toupper(wc) == toupper(*s) || wc == '?') - { - w++; - s++; - } - // mismatched character - else - { - // no '*' found yet => mismatch. - if(!s2) - return 0; - - // resume at previous position+1 - w = w2; - s = s2++; - } - } - - // strip trailing * in wildcard string - while(*w == '*') - w++; - - return (*w == '\0'); -} - -int match_wildcardw(const wchar_t* s, const wchar_t* w) +int match_wildcard(const wchar_t* s, const wchar_t* w) { if(!w) return 1; diff --git a/source/lib/regex.h b/source/lib/regex.h index c5b9b90dda..db37001844 100644 --- a/source/lib/regex.h +++ b/source/lib/regex.h @@ -31,10 +31,8 @@ * * @return 1 if they match, otherwise 0. * - * algorithmfrom http://www.codeproject.com/string/wildcmp.asp. + * algorithm from http://www.codeproject.com/string/wildcmp.asp. **/ -extern int match_wildcard(const char* s, const char* w); -/// unicode version of match_wildcard. -extern int match_wildcardw(const wchar_t* s, const wchar_t* w); +extern int match_wildcard(const wchar_t* s, const wchar_t* w); #endif // #ifndef INCLUDED_REGEX diff --git a/source/lib/res/graphics/cursor.cpp b/source/lib/res/graphics/cursor.cpp index 0e28a29f82..a51415c2ea 100644 --- a/source/lib/res/graphics/cursor.cpp +++ b/source/lib/res/graphics/cursor.cpp @@ -186,27 +186,27 @@ static void Cursor_dtor(Cursor* c) static LibError Cursor_reload(Cursor* c, const VfsPath& name, Handle) { - const VfsPath path("art/textures/cursors"); - const std::string basename = name.string(); + const VfsPath path(L"art/textures/cursors"); + const VfsPath pathname(path/name); // read pixel offset of the cursor's hotspot [the bit of it that's // drawn at (g_mouse_x,g_mouse_y)] from file. int hotspotx = 0, hotspoty = 0; { - const VfsPath pathname(path / (basename + ".txt")); + const VfsPath pathnameHotspot = fs::change_extension(pathname, L".txt"); shared_ptr buf; size_t size; - RETURN_ERR(g_VFS->LoadFile(pathname, buf, size)); - std::stringstream s(std::string((const char*)buf.get(), size)); + RETURN_ERR(g_VFS->LoadFile(pathnameHotspot, buf, size)); + std::wstringstream s(std::wstring((const wchar_t*)buf.get(), size)); s >> hotspotx >> hotspoty; } - const VfsPath pathname(path / (basename + ".dds")); + const VfsPath pathnameImage = fs::change_extension(pathname, L".dds"); // try loading as system cursor (2d, hardware accelerated) - if(load_sys_cursor(pathname, hotspotx, hotspoty, &c->system_cursor) == INFO::OK) + if(load_sys_cursor(pathnameImage, hotspotx, hotspoty, &c->system_cursor) == INFO::OK) c->kind = CK_System; // fall back to GLCursor (system cursor code is disabled or failed) - else if(c->gl_cursor.create(pathname, hotspotx, hotspoty) == INFO::OK) + else if(c->gl_cursor.create(pathnameImage, hotspotx, hotspoty) == INFO::OK) { c->kind = CK_OpenGL; // (we need to hide the system cursor when using a OpenGL cursor) @@ -277,7 +277,7 @@ static LibError Cursor_to_string(const Cursor* c, char* buf) // in other words, we continually create/free the cursor resource in // cursor_draw and trust h_mgr's caching to absorb it. -static Handle cursor_load(const char* name) +static Handle cursor_load(const VfsPath& name) { return h_alloc(H_Cursor, name, 0); } @@ -288,7 +288,7 @@ static LibError cursor_free(Handle& h) } -LibError cursor_draw(const char* name, int x, int y) +LibError cursor_draw(const wchar_t* name, int x, int y) { // hide the cursor if(!name) diff --git a/source/lib/res/graphics/cursor.h b/source/lib/res/graphics/cursor.h index f8bb247771..d1e18bc695 100644 --- a/source/lib/res/graphics/cursor.h +++ b/source/lib/res/graphics/cursor.h @@ -31,7 +31,7 @@ * uses a hardware mouse cursor where available, otherwise a * portable OpenGL implementation. **/ -extern LibError cursor_draw(const char* name, int x, int y); +extern LibError cursor_draw(const wchar_t* name, int x, int y); // internal use only: extern int g_yres; diff --git a/source/lib/res/graphics/ogl_shader.cpp b/source/lib/res/graphics/ogl_shader.cpp index cb58c62755..a62cf18d71 100644 --- a/source/lib/res/graphics/ogl_shader.cpp +++ b/source/lib/res/graphics/ogl_shader.cpp @@ -33,14 +33,14 @@ extern PIVFS g_VFS; -#define LOG_CATEGORY "shaders" +#define LOG_CATEGORY L"shaders" -ERROR_ASSOCIATE(ERR::SHDR_CREATE, "Shader creation failed", -1); -ERROR_ASSOCIATE(ERR::SHDR_COMPILE, "Shader compile failed", -1); -ERROR_ASSOCIATE(ERR::SHDR_NO_SHADER, "Invalid shader reference", -1); -ERROR_ASSOCIATE(ERR::SHDR_LINK, "Shader linking failed", -1); -ERROR_ASSOCIATE(ERR::SHDR_NO_PROGRAM, "Invalid shader program reference", -1); +ERROR_ASSOCIATE(ERR::SHDR_CREATE, L"Shader creation failed", -1); +ERROR_ASSOCIATE(ERR::SHDR_COMPILE, L"Shader compile failed", -1); +ERROR_ASSOCIATE(ERR::SHDR_NO_SHADER, L"Invalid shader reference", -1); +ERROR_ASSOCIATE(ERR::SHDR_LINK, L"Shader linking failed", -1); +ERROR_ASSOCIATE(ERR::SHDR_NO_PROGRAM, L"Invalid shader program reference", -1); // Convert a shader object type into a descriptive string. @@ -139,23 +139,21 @@ static LibError Ogl_Shader_reload(Ogl_Shader* shdr, const VfsPath& pathname, Han if(ogl_SquelchError(GL_INVALID_ENUM)) goto fail_shadercreated; } - + + { + char typenamebuf[32]; + CStrW type(shader_type_to_string(shdr->type, typenamebuf, ARRAY_SIZE(typenamebuf))); + GLint log_length; GLint compile_success; pglGetShaderiv(shdr->id, GL_OBJECT_COMPILE_STATUS_ARB, &compile_success); pglGetShaderiv(shdr->id, GL_OBJECT_INFO_LOG_LENGTH_ARB, &log_length); if (log_length > 1) { - char typenamebuf[32]; char* infolog = new char[log_length]; - pglGetShaderInfoLog(shdr->id, log_length, 0, infolog); - - debug_printf("Compile log for shader %s (type %s):\n%s", - pathname.string().c_str(), - shader_type_to_string(shdr->type, typenamebuf, ARRAY_SIZE(typenamebuf)), - infolog); - + CStrW infologw(infolog); + debug_printf(L"Compile log for shader %ls (type %ls):\n%ls", pathname.string().c_str(), type.c_str(), infologw.c_str()); delete[] infolog; } @@ -167,14 +165,12 @@ static LibError Ogl_Shader_reload(Ogl_Shader* shdr, const VfsPath& pathname, Han // useful some time. ogl_WarnIfError(); - char typenamebuf[32]; - debug_printf("Failed to compile shader %s (type %s)\n", - pathname.string().c_str(), - shader_type_to_string(shdr->type, typenamebuf, ARRAY_SIZE(typenamebuf))); + debug_printf(L"Failed to compile shader %ls (type %ls)\n", pathname.string().c_str(), type.c_str()); err = ERR::SHDR_COMPILE; goto fail_shadercreated; } + } return INFO::OK; @@ -276,7 +272,7 @@ static LibError do_load_shader( if (Type.empty()) { - LOG(CLogger::Error, LOG_CATEGORY, "%s: Missing attribute \"type\" in element \"Shader\".", pathname.string().c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"%ls: Missing attribute \"type\" in element \"Shader\".", pathname.string().c_str()); WARN_RETURN(ERR::CORRUPTED); } @@ -284,19 +280,19 @@ static LibError do_load_shader( if (!shadertype) { - LOG(CLogger::Error, LOG_CATEGORY, "%s: Unknown shader type \"%s\" (valid are: VERTEX_SHADER, FRAGMENT_SHADER).", pathname.string().c_str(), Type.c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"%ls: Unknown shader type \"%hs\" (valid are: VERTEX_SHADER, FRAGMENT_SHADER).", pathname.string().c_str(), Type.c_str()); WARN_RETURN(ERR::CORRUPTED); } - CStr Name = Shader.GetText(); + CStr pathnameShader = Shader.GetText(); - if (Name.empty()) + if (pathnameShader.empty()) { - LOG(CLogger::Error, LOG_CATEGORY, "%s: Missing shader name.", pathname.string().c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"%ls: Missing shader name.", pathname.string().c_str()); WARN_RETURN(ERR::CORRUPTED); } - Handle hshader = ogl_shader_load(Name, shadertype); + Handle hshader = ogl_shader_load(CStrW(pathnameShader), shadertype); RETURN_ERR(hshader); ogl_shader_attach(p->id, hshader); @@ -312,7 +308,7 @@ static LibError do_load_shader( // Reload the program object from the source file. -static LibError Ogl_Program_reload(Ogl_Program* p, const VfsPath& pathname_, Handle h) +static LibError Ogl_Program_reload(Ogl_Program* p, const VfsPath& pathname, Handle h) { if (p->id) return INFO::OK; @@ -329,7 +325,6 @@ static LibError Ogl_Program_reload(Ogl_Program* p, const VfsPath& pathname_, Han WARN_RETURN(ERR::SHDR_CREATE); } - const char* pathname = pathname_.string().c_str(); CXeromyces XeroFile; if (XeroFile.Load(pathname) != PSRETURN_OK) WARN_RETURN(ERR::CORRUPTED); // more informative error message? @@ -345,7 +340,7 @@ static LibError Ogl_Program_reload(Ogl_Program* p, const VfsPath& pathname_, Han if (Root.GetNodeName() != el_program) { - LOG(CLogger::Error, LOG_CATEGORY, "%s: XML root was not \"Program\".", pathname); + LOG(CLogger::Error, LOG_CATEGORY, L"%ls: XML root was not \"Program\".", pathname.string().c_str()); WARN_RETURN(ERR::CORRUPTED); } @@ -366,7 +361,7 @@ static LibError Ogl_Program_reload(Ogl_Program* p, const VfsPath& pathname_, Han if (Shader.GetNodeName() != el_shader) { - LOG(CLogger::Error, LOG_CATEGORY, "%s: Only \"Shader\" may be child of \"Shaders\".", pathname); + LOG(CLogger::Error, LOG_CATEGORY, L"%ls: Only \"Shader\" may be child of \"Shaders\".", pathname.string().c_str()); WARN_RETURN(ERR::CORRUPTED); } @@ -375,7 +370,7 @@ static LibError Ogl_Program_reload(Ogl_Program* p, const VfsPath& pathname_, Han } else { - LOG(CLogger::Warning, LOG_CATEGORY, "%s: Unknown child of \"Program\".", pathname); + LOG(CLogger::Warning, LOG_CATEGORY, L"%ls: Unknown child of \"Program\".", pathname.string().c_str()); } } @@ -390,14 +385,14 @@ static LibError Ogl_Program_reload(Ogl_Program* p, const VfsPath& pathname_, Han { char* infolog = new char[log_length]; pglGetProgramInfoLog(p->id, log_length, 0, infolog); - - debug_printf("Linker log for %s:\n%s\n", pathname, infolog); + CStrW infologw(infolog); + debug_printf(L"Linker log for %ls:\n%ls\n", pathname.string().c_str(), infologw.c_str()); delete[] infolog; } if (!linked) { - debug_printf("Link failed for %s\n", pathname); + debug_printf(L"Link failed for %ls\n", pathname.string().c_str()); WARN_RETURN(ERR::SHDR_LINK); } @@ -433,9 +428,9 @@ static LibError Ogl_Program_to_string(const Ogl_Program* UNUSED(p), char* buf) // Load a program object based on the given XML file description. // Shader objects are loaded and attached automatically. -Handle ogl_program_load(const char* fn) +Handle ogl_program_load(const VfsPath& pathname) { - return h_alloc(H_Ogl_Program, fn, 0); + return h_alloc(H_Ogl_Program, pathname, 0); } // Free all resources associated with the given program handle. diff --git a/source/lib/res/graphics/ogl_shader.h b/source/lib/res/graphics/ogl_shader.h index 610da618a2..5944ed758b 100644 --- a/source/lib/res/graphics/ogl_shader.h +++ b/source/lib/res/graphics/ogl_shader.h @@ -76,7 +76,7 @@ Encapsulate program objects into handles. * * note: Shader objects are loaded and attached automatically. **/ -Handle ogl_program_load(const char* pathname); +Handle ogl_program_load(const VfsPath& pathname); /** * Free all resources associated with the given program handle. diff --git a/source/lib/res/graphics/ogl_tex.cpp b/source/lib/res/graphics/ogl_tex.cpp index bb34d74529..4d45b86741 100644 --- a/source/lib/res/graphics/ogl_tex.cpp +++ b/source/lib/res/graphics/ogl_tex.cpp @@ -499,7 +499,7 @@ Handle ogl_tex_load(const VfsPath& pathname, size_t flags) // is still in memory; otherwise, a negative error code. Handle ogl_tex_find(const VfsPath& pathname) { - const uintptr_t key = fnv_hash(pathname.string().c_str(), pathname.string().length()); + const uintptr_t key = fnv_hash(pathname.string().c_str(), pathname.string().length()*sizeof(pathname.string()[0])); return h_find(H_OglTex, key); } @@ -516,7 +516,7 @@ Handle ogl_tex_find(const VfsPath& pathname) // note: because we cannot guarantee that callers will pass distinct // "filenames", caching is disabled for the created object. this avoids // mistakenly reusing previous objects that share the same comment. -Handle ogl_tex_wrap(Tex* t, const char* fn, size_t flags) +Handle ogl_tex_wrap(Tex* t, const VfsPath& pathname, size_t flags) { // this object may not be backed by a file ("may", because // someone could do tex_load and then ogl_tex_wrap). @@ -526,7 +526,7 @@ Handle ogl_tex_wrap(Tex* t, const char* fn, size_t flags) // 'descriptive comment' instead of filename, but don't rely on that) // also disable caching as explained above. flags |= RES_DISALLOW_RELOAD|RES_NO_CACHE; - return h_alloc(H_OglTex, fn, flags, t); + return h_alloc(H_OglTex, pathname, flags, t); } @@ -687,9 +687,9 @@ static void detect_gl_upload_caps() // rationale: janwas's laptop's S3 card blows up if S3TC is used // (oh, the irony). it'd be annoying to have to share this between all // projects, hence this default implementation here. - if(!strcmp(gfx_card, "S3 SuperSavage/IXC 1014")) + if(!wcscmp(gfx_card, L"S3 SuperSavage/IXC 1014")) { - if(strstr(gfx_drv_ver, "ssicdnt.dll (2.60.115)")) + if(wcsstr(gfx_drv_ver, L"ssicdnt.dll (2.60.115)")) ogl_tex_override(OGL_TEX_S3TC, OGL_TEX_DISABLE); } } diff --git a/source/lib/res/graphics/ogl_tex.h b/source/lib/res/graphics/ogl_tex.h index 9b4ae248cb..947733c236 100644 --- a/source/lib/res/graphics/ogl_tex.h +++ b/source/lib/res/graphics/ogl_tex.h @@ -243,7 +243,7 @@ extern Handle ogl_tex_find(const VfsPath& pathname); * we need only add bookkeeping information and "wrap" it in * a resource object (accessed via Handle), hence the name. */ -extern Handle ogl_tex_wrap(Tex* t, const char* fn = 0, size_t flags = 0); +extern Handle ogl_tex_wrap(Tex* t, const VfsPath& pathname, size_t flags = 0); /** * Release this texture reference. When the count reaches zero, all of diff --git a/source/lib/res/graphics/tests/test_tex.h b/source/lib/res/graphics/tests/test_tex.h index 4868b61a15..55a396e14a 100644 --- a/source/lib/res/graphics/tests/test_tex.h +++ b/source/lib/res/graphics/tests/test_tex.h @@ -23,7 +23,7 @@ class TestTex : public CxxTest::TestSuite { - void generate_encode_decode_compare(size_t w, size_t h, size_t flags, size_t bpp, const std::string& extension) + void generate_encode_decode_compare(size_t w, size_t h, size_t flags, size_t bpp, const std::wstring& extension) { // generate test data const size_t size = w*h*bpp/8; @@ -69,8 +69,8 @@ public: // get an extension that this codec will support // (so that tex_encode uses this codec) - char extension[30] = {'.'}; - strcpy_s(extension+1, 29, c->name); + wchar_t extension[30] = {'.'}; + wcscpy_s(extension+1, 29, c->name); // .. make sure the c->name hack worked const TexCodecVTbl* correct_c = 0; TS_ASSERT_OK(tex_codec_for_filename(extension, &correct_c)); @@ -85,7 +85,7 @@ public: for(size_t bpp = 8; bpp <= 32; bpp += 8) { size_t flags = 0; - if(!strcmp(extension, ".dds")) + if(!wcscmp(extension, L".dds")) flags |= (TEX_DXT&3); // DXT3 if(bpp == 8) flags |= TEX_GREY; diff --git a/source/lib/res/graphics/unifont.cpp b/source/lib/res/graphics/unifont.cpp index 8da40b9593..c08f6dc4d1 100644 --- a/source/lib/res/graphics/unifont.cpp +++ b/source/lib/res/graphics/unifont.cpp @@ -82,13 +82,13 @@ static LibError UniFont_reload(UniFont* f, const VfsPath& basename, Handle UNUSE f->glyphs_id = new glyphmap_id(); f->glyphs_size = new glyphmap_size(); - const VfsPath path("fonts/"); + const VfsPath path(L"fonts/"); // Read font definition file into a stringstream shared_ptr buf; size_t size; - const VfsPath fntName(basename.string() + ".fnt"); + const VfsPath fntName(basename.string() + L".fnt"); RETURN_ERR(g_VFS->LoadFile(path/fntName, buf, size)); // [cumulative for 12: 36ms] - std::istringstream FNTStream (std::string((const char*)buf.get(), size)); + std::istringstream FNTStream(std::string((const char*)buf.get(), size)); int Version; FNTStream >> Version; @@ -156,7 +156,7 @@ static LibError UniFont_reload(UniFont* f, const VfsPath& basename, Handle UNUSE // Load glyph texture // [cumulative for 12: 20ms] - const VfsPath tgaName(basename.string() + ".tga"); + const VfsPath tgaName(basename.string() + L".tga"); Handle ht = ogl_tex_load(path/tgaName); RETURN_ERR(ht); (void)ogl_tex_set_filter(ht, GL_NEAREST); @@ -196,7 +196,7 @@ static LibError UniFont_to_string(const UniFont* f, char* buf) if (f->ht) // not true if this is called after dtor (which it is) { const VfsPath& path = h_filename(f->ht); - snprintf(buf, H_STRING_LEN, "Font %s", path.string().c_str()); + snprintf(buf, H_STRING_LEN, "Font %ls", path.string().c_str()); } else snprintf(buf, H_STRING_LEN, "Font"); @@ -261,7 +261,7 @@ void glvwprintf(const wchar_t* fmt, va_list args) int ret = vswprintf(buf, buf_size-1, fmt, args); if(ret < 0) { - debug_printf("glwprintf failed (buffer size exceeded?) - return value %d, errno %d\n", ret, errno); + debug_printf(L"glwprintf failed (buffer size exceeded?) - return value %d, errno %d\n", ret, errno); } // Make sure there's always null termination diff --git a/source/lib/res/h_mgr.cpp b/source/lib/res/h_mgr.cpp index 6a085e3095..70b4a0bc48 100644 --- a/source/lib/res/h_mgr.cpp +++ b/source/lib/res/h_mgr.cpp @@ -447,8 +447,8 @@ static u32 gen_tag() static u32 tag; if(++tag >= TAG_MASK) { - debug_warn("h_mgr: tag overflow - allocations are no longer unique."\ - "may not notice stale handle reuse. increase TAG_BITS."); + debug_warn(L"h_mgr: tag overflow - allocations are no longer unique."\ + L"may not notice stale handle reuse. increase TAG_BITS."); tag = 1; } return tag; @@ -564,9 +564,7 @@ Handle h_alloc(H_Type type, const VfsPath& pathname, size_t flags, ...) { RETURN_ERR(type_validate(type)); - const uintptr_t key = fnv_hash(pathname.string().c_str(), pathname.string().length()); - -//debug_printf("alloc %s %s\n", type->name, fn); + const uintptr_t key = fnv_hash(pathname.string().c_str(), pathname.string().length()*sizeof(pathname.string()[0])); // see if we can reuse an existing handle Handle h = reuse_existing_handle(key, type, flags); @@ -588,8 +586,6 @@ Handle h_alloc(H_Type type, const VfsPath& pathname, size_t flags, ...) // currently cannot fail. static LibError h_free_idx(ssize_t idx, HDATA* hd) { - // debug_printf("free %s %s\n", type->name, hd->fn); - // only decrement if refcount not already 0. if(hd->refs > 0) hd->refs--; @@ -613,16 +609,16 @@ static LibError h_free_idx(ssize_t idx, HDATA* hd) #ifndef NDEBUG // to_string is slow for some handles, so avoid calling it if unnecessary - if(debug_filter_allows("H_MGR|")) + if(debug_filter_allows(L"H_MGR|")) { char buf[H_STRING_LEN]; if(vtbl->to_string(hd->user, buf) < 0) strcpy(buf, "(error)"); // safe - debug_printf("H_MGR| free %s %s accesses=%lu %s\n", hd->type->name, hd->pathname.string().c_str(), (unsigned long)hd->num_derefs, buf); + debug_printf(L"H_MGR| free %ls %ls accesses=%lu %hs\n", hd->type->name, hd->pathname.string().c_str(), (unsigned long)hd->num_derefs, buf); } #endif - hd->pathname.~VfsPath(); // FIXME: ugly hack, but necessary to reclaim std::string memory + hd->pathname.~VfsPath(); // FIXME: ugly hack, but necessary to reclaim std::wstring memory memset(hd, 0, sizeof(*hd)); new (&hd->pathname) VfsPath; // FIXME too: necessary because otherwise it'll break if we reuse this page @@ -695,7 +691,7 @@ VfsPath h_filename(const Handle h) // TODO: what if iterating through all handles is too slow? LibError h_reload(const VfsPath& pathname) { - const u32 key = fnv_hash(pathname.string().c_str(), pathname.string().length()); + const u32 key = fnv_hash(pathname.string().c_str(), pathname.string().length()*sizeof(pathname.string()[0])); // destroy (note: not free!) all handles backed by this file. // do this before reloading any of them, because we don't specify reload @@ -813,7 +809,7 @@ void h_mgr_shutdown() if(!ModuleShouldShutdown(&initState)) return; - debug_printf("H_MGR| shutdown. any handle frees after this are leaks!\n"); + debug_printf(L"H_MGR| shutdown. any handle frees after this are leaks!\n"); // forcibly close all open handles for(ssize_t i = 0; i <= last_in_use; i++) @@ -844,7 +840,7 @@ void h_mgr_shutdown() { if (pages[j]) for(size_t k = 0; k < hdata_per_page; ++k) - pages[j][k].pathname.~VfsPath(); // FIXME: ugly hack, but necessary to reclaim std::string memory + pages[j][k].pathname.~VfsPath(); // FIXME: ugly hack, but necessary to reclaim std::wstring memory free(pages[j]); pages[j] = 0; } diff --git a/source/lib/res/h_mgr.h b/source/lib/res/h_mgr.h index d2b9534fee..6fc7476da7 100644 --- a/source/lib/res/h_mgr.h +++ b/source/lib/res/h_mgr.h @@ -294,7 +294,7 @@ struct H_VTbl LibError (*validate)(const void* user); LibError (*to_string)(const void* user, char* buf); size_t user_size; - const char* name; + const wchar_t* name; }; typedef H_VTbl* H_Type; @@ -314,7 +314,7 @@ typedef H_VTbl* H_Type; (LibError (*)(const void*))type##_validate,\ (LibError (*)(const void*, char*))type##_to_string,\ sizeof(type), /* control block size */\ - #type /* name */\ + WIDEN(#type) /* name */\ };\ static H_Type H_##type = &V_##type diff --git a/source/lib/res/sound/snd_mgr.cpp b/source/lib/res/sound/snd_mgr.cpp index 987c4c7bd7..d4294527e5 100644 --- a/source/lib/res/sound/snd_mgr.cpp +++ b/source/lib/res/sound/snd_mgr.cpp @@ -107,12 +107,11 @@ static LibError list_free_all(); static void hsd_list_free_all(); -static void al_ReportError(ALenum err, const char* caller, int line) +static void al_ReportError(ALenum err, const wchar_t* caller, int line) { debug_assert(al_initialized); - const char* str = (const char*)alGetString(err); - debug_printf("OpenAL error: %s; called from %s (line %d)\n", str, caller, line); + debug_printf(L"OpenAL error: %hs; called from %ls (line %d)\n", alGetString(err), caller, line); debug_assert(0); } @@ -124,7 +123,7 @@ static void al_ReportError(ALenum err, const char* caller, int line) * @param line line number of the call site (typically passed via __LINE__) * (identifies the exact call site since there may be several per caller) */ -static void al_check(const char* caller, int line) +static void al_check(const wchar_t* caller, int line) { ALenum err = alGetError(); if(err != AL_NO_ERROR) @@ -132,7 +131,7 @@ static void al_check(const char* caller, int line) } // convenience version that automatically passes in function name. -#define AL_CHECK al_check(__func__, __LINE__) +#define AL_CHECK al_check(__wfunc__, __LINE__) //----------------------------------------------------------------------------- @@ -263,7 +262,7 @@ static LibError alc_init() ALCenum err = alcGetError(alc_dev); if(err != ALC_NO_ERROR || !alc_dev || !alc_ctx) { - debug_printf("alc_init failed. alc_dev=%p alc_ctx=%p alc_dev_name=%s err=%d\n", alc_dev, alc_ctx, alc_dev_name, err); + debug_printf(L"alc_init failed. alc_dev=%p alc_ctx=%p alc_dev_name=%hs err=%d\n", alc_dev, alc_ctx, alc_dev_name, err); // FIXME Hack to get around exclusive access to the sound device #if OS_UNIX ret = INFO::OK; @@ -1216,11 +1215,11 @@ static LibError VSrc_reload(VSrc* vs, const VfsPath& pathname, Handle hvs) // pathname is a definition file containing the data file name and // its gain. - if(fs::extension(pathname) == ".txt") + if(fs::extension(pathname) == L".txt") { shared_ptr buf; size_t size; RETURN_ERR(g_VFS->LoadFile(pathname, buf, size)); - std::istringstream def(std::string((char*)buf.get(), (int)size)); + std::wistringstream def(std::wstring((wchar_t*)buf.get(), (int)size)); def >> dataPathname; def >> vs->gain; @@ -1268,7 +1267,7 @@ static LibError VSrc_validate(const VSrc* vs) return INFO::OK; } -static LibError VSrc_to_string(const VSrc* vs, char * buf) +static LibError VSrc_to_string(const VSrc* vs, char* buf) { snprintf(buf, H_STRING_LEN, "al_src = %d", vs->al_src); return INFO::OK; @@ -1469,18 +1468,18 @@ static void vsrc_latch(VSrc* vs) ALenum err = alGetError(); if(err != AL_NO_ERROR) { - debug_printf("vsrc_latch: one of the below is invalid:\n"); - debug_printf(" al_src: %d\n", vs->al_src); - debug_printf(" pos: %f %f %f\n", vs->pos[0], vs->pos[1], vs->pos[2]); - debug_printf(" relative: %d\n", (int)vs->relative); - debug_printf(" rolloff: %f\n", rolloff); - debug_printf(" ref dist: %f\n", referenceDistance); - debug_printf(" max dist: %f\n", maxDistance); - debug_printf(" gain: %f\n", vs->gain); - debug_printf(" pitch: %f\n", vs->pitch); - debug_printf(" loop: %d\n", (int)vs->loop); + debug_printf(L"vsrc_latch: one of the below is invalid:\n"); + debug_printf(L" al_src: %d\n", vs->al_src); + debug_printf(L" pos: %f %f %f\n", vs->pos[0], vs->pos[1], vs->pos[2]); + debug_printf(L" relative: %d\n", (int)vs->relative); + debug_printf(L" rolloff: %f\n", rolloff); + debug_printf(L" ref dist: %f\n", referenceDistance); + debug_printf(L" max dist: %f\n", maxDistance); + debug_printf(L" gain: %f\n", vs->gain); + debug_printf(L" pitch: %f\n", vs->pitch); + debug_printf(L" loop: %d\n", (int)vs->loop); - al_ReportError(err, __func__, __LINE__); + al_ReportError(err, __wfunc__, __LINE__); } } diff --git a/source/lib/secure_crt.cpp b/source/lib/secure_crt.cpp index 1234337f61..3aba14cee6 100644 --- a/source/lib/secure_crt.cpp +++ b/source/lib/secure_crt.cpp @@ -31,7 +31,7 @@ // we were included from wsecure_crt.cpp; skip all stuff that // must only be done once. #ifndef WSECURE_CRT -ERROR_ASSOCIATE(ERR::STRING_NOT_TERMINATED, "Invalid string (no 0 terminator found in buffer)", -1); +ERROR_ASSOCIATE(ERR::STRING_NOT_TERMINATED, L"Invalid string (no 0 terminator found in buffer)", -1); #endif diff --git a/source/lib/self_test.cpp b/source/lib/self_test.cpp index 2b90d674ef..be59d40562 100644 --- a/source/lib/self_test.cpp +++ b/source/lib/self_test.cpp @@ -54,7 +54,7 @@ int self_test_register(SelfTestRecord* r) void self_test_run_all() { - debug_printf("SELF TESTS:\n"); + debug_printf(L"SELF TESTS:\n"); const double t0 = timer_Time(); // someone somewhere may want to run self-tests twice (e.g. to help @@ -68,7 +68,7 @@ void self_test_run_all() } const double dt = timer_Time() - t0; - debug_printf("-- done (elapsed time %.0f ms)\n", dt*1e3); + debug_printf(L"-- done (elapsed time %.0f ms)\n", dt*1e3); } #endif diff --git a/source/lib/self_test.h b/source/lib/self_test.h index 8ea5bf12d5..15f86d41c9 100644 --- a/source/lib/self_test.h +++ b/source/lib/self_test.h @@ -130,7 +130,7 @@ For further details, see below. ) -// your source file should contain a function: void self_test(void) that +// your source file should contain a function: void self_test() that // performs all tests or calls out to individual test functions. // this macro calls it at static init time and takes care of setting // self_test_active (see above). @@ -216,8 +216,8 @@ namespace CxxTest #define TS_ASSERT_STR_EQUALS(str1, str2) TS_ASSERT_EQUALS(std::string(str1), std::string(str2)) #define TS_ASSERT_WSTR_EQUALS(str1, str2) TS_ASSERT_EQUALS(std::wstring(str1), std::wstring(str2)) -bool ts_str_contains(const std::string& str1, const std::string& str2); // defined in test_setup.cpp -#define TS_ASSERT_STR_CONTAINS(str1, str2) TS_ASSERT(ts_str_contains(str1, str2)) +bool ts_str_contains(const std::wstring& str1, const std::wstring& str2); // defined in test_setup.cpp +#define TS_ASSERT_WSTR_CONTAINS(str1, str2) TS_ASSERT(ts_str_contains(str1, str2)) template std::vector ts_make_vector(T* start, size_t size_bytes) diff --git a/source/lib/sysdep/cpu.cpp b/source/lib/sysdep/cpu.cpp index 16f1a59272..e850b872c4 100644 --- a/source/lib/sysdep/cpu.cpp +++ b/source/lib/sysdep/cpu.cpp @@ -22,6 +22,6 @@ #include "precompiled.h" #include "cpu.h" -ERROR_ASSOCIATE(ERR::CPU_FEATURE_MISSING, "This CPU doesn't support a required feature", -1); -ERROR_ASSOCIATE(ERR::CPU_UNKNOWN_OPCODE, "Disassembly failed", -1); -ERROR_ASSOCIATE(ERR::CPU_UNKNOWN_VENDOR, "CPU vendor unknown", -1); +ERROR_ASSOCIATE(ERR::CPU_FEATURE_MISSING, L"This CPU doesn't support a required feature", -1); +ERROR_ASSOCIATE(ERR::CPU_UNKNOWN_OPCODE, L"Disassembly failed", -1); +ERROR_ASSOCIATE(ERR::CPU_UNKNOWN_VENDOR, L"CPU vendor unknown", -1); diff --git a/source/lib/sysdep/dir_watch.h b/source/lib/sysdep/dir_watch.h index cb7fd5271b..0a8a930fb8 100644 --- a/source/lib/sysdep/dir_watch.h +++ b/source/lib/sysdep/dir_watch.h @@ -75,16 +75,16 @@ public: return m_type; } - static const char* EventString(Event type) + static const wchar_t* EventString(Event type) { switch(type) { case Created: - return "created"; + return L"created"; case Deleted: - return "deleted"; + return L"deleted"; case Changed: - return "changed"; + return L"changed"; default: throw std::logic_error("invalid type"); } diff --git a/source/lib/sysdep/gfx.cpp b/source/lib/sysdep/gfx.cpp index efedbd4d06..bd2980fbea 100644 --- a/source/lib/sysdep/gfx.cpp +++ b/source/lib/sysdep/gfx.cpp @@ -29,8 +29,8 @@ #endif -char gfx_card[GFX_CARD_LEN] = ""; -char gfx_drv_ver[GFX_DRV_VER_LEN] = ""; +wchar_t gfx_card[GFX_CARD_LEN] = L""; +wchar_t gfx_drv_ver[GFX_DRV_VER_LEN] = L""; int gfx_mem = -1; // [MiB]; approximate @@ -55,11 +55,11 @@ void gfx_detect() // remove crap from vendor names. (don't dare touch the model name - // it's too risky, there are too many different strings) #define SHORTEN(what, chars_to_keep)\ - if(!strncmp(gfx_card, what, ARRAY_SIZE(what)-1))\ - memmove(gfx_card+chars_to_keep, gfx_card+ARRAY_SIZE(what)-1, strlen(gfx_card)-(ARRAY_SIZE(what)-1)+1); - SHORTEN("ATI Technologies Inc.", 3); - SHORTEN("NVIDIA Corporation", 6); - SHORTEN("S3 Graphics", 2); // returned by EnumDisplayDevices - SHORTEN("S3 Graphics, Incorporated", 2); // returned by GL_VENDOR + if(!wcsncmp(gfx_card, what, ARRAY_SIZE(what)-1))\ + memmove(gfx_card+chars_to_keep, gfx_card+ARRAY_SIZE(what)-1, (wcslen(gfx_card)-ARRAY_SIZE(what))*sizeof(wchar_t)); + SHORTEN(L"ATI Technologies Inc.", 3); + SHORTEN(L"NVIDIA Corporation", 6); + SHORTEN(L"S3 Graphics", 2); // returned by EnumDisplayDevices + SHORTEN(L"S3 Graphics, Incorporated", 2); // returned by GL_VENDOR #undef SHORTEN } diff --git a/source/lib/sysdep/gfx.h b/source/lib/sysdep/gfx.h index 9926660e66..cbe3ac51c9 100644 --- a/source/lib/sysdep/gfx.h +++ b/source/lib/sysdep/gfx.h @@ -27,7 +27,7 @@ const size_t GFX_CARD_LEN = 128; * description of graphics card. * initial value is "". **/ -extern char gfx_card[GFX_CARD_LEN]; +extern wchar_t gfx_card[GFX_CARD_LEN]; // note: increased from 64 by Joe Cocovich; this large size is necessary // because there must be enough space to list the versions of all drivers @@ -37,7 +37,7 @@ const size_t GFX_DRV_VER_LEN = 256; * (OpenGL) graphics driver identification and version. * initial value is "". **/ -extern char gfx_drv_ver[GFX_DRV_VER_LEN]; +extern wchar_t gfx_drv_ver[GFX_DRV_VER_LEN]; /** * approximate amount of graphics memory [MiB] @@ -47,7 +47,7 @@ extern int gfx_mem; /** * detect graphics card and set the above information. **/ -extern void gfx_detect(void); +extern void gfx_detect(); /** diff --git a/source/lib/sysdep/os/osx/osx.cpp b/source/lib/sysdep/os/osx/osx.cpp index acaf33c01f..fb55307461 100644 --- a/source/lib/sysdep/os/osx/osx.cpp +++ b/source/lib/sysdep/os/osx/osx.cpp @@ -85,9 +85,9 @@ LibError sys_get_executable_name(char* n_path, size_t max_chars) { return ERR::NO_SYS; } - debug_printf("exe name before realpath: %s\n", temp); + debug_printf(L"exe name before realpath: %hs\n", temp); realpath(temp, name); - debug_printf("exe name after realpath: %s\n", temp); + debug_printf(L"exe name after realpath: %hs\n", temp); } // On OS X, we might be in a bundle. In this case set its name as our name. @@ -95,11 +95,11 @@ LibError sys_get_executable_name(char* n_path, size_t max_chars) if (app) { // Remove everything after the .app *(app + strlen(".app")) = '\0'; - debug_printf("app bundle name: %s\n", name); + debug_printf(L"app bundle name: %hs\n", name); } strncpy(n_path, name, max_chars); - debug_printf("returning exe name: %s\n", name); + debug_printf(L"returning exe name: %hs\n", name); return INFO::OK; } diff --git a/source/lib/sysdep/os/win/tests/test_wdbg_sym.h b/source/lib/sysdep/os/win/tests/test_wdbg_sym.h index bc0b32ff22..f9441c44d4 100644 --- a/source/lib/sysdep/os/win/tests/test_wdbg_sym.h +++ b/source/lib/sysdep/os/win/tests/test_wdbg_sym.h @@ -231,7 +231,7 @@ class TestWdbgSym : public CxxTest::TestSuite // anyway (to see at a glance whether symbol engine addrs are correct) static void m_test_addrs(int p_int, double p_double, char* p_pchar, uintptr_t p_uintptr) { - debug_printf("\nTEST_ADDRS\n"); + debug_printf(L"\nTEST_ADDRS\n"); size_t l_uint = 0x1234; bool l_bool = true; UNUSED2(l_bool); @@ -246,16 +246,16 @@ class TestWdbgSym : public CxxTest::TestSuite static void* s_ptr = (void*)(uintptr_t)0x87654321; static HDC s_hdc = (HDC)0xff0; - debug_printf("p_int addr=%p val=%d\n", &p_int, p_int); - debug_printf("p_double addr=%p val=%g\n", &p_double, p_double); - debug_printf("p_pchar addr=%p val=%s\n", &p_pchar, p_pchar); - debug_printf("p_uintptr addr=%p val=%lu\n", &p_uintptr, p_uintptr); + debug_printf(L"p_int addr=%p val=%d\n", &p_int, p_int); + debug_printf(L"p_double addr=%p val=%g\n", &p_double, p_double); + debug_printf(L"p_pchar addr=%p val=%hs\n", &p_pchar, p_pchar); + debug_printf(L"p_uintptr addr=%p val=%lu\n", &p_uintptr, p_uintptr); - debug_printf("l_uint addr=%p val=%u\n", &l_uint, l_uint); - debug_printf("l_wchars addr=%p val=%ws\n", &l_wchars, l_wchars); - debug_printf("l_enum addr=%p val=%d\n", &l_enum, l_enum); - debug_printf("l_u8s addr=%p val=%d\n", &l_u8s, l_u8s); - debug_printf("l_funcptr addr=%p val=%p\n", &l_funcptr, l_funcptr); + debug_printf(L"l_uint addr=%p val=%u\n", &l_uint, l_uint); + debug_printf(L"l_wchars addr=%p val=%ls\n", &l_wchars, l_wchars); + debug_printf(L"l_enum addr=%p val=%d\n", &l_enum, l_enum); + debug_printf(L"l_u8s addr=%p val=%d\n", &l_u8s, l_u8s); + debug_printf(L"l_funcptr addr=%p val=%p\n", &l_funcptr, l_funcptr); m_test_stl(); diff --git a/source/lib/sysdep/os/win/wdbg.cpp b/source/lib/sysdep/os/win/wdbg.cpp index 581ba52c14..f17f7e110a 100644 --- a/source/lib/sysdep/os/win/wdbg.cpp +++ b/source/lib/sysdep/os/win/wdbg.cpp @@ -87,18 +87,18 @@ bool debug_IsStackPointer(void* p) } -void debug_puts(const char* text) +void debug_puts(const wchar_t* text) { - OutputDebugStringA(text); + OutputDebugStringW(text); } -void wdbg_printf(const char* fmt, ...) +void wdbg_printf(const wchar_t* fmt, ...) { - char buf[1024]; // as required by wvsprintf + wchar_t buf[1024]; // as required by wvsprintf va_list ap; va_start(ap, fmt); - wvsprintf(buf, fmt, ap); + wvsprintfW(buf, fmt, ap); va_end(ap); debug_puts(buf); diff --git a/source/lib/sysdep/os/win/wdbg.h b/source/lib/sysdep/os/win/wdbg.h index 502df531e3..6f46205fa8 100644 --- a/source/lib/sysdep/os/win/wdbg.h +++ b/source/lib/sysdep/os/win/wdbg.h @@ -29,7 +29,7 @@ * this function does not allocate memory from the CRT heap, which makes it * safe to use from an allocation hook. **/ -LIB_API void wdbg_printf(const char* fmt, ...); +LIB_API void wdbg_printf(const wchar_t* fmt, ...); /** * similar to debug_assert but safe to use during critical init or diff --git a/source/lib/sysdep/os/win/wdbg_heap.cpp b/source/lib/sysdep/os/win/wdbg_heap.cpp index 6bdb192d6b..12d03653d2 100644 --- a/source/lib/sysdep/os/win/wdbg_heap.cpp +++ b/source/lib/sysdep/os/win/wdbg_heap.cpp @@ -18,10 +18,11 @@ #include "precompiled.h" #include "wdbg_heap.h" -#include "lib/sysdep/os/win/win.h" +#include "win.h" #include #include +#include "lib/external_libraries/dbghelp.h" #include "lib/sysdep/cpu.h" // cpu_AtomicAdd #include "winit.h" #include "wdbg.h" // wdbg_printf @@ -126,7 +127,7 @@ struct _CrtMemBlockHeader int blockType; #endif long allocationNumber; - unsigned char gap[4]; + u8 gap[4]; bool IsValid() const { @@ -245,9 +246,9 @@ public: { } - ModuleExtents(const char* dllName) + ModuleExtents(const wchar_t* dllName) { - HMODULE hModule = GetModuleHandle(dllName); + HMODULE hModule = GetModuleHandleW(dllName); PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((u8*)hModule + ((PIMAGE_DOS_HEADER)hModule)->e_lfanew); m_address = (uintptr_t)hModule + ntHeaders->OptionalHeader.BaseOfCode; MEMORY_BASIC_INFORMATION mbi = {0}; @@ -362,17 +363,17 @@ private: { #if MSC_VERSION && _DLL // DLL runtime library #ifdef NDEBUG - static const char* dllNameFormat = "msvc%c%d" ".dll"; + static const wchar_t* dllNameFormat = L"msvc%c%d" L".dll"; #else - static const char* dllNameFormat = "msvc%c%d" "d" ".dll"; + static const wchar_t* dllNameFormat = L"msvc%c%d" L"d" L".dll"; #endif const int dllVersion = (MSC_VERSION-600)/10; // VC2005: 1400 => 80 wdbg_assert(0 < dllVersion && dllVersion <= 999); for(int i = 0; i < numModules; i++) { static const char modules[numModules] = { 'r', 'p' }; // C and C++ runtime libraries - char dllName[20]; - sprintf_s(dllName, ARRAY_SIZE(dllName), dllNameFormat, modules[i], dllVersion); + wchar_t dllName[20]; + swprintf_s(dllName, ARRAY_SIZE(dllName), dllNameFormat, modules[i], dllVersion); m_moduleIgnoreList[i] = ModuleExtents(dllName); } #endif @@ -389,11 +390,11 @@ private: free(p1); } { - char* p = new char; + u8* p = new u8; delete p; } { - char* p = new char[2]; + u8* p = new u8[2]; delete[] p; } } @@ -471,7 +472,7 @@ static uintptr_t quantizedCodeSegmentLength; static void FindCodeSegment() { - const char* dllName = 0; // current module + const wchar_t* dllName = 0; // current module ModuleExtents extents(dllName); codeSegmentAddress = extents.Address(); quantizedCodeSegmentAddress = Quantize(codeSegmentAddress); @@ -837,25 +838,25 @@ static void PrintCallStack(const uintptr_t* callers, size_t numCallers) { if(!numCallers || callers[0] == 0) { - wdbg_printf("\n call stack not available.\n"); + wdbg_printf(L"\n call stack not available.\n"); return; } - wdbg_printf("\n partial call stack:\n"); + wdbg_printf(L"\n partial call stack:\n"); for(size_t i = 0; i < numCallers; i++) { - char name[DBG_SYMBOL_LEN] = {'\0'}; char file[DBG_FILE_LEN] = {'\0'}; int line = -1; + wchar_t name[DBG_SYMBOL_LEN] = {'\0'}; wchar_t file[DBG_FILE_LEN] = {'\0'}; int line = -1; LibError err = debug_ResolveSymbol((void*)callers[i], name, file, &line); - wdbg_printf(" "); + wdbg_printf(L" "); if(err != INFO::OK) - wdbg_printf("(error %d resolving PC=%p) ", err, callers[i]); + wdbg_printf(L"(error %d resolving PC=%p) ", err, callers[i]); if(file[0] != '\0') - wdbg_printf("%s(%d) : ", file, line); - wdbg_printf("%s\n", name); + wdbg_printf(L"%ls(%d) : ", file, line); + wdbg_printf(L"%ls\n", name); } } -static int __cdecl ReportHook(int reportType, char* message, int* out) +static int __cdecl ReportHook(int reportType, wchar_t* message, int* out) { UNUSED2(reportType); @@ -877,17 +878,17 @@ static int __cdecl ReportHook(int reportType, char* message, int* out) switch(state) { case WaitingForDump: - if(!strcmp(message, "Dumping objects ->\n")) + if(!wcscmp(message, L"Dumping objects ->\n")) state = WaitingForBlock; return ret; case IsBlock: { // common case: "normal block at 0xPPPPPPPP, N bytes long". - const char* addressString = strstr(message, "0x"); + const wchar_t* addressString = wcsstr(message, L"0x"); if(addressString) { - const uintptr_t address = strtoul(addressString, 0, 0); + const uintptr_t address = wcstoul(addressString, 0, 0); _CrtMemBlockHeader* header = HeaderFromData((void*)address); uintptr_t callers[maxCallers]; size_t numCallers; RetrieveCallers(header, callers, numCallers); @@ -905,11 +906,10 @@ static int __cdecl ReportHook(int reportType, char* message, int* out) state = IsBlock; // suppress messages containing "file" and "line" since the normal // interpretation of those header fields is invalid. - else if(strchr(message, '(')) + else if(wcschr(message, '(')) message[0] = '\0'; return ret; - default: wdbg_assert(0); // unreachable } @@ -939,10 +939,10 @@ static LibError wdbg_heap_Init() FindCodeSegment(); // load symbol information now (fails if it happens during shutdown) - char name[DBG_SYMBOL_LEN]; char file[DBG_FILE_LEN]; int line; + wchar_t name[DBG_SYMBOL_LEN]; wchar_t file[DBG_FILE_LEN]; int line; (void)debug_ResolveSymbol(wdbg_heap_Init, name, file, &line); - int ret = _CrtSetReportHook2(_CRT_RPTHOOK_INSTALL, ReportHook); + int ret = _CrtSetReportHookW2(_CRT_RPTHOOK_INSTALL, ReportHook); if(ret == -1) abort(); diff --git a/source/lib/sysdep/os/win/wdbg_heap.h b/source/lib/sysdep/os/win/wdbg_heap.h index aae9292811..b8988ad417 100644 --- a/source/lib/sysdep/os/win/wdbg_heap.h +++ b/source/lib/sysdep/os/win/wdbg_heap.h @@ -39,7 +39,7 @@ LIB_API void wdbg_heap_Enable(bool); * no effect if called between wdbg_heap_Enable(false) and the next * wdbg_heap_Enable(true). **/ -LIB_API void wdbg_heap_Validate(void); +LIB_API void wdbg_heap_Validate(); /** * @return the total number of alloc and realloc operations thus far. diff --git a/source/lib/sysdep/os/win/wdbg_sym.cpp b/source/lib/sysdep/os/win/wdbg_sym.cpp index e3007b798d..8be4966e1c 100644 --- a/source/lib/sysdep/os/win/wdbg_sym.cpp +++ b/source/lib/sysdep/os/win/wdbg_sym.cpp @@ -31,7 +31,6 @@ #include "lib/debug_stl.h" #include "lib/app_hooks.h" -#include "lib/os_path.h" #include "lib/path_util.h" #if ARCH_IA32 # include "lib/sysdep/arch/ia32/ia32.h" @@ -133,7 +132,7 @@ struct TI_FINDCHILDREN_PARAMS2 // actual implementation; made available so that functions already under // the lock don't have to unlock (slow) to avoid recursive locking. -static LibError ResolveSymbol_lk(void* ptr_of_interest, char* sym_name, char* file, int* line) +static LibError ResolveSymbol_lk(void* ptr_of_interest, wchar_t* sym_name, wchar_t* file, int* line) { sym_init(); @@ -149,7 +148,7 @@ static LibError ResolveSymbol_lk(void* ptr_of_interest, char* sym_name, char* fi SYMBOL_INFOW* sym = &sp.si; if(pSymFromAddrW(hProcess, addr, 0, sym)) { - wsprintfA(sym_name, "%ws", sym->Name); + wcscpy_s(sym_name, DBG_SYMBOL_LEN, sym->Name); successes++; } } @@ -160,9 +159,9 @@ static LibError ResolveSymbol_lk(void* ptr_of_interest, char* sym_name, char* fi file[0] = '\0'; *line = 0; - IMAGEHLP_LINE64 line_info = { sizeof(IMAGEHLP_LINE64) }; + IMAGEHLP_LINEW64 line_info = { sizeof(IMAGEHLP_LINEW64) }; DWORD displacement; // unused but required by pSymGetLineFromAddr64! - if(pSymGetLineFromAddr64(hProcess, addr, &displacement, &line_info)) + if(pSymGetLineFromAddrW64(hProcess, addr, &displacement, &line_info)) { if(file) { @@ -170,8 +169,8 @@ static LibError ResolveSymbol_lk(void* ptr_of_interest, char* sym_name, char* fi // this loses information, but that isn't expected to be a // problem and is balanced by not having to do this from every // call site (full path is too long to display nicely). - const char* base_name = path_name_only(line_info.FileName); - wsprintf(file, "%s", base_name); + const wchar_t* basename = path_name_only(line_info.FileName); + wcscpy_s(file, DBG_FILE_LEN, basename); successes++; } @@ -193,7 +192,7 @@ static LibError ResolveSymbol_lk(void* ptr_of_interest, char* sym_name, char* fi // sym_name and file must hold at least the number of chars above; // file is the base name only, not path (see rationale in wdbg_sym). // the PDB implementation is rather slow (~500µs). -LibError debug_ResolveSymbol(void* ptr_of_interest, char* sym_name, char* file, int* line) +LibError debug_ResolveSymbol(void* ptr_of_interest, wchar_t* sym_name, wchar_t* file, int* line) { WinScopedLock lock(WDBG_SYM_CS); return ResolveSymbol_lk(ptr_of_interest, sym_name, file, line); @@ -303,7 +302,7 @@ typedef VOID (WINAPI *PRtlCaptureContext)(PCONTEXT); static PRtlCaptureContext s_RtlCaptureContext; -LibError wdbg_sym_WalkStack(StackFrameCallback cb, uintptr_t cbData, const CONTEXT* pcontext, const char* lastFuncToSkip) +LibError wdbg_sym_WalkStack(StackFrameCallback cb, uintptr_t cbData, const CONTEXT* pcontext, const wchar_t* lastFuncToSkip) { // to function properly, StackWalk64 requires a CONTEXT on // non-x86 systems (documented) or when in release mode (observed). @@ -405,11 +404,11 @@ LibError wdbg_sym_WalkStack(StackFrameCallback cb, uintptr_t cbData, const CONTE if(lastFuncToSkip) { void* const pc = (void*)(uintptr_t)sf.AddrPC.Offset; - char func[DBG_SYMBOL_LEN]; + wchar_t func[DBG_SYMBOL_LEN]; err = debug_ResolveSymbol(pc, func, 0, 0); if(err == INFO::OK) { - if(strstr(func, lastFuncToSkip)) + if(wcsstr(func, lastFuncToSkip)) lastFuncToSkip = 0; continue; } @@ -444,7 +443,7 @@ static LibError nth_caller_cb(const _tagSTACKFRAME64* sf, uintptr_t cbData) return INFO::OK; } -void* debug_GetCaller(void* pcontext, const char* lastFuncToSkip) +void* debug_GetCaller(void* pcontext, const wchar_t* lastFuncToSkip) { void* func; LibError ret = wdbg_sym_WalkStack(nth_caller_cb, (uintptr_t)&func, (const CONTEXT*)pcontext, lastFuncToSkip); @@ -704,7 +703,7 @@ static LibError dump_string(const u8* p, size_t el_size) buf[i] = '\0'; } - out(L"\"%s\"", buf); + out(L"\"%ls\"", buf); return INFO::OK; } @@ -920,7 +919,7 @@ static LibError DetermineSymbolAddress(DWORD id, const SYMBOL_INFOW* sym, const *pp = (const u8*)(uintptr_t)addr; - debug_printf("SYM| %ws at %p flags=%X dk=%d sym->addr=%I64X fp=%I64x\n", sym->Name, *pp, sym->Flags, dataKind, sym->Address, sf->AddrFrame.Offset); + debug_printf(L"SYM| %ls at %p flags=%X dk=%d sym->addr=%I64X fp=%I64x\n", sym->Name, *pp, sym->Flags, dataKind, sym->Address, sf->AddrFrame.Offset); return INFO::OK; } @@ -1135,7 +1134,7 @@ static LibError dump_sym_data(DWORD id, const u8* p, DumpState state) if(!pSymFromIndexW(hProcess, mod_base, id, sym)) WARN_RETURN(ERR::SYM_TYPE_INFO_UNAVAILABLE); - out(L"%ws = ", sym->Name); + out(L"%ls = ", sym->Name); __try { @@ -1193,7 +1192,7 @@ static LibError dump_sym_enum(DWORD type_id, const u8* p, DumpState UNUSED(state const wchar_t* name; if(!pSymGetTypeInfo(hProcess, mod_base, child_data_id, TI_GET_SYMNAME, &name)) WARN_RETURN(ERR::SYM_TYPE_INFO_UNAVAILABLE); - out(L"%s", name); + out(L"%ls", name); LocalFree((HLOCAL)name); return INFO::OK; } @@ -1224,7 +1223,7 @@ static LibError dump_sym_function_type(DWORD UNUSED(type_id), const u8* p, DumpS // unfortunately the one thing we care about, its name, // isn't exposed via TI_GET_SYMNAME, so we resolve it ourselves. - char name[DBG_SYMBOL_LEN]; + wchar_t name[DBG_SYMBOL_LEN]; LibError err = ResolveSymbol_lk((void*)p, name, 0, 0); if(state.indirection == 0) @@ -1276,7 +1275,7 @@ static bool ptr_already_visited(const u8* p) static bool haveComplained; if(!haveComplained) { - debug_printf("WARNING: ptr_already_visited: capacity exceeded, increase maxVisited\n"); + debug_printf(L"WARNING: ptr_already_visited: capacity exceeded, increase maxVisited\n"); debug_break(); haveComplained = true; } @@ -1377,24 +1376,20 @@ static LibError udt_get_child_type(const wchar_t* child_name, ULONG num_children } -static LibError udt_dump_std(const wchar_t* wtype_name, const u8* p, size_t size, DumpState state, ULONG num_children, const DWORD* children) +static LibError udt_dump_std(const wchar_t* type_name, const u8* p, size_t size, DumpState state, ULONG num_children, const DWORD* children) { LibError err; // not a C++ standard library object; can't handle it. - if(wcsncmp(wtype_name, L"std::", 5) != 0) + if(wcsncmp(type_name, L"std::", 5) != 0) return INFO::CANNOT_HANDLE; // check for C++ objects that should be displayed via udt_dump_normal. // STL containers are special-cased and the rest (apart from those here) // are ignored, because for the most part they are spew. - if(!wcsncmp(wtype_name, L"std::pair", 9)) + if(!wcsncmp(type_name, L"std::pair", 9)) return INFO::CANNOT_HANDLE; - // convert to char since debug_stl doesn't support wchar_t. - char ctype_name[DBG_SYMBOL_LEN]; - sprintf_s(ctype_name, ARRAY_SIZE(ctype_name), "%ws", wtype_name); - // display contents of STL containers // .. get element type DWORD el_type_id; @@ -1406,34 +1401,40 @@ static LibError udt_dump_std(const wchar_t* wtype_name, const u8* p, size_t size size_t el_count; DebugStlIterator el_iterator; u8 it_mem[DEBUG_STL_MAX_ITERATOR_SIZE]; - err = debug_stl_get_container_info(ctype_name, p, size, el_size, &el_count, &el_iterator, it_mem); + err = debug_stl_get_container_info(type_name, p, size, el_size, &el_count, &el_iterator, it_mem); if(err != INFO::OK) goto not_valid_container; return dump_sequence(el_iterator, it_mem, el_count, el_type_id, el_size, state); not_valid_container: // build and display detailed "error" message. - char buf[100]; - const char* text; + wchar_t buf[100]; + const wchar_t* text; // .. object named std::* but doesn't include a "value_type" child => // it's a non-STL C++ stdlib object. wasn't handled by the // special case above, so we just display its simplified type name // (the contents are usually spew). if(err == ERR::SYM_CHILD_NOT_FOUND) - text = ""; + text = L""; // .. not one of the containers we can analyse. if(err == ERR::STL_CNT_UNKNOWN) - text = "unsupported "; + text = L"unsupported "; // .. container of a known type but contents are invalid. if(err == ERR::STL_CNT_INVALID) - text = "uninitialized/invalid "; + text = L"uninitialized/invalid "; // .. some other error encountered else { - sprintf_s(buf, ARRAY_SIZE(buf), "error %d while analyzing ", err); + swprintf_s(buf, ARRAY_SIZE(buf), L"error %d while analyzing ", err); text = buf; } - out(L"(%hs%hs)", text, debug_stl_simplify_name(ctype_name)); + + // (debug_stl modifies its input string in-place; type_name is + // a const string returned by dbghelp) + wchar_t type_name_buf[DBG_SYMBOL_LEN]; + wcscpy_s(type_name_buf, ARRAY_SIZE(type_name_buf), type_name); + + out(L"(%ls%ls)", text, debug_stl_simplify_name(type_name_buf)); return INFO::OK; } @@ -1562,7 +1563,7 @@ static LibError udt_dump_normal(const wchar_t* type_name, const u8* p, size_t si continue; if(ofs >= size) { - debug_printf("INVALID_UDT %ws %d %d\n", type_name, ofs, size); + debug_printf(L"INVALID_UDT %ls %d %d\n", type_name, ofs, size); } //debug_assert(ofs < size); @@ -1594,7 +1595,7 @@ static LibError udt_dump_normal(const wchar_t* type_name, const u8* p, size_t si if(!displayed_anything) { out_erase(2); // "{ " or "\r\n" - out(L"(%s)", type_name); + out(L"(%ls)", type_name); return INFO::OK; } @@ -1674,7 +1675,7 @@ static LibError dump_sym_unknown(DWORD type_id, const u8* UNUSED(p), DumpState U if(!pSymGetTypeInfo(hProcess, mod_base, type_id, TI_GET_SYMTAG, &type_tag)) WARN_RETURN(ERR::SYM_TYPE_INFO_UNAVAILABLE); - debug_printf("SYM| unknown tag: %d\n", type_tag); + debug_printf(L"SYM| unknown tag: %d\n", type_tag); out(L"(unknown symbol type)"); return INFO::OK; } @@ -1784,7 +1785,7 @@ static LibError dump_frame_cb(const _tagSTACKFRAME64* sf, uintptr_t UNUSED(cbDat current_stackframe64 = sf; void* func = (void*)(uintptr_t)sf->AddrPC.Offset; - char func_name[DBG_SYMBOL_LEN]; char file[DBG_FILE_LEN]; int line; + wchar_t func_name[DBG_SYMBOL_LEN]; wchar_t file[DBG_FILE_LEN]; int line; LibError ret = ResolveSymbol_lk(func, func_name, file, &line); if(ret == INFO::OK) { @@ -1795,10 +1796,10 @@ static LibError dump_frame_cb(const _tagSTACKFRAME64* sf, uintptr_t UNUSED(cbDat // that would cut off callbacks as well. // note: the stdcall mangled name includes parameter size, which is // different in 64-bit, so only check the first characters. - if(!strncmp(func_name, "_BaseProcessStart", 17)) + if(!wcsncmp(func_name, L"_BaseProcessStart", 17)) return INFO::OK; - out(L"%hs (%hs:%d)\r\n", func_name, file, line); + out(L"%ls (%ls:%d)\r\n", func_name, file, line); } else out(L"%p\r\n", func); @@ -1820,7 +1821,7 @@ static LibError dump_frame_cb(const _tagSTACKFRAME64* sf, uintptr_t UNUSED(cbDat } -LibError debug_DumpStack(wchar_t* buf, size_t maxChars, void* pcontext, const char* lastFuncToSkip) +LibError debug_DumpStack(wchar_t* buf, size_t maxChars, void* pcontext, const wchar_t* lastFuncToSkip) { static uintptr_t already_in_progress; if(!cpu_CAS(&already_in_progress, 0, 1)) @@ -1847,8 +1848,8 @@ void wdbg_sym_WriteMinidump(EXCEPTION_POINTERS* exception_pointers) { WinScopedLock lock(WDBG_SYM_CS); - OsPath path = OsPath(ah_get_log_dir())/"crashlog.dmp"; - HANDLE hFile = CreateFile(path.string().c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, 0, CREATE_ALWAYS, 0, 0); + fs::wpath path = ah_get_log_dir()/L"crashlog.dmp"; + HANDLE hFile = CreateFileW(path.string().c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, 0, CREATE_ALWAYS, 0, 0); if(hFile == INVALID_HANDLE_VALUE) { DEBUG_DISPLAY_ERROR(L"wdbg_sym_WriteMinidump: unable to create crashlog.dmp."); diff --git a/source/lib/sysdep/os/win/wdbg_sym.h b/source/lib/sysdep/os/win/wdbg_sym.h index 9e0ac38b62..582cf86a2f 100644 --- a/source/lib/sysdep/os/win/wdbg_sym.h +++ b/source/lib/sysdep/os/win/wdbg_sym.h @@ -48,7 +48,7 @@ typedef LibError (*StackFrameCallback)(const _tagSTACKFRAME64* frame, uintptr_t * stack trace (which is triggered by debug_assert et al. in app code) because * nested stack traces are ignored and only the error is displayed. **/ -extern LibError wdbg_sym_WalkStack(StackFrameCallback cb, uintptr_t cbData = 0, size_t skip = 0, const _CONTEXT* pcontext = 0); +extern LibError wdbg_sym_WalkStack(StackFrameCallback cb, uintptr_t cbData = 0, const _CONTEXT* pcontext = 0, const wchar_t* lastFuncToSkip = 0); extern void wdbg_sym_WriteMinidump(_EXCEPTION_POINTERS* ep); diff --git a/source/lib/sysdep/os/win/wdir_watch.cpp b/source/lib/sysdep/os/win/wdir_watch.cpp index 26a9e92bda..3e09727231 100644 --- a/source/lib/sysdep/os/win/wdir_watch.cpp +++ b/source/lib/sysdep/os/win/wdir_watch.cpp @@ -39,7 +39,7 @@ class DirWatchRequest { public: DirWatchRequest() - : m_data(new char[dataSize]) + : m_data(new u8[dataSize]) { m_undefined = 0; memset(&m_ovl, 0, sizeof(m_ovl)); @@ -48,7 +48,7 @@ public: /** * @return the buffer containing one or more FILE_NOTIFY_INFORMATION **/ - char* Results() const + u8* Results() const { debug_assert(HasOverlappedIoCompleted(&m_ovl)); return m_data.get(); @@ -79,7 +79,7 @@ private: // note: each instance needs their own buffer. (we can't share a central // copy because the watches are independent and may be triggered // 'simultaneously' before the next poll.) - shared_ptr m_data; + shared_ptr m_data; // (passing this instead of a null pointer avoids a BoundsChecker warning // but has no other value since its contents are undefined.) @@ -209,7 +209,7 @@ public: return m_path; } - const char* Results() const + const u8* Results() const { return m_request.Results(); } @@ -239,9 +239,9 @@ public: * @param packets points to at least one (variable-length) * FILE_NOTIFY_INFORMATION. **/ - void Enqueue(const fs::wpath& path, const char* const packets) + void Enqueue(const fs::wpath& path, const u8* const packets) { - const char* pos = packets; + const u8* pos = packets; for(;;) { const FILE_NOTIFY_INFORMATION* fni = (const FILE_NOTIFY_INFORMATION*)pos; @@ -350,7 +350,7 @@ public: { DirWatch& dirWatch = *(DirWatch*)key; const fs::wpath& path = dirWatch.Path(); - const char* const packets = dirWatch.Results(); + const u8* const packets = dirWatch.Results(); m_queue.Enqueue(path, packets); diff --git a/source/lib/sysdep/os/win/wdll_delay_load.h b/source/lib/sysdep/os/win/wdll_delay_load.h index a8bb7bfb41..6d96eeb674 100644 --- a/source/lib/sysdep/os/win/wdll_delay_load.h +++ b/source/lib/sysdep/os/win/wdll_delay_load.h @@ -26,7 +26,7 @@ struct WdllLoadNotify { const char* dll_name; - LibError (*func)(void); + LibError (*func)(); WdllLoadNotify* next; }; diff --git a/source/lib/sysdep/os/win/wdll_ver.cpp b/source/lib/sysdep/os/win/wdll_ver.cpp index 8355142e65..cd85c25515 100644 --- a/source/lib/sysdep/os/win/wdll_ver.cpp +++ b/source/lib/sysdep/os/win/wdll_ver.cpp @@ -37,69 +37,69 @@ //----------------------------------------------------------------------------- -static LibError ReadVersionString(const OsPath& modulePathname_, char* out_ver, size_t out_ver_len) +static LibError ReadVersionString(const fs::wpath& modulePathname_, wchar_t* out_ver, size_t out_ver_len) { WinScopedPreserveLastError s; // GetFileVersion*, Ver* WinScopedDisableWow64Redirection noRedirect; - const std::string modulePathname = modulePathname_.external_file_string(); + const std::wstring modulePathname = modulePathname_.external_file_string(); // determine size of and allocate memory for version information. DWORD unused; - const DWORD ver_size = GetFileVersionInfoSize(modulePathname.c_str(), &unused); + const DWORD ver_size = GetFileVersionInfoSizeW(modulePathname.c_str(), &unused); // [bytes] if(!ver_size) { // check if the failure is due to not finding modulePathname // (necessary since GetFileVersionInfoSize doesn't SetLastError) - HMODULE hModule = LoadLibraryEx(modulePathname.c_str(), 0, LOAD_LIBRARY_AS_DATAFILE); + HMODULE hModule = LoadLibraryExW(modulePathname.c_str(), 0, LOAD_LIBRARY_AS_DATAFILE); FreeLibrary(hModule); const LibError err = hModule? ERR::_1 : ERR::_2; WARN_RETURN(err); } shared_ptr mem = Allocate(ver_size); - if(!GetFileVersionInfo(modulePathname.c_str(), 0, ver_size, mem.get())) + if(!GetFileVersionInfoW(modulePathname.c_str(), 0, ver_size, mem.get())) WARN_RETURN(ERR::_3); u16* lang; // -> 16 bit language ID, 16 bit codepage UINT lang_len; - const BOOL ok = VerQueryValue(mem.get(), "\\VarFileInfo\\Translation", (void**)&lang, &lang_len); + const BOOL ok = VerQueryValueW(mem.get(), L"\\VarFileInfo\\Translation", (void**)&lang, &lang_len); if(!ok || !lang || lang_len != 4) WARN_RETURN(ERR::_4); - char subblock[64]; - sprintf(subblock, "\\StringFileInfo\\%04X%04X\\FileVersion", lang[0], lang[1]); - const char* in_ver; + wchar_t subblock[64]; + swprintf_s(subblock, ARRAY_SIZE(subblock), L"\\StringFileInfo\\%04X%04X\\FileVersion", lang[0], lang[1]); + const wchar_t* in_ver; UINT in_ver_len; - if(!VerQueryValue(mem.get(), subblock, (void**)&in_ver, &in_ver_len)) + if(!VerQueryValueW(mem.get(), subblock, (void**)&in_ver, &in_ver_len)) WARN_RETURN(ERR::_5); - strcpy_s(out_ver, out_ver_len, in_ver); + wcscpy_s(out_ver, out_ver_len, in_ver); return INFO::OK; } -void wdll_ver_Append(const OsPath& pathname, std::string& list) +void wdll_ver_Append(const fs::wpath& pathname, std::wstring& list) { // pathname may not have an extension (e.g. driver names from the // registry). note that always appending ".dll" would be incorrect // since some have ".sys" extension. - OsPath modulePathname(pathname); + fs::wpath modulePathname(pathname); if(fs::extension(modulePathname).empty()) - modulePathname = fs::change_extension(modulePathname, ".dll"); - const std::string moduleName(modulePathname.leaf()); + modulePathname = fs::change_extension(modulePathname, L".dll"); + const std::wstring moduleName(modulePathname.leaf()); // read file version. // (note: we can ignore the return value since the default // text has already been set) - char versionString[500] = "unknown"; // enclosed in () below + wchar_t versionString[500] = L"unknown"; // enclosed in () below (void)ReadVersionString(modulePathname, versionString, ARRAY_SIZE(versionString)); if(!list.empty()) - list += ", "; + list += L", "; list += moduleName; - list += " ("; + list += L" ("; list += versionString; - list += ")"; + list += L")"; } diff --git a/source/lib/sysdep/os/win/wdll_ver.h b/source/lib/sysdep/os/win/wdll_ver.h index ef13db6907..927a2d571f 100644 --- a/source/lib/sysdep/os/win/wdll_ver.h +++ b/source/lib/sysdep/os/win/wdll_ver.h @@ -22,8 +22,6 @@ #ifndef INCLUDED_WDLL_VER #define INCLUDED_WDLL_VER -#include "lib/os_path.h" - /** * read DLL version information and append it to a string. * @@ -34,6 +32,6 @@ * the text output includes the module name. * on failure, the version is given as "unknown". **/ -extern void wdll_ver_Append(const OsPath& pathname, std::string& list); +extern void wdll_ver_Append(const fs::wpath& pathname, std::wstring& list); #endif // #ifndef INCLUDED_WDLL_VER diff --git a/source/lib/sysdep/os/win/wgfx.cpp b/source/lib/sysdep/os/win/wgfx.cpp index 092a3f241a..cebc0d4a91 100644 --- a/source/lib/sysdep/os/win/wgfx.cpp +++ b/source/lib/sysdep/os/win/wgfx.cpp @@ -81,8 +81,8 @@ LibError gfx_get_monitor_size(int& width_mm, int& height_mm) static LibError win_get_gfx_card() { WmiMap wmiMap; - RETURN_ERR(wmi_GetClass("Win32_VideoController", wmiMap)); - sprintf_s(gfx_card, GFX_CARD_LEN, "%ls", wmiMap[L"Caption"].bstrVal); + RETURN_ERR(wmi_GetClass(L"Win32_VideoController", wmiMap)); + swprintf_s(gfx_card, GFX_CARD_LEN, L"%ls", wmiMap[L"Caption"].bstrVal); return INFO::OK; } @@ -112,29 +112,29 @@ static LibError win_get_gfx_drv_ver() // name checks and reporting incorrectly. DWORD i; - char drv_name[MAX_PATH+1]; - std::string versionList; + wchar_t drv_name[MAX_PATH+1]; + std::wstring versionList; HKEY hkOglDrivers; - const char* key = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\OpenGLDrivers"; - if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &hkOglDrivers) != 0) + const wchar_t* key = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\OpenGLDrivers"; + if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &hkOglDrivers) != 0) WARN_RETURN(ERR::FAIL); // for each subkey (i.e. set of installed OpenGL drivers): for(i = 0; ; i++) { - char set_name[32]; + wchar_t set_name[32]; DWORD set_name_len = ARRAY_SIZE(set_name); - const LONG err = RegEnumKeyEx(hkOglDrivers, i, set_name, &set_name_len, 0, 0,0, 0); + const LONG err = RegEnumKeyExW(hkOglDrivers, i, set_name, &set_name_len, 0, 0,0, 0); if(err == ERROR_NO_MORE_ITEMS) break; debug_assert(err == ERROR_SUCCESS); HKEY hkSet; - if(RegOpenKeyEx(hkOglDrivers, set_name, 0, KEY_QUERY_VALUE, &hkSet) == 0) + if(RegOpenKeyExW(hkOglDrivers, set_name, 0, KEY_QUERY_VALUE, &hkSet) == 0) { DWORD drv_name_len = ARRAY_SIZE(drv_name)-5; // for ".dll" - if(RegQueryValueEx(hkSet, "Dll", 0, 0, (LPBYTE)drv_name, &drv_name_len) == 0) + if(RegQueryValueExW(hkSet, L"Dll", 0, 0, (LPBYTE)drv_name, &drv_name_len) == 0) wdll_ver_Append(drv_name, versionList); RegCloseKey(hkSet); @@ -146,11 +146,11 @@ static LibError win_get_gfx_drv_ver() // single REG_SZ value. we therefore include those as well.) for(i = 0; ; i++) { - char value_name[100]; // we don't need this, but RegEnumValue fails otherwise. + wchar_t value_name[100]; // we don't need this, but RegEnumValue fails otherwise. DWORD value_name_len = ARRAY_SIZE(value_name); DWORD type; DWORD drv_name_len = ARRAY_SIZE(drv_name)-5; // for ".dll" - const DWORD err = RegEnumValue(hkOglDrivers, i, value_name, &value_name_len, 0, &type, (LPBYTE)drv_name, &drv_name_len); + const DWORD err = RegEnumValueW(hkOglDrivers, i, value_name, &value_name_len, 0, &type, (LPBYTE)drv_name, &drv_name_len); if(err == ERROR_NO_MORE_ITEMS) break; debug_assert(err == ERROR_SUCCESS); @@ -160,7 +160,7 @@ static LibError win_get_gfx_drv_ver() RegCloseKey(hkOglDrivers); - strcpy_s(gfx_drv_ver, GFX_DRV_VER_LEN, versionList.c_str()); + wcscpy_s(gfx_drv_ver, GFX_DRV_VER_LEN, versionList.c_str()); return INFO::OK; } diff --git a/source/lib/sysdep/os/win/wgl.h b/source/lib/sysdep/os/win/wgl.h index 3ee43f0fbd..7d0c419702 100644 --- a/source/lib/sysdep/os/win/wgl.h +++ b/source/lib/sysdep/os/win/wgl.h @@ -52,7 +52,7 @@ typedef __int64 INT64; typedef float FLOAT; typedef const char* LPCSTR; typedef void* HANDLE; -typedef int (*PROC)(void); +typedef int (*PROC)(); #define DECLARE_HANDLE(name) typedef HANDLE name DECLARE_HANDLE(HDC); DECLARE_HANDLE(HGLRC); @@ -68,8 +68,8 @@ WINGDIAPI BOOL WINAPI wglCopyContext(HGLRC, HGLRC, UINT); WINGDIAPI HGLRC WINAPI wglCreateContext(HDC); WINGDIAPI HGLRC WINAPI wglCreateLayerContext(HDC, int); WINGDIAPI BOOL WINAPI wglDeleteContext(HGLRC); -WINGDIAPI HGLRC WINAPI wglGetCurrentContext(void); -WINGDIAPI HDC WINAPI wglGetCurrentDC(void); +WINGDIAPI HGLRC WINAPI wglGetCurrentContext(); +WINGDIAPI HDC WINAPI wglGetCurrentDC(); WINGDIAPI PROC WINAPI wglGetProcAddress(LPCSTR); WINGDIAPI BOOL WINAPI wglMakeCurrent(HDC, HGLRC); WINGDIAPI BOOL WINAPI wglShareLists(HGLRC, HGLRC); diff --git a/source/lib/sysdep/os/win/whrt/counter.h b/source/lib/sysdep/os/win/whrt/counter.h index 8c15a35b06..b7f2422253 100644 --- a/source/lib/sysdep/os/win/whrt/counter.h +++ b/source/lib/sysdep/os/win/whrt/counter.h @@ -30,7 +30,7 @@ public: // (compiled-generated) ctor only sets up the vptr virtual ~ICounter() {} - virtual const char* Name() const = 0; + virtual const wchar_t* Name() const = 0; // Activate with an error return value is much cleaner+safer than // throwing exceptions in the ctor. diff --git a/source/lib/sysdep/os/win/whrt/hpet.cpp b/source/lib/sysdep/os/win/whrt/hpet.cpp index 68341aa2f3..91c8c5371a 100644 --- a/source/lib/sysdep/os/win/whrt/hpet.cpp +++ b/source/lib/sysdep/os/win/whrt/hpet.cpp @@ -40,9 +40,9 @@ public: { } - virtual const char* Name() const + virtual const wchar_t* Name() const { - return "HPET"; + return L"HPET"; } LibError Activate() @@ -60,7 +60,7 @@ public: debug_assert(period_fs != 0); // "a value of 0 in this field is not permitted" debug_assert(period_fs <= 0x05F5E100); // 100 ns (min freq is 10 MHz) m_frequency = 1e15 / period_fs; - debug_printf("HPET: rev=%X vendor=%X bits=%d period=%X freq=%g\n", revision, vendorID, m_counterBits, period_fs, m_frequency); + debug_printf(L"HPET: rev=%X vendor=%X bits=%d period=%X freq=%g\n", revision, vendorID, m_counterBits, period_fs, m_frequency); } // start the counter (if not already running) @@ -174,7 +174,9 @@ private: #if ARCH_AMD64 return _mm_cvtsi128_si64x(value128); #else - return u64_from_u32(value128.m128i_u32[1], value128.m128i_u32[0]); + __declspec(align(16)) u32 values[4]; + _mm_store_si128((__m128i*)values, value128); + return u64_from_u32(values[1], values[0]); #endif } diff --git a/source/lib/sysdep/os/win/whrt/pmt.cpp b/source/lib/sysdep/os/win/whrt/pmt.cpp index d94ab4bca4..8239f403a0 100644 --- a/source/lib/sysdep/os/win/whrt/pmt.cpp +++ b/source/lib/sysdep/os/win/whrt/pmt.cpp @@ -53,9 +53,9 @@ public: { } - virtual const char* Name() const + virtual const wchar_t* Name() const { - return "PMT"; + return L"PMT"; } LibError Activate() diff --git a/source/lib/sysdep/os/win/whrt/qpc.cpp b/source/lib/sysdep/os/win/whrt/qpc.cpp index 282c89c94c..0d69c9e4e1 100644 --- a/source/lib/sysdep/os/win/whrt/qpc.cpp +++ b/source/lib/sysdep/os/win/whrt/qpc.cpp @@ -39,9 +39,9 @@ public: { } - virtual const char* Name() const + virtual const wchar_t* Name() const { - return "QPC"; + return L"QPC"; } LibError Activate() @@ -97,7 +97,7 @@ public: usesTsc |= IsSimilarMagnitude((double)m_frequency, os_cpu_ClockFrequency()/3); if(usesTsc) { - const bool isTscSafe = wutil_HasCommandLineArgument("-wQpcTscSafe"); + const bool isTscSafe = wutil_HasCommandLineArgument(L"-wQpcTscSafe"); return isTscSafe; } diff --git a/source/lib/sysdep/os/win/whrt/tgt.cpp b/source/lib/sysdep/os/win/whrt/tgt.cpp index 23329b8e36..e503cad4b1 100644 --- a/source/lib/sysdep/os/win/whrt/tgt.cpp +++ b/source/lib/sysdep/os/win/whrt/tgt.cpp @@ -44,9 +44,9 @@ static const UINT PERIOD_MS = 2; class CounterTGT : public ICounter { public: - virtual const char* Name() const + virtual const wchar_t* Name() const { - return "TGT"; + return L"TGT"; } LibError Activate() diff --git a/source/lib/sysdep/os/win/whrt/tsc.cpp b/source/lib/sysdep/os/win/whrt/tsc.cpp index 08f091c04f..fd12836af9 100644 --- a/source/lib/sysdep/os/win/whrt/tsc.cpp +++ b/source/lib/sysdep/os/win/whrt/tsc.cpp @@ -75,9 +75,9 @@ static bool IsThrottlingPossible() class CounterTSC : public ICounter { public: - virtual const char* Name() const + virtual const wchar_t* Name() const { - return "TSC"; + return L"TSC"; } LibError Activate() diff --git a/source/lib/sysdep/os/win/whrt/whrt.cpp b/source/lib/sysdep/os/win/whrt/whrt.cpp index c30a5c40f0..16628d9182 100644 --- a/source/lib/sysdep/os/win/whrt/whrt.cpp +++ b/source/lib/sysdep/os/win/whrt/whrt.cpp @@ -73,13 +73,13 @@ static ICounter* GetNextBestSafeCounter() LibError err = ActivateCounter(counter); if(err == INFO::OK) { - debug_printf("HRT| using name=%s freq=%f\n", counter->Name(), counter->NominalFrequency()); + debug_printf(L"HRT| using name=%ls freq=%f\n", counter->Name(), counter->NominalFrequency()); return counter; // found a safe counter } else { - char buf[100]; - debug_printf("HRT| activating %s failed: %s\n", counter->Name(), error_description_r(err, buf, ARRAY_SIZE(buf))); + wchar_t buf[100]; + debug_printf(L"HRT| activating %ls failed: %ls\n", counter->Name(), error_description_r(err, buf, ARRAY_SIZE(buf))); DestroyCounter(counter); } } @@ -107,7 +107,7 @@ static void InitCounter() nominalFrequency = counter->NominalFrequency(); resolution = counter->Resolution(); counterBits = counter->CounterBits(); - debug_printf("HRT| counter=%s freq=%g res=%g bits=%d\n", counter->Name(), nominalFrequency, resolution, counterBits); + debug_printf(L"HRT| counter=%ls freq=%g res=%g bits=%d\n", counter->Name(), nominalFrequency, resolution, counterBits); // sanity checks debug_assert(nominalFrequency >= 500.0-DBL_EPSILON); diff --git a/source/lib/sysdep/os/win/winit.cpp b/source/lib/sysdep/os/win/winit.cpp index a03be695dd..305bbc6703 100644 --- a/source/lib/sysdep/os/win/winit.cpp +++ b/source/lib/sysdep/os/win/winit.cpp @@ -38,7 +38,7 @@ // main : waio, wsock, wtime, wdir_watch // late : wsdl -typedef LibError (*PfnLibErrorVoid)(void); +typedef LibError (*PfnLibError)(); // pointers to start and end of function tables. // notes: @@ -46,10 +46,10 @@ typedef LibError (*PfnLibErrorVoid)(void); // (zero, because CallFunctionPointers has to ignore entries =0 anyway). // - ASCII '$' and 'Z' come before resp. after '0'..'9', so use that to // bound the section names. -__declspec(allocate(".WINIT$I$")) PfnLibErrorVoid initBegin = 0; -__declspec(allocate(".WINIT$IZ")) PfnLibErrorVoid initEnd = 0; -__declspec(allocate(".WINIT$S$")) PfnLibErrorVoid shutdownBegin = 0; -__declspec(allocate(".WINIT$SZ")) PfnLibErrorVoid shutdownEnd = 0; +__declspec(allocate(".WINIT$I$")) PfnLibError initBegin = 0; +__declspec(allocate(".WINIT$IZ")) PfnLibError initEnd = 0; +__declspec(allocate(".WINIT$S$")) PfnLibError shutdownBegin = 0; +__declspec(allocate(".WINIT$SZ")) PfnLibError shutdownEnd = 0; // note: #pragma comment(linker, "/include") is not necessary since // these are referenced below. @@ -62,11 +62,11 @@ __declspec(allocate(".WINIT$SZ")) PfnLibErrorVoid shutdownEnd = 0; * are initialized to 0 and because the range may be larger than * expected due to COFF section padding (with zeroes). **/ -static void CallFunctionPointers(PfnLibErrorVoid* begin, PfnLibErrorVoid* end) +static void CallFunctionPointers(PfnLibError* begin, PfnLibError* end) { const DWORD t0 = GetTickCount(); - for(PfnLibErrorVoid* ppfunc = begin; ppfunc < end; ppfunc++) + for(PfnLibError* ppfunc = begin; ppfunc < end; ppfunc++) { if(*ppfunc) { @@ -75,7 +75,7 @@ static void CallFunctionPointers(PfnLibErrorVoid* begin, PfnLibErrorVoid* end) } const DWORD t1 = GetTickCount(); - debug_printf("WINIT| total elapsed time in callbacks %d ms (+-10)\n", t1-t0); + debug_printf(L"WINIT| total elapsed time in callbacks %d ms (+-10)\n", t1-t0); } diff --git a/source/lib/sysdep/os/win/winit.h b/source/lib/sysdep/os/win/winit.h index a331dd9e9e..8c7e0b6d7a 100644 --- a/source/lib/sysdep/os/win/winit.h +++ b/source/lib/sysdep/os/win/winit.h @@ -128,29 +128,29 @@ Several methods of module init are possible: (see Large Scale C++ Design) // very early init; must not fail, since error handling code *crashes* // if called before these have completed. -#define WINIT_REGISTER_CRITICAL_INIT(func) __pragma(comment(linker, "/include:" STRINGIZE(DECORATED_NAME(p##func)))) static LibError func(void); EXTERN_C __declspec(allocate(".WINIT$I0")) LibError (*p##func)(void) = func +#define WINIT_REGISTER_CRITICAL_INIT(func) __pragma(comment(linker, "/include:" STRINGIZE(DECORATED_NAME(p##func)))) static LibError func(); EXTERN_C __declspec(allocate(".WINIT$I0")) LibError (*p##func)(void) = func // meant for modules with dependents but whose init is complicated and may // raise error/warning messages (=> can't go in WINIT_REGISTER_CRITICAL_INIT) -#define WINIT_REGISTER_EARLY_INIT(func) __pragma(comment(linker, "/include:" STRINGIZE(DECORATED_NAME(p##func)))) static LibError func(void); EXTERN_C __declspec(allocate(".WINIT$I1")) LibError (*p##func)(void) = func +#define WINIT_REGISTER_EARLY_INIT(func) __pragma(comment(linker, "/include:" STRINGIZE(DECORATED_NAME(p##func)))) static LibError func(); EXTERN_C __declspec(allocate(".WINIT$I1")) LibError (*p##func)(void) = func // available for dependents of WINIT_REGISTER_EARLY_INIT-modules that // must still come before WINIT_REGISTER_MAIN_INIT. -#define WINIT_REGISTER_EARLY_INIT2(func) __pragma(comment(linker, "/include:" STRINGIZE(DECORATED_NAME(p##func)))) static LibError func(void); EXTERN_C __declspec(allocate(".WINIT$I2")) LibError (*p##func)(void) = func +#define WINIT_REGISTER_EARLY_INIT2(func) __pragma(comment(linker, "/include:" STRINGIZE(DECORATED_NAME(p##func)))) static LibError func(); EXTERN_C __declspec(allocate(".WINIT$I2")) LibError (*p##func)(void) = func // most modules will go here unless they are often used or // have many dependents. -#define WINIT_REGISTER_MAIN_INIT(func) __pragma(comment(linker, "/include:" STRINGIZE(DECORATED_NAME(p##func)))) static LibError func(void); EXTERN_C __declspec(allocate(".WINIT$I6")) LibError (*p##func)(void) = func +#define WINIT_REGISTER_MAIN_INIT(func) __pragma(comment(linker, "/include:" STRINGIZE(DECORATED_NAME(p##func)))) static LibError func(); EXTERN_C __declspec(allocate(".WINIT$I6")) LibError (*p##func)(void) = func // available for any modules that may need to come after // WINIT_REGISTER_MAIN_INIT (unlikely) -#define WINIT_REGISTER_LATE_INIT(func) __pragma(comment(linker, "/include:" STRINGIZE(DECORATED_NAME(p##func)))) static LibError func(void); EXTERN_C __declspec(allocate(".WINIT$I7")) LibError (*p##func)(void) = func +#define WINIT_REGISTER_LATE_INIT(func) __pragma(comment(linker, "/include:" STRINGIZE(DECORATED_NAME(p##func)))) static LibError func(); EXTERN_C __declspec(allocate(".WINIT$I7")) LibError (*p##func)(void) = func -#define WINIT_REGISTER_EARLY_SHUTDOWN(func) __pragma(comment(linker, "/include:" STRINGIZE(DECORATED_NAME(p##func)))) static LibError func(void); EXTERN_C __declspec(allocate(".WINIT$S0")) LibError (*p##func)(void) = func -#define WINIT_REGISTER_EARLY_SHUTDOWN2(func) __pragma(comment(linker, "/include:" STRINGIZE(DECORATED_NAME(p##func)))) static LibError func(void); EXTERN_C __declspec(allocate(".WINIT$S1")) LibError (*p##func)(void) = func -#define WINIT_REGISTER_MAIN_SHUTDOWN(func) __pragma(comment(linker, "/include:" STRINGIZE(DECORATED_NAME(p##func)))) static LibError func(void); EXTERN_C __declspec(allocate(".WINIT$S6")) LibError (*p##func)(void) = func -#define WINIT_REGISTER_LATE_SHUTDOWN(func) __pragma(comment(linker, "/include:" STRINGIZE(DECORATED_NAME(p##func)))) static LibError func(void); EXTERN_C __declspec(allocate(".WINIT$S7")) LibError (*p##func)(void) = func -#define WINIT_REGISTER_LATE_SHUTDOWN2(func) __pragma(comment(linker, "/include:" STRINGIZE(DECORATED_NAME(p##func)))) static LibError func(void); EXTERN_C __declspec(allocate(".WINIT$S8")) LibError (*p##func)(void) = func +#define WINIT_REGISTER_EARLY_SHUTDOWN(func) __pragma(comment(linker, "/include:" STRINGIZE(DECORATED_NAME(p##func)))) static LibError func(); EXTERN_C __declspec(allocate(".WINIT$S0")) LibError (*p##func)(void) = func +#define WINIT_REGISTER_EARLY_SHUTDOWN2(func) __pragma(comment(linker, "/include:" STRINGIZE(DECORATED_NAME(p##func)))) static LibError func(); EXTERN_C __declspec(allocate(".WINIT$S1")) LibError (*p##func)(void) = func +#define WINIT_REGISTER_MAIN_SHUTDOWN(func) __pragma(comment(linker, "/include:" STRINGIZE(DECORATED_NAME(p##func)))) static LibError func(); EXTERN_C __declspec(allocate(".WINIT$S6")) LibError (*p##func)(void) = func +#define WINIT_REGISTER_LATE_SHUTDOWN(func) __pragma(comment(linker, "/include:" STRINGIZE(DECORATED_NAME(p##func)))) static LibError func(); EXTERN_C __declspec(allocate(".WINIT$S7")) LibError (*p##func)(void) = func +#define WINIT_REGISTER_LATE_SHUTDOWN2(func) __pragma(comment(linker, "/include:" STRINGIZE(DECORATED_NAME(p##func)))) static LibError func(); EXTERN_C __declspec(allocate(".WINIT$S8")) LibError (*p##func)(void) = func //----------------------------------------------------------------------------- diff --git a/source/lib/sysdep/os/win/wmi.cpp b/source/lib/sysdep/os/win/wmi.cpp index e20787b8ba..718d8a9e51 100644 --- a/source/lib/sysdep/os/win/wmi.cpp +++ b/source/lib/sysdep/os/win/wmi.cpp @@ -83,13 +83,13 @@ void wmi_Shutdown() } -LibError wmi_GetClass(const char* className, WmiMap& wmiMap) +LibError wmi_GetClass(const wchar_t* className, WmiMap& wmiMap) { RETURN_ERR(Init()); IEnumWbemClassObjectPtr pEnum = 0; - char query[200]; - sprintf_s(query, ARRAY_SIZE(query), "SELECT * FROM %s", className); + wchar_t query[200]; + swprintf_s(query, ARRAY_SIZE(query), L"SELECT * FROM %ls", className); HRESULT hr = pSvc->ExecQuery(L"WQL", _bstr_t(query), WBEM_FLAG_FORWARD_ONLY|WBEM_FLAG_RETURN_IMMEDIATELY, 0, &pEnum); if(FAILED(hr)) WARN_RETURN(ERR::FAIL); diff --git a/source/lib/sysdep/os/win/wmi.h b/source/lib/sysdep/os/win/wmi.h index da99e12ddf..995f19df72 100644 --- a/source/lib/sysdep/os/win/wmi.h +++ b/source/lib/sysdep/os/win/wmi.h @@ -35,7 +35,7 @@ typedef std::map WmiMap; * return a map of name/value pairs of the WMI class members. * @return LibError **/ -extern LibError wmi_GetClass(const char* className, WmiMap& wmiMap); +extern LibError wmi_GetClass(const wchar_t* className, WmiMap& wmiMap); extern void wmi_Shutdown(); diff --git a/source/lib/sysdep/os/win/wnuma.cpp b/source/lib/sysdep/os/win/wnuma.cpp index 58e403faa4..dd81fe6248 100644 --- a/source/lib/sysdep/os/win/wnuma.cpp +++ b/source/lib/sysdep/os/win/wnuma.cpp @@ -301,7 +301,7 @@ void* numa_Allocate(size_t size, LargePageDisposition largePageDisposition, size if(ppageSize) *ppageSize = largePageSize; const double elapsedTime = timer_Time() - startTime; - debug_printf("TIMER| NUMA large page allocation: %g\n", elapsedTime); + debug_printf(L"TIMER| NUMA large page allocation: %g\n", elapsedTime); if(elapsedTime > 1.0) largePageAllocationTookTooLong = true; } @@ -353,12 +353,12 @@ static bool VerifyPages(void* mem, size_t size, size_t pageSize, size_t node) return false; if((attributes.LargePage != 0) != (pageSize == largePageSize)) { - debug_printf("NUMA: is not a large page\n"); + debug_printf(L"NUMA: is not a large page\n"); return false; } if(attributes.Node != node) { - debug_printf("NUMA: allocated from remote node\n"); + debug_printf(L"NUMA: allocated from remote node\n"); return false; } } @@ -384,7 +384,7 @@ void* numa_AllocateOnNode(size_t node, size_t size, LargePageDisposition largePa const size_t sizeMiB = size/MiB; const size_t availableMiB = numa_AvailableMemory(node); if(availableMiB < sizeMiB) - debug_printf("NUMA: warning: node reports insufficient memory (%d vs %d MB)\n", availableMiB, sizeMiB); + debug_printf(L"NUMA: warning: node reports insufficient memory (%d vs %d MB)\n", availableMiB, sizeMiB); } size_t pageSize; // (used below even if ppageSize is zero) diff --git a/source/lib/sysdep/os/win/wposix/waio.cpp b/source/lib/sysdep/os/win/wposix/waio.cpp index c57e59349c..183ac470c6 100644 --- a/source/lib/sysdep/os/win/wposix/waio.cpp +++ b/source/lib/sysdep/os/win/wposix/waio.cpp @@ -171,7 +171,7 @@ static bool isAioPossible(int fd, bool is_com_port, int oflag) if(is_com_port) return false; - // caller is requesting we skip it (see file_open) + // caller is requesting we skip it (see open()) if(oflag & O_NO_AIO_NP) return false; @@ -234,7 +234,7 @@ int wopen(const wchar_t* fn, int oflag, ...) va_end(args); } - WinScopedPreserveLastError s; // _open's CreateFile + WinScopedPreserveLastError s; // _wopen's CreateFile int fd = _wopen(fn, oflag, mode); // none of the above apply; now re-open the file. diff --git a/source/lib/sysdep/os/win/wposix/waio.h b/source/lib/sysdep/os/win/wposix/waio.h index 5db211ae5e..6a82b4b51d 100644 --- a/source/lib/sysdep/os/win/wposix/waio.h +++ b/source/lib/sysdep/os/win/wposix/waio.h @@ -83,6 +83,9 @@ extern int close(int); extern int read (int fd, void* buf, size_t nbytes); // thunk extern int write(int fd, void* buf, size_t nbytes); // thunk extern off_t lseek(int fd, off_t ofs, int whence); // thunk +// portable code for truncating files can use truncate or ftruncate. +// we'd like to use wchar_t pathnames, but neither truncate nor open have +// portable wchar_t variants. callers will have to use multi-byte strings. LIB_API int truncate(const char* path, off_t length); diff --git a/source/lib/sysdep/os/win/wposix/wdlfcn.cpp b/source/lib/sysdep/os/win/wposix/wdlfcn.cpp index 924becf00a..0f988f0563 100644 --- a/source/lib/sysdep/os/win/wposix/wdlfcn.cpp +++ b/source/lib/sysdep/os/win/wposix/wdlfcn.cpp @@ -18,7 +18,6 @@ #include "precompiled.h" #include "wdlfcn.h" -#include "lib/os_path.h" #include "wposix_internal.h" @@ -41,7 +40,7 @@ int dlclose(void* handle) } -char* dlerror(void) +char* dlerror() { return 0; } @@ -51,8 +50,8 @@ void* dlopen(const char* so_name, int flags) { debug_assert(!(flags & RTLD_GLOBAL)); - OsPath path = fs::change_extension(so_name, ".dll"); - HMODULE hModule = LoadLibrary(path.external_directory_string().c_str()); + fs::path pathname = fs::change_extension(so_name, ".dll"); + HMODULE hModule = LoadLibrary(pathname.string().c_str()); debug_assert(hModule); return void_from_HMODULE(hModule); } diff --git a/source/lib/sysdep/os/win/wposix/wdlfcn.h b/source/lib/sysdep/os/win/wposix/wdlfcn.h index b00a6c283b..ca8a4404c2 100644 --- a/source/lib/sysdep/os/win/wposix/wdlfcn.h +++ b/source/lib/sysdep/os/win/wposix/wdlfcn.h @@ -30,7 +30,7 @@ #define RTLD_LOCAL 0x08 extern int dlclose(void* handle); -extern char* dlerror(void); +extern char* dlerror(); extern void* dlopen(const char* so_name, int flags); extern void* dlsym(void* handle, const char* sym_name); diff --git a/source/lib/sysdep/os/win/wposix/wfilesystem.cpp b/source/lib/sysdep/os/win/wposix/wfilesystem.cpp index 9d9575d412..b9baf2c512 100644 --- a/source/lib/sysdep/os/win/wposix/wfilesystem.cpp +++ b/source/lib/sysdep/os/win/wposix/wfilesystem.cpp @@ -56,14 +56,14 @@ filesystem; // the app's directory (and therefore its appendant volume - see above). static void detect_filesystem() { - char root_path[MAX_PATH] = "c:\\"; // default in case GCD fails - DWORD gcd_ret = GetCurrentDirectory(sizeof(root_path), root_path); + wchar_t root_path[MAX_PATH] = L"c:\\"; // default in case GCD fails + DWORD gcd_ret = GetCurrentDirectoryW(ARRAY_SIZE(root_path), root_path); debug_assert(gcd_ret != 0); // if this fails, no problem - we have the default from above. root_path[3] = '\0'; // cut off after "c:\" - char fs_name[32] = {0}; - BOOL ret = GetVolumeInformation(root_path, 0,0,0,0,0, fs_name, sizeof(fs_name)); + wchar_t fs_name[32] = {0}; + BOOL ret = GetVolumeInformationW(root_path, 0,0,0,0,0, fs_name, sizeof(fs_name)); fs_name[ARRAY_SIZE(fs_name)-1] = '\0'; debug_assert(ret != 0); // if this fails, no problem - we really only care if fs is FAT, @@ -71,9 +71,9 @@ static void detect_filesystem() filesystem = FS_UNKNOWN; - if(!strncmp(fs_name, "FAT", 3)) // e.g. FAT32 + if(!wcsncmp(fs_name, L"FAT", 3)) // e.g. FAT32 filesystem = FS_FAT; - else if(!strcmp(fs_name, "NTFS")) + else if(!wcscmp(fs_name, L"NTFS")) filesystem = FS_NTFS; } @@ -295,7 +295,7 @@ DIR* opendir(const char* path) // information about that directory; trailing slashes aren't allowed. // for dir entries to be returned, we have to append "\\*". char search_path[PATH_MAX]; - snprintf(search_path, ARRAY_SIZE(search_path), "%s\\*", path); + sprintf_s(search_path, ARRAY_SIZE(search_path), "%s\\*", path); // note: we could store search_path and defer FindFirstFile until // readdir. this way is a bit more complex but required for diff --git a/source/lib/sysdep/os/win/wposix/wmman.cpp b/source/lib/sysdep/os/win/wposix/wmman.cpp index 088e1ad7bd..78f001de10 100644 --- a/source/lib/sysdep/os/win/wposix/wmman.cpp +++ b/source/lib/sysdep/os/win/wposix/wmman.cpp @@ -102,7 +102,7 @@ static LibError mmap_mem(void* start, size_t len, int prot, int flags, int fd, v void* p = VirtualAlloc(start, len, flAllocationType, flProtect); if(!p) { - debug_printf("wmman: VirtualAlloc(%p, 0x%I64X) failed\n", start, len); + debug_printf(L"wmman: VirtualAlloc(%p, 0x%I64X) failed\n", start, len); WARN_RETURN(ERR::NO_MEM); } *pp = p; diff --git a/source/lib/sysdep/os/win/wposix/wpthread.cpp b/source/lib/sysdep/os/win/wposix/wpthread.cpp index b7f2e5428e..588ec70912 100644 --- a/source/lib/sysdep/os/win/wposix/wpthread.cpp +++ b/source/lib/sysdep/os/win/wposix/wpthread.cpp @@ -47,13 +47,13 @@ static pthread_t pthread_from_HANDLE(HANDLE h) // misc //----------------------------------------------------------------------------- -pthread_t pthread_self(void) +pthread_t pthread_self() { return pthread_from_HANDLE(GetCurrentThread()); } -int pthread_once(pthread_once_t* once, void (*init_routine)(void)) +int pthread_once(pthread_once_t* once, void (*init_routine)()) { if(cpu_CAS(once, 0, 1)) init_routine(); @@ -622,7 +622,7 @@ int pthread_cancel(pthread_t thread) { HANDLE hThread = HANDLE_from_pthread(thread); TerminateThread(hThread, 0); - debug_printf("WARNING: pthread_cancel is unsafe\n"); + debug_printf(L"WARNING: pthread_cancel is unsafe\n"); return 0; } diff --git a/source/lib/sysdep/os/win/wposix/wpthread.h b/source/lib/sysdep/os/win/wposix/wpthread.h index cea3e89781..fdd68ae964 100644 --- a/source/lib/sysdep/os/win/wposix/wpthread.h +++ b/source/lib/sysdep/os/win/wposix/wpthread.h @@ -52,12 +52,12 @@ enum typedef uintptr_t pthread_once_t; #define PTHREAD_ONCE_INIT 0 // static pthread_once_t x = PTHREAD_ONCE_INIT; -extern int pthread_once(pthread_once_t*, void (*init_routine)(void)); +extern int pthread_once(pthread_once_t*, void (*init_routine)()); // thread typedef uintptr_t pthread_t; -extern pthread_t pthread_self(void); +extern pthread_t pthread_self(); extern int pthread_getschedparam(pthread_t thread, int* policy, struct sched_param* param); extern int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param* param); extern int pthread_create(pthread_t* thread, const void* attr, void* (*func)(void*), void* arg); @@ -69,7 +69,7 @@ typedef void* pthread_mutex_t; // pointer to critical section typedef void pthread_mutexattr_t; #define PTHREAD_MUTEX_INITIALIZER pthread_mutex_initializer() -extern pthread_mutex_t pthread_mutex_initializer(void); +extern pthread_mutex_t pthread_mutex_initializer(); extern int pthread_mutex_init(pthread_mutex_t*, const pthread_mutexattr_t*); extern int pthread_mutex_destroy(pthread_mutex_t*); extern int pthread_mutex_lock(pthread_mutex_t*); diff --git a/source/lib/sysdep/os/win/wposix/wsock_internal.h b/source/lib/sysdep/os/win/wposix/wsock_internal.h index a9437588d9..a526cbc60b 100644 --- a/source/lib/sysdep/os/win/wposix/wsock_internal.h +++ b/source/lib/sysdep/os/win/wposix/wsock_internal.h @@ -20,9 +20,9 @@ extern "C" { #endif extern __declspec(dllimport) int __stdcall WSAStartup(unsigned short, void*); -extern __declspec(dllimport) int __stdcall WSACleanup(void); +extern __declspec(dllimport) int __stdcall WSACleanup(); extern __declspec(dllimport) int __stdcall WSAAsyncSelect(int s, HANDLE hWnd, unsigned int wMsg, long lEvent); -extern __declspec(dllimport) int __stdcall WSAGetLastError(void); +extern __declspec(dllimport) int __stdcall WSAGetLastError(); #ifdef __cplusplus } diff --git a/source/lib/sysdep/os/win/wposix/wterminal.h b/source/lib/sysdep/os/win/wposix/wterminal.h index c2ea561cb1..b752529140 100644 --- a/source/lib/sysdep/os/win/wposix/wterminal.h +++ b/source/lib/sysdep/os/win/wposix/wterminal.h @@ -43,8 +43,8 @@ extern int ioctl(int fd, int op, int* data); #endif -extern void _get_console(void); -extern void _hide_console(void); +extern void _get_console(); +extern void _hide_console(); // diff --git a/source/lib/sysdep/os/win/wprintf.cpp b/source/lib/sysdep/os/win/wprintf.cpp index dcbae42d02..d985197acb 100644 --- a/source/lib/sysdep/os/win/wprintf.cpp +++ b/source/lib/sysdep/os/win/wprintf.cpp @@ -16,7 +16,7 @@ */ /* - * implementation of sys_vsnprintf. + * implementation of sys_vswprintf. */ #include "precompiled.h" @@ -47,7 +47,15 @@ */ +#define _UNICODE #include +#ifdef _UNICODE +# define tstring wstring +# define tstringstream wstringstream +#else +# define tstring string +# define tstringstream stringstream +#endif #include #include @@ -90,8 +98,8 @@ struct FormatVariable : public FormatChunk struct FormatString : public FormatChunk { int ChunkType() { return 1; } - FormatString(std::string t) : text(t) {} - std::string text; + FormatString(std::tstring t) : text(t) {} + std::tstring text; }; @@ -109,9 +117,9 @@ int get_flag(TCHAR c) return 0; } -std::string flags_to_string(char flags) +std::tstring flags_to_string(char flags) { - std::string s; + std::tstring s; const char* c = "\'-+ #0"; for (int i=0; i<6; ++i) if (flags & (1< -std::string to_string(T n) +std::tstring to_string(T n) { - std::string s; - std::stringstream str; + std::tstring s; + std::tstringstream str; str << n; str >> s; return s; @@ -198,7 +206,7 @@ int type_size(TCHAR type, int length) return 0; } -int sys_vsnprintf(TCHAR* buffer, size_t count, const TCHAR* format, va_list argptr) +int sys_vswprintf(TCHAR* buffer, size_t count, const TCHAR* format, va_list argptr) { /* @@ -212,7 +220,7 @@ int sys_vsnprintf(TCHAR* buffer, size_t count, const TCHAR* format, va_list argp /**** Parse the format string into constant/variable chunks ****/ std::vector specs; - std::string stringchunk; + std::tstring stringchunk; TCHAR chr; @@ -346,7 +354,7 @@ finished_reading: /**** Build a new format string (to pass to the system printf) ****/ - std::string newformat; + std::tstring newformat; std::vector varsizes; // stores the size of each variable type, to allow stack twiddling @@ -368,7 +376,7 @@ finished_reading: } - newformat += "%"; + newformat += _T("%"); if (s->flags) newformat += flags_to_string(s->flags); @@ -395,10 +403,10 @@ finished_reading: #if USE_I64_FORMAT newformat += "I64"; #else - newformat += "ll"; + newformat += _T("ll"); #endif else if (s->length == 0x00006868) - newformat += "hh"; + newformat += _T("hh"); } else { @@ -433,14 +441,14 @@ finished_reading: #endif // Highly efficient buffer to store the rearranged copy of the stack - std::string newstack; + std::tstring newstack; std::vector< std::pair > stackitems; va_list arglist = argptr; //va_start(arglist, format); - const char* newstackptr; + const TCHAR* newstackptr; if (varsizes.size()) { @@ -474,7 +482,7 @@ finished_reading: debug_assert(0); // Invalid use of positional elements - make sure all variable things are positional and defined return -1; } - newstack += std::string( stackitems[s->position-1].first, stackitems[s->position-1].second ); + newstack += std::tstring( stackitems[s->position-1].first, stackitems[s->position-1].second ); } } @@ -482,7 +490,7 @@ finished_reading: } else { - newstackptr = arglist; + newstackptr = (const TCHAR*)arglist; } for (ChunkIt it = specs.begin(); it != specs.end(); ++it) @@ -491,7 +499,7 @@ finished_reading: else delete static_cast(*it); - int ret = _vsnprintf(buffer, count, newformat.c_str(), (va_list)newstackptr); + int ret = _vsntprintf(buffer, count, newformat.c_str(), (va_list)newstackptr); // For consistency with GCC's vsnprintf, make sure the buffer is null-terminated // and return an error if that truncates the output diff --git a/source/lib/sysdep/os/win/wsdl.cpp b/source/lib/sysdep/os/win/wsdl.cpp index ae7cdae291..2447b06051 100644 --- a/source/lib/sysdep/os/win/wsdl.cpp +++ b/source/lib/sysdep/os/win/wsdl.cpp @@ -367,7 +367,7 @@ SDL_VideoInfo* SDL_GetVideoInfo() if(video_info.video_mem == 0) { WmiMap videoAdapter; - if(wmi_GetClass("Win32_VideoController", videoAdapter) == INFO::OK) + if(wmi_GetClass(L"Win32_VideoController", videoAdapter) == INFO::OK) { VARIANT vTotalMemory = videoAdapter[L"AdapterRAM"]; video_info.video_mem = vTotalMemory.lVal; @@ -1039,7 +1039,7 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar } -void SDL_PumpEvents(void) +void SDL_PumpEvents() { // rationale: we would like to reduce CPU usage automatically if // possible. blocking here until a message arrives would accomplish @@ -1251,13 +1251,12 @@ static LibError wsdl_Init() // notes: // - use full path for safety (works even if someone does chdir) // - the real SDL does this in its WinMain hook - char path[MAX_PATH]; - snprintf(path, ARRAY_SIZE(path), "%s\\stdout.txt", win_exe_dir); + fs::wpath path = wutil_ExecutablePath()/L"stdout.txt"; // ignore BoundsChecker warnings here. subsystem is set to "Windows" // to avoid the OS opening a console on startup (ugly). that means // stdout isn't associated with a lowio handle; _close ends up // getting called with fd = -1. oh well, nothing we can do. - FILE* f = freopen(path, "wt", stdout); + FILE* f = _wfreopen(path.string().c_str(), L"wt", stdout); debug_assert(f); #if CONFIG_PARANOIA diff --git a/source/lib/sysdep/os/win/wsdl.h b/source/lib/sysdep/os/win/wsdl.h index cffecc1001..1ed350a80d 100644 --- a/source/lib/sysdep/os/win/wsdl.h +++ b/source/lib/sysdep/os/win/wsdl.h @@ -38,7 +38,7 @@ typedef u32 Uint32; extern int SDL_Init(Uint32 flags); -extern void SDL_Quit(void); +extern void SDL_Quit(); // @@ -66,7 +66,7 @@ typedef struct } SDL_Surface; -extern SDL_Surface* SDL_GetVideoSurface(void); +extern SDL_Surface* SDL_GetVideoSurface(); typedef struct { @@ -74,11 +74,11 @@ typedef struct } SDL_VideoInfo; -extern SDL_VideoInfo* SDL_GetVideoInfo(void); +extern SDL_VideoInfo* SDL_GetVideoInfo(); extern void* SDL_GL_GetProcAddress(const char*); -extern void SDL_GL_SwapBuffers(void); +extern void SDL_GL_SwapBuffers(); // @@ -88,7 +88,7 @@ extern void SDL_GL_SwapBuffers(void); typedef void SDL_sem; typedef void SDL_Thread; -extern u32 SDL_GetTicks(void); +extern u32 SDL_GetTicks(); extern void SDL_Delay(u32 ms); extern SDL_sem* SDL_CreateSemaphore(int cnt); diff --git a/source/lib/sysdep/os/win/wseh.cpp b/source/lib/sysdep/os/win/wseh.cpp index 0f954339a3..0cdf537feb 100644 --- a/source/lib/sysdep/os/win/wseh.cpp +++ b/source/lib/sysdep/os/win/wseh.cpp @@ -133,7 +133,7 @@ static const wchar_t* GetCppExceptionDescription(const EXCEPTION_RECORD* er, // format the info we got (if both are empty, then something is seriously // wrong; it's better to show empty strings than returning 0 to have our // caller display the SEH info) - swprintf(description, maxChars, L"%hs(\"%hs\")", type_name, what); + swprintf_s(description, maxChars, L"%hs(\"%hs\")", type_name, what); return description; } @@ -156,7 +156,7 @@ static const wchar_t* GetSehExceptionDescription(const EXCEPTION_RECORD* er, // special case: display type and address. const wchar_t* accessType = (ei[0])? L"writing" : L"reading"; const ULONG_PTR address = ei[1]; - swprintf(description, maxChars, L"Access violation %s 0x%08X", accessType, address); + swprintf_s(description, maxChars, L"Access violation %ls 0x%08X", accessType, address); return description; } case EXCEPTION_DATATYPE_MISALIGNMENT: return L"Datatype misalignment"; @@ -208,13 +208,13 @@ static const wchar_t* GetExceptionDescription(const EXCEPTION_POINTERS* ep, // return location at which the exception occurred. // params: see debug_ResolveSymbol. static void GetExceptionLocus(const EXCEPTION_POINTERS* ep, - char* file, int* line, char* func) + wchar_t* file, int* line, wchar_t* func) { // HACK: provides no useful information - ExceptionAddress always // points to kernel32!RaiseException. we use debug_GetCaller to // determine the real location. - const char* const lastFuncToSkip = "RaiseException"; + const wchar_t* const lastFuncToSkip = L"RaiseException"; void* func_addr = debug_GetCaller(ep->ContextRecord, lastFuncToSkip); (void)debug_ResolveSymbol(func_addr, func, file, line); } @@ -262,9 +262,9 @@ long __stdcall wseh_ExceptionFilter(struct _EXCEPTION_POINTERS* ep) // extract details from ExceptionRecord. wchar_t descriptionBuf[150]; const wchar_t* description = GetExceptionDescription(ep, descriptionBuf, ARRAY_SIZE(descriptionBuf)); - char file[DBG_FILE_LEN] = {0}; + wchar_t file[DBG_FILE_LEN] = {0}; int line = 0; - char func[DBG_SYMBOL_LEN] = {0}; + wchar_t func[DBG_SYMBOL_LEN] = {0}; GetExceptionLocus(ep, file, &line, func); wchar_t message[500]; @@ -273,13 +273,13 @@ long __stdcall wseh_ExceptionFilter(struct _EXCEPTION_POINTERS* ep) L"\r\n" L"Please let us know at http://trac.wildfiregames.com/ and attach the crashlog.txt and crashlog.dmp files.\r\n" L"\r\n" - L"Details: unhandled exception (%s)\r\n"; - swprintf(message, ARRAY_SIZE(message), messageFormat, description); + L"Details: unhandled exception (%ls)\r\n"; + swprintf_s(message, ARRAY_SIZE(message), messageFormat, description); size_t flags = 0; if(ep->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE) flags = DE_NO_CONTINUE; - const char* const lastFuncToSkip = STRINGIZE(DECORATED_NAME(wseh_ExceptionFilter)); + const wchar_t* const lastFuncToSkip = WIDEN(STRINGIZE(DECORATED_NAME(wseh_ExceptionFilter))); ErrorReaction er = debug_DisplayError(message, flags, ep->ContextRecord, lastFuncToSkip, file,line,func, 0); debug_assert(er == ER_CONTINUE); // nothing else possible diff --git a/source/lib/sysdep/os/win/wsnd.cpp b/source/lib/sysdep/os/win/wsnd.cpp index 37d2ae71b8..95df5277e1 100644 --- a/source/lib/sysdep/os/win/wsnd.cpp +++ b/source/lib/sysdep/os/win/wsnd.cpp @@ -34,29 +34,29 @@ #include "wmi.h" -static LibError IsOpenAlDllName(const std::string& name) +static bool IsOpenAlDllName(const std::wstring& name) { // (matches "*oal.dll" and "*OpenAL*", as with OpenAL router's search) - return name.find("oal.dll") != std::string::npos || name.find("OpenAL") != std::string::npos; + return name.find(L"oal.dll") != std::wstring::npos || name.find(L"OpenAL") != std::wstring::npos; } // ensures each OpenAL DLL is only listed once (even if present in several // directories on our search path). -typedef std::set StringSet; +typedef std::set StringSet; // find all OpenAL DLLs in a dir. // call in library search order (exe dir, then win sys dir); otherwise, // DLLs in the executable's starting directory hide those of the // same name in the system directory. -static void add_oal_dlls_in_dir(const OsPath& path, StringSet& dlls, std::string& versionList) +static void add_oal_dlls_in_dir(const fs::wpath& path, StringSet& dlls, std::wstring& versionList) { - for(OsDirectoryIterator it(path); it != OsDirectoryIterator(); ++it) + for(fs::wdirectory_iterator it(path); it != fs::wdirectory_iterator(); ++it) { if(!fs::is_regular(it->status())) continue; - const OsPath& pathname = it->path(); - const std::string& name = pathname.leaf(); + const fs::wpath& pathname = it->path(); + const std::wstring& name = pathname.leaf(); if(!IsOpenAlDllName(name)) continue; @@ -82,12 +82,12 @@ static void add_oal_dlls_in_dir(const OsPath& path, StringSet& dlls, std::string // the version info for that bogus driver path, we'll skip this code there. // (delay-loading dsound.dll eliminates any overhead) -static char directSoundDriverPath[MAX_PATH+1]; +static fs::wpath directSoundDriverPath; // store sound card name and path to DirectSound driver. // called for each DirectSound driver, but aborts after first valid driver. -static BOOL CALLBACK DirectSoundCallback(void* guid, const char* UNUSED(description), - const char* module, void* UNUSED(cbData)) +static BOOL CALLBACK DirectSoundCallback(void* guid, const wchar_t* UNUSED(description), + const wchar_t* module, void* UNUSED(cbData)) { // skip first dummy entry (description == "Primary Sound Driver") if(guid == NULL) @@ -95,23 +95,23 @@ static BOOL CALLBACK DirectSoundCallback(void* guid, const char* UNUSED(descript // note: $system\\drivers is not in LoadLibrary's search list, // so we have to give the full pathname. - snprintf(directSoundDriverPath, ARRAY_SIZE(directSoundDriverPath), "%s\\drivers\\%s", win_sys_dir, module); + directSoundDriverPath = wutil_SystemPath()/L"drivers"/module; // we assume the first "driver name" (sound card) is the one we want; // stick with that and stop calling. return FALSE; } -static const char* GetDirectSoundDriverPath() +static const fs::wpath& GetDirectSoundDriverPath() { #define DS_OK 0 - typedef BOOL (CALLBACK* LPDSENUMCALLBACKA)(void*, const char*, const char*, void*); - typedef HRESULT (WINAPI *PDirectSoundEnumerateA)(LPDSENUMCALLBACKA, void*); + typedef BOOL (CALLBACK* LPDSENUMCALLBACKW)(void*, const wchar_t*, const wchar_t*, void*); + typedef HRESULT (WINAPI *PDirectSoundEnumerateW)(LPDSENUMCALLBACKW, void*); HMODULE hDsoundDll = LoadLibrary("dsound.dll"); - PDirectSoundEnumerateA pDirectSoundEnumerateA = (PDirectSoundEnumerateA)GetProcAddress(hDsoundDll, "DirectSoundEnumerateA"); - if(pDirectSoundEnumerateA) + PDirectSoundEnumerateW pDirectSoundEnumerateW = (PDirectSoundEnumerateW)GetProcAddress(hDsoundDll, "DirectSoundEnumerateW"); + if(pDirectSoundEnumerateW) { - HRESULT ret = pDirectSoundEnumerateA(DirectSoundCallback, (void*)0); + HRESULT ret = pDirectSoundEnumerateW(DirectSoundCallback, (void*)0); debug_assert(ret == DS_OK); } FreeLibrary(hDsoundDll); @@ -124,17 +124,17 @@ static const char* GetDirectSoundDriverPath() LibError win_get_snd_info() { WmiMap wmiMap; - if(wmi_GetClass("Win32_SoundDevice", wmiMap) == INFO::OK) - sprintf_s(snd_card, SND_CARD_LEN, "%ls", wmiMap[L"ProductName"].bstrVal); + if(wmi_GetClass(L"Win32_SoundDevice", wmiMap) == INFO::OK) + swprintf_s(snd_card, SND_CARD_LEN, L"%ls", wmiMap[L"ProductName"].bstrVal); // find all DLLs related to OpenAL and retrieve their versions. - std::string versionList; + std::wstring versionList; if(wutil_WindowsVersion() < WUTIL_VERSION_VISTA) wdll_ver_Append(GetDirectSoundDriverPath(), versionList); StringSet dlls; // ensures uniqueness - (void)add_oal_dlls_in_dir(win_exe_dir, dlls, versionList); - (void)add_oal_dlls_in_dir(win_sys_dir, dlls, versionList); - strcpy_s(snd_drv_ver, SND_DRV_VER_LEN, versionList.c_str()); + (void)add_oal_dlls_in_dir(wutil_ExecutablePath(), dlls, versionList); + (void)add_oal_dlls_in_dir(wutil_SystemPath(), dlls, versionList); + wcscpy_s(snd_drv_ver, SND_DRV_VER_LEN, versionList.c_str()); return INFO::OK; } diff --git a/source/lib/sysdep/os/win/wsysdep.cpp b/source/lib/sysdep/os/win/wsysdep.cpp index 7d87e19472..62ab345cca 100644 --- a/source/lib/sysdep/os/win/wsysdep.cpp +++ b/source/lib/sysdep/os/win/wsysdep.cpp @@ -281,7 +281,7 @@ ErrorReaction sys_display_error(const wchar_t* text, size_t flags) // misc //----------------------------------------------------------------------------- -LibError sys_error_description_r(int user_err, char* buf, size_t max_chars) +LibError sys_error_description_r(int user_err, wchar_t* buf, size_t max_chars) { // validate user_err - Win32 doesn't have negative error numbers if(user_err < 0) @@ -293,44 +293,55 @@ LibError sys_error_description_r(int user_err, char* buf, size_t max_chars) // error messages, so return more descriptive text instead. if(err == 0) { - strcpy_s(buf, max_chars, "0 (no error code was set)"); + wcscpy_s(buf, max_chars, L"0 (no error code was set)"); return INFO::OK; } - char message[200]; + wchar_t message[200]; { const LPCVOID source = 0; // ignored (we're not using FROM_HMODULE etc.) const DWORD lang_id = 0; // look for neutral, then current locale va_list* args = 0; // we don't care about "inserts" - const DWORD charsWritten = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, source, err, lang_id, message, (DWORD)ARRAY_SIZE(message), args); + const DWORD charsWritten = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, source, err, lang_id, message, (DWORD)ARRAY_SIZE(message), args); if(!charsWritten) WARN_RETURN(ERR::FAIL); debug_assert(charsWritten < max_chars); } - const int charsWritten = sprintf_s(buf, max_chars, "%d (%s)", err, message); + const int charsWritten = swprintf_s(buf, max_chars, L"%d (%ls)", err, message); debug_assert(charsWritten != -1); return INFO::OK; } -void sys_get_module_filename(void* addr, wchar_t* path, size_t max_chars) +LibError sys_get_module_filename(void* addr, fs::wpath& pathname) { - path[0] = '\0'; // in case either API call below fails - MEMORY_BASIC_INFORMATION mbi; - if(VirtualQuery(addr, &mbi, sizeof(mbi))) - { - HMODULE hModule = (HMODULE)mbi.AllocationBase; - GetModuleFileNameW(hModule, path, (DWORD)max_chars); - } + const SIZE_T bytesWritten = VirtualQuery(addr, &mbi, sizeof(mbi)); + if(!bytesWritten) + return LibError_from_GLE(); + debug_assert(bytesWritten >= sizeof(mbi)); + const HMODULE hModule = (HMODULE)mbi.AllocationBase; + + wchar_t pathnameBuf[MAX_PATH+1]; + const DWORD charsWritten = GetModuleFileNameW(hModule, pathnameBuf, (DWORD)ARRAY_SIZE(pathnameBuf)); + if(charsWritten == 0) + return LibError_from_GLE(); + debug_assert(charsWritten < ARRAY_SIZE(pathnameBuf)); + pathname = pathnameBuf; + return INFO::OK; } -LibError sys_get_executable_name(char* n_path, size_t max_chars) +LibError sys_get_executable_name(fs::wpath& pathname) { - const DWORD num_chars = GetModuleFileName(0, n_path, (DWORD)max_chars); - return num_chars? INFO::OK : ERR::FAIL; + wchar_t pathnameBuf[MAX_PATH+1]; + const DWORD charsWritten = GetModuleFileNameW(0, pathnameBuf, (DWORD)ARRAY_SIZE(pathnameBuf)); + if(charsWritten == 0) + return LibError_from_GLE(); + debug_assert(charsWritten < ARRAY_SIZE(pathnameBuf)); + pathname = pathnameBuf; + return INFO::OK; } @@ -340,29 +351,28 @@ static int CALLBACK browse_cb(HWND hWnd, unsigned int msg, LPARAM UNUSED(lParam) { if(msg == BFFM_INITIALIZED) { - const char* cur_dir = (const char*)ldata; - SendMessage(hWnd, BFFM_SETSELECTIONA, 1, (LPARAM)cur_dir); + const wchar_t* initialPath = (const wchar_t*)ldata; + SendMessage(hWnd, BFFM_SETSELECTIONA, 1, (LPARAM)initialPath); return 1; } return 0; } -LibError sys_pick_directory(char* path, size_t max_chars) +LibError sys_pick_directory(fs::wpath& path) { // bring up dialog; set starting directory to current working dir. - WARN_IF_FALSE(GetCurrentDirectory((DWORD)max_chars, path)); + fs::wpath initialPath = fs::current_path(); BROWSEINFOA bi; memset(&bi, 0, sizeof(bi)); bi.ulFlags = BIF_RETURNONLYFSDIRS; bi.lpfn = (BFFCALLBACK)browse_cb; - bi.lParam = (LPARAM)path; + bi.lParam = (LPARAM)initialPath.string().c_str(); LPITEMIDLIST pidl = SHBrowseForFolderA(&bi); - // translate ITEMIDLIST to string. note: SHGetPathFromIDList doesn't - // support a user-specified char limit *sigh* - debug_assert(max_chars >= MAX_PATH); - BOOL ok = SHGetPathFromIDList(pidl, path); + // translate ITEMIDLIST to string + wchar_t pathBuf[MAX_PATH]; + BOOL ok = SHGetPathFromIDListW(pidl, pathBuf); // free the ITEMIDLIST IMalloc* p_malloc; @@ -370,5 +380,6 @@ LibError sys_pick_directory(char* path, size_t max_chars) p_malloc->Free(pidl); p_malloc->Release(); + path = pathBuf; return LibError_from_win32(ok); } diff --git a/source/lib/sysdep/os/win/wutil.cpp b/source/lib/sysdep/os/win/wutil.cpp index 0930106314..eb424ee10b 100644 --- a/source/lib/sysdep/os/win/wutil.cpp +++ b/source/lib/sysdep/os/win/wutil.cpp @@ -162,18 +162,18 @@ LibError LibError_from_win32(DWORD ret, bool warn_if_failed) // copy of GetCommandLine string. will be tokenized and then referenced by // the argv pointers. -static char* argvContents; +static wchar_t* argvContents; int wutil_argc = 0; -char** wutil_argv = 0; +wchar_t** wutil_argv = 0; static void ReadCommandLine() { - const char* commandLine = GetCommandLine(); + const wchar_t* commandLine = GetCommandLineW(); // (this changes as quotation marks are removed) - size_t numChars = strlen(commandLine); - argvContents = (char*)HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, numChars+1); - strcpy_s(argvContents, numChars+1, commandLine); + size_t numChars = wcslen(commandLine); + argvContents = (wchar_t*)HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, (numChars+1)*sizeof(wchar_t)); + wcscpy_s(argvContents, numChars+1, commandLine); // first pass: tokenize string and count number of arguments bool ignoreSpace = false; @@ -184,7 +184,7 @@ static void ReadCommandLine() case '"': ignoreSpace = !ignoreSpace; // strip the " character - memmove(argvContents+i, argvContents+i+1, numChars-i); + memmove(argvContents+i, argvContents+i+1, (numChars-i)*sizeof(wchar_t)); numChars--; i--; break; @@ -201,12 +201,12 @@ static void ReadCommandLine() wutil_argc++; // have argv entries point into the tokenized string - wutil_argv = (char**)HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, wutil_argc*sizeof(char*)); - char* nextArg = argvContents; + wutil_argv = (wchar_t**)HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, wutil_argc*sizeof(wchar_t*)); + wchar_t* nextArg = argvContents; for(int i = 0; i < wutil_argc; i++) { wutil_argv[i] = nextArg; - nextArg += strlen(nextArg)+1; + nextArg += wcslen(nextArg)+1; } } @@ -218,11 +218,11 @@ static void FreeCommandLine() } -bool wutil_HasCommandLineArgument(const char* arg) +bool wutil_HasCommandLineArgument(const wchar_t* arg) { for(int i = 0; i < wutil_argc; i++) { - if(!strcmp(wutil_argv[i], arg)) + if(!wcscmp(wutil_argv[i], arg)) return true; } @@ -233,42 +233,69 @@ bool wutil_HasCommandLineArgument(const char* arg) //----------------------------------------------------------------------------- // directories -char win_sys_dir[MAX_PATH+1]; -char win_exe_dir[MAX_PATH+1]; -char win_appdata_dir[MAX_PATH+1]; +// (NB: wutil_Init is called before static ctors => use placement new) +static fs::wpath* systemPath; +static fs::wpath* executablePath; +static fs::wpath* appdataPath; + +const fs::wpath& wutil_SystemPath() +{ + return *systemPath; +} + +const fs::wpath& wutil_ExecutablePath() +{ + return *executablePath; +} + +const fs::wpath& wutil_AppdataPath() +{ + return *appdataPath; +} + static void GetDirectories() { WinScopedPreserveLastError s; + wchar_t path[MAX_PATH+1]; // system directory { - const UINT charsWritten = GetSystemDirectory(win_sys_dir, ARRAY_SIZE(win_sys_dir)); + const UINT charsWritten = GetSystemDirectoryW(path, ARRAY_SIZE(path)); debug_assert(charsWritten != 0); + systemPath = new(win_alloc(sizeof(fs::wpath))) fs::wpath(path); } // executable's directory { - const DWORD len = GetModuleFileName(GetModuleHandle(0), win_exe_dir, ARRAY_SIZE(win_exe_dir)); + const DWORD len = GetModuleFileNameW(GetModuleHandle(0), path, ARRAY_SIZE(path)); debug_assert(len != 0); - // strip EXE filename and trailing slash - char* slash = strrchr(win_exe_dir, '\\'); - if(slash) - *slash = '\0'; - else - debug_assert(0); // directory name invalid?! + executablePath = new(win_alloc(sizeof(fs::wpath))) fs::wpath(path); + *executablePath = executablePath->branch_path(); } // application data { HWND hwnd = 0; // ignored unless a dial-up connection is needed to access the folder HANDLE token = 0; - const HRESULT ret = SHGetFolderPath(hwnd, CSIDL_APPDATA, token, 0, win_appdata_dir); + const HRESULT ret = SHGetFolderPathW(hwnd, CSIDL_APPDATA, token, 0, path); debug_assert(SUCCEEDED(ret)); + appdataPath = new(win_alloc(sizeof(fs::wpath))) fs::wpath(path); } } +static void FreeDirectories() +{ + systemPath->~basic_path(); + win_free(systemPath); + executablePath->~basic_path(); + win_free(executablePath); + appdataPath->~basic_path(); + win_free(appdataPath); +} + + //----------------------------------------------------------------------------- // user32 fix @@ -334,7 +361,7 @@ static void DetectWindowsVersion() (void)RegQueryValueEx(hKey, "CurrentVersion", 0, 0, (LPBYTE)windowsVersionString, &size); int major = 0, minor = 0; - int ret = sscanf(windowsVersionString, "%d.%d", &major, &minor); + int ret = sscanf_s(windowsVersionString, "%d.%d", &major, &minor); debug_assert(ret == 2); debug_assert(major <= 0xFF && minor <= 0xFF); windowsVersion = (major << 8) | minor; @@ -538,5 +565,7 @@ static LibError wutil_Shutdown() ShutdownLocks(); + FreeDirectories(); + return INFO::OK; } diff --git a/source/lib/sysdep/os/win/wutil.h b/source/lib/sysdep/os/win/wutil.h index 262028516e..bf0532af20 100644 --- a/source/lib/sysdep/os/win/wutil.h +++ b/source/lib/sysdep/os/win/wutil.h @@ -135,19 +135,18 @@ extern LibError LibError_from_win32(DWORD ret, bool warn_if_failed = true); // extern int wutil_argc; -extern char** wutil_argv; +extern wchar_t** wutil_argv; -extern bool wutil_HasCommandLineArgument(const char* arg); +extern bool wutil_HasCommandLineArgument(const wchar_t* arg); // // directories // -// none of these end with a slash. -extern char win_sys_dir[MAX_PATH+1]; -extern char win_exe_dir[MAX_PATH+1]; -extern char win_appdata_dir[MAX_PATH+1]; +extern const fs::wpath& wutil_SystemPath(); +extern const fs::wpath& wutil_ExecutablePath(); +extern const fs::wpath& wutil_AppdataPath(); // diff --git a/source/lib/sysdep/os_cpu.cpp b/source/lib/sysdep/os_cpu.cpp index 786eba7739..977f808ad9 100644 --- a/source/lib/sysdep/os_cpu.cpp +++ b/source/lib/sysdep/os_cpu.cpp @@ -22,4 +22,4 @@ #include "precompiled.h" #include "os_cpu.h" -ERROR_ASSOCIATE(ERR::OS_CPU_RESTRICTED_AFFINITY, "Cannot set desired CPU affinity", -1); +ERROR_ASSOCIATE(ERR::OS_CPU_RESTRICTED_AFFINITY, L"Cannot set desired CPU affinity", -1); diff --git a/source/lib/sysdep/snd.cpp b/source/lib/sysdep/snd.cpp index 589ccb87c6..3daa044840 100644 --- a/source/lib/sysdep/snd.cpp +++ b/source/lib/sysdep/snd.cpp @@ -27,8 +27,8 @@ #endif -char snd_card[SND_CARD_LEN]; -char snd_drv_ver[SND_DRV_VER_LEN]; +wchar_t snd_card[SND_CARD_LEN]; +wchar_t snd_drv_ver[SND_DRV_VER_LEN]; void snd_detect() { diff --git a/source/lib/sysdep/snd.h b/source/lib/sysdep/snd.h index e39f865aff..259c5e080d 100644 --- a/source/lib/sysdep/snd.h +++ b/source/lib/sysdep/snd.h @@ -26,17 +26,17 @@ const size_t SND_CARD_LEN = 128; /** * description of sound card. **/ -extern char snd_card[SND_CARD_LEN]; +extern wchar_t snd_card[SND_CARD_LEN]; const size_t SND_DRV_VER_LEN = 256; /** * sound driver identification and version. **/ -extern char snd_drv_ver[SND_DRV_VER_LEN]; +extern wchar_t snd_drv_ver[SND_DRV_VER_LEN]; /** * detect sound card and set the above information. **/ -extern void snd_detect(void); +extern void snd_detect(); #endif // #ifndef INCLUDED_SND diff --git a/source/lib/sysdep/stl.h b/source/lib/sysdep/stl.h index b6239a6f58..0dd5f25a81 100644 --- a/source/lib/sysdep/stl.h +++ b/source/lib/sysdep/stl.h @@ -143,7 +143,7 @@ template<> struct hash { union { const void* ptr; - unsigned char bytes[sizeof(void*)]; + u8 bytes[sizeof(void*)]; } val; size_t h = 5381; diff --git a/source/lib/sysdep/sysdep.h b/source/lib/sysdep/sysdep.h index 3f621d910c..d644964290 100644 --- a/source/lib/sysdep/sysdep.h +++ b/source/lib/sysdep/sysdep.h @@ -24,7 +24,7 @@ #include "lib/debug.h" // ErrorReaction -#include // needed for sys_vsnprintf +#include // needed for sys_vswprintf // @@ -60,13 +60,13 @@ extern ErrorReaction sys_display_error(const wchar_t* text, size_t flags); // /** - * sys_vsnprintf: doesn't quite follow the standard for vsnprintf, but works + * sys_vswprintf: doesn't quite follow the standard for vswprintf, but works * better across compilers: * - handles positional parameters and %lld * - always null-terminates the buffer * - returns -1 on overflow (if the output string (including null) does not fit in the buffer) **/ -extern int sys_vsnprintf(char* buffer, size_t count, const char* format, va_list argptr); +extern int sys_vswprintf(wchar_t* buffer, size_t count, const wchar_t* format, va_list argptr); /** * describe the current OS error state. @@ -79,35 +79,34 @@ extern int sys_vsnprintf(char* buffer, size_t count, const char* format, va_list * rationale: it is expected to be rare that OS return/error codes are * actually seen by user code, but we leave the possibility open. **/ -extern LibError sys_error_description_r(int err, char* buf, size_t max_chars); +extern LibError sys_error_description_r(int err, wchar_t* buf, size_t max_chars); /** * determine filename of the module to whom an address belongs. * - * @param path receives full path to module or L"" on error. - * @param max_chars + * @param path full path to module (unchanged unless INFO::OK is returned). + * @return LibError * * note: this is useful for handling exceptions in other modules. **/ -void sys_get_module_filename(void* addr, wchar_t* path, size_t max_chars); +LibError sys_get_module_filename(void* addr, fs::wpath& pathname); /** * get path to the current executable. * - * @param n_path receives the full native path. - * @param max_chars + * @param path full path to executable (unchanged unless INFO::OK is returned). + * @return LibError * * this is useful for determining installation directory, e.g. for VFS. **/ -extern LibError sys_get_executable_name(char* n_path, size_t max_chars); +extern LibError sys_get_executable_name(fs::wpath& pathname); /** * have the user choose a directory via OS dialog. * - * @param n_path receives the full native path. - * @param max_chars must be at least PATH_MAX due to a Win32 limitation. + * @param path (unchanged unless INFO::OK is returned). **/ -extern LibError sys_pick_directory(char* n_path, size_t max_chars); +extern LibError sys_pick_directory(fs::wpath& path); /** * return the largest sector size [bytes] of any storage medium diff --git a/source/lib/sysdep/tests/test_printf.h b/source/lib/sysdep/tests/test_printf.h index 8ca271c2a3..dd8e72f788 100644 --- a/source/lib/sysdep/tests/test_printf.h +++ b/source/lib/sysdep/tests/test_printf.h @@ -22,35 +22,35 @@ class TestPrintf : public CxxTest::TestSuite { // Split some bits into separate functions, so we can get - // a legitimate va_list to pass to sys_vsnprintf: + // a legitimate va_list to pass to sys_vswprintf: - void _test_truncate(int buffer_size, const char* expected_output, int expected_return, /* char* input_string */...) + void _test_truncate(int buffer_size, const wchar_t* expected_output, int expected_return, /* wchar_t* input_string */...) { - char buf[17] = "................"; // fill with dots so null-termination is made obvious + wchar_t buf[17] = L"................"; // fill with dots so null-termination is made obvious va_list ap; va_start(ap, expected_return); - int ret = sys_vsnprintf(buf, buffer_size, "%s", ap); + int ret = sys_vswprintf(buf, buffer_size, L"%ls", ap); - TS_ASSERT_STR_EQUALS(buf, expected_output); + TS_ASSERT_WSTR_EQUALS(buf, expected_output); TS_ASSERT_EQUALS(ret, expected_return); - std::string past_buffer (buf + buffer_size); + std::wstring past_buffer(buf + buffer_size); TS_ASSERT(past_buffer.find_first_not_of('.') == past_buffer.npos); va_end(ap); } - void _test_sprintf(const char* expected_output, const char* format, ...) + void _test_sprintf(const wchar_t* expected_output, const wchar_t* format, ...) { - char buf[256]; + wchar_t buf[256]; va_list ap; va_start(ap, format); - sys_vsnprintf(buf, sizeof(buf), format, ap); - TS_ASSERT_STR_EQUALS(buf, expected_output); + sys_vswprintf(buf, ARRAY_SIZE(buf), format, ap); + TS_ASSERT_WSTR_EQUALS(buf, expected_output); va_end(ap); } @@ -58,34 +58,34 @@ class TestPrintf : public CxxTest::TestSuite public: void test_truncate() { - _test_truncate(8, "1234", 4, "1234"); - _test_truncate(8, "1234567", 7, "1234567"); - _test_truncate(8, "1234567", -1, "12345678"); - _test_truncate(8, "1234567", -1, "123456789"); - _test_truncate(8, "1234567", -1, "123456789abcdef"); + _test_truncate(8, L"1234", 4, L"1234"); + _test_truncate(8, L"1234567", 7, L"1234567"); + _test_truncate(8, L"1234567", -1, L"12345678"); + _test_truncate(8, L"1234567", -1, L"123456789"); + _test_truncate(8, L"1234567", -1, L"123456789abcdef"); } void test_lld() { i64 z = 0; i64 n = 65536; - _test_sprintf("0", "%lld", z); - _test_sprintf("65536", "%lld", n); - _test_sprintf("4294967296", "%lld", n*n); - _test_sprintf("281474976710656", "%lld", n*n*n); - _test_sprintf("-281474976710656", "%lld", -n*n*n); - _test_sprintf("123 456 281474976710656 789", "%d %d %lld %d", 123, 456, n*n*n, 789); + _test_sprintf(L"0", L"%lld", z); + _test_sprintf(L"65536", L"%lld", n); + _test_sprintf(L"4294967296", L"%lld", n*n); + _test_sprintf(L"281474976710656", L"%lld", n*n*n); + _test_sprintf(L"-281474976710656", L"%lld", -n*n*n); + _test_sprintf(L"123 456 281474976710656 789", L"%d %d %lld %d", 123, 456, n*n*n, 789); } void test_pos() { - _test_sprintf("a b", "%1$c %2$c", 'a', 'b'); - _test_sprintf("b a", "%2$c %1$c", 'a', 'b'); + _test_sprintf(L"a b", L"%1$c %2$c", 'a', 'b'); + _test_sprintf(L"b a", L"%2$c %1$c", 'a', 'b'); } void test_pos_lld() { - _test_sprintf("1 2 3", "%1$d %2$lld %3$d", 1, (i64)2, 3); - _test_sprintf("2 1 3", "%2$lld %1$d %3$d", 1, (i64)2, 3); + _test_sprintf(L"1 2 3", L"%1$d %2$lld %3$d", 1, (i64)2, 3); + _test_sprintf(L"2 1 3", L"%2$lld %1$d %3$d", 1, (i64)2, 3); } }; diff --git a/source/lib/sysdep/tests/test_sysdep.h b/source/lib/sysdep/tests/test_sysdep.h index 897a9ba214..8dc0bc3776 100644 --- a/source/lib/sysdep/tests/test_sysdep.h +++ b/source/lib/sysdep/tests/test_sysdep.h @@ -18,6 +18,7 @@ #include "lib/self_test.h" #include "lib/lib.h" +#include "lib/path_util.h" #include "lib/sysdep/sysdep.h" #include "lib/posix/posix.h" // fminf etc. @@ -79,16 +80,17 @@ public: void test_sys_get_executable_name() { - char path[PATH_MAX] = ""; + fs::wpath path; // Try it first with the real executable (i.e. the // one that's running this test code) - TS_ASSERT_EQUALS(sys_get_executable_name(path, PATH_MAX), INFO::OK); + TS_ASSERT_EQUALS(sys_get_executable_name(path), INFO::OK); // Check it's absolute - TSM_ASSERT(std::string("Path: ")+path, path_is_absolute(path)); + TSM_ASSERT(std::wstring(L"Path: ")+path.string(), path_is_absolute(path.string().c_str())); // Check the file exists + fs::path path_c = path_from_wpath(path); struct stat s; - TSM_ASSERT_EQUALS(std::string("Path: ")+path, stat(path, &s), 0); + TSM_ASSERT_EQUALS(std::wstring(L"Path: ")+path.string(), stat(path_c.string().c_str(), &s), 0); // Do some platform-specific tests, based on the // implementations of sys_get_executable_name: @@ -213,7 +215,7 @@ public: #endif private: - bool path_is_absolute(const char* path) + bool path_is_absolute(const wchar_t* path) { // UNIX-style absolute paths if (path[0] == '/') @@ -224,7 +226,7 @@ private: return true; // Windows drive-letter absolute paths - if (isalpha(path[0]) && path[1] == ':' && (path[2] == '/' || path[2] == '\\')) + if (iswalpha(path[0]) && path[1] == ':' && (path[2] == '/' || path[2] == '\\')) return true; return false; diff --git a/source/lib/tests/test_lockfree.h b/source/lib/tests/test_lockfree.h index 80a3ec2f1f..042585a148 100644 --- a/source/lib/tests/test_lockfree.h +++ b/source/lib/tests/test_lockfree.h @@ -142,9 +142,9 @@ class TestMultithread : public CxxTest::TestSuite TA_ERASE = 2, TA_SLEEP = 3 }; - static const char* const action_strings[] = + static const wchar_t* const action_strings[] = { - "find", "insert", "erase", "sleep" + L"find", L"insert", L"erase", L"sleep" }; while(!this_->is_complete) @@ -154,7 +154,7 @@ class TestMultithread : public CxxTest::TestSuite const size_t action = rand(0, 4); const uintptr_t key = (uintptr_t)rand(0, 100); const size_t sleep_duration_ms = rand(0, 100); - debug_printf("thread %d: %s\n", thread_number, action_strings[action]); + debug_printf(L"thread %d: %ls\n", thread_number, action_strings[action]); // pthread_mutex_lock(&this_->mutex); diff --git a/source/lib/tests/test_path_util.h b/source/lib/tests/test_path_util.h index 49010c701d..e99a9f5be2 100644 --- a/source/lib/tests/test_path_util.h +++ b/source/lib/tests/test_path_util.h @@ -23,31 +23,31 @@ // Macros, not functions, to get proper line number reports when tests fail #define TEST_APPEND(path1, path2, flags, correct_result) \ { \ - char dst[PATH_MAX] = {0}; \ + wchar_t dst[PATH_MAX] = {0}; \ path_append(dst, path1, path2, flags); \ - TS_ASSERT_STR_EQUALS(dst, correct_result); \ + TS_ASSERT_WSTR_EQUALS(dst, correct_result); \ } #define TEST_NAME_ONLY(path, correct_result) \ { \ - const char* result = path_name_only(path); \ - TS_ASSERT_STR_EQUALS(result, correct_result); \ + const wchar_t* result = path_name_only(path); \ + TS_ASSERT_WSTR_EQUALS(result, correct_result); \ } #define TEST_STRIP_FN(path_readonly, correct_result) \ { \ - char path[PATH_MAX]; \ + wchar_t path[PATH_MAX]; \ path_copy(path, path_readonly); \ path_strip_fn(path); \ - TS_ASSERT_STR_EQUALS(path, correct_result); \ + TS_ASSERT_WSTR_EQUALS(path, correct_result); \ } class TestPathUtil : public CxxTest::TestSuite { - void TEST_PATH_EXT(const char* path, const char* correct_result) + void TEST_PATH_EXT(const wchar_t* path, const wchar_t* correct_result) { - const char* result = path_extension(path); - TS_ASSERT_STR_EQUALS(result, correct_result); + const wchar_t* result = path_extension(path); + TS_ASSERT_WSTR_EQUALS(result, correct_result); } public: @@ -55,22 +55,22 @@ public: void test_subpath() { // obvious true - TS_ASSERT(path_is_subpath("abc/def/", "abc/def/") == true); // same - TS_ASSERT(path_is_subpath("abc/def/", "abc/") == true); // 2 is subpath - TS_ASSERT(path_is_subpath("abc/", "abc/def/") == true); // 1 is subpath + TS_ASSERT(path_is_subpath(L"abc/def/", L"abc/def/") == true); // same + TS_ASSERT(path_is_subpath(L"abc/def/", L"abc/") == true); // 2 is subpath + TS_ASSERT(path_is_subpath(L"abc/", L"abc/def/") == true); // 1 is subpath // nonobvious true - TS_ASSERT(path_is_subpath("", "") == true); - TS_ASSERT(path_is_subpath("abc/def/", "abc/def") == true); // no '/' ! + TS_ASSERT(path_is_subpath(L"", L"") == true); + TS_ASSERT(path_is_subpath(L"abc/def/", L"abc/def") == true); // no '/' ! // obvious false - TS_ASSERT(path_is_subpath("abc", "def") == false); // different, no path + TS_ASSERT(path_is_subpath(L"abc", L"def") == false); // different, no path // nonobvious false - TS_ASSERT(path_is_subpath("abc", "") == false); // empty comparand + TS_ASSERT(path_is_subpath(L"abc", L"") == false); // empty comparand // .. different but followed by common subdir - TS_ASSERT(path_is_subpath("abc/def/", "ghi/def/") == false); - TS_ASSERT(path_is_subpath("abc/def/", "abc/ghi") == false); + TS_ASSERT(path_is_subpath(L"abc/def/", L"ghi/def/") == false); + TS_ASSERT(path_is_subpath(L"abc/def/", L"abc/ghi") == false); } // TODO: can't test path validate yet without suppress-error-dialog @@ -78,66 +78,66 @@ public: void test_append() { // simplest case - TEST_APPEND("abc", "def", 0, "abc/def"); + TEST_APPEND(L"abc", L"def", 0, L"abc/def"); // trailing slash - TEST_APPEND("abc", "def", PATH_APPEND_SLASH, "abc/def/"); + TEST_APPEND(L"abc", L"def", PATH_APPEND_SLASH, L"abc/def/"); // intervening slash - TEST_APPEND("abc/", "def", 0, "abc/def"); + TEST_APPEND(L"abc/", L"def", 0, L"abc/def"); // nonportable intervening slash - TEST_APPEND("abc\\", "def", 0, "abc\\def"); + TEST_APPEND(L"abc\\", L"def", 0, L"abc\\def"); // mixed path slashes - TEST_APPEND("abc", "def/ghi\\jkl", 0, "abc/def/ghi\\jkl"); + TEST_APPEND(L"abc", L"def/ghi\\jkl", 0, L"abc/def/ghi\\jkl"); // path1 empty - TEST_APPEND("", "abc/def/", 0, "abc/def/"); + TEST_APPEND(L"", L"abc/def/", 0, L"abc/def/"); // path2 empty, no trailing slash - TEST_APPEND("abc/def", "", 0, "abc/def"); + TEST_APPEND(L"abc/def", L"", 0, L"abc/def"); // path2 empty, require trailing slash - TEST_APPEND("abc/def", "", PATH_APPEND_SLASH, "abc/def/"); + TEST_APPEND(L"abc/def", L"", PATH_APPEND_SLASH, L"abc/def/"); // require trailing slash, already exists - TEST_APPEND("abc/", "def/", PATH_APPEND_SLASH, "abc/def/"); + TEST_APPEND(L"abc/", L"def/", PATH_APPEND_SLASH, L"abc/def/"); } void test_name_only() { // path with filename - TEST_NAME_ONLY("abc/def", "def"); + TEST_NAME_ONLY(L"abc/def", L"def"); // nonportable path with filename - TEST_NAME_ONLY("abc\\def\\ghi", "ghi"); + TEST_NAME_ONLY(L"abc\\def\\ghi", L"ghi"); // mixed path with filename - TEST_NAME_ONLY("abc/def\\ghi", "ghi"); + TEST_NAME_ONLY(L"abc/def\\ghi", L"ghi"); // mixed path with filename (2) - TEST_NAME_ONLY("abc\\def/ghi", "ghi"); + TEST_NAME_ONLY(L"abc\\def/ghi", L"ghi"); // filename only - TEST_NAME_ONLY("abc", "abc"); + TEST_NAME_ONLY(L"abc", L"abc"); // empty - TEST_NAME_ONLY("", ""); + TEST_NAME_ONLY(L"", L""); } void test_strip_fn() { // path with filename - TEST_STRIP_FN("abc/def", "abc/"); + TEST_STRIP_FN(L"abc/def", L"abc/"); // nonportable path with filename - TEST_STRIP_FN("abc\\def\\ghi", "abc\\def\\"); + TEST_STRIP_FN(L"abc\\def\\ghi", L"abc\\def\\"); // mixed path with filename - TEST_STRIP_FN("abc/def\\ghi", "abc/def\\"); + TEST_STRIP_FN(L"abc/def\\ghi", L"abc/def\\"); // mixed path with filename (2) - TEST_STRIP_FN("abc\\def/ghi", "abc\\def/"); + TEST_STRIP_FN(L"abc\\def/ghi", L"abc\\def/"); // filename only - TEST_STRIP_FN("abc", ""); + TEST_STRIP_FN(L"abc", L""); // empty - TEST_STRIP_FN("", ""); + TEST_STRIP_FN(L"", L""); // path - TEST_STRIP_FN("abc/def/", "abc/def/"); + TEST_STRIP_FN(L"abc/def/", L"abc/def/"); // nonportable path - TEST_STRIP_FN("abc\\def\\ghi\\", "abc\\def\\ghi\\"); + TEST_STRIP_FN(L"abc\\def\\ghi\\", L"abc\\def\\ghi\\"); } void test_path_ext() { - TEST_PATH_EXT("a/b/c.bmp", "bmp"); - TEST_PATH_EXT("a.BmP", "BmP"); // case sensitive - TEST_PATH_EXT("c", ""); // no extension - TEST_PATH_EXT("", ""); // empty + TEST_PATH_EXT(L"a/b/c.bmp", L"bmp"); + TEST_PATH_EXT(L"a.BmP", L"BmP"); // case sensitive + TEST_PATH_EXT(L"c", L""); // no extension + TEST_PATH_EXT(L"", L""); // empty } }; diff --git a/source/lib/tests/test_regex.h b/source/lib/tests/test_regex.h index aee5f786dc..9d5fb339c2 100644 --- a/source/lib/tests/test_regex.h +++ b/source/lib/tests/test_regex.h @@ -24,44 +24,23 @@ class TestRegex : public CxxTest::TestSuite public: void test_regex() { - TS_ASSERT_EQUALS(match_wildcard("", ""), 1); - TS_ASSERT_EQUALS(match_wildcard("a", 0), 1); // NULL matches everything + TS_ASSERT_EQUALS(match_wildcard(L"", L""), 1); + TS_ASSERT_EQUALS(match_wildcard(L"a", 0), 1); // NULL matches everything - TS_ASSERT_EQUALS(match_wildcard("abc", "abc") , 1); // direct match - TS_ASSERT_EQUALS(match_wildcard("abc", "???") , 1); // only ? - TS_ASSERT_EQUALS(match_wildcard("abc", "*" ) , 1); // only * + TS_ASSERT_EQUALS(match_wildcard(L"abc", L"abc") , 1); // direct match + TS_ASSERT_EQUALS(match_wildcard(L"abc", L"???") , 1); // only ? + TS_ASSERT_EQUALS(match_wildcard(L"abc", L"*" ) , 1); // only * - TS_ASSERT_EQUALS(match_wildcard("ab" , "a?" ) , 1); // trailing ? - TS_ASSERT_EQUALS(match_wildcard("abc", "a?c") , 1); // middle ? - TS_ASSERT_EQUALS(match_wildcard("abc", "?bc") , 1); // leading ? + TS_ASSERT_EQUALS(match_wildcard(L"ab" , L"a?" ) , 1); // trailing ? + TS_ASSERT_EQUALS(match_wildcard(L"abc", L"a?c") , 1); // middle ? + TS_ASSERT_EQUALS(match_wildcard(L"abc", L"?bc") , 1); // leading ? - TS_ASSERT_EQUALS(match_wildcard("abc", "a*" ) , 1); // trailing * - TS_ASSERT_EQUALS(match_wildcard("abcdef", "ab*ef"), 1); // middle * - TS_ASSERT_EQUALS(match_wildcard("abcdef", "*f" ), 1); // leading * + TS_ASSERT_EQUALS(match_wildcard(L"abc", L"a*" ) , 1); // trailing * + TS_ASSERT_EQUALS(match_wildcard(L"abcdef", L"ab*ef"), 1); // middle * + TS_ASSERT_EQUALS(match_wildcard(L"abcdef", L"*f" ), 1); // leading * - TS_ASSERT_EQUALS(match_wildcard("abcdef", "a?cd*"), 1); // ? and * - TS_ASSERT_EQUALS(match_wildcard("abcdef", "a*d?f"), 1); // * and ? - TS_ASSERT_EQUALS(match_wildcard("abcdef", "a*d*" ), 1); // multiple * - - // unicode test pasted from the above; keep in sync! - - TS_ASSERT_EQUALS(match_wildcardw(L"", L""), 1); - TS_ASSERT_EQUALS(match_wildcardw(L"a", 0), 1); // NULL matches everything - - TS_ASSERT_EQUALS(match_wildcardw(L"abc", L"abc") , 1); // direct match - TS_ASSERT_EQUALS(match_wildcardw(L"abc", L"???") , 1); // only ? - TS_ASSERT_EQUALS(match_wildcardw(L"abc", L"*" ) , 1); // only * - - TS_ASSERT_EQUALS(match_wildcardw(L"ab" , L"a?" ) , 1); // trailing ? - TS_ASSERT_EQUALS(match_wildcardw(L"abc", L"a?c") , 1); // middle ? - TS_ASSERT_EQUALS(match_wildcardw(L"abc", L"?bc") , 1); // leading ? - - TS_ASSERT_EQUALS(match_wildcardw(L"abc", L"a*" ) , 1); // trailing * - TS_ASSERT_EQUALS(match_wildcardw(L"abcdef", L"ab*ef"), 1); // middle * - TS_ASSERT_EQUALS(match_wildcardw(L"abcdef", L"*f" ), 1); // leading * - - TS_ASSERT_EQUALS(match_wildcardw(L"abcdef", L"a?cd*"), 1); // ? and * - TS_ASSERT_EQUALS(match_wildcardw(L"abcdef", L"a*d?f"), 1); // * and ? - TS_ASSERT_EQUALS(match_wildcardw(L"abcdef", L"a*d*" ), 1); // multiple * + TS_ASSERT_EQUALS(match_wildcard(L"abcdef", L"a?cd*"), 1); // ? and * + TS_ASSERT_EQUALS(match_wildcard(L"abcdef", L"a*d?f"), 1); // * and ? + TS_ASSERT_EQUALS(match_wildcard(L"abcdef", L"a*d*" ), 1); // multiple * } }; diff --git a/source/lib/tex/tex.cpp b/source/lib/tex/tex.cpp index 065398e571..081ecee938 100644 --- a/source/lib/tex/tex.cpp +++ b/source/lib/tex/tex.cpp @@ -33,14 +33,14 @@ #include "tex_codec.h" -ERROR_ASSOCIATE(ERR::TEX_FMT_INVALID, "Invalid/unsupported texture format", -1); -ERROR_ASSOCIATE(ERR::TEX_INVALID_COLOR_TYPE, "Invalid color type", -1); -ERROR_ASSOCIATE(ERR::TEX_NOT_8BIT_PRECISION, "Not 8-bit channel precision", -1); -ERROR_ASSOCIATE(ERR::TEX_INVALID_LAYOUT, "Unsupported texel layout, e.g. right-to-left", -1); -ERROR_ASSOCIATE(ERR::TEX_COMPRESSED, "Unsupported texture compression", -1); -ERROR_ASSOCIATE(WARN::TEX_INVALID_DATA, "Warning: invalid texel data encountered", -1); -ERROR_ASSOCIATE(ERR::TEX_INVALID_SIZE, "Texture size is incorrect", -1); -ERROR_ASSOCIATE(INFO::TEX_CODEC_CANNOT_HANDLE, "Texture codec cannot handle the given format", -1); +ERROR_ASSOCIATE(ERR::TEX_FMT_INVALID, L"Invalid/unsupported texture format", -1); +ERROR_ASSOCIATE(ERR::TEX_INVALID_COLOR_TYPE, L"Invalid color type", -1); +ERROR_ASSOCIATE(ERR::TEX_NOT_8BIT_PRECISION, L"Not 8-bit channel precision", -1); +ERROR_ASSOCIATE(ERR::TEX_INVALID_LAYOUT, L"Unsupported texel layout, e.g. right-to-left", -1); +ERROR_ASSOCIATE(ERR::TEX_COMPRESSED, L"Unsupported texture compression", -1); +ERROR_ASSOCIATE(WARN::TEX_INVALID_DATA, L"Warning: invalid texel data encountered", -1); +ERROR_ASSOCIATE(ERR::TEX_INVALID_SIZE, L"Texture size is incorrect", -1); +ERROR_ASSOCIATE(INFO::TEX_CODEC_CANNOT_HANDLE, L"Texture codec cannot handle the given format", -1); //----------------------------------------------------------------------------- @@ -484,11 +484,11 @@ bool tex_orientations_match(size_t src_flags, size_t dst_orientation) // enumerating only images in a file picker. // an alternative might be a flag to suppress warning about invalid files, // but this is open to misuse. -bool tex_is_known_extension(const char* filename) +bool tex_is_known_extension(const VfsPath& pathname) { const TexCodecVTbl* dummy; // found codec for it => known extension - const std::string extension = fs::extension(filename); + const std::wstring extension = fs::extension(pathname); if(tex_codec_for_filename(extension, &dummy) == INFO::OK) return true; @@ -588,7 +588,7 @@ size_t tex_hdr_size(const VfsPath& filename) { const TexCodecVTbl* c; - const std::string extension = fs::extension(filename); + const std::wstring extension = fs::extension(filename); CHECK_ERR(tex_codec_for_filename(extension, &c)); return c->hdr_size(0); } @@ -640,7 +640,7 @@ LibError tex_decode(const shared_ptr& data, size_t data_size, Tex* t) } -LibError tex_encode(Tex* t, const std::string& extension, DynArray* da) +LibError tex_encode(Tex* t, const std::wstring& extension, DynArray* da) { CHECK_TEX(t); CHECK_ERR(tex_validate_plain_format(t->bpp, t->flags)); diff --git a/source/lib/tex/tex.h b/source/lib/tex/tex.h index cb3489712b..456c9df06f 100644 --- a/source/lib/tex/tex.h +++ b/source/lib/tex/tex.h @@ -277,7 +277,7 @@ extern LibError tex_decode(const shared_ptr& data, size_t data_size, Tex* t) * when no longer needed. invalid unless function succeeds. * @return LibError **/ -extern LibError tex_encode(Tex* t, const std::string& extension, DynArray* da); +extern LibError tex_encode(Tex* t, const std::wstring& extension, DynArray* da); /** * store the given image data into a Tex object; this will be as if @@ -419,10 +419,10 @@ extern void tex_util_foreach_mipmap(size_t w, size_t h, size_t bpp, const u8* da * an alternative might be a flag to suppress warning about invalid files, * but this is open to misuse. * - * @param filename only the extension (that after '.') is used. case-insensitive. + * @param pathname only the extension (starting with '.') is used. case-insensitive. * @return bool **/ -extern bool tex_is_known_extension(const char* filename); +extern bool tex_is_known_extension(const VfsPath& pathname); /** * return the minimum header size (i.e. offset to pixel data) of the diff --git a/source/lib/tex/tex_bmp.cpp b/source/lib/tex/tex_bmp.cpp index b4ed17008f..72b969109d 100644 --- a/source/lib/tex/tex_bmp.cpp +++ b/source/lib/tex/tex_bmp.cpp @@ -69,9 +69,9 @@ static bool bmp_is_hdr(const u8* file) } -static bool bmp_is_ext(const std::string& extension) +static bool bmp_is_ext(const std::wstring& extension) { - return !strcasecmp(extension.c_str(), ".bmp"); + return !wcscasecmp(extension.c_str(), L".bmp"); } diff --git a/source/lib/tex/tex_codec.cpp b/source/lib/tex/tex_codec.cpp index eb437c3fdc..0ccaaa5c6c 100644 --- a/source/lib/tex/tex_codec.cpp +++ b/source/lib/tex/tex_codec.cpp @@ -53,7 +53,7 @@ int tex_codec_register(TexCodecVTbl* c) // or return ERR::TEX_UNKNOWN_FORMAT if unknown. // note: does not raise a warning because it is used by // tex_is_known_extension. -LibError tex_codec_for_filename(const std::string& extension, const TexCodecVTbl** c) +LibError tex_codec_for_filename(const std::wstring& extension, const TexCodecVTbl** c) { for(*c = codecs; *c; *c = (*c)->next) { diff --git a/source/lib/tex/tex_codec.h b/source/lib/tex/tex_codec.h index d176632a93..649e18d4ca 100644 --- a/source/lib/tex/tex_codec.h +++ b/source/lib/tex/tex_codec.h @@ -91,7 +91,7 @@ struct TexCodecVTbl * @param extension (including '.') * @return bool **/ - bool (*is_ext)(const std::string& extension); + bool (*is_ext)(const std::wstring& extension); /** * return size of the file header supported by this codec. @@ -107,7 +107,7 @@ struct TexCodecVTbl /** * name of codec for debug purposes. typically set via TEX_CODEC_REGISTER. **/ - const char* name; + const wchar_t* name; /** * intrusive linked-list of codecs: more convenient than fixed-size @@ -135,7 +135,7 @@ struct TexCodecVTbl {\ name##_decode, name##_encode, name##_transform,\ name##_is_hdr, name##_is_ext, name##_hdr_size,\ - #name\ + WIDEN(#name)\ };\ /*static int dummy = tex_codec_register(&vtbl);*/\ /* note: when building as a static library, pre-main initializers */\ @@ -164,7 +164,7 @@ extern int tex_codec_register(TexCodecVTbl* c); * called by tex_is_known_extension) if no codec indicates they can * handle the given extension. **/ -extern LibError tex_codec_for_filename(const std::string& extension, const TexCodecVTbl** c); +extern LibError tex_codec_for_filename(const std::wstring& extension, const TexCodecVTbl** c); /** * find codec that recognizes the header's magic field. diff --git a/source/lib/tex/tex_dds.cpp b/source/lib/tex/tex_dds.cpp index a19b3c96f3..67a907b20f 100644 --- a/source/lib/tex/tex_dds.cpp +++ b/source/lib/tex/tex_dds.cpp @@ -597,9 +597,9 @@ static bool dds_is_hdr(const u8* file) } -static bool dds_is_ext(const std::string& extension) +static bool dds_is_ext(const std::wstring& extension) { - return !strcasecmp(extension.c_str(), ".dds"); + return !wcscasecmp(extension.c_str(), L".dds"); } diff --git a/source/lib/tex/tex_jpg.cpp b/source/lib/tex/tex_jpg.cpp index 8126ff5bb6..ffe531f64d 100644 --- a/source/lib/tex/tex_jpg.cpp +++ b/source/lib/tex/tex_jpg.cpp @@ -568,9 +568,9 @@ static bool jpg_is_hdr(const u8* file) } -static bool jpg_is_ext(const std::string& extension) +static bool jpg_is_ext(const std::wstring& extension) { - return !strcasecmp(extension.c_str(), ".jpg") || !strcasecmp(extension.c_str(), ".jpeg"); + return !wcscasecmp(extension.c_str(), L".jpg") || !wcscasecmp(extension.c_str(), L".jpeg"); } diff --git a/source/lib/tex/tex_png.cpp b/source/lib/tex/tex_png.cpp index 1243675ee4..6803dfda63 100644 --- a/source/lib/tex/tex_png.cpp +++ b/source/lib/tex/tex_png.cpp @@ -178,9 +178,9 @@ static bool png_is_hdr(const u8* file) } -static bool png_is_ext(const std::string& extension) +static bool png_is_ext(const std::wstring& extension) { - return !strcasecmp(extension.c_str(), ".png"); + return !wcscasecmp(extension.c_str(), L".png"); } diff --git a/source/lib/tex/tex_tga.cpp b/source/lib/tex/tex_tga.cpp index 9f68a9e652..2b965ce36c 100644 --- a/source/lib/tex/tex_tga.cpp +++ b/source/lib/tex/tex_tga.cpp @@ -88,9 +88,9 @@ static bool tga_is_hdr(const u8* file) } -static bool tga_is_ext(const std::string& extension) +static bool tga_is_ext(const std::wstring& extension) { - return !strcasecmp(extension.c_str(), ".tga"); + return !wcscasecmp(extension.c_str(), L".tga"); } diff --git a/source/lib/timer.cpp b/source/lib/timer.cpp index 86ed940a66..fb88276a3e 100644 --- a/source/lib/timer.cpp +++ b/source/lib/timer.cpp @@ -143,7 +143,7 @@ static size_t num_clients; static TimerClient* clients; -TimerClient* timer_AddClient(TimerClient* tc, const char* description) +TimerClient* timer_AddClient(TimerClient* tc, const wchar_t* description) { tc->sum.SetToZero(); @@ -167,8 +167,8 @@ void timer_BillClient(TimerClient* tc, TimerUnit t0, TimerUnit t1) void timer_DisplayClientTotals() { - debug_printf("TIMER TOTALS (%lu clients)\n", (unsigned long)num_clients); - debug_printf("-----------------------------------------------------\n"); + debug_printf(L"TIMER TOTALS (%lu clients)\n", (unsigned long)num_clients); + debug_printf(L"-----------------------------------------------------\n"); while(clients) { @@ -178,9 +178,9 @@ void timer_DisplayClientTotals() clients = tc->next; num_clients--; - const std::string duration = tc->sum.ToString(); - debug_printf(" %s: %s (%lux)\n", tc->description, duration.c_str(), (unsigned long)tc->num_calls); + const std::wstring duration = tc->sum.ToString(); + debug_printf(L" %ls: %ls (%lux)\n", tc->description, duration.c_str(), (unsigned long)tc->num_calls); } - debug_printf("-----------------------------------------------------\n"); + debug_printf(L"-----------------------------------------------------\n"); } diff --git a/source/lib/timer.h b/source/lib/timer.h index b463b27607..84344cae66 100644 --- a/source/lib/timer.h +++ b/source/lib/timer.h @@ -38,12 +38,12 @@ LIB_API void timer_LatchStartTime(); /** * @return high resolution (> 1 us) timestamp [s]. **/ -LIB_API double timer_Time(void); +LIB_API double timer_Time(); /** * @return resolution [s] of the timer. **/ -LIB_API double timer_Resolution(void); +LIB_API double timer_Resolution(); //----------------------------------------------------------------------------- @@ -54,7 +54,7 @@ class ScopeTimer { NONCOPYABLE(ScopeTimer); public: - ScopeTimer(const char* description) + ScopeTimer(const wchar_t* description) : m_t0(timer_Time()), m_description(description) { } @@ -66,18 +66,18 @@ public: // determine scale factor for pretty display double scale = 1e6; - const char* unit = "us"; + const wchar_t* unit = L"us"; if(dt > 1.0) - scale = 1, unit = "s"; + scale = 1, unit = L"s"; else if(dt > 1e-3) - scale = 1e3, unit = "ms"; + scale = 1e3, unit = L"ms"; - debug_printf("TIMER| %s: %g %s\n", m_description, dt*scale, unit); + debug_printf(L"TIMER| %ls: %g %ls\n", m_description, dt*scale, unit); } private: double m_t0; - const char* m_description; + const wchar_t* m_description; }; /** @@ -90,7 +90,7 @@ private: * Example usage: * void func() * { - * TIMER("description"); + * TIMER(L"description"); * // code to be measured * } **/ @@ -113,9 +113,9 @@ private: * void func2() * { * // uninteresting code - * TIMER_BEGIN("description2"); + * TIMER_BEGIN(L"description2"); * // code to be measured - * TIMER_END("description2"); + * TIMER_END(L"description2"); * // uninteresting code * } **/ @@ -172,21 +172,21 @@ public: m_ticks -= t.m_ticks; } - std::string ToString() const + std::wstring ToString() const { debug_assert(m_ticks >= 0.0); // determine scale factor for pretty display double scale = 1.0; - const char* unit = " c"; + const wchar_t* unit = L" c"; if(m_ticks > 10000000000LL) // 10 Gc - scale = 1e-9, unit = " Gc"; + scale = 1e-9, unit = L" Gc"; else if(m_ticks > 10000000) // 10 Mc - scale = 1e-6, unit = " Mc"; + scale = 1e-6, unit = L" Mc"; else if(m_ticks > 10000) // 10 kc - scale = 1e-3, unit = " kc"; + scale = 1e-3, unit = L" kc"; - std::stringstream ss; + std::wstringstream ss; ss << m_ticks*scale; ss << unit; return ss.str(); @@ -226,19 +226,19 @@ public: m_seconds -= t.m_seconds; } - std::string ToString() const + std::wstring ToString() const { debug_assert(m_seconds >= 0.0); // determine scale factor for pretty display double scale = 1e6; - const char* unit = " us"; + const wchar_t* unit = L" us"; if(m_seconds > 1.0) - scale = 1, unit = " s"; + scale = 1, unit = L" s"; else if(m_seconds > 1e-3) - scale = 1e3, unit = " ms"; + scale = 1e3, unit = L" ms"; - std::stringstream ss; + std::wstringstream ss; ss << m_seconds*scale; ss << unit; return ss.str(); @@ -263,7 +263,7 @@ struct TimerClient TimerUnit sum; // total bill // only store a pointer for efficiency. - const char* description; + const wchar_t* description; TimerClient* next; @@ -283,7 +283,7 @@ struct TimerClient * - free() is not needed nor possible. * - description must remain valid until exit; a string literal is safest. **/ -LIB_API TimerClient* timer_AddClient(TimerClient* tc, const char* description); +LIB_API TimerClient* timer_AddClient(TimerClient* tc, const wchar_t* description); /** * "allocate" a new TimerClient that will keep track of the total time @@ -294,7 +294,7 @@ LIB_API TimerClient* timer_AddClient(TimerClient* tc, const char* description); **/ #define TIMER_ADD_CLIENT(id)\ static TimerClient UID__;\ - static TimerClient* id = timer_AddClient(&UID__, #id); + static TimerClient* id = timer_AddClient(&UID__, WIDEN(#id)); /** * bill the difference between t0 and t1 to the client's total. diff --git a/source/main.cpp b/source/main.cpp index 5865a2920c..a2a431e592 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -59,7 +59,7 @@ that of Atlas depending on commandline parameters. #include "sound/SoundGroupMgr.h" #include "gui/GUI.h" -#define LOG_CATEGORY "main" +#define LOG_CATEGORY L"main" extern bool g_TerrainModified; extern bool g_GameRestarted; @@ -84,11 +84,11 @@ static InReaction MainInputHandler(const SDL_Event_* ev) return IN_HANDLED; case HOTKEY_SCREENSHOT: - WriteScreenshot(".png"); + WriteScreenshot(L".png"); return IN_HANDLED; case HOTKEY_BIGSCREENSHOT: - WriteBigScreenshot(".bmp", 10); + WriteBigScreenshot(L".bmp", 10); return IN_HANDLED; default: @@ -295,7 +295,7 @@ static void Frame() // coincide in position and orientation. float down[3] = { -up[0], -up[1], -up[2] }; if(snd_update(pos, dir, down) < 0) - debug_printf("snd_update failed\n"); + debug_printf(L"snd_update failed\n"); g_soundGroupMgr->UpdateSoundGroups(TimeSinceLastFrame); PROFILE_END( "sound update" ); } @@ -306,7 +306,7 @@ static void Frame() int ms_elapsed = (int)(TimeSinceLastFrame*1000); g_Scheduler.Update(ms_elapsed); if(snd_update(0, 0, 0) < 0) - debug_printf("snd_update (pos=0 version) failed\n"); + debug_printf(L"snd_update (pos=0 version) failed\n"); } PROFILE_END( "game logic" ); diff --git a/source/network/NetClient.cpp b/source/network/NetClient.cpp index 2060f19ed1..6f519c6c54 100644 --- a/source/network/NetClient.cpp +++ b/source/network/NetClient.cpp @@ -42,7 +42,7 @@ // DECLARATIONS -#define LOG_CAT_NET "net" +#define LOG_CATEGORY L"net" CNetClient *g_NetClient=NULL; extern int fps; @@ -258,7 +258,7 @@ bool CNetClient::OnError( void* pContext, CFsmEvent* pEvent ) CErrorMessage* pMessage = ( CErrorMessage* )pEvent->GetParamRef(); if ( pMessage ) { - LOG( CLogger::Error, LOG_CAT_NET, "CNetClient::OnError(): Error description %s", pMessage->m_Error ); + LOG( CLogger::Error, LOG_CATEGORY, L"CNetClient::OnError(): Error description %s", pMessage->m_Error ); if ( pClient->m_OnConnectComplete.Defined() ) { @@ -373,11 +373,11 @@ bool CNetClient::OnAuthenticate( void* pContext, CFsmEvent* pEvent ) CAuthenticateResultMessage* pMessage =( CAuthenticateResultMessage* )pEvent->GetParamRef(); if ( !pMessage ) return true; - LOG(CLogger::Error, LOG_CAT_NET, "CNetClient::OnAuthenticate(): Authentication result: %ls", pMessage->m_Message.c_str() ); + LOG(CLogger::Error, LOG_CATEGORY, L"CNetClient::OnAuthenticate(): Authentication result: %ls", pMessage->m_Message.c_str() ); pSession->SetID( pMessage->m_SessionID ); - LOG(CLogger::Error, LOG_CAT_NET, "CNetClient::OnAuthenticate(): My session ID is %d", pMessage->m_SessionID); + LOG(CLogger::Error, LOG_CATEGORY, L"CNetClient::OnAuthenticate(): My session ID is %d", pMessage->m_SessionID); } return true; @@ -461,7 +461,7 @@ bool CNetClient::OnPreGame( void* pContext, CFsmEvent* pEvent ) break; default: - LOG( CLogger::Warning, LOG_CAT_NET, "Invalid slot assignment %s", pMessage->ToString().c_str() ); + LOG( CLogger::Warning, LOG_CATEGORY, L"Invalid slot assignment %s", pMessage->ToString().c_str() ); break; } } @@ -609,7 +609,7 @@ void CNetClient::OnPlayerLeave( uint ID ) PlayerMap::iterator it = m_Players.find( ID ); if ( it == m_Players.end() ) { - LOG( CLogger::Warning, LOG_CAT_NET, "CNetClient::OnPlayerLeav(): No such player %d.", ID ); + LOG( CLogger::Warning, LOG_CATEGORY, L"CNetClient::OnPlayerLeav(): No such player %d.", ID ); return; } @@ -666,7 +666,7 @@ void CNetClient::NewTurn() ClearBatch(2); m_TurnPending = false; - //debug_printf("In NewTurn - sending ack\n"); + //debug_printf(L"In NewTurn - sending ack\n"); CEndCommandBatchMessage* pMsg = new CEndCommandBatchMessage; pMsg->m_TurnLength=1000/g_frequencyFilter->StableFrequency(); // JW: it'd probably be nicer to get the FPS as a parameter diff --git a/source/network/NetLog.cpp b/source/network/NetLog.cpp index 9f83eff994..cc898f07b3 100644 --- a/source/network/NetLog.cpp +++ b/source/network/NetLog.cpp @@ -258,8 +258,8 @@ CNetLogFileSink::CNetLogFileSink( void ) CNetLogger::GetStringTime( time ); // Make relative path - fs::path path(fs::path(psLogDir())/"net_log"); - path /= time+".txt"; + fs::wpath path(psLogDir()/L"net_log"); + path /= CStrW(time)+L".txt"; m_FileName = path.external_file_string(); m_Append = true; } @@ -268,7 +268,7 @@ CNetLogFileSink::CNetLogFileSink( void ) // Name: CNetLogFileSink() // Desc: Constructor //----------------------------------------------------------------------------- -CNetLogFileSink::CNetLogFileSink( const CStr& filename ) +CNetLogFileSink::CNetLogFileSink( const fs::wpath& filename ) { m_FileName = filename; m_Append = true; @@ -278,7 +278,7 @@ CNetLogFileSink::CNetLogFileSink( const CStr& filename ) // Name: CNetLogFileSink() // Desc: Constructor //----------------------------------------------------------------------------- -CNetLogFileSink::CNetLogFileSink( const CStr& filename, bool append ) +CNetLogFileSink::CNetLogFileSink( const fs::wpath& filename, bool append ) { m_FileName = filename; m_Append = append; @@ -368,13 +368,13 @@ void CNetLogFileSink::Write( char c ) // Name: OpenFile() // Desc: Open the file where the logging will output //----------------------------------------------------------------------------- -void CNetLogFileSink::OpenFile( const CStr& fileName, bool append ) +void CNetLogFileSink::OpenFile( const fs::wpath& fileName, bool append ) { // Close any open file if ( m_File.is_open() ) m_File.close(); // Open the file and log start - m_File.open( fileName.c_str(), append ? std::ios::app : std::ios::out ); + m_File.open( fileName.string().c_str(), append ? std::ios::app : std::ios::out ); if ( !m_File.is_open() ) { // throw std::ios_base::failure @@ -931,6 +931,8 @@ void CNetLogger::RemoveAllSinks( void ) { CScopeLock lock( m_Mutex ); + for ( size_t i = 0; i < GetSinkCount(); i++ ) + delete m_Sinks[i]; m_Sinks.clear(); } diff --git a/source/network/NetLog.h b/source/network/NetLog.h index 63d6df48b6..d2e957e3ee 100644 --- a/source/network/NetLog.h +++ b/source/network/NetLog.h @@ -290,8 +290,8 @@ class CNetLogFileSink : public CNetLogSink public: CNetLogFileSink( void ); - CNetLogFileSink( const CStr& filename ); - CNetLogFileSink( const CStr& filename, bool append ); + CNetLogFileSink( const fs::wpath& filename ); + CNetLogFileSink( const fs::wpath& filename, bool append ); ~CNetLogFileSink( void ); protected: @@ -342,7 +342,7 @@ private: * @param append Indicates whether logging should append to * the file or truncate the file */ - void OpenFile( const CStr& fileName, bool append ); + void OpenFile( const fs::wpath& fileName, bool append ); /** * Close the previously opened file. The footer text will be written each time @@ -352,7 +352,7 @@ private: void CloseFile( void ); std::ofstream m_File; // The log file handle - CStr m_FileName; // The name of the log file + fs::wpath m_FileName; // The name of the log file bool m_Append; // Logging should append to file }; diff --git a/source/network/NetMessage.cpp b/source/network/NetMessage.cpp index efe662b06f..1c87b444de 100644 --- a/source/network/NetMessage.cpp +++ b/source/network/NetMessage.cpp @@ -36,6 +36,7 @@ #include // DEFINES +#define LOG_CATEGORY L"net" // Please don't modify the deserializer map outside the ONCE-block in DeserializeMessage //typedef std::map< NetMessageType, NetMessageDeserializer > MessageDeserializerMap; @@ -135,7 +136,7 @@ const u8* CNetMessage::Deserialize( const u8* pStart, const u8* pEnd ) MessageDeserializerMap::const_iterator it = g_DeserializerMap.find( type ); if ( it == g_DeserializerMap.end() ) { - LOG(WARNING, LOG_CAT_NET, "Unknown message received on socket: type 0x%04x, length %u", type, length); + LOG(WARNING, LOG_CATEGORY, L"Unknown message received on socket: type 0x%04x, length %u", type, length); return NULL; } @@ -1051,7 +1052,7 @@ CNetMessage* CNetMessageFactory::CreateMessage(const void* pData, break; default: - LOG(CLogger::Error, LOG_CAT_NET, "CNetMessageFactory::CreateMessage(): Unknown message received" ); + LOG(CLogger::Error, LOG_CATEGORY, L"CNetMessageFactory::CreateMessage(): Unknown message received" ); break; } diff --git a/source/network/NetServer.cpp b/source/network/NetServer.cpp index 75e1cdacab..bbfd6ef55c 100644 --- a/source/network/NetServer.cpp +++ b/source/network/NetServer.cpp @@ -32,8 +32,9 @@ #include "NetSession.h" #include "NetServer.h" -// DECLARATIONS +#define LOG_CATEGORY L"net" +// DECLARATIONS CNetServer* g_NetServer = NULL; //----------------------------------------------------------------------------- @@ -120,7 +121,7 @@ bool CNetServer::Start( JSContext* UNUSED(pContext), uintN UNUSED(argc), jsval* // Create new session if ( !Create( m_Port, MAX_CLIENTS ) ) { - LOG( CLogger::Error, LOG_CAT_NET, "CNetServer::Run(): Initialize failed" ); + LOG( CLogger::Error, LOG_CATEGORY, L"CNetServer::Run(): Initialize failed" ); return false; } @@ -412,7 +413,7 @@ bool CNetServer::OnError( void* pContext, CFsmEvent* pEvent ) else { // Weird stuff... - LOG( CLogger::Warning, LOG_CAT_NET, "NMT_ERROR: %s", pMessage->ToString().c_str() ); + LOG( CLogger::Warning, LOG_CATEGORY, L"NMT_ERROR: %s", pMessage->ToString().c_str() ); } } @@ -481,7 +482,7 @@ bool CNetServer::OnAuthenticate( void* pContext, CFsmEvent* pEvent ) { if ( pMessage->m_Password == pServer->m_PlayerPassword ) { - LOG( CLogger::Normal, LOG_CAT_NET, "Player authentication successful"); + LOG( CLogger::Normal, LOG_CATEGORY, L"Player authentication successful"); pSession->SetName( pMessage->m_Name ); pSession->SetID( pServer->GetFreeSessionID() ); @@ -511,7 +512,7 @@ bool CNetServer::OnAuthenticate( void* pContext, CFsmEvent* pEvent ) } else { - LOG( CLogger::Warning, LOG_CAT_NET, "Player authentication failed" ); + LOG( CLogger::Warning, LOG_CATEGORY, L"Player authentication failed" ); CAuthenticateResultMessage authenticateResult; authenticateResult.m_Code = ARC_PASSWORD_INVALID; @@ -1021,7 +1022,7 @@ void CNetServer::QueueIncomingCommand( CNetMessage* pMessage ) // Validate parameters if ( !pMessage ) return; - //LOG( NORMAL, LOG_CAT_NET, "CNetServer::QueueIncomingCommand(): %s.", pMessage->ToString().c_str() ); + //LOG( NORMAL, LOG_CATEGORY, L"CNetServer::QueueIncomingCommand(): %s.", pMessage->ToString().c_str() ); QueueMessage( 2, pMessage ); } diff --git a/source/network/NetSession.cpp b/source/network/NetSession.cpp index 9b21093d53..3450a29a53 100644 --- a/source/network/NetSession.cpp +++ b/source/network/NetSession.cpp @@ -866,7 +866,7 @@ bool CNetServerSession::BaseHandler( else { // Not disconnected? Weired... - LOG( WARNING, LOG_CAT_NET, "CNetServerSession::BaseHandler() NMT_ERROR: %s", pErrMessage->ToString().c_str() ); + LOG( WARNING, LOG_CATEGORY, L"CNetServerSession::BaseHandler() NMT_ERROR: %s", pErrMessage->ToString().c_str() ); } delete pMessage; @@ -892,7 +892,7 @@ bool CNetServerSession::HandshakeHandler( CNetServerSession* pSrvSession = dynamic_cast< CNetServerSession* >( pSession ); if ( !pSrvSession ) return false; - LOG( NORMAL, LOG_CAT_NET, "CNetServerSession::HandshakeHandler() %s", pMessage->ToString().c_str() ); + LOG( NORMAL, LOG_CATEGORY, L"CNetServerSession::HandshakeHandler() %s", pMessage->ToString().c_str() ); // Call base handler if other message thant NMT_ClientHandshake if ( pMessage->GetType() != NMT_ClientHandshake ) BaseHandler( pMessage, pSession ); diff --git a/source/network/Network.cpp b/source/network/Network.cpp index fcbd23a27f..ac19188e55 100644 --- a/source/network/Network.cpp +++ b/source/network/Network.cpp @@ -25,7 +25,7 @@ DEFINE_ERROR(CONFLICTING_OP_IN_PROGRESS, "A conflicting operation is already in progress"); -#define LOG_CAT_NET "net" +#define LOG_CATEGORY L"net" /** * The SNetHeader will always be stored in host-order @@ -187,7 +187,7 @@ void CMessageSocket::StartWriteNextMessage() } else if (pMsg->GetType() < 0) { - LOG(CLogger::Warning, LOG_CAT_NET, "CMessageSocket::StartWriteNextMessage(): Non-network message"); + LOG(CLogger::Warning, LOG_CATEGORY, L"CMessageSocket::StartWriteNextMessage(): Non-network message"); delete pMsg; pMsg=NULL; } diff --git a/source/network/Network.h b/source/network/Network.h index 0aa02b40b9..c3853b45fb 100644 --- a/source/network/Network.h +++ b/source/network/Network.h @@ -77,8 +77,6 @@ MORE INFO #define ALIGN_UP( _n, _block ) ( _n + _block - (_n % _block ) ) #define ALIGN_BLOCK( _n ) ALIGN_UP( _n, BLOCK_SIZE ) -#define LOG_CAT_NET "net" - typedef CLocker > CLockedMessageDeque; //------------------------------------------------- diff --git a/source/network/SocketBase.cpp b/source/network/SocketBase.cpp index 44c98655c0..06eafe9e3b 100644 --- a/source/network/SocketBase.cpp +++ b/source/network/SocketBase.cpp @@ -38,6 +38,8 @@ # include #endif +#define LOG_CATEGORY L"net" + // Record global transfer statistics (sent/recvd bytes). This will put a lock // /unlock pair in all read and write operations. #define RECORD_GLOBAL_STATS 1 @@ -76,7 +78,7 @@ PS_RESULT GetPS_RESULT(int error) default: char buf[256]; Network_GetErrorString(error, buf, sizeof(buf)); - LOG(CLogger::Error, LOG_CAT_NET, "SocketBase.cpp::GetPS_RESULT(): Unrecognized error %s[%d]", buf, error); + LOG(CLogger::Error, LOG_CATEGORY, L"SocketBase.cpp::GetPS_RESULT(): Unrecognized error %s[%d]", buf, error); return PS_FAIL; } } @@ -97,7 +99,7 @@ CSocketAddress::CSocketAddress(int port, ESocketProtocol proto) m_Union.m_IPv6.sin6_port=htons(port); break; default: - debug_warn("CSocketAddress::CSocketAddress: Bad proto"); + debug_warn(L"CSocketAddress::CSocketAddress: Bad proto"); } } @@ -117,7 +119,7 @@ CSocketAddress CSocketAddress::Loopback(int port, ESocketProtocol proto) ret.m_Union.m_IPv6.sin6_port=htons(port); break; default: - debug_warn("CSocketAddress::CSocketAddress: Bad proto"); + debug_warn(L"CSocketAddress::CSocketAddress: Bad proto"); } return ret; } @@ -489,7 +491,7 @@ PS_RESULT CSocketBase::Bind(const CSocketAddress &address) break; default: Network_GetErrorString(err, errBuf, sizeof(errBuf)); - LOG(CLogger::Error, LOG_CAT_NET, "CServerSocket::Bind(): bind: %s [%d] => PS_FAIL", errBuf, err); + LOG(CLogger::Error, LOG_CATEGORY, L"CServerSocket::Bind(): bind: %s [%d] => PS_FAIL", errBuf, err); } m_State=SS_UNCONNECTED; m_Error=ret; @@ -501,7 +503,7 @@ PS_RESULT CSocketBase::Bind(const CSocketAddress &address) { int err=Network_LastError; Network_GetErrorString(err, errBuf, sizeof(errBuf)); - LOG(CLogger::Error, LOG_CAT_NET, "CServerSocket::Bind(): listen: %s [%d] => PS_FAIL", errBuf, err); + LOG(CLogger::Error, LOG_CATEGORY, L"CServerSocket::Bind(): listen: %s [%d] => PS_FAIL", errBuf, err); m_State=SS_UNCONNECTED; return PS_FAIL; } diff --git a/source/ps/CConsole.cpp b/source/ps/CConsole.cpp index f7d737d2ce..4c2aae1204 100644 --- a/source/ps/CConsole.cpp +++ b/source/ps/CConsole.cpp @@ -40,6 +40,8 @@ #include "scripting/ScriptableComplex.inl" #include "simulation/Entity.h" +#define LOG_CATEGORY L"Console" + CConsole* g_Console = 0; CConsole::CConsole() @@ -61,17 +63,17 @@ CConsole::CConsole() InsertMessage(L"[ 0 A.D. Console v0.12 ] type \"\\info\" for help"); InsertMessage(L""); - if (FileExists("gui/text/help.txt")) + if (FileExists(L"gui/text/help.txt")) { shared_ptr buf; size_t size; - if ( g_VFS->LoadFile("gui/text/help.txt", buf, size) < 0 ) + if ( g_VFS->LoadFile(L"gui/text/help.txt", buf, size) < 0 ) { - LOG(CLogger::Error, "Console", "Help file not found for console"); + LOG(CLogger::Error, LOG_CATEGORY, L"Help file not found for console"); return; } // TODO: read in text mode, or at least get rid of the \r\n somehow // TODO: maybe the help file should be UTF-8 - we assume it's iso-8859-1 here - m_helpText = CStrW(CStr( (const char*)buf.get() )); + m_helpText = CStrW((const char*)buf.get()); } else { @@ -541,14 +543,14 @@ void CConsole::InsertMessage(const wchar_t* szMessage, ...) va_start(args, szMessage); if (vswprintf(szBuffer, CONSOLE_MESSAGE_SIZE, szMessage, args) == -1) { - debug_printf("Error printfing console message (buffer size exceeded?)\n"); + debug_printf(L"Error printfing console message (buffer size exceeded?)\n"); // Make it obvious that the text was trimmed (assuming it was) wcscpy(szBuffer+CONSOLE_MESSAGE_SIZE-4, L"..."); } va_end(args); - InsertMessageRaw(CStrW(szBuffer)); + InsertMessageRaw(szBuffer); } @@ -701,7 +703,7 @@ void CConsole::ProcessBuffer(const wchar_t* szLine) JS_SetParent(g_ScriptingHost.GetContext(), m_ScriptObject, g_Selection.m_selected[0]->GetScript()); } - jsval rval = g_ScriptingHost.ExecuteScript( CStrW( szLine + 1 ), L"Console", m_ScriptObject ); + jsval rval = g_ScriptingHost.ExecuteScript( szLine+1, L"Console", m_ScriptObject ); if (szLine[0] == '?' && rval) { try { diff --git a/source/ps/CLogger.cpp b/source/ps/CLogger.cpp index 4f0a39ab26..a2adf67546 100644 --- a/source/ps/CLogger.cpp +++ b/source/ps/CLogger.cpp @@ -29,36 +29,36 @@ // Set up a default logger that throws everything away, because that's // better than crashing. (This is particularly useful for unit tests which // don't care about any log output.) -struct BlackHoleStreamBuf : public std::streambuf +struct BlackHoleStreamBuf : public std::wstreambuf { } blackHoleStreamBuf; -std::ostream blackHoleStream(&blackHoleStreamBuf); +std::wostream blackHoleStream(&blackHoleStreamBuf); CLogger nullLogger(&blackHoleStream, &blackHoleStream, false, true); CLogger* g_Logger = &nullLogger; -const char* html_header0 = - "\n" - "Pyrogenesis Log\n" - "\n" - "

0 A.D. "; +const wchar_t* html_header0 = + L"\n" + L"Pyrogenesis Log\n" + L"\n" + L"

0 A.D. "; -const char* html_header1 = "

\n"; +const wchar_t* html_header1 = L"\n"; -const char* html_footer = ""; +const wchar_t* html_footer = L""; CLogger::CLogger() { - fs::path mainlogPath(fs::path(psLogDir())/"mainlog.html"); - m_MainLog = new std::ofstream(mainlogPath.external_file_string().c_str(), std::ofstream::out | std::ofstream::trunc); + fs::wpath mainlogPath(fs::wpath(psLogDir())/L"mainlog.html"); + m_MainLog = new std::wofstream(mainlogPath.external_file_string().c_str(), std::ofstream::out | std::ofstream::trunc); - fs::path interestinglogPath(fs::path(psLogDir())/"interestinglog.html"); - m_InterestingLog = new std::ofstream(interestinglogPath.external_file_string().c_str(), std::ofstream::out | std::ofstream::trunc); + fs::wpath interestinglogPath(fs::wpath(psLogDir())/L"interestinglog.html"); + m_InterestingLog = new std::wofstream(interestinglogPath.external_file_string().c_str(), std::ofstream::out | std::ofstream::trunc); m_OwnsStreams = true; m_UseDebugPrintf = true; @@ -66,7 +66,7 @@ CLogger::CLogger() Init(); } -CLogger::CLogger(std::ostream* mainLog, std::ostream* interestingLog, bool takeOwnership, bool useDebugPrintf) +CLogger::CLogger(std::wostream* mainLog, std::wostream* interestingLog, bool takeOwnership, bool useDebugPrintf) { m_MainLog = mainLog; m_InterestingLog = interestingLog; @@ -83,82 +83,79 @@ void CLogger::Init() m_NumberOfWarnings = 0; //Write Headers for the HTML documents - *m_MainLog << html_header0 << "Main log" << html_header1; + *m_MainLog << html_header0 << L"Main log" << html_header1; //Write Headers for the HTML documents - *m_InterestingLog << html_header0 << "Main log (warnings and errors only)" << html_header1; + *m_InterestingLog << html_header0 << L"Main log (warnings and errors only)" << html_header1; } CLogger::~CLogger () { - char buffer[128]; - sprintf(buffer," with %d message(s), %d error(s) and %d warning(s).", \ - m_NumberOfMessages,m_NumberOfErrors,m_NumberOfWarnings); + wchar_t buffer[128]; + swprintf_s(buffer, ARRAY_SIZE(buffer), L" with %d message(s), %d error(s) and %d warning(s).", m_NumberOfMessages,m_NumberOfErrors,m_NumberOfWarnings); time_t t = time(NULL); struct tm* now = localtime(&t); - //const char* months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; - //CStr currentDate = CStr(months[now->tm_mon]) + " " + CStr(now->tm_mday) + " " + CStr(1900+now->tm_year); - char currentDate[11]; - sprintf(currentDate, "%02d %02d %04d", now->tm_mon, now->tm_mday, (1900+now->tm_year)); - char currentTime[10]; - sprintf(currentTime, "%02d:%02d:%02d", now->tm_hour, now->tm_min, now->tm_sec); + wchar_t currentDate[11]; + swprintf_s(currentDate, ARRAY_SIZE(currentDate), L"%02d %02d %04d", now->tm_mon, now->tm_mday, (1900+now->tm_year)); + wchar_t currentTime[10]; + swprintf_s(currentTime, ARRAY_SIZE(currentTime), L"%02d:%02d:%02d", now->tm_hour, now->tm_min, now->tm_sec); //Write closing text - *m_MainLog << "

Engine exited successfully on " << currentDate; - *m_MainLog << " at " << currentTime << buffer << "

\n"; + *m_MainLog << L"

Engine exited successfully on " << currentDate; + *m_MainLog << L" at " << currentTime << buffer << L"

\n"; *m_MainLog << html_footer; - *m_InterestingLog << "

Engine exited successfully on " << currentDate; - *m_InterestingLog << " at " << currentTime << buffer << "

\n"; + *m_InterestingLog << L"

Engine exited successfully on " << currentDate; + *m_InterestingLog << L" at " << currentTime << buffer << L"

\n"; *m_InterestingLog << html_footer; if (m_OwnsStreams) { - delete m_InterestingLog; - delete m_MainLog; + SAFE_DELETE(m_InterestingLog); + SAFE_DELETE(m_MainLog); } } -void CLogger::WriteMessage(const char *message) +void CLogger::WriteMessage(const wchar_t* message) { ++m_NumberOfMessages; - *m_MainLog << "

" << message << "

\n"; + *m_MainLog << L"

" << message << L"

\n"; m_MainLog->flush(); } -void CLogger::WriteError(const char *message) +void CLogger::WriteError(const wchar_t* message) { ++m_NumberOfErrors; if (m_UseDebugPrintf) - debug_printf("ERROR: %s\n", message); + debug_printf(L"ERROR: %ls\n", message); - if (g_Console) g_Console->InsertMessage(L"ERROR: %hs", message); - *m_InterestingLog << "

ERROR: "<< message << "

\n"; + if (g_Console) g_Console->InsertMessage(L"ERROR: %ls", message); + *m_InterestingLog << L"

ERROR: "<< message << L"

\n"; m_InterestingLog->flush(); - *m_MainLog << "

ERROR: "<< message << "

\n"; + *m_MainLog << L"

ERROR: "<< message << L"

\n"; m_MainLog->flush(); } -void CLogger::WriteWarning(const char *message) +void CLogger::WriteWarning(const wchar_t* message) { ++m_NumberOfWarnings; - if (g_Console) g_Console->InsertMessage(L"WARNING: %hs", message); - *m_InterestingLog << "

WARNING: "<< message << "

\n"; + if (g_Console) g_Console->InsertMessage(L"WARNING: %ls", message); + *m_InterestingLog << L"

WARNING: "<< message << L"

\n"; m_InterestingLog->flush(); - *m_MainLog << "

WARNING: "<< message << "

\n"; + *m_MainLog << L"

WARNING: "<< message << L"

\n"; m_MainLog->flush(); } // Sends the message to the appropriate piece of code // -- This function has not been removed because the build would break. -void CLogger::LogUsingMethod(ELogMethod method, const char* message) +void CLogger::LogUsingMethod(ELogMethod method, const wchar_t* message) { if(method == Normal) WriteMessage(message); @@ -171,16 +168,16 @@ void CLogger::LogUsingMethod(ELogMethod method, const char* message) } // -- This function has not been removed because the build would break. -void CLogger::Log(ELogMethod method, const char* UNUSED(category), const char *fmt, ...) +void CLogger::Log(ELogMethod method, const wchar_t* UNUSED(category), const wchar_t* fmt, ...) { va_list argp; - char buffer[512]; + wchar_t buffer[512]; va_start(argp, fmt); - if (sys_vsnprintf(buffer, sizeof(buffer), fmt, argp) == -1) + if (sys_vswprintf(buffer, ARRAY_SIZE(buffer), fmt, argp) == -1) { // Buffer too small - ensure the string is nicely terminated - strcpy(buffer+sizeof(buffer)-4, "..."); // safe + SAFE_WCSCPY(buffer+ARRAY_SIZE(buffer)-4, L"..."); } va_end(argp); @@ -188,20 +185,20 @@ void CLogger::Log(ELogMethod method, const char* UNUSED(category), const char *f } // -- This function has not been removed because the build would break. -void CLogger::LogOnce(ELogMethod method, const char* UNUSED(category), const char *fmt, ...) +void CLogger::LogOnce(ELogMethod method, const wchar_t* UNUSED(category), const wchar_t* fmt, ...) { va_list argp; - char buffer[512]; + wchar_t buffer[512]; va_start(argp, fmt); - if (sys_vsnprintf(buffer, sizeof(buffer), fmt, argp) == -1) + if (sys_vswprintf(buffer, ARRAY_SIZE(buffer), fmt, argp) == -1) { // Buffer too small - ensure the string is nicely terminated - strcpy(buffer+sizeof(buffer)-4, "..."); // safe + SAFE_WCSCPY(buffer+ARRAY_SIZE(buffer)-4, L"..."); } va_end(argp); - std::string message (buffer); + std::wstring message(buffer); // If this message has already been logged, ignore it if (m_LoggedOnce.find(message) != m_LoggedOnce.end()) @@ -212,54 +209,55 @@ void CLogger::LogOnce(ELogMethod method, const char* UNUSED(category), const cha LogUsingMethod(method, buffer); } -void CLogger::LogMessage(const char *fmt, ...) +void CLogger::LogMessage(const wchar_t* fmt, ...) { va_list argp; - char buffer[512]; + wchar_t buffer[512]; va_start(argp, fmt); - if (sys_vsnprintf(buffer, sizeof(buffer), fmt, argp) == -1) + if (sys_vswprintf(buffer, sizeof(buffer), fmt, argp) == -1) { // Buffer too small - ensure the string is nicely terminated - strcpy(buffer+sizeof(buffer)-4, "..."); // safe + SAFE_WCSCPY(buffer+ARRAY_SIZE(buffer)-4, L"..."); } va_end(argp); WriteMessage(buffer); } -void CLogger::LogWarning(const char *fmt, ...) +void CLogger::LogWarning(const wchar_t* fmt, ...) { va_list argp; - char buffer[512]; + wchar_t buffer[512]; va_start(argp, fmt); - if (sys_vsnprintf(buffer, sizeof(buffer), fmt, argp) == -1) + if (sys_vswprintf(buffer, sizeof(buffer), fmt, argp) == -1) { // Buffer too small - ensure the string is nicely terminated - strcpy(buffer+sizeof(buffer)-4, "..."); // safe + SAFE_WCSCPY(buffer+ARRAY_SIZE(buffer)-4, L"..."); } va_end(argp); WriteWarning(buffer); } -void CLogger::LogError(const char *fmt, ...) +void CLogger::LogError(const wchar_t* fmt, ...) { va_list argp; - char buffer[512]; + wchar_t buffer[512]; va_start(argp, fmt); - if (sys_vsnprintf(buffer, sizeof(buffer), fmt, argp) == -1) + if (sys_vswprintf(buffer, sizeof(buffer), fmt, argp) == -1) { // Buffer too small - ensure the string is nicely terminated - strcpy(buffer+sizeof(buffer)-4, "..."); // safe + SAFE_WCSCPY(buffer+ARRAY_SIZE(buffer)-4, L"..."); } va_end(argp); WriteError(buffer); } + TestLogger::TestLogger() { m_OldLogger = g_Logger; @@ -272,7 +270,7 @@ TestLogger::~TestLogger() g_Logger = m_OldLogger; } -std::string TestLogger::GetOutput() +std::wstring TestLogger::GetOutput() { return m_Stream.str(); } diff --git a/source/ps/CLogger.h b/source/ps/CLogger.h index f0b6d73a16..1bf4d5570d 100644 --- a/source/ps/CLogger.h +++ b/source/ps/CLogger.h @@ -52,37 +52,37 @@ public: // Special constructor (mostly for testing) - outputs to provided streams. // Can take ownership of streams and delete them in the destructor. - CLogger(std::ostream* mainLog, std::ostream* interestingLog, bool takeOwnership, bool useDebugPrintf); + CLogger(std::wostream* mainLog, std::wostream* interestingLog, bool takeOwnership, bool useDebugPrintf); ~CLogger(); // Functions to write different message types (Errors and warnings are placed // both in mainLog and intrestingLog.) - void WriteMessage(const char *message); - void WriteError (const char *message); - void WriteWarning(const char *message); + void WriteMessage(const wchar_t* message); + void WriteError (const wchar_t* message); + void WriteWarning(const wchar_t* message); // Function to log stuff to file // -- This function has not been removed because the build would break. - void Log(ELogMethod method, const char* category, const char *fmt, ...) PRINTF_ARGS(4); + void Log(ELogMethod method, const wchar_t* category, const wchar_t* fmt, ...) PRINTF_ARGS(4); // Similar to Log, but only outputs each message once no matter how many times it's called // -- This function has not been removed because the build would break. - void LogOnce(ELogMethod method, const char* category, const char *fmt, ...) PRINTF_ARGS(4); + void LogOnce(ELogMethod method, const wchar_t* category, const wchar_t* fmt, ...) PRINTF_ARGS(4); // Functions to write a message, warning or error to file. - void LogMessage(const char *fmt, ...) PRINTF_ARGS(2); - void LogWarning(const char *fmt, ...) PRINTF_ARGS(2); - void LogError(const char *fmt, ...) PRINTF_ARGS(2); + void LogMessage(const wchar_t* fmt, ...) PRINTF_ARGS(2); + void LogWarning(const wchar_t* fmt, ...) PRINTF_ARGS(2); + void LogError(const wchar_t* fmt, ...) PRINTF_ARGS(2); private: void Init(); // -- This function has not been removed because the build would break. - void LogUsingMethod(ELogMethod method, const char* message); + void LogUsingMethod(ELogMethod method, const wchar_t* message); // the output streams - std::ostream* m_MainLog; - std::ostream* m_InterestingLog; + std::wostream* m_MainLog; + std::wostream* m_InterestingLog; bool m_OwnsStreams; // whether errors should be reported via debug_printf (default) @@ -95,7 +95,7 @@ private: int m_NumberOfWarnings; // Used to remember LogOnce messages - std::set m_LoggedOnce; + std::set m_LoggedOnce; }; @@ -109,10 +109,10 @@ class TestLogger public: TestLogger(); ~TestLogger(); - std::string GetOutput(); + std::wstring GetOutput(); private: CLogger* m_OldLogger; - std::stringstream m_Stream; + std::wstringstream m_Stream; }; #endif diff --git a/source/ps/CStr.cpp b/source/ps/CStr.cpp index bf060aae2c..a9827f2558 100644 --- a/source/ps/CStr.cpp +++ b/source/ps/CStr.cpp @@ -499,7 +499,7 @@ CStr CStr::Trim(PS_TRIM_MODE Mode) const } break; default: - debug_warn("CStr::Trim: invalid Mode"); + debug_warn(L"CStr::Trim: invalid Mode"); } @@ -531,7 +531,7 @@ CStr CStr::Pad(PS_TRIM_MODE Mode, size_t Length) const break; default: - debug_warn("CStr::Trim: invalid Mode"); + debug_warn(L"CStr::Trim: invalid Mode"); } return std::tstring(Left, _T(' ')) + *this + std::tstring(Right, _T(' ')); @@ -575,7 +575,7 @@ CStr::operator const tchar*() const size_t CStr::GetHashCode() const { - return (size_t)fnv_hash(data(), length()); + return (size_t)fnv_hash(data(), length()*sizeof(value_type)); // janwas 2005-03-18: now use 32-bit version; 64 is slower and // the result was truncated down to 32 anyway. } diff --git a/source/ps/CStr.h b/source/ps/CStr.h index 5238dccfe2..30aad50e90 100644 --- a/source/ps/CStr.h +++ b/source/ps/CStr.h @@ -34,7 +34,7 @@ Examples: // UNICODE LPCWSTR str = L"PI"; - wprintf( L"%s = %fn", str, 3.1459f ); + wprintf( L"%ls = %fn", str, 3.1459f ); */ // history: diff --git a/source/ps/ConfigDB.cpp b/source/ps/ConfigDB.cpp index 98652a7a90..9100109bd0 100644 --- a/source/ps/ConfigDB.cpp +++ b/source/ps/ConfigDB.cpp @@ -24,11 +24,11 @@ #include "Filesystem.h" #include "scripting/ScriptingHost.h" -#define LOG_CATEGORY "config" +#define LOG_CATEGORY L"config" typedef std::map TConfigMap; TConfigMap CConfigDB::m_Map[CFG_LAST]; -CStr CConfigDB::m_ConfigFile[CFG_LAST]; +CStrW CConfigDB::m_ConfigFile[CFG_LAST]; bool CConfigDB::m_UseVFS[CFG_LAST]; namespace ConfigNamespace_JS @@ -103,7 +103,7 @@ namespace ConfigNamespace_JS char *path; if (JS_ConvertArguments(cx, 2, argv, "bs", &useVFS, &path)) { - JSBool res=g_ConfigDB.WriteFile(cfgNs, useVFS?true:false, path); + JSBool res=g_ConfigDB.WriteFile(cfgNs, useVFS?true:false, CStrW(path)); *rval = BOOLEAN_TO_JSVAL(res); return JS_TRUE; } @@ -138,7 +138,7 @@ namespace ConfigNamespace_JS char *path; if (JS_ConvertArguments(cx, 2, argv, "bs", &useVFS, &path)) { - g_ConfigDB.SetConfigFile(cfgNs, useVFS?true:false, path); + g_ConfigDB.SetConfigFile(cfgNs, useVFS?true:false, CStrW(path)); return JS_TRUE; } else @@ -217,7 +217,7 @@ CConfigValueSet *CConfigDB::GetValues(EConfigNamespace ns, const CStr& name ) { if (ns < 0 || ns >= CFG_LAST) { - debug_warn("CConfigDB: Invalid ns value"); + debug_warn(L"CConfigDB: Invalid ns value"); return NULL; } @@ -239,7 +239,7 @@ CConfigValue *CConfigDB::CreateValue(EConfigNamespace ns, const CStr& name) { if (ns < 0 || ns >= CFG_LAST) { - debug_warn("CConfigDB: Invalid ns value"); + debug_warn(L"CConfigDB: Invalid ns value"); return NULL; } @@ -250,11 +250,11 @@ CConfigValue *CConfigDB::CreateValue(EConfigNamespace ns, const CStr& name) return &(it->second[0]); } -void CConfigDB::SetConfigFile(EConfigNamespace ns, bool useVFS, const CStr& path) +void CConfigDB::SetConfigFile(EConfigNamespace ns, bool useVFS, const CStrW& path) { if (ns < 0 || ns >= CFG_LAST) { - debug_warn("CConfigDB: Invalid ns value"); + debug_warn(L"CConfigDB: Invalid ns value"); return; } @@ -276,7 +276,7 @@ bool CConfigDB::Reload(EConfigNamespace ns) // Handle missing files quietly if (g_VFS->GetFileInfo(m_ConfigFile[ns], NULL) < 0) { - LOG(CLogger::Warning, LOG_CATEGORY, "Cannot find config file \"%s\" - ignoring", m_ConfigFile[ns].c_str()); + LOG(CLogger::Warning, LOG_CATEGORY, L"Cannot find config file \"%ls\" - ignoring", m_ConfigFile[ns].c_str()); return false; } else @@ -284,7 +284,7 @@ bool CConfigDB::Reload(EConfigNamespace ns) LibError ret = g_VFS->LoadFile(m_ConfigFile[ns], buffer, buflen); if (ret != INFO::OK) { - LOG(CLogger::Error, LOG_CATEGORY, "vfs_load for \"%s\" failed: return was %ld", m_ConfigFile[ns].c_str(), ret); + LOG(CLogger::Error, LOG_CATEGORY, L"vfs_load for \"%ls\" failed: return was %ld", m_ConfigFile[ns].c_str(), ret); return false; } } @@ -329,7 +329,7 @@ bool CConfigDB::Reload(EConfigNamespace ns) CConfigValue argument; argument.m_String = value; newMap[name].push_back( argument ); - LOG(CLogger::Normal, LOG_CATEGORY, "Loaded config std::string \"%s\" = \"%s\"", name.c_str(), value.c_str()); + LOG(CLogger::Normal, LOG_CATEGORY, L"Loaded config string \"%hs\" = \"%hs\"", name.c_str(), value.c_str()); } } } @@ -340,31 +340,29 @@ bool CConfigDB::Reload(EConfigNamespace ns) return true; } -bool CConfigDB::WriteFile(EConfigNamespace ns, bool useVFS, const CStr& path) +bool CConfigDB::WriteFile(EConfigNamespace ns, bool useVFS, const CStrW& path) { debug_assert(useVFS); if (ns < 0 || ns >= CFG_LAST) { - debug_warn("CConfigDB: Invalid ns value"); + debug_warn(L"CConfigDB: Invalid ns value"); return false; } - const char *filepath=path.c_str(); - shared_ptr buf = io_Allocate(1*MiB); char* pos = (char*)buf.get(); TConfigMap &map=m_Map[ns]; for(TConfigMap::const_iterator it = map.begin(); it != map.end(); ++it) { - pos += sprintf(pos, "%s = \"%s\"\n", it->first.c_str(), it->second[0].m_String.c_str()); + pos += sprintf(pos, "%hs = \"%hs\"\n", it->first.c_str(), it->second[0].m_String.c_str()); } const size_t len = pos - (char*)buf.get(); - LibError ret = g_VFS->CreateFile(filepath, buf, len); + LibError ret = g_VFS->CreateFile(path, buf, len); if(ret < 0) { - LOG(CLogger::Error, LOG_CATEGORY, "CConfigDB::WriteFile(): CreateFile \"%s\" failed (error: %d)", filepath, (int)ret); + LOG(CLogger::Error, LOG_CATEGORY, L"CConfigDB::WriteFile(): CreateFile \"%ls\" failed (error: %d)", path.c_str(), (int)ret); return false; } diff --git a/source/ps/ConfigDB.h b/source/ps/ConfigDB.h index cf30625e4b..52e79f498e 100644 --- a/source/ps/ConfigDB.h +++ b/source/ps/ConfigDB.h @@ -76,7 +76,7 @@ typedef std::vector CConfigValueSet; class CConfigDB: public Singleton { static std::map m_Map[]; - static CStr m_ConfigFile[]; + static CStrW m_ConfigFile[]; static bool m_UseVFS[]; public: @@ -117,7 +117,7 @@ public: // VFS: relative to VFS root // non-VFS: relative to current working directory (binaries/data/) // 'useVFS': true if the path is a VFS path, false if it is a real path - void SetConfigFile(EConfigNamespace ns, bool useVFS, const CStr& path); + void SetConfigFile(EConfigNamespace ns, bool useVFS, const CStrW& path); // Reload() // Reload the config file associated with the specified config namespace @@ -135,7 +135,7 @@ public: // Returns: // true: if the config namespace was successfully written to the file // false: if an error occured - bool WriteFile(EConfigNamespace ns, bool useVFS, const CStr& path); + bool WriteFile(EConfigNamespace ns, bool useVFS, const CStrW& path); }; diff --git a/source/ps/DllLoader.cpp b/source/ps/DllLoader.cpp index 96084ea26a..71d17934b3 100644 --- a/source/ps/DllLoader.cpp +++ b/source/ps/DllLoader.cpp @@ -86,7 +86,7 @@ bool DllLoader::LoadDLL() { const char* error = dlerror(); if (error) - LOG(CLogger::Error, "", "dlopen error: %s", error); + LOG(CLogger::Error, L"", L"dlopen error: %hs", error); m_Handle = HANDLE_UNAVAILABLE; } } @@ -107,7 +107,7 @@ void DllLoader::LoadSymbolInternal(const char* name, void** fptr) const { if (! IsLoaded()) { - debug_warn("Loading symbol from invalid DLL"); + debug_warn(L"Loading symbol from invalid DLL"); *fptr = NULL; throw PSERROR_DllLoader_DllNotLoaded(); } diff --git a/source/ps/Filesystem.cpp b/source/ps/Filesystem.cpp index 964270b2a0..80546d29ae 100644 --- a/source/ps/Filesystem.cpp +++ b/source/ps/Filesystem.cpp @@ -20,16 +20,11 @@ #include "ps/CLogger.h" -#define LOG_CATEGORY "file" +#define LOG_CATEGORY L"file" PIVFS g_VFS; -bool FileExists(const char* pathname) -{ - return g_VFS->GetFileInfo(pathname, 0) == INFO::OK; -} - bool FileExists(const VfsPath& pathname) { return g_VFS->GetFileInfo(pathname, 0) == INFO::OK; @@ -57,7 +52,7 @@ PSRETURN CVFSFile::Load(const VfsPath& filename) LibError ret = g_VFS->LoadFile(filename, m_Buffer, m_BufferSize); if (ret != INFO::OK) { - LOG(CLogger::Error, LOG_CATEGORY, "CVFSFile: file %s couldn't be opened (vfs_load: %ld)", filename.string().c_str(), ret); + LOG(CLogger::Error, LOG_CATEGORY, L"CVFSFile: file %ls couldn't be opened (vfs_load: %ld)", filename.string().c_str(), ret); return PSRETURN_CVFSFile_LoadFailed; } @@ -70,7 +65,7 @@ const u8* CVFSFile::GetBuffer() const // accidentally forgetting to check that the open succeeded if (!m_Buffer) { - debug_warn("GetBuffer() called with no file loaded"); + debug_warn(L"GetBuffer() called with no file loaded"); throw PSERROR_CVFSFile_InvalidBufferAccess(); } diff --git a/source/ps/Filesystem.h b/source/ps/Filesystem.h index abcf7b903d..4a8250b48f 100644 --- a/source/ps/Filesystem.h +++ b/source/ps/Filesystem.h @@ -30,7 +30,6 @@ extern PIVFS g_VFS; -extern bool FileExists(const char* pathname); extern bool FileExists(const VfsPath& pathname); ERROR_GROUP(CVFSFile); diff --git a/source/ps/Font.cpp b/source/ps/Font.cpp index 89d6b5c700..9f1caf0cc8 100644 --- a/source/ps/Font.cpp +++ b/source/ps/Font.cpp @@ -23,27 +23,27 @@ #include "lib/res/graphics/unifont.h" #include "ps/CLogger.h" -#define LOG_CATEGORY "graphics" +#define LOG_CATEGORY L"graphics" #include #include -const char* DefaultFont = "verdana16"; +const wchar_t* DefaultFont = L"verdana16"; -CFont::CFont(const char* name) +CFont::CFont(const wchar_t* name) { // TODO perhaps: cache the resultant filename (or Handle) for each // font name; but it's nice to allow run-time alteration of the fonts std::string fontFilename; - CStr fontName = "font."; fontName += name; + CStrW fontName = L"font."; fontName += name; // See if the config value can be loaded CConfigValue* fontFilenameVar = g_ConfigDB.GetValue(CFG_USER, fontName); if (fontFilenameVar && fontFilenameVar->GetString(fontFilename)) { - h = unifont_load(fontFilename.c_str()); + h = unifont_load(CStrW(fontFilename)); } else { @@ -55,7 +55,7 @@ CFont::CFont(const char* name) return; // Not found as a font -- give up and use the default. - LOG_ONCE(CLogger::Error, LOG_CATEGORY, "Failed to find font '%s'", name); + LOG_ONCE(CLogger::Error, LOG_CATEGORY, L"Failed to find font '%ls'", name); h = unifont_load(DefaultFont); // Assume this worked } diff --git a/source/ps/Font.h b/source/ps/Font.h index c18f5e14a0..d35e4aa45c 100644 --- a/source/ps/Font.h +++ b/source/ps/Font.h @@ -35,7 +35,7 @@ glwprintf(L"Hello world"); class CFont { public: - CFont(const char* name); + CFont(const wchar_t* name); ~CFont(); void Bind(); diff --git a/source/ps/Game.cpp b/source/ps/Game.cpp index fab6d5dbd8..26cce59cf7 100644 --- a/source/ps/Game.cpp +++ b/source/ps/Game.cpp @@ -141,7 +141,7 @@ PSRETURN CGame::ReallyStartGame() debug_assert(ok); } - debug_printf("GAME STARTED, ALL INIT COMPLETE\n"); + debug_printf(L"GAME STARTED, ALL INIT COMPLETE\n"); m_GameStarted=true; // The call tree we've built for pregame probably isn't useful in-game. @@ -323,15 +323,15 @@ CPlayer *CGame::GetPlayer(size_t idx) { if (idx > m_NumPlayers) { -// debug_warn("Invalid player ID"); +// debug_warn(L"Invalid player ID"); // LOG(CLogger::Error, "", "Invalid player ID %d (outside 0..%d)", idx, m_NumPlayers); return m_Players[0]; } // Be a bit more paranoid - maybe m_Players hasn't been set large enough else if (idx >= m_Players.size()) { - debug_warn("Invalid player ID"); - LOG(CLogger::Error, "", "Invalid player ID %lu (not <=%lu - internal error?)", (unsigned long)idx, (unsigned long)m_Players.size()); + debug_warn(L"Invalid player ID"); + LOG(CLogger::Error, L"", L"Invalid player ID %lu (not <=%lu - internal error?)", (unsigned long)idx, (unsigned long)m_Players.size()); if (m_Players.size() != 0) return m_Players[0]; diff --git a/source/ps/GameAttributes.cpp b/source/ps/GameAttributes.cpp index edb90e1e13..f35ed94726 100644 --- a/source/ps/GameAttributes.cpp +++ b/source/ps/GameAttributes.cpp @@ -221,9 +221,9 @@ CGameAttributes::CGameAttributes(): AddSynchedProperty(L"screenshotMode", &m_ScreenshotMode); CXeromyces XeroFile; - if (XeroFile.Load("temp/players.xml") != PSRETURN_OK) + if (XeroFile.Load(L"temp/players.xml") != PSRETURN_OK) { - LOG(CLogger::Error, "", "Failed to load players list (temp/players.xml)"); + LOG(CLogger::Error, L"", L"Failed to load players list (temp/players.xml)"); // Basic default players @@ -248,7 +248,7 @@ CGameAttributes::CGameAttributes(): m_Players.back()->SetName(attr.GetNamedItem(at_name)); std::stringstream str; - str << (CStr)attr.GetNamedItem(at_rgb); + str << CStr(attr.GetNamedItem(at_rgb)); int r, g, b; if (str >> r >> g >> b) m_Players.back()->SetColour(SPlayerColour(r/255.0f, g/255.0f, b/255.0f)); @@ -369,7 +369,7 @@ CPlayer *CGameAttributes::GetPlayer(size_t id) return m_Players[id]; else { - LOG(CLogger::Error, "", "CGameAttributes::GetPlayer(): Attempt to get player %lu (while there only are %lu players)", (unsigned long)id, (unsigned long)m_Players.size()); + LOG(CLogger::Error, L"", L"CGameAttributes::GetPlayer(): Attempt to get player %lu (while there only are %lu players)", (unsigned long)id, (unsigned long)m_Players.size()); return m_Players[0]; } } @@ -380,7 +380,7 @@ CPlayerSlot *CGameAttributes::GetSlot(size_t index) return m_PlayerSlots[index]; else { - LOG(CLogger::Error, "", "CGameAttributes::GetSlot(): Attempt to get slot %lu (while there only are %lu slots)", (unsigned long)index, (unsigned long)m_PlayerSlots.size()); + LOG(CLogger::Error, L"", L"CGameAttributes::GetSlot(): Attempt to get slot %lu (while there only are %lu slots)", (unsigned long)index, (unsigned long)m_PlayerSlots.size()); return m_PlayerSlots[0]; } } diff --git a/source/ps/GameSetup/Atlas.cpp b/source/ps/GameSetup/Atlas.cpp index e8b81feadb..bea044027a 100644 --- a/source/ps/GameSetup/Atlas.cpp +++ b/source/ps/GameSetup/Atlas.cpp @@ -53,7 +53,7 @@ static void ATLAS_Run(const CmdLineArgs& args, int flags = 0) extern bool BeginAtlas(const CmdLineArgs& args, const DllLoader& dll); if (!BeginAtlas(args, atlas_dll)) { - debug_warn("Atlas loading failed"); + debug_warn(L"Atlas loading failed"); return; } } diff --git a/source/ps/GameSetup/Config.cpp b/source/ps/GameSetup/Config.cpp index 3cced75684..504a9881f8 100644 --- a/source/ps/GameSetup/Config.cpp +++ b/source/ps/GameSetup/Config.cpp @@ -25,12 +25,12 @@ #include "lib/res/sound/snd_mgr.h" #include "Config.h" -#define LOG_CATEGORY "config" +#define LOG_CATEGORY L"config" // (these variables are documented in the header.) -CStr g_CursorName = "test"; +CStrW g_CursorName = L"test"; CStr g_ActiveProfile = "default"; bool g_NoGLS3TC = false; @@ -73,15 +73,15 @@ CStr g_AutostartMap = ""; static void LoadProfile( const CStr& profile ) { - VfsPath path = VfsPath("profiles") / (std::string)profile; + VfsPath path = VfsPath(L"profiles") / CStrW(profile); - VfsPath configFilename = path / "settings/user.cfg"; + VfsPath configFilename = path / L"settings/user.cfg"; g_ConfigDB.SetConfigFile(CFG_USER, true, configFilename.string().c_str()); g_ConfigDB.Reload(CFG_USER); int max_history_lines = 200; CFG_GET_USER_VAL("console.history.size", Int, max_history_lines); - g_Console->UseHistoryFile(path / "settings/history", max_history_lines); + g_Console->UseHistoryFile(path / L"settings/history", max_history_lines); } @@ -113,8 +113,8 @@ static void LoadGlobals() if(gain > 0.0f) WARN_ERR(snd_set_master_gain(gain)); - LOG(CLogger::Normal, LOG_CATEGORY, "g_x/yres is %dx%d", g_xres, g_yres); - LOG(CLogger::Normal, LOG_CATEGORY, "Active profile is %s", g_ActiveProfile.c_str()); + LOG(CLogger::Normal, LOG_CATEGORY, L"g_x/yres is %dx%d", g_xres, g_yres); + LOG(CLogger::Normal, LOG_CATEGORY, L"Active profile is %hs", g_ActiveProfile.c_str()); } @@ -191,21 +191,21 @@ static void ProcessCommandLineArgs(const CmdLineArgs& args) void CONFIG_Init(const CmdLineArgs& args) { - TIMER("CONFIG_Init"); + TIMER(L"CONFIG_Init"); MICROLOG(L"init config"); new CConfigDB; // Load the global, default config file - g_ConfigDB.SetConfigFile(CFG_DEFAULT, false, "config/default.cfg"); + g_ConfigDB.SetConfigFile(CFG_DEFAULT, false, L"config/default.cfg"); g_ConfigDB.Reload(CFG_DEFAULT); // 216ms // Try loading the local system config file (which doesn't exist by // default) - this is designed as a way of letting developers edit the // system config without accidentally committing their changes back to SVN. - g_ConfigDB.SetConfigFile(CFG_SYSTEM, false, "config/local.cfg"); + g_ConfigDB.SetConfigFile(CFG_SYSTEM, false, L"config/local.cfg"); g_ConfigDB.Reload(CFG_SYSTEM); - g_ConfigDB.SetConfigFile(CFG_MOD, true, "config/mod.cfg"); + g_ConfigDB.SetConfigFile(CFG_MOD, true, L"config/mod.cfg"); // No point in reloading mod.cfg here - we haven't mounted mods yet ProcessCommandLineArgs(args); diff --git a/source/ps/GameSetup/Config.h b/source/ps/GameSetup/Config.h index 9ba81c7937..cbb247ccbe 100644 --- a/source/ps/GameSetup/Config.h +++ b/source/ps/GameSetup/Config.h @@ -65,7 +65,7 @@ extern bool g_Quickstart; // If non-empty, specified map will be automatically loaded extern CStr g_AutostartMap; -extern CStr g_CursorName; +extern CStrW g_CursorName; class CmdLineArgs; extern void CONFIG_Init(const CmdLineArgs& args); diff --git a/source/ps/GameSetup/GameSetup.cpp b/source/ps/GameSetup/GameSetup.cpp index afbb368a00..be6b834adc 100644 --- a/source/ps/GameSetup/GameSetup.cpp +++ b/source/ps/GameSetup/GameSetup.cpp @@ -97,7 +97,7 @@ ERROR_TYPE(System, SDLInitFailed); ERROR_TYPE(System, VmodeFailed); ERROR_TYPE(System, RequiredExtensionsMissing); -#define LOG_CATEGORY "gamesetup" +#define LOG_CATEGORY L"gamesetup" bool g_DoRenderGui = true; @@ -129,7 +129,7 @@ static int SetVideoMode(int w, int h, int bpp, bool fullscreen) ogl_Init(); // required after each mode change if(SDL_SetGamma(g_Gamma, g_Gamma, g_Gamma) < 0) - debug_warn("SDL_SetGamma failed"); + debug_warn(L"SDL_SetGamma failed"); return 0; } @@ -183,7 +183,7 @@ retry: break; // invalid default: - debug_warn("SetTextureQuality: invalid quality"); + debug_warn(L"SetTextureQuality: invalid quality"); quality = SANE_TEX_QUALITY_DEFAULT; // careful: recursion doesn't work and we don't want to duplicate // the "sane" default values. @@ -200,15 +200,15 @@ retry: void GUI_Init() { - {TIMER("ps_gui_init"); + {TIMER(L"ps_gui_init"); g_GUI.Initialize();} - {TIMER("ps_gui_setup_xml"); - g_GUI.LoadXmlFile("gui/test/setup.xml");} - {TIMER("ps_gui_styles_xml"); - g_GUI.LoadXmlFile("gui/test/styles.xml");} - {TIMER("ps_gui_sprite1_xml"); - g_GUI.LoadXmlFile("gui/test/sprite1.xml");} + {TIMER(L"ps_gui_setup_xml"); + g_GUI.LoadXmlFile(L"gui/test/setup.xml");} + {TIMER(L"ps_gui_styles_xml"); + g_GUI.LoadXmlFile(L"gui/test/styles.xml");} + {TIMER(L"ps_gui_sprite1_xml"); + g_GUI.LoadXmlFile(L"gui/test/sprite1.xml");} // Atlas is running, we won't need these GUI pages (for now! // what if Atlas switches to in-game mode?!) @@ -216,24 +216,24 @@ void GUI_Init() // if(ATLAS_IsRunning()) // return; - {TIMER("ps_gui_1"); - g_GUI.LoadXmlFile("gui/test/1_init.xml");} - {TIMER("ps_gui_2"); - g_GUI.LoadXmlFile("gui/test/2_mainmenu.xml");} - {TIMER("ps_gui_3"); - g_GUI.LoadXmlFile("gui/test/3_loading.xml");} - {TIMER("ps_gui_4"); - g_GUI.LoadXmlFile("gui/test/4_session.xml");} - {TIMER("ps_gui_6"); - g_GUI.LoadXmlFile("gui/test/6_subwindows.xml");} - {TIMER("ps_gui_6_1"); - g_GUI.LoadXmlFile("gui/test/6_1_manual.xml");} - {TIMER("ps_gui_6_2"); - g_GUI.LoadXmlFile("gui/test/6_2_jukebox.xml");} - {TIMER("ps_gui_7"); - g_GUI.LoadXmlFile("gui/test/7_atlas.xml");} - {TIMER("ps_gui_9"); - g_GUI.LoadXmlFile("gui/test/9_global.xml");} + {TIMER(L"ps_gui_1"); + g_GUI.LoadXmlFile(L"gui/test/1_init.xml");} + {TIMER(L"ps_gui_2"); + g_GUI.LoadXmlFile(L"gui/test/2_mainmenu.xml");} + {TIMER(L"ps_gui_3"); + g_GUI.LoadXmlFile(L"gui/test/3_loading.xml");} + {TIMER(L"ps_gui_4"); + g_GUI.LoadXmlFile(L"gui/test/4_session.xml");} + {TIMER(L"ps_gui_6"); + g_GUI.LoadXmlFile(L"gui/test/6_subwindows.xml");} + {TIMER(L"ps_gui_6_1"); + g_GUI.LoadXmlFile(L"gui/test/6_1_manual.xml");} + {TIMER(L"ps_gui_6_2"); + g_GUI.LoadXmlFile(L"gui/test/6_2_jukebox.xml");} + {TIMER(L"ps_gui_7"); + g_GUI.LoadXmlFile(L"gui/test/7_atlas.xml");} + {TIMER(L"ps_gui_9"); + g_GUI.LoadXmlFile(L"gui/test/9_global.xml");} } @@ -409,7 +409,7 @@ void Render() glLoadIdentity(); MICROLOG(L"render console"); - CFont font("console"); + CFont font(L"console"); font.Bind(); g_Console->Render(); } @@ -435,11 +435,11 @@ void Render() ogl_WarnIfError(); // Draw the cursor (or set the Windows cursor, on Windows) - CStr cursorName = g_BuildingPlacer.m_active ? "action-build" : g_CursorName; + CStrW cursorName = g_BuildingPlacer.m_active ? L"action-build" : g_CursorName; if (cursorName.empty()) cursor_draw(NULL, g_mouse_x, g_mouse_y); else - cursor_draw(cursorName, g_mouse_x, g_mouse_y); + cursor_draw(cursorName.c_str(), g_mouse_x, g_mouse_y); // restore glMatrixMode(GL_PROJECTION); @@ -505,7 +505,7 @@ static void RegisterJavascriptInterfaces() static void InitScripting() { - TIMER("InitScripting"); + TIMER(L"InitScripting"); // Create the scripting host. This needs to be done before the GUI is created. // [7ms] @@ -539,36 +539,36 @@ static size_t ChooseCacheSize() static void InitVfs(const CmdLineArgs& args) { - TIMER("InitVfs"); + TIMER(L"InitVfs"); const Paths paths(args); - fs::path logs(paths.Logs()); + fs::wpath logs(paths.Logs()); CreateDirectories(logs, 0700); - psSetLogDir(logs.string().c_str()); + psSetLogDir(logs); const size_t cacheSize = ChooseCacheSize(); g_VFS = CreateVfs(cacheSize); - g_VFS->Mount("screenshots/", paths.Data()/"screenshots"); - g_VFS->Mount("config/", paths.RData()/"config"); - g_VFS->Mount("profiles/", paths.Config()/"profiles"); - g_VFS->Mount("cache/", paths.Cache(), VFS_MOUNT_ARCHIVABLE); // (adding XMBs to archive speeds up subsequent reads) + g_VFS->Mount(L"screenshots/", paths.Data()/L"screenshots"); + g_VFS->Mount(L"config/", paths.RData()/L"config"); + g_VFS->Mount(L"profiles/", paths.Config()/L"profiles"); + g_VFS->Mount(L"cache/", paths.Cache(), VFS_MOUNT_ARCHIVABLE); // (adding XMBs to archive speeds up subsequent reads) std::vector mods = args.GetMultiple("mod"); mods.push_back("public"); if(!args.Has("onlyPublicFiles")) mods.push_back("internal"); - fs::path modArchivePath(paths.Cache()/"mods"); - fs::path modLoosePath(paths.RData()/"mods"); + fs::wpath modArchivePath(paths.Cache()/L"mods"); + fs::wpath modLoosePath(paths.RData()/L"mods"); for (size_t i = 0; i < mods.size(); ++i) { size_t priority = i; const int flags = VFS_MOUNT_WATCH|VFS_MOUNT_ARCHIVABLE; - const std::string modName = mods[i]; - g_VFS->Mount("", modLoosePath/modName, flags, priority); - g_VFS->Mount("", modArchivePath/modName, flags, priority); + const CStrW modName(mods[i]); + g_VFS->Mount(L"", modLoosePath/modName, flags, priority); + g_VFS->Mount(L"", modArchivePath/modName, flags, priority); } // don't try g_VFS->Display yet: SDL_Init hasn't yet redirected stdout @@ -584,12 +584,12 @@ static void InitPs(bool setup_gui) { // console - TIMER("ps_console"); + TIMER(L"ps_console"); g_Console->UpdateScreenSize(g_xres, g_yres); // Calculate and store the line spacing - CFont font("console"); + CFont font(L"console"); g_Console->m_iFontHeight = font.GetLineSpacing(); g_Console->m_iFontWidth = font.GetCharacterWidth(L'C'); g_Console->m_charsPerPage = (size_t)(g_xres / g_Console->m_iFontWidth); @@ -599,7 +599,7 @@ static void InitPs(bool setup_gui) // language and hotkeys { - TIMER("ps_lang_hotkeys"); + TIMER(L"ps_lang_hotkeys"); std::string lang = "english"; CFG_GET_SYS_VAL("language", String, lang); @@ -657,7 +657,7 @@ static void ShutdownPs() static void InitRenderer() { - TIMER("InitRenderer"); + TIMER(L"InitRenderer"); if(g_NoGLS3TC) ogl_tex_override(OGL_TEX_S3TC, OGL_TEX_DISABLE); @@ -706,7 +706,7 @@ static void InitSDL() MICROLOG(L"init sdl"); if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_NOPARACHUTE) < 0) { - LOG(CLogger::Error, LOG_CATEGORY, "SDL library initialization failed: %s", SDL_GetError()); + LOG(CLogger::Error, LOG_CATEGORY, L"SDL library initialization failed: %hs", SDL_GetError()); throw PSERROR_System_SDLInitFailed(); } atexit(SDL_Quit); @@ -741,68 +741,68 @@ void Shutdown(int flags) ShutdownPs(); // Must delete g_GUI before g_ScriptingHost - TIMER_BEGIN("shutdown Scheduler"); + TIMER_BEGIN(L"shutdown Scheduler"); delete &g_Scheduler; - TIMER_END("shutdown Scheduler"); + TIMER_END(L"shutdown Scheduler"); delete &g_JSGameEvents; if (! (flags & INIT_NO_SIM)) { - TIMER_BEGIN("shutdown mouse stuff"); + TIMER_BEGIN(L"shutdown mouse stuff"); delete &g_Mouseover; delete &g_Selection; delete &g_BuildingPlacer; - TIMER_END("shutdown mouse stuff"); + TIMER_END(L"shutdown mouse stuff"); - TIMER_BEGIN("shutdown game scripting stuff"); + TIMER_BEGIN(L"shutdown game scripting stuff"); delete &g_GameAttributes; SimulationShutdown(); - TIMER_END("shutdown game scripting stuff"); + TIMER_END(L"shutdown game scripting stuff"); } // destroy actor related stuff - TIMER_BEGIN("shutdown actor stuff"); + TIMER_BEGIN(L"shutdown actor stuff"); delete &g_MaterialManager; - TIMER_END("shutdown actor stuff"); + TIMER_END(L"shutdown actor stuff"); // destroy terrain related stuff - TIMER_BEGIN("shutdown TexMan"); + TIMER_BEGIN(L"shutdown TexMan"); delete &g_TexMan; - TIMER_END("shutdown TexMan"); + TIMER_END(L"shutdown TexMan"); // destroy renderer - TIMER_BEGIN("shutdown Renderer"); + TIMER_BEGIN(L"shutdown Renderer"); delete &g_Renderer; g_VBMan.Shutdown(); - TIMER_END("shutdown Renderer"); + TIMER_END(L"shutdown Renderer"); - TIMER_BEGIN("shutdown ScriptingHost"); + TIMER_BEGIN(L"shutdown ScriptingHost"); delete &g_ScriptingHost; - TIMER_END("shutdown ScriptingHost"); + TIMER_END(L"shutdown ScriptingHost"); - TIMER_BEGIN("shutdown ConfigDB"); + TIMER_BEGIN(L"shutdown ConfigDB"); delete &g_ConfigDB; - TIMER_END("shutdown ConfigDB"); + TIMER_END(L"shutdown ConfigDB"); // Shut down the network loop - TIMER_BEGIN("shutdown CSocketBase"); + TIMER_BEGIN(L"shutdown CSocketBase"); CSocketBase::Shutdown(); - TIMER_END("shutdown CSocketBase"); + TIMER_END(L"shutdown CSocketBase"); - TIMER_BEGIN("shutdown CNetLogManager"); + TIMER_BEGIN(L"shutdown CNetLogManager"); CNetLogManager::Shutdown(); - TIMER_END("shutdown CNetLogManager"); + TIMER_END(L"shutdown CNetLogManager"); // Really shut down the i18n system. Any future calls // to translate() will crash. - TIMER_BEGIN("shutdown I18N"); + TIMER_BEGIN(L"shutdown I18N"); I18n::Shutdown(); - TIMER_END("shutdown I18N"); + TIMER_END(L"shutdown I18N"); // resource // first shut down all resource owners, and then the handle manager. - TIMER_BEGIN("resource modules"); + TIMER_BEGIN(L"resource modules"); snd_shutdown(); g_VFS.reset(); @@ -811,16 +811,16 @@ void Shutdown(int flags) // and makes further access to h_mgr impossible. h_mgr_shutdown(); - TIMER_END("resource modules"); + TIMER_END(L"resource modules"); - TIMER_BEGIN("shutdown misc"); + TIMER_BEGIN(L"shutdown misc"); timer_DisplayClientTotals(); // should be last, since the above use them SAFE_DELETE(g_Logger); delete &g_Profiler; delete &g_ProfileViewer; - TIMER_END("shutdown misc"); + TIMER_END(L"shutdown misc"); } void EarlyInit() @@ -828,12 +828,12 @@ void EarlyInit() MICROLOG(L"EarlyInit"); // If you ever want to catch a particular allocation: - //_CrtSetBreakAlloc(321); + //_CrtSetBreakAlloc(232647); debug_SetThreadName("main"); // add all debug_printf "tags" that we are interested in: - debug_filter_add("TIMER"); - debug_filter_add("HRT"); + debug_filter_add(L"TIMER"); + debug_filter_add(L"HRT"); cpu_ConfigureFloatingPoint(); @@ -917,7 +917,7 @@ void Init(const CmdLineArgs& args, int flags) MICROLOG(L"SetVideoMode"); if(SetVideoMode(g_xres, g_yres, 32, !windowed) < 0) { - LOG(CLogger::Error, LOG_CATEGORY, "Could not set %dx%d graphics mode: %s", g_xres, g_yres, SDL_GetError()); + LOG(CLogger::Error, LOG_CATEGORY, L"Could not set %dx%d graphics mode: %hs", g_xres, g_yres, SDL_GetError()); throw PSERROR_System_VmodeFailed(); } @@ -997,7 +997,7 @@ void Init(const CmdLineArgs& args, int flags) SimulationInit(); { - TIMER("Init_miscgamesection"); + TIMER(L"Init_miscgamesection"); new CSelectedEntities; new CMouseoverEntities; new CBuildingPlacer; @@ -1013,7 +1013,7 @@ void Init(const CmdLineArgs& args, int flags) ogl_WarnIfError(); { - TIMER("Init_guiload"); + TIMER(L"Init_guiload"); g_GUI.SendEventToAll("load"); } diff --git a/source/ps/GameSetup/Paths.cpp b/source/ps/GameSetup/Paths.cpp index 55171b0d66..0db4c7780a 100644 --- a/source/ps/GameSetup/Paths.cpp +++ b/source/ps/GameSetup/Paths.cpp @@ -18,8 +18,9 @@ #include "precompiled.h" #include "Paths.h" +#include "lib/path_util.h" #if OS_WIN -#include "lib/sysdep/os/win/wutil.h" // win_appdata_dir +#include "lib/sysdep/os/win/wutil.h" // wutil_AppdataPath #endif #include "lib/sysdep/sysdep.h" // sys_get_executable_name @@ -27,29 +28,29 @@ Paths::Paths(const CmdLineArgs& args) { m_root = Root(args.GetArg0()); - m_rdata = m_root/"data"; - const char* subdirectoryName = args.Has("writableRoot")? 0 : "0ad"; + m_rdata = m_root/L"data"; + const wchar_t* subdirectoryName = args.Has("writableRoot")? 0 : L"0ad"; // everything is a subdirectory of the root if(!subdirectoryName) { m_data = m_rdata; - m_config = m_data/"config"; - m_cache = m_data/"cache"; - m_logs = m_root/"logs"; + m_config = m_data/L"config"; + m_cache = m_data/L"cache"; + m_logs = m_root/L"logs"; } else { #if OS_WIN - const fs::path appdata(fs::path(win_appdata_dir)/subdirectoryName); - m_data = appdata/"data"; - m_config = appdata/"config"; - m_cache = appdata/"cache"; - m_logs = appdata/"logs"; + const fs::wpath appdata(wutil_AppdataPath()/subdirectoryName); + m_data = appdata/L"data"; + m_config = appdata/L"config"; + m_cache = appdata/L"cache"; + m_logs = appdata/L"logs"; #else const char* envHome = getenv("HOME"); debug_assert(envHome); - const fs::path home(envHome); + const fs::wpath home(envHome); m_data = XDG_Path("XDG_DATA_HOME", home, home/".local/share")/subdirectoryName; m_config = XDG_Path("XDG_CONFIG_HOME", home, home/".config")/subdirectoryName; m_cache = XDG_Path("XDG_CACHE_HOME", home, home/".cache")/subdirectoryName; @@ -59,39 +60,39 @@ Paths::Paths(const CmdLineArgs& args) } -/*static*/ fs::path Paths::Root(const CStr& argv0) +/*static*/ fs::wpath Paths::Root(const CStr& argv0) { // get full path to executable - char pathname[PATH_MAX]; + fs::wpath pathname; // .. first try safe, but system-dependent version - if(sys_get_executable_name(pathname, PATH_MAX) < 0) + if(sys_get_executable_name(pathname) != INFO::OK) { // .. failed; use argv[0] + char pathname_c[PATH_MAX]; errno = 0; - if(!realpath(argv0.c_str(), pathname)) + if(!realpath(argv0.c_str(), pathname_c)) WARN_ERR(LibError_from_errno(false)); + pathname = wpath_from_path(pathname_c); } // make sure it's valid - errno = 0; - if(access(pathname, X_OK) < 0) + if(!fs::exists(pathname)) WARN_ERR(LibError_from_errno(false)); - fs::path path(pathname); for(size_t i = 0; i < 3; i++) // remove "system/name.exe" - path.remove_leaf(); - return path; + pathname.remove_leaf(); + return pathname; } -/*static*/ fs::path Paths::XDG_Path(const char* envname, const fs::path& home, const fs::path& defaultPath) +/*static*/ fs::wpath Paths::XDG_Path(const char* envname, const fs::wpath& home, const fs::wpath& defaultPath) { const char* path = getenv(envname); if(path) { if(path[0] != '/') // relative to $HOME - return home/path; - return fs::path(path); + return home/CStrW(path); + return fs::wpath(CStrW(path)); } return defaultPath; } diff --git a/source/ps/GameSetup/Paths.h b/source/ps/GameSetup/Paths.h index 87c829020b..a7b32a1928 100644 --- a/source/ps/GameSetup/Paths.h +++ b/source/ps/GameSetup/Paths.h @@ -25,49 +25,49 @@ class Paths public: Paths(const CmdLineArgs& args); - const fs::path& Root() const + const fs::wpath& Root() const { return m_root; } - const fs::path& RData() const + const fs::wpath& RData() const { return m_rdata; } - const fs::path& Data() const + const fs::wpath& Data() const { return m_data; } - const fs::path& Config() const + const fs::wpath& Config() const { return m_config; } - const fs::path& Cache() const + const fs::wpath& Cache() const { return m_cache; } - const fs::path& Logs() const + const fs::wpath& Logs() const { return m_logs; } private: - static fs::path Root(const CStr& argv0); - static fs::path XDG_Path(const char* envname, const fs::path& home, const fs::path& defaultPath); + static fs::wpath Root(const CStr& argv0); + static fs::wpath XDG_Path(const char* envname, const fs::wpath& home, const fs::wpath& defaultPath); // read-only directories, fixed paths relative to executable - fs::path m_root; - fs::path m_rdata; + fs::wpath m_root; + fs::wpath m_rdata; // writable directories - fs::path m_data; - fs::path m_config; - fs::path m_cache; - fs::path m_logs; // special-cased in single-root-folder installations + fs::wpath m_data; + fs::wpath m_config; + fs::wpath m_cache; + fs::wpath m_logs; // special-cased in single-root-folder installations }; #endif // #ifndef INCLUDED_PS_GAMESETUP_PATHS diff --git a/source/ps/Globals.cpp b/source/ps/Globals.cpp index 0d456088e0..7f76b98266 100644 --- a/source/ps/Globals.cpp +++ b/source/ps/Globals.cpp @@ -60,7 +60,7 @@ InReaction GlobalsInputHandler(const SDL_Event_* ev) else { // don't complain: just ignore people with too many mouse buttons - //debug_warn("invalid mouse button"); + //debug_warn(L"invalid mouse button"); } return IN_PASS; @@ -73,7 +73,7 @@ InReaction GlobalsInputHandler(const SDL_Event_* ev) { // don't complain: this happens when the hotkey system // spoofs keys (it assigns values starting from SDLK_LAST) - //debug_warn("invalid key"); + //debug_warn(L"invalid key"); } return IN_PASS; diff --git a/source/ps/Hotkey.cpp b/source/ps/Hotkey.cpp index b03fda880d..4647b4a5c3 100644 --- a/source/ps/Hotkey.cpp +++ b/source/ps/Hotkey.cpp @@ -241,7 +241,7 @@ static void setBindings( const CStr& hotkeyName, int integerMapping = -1 ) if( !mapping ) if( !it->GetInt( mapping ) ) // Attempt decode as key code { - LOG(CLogger::Warning, "hotkey", "Couldn't map '%s'", hotkey.c_str() ); + LOG(CLogger::Warning, L"hotkey", L"Couldn't map '%hs'", hotkey.c_str() ); continue; } @@ -477,8 +477,8 @@ InReaction HotkeyInputHandler( const SDL_Event_* ev ) } else { - debug_printf("keyCode = %i\n", keyCode); - debug_warn("keyCode out of range in GUI hotkey requirements"); + debug_printf(L"keyCode = %i\n", keyCode); + debug_warn(L"keyCode out of range in GUI hotkey requirements"); } // If this event requires a multiple keypress (with the exception @@ -546,8 +546,8 @@ InReaction HotkeyInputHandler( const SDL_Event_* ev ) } else { - debug_printf("keyCode = %i\n", keyCode); - debug_warn("keyCode out of range in GUI hotkey requirements"); + debug_printf(L"keyCode = %i\n", keyCode); + debug_warn(L"keyCode out of range in GUI hotkey requirements"); } // If this event requires a multiple keypress (with the exception diff --git a/source/ps/Interact.cpp b/source/ps/Interact.cpp index f2b5bb4602..902512d727 100644 --- a/source/ps/Interact.cpp +++ b/source/ps/Interact.cpp @@ -55,9 +55,9 @@ #include "simulation/TerritoryManager.h" #include "ps/CLogger.h" -#define LOG_CATEGORY "world" +#define LOG_CATEGORY L"world" -extern CStr g_CursorName; +extern CStrW g_CursorName; extern float g_xres, g_yres; static const double SELECT_DBLCLICK_RATE = 0.5; @@ -429,7 +429,7 @@ void CSelectedEntities::LoadGroup( i8 groupid ) if( groupid >= MAX_GROUPS ) { - debug_warn( "Invalid group id" ); + debug_warn( L"Invalid group id" ); return; } @@ -974,30 +974,30 @@ void CMouseoverEntities::RenderRallyPoints() // Helper function for CSelectedEntities::LoadUnitUiTextures static LibError LoadUnitUIThunk( const VfsPath& pathname, const FileInfo& UNUSED(fileInfo), uintptr_t cbData ) { - std::map* textures = (std::map*)cbData; - CStr name(pathname.string()); + CSelectedEntities::MapFilenameToHandle* textures = (CSelectedEntities::MapFilenameToHandle*)cbData; - if ( !tex_is_known_extension(name.c_str()) ) + if ( !tex_is_known_extension(pathname) ) return INFO::CB_CONTINUE; - Handle tmp = ogl_tex_load(name.c_str()); - if (tmp <= 0) + Handle ht = ogl_tex_load(pathname); + if (ht <= 0) { - LOG(CLogger::Error, LOG_CATEGORY, "loadRankTextures failed on \"%s\"", name.c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"loadRankTextures failed on \"%ls\"", pathname.string().c_str()); return INFO::CB_CONTINUE; } - name.Remove("art/textures/ui/session/icons/"); //Names are relative to this directory - (*textures)[name] = tmp; - ogl_tex_upload(tmp); + CStrW filename = pathname.string(); + filename.Remove(L"art/textures/ui/session/icons/"); //Names are relative to this directory + (*textures)[filename] = ht; + ogl_tex_upload(ht); return INFO::CB_CONTINUE; } int CSelectedEntities::LoadUnitUiTextures() { - THROW_ERR( fs_util::ForEachFile(g_VFS, "art/textures/ui/session/icons/", LoadUnitUIThunk, (uintptr_t)&m_unitUITextures, 0, fs_util::DIR_RECURSIVE)); + THROW_ERR( fs_util::ForEachFile(g_VFS, L"art/textures/ui/session/icons/", LoadUnitUIThunk, (uintptr_t)&m_unitUITextures, 0, fs_util::DIR_RECURSIVE)); return 0; } void CSelectedEntities::DestroyUnitUiTextures() { - for ( std::map::iterator it=m_unitUITextures.begin(); it != m_unitUITextures.end(); it++ ) + for ( MapFilenameToHandle::iterator it=m_unitUITextures.begin(); it != m_unitUITextures.end(); it++ ) { ogl_tex_free(it->second); it->second = 0; @@ -1062,7 +1062,7 @@ void CMouseoverEntities::StopBandbox() void FireWorldClickEvent(int button, int clicks) { - //debug_printf("FireWorldClickEvent: button %d, clicks %d\n", button, clicks); + //debug_printf(L"FireWorldClickEvent: button %d, clicks %d\n", button, clicks); //If we're clicking on the minimap, use its world click handler if ( g_Selection.m_mouseOverMM ) diff --git a/source/ps/Interact.h b/source/ps/Interact.h index 2a0c8e3a22..af794e5949 100644 --- a/source/ps/Interact.h +++ b/source/ps/Interact.h @@ -104,7 +104,8 @@ struct CSelectedEntities : public Singleton void DestroyUnitUiTextures(); int LoadUnitUiTextures(); - std::map m_unitUITextures; + typedef std::map MapFilenameToHandle; + MapFilenameToHandle m_unitUITextures; }; // CMouseoverEntities: the singleton containing entities the mouse is currently hovering over or bandboxing diff --git a/source/ps/Loader.cpp b/source/ps/Loader.cpp index e64d7cef66..92dac41ccb 100644 --- a/source/ps/Loader.cpp +++ b/source/ps/Loader.cpp @@ -239,7 +239,7 @@ LibError LDR_ProgressiveLoad(double time_budget, wchar_t* description, size_t ma // either finished entirely, or failed => remove from queue. if(!timed_out) { - debug_printf("LOADER| completed %ls in %g ms; estimate was %g ms\n", lr.description.c_str(), task_elapsed_time*1e3, estimated_duration*1e3); + debug_printf(L"LOADER| completed %ls in %g ms; estimate was %g ms\n", lr.description.c_str(), task_elapsed_time*1e3, estimated_duration*1e3); task_elapsed_time = 0.0; estimated_duration_tally += estimated_duration; load_requests.pop_front(); @@ -295,7 +295,7 @@ done: new_description = load_requests.front().description.c_str(); wcscpy_s(description, max_chars, new_description); - debug_printf("LOADER| returning; desc=%ls progress=%d\n", description, *progress_percent); + debug_printf(L"LOADER| returning; desc=%ls progress=%d\n", description, *progress_percent); return ret; } @@ -317,7 +317,7 @@ LibError LDR_NonprogressiveLoad() switch(ret) { case INFO::OK: - debug_warn("No load in progress"); + debug_warn(L"No load in progress"); return INFO::OK; case INFO::ALL_COMPLETE: return INFO::OK; diff --git a/source/ps/ProfileViewer.cpp b/source/ps/ProfileViewer.cpp index 4df93a5c36..93d2bb775e 100644 --- a/source/ps/ProfileViewer.cpp +++ b/source/ps/ProfileViewer.cpp @@ -34,6 +34,7 @@ #include "ps/CLogger.h" #include "lib/external_libraries/sdl.h" +#define LOG_CATEGORY L"profiler" extern int g_xres, g_yres; struct CProfileViewerInternals @@ -428,12 +429,12 @@ void CProfileViewer::SaveToFile() { // Open the file. (It will be closed when the CProfileViewer // destructor is called.) - fs::path path(fs::path(psLogDir())/"profile.txt"); + fs::wpath path(fs::wpath(psLogDir())/L"profile.txt"); m->outputStream.open(path.external_file_string().c_str(), std::ofstream::out | std::ofstream::trunc); if (m->outputStream.fail()) { - LOG(CLogger::Error, "profiler", "Failed to open profile log file"); + LOG(CLogger::Error, LOG_CATEGORY, L"Failed to open profile log file"); return; } } diff --git a/source/ps/Pyrogenesis.cpp b/source/ps/Pyrogenesis.cpp index 0fa6e36b06..730b31d8f1 100644 --- a/source/ps/Pyrogenesis.cpp +++ b/source/ps/Pyrogenesis.cpp @@ -65,9 +65,10 @@ void psTranslateFree(const wchar_t* text) // convert contents of file from char to wchar_t and // append to file. -static void AppendAsciiFile(FILE* out, const char* in_filename) +static void AppendAsciiFile(FILE* out, const fs::wpath& pathname) { - FILE* in = fopen(in_filename, "rb"); + const fs::path pathname_c = path_from_wpath(pathname); + FILE* in = fopen(pathname_c.external_file_string().c_str(), "rb"); if(!in) { fwprintf(out, L"(unavailable)"); @@ -95,25 +96,25 @@ void psBundleLogs(FILE* f) fwprintf(f, L"SVN Revision: %ls\n\n", svn_revision); fwprintf(f, L"System info:\n\n"); - fs::path path1(fs::path(psLogDir())/"system_info.txt"); - AppendAsciiFile(f, path1.external_file_string().c_str()); + fs::wpath path1(fs::wpath(psLogDir())/L"system_info.txt"); + AppendAsciiFile(f, path1); fwprintf(f, L"\n\n====================================\n\n"); fwprintf(f, L"Main log:\n\n"); - fs::path path2(fs::path(psLogDir())/"mainlog.html"); - AppendAsciiFile(f, path2.external_file_string().c_str()); + fs::wpath path2(fs::wpath(psLogDir())/L"mainlog.html"); + AppendAsciiFile(f, path2); fwprintf(f, L"\n\n====================================\n\n"); } -static char logDir[PATH_MAX]; +static fs::wpath logDir; -void psSetLogDir(const char* path) +void psSetLogDir(const fs::wpath& newLogDir) { - path_copy(logDir, path); + logDir = newLogDir; } -const char* psLogDir() +const fs::wpath& psLogDir() { return logDir; } diff --git a/source/ps/Pyrogenesis.h b/source/ps/Pyrogenesis.h index 6c3b56732e..e13cab0fc5 100644 --- a/source/ps/Pyrogenesis.h +++ b/source/ps/Pyrogenesis.h @@ -42,7 +42,7 @@ extern const wchar_t* psTranslate(const wchar_t* text); extern void psTranslateFree(const wchar_t* text); extern void psBundleLogs(FILE* f); -extern void psSetLogDir(const char* path); // set during InitVfs -extern const char* psLogDir(); // used by AppHooks and engine code when reporting errors +extern void psSetLogDir(const fs::wpath& logDir); // set during InitVfs +extern const fs::wpath& psLogDir(); // used by AppHooks and engine code when reporting errors #endif diff --git a/source/ps/Util.cpp b/source/ps/Util.cpp index 1ad9d85d10..e95f1bf21d 100644 --- a/source/ps/Util.cpp +++ b/source/ps/Util.cpp @@ -63,7 +63,7 @@ static std::string SplitExts(const char *exts) void WriteSystemInfo() { - TIMER("write_sys_info"); + TIMER(L"write_sys_info"); // get_cpu_info and gfx_detect already called during init - see call site snd_detect(); @@ -71,21 +71,22 @@ void WriteSystemInfo() struct utsname un; uname(&un); - fs::path pathname(fs::path(psLogDir())/"system_info.txt"); - FILE* f = fopen(pathname.external_file_string().c_str(), "w"); + fs::wpath pathname(fs::wpath(psLogDir())/L"system_info.txt"); + const fs::path pathname_c = path_from_wpath(pathname); + FILE* f = fopen(pathname_c.string().c_str(), "w"); if(!f) return; // current timestamp (redundant WRT OS timestamp, but that is not // visible when people are posting this file's contents online) { - char timestamp_buf[100] = {'\0'}; + wchar_t timestampBuf[100] = {'\0'}; time_t seconds; time(&seconds); struct tm* t = gmtime(&seconds); - const size_t chars_written = strftime(timestamp_buf, ARRAY_SIZE(timestamp_buf), "(generated %Y-%m-%d %H:%M:%S UTC)", t); - debug_assert(chars_written != 0); - fprintf(f, "%s\n\n", timestamp_buf); + const size_t charsWritten = wcsftime(timestampBuf, ARRAY_SIZE(timestampBuf), L"(generated %Y-%m-%d %H:%M:%S UTC)", t); + debug_assert(charsWritten != 0); + fwprintf(f, L"%ls\n\n", timestampBuf); } // OS @@ -109,13 +110,13 @@ void WriteSystemInfo() fprintf(f, "Memory : %u MiB; %u MiB free\n", (unsigned)os_cpu_MemorySize(), (unsigned)os_cpu_MemoryAvailable()); // graphics - fprintf(f, "Graphics Card : %s\n", gfx_card); - fprintf(f, "OpenGL Drivers : %s; %s\n", glGetString(GL_VERSION), gfx_drv_ver); + fwprintf(f, L"Graphics Card : %ls\n", gfx_card); + fprintf(f, "OpenGL Drivers : %s; %ls\n", glGetString(GL_VERSION), gfx_drv_ver); fprintf(f, "Video Mode : %dx%d:%d@%d\n", g_xres, g_yres, g_bpp, g_freq); // sound - fprintf(f, "Sound Card : %s\n", snd_card); - fprintf(f, "Sound Drivers : %s\n", snd_drv_ver); + fwprintf(f, L"Sound Card : %ls\n", snd_card); + fwprintf(f, L"Sound Drivers : %ls\n", snd_drv_ver); // @@ -168,11 +169,9 @@ no_ip: // not thread-safe! static const wchar_t* HardcodedErrorString(int err) { - char description[200]; + static wchar_t description[200]; error_description_r((LibError)err, description, ARRAY_SIZE(description)); - static wchar_t output_buf[200]; - mbstowcs(output_buf, description, ARRAY_SIZE(output_buf)); - return output_buf; + return description; } // not thread-safe! @@ -191,7 +190,7 @@ const wchar_t* ErrorString(int err) // transformed to write it out in the format determined by 's extension. static LibError tex_write(Tex* t, const VfsPath& filename) { - const std::string extension = fs::extension(filename); + const std::wstring extension = fs::extension(filename); DynArray da; RETURN_ERR(tex_encode(t, extension, &da)); @@ -218,11 +217,11 @@ static size_t s_nextScreenshotNumber; // identifies the file format that is to be written // (case-insensitive). examples: "bmp", "png", "jpg". // BMP is good for quick output at the expense of large files. -void WriteScreenshot(const char* extension) +void WriteScreenshot(const std::wstring& extension) { // get next available numbered filename // note: %04d -> always 4 digits, so sorting by filename works correctly. - const VfsPath basenameFormat("screenshots/screenshot%04d"); + const VfsPath basenameFormat(L"screenshots/screenshot%04d"); const VfsPath filenameFormat = fs::change_extension(basenameFormat, extension); VfsPath filename; fs_util::NextNumberedFilename(g_VFS, filenameFormat, s_nextScreenshotNumber, filename); @@ -233,7 +232,7 @@ void WriteScreenshot(const char* extension) int flags = TEX_BOTTOM_UP; // we want writing BMP to be as fast as possible, // so read data from OpenGL in BMP format to obviate conversion. - if(!strcasecmp(extension, "bmp")) + if(!wcscasecmp(extension.c_str(), L".bmp")) { fmt = GL_BGR; flags |= TEX_BGR; @@ -254,14 +253,14 @@ void WriteScreenshot(const char* extension) // Similar to WriteScreenshot, but generates an image of size 640*tiles x 480*tiles. -void WriteBigScreenshot(const char* extension, int tiles) +void WriteBigScreenshot(const std::wstring& extension, int tiles) { // If the game hasn't started yet then use WriteScreenshot to generate the image. - if(g_Game == NULL){ WriteScreenshot(".bmp"); return; } + if(g_Game == NULL){ WriteScreenshot(L".bmp"); return; } // get next available numbered filename // note: %04d -> always 4 digits, so sorting by filename works correctly. - const VfsPath basenameFormat("screenshots/screenshot%04d"); + const VfsPath basenameFormat(L"screenshots/screenshot%04d"); const VfsPath filenameFormat = fs::change_extension(basenameFormat, extension); VfsPath filename; fs_util::NextNumberedFilename(g_VFS, filenameFormat, s_nextScreenshotNumber, filename); @@ -277,7 +276,7 @@ void WriteBigScreenshot(const char* extension, int tiles) int flags = TEX_BOTTOM_UP; // we want writing BMP to be as fast as possible, // so read data from OpenGL in BMP format to obviate conversion. - if(!strcasecmp(extension, "bmp")) + if(!wcscasecmp(extension.c_str(), L".bmp")) { fmt = GL_BGR; flags |= TEX_BGR; diff --git a/source/ps/Util.h b/source/ps/Util.h index bbfece712c..f6412732fa 100644 --- a/source/ps/Util.h +++ b/source/ps/Util.h @@ -19,5 +19,5 @@ extern void WriteSystemInfo(); extern const wchar_t* ErrorString(int err); -extern void WriteScreenshot(const char* extension); -extern void WriteBigScreenshot(const char* extension, int tiles); +extern void WriteScreenshot(const std::wstring& extension); +extern void WriteBigScreenshot(const std::wstring& extension, int tiles); diff --git a/source/ps/World.cpp b/source/ps/World.cpp index 14187a28a9..d8cccfde00 100644 --- a/source/ps/World.cpp +++ b/source/ps/World.cpp @@ -47,7 +47,7 @@ #include "simulation/TerritoryManager.h" #include "simulation/Projectile.h" -#define LOG_CATEGORY "world" +#define LOG_CATEGORY L"world" /** * Global light settings. @@ -86,10 +86,7 @@ void CWorld::Initialize(CGameAttributes *pAttribs) // Load the map, if one was specified if (pAttribs->m_MapFile.length()) { - CStr mapfilename("maps/scenarios/"); - - mapfilename += (CStr)pAttribs->m_MapFile; - + VfsPath mapfilename(VfsPath(L"maps/scenarios/")/pAttribs->m_MapFile); CMapReader* reader = 0; try { @@ -99,7 +96,7 @@ void CWorld::Initialize(CGameAttributes *pAttribs) // fails immediately, or registers for delay loading } catch (PSERROR_File&) { delete reader; - LOG(CLogger::Error, LOG_CATEGORY, "Failed to load map %s", mapfilename.c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"Failed to load map %ls", mapfilename.string().c_str()); throw PSERROR_Game_World_MapLoadFailed(); } } diff --git a/source/ps/XML/XMLWriter.cpp b/source/ps/XML/XMLWriter.cpp index 25120e713b..d0ad006e71 100644 --- a/source/ps/XML/XMLWriter.cpp +++ b/source/ps/XML/XMLWriter.cpp @@ -22,6 +22,8 @@ #include "ps/CLogger.h" #include "ps/Filesystem.h" +#define LOG_CATEGORY L"xml" + // TODO (maybe): Write to the file frequently, instead of buffering // the entire file, so that large files get written faster. @@ -79,17 +81,17 @@ XMLWriter_File::XMLWriter_File() m_Data = "\n"; } -bool XMLWriter_File::StoreVFS(const char* filename) +bool XMLWriter_File::StoreVFS(const VfsPath& pathname) { - if (m_LastElement) debug_warn("ERROR: Saving XML while an element is still open"); + if (m_LastElement) debug_warn(L"ERROR: Saving XML while an element is still open"); const size_t size = m_Data.length(); shared_ptr data = io_Allocate(size); cpu_memcpy(data.get(), m_Data.data(), size); - LibError ret = g_VFS->CreateFile(filename, data, size); + LibError ret = g_VFS->CreateFile(pathname, data, size); if (ret < 0) { - LOG(CLogger::Error, "xml", "Error saving XML data through VFS: %ld", ret); + LOG(CLogger::Error, LOG_CATEGORY, L"Error saving XML data through VFS: %ld", ret); return false; } return true; diff --git a/source/ps/XML/XMLWriter.h b/source/ps/XML/XMLWriter.h index b1f0fa5943..d63bfc10e6 100644 --- a/source/ps/XML/XMLWriter.h +++ b/source/ps/XML/XMLWriter.h @@ -90,7 +90,7 @@ end of XMLWriter.cpp. // Create a VFS file from the XML data. // Returns true on success, false (and logs an error) on failure. -#define XML_StoreVFS(handle) xml_file_.StoreVFS(handle) +#define XML_StoreVFS(pathname) xml_file_.StoreVFS(pathname) // Returns the contents of the XML file as a UTF-8 byte stream in a const CStr& // string. (Use CStr::FromUTF8 to get a Unicode string back.) @@ -98,6 +98,7 @@ end of XMLWriter.cpp. #include "ps/CStr.h" +#include "lib/file/vfs/vfs_path.h" class XMLWriter_Element; @@ -110,7 +111,7 @@ public: void Comment(const char* text); - bool StoreVFS(const char* filename); + bool StoreVFS(const VfsPath& pathname); const CStr& GetOutput(); private: diff --git a/source/ps/XML/Xeromyces.cpp b/source/ps/XML/Xeromyces.cpp index 095dabce58..359b0dfe8e 100644 --- a/source/ps/XML/Xeromyces.cpp +++ b/source/ps/XML/Xeromyces.cpp @@ -29,12 +29,12 @@ #include -#define LOG_CATEGORY "xml" +#define LOG_CATEGORY L"xml" static void errorHandler(void* UNUSED(userData), xmlErrorPtr error) { - LOG(CLogger::Error, LOG_CATEGORY, "CXeromyces: Parse %s: %s:%d: %s", - error->level == XML_ERR_WARNING ? "warning" : "error", + LOG(CLogger::Error, LOG_CATEGORY, L"CXeromyces: Parse %hs: %ls:%d: %hs", + error->level == XML_ERR_WARNING ? L"warning" : L"error", error->file, error->line, error->message); // TODO: The (non-fatal) warnings and errors don't get stored in the XMB, // so the caching is less transparent than it should be @@ -74,21 +74,21 @@ void CXeromyces::GetXMBPath(const PIVFS& vfs, const VfsPath& xmlFilename, const // a subdirectory (which would make manually deleting all harder). // get real path of XML file (e.g. mods/official/entities/...) - fs::path XMBRealPath_; + fs::wpath XMBRealPath_; vfs->GetRealPath(xmlFilename, XMBRealPath_); - char XMBRealPath[PATH_MAX]; + wchar_t XMBRealPath[PATH_MAX]; path_copy(XMBRealPath, XMBRealPath_.string().c_str()); // extract mod name from that - const char* modPath = strstr(XMBRealPath, "mods/"); + const wchar_t* modPath = wcsstr(XMBRealPath, L"mods/"); debug_assert(modPath != 0); - char modName[PATH_MAX]; + wchar_t modName[PATH_MAX]; // .. NOTE: can't use %s, of course (keeps going beyond '/') - int matches = sscanf(modPath, "mods/%[^/]", modName); + int matches = swscanf(modPath, L"mods/%[^/]", modName); debug_assert(matches == 1); // build full name: cache, then mod name, XMB subdir, original XMB path - xmbActualPath = VfsPath("cache/mods") / modName / "xmb" / xmbFilename; + xmbActualPath = VfsPath(L"cache/mods") / modName / L"xmb" / xmbFilename; } PSRETURN CXeromyces::Load(const VfsPath& filename) @@ -98,7 +98,7 @@ PSRETURN CXeromyces::Load(const VfsPath& filename) // Make sure the .xml actually exists if (! FileExists(filename)) { - LOG(CLogger::Error, LOG_CATEGORY, "CXeromyces: Failed to find XML file %s", filename.string().c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"CXeromyces: Failed to find XML file %ls", filename.string().c_str()); return PSRETURN_Xeromyces_XMLOpenFailed; } @@ -106,7 +106,7 @@ PSRETURN CXeromyces::Load(const VfsPath& filename) FileInfo fileInfo; if (g_VFS->GetFileInfo(filename, &fileInfo) < 0) { - LOG(CLogger::Error, LOG_CATEGORY, "CXeromyces: Failed to stat XML file %s", filename.string().c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"CXeromyces: Failed to stat XML file %ls", filename.string().c_str()); return PSRETURN_Xeromyces_XMLOpenFailed; } @@ -131,8 +131,8 @@ PSRETURN CXeromyces::Load(const VfsPath& filename) // with mtime/size as 8-digit hex, where mtime's lowest bit is // zeroed because zip files only have 2 second resolution. const int suffixLength = 22; - char suffix[suffixLength+1]; - int printed = sprintf(suffix, "_%08x%08xB.xmb", (int)(fileInfo.MTime() & ~1), (int)fileInfo.Size()); + wchar_t suffix[suffixLength+1]; + int printed = swprintf_s(suffix, L"_%08x%08xB.xmb", (int)(fileInfo.MTime() & ~1), (int)fileInfo.Size()); debug_assert(printed == suffixLength); VfsPath xmbFilename = change_extension(filename, suffix); @@ -154,15 +154,16 @@ PSRETURN CXeromyces::Load(const VfsPath& filename) CVFSFile input; if (input.Load(filename)) { - LOG(CLogger::Error, LOG_CATEGORY, "CXeromyces: Failed to open XML file %s", filename.string().c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"CXeromyces: Failed to open XML file %ls", filename.string().c_str()); return PSRETURN_Xeromyces_XMLOpenFailed; } + CStr8 filename8(filename.string()); xmlDocPtr doc = xmlReadMemory((const char*)input.GetBuffer(), (int)input.GetBufferSize(), - filename.string().c_str(), NULL, XML_PARSE_NONET|XML_PARSE_NOCDATA); + filename8.c_str(), NULL, XML_PARSE_NONET|XML_PARSE_NOCDATA); if (! doc) { - LOG(CLogger::Error, LOG_CATEGORY, "CXeromyces: Failed to parse XML file %s", filename.string().c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"CXeromyces: Failed to parse XML file %ls", filename.string().c_str()); return PSRETURN_Xeromyces_XMLParseError; } diff --git a/source/ps/XML/tests/test_Xeromyces.h b/source/ps/XML/tests/test_Xeromyces.h index 786bfdd2f8..c10bd7f139 100644 --- a/source/ps/XML/tests/test_Xeromyces.h +++ b/source/ps/XML/tests/test_Xeromyces.h @@ -22,11 +22,11 @@ #include "lib/sysdep/sysdep.h" // FIXME: copied from test_MeshManager -static fs::path DataDir() +static fs::wpath DataDir() { - char path[PATH_MAX]; - TS_ASSERT_OK(sys_get_executable_name(path, ARRAY_SIZE(path))); - return fs::path(path).branch_path()/"../data"; + fs::wpath path; + TS_ASSERT_OK(sys_get_executable_name(path)); + return path.branch_path()/L"../data"; } class TestXeromyces : public CxxTest::TestSuite @@ -36,15 +36,15 @@ public: { PIVFS vfs = CreateVfs(20*MiB); - TS_ASSERT_OK(vfs->Mount("", DataDir()/"mods/_test.xero")); + TS_ASSERT_OK(vfs->Mount(L"", DataDir()/L"mods/_test.xero")); VfsPath xmbPath; - CXeromyces::GetXMBPath(vfs, "test1.xml", "test1.xmb", xmbPath); - TS_ASSERT_STR_EQUALS(xmbPath.string(), "cache/mods/_test.xero/xmb/test1.xmb"); + CXeromyces::GetXMBPath(vfs, L"test1.xml", L"test1.xmb", xmbPath); + TS_ASSERT_WSTR_EQUALS(xmbPath.string(), L"cache/mods/_test.xero/xmb/test1.xmb"); - CXeromyces::GetXMBPath(vfs, "a/b/test1.xml", "a/b/test1.xmb", xmbPath); - TS_ASSERT_STR_EQUALS(xmbPath.string(), "cache/mods/_test.xero/xmb/a/b/test1.xmb"); + CXeromyces::GetXMBPath(vfs, L"a/b/test1.xml", L"a/b/test1.xmb", xmbPath); + TS_ASSERT_WSTR_EQUALS(xmbPath.string(), L"cache/mods/_test.xero/xmb/a/b/test1.xmb"); } // TODO: Should test the reading/parsing/writing code, diff --git a/source/ps/i18n.cpp b/source/ps/i18n.cpp index 56f0aac0f9..64f58145ea 100644 --- a/source/ps/i18n.cpp +++ b/source/ps/i18n.cpp @@ -23,7 +23,7 @@ #include "ps/Filesystem.h" #include "ps/CLogger.h" -#define LOG_CATEGORY "i18n" +#define LOG_CATEGORY L"i18n" // Yay, global variables. (The user only ever wants to be using one language // at a time, so this is sufficient) @@ -51,60 +51,59 @@ bool I18n::LoadLanguage(const char* name) if (! locale_ptr) { - debug_warn("Failed to create locale"); + debug_warn(L"Failed to create locale"); return false; } // Automatically delete the pointer when returning early std::auto_ptr locale (locale_ptr); - CStr dirname = CStr("language/")+name+"/"; + VfsPath dirname = VfsPath(L"language")/CStrW(name)/L"/"; // Open *.lng with LoadStrings VfsPaths pathnames; - if(fs_util::GetPathnames(g_VFS, dirname, "*.lng", pathnames) < 0) + if(fs_util::GetPathnames(g_VFS, dirname, L"*.lng", pathnames) < 0) return false; for (size_t i = 0; i < pathnames.size(); i++) { - const char* pathname = pathnames[i].string().c_str(); CVFSFile strings; - if (! (strings.Load(pathname) == PSRETURN_OK && locale->LoadStrings((const char*)strings.GetBuffer()))) + if (! (strings.Load(pathnames[i]) == PSRETURN_OK && locale->LoadStrings((const char*)strings.GetBuffer()))) { - LOG(CLogger::Error, LOG_CATEGORY, "Error opening language string file '%s'", pathname); + LOG(CLogger::Error, LOG_CATEGORY, L"Error opening language string file '%ls'", pathnames[i].string().c_str()); return false; } } // Open *.wrd with LoadDictionary - if(fs_util::GetPathnames(g_VFS, dirname, "*.wrd", pathnames) < 0) + if(fs_util::GetPathnames(g_VFS, dirname, L"*.wrd", pathnames) < 0) return false; for (size_t i = 0; i < pathnames.size(); i++) { - const char* pathname = pathnames[i].string().c_str(); CVFSFile strings; - if (! (strings.Load(pathname) == PSRETURN_OK && locale->LoadDictionary((const char*)strings.GetBuffer()))) + if (! (strings.Load(pathnames[i]) == PSRETURN_OK && locale->LoadDictionary((const char*)strings.GetBuffer()))) { - LOG(CLogger::Error, LOG_CATEGORY, "Error opening language string file '%s'", pathname); + LOG(CLogger::Error, LOG_CATEGORY, L"Error opening language string file '%ls'", pathnames[i].string().c_str()); return false; } } // Open *.js with LoadFunctions - if(fs_util::GetPathnames(g_VFS, dirname, "*.js", pathnames) < 0) + if(fs_util::GetPathnames(g_VFS, dirname, L"*.js", pathnames) < 0) return false; for (size_t i = 0; i < pathnames.size(); i++) { - const char* pathname = pathnames[i].string().c_str(); + const wchar_t* pathname = pathnames[i].string().c_str(); + CStr8 pathname8(pathname); CVFSFile strings; if (! (strings.Load(pathname) == PSRETURN_OK && locale->LoadFunctions( (const char*)strings.GetBuffer(), strings.GetBufferSize(), - pathname + pathname8.c_str() ))) { - LOG(CLogger::Error, LOG_CATEGORY, "Error opening language function file '%s'", pathname); + LOG(CLogger::Error, LOG_CATEGORY, L"Error opening language function file '%ls'", pathname); return false; } } diff --git a/source/ps/scripting/JSInterface_VFS.cpp b/source/ps/scripting/JSInterface_VFS.cpp index 4d17851191..9ed49f3fbe 100644 --- a/source/ps/scripting/JSInterface_VFS.cpp +++ b/source/ps/scripting/JSInterface_VFS.cpp @@ -96,15 +96,15 @@ JSBool JSI_VFS::BuildDirEntList( JSContext* cx, JSObject* UNUSED(obj), uintN arg if( !ToPrimitive( cx, argv[0], path ) ) return( JS_FALSE ); - CStr filter_str = ""; + CStrW filter_str = L""; if(argc >= 2) { - if( !ToPrimitive( cx, argv[1], filter_str ) ) + if( !ToPrimitive( cx, argv[1], filter_str ) ) return( JS_FALSE ); } - // convert to const char*; if there's no filter, pass 0 for speed + // convert to const wchar_t*; if there's no filter, pass 0 for speed // (interpreted as: "accept all files without comparing"). - const char* filter = 0; + const wchar_t* filter = 0; if(!filter_str.empty()) filter = filter_str.c_str(); @@ -119,7 +119,7 @@ JSBool JSI_VFS::BuildDirEntList( JSContext* cx, JSObject* UNUSED(obj), uintN arg // build array in the callback function BuildDirEntListState state(cx); - fs_util::ForEachFile(g_VFS, path, BuildDirEntListCB, (uintptr_t)&state, filter, flags); + fs_util::ForEachFile(g_VFS, CStrW(path), BuildDirEntListCB, (uintptr_t)&state, filter, flags); *rval = OBJECT_TO_JSVAL( state.filename_array ); return( JS_TRUE ); @@ -138,7 +138,7 @@ JSBool JSI_VFS::GetFileMTime( JSContext* cx, JSObject* UNUSED(obj), uintN argc, return( JS_FALSE ); FileInfo fileInfo; - LibError err = g_VFS->GetFileInfo(filename.c_str(), &fileInfo); + LibError err = g_VFS->GetFileInfo(CStrW(filename), &fileInfo); JS_CHECK_FILE_ERR( err ); *rval = ToJSVal( (double)fileInfo.MTime() ); @@ -158,7 +158,7 @@ JSBool JSI_VFS::GetFileSize( JSContext* cx, JSObject* UNUSED(obj), uintN argc, j return( JS_FALSE ); FileInfo fileInfo; - LibError err = g_VFS->GetFileInfo(filename.c_str(), &fileInfo); + LibError err = g_VFS->GetFileInfo(CStrW(filename), &fileInfo); JS_CHECK_FILE_ERR(err); *rval = ToJSVal( (unsigned)fileInfo.Size() ); @@ -178,7 +178,7 @@ JSBool JSI_VFS::ReadFile( JSContext* cx, JSObject* UNUSED(obj), uintN argc, jsva return( JS_FALSE ); shared_ptr buf; size_t size; - LibError err = g_VFS->LoadFile( filename.c_str(), buf, size ); + LibError err = g_VFS->LoadFile( CStrW(filename), buf, size ); JS_CHECK_FILE_ERR( err ); CStr contents( (const char*)buf.get(), size ); @@ -208,7 +208,7 @@ JSBool JSI_VFS::ReadFileLines( JSContext* cx, JSObject* UNUSED(obj), uintN argc, // shared_ptr buf; size_t size; - LibError err = g_VFS->LoadFile( filename.c_str( ), buf, size ); + LibError err = g_VFS->LoadFile( CStrW(filename), buf, size ); JS_CHECK_FILE_ERR( err ); CStr contents( (const char*)buf.get(), size ); diff --git a/source/ps/tests/test_CLogger.h b/source/ps/tests/test_CLogger.h index 9d8d8a4734..4d5fe3c350 100644 --- a/source/ps/tests/test_CLogger.h +++ b/source/ps/tests/test_CLogger.h @@ -24,37 +24,37 @@ class TestCLogger : public CxxTest::TestSuite public: void test_basic() { - logger->Log(CLogger::Normal, "", "Test 1"); - logger->Log(CLogger::Normal, "", "Test 2"); + logger->Log(CLogger::Normal, L"", L"Test 1"); + logger->Log(CLogger::Normal, L"", L"Test 2"); ParseOutput(); TS_ASSERT_EQUALS((int)lines.size(), 2); - TS_ASSERT_EQUALS(lines[0], "Test 1"); - TS_ASSERT_EQUALS(lines[1], "Test 2"); + TS_ASSERT_EQUALS(lines[0], L"Test 1"); + TS_ASSERT_EQUALS(lines[1], L"Test 2"); } void test_overflow() { const int buflen = 512; - std::string msg0 (buflen-2, '*'); - std::string msg1 (buflen-1, '*'); - std::string msg2 (buflen, '*'); - std::string msg3 (buflen+1, '*'); + std::wstring msg0 (buflen-2, '*'); + std::wstring msg1 (buflen-1, '*'); + std::wstring msg2 (buflen, '*'); + std::wstring msg3 (buflen+1, '*'); - std::string clipped (buflen-4, '*'); - clipped += "..."; + std::wstring clipped (buflen-4, '*'); + clipped += L"..."; - logger->Log(CLogger::Normal, "", "%s", msg0.c_str()); - logger->Log(CLogger::Normal, "", "%s", msg1.c_str()); - logger->Log(CLogger::Normal, "", "%s", msg2.c_str()); - logger->Log(CLogger::Normal, "", "%s", msg3.c_str()); + logger->Log(CLogger::Normal, L"", L"%ls", msg0.c_str()); + logger->Log(CLogger::Normal, L"", L"%ls", msg1.c_str()); + logger->Log(CLogger::Normal, L"", L"%ls", msg2.c_str()); + logger->Log(CLogger::Normal, L"", L"%ls", msg3.c_str()); - logger->LogOnce(CLogger::Normal, "", "%s", msg0.c_str()); - logger->LogOnce(CLogger::Normal, "", "%s", msg1.c_str()); - logger->LogOnce(CLogger::Normal, "", "%s", msg2.c_str()); - logger->LogOnce(CLogger::Normal, "", "%s", msg3.c_str()); + logger->LogOnce(CLogger::Normal, L"", L"%ls", msg0.c_str()); + logger->LogOnce(CLogger::Normal, L"", L"%ls", msg1.c_str()); + logger->LogOnce(CLogger::Normal, L"", L"%ls", msg2.c_str()); + logger->LogOnce(CLogger::Normal, L"", L"%ls", msg3.c_str()); ParseOutput(); @@ -71,14 +71,14 @@ public: ////////////////////////////////////////////////////////////////////////// CLogger* logger; - std::stringstream* mainlog; - std::stringstream* interestinglog; - std::vector lines; + std::wstringstream* mainlog; + std::wstringstream* interestinglog; + std::vector lines; void setUp() { - mainlog = new std::stringstream(); - interestinglog = new std::stringstream(); + mainlog = new std::wstringstream(); + interestinglog = new std::wstringstream(); logger = new CLogger(mainlog, interestinglog, true, true); @@ -93,9 +93,9 @@ public: void ParseOutput() { - const std::string header_end = "\n"; + const std::wstring header_end = L"\n"; - std::string s = mainlog->str(); + std::wstring s = mainlog->str(); size_t start = s.find(header_end); TS_ASSERT_DIFFERS(start, s.npos); s = s.substr(start + header_end.length()); diff --git a/source/renderer/FixedFunctionModelRenderer.cpp b/source/renderer/FixedFunctionModelRenderer.cpp index 0e99f12181..3fa447abd1 100644 --- a/source/renderer/FixedFunctionModelRenderer.cpp +++ b/source/renderer/FixedFunctionModelRenderer.cpp @@ -37,7 +37,7 @@ #include "renderer/VertexArray.h" -#define LOG_CATEGORY "graphics" +#define LOG_CATEGORY L"graphics" /////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/source/renderer/HWLightingModelRenderer.cpp b/source/renderer/HWLightingModelRenderer.cpp index fd0765db69..4ad76252bb 100644 --- a/source/renderer/HWLightingModelRenderer.cpp +++ b/source/renderer/HWLightingModelRenderer.cpp @@ -40,7 +40,7 @@ #include "renderer/VertexArray.h" -#define LOG_CATEGORY "graphics" +#define LOG_CATEGORY L"graphics" /////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/source/renderer/InstancingModelRenderer.cpp b/source/renderer/InstancingModelRenderer.cpp index cb08c90039..d8d0b0afb0 100644 --- a/source/renderer/InstancingModelRenderer.cpp +++ b/source/renderer/InstancingModelRenderer.cpp @@ -40,7 +40,7 @@ #include "renderer/VertexArray.h" -#define LOG_CATEGORY "graphics" +#define LOG_CATEGORY L"graphics" /////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/source/renderer/ModelRenderer.cpp b/source/renderer/ModelRenderer.cpp index 624ee53a8a..6af805558b 100644 --- a/source/renderer/ModelRenderer.cpp +++ b/source/renderer/ModelRenderer.cpp @@ -40,7 +40,7 @@ #include -#define LOG_CATEGORY "graphics" +#define LOG_CATEGORY L"graphics" /////////////////////////////////////////////////////////////////////////////////////////////// @@ -81,7 +81,7 @@ void ModelRenderer::BuildPositionAndNormals( // some broken situations if (numVertices && vertices[0].m_Blend.m_Bone[0] == 0xff) { - LOG_ONCE(CLogger::Error, LOG_CATEGORY, "Model %s is boned with unboned animation", mdef->GetName().c_str()); + LOG_ONCE(CLogger::Error, LOG_CATEGORY, L"Model %ls is boned with unboned animation", mdef->GetName().string().c_str()); return; } @@ -401,7 +401,7 @@ void BatchModelRenderer::EndFrame() if (mdeftracker->m_Slots > mostslots) { mostslots = mdeftracker->m_Slots; - //debug_printf("BatchModelRenderer: SubmissionSlots maximum: %u\n", mostslots); + //debug_printf(L"BatchModelRenderer: SubmissionSlots maximum: %u\n", mostslots); } mdeftracker->m_Slots = 0; } diff --git a/source/renderer/PlayerRenderer.cpp b/source/renderer/PlayerRenderer.cpp index 07e53fa4f4..39c5eaac95 100644 --- a/source/renderer/PlayerRenderer.cpp +++ b/source/renderer/PlayerRenderer.cpp @@ -30,7 +30,7 @@ #include "ps/CLogger.h" -#define LOG_CATEGORY "graphics" +#define LOG_CATEGORY L"graphics" /////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/source/renderer/RenderModifiers.cpp b/source/renderer/RenderModifiers.cpp index 89aaf1036c..348f46f896 100644 --- a/source/renderer/RenderModifiers.cpp +++ b/source/renderer/RenderModifiers.cpp @@ -36,7 +36,7 @@ #include "renderer/Renderer.h" #include "renderer/ShadowMap.h" -#define LOG_CATEGORY "graphics" +#define LOG_CATEGORY L"graphics" @@ -45,7 +45,7 @@ const CMatrix3D* RenderModifier::GetTexGenMatrix(int UNUSED(pass)) { - debug_warn("GetTexGenMatrix not implemented by a derived RenderModifier"); + debug_warn(L"GetTexGenMatrix not implemented by a derived RenderModifier"); return 0; } diff --git a/source/renderer/RenderPathVertexShader.cpp b/source/renderer/RenderPathVertexShader.cpp index b07782f314..09b4c2ed5c 100644 --- a/source/renderer/RenderPathVertexShader.cpp +++ b/source/renderer/RenderPathVertexShader.cpp @@ -23,7 +23,7 @@ #include "renderer/Renderer.h" #include "renderer/RenderPathVertexShader.h" -#define LOG_CATEGORY "graphics" +#define LOG_CATEGORY L"graphics" void VS_GlobalLight::Init(Handle shader) { @@ -77,45 +77,45 @@ bool RenderPathVertexShader::Init() if (!g_Renderer.m_Caps.m_VertexShader) return false; - m_ModelLight = ogl_program_load("shaders/model_light.xml"); + m_ModelLight = ogl_program_load(L"shaders/model_light.xml"); if (m_ModelLight < 0) { - LOG(CLogger::Warning, LOG_CATEGORY, "Failed to load shaders/model_light.xml: %i\n", (int)m_ModelLight); + LOG(CLogger::Warning, LOG_CATEGORY, L"Failed to load shaders/model_light.xml: %i\n", (int)m_ModelLight); return false; } - m_ModelLightP = ogl_program_load("shaders/model_lightp.xml"); + m_ModelLightP = ogl_program_load(L"shaders/model_lightp.xml"); if (m_ModelLightP < 0) { - LOG(CLogger::Warning, LOG_CATEGORY, "Failed to load shaders/model_lightp.xml: %i\n", (int)m_ModelLightP); + LOG(CLogger::Warning, LOG_CATEGORY, L"Failed to load shaders/model_lightp.xml: %i\n", (int)m_ModelLightP); return false; } - m_InstancingLight = ogl_program_load("shaders/instancing_light.xml"); + m_InstancingLight = ogl_program_load(L"shaders/instancing_light.xml"); if (m_InstancingLight < 0) { - LOG(CLogger::Warning, LOG_CATEGORY, "Failed to load shaders/instancing_light.xml: %i\n", (int)m_InstancingLight); + LOG(CLogger::Warning, LOG_CATEGORY, L"Failed to load shaders/instancing_light.xml: %i\n", (int)m_InstancingLight); return false; } - m_InstancingLightP = ogl_program_load("shaders/instancing_lightp.xml"); + m_InstancingLightP = ogl_program_load(L"shaders/instancing_lightp.xml"); if (m_InstancingLightP < 0) { - LOG(CLogger::Warning, LOG_CATEGORY, "Failed to load shaders/instancing_lightp.xml: %i\n", (int)m_InstancingLightP); + LOG(CLogger::Warning, LOG_CATEGORY, L"Failed to load shaders/instancing_lightp.xml: %i\n", (int)m_InstancingLightP); return false; } - m_Instancing = ogl_program_load("shaders/instancing.xml"); + m_Instancing = ogl_program_load(L"shaders/instancing.xml"); if (m_Instancing < 0) { - LOG(CLogger::Warning, LOG_CATEGORY, "Failed to load shaders/instancing.xml: %i\n", (int)m_Instancing); + LOG(CLogger::Warning, LOG_CATEGORY, L"Failed to load shaders/instancing.xml: %i\n", (int)m_Instancing); return false; } - m_InstancingP = ogl_program_load("shaders/instancingp.xml"); + m_InstancingP = ogl_program_load(L"shaders/instancingp.xml"); if (m_InstancingP < 0) { - LOG(CLogger::Warning, LOG_CATEGORY, "Failed to load shaders/instancingp.xml: %i\n", (int)m_InstancingP); + LOG(CLogger::Warning, LOG_CATEGORY, L"Failed to load shaders/instancingp.xml: %i\n", (int)m_InstancingP); return false; } diff --git a/source/renderer/Renderer.cpp b/source/renderer/Renderer.cpp index 4d607089c7..273346d5e1 100644 --- a/source/renderer/Renderer.cpp +++ b/source/renderer/Renderer.cpp @@ -65,7 +65,7 @@ #include "renderer/WaterManager.h" #include "renderer/SkyManager.h" -#define LOG_CATEGORY "graphics" +#define LOG_CATEGORY L"graphics" /////////////////////////////////////////////////////////////////////////////////// @@ -550,11 +550,11 @@ bool CRenderer::Open(int width, int height, int depth) GLint bits; glGetIntegerv(GL_DEPTH_BITS,&bits); - LOG(CLogger::Normal, LOG_CATEGORY, "CRenderer::Open: depth bits %d",bits); + LOG(CLogger::Normal, LOG_CATEGORY, L"CRenderer::Open: depth bits %d",bits); glGetIntegerv(GL_STENCIL_BITS,&bits); - LOG(CLogger::Normal, LOG_CATEGORY, "CRenderer::Open: stencil bits %d",bits); + LOG(CLogger::Normal, LOG_CATEGORY, L"CRenderer::Open: stencil bits %d",bits); glGetIntegerv(GL_ALPHA_BITS,&bits); - LOG(CLogger::Normal, LOG_CATEGORY, "CRenderer::Open: alpha bits %d",bits); + LOG(CLogger::Normal, LOG_CATEGORY, L"CRenderer::Open: alpha bits %d",bits); // Validate the currently selected render path SetRenderPath(m_Options.m_RenderPath); @@ -590,7 +590,7 @@ void CRenderer::SetOptionBool(enum Option opt,bool value) m_Options.m_FancyWater=value; break; default: - debug_warn("CRenderer::SetOptionBool: unknown option"); + debug_warn(L"CRenderer::SetOptionBool: unknown option"); break; } } @@ -609,7 +609,7 @@ bool CRenderer::GetOptionBool(enum Option opt) const case OPT_FANCYWATER: return m_Options.m_FancyWater; default: - debug_warn("CRenderer::GetOptionBool: unknown option"); + debug_warn(L"CRenderer::GetOptionBool: unknown option"); break; } @@ -622,7 +622,7 @@ bool CRenderer::GetOptionBool(enum Option opt) const // { // // switch (opt) { // // default: -// debug_warn("CRenderer::SetOptionColor: unknown option"); +// debug_warn(L"CRenderer::SetOptionColor: unknown option"); // // break; // // } // } @@ -635,7 +635,7 @@ void CRenderer::SetOptionFloat(enum Option opt, float val) m_Options.m_LodBias = val; break; default: - debug_warn("CRenderer::SetOptionFloat: unknown option"); + debug_warn(L"CRenderer::SetOptionFloat: unknown option"); break; } } @@ -648,7 +648,7 @@ void CRenderer::SetOptionFloat(enum Option opt, float val) // // // switch (opt) { // // default: -// debug_warn("CRenderer::GetOptionColor: unknown option"); +// debug_warn(L"CRenderer::GetOptionColor: unknown option"); // // break; // // } // @@ -682,7 +682,7 @@ void CRenderer::SetRenderPath(RenderPath rp) { if (!m->CanUseRenderPathVertexShader()) { - LOG(CLogger::Warning, LOG_CATEGORY, "Falling back to fixed function\n"); + LOG(CLogger::Warning, LOG_CATEGORY, L"Falling back to fixed function\n"); rp = RP_FIXED; } } @@ -710,7 +710,7 @@ CRenderer::RenderPath CRenderer::GetRenderPathByName(const CStr& name) if (name == "default") return RP_DEFAULT; - LOG(CLogger::Warning, LOG_CATEGORY, "Unknown render path name '%s', assuming 'default'", name.c_str()); + LOG(CLogger::Warning, LOG_CATEGORY, L"Unknown render path name '%hs', assuming 'default'", name.c_str()); return RP_DEFAULT; } @@ -725,7 +725,7 @@ void CRenderer::SetFastPlayerColor(bool fast) { if (!FastPlayerColorRender::IsAvailable()) { - LOG(CLogger::Warning, LOG_CATEGORY, "Falling back to slower player color rendering."); + LOG(CLogger::Warning, LOG_CATEGORY, L"Falling back to slower player color rendering."); m_FastPlayerColor = false; } } @@ -1328,7 +1328,7 @@ void CRenderer::EndFrame() static bool once=false; if (!once && glGetError()) { - LOG(CLogger::Error, LOG_CATEGORY, "CRenderer::EndFrame: GL errors occurred"); + LOG(CLogger::Error, LOG_CATEGORY, L"CRenderer::EndFrame: GL errors occurred"); once=true; } } @@ -1451,7 +1451,7 @@ bool CRenderer::LoadTexture(CTexture* texture,int wrapflags) h = ogl_tex_load(texture->GetName()); if (h <= 0) { - LOG(CLogger::Error, LOG_CATEGORY, "LoadTexture failed on \"%s\"",(const char*) texture->GetName()); + LOG(CLogger::Error, LOG_CATEGORY, L"LoadTexture failed on \"%ls\"", texture->GetName().string().c_str()); texture->SetHandle(errorhandle); return false; } @@ -1464,7 +1464,7 @@ bool CRenderer::LoadTexture(CTexture* texture,int wrapflags) // (this also verifies that the texture is a power-of-two) if(ogl_tex_upload(h) < 0) { - LOG(CLogger::Error, LOG_CATEGORY, "LoadTexture failed on \"%s\" : upload failed",(const char*) texture->GetName()); + LOG(CLogger::Error, LOG_CATEGORY, L"LoadTexture failed on \"%ls\" : upload failed", texture->GetName().string().c_str()); ogl_tex_free(h); texture->SetHandle(errorhandle); return false; @@ -1528,7 +1528,7 @@ static inline void CopyTriple(unsigned char* dst,const unsigned char* src) // calculate the coordinate of each alphamap within this packed texture int CRenderer::LoadAlphaMaps() { - const char* const key = "(alpha map composite)"; + const wchar_t* const key = L"(alpha map composite)"; Handle ht = ogl_tex_find(key); // alpha map texture had already been created and is still in memory: // reuse it, do not load again. @@ -1542,22 +1542,22 @@ int CRenderer::LoadAlphaMaps() // load all textures and store Handle in array // Handle textures[NumAlphaMaps] = {0}; - VfsPath path("art/textures/terrain/alphamaps/special"); - const char* fnames[NumAlphaMaps] = { - "blendcircle.dds", - "blendlshape.dds", - "blendedge.dds", - "blendedgecorner.dds", - "blendedgetwocorners.dds", - "blendfourcorners.dds", - "blendtwooppositecorners.dds", - "blendlshapecorner.dds", - "blendtwocorners.dds", - "blendcorner.dds", - "blendtwoedges.dds", - "blendthreecorners.dds", - "blendushape.dds", - "blendbad.dds" + VfsPath path(L"art/textures/terrain/alphamaps/special"); + const wchar_t* fnames[NumAlphaMaps] = { + L"blendcircle.dds", + L"blendlshape.dds", + L"blendedge.dds", + L"blendedgecorner.dds", + L"blendedgetwocorners.dds", + L"blendfourcorners.dds", + L"blendtwooppositecorners.dds", + L"blendlshapecorner.dds", + L"blendtwocorners.dds", + L"blendcorner.dds", + L"blendtwoedges.dds", + L"blendthreecorners.dds", + L"blendushape.dds", + L"blendbad.dds" }; size_t base = 0; // texture width/height (see below) // for convenience, we require all alpha maps to be of the same BPP diff --git a/source/renderer/ShadowMap.cpp b/source/renderer/ShadowMap.cpp index 1f8bdd5136..e0bd6338e8 100644 --- a/source/renderer/ShadowMap.cpp +++ b/source/renderer/ShadowMap.cpp @@ -34,7 +34,7 @@ #include "renderer/Renderer.h" #include "renderer/ShadowMap.h" -#define LOG_CATEGORY "graphics" +#define LOG_CATEGORY L"graphics" /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -332,8 +332,8 @@ void ShadowMapInternals::CreateTexture() } } - LOG(CLogger::Normal, LOG_CATEGORY, "Creating shadow texture (size %dx%d) (format = %s)%s", - Width, Height, formatname, Framebuffer ? " (using EXT_framebuffer_object)" : ""); + LOG(CLogger::Normal, LOG_CATEGORY, L"Creating shadow texture (size %dx%d) (format = %hs)%ls", + Width, Height, formatname, Framebuffer ? L" (using EXT_framebuffer_object)" : L""); // create texture object glGenTextures(1, &Texture); @@ -398,7 +398,7 @@ void ShadowMapInternals::CreateTexture() if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { - LOG(CLogger::Warning, LOG_CATEGORY, "Framebuffer object incomplete: %04d", status); + LOG(CLogger::Warning, LOG_CATEGORY, L"Framebuffer object incomplete: %04d", status); pglDeleteFramebuffersEXT(1, &Framebuffer); Framebuffer = 0; @@ -513,7 +513,7 @@ void ShadowMap::SetUseDepthTexture(bool depthTexture) { if (!g_Renderer.GetCapabilities().m_DepthTextureShadows) { - LOG(CLogger::Warning, LOG_CATEGORY, "Depth textures are not supported by your graphics card/driver. Fallback to luminance map (no self-shadowing)!"); + LOG(CLogger::Warning, LOG_CATEGORY, L"Depth textures are not supported by your graphics card/driver. Fallback to luminance map (no self-shadowing)!"); depthTexture = false; } } diff --git a/source/renderer/SkyManager.cpp b/source/renderer/SkyManager.cpp index e08934ef9a..8d07c9ce61 100644 --- a/source/renderer/SkyManager.cpp +++ b/source/renderer/SkyManager.cpp @@ -40,7 +40,7 @@ #include "graphics/Camera.h" #include "graphics/LightEnv.h" -#define LOG_CATEGORY "graphics" +#define LOG_CATEGORY L"graphics" /////////////////////////////////////////////////////////////////////////////////////////////// @@ -49,12 +49,12 @@ /////////////////////////////////////////////////////////////////// // String names for each image, in order of the IMG_ constants -const char* SkyManager::IMAGE_NAMES[5] = { - "front", - "back", - "right", - "left", - "top" +const wchar_t* SkyManager::s_imageNames[numTextures] = { + L"front", + L"back", + L"right", + L"left", + L"top" }; @@ -82,6 +82,25 @@ SkyManager::~SkyManager() } +/////////////////////////////////////////////////////////////////// +// Load single sky textures +LibError SkyManager::LoadSkyTexture(size_t index) +{ + wchar_t filename[PATH_MAX]; + swprintf_s(filename, ARRAY_SIZE(filename), L"art/textures/skies/%ls/%ls.dds", m_SkySet.c_str(), s_imageNames[index]); + Handle ht = ogl_tex_load(filename); + if(ht <= 0) + { + LOG(CLogger::Error, LOG_CATEGORY, L"SkyManager::LoadSkyTexture failed on \"%ls\"", filename); + return ht; + } + ogl_tex_set_wrap(ht, GL_CLAMP_TO_EDGE); + m_SkyTexture[index] = ht; + RETURN_ERR(ogl_tex_upload(ht)); + return INFO::OK; +} + + /////////////////////////////////////////////////////////////////// // Progressive load of sky textures int SkyManager::LoadSkyTextures() @@ -94,19 +113,7 @@ int SkyManager::LoadSkyTextures() while (cur_loading_tex < num_textures) { - char filename[PATH_MAX]; - snprintf(filename, ARRAY_SIZE(filename), "art/textures/skies/%s/%s.dds", - CStr8(m_SkySet).c_str(), IMAGE_NAMES[cur_loading_tex]); - Handle ht = ogl_tex_load(filename); - if (ht <= 0) - { - LOG(CLogger::Error, LOG_CATEGORY, "SkyManager::LoadSkyTextures failed on \"%s\"", filename); - return ht; - } - ogl_tex_set_wrap(ht, GL_CLAMP_TO_EDGE); - m_SkyTexture[cur_loading_tex] = ht; - RETURN_ERR(ogl_tex_upload(ht)); - + RETURN_ERR(LoadSkyTexture(cur_loading_tex)); cur_loading_tex++; LDR_CHECK_TIMEOUT(cur_loading_tex, num_textures); } @@ -132,27 +139,14 @@ void SkyManager::UnloadSkyTextures() // Switch to a different sky set (while the game is running) void SkyManager::SetSkySet( const CStrW& newSet ) { - if( newSet != m_SkySet ) - { - m_SkySet = newSet; + if(newSet == m_SkySet) + return; + m_SkySet = newSet; - UnloadSkyTextures(); + UnloadSkyTextures(); - for( size_t i=0; i SkyManager::GetSkySets() const // Find all subdirectories in art/textures/skies - const char* dirname = "art/textures/skies/"; + const VfsPath path(L"art/textures/skies/"); DirectoryNames subdirectories; - if(g_VFS->GetDirectoryEntries(dirname, 0, &subdirectories) < 0) + if(g_VFS->GetDirectoryEntries(path, 0, &subdirectories) < 0) { - LOG(CLogger::Error, "vfs", "Error opening directory '%s'", dirname); + LOG(CLogger::Error, LOG_CATEGORY, L"Error opening directory '%ls'", path); return std::vector(1, GetSkySet()); // just return what we currently have } for(size_t i = 0; i < subdirectories.size(); i++) - skies.push_back(CStr(subdirectories[i])); - + skies.push_back(subdirectories[i]); sort(skies.begin(), skies.end()); return skies; @@ -211,7 +204,7 @@ void SkyManager::RenderSky() const float D = 2000.0; // Front face (positive Z) - ogl_tex_bind( m_SkyTexture[IMG_FRONT] ); + ogl_tex_bind( m_SkyTexture[FRONT] ); glBegin( GL_QUADS ); glTexCoord2f( 0, 1 ); glVertex3f( -D, -D, +D ); @@ -224,7 +217,7 @@ void SkyManager::RenderSky() glEnd(); // Back face (negative Z) - ogl_tex_bind( m_SkyTexture[IMG_BACK] ); + ogl_tex_bind( m_SkyTexture[BACK] ); glBegin( GL_QUADS ); glTexCoord2f( 1, 1 ); glVertex3f( -D, -D, -D ); @@ -237,7 +230,7 @@ void SkyManager::RenderSky() glEnd(); // Right face (negative X) - ogl_tex_bind( m_SkyTexture[IMG_RIGHT] ); + ogl_tex_bind( m_SkyTexture[RIGHT] ); glBegin( GL_QUADS ); glTexCoord2f( 0, 1 ); glVertex3f( -D, -D, -D ); @@ -250,7 +243,7 @@ void SkyManager::RenderSky() glEnd(); // Left face (positive X) - ogl_tex_bind( m_SkyTexture[IMG_LEFT] ); + ogl_tex_bind( m_SkyTexture[LEFT] ); glBegin( GL_QUADS ); glTexCoord2f( 1, 1 ); glVertex3f( +D, -D, -D ); @@ -263,7 +256,7 @@ void SkyManager::RenderSky() glEnd(); // Top face (positive Y) - ogl_tex_bind( m_SkyTexture[IMG_TOP] ); + ogl_tex_bind( m_SkyTexture[TOP] ); glBegin( GL_QUADS ); glTexCoord2f( 1, 0 ); glVertex3f( +D, +D, -D ); diff --git a/source/renderer/SkyManager.h b/source/renderer/SkyManager.h index 803fdc4fb8..a57239728e 100644 --- a/source/renderer/SkyManager.h +++ b/source/renderer/SkyManager.h @@ -76,21 +76,31 @@ public: std::vector GetSkySets() const; private: + /** + * load texture file from skyset and store in m_SkyTexture + * @param index 0..numTextures-1 + **/ + LibError LoadSkyTexture(size_t index); + /// Name of current skyset (a directory within art/textures/skies) CStrW m_SkySet; - // Sky textures - Handle m_SkyTexture[5]; - // Indices into m_SkyTexture - static const int IMG_FRONT = 0; - static const int IMG_BACK = 1; - static const int IMG_RIGHT = 2; - static const int IMG_LEFT = 3; - static const int IMG_TOP = 4; + enum + { + FRONT, + BACK, + RIGHT, + LEFT, + TOP, + numTextures + }; + + // Sky textures + Handle m_SkyTexture[numTextures]; // Array of image names (defined in SkyManager.cpp), in the order of the IMG_ id's - static const char* IMAGE_NAMES[5]; + static const wchar_t* s_imageNames[numTextures]; /// State of progressive loading (in # of loaded textures) size_t cur_loading_tex; diff --git a/source/renderer/TerrainOverlay.cpp b/source/renderer/TerrainOverlay.cpp index 41014d5b46..54c3da4cfc 100644 --- a/source/renderer/TerrainOverlay.cpp +++ b/source/renderer/TerrainOverlay.cpp @@ -118,7 +118,7 @@ void TerrainOverlay::RenderEntityEdges() glBegin(GL_LINE_LOOP); CEntity* tempHandle = results[i]; - debug_printf("Entity position: %f %f %f\n", tempHandle->m_position.X,tempHandle->m_position.Y,tempHandle->m_position.Z); + debug_printf(L"Entity position: %f %f %f\n", tempHandle->m_position.X,tempHandle->m_position.Y,tempHandle->m_position.Z); CVector2D p, q; CVector2D u, v; diff --git a/source/renderer/TerrainRenderer.cpp b/source/renderer/TerrainRenderer.cpp index 65ff3a636b..c64b4361ca 100644 --- a/source/renderer/TerrainRenderer.cpp +++ b/source/renderer/TerrainRenderer.cpp @@ -46,7 +46,7 @@ #include "lib/res/graphics/ogl_shader.h" -#define LOG_CATEGORY "graphics" +#define LOG_CATEGORY L"graphics" /////////////////////////////////////////////////////////////////////////////////////////////// @@ -418,10 +418,10 @@ void TerrainRenderer::RenderWater() // If we're using fancy water, make sure its shader is loaded if(fancy && !m->fancyWaterShader) { - Handle h = ogl_program_load("shaders/water_high.xml"); + Handle h = ogl_program_load(L"shaders/water_high.xml"); if (h < 0) { - LOG(CLogger::Error, LOG_CATEGORY, "Failed to load water shader. Falling back to non-fancy water.\n"); + LOG(CLogger::Error, LOG_CATEGORY, L"Failed to load water shader. Falling back to non-fancy water.\n"); g_Renderer.m_Options.m_FancyWater = false; fancy = false; } diff --git a/source/renderer/VertexArray.cpp b/source/renderer/VertexArray.cpp index 2190f4258e..511fb1ef60 100644 --- a/source/renderer/VertexArray.cpp +++ b/source/renderer/VertexArray.cpp @@ -158,7 +158,7 @@ void VertexArray::Layout() m_Stride = 0; - //debug_printf("Layouting VertexArray\n"); + //debug_printf(L"Layouting VertexArray\n"); for(int idx = (int)m_Attributes.size()-1; idx >= 0; --idx) { @@ -178,7 +178,7 @@ void VertexArray::Layout() break; default: attrSize = 0; - debug_warn("Bad AttributeInfo::Type"); break; + debug_warn(L"Bad AttributeInfo::Type"); break; } attrSize *= attr->elems; @@ -186,12 +186,12 @@ void VertexArray::Layout() attr->offset = m_Stride; m_Stride = (m_Stride + attrSize + 3) & ~3; - //debug_printf("%i: offset: %u\n", idx, attr->offset); + //debug_printf(L"%i: offset: %u\n", idx, attr->offset); } m_Stride = RoundStride(m_Stride); - //debug_printf("Stride: %u\n", m_Stride); + //debug_printf(L"Stride: %u\n", m_Stride); if (m_Stride) m_BackingStore = new char[m_Stride * m_NumVertices]; diff --git a/source/renderer/VertexBufferManager.cpp b/source/renderer/VertexBufferManager.cpp index e65f754e9f..b976fe1f64 100644 --- a/source/renderer/VertexBufferManager.cpp +++ b/source/renderer/VertexBufferManager.cpp @@ -25,7 +25,7 @@ #include "VertexBufferManager.h" #include "ps/CLogger.h" -#define LOG_CATEGORY "graphics" +#define LOG_CATEGORY L"graphics" // janwas 2004-06-14: added dtor @@ -74,7 +74,7 @@ CVertexBuffer::VBChunk* CVertexBufferManager::Allocate(size_t vertexSize, size_t if (!result) { - LOG(CLogger::Error, LOG_CATEGORY, "Failed to create VBOs (%lu*%lu)", (unsigned long)vertexSize, (unsigned long)numVertices); + LOG(CLogger::Error, LOG_CATEGORY, L"Failed to create VBOs (%lu*%lu)", (unsigned long)vertexSize, (unsigned long)numVertices); } return result; diff --git a/source/renderer/WaterManager.cpp b/source/renderer/WaterManager.cpp index 6104782290..355e3d2dd9 100644 --- a/source/renderer/WaterManager.cpp +++ b/source/renderer/WaterManager.cpp @@ -34,7 +34,7 @@ #include "renderer/WaterManager.h" #include "renderer/Renderer.h" -#define LOG_CATEGORY "graphics" +#define LOG_CATEGORY L"graphics" /////////////////////////////////////////////////////////////////////////////////////////////// @@ -99,23 +99,22 @@ int WaterManager::LoadWaterTextures() // TODO: add a member variable and setter for this. (can't make this // a parameter because this function is called via delay-load code) - static const char* const water_type = "default"; + static const wchar_t* const water_type = L"default"; // yield after this time is reached. balances increased progress bar // smoothness vs. slowing down loading. const double end_time = timer_Time() + 100e-3; - char filename[PATH_MAX]; + wchar_t pathname[PATH_MAX]; // Load diffuse grayscale images (for non-fancy water) while (cur_loading_water_tex < num_textures) { - snprintf(filename, ARRAY_SIZE(filename), "art/textures/animated/water/%s/diffuse%02d.dds", - water_type, (int)cur_loading_water_tex+1); - Handle ht = ogl_tex_load(filename); + swprintf_s(pathname, ARRAY_SIZE(pathname), L"art/textures/animated/water/%ls/diffuse%02d.dds", water_type, (int)cur_loading_water_tex+1); + Handle ht = ogl_tex_load(pathname); if (ht <= 0) { - LOG(CLogger::Error, LOG_CATEGORY, "LoadWaterTextures failed on \"%s\"", filename); + LOG(CLogger::Error, LOG_CATEGORY, L"LoadWaterTextures failed on \"%ls\"", pathname); return ht; } m_WaterTexture[cur_loading_water_tex] = ht; @@ -127,12 +126,11 @@ int WaterManager::LoadWaterTextures() // Load normalmaps (for fancy water) while (cur_loading_normal_map < num_normal_maps) { - snprintf(filename, ARRAY_SIZE(filename), "art/textures/animated/water/%s/normal%02d.dds", - water_type, (int)cur_loading_normal_map+1); - Handle ht = ogl_tex_load(filename); + swprintf_s(pathname, ARRAY_SIZE(pathname), L"art/textures/animated/water/%ls/normal%02d.dds", water_type, (int)cur_loading_normal_map+1); + Handle ht = ogl_tex_load(pathname); if (ht <= 0) { - LOG(CLogger::Error, LOG_CATEGORY, "LoadWaterTextures failed on \"%s\"", filename); + LOG(CLogger::Error, LOG_CATEGORY, L"LoadWaterTextures failed on \"%ls\"", pathname); return ht; } m_NormalMap[cur_loading_normal_map] = ht; diff --git a/source/scripting/JSConversions.cpp b/source/scripting/JSConversions.cpp index 2293f9bca3..22dda2ee33 100644 --- a/source/scripting/JSConversions.cpp +++ b/source/scripting/JSConversions.cpp @@ -342,7 +342,7 @@ jsval JSParseString( const CStrW& Native ) CParser stringParser; stringParser.InputTaskType( "string", "_$value_" ); CParserLine result; - result.ParseString( stringParser, (CStr)Native ); + result.ParseString( stringParser, CStr(Native) ); bool boolResult; int intResult; float floatResult; if( result.GetArgFloat( 0, floatResult ) ) diff --git a/source/scripting/JSSerialization.h b/source/scripting/JSSerialization.h index 9a78d37901..b696a9e7aa 100644 --- a/source/scripting/JSSerialization.h +++ b/source/scripting/JSSerialization.h @@ -75,7 +75,7 @@ public: case TAG_STRING: return( 1 + (ToPrimitive(m_data)).GetSerializedLength() ); default: - debug_warn("An attempt was made to serialize a jsval other than a number, boolean or string." ); + debug_warn(L"An attempt was made to serialize a jsval other than a number, boolean or string." ); return( 1 ); } } @@ -108,7 +108,7 @@ public: buffer = ( ToPrimitive( m_data ) ).Serialize( buffer ); break; default: - debug_warn("An attempt was made to serialize a jsval other than a number, boolean or string." ); + debug_warn(L"An attempt was made to serialize a jsval other than a number, boolean or string." ); break; } return( buffer ); @@ -150,7 +150,7 @@ public: } break; default: - debug_warn("An attempt was made to deserialize a jsval other than a number, boolean or string." ); + debug_warn(L"An attempt was made to deserialize a jsval other than a number, boolean or string." ); break; } return( buffer ); diff --git a/source/scripting/ScriptGlue.cpp b/source/scripting/ScriptGlue.cpp index 7d52800a8d..f2cf42306c 100644 --- a/source/scripting/ScriptGlue.cpp +++ b/source/scripting/ScriptGlue.cpp @@ -75,6 +75,7 @@ #include "gui/scripting/JSInterface_IGUIObject.h" +#define LOG_CATEGORY L"script" extern bool g_TerrainModified; @@ -101,13 +102,13 @@ JSBool WriteLog(JSContext* cx, JSObject*, uintN argc, jsval* argv, jsval* rval) { JSU_REQUIRE_PARAMS(1); - CStr logMessage; + CStrW logMessage; for (int i = 0; i < (int)argc; i++) { try { - CStr arg = g_ScriptingHost.ValueToString( argv[i] ); + CStrW arg = g_ScriptingHost.ValueToUCString( argv[i] ); logMessage += arg; } catch( PSERROR_Scripting_ConversionFailed ) @@ -116,9 +117,7 @@ JSBool WriteLog(JSContext* cx, JSObject*, uintN argc, jsval* argv, jsval* rval) } } - // We should perhaps unicodify (?) the logger at some point. - - LOG(CLogger::Normal, "script", logMessage ); + LOG(CLogger::Normal, LOG_CATEGORY, logMessage.c_str()); *rval = JSVAL_TRUE; return JS_TRUE; @@ -635,15 +634,15 @@ static const size_t MAX_JS_TIMERS = 20; static TimerUnit js_start_times[MAX_JS_TIMERS]; static TimerUnit js_timer_overhead; static TimerClient js_timer_clients[MAX_JS_TIMERS]; -static char js_timer_descriptions_buf[MAX_JS_TIMERS * 12]; // depends on MAX_JS_TIMERS and format string below +static wchar_t js_timer_descriptions_buf[MAX_JS_TIMERS * 12]; // depends on MAX_JS_TIMERS and format string below static void InitJsTimers() { - char* pos = js_timer_descriptions_buf; + wchar_t* pos = js_timer_descriptions_buf; for(size_t i = 0; i < MAX_JS_TIMERS; i++) { - const char* description = pos; - pos += sprintf(pos, "js_timer %d", (int)i)+1; + const wchar_t* description = pos; + pos += swprintf(pos, 12, L"js_timer %d", (int)i)+1; timer_AddClient(&js_timer_clients[i], description); } @@ -976,7 +975,7 @@ JSBool WriteVideoMemToConsole( JSContext* cx, JSObject*, uintN argc, jsval* argv JSBool SetCursor( JSContext* cx, JSObject*, uintN argc, jsval* argv, jsval* rval ) { JSU_REQUIRE_PARAMS(1); - g_CursorName = g_ScriptingHost.ValueToString(argv[0]); + g_CursorName = g_ScriptingHost.ValueToUCString(argv[0]); return JS_TRUE; } @@ -1376,7 +1375,7 @@ JSBool GetTrigger( JSContext* cx, JSObject* UNUSED(globalObject), uintN argc, js *rval = ToJSVal( g_TriggerManager.m_TriggerMap[name] ); else { - debug_printf("Invalid trigger name %ls", name.c_str()); + debug_printf(L"Invalid trigger name %ls", name.c_str()); *rval = JSVAL_NULL; } return JS_TRUE; diff --git a/source/scripting/ScriptGlue.h b/source/scripting/ScriptGlue.h index 4c99dec659..6e0193940c 100644 --- a/source/scripting/ScriptGlue.h +++ b/source/scripting/ScriptGlue.h @@ -29,7 +29,7 @@ extern JSPropertySpec ScriptGlobalTable[]; // .. from main.cpp: extern int fps; extern void kill_mainloop(); -extern CStr g_CursorName; +extern CStrW g_CursorName; extern void StartGame(); extern void EndGame(); // .. other diff --git a/source/scripting/ScriptableComplex.inl b/source/scripting/ScriptableComplex.inl index 9b5684f4da..264731046e 100644 --- a/source/scripting/ScriptableComplex.inl +++ b/source/scripting/ScriptableComplex.inl @@ -416,7 +416,7 @@ public: void ImmediateCopy( IJSComplex* UNUSED(CopyTo), IJSComplex* UNUSED(CopyFrom), IJSComplexProperty* UNUSED(CopyProperty) ) { - debug_warn("ImmediateCopy called on a CJSValComplexProperty (something's gone wrong with the inheritance on this object)" ); + debug_warn(L"ImmediateCopy called on a CJSValComplexProperty (something's gone wrong with the inheritance on this object)" ); } }; @@ -449,7 +449,7 @@ public: } void ImmediateCopy( IJSComplex* UNUSED(CopyTo), IJSComplex* UNUSED(CopyFrom), IJSComplexProperty* UNUSED(CopyProperty) ) { - debug_warn("ImmediateCopy called on a property wrapping getter/setter functions (something's gone wrong with the inheritance for this object)" ); + debug_warn(L"ImmediateCopy called on a property wrapping getter/setter functions (something's gone wrong with the inheritance for this object)" ); } }; @@ -983,7 +983,7 @@ void CJSComplex::DeletePreviouslyAssignedProperty( const CStrW& Pro it = m_Properties.find( PropertyName ); if( it != m_Properties.end() ) { - debug_warn("BUG: CJSComplexProperty added but already existed!"); + debug_warn(L"BUG: CJSComplexProperty added but already existed!"); jscomplexproperty_suballoc_free(it->second); } #endif diff --git a/source/scripting/ScriptingHost.cpp b/source/scripting/ScriptingHost.cpp index e2ee88906d..e8c03457d6 100644 --- a/source/scripting/ScriptingHost.cpp +++ b/source/scripting/ScriptingHost.cpp @@ -34,7 +34,7 @@ #endif #endif -#define LOG_CATEGORY "scriptinghost" +#define LOG_CATEGORY L"scriptinghost" namespace { @@ -127,14 +127,15 @@ void ScriptingHost::RunMemScript(const char* script, size_t size, const char* fi } // globalObject defaults to 0 (in which case we use our m_GlobalObject). -void ScriptingHost::RunScript(const CStr& filename, JSObject* globalObject) +void ScriptingHost::RunScript(const VfsPath& pathname, JSObject* globalObject) { shared_ptr buf; size_t size; - if(g_VFS->LoadFile(filename, buf, size) != INFO::OK) // ERRTODO: translate/pass it on + if(g_VFS->LoadFile(pathname, buf, size) != INFO::OK) // ERRTODO: translate/pass it on throw PSERROR_Scripting_LoadFile_OpenFailed(); const char* script = (const char*)buf.get(); - RunMemScript(script, size, filename.c_str(), 1, globalObject); + CStr pathname_c(pathname.string()); + RunMemScript(script, size, pathname_c.c_str(), 1, globalObject); } jsval ScriptingHost::CallFunction(const std::string & functionName, jsval * params, int numParams) @@ -400,28 +401,24 @@ jsval ScriptingHost::UTF16ToValue(const utf16string &str) // called by SpiderMonkey whenever someone does JS_ReportError. // prints that message as well as locus to log, debug output and console. -void ScriptingHost::ErrorReporter(JSContext* UNUSED(cx), const char* message, JSErrorReport* report) +void ScriptingHost::ErrorReporter(JSContext* UNUSED(cx), const char* pmessage, JSErrorReport* report) { - const char* file = report->filename; + const CStrW file = report->filename? report->filename : "(current document)"; const int line = report->lineno; + const CStrW message = pmessage? pmessage : "No error message available"; // apparently there is no further information in this struct we can use // because linebuf/tokenptr require a buffer to have been allocated. // that doesn't look possible since we are a callback and there is // no mention in the dox about where this would happen (typical). - if(!file) - file = "(current document)"; - if(!message) - message = "No error message available"; - // for developer convenience: write to output window so they can // doubleclick on that line and be taken to the error locus. - debug_printf("%s(%d): %s\n", file, line, message); + debug_printf(L"%ls(%d): %ls\n", file.c_str(), line, message.c_str()); // note: CLogger's LOG already takes care of writing to the console, // so don't do that here. - LOG(CLogger::Error, LOG_CATEGORY, "JavaScript Error (%s, line %d): %s", file, line, message); + LOG(CLogger::Error, LOG_CATEGORY, L"JavaScript Error (%s, line %d): %s", file.c_str(), line, message.c_str()); } #ifndef NDEBUG diff --git a/source/scripting/ScriptingHost.h b/source/scripting/ScriptingHost.h index 7b06aec7b2..62cb53a8ed 100644 --- a/source/scripting/ScriptingHost.h +++ b/source/scripting/ScriptingHost.h @@ -40,6 +40,7 @@ ERROR_TYPE(Scripting_DefineType, AlreadyExists); ERROR_TYPE(Scripting_DefineType, CreationFailed); #include "scripting/SpiderMonkey.h" +#include "lib/file/vfs/vfs_path.h" #include #include @@ -105,12 +106,12 @@ public: inline JSObject* GetGlobalObject() { return m_GlobalObject; } void RunMemScript(const char* script, size_t size, const char* filename = 0, int line = 0, JSObject* globalObject = 0); - void RunScript(const CStr& filename, JSObject* globalObject = 0); + void RunScript(const VfsPath& filename, JSObject* globalObject = 0); jsval CallFunction(const std::string & functionName, jsval * params, int numParams); - jsval ExecuteScript(const CStrW& script, const CStrW& calledFrom = CStrW( L"Console" ), JSObject* contextObject = NULL ); + jsval ExecuteScript(const CStrW& script, const CStrW& calledFrom = L"Console", JSObject* contextObject = NULL ); void RegisterFunction(const std::string & functionName, JSNative function, int numArgs); diff --git a/source/scripting/SynchedJSObject.cpp b/source/scripting/SynchedJSObject.cpp index baf03eeb36..aa771ec2c4 100644 --- a/source/scripting/SynchedJSObject.cpp +++ b/source/scripting/SynchedJSObject.cpp @@ -48,13 +48,13 @@ void SetFromNetString(int &val, const CStrW& string) template <> CStrW ToNetString(const bool &val) { - return val ? CStrW("true") : CStrW("false"); + return val ? L"true" : L"false"; } template <> void SetFromNetString(bool &val, const CStrW& string) { - val = (string == CStrW("true")); + val = (string == L"true"); } template <> @@ -75,7 +75,7 @@ CStrW ToNetString(const SColour &data) swprintf(buf, 256, L"%f %f %f %f", data.r, data.g, data.b, data.a); buf[255]=0; - return CStrW(buf); + return buf; } template <> diff --git a/source/simulation/AStarEngine.cpp b/source/simulation/AStarEngine.cpp index f96e507273..812853f920 100644 --- a/source/simulation/AStarEngine.cpp +++ b/source/simulation/AStarEngine.cpp @@ -145,7 +145,7 @@ void CAStarEngine::TAStarTest() - debug_printf("Entity position: %f %f %f\n", tempHandle->m_position.X,tempHandle->m_position.Y,tempHandle->m_position.Z); + debug_printf(L"Entity position: %f %f %f\n", tempHandle->m_position.X,tempHandle->m_position.Y,tempHandle->m_position.Z); CBoundingObject* m_bounds = tempHandle->m_bounds; @@ -178,7 +178,7 @@ void CAStarEngine::TAStarTest() if(tempHandler->m_bound_type == CBoundingOjbect::BOUND_OABB) { - debug_printf("Entity bound box: %f\n", tempHandler->m_bound_box.m_v); + debug_printf(L"Entity bound box: %f\n", tempHandler->m_bound_box.m_v); } @@ -275,7 +275,7 @@ bool CAStarEngine::FindPath( if (mSolved && best!=NULL) { - //debug_printf("Number of nodes searched: %d\n", iterations); + //debug_printf(L"Number of nodes searched: %d\n", iterations); ConstructPath(best); } diff --git a/source/simulation/Entity.cpp b/source/simulation/Entity.cpp index 4670a9edfe..81f9907e7a 100644 --- a/source/simulation/Entity.cpp +++ b/source/simulation/Entity.cpp @@ -502,7 +502,7 @@ void CEntity::UpdateOrders( int timestep ) CEntityOrder* current = &m_orderQueue.front(); CStr name = me; #ifdef DEBUG_SYNCHRONIZATION - debug_printf("Order for %ls: %d (src %d)\n", + debug_printf(L"Order for %ls: %d (src %d)\n", m_base->m_Tag.c_str(), current->m_type, current->m_source); #endif @@ -607,7 +607,7 @@ void CEntity::UpdateOrders( int timestep ) m_orderQueue.pop_front(); break; default: - debug_warn( "Invalid entity order" ); + debug_warn( L"Invalid entity order" ); } } @@ -814,7 +814,7 @@ bool CEntity::Initialize() CEventInitialize evt; if( !DispatchEvent( &evt ) ) { - //debug_printf("start construction failed, killing self\n"); + //debug_printf(L"start construction failed, killing self\n"); Kill(); return false; } @@ -937,7 +937,7 @@ void CEntity::DispatchFormationEvent( int type ) } void CEntity::Repath() { - debug_printf("Repath\n"); + debug_printf(L"Repath\n"); CVector2D destination; CEntityOrder::EOrderSource orderSource = CEntityOrder::SOURCE_PLAYER; @@ -1132,7 +1132,7 @@ int CEntity::FindSector( int divs, float angle, float maxAngle, bool negative ) return i; } } - debug_warn("CEntity::FindSector() - invalid parameters passed."); + debug_warn(L"CEntity::FindSector() - invalid parameters passed."); return -1; } diff --git a/source/simulation/EntityManager.cpp b/source/simulation/EntityManager.cpp index f4312cb180..9488e8e537 100644 --- a/source/simulation/EntityManager.cpp +++ b/source/simulation/EntityManager.cpp @@ -224,7 +224,7 @@ HEntity CEntityManager::Create(CEntityTemplate* base, CVector3D position, float m_nextalloc++; if(m_nextalloc >= MAX_HANDLES) { - debug_warn("Ran out of entity handles!"); + debug_warn(L"Ran out of entity handles!"); return HEntity(); } } diff --git a/source/simulation/EntityRendering.cpp b/source/simulation/EntityRendering.cpp index c7c32a7fda..d8fb8e5ef3 100644 --- a/source/simulation/EntityRendering.cpp +++ b/source/simulation/EntityRendering.cpp @@ -407,7 +407,7 @@ void CEntity::RenderBars() // Draw the rank icon - std::map::iterator it = g_Selection.m_unitUITextures.find( m_rankName ); + CSelectedEntities::MapFilenameToHandle::iterator it = g_Selection.m_unitUITextures.find( m_rankName ); if( it != g_Selection.m_unitUITextures.end() ) { float size = 2*h + borderSize; diff --git a/source/simulation/EntityScriptInterface.cpp b/source/simulation/EntityScriptInterface.cpp index f26f4ee069..6df0f7e7cb 100644 --- a/source/simulation/EntityScriptInterface.cpp +++ b/source/simulation/EntityScriptInterface.cpp @@ -404,14 +404,14 @@ jsval_t CEntity::GetSpawnPoint( JSContext* UNUSED(cx), uintN argc, jsval* argv ) spawn_clearance = be->m_bound_box->m_radius; break; default: - debug_warn("No bounding information for spawned object!" ); + debug_warn(L"No bounding information for spawned object!" ); } } else spawn_clearance = ToPrimitive( argv[0] ); } else - debug_warn("No arguments to Entity::GetSpawnPoint()" ); + debug_warn(L"No arguments to Entity::GetSpawnPoint()" ); // TODO: Make netsafe. CBoundingCircle spawn( 0.0f, 0.0f, spawn_clearance, 0.0f ); @@ -703,7 +703,7 @@ void CEntity::CheckListeners( int type, CEntity *target) m_listeners[i].m_sender->DispatchNotification( order, result ); break; default: - debug_warn("Invalid notification: CheckListeners()"); + debug_warn(L"Invalid notification: CheckListeners()"); continue; } } diff --git a/source/simulation/EntityTemplate.cpp b/source/simulation/EntityTemplate.cpp index 5dd985569f..524fee68ef 100644 --- a/source/simulation/EntityTemplate.cpp +++ b/source/simulation/EntityTemplate.cpp @@ -27,7 +27,7 @@ #include "sound/SoundGroupMgr.h" #include "ps/CLogger.h" -#define LOG_CATEGORY "entity" +#define LOG_CATEGORY L"entity" STL_HASH_SET CEntityTemplate::scriptsLoaded; @@ -156,10 +156,10 @@ void CEntityTemplate::RebuildClassSet() (*it)->RebuildClassSet(); } -bool CEntityTemplate::LoadXml( const CStr& filename ) +bool CEntityTemplate::LoadXml( const VfsPath& pathname ) { CXeromyces XeroFile; - if (XeroFile.Load(filename) != PSRETURN_OK) + if (XeroFile.Load(pathname) != PSRETURN_OK) // Fail return false; @@ -188,13 +188,13 @@ bool CEntityTemplate::LoadXml( const CStr& filename ) if( Root.GetNodeName() != el_Entity ) { - LOG(CLogger::Error, LOG_CATEGORY, "CEntityTemplate::LoadXml: XML root was not \"Entity\" in file %s. Load failed.", filename.c_str() ); + LOG(CLogger::Error, LOG_CATEGORY, L"CEntityTemplate::LoadXml: XML root was not \"Entity\" in file %ls. Load failed.", pathname.string().c_str() ); return( false ); } XMBElementList RootChildren = Root.GetChildNodes(); - m_Tag = CStr(filename).AfterLast("/").BeforeLast(".xml"); + m_Tag = CStr(pathname.string()).AfterLast("/").BeforeLast(".xml"); m_Base_Name = Root.GetAttributes().GetNamedItem( at_Parent ); @@ -209,7 +209,7 @@ bool CEntityTemplate::LoadXml( const CStr& filename ) } else { - LOG(CLogger::Warning, LOG_CATEGORY, "Parent template \"%ls\" does not exist in template \"%ls\"", m_Base_Name.c_str(), m_Tag.c_str() ); + LOG(CLogger::Warning, LOG_CATEGORY, L"Parent template \"%ls\" does not exist in template \"%ls\"", m_Base_Name.c_str(), m_Tag.c_str() ); // (The requested entity will still be returned, but with no parent. // Is this a reasonable thing to do?) } @@ -227,13 +227,14 @@ bool CEntityTemplate::LoadXml( const CStr& filename ) if( !Include.empty() && scriptsLoaded.find( Include ) == scriptsLoaded.end() ) { scriptsLoaded.insert( Include ); - g_ScriptingHost.RunScript( Include ); + g_ScriptingHost.RunScript( CStrW(Include) ); } CStr Inline = Child.GetText(); if( !Inline.empty() ) { - g_ScriptingHost.RunMemScript( Inline.c_str(), Inline.length(), filename.c_str(), Child.GetLineNumber() ); + CStr pathname_c = CStr(pathname.string()); + g_ScriptingHost.RunMemScript( Inline.c_str(), Inline.length(), pathname_c.c_str(), Child.GetLineNumber() ); } } else if (ChildName == el_Traits) @@ -317,13 +318,13 @@ bool CEntityTemplate::LoadXml( const CStr& filename ) JSFunction* fn = JS_ValueToFunction( g_ScriptingHost.GetContext(), fnval ); if( !fn ) { - LOG(CLogger::Error, LOG_CATEGORY, "CEntityTemplate::LoadXml: Function does not exist for event %ls in file %s. Load failed.", EventName.c_str(), filename.c_str() ); + LOG(CLogger::Error, LOG_CATEGORY, L"CEntityTemplate::LoadXml: Function does not exist for event %ls in file %ls. Load failed.", EventName.c_str(), pathname.string().c_str() ); break; } m_EventHandlers[eventID].SetFunction( fn ); } else - m_EventHandlers[eventID].Compile( CStrW( filename ) + L"::" + EventName + L" (" + CStrW( Child.GetLineNumber() ) + L")", Code ); + m_EventHandlers[eventID].Compile( pathname.string() + L"::" + EventName + L" (" + CStrW( Child.GetLineNumber() ) + L")", Code ); HasProperty( EventName )->m_Inherited = false; break; } @@ -337,7 +338,7 @@ bool CEntityTemplate::LoadXml( const CStr& filename ) { XMBElement child = children.Item(j); CStr8 name = toCamelCase( XeroFile.GetElementString( child.GetNodeName() ) ); - CStr8 soundGroupFilename = child.GetText(); + VfsPath soundGroupFilename = CStrW(child.GetText()); const size_t soundGroupIndex = g_soundGroupMgr->AddGroup(soundGroupFilename); m_SoundGroupTable[name] = soundGroupIndex; } @@ -370,7 +371,7 @@ void CEntityTemplate::XMLLoadProperty( const CXeromyces& XeroFile, const XMBElem if( Existing ) { if( !Existing->m_Intrinsic ) - LOG(CLogger::Warning, LOG_CATEGORY, "CEntityTemplate::XMLAddProperty: %ls already defined for %ls. Property trees will be merged.", PropertyName.c_str(), m_Tag.c_str() ); + LOG(CLogger::Warning, LOG_CATEGORY, L"CEntityTemplate::XMLAddProperty: %ls already defined for %ls. Property trees will be merged.", PropertyName.c_str(), m_Tag.c_str() ); Existing->Set( this, JSParseString( Source.GetText() ) ); //Existing->m_Inherited = false; } @@ -389,7 +390,7 @@ void CEntityTemplate::XMLLoadProperty( const CXeromyces& XeroFile, const XMBElem } - PropertyName += CStrW( L"." ); + PropertyName += L"."; // Retrieve any attributes it has and add them as subproperties. XMBAttributeList AttributeSet = Source.GetAttributes(); diff --git a/source/simulation/EntityTemplate.h b/source/simulation/EntityTemplate.h index 62f7a77eff..36552ef7cb 100644 --- a/source/simulation/EntityTemplate.h +++ b/source/simulation/EntityTemplate.h @@ -33,6 +33,7 @@ #define INCLUDED_ENTITYTEMPLATE #include "ps/CStr.h" +#include "lib/file/vfs/vfs_path.h" #include "scripting/ScriptableComplex.h" #include "scripting/DOMEvent.h" @@ -54,7 +55,7 @@ public: CEntityTemplate(CPlayer* player); ~CEntityTemplate(); // Load from XML - bool LoadXml(const CStr& filename); + bool LoadXml(const VfsPath& filename); // Load a tree of properties from an XML (XMB) node. void XMLLoadProperty(const CXeromyces& XeroFile, const XMBElement& Source, const CStrW& BasePropertyName); diff --git a/source/simulation/EntityTemplateCollection.cpp b/source/simulation/EntityTemplateCollection.cpp index a9cf6b0d80..a859a97e78 100644 --- a/source/simulation/EntityTemplateCollection.cpp +++ b/source/simulation/EntityTemplateCollection.cpp @@ -25,7 +25,7 @@ #include "ps/Player.h" #include "ps/Game.h" -#define LOG_CATEGORY "entity" +#define LOG_CATEGORY L"entity" #include @@ -37,7 +37,7 @@ void CEntityTemplateCollection::LoadFile( const VfsPath& pathname ) // we don't have to search every directory for x.xml. const CStrW basename(fs::basename(pathname)); - m_templateFilenames[basename] = pathname.string(); + m_templateFilenames[basename] = pathname; } static LibError LoadFileThunk( const VfsPath& path, const FileInfo& UNUSED(fileInfo), uintptr_t cbData ) @@ -50,7 +50,7 @@ static LibError LoadFileThunk( const VfsPath& path, const FileInfo& UNUSED(fileI int CEntityTemplateCollection::LoadTemplates() { // List all files in entities/ and its subdirectories. - THROW_ERR( fs_util::ForEachFile(g_VFS, "entities/", LoadFileThunk, (uintptr_t)this, "*.xml", fs_util::DIR_RECURSIVE)); + THROW_ERR( fs_util::ForEachFile(g_VFS, L"entities/", LoadFileThunk, (uintptr_t)this, L"*.xml", fs_util::DIR_RECURSIVE)); /*// Load all the templates; this is necessary so that we can apply techs to them // (otherwise a tech can't affect the template of a unit that doesn't yet exist) @@ -84,18 +84,18 @@ CEntityTemplate* CEntityTemplateCollection::GetTemplate( const CStrW& name, CPla if( filename_it == m_templateFilenames.end() ) return( NULL ); - CStr path( filename_it->second ); + VfsPath path( filename_it->second ); // Try to load to the entity CEntityTemplate* newTemplate = new CEntityTemplate( player ); if( !newTemplate->LoadXml( path ) ) { - LOG(CLogger::Error, LOG_CATEGORY, "CEntityTemplateCollection::GetTemplate(): Couldn't load template \"%s\"", path.c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"CEntityTemplateCollection::GetTemplate(): Couldn't load template \"%ls\"", path.string().c_str()); delete newTemplate; return( NULL ); } - LOG(CLogger::Normal, LOG_CATEGORY, "CEntityTemplateCollection::GetTemplate(): Loaded template \"%s\"", path.c_str()); + LOG(CLogger::Normal, LOG_CATEGORY, L"CEntityTemplateCollection::GetTemplate(): Loaded template \"%ls\"", path.string().c_str()); m_templates[id][name] = newTemplate; return newTemplate; diff --git a/source/simulation/EntityTemplateCollection.h b/source/simulation/EntityTemplateCollection.h index 758531d5e5..cf6766365b 100644 --- a/source/simulation/EntityTemplateCollection.h +++ b/source/simulation/EntityTemplateCollection.h @@ -33,6 +33,7 @@ #include #include +#include "lib/file/vfs/vfs_path.h" #include "ps/CStr.h" #include "ps/Singleton.h" #include "ps/Game.h" @@ -51,7 +52,7 @@ class CEntityTemplateCollection : public Singleton static const size_t NULL_PLAYER = (PS_MAX_PLAYERS+1); typedef STL_HASH_MAP TemplateMap; - typedef STL_HASH_MAP TemplateFilenameMap; + typedef STL_HASH_MAP TemplateFilenameMap; TemplateMap m_templates[PS_MAX_PLAYERS + 2]; TemplateFilenameMap m_templateFilenames; diff --git a/source/simulation/Formation.cpp b/source/simulation/Formation.cpp index 2ebe338c28..31b5f54859 100644 --- a/source/simulation/Formation.cpp +++ b/source/simulation/Formation.cpp @@ -21,13 +21,13 @@ #include "ps/CStr.h" #include "maths/MathUtil.h" -#define LOG_CATEGORY "Formation" +#define LOG_CATEGORY L"Formation" CFormation::CFormation() { m_numSlots = 0; } -bool CFormation::LoadXml(const CStr& filename) +bool CFormation::LoadXml(const VfsPath& filename) { CXeromyces XeroFile; @@ -69,7 +69,7 @@ bool CFormation::LoadXml(const CStr& filename) XMBElement Root = XeroFile.GetRoot(); if( Root.GetNodeName() != el_formation ) { - LOG(CLogger::Error, LOG_CATEGORY, "CFormation::LoadXml: XML root was not \"Formation\" in file %s. Load failed.", filename.c_str() ); + LOG(CLogger::Error, LOG_CATEGORY, L"CFormation::LoadXml: XML root was not \"Formation\" in file %ls. Load failed.", filename.string().c_str() ); return( false ); } @@ -121,7 +121,7 @@ bool CFormation::LoadXml(const CStr& filename) else { const char* invAttr = XeroFile.GetAttributeString(Attr.Name).c_str(); - LOG(CLogger::Error, LOG_CATEGORY, "CFormation::LoadXml: Invalid attribute %s defined in formation file %s. Load failed.", invAttr, filename.c_str() ); + LOG(CLogger::Error, LOG_CATEGORY, L"CFormation::LoadXml: Invalid attribute %hs defined in formation file %ls. Load failed.", invAttr, filename.string().c_str() ); return( false ); } } @@ -164,7 +164,7 @@ bool CFormation::LoadXml(const CStr& filename) if( order <= 0 ) { - LOG(CLogger::Error, LOG_CATEGORY, "CFormation::LoadXml: Invalid (negative number or 0) order defined in formation file %s. The game will try to continue anyway.", filename.c_str() ); + LOG(CLogger::Error, LOG_CATEGORY, L"CFormation::LoadXml: Invalid (negative number or 0) order defined in formation file %ls. The game will try to continue anyway.", filename.string().c_str() ); continue; } --order; //We need this to be in line with arrays, so start at 0 @@ -196,7 +196,7 @@ bool CFormation::LoadXml(const CStr& filename) { if ( m_slots.find(i) == m_slots.end() ) { - LOG(CLogger::Error, LOG_CATEGORY, "CFormation::LoadXml: Missing orders in %s. Load failed.", filename.c_str() ); + LOG(CLogger::Error, LOG_CATEGORY, L"CFormation::LoadXml: Missing orders in %ls. Load failed.", filename.string().c_str() ); return false; } else diff --git a/source/simulation/Formation.h b/source/simulation/Formation.h index f3e28eaf76..ca5d502546 100644 --- a/source/simulation/Formation.h +++ b/source/simulation/Formation.h @@ -90,7 +90,7 @@ private: //The key is the "order" of the slot std::map m_slots; - bool LoadXml(const CStr& filename); + bool LoadXml(const VfsPath& filename); void AssignCategory(size_t order, const CStr& category); //takes care of formatting strings }; #endif diff --git a/source/simulation/FormationCollection.cpp b/source/simulation/FormationCollection.cpp index dd42e35d7d..e48dcb359a 100644 --- a/source/simulation/FormationCollection.cpp +++ b/source/simulation/FormationCollection.cpp @@ -22,7 +22,7 @@ #include "graphics/Model.h" #include "ps/CLogger.h" -#define LOG_CATEGORY "formation" +#define LOG_CATEGORY L"formation" void CFormationCollection::LoadFile( const VfsPath& pathname ) @@ -32,7 +32,7 @@ void CFormationCollection::LoadFile( const VfsPath& pathname ) // we don't have to search every directory for x.xml. const CStrW basename(fs::basename(pathname)); - m_templateFilenames[basename] = pathname.string(); + m_templateFilenames[basename] = pathname; } static LibError LoadFormationThunk( const VfsPath& path, const FileInfo& UNUSED(fileInfo), uintptr_t cbData ) @@ -45,7 +45,7 @@ static LibError LoadFormationThunk( const VfsPath& path, const FileInfo& UNUSED( int CFormationCollection::LoadTemplates() { // Load all files in formations and subdirectories. - THROW_ERR( fs_util::ForEachFile(g_VFS, "formations/", LoadFormationThunk, (uintptr_t)this, "*.xml", fs_util::DIR_RECURSIVE)); + THROW_ERR( fs_util::ForEachFile(g_VFS, L"formations/", LoadFormationThunk, (uintptr_t)this, L"*.xml", fs_util::DIR_RECURSIVE)); return 0; } @@ -61,18 +61,18 @@ CFormation* CFormationCollection::GetTemplate( const CStrW& name ) if( filename_it == m_templateFilenames.end() ) return( NULL ); - CStr path( filename_it->second ); + VfsPath pathname( filename_it->second ); //Try to load to the formation CFormation* newTemplate = new CFormation(); - if( !newTemplate->LoadXml( path ) ) + if( !newTemplate->LoadXml( pathname ) ) { - LOG(CLogger::Error, LOG_CATEGORY, "CFormationCollection::LoadTemplates(): Couldn't load template \"%s\"", path.c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"CFormationCollection::LoadTemplates(): Couldn't load template \"%ls\"", pathname.string().c_str()); delete newTemplate; return( NULL ); } - LOG(CLogger::Normal, LOG_CATEGORY, "CFormationCollection::LoadTemplates(): Loaded template \"%s\"", path.c_str()); + LOG(CLogger::Normal, LOG_CATEGORY, L"CFormationCollection::LoadTemplates(): Loaded template \"%ls\"", pathname.string().c_str()); m_templates[name] = newTemplate; return newTemplate; diff --git a/source/simulation/FormationCollection.h b/source/simulation/FormationCollection.h index 7dd82f5305..463505f07c 100644 --- a/source/simulation/FormationCollection.h +++ b/source/simulation/FormationCollection.h @@ -25,6 +25,7 @@ #define INCLUDED_FORMATIONCOLLECTION #include +#include "lib/file/vfs/vfs_path.h" #include "ps/CStr.h" #include "ps/Singleton.h" #include "ps/Filesystem.h" @@ -37,7 +38,7 @@ class CFormationCollection : public Singleton { typedef std::map templateMap; - typedef std::map templateFilenameMap; + typedef std::map templateFilenameMap; templateMap m_templates; templateFilenameMap m_templateFilenames; public: diff --git a/source/simulation/FormationManager.cpp b/source/simulation/FormationManager.cpp index ded44583cd..3c7dcd64e6 100644 --- a/source/simulation/FormationManager.cpp +++ b/source/simulation/FormationManager.cpp @@ -36,7 +36,7 @@ void CFormationManager::CreateFormation( CEntityList& entities, CStrW& name ) { if ( entities.empty() ) { - debug_warn("Attempting to create a formation with no entities"); + debug_warn(L"Attempting to create a formation with no entities"); return; } CFormation* base = g_EntityFormationCollection.GetTemplate(name); @@ -66,7 +66,7 @@ void CFormationManager::DestroyFormation( size_t form ) { if ( form >= m_formations.size()) { - debug_warn("CFormationManager::DestroyFormation--invalid entity"); + debug_warn(L"CFormationManager::DestroyFormation--invalid entity"); return; } FormIterator it=m_formations.begin() + form; diff --git a/source/simulation/PathfindEngine.cpp b/source/simulation/PathfindEngine.cpp index e33c8e4519..1811a2eadd 100644 --- a/source/simulation/PathfindEngine.cpp +++ b/source/simulation/PathfindEngine.cpp @@ -237,7 +237,7 @@ void CPathfindEngine::insertObstacles() CEntity* tempHandle = results[i]; - //debug_printf("Entity position: %f %f %f\n", tempHandle->m_position.X,tempHandle->m_position.Y,tempHandle->m_position.Z); + //debug_printf(L"Entity position: %f %f %f\n", tempHandle->m_position.X,tempHandle->m_position.Y,tempHandle->m_position.Z); CVector2D p, q; @@ -333,7 +333,7 @@ void CPathfindEngine::drawTriangulation() int polyNum = dcdtPathfinder.num_polygons(); - //debug_printf("Number of polygons: %d",polyNum); + //debug_printf(L"Number of polygons: %d",polyNum); if(polyNum) { @@ -452,7 +452,7 @@ void CPathfindEngine::RequestTriangulationPath( HEntity entity, const CVector2D& // Make the path take as few steps as possible by collapsing steps in the same direction together. std::vector path; - debug_printf("waypoints: %d channel size %d \n ",CurPath.size(),CurChannel.size()); + debug_printf(L"waypoints: %d channel size %d \n ",CurPath.size(),CurChannel.size()); for (int i = 0; i < CurPath.size(); i++) { @@ -461,7 +461,7 @@ void CPathfindEngine::RequestTriangulationPath( HEntity entity, const CVector2D& waypoint.x = CurPath[i].x; waypoint.y = CurPath[i].y; - debug_printf("waypoints: %f %f \n",waypoint.x, waypoint.y); + debug_printf(L"waypoints: %f %f \n",waypoint.x, waypoint.y); path.push_back(waypoint); diff --git a/source/simulation/Projectile.cpp b/source/simulation/Projectile.cpp index 5adc8850ae..ec82c85ecb 100644 --- a/source/simulation/Projectile.cpp +++ b/source/simulation/Projectile.cpp @@ -145,7 +145,7 @@ void CProjectile::ScriptingInit() JSBool CProjectile::Construct( JSContext* cx, JSObject* UNUSED(obj), uintN argc, jsval* argv, jsval* rval ) { debug_assert( argc >= 4 ); - CStr ModelString; + CStrW ModelString; CVector3D Here, There; float Speed; CEntity* Temp, *Originator = NULL; @@ -165,7 +165,7 @@ JSBool CProjectile::Construct( JSContext* cx, JSObject* UNUSED(obj), uintN argc, goto fail; } } - else if( !ToPrimitive( cx, argv[0], ModelString ) || NULL == ( oe = g_Game->GetView()->GetObjectManager().FindObject( ModelString ) ) || NULL == ( Model = oe->m_Model ) ) + else if( !ToPrimitive( cx, argv[0], ModelString ) || NULL == ( oe = g_Game->GetView()->GetObjectManager().FindObject( ModelString ) ) || NULL == ( Model = oe->m_Model ) ) { err = "Invalid actor"; goto fail; diff --git a/source/simulation/Scheduler.cpp b/source/simulation/Scheduler.cpp index 886a91fecb..2fdb77ee28 100644 --- a/source/simulation/Scheduler.cpp +++ b/source/simulation/Scheduler.cpp @@ -109,7 +109,7 @@ void CScheduler::Update(int simElapsed) continue; } - g_ScriptingHost.ExecuteScript( top.script, CStrW( L"timer" ), top.operateOn ); + g_ScriptingHost.ExecuteScript( top.script, L"timer", top.operateOn ); if( top.isRecurrent && !m_abortInterval ) PushInterval( top.delay, top.delay, top.script, top.operateOn, top.id ); } @@ -126,7 +126,7 @@ void CScheduler::Update(int simElapsed) continue; } - g_ScriptingHost.ExecuteScript( top.script, CStrW( L"timer" ), top.operateOn ); + g_ScriptingHost.ExecuteScript( top.script, L"timer", top.operateOn ); } while( !timeFunction.empty() ) { diff --git a/source/simulation/ScriptObject.cpp b/source/simulation/ScriptObject.cpp index 8f6b8aa901..9e60d86b99 100644 --- a/source/simulation/ScriptObject.cpp +++ b/source/simulation/ScriptObject.cpp @@ -135,7 +135,7 @@ void CScriptObject::Compile( const CStrW& FileNameTag, const CStrW& FunctionBody const char* argnames[] = { "evt" }; utf16string str16=FunctionBody.utf16(); - Function = JS_CompileUCFunction( g_ScriptingHost.GetContext(), NULL, NULL, 1, argnames, str16.c_str(), str16.size(), (CStr)FileNameTag, 0 ); + Function = JS_CompileUCFunction( g_ScriptingHost.GetContext(), NULL, NULL, 1, argnames, str16.c_str(), str16.size(), CStr(FileNameTag), 0 ); Root(); } diff --git a/source/simulation/Simulation.cpp b/source/simulation/Simulation.cpp index 82eef36c50..60f150dfd1 100644 --- a/source/simulation/Simulation.cpp +++ b/source/simulation/Simulation.cpp @@ -45,6 +45,8 @@ #include "simulation/TurnManager.h" #include "simulation/TriggerManager.h" +#define LOG_CATEGORY L"simulation" + CSimulation::CSimulation(CGame *pGame): m_pGame(pGame), m_pWorld(pGame->GetWorld()), @@ -69,7 +71,7 @@ int CSimulation::Initialize(CGameAttributes* pAttribs) // Call the game startup script // TODO: Maybe don't do this if we're in Atlas // [2006-06-26 20ms] - g_ScriptingHost.RunScript( "scripts/game_startup.js" ); + g_ScriptingHost.RunScript( L"scripts/game_startup.js" ); // [2006-06-26 3647ms] g_EntityManager.m_screenshotMode = pAttribs->m_ScreenshotMode; @@ -114,7 +116,7 @@ bool CSimulation::Update(double frameTime) // cutting down on Interpolate and rendering, and call us a few times // with frameTime == 0 to give us a chance to catch up. ok = false; - debug_printf("WARNING: missing a simulation turn due to low FPS\n"); + debug_printf(L"WARNING: missing a simulation turn due to low FPS\n"); } } else @@ -169,7 +171,7 @@ void CSimulation::Simulate() m_Time += time / 1000.0f; #if defined(DEBUG_SYNCHRONIZATION) - debug_printf("Simulation turn: %.3lf\n", m_Time); + debug_printf(L"Simulation turn: %.3lf\n", m_Time); #endif PROFILE_START( "scheduler tick" ); @@ -197,7 +199,7 @@ void CSimulation::Simulate() PROFILE_END( "turn manager update" ); #if defined(DEBUG_SYNCHRONIZATION) - debug_printf("End turn\n", m_Time); + debug_printf(L"End turn\n", m_Time); #endif } @@ -387,7 +389,7 @@ size_t CSimulation::TranslateMessage(CNetMessage* pMsg, size_t clientMask, void* } if (order.m_type == CEntityOrder::ORDER_LAST) { - LOG(CLogger::Error, "simulation", "Got an AddWaypoint message for an entity that isn't moving."); + LOG(CLogger::Error, LOG_CATEGORY, L"Got an AddWaypoint message for an entity that isn't moving."); } } break; diff --git a/source/simulation/Technology.cpp b/source/simulation/Technology.cpp index c06b7cccaa..3f6a073c96 100644 --- a/source/simulation/Technology.cpp +++ b/source/simulation/Technology.cpp @@ -30,7 +30,7 @@ #include "ps/Player.h" #include "scripting/ScriptableComplex.inl" -#define LOG_CATEGORY "Techs" +#define LOG_CATEGORY L"Techs" STL_HASH_SET CTechnology::m_scriptsLoaded; @@ -42,11 +42,11 @@ CTechnology::CTechnology( const CStrW& name, CPlayer* player ) m_inProgress = false; } -bool CTechnology::LoadXml( const CStr& filename ) +bool CTechnology::LoadXml( const VfsPath& pathname ) { CXeromyces XeroFile; - if (XeroFile.Load(filename) != PSRETURN_OK) + if (XeroFile.Load(pathname) != PSRETURN_OK) return false; #define EL(x) int el_##x = XeroFile.GetElementID(#x) @@ -61,7 +61,7 @@ bool CTechnology::LoadXml( const CStr& filename ) XMBElement Root = XeroFile.GetRoot(); if ( Root.GetNodeName() != el_tech ) { - LOG(CLogger::Error, LOG_CATEGORY, "CTechnology: XML root was not \"Tech\" in file %s. Load failed.", filename.c_str() ); + LOG(CLogger::Error, LOG_CATEGORY, L"CTechnology: XML root was not \"Tech\" in file %ls. Load failed.", pathname.string().c_str() ); return false; } XMBElementList RootChildren = Root.GetChildNodes(); @@ -75,12 +75,12 @@ bool CTechnology::LoadXml( const CStr& filename ) else if ( name == el_req ) ret = LoadElReq( element, XeroFile ); else if ( name == el_effect ) - ret = LoadElEffect( element, XeroFile, filename ); + ret = LoadElEffect( element, XeroFile, pathname ); else continue; if ( !ret ) { - LOG(CLogger::Error, LOG_CATEGORY, "CTechnology: Load failed for file %s", filename.c_str() ); + LOG(CLogger::Error, LOG_CATEGORY, L"CTechnology: Load failed for file %ls", pathname.string().c_str() ); return false; } } @@ -125,8 +125,8 @@ bool CTechnology::LoadElId( XMBElement ID, CXeromyces& XeroFile ) m_History = value; else { - const char* tagName = XeroFile.GetElementString(name).c_str(); - LOG(CLogger::Error, LOG_CATEGORY, "CTechnology: invalid tag %s for XML file", tagName ); + const CStrW tagName(XeroFile.GetElementString(name)); + LOG(CLogger::Error, LOG_CATEGORY, L"CTechnology: invalid tag %ls for XML file", tagName.c_str() ); return false; } } @@ -176,15 +176,15 @@ bool CTechnology::LoadElReq( XMBElement Req, CXeromyces& XeroFile ) } else { - const char* tagName = XeroFile.GetElementString(name).c_str(); - LOG(CLogger::Error, LOG_CATEGORY, "CTechnology: invalid tag %s for XML file", tagName ); + const CStrW tagName(XeroFile.GetElementString(name)); + LOG(CLogger::Error, LOG_CATEGORY, L"CTechnology: invalid tag %ls for XML file", tagName.c_str() ); return false; } } return true; } -bool CTechnology::LoadElEffect( XMBElement effect, CXeromyces& XeroFile, const CStr& filename ) +bool CTechnology::LoadElEffect( XMBElement effect, CXeromyces& XeroFile, const VfsPath& pathname ) { #define EL(x) int el_##x = XeroFile.GetElementID(#x) #define AT(x) int at_##x = XeroFile.GetAttributeID(#x) @@ -229,7 +229,7 @@ bool CTechnology::LoadElEffect( XMBElement effect, CXeromyces& XeroFile, const C { if( modValue.size() == 0) { - LOG(CLogger::Error, LOG_CATEGORY, "CTechnology::LoadXml: invalid Modifier value (empty string)" ); + LOG(CLogger::Error, LOG_CATEGORY, L"CTechnology::LoadXml(%ls): invalid Modifier value (empty string)", pathname.string().c_str() ); m_Modifiers.pop_back(); return false; } @@ -243,7 +243,7 @@ bool CTechnology::LoadElEffect( XMBElement effect, CXeromyces& XeroFile, const C } else { - LOG(CLogger::Error, LOG_CATEGORY, "CTechnology::LoadXml: invalid tag inside \"Modifier\" tag" ); + LOG(CLogger::Error, LOG_CATEGORY, L"CTechnology::LoadXml(%ls): invalid tag inside \"Modifier\" tag", pathname.string().c_str() ); m_Modifiers.pop_back(); return false; } @@ -264,7 +264,7 @@ bool CTechnology::LoadElEffect( XMBElement effect, CXeromyces& XeroFile, const C m_Sets.back().value = setValue.ToFloat(); else { - LOG(CLogger::Error, LOG_CATEGORY, "CTechnology::LoadXml: invalid tag inside \"Set\" tag" ); + LOG(CLogger::Error, LOG_CATEGORY, L"CTechnology::LoadXml(%ls): invalid tag inside \"Set\" tag", pathname.string().c_str() ); m_Sets.pop_back(); return false; } @@ -276,12 +276,13 @@ bool CTechnology::LoadElEffect( XMBElement effect, CXeromyces& XeroFile, const C if( !Include.empty() && m_scriptsLoaded.find( Include ) == m_scriptsLoaded.end() ) { m_scriptsLoaded.insert( Include ); - g_ScriptingHost.RunScript( Include ); + g_ScriptingHost.RunScript( CStrW(Include) ); } CStr Inline = element.GetText(); if( !Inline.empty() ) { - g_ScriptingHost.RunMemScript( Inline.c_str(), Inline.length(), filename, element.GetLineNumber() ); + CStr pathname_c = CStr(pathname.string()); + g_ScriptingHost.RunMemScript( Inline.c_str(), Inline.length(), pathname_c.c_str(), element.GetLineNumber() ); } } else if ( name == el_function ) @@ -297,19 +298,19 @@ bool CTechnology::LoadElEffect( XMBElement effect, CXeromyces& XeroFile, const C JSFunction* fn = JS_ValueToFunction( g_ScriptingHost.GetContext(), fnval ); if( !fn ) { - LOG(CLogger::Error, LOG_CATEGORY, "CTechnology::LoadXml: Function does not exist for %s in file %s. Load failed.", CStr(funcName).c_str(), filename.c_str() ); + LOG(CLogger::Error, LOG_CATEGORY, L"CTechnology::LoadXml: Function does not exist for %hs in file %ls. Load failed.", funcName.c_str(), pathname.string().c_str() ); return false; } m_effectFunction.SetFunction( fn ); } else if ( Inline != CStr() ) - m_effectFunction.Compile( CStrW( filename ) + L"::" + (CStrW)funcName + L" (" + CStrW( element.GetLineNumber() ) + L")", Inline ); + m_effectFunction.Compile( pathname.string() + L"::" + CStrW(funcName) + L" (" + CStrW( element.GetLineNumber() ) + L")", Inline ); //(No error needed; scripts are optional) } else { - const char* tagName = XeroFile.GetElementString(name).c_str(); - LOG(CLogger::Error, LOG_CATEGORY, "CTechnology: invalid tag %s for XML file", tagName ); + const CStrW tagName(XeroFile.GetElementString(name)); + LOG(CLogger::Error, LOG_CATEGORY, L"CTechnology: invalid tag %ls for XML file", tagName.c_str() ); return false; } } diff --git a/source/simulation/Technology.h b/source/simulation/Technology.h index 684d221e01..f6494ca78b 100644 --- a/source/simulation/Technology.h +++ b/source/simulation/Technology.h @@ -67,10 +67,10 @@ public: void SetExclusion( bool exclude ) { m_excluded=exclude; } - bool LoadXml( const CStr& filename ); + bool LoadXml( const VfsPath& filename ); bool LoadElId( XMBElement ID, CXeromyces& XeroFile ); bool LoadElReq( XMBElement Req, CXeromyces& XeroFile ); - bool LoadElEffect( XMBElement Effect, CXeromyces& XeroFile, const CStr& filename ); + bool LoadElEffect( XMBElement Effect, CXeromyces& XeroFile, const VfsPath& pathname); private: CStrW m_Name; // name of the tech file diff --git a/source/simulation/TechnologyCollection.cpp b/source/simulation/TechnologyCollection.cpp index 71b2b44177..5f5be4292c 100644 --- a/source/simulation/TechnologyCollection.cpp +++ b/source/simulation/TechnologyCollection.cpp @@ -21,12 +21,12 @@ #include "ps/CLogger.h" #include "ps/Player.h" -#define LOG_CATEGORY "tech" +#define LOG_CATEGORY L"tech" void CTechnologyCollection::LoadFile( const VfsPath& pathname ) { const CStrW basename(fs::basename(pathname)); - m_techFilenames[basename] = pathname.string(); + m_techFilenames[basename] = pathname; } static LibError LoadTechThunk( const VfsPath& pathname, const FileInfo& UNUSED(fileInfo), uintptr_t cbData ) @@ -39,7 +39,7 @@ static LibError LoadTechThunk( const VfsPath& pathname, const FileInfo& UNUSED(f int CTechnologyCollection::LoadTechnologies() { // Load all files in techs/ and subdirectories. - THROW_ERR( fs_util::ForEachFile(g_VFS, "technologies/", LoadTechThunk, (uintptr_t)this, "*.xml", fs_util::DIR_RECURSIVE)); + THROW_ERR( fs_util::ForEachFile(g_VFS, L"technologies/", LoadTechThunk, (uintptr_t)this, L"*.xml", fs_util::DIR_RECURSIVE)); return 0; } @@ -60,20 +60,20 @@ CTechnology* CTechnologyCollection::GetTechnology( const CStrW& name, CPlayer* p if( filename_it == m_techFilenames.end() ) return( NULL ); - CStr path( filename_it->second ); + VfsPath path( filename_it->second ); //Try to load to the tech CTechnology* newTemplate = new CTechnology( name, player ); if( !newTemplate->LoadXml( path ) ) { - LOG(CLogger::Error, LOG_CATEGORY, "CTechnologyCollection::GetTechnology(): Couldn't load tech \"%s\"", path.c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"CTechnologyCollection::GetTechnology(): Couldn't load tech \"%ls\"", path.string().c_str()); delete newTemplate; return( NULL ); } m_techs[id][name] = newTemplate; - LOG(CLogger::Normal, LOG_CATEGORY, "CTechnologyCollection::GetTechnology(): Loaded tech \"%s\"", path.c_str()); + LOG(CLogger::Normal, LOG_CATEGORY, L"CTechnologyCollection::GetTechnology(): Loaded tech \"%ls\"", path.string().c_str()); return newTemplate; } diff --git a/source/simulation/TechnologyCollection.h b/source/simulation/TechnologyCollection.h index 77a0a0a4d0..3dc2ace737 100644 --- a/source/simulation/TechnologyCollection.h +++ b/source/simulation/TechnologyCollection.h @@ -32,7 +32,7 @@ class CTechnologyCollection : public Singleton { typedef std::map TechMap; - typedef std::map TechFilenameMap; + typedef std::map TechFilenameMap; TechMap m_techs[PS_MAX_PLAYERS+1]; TechFilenameMap m_techFilenames; diff --git a/source/simulation/TriggerManager.cpp b/source/simulation/TriggerManager.cpp index 825691a44c..f06bd56962 100644 --- a/source/simulation/TriggerManager.cpp +++ b/source/simulation/TriggerManager.cpp @@ -23,7 +23,7 @@ #include "ps/XML/XeroXMB.h" #include "ps/CLogger.h" -#define LOG_CATEGORY "Triggers" +#define LOG_CATEGORY L"Triggers" CTrigger::CTrigger() @@ -132,13 +132,13 @@ void CTrigger::Deactivate(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUS void TriggerParameter::SetWindowData(const CStrW& _windowType, CStrW& windowPosition, CStrW& windowSize) { - windowPosition.Remove( CStrW(L" ") ); - windowSize.Remove( CStrW(L" ") ); + windowPosition.Remove( L" " ); + windowSize.Remove( L" " ); - xPos = windowPosition.BeforeFirst( CStrW(L",") ).ToInt(); - yPos = windowPosition.AfterFirst( CStrW(L",") ).ToInt(); - xSize = windowSize.BeforeFirst( CStrW(L",") ).ToInt(); - ySize = windowSize.AfterFirst( CStrW(L",") ).ToInt(); + xPos = windowPosition.BeforeFirst( L"," ).ToInt(); + yPos = windowPosition.AfterFirst( L"," ).ToInt(); + xSize = windowSize.BeforeFirst( L"," ).ToInt(); + ySize = windowSize.AfterFirst( L"," ).ToInt(); windowType = _windowType; } @@ -227,15 +227,15 @@ void CTriggerManager::SetAllGroups(const std::list& groups) void CTriggerManager::AddTrigger(MapTriggerGroup& group, const MapTrigger& trigger) { CStrW conditionBody; - CStrW linkLogic[] = { CStrW(L""), CStrW(L" && "), CStrW(L" || ") }; + CStrW linkLogic[] = { L"", L" && ", L" || " }; size_t i=0; bool allParameters = true; if(trigger.conditions.size() == 0) { - conditionBody = CStrW(L"return ( true );"); + conditionBody = L"return ( true );"; } else { - conditionBody = CStrW(L"return ( "); + conditionBody = L"return ( "; for ( std::list::const_iterator it = trigger.conditions.begin(); it != trigger.conditions.end(); ++it, ++i ) @@ -245,14 +245,14 @@ void CTriggerManager::AddTrigger(MapTriggerGroup& group, const MapTrigger& trigg if ( ( blockIt = trigger.logicBlocks.find(MapTriggerLogicBlock(i)) ) != trigger.logicBlocks.end() ) { if ( blockIt->negated ) - conditionBody += CStrW(L"!"); - conditionBody += CStrW(L" ("); + conditionBody += L"!"; + conditionBody += L" ("; } if ( it->negated ) - conditionBody += CStrW(L"!"); + conditionBody += L"!"; conditionBody += it->functionName; - conditionBody += CStrW(L"("); + conditionBody += L"("; for ( std::list::const_iterator it2 = it->parameters.begin(); it2 != it->parameters.end(); ++it2 ) @@ -263,7 +263,7 @@ void CTriggerManager::AddTrigger(MapTriggerGroup& group, const MapTrigger& trigg //Parameters end here, additional "parameters" are used directly as script if ( distance == params ) { - conditionBody += CStrW(L") "); + conditionBody += L") "; allParameters = false; } @@ -284,19 +284,19 @@ void CTriggerManager::AddTrigger(MapTriggerGroup& group, const MapTrigger& trigg conditionBody += m_TriggerTranslations[combined][translatedIndex]; if ( distance + 1 < params ) - conditionBody += CStrW(L", "); + conditionBody += L", "; } if ( allParameters ) //Otherwise, closed inside loop - conditionBody += CStrW(L")"); + conditionBody += L")"; if ( trigger.logicBlockEnds.find(i) != trigger.logicBlockEnds.end() ) - conditionBody += CStrW(L" )"); + conditionBody += L" )"; if ( std::distance(it, trigger.conditions.end()) != 1 ) conditionBody += linkLogic[it->linkLogic]; } - conditionBody += CStrW(L" );"); + conditionBody += L" );"; } CStrW effectBody; @@ -305,7 +305,7 @@ void CTriggerManager::AddTrigger(MapTriggerGroup& group, const MapTrigger& trigg it != trigger.effects.end(); ++it ) { effectBody += it->functionName; - effectBody += CStrW(L"("); + effectBody += L"("; for ( std::list::const_iterator it2 = it->parameters.begin(); it2 != it->parameters.end(); ++it2 ) { @@ -327,10 +327,10 @@ void CTriggerManager::AddTrigger(MapTriggerGroup& group, const MapTrigger& trigg effectBody += m_TriggerTranslations[combined][translatedIndex]; std::list::const_iterator endIt = it->parameters.end(); if ( std::distance(it2, endIt) != 1 ) - effectBody += CStrW(L", "); + effectBody += L", "; } - effectBody += CStrW(L");"); + effectBody += L");"; } group.triggers.push_back(trigger); @@ -342,11 +342,11 @@ void CTriggerManager::AddTrigger(MapTriggerGroup& group, const MapTrigger& trigg //XML stuff -bool CTriggerManager::LoadXml( const CStr& filename ) +bool CTriggerManager::LoadXml( const VfsPath& pathname ) { CXeromyces XeroFile; - if ( XeroFile.Load( filename.c_str() ) != PSRETURN_OK ) + if ( XeroFile.Load( pathname ) != PSRETURN_OK ) return false; #define EL(x) int el_##x = XeroFile.GetElementID(#x) @@ -372,7 +372,7 @@ bool CTriggerManager::LoadXml( const CStr& filename ) { if ( !LoadTriggerSpec(rootChild, XeroFile, true) ) { - LOG(CLogger::Error, LOG_CATEGORY, "Error detected in Trigger XML tag. File: %s", filename.c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"Error detected in Trigger XML tag. File: %ls", pathname.string().c_str()); return false; } } @@ -380,13 +380,13 @@ bool CTriggerManager::LoadXml( const CStr& filename ) { if ( !LoadTriggerSpec(rootChild, XeroFile, false) ) { - LOG(CLogger::Error, LOG_CATEGORY, "Error detected in Trigger XML tag. File: %s", filename.c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"Error detected in Trigger XML tag. File: %ls", pathname.string().c_str()); return false; } } else { - LOG(CLogger::Error, LOG_CATEGORY, "Invalid tag in trigger XML. File: %s", filename.c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"Invalid tag in trigger XML. File: %ls", pathname.string().c_str()); return false; } } diff --git a/source/simulation/TriggerManager.h b/source/simulation/TriggerManager.h index 1141dd8469..c92a6df03d 100644 --- a/source/simulation/TriggerManager.h +++ b/source/simulation/TriggerManager.h @@ -198,7 +198,7 @@ public: ~CTriggerManager(); //Returns false on detection of error - bool LoadXml( const CStr& filename ); + bool LoadXml( const VfsPath& filename ); void Update(float delta); //Add simulation trigger (probably only called from JS) diff --git a/source/simulation/scripting/SimulationScriptInit.cpp b/source/simulation/scripting/SimulationScriptInit.cpp index 936629c0d7..52bbf02b91 100644 --- a/source/simulation/scripting/SimulationScriptInit.cpp +++ b/source/simulation/scripting/SimulationScriptInit.cpp @@ -78,7 +78,7 @@ void SimulationScriptInit() void SimulationInit() { - TIMER("SimulationInit"); + TIMER(L"SimulationInit"); new CEntityTemplateCollection; new CFormationCollection; @@ -87,8 +87,8 @@ void SimulationInit() g_TechnologyCollection.LoadTechnologies(); new CFormationManager; new CTriggerManager; - g_TriggerManager.LoadXml(CStr("scripts/TriggerSpecs.xml")); - g_ScriptingHost.RunScript("scripts/trigger_functions.js"); + g_TriggerManager.LoadXml(L"scripts/TriggerSpecs.xml"); + g_ScriptingHost.RunScript(L"scripts/trigger_functions.js"); // CEntityManager is managed by CWorld //new CEntityManager; @@ -98,9 +98,9 @@ void SimulationInit() void SimulationShutdown() { - TIMER_BEGIN("shutdown Pathfinder"); + TIMER_BEGIN(L"shutdown Pathfinder"); delete &g_Pathfinder; - TIMER_END("shutdown Pathfinder"); + TIMER_END(L"shutdown Pathfinder"); // Managed by CWorld // delete &g_EntityManager; diff --git a/source/sound/CMusicPlayer.cpp b/source/sound/CMusicPlayer.cpp index 2c89d2aa80..923d9dce24 100644 --- a/source/sound/CMusicPlayer.cpp +++ b/source/sound/CMusicPlayer.cpp @@ -23,7 +23,7 @@ #include #include -#define LOG_CATEGORY "audio" +#define LOG_CATEGORY L"audio" @@ -37,7 +37,7 @@ CMusicPlayer::CMusicPlayer(void) oal_Init(); if(!alIsExtensionPresent((ALubyte*)"AL_EXT_vorbis")) - debug_warn("no OpenAL ogg extension"); + debug_warn(L"no OpenAL ogg extension"); */ is_open = false; } @@ -59,11 +59,11 @@ void CMusicPlayer::Open(char* UNUSED(filename)) size_t sizeOfFile; if(vfs_load(filename, p, sizeOfFile) != INFO::OK) { - LOG(CLogger::Error, LOG_CATEGORY, "CMusicPlayer::open(): vfs_load for %s failed!\n", filename); + LOG(CLogger::Error, LOG_CATEGORY, L"CMusicPlayer::open(): vfs_load for %s failed!\n", filename); return; } else - LOG(CLogger::Normal, LOG_CATEGORY, "CMusicPlayer::open(): file %s loaded successfully\n", filename); + LOG(CLogger::Normal, LOG_CATEGORY, L"CMusicPlayer::open(): file %s loaded successfully\n", filename); memFile.dataPtr = (char*)p; memFile.dataRead = 0; memFile.dataSize = sizeOfFile; @@ -164,7 +164,7 @@ bool CMusicPlayer::Play() return true; if(!is_open) - debug_warn("play() called before open()"); + debug_warn(L"play() called before open()"); /* if(!stream(0)) return false; @@ -208,7 +208,7 @@ bool CMusicPlayer::Update() for(i = 0; i < NUM_BUFS; i++) if(bufs[i].al_buffer == buffer) goto found; - debug_warn("al_buffer not found!"); + debug_warn(L"al_buffer not found!"); found: //fill buffer with new data if false is returned the there is no more data @@ -233,7 +233,7 @@ void CMusicPlayer::Check() if(error != AL_NO_ERROR) { std::string str = errorString(error); - LOG(CLogger::Error, LOG_CATEGORY, "OpenAL error: %s\n", str.c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"OpenAL error: %s\n", str.c_str()); } */ } diff --git a/source/sound/CPlayList.cpp b/source/sound/CPlayList.cpp index 1d865a2738..f78ae586be 100644 --- a/source/sound/CPlayList.cpp +++ b/source/sound/CPlayList.cpp @@ -22,34 +22,35 @@ #include // sscanf #include "ps/Filesystem.h" -CPlayList::CPlayList(void) + +CPlayList::CPlayList() { tracks.clear(); } -CPlayList::CPlayList(const char* file) +CPlayList::CPlayList(const VfsPath& pathname) { - Load(file); + Load(pathname); } -CPlayList::~CPlayList(void) +CPlayList::~CPlayList() { } -void CPlayList::Load(const char* filename) +void CPlayList::Load(const VfsPath& pathname) { tracks.clear(); shared_ptr buf; size_t size; - if(g_VFS->LoadFile(filename, buf, size) < 0) + if(g_VFS->LoadFile(pathname, buf, size) < 0) return; const char* playlist = (const char*)buf.get(); char track[512]; while(sscanf(playlist, "%511s\n", track) == 1) - tracks.push_back(track); + tracks.push_back(CStrW(track)); } @@ -57,11 +58,11 @@ void CPlayList::List() { for(size_t i = 0; i < tracks.size(); i++) { - debug_printf("%s\n", tracks.at(i).c_str()); + debug_printf(L"%ls\n", tracks[i].c_str()); } } -void CPlayList::Add(std::string name) +void CPlayList::Add(std::wstring name) { tracks.push_back(name); } diff --git a/source/sound/CPlayList.h b/source/sound/CPlayList.h index e270feab28..8ff56c6301 100644 --- a/source/sound/CPlayList.h +++ b/source/sound/CPlayList.h @@ -19,21 +19,20 @@ #define INCLUDED_CPLAYLIST #include -#include -#include +#include "lib/file/vfs/vfs_path.h" class CPlayList { public: CPlayList(); - CPlayList(const char* file); + CPlayList(const VfsPath& pathname); ~CPlayList(); - void Load(const char* file); + void Load(const VfsPath& pathname); void List(); - void Add(std::string name); + void Add(std::wstring name); private: - std::vector tracks; + std::vector tracks; }; #endif diff --git a/source/sound/JSI_Sound.cpp b/source/sound/JSI_Sound.cpp index fa35f17d48..41ddd39257 100644 --- a/source/sound/JSI_Sound.cpp +++ b/source/sound/JSI_Sound.cpp @@ -23,9 +23,9 @@ #include "lib/res/h_mgr.h" // h_filename -JSI_Sound::JSI_Sound(const CStr& Filename) +JSI_Sound::JSI_Sound(const VfsPath& pathname) { - m_Handle = snd_open(Filename); + m_Handle = snd_open(pathname); // special-case to avoid throwing exceptions if quickstart has // disabled sound: set a flag queried by Construct; the object will @@ -185,7 +185,7 @@ void JSI_Sound::ScriptingInit() CStr JSI_Sound::ToString(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv)) { - return "[object Sound: " + h_filename(m_Handle).string() + "]"; + return "[object Sound: " + CStr(h_filename(m_Handle).string()) + "]"; } JSBool JSI_Sound::Construct(JSContext* cx, JSObject* UNUSED(obj), uintN argc, jsval* argv, jsval* rval) diff --git a/source/sound/JSI_Sound.h b/source/sound/JSI_Sound.h index 1f034b40ce..2b6c3ca2ec 100644 --- a/source/sound/JSI_Sound.h +++ b/source/sound/JSI_Sound.h @@ -43,7 +43,7 @@ public: // note: filename is stored by handle manager; no need to keep a copy here. - JSI_Sound(const CStr& Filename); + JSI_Sound(const VfsPath& pathname); ~JSI_Sound(); // Script-bound functions diff --git a/source/sound/SoundGroup.cpp b/source/sound/SoundGroup.cpp index f424ec01ff..6909073100 100644 --- a/source/sound/SoundGroup.cpp +++ b/source/sound/SoundGroup.cpp @@ -33,7 +33,7 @@ #include "ps/CLogger.h" #include "lib/rand.h" -#define LOG_CATEGORY "audio" +#define LOG_CATEGORY L"audio" void CSoundGroup::SetGain(float gain) @@ -70,10 +70,10 @@ CSoundGroup::CSoundGroup() SetDefaultValues(); } -CSoundGroup::CSoundGroup(const char *XMLfile) +CSoundGroup::CSoundGroup(const VfsPath& pathnameXML) { SetDefaultValues(); - LoadSoundGroup(XMLfile); + LoadSoundGroup(pathnameXML); } CSoundGroup::~CSoundGroup() @@ -122,7 +122,7 @@ void CSoundGroup::PlayNext(const CVector3D& position) if(!is_playing(m_hReplacement)) { // load up replacement file - m_hReplacement = snd_open(m_filepath + m_intensity_file); + m_hReplacement = snd_open(m_filepath/m_intensity_file); if(m_hReplacement < 0) // one cause: sound is disabled return; @@ -139,7 +139,7 @@ void CSoundGroup::PlayNext(const CVector3D& position) if(TestFlag(eRandOrder)) m_index = (size_t)rand(0, (size_t)filenames.size()); // (note: previously snd_group[m_index] was used in place of hs) - Handle hs = snd_open(m_filepath + filenames[m_index]); + Handle hs = snd_open(m_filepath/filenames[m_index]); if(hs < 0) // one cause: sound is disabled return; @@ -210,10 +210,10 @@ void CSoundGroup::Update(float TimeSinceLastFrame) } } -bool CSoundGroup::LoadSoundGroup(const char *XMLfile) +bool CSoundGroup::LoadSoundGroup(const VfsPath& pathnameXML) { CXeromyces XeroFile; - if (XeroFile.Load(XMLfile) != PSRETURN_OK) + if (XeroFile.Load(pathnameXML) != PSRETURN_OK) return false; // adjust the path name for resources if necessary @@ -250,7 +250,7 @@ bool CSoundGroup::LoadSoundGroup(const char *XMLfile) if (root.GetNodeName() != el_soundgroup) { - LOG(CLogger::Error, LOG_CATEGORY, "Invalid SoundGroup format (unrecognised root element '%s')", XeroFile.GetElementString(root.GetNodeName()).c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"Invalid SoundGroup format (unrecognised root element '%hs')", XeroFile.GetElementString(root.GetNodeName()).c_str()); return false; } @@ -341,13 +341,13 @@ bool CSoundGroup::LoadSoundGroup(const char *XMLfile) if(child_name == el_sound) { - CStr szTemp(child.GetText()); + CStrW szTemp(child.GetText()); this->filenames.push_back(szTemp); } if(child_name == el_path) { - m_filepath = child.GetText(); + m_filepath = CStrW(child.GetText()); } if(child_name == el_threshold) @@ -364,8 +364,7 @@ bool CSoundGroup::LoadSoundGroup(const char *XMLfile) if(child_name == el_replacement) { - m_intensity_file = child.GetText(); - + m_intensity_file = CStrW(child.GetText()); } } diff --git a/source/sound/SoundGroup.h b/source/sound/SoundGroup.h index 310f27b69e..07be3e49ac 100644 --- a/source/sound/SoundGroup.h +++ b/source/sound/SoundGroup.h @@ -53,6 +53,7 @@ Example SoundGroup.xml #define INCLUDED_SOUNDGROUP #include "lib/res/handle.h" +#include "lib/file/vfs/vfs_path.h" #include "ps/CStr.h" #include "maths/Vector3D.h" #include "lib/res/sound/snd_mgr.h" @@ -72,7 +73,7 @@ enum eSndGrpFlags class CSoundGroup { public: - CSoundGroup(const char *XMLfile); + CSoundGroup(const VfsPath& pathnameXML); CSoundGroup(void); ~CSoundGroup(void); @@ -82,7 +83,7 @@ public: void PlayNext(const CVector3D& position); // Load a group - bool LoadSoundGroup(const char *XMLfile); + bool LoadSoundGroup(const VfsPath& pathnameXML); void Reload(); @@ -108,10 +109,10 @@ private: Handle m_hReplacement; std::vector snd_group; // we store the handles so we can load now and play later - std::vector filenames; // we need the filenames so we can reload when necessary. + std::vector filenames; // we need the filenames so we can reload when necessary. std::vector playtimes; // it would be better to store this in with the Handles perhaps? - CStr m_filepath; // the file path for the list of sound file resources - CStr m_intensity_file; // the replacement aggregate 'intense' sound + VfsPath m_filepath; // the file path for the list of sound file resources + std::wstring m_intensity_file; // the replacement aggregate 'intense' sound float m_CurTime; // Time elapsed since soundgroup was created float m_TimeWindow; // The Intensity Threshold Window diff --git a/source/sound/SoundGroupMgr.cpp b/source/sound/SoundGroupMgr.cpp index c8347ae408..eaf66ea0ad 100644 --- a/source/sound/SoundGroupMgr.cpp +++ b/source/sound/SoundGroupMgr.cpp @@ -82,7 +82,7 @@ void CSoundGroupMgr::DeleteInstance() // out: size_t index into m_Groups // Loads the given XML file and returns an index for later use /////////////////////////////////////////// -size_t CSoundGroupMgr::AddGroup(const char *XMLFile) +size_t CSoundGroupMgr::AddGroup(const VfsPath& XMLFile) { CSoundGroup* newGroup = new CSoundGroup(XMLFile); m_Groups.push_back(newGroup); @@ -157,5 +157,5 @@ void CSoundGroupMgr::PlayNext(size_t index, const CVector3D& position) if(index < m_Groups.size()) m_Groups[index]->PlayNext(position); else - debug_printf("SND: PlayNext(%lu) invalid, %lu groups defined\n", (unsigned long)index, (unsigned long)m_Groups.size()); + debug_printf(L"SND: PlayNext(%lu) invalid, %lu groups defined\n", (unsigned long)index, (unsigned long)m_Groups.size()); } diff --git a/source/sound/SoundGroupMgr.h b/source/sound/SoundGroupMgr.h index 251a519e10..e4f5e0f55a 100644 --- a/source/sound/SoundGroupMgr.h +++ b/source/sound/SoundGroupMgr.h @@ -53,7 +53,7 @@ public: // out: size_t index into m_Groups // Loads the given XML file and returns an index for later use /////////////////////////////////////////// - size_t AddGroup(const char *XMLFile); + size_t AddGroup(const VfsPath& XMLFile); /////////////////////////////////////////// // RemoveGroup() diff --git a/source/test_setup.cpp b/source/test_setup.cpp index 49bc739217..457d523acd 100644 --- a/source/test_setup.cpp +++ b/source/test_setup.cpp @@ -58,7 +58,7 @@ class LeakReporter : public CxxTest::GlobalFixture static LeakReporter leakReporter; // Definition of function from lib/self_test.h -bool ts_str_contains(const std::string& str1, const std::string& str2) +bool ts_str_contains(const std::wstring& str1, const std::wstring& str2) { return str1.find(str2) != str1.npos; } diff --git a/source/tools/atlas/GameInterface/ActorViewer.cpp b/source/tools/atlas/GameInterface/ActorViewer.cpp index 894660ffb2..3204b7cfe5 100644 --- a/source/tools/atlas/GameInterface/ActorViewer.cpp +++ b/source/tools/atlas/GameInterface/ActorViewer.cpp @@ -179,7 +179,7 @@ void ActorViewer::SetActor(const CStrW& name, const CStrW& animation) if (id.empty()) return; - m.Unit = CUnit::Create((CStr)id, NULL, std::set(), m.ObjectManager); + m.Unit = CUnit::Create(CStr(id), NULL, std::set(), m.ObjectManager); if (! m.Unit) return; @@ -199,7 +199,7 @@ void ActorViewer::SetActor(const CStrW& name, const CStrW& animation) if (needsAnimReload) { - CStr anim = ((CStr)animation).LowerCase(); + CStr anim = CStr(animation).LowerCase(); float speed; // TODO: this is just copied from template_unit.xml and isn't the @@ -288,7 +288,7 @@ void ActorViewer::Render() glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glEnable(GL_TEXTURE_2D); - CFont font("console"); + CFont font(L"console"); font.Bind(); g_ProfileViewer.RenderProfile(); diff --git a/source/tools/atlas/GameInterface/CommandProc.cpp b/source/tools/atlas/GameInterface/CommandProc.cpp index d184989560..18aaed74ee 100644 --- a/source/tools/atlas/GameInterface/CommandProc.cpp +++ b/source/tools/atlas/GameInterface/CommandProc.cpp @@ -105,13 +105,13 @@ void CommandProc::Merge() { if (m_CurrentCommand == m_Commands.begin()) { - debug_warn("Merge illogic: no commands"); + debug_warn(L"Merge illogic: no commands"); return; } if (next(m_CurrentCommand) != m_Commands.end()) { - debug_warn("Merge illogic: not at stack top"); + debug_warn(L"Merge illogic: not at stack top"); return; } @@ -120,16 +120,16 @@ void CommandProc::Merge() if (prev == m_Commands.begin()) { - debug_warn("Merge illogic: only 1 command"); + debug_warn(L"Merge illogic: only 1 command"); return; } if ((*prev)->GetType() != (*m_CurrentCommand)->GetType()) { - const char* a = (*prev)->GetType(); - const char* b = (*m_CurrentCommand)->GetType(); - debug_printf("[incompatible: %s -> %s]\n", a, b); - debug_warn("Merge illogic: incompatible command"); + const CStrW a = (*prev)->GetType(); + const CStrW b = (*m_CurrentCommand)->GetType(); + debug_printf(L"[incompatible: %ls -> %ls]\n", a.c_str(), b.c_str()); + debug_warn(L"Merge illogic: incompatible command"); return; } diff --git a/source/tools/atlas/GameInterface/CommandProc.h b/source/tools/atlas/GameInterface/CommandProc.h index 428d2b047c..6c56722465 100644 --- a/source/tools/atlas/GameInterface/CommandProc.h +++ b/source/tools/atlas/GameInterface/CommandProc.h @@ -150,7 +150,7 @@ The following macros convert that into: d##t* msg; \ public: \ c##t##_base() : msg(NULL) {} \ - void MergeIntoPrevious(void*) { debug_warn("MergeIntoPrevious unimplemented in command " #t); } \ + void MergeIntoPrevious(void*) { debug_warn(L"MergeIntoPrevious unimplemented in command " WIDEN(#t)); } \ }; \ struct c##t : public c##t##_base diff --git a/source/tools/atlas/GameInterface/GameLoop.cpp b/source/tools/atlas/GameInterface/GameLoop.cpp index 3af771ed9c..c8412eff99 100644 --- a/source/tools/atlas/GameInterface/GameLoop.cpp +++ b/source/tools/atlas/GameInterface/GameLoop.cpp @@ -110,7 +110,7 @@ bool BeginAtlas(const CmdLineArgs& args, const DllLoader& dll) } catch (PSERROR_DllLoader&) { - debug_warn("Failed to initialise DLL"); + debug_warn(L"Failed to initialise DLL"); return false; } @@ -131,8 +131,8 @@ bool BeginAtlas(const CmdLineArgs& args, const DllLoader& dll) app_hooks_update(&hooks); // Disable the game's cursor rendering - extern CStr g_CursorName; - g_CursorName = ""; + extern CStrW g_CursorName; + g_CursorName = L""; state.args = args; state.running = true; @@ -182,10 +182,10 @@ bool BeginAtlas(const CmdLineArgs& args, const DllLoader& dll) } else { - debug_warn("Unrecognised message"); + debug_warn(L"Unrecognised message"); // CLogger might not be initialised, but this error will be sent // to the debug output window anyway so people can still see it - LOG(CLogger::Error, "atlas", "Unrecognised message (%s)", name.c_str()); + LOG(CLogger::Error, L"atlas", L"Unrecognised message (%hs)", name.c_str()); } if (msg->GetType() == IMessage::Query) diff --git a/source/tools/atlas/GameInterface/Handlers/CameraCtrlHandlers.cpp b/source/tools/atlas/GameInterface/Handlers/CameraCtrlHandlers.cpp index 7f090fc4af..77aee09d48 100644 --- a/source/tools/atlas/GameInterface/Handlers/CameraCtrlHandlers.cpp +++ b/source/tools/atlas/GameInterface/Handlers/CameraCtrlHandlers.cpp @@ -40,7 +40,7 @@ MESSAGEHANDLER(ScrollConstant) if (msg->dir < 0 || msg->dir > 3) { - debug_warn("ScrollConstant: invalid direction"); + debug_warn(L"ScrollConstant: invalid direction"); } else { @@ -96,7 +96,7 @@ MESSAGEHANDLER(Scroll) } else { - debug_warn("Scroll: Invalid type"); + debug_warn(L"Scroll: Invalid type"); } lastCameraPos = camera.GetTranslation(); } @@ -158,7 +158,7 @@ MESSAGEHANDLER(RotateAround) } else { - debug_warn("RotateAround: Invalid type"); + debug_warn(L"RotateAround: Invalid type"); } } diff --git a/source/tools/atlas/GameInterface/Handlers/CinemaHandler.cpp b/source/tools/atlas/GameInterface/Handlers/CinemaHandler.cpp index 32ebd0256d..adf368ef98 100644 --- a/source/tools/atlas/GameInterface/Handlers/CinemaHandler.cpp +++ b/source/tools/atlas/GameInterface/Handlers/CinemaHandler.cpp @@ -30,7 +30,7 @@ #include "maths/Quaternion.h" #include "lib/res/graphics/ogl_tex.h" -#define LOG_CATEGORY "Cinema" +#define LOG_CATEGORY L"Cinema" namespace AtlasMessage { diff --git a/source/tools/atlas/GameInterface/Handlers/CommandHandlers.cpp b/source/tools/atlas/GameInterface/Handlers/CommandHandlers.cpp index afe0e114f6..9a09bb83f9 100644 --- a/source/tools/atlas/GameInterface/Handlers/CommandHandlers.cpp +++ b/source/tools/atlas/GameInterface/Handlers/CommandHandlers.cpp @@ -34,7 +34,7 @@ MESSAGEHANDLER(DoCommand) } else { - debug_warn("Unrecognised command"); + debug_warn(L"Unrecognised command"); return; } diff --git a/source/tools/atlas/GameInterface/Handlers/MapHandlers.cpp b/source/tools/atlas/GameInterface/Handlers/MapHandlers.cpp index c7c98a0b83..7c99c82a84 100644 --- a/source/tools/atlas/GameInterface/Handlers/MapHandlers.cpp +++ b/source/tools/atlas/GameInterface/Handlers/MapHandlers.cpp @@ -137,7 +137,8 @@ MESSAGEHANDLER(LoadMap) MESSAGEHANDLER(SaveMap) { CMapWriter writer; - writer.SaveMap(CStr(L"maps/scenarios/" + *msg->filename), + const VfsPath pathname = VfsPath(L"maps/scenarios/") / *msg->filename; + writer.SaveMap(pathname, g_Game->GetWorld()->GetTerrain(), &g_Game->GetWorld()->GetUnitManager(), g_Renderer.GetWaterManager(), g_Renderer.GetSkyManager(), &g_LightEnv, g_Game->GetView()->GetCamera(), g_Game->GetView()->GetCinema()); diff --git a/source/tools/atlas/GameInterface/Handlers/MiscHandlers.cpp b/source/tools/atlas/GameInterface/Handlers/MiscHandlers.cpp index bdcaad1177..5f3174bcde 100644 --- a/source/tools/atlas/GameInterface/Handlers/MiscHandlers.cpp +++ b/source/tools/atlas/GameInterface/Handlers/MiscHandlers.cpp @@ -43,7 +43,7 @@ MESSAGEHANDLER(MessageTrace) MESSAGEHANDLER(Screenshot) { // TODO: allow non-big screenshots too - WriteBigScreenshot(".bmp", msg->tiles); + WriteBigScreenshot(L".bmp", msg->tiles); } QUERYHANDLER(CinemaRecord) diff --git a/source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp b/source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp index 7d92f80bd4..0d832ac2a1 100644 --- a/source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp +++ b/source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp @@ -46,7 +46,7 @@ #include "simulation/EntityManager.h" #include "simulation/TerritoryManager.h" -#define LOG_CATEGORY "editor" +#define LOG_CATEGORY L"editor" namespace AtlasMessage { @@ -443,20 +443,20 @@ BEGIN_COMMAND(CreateObject) { CEntityTemplate* base = g_EntityTemplateCollection.GetTemplate(name); if (! base) - LOG(CLogger::Error, LOG_CATEGORY, "Failed to load entity template '%ls'", name.c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"Failed to load entity template '%ls'", name.c_str()); else { HEntity ent = g_EntityManager.Create(base, m_Pos, m_Angle, selections); if (! ent) { - LOG(CLogger::Error, LOG_CATEGORY, "Failed to create entity of type '%ls'", name.c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"Failed to create entity of type '%ls'", name.c_str()); } else if (! ent->m_actor) { // We don't want to allow entities with no actors, because // they'll be be invisible and will confuse scenario designers - LOG(CLogger::Error, LOG_CATEGORY, "Failed to create entity of type '%ls'", name.c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"Failed to create entity of type '%ls'", name.c_str()); ent->Kill(); } else @@ -476,7 +476,7 @@ BEGIN_COMMAND(CreateObject) CUnit* unit = GetUnitManager().CreateUnit(CStr(name), NULL, selections); if (! unit) { - LOG(CLogger::Error, LOG_CATEGORY, "Failed to load nonentity actor '%ls'", name.c_str()); + LOG(CLogger::Error, LOG_CATEGORY, L"Failed to load nonentity actor '%ls'", name.c_str()); } else { diff --git a/source/tools/atlas/GameInterface/Handlers/TerrainHandlers.cpp b/source/tools/atlas/GameInterface/Handlers/TerrainHandlers.cpp index 58a6fcd8db..c86c2213ce 100644 --- a/source/tools/atlas/GameInterface/Handlers/TerrainHandlers.cpp +++ b/source/tools/atlas/GameInterface/Handlers/TerrainHandlers.cpp @@ -190,7 +190,7 @@ BEGIN_COMMAND(PaintTerrain) CTextureEntry* texentry = g_TexMan.FindTexture(CStrW(*msg->texture)); if (! texentry) { - debug_warn("Can't find texentry"); // TODO: nicer error handling + debug_warn(L"Can't find texentry"); // TODO: nicer error handling return; } Handle texture = texentry->GetHandle(); diff --git a/source/tools/atlas/GameInterface/Handlers/TriggerHandler.cpp b/source/tools/atlas/GameInterface/Handlers/TriggerHandler.cpp index 5a0b3bc79b..c691c12c19 100644 --- a/source/tools/atlas/GameInterface/Handlers/TriggerHandler.cpp +++ b/source/tools/atlas/GameInterface/Handlers/TriggerHandler.cpp @@ -317,7 +317,7 @@ QUERYHANDLER(GetTriggerChoices) } } else - debug_warn("Invalid special choice list for trigger specification parameter"); + debug_warn(L"Invalid special choice list for trigger specification parameter"); } msg->choices = choices; msg->translations = translations; diff --git a/source/tools/atlas/GameInterface/MessagePasserImpl.cpp b/source/tools/atlas/GameInterface/MessagePasserImpl.cpp index 08de769f8d..042cfce3e0 100644 --- a/source/tools/atlas/GameInterface/MessagePasserImpl.cpp +++ b/source/tools/atlas/GameInterface/MessagePasserImpl.cpp @@ -50,7 +50,7 @@ MessagePasserImpl::MessagePasserImpl() continue; } // Otherwise, it's a probably-fatal error - debug_warn("sem_open failed"); + debug_warn(L"sem_open failed"); break; } // Succeeded - use this semaphore @@ -61,7 +61,7 @@ MessagePasserImpl::MessagePasserImpl() if (! m_Semaphore) { - debug_warn("Failed to create semaphore for Atlas - giving up"); + debug_warn(L"Failed to create semaphore for Atlas - giving up"); // We will probably crash later - maybe we could fall back on sem_init, if this // ever fails in practice } @@ -83,7 +83,7 @@ void MessagePasserImpl::Add(IMessage* msg) debug_assert(msg->GetType() == IMessage::Message); if (m_Trace) - debug_printf("%8.3f add message: %s\n", timer_Time(), msg->GetName()); + debug_printf(L"%8.3f add message: %hs\n", timer_Time(), msg->GetName()); m_Mutex.Lock(); m_Queue.push(msg); @@ -108,7 +108,7 @@ IMessage* MessagePasserImpl::Retrieve() m_Mutex.Unlock(); if (m_Trace && msg) - debug_printf("%8.3f retrieved message: %s\n", timer_Time(), msg->GetName()); + debug_printf(L"%8.3f retrieved message: %hs\n", timer_Time(), msg->GetName()); return msg; } @@ -119,7 +119,7 @@ void MessagePasserImpl::Query(QueryMessage* qry, void(* UNUSED(timeoutCallback) debug_assert(qry->GetType() == IMessage::Query); if (m_Trace) - debug_printf("%8.3f add query: %s\n", timer_Time(), qry->GetName()); + debug_printf(L"%8.3f add query: %hs\n", timer_Time(), qry->GetName()); // Set the semaphore, so we can block until the query has been handled qry->m_Semaphore = static_cast(m_Semaphore); @@ -172,7 +172,7 @@ void MessagePasserImpl::Query(QueryMessage* qry, void(* UNUSED(timeoutCallback) // Keep retrying while EINTR, but other errors are probably fatal if (errno != EINTR) { - debug_warn("Semaphore wait failed"); + debug_warn(L"Semaphore wait failed"); return; // (leaks the semaphore) } } diff --git a/source/tools/atlas/GameInterface/Misc.cpp b/source/tools/atlas/GameInterface/Misc.cpp index 5e5637faca..e8f619fa8f 100644 --- a/source/tools/atlas/GameInterface/Misc.cpp +++ b/source/tools/atlas/GameInterface/Misc.cpp @@ -39,12 +39,12 @@ CVector3D AtlasMessage::Position::GetWorldSpace(bool floating) const break; case 2: - debug_warn("Invalid Position acquisition (unchanged without previous)"); + debug_warn(L"Invalid Position acquisition (unchanged without previous)"); return CVector3D(0.f, 0.f, 0.f); break; default: - debug_warn("Invalid Position type"); + debug_warn(L"Invalid Position type"); return CVector3D(0.f, 0.f, 0.f); } } @@ -87,7 +87,7 @@ void AtlasMessage::Position::GetScreenSpace(float& x, float& y) const break; default: - debug_warn("Invalid Position type"); + debug_warn(L"Invalid Position type"); x = y = 0.f; } } diff --git a/source/tools/atlas/GameInterface/View.cpp b/source/tools/atlas/GameInterface/View.cpp index 708c7176cf..7cb4934518 100644 --- a/source/tools/atlas/GameInterface/View.cpp +++ b/source/tools/atlas/GameInterface/View.cpp @@ -267,7 +267,7 @@ View* View::GetView(int /*eRenderView*/ view) case AtlasMessage::eRenderView::GAME: return View::GetView_Game(); case AtlasMessage::eRenderView::ACTOR: return View::GetView_Actor(); default: - debug_warn("Invalid view type"); + debug_warn(L"Invalid view type"); return View::GetView_None(); } }