void Font::loadTTFData(char* data, fzFloat fontHeight) { if(data == NULL) FZ_RAISE("Font:TTF: Imposible to load TTF data. Pointer is NULL."); FZ_RAISE_STOP("Font:TTF: TTF NOT IMPLEMENTED."); }
GLShader::GLShader(const char *source, GLenum type) : m_shaderType(type), m_shader(0) { FZ_ASSERT(m_shaderType == GL_VERTEX_SHADER || m_shaderType == GL_FRAGMENT_SHADER, "Invalid shader type"); FZ_ASSERT(source != NULL, "Argumment must be non-NULL"); if(!compileShader(source)) FZ_RAISE("GLProgram: Error compiling shader."); }
void MS::initialize() { if (_initialized) return; // Initialize stack _modelview_stack.stack = new float*[STACK_SIZE]; if(_modelview_stack.stack == NULL) FZ_RAISE("MatrixStack: Imposible to allocate memory."); _modelview_stack.capacity = STACK_SIZE; _modelview_stack.num = 1; _modelview_stack.stack[0] = NULL; _initialized = true; }
void Label::createFontChars() { // Get string length fzUInt m_stringLen = m_string.size(); Sprite *fontChar = static_cast<Sprite*>(m_children.front()); if(m_stringLen > 0) { // Is font available? if(p_font == NULL) { FZLOGERROR("Label: Impossible to generate label, font config is missing."); return; } // Precalculate label size fzFloat longestLine = 0; fzUInt currentLine = 0; char charId = 0, prevId = 0; fzFloat lineWidth[100]; memset(lineWidth, 0, sizeof(fzFloat) * 100); for(fzUInt i = 0; i < m_stringLen; ++i) { charId = m_string.at(i); if(charId < 0) FZ_RAISE("Label: CHAR[] doesn't exist. It's negative."); if( charId == '\n') { longestLine = fzMax(longestLine, lineWidth[currentLine]); ++currentLine; }else { lineWidth[currentLine] += p_font->getCharInfo(charId).xAdvance + m_horizontalPadding + p_font->getKerning(prevId, charId); prevId = charId; } } longestLine = fzMax(longestLine, lineWidth[currentLine]); fzFloat lineHeight = p_font->getLineHeight() + m_verticalPadding; fzFloat totalHeight = lineHeight * (currentLine+1); fzInt nextFontPositionY = totalHeight - lineHeight; fzInt nextFontPositionX = 0; prevId = 0; currentLine = 0; for(fzUInt i = 0; i < m_stringLen; ++i) { charId = m_string.at(i); // line jump if (charId == '\n') { nextFontPositionY -= lineHeight; nextFontPositionX = 0; ++currentLine; continue; } // config line start point if (nextFontPositionX == 0) { switch (m_alignment) { case kFZLabelAlignment_left: nextFontPositionX = 0; break; case kFZLabelAlignment_right: nextFontPositionX = longestLine - lineWidth[currentLine]; //nextFontPositionX = (longestLine - lineWidth[currentLine])/2.0f; break; case kFZLabelAlignment_center: nextFontPositionX = (longestLine - lineWidth[currentLine])/2.0f; break; default: break; } } // get font def const fzCharDef& fontDef = p_font->getCharInfo(static_cast<unsigned char>(charId)); if(fontDef.xAdvance == 0) { char toPrint[3]; printChar(toPrint, charId); FZLOGERROR("Label: CHAR[%d] '%s' is not included.", charId, toPrint); nextFontPositionX += p_font->getLineHeight(); continue; } // get sprite if( fontChar == NULL ) { fontChar = new Sprite(); addChild(fontChar); }else { // reusing sprites fontChar->setIsVisible(true); } // config sprite nextFontPositionX += p_font->getKerning(prevId, charId); fzFloat yOffset = p_font->getLineHeight() - fontDef.yOffset; fzPoint fontPos = fzPoint(nextFontPositionX + fontDef.xOffset + fontDef.width * 0.5f, nextFontPositionY + yOffset - fontDef.height * 0.5f ); fontChar->setTextureRect(fontDef.getRect()); fontChar->setPosition(fontPos); fontChar->setColor(m_color); // next sprite nextFontPositionX += fontDef.xAdvance + m_horizontalPadding; prevId = charId; fontChar = static_cast<Sprite*>(fontChar->next()); } // new content size setContentSize(fzSize(longestLine, totalHeight)); }else{ setContentSize(FZSizeZero); } // make sprites not longer used hidden. for(; fontChar; fontChar = static_cast<Sprite*>(fontChar->next())) fontChar->setIsVisible(false); }
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."); } }
void Director::updateProjection() { FZ_ASSERT(OSW::Instance(), "OS Wrapper is not defined."); updateViewRect(); if(!(m_dirtyFlags & kFZDDirty_projection)) return; // VIEW PORT // The view port must be the display size in pixels. // Display size is not equal to the screen size, an application could not use the whole screen. fzSize viewPort = getViewPort(); glViewport(0, 0, viewPort.width, viewPort.height); // PROJECTION // The projection must be calculated using the canvas size. No pixels here. fzSize canvasSize = getCanvasSize(); fzOrientation orientation = getOrientation(); if(orientation == kFZOrientation_LandscapeLeft || orientation == kFZOrientation_LandscapeRight) FZ_SWAP(canvasSize.width, canvasSize.height); switch (m_projection) { case kFZProjection2D: { fzMath_mat4OrthoProjection(0, canvasSize.width, 0, canvasSize.height, -1024, 1024, m_transformMV); break; } default: FZ_RAISE("Director: Unrecognized projection."); } m_orientationTransform = FZAffineTransformIdentity; if(orientation == kFZOrientation_LandscapeLeft) { m_orientationTransform.translate(canvasSize.width, 0); m_orientationTransform.rotate(FZ_DEGREES_TO_RADIANS(90)); fzMat4 mat; fzMath_mat4Multiply(m_transformMV, m_orientationTransform, mat); fzMath_mat4Copy(mat, m_transformMV); }else if(orientation == kFZOrientation_LandscapeRight) { m_orientationTransform.translate(0, canvasSize.height); m_orientationTransform.rotate(FZ_DEGREES_TO_RADIANS(-90)); fzMat4 mat; fzMath_mat4Multiply(m_transformMV, m_orientationTransform, mat); fzMath_mat4Copy(mat, m_transformMV); } m_orientationTransform = m_orientationTransform.getInverse(); m_dirtyFlags &= ~kFZDDirty_projection; if(p_runningScene) { p_runningScene->updateLayout(); if(p_hud) p_hud->updateLayout(); } }
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."); }