/* Race Engine Initialization */ void ReInit(void) { char *dllname; char key[256]; tRmMovieCapture *capture; ReShutdown(); ReInfo = (tRmInfo *)calloc(1, sizeof(tRmInfo)); ReInfo->s = (tSituation *)calloc(1, sizeof(tSituation)); ReInfo->modList = &ReRaceModList; char buf[1024]; snprintf(buf, 1024, "%s%s", GetLocalDir(), RACE_ENG_CFG); ReInfo->_reParam = GfParmReadFile(buf, GFPARM_RMODE_REREAD | GFPARM_RMODE_CREAT); GfOut("Loading Track Loader...\n"); dllname = GfParmGetStr(ReInfo->_reParam, "Modules", "track", ""); sprintf(key, "%smodules/track/%s.%s", GetLibDir (), dllname, DLLEXT); if (GfModLoad(0, key, &reEventModList)) return; reEventModList->modInfo->fctInit(reEventModList->modInfo->index, &ReInfo->_reTrackItf); GfOut("Loading Graphic Engine...\n"); dllname = GfParmGetStr(ReInfo->_reParam, "Modules", "graphic", ""); sprintf(key, "%smodules/graphic/%s.%s", GetLibDir (), dllname, DLLEXT); if (GfModLoad(0, key, &reEventModList)) return; reEventModList->modInfo->fctInit(reEventModList->modInfo->index, &ReInfo->_reGraphicItf); capture = &(ReInfo->movieCapture); if (strcmp(GfParmGetStr(ReInfo->_reParam, RM_SECT_MOVIE_CAPTURE, RM_ATT_CAPTURE_ENABLE, "no"), "no") == 0){ capture->enabled = 0; } else { capture->enabled = 1; capture->state = 0; capture->deltaFrame = 1.0 / GfParmGetNum(ReInfo->_reParam, RM_SECT_MOVIE_CAPTURE, RM_ATT_CAPTURE_FPS, NULL, 1.0); capture->outputBase = GfParmGetStr(ReInfo->_reParam, RM_SECT_MOVIE_CAPTURE, RM_ATT_CAPTURE_OUT_DIR, "/tmp"); capture->deltaSimu = RCM_MAX_DT_SIMU; } ReInfo->_reGameScreen = ReHookInit(); }
/** 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]; tModInfo *curModInfo; memset(&tlm, 0, sizeof(tTelemItf)); sprintf(buf, "%smodules/telemetry/%s.%s", "telemetry", GetLibDir (), 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 }
static void Generate(void) { char *trackdllname; char *extName; FILE *outfd = NULL; // Get the trackgen paramaters. sprintf(buf, "%s", CFG_FILE); CfgHandle = GfParmReadFile(buf, GFPARM_RMODE_STD | GFPARM_RMODE_CREAT); trackdllname = GfParmGetStr(CfgHandle, "Modules", "track", "track"); sprintf(buf, "%smodules/track/%s.%s", GetLibDir (), trackdllname, DLLEXT); if (GfModLoad(TRK_IDENT, buf, &modlist) < 0) { GfFatal("Failed to find the track module %s", buf); } if (modlist->modInfo->fctInit(modlist->modInfo->index, &TrackItf)) { GfFatal("Failed to init the track module %s", buf); } // This is the track definition. sprintf(trackdef, "tracks/%s/%s/%s.xml", 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 = TrackItf.trkBuildEx(trackdef); if (!JustCalculate) { // Get the output file radix. sprintf(buf2, "tracks/%s/%s/%s", Track->category, Track->internalname, Track->internalname); OutputFileName = strdup(buf2); // Number of goups 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, saveElevation); if (saveElevation != -1) { if (outfd) { Ac3dClose(outfd); } switch (saveElevation) { case 0: case 1: sprintf(buf2, "%s.ac", OutputFileName); sprintf(buf, "%s-elv.png", OutputFileName); SaveElevation(Track, TrackHandle, buf, buf2, 1); if (saveElevation) { break; } case 2: sprintf(buf, "%s-elv2.png", OutputFileName); SaveElevation(Track, TrackHandle, buf, OutMeshName, 1); if (saveElevation) { break; } case 3: sprintf(buf, "%s-elv3.png", OutputFileName); SaveElevation(Track, TrackHandle, buf, OutMeshName, 0); if (saveElevation) { break; } case 4: sprintf(buf, "%s-elv4.png", OutputFileName); SaveElevation(Track, TrackHandle, buf, OutTrackName, 2); break; } return; } GenerateObjects(Track, TrackHandle, CfgHandle, outfd, OutMeshName); }
/** 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); }
/* 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; }
/** 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; }