mirror of
https://gitlab.com/ryandwyer/perfect-dark
synced 2026-07-08 13:06:13 -04:00
Tighten up model rwdata cache
This commit is contained in:
@@ -1767,7 +1767,6 @@ void lvTick(void)
|
||||
sndTick();
|
||||
pakExecuteDebugOperations();
|
||||
lightingTick();
|
||||
modelmgrPrintCounts();
|
||||
boltbeamsTick();
|
||||
amTick();
|
||||
menuTick();
|
||||
|
||||
+23
-98
@@ -15,6 +15,12 @@ struct modelrwdatabinding *g_ModelRwdataBindings[3];
|
||||
|
||||
s32 g_MaxModels = 0;
|
||||
s32 g_MaxAnims = 0;
|
||||
s32 g_MaxRwdataType1 = 0;
|
||||
s32 g_MaxRwdataType2 = 0;
|
||||
s32 g_MaxRwdataType3 = 0;
|
||||
s32 g_Rwdata1EntrySizeInWords = 0;
|
||||
s32 g_Rwdata2EntrySizeInWords = 0;
|
||||
s32 g_Rwdata3EntrySizeInWords = 0;
|
||||
bool g_ModelIsLvResetting = false;
|
||||
s32 g_ModelMostType1 = 0;
|
||||
s32 g_ModelMostType2 = 0;
|
||||
@@ -22,86 +28,12 @@ s32 g_ModelMostType3 = 0;
|
||||
s32 g_ModelMostModels = 0;
|
||||
s32 g_ModelMostAnims = 0;
|
||||
|
||||
#define NUMTYPE1() (IS4MB() ? 0 : 35)
|
||||
#define NUMTYPE2() (IS4MB() ? 24 : 25)
|
||||
#define NUMTYPE3() (IS4MB() ? 0 : 20)
|
||||
|
||||
bool modelmgrCanSlotFitRwdata(struct model *modelslot, struct modelfiledata *modeldef)
|
||||
{
|
||||
return modeldef->rwdatalen <= 0
|
||||
|| (modelslot->rwdatas != NULL && modelslot->rwdatalen >= modeldef->rwdatalen);
|
||||
}
|
||||
|
||||
void modelmgrPrintCounts(void)
|
||||
{
|
||||
s32 i;
|
||||
s32 numtype1 = 0;
|
||||
s32 numtype2 = 0;
|
||||
s32 numtype3 = 0;
|
||||
s32 nummodels = 0;
|
||||
s32 numanims = 0;
|
||||
|
||||
for (i = 0; i < NUMTYPE1(); i++) {
|
||||
if (g_ModelRwdataBindings[0][i].model) {
|
||||
numtype1++;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < NUMTYPE2(); i++) {
|
||||
if (g_ModelRwdataBindings[1][i].model) {
|
||||
numtype2++;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < NUMTYPE3(); i++) {
|
||||
if (g_ModelRwdataBindings[2][i].model) {
|
||||
numtype3++;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < g_MaxModels; i++) {
|
||||
if (g_ModelSlots[i].filedata) {
|
||||
nummodels++;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < g_MaxAnims; i++) {
|
||||
if (g_AnimSlots[i].animnum != -1) {
|
||||
numanims++;
|
||||
}
|
||||
}
|
||||
|
||||
if (numtype1 > g_ModelMostType1) {
|
||||
g_ModelMostType1 = numtype1;
|
||||
}
|
||||
|
||||
if (numtype2 > g_ModelMostType2) {
|
||||
g_ModelMostType2 = numtype2;
|
||||
}
|
||||
|
||||
if (numtype3 > g_ModelMostType3) {
|
||||
g_ModelMostType3 = numtype3;
|
||||
}
|
||||
|
||||
if (nummodels > g_ModelMostModels) {
|
||||
g_ModelMostModels = nummodels;
|
||||
}
|
||||
|
||||
if (numanims > g_ModelMostAnims) {
|
||||
g_ModelMostAnims = numanims;
|
||||
}
|
||||
|
||||
osSyncPrintf("MOT : Type 1 = %d/%d (%d)");
|
||||
osSyncPrintf("MOT : Type 2 = %d/%d (%d)");
|
||||
osSyncPrintf("MOT : Type 3 = %d/%d (%d)");
|
||||
osSyncPrintf("MOT : Type OI = %d/%d/%d/%d");
|
||||
osSyncPrintf("MOT : Type OA = %d/%d/%d/%d");
|
||||
osSyncPrintf("MOT : g_ObjCount = %d");
|
||||
osSyncPrintf("MOT : g_AnimCount = %d");
|
||||
|
||||
if (IS4MB());
|
||||
}
|
||||
|
||||
struct model *modelmgrInstantiateModel(struct modelfiledata *modeldef, bool withanim)
|
||||
{
|
||||
struct model *model = NULL;
|
||||
@@ -146,13 +78,13 @@ struct model *modelmgrInstantiateModel(struct modelfiledata *modeldef, bool with
|
||||
} else {
|
||||
// At this point, it's during gameplay. A model instance slot has
|
||||
// been found or allocated, but rwdata needs to be allocated.
|
||||
if (modeldef->rwdatalen < 256) {
|
||||
if (modeldef->rwdatalen < g_Rwdata3EntrySizeInWords) {
|
||||
bool done = false;
|
||||
u32 stack;
|
||||
|
||||
// 4 words (0x10 bytes) or less -> try type 1
|
||||
if (modeldef->rwdatalen <= 4) {
|
||||
for (i = 0; i < NUMTYPE1(); i++) {
|
||||
// Try type 1
|
||||
if (modeldef->rwdatalen <= g_Rwdata1EntrySizeInWords) {
|
||||
for (i = 0; i < g_MaxRwdataType1; i++) {
|
||||
if (g_ModelRwdataBindings[0][i].model == NULL) {
|
||||
osSyncPrintf("MotInst: Using cache entry type 1 %d (0x%08x) - Bytes=%d\n");
|
||||
rwdatas = g_ModelRwdataBindings[0][i].rwdata;
|
||||
@@ -163,12 +95,11 @@ struct model *modelmgrInstantiateModel(struct modelfiledata *modeldef, bool with
|
||||
}
|
||||
}
|
||||
|
||||
// 52 words (0xd0 bytes) or less -> try type 2
|
||||
if (!done && modeldef->rwdatalen <= 52) {
|
||||
for (i = 0; i < NUMTYPE2(); i++) {
|
||||
// Try type 2
|
||||
if (!done && modeldef->rwdatalen <= g_Rwdata2EntrySizeInWords) {
|
||||
for (i = 0; i < g_MaxRwdataType2; i++) {
|
||||
if (g_ModelRwdataBindings[1][i].model == NULL) {
|
||||
osSyncPrintf("MotInst: Using cache entry type 2 %d (0x%08x) - Bytes=%d\n");
|
||||
if (IS4MB());
|
||||
rwdatas = g_ModelRwdataBindings[1][i].rwdata;
|
||||
g_ModelRwdataBindings[1][i].model = model;
|
||||
done = true;
|
||||
@@ -177,13 +108,12 @@ struct model *modelmgrInstantiateModel(struct modelfiledata *modeldef, bool with
|
||||
}
|
||||
}
|
||||
|
||||
// 256 words (0x400 bytes) or less -> try type 3
|
||||
// Try type 3
|
||||
// First looking for unused slots with an existing rwdata allocation
|
||||
if (!done && modeldef->rwdatalen <= 256) {
|
||||
for (i = 0; i < NUMTYPE3(); i++) {
|
||||
if (!done && modeldef->rwdatalen <= g_Rwdata3EntrySizeInWords) {
|
||||
for (i = 0; i < g_MaxRwdataType3; i++) {
|
||||
if (g_ModelRwdataBindings[2][i].model == NULL && g_ModelRwdataBindings[2][i].rwdata != NULL) {
|
||||
osSyncPrintf("MotInst: Using cache entry type 3 %d (0x%08x) - Bytes=%d\n");
|
||||
if (IS4MB());
|
||||
rwdatas = g_ModelRwdataBindings[2][i].rwdata;
|
||||
g_ModelRwdataBindings[2][i].model = model;
|
||||
done = true;
|
||||
@@ -193,10 +123,10 @@ struct model *modelmgrInstantiateModel(struct modelfiledata *modeldef, bool with
|
||||
}
|
||||
|
||||
// Type 3 again, but looking for null rwdata allocations
|
||||
if (!done && modeldef->rwdatalen <= 256) {
|
||||
for (i = 0; i < NUMTYPE3(); i++) {
|
||||
if (!done && modeldef->rwdatalen <= g_Rwdata3EntrySizeInWords) {
|
||||
for (i = 0; i < g_MaxRwdataType3; i++) {
|
||||
if (g_ModelRwdataBindings[2][i].model == NULL && g_ModelRwdataBindings[2][i].rwdata == NULL) {
|
||||
g_ModelRwdataBindings[2][i].rwdata = mempAlloc(256 * 4, MEMPOOL_STAGE);
|
||||
g_ModelRwdataBindings[2][i].rwdata = mempAlloc(g_Rwdata3EntrySizeInWords * 4, MEMPOOL_STAGE);
|
||||
rwdatas = g_ModelRwdataBindings[2][i].rwdata;
|
||||
g_ModelRwdataBindings[2][i].model = model;
|
||||
break;
|
||||
@@ -207,11 +137,7 @@ struct model *modelmgrInstantiateModel(struct modelfiledata *modeldef, bool with
|
||||
// empty
|
||||
}
|
||||
|
||||
if (withanim) {
|
||||
datalen = 256;
|
||||
} else {
|
||||
datalen = IS4MB() ? 52 : 256;
|
||||
}
|
||||
datalen = 256;
|
||||
|
||||
if (datalen < modeldef->rwdatalen) {
|
||||
datalen = modeldef->rwdatalen;
|
||||
@@ -259,7 +185,7 @@ void modelmgrFreeModel(struct model *model)
|
||||
bool done = false;
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < NUMTYPE1(); i++) {
|
||||
for (i = 0; i < g_MaxRwdataType1; i++) {
|
||||
if (g_ModelRwdataBindings[0][i].model == model) {
|
||||
g_ModelRwdataBindings[0][i].model = NULL;
|
||||
|
||||
@@ -272,12 +198,11 @@ void modelmgrFreeModel(struct model *model)
|
||||
}
|
||||
|
||||
if (!done) {
|
||||
for (i = 0; i < NUMTYPE2(); i++) {
|
||||
for (i = 0; i < g_MaxRwdataType2; i++) {
|
||||
if (g_ModelRwdataBindings[1][i].model == model) {
|
||||
osSyncPrintf("\nMotInst: Freeing type 2 cache entry %d (0x%08x)\n\n");
|
||||
|
||||
g_ModelRwdataBindings[1][i].model = NULL;
|
||||
|
||||
model->rwdatas = NULL;
|
||||
model->rwdatalen = -1;
|
||||
|
||||
@@ -288,7 +213,7 @@ void modelmgrFreeModel(struct model *model)
|
||||
}
|
||||
|
||||
if (!done) {
|
||||
for (i = 0; i < NUMTYPE3(); i++) {
|
||||
for (i = 0; i < g_MaxRwdataType3; i++) {
|
||||
if (g_ModelRwdataBindings[2][i].model == model) {
|
||||
osSyncPrintf("\nMotInst: Freeing type 3 cache entry %d (0x%08x)\n\n");
|
||||
g_ModelRwdataBindings[2][i].model = NULL;
|
||||
|
||||
+54
-30
@@ -23,10 +23,12 @@
|
||||
#include "data.h"
|
||||
#include "types.h"
|
||||
|
||||
#define NUMTYPE1() (IS4MB() ? 0 : 35)
|
||||
#define NUMTYPE2() (IS4MB() ? 24 : 25)
|
||||
#define NUMTYPE3() (IS4MB() ? 0 : 20)
|
||||
#define NUMSPARE() (IS4MB() ? 40 : 60)
|
||||
extern s32 g_MaxRwdataType1;
|
||||
extern s32 g_MaxRwdataType2;
|
||||
extern s32 g_MaxRwdataType3;
|
||||
extern s32 g_Rwdata1EntrySizeInWords;
|
||||
extern s32 g_Rwdata2EntrySizeInWords;
|
||||
extern s32 g_Rwdata3EntrySizeInWords;
|
||||
|
||||
void modelmgrReset(void)
|
||||
{
|
||||
@@ -56,7 +58,7 @@ void modelmgrSetLvResetting(bool value)
|
||||
* (eg. for thrown weapons), and a further 20 model and 20 anim slots are
|
||||
* allocated for animated objects.
|
||||
*/
|
||||
void modelmgrAllocateSlots(s32 numobjs, s32 numchrs)
|
||||
void modelmgrAllocateSlots(s32 numobjs, s32 numchrs, bool haslaptops)
|
||||
{
|
||||
s32 rwdata2sizetotal;
|
||||
s32 rwdata1sizetotal;
|
||||
@@ -67,25 +69,47 @@ void modelmgrAllocateSlots(s32 numobjs, s32 numchrs)
|
||||
s32 totalsize;
|
||||
s32 modelssize;
|
||||
s32 animssize;
|
||||
s32 rwdata1sizeeach = 0x10;
|
||||
s32 rwdata2sizeeach = 0xd0;
|
||||
s32 rwdata3sizeeach = 0;
|
||||
s32 maxanimatedobjs = 20;
|
||||
s32 numspare;
|
||||
|
||||
g_ModelNumObjs = numobjs;
|
||||
g_ModelNumChrs = numchrs;
|
||||
|
||||
numspare = NUMSPARE();
|
||||
g_MaxModels = numobjs + numspare + numchrs + maxanimatedobjs;
|
||||
g_MaxAnims = numchrs + maxanimatedobjs;
|
||||
if (g_Vars.stagenum == STAGE_TITLE) {
|
||||
g_MaxRwdataType1 = 35;
|
||||
g_MaxRwdataType2 = 25;
|
||||
g_MaxRwdataType3 = 20;
|
||||
g_Rwdata1EntrySizeInWords = 4;
|
||||
g_Rwdata2EntrySizeInWords = 52;
|
||||
g_Rwdata3EntrySizeInWords = 0;
|
||||
|
||||
i = NUMTYPE2();
|
||||
bindingssize = (NUMTYPE1() + i + NUMTYPE3()) * sizeof(struct modelrwdatabinding);
|
||||
g_MaxModels = 60;
|
||||
g_MaxAnims = 20;
|
||||
} else {
|
||||
g_Rwdata1EntrySizeInWords = 3;
|
||||
g_Rwdata2EntrySizeInWords = 10;
|
||||
g_Rwdata3EntrySizeInWords = 0;
|
||||
|
||||
rwdata1sizetotal = NUMTYPE1() * rwdata1sizeeach;
|
||||
rwdata2sizetotal = NUMTYPE2() * rwdata2sizeeach;
|
||||
rwdata3sizetotal = NUMTYPE3() * rwdata3sizeeach;
|
||||
// Type 1 will be used for third person gun models.
|
||||
// Chrs can equip two guns, and we need to consider dropped items too.
|
||||
// Guns that spawn on the ground store their rwdata elsewhere.
|
||||
g_MaxRwdataType1 = numchrs * 2 + MAX_DROPPED_ITEMS;
|
||||
|
||||
// Each deployed laptop uses 10 slots of rwdata
|
||||
g_MaxRwdataType2 = haslaptops ? numchrs : 0;
|
||||
|
||||
// Type 3 is allocated on the fly and shouldn't happen,
|
||||
// but if it does these slots will track the model-rwdata bindings
|
||||
// and hopefully prevent any memory leaks.
|
||||
g_MaxRwdataType3 = 20;
|
||||
|
||||
g_MaxModels = numobjs + numchrs + MAX_DROPPED_ITEMS;
|
||||
g_MaxAnims = numchrs;
|
||||
}
|
||||
|
||||
bindingssize = (g_MaxRwdataType1 + g_MaxRwdataType2 + g_MaxRwdataType3) * sizeof(struct modelrwdatabinding);
|
||||
|
||||
rwdata1sizetotal = g_MaxRwdataType1 * g_Rwdata1EntrySizeInWords * 4;
|
||||
rwdata2sizetotal = g_MaxRwdataType2 * g_Rwdata2EntrySizeInWords * 4;
|
||||
rwdata3sizetotal = g_MaxRwdataType3 * g_Rwdata3EntrySizeInWords * 4;
|
||||
|
||||
modelssize = ALIGN16(g_MaxModels * sizeof(struct model));
|
||||
animssize = ALIGN16(g_MaxAnims * sizeof(struct anim));
|
||||
@@ -98,19 +122,19 @@ void modelmgrAllocateSlots(s32 numobjs, s32 numchrs)
|
||||
|
||||
ptr = mempAlloc(totalsize, MEMPOOL_STAGE);
|
||||
|
||||
if (NUMTYPE1()) {
|
||||
if (g_MaxRwdataType1) {
|
||||
g_ModelRwdataBindings[0] = (struct modelrwdatabinding *) ptr;
|
||||
ptr += NUMTYPE1() * 8;
|
||||
ptr += g_MaxRwdataType1 * 8;
|
||||
}
|
||||
|
||||
if (NUMTYPE2()) {
|
||||
if (g_MaxRwdataType2) {
|
||||
g_ModelRwdataBindings[1] = (struct modelrwdatabinding *) ptr;
|
||||
ptr += NUMTYPE2() * 8;
|
||||
ptr += g_MaxRwdataType2 * 8;
|
||||
}
|
||||
|
||||
if (NUMTYPE3()) {
|
||||
if (g_MaxRwdataType3) {
|
||||
g_ModelRwdataBindings[2] = (struct modelrwdatabinding *) ptr;
|
||||
ptr += NUMTYPE3() * 8;
|
||||
ptr += g_MaxRwdataType3 * 8;
|
||||
}
|
||||
|
||||
g_ModelSlots = (struct model *) ptr;
|
||||
@@ -118,25 +142,25 @@ void modelmgrAllocateSlots(s32 numobjs, s32 numchrs)
|
||||
g_AnimSlots = (struct anim *) ptr;
|
||||
ptr += animssize;
|
||||
|
||||
for (i = 0; i < NUMTYPE1(); i++) {
|
||||
for (i = 0; i < g_MaxRwdataType1; i++) {
|
||||
g_ModelRwdataBindings[0][i].rwdata = ptr;
|
||||
g_ModelRwdataBindings[0][i].model = NULL;
|
||||
|
||||
ptr += rwdata1sizeeach;
|
||||
ptr += g_Rwdata1EntrySizeInWords * 4;
|
||||
}
|
||||
|
||||
for (i = 0; i < NUMTYPE2(); i++) {
|
||||
for (i = 0; i < g_MaxRwdataType2; i++) {
|
||||
g_ModelRwdataBindings[1][i].rwdata = ptr;
|
||||
g_ModelRwdataBindings[1][i].model = NULL;
|
||||
|
||||
ptr += rwdata2sizeeach;
|
||||
ptr += g_Rwdata2EntrySizeInWords * 4;
|
||||
}
|
||||
|
||||
for (i = 0; i < NUMTYPE3(); i++) {
|
||||
for (i = 0; i < g_MaxRwdataType3; i++) {
|
||||
g_ModelRwdataBindings[2][i].rwdata = NULL;
|
||||
g_ModelRwdataBindings[2][i].model = NULL;
|
||||
|
||||
ptr += rwdata3sizeeach;
|
||||
ptr += g_Rwdata3EntrySizeInWords * 4;
|
||||
}
|
||||
|
||||
for (i = 0; i < g_MaxModels; i++) {
|
||||
|
||||
+1
-1
@@ -845,7 +845,7 @@ void setupAllocateEverything(void)
|
||||
g_NumBots = setupCalculateMaxBots(numbotsrequested, haslaptops);
|
||||
|
||||
// Allocate everything
|
||||
modelmgrAllocateSlots(g_ModelNumObjs, PLAYERCOUNT() + g_NumBots);
|
||||
modelmgrAllocateSlots(g_ModelNumObjs, PLAYERCOUNT() + g_NumBots, haslaptops);
|
||||
|
||||
g_Vars.maxprops += PLAYERCOUNT() + g_NumBots;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
void modelmgrReset(void);
|
||||
void modelmgrSetLvResetting(bool value);
|
||||
void modelmgrAllocateSlots(s32 numobjs, s32 numchrs);
|
||||
void modelmgrAllocateSlots(s32 numobjs, s32 numchrs, bool haslaptops);
|
||||
bool modelmgrLoadProjectileModeldefs(s32 weaponnum);
|
||||
void playerInitEyespy(void);
|
||||
void playerReset(void);
|
||||
|
||||
Reference in New Issue
Block a user