huge cleanup and conversion of most string handling (especially paths) to unicode

please note: format strings must be %hs for char* arguments and %ls for
wchar_t*

This was SVN commit r7161.
This commit is contained in:
janwas 2009-11-03 21:46:35 +00:00
parent a46f3432f3
commit 8a52113e60
317 changed files with 2517 additions and 2588 deletions

View file

@ -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))

View file

@ -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();

View file

@ -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<void*>(&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;

View file

@ -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;

View file

@ -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");
}
}

View file

@ -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<SplineData>& 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<CStr> 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<CStr> 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++;

View file

@ -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;

View file

@ -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<MapTriggerGroup>& groups = g_TriggerManager.GetAllTriggerGroups();
std::list<MapTriggerGroup> rootChildren;
std::list<MapTriggerGroup>::const_iterator root = std::find( groups.begin(), groups.end(),
CStrW(L"Triggers") );
std::list<MapTriggerGroup>::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<MapTrigger>::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"&lt;"));
//paramString.Replace(CStrW(L">"), CStrW(L"&gt;"));
//paramString.Replace(L"<", L"&lt;");
//paramString.Replace(L">", L"&gt;");
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);
}

View file

@ -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<STileDesc>& 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,

View file

@ -173,7 +173,7 @@ CMaterialManager::CMaterialManager()
CMaterialManager::~CMaterialManager()
{
std::map<std::string, CMaterial *>::iterator iter;
std::map<VfsPath, CMaterial*>::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<std::string, CMaterial *>::iterator iter;
if((iter = m_Materials.find(std::string(file))) != m_Materials.end())
std::map<VfsPath, CMaterial*>::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(...)
{

View file

@ -30,9 +30,9 @@ public:
CMaterialManager();
~CMaterialManager();
CMaterial &LoadMaterial(const char *file);
CMaterial& LoadMaterial(const VfsPath& pathname);
private:
std::map<std::string, CMaterial *> m_Materials;
std::map<VfsPath, CMaterial*> m_Materials;
};
#endif

View file

@ -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();
}
}

View file

@ -19,6 +19,7 @@
#define INCLUDED_MESHMANAGER
#include "ps/CStr.h"
#include "lib/file/vfs/vfs_path.h"
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
@ -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, boost::weak_ptr<CModelDef>, CStr_hash_compare> mesh_map;
typedef STL_HASH_MAP<CStrW, boost::weak_ptr<CModelDef>, CStrW_hash_compare> mesh_map;
mesh_map m_MeshMap;
CColladaManager& m_ColladaManager;
};

View file

@ -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;
}

View file

@ -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);

View file

@ -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;

View file

@ -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

View file

