Document vtxstores
This commit is contained in:
parent
62e9f4d1a6
commit
b7c4828289
|
@ -1395,7 +1395,7 @@ void chr_remove(struct prop *prop, bool free)
|
|||
wallhit_fade_splats_for_removed_chr(prop);
|
||||
ps_stop_sound(prop, PSTYPE_GENERAL, 0xffff);
|
||||
shieldhits_remove_by_prop(prop);
|
||||
model_free_vertices(VTXSTORETYPE_CHRVTX, model);
|
||||
model_free_vtxstores(VTXSTORETYPE_CHRVTX, model);
|
||||
prop_deregister_rooms(prop);
|
||||
|
||||
if (g_Vars.stagenum == STAGE_CITRAINING) {
|
||||
|
@ -4271,11 +4271,9 @@ void chr_bruise(struct model *model, s32 hitpart, struct modelnode *node, struct
|
|||
/**
|
||||
* Disfigure and darken a chr due to them dying from explosion damage.
|
||||
*
|
||||
* Vertices and colours are typically stored in the model definition which is
|
||||
* shared between all instances of that model. To have different vertices and
|
||||
* colours for a single instance requires copying that information out of the
|
||||
* model definition and into a vtx store. If the vtx store is full, the chr will
|
||||
* not become disfigured.
|
||||
* Vertices and colours are copied from the modeldef into new vtxstore
|
||||
* allocations. If the vtxstore is full, the chr will not become disfigured
|
||||
* or will only be partially disfigured.
|
||||
*
|
||||
* The function looks for displaylist nodes in the chr's model. For each DL node
|
||||
* found, its vertex and colour information is copied to the vtx store. The GBI
|
||||
|
|
|
@ -2560,7 +2560,7 @@ void obj_free(struct defaultobj *obj, bool freeprop, bool canregen)
|
|||
prop_deregister_rooms(obj->prop);
|
||||
|
||||
if (obj->prop->type != PROPTYPE_DOOR) {
|
||||
model_free_vertices(1, obj->model);
|
||||
model_free_vtxstores(VTXSTORETYPE_OBJVTX, obj->model);
|
||||
}
|
||||
|
||||
modelmgr_free_model(obj->model);
|
||||
|
@ -10926,7 +10926,7 @@ u32 obj_tick(struct prop *prop)
|
|||
obj->hidden &= ~OBJHFLAG_GONE;
|
||||
}
|
||||
} else {
|
||||
// Object was previously damaged. Probably glass.
|
||||
// Object was previously damaged. Probably glass or deformed object.
|
||||
if (obj->hidden2 & OBJH2FLAG_CORE_GEO_EXISTS) {
|
||||
obj->flags |= OBJFLAG_CORE_GEO_INUSE;
|
||||
} else {
|
||||
|
@ -10935,7 +10935,8 @@ u32 obj_tick(struct prop *prop)
|
|||
|
||||
obj->damage = 0;
|
||||
obj->hidden2 &= ~OBJH2FLAG_DESTROYED;
|
||||
model_free_vertices(1, obj->model);
|
||||
|
||||
model_free_vtxstores(VTXSTORETYPE_OBJVTX, obj->model);
|
||||
}
|
||||
|
||||
if (obj->type == OBJTYPE_SHIELD) {
|
||||
|
@ -12420,7 +12421,7 @@ void obj_render_prop(struct prop *prop, struct modelrenderdata *renderdata, bool
|
|||
if (renderdata->unk30 == 9) {
|
||||
renderdata->envcolour &= 0xffffff00;
|
||||
}
|
||||
} else if ((obj->hidden2 & OBJH2FLAG_80) == 0) {
|
||||
} else if ((obj->hidden2 & OBJH2FLAG_DEFORMED) == 0) {
|
||||
renderdata->cullmode = CULLMODE_BACK;
|
||||
|
||||
if (renderdata->unk30 == 9) {
|
||||
|
@ -13118,11 +13119,11 @@ void obj_deform(struct defaultobj *obj, s32 level)
|
|||
}
|
||||
}
|
||||
|
||||
if ((obj->hidden2 & OBJH2FLAG_80) == 0) {
|
||||
if ((obj->hidden2 & OBJH2FLAG_DEFORMED) == 0) {
|
||||
if (!ok) {
|
||||
model_free_vertices(VTXSTORETYPE_OBJVTX, model);
|
||||
model_free_vtxstores(VTXSTORETYPE_OBJVTX, model);
|
||||
} else {
|
||||
obj->hidden2 |= OBJH2FLAG_80;
|
||||
obj->hidden2 |= OBJH2FLAG_DEFORMED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16697,7 +16698,7 @@ bool func0f0899dc(struct prop *prop, struct coord *arg1, f32 *xrange, f32 *yrang
|
|||
return false;
|
||||
}
|
||||
|
||||
void model_free_vertices(s32 vtxstoretype, struct model *model)
|
||||
void model_free_vtxstores(s32 vtxstoretype, struct model *model)
|
||||
{
|
||||
struct modeldef *modeldef = model->definition;
|
||||
struct modelnode *node = modeldef->rootnode;
|
||||
|
@ -16706,7 +16707,6 @@ void model_free_vertices(s32 vtxstoretype, struct model *model)
|
|||
u32 type = node->type & 0xff;
|
||||
union modelrodata *rodata;
|
||||
union modelrwdata *rwdata;
|
||||
s32 newtype;
|
||||
|
||||
switch (type) {
|
||||
case MODELNODETYPE_DL:
|
||||
|
@ -16720,14 +16720,7 @@ void model_free_vertices(s32 vtxstoretype, struct model *model)
|
|||
}
|
||||
|
||||
if ((uintptr_t)rwdata->dl.colours != ALIGN8((uintptr_t)rodata->dl.vertices + rodata->dl.numvertices * sizeof(Vtx))) {
|
||||
if (vtxstoretype == VTXSTORETYPE_OBJVTX) {
|
||||
newtype = VTXSTORETYPE_OBJCOL;
|
||||
} else {
|
||||
newtype = VTXSTORETYPE_CHRCOL;
|
||||
}
|
||||
|
||||
vtxstore_free(newtype, rwdata->dl.colours);
|
||||
|
||||
vtxstore_free(vtxstoretype == VTXSTORETYPE_OBJVTX ? VTXSTORETYPE_OBJCOL : VTXSTORETYPE_CHRCOL, rwdata->dl.colours);
|
||||
rwdata->dl.colours = (Col *)ALIGN8((uintptr_t)rodata->dl.vertices + rodata->dl.numvertices * sizeof(Vtx));
|
||||
}
|
||||
}
|
||||
|
@ -20040,7 +20033,7 @@ void alarm_tick(void)
|
|||
g_PlayersDetonatingMines = 0;
|
||||
}
|
||||
|
||||
void func0f091030(void)
|
||||
void obj_free_all_offscreen_deformed_objs(void)
|
||||
{
|
||||
struct prop *prop = g_Vars.activeprops;
|
||||
|
||||
|
@ -20048,7 +20041,7 @@ void func0f091030(void)
|
|||
if (prop->type == PROPTYPE_OBJ
|
||||
&& (prop->flags & (PROPFLAG_ONTHISSCREENTHISTICK | PROPFLAG_ONANYSCREENTHISTICK | PROPFLAG_ONANYSCREENPREVTICK)) == 0
|
||||
&& (prop->obj->hidden2 & OBJH2FLAG_DESTROYED)
|
||||
&& (prop->obj->hidden2 & OBJH2FLAG_80)) {
|
||||
&& (prop->obj->hidden2 & OBJH2FLAG_DEFORMED)) {
|
||||
obj_free_permanently(prop->obj, true);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -12,45 +12,52 @@
|
|||
#include "data.h"
|
||||
#include "types.h"
|
||||
|
||||
const char var7f1b5230[] = "VTXSTORE : vtxfixrefs -> Start - p1=%x, p2=%x\n";
|
||||
const char var7f1b5260[] = "vtxfixrefs : Part=%x -- Mapping ptr %x -> %x\n";
|
||||
const char var7f1b5290[] = "VTXSTORE : vtxfixrefs -> End - Done=%d\n";
|
||||
const char var7f1b52b8[] = "vtxstorecheck : memaFree -> %u bytes at Ptr=%x(%x)\n";
|
||||
const char var7f1b52ec[] = "vtxstorecheck : At block 1 %d -> Ref1=%x, Ref2=%x\n";
|
||||
const char var7f1b5320[] = "vtxstorecheck : At block 2 %d -> Ref1=%x, Ref2=%x\n";
|
||||
const char var7f1b5354[] = "vtx buffer low, need to delete objects\n";
|
||||
const char var7f1b537c[] = "getfreevertices : %d of type %d -> ref1=%x, ref2=%x\n";
|
||||
const char var7f1b53b4[] = "vtxstore: 1st mema alloc of %u bytes\n";
|
||||
/**
|
||||
* Vtxstores are used for:
|
||||
* - deforming objects when destroyed (obj vtx)
|
||||
* - darkening objects when destroyed (obj col)
|
||||
* - disfiguring chrs when damaged by explosions (chr vtx)
|
||||
* - darkening chrs when damaged by explosions (chr col)
|
||||
* - bruising chrs when shot or stabbed (chr col)
|
||||
*
|
||||
* Model vertices and colours are typically stored in the model definition,
|
||||
* which is shared between all instances of that model. To have different
|
||||
* vertices or colours for a single instance, this data has to be copied out of
|
||||
* the model definition and into its own allocation before it can be customised.
|
||||
* These allocations are managed using vtxstores.
|
||||
*
|
||||
* Despite the name, vtxstores are also used for colours.
|
||||
*
|
||||
* Vtxstores are allocated out of mema. They are freed by the caller when the
|
||||
* object or chr is deleted. The vtxstore system will force free offscreen
|
||||
* chrs and objects if it is low on memory.
|
||||
*/
|
||||
|
||||
#if VERSION < VERSION_NTSC_1_0
|
||||
const char var7f1af8ecnb[] = "vtxstore: Trying to free %d from mema (bgRooms)\n";
|
||||
#endif
|
||||
|
||||
const char var7f1b53dc[] = "getfreevertices : Return ptr = %x\n";
|
||||
const char var7f1b5400[] = "vtxstore: Out of mema (returning NULL)\n";
|
||||
const char var7f1b5428[] = "vtxstore: GROSS! CorspeCount > MAX_CORPSES corpses! Freeing corpse %x\n";
|
||||
const char var7f1b5470[] = "vtxstore: CorpseCount %d, Trying to free %d\n";
|
||||
const char var7f1b54a0[] = "vtxstore: Freeing corpse %x\n";
|
||||
const char var7f1b54c0[] = "vtxstore: Out of vertices type %d wanted %d free %d (returning NULL)\n";
|
||||
const char var7f1b5508[] = "vtxstore: freevertices type %d, list %x\n";
|
||||
const char var7f1b5534[] = "freevertices: address not found in array %x\n";
|
||||
// Vertices are 12 bytes while colours are 4 bytes.
|
||||
// The game allocates 12 bytes regardless of whether it's
|
||||
// for a vertex or a colour. This is wasteful for colours.
|
||||
#define UNIT_SIZE MAX(sizeof(Vtx), sizeof(Col))
|
||||
|
||||
struct vtxstoretype g_VtxstoreTypes[] = {
|
||||
{ 3000, 120, 3000, 80, 0, 0, 500, 20, 12, 0, 0, 0, 0 },
|
||||
{ 1500, 40, 500, 20, 0, 0, 500, 20, 12, 0, 0, 0, 0 },
|
||||
{ 6000, 120, 6000, 80, 0, 0, 1000, 20, 4, 0, 0, 0, 0 },
|
||||
{ 1500, 40, 500, 20, 0, 0, 500, 20, 4, 0, 0, 0, 0 },
|
||||
// |------ sp -------| |------ mp -------| |----- other -----| |- unused -|
|
||||
// maxunits numbatches maxunits numbatches maxunits numbatches
|
||||
/* chr vtx */ { 3000, 120, 3000, 80, 0, 0, 500, 20, 12 },
|
||||
/* obj vtx */ { 1500, 40, 500, 20, 0, 0, 500, 20, 12 },
|
||||
/* chr col */ { 6000, 120, 6000, 80, 0, 0, 1000, 20, 4 },
|
||||
/* obj col */ { 1500, 40, 500, 20, 0, 0, 500, 20, 4 },
|
||||
};
|
||||
|
||||
/**
|
||||
* Search all props and their model data for something, and replace it with
|
||||
* something else.
|
||||
* Search all props and their model data for references to the `find` address
|
||||
* and replace it with the `replacement` address.
|
||||
*/
|
||||
void vtxstore_fix_refs(void *find, void *replacement)
|
||||
{
|
||||
u32 stack;
|
||||
s32 count = 0;
|
||||
struct prop *prop = g_Vars.activeprops;
|
||||
|
||||
osSyncPrintf("VTXSTORE : vtxfixrefs -> Start - p1=%x, p2=%x\n", find, replacement);
|
||||
|
||||
while (prop) {
|
||||
if (prop->type == PROPTYPE_OBJ) {
|
||||
struct defaultobj *obj = prop->obj;
|
||||
|
@ -64,8 +71,10 @@ void vtxstore_fix_refs(void *find, void *replacement)
|
|||
case MODELNODETYPE_DL:
|
||||
rodata = &node->rodata->dl;
|
||||
|
||||
if (model->rwdatas[rodata->rwdataindex] == (u32) find) {
|
||||
model->rwdatas[rodata->rwdataindex] = (u32) replacement;
|
||||
if (model->rwdatas[rodata->rwdataindex] == (uintptr_t) find) {
|
||||
osSyncPrintf("vtxfixrefs : Part=%x -- Mapping ptr %x -> %x\n", rodata->rwdataindex, model->rwdatas[rodata->rwdataindex], replacement);
|
||||
model->rwdatas[rodata->rwdataindex] = (uintptr_t) replacement;
|
||||
count++;
|
||||
}
|
||||
break;
|
||||
case MODELNODETYPE_DISTANCE:
|
||||
|
@ -96,6 +105,8 @@ void vtxstore_fix_refs(void *find, void *replacement)
|
|||
|
||||
prop = prop->next;
|
||||
}
|
||||
|
||||
osSyncPrintf("VTXSTORE : vtxfixrefs -> End - Done=%d\n", count);
|
||||
}
|
||||
|
||||
void vtxstore_tick(void)
|
||||
|
@ -103,38 +114,53 @@ void vtxstore_tick(void)
|
|||
s32 i;
|
||||
s32 j;
|
||||
|
||||
if (g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].val2 < g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].val1 >> 2) {
|
||||
for (i = 0; i < g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].numallocated - 1; i++) {
|
||||
if (g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].unk24[i].unk0e > 0) {
|
||||
for (j = i + 1; j < g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].numallocated; j++) {
|
||||
if (g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].unk24[j].unk0e > 0
|
||||
&& g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].unk24[i].node == g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].unk24[j].node
|
||||
&& g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].unk24[i].level == g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].unk24[j].level) {
|
||||
s32 size = ALIGN16(g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].unk24[j].count * 0x0c);
|
||||
vtxstore_fix_refs(g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].unk24[j].unk00, g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].unk24[i].unk00);
|
||||
g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].unk24[i].unk0e += g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].unk24[j].unk0e;
|
||||
mema_free(g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].unk24[j].unk00, size);
|
||||
g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].unk24[j].unk0e = 0;
|
||||
g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].val2 += g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].unk24[j].count;
|
||||
// If the obj vtx stores are at least 75% full then iterate them and try to
|
||||
// find duplicates. Merge duplicates into the original.
|
||||
// I don't think it's possible for there to be duplicates though.
|
||||
if (g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].numunitsfree < g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].numunitsmax >> 2) {
|
||||
for (i = 0; i < g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].numbatches - 1; i++) {
|
||||
if (g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].batches[i].refcount > 0) {
|
||||
for (j = i + 1; j < g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].numbatches; j++) {
|
||||
if (g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].batches[j].refcount > 0
|
||||
&& g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].batches[i].node == g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].batches[j].node
|
||||
&& g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].batches[i].level == g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].batches[j].level) {
|
||||
s32 size = ALIGN16(g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].batches[j].numunitsalloced * UNIT_SIZE);
|
||||
|
||||
vtxstore_fix_refs(g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].batches[j].allocation, g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].batches[i].allocation);
|
||||
|
||||
g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].batches[i].refcount += g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].batches[j].refcount;
|
||||
|
||||
osSyncPrintf("vtxstorecheck : memaFree -> %u bytes at Ptr=%x(%x)\n", size, g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].batches[j].allocation);
|
||||
|
||||
mema_free(g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].batches[j].allocation, size);
|
||||
|
||||
g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].batches[j].refcount = 0;
|
||||
g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].numunitsfree += g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].batches[j].numunitsalloced;
|
||||
}
|
||||
|
||||
osSyncPrintf("vtxstorecheck : At block 1 %d -> Ref1=%x, Ref2=%x\n", i, g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].batches[i].node, g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].batches[i].level);
|
||||
osSyncPrintf("vtxstorecheck : At block 2 %d -> Ref1=%x, Ref2=%x\n", j, g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].batches[j].node, g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].batches[j].level);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].val2 < g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].val1 >> 2) {
|
||||
func0f091030();
|
||||
// If the obj vtx stores are still at least 75% full
|
||||
// then free all the offscreen and deformed objects.
|
||||
if (g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].numunitsfree < g_VtxstoreTypes[VTXSTORETYPE_OBJVTX].numunitsmax >> 2) {
|
||||
osSyncPrintf("vtx buffer low, need to delete objects\n");
|
||||
obj_free_all_offscreen_deformed_objs();
|
||||
}
|
||||
}
|
||||
|
||||
void *vtxstore_allocate(s32 count, s32 index, struct modelnode *node, s32 level)
|
||||
void *vtxstore_allocate(s32 count, s32 type, struct modelnode *node, s32 level)
|
||||
{
|
||||
s32 i;
|
||||
s32 numchrs;
|
||||
s32 tally;
|
||||
s32 corpsecount;
|
||||
s32 rand;
|
||||
u32 size;
|
||||
struct chrdata *chrs[6];
|
||||
struct chrdata *corpses[6];
|
||||
|
||||
#if VERSION >= VERSION_NTSC_1_0
|
||||
if (IS4MB()) {
|
||||
|
@ -142,29 +168,39 @@ void *vtxstore_allocate(s32 count, s32 index, struct modelnode *node, s32 level)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (count <= g_VtxstoreTypes[index].val2) {
|
||||
for (i = 0; i < g_VtxstoreTypes[index].numallocated; i++) {
|
||||
if (g_VtxstoreTypes[index].unk24[i].unk0e == 0) {
|
||||
size = ALIGN16(count * 0xc);
|
||||
g_VtxstoreTypes[index].unk24[i].unk00 = mema_alloc(size);
|
||||
osSyncPrintf("getfreevertices : %d of type %d -> ref1=%x, ref2=%x\n", count, type, node, level);
|
||||
|
||||
if (count <= g_VtxstoreTypes[type].numunitsfree) {
|
||||
for (i = 0; i < g_VtxstoreTypes[type].numbatches; i++) {
|
||||
if (g_VtxstoreTypes[type].batches[i].refcount == 0) {
|
||||
size = ALIGN16(count * UNIT_SIZE);
|
||||
|
||||
osSyncPrintf("vtxstore: 1st mema alloc of %u bytes\n", size);
|
||||
|
||||
g_VtxstoreTypes[type].batches[i].allocation = mema_alloc(size);
|
||||
|
||||
#if VERSION < VERSION_NTSC_1_0
|
||||
if (!g_VtxstoreTypes[index].unk24[i].unk00) {
|
||||
if (g_VtxstoreTypes[type].batches[i].allocation == NULL) {
|
||||
osSyncPrintf("vtxstore: Trying to free %d from mema (bgRooms)\n", size);
|
||||
bg_garbage_collect_rooms(size, false);
|
||||
g_VtxstoreTypes[index].unk24[i].unk00 = mema_alloc(size);
|
||||
g_VtxstoreTypes[type].batches[i].allocation = mema_alloc(size);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (g_VtxstoreTypes[index].unk24[i].unk00) {
|
||||
g_VtxstoreTypes[index].unk24[i].count = count;
|
||||
g_VtxstoreTypes[index].unk24[i].unk0e = 1;
|
||||
g_VtxstoreTypes[index].unk24[i].node = node;
|
||||
g_VtxstoreTypes[index].unk24[i].level = level;
|
||||
g_VtxstoreTypes[index].val2 -= count;
|
||||
osSyncPrintf("getfreevertices : Return ptr = %x\n", g_VtxstoreTypes[type].batches[i].allocation);
|
||||
|
||||
return g_VtxstoreTypes[index].unk24[i].unk00;
|
||||
if (g_VtxstoreTypes[type].batches[i].allocation != NULL) {
|
||||
g_VtxstoreTypes[type].batches[i].numunitsalloced = count;
|
||||
g_VtxstoreTypes[type].batches[i].refcount = 1;
|
||||
g_VtxstoreTypes[type].batches[i].node = node;
|
||||
g_VtxstoreTypes[type].batches[i].level = level;
|
||||
g_VtxstoreTypes[type].numunitsfree -= count;
|
||||
|
||||
return g_VtxstoreTypes[type].batches[i].allocation;
|
||||
}
|
||||
|
||||
osSyncPrintf("vtxstore: Out of mema (returning NULL)\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -175,7 +211,7 @@ void *vtxstore_allocate(s32 count, s32 index, struct modelnode *node, s32 level)
|
|||
// So at the end, we'll have an array of up to six unreapable corpses and
|
||||
// all other corpses will be flagged for reaping.
|
||||
numchrs = chrs_get_num_slots();
|
||||
tally = 0;
|
||||
corpsecount = 0;
|
||||
|
||||
for (i = 0; i < numchrs; i++) {
|
||||
struct chrdata *chr = &g_ChrSlots[i];
|
||||
|
@ -185,13 +221,14 @@ void *vtxstore_allocate(s32 count, s32 index, struct modelnode *node, s32 level)
|
|||
&& (chr->prop->flags & PROPFLAG_ONANYSCREENPREVTICK) == 0
|
||||
&& chr->actiontype == ACT_DEAD
|
||||
&& chr->act_dead.fadewheninvis == false) {
|
||||
if (tally < 6) {
|
||||
chrs[tally] = chr;
|
||||
tally++;
|
||||
if (corpsecount < ARRAYCOUNT(corpses)) {
|
||||
corpses[corpsecount] = chr;
|
||||
corpsecount++;
|
||||
} else {
|
||||
rand = random() % tally;
|
||||
chr_fade_corpse_when_off_screen(chrs[rand]);
|
||||
chrs[rand] = chr;
|
||||
rand = random() % corpsecount;
|
||||
osSyncPrintf("vtxstore: GROSS! CorspeCount > MAX_CORPSES corpses! Freeing corpse %x\n", &corpses[rand]);
|
||||
chr_fade_corpse_when_off_screen(corpses[rand]);
|
||||
corpses[rand] = chr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -199,37 +236,45 @@ void *vtxstore_allocate(s32 count, s32 index, struct modelnode *node, s32 level)
|
|||
// Enable reaping on half the remaining corpses.
|
||||
// I'm reusing the rand and i variables here in order to get a match.
|
||||
// The original code likely didn't reuse them.
|
||||
rand = tally >> 1;
|
||||
rand = corpsecount >> 1;
|
||||
|
||||
osSyncPrintf("vtxstore: CorpseCount %d, Trying to free %d\n", corpsecount, rand);
|
||||
|
||||
while (rand) {
|
||||
i = random() % tally;
|
||||
i = random() % corpsecount;
|
||||
|
||||
if (chrs[i]) {
|
||||
chr_fade_corpse_when_off_screen(chrs[i]);
|
||||
chrs[i] = NULL;
|
||||
if (corpses[i]) {
|
||||
osSyncPrintf("vtxstore: Freeing corpse %x\n", &corpses[i]);
|
||||
chr_fade_corpse_when_off_screen(corpses[i]);
|
||||
corpses[i] = NULL;
|
||||
rand--;
|
||||
}
|
||||
}
|
||||
|
||||
osSyncPrintf("vtxstore: Out of vertices type %d wanted %d free %d (returning NULL)\n", type, count, g_VtxstoreTypes[type].numunitsfree);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void vtxstore_free(s32 type, void *arg1)
|
||||
void vtxstore_free(s32 type, void *allocation)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < g_VtxstoreTypes[type].numallocated; i++) {
|
||||
if (g_VtxstoreTypes[type].unk24[i].unk0e > 0 && arg1 == g_VtxstoreTypes[type].unk24[i].unk00) {
|
||||
g_VtxstoreTypes[type].unk24[i].unk0e--;
|
||||
osSyncPrintf("vtxstore: freevertices type %d, list %x\n", type, allocation);
|
||||
|
||||
if (g_VtxstoreTypes[type].unk24[i].unk0e) {
|
||||
return;
|
||||
for (i = 0; i < g_VtxstoreTypes[type].numbatches; i++) {
|
||||
if (g_VtxstoreTypes[type].batches[i].refcount > 0 && g_VtxstoreTypes[type].batches[i].allocation == allocation) {
|
||||
g_VtxstoreTypes[type].batches[i].refcount--;
|
||||
|
||||
if (g_VtxstoreTypes[type].batches[i].refcount == 0) {
|
||||
mema_free(g_VtxstoreTypes[type].batches[i].allocation, ALIGN16(g_VtxstoreTypes[type].batches[i].numunitsalloced * UNIT_SIZE));
|
||||
|
||||
g_VtxstoreTypes[type].numunitsfree += g_VtxstoreTypes[type].batches[i].numunitsalloced;
|
||||
}
|
||||
|
||||
mema_free(g_VtxstoreTypes[type].unk24[i].unk00, ALIGN16(g_VtxstoreTypes[type].unk24[i].count * 0xc));
|
||||
|
||||
g_VtxstoreTypes[type].val2 += g_VtxstoreTypes[type].unk24[i].count;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
osSyncPrintf("freevertices: address not found in array %x\n", allocation);
|
||||
}
|
||||
|
|
|
@ -9,31 +9,31 @@ void vtxstore_reset(void)
|
|||
{
|
||||
s32 i;
|
||||
s32 j;
|
||||
s32 num;
|
||||
s32 val;
|
||||
s32 numbatches;
|
||||
s32 maxunits;
|
||||
|
||||
for (i = 0; i < ARRAYCOUNT(g_VtxstoreTypes); i++) {
|
||||
if (PLAYERCOUNT() >= 2) {
|
||||
val = g_VtxstoreTypes[i].valifmp;
|
||||
num = g_VtxstoreTypes[i].numifmp;
|
||||
maxunits = g_VtxstoreTypes[i].mpmaxunits;
|
||||
numbatches = g_VtxstoreTypes[i].mpnumbatches;
|
||||
} else if (g_Vars.stagenum >= STAGE_TITLE) {
|
||||
val = g_VtxstoreTypes[i].valifspecial;
|
||||
num = g_VtxstoreTypes[i].numifspecial;
|
||||
maxunits = g_VtxstoreTypes[i].othermaxunits;
|
||||
numbatches = g_VtxstoreTypes[i].othernumbatches;
|
||||
} else {
|
||||
val = g_VtxstoreTypes[i].valifsp;
|
||||
num = g_VtxstoreTypes[i].numifsp;
|
||||
maxunits = g_VtxstoreTypes[i].spmaxunits;
|
||||
numbatches = g_VtxstoreTypes[i].spnumbatches;
|
||||
}
|
||||
|
||||
if (num > 0) {
|
||||
g_VtxstoreTypes[i].unk24 = memp_alloc(num * sizeof(struct var8007e3d0_data), MEMPOOL_STAGE);
|
||||
if (numbatches > 0) {
|
||||
g_VtxstoreTypes[i].batches = memp_alloc(numbatches * sizeof(struct vtxstorebatch), MEMPOOL_STAGE);
|
||||
}
|
||||
|
||||
for (j = 0; j < num; j++) {
|
||||
g_VtxstoreTypes[i].unk24[j].unk0e = 0;
|
||||
for (j = 0; j < numbatches; j++) {
|
||||
g_VtxstoreTypes[i].batches[j].refcount = 0;
|
||||
}
|
||||
|
||||
g_VtxstoreTypes[i].numallocated = num;
|
||||
g_VtxstoreTypes[i].val1 = val;
|
||||
g_VtxstoreTypes[i].val2 = val;
|
||||
g_VtxstoreTypes[i].numbatches = numbatches;
|
||||
g_VtxstoreTypes[i].numunitsmax = maxunits;
|
||||
g_VtxstoreTypes[i].numunitsfree = maxunits;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3170,13 +3170,13 @@
|
|||
#define OBJHFLAG_GRABBED 0x08000000
|
||||
|
||||
// obj->hidden2
|
||||
#define OBJH2FLAG_HASOPA 0x01 // obj has opaque polygons (ie. most objects)
|
||||
#define OBJH2FLAG_HASXLU 0x02 // obj has translucent polygons
|
||||
#define OBJH2FLAG_CANREGEN 0x04
|
||||
#define OBJH2FLAG_CORE_GEO_EXISTS 0x08
|
||||
#define OBJH2FLAG_10 0x10
|
||||
#define OBJH2FLAG_DESTROYED 0x40
|
||||
#define OBJH2FLAG_80 0x80
|
||||
#define OBJH2FLAG_HASOPA 0x01 // obj has opaque polygons (ie. most objects)
|
||||
#define OBJH2FLAG_HASXLU 0x02 // obj has translucent polygons
|
||||
#define OBJH2FLAG_CANREGEN 0x04
|
||||
#define OBJH2FLAG_CORE_GEO_EXISTS 0x08
|
||||
#define OBJH2FLAG_10 0x10
|
||||
#define OBJH2FLAG_DESTROYED 0x40
|
||||
#define OBJH2FLAG_DEFORMED 0x80
|
||||
|
||||
#define OBJTYPE_DOOR 0x01
|
||||
#define OBJTYPE_DOORSCALE 0x02
|
||||
|
|
|
@ -130,7 +130,7 @@ void current_player_queue_pickup_weapon_hudmsg(u32 weaponnum, bool dual);
|
|||
s32 prop_pickup_by_player(struct prop *prop, bool showhudmsg);
|
||||
s32 obj_test_for_pickup(struct prop *prop);
|
||||
bool func0f0899dc(struct prop *prop, struct coord *arg1, f32 *xrange, f32 *yrange);
|
||||
void model_free_vertices(s32 vtxstoretype, struct model *model);
|
||||
void model_free_vtxstores(s32 vtxstoretype, struct model *model);
|
||||
void hat_assign_to_chr(struct hatobj *hat, struct chrdata *chr);
|
||||
struct prop *hat_create_for_chr(struct chrdata *chr, s32 modelnum, u32 flags);
|
||||
void player_activate_remote_mine_detonator(s32 playernum);
|
||||
|
@ -172,7 +172,7 @@ bool gas_is_active(void);
|
|||
Gfx *countdown_timer_render(Gfx *gdl);
|
||||
void projectiles_debug(void);
|
||||
void alarm_tick(void);
|
||||
void func0f091030(void);
|
||||
void obj_free_all_offscreen_deformed_objs(void);
|
||||
void current_player_drop_all_items(void);
|
||||
void weapon_create_for_player_drop(s32 weaponnum);
|
||||
void projectile_create(struct prop *fromprop, struct fireslotthing *arg1, struct coord *pos, struct coord *direction, u8 weaponnum, struct prop *targetprop);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
void vtxstore_reset(void);
|
||||
|
||||
void vtxstore_tick(void);
|
||||
void *vtxstore_allocate(s32 count, s32 index, struct modelnode *node, s32 level);
|
||||
void vtxstore_free(s32 type, void *arg1);
|
||||
void *vtxstore_allocate(s32 count, s32 type, struct modelnode *node, s32 level);
|
||||
void vtxstore_free(s32 type, void *allocation);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5359,28 +5359,28 @@ struct pschannel {
|
|||
#endif
|
||||
};
|
||||
|
||||
struct var8007e3d0_data {
|
||||
void *unk00;
|
||||
struct modelnode *node;
|
||||
s32 level;
|
||||
s16 count;
|
||||
s16 unk0e;
|
||||
struct vtxstoretype {
|
||||
s32 spmaxunits;
|
||||
s32 spnumbatches;
|
||||
s32 mpmaxunits;
|
||||
s32 mpnumbatches;
|
||||
s32 othermaxunits;
|
||||
s32 othernumbatches;
|
||||
s32 unused18;
|
||||
s32 unused1c;
|
||||
s32 unused20;
|
||||
struct vtxstorebatch *batches;
|
||||
s32 numunitsmax;
|
||||
s32 numunitsfree;
|
||||
s32 numbatches;
|
||||
};
|
||||
|
||||
struct vtxstoretype {
|
||||
s32 valifsp;
|
||||
s32 numifsp;
|
||||
s32 valifmp;
|
||||
s32 numifmp;
|
||||
s32 valifspecial;
|
||||
s32 numifspecial;
|
||||
s32 unk18;
|
||||
s32 unk1c;
|
||||
s32 unk20;
|
||||
struct var8007e3d0_data *unk24;
|
||||
s32 val1;
|
||||
s32 val2;
|
||||
s32 numallocated;
|
||||
struct vtxstorebatch {
|
||||
void *allocation;
|
||||
struct modelnode *node;
|
||||
s32 level;
|
||||
s16 numunitsalloced;
|
||||
s16 refcount;
|
||||
};
|
||||
|
||||
struct wallhit {
|
||||
|
|
Loading…
Reference in New Issue