void Sound::stop() { int playingChannel = m_playingChannel.load(); bool ownsChannel = false; if(playingChannel != -1) { std::lock_guard<decltype(playingListMutex)> playingListLock(playingListMutex); auto soundInChannelIter = Sound::playingList.find(playingChannel); ownsChannel = soundInChannelIter != Sound::playingList.end() && soundInChannelIter->second == this; } if(ownsChannel) { DEBUG("Sound \"%s\": Stopping...", getResourceName().c_str()); // N.B.: This call will synchronously call the // Mix_ChannelFinished callback, so make sure that // path doesn't try to recursively acquire any locks // acquired at this point Mix_HaltChannel(playingChannel); DEBUG("Sound \"%s\": Stopped.", getResourceName().c_str()); } else { m_playingChannel = -1; } }
//---------------------------------------------------------------------------------- Result Plugin::unloadResource() { // only unload, if we are loaded if (isResourceLoaded()) { // call the release function of the plugin m_plgRelease(); // set all symbols to NULL m_plgInitialize = NULL; m_plgEngineVersion = NULL; m_plgVersionString = NULL; m_plgError = NULL; m_plgRelease = NULL; // now unload the plugin handle from memory if (NR_PLUGIN_UNLOAD(mPluginHandle)) { NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "Could not unload plugin %s. System Msg: %s", getResourceName().c_str(), getLastPluginError().c_str()); return PLG_UNLOAD_ERROR; } // set the handle to 0 mPluginHandle = NULL; markResourceUnloaded(); } // OK return OK; }
void Sound::load(const std::string& path) { std::lock_guard<decltype(m_playbackMutex)> lock(m_playbackMutex); DEBUG("Sound \"%s\": Loading WAV %s", getResourceName().c_str(), path.c_str()); auto sound = Mix_LoadWAV(path.c_str()); if(!sound) { T_T(Mix_GetError()); } DEBUG("Sound \"%s\": Successfully loaded WAV %s.", getResourceName().c_str(), path.c_str()); m_sound.reset(sound); }
/* * Function: processPost * ---------------------------- * Call to process POST requests * * Parameters: * socket: The socket to send data out to. * requestData: The data from the request. */ void processPost(int socket, char *requestData) { char resourceName[strlen(requestData)]; bzero(resourceName, strlen(requestData)); getResourceName(resourceName, requestData); char *formData[3]; formData[0] = NULL; getFormData(formData, requestData); int responseSize = getResponseSize(resourceName, formData, socket); if (responseSize != -1) { char *contentType = getContentType(resourceName); if (strlen(contentType) == 0) { sendError(socket, 415); return; } sendResponseHeader(resourceName, contentType, responseSize, socket); sendData(resourceName, formData, socket); close(socket); } }
int VMIFile::readData() { file_t f; vmi_hdr_t header; uint8 *raw; char tmp[13]; DreamcastFile *df; df=getDCFile(); if(df == NULL) { df=new DreamcastFile(); setDCFile(df); } if (!(f=fs_open(getFileName(), O_RDONLY))) { printf("ERROR: Can't open %s!\n", getFileName()); return(-1); } fs_read(f, &header, 0x6C); fs_close(f); loadHeader(&header); sprintf(tmp, "%s.VMS", getResourceName()); if (!(f=fs_open(tmp, O_RDONLY))) { printf("ERROR: Can't open %s!\n", tmp); return(-2); } // raw=(uint8*)malloc(df->getSize()); raw=new uint8[df->getSize()]; fs_read(f, raw, df->getSize()); df->setData(raw); // free(raw); fs_close(f); return(0); }
std::string CResourceLoader::getResourceName(const ResourceID & resourceIdent) const { auto locator = getResource(resourceIdent); if (locator.getLoader()) return locator.getLoader()->getFullName(locator.getResourceName()); return ""; }
int removeSharedMemory() { char shm_name[1024]; getResourceName( shm_name, shm_rname ); if ( !boost::interprocess::shared_memory_object::remove( shm_name ) ) { return RE_SHM_UNLINK_ERROR; } return 0; }
void gkMesh::reload() { Ogre::MeshManager& mgr = Ogre::MeshManager::getSingleton(); const gkString& name = getResourceName().getName(); Ogre::MeshPtr omesh = mgr.getByName(name); if (!omesh.isNull()) omesh.getPointer()->reload(); }
void Sound::finished() { DEBUG("Sound \"%s\": Finished.", getResourceName().c_str()); std::lock_guard<decltype(m_playbackMutex)> lock(m_playbackMutex); if(m_playTask) { m_playTask->complete(); m_playTask.reset(); } m_playingChannel = -1; }
unsigned char *prepareNonServerSharedMemory() { char shm_name[1024]; getResourceName( shm_name, shm_rname ); try { shm_obj = new boost::interprocess::shared_memory_object( boost::interprocess::open_only, shm_name, boost::interprocess::read_only ); mapped = new boost::interprocess::mapped_region( *shm_obj, boost::interprocess::read_only ); unsigned char *buf = ( unsigned char * ) mapped->get_address(); return buf; } catch ( boost::interprocess::interprocess_exception e ) { return NULL; } }
void Sound::play(const std::shared_ptr<Task>& task) { std::lock_guard<decltype(m_playbackMutex)> playbackLock(m_playbackMutex); if(!Settings::getCurrentSettings().isSoundEnabled() || !m_sound) { if(task) { task->complete(); } return; } // If the sound is already playing somewhere, stop it. stop(); // At this point, there should be nothing playing. DEBUG("Sound \"%s\": Playing...", getResourceName().c_str()); { std::lock_guard<decltype(playingListMutex)> playingListLock(playingListMutex); m_playingChannel = Mix_PlayChannel(-1, m_sound.get(), 0); if(m_playingChannel == -1) { DEBUG("There was a problem playing the sound ""%s"": %s", getResourceName().c_str(), Mix_GetError()); task->complete(); return; } DEBUG("Sound \"%s\": Using channel %d.", getResourceName().c_str(), m_playingChannel.load()); Sound::playingList[m_playingChannel] = this; m_playTask = task; } }
RenderMaterial* RenderMaterial::Duplicate(){ RenderMaterial* m=new RenderMaterial(); m->setResourceName(getResourceName()); for(int i=0;i<m_techniques.size();++i) { RenderTechnique* t; m->AddTechnique( t=m_techniques[i]->Duplicate()); t->SetOwnerMaterial(this); if(m_techniques[i]==m_activeTechnique) { m->m_activeTechnique=t; } } return m; }
void gkMesh::updateBounds() { m_boundsInit = false; getBoundingBox(); // update ogre-bounds Ogre::MeshManager& mgr = Ogre::MeshManager::getSingleton(); const gkString& name = getResourceName().getName(); Ogre::MeshPtr omesh = mgr.getByName(name); if (!omesh.isNull()){ omesh.getPointer()->_setBounds(m_bounds, false); omesh.getPointer()->_setBoundingSphereRadius(m_bounds.getSize().squaredLength()); } }
unsigned char *prepareServerSharedMemory() { try { char shm_name[1024]; getResourceName( shm_name, shm_rname ); shm_obj = new boost::interprocess::shared_memory_object( boost::interprocess::open_or_create, shm_name, boost::interprocess::read_write ); boost::interprocess::offset_t size; if ( shm_obj->get_size( size ) && size == 0 ) { shm_obj->truncate( SHMMAX ); } mapped = new boost::interprocess::mapped_region( *shm_obj, boost::interprocess::read_write ); unsigned char *shmBuf = ( unsigned char * ) mapped->get_address(); return shmBuf; } catch ( boost::interprocess::interprocess_exception e ) { return NULL; } }
/* * Function: processHead * ---------------------------- * Call to process HEAD requests * * Parameters: * socket: The socket to send data out to. * requestData: The data from the request. */ void processHead(int socket, char *requestData) { char resourceName[strlen(requestData)]; getResourceName(resourceName, requestData); int responseSize = getResponseSize(resourceName, NULL, socket); if (responseSize != -1) { char *contentType = getContentType(resourceName); if (strlen(contentType) == 0) { sendError(socket, 415); return; } sendResponseHeader(resourceName, contentType, responseSize, socket); close(socket); } }
void Sound::play(Task* task) { #ifndef SOUND_OFF if(sound == NULL) { if(task) { task->signal(); } return; } playingChannel = Mix_PlayChannel(-1, sound, 0); if(playingChannel == -1) { DEBUG("There was a problem playing the sound ""%s"": %s", getResourceName().c_str(), Mix_GetError()); } playingList[playingChannel] = this; playTask = task; #endif }
int VMIFile::writeData() { file_t f; vmi_hdr_t header; DreamcastFile *df; char tmp[13]; df=getDCFile(); if (!(f=fs_open(getFileName(), "wb"))) { printf("ERROR: Can't open %s!\n", getFileName()); return(-1); } buildHeader(&header); fs_write(f, &header, 0x6C); fs_close(f); sprintf(tmp, "%s.VMS", getResourceName()); if (!(f=fs_open(tmp, "wb"))) { printf("ERROR: Can't open %s!\n", tmp); return(-2); } fs_write(f, df->getData(), df->getSize()); fs_close(f); return(0); }
void VMIFile::buildHeader(vmi_hdr_t *header) { DreamcastFile *df; uint16 year; df=getDCFile(); memset(header, 0x00, 0x6C); strcpy(header->description, getDescription()); strcpy(header->copyright, getCopyright()); strcpy(header->resource_name, getResourceName()); header->checksum[0]=header->resource_name[0] & 'S'; header->checksum[1]=header->resource_name[1] & 'E'; header->checksum[2]=header->resource_name[2] & 'G'; header->checksum[3]=header->resource_name[3] & 'A'; header->timestamp=df->getTime(); df->timeToDec(&header->timestamp); year=header->timestamp.cent*100 + header->timestamp.year; memcpy(&header->timestamp.cent, &year, 2); header->timestamp.dow=(header->timestamp.dow == 6) ? 0 : header->timestamp.dow+1; header->filenumber=0x01; strcpy(header->filename, df->getName()); header->filemode=((df->isGameFile()) ? VMI_VMUGAME : 0x00) | ((df->isCopyProtected()) ? VMI_NOCOPY : 0x00); header->filesize=df->getSize(); }
//---------------------------------------------------------------------------------- Result Plugin::reloadResource(PropertyList* params) { if (!isResourceLoaded()) { // get filename const std::string& name = getResourceFilenameList().front(); // now load the library mPluginHandle = (PluginHandle)NR_PLUGIN_LOAD(name.c_str()); // check whenever the library could be loaded if (mPluginHandle == NULL) { NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "Plugin %s could not be loaded! System Msg: %s", getResourceName().c_str(), getLastPluginError().c_str()); return PLG_COULD_NOT_LOAD; } // force the plugin resource object to initialize itself after loading return initialize(params); } return OK; }
//---------------------------------------------------------------------------------- Result Plugin::initialize(PropertyList* params) { NR_Log(Log::LOG_ENGINE, Log::LL_DEBUG, "Check if the loaded library is valid plugin"); // get version information m_plgEngineVersion = (plgEngineVersion)getSymbol("plgEngineVersion"); m_plgVersionString = (plgVersionString)getSymbol("plgVersionString"); if (!m_plgEngineVersion || !m_plgVersionString) { NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "Plugin seems not to be written for the nrEngine"); NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "plgVersionString/plgEngineVersion symbols were not found!!!"); return PLG_SYMBOL_NOT_FOUND; } // Log this NR_Log(Log::LOG_ENGINE, "Plugin found: %s written for nrEngine v%s", m_plgVersionString(), convertVersionToString(m_plgEngineVersion()).c_str()); // check if plugin is working with the current engine version if (m_plgEngineVersion() > nrEngineVersion){ NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "Plugin has got greater version as the engine, so plugin not loaded"); return PLG_WRONG_VERSION; } // log something NR_Log(Log::LOG_PLUGIN, "Initialize plugin %s", getResourceName().c_str()); #define GET_SYMBOL(var, type)\ {\ NR_Log(Log::LOG_ENGINE, Log::LL_DEBUG, "Get plugin symbol %s", #type);\ var = (type)getSymbol(#type);\ if (!var){\ NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "Plugin symbol %s was not found", #type);\ return PLG_SYMBOL_NOT_FOUND;\ }\ } // Get plugin symbols GET_SYMBOL(m_plgInitialize, plgInitialize); GET_SYMBOL(m_plgError, plgError); GET_SYMBOL(m_plgRelease, plgRelease); #undef GET_SYMBOL // call the function and check for return code int result = m_plgInitialize(Engine::instance(), params); // check for error if (result != 0){ NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "Plugin returns error %d (%s). See plugin log for more detail information", result, m_plgError(result)); return PLG_EXTERNAL_ERROR; } // now get some extra symbols /*m_plgGetMethods = (plgGetMethods)getSymbol("plgGetMethods"); m_plgCall = (plgCall)getSymbol("plgCall"); if (m_plgGetMethods){ // get the list of methods provided by this plugin m_plgGetMethods(mPlgMethods); NR_Log(Log::LOG_ENGINE, Log::LL_DEBUG, "Plugin provides following symbols: "); // now go through each of this method and print some log info about it for (uint32 i=0; i < mPlgMethods.size(); i++){ std::string params; for (uint32 j=0; j < mPlgMethods[i].param.size(); j++){ params += mPlgMethods[i].param[j].name; if (j < mPlgMethods[i].param.size() - 1) params += ", "; } NR_Log(Log::LOG_ENGINE, Log::LL_DEBUG, " found - %s (%s)", mPlgMethods[i].name.c_str(), params.c_str()); } }*/ // all right! return OK; }
void ResourceTrueTypeFont::deserialization(xml::ElementPtr _node, Version _version) { Base::deserialization(_node, _version); MYGUI_LOG(Error, "ResourceTrueTypeFont: TrueType font '" << getResourceName() << "' disabled. Define MYGUI_USE_FREETYE if you need TrueType fonts."); }
void ResourceTrueTypeFont::initialiseFreeType() { //-------------------------------------------------------------------// // Initialise FreeType and load the font. //-------------------------------------------------------------------// FT_Library ftLibrary; if (FT_Init_FreeType(&ftLibrary) != 0) MYGUI_EXCEPT("ResourceTrueTypeFont: Could not init the FreeType library!"); uint8* fontBuffer = nullptr; FT_Face ftFace = loadFace(ftLibrary, fontBuffer); if (ftFace == nullptr) { MYGUI_LOG(Error, "ResourceTrueTypeFont: Could not load the font '" << getResourceName() << "'!"); return; } //-------------------------------------------------------------------// // Calculate the font metrics. //-------------------------------------------------------------------// // The font's overall ascent and descent are defined in three different places in a TrueType font, and with different // values in each place. The most reliable source for these metrics is usually the "usWinAscent" and "usWinDescent" pair of // values in the OS/2 header; however, some fonts contain inaccurate data there. To be safe, we use the highest of the set // of values contained in the face metrics and the two sets of values contained in the OS/2 header. int fontAscent = ftFace->size->metrics.ascender >> 6; int fontDescent = -ftFace->size->metrics.descender >> 6; TT_OS2* os2 = (TT_OS2*)FT_Get_Sfnt_Table(ftFace, ft_sfnt_os2); if (os2 != nullptr) { setMax(fontAscent, os2->usWinAscent * ftFace->size->metrics.y_ppem / ftFace->units_per_EM); setMax(fontDescent, os2->usWinDescent * ftFace->size->metrics.y_ppem / ftFace->units_per_EM); setMax(fontAscent, os2->sTypoAscender * ftFace->size->metrics.y_ppem / ftFace->units_per_EM); setMax(fontDescent, -os2->sTypoDescender * ftFace->size->metrics.y_ppem / ftFace->units_per_EM); } // The nominal font height is calculated as the sum of its ascent and descent as specified by the font designer. Previously // it was defined by MyGUI in terms of the maximum ascent and descent of the glyphs currently in use, but this caused the // font's line spacing to change whenever glyphs were added to or removed from the font definition. Doing it this way // instead prevents a lot of layout problems, and it is also more typographically correct and more aesthetically pleasing. mDefaultHeight = fontAscent + fontDescent; // Set the load flags based on the specified type of hinting. FT_Int32 ftLoadFlags; switch (mHinting) { case HintingForceAuto: ftLoadFlags = FT_LOAD_FORCE_AUTOHINT; break; case HintingDisableAuto: ftLoadFlags = FT_LOAD_NO_AUTOHINT; break; case HintingDisableAll: // When hinting is completely disabled, glyphs must always be rendered -- even during layout calculations -- due to // discrepancies between the glyph metrics and the actual rendered bitmap metrics. ftLoadFlags = FT_LOAD_NO_HINTING | FT_LOAD_RENDER; break; case HintingUseNative: ftLoadFlags = FT_LOAD_DEFAULT; break; } //-------------------------------------------------------------------// // Create the glyphs and calculate their metrics. //-------------------------------------------------------------------// GlyphHeightMap glyphHeightMap; int texWidth = 0; // Before creating the glyphs, add the "Space" code point to force that glyph to be created. For historical reasons, MyGUI // users are accustomed to omitting this code point in their font definitions. addCodePoint(FontCodeType::Space); // Create the standard glyphs. for (CharMap::iterator iter = mCharMap.begin(); iter != mCharMap.end(); ) { const Char& codePoint = iter->first; FT_UInt glyphIndex = FT_Get_Char_Index(ftFace, codePoint); texWidth += createFaceGlyph(glyphIndex, codePoint, fontAscent, ftFace, ftLoadFlags, glyphHeightMap); // If the newly created glyph is the "Not Defined" glyph, it means that the code point is not supported by the font. // Remove it from the character map so that we can provide our own substitute instead of letting FreeType do it. if (iter->second != 0) ++iter; else mCharMap.erase(iter++); } // Do some special handling for the "Space" and "Tab" glyphs. GlyphInfo* spaceGlyphInfo = getGlyphInfo(FontCodeType::Space); if (spaceGlyphInfo != nullptr && spaceGlyphInfo->codePoint == FontCodeType::Space) { // Adjust the width of the "Space" glyph if it has been customized. if (mSpaceWidth != 0.0f) { texWidth += (int)std::ceil(mSpaceWidth) - (int)std::ceil(spaceGlyphInfo->width); spaceGlyphInfo->width = mSpaceWidth; spaceGlyphInfo->advance = mSpaceWidth; } // If the width of the "Tab" glyph hasn't been customized, make it eight spaces wide. if (mTabWidth == 0.0f) mTabWidth = mDefaultTabWidth * spaceGlyphInfo->advance; } // Create the special glyphs. They must be created after the standard glyphs so that they take precedence in case of a // collision. To make sure that the indices of the special glyphs don't collide with any glyph indices in the font, we must // use glyph indices higher than the highest glyph index in the font. FT_UInt nextGlyphIndex = (FT_UInt)ftFace->num_glyphs; float height = (float)mDefaultHeight; texWidth += createGlyph(nextGlyphIndex++, GlyphInfo(static_cast<Char>(FontCodeType::Tab), 0.0f, 0.0f, mTabWidth, 0.0f, 0.0f), glyphHeightMap); texWidth += createGlyph(nextGlyphIndex++, GlyphInfo(static_cast<Char>(FontCodeType::Selected), mSelectedWidth, height, 0.0f, 0.0f, 0.0f), glyphHeightMap); texWidth += createGlyph(nextGlyphIndex++, GlyphInfo(static_cast<Char>(FontCodeType::SelectedBack), mSelectedWidth, height, 0.0f, 0.0f, 0.0f), glyphHeightMap); texWidth += createGlyph(nextGlyphIndex++, GlyphInfo(static_cast<Char>(FontCodeType::Cursor), mCursorWidth, height, 0.0f, 0.0f, 0.0f), glyphHeightMap); // If a substitute code point has been specified, check to make sure that it exists in the character map. If it doesn't, // revert to the default "Not Defined" code point. This is not a real code point but rather an invalid Unicode value that // is guaranteed to cause the "Not Defined" special glyph to be created. if (mSubstituteCodePoint != FontCodeType::NotDefined && mCharMap.find(mSubstituteCodePoint) == mCharMap.end()) mSubstituteCodePoint = static_cast<Char>(FontCodeType::NotDefined); // Create the "Not Defined" code point (and its corresponding glyph) if it's in use as the substitute code point. if (mSubstituteCodePoint == FontCodeType::NotDefined) texWidth += createFaceGlyph(0, static_cast<Char>(FontCodeType::NotDefined), fontAscent, ftFace, ftLoadFlags, glyphHeightMap); // Cache a pointer to the substitute glyph info for fast lookup. mSubstituteGlyphInfo = &mGlyphMap.find(mSubstituteCodePoint)->second; // Calculate the average height of all of the glyphs that are in use. This value will be used for estimating how large the // texture needs to be. double averageGlyphHeight = 0.0; for (GlyphHeightMap::const_iterator j = glyphHeightMap.begin(); j != glyphHeightMap.end(); ++j) averageGlyphHeight += j->first * j->second.size(); averageGlyphHeight /= mGlyphMap.size(); //-------------------------------------------------------------------// // Calculate the final texture size. //-------------------------------------------------------------------// // Round the current texture width and height up to the nearest powers of two. texWidth = Bitwise::firstPO2From(texWidth); int texHeight = Bitwise::firstPO2From((int)ceil(averageGlyphHeight) + mGlyphSpacing); // At this point, the texture is only one glyph high and is probably very wide. For efficiency reasons, we need to make the // texture as square as possible. If the texture cannot be made perfectly square, make it taller than it is wide, because // the height may decrease in the final layout due to height packing. while (texWidth > texHeight) { texWidth /= 2; texHeight *= 2; } // Calculate the final layout of all of the glyphs in the texture, packing them tightly by first arranging them by height. // We assume that the texture width is fixed but that the texture height can be adjusted up or down depending on how much // space is actually needed. // In most cases, the final texture will end up square or almost square. In some rare cases, however, we can end up with a // texture that's more than twice as high as it is wide; when this happens, we double the width and try again. do { if (texHeight > texWidth * 2) texWidth *= 2; int texX = mGlyphSpacing; int texY = mGlyphSpacing; for (GlyphHeightMap::const_iterator j = glyphHeightMap.begin(); j != glyphHeightMap.end(); ++j) { for (GlyphHeightMap::mapped_type::const_iterator i = j->second.begin(); i != j->second.end(); ++i) { GlyphInfo& info = *i->second; int glyphWidth = (int)std::ceil(info.width); int glyphHeight = (int)std::ceil(info.height); autoWrapGlyphPos(glyphWidth, texWidth, glyphHeight, texX, texY); if (glyphWidth > 0) texX += mGlyphSpacing + glyphWidth; } } texHeight = Bitwise::firstPO2From(texY + glyphHeightMap.rbegin()->first); } while (texHeight > texWidth * 2); //-------------------------------------------------------------------// // Create the texture and render the glyphs onto it. //-------------------------------------------------------------------// if (mTexture) { RenderManager::getInstance().destroyTexture( mTexture ); mTexture = nullptr; } mTexture = RenderManager::getInstance().createTexture(MyGUI::utility::toString((size_t)this, "_TrueTypeFont")); mTexture->createManual(texWidth, texHeight, TextureUsage::Static | TextureUsage::Write, Pixel<LAMode>::getFormat()); mTexture->setInvalidateListener(this); uint8* texBuffer = static_cast<uint8*>(mTexture->lock(TextureUsage::Write)); if (texBuffer != nullptr) { // Make the texture background transparent white. for (uint8* dest = texBuffer, * endDest = dest + texWidth * texHeight * Pixel<LAMode>::getNumBytes(); dest != endDest; ) Pixel<LAMode, false, false>::set(dest, charMaskWhite, charMaskBlack); renderGlyphs<LAMode, Antialias>(glyphHeightMap, ftLibrary, ftFace, ftLoadFlags, texBuffer, texWidth, texHeight); mTexture->unlock(); MYGUI_LOG(Info, "ResourceTrueTypeFont: Font '" << getResourceName() << "' using texture size " << texWidth << " x " << texHeight << "."); MYGUI_LOG(Info, "ResourceTrueTypeFont: Font '" << getResourceName() << "' using real height " << mDefaultHeight << " pixels."); } else { MYGUI_LOG(Error, "ResourceTrueTypeFont: Error locking texture; pointer is nullptr."); } FT_Done_Face(ftFace); FT_Done_FreeType(ftLibrary); delete [] fontBuffer; }
FT_Face ResourceTrueTypeFont::loadFace(const FT_Library& _ftLibrary, uint8*& _fontBuffer) { FT_Face result = nullptr; // Load the font file. IDataStream* datastream = DataManager::getInstance().getData(mSource); if (datastream == nullptr) return result; size_t fontBufferSize = datastream->size(); _fontBuffer = new uint8[fontBufferSize]; datastream->read(_fontBuffer, fontBufferSize); DataManager::getInstance().freeData(datastream); datastream = nullptr; // Determine how many faces the font contains. if (FT_New_Memory_Face(_ftLibrary, _fontBuffer, (FT_Long)fontBufferSize, -1, &result) != 0) MYGUI_EXCEPT("ResourceTrueTypeFont: Could not load the font '" << getResourceName() << "'!"); FT_Long numFaces = result->num_faces; FT_Long faceIndex = 0; // Load the first face. if (FT_New_Memory_Face(_ftLibrary, _fontBuffer, (FT_Long)fontBufferSize, faceIndex, &result) != 0) MYGUI_EXCEPT("ResourceTrueTypeFont: Could not load the font '" << getResourceName() << "'!"); if (result->face_flags & FT_FACE_FLAG_SCALABLE) { // The font is scalable, so set the font size by first converting the requested size to FreeType's 26.6 fixed-point // format. FT_F26Dot6 ftSize = (FT_F26Dot6)(mSize * (1 << 6)); if (FT_Set_Char_Size(result, ftSize, 0, mResolution, mResolution) != 0) MYGUI_EXCEPT("ResourceTrueTypeFont: Could not set the font size for '" << getResourceName() << "'!"); // If no code points have been specified, use the Unicode Basic Multilingual Plane by default. if (mCharMap.empty()) addCodePointRange(0, 0xFFFF); } else { // The font isn't scalable, so try to load it as a Windows FNT/FON file. FT_WinFNT_HeaderRec fnt; // Enumerate all of the faces in the font and select the smallest one that's at least as large as the requested size // (after adjusting for resolution). If none of the faces are large enough, use the largest one. std::map<float, FT_Long> faceSizes; do { if (FT_Get_WinFNT_Header(result, &fnt) != 0) MYGUI_EXCEPT("ResourceTrueTypeFont: Could not load the font '" << getResourceName() << "'!"); faceSizes.insert(std::make_pair((float)fnt.nominal_point_size * fnt.vertical_resolution / mResolution, faceIndex)); FT_Done_Face(result); if (++faceIndex < numFaces) if (FT_New_Memory_Face(_ftLibrary, _fontBuffer, (FT_Long)fontBufferSize, faceIndex, &result) != 0) MYGUI_EXCEPT("ResourceTrueTypeFont: Could not load the font '" << getResourceName() << "'!"); } while (faceIndex < numFaces); std::map<float, FT_Long>::const_iterator iter = faceSizes.lower_bound(mSize); faceIndex = (iter != faceSizes.end()) ? iter->second : faceSizes.rbegin()->second; if (FT_New_Memory_Face(_ftLibrary, _fontBuffer, (FT_Long)fontBufferSize, faceIndex, &result) != 0) MYGUI_EXCEPT("ResourceTrueTypeFont: Could not load the font '" << getResourceName() << "'!"); // Select the first bitmap strike available in the selected face. This needs to be done explicitly even though Windows // FNT/FON files contain only one bitmap strike per face. if (FT_Select_Size(result, 0) != 0) MYGUI_EXCEPT("ResourceTrueTypeFont: Could not set the font size for '" << getResourceName() << "'!"); // Windows FNT/FON files do not support Unicode, so restrict the code-point range to either ISO-8859-1 or ASCII, // depending on the font's encoding. if (mCharMap.empty()) { // No code points have been specified, so add the printable ASCII range by default. addCodePointRange(0x20, 0x7E); // Additionally, if the font's character set is CP-1252, add the range of non-ASCII 8-bit code points that are // common between CP-1252 and ISO-8859-1; i.e., everything but 0x80 through 0x9F. if (fnt.charset == FT_WinFNT_ID_CP1252) addCodePointRange(0xA0, 0xFF); } else { // Some code points have been specified, so remove anything in the non-printable ASCII range as well as anything // over 8 bits. removeCodePointRange(0, 0x1F); removeCodePointRange(0x100, std::numeric_limits<Char>::max()); // Additionally, remove non-ASCII 8-bit code points (plus ASCII DEL, 0x7F). If the font's character set is CP-1252, // remove only the code points that differ between CP-1252 and ISO-8859-1; otherwise, remove all of them. if (fnt.charset == FT_WinFNT_ID_CP1252) removeCodePointRange(0x7F, 0x9F); else removeCodePointRange(0x7F, 0xFF); } } return result; }
/** * Forms an AA resource name based on the given passed index */ const char *MADSResourceManager::getAAName(int index) { return getResourceName('I', 0, EXTTYPE_AA, NULL, index); }
int ResourceTrueTypeFont::createFaceGlyph(FT_UInt _glyphIndex, Char _codePoint, int _fontAscent, const FT_Face& _ftFace, FT_Int32 _ftLoadFlags, GlyphHeightMap& _glyphHeightMap) { if (mGlyphMap.find(_codePoint) == mGlyphMap.end()) { if (FT_Load_Glyph(_ftFace, _glyphIndex, _ftLoadFlags) == 0) return createGlyph(_glyphIndex, createFaceGlyphInfo(_codePoint, _fontAscent, _ftFace->glyph), _glyphHeightMap); else MYGUI_LOG(Warning, "ResourceTrueTypeFont: Cannot load glyph " << _glyphIndex << " for character " << _codePoint << " in font '" << getResourceName() << "'."); } else { mCharMap[_codePoint] = _glyphIndex; } return 0; }
void ResourceTrueTypeFont::renderGlyphs(const GlyphHeightMap& _glyphHeightMap, const FT_Library& _ftLibrary, const FT_Face& _ftFace, FT_Int32 _ftLoadFlags, uint8* _texBuffer, int _texWidth, int _texHeight) { FT_Bitmap ftBitmap; FT_Bitmap_New(&ftBitmap); int texX = mGlyphSpacing, texY = mGlyphSpacing; for (GlyphHeightMap::const_iterator j = _glyphHeightMap.begin(); j != _glyphHeightMap.end(); ++j) { for (GlyphHeightMap::mapped_type::const_iterator i = j->second.begin(); i != j->second.end(); ++i) { GlyphInfo& info = *i->second; switch (info.codePoint) { case FontCodeType::Selected: case FontCodeType::SelectedBack: { renderGlyph<LAMode, false, false>(info, charMaskWhite, charMaskBlack, charMask.find(info.codePoint)->second, j->first, _texBuffer, _texWidth, _texHeight, texX, texY); // Manually adjust the glyph's width to zero. This prevents artifacts from appearing at the seams when // rendering multi-character selections. GlyphInfo* glyphInfo = getGlyphInfo(info.codePoint); glyphInfo->width = 0.0f; glyphInfo->uvRect.right = glyphInfo->uvRect.left; } break; case FontCodeType::Cursor: case FontCodeType::Tab: renderGlyph<LAMode, false, false>(info, charMaskWhite, charMaskBlack, charMask.find(info.codePoint)->second, j->first, _texBuffer, _texWidth, _texHeight, texX, texY); break; default: if (FT_Load_Glyph(_ftFace, i->first, _ftLoadFlags | FT_LOAD_RENDER) == 0) { if (_ftFace->glyph->bitmap.buffer != nullptr) { uint8* glyphBuffer = nullptr; switch (_ftFace->glyph->bitmap.pixel_mode) { case FT_PIXEL_MODE_GRAY: glyphBuffer = _ftFace->glyph->bitmap.buffer; break; case FT_PIXEL_MODE_MONO: // Convert the monochrome bitmap to 8-bit before rendering it. if (FT_Bitmap_Convert(_ftLibrary, &_ftFace->glyph->bitmap, &ftBitmap, 1) == 0) { // Go through the bitmap and convert all of the nonzero values to 0xFF (white). for (uint8* p = ftBitmap.buffer, * endP = p + ftBitmap.width * ftBitmap.rows; p != endP; ++p) *p ^= -*p ^ *p; glyphBuffer = ftBitmap.buffer; } break; } if (glyphBuffer != nullptr) renderGlyph<LAMode, true, Antialias>(info, charMaskWhite, charMaskWhite, charMaskWhite, j->first, _texBuffer, _texWidth, _texHeight, texX, texY, glyphBuffer); } } else { MYGUI_LOG(Warning, "ResourceTrueTypeFont: Cannot render glyph " << i->first << " for character " << info.codePoint << " in font '" << getResourceName() << "'."); } break; } } } FT_Bitmap_Done(_ftLibrary, &ftBitmap); }
/* Patches the menu in EYE.RES from the EOB 3 so that it is usable in the AESOP/32 (changes the resource file) */ int patchEOB3MenuInOpenedFile(FILE *aNewFile, DIRPOINTER *aNewFileDirectoryPointers, struct RESGlobalHeader *aNewFileHeader) { int loResourceNumber = 1374; char loResourceName[] = "menu"; char loFoundResourceName[256]; unsigned char *loResourceBuffer; int loFoundResourceLength; printf("Patching the resource number %d, name \"%s\" ...\n", loResourceNumber, loResourceName); if (getResourceName(loFoundResourceName, 1374) == NULL) { printf("The resource number %d (%s)was not found!\n", loResourceNumber, loResourceName); return (false); } if (strcmp(loResourceName, loFoundResourceName) != 0) { printf( "The resource number %d has name %s (the program expected %s)!\n", loResourceNumber, loFoundResourceName, loResourceName); return (false); } loResourceBuffer = readResourceBinary(loResourceNumber, aNewFile, aNewFileDirectoryPointers, &loFoundResourceLength); if (loResourceBuffer == NULL) { printf("Failed to read the resource number %d!\n", loResourceNumber); return (false); } /* patch (addr. inside the resource, old, new) 00000345: 00 FF 00000346: 00 FF 00000348: FF 00 00000349: 0F 1A */ if (patchOneByte(loResourceBuffer, loFoundResourceLength, 0x345, 0x00, 0xff) == false) { free(loResourceBuffer); return (false); } if (patchOneByte(loResourceBuffer, loFoundResourceLength, 0x346, 0x00, 0xff) == false) { free(loResourceBuffer); return (false); } if (patchOneByte(loResourceBuffer, loFoundResourceLength, 0x348, 0xff, 0x00) == false) { free(loResourceBuffer); return (false); } if (patchOneByte(loResourceBuffer, loFoundResourceLength, 0x349, 0x0f, 0x1a) == false) { free(loResourceBuffer); return (false); } // replace the old resource by a new one if (replaceResourceInOpenedFile(loResourceName, loResourceNumber, loResourceBuffer, loFoundResourceLength, aNewFile, aNewFileHeader, aNewFileDirectoryPointers, false) == false) { printf( "Failed to replace the old resource %s by a new one (resource number %d)!\n", loResourceName, loResourceNumber); free(loResourceBuffer); return (false); } else { free(loResourceBuffer); return (true); } }
Sound::~Sound() { DEBUG("Sound \"%s\": Deleting...", getResourceName().c_str()); stop(); }