World of Might and Magic  0.2.0
Open reimplementation of Might and Magic 6 7 8 game engine
Класс LOD::WriteableFile

#include <LOD.h>

+ Граф наследования:LOD::WriteableFile:
+ Граф связей класса LOD::WriteableFile:

Открытые члены

 WriteableFile ()
 
bool LoadFile (const String &pFilename, bool bWriting)
 
unsigned int Write (const String &file_name, const void *pDirData, size_t size, int a4)
 
void CloseWriteFile ()
 
int CreateTempFile ()
 
int FixDirectoryOffsets ()
 
bool _4621A7 ()
 
int CreateNewLod (LOD::FileHeader *pHeader, const String &root_name, const String &Source)
 
void AllocSubIndicesAndIO (unsigned int uNumSubIndices, unsigned int uBufferSize)
 
void FreeSubIndexAndIO ()
 
bool AppendDirectory (const String &file_name, const void *pData, size_t data_size)
 
void ClearSubNodes ()
 
- Открытые члены унаследованные от LOD::File
 File ()
 
virtual ~File ()
 
bool Open (const String &pFilename)
 
void Close ()
 
voidLoadRaw (const String &pContainer, size_t *data_size=nullptr)
 
voidLoadCompressedTexture (const String &pContainer, size_t *data_size=nullptr)
 
voidLoadCompressed (const String &pContainer, size_t *data_size=nullptr)
 
bool DoesContainerExist (const String &filename)
 
String GetSubNodeName (size_t index) const
 
size_t GetSubNodesCount () const
 
int GetSubNodeIndex (const String &name) const
 

Защищенные члены

virtual void ResetSubIndices ()
 
- Защищенные члены унаследованные от LOD::File
FILE * FindContainer (const String &filename, size_t *data_size=nullptr)
 
virtual bool OpenFile (const String &sFilename)
 
bool LoadHeader ()
 
bool LoadSubIndices (const String &sFolder)
 

Защищенные данные

uint8_tpIOBuffer
 
unsigned int uIOBufferSize
 
FILE * pOutputFileHandle
 
unsigned int uLODDataSize
 
- Защищенные данные унаследованные от LOD::File
FILE * pFile
 
String pLODName
 
bool isFileOpened
 
struct FileHeader header
 
std::vector< DirectorypRoot
 
String pContainerName
 
unsigned int uOffsetToSubIndex
 
unsigned int uNumSubDirs
 
struct DirectorypSubIndices
 

Подробное описание

См. определение в файле LOD.h строка 97

Конструктор(ы)

◆ WriteableFile()

LOD::WriteableFile::WriteableFile ( )

См. определение в файле LOD.cpp строка 681

681  {
682  pIOBuffer = nullptr;
683  uIOBufferSize = 0;
684 }

Методы

◆ LoadFile()

bool LOD::WriteableFile::LoadFile ( const String pFilename,
bool  bWriting 
)

См. определение в файле LOD.cpp строка 686

686  {
687  pFile = fopen(pFilename.c_str(), bWriting ? "rb" : "rb+");
688  if (pFile == nullptr) {
689  return false; // возможно файл не закрыт, поэтому не открывается
690  }
691 
692  pLODName = pFilename;
693  fread(&header, sizeof(LOD::FileHeader), 1, pFile);
694 
695  LOD::Directory lod_indx;
696  fread(&lod_indx, sizeof(LOD::Directory), 1, pFile);
697 
698  fseek(pFile, 0, SEEK_SET);
699  isFileOpened = true;
700  pContainerName = "chapter";
701  uLODDataSize = lod_indx.uDataSize;
702  uNumSubDirs = lod_indx.uNumSubIndices;
703  Assert(uNumSubDirs <= 300);
704 
706  fseek(pFile, uOffsetToSubIndex, SEEK_SET);
707 
708  fread(pSubIndices, sizeof(LOD::Directory), uNumSubDirs, pFile);
709  return true;
710 }

Перекрестные ссылки LOD::Directory::uDataSize, LOD::Directory::uNumSubIndices и LOD::Directory::uOfsetFromSubindicesStart.

Используется в _4621A7(), LoadGame() и SaveNewGame().

+ Граф вызова функции:

◆ Write()

unsigned int LOD::WriteableFile::Write ( const String file_name,
const void pDirData,
size_t  size,
int  a4 
)

См. определение в файле LOD.cpp строка 544

544  {
545  LOD::Directory dir;
546  strcpy(dir.pFilename, file_name.c_str());
547  dir.uDataSize = size;
548 
549  // insert new data in sorted index lod file
550  bool bRewrite_data = false;
551  int insert_index = -1;
552  if (!isFileOpened) { // sometimes gives crash
553  return 1;
554  }
555  if (!pSubIndices) {
556  return 2;
557  }
558  if (!pIOBuffer || !uIOBufferSize) {
559  return 3;
560  }
561 
562  for (size_t i = 0; i < uNumSubDirs; i++) {
563  int comp_res = _stricmp(pSubIndices[i].pFilename, dir.pFilename);
564  if (comp_res == 0) {
565  insert_index = i;
566  if (a4 == 0) {
567  bRewrite_data = true;
568  break;
569  }
570  if (a4 == 1) {
571  if (pSubIndices[i].uNumSubIndices < dir.uNumSubIndices) {
572  if (pSubIndices[i].priority < dir.priority)
573  return 4;
574  } else {
575  bRewrite_data = true;
576  }
577  break;
578  }
579  if (a4 == 2) return 4;
580  } else if (comp_res > 0) {
581  if (insert_index == -1) {
582  insert_index = i;
583  break;
584  }
585  }
586  }
587 
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;
592  if (!bRewrite_data)
593  size_correction = 0;
594  else
595  size_correction = pSubIndices[insert_index].uDataSize;
596 
597  // create chapter index
598  LOD::Directory Lindx;
599  strcpy(Lindx.pFilename, "chapter");
600  Lindx.dword_000018 = 0;
601  Lindx.priority = 0;
602  Lindx.uNumSubIndices = uNumSubDirs;
603  Lindx.uOfsetFromSubindicesStart = sizeof(LOD::FileHeader) + sizeof(LOD::Directory);
604  int total_data_size = uLODDataSize + dir.uDataSize - size_correction;
605  if (!bRewrite_data) {
606  total_data_size += sizeof(LOD::Directory);
607  Lindx.uNumSubIndices++;
608  }
609 
610  Lindx.uDataSize = total_data_size;
611  uNumSubDirs = Lindx.uNumSubIndices;
612  // move indexes +1 after insert point
613  if (!bRewrite_data &&
614  (insert_index < uNumSubDirs)) { // перезаписывание файлов для освобождения
615  // места для нового ф-ла
616  for (int i = uNumSubDirs; i > insert_index; --i)
617  memcpy(&pSubIndices[i], &pSubIndices[i - 1],
618  sizeof(LOD::Directory)); // Uninitialized memory access
619  }
620  // insert
621  memcpy(&pSubIndices[insert_index], &dir, sizeof(LOD::Directory)); // записать текущий файл
622  // correct offsets to data
623  if (uNumSubDirs > 0) {
624  size_t offset_to_data = sizeof(LOD::Directory) * uNumSubDirs;
625  for (int i = 0; i < uNumSubDirs; i++) {
626  pSubIndices[i].uOfsetFromSubindicesStart = offset_to_data;
627  offset_to_data += pSubIndices[i].uDataSize;
628  }
629  }
630 
631  // construct lod file with added data
632  fwrite(&header, sizeof(LOD::FileHeader), 1, tmp_file);
633  fwrite(&Lindx, sizeof(LOD::Directory), 1, tmp_file);
634  fseek(pFile, Lindx.uOfsetFromSubindicesStart, SEEK_SET);
635  fwrite(pSubIndices, sizeof(LOD::Directory), uNumSubDirs, tmp_file);
636 
637  size_t offset_to_data = sizeof(LOD::Directory) * uNumSubDirs;
638  if (!bRewrite_data) offset_to_data -= sizeof(LOD::Directory);
639 
640  fseek(pFile, offset_to_data, SEEK_CUR);
641  // copy from open lod to temp lod first half
642  int to_copy_size = pSubIndices[insert_index].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;
650  }
651  // add container data
652  fwrite(pDirData, 1, dir.uDataSize, tmp_file); // Uninitialized memory access(tmp_file)
653  if (bRewrite_data) fseek(pFile, size_correction, SEEK_CUR);
654 
655  // add remainng data last half
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;
666  }
667 
668  // replace old file by new with added data
669  fclose(tmp_file);
670  fclose(pFile);
671  CloseWriteFile();
672  remove(pLODName.c_str());
673  rename(Filename.c_str(), pLODName.c_str());
674  CloseWriteFile();
675 
676  // reload new
677  LoadFile(pLODName, 0); // isFileOpened == true, next file
678  return 0;
679 }

Перекрестные ссылки LOD::Directory::dword_000018, LOD::Directory::pFilename, LOD::Directory::priority, LOD::Directory::uDataSize, LOD::Directory::uNumSubIndices и LOD::Directory::uOfsetFromSubindicesStart.

Используется в DoSavegame() и SaveGame().

+ Граф вызова функции:

◆ CloseWriteFile()

void LOD::WriteableFile::CloseWriteFile ( )

См. определение в файле LOD.cpp строка 530

530  {
531  if (isFileOpened) {
532  pContainerName[0] = 0;
533  _6A0CA8_lod_unused = 0;
534 
535  isFileOpened = false;
536  fflush(pFile);
537  fclose(pFile);
538  pFile = nullptr;
539  }
540  // else
541  // __debugbreak();
542 }

Перекрестные ссылки _6A0CA8_lod_unused.

Используется в _4621A7(), DoSavegame(), LoadGame() и SaveNewGame().

+ Граф вызова функции:

◆ CreateTempFile()

int LOD::WriteableFile::CreateTempFile ( )

См. определение в файле LOD.cpp строка 518

518  {
519  if (!isFileOpened) return 1;
520 
521  if (pIOBuffer && uIOBufferSize) {
522  uNumSubDirs = 0;
523  pOutputFileHandle = fopen("lodapp.tmp", "wb+");
524  return pOutputFileHandle ? 1 : 7;
525  } else {
526  return 5;
527  }
528 }

Используется в SaveNewGame().

+ Граф вызова функции:

◆ FixDirectoryOffsets()

int LOD::WriteableFile::FixDirectoryOffsets ( )

См. определение в файле LOD.cpp строка 452

452  {
453  unsigned int total_size = 0;
454  for (int i = 0; i < uNumSubDirs; i++) {
455  total_size += pSubIndices[i].uDataSize;
456  }
457 
458  // fix offsets
459  int temp_offset = sizeof(LOD::Directory) * uNumSubDirs;
460  for (int i = 0; i < uNumSubDirs; i++) {
461  pSubIndices[i].uOfsetFromSubindicesStart = temp_offset;
462  temp_offset += pSubIndices[i].uDataSize;
463  }
464 
465  String Filename = "lod.tmp";
466  FILE *tmp_file = fopen(Filename.c_str(), "wb+");
467  if (tmp_file == nullptr) {
468  return 5;
469  }
470 
471  fwrite((const void *)&header, sizeof(LOD::FileHeader), 1, tmp_file);
472 
473  LOD::Directory Lindx;
474  strcpy(Lindx.pFilename, "chapter");
476  Lindx.uDataSize =
477  sizeof(LOD::Directory) * uNumSubDirs + total_size; // 14h 20
478  Lindx.dword_000018 = 0; // 18h 24
479  Lindx.uNumSubIndices = uNumSubDirs; // 1ch 28
480  Lindx.priority = 0; // 1Eh 30
481  fwrite(&Lindx, sizeof(LOD::Directory), 1, tmp_file);
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;
488  }
489  fread(pIOBuffer, 1, write_size, pOutputFileHandle);
490  fwrite(pIOBuffer, 1, write_size, tmp_file);
491  total_size -= write_size;
492  }
493 
494  fclose(tmp_file);
495  fclose(pOutputFileHandle);
496  CloseWriteFile();
497  remove("lodapp.tmp");
498  remove(pLODName.c_str());
499  rename(Filename.c_str(), pLODName.c_str());
500  CloseWriteFile();
501  LoadFile(pLODName.c_str(), 0);
502 
503  return 0;
504 }

Перекрестные ссылки LOD::Directory::dword_000018, LOD::Directory::pFilename, LOD::Directory::priority, LOD::Directory::uDataSize, LOD::Directory::uNumSubIndices и LOD::Directory::uOfsetFromSubindicesStart.

Используется в SaveNewGame().

+ Граф вызова функции:

◆ _4621A7()

bool LOD::WriteableFile::_4621A7 ( )

См. определение в файле LOD.cpp строка 446

446  { // закрыть и загрузить записываемый ф-л(при
447  // сохранении)
448  CloseWriteFile();
449  return LoadFile(pLODName, 0);
450 }

Перекрестные ссылки CloseWriteFile(), LoadFile() и LOD::File::pLODName.

Используется в DoSavegame().

+ Граф вызовов:
+ Граф вызова функции:

◆ CreateNewLod()

int LOD::WriteableFile::CreateNewLod ( LOD::FileHeader pHeader,
const String root_name,
const String Source 
)

См. определение в файле LOD.cpp строка 257

258  {
259  if (isFileOpened) return 1;
260  if (root_name.empty()) {
261  return 2;
262  }
263  strcpy(pHeader->pSignature, "LOD");
264  pHeader->LODSize = 100;
265  pHeader->uNumIndices = 1;
266 
267  LOD::Directory dir;
268  strcpy(dir.pFilename, root_name.c_str());
269  dir.field_F = 0;
270  dir.uDataSize = 0;
272  pLODName = lod_name;
273 
274  pFile = fopen(pLODName.c_str(), "wb+");
275  if (!pFile) return 3;
276  fwrite(pHeader, sizeof(LOD::FileHeader), 1, pFile);
277  fwrite(&dir, sizeof(LOD::Directory), 1, pFile);
278  fclose(pFile);
279  pFile = nullptr;
280  return 0;
281 }

Перекрестные ссылки LOD::Directory::field_F, LOD::FileHeader::LODSize, LOD::Directory::pFilename, LOD::FileHeader::pSignature, LOD::Directory::uDataSize, LOD::FileHeader::uNumIndices и LOD::Directory::uOfsetFromSubindicesStart.

Используется в SaveNewGame().

+ Граф вызова функции:

◆ AllocSubIndicesAndIO()

void LOD::WriteableFile::AllocSubIndicesAndIO ( unsigned int  uNumSubIndices,
unsigned int  uBufferSize 
)

См. определение в файле LOD.cpp строка 712

713  {
714  if (pSubIndices) {
715  logger->Warning(L"Attempt to reset a LOD subindex!");
716  free(pSubIndices);
717  pSubIndices = nullptr;
718  }
719  pSubIndices = (LOD::Directory *)malloc(sizeof(LOD::Directory) * uNumSubIndices);
720  if (pIOBuffer) {
721  logger->Warning(L"Attempt to reset a LOD IObuffer!");
722  free(pIOBuffer);
723  pIOBuffer = nullptr;
724  uIOBufferSize = 0;
725  }
726  if (uBufferSize) {
727  pIOBuffer = (uint8_t*)malloc(uBufferSize);
728  uIOBufferSize = uBufferSize;
729  }
730 }

Перекрестные ссылки logger и Log::Warning().

Используется в Initialize_GamesLOD_NewLOD().

+ Граф вызовов:
+ Граф вызова функции:

◆ FreeSubIndexAndIO()

void LOD::WriteableFile::FreeSubIndexAndIO ( )

См. определение в файле LOD.cpp строка 732

732  {
733  free(pSubIndices);
734  pSubIndices = nullptr;
735  free(pIOBuffer);
736  pIOBuffer = nullptr;
737 }

Используется в Engine::Deinitialize().

+ Граф вызова функции:

◆ AppendDirectory()

bool LOD::WriteableFile::AppendDirectory ( const String file_name,
const void pData,
size_t  data_size 
)

См. определение в файле LOD.cpp строка 506

506  {
507  Assert(uNumSubDirs < 299);
508 
509  LOD::Directory dir;
510  strcpy(dir.pFilename, file_name.c_str());
511  dir.uDataSize = data_size;
512 
513  memcpy(&pSubIndices[uNumSubDirs++], &dir, sizeof(LOD::Directory));
514  fwrite(pData, 1, dir.uDataSize, pOutputFileHandle);
515  return true;
516 }

Перекрестные ссылки LOD::Directory::pFilename и LOD::Directory::uDataSize.

Используется в SaveNewGame().

+ Граф вызова функции:

◆ ClearSubNodes()

void LOD::WriteableFile::ClearSubNodes ( )
inline

