1
0
forked from 0ad/0ad

part4: adapt codebase to changes in lib/

mostly straightforward except for CVSFile / Filesystem. moved the former
into the newly created latter component. removed VFSUtil entirely (that
functionality is available from lib/file/file_system_util.h)

Xeromyces.cpp: simplify buffer handling since smart pointers are now in
play. also use WriteBuffer instead of membuffer.

This was SVN commit r5519.
This commit is contained in:
janwas 2007-12-20 20:21:45 +00:00
parent 63086f4e26
commit e2eb5b2610
68 changed files with 619 additions and 980 deletions

View File

@ -12,8 +12,6 @@
#include "maths/Vector3D.h"
#include "maths/Vector4D.h"
#include "maths/Quaternion.h"
#include "lib/res/file/vfs.h"
#include "lib/res/mem.h"
CCinemaPath::CCinemaPath(const CCinemaData& data, const TNSpline& spline)
: CCinemaData(data), TNSpline(spline), m_TimeElapsed(0.f)

View File

@ -4,12 +4,10 @@
#include "graphics/ModelDef.h"
#include "lib/fnv_hash.h"
#include "lib/res/file/vfs.h"
#include "lib/res/handle.h"
#include "ps/CLogger.h"
#include "ps/CStr.h"
#include "ps/CVFSFile.h"
#include "ps/DllLoader.h"
#include "ps/Filesystem.h"
namespace Collada
{
@ -18,19 +16,6 @@ namespace Collada
namespace
{
struct VFSOutputCB
{
VFSOutputCB(Handle hf) : hf(hf) {}
void operator() (const char* data, unsigned int length)
{
FileIOBuf buf = (FileIOBuf)data;
const ssize_t ret = vfs_io(hf, length, &buf);
WARN_ERR(ret);
}
Handle hf;
};
void ColladaLog(int severity, const char* text)
{
LOG(severity == LOG_INFO ? NORMAL :
@ -40,8 +25,8 @@ namespace
void ColladaOutput(void* cb_data, const char* data, unsigned int length)
{
VFSOutputCB* cb = static_cast<VFSOutputCB*>(cb_data);
(*cb)(data, length);
WriteBuffer* writeBuffer = static_cast<WriteBuffer*>(cb_data);
writeBuffer->Append(data, (size_t)length);
}
}
@ -122,34 +107,22 @@ public:
// We need to null-terminate the buffer, so do it (possibly inefficiently)
// by converting to a CStr
CStr daeData;
{
CVFSFile daeFile;
if (daeFile.Load(daeFilename) != PSRETURN_OK)
return false;
daeData = daeFile.GetAsString();
// scope closes daeFile - necessary if we don't use FILE_LONG_LIVED
}
// Prepare the output file
Handle hf = vfs_open(pmdFilename, FILE_WRITE|FILE_NO_AIO);
if (hf < 0)
return false;
// Do the conversion
VFSOutputCB cb (hf);
// Do the conversion into a memory buffer
WriteBuffer writeBuffer;
switch (type)
{
case CColladaManager::PMD: convert_dae_to_pmd(daeData.c_str(), ColladaOutput, static_cast<void*>(&cb)); break;
case CColladaManager::PSA: convert_dae_to_psa(daeData.c_str(), ColladaOutput, static_cast<void*>(&cb)); break;
case CColladaManager::PMD: convert_dae_to_pmd(daeData.c_str(), ColladaOutput, &writeBuffer); break;
case CColladaManager::PSA: convert_dae_to_psa(daeData.c_str(), ColladaOutput, &writeBuffer); break;
}
vfs_close(hf);
g_VFS->CreateFile(pmdFilename, writeBuffer.Data(), writeBuffer.Size());
return true;
}
@ -204,7 +177,7 @@ CStr CColladaManager::GetLoadableFilename(const CStr& sourceName, FileType type)
// be "psa" too.)
CStr dae = sourceName + ".dae";
if (! vfs_exists(dae))
if (! FileExists(dae))
{
// No .dae - got to use the .pmd, assuming there is one
return sourceName + extn;
@ -212,8 +185,8 @@ CStr CColladaManager::GetLoadableFilename(const CStr& sourceName, FileType type)
// There is a .dae - see if there's an up-to-date cached copy
struct stat fileStat;
if (vfs_stat(dae, &fileStat) < 0)
FileInfo fileInfo;
if (g_VFS->GetFileInfo(dae, &fileInfo) < 0)
{
// This shouldn't occur for any sensible reasons
LOG(ERROR, "collada", "Failed to stat DAE file '%s'", dae.c_str());
@ -226,7 +199,7 @@ CStr CColladaManager::GetLoadableFilename(const CStr& sourceName, FileType type)
// (Remove the lowest bit of mtime because some things round it to a
// resolution of 2 seconds)
struct { int version; int mtime; int size; } hashSource
= { COLLADA_CONVERTER_VERSION, (int)fileStat.st_mtime & ~1, (int)fileStat.st_size };
= { COLLADA_CONVERTER_VERSION, (int)fileInfo.MTime() & ~1, (int)fileInfo.Size() };
cassert(sizeof(hashSource) == sizeof(int) * 3); // no padding, because that would be bad
// Calculate the hash, convert to hex
@ -236,7 +209,7 @@ CStr CColladaManager::GetLoadableFilename(const CStr& sourceName, FileType type)
// realDaePath is "mods/whatever/art/meshes/whatever.dae"
char realDaePath[PATH_MAX];
vfs_realpath(dae, realDaePath);
g_VFS->GetRealPath(dae, realDaePath);
// cachedPmdVfsPath is "cache/mods/whatever/art/meshes/whatever_{hash}.pmd"
CStr cachedPmdVfsPath = "cache/";
@ -249,7 +222,7 @@ CStr CColladaManager::GetLoadableFilename(const CStr& sourceName, FileType type)
cachedPmdVfsPath += extn;
// If it's not in the cache, we'll have to create it first
if (! vfs_exists(cachedPmdVfsPath))
if (! FileExists(cachedPmdVfsPath))
{
if (! m->Convert(dae, cachedPmdVfsPath, type))
return ""; // failed to convert

View File

@ -29,7 +29,7 @@ u32 (*ConvertRGBColorTo4ub)(const RGBColor& src) = fallback_ConvertRGBColorTo4ub
// Assembler-optimized function for color conversion
#if CPU_IA32
#if ARCH_IA32
EXTERN_C u32 sse_ConvertRGBColorTo4ub(const RGBColor& src);
#endif
@ -38,7 +38,7 @@ void ColorActivateFastImpl()
if(0)
{
}
#if CPU_IA32
#if ARCH_IA32
else if (ia32_cap(IA32_CAP_SSE))
{
ConvertRGBColorTo4ub = sse_ConvertRGBColorTo4ub;

View File

@ -1,7 +1,5 @@
#include "precompiled.h"
#include "lib/res/file/vfs.h"
#include "Camera.h"
#include "CinemaTrack.h"
#include "LightEnv.h"
@ -22,7 +20,7 @@
#include "maths/NUSpline.h"
#include "ps/Loader.h"
#include "ps/Player.h"
#include "ps/VFSUtil.h"
#include "ps/Filesystem.h"
#include "ps/XML/XMLWriter.h"
#include "renderer/SkyManager.h"
#include "renderer/WaterManager.h"
@ -163,13 +161,6 @@ void CMapWriter::WriteXML(const char* filename,
CUnitManager* pUnitMan, WaterManager* pWaterMan, SkyManager* pSkyMan,
CLightEnv* pLightEnv, CCamera* pCamera, CCinemaManager* pCinema)
{
Handle h = vfs_open(filename, FILE_WRITE_TO_TARGET|FILE_NO_AIO);
if (h <= 0)
{
debug_warn("Failed to open map XML file");
return;
}
XML_Start();
{
@ -408,11 +399,8 @@ void CMapWriter::WriteXML(const char* filename,
}
}
}
if (! XML_StoreVFS(h))
{
debug_warn("Failed to write map XML file");
}
(void)vfs_close(h);
if (! XML_StoreVFS(filename))
debug_assert(0); // failed to write map XML file
}
void CMapWriter::WriteTriggerGroup(XMLWriter_File& xml_file_, const MapTriggerGroup& group, const std::list<MapTriggerGroup>& groupList)
@ -528,20 +516,20 @@ void CMapWriter::RewriteAllMaps(CTerrain* pTerrain, CUnitManager* pUnitMan,
WaterManager* pWaterMan, SkyManager* pSkyMan,
CLightEnv* pLightEnv, CCamera* pCamera, CCinemaManager* pCinema)
{
VFSUtil::FileList files;
VFSUtil::FindFiles("maps/scenarios", "*.pmp", files);
for (VFSUtil::FileList::iterator it = files.begin(); it != files.end(); ++it)
VfsPaths pathnames;
fs_GetPathnames(g_VFS, "maps/scenarios", "*.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(*it, pTerrain, pUnitMan, pWaterMan, pSkyMan, pLightEnv, pCamera, pCinema);
reader->LoadMap(pathname, pTerrain, pUnitMan, pWaterMan, pSkyMan, pLightEnv, pCamera, pCinema);
LDR_EndRegistering();
LDR_NonprogressiveLoad();
CStr n (*it);
n.Replace("scenarios/", "scenarios/new/");
CStr newPathname(pathname);
newPathname.Replace("scenarios/", "scenarios/new/");
CMapWriter writer;
writer.SaveMap(n, pTerrain, pUnitMan, pWaterMan, pSkyMan, pLightEnv, pCamera, pCinema);
writer.SaveMap(newPathname, pTerrain, pUnitMan, pWaterMan, pSkyMan, pLightEnv, pCamera, pCinema);
}
}

View File

@ -1,7 +1,6 @@
#include "precompiled.h"
#include "lib/ogl.h"
#include "lib/res/res.h"
#include "Material.h"
#include "ps/Player.h"
#include "ps/Game.h"

View File

@ -7,7 +7,7 @@
#include <boost/weak_ptr.hpp>
class CModelDef;
typedef boost::shared_ptr<CModelDef> CModelDefPtr;
typedef shared_ptr<CModelDef> CModelDefPtr;
class CColladaManager;

View File

@ -16,7 +16,6 @@
#include "ps/XML/Xeromyces.h"
#include "ps/XML/XMLWriter.h"
#include "lib/res/file/vfs.h"
#include "lib/rand.h"
#include <sstream>

View File

@ -6,7 +6,7 @@
#include "graphics/ObjectEntry.h"
#include "ps/CLogger.h"
#include "ps/Profile.h"
#include "ps/VFSUtil.h"
#include "ps/Filesystem.h"
#define LOG_CATEGORY "graphics"
@ -150,21 +150,20 @@ void CObjectManager::UnloadObjects()
static void GetObjectName_ThunkCb(const char* path, const DirEnt* UNUSED(ent), uintptr_t cbData)
static LibError GetObjectName_ThunkCb(const VfsPath& pathname, const FileInfo& UNUSED(fileInfo), uintptr_t cbData)
{
std::vector<CStr>* names = (std::vector<CStr>*)cbData;
CStr name (path);
CStr name(pathname.string());
names->push_back(name.AfterFirst("actors/"));
return INFO::CB_CONTINUE;
}
void CObjectManager::GetAllObjectNames(std::vector<CStr>& names)
{
vfs_dir_enum("art/actors/", VFS_DIR_RECURSIVE, "*.xml",
GetObjectName_ThunkCb, (uintptr_t)&names);
fs_ForEachFile(g_VFS, "art/actors/", GetObjectName_ThunkCb, (uintptr_t)&names, "*.xml", DIR_RECURSIVE);
}
void CObjectManager::GetPropObjectNames(std::vector<CStr>& names)
{
vfs_dir_enum("art/actors/props/", VFS_DIR_RECURSIVE, "*.xml",
GetObjectName_ThunkCb, (uintptr_t)&names);
fs_ForEachFile(g_VFS, "art/actors/props/", GetObjectName_ThunkCb, (uintptr_t)&names, "*.xml", DIR_RECURSIVE);
}

View File

@ -10,7 +10,7 @@
#define INCLUDED_PARTICLEENGINE
#include "ParticleEmitter.h"
#include "lib/res/graphics/tex.h"
#include "lib/tex/tex.h"
#include "lib/res/graphics/ogl_tex.h"
#include "graphics/Texture.h"

View File

@ -13,7 +13,6 @@
#include "graphics/ColladaManager.h"
#include "graphics/Model.h"
#include "graphics/SkeletonAnimDef.h"
#include "lib/res/res.h"
#include "ps/CLogger.h"
#include "ps/FileUnpacker.h"

View File

@ -9,7 +9,6 @@
#include "precompiled.h"
#include "lib/res/graphics/ogl_tex.h"
#include "lib/res/mem.h"
#include "renderer/Renderer.h"
#include "renderer/WaterManager.h"

View File

@ -19,7 +19,7 @@ class CXeromyces;
class CTerrainProperties;
class HEntity;
typedef boost::shared_ptr<CTerrainProperties> CTerrainPropertiesPtr;
typedef shared_ptr<CTerrainProperties> CTerrainPropertiesPtr;
struct STerrainPassability
{

View File

@ -7,13 +7,12 @@
#include "TextureEntry.h"
#include "TerrainProperties.h"
#include "lib/res/res.h"
#include "lib/res/graphics/ogl_tex.h"
#include "lib/ogl.h"
#include "lib/timer.h"
#include "ps/CLogger.h"
#include "ps/VFSUtil.h"
#include "ps/Filesystem.h"
#define LOG_CATEGORY "graphics"
@ -96,14 +95,12 @@ void CTextureManager::DeleteTexture(CTextureEntry* entry)
// typical maps. therefore, we'll leave it for now.
void CTextureManager::LoadTextures(CTerrainPropertiesPtr props, const char* dir)
{
VFSUtil::FileList files;
if(!VFSUtil::FindFiles(dir, 0, files))
// FindFiles has already logged the failure
VfsPaths pathnames;
if(fs_GetPathnames(g_VFS, dir, 0, pathnames) < 0)
return;
for(VFSUtil::FileList::iterator it = files.begin(); it != files.end(); ++it)
for(size_t i = 0; i < pathnames.size(); i++)
{
const char* texture_name = it->c_str();
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;
@ -122,7 +119,7 @@ void CTextureManager::LoadTextures(CTerrainPropertiesPtr props, const char* dir)
CTerrainPropertiesPtr myprops;
// Has XML file -> attempt to load properties
if (vfs_exists(xml_name))
if (FileExists(xml_name))
{
myprops = GetPropertiesFromFile(props, xml_name);
if (myprops)
@ -147,7 +144,7 @@ void CTextureManager::RecurseDirectory(CTerrainPropertiesPtr parentProps, const
char fn[PATH_MAX];
snprintf(fn, PATH_MAX, "%s%s", cur_dir_path, "terrains.xml");
fn[PATH_MAX-1] = '\0';
if (vfs_exists(fn))
if (FileExists(fn))
props = GetPropertiesFromFile(parentProps, fn);
// No terrains.xml, or read failures -> use parent props (i.e.
@ -159,11 +156,13 @@ void CTextureManager::RecurseDirectory(CTerrainPropertiesPtr parentProps, const
}
// Recurse once for each subdirectory
VFSUtil::FileList subdirs;
VFSUtil::FindFiles(cur_dir_path, "/", subdirs);
for (uint i=0;i<subdirs.size();i++)
DirectoryNames subdirectoryNames;
g_VFS->GetDirectoryEntries(cur_dir_path, 0, &subdirectoryNames);
for (uint i=0;i<subdirectoryNames.size();i++)
{
RecurseDirectory(props, subdirs[i].c_str());
char subdirectoryPath[PATH_MAX];
path_append(subdirectoryPath, cur_dir_path, subdirectoryNames[i].c_str(), PATH_APPEND_SLASH);
RecurseDirectory(props, subdirectoryPath);
}
LoadTextures(props, cur_dir_path);

View File

@ -17,7 +17,7 @@ class CXeromyces;
class CTextureEntry;
class CTerrainProperties;
typedef boost::shared_ptr<CTerrainProperties> CTerrainPropertiesPtr;
typedef shared_ptr<CTerrainProperties> CTerrainPropertiesPtr;
class CTerrainGroup
{

View File

@ -10,7 +10,6 @@
#include <float.h>
#include "lib/res/res.h"
#include "Model.h"
#include "UnitManager.h"
#include "Unit.h"

View File

@ -1,10 +1,9 @@
#include "lib/self_test.h"
#include "lib/res/file/vfs.h"
#include "lib/res/file/archive/vfs_optimizer.h"
#include "lib/res/file/path.h"
#include "lib/res/file/archive/trace.h"
#include "lib/res/h_mgr.h"
#include "lib/file/vfs/vfs.h"
#include "lib/file/io/io.h"
#include "lib/file/path.h"
#include "lib/file/directory_posix.h"
#include "graphics/ColladaManager.h"
#include "graphics/MeshManager.h"
@ -30,78 +29,59 @@ class TestMeshManager : public CxxTest::TestSuite
{
// Initialise VFS:
TS_ASSERT_OK(file_init());
TS_ASSERT_OK(file_set_root_dir(0, "../data"));
TS_ASSERT_OK(path_SetRoot(0, "../data"));
// Set up a mod directory to work in:
// Make sure the required directories doesn't exist when we start,
// in case the previous test aborted and left them full of junk
if (file_exists(MOD_PATH))
TS_ASSERT_OK(dir_delete(MOD_PATH));
directoryPosix.DeleteDirectory(MOD_PATH);
directoryPosix.DeleteDirectory(CACHE_PATH);
if (file_exists(CACHE_PATH))
TS_ASSERT_OK(dir_delete(CACHE_PATH));
TS_ASSERT_OK(directoryPosix.CreateDirectory(MOD_PATH));
TS_ASSERT_OK(directoryPosix.CreateDirectory(CACHE_PATH));
TS_ASSERT_OK(dir_create(MOD_PATH));
TS_ASSERT_OK(dir_create(CACHE_PATH));
vfs_init();
vfs = CreateVfs();
// Mount the mod on /
TS_ASSERT_OK(vfs_mount("", MOD_PATH, VFS_MOUNT_RECURSIVE|VFS_MOUNT_ARCHIVES|VFS_MOUNT_ARCHIVABLE));
TS_ASSERT_OK(vfs->Mount("", MOD_PATH, VFS_MOUNT_ARCHIVABLE));
// 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(vfs_mount("cache/", CACHE_PATH, VFS_MOUNT_RECURSIVE|VFS_MOUNT_ARCHIVES|VFS_MOUNT_ARCHIVABLE));
TS_ASSERT_OK(vfs_set_write_target(MOD_PATH));
TS_ASSERT_OK(vfs->Mount("cache/", CACHE_PATH, VFS_MOUNT_ARCHIVABLE));
}
void deinitVfs()
{
// (TODO: It'd be nice if this kind of code didn't have to be
// duplicated in each test suite that's using VFS things)
directoryPosix.DeleteDirectory(MOD_PATH);
directoryPosix.DeleteDirectory(CACHE_PATH);
vfs_shutdown();
TS_ASSERT_OK(file_shutdown());
TS_ASSERT_OK(dir_delete(MOD_PATH));
if (file_exists(CACHE_PATH))
TS_ASSERT_OK(dir_delete(CACHE_PATH));
path_reset_root_dir();
path_ResetRootDir();
}
void copyFile(const char* src, const char* dst)
{
// Copy a file into the mod directory, so we can work on it:
File f;
TS_ASSERT_OK(file_open(src, 0, &f));
FileIOBuf buf = FILE_BUF_ALLOC;
ssize_t read = file_io(&f, 0, f.size, &buf);
TS_ASSERT_EQUALS(read, f.size);
file_close(&f);
vfs_store(dst, buf, read, FILE_NO_AIO);
file_buf_free(buf);
shared_ptr<u8> data; size_t size = 0;
TS_ASSERT_OK(vfs->LoadFile(src, data, size));
TS_ASSERT_OK(vfs->CreateFile(dst, data, size));
}
void buildArchive()
{
// Create a junk trace file first, because vfs_opt_auto_build requires one
std::string trace = "000.000000: L \"-\" 0 0000\n";
vfs_store("trace.txt", (const u8*)trace.c_str(), trace.size(), FILE_NO_AIO);
// std::string trace = "000.000000: L \"-\" 0 0000\n";
// vfs_store("trace.txt", (const u8*)trace.c_str(), trace.size(), FILE_NO_AIO);
// then make the archive
TS_ASSERT_OK(vfs_opt_rebuild_main_archive(MOD_PATH"/trace.txt", MOD_PATH"/test%02d.zip"));
// TS_ASSERT_OK(vfs_opt_rebuild_main_archive(MOD_PATH"/trace.txt", MOD_PATH"/test%02d.zip"));
}
CColladaManager* colladaManager;
CMeshManager* meshManager;
PIVFS vfs;
FileSystem_Posix directoryPosix;
public:
@ -122,16 +102,10 @@ public:
void IRRELEVANT_test_archived()
{
copyFile(srcDAE, testDAE);
buildArchive();
// Have to specify FILE_WRITE_TO_TARGET in order to overwrite existent
// files when they might have been archived
vfs_store(testDAE, (const u8*)"Test", 4, FILE_NO_AIO | FILE_WRITE_TO_TARGET);
// We can't overwrite cache files because FILE_WRITE_TO_TARGET won't
// write into cache/ - it might be nice to fix that. For now we just
// use unique filenames.
//buildArchive();
shared_ptr<u8> buf = io_Allocate(100);
SAFE_STRCPY((char*)buf.get(), "Test");
vfs->CreateFile(testDAE, buf, 4);
}
void test_load_pmd_with_extension()
@ -164,11 +138,6 @@ public:
void test_load_dae()
{
// TODO: I get
// Assertion failed: "buf_in_cache == buf"
// Location: file_cache.cpp:1094 (file_buf_free)
// when the order of these is swapped...
copyFile(srcDAE, testDAE);
copyFile(srcSkeletonDefs, testSkeletonDefs);
@ -196,8 +165,9 @@ public:
TestLogger logger;
copyFile(srcDAE, testDAE);
const char text[] = "Not valid XML";
vfs_store(testSkeletonDefs, (const u8*)text, strlen(text), FILE_NO_AIO);
shared_ptr<u8> buf = io_Allocate(100);
SAFE_STRCPY((char*)buf.get(), "Not valid XML");
vfs->CreateFile(testSkeletonDefs, buf, 13);
CModelDefPtr modeldef = meshManager->GetMesh(testDAE);
TS_ASSERT(! modeldef);
@ -209,8 +179,9 @@ public:
TestLogger logger;
copyFile(srcSkeletonDefs, testSkeletonDefs);
const char text[] = "Not valid XML";
vfs_store(testDAE, (const u8*)text, strlen(text), FILE_NO_AIO);
shared_ptr<u8> buf = io_Allocate(100);
SAFE_STRCPY((char*)buf.get(), "Not valid XML");
vfs->CreateFile(testDAE, buf, 13);
CModelDefPtr modeldef = meshManager->GetMesh(testDAE);
TS_ASSERT(! modeldef);

View File

@ -31,6 +31,8 @@ CGUI
#include "ps/Pyrogenesis.h"
#include "lib/input.h"
#include "lib/bits.h"
#include "lib/timer.h"
#include "lib/sysdep/sysdep.h"
// TODO Gee: Whatever include CRect/CPos/CSize
#include "ps/Overlay.h"
#include "ps/Profile.h"
@ -38,8 +40,7 @@ CGUI
#include "scripting/ScriptingHost.h"
#include "ps/Hotkey.h"
#include "ps/Globals.h"
#include "lib/timer.h"
#include "lib/sysdep/sysdep.h"
#include "ps/Filesystem.h"
// namespaces used
using namespace std;

View File

@ -4,7 +4,7 @@
#include "lib/ogl.h"
#include "lib/res/h_mgr.h"
#include "lib/res/graphics/tex.h"
#include "lib/tex/tex.h"
#include "ps/CLogger.h"
#define LOG_CATEGORY "gui"

View File

@ -15,10 +15,9 @@ that of Atlas depending on commandline parameters.
#include "lib/input.h"
#include "lib/timer.h"
#include "lib/frequency_filter.h"
#include "lib/external_libraries/sdl.h"
#include "lib/res/file/vfs.h"
#include "lib/res/sound/snd_mgr.h"
#include "lib/res/file/archive/vfs_optimizer.h"
#include "ps/GameSetup/GameSetup.h"
#include "ps/GameSetup/Atlas.h"
@ -46,6 +45,8 @@ that of Atlas depending on commandline parameters.
extern bool g_TerrainModified;
extern bool g_GameRestarted;
PIFrequencyFilter g_frequencyFilter;
void kill_mainloop();
@ -99,6 +100,9 @@ static void PumpEvents()
// used to prevent reloading during that time (see call site).
static bool ProgressiveBuildArchive()
{
ONCE(g_GUI.SendEventToAll("archivebuildercomplete"));
return false;
#if 0
int ret = vfs_opt_auto_build("../logs/trace.txt", "mods/official/official%02d.zip", "mods/official/mini%02d.zip");
if(ret == INFO::ALL_COMPLETE)
{
@ -118,6 +122,7 @@ static bool ProgressiveBuildArchive()
}
return false;
#endif
}
@ -162,7 +167,8 @@ static void Frame()
ogl_WarnIfError();
// get elapsed time
calc_fps();
const double time = get_time();
g_frequencyFilter->Update(time);
// .. old method - "exact" but contains jumps
#if 0
static double last_time;
@ -173,7 +179,7 @@ static void Frame()
// .. new method - filtered and more smooth, but errors may accumulate
#else
const float TimeSinceLastFrame = spf;
const float TimeSinceLastFrame = 1.0 / g_frequencyFilter->SmoothedFrequency();
#endif
debug_assert(TimeSinceLastFrame >= 0.0f);
@ -215,7 +221,7 @@ static void Frame()
{
PROFILE_START("reload changed files");
MICROLOG(L"reload changed files");
vfs_reload_changed_files();
// vfs_reload_changed_files();
PROFILE_END( "reload changed files");
}
@ -359,6 +365,7 @@ static void RunGameOrAtlas(int argc, char* argv[])
// run the game
Init(args, 0);
g_frequencyFilter = CreateFrequencyFilter(timer_res(), 30.0);
MainControllerInit();
while(!quit)
Frame();

View File

@ -14,8 +14,11 @@
#define LOG_CAT_NET "net"
#include "lib/frequency_filter.h"
extern PIFrequencyFilter g_frequencyFilter;
CNetClient *g_NetClient=NULL;
extern int fps;
CNetClient::CServerSession::CServerSession(int sessionID, const CStrW& name):
m_SessionID(sessionID),
@ -445,7 +448,7 @@ int CNetClient::StartGame()
debug_printf("Client StartGame - sending end-of-batch ack\n");
// Send an end-of-batch message for turn 0 to signal that we're ready.
CEndCommandBatch *pMsg=new CEndCommandBatch();
pMsg->m_TurnLength=1000/fps;
pMsg->m_TurnLength=1000/g_frequencyFilter->SmoothedFrequency();
Push(pMsg);
return 0;
}
@ -471,7 +474,7 @@ void CNetClient::NewTurn()
//debug_printf("In NewTurn - sending ack\n");
CEndCommandBatch *pMsg=new CEndCommandBatch();
pMsg->m_TurnLength=1000/fps;
pMsg->m_TurnLength=1000/g_frequencyFilter->SmoothedFrequency();
Push(pMsg);
}

View File

@ -10,7 +10,7 @@
#include "precompiled.h"
#include "NetLog.h"
#include "ps/CConsole.h"
#include "lib/res/file/file.h"
#include "lib/file/path.h"
#include <stdio.h>
#include <stdarg.h>
@ -237,23 +237,15 @@ void CNetLogSink::OnClose( void )
//-----------------------------------------------------------------------------
CNetLogFileSink::CNetLogFileSink( void )
{
char filePath[ PATH_MAX ] = {0};
CStr time;
CStr path;
// Get string time
CStr time;
CNetLogger::GetStringTime( time );
// Make relative path
path = "../logs/net_log";
path += time;
path += ".txt";
// Make full path
file_make_full_native_path( path.c_str(), filePath );
m_FileName = filePath;
m_Append = true;
Path path("../logs/net_log");
path /= time+".txt";
m_FileName = path.external_file_string();
m_Append = true;
}
//-----------------------------------------------------------------------------

View File

@ -12,13 +12,13 @@
#include "CConsole.h"
#include "lib/ogl.h"
#include "lib/res/file/vfs.h"
#include "lib/res/graphics/unifont.h"
#include "lib/sysdep/clipboard.h"
#include "maths/MathUtil.h"
#include "network/Client.h"
#include "network/Server.h"
#include "ps/CLogger.h"
#include "ps/Filesystem.h"
#include "ps/Globals.h"
#include "ps/Hotkey.h"
#include "ps/Interact.h"
@ -47,20 +47,17 @@ CConsole::CConsole()
InsertMessage(L"[ 0 A.D. Console v0.12 ] type \"\\info\" for help");
InsertMessage(L"");
if (vfs_exists("gui/text/help.txt"))
if (FileExists("gui/text/help.txt"))
{
FileIOBuf buf;
size_t size;
if ( vfs_load("gui/text/help.txt", buf, size) < 0 )
shared_ptr<u8> buf; size_t size;
if ( g_VFS->LoadFile("gui/text/help.txt", buf, size) < 0 )
{
LOG( ERROR,"Console", "Help file not found for console" );
file_buf_free(buf);
return;
}
// TODO: read in text mode, or at least get rid of the \r\n somehow
// TODO: maybe the help file should be UTF-8 - we assume it's iso-8859-1 here
m_helpText = CStrW(CStr( (const char*)buf ));
file_buf_free(buf);
m_helpText = CStrW(CStr( (const char*)buf.get() ));
}
else
{
@ -713,16 +710,15 @@ void CConsole::LoadHistory()
// note: we don't care if this file doesn't exist or can't be read;
// just don't load anything in that case.
// do this before vfs_load to avoid an error message if file not found.
if (!vfs_exists(m_sHistoryFile))
// do this before LoadFile to avoid an error message if file not found.
if (!FileExists(m_sHistoryFile))
return;
FileIOBuf buf; size_t buflen;
if (vfs_load(m_sHistoryFile, buf, buflen) < 0)
shared_ptr<u8> buf; size_t buflen;
if (g_VFS->LoadFile(m_sHistoryFile, buf, buflen) < 0)
return;
CStr bytes ((char*)buf, buflen);
(void)file_buf_free(buf);
CStr bytes ((char*)buf.get(), buflen);
CStrW str (bytes.FromUTF8());
size_t pos = 0;
@ -742,16 +738,19 @@ void CConsole::LoadHistory()
void CConsole::SaveHistory()
{
CStr buffer;
std::deque<std::wstring>::iterator it;
int line_count = 0;
for (it = m_deqBufHistory.begin(); it != m_deqBufHistory.end(); ++it)
WriteBuffer buffer;
const int linesToSkip = (int)m_deqBufHistory.size() - m_MaxHistoryLines;
std::deque<std::wstring>::const_reverse_iterator it = m_deqBufHistory.rbegin();
if(linesToSkip > 0)
std::advance(it, linesToSkip);
for (; it != m_deqBufHistory.rend(); ++it)
{
if (line_count++ >= m_MaxHistoryLines)
break;
buffer = CStrW(*it).ToUTF8() + "\n" + buffer;
CStr8 line = CStrW(*it).ToUTF8();
buffer.Append(line.data(), line.length());
static const char newline = '\n';
buffer.Append(&newline, 1);
}
vfs_store(m_sHistoryFile, (const u8*)buffer.c_str(), buffer.length(), FILE_NO_AIO);
g_VFS->CreateFile(m_sHistoryFile, buffer.Data(), buffer.Size());
}
void CConsole::SendChatMessage(const wchar_t *szMessage)

View File

@ -4,7 +4,7 @@
#include "CConsole.h"
#include "ConfigDB.h"
#include "lib/path_util.h"
#include "lib/res/file/file.h"
#include "lib/file/path.h"
#include "lib/sysdep/sysdep.h"
#include <time.h>
@ -39,16 +39,11 @@ const char* html_footer = "";
CLogger::CLogger()
{
char N_path[PATH_MAX];
(void)file_make_full_native_path("../logs", N_path);
PathPackage pp;
(void)path_package_set_dir(&pp, N_path);
Path mainlogPath("../logs/mainlog.html");
m_MainLog = new std::ofstream(mainlogPath.external_file_string().c_str(), std::ofstream::out | std::ofstream::trunc);
(void)path_package_append_file(&pp, "mainlog.html");
m_MainLog = new std::ofstream(pp.path, std::ofstream::out | std::ofstream::trunc);
(void)path_package_append_file(&pp, "interestinglog.html");
m_InterestingLog = new std::ofstream(pp.path, std::ofstream::out | std::ofstream::trunc);
Path interestinglogPath("../logs/interestinglog.html");
m_InterestingLog = new std::ofstream(interestinglogPath.external_file_string().c_str(), std::ofstream::out | std::ofstream::trunc);
m_OwnsStreams = true;

View File

@ -4,8 +4,7 @@
#include "Parser.h"
#include "ConfigDB.h"
#include "CLogger.h"
#include "lib/res/file/vfs.h"
#include "lib/res/mem.h"
#include "Filesystem.h"
#include "scripting/ScriptingHost.h"
#define LOG_CATEGORY "config"
@ -255,41 +254,20 @@ bool CConfigDB::Reload(EConfigNamespace ns)
parser.InputTaskType("Assignment", "_$ident_=<_[-$arg(_minus)]_$value_,>_[-$arg(_minus)]_$value[[;]$rest]");
parser.InputTaskType("CommentOrBlank", "_[;[$rest]]");
FileIOBuf buffer;
size_t buflen;
File f;
LibError ret;
if (m_UseVFS[ns])
// Open file with VFS
shared_ptr<u8> buffer; size_t buflen;
{
// Open file with VFS
ret = vfs_load(m_ConfigFile[ns], buffer, buflen);
LibError ret = g_VFS->LoadFile(m_ConfigFile[ns], buffer, buflen);
if(ret != INFO::OK)
{
LOG(ERROR, LOG_CATEGORY, "vfs_load for \"%s\" failed: return was %lld", m_ConfigFile[ns].c_str(), ret);
return false;
}
}
else
{
if (file_open(m_ConfigFile[ns], 0, &f)!=INFO::OK)
{
LOG(ERROR, LOG_CATEGORY, "file_open for \"%s\" failed", m_ConfigFile[ns].c_str());
return false;
}
buffer = FILE_BUF_ALLOC;
buflen = f.size;
ssize_t ret = file_io(&f, 0, buflen, &buffer);
(void)file_close(&f);
if(ret != (ssize_t)buflen)
{
LOG(ERROR, LOG_CATEGORY, "file_io for \"%s\" failed", m_ConfigFile[ns].c_str());
return false;
}
}
TConfigMap newMap;
char *filebuf=(char *)buffer;
char *filebuf=(char *)buffer.get();
char *filebufend=filebuf+buflen;
// Read file line by line
@ -334,50 +312,36 @@ bool CConfigDB::Reload(EConfigNamespace ns)
m_Map[ns].swap(newMap);
(void)file_buf_free(buffer);
return true;
}
bool CConfigDB::WriteFile(EConfigNamespace ns, bool useVFS, const CStr& path)
{
debug_assert(useVFS);
if (ns < 0 || ns >= CFG_LAST)
{
debug_warn("CConfigDB: Invalid ns value");
return false;
}
char realpath[PATH_MAX];
char nativepath[PATH_MAX];
const char *filepath=path.c_str();
int err;
FILE *fp;
if (useVFS)
shared_ptr<u8> buf = io_Allocate(1*MiB);
char* pos = (char*)buf.get();
TConfigMap &map=m_Map[ns];
for(TConfigMap::const_iterator it = it=map.begin(); it != map.end(); ++it)
{
if ((err=vfs_realpath(filepath, realpath))!=0)
{
LOG(ERROR, LOG_CATEGORY, "CConfigDB::WriteFile(): vfs_realpath for VFS path \"%s\" failed (error: %d)", filepath, err);
return false;
}
filepath=realpath;
pos += sprintf(pos, "%s = \"%s\"\n", it->first.c_str(), it->second[0].m_String.c_str());
}
file_make_full_native_path(filepath, nativepath);
if ((fp = fopen(nativepath, "w")) == NULL)
const size_t len = pos - (char*)buf.get();
LibError ret = g_VFS->CreateFile(filepath, buf, len);
if(ret < 0)
{
LOG(ERROR, LOG_CATEGORY, "CConfigDB::WriteFile(): fopen for path \"%s\" failed (error: %d)", filepath, errno);
LOG(ERROR, LOG_CATEGORY, "CConfigDB::WriteFile(): CreateFile \"%s\" failed (error: %d)", filepath, (int)ret);
return false;
}
//uint offset=0; // unused
TConfigMap &map=m_Map[ns];
TConfigMap::const_iterator it=map.begin();
while (it != map.end())
{
fprintf(fp, "%s = \"%s\"\n", it->first.c_str(), it->second[0].m_String.c_str());
++it;
}
fclose(fp);
return true;
}

View File

@ -9,54 +9,52 @@
#include "precompiled.h"
#include "FilePacker.h"
#include "ps/Filesystem.h"
#include "lib/byte_order.h"
#include <string.h>
#include "lib/res/file/vfs.h"
////////////////////////////////////////////////////////////////////////////////////////
// CFilePacker constructor
// rationale for passing in version + signature here: see header
CFilePacker::CFilePacker(u32 version, const char magicstr[4])
CFilePacker::CFilePacker(u32 version, const char magicstr[4])
{
// put header in our data array.
// (size will be updated on every Pack*() call)
m_Data.resize(12);
u8* header = (u8*)&m_Data[0];
strncpy((char*)(header+0), magicstr, 4); // not 0-terminated => no _s
*(u32*)(header+4) = version;
*(u32*)(header+8) = 0; // datasize
// FIXME m_Version: Byte order? -- Simon
char header[12];
strncpy(header+0, magicstr, 4); // not 0-terminated => no _s
write_le32(header+4, version);
write_le32(header+8, 0); // datasize
m_writeBuffer.Append(header, 12);
}
////////////////////////////////////////////////////////////////////////////////////////
// Write: write out to file all packed data added so far
void CFilePacker::Write(const char* filename)
{
const u32 size_le = to_le32(u32_from_larger(m_writeBuffer.Size()));
m_writeBuffer.Overwrite(&size_le, sizeof(size_le), 8);
// write out all data (including header)
if(vfs_store(filename, &m_Data[0], m_Data.size(), FILE_NO_AIO|FILE_WRITE_TO_TARGET) < 0)
if(g_VFS->CreateFile(filename, m_writeBuffer.Data(), m_writeBuffer.Size()) < 0)
throw PSERROR_File_WriteFailed();
}
////////////////////////////////////////////////////////////////////////////////////////
// PackRaw: pack given number of bytes onto the end of the data stream
void CFilePacker::PackRaw(const void* rawdata,u32 rawdatalen)
void CFilePacker::PackRaw(const void* rawData, size_t rawSize)
{
u32 start=(u32)m_Data.size();
m_Data.resize(m_Data.size()+rawdatalen);
cpu_memcpy(&m_Data[start],rawdata,rawdatalen);
*(u32*)&m_Data[8] += rawdatalen; // FIXME byte order?
m_writeBuffer.Append(rawData, rawSize);
}
////////////////////////////////////////////////////////////////////////////////////////
// PackString: pack a string onto the end of the data stream
void CFilePacker::PackString(const CStr& str)
{
u32 len=(u32)str.length();
PackRaw(&len,sizeof(len));
PackRaw((const char*) str,len);
const size_t length = str.length();
const u32 length_le = to_le32(u32_from_larger(length));
PackRaw(&length_le, sizeof(length_le));
PackRaw((const char*)str, length);
}

View File

@ -13,6 +13,7 @@
#include "CStr.h"
#include "ps/Errors.h"
#include "ps/Filesystem.h" // WriteBuffer
#ifndef ERROR_GROUP_FILE_DEFINED
#define ERROR_GROUP_FILE_DEFINED
@ -39,14 +40,14 @@ public:
void Write(const char* filename);
// PackRaw: pack given number of bytes onto the end of the data stream
void PackRaw(const void* rawdata, u32 rawdatalen);
void PackRaw(const void* rawdata, size_t rawdatalen);
// PackString: pack a string onto the end of the data stream
void PackString(const CStr& str);
private:
// the output data stream built during pack operations.
// contains the header, so we can write this out in one go.
std::vector<u8> m_Data;
WriteBuffer m_writeBuffer;
};
#endif

View File

@ -8,16 +8,15 @@
#include "precompiled.h"
#include "FileUnpacker.h"
#include "lib/path_util.h"
#include "lib/res/res.h"
#include "ps/FileUnpacker.h"
#include "ps/CStr.h"
#include "ps/Filesystem.h"
#include "lib/byte_order.h"
////////////////////////////////////////////////////////////////////////////////////////
// CFileUnpacker constructor
CFileUnpacker::CFileUnpacker()
{
m_Buf = 0;
m_Size = 0;
m_UnpackPos = 0;
m_Version = 0;
@ -25,13 +24,12 @@ CFileUnpacker::CFileUnpacker()
CFileUnpacker::~CFileUnpacker()
{
file_buf_free(m_Buf);
}
////////////////////////////////////////////////////////////////////////////////////////
// Read: open and read in given file, check magic bits against those given; throw
// variety of exceptions for missing files etc
void CFileUnpacker::Read(const char* filename,const char magicstr[4])
void CFileUnpacker::Read(const char* filename, const char magicstr[4])
{
// avoid vfs_load complaining about missing data files (which happens
// too often). better to check here than squelch internal VFS error
@ -39,44 +37,34 @@ void CFileUnpacker::Read(const char* filename,const char magicstr[4])
// UPDATE: We don't disable this in release mode, because vfs_load now
// complains about missing files when running in release
//#ifndef NDEBUG
if(!vfs_exists(filename))
if(!FileExists(filename))
throw PSERROR_File_OpenFailed();
//#endif
// somewhat of a hack: if loading a map (.PMP), tell the file manager
// that the buffer will be kept in memory longer (avoids warning).
uint flags = 0;
const char* ext = path_extension(filename);
if(!strcasecmp(ext, "pmp"))
flags |= FILE_LONG_LIVED;
// load the whole thing into memory
if(vfs_load(filename, m_Buf, m_Size, flags) < 0)
if(g_VFS->LoadFile(filename, m_Buf, m_Size) < 0)
throw PSERROR_File_OpenFailed();
// make sure we read enough for the header
if(m_Size < 12)
{
(void)file_buf_free(m_Buf);
m_Buf = 0;
m_Buf.reset();
m_Size = 0;
throw PSERROR_File_ReadFailed();
}
// extract data from header
u8* header = (u8*)m_Buf;
u8* header = (u8*)m_Buf.get();
char* magic = (char*)(header+0);
// FIXME m_Version and datasize: Byte order? -- Simon
m_Version = *(u32*)(header+4);
u32 datasize = *(u32*)(header+8);
m_Version = read_le32(header+4);
u32 datasize = read_le32(header+8);
// check we've got the right kind of file
// .. and that we read exactly headersize+datasize
if(strncmp(magic, magicstr, 4) != 0 ||
m_Size != 12+datasize)
if(strncmp(magic, magicstr, 4) != 0 || m_Size != 12+datasize)
{
(void)file_buf_free(m_Buf);
m_Buf = 0;
m_Buf.reset();
m_Size = 0;
throw PSERROR_File_InvalidType();
}
@ -88,19 +76,15 @@ void CFileUnpacker::Read(const char* filename,const char magicstr[4])
// UnpackRaw: unpack given number of bytes from the input stream into the given array
// - throws CFileEOFError if the end of the data stream is reached before the given
// number of bytes have been read
void CFileUnpacker::UnpackRaw(void* rawdata,u32 rawdatalen)
void CFileUnpacker::UnpackRaw(void* rawdata, size_t rawdatalen)
{
// got enough data to unpack?
if (m_UnpackPos+rawdatalen<=m_Size)
{
// yes .. copy over
void* src = (char*)m_Buf + m_UnpackPos;
cpu_memcpy(rawdata, src, rawdatalen);
m_UnpackPos += rawdatalen;
}
else
// nope - throw exception
// fail if reading past end of stream
if (m_UnpackPos+rawdatalen > m_Size)
throw PSERROR_File_UnexpectedEOF();
void* src = m_Buf.get() + m_UnpackPos;
cpu_memcpy(rawdata, src, rawdatalen);
m_UnpackPos += rawdatalen;
}
////////////////////////////////////////////////////////////////////////////////////////
@ -110,16 +94,14 @@ void CFileUnpacker::UnpackRaw(void* rawdata,u32 rawdatalen)
void CFileUnpacker::UnpackString(CStr& result)
{
// get string length
u32 length;
UnpackRaw(&length,sizeof(length)); // FIXME Byte order? -- Simon
if (m_UnpackPos + length <= m_Size)
{
result=std::string((char *)m_Buf+m_UnpackPos, length);
m_UnpackPos += length;
}
else
u32 length_le;
UnpackRaw(&length_le, sizeof(length_le));
const size_t length = to_le32(length_le);
// fail if reading past end of stream
if (m_UnpackPos + length > m_Size)
throw PSERROR_File_UnexpectedEOF();
result = CStr((char*)m_Buf.get()+m_UnpackPos, length);
m_UnpackPos += length;
}

View File

@ -10,7 +10,6 @@
#define INCLUDED_FILEUNPACKER
#include <vector>
#include "lib/res/file/file_io.h"
class CStr8;
@ -46,16 +45,16 @@ public:
// UnpackRaw: unpack given number of bytes from the input stream into the given array
// - throws PSERROR_File_UnexpectedEOF if the end of the data stream is reached before
// the given number of bytes have been read
void UnpackRaw(void* rawdata, u32 rawdatalen);
void UnpackRaw(void* rawdata, size_t rawdatalen);
// UnpackString: unpack a string from the raw data stream
void UnpackString(CStr8& result);
private:
// the data read from file and used during unpack operations
FileIOBuf m_Buf;
shared_ptr<u8> m_Buf;
size_t m_Size;
// current unpack position in stream
u32 m_UnpackPos;
size_t m_UnpackPos;
// version of the file currently being read
u32 m_Version;
};

View File

@ -1,59 +1,65 @@
#include "precompiled.h"
#include "CVFSFile.h"
#include "lib/res/mem.h"
#include "lib/res/file/vfs.h"
#include "ps/CLogger.h"
#define LOG_CATEGORY "file"
// (for only-call-once check)
CVFSFile::CVFSFile() : m_Buffer(0) {}
CVFSFile::~CVFSFile()
{
(void)file_buf_free(m_Buffer);
}
PSRETURN CVFSFile::Load(const char* filename, uint flags /* = 0 */)
{
if (m_Buffer)
{
// Load should never be called more than once, so complain
debug_warn("Mustn't open files twice");
return PSRETURN_CVFSFile_AlreadyLoaded;
}
LibError ret = vfs_load(filename, m_Buffer, m_BufferSize, flags);
if (ret != INFO::OK)
{
LOG(ERROR, LOG_CATEGORY, "CVFSFile: file %s couldn't be opened (vfs_load: %d)", filename, ret);
return PSRETURN_CVFSFile_LoadFailed;
}
return PSRETURN_OK;
}
const u8* CVFSFile::GetBuffer() const
{
// Die in a very obvious way, to avoid subtle problems caused by
// accidentally forgetting to check that the open succeeded
if (!m_Buffer)
{
debug_warn("GetBuffer() called with no file loaded");
throw PSERROR_CVFSFile_InvalidBufferAccess();
}
return m_Buffer;
}
size_t CVFSFile::GetBufferSize() const
{
return m_BufferSize;
}
CStr CVFSFile::GetAsString() const
{
return std::string((char*)GetBuffer(), GetBufferSize());
}
#include "precompiled.h"
#include "Filesystem.h"
#include "ps/CLogger.h"
#define LOG_CATEGORY "file"
PIVFS g_VFS;
bool FileExists(const char* pathname)
{
return g_VFS->GetFileInfo(pathname, 0) == INFO::OK;
}
CVFSFile::CVFSFile()
{
}
CVFSFile::~CVFSFile()
{
}
PSRETURN CVFSFile::Load(const char* filename)
{
// Load should never be called more than once, so complain
if (m_Buffer)
{
debug_assert(0);
return PSRETURN_CVFSFile_AlreadyLoaded;
}
LibError ret = g_VFS->LoadFile(filename, m_Buffer, m_BufferSize);
if (ret != INFO::OK)
{
LOG(ERROR, LOG_CATEGORY, "CVFSFile: file %s couldn't be opened (vfs_load: %d)", filename, ret);
return PSRETURN_CVFSFile_LoadFailed;
}
return PSRETURN_OK;
}
const u8* CVFSFile::GetBuffer() const
{
// Die in a very obvious way, to avoid subtle problems caused by
// accidentally forgetting to check that the open succeeded
if (!m_Buffer)
{
debug_warn("GetBuffer() called with no file loaded");
throw PSERROR_CVFSFile_InvalidBufferAccess();
}
return m_Buffer.get();
}
size_t CVFSFile::GetBufferSize() const
{
return m_BufferSize;
}
CStr CVFSFile::GetAsString() const
{
return std::string((char*)GetBuffer(), GetBufferSize());
}

View File

@ -1,33 +1,44 @@
// OO wrapper around VFS file Handles, to simplify common usages
#include "lib/res/handle.h"
#include "lib/res/file/file.h"
#include "ps/CStr.h"
#include "ps/Errors.h"
ERROR_GROUP(CVFSFile);
ERROR_TYPE(CVFSFile, LoadFailed);
ERROR_TYPE(CVFSFile, AlreadyLoaded);
ERROR_TYPE(CVFSFile, InvalidBufferAccess);
// Reads a file, then gives read-only access to the contents
class CVFSFile
{
public:
CVFSFile();
~CVFSFile();
// Returns either PSRETURN_OK or PSRETURN_CVFSFile_LoadFailed.
// Dies if a file has already been successfully loaded.
PSRETURN Load(const char* filename, uint flags = 0);
// These die if called when no file has been successfully loaded.
const u8* GetBuffer() const;
size_t GetBufferSize() const;
CStr GetAsString() const;
private:
FileIOBuf m_Buffer;
size_t m_BufferSize;
};
#ifndef INCLUDED_FILESYSTEM
#define INCLUDED_FILESYSTEM
#include "lib/path_util.h"
#include "lib/file/path.h"
#include "lib/file/vfs/vfs.h"
#include "lib/file/file_system_util.h"
#include "lib/file/io/io.h"
#include "lib/file/io/write_buffer.h"
#include "ps/CStr.h"
#include "ps/Errors.h"
extern PIVFS g_VFS;
extern bool FileExists(const char* pathname);
ERROR_GROUP(CVFSFile);
ERROR_TYPE(CVFSFile, LoadFailed);
ERROR_TYPE(CVFSFile, AlreadyLoaded);
ERROR_TYPE(CVFSFile, InvalidBufferAccess);
// Reads a file, then gives read-only access to the contents
class CVFSFile
{
public:
CVFSFile();
~CVFSFile();
// Returns either PSRETURN_OK or PSRETURN_CVFSFile_LoadFailed.
// Dies if a file has already been successfully loaded.
PSRETURN Load(const char* filename);
// These die if called when no file has been successfully loaded.
const u8* GetBuffer() const;
size_t GetBufferSize() const;
CStr GetAsString() const;
private:
shared_ptr<u8> m_Buffer;
size_t m_BufferSize;
};
#endif // #ifndef INCLUDED_FILESYSTEM

View File

@ -6,9 +6,6 @@
#include "ps/GameSetup/CmdLineArgs.h"
#include "lib/timer.h"
#include "lib/res/sound/snd_mgr.h"
#include "lib/res/file/archive/trace.h"
#include "lib/res/file/vfs.h"
#include "lib/res/file/archive/vfs_optimizer.h"
#include "Config.h"
#define LOG_CATEGORY "config"
@ -115,7 +112,7 @@ static void ProcessCommandLineArgs(const CmdLineArgs& args)
// note: VFS init is sure to have been completed by now
// (since CONFIG_Init reads from file); therefore,
// it is safe to call this from here directly.
vfs_opt_rebuild_main_archive("mods/official/official1.zip", "../logs/trace.txt");
// vfs_opt_rebuild_main_archive("mods/official/official1.zip", "../logs/trace.txt");
}
// Handle "-conf=key:value" (potentially multiple times)
@ -144,8 +141,8 @@ static void ProcessCommandLineArgs(const CmdLineArgs& args)
g_Gamma = 1.0f;
}
if (args.Has("listfiles"))
trace_enable(true);
// if (args.Has("listfiles"))
// trace_enable(true);
if (args.Has("profile"))
g_ConfigDB.CreateValue(CFG_COMMAND, "profile")->m_String = args.Get("profile");

View File

@ -8,15 +8,15 @@
#include "lib/app_hooks.h"
#include "lib/sysdep/cpu.h"
#include "lib/sysdep/gfx.h"
#include "lib/res/res.h"
#include "lib/res/file/archive/trace.h"
#include "lib/res/h_mgr.h"
#include "lib/res/sound/snd_mgr.h"
#include "lib/res/graphics/tex.h"
#include "lib/tex/tex.h"
#include "lib/res/graphics/cursor.h"
#include "ps/CConsole.h"
#include "ps/CLogger.h"
#include "ps/ConfigDB.h"
#include "ps/Filesystem.h"
#include "ps/Font.h"
#include "ps/Game.h"
#include "ps/Globals.h"
@ -550,8 +550,6 @@ static void InitVfs(const CmdLineArgs& args)
{
TIMER("InitVfs");
(void)file_init();
// set root directory to "$game_dir/data". all relative file paths
// passed to file.cpp will be based from this dir.
// (we don't set current directory because other libraries may
@ -562,12 +560,13 @@ static void InitVfs(const CmdLineArgs& args)
// rationale for data/ being root: untrusted scripts must not be
// allowed to overwrite critical game (or worse, OS) files.
// the VFS prevents any accesses to files above this directory.
(void)file_set_root_dir(args.GetArg0(), "../data");
path_SetRoot(args.GetArg0(), "../data");
vfs_init();
g_VFS = CreateVfs();
vfs_mount("screenshots/", "screenshots");
vfs_mount("profiles/", "profiles", VFS_MOUNT_RECURSIVE);
g_VFS->Mount("screenshots/", "screenshots");
g_VFS->Mount("config/", "config");
g_VFS->Mount("profiles/", "profiles");
// rationale:
// - this is in a separate real directory so that it can later be moved
@ -577,7 +576,7 @@ static void InitVfs(const CmdLineArgs& args)
// so putting them in an archive boosts performance.
//
// [hot: 16ms]
vfs_mount("cache/", "cache", VFS_MOUNT_RECURSIVE|VFS_MOUNT_ARCHIVES|VFS_MOUNT_ARCHIVABLE);
g_VFS->Mount("cache/", "cache", VFS_MOUNT_ARCHIVABLE);
std::vector<CStr> mods = args.GetMultiple("mod");
if (mods.empty())
@ -587,7 +586,7 @@ static void InitVfs(const CmdLineArgs& args)
{
CStr path = "mods/" + mods[i];
uint priority = (uint)i;
uint flags = VFS_MOUNT_RECURSIVE|VFS_MOUNT_ARCHIVES|VFS_MOUNT_WATCH;
uint flags = VFS_MOUNT_WATCH;
// TODO: currently only archive 'official' - probably ought to archive
// all mods instead?
@ -595,14 +594,10 @@ static void InitVfs(const CmdLineArgs& args)
flags |= VFS_MOUNT_ARCHIVABLE;
// [hot: 150ms for mods/official]
(void)vfs_mount("", path, flags, priority);
g_VFS->Mount("", path, flags, priority);
}
// set the top (last) mod to be the write target
CStr top_mod_path = "mods/" + mods.back(); // (mods is never empty)
vfs_set_write_target(top_mod_path);
// don't try vfs_display yet: SDL_Init hasn't yet redirected stdout
// don't try g_VFS->Display yet: SDL_Init hasn't yet redirected stdout
}
@ -851,21 +846,12 @@ void Shutdown(uint flags)
TIMER_BEGIN("resource modules");
snd_shutdown();
(void)trace_write_to_file("../logs/trace.txt");
vfs_shutdown();
// must come before h_mgr_shutdown - it frees IO buffers,
// which we don't want showing up as leaks.
file_shutdown();
g_VFS.reset();
// this forcibly frees all open handles (thus preventing real leaks),
// and makes further access to h_mgr impossible.
h_mgr_shutdown();
// must come after h_mgr_shutdown - it causes memory
// to be freed, which requires this module to still be active.
mem_shutdown();
TIMER_END("resource modules");
TIMER_BEGIN("shutdown misc");

View File

@ -37,7 +37,7 @@ enum InitFlags
// skip initializing the simulation.
// used by actor viewer because it doesn't need the simulation code.
INIT_NO_SIM = 4,
INIT_NO_SIM = 4
};
class CmdLineArgs;

View File

@ -20,7 +20,7 @@
#include "ps/Globals.h"
#include "ps/Hotkey.h"
#include "ps/Player.h"
#include "ps/VFSUtil.h"
#include "ps/Filesystem.h"
#include "ps/World.h"
#include "renderer/Renderer.h"
#include "scripting/GameEvents.h"
@ -954,27 +954,27 @@ void CMouseoverEntities::RenderRallyPoints()
glDisable( GL_BLEND );
}
// Helper function for CSelectedEntities::LoadUnitUiTextures
static void LoadUnitUIThunk( const char* path, const DirEnt* UNUSED(ent), uintptr_t cbData )
static LibError LoadUnitUIThunk( const VfsPath& pathname, const FileInfo& UNUSED(fileInfo), uintptr_t cbData )
{
std::map<CStr, Handle>* textures = (std::map<CStr, Handle>*)cbData;
CStr name(path);
CStr name(pathname.string());
if ( !tex_is_known_extension(path) )
return;
Handle tmp = ogl_tex_load(path);
if ( !tex_is_known_extension(name.c_str()) )
return INFO::CB_CONTINUE;
Handle tmp = ogl_tex_load(name.c_str());
if (tmp <= 0)
{
LOG(ERROR, LOG_CATEGORY, "Rank Textures", "loadRankTextures failed on \"%s\"", path);
return;
LOG(ERROR, LOG_CATEGORY, "Rank Textures", "loadRankTextures failed on \"%s\"", name.c_str());
return INFO::CB_CONTINUE;
}
name.Remove("art/textures/ui/session/icons/"); //Names are relative to this directory
(*textures)[name] = tmp;
ogl_tex_upload(tmp);
return INFO::CB_CONTINUE;
}
int CSelectedEntities::LoadUnitUiTextures()
{
THROW_ERR( vfs_dir_enum( "art/textures/ui/session/icons/", VFS_DIR_RECURSIVE,
NULL, LoadUnitUIThunk, (uintptr_t)&m_unitUITextures ) );
THROW_ERR( fs_ForEachFile(g_VFS, "art/textures/ui/session/icons/", LoadUnitUIThunk, (uintptr_t)&m_unitUITextures, 0, DIR_RECURSIVE));
return 0;
}
void CSelectedEntities::DestroyUnitUiTextures()

View File

@ -34,7 +34,7 @@ static enum
IDLE,
REGISTERING,
FIRST_LOAD,
LOADING,
LOADING
}
state = IDLE;
@ -193,8 +193,7 @@ static bool HaveTimeForNextTask(double time_left, double time_budget, int estima
// persistent, we can't just store a pointer. returning a pointer to
// our copy of the description doesn't work either, since it's freed when
// the request is de-queued. that leaves writing into caller's buffer.
LibError LDR_ProgressiveLoad(double time_budget, wchar_t* description,
size_t max_chars, int* progress_percent)
LibError LDR_ProgressiveLoad(double time_budget, wchar_t* description, size_t max_chars, int* progress_percent)
{
LibError ret; // single exit; this is returned
double progress = 0.0; // used to set progress_percent

View File

@ -141,8 +141,7 @@ extern LibError LDR_Cancel();
// persistent, we can't just store a pointer. returning a pointer to
// our copy of the description doesn't work either, since it's freed when
// the request is de-queued. that leaves writing into caller's buffer.
extern LibError LDR_ProgressiveLoad(double time_budget, wchar_t* next_description,
size_t max_chars, int* progress_percent);
extern LibError LDR_ProgressiveLoad(double time_budget, wchar_t* next_description, size_t max_chars, int* progress_percent);
// immediately process all queued load requests.
// returns 0 on success or a negative error code.

View File

@ -16,8 +16,7 @@
#include "Profile.h"
#include "renderer/Renderer.h"
#include "lib/res/graphics/unifont.h"
#include "lib/path_util.h"
#include "lib/res/file/file.h"
#include "Filesystem.h"
#include "Hotkey.h"
#include "ps/CLogger.h"
#include "lib/external_libraries/sdl.h"
@ -414,16 +413,10 @@ void CProfileViewer::SaveToFile()
// run.
if (! m->outputStream.is_open())
{
// Work out the filename
char N_path[PATH_MAX];
(void)file_make_full_native_path("../logs", N_path);
PathPackage pp;
(void)path_package_set_dir(&pp, N_path);
(void)path_package_append_file(&pp, "profile.txt");
// Open the file. (It will be closed when the CProfileViewer
// destructor is called.)
m->outputStream.open(pp.path, std::ofstream::out | std::ofstream::trunc);
Path path("../logs/profile.txt");
m->outputStream.open(path.external_file_string().c_str(), std::ofstream::out | std::ofstream::trunc);
if (m->outputStream.fail())
{

View File

@ -3,9 +3,9 @@
#include "Pyrogenesis.h"
#include "ps/i18n.h"
#include "lib/path_util.h"
#include "lib/res/file/file.h"
#include "lib/sysdep/sysdep.h"
#include "lib/file/path.h"
#include "lib/path_util.h"
DEFINE_ERROR(PS_OK, "OK");
DEFINE_ERROR(PS_FAIL, "Fail");
@ -46,7 +46,7 @@ void psTranslateFree(const wchar_t* text)
// convert contents of file <in_filename> from char to wchar_t and
// append to <out> file.
static void cat_atow(FILE* out, const char* in_filename)
static void AppendAsciiFile(FILE* out, const char* in_filename)
{
FILE* in = fopen(in_filename, "rb");
if(!in)
@ -70,19 +70,17 @@ static void cat_atow(FILE* out, const char* in_filename)
fclose(in);
}
// for user convenience, bundle all logs into this file:
void psBundleLogs(FILE* f)
{
// for user convenience, bundle all logs into this file:
char N_path[PATH_MAX];
fwprintf(f, L"System info:\n\n");
(void)file_make_full_native_path("../logs/system_info.txt", N_path);
cat_atow(f, N_path);
Path path1("../logs/system_info.txt");
AppendAsciiFile(f, path1.external_file_string().c_str());
fwprintf(f, L"\n\n====================================\n\n");
fwprintf(f, L"Main log:\n\n");
(void)file_make_full_native_path("../logs/mainlog.html", N_path);
cat_atow(f, N_path);
Path path2("../logs/mainlog.html");
AppendAsciiFile(f, path2.external_file_string().c_str());
fwprintf(f, L"\n\n====================================\n\n");
}

View File

@ -2,19 +2,17 @@
#include "lib/posix/posix_utsname.h"
#include "lib/posix/posix_sock.h"
#include "lib/res/file/path.h"
#include "lib/res/file/vfs.h"
#include "lib/ogl.h"
#include "lib/timer.h"
#include "lib/sysdep/gfx.h"
#include "lib/sysdep/snd.h"
#include "lib/sysdep/cpu.h"
#include "lib/res/res.h"
#include "lib/res/graphics/tex.h"
#include "lib/tex/tex.h"
#include "ps/GameSetup/Config.h"
#include "ps/GameSetup/GameSetup.h"
#include "ps/Game.h"
#include "ps/Filesystem.h"
#include "renderer/Renderer.h"
#include "maths/MathUtil.h"
#include "graphics/GameView.h"
@ -52,9 +50,8 @@ void WriteSystemInfo()
struct utsname un;
uname(&un);
char N_path[PATH_MAX];
(void)file_make_full_native_path("../logs/system_info.txt", N_path);
FILE* f = fopen(N_path, "w");
Path pathname("../logs/system_info.txt");
FILE* f = fopen(pathname.external_file_string().c_str(), "w");
if(!f)
return;
@ -166,7 +163,7 @@ const wchar_t* ErrorString(int err)
}
static NextNumberedFilenameInfo screenshot_nfi;
static unsigned s_nextScreenshotNumber;
// <extension> identifies the file format that is to be written
// (case-insensitive). examples: "bmp", "png", "jpg".
@ -180,8 +177,7 @@ void WriteScreenshot(const char* extension)
snprintf(file_format_string, PATH_MAX, "screenshots/screenshot%%04d.%s", extension);
file_format_string[PATH_MAX-1] = '\0';
char fn[PATH_MAX];
next_numbered_filename(file_format_string, &screenshot_nfi, fn);
const char* atom_fn = file_make_unique_fn_copy(fn);
fs_NextNumberedFilename(g_VFS, file_format_string, s_nextScreenshotNumber, fn);
const int w = g_xres, h = g_yres;
const int bpp = 24;
@ -197,15 +193,14 @@ void WriteScreenshot(const char* extension)
const size_t img_size = w * h * bpp/8;
const size_t hdr_size = tex_hdr_size(fn);
FileIOBuf buf = file_buf_alloc(hdr_size+img_size, atom_fn, FB_FROM_HEAP);
GLvoid* img = (u8*)buf + hdr_size;
shared_ptr<u8> buf = io_Allocate(hdr_size+img_size);
GLvoid* img = buf.get() + hdr_size;
Tex t;
if(tex_wrap(w, h, bpp, flags, img, &t) < 0)
if(tex_wrap(w, h, bpp, flags, buf, hdr_size, &t) < 0)
return;
glReadPixels(0, 0, w, h, fmt, GL_UNSIGNED_BYTE, img);
(void)tex_write(&t, fn);
(void)tex_free(&t);
(void)file_buf_free(buf, FB_FROM_HEAP);
tex_free(&t);
}
@ -220,8 +215,7 @@ void WriteBigScreenshot(const char* extension, int tiles)
snprintf(file_format_string, PATH_MAX, "screenshots/screenshot%%04d.%s", extension);
file_format_string[PATH_MAX-1] = '\0';
char fn[PATH_MAX];
next_numbered_filename(file_format_string, &screenshot_nfi, fn);
const char* atom_fn = file_make_unique_fn_copy(fn);
fs_NextNumberedFilename(g_VFS, file_format_string, s_nextScreenshotNumber, fn);
// Slightly ugly and inflexible: Always draw 640*480 tiles onto the screen, and
// hope the screen is actually large enough for that.
@ -246,11 +240,11 @@ void WriteBigScreenshot(const char* extension, int tiles)
void* tile_data = malloc(tile_size);
if(!tile_data)
WARN_ERR_RETURN(ERR::NO_MEM);
FileIOBuf img_buf = file_buf_alloc(hdr_size+img_size, atom_fn, FB_FROM_HEAP);
shared_ptr<u8> img_buf = io_Allocate(hdr_size+img_size);
Tex t;
GLvoid* img = (u8*)img_buf + hdr_size;
if(tex_wrap(img_w, img_h, bpp, flags, img, &t) < 0)
GLvoid* img = img_buf.get() + hdr_size;
if(tex_wrap(img_w, img_h, bpp, flags, img_buf, hdr_size, &t) < 0)
return;
ogl_WarnIfError();
@ -309,7 +303,6 @@ void WriteBigScreenshot(const char* extension, int tiles)
}
(void)tex_write(&t, fn);
(void)tex_free(&t);
tex_free(&t);
free(tile_data);
(void)file_buf_free(img_buf, FB_FROM_HEAP);
}

View File

@ -1,46 +0,0 @@
#include "precompiled.h"
#include "VFSUtil.h"
#include "lib/res/file/vfs.h"
#include "CLogger.h"
#define LOG_CATEGORY "vfs"
#include <deque>
using namespace VFSUtil;
// Because I'm lazy, and it saves a few lines of code in other places:
bool VFSUtil::FindFiles (const CStr& dirname, const char* filter, FileList& files)
{
files.clear();
Handle dir = vfs_dir_open(dirname);
if (dir <= 0)
{
LOG(ERROR, LOG_CATEGORY, "Error opening directory '%s' (%lld)", dirname.c_str(), dir);
return false;
}
int err;
DirEnt entry;
while ((err = vfs_dir_next_ent(dir, &entry, filter)) == 0)
{
CStr path = dirname+entry.name;
if(DIRENT_IS_DIR(&entry))
path += '/';
files.push_back(path);
}
if (err != ERR::DIR_END)
{
LOG(ERROR, LOG_CATEGORY, "Error reading files from directory '%s' (%d)", dirname.c_str(), err);
return false;
}
vfs_dir_close(dir);
return true;
}

View File

@ -1,17 +0,0 @@
#include "ps/CStr.h"
#include "lib/path_util.h" // for convenience
#include "lib/res/file/vfs.h"
namespace VFSUtil
{
typedef std::vector<CStr> FileList;
// Puts the list of files inside 'dirname' matching 'filter' into 'files'.
// 'dirname' must end with a slash.
// 'filter': see vfs_next_dirent
// 'files' is initially cleared, and undefined on failure.
// On failure, logs an error and returns false.
extern bool FindFiles(const CStr& dirname, const char* filter, FileList& files);
} // namespace VFSUtil

View File

@ -54,8 +54,6 @@
#include "lib/mmgr.h" // restore malloc/new macros
#include "lib/res/handle.h"
#include "lib/res/file/file.h"
#include "XercesErrorHandler.h"
#include "ps/CStr.h"
@ -71,23 +69,23 @@ XMLCh *XMLTranscode(const char *);
*/
class CVFSInputSource: public InputSource
{
FileIOBuf m_pBuffer;
shared_ptr<u8> m_pBuffer;
size_t m_BufferSize;
CVFSInputSource(const CVFSInputSource &);
CVFSInputSource &operator = (const CVFSInputSource &);
public:
CVFSInputSource():
m_pBuffer(NULL),
m_BufferSize(0)
{}
CVFSInputSource()
: m_BufferSize(0)
{
}
virtual ~CVFSInputSource();
// Open a VFS path for XML parsing
// returns 0 if successful, -1 on failure
int OpenFile(const char *path, uint flags);
int OpenFile(const char *path);
virtual BinInputStream *makeStream() const;
};

View File

@ -1,12 +1,9 @@
#include "precompiled.h"
#include "XML.h"
#include "ps/Filesystem.h"
#include "ps/CStr.h"
#include "ps/CLogger.h"
#include "lib/posix/posix_types.h" // ptrdiff_t
#include "lib/res/file/vfs.h"
#include "lib/res/mem.h"
#define LOG_CATEGORY "xml"
@ -49,12 +46,12 @@ XMLCh *XMLTranscode(const char *str)
return XMLString::transcode(str);
}
int CVFSInputSource::OpenFile(const char *path, uint flags = 0)
int CVFSInputSource::OpenFile(const char *path)
{
LibError ret = vfs_load(path, m_pBuffer, m_BufferSize, flags);
LibError ret = g_VFS->LoadFile(path, m_pBuffer, m_BufferSize);
if(ret != INFO::OK)
{
LOG(ERROR, LOG_CATEGORY, "CVFSInputSource: file %s couldn't be loaded (vfs_load: %d)", path, ret);
LOG(ERROR, LOG_CATEGORY, "CVFSInputSource: file %s couldn't be loaded (LoadFile: %d)", path, ret);
return -1;
}
@ -67,22 +64,16 @@ int CVFSInputSource::OpenFile(const char *path, uint flags = 0)
CVFSInputSource::~CVFSInputSource()
{
// our buffer was vfs_load-ed; free it now
(void)file_buf_free(m_pBuffer);
m_pBuffer = 0;
}
BinInputStream *CVFSInputSource::makeStream() const
{
if (m_pBuffer != 0)
{
#include "lib/nommgr.h"
return new BinMemInputStream((XMLByte *)m_pBuffer, (unsigned int)m_BufferSize,
BinMemInputStream::BufOpt_Reference);
if(!m_pBuffer)
return 0;
#include "lib/nommgr.h" // BinMemInputStream has its own operator new
return new BinMemInputStream((XMLByte *)m_pBuffer.get(), (unsigned int)m_BufferSize, BinMemInputStream::BufOpt_Reference);
#include "lib/mmgr.h"
}
else
return NULL;
}
#define IS_PATH_SEP(_chr) (_chr == '/' || _chr == '\\')

View File

@ -3,10 +3,10 @@
#include "XMLWriter.h"
#include "ps/CLogger.h"
#include "lib/res/file/vfs.h"
#include "ps/Filesystem.h"
// TODO (maybe): Write to the VFS handle frequently, instead of buffering
// TODO (maybe): Write to the file frequently, instead of buffering
// the entire file, so that large files get written faster.
namespace
@ -62,15 +62,17 @@ XMLWriter_File::XMLWriter_File()
m_Data = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n";
}
bool XMLWriter_File::StoreVFS(Handle h)
bool XMLWriter_File::StoreVFS(const char* filename)
{
if (m_LastElement) debug_warn("ERROR: Saving XML while an element is still open");
FileIOBuf data = (FileIOBuf)m_Data.data();
int err = vfs_io(h, m_Data.length(), &data);
if (err < 0)
const size_t size = m_Data.length();
shared_ptr<u8> data = io_Allocate(size);
cpu_memcpy(data.get(), m_Data.data(), size);
LibError ret = g_VFS->CreateFile(filename, data, size);
if (ret < 0)
{
LOG(ERROR, "xml", "Error saving XML data through VFS: %lld", h);
LOG(ERROR, "xml", "Error saving XML data through VFS: %d", ret);
return false;
}
return true;

View File

@ -71,7 +71,7 @@ end of XMLWriter.cpp.
// Add a 'setting': <name>value</name>
#define XML_Setting(name, value) xml_element_.Setting(name, value)
// Output the XML file to a VFS handle, which must be opened with FILE_WRITE|FILE_NO_AIO.
// Create a VFS file from the XML data.
// Returns true on success, false (and logs an error) on failure.
#define XML_StoreVFS(handle) xml_file_.StoreVFS(handle)
@ -81,7 +81,6 @@ end of XMLWriter.cpp.
#include "ps/CStr.h"
#include "lib/res/handle.h"
class XMLWriter_Element;
@ -94,7 +93,7 @@ public:
void Comment(const char* text);
bool StoreVFS(Handle h);
bool StoreVFS(const char* filename);
const CStr& GetOutput();
private:

View File

@ -7,7 +7,7 @@
#include <algorithm>
#include "ps/CLogger.h"
#include "lib/res/file/vfs.h"
#include "ps/Filesystem.h"
#include "Xeromyces.h"
#define LOG_CATEGORY "xml"
@ -17,65 +17,6 @@
int CXeromyces::XercesLoaded = 0; // for once-only initialisation
// Slightly nasty fwrite/fseek/ftell style thing
class membuffer
{
public:
membuffer()
{
buffer = (char*)malloc(bufferinc);
debug_assert(buffer);
allocated = bufferinc;
length = 0;
}
~membuffer()
{
free(buffer);
}
void write(const void* data, int size)
{
while (length + size >= allocated) grow();
cpu_memcpy(&buffer[length], data, size);
length += size;
}
void write(const void* data, int size, int offset)
{
debug_assert(offset >= 0 && offset+size < length);
cpu_memcpy(&buffer[offset], data, size);
}
int tell()
{
return length;
}
char* steal_buffer()
{
char* ret = buffer;
buffer = NULL;
return ret;
}
char* buffer;
int length;
private:
int allocated;
static const int bufferinc = 1024;
void grow()
{
allocated += bufferinc;
char* newbuffer = (char*)realloc(buffer, allocated);
if (newbuffer)
buffer = newbuffer;
else
debug_warn("Xeromyces: realloc failed");
}
};
// Convenient storage for the internal tree
typedef struct {
std::string name;
@ -116,9 +57,9 @@ public:
// Non-SAX2 stuff, used for storing the
// parsed data and constructing the XMB:
void CreateXMB();
membuffer buffer;
WriteBuffer writeBuffer;
private:
std::set<std::string> ElementNames;
@ -139,23 +80,11 @@ private:
CXeromyces::CXeromyces()
: XMBFileHandle(0), XMBBuffer(NULL)
{
}
CXeromyces::~CXeromyces() {
if (XMBFileHandle)
{
// If it was read from a file, close it
delete XMBFileHandle;
}
else
{
// If it was converted from a XML directly into memory,
// free that memory buffer
free(XMBBuffer);
}
CXeromyces::~CXeromyces()
{
}
void CXeromyces::Terminate()
@ -186,7 +115,7 @@ void CXeromyces::GetXMBPath(const char* xmlFilename, const char* xmbFilename,
// get real path of XML file (e.g. mods/official/entities/...)
char P_XMBRealPath[PATH_MAX];
vfs_realpath(xmlFilename, P_XMBRealPath);
g_VFS->GetRealPath(xmlFilename, P_XMBRealPath);
// extract mod name from that
char modName[PATH_MAX];
@ -202,15 +131,15 @@ void CXeromyces::GetXMBPath(const char* xmlFilename, const char* xmbFilename,
PSRETURN CXeromyces::Load(const char* filename)
{
// Make sure the .xml actually exists
if (! vfs_exists(filename))
if (! FileExists(filename))
{
LOG(ERROR, LOG_CATEGORY, "CXeromyces: Failed to find XML file %s", filename);
return PSRETURN_Xeromyces_XMLOpenFailed;
}
// Get some data about the .xml file
struct stat xmlStat;
if (vfs_stat(filename, &xmlStat) < 0)
FileInfo fileInfo;
if (g_VFS->GetFileInfo(filename, &fileInfo) < 0)
{
LOG(ERROR, LOG_CATEGORY, "CXeromyces: Failed to stat XML file %s", filename);
return PSRETURN_Xeromyces_XMLOpenFailed;
@ -246,9 +175,9 @@ PSRETURN CXeromyces::Load(const char* filename)
const int bufLen = 22;
char buf[bufLen+1];
if (sprintf(buf, "_%08x%08xB.xmb", (int)xmlStat.st_mtime & ~1, (int)xmlStat.st_size) != bufLen)
if (sprintf(buf, "_%08x%08xB.xmb", (int)(fileInfo.MTime() & ~1), (int)fileInfo.Size()) != bufLen)
{
debug_warn("Failed to create filename (?!)");
debug_assert(0); // Failed to create filename (?!)
return PSRETURN_Xeromyces_XMLOpenFailed;
}
xmbFilename += buf;
@ -258,7 +187,7 @@ PSRETURN CXeromyces::Load(const char* filename)
// If the file exists, use it
if (vfs_exists(xmbPath))
if (FileExists(xmbPath))
{
if (ReadXMBFile(xmbPath))
return PSRETURN_OK;
@ -277,10 +206,8 @@ PSRETURN CXeromyces::Load(const char* filename)
}
// Open the .xml file
// note: FILE_LONG_LIVED is necessary because we load XML, load DTD,
// and only then free XML.
CVFSInputSource source;
if (source.OpenFile(filename, FILE_LONG_LIVED) < 0)
if (source.OpenFile(filename) < 0)
{
LOG(ERROR, LOG_CATEGORY, "CXeromyces: Failed to open XML file %s", filename);
return PSRETURN_Xeromyces_XMLOpenFailed;
@ -324,37 +251,26 @@ PSRETURN CXeromyces::Load(const char* filename)
handler.CreateXMB();
// Save the file to disk, so it can be loaded quickly next time
vfs_store(xmbPath, (const u8*)handler.buffer.buffer, handler.buffer.length, FILE_NO_AIO);
WriteBuffer& writeBuffer = handler.writeBuffer;
g_VFS->CreateFile(xmbPath, writeBuffer.Data(), writeBuffer.Size());
// Store the buffer so it can be freed later
XMBBuffer = handler.buffer.steal_buffer();
XMBBuffer = writeBuffer.Data(); // add a reference
// Set up the XMBFile
Initialise(XMBBuffer);
Initialise((const char*)XMBBuffer.get());
return PSRETURN_OK;
}
bool CXeromyces::ReadXMBFile(const char* filename)
{
CVFSFile* file = new CVFSFile;
// note: an XMB file's buffer is held in memory across all load/free
// sequences of dependent files it references. that hurts the
// file cache allocator and incurs a warning unless we
// inform the file manager of this behavior via FILE_LONG_LIVED.
if (file->Load(filename, FILE_LONG_LIVED) != PSRETURN_OK)
size_t size;
if(g_VFS->LoadFile(filename, XMBBuffer, size) < 0)
return false;
const u8* buffer = file->GetBuffer();
debug_assert(file->GetBufferSize() >= 42 && "Invalid XMB file"); // 42 bytes is the smallest possible XMB. (Well, maybe not quite, but it's a nice number.)
debug_assert(*(u32*)buffer == HeaderMagic && "Invalid XMB file header");
// Store the Handle so it can be closed later
XMBFileHandle = file;
debug_assert(size >= 42); // else: invalid XMB file size. (42 bytes is the smallest possible XMB. (Well, maybe not quite, but it's a nice number.))
// Set up the XMBFile
Initialise((const char*)buffer);
Initialise((const char*)XMBBuffer.get());
return true;
}
@ -447,7 +363,7 @@ void XeroHandler::characters(const XMLCh* const chars, const unsigned int UNUSED
void XeroHandler::CreateXMB()
{
// Header
buffer.write((void*)HeaderMagicStr, 4);
writeBuffer.Append((void*)HeaderMagicStr, 4);
std::set<std::string>::iterator it;
int i;
@ -455,24 +371,24 @@ void XeroHandler::CreateXMB()
// Element names
i = 0;
int ElementCount = (int)ElementNames.size();
buffer.write(&ElementCount, 4);
writeBuffer.Append(&ElementCount, 4);
for (it = ElementNames.begin(); it != ElementNames.end(); ++it)
{
int TextLen = (int)it->length()+1;
buffer.write(&TextLen, 4);
buffer.write((void*)it->c_str(), TextLen);
writeBuffer.Append(&TextLen, 4);
writeBuffer.Append((void*)it->c_str(), TextLen);
ElementID[*it] = i++;
}
// Attribute names
i = 0;
int AttributeCount = (int)AttributeNames.size();
buffer.write(&AttributeCount, 4);
writeBuffer.Append(&AttributeCount, 4);
for (it = AttributeNames.begin(); it != AttributeNames.end(); ++it)
{
int TextLen = (int)it->length()+1;
buffer.write(&TextLen, 4);
buffer.write((void*)it->c_str(), TextLen);
writeBuffer.Append(&TextLen, 4);
writeBuffer.Append((void*)it->c_str(), TextLen);
AttributeID[*it] = i++;
}
@ -490,21 +406,21 @@ void XeroHandler::CreateXMB()
void XeroHandler::OutputElement(XMLElement* el)
{
// Filled in later with the length of the element
int Pos_Length = buffer.tell();
buffer.write("????", 4);
int Pos_Length = (int)writeBuffer.Size();
writeBuffer.Append("????", 4);
int NameID = ElementID[el->name];
buffer.write(&NameID, 4);
writeBuffer.Append(&NameID, 4);
int AttrCount = (int)el->attrs.size();
buffer.write(&AttrCount, 4);
writeBuffer.Append(&AttrCount, 4);
int ChildCount = (int)el->childs.size();
buffer.write(&ChildCount, 4);
writeBuffer.Append(&ChildCount, 4);
// Filled in later with the offset to the list of child elements
int Pos_ChildrenOffset = buffer.tell();
buffer.write("????", 4);
int Pos_ChildrenOffset = (int)writeBuffer.Size();
writeBuffer.Append("????", 4);
// Trim excess whitespace in the entity's text, while counting
@ -538,15 +454,15 @@ void XeroHandler::OutputElement(XMLElement* el)
if (el->text.length() == 0)
{
// No text; don't write much
buffer.write("\0\0\0\0", 4);
writeBuffer.Append("\0\0\0\0", 4);
}
else
{
// Write length and line number and null-terminated text
int NodeLen = 4 + 2*((int)el->text.length()+1);
buffer.write(&NodeLen, 4);
buffer.write(&el->linenum, 4);
buffer.write((void*)el->text.c_str(), NodeLen-4);
writeBuffer.Append(&NodeLen, 4);
writeBuffer.Append(&el->linenum, 4);
writeBuffer.Append((void*)el->text.c_str(), NodeLen-4);
}
// Output attributes
@ -556,27 +472,27 @@ void XeroHandler::OutputElement(XMLElement* el)
for (i = 0; i < AttrCount; ++i)
{
int AttrName = AttributeID[el->attrs[i]->name];
buffer.write(&AttrName, 4);
writeBuffer.Append(&AttrName, 4);
int AttrLen = 2*((int)el->attrs[i]->value.length()+1);
buffer.write(&AttrLen, 4);
buffer.write((void*)el->attrs[i]->value.c_str(), AttrLen);
writeBuffer.Append(&AttrLen, 4);
writeBuffer.Append((void*)el->attrs[i]->value.c_str(), AttrLen);
// Free each attribute as soon as it's been dealt with
delete el->attrs[i];
}
// Go back and fill in the child-element offset
int ChildrenOffset = buffer.tell() - (Pos_ChildrenOffset+4);
buffer.write(&ChildrenOffset, 4, Pos_ChildrenOffset);
int ChildrenOffset = (int)writeBuffer.Size() - (Pos_ChildrenOffset+4);
writeBuffer.Overwrite(&ChildrenOffset, 4, Pos_ChildrenOffset);
// Output all child nodes
for (i = 0; i < ChildCount; ++i)
OutputElement(el->childs[i]);
// Go back and fill in the length
int Length = buffer.tell() - Pos_Length;
buffer.write(&Length, 4, Pos_Length);
int Length = (int)writeBuffer.Size() - Pos_Length;
writeBuffer.Overwrite(&Length, 4, Pos_Length);
// Tidy up the parser's mess
delete el;

View File

@ -13,7 +13,6 @@ ERROR_TYPE(Xeromyces, XMLOpenFailed);
ERROR_TYPE(Xeromyces, XMLParseError);
#include "XeroXMB.h"
#include "ps/CVFSFile.h"
class CXeromyces : public XMBFile
{
@ -31,14 +30,11 @@ public:
private:
// Find out write location of the XMB file corresponding to xmlFilename
static void GetXMBPath(const char* xmlFilename, const char* xmbFilename,
char* xmbPath);
static void GetXMBPath(const char* xmlFilename, const char* xmbFilename, char* xmbPath);
bool ReadXMBFile(const char* filename);
XMBFile* XMB;
CVFSFile* XMBFileHandle; // if it's being read from disk
char* XMBBuffer; // if it's being read from RAM
shared_ptr<u8> XMBBuffer;
static int XercesLoaded; // for once-only initialisation
};

View File

@ -1,10 +1,9 @@
#include "precompiled.h"
#include "ps/i18n.h"
#include "ps/CVFSFile.h"
#include "scripting/ScriptingHost.h"
#include "ps/VFSUtil.h"
#include "ps/Filesystem.h"
#include "ps/CLogger.h"
#define LOG_CATEGORY "i18n"
@ -44,59 +43,51 @@ bool I18n::LoadLanguage(const char* name)
CStr dirname = CStr("language/")+name+"/";
VFSUtil::FileList files;
VFSUtil::FileList::iterator filename;
// Open *.lng with LoadStrings
if (! VFSUtil::FindFiles(dirname, "*.lng", files))
VfsPaths pathnames;
if(fs_GetPathnames(g_VFS, dirname, "*.lng", pathnames) < 0)
return false;
for (filename = files.begin(); filename != files.end(); ++filename)
for (size_t i = 0; i < pathnames.size(); i++)
{
const char* pathname = pathnames[i].string().c_str();
CVFSFile strings;
if (! (strings.Load(*filename) == PSRETURN_OK && locale->LoadStrings((const char*)strings.GetBuffer())))
if (! (strings.Load(pathname) == PSRETURN_OK && locale->LoadStrings((const char*)strings.GetBuffer())))
{
LOG(ERROR, LOG_CATEGORY, "Error opening language string file '%s'", filename->c_str());
LOG(ERROR, LOG_CATEGORY, "Error opening language string file '%s'", pathname);
return false;
}
}
// Open *.wrd with LoadDictionary
if (! VFSUtil::FindFiles(dirname, "*.wrd", files))
if(fs_GetPathnames(g_VFS, dirname, "*.wrd", pathnames) < 0)
return false;
for (filename = files.begin(); filename != files.end(); ++filename)
for (size_t i = 0; i < pathnames.size(); i++)
{
const char* pathname = pathnames[i].string().c_str();
CVFSFile strings;
if (! (strings.Load(*filename) == PSRETURN_OK && locale->LoadDictionary((const char*)strings.GetBuffer())))
if (! (strings.Load(pathname) == PSRETURN_OK && locale->LoadDictionary((const char*)strings.GetBuffer())))
{
LOG(ERROR, LOG_CATEGORY, "Error opening language string file '%s'", filename->c_str());
LOG(ERROR, LOG_CATEGORY, "Error opening language string file '%s'", pathname);
return false;
}
}
// Open *.js with LoadFunctions
if (! VFSUtil::FindFiles(dirname, "*.js", files))
if(fs_GetPathnames(g_VFS, dirname, "*.js", pathnames) < 0)
return false;
for (filename = files.begin(); filename != files.end(); ++filename)
for (size_t i = 0; i < pathnames.size(); i++)
{
const char* pathname = pathnames[i].string().c_str();
CVFSFile strings;
if (! (strings.Load(*filename) == PSRETURN_OK
if (! (strings.Load(pathname) == PSRETURN_OK
&&
locale->LoadFunctions(
(const char*)strings.GetBuffer(),
strings.GetBufferSize(),
filename->c_str()
pathname
)))
{
LOG(ERROR, LOG_CATEGORY, "Error opening language function file '%s'", filename->c_str());
LOG(ERROR, LOG_CATEGORY, "Error opening language function file '%s'", pathname);
return false;
}
}

View File

@ -3,10 +3,8 @@
#include <sstream>
#include "ps/CStr.h"
#include "ps/VFSUtil.h"
#include "lib/res/res.h"
#include "lib/res/file/archive/vfs_optimizer.h" // ArchiveBuilderCancel
#include "lib/res/file/vfs_mount.h" // TNODE_NOT_FOUND
#include "ps/Filesystem.h"
//#include "lib/res/file/archive/vfs_optimizer.h" // ArchiveBuilderCancel
#include "scripting/ScriptingHost.h"
#include "scripting/JSConversions.h"
#include "ps/scripting/JSInterface_VFS.h"
@ -14,7 +12,7 @@
// shared error handling code
#define JS_CHECK_FILE_ERR(err)\
/* this is liable to happen often, so don't complain */\
if(err == ERR::TNODE_NOT_FOUND)\
if(err == ERR::VFS_FILE_NOT_FOUND)\
{\
*rval = JSVAL_NULL;\
return( JS_TRUE );\
@ -50,14 +48,13 @@ struct BuildDirEntListState
};
// called for each matching directory entry; add its full pathname to array.
static void BuildDirEntListCB(const char* path, const DirEnt* UNUSED(ent), uintptr_t cbData)
static LibError BuildDirEntListCB(const VfsPath& pathname, const FileInfo& UNUSED(fileINfo), uintptr_t cbData)
{
BuildDirEntListState* s = (BuildDirEntListState*)cbData;
jsval val = ToJSVal( CStr ( path ) );
// note: <path> is already directory + name!
jsval val = ToJSVal( CStr(pathname.string()) );
JS_SetElement(s->cx, s->filename_array, s->cur_idx++, &val);
return INFO::CB_CONTINUE;
}
@ -100,12 +97,12 @@ JSBool JSI_VFS::BuildDirEntList( JSContext* cx, JSObject* UNUSED(obj), uintN arg
if( !ToPrimitive<bool>( cx, argv[2], recursive ) )
return( JS_FALSE );
}
int flags = recursive? VFS_DIR_RECURSIVE : 0;
int flags = recursive? DIR_RECURSIVE : 0;
// build array in the callback function
BuildDirEntListState state(cx);
vfs_dir_enum( path, flags, filter, BuildDirEntListCB, (uintptr_t)&state );
fs_ForEachFile(g_VFS, path, BuildDirEntListCB, (uintptr_t)&state, filter, flags);
*rval = OBJECT_TO_JSVAL( state.filename_array );
return( JS_TRUE );
@ -123,11 +120,11 @@ JSBool JSI_VFS::GetFileMTime( JSContext* cx, JSObject* UNUSED(obj), uintN argc,
if( !ToPrimitive<CStr>( cx, argv[0], filename ) )
return( JS_FALSE );
struct stat s;
LibError err = vfs_stat( filename.c_str(), &s );
FileInfo fileInfo;
LibError err = g_VFS->GetFileInfo(filename.c_str(), &fileInfo);
JS_CHECK_FILE_ERR( err );
*rval = ToJSVal( (double)s.st_mtime );
*rval = ToJSVal( (double)fileInfo.MTime() );
return( JS_TRUE );
}
@ -143,11 +140,11 @@ JSBool JSI_VFS::GetFileSize( JSContext* cx, JSObject* UNUSED(obj), uintN argc, j
if( !ToPrimitive<CStr>( cx, argv[0], filename ) )
return( JS_FALSE );
struct stat s;
LibError err = vfs_stat( filename.c_str(), &s );
FileInfo fileInfo;
LibError err = g_VFS->GetFileInfo(filename.c_str(), &fileInfo);
JS_CHECK_FILE_ERR(err);
*rval = ToJSVal( (uint)s.st_size );
*rval = ToJSVal( (uint)fileInfo.Size() );
return( JS_TRUE );
}
@ -163,13 +160,11 @@ JSBool JSI_VFS::ReadFile( JSContext* cx, JSObject* UNUSED(obj), uintN argc, jsva
if( !ToPrimitive<CStr>( cx, argv[0], filename ) )
return( JS_FALSE );
FileIOBuf buf;
size_t size;
LibError err = vfs_load( filename.c_str(), buf, size );
shared_ptr<u8> buf; size_t size;
LibError err = g_VFS->LoadFile( filename.c_str(), buf, size );
JS_CHECK_FILE_ERR( err );
CStr contents( (const char*)buf, size );
(void)file_buf_free(buf);
CStr contents( (const char*)buf.get(), size );
// Fix CRLF line endings. (This function will only ever be used on text files.)
contents.Replace("\r\n", "\n");
@ -194,13 +189,11 @@ JSBool JSI_VFS::ReadFileLines( JSContext* cx, JSObject* UNUSED(obj), uintN argc,
// read file
//
FileIOBuf buf;
size_t size;
LibError err = vfs_load( filename.c_str( ), buf, size );
shared_ptr<u8> buf; size_t size;
LibError err = g_VFS->LoadFile( filename.c_str( ), buf, size );
JS_CHECK_FILE_ERR( err );
CStr contents( (const char*)buf, size );
(void)file_buf_free( buf );
CStr contents( (const char*)buf.get(), size );
// Fix CRLF line endings. (This function will only ever be used on text files.)
contents.Replace("\r\n", "\n");
@ -234,6 +227,6 @@ JSBool JSI_VFS::ReadFileLines( JSContext* cx, JSObject* UNUSED(obj), uintN argc,
JSBool JSI_VFS::ArchiveBuilderCancel(JSContext* UNUSED(cx), JSObject* UNUSED(obj), uintN argc, jsval* UNUSED(argv), jsval* UNUSED(rval) )
{
debug_assert( argc == 0 );
vfs_opt_auto_build_cancel();
// vfs_opt_auto_build_cancel();
return( JS_TRUE );
}

View File

@ -7,8 +7,6 @@
#include "scripting/ScriptingHost.h"
// [KEEP IN SYNC WITH TDD AND WIKI]
// these are registered in ScriptGlue.cpp, hence the need for a header.
namespace JSI_VFS
@ -18,7 +16,7 @@ namespace JSI_VFS
//
// pathnames = buildDirEntList(start_path [, filter_string [, recursive ] ]);
// directory: VFS path
// filter_string: default "" matches everything; otherwise, see vfs_next_dirent.
// filter_string: see match_wildcard; "" matches everything.
// recurse: should subdirectories be included in the search? default false.
//
// note: full pathnames of each file/subdirectory are returned,

View File

@ -10,84 +10,86 @@
// native type and distinct from utf16_t.
#include <string>
#include "lib/sysdep/cpu.h"
#include "lib/sysdep/cpu.h" // cpu_memcpy
typedef uint16_t utf16_t;
typedef std::basic_string<utf16_t> utf16string;
typedef std::basic_stringstream<utf16_t> utf16stringstream;
namespace std {
template<>
struct char_traits<utf16_t>
// jw: this was originally defined in the std namespace, which is at
// least frowned upon if not illegal. giving it a new name and passing it
// as a template parameter is the "correct" and safe way.
struct utf16_traits
{
typedef utf16_t char_type;
typedef int int_type;
typedef std::streampos pos_type;
typedef std::streamoff off_type;
typedef std::mbstate_t state_type;
static void assign(char_type& c1, const char_type& c2)
{ c1 = c2; }
static bool eq(const char_type& c1, const char_type& c2)
{ return c1 == c2; }
static bool lt(const char_type& c1, const char_type& c2)
{ return c1 < c2; }
static int compare(const char_type* s1, const char_type* s2, size_t n)
{
typedef utf16_t char_type;
typedef int int_type;
typedef streampos pos_type;
typedef streamoff off_type;
typedef mbstate_t state_type;
return memcmp(s1, s2, n*sizeof(char_type));
}
static void assign(char_type& c1, const char_type& c2)
{ c1 = c2; }
static size_t length(const char_type* s)
{
const char_type* end=s;
while (*end) end++;
return end-s;
}
static bool eq(const char_type& c1, const char_type& c2)
{ return c1 == c2; }
static const char_type* find(const char_type* s, size_t n, const char_type& a)
{
const char_type *end = s+n;
const char_type *res = std::find(s, end, a);
return (res != end)?res:NULL;
}
static bool lt(const char_type& c1, const char_type& c2)
{ return c1 < c2; }
static char_type* move(char_type* s1, const char_type* s2, size_t n)
{
return (char_type *)memmove(s1, s2, n*sizeof(char_type));
}
static int compare(const char_type* s1, const char_type* s2, size_t n)
static char_type* copy(char_type* s1, const char_type* s2, size_t n)
{
return (char_type *)cpu_memcpy(s1, s2, n*sizeof(char_type));
}
static char_type* assign(char_type* s, size_t n, char_type a)
{
while (n--)
{
return memcmp(s1, s2, n*sizeof(char_type));
s[n]=a;
}
return s;
}
static size_t length(const char_type* s)
{
const char_type* end=s;
while (*end) end++;
return end-s;
}
static char_type to_char_type(const int_type& c)
{ return (char_type)c; }
static const char_type* find(const char_type* s, size_t n, const char_type& a)
{
const char_type *end = s+n;
const char_type *res = std::find(s, end, a);
return (res != end)?res:NULL;
}
static int_type to_int_type(const char_type& c)
{ return (int_type)c; }
static char_type* move(char_type* s1, const char_type* s2, size_t n)
{
return (char_type *)memmove(s1, s2, n*sizeof(char_type));
}
static bool eq_int_type(const int_type& c1, const int_type& c2)
{ return c1 == c2; }
static char_type* copy(char_type* s1, const char_type* s2, size_t n)
{
return (char_type *)cpu_memcpy(s1, s2, n*sizeof(char_type));
}
static int_type eof()
{ return -1; }
static char_type* assign(char_type* s, size_t n, char_type a)
{
while (n--)
{
s[n]=a;
}
return s;
}
static int_type not_eof(const int_type& c)
{ return (c == -1) ? 0 : c; }
};
static char_type to_char_type(const int_type& c)
{ return (char_type)c; }
static int_type to_int_type(const char_type& c)
{ return (int_type)c; }
static bool eq_int_type(const int_type& c1, const int_type& c2)
{ return c1 == c2; }
static int_type eof()
{ return -1; }
static int_type not_eof(const int_type& c)
{ return (c == -1) ? 0 : c; }
};
}
typedef std::basic_string<utf16_t, utf16_traits> utf16string;
typedef std::basic_stringstream<utf16_t, utf16_traits> utf16stringstream;
#endif

View File

@ -19,13 +19,13 @@
#include "renderer/VertexArray.h"
class RenderModifier;
typedef boost::shared_ptr<RenderModifier> RenderModifierPtr;
typedef shared_ptr<RenderModifier> RenderModifierPtr;
class LitRenderModifier;
typedef boost::shared_ptr<LitRenderModifier> LitRenderModifierPtr;
typedef shared_ptr<LitRenderModifier> LitRenderModifierPtr;
class ModelVertexRenderer;
typedef boost::shared_ptr<ModelVertexRenderer> ModelVertexRendererPtr;
typedef shared_ptr<ModelVertexRenderer> ModelVertexRendererPtr;
class CModel;

View File

@ -14,13 +14,8 @@
#include <algorithm>
#include "lib/bits.h" // is_pow2
#include "Renderer.h"
#include "graphics/Terrain.h"
#include "maths/Matrix3D.h"
#include "maths/MathUtil.h"
#include "graphics/Camera.h"
#include "graphics/Texture.h"
#include "graphics/LightEnv.h"
#include "graphics/Terrain.h"
#include "ps/Pyrogenesis.h" // MICROLOG
#include "ps/CLogger.h"
#include "ps/Game.h"
@ -28,20 +23,21 @@
#include "ps/Game.h"
#include "ps/World.h"
#include "ps/Player.h"
#include "ps/Loader.h"
#include "ps/ProfileViewer.h"
#include "simulation/LOSManager.h"
#include "simulation/TerritoryManager.h"
#include "lib/path_util.h"
#include "lib/file/io/io.h" // io_Allocate
#include "lib/res/graphics/ogl_tex.h"
#include "graphics/Camera.h"
#include "graphics/Texture.h"
#include "graphics/LightEnv.h"
#include "graphics/Terrain.h"
#include "graphics/Model.h"
#include "graphics/ModelDef.h"
#include "lib/ogl.h"
#include "lib/path_util.h"
#include "lib/res/res.h"
#include "lib/res/graphics/tex.h"
#include "lib/res/graphics/ogl_tex.h"
#include "ps/Loader.h"
#include "ps/ProfileViewer.h"
#include "graphics/GameView.h"
#include "graphics/ParticleEngine.h"
#include "graphics/DefaultEmitter.h"
@ -1561,7 +1557,7 @@ int CRenderer::LoadAlphaMaps()
(void)path_package_append_file(&pp, fnames[i]);
// note: these individual textures can be discarded afterwards;
// we cache the composite.
textures[i] = ogl_tex_load(pp.path, RES_NO_CACHE);
textures[i] = ogl_tex_load(pp.path);
RETURN_ERR(textures[i]);
// quick hack: we require plain RGB(A) format, so convert to that.
@ -1592,7 +1588,7 @@ ogl_tex_transform_to(textures[i], flags & ~TEX_DXT);
uint tile_w = 2+base+2; // 2 pixel border (avoids bilinear filtering artifacts)
uint total_w = RoundUpToPowerOf2(tile_w * NumAlphaMaps);
uint total_h = base; debug_assert(is_pow2(total_h));
u8* data=new u8[total_w*total_h*3];
shared_ptr<u8> data = io_Allocate(total_w*total_h*3);
// for each tile on row
for(uint i=0;i<NumAlphaMaps;i++)
{
@ -1603,7 +1599,7 @@ ogl_tex_transform_to(textures[i], flags & ~TEX_DXT);
uint srcstep=bpp/8;
// get destination of copy
u8* dst=data+3*(i*tile_w);
u8* dst=data.get()+3*(i*tile_w);
// for each row of image
for (uint j=0;j<base;j++) {
@ -1640,12 +1636,11 @@ ogl_tex_transform_to(textures[i], flags & ~TEX_DXT);
// upload the composite texture
Tex t;
(void)tex_wrap(total_w, total_h, 24, 0, data, &t);
(void)tex_wrap(total_w, total_h, 24, 0, data, 0, &t);
m_hCompositeAlphaMap = ogl_tex_wrap(&t, key);
(void)ogl_tex_set_filter(m_hCompositeAlphaMap, GL_LINEAR);
(void)ogl_tex_set_wrap (m_hCompositeAlphaMap, GL_CLAMP_TO_EDGE);
int ret = ogl_tex_upload(m_hCompositeAlphaMap, 0, 0, GL_INTENSITY);
delete[] data;
return ret;
}

View File

@ -11,15 +11,15 @@
#include <algorithm>
#include "lib/timer.h"
#include "lib/res/file/vfs.h"
#include "lib/res/graphics/tex.h"
#include "lib/tex/tex.h"
#include "lib/res/graphics/ogl_tex.h"
#include "maths/MathUtil.h"
#include "ps/CStr.h"
#include "ps/CLogger.h"
#include "ps/Loader.h"
#include "ps/VFSUtil.h"
#include "ps/Filesystem.h"
#include "renderer/SkyManager.h"
#include "renderer/Renderer.h"
@ -151,28 +151,15 @@ std::vector<CStrW> SkyManager::GetSkySets() const
// Find all subdirectories in art/textures/skies
const char* dirname = "art/textures/skies/";
Handle dir = vfs_dir_open(dirname);
if (dir <= 0)
DirectoryNames subdirectories;
if(g_VFS->GetDirectoryEntries(dirname, 0, &subdirectories) < 0)
{
LOG(ERROR, "vfs", "Error opening directory '%s' (%lld)", dirname, dir);
LOG(ERROR, "vfs", "Error opening directory '%s'", dirname);
return std::vector<CStrW>(1, GetSkySet()); // just return what we currently have
}
const char* filter = "/";
int err;
DirEnt entry;
while ((err = vfs_dir_next_ent(dir, &entry, filter)) == 0)
{
skies.push_back(CStr(entry.name));
}
if (err != ERR::DIR_END)
{
LOG(ERROR, "vfs", "Error reading files from directory '%s' (%d)", dirname, err);
return std::vector<CStrW>(1, GetSkySet()); // just return what we currently have
}
vfs_dir_close(dir);
for(size_t i = 0; i < subdirectories.size(); i++)
skies.push_back(CStr(subdirectories[i]));
sort(skies.begin(), skies.end());

View File

@ -9,7 +9,7 @@
#include "precompiled.h"
#include "lib/timer.h"
#include "lib/res/graphics/tex.h"
#include "lib/tex/tex.h"
#include "lib/res/graphics/ogl_tex.h"
#include "maths/MathUtil.h"

View File

@ -19,6 +19,7 @@
#include "graphics/scripting/JSInterface_LightEnv.h"
#include "gui/CGUI.h"
#include "lib/timer.h"
#include "lib/frequency_filter.h"
#include "maths/scripting/JSInterface_Vector3D.h"
#include "network/Client.h"
#include "network/Server.h"
@ -913,7 +914,8 @@ JSBool GetFps( JSContext* cx, JSObject*, uint argc, jsval* argv, jsval* rval )
{
JSU_REQUIRE_NO_PARAMS();
*rval = INT_TO_JSVAL(fps);
extern PIFrequencyFilter g_frequencyFilter;
*rval = INT_TO_JSVAL(g_frequencyFilter->StableFrequency());
return JS_TRUE;
}

View File

@ -6,8 +6,7 @@
#include "ScriptGlue.h"
#include "ps/Profile.h"
#include "ps/CLogger.h"
#include "lib/res/res.h"
#include "ps/Filesystem.h"
#if OS_WIN
@ -116,15 +115,12 @@ void ScriptingHost::RunScript(const CStr& filename, JSObject* globalObject)
{
const char* fn = filename.c_str();
FileIOBuf buf;
size_t size;
if(vfs_load(fn, buf, size) != INFO::OK) // ERRTODO: translate/pass it on
shared_ptr<u8> buf; size_t size;
if(g_VFS->LoadFile(fn, buf, size) != INFO::OK) // ERRTODO: translate/pass it on
throw PSERROR_Scripting_LoadFile_OpenFailed();
const char* script = (const char*)buf;
const char* script = (const char*)buf.get();
RunMemScript(script, size, fn, 1, globalObject);
(void)file_buf_free(buf);
}
jsval ScriptingHost::CallFunction(const std::string & functionName, jsval * params, int numParams)

View File

@ -5,35 +5,32 @@
#include "graphics/ObjectManager.h"
#include "graphics/Model.h"
#include "ps/CLogger.h"
#include "ps/VFSUtil.h"
#include "ps/Player.h"
#include "ps/Game.h"
#define LOG_CATEGORY "entity"
void CEntityTemplateCollection::LoadFile( const char* path )
void CEntityTemplateCollection::LoadFile( const VfsPath& pathname )
{
// Build the entity name -> filename mapping. This is done so that
// the entity 'x' can be in units/x.xml, structures/x.xml, etc, and
// we don't have to search every directory for x.xml.
// Extract the filename out of the path+name+extension.
// Equivalent to /.*\/(.*)\.xml/, but not as pretty.
CStrW tag = CStr(path).AfterLast("/").BeforeLast(".xml");
m_templateFilenames[tag] = path;
CStrW basename(Basename(pathname));
m_templateFilenames[basename] = pathname.string();
}
static void LoadFileThunk( const char* path, const DirEnt* UNUSED(ent), uintptr_t cbData )
static LibError LoadFileThunk( const VfsPath& path, const FileInfo& UNUSED(fileInfo), uintptr_t cbData )
{
CEntityTemplateCollection* this_ = (CEntityTemplateCollection*)cbData;
this_->LoadFile(path);
return INFO::CB_CONTINUE;
}
int CEntityTemplateCollection::LoadTemplates()
{
// List all files in entities/ and its subdirectories.
THROW_ERR( vfs_dir_enum( "entities/", VFS_DIR_RECURSIVE, "*.xml",
LoadFileThunk, (uintptr_t)this ) );
THROW_ERR( fs_ForEachFile(g_VFS, "entities/", LoadFileThunk, (uintptr_t)this, "*.xml", DIR_RECURSIVE));
/*// Load all the templates; this is necessary so that we can apply techs to them
// (otherwise a tech can't affect the template of a unit that doesn't yet exist)

View File

@ -19,6 +19,7 @@
#include "ps/CStr.h"
#include "ps/Singleton.h"
#include "ps/Game.h"
#include "ps/Filesystem.h"
#define g_EntityTemplateCollection CEntityTemplateCollection::GetSingleton()
@ -43,7 +44,7 @@ public:
// Load list of template filenames
int LoadTemplates();
void LoadFile( const char* path );
void LoadFile( const VfsPath& path );
// Create a list of the names of all base entities, excluding template_*,
// for display in ScEd's entity-selection box.

View File

@ -4,34 +4,31 @@
#include "graphics/ObjectManager.h"
#include "graphics/Model.h"
#include "ps/CLogger.h"
#include "ps/VFSUtil.h"
#define LOG_CATEGORY "formation"
void CFormationCollection::LoadFile( const char* path )
void CFormationCollection::LoadFile( const VfsPath& pathname )
{
// Build the formation name -> filename mapping. This is done so that
// the formation 'x' can be in units/x.xml, structures/x.xml, etc, and
// we don't have to search every directory for x.xml.
// Extract the filename out of the path+name+extension.
// Equivalent to /.*\/(.*)\.xml/, but not as pretty.
CStrW tag = CStr(path).AfterLast("/").BeforeLast(".xml");
m_templateFilenames[tag] = path;
CStrW basename(Basename(pathname));
m_templateFilenames[basename] = pathname.string();
}
static void LoadFormationThunk( const char* path, const DirEnt* UNUSED(ent), uintptr_t cbData )
static LibError LoadFormationThunk( const VfsPath& path, const FileInfo& UNUSED(fileInfo), uintptr_t cbData )
{
CFormationCollection* this_ = (CFormationCollection*)cbData;
this_->LoadFile(path);
return INFO::CB_CONTINUE;
}
int CFormationCollection::LoadTemplates()
{
// Load all files in formations and subdirectories.
THROW_ERR( vfs_dir_enum( "formations", VFS_DIR_RECURSIVE, "*.xml",
LoadFormationThunk, (uintptr_t)this ) );
THROW_ERR( fs_ForEachFile(g_VFS, "formations/", LoadFormationThunk, (uintptr_t)this, "*.xml", DIR_RECURSIVE));
return 0;
}

View File

@ -10,6 +10,7 @@
#include <vector>
#include "ps/CStr.h"
#include "ps/Singleton.h"
#include "ps/Filesystem.h"
#include "Formation.h"
#define g_EntityFormationCollection CFormationCollection::GetSingleton()
@ -26,7 +27,7 @@ public:
~CFormationCollection();
CFormation* GetTemplate( const CStrW& formationType );
int LoadTemplates();
void LoadFile( const char* path );
void LoadFile( const VfsPath& path );
// Create a list of the names of all base entities, excluding template_*,
// for display in ScEd's entity-selection box.

View File

@ -2,29 +2,27 @@
#include "TechnologyCollection.h"
#include "ps/CLogger.h"
#include "ps/VFSUtil.h"
#include "ps/Player.h"
#define LOG_CATEGORY "tech"
void CTechnologyCollection::LoadFile( const char* path )
void CTechnologyCollection::LoadFile( const VfsPath& pathname )
{
//Make tech file reading
CStrW tag = CStr(path).AfterLast("/").BeforeLast(".xml");
m_techFilenames[tag] = path;
CStrW basename(Basename(pathname));
m_techFilenames[basename] = pathname.string();
}
static void LoadTechThunk( const char* path, const DirEnt* UNUSED(ent), uintptr_t cbData )
static LibError LoadTechThunk( const VfsPath& pathname, const FileInfo& UNUSED(fileInfo), uintptr_t cbData )
{
CTechnologyCollection* this_ = (CTechnologyCollection*)cbData;
this_->LoadFile(path);
this_->LoadFile(pathname);
return INFO::CB_CONTINUE;
}
int CTechnologyCollection::LoadTechnologies()
{
// Load all files in techs/ and subdirectories.
THROW_ERR( vfs_dir_enum( "technologies/", VFS_DIR_RECURSIVE, "*.xml",
LoadTechThunk, (uintptr_t)this ) );
THROW_ERR( fs_ForEachFile(g_VFS, "technologies/", LoadTechThunk, (uintptr_t)this, "*.xml", DIR_RECURSIVE));
return 0;
}

View File

@ -8,6 +8,7 @@
#include "ps/Singleton.h"
#include "Technology.h"
#include "ps/Game.h"
#include "ps/Filesystem.h"
#define g_TechnologyCollection CTechnologyCollection::GetSingleton()
@ -28,7 +29,7 @@ public:
int LoadTechnologies();
// called by non-member trampoline via LoadTechnologies
void LoadFile( const char* path );
void LoadFile( const VfsPath& path );
};
#endif

View File

@ -6,8 +6,6 @@
#include <sstream>
#include <list>
#include "lib/res/res.h"
#define LOG_CATEGORY "audio"

View File

@ -1,8 +1,9 @@
#include "precompiled.h"
#include "CPlayList.h"
#include <stdio.h> // sscanf
#include "lib/res/res.h"
#include "ps/Filesystem.h"
CPlayList::CPlayList(void)
{
@ -19,21 +20,19 @@ CPlayList::~CPlayList(void)
}
void CPlayList::Load(const char* file)
void CPlayList::Load(const char* filename)
{
tracks.clear();
FileIOBuf buf; size_t size;
if(vfs_load(file, buf, size) < 0)
shared_ptr<u8> buf; size_t size;
if(g_VFS->LoadFile(filename, buf, size) < 0)
return;
const char* playlist = (const char*)buf;
const char* playlist = (const char*)buf.get();
char track[512];
while(sscanf(playlist, "%511s\n", track) == 1)
tracks.push_back(track);
(void)file_buf_free(buf);
}

View File

@ -14,7 +14,6 @@
#include "lib/app_hooks.h"
#include "lib/external_libraries/sdl.h"
#include "lib/timer.h"
#include "lib/res/file/vfs.h"
#include "ps/CLogger.h"
#include "ps/DllLoader.h"
#include "ps/Profile.h"
@ -203,7 +202,7 @@ bool BeginAtlas(const CmdLineArgs& args, const DllLoader& dll)
// Do per-frame processing:
vfs_reload_changed_files();
// vfs_reload_changed_files();
state.view->Update(state.frameLength);

View File

@ -8,7 +8,7 @@
#include "ps/Game.h"
#include "ps/CStr.h"
#include "ps/CLogger.h"
#include "ps/VFSUtil.h"
#include "ps/Filesystem.h"
#include "maths/MathUtil.h"
#include "maths/Quaternion.h"
#include "lib/res/graphics/ogl_tex.h"

View File

@ -10,7 +10,6 @@
#include "graphics/ObjectManager.h"
#include "gui/CGUI.h"
#include "gui/GUIbase.h"
#include "lib/res/file/vfs.h"
#include "lib/external_libraries/sdl.h"
#include "maths/MathUtil.h"
#include "ps/CConsole.h"
@ -131,7 +130,7 @@ MESSAGEHANDLER(SetActorViewer)
View::GetView_Actor()->GetActorViewer().SetActor(L"", L"");
View::GetView_Actor()->GetActorViewer().UnloadObjects();
vfs_reload_changed_files();
// vfs_reload_changed_files();
}
View::GetView_Actor()->SetSpeedMultiplier(msg->speed);
View::GetView_Actor()->GetActorViewer().SetActor(*msg->id, *msg->animation);