uint32 CIoman::Seek(uint32 handle, uint32 position, uint32 whence) { CLog::GetInstance().Print(LOG_NAME, "Seek(handle = %d, position = 0x%X, whence = %d);\r\n", handle, position, whence); uint32 result = 0xFFFFFFFF; try { Framework::CStream* stream = GetFileStream(handle); switch(whence) { case SEEK_DIR_SET: whence = Framework::STREAM_SEEK_SET; break; case SEEK_DIR_CUR: whence = Framework::STREAM_SEEK_CUR; break; case SEEK_DIR_END: whence = Framework::STREAM_SEEK_END; break; } stream->Seek(position, static_cast<Framework::STREAM_SEEK_DIRECTION>(whence)); result = static_cast<uint32>(stream->Tell()); } catch(const std::exception& except) { CLog::GetInstance().Print(LOG_NAME, "%s: Error occured while trying to seek file : %s\r\n", __FUNCTION__, except.what()); } return result; }
void CContainerChunk::LoadChildren(Framework::CStream& inputStream) { for(uint32 i = 0; i < m_childrenCount; i++) { uint64 baseOffset = inputStream.Tell(); auto chunk = CChunkLoader::Load(shared_from_this(), inputStream); AddChild(chunk); uint64 nextOffset = baseOffset + chunk->GetNextChunkOffset(); inputStream.Seek(nextOffset, Framework::STREAM_SEEK_SET); } }
void CDialog::WriteDialogTemplate(DIALOGTEMPLATE& dialog, Framework::CStream& stream) { stream.Write16(dialog.dlgVer); stream.Write16(dialog.signature); stream.Write32(dialog.helpID); stream.Write32(dialog.exStyle); stream.Write32(dialog.style); stream.Write16(dialog.cDlgItems); stream.Write16(dialog.x); stream.Write16(dialog.y); stream.Write16(dialog.cx); stream.Write16(dialog.cy); WriteSzOrOrd(dialog.menu, stream); WriteSzOrOrd(dialog.windowClass, stream); WriteString(dialog.title, stream); stream.Write16(dialog.pointsize); stream.Write16(dialog.weight); stream.Write8(dialog.italic); stream.Write8(dialog.charset); WriteString(dialog.typeface, stream); //Pad struct for alignment to DWORD boundary { auto currentBytePos = stream.Tell() & 0x3; if(currentBytePos != 0) { for(unsigned int i = 0; i < (4 - currentBytePos); i++) { stream.Write8(0); } } assert((stream.Tell() & 0x03) == 0); } if(!dialog.dialogItemData.empty()) { stream.Write(dialog.dialogItemData.data(), dialog.dialogItemData.size()); } }
CDialog::DIALOGTEMPLATE CDialog::ReadDialogTemplate(Framework::CStream& stream) { DIALOGTEMPLATE dialog; dialog.dlgVer = stream.Read16(); dialog.signature = stream.Read16(); assert(dialog.dlgVer == 1); assert(dialog.signature == 0xFFFF); dialog.helpID = stream.Read32(); dialog.exStyle = stream.Read32(); dialog.style = stream.Read32(); dialog.cDlgItems = stream.Read16(); dialog.x = stream.Read16(); dialog.y = stream.Read16(); dialog.cx = stream.Read16(); dialog.cy = stream.Read16(); assert((stream.Tell() & 0x01) == 0); dialog.menu = ReadSzOrOrd(stream); assert((stream.Tell() & 0x01) == 0); dialog.windowClass = ReadSzOrOrd(stream); assert((stream.Tell() & 0x01) == 0); dialog.title = ReadString(stream); dialog.pointsize = stream.Read16(); dialog.weight = stream.Read16(); dialog.italic = stream.Read8(); dialog.charset = stream.Read8(); assert((stream.Tell() & 0x01) == 0); dialog.typeface = ReadString(stream); //Struct has padding for alignment to DWORD boundary (only if there's other items to read) if(stream.GetRemainingLength() != 0) { auto currentBytePos = stream.Tell() & 0x3; if(currentBytePos != 0) { stream.Seek(4 - currentBytePos, Framework::STREAM_SEEK_CUR); } assert((stream.Tell() & 0x03) == 0); } uint32 itemDataLength = static_cast<uint32>(stream.GetRemainingLength()); if(itemDataLength != 0) { dialog.dialogItemData.resize(itemDataLength); stream.Read(&dialog.dialogItemData[0], itemDataLength); } return dialog; }
void CResourceSection::Read(Framework::CStream& inputStream) { CBaseSection::Read(inputStream); SEDBRES_HEADER header = {}; inputStream.Read(&header, sizeof(SEDBRES_HEADER)); std::vector<SEDBRES_ENTRY> entries; entries.resize(header.resourceCount); inputStream.Read(entries.data(), header.resourceCount * sizeof(SEDBRES_ENTRY)); uint64 basePosition = inputStream.Tell(); assert(header.resourceCount >= 2); const auto& resourceTypeEntry = entries[header.resourceCount - 2]; const auto& resourceIdEntry = entries[header.resourceCount - 1]; std::vector<uint32> resourceTypes; resourceTypes.resize(header.resourceCount); inputStream.Seek(basePosition + resourceTypeEntry.offset, Framework::STREAM_SEEK_SET); inputStream.Read(resourceTypes.data(), sizeof(uint32) * header.resourceCount); //Read resource ids std::vector<std::string> resourceIds; for(unsigned int i = 0; i < header.resourceCount; i++) { inputStream.Seek(basePosition + resourceIdEntry.offset + (i * 0x10), Framework::STREAM_SEEK_SET); resourceIds.push_back(inputStream.ReadString()); } //Read string table inputStream.Seek(basePosition + header.stringsOffset, Framework::STREAM_SEEK_SET); std::vector<std::string> strings; for(unsigned int i = 0; i < header.stringCount; i++) { strings.push_back(inputStream.ReadString()); } for(unsigned int i = 0; i < header.resourceCount; i++) { const auto& entry = entries[i]; if(entry.type == 0 || entry.size == 0) continue; uint32 resourceType = resourceTypes[i]; inputStream.Seek(basePosition + entry.offset, Framework::STREAM_SEEK_SET); SectionPtr section; switch(resourceType) { case '\0trb': case '\0bin': section = std::make_shared<CResourceSection>(); break; case 'sdrb': section = std::make_shared<CShaderSection>(); break; case '\0wrb': section = std::make_shared<CModelSection>(); break; case '\0skl': section = std::make_shared<CSkeletonSection>(); break; case '\0phb': section = std::make_shared<CPhbSection>(); break; case '\0txb': section = std::make_shared<CTextureSection>(); break; default: assert(0); break; } if(section) { AddChild(section); section->Read(inputStream); section->SetResourceId(resourceIds[i]); section->SetResourcePath(strings[i]); } } inputStream.Seek(basePosition, Framework::STREAM_SEEK_SET); }