mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Implement per-thread current directory
This commit is contained in:
parent
2f394fb7ed
commit
320c0d06c3
5 changed files with 81 additions and 17 deletions
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
#include "Common/StringUtil.h"
|
#include "Common/StringUtil.h"
|
||||||
|
#include "../HLE/sceKernelThread.h"
|
||||||
#include "MetaFileSystem.h"
|
#include "MetaFileSystem.h"
|
||||||
|
|
||||||
static bool ApplyPathStringToComponentsVector(std::vector<std::string> &vector, const std::string &pathString)
|
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)
|
bool MetaFileSystem::MapFilePath(const std::string &_inpath, std::string &outpath, IFileSystem **system)
|
||||||
{
|
{
|
||||||
//TODO: implement current directory per thread (NOT per drive)
|
|
||||||
std::string realpath;
|
std::string realpath;
|
||||||
|
|
||||||
// Special handling: host0:command.txt (as seen in Super Monkey Ball Adventures, for example)
|
// 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);
|
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++)
|
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);
|
fileSystems.push_back(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetaFileSystem::UnmountAll()
|
void MetaFileSystem::Shutdown()
|
||||||
{
|
{
|
||||||
current = 6;
|
current = 6;
|
||||||
|
|
||||||
|
@ -220,7 +235,8 @@ void MetaFileSystem::UnmountAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
fileSystems.clear();
|
fileSystems.clear();
|
||||||
currentDirectory = "";
|
currentDir.clear();
|
||||||
|
startingDirectory = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 MetaFileSystem::OpenFile(std::string filename, FileAccess access)
|
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)
|
bool MetaFileSystem::MkDir(const std::string &dirname)
|
||||||
{
|
{
|
||||||
std::string of;
|
std::string of;
|
||||||
|
@ -372,9 +401,34 @@ size_t MetaFileSystem::SeekFile(u32 handle, s32 position, FileMove type)
|
||||||
void MetaFileSystem::DoState(PointerWrap &p)
|
void MetaFileSystem::DoState(PointerWrap &p)
|
||||||
{
|
{
|
||||||
p.Do(current);
|
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);
|
p.Do(n);
|
||||||
if (n != fileSystems.size())
|
if (n != fileSystems.size())
|
||||||
{
|
{
|
||||||
|
@ -382,7 +436,7 @@ void MetaFileSystem::DoState(PointerWrap &p)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < n; ++i)
|
for (u32 i = 0; i < n; ++i)
|
||||||
fileSystems[i].system->DoState(p);
|
fileSystems[i].system->DoState(p);
|
||||||
|
|
||||||
p.DoMarker("MetaFileSystem");
|
p.DoMarker("MetaFileSystem");
|
||||||
|
|
|
@ -30,8 +30,9 @@ public:
|
||||||
void Mount(std::string prefix, IFileSystem *system);
|
void Mount(std::string prefix, IFileSystem *system);
|
||||||
void Unmount(IFileSystem *system);
|
void Unmount(IFileSystem *system);
|
||||||
|
|
||||||
// Effectively "Shutdown".
|
void ThreadEnded(int threadID);
|
||||||
void UnmountAll();
|
|
||||||
|
void Shutdown();
|
||||||
|
|
||||||
u32 GetNewHandle() {return current++;}
|
u32 GetNewHandle() {return current++;}
|
||||||
void FreeHandle(u32 handle) {}
|
void FreeHandle(u32 handle) {}
|
||||||
|
@ -57,7 +58,7 @@ public:
|
||||||
return SeekFile(handle, 0, FILEMOVE_CURRENT);
|
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 MkDir(const std::string &dirname);
|
||||||
virtual bool RmDir(const std::string &dirname);
|
virtual bool RmDir(const std::string &dirname);
|
||||||
|
@ -66,8 +67,8 @@ public:
|
||||||
|
|
||||||
// TODO: void IoCtl(...)
|
// TODO: void IoCtl(...)
|
||||||
|
|
||||||
void SetCurrentDirectory(const std::string &dir) {
|
void SetStartingDirectory(const std::string &dir) {
|
||||||
currentDirectory = dir;
|
startingDirectory = dir;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
u32 current;
|
u32 current;
|
||||||
|
@ -78,5 +79,8 @@ private:
|
||||||
};
|
};
|
||||||
std::vector<System> fileSystems;
|
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;
|
PSPFileInfo info;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void TellFsThreadEnded (SceUID threadID) {
|
||||||
|
pspFileSystem.ThreadEnded(threadID);
|
||||||
|
}
|
||||||
|
|
||||||
void __IoInit() {
|
void __IoInit() {
|
||||||
INFO_LOG(HLE, "Starting up I/O...");
|
INFO_LOG(HLE, "Starting up I/O...");
|
||||||
|
|
||||||
|
@ -199,6 +203,8 @@ void __IoInit() {
|
||||||
pspFileSystem.Mount("fatms:", memstick);
|
pspFileSystem.Mount("fatms:", memstick);
|
||||||
pspFileSystem.Mount("flash0:", flash);
|
pspFileSystem.Mount("flash0:", flash);
|
||||||
pspFileSystem.Mount("flash1:", flash);
|
pspFileSystem.Mount("flash1:", flash);
|
||||||
|
|
||||||
|
__KernelListenThreadEnd(&TellFsThreadEnded);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __IoDoState(PointerWrap &p) {
|
void __IoDoState(PointerWrap &p) {
|
||||||
|
|
|
@ -92,11 +92,11 @@ bool LoadFile(const char *filename, std::string *error_string)
|
||||||
// If loading from memstick...
|
// If loading from memstick...
|
||||||
size_t pos = path.find("/PSP/GAME/");
|
size_t pos = path.find("/PSP/GAME/");
|
||||||
if (pos != std::string::npos)
|
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);
|
return Load_PSP_ELF_PBP(filename, error_string);
|
||||||
}
|
}
|
||||||
case FILETYPE_PSP_ISO:
|
case FILETYPE_PSP_ISO:
|
||||||
pspFileSystem.SetCurrentDirectory("disc0:/PSP_GAME/USRDIR");
|
pspFileSystem.SetStartingDirectory("disc0:/PSP_GAME/USRDIR");
|
||||||
return Load_PSP_ISO(filename, error_string);
|
return Load_PSP_ISO(filename, error_string);
|
||||||
case FILETYPE_ERROR:
|
case FILETYPE_ERROR:
|
||||||
ERROR_LOG(LOADER, "Could not file");
|
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))
|
if (!LoadFile(coreParameter.fileToStart.c_str(), error_string))
|
||||||
{
|
{
|
||||||
pspFileSystem.UnmountAll();
|
pspFileSystem.Shutdown();
|
||||||
CoreTiming::ClearPendingEvents();
|
CoreTiming::ClearPendingEvents();
|
||||||
CoreTiming::UnregisterAllEvents();
|
CoreTiming::UnregisterAllEvents();
|
||||||
__KernelShutdown();
|
__KernelShutdown();
|
||||||
|
@ -90,7 +90,7 @@ bool PSP_IsInited()
|
||||||
|
|
||||||
void PSP_Shutdown()
|
void PSP_Shutdown()
|
||||||
{
|
{
|
||||||
pspFileSystem.UnmountAll();
|
pspFileSystem.Shutdown();
|
||||||
|
|
||||||
TextureCache_Clear(true);
|
TextureCache_Clear(true);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue