123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614 |
- #include "3dc.h"
- #include "module.h"
- #include "stratdef.h"
- #include "sfx.h"
- #define UseLocalAssert Yes
- #include "ourasert.h"
- /* globals for export */
- int NumActiveBlocks;
- DISPLAYBLOCK *ActiveBlockList[maxobjects];
- /*
- Object Block Lists et al
- */
- static int NumFreeBlocks;
- static DISPLAYBLOCK *FreeBlockList[maxobjects];
- static DISPLAYBLOCK **FreeBlockListPtr = &FreeBlockList[maxobjects-1];
- static DISPLAYBLOCK FreeBlockData[maxobjects];
- static DISPLAYBLOCK **ActiveBlockListPtr = &ActiveBlockList[0];
- /*
- Texture Animation Block Extensions
- */
- static int NumFreeTxAnimBlocks;
- static TXACTRLBLK *FreeTxAnimBlockList[maxTxAnimblocks];
- static TXACTRLBLK **FreeTxAnimBlockListPtr = &FreeTxAnimBlockList[maxTxAnimblocks-1];
- static TXACTRLBLK FreeTxAnimBlockData[maxTxAnimblocks];
- /*
- Light Block Extensions
- */
- static int NumFreeLightBlocks;
- static LIGHTBLOCK *FreeLightBlockList[maxlightblocks];
- static LIGHTBLOCK **FreeLightBlockListPtr = &FreeLightBlockList[maxlightblocks-1];
- static LIGHTBLOCK FreeLightBlockData[maxlightblocks];
- /*
- To create the free block list, pointers to "FreeBlockData[]" must be copied
- to "FreeBlockList[]".
- Also:
- "NumFreeBlocks" must be updated as "FreeBlockList[]" is created.
- "NumActiveBlocks" must be initialised to zero.
- */
- void InitialiseObjectBlocks(void)
- {
- DISPLAYBLOCK *FreeBlkPtr = &FreeBlockData[0];
- NumActiveBlocks = 0;
- FreeBlockListPtr = &FreeBlockList[maxobjects-1];
- ActiveBlockListPtr = &ActiveBlockList[0];
- for(NumFreeBlocks = 0; NumFreeBlocks<maxobjects; NumFreeBlocks++) {
- FreeBlockList[NumFreeBlocks] = FreeBlkPtr;
- FreeBlkPtr++;
- }
- }
- /*
- "AllocateObjectBlock()" is identical to the routine "GetBlock"
- */
- DISPLAYBLOCK* AllocateObjectBlock(void)
- {
- DISPLAYBLOCK *FreeBlkPtr = 0; /* Default to null ptr */
- int *sptr;
- int i;
- if(NumFreeBlocks) {
- FreeBlkPtr = *FreeBlockListPtr--;
- NumFreeBlocks--; /* One less free block */
- /* Clear the block */
- sptr = (int *)FreeBlkPtr;
- for(i = sizeof(DISPLAYBLOCK)/4; i!=0; i--)
- *sptr++ = 0;
- }
- return(FreeBlkPtr);
- }
- /*
- "DeallocateObjectBlock()" is identical to the routine "ReturnBlock"
- */
- void DeallocateObjectBlock(DISPLAYBLOCK *dblockptr)
- {
- /* Deallocate the Display Block */
- FreeBlockListPtr++;
- *FreeBlockListPtr = dblockptr;
- NumFreeBlocks++; /* One more free block */
- }
- /*
- "CreateActiveObject()" calls "AllocateObjectBlock()". An active object is
- passed into the view and strategy routines unless flagged otherwise
- WARNING!
- An active object must ALWAYS be deallocated by "DestroyActiveObject()".
- */
- DISPLAYBLOCK* CreateActiveObject(void)
- {
- DISPLAYBLOCK *dblockptr;
- dblockptr = AllocateObjectBlock();
- if(dblockptr) {
- *ActiveBlockListPtr++ = dblockptr;
- NumActiveBlocks++;
- }
- return dblockptr;
- }
- /*
- DestroyActiveObject()
- Remove the block from "ActiveBlockList".
- Use the array model because it's clearer.
- This function returns 0 if successful, -1 if not
- */
- int DestroyActiveObject(DISPLAYBLOCK *dblockptr)
- {
- int i, light;
- TXACTRLBLK *taptr;
- /* If the block ptr is OK, search the Active Blocks List */
- if(dblockptr) {
- for(i = 0; i < NumActiveBlocks; i++) {
- if(ActiveBlockList[i] == dblockptr) {
- ActiveBlockList[i] = ActiveBlockList[NumActiveBlocks-1];
- NumActiveBlocks--;
- ActiveBlockListPtr--;
- DestroyActiveVDB(dblockptr->ObVDBPtr); /* Checks for null */
- if(dblockptr->ObNumLights) {
- for(light = dblockptr->ObNumLights - 1; light != -1; light--)
- DeleteLightBlock(dblockptr->ObLights[light], dblockptr);
- }
- /* If no SB, deallocate any Texture Animation Blocks */
- if(dblockptr->ObStrategyBlock == 0) {
- if(dblockptr->ObTxAnimCtrlBlks) {
- taptr = dblockptr->ObTxAnimCtrlBlks;
- while(taptr) {
- DeallocateTxAnimBlock(taptr);
- taptr = taptr->tac_next;
- }
- }
- }
- /* Deallocate the Lazy Morphed Points Array Pointer */
- #if (SupportMorphing && LazyEvaluationForMorphing)
- if(dblockptr->ObMorphedPts) {
- DeallocateMem(dblockptr->ObMorphedPts);
- dblockptr->ObMorphedPts = 0;
- }
- #endif
- /* KJL 16:52:43 06/01/98 - dealloc sfx block if one exists */
- if(dblockptr->SfxPtr)
- {
- DeallocateSfxBlock(dblockptr->SfxPtr);
- }
- DeallocateObjectBlock(dblockptr); /* Back to Free List */
- /* If this is the current landscape, clear the pointer */
- return 0;
- }
- }
- }
- return -1;
- }
- /*
- Support Functions for Texture Animation Blocks
- */
- void InitialiseTxAnimBlocks(void)
- {
- TXACTRLBLK *FreeBlkPtr = &FreeTxAnimBlockData[0];
- FreeTxAnimBlockListPtr = &FreeTxAnimBlockList[maxTxAnimblocks-1];
- for(NumFreeTxAnimBlocks=0; NumFreeTxAnimBlocks < maxTxAnimblocks; NumFreeTxAnimBlocks++) {
- FreeTxAnimBlockList[NumFreeTxAnimBlocks] = FreeBlkPtr;
- FreeBlkPtr++;
- }
- }
- /*
- Allocate a Texture Animation Block
- */
- TXACTRLBLK* AllocateTxAnimBlock(void)
- {
- TXACTRLBLK *FreeBlkPtr = 0; /* Default to null ptr */
- int *sptr;
- int i;
- if(NumFreeTxAnimBlocks) {
- FreeBlkPtr = *FreeTxAnimBlockListPtr--;
- NumFreeTxAnimBlocks--; /* One less free block */
- /* Clear the block */
- sptr = (int *)FreeBlkPtr;
- for(i = sizeof(TXACTRLBLK)/4; i!=0; i--)
- *sptr++ = 0;
- }
- return FreeBlkPtr;
- }
- /*
- Deallocate a Texture Animation Block
- */
- void DeallocateTxAnimBlock(TXACTRLBLK *TxAnimblockptr)
- {
- FreeTxAnimBlockListPtr++;
- *FreeTxAnimBlockListPtr = TxAnimblockptr;
- NumFreeTxAnimBlocks++; /* One more free block */
- }
- /*
- Add a Texture Animation Block to a Display Block
- */
- void AddTxAnimBlock(DISPLAYBLOCK *dptr, TXACTRLBLK *taptr)
- {
- TXACTRLBLK *taptr_tmp;
- if(dptr->ObTxAnimCtrlBlks) {
- taptr_tmp = dptr->ObTxAnimCtrlBlks;
- while(taptr_tmp->tac_next)
- taptr_tmp = taptr_tmp->tac_next;
- taptr_tmp->tac_next = taptr;
- }
- else dptr->ObTxAnimCtrlBlks = taptr;
- }
- /*
- Support functions for Light Blocks
- */
- void InitialiseLightBlocks(void)
- {
- LIGHTBLOCK *FreeBlkPtr = &FreeLightBlockData[0];
- FreeLightBlockListPtr = &FreeLightBlockList[maxlightblocks-1];
- for(NumFreeLightBlocks=0; NumFreeLightBlocks < maxlightblocks; NumFreeLightBlocks++) {
- FreeLightBlockList[NumFreeLightBlocks] = FreeBlkPtr;
- FreeBlkPtr++;
- }
- }
- LIGHTBLOCK* AllocateLightBlock(void)
- {
- LIGHTBLOCK *FreeBlkPtr = 0; /* Default to null ptr */
- int *lptr;
- int i;
- if(NumFreeLightBlocks) {
- FreeBlkPtr = *FreeLightBlockListPtr--;
- NumFreeLightBlocks--; /* One less free block */
- /* Clear the block */
- lptr = (int *)FreeBlkPtr;
- for(i = sizeof(LIGHTBLOCK)/4; i!=0; i--)
- *lptr++ = 0;
- }
- return(FreeBlkPtr);
- }
- void DeallocateLightBlock(LIGHTBLOCK *lptr)
- {
- /* Not all lights come from the free light list */
- if(lptr->LightFlags & LFlag_WasNotAllocated) return;
- /* Make sure that this light IS from the free light list */
- GLOBALASSERT(
- (lptr >= FreeLightBlockData) &&
- (lptr < &FreeLightBlockData[maxlightblocks])
- );
- /* Ok to return the light */
- FreeLightBlockListPtr++;
- *FreeLightBlockListPtr = lptr;
- NumFreeLightBlocks++; /* One more free block */
- }
- /*
- See if there are any free slots in the dptr light block array.
- If there are, allocate a light block, place it in the list and return
- the pointer to the caller.
- A late addition is the passing of a light block (from somewhere, it does
- not matter where). This light block is then added rather than one being
- allocated from the free light block list.
- */
- LIGHTBLOCK* AddLightBlock(DISPLAYBLOCK *dptr, LIGHTBLOCK *lptr_to_add)
- {
- LIGHTBLOCK **larrayptr;
- LIGHTBLOCK **freelarrayptr;
- LIGHTBLOCK *lptr = 0;
- int i, lfree;
- /* Are there any free slots? */
- lfree = No;
- larrayptr = &dptr->ObLights[0];
- for(i = MaxObjectLights; i!=0 && lfree == No; i--) {
- if(*larrayptr == 0) {
- freelarrayptr = larrayptr;
- lfree = Yes;
- }
- larrayptr++;
- }
- if(lfree) {
- if(lptr_to_add) {
- lptr = lptr_to_add;
- }
- else {
- lptr = AllocateLightBlock();
- }
- if(lptr)
- {
- *freelarrayptr = lptr;
- dptr->ObNumLights++;
- }
- }
- return lptr;
- }
- /*
- To delete a light block, copy the end block to the new free slot and
- reduce the count by one. Make sure the end block array entry is cleared.
- */
- void DeleteLightBlock(LIGHTBLOCK *lptr, DISPLAYBLOCK *dptr)
- {
- int i, larrayi;
- DeallocateLightBlock(lptr);
- /* What is lptr's array index? */
- larrayi = -1; /* null value */
- for(i = 0; i < dptr->ObNumLights; i++)
- if(dptr->ObLights[i] == lptr) larrayi = i;
- /* Proceed only if lptr has been found in the array */
- if(larrayi != -1) {
- /* Copy the end block to that of lptr */
- dptr->ObLights[larrayi] = dptr->ObLights[dptr->ObNumLights - 1];
- /* Clear the end block array entry */
- dptr->ObLights[dptr->ObNumLights - 1] = 0;
- /* One less light in the dptr list */
- dptr->ObNumLights--;
- }
- }
- /*
- When running the parallel strategies, display and light block deallocation
- must only be done at the end of the frame, AFTER processor synchronisation
- and BEFORE the shadow copy.
- */
- int DisplayAndLightBlockDeallocation(void)
- {
- DISPLAYBLOCK **activeblocksptr;
- DISPLAYBLOCK *dptr;
- int i, j;
- LIGHTBLOCK *lptr;
- if(NumActiveBlocks) {
- activeblocksptr = &ActiveBlockList[NumActiveBlocks - 1];
- for(i = NumActiveBlocks; i!=0; i--) {
- dptr = *activeblocksptr--;
- /* Deallocate Object? */
- if(dptr->ObFlags2 & ObFlag2_Deallocate) {
- DestroyActiveObject(dptr);
- }
- /* Deallocate any Lights? */
- else {
- if(dptr->ObNumLights) {
- for(j = dptr->ObNumLights - 1; j > -1; j--) {
- lptr = dptr->ObLights[j];
- if(lptr->LightFlags & LFlag_Deallocate) {
- DeleteLightBlock(dptr->ObLights[j], dptr);
- }
- }
- }
- }
- }
- }
- return 0;
- }
|