diff options
| author | robojumper <robojumper@gmail.com> | 2024-05-17 00:23:15 +0200 |
|---|---|---|
| committer | robojumper <robojumper@gmail.com> | 2024-05-17 00:43:56 +0200 |
| commit | 48e6945e3e11f16874ece6e39d4bafaceb2372bf (patch) | |
| tree | 520b77d444d6f7ebc9a478cf733d174632ec65b1 /src/m/m_dvd.cpp | |
| parent | 62e0778390f838cdb92f16b3582e2d76299ae8a5 (diff) | |
m_dvd work
Diffstat (limited to 'src/m/m_dvd.cpp')
| -rw-r--r-- | src/m/m_dvd.cpp | 564 |
1 files changed, 564 insertions, 0 deletions
diff --git a/src/m/m_dvd.cpp b/src/m/m_dvd.cpp new file mode 100644 index 00000000..ed486c44 --- /dev/null +++ b/src/m/m_dvd.cpp @@ -0,0 +1,564 @@ +#include <egg/core/eggArchive.h> +#include <egg/core/eggDecomp.h> +#include <egg/core/eggDvdFile.h> +#include <egg/core/eggDvdRipper.h> +#include <egg/core/eggHeap.h> +#include <m/m_dvd.h> +#include <m/m_heap.h> + +namespace mDvd { + +TUncompressInfo_c<EGG::StreamDecompSZS> DECOMP_SZS(3, ".szs"); +TUncompressInfo_c<EGG::StreamDecompLZ> DECOMP_LZ(5, ".LZ"); +TUncompressInfo_c<EGG::StreamDecompLH> DECOMP_LH(7, ".LH"); +TUncompressInfo_c<EGG::StreamDecompLRC> DECOMP_LRC(8, ".LRC"); +TUncompressInfo_c<EGG::StreamDecompRL> DECOMP_RL(4, ".RL"); + +// TODO This the space within which the actual decompressors +// are allocated. +char likely_align[0x7A04]; +char more_empty_space[0x1638]; +char decompressor_alloc_space[0x9930]; + +mDvd_param_c DVD_MANAGER; + +TUncompressInfo_Base_c *decompressorPtrs[1] = { + &DECOMP_LZ, +}; + +u8 g_mountDirection = 1; +int maxChunkSize = 0x10000; + +void *somePtr; +u32 someNumber; +TUncompressInfo_Base_c **compressors_ptr; +TUncompressInfo_Base_c **compressors_last; +OSThread *sOsThread; +mDvd::MyThread_c *sThread; +EGG::Heap *sCommandHeap; +EGG::Heap *sArchiveHeap; +bool isAutoStreamDecomp; +bool isRegistered; + +/** 802eece0 */ +extern "C" void fn_802EECE0(TUncompressInfo_Base_c **ptr, TUncompressInfo_Base_c **last) { + compressors_ptr = ptr; + compressors_last = last; +} + +/** 802eecf0 */ +extern "C" void fn_802EECF0() { + fn_802EECE0(decompressorPtrs, &decompressorPtrs[1]); + somePtr = decompressor_alloc_space; + someNumber = 0x24; +} + +/** 802eed30 */ +TUncompressInfo_Base_c *findUncompressInfo(u8 type) { + TUncompressInfo_Base_c **ptr = compressors_ptr; + while (ptr != compressors_last) { + if ((*ptr)->mType == type) { + return *ptr; + } + ptr++; + } + return nullptr; +} + +/** 802eed70 */ +EGG::StreamDecomp *newUncompressObj(u8 type) { + TUncompressInfo_Base_c *factory = findUncompressInfo(type); + if (factory != nullptr) { + return factory->Construct(); + } else { + return nullptr; + } +} + +/** 802eedb0 */ +void deleteUncompressObj(u8 type) { + TUncompressInfo_Base_c *factory = findUncompressInfo(type); + if (factory != nullptr) { + factory->Destruct(); + } +} + +OSThread *getOSThread() { + return sOsThread; +} + +EGG::Heap *getArchiveHeap() { + return sArchiveHeap; +} + +/** 802eee10 */ +void *MyThread_c::run(mDvd_param_c *dvd) { + dvd->mainLoop(); + return nullptr; +} + +/** 802eee40 */ +MyThread_c::MyThread_c(int priority, EGG::Heap *heap) : EGG::Thread(0x4000, 0, priority, heap) {} + +/** 802eee90 */ +void *MyThread_c::run() { + return run(mDvd_param_c::mInstance); +} + +/** 802eeea0 */ +void create(int priority, EGG::Heap *commandHeap, EGG::Heap *archiveHeap, EGG::Heap *threadHeap) { + sCommandHeap = commandHeap; + sArchiveHeap = archiveHeap; + mDvd::MyThread_c *thread = new (threadHeap, 0x04) mDvd::MyThread_c(priority, threadHeap); + sThread = thread; + sOsThread = thread->getMyOsThread(); + if (mHeap::g_assertHeap != nullptr) { + thread->setThreadHeap((EGG::Heap *)mHeap::g_assertHeap); + } + OSResumeThread(sThread->getMyOsThread()); +} + +/** 802eef30 */ +void *loadToMainRAM(int entryNum, char *dst, EGG::Heap *heap, EGG::DvdRipper::EAllocDirection allocDir, u32 offset, + u32 *p6, u32 *p7, u32 decompressorType) { + // TODO + + if (decompressorType == 0) { + } else { + extern EGG::DvdFile DvdFile; + if (mDvd::isRegistered == false) { + static EGG::DvdFile DvdFile; + + isRegistered = true; + } + } +} + +int ConvertPathToEntrynum(const char *path) { + return ::ConvertPathToEntrynum(path, nullptr); +} + +u32 IsExistPath(const char *path) { + u32 entry = ConvertPathToEntrynum(path); + // TODO fake match + return (((-entry - 1) | (entry + 1)) >> 0x1f); +} + +} // namespace mDvd + +mDvd_param_c *mDvd_param_c::mInstance; + +/** 802ef0d0 */ +mDvd_command_c::~mDvd_command_c() { + waitDone(); +} + +/** 802ef130 */ +void *mDvd_command_c::operator new(size_t size) { + return EGG::Heap::alloc(size, -4, mDvd::sCommandHeap); +} + +void mDvd_command_c::operator delete(void *ptr) { + EGG::Heap::free(ptr, mDvd::sCommandHeap); +} + +/** 802ef150 */ +void mDvd_command_c::doClear() { + onComplete(); +} + +/** 802ef170 */ +void mDvd_command_c::done() {} + +void mDvd_command_c::waitDone() { + mStatus = 1; + OSWakeupThread(&mDvd_param_c::mInstance->mThreadQueue2); +} + +/** 802ef190 */ +void mDvd_command_c::waitUntilDone() { + while (mStatus == 0) { + OSSleepThread(&mDvd_param_c::mInstance->mThreadQueue2); + } +} + +/** 802ef1e0 */ +mDvd_param_c::mDvd_param_c() { + mFirstRequest = nullptr; + mLastRequest = nullptr; + OSInitMutex(&mMutex); + OSInitThreadQueue(&mThreadQueue1); + OSInitThreadQueue(&mThreadQueue2); + mDvd_param_c::mInstance = this; +} + +/** 802ef230 */ +void mDvd_param_c::kick() { + OSWakeupThread(&mThreadQueue1); +} + +/** 802ef240 */ +void mDvd_param_c::waitForKick() { + OSSleepThread(&mThreadQueue1); +} + +/** 802ef250 */ +mDvd_command_c *mDvd_param_c::getFirstCommand() { + return mFirstRequest; +} + +/** 802ef260 */ +void mDvd_param_c::addCommand(mDvd_command_c *cmd) { + OSThread *dvdThread = mDvd::getOSThread(); + OSThread *currThread = OSGetCurrentThread(); + if (currThread == dvdThread) { + cmd->execute(); + } else { + OSLockMutex(&mMutex); + cmd->mNext = nullptr; + if (mLastRequest == nullptr) { + mLastRequest = cmd; + mFirstRequest = cmd; + } else { + mLastRequest->mNext = cmd; + mLastRequest = cmd; + } + OSUnlockMutex(&mMutex); + kick(); + } +} + +/** 802ef310 */ +void mDvd_param_c::removeCommand(mDvd_command_c *toRemove) { + OSLockMutex(&mMutex); + mDvd_command_c *prev = nullptr; + + for (mDvd_command_c *cmd = mFirstRequest; cmd != nullptr; cmd = cmd->mNext) { + if (cmd == toRemove) { + if (prev != nullptr) { + prev->mNext = cmd->mNext; + if (mLastRequest == cmd) { + mLastRequest = prev; + } + } else { + if (mFirstRequest == mLastRequest) { + mFirstRequest = nullptr; + mLastRequest = nullptr; + } else { + mFirstRequest = cmd->mNext; + } + } + } + + prev = cmd; + } + + OSUnlockMutex(&mMutex); + kick(); +} + +u32 mDvd_param_c::executeCB(mDvd_command_c **cmd) { + (*cmd)->execute(); + return 0; +} + +/** 802ef410 */ +void mDvd_param_c::mainLoop() { + mDvd_command_c *cmd; + while (true) { + waitForKick(); + while ((cmd = getFirstCommand()) != nullptr) { + removeCommand(cmd); + executeCB(&cmd); + } + } +} + +/** 802ef460 */ +mDvd_command_c::mDvd_command_c() { + mNext = nullptr; + mStatus = 0; +} + +/** 802ef480 */ +extern "C" void fn_802EF480(mDvd_command_c *cmd) { + delete cmd; +} + +/** 802ef4a0 */ +void mDvd_command_c::destroy(mDvd_command_c **cmd) { + if (cmd != nullptr && *cmd != nullptr) { + (*cmd)->doClear(); + // TODO + delete *cmd; + *cmd = nullptr; + } +} + +/** 802ef500 */ +mDvdCommandReadCallback_c::~mDvdCommandReadCallback_c() {} + +/** 802ef560 */ +mDvdCommandReadCallback_c::mDvdCommandReadCallback_c(dvdReadCallback cb, void *cbData) { + mCallback = cb; + mCallbackData = cbData; + mDataPtr = nullptr; +} + +/* 802ef5d0 */ +mDvdCommandReadCallback_c *mDvdCommandReadCallback_c::create(dvdReadCallback cb, void *cbData) { + // TODO instshuffle + mDvdCommandReadCallback_c *cmd = new mDvdCommandReadCallback_c(cb, cbData); + if (cmd != nullptr) { + mDvd_param_c::mInstance->addCommand(cmd); + } + return cmd; +} + +/** 802ef650 */ +extern "C" void fn_802EF650() {} + +/** 802ef680 */ +u32 mDvdCommandReadCallback_c::execute() { + mDataPtr = (mCallback)(mCallbackData); + waitDone(); + return (bool)mDataPtr; +} + +/** 802ef6e0 */ +mDvd_mountMemArchive_c::~mDvd_mountMemArchive_c() {} + +/** 802ef740 */ +mDvd_mountMemArchive_c::mDvd_mountMemArchive_c(int mountDirection) { + if (mountDirection == 0) { + mountDirection = mDvd::g_mountDirection; + } + mMountDirection = mountDirection; + mCompressionType = 0; + mEntryNum = -1; + mDataPtr = nullptr; + mHeap = nullptr; + field_0x18 = 0; +} + +/** 802ef7c0 */ +int findPathWithCompressedExtension(const char *name, u8 *outType) { + return 0; // TODO +} + +/** 802ef930 */ +void setAutoStreamDecomp(bool arg) { + mDvd::isAutoStreamDecomp = arg; +} + +/** 802ef940 */ +bool getAutoStreamDecomp() { + return mDvd::isAutoStreamDecomp; +} + +// TODO maybe weak +/** 802ef950 */ +int ConvertPathToEntrynum(const char *path, u8 *outType) { + return 0; // TODO +} + +// TODO thunk +/** 802ef950 */ +int ConvertPathToEntrynum_Thunk(const char *path, u8 *outType) { + return ConvertPathToEntrynum(path, outType); +} + +/** 802ef9e0 */ +mDvd_mountMemArchive_c *mDvd_mountMemArchive_c::create(const char *path, u8 mountDirection, EGG::Heap *heap) { + u8 type; + mDvd_mountMemArchive_c *cmd = nullptr; + int entryNum = ConvertPathToEntrynum_Thunk(path, &type); + if (entryNum != -1) { + cmd = new mDvd_mountMemArchive_c(mountDirection); + if (cmd != nullptr) { + cmd->mEntryNum = entryNum; + cmd->mHeap = heap; + cmd->mCompressionType = type; + mDvd_param_c::mInstance->addCommand(cmd); + } + } + + return cmd; +} + +/** 802efa80 */ +u32 mDvd_mountMemArchive_c::execute() { + void *data; + int align; + EGG::DvdRipper::EAllocDirection allocDirection; + EGG::Archive *archive; + EGG::Heap *heap; + + heap = mHeap != nullptr ? mHeap : mDvd::sArchiveHeap; + archive = nullptr; + + allocDirection = mMountDirection == 1 ? EGG::DvdRipper::ALLOC_DIR_TOP : EGG::DvdRipper::ALLOC_DIR_BOTTOM; + data = mDvd::loadToMainRAM(mEntryNum, nullptr, heap, allocDirection, 0, (u32 *)field_0x18, 0, mCompressionType); + if (data != nullptr) { + align = -4; + if (mMountDirection == 1) { + align = 4; + } + archive = EGG::Archive::mount(data, heap, align); + } + + if (archive == nullptr) { + if (data != nullptr) { + delete data; + } + field_0x18 = 0; + } else { + mDataPtr = archive; + } + waitDone(); + return (bool)mDataPtr; +} + +/** 802efb80 */ +void *mDvd_mountMemArchive_c::getArcBinary() { + void *result = nullptr; + if (mDataPtr != nullptr) { + result = mDataPtr->mHandle.header; + } + return result; +} + +/** 802efba0 */ +void mDvd_mountMemArchive_c::onComplete() { + if (mDataPtr != nullptr) { + void *data = mDataPtr->mHandle.header; + mDataPtr->unmount(); + mDataPtr = nullptr; + if (data != nullptr) { + EGG::Heap::free(data, nullptr); + } + } +} + +/** 802efc10 */ +mDvd_toMainRam_base_c::mDvd_toMainRam_base_c(int mountDirection) { + if (mountDirection == 0) { + mountDirection = mDvd::g_mountDirection; + } + mMountDirection = mountDirection; + mDataPtr = nullptr; + field_0x10 = 0; + field_0x14 = 0; + mHeap = nullptr; +} + +/** 802efc80 */ +mDvd_toMainRam_base_c::~mDvd_toMainRam_base_c() {} + +/** 802efce0 */ +mDvd_toMainRam_arc_c::~mDvd_toMainRam_arc_c() {} + +/** 802efd40 */ +mDvd_toMainRam_arc_c::mDvd_toMainRam_arc_c(EGG::Archive *arc, int entryNum, int mountDirection) + : mDvd_toMainRam_base_c(mountDirection), mArcPtr(arc) { + mEntryNum = entryNum; +} + +/** 802efda0 */ +mDvd_toMainRam_arc_c *mDvd_toMainRam_arc_c::makeRequest(EGG::Archive *arc, int entryNum, int mountDirection, + EGG::Heap *heap) { + mDvd_toMainRam_arc_c *cmd = new mDvd_toMainRam_arc_c(arc, entryNum, mountDirection); + if (cmd != nullptr) { + cmd->mHeap = heap; + mDvd_param_c::mInstance->addCommand(cmd); + } + return cmd; +} + +/** 802efe20 */ +mDvd_toMainRam_arc_c *create(EGG::Archive *arc, const char *path, int mountDirection, EGG::Heap *heap) { + int entryNum = arc->convertPathToEntryID(path); + mDvd_toMainRam_arc_c *cmd = nullptr; + if (entryNum != -1) { + cmd = mDvd_toMainRam_arc_c::makeRequest(arc, entryNum, mountDirection, heap); + } + return cmd; +} + +/** 802efe90 */ +extern "C" void fn_802EFE90() { + // TODO +} + +/** 802efec0 */ +u32 mDvd_toMainRam_arc_c::execute() { + EGG::Heap *heap = mHeap != nullptr ? mHeap : mDvd::sArchiveHeap; + mDataPtr = mArcPtr->getFileFast(mEntryNum, heap, mMountDirection == 1 ? 0x20 : -0x20); + waitDone(); + return (bool)mDataPtr; +} + +/** 802eff40 */ +mDvd_toMainRam_normal_c::mDvd_toMainRam_normal_c(int mountDirection) : mDvd_toMainRam_base_c(mountDirection) { + mCompressionType2 = 0; + mEntryNum = -1; +} + +/** 802eff90 */ +mDvd_toMainRam_normal_c *mDvd_toMainRam_normal_c::create(const char *path, int mountDirection, EGG::Heap *heap) { + u8 type; + int entryNum = ConvertPathToEntrynum(path, &type); + mDvd_toMainRam_normal_c *cmd; + if (entryNum == -1) { + cmd = nullptr; + } else { + cmd = new mDvd_toMainRam_normal_c(mountDirection); + if (cmd != nullptr) { + cmd->mEntryNum = entryNum; + cmd->mHeap = heap; + cmd->mCompressionType2 = type; + mDvd_param_c::mInstance->addCommand(cmd); + } + } + return cmd; +} + +/** 802f0030 */ +extern "C" void fn_802F0030() { + // TODO +} + +/** 802f0060 */ +void mDvd_toMainRam_normal_c::create2(mDvd_toMainRam_normal_c **cmd, const char *path, int mountDirection, + EGG::Heap *heap) { + if (*cmd == nullptr) { + *cmd = mDvd_toMainRam_normal_c::create(path, mountDirection, heap); + } +} + +/** 802f00b0 */ +mDvd_toMainRam_normal_c::~mDvd_toMainRam_normal_c() {} + +/** 802f0110 */ +u32 mDvd_toMainRam_normal_c::execute() { + // TODO + u32 p6; + u32 p7; + EGG::Heap *heap = mHeap != nullptr ? mHeap : mDvd::sArchiveHeap; + EGG::DvdRipper::EAllocDirection allocDirection = mMountDirection == 1 ? EGG::DvdRipper::ALLOC_DIR_TOP : EGG::DvdRipper::ALLOC_DIR_BOTTOM; + mDataPtr = mDvd::loadToMainRAM(mEntryNum, 0, heap, allocDirection, 0, &p6, &p7, mCompressionType2); + if (mDataPtr != nullptr) { + field_0x10 = p6; + field_0x14 = p7; + } + waitDone(); + return (bool)mDataPtr; +} + +/** 802f01b0 */ +void mDvd_toMainRam_normal_c::onComplete() { + if (mDataPtr == nullptr) { + return; + } + EGG::Heap::free(mDataPtr, nullptr); +} |
