Esempio n. 1
0
//-----------------------------------------------------------------------------
// HOOK: Response Send Handler
// If an other Hook has set HookVarList["CacheCategory"] then the Conntent
// in hh->yresult should be cached into a file.
// Remeber: url, filename, mimetype, category, createdate
//-----------------------------------------------------------------------------
THandleStatus CmodCache::Hook_SendResponse(CyhookHandler *hh)
{
	hh->status = HANDLED_NONE;
	std::string url = hh->UrlData["fullurl"];
	log_level_printf(4,"mod_cache hook start url:%s\n",url.c_str());	

	std::string category = hh->HookVarList["CacheCategory"];
	if(!(hh->HookVarList["CacheCategory"]).empty())	// Category set = cache it
	{
		AddToCache(hh, url, hh->yresult, hh->HookVarList["CacheMimeType"], category); // create cache file and add to cache list
		hh->ContentLength = (hh->yresult).length();
		hh->SendFile(CacheList[url].filename);				// Send as file
		hh->ResponseMimeType = CacheList[url].mime_type;		// remember mime
	}
	else if(hh->UrlData["path"] == "/y/")	// /y/ commands
	{
		hh->status = HANDLED_READY;
		if(hh->UrlData["filename"] == "cache-info")
			yshowCacheInfo(hh);
		else if(hh->UrlData["filename"] == "cache-clear")
			yCacheClear(hh);
		else
			hh->status = HANDLED_CONTINUE;	// y-calls can be implemented anywhere
	}
	log_level_printf(4,"mod_cache hook end status:%d\n",(int)hh->status);	
	
	return hh->status;
}
static void doDestroyMemory(struct PVR2DPixmap *ppix)
{
	CALLTRACE("%s: Start\n", __func__);

#if SGX_CACHE_SEGMENTS
	if (AddToCache (ppix))
		return;
#endif

	if (ppix->pvr2dmem) {
		PVR2DMemFree(pvr2d_get_screen()->context, ppix->pvr2dmem);
		ppix->pvr2dmem = NULL;
	}

	if (ppix->shmid != -1) {
		shmdt(ppix->shmaddr);
		ppix->shmaddr = NULL;
		ppix->shmid = -1;
		PERF_DECREMENT2(shm_bytes, ppix->shmsize);
		PERF_DECREMENT(shm_segments);
		ppix->shmsize = 0;
	}

	if (ppix->mallocaddr) {
		free(ppix->mallocaddr);
		ppix->mallocaddr = NULL;
		PERF_DECREMENT2(malloc_bytes, ppix->mallocsize);
		PERF_DECREMENT(malloc_segments);
		ppix->mallocsize = 0;
	}
}
Esempio n. 3
0
// TODO(brettw): this function does not handle long paths (filename > MAX_PATH)
// characters). This isn't supported very well by Windows right now, so it is
// moot, but we should keep this in mind for the future.
// static
bool PathService::Get(int key, FilePath* result)
{
    PathData* path_data = GetPathData();
    DCHECK(path_data);
    DCHECK(result);
    DCHECK_GE(key, base::DIR_CURRENT);

    // special case the current directory because it can never be cached
    if(key == base::DIR_CURRENT)
    {
        return base::GetCurrentDirectory(result);
    }

    if(GetFromCache(key, result))
    {
        return true;
    }

    if(GetFromOverrides(key, result))
    {
        return true;
    }

    FilePath path;

    // search providers for the requested path
    // NOTE: it should be safe to iterate here without the lock
    // since RegisterProvider always prepends.
    Provider* provider = path_data->providers;
    while(provider)
    {
        if(provider->func(key, &path))
        {
            break;
        }
        DCHECK(path.empty()) << "provider should not have modified path";
        provider = provider->next;
    }

    if(path.empty())
    {
        return false;
    }

    AddToCache(key, path);

    *result = path;
    return true;
}
Esempio n. 4
0
wxArchiveFSEntry *wxArchiveFSCacheDataImpl::GetNext(wxArchiveFSEntry *fse)
{
    wxArchiveFSEntry *next = fse ? fse->next : m_begin;

    if (!next && m_archive)
    {
        wxArchiveEntry *entry = m_archive->GetNextEntry();

        if (entry)
            next = AddToCache(entry);
        else
            CloseStreams();
    }

    return next;
}
Esempio n. 5
0
// Adds all the documents in the list of filenames, couting memory.
// The reader is used to read the files.
bool DocumentCache::LoadDocuments(const GenericVector<STRING>& filenames,
                                  const char* lang, FileReader reader) {
  for (int arg = 0; arg < filenames.size(); ++arg) {
    STRING filename = filenames[arg] + ".lstmf";
    DocumentData* document = new DocumentData(filename);
    if (document->LoadDocument(filename.string(), lang, reader)) {
      AddToCache(document);
      tprintf("File %d, count=%d\n", arg, document->pages().size());
    } else {
      tprintf("Failed to load image %s!\n", filename.string());
      delete document;
    }
  }
  tprintf("Loaded %d pages, total %gMB\n",
          total_pages_, memory_used_ / 1048576.0);
  return total_pages_ > 0;
}
Esempio n. 6
0
static HANDLE IsHContactFromUIN(DWORD uin)
{
	MCONTACT hContact;
	DWORD dwUin;
	hContact = HandleFromCacheByUin(uin);
	if (hContact != NULL) return hContact;
	hContact = ICQFindFirstContact();
	while (hContact != NULL) {
		dwUin = ICQGetContactSettingUIN(hContact);
		if (dwUin == uin) {
			AddToCache(hContact, dwUin);
			return hContact;
		}
		hContact = ICQFindNextContact(hContact);
	}
	return NULL;
}
Esempio n. 7
0
char *SearchWadsForTextureName( const char *cleantexturename ){
	char *str;
	char *wadname;
	char *actualtexturename = NULL;
	GSList *l;
	int count;

	actualtexturename = CheckCacheForTextureName( cleantexturename );
	if ( actualtexturename ) {
		return actualtexturename;
	}

	// still here ?  guess it's not in the cache then!

	// search the wads listed in the worldspawn "wad" key
	for ( l = g_WadList; l != NULL && actualtexturename == NULL ; l = l->next )
	{
		wadname = (char *)l->data;

		str = new char[strlen( wadname ) + strlen( cleantexturename ) + 9 + 1 + 4 + 1];

		// hlw here is ok as we never have anything other than hlw files in a wad.
		sprintf( str,"textures/%s/%s.hlw",wadname,cleantexturename );
		count = vfsGetFileCount( str, VFS_SEARCH_PAK ); // only search pack files
		// LordHavoc: hacked in .mip loading here
		if ( !count ) {
			sprintf( str,"textures/%s/%s.mip",wadname,cleantexturename );
			count = vfsGetFileCount( str, VFS_SEARCH_PAK ); // only search pack files
		}

		if ( count > 0 ) {
			// strip the extension, build the cache string and add the the cache
			str[strlen( str ) - 4] = 0;

			actualtexturename = AddToCache( cleantexturename,str );

			//point the return value to the actual name, not what we add to the cache
			actualtexturename += 1 + strlen( cleantexturename );
		}
		delete [] str;
	}
	return actualtexturename;
}
Esempio n. 8
0
ISC::ISC(void)
{
  InitializeCriticalSection(&m_cs);

  Interface* pUnk = new Interface;
  pUnk->Guid = IID_IUnknown;
  pUnk->GuidBase = GUID_NULL;
  pUnk->nMethodCount = 3;
  pUnk->pBase = NULL;
  pUnk->strName = _T("IUnknown");

  pUnk->pMethods = new InterfaceMethod[3];
  pUnk->pMethods[0].nParamCount = 0;  // QI
  pUnk->pMethods[1].nParamCount = 0;  // AddRef
  pUnk->pMethods[2].nParamCount = 0;  // Release

  pUnk->pMethods[0].pParams = NULL;
  pUnk->pMethods[1].pParams = NULL;
  pUnk->pMethods[2].pParams = NULL;

  pUnk->pMethods[0].strName = _T("QueryInterface");
  pUnk->pMethods[1].strName = _T("AddRef");
  pUnk->pMethods[2].strName = _T("Release");

  // params for QI
  pUnk->pMethods[0].pParams = new InterfaceParam[2];
  pUnk->pMethods[0].nParamCount = 2;

  // first param for QI (REFIID riid)
  pUnk->pMethods[0].pParams[0].vtType = VT_CLSID; // using this for GUID's
  pUnk->pMethods[0].pParams[0].bInParam = true;
  pUnk->pMethods[0].pParams[0].pointerSpec = ISC::Ptr;

  // second param for QI (VOID** ppv)
  pUnk->pMethods[0].pParams[1].vtType = VT_UNKNOWN; 
  pUnk->pMethods[0].pParams[1].bOutParam = true;
  pUnk->pMethods[0].pParams[1].pointerSpec = ISC::Ptr2Ptr;
  pUnk->pMethods[0].pParams[1].pIidIsParam = &pUnk->pMethods[0].pParams[0]; // reference the first parameter 

  AddToCache(pUnk);
}
Esempio n. 9
0
wxArchiveEntry *wxArchiveFSCacheDataImpl::Get(const wxString& name)
{
    wxArchiveFSEntryHash::iterator it = m_hash.find(name);

    if (it != m_hash.end())
        return it->second;

    if (!m_archive)
        return NULL;

    wxArchiveEntry *entry;

    while ((entry = m_archive->GetNextEntry()) != NULL)
    {
        AddToCache(entry);

        if (entry->GetName(wxPATH_UNIX) == name)
            return entry;
    }

    CloseStreams();

    return NULL;
}
Esempio n. 10
0
	bool ISO9660::ReadDirectoryBlock(ISO9660_DirectoryEntry *pDirectoryEntry, FileSystemDirectoryEntry *pParentDirectory, bool bVerbose)
	{
		// Check if this directory entry has already been cached.
		FileSystemSectorCacheEntry *pCacheEntry = (FileSystemSectorCacheEntry*)FindCacheEntry(pDirectoryEntry->dwExtentLBA.LE);
		if (pCacheEntry != nullptr)
		{
			// The directory entry has already been cached so there is nothing to do here.
			return true;
		}

		// Create a new FileSystemDirectoryEntry object for the directory entry provided.
		FileSystemDirectoryEntry *pFsDirectoryEntry = new FileSystemDirectoryEntry(pDirectoryEntry, pParentDirectory);
		if (bVerbose == true)
		{
			// Print the folder name.
			if (pFsDirectoryEntry->IsDirectory() == true)
				printf("%d\t\t%d\t\t%s\\..\n", pFsDirectoryEntry->GetExtentLBA(), pFsDirectoryEntry->GetExtentSize(), pFsDirectoryEntry->GetFullName());
		}

		// The directory entry has not been cached yet so add it to the directory cache.
		if (AddToCache(pFsDirectoryEntry, &pCacheEntry) == false)
		{
			// Failed to cache directory entry data.
			delete pDirectoryEntry;
			return false;
		}

		// If this is a root entry then add it to our list of root directory entries.
		if (pParentDirectory == nullptr)
		{
			// This is a root entry so add it to the root list.
			this->lDirectoryEntries.push_back(pFsDirectoryEntry);
		}

		// Initialize the loop counter and interator.
		DWORD dwRemainingData = pDirectoryEntry->dwExtentSize.LE;
		PBYTE pbCacheData = pCacheEntry->pbSectorData;

		// Loop through the directory sectors until we reach the last directory entry.
		do
		{
			// Get the next ISO9660 directory entry from the cache data.
			ISO9660_DirectoryEntry *pDirEntry = (ISO9660_DirectoryEntry*)pbCacheData;

			// Check if the current directory entry is valid or if we are on a sector boundary.
			if (pDirEntry->bEntryLength == 0)
			{
				// Check if this next entry would cross a sector boundary.
				DWORD dwRemainder = dwRemainingData % ISO9660_SECTOR_SIZE;
				if (dwRemainder > 0 && dwRemainder < ISO9660_DIR_ENTRY_MAX_SIZE)
				{
					// Skip to the next sector.
					dwRemainingData -= dwRemainder;
					pbCacheData += dwRemainder;

					// Check to see if there is any remaining data left to be parsed.
					if (dwRemainingData <= 0)
						break;

					// Update the entry pointer.
					pDirEntry = (ISO9660_DirectoryEntry*)pbCacheData;
				}

				// Double check we now have a valid entry to work with.
				if (pDirEntry->bEntryLength == 0)
					break;
			}

			// Check if this entry is a directory or a file.
			if ((pDirEntry->bFileFlags & FileFlags::FileIsDirectory) != 0)
			{
				// Make sure we don't print the entry for the "./" file entry.
				if (pDirEntry->dwExtentLBA.LE != pDirectoryEntry->dwExtentLBA.LE)
				{
					// Recursively parse the child directory.
					if (ReadDirectoryBlock(pDirEntry, pFsDirectoryEntry, bVerbose) == false)
					{
						// Failed to read child directory entry data.
						return false;
					}
				}
			}
			else
			{
				// Setup the fs child entry which will automatically add it to the parent's list of children.
				FileSystemDirectoryEntry *pEntry = new FileSystemDirectoryEntry(pDirEntry, pFsDirectoryEntry);

				// Check if we should print the file information.
				if (bVerbose == true)
					printf("%d\t\t%d\t\t%s\n", pDirEntry->dwExtentLBA.LE, pDirEntry->dwExtentSize.LE, pEntry->GetFullName());
			}

			// Next entry.
			dwRemainingData -= pDirEntry->bEntryLength;
			pbCacheData += pDirEntry->bEntryLength;
		} while (dwRemainingData > 0);

		// Successfully parsed the file system for this directory entry.
		return true;
	}
