bool GLProgram::link() { glLinkProgram(m_program); glValidateProgram(m_program); GLint status; glGetProgramiv(m_program, GL_LINK_STATUS, &status); if (status == GL_FALSE) { FZLOGERROR("GLProgram: Error linking program: %i.", m_program); FZLOGERROR("%s", getProgramLog().c_str()); fzGLDeleteProgram( m_program ); m_program = 0; return false; } char uniformName[256]; GLint nuUniforms = 0; glGetProgramiv(m_program, GL_ACTIVE_UNIFORMS, &nuUniforms); for(fzInt index = 0; index < nuUniforms; ++index) { glGetActiveUniform(m_program, index, 256, NULL, NULL, NULL, uniformName); m_uniforms.insert(uniformsPair(fzHash(uniformName), glGetUniformLocation(m_program, uniformName))); } CHECK_GL_ERROR_DEBUG(); setUniform1i("u_texture", 0); return true; }
GLint GLProgram::getUniform(const char* uniform) const { uniformsMap::const_iterator it(m_uniforms.find(fzHash(uniform))); if(it == m_uniforms.end()) return -1; return it->second; }
fzSpriteFrame SpriteFrameCache::getSpriteFrameByKey(const char* key) const { fzSpriteFrame frame = getSpriteFrameByHash(fzHash(key)); if(!frame.isValid()) { FZLOGERROR("SpriteFrameCache: The fzSpriteFrame was not found for the key \"%s\".", key); } return frame; }
Animation* AnimationCache::getAnimationByName(const char* name) const { FZ_ASSERT(name != NULL, "Name argument must be non-NULL."); animationMap::const_iterator it(m_animations.find(fzHash(name))); if(it == m_animations.end()) return NULL; return it->second; }
void DataStore::setData(const fzBuffer& data, const char *key) { fzStoreEntry entry; entry.key = fzStrcpy(key); entry.hash = fzHash(key); entry.type = kFZData_data; entry.data = data; setEntry(entry); }
void DataStore::setInteger(int32_t value, const char *key) { fzStoreEntry entry; entry.key = fzStrcpy(key); entry.hash = fzHash(key); entry.type = kFZData_integer; entry.integerValue = value; setEntry(entry); }
void DataStore::setString(const char* value, const char *key) { fzStoreEntry entry; entry.key = fzStrcpy(key); entry.hash = fzHash(key); entry.type = kFZData_string; entry.data = fzBuffer(fzStrcpy(value), strlen(value)+1); setEntry(entry); }
void FontCache::removeFontByName(const char* filename) { FZ_ASSERT(filename, "Filename can not be NULL."); uint32_t hash = fzHash(filename); Font *font = getFontForHash(hash); if(font) { m_fonts.erase(hash); font->release(); } }
void DataStore::setFloat(double value, const char *key) { fzStoreEntry entry; entry.key = fzStrcpy(key); entry.hash = fzHash(key); entry.type = kFZData_float; entry.floatValue = value; setEntry(entry); }
Font* FontCache::addFont(const char* filename, fzFloat lineHeight) { FZ_ASSERT(filename != NULL, "Filename argument must be non-NULL."); // Make string mutable char *filenameCpy = fzStrcpy(filename); // Remove "-x" suffix IO::removeFileSuffix(filenameCpy); uint32_t hash = fzHash(filenameCpy); Font *font = getFontForHash(hash); if(font != NULL && strcmp(IO::getExtension(filenameCpy), "ttf") == 0) { // Rewritting FZ_ASSERT(lineHeight > 0, "Line height must me positive."); FZLog("NOT IMPLEMENTED"); } if(font == NULL) { try { font = new Font(filenameCpy, lineHeight); font->retain(); m_fonts.insert(fontsPair(hash, font)); } catch(std::exception& error) { delete filenameCpy; FZLOGERROR("%s", error.what()); return NULL; } } delete filenameCpy; return font; }
void SpriteFrameCache::removeSpriteFramesFromFile(const char* plist) { fzUInt factor; fzBuffer data = ResourcesManager::Instance().loadResource(plist, &factor); if(data.isEmpty()) return; xml_document<> doc; doc.parse<parse_fastest>(data.getPointer()); xml_node<> *rootNode, *frameNode; // Parse frames rootNode = doc.first_node("frames"); if(rootNode == NULL) { FZLOGERROR("SpriteFrameCache: <frames> tag wasn't found."); data.free(); return; } for(frameNode = rootNode->first_node(); frameNode; frameNode = frameNode->next_sibling()) { FZ_ASSERT(strncmp(frameNode->name(), "node", frameNode->name_size()) == 0, "XML tag is not \"node\"."); // NAME xml_attribute<> *attribute = frameNode->first_attribute("name"); if(attribute == NULL) { FZ_ASSERT(false, "SpriteFrameCache: <node name> attribute wasn't found."); continue; } m_frames.erase(fzHash(attribute->value(), attribute->value_size())); } data.free(); }
uint32_t fzHash(const char *str) { return fzHash(str, strlen(str)); }
DataStore::fzStoreEntry* DataStore::entryForKey(const char *key) const { return entryForHash(fzHash(key)); }
void DataStore::readFromMemory() { FZ_ASSERT(p_path, "Path cannot be NULL."); if(m_dirty) return; fzBuffer buffer = IO::loadFile(p_path); if(!buffer.isEmpty()) { xml_document<> doc; doc.parse<parse_fastest | parse_validate_closing_tags>(buffer.getPointer()); xml_node<> *node = doc.first_node(); if(strncmp(node->name(), XML_SIZE_TAG, node->name_size()) != 0) FZ_RAISE("DataStore: XML is corrupted."); // RESERVE CAPACITY reserveCapacity(atoi(node->value())+1); // ITERATE XML m_num = 0; node = node->next_sibling(); for(; node; node = node->next_sibling()) { if(strncmp(node->name(), XML_ENTRY_TAG, node->name_size()) != 0) { FZLOGERROR("DataStore: XML entry is corrupted."); continue; } fzStoreEntry &entry = p_store[m_num]; // KEY xml_attribute<> *attribute = node->first_attribute(XML_KEY_ATTRIBUTE); if(attribute == NULL) { FZLOGERROR("DataStore: Key attribute is missing."); continue; } entry.key = fzStrcpy(attribute->value(), attribute->value_size()); entry.hash = fzHash(attribute->value(), attribute->value_size()); // ENTRY TYPE attribute = node->last_attribute(XML_TYPE_ATTRIBUTE); if(attribute == NULL) { FZLOGERROR("DataStore: Type attribute is missing."); continue; } int type = atoi(attribute->value()); // DATA const char *data = node->value(); if(data) { switch (type) { case kFZData_string: case kFZData_data: { fzBuffer decoded = Data::B64Decode(data, node->value_size()); entry.data = decoded; break; } case kFZData_integer: entry.integerValue = atoi(data); break; case kFZData_float: entry.floatValue = atof(data); break; default: FZ_RAISE("DataStore: Entry type is invalid."); break; } } entry.type = static_cast<unsigned char>(type); ++m_num; } buffer.free(); FZ_ASSERT(m_num <= m_capacity, "Memory overflow."); } }
Font* FontCache::getFontByName(const char* filename) const { FZ_ASSERT(filename, "Filename can not be NULL."); return getFontForHash(fzHash(filename)); }
void Font::loadFNTData(char* data) { if(data == NULL) FZ_RAISE("Font:FNT: Imposible to load FNT data. Pointer is NULL."); int line = 1; char word[30]; bool parsedCommon = false; bool parsedPage = false; while(*data != '\0') { firstWord(data, word); switch(fzHash(word)) { case "common"_hash: { int nuPages = 0; int nu_arg = sscanf(data, "common lineHeight=%f base=%*d scaleW=%*d scaleH=%*d pages=%d", &m_lineHeight, &nuPages); if(nu_arg != 2) FZ_RAISE_STOP("Font:FNT: Line 2. Sintax error. Error parsing FNT common data."); if(nuPages != 1) FZ_RAISE_STOP("Font:FNT: Line 2. Number of pages must be 1."); if(m_lineHeight == 0) FZ_RAISE_STOP("Font:FNT: Line 2. Line height parsing error."); m_lineHeight /= m_factor; parsedCommon = true; break; } case "page"_hash: { char filename[256]; int nu_arg = sscanf(data, "page id=%*d file=\"%s\"", filename); if(nu_arg != 1) FZ_RAISE_STOP("Font:FNT: Line 3. Sintax erro. Error parsing FNT page data."); if(filename[0] == '\0') FZ_RAISE_STOP("Font:FNT: Line 3. texture's path is missing."); filename[strlen(filename)-1] = '\0'; // remove last " p_texture = TextureCache::Instance().addImage(filename); if(p_texture == NULL) FZ_RAISE("Font:FNT: Font's texture is missing."); p_texture->retain(); parsedPage = true; break; } case "char"_hash: { // CHAR DATA PARSING int charID = 0; fzCharDef temp_char; int nu_arg = sscanf(data, "char id=%d x=%f y=%f width=%f height=%f xoffset=%f yoffset=%f xadvance=%f", &charID, &temp_char.x, &temp_char.y, &temp_char.width, &temp_char.height, &temp_char.xOffset, &temp_char.yOffset, &temp_char.xAdvance); temp_char.x /= m_factor; temp_char.y /= m_factor; temp_char.width /= m_factor; temp_char.height /= m_factor; temp_char.xOffset /= m_factor; temp_char.yOffset /= m_factor; temp_char.xAdvance /= m_factor; if(nu_arg != 8) { FZLOGERROR("Font:FNT: Line %d. Error parsing FNT char data, syntax is not correct.", line); break; } if(charID >= 256) { FZLOGERROR("Font:FNT: Line %d. CharID is out of bounds [0, 255].", line); break; } m_chars[charID] = temp_char; break; } case "kerning"_hash: { // KERNING DATA PARSING int first = 0; int second = 0; fzFloat amount = 0; int nu_arg = sscanf(data, "kerning first=%d second=%d amount=%f", &first, &second, &amount); if(first < 0 || second < 0 || first > 255 || second > 255) { FZLOGERROR("Font:FNT: Line %d. Invalid indexes.", line); break; } if(nu_arg != 3) { FZLOGERROR("Font:FNT: Line %d. Error parsing FNT kerning data.", line); break; } uint16_t key = generateKey((uint8_t)first, (uint8_t)second); m_kerning.insert(pair<uint16_t, fzFloat>(key, amount)); break; } } while(true) { if(*data != '\0') { if(*(data++) == '\n'){ ++line; break; } } } } if(!parsedCommon) FZ_RAISE_STOP("Font:FNT: FNT common data not found."); if(!parsedPage) FZ_RAISE_STOP("Font:FNT: FNT page data not found."); }
void SpriteFrameCache::addSpriteFrame(const fzSpriteFrame& frame, const char* name) { m_frames.insert(framesPair(fzHash(name), frame)); }
void SpriteFrameCache::removeSpriteFrameByName(const char* name) { m_frames.erase(fzHash(name)); }
void AnimationCache::removeAnimationByName(const char* name) { FZ_ASSERT(name != NULL, "Name argument must be non-NULL."); m_animations.erase(fzHash(name)); }
void AnimationCache::addAnimation(Animation *animation, const char* name) { m_animations.insert(animationPair(fzHash(name), animation)); }
void SpriteFrameCache::addSpriteFrames(const char* coordsFilename, Texture2D *texture) { fzUInt factor; fzBuffer data = ResourcesManager::Instance().loadResource(coordsFilename, &factor); if(data.isEmpty()) return; xml_document<> doc; try { doc.parse<parse_fastest | parse_validate_closing_tags>(data.getPointer()); } catch(std::exception &error) { data.free(); FZLOGERROR("SpriteFrameCache: Error parsing \"%s\". rapidXML exception: %s", coordsFilename, error.what()); return; } xml_node<> *rootNode, *subNode, *node; rootNode = doc.first_node("metadata"); if(texture == NULL) { subNode = rootNode->first_node("textureFileName"); if(subNode) { char *filename = fzStrcpy(subNode->value(), subNode->value_size()); texture = TextureCache::Instance().addImage(filename); delete filename; } } // Parse metadata if(texture == NULL) { data.free(); FZLOGERROR("SpriteFrameCache: Error parsing \"%s\". Error pTexture could not be loaded.", coordsFilename); return; } // Parse frames rootNode = doc.first_node("frames"); if(rootNode == NULL) { data.free(); FZLOGERROR("SpriteFrameCache: Error parsing \"%s\". <frames> tag wasn't found.", coordsFilename); return; } for(subNode = rootNode->first_node(); subNode; subNode = subNode->next_sibling()) { if(strncmp(subNode->name(), "frame", subNode->name_size()) != 0) { FZLOGERROR("SpriteFrameCache: Error parsing \"%s\". XML format is not correct.", coordsFilename); continue; } fzRect rect; fzPoint offset = FZPointZero; fzSize originalSize = FZSizeZero; bool rotated = false; // NAME xml_attribute<> *attribute = subNode->first_attribute("name"); if(attribute == NULL) { FZLOGERROR("SpriteFrameCache: Error parsing \"%s\". <node name> attribute wasn't found.", coordsFilename); continue; } uint32_t hash = fzHash(attribute->value(), attribute->value_size()); if(getSpriteFrameByHash(hash).isValid()) continue; // ORIGIN node = subNode->first_node("p"); if(node == NULL) { FZLOGERROR("SpriteFrameCache: Error parsing \"%s\". <p> tag wasn't found.", coordsFilename); continue; } attribute = node->first_attribute("x"); if(attribute == NULL) { FZLOGERROR("SpriteFrameCache: Error parsing \"%s\". <p x> attribute wasn't found.", coordsFilename); continue; } rect.origin.x = atof(attribute->value()) / factor; attribute = node->first_attribute("y"); if(attribute == NULL) { FZLOGERROR("SpriteFrameCache: Error parsing \"%s\". <p y> attribute wasn't found.", coordsFilename); continue; } rect.origin.y = atof(attribute->value()) / factor; // SIZE node = subNode->first_node("s"); if(node == NULL) { FZLOGERROR("SpriteFrameCache: Error parsing \"%s\". <s> tag wasn't found.", coordsFilename); continue; } attribute = node->first_attribute("x"); if(attribute == NULL) { FZLOGERROR("SpriteFrameCache: Error parsing \"%s\". <s x> attribute wasn't found.", coordsFilename); continue; } rect.size.width = atof(attribute->value()) / factor; attribute = node->first_attribute("y"); if(attribute == NULL) { FZLOGERROR("SpriteFrameCache: Error parsing \"%s\". <s y> attribute wasn't found.", coordsFilename); continue; } rect.size.height = atof(attribute->value()) / factor; // OFFSET POSITION node = subNode->first_node("o"); if(node) { attribute = node->first_attribute("x"); if(attribute) offset.x = atof(attribute->value()) / factor; attribute = node->first_attribute("y"); if(attribute) offset.y = atof(attribute->value()) / factor; } // UNTRIMMED SIZE (ORIGINAL) node = subNode->first_node("u"); if(node) { attribute = node->first_attribute("x"); if(attribute) originalSize.width = atof(attribute->value()) / factor; attribute = node->first_attribute("y"); if(attribute) originalSize.height = atof(attribute->value()) / factor; } // IS ROTATED node = subNode->last_node("r"); if(node) { attribute = node->first_attribute("x"); if(attribute) rotated = atoi(attribute->value()); } if(originalSize == FZSizeZero) originalSize = rect.size; // create frame fzSpriteFrame spriteFrame(texture, rect, offset, originalSize, rotated); m_frames.insert(framesPair(hash, spriteFrame)); } data.free(); }