Skip to content

Commit

Permalink
Statically-allocated objnode pool
Browse files Browse the repository at this point in the history
  • Loading branch information
jorio committed Jan 22, 2023
1 parent 653af0c commit a1ca572
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 36 deletions.
1 change: 1 addition & 0 deletions src/Headers/game.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ extern int gDebugMode;
extern int gFullscreenModeAppliedOnBoot;
extern int gMaxItemsAllocatedInAPass;
extern int gNitroParticleGroup;
extern int gNumObjNodes;
extern int gWindowHeight;
extern int gWindowWidth;
extern int gCurrentSaveSlot;
Expand Down
8 changes: 4 additions & 4 deletions src/Headers/structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,14 +236,14 @@ struct ObjNode

struct ObjNode *ShadowNode; // ptr to node's shadow (if any)

u_short Slot; // sort value
uint16_t Slot; // sort value
Byte Genre; // obj genre (skeleton, display_group, custom, event)
Byte Type; // obj type (If Genre=display_group: model# in group. If Genre is skel: skel#.)
Byte Group; // obj group (If Genre=display_group: index into gObjectGroupList.)
void (*MoveCall)(struct ObjNode *); // pointer to object's move routine
void (*SplineMoveCall)(struct ObjNode *); // pointer to object's spline move routine
void (*CustomDrawFunction)(struct ObjNode *);// pointer to object's custom draw function
u_long StatusBits; // various status bits
uint32_t StatusBits; // various status bits

TQ3Point3D Coord; // coord of object
TQ3Point3D OldCoord; // coord @ previous frame
Expand All @@ -256,8 +256,8 @@ struct ObjNode
TQ3Vector3D Scale; // scale of object
TQ3Point2D TargetOff; // target offsets

u_long CType; // collision type bits
u_long CBits; // collision attribute bits
uint32_t CType; // collision type bits
uint32_t CBits; // collision attribute bits
Byte NumCollisionBoxes;
CollisionBoxType *CollisionBoxes;// Ptr to array of collision rectangles
CollisionBoxType *OldCollisionBoxes;
Expand Down
133 changes: 102 additions & 31 deletions src/System/Objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,32 +17,38 @@
/****************************/

static void FlushObjectDeleteQueue(int queueID);
static void DisposeObjNodeMemory(ObjNode* node);


/****************************/
/* CONSTANTS */
/****************************/

#define OBJ_DEL_Q_SIZE 100
#define OBJ_BUDGET 500


/**********************/
/* VARIABLES */
/**********************/

static Boolean gPooledObjNodesInUse[OBJ_BUDGET];
static ObjNode gObjNodePool[OBJ_BUDGET];
static ObjNode gObjNodeTemplate;

// OBJECT LIST
ObjNode *gFirstNodePtr = nil;

ObjNode *gCurrentNode,*gMostRecentlyAddedNode,*gNextNode;

int gNumObjNodes = 0;

NewObjectDefinitionType gNewObjectDefinition;

TQ3Point3D gCoord;
TQ3Vector3D gDelta;

// Source port change: We now have a double-buffered deletion queue, so objects
// that get queued for deletion during frame N will be deleted at the end of frame N+1.
// Double-buffered deletion queue: objects that get queued for deletion during
// frame N will be deleted at the end of frame N+1.
// This gives live objects a full frame to clean up references to dead objects.
static int gNumObjsInDeleteQueue[2];
static ObjNode* gObjectDeleteQueue[2][OBJ_DEL_Q_SIZE];
Expand All @@ -62,15 +68,36 @@ float gAutoFadeStartDist;

void InitObjectManager(void)
{
/* INIT LINKED LIST */

/* INIT LINKED LIST */


gCurrentNode = nil;

/* CLEAR ENTIRE OBJECT LIST */

gFirstNodePtr = nil; // no node yet
gNumObjNodes = 0;

/* INIT OBJECT POOL */

memset(gObjNodePool, 0, sizeof(gObjNodePool));
memset(gPooledObjNodesInUse, 0, sizeof(gPooledObjNodesInUse));

/* MAKE OBJECT TEMPLATE */

gObjNodeTemplate = (ObjNode)
{
.CType = 0, // must init ctype to something (INVALID_NODE_FLAG might be set from last delete)
.Scale = {1,1,1},
.BoundingSphere = {.origin={0,0,0}, .radius=40, .isEmpty=kQ3False},
.EffectChannel = -1, // no effect channel yet
.ParticleGroup = -1, // no particle group
.SplineObjectIndex = -1, // no index yet
.StatusBits = STATUS_BIT_DETACHED, // not attached to linked list yet
};

Render_SetDefaultModifiers(&gObjNodeTemplate.RenderModifiers);

/* INIT NEW OBJ DEF */

memset(&gNewObjectDefinition, 0, sizeof(NewObjectDefinitionType));
gNewObjectDefinition.scale = 1;
}


Expand All @@ -83,18 +110,40 @@ void InitObjectManager(void)