См. определение в файле LOD.h строка 112

112 { uNumSubDirs = 0; }

Перекрестные ссылки LOD::File::uNumSubDirs.

Используется в SaveNewGame().

+ Граф вызова функции:

◆ ResetSubIndices()

void LOD::WriteableFile::ResetSubIndices ( )
protectedvirtual

Переопределяет метод предка LOD::File.

См. определение в файле LOD.cpp строка 294

294  {
296  uLODDataSize = 0;
297 }

Перекрестные ссылки LOD::File::ResetSubIndices().

+ Граф вызовов:

Данные класса

◆ pIOBuffer

uint8_t* LOD::WriteableFile::pIOBuffer
protected

См. определение в файле LOD.h строка 118

◆ uIOBufferSize

unsigned int LOD::WriteableFile::uIOBufferSize
protected

См. определение в файле LOD.h строка 119

◆ pOutputFileHandle

FILE* LOD::WriteableFile::pOutputFileHandle
protected

См. определение в файле LOD.h строка 120

◆ uLODDataSize

unsigned int LOD::WriteableFile::uLODDataSize
protected

См. определение в файле LOD.h строка 121


Объявления и описания членов классов находятся в файлах:
LOD::Directory::field_F
char field_F
Definition: LOD.h:49
LOD::Directory::uDataSize
uint32_t uDataSize
Definition: LOD.h:51
LOD::WriteableFile::LoadFile
bool LoadFile(const String &pFilename, bool bWriting)
Definition: LOD.cpp:686
LOD::FileHeader::uNumIndices
uint32_t uNumIndices
Definition: LOD.h:39
LOD::File::ResetSubIndices
virtual void ResetSubIndices()
Definition: LOD.cpp:283
LOD::Directory::pFilename
char pFilename[15]
Definition: LOD.h:48
LOD::WriteableFile::pIOBuffer
uint8_t * pIOBuffer
Definition: LOD.h:118
LOD::File::header
struct FileHeader header
Definition: LOD.h:87
LOD::FileHeader::LODSize
uint32_t LODSize
Definition: LOD.h:37
LOD::WriteableFile::CloseWriteFile
void CloseWriteFile()
Definition: LOD.cpp:530
LOD::Directory::uOfsetFromSubindicesStart
uint32_t uOfsetFromSubindicesStart
Definition: LOD.h:50
LOD::WriteableFile::uLODDataSize
unsigned int uLODDataSize
Definition: LOD.h:121
LOD::File::pFile
FILE * pFile
Definition: LOD.h:83
LOD::Directory
Definition: LOD.h:45
LOD::File::uOffsetToSubIndex
unsigned int uOffsetToSubIndex
Definition: LOD.h:91
LOD::File::isFileOpened
bool isFileOpened
Definition: LOD.h:85
_6A0CA8_lod_unused
int _6A0CA8_lod_unused
Definition: LOD.cpp:28
Log::Warning
void Warning(const wchar_t *pFormat,...)
Definition: Log.cpp:28
LOD::Directory::uNumSubIndices
uint16_t uNumSubIndices
Definition: LOD.h:53
LOD::File::pSubIndices
struct Directory * pSubIndices
Definition: LOD.h:94
LOD::WriteableFile::pOutputFileHandle
FILE * pOutputFileHandle
Definition: LOD.h:120
LOD::File::uNumSubDirs
unsigned int uNumSubDirs
Definition: LOD.h:93
LOD::FileHeader::pSignature
char pSignature[4]
Definition: LOD.h:34
LOD::WriteableFile::uIOBufferSize
unsigned int uIOBufferSize
Definition: LOD.h:119
uint8_t
unsigned __int8 uint8_t
Definition: SDL_config.h:35
LOD::File::pContainerName
String pContainerName
Definition: LOD.h:90
LOD::Directory::priority
uint16_t priority
Definition: LOD.h:54
size
GLsizeiptr size
Definition: SDL_opengl_glext.h:540
logger
Log * logger
Definition: IocContainer.cpp:47
LOD::Directory::dword_000018
uint32_t dword_000018
Definition: LOD.h:52
LOD::FileHeader
Definition: LOD.h:22
String
std::string String
Definition: Strings.h:10
LOD::File::pLODName
String pLODName
Definition: LOD.h:84