Open Source Tomb Raider Engine
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

UTPackage.cpp 25KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253
  1. /* -*- Mode: C++; tab-width: 3; indent-tabs-mode: t; c-basic-offset: 3 -*- */
  2. /*================================================================
  3. *
  4. * Project : OpenRaider, PSKModel viewer, libhel_modelloader
  5. * Author : Terry 'Mongoose' Hendrix II
  6. * Website : http://www.westga.edu/~stu7440/
  7. * Email : stu7440@westga.edu
  8. * Object : UTPackage
  9. * License : No use w/o permission (C) 2003 Mongoose
  10. * Comments: This class handles UT packages
  11. *
  12. *
  13. * This file was generated using Mongoose's C++
  14. * template generator script. <stu7440@westga.edu>
  15. *
  16. *-- History -------------------------------------------------
  17. *
  18. * 2003.07.11:
  19. * Mongoose - Created, form old PSKModel prototype
  20. =================================================================*/
  21. #include <stdio.h>
  22. #include <sys/stat.h>
  23. #include <string.h>
  24. #include <stdlib.h>
  25. #include <stdarg.h>
  26. #include <math.h>
  27. #include "mtk_tga.h"
  28. #include "UTPackage.h"
  29. //#define USE_PROPERTY_STRUCT
  30. char *get_utx_name(unsigned int version, FILE *f)
  31. {
  32. unsigned int i, l;
  33. unsigned char sl;
  34. char buffer[256];
  35. char *s;
  36. if (version < 64)
  37. {
  38. for (i = 0; i < 255; ++i)
  39. {
  40. fread(buffer+i, 1, 1, f);
  41. buffer[i+1] = 0;
  42. if (buffer[i] == '\0')
  43. {
  44. break;
  45. }
  46. }
  47. l = i;
  48. s = new char[l];
  49. strcpy(s, buffer);
  50. }
  51. else
  52. {
  53. fread(&sl, 1, 1, f);
  54. s = new char[sl];
  55. fread(s, sl, 1, f);
  56. }
  57. return s;
  58. }
  59. int get_utx_array_index(FILE *f)
  60. {
  61. unsigned char u8;
  62. short u16;
  63. int index, u32;
  64. fread(&u8, 1, 1, f);
  65. if (u8 < 128)
  66. {
  67. index = (unsigned int)u8;
  68. }
  69. else
  70. {
  71. fseek(f, -1, SEEK_SET);
  72. fread(&u16, 2, 1, f);
  73. if (u16 < 16384 )
  74. {
  75. index = (unsigned int)u16;
  76. }
  77. else
  78. {
  79. fseek(f, -2, SEEK_SET);
  80. fread(&u32, 4, 1, f);
  81. index = u32 & 0x3fffffff;
  82. }
  83. }
  84. return index;
  85. }
  86. int get_utx_index(FILE *f)
  87. {
  88. unsigned int index, data;
  89. int vindex;
  90. unsigned short shift = 6;
  91. unsigned char b;
  92. bool sign;
  93. fread(&b, 1, 1, f);
  94. sign = (b & INDEX_SIGN_BIT) != 0;
  95. index = b & INDEX_BYT1_MASK;
  96. if (b & INDEX_CONT1_BIT)
  97. {
  98. do {
  99. fread(&b, 1, 1, f);
  100. data = b & INDEX_BYTE_MASK;
  101. data = ((unsigned int)data) << shift;
  102. index = index | data;
  103. shift = (unsigned short)(shift + 7);
  104. } while ((b & INDEX_CONT_BIT) && (shift < 32));
  105. }
  106. vindex = index;
  107. return ((sign) ? -vindex : vindex);
  108. }
  109. unsigned int use_utx_index(int index, unsigned int *type)
  110. {
  111. if (index == 0)
  112. {
  113. *type = UTPackage::UT_NULL;
  114. return 0;
  115. }
  116. else if (index < 0)
  117. {
  118. *type = UTPackage::UT_IMPORT; // import entry
  119. // return ((-index)-1);
  120. return (-index - 1);
  121. }
  122. *type = UTPackage::UT_EXPORT; // export entry
  123. return (index-1);
  124. }
  125. /* Hexdump util */
  126. void hex_dump(FILE *f, unsigned char *buffer, unsigned int size);
  127. #define hex_dump_file(f, size) hex_dump(f, 0x0, size)
  128. #define hex_dump_buffer(buffer, size) hex_dump(0x0, buffer, size)
  129. void hex_dump(FILE *f, unsigned char *buffer, unsigned int size)
  130. {
  131. unsigned int i, j;
  132. unsigned char u;
  133. char s[16];
  134. char none = 183;
  135. memset(s, 0, 16);
  136. /* Dump it out all pretty */
  137. if (f)
  138. {
  139. printf("[Hexdumping, Offset 0x%08lx to 0x%08lx, %u bytes]\n",
  140. ftell(f), ftell(f)+size, size);
  141. }
  142. else if (buffer)
  143. {
  144. printf("[Hexdumping buffer, %u bytes]\n", size);
  145. }
  146. else
  147. {
  148. printf("Nothing to hexdump!\n");
  149. return;
  150. }
  151. for (i = 0, j = 0; i < size; ++i, ++j)
  152. {
  153. if (f) // Dump from file
  154. {
  155. fread(&u, 1, 1, f);
  156. }
  157. else // Dump from buffer
  158. {
  159. u = buffer[i];
  160. }
  161. s[j] = u;
  162. /* Print ASCII */
  163. if (j == 16)
  164. {
  165. printf(" ");
  166. for (j = 0; j < 16; ++j)
  167. {
  168. printf("%s",
  169. ((j == 0) ? "" :
  170. (j%8 == 0) ? " ":
  171. (j%4 == 0) ? " " : ""));
  172. if (s[j] > 32 && s[j] < 127)
  173. printf("%c", s[j]);
  174. else
  175. printf("%c", none);
  176. }
  177. j = 0;
  178. memset(s, 0, 16);
  179. }
  180. /* Print Hex */
  181. printf("%s%02X",
  182. ((i == 0) ? "" :
  183. ((i%16 == 0) ? "\n" :
  184. ((i%8 == 0) ? " ":
  185. (i%4 == 0) ? " " : " "))),
  186. u);
  187. }
  188. if (j < 16 && j != 0)
  189. {
  190. i = 16 - j;
  191. for (j = 0; j < i; ++j)
  192. {
  193. printf("%s ",
  194. ((j == 0) ? " " :
  195. ((j%16 == 0) ? "\n" :
  196. ((j%8 == 0) ? " ":
  197. (j%4 == 0) ? " " : " "))));
  198. }
  199. printf(" ");
  200. for (j = 0; j < 16; ++j)
  201. {
  202. printf("%s",
  203. ((j == 0) ? "" :
  204. (j%8 == 0) ? " ":
  205. (j%4 == 0) ? " " : ""));
  206. if (s[j] > 32 && s[j] < 127)
  207. printf("%c", s[j]);
  208. else
  209. printf("%c", none);
  210. }
  211. }
  212. printf("\n");
  213. }
  214. int dump_file(FILE *f, unsigned int size, char *s, ...)
  215. {
  216. char buffer[1024];
  217. FILE *f2;
  218. va_list args;
  219. if (!f || size <= 0)
  220. return -1;
  221. va_start(args, s);
  222. vsnprintf(buffer, 1023, s, args);
  223. va_end(args);
  224. f2 = fopen(buffer, "wb");
  225. if (!f2)
  226. {
  227. perror(buffer);
  228. return -2;
  229. }
  230. while (size > 1024)
  231. {
  232. fread(buffer, 1, 1024, f);
  233. fwrite(buffer, 1, 1024, f2);
  234. if (size - 1024 < 0)
  235. break;
  236. size -= 1024;
  237. }
  238. fread(buffer, 1, size, f);
  239. fwrite(buffer, 1, size, f2);
  240. fclose(f2);
  241. return 0;
  242. }
  243. //////////////////////////////////////////////////////////////////////
  244. // UTPackageProperty Class
  245. //////////////////////////////////////////////////////////////////////
  246. UTPackageProperty::UTPackageProperty()
  247. {
  248. index = 0;
  249. nameIndex = 0;
  250. size = 0;
  251. type = 0;
  252. flags = 0;
  253. data = 0x0;
  254. }
  255. UTPackageProperty::~UTPackageProperty()
  256. {
  257. clear();
  258. }
  259. void UTPackageProperty::clear()
  260. {
  261. index = 0;
  262. nameIndex = 0;
  263. size = 0;
  264. type = 0;
  265. flags = 0;
  266. if (data)
  267. delete [] data;
  268. }
  269. int UTPackageProperty::load(utx_header_t *header, FILE *f)
  270. {
  271. bool isArray;
  272. unsigned char info;//, u8;
  273. unsigned short u16;
  274. unsigned int u32;
  275. int idx;
  276. /* Property */
  277. index = get_utx_index(f);
  278. nameIndex = ((type == UTPackage::UT_NULL) ? 0 :
  279. (type == UTPackage::UT_IMPORT) ?
  280. header->importTable[index].objName :
  281. header->exportTable[index].objName);
  282. if (index >= 0)
  283. nameIndex = index;
  284. if (nameIndex > header->nameCount)
  285. {
  286. printf("index = %i nameIndex = %i ERROR Out of bounds\n",
  287. index, nameIndex);
  288. return -2;
  289. }
  290. printf("\n{ index = %i, '%s'\n", nameIndex,
  291. ((nameIndex >= 0) ? header->nameTable[nameIndex].objName :
  292. "Bad Index"));
  293. if (nameIndex < 0 ||
  294. strcmp("None", header->nameTable[nameIndex].objName) == 0)
  295. {
  296. return -1;
  297. }
  298. /* Read info byte */
  299. fread(&info, 1, 1, f);
  300. isArray = (info & PROPERTY_ARRAY_MASK) != 0;
  301. type = (info & PROPERTY_TYPE_MASK);
  302. switch (info & PROPERTY_SIZE_MASK)
  303. {
  304. case 0x00:
  305. size = 1;
  306. break;
  307. case 0x10:
  308. size = 2;
  309. break;
  310. case 0x20:
  311. size = 4;
  312. break;
  313. case 0x30:
  314. size = 12;
  315. break;
  316. case 0x40:
  317. size = 16;
  318. break;
  319. case 0x50:
  320. fread(&info, 1, 1, f);
  321. size = info;
  322. break;
  323. case 0x60:
  324. fread(&u16, 2, 1, f);
  325. size = u16;
  326. break;
  327. case 0x70:
  328. fread(&size, 4, 1, f);
  329. break;
  330. }
  331. printf(" size %u, type 0x%x, flags 0x%x\n",
  332. size, type, flags);
  333. idx = 1;
  334. switch (type)
  335. {
  336. case UNP_ByteProperty:
  337. if (isArray)
  338. {
  339. idx = get_utx_array_index(f);
  340. }
  341. data = new unsigned char[1*idx];
  342. fread(data, 1, idx, f);
  343. printf(" %i byte 0x%02x", idx, data[0]);
  344. break;
  345. case UNP_IntProperty:
  346. if (isArray)
  347. {
  348. idx = get_utx_array_index(f);
  349. }
  350. data = new unsigned char[4*idx];
  351. fread(data, 4, idx, f);
  352. printf(" %i int %i", idx, *((int *)data));
  353. break;
  354. case UNP_BoolProperty:
  355. printf(" bool 0x%x\n", isArray);
  356. data = new unsigned char[1];
  357. data[0] = isArray;
  358. break;
  359. case UNP_FloatProperty:
  360. if (isArray)
  361. {
  362. idx = get_utx_array_index(f);
  363. }
  364. fread(&u32, 4, 1, f);
  365. printf(" float %f", *((float *)&u32));
  366. break;
  367. case UNP_ObjectProperty:
  368. case UNP_NameProperty: // SetObjectProperty( aUf );
  369. if (isArray)
  370. {
  371. idx = get_utx_array_index(f);
  372. }
  373. if (isArray)
  374. {
  375. idx = get_utx_index(f);
  376. }
  377. hex_dump_buffer((unsigned char *)&idx, 4);
  378. break;
  379. case UNP_StrProperty:
  380. printf(" String:\n");
  381. hex_dump_file(f, size);
  382. break;
  383. case UNP_StringProperty:
  384. printf(" ASCII String:\n");
  385. hex_dump_file(f, size);
  386. break;
  387. case UNP_StructProperty:
  388. printf(" Struct:\n");
  389. #ifdef USE_PROPERTY_STRUCT
  390. idx = get_utx_index(f);
  391. if (isArray)
  392. {
  393. get_utx_array_index(f);
  394. }
  395. if (idx > (int)header->nameCount || idx < 0)
  396. {
  397. printf(" idx = %i\n", idx);
  398. hex_dump_file(f, size);
  399. }
  400. else if (strcmp("Color", header->nameTable[idx].objName) == 0)
  401. {
  402. //fread(&u32, 4, 1, f);
  403. hex_dump_file(f, 4); /* RGBA */
  404. }
  405. else if (strcmp("Vector", header->nameTable[idx].objName) == 0)
  406. {
  407. /* XYZ */
  408. fread(&u32, 4, 1, f);
  409. printf(" float %f", *((float *)&u32));
  410. fread(&u32, 4, 1, f);
  411. printf(" float %f", *((float *)&u32));
  412. fread(&u32, 4, 1, f);
  413. printf(" float %f", *((float *)&u32));
  414. }
  415. else if (strcmp("Rotator", header->nameTable[idx].objName) == 0)
  416. {
  417. /* Pitch, Roll, Yaw */
  418. fread(&u32, 4, 1, f);
  419. printf(" float %f", *((float *)&u32));
  420. fread(&u32, 4, 1, f);
  421. printf(" float %f", *((float *)&u32));
  422. fread(&u32, 4, 1, f);
  423. printf(" float %f", *((float *)&u32));
  424. }
  425. else if (strcmp("Scale", header->nameTable[idx].objName) == 0)
  426. {
  427. /* XYZ, sheer rate, sheer axis */
  428. fread(&u32, 4, 1, f);
  429. printf(" float %f", *((float *)&u32));
  430. fread(&u32, 4, 1, f);
  431. printf(" float %f", *((float *)&u32));
  432. fread(&u32, 4, 1, f);
  433. printf(" float %f", *((float *)&u32));
  434. fread(&u32, 4, 1, f);
  435. printf(" %i\n", u32);
  436. fread(&u8, 1, 1, f);
  437. printf(" %i\n", u8);
  438. }
  439. else if (strcmp("PointRegion", header->nameTable[idx].objName) == 0)
  440. {
  441. get_utx_index(f);
  442. fread(&u32, 4, 1, f);
  443. fread(&u8, 1, 1, f);
  444. }
  445. else
  446. {
  447. printf("UNKOWN Struct\n");
  448. hex_dump_file(f, size);
  449. }
  450. #else
  451. hex_dump_file(f, size);
  452. #endif
  453. break;
  454. case UNP_ArrayProperty: //SetArrayProperty( aUf, aUn, aUi, aUe );
  455. printf(" ** Array Property!\n");
  456. hex_dump_file(f, size);
  457. break;
  458. case UNP_ClassProperty:
  459. case UNP_VectorProperty:
  460. case UNP_RotatorProperty:
  461. case UNP_FixedArrayProperty: // SetUnknownProperty( aUn, aUf )
  462. printf(" ** Unknown/Unsupported Property!\n");
  463. //data = new unsigned char[size];
  464. //fread(data, 1, size, f);
  465. hex_dump_file(f, size);
  466. break;
  467. case UNP_MapProperty:
  468. printf(" ** Map Property!\n");
  469. hex_dump_file(f, size);
  470. break;
  471. }
  472. printf(" }\n");
  473. return 0;
  474. }
  475. int load_utx(char *filename, bool hexDump, bool diskDump)
  476. {
  477. FILE *f;
  478. unsigned int i, index, type;
  479. utx_header_t header;
  480. f = fopen(filename, "rb");
  481. if (!f)
  482. {
  483. perror(filename);
  484. return -1;
  485. }
  486. fread(&header.signature, 4, 1, f);
  487. /* UT package signature 0x9E2a83c1 */
  488. if (header.signature != 0x9E2a83c1)
  489. {
  490. printf("Not a UT package ( 0x9E2a83c1 )\n");
  491. return -2;
  492. }
  493. fread(&header.version, 2, 1, f);
  494. fread(&header.version2, 2, 1, f);
  495. fread(&header.flags, 4, 1, f);
  496. fread(&header.nameCount, 4, 1, f);
  497. fread(&header.nameOffset, 4, 1, f);
  498. fread(&header.exportCount, 4, 1, f);
  499. fread(&header.exportOffset, 4, 1, f);
  500. fread(&header.importCount, 4, 1, f);
  501. fread(&header.importOffset, 4, 1, f);
  502. printf("header {\n");
  503. printf("signature = 0x%x\n", header.signature);
  504. printf("version = %u, version2 (mode) = %u\n",
  505. header.version, header.version2);
  506. printf("flags = 0x%x\n", header.flags);
  507. printf("nameCount = %u, nameOffset = 0x%x\n",
  508. header.nameCount, header.nameOffset);
  509. printf("exportCount = %u, exportOffset = 0x%x\n",
  510. header.exportCount, header.exportOffset);
  511. printf("importCount = %u, importOffset = 0x%x\n",
  512. header.importCount, header.importOffset);
  513. if (header.version < 68)
  514. {
  515. header.generationCount = 0;
  516. header.generations = 0x0;
  517. fread(&header.heritageCount, 4, 1, f);
  518. fread(&header.heritageOffset, 4, 1, f);
  519. printf("heritageCount = %u, heritageOffset = 0x%x\n",
  520. header.heritageCount, header.heritageOffset);
  521. }
  522. else
  523. {
  524. header.heritageCount = 0;
  525. header.heritageOffset = 0;
  526. fread(header.guid, 16, 1, f);
  527. fread(&header.generationCount, 4, 1, f);
  528. printf("guid = 0x%x%x%x%x\n",
  529. header.guid[0], header.guid[1], header.guid[2], header.guid[3]);
  530. printf("generationCount = %u\n",
  531. header.generationCount);
  532. header.generations = new utx_generation_t[header.generationCount];
  533. for (i = 0; i < header.generationCount; ++i)
  534. {
  535. fread(&header.generations[i].exportCount, 4, 1, f);
  536. fread(&header.generations[i].nameCount, 4, 1, f);
  537. printf(" generation[%u] { exportCount = %u, nameCount = %u }\n", i,
  538. header.generations[i].exportCount,
  539. header.generations[i].nameCount);
  540. }
  541. }
  542. printf("}\n");
  543. /* 2003.06.14, Mongoose - These tables are not sequentally read,
  544. you have to skip around a lot */
  545. /* Read Name table */
  546. if ((int)header.nameOffset != ftell(f))
  547. {
  548. fseek(f, header.nameOffset, SEEK_SET);
  549. }
  550. header.nameTable = new utx_name_table_t[header.nameCount];
  551. for (i = 0; i < header.nameCount; ++i)
  552. {
  553. header.nameTable[i].objName = get_utx_name(header.version, f);
  554. fread(&header.nameTable[i].objFlags, 4, 1, f);
  555. printf("nameTable[%u] { objName = '%s', objFlags = 0x%x }\n", i,
  556. header.nameTable[i].objName, header.nameTable[i].objFlags);
  557. }
  558. /* Read export table */
  559. if ((int)header.exportOffset != ftell(f))
  560. {
  561. fseek(f, header.exportOffset, SEEK_SET);
  562. }
  563. header.exportTable = new utx_export_table_t[header.exportCount];
  564. for (i = 0; i < header.exportCount; ++i)
  565. {
  566. header.exportTable[i].objClass = get_utx_index(f);
  567. header.exportTable[i].objSuper = get_utx_index(f);
  568. fread(&header.exportTable[i].package, 4, 1, f);
  569. header.exportTable[i].objName = get_utx_index(f);
  570. fread(&header.exportTable[i].objFlags, 4, 1, f);
  571. header.exportTable[i].serialSize = get_utx_index(f);
  572. header.exportTable[i].serialOffset = get_utx_index(f);
  573. printf("exportTable[%u] { class %i, super %i, package %u, name %i\n",i,
  574. header.exportTable[i].objClass, header.exportTable[i].objSuper,
  575. header.exportTable[i].package, header.exportTable[i].objName);
  576. printf(" flags %u, serialSz %i bytes, serialOff %i }\n",
  577. header.exportTable[i].objFlags,
  578. header.exportTable[i].serialSize,
  579. header.exportTable[i].serialOffset);
  580. }
  581. /* Read import table */
  582. if ((int)header.importOffset != ftell(f))
  583. {
  584. fseek(f, header.importOffset, SEEK_SET);
  585. }
  586. header.importTable = new utx_import_table_t[header.importCount];
  587. for (i = 0; i < header.importCount; ++i)
  588. {
  589. header.importTable[i].objClass = get_utx_index(f);
  590. header.importTable[i].objSuper = get_utx_index(f);
  591. fread(&header.importTable[i].package, 4, 1, f);
  592. header.importTable[i].objName = get_utx_index(f);
  593. printf("importTable[%u] { class %i, super %i, package %u, name %i\n",i,
  594. header.importTable[i].objClass, header.importTable[i].objSuper,
  595. header.importTable[i].package, header.importTable[i].objName);
  596. }
  597. /* Read Heritage table */
  598. if (header.heritageCount > 0)
  599. {
  600. if ((int)header.heritageOffset != ftell(f))
  601. {
  602. fseek(f, header.exportOffset, SEEK_SET);
  603. }
  604. header.heritageTable = new unsigned int[header.heritageCount * 4];
  605. for (i = 0; i < header.heritageCount; ++i)
  606. {
  607. fread(header.heritageTable+(i*16), 16, 1, f);
  608. printf("heritageTable[%u] = 0x%x%x%x%x\n", i,
  609. header.heritageTable[i*16], header.heritageTable[i*16+1],
  610. header.heritageTable[i*16+2], header.heritageTable[i*16+3]);
  611. }
  612. }
  613. /* Testing the export table here to find objects in the file */
  614. for (i = 0; i < header.exportCount; ++i)
  615. {
  616. unsigned int sz, off;
  617. int nameIndex;
  618. index = use_utx_index(header.exportTable[i].objClass, &type);
  619. nameIndex = ((type == UTPackage::UT_NULL) ? -1 :
  620. (type == UTPackage::UT_IMPORT) ?
  621. header.importTable[index].objName :
  622. header.exportTable[index].objName);
  623. printf("* Export Class '%s'\n",
  624. ((nameIndex < 0) ? "Null" :
  625. header.nameTable[nameIndex].objName));
  626. index = use_utx_index(header.exportTable[i].objName, &type);
  627. printf(" Name '%s'\n",
  628. ((type == UTPackage::UT_NULL) ? "Null" :
  629. header.nameTable[index].objName));
  630. sz = use_utx_index(header.exportTable[i].serialSize, &type);
  631. printf(" Size %i bytes\n", sz);
  632. off = use_utx_index(header.exportTable[i].serialOffset, &type);
  633. printf(" Offset 0x%x (%u bytes)\n", off, off);
  634. /* Skip to the object */
  635. fseek(f, off, SEEK_SET);
  636. /* HexDump to stdout */
  637. if (hexDump)
  638. {
  639. hex_dump_file(f, sz);
  640. fseek(f, off, SEEK_SET);
  641. }
  642. /* RAW dump */
  643. if (diskDump)
  644. {
  645. char buf[512];
  646. unsigned int k, j;
  647. sprintf(buf, "/tmp/utpak/%s/%s.raw",
  648. header.nameTable[nameIndex].objName,
  649. header.nameTable[index].objName);
  650. FILE *f2 = fopen(buf, "wb");
  651. mkdir("/tmp/utpak", S_IRWXU | S_IRWXG);
  652. sprintf(buf, "/tmp/utpak/%s",
  653. header.nameTable[nameIndex].objName);
  654. mkdir(buf, S_IRWXU | S_IRWXG);
  655. printf("Writing /tmp/utpak/%s/%s.raw...\n",
  656. header.nameTable[nameIndex].objName,
  657. header.nameTable[index].objName);
  658. if (f2)
  659. {
  660. for (k = 0, j = 0; k < sz; k += j)
  661. {
  662. if (sz - k >= 512)
  663. {
  664. j = 512;
  665. }
  666. else
  667. {
  668. j = sz - k;
  669. }
  670. fread(buf, j, 1, f);
  671. fwrite(buf, j, 1, f2);
  672. }
  673. fclose(f2);
  674. }
  675. fseek(f, off, SEEK_SET);
  676. }
  677. /* Exported dump to usable external formats */
  678. if (diskDump && nameIndex > 0 &&
  679. strcmp("Texture", header.nameTable[nameIndex].objName) == 0)
  680. {
  681. int idx;
  682. unsigned char u8;
  683. // unsigned short u16;
  684. unsigned int u32, i, count, off2, w, h, byteperpixel = 4;
  685. unsigned char *data;
  686. UTPackageProperty prop;
  687. printf("Dumping texture...\n");
  688. /* Property list */
  689. while ((idx = prop.load(&header, f)) == 0)
  690. {
  691. if (strcmp("Format", header.nameTable[prop.nameIndex].objName) == 0)
  692. {
  693. u8 = prop.data[0];
  694. switch (u8)
  695. {
  696. case 0x00: /* Indexed 8bit, uncompressed mipmaps */
  697. printf("Indexed 8bit, uncompressed mipmaps\n");
  698. byteperpixel = 1;
  699. break;
  700. case 0x04: /* BGRA 32bit, uncompressed mipmaps */
  701. printf("BGR 24bit, uncompressed mipmaps\n");
  702. byteperpixel = 3;
  703. break;
  704. case 0x05: /* BGRA 32bit, uncompressed mipmaps */
  705. printf("BGRA 32bit, uncompressed mipmaps\n");
  706. byteperpixel = 4;
  707. break;
  708. default:
  709. printf("Unknown mipmap type\n");
  710. byteperpixel = 0;
  711. }
  712. }
  713. //prop.clear();
  714. }
  715. if (idx == -2)
  716. {
  717. printf("FATAL ERROR: Invalid property returned for class!\n");
  718. continue;
  719. }
  720. /* Texture class */
  721. #ifdef OBSOLETE
  722. if (header.version < 63)
  723. {
  724. fread(&u8, 1, 1, f);
  725. count = u8;
  726. }
  727. else if (header.version < 100)
  728. {
  729. fread(&u8, 1, 1, f);
  730. count = u8;
  731. fread(&u32, 4, 1, f);
  732. idx = get_utx_index(f);
  733. }
  734. else if (header.version < 120)
  735. {
  736. fread(&u8, 1, 1, f);
  737. count = u8;
  738. fread(&u32, 4, 1, f);
  739. fread(&u32, 4, 1, f);
  740. idx = get_utx_index(f);
  741. }
  742. else // ut2k3
  743. {
  744. fread(&u8, 1, 1, f);
  745. count = u8;
  746. fread(&u32, 4, 1, f);
  747. idx = get_utx_index(f);
  748. }
  749. #else
  750. fread(&u8, 1, 1, f);
  751. count = u8;
  752. #endif
  753. printf("Number of MipMaps: %i\n", count);
  754. for (i = 0; i < count; ++i)
  755. {
  756. printf("MipMap[%i]\n", i);
  757. if (header.version >= 63)
  758. {
  759. fread(&off2, 4, 1, f);
  760. printf("\tMipmap header offset = %i\n", off2);
  761. }
  762. u32 = get_utx_index(f);
  763. u32 = use_utx_index(u32, &type) + 1;
  764. printf("\tMipMap pixels = %u\n", u32);
  765. if (u32 > sz)
  766. {
  767. printf("\t\t*** ERROR: Size over threshold! ***\n");
  768. break;
  769. }
  770. // Dump 'u32' bytes texture data here
  771. //hex_dump_file(f, u32);
  772. //dump_file(f, u32*4, "/tmp/utpak-%s-%i.texture",
  773. // header.nameTable[index].objName, i);
  774. if (byteperpixel > 0)
  775. {
  776. data = new unsigned char[u32*byteperpixel];
  777. fread(data, 1, u32*byteperpixel, f);
  778. }
  779. if (header.version >= 63)
  780. {
  781. fseek(f, off2, SEEK_SET);
  782. }
  783. fread(&w, 4, 1, f);
  784. printf("\twidth = %u\n", w);
  785. fread(&h, 4, 1, f);
  786. printf("\theight = %u\n", h);
  787. fread(&u8, 1, 1, f);
  788. printf("\tbitswidth = %u \n", u8);
  789. fread(&u8, 1, 1, f);
  790. printf("\tbitsheight = %u\n", u8);
  791. if (byteperpixel > 0)
  792. {
  793. printf("\tWriting /tmp/utpak/Texture/%s-%i.tga...\n",
  794. header.nameTable[index].objName,
  795. i);
  796. mtk_image__tga_save_filename(data, w, h, byteperpixel,
  797. "/tmp/utpak/Texture/%s-%i.tga",
  798. header.nameTable[index].objName,
  799. i);
  800. delete [] data;
  801. }
  802. printf("\n");
  803. printf("\n");
  804. }
  805. }
  806. else if (diskDump && nameIndex > 0 &&
  807. strcmp("SkeletalMesh", header.nameTable[nameIndex].objName) == 0)
  808. {
  809. unsigned short u16;
  810. unsigned int numWedges, i; // u32
  811. int idx;
  812. float r;
  813. UTPackageProperty prop;
  814. printf("Dumping skeletal mesh...\n");
  815. /* Property list */
  816. while ((idx = prop.load(&header, f)) == 0)
  817. {
  818. }
  819. if (idx == -2)
  820. {
  821. printf("FATAL ERROR: Invalid property returned for class!\n");
  822. continue;
  823. }
  824. /* Skeletal mesh */
  825. idx = get_utx_index(f);
  826. numWedges = use_utx_index(idx, &type) + 1;
  827. printf("numWedges = %i\n", numWedges);
  828. for (i = 0; i < numWedges; ++i)
  829. {
  830. printf("extWedges[%i] {\n", i);
  831. fread(&u16, 2, 1, f);
  832. printf("\tiVertex = %i\n", u16);
  833. fread(&u16, 2, 1, f);
  834. printf("\tflags = 0x%04x\n", u16);
  835. fread(&r, 4, 1, f);
  836. printf("\tu = %f\n", r);
  837. fread(&r, 4, 1, f);
  838. printf("\tv = %f\n", r);
  839. printf("}\n\n");
  840. }
  841. }
  842. }
  843. fclose(f);
  844. return 0;
  845. }
  846. ////////////////////////////////////////////////////////////
  847. // Constructors
  848. ////////////////////////////////////////////////////////////
  849. UTPackage::UTPackage()
  850. {
  851. }
  852. UTPackage::~UTPackage()
  853. {
  854. }
  855. ////////////////////////////////////////////////////////////
  856. // Public Accessors
  857. ////////////////////////////////////////////////////////////
  858. ////////////////////////////////////////////////////////////
  859. // Public Mutators
  860. ////////////////////////////////////////////////////////////
  861. ////////////////////////////////////////////////////////////
  862. // Private Accessors
  863. ////////////////////////////////////////////////////////////
  864. ////////////////////////////////////////////////////////////
  865. // Private Mutators
  866. ////////////////////////////////////////////////////////////
  867. ////////////////////////////////////////////////////////////
  868. // Unit Test code
  869. ////////////////////////////////////////////////////////////
  870. #ifdef UNIT_TEST_UTPACKAGE
  871. int runUTPackageUnitTest(int argc, char *argv[])
  872. {
  873. UTPackage test;
  874. if (argc > 2)
  875. {
  876. for (int i = 0; argv[1][i] != 0; ++i)
  877. {
  878. switch (argv[1][i])
  879. {
  880. case 'd': /* Dump to file */
  881. load_utx(argv[2], false, true);
  882. break;
  883. case 'h': /* Hexdump to console */
  884. load_utx(argv[2], true, false);
  885. break;
  886. case '0':
  887. load_utx(argv[2], false, false);
  888. break;
  889. }
  890. }
  891. }
  892. else
  893. {
  894. printf("UTPackage.test [h | d | 0] <UT_Packge_Filename>\n");
  895. printf("h - Hexdump to console\n");
  896. printf("d - Dump all objects to file possible\n");
  897. printf("0 - Just attempt to parse\n");
  898. }
  899. return 0;
  900. }
  901. int main(int argc, char *argv[])
  902. {
  903. printf("[UTPackage class test]\n");
  904. runUTPackageUnitTest(argc, argv);
  905. return 0;
  906. }
  907. #endif
  908. #ifdef OBSOLETE
  909. int get_utx_property(utx_header_t *header, FILE *f,
  910. unsigned int *rsize, unsigned int *rtype,
  911. unsigned char **data)
  912. {
  913. unsigned char info, isArray;
  914. unsigned short us;
  915. unsigned int u, size, type, flags;
  916. int index, nameIndex;
  917. /* Property */
  918. index = get_utx_index(f);
  919. nameIndex = ((type == UTPackage::UT_NULL) ? -1 :
  920. (type == UTPackage::UT_IMPORT) ?
  921. header->importTable[index].objName :
  922. header->exportTable[index].objName);
  923. if (index < 0) index = nameIndex;
  924. printf("\n{ index = %i, '%s'\n", index,
  925. ((index >= 0) ? header->nameTable[index].objName :
  926. "Bad Index"));
  927. if (index < 0 || strcmp("None", header->nameTable[index].objName) == 0)
  928. {
  929. return -1;
  930. }
  931. /* Read info byte */
  932. fread(&info, 1, 1, f);
  933. isArray = (info & PROPERTY_ARRAY_MASK) != 0;
  934. type = (info & PROPERTY_TYPE_MASK);
  935. switch (info & PROPERTY_SIZE_MASK)
  936. {
  937. case 0x00:
  938. size = 1;
  939. break;
  940. case 0x10:
  941. size = 2;
  942. break;
  943. case 0x20:
  944. size = 4;
  945. break;
  946. case 0x30:
  947. size = 12;
  948. break;
  949. case 0x40:
  950. size = 16;
  951. break;
  952. case 0x50:
  953. fread(&info, 1, 1, f);
  954. size = info;
  955. break;
  956. case 0x60:
  957. fread(&us, 2, 1, f);
  958. size = us;
  959. break;
  960. case 0x70:
  961. fread(&size, 4, 1, f);
  962. break;
  963. }
  964. printf(" size %u, type 0x%x, flags 0x%x\n",
  965. size, type, flags);
  966. *rsize = size;
  967. *rtype = type;
  968. switch (type)
  969. {
  970. case UNP_ByteProperty:
  971. index = 1;
  972. if (isArray)
  973. {
  974. index = get_utx_index(f);
  975. }
  976. //*data = new unsigned char[1*index];
  977. //fread(*data, 1, index, f);
  978. fread(&info, 1, 1, f);
  979. printf(" byte 0x%02x", info);
  980. break;
  981. case UNP_IntProperty:
  982. if (isArray)
  983. {
  984. index = get_utx_index(f);
  985. }
  986. fread(&u, 4, 1, f);
  987. printf(" int %i", *((int *)&u));
  988. break;
  989. case UNP_BoolProperty:
  990. printf(" bool 0x%x\n", isArray);
  991. break;
  992. case UNP_FloatProperty:
  993. if (isArray)
  994. {
  995. index = get_utx_index(f);
  996. }
  997. fread(&u, 4, 1, f);
  998. printf(" float %f", *((float *)&u));
  999. break;
  1000. case UNP_ObjectProperty:
  1001. case UNP_NameProperty: // SetObjectProperty( aUf );
  1002. if (isArray)
  1003. {
  1004. index = get_utx_index(f);
  1005. }
  1006. if (isArray)
  1007. {
  1008. index = get_utx_index(f);
  1009. }
  1010. hex_dump_buffer((unsigned char *)&index, 4);
  1011. break;
  1012. case UNP_StrProperty: // SetStringProperty( aUf );
  1013. hex_dump_file(f, size);
  1014. break;
  1015. case UNP_StringProperty: //SetAsciizProperty( aUf );
  1016. hex_dump_file(f, size);
  1017. break;
  1018. case UNP_StructProperty: //SetStructProperty( aUf, aUn );
  1019. hex_dump_file(f, size);
  1020. break;
  1021. case UNP_ArrayProperty: //SetArrayProperty( aUf, aUn, aUi, aUe );
  1022. hex_dump_file(f, size);
  1023. break;
  1024. case UNP_ClassProperty:
  1025. case UNP_VectorProperty:
  1026. case UNP_RotatorProperty:
  1027. case UNP_MapProperty:
  1028. case UNP_FixedArrayProperty: // SetUnknownProperty( aUn, aUf )
  1029. hex_dump_file(f, size);
  1030. break;
  1031. }
  1032. printf(" }\n");
  1033. return 0;
  1034. }
  1035. #endif