ObjNode *MakeNewObject(NewObjectDefinitionType *newObjDef)
{
ObjNode *newNodePtr;
ObjNode *newNodePtr = NULL;

/* TRY TO GET AN OBJECT FROM THE POOL */

for (int i = 0; i < OBJ_BUDGET; i++)
{
if (!gPooledObjNodesInUse[i])
{
gPooledObjNodesInUse[i] = true; // lock that one
newNodePtr = &gObjNodePool[i]; // point to pooled node
break;
}
}

/* POOL FULL, ALLOCATE NEW NODE ON HEAP */

if (newNodePtr == NULL)
{
newNodePtr = (ObjNode*) AllocPtr(sizeof(ObjNode));
}

/* MAKE SURE WE GOT ONE */

GAME_ASSERT(newNodePtr);

/* MAKE SURE SCALE != 0 */
/* MAKE SURE SCALE != 0 */

float scale = newObjDef->scale;
if (scale == 0.0f)
scale = 0.0001f;

/* INITIALIZE NEW NODE */

newNodePtr = (ObjNode*) NewPtrClear(sizeof(ObjNode)); // source port change: use NewPtrClear so all fields start at 0
GAME_ASSERT(newNodePtr);
/* INITIALIZE NEW NODE */

*newNodePtr = gObjNodeTemplate;

newNodePtr->Slot = newObjDef->slot;
newNodePtr->Type = newObjDef->type;
Expand All @@ -116,29 +165,21 @@ ObjNode *newNodePtr;
newNodePtr->Rot.y = newObjDef->rot;
newNodePtr->Rot.z = 0;

newNodePtr->BoundingSphere.radius = 40; // set default bounding sphere at offset 0,0,0

newNodePtr->EffectChannel = -1; // no streaming sound effect
newNodePtr->ParticleGroup = -1; // no particle group
newNodePtr->SplineObjectIndex = -1; // no index yet

Render_SetDefaultModifiers(&newNodePtr->RenderModifiers);
newNodePtr->RenderModifiers.statusBits = 0;
newNodePtr->RenderModifiers.diffuseColor = (TQ3ColorRGBA) { 1,1,1,1 }; // default diffuse color is opaque white

if (newObjDef->flags & STATUS_BIT_ONSPLINE)
newNodePtr->SplineMoveCall = newObjDef->moveCall; // save spline move routine
else
newNodePtr->MoveCall = newObjDef->moveCall; // save move routine

/* INSERT NODE INTO LINKED LIST */

newNodePtr->StatusBits |= STATUS_BIT_DETACHED; // its not attached to linked list yet
AttachObject(newNodePtr);

/* CLEANUP */

gMostRecentlyAddedNode = newNodePtr; // remember this
gNumObjNodes++;

return(newNodePtr);
}

Expand Down Expand Up @@ -590,7 +631,7 @@ void DeleteObject(ObjNode *theNode)
{
// We're out of room in the delete queue. Just delete the node immediately,
// but that might cause the game to become unstable (unless we're here from DeleteAllNodes).
DisposePtr((Ptr) theNode);
DisposeObjNodeMemory(theNode);
}
else
{
Expand Down Expand Up @@ -705,14 +746,44 @@ short slot;
}



/***************** DISPOSE OBJECT MEMORY ****************/

static void DisposeObjNodeMemory(ObjNode* node)
{
GAME_ASSERT(node != NULL);

ptrdiff_t poolIndex = node - gObjNodePool;

if (poolIndex >= 0 && poolIndex < OBJ_BUDGET)
{
// node is pooled, put back into pool
GAME_ASSERT_MESSAGE(gPooledObjNodesInUse[poolIndex], "Pooled node freed twice");
gPooledObjNodesInUse[poolIndex] = false;
}
else
{
// node was allocated on heap
DisposePtr((Ptr) node);
}

gNumObjNodes--;
}


/***************** FLUSH OBJECT DELETE QUEUE ****************/

static void FlushObjectDeleteQueue(int qid)
{
int num = gNumObjsInDeleteQueue[qid];

for (int i = 0; i < num; i++)
DisposePtr((Ptr) gObjectDeleteQueue[qid][i]);
{
if (gObjectDeleteQueue[qid][i])
{
DisposeObjNodeMemory(gObjectDeleteQueue[qid][i]);
}
}

gNumObjsInDeleteQueue[qid] = 0;
}
Expand Down
3 changes: 2 additions & 1 deletion src/System/SDLMaintenance.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ static void UpdateDebugStats(void)

snprintf(
gDebugTextBuffer, sizeof(gDebugTextBuffer),
"fps: %d\ntris: %d\nmeshes: %d+%d\ntiles: %ld/%ld%s\n\nx: %d\nz: %d\ny: %f %s%s\n%s\n%s\n\n\n\n\n\n\n\n\n\n\n"
"fps: %d\ntris: %d\nmeshes: %d+%d\ntiles: %ld/%ld%s\nnodes: %d\n\nx: %d\nz: %d\ny: %.3f %s%s\n%s\n%s\n\n\n\n\n\n\n\n\n\n"
"Bugdom %s\nOpenGL %s, %s @ %dx%d",
(int)roundf(fps),
gRenderStats.triangles,
Expand All @@ -47,6 +47,7 @@ static void UpdateDebugStats(void)
gSupertileBudget - gNumFreeSupertiles,
gSupertileBudget,
gSuperTileMemoryListExists ? "" : " (no terrain)",
gNumObjNodes,
(int)(gPlayerObj? gPlayerObj->Coord.x: 0),
(int)(gPlayerObj? gPlayerObj->Coord.z: 0),
gPlayerObj? gPlayerObj->Coord.y: 0,
Expand Down

0 comments on commit a1ca572

Please sign in to comment.