static void rmdsClickOnDriver(void * /* dummy */) { char *name; tDrvElt *curDrv; void *robhdle; name = GfuiScrollListGetSelectedElement(scrHandle, selectedScrollList, (void**)&curDrv); if (!name) { name = GfuiScrollListGetSelectedElement(scrHandle, unselectedScrollList, (void**)&curDrv); } if (name) { GfuiLabelSetText(scrHandle, PickDrvNameLabelId, curDrv->name); /* search driver infos */ sprintf(buf, "%sdrivers/%s/%s.xml", GetLocalDir(), curDrv->dname, curDrv->dname); robhdle = GfParmReadFile(buf, GFPARM_RMODE_STD); if (!robhdle) { sprintf(buf, "drivers/%s/%s.xml", curDrv->dname, curDrv->dname); robhdle = GfParmReadFile(buf, GFPARM_RMODE_STD); } if (robhdle != NULL) { sprintf(buf, "%s/%s/%d", ROB_SECT_ROBOTS, ROB_LIST_INDEX, curDrv->index); GfuiLabelSetText(scrHandle, PickDrvCarLabelId, GfParmGetName(curDrv->car)); GfuiLabelSetText(scrHandle, PickDrvCategoryLabelId, GfParmGetStr(curDrv->car, SECT_CAR, PRM_CATEGORY, "")); GfParmReleaseHandle(robhdle); } } }
void ReUpdateQualifCurRes(tCarElt *car) { int i; int nCars; int printed; int maxLines; void *carparam; char *carName; const char *race = ReInfo->_reRaceName; void *results = ReInfo->results; const int BUFSIZE = 1024; char buf[BUFSIZE], path[BUFSIZE]; ReResEraseScreen(); maxLines = ReResGetLines(); snprintf(buf, BUFSIZE, "%s on %s - Lap %d", car->_name, ReInfo->track->name, car->_laps); ReResScreenSetTitle(buf); snprintf(buf, BUFSIZE, "cars/%s/%s.xml", car->_carName, car->_carName); carparam = GfParmReadFile(buf, GFPARM_RMODE_STD); carName = GfParmGetName(carparam); printed = 0; snprintf(path, BUFSIZE, "%s/%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK); nCars = GfParmGetEltNb(results, path); nCars = MIN(nCars + 1, maxLines); for (i = 1; i < nCars; i++) { snprintf(path, BUFSIZE, "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, i); if (!printed) { if ((car->_bestLapTime != 0.0) && (car->_bestLapTime < GfParmGetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, 0))) { snprintf(buf, BUFSIZE, "%d - %s - %s (%s)", i, GfTime2Str(car->_bestLapTime, 0), car->_name, carName); ReResScreenSetText(buf, i - 1, 1); printed = 1; } } snprintf(buf, BUFSIZE, "%d - %s - %s (%s)", i + printed, GfTime2Str(GfParmGetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, 0), 0), GfParmGetStr(results, path, RE_ATTR_NAME, ""), GfParmGetStr(results, path, RE_ATTR_CAR, "")); ReResScreenSetText(buf, i - 1 + printed, 0); } if (!printed) { snprintf(buf, BUFSIZE, "%d - %s - %s (%s)", i, GfTime2Str(car->_bestLapTime, 0), car->_name, carName); ReResScreenSetText(buf, i - 1, 1); } GfParmReleaseHandle(carparam); ReInfo->_refreshDisplay = 1; }
/* return state mode */ int ReRaceRealStart(void) { int i, j; tRobotItf *robot; tReCarInfo *carInfo; char buf[128]; int foundHuman; void *params = ReInfo->params; tSituation *s = ReInfo->s; tMemoryPool oldPool = NULL; void* carHdle; // Load the physics engine if (!RaceEngine::self().loadPhysicsEngine()) return RM_ERROR; // Get the session display mode (default to "All sessions" ones, or else "normal"). std::string strDispMode = GfParmGetStr(params, ReInfo->_reRaceName, RM_ATTR_DISPMODE, ""); if (strDispMode.empty()) strDispMode = GfParmGetStr(params, RM_VAL_ANYRACE, RM_ATTR_DISPMODE, RM_VAL_VISIBLE); if (strDispMode == RM_VAL_INVISIBLE) ReInfo->_displayMode = RM_DISP_MODE_NONE; else if (strDispMode == RM_VAL_VISIBLE) ReInfo->_displayMode = RM_DISP_MODE_NORMAL; else if (strDispMode == RM_VAL_SIMUSIMU) ReInfo->_displayMode = RM_DISP_MODE_SIMU_SIMU; else { GfLogError("Unsupported display mode '%s' loaded from race file ; " "assuming 'normal'\n", strDispMode.c_str()); ReInfo->_displayMode = RM_DISP_MODE_NORMAL; } //GfLogDebug("ReRaceRealStart: Loaded dispMode=0x%x\n", ReInfo->_displayMode); // Check if there is a human in the driver list foundHuman = ReHumanInGroup() ? 2 : 0; // Reset SimuSimu bit if any human in the race. // Note: Done here in order to make SimuSimu faster. if ((ReInfo->_displayMode & RM_DISP_MODE_SIMU_SIMU) && foundHuman) { ReInfo->_displayMode &= ~RM_DISP_MODE_SIMU_SIMU; } // Initialize & place cars // Note: if SimuSimu display mode, robot->rbNewTrack isn't called. This is a lot faster. if (ReInitCars()) return RM_ERROR; // Check if there is a human in the current race // Warning: Don't move this before ReInitCars (initializes s->cars). for (i = 0; i < s->_ncars; i++) { if (s->cars[i]->_driverType == RM_DRV_HUMAN) { foundHuman = 1; break; }//if human }//for i // Force "normal" display mode if any human in the session if (foundHuman == 1) { ReInfo->_displayMode = RM_DISP_MODE_NORMAL; } // Force "result only" mode in Practice / Qualif. sessions without any human, // but at least 1 in another session (why this ?), and SimuSimu bit on. else if (foundHuman == 2 && (ReInfo->_displayMode & RM_DISP_MODE_SIMU_SIMU) && (ReInfo->s->_raceType == RM_TYPE_QUALIF || ReInfo->s->_raceType == RM_TYPE_PRACTICE)) { ReInfo->_displayMode = RM_DISP_MODE_NONE; } GfLogInfo("Display mode : %s\n", (ReInfo->_displayMode & RM_DISP_MODE_SIMU_SIMU) ? "SimuSimu" : ((ReInfo->_displayMode & RM_DISP_MODE_NORMAL) ? "Normal" : "Results-only")); // Notify the UI that it's "race loading time". ReUI().onRaceLoadingDrivers(); // Load drivers for the race for (i = 0; i < s->_ncars; i++) { snprintf(buf, sizeof(buf), "cars/%s/%s.xml", s->cars[i]->_carName, s->cars[i]->_carName); carHdle = GfParmReadFile(buf, GFPARM_RMODE_STD); snprintf(buf, sizeof(buf), "Loading %s driver (%s) ...", s->cars[i]->_name, GfParmGetName(carHdle)); ReUI().addLoadingMessage(buf); if (!(ReInfo->_displayMode & RM_DISP_MODE_SIMU_SIMU)) { //Tell robots they are to start a new race robot = s->cars[i]->robot; GfPoolMove( &s->cars[i]->_newRaceMemPool, &oldPool ); robot->rbNewRace(robot->index, s->cars[i], s); GfPoolFreePool( &oldPool ); }//if ! simusimu }//for i RtTeamManagerStart(); // Notify the UI that the drivers have been loaded now. ReUI().onRaceDriversLoaded(); // Initialize the physics engine RePhysicsEngine().updateSituation(s, RCM_MAX_DT_SIMU); carInfo = ReInfo->_reCarInfo; for (i = 0; i < s->_ncars; i++) { carInfo[i].prevTrkPos = s->cars[i]->_trkPos; } // All cars start with max brakes on ReUI().addLoadingMessage("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++) RePhysicsEngine().updateSituation(s, RCM_MAX_DT_SIMU); // Initialize current result manager. ReInitCurRes(); // More initializations. ReInfo->_reTimeMult = 1.0; ReInfo->_reLastRobTime = -1.0; if (NetGetNetwork()) ReInfo->s->currentTime = GfTimeClock() - NetGetNetwork()->GetRaceStartTime(); else ReInfo->s->currentTime = -2.0; // We start 2 seconds before the real race start ReInfo->s->deltaTime = RCM_MAX_DT_SIMU; ReInfo->s->_raceState = RM_RACE_STARTING; ReInfo->_rePitRequester = 0; ReInfo->_reMessage = 0; ReInfo->_reMessageEnd = 0.0; ReInfo->_reBigMessage = 0; ReInfo->_reBigMessageEnd = 0.0; ReInitUpdaters(); // Notify the UI that the race simulation is ready now. ReUI().onRaceSimulationReady(); // Initialize the network if needed. if (NetGetNetwork()) { ReUI().addLoadingMessage("Preparing online race ..."); NetGetNetwork()->RaceInit(ReOutputSituation()->s); NetGetNetwork()->SetRaceActive(true); } // Notify the UI that the race is now started. ReUI().addLoadingMessage("Ready."); ReUI().onRaceStarted(); // And go on looping the race state automaton. return RM_SYNC | RM_NEXT_STEP; }//ReRaceRealStart
void ReStoreRaceResults(const char *race) { int i; int nCars; tCarElt *car; tSituation *s = ReInfo->s; char *carName; void *carparam; void *results = ReInfo->results; void *params = ReInfo->params; const int BUFSIZE = 1024; char buf[BUFSIZE], path[BUFSIZE], path2[BUFSIZE]; /* Store the number of laps of the race */ switch (ReInfo->s->_raceType) { case RM_TYPE_RACE: car = s->cars[0]; if (car->_laps > s->_totLaps) car->_laps = s->_totLaps + 1; snprintf(path, BUFSIZE, "%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, race); GfParmListClean(results, path); GfParmSetNum(results, path, RE_ATTR_LAPS, NULL, car->_laps - 1); for (i = 0; i < s->_ncars; i++) { snprintf(path, BUFSIZE, "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, i + 1); car = s->cars[i]; if (car->_laps > s->_totLaps) car->_laps = s->_totLaps + 1; GfParmSetStr(results, path, RE_ATTR_NAME, car->_name); snprintf(buf, BUFSIZE, "cars/%s/%s.xml", car->_carName, car->_carName); carparam = GfParmReadFile(buf, GFPARM_RMODE_STD); carName = GfParmGetName(carparam); GfParmSetStr(results, path, RE_ATTR_CAR, carName); GfParmSetNum(results, path, RE_ATTR_INDEX, NULL, car->index); GfParmSetNum(results, path, RE_ATTR_LAPS, NULL, car->_laps - 1); GfParmSetNum(results, path, RE_ATTR_TIME, NULL, car->_curTime); GfParmSetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, car->_bestLapTime); GfParmSetNum(results, path, RE_ATTR_TOP_SPEED, NULL, car->_topSpeed); GfParmSetNum(results, path, RE_ATTR_DAMMAGES, NULL, car->_dammage); GfParmSetNum(results, path, RE_ATTR_NB_PIT_STOPS, NULL, car->_nbPitStops); GfParmSetStr(results, path, RE_ATTR_MODULE, car->_modName); GfParmSetNum(results, path, RE_ATTR_IDX, NULL, car->_driverIndex); snprintf(path2, BUFSIZE, "%s/%s/%d", race, RM_SECT_POINTS, i + 1); GfParmSetNum(results, path, RE_ATTR_POINTS, NULL, (int)GfParmGetNum(params, path2, RE_ATTR_POINTS, NULL, 0)); GfParmReleaseHandle(carparam); } break; case RM_TYPE_PRACTICE: car = s->cars[0]; snprintf(path, BUFSIZE, "%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, race); GfParmSetStr(results, path, RM_ATTR_DRVNAME, car->_name); break; case RM_TYPE_QUALIF: car = s->cars[0]; snprintf(path, BUFSIZE, "%s/%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK); nCars = GfParmGetEltNb(results, path); for (i = nCars; i > 0; i--) { snprintf(path, BUFSIZE, "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, i); float opponentBestLapTime = GfParmGetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, 0); if ( (car->_bestLapTime != 0.0) && ((car->_bestLapTime < opponentBestLapTime) || (opponentBestLapTime == 0.0)) ) { /* shift */ snprintf(path2, BUFSIZE, "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, i + 1); GfParmSetStr(results, path2, RE_ATTR_NAME, GfParmGetStr(results, path, RE_ATTR_NAME, "")); GfParmSetStr(results, path2, RE_ATTR_CAR, GfParmGetStr(results, path, RE_ATTR_CAR, "")); GfParmSetNum(results, path2, RE_ATTR_BEST_LAP_TIME, NULL, GfParmGetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, 0)); GfParmSetStr(results, path2, RE_ATTR_MODULE, GfParmGetStr(results, path, RM_ATTR_MODULE, "")); GfParmSetNum(results, path2, RE_ATTR_IDX, NULL, GfParmGetNum(results, path, RM_ATTR_IDX, NULL, 0)); snprintf(path, BUFSIZE, "%s/%s/%d", race, RM_SECT_POINTS, i + 1); GfParmSetNum(results, path2, RE_ATTR_POINTS, NULL, (int)GfParmGetNum(params, path, RE_ATTR_POINTS, NULL, 0)); } else { break; } } /* insert after */ snprintf(path, BUFSIZE, "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, i + 1); GfParmSetStr(results, path, RE_ATTR_NAME, car->_name); snprintf(buf, BUFSIZE, "cars/%s/%s.xml", car->_carName, car->_carName); carparam = GfParmReadFile(buf, GFPARM_RMODE_STD); carName = GfParmGetName(carparam); GfParmSetStr(results, path, RE_ATTR_CAR, carName); GfParmSetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, car->_bestLapTime); GfParmSetStr(results, path, RE_ATTR_MODULE, car->_modName); GfParmSetNum(results, path, RE_ATTR_IDX, NULL, car->_driverIndex); snprintf(path2, BUFSIZE, "%s/%s/%d", race, RM_SECT_POINTS, i + 1); GfParmSetNum(results, path, RE_ATTR_POINTS, NULL, (int)GfParmGetNum(params, path2, RE_ATTR_POINTS, NULL, 0)); GfParmReleaseHandle(carparam); break; } }
void ReUpdateRaceCurRes() { static const char* pszTableHeader = "Rank \tTime \tDriver \tCar"; int ncars; int xx; void *carparam; char *carName; tCarElt *car; char *tmp_str; double time_left; ncars = ReInfo->s->_ncars; if (ncars > ReUI().getResultsTableRowCount()) ncars = ReUI().getResultsTableRowCount(); char pszTitle[128]; snprintf(pszTitle, sizeof(pszTitle), "%s at %s", ReInfo->_reRaceName, ReInfo->track->name); if (ReInfo->s->_totTime > ReInfo->s->currentTime) { time_left = ReInfo->s->_totTime - ReInfo->s->currentTime; snprintf( buf, sizeof(buf), "%d:%02d:%02d", (int)floor( time_left / 3600.0f ), (int)floor( time_left / 60.0f ) % 60, (int)floor( time_left ) % 60 ); } else { snprintf( buf, sizeof(buf), "%d laps", ReInfo->s->_totLaps ); } ReUI().setResultsTableTitles(pszTitle, buf); ReUI().setResultsTableHeader(pszTableHeader); for (xx = 0; xx < ncars; ++xx) { car = ReInfo->s->cars[ xx ]; snprintf(buf, sizeof(buf), "cars/models/%s/%s.xml", car->_carName, car->_carName); carparam = GfParmReadFile(buf, GFPARM_RMODE_STD); carName = strdup(GfParmGetName(carparam)); GfParmReleaseHandle(carparam); if (car->_state & RM_CAR_STATE_DNF) { snprintf(buf, sizeof(buf), "out %-20s %-20s", car->_name, carName); } else if (car->_timeBehindLeader == 0.0f) { if (xx != 0) snprintf(buf, sizeof(buf), " %2d \t --:--- \t%-25s \t%-20s", xx + 1, car->_name, carName); else snprintf(buf, sizeof(buf), " %2d \t%3d laps \t%-25s \t%-20s", xx + 1, car->_laps - 1, car->_name, carName); } else { if (xx == 0) { snprintf(buf, sizeof(buf), " %2d \t%3d laps \t%-25s \t%-20s", xx + 1, car->_laps - 1, car->_name, carName); } else { if (car->_lapsBehindLeader == 0) { tmp_str = GfTime2Str(car->_timeBehindLeader, " ", false, 3); snprintf(buf, sizeof(buf), " %2d \t%-12s\t%-25s \t%-20s", xx + 1, tmp_str, car->_name, carName); free(tmp_str); } else if (car->_lapsBehindLeader == 1) snprintf(buf, sizeof(buf), " %2d \t 1 lap \t%-25s \t%-20s", xx + 1, car->_name, carName); else snprintf(buf, sizeof(buf), " %2d \t %3d laps \t%-25s \t%-20s", xx + 1, car->_lapsBehindLeader, car->_name, carName); } } ReUI().setResultsTableRow(xx, buf); FREEZ(carName); } }
void ReUpdateQualifCurRes(tCarElt *car) { static const char* pszTableHeader = "Rank \tTime \tDriver \tCar"; int i; int xx; int nCars; int nCarsReal; int printed; int maxLines; void *carparam; char *carName; const char *race = ReInfo->_reRaceName; void *results = ReInfo->results; char *tmp_str; double time_left; if (ReInfo->s->_ncars == 1) { ReUI().eraseResultsTable(); maxLines = ReUI().getResultsTableRowCount(); snprintf(buf, sizeof(buf), "cars/models/%s/%s.xml", car->_carName, car->_carName); carparam = GfParmReadFile(buf, GFPARM_RMODE_STD); carName = GfParmGetName(carparam); char pszTitle[128]; snprintf(pszTitle, sizeof(pszTitle), "%s at %s", race, ReInfo->track->name); if (ReInfo->s->_raceType == RM_TYPE_PRACTICE || car->_laps < 1 || car->_laps > ReInfo->s->_totLaps) snprintf(buf, sizeof(buf), "%s (%s)", car->_name, carName); else snprintf(buf, sizeof(buf), "%s (%s) - Lap %d", car->_name, carName, car->_laps); ReUI().setResultsTableTitles(pszTitle, buf); ReUI().setResultsTableHeader(pszTableHeader); printed = 0; snprintf(path, sizeof(path), "%s/%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK); nCarsReal = GfParmGetEltNb(results, path); nCars = MIN(nCarsReal + 1, maxLines); // limit display to only those on 1st page for (i = 1; i < nCars; i++) { snprintf(path, sizeof(path), "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, i); if (!printed && car->_bestLapTime != 0.0 && car->_bestLapTime < GfParmGetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, 0)) { tmp_str = GfTime2Str(car->_bestLapTime, " ", false, 3); snprintf(buf, sizeof(buf), " %2d \t%-12s \t%-25s \t%-20s", i, tmp_str, car->_name, carName); free(tmp_str); ReUI().setResultsTableRow(i - 1, buf, /*highlight=*/true); printed = 1; } tmp_str = GfTime2Str(GfParmGetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, 0), " ", false, 3); snprintf(buf, sizeof(buf), " %2d \t%-12s \t%-25s \t%-20s", i + printed, tmp_str, GfParmGetStr(results, path, RE_ATTR_NAME, ""), GfParmGetStr(results, path, RE_ATTR_CAR, "")); free (tmp_str); ReUI().setResultsTableRow(i - 1 + printed, buf); } if (!printed) { tmp_str = GfTime2Str(car->_bestLapTime, " ", false, 3); snprintf(buf, sizeof(buf), " %2d \t%-12s \t%-25s \t%-20s", nCarsReal + 1, tmp_str, car->_name, carName); free(tmp_str); ReUI().setResultsTableRow(i - 1, buf, /*highlight=*/true); } GfParmReleaseHandle(carparam); } else { nCars = ReInfo->s->_ncars; if (nCars > ReUI().getResultsTableRowCount()) nCars = ReUI().getResultsTableRowCount(); char pszTitle[128]; snprintf(pszTitle, sizeof(pszTitle), "%s at %s", race, ReInfo->track->name); if (ReInfo->s->_totTime > ReInfo->s->currentTime) { time_left = ReInfo->s->_totTime - ReInfo->s->currentTime; snprintf( buf, sizeof(buf), "%d:%02d:%02d", (int)floor( time_left / 3600.0f ), (int)floor( time_left / 60.0f ) % 60, (int)floor( time_left ) % 60 ); } else { snprintf( buf, sizeof(buf), "%d laps", ReInfo->s->_totLaps ); } ReUI().setResultsTableTitles(pszTitle, buf); ReUI().setResultsTableHeader(pszTableHeader); for (xx = 0; xx < nCars; ++xx) { car = ReInfo->s->cars[ xx ]; snprintf(buf, sizeof(buf), "cars/models/%s/%s.xml", car->_carName, car->_carName); carparam = GfParmReadFile(buf, GFPARM_RMODE_STD); carName = strdup(GfParmGetName(carparam)); GfParmReleaseHandle(carparam); if (car->_state & RM_CAR_STATE_DNF) { snprintf(buf, sizeof(buf), "out \t \t%-25s \t%-20s", car->_name, carName); } else if (car->_bestLapTime <= 0.0f) { snprintf(buf, sizeof(buf), " %2d \t --:--- \t%-25s \t%-20s", xx + 1, car->_name, carName); } else { if (xx == 0) tmp_str = GfTime2Str(car->_bestLapTime, " ", false, 3); else tmp_str = GfTime2Str(car->_bestLapTime - ReInfo->s->cars[0]->_bestLapTime, "+", false, 3); snprintf(buf, sizeof(buf), " %2d \t%-12s \t%-25s \t%-20s", xx + 1, tmp_str, car->_name, carName); free(tmp_str); } ReUI().setResultsTableRow(xx, buf); FREEZ(carName); } } }
void ReStoreRaceResults(const char *race) { int i; int nCars; tCarElt *car; tSituation *s = ReInfo->s; char *carName; void *carparam; void *results = ReInfo->results; void *params = ReInfo->params; /* Store the number of laps of the race */ switch (ReInfo->s->_raceType) { case RM_TYPE_RACE: car = s->cars[0]; if (car->_laps > s->_totLaps) car->_laps = s->_totLaps + 1; snprintf(path, sizeof(path), "%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, race); GfParmListClean(results, path); GfParmSetNum(results, path, RE_ATTR_LAPS, NULL, (tdble)(car->_laps - 1)); for (i = 0; i < s->_ncars; i++) { snprintf(path, sizeof(path), "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, i + 1); car = s->cars[i]; if (car->_laps > s->_totLaps) car->_laps = s->_totLaps + 1; GfParmSetStr(results, path, RE_ATTR_NAME, car->_name); snprintf(buf, sizeof(buf), "cars/models/%s/%s.xml", car->_carName, car->_carName); carparam = GfParmReadFile(buf, GFPARM_RMODE_STD); carName = GfParmGetName(carparam); GfParmSetStr(results, path, RE_ATTR_CAR, carName); GfParmSetNum(results, path, RE_ATTR_INDEX, NULL, (tdble)car->index); GfParmSetNum(results, path, RE_ATTR_LAPS, NULL, (tdble)(car->_laps - 1)); GfParmSetNum(results, path, RE_ATTR_TIME, NULL, (tdble)car->_curTime); GfParmSetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, (tdble)car->_bestLapTime); GfParmSetNum(results, path, RE_ATTR_TOP_SPEED, NULL, car->_topSpeed); GfParmSetNum(results, path, RE_ATTR_DAMMAGES, NULL, (tdble)car->_dammage); GfParmSetNum(results, path, RE_ATTR_NB_PIT_STOPS, NULL, (tdble)car->_nbPitStops); GfParmSetStr(results, path, RE_ATTR_MODULE, car->_modName); GfParmSetNum(results, path, RE_ATTR_IDX, NULL, (tdble)car->_moduleIndex); snprintf(path2, sizeof(path2), "%s/%d", RM_SECT_DRIVERS_RACING, car->index + 1 ); GfParmSetNum(results, path, RM_ATTR_EXTENDED, NULL, GfParmGetNum(params, path2, RM_ATTR_EXTENDED, NULL, 0)); GfParmSetStr(results, path, ROB_ATTR_CAR, car->_carName); snprintf(path2, sizeof(path2), "%s/%s/%d", race, RM_SECT_POINTS, i + 1); GfParmSetNum(results, path, RE_ATTR_POINTS, NULL, GfParmGetNum(params, path2, RE_ATTR_POINTS, NULL, 0)); if (strlen(car->_skinName) > 0) GfParmSetStr(results, path, RM_ATTR_SKINNAME, car->_skinName); GfParmSetNum(results, path, RM_ATTR_SKINTARGETS, NULL, (tdble)car->_skinTargets); GfParmReleaseHandle(carparam); } break; case RM_TYPE_PRACTICE: if (s->_ncars == 1) { car = s->cars[0]; snprintf(path, sizeof(path), "%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, race); GfParmSetStr(results, path, RM_ATTR_DRVNAME, car->_name); snprintf(buf, sizeof(buf), "cars/models/%s/%s.xml", car->_carName, car->_carName); carparam = GfParmReadFile(buf, GFPARM_RMODE_STD); carName = GfParmGetName(carparam); GfParmSetStr(results, path, RE_ATTR_CAR, carName); GfParmReleaseHandle(carparam); break; } /* Otherwise, fall through */ case RM_TYPE_QUALIF: if (s->_ncars == 1) { car = s->cars[0]; snprintf(path, sizeof(path), "%s/%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK); nCars = GfParmGetEltNb(results, path); for (i = nCars; i > 0; i--) { snprintf(path, sizeof(path), "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, i); float opponentBestLapTime = GfParmGetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, 0); if (car->_bestLapTime != 0.0 && (car->_bestLapTime < opponentBestLapTime || opponentBestLapTime == 0.0)) { /* shift */ snprintf(path2, sizeof(path2), "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, i + 1); GfParmSetStr(results, path2, RE_ATTR_NAME, GfParmGetStr(results, path, RE_ATTR_NAME, "")); GfParmSetStr(results, path2, RE_ATTR_CAR, GfParmGetStr(results, path, RE_ATTR_CAR, "")); GfParmSetNum(results, path2, RE_ATTR_BEST_LAP_TIME, NULL, GfParmGetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, 0)); GfParmSetStr(results, path2, RE_ATTR_MODULE, GfParmGetStr(results, path, RM_ATTR_MODULE, "")); GfParmSetNum(results, path2, RE_ATTR_IDX, NULL, GfParmGetNum(results, path, RM_ATTR_IDX, NULL, 0)); GfParmSetNum(results, path2, RM_ATTR_EXTENDED, NULL, GfParmGetNum(results, path, RM_ATTR_EXTENDED, NULL, 0)); GfParmSetStr(results, path2, ROB_ATTR_CAR, GfParmGetStr(results, path, ROB_ATTR_CAR, "")); GfParmSetStr(results, path2, ROB_ATTR_NAME, GfParmGetStr(results, path, ROB_ATTR_NAME, "")); snprintf(path, sizeof(path), "%s/%s/%d", race, RM_SECT_POINTS, i + 1); GfParmSetNum(results, path2, RE_ATTR_POINTS, NULL, GfParmGetNum(params, path, RE_ATTR_POINTS, NULL, 0)); if (GfParmGetStr(results, path, RM_ATTR_SKINNAME, 0)) GfParmSetStr(results, path2, RM_ATTR_SKINNAME, GfParmGetStr(results, path, RM_ATTR_SKINNAME, 0)); GfParmSetNum(results, path2, RM_ATTR_SKINTARGETS, NULL, GfParmGetNum(results, path, RM_ATTR_SKINTARGETS, NULL, 0)); } else { break; } } /* insert after */ snprintf(path, sizeof(path), "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, i + 1); GfParmSetStr(results, path, RE_ATTR_NAME, car->_name); snprintf(buf, sizeof(buf), "cars/models/%s/%s.xml", car->_carName, car->_carName); carparam = GfParmReadFile(buf, GFPARM_RMODE_STD); carName = GfParmGetName(carparam); GfParmSetStr(results, path, RE_ATTR_CAR, carName); GfParmSetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, (tdble)car->_bestLapTime); GfParmSetStr(results, path, RE_ATTR_MODULE, car->_modName); GfParmSetNum(results, path, RE_ATTR_IDX, NULL, (tdble)car->_moduleIndex); GfParmSetStr(results, path, ROB_ATTR_CAR, car->_carName); GfParmSetStr(results, path, ROB_ATTR_NAME, car->_name); snprintf(path2, sizeof(path2), "%s/%d", RM_SECT_DRIVERS_RACING, car->index + 1 ); GfParmSetNum(results, path, RM_ATTR_EXTENDED, NULL, GfParmGetNum(params, path2, RM_ATTR_EXTENDED, NULL, 0)); snprintf(path2, sizeof(path2), "%s/%s/%d", race, RM_SECT_POINTS, i + 1); GfParmSetNum(results, path, RE_ATTR_POINTS, NULL, GfParmGetNum(params, path2, RE_ATTR_POINTS, NULL, 0)); if (strlen(car->_skinName) > 0) GfParmSetStr(results, path, RM_ATTR_SKINNAME, car->_skinName); GfParmSetNum(results, path, RM_ATTR_SKINTARGETS, NULL, (tdble)car->_skinTargets); GfParmReleaseHandle(carparam); break; } else { car = s->cars[0]; if (s->_totTime < 0.0f) GfLogWarning("Saving results of multicar non-race session, but it was not timed!\n" ); snprintf(path, sizeof(path), "%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, race); GfParmListClean(results, path); GfParmSetNum(results, path, RE_ATTR_SESSIONTIME, NULL, (tdble)s->_totTime); for (i = 0; i < s->_ncars; i++) { snprintf(path, sizeof(path), "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, i + 1); car = s->cars[i]; GfParmSetStr(results, path, RE_ATTR_NAME, car->_name); snprintf(buf, sizeof(buf), "cars/models/%s/%s.xml", car->_carName, car->_carName); carparam = GfParmReadFile(buf, GFPARM_RMODE_STD); carName = GfParmGetName(carparam); GfParmSetStr(results, path, RE_ATTR_CAR, carName); GfParmSetNum(results, path, RE_ATTR_INDEX, NULL, (tdble)car->index); GfParmSetNum(results, path, RE_ATTR_LAPS, NULL, (tdble)(car->_laps - 1)); GfParmSetNum(results, path, RE_ATTR_TIME, NULL, (tdble)car->_curTime); GfParmSetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, (tdble)car->_bestLapTime); GfParmSetNum(results, path, RE_ATTR_TOP_SPEED, NULL, car->_topSpeed); GfParmSetNum(results, path, RE_ATTR_DAMMAGES, NULL, (tdble)car->_dammage); GfParmSetNum(results, path, RE_ATTR_NB_PIT_STOPS, NULL, (tdble)car->_nbPitStops); GfParmSetStr(results, path, RE_ATTR_MODULE, car->_modName); GfParmSetNum(results, path, RE_ATTR_IDX, NULL, (tdble)car->_moduleIndex); snprintf(path2, sizeof(path2), "%s/%d", RM_SECT_DRIVERS_RACING, car->index + 1 ); GfParmSetNum(results, path, RM_ATTR_EXTENDED, NULL, GfParmGetNum(params, path2, RM_ATTR_EXTENDED, NULL, 0)); GfParmSetStr(results, path, ROB_ATTR_CAR, car->_carName); snprintf(path2, sizeof(path2), "%s/%s/%d", race, RM_SECT_POINTS, i + 1); GfParmSetNum(results, path, RE_ATTR_POINTS, NULL, GfParmGetNum(params, path2, RE_ATTR_POINTS, NULL, 0)); if (strlen(car->_skinName) > 0) GfParmSetStr(results, path, RM_ATTR_SKINNAME, car->_skinName); GfParmSetNum(results, path, RM_ATTR_SKINTARGETS, NULL, (tdble)car->_skinTargets); GfParmReleaseHandle(carparam); } break; } } }