@ -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<u8> CObjectBase::CalculateVariationKey(const std::vector<std::set<CS
std::vector<u8> choices;
std::multimap<CStr, CStr> chosenProps;
std::multimap<CStr, CStrW> chosenProps;
for (std::vector<std::vector<CObjectBase::Variant> >::iterator grp = m_VariantGroups.begin();
grp != m_VariantGroups.end();
@ -305,12 +302,12 @@ std::vector<u8> CObjectBase::CalculateVariationKey(const std::vector<std::set<CS
// and then insert the new ones:
for (std::vector<CObjectBase::Prop>::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<CStr, CStr>::iterator it = chosenProps.begin(); it != chosenProps.end(); ++it)
for (std::multimap<CStr, CStrW>::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<u8>&
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<CStr> CObjectBase::CalculateRandomVariation(const std::set<CStr>& initi
{
std::set<CStr> selections = initialSelections;
std::multimap<CStr, CStr> chosenProps;
std::multimap<CStr, CStrW> 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<CStr> CObjectBase::CalculateRandomVariation(const std::set<CStr>& initi
// and then insert the new ones:
for (std::vector<CObjectBase::Prop>::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<CStr, CStr>::iterator it = chosenProps.begin(); it != chosenProps.end(); ++it)
for (std::multimap<CStr, CStrW>::iterator it = chosenProps.begin(); it != chosenProps.end(); ++it)
{
CObjectBase* prop = m_ObjectManager.FindObjectBase(it->second);
if (prop)
@ -566,7 +563,7 @@ std::vector<std::vector<CStr> > 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);
}

View file

@ -25,6 +25,7 @@ class CObjectManager;
#include <vector>
#include <set>
#include <map>
#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<Anim> m_Anims;
@ -70,8 +71,8 @@ public:
struct Variation
{
CStr texture;
CStr model;
VfsPath texture;
VfsPath model;
CStr color;
std::multimap<CStr, CObjectBase::Prop> props;
std::multimap<CStr, CObjectBase::Anim> anims;
@ -96,13 +97,13 @@ public:
// variant names.
std::vector<std::vector<CStr> > 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<Variant> > m_VariantGroups;
CObjectManager& m_ObjectManager;
};
#endif

View file

@ -37,7 +37,7 @@
#include <sstream>
#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<std::set<CStr> >& 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<std::set<CStr> >& 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<std::set<CStr> >& 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<std::set<CStr> >& 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<std::set<CStr> >& 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<std::set<CStr> >& 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

View file

@ -28,6 +28,7 @@ struct SPropPoint;
#include <set>
#include <vector>
#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,

View file

@ -25,7 +25,7 @@
#include "ps/Profile.h"
#include "ps/Filesystem.h"
#define LOG_CATEGORY "graphics"
#define LOG_CATEGORY L"graphics"
template<typename T, typename S>
static void delete_pair_2nd(std::pair<T,S> 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<CStr, CObjectBase*>::iterator it = m_ObjectBases.find(objectname);
std::map<CStrW, CObjectBase*>::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<std::set<CStr> > selections; // TODO - should this really be empty?
return FindObjectVariation(objname, selections);
}
CObjectEntry* CObjectManager::FindObjectVariation(const char* objname, const std::vector<std::set<CStr> >& selections)
CObjectEntry* CObjectManager::FindObjectVariation(const wchar_t* objname, const std::vector<std::set<CStr> >& selections)
{
CObjectBase* base = FindObjectBase(objname);
@ -177,10 +177,10 @@ static LibError GetObjectName_ThunkCb(const VfsPath& pathname, const FileInfo& U
void CObjectManager::GetAllObjectNames(std::vector<CStr>& 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<CStr>& 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);
}

View file

@ -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<std::set<CStr> >& selections);
CObjectEntry* FindObjectVariation(const wchar_t* objname, const std::vector<std::set<CStr> >& selections);
CObjectEntry* FindObjectVariation(CObjectBase* base, const std::vector<std::set<CStr> >& selections);
// Get all names, quite slowly. (Intended only for Atlas.)
@ -78,7 +78,7 @@ private:
CSkeletonAnimManager& m_SkeletonAnimManager;
std::map<ObjectKey, CObjectEntry*> m_Objects;
std::map<CStr, CObjectBase*> m_ObjectBases;
std::map<CStrW, CObjectBase*> m_ObjectBases;
};
#endif

View file

@ -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;

View file

@ -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; }

View file

@ -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)))

View file

@ -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);
}

View file

@ -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

View file

@ -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<CStr,CSkeletonAnimDef*>::iterator Iter;
typedef std::map<VfsPath,CSkeletonAnimDef*>::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<CStr, CSkeletonAnimDef*>::iterator iter = m_Animations.find(name);
std::map<VfsPath, CSkeletonAnimDef*>::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

View file

@ -24,6 +24,7 @@
#include <map>
#include <set>
#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<CStr8, CSkeletonAnimDef*> m_Animations;
std::map<VfsPath, CSkeletonAnimDef*> m_Animations;
CColladaManager& m_ColladaManager;
};

View file

@ -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);

View file

