diff --git a/src/libs/raceengine/racemain.cpp b/src/libs/raceengine/racemain.cpp index 0389c4ec7..165f51a73 100644 --- a/src/libs/raceengine/racemain.cpp +++ b/src/libs/raceengine/racemain.cpp @@ -178,20 +178,18 @@ int RePreRace(void) { char path[64]; - tdble dist; const char *raceName; const char *raceType; void *params = ReInfo->params; void *results = ReInfo->results; int curRaceIdx; - int laps; raceName = ReInfo->_reRaceName = ReGetCurrentRaceName(); - GfParmRemoveVariable (ReInfo->params, "/", "humanInGroup"); - GfParmRemoveVariable (ReInfo->params, "/", "eventNb"); - GfParmSetVariable (ReInfo->params, "/", "humanInGroup", ReHumanInGroup() ? 1.0f : 0.0f); - GfParmSetVariable (ReInfo->params, "/", "eventNb", GfParmGetNum (ReInfo->results, RE_SECT_CURRENT, RE_ATTR_CUR_TRACK, NULL, 1.0 ) ); + GfParmRemoveVariable (params, "/", "humanInGroup"); + GfParmRemoveVariable (params, "/", "eventNb"); + GfParmSetVariable (params, "/", "humanInGroup", ReHumanInGroup() ? 1.0f : 0.0f); + GfParmSetVariable (params, "/", "eventNb", GfParmGetNum (ReInfo->results, RE_SECT_CURRENT, RE_ATTR_CUR_TRACK, NULL, 1.0 ) ); if (!raceName) { return RM_ERROR; } @@ -212,32 +210,55 @@ RePreRace(void) return RM_SYNC | RM_NEXT_RACE | RM_NEXT_STEP; } + // Get session max dammages. ReInfo->s->_maxDammage = (int)GfParmGetNum(params, raceName, RM_ATTR_MAX_DMG, NULL, 10000); - ReInfo->s->_extraLaps = 0; - ReInfo->s->_totLaps = 30; /* Make sure it is initialized */ - ReInfo->s->_totTime = GfParmGetNum(params, raceName, RM_ATTR_SESSIONTIME, NULL, -60.0f); - if (ReInfo->s->_totTime > 0.0f && ( ReInfo->s->_features & RM_FEATURE_TIMEDSESSION ) == 0 ) - { - /* Timed session not supported: add 2 km for every minute */ - ReInfo->s->_totLaps = (int)floor(ReInfo->s->_totTime * 2000.0f / ReInfo->track->length + 0.5f); + + // Get session duration (defaults to "All sessions" one, or else -60). + ReInfo->s->_totTime = GfParmGetNum(params, raceName, RM_ATTR_SESSIONTIME, NULL, -1); + if (ReInfo->s->_totTime < 0) + ReInfo->s->_totTime = GfParmGetNum(params, RM_VAL_ANYRACE, RM_ATTR_SESSIONTIME, NULL, -60.0f); + + // Determine the actual session duration and/or number of laps. + ReInfo->s->_extraLaps = 0; // TODO: Does this is ever needed ? + ReInfo->s->_totLaps = 30; // Make sure it is initialized + + if (ReInfo->s->_totTime > 0 && !(ReInfo->s->_features & RM_FEATURE_TIMEDSESSION)) { + // Timed session not supported: add 2 km for every minute + ReInfo->s->_totLaps = (int)floor(ReInfo->s->_totTime * 2000.0f / 60.0f / ReInfo->track->length + 0.5f); ReInfo->s->_totTime = -60.0f; } - if (ReInfo->s->_totTime <= 0.0f) - { - ReInfo->s->_totTime = -60.0f; /* Make sure that if no time is set, the set is far below zero */ - dist = GfParmGetNum(params, raceName, RM_ATTR_DISTANCE, NULL, 0.0); - if (dist >= 0.001) { - ReInfo->s->_totLaps = ((int)(dist / ReInfo->track->length)) + 1; + + if (ReInfo->s->_totTime <= 0) { + // Make sure that if no time set, we set far below zero + ReInfo->s->_totTime = -60.0f; + + // Get session distance (defaults to "All sessions" one, or else 0). + tdble dist = GfParmGetNum(params, raceName, RM_ATTR_DISTANCE, NULL, -1); + if (dist < 0) + dist = GfParmGetNum(params, RM_VAL_ANYRACE, RM_ATTR_DISTANCE, NULL, 0); + + // If a (> 0) session distance was specified, deduce the number of laps + // in case the race settings don't specify it. + if (dist >= 0.001) { // Why not 'if (dist > 0)' ??? + ReInfo->s->_totLaps = (int)(dist / ReInfo->track->length) + 1; + ReInfo->s->_extraLaps = ReInfo->s->_totLaps; // TODO: Does this is ever needed ? } - laps = (int)GfParmGetNum(params, raceName, RM_ATTR_LAPS, NULL, (tdble)ReInfo->s->_totLaps); + + // Get the number of laps (defaults to "All sessions" one, + // or else the already computed one from the session distance, or 30). + int laps = (int)GfParmGetNum(params, raceName, RM_ATTR_LAPS, NULL, -1); + if (laps < 0) + laps = (int)GfParmGetNum(params, RM_VAL_ANYRACE, RM_ATTR_LAPS, NULL, (tdble)ReInfo->s->_totLaps); if (laps > 0 ) { ReInfo->s->_totLaps = laps; + ReInfo->s->_extraLaps = ReInfo->s->_totLaps; // TODO: Does this is ever needed ? } } else { ReInfo->s->_totLaps = 0; } + // Get session type (race, qualification or practice). raceType = GfParmGetStr(params, raceName, RM_ATTR_TYPE, RM_VAL_RACE); if (!strcmp(raceType, RM_VAL_RACE)) { ReInfo->s->_raceType = RM_TYPE_RACE; @@ -247,16 +268,19 @@ RePreRace(void) ReInfo->s->_raceType = RM_TYPE_PRACTICE; } - if (ReInfo->s->_raceType != RM_TYPE_RACE && ReInfo->s->_extraLaps > 0) - { - /* During timed practice or qualification, there are no extra laps */ - ReInfo->s->_extraLaps = 0; - ReInfo->s->_totLaps = 0; + // Correct extra laps (possible laps run after the winner arrived ?) : + // during timed practice or qualification, there are none. + if (ReInfo->s->_raceType != RM_TYPE_RACE && ReInfo->s->_totTime > 0) { + ReInfo->s->_extraLaps = 0; // TODO: Does this is ever needed ? } + GfLogInfo("Race length : time=%.0fs, laps=%d (extra=%d)\n", + ReInfo->s->_totTime, ReInfo->s->_totLaps, ReInfo->s->_extraLaps); + + // Initialize race state. ReInfo->s->_raceState = 0; - /* Cleanup results */ + // Cleanup results snprintf(path, sizeof(path), "%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, raceName); GfParmListClean(results, path); @@ -280,13 +304,20 @@ ReRaceRealStart(void) // 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); + // Check if there is a human in the driver list foundHuman = ReHumanInGroup() ? 2 : 0; // TODO: Replace this _displayMode dirty hack by adding a new bSimuSimu arg to ReInitCars ? // Set _displayMode here because then robot->rbNewTrack isn't called. This is a lot faster for simusimu - if (strcmp(GfParmGetStr(params, ReInfo->_reRaceName, RM_ATTR_DISPMODE, RM_VAL_VISIBLE), RM_VAL_SIMUSIMU) == 0 && foundHuman == 0) + if (strDispMode == RM_VAL_SIMUSIMU && foundHuman == 0) ReInfo->_displayMode = RM_DISP_MODE_SIMU_SIMU; else ReInfo->_displayMode = RM_DISP_MODE_NORMAL; @@ -296,6 +327,7 @@ ReRaceRealStart(void) return RM_ERROR; // Check if there is a human in the current race + // TODO: Why is this computed again, after ReHumanInGroup(), and in a different way ??? for (i = 0; i < s->_ncars; i++) { if (s->cars[i]->_driverType == RM_DRV_HUMAN) { foundHuman = 1; @@ -309,8 +341,6 @@ ReRaceRealStart(void) if (foundHuman != 1) { // No human in current race - const std::string strDispMode = - GfParmGetStr(params, ReInfo->_reRaceName, RM_ATTR_DISPMODE, RM_VAL_VISIBLE); if (strDispMode == RM_VAL_INVISIBLE) { ReInfo->_displayMode = RM_DISP_MODE_NONE; diff --git a/src/libs/raceengine/racetrack.cpp b/src/libs/raceengine/racetrack.cpp index 3bf9b2833..00598c6d6 100644 --- a/src/libs/raceengine/racetrack.cpp +++ b/src/libs/raceengine/racetrack.cpp @@ -191,10 +191,14 @@ reTrackInitTimeOfDay(void) tTrackLocalInfo *trackLocal = &ReInfo->track->local; - // Load time of day settings for the race. + // Load time of day settings for the session + // (defaults to "All sesions" one, or else "afternoon"). int timeofday = RM_IND_TIME_AFTERNOON; const char* pszTimeOfDay = - GfParmGetStr(ReInfo->params, ReInfo->_reRaceName, RM_ATTR_TIME_OF_DAY, RM_VAL_TIME_AFTERNOON); + GfParmGetStr(ReInfo->params, ReInfo->_reRaceName, RM_ATTR_TIME_OF_DAY, 0); + if (!pszTimeOfDay) + pszTimeOfDay = + GfParmGetStr(ReInfo->params, RM_VAL_ANYRACE, RM_ATTR_TIME_OF_DAY, RM_VAL_TIME_AFTERNOON); for (int i = 0; i < NTimeOfDayValues; i++) if (!strcmp(pszTimeOfDay, TimeOfDayValues[i])) { @@ -264,10 +268,14 @@ reTrackInitWeather(void) tTrackLocalInfo *trackLocal = &ReInfo->track->local; - // Load cloud cover settings for the race. + // Load cloud cover settings for the session + // (defaults to "All sesions" one, or else "none"). int clouds = TR_CLOUDS_NONE; const char* pszClouds = - GfParmGetStr(ReInfo->params, ReInfo->_reRaceName, RM_ATTR_CLOUDS, RM_VAL_CLOUDS_NONE); + GfParmGetStr(ReInfo->params, ReInfo->_reRaceName, RM_ATTR_CLOUDS, 0); + if (!pszClouds) + pszClouds = + GfParmGetStr(ReInfo->params, RM_VAL_ANYRACE, RM_ATTR_CLOUDS, RM_VAL_CLOUDS_NONE); for (int i = 0; i < NCloudsValues; i++) if (!strcmp(pszClouds, CloudsValues[i])) { @@ -275,12 +283,16 @@ reTrackInitWeather(void) break; } - // Load rain fall (and track dry/wet conditions) settings for the race if feature supported. + // Load rain fall (and track dry/wet conditions) settings for the session + // if feature supported (defaults to "All sesions" one, or else "none"). int rain = TR_RAIN_NONE; if (ReInfo->s->_features & RM_FEATURE_WETTRACK) { const char* pszRain = - GfParmGetStr(ReInfo->params, ReInfo->_reRaceName, RM_ATTR_RAIN, RM_VAL_RAIN_NONE); + GfParmGetStr(ReInfo->params, ReInfo->_reRaceName, RM_ATTR_RAIN, 0); + if (!pszRain) + pszRain = + GfParmGetStr(ReInfo->params, RM_VAL_ANYRACE, RM_ATTR_RAIN, RM_VAL_RAIN_NONE); for (int i = 0; i < NRainValues; i++) if (!strcmp(pszRain, RainValues[i])) { diff --git a/src/libs/tgfdata/race.cpp b/src/libs/tgfdata/race.cpp index 43875a6bb..da7e4247a 100644 --- a/src/libs/tgfdata/race.cpp +++ b/src/libs/tgfdata/race.cpp @@ -170,7 +170,7 @@ void GfRace::load(GfRaceManager* pRaceMan, void* hparmResults) } // Load the parameters for all the referenced sessions, even if not user-configurable - // ("All Sessions" include, if any). + // ("All Sessions" included, if any). // 1) Pre-load the parameters for user-configurable sessions. const std::vector& vecRefSessionNames = _pPrivate->pRaceMan->getSessionNames(); for (int nConfInd = 1; nConfInd <= GfParmGetEltNb(hparmRaceMan, RM_SECT_CONF); nConfInd++) @@ -243,7 +243,7 @@ void GfRace::load(GfRaceManager* pRaceMan, void* hparmResults) } // 3) Load the actual parameter values for each referenced session - // (user-configurable or not, the "Any Race" one included if needed). + // (user-configurable or not, the "All Sessions" one included if needed). std::map::iterator itSessionParams; for (itSessionParams = _pPrivate->mapParametersBySession.begin(); itSessionParams != _pPrivate->mapParametersBySession.end(); itSessionParams++) @@ -299,12 +299,12 @@ void GfRace::load(GfRaceManager* pRaceMan, void* hparmResults) break; } -// GfLogDebug("GfRace::load(...) : %s : opts=%02x, " -// "laps=%d, dist=%d, dur=%d, disp=%d, tod=%d, clds=%d, rain=%d\n", -// pszSessionName, pSessionParams->bfOptions, -// pSessionParams->nLaps, pSessionParams->nDistance, pSessionParams->nDuration, -// pSessionParams->eDisplayMode, pSessionParams->eTimeOfDaySpec, -// pSessionParams->eCloudsSpec, pSessionParams->eRainSpec); + // GfLogDebug("GfRace::load(...) : %s : opts=%02x, " + // "laps=%d, dist=%d, dur=%d, disp=%d, tod=%d, clds=%d, rain=%d\n", + // pszSessionName, pSessionParams->bfOptions, + // pSessionParams->nLaps, pSessionParams->nDistance, pSessionParams->nDuration, + // pSessionParams->eDisplayMode, pSessionParams->eTimeOfDaySpec, + // pSessionParams->eCloudsSpec, pSessionParams->eRainSpec); } // Load the max number of competitors from the raceman params and / or the results file. @@ -514,9 +514,6 @@ void GfRace::store() // Save race manager level data. _pPrivate->pRaceMan->store(); - // Get the parameters for "All Sessions" (warning: may not exist). - const Parameters* pAllSessionParams = getParameters(RM_VAL_ANYRACE); - // Save the parameters for all the sessions : // for a given parameter of a given non-"All Sessions" session, // save the parameter value if valid, otherwise use the coresponding one's value @@ -530,70 +527,55 @@ void GfRace::store() const Parameters* pSessionParams = itSessionParams->second; // Write valid param. value for the current session, - // or else the one from the corresponding parameter of "All Sessions" - // if valid and if "All Sessions" is present. + // or remove the parameter if invalid value. if (pSessionParams->nLaps >= 0) GfParmSetNum(hparmRaceMan, pszSessionName, RM_ATTR_LAPS, (char*)NULL, (tdble)pSessionParams->nLaps); - else if (pAllSessionParams && pSessionParams != pAllSessionParams - && pAllSessionParams->nLaps >= 0) - GfParmSetNum(hparmRaceMan, pszSessionName, RM_ATTR_LAPS, - (char*)NULL, (tdble)pAllSessionParams->nLaps); + else + GfParmRemove(hparmRaceMan, pszSessionName, RM_ATTR_LAPS); if (pSessionParams->nDistance >= 0) GfParmSetNum(hparmRaceMan, pszSessionName, RM_ATTR_DISTANCE, "km", (tdble)pSessionParams->nDistance); - else if (pAllSessionParams && pSessionParams != pAllSessionParams - && pAllSessionParams->nDistance >= 0) - GfParmSetNum(hparmRaceMan, pszSessionName, RM_ATTR_DISTANCE, - "km", (tdble)pAllSessionParams->nDistance); + else + GfParmRemove(hparmRaceMan, pszSessionName, RM_ATTR_DISTANCE); if (pSessionParams->nDuration >= 0) GfParmSetNum(hparmRaceMan, pszSessionName, RM_ATTR_SESSIONTIME, "s", (tdble)pSessionParams->nDuration); - else if (pAllSessionParams && pSessionParams != pAllSessionParams - && pAllSessionParams->nDuration >= 0) - GfParmSetNum(hparmRaceMan, pszSessionName, RM_ATTR_SESSIONTIME, - "s", (tdble)pAllSessionParams->nDuration); + else + GfParmRemove(hparmRaceMan, pszSessionName, RM_ATTR_SESSIONTIME); if (pSessionParams->eDisplayMode != nDisplayModeNumber) GfParmSetStr(hparmRaceMan, pszSessionName, RM_ATTR_DISPMODE, DisplayModeNames[pSessionParams->eDisplayMode]); - else if (pAllSessionParams && pSessionParams != pAllSessionParams - && pAllSessionParams->eDisplayMode != nDisplayModeNumber) - GfParmSetStr(hparmRaceMan, pszSessionName, RM_ATTR_DISPMODE, - DisplayModeNames[pAllSessionParams->eDisplayMode]); + else + GfParmRemove(hparmRaceMan, pszSessionName, RM_ATTR_DISPMODE); if (pSessionParams->eTimeOfDaySpec != nTimeSpecNumber) GfParmSetStr(hparmRaceMan, pszSessionName, RM_ATTR_TIME_OF_DAY, TimeOfDaySpecNames[pSessionParams->eTimeOfDaySpec]); - else if (pAllSessionParams && pSessionParams != pAllSessionParams - && pAllSessionParams->eTimeOfDaySpec != nTimeSpecNumber) - GfParmSetStr(hparmRaceMan, pszSessionName, RM_ATTR_TIME_OF_DAY, - TimeOfDaySpecNames[pAllSessionParams->eTimeOfDaySpec]); + else + GfParmRemove(hparmRaceMan, pszSessionName, RM_ATTR_TIME_OF_DAY); if (pSessionParams->eCloudsSpec != nCloudsSpecNumber) GfParmSetStr(hparmRaceMan, pszSessionName, RM_ATTR_CLOUDS, CloudsSpecNames[pSessionParams->eCloudsSpec]); - else if (pAllSessionParams && pSessionParams != pAllSessionParams - && pAllSessionParams->eCloudsSpec != nCloudsSpecNumber) - GfParmSetStr(hparmRaceMan, pszSessionName, RM_ATTR_CLOUDS, - CloudsSpecNames[pAllSessionParams->eCloudsSpec]); + else + GfParmRemove(hparmRaceMan, pszSessionName, RM_ATTR_CLOUDS); if (pSessionParams->eRainSpec != nRainSpecNumber) GfParmSetStr(hparmRaceMan, pszSessionName, RM_ATTR_RAIN, RainSpecNames[pSessionParams->eRainSpec]); - else if (pAllSessionParams && pSessionParams != pAllSessionParams - && pAllSessionParams->eRainSpec != nRainSpecNumber) - GfParmSetStr(hparmRaceMan, pszSessionName, RM_ATTR_RAIN, - RainSpecNames[pAllSessionParams->eRainSpec]); + else + GfParmRemove(hparmRaceMan, pszSessionName, RM_ATTR_RAIN); -// GfLogDebug("GfRace::store(...) : %s params : " -// "laps=%d, dist=%d, dur=%d, disp=%d, tod=%d, clds=%d, rain=%d\n", -// pszSessionName, pSessionParams->nLaps, -// pSessionParams->nDistance, pSessionParams->nDuration, -// pSessionParams->eDisplayMode, pSessionParams->eTimeOfDaySpec, -// pSessionParams->eCloudsSpec, pSessionParams->eRainSpec); + // GfLogDebug("GfRace::store(...) : %s params : " + // "laps=%d, dist=%d, dur=%d, disp=%d, tod=%d, clds=%d, rain=%d\n", + // pszSessionName, pSessionParams->nLaps, + // pSessionParams->nDistance, pSessionParams->nDuration, + // pSessionParams->eDisplayMode, pSessionParams->eTimeOfDaySpec, + // pSessionParams->eCloudsSpec, pSessionParams->eRainSpec); } // Clear the race starting grid. @@ -679,16 +661,14 @@ GfRaceManager* GfRace::getManager() const return _pPrivate->pRaceMan; } -GfRace::Parameters* GfRace::getParameters(const std::string& strSessionName, - bool bUserConfig) const +GfRace::Parameters* GfRace::getParameters(const std::string& strSessionName) const { Parameters* pParams = 0; std::map::const_iterator itParams = _pPrivate->mapParametersBySession.find(strSessionName); if (itParams != _pPrivate->mapParametersBySession.end()) - if (!bUserConfig || itParams->second->bfOptions) - pParams = itParams->second; + pParams = itParams->second; return pParams; } diff --git a/src/libs/tgfdata/race.h b/src/libs/tgfdata/race.h index 27a148193..8f5b5b914 100644 --- a/src/libs/tgfdata/race.h +++ b/src/libs/tgfdata/race.h @@ -83,7 +83,7 @@ public: ERainSpec eRainSpec; }; - Parameters* getParameters(const std::string& strSessionName, bool bUserConfig = false) const; + Parameters* getParameters(const std::string& strSessionName) const; int getSupportedFeatures() const; diff --git a/src/modules/userinterface/legacymenu/racescreens/raceparamsmenu.cpp b/src/modules/userinterface/legacymenu/racescreens/raceparamsmenu.cpp index e6292cb0c..b7192a235 100644 --- a/src/modules/userinterface/legacymenu/racescreens/raceparamsmenu.cpp +++ b/src/modules/userinterface/legacymenu/racescreens/raceparamsmenu.cpp @@ -258,8 +258,8 @@ rmrpValidate(void * /* dummy */) // And then update configurable race session parameters from the current local settings, // if anything to configure (Don't change non-configurable parameters). GfRace::Parameters* pRaceSessionParams = - MenuData->pRace->getParameters(MenuData->session, /* bUserConfig */ true); - if (pRaceSessionParams) + MenuData->pRace->getParameters(MenuData->session); + if (pRaceSessionParams && pRaceSessionParams->bfOptions) { if (rmrpConfMask & RM_CONF_RACE_LEN) { @@ -315,11 +315,8 @@ RmRaceParamsMenu(void *vrp) // Update the conf mask according to the session params, graphics options and race features. // 1) According to the availability of parameters for this session,. GfRace::Parameters* pRaceSessionParams = - MenuData->pRace->getParameters(MenuData->session, /* bUserConfig */ true); - if (!pRaceSessionParams) - rmrpConfMask = 0; - else - rmrpConfMask = pRaceSessionParams->bfOptions; + MenuData->pRace->getParameters(MenuData->session); + rmrpConfMask = pRaceSessionParams ? pRaceSessionParams->bfOptions : 0; // 2) According to SkyDome settings. snprintf(buf, sizeof(buf), "%s%s", GfLocalDir(), GR_PARAM_FILE);