コード例 #1
0
ファイル: module.cpp プロジェクト: rongzhou/speed-dreams
GfModule* GfModule::load(const std::string& strModPathName, const std::string& strModName)
{
	std::ostringstream ossModLibPathName;
	
	ossModLibPathName << GfLibDir() << strModPathName << "/" <<  strModName << '.' << DLLEXT;

	return load(ossModLibPathName.str());
}
コード例 #2
0
ファイル: module.cpp プロジェクト: rongzhou/speed-dreams
bool GfModule::isPresent(const std::string& strModCatName, const std::string& strModName)
{
	std::ostringstream ossModLibPathName;
	
	ossModLibPathName << GfLibDir() << "modules/" << strModCatName << "/"
					  <<  strModName << '.' << DLLEXT;

	return GfFileExists(ossModLibPathName.str().c_str());
}
コード例 #3
0
ファイル: simuconfig.cpp プロジェクト: 702nADOS/speed-dreams
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]);
}
コード例 #4
0
/** Initialization of a telemetry session.
    @ingroup	telemetry
    @param	ymin	Minimum value for Y.
    @param	ymax	Maximum value for Y.
    @return	None
 */
void RtTelemInit(tdble ymin, tdble ymax)
{
#ifdef later
    char	buf[256];
    tModInfoNC	*curModInfo;

    memset(&tlm, 0, sizeof(tTelemItf));
    sprintf(buf, "%smodules/telemetry/%s.%s", "telemetry", GfLibDir (), DLLEXT);
    if (GfModLoad(TLM_IDENT, buf, &modlist)) return;
    GfOut("--- %s loaded ---\n", modlist->modInfo->name);
    curModInfo = modlist->modInfo;
    curModInfo->fctInit(curModInfo->index, &tlm);

    tlm.init(ymin, ymax);
#endif
}
コード例 #5
0
ファイル: simuconfig.cpp プロジェクト: 702nADOS/speed-dreams
/* Change the simulation version (but only show really available modules) */
static void
onChangeSimuVersion(void *vp)
{
	char buf[1024];

	if (!vp)
		return;

	const int oldSimuVersion = CurSimuVersion;
	do
	{
		CurSimuVersion = (CurSimuVersion + NbSimuVersions + (int)(long)vp) % NbSimuVersions;
	
		snprintf(buf, sizeof(buf), "%smodules/simu/%s.%s", GfLibDir(), SimuVersionList[CurSimuVersion], DLLEXT);
	}
	while (!GfFileExists(buf) && CurSimuVersion != oldSimuVersion);

	GfuiLabelSetText(ScrHandle, SimuVersionId, SimuVersionDispNameList[CurSimuVersion]);
}
コード例 #6
0
ファイル: drivers.cpp プロジェクト: xinderuila1/speed-dream
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();
}
コード例 #7
0
ファイル: raceinit.cpp プロジェクト: rongzhou/speed-dreams
/**
 * Function to load a car.
 *
 * @param carindex The index whichs will be used as car->index for the car.
 * @param listindex The listindex in RM_SECT_DRIVERS_RACING
 * @param modindex The index of the mod; must be MAX_MOD_ITF if normal_carname is FALSE.
 * @param robotIdx The index of the robot.
 * @param normal_carname If this member is TRUE, the car is treated as an ordinary car;
 *                       if this member is FALSE, then the car used is the one given
 *                       in the xml-file, and there is no restriction on the number of instances.
 * @param cardllname The dllname of the driver
 * @return A pointer to the newly created car if successfull; NULL otherwise
 */