@ -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; i<children.Count; ++i)
{
//debug_printf("Object %d\n", i);
//debug_printf(L"Object %d\n", i);
XMBElement child = children.Item(i);
if (child.GetNodeName() == el_terrain)
{
CTerrainPropertiesPtr ret (new CTerrainProperties(parent));
ret->LoadXml(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;i<parserLine.GetArgCount();i++)
@ -154,7 +154,7 @@ void CTerrainProperties::LoadXml(XMBElement node, CXeromyces *pFile, const char
else if (attr.Name == attr_mmap)
{
CColor col;
if (!col.ParseString((CStr)attr.Value, 255))
if (!col.ParseString(CStr(attr.Value), 255))
continue;
// m_BaseColor is BGRA
@ -178,17 +178,17 @@ void CTerrainProperties::LoadXml(XMBElement node, CXeromyces *pFile, const char
if (child.GetNodeName() == elmt_passable)
{
ReadPassability(true, child, pFile, path);
ReadPassability(true, child, pFile, pathname);
}
else if (child.GetNodeName() == elmt_impassable)
{
ReadPassability(false, child, pFile, path);
ReadPassability(false, child, pFile, pathname);
}
// TODO Parse information about doodads and events and store it
}
}
void CTerrainProperties::ReadPassability(bool passable, XMBElement node, CXeromyces *pFile, const char *UNUSED(path))
void CTerrainProperties::ReadPassability(bool passable, XMBElement node, CXeromyces *pFile, const VfsPath& UNUSED(pathname))
{
#define ATTR(x) int attr_##x = pFile->GetAttributeID(#x)
// Passable Attribs

View file

@ -28,6 +28,7 @@
#define INCLUDED_TERRAINPROPERTIES
#include "ps/CStr.h"
#include "lib/file/vfs/vfs_path.h"
#include <boost/shared_ptr.hpp>
class CTerrainGroup;
@ -74,8 +75,8 @@ private:
// Passability definitions
std::vector<STerrainPassability> 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);

View file

@ -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;
};

View file

@ -30,13 +30,13 @@
#include "Texture.h"
#include "renderer/Renderer.h"
#define LOG_CATEGORY "graphics"
#define LOG_CATEGORY L"graphics"
std::map<Handle, CTextureEntry *> 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;

View file

@ -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; }

View file

@ -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<subdirectoryNames.size();i++)
{
char subdirectoryPath[PATH_MAX];
path_append(subdirectoryPath, cur_dir_path, subdirectoryNames[i].c_str(), PATH_APPEND_SLASH);
VfsPath subdirectoryPath = path/subdirectoryNames[i]/L"/"; // (VFS paths must end with a slash)
RecurseDirectory(props, subdirectoryPath);
}
LoadTextures(props, cur_dir_path);
LoadTextures(props, path);
}
int CTextureManager::LoadTerrainTextures()
{
RecurseDirectory(CTerrainPropertiesPtr(), "art/textures/terrain/types/");
RecurseDirectory(CTerrainPropertiesPtr(), L"art/textures/terrain/types/");
return 0;
}
CTerrainGroup *CTextureManager::FindGroup(const CStr& name)
CTerrainGroup* CTextureManager::FindGroup(const CStr& name)
{
TerrainGroupMap::const_iterator it=m_TerrainGroups.find(name);
if (it != m_TerrainGroups.end())

View file

@ -84,12 +84,12 @@ private:
// Find+load all textures in directory; check if
// there's an override XML with the same basename (if there is, load it)
void LoadTextures(const CTerrainPropertiesPtr& props, const char* dir);
void LoadTextures(const CTerrainPropertiesPtr& props, const VfsPath& path);
// Load all terrains below path, using props as the parent property sheet.
void RecurseDirectory(const CTerrainPropertiesPtr& props, const char* dir);
void RecurseDirectory(const CTerrainPropertiesPtr& props, const VfsPath& path);
CTerrainPropertiesPtr GetPropertiesFromFile(const CTerrainPropertiesPtr& props, const char* path);
CTerrainPropertiesPtr GetPropertiesFromFile(const CTerrainPropertiesPtr& props, const VfsPath& pathname);
public:
// constructor, destructor
@ -107,7 +107,7 @@ public:
// Create a texture object for a new terrain texture at path, using the
// property sheet props.
CTextureEntry *AddTexture(const CTerrainPropertiesPtr& props, const CStr& path);
CTextureEntry *AddTexture(const CTerrainPropertiesPtr& props, const VfsPath& path);
// Remove the texture from all our maps and lists and delete it afterwards.
void DeleteTexture(CTextureEntry* entry);

View file

@ -46,7 +46,7 @@ CUnit::~CUnit()
delete m_Model;
}
CUnit* CUnit::Create(const CStr& actorName, CEntity* entity,
CUnit* CUnit::Create(const CStrW& actorName, CEntity* entity,
const std::set<CStr>& selections, CObjectManager& objectManager)
{
CObjectBase* base = objectManager.FindObjectBase(actorName);

View file

@ -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<CStr>& selections, CObjectManager& objectManager);
// destructor

View file

@ -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<u8> 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);

