100 if (
File ==
nullptr) {
105 strcpy(pSprite->
pName, pContainer.c_str());
109 uint8_t *pDecompressedBytes =
nullptr;
114 void *DstBufa = malloc(Sizea);
115 fread(DstBufa, 1, Sizea,
File);
122 pDecompressedBytes = (
uint8_t*)malloc(Sizea);
123 fread(pDecompressedBytes, 1, Sizea,
File);
129 if (pSpriteLines[i].begin >= 0) {
131 pDecompressedBytes + pSpriteLines[i].
offset,
132 pSpriteLines[i].
end - pSpriteLines[i].
begin);
136 delete[] pSpriteLines;
142 if (!
Open(pFilename)) {
259 if (isFileOpened)
return 1;
260 if (root_name.empty()) {
268 strcpy(dir.
pFilename, root_name.c_str());
274 pFile = fopen(pLODName.c_str(),
"wb+");
275 if (!pFile)
return 3;
288 pContainerName.clear();
289 uOffsetToSubIndex = 0;
291 pSubIndices =
nullptr;
300 int *
v1 = (
int *)&this->uNumLoadedSprites;
301 int *
v2 = &this->field_ECA8;
302 DeleteSpritesRange(this->field_ECA8, this->uNumLoadedSprites);
307 if (this->pHardwareSprites) {
308 if (uStartIndex < uStopIndex) {
309 for (
int i = uStartIndex; i < uStopIndex; i++) {
310 pHardwareSprites[i].Release();
317 if (!(this->word_1A & 0x400)) {
325 this->uPaletteId = 0;
326 this->uTexturePitch = 0;
329 this->uSpriteSize = 0;
342 this->sprite_header->Release();
345 this->pName =
"NULL";
346 this->uPaletteID = 0;
350 if (!Open(pLODFilename)) {
354 return LoadSubIndices(pFolderName);
358 for (
uint i = 0; i < this->uNumLoadedFiles; i++) {
359 this->pTextures[i].Release();
361 this->uTexturePacksCount = 0;
362 this->uNumPrevLoadedFiles = 0;
363 this->dword_11B84 = 0;
364 this->dword_11B80 = 0;
365 this->uNumLoadedFiles = 0;
369 for (
uint i = 0; i < this->uNumLoadedFiles; i++) {
370 if (!_stricmp(this->pTextures[i].header.pName, pName))
return i;
378 int loaded_files = this->uNumLoadedFiles;
379 for (pTex = &this->pTextures[loaded_files]; !pTex->
header.
pName[0]; --pTex)
381 if (loaded_files < (
signed int)this->uNumLoadedFiles) {
383 this->uNumLoadedFiles = loaded_files;
388 if (this->pHardwareSprites) {
389 for (
int i = 0; i < this->uNumLoadedSprites; ++i) {
390 this->pHardwareSprites[i].Release();
396 if (!(this->word_1A & 0x400)) {
453 unsigned int total_size = 0;
454 for (
int i = 0; i < uNumSubDirs; i++) {
455 total_size += pSubIndices[i].uDataSize;
460 for (
int i = 0; i < uNumSubDirs; i++) {
461 pSubIndices[i].uOfsetFromSubindicesStart = temp_offset;
462 temp_offset += pSubIndices[i].uDataSize;
465 String Filename =
"lod.tmp";
466 FILE *tmp_file = fopen(Filename.c_str(),
"wb+");
467 if (tmp_file ==
nullptr) {
482 fwrite(pSubIndices,
sizeof(
LOD::Directory), uNumSubDirs, tmp_file);
483 fseek(pOutputFileHandle, 0, 0);
484 while (total_size > 0) {
485 int write_size = uIOBufferSize;
486 if (total_size <= uIOBufferSize) {
487 write_size = total_size;
489 fread(pIOBuffer, 1, write_size, pOutputFileHandle);
490 fwrite(pIOBuffer, 1, write_size, tmp_file);
491 total_size -= write_size;
495 fclose(pOutputFileHandle);
497 remove(
"lodapp.tmp");
498 remove(pLODName.c_str());
499 rename(Filename.c_str(), pLODName.c_str());
501 LoadFile(pLODName.c_str(), 0);
507 Assert(uNumSubDirs < 299);
510 strcpy(dir.
pFilename, file_name.c_str());
513 memcpy(&pSubIndices[uNumSubDirs++], &dir,
sizeof(
LOD::Directory));
514 fwrite(pData, 1, dir.
uDataSize, pOutputFileHandle);
519 if (!isFileOpened)
return 1;
521 if (pIOBuffer && uIOBufferSize) {
523 pOutputFileHandle = fopen(
"lodapp.tmp",
"wb+");
524 return pOutputFileHandle ? 1 : 7;
532 pContainerName[0] = 0;
535 isFileOpened =
false;
546 strcpy(dir.
pFilename, file_name.c_str());
550 bool bRewrite_data =
false;
551 int insert_index = -1;
558 if (!pIOBuffer || !uIOBufferSize) {
562 for (
size_t i = 0; i < uNumSubDirs; i++) {
563 int comp_res = _stricmp(pSubIndices[i].pFilename, dir.
pFilename);
567 bRewrite_data =
true;
572 if (pSubIndices[i].priority < dir.
priority)
575 bRewrite_data =
true;
579 if (a4 == 2)
return 4;
580 }
else if (comp_res > 0) {
581 if (insert_index == -1) {
588 int size_correction = 0;
589 String Filename =
"lod.tmp";
590 FILE *tmp_file = fopen(Filename.c_str(),
"wb+");
591 if (!tmp_file)
return 5;
595 size_correction = pSubIndices[insert_index].uDataSize;
604 int total_data_size = uLODDataSize + dir.
uDataSize - size_correction;
605 if (!bRewrite_data) {
613 if (!bRewrite_data &&
614 (insert_index < uNumSubDirs)) {
616 for (
int i = uNumSubDirs; i > insert_index; --i)
617 memcpy(&pSubIndices[i], &pSubIndices[i - 1],
623 if (uNumSubDirs > 0) {
625 for (
int i = 0; i < uNumSubDirs; i++) {
626 pSubIndices[i].uOfsetFromSubindicesStart = offset_to_data;
627 offset_to_data += pSubIndices[i].uDataSize;
635 fwrite(pSubIndices,
sizeof(
LOD::Directory), uNumSubDirs, tmp_file);
640 fseek(pFile, offset_to_data, SEEK_CUR);
642 int to_copy_size = pSubIndices[insert_index].uOfsetFromSubindicesStart -
643 pSubIndices[0].uOfsetFromSubindicesStart;
644 while (to_copy_size > 0) {
645 int read_size = uIOBufferSize;
646 if (to_copy_size <= uIOBufferSize) read_size = to_copy_size;
647 fread(pIOBuffer, 1, read_size, pFile);
648 fwrite(pIOBuffer, 1, read_size, tmp_file);
649 to_copy_size -= read_size;
652 fwrite(pDirData, 1, dir.
uDataSize, tmp_file);
653 if (bRewrite_data) fseek(pFile, size_correction, SEEK_CUR);
656 int curr_position = ftell(pFile);
657 fseek(pFile, 0, SEEK_END);
658 to_copy_size = ftell(pFile) - curr_position;
659 fseek(pFile, curr_position, SEEK_SET);
660 while (to_copy_size > 0) {
661 int read_size = uIOBufferSize;
662 if (to_copy_size <= uIOBufferSize) read_size = to_copy_size;
663 fread(pIOBuffer, 1, read_size, pFile);
664 fwrite(pIOBuffer, 1, read_size, tmp_file);
665 to_copy_size -= read_size;
672 remove(pLODName.c_str());
673 rename(Filename.c_str(), pLODName.c_str());
677 LoadFile(pLODName, 0);
687 pFile = fopen(pFilename.c_str(), bWriting ?
"rb" :
"rb+");
688 if (pFile ==
nullptr) {
692 pLODName = pFilename;
698 fseek(pFile, 0, SEEK_SET);
700 pContainerName =
"chapter";
703 Assert(uNumSubDirs <= 300);
706 fseek(pFile, uOffsetToSubIndex, SEEK_SET);
713 unsigned int uBufferSize) {
717 pSubIndices =
nullptr;
727 pIOBuffer = (
uint8_t*)malloc(uBufferSize);
728 uIOBufferSize = uBufferSize;
734 pSubIndices =
nullptr;
752 if (!OpenFile(sFilename)) {
760 return LoadSubIndices(pRoot.front().pFilename);
768 pFile = fopen(sFilename.c_str(),
"rb");
769 if (pFile ==
nullptr) {
773 pLODName = sFilename;
779 if (pFile ==
nullptr) {
783 fseek(pFile, 0, SEEK_SET);
788 for (
unsigned int i = 0; i < header.uNumIndices; i++) {
794 pRoot.push_back(dir);
797 fseek(pFile, 0, SEEK_SET);
808 if (!_stricmp(pContainer.c_str(), dir.pFilename)) {
809 pContainerName = pContainer;
810 uOffsetToSubIndex = dir.uOfsetFromSubindicesStart;
811 uNumSubDirs = dir.uNumSubIndices;
812 fseek(pFile, uOffsetToSubIndex, SEEK_SET);
825 memset(pFilename, 0, 16);
826 this->uOfsetFromSubindicesStart = 0;
828 this->uNumSubIndices = 0;
829 this->dword_000018 = 0;
834 for (
size_t i = 0; i < uNumSubDirs; ++i) {
835 if (!_stricmp(pContainer.c_str(), pSubIndices[i].pFilename)) {
844 this->field_ECA8 = this->uNumLoadedSprites;
845 if (this->uNumLoadedSprites < this->field_ECA0)
846 this->field_ECA8 = this->field_ECA0;
847 if (this->field_ECA0 < this->field_ECA4) field_ECA0 = this->field_ECA4;
848 return this->uNumLoadedSprites;
855 if (data_size !=
nullptr) {
859 for (
uint i = 0; i < uNumSubDirs; ++i) {
860 if (!_stricmp(pContainer_Name.c_str(), pSubIndices[i].pFilename)) {
861 fseek(pFile, uOffsetToSubIndex + pSubIndices[i].uOfsetFromSubindicesStart, SEEK_SET);
862 if (data_size !=
nullptr) {
863 *data_size = pSubIndices[i].uDataSize;
873 unsigned int uTargetGBits,
874 unsigned int uTargetBBits) {
875 if (this->uTextureRedBits != uTargetRBits ||
876 this->uTextureGreenBits != uTargetGBits ||
877 this->uTextureBlueBits != uTargetBBits) {
878 this->uTextureRedBits = uTargetRBits;
879 this->uTextureGreenBits = uTargetGBits;
880 this->uTextureBlueBits = uTargetBBits;
881 for (
unsigned int i = 0; i < this->uNumLoadedFiles; ++i) {
882 if (this->pTextures[i].pPalette24) {
883 FILE *File = FindContainer(this->pTextures[i].header.pName);
888 fread(this->pTextures[i].pPalette24, 1, 0x300, File);
896 if (data_size !=
nullptr) {
901 FILE *
File = FindContainer(pContainer, &
size);
903 Error(
"Unable to load %s", pContainer.c_str());
914 if (data_size !=
nullptr) {
923 if (data_size !=
nullptr) {
927 FILE *
File = FindContainer(pContainer, 0);
929 Error(
"Unable to load %s", pContainer.c_str());
949 if (data_size !=
nullptr) {
956 #pragma pack(push, 1)
969 if (data_size !=
nullptr) {
973 FILE *
File = FindContainer(pContainer, 0);
975 Error(
"Unable to load %s", pContainer.c_str());
981 if (header.
uVersion != 91969 || (memcmp(&header.
pMagic,
"mvii", 4) != 0)) {
982 Error(
"Unable to load %s", pContainer.c_str());
998 if (data_size !=
nullptr) {
1007 if (
name == pSubIndices[
index].pFilename) {
1020 const char *pContainer,
int mode) {
1030 FILE *File = FindContainer(pContainer);
1031 if (File ==
nullptr) {
1041 this->_011BA4_debug_paletted_pixels_uncompressed) {
1064 const char *pContainer,
1071 size_t data_size = 0;
1072 FILE *pFile = FindContainer(pContainer, &data_size);
1073 if (pFile ==
nullptr) {
1079 strncpy(header->
pName, pContainer, 16);
1083 if ((header->
pBits & 2) && strcmp(header->
pName,
"sptext01")) {
1084 if (!pHardwareSurfaces || !pHardwareTextures) {
1085 pHardwareSurfaces =
new IDirectDrawSurface *[1000];
1086 memset(pHardwareSurfaces, 0, 1000 *
sizeof(IDirectDrawSurface *));
1088 pHardwareTextures =
new IDirect3DTexture2 *[1000];
1089 memset(pHardwareTextures, 0, 1000 *
sizeof(IDirect3DTexture2 *));
1091 ptr_011BB4 =
new char[1000];
1092 memset(ptr_011BB4, 0, 1000);
1094 if (_strnicmp(pContainer,
"wtrdr", 5)) {
1095 if (_strnicmp(pContainer,
"WtrTyl", 6)) {
1096 v14 = uNumLoadedFiles;
1098 render->hd_water_tile_id = uNumLoadedFiles;
1099 v14 = uNumLoadedFiles;
1106 char *temp_container;
1107 temp_container = (
char *)malloc(strlen(pContainer) + 2);
1108 *temp_container = 104;
1109 strcpy(temp_container + 1, pContainer);
1111 free((
void *)temp_container);
1118 _011BA4_debug_paletted_pixels_uncompressed) {
1131 fread(tmp_buf, 1, (
size_t)header->
uTextureSize, pFile);
1141 if (0x300 > data_size) {
1148 assert(data_size == 0);
1150 if (header->
pBits & 2) {
1163 for (
int v41 = 1; v41 < 15; ++v41) {
1166 for (
int v42 = 1; v42 < 15; ++v42) {
1177 const char *pContainer,
enum TEXTURE_TYPE uTextureType) {
1178 uint id = LoadTexture(pContainer, uTextureType);
1180 Assert(
id != -1 && L
"Texture_MM7 not found");
1182 return &pTextures[
id];
1187 for (
uint i = 0; i < uNumLoadedFiles; ++i) {
1188 if (!_stricmp(pContainer, pTextures[i].header.pName)) {
1193 Assert(uNumLoadedFiles < 1000);
1195 if (LoadTextureFromLOD(&pTextures[uNumLoadedFiles], pContainer,
1196 uTextureType) == -1) {
1197 for (
uint i = 0; i < uNumLoadedFiles; ++i) {
1198 if (!_stricmp(pTextures[i].header.pName,
"pending")) {
1202 LoadTextureFromLOD(&pTextures[uNumLoadedFiles],
"pending",
1206 return uNumLoadedFiles++;
1210 Assert(idx < MAX_LOD_TEXTURES,
"Texture_MM7 index out of bounds (%u)", idx);
1213 return pTextures + LoadDummyTexture();
1215 return pTextures + idx;