/* FontManager::initFonts * Loads all needed fonts for rendering. SFML 2.x implementation *******************************************************************/ int FontManager::initFonts() { // --- Load general fonts --- int ret = 0; // Normal ArchiveEntry* entry = theArchiveManager->programResourceArchive()->entryAtPath("fonts/dejavu_sans.ttf"); if (entry) ++ret, font_normal.loadFromMemory((const char*)entry->getData(), entry->getSize()); // Condensed entry = theArchiveManager->programResourceArchive()->entryAtPath("fonts/dejavu_sans_c.ttf"); if (entry) ++ret, font_condensed.loadFromMemory((const char*)entry->getData(), entry->getSize()); // Bold entry = theArchiveManager->programResourceArchive()->entryAtPath("fonts/dejavu_sans_b.ttf"); if (entry) ++ret, font_bold.loadFromMemory((const char*)entry->getData(), entry->getSize()); // Condensed Bold entry = theArchiveManager->programResourceArchive()->entryAtPath("fonts/dejavu_sans_cb.ttf"); if (entry) ++ret, font_boldcondensed.loadFromMemory((const char*)entry->getData(), entry->getSize()); // Monospace entry = theArchiveManager->programResourceArchive()->entryAtPath("fonts/dejavu_mono.ttf"); if (entry) ++ret, font_small.loadFromMemory((const char*)entry->getData(), entry->getSize()); return ret; }
/* CTexture::parseDefine * Parses a HIRESTEX define block *******************************************************************/ bool CTexture::parseDefine(Tokenizer& tz) { this->type = "Define"; this->extended = true; this->defined = true; name = tz.getToken().Upper(); def_width = tz.getInteger(); def_height = tz.getInteger(); width = def_width; height = def_height; ArchiveEntry* entry = theResourceManager->getPatchEntry(name); if (entry) { SImage image; if (image.open(entry->getMCData())) { width = image.getWidth(); height = image.getHeight(); scale_x = (double)width / (double)def_width; scale_y = (double)height / (double)def_height; } } CTPatchEx* patch = new CTPatchEx(name); patches.push_back(patch); return true; }
void importEditorImages(MapTexHashMap& map, ArchiveTreeNode* dir, string path) { SImage image; // Go through entries for (unsigned a = 0; a < dir->numEntries(); a++) { ArchiveEntry* entry = dir->getEntry(a); // Load entry to image if (image.open(entry->getMCData())) { // Create texture in hashmap string name = path + entry->getName(true); //wxLogMessage("Loading editor texture %s", CHR(name)); map_tex_t& mtex = map[name]; mtex.texture = new GLTexture(false); mtex.texture->setFilter(GLTexture::MIPMAP); mtex.texture->loadImage(&image); } } // Go through subdirs for (unsigned a = 0; a < dir->nChildren(); a++) { ArchiveTreeNode* subdir = (ArchiveTreeNode*)dir->getChild(a); importEditorImages(map, subdir, path + subdir->getName() + "/"); } }
/* TextureXPanel::exportTexture * Create standalone image entries of any selected textures *******************************************************************/ void TextureXPanel::exportTexture() { // Get selected textures vector<long> selec_num = list_textures->getSelection(); vector<CTexture*> selection; if (!tx_entry) return; //saveTEXTUREX(); Archive* archive = tx_entry->getParent(); bool force_rgba = texture_editor->getBlendRGBA(); // Go through selection for (unsigned a = 0; a < selec_num.size(); ++a) { selection.push_back(texturex.getTexture(selec_num[a])); } // Create gfx conversion dialog GfxConvDialog gcd(this); // Send selection to the gcd gcd.openTextures(selection, texture_editor->getPalette(), archive, force_rgba); // Run the gcd gcd.ShowModal(); // Show splash window theSplashWindow->show("Writing converted image data...", true); // Write any changes for (unsigned a = 0; a < selection.size(); a++) { // Update splash window theSplashWindow->setProgressMessage(selection[a]->getName()); theSplashWindow->setProgress((float)a / (float)selection.size()); // Skip if the image wasn't converted if (!gcd.itemModified(a)) continue; // Get image and conversion info SImage* image = gcd.getItemImage(a); SIFormat* format = gcd.getItemFormat(a); // Write converted image back to entry MemChunk mc; format->saveImage(*image, mc, force_rgba ? NULL : gcd.getItemPalette(a)); ArchiveEntry* lump = new ArchiveEntry; lump->importMemChunk(mc); lump->rename(selection[a]->getName()); archive->addEntry(lump, "textures"); EntryType::detectEntryType(lump); lump->setExtensionByType(); } // Hide splash window theSplashWindow->hide(); }
/* Archive::importDir * Imports all files (including subdirectories) from [directory] into * the archive *******************************************************************/ bool Archive::importDir(string directory) { // Get a list of all files in the directory wxArrayString files; wxDir::GetAllFiles(directory, &files); // Go through files for (unsigned a = 0; a < files.size(); a++) { string name = files[a]; name.Replace(directory, "", false); // Remove directory from entry name // Split filename into dir+name wxFileName fn(name); string ename = fn.GetFullName(); string edir = fn.GetPath(); // Remove beginning \ or / from dir if (edir.StartsWith("\\") || edir.StartsWith("/")) edir.Remove(0, 1); // Add the entry ArchiveTreeNode* dir = createDir(edir); ArchiveEntry* entry = addNewEntry(ename, dir->numEntries()+1, dir); // Load data entry->importFile(files[a]); // Set unmodified entry->setState(0); dir->getDirEntry()->setState(0); } return true; }
// ---------------------------------------------------------------------------- // ArchiveEntryList::getSelectedDirectories // // Returns a vector of all currently selected directories // ---------------------------------------------------------------------------- vector<ArchiveTreeNode*> ArchiveEntryList::getSelectedDirectories() { vector<ArchiveTreeNode*> ret; // Get all selected items vector<long> selection = getSelection(); // Go through the selection for (size_t a = 0; a < selection.size(); a++) { ArchiveEntry* entry = getEntry(selection[a]); // If the selected entry is the 'back folder', ignore it if (entry == entry_dir_back) continue; else if (entry->getType() == EntryType::folderType()) { // If the entry is a folder type, get its ArchiveTreeNode counterpart ArchiveTreeNode* dir = archive->getDir(entry->getName(), current_dir); // Add it to the return list if (dir) ret.push_back(dir); } } return ret; }
/* MapEntryPanel::createImage * Creates a PNG file of the map preview * TODO: Preference panel for background and line colors, * as well as for image size *******************************************************************/ bool MapEntryPanel::createImage() { if (entry == NULL) return false; ArchiveEntry temp; // Stupid OpenGL grumble grumble grumble if (GLEW_ARB_framebuffer_object) map_canvas->createImage(temp, map_image_width, map_image_height); else map_canvas->createImage(temp, min<int>(map_image_width, map_canvas->GetSize().x), min<int>(map_image_height, map_canvas->GetSize().y)); string name = S_FMT("%s_%s", CHR(entry->getParent()->getFilename(false)), CHR(entry->getName())); wxFileName fn(name); // Create save file dialog wxFileDialog dialog_save(this, S_FMT("Save Map Preview \"%s\"", name.c_str()), dir_last, fn.GetFullName(), "PNG (*.PNG)|*.png", wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition); // Run the dialog & check that the user didn't cancel if (dialog_save.ShowModal() == wxID_OK) { // If a filename was selected, export it bool ret = temp.exportFile(dialog_save.GetPath()); // Save 'dir_last' dir_last = dialog_save.GetDirectory(); return ret; } return true; }
/* TextureClipboardItem::TextureClipboardItem * TextureClipboardItem class constructor *******************************************************************/ TextureClipboardItem::TextureClipboardItem(CTexture* texture, Archive* parent) : ClipboardItem(CLIPBOARD_COMPOSITE_TEXTURE) { // Create/copy texture this->texture = new CTexture(); this->texture->copyTexture(texture); // Copy patch entries if possible for (unsigned a = 0; a < texture->nPatches(); a++) { ArchiveEntry* entry = texture->getPatch(a)->getPatchEntry(parent); // FIXME/TODO: Do something to handle patches that are defined // in TEXTURES rather than a discrete entry! if (entry == NULL) continue; // Don't copy patch if it has been already bool there = false; for (unsigned b = 0; b < patch_entries.size(); b++) { if (patch_entries[b]->getName() == entry->getName()) { there = true; break; } } if (there) continue; // Copy patch entry if (entry) patch_entries.push_back(new ArchiveEntry(*entry)); } }
/* ArchiveEntry::ArchiveEntry * ArchiveEntry class copy constructor *******************************************************************/ ArchiveEntry::ArchiveEntry(ArchiveEntry& copy) { // Initialise (copy) attributes this->parent = NULL; this->name = copy.name; this->size = copy.size; this->data_loaded = true; this->state = 2; this->type = copy.type; this->locked = false; this->state_locked = false; this->reliability = copy.reliability; this->next = NULL; this->prev = NULL; this->encrypted = copy.encrypted; // Copy data data.importMem(copy.getData(true), copy.getSize()); // Copy extra properties copy.exProps().copyTo(ex_props); // Clear properties that shouldn't be copied ex_props.removeProperty("ZipIndex"); ex_props.removeProperty("Offset"); // Set entry state state = 2; state_locked = false; }
SBrush::SBrush(string name) { image = nullptr; this->name = name; icon = name.AfterFirst('_'); cx = 0; cy = 0; Archive* res = App::archiveManager().programResourceArchive(); if (res == nullptr) return; ArchiveEntry* file = res->entryAtPath(S_FMT("icons/general/%s.png", icon)); if (file == nullptr || file->getSize() == 0) { LOG_MESSAGE(2, "error, no file at icons/general/%s.png", icon); return; } image = new SImage(); if (!image->open(file->getMCData(), 0, "png")) { LOG_MESSAGE(2, "couldn't load image data for icons/general/%s.png", icon); return; } image->convertAlphaMap(SImage::ALPHA); cx = image->getWidth() >> 1; cy = image->getHeight() >> 1; theBrushManager->add(this); }
/* PatchTableListView::getItemText * Returns the string for [item] at [column] *******************************************************************/ string PatchTableListView::getItemText(long item, long column, long index) const { // Check patch table exists if (!patch_table) return "INVALID INDEX"; // Check index is ok if (index < 0 || (unsigned)index > patch_table->nPatches()) return "INVALID INDEX"; // Get associated patch patch_t& patch = patch_table->patch(index); if (column == 0) // Index column return S_FMT("%04d", index); else if (column == 1) // Name column return patch.name; else if (column == 2) // Usage count column return S_FMT("%lu", patch.used_in.size()); else if (column == 3) // Archive column { // Get patch entry ArchiveEntry* entry = patch_table->patchEntry(index); // If patch entry can't be found return invalid if (entry) return entry->getParent()->getFilename(false); else return "(!) NOT FOUND"; } else // Invalid column return "INVALID COLUMN"; }
/* ArchiveTreeNode::merge * Merges [node] with this node. Entries within [node] are added * at [position] within this node. Returns false if [node] is invalid, * true otherwise *******************************************************************/ bool ArchiveTreeNode::merge(ArchiveTreeNode* node, unsigned position, int state) { // Check node was given to merge if (!node) return false; // Merge entries for (unsigned a = 0; a < node->numEntries(); a++) { if (node->getEntry(a)) { string name = Misc::lumpNameToFileName(node->getEntry(a)->getName()); node->getEntry(a)->setName(name); } ArchiveEntry* nentry = new ArchiveEntry(*(node->getEntry(a))); addEntry(nentry, position); nentry->setState(state); if (position < entries.size()) position++; } // Merge subdirectories for (unsigned a = 0; a < node->nChildren(); a++) { ArchiveTreeNode* child = (ArchiveTreeNode*)STreeNode::addChild(node->getChild(a)->getName()); child->merge((ArchiveTreeNode*)node->getChild(a)); child->getDirEntry()->setState(state); } return true; }
/* Archive::findModifiedEntries * Returns a list of modified entries, and set archive to unmodified * status if the list is empty *******************************************************************/ vector<ArchiveEntry*> Archive::findModifiedEntries(ArchiveTreeNode* dir) { // Init search variables if (dir == NULL) dir = dir_root; vector<ArchiveEntry*> ret; // Search entries for (unsigned a = 0; a < dir->numEntries(); a++) { ArchiveEntry* entry = dir->getEntry(a); // Add new and modified entries if (entry->getState() != 0) ret.push_back(entry); } // Search subdirectories for (unsigned a = 0; a < dir->nChildren(); a++) { vector<ArchiveEntry*> vec = findModifiedEntries((ArchiveTreeNode*)dir->getChild(a)); ret.insert(ret.end(), vec.begin(), vec.end()); } // If there aren't actually any, set archive to be unmodified if (ret.size() == 0) setModified(false); // Return matches return ret; }
// ---------------------------------------------------------------------------- // ArchiveEntryList::onListItemActivated // // Called when a list item is 'activated' (double-click or enter) // ---------------------------------------------------------------------------- void ArchiveEntryList::onListItemActivated(wxListEvent& e) { // Get item entry ArchiveEntry* entry = getEntry(e.GetIndex()); // Do nothing if NULL (shouldn't be) if (!entry) return; // If it's a folder, open it if (entry->getType() == EntryType::folderType()) { // Get directory to open ArchiveTreeNode* dir = nullptr; if (entry == entry_dir_back) dir = (ArchiveTreeNode*)current_dir->getParent(); // 'Back directory' entry, open current dir's parent else dir = archive->getDir(entry->getName(), current_dir); // Check it exists (really should) if (!dir) { LOG_MESSAGE(1, "Error: Trying to open nonexistant directory"); return; } // Set current dir setDir(dir); } else e.Skip(); }
// ---------------------------------------------------------------------------- // ArchiveEntryList::updateItemAttr // // Called when widget requests the attributes // (text colour / background colour / font) for [item] // ---------------------------------------------------------------------------- void ArchiveEntryList::updateItemAttr(long item, long column, long index) const { // Get associated entry ArchiveEntry* entry = getEntry(item); // Init attributes wxColour col_bg = wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOX); item_attr->SetTextColour(WXCOL(ColourConfiguration::getColour("error"))); item_attr->SetBackgroundColour(col_bg); // If entry doesn't exist, return error colour if (!entry) return; // Set font if (elist_name_monospace && !list_font_monospace) item_attr->SetFont((column == 0) ? *font_monospace : *font_normal); else item_attr->SetFont(list_font_monospace ? *font_monospace : *font_normal); // Set background colour defined in entry type (if any) rgba_t col = entry->getType()->getColour(); if ((col.r != 255 || col.g != 255 || col.b != 255) && elist_type_bgcol) { rgba_t bcol; bcol.r = (col.r * elist_type_bgcol_intensity) + (col_bg.Red() * (1.0 - elist_type_bgcol_intensity)); bcol.g = (col.g * elist_type_bgcol_intensity) + (col_bg.Green() * (1.0 - elist_type_bgcol_intensity)); bcol.b = (col.b * elist_type_bgcol_intensity) + (col_bg.Blue() * (1.0 - elist_type_bgcol_intensity)); item_attr->SetBackgroundColour(WXCOL(bcol)); } // Alternating row colour if (elist_alt_row_colour && item % 2 > 0) { wxColour dark = item_attr->GetBackgroundColour().ChangeLightness(95); item_attr->SetBackgroundColour(dark); } // Set colour depending on entry state switch (entry->getState()) { case 1: item_attr->SetTextColour(WXCOL(ColourConfiguration::getColour("modified"))); break; case 2: item_attr->SetTextColour(WXCOL(ColourConfiguration::getColour("new"))); break; default: item_attr->SetTextColour(wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOXTEXT)); break; }; // Locked state overrides others if (entry->isLocked()) item_attr->SetTextColour(WXCOL(ColourConfiguration::getColour("locked"))); }
/* MapEditorWindow::loadMapScripts * Loads any scripts from [map] into the script editor *******************************************************************/ void MapEditorWindow::loadMapScripts(Archive::mapdesc_t map) { // Don't bother if no scripting language specified if (theGameConfiguration->scriptLanguage().IsEmpty()) { // Hide script editor wxAuiManager* m_mgr = wxAuiManager::GetManager(this); wxAuiPaneInfo& p_inf = m_mgr->GetPane("script_editor"); p_inf.Show(false); m_mgr->Update(); return; } // Don't bother if new map if (!map.head) { panel_script_editor->openScripts(NULL, NULL); return; } // Check for pk3 map if (map.archive) { WadArchive* wad = new WadArchive(); wad->open(map.head->getMCData()); vector<Archive::mapdesc_t> maps = wad->detectMaps(); if (!maps.empty()) { loadMapScripts(maps[0]); wad->close(); delete wad; return; } } // Go through map entries ArchiveEntry* entry = map.head->nextEntry(); ArchiveEntry* scripts = NULL; ArchiveEntry* compiled = NULL; while (entry && entry != map.end->nextEntry()) { // Check for SCRIPTS/BEHAVIOR if (theGameConfiguration->scriptLanguage() == "acs_hexen" || theGameConfiguration->scriptLanguage() == "acs_zdoom") { if (S_CMPNOCASE(entry->getName(), "SCRIPTS")) scripts = entry; if (S_CMPNOCASE(entry->getName(), "BEHAVIOR")) compiled = entry; } // Next entry entry = entry->nextEntry(); } // Open scripts/compiled if found panel_script_editor->openScripts(scripts, compiled); }
/* NodeBuilders::init * Loads all node builder definitions from the program resource *******************************************************************/ void NodeBuilders::init() { // Init invalid builder invalid.id = "invalid"; // Get nodebuilders configuration from slade.pk3 Archive* archive = theArchiveManager->programResourceArchive(); ArchiveEntry* config = archive->entryAtPath("config/nodebuilders.cfg"); if (!config) return; // Parse it Parser parser; parser.parseText(config->getMCData(), "nodebuilders.cfg"); // Get 'nodebuilders' block ParseTreeNode* root = (ParseTreeNode*)parser.parseTreeRoot()->getChild("nodebuilders"); if (!root) return; // Go through child block for (unsigned a = 0; a < root->nChildren(); a++) { ParseTreeNode* n_builder = (ParseTreeNode*)root->getChild(a); // Parse builder block builder_t builder; builder.id = n_builder->getName(); for (unsigned b = 0; b < n_builder->nChildren(); b++) { ParseTreeNode* node = (ParseTreeNode*)n_builder->getChild(b); // Option if (S_CMPNOCASE(node->getType(), "option")) { builder.options.push_back(node->getName()); builder.option_desc.push_back(node->getStringValue()); } // Builder name else if (S_CMPNOCASE(node->getName(), "name")) builder.name = node->getStringValue(); // Builder command else if (S_CMPNOCASE(node->getName(), "command")) builder.command = node->getStringValue(); // Builder executable else if (S_CMPNOCASE(node->getName(), "executable")) builder.exe = node->getStringValue(); } builders.push_back(builder); } // Set builder paths for (unsigned a = 0; a < builder_paths.size(); a+=2) getBuilder(builder_paths[a]).path = builder_paths[a+1]; }
/* MapPreviewCanvas::readVertices * Reads non-UDMF vertex data *******************************************************************/ bool MapPreviewCanvas::readVertices(ArchiveEntry* map_head, ArchiveEntry* map_end, int map_format) { // Find VERTEXES entry ArchiveEntry* vertexes = NULL; while (map_head) { // Check entry type if (map_head->getType() == EntryType::getType("map_vertexes")) { vertexes = 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(); } // Can't open a map without vertices if (!vertexes) return false; // Read vertex data MemChunk& mc = vertexes->getMCData(); mc.seek(0, SEEK_SET); if (map_format == MAP_DOOM64) { doom64vertex_t v; while (1) { // Read vertex if (!mc.read(&v, 8)) break; // Add vertex addVertex((double)v.x/65536, (double)v.y/65536); } } else { doomvertex_t v; while (1) { // Read vertex if (!mc.read(&v, 4)) break; // Add vertex addVertex((double)v.x, (double)v.y); } } return true; }
// ----------------------------------------------------------------------------- // Reads non-UDMF vertex data // ----------------------------------------------------------------------------- bool MapPreviewCanvas::readVertices(ArchiveEntry* map_head, ArchiveEntry* map_end, MapFormat map_format) { // Find VERTEXES entry ArchiveEntry* vertexes = nullptr; while (map_head) { // Check entry type if (map_head->type() == EntryType::fromId("map_vertexes")) { vertexes = 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(); } // Can't open a map without vertices if (!vertexes) return false; // Read vertex data auto& mc = vertexes->data(); mc.seek(0, SEEK_SET); if (map_format == MapFormat::Doom64) { Doom64MapFormat::Vertex v; while (true) { // Read vertex if (!mc.read(&v, 8)) break; // Add vertex addVertex((double)v.x / 65536, (double)v.y / 65536); } } else { DoomMapFormat::Vertex v; while (true) { // Read vertex if (!mc.read(&v, 4)) break; // Add vertex addVertex((double)v.x, (double)v.y); } } return true; }
/* GobArchive::write * Writes the gob archive to a MemChunk * Returns true if successful, false otherwise *******************************************************************/ bool GobArchive::write(MemChunk& mc, bool update) { // Determine directory offset & individual lump offsets uint32_t dir_offset = 8; ArchiveEntry* entry = NULL; for (uint32_t l = 0; l < numEntries(); l++) { entry = getEntry(l); setEntryOffset(entry, dir_offset); dir_offset += entry->getSize(); } // Clear/init MemChunk mc.clear(); mc.seek(0, SEEK_SET); mc.reSize(dir_offset + 4 + numEntries() * 21); // Write the header uint32_t num_lumps = wxINT32_SWAP_ON_BE(numEntries()); dir_offset = wxINT32_SWAP_ON_BE(dir_offset); char header[4] = { 'G', 'O', 'B', 0xA }; mc.write(header, 4); mc.write(&dir_offset, 4); // Write the lumps for (uint32_t l = 0; l < numEntries(); l++) { entry = getEntry(l); mc.write(entry->getData(), entry->getSize()); } // Write the directory mc.write(&num_lumps, 4); for (uint32_t l = 0; l < numEntries(); l++) { entry = getEntry(l); char name[13] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; long offset = wxINT32_SWAP_ON_BE(getEntryOffset(entry)); long size = wxINT32_SWAP_ON_BE(entry->getSize()); for (size_t c = 0; c < entry->getName().length() && c < 13; c++) name[c] = entry->getName()[c]; mc.write(&offset, 4); mc.write(&size, 4); mc.write(name, 13); if (update) { entry->setState(0); entry->exProp("Offset") = (int)offset; } } return true; }
// ---------------------------------------------------------------------------- // ArchiveEntryList::entrySize // // Returns either the size of the entry at [index], or if it is a folder, the // number of entries+subfolders within it // ---------------------------------------------------------------------------- int ArchiveEntryList::entrySize(long index) { ArchiveEntry* entry = getEntry(index, false); if (entry->getType() == EntryType::folderType()) { ArchiveTreeNode* dir = archive->getDir(entry->getName(), current_dir); if (dir) return dir->numEntries() + dir->nChildren(); else return 0; } else return entry->getSize(); }
/* SplashWindow::init * Sets up the splash window *******************************************************************/ void SplashWindow::init() { // Load logo image string tempfile = appPath("temp.png", DIR_TEMP); ArchiveEntry* logo = theArchiveManager->programResourceArchive()->getEntry("logo.png"); if (logo) { logo->exportFile(tempfile); bm_logo.LoadFile(tempfile, wxBITMAP_TYPE_PNG); } // Clean up wxRemoveFile(tempfile); }
// ---------------------------------------------------------------------------- // ArchiveEntryList::getItemIcon // // Called when the widget requests the icon for [item] // ---------------------------------------------------------------------------- int ArchiveEntryList::getItemIcon(long item, long column, long index) const { if (column > 0) return -1; // Get associated entry ArchiveEntry* entry = getEntry(item); // If entry doesn't exist, return invalid image if (!entry) return -1; return entry->getType()->getIndex(); }
Palette8bit* MapTextureManager::getResourcePalette() { if (thePaletteChooser->globalSelected()) { ArchiveEntry* entry = theResourceManager->getPaletteEntry("PLAYPAL", archive); if (!entry) return thePaletteChooser->getSelectedPalette(); palette->loadMem(entry->getMCData()); return palette; } else return thePaletteChooser->getSelectedPalette(); }
// ---------------------------------------------------------------------------- // ArchiveEntryList::labelEdited // // Called when a label has been edited // ---------------------------------------------------------------------------- void ArchiveEntryList::labelEdited(int col, int index, string new_label) { if (undo_manager) undo_manager->beginRecord("Rename Entry"); // Rename the entry ArchiveEntry* entry = getEntry(index); if (entry->getParent()) entry->getParent()->renameEntry(entry, new_label); else entry->rename(new_label); if (undo_manager) undo_manager->endRecord(true); }
/* WadArchive::detectIncludes * Parses the DECORATE, GLDEFS, etc. lumps for included files, and * mark them as being of the same type *******************************************************************/ void WadArchive::detectIncludes() { // DECORATE: #include "lumpname" // GLDEFS: #include "lumpname" // SBARINFO: #include "lumpname" // ZMAPINFO: translator = "lumpname" // EMAPINFO: extradata = lumpname // EDFROOT: lumpinclude("lumpname") const char * lumptypes[6] = { "DECORATE", "GLDEFS", "SBARINFO", "ZMAPINFO", "EMAPINFO", "EDFROOT" }; const char * entrytypes[6] = { "decorate", "gldefslump", "sbarinfo", "xlat", "extradata", "edf" }; const char * tokens[6] = { "#include", "#include", "#include", "translator", "extradata", "lumpinclude" }; Archive::search_options_t opt; opt.ignore_ext = true; Tokenizer tz; tz.setSpecialCharacters(";,:|={}/()"); for (int i = 0; i < 6; ++i) { opt.match_name = lumptypes[i]; vector<ArchiveEntry*> entries = findAll(opt); if (entries.size()) { for (size_t j = 0; j < entries.size(); ++j) { tz.openMem(&entries[j]->getMCData(), lumptypes[i]); string token = tz.getToken(); while (token.length()) { if (token.Lower() == tokens[i]) { if (i >= 3) // skip '=' or '(' tz.getToken(); string name = tz.getToken(); if (i == 5) // skip ')' tz.getToken(); opt.match_name = name; ArchiveEntry * entry = findFirst(opt); if (entry) entry->setType(EntryType::getType(entrytypes[i])); } else tz.skipLineComment(); token = tz.getToken(); } } } } }
/* ArchiveManager::addArchive * Adds an archive to the archive list *******************************************************************/ bool ArchiveManager::addArchive(Archive* archive) { // Only add if archive is a valid pointer if (archive) { // Add to the list archive_t n_archive; n_archive.archive = archive; n_archive.resource = true; open_archives.push_back(n_archive); // Listen to the archive listenTo(archive); // Announce the addition announce("archive_added"); // Add to resource manager theResourceManager->addArchive(archive); // ZDoom also loads any WADs found in the root of a PK3 or directory if ((archive->getType() == ARCHIVE_ZIP || archive->getType() == ARCHIVE_FOLDER) && auto_open_wads_root) { ArchiveTreeNode* root = archive->getRoot(); ArchiveEntry* entry; EntryType* type; for (unsigned a = 0; a < root->numEntries(); a++) { entry = root->getEntry(a); if (entry->getType() == EntryType::unknownType()) EntryType::detectEntryType(entry); type = entry->getType(); if (type->getId() == "wad") // First true: yes, manage this // Second true: open silently, don't open a tab for it openArchive(entry, true, true); } } return true; } else return false; }
/* EntryOperations::convertTextures * Converts multiple TEXTURE1/2 entries to a single ZDoom text-based * TEXTURES entry *******************************************************************/ bool EntryOperations::convertTextures(vector<ArchiveEntry*> entries) { // Check any entries were given if (entries.size() == 0) return false; // Get parent archive of entries Archive* parent = entries[0]->getParent(); // Can't do anything if entry isn't in an archive if (!parent) return false; // Find patch table in parent archive Archive::search_options_t opt; opt.match_type = EntryType::getType("pnames"); ArchiveEntry* pnames = parent->findLast(opt); // Check it exists if (!pnames) return false; // Load patch table PatchTable ptable; ptable.loadPNAMES(pnames); // Read all texture entries to a single list TextureXList tx; for (unsigned a = 0; a < entries.size(); a++) tx.readTEXTUREXData(entries[a], ptable, true); // Convert to extended (TEXTURES) format tx.convertToTEXTURES(); // Create new TEXTURES entry and write to it ArchiveEntry* textures = parent->addNewEntry("TEXTURES", parent->entryIndex(entries[0])); if (textures) { bool ok = tx.writeTEXTURESData(textures); EntryType::detectEntryType(textures); textures->setExtensionByType(); return ok; } else return false; }
/* DatArchive::updateNamespaces * Updates the namespace list *******************************************************************/ void DatArchive::updateNamespaces() { // Clear current namespace info sprites[0] = sprites[1] = flats[0] = flats[1] = walls[0] = walls[1] = -1; // Go through all entries for (unsigned a = 0; a < numEntries(); a++) { ArchiveEntry* entry = getRoot()->getEntry(a); // Check for markers if (!entry->getName().Cmp("startflats")) flats[0] = a; if (!entry->getName().Cmp("endflats")) flats[1] = a; if (!entry->getName().Cmp("startsprites")) sprites[0] = a; if (!entry->getName().Cmp("endmonsters")) sprites[1] = a; if (!entry->getName().Cmp("startwalls")) walls[0] = a; if (!entry->getName().Cmp("endwalls")) walls[1] = a; } }
void csArchive::ReadZipEntries (FILE *infile) { size_t cur_offs, new_offs; char buff[1024]; ZIP_central_directory_file_header cdfh; ZIP_local_file_header lfh; cur_offs = 0; while ((fread (buff, 1, sizeof (hdr_local), infile) >= sizeof (hdr_local)) && (memcmp (buff, hdr_local, sizeof (hdr_local)) == 0) && (ReadLFH (lfh, infile))) { new_offs = cur_offs + sizeof (hdr_local) + ZIP_LOCAL_FILE_HEADER_SIZE + lfh.filename_length + lfh.extra_field_length + lfh.csize; if ((lfh.filename_length > sizeof (buff)) || (fread (buff, 1, lfh.filename_length, infile) < lfh.filename_length)) return; /* Broken zipfile? */ buff[lfh.filename_length] = 0; if ((buff[lfh.filename_length - 1] != '/') && (buff[lfh.filename_length - 1] != PATH_SEPARATOR)) { /* Partialy convert lfh to cdfh */ memset (&cdfh, 0, sizeof (cdfh)); cdfh.version_needed_to_extract[0] = lfh.version_needed_to_extract[0]; cdfh.version_needed_to_extract[1] = lfh.version_needed_to_extract[1]; cdfh.general_purpose_bit_flag = lfh.general_purpose_bit_flag; cdfh.compression_method = lfh.compression_method; cdfh.last_mod_file_time = lfh.last_mod_file_time; cdfh.last_mod_file_date = lfh.last_mod_file_date; cdfh.crc32 = lfh.crc32; cdfh.csize = lfh.csize; cdfh.ucsize = lfh.ucsize; cdfh.relative_offset_local_header = cur_offs; ArchiveEntry *curentry = InsertEntry (buff, cdfh); if (!curentry->ReadExtraField (infile, lfh.extra_field_length)) return; /* Broken zipfile */ } /* endif */ if (fseek (infile, cur_offs = new_offs, SEEK_SET)) return; /* Broken zipfile */ } /* endwhile */ }