Beispiel #1
0
int
ReRaceEventInit(void)
{
	void *params = ReInfo->params;

	RmLoadingScreenStart(ReInfo->_reName, "data/img/splash-qrloading.png");

	taManager->Init(ReInfo);

	// Initialize Track
	if (!taManager->IsActive())
		ReInitTrack();

	// Initialize Graphics
	if (
		(ReInfo->_displayMode != RM_DISP_MODE_CONSOLE) &&
		(ReInfo->_reGraphicItf.inittrack != 0)
		) {
		RmLoadingScreenSetText("Loading Track 3D Description...");
		ReInfo->_reGraphicItf.inittrack(ReInfo->track);
	};

	if (taManager->IsActive())
	{
		RmLoadingScreenSetText("Initializing TORCS Adaptive Manager...");
		taManager->InitGraphics();
	}

	ReEventInitResults();

	if (
		(GfParmGetEltNb(params, RM_SECT_TRACKS) > 1) &&
		(ReInfo->_displayMode != RM_DISP_MODE_NONE) &&
		(ReInfo->_displayMode != RM_DISP_MODE_CONSOLE)
	) {
		ReNewTrackMenu();
		return RM_ASYNC | RM_NEXT_STEP;
	}

	return RM_SYNC | RM_NEXT_STEP;
}
/** Initialize the track for a race manager.
    @return	<tt>0 ... </tt>Ok<br>
		<tt>-1 .. </tt>Error
*/
int
ReInitTrack(void)
{
    char	*trackName;
    char	*catName;
    int		curTrkIdx;
    void	*params = ReInfo->params;
    void	*results = ReInfo->results;

    curTrkIdx = (int)GfParmGetNum(results, RE_SECT_CURRENT, RE_ATTR_CUR_TRACK, NULL, 1);
    sprintf(buf, "%s/%d", RM_SECT_TRACKS, curTrkIdx);
    trackName = GfParmGetStr(params, buf, RM_ATTR_NAME, 0);
    if (!trackName) return -1;
    catName = GfParmGetStr(params, buf, RM_ATTR_CATEGORY, 0);
    if (!catName) return -1;

    sprintf(buf, "Loading Track %s...", trackName);
    RmLoadingScreenSetText(buf);
    sprintf(buf, "tracks/%s/%s/%s.%s", catName, trackName, trackName, TRKEXT);
    ReInfo->track = ReInfo->_reTrackItf.trkBuild(buf);
    reDumpTrack(ReInfo->track, 0);

    return 0;
}
Beispiel #3
0
/* return state mode */
int
ReRaceStart(void)
{
	int i;
	int nCars;
	int maxCars;
	const char *raceName = ReInfo->_reRaceName;
	void *params = ReInfo->params;
	void *results = ReInfo->results;
	const int BUFSIZE = 1024;
	char path[BUFSIZE], path2[BUFSIZE];

	FREEZ(ReInfo->_reCarInfo);
	ReInfo->_reCarInfo = (tReCarInfo*)calloc(GfParmGetEltNb(params, RM_SECT_DRIVERS), sizeof(tReCarInfo));

	/* Drivers starting order */
	GfParmListClean(params, RM_SECT_DRIVERS_RACING);
	if (ReInfo->s->_raceType == RM_TYPE_QUALIF) {
		i = (int)GfParmGetNum(results, RE_SECT_CURRENT, RE_ATTR_CUR_DRIVER, NULL, 1);
		if (i == 1) {
			RmLoadingScreenStart(ReInfo->_reName, "data/img/splash-qrloading.png");
			RmLoadingScreenSetText("Preparing Starting Grid...");
		} else {
			RmShutdownLoadingScreen();
		}

		snprintf(path, BUFSIZE, "%s/%d", RM_SECT_DRIVERS, i);
		snprintf(path2, BUFSIZE, "%s/%d", RM_SECT_DRIVERS_RACING, 1);
		GfParmSetStr(params, path2, RM_ATTR_MODULE, GfParmGetStr(params, path, RM_ATTR_MODULE, ""));
		GfParmSetNum(params, path2, RM_ATTR_IDX, NULL, GfParmGetNum(params, path, RM_ATTR_IDX, NULL, 0));
	} else {
		RmLoadingScreenStart(ReInfo->_reName, "data/img/splash-qrloading.png");
		RmLoadingScreenSetText("Preparing Starting Grid...");

		const char* gridType = GfParmGetStr(params, raceName, RM_ATTR_START_ORDER, RM_VAL_DRV_LIST_ORDER);
		if (!strcmp(gridType, RM_VAL_LAST_RACE_ORDER)) {
			/* Starting grid in the arrival of the previous race */
			nCars = GfParmGetEltNb(params, RM_SECT_DRIVERS);
			maxCars = (int)GfParmGetNum(params, raceName, RM_ATTR_MAX_DRV, NULL, 100);
			nCars = MIN(nCars, maxCars);
			const char* prevRaceName = ReGetPrevRaceName();
			if (!prevRaceName) {
				return RM_QUIT;
			}
			for (i = 1; i < nCars + 1; i++) {
				snprintf(path, BUFSIZE, "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, prevRaceName, RE_SECT_RANK, i);
				snprintf(path2, BUFSIZE, "%s/%d", RM_SECT_DRIVERS_RACING, i);
				GfParmSetStr(params, path2, RM_ATTR_MODULE, GfParmGetStr(results, path, RE_ATTR_MODULE, ""));
				GfParmSetNum(params, path2, RM_ATTR_IDX, NULL, GfParmGetNum(results, path, RE_ATTR_IDX, NULL, 0));
			}
		} else if (!strcmp(gridType, RM_VAL_LAST_RACE_RORDER)) {
			/* Starting grid in the reversed arrival order of the previous race */
			nCars = GfParmGetEltNb(params, RM_SECT_DRIVERS);
			maxCars = (int)GfParmGetNum(params, raceName, RM_ATTR_MAX_DRV, NULL, 100);
			nCars = MIN(nCars, maxCars);
			const char* prevRaceName = ReGetPrevRaceName();
			if (!prevRaceName) {
				return RM_QUIT;
			}
			for (i = 1; i < nCars + 1; i++) {
				snprintf(path, BUFSIZE, "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, prevRaceName, RE_SECT_RANK, nCars - i + 1);
				snprintf(path2, BUFSIZE, "%s/%d", RM_SECT_DRIVERS_RACING, i);
				GfParmSetStr(params, path2, RM_ATTR_MODULE, GfParmGetStr(results, path, RE_ATTR_MODULE, ""));
				GfParmSetNum(params, path2, RM_ATTR_IDX, NULL, GfParmGetNum(results, path, RE_ATTR_IDX, NULL, 0));
			}
		} else {
			/* Starting grid in the drivers list order */
			nCars = GfParmGetEltNb(params, RM_SECT_DRIVERS);
			maxCars = (int)GfParmGetNum(params, raceName, RM_ATTR_MAX_DRV, NULL, 100);
			nCars = MIN(nCars, maxCars);
			for (i = 1; i < nCars + 1; i++) {
				snprintf(path, BUFSIZE, "%s/%d", RM_SECT_DRIVERS, i);
				snprintf(path2, BUFSIZE, "%s/%d", RM_SECT_DRIVERS_RACING, i);
				GfParmSetStr(params, path2, RM_ATTR_MODULE, GfParmGetStr(params, path, RM_ATTR_MODULE, ""));
				GfParmSetNum(params, path2, RM_ATTR_IDX, NULL, GfParmGetNum(params, path, RM_ATTR_IDX, NULL, 0));
			}
		}
	}

	if (ReInfo->_displayMode != RM_DISP_MODE_CONSOLE) {
		if (!strcmp(GfParmGetStr(params, ReInfo->_reRaceName, RM_ATTR_SPLASH_MENU, RM_VAL_NO), RM_VAL_YES)) {
			RmShutdownLoadingScreen();
			RmDisplayStartRace(ReInfo, StartRaceHookInit(), AbandonRaceHookInit());
			return RM_ASYNC | RM_NEXT_STEP;
		}
	}

	return reRaceRealStart();
}
Beispiel #4
0
/* return state mode */
static int
reRaceRealStart(void)
{
	int i, j;
	int sw, sh, vw, vh;
	tRobotItf *robot;
	tReCarInfo *carInfo;
	const int BUFSIZE = 1024;
	char buf[BUFSIZE];
	int foundHuman;
	void *params = ReInfo->params;
	void *results = ReInfo->results;
	tSituation *s = ReInfo->s;

	RmLoadingScreenSetText("Loading Simulation Engine...");
	const char* dllname = GfParmGetStr(ReInfo->_reParam, "Modules", "simu", "");
	snprintf(buf, BUFSIZE, "%smodules/simu/%s.%s", GetLibDir (), dllname, DLLEXT);
	if (GfModLoad(0, buf, &ReRaceModList)) return RM_QUIT;
	ReRaceModList->modInfo->fctInit(ReRaceModList->modInfo->index, &ReInfo->_reSimItf);

	if (ReInitCars()) {
		return RM_QUIT;
	}

	/* Blind mode or not */
	if (ReInfo->_displayMode != RM_DISP_MODE_CONSOLE) {
		ReInfo->_displayMode = RM_DISP_MODE_NORMAL;
		ReInfo->_reGameScreen = ReScreenInit();
		foundHuman = 0;
		for (i = 0; i < s->_ncars; i++) {
			if (s->cars[i]->_driverType == RM_DRV_HUMAN) {
				foundHuman = 1;
				break;
			}
		}
		if (!foundHuman) {
			if (!strcmp(GfParmGetStr(params, ReInfo->_reRaceName, RM_ATTR_DISPMODE, RM_VAL_VISIBLE), RM_VAL_INVISIBLE)) {
				ReInfo->_displayMode = RM_DISP_MODE_NONE;
				ReInfo->_reGameScreen = ReResScreenInit();
			}
		}
	}

	if (!(ReInfo->s->_raceType == RM_TYPE_QUALIF) ||
	((int)GfParmGetNum(results, RE_SECT_CURRENT, RE_ATTR_CUR_DRIVER, NULL, 1) == 1))
	{
		RmLoadingScreenStart(ReInfo->_reName, "data/img/splash-qrloading.png");
	}

	for (i = 0; i < s->_ncars; i++) {
		snprintf(buf, BUFSIZE, "Initializing Driver %s...", s->cars[i]->_name);
		RmLoadingScreenSetText(buf);
		robot = s->cars[i]->robot;
		robot->rbNewRace(robot->index, s->cars[i], s);
	}
	carInfo = ReInfo->_reCarInfo;

	ReInfo->_reSimItf.update(s, RCM_MAX_DT_SIMU, -1);
	for (i = 0; i < s->_ncars; i++) {
		carInfo[i].prevTrkPos = s->cars[i]->_trkPos;
	}

	RmLoadingScreenSetText("Running Prestart...");
	for (i = 0; i < s->_ncars; i++) {
		memset(&(s->cars[i]->ctrl), 0, sizeof(tCarCtrl));
		s->cars[i]->ctrl.brakeCmd = 1.0;
	}
	for (j = 0; j < ((int)(1.0 / RCM_MAX_DT_SIMU)); j++) {
		ReInfo->_reSimItf.update(s, RCM_MAX_DT_SIMU, -1);
	}

	if (ReInfo->_displayMode == RM_DISP_MODE_NONE) {
		if (ReInfo->s->_raceType == RM_TYPE_QUALIF) {
			ReUpdateQualifCurRes(s->cars[0]);
		} else {
			snprintf(buf, BUFSIZE, "%s on %s", s->cars[0]->_name, ReInfo->track->name);
			ReResScreenSetTitle(buf);
		}
	}

	RmLoadingScreenSetText("Ready.");

	ReInfo->_reTimeMult = 1.0;
	ReInfo->_reLastTime = -1.0;
	ReInfo->s->currentTime = -2.0;
	ReInfo->s->deltaTime = RCM_MAX_DT_SIMU;

	ReInfo->s->_raceState = RM_RACE_STARTING;

	if ((ReInfo->_displayMode != RM_DISP_MODE_CONSOLE) &&  ReInfo->_reGraphicItf.initview != 0) {
		GfScrGetSize(&sw, &sh, &vw, &vh);
		ReInfo->_reGraphicItf.initview((sw-vw)/2, (sh-vh)/2, vw, vh, GR_VIEW_STD, ReInfo->_reGameScreen);

		if (ReInfo->_displayMode == RM_DISP_MODE_NORMAL) {
			/* RmLoadingScreenSetText("Loading Cars 3D Objects..."); */
			stopMenuMusic();
			ReInfo->_reGraphicItf.initcars(s);
		}

		GfuiScreenActivate(ReInfo->_reGameScreen);
	}

	// If the race is adaptive, initialize performance measurement. Uses strategy pattern, pass in the desired performance measurement object.
	if (taManager->IsActive())
	{
		if (taManager->GetRaceType() == torcsAdaptive::TARaceType::Adaptive)
			taManager->InitPerfMeasurement(new RaceLineEvaluation(&ReInfo->carList[0], Pathfinder::K1999, ReInfo->track, ReInfo->s));
	}
	return RM_SYNC | RM_NEXT_STEP;
}
/** Dump the track segments on screen
    @param	track	track to dump
    @param	verbose	if set to 1 all the segments are described (long)
    @ingroup	racemantools
 */
static void
reDumpTrack(tTrack *track, int verbose)
{
    int		i;
    tTrackSeg	*seg;
#ifdef DEBUG
    char	*stype[4] = { "", "RGT", "LFT", "STR" };
#endif

    RmLoadingScreenSetText("Loading Track Geometry...");
    sprintf(buf, ">>> Track Name    %s", track->name);
    RmLoadingScreenSetText(buf);
    sprintf(buf, ">>> Track Author  %s", track->author);
    RmLoadingScreenSetText(buf);
    sprintf(buf, ">>> Track Length  %.2f m", track->length);
    RmLoadingScreenSetText(buf);
    sprintf(buf, ">>> Track Width   %.2f m", track->width);
    RmLoadingScreenSetText(buf);

    GfOut("++++++++++++ Track ++++++++++++\n");
    GfOut("name     = %s\n", track->name);
    GfOut("author   = %s\n", track->author);
    GfOut("filename = %s\n", track->filename);
    GfOut("nseg     = %d\n", track->nseg);
    GfOut("version  = %d\n", track->version);
    GfOut("length   = %f\n", track->length);
    GfOut("width    = %f\n", track->width);
    GfOut("XSize    = %f\n", track->max.x);
    GfOut("YSize    = %f\n", track->max.y);
    GfOut("ZSize    = %f\n", track->max.z);
    switch (track->pits.type) {
    case TR_PIT_NONE:
	GfOut("Pits     = none\n");
	break;
    case TR_PIT_ON_TRACK_SIDE:
	GfOut("Pits     = present on track side\n");
	break;
    case TR_PIT_ON_SEPARATE_PATH:
	GfOut("Pits     = present on separate path\n");
	break;
    }
    if (verbose) {
	for (i = 0, seg = track->seg->next; i < track->nseg; i++, seg = seg->next) {
	    GfOut("	segment %d -------------- \n", seg->id);
#ifdef DEBUG
	    GfOut("        type    %s\n", stype[seg->type]);
#endif
	    GfOut("        length  %f\n", seg->length);
	    GfOut("	radius  %f\n", seg->radius);
	    GfOut("	arc	%f   Zs %f   Ze %f   Zcs %f\n", RAD2DEG(seg->arc),
		   RAD2DEG(seg->angle[TR_ZS]),
		   RAD2DEG(seg->angle[TR_ZE]),
		   RAD2DEG(seg->angle[TR_CS]));
	    GfOut("	Za	%f\n", RAD2DEG(seg->angle[TR_ZS]));
	    GfOut("	vertices: %-8.8f %-8.8f %-8.8f ++++ ",
		   seg->vertex[TR_SR].x,
		   seg->vertex[TR_SR].y,
		   seg->vertex[TR_SR].z);
	    GfOut("%-8.8f %-8.8f %-8.8f\n",
		   seg->vertex[TR_SL].x,
		   seg->vertex[TR_SL].y,
		   seg->vertex[TR_SL].z);
	    GfOut("	vertices: %-8.8f %-8.8f %-8.8f ++++ ",
		   seg->vertex[TR_ER].x,
		   seg->vertex[TR_ER].y,
		   seg->vertex[TR_ER].z);
	    GfOut("%-8.8f %-8.8f %-8.8f\n",
		   seg->vertex[TR_EL].x,
		   seg->vertex[TR_EL].y,
		   seg->vertex[TR_EL].z);
	    GfOut("	prev    %d\n", seg->prev->id);
	    GfOut("	next    %d\n", seg->next->id);
	}
	GfOut("From Last To First\n");
	GfOut("Dx = %-8.8f  Dy = %-8.8f Dz = %-8.8f\n",
	       track->seg->next->vertex[TR_SR].x - track->seg->vertex[TR_ER].x,
	       track->seg->next->vertex[TR_SR].y - track->seg->vertex[TR_ER].y,
	       track->seg->next->vertex[TR_SR].z - track->seg->vertex[TR_ER].z);

    }
}
/** Initialize the cars for a race.
    The car are positionned on the starting grid.
    @return	0 Ok
		-1 Error
 */
int
ReInitCars(void)
{
	int nCars;
	int index;
	int i, j, k;
	char *cardllname;
	int robotIdx;
	tModInfo *curModInfo;
	tRobotItf *curRobot;
	void *handle;
	char *category;
	void *cathdle;
	void *carhdle;
	void *robhdle;
	tCarElt *elt;
	char *focused;
	char *str;
	int focusedIdx;
	void *params = ReInfo->params;

	/* Get the number of cars racing */
	nCars = GfParmGetEltNb(params, RM_SECT_DRIVERS_RACING);
	GfOut("loading %d cars\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 (i = 1; i < nCars + 1; i++) {
		/* Get Shared library name */
		sprintf(path, "%s/%d", RM_SECT_DRIVERS_RACING, i);
		cardllname = GfParmGetStr(ReInfo->params, path, RM_ATTR_MODULE, "");
		robotIdx = (int)GfParmGetNum(ReInfo->params, path, RM_ATTR_IDX, NULL, 0);
		sprintf(path, "%sdrivers/%s/%s.%s", GetLibDir (), cardllname, cardllname, DLLEXT);

		/* load the robot shared library */
		if (GfModLoad(CAR_IDENT, path, ReInfo->modList)) {
			GfTrace("Pb with loading %s driver\n", path);
			break;
		}

		/* search for corresponding index */
		for (j = 0; j < MAX_MOD_ITF; j++) {
			if ((*(ReInfo->modList))->modInfo[j].index == robotIdx) {
				/* good robot found */
				curModInfo = &((*(ReInfo->modList))->modInfo[j]);
				GfOut("Driver's name: %s\n", curModInfo->name);
				/* retrieve the robot interface (function pointers) */
				curRobot = (tRobotItf*)calloc(1, sizeof(tRobotItf));
				curModInfo->fctInit(robotIdx, (void*)(curRobot));
				sprintf(buf, "%sdrivers/%s/%s.xml", GetLocalDir(), cardllname, cardllname);
				robhdle = GfParmReadFile(buf, GFPARM_RMODE_STD);
				if (!robhdle) {
					sprintf(buf, "drivers/%s/%s.xml", cardllname, cardllname);
					robhdle = GfParmReadFile(buf, GFPARM_RMODE_STD);
				}
				if (robhdle != NULL) {
					elt = &(ReInfo->carList[index]);
					GF_TAILQ_INIT(&(elt->_penaltyList));

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

					sprintf(path, "%s/%s/%d", ROB_SECT_ROBOTS, ROB_LIST_INDEX, robotIdx);
					strncpy(elt->_name, GfParmGetStr(robhdle, path, ROB_ATTR_NAME, "<none>"), MAX_NAME_LEN - 1);
					elt->_name[MAX_NAME_LEN - 1] = 0;
					strncpy(elt->_teamname, GfParmGetStr(robhdle, path, ROB_ATTR_TEAM, "<none>"), MAX_NAME_LEN - 1);
					elt->_teamname[MAX_NAME_LEN - 1] = 0;
					
					strncpy(elt->_carName, GfParmGetStr(robhdle, path, ROB_ATTR_CAR, ""), MAX_NAME_LEN - 1);
					elt->_carName[MAX_NAME_LEN - 1] = 0;
					elt->_raceNumber = (int)GfParmGetNum(robhdle, path, ROB_ATTR_RACENUM, (char*)NULL, 0);
					if (strcmp(GfParmGetStr(robhdle, path, ROB_ATTR_TYPE, ROB_VAL_ROBOT), ROB_VAL_ROBOT)) {
						elt->_driverType = RM_DRV_HUMAN;
					} else {
						elt->_driverType = RM_DRV_ROBOT;
					}
					elt->_skillLevel = 0;
					str = GfParmGetStr(robhdle, path, ROB_ATTR_LEVEL, ROB_VAL_SEMI_PRO);
					for(k = 0; k < (int)(sizeof(level_str)/sizeof(char*)); k++) {
						if (strcmp(level_str[k], str) == 0) {
							elt->_skillLevel = k;
							break;
						}
					}
					elt->_startRank  = index;
					elt->_pos        = index+1;
					elt->_remainingLaps = ReInfo->s->_totLaps;

					/* handle contains the drivers modifications to the car */
					/* Read Car model specifications */
					sprintf(buf, "cars/%s/%s.xml", elt->_carName, elt->_carName);
					GfOut("Car Specification: %s\n", buf);
					carhdle = GfParmReadFile(buf, GFPARM_RMODE_STD | GFPARM_RMODE_CREAT);
					category = GfParmGetStr(carhdle, SECT_CAR, PRM_CATEGORY, NULL);
					sprintf(buf, "Loading Driver %-20s... Car: %s", curModInfo->name, elt->_carName);
					RmLoadingScreenSetText(buf);
					if (category != 0) {
						strncpy(elt->_category, category, MAX_NAME_LEN - 1);
						elt->_category[MAX_NAME_LEN - 1] = '\0';

						/* Read Car Category specifications */
						sprintf(buf, "categories/%s.xml", category);
						GfOut("Category Specification: %s\n", buf);
						cathdle = GfParmReadFile(buf, GFPARM_RMODE_STD | GFPARM_RMODE_CREAT);
						if (GfParmCheckHandle(cathdle, carhdle)) {
							GfTrace("Car %s not in Category %s (driver %s) !!!\n", elt->_carName, category, elt->_name);
							break;
						}
						carhdle = GfParmMergeHandles(cathdle, carhdle,
										GFPARM_MMODE_SRC | GFPARM_MMODE_DST | GFPARM_MMODE_RELSRC | GFPARM_MMODE_RELDST);
										curRobot->rbNewTrack(robotIdx, ReInfo->track, carhdle, &handle, ReInfo->s);
						if (handle != NULL) {
							if (GfParmCheckHandle(carhdle, handle)) {
								GfTrace("Bad Car parameters for driver %s\n", elt->_name);
								break;
							}
							handle = GfParmMergeHandles(carhdle, handle,
										GFPARM_MMODE_SRC | GFPARM_MMODE_DST | GFPARM_MMODE_RELSRC | GFPARM_MMODE_RELDST);
						} else {
							handle = carhdle;
						}
						elt->_carHandle = handle;
						//GfParmWriteFile("toto.xml", handle, "toto");
					} else {
						elt->_category[0] = '\0';
						GfTrace("Bad Car category for driver %s\n", elt->_name);
						break;
					}
					index ++;
				} else {
					GfTrace("Pb No description file for driver %s\n", cardllname);
				}
				break;
			}
		}
    }

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

	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]);
	}

	// 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.).
    ReInfo->_reSimItf.init(nCars, ReInfo->track);

    initStartingGrid();

    initPits();

    return 0;
}