Clone of Akilla's ac2d @ https://github.com/deregtd/AC2D

Landblocks.cpp 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  1. #include "stdafx.h"
  2. #include "Landblocks.h"
  3. BYTE landColor[33][4] = {
  4. {84, 67, 37, 110},
  5. {56, 66, 21, 110},
  6. {147, 154, 167, 110},
  7. {51, 69, 10, 110},
  8. {71, 37, 7, 113},
  9. {54, 34, 23, 113},
  10. {39, 35, 43, 113},
  11. {89, 65, 34, 113},
  12. {57, 41, 9, 113},
  13. {44, 77, 2, 113},
  14. {144, 99, 50, 113},
  15. {132, 132, 97, 113},
  16. {138, 93, 53, 114},
  17. {111, 68, 41, 114},
  18. {75, 85, 59, 114},
  19. {208, 219, 233, 114},
  20. {62, 108, 131, 130},
  21. {20, 79, 56, 130},
  22. {31, 80, 100, 130},
  23. {44, 76, 94, 130},
  24. {43, 59, 83, 130},
  25. {34, 47, 6, 130},
  26. {62, 108, 131, 130},
  27. {30, 38, 26, 130},
  28. {100, 79, 43, 130},
  29. {45, 33, 33, 130},
  30. {72, 72, 70, 130},
  31. {197, 227, 242, 130},
  32. {100, 79, 43, 130},
  33. {100, 79, 43, 130},
  34. {100, 79, 43, 130},
  35. {100, 79, 43, 130},
  36. {138, 130, 112, 130}
  37. };
  38. DWORD texnum[] = {
  39. /* 0x145C,
  40. 0x1459,
  41. 0x1468,
  42. 0x1456,
  43. 0x145E,
  44. 0x1462,
  45. 0x1463,
  46. 0x1465, //65140005
  47. 0x145B,
  48. 0x1457,
  49. 0x145D,
  50. 0x145F,
  51. 0x1467,
  52. 0x14A7,
  53. 0x145A,
  54. 0x1464,
  55. 0x146A,
  56. 0x1469,
  57. 0x146C,
  58. 0x1461,
  59. 0x146B,
  60. 0x1466,
  61. 0x1820,
  62. 0x1827,
  63. 0x1888,
  64. 0x181F,
  65. 0x1924,
  66. 0x1900,
  67. 0x1456,
  68. 0x1456,
  69. 0x1466,
  70. 0x1458*/
  71. 0x0500145C,
  72. 0x05001459,
  73. 0x05001468,
  74. 0x05001456,
  75. 0x05001467,
  76. 0x05001462,
  77. 0x05001463,
  78. 0x05001465,
  79. 0x0500145B,
  80. 0x05001457,
  81. 0x0500145D,
  82. 0x0500145F,
  83. 0x0500145E,
  84. 0x050014A7,
  85. 0x0500145A,
  86. 0x05001464,
  87. 0x0500146A,
  88. 0x05001461,
  89. 0x0500146C,
  90. 0x05001469,
  91. 0x0500146B,
  92. 0x05001466,
  93. 0x0500146A,
  94. 0x05001827,
  95. 0x0500145C,
  96. 0x0500181F,
  97. 0x05001924,
  98. 0x05001900,
  99. 0x05001C3A,
  100. 0x05001C3B,
  101. 0x05001C3C,
  102. 0x0500145C,
  103. 0x05001458
  104. };
  105. cLandblock::cLandblock()
  106. {
  107. m_wBlock = 0;
  108. }
  109. cLandblock::~cLandblock()
  110. {
  111. for (std::vector<cModelGroup *>::iterator i = Models.begin(); i != Models.end(); i++)
  112. delete *i;
  113. }
  114. void cLandblock::Load(WORD wBlock)
  115. {
  116. m_wBlock = wBlock;
  117. DWORD dwLB = ((DWORD) m_wBlock) << 16;
  118. //First load the FFFF
  119. cPortalFile *pfFFFF = m_Cell->OpenEntry(dwLB | 0xFFFF);
  120. if (!pfFFFF)
  121. {
  122. //Add request mechanism here...
  123. ZeroMemory(&m_lbFFFF, sizeof(stLandblockFFFF));
  124. return;
  125. }
  126. //Fill in FFFF structure
  127. memcpy(&m_lbFFFF, pfFFFF->data, sizeof(stLandblockFFFF));
  128. //If applicable, load object block
  129. if (m_lbFFFF.dwObjectBlock) //1 for block, 0 for none
  130. {
  131. //Now load the FFFE
  132. cPortalFile *pfFFFE = m_Cell->OpenEntry(dwLB | 0xFFFE);
  133. if (!pfFFFE)
  134. {
  135. //Add request mechanism here...
  136. return;
  137. }
  138. cByteStream pBS(pfFFFE->data, pfFFFE->length);
  139. pBS.ReadBegin();
  140. DWORD dwID = pBS.ReadDWORD();
  141. DWORD iNumCells = pBS.ReadDWORD();
  142. for (DWORD j=0;j<iNumCells;j++)
  143. {
  144. //Read the cells (0xYYXX01xx
  145. DWORD pfID = (dwLB | 0x0100) + j;
  146. cPortalFile *pfTemp = m_Cell->OpenEntry(pfID);
  147. if (!pfTemp)
  148. continue;
  149. cByteStream pBS2(pfTemp->data, pfTemp->length);
  150. pBS2.ReadBegin();
  151. pBS2.ReadDWORD(); //ID
  152. DWORD dwCellFlags = pBS2.ReadDWORD();
  153. pBS2.ReadDWORD(); //ID again for some reason
  154. BYTE bTexCount = pBS2.ReadByte(); //Num of words below
  155. BYTE bConnCount = pBS2.ReadByte(); //2x this = number of extra DWORDs down below
  156. WORD wVisCount = pBS2.ReadWORD();
  157. std::vector<WORD> vTexes;
  158. vTexes.clear();
  159. //These are texture refs for the dungeonpart
  160. for (int i=0; i<bTexCount; i++)
  161. vTexes.push_back(pBS2.ReadWORD());
  162. DWORD DungeonRef = 0x0D000000 | pBS2.ReadWORD(); //Dungeon Ref
  163. WORD DungeonPart = pBS2.ReadWORD(); //Which part of the dungeon ref it needs
  164. stLocation tpld;
  165. tpld.xOffset = pBS2.ReadFloat();
  166. tpld.yOffset = pBS2.ReadFloat();
  167. tpld.zOffset = pBS2.ReadFloat();
  168. tpld.wHeading = pBS2.ReadFloat();
  169. tpld.aHeading = pBS2.ReadFloat();
  170. tpld.bHeading = pBS2.ReadFloat();
  171. tpld.cHeading = pBS2.ReadFloat();
  172. tpld.landblock = dwLB;
  173. cPoint3D tp3d;
  174. tp3d.CalcFromLocation(&tpld);
  175. cModelGroup *DModel = new cModelGroup();
  176. if (!DModel->ReadDungeon(DungeonRef, DungeonPart, &vTexes))
  177. {
  178. return;
  179. }
  180. DModel->SetScale(1/240.0f);
  181. DModel->SetTranslation(tp3d);
  182. DModel->SetRotation(tpld.wHeading, tpld.aHeading, tpld.bHeading, tpld.cHeading);
  183. Models.push_back(DModel);
  184. //Kewt says this is connections to adjascent cells
  185. for (int i=0; i<bConnCount; i++)
  186. {
  187. pBS2.ReadWORD(); //Type
  188. pBS2.ReadWORD(); //Face
  189. pBS2.ReadWORD(); //Block
  190. pBS2.ReadWORD(); //Unknown
  191. }
  192. //List of visible cells from this cell
  193. for (int i=0; i<wVisCount; i++)
  194. pBS2.ReadWORD();
  195. if (dwCellFlags & 1)
  196. {
  197. //?...
  198. }
  199. if (dwCellFlags & 2)
  200. {
  201. //models!
  202. DWORD dwModelCount = pBS2.ReadDWORD();
  203. for (int i=0; i<(int)dwModelCount; i++)
  204. {
  205. DWORD dwModelID = pBS2.ReadDWORD();
  206. stLocation tpl;
  207. tpl.xOffset = pBS2.ReadFloat();
  208. tpl.yOffset = pBS2.ReadFloat();
  209. tpl.zOffset = pBS2.ReadFloat();
  210. tpl.wHeading = pBS2.ReadFloat();
  211. tpl.aHeading = pBS2.ReadFloat();
  212. tpl.bHeading = pBS2.ReadFloat();
  213. tpl.cHeading = pBS2.ReadFloat();
  214. tpl.landblock = dwLB;
  215. cPoint3D tp3d;
  216. tp3d.CalcFromLocation(&tpl);
  217. cModelGroup *Model = new cModelGroup();
  218. if (!Model->ReadModel(dwModelID))
  219. {
  220. return;
  221. // OutputString(eRed, "Failed model load: %08X", m_lbFFFE.Objects[j].dwID);
  222. // OutputConsoleString("Failed model load: %08X", dwModelID);
  223. }
  224. Model->SetScale(1/240.0f);
  225. Model->SetTranslation(tp3d);
  226. Model->SetRotation(tpl.wHeading, tpl.aHeading, tpl.bHeading, tpl.cHeading);
  227. Models.push_back(Model);
  228. }
  229. }
  230. if (dwCellFlags & 8)
  231. {
  232. pBS2.ReadDWORD(); //? - 7D2221A0
  233. }
  234. }
  235. DWORD iNumObjects = pBS.ReadDWORD();
  236. for (DWORD j=0;j<iNumObjects;j++)
  237. {
  238. DWORD dwModelID = pBS.ReadDWORD();
  239. stLocation tpl;
  240. tpl.xOffset = pBS.ReadFloat();
  241. tpl.yOffset = pBS.ReadFloat();
  242. tpl.zOffset = pBS.ReadFloat();
  243. tpl.wHeading = pBS.ReadFloat();
  244. tpl.aHeading = pBS.ReadFloat();
  245. tpl.bHeading = pBS.ReadFloat();
  246. tpl.cHeading = pBS.ReadFloat();
  247. tpl.landblock = dwLB;
  248. cPoint3D tp3d;
  249. tp3d.CalcFromLocation(&tpl);
  250. cModelGroup *Model = new cModelGroup();
  251. if (!Model->ReadModel(dwModelID))
  252. {
  253. return;
  254. // OutputString(eRed, "Failed model load: %08X", m_lbFFFE.Objects[j].dwID);
  255. // OutputConsoleString("Failed model load: %08X", dwModelID);
  256. }
  257. Model->SetScale(1/240.0f);
  258. Model->SetTranslation(tp3d);
  259. Model->SetRotation(tpl.wHeading, tpl.aHeading, tpl.bHeading, tpl.cHeading);
  260. Models.push_back(Model);
  261. }
  262. WORD wNumSkins = pBS.ReadWORD();
  263. WORD wSkinUnknown = pBS.ReadWORD();
  264. for (int j = 0; j < wNumSkins; j++)
  265. {
  266. DWORD dwModelID = pBS.ReadDWORD();
  267. stLocation tpl;
  268. tpl.xOffset = pBS.ReadFloat();
  269. tpl.yOffset = pBS.ReadFloat();
  270. tpl.zOffset = pBS.ReadFloat();
  271. tpl.wHeading = pBS.ReadFloat();
  272. tpl.aHeading = pBS.ReadFloat();
  273. tpl.bHeading = pBS.ReadFloat();
  274. tpl.cHeading = pBS.ReadFloat();
  275. tpl.landblock = dwLB;
  276. cPoint3D tp3d;
  277. tp3d.CalcFromLocation(&tpl);
  278. cModelGroup *Model = new cModelGroup();
  279. if (!Model->ReadModel(dwModelID))
  280. {
  281. return;
  282. // OutputString(eRed, "Failed model load: %08X", dwModelID);
  283. // OutputConsoleString("Failed model load: %08X", dwModelID);
  284. }
  285. Model->SetScale(1/240.0f);
  286. Model->SetTranslation(tp3d);
  287. Model->SetRotation(tpl.wHeading, tpl.aHeading, tpl.bHeading, tpl.cHeading);
  288. Models.push_back(Model);
  289. //Skip the strange data
  290. DWORD unknown1 = pBS.ReadDWORD();
  291. DWORD dwWeirdCount = pBS.ReadDWORD();
  292. for (DWORD k = 0; k < dwWeirdCount; k++)
  293. {
  294. DWORD dwUnk1 = pBS.ReadDWORD();
  295. WORD wUnk1 = pBS.ReadWORD();
  296. WORD wTableCount = pBS.ReadWORD();
  297. for (int l = 0; l < wTableCount; l++)
  298. {
  299. WORD wUnk2 = pBS.ReadWORD();
  300. }
  301. if (wTableCount & 1)
  302. pBS.ReadWORD();
  303. }
  304. }
  305. }
  306. }
  307. bool cLandblock::FSplitNESW(DWORD x, DWORD y)
  308. {
  309. DWORD dw = x * y * 0x0CCAC033 - x * 0x421BE3BD + y * 0x6C1AC587 - 0x519B8F25;
  310. return (dw & 0x80000000) != 0;
  311. }
  312. int cLandblock::Draw()
  313. {
  314. /*
  315. Landblock notes:
  316. Landblocks are XXYY____
  317. x is EW
  318. y is NS
  319. Landblocks start at (0,0) = SW corner
  320. */
  321. //Draw the FFFF
  322. float fXCorn, fYCorn;
  323. DWORD dwBlockX = (m_lbFFFF.dwID & 0xff000000) >> 24;
  324. DWORD dwBlockY = (m_lbFFFF.dwID & 0x00ff0000) >> 16;
  325. /* if (dwBlockX < 3)
  326. {
  327. // dungeon, dwBlockX and dwBlockY remain constant - just use x and y
  328. fXCorn = 0;
  329. fYCorn = 0;
  330. }
  331. else*/
  332. {
  333. // outdoors
  334. fXCorn = (float) ((((dwBlockX+1.00f) * 8.0f) - 1027.5) / 10.0f);
  335. fYCorn = (float) ((((dwBlockY+1.00f) * 8.0f) - 1027.5) / 10.0f);
  336. }
  337. float fDiv = 240.0f/2;
  338. glPushName(0xDEADBEEF);
  339. for (int y=0;y<8;y++)
  340. {
  341. for (int x=0;x<8;x++)
  342. {
  343. int type0;
  344. if ((m_lbFFFF.wTopo[x][y] & 0x0003)) type0 = 32;
  345. else type0 = (m_lbFFFF.wTopo[x][y] & 0x00FF) >> 2;
  346. bool NESW = FSplitNESW((dwBlockX * 8) | x, (dwBlockY * 8) | y);
  347. int tex1 = m_Portal->FindTexturePalette(texnum[type0], 0);
  348. glBindTexture( GL_TEXTURE_2D, tex1);
  349. glBegin(GL_TRIANGLE_FAN);
  350. glColor4f(1,1,1,1.0f);
  351. if (NESW)
  352. {
  353. glTexCoord2f(0,0);
  354. glVertex3f(fXCorn + x/10.0f, fYCorn + y/10.0f, m_lbFFFF.bZ[x][y]/fDiv);
  355. glTexCoord2f(2,0);
  356. glVertex3f(fXCorn + (x+1)/10.0f, fYCorn + y/10.0f, m_lbFFFF.bZ[x+1][y]/fDiv);
  357. glTexCoord2f(2,2);
  358. glVertex3f(fXCorn + (x+1)/10.0f, fYCorn + (y+1)/10.0f, m_lbFFFF.bZ[x+1][y+1]/fDiv);
  359. glTexCoord2f(0,2);
  360. glVertex3f(fXCorn + x/10.0f, fYCorn + (y+1)/10.0f, m_lbFFFF.bZ[x][y+1]/fDiv);
  361. }
  362. else
  363. {
  364. glTexCoord2f(2,0);
  365. glVertex3f(fXCorn + (x+1)/10.0f, fYCorn + y/10.0f, m_lbFFFF.bZ[x+1][y]/fDiv);
  366. glTexCoord2f(2,2);
  367. glVertex3f(fXCorn + (x+1)/10.0f, fYCorn + (y+1)/10.0f, m_lbFFFF.bZ[x+1][y+1]/fDiv);
  368. glTexCoord2f(0,2);
  369. glVertex3f(fXCorn + x/10.0f, fYCorn + (y+1)/10.0f, m_lbFFFF.bZ[x][y+1]/fDiv);
  370. glTexCoord2f(0,0);
  371. glVertex3f(fXCorn + x/10.0f, fYCorn + y/10.0f, m_lbFFFF.bZ[x][y]/fDiv);
  372. }
  373. glEnd();
  374. }
  375. }
  376. glPopName();
  377. //Draw the Objects
  378. int m_iTriCount = 8*8*2;
  379. for (std::vector<cModelGroup *>::iterator i = Models.begin(); i != Models.end(); i++)
  380. m_iTriCount += (*i)->Draw();
  381. return m_iTriCount;
  382. }
  383. // glColor4ub(landColor[type1][0], landColor[type1][1], landColor[type1][2], 255);
  384. /* glBegin(GL_LINE_STRIP);
  385. glColor4ub(landColor[type0][0], landColor[type0][1], landColor[type0][2], 255);
  386. glVertex3f(fXCorn + x/10.0f, fYCorn + y/10.0f, m_lbFFFF.bZ[x][y]/fDiv);
  387. glColor4ub(landColor[type1][0], landColor[type1][1], landColor[type1][2], 255);
  388. glVertex3f(fXCorn + (x+1)/10.0f, fYCorn + y/10.0f, m_lbFFFF.bZ[x+1][y]/fDiv);
  389. glColor4ub(landColor[type2][0], landColor[type2][1], landColor[type2][2], 255);
  390. glVertex3f(fXCorn + (x+1)/10.0f, fYCorn + (y+1)/10.0f, m_lbFFFF.bZ[x+1][y+1]/fDiv);
  391. glColor4ub(landColor[type3][0], landColor[type3][1], landColor[type3][2], 255);
  392. glVertex3f(fXCorn + x/10.0f, fYCorn + (y+1)/10.0f, m_lbFFFF.bZ[x][y+1]/fDiv);
  393. glEnd();
  394. glBegin(GL_LINE_STRIP);
  395. if (NESW)
  396. {
  397. glColor4ub(landColor[type0][0], landColor[type0][1], landColor[type0][2], 255);
  398. glVertex3f(fXCorn + x/10.0f, fYCorn + y/10.0f, m_lbFFFF.bZ[x][y]/fDiv);
  399. glColor4ub(landColor[type2][0], landColor[type2][1], landColor[type2][2], 255);
  400. glVertex3f(fXCorn + (x+1)/10.0f, fYCorn + (y+1)/10.0f, m_lbFFFF.bZ[x+1][y+1]/fDiv);
  401. }
  402. else
  403. {
  404. glColor4ub(landColor[type1][0], landColor[type1][1], landColor[type1][2], 255);
  405. glVertex3f(fXCorn + (x+1)/10.0f, fYCorn + y/10.0f, m_lbFFFF.bZ[x+1][y]/fDiv);
  406. glColor4ub(landColor[type3][0], landColor[type3][1], landColor[type3][2], 255);
  407. glVertex3f(fXCorn + x/10.0f, fYCorn + (y+1)/10.0f, m_lbFFFF.bZ[x][y+1]/fDiv);
  408. }
  409. glEnd();*/
  410. /* glBindTexture( GL_TEXTURE_2D, 0);
  411. if (type0 == 32)
  412. {
  413. glColor3f(1.0,1.0,1.0);
  414. glRasterPos3f(fXCorn + x/10.0f, fYCorn + y/10.0f, m_lbFFFF.bZ[x][y]/fDiv);
  415. char lele[50];
  416. sprintf(lele, "%02X - %08X - %04X", type0, texnum[type0], m_lbFFFF.wTopo[x][y]);
  417. glCallLists(strlen(lele), GL_UNSIGNED_BYTE, lele);
  418. }*/