EffectRef SoundEngine::loadEffect(InputSourceRef inputSource) { FMOD_RESULT result = FMOD_OK; FMOD::Sound *sound = NULL; if (inputSource->isFile()) { result = system->createSound(inputSource->getFilePath().c_str(), FMOD_DEFAULT, NULL, &sound); } else { auto buffer = inputSource->loadDataSource()->getBuffer(); FMOD_CREATESOUNDEXINFO exinfo; memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO)); exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO); exinfo.length = buffer.getDataSize(); result = system->createSound(static_cast<const char*>(buffer.getData()), FMOD_DEFAULT | FMOD_OPENMEMORY, &exinfo, &sound); } if (result) { throw FMODException(result); } else { return make_shared<Effect>(inputSource, sound); } }
void TextureAtlas::init(InputSourceRef inputSource, bool useMipmap) { XmlTree doc(inputSource->loadDataSource()); auto texturePath = doc.getChild("TextureAtlas").getAttributeValue<string>("imagePath"); auto textureSource = inputSource->getSubSource(texturePath); texture = textureManager.getTexture(textureSource, useMipmap); float width = texture->getWidth(); float height = texture->getHeight(); // --- for (auto spriteElement = doc.begin("TextureAtlas/sprite"); spriteElement != doc.end(); ++spriteElement) { auto spritePath = spriteElement->getAttributeValue<string>("n"); auto x = spriteElement->getAttributeValue<float>("x"); auto y = spriteElement->getAttributeValue<float>("y"); auto w = spriteElement->getAttributeValue<float>("w"); auto h = spriteElement->getAttributeValue<float>("h"); auto rotated = spriteElement->hasAttribute("r"); float ox, oy; float ow, oh; if (rotated) { oy = spriteElement->getAttributeValue<float>("oX", 0); ox = spriteElement->getAttributeValue<float>("oY", 0); ow = spriteElement->getAttributeValue<float>("oW", h); oh = spriteElement->getAttributeValue<float>("oH", w); } else { ox = spriteElement->getAttributeValue<float>("oX", 0); oy = spriteElement->getAttributeValue<float>("oY", 0); ow = spriteElement->getAttributeValue<float>("oW", w); oh = spriteElement->getAttributeValue<float>("oH", h); } float u1 = x / width; float v1 = y / height; float u2 = (x + w) / width; float v2 = (y + h) / height; sprites[spritePath] = make_shared<Sprite>(texture, w, h, ox, oy, ow, oh, rotated, u1, v1, u2, v2); } }
void XFont::read(InputSourceRef inputSource) { if (inputSource->isFile()) { ifstream in(inputSource->getFilePath().c_str(), ifstream::binary); readFromStream(in); in.close(); } else { DataSourceRef resource = inputSource->loadDataSource(); Buffer &buffer = resource->getBuffer(); ReadStreamBuffer tmp(buffer); istream in(&tmp); readFromStream(in); } }
FollowablePath::FollowablePath(InputSourceRef inputSource, int mode) : mode(mode) { if (inputSource->isFile()) { ifstream in(inputSource->getFilePath().c_str(), ifstream::binary); readFromStream(in); in.close(); } else { DataSourceRef resource = inputSource->loadDataSource(); Buffer &buffer = resource->getBuffer(); ReadStreamBuffer tmp(buffer); istream in(&tmp); readFromStream(in); } }
void FontManager::unload(InputSourceRef inputSource) { for (auto it = fonts.begin(); it != fonts.end();) { if (it->first.first == inputSource->getURI()) { it = fonts.erase(it); } else { ++it; } } discardUnusedTextures(); }
EffectRef SoundEngine::preloadEffect(InputSourceRef inputSource) { string key = inputSource->getURI(); auto it = effects.find(key); if (it == effects.end()) { EffectRef effect = loadEffect(inputSource); effects[key] = effect; return effect; } else { return it->second; } }
std::shared_ptr<Font> FontManager::getCachedFont(InputSourceRef inputSource, const Font::Properties &properties) { auto uri = inputSource->getURI(); auto key = make_pair(uri, properties); auto it1 = fonts.find(key); if (it1 != fonts.end()) { return it1->second; } else { FontData *data; FontTexture *texture; auto it2 = fontDataAndTextures.find(uri); if (it2 == fontDataAndTextures.end()) { FontAtlas *atlas; tie(data, atlas) = fetchFontDataAndAtlas(inputSource); // CAN THROW texture = new FontTexture(atlas, inputSource); delete atlas; fontDataAndTextures[uri] = make_pair(unique_ptr<FontData>(data), unique_ptr<FontTexture>(texture)); } else { data = it2->second.first.get(); texture = it2->second.second.get(); } auto font = shared_ptr<Font>(new Font(*this, data, texture, properties)); // make_shared WON'T WORK WITH A PROTECTED CONSTRUCTOR fonts[key] = font; return font; } }
std::pair<FontData*, FontAtlas*> FontManager::fetchFontDataAndAtlas(InputSourceRef source) { auto in = source->loadDataSource()->createStream(); // CAN THROW string version; in->readFixedString(&version, 10); if (version != "XFONT.003") { throw runtime_error("Font: WRONG FORMAT"); } // --- int glyphCount; in->readLittle(&glyphCount); auto data = new FontData(glyphCount); in->readLittle(&data->baseSize); in->readLittle(&data->height); in->readLittle(&data->ascent); in->readLittle(&data->descent); in->readLittle(&data->spaceAdvance); in->readLittle(&data->strikethroughFactor); in->readLittle(&data->underlineOffset); in->readLittle(&data->lineThickness); int atlasWidth; int atlasHeight; int atlasPadding; int unitMargin; int unitPadding; in->readLittle(&atlasWidth); in->readLittle(&atlasHeight); in->readLittle(&atlasPadding); in->readLittle(&unitMargin); in->readLittle(&unitPadding); auto atlas = new FontAtlas(atlasWidth, atlasHeight); for (int i = 0; i < glyphCount; i++) { int glyphChar; int glyphWidth; int glyphHeight; int glyphLeftExtent; int glyphTopExtent; int glyphAtlasX; int glyphAtlasY; in->readLittle(&glyphChar); data->glyphs[(wchar_t)glyphChar] = i; in->readLittle(&data->advance[i]); in->readLittle(&glyphWidth); in->readLittle(&glyphHeight); in->readLittle(&glyphLeftExtent); in->readLittle(&glyphTopExtent); in->readLittle(&glyphAtlasX); in->readLittle(&glyphAtlasY); auto glyphData = new unsigned char[glyphWidth * glyphHeight]; in->readData(glyphData, glyphWidth * glyphHeight); atlas->addGlyph(glyphData, glyphAtlasX + atlasPadding + unitMargin, glyphAtlasY + atlasPadding + unitMargin, glyphWidth, glyphHeight); delete[] glyphData; data->w[i] = glyphWidth + unitPadding * 2; data->h[i] = glyphHeight + unitPadding * 2; data->le[i] = glyphLeftExtent - unitPadding; data->te[i] = glyphTopExtent + unitPadding; int x = glyphAtlasX + atlasPadding + unitMargin - unitPadding; int y = glyphAtlasY + atlasPadding + unitMargin - unitPadding; data->u1[i] = x / (float)atlasWidth; data->v1[i] = y / (float)atlasHeight; data->u2[i] = (x + data->w[i]) / (float)atlasWidth; data->v2[i] = (y + data->h[i]) / (float)atlasHeight; } return make_pair(data, atlas); }