// Translation function from SDL key to unicode if possible (or SDL key sym otherwise) // As the unicode is not available on KEYUP events, we store it on KEYDOWN event, // (and then, we can get it on KEYUP event, that ALWAYS come after a KEYDOWN event). // The unicode is stored in a map that grows each time 1 new key sym + modifiers combination // is typed ; we never clears this map, but assume not that many such combinations // will be typed in a game session (could theorically go up to 2^23 combinations, though ;-) // Known issues (TODO): No support for Caps and NumLock keys ... don't use them ! int GfEventLoop::Private::translateKeySym(int code, int modifier, int unicode) { #if SDL_MAJOR_VERSION < 2 // Generate the key Id from its code and modifier. const Uint32 keyId = ((Uint32)code & 0x1FF) | (((Uint32)modifier) << 9); // Search it in our unicode map. const std::map<Uint32, Uint16>::const_iterator itUnicode = _mapUnicodes.find(keyId); // If not found, update the map for next times. int keyUnicode; if (itUnicode == _mapUnicodes.end()) { // Truncate unicodes above GF_MAX_KEYCODE (no need for more). keyUnicode = unicode ? (unicode & GF_MAX_KEYCODE) : code; _mapUnicodes[keyId] = (unsigned short)keyUnicode; GfLogDebug("translateKeySym(c=%X, m=%X, u=%X) : '%c', id=%X, ucode=%X (nk=%d)\n", code, modifier, unicode, // Truncate high bits for MSVC 2010 bugs. (keyUnicode > 0 && keyUnicode < 128 && isprint(keyUnicode & 0x7F)) ? (char)(keyUnicode & 0x7F) : ' ', keyId, keyUnicode, _mapUnicodes.size()); } // If found, get the unicode from the map. else keyUnicode = (*itUnicode).second; // Done. return keyUnicode; #else return code; #endif }
// TODO: Tests (not yet used, see #809). std::vector<GfModule*> GfModule::loadFromDir(const std::string& strDirPath, bool bUseChildDirs) { std::vector<GfModule*> vecModules; GfLogDebug("GfModule::loadFromDir(%s)\n", strDirPath.c_str()); // Get the list of files/sub-dirs in the folder. tFList* lstFilesOrDirs = GfDirGetList(strDirPath.c_str()); if (lstFilesOrDirs) { // Filter module shared libraries and try and load each of them. tFList* pFileOrDir = lstFilesOrDirs; do { // Ignore "." and ".." folders. if (pFileOrDir->name[0] == '.') continue; GfLogDebug(" Examining %s\n", pFileOrDir->name); // Build module shared library path-name (consider only foders, not files). std::ostringstream ossShLibPath; ossShLibPath << strDirPath << '/' << pFileOrDir->name; if (bUseChildDirs) ossShLibPath << '/' << pFileOrDir->name; ossShLibPath << DLLEXT; // Check existence. if (!GfFileExists(ossShLibPath.str().c_str())) continue; // Try and load. GfModule* pModule = GfModule::load(ossShLibPath.str().c_str()); if (pModule) vecModules.push_back(pModule); else GfLogWarning("Failed to load module %s\n", ossShLibPath.str().c_str()); } while ((pFileOrDir = pFileOrDir->next) != lstFilesOrDirs); } return vecModules; }
void NetServer::Dump(const char* pszCaller) { NetMutexData *pNData = LockNetworkData(); NetServerMutexData *pSData = LockServerData(); GfLogDebug("%s : vecReady:%u, vecPlayers:%u\n", pszCaller, pNData->m_vecReadyStatus.size(), pSData->m_vecNetworkPlayers.size()); UnlockServerData(); UnlockNetworkData(); }
GfModule* GfModule::load(const std::string& strShLibName) { // Don't load shared libraries twice // Warning: Only checked through the give nlibrary file path-name ... if (_mapModulesByLibName.find(strShLibName) != _mapModulesByLibName.end()) { GfLogDebug("Not re-loading module %s (already done)\n", strShLibName.c_str()); return _mapModulesByLibName[strShLibName]; } // Try and open the shared library. void* hSOLib = dlopen(strShLibName.c_str()); if (!hSOLib) { GfLogError("Failed to load library %s (%s)\n", strShLibName.c_str(), lastDLErrorString().c_str()); return 0; } // Try and get the module opening function. tModOpenFunc modOpenFunc = (tModOpenFunc)dlsym(hSOLib, pszOpenModuleFuncName); if (!modOpenFunc) { GfLogError("Library %s doesn't export any '%s' function' ; module NOT loaded\n", strShLibName.c_str(), pszOpenModuleFuncName); (void)dlclose(hSOLib); return 0; } // Call the module opening function (must instanciate the module and register_ it on success). if (modOpenFunc(strShLibName.c_str(), hSOLib)) { GfLogError("Library %s '%s' function call failed ; module NOT loaded\n", strShLibName.c_str(), pszOpenModuleFuncName); (void)dlclose(hSOLib); return 0; } // Check if the module was successfully register_ed. if (_mapModulesByLibName.find(strShLibName) == _mapModulesByLibName.end()) { GfLogError("Library %s '%s' function failed to register the open module ; NOT loaded\n", strShLibName.c_str(), pszOpenModuleFuncName); (void)dlclose(hSOLib); return 0; } // Yesssss ! GfLogTrace("Module %s loaded\n", strShLibName.c_str()); return _mapModulesByLibName[strShLibName]; }
// Update Track Physics (compute kFriction from current "water level" on ground). void reTrackUpdatePhysics(void) { tTrackLocalInfo *trackLocal = &ReInfo->track->local; // Get the wet / dry friction coefficients ratio. void* hparmTrackConsts = GfParmReadFile(TRK_PHYSICS_FILE, GFPARM_RMODE_STD | GFPARM_RMODE_CREAT); const tdble kFrictionWetDryRatio = GfParmGetNum(hparmTrackConsts, TRKP_SECT_SURFACES, TRKP_VAL_FRICTIONWDRATIO, (char*)NULL, 0.5f); GfParmReleaseHandle(hparmTrackConsts); // Determine the "wetness" of the track (inside [0, 1]). const tdble wetness = (tdble)trackLocal->water / TR_WATER_MUCH; GfLogDebug("ReTrackUpdate : water = %d, wetness = %.2f, wet/dry mu = %.4f\n", trackLocal->water, wetness, kFrictionWetDryRatio); // Set the actual friction for each _ground_ surface of the track. GfLogDebug("ReTrackUpdate : kFriction | kRollRes | Surface :\n"); tTrackSurface *curSurf; curSurf = ReInfo->track->surfaces; do { // Linear interpolation of kFriction from dry to wet according to wetness. curSurf->kFriction = curSurf->kFrictionDry * (1 - wetness) + curSurf->kFrictionDry * kFrictionWetDryRatio * wetness; // For the moment, we don't change curSurf->kRollRes (might change in the future). GfLogDebug(" %.4f | %.4f | %s\n", curSurf->kFriction, curSurf->kRollRes, curSurf->material); curSurf = curSurf->next; } while ( curSurf ); }
void ReCalculateClassPoints(char const *race) { double points; char *path3; int rank = 1; int count; snprintf(buf, sizeof(buf), "%s/%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, ReInfo->_reRaceName, RE_SECT_RANK); path3 = strdup(buf); if (GfParmListSeekFirst(ReInfo->results, path3) != 0) { free(path3); return; /* No result found */ } count = GfParmGetEltNb(ReInfo->results, path3); do { snprintf( path2, sizeof(path2), "%s/%s", race, RM_SECT_CLASSPOINTS ); if (GfParmListSeekFirst( ReInfo->params, path2 ) != 0) { GfLogDebug( "ReCalculateClassPoints: First not found in %s)\n", path2 ); continue; } do { snprintf( buf, sizeof(buf), "%s/%s", path2, GfParmListGetCurEltName( ReInfo->params, path2 ) ); snprintf( path, sizeof(path), "%s/%s/%d/%d/%s", RE_SECT_CLASSPOINTS, GfParmGetCurStr (ReInfo->results, path3, RE_ATTR_MODULE, ""), (int)GfParmGetCurNum (ReInfo->results, path3, RM_ATTR_EXTENDED, NULL, 0), (int)GfParmGetCurNum (ReInfo->results, path3, RE_ATTR_IDX, NULL, 0), GfParmGetStr( ReInfo->params, buf, RM_ATTR_SUFFIX, "" ) ); points = GfParmGetNum (ReInfo->results, path, RE_ATTR_POINTS, NULL, 0); GfParmSetVariable (ReInfo->params, buf, "pos", (tdble)rank); GfParmSetVariable (ReInfo->params, buf, "cars", (tdble)count); //GfLogDebug( "ReCalculateClassPoints: pos = %d; count = %d\n", rank, count); //GfLogDebug( "ReCalculateClassPoints: GfParmGetNum (..., %s, %s, NULL, 0)\n", buf, RM_ATTR_POINTS ); points += ( GfParmGetNum (ReInfo->params, buf, RM_ATTR_POINTS, NULL, 0) / GfParmGetNum (ReInfo->params, RM_SECT_TRACKS, RM_ATTR_NUMBER, NULL, 1) ); GfParmRemoveVariable (ReInfo->params, buf, "pos"); GfParmRemoveVariable (ReInfo->params, buf, "cars"); GfParmSetNum (ReInfo->results, path, RE_ATTR_POINTS, NULL, (tdble)points); } while (GfParmListSeekNext( ReInfo->params, path2 ) == 0); ++rank; } while (GfParmListSeekNext (ReInfo->results, path3) == 0); free(path3); }
void RmShowResults(void *prevHdle, tRmInfo *info) { switch (info->s->_raceType) { case RM_TYPE_PRACTICE: { char buffer[128]; snprintf(buffer, sizeof(buffer), "%s/%s", info->track->name, RE_SECT_DRIVERS); int nCars = GfParmGetEltNb(info->results, buffer); bool bQualif = (nCars != 1); // Career special case : Practice results show multiple cars, // but only 1 driver, so no 'rank' section. // TODO: Rather fix the Career code ? if (bQualif) { snprintf(buffer, sizeof(buffer), "%s/%s/%s/%s", info->track->name, RE_SECT_RESULTS, info->_reRaceName, RE_SECT_RANK); nCars = (int)GfParmGetEltNb(info->results, buffer); GfLogDebug("RmShowResults: %d elements in %s\n", nCars, buffer); bQualif = bQualif && (nCars != 0); } if (bQualif) rmQualifResults(prevHdle, info, "Practice", 0); else rmPracticeResults(prevHdle, info, 0); break; } case RM_TYPE_RACE: rmRaceResults(prevHdle, info, 0); break; case RM_TYPE_QUALIF: rmQualifResults(prevHdle, info, "Qualification", 0); break; }//switch raceType }//RmShowResults
/* * Function * GetTrackHeader * * Description * Get the header of the track file * in order to know the number of segments * Parameters * * * Return * * * Remarks * */ static void GetTrackHeader(void *TrackHandle) { // Read header theTrack->name = GfParmGetStr(TrackHandle, TRK_SECT_HDR, TRK_ATT_NAME, "no name"); theTrack->descr = GfParmGetStr(TrackHandle, TRK_SECT_HDR, TRK_ATT_DESCR, "no description"); theTrack->version = (int)GfParmGetNum(TrackHandle, TRK_SECT_HDR, TRK_ATT_VERSION, (char*)NULL, 0); theTrack->width = GfParmGetNum(TrackHandle, TRK_SECT_MAIN, TRK_ATT_WIDTH, (char*)NULL, 15.0); theTrack->authors = GfParmGetStr(TrackHandle, TRK_SECT_HDR, TRK_ATT_AUTHOR, "none"); theTrack->category = GfParmGetStr(TrackHandle, TRK_SECT_HDR, TRK_ATT_CAT, "road"); theTrack->subcategory = GfParmGetStr(TrackHandle, TRK_SECT_HDR, TRK_ATT_SUBCAT, "none"); // Read Local Info section tTrackLocalInfo *local = &theTrack->local; local->station = GfParmGetStr(TrackHandle, TRK_SECT_LOCAL, TRK_ATT_STATION, "LFPG"); local->timezone = (int)GfParmGetNum(TrackHandle, TRK_SECT_LOCAL, TRK_ATT_TIMEZONE, (char*)NULL, 0); local->anyrainlkhood = GfParmGetNum(TrackHandle, TRK_SECT_LOCAL, TRK_ATT_ANYRAINLKHD, (char*)NULL, 0); local->littlerainlkhood = GfParmGetNum(TrackHandle, TRK_SECT_LOCAL, TRK_ATT_LITTLERAINLKHD, (char*)NULL, 0); local->mediumrainlkhood = GfParmGetNum(TrackHandle, TRK_SECT_LOCAL, TRK_ATT_MEDIUMRAINLKHD, (char*)NULL, 0); local->timeofday = GfParmGetNum(TrackHandle, TRK_SECT_LOCAL, TRK_ATT_TIMEOFDAY, (char*)NULL, (tdble)(15 * 3600 + 0 * 60 + 0)); // 15:00:00 local->sunascension = GfParmGetNum(TrackHandle, TRK_SECT_LOCAL, TRK_ATT_SUN_ASCENSION, (char*)NULL, 0.0f); // Read Graphic section tTrackGraphicInfo *graphic = &theTrack->graphic; graphic->model3d = GfParmGetStr(TrackHandle, TRK_SECT_GRAPH, TRK_ATT_3DDESC, 0); graphic->background = GfParmGetStr(TrackHandle, TRK_SECT_GRAPH, TRK_ATT_BKGRND, "background.png"); graphic->bgtype = (int)GfParmGetNum(TrackHandle, TRK_SECT_GRAPH, TRK_ATT_BGTYPE, (char*)NULL, 0.0); graphic->bgColor[0] = (float)GfParmGetNum(TrackHandle, TRK_SECT_GRAPH, TRK_ATT_BGCLR_R, (char*)NULL, 0.0f); graphic->bgColor[1] = (float)GfParmGetNum(TrackHandle, TRK_SECT_GRAPH, TRK_ATT_BGCLR_G, (char*)NULL, 0.0f); graphic->bgColor[2] = (float)GfParmGetNum(TrackHandle, TRK_SECT_GRAPH, TRK_ATT_BGCLR_B, (char*)NULL, 0.1f); // Environment map images char buf[256]; sprintf(buf, "%s/%s", TRK_SECT_GRAPH, TRK_LST_ENV); graphic->envnb = GfParmGetEltNb(TrackHandle, buf); if (graphic->envnb < 1) graphic->envnb = 1; graphic->env = (const char**)calloc(graphic->envnb, sizeof(const char*)); const char **env = graphic->env; for (int i = 1; i <= graphic->envnb; ++i) { sprintf(buf, "%s/%s/%d", TRK_SECT_GRAPH, TRK_LST_ENV, i); *env = GfParmGetStr(TrackHandle, buf, TRK_ATT_ENVNAME, "env.png"); ++env; } // Track lights graphic->nb_lights = GfParmGetEltNb(TrackHandle, TRK_SECT_TRACKLIGHTS ); GfLogDebug( "Number of lights: %d\n", graphic->nb_lights ); if (graphic->nb_lights > 0 ) { graphic->lights = (tGraphicLightInfo*)malloc( sizeof( tGraphicLightInfo ) * graphic->nb_lights ); for (int i = 0; i < graphic->nb_lights; ++i) { sprintf(buf, "%s/%d/%s", TRK_SECT_TRACKLIGHTS, i + 1, TRK_SECT_TOPLEFT); graphic->lights[ i ].topleft.x = GfParmGetNum(TrackHandle, buf, TRK_ATT_X, (char*)NULL, 0.0f); graphic->lights[ i ].topleft.y = GfParmGetNum(TrackHandle, buf, TRK_ATT_Y, (char*)NULL, 0.0f); graphic->lights[ i ].topleft.z = GfParmGetNum(TrackHandle, buf, TRK_ATT_Z, (char*)NULL, 0.0f); sprintf(buf, "%s/%d/%s", TRK_SECT_TRACKLIGHTS, i + 1, TRK_SECT_BOTTOMRIGHT); graphic->lights[ i ].bottomright.x = GfParmGetNum(TrackHandle, buf, TRK_ATT_X, (char*)NULL, 0.0f); graphic->lights[ i ].bottomright.y = GfParmGetNum(TrackHandle, buf, TRK_ATT_Y, (char*)NULL, 0.0f); graphic->lights[ i ].bottomright.z = GfParmGetNum(TrackHandle, buf, TRK_ATT_Z, (char*)NULL, 0.0f); sprintf(buf, "%s/%d", TRK_SECT_TRACKLIGHTS, i + 1); graphic->lights[ i ].onTexture = strdup(GfParmGetStr(TrackHandle, buf, TRK_ATT_TEXTURE_ON, "")); graphic->lights[ i ].offTexture = strdup(GfParmGetStr(TrackHandle, buf, TRK_ATT_TEXTURE_OFF, "")); graphic->lights[ i ].index = (int)GfParmGetNum(TrackHandle, buf, TRK_ATT_INDEX, (char*)NULL, 0.0f); graphic->lights[ i ].role = 0; if( strcmp( GfParmGetStr(TrackHandle, buf, TRK_ATT_ROLE, ""), "st_red" ) == 0 ) graphic->lights[ i ].role = GR_TRACKLIGHT_START_RED; else if( strcmp( GfParmGetStr(TrackHandle, buf, TRK_ATT_ROLE, ""), "st_green" ) == 0 ) graphic->lights[ i ].role = GR_TRACKLIGHT_START_GREEN; else if( strcmp( GfParmGetStr(TrackHandle, buf, TRK_ATT_ROLE, ""), "st_green_st" ) == 0 ) graphic->lights[ i ].role = GR_TRACKLIGHT_START_GREENSTART; else if( strcmp( GfParmGetStr(TrackHandle, buf, TRK_ATT_ROLE, ""), "st_yellow" ) == 0 ) graphic->lights[ i ].role = GR_TRACKLIGHT_START_YELLOW; graphic->lights[ i ].red = GfParmGetNum(TrackHandle, buf, TRK_ATT_RED, (char*)NULL, 1.0f); graphic->lights[ i ].green = GfParmGetNum(TrackHandle, buf, TRK_ATT_GREEN, (char*)NULL, 1.0f); graphic->lights[ i ].blue = GfParmGetNum(TrackHandle, buf, TRK_ATT_BLUE, (char*)NULL, 1.0f); } // for i } // if nb_lights theTrack->nseg = 0; // Search for track filename, without any path info, eg: 'foo.xml' const char *s = strrchr(theTrack->filename, '/'); if (s == NULL) { s = theTrack->filename; } else { ++s; } // Internal name is track filename, without extension, eg: 'foo' theTrack->internalname = strdup(s); char *cs = strrchr(theTrack->internalname, '.'); if (cs != NULL) { *cs = 0; } // Default turnmark is 1m*1m, right next to the track graphic->turnMarksInfo.height = GfParmGetNum(TrackHandle, TRK_SECT_TURNMARKS, TRK_ATT_HEIGHT, NULL, 1); graphic->turnMarksInfo.width = GfParmGetNum(TrackHandle, TRK_SECT_TURNMARKS, TRK_ATT_WIDTH, NULL, 1); graphic->turnMarksInfo.vSpace = GfParmGetNum(TrackHandle, TRK_SECT_TURNMARKS, TRK_ATT_VSPACE, NULL, 0); graphic->turnMarksInfo.hSpace = GfParmGetNum(TrackHandle, TRK_SECT_TURNMARKS, TRK_ATT_HSPACE, NULL, 0); } // GetTrackHeader
void NetClient::ReadPacket(ENetEvent event) { ENetPacket *pPacket = event.packet; assert(pPacket->dataLength>=1); unsigned char packetId = pPacket->data[0]; //unsigned char *pData = &pPacket->data[1]; //int datasize = pPacket->dataLength-1; switch (packetId) { case RACEINFOCHANGE_PACKET: ReadRaceSetupPacket(event.packet); break; case PREPARETORACE_PACKET: ReadPrepareToRacePacket(event.packet); break; case RACESTARTTIME_PACKET: ReadStartTimePacket(event.packet); break; case CARCONTROLS_PACKET: ReadCarControlsPacket(event.packet); break; case FILE_PACKET: ReadFilePacket(event.packet); break; case SERVER_TIME_SYNC_PACKET: ReadTimePacket(event.packet); break; case WEATHERCHANGE_PACKET: ReadWeatherPacket(event.packet); break; case CARSTATUS_PACKET: ReadCarStatusPacket(event.packet); break; case LAPSTATUS_PACKET: ReadLapStatusPacket(event.packet); break; case FINISHTIME_PACKET: ReadFinishTimePacket(event.packet); break; case ALLDRIVERREADY_PACKET: ReadAllDriverReadyPacket(event.packet); break; case PLAYERREJECTED_PACKET: ReadPlayerRejectedPacket(event.packet); break; case PLAYERACCEPTED_PACKET: ReadPlayerAcceptedPacket(event.packet); break; default: assert(false); GfLogDebug ("A packet of length %u containing %s was received from %s on channel %u.\n", event.packet -> dataLength, event.packet -> data, (char*)event.peer -> data, event.channelID); } enet_packet_destroy (event.packet); }
void OsgGraph::shutdownView() { GfLogDebug("OsgGraph::shutdownView\n"); ::shutdownView(); }
// Initialize track weather info from race settings void reTrackInitWeather(void) { static const char* CloudsValues[] = RM_VALS_CLOUDS; static const int NCloudsValues = sizeof(CloudsValues) / sizeof(const char*); static const char *RainValues[] = RM_VALS_RAIN; static const int NRainValues = sizeof(RainValues) / sizeof(const char*); tTrackLocalInfo *trackLocal = &ReInfo->track->local; // 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, 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])) { clouds = i; break; } // 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, 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])) { rain = i; break; } } // Take care of the random case for rain falls and ground water. const bool bRandomRain = (rain == TR_RAIN_RANDOM); if (bRandomRain) { // Force random clouds, in case there is no rain at the end. clouds = TR_CLOUDS_RANDOM; // Random rain (if random[0,1] < trackLocal->anyrainlkhood, then it rains). const tdble randDraw = (tdble)(rand()/(double)RAND_MAX); GfLogTrace("Rain likelyhoods : overall=%.2f, little=%.2f, medium=%.2f\n", trackLocal->anyrainlkhood, trackLocal->littlerainlkhood, trackLocal->mediumrainlkhood); GfLogDebug("Overall rain random draw = %.2f,\n", randDraw); if (randDraw < trackLocal->anyrainlkhood) { // Now, let's determine how much it rains : // if random[0,1] < little rain likelyhood => rain = little rain const tdble randDraw2 = (tdble)(rand()/(double)RAND_MAX); GfLogDebug("Specific rain random draw = %.2f,\n", randDraw2); if (randDraw2 < trackLocal->littlerainlkhood) rain = TR_RAIN_LITTLE; // else if random[0,1] < medium + little rain likelyhood => rain = medium rain else if (randDraw2 < trackLocal->littlerainlkhood + trackLocal->mediumrainlkhood) rain = TR_RAIN_MEDIUM; // otherwise, random[0,1] >= medium + little rain likelyhood => rain = Heavy rain else rain = TR_RAIN_HEAVY; } else { // No Rain. rain = TR_RAIN_NONE; } } // Take care of the random case for clouds cover. const bool bRandomClouds = (clouds == TR_CLOUDS_RANDOM); if (bRandomClouds) { if (rain != TR_RAIN_NONE) { // If any rain level, heavy clouds. clouds = TR_CLOUDS_FULL; } else { // Really random clouds. clouds = rand() % (TR_CLOUDS_FULL + 1); } } // Ground water = rain for the moment (might change in the future). const int water = rain; GfLogInfo("Weather : Using %s rain (%d) and ground water (%d) + %s clouds (%d) settings\n", bRandomRain ? "random" : "user defined", rain, water, bRandomClouds ? "random" : "user defined", clouds); // Update track local info. trackLocal->rain = rain; trackLocal->clouds = clouds; trackLocal->water = water; // Update track physics from computed local info. reTrackUpdatePhysics(); }
// Initialize track time of day from race settings void reTrackInitTimeOfDay(void) { static const char *TimeOfDayValues[] = RM_VALS_TIME; static const int NTimeOfDayValues = sizeof(TimeOfDayValues) / sizeof(const char*); tTrackLocalInfo *trackLocal = &ReInfo->track->local; // 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, 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])) { timeofday = i; break; } trackLocal->timeofdayindex = timeofday; switch (timeofday) { case RM_IND_TIME_DAWN: trackLocal->timeofday = 6 * 3600 + 13 * 60 + 20; // 06:13:20 break; case RM_IND_TIME_MORNING: trackLocal->timeofday = 10 * 3600 + 0 * 60 + 0; // 10:00:00 break; case RM_IND_TIME_NOON: case RM_IND_TIME_24HR: trackLocal->timeofday = 12 * 3600 + 0 * 60 + 0; // 12:00:00 break; case RM_IND_TIME_AFTERNOON: trackLocal->timeofday = 15 * 3600 + 0 * 60 + 0; // 15:00:00 break; case RM_IND_TIME_DUSK: trackLocal->timeofday = 17 * 3600 + 46 * 60 + 40; // 17:46:40 break; case RM_IND_TIME_NIGHT: trackLocal->timeofday = 0 * 3600 + 0 * 60 + 0; // Midnight = 00:00:00 break; case RM_IND_TIME_REAL: case RM_IND_TIME_NOW: { time_t t = time(0); struct tm *ptm = localtime(&t); trackLocal->timeofday = ptm->tm_hour * 3600.0f + ptm->tm_min * 60.0f + ptm->tm_sec; GfLogDebug(" Now time of day\n"); break; } case RM_IND_TIME_TRACK: // Already loaded by the track loader (or else default value). GfLogDebug(" Track-defined time of day\n"); break; case RM_IND_TIME_RANDOM: trackLocal->timeofday = (tdble)(rand() % (24*60*60)); break; default: trackLocal->timeofday = 15 * 3600 + 0 * 60 + 0; // 15:00:00 trackLocal->timeofdayindex = RM_IND_TIME_AFTERNOON; GfLogError("Unsupported value %d for user timeofday (assuming 15:00)\n", timeofday); break; }//switch timeofday }
std::vector<GfDriverSkin> GfDriver::getPossibleSkins(const std::string& strAltCarId) const { const std::string strCarId = strAltCarId.empty() ? _pCar->getId() : strAltCarId; GfLogDebug("Checking skins for %s ...\n", strCarId.c_str()); // Clear the skin and preview lists. std::vector<GfDriverSkin> vecPossSkins; // Get/check skins/skin targets/previews from the directories in the search path // WARNING: Must be consistent with the search paths used in grcar.cpp, grboard.cpp, // grscene.cpp ... etc ... but it is not currently 100% achieved // (pit door logos are not searched by the graphics engine // in the car-dedicated folders ... so they may be "over-detected" here). std::ostringstream ossDirPath; ossDirPath << GfLocalDir() << "drivers/" << _strModName << '/' << _nItfIndex << '/' << strCarId; getPossibleSkinsInFolder(strCarId, ossDirPath.str(), vecPossSkins); ossDirPath.str(""); ossDirPath << GfLocalDir() << "drivers/" << _strModName << '/' << _nItfIndex; getPossibleSkinsInFolder(strCarId, ossDirPath.str(), vecPossSkins); ossDirPath.str(""); ossDirPath << GfLocalDir() << "drivers/" << _strModName << '/' << strCarId; getPossibleSkinsInFolder(strCarId, ossDirPath.str(), vecPossSkins); ossDirPath.str(""); ossDirPath << GfLocalDir() << "drivers/" << _strModName; getPossibleSkinsInFolder(strCarId, ossDirPath.str(), vecPossSkins); ossDirPath.str(""); ossDirPath << "drivers/" << _strModName << '/' << _nItfIndex << '/' << strCarId; getPossibleSkinsInFolder(strCarId, ossDirPath.str(), vecPossSkins); ossDirPath.str(""); ossDirPath << "drivers/" << _strModName << '/' << _nItfIndex; getPossibleSkinsInFolder(strCarId, ossDirPath.str(), vecPossSkins); ossDirPath.str(""); ossDirPath << "drivers/" << _strModName << '/' << strCarId; getPossibleSkinsInFolder(strCarId, ossDirPath.str(), vecPossSkins); ossDirPath.str(""); ossDirPath << "drivers/" << _strModName; getPossibleSkinsInFolder(strCarId, ossDirPath.str(), vecPossSkins); ossDirPath.str(""); ossDirPath << "cars/models/" << strCarId; getPossibleSkinsInFolder(strCarId, ossDirPath.str(), vecPossSkins); // If we have at least 1 skin, make sure that, if the standard one is inside, // it is the first one. if (!vecPossSkins.empty()) { std::vector<GfDriverSkin>::iterator itSkin; for (itSkin = vecPossSkins.begin(); itSkin != vecPossSkins.end(); itSkin++) { if (itSkin->getName().empty() && itSkin != vecPossSkins.begin()) { GfDriverSkin stdSkin = *itSkin; vecPossSkins.erase(itSkin); vecPossSkins.insert(vecPossSkins.begin(), stdSkin); break; } } } // If no skin was found, add the car's standard one // (that way, the skin list will never be empty, and that's safer) else { GfLogError("No skin at all found for '%s/%d/%s' : adding dummy '%s' one\n", _strModName.c_str(), _nItfIndex, strCarId.c_str(), "standard"); GfDriverSkin stdSkin; std::ostringstream ossPreviewName; ossPreviewName << "cars/models/" << strCarId << '/' << strCarId << pszPreviewTexSufx; stdSkin.setCarPreviewFileName(ossPreviewName.str()); if (!GfFileExists(ossPreviewName.str().c_str())) GfLogWarning("No preview file %s found for dummy '%s' skin\n", ossPreviewName.str().c_str(), "standard"); vecPossSkins.push_back(stdSkin); } return vecPossSkins; }
void GfDriver::getPossibleSkinsInFolder(const std::string& strCarId, const std::string& strFolderPath, std::vector<GfDriverSkin>& vecPossSkins) const { //GfLogDebug(" getPossibleSkinsInFolder(%s, %s) ...\n", // strCarId.c_str(), strFolderPath.c_str()); // Search for skinned livery files, and associated preview files if any. tFList *pLiveryFileList = GfDirGetListFiltered(strFolderPath.c_str(), strCarId.c_str(), pszLiveryTexExt); if (pLiveryFileList) { tFList *pCurLiveryFile = pLiveryFileList; do { pCurLiveryFile = pCurLiveryFile->next; // Extract the skin name from the livery file name. const int nSkinNameLen = // Expecting "<car name>-<skin name>.png" strlen(pCurLiveryFile->name) - strCarId.length() - 1 - strlen(pszLiveryTexExt); std::string strSkinName; if (nSkinNameLen > 0) // Otherwise, default/standard "<car name>.png" { strSkinName = std::string(pCurLiveryFile->name) .substr(strCarId.length() + 1, nSkinNameLen); // Ignore skins with an excluded prefix. int nExclPrfxInd = 0; for (; nExclPrfxInd < nExcludedSkinNamePrefixes; nExclPrfxInd++) if (strSkinName.find(apszExcludedSkinNamePrefixes[nExclPrfxInd]) == 0) break; if (nExclPrfxInd < nExcludedSkinNamePrefixes) continue; } // Ignore skins that are already in the list (path search priority). if (findSkin(vecPossSkins, strSkinName) == vecPossSkins.end()) { // Create the new skin. GfDriverSkin skin(strSkinName); // Add the whole car livery to the skin targets. skin.addTargets(RM_CAR_SKIN_TARGET_WHOLE_LIVERY); GfLogDebug(" Found %s%s livery\n", strSkinName.empty() ? "standard" : strSkinName.c_str(), strSkinName.empty() ? "" : "-skinned"); // Add associated preview image, without really checking file existence // (warn only ; up to the client GUI to do what to do if it doesn't exist). std::ostringstream ossPreviewName; ossPreviewName << strFolderPath << '/' << strCarId; if (!strSkinName.empty()) ossPreviewName << '-' << strSkinName; ossPreviewName << pszPreviewTexSufx; skin.setCarPreviewFileName(ossPreviewName.str()); if (!GfFileExists(ossPreviewName.str().c_str())) GfLogWarning("Preview file not found for %s %s skin (%s)\n", strCarId.c_str(), strSkinName.c_str(), ossPreviewName.str().c_str()); //else // GfLogDebug("* found skin=%s, preview=%s\n", // strSkinName.c_str(), ossPreviewName.str().c_str()); // Add the new skin to the list. vecPossSkins.push_back(skin); } } while (pCurLiveryFile != pLiveryFileList); } GfDirFreeList(pLiveryFileList, NULL, true, true); // Search for skinned interior files, if any. std::string strInteriorPrefix(strCarId); strInteriorPrefix += pszInteriorTexSufx; tFList *pIntFileList = GfDirGetListFiltered(strFolderPath.c_str(), strInteriorPrefix.c_str(), pszInteriorTexExt); if (pIntFileList) { tFList *pCurIntFile = pIntFileList; do { pCurIntFile = pCurIntFile->next; // Extract the skin name from the interior file name. const int nSkinNameLen = // Expecting "<car name>-int-<skin name>.png" strlen(pCurIntFile->name) - strInteriorPrefix.length() - 1 - strlen(pszInteriorTexExt); std::string strSkinName; if (nSkinNameLen > 0) { strSkinName = std::string(pCurIntFile->name) .substr(strInteriorPrefix.length() + 1, nSkinNameLen); // If a skin with such name already exists in the list, update it. std::vector<GfDriverSkin>::iterator itSkin = findSkin(vecPossSkins, strSkinName); if (itSkin != vecPossSkins.end()) { itSkin->addTargets(RM_CAR_SKIN_TARGET_INTERIOR); GfLogDebug(" Found %s-skinned interior (targets:%x)\n", strSkinName.c_str(), itSkin->getTargets()); } } } while (pCurIntFile != pIntFileList); } GfDirFreeList(pIntFileList, NULL, true, true); // Search for skinned logo files if any. tFList *pLogoFileList = GfDirGetListFiltered(strFolderPath.c_str(), pszLogoTexName, pszLogoTexExt); if (pLogoFileList) { tFList *pCurLogoFile = pLogoFileList; do { pCurLogoFile = pCurLogoFile->next; // Extract the skin name from the logo file name. const int nSkinNameLen = // Expecting "logo-<skin name>.png" strlen(pCurLogoFile->name) - strlen(pszLogoTexName) - 1 - strlen(pszLogoTexExt); if (nSkinNameLen > 0) { const std::string strSkinName = std::string(pCurLogoFile->name) .substr(strlen(pszLogoTexName) + 1, nSkinNameLen); // If a skin with such name already exists in the list, update it. std::vector<GfDriverSkin>::iterator itSkin = findSkin(vecPossSkins, strSkinName); if (itSkin != vecPossSkins.end()) { itSkin->addTargets(RM_CAR_SKIN_TARGET_PIT_DOOR); GfLogDebug(" Found %s-skinned logo (targets:%x)\n", strSkinName.c_str(), itSkin->getTargets()); } } } while (pCurLogoFile != pLogoFileList); } GfDirFreeList(pLogoFileList, NULL, true, true); // Search for skinned 3D wheel files if any. tFList *pWheel3DFileList = GfDirGetListFiltered(strFolderPath.c_str(), pszWheel3DTexName, pszWheel3DTexExt); if (pWheel3DFileList) { tFList *pCurWheel3DFile = pWheel3DFileList; do { pCurWheel3DFile = pCurWheel3DFile->next; // Extract the skin name from the 3D wheel texture file name. const int nSkinNameLen = // Expecting "wheel3d-<skin name>.png" strlen(pCurWheel3DFile->name) - strlen(pszWheel3DTexName) - 1 - strlen(pszWheel3DTexExt); if (nSkinNameLen > 0) { const std::string strSkinName = std::string(pCurWheel3DFile->name) .substr(strlen(pszWheel3DTexName) + 1, nSkinNameLen); // If a skin with such name already exists in the list, update it. std::vector<GfDriverSkin>::iterator itSkin = findSkin(vecPossSkins, strSkinName); if (itSkin != vecPossSkins.end()) { itSkin->addTargets(RM_CAR_SKIN_TARGET_3D_WHEELS); GfLogDebug(" Found %s-skinned 3D wheels (targets:%x)\n", strSkinName.c_str(), itSkin->getTargets()); } } } while (pCurWheel3DFile != pWheel3DFileList); } GfDirFreeList(pWheel3DFileList, NULL, true, true); // Search for skinned driver files if any. tFList *pDriverFileList = GfDirGetListFiltered(strFolderPath.c_str(), pszDriverTexName, pszDriverTexExt); if (pDriverFileList) { tFList *pCurDriverFile = pDriverFileList; do { pCurDriverFile = pCurDriverFile->next; // Extract the skin name from the 3D wheel texture file name. const int nSkinNameLen = // Expecting "driver-<skin name>.png" strlen(pCurDriverFile->name) - strlen(pszDriverTexName) - 1 - strlen(pszDriverTexExt); if (nSkinNameLen > 0) { const std::string strSkinName = std::string(pCurDriverFile->name) .substr(strlen(pszDriverTexName) + 1, nSkinNameLen); // If a skin with such name already exists in the list, update it. std::vector<GfDriverSkin>::iterator itSkin = findSkin(vecPossSkins, strSkinName); if (itSkin != vecPossSkins.end()) { itSkin->addTargets(RM_CAR_SKIN_TARGET_DRIVER); GfLogDebug(" Found %s-skinned driver (targets:%x)\n", strSkinName.c_str(), itSkin->getTargets()); } } } while (pCurDriverFile != pDriverFileList); } GfDirFreeList(pDriverFileList, NULL, true, true); }
void OsgGraph::unloadTrack() { GfLogDebug("OsgGraph::unloadTrack\n"); ::shutdownTrack(); }
int RmGetFeaturesList( void* param ) { int nCars; char const *cardllname; int caridx; char const *features; int driverFeatureMask; int raceFeatureMask = -1; // All bits set to 1. void *robhdle; char path[ 256 ]; char buf[ 1024 ]; int xx, yy; int features_index; int buf_index; nCars = GfParmGetEltNb( param, RM_SECT_DRIVERS ); for( xx = 1; xx < nCars + 1; ++xx ) { /* Open robot */ sprintf( path, "%s/%d", RM_SECT_DRIVERS, xx ); cardllname = GfParmGetStr( param, path, RM_ATTR_MODULE, "" ); caridx = (int)GfParmGetNum( param, path, RM_ATTR_IDX, NULL, 0 ); sprintf( buf, "%s/drivers/%s/%s.xml", GfLocalDir(), 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 ) continue; driverFeatureMask = 0; sprintf( buf, "%s/%s/%d", ROB_SECT_ROBOTS, ROB_LIST_INDEX, caridx ); if( strcmp( GfParmGetStr( robhdle, buf, ROB_ATTR_TYPE, ROB_VAL_ROBOT ), ROB_VAL_HUMAN ) == 0 ) { if( strcmp( GfParmGetStr( robhdle, buf, ROB_ATTR_LEVEL, ROB_VAL_ARCADE ), ROB_VAL_ARCADE ) == 0 ) driverFeatureMask |= RM_FEATURE_TIMEDSESSION; else if( strcmp( GfParmGetStr( robhdle, buf, ROB_ATTR_LEVEL, ROB_VAL_ARCADE ), ROB_VAL_SEMI_ROOKIE ) == 0 ) driverFeatureMask |= RM_FEATURE_TIMEDSESSION; else if( strcmp( GfParmGetStr( robhdle, buf, ROB_ATTR_LEVEL, ROB_VAL_ARCADE ), ROB_VAL_ROOKIE ) == 0 ) driverFeatureMask |= RM_FEATURE_TIMEDSESSION; else if( strcmp( GfParmGetStr( robhdle, buf, ROB_ATTR_LEVEL, ROB_VAL_ARCADE ), ROB_VAL_AMATEUR ) == 0 ) driverFeatureMask |= RM_FEATURE_TIMEDSESSION | RM_FEATURE_WETTRACK; /* | RM_FEATURE_BLUE */ else if( strcmp( GfParmGetStr( robhdle, buf, ROB_ATTR_LEVEL, ROB_VAL_ARCADE ), ROB_VAL_SEMI_PRO ) == 0 ) driverFeatureMask |= RM_FEATURE_TIMEDSESSION | RM_FEATURE_WETTRACK; /* | RM_FEATURE_PENALTIES | RM_FEATURE_SC | RM_FEATURE_YELLOW | RM_FEATURE_RED | */ else if( strcmp( GfParmGetStr( robhdle, buf, ROB_ATTR_LEVEL, ROB_VAL_ARCADE ), ROB_VAL_PRO ) == 0 ) driverFeatureMask |= RM_FEATURE_TIMEDSESSION | RM_FEATURE_PENALTIES | RM_FEATURE_WETTRACK; /*RM_FEATURE_SC | RM_FEATURE_YELLOW | RM_FEATURE_BLUE | RM_FEATURE_RED | RM_FEATURE_PITEXIT |*/ } else if( strcmp( GfParmGetStr( robhdle, buf, ROB_ATTR_TYPE, ROB_VAL_ROBOT ), ROB_VAL_ROBOT ) == 0 ) { sprintf( buf, "%s/%s/%d", ROB_SECT_ROBOTS, ROB_LIST_INDEX, caridx ); features = GfParmGetStr( robhdle, buf, ROB_ATTR_FEATURES, "" ); features_index = 0; buf_index = 0; while( true ) { if( features[ features_index ] != '\0' && features[ features_index ] != ';' && buf_index < nMaxFeatureNameLength ) { /* Feature name not yet ended */ buf[ buf_index ] = features[ features_index ]; ++buf_index; ++features_index; } else if( features[ features_index ] == '\0' || features[ features_index ] == ';' ) { /* Feature name ended, check for matched */ buf[ buf_index ] = '\0'; for( yy = 0; yy < nFeatures; ++yy ) { if( strcmp( features_list[ yy ].name, buf ) == 0 ) { driverFeatureMask |= features_list[ yy ].value; } } if( features[ features_index ] == '\0' ) break; /* Leave */ ++features_index; buf_index = 0; } } } GfLogDebug("Driver %s#%d supported-feature mask : 0x%02X\n", cardllname, caridx, driverFeatureMask); /* Binary and: the raceFeatureMask is only the features all cars have */ raceFeatureMask &= driverFeatureMask; GfParmReleaseHandle( robhdle ); } GfLogTrace("Race supported-feature mask : 0x%02X\n", raceFeatureMask); return raceFeatureMask; }
static void rmQualifResults(void *prevHdle, tRmInfo *info, const char* pszTitle, int start) { void *results = info->results; const char *race = info->_reRaceName; int i; static char buf[256]; static char path[512]; char *str; GfLogTrace("Entering %s Results menu\n", pszTitle); // Create screen, load menu XML descriptor and create static controls. rmScrHdle = GfuiScreenCreate(); void *hmenu = GfuiMenuLoad("qualifsresultsmenu.xml"); GfuiMenuCreateStaticControls(rmScrHdle, hmenu); // Create variable title label. const int titleId = GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "Title"); snprintf(buf, sizeof(buf), "%s at %s", race, info->track->name); GfuiLabelSetText(rmScrHdle, titleId, buf); // Get layout properties. const int nMaxLines = (int)GfuiMenuGetNumProperty(hmenu, "nMaxResultLines", 15); const int yTopLine = (int)GfuiMenuGetNumProperty(hmenu, "yTopLine", 400); const int yLineShift = (int)GfuiMenuGetNumProperty(hmenu, "yLineShift", 20); // Never used : remove ? //snprintf(path, sizeof(path), "%s/%s/%s/%s/%d", info->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, 1); //tdble refTime = GfParmGetNum(results, path, RE_ATTR_TIME, NULL, 0); //snprintf(path, sizeof(path), "%s/%s/%s", info->track->name, RE_SECT_RESULTS, race); //const int totLaps = (int)GfParmGetNum(results, path, RE_ATTR_LAPS, NULL, 0); snprintf(path, sizeof(path), "%s/%s/%s/%s", info->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK); const int nbCars = (int)GfParmGetEltNb(results, path); GfLogDebug("rmQualifResults: path=%s, file=%s\n", path, GfParmGetFileName(results)); GfLogDebug("rmQualifResults: start=%d, nbCars=%d, nMaxLines=%d\n", start, nbCars, nMaxLines); int y = yTopLine; for (i = start; i < MIN(start + nMaxLines, nbCars); i++) { snprintf(path, sizeof(path), "%s/%s/%s/%s/%d", info->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, i + 1); // Never used : remove ? //const int laps = (int)GfParmGetNum(results, path, RE_ATTR_LAPS, NULL, 0); //Rank snprintf(buf, sizeof(buf), "%d", i+1); GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "Rank", true, // From template. buf, GFUI_TPL_X, y); //Driver short name GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "DriverName", true, // From template. GfParmGetStr(results, path, RE_ATTR_SNAME, ""), GFUI_TPL_X, y); //Driver type const std::string strModName = GfParmGetStr(results, path, RE_ATTR_MODULE, ""); GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "DriverType", true, // From template. GfDriver::getType(strModName).c_str(), GFUI_TPL_X, y); //Car GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "CarModel", true, // From template. GfParmGetStr(results, path, RE_ATTR_CAR, ""), GFUI_TPL_X, y); //Best lap str = GfTime2Str(GfParmGetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, 0), 0, false, 3); GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "BestLapTime", true, // From template. str, GFUI_TPL_X, y); free(str); // Next line. y -= yLineShift; }//for i if (start > 0) { RmPrevRace.prevHdle = prevHdle; RmPrevRace.info = info; RmPrevRace.start = start - nMaxLines; RmPrevRace.title = pszTitle; GfuiMenuCreateButtonControl(rmScrHdle, hmenu, "PreviousPageArrow", (void*)&RmPrevRace, rmChgQualifScreen); GfuiAddKey(rmScrHdle, GFUIK_PAGEUP, "Previous Results", (void*)&RmPrevRace, rmChgQualifScreen, NULL); } // Add "Continue" button GfuiMenuCreateButtonControl(rmScrHdle, hmenu, "ContinueButton", prevHdle, GfuiScreenReplace); //Create 'save' button in the bottom right //rmSaveButtonId = GfuiMenuCreateButtonControl(rmScrHdle, hmenu, "savebutton", info, rmSaveRes); if (i < nbCars) { RmNextRace.prevHdle = prevHdle; RmNextRace.info = info; RmNextRace.start = start + nMaxLines; RmNextRace.title = pszTitle; GfuiMenuCreateButtonControl(rmScrHdle, hmenu, "NextPageArrow", (void*)&RmNextRace, rmChgQualifScreen); GfuiAddKey(rmScrHdle, GFUIK_PAGEDOWN, "Next Results", (void*)&RmNextRace, rmChgQualifScreen, NULL); } GfuiAddKey(rmScrHdle, GFUIK_ESCAPE, "Continue", prevHdle, GfuiScreenReplace, NULL); GfuiAddKey(rmScrHdle, GFUIK_RETURN, "Continue", prevHdle, GfuiScreenReplace, NULL); GfuiAddKey(rmScrHdle, GFUIK_F12, "Take a Screen Shot", NULL, GfuiScreenShot, NULL); GfuiAddKey(rmScrHdle, GFUIK_F1, "Help", rmScrHdle, GfuiHelpScreen, NULL); GfuiScreenActivate(rmScrHdle); }
bool OsgGraph::setupView(int x, int y, int width, int height, void* pMenuScreen) { GfLogDebug("OsgGraph::setupView\n"); return ::initView(x, y, width, height, GR_VIEW_STD, pMenuScreen) == 0; }
bool OsgGraph::loadCars(tSituation* pSituation) { initCars(pSituation); GfLogDebug("OsgGraph::loadCars\n"); /*return true;*/ return ::initCars(pSituation) == 0; }
// Implementation of IGraphicsEngine **************************************** bool OsgGraph::loadTrack(tTrack* pTrack) { GfLogDebug("OsgGraph::loadTrack\n"); return ::initTrack(pTrack) == 0; }
void SimWheelUpdateForce(tCar *car, int index) { tWheel *wheel = &(car->wheel[index]); tdble axleFz = wheel->axleFz; tdble vt, v, v2, wrl; // wheel related velocity tdble Fn, Ft; tdble waz; tdble CosA, SinA; tdble s, sa, sx, sy; // slip vector tdble stmp, F, Bx; tdble mu; tdble reaction_force = 0.0f; wheel->state = 0; // VERTICAL STUFF CONSIDERING SMALL PITCH AND ROLL ANGLES // update suspension force SimSuspUpdate(&(wheel->susp)); // check suspension state wheel->state |= wheel->susp.state; if ((wheel->state & SIM_SUSP_EXT) == 0) { wheel->forces.z = axleFz + wheel->susp.force; reaction_force = wheel->forces.z; wheel->rel_vel -= SimDeltaTime * wheel->susp.force / wheel->mass; if (wheel->forces.z < 0.0f) { wheel->forces.z = 0.0f; } } else { if (wheel->rel_vel < 0.0) { wheel->rel_vel = 0.0; } wheel->rel_vel -= SimDeltaTime * wheel->susp.force / wheel->mass; wheel->forces.z = 0.0f; } // update wheel coord, center relative to GC wheel->relPos.z = - wheel->susp.x / wheel->susp.spring.bellcrank + wheel->radius; // HORIZONTAL FORCES waz = wheel->steer + wheel->staticPos.az; CosA = cos(waz); SinA = sin(waz); // tangent velocity. vt = wheel->bodyVel.x * CosA + wheel->bodyVel.y * SinA; v2 = wheel->bodyVel.x * wheel->bodyVel.x + wheel->bodyVel.y * wheel->bodyVel.y; v = sqrt(v2); // slip angle if (v < 0.000001f) { sa = 0.0f; } else { sa = atan2(wheel->bodyVel.y, wheel->bodyVel.x) - waz; } FLOAT_NORM_PI_PI(sa); wrl = wheel->spinVel * wheel->radius; if ((wheel->state & SIM_SUSP_EXT) != 0) { sx = sy = 0.0f; } else if (v < 0.000001f) { sx = wrl; sy = 0.0f; } else { sx = (vt - wrl) / fabs(vt); sy = sin(sa); } Ft = 0.0f; Fn = 0.0f; s = sqrt(sx*sx+sy*sy); { // calculate _skid and _reaction for sound. if (v < 2.0f) { car->carElt->_skid[index] = 0.0f; } else { car->carElt->_skid[index] = MIN(1.0f, (s*reaction_force*0.0002f)); } car->carElt->_reaction[index] = reaction_force; } stmp = MIN(s, 1.5f); // MAGIC FORMULA Bx = wheel->mfB * stmp; F = sin(wheel->mfC * atan(Bx * (1.0f - wheel->mfE) + wheel->mfE * atan(Bx))) * (1.0f + stmp * simSkidFactor[car->carElt->_skillLevel]); // load sensitivity mu = wheel->mu * (wheel->lfMin + (wheel->lfMax - wheel->lfMin) * exp(wheel->lfK * wheel->forces.z / wheel->opLoad)); F *= wheel->forces.z * mu * wheel->trkPos.seg->surface->kFriction * (1.0f + 0.05f * sin(-wheel->staticPos.ax * 18.0f)); /* coeff */ //For debug weather with some tracks #ifdef SD_DEBUG GfLogDebug("Simu v2 kFriction : %f ", wheel->trkPos.seg->surface->kFriction); #endif wheel->rollRes = wheel->forces.z * wheel->trkPos.seg->surface->kRollRes; car->carElt->priv.wheel[index].rollRes = wheel->rollRes; if (s > 0.000001f) { // wheel axis based Ft -= F * sx / s; Fn -= F * sy / s; } FLOAT_RELAXATION2(Fn, wheel->preFn, 50.0f); FLOAT_RELAXATION2(Ft, wheel->preFt, 50.0f); wheel->relPos.az = waz; wheel->forces.x = Ft * CosA - Fn * SinA; wheel->forces.y = Ft * SinA + Fn * CosA; wheel->spinTq = Ft * wheel->radius; wheel->sa = sa; wheel->sx = sx; wheel->feedBack.spinVel = wheel->spinVel; wheel->feedBack.Tq = wheel->spinTq; wheel->feedBack.brkTq = wheel->brake.Tq; car->carElt->_wheelSlipSide(index) = sy*v; car->carElt->_wheelSlipAccel(index) = sx*v; car->carElt->_reaction[index] = reaction_force; }
void OsgGraph::unloadCars() { GfLogDebug("OsgGraph::unloadCars\n"); ::shutdownCars(); }