/* Load a simple database */ void LoadRelief(void *TrackHandle, char *reliefFile) { GF_TAILQ_INIT(&InteriorList); GF_TAILQ_INIT(&ExteriorList); GridStep = GfParmGetNum(TrackHandle, TRK_SECT_TERRAIN, TRK_ATT_BSTEP, NULL, GridStep); ssgLoaderOptions *loaderopt = new ssgLoaderOptions(); loaderopt->setCreateBranchCallback(hookNode); printf("\nLoading relief file %s\n", reliefFile); Root = ssgLoadAC(reliefFile, loaderopt); }
void load_params(void) { int i, j; int nbcol; char *col; char buf[256]; tFace *curFace; char *s; ImgSize = (int)GfParmGetNum(ParamHandle, "image", "size", NULL, 256); NbRows = GfParmGetEltNb(ParamHandle, "faces"); Row = (tRow*)calloc(NbRows, sizeof(tRow)); GfParmListSeekFirst(ParamHandle, "faces"); for (i = 0; i < NbRows; i++) { col = GfParmListGetCurEltName(ParamHandle, "faces"); GF_TAILQ_INIT(&(Row[i].faces)); sprintf(buf, "faces/%s/col", col); nbcol = GfParmGetEltNb(ParamHandle, buf); GfParmListSeekFirst(ParamHandle, buf); for (j = 0; j < nbcol; j++) { curFace = (tFace*)calloc(1, sizeof(tFace)); GF_TAILQ_INSERT_TAIL(&(Row[i].faces), curFace, link); curFace->faceName = GfParmGetCurStr(ParamHandle, buf, "face name", NULL); if ((curFace->faceName != 0) && (strlen(curFace->faceName) != 0)) { curFace->isPresent = true; curFace->xform.hpr[1] = GfParmGetCurNum(ParamHandle, buf, "rotX", NULL, 0.0); curFace->xform.hpr[2] = -GfParmGetCurNum(ParamHandle, buf, "rotZ", NULL, 0.0); curFace->xform.hpr[0] = GfParmGetCurNum(ParamHandle, buf, "rotY", NULL, 0.0); curFace->lscale[0] = GfParmGetCurNum(ParamHandle, buf, "scaleX", NULL, 1.0); curFace->lscale[1] = GfParmGetCurNum(ParamHandle, buf, "scaleZ", NULL, 1.0); curFace->lscale[2] = GfParmGetCurNum(ParamHandle, buf, "scaleY", NULL, 1.0); s = GfParmGetCurStr(ParamHandle, buf, "align", ""); switch (s[0]) { case 'X': case 'x': curFace->align[0] = 1.0; break; case 'Y': case 'y': curFace->align[2] = 1.0; break; case 'Z': case 'z': curFace->align[1] = -1.0; break; } } GfParmListSeekNext(ParamHandle, buf); } GfParmListSeekNext(ParamHandle, "faces"); } }
tRmInfo* ReSituationUpdater::initSituation(const tRmInfo* pSource) { tRmInfo* pTarget; // Allocate main structure (level 0). pTarget = (tRmInfo *)calloc(1, sizeof(tRmInfo)); // Allocate variable level 1 structures. pTarget->carList = (tCarElt*)calloc(_nInitDrivers, sizeof(tCarElt)); pTarget->s = (tSituation *)calloc(1, sizeof(tSituation)); pTarget->rules = (tRmCarRules*)calloc(_nInitDrivers, sizeof(tRmCarRules)); // Assign level 1 constants. pTarget->track = pSource->track; // Only read during race. pTarget->params = pSource->params; // Never read/written during race. pTarget->mainParams = pSource->mainParams; // Never read/written during race. pTarget->results = pSource->results; // Never read/written during race. pTarget->mainResults = pSource->mainResults; // Never read/written during race. pTarget->robModList = pSource->robModList; // Not used / written by updater. // Assign level 2 constants and initialize lists in carList field. for (int nCarInd = 0; nCarInd < _nInitDrivers; nCarInd++) { tCarElt* pTgtCar = &pTarget->carList[nCarInd]; tCarElt* pSrcCar = &pSource->carList[nCarInd]; pTgtCar->_curSplitTime = (double*)malloc(sizeof(double) * (pSource->track->numberOfSectors - 1)); pTgtCar->_bestSplitTime = (double*)malloc(sizeof(double) * (pSource->track->numberOfSectors - 1)); GF_TAILQ_INIT(&(pTgtCar->_penaltyList)); // Not used by the graphics engine. memcpy(&pTgtCar->info, &pSrcCar->info, sizeof(tInitCar)); // Not changed + only read during race. memcpy(&pTgtCar->priv, &pSrcCar->priv, sizeof(tPrivCar)); // Partly only read during race ; other copied in vars below. pTgtCar->robot = pSrcCar->robot; // Not changed + only read during race. } // Allocate level 2 structures in s field. pTarget->s->cars = (tCarElt **)calloc(_nInitDrivers, sizeof(tCarElt *)); // Allocate level 2 structures in raceEngineInfo field. pTarget->_reCarInfo = (tReCarInfo*)calloc(_nInitDrivers, sizeof(tReCarInfo)); // Assign level 2 constants in raceEngineInfo field. pTarget->_reParam = pSource->_reParam; // Not used / written by updater. pTarget->_reFilename = pSource->_reFilename; // Not used during race. pTarget->_reName = pSource->_reName; // Not changed + only read during race. pTarget->_reRaceName = pSource->_reRaceName; // Not changed + only read during race. return pTarget; }
/** * 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; }
/** Interactive Drivers list selection @param vs Pointer on tRmDrvSelect structure (cast to void) @warning The race manager params are modified but not saved. */ void RmDriversSelect(void *vs) { tModList *list; tModList *curmod; char dname[256]; char *sp; char *cardllname; int i, index; tDrvElt *curDrv; int nCars, robotIdx; void *robhdle; struct stat st; char *carName; void *carhdle; int human; #define B_BASE 380 #define B_HT 30 ds = (tRmDrvSelect*)vs; GF_TAILQ_INIT(&DrvList); scrHandle = GfuiScreenCreateEx((float*)NULL, NULL, rmdsActivate, NULL, (tfuiCallback)NULL, 1); GfuiScreenAddBgImg(scrHandle, "data/img/splash-qrdrv.png"); GfuiTitleCreate(scrHandle, "Select Drivers", sizeof("Select Drivers")); GfuiLabelCreate(scrHandle, "Selected", GFUI_FONT_LARGE, 120, 400, GFUI_ALIGN_HC_VB, 0); GfuiLabelCreate(scrHandle, "Not Selected", GFUI_FONT_LARGE, 496, 400, GFUI_ALIGN_HC_VB, 0); selectedScrollList = GfuiScrollListCreate(scrHandle, GFUI_FONT_MEDIUM_C, 20, 80, GFUI_ALIGN_HL_VB, 200, 310, GFUI_SB_RIGHT, NULL, rmdsClickOnDriver); unselectedScrollList = GfuiScrollListCreate(scrHandle, GFUI_FONT_MEDIUM_C, 396, 80, GFUI_ALIGN_HL_VB, 200, 310, GFUI_SB_RIGHT, NULL, rmdsClickOnDriver); GfuiButtonCreate(scrHandle, "Accept", GFUI_FONT_LARGE, 210, 40, 150, GFUI_ALIGN_HC_VB, GFUI_MOUSE_UP, NULL, rmdsSelect, NULL, (tfuiCallback)NULL, (tfuiCallback)NULL); GfuiButtonCreate(scrHandle, "Cancel", GFUI_FONT_LARGE, 430, 40, 150, GFUI_ALIGN_HC_VB, GFUI_MOUSE_UP, ds->prevScreen, rmdsDeactivate, NULL, (tfuiCallback)NULL, (tfuiCallback)NULL); GfuiButtonCreate(scrHandle, "Move Up", GFUI_FONT_MEDIUM, 320, B_BASE, 100, GFUI_ALIGN_HC_VB, GFUI_MOUSE_UP, (void*)-1, rmMove, NULL, (tfuiCallback)NULL, (tfuiCallback)NULL); GfuiButtonCreate(scrHandle, "Move Down", GFUI_FONT_MEDIUM, 320, B_BASE - B_HT, 100, GFUI_ALIGN_HC_VB, GFUI_MOUSE_UP, (void*)1, rmMove, NULL, (tfuiCallback)NULL, (tfuiCallback)NULL); GfuiButtonCreate(scrHandle, "(De)Select", GFUI_FONT_MEDIUM, 320, B_BASE - 2 * B_HT, 100, GFUI_ALIGN_HC_VB, GFUI_MOUSE_UP, (void*)0, rmSelectDeselect, NULL, (tfuiCallback)NULL, (tfuiCallback)NULL); GfuiButtonCreate(scrHandle, "Set Focus", GFUI_FONT_MEDIUM, 320, B_BASE - 3 * B_HT, 100, GFUI_ALIGN_HC_VB, GFUI_MOUSE_UP, NULL, rmdsSetFocus, NULL, (tfuiCallback)NULL, (tfuiCallback)NULL); list = (tModList *)NULL; sprintf(buf, "%sdrivers", GetLibDir ()); GfModInfoDir(CAR_IDENT, buf, 1, &list); curmod = list; if (curmod != NULL) { do { curmod = curmod->next; for (i = 0; i < MAX_MOD_ITF; i++) { if (curmod->modInfo[i].name) { sp = strrchr(curmod->sopath, '/'); if (sp == NULL) { sp = curmod->sopath; } else { sp++; } strcpy(dname, sp); dname[strlen(dname) - strlen(DLLEXT) - 1] = 0; /* cut .so or .dll */ sprintf(buf, "%sdrivers/%s/%s.xml", GetLocalDir(), dname, dname); robhdle = GfParmReadFile(buf, GFPARM_RMODE_STD); if (!robhdle) { sprintf(buf, "drivers/%s/%s.xml", dname, dname); robhdle = GfParmReadFile(buf, GFPARM_RMODE_STD); } sprintf(path, "%s/%s/%d", ROB_SECT_ROBOTS, ROB_LIST_INDEX, curmod->modInfo[i].index); carName = GfParmGetStr(robhdle, path, ROB_ATTR_CAR, ""); if (strcmp(GfParmGetStr(robhdle, path, ROB_ATTR_TYPE, ROB_VAL_ROBOT), ROB_VAL_ROBOT)) { human = 1; } else { human = 0; } sprintf(path, "cars/%s/%s.xml", carName, carName); if (!stat(path, &st)) { carhdle = GfParmReadFile(path, GFPARM_RMODE_STD); if (carhdle) { curDrv = (tDrvElt*)calloc(1, sizeof(tDrvElt)); curDrv->index = curmod->modInfo[i].index; curDrv->dname = strdup(dname); curDrv->name = strdup(curmod->modInfo[i].name); curDrv->car = carhdle; if (human) { curDrv->human = 1; GF_TAILQ_INSERT_HEAD(&DrvList, curDrv, link); } else { curDrv->human = 0; GF_TAILQ_INSERT_TAIL(&DrvList, curDrv, link); } } else { GfOut("Driver %s not selected because car %s is not readable\n", curmod->modInfo[i].name, carName); } } else { GfOut("Driver %s not selected because car %s is not present\n", curmod->modInfo[i].name, carName); } GfParmReleaseHandle(robhdle); } } } while (curmod != list); } nbSelectedDrivers = 0; nbMaxSelectedDrivers = (int)GfParmGetNum(ds->param, RM_SECT_DRIVERS, RM_ATTR_MAXNUM, NULL, 0); nCars = GfParmGetEltNb(ds->param, RM_SECT_DRIVERS); index = 1; for (i = 1; i < nCars+1; i++) { sprintf(dname, "%s/%d", RM_SECT_DRIVERS, i); cardllname = GfParmGetStr(ds->param, dname, RM_ATTR_MODULE, ""); robotIdx = (int)GfParmGetNum(ds->param, dname, RM_ATTR_IDX, (char*)NULL, 0); curDrv = GF_TAILQ_FIRST(&DrvList); if (curDrv != NULL) { do { if ((curDrv->index == robotIdx) && (strcmp(curDrv->dname, cardllname) == 0)) { if (nbSelectedDrivers < nbMaxSelectedDrivers) { GfuiScrollListInsertElement(scrHandle, selectedScrollList, curDrv->name, index, (void*)curDrv); curDrv->sel = index++; nbSelectedDrivers++; } break; } } while ((curDrv = GF_TAILQ_NEXT(curDrv, link)) != NULL); } } curDrv = GF_TAILQ_FIRST(&DrvList); if (curDrv != NULL) { do { if (curDrv->sel == 0) { GfuiScrollListInsertElement(scrHandle, unselectedScrollList, curDrv->name, 1000, (void*)curDrv); } } while ((curDrv = GF_TAILQ_NEXT(curDrv, link)) != NULL); } GfuiLabelCreate(scrHandle, "Focused:", GFUI_FONT_MEDIUM, 320, B_BASE - 5 * B_HT, GFUI_ALIGN_HC_VB, 0); cardllname = GfParmGetStr(ds->param, RM_SECT_DRIVERS, RM_ATTR_FOCUSED, ""); robotIdx = (int)GfParmGetNum(ds->param, RM_SECT_DRIVERS, RM_ATTR_FOCUSEDIDX, (char*)NULL, 0); curDrv = GF_TAILQ_FIRST(&DrvList); if (curDrv != NULL) { do { if ((curDrv->index == robotIdx) && (strcmp(curDrv->dname, cardllname) == 0)) { break; } } while ((curDrv = GF_TAILQ_NEXT(curDrv, link)) != NULL); } if (curDrv == NULL) { curDrv = GF_TAILQ_FIRST(&DrvList); } if (curDrv == NULL) { FocDrvLabelId = GfuiLabelCreate(scrHandle, "", GFUI_FONT_MEDIUM_C, 320, B_BASE - 5 * B_HT - GfuiFontHeight(GFUI_FONT_MEDIUM), GFUI_ALIGN_HC_VB, 256); } else { FocDrvLabelId = GfuiLabelCreate(scrHandle, curDrv->name, GFUI_FONT_MEDIUM_C, 320, B_BASE - 5 * B_HT - GfuiFontHeight(GFUI_FONT_MEDIUM), GFUI_ALIGN_HC_VB, 256); } /* Picked Driver Info */ GfuiLabelCreate(scrHandle, "Driver:", GFUI_FONT_MEDIUM, 320, B_BASE - 7 * B_HT, GFUI_ALIGN_HC_VB, 0); PickDrvNameLabelId = GfuiLabelCreateEx(scrHandle, "", aColor, GFUI_FONT_MEDIUM_C, 320, B_BASE - 7 * B_HT - GfuiFontHeight(GFUI_FONT_MEDIUM), GFUI_ALIGN_HC_VB, 256); GfuiLabelCreate(scrHandle, "Car:", GFUI_FONT_MEDIUM, 320, B_BASE - 8 * B_HT, GFUI_ALIGN_HC_VB, 0); PickDrvCarLabelId = GfuiLabelCreateEx(scrHandle, "", aColor, GFUI_FONT_MEDIUM_C, 320, B_BASE - 8 * B_HT - GfuiFontHeight(GFUI_FONT_MEDIUM), GFUI_ALIGN_HC_VB, 256); GfuiLabelCreate(scrHandle, "Category:", GFUI_FONT_MEDIUM, 320, B_BASE - 9 * B_HT, GFUI_ALIGN_HC_VB, 0); PickDrvCategoryLabelId = GfuiLabelCreateEx(scrHandle, "", aColor, GFUI_FONT_MEDIUM_C, 320, B_BASE - 9 * B_HT - GfuiFontHeight(GFUI_FONT_MEDIUM), GFUI_ALIGN_HC_VB, 256); GfuiMenuDefaultKeysAdd(scrHandle); rmdsAddKeys(); GfuiScreenActivate(scrHandle); }
/** 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; }