PageRenderTime 45ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/devtools/create_kyradat/types.cpp

http://github.com/scummvm/scummvm
C++ | 666 lines | 461 code | 123 blank | 82 comment | 43 complexity | e6873d30c85186ab02ea9da5ca6c9a40 MD5 | raw file
Possible License(s): GPL-3.0, LGPL-2.1, GPL-2.0
  1. /* ScummVM - Graphic Adventure Engine
  2. *
  3. * ScummVM is the legal property of its developers, whose names
  4. * are too numerous to list here. Please refer to the COPYRIGHT
  5. * file distributed with this source distribution.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  20. *
  21. */
  22. // Disable symbol overrides so that we can use system headers.
  23. #define FORBIDDEN_SYMBOL_ALLOW_ALL
  24. #include "types.h"
  25. #include "pak.h"
  26. #include "common/endian.h"
  27. static void writeStringList(PAKFile &out, const char *filename, const StringListProvider *provider);
  28. static void writeRawData(PAKFile &out, const char *filename, const ByteProvider *provider);
  29. static void writeRoomList(PAKFile &out, const char *filename, const RoomProvider *provider);
  30. static void writeShapeList(PAKFile &out, const char *filename, const ShapeProvider *provider);
  31. static void writeAmigaSfxTable(PAKFile &out, const char *filename, const AmigaSfxTableProvider *provider);
  32. static void writeK2SeqData(PAKFile &out, const char *filename, const HoFSequenceProvider *provider);
  33. static void writeK2SeqItemAnimData(PAKFile &out, const char *filename, const HoFSeqItemAnimDataProvider *provider);
  34. static void writeK2ItemAnimDefinition(PAKFile &out, const char *filename, const ItemAnimDefinitionProvider *provider);
  35. static void writeLoLCharData(PAKFile &out, const char *filename, const LoLCharacterProvider *provider);
  36. static void writeLoLSpellData(PAKFile &out, const char *filename, const SpellPropertyProvider *provider);
  37. static void writeLoLCompassData(PAKFile &out, const char *filename, const CompassDefProvider *provider);
  38. static void writeLoLFlightShpData(PAKFile &out, const char *filename, const FlyingObjectShapeProvider *provider);
  39. static void writeLoLButtonData(PAKFile &out, const char *filename, const LoLButtonDefProvider *provider);
  40. static void writeRawDataBe16(PAKFile &out, const char *filename, const Uint16Provider *provider);
  41. static void writeRawDataBe32(PAKFile &out, const char *filename, const Uint32Provider *provider);
  42. static void writeEoB2SequenceData(PAKFile &out, const char *filename, const DarkMoonAnimCommandProvider *provider);
  43. static void writeEoB2ShapeData(PAKFile &out, const char *filename, const DarkMoonShapeDefProvider *provider);
  44. static void writeEoBNpcData(PAKFile &out, const char *filename, const EoBCharacterProvider *provider);
  45. void writeResource(PAKFile &out, const char *filename, ResTypes type, const void *provider) {
  46. switch (type) {
  47. case kStringList:
  48. writeStringList(out, filename, (const StringListProvider *)provider);
  49. break;
  50. case kRawData:
  51. writeRawData(out, filename, (const ByteProvider *)provider);
  52. break;
  53. case kRoomList:
  54. writeRoomList(out, filename, (const RoomProvider *)provider);
  55. break;
  56. case kShapeList:
  57. writeShapeList(out, filename, (const ShapeProvider *)provider);
  58. break;
  59. case kAmigaSfxTable:
  60. writeAmigaSfxTable(out, filename, (const AmigaSfxTableProvider *)provider);
  61. break;
  62. case k2SeqData:
  63. writeK2SeqData(out, filename, (const HoFSequenceProvider *)provider);
  64. break;
  65. case k2SeqItemAnimData:
  66. writeK2SeqItemAnimData(out, filename, (const HoFSeqItemAnimDataProvider *)provider);
  67. break;
  68. case k2ItemAnimDefinition:
  69. writeK2ItemAnimDefinition(out, filename, (const ItemAnimDefinitionProvider *)provider);
  70. break;
  71. case kLoLCharData:
  72. writeLoLCharData(out, filename, (const LoLCharacterProvider *)provider);
  73. break;
  74. case kLoLSpellData:
  75. writeLoLSpellData(out, filename, (const SpellPropertyProvider *)provider);
  76. break;
  77. case kLoLCompassData:
  78. writeLoLCompassData(out, filename, (const CompassDefProvider *)provider);
  79. break;
  80. case kLoLFlightShpData:
  81. writeLoLFlightShpData(out, filename, (const FlyingObjectShapeProvider *)provider);
  82. break;
  83. case kLoLButtonData:
  84. writeLoLButtonData(out, filename, (const LoLButtonDefProvider *)provider);
  85. break;
  86. case kRawDataBe16:
  87. writeRawDataBe16(out, filename, (const Uint16Provider *)provider);
  88. break;
  89. case kRawDataBe32:
  90. writeRawDataBe32(out, filename, (const Uint32Provider *)provider);
  91. break;
  92. case kEoB2SequenceData:
  93. writeEoB2SequenceData(out, filename, (const DarkMoonAnimCommandProvider *)provider);
  94. break;
  95. case kEoB2ShapeData:
  96. writeEoB2ShapeData(out, filename, (const DarkMoonShapeDefProvider *)provider);
  97. break;
  98. case kEoBNpcData:
  99. writeEoBNpcData(out, filename, (const EoBCharacterProvider *)provider);
  100. break;
  101. default:
  102. break;
  103. }
  104. }
  105. static void writeStringList(PAKFile &out, const char *filename, const StringListProvider *provider) {
  106. // Step 1: Calculate size
  107. size_t size = 4;
  108. for (uint i = 0; i < provider->numEntries; ++i) {
  109. size += strlen(provider->data[i]) + 1;
  110. }
  111. // Step 2: Write data
  112. byte *const output = new byte[size];
  113. byte *dst = output;
  114. WRITE_BE_UINT32(dst, provider->numEntries); dst += 4;
  115. for (uint i = 0; i < provider->numEntries; ++i) {
  116. size_t num = strlen(provider->data[i]) + 1;
  117. memcpy(dst, provider->data[i], num); dst += num;
  118. }
  119. // Step 3: Add data to output
  120. out.addFile(filename, output, size);
  121. }
  122. static void writeRawData(PAKFile &out, const char *filename, const ByteProvider *provider) {
  123. // Step 1: Calculate size
  124. size_t size = provider->numEntries;
  125. // Step 2: Write data
  126. byte *const output = new byte[size];
  127. memcpy(output, provider->data, size);
  128. // Step 3: Add data to output
  129. out.addFile(filename, output, size);
  130. }
  131. static void writeRoomList(PAKFile &out, const char *filename, const RoomProvider *provider) {
  132. // Step 1: Calculate size
  133. size_t size = 4 + 9 * provider->numEntries;
  134. // Step 2: Write data
  135. byte *const output = new byte[size];
  136. byte *dst = output;
  137. WRITE_BE_UINT32(dst, provider->numEntries); dst += 4;
  138. for (uint i = 0; i < provider->numEntries; ++i) {
  139. const Room &room = provider->data[i];
  140. *dst = room.index; dst += 1;
  141. WRITE_BE_UINT16(dst, room.north); dst += 2;
  142. WRITE_BE_UINT16(dst, room.east); dst += 2;
  143. WRITE_BE_UINT16(dst, room.south); dst += 2;
  144. WRITE_BE_UINT16(dst, room.west); dst += 2;
  145. }
  146. // Step 3: Add data to output
  147. out.addFile(filename, output, size);
  148. }
  149. static void writeShapeList(PAKFile &out, const char *filename, const ShapeProvider *provider) {
  150. // Step 1: Calculate size
  151. size_t size = 4 + 7 * provider->numEntries;
  152. // Step 2: Write data
  153. byte *const output = new byte[size];
  154. byte *dst = output;
  155. WRITE_BE_UINT32(dst, provider->numEntries); dst += 4;
  156. for (uint i = 0; i < provider->numEntries; ++i) {
  157. const Shape &shape = provider->data[i];
  158. *dst = shape.imageIndex; dst += 1;
  159. *dst = shape.x; dst += 1;
  160. *dst = shape.y; dst += 1;
  161. *dst = shape.w; dst += 1;
  162. *dst = shape.h; dst += 1;
  163. *dst = shape.xOffset; dst += 1;
  164. *dst = shape.yOffset; dst += 1;
  165. }
  166. // Step 3: Add data to output
  167. out.addFile(filename, output, size);
  168. }
  169. static void writeAmigaSfxTable(PAKFile &out, const char *filename, const AmigaSfxTableProvider *provider) {
  170. // Step 1: Calculate size
  171. size_t size = 4 + 6 * provider->numEntries;
  172. // Step 2: Write data
  173. byte *const output = new byte[size];
  174. byte *dst = output;
  175. WRITE_BE_UINT32(dst, provider->numEntries); dst += 4;
  176. for (uint i = 0; i < provider->numEntries; ++i) {
  177. const AmigaSfxTable &entry = provider->data[i];
  178. *dst = entry.note; dst += 1;
  179. *dst = entry.patch; dst += 1;
  180. WRITE_BE_UINT16(dst, entry.duration); dst += 2;
  181. *dst = entry.volume; dst += 1;
  182. *dst = entry.pan; dst += 1;
  183. }
  184. // Step 3: Add data to output
  185. out.addFile(filename, output, size);
  186. }
  187. static void writeK2SeqData(PAKFile &out, const char *filename, const HoFSequenceProvider *provider) {
  188. // Step 1: Calculate size
  189. size_t size = 4 + (2 + 48) * provider->numSequences + (2 + 32) * provider->numNestedSequences;
  190. const size_t startSequenceOffset = 4 + 2 * provider->numSequences + 2 * provider->numNestedSequences;
  191. const size_t startNestedSequences = startSequenceOffset + 48 * provider->numSequences;
  192. const size_t startControlOffset = size;
  193. for (uint i = 0; i < provider->numNestedSequences; ++i) {
  194. if (provider->nestedSequences[i].numControls) {
  195. size += 1 + 4 * provider->nestedSequences[i].numControls;
  196. }
  197. }
  198. // Step 2: Write data
  199. byte *const output = new byte[size];
  200. byte *offsetTable = output;
  201. byte *sequenceDst = output + startSequenceOffset;
  202. byte *nestedDst = output + startNestedSequences;
  203. byte *controlDst = output + startControlOffset;
  204. // First write all sequences
  205. WRITE_BE_UINT16(offsetTable, provider->numSequences); offsetTable += 2;
  206. for (uint i = 0; i < provider->numSequences; ++i) {
  207. const HoFSequence &entry = provider->sequences[i];
  208. // Write location to the offset table
  209. WRITE_BE_UINT16(offsetTable, sequenceDst - output); offsetTable += 2;
  210. // Write actual sequence data
  211. WRITE_BE_UINT16(sequenceDst, entry.flags); sequenceDst += 2;
  212. memcpy(sequenceDst, entry.wsaFile, 14); sequenceDst += 14;
  213. memcpy(sequenceDst, entry.cpsFile, 14); sequenceDst += 14;
  214. *sequenceDst = entry.fadeInTransitionType; sequenceDst += 1;
  215. *sequenceDst = entry.fadeOutTransitionType; sequenceDst += 1;
  216. WRITE_BE_UINT16(sequenceDst, entry.stringIndex1); sequenceDst += 2;
  217. WRITE_BE_UINT16(sequenceDst, entry.stringIndex2); sequenceDst += 2;
  218. WRITE_BE_UINT16(sequenceDst, entry.startFrame); sequenceDst += 2;
  219. WRITE_BE_UINT16(sequenceDst, entry.numFrames); sequenceDst += 2;
  220. WRITE_BE_UINT16(sequenceDst, entry.duration); sequenceDst += 2;
  221. WRITE_BE_UINT16(sequenceDst, entry.xPos); sequenceDst += 2;
  222. WRITE_BE_UINT16(sequenceDst, entry.yPos); sequenceDst += 2;
  223. WRITE_BE_UINT16(sequenceDst, entry.timeout); sequenceDst += 2;
  224. }
  225. assert(sequenceDst == nestedDst);
  226. // Then write all nested sequences
  227. WRITE_BE_UINT16(offsetTable, provider->numNestedSequences); offsetTable += 2;
  228. for (uint i = 0; i < provider->numNestedSequences; ++i) {
  229. const HoFNestedSequence &entry = provider->nestedSequences[i];
  230. // Write location to the offset table
  231. WRITE_BE_UINT16(offsetTable, nestedDst - output); offsetTable += 2;
  232. // Write the nested sequence data
  233. WRITE_BE_UINT16(nestedDst, entry.flags); nestedDst += 2;
  234. memcpy(nestedDst, entry.wsaFile, 14); nestedDst += 14;
  235. WRITE_BE_UINT16(nestedDst, entry.startFrame); nestedDst += 2;
  236. WRITE_BE_UINT16(nestedDst, entry.endFrame); nestedDst += 2;
  237. WRITE_BE_UINT16(nestedDst, entry.frameDelay); nestedDst += 2;
  238. WRITE_BE_UINT16(nestedDst, entry.x); nestedDst += 2;
  239. WRITE_BE_UINT16(nestedDst, entry.y); nestedDst += 2;
  240. if (entry.numControls) {
  241. WRITE_BE_UINT16(nestedDst, controlDst - output); nestedDst += 2;
  242. *controlDst = entry.numControls; controlDst += 1;
  243. for (uint j = 0; j < entry.numControls; ++j) {
  244. WRITE_BE_UINT16(controlDst, entry.wsaControl[j].index); controlDst += 2;
  245. WRITE_BE_UINT16(controlDst, entry.wsaControl[j].delay); controlDst += 2;
  246. }
  247. } else {
  248. WRITE_BE_UINT16(nestedDst, 0); nestedDst += 2;
  249. }
  250. WRITE_BE_UINT16(nestedDst, entry.fadeInTransitionType); nestedDst += 2;
  251. WRITE_BE_UINT16(nestedDst, entry.fadeOutTransitionType); nestedDst += 2;
  252. }
  253. assert(offsetTable == output + startSequenceOffset);
  254. assert(nestedDst == output + startControlOffset);
  255. assert(controlDst == output + size);
  256. // Step 3: Add data to output
  257. out.addFile(filename, output, size);
  258. }
  259. static void writeK2SeqItemAnimData(PAKFile &out, const char *filename, const HoFSeqItemAnimDataProvider *provider) {
  260. // Step 1: Calculate size
  261. size_t size = 1 + 44 * provider->numEntries;
  262. // Step 2: Write data
  263. byte *const output = new byte[size];
  264. byte *dst = output;
  265. *dst = provider->numEntries; dst += 1;
  266. for (uint i = 0; i < provider->numEntries; ++i) {
  267. const HoFSeqItemAnimData &entry = provider->data[i];
  268. WRITE_BE_UINT16(dst, entry.itemIndex); dst += 2;
  269. WRITE_BE_UINT16(dst, entry.y); dst += 2;
  270. for (uint j = 0; j < 20; ++j) {
  271. WRITE_BE_UINT16(dst, entry.frames[j]); dst += 2;
  272. }
  273. }
  274. // Step 3: Add data to output
  275. out.addFile(filename, output, size);
  276. }
  277. static void writeK2ItemAnimDefinition(PAKFile &out, const char *filename, const ItemAnimDefinitionProvider *provider) {
  278. // Step 1: Calculate size
  279. size_t size = 1 + 3 * provider->numEntries;
  280. for (uint i = 0; i < provider->numEntries; ++i) {
  281. size += provider->data[i].numFrames * 4;
  282. }
  283. // Step 2: Write data
  284. byte *const output = new byte[size];
  285. byte *dst = output;
  286. *dst = provider->numEntries; dst += 1;
  287. for (uint i = 0; i < provider->numEntries; ++i) {
  288. const ItemAnimDefinition &entry = provider->data[i];
  289. WRITE_BE_UINT16(dst, entry.itemIndex); dst += 2;
  290. *dst = entry.numFrames; dst += 1;
  291. for (uint j = 0; j < entry.numFrames; ++j) {
  292. WRITE_BE_UINT16(dst, entry.frames[j].index); dst += 2;
  293. WRITE_BE_UINT16(dst, entry.frames[j].delay); dst += 2;
  294. }
  295. }
  296. // Step 3: Add data to output
  297. out.addFile(filename, output, size);
  298. }
  299. static void writeLoLCharData(PAKFile &out, const char *filename, const LoLCharacterProvider *provider) {
  300. // Step 1: Calculate size
  301. size_t size = 130 * provider->numEntries;
  302. // Step 2: Write data
  303. byte *const output = new byte[size];
  304. byte *dst = output;
  305. for (uint i = 0; i < provider->numEntries; ++i) {
  306. const LoLCharacter &entry = provider->data[i];
  307. WRITE_LE_UINT16(dst, entry.flags); dst += 2;
  308. memcpy(dst, entry.name, 11); dst += 11;
  309. *dst = entry.raceClassSex; dst += 1;
  310. WRITE_LE_UINT16(dst, entry.id); dst += 2;
  311. *dst = entry.curFaceFrame; dst += 1;
  312. *dst = entry.tempFaceFrame; dst += 1;
  313. *dst = entry.screamSfx; dst += 1;
  314. WRITE_BE_UINT32(dst, 0xDEADBEEF); dst += 4;
  315. for (uint j = 0; j < 8; ++j) {
  316. WRITE_LE_UINT16(dst, entry.itemsMight[j]); dst += 2;
  317. }
  318. for (uint j = 0; j < 8; ++j) {
  319. WRITE_LE_UINT16(dst, entry.protectionAgainstItems[j]); dst += 2;
  320. }
  321. WRITE_LE_UINT16(dst, entry.itemProtection); dst += 2;
  322. WRITE_LE_UINT16(dst, entry.hitPointsCur); dst += 2;
  323. WRITE_LE_UINT16(dst, entry.hitPointsMax); dst += 2;
  324. WRITE_LE_UINT16(dst, entry.magicPointsCur); dst += 2;
  325. WRITE_LE_UINT16(dst, entry.magicPointsMax); dst += 2;
  326. *dst = entry.field_41; dst += 1;
  327. WRITE_LE_UINT16(dst, entry.damageSuffered); dst += 2;
  328. WRITE_LE_UINT16(dst, entry.weaponHit); dst += 2;
  329. WRITE_LE_UINT16(dst, entry.totalMightModifier); dst += 2;
  330. WRITE_LE_UINT16(dst, entry.totalProtectionModifier); dst += 2;
  331. WRITE_LE_UINT16(dst, entry.might); dst += 2;
  332. WRITE_LE_UINT16(dst, entry.protection); dst += 2;
  333. WRITE_LE_UINT16(dst, entry.nextAnimUpdateCountdown); dst += 2;
  334. for (uint j = 0; j < 11; ++j) {
  335. WRITE_LE_UINT16(dst, entry.items[j]); dst += 2;
  336. }
  337. for (uint j = 0; j < 3; ++j) {
  338. *dst = entry.skillLevels[j]; dst += 1;
  339. }
  340. for (uint j = 0; j < 3; ++j) {
  341. *dst = entry.skillModifiers[j]; dst += 1;
  342. }
  343. for (uint j = 0; j < 3; ++j) {
  344. WRITE_LE_UINT32(dst, entry.experiencePts[j]); dst += 4;
  345. }
  346. for (uint j = 0; j < 5; ++j) {
  347. *dst = entry.characterUpdateEvents[j]; dst += 1;
  348. }
  349. for (uint j = 0; j < 5; ++j) {
  350. *dst = entry.characterUpdateDelay[j]; dst += 1;
  351. }
  352. }
  353. // Step 3: Add data to output
  354. out.addFile(filename, output, size);
  355. }
  356. static void writeLoLSpellData(PAKFile &out, const char *filename, const SpellPropertyProvider *provider) {
  357. // Step 1: Calculate size
  358. size_t size = 28 * provider->numEntries;
  359. // Step 2: Write data
  360. byte *const output = new byte[size];
  361. byte *dst = output;
  362. for (uint i = 0; i < provider->numEntries; ++i) {
  363. const SpellProperty &entry = provider->data[i];
  364. WRITE_LE_UINT16(dst, entry.spellNameCode); dst += 2;
  365. for (uint j = 0; j < 4; ++j) {
  366. WRITE_LE_UINT16(dst, entry.mpRequired[j]); dst += 2;
  367. }
  368. WRITE_LE_UINT16(dst, entry.field_a); dst += 2;
  369. WRITE_LE_UINT16(dst, entry.field_c); dst += 2;
  370. for (uint j = 0; j < 4; ++j) {
  371. WRITE_LE_UINT16(dst, entry.hpRequired[j]); dst += 2;
  372. }
  373. WRITE_LE_UINT16(dst, entry.field_16); dst += 2;
  374. WRITE_LE_UINT16(dst, entry.field_18); dst += 2;
  375. WRITE_LE_UINT16(dst, entry.flags); dst += 2;
  376. }
  377. // Step 3: Add data to output
  378. out.addFile(filename, output, size);
  379. }
  380. static void writeLoLCompassData(PAKFile &out, const char *filename, const CompassDefProvider *provider) {
  381. // Step 1: Calculate size
  382. size_t size = 4 * provider->numEntries;
  383. // Step 2: Write data
  384. byte *const output = new byte[size];
  385. byte *dst = output;
  386. for (uint i = 0; i < provider->numEntries; ++i) {
  387. const CompassDef &entry = provider->data[i];
  388. *dst = entry.shapeIndex; dst += 1;
  389. *dst = entry.x; dst += 1;
  390. *dst = entry.y; dst += 1;
  391. *dst = entry.flags; dst += 1;
  392. }
  393. // Step 3: Add data to output
  394. out.addFile(filename, output, size);
  395. }
  396. static void writeLoLFlightShpData(PAKFile &out, const char *filename, const FlyingObjectShapeProvider *provider) {
  397. // Step 1: Calculate size
  398. size_t size = 5 * provider->numEntries;
  399. // Step 2: Write data
  400. byte *const output = new byte[size];
  401. byte *dst = output;
  402. for (uint i = 0; i < provider->numEntries; ++i) {
  403. const FlyingObjectShape &entry = provider->data[i];
  404. *dst = entry.shapeFront; dst += 1;
  405. *dst = entry.shapeBack; dst += 1;
  406. *dst = entry.shapeLeft; dst += 1;
  407. *dst = entry.drawFlags; dst += 1;
  408. *dst = entry.flipFlags; dst += 1;
  409. }
  410. // Step 3: Add data to output
  411. out.addFile(filename, output, size);
  412. }
  413. static void writeLoLButtonData(PAKFile &out, const char *filename, const LoLButtonDefProvider *provider) {
  414. // Step 1: Calculate size
  415. size_t size = 18 * provider->numEntries;
  416. // Step 2: Write data
  417. byte *const output = new byte[size];
  418. byte *dst = output;
  419. for (uint i = 0; i < provider->numEntries; ++i) {
  420. const LoLButtonDef &entry = provider->data[i];
  421. WRITE_BE_UINT16(dst, entry.buttonFlags); dst += 2;
  422. WRITE_BE_UINT16(dst, entry.keyCode); dst += 2;
  423. WRITE_BE_UINT16(dst, entry.keyCode2); dst += 2;
  424. WRITE_BE_UINT16(dst, entry.x); dst += 2;
  425. WRITE_BE_UINT16(dst, entry.y); dst += 2;
  426. WRITE_BE_UINT16(dst, entry.w); dst += 2;
  427. WRITE_BE_UINT16(dst, entry.h); dst += 2;
  428. WRITE_BE_UINT16(dst, entry.index); dst += 2;
  429. WRITE_BE_UINT16(dst, entry.screenDim); dst += 2;
  430. }
  431. // Step 3: Add data to output
  432. out.addFile(filename, output, size);
  433. }
  434. static void writeRawDataBe16(PAKFile &out, const char *filename, const Uint16Provider *provider) {
  435. // Step 1: Calculate size
  436. size_t size = 2 * provider->numEntries;
  437. // Step 2: Write data
  438. byte *const output = new byte[size];
  439. byte *dst = output;
  440. for (uint i = 0; i < provider->numEntries; ++i) {
  441. WRITE_BE_UINT16(dst, provider->data[i]); dst += 2;
  442. }
  443. // Step 3: Add data to output
  444. out.addFile(filename, output, size);
  445. }
  446. static void writeRawDataBe32(PAKFile &out, const char *filename, const Uint32Provider *provider) {
  447. // Step 1: Calculate size
  448. size_t size = 4 * provider->numEntries;
  449. // Step 2: Write data
  450. byte *const output = new byte[size];
  451. byte *dst = output;
  452. for (uint i = 0; i < provider->numEntries; ++i) {
  453. WRITE_BE_UINT32(dst, provider->data[i]); dst += 4;
  454. }
  455. // Step 3: Add data to output
  456. out.addFile(filename, output, size);
  457. }
  458. static void writeEoB2SequenceData(PAKFile &out, const char *filename, const DarkMoonAnimCommandProvider *provider) {
  459. // Step 1: Calculate size
  460. size_t size = 11 * provider->numEntries;
  461. // Step 2: Write data
  462. byte *const output = new byte[size];
  463. byte *dst = output;
  464. for (uint i = 0; i < provider->numEntries; ++i) {
  465. const DarkMoonAnimCommand &entry = provider->data[i];
  466. *dst = entry.command; dst += 1;
  467. *dst = entry.obj; dst += 1;
  468. WRITE_BE_UINT16(dst, entry.x1); dst += 2;
  469. *dst = entry.y1; dst += 1;
  470. *dst = entry.delay; dst += 1;
  471. *dst = entry.pal; dst += 1;
  472. *dst = entry.x2; dst += 1;
  473. *dst = entry.y2; dst += 1;
  474. *dst = entry.w; dst += 1;
  475. *dst = entry.h; dst += 1;
  476. }
  477. // Step 3: Add data to output
  478. out.addFile(filename, output, size);
  479. }
  480. static void writeEoB2ShapeData(PAKFile &out, const char *filename, const DarkMoonShapeDefProvider *provider) {
  481. // Step 1: Calculate size
  482. size_t size = 6 * provider->numEntries;
  483. // Step 2: Write data
  484. byte *const output = new byte[size];
  485. byte *dst = output;
  486. for (uint i = 0; i < provider->numEntries; ++i) {
  487. const DarkMoonShapeDef &entry = provider->data[i];
  488. WRITE_BE_UINT16(dst, entry.index); dst += 2;
  489. *dst = entry.x; dst += 1;
  490. *dst = entry.y; dst += 1;
  491. *dst = entry.w; dst += 1;
  492. *dst = entry.h; dst += 1;
  493. }
  494. // Step 3: Add data to output
  495. out.addFile(filename, output, size);
  496. }
  497. static void writeEoBNpcData(PAKFile &out, const char *filename, const EoBCharacterProvider *provider) {
  498. // Step 1: Calculate size
  499. size_t size = 2 + 111 * provider->numEntries;
  500. // Step 2: Write data
  501. byte *const output = new byte[size];
  502. byte *dst = output;
  503. WRITE_BE_UINT16(dst, provider->numEntries); dst += 2;
  504. for (uint i = 0; i < provider->numEntries; ++i) {
  505. const EoBCharacter &entry = provider->data[i];
  506. *dst = entry.id; dst += 1;
  507. *dst = entry.flags; dst += 1;
  508. memcpy(dst, entry.name, 11); dst += 11;
  509. *dst = entry.strengthCur; dst += 1;
  510. *dst = entry.strengthMax; dst += 1;
  511. *dst = entry.strengthExtCur; dst += 1;
  512. *dst = entry.strengthExtMax; dst += 1;
  513. *dst = entry.intelligenceCur; dst += 1;
  514. *dst = entry.intelligenceMax; dst += 1;
  515. *dst = entry.wisdomCur; dst += 1;
  516. *dst = entry.wisdomMax; dst += 1;
  517. *dst = entry.dexterityCur; dst += 1;
  518. *dst = entry.dexterityMax; dst += 1;
  519. *dst = entry.constitutionCur; dst += 1;
  520. *dst = entry.constitutionMax; dst += 1;
  521. *dst = entry.charismaCur; dst += 1;
  522. *dst = entry.charismaMax; dst += 1;
  523. WRITE_BE_UINT16(dst, entry.hitPointsCur); dst += 2;
  524. WRITE_BE_UINT16(dst, entry.hitPointsMax); dst += 2;
  525. *dst = entry.armorClass; dst += 1;
  526. *dst = entry.disabledSlots; dst += 1;
  527. *dst = entry.raceSex; dst += 1;
  528. *dst = entry.cClass; dst += 1;
  529. *dst = entry.alignment; dst += 1;
  530. *dst = entry.portrait; dst += 1;
  531. *dst = entry.food; dst += 1;
  532. memcpy(dst, entry.level, 3); dst += 3;
  533. WRITE_BE_UINT32(dst, entry.experience[0]); dst += 4;
  534. WRITE_BE_UINT32(dst, entry.experience[1]); dst += 4;
  535. WRITE_BE_UINT32(dst, entry.experience[2]); dst += 4;
  536. WRITE_BE_UINT32(dst, entry.mageSpellsAvailableFlags); dst += 4;
  537. for (uint j = 0; j < 27; ++j) {
  538. WRITE_BE_UINT16(dst, entry.inventory[j]); dst += 2;
  539. }
  540. }
  541. // Step 3: Add data to output
  542. out.addFile(filename, output, size);
  543. }