Esempio n. 11
0
void SpriteHandler::initialize()
{
    cumulatedTime = 0.0f;
    
    NameGenerator::init();
    
    int targetIdleF = 0;
    int targetWalkF = 0;
    
    //here I assume there are 10 enums.
    for (int i = 0; i < SPRITE_APPEARANCE_TYPE_END; i++)
    {
        std::string fileName;
        std::string configContent;
        std::string defaultContent;
        std::string targetClass;
        std::string spriteContent;
        char targetGender;
        VillagerClass villagerClass;
        SpriteAppearanceType sat;
        
        //randomly spawn as male or female.
      
        //it's always a human now.
        char targetRace = 'h';
        
        switch (i)
        {
            case 0:
                targetGender = 'm';
                fileName = "MaleVillager";
                targetIdleF = 3;
                targetWalkF = 4;
                villagerClass = V_REFUGEE;
                sat = M_A_VILLAGER;
                break;
            case 1:
                targetGender = 'f';
                fileName = "FemaleVillager";
                targetIdleF = 3;
                targetWalkF = 4;
                villagerClass = V_REFUGEE;
                sat = F_A_VILLAGER;
                break;
            case 2:
                targetGender = 'm';
                fileName = "MaleYoungVillager";
                targetIdleF = 3;
                targetWalkF = 4;
                villagerClass = V_REFUGEE;
                sat = M_A_YOUNG_VILLAGER;
                break;
            case 3:
                targetGender = 'f';
                fileName = "YoungGirl";
                targetIdleF = 3;
                targetWalkF = 4;
                villagerClass = V_REFUGEE;
                sat = F_A_YOUNG_GIRL;
                break;
            case 4:
                targetGender = 'f';
                fileName = "Girl";
                targetIdleF = 3;
                targetWalkF = 4;
                villagerClass = V_REFUGEE;
                sat = F_A_GIRL;
                break;
            case 5:
                targetGender = 'f';
                fileName = "FemaleFarmer";
                targetIdleF = 3;
                targetWalkF = 4;
                villagerClass = V_REFUGEE;
                sat = F_A_FARMER;
                break;
            case 6:
                targetGender = 'm';
                fileName = "MaleFarmer";
                targetIdleF = 3;
                targetWalkF = 4;
                villagerClass = V_REFUGEE;
                sat = M_A_FARMER;
                break;
            case 7:
                targetGender = 'm';
                fileName = "MaleOldMan";
                targetIdleF = 3;
                targetWalkF = 4;
                villagerClass = V_REFUGEE;
                sat = M_A_OLDMAN;
                break;
            case 8:
                targetGender = 'm';
                fileName = "Soldier";
                targetIdleF = 3;
                targetWalkF = 4;
                villagerClass = V_SOLDIER;
                sat = M_A_SOLDIER;
                break;
            case 9:
                targetGender = 'f';
                fileName = "Soldier";
                targetIdleF = 3;
                targetWalkF = 4;
                villagerClass = V_SOLDIER;
                sat = F_A_SOLDIER;
                break;
            case 10:
                targetGender = 'm';
                fileName = "MaleBandit";
                targetIdleF = 3;
                targetWalkF = 4;
                villagerClass = V_BANDIT;
                sat = M_A_BANDIT;
                break;
            case 11:
                targetGender = 'f';
                fileName = "FemaleBandit";
                targetIdleF = 3;
                targetWalkF = 4;
                villagerClass = V_BANDIT;
                sat = F_A_BANDIT;
                break;
        }
        
        configContent = refugeeConfig;
        defaultContent = refugeeDefaults;
        targetClass = "refugee";
        
        std::string filepath = fileName + ".png";
        std::string plistName = fileName +".plist";
     
        CCSpriteBatchNode* spriteSheet = CCSpriteBatchNode::create(filepath.c_str());
        
        /*all spritesheets must be a child of the map*/
        AddToCache(NULL, fileName);
        CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(plistName.c_str());//  plistName.c_str());
        allSpriteSheets->addObject(spriteSheet);
        
        /*1 sprite per char. */
        GameSprite* gs = GameSprite::create();
        gs->gender = targetGender;
        gs->race = targetRace;
        gs->spriteName = fileName;
        gs->baseSpriteName = fileName;
        gs->setFrameCount(targetIdleF, targetWalkF);
        gs->batchLayerIndex = i;
        gs->spriteClass = targetClass;
        gs->setAIConfig(configContent);
        gs->setDefaultsConfig(defaultContent);
        gs->villagerClass = villagerClass;
        
        allSprites->addObject(gs);
        configContent = "";
    }
    
    for(int i = 0; i < V_CLASS_END; i++)
    {
        std::string configContent;
        std::string defaultContent;
        std::string targetClass;
        VillagerClass villagerClass;
        
        switch (i)
        {
            case 0:
                configContent = refugeeConfig;
                defaultContent = refugeeDefaults;
                targetClass = "refugee";
                villagerClass = V_REFUGEE;
                break;
            case 1:
                configContent = citizenConfig;
                defaultContent = citizenDefaults;
                targetClass = "citizen";
                villagerClass = V_CITIZEN;
                break;
            case 2:
                configContent = farmerConfig;
                defaultContent = farmerDefaults;
                targetClass = "farmer";
                villagerClass = V_FARMER;
                break;
            case 3:
                configContent = builderConfig;
                defaultContent = builderDefaults;
                targetClass = "builder";
                villagerClass = V_BUILDER;
                break;
            case 4:
                configContent = soldierConfig;
                defaultContent = soldierDefaults;
                targetClass = "soldier";
                villagerClass = V_SOLDIER;
                break;
            case 5:
                configContent = banditConfig;
                defaultContent = banditDefaults;
                targetClass = "bandit";
                villagerClass = V_BANDIT;
                break;
            case 6:
                configContent = marketerConfig;
                defaultContent = marketerDefaults;
                targetClass = "marketer";
                villagerClass = V_MARKET;
            default:
                break;
        }
        
        SpriteClass* spriteClass = new SpriteClass();
        spriteClass->configContent = configContent;
        spriteClass->defaultContent = defaultContent;
        spriteClass->targetClass = targetClass;
        spriteClass->villagerClass = villagerClass;
        allSpriteClass->addObject(spriteClass);
    }
}
Esempio n. 12
0
void Face_Parse( face_t *face, bool bAlternateTexdef = false ){
	int i, j;
	char *str;
	bool bworldcraft = false;

	char *token = Token();

	// parse planepts
	str = NULL;
	for ( i = 0; i < 3; i++ )
	{
		GetToken( true ); //(
		for ( j = 0; j < 3; j++ )
		{
			GetToken( false );
			face->planepts[i][j] = atof( token );
		}
		GetToken( false ); //)
	}

	if ( bAlternateTexdef ) {
		// parse alternate texdef
		GetToken( false ); // (
		GetToken( false ); // (
		for ( i = 0; i < 3; i++ )
		{
			GetToken( false );
			face->brushprimit_texdef.coords[0][i] = atof( token );
		}
		GetToken( false ); // )
		GetToken( false ); // (
		for ( i = 0; i < 3; i++ )
		{
			GetToken( false );
			face->brushprimit_texdef.coords[1][i] = atof( token );
		}
		GetToken( false ); // )
		GetToken( false ); // )
	}


	// parse shader name
	GetToken( false ); // shader

	// if we're loading a halflife map then we don't have a relative texture name
	// we just get <texturename>.  So we need to convert this to a relative name
	// like this: "textures/<wadname>/shader", so we use vfsFileFile to get the filename.

	// *** IMPORTANT ***
	// For Halflife we need to see if the texture is in wads listed in the
	// map's worldspawn "wad" e-pair.  If we don't then the image used will be the
	// first image with this texture name that is found in any of the wads on the
	// user's system.  this is not a huge problem, because the map compiler obeys
	// the "wad" epair when compiling the map, but the user might end up looking at
	// the wrong texture in the editor. (more of a problem if the texture we use
	// here has a different size from the one in the wad the map compiler uses...)

	// Hydra: - TTimo: I looked all over for other places to put this, but really it
	// is an issue with map loading (because of a limitation of halflife/q2 map format)
	// so it's gone in here, it also stops incorrect shader/texdef names getting used
	// in the radiant core and it's modules which we'd only have to change later on.
	// (either in map_importentities() or the shader module).  so it's actually cleaner
	// in the long run, even if a little odd.  And it keeps more game specific stuff
	// OUT of the core, which is a good thing.

	if ( g_MapVersion == MAPVERSION_HL ) {
		qboolean done = false;

		// FIXME: This bit is halflife specific.
		// look in the list of wads supplied in the worldspawn "wad" key/pair for the
		// texture first, if it's not in any then we carry on searching the vfs for it
		// as usual.

		// each time we find a texture, we add it to the a cache
		// so we don't have to hunt the vfs for it each time.
		// See SearchWadsForTextureName() and AddToCache() above for cache stuff

		char *wadname;
		wadname = SearchWadsForTextureName( token );

		if ( wadname ) {
			face->texdef.SetName( wadname );
			done = true;
		}
		else
		{
			// using the cache below means that this message is only ever printed out once!
			Sys_Printf( "WARNING: could not find \"%s\" in any listed wad files, searching all wad files instead!\n",token );
		}
		// end of half-life specific bit.

		// check the cache!
		if ( !done ) {
			str = CheckCacheForTextureName( token );
			if ( str ) {
				face->texdef.SetName( str );
				done = true;
			}
		}

		if ( !done ) {
			char *fullpath;

			str = new char[strlen( token ) + 4 + 1];

			// FIXME: halflife specific file extension, we'll have to support Q2/Q1 formats
			// and maybe tga texture format for HL here too..
			sprintf( str,"%s.hlw",token );
			fullpath = vfsGetFullPath( str,0,VFS_SEARCH_PAK | VFS_SEARCH_DIR );

			// MIP support for quake
			if ( !fullpath ) {
				sprintf( str,"%s.mip",token );
				fullpath = vfsGetFullPath( str, 0, 0 );
			}

			// TGA support in halflife ?
			/*
			   if (!fullpath)
			   {
			   sprintf(str,"%s.tga",token);
			   fullpath = vfsGetFullPath(str);
			   }
			 */
			delete [] str;

			if ( fullpath ) {
				// strip the extension.
				int len = strlen( fullpath );
				if ( fullpath[len - 4] == '.' ) {
					fullpath[len - 4] = '\0';
				}

				// and set the correct name!
				face->texdef.SetName( fullpath );
				AddToCache( token,fullpath );
			}
			else
			{
				Sys_Printf( "WARNING: could not find \"%s\" in the vfs search path\n",token );
				str = new char[strlen( token ) + 10];
				strcpy( str, "textures/" );
				strcpy( str + 9, token );
				face->texdef.SetName( str );
				AddToCache( token,str );
				delete [] str;
			}
		}
	}
	else // !MAPVERSION_HL
	{
		str = new char[strlen( token ) + 10];
		strcpy( str, "textures/" );
		strcpy( str + 9, token );
		face->texdef.SetName( str );
		delete [] str;
	}

	if ( !bAlternateTexdef ) {
		if ( g_MapVersion == MAPVERSION_HL ) { // Q1 as well ?
			GetToken( false );
			if ( token[0] == '[' && token[1] == '\0' ) {
				bworldcraft = true;

				GetToken( false ); // UAxis[0]
				GetToken( false ); // UAxis[1]
				GetToken( false ); // UAxis[2]

				GetToken( false ); // shift
				face->texdef.shift[0] = atof( token );

				GetToken( false ); // ]

				GetToken( false ); // [
				GetToken( false ); // VAxis[0]
				GetToken( false ); // VAxis[1]
				GetToken( false ); // VAxis[2]

				GetToken( false ); // shift
				face->texdef.shift[1] = atof( token );

				GetToken( false ); // ]

				// rotation is derived from the U and V axes.
				// ZHLT ignores this setting even if present in a .map file.
				GetToken( false );
				face->texdef.rotate = atof( token );

				// Scales
				GetToken( false );
				face->texdef.scale[0] = atof( token );
				GetToken( false );
				face->texdef.scale[1] = atof( token );
			}
			else
			{
				UnGetToken();
			}
		}

		if ( !bworldcraft ) { // !MAPVERSION_HL
			// parse texdef
			GetToken( false );
			face->texdef.shift[0] = atof( token );
			GetToken( false );
			face->texdef.shift[1] = atof( token );
			GetToken( false );
			face->texdef.rotate = atof( token );
			GetToken( false );
			face->texdef.scale[0] = atof( token );
			GetToken( false );
			face->texdef.scale[1] = atof( token );
		}
	}
	// parse the optional contents/flags/value
	if ( !bworldcraft && TokenAvailable() ) {
		GetToken( true );
		if ( isdigit( token[0] ) ) {
			face->texdef.contents = atoi( token );
			GetToken( false );
			face->texdef.flags = atoi( token );
			GetToken( false );
			face->texdef.value = atoi( token );
		}
		else
		{
			UnGetToken();
		}
	}
}