View file

@ -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<CStr>::GetSetting(this, "font", font) != PSRETURN_OK || font.empty())
CStrW font;
if (GUI<CStrW>::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<CGUIString>::GetSetting(this, "caption", caption);

View file

@ -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<CStr>::GetSetting(this, "font", font) != PSRETURN_OK || font.empty())
CStrW font;
if (GUI<CStrW>::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<float>::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<float>::GetSetting(this, "square_side", square_side);
GUI<float>::GetSetting(this, "buffer_zone", buffer_zone);
GUI<CStr>::GetSetting(this, "font", font_name);
GUI<CStrW>::GetSetting(this, "font", font_name);
GUI<bool>::GetSetting(this, "checked", checked);
GUI<int>::GetSetting(this, "cell_id", cell_id);

View file

@ -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

View file

@ -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<SGUIText::STextCall>::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; i<children.Count; ++i)
{
//debug_printf("Object %d\n", i);
//debug_printf(L"Object %d\n", i);
XMBElement child = children.Item(i);
if (child.GetNodeName() == el_script)
@ -1207,7 +1206,7 @@ void CGUI::Xeromyces_ReadRootSetup(XMBElement Element, CXeromyces* pFile)
}
else
{
debug_warn("Invalid data - DTD shouldn't allow this");
debug_warn(L"Invalid data - DTD shouldn't allow this");
}
}
}
@ -1235,7 +1234,7 @@ void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec
if (!object)
{
// Report error that object was unsuccessfully loaded
ReportParseError("Unrecognized type \"%s\"", type.c_str());
ReportParseError(L"Unrecognized type \"%hs\"", type.c_str());
return;
}
@ -1269,7 +1268,7 @@ void CGUI::Xeromyces_ReadObject(XMBElement Element, CXeromyces* pFile, IGUIObjec
// additional check
if (m_Styles.count(argStyle) == 0)
{
ReportParseError("Trying to use style '%s' that doesn't exist.", argStyle.c_str());
ReportParseError(L"Trying to use style '%hs' that doesn't exist.", argStyle.c_str());
}
else object->LoadStyle(*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 <action> 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<CClientArea>::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<CClientArea>::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<CRect>::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<CSize>::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<float>::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<CColor>::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<CColor>::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<bool>::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<int>::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<float>::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<float>::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<CSize>::ParseString(attr_value, size))
ReportParseError("Error parsing '%s' (\"%s\") inside <icon>.", attr_name.c_str(), attr_value.c_str());
ReportParseError(L"Error parsing '%hs' (\"%hs\") inside <icon>.", 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<int>::ParseString(attr_value, cell_id))
ReportParseError("Error parsing '%s' (\"%s\") inside <icon>.", attr_name.c_str(), attr_value.c_str());
ReportParseError(L"Error parsing '%hs' (\"%hs\") inside <icon>.", 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
{

View file

@ -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

View file

@ -23,7 +23,7 @@ IGUIScrollBar
#include "GUI.h"
#include "ps/CLogger.h"
#define LOG_CATEGORY "gui"
#define LOG_CATEGORY L"gui"
CGUIScrollBarVertical::CGUIScrollBarVertical()

View file

@ -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;

View file

@ -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<CStr>::GetSetting(this, "font", font_name);
GUI<CStrW>::GetSetting(this, "font", font_name);
GUI<CColor>::GetSetting(this, "textcolor", color);
GUI<CColor>::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<CStr>::GetSetting(this, "font", font_name);
GUI<CStrW>::GetSetting(this, "font", font_name);
GUI<CStrW>::GetSetting(this, "caption", caption);
GUI<float>::GetSetting(this, "buffer_zone", buffer_zone);
GUI<bool>::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<CStr>::GetSetting(this, "font", font_name);
GUI<CStrW>::GetSetting(this, "font", font_name);
GUI<bool>::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<CStr>::GetSetting(this, "font", font_name);
GUI<CStrW>::GetSetting(this, "font", font_name);
GUI<bool>::GetSetting(this, "scrollbar", scrollbar);
float scroll=0.f;

View file

@ -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<CGUIList>::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<CStr>::GetSetting(this, "font", font) != PSRETURN_OK || font.empty())
CStrW font;
if (GUI<CStrW>::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;
}

View file

@ -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<CStr>::GetSetting(this, "font", font) != PSRETURN_OK || font.empty())
CStrW font;
if (GUI<CStrW>::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;

View file

@ -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<CStr>::GetSetting(this, "font", font) != PSRETURN_OK || font.empty())
font = "default";
CStrW font;
if (GUI<CStrW>::GetSetting(this, "font", font) != PSRETURN_OK || font.empty())
font = L"default";
float buffer_zone = 0.f;
GUI<float>::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!");
}

