mirror of
https://gitlab.com/skmp/dca3-game.git
synced 2025-08-31 02:20:04 +02:00
Merge branch 'skmp/oom-mitigation-3' into 'main'
Memory usage improvements and memleak fixes See merge request skmp/dca3-game!72
This commit is contained in:
@@ -11,6 +11,8 @@
|
||||
#include "AnimBlendAssocGroup.h"
|
||||
#include "AnimManager.h"
|
||||
|
||||
void* re3StreamingAlloc(size_t size);
|
||||
|
||||
CAnimBlock CAnimManager::ms_aAnimBlocks[NUMANIMBLOCKS];
|
||||
CAnimBlendHierarchy CAnimManager::ms_aAnimations[NUMANIMATIONS];
|
||||
int32 CAnimManager::ms_numAnimBlocks;
|
||||
@@ -837,7 +839,7 @@ CAnimManager::LoadAnimFile(int fd, bool compress)
|
||||
uint16_t flags;
|
||||
CFileMgr::Read(fd, (char*)&flags, sizeof(flags));
|
||||
|
||||
seq->keyFrames = RwMalloc(dataSize);
|
||||
seq->keyFrames = re3StreamingAlloc(dataSize);
|
||||
assert(seq->keyFrames);
|
||||
CFileMgr::Read(fd, (char*)seq->keyFrames, dataSize - sizeof(flags));
|
||||
seq->type = flags;
|
||||
|
@@ -175,6 +175,12 @@ file_t fdPedSfx;
|
||||
volatile uint32 nPedSfxReqReadId = 1;
|
||||
volatile uint32 nPedSfxReqNextId = 1;
|
||||
|
||||
// this is very wasteful and temporary
|
||||
#define BANK_STAGE_SIZE 16 * 2048
|
||||
static uint8_t stagingBufferBank[BANK_STAGE_SIZE] __attribute__((aligned(32)));
|
||||
std::mutex stagingBufferMtx;
|
||||
|
||||
|
||||
static int32 DCStreamedLength[TOTAL_STREAMED_SOUNDS];
|
||||
|
||||
struct WavHeader {
|
||||
@@ -568,26 +574,29 @@ cSampleManager::LoadSampleBank(uint8 nBank)
|
||||
// TODO: Split per-bank sfx file
|
||||
int fd = fs_open(SampleBankDataFilename, O_RDONLY);
|
||||
assert(fd >= 0);
|
||||
// this is very wasteful and temporary
|
||||
void* stagingBuffer = memalign(32, 32 * 2048);
|
||||
assert(stagingBuffer != 0);
|
||||
|
||||
|
||||
{
|
||||
std::lock_guard lk(stagingBufferMtx); // for stagingBufferBank
|
||||
|
||||
void* stagingBuffer = stagingBufferBank;
|
||||
|
||||
// Ideally, we'd suspend the CdStream thingy here or read via that instead
|
||||
uintptr_t loadOffset = bank.base;
|
||||
fs_seek(fd, fileStart, SEEK_SET);
|
||||
// Ideally, we'd suspend the CdStream thingy here or read via that instead
|
||||
uintptr_t loadOffset = bank.base;
|
||||
fs_seek(fd, fileStart, SEEK_SET);
|
||||
|
||||
while (fileSize > 0) {
|
||||
size_t readSize = fileSize > 32 * 2048 ? 32 * 2048 : fileSize;
|
||||
int rs = fs_read(fd, stagingBuffer, readSize);
|
||||
debugf("Read %d bytes, expected %d\n", rs, readSize);
|
||||
assert(rs == readSize);
|
||||
spu_memload(loadOffset, stagingBuffer, readSize);
|
||||
loadOffset += readSize;
|
||||
fileSize -= readSize;
|
||||
debugf("Loaded %d bytes, %d remaining\n", readSize, fileSize);
|
||||
while (fileSize > 0) {
|
||||
size_t readSize = fileSize > sizeof(stagingBufferBank) ? sizeof(stagingBufferBank) : fileSize;
|
||||
int rs = fs_read(fd, stagingBuffer, readSize);
|
||||
debugf("Read %d bytes, expected %d\n", rs, readSize);
|
||||
assert(rs == readSize);
|
||||
spu_memload(loadOffset, stagingBuffer, readSize);
|
||||
loadOffset += readSize;
|
||||
fileSize -= readSize;
|
||||
debugf("Loaded %d bytes, %d remaining\n", readSize, fileSize);
|
||||
}
|
||||
}
|
||||
fs_close(fd);
|
||||
free(stagingBuffer);
|
||||
|
||||
|
||||
for (int nSfx = BankStartOffset[nBank]; nSfx < BankStartOffset[nBank+1]; nSfx++) {
|
||||
@@ -736,15 +745,19 @@ cSampleManager::LoadPedComment(uint32 nComment)
|
||||
// TODO: When we can dma directly to AICA, we can use this instead
|
||||
// fs_read(fdPedSfx, SPU_BASE_U8 + (uintptr_t)cmd->dest, cmd->size);
|
||||
|
||||
void* stagingBuffer = memalign(32, cmd->size);
|
||||
assert(stagingBuffer != 0);
|
||||
debugf("Allocated %d bytes at %p\n", cmd->size, stagingBuffer);
|
||||
int rs = fs_read(fdPedSfx, stagingBuffer, cmd->size);
|
||||
debugf("Read %d bytes, expected %d\n", rs, cmd->size);
|
||||
assert(rs == cmd->size);
|
||||
|
||||
spu_memload((uintptr_t)cmd->dest, stagingBuffer, cmd->size);
|
||||
free(stagingBuffer);
|
||||
assert(cmd->size < sizeof(stagingBufferBank));
|
||||
{
|
||||
std::lock_guard lk(stagingBufferMtx); // for stagingBufferBank
|
||||
void* stagingBuffer = stagingBufferBank;
|
||||
assert(stagingBuffer != 0);
|
||||
debugf("Allocated %d bytes at %p\n", cmd->size, stagingBuffer);
|
||||
int rs = fs_read(fdPedSfx, stagingBuffer, cmd->size);
|
||||
debugf("Read %d bytes, expected %d\n", rs, cmd->size);
|
||||
assert(rs == cmd->size);
|
||||
|
||||
spu_memload((uintptr_t)cmd->dest, stagingBuffer, cmd->size);
|
||||
}
|
||||
|
||||
nPedSfxReqReadId = nPedSfxReqReadId + 1;
|
||||
});
|
||||
|
||||
@@ -1268,6 +1281,8 @@ cSampleManager::InitialiseSampleBanks(void)
|
||||
assert(m_aSamples[nComment].nByteSize <= PED_BLOCKSIZE_ADPCM);
|
||||
}
|
||||
|
||||
assert(PED_BLOCKSIZE_ADPCM <= BANK_STAGE_SIZE);
|
||||
|
||||
LoadSampleBank(SFX_BANK_0);
|
||||
|
||||
return TRUE;
|
||||
|
@@ -2,6 +2,9 @@
|
||||
#include "ColModel.h"
|
||||
#include "Game.h"
|
||||
#include "MemoryHeap.h"
|
||||
#include "Collision.h"
|
||||
|
||||
void* re3StreamingAlloc(size_t size);
|
||||
|
||||
CColModel::CColModel(void)
|
||||
{
|
||||
@@ -22,12 +25,12 @@ CColModel::CColModel(void)
|
||||
CColModel::~CColModel(void)
|
||||
{
|
||||
RemoveCollisionVolumes();
|
||||
RemoveTrianglePlanes();
|
||||
}
|
||||
|
||||
void
|
||||
CColModel::RemoveCollisionVolumes(void)
|
||||
{
|
||||
CCollision::RemoveTrianglePlanes(this);
|
||||
if(ownsCollisionVolumes){
|
||||
RwFree(spheres);
|
||||
RwFree(lines);
|
||||
@@ -93,6 +96,8 @@ CColModel::operator=(const CColModel &other)
|
||||
int i;
|
||||
int numVerts;
|
||||
|
||||
CCollision::RemoveTrianglePlanes(this);
|
||||
|
||||
boundingSphere = other.boundingSphere;
|
||||
boundingBox = other.boundingBox;
|
||||
|
||||
@@ -163,7 +168,7 @@ CColModel::operator=(const CColModel &other)
|
||||
if(vertices)
|
||||
RwFree(vertices);
|
||||
if(numVerts){
|
||||
vertices = (CompressedVector*)RwMalloc(numVerts*sizeof(CompressedVector));
|
||||
vertices = (CompressedVector*)re3StreamingAlloc(numVerts*sizeof(CompressedVector));
|
||||
for(i = 0; i < numVerts; i++)
|
||||
vertices[i] = other.vertices[i];
|
||||
}
|
||||
@@ -173,7 +178,7 @@ CColModel::operator=(const CColModel &other)
|
||||
numTriangles = other.numTriangles;
|
||||
if(triangles)
|
||||
RwFree(triangles);
|
||||
triangles = (CColTriangle*)RwMalloc(numTriangles*sizeof(CColTriangle));
|
||||
triangles = (CColTriangle*)re3StreamingAlloc(numTriangles*sizeof(CColTriangle));
|
||||
}
|
||||
for(i = 0; i < numTriangles; i++)
|
||||
triangles[i] = other.triangles[i];
|
||||
|
@@ -2287,6 +2287,15 @@ CCollision::DistToLine(const CVector *l0, const CVector *l1, const CVector *poin
|
||||
return (*point - closest).Magnitude();
|
||||
}
|
||||
|
||||
void
|
||||
CCollision::RemoveTrianglePlanes(CColModel *model)
|
||||
{
|
||||
if(model->trianglePlanes){
|
||||
ms_colModelCache.Remove(model->GetLinkPtr());
|
||||
model->RemoveTrianglePlanes();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CCollision::CalculateTrianglePlanes(CColModel *model)
|
||||
{
|
||||
|
@@ -41,6 +41,7 @@ public:
|
||||
static void DrawColModel(const CMatrix &mat, const CColModel &colModel);
|
||||
static void DrawColModel_Coloured(const CMatrix &mat, const CColModel &colModel, int32 id);
|
||||
|
||||
static void RemoveTrianglePlanes(CColModel *model);
|
||||
static void CalculateTrianglePlanes(CColModel *model);
|
||||
|
||||
// all these return true if there's a collision
|
||||
|
@@ -28,6 +28,8 @@
|
||||
|
||||
#include <kos/dbglog.h>
|
||||
|
||||
void* re3StreamingAlloc(size_t size);
|
||||
|
||||
char CFileLoader::ms_line[256];
|
||||
|
||||
const char*
|
||||
@@ -221,7 +223,7 @@ CFileLoader::LoadCollisionFile(const char *filename)
|
||||
|
||||
mi = CModelInfo::GetModelInfo(modelname, nil);
|
||||
if(mi){
|
||||
if(mi->GetColModel()){
|
||||
if(mi->GetColModel() && mi->DoesOwnColModel()){
|
||||
LoadCollisionModel(work_buff+24, *mi->GetColModel(), modelname);
|
||||
}else{
|
||||
CColModel *model = new CColModel;
|
||||
@@ -255,6 +257,24 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
|
||||
model.boundingBox.max.z = *(float*)(buf+36);
|
||||
model.numSpheres = *(int16*)(buf+40);
|
||||
buf += 44;
|
||||
if (model.spheres) {
|
||||
RwFree(model.spheres);
|
||||
}
|
||||
if (model.lines) {
|
||||
RwFree(model.lines);
|
||||
}
|
||||
if (model.boxes) {
|
||||
RwFree(model.boxes);
|
||||
}
|
||||
if (model.vertices) {
|
||||
RwFree(model.vertices);
|
||||
}
|
||||
if (model.triangles) {
|
||||
RwFree(model.triangles);
|
||||
}
|
||||
if (model.trianglePlanes) {
|
||||
CCollision::RemoveTrianglePlanes(&model);
|
||||
}
|
||||
if(model.numSpheres > 0){
|
||||
model.spheres = (CColSphere*)RwMalloc(model.numSpheres*sizeof(CColSphere));
|
||||
REGISTER_MEMPTR(&model.spheres);
|
||||
@@ -292,7 +312,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
|
||||
int32 numVertices = *(int16*)buf;
|
||||
buf += 4;
|
||||
if(numVertices > 0){
|
||||
model.vertices = (CompressedVector*)RwMalloc(numVertices*sizeof(CompressedVector));
|
||||
model.vertices = (CompressedVector*)re3StreamingAlloc(numVertices*sizeof(CompressedVector));
|
||||
REGISTER_MEMPTR(&model.vertices);
|
||||
for(i = 0; i < numVertices; i++){
|
||||
model.vertices[i].SetFixed(*(int16*)buf, *(int16*)(buf+2), *(int16*)(buf+4));
|
||||
@@ -304,7 +324,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
|
||||
model.numTriangles = *(int16*)buf;
|
||||
buf += 4;
|
||||
if(model.numTriangles > 0){
|
||||
model.triangles = (CColTriangle*)RwMalloc(model.numTriangles*sizeof(CColTriangle));
|
||||
model.triangles = (CColTriangle*)re3StreamingAlloc(model.numTriangles*sizeof(CColTriangle));
|
||||
REGISTER_MEMPTR(&model.triangles);
|
||||
for(i = 0; i < model.numTriangles; i++){
|
||||
model.triangles[i].Set(model.vertices, *(uint16*)buf, *(uint16*)(buf+2), *(uint16*)(buf+4), buf[6], buf[7]);
|
||||
|
@@ -1170,6 +1170,24 @@ bool re3EmergencyRemoveModel() {
|
||||
return usedmem != CStreaming::ms_memoryUsed;
|
||||
}
|
||||
|
||||
void* re3StreamingAlloc(size_t size) {
|
||||
auto rv = RwMalloc(size);
|
||||
|
||||
while (rv == nil) {
|
||||
if (re3RemoveLeastUsedModel()) {
|
||||
rv = RwMalloc(size);
|
||||
continue;
|
||||
}
|
||||
if (re3EmergencyRemoveModel()) {
|
||||
rv = RwMalloc(size);
|
||||
continue;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool
|
||||
CStreaming::RemoveLeastUsedModel(void)
|
||||
{
|
||||
|
@@ -38,6 +38,14 @@ CBaseModelInfo::DeleteCollisionModel(void)
|
||||
}
|
||||
}
|
||||
|
||||
void CBaseModelInfo::SetColModel(CColModel *col, bool owns) {
|
||||
if (m_bOwnsColModel) {
|
||||
delete m_colModel;
|
||||
}
|
||||
m_colModel = col;
|
||||
m_bOwnsColModel = owns;
|
||||
}
|
||||
|
||||
void
|
||||
CBaseModelInfo::AddRef(void)
|
||||
{
|
||||
|
@@ -56,8 +56,7 @@ public:
|
||||
}
|
||||
char *GetModelName(void) { return m_name; }
|
||||
void SetModelName(const char *name) { strncpy(m_name, name, MAX_MODEL_NAME); }
|
||||
void SetColModel(CColModel *col, bool owns = false){
|
||||
m_colModel = col; m_bOwnsColModel = owns; }
|
||||
void SetColModel(CColModel *col, bool owns = false);
|
||||
CColModel *GetColModel(void) { return m_colModel; }
|
||||
bool DoesOwnColModel(void) { return m_bOwnsColModel; }
|
||||
void DeleteCollisionModel(void);
|
||||
|
@@ -197,6 +197,10 @@ CCutsceneHead::PlayAnimation(const char *animName)
|
||||
RwStreamSkip(stream, offset*2048);
|
||||
if(RwStreamFindChunk(stream, rwID_HANIMANIMATION, nil, nil)){
|
||||
anim = RpHAnimAnimationStreamRead(stream);
|
||||
if (hier->interpolator->currentAnim) {
|
||||
RpHAnimAnimationDestroy(hier->interpolator->currentAnim);
|
||||
hier->interpolator->currentAnim = nil;
|
||||
}
|
||||
RpHAnimHierarchySetCurrentAnim(hier, anim);
|
||||
}
|
||||
|
||||
|
@@ -17,6 +17,8 @@
|
||||
|
||||
#include "vmu/vmu.h"
|
||||
|
||||
void* re3StreamingAlloc(size_t size);
|
||||
|
||||
const char* _psGetUserFilesFolder();
|
||||
|
||||
C_PcSave PcSaveHelper;
|
||||
@@ -93,16 +95,17 @@ uint32_t C_PcSave::PcClassLoadRoutine(int32 file, uint8 *data) {
|
||||
return size;
|
||||
} else {
|
||||
size &= ~0x80000000;
|
||||
uint8* compressed = (uint8*)malloc(size);
|
||||
uint8* compressed = (uint8*)re3StreamingAlloc(size);
|
||||
assert(compressed);
|
||||
err = CFileMgr::Read(file, (const char*)compressed, size) != size;
|
||||
if (err || CFileMgr::GetErrorReadWrite(file)) {
|
||||
free(compressed);
|
||||
RwFree(compressed);
|
||||
return 0;
|
||||
}
|
||||
|
||||
lzo_uint decompressed_size = 0;
|
||||
auto crv = lzo1x_decompress(compressed, size, data, &decompressed_size, NULL);
|
||||
free(compressed);
|
||||
RwFree(compressed);
|
||||
if (crv != LZO_E_OK) {
|
||||
return 0;
|
||||
}
|
||||
@@ -117,31 +120,37 @@ uint32_t C_PcSave::PcClassLoadRoutine(int32 file, uint8 *data) {
|
||||
bool
|
||||
C_PcSave::PcClassSaveRoutine(int32 file, uint8 *data, uint32 size)
|
||||
{
|
||||
void* wrkmem = malloc(LZO1X_1_MEM_COMPRESS);
|
||||
uint8* compressed = (uint8*)malloc(size*2);
|
||||
void* wrkmem = re3StreamingAlloc(LZO1X_1_MEM_COMPRESS);
|
||||
assert(wrkmem);
|
||||
uint8* compressed = (uint8*)re3StreamingAlloc(size*2);
|
||||
assert(compressed);
|
||||
lzo_uint compressed_size;
|
||||
int crv = lzo1x_1_compress(data, size, compressed, &compressed_size, wrkmem);
|
||||
free(wrkmem);
|
||||
RwFree(wrkmem);
|
||||
|
||||
if (crv == LZO_E_OK && compressed_size >= size) {
|
||||
crv = LZO_E_NOT_COMPRESSIBLE;
|
||||
}
|
||||
|
||||
if (crv == LZO_E_OK) {
|
||||
uint32_t compressed_size32 = compressed_size | 0x80000000;
|
||||
bool err = CFileMgr::Write(file, (const char*)&compressed_size32, sizeof(compressed_size32)) != sizeof(compressed_size32);
|
||||
if (err || CFileMgr::GetErrorReadWrite(file)) {
|
||||
free(compressed);
|
||||
RwFree(compressed);
|
||||
nErrorCode = SAVESTATUS_ERR_SAVE_WRITE;
|
||||
strncpy(SaveFileNameJustSaved, ValidSaveName, sizeof(ValidSaveName) - 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
err = CFileMgr::Write(file, (const char*)compressed, compressed_size) != compressed_size;
|
||||
free(compressed);
|
||||
RwFree(compressed);
|
||||
if (err || CFileMgr::GetErrorReadWrite(file)) {
|
||||
nErrorCode = SAVESTATUS_ERR_SAVE_WRITE;
|
||||
strncpy(SaveFileNameJustSaved, ValidSaveName, sizeof(ValidSaveName) - 1);
|
||||
return false;
|
||||
}
|
||||
} else if (crv == LZO_E_NOT_COMPRESSIBLE) {
|
||||
free(compressed);
|
||||
RwFree(compressed);
|
||||
uint32_t compressed_size32 = size;
|
||||
bool err = CFileMgr::Write(file, (const char*)&compressed_size32, sizeof(compressed_size32)) != sizeof(compressed_size32);
|
||||
if (err || CFileMgr::GetErrorReadWrite(file)) {
|
||||
@@ -156,7 +165,7 @@ C_PcSave::PcClassSaveRoutine(int32 file, uint8 *data, uint32 size)
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
free(compressed);
|
||||
RwFree(compressed);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@@ -12,6 +12,8 @@
|
||||
#include "AnimManager.h"
|
||||
#include "Streaming.h"
|
||||
|
||||
void* re3StreamingAlloc(size_t size);
|
||||
|
||||
CAnimBlock CAnimManager::ms_aAnimBlocks[NUMANIMBLOCKS];
|
||||
CAnimBlendHierarchy CAnimManager::ms_aAnimations[NUMANIMATIONS];
|
||||
int32 CAnimManager::ms_numAnimBlocks;
|
||||
@@ -1312,7 +1314,7 @@ CAnimManager::LoadAnimFile(RwStream *stream, bool compress, char (*uncompressedA
|
||||
uint16_t flags;
|
||||
RwStreamRead(stream, &flags, sizeof(flags));
|
||||
|
||||
seq->keyFrames = RwMalloc(dataSize);
|
||||
seq->keyFrames = re3StreamingAlloc(dataSize);
|
||||
assert(seq->keyFrames);
|
||||
RwStreamRead(stream, seq->keyFrames, dataSize - sizeof(flags));
|
||||
seq->type = flags;
|
||||
|
@@ -419,7 +419,8 @@ CCutsceneMgr::DeleteCutsceneData(void)
|
||||
CBaseModelInfo *minfo = CModelInfo::GetModelInfo(i);
|
||||
CColModel *colModel = minfo->GetColModel();
|
||||
if (colModel != &CTempColModels::ms_colModelPed1) {
|
||||
delete colModel;
|
||||
// no need to delete anymore, SetColModel will do it (~skmp)
|
||||
//delete colModel;
|
||||
minfo->SetColModel(&CTempColModels::ms_colModelPed1);
|
||||
}
|
||||
}
|
||||
|
@@ -182,6 +182,12 @@ uintptr_t gPlayerTalkData = 0;
|
||||
uint32 gPlayerTalkReqId = 0;
|
||||
#endif
|
||||
|
||||
// this is very wasteful and temporary
|
||||
#define BANK_STAGE_SIZE 16 * 2048
|
||||
static uint8_t stagingBufferBank[BANK_STAGE_SIZE] __attribute__((aligned(32)));
|
||||
std::mutex stagingBufferMtx;
|
||||
|
||||
|
||||
static int32 DCStreamedLength[TOTAL_STREAMED_SOUNDS];
|
||||
|
||||
struct WavHeader {
|
||||
@@ -581,26 +587,29 @@ cSampleManager::LoadSampleBank(uint8 nBank)
|
||||
// TODO: Split per-bank sfx file
|
||||
int fd = fs_open(SampleBankDataFilename, O_RDONLY);
|
||||
assert(fd >= 0);
|
||||
// this is very wasteful and temporary
|
||||
void* stagingBuffer = memalign(32, 8 * 2048);
|
||||
assert(stagingBuffer != 0);
|
||||
|
||||
// Ideally, we'd suspend the CdStream thingy here or read via that instead
|
||||
uintptr_t loadOffset = bank.base;
|
||||
|
||||
fs_seek(fd, fileStart, SEEK_SET);
|
||||
{
|
||||
std::lock_guard lk(stagingBufferMtx); // for stagingBufferBank
|
||||
|
||||
void* stagingBuffer = stagingBufferBank;
|
||||
assert(stagingBuffer != 0);
|
||||
|
||||
while (fileSize > 0) {
|
||||
size_t readSize = fileSize > 8 * 2048 ? 8 * 2048 : fileSize;
|
||||
int rs = fs_read(fd, stagingBuffer, readSize);
|
||||
debugf("Read %d bytes, expected %d\n", rs, readSize);
|
||||
assert(rs == readSize);
|
||||
spu_memload(loadOffset, stagingBuffer, readSize);
|
||||
loadOffset += readSize;
|
||||
fileSize -= readSize;
|
||||
debugf("Loaded %d bytes, %d remaining\n", readSize, fileSize);
|
||||
// Ideally, we'd suspend the CdStream thingy here or read via that instead
|
||||
uintptr_t loadOffset = bank.base;
|
||||
|
||||
while (fileSize > 0) {
|
||||
size_t readSize = fileSize > sizeof(stagingBufferBank) ? sizeof(stagingBufferBank) : fileSize;
|
||||
int rs = fs_read(fd, stagingBuffer, readSize);
|
||||
debugf("Read %d bytes, expected %d\n", rs, readSize);
|
||||
assert(rs == readSize);
|
||||
spu_memload(loadOffset, stagingBuffer, readSize);
|
||||
loadOffset += readSize;
|
||||
fileSize -= readSize;
|
||||
debugf("Loaded %d bytes, %d remaining\n", readSize, fileSize);
|
||||
}
|
||||
}
|
||||
fs_close(fd);
|
||||
free(stagingBuffer);
|
||||
|
||||
|
||||
for (int nSfx = BankStartOffset[nBank]; nSfx < BankStartOffset[nBank+1]; nSfx++) {
|
||||
@@ -693,15 +702,19 @@ cSampleManager::LoadMissionAudio(uint8 nSlot, uint32 nSample)
|
||||
// TODO: When we can dma directly to AICA, we can use this instead
|
||||
// fs_read(fdPedSfx, SPU_BASE_U8 + (uintptr_t)cmd->dest, cmd->size);
|
||||
|
||||
void* stagingBuffer = memalign(32, cmd->size);
|
||||
assert(stagingBuffer != 0);
|
||||
debugf("Allocated %d bytes at %p\n", cmd->size, stagingBuffer);
|
||||
int rs = fs_read(fdPedSfx, stagingBuffer, cmd->size);
|
||||
debugf("Read %d bytes, expected %d\n", rs, cmd->size);
|
||||
assert(rs == cmd->size);
|
||||
|
||||
spu_memload((uintptr_t)cmd->dest, stagingBuffer, cmd->size);
|
||||
free(stagingBuffer);
|
||||
assert(cmd->size < sizeof(stagingBufferBank));
|
||||
{
|
||||
std::lock_guard lk(stagingBufferMtx); // for stagingBufferBank
|
||||
void* stagingBuffer = stagingBufferBank;
|
||||
assert(stagingBuffer != 0);
|
||||
debugf("Allocated %d bytes at %p\n", cmd->size, stagingBuffer);
|
||||
int rs = fs_read(fdPedSfx, stagingBuffer, cmd->size);
|
||||
debugf("Read %d bytes, expected %d\n", rs, cmd->size);
|
||||
assert(rs == cmd->size);
|
||||
|
||||
spu_memload((uintptr_t)cmd->dest, stagingBuffer, cmd->size);
|
||||
}
|
||||
|
||||
nPedSfxReqReadId = nPedSfxReqReadId + 1;
|
||||
});
|
||||
|
||||
@@ -787,15 +800,19 @@ cSampleManager::LoadPedComment(uint32 nComment)
|
||||
// TODO: When we can dma directly to AICA, we can use this instead
|
||||
// fs_read(fdPedSfx, SPU_BASE_U8 + (uintptr_t)cmd->dest, cmd->size);
|
||||
|
||||
void* stagingBuffer = memalign(32, cmd->size);
|
||||
assert(stagingBuffer != 0);
|
||||
debugf("Allocated %d bytes at %p\n", cmd->size, stagingBuffer);
|
||||
int rs = fs_read(fdPedSfx, stagingBuffer, cmd->size);
|
||||
debugf("Read %d bytes, expected %d\n", rs, cmd->size);
|
||||
assert(rs == cmd->size);
|
||||
assert(cmd->size < sizeof(stagingBufferBank));
|
||||
{
|
||||
std::lock_guard lk(stagingBufferMtx); // for stagingBufferBank
|
||||
void* stagingBuffer = stagingBufferBank;
|
||||
assert(stagingBuffer != 0);
|
||||
debugf("Allocated %d bytes at %p\n", cmd->size, stagingBuffer);
|
||||
int rs = fs_read(fdPedSfx, stagingBuffer, cmd->size);
|
||||
debugf("Read %d bytes, expected %d\n", rs, cmd->size);
|
||||
assert(rs == cmd->size);
|
||||
|
||||
spu_memload((uintptr_t)cmd->dest, stagingBuffer, cmd->size);
|
||||
}
|
||||
|
||||
spu_memload((uintptr_t)cmd->dest, stagingBuffer, cmd->size);
|
||||
free(stagingBuffer);
|
||||
nPedSfxReqReadId = nPedSfxReqReadId + 1;
|
||||
});
|
||||
|
||||
@@ -1349,16 +1366,21 @@ cSampleManager::InitialiseSampleBanks(void)
|
||||
for (uint32 nComment = SAMPLEBANK_PED_START; nComment <= SAMPLEBANK_PED_END; nComment++) {
|
||||
pedBlocksizeMax = Max(pedBlocksizeMax, m_aSamples[nComment].nByteSize);
|
||||
}
|
||||
assert(pedBlocksizeMax <= BANK_STAGE_SIZE);
|
||||
debugf("Max ped comment size: %d\n", pedBlocksizeMax);
|
||||
|
||||
#ifdef FIX_BUGS
|
||||
|
||||
// Find biggest player comment
|
||||
uint32 nMaxPlayerSize = 0;
|
||||
for (uint32 i = PLAYER_COMMENTS_START; i <= PLAYER_COMMENTS_END; i++)
|
||||
for (uint32 i = PLAYER_COMMENTS_START; i <= PLAYER_COMMENTS_END; i++) {
|
||||
nMaxPlayerSize = Max(nMaxPlayerSize, m_aSamples[i].nByteSize);
|
||||
}
|
||||
|
||||
debugf("Max player comment size: %d\n", nMaxPlayerSize);
|
||||
|
||||
assert(nMaxPlayerSize < sizeof(stagingBufferBank));
|
||||
|
||||
gPlayerTalkData = snd_mem_malloc(nMaxPlayerSize);
|
||||
ASSERT(gPlayerTalkData != 0);
|
||||
|
||||
|
@@ -5,6 +5,8 @@
|
||||
#include "MemoryHeap.h"
|
||||
#include "Pools.h"
|
||||
|
||||
void* re3StreamingAlloc(size_t size);
|
||||
|
||||
CColModel::CColModel(void)
|
||||
{
|
||||
numSpheres = 0;
|
||||
@@ -43,13 +45,13 @@ CColModel::operator delete(void *p, size_t) throw()
|
||||
void
|
||||
CColModel::RemoveCollisionVolumes(void)
|
||||
{
|
||||
CCollision::RemoveTrianglePlanes(this);
|
||||
if(ownsCollisionVolumes){
|
||||
RwFree(spheres);
|
||||
RwFree(lines);
|
||||
RwFree(boxes);
|
||||
RwFree(vertices);
|
||||
RwFree(triangles);
|
||||
CCollision::RemoveTrianglePlanes(this);
|
||||
}
|
||||
numSpheres = 0;
|
||||
numLines = 0;
|
||||
@@ -109,6 +111,8 @@ CColModel::operator=(const CColModel &other)
|
||||
int i;
|
||||
int numVerts;
|
||||
|
||||
CCollision::RemoveTrianglePlanes(this);
|
||||
|
||||
boundingSphere = other.boundingSphere;
|
||||
boundingBox = other.boundingBox;
|
||||
|
||||
@@ -179,7 +183,7 @@ CColModel::operator=(const CColModel &other)
|
||||
if(vertices)
|
||||
RwFree(vertices);
|
||||
if(numVerts){
|
||||
vertices = (CompressedVector*)RwMalloc(numVerts*sizeof(CompressedVector));
|
||||
vertices = (CompressedVector*)re3StreamingAlloc(numVerts*sizeof(CompressedVector));
|
||||
for(i = 0; i < numVerts; i++)
|
||||
vertices[i] = other.vertices[i];
|
||||
}
|
||||
@@ -189,7 +193,7 @@ CColModel::operator=(const CColModel &other)
|
||||
numTriangles = other.numTriangles;
|
||||
if(triangles)
|
||||
RwFree(triangles);
|
||||
triangles = (CColTriangle*)RwMalloc(numTriangles*sizeof(CColTriangle));
|
||||
triangles = (CColTriangle*)re3StreamingAlloc(numTriangles*sizeof(CColTriangle));
|
||||
}
|
||||
for(i = 0; i < numTriangles; i++)
|
||||
triangles[i] = other.triangles[i];
|
||||
|
@@ -30,6 +30,8 @@
|
||||
#include "ColStore.h"
|
||||
#include "Occlusion.h"
|
||||
|
||||
void* re3StreamingAlloc(size_t size);
|
||||
|
||||
char CFileLoader::ms_line[256];
|
||||
|
||||
const char*
|
||||
@@ -303,6 +305,24 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
|
||||
model.boundingBox.max.z = *(float*)(buf+36);
|
||||
model.numSpheres = *(int16*)(buf+40);
|
||||
buf += 44;
|
||||
if (model.spheres) {
|
||||
RwFree(model.spheres);
|
||||
}
|
||||
if (model.lines) {
|
||||
RwFree(model.lines);
|
||||
}
|
||||
if (model.boxes) {
|
||||
RwFree(model.boxes);
|
||||
}
|
||||
if (model.vertices) {
|
||||
RwFree(model.vertices);
|
||||
}
|
||||
if (model.triangles) {
|
||||
RwFree(model.triangles);
|
||||
}
|
||||
if (model.trianglePlanes) {
|
||||
CCollision::RemoveTrianglePlanes(&model);
|
||||
}
|
||||
if(model.numSpheres > 0){
|
||||
model.spheres = (CColSphere*)RwMalloc(model.numSpheres*sizeof(CColSphere));
|
||||
REGISTER_MEMPTR(&model.spheres);
|
||||
@@ -360,7 +380,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
|
||||
model.numTriangles = *(int16*)buf;
|
||||
buf += 4;
|
||||
if(model.numTriangles > 0){
|
||||
model.triangles = (CColTriangle*)RwMalloc(model.numTriangles*sizeof(CColTriangle));
|
||||
model.triangles = (CColTriangle*)re3StreamingAlloc(model.numTriangles*sizeof(CColTriangle));
|
||||
REGISTER_MEMPTR(&model.triangles);
|
||||
for(i = 0; i < model.numTriangles; i++){
|
||||
model.triangles[i].Set(*(uint16*)buf, *(uint16*)(buf+2), *(uint16*)(buf+4), buf[6]);
|
||||
|
@@ -1386,6 +1386,24 @@ bool re3EmergencyRemoveModel() {
|
||||
return usedmem != CStreaming::ms_memoryUsed;
|
||||
}
|
||||
|
||||
void* re3StreamingAlloc(size_t size) {
|
||||
auto rv = RwMalloc(size);
|
||||
|
||||
while (rv == nil) {
|
||||
if (re3RemoveLeastUsedModel()) {
|
||||
rv = RwMalloc(size);
|
||||
continue;
|
||||
}
|
||||
if (re3EmergencyRemoveModel()) {
|
||||
rv = RwMalloc(size);
|
||||
continue;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool
|
||||
CStreaming::RemoveLeastUsedModel(uint32 excludeMask)
|
||||
{
|
||||
|
@@ -40,6 +40,14 @@ CBaseModelInfo::DeleteCollisionModel(void)
|
||||
}
|
||||
}
|
||||
|
||||
void CBaseModelInfo::SetColModel(CColModel *col, bool owns) {
|
||||
if (m_bOwnsColModel) {
|
||||
delete m_colModel;
|
||||
}
|
||||
m_colModel = col;
|
||||
m_bOwnsColModel = owns;
|
||||
}
|
||||
|
||||
void
|
||||
CBaseModelInfo::AddRef(void)
|
||||
{
|
||||
|
@@ -52,8 +52,7 @@ public:
|
||||
bool IsClump(void) { return m_type == MITYPE_CLUMP || m_type == MITYPE_PED || m_type == MITYPE_VEHICLE; }
|
||||
char *GetModelName(void) { return m_name; }
|
||||
void SetModelName(const char *name) { strncpy(m_name, name, MAX_MODEL_NAME); }
|
||||
void SetColModel(CColModel *col, bool owns = false){
|
||||
m_colModel = col; m_bOwnsColModel = owns; }
|
||||
void SetColModel(CColModel *col, bool owns = false);
|
||||
CColModel *GetColModel(void) { return m_colModel; }
|
||||
bool DoesOwnColModel(void) { return m_bOwnsColModel; }
|
||||
void DeleteCollisionModel(void);
|
||||
|
@@ -271,13 +271,13 @@ CShadowCamera::InvertRaster()
|
||||
RwIm2DVertexSetIntRGBA (&vx[1], 255, 255, 255, 255);
|
||||
|
||||
RwIm2DVertexSetScreenX (&vx[2], crw);
|
||||
RwIm2DVertexSetScreenY (&vx[2], 0.0f);
|
||||
RwIm2DVertexSetScreenY (&vx[2], crh);
|
||||
RwIm2DVertexSetScreenZ (&vx[2], RwIm2DGetNearScreenZ());
|
||||
RwIm2DVertexSetRecipCameraZ(&vx[2], recipZ);
|
||||
RwIm2DVertexSetIntRGBA (&vx[2], 255, 255, 255, 255);
|
||||
|
||||
RwIm2DVertexSetScreenX (&vx[3], crw);
|
||||
RwIm2DVertexSetScreenY (&vx[3], crh);
|
||||
RwIm2DVertexSetScreenY (&vx[3], 0.0f);
|
||||
RwIm2DVertexSetScreenZ (&vx[3], RwIm2DGetNearScreenZ());
|
||||
RwIm2DVertexSetRecipCameraZ(&vx[3], recipZ);
|
||||
RwIm2DVertexSetIntRGBA (&vx[3], 255, 255, 255, 255);
|
||||
@@ -289,7 +289,7 @@ CShadowCamera::InvertRaster()
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDINVDESTCOLOR);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDZERO);
|
||||
|
||||
RwIm2DRenderPrimitive(rwPRIMTYPETRISTRIP, vx, 4);
|
||||
RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, vx, 4);
|
||||
|
||||
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
|
||||
|
@@ -384,23 +384,23 @@ RwBool Im2DRenderQuad(RwReal x1, RwReal y1, RwReal x2, RwReal y2, RwReal z, RwRe
|
||||
RwIm2DVertexSetU(&vx[1], uvOffset, recipCamZ);
|
||||
RwIm2DVertexSetV(&vx[1], 1.0f + uvOffset, recipCamZ);
|
||||
|
||||
RwIm2DVertexSetScreenX(&vx[2], x2);
|
||||
RwIm2DVertexSetScreenY(&vx[2], y1);
|
||||
RwIm2DVertexSetScreenX(&vx[2], x2);
|
||||
RwIm2DVertexSetScreenY(&vx[2], y2);
|
||||
RwIm2DVertexSetScreenZ(&vx[2], z);
|
||||
RwIm2DVertexSetIntRGBA(&vx[2], 255, 255, 255, 255);
|
||||
RwIm2DVertexSetRecipCameraZ(&vx[2], recipCamZ);
|
||||
RwIm2DVertexSetU(&vx[2], 1.0f + uvOffset, recipCamZ);
|
||||
RwIm2DVertexSetV(&vx[2], uvOffset, recipCamZ);
|
||||
|
||||
RwIm2DVertexSetV(&vx[2], 1.0f + uvOffset, recipCamZ);
|
||||
|
||||
RwIm2DVertexSetScreenX(&vx[3], x2);
|
||||
RwIm2DVertexSetScreenY(&vx[3], y2);
|
||||
RwIm2DVertexSetScreenY(&vx[3], y1);
|
||||
RwIm2DVertexSetScreenZ(&vx[3], z);
|
||||
RwIm2DVertexSetIntRGBA(&vx[3], 255, 255, 255, 255);
|
||||
RwIm2DVertexSetRecipCameraZ(&vx[3], recipCamZ);
|
||||
RwIm2DVertexSetU(&vx[3], 1.0f + uvOffset, recipCamZ);
|
||||
RwIm2DVertexSetV(&vx[3], 1.0f + uvOffset, recipCamZ);
|
||||
RwIm2DVertexSetV(&vx[3], uvOffset, recipCamZ);
|
||||
|
||||
RwIm2DRenderPrimitive(rwPRIMTYPETRISTRIP, vx, 4);
|
||||
RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, vx, 4);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@@ -17,6 +17,8 @@
|
||||
|
||||
#include "vmu/vmu.h"
|
||||
|
||||
void* re3StreamingAlloc(size_t size);
|
||||
|
||||
const char* _psGetUserFilesFolder();
|
||||
|
||||
C_PcSave PcSaveHelper;
|
||||
@@ -76,31 +78,37 @@ C_PcSave::SaveSlot(int32 slot)
|
||||
bool
|
||||
C_PcSave::PcClassSaveRoutine(int32 file, uint8 *data, uint32 size)
|
||||
{
|
||||
void* wrkmem = malloc(LZO1X_1_MEM_COMPRESS);
|
||||
uint8* compressed = (uint8*)malloc(size*2);
|
||||
void* wrkmem = re3StreamingAlloc(LZO1X_1_MEM_COMPRESS);
|
||||
assert(wrkmem);
|
||||
uint8* compressed = (uint8*)re3StreamingAlloc(size*2);
|
||||
assert(compressed);
|
||||
lzo_uint compressed_size;
|
||||
int crv = lzo1x_1_compress(data, size, compressed, &compressed_size, wrkmem);
|
||||
free(wrkmem);
|
||||
RwFree(wrkmem);
|
||||
|
||||
if (crv == LZO_E_OK && compressed_size >= size) {
|
||||
crv = LZO_E_NOT_COMPRESSIBLE;
|
||||
}
|
||||
|
||||
if (crv == LZO_E_OK) {
|
||||
uint32_t compressed_size32 = compressed_size | 0x80000000;
|
||||
bool err = CFileMgr::Write(file, (const char*)&compressed_size32, sizeof(compressed_size32)) != sizeof(compressed_size32);
|
||||
if (err || CFileMgr::GetErrorReadWrite(file)) {
|
||||
free(compressed);
|
||||
RwFree(compressed);
|
||||
nErrorCode = SAVESTATUS_ERR_SAVE_WRITE;
|
||||
strncpy(SaveFileNameJustSaved, ValidSaveName, sizeof(ValidSaveName) - 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
err = CFileMgr::Write(file, (const char*)compressed, compressed_size) != compressed_size;
|
||||
free(compressed);
|
||||
RwFree(compressed);
|
||||
if (err || CFileMgr::GetErrorReadWrite(file)) {
|
||||
nErrorCode = SAVESTATUS_ERR_SAVE_WRITE;
|
||||
strncpy(SaveFileNameJustSaved, ValidSaveName, sizeof(ValidSaveName) - 1);
|
||||
return false;
|
||||
}
|
||||
} else if (crv == LZO_E_NOT_COMPRESSIBLE) {
|
||||
free(compressed);
|
||||
RwFree(compressed);
|
||||
uint32_t compressed_size32 = size;
|
||||
bool err = CFileMgr::Write(file, (const char*)&compressed_size32, sizeof(compressed_size32)) != sizeof(compressed_size32);
|
||||
if (err || CFileMgr::GetErrorReadWrite(file)) {
|
||||
@@ -115,7 +123,7 @@ C_PcSave::PcClassSaveRoutine(int32 file, uint8 *data, uint32 size)
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
free(compressed);
|
||||
RwFree(compressed);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -153,16 +161,17 @@ uint32_t C_PcSave::PcClassLoadRoutine(int32 file, uint8 *data) {
|
||||
return size;
|
||||
} else {
|
||||
size &= ~0x80000000;
|
||||
uint8* compressed = (uint8*)malloc(size);
|
||||
uint8* compressed = (uint8*)re3StreamingAlloc(size);
|
||||
assert(compressed);
|
||||
err = CFileMgr::Read(file, (const char*)compressed, size) != size;
|
||||
if (err || CFileMgr::GetErrorReadWrite(file)) {
|
||||
free(compressed);
|
||||
RwFree(compressed);
|
||||
return 0;
|
||||
}
|
||||
|
||||
lzo_uint decompressed_size = 0;
|
||||
auto crv = lzo1x_decompress(compressed, size, data, &decompressed_size, NULL);
|
||||
free(compressed);
|
||||
RwFree(compressed);
|
||||
if (crv != LZO_E_OK) {
|
||||
return 0;
|
||||
}
|
||||
|
@@ -53,6 +53,9 @@ uint32_t pvr_map32(uint32_t offset32) {return 0;}
|
||||
void Hackpresent() { }
|
||||
void re3RemoveLeastUsedModel() { assert(false); }
|
||||
void re3EmergencyRemoveModel() { assert(false); }
|
||||
void* re3StreamingAlloc(size_t sz) {
|
||||
return RwMalloc(sz);
|
||||
}
|
||||
void RwTexDictionaryGtaStreamRead1(rw::Stream*){ assert(false); }
|
||||
void RwTexDictionaryGtaStreamRead2(rw::Stream*, rw::TexDictionary*) { assert(false); }
|
||||
void pvr_ta_data(void* data, int size) {
|
||||
|
2
vendor/emu/emu/window.cpp
vendored
2
vendor/emu/emu/window.cpp
vendored
@@ -125,6 +125,8 @@ void x11_window_create()
|
||||
x11_win = (void*)x11Window;
|
||||
x11_vis = (void*)x11Visual->visual;
|
||||
|
||||
delete x11Visual;
|
||||
|
||||
x11_window_set_text("GTA3dc");
|
||||
}
|
||||
|
||||
|
1
vendor/librw/src/anim.cpp
vendored
1
vendor/librw/src/anim.cpp
vendored
@@ -221,6 +221,7 @@ AnimInterpolator::setCurrentAnim(Animation *anim)
|
||||
{
|
||||
int32 i;
|
||||
AnimInterpolatorInfo *interpInfo = anim->interpInfo;
|
||||
assert(this->currentAnim == nil || this->currentAnim == anim);
|
||||
this->currentAnim = anim;
|
||||
this->currentTime = 0.0f;
|
||||
int32 maxkf = this->maxInterpKeyFrameSize;
|
||||
|
880
vendor/librw/src/dc/rwdc.cpp
vendored
880
vendor/librw/src/dc/rwdc.cpp
vendored
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user