Ejemplo n.º 1
0
bool GfModule::unload(GfModule*& pModule)
{
	// Try and get the module closing function.
	std::string strShLibName = pModule->getSharedLibName();
	void* hShLibHandle = pModule->getSharedLibHandle();
	tModCloseFunc modCloseFunc = (tModCloseFunc)dlsym(hShLibHandle, pszCloseModuleFuncName);
    if (!modCloseFunc)
    {
		GfLogWarning("Library %s doesn't export any '%s' function' ; not called\n",
					 strShLibName.c_str(), pszCloseModuleFuncName);
	}

	// Call the module closing function (must delete the module instance).
	if (modCloseFunc())
	{
		GfLogWarning("Library %s '%s' function call failed ; going on\n",
					 strShLibName.c_str(), pszCloseModuleFuncName);
	}
	
	// Make it clear that the passed pointer is no more usable (it was deleted).
	pModule = 0; 
	
	// Try and close the shared library.
	if (dlclose(hShLibHandle))
	{
		GfLogWarning("Failed to unload library %s (%s) ; \n",
					 strShLibName.c_str(), lastDLErrorString().c_str());
		return false;
	}
	
	GfLogTrace("Module %s unloaded\n", strShLibName.c_str());

	return true;
}
Ejemplo n.º 2
0
bool
linuxSetThreadAffinity(int nCPUId)
{
	// MacOS X, FreeBSD, OpenBSD, NetBSD, etc ...
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
	
	GfLogWarning("Thread affinity not yet implemented on Mac OS X or BSD.\n");
	// TODO.
	
	// Linux, Solaris, AIX ... with NPTL (Native POSIX Threads Library)
#elif defined(linux) || defined(__linux__)
	
	// Get the handle for the current thread.
	pthread_t hCurrThread = pthread_self();
	
	// Determine the affinity mask to set for the current thread.
	cpu_set_t nThreadAffinityMask;
	CPU_ZERO(&nThreadAffinityMask);
	if (nCPUId == GfAffinityAnyCPU)
	{
		// No special affinity on any CPU => set "system" affinity mask
		// (1 bit for each installed CPU).
		for (int nCPUIndex = 0; (unsigned)nCPUIndex < linuxGetNumberOfCPUs(); nCPUIndex++)
		{
			CPU_SET(nCPUIndex, &nThreadAffinityMask);
		}
	}
	else
	{	
		// Affinity on a specified CPU => compute its mask.
		CPU_SET(nCPUId, &nThreadAffinityMask);
	}
	
	// Set the affinity mask for the current thread ("stick" it to the target core).
	if (pthread_setaffinity_np(hCurrThread, sizeof(nThreadAffinityMask), &nThreadAffinityMask))
	{
		GfLogError("Failed to set current pthread (handle=0x%X) affinity on CPU(s) %s (%s)\n",
				   hCurrThread, cpuSet2String(&nThreadAffinityMask).c_str(), strerror(errno));
		return false;
	}
	else
		GfLogInfo("Affinity set on CPU(s) %s for current pthread (handle=0x%X)\n",
				  cpuSet2String(&nThreadAffinityMask).c_str(), hCurrThread);
	
	return true;
	
	// Anything else ... not supported.
#else
	
#warning "linuxspec.cpp::linuxSetThreadAffinity : Unsupported Linux OS"
	GfLogWarning("Thread affinity not yet implemented on this unknown Unix.\n");
	
#endif
	
	return false;
}
Ejemplo n.º 3
0
int
ReRaceEventInit(void)
{
	void *mainParams = ReInfo->mainParams;
	void *params = ReInfo->params;

	const bool careerMode = strcmp(GfParmGetStr(ReInfo->mainParams, RM_SECT_SUBFILES, RM_ATTR_HASSUBFILES, RM_VAL_NO), RM_VAL_YES) == 0;
	
	/* Career mode : Look if it is necessary to open another file */
	if (strcmp(GfParmGetStr(mainParams, RM_SECT_SUBFILES, RM_ATTR_HASSUBFILES, RM_VAL_NO), RM_VAL_YES) == 0)
	{
		/* Close previous params */
		if (params != mainParams)
			GfParmReleaseHandle(params);

		/* Read the new params */
		ReInfo->params = GfParmReadFile( GfParmGetStr( ReInfo->mainResults, RE_SECT_CURRENT, RE_ATTR_CUR_FILE, "" ), GFPARM_RMODE_STD );
		GfLogTrace("Career : New params file is %s (from main results file)\n",
				   GfParmGetStr( ReInfo->mainResults, RE_SECT_CURRENT, RE_ATTR_CUR_FILE, ""));
		if (!ReInfo->params)
			GfLogWarning( "Career : MainResults params weren't read correctly\n" );

		/* Close previous results */
		if (ReInfo->results != ReInfo->mainResults)
		{
			GfParmWriteFile(NULL, ReInfo->results, NULL);
			GfParmReleaseHandle(ReInfo->results);
		}

		/* Read the new results */
		ReInfo->results = GfParmReadFile( GfParmGetStr( ReInfo->params, RM_SECT_SUBFILES, RM_ATTR_RESULTSUBFILE, ""), GFPARM_RMODE_STD );
		if (!ReInfo->results)
			GfLogWarning( "Career : New results weren't read correctly\n" );
	}

	// Initialize the race session name.
	ReInfo->_reRaceName = ReGetCurrentRaceName();
	GfLogInfo("Starting new event (%s session)\n", ReInfo->_reRaceName);

	ReUI().onRaceEventInitializing();
	
	ReInfo->s->_features = RmGetFeaturesList(ReInfo->params);

	ReTrackInit();
	
	ReEventInitResults();

	NoCleanupNeeded = false;

	const bool bGoOnLooping = ReUI().onRaceEventStarting(careerMode && !ReHumanInGroup());

	return (bGoOnLooping ? RM_SYNC : RM_ASYNC) | RM_NEXT_STEP;
}
Ejemplo n.º 4
0
/*
* Function
*	linuxGetOSInfo
*
* Description
*	Get some info about the running OS (name, x.y.z release, and nb of bits).
*
* Parameters
*	strName : target string  for the OS name ("" if any error occurred)
*	nMajor  : target OS major version integer (-1 if could not be obtained)
*	nMinor  : target OS minor version integer (-1 if could not be obtained)
*	nPatch  : target OS patch version integer (-1 if could not be obtained)
*	nBits   : target OS number of bits (32 or 64) integer (or -1 if could not be obtained)
*
* Return
*	True if OK, False otherwise.
*/
static bool
linuxGetOSInfo(std::string& strName, int& nMajor, int& nMinor, int& nPatch, int& nBits)
{
	struct utsname utsName;
	if(uname(&utsName) < 0)
	{
		const int errnum = errno; // Get errno before it is overwritten by some system call.
		GfLogWarning("Could not get OS info through uname (%s).\n", strerror(errnum));
		return false;
	}
	
	//GfLogDebug("linuxGetOSInfo : name='%s', version='%s', release='%s'\n",
	//		   utsName.sysname, utsName.version, utsName.release);
	strName = utsName.sysname;
	strName += " ";
	strName += utsName.release;
	strName += " ";
	strName += utsName.version;
	const int nNums = sscanf(utsName.release, "%d.%d.%d", &nMajor, &nMinor, &nPatch);
	if (nNums < 1)
		nMajor = -1;
	if (nNums < 2)
		nMinor = -1;
	if (nNums < 3)
		nPatch = -1;
	nBits = strstr(utsName.release, "64") ? 64 : 32;
	
	return true;
}
Ejemplo n.º 5
0
void NetClient::ConnectToDriver(NetDriver driver)
{
    char hostName[256];
    enet_address_get_host_ip (&driver.address,hostName,256);

    if (!driver.client)
    {
        GfLogTrace("Skipping server: %s Address: %s\n",driver.name,hostName);
        return;
    }

    if (strcmp(driver.name,GetDriverName())==0)
    {
        GfLogTrace("Skipping ourself: %s Address:  %s\n",driver.name,hostName);
        return;
    }

    ENetPeer * pCurrentPeer;

    for (pCurrentPeer = m_pClient-> peers;
            pCurrentPeer < & m_pClient->peers [m_pClient->peerCount];
            ++ pCurrentPeer)
    {
        if (pCurrentPeer->state == ENET_PEER_STATE_CONNECTED)
        {
            if ((pCurrentPeer->address.host == driver.address.host)&&
                    (pCurrentPeer->address.port == driver.address.port))
            {
                GfLogTrace("Already connected to driver: %s Address: %s\n",driver.name,hostName);
                return;
            }
        }

    }

    GfLogTrace("connecting to driver: %s Address: %s\n",driver.name,hostName);

    //Connect to peer player
    //ENetPeer *pPeer = enet_host_connect (m_pClient, &driver.address, 2);



    ENetEvent event;

    if (enet_host_service (m_pClient, & event, 5000) > 0 &&
            event.type == ENET_EVENT_TYPE_CONNECT)
    {
        GfLogTrace("Successfully connected to peer\n");
        return;
    }
    else
    {
        //char hostName[256];
        //enet_address_get_host_ip (&event.peer->address,hostName,256);
        GfLogWarning("Failed to connect to peer! (%X)\n", &event.peer->address);
        return;
    }

}
Ejemplo n.º 6
0
bool GfTrack::load() const
{
	// Check if the track loader is ready.
	ITrackLoader* piTrackLoader = GfTracks::self()->getTrackLoader();
    if (!piTrackLoader)
	{
		GfLogError("Track loader not yet initialized ; failed to load any track\n");
        return false;
    }
	
    // Load track data from the XML file.
    tTrack* pTrack = piTrackLoader->load(_strDescFile.c_str());
    if (!pTrack)
	{
		GfLogWarning("Unusable track %s : failed to build track data from %s\n",
					 _strId.c_str(), _strDescFile.c_str());
        return false;
    }

	// Check if the track 3D model file exists.
	std::ostringstream ossFileName;
	ossFileName << "tracks/" << _strCatId << '/' << _strId << '/'
				<< (pTrack->graphic.model3d ? pTrack->graphic.model3d : "track.ac");
    if (!GfFileExists(ossFileName.str().c_str()))
	{
		GfLogWarning("Unusable track %s : could not find 3D model %s\n",
					 _strId.c_str(), ossFileName.str().c_str());
        return false;
    }

	// All right now : let's read last needed infos.
	_strName = pTrack->name;
	_strDesc = pTrack->descr;
	_strAuthors = pTrack->authors;
	_fLength = pTrack->length;
	_fWidth = pTrack->width;
	_nMaxPitSlots = pTrack->pits.nMaxPits;

    // Unload track data.
    piTrackLoader->unload();

	// Now, the track seems usable (hm ... OK, we didn't check the 3D file contents ...).
	_bUsable = true;
	
	return true;
}
Ejemplo n.º 7
0
bool ReSituation::unlock(const char* pszCallerName)
{
	if (!_pMutex)
		return true;
	
	const bool bStatus = SDL_mutexV(_pMutex) == 0;
	if (!bStatus)
		GfLogWarning("%s : Failed to unlock situation mutex\n", pszCallerName);

	return bStatus;
}
Ejemplo n.º 8
0
static void loadSimuCfg(void)
{
	const char *simuVersionName;
	const char *multiThreadSchemeName;
	const char *threadAffinitySchemeName;
	int i;

	char buf[1024];
	snprintf(buf, sizeof(buf), "%s%s", GfLocalDir(), RACE_ENG_CFG);

	void *paramHandle = GfParmReadFile(buf, GFPARM_RMODE_REREAD | GFPARM_RMODE_CREAT);

	// Simulation engine name.
	simuVersionName = GfParmGetStr(paramHandle, RM_SECT_MODULES, RM_ATTR_MOD_SIMU, SimuVersionList[DefaultSimuVersion]);
	for (i = 0; i < NbSimuVersions; i++) {
		if (strcmp(simuVersionName, SimuVersionList[i]) == 0) {
			CurSimuVersion = i;
			break;
		}
	}

	// Check if the selected simulation module is there, and fall back to the default one if not.
	snprintf(buf, sizeof(buf), "%smodules/simu/%s.%s", GfLibDir(), SimuVersionList[CurSimuVersion], DLLEXT);
	if (!GfFileExists(buf))
	{
		GfLogWarning("User settings %s physics engine module not found ; falling back to %s\n",
					 SimuVersionList[CurSimuVersion], SimuVersionList[DefaultSimuVersion]);
		CurSimuVersion = DefaultSimuVersion;
	}

	// Multi-threading.
	multiThreadSchemeName = GfParmGetStr(paramHandle, RM_SECT_RACE_ENGINE, RM_ATTR_MULTI_THREADING, MultiThreadSchemeList[0]);
	for (i = 0; i < NbMultiThreadSchemes; i++) {
		if (strcmp(multiThreadSchemeName, MultiThreadSchemeList[i]) == 0) {
			CurMultiThreadScheme = i;
			break;
		}
	}

	// Thread affinity.
	threadAffinitySchemeName = GfParmGetStr(paramHandle, RM_SECT_RACE_ENGINE, RM_ATTR_THREAD_AFFINITY, ThreadAffinitySchemeList[0]);
	for (i = 0; i < NbThreadAffinitySchemes; i++) {
		if (strcmp(threadAffinitySchemeName, ThreadAffinitySchemeList[i]) == 0) {
			CurThreadAffinityScheme = i;
			break;
		}
	}

	GfParmReleaseHandle(paramHandle);

	GfuiLabelSetText(ScrHandle, SimuVersionId, SimuVersionDispNameList[CurSimuVersion]);
	GfuiLabelSetText(ScrHandle, MultiThreadSchemeId, MultiThreadSchemeList[CurMultiThreadScheme]);
	GfuiLabelSetText(ScrHandle, ThreadAffinitySchemeId, ThreadAffinitySchemeList[CurThreadAffinityScheme]);
}
Ejemplo n.º 9
0
static void
rmToggleMovieCapture(void * /* dummy */)
{
    if (!rmMovieCapture.enabled) 
    {
		GfLogWarning("Movie capture is not enabled : command ignored\n");
		return;
    }
    
    if (!(LmRaceEngine().outData()->_displayMode & RM_DISP_MODE_NORMAL))
    {
		GfLogWarning("Movie capture is available only in normal display mode : command ignored\n");
		return;
    }
    
    rmMovieCapture.active = !rmMovieCapture.active;
    if (rmMovieCapture.active)
	{
		// Try and change the race engine scheduling scheme for movie capture.
		if (LmRaceEngine().setSchedulingSpecs(rmMovieCapture.simuRate, rmMovieCapture.frameRate))
		{
			rmMovieCapture.currentFrame = 0;
			rmMovieCapture.currentCapture++;
			GfLogInfo("Starting movie capture\n");
		}
		else
		{
			// Not supported (multi-threaded mode).
			rmMovieCapture.active = false;
			GfLogWarning("Movie capture not supported in multi-threaded mode : command ignored\n");
		}
    }
	else
	{
		GfLogInfo("Stopping movie capture\n");
		LmRaceEngine().setSchedulingSpecs(1.0 / RCM_MAX_DT_SIMU);
		LmRaceEngine().start(); // Resynchronize the race engine.
    }
}
Ejemplo n.º 10
0
/*
* Function
*	linuxGetNumberOfCPUs
*
* Description
*	Retrieve the actual number of CPUs in the system
*       Note that a core is considered here as a "CPU", and an Intel hyper-threaded processor
*       will report twice as many "CPUs" as actual cores ...
*
* Parameters
*	None
*
* Return
*	The number of CPUs in the system
*
* Remarks
*       WARNING: Not tested under platforms other than Linux : Mac OS X, BSD, Solaris, AIX.
*	
*/
unsigned linuxGetNumberOfCPUs()
{
	static unsigned nCPUs = 0;
	
	if (nCPUs == 0)
	{
		
		// MacOS X, FreeBSD, OpenBSD, NetBSD, etc ...
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
		
		nt mib[4];
		size_t len; 
		
		// Set the mib for hw.ncpu
		
		// Get the number of CPUs from the system
		// 1) Try HW_AVAILCPU first.
		mib[0] = CTL_HW;
		mib[1] = HW_AVAILCPU;  // alternatively, try HW_NCPU;
		sysctl(mib, 2, &nCPUs, &len, NULL, 0);
		
		if (nCPUs < 1) 
		{
			// 2) Try alternatively HW_NCPU.
			mib[1] = HW_NCPU;
			sysctl(mib, 2, &nCPUs, &len, NULL, 0);
		}
		
		// Linux, Solaris, AIX
#elif defined(linux) || defined(__linux__)
		
		nCPUs = (unsigned)sysconf(_SC_NPROCESSORS_ONLN);
		
		// Anything else ... not supported.
#else
		
#warning "Unsupported Linux OS"
		
#endif
		
		if (nCPUs < 1)
		{
			GfLogWarning("Could not get the number of CPUs here ; assuming only 1\n");
			nCPUs = 1;
		}
		else
			GfLogInfo("Detected %d CPUs\n", nCPUs);
	}
	
	return nCPUs;
}
Ejemplo n.º 11
0
// Restore the race from the given results file
void
ReRaceRestore(void* hparmResults)
{
	// Update race engine info in order to set it in the exact state
	// it was in when the race mode was saved.
	GfRace* pRace = StandardGame::self().race();
	ReInfo->mainParams = pRace->getManager()->getDescriptorHandle();
	ReInfo->mainResults = pRace->getResultsDescriptorHandle();
	if (!pRace->getManager()->hasSubFiles())
	{
		// Non-Career mode.
		ReInfo->params = ReInfo->mainParams;
		ReInfo->results = ReInfo->mainResults;
		ReInfo->_reRaceName = pRace->getSessionName().c_str(); //ReInfo->_reName;
	}
	else
	{
		// Career mode : More complicated, as everything is not in one params/results file
		// (the target state is right after the end of the previous event,
		//  which was from the previous group).
		const char* pszPrevParamsFile =
			GfParmGetStr(ReInfo->mainResults, RE_SECT_CURRENT, RE_ATTR_PREV_FILE, 0);
		if (!pszPrevParamsFile)
			GfLogWarning("Career : No previous file in MainResults\n");
		ReInfo->params =
			pszPrevParamsFile ? GfParmReadFile(pszPrevParamsFile, GFPARM_RMODE_STD) : ReInfo->mainParams;
		const char* pszPrevResultsFile =
			GfParmGetStr(ReInfo->params, RM_SECT_SUBFILES, RM_ATTR_RESULTSUBFILE, 0);
		if (!pszPrevResultsFile)
			GfLogWarning("Career : Failed to load previous results from previous params\n");
		ReInfo->results = 
			pszPrevResultsFile ? GfParmReadFile(pszPrevResultsFile, GFPARM_RMODE_STD) : ReInfo->mainResults;
		ReInfo->_reRaceName = ReGetPrevRaceName(/* bLoop = */true);
	}

	GfParmRemoveVariable(ReInfo->params, "/", "humanInGroup");
	GfParmSetVariable(ReInfo->params, "/", "humanInGroup", ReHumanInGroup() ? 1.0f : 0.0f);
}
Ejemplo n.º 12
0
// TODO: Tests (not yet used, see #809).
std::vector<GfModule*> GfModule::loadFromDir(const std::string& strDirPath,
											 bool bUseChildDirs)
{
	std::vector<GfModule*> vecModules;

	GfLogDebug("GfModule::loadFromDir(%s)\n", strDirPath.c_str());

	// Get the list of files/sub-dirs in the folder.
	tFList* lstFilesOrDirs = GfDirGetList(strDirPath.c_str());
	if (lstFilesOrDirs)
	{
		// Filter module shared libraries and try and load each of them.
		tFList* pFileOrDir = lstFilesOrDirs;
		do 
		{
			// Ignore "." and ".." folders.
			if (pFileOrDir->name[0] == '.') 
				continue;
			
			GfLogDebug("  Examining %s\n", pFileOrDir->name);
		
			// Build module shared library path-name (consider only foders, not files).
			std::ostringstream ossShLibPath;
			ossShLibPath << strDirPath << '/' << pFileOrDir->name;
			if (bUseChildDirs)
				ossShLibPath << '/' << pFileOrDir->name;
			ossShLibPath << DLLEXT;

			// Check existence.
			if (!GfFileExists(ossShLibPath.str().c_str()))
				continue;

			// Try and load.
			GfModule* pModule = GfModule::load(ossShLibPath.str().c_str());
			if (pModule)
				vecModules.push_back(pModule);
			else
				GfLogWarning("Failed to load module %s\n", ossShLibPath.str().c_str());
			
		}
		while ((pFileOrDir = pFileOrDir->next) != lstFilesOrDirs);
	}
	
	return vecModules;
}
Ejemplo n.º 13
0
bool 
GfuiMenuCreateStaticControls(void* hscr, void* hparm)
{
	if (!hparm)
	{
		GfLogError("Failed to create static controls (XML menu descriptor not yet loaded)\n");
		return false;
	}

    char buf[32];

    for (int i = 1; i <= GfParmGetEltNb(hparm, GFMNU_SECT_STATIC_CONTROLS); i++)
    {
		snprintf(buf, sizeof(buf), GFMNU_SECT_STATIC_CONTROLS"/%d", i);
		const char* pszType = GfParmGetStr(hparm, buf, GFMNU_ATTR_TYPE, "");
    
		if (!strcmp(pszType, GFMNU_TYPE_LABEL))
		{
			createLabel(hscr, hparm, buf);
		}
		else if (!strcmp(pszType, GFMNU_TYPE_STATIC_IMAGE))
		{
			createStaticImage(hscr, hparm, buf);
		}
		else if (!strcmp(pszType, GFMNU_TYPE_BACKGROUND_IMAGE))
		{
			createBackgroundImage(hscr, hparm, buf);
		}
		else
		{
			GfLogWarning("Failed to create static control '%s' of unknown type '%s'\n",
						 buf, pszType);
		}
    }
	 
	 // while not truly a static control (visually), each menu/screen can have
	 // background music. As 'GfuiMenuCreateStaticControls()' is called on load
	 // of each menu, this was deemed the least intrusive place to add the
	 // music filename to the screen's struct.
	 createMusic(hscr,hparm);
    return true;
}
Ejemplo n.º 14
0
// Physics engine management.
bool StandardGame::loadPhysicsEngine()
{
    // Load the Physics engine module if not already done.
	if (_piPhysEngine)
		return true;

	// 1) Get the physics engine name from user settings (default: Simu V4.0)
	static const char* pszDefaultModName = RM_VAL_MOD_SIMU_V4;
	std::string strModName =
		GfParmGetStr(ReSituation::self().data()->_reParam, "Modules", "simu", pszDefaultModName);

	// 2) Check if the module is really there, and fall back to the default one if not
	//    Note : The default module is supposed to be always there.
	if (!GfModule::isPresent("simu", strModName.c_str()))
	{
		GfLogWarning("User settings %s physics engine module not found ; "
					 "falling back to %s\n", strModName.c_str(), pszDefaultModName);
		strModName = pszDefaultModName;
	}

	// 3) Load it.
	std::ostringstream ossLoadMsg;
	ossLoadMsg << "Loading physics engine (" << strModName << ") ...";
	if (_piUserItf)
		_piUserItf->addLoadingMessage(ossLoadMsg.str().c_str());

	GfModule* pmodPhysEngine = GfModule::load("modules/simu", strModName.c_str());
	if (pmodPhysEngine)
		_piPhysEngine = pmodPhysEngine->getInterface<IPhysicsEngine>();
	if (pmodPhysEngine && !_piPhysEngine)
		GfModule::unload(pmodPhysEngine);

	// don't record if we're 'replaying'
	printf("Checking type of SIMU\n");
	if (strcmp(RM_VAL_MOD_SIMU_REPLAY, strModName.c_str()) == 0)
		replayReplay = 1;
	else
		replayReplay = 0;

	return _piPhysEngine ? true : false;
}
Ejemplo n.º 15
0
void LegacyMenu::shutdownGraphics(bool bUnloadModule)
{
    // Do nothing if the module has already been unloaded.
    if (!_piGraphicsEngine)
        return;

    if (bUnloadModule)
	{
        // Unload the graphics module.
        GfModule* pmodGrEngine = dynamic_cast<GfModule*> (_piGraphicsEngine);
#ifndef UNLOAD_SSGGRAPH
        if (pmodGrEngine->getSharedLibName().find("ssggraph") == std::string::npos)
#endif
            GfModule::unload(pmodGrEngine);

        // And remember it was.
        _piGraphicsEngine = 0;
    }

    // A little consistency check.
    if (_bfGraphicsState)
        GfLogWarning("Graphics shutdown procedure not smartly completed (state = 0x%x)\n",
					 _bfGraphicsState);
}
Ejemplo n.º 16
0
void GfDrivers::reload()
{
	// Clear all.
	clear();
	
	// (Re)Load robot modules from the "drivers" installed folder.
	std::string strDriversDirName(GfLibDir());
	strDriversDirName += "drivers";

    tModList* lstDriverModules = 0;
    const int nDriverModules = GfModInfoDir(CAR_IDENT, strDriversDirName.c_str(), 1, &lstDriverModules);
	if (nDriverModules <= 0 || !lstDriverModules)
	{
		GfLogFatal("Could not load any driver module from %s", strDriversDirName.c_str());
		return;
	}
	
	// For each module found, load drivers information.
    tModList *pCurModule = lstDriverModules;
	do
	{
		pCurModule = pCurModule->next;

		// Determine the module name.
		std::string strModName(pCurModule->sopath);
		strModName.erase(strlen(pCurModule->sopath) - strlen(DLLEXT) - 1); // Truncate file ext.
		const size_t nLastSlashInd = strModName.rfind('/');
		if (nLastSlashInd != std::string::npos)
			strModName = strModName.substr(nLastSlashInd+1); // Remove heading folder path.

		// Load the module XML descriptor file (try  user settings first, and then installed one)
		std::ostringstream ossRobotFileName;
		ossRobotFileName << GfLocalDir() << "drivers/" << strModName
						 << '/' << strModName << PARAMEXT;
		void *hparmRobot =
			GfParmReadFile(ossRobotFileName.str().c_str(), GFPARM_RMODE_STD | GFPARM_RMODE_REREAD);
		if (!hparmRobot)
		{
			ossRobotFileName.str("");
			ossRobotFileName << "drivers/" << strModName << '/' << strModName << PARAMEXT;
			hparmRobot =
				GfParmReadFile(ossRobotFileName.str().c_str(), GFPARM_RMODE_STD | GFPARM_RMODE_REREAD);
		}
		if (!hparmRobot)
		{
			// Do not waste log with drivers that do not exists or do not have to exist!
			if (strncmp("dandroid",strModName.c_str(),8) == 0)
				continue;
			else if (strncmp("usr",strModName.c_str(),3) == 0)
				continue;
			else if (strncmp("replay",strModName.c_str(),6) == 0)
				continue;

			GfLogError("No usable '%s' driver (%s.xml not found or not readable)\n",
					   strModName.c_str(), strModName.c_str());
			continue;
		}

		// For each driver (= interface) "in" the module
		for (int nItfInd = 0; nItfInd < pCurModule->modInfoSize; nItfInd++)
		{
			// Ignore undefined drivers or showing an empty name
			if (!pCurModule->modInfo[nItfInd].name || pCurModule->modInfo[nItfInd].name[0] == '\0')
			{
				GfLogInfo("Ignoring '%s' driver #%d (not defined or empty name)\n",
							 strModName.c_str(), nItfInd);
				continue;
			}

			// Create the driver and load info from the XML file.
			GfDriver* pDriver = new GfDriver(strModName, pCurModule->modInfo[nItfInd].index,
											 pCurModule->modInfo[nItfInd].name, hparmRobot);

			// For human drivers, if the car was not found, select the 1st possible one.
			if (!pDriver->getCar() && pDriver->isHuman())
			{
				GfCar* pSubstCar = GfCars::self()->getCarsInCategory()[0]; // Should never fail.
				if (pSubstCar)
				{
					std::ostringstream ossDrvSecPath;
					ossDrvSecPath << ROB_SECT_ROBOTS << '/' << ROB_LIST_INDEX << '/'
								  << pCurModule->modInfo[nItfInd].index;
					const char* pszCarId =
						GfParmGetStr(hparmRobot, ossDrvSecPath.str().c_str(), ROB_ATTR_CAR, "");
					GfLogWarning("Changing '%s' driver '%s' (#%d) 's car to %s (default one '%s' not available)\n",
								 strModName.c_str(), pCurModule->modInfo[nItfInd].name,
								 pCurModule->modInfo[nItfInd].index, pSubstCar->getId().c_str(),
								 pszCarId);
					pDriver->setCar(pSubstCar);
				}
			}
			
			// Keep the driver only if he drives an existing car.
			if (pDriver->getCar())
			{
				// Update the GfDrivers singleton.
				_pPrivate->vecDrivers.push_back(pDriver);
				const std::pair<std::string, int> driverKey(pDriver->getModuleName(),
															pDriver->getInterfaceIndex());
				_pPrivate->mapDriversByKey[driverKey] = pDriver;
				if (std::find(_pPrivate->vecTypes.begin(), _pPrivate->vecTypes.end(),
							  pDriver->getType()) == _pPrivate->vecTypes.end())
					_pPrivate->vecTypes.push_back(pDriver->getType());
				if (std::find(_pPrivate->vecCarCategoryIds.begin(), _pPrivate->vecCarCategoryIds.end(),
							  pDriver->getCar()->getCategoryId()) == _pPrivate->vecCarCategoryIds.end())
					_pPrivate->vecCarCategoryIds.push_back(pDriver->getCar()->getCategoryId());
			}
			else
			{
				delete pDriver;
				
				std::ostringstream ossDrvSecPath;
				ossDrvSecPath << ROB_SECT_ROBOTS << '/' << ROB_LIST_INDEX << '/'
							  << pCurModule->modInfo[nItfInd].index;
				const char* pszCarId =
					GfParmGetStr(hparmRobot, ossDrvSecPath.str().c_str(), ROB_ATTR_CAR, "");
				GfLogInfo("Ignoring '%s' driver '%s' (#%d) (not defined or default car '%s' not available)\n",
							 strModName.c_str(), pCurModule->modInfo[nItfInd].name,
							 pCurModule->modInfo[nItfInd].index, pszCarId);
			}
		}
		
		// Close driver module descriptor file if open
		GfParmReleaseHandle(hparmRobot);
		
	} while (pCurModule != lstDriverModules);

	// Free the module list.
    GfModFreeInfoList(&lstDriverModules);

	// Sort the car category ids and driver types vectors.
	std::sort(_pPrivate->vecCarCategoryIds.begin(), _pPrivate->vecCarCategoryIds.end());
	std::sort(_pPrivate->vecTypes.begin(), _pPrivate->vecTypes.end());

	// Trace what we got.
	print();
}
Ejemplo n.º 17
0
std::vector<GfDriverSkin> GfDriver::getPossibleSkins(const std::string& strAltCarId) const
{
	const std::string strCarId = strAltCarId.empty() ? _pCar->getId() : strAltCarId;

	GfLogDebug("Checking skins for %s ...\n", strCarId.c_str());

	// Clear the skin and preview lists.
	std::vector<GfDriverSkin> vecPossSkins;

	// Get/check skins/skin targets/previews from the directories in the search path
	// WARNING: Must be consistent with the search paths used in grcar.cpp, grboard.cpp,
	//          grscene.cpp ... etc ... but it is not currently 100% achieved
	//          (pit door logos are not searched by the graphics engine
	//           in the car-dedicated folders ... so they may be "over-detected" here).
	std::ostringstream ossDirPath;
	ossDirPath << GfLocalDir() << "drivers/" << _strModName
			   << '/' << _nItfIndex << '/' << strCarId;
	getPossibleSkinsInFolder(strCarId, ossDirPath.str(), vecPossSkins);

	ossDirPath.str("");
	ossDirPath << GfLocalDir() << "drivers/" << _strModName
			   << '/' << _nItfIndex;
	getPossibleSkinsInFolder(strCarId, ossDirPath.str(), vecPossSkins);

	ossDirPath.str("");
	ossDirPath << GfLocalDir() << "drivers/" << _strModName
			   << '/' << strCarId;
	getPossibleSkinsInFolder(strCarId, ossDirPath.str(), vecPossSkins);

	ossDirPath.str("");
	ossDirPath << GfLocalDir() << "drivers/" << _strModName;
	getPossibleSkinsInFolder(strCarId, ossDirPath.str(), vecPossSkins);

	ossDirPath.str("");
	ossDirPath << "drivers/" << _strModName
			   << '/' << _nItfIndex << '/' << strCarId;
	getPossibleSkinsInFolder(strCarId, ossDirPath.str(), vecPossSkins);

	ossDirPath.str("");
	ossDirPath << "drivers/" << _strModName
			   << '/' << _nItfIndex;
	getPossibleSkinsInFolder(strCarId, ossDirPath.str(), vecPossSkins);

	ossDirPath.str("");
	ossDirPath << "drivers/" << _strModName
			   << '/' << strCarId;
	getPossibleSkinsInFolder(strCarId, ossDirPath.str(), vecPossSkins);

	ossDirPath.str("");
	ossDirPath << "drivers/" << _strModName;
	getPossibleSkinsInFolder(strCarId, ossDirPath.str(), vecPossSkins);

	ossDirPath.str("");
	ossDirPath << "cars/models/" << strCarId;
	getPossibleSkinsInFolder(strCarId, ossDirPath.str(), vecPossSkins);

	// If we have at least 1 skin, make sure that, if the standard one is inside,
	// it is the first one.
	if (!vecPossSkins.empty())
	{
		std::vector<GfDriverSkin>::iterator itSkin;
		for (itSkin = vecPossSkins.begin(); itSkin != vecPossSkins.end(); itSkin++)
		{
			if (itSkin->getName().empty() && itSkin != vecPossSkins.begin())
			{
				GfDriverSkin stdSkin = *itSkin;
				vecPossSkins.erase(itSkin);
				vecPossSkins.insert(vecPossSkins.begin(), stdSkin);
				break;
			}
		}
	}
	
	// If no skin was found, add the car's standard one
	// (that way, the skin list will never be empty, and that's safer)
	else
	{
		GfLogError("No skin at all found for '%s/%d/%s' : adding dummy '%s' one\n",
				   _strModName.c_str(), _nItfIndex, strCarId.c_str(), "standard");
		
		GfDriverSkin stdSkin;
		std::ostringstream ossPreviewName;
		ossPreviewName << "cars/models/" << strCarId << '/' << strCarId << pszPreviewTexSufx;
		stdSkin.setCarPreviewFileName(ossPreviewName.str());

		if (!GfFileExists(ossPreviewName.str().c_str()))
			GfLogWarning("No preview file %s found for dummy '%s' skin\n",
						 ossPreviewName.str().c_str(), "standard");

		vecPossSkins.push_back(stdSkin);
	}

	return vecPossSkins;
}
Ejemplo n.º 18
0
void GfDriver::getPossibleSkinsInFolder(const std::string& strCarId,
										const std::string& strFolderPath,
										std::vector<GfDriverSkin>& vecPossSkins) const
{
	//GfLogDebug("  getPossibleSkinsInFolder(%s, %s) ...\n",
	//		   strCarId.c_str(), strFolderPath.c_str());

	// Search for skinned livery files, and associated preview files if any.
	tFList *pLiveryFileList =
		GfDirGetListFiltered(strFolderPath.c_str(), strCarId.c_str(), pszLiveryTexExt);
	if (pLiveryFileList)
	{
		tFList *pCurLiveryFile = pLiveryFileList;
		do
		{
			pCurLiveryFile = pCurLiveryFile->next;

			// Extract the skin name from the livery file name.
			const int nSkinNameLen = // Expecting "<car name>-<skin name>.png"
				strlen(pCurLiveryFile->name) - strCarId.length() - 1 - strlen(pszLiveryTexExt);
			std::string strSkinName;
			if (nSkinNameLen > 0) // Otherwise, default/standard "<car name>.png"
			{
				strSkinName =
					std::string(pCurLiveryFile->name)
					.substr(strCarId.length() + 1, nSkinNameLen);
				
				// Ignore skins with an excluded prefix.
				int nExclPrfxInd = 0;
				for (; nExclPrfxInd < nExcludedSkinNamePrefixes; nExclPrfxInd++)
					if (strSkinName.find(apszExcludedSkinNamePrefixes[nExclPrfxInd]) == 0)
						break;
				if (nExclPrfxInd < nExcludedSkinNamePrefixes)
					continue;
			}
			
			// Ignore skins that are already in the list (path search priority).
			if (findSkin(vecPossSkins, strSkinName) == vecPossSkins.end())
			{
				// Create the new skin.
				GfDriverSkin skin(strSkinName);

				// Add the whole car livery to the skin targets.
				skin.addTargets(RM_CAR_SKIN_TARGET_WHOLE_LIVERY);
				
				GfLogDebug("  Found %s%s livery\n",
						   strSkinName.empty() ? "standard" : strSkinName.c_str(),
						   strSkinName.empty() ? "" : "-skinned");
				
				// Add associated preview image, without really checking file existence
				// (warn only ; up to the client GUI to do what to do if it doesn't exist).
				std::ostringstream ossPreviewName;
				ossPreviewName << strFolderPath << '/' << strCarId;
				if (!strSkinName.empty())
					ossPreviewName << '-' << strSkinName;
				ossPreviewName << pszPreviewTexSufx;
				skin.setCarPreviewFileName(ossPreviewName.str());

				if (!GfFileExists(ossPreviewName.str().c_str()))
					GfLogWarning("Preview file not found for %s %s skin (%s)\n",
								 strCarId.c_str(), strSkinName.c_str(), ossPreviewName.str().c_str());
				//else
				//	GfLogDebug("* found skin=%s, preview=%s\n",
				//			   strSkinName.c_str(), ossPreviewName.str().c_str());

				// Add the new skin to the list.
				vecPossSkins.push_back(skin);
			}

		}
		while (pCurLiveryFile != pLiveryFileList);
	}
	
	GfDirFreeList(pLiveryFileList, NULL, true, true);
	
	// Search for skinned interior files, if any.
	std::string strInteriorPrefix(strCarId);
	strInteriorPrefix += pszInteriorTexSufx;
	tFList *pIntFileList =
		GfDirGetListFiltered(strFolderPath.c_str(), strInteriorPrefix.c_str(), pszInteriorTexExt);
	if (pIntFileList)
	{
		tFList *pCurIntFile = pIntFileList;
		do
		{
			pCurIntFile = pCurIntFile->next;

			// Extract the skin name from the interior file name.
			const int nSkinNameLen = // Expecting "<car name>-int-<skin name>.png"
				strlen(pCurIntFile->name) - strInteriorPrefix.length()
				- 1 - strlen(pszInteriorTexExt);
			std::string strSkinName;
			if (nSkinNameLen > 0)
			{
				strSkinName =
					std::string(pCurIntFile->name)
					.substr(strInteriorPrefix.length() + 1, nSkinNameLen);

				// If a skin with such name already exists in the list, update it.
				std::vector<GfDriverSkin>::iterator itSkin =
					findSkin(vecPossSkins, strSkinName);
				if (itSkin != vecPossSkins.end())
				{
					itSkin->addTargets(RM_CAR_SKIN_TARGET_INTERIOR);
					GfLogDebug("  Found %s-skinned interior (targets:%x)\n",
							   strSkinName.c_str(), itSkin->getTargets());
				}
			}
		}
		while (pCurIntFile != pIntFileList);
	}
	
	GfDirFreeList(pIntFileList, NULL, true, true);
	
	// Search for skinned logo files if any.
	tFList *pLogoFileList =
		GfDirGetListFiltered(strFolderPath.c_str(), pszLogoTexName, pszLogoTexExt);
	if (pLogoFileList)
	{
		tFList *pCurLogoFile = pLogoFileList;
		do
		{
			pCurLogoFile = pCurLogoFile->next;

			// Extract the skin name from the logo file name.
			const int nSkinNameLen = // Expecting "logo-<skin name>.png"
				strlen(pCurLogoFile->name) - strlen(pszLogoTexName)
				- 1 - strlen(pszLogoTexExt);
			if (nSkinNameLen > 0)
			{
				const std::string strSkinName =
					std::string(pCurLogoFile->name)
					.substr(strlen(pszLogoTexName) + 1, nSkinNameLen);
			
				// If a skin with such name already exists in the list, update it.
				std::vector<GfDriverSkin>::iterator itSkin = findSkin(vecPossSkins, strSkinName);
				if (itSkin != vecPossSkins.end())
				{
					itSkin->addTargets(RM_CAR_SKIN_TARGET_PIT_DOOR);
					GfLogDebug("  Found %s-skinned logo (targets:%x)\n",
							   strSkinName.c_str(), itSkin->getTargets());
				}
			}
				
		}
		while (pCurLogoFile != pLogoFileList);
	}
	
	GfDirFreeList(pLogoFileList, NULL, true, true);
	
	// Search for skinned 3D wheel files if any.
	tFList *pWheel3DFileList =
		GfDirGetListFiltered(strFolderPath.c_str(), pszWheel3DTexName, pszWheel3DTexExt);
	if (pWheel3DFileList)
	{
		tFList *pCurWheel3DFile = pWheel3DFileList;
		do
		{
			pCurWheel3DFile = pCurWheel3DFile->next;

			// Extract the skin name from the 3D wheel texture file name.
			const int nSkinNameLen = // Expecting "wheel3d-<skin name>.png"
				strlen(pCurWheel3DFile->name) - strlen(pszWheel3DTexName)
				- 1 - strlen(pszWheel3DTexExt);
			if (nSkinNameLen > 0)
			{
				const std::string strSkinName =
					std::string(pCurWheel3DFile->name)
					.substr(strlen(pszWheel3DTexName) + 1, nSkinNameLen);
			
				// If a skin with such name already exists in the list, update it.
				std::vector<GfDriverSkin>::iterator itSkin = findSkin(vecPossSkins, strSkinName);
				if (itSkin != vecPossSkins.end())
				{
					itSkin->addTargets(RM_CAR_SKIN_TARGET_3D_WHEELS);
					GfLogDebug("  Found %s-skinned 3D wheels (targets:%x)\n",
							   strSkinName.c_str(), itSkin->getTargets());
				}
			}
		}
		while (pCurWheel3DFile != pWheel3DFileList);
	}
	
	GfDirFreeList(pWheel3DFileList, NULL, true, true);
	
	// Search for skinned driver files if any.
	tFList *pDriverFileList =
		GfDirGetListFiltered(strFolderPath.c_str(), pszDriverTexName, pszDriverTexExt);
	if (pDriverFileList)
	{
		tFList *pCurDriverFile = pDriverFileList;
		do
		{
			pCurDriverFile = pCurDriverFile->next;

			// Extract the skin name from the 3D wheel texture file name.
			const int nSkinNameLen = // Expecting "driver-<skin name>.png"
				strlen(pCurDriverFile->name) - strlen(pszDriverTexName)
				- 1 - strlen(pszDriverTexExt);
			if (nSkinNameLen > 0)
			{
				const std::string strSkinName =
					std::string(pCurDriverFile->name)
					.substr(strlen(pszDriverTexName) + 1, nSkinNameLen);
			
				// If a skin with such name already exists in the list, update it.
				std::vector<GfDriverSkin>::iterator itSkin = findSkin(vecPossSkins, strSkinName);
				if (itSkin != vecPossSkins.end())
				{
					itSkin->addTargets(RM_CAR_SKIN_TARGET_DRIVER);
					GfLogDebug("  Found %s-skinned driver (targets:%x)\n",
							   strSkinName.c_str(), itSkin->getTargets());
				}
			}
		}
		while (pCurDriverFile != pDriverFileList);
	}
	
	GfDirFreeList(pDriverFileList, NULL, true, true);
}
Ejemplo n.º 19
0
void cgrSimpleState::setTexture(GLuint tex)
{
	GfLogWarning("Obsolete call: setTexture(GLuint tex)\n");
	
	ssgSimpleState::setTexture(tex);
}
Ejemplo n.º 20
0
GfTracks::GfTracks()
{
	_pPrivate = new GfTracks::Private;

	// Get the list of sub-dirs in the "tracks" folder (the track categories).
	tFList* lstCatFolders = GfDirGetList("tracks");
	if (!lstCatFolders)
	{
		GfLogFatal("No track category available in the 'tracks' folder\n");
		return;
	}
	
	tFList* pCatFolder = lstCatFolders;
	do 
	{
		//GfLogDebug("GfTracks::GfTracks() : Examining category %s\n", pCatFolder->name);
		
		// Ignore "." and ".." folders.
		const char* pszCatId = pCatFolder->name;
		if (pszCatId[0] == '.') 
			continue;
			
		// Get the list of sub-dirs in the "tracks" folder (the track categories).
		std::string strDirName("tracks/");
		strDirName += pszCatId;
		tFList* lstTrackFolders = GfDirGetList(strDirName.c_str());
		if (!lstTrackFolders)
		{
			GfLogWarning("No track available in the '%s' folder\n", strDirName.c_str());
			continue;
		}

		// Add new category.
		_pPrivate->vecCatIds.push_back(pszCatId);

		// Look at the tracks in this category.
		tFList* pTrackFolder = lstTrackFolders;
		do 
		{
			//GfLogDebug("GfTracks::GfTracks() : Examining track %s\n", pTrackFolder->name);
		
			// Determine and check the XML file of the track.
			const char* pszTrackId = pTrackFolder->name;
			
			std::ostringstream ossFileName;
			ossFileName << "tracks/" << pszCatId << '/' << pszTrackId
						<< '/' << pszTrackId << '.' << TRKEXT;
			const std::string strTrackFileName(ossFileName.str());
			if (!GfFileExists(strTrackFileName.c_str()))
			{
				GfLogInfo("Ignoring track %s : %s not found\n",
							 pszTrackId, strTrackFileName.c_str());
				continue;
			}

			// Get 1st level track info (those which don't need to open any file).
			ossFileName.str("");
			ossFileName << "tracks/" << pszCatId << '/' << pszTrackId
						<< '/' << pszTrackId << ".jpg";
			std::string strPreviewFileName(ossFileName.str());
			if (!GfFileExists(strPreviewFileName.c_str()))
			{
				ossFileName.str("");
				ossFileName << "tracks/" << pszCatId << '/' << pszTrackId
							<< '/' << pszTrackId << ".png";
				strPreviewFileName = ossFileName.str();
			}
			if (!GfFileExists(strPreviewFileName.c_str()))
				strPreviewFileName = "data/img/splash-trackselect.jpg";
			
			ossFileName.str("");
			ossFileName << "tracks/" << pszCatId << '/' << pszTrackId << '/' << "outline.png";
			std::string strOutlineFileName(ossFileName.str());
			if (!GfFileExists(strOutlineFileName.c_str()))
				strOutlineFileName = "data/img/notrackoutline.png";
			
			// Store track info in the GfTrack structure.
			GfTrack* pTrack = new GfTrack;
			pTrack->setId(pszTrackId);
			pTrack->setCategoryId(pszCatId);
			pTrack->setDescriptorFile(strTrackFileName);
			pTrack->setPreviewFile(strPreviewFileName);
			pTrack->setOutlineFile(strOutlineFileName);

			// Update the GfTracks singleton.
			_pPrivate->vecTracks.push_back(pTrack);
			_pPrivate->mapTracksById[pszTrackId] = pTrack;
		}
		while ((pTrackFolder = pTrackFolder->next) != lstTrackFolders);
		
		GfDirFreeList(lstTrackFolders, NULL, true, true);
	} 
	while ((pCatFolder = pCatFolder->next) != lstCatFolders);
	
	GfDirFreeList(lstCatFolders, NULL, true, true);
	
	// Sort the car category ids and driver types vectors.
	std::sort(_pPrivate->vecCatIds.begin(), _pPrivate->vecCatIds.end());

	// Trace what we got.
	print(false); // No verbose here, otherwise infinite recursion.
}
Ejemplo n.º 21
0
void
SimEngineConfig(tCar *car)
{
    void	*hdle = car->params;
    int		i;
    tdble	maxTq;
    tdble	rpmMaxTq = 0;
    char	idx[64];
    tEngineCurveElem *data;
    struct tEdesc {
	    tdble rpm;
	    tdble tq;
    } *edesc;


	car->engine.lastInterval = 0; // Initialize interval
    car->engine.revsLimiter = GfParmGetNum(hdle, SECT_ENGINE, PRM_REVSLIM, (char*)NULL, 800);
    car->carElt->_enginerpmRedLine = car->engine.revsLimiter;
    car->engine.revsMax     = GfParmGetNum(hdle, SECT_ENGINE, PRM_REVSMAX, (char*)NULL, 1000);
    car->carElt->_enginerpmMax = car->engine.revsMax;
    car->engine.tickover    = GfParmGetNum(hdle, SECT_ENGINE, PRM_TICKOVER, (char*)NULL, 150);
    car->engine.I           = GfParmGetNum(hdle, SECT_ENGINE, PRM_INERTIA, (char*)NULL, 0.2423f);
    car->engine.fuelcons    = GfParmGetNum(hdle, SECT_ENGINE, PRM_FUELCONS, (char*)NULL, 0.0622f);
    car->engine.brakeCoeff  = GfParmGetNum(hdle, SECT_ENGINE, PRM_ENGBRKCOEFF, (char*)NULL, 0.05f);
	car->engine.pressure = 0.0f;
	car->engine.exhaust_pressure = 0.0f;
	car->engine.exhaust_refract = 0.1f;
	car->engine.Tq_response = 0.0f;
    car->engine.I_joint = car->engine.I;
    sprintf(idx, "%s/%s", SECT_ENGINE, ARR_DATAPTS);
    car->engine.curve.nbPts = GfParmGetEltNb(hdle, idx);
    edesc = (struct tEdesc*)malloc((car->engine.curve.nbPts + 1) * sizeof(struct tEdesc));

    for (i = 0; i < car->engine.curve.nbPts; i++) {
		sprintf(idx, "%s/%s/%d", SECT_ENGINE, ARR_DATAPTS, i+1);
		edesc[i].rpm = GfParmGetNum(hdle, idx, PRM_RPM, (char*)NULL, car->engine.revsMax);
		edesc[i].tq  = GfParmGetNum(hdle, idx, PRM_TQ, (char*)NULL, 0);
    }
    edesc[i].rpm = edesc[i - 1].rpm;
    edesc[i].tq  = edesc[i].tq;

    maxTq = 0;
	car->engine.curve.maxPw = 0;
    car->engine.curve.data = (tEngineCurveElem *)malloc(car->engine.curve.nbPts * sizeof(tEngineCurveElem));

    for(i = 0; i < car->engine.curve.nbPts; i++) {
		data = &(car->engine.curve.data[i]);

		data->rads = edesc[i].rpm;
		if ((data->rads>=car->engine.tickover)
			&& (edesc[i].tq > maxTq)
			&& (data->rads < car->engine.revsLimiter)) {
			maxTq = edesc[i].tq;
			rpmMaxTq = data->rads;
		}
		if ((data->rads>=car->engine.tickover)
			&& (data->rads * edesc[i].tq > car->engine.curve.maxPw)
			&& (data->rads < car->engine.revsLimiter)) {
			car->engine.curve.TqAtMaxPw = edesc[i].tq;
			car->engine.curve.maxPw = data->rads * edesc[i].tq;
			car->engine.curve.rpmMaxPw = data->rads;
		}
		data->Tq = edesc[i].tq;
    }
    car->engine.curve.maxTq = maxTq;
    car->carElt->_engineMaxTq = maxTq;
    car->carElt->_enginerpmMaxTq = rpmMaxTq;
    car->carElt->_engineMaxPw = car->engine.curve.maxPw;
    car->carElt->_enginerpmMaxPw = car->engine.curve.rpmMaxPw;
	//printf ("%fNm@%frpm, %fKW@%f rpm\n",
	//  car->carElt->_engineMaxTq,
	//	car->carElt->_enginerpmMaxTq * (30.0 / M_PI),
	//	car->carElt->_engineMaxPw * 0.001,
	//	car->carElt->_enginerpmMaxPw * (30.0 / M_PI)
	//	);
	float X=urandom();
    car->engine.rads = X*car->engine.tickover+(1-X)*car->engine.revsMax;
    
    /*sanity check of rev limits*/
    if (car->engine.revsMax > car->engine.curve.data[car->engine.curve.nbPts-1].rads) {
        car->engine.revsMax = car->engine.curve.data[car->engine.curve.nbPts-1].rads;
        GfLogWarning("Revs maxi bigger than the maximum RPM in the curve data.\nIt is set to %g.\n",car->engine.revsMax);
    }
    if (car->engine.revsLimiter > car->engine.revsMax) {
        car->engine.revsLimiter = car->engine.revsMax;
        GfLogWarning("Revs limiter is bigger than revs maxi.\nIt is set to %g.\n",car->engine.revsLimiter);
    }

#if 0
	// TEST TORQUE FUNCTION
	for (float rads=1.0; rads<car->engine.revsMax; rads+=1.0) {
		float Tq = CalculateTorque(&(car->engine), rads);
		float Tq2 = CalculateTorque2(&(car->engine), rads);
		printf ("%f %f %f %d #TORQUE\n", 30.0*rads/M_PI, Tq, Tq2, engine->lastInterval);
	}
#endif
    free(edesc);
}
Ejemplo n.º 22
0
/** Interactive track selection
    @param  vs  Pointer on a tRmTrackSelect structure (cast to void *)
    @warning    The race manager's parameters are updated but not saved to the file.
    @ingroup    racemantools
 */
