示例#1
0
文件: Sound.cpp 项目: noam-c/EDEn
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;
   }
}
示例#2
0
文件: Plugin.cpp 项目: cgart/nrEngine
	//----------------------------------------------------------------------------------
	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;
	}
示例#3
0
文件: Sound.cpp 项目: noam-c/EDEn
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);
}
示例#4
0
/*
 * 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);
	}
}
示例#5
0
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);
}
示例#6
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;
}
示例#8
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();
}
示例#9
0
文件: Sound.cpp 项目: noam-c/EDEn
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;
}
示例#10
0
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;
    }
}
示例#11
0
文件: Sound.cpp 项目: noam-c/EDEn
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;
}
示例#13
0
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());
	}
}
示例#14
0
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;
    }
}
示例#15
0
/*
 * 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);
	}
}
示例#16
0
文件: Sound.cpp 项目: linwang/EDEn
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
}
示例#17
0
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);
}
示例#18
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();
}
示例#19
0
文件: Plugin.cpp 项目: cgart/nrEngine
	//----------------------------------------------------------------------------------
	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;
	}
示例#20
0
文件: Plugin.cpp 项目: cgart/nrEngine
	//----------------------------------------------------------------------------------
	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;
	}
示例#21
0
	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.");
	}
示例#22
0
	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;
	}
示例#23
0
	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;
	}
示例#24
0
/**
 * 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);
}
示例#25
0
	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;
	}
示例#26
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);
	}
示例#27
0
/*
 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);
	}
}
示例#28
0
文件: Sound.cpp 项目: noam-c/EDEn
Sound::~Sound()
{
   DEBUG("Sound \"%s\": Deleting...", getResourceName().c_str());
   stop();
}