#include #include #include "DNAMP1.hpp" #include "PAK.hpp" namespace Retro { namespace DNAMP1 { void PAK::read(Athena::io::IStreamReader& reader) { atUint32 version = reader.readUint32Big(); if (version != 0x00030005) Log.report(LogVisor::FatalError, "unexpected PAK magic"); reader.readUint32Big(); atUint32 nameCount = reader.readUint32Big(); m_nameEntries.clear(); m_nameEntries.reserve(nameCount); for (atUint32 n=0 ; n::iterator found = m_idMap.find(entry.id); if (found != m_idMap.end()) { m_nameMap[entry.name] = found->second; found->second->name = entry.name; } } } void PAK::write(Athena::io::IStreamWriter& writer) const { writer.writeUint32Big(0x00030005); writer.writeUint32Big(0); writer.writeUint32Big((atUint32)m_nameEntries.size()); for (const NameEntry& entry : m_nameEntries) { NameEntry copy = entry; copy.nameLen = copy.name.size(); copy.write(writer); } writer.writeUint32Big(m_entries.size()); for (const Entry& entry : m_entries) { Entry tmp = entry; if (tmp.compressed) tmp.compressed = 1; tmp.write(writer); } } size_t PAK::binarySize(size_t __isz) const { __isz += 12; for (const NameEntry& entry : m_nameEntries) __isz += 12 + entry.name.size(); __isz += m_entries.size() * 20 + 4; return __isz; } std::unique_ptr PAK::Entry::getBuffer(const NOD::Node& pak, atUint64& szOut) const { if (compressed) { std::unique_ptr strm = pak.beginReadStream(offset); atUint32 decompSz; strm->read(&decompSz, 4); decompSz = HECL::SBig(decompSz); atUint8* buf = new atUint8[decompSz]; atUint8* bufCur = buf; atUint8 compBuf[0x8000]; if (compressed == 1) { atUint32 compRem = size - 4; z_stream zs = {}; inflateInit(&zs); zs.avail_out = decompSz; zs.next_out = buf; while (zs.avail_out) { atUint64 readSz = strm->read(compBuf, std::min(compRem, atUint32(0x8000))); compRem -= readSz; zs.avail_in = readSz; zs.next_in = compBuf; inflate(&zs, Z_FINISH); } inflateEnd(&zs); } else { atUint32 rem = decompSz; while (rem) { atUint16 chunkSz; strm->read(&chunkSz, 2); chunkSz = HECL::SBig(chunkSz); strm->read(compBuf, chunkSz); lzo_uint dsz = rem; lzo1x_decompress(compBuf, chunkSz, bufCur, &dsz, nullptr); bufCur += dsz; rem -= dsz; } } szOut = decompSz; return std::unique_ptr(buf); } else { atUint8* buf = new atUint8[size]; pak.beginReadStream(offset)->read(buf, size); szOut = size; return std::unique_ptr(buf); } } } }