void PicoPrintFunc( int level, const char *str ){ if ( str == 0 ) { return; } switch ( level ) { case PICO_NORMAL: globalOutputStream() << str << "\n"; break; case PICO_VERBOSE: //globalOutputStream() << "PICO_VERBOSE: " << str << "\n"; break; case PICO_WARNING: globalWarningStream() << "PICO_WARNING: " << str << "\n"; break; case PICO_ERROR: globalErrorStream() << "PICO_ERROR: " << str << "\n"; break; case PICO_FATAL: globalErrorStream() << "PICO_FATAL: " << str << "\n"; break; } }
const char* misc_model_dialog( GtkWidget* parent ){ StringOutputStream buffer( 1024 ); buffer << g_qeglobals.m_userGamePath.c_str() << "models/"; if ( !file_readable( buffer.c_str() ) ) { // just go to fsmain buffer.clear(); buffer << g_qeglobals.m_userGamePath.c_str() << "/"; } const char *filename = file_dialog( parent, TRUE, "Choose Model", buffer.c_str(), ModelLoader::Name() ); if ( filename != 0 ) { // use VFS to get the correct relative path const char* relative = path_make_relative( filename, GlobalFileSystem().findRoot( filename ) ); if ( relative == filename ) { globalWarningStream() << "WARNING: could not extract the relative path, using full path instead\n"; } return relative; } return 0; }
TextOutputStream& getWarningStream () { return globalWarningStream(); }
Image* LoadIDSPBuff( byte *buffer ){ byte *buf_p; int columns, rows; byte *pixbuf; int row, column; byte *palette; unsigned char red, green, blue, alphabyte; dspriteheader_t *header; dspritev1_t *pinv1; dspritev2_t *pinv2; dspriteframetype_t *pframetype; int version; int numframes; dspriteframe_t *spriteframe; header = (dspriteheader_t *)buffer; if ( header->ident != IDSPRITEHEADER ) { globalWarningStream() << "WARNING: IDSP file has wrong header\n"; return 0; } version = header->version; if ( version != 1 && version != 2 ) { globalWarningStream() << "WARNING: IDSP file has wrong version number " "(" << version << " should be 1 or 2)\n"; return 0; } // initialise variables depending on the sprite version. switch ( version ) { case 1: pinv1 = (dspritev1_t *)( header + 1 ); numframes = pinv1->numframes; columns = pinv1->width; rows = pinv1->height; pframetype = (dspriteframetype_t *)( pinv1 + 1 ); break; case 2: pinv2 = (dspritev2_t *)( header + 1 ); numframes = pinv2->numframes; columns = pinv2->width; rows = pinv2->height; pframetype = (dspriteframetype_t *)( pinv2 + 1 ); break; default: globalWarningStream() << "WARNING: IDSP file has unsupported version\n"; return 0; } if ( numframes > 1 ) { globalWarningStream() << "WARNING: IDSP file has multiple frames, only the first frame will be used.\n"; } // palette = buffer+mipdatasize+2; // buf_p = buffer+lpMip->offsets[0]; RGBAImage* image = new RGBAImage( columns, rows ); #ifdef DEBUG frametype = spriteframetype_t( pframetype->type ); if ( frametype == SPR_SINGLE ) { globalOutputStream() << "Single Frame\n"; } else if ( frametype == SPR_GROUP ) { globalOutputStream() << "Group of Frames\n"; } else { globalWarningStream() << "Bleh!\n"; // <-- we always get this, wtf! } #endif palette = (byte *)( pframetype + 1 ); spriteframe = (dspriteframe_t *)( palette + ( 256 * 3 ) + 4 ); // what are those 4 extra bytes ? what's missing ? buf_p = (byte *)( spriteframe + 1 ); for ( row = 0; row < rows; row++ ) { pixbuf = image->getRGBAPixels() + row * columns * 4; for ( column = 0; column < columns; column++ ) { int palIndex; palIndex = *buf_p++; red = *( palette + ( palIndex * 3 ) ); green = *( palette + ( palIndex * 3 ) + 1 ); blue = *( palette + ( palIndex * 3 ) + 2 ); // HalfLife engine makes pixels that are BLUE transparent. (RGB = 0x0000FF) // So show them that way in the editor. if ( blue == 0xff && red == 0x00 && green == 0x00 ) { alphabyte = 0xff; //FIXME: backwards? (so sprite models to render correctly) blue = 0x00; // don't set the resulting pixel to blue } else { alphabyte = 0x00; //FIXME: backwards? (so sprite models to render correctly) } *pixbuf++ = red; *pixbuf++ = green; *pixbuf++ = blue; *pixbuf++ = alphabyte; } } return image; }
// Parse the provided stream containing the contents of a single .def file. // Extract all entitydefs and create objects accordingly. void EClassManager::parse(TextInputStream& inStr, const std::string& modDir) { // Construct a tokeniser for the stream std::istream is(&inStr); parser::BasicDefTokeniser<std::istream> tokeniser(is); while (tokeniser.hasMoreTokens()) { std::string blockType = tokeniser.nextToken(); boost::algorithm::to_lower(blockType); if (blockType == "entitydef") { // Get the (lowercase) entity name const std::string sName = boost::algorithm::to_lower_copy(tokeniser.nextToken()); // Ensure that an Entity class with this name already exists // When reloading entityDef declarations, most names will already be registered EntityClasses::iterator i = _entityClasses.find(sName); if (i == _entityClasses.end()) { // Not existing yet, allocate a new class Doom3EntityClassPtr entityClass(new eclass::Doom3EntityClass(sName)); std::pair<EntityClasses::iterator, bool> result = _entityClasses.insert( EntityClasses::value_type(sName, entityClass) ); i = result.first; } else { // EntityDef already exists, compare the parse stamp if (i->second->getParseStamp() == _curParseStamp) { globalWarningStream() << "[eclassmgr]: EntityDef " << sName << " redefined" << std::endl; } } // At this point, i is pointing to a valid entityclass i->second->setParseStamp(_curParseStamp); // Parse the contents of the eclass (excluding name) i->second->parseFromTokens(tokeniser); // Set the mod directory i->second->setModName(modDir); } else if (blockType == "model") { // Read the name std::string modelDefName = tokeniser.nextToken(); // Ensure that an Entity class with this name already exists // When reloading entityDef declarations, most names will already be registered Models::iterator i = _models.find(modelDefName); if (i == _models.end()) { // Does not exist yet, allocate a new one // Allocate an empty ModelDef Doom3ModelDefPtr model(new Doom3ModelDef(modelDefName)); std::pair<Models::iterator, bool> result = _models.insert( Models::value_type(modelDefName, model) ); i = result.first; } else { // Model already exists, compare the parse stamp if (i->second->getParseStamp() == _curParseStamp) { globalWarningStream() << "[eclassmgr]: Model " << modelDefName << " redefined" << std::endl; } } // Model structure is allocated and in the map, // invoke the parser routine i->second->setParseStamp(_curParseStamp); i->second->parseFromTokens(tokeniser); i->second->setModName(modDir); } } }
void Doom3EntityClass::parseFromTokens(parser::DefTokeniser& tokeniser) { // Clear this structure first, we might be "refreshing" ourselves from tokens clear(); // Required open brace (the name has already been parsed by the EClassManager) tokeniser.assertNextToken("{"); // Loop over all of the keys in this entitydef while (true) { const std::string key = tokeniser.nextToken(); if (key == "}") { break; // end of def } const std::string value = tokeniser.nextToken(); // Otherwise, switch on the key name if (key == "model") { setModelPath(os::standardPath(value)); } else if (key == "editor_color") { setColour(value); } else if (key == "editor_light") { if (value == "1") { setIsLight(true); } } else if (key == "spawnclass") { if (value == "idLight") { setIsLight(true); } } else if (boost::algorithm::istarts_with(key, "editor_")) { // "editor_yyy" represents an attribute that may be set on this // entity. Construct a value-less EntityClassAttribute to add to // the class, so that it will show in the entity inspector. // Locate the space in "editor_bool myVariable", starting after "editor_" std::size_t spacePos = key.find(' ', 7); // Only proceed if we have a space (some keys like "editor_displayFolder" don't have spaces) if (spacePos != std::string::npos) { // The part beyond the space is the name of the attribute std::string attName = key.substr(spacePos + 1); // Get the type by trimming the string left and right std::string type = key.substr(7, key.length() - attName.length() - 8); // Ignore editor_setKeyValue if (!attName.empty() && type != "setKeyValue") { // Transform the type into a better format if (type == "var" || type == "string") { type = "text"; } addAttribute(EntityClassAttribute(type, attName, "", value)); } } } // Following key-specific processing, add the keyvalue to the eclass EntityClassAttribute attribute("text", key, value, ""); if (getAttribute(key).type.empty()) { // Type is empty, attribute does not exist, add it. addAttribute(attribute); } else if (getAttribute(key).value.empty() ) { // Attribute type is set, but value is empty, set the value. getAttribute(key).value = value; } else { // Both type and value are not empty, emit a warning globalWarningStream() << "[eclassmgr] attribute " << key << " already set on entityclass " << _name << std::endl; } } // while true // Notify the observers for (Observers::const_iterator i = _observers.begin(); i != _observers.end(); ++i) { (*i)->OnEClassReload(); } }
// Resolve inheritance for this class void Doom3EntityClass::resolveInheritance(EntityClasses& classmap) { // If we have already resolved inheritance, do nothing if (_inheritanceResolved) return; // Lookup the parent name and return if it is not set. Also return if the // parent name is the same as our own classname, to avoid infinite // recursion. std::string parName = getAttribute("inherit").value; if (parName.empty() || parName == _name) return; // Find the parent entity class EntityClasses::iterator pIter = classmap.find(parName); if (pIter != classmap.end()) { // Recursively resolve inheritance of parent pIter->second->resolveInheritance(classmap); // Copy attributes from the parent to the child, including editor keys AttributeCopyingVisitor visitor(*this); pIter->second->forEachClassAttribute(visitor, true); } else { globalWarningStream() << "[eclassmgr] Entity class " << _name << " specifies parent " << parName << " which is not found." << std::endl; } // Set the resolved flag _inheritanceResolved = true; // Construct the inheritance list buildInheritanceChain(); if (getAttribute("model").value != "") { // We have a model path (probably an inherited one) setModelPath(getAttribute("model").value); } if (getAttribute("editor_light").value == "1" || getAttribute("spawnclass").value == "idLight") { // We have a light setIsLight(true); } if (getAttribute("editor_transparent").value == "1") { _colourTransparent = true; } // (Re)set the colour const EntityClassAttribute& colourAttr = getAttribute("editor_color"); if (!colourAttr.value.empty()) { setColour(Vector3(colourAttr.value)); } // Update the colour shader captureColour(); }