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; }
/* 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(); }
/* 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; }