// ----------------------------------------------------------------------------- // Reads non-UDMF thing data // ----------------------------------------------------------------------------- bool MapPreviewCanvas::readThings(ArchiveEntry* map_head, ArchiveEntry* map_end, MapFormat map_format) { // Find THINGS entry ArchiveEntry* things = nullptr; while (map_head) { // Check entry type if (map_head->type() == EntryType::fromId("map_things")) { things = map_head; break; } // Exit loop if we've reached the end of the map entries if (map_head == map_end) break; else map_head = map_head->nextEntry(); } // No things if (!things) return false; // Read things data if (map_format == MapFormat::Doom) { auto thng_data = (DoomMapFormat::Thing*)things->rawData(true); unsigned nt = things->size() / sizeof(DoomMapFormat::Thing); for (size_t a = 0; a < nt; a++) addThing(thng_data[a].x, thng_data[a].y); } else if (map_format == MapFormat::Doom64) { auto thng_data = (Doom64MapFormat::Thing*)things->rawData(true); unsigned nt = things->size() / sizeof(Doom64MapFormat::Thing); for (size_t a = 0; a < nt; a++) addThing(thng_data[a].x, thng_data[a].y); } else if (map_format == MapFormat::Hexen) { auto thng_data = (HexenMapFormat::Thing*)things->rawData(true); unsigned nt = things->size() / sizeof(HexenMapFormat::Thing); for (size_t a = 0; a < nt; a++) addThing(thng_data[a].x, thng_data[a].y); } return true; }
// ----------------------------------------------------------------------------- // Writes the wad archive to a MemChunk // Returns true if successful, false otherwise // ----------------------------------------------------------------------------- bool Wad2Archive::write(MemChunk& mc, bool update) { // Determine directory offset & individual lump offsets uint32_t dir_offset = 12; ArchiveEntry* entry = nullptr; for (uint32_t l = 0; l < numEntries(); l++) { entry = entryAt(l); entry->exProp("Offset") = (int)dir_offset; dir_offset += entry->size(); } // Clear/init MemChunk mc.clear(); mc.seek(0, SEEK_SET); mc.reSize(dir_offset + numEntries() * 32); // Setup wad type char wad_type[4] = { 'W', 'A', 'D', '2' }; if (wad3_) wad_type[3] = '3'; // Write the header uint32_t num_lumps = numEntries(); mc.write(wad_type, 4); mc.write(&num_lumps, 4); mc.write(&dir_offset, 4); // Write the lumps for (uint32_t l = 0; l < num_lumps; l++) { entry = entryAt(l); mc.write(entry->rawData(), entry->size()); } // Write the directory for (uint32_t l = 0; l < num_lumps; l++) { entry = entryAt(l); // Setup directory entry Wad2Entry info; memset(info.name, 0, 16); memcpy(info.name, CHR(entry->name()), entry->name().Len()); info.cmprs = (bool)entry->exProp("W2Comp"); info.dsize = entry->size(); info.size = entry->size(); info.offset = (int)entry->exProp("Offset"); info.type = (int)entry->exProp("W2Type"); // Write it mc.write(&info, 32); if (update) entry->setState(ArchiveEntry::State::Unmodified); } return true; }
// ----------------------------------------------------------------------------- // Writes the grp archive to a MemChunk // Returns true if successful, false otherwise // ----------------------------------------------------------------------------- bool GrpArchive::write(MemChunk& mc, bool update) { // Clear/init MemChunk mc.clear(); mc.seek(0, SEEK_SET); mc.reSize((1 + numEntries()) * 16); ArchiveEntry* entry; // Write the header uint32_t num_lumps = numEntries(); mc.write("KenSilverman", 12); mc.write(&num_lumps, 4); // Write the directory for (uint32_t l = 0; l < num_lumps; l++) { entry = entryAt(l); char name[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; long size = entry->size(); for (size_t c = 0; c < entry->name().length() && c < 12; c++) name[c] = entry->name()[c]; mc.write(name, 12); mc.write(&size, 4); if (update) { long offset = getEntryOffset(entry); entry->setState(ArchiveEntry::State::Unmodified); entry->exProp("Offset") = (int)offset; } } // Write the lumps for (uint32_t l = 0; l < num_lumps; l++) { entry = entryAt(l); mc.write(entry->rawData(), entry->size()); } return true; }
// ----------------------------------------------------------------------------- // Writes the lfd archive to a MemChunk // Returns true if successful, false otherwise // ----------------------------------------------------------------------------- bool LfdArchive::write(MemChunk& mc, bool update) { // Determine total size uint32_t dir_size = (numEntries() + 1) << 4; uint32_t total_size = dir_size; ArchiveEntry* entry; for (uint32_t l = 0; l < numEntries(); l++) { entry = entryAt(l); total_size += 16; setEntryOffset(entry, total_size); if (update) { entry->setState(ArchiveEntry::State::Unmodified); entry->exProp("Offset") = (int)total_size; } total_size += entry->size(); } // Clear/init MemChunk mc.clear(); mc.seek(0, SEEK_SET); mc.reSize(total_size); // Variables char type[5] = "RMAP"; char name[9] = "resource"; size_t size = wxINT32_SWAP_ON_BE(numEntries() << 4); // Write the resource map first mc.write(type, 4); mc.write(name, 8); mc.write(&size, 4); for (uint32_t l = 0; l < numEntries(); l++) { entry = entryAt(l); for (char& t : type) t = 0; for (char& n : name) n = 0; size = wxINT32_SWAP_ON_BE(entry->size()); wxFileName fn(entry->name()); for (size_t c = 0; c < fn.GetName().length() && c < 9; c++) name[c] = fn.GetName()[c]; for (size_t c = 0; c < fn.GetExt().length() && c < 5; c++) type[c] = fn.GetExt()[c]; mc.write(type, 4); mc.write(name, 8); mc.write(&size, 4); } // Write the lumps for (uint32_t l = 0; l < numEntries(); l++) { entry = entryAt(l); for (char& t : type) t = 0; for (char& n : name) n = 0; size = wxINT32_SWAP_ON_BE(entry->size()); wxFileName fn(entry->name()); for (size_t c = 0; c < fn.GetName().length() && c < 9; c++) name[c] = fn.GetName()[c]; for (size_t c = 0; c < fn.GetExt().length() && c < 5; c++) type[c] = fn.GetExt()[c]; mc.write(type, 4); mc.write(name, 8); mc.write(&size, 4); mc.write(entry->rawData(), entry->size()); } return true; }