/* TextureXList::readTEXTURESData * Reads in a ZDoom-format TEXTURES entry. Returns true on success, * false otherwise *******************************************************************/ bool TextureXList::readTEXTURESData(ArchiveEntry* entry) { // Check for empty entry if (!entry) { Global::error = "Attempt to read texture data from NULL entry"; return false; } if (entry->getSize() == 0) { txformat = TXF_TEXTURES; return true; } // Get text to parse Tokenizer tz; tz.openMem(&(entry->getMCData()), entry->getName()); // Parsing gogo string token = tz.getToken(); while (!token.IsEmpty()) { // Texture definition if (S_CMPNOCASE(token, "Texture")) { CTexture* tex = new CTexture(); if (tex->parse(tz, "Texture")) addTexture(tex); } // Sprite definition if (S_CMPNOCASE(token, "Sprite")) { CTexture* tex = new CTexture(); if (tex->parse(tz, "Sprite")) addTexture(tex); } // Graphic definition if (S_CMPNOCASE(token, "Graphic")) { CTexture* tex = new CTexture(); if (tex->parse(tz, "Graphic")) addTexture(tex); } // WallTexture definition if (S_CMPNOCASE(token, "WallTexture")) { CTexture* tex = new CTexture(); if (tex->parse(tz, "WallTexture")) addTexture(tex); } // Flat definition if (S_CMPNOCASE(token, "Flat")) { CTexture* tex = new CTexture(); if (tex->parse(tz, "Flat")) addTexture(tex); } token = tz.getToken(); } txformat = TXF_TEXTURES; return true; }
/* StyleSet::getStyle * Returns the text style associated with [name] (these are hard * coded), or NULL if [name] was invalid *******************************************************************/ TextStyle* StyleSet::getStyle(string name) { // Return style matching name given if (S_CMPNOCASE(name, "default")) return &ts_default; else if (S_CMPNOCASE(name, "preprocessor")) return &ts_preprocessor; else if (S_CMPNOCASE(name, "comment")) return &ts_comment; else if (S_CMPNOCASE(name, "string")) return &ts_string; else if (S_CMPNOCASE(name, "character")) return &ts_character; else if (S_CMPNOCASE(name, "keyword")) return &ts_keyword; else if (S_CMPNOCASE(name, "constant")) return &ts_constant; else if (S_CMPNOCASE(name, "function")) return &ts_function; else if (S_CMPNOCASE(name, "bracematch")) return &ts_bracematch; else if (S_CMPNOCASE(name, "bracebad")) return &ts_bracebad; // Not a valid style return NULL; }
/* DatArchive::addEntry * Adds [entry] to the end of the namespace matching [add_namespace]. * If [copy] is true a copy of the entry is added. Returns the added * entry or NULL if the entry is invalid *******************************************************************/ ArchiveEntry* DatArchive::addEntry(ArchiveEntry* entry, string add_namespace, bool copy) { // Find requested namespace, only three non-global namespaces are valid in this format if (S_CMPNOCASE(add_namespace, "textures")) { if (walls[1] >= 0) return addEntry(entry, walls[1], NULL, copy); else { addNewEntry("startwalls"); addNewEntry("endwalls"); return addEntry(entry, add_namespace, copy); } } else if (S_CMPNOCASE(add_namespace, "flats")) { if (flats[1] >= 0) return addEntry(entry, flats[1], NULL, copy); else { addNewEntry("startflats"); addNewEntry("endflats"); return addEntry(entry, add_namespace, copy); } } else if (S_CMPNOCASE(add_namespace, "sprites")) { if (sprites[1] >= 0) return addEntry(entry, sprites[1], NULL, copy); else { addNewEntry("startsprites"); addNewEntry("endmonsters"); return addEntry(entry, add_namespace, copy); } } else return addEntry(entry, 0xFFFFFFFF, NULL, copy); }
/* 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]; }
/* 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); }
/* ScriptEditorPanel::ScriptEditorPanel * ScriptEditorPanel class constructor *******************************************************************/ ScriptEditorPanel::ScriptEditorPanel(wxWindow* parent) : wxPanel(parent, -1) { // Init variables entry_script = new ArchiveEntry(); entry_compiled = new ArchiveEntry(); // Setup sizer wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL); SetSizer(sizer); // Toolbar SToolBar* toolbar = new SToolBar(this); sizer->Add(toolbar, 0, wxEXPAND); wxArrayString actions; actions.Add("mapw_script_save"); actions.Add("mapw_script_compile"); actions.Add("mapw_script_jumpto"); actions.Add("mapw_script_togglelanguage"); toolbar->addActionGroup("Scripts", actions); // Add text editor wxBoxSizer* hbox = new wxBoxSizer(wxHORIZONTAL); sizer->Add(hbox, 1, wxEXPAND); text_editor = new TextEditor(this, -1); hbox->Add(text_editor, 1, wxEXPAND|wxALL, 4); // Set language string lang = theGameConfiguration->scriptLanguage(); if (S_CMPNOCASE(lang, "acs_hexen")) { text_editor->setLanguage(TextLanguage::getLanguage("acs")); entry_script->setName("SCRIPTS"); entry_compiled->setName("BEHAVIOR"); } else if (S_CMPNOCASE(lang, "acs_zdoom")) { text_editor->setLanguage(TextLanguage::getLanguage("acs_z")); entry_script->setName("SCRIPTS"); entry_compiled->setName("BEHAVIOR"); } // Add function/constants list list_words = new wxTreeListCtrl(this, -1); list_words->SetInitialSize(wxSize(200, -10)); hbox->Add(list_words, 0, wxEXPAND|wxALL, 4); populateWordList(); list_words->Show(script_show_language_list); // Bind events list_words->Bind(wxEVT_TREELIST_ITEM_ACTIVATED, &ScriptEditorPanel::onWordListActivate, this); }
/* Tokenizer::getBool * Reads a token and writes its boolean value to [b], same rules as * getBool above *******************************************************************/ void Tokenizer::getBool(bool* b) { // Read token readToken(); // If the token is a string "no" or "false", the value is false if (S_CMPNOCASE(token_current, "no") || S_CMPNOCASE(token_current, "false")) *b = false; else *b = !!atoi(CHR(token_current)); }
/* Tokenizer::getBool * Reads a token and returns its boolean value, anything except * "0", "no", or "false" will return true *******************************************************************/ bool Tokenizer::getBool() { // Read token readToken(); // If the token is a string "no" or "false", the value is false if (S_CMPNOCASE(token_current, "no") || S_CMPNOCASE(token_current, "false")) return false; // Returns true ("1") or false ("0") return !!atoi(CHR(token_current)); }
/* SAction::initActions * Loads and parses all SActions configured in actions.cfg in the * program resource archive *******************************************************************/ bool SAction::initActions() { // Get actions.cfg from slade.pk3 auto cfg_entry = theArchiveManager->programResourceArchive()->entryAtPath("actions.cfg"); if (!cfg_entry) return false; Parser parser(cfg_entry->getParentDir()); if (parser.parseText(cfg_entry->getMCData(), "actions.cfg")) { auto root = parser.parseTreeRoot(); for (unsigned a = 0; a < root->nChildren(); a++) { auto node = root->getChildPTN(a); // Single action if (S_CMPNOCASE(node->type(), "action")) { auto action = new SAction(node->getName(), node->getName()); if (action->parse(node)) actions.push_back(action); else delete action; } // Group of actions else if (S_CMPNOCASE(node->getName(), "group")) { int group = newGroup(); for (unsigned b = 0; b < node->nChildren(); b++) { auto group_node = node->getChildPTN(b); if (S_CMPNOCASE(group_node->type(), "action")) { auto action = new SAction(group_node->getName(), group_node->getName()); if (action->parse(group_node)) { action->group = group; actions.push_back(action); } else delete action; } } } } } return true; }
/* CTexture::loadPatchImage * Loads the image for the patch at [pindex] into [image]. Can deal * with textures-as-patches *******************************************************************/ bool CTexture::loadPatchImage(unsigned pindex, SImage& image, Archive* parent, Palette8bit* pal) { // Check patch index if (pindex >= patches.size()) return false; CTPatch* patch = patches[pindex]; // If the texture is extended, search for textures-as-patches first // (as long as the patch name is different from this texture's name) if (extended && !(S_CMPNOCASE(patch->getName(), name))) { // Search the texture list we're in first if (in_list) { for (unsigned a = 0; a < in_list->nTextures(); a++) { CTexture* tex = in_list->getTexture(a); // Don't look past this texture in the list if (tex->getName() == name) break; // Check for name match if (S_CMPNOCASE(tex->getName(), patch->getName())) { // Load texture to image return tex->toImage(image, parent, pal); } } } // Otherwise, try the resource manager // TODO: Something has to be ignored here. The entire archive or just the current list? CTexture* tex = theResourceManager->getTexture(patch->getName(), parent); if (tex) return tex->toImage(image, parent, pal); } // Get patch entry ArchiveEntry* entry = patch->getPatchEntry(parent); // Load entry to image if valid if (entry) return Misc::loadImageFromEntry(&image, entry); else return false; }
/* Archive::renameDir * Renames [dir] to [new_name]. Returns false if [dir] isn't part of * the archive, true otherwise *******************************************************************/ bool Archive::renameDir(ArchiveTreeNode* dir, string new_name) { // Abort if read only if (read_only) return false; // Check the directory is part of this archive if (dir->getArchive() != this) return false; // Rename the directory if needed if (!(S_CMPNOCASE(dir->getName(), new_name))) { if (UndoRedo::currentlyRecording()) UndoRedo::currentManager()->recordUndoStep(new DirRenameUS(dir, new_name)); dir->setName(new_name); dir->getDirEntry()->setState(1); } else return true; // Announce MemChunk mc; wxUIntPtr ptr = wxPtrToUInt(dir); mc.write(&ptr, sizeof(wxUIntPtr)); announce("directory_modified", mc); // Update variables etc setModified(true); return true; }
bool Tokenizer::checkNextNC(const char* check) const { if (!token_next_.valid) return false; return S_CMPNOCASE(token_next_.text, check); }
/* WadArchive::addEntry * Adds [entry] to the end of the namespace matching [add_namespace]. * If [copy] is true a copy of the entry is added. Returns the added * entry or NULL if the entry is invalid *******************************************************************/ ArchiveEntry* WadArchive::addEntry(ArchiveEntry* entry, string add_namespace, bool copy) { // Find requested namespace for (unsigned a = 0; a < namespaces.size(); a++) { if (S_CMPNOCASE(namespaces[a].name, add_namespace)) { // Namespace found, add entry before end marker return addEntry(entry, namespaces[a].end_index++, NULL, copy); } } // If the requested namespace is a special namespace and doesn't exist, create it for (int a = 0; a < n_special_namespaces; a++) { if (add_namespace == special_namespaces[a].name) { addNewEntry(special_namespaces[a].letter + "_start"); addNewEntry(special_namespaces[a].letter + "_end"); return addEntry(entry, add_namespace, copy); } } // Unsupported namespace not found, so add to global namespace (ie end of archive) return addEntry(entry, 0xFFFFFFFF, NULL, copy); }
SBrush * SBrushManager::get(string name) { for (size_t i = 0; i < brushes.size(); ++i) if (S_CMPNOCASE(name, brushes[i]->getName())) return brushes[i]; return nullptr; }
// ----------------------------------------------------------------------------- // Get a brush from its name // ----------------------------------------------------------------------------- SBrush* SBrush::get(const wxString& name) { for (auto& brush : brushes) if (S_CMPNOCASE(name, brush->name())) return brush.get(); return nullptr; }
bool Tokenizer::checkOrEndNC(const char* check) const { // At end, return true if (!token_next_.valid) return true; return S_CMPNOCASE(token_current_.text, check); }
// ----------------------------------------------------------------------------- // Returns true if [word] is a ZScript keyword // ----------------------------------------------------------------------------- bool isKeyword(const string& word) { for (auto& kw : keywords) if (S_CMPNOCASE(word, kw)) return true; return false; }
bool TLFunction::hasContext(const string& name) { for (auto& c : contexts_) if (S_CMPNOCASE(c.context, name)) return true; return false; }
// ----------------------------------------------------------------------------- // Loads an entry into the panel as text // ----------------------------------------------------------------------------- bool TextEntryPanel::loadEntry(ArchiveEntry* entry) { // Load entry into the text editor if (!text_area_->loadEntry(entry)) return false; // Scroll to previous position (if any) if (entry->exProps().propertyExists("TextPosition")) text_area_->GotoPos((int)(entry->exProp("TextPosition"))); // --- Attempt to determine text language --- TextLanguage* tl = nullptr; // Level markers use FraggleScript if (entry->getType() == EntryType::mapMarkerType()) tl = TextLanguage::fromId("fragglescript"); // From entry language hint if (entry->exProps().propertyExists("TextLanguage")) { string lang_id = entry->exProp("TextLanguage"); tl = TextLanguage::fromId(lang_id); } // Or, from entry type if (!tl && entry->getType()->extraProps().propertyExists("text_language")) { string lang_id = entry->getType()->extraProps()["text_language"]; tl = TextLanguage::fromId(lang_id); } // Load language text_area_->setLanguage(tl); // Select it in the choice box if (tl) { for (auto a = 0u; a < choice_text_language_->GetCount(); ++a) { if (S_CMPNOCASE(tl->name(), choice_text_language_->GetString(a))) { choice_text_language_->Select(a); break; } } } else choice_text_language_->Select(0); // Prevent undoing loading the entry text_area_->EmptyUndoBuffer(); // Update variables this->entry_ = entry; setModified(false); return true; }
/* BrowserWindow::selectItem * Finds the item matching [name] in the tree, starting from [node]. * If the item is found, its parent node is opened in the browser * and the item is selected *******************************************************************/ bool BrowserWindow::selectItem(string name, BrowserTreeNode* node) { // Check node was given, if not start from root if (!node) node = items_root; // Check global items for (unsigned a = 0; a < items_global.size(); a++) { if (S_CMPNOCASE(name, items_global[a]->getName())) { openTree(node); canvas->selectItem(items_global[a]); canvas->showSelectedItem(); return true; } } // Go through all items in this node for (unsigned a = 0; a < node->nItems(); a++) { // Check for name match (not case-sensitive) if (S_CMPNOCASE(node->getItem(a)->getName(), name)) { // Open this node in the browser and select the item openTree(node); canvas->selectItem(node->getItem(a)); canvas->showSelectedItem(); tree_items->Select(node->getTreeId()); tree_items->Expand(node->getTreeId()); return true; } } // Item not found in this one, try its child nodes for (unsigned a = 0; a < node->nChildren(); a++) { if (selectItem(name, (BrowserTreeNode*)node->getChild(a))) return true; } // Item not found return false; }
bool Tokenizer::advIfNC(const string& check, size_t inc) { if (S_CMPNOCASE(token_current_.text, check)) { adv(inc); return true; } return false; }
/* TextureXList::getTexture * Returns the texture matching [name], or the 'invalid' texture if * no match is found *******************************************************************/ CTexture* TextureXList::getTexture(string name) { // Search for texture by name for (size_t a = 0; a < textures.size(); a++) { if (S_CMPNOCASE(textures[a]->getName(), name)) return textures[a]; } // Not found return &tex_invalid; }
/* StyleSet::getStyle * Returns the text style associated with [name] (these are hard * coded), or NULL if [name] was invalid *******************************************************************/ TextStyle* StyleSet::getStyle(string name) { // Return style matching name given if (S_CMPNOCASE(name, "default")) return &ts_default; else if (S_CMPNOCASE(name, "selection")) return &ts_selection; else { for (unsigned a = 0; a < styles.size(); a++) { if (styles[a]->name == name) return styles[a]; } } // Not a valid style return NULL; }
/* SAction::fromId * Returns the SAction with id matching [id] *******************************************************************/ SAction* SAction::fromId(const string& id) { // Find action with id for (auto& action : actions) if (S_CMPNOCASE(action->id, id)) return action; // Not found return invalidAction(); }
/* Parser::defined * Returns true if [def] is in the defines list *******************************************************************/ bool Parser::defined(string def) { for (unsigned a = 0; a < defines.size(); a++) { if (S_CMPNOCASE(defines[a], def)) return true; } return false; }
void TextureXEditor::setSelection(ArchiveEntry* entry) const { for (size_t a = 0; a < tabs_->GetPageCount(); a++) { if (S_CMPNOCASE(tabs_->GetPage(a)->GetName(), "pnames") && (entry == pnames_)) { tabs_->SetSelection(a); return; } else if (S_CMPNOCASE(tabs_->GetPage(a)->GetName(), "textures")) { auto txp = dynamic_cast<TextureXPanel*>(tabs_->GetPage(a)); if (txp->txEntry() == entry) { tabs_->SetSelection(a); return; } } } }
/* Tokenizer::getTokensUntil * Reads tokens into [tokens] until either [end] token is found, or * the end of the data is reached *******************************************************************/ void Tokenizer::getTokensUntil(vector<string>& tokens, string end) { while (1) { readToken(); if (token_current.IsEmpty() && !qstring) break; if (S_CMPNOCASE(token_current, end)) break; tokens.push_back(token_current); } }
/* TextureXList::textureIndex * Returns the index of the texture matching [name], or -1 if no * match was found *******************************************************************/ int TextureXList::textureIndex(string name) { // Search for texture by name for (unsigned a = 0; a < textures.size(); a++) { if (S_CMPNOCASE(textures[a]->getName(), name)) { textures[a]->index = a; return a; } } // Not found return -1; }
/* TextureClipboardItem::getPatchEntry * Returns the entry copy for the patch at [index] in the texture *******************************************************************/ ArchiveEntry* TextureClipboardItem::getPatchEntry(string patch) { // Find copied patch entry with matching name for (unsigned a = 0; a < patch_entries.size(); a++) { if (S_CMPNOCASE(patch_entries[a]->getName(true).Truncate(8), patch)) return patch_entries[a]; } // Not found return NULL; }
// ---------------------------------------------------------------------------- // TextLanguage::getLanguageByName // // Returns the language definition matching [name], or NULL if no match found // ---------------------------------------------------------------------------- TextLanguage* TextLanguage::fromName(string name) { // Find text language matching [name] for (unsigned a = 0; a < text_languages.size(); a++) { if (S_CMPNOCASE(text_languages[a]->name_, name)) return text_languages[a]; } // Not found return nullptr; }