OBJECT.C 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614
  1. #include "3dc.h"
  2. #include "module.h"
  3. #include "stratdef.h"
  4. #include "sfx.h"
  5. #define UseLocalAssert Yes
  6. #include "ourasert.h"
  7. /* globals for export */
  8. int NumActiveBlocks;
  9. DISPLAYBLOCK *ActiveBlockList[maxobjects];
  10. /*
  11. Object Block Lists et al
  12. */
  13. static int NumFreeBlocks;
  14. static DISPLAYBLOCK *FreeBlockList[maxobjects];
  15. static DISPLAYBLOCK **FreeBlockListPtr = &FreeBlockList[maxobjects-1];
  16. static DISPLAYBLOCK FreeBlockData[maxobjects];
  17. static DISPLAYBLOCK **ActiveBlockListPtr = &ActiveBlockList[0];
  18. /*
  19. Texture Animation Block Extensions
  20. */
  21. static int NumFreeTxAnimBlocks;
  22. static TXACTRLBLK *FreeTxAnimBlockList[maxTxAnimblocks];
  23. static TXACTRLBLK **FreeTxAnimBlockListPtr = &FreeTxAnimBlockList[maxTxAnimblocks-1];
  24. static TXACTRLBLK FreeTxAnimBlockData[maxTxAnimblocks];
  25. /*
  26. Light Block Extensions
  27. */
  28. static int NumFreeLightBlocks;
  29. static LIGHTBLOCK *FreeLightBlockList[maxlightblocks];
  30. static LIGHTBLOCK **FreeLightBlockListPtr = &FreeLightBlockList[maxlightblocks-1];
  31. static LIGHTBLOCK FreeLightBlockData[maxlightblocks];
  32. /*
  33. To create the free block list, pointers to "FreeBlockData[]" must be copied
  34. to "FreeBlockList[]".
  35. Also:
  36. "NumFreeBlocks" must be updated as "FreeBlockList[]" is created.
  37. "NumActiveBlocks" must be initialised to zero.
  38. */
  39. void InitialiseObjectBlocks(void)
  40. {
  41. DISPLAYBLOCK *FreeBlkPtr = &FreeBlockData[0];
  42. NumActiveBlocks = 0;
  43. FreeBlockListPtr = &FreeBlockList[maxobjects-1];
  44. ActiveBlockListPtr = &ActiveBlockList[0];
  45. for(NumFreeBlocks = 0; NumFreeBlocks<maxobjects; NumFreeBlocks++) {
  46. FreeBlockList[NumFreeBlocks] = FreeBlkPtr;
  47. FreeBlkPtr++;
  48. }
  49. }
  50. /*
  51. "AllocateObjectBlock()" is identical to the routine "GetBlock"
  52. */
  53. DISPLAYBLOCK* AllocateObjectBlock(void)
  54. {
  55. DISPLAYBLOCK *FreeBlkPtr = 0; /* Default to null ptr */
  56. int *sptr;
  57. int i;
  58. if(NumFreeBlocks) {
  59. FreeBlkPtr = *FreeBlockListPtr--;
  60. NumFreeBlocks--; /* One less free block */
  61. /* Clear the block */
  62. sptr = (int *)FreeBlkPtr;
  63. for(i = sizeof(DISPLAYBLOCK)/4; i!=0; i--)
  64. *sptr++ = 0;
  65. }
  66. return(FreeBlkPtr);
  67. }
  68. /*
  69. "DeallocateObjectBlock()" is identical to the routine "ReturnBlock"
  70. */
  71. void DeallocateObjectBlock(DISPLAYBLOCK *dblockptr)
  72. {
  73. /* Deallocate the Display Block */
  74. FreeBlockListPtr++;
  75. *FreeBlockListPtr = dblockptr;
  76. NumFreeBlocks++; /* One more free block */
  77. }
  78. /*
  79. "CreateActiveObject()" calls "AllocateObjectBlock()". An active object is
  80. passed into the view and strategy routines unless flagged otherwise
  81. WARNING!
  82. An active object must ALWAYS be deallocated by "DestroyActiveObject()".
  83. */
  84. DISPLAYBLOCK* CreateActiveObject(void)
  85. {
  86. DISPLAYBLOCK *dblockptr;
  87. dblockptr = AllocateObjectBlock();
  88. if(dblockptr) {
  89. *ActiveBlockListPtr++ = dblockptr;
  90. NumActiveBlocks++;
  91. }
  92. return dblockptr;
  93. }
  94. /*
  95. DestroyActiveObject()
  96. Remove the block from "ActiveBlockList".
  97. Use the array model because it's clearer.
  98. This function returns 0 if successful, -1 if not
  99. */
  100. int DestroyActiveObject(DISPLAYBLOCK *dblockptr)
  101. {
  102. int i, light;
  103. TXACTRLBLK *taptr;
  104. /* If the block ptr is OK, search the Active Blocks List */
  105. if(dblockptr) {
  106. for(i = 0; i < NumActiveBlocks; i++) {
  107. if(ActiveBlockList[i] == dblockptr) {
  108. ActiveBlockList[i] = ActiveBlockList[NumActiveBlocks-1];
  109. NumActiveBlocks--;
  110. ActiveBlockListPtr--;
  111. DestroyActiveVDB(dblockptr->ObVDBPtr); /* Checks for null */
  112. if(dblockptr->ObNumLights) {
  113. for(light = dblockptr->ObNumLights - 1; light != -1; light--)
  114. DeleteLightBlock(dblockptr->ObLights[light], dblockptr);
  115. }
  116. /* If no SB, deallocate any Texture Animation Blocks */
  117. if(dblockptr->ObStrategyBlock == 0) {
  118. if(dblockptr->ObTxAnimCtrlBlks) {
  119. taptr = dblockptr->ObTxAnimCtrlBlks;
  120. while(taptr) {
  121. DeallocateTxAnimBlock(taptr);
  122. taptr = taptr->tac_next;
  123. }
  124. }
  125. }
  126. /* Deallocate the Lazy Morphed Points Array Pointer */
  127. #if (SupportMorphing && LazyEvaluationForMorphing)
  128. if(dblockptr->ObMorphedPts) {
  129. DeallocateMem(dblockptr->ObMorphedPts);
  130. dblockptr->ObMorphedPts = 0;
  131. }
  132. #endif
  133. /* KJL 16:52:43 06/01/98 - dealloc sfx block if one exists */
  134. if(dblockptr->SfxPtr)
  135. {
  136. DeallocateSfxBlock(dblockptr->SfxPtr);
  137. }
  138. DeallocateObjectBlock(dblockptr); /* Back to Free List */
  139. /* If this is the current landscape, clear the pointer */
  140. return 0;
  141. }
  142. }
  143. }
  144. return -1;
  145. }
  146. /*
  147. Support Functions for Texture Animation Blocks
  148. */
  149. void InitialiseTxAnimBlocks(void)
  150. {
  151. TXACTRLBLK *FreeBlkPtr = &FreeTxAnimBlockData[0];
  152. FreeTxAnimBlockListPtr = &FreeTxAnimBlockList[maxTxAnimblocks-1];
  153. for(NumFreeTxAnimBlocks=0; NumFreeTxAnimBlocks < maxTxAnimblocks; NumFreeTxAnimBlocks++) {
  154. FreeTxAnimBlockList[NumFreeTxAnimBlocks] = FreeBlkPtr;
  155. FreeBlkPtr++;
  156. }
  157. }
  158. /*
  159. Allocate a Texture Animation Block
  160. */
  161. TXACTRLBLK* AllocateTxAnimBlock(void)
  162. {
  163. TXACTRLBLK *FreeBlkPtr = 0; /* Default to null ptr */
  164. int *sptr;
  165. int i;
  166. if(NumFreeTxAnimBlocks) {
  167. FreeBlkPtr = *FreeTxAnimBlockListPtr--;
  168. NumFreeTxAnimBlocks--; /* One less free block */
  169. /* Clear the block */
  170. sptr = (int *)FreeBlkPtr;
  171. for(i = sizeof(TXACTRLBLK)/4; i!=0; i--)
  172. *sptr++ = 0;
  173. }
  174. return FreeBlkPtr;
  175. }
  176. /*
  177. Deallocate a Texture Animation Block
  178. */
  179. void DeallocateTxAnimBlock(TXACTRLBLK *TxAnimblockptr)
  180. {
  181. FreeTxAnimBlockListPtr++;
  182. *FreeTxAnimBlockListPtr = TxAnimblockptr;
  183. NumFreeTxAnimBlocks++; /* One more free block */
  184. }
  185. /*
  186. Add a Texture Animation Block to a Display Block
  187. */
  188. void AddTxAnimBlock(DISPLAYBLOCK *dptr, TXACTRLBLK *taptr)
  189. {
  190. TXACTRLBLK *taptr_tmp;
  191. if(dptr->ObTxAnimCtrlBlks) {
  192. taptr_tmp = dptr->ObTxAnimCtrlBlks;
  193. while(taptr_tmp->tac_next)
  194. taptr_tmp = taptr_tmp->tac_next;
  195. taptr_tmp->tac_next = taptr;
  196. }
  197. else dptr->ObTxAnimCtrlBlks = taptr;
  198. }
  199. /*
  200. Support functions for Light Blocks
  201. */
  202. void InitialiseLightBlocks(void)
  203. {
  204. LIGHTBLOCK *FreeBlkPtr = &FreeLightBlockData[0];
  205. FreeLightBlockListPtr = &FreeLightBlockList[maxlightblocks-1];
  206. for(NumFreeLightBlocks=0; NumFreeLightBlocks < maxlightblocks; NumFreeLightBlocks++) {
  207. FreeLightBlockList[NumFreeLightBlocks] = FreeBlkPtr;
  208. FreeBlkPtr++;
  209. }
  210. }
  211. LIGHTBLOCK* AllocateLightBlock(void)
  212. {
  213. LIGHTBLOCK *FreeBlkPtr = 0; /* Default to null ptr */
  214. int *lptr;
  215. int i;
  216. if(NumFreeLightBlocks) {
  217. FreeBlkPtr = *FreeLightBlockListPtr--;
  218. NumFreeLightBlocks--; /* One less free block */
  219. /* Clear the block */
  220. lptr = (int *)FreeBlkPtr;
  221. for(i = sizeof(LIGHTBLOCK)/4; i!=0; i--)
  222. *lptr++ = 0;
  223. }
  224. return(FreeBlkPtr);
  225. }
  226. void DeallocateLightBlock(LIGHTBLOCK *lptr)
  227. {
  228. /* Not all lights come from the free light list */
  229. if(lptr->LightFlags & LFlag_WasNotAllocated) return;
  230. /* Make sure that this light IS from the free light list */
  231. GLOBALASSERT(
  232. (lptr >= FreeLightBlockData) &&
  233. (lptr < &FreeLightBlockData[maxlightblocks])
  234. );
  235. /* Ok to return the light */
  236. FreeLightBlockListPtr++;
  237. *FreeLightBlockListPtr = lptr;
  238. NumFreeLightBlocks++; /* One more free block */
  239. }
  240. /*
  241. See if there are any free slots in the dptr light block array.
  242. If there are, allocate a light block, place it in the list and return
  243. the pointer to the caller.
  244. A late addition is the passing of a light block (from somewhere, it does
  245. not matter where). This light block is then added rather than one being
  246. allocated from the free light block list.
  247. */
  248. LIGHTBLOCK* AddLightBlock(DISPLAYBLOCK *dptr, LIGHTBLOCK *lptr_to_add)
  249. {
  250. LIGHTBLOCK **larrayptr;
  251. LIGHTBLOCK **freelarrayptr;
  252. LIGHTBLOCK *lptr = 0;
  253. int i, lfree;
  254. /* Are there any free slots? */
  255. lfree = No;
  256. larrayptr = &dptr->ObLights[0];
  257. for(i = MaxObjectLights; i!=0 && lfree == No; i--) {
  258. if(*larrayptr == 0) {
  259. freelarrayptr = larrayptr;
  260. lfree = Yes;
  261. }
  262. larrayptr++;
  263. }
  264. if(lfree) {
  265. if(lptr_to_add) {
  266. lptr = lptr_to_add;
  267. }
  268. else {
  269. lptr = AllocateLightBlock();
  270. }
  271. if(lptr)
  272. {
  273. *freelarrayptr = lptr;
  274. dptr->ObNumLights++;
  275. }
  276. }
  277. return lptr;
  278. }
  279. /*
  280. To delete a light block, copy the end block to the new free slot and
  281. reduce the count by one. Make sure the end block array entry is cleared.
  282. */
  283. void DeleteLightBlock(LIGHTBLOCK *lptr, DISPLAYBLOCK *dptr)
  284. {
  285. int i, larrayi;
  286. DeallocateLightBlock(lptr);
  287. /* What is lptr's array index? */
  288. larrayi = -1; /* null value */
  289. for(i = 0; i < dptr->ObNumLights; i++)
  290. if(dptr->ObLights[i] == lptr) larrayi = i;
  291. /* Proceed only if lptr has been found in the array */
  292. if(larrayi != -1) {
  293. /* Copy the end block to that of lptr */
  294. dptr->ObLights[larrayi] = dptr->ObLights[dptr->ObNumLights - 1];
  295. /* Clear the end block array entry */
  296. dptr->ObLights[dptr->ObNumLights - 1] = 0;
  297. /* One less light in the dptr list */
  298. dptr->ObNumLights--;
  299. }
  300. }
  301. /*
  302. When running the parallel strategies, display and light block deallocation
  303. must only be done at the end of the frame, AFTER processor synchronisation
  304. and BEFORE the shadow copy.
  305. */
  306. int DisplayAndLightBlockDeallocation(void)
  307. {
  308. DISPLAYBLOCK **activeblocksptr;
  309. DISPLAYBLOCK *dptr;
  310. int i, j;
  311. LIGHTBLOCK *lptr;
  312. if(NumActiveBlocks) {
  313. activeblocksptr = &ActiveBlockList[NumActiveBlocks - 1];
  314. for(i = NumActiveBlocks; i!=0; i--) {
  315. dptr = *activeblocksptr--;
  316. /* Deallocate Object? */
  317. if(dptr->ObFlags2 & ObFlag2_Deallocate) {
  318. DestroyActiveObject(dptr);
  319. }
  320. /* Deallocate any Lights? */
  321. else {
  322. if(dptr->ObNumLights) {
  323. for(j = dptr->ObNumLights - 1; j > -1; j--) {
  324. lptr = dptr->ObLights[j];
  325. if(lptr->LightFlags & LFlag_Deallocate) {
  326. DeleteLightBlock(dptr->ObLights[j], dptr);
  327. }
  328. }
  329. }
  330. }
  331. }
  332. }
  333. return 0;
  334. }