diff --git a/UWP/PPSSPP_UWPMain.cpp b/UWP/PPSSPP_UWPMain.cpp index ead36b0743..e4ed18b8f2 100644 --- a/UWP/PPSSPP_UWPMain.cpp +++ b/UWP/PPSSPP_UWPMain.cpp @@ -32,7 +32,6 @@ #include "XAudioSoundStream.h" #include "UWPHost.h" #include "UWPUtil.h" -#include "StorageFileLoader.h" #include "App.h" using namespace UWP; @@ -304,11 +303,6 @@ void PPSSPP_UWPMain::OnSuspend() { // TODO } -void PPSSPP_UWPMain::LoadStorageFile(StorageFile ^file) { - std::unique_ptr factory(new StorageFileLoaderFactory(file, IdentifiedFileType::PSP_ISO)); - RegisterFileLoaderFactory("override://", std::move(factory)); - NativeMessageReceived("boot", "override://file"); -} UWPGraphicsContext::UWPGraphicsContext(std::shared_ptr resources) { std::vector adapterNames; @@ -457,13 +451,14 @@ void System_SendMessage(const char *command, const char *parameter) { picker->FileTypeFilter->Append(".iso"); // Can't load these this way currently, they require mounting the underlying folder. - // picker->FileTypeFilter->Append(".bin"); - // picker->FileTypeFilter->Append(".elf"); + picker->FileTypeFilter->Append(".bin"); + picker->FileTypeFilter->Append(".elf"); picker->SuggestedStartLocation = Pickers::PickerLocationId::DocumentsLibrary; create_task(picker->PickSingleFileAsync()).then([](StorageFile ^file){ if (file) { - g_main->LoadStorageFile(file); + std::string path = FromPlatformString(file->Path); + NativeMessageReceived("boot", path.c_str()); } }); } else if (!strcmp(command, "toggle_fullscreen")) { diff --git a/UWP/StorageFileLoader.cpp b/UWP/StorageFileLoader.cpp deleted file mode 100644 index 8e831a8787..0000000000 --- a/UWP/StorageFileLoader.cpp +++ /dev/null @@ -1,185 +0,0 @@ -#include "pch.h" -#include "ppltasks.h" - -#include "Common/Log.h" -#include "Common/File/FileUtil.h" -#include "Common/File/Path.h" -#include "Common/File/DirListing.h" -#include "Common/Thread/ThreadUtil.h" -#include "StorageFileLoader.h" -#include "Common/Log.h" -#include "UWPUtil.h" - -using namespace Concurrency; -using namespace Windows::Storage; -using namespace Windows::Storage::Streams; - -// Not sure how necessary this one is. -static std::mutex initMutex; - -StorageFileLoader::StorageFileLoader(Windows::Storage::StorageFile ^file) { - active_ = false; - file_ = file; - path_ = Path(FromPlatformString(file_->Path)); - thread_.reset(new std::thread([this]() { this->threadfunc(); })); - - // Before we proceed, we need to block until the thread has found the size. - // Hacky way: - while (size_ < 0) { - Sleep(10); - } -} - -StorageFileLoader::~StorageFileLoader() { - { - std::unique_lock lock(mutex_); - active_ = false; - operationRequested_ = false; - cond_.notify_one(); - } - thread_->join(); -} - -void StorageFileLoader::threadfunc() { - SetCurrentThreadName("StorageFileLoader"); - - { - std::unique_lock lock(initMutex); - _assert_(!active_); - auto opentask = create_task(file_->OpenReadAsync()).then([this](IRandomAccessStreamWithContentType ^stream) { - stream_ = stream; - active_ = true; - }); - - try { - opentask.wait(); - } catch (const std::exception& e) { - operationFailed_ = true; - // TODO: What do we do? - const char *what = e.what(); - INFO_LOG(SYSTEM, "%s", what); - } catch (Platform::COMException ^e) { - - } - - auto sizetask = create_task(file_->GetBasicPropertiesAsync()).then([this](Windows::Storage::FileProperties::BasicProperties ^props) { - size_ = props->Size; - }); - try { - sizetask.wait(); - } catch (const std::exception& e) { - const char *what = e.what(); - INFO_LOG(SYSTEM, "%s", what); - } catch (Platform::COMException ^e) { - std::string what = FromPlatformString(e->ToString()); - INFO_LOG(SYSTEM, "%s", what.c_str()); - } - } - - std::unique_lock lock(mutex_); - while (active_) { - if (!operationRequested_) { - cond_.wait(lock); - } - if (operationRequested_) { - switch (operation_.type) { - case OpType::READ_AT: { - Streams::Buffer ^buf = ref new Streams::Buffer((unsigned int)operation_.size); - operationFailed_ = false; - stream_->Seek(operation_.offset); - auto task = create_task(stream_->ReadAsync(buf, (unsigned int)operation_.size, Streams::InputStreamOptions::None)); - Streams::IBuffer ^output = nullptr; - try { - task.wait(); - output = task.get(); - } catch (const std::exception& e) { - operationFailed_ = true; - const char *what = e.what(); - INFO_LOG(SYSTEM, "%s", what); - } - std::unique_lock lock(mutexResponse_); - operationRequested_ = false; - response_.buffer = output; - responseAvailable_ = true; - condResponse_.notify_one(); - break; - } - default: - operationRequested_ = false; - break; - } - } - } -} - -bool StorageFileLoader::Exists() { - return file_ != nullptr; -} - -bool StorageFileLoader::ExistsFast() { - return file_ != nullptr; -} - -bool StorageFileLoader::IsDirectory() { - return (file_->Attributes & Windows::Storage::FileAttributes::Directory) != Windows::Storage::FileAttributes::Normal; -} - -s64 StorageFileLoader::FileSize() { - EnsureOpen(); - if (size_ == -1) - __debugbreak(); // crude race condition detection - return size_; -} - -Path StorageFileLoader::GetPath() const { - return path_; -} - -void StorageFileLoader::EnsureOpen() { - while (size_ == -1) - Sleep(50); -} - -size_t StorageFileLoader::ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags) { - // We can't handle multiple of these at a time, so serialize the easy way. - std::unique_lock lock(operationMutex_); - - EnsureOpen(); - - _assert_(!operationRequested_); - _assert_(!responseAvailable_) - - { - std::unique_lock lock(mutex_); - operation_.type = OpType::READ_AT; - operation_.offset = absolutePos; - operation_.size = (int64_t)(bytes * count); - operationRequested_ = true; - cond_.notify_one(); - } - - // OK, now wait for response... - { - std::unique_lock responseLock(mutexResponse_); - while (!responseAvailable_) { - condResponse_.wait(responseLock); - } - // still under mutexResponse_ lock here. - responseAvailable_ = false; - if (operationFailed_) { - return 0; - } - - DataReader ^rd = DataReader::FromBuffer(response_.buffer); - size_t len = response_.buffer->Length; - Platform::Array ^bytearray = ref new Platform::Array((unsigned int)len); - rd->ReadBytes(bytearray); - memcpy(data, bytearray->Data, len); - response_.buffer = nullptr; - return len / bytes; - } -} - -FileLoader *StorageFileLoaderFactory::ConstructFileLoader(const Path &filename) { - return file_ ? new StorageFileLoader(file_) : nullptr; -} diff --git a/UWP/StorageFileLoader.h b/UWP/StorageFileLoader.h deleted file mode 100644 index 316ca4cc34..0000000000 --- a/UWP/StorageFileLoader.h +++ /dev/null @@ -1,90 +0,0 @@ -#pragma once - -#include "pch.h" - -#include -#include -#include -#include -#include - -#include "Common/CommonTypes.h" -#include "Common/File/Path.h" -#include "Core/Loaders.h" - -// This thing is a terrible abomination that wraps asynchronous file access behind a synchronous interface, -// completely defeating MS' design goals for StorageFile. But hey, you gotta do what you gotta do. -// This opens a stream attached to the passed-in file. Multiple of these can be created against one StorageFile. -class StorageFileLoader : public FileLoader { -public: - StorageFileLoader(Windows::Storage::StorageFile ^file); - ~StorageFileLoader(); - - bool Exists() override; - bool ExistsFast() override; - - bool IsDirectory() override; - s64 FileSize() override; - Path GetPath() const override; - - size_t ReadAt(s64 absolutePos, size_t bytes, size_t count, void *data, Flags flags = Flags::NONE) override; - -private: - void threadfunc(); - void EnsureOpen(); - - enum class OpType { - NONE, - READ_AT, - }; - - struct Operation { - OpType type; - int64_t offset; - int64_t size; - }; - - struct Response { - Windows::Storage::Streams::IBuffer ^buffer; - }; - - bool active_ = false; - int64_t size_ = -1; - std::unique_ptr thread_; - - Windows::Storage::StorageFile ^file_; - Windows::Storage::Streams::IRandomAccessStreamWithContentType ^stream_; - Path path_; - - std::mutex operationMutex_; - - bool operationRequested_ = false; - Operation operation_{ OpType::NONE, 0, 0 }; - std::condition_variable cond_; - std::mutex mutex_; - - bool operationFailed_ = false; - - bool responseAvailable_ = false; - Response response_; - std::condition_variable condResponse_; - std::mutex mutexResponse_; - - int64_t seekPos_ = 0; -}; - -class StorageFileLoaderFactory : public FileLoaderFactory { -public: - StorageFileLoaderFactory(Windows::Storage::StorageFile ^file, IdentifiedFileType fileType) : file_(file), fileType_(fileType) { } - FileLoader *ConstructFileLoader(const Path &filename) override; - -private: - Windows::Storage::StorageFile ^file_; - IdentifiedFileType fileType_; -}; - -// Similar to StorageFileLoader but for directory browsing. -class StorageDirectoryWrapper { -private: - std::thread thread_; -}; diff --git a/UWP/StorageFolderBrowser.cpp b/UWP/StorageFolderBrowser.cpp deleted file mode 100644 index 00f5275dbb..0000000000 --- a/UWP/StorageFolderBrowser.cpp +++ /dev/null @@ -1,100 +0,0 @@ -#include "pch.h" -#include "ppltasks.h" - -#include "Common/Thread/ThreadUtil.h" - -#include "StorageFolderBrowser.h" -#include "UWPUtil.h" - -using namespace Concurrency; -using namespace Windows::Storage; -using namespace Windows::Storage::Streams; - -static std::mutex initMutex; - -StorageFolderBrowser::StorageFolderBrowser(Windows::Storage::StorageFolder ^folder) : folder_(folder) { - thread_.reset(new std::thread([this]() { this->threadfunc(); })); - - path_ = FromPlatformString(folder->Path); - displayName_ = FromPlatformString(folder->DisplayName); -} - -void StorageFolderBrowser::threadfunc() { - SetCurrentThreadName("StorageFileLoader"); - - initMutex.lock(); - - /* - auto opentask = create_task(folder_->GetItemsAsync()->OpenReadAsync()).then([this](IRandomAccessStreamWithContentType ^stream) { - stream_ = stream; - active_ = true; - }); - - try { - opentask.wait(); - } - catch (const std::exception& e) { - operationFailed_ = true; - // TODO: What do we do? - const char *what = e.what(); - ILOG("%s", what); - } - catch (Platform::COMException ^e) { - - } - - auto sizetask = create_task(file_->GetBasicPropertiesAsync()).then([this](Windows::Storage::FileProperties::BasicProperties ^props) { - size_ = props->Size; - }); - try { - sizetask.wait(); - } - catch (const std::exception& e) { - const char *what = e.what(); - ILOG("%s", what); - } - catch (Platform::COMException ^e) { - std::string what = FromPlatformString(e->ToString()); - ILOG("%s", what.c_str()); - } - */ - initMutex.unlock(); - - std::unique_lock lock(mutex_); - while (active_) { - if (!operationRequested_) { - cond_.wait(lock); - } - if (operationRequested_) { - switch (operation_.type) { - case OpType::LIST_DIRECTORY: { - - /* - Streams::Buffer ^buf = ref new Streams::Buffer(operation_.size); - operationFailed_ = false; - stream_->Seek(operation_.offset); - auto task = create_task(stream_->ReadAsync(buf, operation_.size, Streams::InputStreamOptions::None)); - Streams::IBuffer ^output = nullptr; - try { - task.wait(); - output = task.get(); - } - catch (const std::exception& e) { - operationFailed_ = true; - const char *what = e.what(); - ILOG("%s", what); - } - operationRequested_ = false; - std::unique_lock lock(mutexResponse_); - response_.buffer = output; - responseAvailable_ = true; - condResponse_.notify_one(); - break;*/ - } - default: - operationRequested_ = false; - break; - } - } - } -} diff --git a/UWP/StorageFolderBrowser.h b/UWP/StorageFolderBrowser.h deleted file mode 100644 index b349b4636e..0000000000 --- a/UWP/StorageFolderBrowser.h +++ /dev/null @@ -1,70 +0,0 @@ -#pragma once -#pragma once - -#include "pch.h" - -#include -#include -#include -#include -#include - -#include "Common/CommonTypes.h" -#include "Core/Loaders.h" - -// This thing is a terrible abomination that wraps asynchronous file access behind a synchronous interface, -// completely defeating MS' design goals for StorageFile. But hey, you gotta do what you gotta do. -// This opens a stream attached to the passed-in file. Multiple of these can be created against one StorageFile. - -class StorageFolderBrowser { -public: - StorageFolderBrowser(Windows::Storage::StorageFolder ^folder); - ~StorageFolderBrowser(); - - std::string GetPath() const { - return path_; - } - - std::string DisplayName() const { - return displayName_; - } - - -private: - void threadfunc(); - - enum class OpType { - NONE, - LIST_DIRECTORY, - CHANGE_FOLDER, - }; - - struct Operation { - OpType type; - }; - - struct Response { - }; - - std::string path_; - std::string displayName_; - - bool active_ = false; - std::unique_ptr thread_; - - Windows::Storage::StorageFolder ^folder_; - - bool operationRequested_ = false; - Operation operation_{ OpType::NONE }; - std::condition_variable cond_; - std::mutex mutex_; - - bool operationFailed_ = false; - - bool responseAvailable_ = false; - Response response_; - std::condition_variable condResponse_; - std::mutex mutexResponse_; - - int64_t seekPos_ = 0; -}; diff --git a/UWP/UWP.vcxproj b/UWP/UWP.vcxproj index 6426e6309b..3b7f8013d4 100644 --- a/UWP/UWP.vcxproj +++ b/UWP/UWP.vcxproj @@ -538,8 +538,6 @@ - - @@ -579,8 +577,6 @@ Create Create - - @@ -1778,4 +1774,4 @@ - + \ No newline at end of file diff --git a/UWP/UWP.vcxproj.filters b/UWP/UWP.vcxproj.filters index 209fd4951f..03611fcc46 100644 --- a/UWP/UWP.vcxproj.filters +++ b/UWP/UWP.vcxproj.filters @@ -61,10 +61,8 @@ - - @@ -74,11 +72,9 @@ - - @@ -381,4 +377,4 @@ Content - + \ No newline at end of file