View file

@ -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;
}

View file

@ -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<CPos>::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<CStr>::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<int>::GetSetting(tooltipobj, "delay", delay);

View file

@ -26,7 +26,7 @@ GUI text
#include "ps/Parser.h"
#include <algorithm>
#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<CSize>::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<CColor>::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

View file

@ -120,7 +120,7 @@ struct SGUIText
/**
* Font name
*/
CStr m_Font;
CStrW m_Font;
/**
* Settings

View file

@ -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<T>::GetSettingPointer(const IGUIObject *pObject, const CStr& Settin
std::map<CStr, SGUISetting>::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<T>::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;

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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;
}

View file

@ -136,7 +136,7 @@ bool I18n::operator== (BufferVariable& a, BufferVariable& b)
case vartype_rawstring:
return *static_cast<BufferVariable_rawstring*>(&a) == *static_cast<BufferVariable_rawstring*>(&b);
}
debug_warn("Invalid buffer variable vartype");
debug_warn(L"Invalid buffer variable vartype");
return false;
}

View file

@ -25,7 +25,7 @@
#include <algorithm>
#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<Str, DictData>::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<Str, std::vector<Str> >::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);

View file

@ -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;
}
}

View file

@ -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<Buff
if (! called)
{
LOG(CLogger::Error, LOG_CATEGORY, "I18n: Error executing JS function '%s'", name);
LOG(CLogger::Error, LOG_CATEGORY, L"I18n: Error executing JS function '%hs'", name);
return L"(JS error)";
}
@ -349,13 +349,13 @@ const StrImW ScriptObject::CallFunction(const char* name, const std::vector<Buff
JSString* str = JS_ValueToString(Context, rval);
if (! str)
{
debug_warn("Conversion to string failed");
debug_warn(L"Conversion to string failed");
return L"(JS error)";
}
jschar* chars = JS_GetStringChars(str);
if (! chars)
{
debug_warn("GetStringChars failed");
debug_warn(L"GetStringChars failed");
return L"(JS error)";
}
return StrImW(chars, JS_GetStringLength(str));
@ -369,7 +369,7 @@ ScriptValueString::ScriptValueString(ScriptObject& script, const wchar_t* s)
JSString* str = StringConvert::wchars_to_jsstring(Context, s);
if (!str)
{
debug_warn("Error creating JS string");
debug_warn(L"Error creating JS string");
Value = JSVAL_NULL;
}
else
@ -441,7 +441,7 @@ jsval ScriptValueVariable::GetJsval(const std::vector<BufferVariable*>& 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<BufferVariable*>& 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<BufferVariable*>& 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<BufferVariable*>& vars)
return STRING_TO_JSVAL(val);
}
default:
debug_warn("Invalid type");
debug_warn(L"Invalid type");
return JSVAL_NULL;
}
}

View file

@ -28,7 +28,7 @@ template<typename T> void delete_fn(T* v) { delete v; }
#include <iostream>
#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<BufferVariable>);

View file

@ -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();
}

View file

@ -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);

View file

@ -27,7 +27,6 @@
#include <cstdio>
#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);
}

View file

@ -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

View file

@ -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<char,", "string<")
REPLACE("std::basic_string<unsigned short,", "wstring<")
STRIP("std::char_traits<char>,")
STRIP("std::char_traits<unsigned short>,")
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<char,", L"string<")
REPLACE(L"std::basic_string<unsigned short,", L"wstring<")
STRIP(L"std::char_traits<char>,")
STRIP(L"std::char_traits<unsigned short>,")
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<class T> 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

View file

@ -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

View file

@ -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))

View file

@ -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()
{

View file

@ -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<IArchiveWriter> PIArchiveWriter;

View file

@ -82,7 +82,7 @@ class IdMgr
const Map::value_type item = std::make_pair(node.atom_fn, id);
std::pair<Map::iterator, bool> 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");
}
}

View file

@ -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<u8>& buf, size_t size) const
virtual LibError Load(const std::wstring& UNUSED(name), const shared_ptr<u8>& 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_Zip> 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));
}

View file

@ -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

View file

@ -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<u8>& buf, size_t size) const = 0;
virtual LibError Load(const std::wstring& name, const shared_ptr<u8>& buf, size_t size) const = 0;
};
typedef shared_ptr<IFileLoader> PIFileLoader;

View file

@ -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<typename T> 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)
);
}

View file

@ -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()

View file

@ -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<u8>& buf, size_t size) const
/*virtual*/ LibError RealDirectory::Load(const std::wstring& name, const shared_ptr<u8>& 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<u8>& fileContents, size_t size)
LibError RealDirectory::Store(const std::wstring& name, const shared_ptr<u8>& 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<u8>& 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<u8>& 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()));
}

