// Retrieve the NetDriver instance with given index in the human module interface list static int GetHumanDriver(NetDriver &driver,int index) { void *params = GfParmReadFileLocal("drivers/human/human.xml", GFPARM_RMODE_STD); assert(params); char path2[256]; sprintf(path2, "Robots/index/%d",index); if (GfParmExistsSection(params, path2) == 0) return 0; strncpy(driver.name,GfParmGetStr(params, path2, "name",NULL),64); strncpy(driver.sname,GfParmGetStr(params, path2, ROB_ATTR_SNAME, NULL), 64); strncpy(driver.cname,GfParmGetStr(params, path2, ROB_ATTR_CODE, NULL), 4); strncpy(driver.car,GfParmGetStr(params, path2, "car name",NULL),64); strncpy(driver.type,GfParmGetStr(params, path2, "type",NULL),64); strncpy(driver.skilllevel,GfParmGetStr(params, path2, "skill level",NULL),64); driver.racenumber = GfParmGetNum(params, path2, "race number",NULL,1.0); driver.red = GfParmGetNum(params, path2, "red",NULL,1.0); driver.green = GfParmGetNum(params, path2, "green",NULL,1.0); driver.blue = GfParmGetNum(params, path2, "blue",NULL,1.0); strncpy(driver.module,NETWORKROBOT,64); GfParmReleaseHandle(params); return 1; }
/* Put given player settings (from PlayersInfo array) to the human drivers and preferences params (index is the identification number in params, beginning at 1)*/ static void PutPlayerSettings(unsigned index) { if (!PlayerHdle || !PrefHdle) { return; } tPlayerInfo *player = PlayersInfo[index-1]; // Graphics params (take driver name changes into account for camera settings). char drvSectionPath[128]; snprintf(drvSectionPath, sizeof(drvSectionPath), "%s/%s/%u", ROB_SECT_ROBOTS, ROB_LIST_INDEX, index); const char* pszOldDispName = GfParmGetStr(PlayerHdle, drvSectionPath, ROB_ATTR_NAME, ""); if (strcmp(pszOldDispName, player->dispName())) { // Only if the display name changed. char drvDispSecPath[128]; snprintf(drvDispSecPath, sizeof(drvDispSecPath), "%s/%s", GR_SCT_DISPMODE, pszOldDispName); if (!GraphHdle) // Load graphic params file if not already done. { char pszGraphFileName[256]; snprintf(pszGraphFileName, sizeof(pszGraphFileName), "%s%s", GfLocalDir(), GR_PARAM_FILE); GraphHdle = GfParmReadFile(pszGraphFileName, GFPARM_RMODE_REREAD); } if (GfParmExistsSection(GraphHdle, drvDispSecPath)) { // Change section name. GfParmListRenameElt(GraphHdle, GR_SCT_DISPMODE, pszOldDispName, player->dispName()); } if (!GfParmListSeekFirst(GraphHdle, GR_SCT_DISPMODE)) { do { const char* pszSecName = GfParmListGetCurEltName(GraphHdle, GR_SCT_DISPMODE); if (!pszSecName || !isdigit(*pszSecName)) continue; // Ignore sections whose name is not (likely) a screen id. snprintf(drvDispSecPath, sizeof(drvDispSecPath), "%s/%s", GR_SCT_DISPMODE, pszSecName); const char* pszCurDrvName = GfParmGetStr(GraphHdle, drvDispSecPath, GR_ATT_CUR_DRV, ""); if (!strcmp(pszOldDispName, pszCurDrvName)) // Change current driver name. GfParmSetStr(GraphHdle, drvDispSecPath, GR_ATT_CUR_DRV, player->dispName()); } while (!GfParmListSeekNext(GraphHdle, GR_SCT_DISPMODE)); } } // Human driver params GfParmSetStr(PlayerHdle, drvSectionPath, ROB_ATTR_NAME, player->dispName()); GfParmSetStr(PlayerHdle, drvSectionPath, ROB_ATTR_SNAME, player->dispName()); GfParmSetStr(PlayerHdle, drvSectionPath, ROB_ATTR_CODE, "PLA"); GfParmSetStr(PlayerHdle, drvSectionPath, ROB_ATTR_CAR, player->defaultCarName()); GfParmSetNum(PlayerHdle, drvSectionPath, ROB_ATTR_RACENUM, (char*)NULL, player->raceNumber()); GfParmSetNum(PlayerHdle, drvSectionPath, ROB_ATTR_RED, (char*)NULL, player->color(0)); GfParmSetNum(PlayerHdle, drvSectionPath, ROB_ATTR_GREEN, (char*)NULL, player->color(1)); GfParmSetNum(PlayerHdle, drvSectionPath, ROB_ATTR_BLUE, (char*)NULL, player->color(2)); GfParmSetStr(PlayerHdle, drvSectionPath, ROB_ATTR_TYPE, ROB_VAL_HUMAN); GfParmSetStr(PlayerHdle, drvSectionPath, ROB_ATTR_LEVEL, SkillLevelString[player->skillLevel()]); // Driver preferences params snprintf(drvSectionPath, sizeof(drvSectionPath), "%s/%s/%u", HM_SECT_PREF, HM_LIST_DRV, index); GfParmSetStr(PrefHdle, drvSectionPath, HM_ATT_TRANS, player->gearChangeModeString()); GfParmSetNum(PrefHdle, drvSectionPath, HM_ATT_NBPITS, (char*)NULL, (tdble)player->nbPitStops()); GfParmSetStr(PrefHdle, drvSectionPath, HM_ATT_AUTOREVERSE, Yn[player->autoReverse()]); /* Allow neutral gear in sequential mode if neutral gear command not defined */ if (player->gearChangeMode() == GEAR_MODE_SEQ && !strcmp(GfParmGetStr(PrefHdle, drvSectionPath, HM_ATT_GEAR_N, "-"), "-")) GfParmSetStr(PrefHdle, drvSectionPath, HM_ATT_SEQSHFT_ALLOW_NEUTRAL, HM_VAL_YES); else GfParmSetStr(PrefHdle, drvSectionPath, HM_ATT_SEQSHFT_ALLOW_NEUTRAL, HM_VAL_NO); /* Allow reverse gear in sequential mode if reverse gear command not defined */ if (player->gearChangeMode() == GEAR_MODE_SEQ && !strcmp(GfParmGetStr(PrefHdle, drvSectionPath, HM_ATT_GEAR_R, "-"), "-")) GfParmSetStr(PrefHdle, drvSectionPath, HM_ATT_SEQSHFT_ALLOW_REVERSE, HM_VAL_YES); else GfParmSetStr(PrefHdle, drvSectionPath, HM_ATT_SEQSHFT_ALLOW_REVERSE, HM_VAL_NO); /* Release gear lever goes neutral in grid mode if no neutral gear command defined */ if (player->gearChangeMode() == GEAR_MODE_GRID && !strcmp(GfParmGetStr(PrefHdle, drvSectionPath, HM_ATT_GEAR_N, "-"), "-")) GfParmSetStr(PrefHdle, drvSectionPath, HM_ATT_REL_BUT_NEUTRAL, HM_VAL_YES); else GfParmSetStr(PrefHdle, drvSectionPath, HM_ATT_REL_BUT_NEUTRAL, HM_VAL_NO); }
// Save settings to screen.xml void GfglFeatures::storeSelection(void* hparmConfig) const { // Display what we have selected. dumpSelection(); // Open the config file if not already done. void* hparm = hparmConfig ? hparmConfig : openConfigFile(); // Write new values. GfParmSetStr(hparm, GFSCR_SECT_GLSELFEATURES, GFSCR_ATT_TEXTURECOMPRESSION, isSelected(TextureCompression) ? GFSCR_ATT_TEXTURECOMPRESSION_ENABLED : GFSCR_ATT_TEXTURECOMPRESSION_DISABLED); if (getSupported(TextureMaxSize) != InvalidInt) GfParmSetNum(hparm, GFSCR_SECT_GLSELFEATURES, GFSCR_ATT_MAXTEXTURESIZE, pszNoUnit, (tdble)getSelected(TextureMaxSize)); else GfParmRemove(hparm, GFSCR_SECT_GLSELFEATURES, GFSCR_ATT_MAXTEXTURESIZE); GfParmSetStr(hparm, GFSCR_SECT_GLSELFEATURES, GFSCR_ATT_MULTITEXTURING, isSelected(MultiTexturing) ? GFSCR_ATT_MULTITEXTURING_ENABLED : GFSCR_ATT_MULTITEXTURING_DISABLED); GfParmSetStr(hparm, GFSCR_SECT_GLSELFEATURES, GFSCR_ATT_MULTISAMPLING, isSelected(MultiSampling) ? GFSCR_ATT_MULTISAMPLING_ENABLED : GFSCR_ATT_MULTISAMPLING_DISABLED); if (getSupported(MultiSamplingSamples) != InvalidInt) GfParmSetNum(hparm, GFSCR_SECT_GLSELFEATURES, GFSCR_ATT_MULTISAMPLINGSAMPLES, pszNoUnit, (tdble)getSelected(MultiSamplingSamples)); else GfParmRemove(hparm, GFSCR_SECT_GLSELFEATURES, GFSCR_ATT_MULTISAMPLINGSAMPLES); // Force 'best possible' mode for video initialization when anti-aliasing selected if (isSelected(MultiSampling)) { // Use the 'in-test' specs if present, and reset the test state // (force a new validation). if (GfParmExistsSection(hparm, GFSCR_SECT_INTESTPROPS)) { GfParmSetStr(hparm, GFSCR_SECT_INTESTPROPS, GFSCR_ATT_TESTSTATE, GFSCR_VAL_INPROGRESS); GfParmSetStr(hparm, GFSCR_SECT_INTESTPROPS, GFSCR_ATT_VINIT, GFSCR_VAL_VINIT_BEST); } // Otherwise, use the 'validated' specs ... no new validation needed // (if we can en/disable multi-sampling, it means that we already checked // that it was possible, and how much). else { GfParmSetStr(hparm, GFSCR_SECT_VALIDPROPS, GFSCR_ATT_VINIT, GFSCR_VAL_VINIT_BEST); } } GfParmSetStr(hparm, GFSCR_SECT_GLSELFEATURES, GFSCR_ATT_STEREOVISION, isSelected(StereoVision) ? GFSCR_ATT_STEREOVISION_ENABLED : GFSCR_ATT_STEREOVISION_DISABLED); GfParmSetStr(hparm, GFSCR_SECT_GLSELFEATURES, GFSCR_ATT_BUMPMAPPING, isSelected(BumpMapping) ? GFSCR_ATT_BUMPMAPPING_ENABLED : GFSCR_ATT_BUMPMAPPING_DISABLED); if (getSupported(AnisotropicFiltering) != InvalidInt) GfParmSetNum(hparm, GFSCR_SECT_GLSELFEATURES, GFSCR_ATT_ANISOTROPICFILTERING, pszNoUnit, (tdble)getSelected(AnisotropicFiltering)); else GfParmRemove(hparm, GFSCR_SECT_GLSELFEATURES, GFSCR_ATT_ANISOTROPICFILTERING); // Write new params to config file. GfParmWriteFile(NULL, hparm, "Screen"); // Close config file if we open it. if (!hparmConfig) closeConfigFile(hparm); }
static void UpdateNetworkPlayers() { GfDriver* newDriver; NetNetwork *pNetwork = NetGetNetwork(); if (pNetwork->GetRefreshDisplay() == false) return; tRmInfo* reInfo = LmRaceEngine().inData(); //Set current driver that camera will look at pNetwork->SetCurrentDriver(); //reload xml file NetGetNetwork()->SetRaceXMLFile("config/raceman/networkrace.xml"); reInfo->params = GfParmReadFileLocal("config/raceman/networkrace.xml",GFPARM_RMODE_REREAD); assert(reInfo->params); reInfo->_reName = GfParmGetStr(reInfo->params, RM_SECT_HEADER, RM_ATTR_NAME, ""); assert(reInfo->_reName); // Scan each of the human drivers to see if they're active in this race if (NetIsServer()) { NetServerMutexData *pSData = NetGetServer()->LockServerData(); assert(pSData); // Ensure that garage menu knows about driver for (unsigned int i=0; i < pSData->m_vecNetworkPlayers.size(); i++) { newDriver = GfDrivers::self()->getDriver(NETWORKROBOT, pSData->m_vecNetworkPlayers[i].idx); if (!newDriver) { GfLogInfo("Driver %s not found, reloading drivers\n", pSData->m_vecNetworkPlayers[i].name); GfDrivers::self()->reload(); LmRaceEngine().race()->load(LmRaceEngine().race()->getManager(), true); break; } } for (unsigned int i=0; i < pSData->m_vecNetworkPlayers.size(); i++) { int k = 1; char path2[256]; pSData->m_vecNetworkPlayers[i].active = false; newDriver = GfDrivers::self()->getDriver(NETWORKROBOT, pSData->m_vecNetworkPlayers[i].idx); // Scan through drivers listed in 'networkrace.xml' while (pSData->m_vecNetworkPlayers[i].active == false) { sprintf(path2, "%s/%d", RM_SECT_DRIVERS, k++); if (GfParmExistsSection(reInfo->params, path2) == 0) { GfLogInfo("UpdateNetworkPlayers: Removing driver %s\n", pSData->m_vecNetworkPlayers[i].name); if (pSData->m_vecNetworkPlayers[i].client) { //need to tell/force client to disconnect } break; } if ((tdble)pSData->m_vecNetworkPlayers[i].idx == GfParmGetNum(reInfo->params, path2, RM_ATTR_IDX, NULL, 1.0) && strcmp(NETWORKROBOT, GfParmGetStr(reInfo->params, path2, RM_ATTR_MODULE, "")) == 0) { pSData->m_vecNetworkPlayers[i].active = true; } } // add or remove from competitor list (for garage menu) GfDriver* activeDriver = LmRaceEngine().race()->getCompetitor(NETWORKROBOT, pSData->m_vecNetworkPlayers[i].idx); if (pSData->m_vecNetworkPlayers[i].active) { if (!activeDriver) LmRaceEngine().race()->appendCompetitor(newDriver); } else { if (activeDriver) LmRaceEngine().race()->removeCompetitor(newDriver); } } NetGetServer()->UnlockServerData(); } else { #if 1 // Client XML files already written to disk - this works but is not the best solution.... GfDrivers::self()->reload(); LmRaceEngine().race()->load(LmRaceEngine().race()->getManager(), true); #endif } //Update track info std::string strTrackPath = GfParmGetStr(reInfo->params, "Tracks/1", RM_ATTR_NAME, ""); std::string strCategory = GfParmGetStr(reInfo->params, "Tracks/1", RM_ATTR_CATEGORY, ""); std::string strTrackName = GetTrackName(strCategory.c_str(),strTrackPath.c_str()); sprintf(buf, "%s", strTrackName.c_str()); GfuiLabelSetText(racemanMenuHdle,g_trackHd,buf); //Store current track - client needs this GfTrack* PCurTrack = GfTracks::self()->getTrackWithName(buf); LmRaceEngine().race()->getManager()->setEventTrack(0, PCurTrack); int laps = (int)GfParmGetNum(reInfo->params, reInfo->_reName,"laps", "", 1); sprintf(buf, "%i", laps); GfuiLabelSetText(racemanMenuHdle,g_lapsHd,buf); GfuiScreenAddBgImg(racemanMenuHdle, GetTrackPreviewFileName(strCategory.c_str(),strTrackPath.c_str()).c_str()); GfuiStaticImageSet(racemanMenuHdle, g_OutlineId, GetTrackOutlineFileName(strCategory.c_str(),strTrackPath.c_str()).c_str()); // Update category info std::string strCarCat; bool bCollisions; NetGetNetwork()->GetHostSettings(strCarCat,bCollisions); GfuiLabelSetText(racemanMenuHdle,g_catHd,strCarCat.c_str()); //fill in player data int nCars = GfParmGetEltNb(reInfo->params, RM_SECT_DRIVERS); char dname[256]; char robpath[256]; float *pColor = &green[0]; bool bEveryoneReadyToRace = true; for (int i = 1; i < nCars+1; i++) { sprintf(dname, "%s/%d", RM_SECT_DRIVERS, i); const char* robot = GfParmGetStr(reInfo->params, dname, RM_ATTR_MODULE, ""); //lookup playerName and car name sprintf(robpath,"drivers/%s/%s.xml",robot,robot); void *pMod = GfParmReadFileLocal(robpath,GFPARM_RMODE_REREAD); if (pMod == NULL) { //try again in other path sprintf(robpath,"drivers/%s/%s.xml",robot,robot); pMod = GfParmReadFile(robpath,GFPARM_RMODE_REREAD); if (pMod == NULL) continue; } assert(pMod); char ppname[256]; int idx = GfParmGetNum(reInfo->params, dname, RM_ATTR_IDX, "",0); sprintf(ppname,"Robots/index/%d",idx); const char* name = GfParmGetStr(pMod, ppname, RM_ATTR_NAME, ""); const char* car = GfParmGetStr(pMod, ppname, "car name", ""); std::string strRealCar = GfCars::self()->getCar(car)->getName(); // WAIT : pNData->m_vecReadyStatus[i-1] ?! // This can only work when _only_ networkhuman drivers in the race // (that is _no_robot_driver_) ; because m_vecReadyStatus is indexed // by the networkhuman drivers list. // TO fix this, 2 solutions: // 1) make the networking module take care of the robot drivers too // (in m_vecReadyStatus, m_vecNetworkPlayers, ...) // 2) make the networking _menu_ only take care of the networkhuman drivers. bool bReady = bRobotsReady; if(strcmp(NETWORKROBOT, GfParmGetStr(reInfo->params, dname, RM_ATTR_MODULE, "")) == 0) { // Write car model, as it may have changed via garage menu if (NetIsServer()) { NetServerMutexData *pSData = NetGetServer()->LockServerData(); strncpy(pSData->m_vecNetworkPlayers[idx-1].car, car, 64); GfLogInfo("idx %d car set to %s\n", idx, car); // also need to write back for garage menu const GfCar* newCar = GfCars::self()->getCar(car); newDriver = GfDrivers::self()->getDriver(NETWORKROBOT, pSData->m_vecNetworkPlayers[idx-1].idx); newDriver->setCar(newCar); NetGetServer()->UnlockServerData(); } //GfLogInfo("idx %d, m_vecReadyStatus.size() %d\n", idx, pNData->m_vecReadyStatus.size()); NetMutexData *pNData = NetGetNetwork()->LockNetworkData(); bReady = pNData->m_vecReadyStatus[idx-1]; NetGetNetwork()->UnlockNetworkData(); } int readyindex = 0; if (bReady) readyindex = 1; else bEveryoneReadyToRace = false; if (strcmp(NetGetNetwork()->GetDriverName(),name)==0) { pColor = &green[0]; g_strCar = strRealCar; //Make sure checkbox matches ready state GfuiCheckboxSetChecked(racemanMenuHdle, g_ReadyCheckboxId, bReady); if (NetGetClient()) EnableMenuClientButtons(bReady); else EnableMenuHostButtons(bReady); } else pColor = &white[0]; GfuiVisibilitySet(racemanMenuHdle,g_readystatus[i-1],true); GfuiStaticImageSetActive(racemanMenuHdle,g_readystatus[i-1],readyindex); GfuiLabelSetColor(racemanMenuHdle, g_playerNames[i-1], pColor); GfuiLabelSetText(racemanMenuHdle,g_playerNames[i-1],name); GfuiLabelSetColor(racemanMenuHdle, g_carNames[i-1], pColor); GfuiLabelSetText(racemanMenuHdle,g_carNames[i-1],strRealCar.c_str()); GfParmReleaseHandle(pMod); } //Clear out rest of table for (int i=nCars;i<MAXNETWORKPLAYERS;i++) { GfuiVisibilitySet(racemanMenuHdle,g_readystatus[i],false); GfuiLabelSetText(racemanMenuHdle,g_playerNames[i],""); GfuiLabelSetText(racemanMenuHdle,g_carNames[i],""); } pNetwork->SetRefreshDisplay(false); GfuiApp().eventLoop().postRedisplay(); if (NetIsClient()) { NetGetClient()->ConnectToClients(); if (!NetGetClient()->TimeSynced()) { NetGetClient()->SendServerTimeRequest(); } } if (NetIsServer()) { if (bEveryoneReadyToRace && nCars > 1) ServerPrepareStartNetworkRace(NULL); } }