mirror of
https://github.com/libretro/ppsspp.git
synced 2025-02-16 15:08:34 +00:00
Implement per-thread current directory
This commit is contained in:
parent
2f394fb7ed
commit
320c0d06c3
@ -17,6 +17,7 @@
|
||||
|
||||
#include <set>
|
||||
#include "Common/StringUtil.h"
|
||||
#include "../HLE/sceKernelThread.h"
|
||||
#include "MetaFileSystem.h"
|
||||
|
||||
static bool ApplyPathStringToComponentsVector(std::vector<std::string> &vector, const std::string &pathString)
|
||||
@ -163,7 +164,6 @@ IFileSystem *MetaFileSystem::GetHandleOwner(u32 handle)
|
||||
|
||||
bool MetaFileSystem::MapFilePath(const std::string &_inpath, std::string &outpath, IFileSystem **system)
|
||||
{
|
||||
//TODO: implement current directory per thread (NOT per drive)
|
||||
std::string realpath;
|
||||
|
||||
// Special handling: host0:command.txt (as seen in Super Monkey Ball Adventures, for example)
|
||||
@ -174,7 +174,22 @@ bool MetaFileSystem::MapFilePath(const std::string &_inpath, std::string &outpat
|
||||
inpath = inpath.substr(6);
|
||||
}
|
||||
|
||||
if ( RealPath(currentDirectory, inpath, realpath) )
|
||||
const std::string *currentDirectory = &startingDirectory;
|
||||
|
||||
int currentThread = __KernelGetCurThread();
|
||||
currentDir_t::iterator i = currentDir.find(currentThread);
|
||||
if (i == currentDir.end())
|
||||
{
|
||||
//TODO: emulate PSP's error 8002032C: "no current working directory" if relative... may break things requiring fixes elsewhere
|
||||
if (inpath.find(':') == std::string::npos /* means path is relative */)
|
||||
WARN_LOG(HLE, "Path is relative, but current directory not set for thread %i. Should give error, instead falling back to %s", currentThread, startingDirectory.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
currentDirectory = &(i->second);
|
||||
}
|
||||
|
||||
if ( RealPath(*currentDirectory, inpath, realpath) )
|
||||
{
|
||||
for (size_t i = 0; i < fileSystems.size(); i++)
|
||||
{
|
||||
@ -203,7 +218,7 @@ void MetaFileSystem::Mount(std::string prefix, IFileSystem *system)
|
||||
fileSystems.push_back(x);
|
||||
}
|
||||
|
||||
void MetaFileSystem::UnmountAll()
|
||||
void MetaFileSystem::Shutdown()
|
||||
{
|
||||
current = 6;
|
||||
|
||||
@ -220,7 +235,8 @@ void MetaFileSystem::UnmountAll()
|
||||
}
|
||||
|
||||
fileSystems.clear();
|
||||
currentDirectory = "";
|
||||
currentDir.clear();
|
||||
startingDirectory = "";
|
||||
}
|
||||
|
||||
u32 MetaFileSystem::OpenFile(std::string filename, FileAccess access)
|
||||
@ -278,6 +294,19 @@ std::vector<PSPFileInfo> MetaFileSystem::GetDirListing(std::string path)
|
||||
}
|
||||
}
|
||||
|
||||
void MetaFileSystem::ThreadEnded(int threadID)
|
||||
{
|
||||
currentDir.erase(threadID);
|
||||
}
|
||||
|
||||
void MetaFileSystem::ChDir(const std::string &dir)
|
||||
{
|
||||
//TODO: test sceIoChdir("..") on PSP - maybe we should map it before saving it?
|
||||
|
||||
int curThread = __KernelGetCurThread();
|
||||
currentDir[curThread] = dir;
|
||||
}
|
||||
|
||||
bool MetaFileSystem::MkDir(const std::string &dirname)
|
||||
{
|
||||
std::string of;
|
||||
@ -372,9 +401,34 @@ size_t MetaFileSystem::SeekFile(u32 handle, s32 position, FileMove type)
|
||||
void MetaFileSystem::DoState(PointerWrap &p)
|
||||
{
|
||||
p.Do(current);
|
||||
p.Do(currentDirectory);
|
||||
|
||||
int n = (int) fileSystems.size();
|
||||
// Save/load per-thread current directory map
|
||||
u32 n = (u32) currentDir.size();
|
||||
p.Do(n);
|
||||
if (p.mode == p.MODE_READ)
|
||||
{
|
||||
std::string dir;
|
||||
currentDir.clear();
|
||||
for (u32 i = 0; i < n; ++i)
|
||||
{
|
||||
int threadID;
|
||||
p.Do(threadID);
|
||||
p.Do(dir);
|
||||
|
||||
currentDir[threadID] = dir;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
currentDir_t::iterator i = currentDir.begin(), end = currentDir.end();
|
||||
for (; i != end; ++i)
|
||||
{
|
||||
p.Do(i->first);
|
||||
p.Do(i->second);
|
||||
}
|
||||
}
|
||||
|
||||
n = (u32) fileSystems.size();
|
||||
p.Do(n);
|
||||
if (n != fileSystems.size())
|
||||
{
|
||||
@ -382,7 +436,7 @@ void MetaFileSystem::DoState(PointerWrap &p)
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < n; ++i)
|
||||
for (u32 i = 0; i < n; ++i)
|
||||
fileSystems[i].system->DoState(p);
|
||||
|
||||
p.DoMarker("MetaFileSystem");
|
||||
|
@ -30,8 +30,9 @@ public:
|
||||
void Mount(std::string prefix, IFileSystem *system);
|
||||
void Unmount(IFileSystem *system);
|
||||
|
||||
// Effectively "Shutdown".
|
||||
void UnmountAll();
|
||||
void ThreadEnded(int threadID);
|
||||
|
||||
void Shutdown();
|
||||
|
||||
u32 GetNewHandle() {return current++;}
|
||||
void FreeHandle(u32 handle) {}
|
||||
@ -57,7 +58,7 @@ public:
|
||||
return SeekFile(handle, 0, FILEMOVE_CURRENT);
|
||||
}
|
||||
|
||||
virtual void ChDir(std::string dir) {currentDirectory = dir;}
|
||||
virtual void ChDir(const std::string &dir);
|
||||
|
||||
virtual bool MkDir(const std::string &dirname);
|
||||
virtual bool RmDir(const std::string &dirname);
|
||||
@ -66,8 +67,8 @@ public:
|
||||
|
||||
// TODO: void IoCtl(...)
|
||||
|
||||
void SetCurrentDirectory(const std::string &dir) {
|
||||
currentDirectory = dir;
|
||||
void SetStartingDirectory(const std::string &dir) {
|
||||
startingDirectory = dir;
|
||||
}
|
||||
private:
|
||||
u32 current;
|
||||
@ -78,5 +79,8 @@ private:
|
||||
};
|
||||
std::vector<System> fileSystems;
|
||||
|
||||
std::string currentDirectory;
|
||||
typedef std::map<int, std::string> currentDir_t;
|
||||
currentDir_t currentDir;
|
||||
|
||||
std::string startingDirectory;
|
||||
};
|
||||
|
@ -159,6 +159,10 @@ public:
|
||||
PSPFileInfo info;
|
||||
};
|
||||
|
||||
void TellFsThreadEnded (SceUID threadID) {
|
||||
pspFileSystem.ThreadEnded(threadID);
|
||||
}
|
||||
|
||||
void __IoInit() {
|
||||
INFO_LOG(HLE, "Starting up I/O...");
|
||||
|
||||
@ -199,6 +203,8 @@ void __IoInit() {
|
||||
pspFileSystem.Mount("fatms:", memstick);
|
||||
pspFileSystem.Mount("flash0:", flash);
|
||||
pspFileSystem.Mount("flash1:", flash);
|
||||
|
||||
__KernelListenThreadEnd(&TellFsThreadEnded);
|
||||
}
|
||||
|
||||
void __IoDoState(PointerWrap &p) {
|
||||
|
@ -92,11 +92,11 @@ bool LoadFile(const char *filename, std::string *error_string)
|
||||
// If loading from memstick...
|
||||
size_t pos = path.find("/PSP/GAME/");
|
||||
if (pos != std::string::npos)
|
||||
pspFileSystem.SetCurrentDirectory("ms0:" + path.substr(pos));
|
||||
pspFileSystem.SetStartingDirectory("ms0:" + path.substr(pos));
|
||||
return Load_PSP_ELF_PBP(filename, error_string);
|
||||
}
|
||||
case FILETYPE_PSP_ISO:
|
||||
pspFileSystem.SetCurrentDirectory("disc0:/PSP_GAME/USRDIR");
|
||||
pspFileSystem.SetStartingDirectory("disc0:/PSP_GAME/USRDIR");
|
||||
return Load_PSP_ISO(filename, error_string);
|
||||
case FILETYPE_ERROR:
|
||||
ERROR_LOG(LOADER, "Could not file");
|
||||
|
@ -64,7 +64,7 @@ bool PSP_Init(const CoreParameter &coreParam, std::string *error_string)
|
||||
|
||||
if (!LoadFile(coreParameter.fileToStart.c_str(), error_string))
|
||||
{
|
||||
pspFileSystem.UnmountAll();
|
||||
pspFileSystem.Shutdown();
|
||||
CoreTiming::ClearPendingEvents();
|
||||
CoreTiming::UnregisterAllEvents();
|
||||
__KernelShutdown();
|
||||
@ -90,7 +90,7 @@ bool PSP_IsInited()
|
||||
|
||||
void PSP_Shutdown()
|
||||
{
|
||||
pspFileSystem.UnmountAll();
|
||||
pspFileSystem.Shutdown();
|
||||
|
||||
TextureCache_Clear(true);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user