diff --git a/.gitignore b/.gitignore index ce3a06d2d1..86e02e32ae 100644 --- a/.gitignore +++ b/.gitignore @@ -46,5 +46,6 @@ __testfailure.bmp GameLogNotes.txt android/ui_atlas.zim +android/assets/flash0 ppge_atlas.zim.png local.properties diff --git a/Core/FileSystems/DirectoryFileSystem.cpp b/Core/FileSystems/DirectoryFileSystem.cpp index 00a163fc5c..6938ed4fe0 100644 --- a/Core/FileSystems/DirectoryFileSystem.cpp +++ b/Core/FileSystems/DirectoryFileSystem.cpp @@ -18,7 +18,7 @@ #include "ChunkFile.h" #include "FileUtil.h" #include "DirectoryFileSystem.h" - +#include "file/zip_read.h" #ifdef _WIN32 #include @@ -595,3 +595,153 @@ void DirectoryFileSystem::DoState(PointerWrap &p) { ERROR_LOG(FILESYS, "FIXME: Open files during savestate, could go badly."); } } + + +VFSFileSystem::VFSFileSystem(IHandleAllocator *_hAlloc, std::string _basePath) : basePath(_basePath) { + INFO_LOG(HLE, "Creating VFS file system"); + hAlloc = _hAlloc; +} + +VFSFileSystem::~VFSFileSystem() { + for (auto iter = entries.begin(); iter != entries.end(); ++iter) { + delete [] iter->second.fileData; + } + entries.clear(); +} + +std::string VFSFileSystem::GetLocalPath(std::string localPath) { + return basePath + localPath; +} + +bool VFSFileSystem::MkDir(const std::string &dirname) { + // NOT SUPPORTED - READ ONLY + return false; +} + +bool VFSFileSystem::RmDir(const std::string &dirname) { + // NOT SUPPORTED - READ ONLY + return false; +} + +bool VFSFileSystem::RenameFile(const std::string &from, const std::string &to) { + // NOT SUPPORTED - READ ONLY + return false; +} + +bool VFSFileSystem::RemoveFile(const std::string &filename) { + // NOT SUPPORTED - READ ONLY + return false; +} + +u32 VFSFileSystem::OpenFile(std::string filename, FileAccess access) { + if (access != FILEACCESS_READ) { + ERROR_LOG(HLE, "VFSFileSystem only supports plain reading"); + return 0; + } + + std::string fullName = GetLocalPath(filename); + const char *fullNameC = fullName.c_str(); + INFO_LOG(HLE,"VFSFileSystem actually opening %s (%s)", fullNameC, filename.c_str()); + + size_t size; + u8 *data = VFSReadFile(fullNameC, &size); + if (!data) { + ERROR_LOG(HLE, "VFSFileSystem failed to open %s", filename.c_str()); + return 0; + } + + OpenFileEntry entry; + entry.fileData = data; + entry.size = size; + entry.seekPos = 0; + u32 newHandle = hAlloc->GetNewHandle(); + entries[newHandle] = entry; + return newHandle; +} + +PSPFileInfo VFSFileSystem::GetFileInfo(std::string filename) { + PSPFileInfo x; + x.name = filename; + + std::string fullName = GetLocalPath(filename); + INFO_LOG(HLE,"Getting VFS file info %s (%s)", fullName.c_str(), filename.c_str()); + FileInfo fo; + VFSGetFileInfo(fullName.c_str(), &fo); + x.exists = fo.exists; + if (x.exists) { + x.size = fo.size; + x.type = fo.isDirectory ? FILETYPE_DIRECTORY : FILETYPE_NORMAL; + } + INFO_LOG(HLE,"Got VFS file info: size = %i", (int)x.size); + return x; +} + +void VFSFileSystem::CloseFile(u32 handle) { + EntryMap::iterator iter = entries.find(handle); + if (iter != entries.end()) { + delete [] iter->second.fileData; + entries.erase(iter); + } else { + //This shouldn't happen... + ERROR_LOG(HLE,"Cannot close file that hasn't been opened: %08x", handle); + } +} + +bool VFSFileSystem::OwnsHandle(u32 handle) { + EntryMap::iterator iter = entries.find(handle); + return (iter != entries.end()); +} + +size_t VFSFileSystem::ReadFile(u32 handle, u8 *pointer, s64 size) { + INFO_LOG(HLE,"VFSFileSystem::ReadFile %08x %p %i", handle, pointer, (u32)size); + EntryMap::iterator iter = entries.find(handle); + if (iter != entries.end()) + { + size_t bytesRead = size; + memcpy(pointer, iter->second.fileData + iter->second.seekPos, size); + iter->second.seekPos += size; + return bytesRead; + } else { + ERROR_LOG(HLE,"Cannot read file that hasn't been opened: %08x", handle); + return 0; + } +} + +size_t VFSFileSystem::WriteFile(u32 handle, const u8 *pointer, s64 size) { + // NOT SUPPORTED - READ ONLY + return 0; +} + +size_t VFSFileSystem::SeekFile(u32 handle, s32 position, FileMove type) { + EntryMap::iterator iter = entries.find(handle); + if (iter != entries.end()) { + switch (type) { + case FILEMOVE_BEGIN: iter->second.seekPos = position; break; + case FILEMOVE_CURRENT: iter->second.seekPos += position; break; + case FILEMOVE_END: iter->second.seekPos = iter->second.size + position; break; + } + return iter->second.seekPos; + } else { + //This shouldn't happen... + ERROR_LOG(HLE,"Cannot seek in file that hasn't been opened: %08x", handle); + return 0; + } +} + + +bool VFSFileSystem::GetHostPath(const std::string &inpath, std::string &outpath) { + // NOT SUPPORTED + return false; +} + +std::vector VFSFileSystem::GetDirListing(std::string path) { + std::vector myVector; + // TODO + return myVector; +} + +void VFSFileSystem::DoState(PointerWrap &p) { + if (!entries.empty()) { + ERROR_LOG(FILESYS, "FIXME: Open files during savestate, could go badly."); + } +} diff --git a/Core/FileSystems/DirectoryFileSystem.h b/Core/FileSystems/DirectoryFileSystem.h index 61ee605406..1ee0ac474a 100644 --- a/Core/FileSystems/DirectoryFileSystem.h +++ b/Core/FileSystems/DirectoryFileSystem.h @@ -95,3 +95,41 @@ private: bool FixPathCase(std::string &path, FixPathCaseBehavior behavior); #endif }; + +// VFSFileSystem: Ability to map in Android APK paths as well! Does not support all features, only meant for fonts. +// Very inefficient - always load the whole file on open. +class VFSFileSystem : public IFileSystem { +public: + VFSFileSystem(IHandleAllocator *_hAlloc, std::string _basePath); + ~VFSFileSystem(); + + void DoState(PointerWrap &p); + std::vector GetDirListing(std::string path); + u32 OpenFile(std::string filename, FileAccess access); + void CloseFile(u32 handle); + size_t ReadFile(u32 handle, u8 *pointer, s64 size); + size_t WriteFile(u32 handle, const u8 *pointer, s64 size); + size_t SeekFile(u32 handle, s32 position, FileMove type); + PSPFileInfo GetFileInfo(std::string filename); + bool OwnsHandle(u32 handle); + + bool MkDir(const std::string &dirname); + bool RmDir(const std::string &dirname); + bool RenameFile(const std::string &from, const std::string &to); + bool RemoveFile(const std::string &filename); + bool GetHostPath(const std::string &inpath, std::string &outpath); + +private: + struct OpenFileEntry { + u8 *fileData; + size_t size; + size_t seekPos; + }; + + typedef std::map EntryMap; + EntryMap entries; + std::string basePath; + IHandleAllocator *hAlloc; + + std::string GetLocalPath(std::string localpath); +}; diff --git a/Core/HLE/sceFont.cpp b/Core/HLE/sceFont.cpp index c33032a3a0..f9ccf1d3d8 100644 --- a/Core/HLE/sceFont.cpp +++ b/Core/HLE/sceFont.cpp @@ -178,6 +178,13 @@ private: class FontLib; +// These should not need to be state saved. +static std::vector internalFonts; +// However, these we must save - but we could take a shortcut +// for LoadedFonts that point to internal fonts. +static std::map fontMap; +static std::map fontLibMap; + class PostAllocCallback : public Action { public: PostAllocCallback() {} @@ -222,8 +229,17 @@ public: } void Done() { + for (size_t i = 0; i < fonts_.size(); i++) { + if (Memory::Read_U32(fonts_[i]) == FONT_IS_OPEN) { + fontMap[fonts_[i]]->Close(); + delete fontMap[fonts_[i]]; + fontMap.erase(fonts_[i]); + } + } u32 args[1] = { handle_ }; __KernelDirectMipsCall(params_.freeFuncAddr, 0, args, 1, false); + handle_ = 0; + fonts_.clear(); } void AllocDone(u32 allocatedAddr) { @@ -274,6 +290,7 @@ public: for (size_t i = 0; i < fonts_.size(); i++) { if (fonts_[i] == font->Handle()) { Memory::Write_U32(FONT_IS_CLOSED, font->Handle()); + } } font->Close(); @@ -296,7 +313,7 @@ public: u32 GetAltCharCode() const { return altCharCode_; } private: - std::vector fonts_; + std::vector fonts_; FontNewLibParams params_; float fontHRes_; @@ -308,18 +325,13 @@ private: }; -// These should not need to be state saved. -static std::vector internalFonts; -// However, these we must save - but we could take a shortcut -// for LoadedFonts that point to internal fonts. -static std::map fontMap; -static std::map fontLibMap; - void PostAllocCallback::run(MipsCall &call) { + INFO_LOG(HLE, "Entering PostAllocCallback::run"); u32 v0 = currentMIPS->r[0]; fontLib_->AllocDone(call.savedV0); fontLibMap[fontLib_->handle()] = fontLib_; call.setReturnValue(fontLib_->handle()); + INFO_LOG(HLE, "Leaving PostAllocCallback::run"); } void PostOpenCallback::run(MipsCall &call) { @@ -357,8 +369,14 @@ void __LoadInternalFonts() { std::string fontFilename = fontPath + entry.fileName; PSPFileInfo info = pspFileSystem.GetFileInfo(fontFilename); if (info.exists) { + INFO_LOG(HLE, "Loading font %s (%i bytes)", fontFilename.c_str(), (int)info.size); u8 *buffer = new u8[(size_t)info.size]; u32 handle = pspFileSystem.OpenFile(fontFilename, FILEACCESS_READ); + if (!handle) { + ERROR_LOG(HLE, "Failed opening font"); + delete [] buffer; + continue; + } pspFileSystem.ReadFile(handle, buffer, info.size); pspFileSystem.CloseFile(handle); diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 3e076e02b8..d1003f5db1 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -220,13 +220,15 @@ void __IoInit() { DirectoryFileSystem *memstick = new DirectoryFileSystem(&pspFileSystem, memstickpath); +#ifdef ANDROID + VFSFileSystem *flash0 = new VFSFileSystem(&pspFileSystem, "flash0"); +#else DirectoryFileSystem *flash0 = new DirectoryFileSystem(&pspFileSystem, flash0path); - DirectoryFileSystem *flash1 = new DirectoryFileSystem(&pspFileSystem, flash0path); +#endif pspFileSystem.Mount("ms0:", memstick); pspFileSystem.Mount("fatms0:", memstick); pspFileSystem.Mount("fatms:", memstick); pspFileSystem.Mount("flash0:", flash0); - pspFileSystem.Mount("flash1:", flash1); __KernelListenThreadEnd(&TellFsThreadEnded); } diff --git a/android/ab.cmd b/android/ab.cmd index a3ca5c5b51..36eecad802 100644 --- a/android/ab.cmd +++ b/android/ab.cmd @@ -1,3 +1,4 @@ +xcopy ..\flash0 assets\flash0 /s /y SET NDK=C:\AndroidNDK SET NDK_MODULE_PATH=..;..\native\ext REM Need to force target-platform to android-9 to get access to OpenSL headers. diff --git a/android/ab.sh b/android/ab.sh index 6190b3e541..cf79aab3bc 100755 --- a/android/ab.sh +++ b/android/ab.sh @@ -1 +1,2 @@ +cp -r ../flash0 assets NDK_MODULE_PATH=..:../native/ext $NDK/ndk-build -j3 TARGET_PLATFORM=android-9 $* diff --git a/native b/native index 17c8eb1ae7..3f6353af5a 160000 --- a/native +++ b/native @@ -1 +1 @@ -Subproject commit 17c8eb1ae7ca285a4228bac56059ca441b53ba6f +Subproject commit 3f6353af5afe1542a50c33eb0bb554ea25653258