mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-07-12 05:28:43 -04:00
Use separate heap for DVD decompression
This fixes crashes when first entering North Faaron cave and Renado's Sanctuary due to system heap exhaustion resulting from multiple threads allocating on the heap at once. There's some sort of weird contention going on - for some reason the game gobbles up seemingly any amount of memory you throw at it when the two threads are competing for heap space. Using a separate heap in the async thread sidesteps the issue.
This commit is contained in:
@@ -36,6 +36,9 @@ public:
|
||||
static JSUList<JKRDMCommand> sDvdAsyncList;
|
||||
static u32 sSZSBufferSize;
|
||||
static bool errorRetry;
|
||||
#if TARGET_PC
|
||||
static JKRHeap* sHeap;
|
||||
#endif
|
||||
|
||||
enum EAllocDirection {
|
||||
UNKNOWN_EALLOC_DIRECTION = 0,
|
||||
@@ -54,6 +57,12 @@ public:
|
||||
|
||||
static bool isErrorRetry(void) { return errorRetry; }
|
||||
inline static u32 getSZSBufferSize() { return sSZSBufferSize; }
|
||||
|
||||
#if TARGET_PC
|
||||
static inline JKRHeap* getHeap() { return sHeap; }
|
||||
static inline void setHeap(JKRHeap* i_heap) { sHeap = i_heap; }
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
// void JKRDecompressFromDVD(JKRDvdFile*, void*, u32, u32, u32, u32, u32*);
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#include <vi.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "JSystem/JKernel/JKRExpHeap.h"
|
||||
|
||||
static int JKRDecompressFromDVD(JKRDvdFile*, void*, u32, u32, u32, u32, u32*);
|
||||
static int decompSZS_subroutine(u8*, u8*);
|
||||
static u8* firstSrcData();
|
||||
@@ -240,6 +242,8 @@ static OSMutex decompMutex;
|
||||
|
||||
u32 JKRDvdRipper::sSZSBufferSize = 0x00000400;
|
||||
|
||||
JKRHeap* JKRDvdRipper::sHeap = NULL;
|
||||
|
||||
static u8* szpBuf;
|
||||
|
||||
static u8* szpEnd;
|
||||
@@ -282,12 +286,20 @@ static int JKRDecompressFromDVD(JKRDvdFile* dvdFile, void* dst, u32 fileSize, u3
|
||||
OSLockMutex(&decompMutex);
|
||||
u32 result = 0;
|
||||
u32 szsBufferSize = JKRDvdRipper::getSZSBufferSize();
|
||||
#if TARGET_PC
|
||||
szpBuf = (u8 *)JKRAllocFromHeap(JKRDvdRipper::getHeap(), szsBufferSize, -0x20);
|
||||
#else
|
||||
szpBuf = (u8 *)JKRAllocFromSysHeap(szsBufferSize, -0x20);
|
||||
#endif
|
||||
JUT_ASSERT(909, szpBuf != NULL);
|
||||
|
||||
szpEnd = szpBuf + szsBufferSize;
|
||||
if (inFileOffset != 0) {
|
||||
#if TARGET_PC
|
||||
refBuf = (u8 *)JKRAllocFromHeap(JKRDvdRipper::getHeap(), 0x1120, -4);
|
||||
#else
|
||||
refBuf = (u8 *)JKRAllocFromSysHeap(0x1120, -4);
|
||||
#endif
|
||||
JUT_ASSERT(918, refBuf != NULL);
|
||||
refEnd = refBuf + 0x1120;
|
||||
refCurrent = refBuf;
|
||||
|
||||
@@ -29,6 +29,10 @@
|
||||
#include "DynamicLink.h"
|
||||
#include "os_report.h"
|
||||
|
||||
#if TARGET_PC
|
||||
#include <assert.h>
|
||||
#endif
|
||||
|
||||
#if !PLATFORM_GCN
|
||||
#include <revolution/sc.h>
|
||||
#include <revolution/wpad.h>
|
||||
@@ -991,6 +995,11 @@ int mDoMch_Create() {
|
||||
GXSetVerifyCallback((GXVerifyCallback)&myGXVerifyCallback);
|
||||
#endif
|
||||
JKRDvdRipper::setSZSBufferSize(0x4000);
|
||||
#if TARGET_PC
|
||||
JKRHeap* dvdHeap = JKRCreateExpHeap(0x10000, NULL, false);
|
||||
assert(dvdHeap != NULL);
|
||||
JKRDvdRipper::setHeap(dvdHeap);
|
||||
#endif
|
||||
JKRDvdAramRipper::setSZSBufferSize(0x4000);
|
||||
JKRAram::setSZSBufferSize(0x2000);
|
||||
mDoDvdThd::create(OSGetThreadPriority(OSGetCurrentThread()) - 2);
|
||||
|
||||
Reference in New Issue
Block a user