void
RmTrackSelect(void *vs)
{
	MenuData = (tRmTrackSelect*)vs;

	// Get currently selected track for the current race type
	// (or the first usable one in the selected category).
	PCurTrack = MenuData->pRace->getTrack();
	const std::string strReqTrackId = PCurTrack->getId();
	const std::string strReqTrackCatId = PCurTrack->getCategoryId();
	PCurTrack =
		GfTracks::self()->getFirstUsableTrack(PCurTrack->getCategoryId(), PCurTrack->getId());
	if (PCurTrack && PCurTrack->getId() != strReqTrackId)
		GfLogWarning("Could not find / use selected track %s (%s) ; using %s (%s)\n", 
					 strReqTrackId.c_str(), strReqTrackCatId.c_str(),
					 PCurTrack->getId().c_str(), PCurTrack->getCategoryId().c_str());

	// If not usable, try and get the first usable track going ahead in categories
	if (!PCurTrack)
	{
		PCurTrack = GfTracks::self()->getFirstUsableTrack(strReqTrackCatId, +1, true);
		if (PCurTrack)
			GfLogWarning("Could not find / use selected track %s and category %s unusable"
						 " ; using %s (%s)\n",
						 strReqTrackId.c_str(), strReqTrackCatId.c_str(),
						 PCurTrack->getId().c_str(), PCurTrack->getCategoryId().c_str());
	}
	
	// If no usable category/track found, ... return
	if (!PCurTrack)
	{
		GfLogError("No available track for any category ; quitting Track Select menu\n");
		return; // or exit(1) abruptly ?
	}

	// Create screen menu and controls.
	ScrHandle =
		GfuiScreenCreate((float*)NULL, NULL, rmtsActivate, NULL, (tfuiCallback)NULL, 1);

	void *hparmMenu = GfuiMenuLoad("trackselectmenu.xml");
	GfuiMenuCreateStaticControls( ScrHandle, hparmMenu);

	PrevCategoryArrowId =
		GfuiMenuCreateButtonControl(ScrHandle, hparmMenu, "trackcatleftarrow",(void*)-1, rmtsTrackCatPrevNext);
	NextCategoryArrowId =
		GfuiMenuCreateButtonControl(ScrHandle, hparmMenu, "trackcatrightarrow",(void*)1, rmtsTrackCatPrevNext);
	CategoryEditId = GfuiMenuCreateLabelControl(ScrHandle, hparmMenu, "trackcatlabel");

	PrevTrackArrowId =
		GfuiMenuCreateButtonControl(ScrHandle, hparmMenu, "trackleftarrow", (void*)-1, rmtsTrackPrevNext);
	NextTrackArrowId =
		GfuiMenuCreateButtonControl(ScrHandle, hparmMenu, "trackrightarrow", (void*)1, rmtsTrackPrevNext);
	NameEditId = GfuiMenuCreateLabelControl(ScrHandle, hparmMenu, "tracklabel");

	OutlineImageId = GfuiMenuCreateStaticImageControl(ScrHandle, hparmMenu, "outlineimage");

	GfuiMenuCreateButtonControl(ScrHandle, hparmMenu, "nextbutton", NULL, rmtsSelect);
	GfuiMenuCreateButtonControl(ScrHandle, hparmMenu, "backbutton", MenuData->prevScreen, rmtsDeactivate);

	DescLine1LabelId = GfuiMenuCreateLabelControl(ScrHandle, hparmMenu, "description1label");
	DescLine2LabelId = GfuiMenuCreateLabelControl(ScrHandle, hparmMenu, "description2label");
	LengthLabelId = GfuiMenuCreateLabelControl(ScrHandle, hparmMenu, "lengthlabel");
	WidthLabelId = GfuiMenuCreateLabelControl(ScrHandle, hparmMenu, "widthlabel");
	MaxPitsLabelId = GfuiMenuCreateLabelControl(ScrHandle, hparmMenu, "pitslabel");
	AuthorsLabelId = GfuiMenuCreateLabelControl(ScrHandle, hparmMenu, "authorslabel");

	// Load menu properties.
	DescLinesMaxLen = (unsigned)GfuiMenuGetNumProperty(hparmMenu, "nDescLinesMaxLen", 35);
	
	GfParmReleaseHandle(hparmMenu);

	// Keyboard shortcuts.
	rmtsAddKeys();

	// Let's go !
	GfuiScreenActivate(ScrHandle);
}
Ejemplo n.º 23
0
int
RePreRace(void)
{
	char path[128];
	const char *raceName;
	const char *raceType;
	void *params = ReInfo->params;
	void *results = ReInfo->results;
	int curRaceIdx;
	int timedLapsReplacement = 0;
	char *prevRaceName;
	
	raceName = ReInfo->_reRaceName = ReGetCurrentRaceName();
	
	GfParmRemoveVariable (params, "/", "humanInGroup");
	GfParmRemoveVariable (params, "/", "eventNb");
	GfParmSetVariable (params, "/", "humanInGroup", ReHumanInGroup() ? 1.0f : 0.0f);
	GfParmSetVariable (params, "/", "eventNb", GfParmGetNum (ReInfo->results, RE_SECT_CURRENT, RE_ATTR_CUR_TRACK, NULL, 1.0 ) );
	if (!raceName) {
		return RM_ERROR;
	}

	if (strcmp(GfParmGetStr(params, raceName, RM_ATTR_ENABLED, RM_VAL_YES), RM_VAL_NO) == 0) {
		GfLogTrace( "Race %s disabled\n",  raceName);
		curRaceIdx = (int)GfParmGetNum(results, RE_SECT_CURRENT, RE_ATTR_CUR_RACE, NULL, 1);
		if (curRaceIdx < GfParmGetEltNb(params, RM_SECT_RACES)) {
			curRaceIdx++;
			GfLogTrace( "Race %s is not the last one, but the #%d\n",  raceName, curRaceIdx);
			GfParmSetNum(results, RE_SECT_CURRENT, RE_ATTR_CUR_RACE, NULL, (tdble)curRaceIdx);
	
			return RM_SYNC | RM_NEXT_RACE;
		}
	
		GfParmSetNum(results, RE_SECT_CURRENT, RE_ATTR_CUR_RACE, NULL, 1);
		return RM_SYNC | RM_NEXT_RACE | RM_NEXT_STEP;
	}

	// Get session max dammages.
	ReInfo->s->_maxDammage = (int)GfParmGetNum(params, raceName, RM_ATTR_MAX_DMG, NULL, 10000);

	// Get session type (race, qualification or practice).
	raceType = GfParmGetStr(params, raceName, RM_ATTR_TYPE, RM_VAL_RACE);
	if (!strcmp(raceType, RM_VAL_RACE)) {
		ReInfo->s->_raceType = RM_TYPE_RACE;
	} else if (!strcmp(raceType, RM_VAL_QUALIF)) {
		ReInfo->s->_raceType = RM_TYPE_QUALIF;
	} else if (!strcmp(raceType, RM_VAL_PRACTICE)) {
		ReInfo->s->_raceType = RM_TYPE_PRACTICE;
	}

	// Get session duration (defaults to "All sessions" one, or else -60).
	ReInfo->s->_totTime = GfParmGetNum(params, raceName, RM_ATTR_SESSIONTIME, NULL, -1);
	if (ReInfo->s->_totTime < 0)
		ReInfo->s->_totTime = GfParmGetNum(params, RM_VAL_ANYRACE, RM_ATTR_SESSIONTIME, NULL, -60.0f);

	// Determine the actual session duration and/or number of laps.
	ReInfo->s->_extraLaps = 0; // TODO: Does this is ever needed ?
	ReInfo->s->_totLaps = 0; // Make sure it is initialized

	if (ReInfo->s->_totTime > 0 && !(ReInfo->s->_features & RM_FEATURE_TIMEDSESSION)) {
		// Timed session not supported: add 1 km for every minute in parctise or qualifying,
		// and 150 km for every hour (2.5 km for every minute) in race
		if (ReInfo->s->_raceType == RM_TYPE_RACE) {
			ReInfo->s->_totLaps = (int)floor(ReInfo->s->_totTime * 2500.0f / 60.0f / ReInfo->track->length + 0.5f);
		} else {
			ReInfo->s->_totLaps = (int)floor(ReInfo->s->_totTime * 1000.0f / 60.0f / ReInfo->track->length + 0.5f);
		}
		timedLapsReplacement = ReInfo->s->_totLaps;
		ReInfo->s->_totTime = -60.0f;
	}
	
	// Timed session doesn't exclude additional laps after the time finishes
	// Make sure that if no time set, we set far below zero
	if(ReInfo->s->_totTime <= 0.0f )
		ReInfo->s->_totTime = -60.0f;
		
	// Get session distance (defaults to "All sessions" one, or else 0).
	tdble dist = GfParmGetNum(params, raceName, RM_ATTR_DISTANCE, NULL, -1);
	if (dist < 0)
		dist = GfParmGetNum(params, RM_VAL_ANYRACE, RM_ATTR_DISTANCE, NULL, 0);
	
	// If a (> 0) session distance was specified, deduce the number of laps
	// in case the race settings don't specify it, and it is not a timed race.
	if ( (dist >= 0.001) && (ReInfo->s->_totTime < 0.0f) ) { // Why not 'if (dist > 0)' ???
		ReInfo->s->_totLaps = (int)(dist / ReInfo->track->length) + 1;
		ReInfo->s->_extraLaps = ReInfo->s->_totLaps; // Extralaps are used to find out how many laps there are after the time is up in timed sessions
	} else {dist = -1;}
	
	// Get the number of laps (defaults to "All sessions" one,
	// or else the already computed one from the session distance, or 0).
	int laps = (int)GfParmGetNum(params, raceName, RM_ATTR_LAPS, NULL, -1);
	if (laps < 0)
		laps = (int)GfParmGetNum(params, RM_VAL_ANYRACE, RM_ATTR_LAPS, NULL, 0);

	// Use lap number only when race distance is not in use.
	if ( (laps > 0) && (dist <= 0.0) && (timedLapsReplacement <= 0) ) {
		ReInfo->s->_totLaps = laps;
		ReInfo->s->_extraLaps = ReInfo->s->_totLaps; //Extralaps are used to find out how many laps there are after the time is up in timed sessions
	}

	// Make sure we have at least 1 lap race length.
	if ( (laps <= 0) && (dist <=0) && (ReInfo->s->_totTime < 0) ) {
		ReInfo->s->_totLaps = 1;
		ReInfo->s->_extraLaps = ReInfo->s->_totLaps; //Extralaps are used to find out how many laps there are after the time is up in timed sessions
	}

	// Correct extra laps (possible laps run after the winner arrived ?) :
	// during timed practice or qualification, there are none.
	if (ReInfo->s->_raceType != RM_TYPE_RACE && ReInfo->s->_totTime > 0) {
		ReInfo->s->_extraLaps = 0; //Extralaps are used to find out how many laps there are after the time is up in timed sessions
		ReInfo->s->_totLaps = 0;
	}

	GfLogInfo("Race length : time=%.0fs, laps=%d (extra=%d)\n",
			  ReInfo->s->_totTime, ReInfo->s->_totLaps, ReInfo->s->_extraLaps);
	
	// Initialize race state.
	ReInfo->s->_raceState = 0;

	// Cleanup results
	snprintf(path, sizeof(path), "%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, raceName);
	GfParmListClean(results, path);

	// Drivers starting order
	// The starting order is decided here,
	// then car indexes are stored in ReStartingOrderIdx, in the starting order.
	// The actual grid is assembled in ReRaceStart().
	// In case of a race, when all cars start at the same time,
	// cars are simply added to the starting list in the order stored in ReStartingOrderIdx.
	// If only one car is at the track at a time (not timed session qualifying or practice),
	// the race is divided into many sub-races.
	// For a sub-race, only the car pointed by results/RE_ATTR_CUR_DRIVER
	// is added to the starting grid.
	// RE_ATTR_CUR_DRIVER is refreshed after every sub-race in ReRaceEnd().
	ReCurrDriverNr = 0;
	int nCars = GfParmGetEltNb(params, RM_SECT_DRIVERS);
	GfParmListClean(params, RM_SECT_DRIVERS_RACING);
	if (nCars == 0)
	{
		// This may happen, when playing with the text-only mode,
		// and forgetting that human are automatically excluded then,
		// or when getting back to the GUI mode, and not reconfiguring the competitors list.
		GfLogError("No competitor in this race : cancelled.\n");
		return RM_ERROR;
	}
	else
	{
		ReUI().addLoadingMessage("Determining Starting Order ...");

		const char* gridType =
			GfParmGetStr(params, raceName, RM_ATTR_START_ORDER, RM_VAL_DRV_LIST_ORDER);
		
		int maxCars = (int)GfParmGetNum(params, raceName, RM_ATTR_MAX_DRV, NULL, 100);
		nCars = MIN(nCars, maxCars);
		
		tReGridPart *GridList = NULL;
		int nGridList = 0;
		
		// Initialize the array of car indexes for starting order
		if (ReStartingOrderIdx != NULL) {
			delete[] ReStartingOrderIdx;
			ReStartingOrderIdx = NULL;
		}
		ReStartingOrderIdx = new int[nCars];
		for (int i = 0; i < nCars; i++) {
			ReStartingOrderIdx[i] = -1;
		}
		
		// Starting grid in the arrival order of the previous race (or qualification session)
		if (!strcmp(gridType, RM_VAL_LAST_RACE_ORDER))
		{
			GfLogTrace("Starting grid in the order of the last race\n");
			
			prevRaceName = ReGetPrevRaceName(/* bLoop = */false);
			if (!prevRaceName) {
				return RM_ERROR;
			}

			for (int i = 1; i < nCars + 1; i++) {
				snprintf(path, sizeof(path), "%s/%s/%s/%s/%d",
						 ReInfo->track->name, RE_SECT_RESULTS, prevRaceName, RE_SECT_RANK, i);
				ReStartingOrderIdx[i-1] = 
					ReFindDriverIdx (GfParmGetStr(results, path, RE_ATTR_MODULE, ""),
									(int)GfParmGetNum(results, path, RE_ATTR_IDX, NULL, 0));
			}
		}
		
		// Starting grid in the reversed arrival order of the previous race
		else if (!strcmp(gridType, RM_VAL_LAST_RACE_RORDER))
		{
			GfLogTrace("Starting grid in the reverse order of the last race\n");

			prevRaceName = ReGetPrevRaceName(/* bLoop = */false);
			if (!prevRaceName) {
				return RM_ERROR;
			}

			for (int i = 1; i < nCars + 1; i++) {
				snprintf(path, sizeof(path), "%s/%s/%s/%s/%d",
						ReInfo->track->name, RE_SECT_RESULTS, prevRaceName, RE_SECT_RANK, nCars - i + 1);
				ReStartingOrderIdx[i-1] = 
					ReFindDriverIdx (GfParmGetStr(results, path, RE_ATTR_MODULE, ""),
									(int)GfParmGetNum(results, path, RE_ATTR_IDX, NULL, 0));
			}
		}

		// Starting grid as a mix from the results of earlier sessions
		else if (ReParseStartingOrder(gridType, &GridList, nCars, nGridList))
		{
			GfLogTrace("Starting grid as a mix from the results of earlier sessions\n");
			
			int idx;
			int gridpos = 1;
			int carnr;
			const char *modulename;
			for (int i = 0; i < nGridList; i++) {
				if (gridpos > nCars) {break;}
				if (GridList[i].diffpos == -1) {//reversed
					for ( int j = GridList[i].startpos; j >= GridList[i].endpos; j--) {
						if (gridpos > nCars) {break;}
						snprintf(path, sizeof(path), "%s/%s/%s/%s/%d",
								ReInfo->track->name, RE_SECT_RESULTS, GridList[i].racename, RE_SECT_RANK, j);
						idx = (int)GfParmGetNum(results, path, RE_ATTR_IDX, NULL, 0);
						modulename = GfParmGetStr(results, path, RE_ATTR_MODULE, "");
						carnr = ReFindDriverIdx(modulename, idx);
						for (int k = 0; k < gridpos-1; k++) {
							if ( carnr == ReStartingOrderIdx[k] ) {
								//oops: same car twice
								GfLogWarning("The same car appears twice in the advanced grid!\n");
								carnr = -1;
								break;
							}
						}
						//adding car to the list
						if (carnr != -1) {
							ReStartingOrderIdx[gridpos-1] = carnr;
							gridpos++;
						}
					}
				} else if (GridList[i].diffpos == 1){//straight order
					for ( int j = GridList[i].startpos; j <= GridList[i].endpos; j++) {
						if (gridpos > nCars) {break;}
						snprintf(path, sizeof(path), "%s/%s/%s/%s/%d",
								ReInfo->track->name, RE_SECT_RESULTS, GridList[i].racename, RE_SECT_RANK, j);
						idx = (int)GfParmGetNum(results, path, RE_ATTR_IDX, NULL, 0);
						modulename = GfParmGetStr(results, path, RE_ATTR_MODULE, "");
						carnr = ReFindDriverIdx(modulename, idx);
						for (int k = 0; k < gridpos-1; k++) {
							if ( carnr == ReStartingOrderIdx[k] ) {
								//oops: same car twice
								GfLogWarning("The same car appears twice in the advanced grid!\n");
								carnr = -1;
								break;
							}
						}
						//adding car to the list
						if (carnr != -1) {
							ReStartingOrderIdx[gridpos-1] = carnr;
							gridpos++;
						}
					}
				}
			}
			//cleaning up memory
			if (nGridList > 0){delete[] GridList;}
		}

		// Starting grid in the drivers list order
		else
		{
			GfLogTrace("Starting grid in the order of the driver list\n");

			for (int i = 1; i < nCars + 1; i++) {
				snprintf(path, sizeof(path), "%s/%d", RM_SECT_DRIVERS, i);
				ReStartingOrderIdx[i-1] = 
					ReFindDriverIdx (GfParmGetStr(params, path, RE_ATTR_MODULE, ""),
									(int)GfParmGetNum(params, path, RE_ATTR_IDX, NULL, 0));
			}
		}
	}
	
	ReCurrDriverNr = 0;
	GfParmSetNum(results, RE_SECT_CURRENT, RE_ATTR_CUR_DRIVER, NULL,
				(tdble)ReStartingOrderIdx[ReCurrDriverNr]);

	return RM_SYNC | RM_NEXT_STEP;
}
Ejemplo n.º 24
0
void NetClient::ReadPlayerRejectedPacket(ENetPacket *pPacket)
{
    m_eClientAccepted = CLIENTREJECTED;
    GfLogWarning ("Server rejected connection.\n");
}
Ejemplo n.º 25
0
void
ReStoreRaceResults(const char *race)
{
	int		i;
	int		nCars;
	tCarElt	*car;
	tSituation 	*s = ReInfo->s;
	char	*carName;
	void	*carparam;
	void	*results = ReInfo->results;
	void	*params = ReInfo->params;
	
	/* Store the number of laps of the race */
	switch (ReInfo->s->_raceType) {
		case RM_TYPE_RACE:
			car = s->cars[0];
			if (car->_laps > s->_totLaps) car->_laps = s->_totLaps + 1;

			snprintf(path, sizeof(path), "%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, race);
			GfParmListClean(results, path);
			GfParmSetNum(results, path, RE_ATTR_LAPS, NULL, (tdble)(car->_laps - 1));
			
			for (i = 0; i < s->_ncars; i++) {
				snprintf(path, sizeof(path), "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, i + 1);
				car = s->cars[i];
				if (car->_laps > s->_totLaps)
					car->_laps = s->_totLaps + 1;
			
				GfParmSetStr(results, path, RE_ATTR_NAME, car->_name);
			
				snprintf(buf, sizeof(buf), "cars/models/%s/%s.xml", car->_carName, car->_carName);
				carparam = GfParmReadFile(buf, GFPARM_RMODE_STD);
				carName = GfParmGetName(carparam);
			
				GfParmSetStr(results, path, RE_ATTR_CAR, carName);
				GfParmSetNum(results, path, RE_ATTR_INDEX, NULL, (tdble)car->index);
			
				GfParmSetNum(results, path, RE_ATTR_LAPS, NULL, (tdble)(car->_laps - 1));
				GfParmSetNum(results, path, RE_ATTR_TIME, NULL, (tdble)car->_curTime);
				GfParmSetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, (tdble)car->_bestLapTime);
				GfParmSetNum(results, path, RE_ATTR_TOP_SPEED, NULL, car->_topSpeed);
				GfParmSetNum(results, path, RE_ATTR_DAMMAGES, NULL, (tdble)car->_dammage);
				GfParmSetNum(results, path, RE_ATTR_NB_PIT_STOPS, NULL, (tdble)car->_nbPitStops);
			
				GfParmSetStr(results, path, RE_ATTR_MODULE, car->_modName);
				GfParmSetNum(results, path, RE_ATTR_IDX, NULL, (tdble)car->_moduleIndex);
				snprintf(path2, sizeof(path2), "%s/%d", RM_SECT_DRIVERS_RACING, car->index + 1 );
				GfParmSetNum(results, path, RM_ATTR_EXTENDED, NULL,
							 GfParmGetNum(params, path2, RM_ATTR_EXTENDED, NULL, 0));
				GfParmSetStr(results, path, ROB_ATTR_CAR, car->_carName);
				snprintf(path2, sizeof(path2), "%s/%s/%d", race, RM_SECT_POINTS, i + 1);
				GfParmSetNum(results, path, RE_ATTR_POINTS, NULL,
							 GfParmGetNum(params, path2, RE_ATTR_POINTS, NULL, 0));
				if (strlen(car->_skinName) > 0)
					GfParmSetStr(results, path, RM_ATTR_SKINNAME, car->_skinName);
				GfParmSetNum(results, path, RM_ATTR_SKINTARGETS, NULL, (tdble)car->_skinTargets);

				GfParmReleaseHandle(carparam);
			}
			break;
			
		case RM_TYPE_PRACTICE:
			if (s->_ncars == 1)
			{
				car = s->cars[0];
				snprintf(path, sizeof(path), "%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, race);
				GfParmSetStr(results, path, RM_ATTR_DRVNAME, car->_name);
				snprintf(buf, sizeof(buf), "cars/models/%s/%s.xml", car->_carName, car->_carName);
				carparam = GfParmReadFile(buf, GFPARM_RMODE_STD);
				carName = GfParmGetName(carparam);
				GfParmSetStr(results, path, RE_ATTR_CAR, carName);
				GfParmReleaseHandle(carparam);
				break;
			}
			/* Otherwise, fall through */
			
		case RM_TYPE_QUALIF:
			if (s->_ncars == 1)
			{
				car = s->cars[0];
				snprintf(path, sizeof(path), "%s/%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK);
				nCars = GfParmGetEltNb(results, path);
				for (i = nCars; i > 0; i--) {
					snprintf(path, sizeof(path), "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, i);
					float opponentBestLapTime = GfParmGetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, 0);
				
					if (car->_bestLapTime != 0.0 
						&& (car->_bestLapTime < opponentBestLapTime || opponentBestLapTime == 0.0))
					{
						/* shift */
						snprintf(path2, sizeof(path2), "%s/%s/%s/%s/%d",
								ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, i + 1);
						GfParmSetStr(results, path2, RE_ATTR_NAME,
									 GfParmGetStr(results, path, RE_ATTR_NAME, ""));
						GfParmSetStr(results, path2, RE_ATTR_CAR,
									 GfParmGetStr(results, path, RE_ATTR_CAR, ""));
						GfParmSetNum(results, path2, RE_ATTR_BEST_LAP_TIME, NULL,
									 GfParmGetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, 0));
						GfParmSetStr(results, path2, RE_ATTR_MODULE,
									 GfParmGetStr(results, path, RM_ATTR_MODULE, ""));
						GfParmSetNum(results, path2, RE_ATTR_IDX, NULL,
									 GfParmGetNum(results, path, RM_ATTR_IDX, NULL, 0));
						GfParmSetNum(results, path2, RM_ATTR_EXTENDED, NULL,
									 GfParmGetNum(results, path, RM_ATTR_EXTENDED, NULL, 0));
						GfParmSetStr(results, path2, ROB_ATTR_CAR,
									 GfParmGetStr(results, path, ROB_ATTR_CAR, ""));
						GfParmSetStr(results, path2, ROB_ATTR_NAME,
									 GfParmGetStr(results, path, ROB_ATTR_NAME, ""));
						snprintf(path, sizeof(path), "%s/%s/%d", race, RM_SECT_POINTS, i + 1);
						GfParmSetNum(results, path2, RE_ATTR_POINTS, NULL,
									 GfParmGetNum(params, path, RE_ATTR_POINTS, NULL, 0));
						if (GfParmGetStr(results, path, RM_ATTR_SKINNAME, 0))
							GfParmSetStr(results, path2, RM_ATTR_SKINNAME,
										 GfParmGetStr(results, path, RM_ATTR_SKINNAME, 0));
						GfParmSetNum(results, path2, RM_ATTR_SKINTARGETS, NULL,
									 GfParmGetNum(results, path, RM_ATTR_SKINTARGETS, NULL, 0));
					} else {
						break;
					}
				}
				/* insert after */
				snprintf(path, sizeof(path), "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, i + 1);
				GfParmSetStr(results, path, RE_ATTR_NAME, car->_name);
				
				snprintf(buf, sizeof(buf), "cars/models/%s/%s.xml", car->_carName, car->_carName);
				carparam = GfParmReadFile(buf, GFPARM_RMODE_STD);
				carName = GfParmGetName(carparam);
				
				GfParmSetStr(results, path, RE_ATTR_CAR, carName);
				GfParmSetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, (tdble)car->_bestLapTime);
				GfParmSetStr(results, path, RE_ATTR_MODULE, car->_modName);
				GfParmSetNum(results, path, RE_ATTR_IDX, NULL, (tdble)car->_moduleIndex);
				GfParmSetStr(results, path, ROB_ATTR_CAR, car->_carName);
				GfParmSetStr(results, path, ROB_ATTR_NAME, car->_name);
				snprintf(path2, sizeof(path2), "%s/%d", RM_SECT_DRIVERS_RACING, car->index + 1 );
				GfParmSetNum(results, path, RM_ATTR_EXTENDED, NULL,
							 GfParmGetNum(params, path2, RM_ATTR_EXTENDED, NULL, 0));
				snprintf(path2, sizeof(path2), "%s/%s/%d", race, RM_SECT_POINTS, i + 1);
				GfParmSetNum(results, path, RE_ATTR_POINTS, NULL,
							 GfParmGetNum(params, path2, RE_ATTR_POINTS, NULL, 0));
				if (strlen(car->_skinName) > 0)
					GfParmSetStr(results, path, RM_ATTR_SKINNAME, car->_skinName);
				GfParmSetNum(results, path, RM_ATTR_SKINTARGETS, NULL, (tdble)car->_skinTargets);
			
				GfParmReleaseHandle(carparam);
				break;
			} else {
				car = s->cars[0];
	
				if (s->_totTime < 0.0f)
					GfLogWarning("Saving results of multicar non-race session, but it was not timed!\n" );
				snprintf(path, sizeof(path), "%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, race);
				GfParmListClean(results, path);
				GfParmSetNum(results, path, RE_ATTR_SESSIONTIME, NULL, (tdble)s->_totTime);
				
				for (i = 0; i < s->_ncars; i++) {
					snprintf(path, sizeof(path), "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, i + 1);
					car = s->cars[i];
				
					GfParmSetStr(results, path, RE_ATTR_NAME, car->_name);
				
					snprintf(buf, sizeof(buf), "cars/models/%s/%s.xml", car->_carName, car->_carName);
					carparam = GfParmReadFile(buf, GFPARM_RMODE_STD);
					carName = GfParmGetName(carparam);
				
					GfParmSetStr(results, path, RE_ATTR_CAR, carName);
					GfParmSetNum(results, path, RE_ATTR_INDEX, NULL, (tdble)car->index);
				
					GfParmSetNum(results, path, RE_ATTR_LAPS, NULL, (tdble)(car->_laps - 1));
					GfParmSetNum(results, path, RE_ATTR_TIME, NULL, (tdble)car->_curTime);
					GfParmSetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, (tdble)car->_bestLapTime);
					GfParmSetNum(results, path, RE_ATTR_TOP_SPEED, NULL, car->_topSpeed);
					GfParmSetNum(results, path, RE_ATTR_DAMMAGES, NULL, (tdble)car->_dammage);
					GfParmSetNum(results, path, RE_ATTR_NB_PIT_STOPS, NULL, (tdble)car->_nbPitStops);
				
					GfParmSetStr(results, path, RE_ATTR_MODULE, car->_modName);
					GfParmSetNum(results, path, RE_ATTR_IDX, NULL, (tdble)car->_moduleIndex);
					snprintf(path2, sizeof(path2), "%s/%d", RM_SECT_DRIVERS_RACING, car->index + 1 );
					GfParmSetNum(results, path, RM_ATTR_EXTENDED, NULL,
								 GfParmGetNum(params, path2, RM_ATTR_EXTENDED, NULL, 0));
					GfParmSetStr(results, path, ROB_ATTR_CAR, car->_carName);
					snprintf(path2, sizeof(path2), "%s/%s/%d", race, RM_SECT_POINTS, i + 1);
					GfParmSetNum(results, path, RE_ATTR_POINTS, NULL,
								 GfParmGetNum(params, path2, RE_ATTR_POINTS, NULL, 0));
					if (strlen(car->_skinName) > 0)
						GfParmSetStr(results, path, RM_ATTR_SKINNAME, car->_skinName);
					GfParmSetNum(results, path, RM_ATTR_SKINTARGETS, NULL, (tdble)car->_skinTargets);
			
					GfParmReleaseHandle(carparam);
				}
				break;
			}
	}
}
Ejemplo n.º 26
0
void SDRender::weather(void)
{
    std::string datapath = GetDataDir();
    double domeSizeRatio = SDSkyDomeDistance / 80000.0;

    // Cloud layers.
    SDNbCloudLayers =
            (unsigned)(GfParmGetNum(grHandle, GR_SCT_GRAPHIC, GR_ATT_CLOUDLAYER, 0, 0) + 0.5);

    GfLogInfo("Graphic options : Number of cloud layers : %u\n", SDNbCloudLayers);

    cloudsTextureIndex = CloudsTextureIndices[SDTrack->local.clouds];
    unsigned int SDRain = 0;

    switch (SDTrack->local.rain)
    {
    case TR_RAIN_NONE:
        SDVisibility = SDMax_Visibility;
        SDRain = 0;
        break;
    case TR_RAIN_LITTLE:
        SDVisibility = 800.0;
        SDRain = 1;
        break;
    case TR_RAIN_MEDIUM:
        SDVisibility = 400.0;
        SDRain = 2;
        break;
    case TR_RAIN_HEAVY:
        SDVisibility = 200.0;
        SDRain = 3;
        break;
    default:
        GfLogWarning("Unsupported rain strength value %d (assuming none)",
                     SDTrack->local.rain);
        SDVisibility = 12000.0;
        break;
    }//switch Rain

    if (SDRain > 0)
    {
        SDCloudLayer *layer = new SDCloudLayer(datapath);
        layer->setCoverage(layer->SD_CLOUD_OVERCAST);
        layer->setSpeed(60);
        layer->setDirection(20);
        layer->setElevation_m(1000);
        layer->setThickness_m(400  / domeSizeRatio);
        layer->setTransition_m(400  / domeSizeRatio);
        layer->setSpan_m(SDSkyDomeDistance / 2);
        thesky->add_cloud_layer(layer);
    }
    else if (SDNbCloudLayers == 1)
    {
        SDCloudLayer *layer = new SDCloudLayer(datapath);
        layer->setCoverage(layer->SD_CLOUD_CIRRUS);
        layer->setSpeed(30);
        layer->setDirection(20);
        layer->setElevation_m(8000);
        layer->setThickness_m(400  / domeSizeRatio);
        layer->setTransition_m(400  / domeSizeRatio);
        layer->setSpan_m(SDSkyDomeDistance / 2);
        thesky->add_cloud_layer(layer);
    }
    else if (SDNbCloudLayers == 2)
    {
        SDCloudLayer *layer = new SDCloudLayer(datapath);
        layer->setCoverage(layer->SD_CLOUD_CIRRUS);
        layer->setSpeed(30);
        layer->setDirection(50);
        layer->setElevation_m(8000);
        layer->setThickness_m(400  / domeSizeRatio);
        layer->setTransition_m(400  / domeSizeRatio);
        layer->setSpan_m(SDSkyDomeDistance / 2);
        thesky->add_cloud_layer(layer);

        SDCloudLayer *layer2 = new SDCloudLayer(datapath);
        layer2->setCoverage(layer2->SD_CLOUD_FEW);
        layer2->setSpeed(80);
        layer2->setDirection(50);
        layer2->setElevation_m(3500);
        layer2->setThickness_m(400  / domeSizeRatio);
        layer2->setTransition_m(400  / domeSizeRatio);
        layer2->setSpan_m(SDSkyDomeDistance / 2);
        thesky->add_cloud_layer(layer2);
    }
    else if (SDNbCloudLayers == 3)
    {
        SDCloudLayer *layer = new SDCloudLayer(datapath);
        layer->setCoverage(layer->SD_CLOUD_CIRRUS);
        layer->setSpeed(30);
        layer->setDirection(20);
        layer->setElevation_m(8000);
        layer->setThickness_m(400  / domeSizeRatio);
        layer->setTransition_m(400  / domeSizeRatio);
        layer->setSpan_m(SDSkyDomeDistance / 2);
        thesky->add_cloud_layer(layer);

        SDCloudLayer *layer2 = new SDCloudLayer(datapath);
        layer2->setCoverage(layer2->SD_CLOUD_SCATTERED);
        layer2->setSpeed(60);
        layer2->setDirection(20);
        layer2->setElevation_m(3500);
        layer2->setThickness_m(400  / domeSizeRatio);
        layer2->setTransition_m(400  / domeSizeRatio);
        layer2->setSpan_m(SDSkyDomeDistance / 2);
        thesky->add_cloud_layer(layer2);

        SDCloudLayer *layer3 = new SDCloudLayer(datapath);
        layer3->setCoverage(layer2->SD_CLOUD_FEW);
        layer3->setSpeed(90);
        layer3->setDirection(20);
        layer3->setElevation_m(2500);
        layer3->setThickness_m(400  / domeSizeRatio);
        layer3->setTransition_m(400  / domeSizeRatio);
        layer3->setSpan_m(SDSkyDomeDistance / 2);
        thesky->add_cloud_layer(layer3);
    }
}
Ejemplo n.º 27
0
GfuiFontClass::GfuiFontClass(char *FileName)
{
	FILE *Input;
	char *TexBytes;
	int unsigned	Num;
	unsigned Tex;
	size_t readSize;

	font = NULL;
	size = 8.0;

	//Open font file
	if (!(Input = fopen(FileName, "rb"))) {
		perror(FileName);
		return;
	}

	if (!(font = (GLFONT *)malloc(sizeof(GLFONT))))
		return;

	//Read glFont structure
	//fread(font, sizeof(GLFONT), 1, Input);
	readSize = fread(font, 24, 1, Input); // for IA64...
	if( readSize <= 0 )
		GfLogWarning( "Not all bytes are successfully read" );
	//GfLogDebug("Font(%s) : texW=%d, texH=%d\n", FileName, font->TexWidth, font->TexHeight);

#ifndef WIN32
#if BYTE_ORDER == BIG_ENDIAN
	swap32((unsigned int *) font, 24);
#endif
#endif

	//Get number of characters
	Num = font->IntEnd - font->IntStart + 1;

	//Allocate memory for characters
	if ((font->Char = (GLFONTCHAR *)malloc(sizeof(GLFONTCHAR) * Num)) == NULL) {
		free(font);
		font = NULL;
		fclose(Input);
		return;
	}

    //Read glFont characters
	readSize = fread(font->Char, sizeof(GLFONTCHAR), Num, Input);
	if( readSize <= 0 )
		GfLogWarning( "Not all bytes are successfully read" );

#ifndef WIN32
#if BYTE_ORDER == BIG_ENDIAN
	swap32((unsigned int *)font->Char, sizeof(GLFONTCHAR) * Num);
#endif
#endif

	// Trace font info.
	// GfLogDebug("  %d chars\n", Num);
	// GfLogDebug("    %d : dx=%f, dy=%f\n", font->IntStart, font->Char[0].dx, font->Char[0].dy);
	// GfLogDebug("    %d : dx=%f, dy=%f\n", font->IntStart+2, font->Char[2].dx, font->Char[2].dy);
	// GfLogDebug("    %d : dx=%f, dy=%f\n", font->IntStart+Num-1, font->Char[Num-1].dx, font->Char[Num-1].dy);

	//Get texture size
	Num = font->TexWidth * font->TexHeight * 2;

	//Allocate memory for texture data
	if ((TexBytes = (char *)malloc(Num)) == NULL) {
		fclose(Input);
		return;
	}

	//Read texture data
	readSize = fread(TexBytes, sizeof(char), Num, Input);
	if( readSize < Num )
		GfLogWarning( "Not all bytes are successfully read" );

	fclose(Input);

	//Save texture number
	glGenTextures(1, &Tex);
	font->Tex = Tex;
	
	//Set texture attributes
	glBindTexture(GL_TEXTURE_2D, Tex);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

	//Create texture
	glTexImage2D(GL_TEXTURE_2D, 0, 2, font->TexWidth,
		 font->TexHeight, 0, GL_LUMINANCE_ALPHA,
		 GL_UNSIGNED_BYTE, (void *)TexBytes);

	//Clean up
	free(TexBytes);

	//Return pointer to new font
	return;
}