static tCarElt* reLoadSingleCar( int carindex, int listindex, int modindex, int relativeRobotIdx, char normal_carname, char const *cardllname )
{
  tCarElt *elt;
  tMemoryPool oldPool;
  char path[256];
  char path2[256];
  char buf[256];
  char buf2[256];
  char const *str;
  char const *category;
  char const *subcategory;
  char const *teamname;
  std::string carname;
  tModInfoNC *curModInfo;
  tRobotItf *curRobot;
  void *robhdle;
  void *cathdle;
  void *carhdle;
  void *handle;
  int k;
  int xx;
  char isHuman;
  int robotIdx = relativeRobotIdx;

  /* good robot found */
  curModInfo = &((*(ReInfo->robModList))->modInfo[modindex]);

  subcategory = ReInfo->track->subcategory;

#if 0 //SDW
  if (replayReplay)
    GfLogInfo("Driver in car %d being driven by replay\n", carindex);
  else
#endif
    GfLogInfo("Driver's name: %s\n", curModInfo->name);

  isHuman = strcmp( cardllname, "human" ) == 0 || strcmp( cardllname, "networkhuman" ) == 0;

  /* Extended is forced for humans, so no need to increase robotIdx */
  if (!normal_carname && !isHuman) 
    robotIdx += curModInfo->index;

  /* Retrieve the driver interface (function pointers) */
  curRobot = (tRobotItf*)calloc(1, sizeof(tRobotItf));

  /* ... and initialize the driver */
#if 0 // SDW
  if (replayReplay) {
    // Register against the Replay driver (which does nothing)
    curModInfo->fctInit(carindex, (void*)(curRobot));
  } else if (!(ReInfo->_displayMode & RM_DISP_MODE_SIMU_SIMU)) {
#else
  if (!(ReInfo->_displayMode & RM_DISP_MODE_SIMU_SIMU)) {
#endif
    curModInfo->fctInit(robotIdx, (void*)(curRobot));
  } else {
    curRobot->rbNewTrack = NULL;
    curRobot->rbNewRace  = NULL;
    curRobot->rbResumeRace  = NULL;
    curRobot->rbDrive    = NULL;
    curRobot->rbPitCmd   = NULL;
    curRobot->rbEndRace  = NULL;
    curRobot->rbShutdown = NULL;
    curRobot->index      = 0;
  }

  /* Retrieve and load the robotXML file :
     1) from user settings dir (local dir)
     2) from installed data dir */
  snprintf(buf, sizeof(buf), "%sdrivers/%s/%s.xml", GfLocalDir(), cardllname, cardllname);
  robhdle = GfParmReadFile(buf, GFPARM_RMODE_STD);
  if (!robhdle) {
    snprintf(buf, sizeof(buf), "drivers/%s/%s.xml", cardllname, cardllname);
    robhdle = GfParmReadFile(buf, GFPARM_RMODE_STD);
  }

  if (normal_carname || isHuman)
    snprintf(path, sizeof(path), "%s/%s/%d", ROB_SECT_ROBOTS, ROB_LIST_INDEX, robotIdx);
  else
    snprintf(path, sizeof(path), "%s", ROB_SECT_ARBITRARY);
  
  /* Load car/driver info (in race engine data structure) */
  if (robhdle)
  {
    elt = &(ReInfo->carList[carindex]);
    GF_TAILQ_INIT(&(elt->_penaltyList));

    const std::string strDType = GfParmGetStr(robhdle, path, ROB_ATTR_TYPE, ROB_VAL_ROBOT);
    if (strDType == ROB_VAL_ROBOT){
      elt->_driverType = RM_DRV_ROBOT;
      elt->_networkPlayer = 0;
    } 
    else if (strDType == ROB_VAL_HUMAN)
    {
      elt->_driverType = RM_DRV_HUMAN;
      std::string strNetPlayer = GfParmGetStr(robhdle, path, "networkrace", "no");
      elt->_networkPlayer = (strNetPlayer == "yes") ? 1 : 0;
    }

    elt->index = carindex;
    elt->robot = curRobot;
    elt->_paramsHandle = robhdle;
    elt->_driverIndex = robotIdx;
    elt->_moduleIndex = relativeRobotIdx;
    strncpy(elt->_modName, cardllname, MAX_NAME_LEN - 1);
    elt->_modName[MAX_NAME_LEN - 1] = 0;

    //snprintf(path, sizeof(path), "%s/%s/%d", ROB_SECT_ROBOTS, ROB_LIST_INDEX, robotIdx);
    snprintf( path2, sizeof(path2), "%s/%s/%d/%d", RM_SECT_DRIVERINFO, elt->_modName, normal_carname ? 0 : 1, elt->_moduleIndex );
    if (normal_carname || elt->_driverType == RM_DRV_HUMAN) {
      strncpy(elt->_name, GfParmGetStr(robhdle, path, ROB_ATTR_NAME, "none"), MAX_NAME_LEN - 1);
      strncpy(elt->_sname, GfParmGetStr(robhdle, path, ROB_ATTR_SNAME, "none"), MAX_NAME_LEN - 1);
      strncpy(elt->_cname, GfParmGetStr(robhdle, path, ROB_ATTR_CODE, "---"), 3);
    } else {
      strncpy(elt->_name, GfParmGetStr(ReInfo->params, path2, ROB_ATTR_NAME, "none"), MAX_NAME_LEN - 1);
      strncpy(elt->_sname, GfParmGetStr(ReInfo->params, path2, ROB_ATTR_SNAME, "none"), MAX_NAME_LEN - 1);
      strncpy(elt->_cname, GfParmGetStr(ReInfo->params, path2, ROB_ATTR_CODE, "---"), 3);
    }
    elt->_name[MAX_NAME_LEN - 1] = 0;
    elt->_sname[MAX_NAME_LEN - 1] = 0;
    elt->_cname[3] = 0;

    teamname = GfParmGetStr(robhdle, path, ROB_ATTR_TEAM, "none");
    teamname = GfParmGetStr(ReInfo->params, path2, ROB_ATTR_TEAM, teamname ); //Use the name in params if it has a team name
    strncpy(elt->_teamname, teamname, MAX_NAME_LEN - 1);
    elt->_teamname[MAX_NAME_LEN - 1] = 0;

    elt->_driveSkill = GfParmGetNum(ReInfo->params, path2, RM_ATTR_SKILLLEVEL, NULL, -1.0f);

    if (normal_carname) /* Even if we get a normal_carname for humans we use it despite of forced extended mode*/
      strncpy(elt->_carName, GfParmGetStr(robhdle, path, ROB_ATTR_CAR, ""), MAX_NAME_LEN - 1);
    else
      strncpy(elt->_carName, GfParmGetStr(ReInfo->params, path2, RM_ATTR_CARNAME, ""), MAX_NAME_LEN - 1);
    elt->_carName[MAX_NAME_LEN - 1] = 0; /* XML file name */

    // Load custom skin name and targets from race info (if specified).
    snprintf(path2, sizeof(path2), "%s/%d", RM_SECT_DRIVERS_RACING, listindex);
    if (GfParmGetStr(ReInfo->params, path2, RM_ATTR_SKINNAME, 0))
    {
      strncpy(elt->_skinName, GfParmGetStr(ReInfo->params, path2, RM_ATTR_SKINNAME, ""), MAX_NAME_LEN - 1);
      elt->_skinName[MAX_NAME_LEN - 1] = 0; // Texture name
    }
	elt->_skinTargets = (int)GfParmGetNum(ReInfo->params, path2, RM_ATTR_SKINTARGETS, (char*)NULL, 0);
	
    // Load other data from robot descriptor.
    elt->_raceNumber = (int)GfParmGetNum(robhdle, path, ROB_ATTR_RACENUM, (char*)NULL, 0);
    if (!normal_carname && elt->_driverType != RM_DRV_HUMAN) // Increase racenumber if needed
      elt->_raceNumber += elt->_moduleIndex;
    elt->_skillLevel = 0;
    str = GfParmGetStr(robhdle, path, ROB_ATTR_LEVEL, ROB_VAL_SEMI_PRO);
    for(k = 0; k < NSkillLevels; k++) {
      if (strcmp(aPszSkillLevelNames[k], str) == 0) {
        elt->_skillLevel = k;
        break;
      }
    }
    elt->_startRank  = carindex;
    elt->_pos        = carindex+1;
    elt->_remainingLaps = ReInfo->s->_totLaps;

    elt->_newTrackMemPool = NULL;
    elt->_newRaceMemPool = NULL;
    elt->_endRaceMemPool = NULL;
    elt->_shutdownMemPool = NULL;

	carname = elt->_carName;

    GfLogTrace("Driver #%d(%d) : module='%s', name='%s', car='%s', cat='%s', skin='%s' on %x\n",
			   carindex, listindex, elt->_modName, elt->_name, elt->_carName,
			   elt->_category, elt->_skinName, elt->_skinTargets);

    if ((strncmp(carname.c_str(), "mpa1", 4) == 0))
	{
		if (strcmp(subcategory, "long") == 0)
			carname = carname+"-long";
		else if (strcmp(subcategory, "short") == 0)
			carname = carname+"-short";
		else 
			carname = carname+"-road";

		GfLogTrace("MPA... Category car = %s \n", carname.c_str());

		/* Retrieve and load car specs : merge car default specs,
		category specs and driver modifications (=> handle) */
		/* Read Car model specifications */
		snprintf(buf, sizeof(buf), "cars/models/%s/%s.xml", elt->_carName, carname.c_str());
		carhdle = GfParmReadFile(buf, GFPARM_RMODE_STD | GFPARM_RMODE_CREAT);

	}
	else
	{  
		/* Retrieve and load car specs : merge car default specs,
		category specs and driver modifications (=> handle) */
		/* Read Car model specifications */
		snprintf(buf, sizeof(buf), "cars/models/%s/%s.xml", elt->_carName, elt->_carName);
		carhdle = GfParmReadFile(buf, GFPARM_RMODE_STD | GFPARM_RMODE_CREAT);
	}

    category = GfParmGetStr(carhdle, SECT_CAR, PRM_CATEGORY, NULL);
    if (category)
    {
	  GfLogTrace("Checking/Merging %s specs into %s base setup for %s ...\n",
				 category, elt->_carName, curModInfo->name);
      strncpy(elt->_category, category, MAX_NAME_LEN - 1);
      elt->_category[MAX_NAME_LEN - 1] = 0;
      /* Read Car Category specifications */
      snprintf(buf2, sizeof(buf2), "cars/categories/%s.xml", elt->_category);
      cathdle = GfParmReadFile(buf2, GFPARM_RMODE_STD | GFPARM_RMODE_CREAT);
	  int errorcode = 0;

      if ((errorcode = GfParmCheckHandle(cathdle, carhdle))) 
	  {
        switch (errorcode)
		{
		  case -1:
            GfLogError("Car %s NOT in category %s (driver %s) !!!\n", elt->_carName, category, elt->_name);
		    break;

		  case -2:
            GfLogError("Parameters out of bound for car %s (driver %s)!!!\n",elt->_carName, elt->_name);
		    break;

		  case -3:
            GfLogError("Parameter not allowed for car %s (driver %s)!!!\n",elt->_carName, elt->_name);
		    break;

		  default:
            GfLogError("Unknown error for %s (driver %s)!!!\n",elt->_carName, elt->_name);
		    break;
	    } 
        return NULL;
      }

      carhdle = GfParmMergeHandles(cathdle, carhdle,
                                   GFPARM_MMODE_SRC | GFPARM_MMODE_DST | GFPARM_MMODE_RELSRC | GFPARM_MMODE_RELDST);
	  
      /* The code below stores the carnames to a separate xml-file
		 such that at newTrack it is known which car is used.
		 TODO: find a better method for this */
      snprintf (buf, sizeof(buf), "%sdrivers/curcarnames.xml", GfLocalDir());
      handle = GfParmReadFile(buf, GFPARM_RMODE_CREAT);
      if (handle) {
        snprintf(path, sizeof(path), "drivers/%s/%d", cardllname, elt->_driverIndex);
        GfParmSetStr (handle, path, RM_ATTR_CARNAME, elt->_carName);
        GfParmWriteFile (0, handle, "Car names");
        GfParmReleaseHandle (handle);
      }
      if (!(ReInfo->_displayMode & RM_DISP_MODE_SIMU_SIMU))
      {
        GfPoolMove(&elt->_newTrackMemPool, &oldPool);
        curRobot->rbNewTrack(elt->_driverIndex, ReInfo->track, carhdle, &handle, ReInfo->s);
        GfPoolFreePool( &oldPool );
      }
      else
        handle = NULL;
      if (handle && !replayReplay) {
		GfLogTrace("Checking/Merging %s specific setup into %s setup.\n",
				   curModInfo->name, elt->_carName);
        if (GfParmCheckHandle(carhdle, handle)) {
          GfLogError("Bad Car parameters for driver %s\n", elt->_name);
          return NULL;
        }
        handle = GfParmMergeHandles(carhdle, handle,
                                    GFPARM_MMODE_SRC | GFPARM_MMODE_DST | GFPARM_MMODE_RELSRC | GFPARM_MMODE_RELDST);
      } else {
		GfLogTrace("Keeping %s setup as is for %s (no specific setup).\n",
				   elt->_carName, curModInfo->name);
		handle = carhdle;
      }
      elt->_carHandle = handle;

      /* Initialize sectors */
      elt->_currentSector = 0;
      elt->_curSplitTime = (double*)malloc( sizeof(double) * ( ReInfo->track->numberOfSectors - 1 ) );
      elt->_bestSplitTime = (double*)malloc( sizeof(double) * ( ReInfo->track->numberOfSectors - 1 ) );
      for (xx = 0; xx < ReInfo->track->numberOfSectors - 1; ++xx)
      {
        elt->_curSplitTime[xx] = -1.0f;
        elt->_bestSplitTime[xx] = -1.0f;
      }
    } else {
      elt->_category[ 0 ] = '\0';
      GfLogError("Bad Car category for driver %s\n", elt->_name);
      return NULL;
    }

    return elt;
  } else {
    GfLogError("No description file for robot %s\n", cardllname);
  }
  return NULL;
}


/** Initialize the cars for a race.
    The cars are positionned on the starting grid.
    @return 0 Ok, -1 Error
 */
int
ReInitCars(void)
{
  char buf[512];
  char path[512];
  int nCars;
  int index;
  int i, j;
  const char *robotModuleName;
  int robotIdx;
  void *robhdle;
  tCarElt *elt;
  //const char *focused; // Never used.
  //int focusedIdx; // Never used.
  void *params = ReInfo->params;

  /* Get the number of cars (= drivers) racing */
  nCars = GfParmGetEltNb(params, RM_SECT_DRIVERS_RACING);
  GfLogTrace("Loading %d car(s)\n", nCars);

  FREEZ(ReInfo->carList);
  ReInfo->carList = (tCarElt*)calloc(nCars, sizeof(tCarElt));
  FREEZ(ReInfo->rules);
  ReInfo->rules = (tRmCarRules*)calloc(nCars, sizeof(tRmCarRules));
  //focused = GfParmGetStr(ReInfo->params, RM_SECT_DRIVERS, RM_ATTR_FOCUSED, "");
  //focusedIdx = (int)GfParmGetNum(ReInfo->params, RM_SECT_DRIVERS, RM_ATTR_FOCUSEDIDX, NULL, 0);
  index = 0;

  /* For each car/driver : */
  for (i = 1; i < nCars + 1; i++) 
  {
    /* Get the name of the module (= shared library) of the robot */
    snprintf(path, sizeof(path), "%s/%d", RM_SECT_DRIVERS_RACING, i);
    robotModuleName = GfParmGetStr(ReInfo->params, path, RM_ATTR_MODULE, "");
    robotIdx = (int)GfParmGetNum(ReInfo->params, path, RM_ATTR_IDX, NULL, 0);

#if 0 // SDW
    if (replayReplay)
      // Register against the Replay driver
      snprintf(path, sizeof(path), "%sdrivers/replay/replay.%s", GfLibDir(), DLLEXT);
    else
#endif
      snprintf(path, sizeof(path), "%sdrivers/%s/%s.%s", GfLibDir(), robotModuleName, robotModuleName, DLLEXT);

    /* Load the robot shared library */
    if (GfModLoad(CAR_IDENT, path, ReInfo->robModList)) 
    {
      GfLogError("Failed to load robot module %s\n", path);
      continue;
    }

    /* Load the racing driver info in the race data structure */
    elt = NULL;
    snprintf(path, sizeof(path), "%s/%d", RM_SECT_DRIVERS_RACING, i);
    if ((int)GfParmGetNum(ReInfo->params, path, RM_ATTR_EXTENDED, NULL, 0) == 0) 
    {
      /* Search for the index of the racing driver in the list of interfaces
         of the module */
      for (j = 0; j < (*(ReInfo->robModList))->modInfoSize; j++) 
      {
        if ((*(ReInfo->robModList))->modInfo[j].name && (*(ReInfo->robModList))->modInfo[j].index == robotIdx) 
        {
          /* We have the right driver : load it */
          elt = reLoadSingleCar( index, i, j, robotIdx, TRUE, robotModuleName );
          if (!elt)
		  {
            GfLogError("No descriptor file for robot %s or parameter errors (1)\n", robotModuleName);
			snprintf(buf, sizeof(buf), "Error: May be no driver, or some parameters are out of bound");
	        ReUI().addLoadingMessage(buf);
			snprintf(buf, sizeof(buf), "       Have a look at the console window for mode details about the error");
	        ReUI().addLoadingMessage(buf);
			snprintf(buf, sizeof(buf), "       Back to the config menu in 10 s ...");
	        ReUI().addLoadingMessage(buf);
			
			// Wait some time to allow the user to read the message!
            GfSleep(10.0); // 10 seconds
		  }
        }
      }
    }
    else 
    {
      GfLogTrace("Loading robot %s descriptor file\n", robotModuleName );
      snprintf(buf, sizeof(buf), "%sdrivers/%s/%s.xml", GfLocalDir(), robotModuleName, robotModuleName);
      robhdle = GfParmReadFile(buf, GFPARM_RMODE_STD);
      if (!robhdle) 
      {
        snprintf(buf, sizeof(buf), "drivers/%s/%s.xml", robotModuleName, robotModuleName);
        robhdle = GfParmReadFile(buf, GFPARM_RMODE_STD);
      }
      if (robhdle && ( strcmp( robotModuleName, "human" ) == 0 || strcmp( robotModuleName, "networkhuman" ) == 0 ) )
      {
        /* Human driver */
        elt = reLoadSingleCar( index, i, robotIdx - (*(ReInfo->robModList))->modInfo[0].index, robotIdx, FALSE, robotModuleName );
      }
      else if (robhdle && ( strcmp( GfParmGetStr( robhdle, ROB_SECT_ARBITRARY, ROB_ATTR_TEAM, "foo" ),
                              GfParmGetStr( robhdle, ROB_SECT_ARBITRARY, ROB_ATTR_TEAM, "bar" ) ) == 0 ) )
      {
        elt = reLoadSingleCar( index, i, (*(ReInfo->robModList))->modInfoSize, robotIdx, FALSE, robotModuleName );
      }
      else
        GfLogError("No descriptor for robot %s (2)\n", robotModuleName );
    }

    if (elt)
      ++index;
  }

  nCars = index; /* real number of cars */
  if (nCars == 0) 
  {
    GfLogError("No driver for that race ; exiting ...\n");
    return -1;
  }
  else 
  {
    GfLogInfo("%d driver(s) ready to race\n", nCars);
  }

  if (replayReplay)
    replayRecord = 0;
  else {
        char buf[1024];
	const char *replayRateSchemeName;
        snprintf(buf, sizeof(buf), "%s%s", GfLocalDir(), RACE_ENG_CFG);

        void *paramHandle = GfParmReadFile(buf, GFPARM_RMODE_REREAD | GFPARM_RMODE_CREAT);
        replayRateSchemeName = GfParmGetStr(paramHandle, RM_SECT_RACE_ENGINE, RM_ATTR_REPLAY_RATE, "0");
        GfParmReleaseHandle(paramHandle);

	replayRecord = atoi(replayRateSchemeName);
  }

  if (replayRecord || replayReplay) {
#ifdef THIRD_PARTY_SQLITE3
    int result;

    result = sqlite3_open("/tmp/race.sqlite", &replayDB);
    if (result) {
      GfLogError("Replay: Unable to open Database: %s\n", sqlite3_errmsg(replayDB));
      sqlite3_close(replayDB);
      replayDB = NULL;
    } else {
      GfLogInfo("Replay: Database Opened 0x8%8.8X\n", replayDB);

      if (replayRecord)
        GfLogInfo("Replay: Record Timestep = %f\n", 1/(float)replayRecord);

      if (replayReplay)
        GfLogInfo("Replay: Playback from file\n");

      /* speed up database by turning of synchronous behaviour/etc */
      sqlite3_exec(replayDB, "PRAGMA synchronous = OFF", NULL, NULL, NULL);
      sqlite3_exec(replayDB, "PRAGMA journal_mode = OFF", NULL, NULL, NULL);
      sqlite3_exec(replayDB, "PRAGMA count_changes = OFF", NULL, NULL, NULL);
#if 0 // This pragma seems to prevent re-opening the sqlite3 database
      sqlite3_exec(replayDB, "PRAGMA locking_mode = EXCLUSIVE", NULL, NULL, NULL);
#endif
      sqlite3_exec(replayDB, "PRAGMA default_temp_store = MEMORY", NULL, NULL, NULL);

      //replayBlobs = (sqlite3_stmt *) calloc(nCars, sizeof(void *)); //sqlite3_stmt));

      replayTimestamp = -5;
      ghostcarActive = 0;
    }
#endif
  }

  ReInfo->s->_ncars = nCars;
  FREEZ(ReInfo->s->cars);
  ReInfo->s->cars = (tCarElt **)calloc(nCars, sizeof(tCarElt *));
  for (i = 0; i < nCars; i++)
  {
    ReInfo->s->cars[i] = &(ReInfo->carList[i]);

#ifdef THIRD_PARTY_SQLITE3
    //open a table for each car
    if (replayDB) {
      char command[200];
      int result;

      if (replayRecord) {
        sprintf(command, "DROP TABLE IF EXISTS car%d", i);
        result = sqlite3_exec(replayDB, command, 0, 0, 0);
        if (result) GfLogInfo("Replay: Unable to drop table car%d: %s\n", i, sqlite3_errmsg(replayDB));
      }

      sprintf(command, "CREATE TABLE IF NOT EXISTS car%d (timestamp, lap, datablob BLOB)", i);
      result = sqlite3_exec(replayDB, command, 0, 0, 0);
      if (result) {
         GfLogInfo("Replay: Unable to create table car%d: %s\n", i, sqlite3_errmsg(replayDB));
         exit(0);
      }

      if (replayReplay) {
        // Build index to allow faster read access
        sprintf(command, "CREATE UNIQUE INDEX IF NOT EXISTS index%d ON car%d (timestamp)", i, i);
        result = sqlite3_exec(replayDB, command, 0, 0, 0);
        if (result) GfLogInfo("Replay: Unable to create index car%d: %s\n", i, sqlite3_errmsg(replayDB));
      }
    }
#endif
  }

  ReInfo->_rePitRequester = 0;

  // TODO: reconsider splitting the call into one for cars, track and maybe other objects.
  // I stuff for now anything into one call because collision detection works with the same
  // library on all objects, so it is a bit dangerous to distribute the handling to various
  // locations (because the library maintains global state like a default collision handler etc.).
  RePhysicsEngine().initialize(nCars, ReInfo->track);

  initStartingGrid();

  initPits();

  return 0;
}
コード例 #8
0
/*
 * Function
 *    main
 *
 * Description
 *    Main function of the game
 *
 * Parameters
 *    argc Number of command line args, + 1 for the executable name
 *    argv Array of zero-terminated strings, 1 for each arg
 *
 * Return
 *    0 status code if OK, non-0 otherwise.
 */
int
main(int argc, char *argv[])
{
	// Look for the "text-only" option flag in the command-line args.
	bool bTextOnly = false;
	for (int i = 1; i < argc; i++)
		if (!strcmp(argv[i], "-to") || !strcmp(argv[i], "--textonly"))
		{
			bTextOnly = true;
			break;
		}

	// Create the application (graphical or text-only UI).
	GfApplication* pApp;
	if (bTextOnly)
		pApp = new GfApplication("Speed Dreams", VERSION_LONG,
								 "an Open Motorsport Sim", argc, argv);
	else
		pApp = new GfuiApplication("Speed Dreams", VERSION_LONG,
								   "an Open Motorsport Sim", argc, argv);

	// Register app. specific options and help text.
	pApp->registerOption("to", "textonly", /* nHasValue = */ false);
	pApp->registerOption("sr", "startrace", /* nHasValue = */ true);
	
	pApp->addOptionsHelpSyntaxLine("[-sr|--startrace <race name> [-to|--textonly] ]");
	pApp->addOptionsHelpExplainLine
		("- text-only : Run the specified race without any GUI (suitable for a headless computer)");
	pApp->addOptionsHelpExplainLine
		("- race name : Name without extension and dir path of the selected raceman file,");
	pApp->addOptionsHelpExplainLine
		("              among the .xml files in <user settings>/config/raceman (no default)");

	// Parse the command line for registered options.
    if (!pApp->parseOptions())
		return 1;

	// Some more checks about command line options.
	std::string strRaceToStart;
	if (bTextOnly && (!pApp->hasOption("startrace", strRaceToStart) || strRaceToStart.empty()))
	{
		std::cerr << "Exiting from " << pApp->name()
				  << " because no race specified in text-only mode." << std::endl;
		return 1;
	}
	
	// If "data dir" specified in any way, cd to it.
	if(chdir(GfDataDir()))
	{
		GfLogError("Could not start %s : failed to cd to the datadir '%s' (%s)\n",
				   pApp->name().c_str(), GfDataDir(), strerror(errno));
		return 1;
	}

	// Update user settings files from installed ones.
    pApp->updateUserSettings();

   // Initialize the event loop management layer (graphical or text-only UI).
	GfEventLoop* pEventLoop;
	if (bTextOnly)
		pEventLoop = new GfEventLoop;
	else
		pEventLoop = new GfuiEventLoop;
	pApp->setEventLoop(pEventLoop);

	// When there's a GUI, setup the window / screen and menu infrastructure.
    if (!bTextOnly && !dynamic_cast<GfuiApplication*>(pApp)->setupWindow())
	{
		std::cerr << "Exiting from " << pApp->name()
				  << " after some error occurred (see above)." << std::endl;
		return 1;
	}

	// Load the user interface module (graphical or text-only UI).
	std::ostringstream ossModLibName;
	ossModLibName << GfLibDir() << "modules/userinterface/"
				  << (bTextOnly ?  "textonly" : "legacymenu") << '.' << DLLEXT;
	GfModule* pmodUserItf = GfModule::load(ossModLibName.str());

	// Check that it implements IUserInterface.
	IUserInterface* piUserItf = 0;
	if (pmodUserItf)
	{
		piUserItf = pmodUserItf->getInterface<IUserInterface>();
	}

 	// Initialize the race engine and the user interface modules.
	if (piUserItf)
	{
		RaceEngine::self().setUserInterface(*piUserItf);
		piUserItf->setRaceEngine(RaceEngine::self());
	}
	
	if (piUserItf)
	{
		// Enter the user interface.
		if (piUserItf->activate())
		{
			// Game event loop (when it returns, it's simply because we are exiting).
			pApp->eventLoop()();
		}
		
		// Shutdown the user interface.
		piUserItf->shutdown();

		// Shutdown the race engine.
		RaceEngine::self().shutdown();
		
		// Unload the user interface module.
		GfModule::unload(pmodUserItf);
	}

	// Done with the app instance.
	const std::string strAppName(pApp->name());
	delete pApp;
	
 	// That's all (but trace what we are doing).
	if (piUserItf)
		GfLogInfo("Exiting normally from %s.\n", strAppName.c_str());
	else
		std::cerr << "Exiting from " << strAppName
				  << " after some error occurred (see above)." << std::endl;
	
	return piUserItf ? 0 : 1;
}
コード例 #9
0
void Application::generate()
{
	const char *extName;
	FILE *outfd = NULL;

	// Get the trackgen paramaters.
	sprintf(buf, "%s", CFG_FILE);
	CfgHandle = GfParmReadFile(buf, GFPARM_RMODE_STD | GFPARM_RMODE_CREAT);

	// Load and initialize the track loader module.
	GfLogInfo("Loading Track Loader ...\n");
	std::ostringstream ossModLibName;
	ossModLibName << GfLibDir() << "modules/track/" << "track" << '.' << DLLEXT;
	GfModule* pmodTrkLoader = GfModule::load(ossModLibName.str());

	// Check that it implements ITrackLoader.
	ITrackLoader* PiTrackLoader = 0;
	if (pmodTrkLoader)
		PiTrackLoader = pmodTrkLoader->getInterface<ITrackLoader>();
	if (!PiTrackLoader)
		return;

	// This is the track definition.
	sprintf(trackdef, "%stracks/%s/%s/%s.xml", GfDataDir(), TrackCategory, TrackName, TrackName);
	TrackHandle = GfParmReadFile(trackdef, GFPARM_RMODE_STD);
	if (!TrackHandle) {
		fprintf(stderr, "Cannot find %s\n", trackdef);
		::exit(1);
	}

	// Build the track structure with graphic extensions.
	Track = PiTrackLoader->load(trackdef, true);

	if (!JustCalculate) {
		// Get the output file radix.
		sprintf(buf2, "%stracks/%s/%s/%s", GfDataDir(), Track->category, Track->internalname, Track->internalname);
		OutputFileName = strdup(buf2);

		// Number of groups for the complete track.
		if (TrackOnly) {
			sprintf(buf2, "%s.ac", OutputFileName);
			// Track.
			outfd = Ac3dOpen(buf2, 1);
		} else if (MergeAll) {
			sprintf(buf2, "%s.ac", OutputFileName);
			// track + terrain + objects.
			outfd = Ac3dOpen(buf2, 2 + GetObjectsNb(TrackHandle));
		}

		// Main Track.
		if (Bump) {
			extName = "trk-bump";
		} else {
			extName = "trk";
		}

		sprintf(buf2, "%s-%s.ac", OutputFileName, extName);
		OutTrackName = strdup(buf2);
	}

	if (JustCalculate){
		CalculateTrack(Track, TrackHandle, Bump);
		return;
	}

	GenerateTrack(Track, TrackHandle, OutTrackName, outfd, Bump);

	if (TrackOnly) {
		return;
	}

	// Terrain.
	if (MergeTerrain && !MergeAll) {
		sprintf(buf2, "%s.ac", OutputFileName);
		/* terrain + objects  */
		outfd = Ac3dOpen(buf2, 1 + GetObjectsNb(TrackHandle));
	}

	extName = "msh";
	sprintf(buf2, "%s-%s.ac", OutputFileName, extName);
	OutMeshName = strdup(buf2);

	GenerateTerrain(Track, TrackHandle, OutMeshName, outfd, DoSaveElevation);

	if (DoSaveElevation != -1) {
		if (outfd) {
			Ac3dClose(outfd);
		}
		switch (DoSaveElevation) {
			case 0:
			case 1:
				sprintf(buf2, "%s.ac", OutputFileName);
				sprintf(buf, "%s-elv.png", OutputFileName);
				SaveElevation(Track, TrackHandle, buf, buf2, 1);
				if (DoSaveElevation) {
					break;
				}
			case 2:
				sprintf(buf, "%s-elv2.png", OutputFileName);
				SaveElevation(Track, TrackHandle, buf, OutMeshName, 1);
				if (DoSaveElevation) {
					break;
				}
			case 3:
				sprintf(buf, "%s-elv3.png", OutputFileName);
				SaveElevation(Track, TrackHandle, buf, OutMeshName, 0);
				if (DoSaveElevation) {
					break;
				}
			case 4:
				sprintf(buf, "%s-elv4.png", OutputFileName);
				SaveElevation(Track, TrackHandle, buf, OutTrackName, 2);
				break;
		}
		return;
	}

	GenerateObjects(Track, TrackHandle, CfgHandle, outfd, OutMeshName);
}