For those of you who don't know PhysFS: It's sort of a virtual file system to which you can mount actual locations from your physical file system (directories or archives). Then, whenever you request a file from the PhysFS system, all locations from the search path are scanned in order and the first match is returned. In addition, you can define one write dir where all of your files will be written to. With this approach PhysFS manages to solve a couple of interesting situations for games:
- Multi-user environments: Traditionally on Unix, but meanwhile sometimes on Windows also, common users don't necessarily have write access to your game's installation directory. But you'll still want to save configuration files, save games, replays, ... With PhysFS you just specify a path in the user's home directory as your first read location and as the write location, then add your game's data directory as the second read location. That way you can access files from both locations even though your game doesn't know because the PhysFS system hides this.
- Security: PhysFS takes care that no write access leaves the PhysFS write directory. Might be useful to protect scripting environments from harmful scripts.
- Support for various types of archives as read locations. Mostly game related archive types, but noticably also ZIP and 7z (!) support.
Anyway, I just more or less finished the wrapper and Ogre integration part and thought I'd share it here in case someone else wants to use PhysFS for his project. The C++ wrapper is pretty straight-forward, most of the PhysFS functions are simply wrapped in a more C++ like way, i. e. the PHYSFS_ function prefix becomes PhysFS namespace, all char* parameters become strings and all lists become vectors of strings. The PHYSFS_File structure is wrapped by a C++ stream (PhysFS::FileStream), that one behaves pretty much like std::fstream, so should feel more or less natural.
Example:
Code: Select all
#include "PhysFS++.h"
int main(int argc, char** argv)
{
// init PhysFS system
PhysFS::init(argv[0]);
// add the program's base directory to the search path
PhysFS::addToSearchPath(PhysFS::getBaseDir());
// set the program's base directory as the write dir
PhysFS::setWriteDir(PhysFS::getBaseDir());
// create some text file and write to it
PhysFS::FileStream stream ("test.txt", PhysFS::OM_WRITE);
stream << "Just a standard stream: " << 12345 << "\n";
stream.close();
// shutdown PhysFS
PhysFS::deinit();
}
The Ogre integration is also very simple, the only thing you have to do is to #include "PhysFSOgre.h" and call PhysFS::registerPhysFSToOgre() after you have initialised both PhysFS and Ogre. That's it, you can then add resource locations to the ResourceGroupManager of type "PhysFS"
Here's the code: click
Consider it public domain. But I haven't yet tested it very thoroughly, so don't blame me If you have suggestions or improvements, post them here.
The code depends on PhysFS (go figure) and boost::iostreams for the wrapper, and naturally Ogre if you're using the Ogre integration.