#include "quam/wad2.h" namespace Wad2 { enum Compression { CompressNone, CompressLZSS, }; } struct Wad2Header { quint32 dirNum; quint32 dirOffset; }; struct Wad2Entry { std::string name; Arc::FileType type; Arc::File file; }; static Arc::FileType getFileType(int n) { switch(n) { case 0: return Arc::FileType::Normal; case 1: return Arc::FileType::Label; case 64: return Arc::FileType::Palette; case 65: return Arc::FileType::Texture; case 66: return Arc::FileType::Picture; case 67: return Arc::FileType::Sound; case 68: return Arc::FileType::MipTexture; default: throw EnumError("invalid file type"); } } static Wad2Header readWad2Header(std::istream &st) { auto magic = readBytes<4>(st); if(magic != std::array{'W', 'A', 'D', '2'}) { throw FileFormatError("not a wad2 file (invalid magic number)"); } Wad2Header hdr; hdr.dirNum = readLE(st); hdr.dirOffset = readLE(st); return hdr; } static Wad2Entry readWad2Entry(std::istream &st) { auto entOffset = readLE(st); auto entSize = readLE(st); auto entCSize = readLE(st); auto entType = readByte(st); auto entCompr = readByte(st); /* padding */ readBytes<2>(st); auto entName = readBytes<16>(st); if(entSize != entCSize || entCompr != Wad2::CompressNone) { throw UnimplementedError("compressed files not supported"); } auto pos = st.tellg(); st.seekg(entOffset); Arc::File file; file.resize(entSize); st.read(file.data(), entSize); st.seekg(pos); Wad2Entry ent; ent.name = ntbsToString(entName); ent.file = std::move(file); ent.type = getFileType(entType); return ent; } Arc::Dir readWad2(std::istream &st) { auto hdr = readWad2Header(st); st.seekg(hdr.dirOffset); Arc::Dir root; for(quint32 i = 0; i < hdr.dirNum; i++) { auto ent = readWad2Entry(st); root.emplace_back(std::move(ent.file), std::move(ent.name), ent.type); } return root; } Wad2Validator::Wad2Validator(QObject *parent) : QValidator{parent} { } QValidator::State Wad2Validator::validate(QString &input, int &pos) const { return QValidator::Acceptable; } // EOF