FileSystem: Allow ::openReadRaw() to break out of game directory
If PhysFS fails to open a path, fall back to simple FILE* handles. Not sure yet if this is a good idea, but from observation RMXP allows load_data() to operate on paths outside the game directory as well, so we have to support this.
This commit is contained in:
parent
7938a07539
commit
d45a400227
|
@ -33,7 +33,6 @@ fileIntFreeInstance(void *inst)
|
||||||
{
|
{
|
||||||
SDL_RWops *ops = static_cast<SDL_RWops*>(inst);
|
SDL_RWops *ops = static_cast<SDL_RWops*>(inst);
|
||||||
|
|
||||||
SDL_RWclose(ops);
|
|
||||||
SDL_FreeRW(ops);
|
SDL_FreeRW(ops);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,16 +41,14 @@ DEF_TYPE_CUSTOMFREE(FileInt, fileIntFreeInstance);
|
||||||
static VALUE
|
static VALUE
|
||||||
fileIntForPath(const char *path, bool rubyExc)
|
fileIntForPath(const char *path, bool rubyExc)
|
||||||
{
|
{
|
||||||
SDL_RWops *ops = SDL_AllocRW();
|
SDL_RWops *ops;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
shState->fileSystem().openReadRaw(*ops, path);
|
ops = shState->fileSystem().openReadRaw(path);
|
||||||
}
|
}
|
||||||
catch (const Exception &e)
|
catch (const Exception &e)
|
||||||
{
|
{
|
||||||
SDL_FreeRW(ops);
|
|
||||||
|
|
||||||
if (rubyExc)
|
if (rubyExc)
|
||||||
raiseRbExc(e);
|
raiseRbExc(e);
|
||||||
else
|
else
|
||||||
|
|
|
@ -273,23 +273,23 @@ runRMXPScripts(mrb_state *mrb, mrbc_context *ctx)
|
||||||
|
|
||||||
/* We use a secondary util state to unmarshal the scripts */
|
/* We use a secondary util state to unmarshal the scripts */
|
||||||
mrb_state *scriptMrb = mrb_open();
|
mrb_state *scriptMrb = mrb_open();
|
||||||
SDL_RWops ops;
|
|
||||||
|
|
||||||
shState->fileSystem().openReadRaw(ops, scriptPack.c_str());
|
SDL_RWops *ops = shState->fileSystem().openReadRaw(scriptPack.c_str());
|
||||||
|
|
||||||
mrb_value scriptArray = mrb_nil_value();
|
mrb_value scriptArray = mrb_nil_value();
|
||||||
std::string readError;
|
std::string readError;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
scriptArray = marshalLoadInt(scriptMrb, &ops);
|
scriptArray = marshalLoadInt(scriptMrb, ops);
|
||||||
}
|
}
|
||||||
catch (const Exception &e)
|
catch (const Exception &e)
|
||||||
{
|
{
|
||||||
readError = std::string(": ") + e.msg;
|
readError = std::string(": ") + e.msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_RWclose(&ops);
|
SDL_RWclose(ops);
|
||||||
|
SDL_FreeRW(ops);
|
||||||
|
|
||||||
if (!mrb_array_p(scriptArray))
|
if (!mrb_array_p(scriptArray))
|
||||||
{
|
{
|
||||||
|
|
|
@ -222,15 +222,6 @@ static int SDL_RWopsClose(SDL_RWops *ops)
|
||||||
return (result != 0) ? 0 : -1;
|
return (result != 0) ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int SDL_RWopsCloseFree(SDL_RWops *ops)
|
|
||||||
{
|
|
||||||
int result = SDL_RWopsClose(ops);
|
|
||||||
|
|
||||||
SDL_FreeRW(ops);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copies the first srcN characters from src into dst,
|
/* Copies the first srcN characters from src into dst,
|
||||||
* or the full string if srcN == -1. Never writes more
|
* or the full string if srcN == -1. Never writes more
|
||||||
* than dstMax, and guarantees dst to be null terminated.
|
* than dstMax, and guarantees dst to be null terminated.
|
||||||
|
@ -272,18 +263,13 @@ findExt(const char *filename)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
initReadOps(PHYSFS_File *handle,
|
initReadOps(PHYSFS_File *handle,
|
||||||
SDL_RWops &ops,
|
SDL_RWops &ops)
|
||||||
bool freeOnClose)
|
|
||||||
{
|
{
|
||||||
ops.size = SDL_RWopsSize;
|
ops.size = SDL_RWopsSize;
|
||||||
ops.seek = SDL_RWopsSeek;
|
ops.seek = SDL_RWopsSeek;
|
||||||
ops.read = SDL_RWopsRead;
|
ops.read = SDL_RWopsRead;
|
||||||
ops.write = SDL_RWopsWrite;
|
ops.write = SDL_RWopsWrite;
|
||||||
|
ops.close = SDL_RWopsClose;
|
||||||
if (freeOnClose)
|
|
||||||
ops.close = SDL_RWopsCloseFree;
|
|
||||||
else
|
|
||||||
ops.close = SDL_RWopsClose;
|
|
||||||
|
|
||||||
ops.type = SDL_RWOPS_PHYSFS;
|
ops.type = SDL_RWOPS_PHYSFS;
|
||||||
ops.hidden.unknown.data1 = handle;
|
ops.hidden.unknown.data1 = handle;
|
||||||
|
@ -504,7 +490,7 @@ fontSetEnumCB (void *data, const char *dir, const char *fname)
|
||||||
return PHYSFS_ENUM_ERROR;
|
return PHYSFS_ENUM_ERROR;
|
||||||
|
|
||||||
SDL_RWops ops;
|
SDL_RWops ops;
|
||||||
initReadOps(handle, ops, false);
|
initReadOps(handle, ops);
|
||||||
|
|
||||||
d->sfs->initFontSetCB(ops, filename);
|
d->sfs->initFontSetCB(ops, filename);
|
||||||
|
|
||||||
|
@ -620,7 +606,7 @@ openReadEnumCB(void *d, const char *dirpath, const char *filename)
|
||||||
return PHYSFS_ENUM_ERROR;
|
return PHYSFS_ENUM_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
initReadOps(phys, data.ops, false);
|
initReadOps(phys, data.ops);
|
||||||
|
|
||||||
const char *ext = findExt(filename);
|
const char *ext = findExt(filename);
|
||||||
|
|
||||||
|
@ -684,14 +670,27 @@ void FileSystem::openRead(OpenHandler &handler, const char *filename)
|
||||||
throw Exception(Exception::NoFileError, "%s", filename);
|
throw Exception(Exception::NoFileError, "%s", filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileSystem::openReadRaw(SDL_RWops &ops,
|
SDL_RWops *FileSystem::openReadRaw(const char *filename)
|
||||||
const char *filename,
|
|
||||||
bool freeOnClose)
|
|
||||||
{
|
{
|
||||||
PHYSFS_File *handle = PHYSFS_openRead(filename);
|
SDL_RWops *ops;
|
||||||
assert(handle);
|
|
||||||
|
|
||||||
initReadOps(handle, ops, freeOnClose);
|
PHYSFS_File *handle = PHYSFS_openRead(filename);
|
||||||
|
if (!handle) {
|
||||||
|
Debug() << "Couldn't open " << filename << " via PhysFS; trying normal FILE*";
|
||||||
|
ops = SDL_RWFromFile(filename, "rb");
|
||||||
|
|
||||||
|
if (!ops) {
|
||||||
|
Debug() << "FILE* path failed too..";
|
||||||
|
throw Exception(Exception::NoFileError, "%s", filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ops = SDL_AllocRW();
|
||||||
|
initReadOps(handle, *ops);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ops;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileSystem::exists(const char *filename)
|
bool FileSystem::exists(const char *filename)
|
||||||
|
|
|
@ -60,9 +60,7 @@ public:
|
||||||
const char *filename);
|
const char *filename);
|
||||||
|
|
||||||
/* Circumvents extension supplementing */
|
/* Circumvents extension supplementing */
|
||||||
void openReadRaw(SDL_RWops &ops,
|
SDL_RWops *openReadRaw(const char *filename);
|
||||||
const char *filename,
|
|
||||||
bool freeOnClose = false);
|
|
||||||
|
|
||||||
/* Does not perform extension supplementing */
|
/* Does not perform extension supplementing */
|
||||||
bool exists(const char *filename);
|
bool exists(const char *filename);
|
||||||
|
|
|
@ -167,14 +167,13 @@ _TTF_Font *SharedFontState::getFont(std::string family,
|
||||||
const char *path = !req.regular.empty()
|
const char *path = !req.regular.empty()
|
||||||
? req.regular.c_str() : req.other.c_str();
|
? req.regular.c_str() : req.other.c_str();
|
||||||
|
|
||||||
ops = SDL_AllocRW();
|
ops = shState->fileSystem().openReadRaw(path);
|
||||||
shState->fileSystem().openReadRaw(*ops, path, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME 0.9 is guesswork at this point
|
// FIXME 0.9 is guesswork at this point
|
||||||
// float gamma = (96.0/45.0)*(5.0/14.0)*(size-5);
|
// float gamma = (96.0/45.0)*(5.0/14.0)*(size-5);
|
||||||
// font = TTF_OpenFontRW(ops, 1, gamma /** .90*/);
|
// font = TTF_OpenFontRW(ops, 0, gamma /** .90*/);
|
||||||
font = TTF_OpenFontRW(ops, 1, size* 0.90f);
|
font = TTF_OpenFontRW(ops, 0, size* 0.90f);
|
||||||
|
|
||||||
if (!font)
|
if (!font)
|
||||||
throw Exception(Exception::SDLError, "%s", SDL_GetError());
|
throw Exception(Exception::SDLError, "%s", SDL_GetError());
|
||||||
|
|
Loading…
Reference in New Issue