2018-10-07 03:42:33 +00:00
|
|
|
#pragma once
|
2015-08-23 06:42:29 +00:00
|
|
|
|
2019-09-22 21:52:05 +00:00
|
|
|
#include <atomic>
|
2016-03-07 03:12:32 +00:00
|
|
|
#include <condition_variable>
|
2019-09-22 21:52:05 +00:00
|
|
|
#include <memory>
|
|
|
|
#include <mutex>
|
|
|
|
#include <string>
|
|
|
|
#include <thread>
|
2019-04-07 05:14:48 +00:00
|
|
|
#include <unordered_map>
|
2016-03-07 03:12:32 +00:00
|
|
|
|
2019-09-22 21:52:05 +00:00
|
|
|
#include "Runtime/GCNTypes.hpp"
|
|
|
|
#include "Runtime/RetroTypes.hpp"
|
|
|
|
|
2022-02-21 09:04:16 +00:00
|
|
|
//#include <athena/FileReader.hpp>
|
2022-02-01 00:06:54 +00:00
|
|
|
#include <nod/nod.hpp>
|
|
|
|
#include <nod/DiscBase.hpp>
|
2019-09-22 21:52:05 +00:00
|
|
|
|
2021-04-10 08:42:06 +00:00
|
|
|
namespace metaforce {
|
2015-08-23 06:42:29 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
enum class ESeekOrigin { Begin = 0, Cur = 1, End = 2 };
|
2015-08-23 06:42:29 +00:00
|
|
|
|
|
|
|
struct DVDFileInfo;
|
2015-10-29 07:52:15 +00:00
|
|
|
class IDvdRequest;
|
2015-08-23 06:42:29 +00:00
|
|
|
|
2022-02-23 06:28:35 +00:00
|
|
|
struct SDiscInfo {
|
|
|
|
std::array<char, 6> gameId;
|
|
|
|
uint8_t version;
|
|
|
|
std::string gameTitle;
|
|
|
|
};
|
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
class CDvdFile {
|
|
|
|
friend class CResLoader;
|
|
|
|
friend class CFileDvdRequest;
|
2022-02-01 00:06:54 +00:00
|
|
|
static std::unique_ptr<nod::DiscBase> m_DvdRoot;
|
|
|
|
// static std::unordered_map<std::string, std::string> m_caseInsensitiveMap;
|
2018-12-08 05:30:43 +00:00
|
|
|
static std::thread m_WorkerThread;
|
|
|
|
static std::mutex m_WorkerMutex;
|
|
|
|
static std::condition_variable m_WorkerCV;
|
|
|
|
static std::mutex m_WaitMutex;
|
|
|
|
static std::atomic_bool m_WorkerRun;
|
|
|
|
static std::vector<std::shared_ptr<IDvdRequest>> m_RequestQueue;
|
2022-02-23 07:04:31 +00:00
|
|
|
static std::string m_rootDirectory;
|
2018-12-08 05:30:43 +00:00
|
|
|
static void WorkerProc();
|
|
|
|
|
|
|
|
std::string x18_path;
|
2022-02-01 00:06:54 +00:00
|
|
|
std::shared_ptr<nod::IPartReadStream> m_reader;
|
|
|
|
uint64_t m_begin;
|
|
|
|
uint64_t m_size;
|
2016-03-07 03:12:32 +00:00
|
|
|
|
2022-02-01 00:06:54 +00:00
|
|
|
static nod::Node* ResolvePath(std::string_view path);
|
|
|
|
// static void RecursiveBuildCaseInsensitiveMap(const hecl::ProjectPath& path, std::string::size_type prefixLen);
|
2019-03-09 08:58:27 +00:00
|
|
|
|
2015-08-23 06:42:29 +00:00
|
|
|
public:
|
2022-02-01 00:06:54 +00:00
|
|
|
static bool Initialize(const std::string_view& path);
|
2022-02-23 06:28:35 +00:00
|
|
|
static SDiscInfo DiscInfo();
|
2022-02-23 07:04:31 +00:00
|
|
|
static void SetRootDirectory(const std::string_view& rootDir);
|
2018-12-08 05:30:43 +00:00
|
|
|
static void Shutdown();
|
|
|
|
|
2022-02-01 00:06:54 +00:00
|
|
|
CDvdFile(std::string_view path);
|
|
|
|
operator bool() const { return m_reader.operator bool(); }
|
|
|
|
void UpdateFilePos(int pos) { m_reader->seek(pos, SEEK_SET); }
|
|
|
|
static bool FileExists(std::string_view path) {
|
|
|
|
nod::Node* node = ResolvePath(path);
|
|
|
|
return node != nullptr && node->getKind() == nod::Node::Kind::File;
|
|
|
|
}
|
|
|
|
void CloseFile() { m_reader.reset(); }
|
2018-12-08 05:30:43 +00:00
|
|
|
std::shared_ptr<IDvdRequest> AsyncSeekRead(void* buf, u32 len, ESeekOrigin whence, int off,
|
|
|
|
std::function<void(u32)>&& cb = {});
|
2022-02-01 00:06:54 +00:00
|
|
|
u32 SyncSeekRead(void* buf, u32 len, ESeekOrigin whence, int offset);
|
2018-12-08 05:30:43 +00:00
|
|
|
std::shared_ptr<IDvdRequest> AsyncRead(void* buf, u32 len, std::function<void(u32)>&& cb = {}) {
|
|
|
|
return AsyncSeekRead(buf, len, ESeekOrigin::Cur, 0, std::move(cb));
|
|
|
|
}
|
2022-02-01 00:06:54 +00:00
|
|
|
u32 SyncRead(void* buf, u32 len) { return m_reader->read(buf, len); }
|
|
|
|
u64 Length() const { return m_size; }
|
2018-12-08 05:30:43 +00:00
|
|
|
std::string_view GetPath() const { return x18_path; }
|
2015-08-23 06:42:29 +00:00
|
|
|
};
|
2021-04-10 08:42:06 +00:00
|
|
|
} // namespace metaforce
|