Clone of PhatAC @ https://github.com/floaterxk/PhatAC

TurbineDungeon.cpp 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. #include "StdAfx.h"
  2. #include "TurbineDungeon.h"
  3. TurbineDungeon::TurbineDungeon(DWORD dwID) : TurbineObject(dwID)
  4. {
  5. m_dwNumPortals = 0;
  6. m_pPortals = NULL;
  7. }
  8. TurbineDungeon::~TurbineDungeon()
  9. {
  10. SafeDeleteArray(m_pPortals);
  11. }
  12. void TurbineDungeon::Initialize(BYTE *pbData, DWORD dwLength)
  13. {
  14. return; // Fix the BSP data
  15. BYTE *_data = pbData;
  16. BYTE* _dataend = pbData + dwLength;
  17. //fileID
  18. DWORD dwFileID = *((DWORD *)pbData);
  19. pbData += sizeof(DWORD);
  20. //numParts
  21. m_dwNumPortals = *((DWORD *)pbData);
  22. pbData += sizeof(DWORD);
  23. m_pPortals = new DUNGEONPORTAL[m_dwNumPortals];
  24. //if ( m_dwNumPortals == 1 ) __asm int 3;
  25. for (unsigned int i = 0; i < m_dwNumPortals; i++)
  26. {
  27. DWORD dwIndex = *((DWORD *)pbData);
  28. pbData += sizeof(DWORD);
  29. DUNGEONPORTAL* pPortal = &m_pPortals[dwIndex];
  30. if (dwIndex != i)
  31. __asm int 3;
  32. DWORD dwNumTriFans = *((DWORD *)pbData);
  33. if (dwNumTriFans > 1000)
  34. __asm int 3;
  35. pbData += sizeof(DWORD);
  36. //if (pPortal->m_dwNumTriFans > 100000) .. owwww...
  37. DWORD dwNumPads = *((DWORD *)pbData);
  38. pbData += sizeof(DWORD);
  39. DWORD dwUnk1 = *((DWORD *)pbData);
  40. pbData += sizeof(DWORD);
  41. DWORD dwUnk2 = *((DWORD *)pbData);
  42. pbData += sizeof(DWORD);
  43. DWORD dwNumVertices = *((DWORD *)pbData);
  44. if (dwNumVertices > 1000)
  45. __asm int 3;
  46. pbData += sizeof(DWORD);
  47. pPortal->m_dwNumVertices = dwNumVertices;
  48. pPortal->m_pVertices = new DUNGEONVERTEX[dwNumVertices];
  49. for (unsigned int j = 0; j < dwNumVertices; j++)
  50. {
  51. DUNGEONVERTEX* pVertex = &pPortal->m_pVertices[*((WORD *)pbData)];
  52. pbData += sizeof(WORD);
  53. WORD wNumSTs = *((WORD *)pbData);
  54. pbData += sizeof(WORD);
  55. pVertex->x = *((float *)pbData);
  56. pbData += sizeof(float);
  57. pVertex->y = *((float *)pbData);
  58. pbData += sizeof(float);
  59. pVertex->z = *((float *)pbData);
  60. pbData += sizeof(float);
  61. pVertex->nx = *((float *)pbData);
  62. pbData += sizeof(float);
  63. pVertex->ny = *((float *)pbData);
  64. pbData += sizeof(float);
  65. pVertex->nz = *((float *)pbData);
  66. pbData += sizeof(float);
  67. for (unsigned int k = 0; k < wNumSTs; k++) {
  68. //S
  69. pbData += sizeof(float);
  70. //T
  71. pbData += sizeof(float);
  72. }
  73. }
  74. //if ( dwFileID == 218103889 && i == 0 )
  75. // __asm int 3;
  76. pPortal->m_pTriFans = new DUNGEONTRIFAN[dwNumTriFans];
  77. pPortal->m_dwNumTriFans = dwNumTriFans;
  78. for (unsigned int j = 0; j < dwNumTriFans; j++)
  79. {
  80. //polyNum
  81. WORD polyNum = *((WORD *)pbData);
  82. if (polyNum != j)
  83. {
  84. // DebugMe();
  85. }
  86. DUNGEONTRIFAN* pTriFan = &pPortal->m_pTriFans[polyNum];
  87. pbData += sizeof(WORD);
  88. unsigned char cNumVerts = *((unsigned char *)pbData);
  89. pbData += sizeof(unsigned char);
  90. unsigned char cType = *((unsigned char *)pbData);
  91. pbData += sizeof(unsigned char);
  92. //??
  93. pbData += sizeof(DWORD);
  94. WORD numTex = *((WORD *)pbData);
  95. pbData += sizeof(WORD);
  96. //??
  97. pbData += sizeof(WORD);
  98. pTriFan->m_pVertexIndices = new WORD[cNumVerts];
  99. pTriFan->m_cNumVertices = cNumVerts;
  100. for (unsigned int k = 0; k < cNumVerts; k++) {
  101. // vertNum
  102. pTriFan->m_pVertexIndices[k] = *((WORD *)pbData);
  103. pbData += sizeof(WORD);
  104. }
  105. if (cType == 4) {
  106. if (cNumVerts & 1)
  107. pbData += sizeof(WORD);
  108. continue;
  109. }
  110. for (unsigned int k = 0; k < cNumVerts; k++)
  111. {
  112. //stNum index for each vertex..
  113. pbData += sizeof(unsigned char);
  114. }
  115. //if ( (cNumVerts * 4 + cNumVerts * 2) % 8 != 0 )
  116. //{
  117. // pbData += sizeof(unsigned char) * ((8 - ((cNumVerts * 4 + cNumVerts * 2) % 8)) / 2);
  118. //}
  119. if ((pbData - _data) & 3) //DWORD-align
  120. pbData += (sizeof(DWORD) - ((pbData - _data) & 3));
  121. }
  122. if ((i + 1) == m_dwNumPortals)
  123. break;
  124. // 0x0006 0x0008 0x0007 0x0000
  125. pbData += dwUnk1 * sizeof(WORD);
  126. if ((pbData - _data) & 3) //DWORD-align
  127. pbData += (4 - ((pbData - _data) & 3));
  128. DWORD* obj = (DWORD *)pbData;
  129. unsigned int k = 0;
  130. while (k < 1/*dwNumPads*/) {
  131. // BPnn = 0x42506E6E = 4 floats?
  132. // BPnN = 0x42506E4E = 4 floats?
  133. // BPLF = 0x4250.... = 4 floats?
  134. // BPIn = 0x4250496E = 4 floats?
  135. //
  136. /*
  137. LEAF (0x4C454146):
  138. DWORD- Index
  139. DWORD- Zero
  140. DWORDx4 - CDCDCDCDh
  141. DWORD- NodeCount?
  142. WORD[NodeCount] Indices?
  143. --dword align--
  144. floatX4[NodeCount] who knows
  145. */
  146. DWORD part = obj[0]; obj++;
  147. if (part == 0)
  148. __asm int 3;
  149. else if (part == 0x42506E6E) //BPnn
  150. obj += 4;
  151. else if (part == 0x42506E4E) //BPnN
  152. obj += 4;
  153. else if (part == 0x4250464C) //BPFL ... not BPLF?
  154. {
  155. obj += 4;
  156. break;
  157. }
  158. else
  159. {
  160. _DebugMe();
  161. }
  162. //k++;
  163. }
  164. pbData = (BYTE *)obj;
  165. for (unsigned int j = 0; j < dwNumPads; j++)
  166. {
  167. //polyNum
  168. pbData += sizeof(WORD);
  169. unsigned char cNumVerts = *((unsigned char *)pbData);
  170. pbData += sizeof(unsigned char);
  171. unsigned char cType = *((unsigned char *)pbData);
  172. pbData += sizeof(unsigned char);
  173. //??
  174. pbData += sizeof(DWORD);
  175. WORD numTex = *((WORD *)pbData);
  176. pbData += sizeof(WORD);
  177. //??
  178. pbData += sizeof(WORD);
  179. for (unsigned int k = 0; k < cNumVerts; k++) {
  180. // vertNum
  181. pbData += sizeof(WORD);
  182. }
  183. if (cType == 4) {
  184. if (cNumVerts & 1)
  185. pbData += sizeof(WORD);
  186. continue;
  187. }
  188. for (unsigned int k = 0; k < cNumVerts; k++)
  189. {
  190. //stNum index for each vertex..
  191. pbData += sizeof(unsigned char);
  192. }
  193. //if ( (cNumVerts * 4 + cNumVerts * 2) % 8 != 0 )
  194. //{
  195. // pbData += sizeof(unsigned char) * ((8 - ((cNumVerts * 4 + cNumVerts * 2) % 8)) / 2);
  196. //}
  197. if ((pbData - _data) & 3) //DWORD-align
  198. pbData += (sizeof(DWORD) - ((pbData - _data) & 3));
  199. }
  200. obj = (DWORD *)pbData;
  201. k = 0;
  202. bool hasdata = false;
  203. while (k < dwNumPads || k < dwNumTriFans) {
  204. // BPnn = 0x42506E6E = 4 floats?
  205. // BPnN = 0x42506E4E = 4 floats?
  206. // BPLF = 0x4250.... = 4 floats?
  207. // BPIn = 0x4250496E = 4 floats?
  208. //
  209. /*
  210. LEAF (0x4C454146):
  211. DWORD- Index
  212. DWORD- Zero
  213. DWORDx4 - CDCDCDCDh
  214. DWORD- NodeCount?
  215. WORD[NodeCount] Indices?
  216. --dword align--
  217. floatX4[NodeCount] who knows
  218. */
  219. DWORD part = obj[0]; obj++;
  220. if (part == 0x42506E6E) //BPnn
  221. obj += 4;
  222. else if (part == 0x42506E4E) //BPnN
  223. obj += 4;
  224. else if (part == 0x42504C46) //BPLF
  225. obj += 4;
  226. else if (part == 0x4250496E) //BPIn
  227. obj += 4;
  228. else if (part == 0x4C454146) //LEAF
  229. {
  230. obj += 1; //index
  231. obj += 1; //zero
  232. obj += 4; //CDCDCDCDh
  233. DWORD nodecount = *obj;
  234. obj += 1;
  235. obj += (nodecount + 1) / 2;
  236. if (nodecount)
  237. obj += 4; //buncha floats
  238. }
  239. else if (part == 0x4270496E || part == 0x42504F4C) //BpIn? and BPOL?
  240. {
  241. obj += 4;
  242. while ((!obj[0]) || (obj[0] > m_dwNumPortals)) {
  243. obj += 4;
  244. k += obj[0];
  245. obj += 1 + ((obj[0] + 1) / 2);
  246. }
  247. hasdata = true;
  248. break;
  249. }
  250. else if (obj[0] < m_dwNumPortals && hasdata)
  251. {
  252. //if ( ((BYTE *)(obj + 2))
  253. break;
  254. }
  255. }
  256. pbData = (BYTE *)obj;
  257. }
  258. }
  259. //#define LANDING_NORMAL( v ) \
  260. // ( ((v->nx == 0.0f) && (v->ny == 0.0f) && (v->nz == 1.0f)) ? TRUE : FALSE )
  261. BOOL TurbineDungeon::IsLandingZone(DUNGEONVERTEX* pVertex1, DUNGEONVERTEX* pVertex2, DUNGEONVERTEX* pVertex3)
  262. {
  263. //if ( BLOCK_WORD( m_dwID ) == 0x2FA )
  264. // break;
  265. //3EA = broke (part1)
  266. /*if ( m_dwID == 0x0D0003EA )
  267. {
  268. LOG(Temp, Normal, "--\n%.01f %.01f %.01f, %.01f %.01f %.01f\n",
  269. pVertex1->x, pVertex1->y, pVertex1->z,
  270. pVertex1->nx, pVertex1->ny, pVertex1->nz );
  271. LOG(Temp, Normal, "%.01f %.01f %.01f, %.01f %.01f %.01f\n",
  272. pVertex2->x, pVertex2->y, pVertex2->z,
  273. pVertex2->nx, pVertex2->ny, pVertex2->nz );
  274. LOG(Temp, Normal, "%.01f %.01f %.01f, %.01f %.01f %.01f\n",
  275. pVertex3->x, pVertex3->y, pVertex3->z,
  276. pVertex3->nx, pVertex3->ny, pVertex3->nz );
  277. }*/
  278. const float width_tolerance = 0.8f;
  279. const float normal_tolerance = 1.0f;
  280. const float height_tolerance = 0.5f;
  281. if (pVertex1->nz < normal_tolerance &&
  282. pVertex2->nz < normal_tolerance &&
  283. pVertex3->nz < normal_tolerance)
  284. return FALSE;
  285. if ((fabs(pVertex3->x - pVertex1->x) < width_tolerance) &&
  286. (fabs(pVertex2->x - pVertex1->x) < width_tolerance) &&
  287. (fabs(pVertex3->x - pVertex2->x) < width_tolerance))
  288. return FALSE;
  289. if ((fabs(pVertex3->y - pVertex1->y) < width_tolerance) &&
  290. (fabs(pVertex2->y - pVertex1->y) < width_tolerance) &&
  291. (fabs(pVertex3->y - pVertex2->y) < width_tolerance))
  292. return FALSE;
  293. if ((fabs(pVertex3->z - pVertex1->z) > height_tolerance) ||
  294. (fabs(pVertex2->z - pVertex1->z) > height_tolerance) ||
  295. (fabs(pVertex3->z - pVertex2->z) > height_tolerance))
  296. return FALSE;
  297. /*if ( m_dwID == 0x0D00011B )
  298. {
  299. LOG(Temp, Normal, "--\n%.01f %.01f %.01f, %.01f %.01f %.01f\n",
  300. pVertex1->x, pVertex1->y, pVertex1->z,
  301. pVertex1->nx, pVertex1->ny, pVertex1->nz );
  302. LOG(Temp, Normal, "%.01f %.01f %.01f, %.01f %.01f %.01f\n",
  303. pVertex2->x, pVertex2->y, pVertex2->z,
  304. pVertex2->nx, pVertex2->ny, pVertex2->nz );
  305. LOG(Temp, Normal, "%.01f %.01f %.01f, %.01f %.01f %.01f\n",
  306. pVertex3->x, pVertex3->y, pVertex3->z,
  307. pVertex3->nx, pVertex3->ny, pVertex3->nz );
  308. }*/
  309. return TRUE;
  310. }
  311. loc_t TurbineDungeon::FindLandingZone(WORD wPortal)
  312. {
  313. loc_t LZ;
  314. LZ.landcell = FALSE;
  315. if (wPortal > m_dwNumPortals)
  316. {
  317. _DebugMe();
  318. return LZ;
  319. }
  320. DUNGEONPORTAL* pPortal = &m_pPortals[wPortal];
  321. if (!pPortal)
  322. {
  323. LOG(Temp, Normal, "Missing portal %u in %08X.\n", wPortal, GetID());
  324. }
  325. else
  326. {
  327. /*for ( unsigned int j = 0; j < pPortal->m_dwNumVertices; j++ )
  328. {
  329. DUNGEONVERTEX* pVertex = &pPortal->m_pVertices[ j ];
  330. if ( !pVertex )
  331. {
  332. LOG(Temp, Normal, "Missing vertex zone!\n");
  333. continue;
  334. }
  335. if ( pVertex->nx == 0.0f && pVertex->ny == 0.0f && pVertex->nz == 1.0f )
  336. {
  337. LZ.landcell = TRUE;
  338. LZ.x = pVertex->x;
  339. LZ.y = pVertex->y;
  340. LZ.z = pVertex->z;
  341. //LOG(Temp, Normal, "Found landing zone.\n");
  342. //return LZ;
  343. }
  344. }*/
  345. for (unsigned int i = 0; i < pPortal->m_dwNumTriFans; i++)
  346. {
  347. DUNGEONTRIFAN* pTriFan = &pPortal->m_pTriFans[i];
  348. if (!pTriFan)
  349. {
  350. _DebugMe();
  351. continue;
  352. }
  353. if (!pTriFan->m_cNumVertices)
  354. {
  355. _DebugMe();
  356. continue;
  357. }
  358. DUNGEONVERTEX* pBaseVertex = &pPortal->m_pVertices[pTriFan->m_pVertexIndices[0]];
  359. for (unsigned int j = 1; j < (unsigned)(pTriFan->m_cNumVertices - 1); j++)
  360. {
  361. DUNGEONVERTEX* pVertex2 = &pPortal->m_pVertices[pTriFan->m_pVertexIndices[j]];
  362. DUNGEONVERTEX* pVertex3 = &pPortal->m_pVertices[pTriFan->m_pVertexIndices[j + 1]];
  363. if (!IsLandingZone(pBaseVertex, pVertex2, pVertex3))
  364. continue;
  365. //LOG(Temp, Normal, "Found landing zone! %f %f %f %f %f %f\n",
  366. // pVertex2->nx, pVertex2->ny, pVertex2->nz,
  367. // pVertex3->nx, pVertex3->ny, pVertex3->nz);
  368. LZ.landcell = TRUE;
  369. //LZ.x = (pBaseVertex->x + pVertex2->x) / 2;
  370. //LZ.y = (pBaseVertex->y + pVertex2->y) / 2;
  371. //LZ.z = (pBaseVertex->z + pVertex2->z) / 2;
  372. LZ.x = (pBaseVertex->x + pVertex2->x + pVertex3->x) / 3;
  373. LZ.y = (pBaseVertex->y + pVertex2->y + pVertex3->y) / 3;
  374. LZ.z = (pBaseVertex->z + pVertex2->z + pVertex3->z) / 3;
  375. return LZ;
  376. }
  377. }
  378. //LOG(Temp, Normal, "Couldn't find landing zone.\n");
  379. }
  380. return LZ;
  381. }