View file

@ -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<u8>& buf, size_t size) const;
virtual wchar_t LocationCode() const;
virtual LibError Load(const std::wstring& name, const shared_ptr<u8>& buf, size_t size) const;
LibError Store(const std::string& name, const shared_ptr<u8>& fileContents, size_t size);
LibError Store(const std::wstring& name, const shared_ptr<u8>& 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<RealDirectory> 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

View file

@ -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);
}
};

View file

@ -25,7 +25,10 @@
#include <cstdio>
#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:

View file

@ -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;

View file

@ -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;

View file

@ -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<File> PFile;

View file

@ -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<DIR> 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;

View file

@ -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<FileInfo> FileInfos;
typedef std::vector<std::string> DirectoryNames;
typedef std::vector<std::wstring> 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
// <mode> 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

View file

@ -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<FileInfo> files;
RETURN_ERR(fs->GetDirectoryEntries(path, &files, 0));
@ -54,7 +54,7 @@ struct FileInfoNameLess : public std::binary_function<const FileInfo, const File
{
bool operator()(const FileInfo& fileInfo1, const FileInfo& fileInfo2) const
{
return strcasecmp(fileInfo1.Name().c_str(), fileInfo2.Name().c_str()) < 0;
return wcscasecmp(fileInfo1.Name().c_str(), fileInfo2.Name().c_str()) < 0;
}
};
@ -64,11 +64,11 @@ void SortFiles(FileInfos& files)
}
struct NameLess : public std::binary_function<const std::string, const std::string, bool>
struct NameLess : public std::binary_function<const std::wstring, const std::wstring, bool>
{
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);

View file

@ -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);
/**

View file

@ -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);

View file

@ -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;

View file

@ -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));

View file

@ -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<IVFS> PIVFS;

View file

@ -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

View file

@ -20,5 +20,5 @@
bool vfs_path_IsDirectory(const VfsPath& pathname)
{
return pathname.empty() || pathname.leaf() == ".";
return pathname.empty() || pathname.leaf() == L".";
}

View file

@ -34,14 +34,14 @@ struct VfsPathTraits;
* rationale: a distinct specialization of basic_path prevents inadvertent
* assignment from other path types.
**/
typedef fs::basic_path<std::string, VfsPathTraits> VfsPath;
typedef fs::basic_path<std::wstring, VfsPathTraits> VfsPath;
typedef std::vector<VfsPath> 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)
{

View file

@ -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]);

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