void HmReadPrefs(const int index) { const char *prm; const char *defaultSettings; char sstring[1024]; tCtrlRef *ref; const int idx = index - 1; tControlCmd *cmdCtrl; cmdCtrl = HCtx[idx]->cmdControl = (tControlCmd *) calloc (NbCmdControl, sizeof (tControlCmd)); memcpy(cmdCtrl, CmdControlRef, NbCmdControl * sizeof (tControlCmd)); sprintf(sstring, "%s%s", GfLocalDir(), HM_PREF_FILE); PrefHdle = GfParmReadFile(sstring, GFPARM_RMODE_REREAD | GFPARM_RMODE_CREAT); sprintf(sstring, "%s/%s/%d", HM_SECT_PREF, HM_LIST_DRV, index); prm = GfParmGetStr(PrefHdle, sstring, HM_ATT_TRANS, HM_VAL_AUTO); if (!strcmp(prm, HM_VAL_AUTO)) HCtx[idx]->transmission = eTransAuto; else if (!strcmp(prm, HM_VAL_SEQ)) HCtx[idx]->transmission = eTransSeq; else if (!strcmp(prm, HM_VAL_HBOX)) HCtx[idx]->transmission = eTransHbox; else HCtx[idx]->transmission = eTransGrid; /* Parameters Settings */ //ABS on/off prm = GfParmGetStr(PrefHdle, sstring, HM_ATT_ABS, Yn[HCtx[idx]->paramAbs].c_str()); HCtx[idx]->paramAbs = (prm == Yn[0]); //ASR on/off prm = GfParmGetStr(PrefHdle, sstring, HM_ATT_ASR, Yn[HCtx[idx]->paramAsr].c_str()); HCtx[idx]->paramAsr = (prm == Yn[0]); //Controls prm = GfParmGetStr(PrefHdle, HM_SECT_PREF, HM_ATT_CONTROL, controlList[2].parmName); prm = GfParmGetStr(PrefHdle, sstring, HM_ATT_CONTROL, prm); int i; for (i = 0; i < nbControl; i++) { if (!strcmp(prm, controlList[i].parmName)) break; }//for i if (i == nbControl) i = 2; if (i == 0 && !joyPresent) i = 2; defaultSettings = controlList[i].settings; /* Command Settings */ GfOut("Command settings :\n"); for (int cmd = 0; cmd < NbCmdControl; cmd++) { prm = GfctrlGetNameByRef(cmdCtrl[cmd].type, cmdCtrl[cmd].val); prm = GfParmGetStr(PrefHdle, defaultSettings, cmdCtrl[cmd].name, prm); prm = GfParmGetStr(PrefHdle, sstring, cmdCtrl[cmd].name, prm); if (!prm || strlen(prm) == 0) { cmdCtrl[cmd].type = GFCTRL_TYPE_NOT_AFFECTED; GfOut(" %s\t: None (-1)\n", cmdCtrl[cmd].name); continue; } ref = GfctrlGetRefByName(prm); cmdCtrl[cmd].type = ref->type; // GFCTRL_TYPE_XX cmdCtrl[cmd].val = ref->index; // Index for joy. axis, buttons ; 1-bytes ASCII code for keys. GfOut(" %s\t: %s\n", cmdCtrl[cmd].name, prm); /* min value < max value */ if (cmdCtrl[cmd].minName) { cmdCtrl[cmd].min = (float)GfParmGetNum(PrefHdle, defaultSettings, cmdCtrl[cmd].minName, (char*)NULL, (tdble)cmdCtrl[cmd].min); cmdCtrl[cmd].min = cmdCtrl[cmd].minVal = (float)GfParmGetNum(PrefHdle, sstring, cmdCtrl[cmd].minName, (char*)NULL, (tdble)cmdCtrl[cmd].min); }//if minName /* max value > min value */ if (cmdCtrl[cmd].maxName) { cmdCtrl[cmd].max = (float)GfParmGetNum(PrefHdle, defaultSettings, cmdCtrl[cmd].maxName, (char*)NULL, (tdble)cmdCtrl[cmd].max); cmdCtrl[cmd].max = (float)GfParmGetNum(PrefHdle, sstring, cmdCtrl[cmd].maxName, (char*)NULL, (tdble)cmdCtrl[cmd].max); }//if maxName /* 0 < sensitivity */ if (cmdCtrl[cmd].sensName) { cmdCtrl[cmd].sens = (float)GfParmGetNum(PrefHdle, defaultSettings, cmdCtrl[cmd].sensName, (char*)NULL, (tdble)cmdCtrl[cmd].sens); cmdCtrl[cmd].sens = (float)GfParmGetNum(PrefHdle, sstring, cmdCtrl[cmd].sensName, (char*)NULL, (tdble)cmdCtrl[cmd].sens); if (cmdCtrl[cmd].sens <= 0.0) cmdCtrl[cmd].sens = 1.0e-6; }//if sensName /* 0 < power (1 = linear) */ if (cmdCtrl[cmd].powName) { cmdCtrl[cmd].pow = (float)GfParmGetNum(PrefHdle, defaultSettings, cmdCtrl[cmd].powName, (char*)NULL, (tdble)cmdCtrl[cmd].pow); cmdCtrl[cmd].pow = (float)GfParmGetNum(PrefHdle, sstring, cmdCtrl[cmd].powName, (char*)NULL, (tdble)cmdCtrl[cmd].pow); }//if powName /* 0 <= sensitivity to car speed */ if (cmdCtrl[cmd].spdSensName) { cmdCtrl[cmd].spdSens = (float)GfParmGetNum(PrefHdle, defaultSettings, cmdCtrl[cmd].spdSensName, (char*)NULL, (tdble)cmdCtrl[cmd].spdSens); cmdCtrl[cmd].spdSens = (float)GfParmGetNum(PrefHdle, sstring, cmdCtrl[cmd].spdSensName, (char*)NULL, (tdble)cmdCtrl[cmd].spdSens); if (cmdCtrl[cmd].spdSens < 0.0) cmdCtrl[cmd].spdSens = 0.0; }//if spdSendName /* 0 =< dead zone < max value - min value (not used for on/off controls like keyboard / mouse buttons / joystick buttons) */ if (cmdCtrl[cmd].deadZoneName) { cmdCtrl[cmd].deadZone = (float)GfParmGetNum(PrefHdle, defaultSettings, cmdCtrl[cmd].deadZoneName, (char*)NULL, (tdble)cmdCtrl[cmd].deadZone); cmdCtrl[cmd].deadZone = (float)GfParmGetNum(PrefHdle, sstring, cmdCtrl[cmd].deadZoneName, (char*)NULL, (tdble)cmdCtrl[cmd].deadZone); if (cmdCtrl[cmd].deadZone < 0.0) cmdCtrl[cmd].deadZone = 0.0; else if (cmdCtrl[cmd].deadZone > 1.0) cmdCtrl[cmd].deadZone = 1.0; }//if deadZoneName if (cmdCtrl[cmd].min > cmdCtrl[cmd].max) std::swap(cmdCtrl[cmd].min, cmdCtrl[cmd].max); //cmdCtrl[cmd].deadZone = (cmdCtrl[cmd].max - cmdCtrl[cmd].min) * cmdCtrl[cmd].deadZone; if (cmdCtrl[cmd].type == GFCTRL_TYPE_MOUSE_AXIS) HCtx[idx]->mouseControlUsed = 1; }//for cmd prm = GfParmGetStr(PrefHdle, defaultSettings, HM_ATT_REL_BUT_NEUTRAL, Yn[HCtx[idx]->relButNeutral].c_str()); prm = GfParmGetStr(PrefHdle, sstring, HM_ATT_REL_BUT_NEUTRAL, prm); HCtx[idx]->relButNeutral = (prm == Yn[0]); prm = GfParmGetStr(PrefHdle, defaultSettings, HM_ATT_SEQSHFT_ALLOW_NEUTRAL, Yn[HCtx[idx]->seqShftAllowNeutral].c_str()); prm = GfParmGetStr(PrefHdle, sstring, HM_ATT_SEQSHFT_ALLOW_NEUTRAL, prm); HCtx[idx]->seqShftAllowNeutral = (prm == Yn[0]); prm = GfParmGetStr(PrefHdle, defaultSettings, HM_ATT_SEQSHFT_ALLOW_REVERSE, Yn[HCtx[idx]->seqShftAllowReverse].c_str()); prm = GfParmGetStr(PrefHdle, sstring, HM_ATT_SEQSHFT_ALLOW_REVERSE, prm); HCtx[idx]->seqShftAllowReverse = (prm == Yn[0]); prm = GfParmGetStr(PrefHdle, sstring, HM_ATT_AUTOREVERSE, Yn[HCtx[idx]->autoReverse].c_str()); HCtx[idx]->autoReverse = (prm == Yn[0]); }//HmReadPrefs
/* Compute aerodynamic drag coefficient CW */ void Driver::initCw() { float cx = GfParmGetNum(car->_carHandle, SECT_AERODYNAMICS, PRM_CX, (char*) NULL, 0.0); float frontarea = GfParmGetNum(car->_carHandle, SECT_AERODYNAMICS, PRM_FRNTAREA, (char*) NULL, 0.0); CW = 0.645*cx*frontarea; }
void grInitBoardCar(tCarElt *car) { const int BUFSIZE=1024; char buf[BUFSIZE]; int index; void *handle; const char *param; myLoaderOptions options ; tgrCarInfo *carInfo; tgrCarInstrument *curInst; tdble xSz, ySz, xpos, ypos; tdble needlexSz, needleySz; ssgSetCurrentOptions ( &options ) ; index = car->index; /* current car's index */ carInfo = &grCarInfo[index]; handle = car->_carHandle; /* Tachometer */ curInst = &(carInfo->instrument[0]); /* Load the Tachometer texture */ param = GfParmGetStr(handle, SECT_GROBJECTS, PRM_TACHO_TEX, "rpm8000.rgb"); snprintf(buf, BUFSIZE, "drivers/%s/%d;drivers/%s;cars/%s;data/textures", car->_modName, car->_driverIndex, car->_modName, car->_carName); grFilePath = strdup(buf); curInst->texture = (ssgSimpleState*)grSsgLoadTexState(param); curInst->texture->ref(); free(grFilePath); /* Load the intrument placement */ xSz = GfParmGetNum(handle, SECT_GROBJECTS, PRM_TACHO_XSZ, (char*)NULL, 128); ySz = GfParmGetNum(handle, SECT_GROBJECTS, PRM_TACHO_YSZ, (char*)NULL, 128); xpos = GfParmGetNum(handle, SECT_GROBJECTS, PRM_TACHO_XPOS, (char*)NULL, Winw / 2.0 - xSz); ypos = GfParmGetNum(handle, SECT_GROBJECTS, PRM_TACHO_YPOS, (char*)NULL, 0); needlexSz = GfParmGetNum(handle, SECT_GROBJECTS, PRM_TACHO_NDLXSZ, (char*)NULL, 50); needleySz = GfParmGetNum(handle, SECT_GROBJECTS, PRM_TACHO_NDLYSZ, (char*)NULL, 2); curInst->needleXCenter = GfParmGetNum(handle, SECT_GROBJECTS, PRM_TACHO_XCENTER, (char*)NULL, xSz / 2.0) + xpos; curInst->needleYCenter = GfParmGetNum(handle, SECT_GROBJECTS, PRM_TACHO_YCENTER, (char*)NULL, ySz / 2.0) + ypos; curInst->digitXCenter = GfParmGetNum(handle, SECT_GROBJECTS, PRM_TACHO_XDIGITCENTER, (char*)NULL, xSz / 2.0) + xpos; curInst->digitYCenter = GfParmGetNum(handle, SECT_GROBJECTS, PRM_TACHO_YDIGITCENTER, (char*)NULL, 16) + ypos; curInst->minValue = GfParmGetNum(handle, SECT_GROBJECTS, PRM_TACHO_MINVAL, (char*)NULL, 0); curInst->maxValue = GfParmGetNum(handle, SECT_GROBJECTS, PRM_TACHO_MAXVAL, (char*)NULL, RPM2RADS(10000)) - curInst->minValue; curInst->minAngle = GfParmGetNum(handle, SECT_GROBJECTS, PRM_TACHO_MINANG, "deg", 225); curInst->maxAngle = GfParmGetNum(handle, SECT_GROBJECTS, PRM_TACHO_MAXANG, "deg", -45) - curInst->minAngle; curInst->monitored = &(car->_enginerpm); curInst->prevVal = curInst->minAngle; curInst->CounterList = glGenLists(1); glNewList(curInst->CounterList, GL_COMPILE); glBegin(GL_TRIANGLE_STRIP); { glColor4f(1.0, 1.0, 1.0, 0.0); glTexCoord2f(0.0, 0.0); glVertex2f(xpos, ypos); glTexCoord2f(0.0, 1.0); glVertex2f(xpos, ypos + ySz); glTexCoord2f(1.0, 0.0); glVertex2f(xpos + xSz, ypos); glTexCoord2f(1.0, 1.0); glVertex2f(xpos + xSz, ypos + ySz); } glEnd(); glEndList(); curInst->needleList = glGenLists(1); glNewList(curInst->needleList, GL_COMPILE); glBegin(GL_TRIANGLE_STRIP); { glColor4f(1.0, 0.0, 0.0, 1.0); glVertex2f(0, -needleySz); glVertex2f(0, needleySz); glVertex2f(needlexSz, -needleySz / 2.0); glVertex2f(needlexSz, needleySz / 2.0); } glEnd(); glEndList(); /* Speedometer */ curInst = &(carInfo->instrument[1]); /* Load the Speedometer texture */ param = GfParmGetStr(handle, SECT_GROBJECTS, PRM_SPEEDO_TEX, "speed360.rgb"); snprintf(buf, BUFSIZE, "drivers/%s/%d;drivers/%s;cars/%s;data/textures", car->_modName, car->_driverIndex, car->_modName, car->_carName); grFilePath = strdup(buf); curInst->texture = (ssgSimpleState*)grSsgLoadTexState(param); curInst->texture->ref(); free(grFilePath); /* Load the intrument placement */ xSz = GfParmGetNum(handle, SECT_GROBJECTS, PRM_SPEEDO_XSZ, (char*)NULL, 128); ySz = GfParmGetNum(handle, SECT_GROBJECTS, PRM_SPEEDO_YSZ, (char*)NULL, 128); xpos = GfParmGetNum(handle, SECT_GROBJECTS, PRM_SPEEDO_XPOS, (char*)NULL, Winw / 2.0); ypos = GfParmGetNum(handle, SECT_GROBJECTS, PRM_SPEEDO_YPOS, (char*)NULL, 0); needlexSz = GfParmGetNum(handle, SECT_GROBJECTS, PRM_SPEEDO_NDLXSZ, (char*)NULL, 50); needleySz = GfParmGetNum(handle, SECT_GROBJECTS, PRM_SPEEDO_NDLYSZ, (char*)NULL, 2); curInst->needleXCenter = GfParmGetNum(handle, SECT_GROBJECTS, PRM_SPEEDO_XCENTER, (char*)NULL, xSz / 2.0) + xpos; curInst->needleYCenter = GfParmGetNum(handle, SECT_GROBJECTS, PRM_SPEEDO_YCENTER, (char*)NULL, ySz / 2.0) + ypos; curInst->digitXCenter = GfParmGetNum(handle, SECT_GROBJECTS, PRM_SPEEDO_XDIGITCENTER, (char*)NULL, xSz / 2.0) + xpos; curInst->digitYCenter = GfParmGetNum(handle, SECT_GROBJECTS, PRM_SPEEDO_YDIGITCENTER, (char*)NULL, 10) + ypos; curInst->minValue = GfParmGetNum(handle, SECT_GROBJECTS, PRM_SPEEDO_MINVAL, (char*)NULL, 0); curInst->maxValue = GfParmGetNum(handle, SECT_GROBJECTS, PRM_SPEEDO_MAXVAL, (char*)NULL, 100) - curInst->minValue; curInst->minAngle = GfParmGetNum(handle, SECT_GROBJECTS, PRM_SPEEDO_MINANG, "deg", 225); curInst->maxAngle = GfParmGetNum(handle, SECT_GROBJECTS, PRM_SPEEDO_MAXANG, "deg", -45) - curInst->minAngle; curInst->monitored = &(car->_speed_x); curInst->prevVal = curInst->minAngle; if (strcmp(GfParmGetStr(handle, SECT_GROBJECTS, PRM_SPEEDO_DIGITAL, "yes"), "yes") == 0) { curInst->digital = 1; } curInst->CounterList = glGenLists(1); glNewList(curInst->CounterList, GL_COMPILE); glBegin(GL_TRIANGLE_STRIP); { glColor4f(1.0, 1.0, 1.0, 0.0); glTexCoord2f(0.0, 0.0); glVertex2f(xpos, ypos); glTexCoord2f(0.0, 1.0); glVertex2f(xpos, ypos + ySz); glTexCoord2f(1.0, 0.0); glVertex2f(xpos + xSz, ypos); glTexCoord2f(1.0, 1.0); glVertex2f(xpos + xSz, ypos + ySz); } glEnd(); glEndList(); curInst->needleList = glGenLists(1); glNewList(curInst->needleList, GL_COMPILE); glBegin(GL_TRIANGLE_STRIP); { glColor4f(1.0, 0.0, 0.0, 1.0); glVertex2f(0, -needleySz); glVertex2f(0, needleySz); glVertex2f(needlexSz, -needleySz / 2.0); glVertex2f(needlexSz, needleySz / 2.0); } glEnd(); glEndList(); }
int GfuiMenuCreateComboboxControl(void* hscr, void* hparm, const char* pszName, void* userData, tfuiComboboxCallback onChange) { std::string strControlPath(GFMNU_SECT_DYNAMIC_CONTROLS"/"); strControlPath += pszName; const std::string strType = GfParmGetStr(hparm, strControlPath.c_str(), GFMNU_ATTR_TYPE, ""); if (strType != GFMNU_TYPE_COMBO_BOX) { GfLogError("Failed to create control '%s' : section not found or not an '%s' \n", pszName, GFMNU_TYPE_COMBO_BOX); return -1; } int id = -1; const int x = (int)GfParmGetNum(hparm,strControlPath.c_str(), GFMNU_ATTR_X, NULL, 0.0); const int y = (int)GfParmGetNum(hparm,strControlPath.c_str(), GFMNU_ATTR_Y, NULL, 0.0); std::string strFontName = GfParmGetStr(hparm, strControlPath.c_str(), GFMNU_ATTR_FONT, ""); const int font = gfuiMenuGetFontId(strFontName.c_str()); int width = (int)GfParmGetNum(hparm,strControlPath.c_str(), GFMNU_ATTR_WIDTH, NULL, 0.0); if (width == 0) width = 200; const int nArrowsWidth = (int)GfParmGetNum(hparm, strControlPath.c_str(), GFMNU_ATTR_ARROWS_WIDTH, NULL, 0); const int nArrowsHeight = (int)GfParmGetNum(hparm, strControlPath.c_str(), GFMNU_ATTR_ARROWS_HEIGHT, NULL, 0); const char* pszText = GfParmGetStr(hparm, strControlPath.c_str(), GFMNU_ATTR_TEXT, ""); const int maxlen = (int)GfParmGetNum(hparm, strControlPath.c_str(), GFMNU_ATTR_MAX_LEN, 0, 0); const char* pszTip = GfParmGetStr(hparm, strControlPath.c_str(), GFMNU_ATTR_TIP, 0); void* userDataOnFocus = 0; tfuiCallback onFocus = 0; tfuiCallback onFocusLost = 0; if (pszTip && strlen(pszTip) > 0) { tMenuCallbackInfo * cbinfo = (tMenuCallbackInfo*)calloc(1, sizeof(tMenuCallbackInfo)); cbinfo->screen = hscr; cbinfo->labelId = GfuiTipCreate(hscr, pszTip, strlen(pszTip)); GfuiVisibilitySet(hscr, cbinfo->labelId, GFUI_INVISIBLE); userDataOnFocus = (void*)cbinfo; onFocus = onFocusShowTip; onFocusLost = onFocusLostHideTip; } const float* aColor = 0; const GfuiColor color = getControlColor(hparm, strControlPath.c_str(), GFMNU_ATTR_COLOR); if (color.alpha) aColor = color.toFloatRGBA(); const float* aFocusColor = 0; const GfuiColor focusColor = getControlColor(hparm, strControlPath.c_str(), GFMNU_ATTR_COLOR_FOCUSED); if (focusColor.alpha) aFocusColor = focusColor.toFloatRGBA(); id = GfuiComboboxCreate(hscr, font, x, y, width, nArrowsWidth, nArrowsHeight, pszText, maxlen, aColor, aFocusColor, userData, onChange, userDataOnFocus, onFocus, onFocusLost); return id; }
tdble GfuiMenuGetNumProperty(void* hparm, const char* pszName, tdble nDefVal, const char* pszUnit) { return GfParmGetNum(hparm, GFMNU_SECT_PROPERTIES, pszName, pszUnit, nDefVal); }
bool GfglFeatures::loadSupport(int &nWidth, int &nHeight, int &nDepth, bool &bAlpha, bool &bFullScreen, bool &bBump, bool &bStereo, int &nAniFilt,void* hparmConfig) { // Clear support data. _mapSupportedBool.clear(); _mapSupportedInt.clear(); // Open the config file if not already done. void* hparm = hparmConfig ? hparmConfig : openConfigFile(); // Load the frame buffer specs for the stored supported features. nWidth = (int)GfParmGetNum(hparm, GFSCR_SECT_GLDETSPECS, GFSCR_ATT_WIN_X, pszNoUnit, 0); nHeight = (int)GfParmGetNum(hparm, GFSCR_SECT_GLDETSPECS, GFSCR_ATT_WIN_Y, pszNoUnit, 0); nDepth = (int)GfParmGetNum(hparm, GFSCR_SECT_GLDETSPECS, GFSCR_ATT_BPP, pszNoUnit, 0); nAniFilt = (int)GfParmGetNum(hparm, GFSCR_SECT_GLDETSPECS, GFSCR_ATT_ANISOTROPICFILTERING, pszNoUnit, 0); bAlpha = std::string(GfParmGetStr(hparm, GFSCR_SECT_GLDETSPECS, GFSCR_ATT_ALPHACHANNEL, GFSCR_VAL_NO)) == GFSCR_VAL_YES; bFullScreen = std::string(GfParmGetStr(hparm, GFSCR_SECT_GLDETSPECS, GFSCR_ATT_FSCR, GFSCR_VAL_NO)) == GFSCR_VAL_YES; bStereo = std::string(GfParmGetStr(hparm, GFSCR_SECT_GLDETSPECS, GFSCR_ATT_STEREOVISION, GFSCR_VAL_NO)) == GFSCR_VAL_YES; bBump = std::string(GfParmGetStr(hparm, GFSCR_SECT_GLDETSPECS, GFSCR_ATT_BUMPMAPPING, GFSCR_VAL_NO)) == GFSCR_VAL_YES; // Check that we have something supported, and return if not. if (nWidth == 0 || nHeight == 0 || nDepth == 0) { GfLogTrace("No info found about best supported features for these specs ; " "will need a detection pass.\n"); // Close config file if we open it. if (!hparmConfig) closeConfigFile(hparm); return false; } // Here, we only update _mapSupportedXXX only if something relevant in the config file // If there's nothing or something not expected, it means no support. // 1) Double-buffer. const std::string strDoubleBuffer = GfParmGetStr(hparm, GFSCR_SECT_GLDETFEATURES, GFSCR_ATT_DOUBLEBUFFER, ""); if (strDoubleBuffer == GFSCR_VAL_YES) _mapSupportedBool[DoubleBuffer] = true; else if (strDoubleBuffer == GFSCR_VAL_NO) _mapSupportedBool[DoubleBuffer] = false; // 2) Color buffer depth. const int nColorDepth = (int)GfParmGetNum(hparm, GFSCR_SECT_GLDETFEATURES, GFSCR_ATT_COLORDEPTH, pszNoUnit, (tdble)0); if (nColorDepth > 0) _mapSupportedInt[ColorDepth] = nColorDepth; // 3) Alpha-channel depth. const int nAlphaDepth = (int)GfParmGetNum(hparm, GFSCR_SECT_GLDETFEATURES, GFSCR_ATT_ALPHADEPTH, pszNoUnit, (tdble)-1); if (nAlphaDepth >= 0) _mapSupportedInt[AlphaDepth] = nAlphaDepth; // 4) Max texture size. const int nMaxTexSize = (int)GfParmGetNum(hparm, GFSCR_SECT_GLDETFEATURES, GFSCR_ATT_MAXTEXTURESIZE, pszNoUnit, (tdble)0); if (nMaxTexSize > 0) _mapSupportedInt[TextureMaxSize] = nMaxTexSize; // 5) Texture compression. const std::string strTexComp = GfParmGetStr(hparm, GFSCR_SECT_GLDETFEATURES, GFSCR_ATT_TEXTURECOMPRESSION, ""); if (strTexComp == GFSCR_VAL_YES) _mapSupportedBool[TextureCompression] = true; else if (strTexComp == GFSCR_VAL_NO) _mapSupportedBool[TextureCompression] = false; // 6) Multi-texturing. const std::string strMultiTex = GfParmGetStr(hparm, GFSCR_SECT_GLDETFEATURES, GFSCR_ATT_MULTITEXTURING, ""); if (strMultiTex == GFSCR_VAL_YES) _mapSupportedBool[MultiTexturing] = true; else if (strMultiTex == GFSCR_VAL_NO) _mapSupportedBool[MultiTexturing] = false; const int nMultiTexUnits = (int)GfParmGetNum(hparm, GFSCR_SECT_GLDETFEATURES, GFSCR_ATT_MULTITEXTURINGUNITS, pszNoUnit, (tdble)0); if (nMultiTexUnits > 0) _mapSupportedInt[MultiTexturingUnits] = nMultiTexUnits; // 7) Rectangle textures). const std::string strRectTex = GfParmGetStr(hparm, GFSCR_SECT_GLDETFEATURES, GFSCR_ATT_RECTANGLETEXTURES, ""); if (strRectTex == GFSCR_VAL_YES) _mapSupportedBool[TextureRectangle] = true; else if (strRectTex == GFSCR_VAL_NO) _mapSupportedBool[TextureRectangle] = false; // 8) Non-power-of-2 textures. const std::string strNonPoTTex = GfParmGetStr(hparm, GFSCR_SECT_GLDETFEATURES, GFSCR_ATT_NONPOTTEXTURES, ""); if (strNonPoTTex == GFSCR_VAL_YES) _mapSupportedBool[TextureNonPowerOf2] = true; else if (strNonPoTTex == GFSCR_VAL_NO) _mapSupportedBool[TextureNonPowerOf2] = false; // 9) Multi-sampling. const std::string strMultiSamp = GfParmGetStr(hparm, GFSCR_SECT_GLDETFEATURES, GFSCR_ATT_MULTISAMPLING, ""); if (strMultiSamp == GFSCR_VAL_YES) _mapSupportedBool[MultiSampling] = true; else if (strMultiSamp == GFSCR_VAL_NO) _mapSupportedBool[MultiSampling] = false; const int nMultiSampSamples = (int)GfParmGetNum(hparm, GFSCR_SECT_GLDETFEATURES, GFSCR_ATT_MULTISAMPLINGSAMPLES, pszNoUnit, (tdble)0); if (nMultiSampSamples > 0) _mapSupportedInt[MultiSamplingSamples] = nMultiSampSamples; // 10) Stereo Vision const std::string strStereoVision = GfParmGetStr(hparm, GFSCR_SECT_GLDETFEATURES, GFSCR_ATT_STEREOVISION, ""); if (strStereoVision == GFSCR_VAL_YES) _mapSupportedBool[StereoVision] = true; else if (strStereoVision == GFSCR_VAL_NO) _mapSupportedBool[StereoVision] = false; // 11) Bump Mapping. const std::string strBumpMapping = GfParmGetStr(hparm, GFSCR_SECT_GLDETFEATURES, GFSCR_ATT_BUMPMAPPING, ""); if (strTexComp == GFSCR_VAL_YES) //strTexComp ? Bug ? _mapSupportedBool[BumpMapping] = true; else if (strTexComp == GFSCR_VAL_NO) _mapSupportedBool[BumpMapping] = false; // 11) Anisotropic Filtering. const int nAF = (int)GfParmGetNum(hparm, GFSCR_SECT_GLDETFEATURES, GFSCR_ATT_ANISOTROPICFILTERING, pszNoUnit, (tdble)0); if (nMaxTexSize > 0) _mapSupportedInt[AnisotropicFiltering] =nAF; // Close config file if we open it. if (!hparmConfig) closeConfigFile(hparm); // Trace best supported features. dumpSupport(); return true; }
static int createLabel(void* hscr, void* hparm, const char* pszPath, bool bFromTemplate = false, const char* text = GFUI_TPL_TEXT, int x = GFUI_TPL_X, int y = GFUI_TPL_Y, int font = GFUI_TPL_FONTID, int width = GFUI_TPL_WIDTH, int hAlign = GFUI_TPL_ALIGN, int maxlen = GFUI_TPL_MAXLEN, const float* aFgColor = GFUI_TPL_COLOR, const float* aFgFocusColor = GFUI_TPL_FOCUSCOLOR) { if (strcmp(GfParmGetStr(hparm, pszPath, GFMNU_ATTR_TYPE, ""), GFMNU_TYPE_LABEL)) { GfLogError("Failed to create label control '%s' : section not found or not a '%s'\n", pszPath, GFMNU_TYPE_LABEL); return -1; } const char* pszText = bFromTemplate && text != GFUI_TPL_TEXT ? text : GfParmGetStr(hparm, pszPath, GFMNU_ATTR_TEXT, ""); const int nX = bFromTemplate && x != GFUI_TPL_X ? x : (int)GfParmGetNum(hparm, pszPath, GFMNU_ATTR_X, NULL, 0); const int nY = bFromTemplate && y != GFUI_TPL_Y ? y : (int)GfParmGetNum(hparm, pszPath, GFMNU_ATTR_Y, NULL, 0); const int nWidth = bFromTemplate && width != GFUI_TPL_WIDTH ? width : (int)GfParmGetNum(hparm, pszPath, GFMNU_ATTR_WIDTH, NULL, 0); const int nFontId = bFromTemplate && font != GFUI_TPL_FONTID ? font : gfuiMenuGetFontId(GfParmGetStr(hparm, pszPath, GFMNU_ATTR_FONT, "")); const char* pszAlignH = GfParmGetStr(hparm, pszPath, GFMNU_ATTR_H_ALIGN, ""); //const char* pszAlignV = GfParmGetStr(hparm, pszPath, GFMNU_ATTR_V_ALIGN, ""); const int nAlign = bFromTemplate && hAlign != GFUI_TPL_ALIGN ? hAlign : gfuiMenuGetAlignment(pszAlignH); //, pszAlignV); int nMaxLen = bFromTemplate && maxlen != GFUI_TPL_MAXLEN ? maxlen : (int)GfParmGetNum(hparm, pszPath, GFMNU_ATTR_MAX_LEN, NULL, 0); GfuiColor color; const float* aColor = 0; if (bFromTemplate && aFgColor != GFUI_TPL_COLOR) aColor = aFgColor; else { color = getControlColor(hparm, pszPath, GFMNU_ATTR_COLOR); if (color.alpha) aColor = color.toFloatRGBA(); } GfuiColor focusColor; const float* aFocusColor = 0; if (bFromTemplate && aFgFocusColor != GFUI_TPL_FOCUSCOLOR) aFocusColor = aFgFocusColor; else { focusColor = getControlColor(hparm, pszPath, GFMNU_ATTR_COLOR_FOCUSED); if (focusColor.alpha) aFocusColor = focusColor.toFloatRGBA(); } void* userDataOnFocus = 0; tfuiCallback onFocus = 0; tfuiCallback onFocusLost = 0; const char* pszTip = GfParmGetStr(hparm, pszPath, GFMNU_ATTR_TIP, 0); if (pszTip && strlen(pszTip) > 0) { tMenuCallbackInfo * cbinfo = (tMenuCallbackInfo*)calloc(1, sizeof(tMenuCallbackInfo)); cbinfo->screen = hscr; cbinfo->labelId = GfuiTipCreate(hscr, pszTip, strlen(pszTip)); GfuiVisibilitySet(hscr, cbinfo->labelId, GFUI_INVISIBLE); userDataOnFocus = (void*)cbinfo; onFocus = onFocusShowTip; onFocusLost = onFocusLostHideTip; } int labelId = GfuiLabelCreate(hscr, pszText, nFontId, nX, nY, nWidth, nAlign, nMaxLen, aColor, aFocusColor, userDataOnFocus, onFocus, onFocusLost); return labelId; }
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/%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/%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/%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/%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; } } }
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/%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/%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); } } }
/* return state mode */ int ReRaceStart(void) { char path[128]; char path2[128]; const char *sessionName = ReInfo->_reRaceName; void *params = ReInfo->params; void *results = ReInfo->results; int mode = 0; // Trace race session identification (more to say for the Carer mode). char pszSessionId[128]; if (!strcmp(GfParmGetStr(ReInfo->mainParams, RM_SECT_SUBFILES, RM_ATTR_HASSUBFILES, RM_VAL_NO), RM_VAL_YES)) { const char* pszGroup = GfParmGetStr(params, RM_SECT_HEADER, RM_ATTR_NAME, "<no group>"); snprintf(pszSessionId, sizeof(pszSessionId), "%s %s %s", ReInfo->_reName, pszGroup, sessionName); } else snprintf(pszSessionId, sizeof(pszSessionId), "%s %s", ReInfo->_reName, sessionName); GfLogInfo("Starting %s session at %s\n", pszSessionId, ReInfo->track->name); // Reallocate and reset car info for the race. FREEZ(ReInfo->_reCarInfo); ReInfo->_reCarInfo = (tReCarInfo*)calloc(GfParmGetEltNb(params, RM_SECT_DRIVERS), sizeof(tReCarInfo)); ReUI().onRaceInitializing(); // Drivers starting order int nCars = GfParmGetEltNb(params, RM_SECT_DRIVERS); GfParmListClean(params, RM_SECT_DRIVERS_RACING); if (nCars == 0) { // This may happen, when playing with the text-only mode, // and forgetting that human are automatically excluded then, // or when getting back to the GUI mode, and not reconfiguring the competitors list. GfLogError("No competitor in this race : cancelled.\n"); mode = RM_ERROR; } else if ((ReInfo->s->_raceType == RM_TYPE_QUALIF || ReInfo->s->_raceType == RM_TYPE_PRACTICE) && ReInfo->s->_totTime < 0.0f /* Timed session? */) //Checks if there is only one driver per session allowed, so practice, qualification without timed session. { // non-timed Qualification or Practice session => 1 driver at a time = the "current" one. int nCurrDrvInd = (int)GfParmGetNum(results, RE_SECT_CURRENT, RE_ATTR_CUR_DRIVER, NULL, 1); if (nCurrDrvInd <= 0) return RM_ERROR; // Propagate competitor drivers info to the real race starting grid snprintf(path, sizeof(path), "%s/%d", RM_SECT_DRIVERS, ReStartingOrderIdx[nCurrDrvInd-1]); snprintf(path2, sizeof(path2), "%s/%d", RM_SECT_DRIVERS_RACING, 1); GfParmSetStr(params, path2, RM_ATTR_MODULE, GfParmGetStr(params, path, RM_ATTR_MODULE, "")); GfParmSetNum(params, path2, RM_ATTR_IDX, NULL, GfParmGetNum(params, path, RM_ATTR_IDX, NULL, 0)); GfParmSetNum(params, path2, RM_ATTR_EXTENDED, NULL, GfParmGetNum(params, path, RM_ATTR_EXTENDED, NULL, 0)); GfParmSetNum(params, path2, RM_ATTR_SKINTARGETS, NULL, GfParmGetNum(params, path, RM_ATTR_SKINTARGETS, NULL, 0)); if (GfParmGetStr(params, path, RM_ATTR_SKINNAME, 0)) GfParmSetStr(params, path2, RM_ATTR_SKINNAME, GfParmGetStr(params, path, RM_ATTR_SKINNAME, "")); } else { // For a race, add cars to the starting grid in the order stored in ReStartingOrderIdx. ReUI().addLoadingMessage("Preparing Starting Grid ..."); int maxCars = (int)GfParmGetNum(params, sessionName, RM_ATTR_MAX_DRV, NULL, 100); nCars = MIN(nCars, maxCars); int currDriver = -1; int aCars = 0; for (int i = 1; i < nCars + 1; i++) { currDriver = ReStartingOrderIdx[i-1]; if (currDriver == -1) continue; aCars++; snprintf(path, sizeof(path), "%s/%d", RM_SECT_DRIVERS, currDriver); snprintf(path2, sizeof(path2), "%s/%d", RM_SECT_DRIVERS_RACING, i); GfParmSetStr(params, path2, RM_ATTR_MODULE, GfParmGetStr(params, path, RE_ATTR_MODULE, "")); GfParmSetNum(params, path2, RM_ATTR_IDX, NULL, GfParmGetNum(params, path, RE_ATTR_IDX, NULL, 0)); GfParmSetNum(params, path2, RM_ATTR_EXTENDED, NULL, GfParmGetNum(params, path, RM_ATTR_EXTENDED, NULL, 0)); GfParmSetNum(params, path2, RM_ATTR_SKINTARGETS, NULL, GfParmGetNum(params, path, RM_ATTR_SKINTARGETS, NULL, 0)); if (GfParmGetStr(params, path, RM_ATTR_SKINNAME, 0)) GfParmSetStr(params, path2, RM_ATTR_SKINNAME, GfParmGetStr(params, path, RM_ATTR_SKINNAME, "")); } //no valid drivers present in the list if (aCars == 0) { GfLogError("No competitor in this race : cancelled.\n"); mode = RM_ERROR; } } //ReTrackUpdate(); if (!(mode & RM_ERROR)) { // According to what the UI answers, start the race right now or not. mode = RM_ASYNC | RM_NEXT_STEP; const bool bGoOn = ReUI().onRaceStarting(); if (bGoOn) mode = ReRaceRealStart(); } return mode; }
void ReUpdateStandings(void) { tReStandings st; std::string drvName; std::vector<tReStandings> *standings; std::vector<tReStandings>::iterator found; std::vector<tReStandings>::iterator it; int runDrv, curDrv; int i; void *results = ReInfo->results; snprintf(path, sizeof(path), "%s/%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, ReInfo->_reRaceName, RE_SECT_RANK); runDrv = GfParmGetEltNb(results, path); curDrv = GfParmGetEltNb(results, RE_SECT_STANDINGS); standings = new std::vector<tReStandings>; standings->reserve(curDrv); /* Read the current standings */ for (i = 0; i < curDrv; i++) { snprintf(path2, sizeof(path2), "%s/%d", RE_SECT_STANDINGS, i + 1); st.drvName = GfParmGetStr(results, path2, RE_ATTR_NAME, 0); st.modName = GfParmGetStr(results, path2, RE_ATTR_MODULE, 0); st.carName = GfParmGetStr(results, path2, RE_ATTR_CAR, 0); st.extended = (int)GfParmGetNum(results, path2, RM_ATTR_EXTENDED, NULL, 0); st.drvIdx = (int)GfParmGetNum(results, path2, RE_ATTR_IDX, NULL, 0); st.points = (int)GfParmGetNum(results, path2, RE_ATTR_POINTS, NULL, 0); standings->push_back(st); }//for i //Void the stored results GfParmListClean(results, RE_SECT_STANDINGS); //Check last races' drivers and search their name in the results. //If found there, adds recent points. //If not found, adds the driver for (i = 0; i < runDrv; i++) { //Search the driver name in the standings snprintf(path, sizeof(path), "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, ReInfo->_reRaceName, RE_SECT_RANK, i + 1); drvName = GfParmGetStr(results, path, RE_ATTR_NAME, 0); found = std::find(standings->begin(), standings->end(), drvName); if(found == standings->end()) { //No such driver in the standings, let's add it st.drvName = drvName; st.modName = GfParmGetStr(results, path, RE_ATTR_MODULE, 0); st.carName = GfParmGetStr(results, path, RE_ATTR_CAR, 0); st.extended = (int)GfParmGetNum(results, path, RM_ATTR_EXTENDED, NULL, 0); st.drvIdx = (int)GfParmGetNum(results, path, RE_ATTR_IDX, NULL, 0); st.points = (int)GfParmGetNum(results, path, RE_ATTR_POINTS, NULL, 0); standings->push_back(st); } else { //Driver found, add recent points found->points += (int)GfParmGetNum(results, path, RE_ATTR_POINTS, NULL, 0); }//if found }//for i //sort standings by score std::sort(standings->begin(), standings->end(), sortByScore); //Store the standing back for(it = standings->begin(), i = 0; it != standings->end(); ++it, ++i) { snprintf(path, sizeof(path), "%s/%d", RE_SECT_STANDINGS, i + 1); GfParmSetStr(results, path, RE_ATTR_NAME, it->drvName.c_str()); GfParmSetStr(results, path, RE_ATTR_MODULE, it->modName.c_str()); GfParmSetStr(results, path, RE_ATTR_CAR, it->carName.c_str()); GfParmSetNum(results, path, RE_ATTR_IDX, NULL, (tdble)it->drvIdx); GfParmSetNum(results, path, RE_ATTR_POINTS, NULL, (tdble)it->points); }//for it delete standings; char str1[512], str2[512]; snprintf(str1, sizeof(str1), "%sconfig/params.dtd", GfDataDir()); snprintf(str2, sizeof(str2), "<?xml-stylesheet type=\"text/xsl\" href=\"file:///%sconfig/raceresults.xsl\"?>", GfDataDir()); GfParmSetDTD (results, str1, str2); GfParmWriteFile(0, results, "Results"); }//ReUpdateStandings
int RePreRace(void) { char path[128]; const char *raceName; const char *raceType; void *params = ReInfo->params; void *results = ReInfo->results; int curRaceIdx; int timedLapsReplacement = 0; char *prevRaceName; raceName = ReInfo->_reRaceName = ReGetCurrentRaceName(); 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; } if (strcmp(GfParmGetStr(params, raceName, RM_ATTR_ENABLED, RM_VAL_YES), RM_VAL_NO) == 0) { GfLogTrace( "Race %s disabled\n", raceName); curRaceIdx = (int)GfParmGetNum(results, RE_SECT_CURRENT, RE_ATTR_CUR_RACE, NULL, 1); if (curRaceIdx < GfParmGetEltNb(params, RM_SECT_RACES)) { curRaceIdx++; GfLogTrace( "Race %s is not the last one, but the #%d\n", raceName, curRaceIdx); GfParmSetNum(results, RE_SECT_CURRENT, RE_ATTR_CUR_RACE, NULL, (tdble)curRaceIdx); return RM_SYNC | RM_NEXT_RACE; } GfParmSetNum(results, RE_SECT_CURRENT, RE_ATTR_CUR_RACE, NULL, 1); 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); // 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; } else if (!strcmp(raceType, RM_VAL_QUALIF)) { ReInfo->s->_raceType = RM_TYPE_QUALIF; } else if (!strcmp(raceType, RM_VAL_PRACTICE)) { ReInfo->s->_raceType = RM_TYPE_PRACTICE; } // 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 = 0; // Make sure it is initialized if (ReInfo->s->_totTime > 0 && !(ReInfo->s->_features & RM_FEATURE_TIMEDSESSION)) { // Timed session not supported: add 1 km for every minute in parctise or qualifying, // and 150 km for every hour (2.5 km for every minute) in race if (ReInfo->s->_raceType == RM_TYPE_RACE) { ReInfo->s->_totLaps = (int)floor(ReInfo->s->_totTime * 2500.0f / 60.0f / ReInfo->track->length + 0.5f); } else { ReInfo->s->_totLaps = (int)floor(ReInfo->s->_totTime * 1000.0f / 60.0f / ReInfo->track->length + 0.5f); } timedLapsReplacement = ReInfo->s->_totLaps; ReInfo->s->_totTime = -60.0f; } // Timed session doesn't exclude additional laps after the time finishes // Make sure that if no time set, we set far below zero if(ReInfo->s->_totTime <= 0.0f ) 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, and it is not a timed race. if ( (dist >= 0.001) && (ReInfo->s->_totTime < 0.0f) ) { // Why not 'if (dist > 0)' ??? ReInfo->s->_totLaps = (int)(dist / ReInfo->track->length) + 1; ReInfo->s->_extraLaps = ReInfo->s->_totLaps; // Extralaps are used to find out how many laps there are after the time is up in timed sessions } else {dist = -1;} // Get the number of laps (defaults to "All sessions" one, // or else the already computed one from the session distance, or 0). 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, 0); // Use lap number only when race distance is not in use. if ( (laps > 0) && (dist <= 0.0) && (timedLapsReplacement <= 0) ) { ReInfo->s->_totLaps = laps; ReInfo->s->_extraLaps = ReInfo->s->_totLaps; //Extralaps are used to find out how many laps there are after the time is up in timed sessions } // Make sure we have at least 1 lap race length. if ( (laps <= 0) && (dist <=0) && (ReInfo->s->_totTime < 0) ) { ReInfo->s->_totLaps = 1; ReInfo->s->_extraLaps = ReInfo->s->_totLaps; //Extralaps are used to find out how many laps there are after the time is up in timed sessions } // 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; //Extralaps are used to find out how many laps there are after the time is up in timed sessions ReInfo->s->_totLaps = 0; } 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 snprintf(path, sizeof(path), "%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, raceName); GfParmListClean(results, path); // Drivers starting order // The starting order is decided here, // then car indexes are stored in ReStartingOrderIdx, in the starting order. // The actual grid is assembled in ReRaceStart(). // In case of a race, when all cars start at the same time, // cars are simply added to the starting list in the order stored in ReStartingOrderIdx. // If only one car is at the track at a time (not timed session qualifying or practice), // the race is divided into many sub-races. // For a sub-race, only the results/RE_ATTR_CUR_DRIVER-th driver in ReStartingOrderIdx // is added to the starting grid. // RE_ATTR_CUR_DRIVER is refreshed after every sub-race in ReRaceEnd(). int nCars = GfParmGetEltNb(params, RM_SECT_DRIVERS); GfParmListClean(params, RM_SECT_DRIVERS_RACING); if (nCars == 0) { // This may happen, when playing with the text-only mode, // and forgetting that human are automatically excluded then, // or when getting back to the GUI mode, and not reconfiguring the competitors list. GfLogError("No competitor in this race : cancelled.\n"); return RM_ERROR; } else { ReUI().addLoadingMessage("Determining Starting Order ..."); const char* gridType = GfParmGetStr(params, raceName, RM_ATTR_START_ORDER, RM_VAL_DRV_LIST_ORDER); int maxCars = (int)GfParmGetNum(params, raceName, RM_ATTR_MAX_DRV, NULL, 100); nCars = MIN(nCars, maxCars); tReGridPart *GridList = NULL; int nGridList = 0; // Initialize the array of car indexes for starting order if (ReStartingOrderIdx != NULL) { delete[] ReStartingOrderIdx; ReStartingOrderIdx = NULL; } ReStartingOrderIdx = new int[nCars]; for (int i = 0; i < nCars; i++) { ReStartingOrderIdx[i] = -1; } // Starting grid in the arrival order of the previous race (or qualification session) if (!strcmp(gridType, RM_VAL_LAST_RACE_ORDER)) { GfLogTrace("Starting grid in the order of the last race\n"); prevRaceName = ReGetPrevRaceName(/* bLoop = */false); if (!prevRaceName) { return RM_ERROR; } for (int i = 1; i < nCars + 1; i++) { snprintf(path, sizeof(path), "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, prevRaceName, RE_SECT_RANK, i); ReStartingOrderIdx[i-1] = ReFindDriverIdx (GfParmGetStr(results, path, RE_ATTR_MODULE, ""), (int)GfParmGetNum(results, path, RE_ATTR_IDX, NULL, 0)); } } // Starting grid in the reversed arrival order of the previous race else if (!strcmp(gridType, RM_VAL_LAST_RACE_RORDER)) { GfLogTrace("Starting grid in the reverse order of the last race\n"); prevRaceName = ReGetPrevRaceName(/* bLoop = */false); if (!prevRaceName) { return RM_ERROR; } for (int i = 1; i < nCars + 1; i++) { snprintf(path, sizeof(path), "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, prevRaceName, RE_SECT_RANK, nCars - i + 1); ReStartingOrderIdx[i-1] = ReFindDriverIdx (GfParmGetStr(results, path, RE_ATTR_MODULE, ""), (int)GfParmGetNum(results, path, RE_ATTR_IDX, NULL, 0)); } } // Starting grid as a mix from the results of earlier sessions else if (ReParseStartingOrder(gridType, &GridList, nCars, nGridList)) { GfLogTrace("Starting grid as a mix from the results of earlier sessions\n"); int idx; int gridpos = 1; int carnr; const char *modulename; for (int i = 0; i < nGridList; i++) { if (gridpos > nCars) {break;} if (GridList[i].diffpos == -1) {//reversed for ( int j = GridList[i].startpos; j >= GridList[i].endpos; j--) { if (gridpos > nCars) {break;} snprintf(path, sizeof(path), "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, GridList[i].racename, RE_SECT_RANK, j); idx = (int)GfParmGetNum(results, path, RE_ATTR_IDX, NULL, 0); modulename = GfParmGetStr(results, path, RE_ATTR_MODULE, ""); carnr = ReFindDriverIdx(modulename, idx); for (int k = 0; k < gridpos-1; k++) { if ( carnr == ReStartingOrderIdx[k] ) { //oops: same car twice GfLogWarning("The same car appears twice in the advanced grid!\n"); carnr = -1; break; } } //adding car to the list if (carnr != -1) { ReStartingOrderIdx[gridpos-1] = carnr; gridpos++; } } } else if (GridList[i].diffpos == 1){//straight order for ( int j = GridList[i].startpos; j <= GridList[i].endpos; j++) { if (gridpos > nCars) {break;} snprintf(path, sizeof(path), "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, GridList[i].racename, RE_SECT_RANK, j); idx = (int)GfParmGetNum(results, path, RE_ATTR_IDX, NULL, 0); modulename = GfParmGetStr(results, path, RE_ATTR_MODULE, ""); carnr = ReFindDriverIdx(modulename, idx); for (int k = 0; k < gridpos-1; k++) { if ( carnr == ReStartingOrderIdx[k] ) { //oops: same car twice GfLogWarning("The same car appears twice in the advanced grid!\n"); carnr = -1; break; } } //adding car to the list if (carnr != -1) { ReStartingOrderIdx[gridpos-1] = carnr; gridpos++; } } } } //cleaning up memory if (nGridList > 0){delete[] GridList;} } // Starting grid in the drivers list order else { GfLogTrace("Starting grid in the order of the driver list\n"); for (int i = 1; i < nCars + 1; i++) { snprintf(path, sizeof(path), "%s/%d", RM_SECT_DRIVERS, i); ReStartingOrderIdx[i-1] = ReFindDriverIdx (GfParmGetStr(params, path, RE_ATTR_MODULE, ""), (int)GfParmGetNum(params, path, RE_ATTR_IDX, NULL, 0)); } } } GfParmSetNum(results, RE_SECT_CURRENT, RE_ATTR_CUR_DRIVER, NULL, 1.0); return RM_SYNC | RM_NEXT_STEP; }
/* returns: 0, when failed to parse; 1, when successfully parsed */ int ReParseStartingOrder(const char *StartingOrder, tReGridPart **pGridList, int nCars, int &nGridList) { char path[128]; char *tempstr; int curRaceIdx; int i, nGL; void *params = ReInfo->params; void *results = ReInfo->results; tReGridPart *GridList; //input sanity check if ((StartingOrder == NULL) || (nCars<1)){nGridList = 0; return 0;} //find the number of parts, that is the number of '[' characters nGL = 0; i = 0; while (StartingOrder[i] != '\0') { if (StartingOrder[i] == '['){nGL++;} i++; } curRaceIdx = (int)GfParmGetNum(results, RE_SECT_CURRENT, RE_ATTR_CUR_RACE, NULL, 1); // check whether it is a name of an earlier session if (nGL == 0) { for ( i = 1; i < curRaceIdx; i++ ) { snprintf(path, sizeof(path), "%s/%d", RM_SECT_RACES, i); tempstr = GfParmGetStrNC(params, path, RM_ATTR_NAME, 0); if (strcmp(tempstr, StartingOrder) == 0 ) { GridList = new tReGridPart[1]; if (GridList == NULL){return 0;} GridList[0].racename = tempstr; GridList[0].startpos = 1; GridList[0].endpos = nCars; GridList[0].diffpos = 1; nGridList = 1; *pGridList = GridList; return 1; } } //badly formatted GridList nGridList = 0; *pGridList = NULL; return 0; } // now try to parse it char *tempstr2 = new char[strlen(StartingOrder)]; int stri; int GLi = 0; GridList = new tReGridPart[nGL]; for (i = 0; i < nGL; i++) { //search for session name stri = 0; while (StartingOrder[GLi] != '[') { tempstr2[stri] = StartingOrder[GLi]; stri++; GLi++; } tempstr2[stri] = '\0'; GLi++; GridList[i].racename = NULL; for ( int j = 1; j < curRaceIdx; j++ ) { snprintf(path, sizeof(path), "%s/%d", RM_SECT_RACES, j); tempstr = GfParmGetStrNC(params, path, RM_ATTR_NAME, 0); if (strcmp(tempstr, tempstr2) == 0 ) { GridList[i].racename = tempstr; break; } } if (GridList[i].racename == NULL) { // failed to find session nGridList = 0; delete[] GridList; delete[] tempstr2; *pGridList = NULL; return 0; } //find indexes stri = 0; while (StartingOrder[GLi] != ']') { tempstr2[stri] = StartingOrder[GLi]; stri++; GLi++; } tempstr2[stri] = '\0'; GLi++; GridList[i].startpos = GridList[i].endpos = -1; sscanf(tempstr2, "%d:%d", &(GridList[i].startpos), &(GridList[i].endpos)); if (GridList[i].startpos <= 0) { nGridList = 0; delete[] GridList; delete[] tempstr2; *pGridList = NULL; return 0; } else if (GridList[i].endpos <= 0) { GridList[i].endpos = GridList[i].startpos; } if (GridList[i].endpos < GridList[i].startpos) {GridList[i].diffpos = -1;} else {GridList[i].diffpos = 1;} } delete[] tempstr2; nGridList = nGL; *pGridList = GridList; return 1; }
int ReRaceEventShutdown(void) { char buf[64]; int curTrkIdx; void *params = ReInfo->params; int nbTrk; void *results = ReInfo->results; int curRaceIdx; bool careerMode = false; bool first = true; // Notify the UI that the race event is finishing now. ReUI().onRaceEventFinishing(); // Shutdown track-physics-related stuff. ReTrackShutdown(); // Determine the track of the next event to come, if not the last one // and, if Career mode, prepare race params / results for the next event or season. do { nbTrk = GfParmGetEltNb(params, RM_SECT_TRACKS); curRaceIdx =(int)GfParmGetNum(results, RE_SECT_CURRENT, RE_ATTR_CUR_RACE, NULL, 1); curTrkIdx = (int)GfParmGetNum(results, RE_SECT_CURRENT, RE_ATTR_CUR_TRACK, NULL, 1); if (curRaceIdx == 1) { if (curTrkIdx < nbTrk) { // Next track. curTrkIdx++; } else if (curTrkIdx >= nbTrk) { // Back to the beginning. curTrkIdx = 1; } } GfParmSetNum(results, RE_SECT_CURRENT, RE_ATTR_CUR_TRACK, NULL, (tdble)curTrkIdx); // Career mode. if (!strcmp(GfParmGetStr(ReInfo->mainParams, RM_SECT_SUBFILES, RM_ATTR_HASSUBFILES, RM_VAL_NO), RM_VAL_YES)) { careerMode = true; const bool lastRaceOfRound = strcmp(GfParmGetStr(params, RM_SECT_SUBFILES, RM_ATTR_LASTSUBFILE, RM_VAL_YES), RM_VAL_YES) == 0; // Previous file <= Current file. GfParmSetStr(ReInfo->mainResults, RE_SECT_CURRENT, RE_ATTR_PREV_FILE, GfParmGetStr(ReInfo->mainResults, RE_SECT_CURRENT, RE_ATTR_CUR_FILE, "")); // Current file <= Next file. GfParmSetStr(ReInfo->mainResults, RE_SECT_CURRENT, RE_ATTR_CUR_FILE, GfParmGetStr(params, RM_SECT_SUBFILES, RM_ATTR_NEXTSUBFILE, "")); GfParmWriteFile(NULL, ReInfo->mainResults, NULL); /* Check if the next competition has a free weekend */ if( !first ) { /* Close old params */ GfParmWriteFile( NULL, results, NULL ); GfParmReleaseHandle( results ); GfParmReleaseHandle( params ); }//if !first /* Open params of next race */ params = GfParmReadFile( GfParmGetStr(ReInfo->mainResults, RE_SECT_CURRENT, RE_ATTR_CUR_FILE, "" ), GFPARM_RMODE_STD ); if( !params ) break; results = GfParmReadFile( GfParmGetStr(params, RM_SECT_SUBFILES, RM_ATTR_RESULTSUBFILE, ""), GFPARM_RMODE_STD ); if( !results ) { GfParmReleaseHandle( results ); break; } if (lastRaceOfRound && curTrkIdx == 1) { ReCareerNextSeason(); } if ((int)GfParmGetNum(results, RE_SECT_CURRENT, RE_ATTR_CUR_TRACK, NULL, 1) == 1) { GfParmListClean(results, RE_SECT_STANDINGS); GfParmWriteFile(NULL, results, NULL); } /* Check if it is free */ snprintf( buf, sizeof(buf), "%s/%d", RM_SECT_TRACKS, (int)GfParmGetNum(results, RE_SECT_CURRENT, RE_ATTR_CUR_TRACK, NULL, 1) ); if( !strcmp(GfParmGetStr(params, buf, RM_ATTR_NAME, "free"), "free") == 0) { /* Not a free weekend */ GfParmReleaseHandle( results ); GfParmReleaseHandle( params ); break; } first = false; } else { // Normal mode (no subfiles, so free weekends possible, so nothing to check) break; } } while( true ); // Determine new race state automaton mode. int mode = (curTrkIdx != 1 || careerMode) ? RM_NEXT_RACE : RM_NEXT_STEP; bool careerNonHumanGroup = careerMode && !ReHumanInGroup(); mode |= ReUI().onRaceEventFinished(nbTrk != 1, careerNonHumanGroup) ? RM_SYNC : RM_ASYNC;; if (mode & RM_NEXT_STEP) FREEZ(ReInfo->_reCarInfo); NoCleanupNeeded = true; return mode; }
static void reConfigRunState(void) { int i; const char* opt; const char* conf; int curConf; int numOpt; void *params = ReInfo->params; curConf = (int)GfParmGetNum(params, RM_SECT_CONF, RM_ATTR_CUR_CONF, NULL, 1); if (curConf > GfParmGetEltNb(params, RM_SECT_CONF)) { GfOut("End of configuration\n"); GfParmWriteFile(NULL, ReInfo->params, ReInfo->_reName); goto menuback; } sprintf(path, "%s/%d", RM_SECT_CONF, curConf); conf = GfParmGetStr(params, path, RM_ATTR_TYPE, 0); if (!conf) { GfOut("no %s here %s\n", RM_ATTR_TYPE, path); goto menuback; } GfOut("Configuration step %s\n", conf); if (!strcmp(conf, RM_VAL_TRACKSEL)) { /* Track Select Menu */ ts.nextScreen = reConfigHookInit(); if (curConf == 1) { ts.prevScreen = racemanMenuHdle; } else { ts.prevScreen = reConfigBackHookInit(); } ts.param = ReInfo->params; ts.trackItf = ReInfo->_reTrackItf; RmTrackSelect(&ts); } else if (!strcmp(conf, RM_VAL_DRVSEL)) { /* Drivers select menu */ ds.nextScreen = reConfigHookInit(); if (curConf == 1) { ds.prevScreen = racemanMenuHdle; } else { ds.prevScreen = reConfigBackHookInit(); } ds.param = ReInfo->params; RmDriversSelect(&ds); } else if (!strcmp(conf, RM_VAL_RACECONF)) { /* Race Options menu */ rp.nextScreen = reConfigHookInit(); if (curConf == 1) { rp.prevScreen = racemanMenuHdle; } else { rp.prevScreen = reConfigBackHookInit(); } rp.param = ReInfo->params; rp.title = GfParmGetStr(params, path, RM_ATTR_RACE, "Race"); /* Select options to configure */ rp.confMask = 0; sprintf(path, "%s/%d/%s", RM_SECT_CONF, curConf, RM_SECT_OPTIONS); numOpt = GfParmGetEltNb(params, path); for (i = 1; i < numOpt + 1; i++) { sprintf(path, "%s/%d/%s/%d", RM_SECT_CONF, curConf, RM_SECT_OPTIONS, i); opt = GfParmGetStr(params, path, RM_ATTR_TYPE, ""); if (!strcmp(opt, RM_VAL_CONFRACELEN)) { /* Configure race length */ rp.confMask |= RM_CONF_RACE_LEN; } else { if (!strcmp(opt, RM_VAL_CONFDISPMODE)) { /* Configure display mode */ rp.confMask |= RM_CONF_DISP_MODE; } } } RmRaceParamMenu(&rp); } curConf++; GfParmSetNum(params, RM_SECT_CONF, RM_ATTR_CUR_CONF, NULL, curConf); return; /* Back to the race menu */ menuback: GfuiScreenActivate(racemanMenuHdle); return; }
int initView(int x, int y, int width, int height, int /* flag */, void *screen) { int i; if (maxTextureUnits==0) { InitMultiTex(); } grWinx = x; grWiny = y; grWinw = width; grWinh = height; grMouseRatioX = width / 640.0; grMouseRatioY = height / 480.0; OldTime = GfTimeClock(); nFrame = 0; grFps = 0; sprintf(buf, "%s%s", GetLocalDir(), GR_PARAM_FILE); grHandle = GfParmReadFile(buf, GFPARM_RMODE_STD | GFPARM_RMODE_CREAT); for (i = 0; i < GR_NB_MAX_SCREEN; i++) { grScreens[i]->initBoard (); } GfuiAddSKey(screen, GLUT_KEY_HOME, "Zoom Maximum", (void*)GR_ZOOM_MAX, grSetZoom, NULL); GfuiAddSKey(screen, GLUT_KEY_END, "Zoom Minimum", (void*)GR_ZOOM_MIN, grSetZoom, NULL); GfuiAddKey(screen, '*', "Zoom Default", (void*)GR_ZOOM_DFLT, grSetZoom, NULL); GfuiAddSKey(screen, GLUT_KEY_PAGE_UP, "Select Previous Car", (void*)0, grPrevCar, NULL); GfuiAddSKey(screen, GLUT_KEY_PAGE_DOWN, "Select Next Car", (void*)0, grNextCar, NULL); GfuiAddSKey(screen, GLUT_KEY_F2, "Driver Views", (void*)0, grSelectCamera, NULL); GfuiAddSKey(screen, GLUT_KEY_F3, "Car Views", (void*)1, grSelectCamera, NULL); GfuiAddSKey(screen, GLUT_KEY_F4, "Side Car Views", (void*)2, grSelectCamera, NULL); GfuiAddSKey(screen, GLUT_KEY_F5, "Up Car View", (void*)3, grSelectCamera, NULL); GfuiAddSKey(screen, GLUT_KEY_F6, "Persp Car View", (void*)4, grSelectCamera, NULL); GfuiAddSKey(screen, GLUT_KEY_F7, "All Circuit Views", (void*)5, grSelectCamera, NULL); GfuiAddSKey(screen, GLUT_KEY_F8, "Track View", (void*)6, grSelectCamera, NULL); GfuiAddSKey(screen, GLUT_KEY_F9, "Track View Zoomed", (void*)7, grSelectCamera, NULL); GfuiAddSKey(screen, GLUT_KEY_F10, "Follow Car Zoomed", (void*)8, grSelectCamera, NULL); GfuiAddSKey(screen, GLUT_KEY_F11, "TV Director View", (void*)9, grSelectCamera, NULL); GfuiAddKey(screen, '5', "FPS Counter", (void*)3, grSelectBoard, NULL); GfuiAddKey(screen, '4', "G/Cmd Graph", (void*)4, grSelectBoard, NULL); GfuiAddKey(screen, '3', "Leaders Board", (void*)2, grSelectBoard, NULL); GfuiAddKey(screen, '2', "Driver Counters", (void*)1, grSelectBoard, NULL); GfuiAddKey(screen, '1', "Driver Board", (void*)0, grSelectBoard, NULL); GfuiAddKey(screen, '9', "Mirror", (void*)0, grSwitchMirror, NULL); GfuiAddKey(screen, '0', "Arcade Board", (void*)5, grSelectBoard, NULL); GfuiAddKey(screen, '>', "Zoom In", (void*)GR_ZOOM_IN, grSetZoom, NULL); GfuiAddKey(screen, '<', "Zoom Out", (void*)GR_ZOOM_OUT, grSetZoom, NULL); GfuiAddKey(screen, '[', "Split Screen", (void*)GR_SPLIT_ADD, grSplitScreen, NULL); GfuiAddKey(screen, ']', "UnSplit Screen", (void*)GR_SPLIT_REM, grSplitScreen, NULL); GfuiAddKey(screen, 'm', "Track Maps", (void*)0, grSelectTrackMap, NULL); grAdaptScreenSize(); grInitScene(); grLodFactorValue = GfParmGetNum(grHandle, GR_SCT_GRAPHIC, GR_ATT_LODFACTOR, NULL, 1.0); return 0; }
// Read OpenGL configuration. static void readOpenGLCfg(void) { int i; const int BUFSIZE = 1024; char buf[BUFSIZE]; snprintf(buf, BUFSIZE, "%s%s", GetLocalDir(), GR_PARAM_FILE); void *paramHandle = GfParmReadFile(buf, GFPARM_RMODE_REREAD | GFPARM_RMODE_CREAT); // Read texture compression parameters. const char *optionName = GfParmGetStr(paramHandle, GR_SCT_GLFEATURES, GR_ATT_TEXTURECOMPRESSION, textureCompressOptionList[0]); for (i = 0; i < nbOptionsTextComp; i++) { if (strcmp(optionName, textureCompressOptionList[i]) == 0) { curOptionTextComp = i; break; } } if (isCompressARBAvailable()) { GfuiLabelSetText(scrHandle, TextureCompressOptionId, textureCompressOptionList[curOptionTextComp]); } // Read texture sizing parameters. int maxsizenb = 0; int sizelimit = getGLTextureMaxSize(); int tsize = (int) GfParmGetNum(paramHandle, GR_SCT_GLFEATURES, GR_ATT_TEXTURESIZE, (char*)NULL, (tdble) sizelimit); bool found = false; for (i = 0; i < nbOptionsTextSize; i++) { if (textureSizeOptionList[i] <= sizelimit) { maxsizenb = i; } else { break; } } // Limit to available sizes. nbOptionsTextSize = maxsizenb+1; for (i = 0; i < nbOptionsTextSize; i++) { if (textureSizeOptionList[i] == tsize) { curOptionTextSize = i; found = true; break; } } if (!found) { // Should never come here if there is no bug in OpenGL. tsize = defaultTextSize; for (i = 0; i < nbOptionsTextSize; i++) { if (textureSizeOptionList[i] == tsize) { curOptionTextSize = i; break; } } } snprintf(buf, BUFSIZE, "%d", textureSizeOptionList[curOptionTextSize]); GfuiLabelSetText(scrHandle, TextureSizeOptionId, buf); GfParmReleaseHandle(paramHandle); }
int initCars(tSituation *s) { char idx[16]; int index; int i; tCarElt *elt; void *hdle; TRACE_GL("initCars: start"); sprintf(buf, "%s%s", GetLocalDir(), GR_PARAM_FILE); grHandle = GfParmReadFile(buf, GFPARM_RMODE_STD | GFPARM_RMODE_CREAT); grInitCommonState(); grInitCarlight(s->_ncars); grMaxDammage = (tdble)s->_maxDammage; grNbCars = s->_ncars; grCustomizePits(); grCarInfo = (tgrCarInfo*)calloc(s->_ncars, sizeof(tgrCarInfo)); for (i = 0; i < s->_ncars; i++) { elt = s->cars[i]; /* Shadow init (Should be done before the cars for display order) */ grInitShadow(elt); /* Skidmarks init */ grInitSkidmarks(elt); } grNbScreen = 0; for (i = 0; i < s->_ncars; i++) { elt = s->cars[i]; index = elt->index; hdle = elt->_paramsHandle; sprintf(idx, "Robots/index/%d", elt->_driverIndex); grCarInfo[index].iconColor[0] = GfParmGetNum(hdle, idx, "red", (char*)NULL, 0); grCarInfo[index].iconColor[1] = GfParmGetNum(hdle, idx, "green", (char*)NULL, 0); grCarInfo[index].iconColor[2] = GfParmGetNum(hdle, idx, "blue", (char*)NULL, 0); grCarInfo[index].iconColor[3] = 1.0; grInitCar(elt); if ((elt->_driverType == RM_DRV_HUMAN) && (grNbScreen < GR_NB_MAX_SCREEN)) { grScreens[grNbScreen]->setCurrentCar(elt); grNbScreen++; } } if (grNbScreen == 0) { grNbScreen = (int)GfParmGetNum(grHandle, GR_SCT_DISPMODE, GR_ATT_NB_SCREENS, NULL, 1.0); } for (i = 0; i < GR_NB_MAX_SCREEN; i++) { grScreens[i]->initCams(s); } TRACE_GL("initCars: end"); grInitSmoke(s->_ncars); grInitSound(s, s->_ncars); grAdaptScreenSize(); return 0; }
// Load the selected OpenGL features from the config file. void GfglFeatures::loadSelection(void* hparmConfig) { // Open the config file if not already done. void* hparm = hparmConfig ? hparmConfig : openConfigFile(); // Select the OpenGL features according to the user settings (when relevant) // or/and to the supported values (by default, select the max supported values). // 1) Double-buffer : not user-customizable. _mapSelectedBool[DoubleBuffer] = isSupported(DoubleBuffer); // 2) Color buffer depth : not user-customizable. _mapSelectedInt[ColorDepth] = getSupported(ColorDepth); // 3) Alpha-channel depth : not user-customizable. _mapSelectedInt[AlphaDepth] = getSupported(AlphaDepth); // 4) Max texture size : load from config file. _mapSelectedInt[TextureMaxSize] = (int)GfParmGetNum(hparm, GFSCR_SECT_GLSELFEATURES, GFSCR_ATT_MAXTEXTURESIZE, pszNoUnit, (tdble)getSupported(TextureMaxSize)); if (_mapSelectedInt[TextureMaxSize] > getSupported(TextureMaxSize)) _mapSelectedInt[TextureMaxSize] = getSupported(TextureMaxSize); // 5) Texture compression : load from config file. _mapSelectedBool[TextureCompression] = isSupported(TextureCompression) && std::string(GfParmGetStr(hparm, GFSCR_SECT_GLSELFEATURES, GFSCR_ATT_TEXTURECOMPRESSION, GFSCR_ATT_TEXTURECOMPRESSION_ENABLED)) == GFSCR_ATT_TEXTURECOMPRESSION_ENABLED; // 6) Multi-texturing : load from config file. _mapSelectedBool[MultiTexturing] = isSupported(MultiTexturing) && std::string(GfParmGetStr(hparm, GFSCR_SECT_GLSELFEATURES, GFSCR_ATT_MULTITEXTURING, GFSCR_ATT_MULTITEXTURING_ENABLED)) == GFSCR_ATT_MULTITEXTURING_ENABLED; _mapSelectedInt[MultiTexturingUnits] = (int)GfParmGetNum(hparm, GFSCR_SECT_GLSELFEATURES, GFSCR_ATT_MULTITEXTURINGUNITS, pszNoUnit, (tdble)getSupported(TextureMaxSize)); if (_mapSelectedInt[MultiTexturingUnits] > getSupported(MultiTexturingUnits)) _mapSelectedInt[MultiTexturingUnits] = getSupported(MultiTexturingUnits); // 7) Rectangle textures : not user-customizable. _mapSelectedBool[TextureRectangle] = isSupported(TextureRectangle); // 8) Non-power-of-2 textures : not user-customizable. _mapSelectedBool[TextureNonPowerOf2] = isSupported(TextureNonPowerOf2); // 9) Multi-sampling : load from config file. const std::string strMultiSamp = GfParmGetStr(hparm, GFSCR_SECT_GLSELFEATURES, GFSCR_ATT_MULTISAMPLING, GFSCR_ATT_MULTISAMPLING_ENABLED); _mapSelectedBool[MultiSampling] = isSupported(MultiSampling) && std::string(GfParmGetStr(hparm, GFSCR_SECT_GLSELFEATURES, GFSCR_ATT_MULTISAMPLING, GFSCR_ATT_MULTISAMPLING_ENABLED)) == GFSCR_ATT_MULTISAMPLING_ENABLED; _mapSelectedInt[MultiSamplingSamples] = (int)GfParmGetNum(hparm, GFSCR_SECT_GLSELFEATURES, GFSCR_ATT_MULTISAMPLINGSAMPLES, pszNoUnit, (tdble)8); // Good but reasonable value. if (_mapSelectedInt[MultiSamplingSamples] > getSupported(MultiSamplingSamples)) _mapSelectedInt[MultiSamplingSamples] = getSupported(MultiSamplingSamples); // 10) Stereo Vision : load from config file. const std::string strStereoVision = GfParmGetStr(hparm, GFSCR_SECT_GLSELFEATURES, GFSCR_ATT_STEREOVISION, GFSCR_ATT_STEREOVISION_ENABLED); _mapSelectedBool[StereoVision] = isSupported(StereoVision) && std::string(GfParmGetStr(hparm, GFSCR_SECT_GLSELFEATURES, GFSCR_ATT_STEREOVISION, GFSCR_ATT_STEREOVISION_ENABLED)) == GFSCR_ATT_STEREOVISION_ENABLED; // 11) Bump Mapping : load from config file. _mapSelectedBool[BumpMapping] = isSupported(BumpMapping) && std::string(GfParmGetStr(hparm, GFSCR_SECT_GLSELFEATURES, GFSCR_ATT_BUMPMAPPING, GFSCR_ATT_BUMPMAPPING_ENABLED)) == GFSCR_ATT_BUMPMAPPING_ENABLED; // 12) Anisotropic Filtering : load from config file. _mapSelectedInt[AnisotropicFiltering] = (int)GfParmGetNum(hparm, GFSCR_SECT_GLSELFEATURES, GFSCR_ATT_ANISOTROPICFILTERING, pszNoUnit, (tdble)getSupported(AnisotropicFiltering)); // Close config file if we open it. if (!hparmConfig) closeConfigFile(hparm); // Display what we have really selected (after checking / fixing to supported values). dumpSelection(); }
// Constructor TGeneticParameter::TGeneticParameter ( void* MetaDataFile, float MinDef, float ValDef, float MaxDef, const char *LabelName, const char *SectionName, const char *ParameterName, const char *UnitName, float ParamWeight, float ParamScale, float ParamRound, bool TwoSided ) { Handle = MetaDataFile; Active = true; if (LabelName) Label = strdup(LabelName); else Label = NULL; if (SectionName) Section = strdup(SectionName); else Section = NULL; if (ParameterName) Parameter = strdup(ParameterName); else Parameter = NULL; if (UnitName) Unit = strdup(UnitName); else Unit = NULL; Min = GfParmGetNumMin(Handle, Section, Parameter, Unit, MinDef); Max = GfParmGetNumMax(Handle, Section, Parameter, Unit, MaxDef); Def = ValDef; Val = GfParmGetNum(Handle, Section, Parameter, Unit, Def); Weight = ParamWeight; Range = Max - Min; Scale = ParamScale; Round = ParamRound; Tries = 0; Changed = 0; Selected = false; if (Range < 0.000001) { Min = MinDef; Max = MaxDef; Range = Max - Min; } LeftRight = TwoSided; };
static int createTextButton(void* hscr, void* hparm, const char* pszPath, void* userDataOnPush, tfuiCallback onPush, void* userDataOnFocus, tfuiCallback onFocus, tfuiCallback onFocusLost, bool bFromTemplate = false, const char* text = GFUI_TPL_TEXT, const char* tip = GFUI_TPL_TIP, int x = GFUI_TPL_X, int y = GFUI_TPL_Y, int width = GFUI_TPL_WIDTH, int font = GFUI_TPL_FONTID, int textHAlign = GFUI_TPL_ALIGN, const float* aFgColor = GFUI_TPL_COLOR, const float* aFgFocusColor = GFUI_TPL_FOCUSCOLOR, const float* aFgPushedColor = GFUI_TPL_PUSHEDCOLOR) { if (strcmp(GfParmGetStr(hparm, pszPath, GFMNU_ATTR_TYPE, ""), GFMNU_TYPE_TEXT_BUTTON)) { GfLogError("Failed to create text button control '%s' : section not found or not a '%s'\n", pszPath, GFMNU_TYPE_TEXT_BUTTON); return -1; } const char* pszText = bFromTemplate && text != GFUI_TPL_TEXT ? text : GfParmGetStr(hparm, pszPath, GFMNU_ATTR_TEXT, ""); const char* pszTip = bFromTemplate && tip != GFUI_TPL_TIP ? tip : GfParmGetStr(hparm, pszPath, GFMNU_ATTR_TIP, ""); const int nX = bFromTemplate && x != GFUI_TPL_X ? x : (int)GfParmGetNum(hparm, pszPath, GFMNU_ATTR_X, NULL, 0); const int nY = bFromTemplate && y != GFUI_TPL_Y ? y : (int)GfParmGetNum(hparm, pszPath, GFMNU_ATTR_Y, NULL, 0); int nWidth = bFromTemplate && width != GFUI_TPL_WIDTH ? width : (int)GfParmGetNum(hparm, pszPath, GFMNU_ATTR_WIDTH, NULL, 0); if (nWidth <= 0) nWidth = GFUI_BTNSZ; // TODO: Get default from screen.xml const int nFontId = bFromTemplate && font != GFUI_TPL_FONTID ? font : gfuiMenuGetFontId(GfParmGetStr(hparm, pszPath, GFMNU_ATTR_FONT, "")); const char* pszAlignH = GfParmGetStr(hparm, pszPath, GFMNU_ATTR_H_ALIGN, ""); //const char* pszAlignV = GfParmGetStr(hparm, pszPath, GFMNU_ATTR_V_ALIGN, ""); const int nAlign = bFromTemplate && textHAlign != GFUI_TPL_ALIGN ? textHAlign : gfuiMenuGetAlignment(pszAlignH); //, pszAlignV); GfuiColor color; const float* aColor = 0; if (bFromTemplate && aFgColor != GFUI_TPL_COLOR) aColor = aFgColor; else { color = getControlColor(hparm, pszPath, GFMNU_ATTR_COLOR); if (color.alpha) aColor = color.toFloatRGBA(); } GfuiColor focusColor; const float* aFocusColor = 0; if (bFromTemplate && aFgFocusColor != GFUI_TPL_FOCUSCOLOR) aFocusColor = aFgFocusColor; else { focusColor = getControlColor(hparm, pszPath, GFMNU_ATTR_COLOR_FOCUSED); if (focusColor.alpha) aFocusColor = focusColor.toFloatRGBA(); } GfuiColor pushedColor; const float* aPushedColor = 0; if (bFromTemplate && aFgPushedColor != GFUI_TPL_PUSHEDCOLOR) aPushedColor = aFgPushedColor; else { pushedColor = getControlColor(hparm, pszPath, GFMNU_ATTR_COLOR_PUSHED); if (pushedColor.alpha) aPushedColor = pushedColor.toFloatRGBA(); } if (pszTip && strlen(pszTip) > 0) { tMenuCallbackInfo * cbinfo = (tMenuCallbackInfo*)calloc(1, sizeof(tMenuCallbackInfo)); cbinfo->screen = hscr; cbinfo->labelId = GfuiTipCreate(hscr, pszTip, strlen(pszTip)); GfuiVisibilitySet(hscr, cbinfo->labelId, GFUI_INVISIBLE); // TODO: In this case, we crudely overwrite onFocus/onFocusLost ! userDataOnFocus = (void*)cbinfo; onFocus = onFocusShowTip; onFocusLost = onFocusLostHideTip; } const bool bShowbox = getControlBoolean(hparm, pszPath, GFMNU_ATTR_BOX_SHOW, true); const char* pszDisabledImage = GfParmGetStr(hparm, pszPath, GFMNU_ATTR_IMAGE_DISABLED, 0); const char* pszEnabledImage = GfParmGetStr(hparm, pszPath, GFMNU_ATTR_IMAGE_ENABLED, 0); const char* pszFocusedImage = GfParmGetStr(hparm, pszPath, GFMNU_ATTR_IMAGE_FOCUSED, 0); const char* pszPushedImage = GfParmGetStr(hparm, pszPath, GFMNU_ATTR_IMAGE_PUSHED, 0); const int imgX = (int)GfParmGetNum(hparm, pszPath, GFMNU_ATTR_IMAGE_X, NULL, 0.0); const int imgY = (int)GfParmGetNum(hparm, pszPath, GFMNU_ATTR_IMAGE_Y, NULL, 0.0); const int imgWidth = (int)GfParmGetNum(hparm, pszPath, GFMNU_ATTR_IMAGE_WIDTH, NULL, 20.0); const int imgHeight = (int)GfParmGetNum(hparm, pszPath, GFMNU_ATTR_IMAGE_HEIGHT, NULL, 20.0); int butId = GfuiButtonCreate(hscr, pszText, nFontId, nX, nY, nWidth, nAlign, GFUI_MOUSE_UP, userDataOnPush, onPush, userDataOnFocus, onFocus, onFocusLost); GfuiButtonShowBox(hscr, butId, bShowbox); if (pszDisabledImage || pszEnabledImage || pszFocusedImage || pszPushedImage) GfuiButtonSetImage(hscr, butId, imgX, imgY, imgWidth, imgHeight, pszDisabledImage, pszEnabledImage, pszFocusedImage, pszPushedImage); GfuiButtonSetColors(hscr, butId, GfuiColor::build(aColor), GfuiColor::build(aFocusColor), GfuiColor::build(aPushedColor)); return butId; }
int main (int argc, char **argv) { FILE *fin; void *param; char buf[1024]; char path[1024]; char *s; char *end; int i; int idx; int vald; tdble valf; init_args (argc, argv); fin = fopen (infile, "rb"); if (!fin) { perror (infile); exit (1); } if (catfile) { param = GfParmReadFile (catfile, GFPARM_RMODE_STD); } else { param = GfParmReadFile (outfile, GFPARM_RMODE_STD | GFPARM_RMODE_CREAT); GfParmClean(param); } /* Main parser */ while (fgets (buf, sizeof (buf), fin)) { s = strrchr (buf, '('); if (!s) { printf ("Syntax error: \"%s\"\n", buf); exit (1); } idx = strtol (s + 1, NULL, 0); switch (idx) { case 2: /* mass [kg] */ if (!fgets (buf, sizeof (buf), fin)) { exit (1); } sscanf (buf, "%f", &valf); GfParmSetNum (param, "Car", "mass", "kg", valf); break; case 4: /* gear shift delay (ticks) */ if (!fgets (buf, sizeof (buf), fin)) { exit (1); } sscanf (buf, "%d", &vald); valf = 0.025f * (tdble)vald; GfParmSetNum (param, "Gearbox", "shift time", "s", valf); break; case 8: /* gear ratios (size 8) */ if (!fgets (buf, sizeof (buf), fin)) { exit (1); } s = buf; i = 0; while (s) { end = strchr (s, ','); if (end) { *end = 0; end++; } sscanf (s, "%f", &valf); if (i == 0) { valf = -valf; } else if (i == 1) { i++; s = end; continue; } sprintf (path, "Gearbox/gears/%s", gears [i++]); GfParmSetNum (param, path, "ratio", NULL, valf); s = end; } break; case 9: /* gear efficiency (size 8) */ if (!fgets (buf, sizeof (buf), fin)) { exit (1); } s = buf; i = 0; while (s) { end = strchr (s, ','); if (end) { *end = 0; end++; } sscanf (s, "%f", &valf); sprintf (path, "Gearbox/gears/%s", gears [i++]); GfParmSetNum (param, path, "efficiency", NULL, valf); s = end; } break; case 10: /* torque curve (size 21) in 500 rpm increments */ if (!fgets (buf, sizeof (buf), fin)) { exit (1); } s = buf; i = 0; while (s) { end = strchr (s, ','); if (end) { *end = 0; end++; } sscanf (s, "%f", &valf); sprintf (path, "Engine/data points/%d", i + 1); GfParmSetNum (param, path, "rpm", "rpm", 500.0f * i); GfParmSetNum (param, path, "Tq", "N.m", valf); s = end; i++; } break; case 11: /* final gear */ if (!fgets (buf, sizeof (buf), fin)) { exit (1); } sscanf (buf, "%f", &valf); GfParmSetNum (param, "Rear Differential", "ratio", NULL, valf); break; case 12: /* engine minimum rpm */ if (!fgets (buf, sizeof (buf), fin)) { exit (1); } sscanf (buf, "%d", &vald); valf = (tdble)vald; GfParmSetNum (param, "Engine", "tickover", "rpm", valf); break; case 13: /* engine redline in rpm */ if (!fgets (buf, sizeof (buf), fin)) { exit (1); } sscanf (buf, "%d", &vald); valf = (tdble)vald; GfParmSetNum (param, "Engine", "revs limiter", "rpm", valf); GfParmSetNum (param, "Engine", "revs maxi", "rpm", valf + 1000.0f); break; case 16: /* front drive ratio */ if (!fgets (buf, sizeof (buf), fin)) { exit (1); } sscanf (buf, "%f", &valf); if (valf != 0) { if (valf == 1.0) { GfParmSetStr (param, "Drivetrain", "type", "FWD"); GfParmSetStr (param, "Rear Differential", "type", "NONE"); GfParmSetStr (param, "Front Differential", "type", "FREE"); GfParmSetNum (param, "Front Differential", "ratio", NULL, valf); } else { GfParmSetStr (param, "Drivetrain", "type", "4WD"); GfParmSetStr (param, "Front Differential", "type", "FREE"); GfParmSetStr (param, "Central Differential", "type", "VISCOUS COUPLER"); GfParmSetNum (param, "Central Differential", "min torque bias", NULL, MAX (valf - 1.0f, 0.1f)); GfParmSetNum (param, "Central Differential", "max torque bias", NULL, MIN (valf + 1.0f, 0.9f)); valf = GfParmGetNum (param, "Rear Differential", "ratio", NULL, 3.5); GfParmSetNum (param, "Central Differential", "ratio", NULL, valf); GfParmSetNum (param, "Rear Differential", "ratio", NULL, 1.0); GfParmSetNum (param, "Front Differential", "ratio", NULL, 1.0); } } break; case 19: /* front bias brake ratio */ if (!fgets (buf, sizeof (buf), fin)) { exit (1); } sscanf (buf, "%f", &valf); GfParmSetNum (param, "Brake System", "front-rear brake repartition", NULL, valf); break; case 25: /* front grip bias */ if (!fgets (buf, sizeof (buf), fin)) { exit (1); } sscanf (buf, "%f", &valf); GfParmSetNum (param, "Front Right Wheel", "mu", NULL, valf * 3.0f); GfParmSetNum (param, "Front Left Wheel", "mu", NULL, valf * 3.0f); GfParmSetNum (param, "Rear Right Wheel", "mu", NULL, (1.0f - valf) * 3.0f); GfParmSetNum (param, "Rear Left Wheel", "mu", NULL, (1.0f - valf) * 3.0f); break; case 31: /* aerodynamic downforce multiplier */ if (!fgets (buf, sizeof (buf), fin)) { exit (1); } sscanf (buf, "%f", &valf); GfParmSetNum (param, "Aerodynamics", "front Clift", NULL, valf * 120.0f); GfParmSetNum (param, "Aerodynamics", "rear Clift", NULL, valf * 100.0f); break; case 35: /* tire specs front */ if (!fgets (buf, sizeof (buf), fin)) { exit (1); } s = buf; end = strchr (s, ','); if (end) { *end = 0; end++; } sscanf (s, "%d", &vald); GfParmSetNum (param, "Front Right Wheel", "tire width", "mm", (tdble)vald); GfParmSetNum (param, "Front Left Wheel", "tire width", "mm", (tdble)vald); s = end; end = strchr (s, ','); if (end) { *end = 0; end++; } sscanf (s, "%d", &vald); GfParmSetNum (param, "Front Right Wheel", "tire height-width ratio", "%", (tdble)vald); GfParmSetNum (param, "Front Left Wheel", "tire height-width ratio", "%", (tdble)vald); s = end; end = strchr (s, ','); if (end) { *end = 0; end++; } sscanf (s, "%d", &vald); GfParmSetNum (param, "Front Right Wheel", "rim diameter", "in", (tdble)vald); GfParmSetNum (param, "Front Left Wheel", "rim diameter", "in", (tdble)vald); s = end; break; case 36: /* tire specs rear */ if (!fgets (buf, sizeof (buf), fin)) { exit (1); } s = buf; end = strchr (s, ','); if (end) { *end = 0; end++; } sscanf (s, "%d", &vald); GfParmSetNum (param, "Rear Right Wheel", "tire width", "mm", (tdble)vald); GfParmSetNum (param, "Rear Left Wheel", "tire width", "mm", (tdble)vald); s = end; end = strchr (s, ','); if (end) { *end = 0; end++; } sscanf (s, "%d", &vald); GfParmSetNum (param, "Rear Right Wheel", "tire height-width ratio", "%", (tdble)vald); GfParmSetNum (param, "Rear Left Wheel", "tire height-width ratio", "%", (tdble)vald); s = end; end = strchr (s, ','); if (end) { *end = 0; end++; } sscanf (s, "%d", &vald); GfParmSetNum (param, "Rear Right Wheel", "rim diameter", "in", (tdble)vald); GfParmSetNum (param, "Rear Left Wheel", "rim diameter", "in", (tdble)vald); s = end; break; default: if (!fgets (buf, sizeof (buf), fin)) { exit (1); } break; } } GfParmWriteFile (outfile, param, "car"); return 0; }
int GfuiMenuCreateCheckboxControl(void* hscr, void* hparm, const char* pszName,void* userData,tfuiCheckboxCallback onChange) { std::string strControlPath(GFMNU_SECT_DYNAMIC_CONTROLS"/"); strControlPath += pszName; const std::string strType = GfParmGetStr(hparm, strControlPath.c_str(), GFMNU_ATTR_TYPE, ""); if (strType != GFMNU_TYPE_CHECK_BOX) { GfLogError("Failed to create control '%s' : section not found or not an '%s' \n", pszName, GFMNU_TYPE_CHECK_BOX); return -1; } int id = -1; const int x = (int)GfParmGetNum(hparm, strControlPath.c_str(), GFMNU_ATTR_X, NULL, 0.0); const int y = (int)GfParmGetNum(hparm, strControlPath.c_str(), GFMNU_ATTR_Y, NULL, 0.0); std::string strFontName = GfParmGetStr(hparm, strControlPath.c_str(), GFMNU_ATTR_FONT, ""); const int font = gfuiMenuGetFontId(strFontName.c_str()); const char* pszText = GfParmGetStr(hparm, strControlPath.c_str(), GFMNU_ATTR_TEXT, ""); int imagewidth = (int)GfParmGetNum(hparm, strControlPath.c_str(), GFMNU_ATTR_IMAGE_WIDTH, NULL, 0.0); if (imagewidth <= 0) imagewidth = 30; // TODO: Get default from screen.xml int imageheight = (int)GfParmGetNum(hparm, strControlPath.c_str(), GFMNU_ATTR_IMAGE_HEIGHT, NULL, 0.0); if (imageheight <= 0) imageheight = 30; // TODO: Get default from screen.xml const bool bChecked = getControlBoolean(hparm, strControlPath.c_str(), GFMNU_ATTR_CHECKED, false); const char* pszTip = GfParmGetStr(hparm, strControlPath.c_str(), GFMNU_ATTR_TIP, ""); void* userDataOnFocus = 0; tfuiCallback onFocus = 0; tfuiCallback onFocusLost = 0; if (strlen(pszTip) > 0) { tMenuCallbackInfo * cbinfo = (tMenuCallbackInfo*)calloc(1, sizeof(tMenuCallbackInfo)); cbinfo->screen = hscr; cbinfo->labelId = GfuiTipCreate(hscr, pszTip, strlen(pszTip)); GfuiVisibilitySet(hscr, cbinfo->labelId, GFUI_INVISIBLE); userDataOnFocus = (void*)cbinfo; onFocus = onFocusShowTip; onFocusLost = onFocusLostHideTip; } id = GfuiCheckboxCreate(hscr, font, x, y, imagewidth, imageheight, pszText, bChecked, userData, onChange, userDataOnFocus, onFocus, onFocusLost); GfuiColor c = getControlColor(hparm, pszName, GFMNU_ATTR_COLOR); if (c.alpha) GfuiCheckboxSetTextColor(hscr, id, c); return id; }
static void rmRaceResults(void *prevHdle, tRmInfo *info, int start) { void *results = info->results; const char *race = info->_reRaceName; int i; int x1, x2, x3, x4, x5, x6, x7, x8, x9; int dlap; int y; const int BUFSIZE = 1024; char buf[BUFSIZE]; char path[BUFSIZE]; const int TIMEFMTSIZE = 256; char timefmt[TIMEFMTSIZE]; float fgcolor[4] = {1.0, 0.0, 1.0, 1.0}; int laps, totLaps; tdble refTime; int nbCars; rmScrHdle = GfuiScreenCreate(); snprintf(buf, BUFSIZE, "Race Results"); GfuiTitleCreate(rmScrHdle, buf, strlen(buf)); snprintf(buf, BUFSIZE, "%s", info->track->name); GfuiLabelCreate(rmScrHdle, buf, GFUI_FONT_LARGE_C, 320, 420, GFUI_ALIGN_HC_VB, 0); GfuiScreenAddBgImg(rmScrHdle, "data/img/splash-result.png"); x1 = 30; x2 = 60; x3 = 260; x4 = 330; x5 = 360; x6 = 420; x7 = 490; x8 = 545; x9 = 630; y = 400; GfuiLabelCreateEx(rmScrHdle, "Rank", fgcolor, GFUI_FONT_MEDIUM_C, x1, y, GFUI_ALIGN_HC_VB, 0); GfuiLabelCreateEx(rmScrHdle, "Driver", fgcolor, GFUI_FONT_MEDIUM_C, x2+10, y, GFUI_ALIGN_HL_VB, 0); GfuiLabelCreateEx(rmScrHdle, "Total", fgcolor, GFUI_FONT_MEDIUM_C, x3, y, GFUI_ALIGN_HR_VB, 0); GfuiLabelCreateEx(rmScrHdle, "Best", fgcolor, GFUI_FONT_MEDIUM_C, x4, y, GFUI_ALIGN_HR_VB, 0); GfuiLabelCreateEx(rmScrHdle, "Laps", fgcolor, GFUI_FONT_MEDIUM_C, x5, y, GFUI_ALIGN_HC_VB, 0); GfuiLabelCreateEx(rmScrHdle, "Top Spd", fgcolor, GFUI_FONT_MEDIUM_C, x6, y, GFUI_ALIGN_HC_VB, 0); GfuiLabelCreateEx(rmScrHdle, "Damage", fgcolor, GFUI_FONT_MEDIUM_C, x7, y, GFUI_ALIGN_HC_VB, 0); GfuiLabelCreateEx(rmScrHdle, "Pit", fgcolor, GFUI_FONT_MEDIUM_C, x8, y, GFUI_ALIGN_HC_VB, 0); GfuiLabelCreateEx(rmScrHdle, "Penalty", fgcolor, GFUI_FONT_MEDIUM_C, x9, y, GFUI_ALIGN_HR_VB, 0); y -= 20; snprintf(path, BUFSIZE, "%s/%s/%s", info->track->name, RE_SECT_RESULTS, race); totLaps = (int)GfParmGetNum(results, path, RE_ATTR_LAPS, NULL, 0); snprintf(path, BUFSIZE, "%s/%s/%s/%s/%d", info->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, 1); refTime = GfParmGetNum(results, path, RE_ATTR_TIME, NULL, 0); snprintf(path, BUFSIZE, "%s/%s/%s/%s", info->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK); nbCars = (int)GfParmGetEltNb(results, path); for (i = start; i < MIN(start + MAX_LINES, nbCars); i++) { snprintf(path, BUFSIZE, "%s/%s/%s/%s/%d", info->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, i + 1); laps = (int)GfParmGetNum(results, path, RE_ATTR_LAPS, NULL, 0); snprintf(buf, BUFSIZE, "%d", i+1); GfuiLabelCreate(rmScrHdle, buf, GFUI_FONT_MEDIUM_C, x1, y, GFUI_ALIGN_HC_VB, 0); GfuiLabelCreate(rmScrHdle, GfParmGetStr(results, path, RE_ATTR_NAME, ""), GFUI_FONT_MEDIUM_C, x2, y, GFUI_ALIGN_HL_VB, 0); if (laps == totLaps) { if (i == 0) { GfTime2Str(timefmt, TIMEFMTSIZE, GfParmGetNum(results, path, RE_ATTR_TIME, NULL, 0), 0); } else { GfTime2Str(timefmt, TIMEFMTSIZE, GfParmGetNum(results, path, RE_ATTR_TIME, NULL, 0) - refTime, 1); } GfuiLabelCreate(rmScrHdle, timefmt, GFUI_FONT_MEDIUM_C, x3, y, GFUI_ALIGN_HR_VB, 0); } else { dlap = totLaps - laps; if (dlap == 1) { snprintf(buf, BUFSIZE, "+1 Lap"); } else { snprintf(buf, BUFSIZE, "+%d Laps", dlap); } GfuiLabelCreate(rmScrHdle, buf, GFUI_FONT_MEDIUM_C, x3, y, GFUI_ALIGN_HR_VB, 0); } GfTime2Str(timefmt, TIMEFMTSIZE, GfParmGetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, 0), 0); GfuiLabelCreate(rmScrHdle, timefmt, GFUI_FONT_MEDIUM_C, x4, y, GFUI_ALIGN_HR_VB, 0); snprintf(buf, BUFSIZE, "%d", laps); GfuiLabelCreate(rmScrHdle, buf, GFUI_FONT_MEDIUM_C, x5, y, GFUI_ALIGN_HC_VB, 0); snprintf(buf, BUFSIZE, "%d", (int)(GfParmGetNum(results, path, RE_ATTR_TOP_SPEED, NULL, 0) * 3.6)); GfuiLabelCreate(rmScrHdle, buf, GFUI_FONT_MEDIUM_C, x6, y, GFUI_ALIGN_HC_VB, 0); snprintf(buf, BUFSIZE, "%d", (int)(GfParmGetNum(results, path, RE_ATTR_DAMMAGES, NULL, 0))); GfuiLabelCreate(rmScrHdle, buf, GFUI_FONT_MEDIUM_C, x7, y, GFUI_ALIGN_HC_VB, 0); snprintf(buf, BUFSIZE, "%d", (int)(GfParmGetNum(results, path, RE_ATTR_NB_PIT_STOPS, NULL, 0))); GfuiLabelCreate(rmScrHdle, buf, GFUI_FONT_MEDIUM_C, x8, y, GFUI_ALIGN_HC_VB, 0); GfTime2Str(timefmt, TIMEFMTSIZE, GfParmGetNum(results, path, RE_ATTR_PENALTYTIME, NULL, 0), 0); GfuiLabelCreate(rmScrHdle, timefmt, GFUI_FONT_MEDIUM_C, x9, y, GFUI_ALIGN_HR_VB, 0); y -= 15; } if (start > 0) { RmPrevRace.prevHdle = prevHdle; RmPrevRace.info = info; RmPrevRace.start = start - MAX_LINES; GfuiGrButtonCreate(rmScrHdle, "data/img/arrow-up.png", "data/img/arrow-up.png", "data/img/arrow-up.png", "data/img/arrow-up-pushed.png", 80, 40, GFUI_ALIGN_HL_VB, 1, (void*)&RmPrevRace, rmChgRaceScreen, NULL, (tfuiCallback)NULL, (tfuiCallback)NULL); GfuiAddSKey(rmScrHdle, GLUT_KEY_PAGE_UP, "Previous Results", (void*)&RmPrevRace, rmChgRaceScreen, NULL); } GfuiButtonCreate(rmScrHdle, "Continue", GFUI_FONT_LARGE, /* 210, */ 320, 40, 150, GFUI_ALIGN_HC_VB, 0, prevHdle, GfuiScreenReplace, NULL, (tfuiCallback)NULL, (tfuiCallback)NULL); if (i < nbCars) { RmNextRace.prevHdle = prevHdle; RmNextRace.info = info; RmNextRace.start = start + MAX_LINES; GfuiGrButtonCreate(rmScrHdle, "data/img/arrow-down.png", "data/img/arrow-down.png", "data/img/arrow-down.png", "data/img/arrow-down-pushed.png", 540, 40, GFUI_ALIGN_HL_VB, 1, (void*)&RmNextRace, rmChgRaceScreen, NULL, (tfuiCallback)NULL, (tfuiCallback)NULL); GfuiAddSKey(rmScrHdle, GLUT_KEY_PAGE_DOWN, "Next Results", (void*)&RmNextRace, rmChgRaceScreen, NULL); } GfuiAddKey(rmScrHdle, (unsigned char)27, "", prevHdle, GfuiScreenReplace, NULL); GfuiAddKey(rmScrHdle, (unsigned char)13, "", prevHdle, GfuiScreenReplace, NULL); GfuiAddSKey(rmScrHdle, GLUT_KEY_F12, "Take a Screen Shot", NULL, GfuiScreenShot, NULL); GfuiScreenActivate(rmScrHdle); }
/* * 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
static void rmShowStandings(void *prevHdle, tRmInfo *info, int start) { int i; int x1, x2, x3; int y; const int BUFSIZE = 1024; char buf[BUFSIZE]; char path[BUFSIZE]; float fgcolor[4] = {1.0, 0.0, 1.0, 1.0}; int nbCars; int offset; void *results = info->results; const char *race = info->_reRaceName; rmScrHdle = GfuiScreenCreate(); snprintf(buf, BUFSIZE, "%s Results", race); GfuiTitleCreate(rmScrHdle, buf, strlen(buf)); GfuiScreenAddBgImg(rmScrHdle, "data/img/splash-result.png"); offset = 200; x1 = offset + 30; x2 = offset + 60; x3 = offset + 240; y = 400; GfuiLabelCreateEx(rmScrHdle, "Rank", fgcolor, GFUI_FONT_MEDIUM_C, x1, y, GFUI_ALIGN_HC_VB, 0); GfuiLabelCreateEx(rmScrHdle, "Driver", fgcolor, GFUI_FONT_MEDIUM_C, x2+10, y, GFUI_ALIGN_HL_VB, 0); GfuiLabelCreateEx(rmScrHdle, "Points", fgcolor, GFUI_FONT_MEDIUM_C, x3, y, GFUI_ALIGN_HR_VB, 0); y -= 20; nbCars = (int)GfParmGetEltNb(results, RE_SECT_STANDINGS); for (i = start; i < MIN(start + MAX_LINES, nbCars); i++) { snprintf(path, BUFSIZE, "%s/%d", RE_SECT_STANDINGS, i + 1); snprintf(buf, BUFSIZE, "%d", i+1); GfuiLabelCreate(rmScrHdle, buf, GFUI_FONT_MEDIUM_C, x1, y, GFUI_ALIGN_HC_VB, 0); GfuiLabelCreate(rmScrHdle, GfParmGetStr(results, path, RE_ATTR_NAME, ""), GFUI_FONT_MEDIUM_C, x2, y, GFUI_ALIGN_HL_VB, 0); snprintf(buf, BUFSIZE, "%d", (int)GfParmGetNum(results, path, RE_ATTR_POINTS, NULL, 0)); GfuiLabelCreate(rmScrHdle, buf, GFUI_FONT_MEDIUM_C, x3, y, GFUI_ALIGN_HR_VB, 0); y -= 15; } if (start > 0) { RmPrevRace.prevHdle = prevHdle; RmPrevRace.info = info; RmPrevRace.start = start - MAX_LINES; GfuiGrButtonCreate(rmScrHdle, "data/img/arrow-up.png", "data/img/arrow-up.png", "data/img/arrow-up.png", "data/img/arrow-up-pushed.png", 80, 40, GFUI_ALIGN_HL_VB, 1, (void*)&RmPrevRace, rmChgStandingScreen, NULL, (tfuiCallback)NULL, (tfuiCallback)NULL); GfuiAddSKey(rmScrHdle, GLUT_KEY_PAGE_UP, "Previous Results", (void*)&RmPrevRace, rmChgStandingScreen, NULL); } GfuiButtonCreate(rmScrHdle, "Continue", GFUI_FONT_LARGE, 210, 40, 150, GFUI_ALIGN_HC_VB, 0, prevHdle, GfuiScreenReplace, NULL, (tfuiCallback)NULL, (tfuiCallback)NULL); rmSaveId = GfuiButtonCreate(rmScrHdle, "Save", GFUI_FONT_LARGE, 430, 40, 150, GFUI_ALIGN_HC_VB, 0, info, rmSaveRes, NULL, (tfuiCallback)NULL, (tfuiCallback)NULL); if (i < nbCars) { RmNextRace.prevHdle = prevHdle; RmNextRace.info = info; RmNextRace.start = start + MAX_LINES; GfuiGrButtonCreate(rmScrHdle, "data/img/arrow-down.png", "data/img/arrow-down.png", "data/img/arrow-down.png", "data/img/arrow-down-pushed.png", 540, 40, GFUI_ALIGN_HL_VB, 1, (void*)&RmNextRace, rmChgStandingScreen, NULL, (tfuiCallback)NULL, (tfuiCallback)NULL); GfuiAddSKey(rmScrHdle, GLUT_KEY_PAGE_DOWN, "Next Results", (void*)&RmNextRace, rmChgStandingScreen, NULL); } GfuiAddKey(rmScrHdle, (unsigned char)27, "", prevHdle, GfuiScreenReplace, NULL); GfuiAddKey(rmScrHdle, (unsigned char)13, "", prevHdle, GfuiScreenReplace, NULL); GfuiAddSKey(rmScrHdle, GLUT_KEY_F12, "Take a Screen Shot", NULL, GfuiScreenShot, NULL); GfuiScreenActivate(rmScrHdle); }
void cGrBoard::loadDefaults(tCarElt *curCar) { const int BUFSIZE=1024; char path[BUFSIZE]; snprintf(path, BUFSIZE, "%s/%d", GR_SCT_DISPMODE, id); debugFlag = (int)GfParmGetNum(grHandle, path, GR_ATT_DEBUG, NULL, 1); boardFlag = (int)GfParmGetNum(grHandle, path, GR_ATT_BOARD, NULL, 2); leaderFlag = (int)GfParmGetNum(grHandle, path, GR_ATT_LEADER, NULL, 1); leaderNb = (int)GfParmGetNum(grHandle, path, GR_ATT_NBLEADER, NULL, 10); counterFlag = (int)GfParmGetNum(grHandle, path, GR_ATT_COUNTER, NULL, 1); GFlag = (int)GfParmGetNum(grHandle, path, GR_ATT_GGRAPH, NULL, 1); arcadeFlag = (int)GfParmGetNum(grHandle, path, GR_ATT_ARCADE, NULL, 0); trackMap->setViewMode((int) GfParmGetNum(grHandle, path, GR_ATT_MAP, NULL, trackMap->getDefaultViewMode())); if (curCar->_driverType == RM_DRV_HUMAN) { snprintf(path, BUFSIZE, "%s/%s", GR_SCT_DISPMODE, curCar->_name); debugFlag = (int)GfParmGetNum(grHandle, path, GR_ATT_DEBUG, NULL, debugFlag); boardFlag = (int)GfParmGetNum(grHandle, path, GR_ATT_BOARD, NULL, boardFlag); leaderFlag = (int)GfParmGetNum(grHandle, path, GR_ATT_LEADER, NULL, leaderFlag); leaderNb = (int)GfParmGetNum(grHandle, path, GR_ATT_NBLEADER, NULL, leaderNb); counterFlag = (int)GfParmGetNum(grHandle, path, GR_ATT_COUNTER, NULL, counterFlag); GFlag = (int)GfParmGetNum(grHandle, path, GR_ATT_GGRAPH, NULL, GFlag); arcadeFlag = (int)GfParmGetNum(grHandle, path, GR_ATT_ARCADE, NULL, arcadeFlag); trackMap->setViewMode((int) GfParmGetNum(grHandle, path, GR_ATT_MAP, NULL, trackMap->getViewMode())); } }
static void rmPracticeResults(void *prevHdle, tRmInfo *info, int start) { void *results = info->results; const char *race = info->_reRaceName; int i; int x1, x2, x3, x4, x5, x6; int offset; int y; const int BUFSIZE = 1024; char buf[BUFSIZE]; char path[BUFSIZE]; const int TIMEFMTSIZE = 256; char timefmt[TIMEFMTSIZE]; float fgcolor[4] = {1.0, 0.0, 1.0, 1.0}; int totLaps; rmScrHdle = GfuiScreenCreate(); snprintf(buf, BUFSIZE, "Practice Results"); GfuiTitleCreate(rmScrHdle, buf, strlen(buf)); snprintf(path, BUFSIZE, "%s/%s/%s", info->track->name, RE_SECT_RESULTS, race); snprintf(buf, BUFSIZE, "%s on track %s", GfParmGetStr(results, path, RM_ATTR_DRVNAME, ""), info->track->name); GfuiLabelCreate(rmScrHdle, buf, GFUI_FONT_LARGE_C, 320, 420, GFUI_ALIGN_HC_VB, 0); GfuiScreenAddBgImg(rmScrHdle, "data/img/splash-result.png"); offset = 90; x1 = offset + 30; x2 = offset + 50; x3 = offset + 130; x4 = offset + 240; x5 = offset + 310; x6 = offset + 400; y = 400; GfuiLabelCreateEx(rmScrHdle, "Lap", fgcolor, GFUI_FONT_MEDIUM_C, x1, y, GFUI_ALIGN_HC_VB, 0); GfuiLabelCreateEx(rmScrHdle, "Time", fgcolor, GFUI_FONT_MEDIUM_C, x2+20, y, GFUI_ALIGN_HL_VB, 0); GfuiLabelCreateEx(rmScrHdle, "Best", fgcolor, GFUI_FONT_MEDIUM_C, x3+20, y, GFUI_ALIGN_HL_VB, 0); GfuiLabelCreateEx(rmScrHdle, "Top Spd", fgcolor, GFUI_FONT_MEDIUM_C, x4, y, GFUI_ALIGN_HC_VB, 0); GfuiLabelCreateEx(rmScrHdle, "Min Spd", fgcolor, GFUI_FONT_MEDIUM_C, x5, y, GFUI_ALIGN_HC_VB, 0); GfuiLabelCreateEx(rmScrHdle, "Damages", fgcolor, GFUI_FONT_MEDIUM_C, x6, y, GFUI_ALIGN_HC_VB, 0); y -= 20; snprintf(path, BUFSIZE, "%s/%s/%s", info->track->name, RE_SECT_RESULTS, race); totLaps = (int)GfParmGetEltNb(results, path); for (i = 0 + start; i < MIN(start + MAX_LINES, totLaps); i++) { snprintf(path, BUFSIZE, "%s/%s/%s/%d", info->track->name, RE_SECT_RESULTS, race, i + 1); /* Lap */ snprintf(buf, BUFSIZE, "%d", i+1); GfuiLabelCreate(rmScrHdle, buf, GFUI_FONT_MEDIUM_C, x1, y, GFUI_ALIGN_HC_VB, 0); /* Time */ GfTime2Str(timefmt, TIMEFMTSIZE, GfParmGetNum(results, path, RE_ATTR_TIME, NULL, 0), 0); GfuiLabelCreate(rmScrHdle, timefmt, GFUI_FONT_MEDIUM_C, x2, y, GFUI_ALIGN_HL_VB, 0); /* Best Lap Time */ GfTime2Str(timefmt, TIMEFMTSIZE, GfParmGetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, 0), 0); GfuiLabelCreate(rmScrHdle, timefmt, GFUI_FONT_MEDIUM_C, x3, y, GFUI_ALIGN_HL_VB, 0); /* Top Spd */ snprintf(buf, BUFSIZE, "%d", (int)(GfParmGetNum(results, path, RE_ATTR_TOP_SPEED, NULL, 0) * 3.6)); GfuiLabelCreate(rmScrHdle, buf, GFUI_FONT_MEDIUM_C, x4, y, GFUI_ALIGN_HC_VB, 0); /* Min Spd */ snprintf(buf, BUFSIZE, "%d", (int)(GfParmGetNum(results, path, RE_ATTR_BOT_SPEED, NULL, 0) * 3.6)); GfuiLabelCreate(rmScrHdle, buf, GFUI_FONT_MEDIUM_C, x5, y, GFUI_ALIGN_HC_VB, 0); /* Damages */ snprintf(buf, BUFSIZE, "%d", (int)(GfParmGetNum(results, path, RE_ATTR_DAMMAGES, NULL, 0))); GfuiLabelCreate(rmScrHdle, buf, GFUI_FONT_MEDIUM_C, x6, y, GFUI_ALIGN_HC_VB, 0); y -= 15; } if (start > 0) { RmPrevRace.prevHdle = prevHdle; RmPrevRace.info = info; RmPrevRace.start = start - MAX_LINES; GfuiGrButtonCreate(rmScrHdle, "data/img/arrow-up.png", "data/img/arrow-up.png", "data/img/arrow-up.png", "data/img/arrow-up-pushed.png", 80, 40, GFUI_ALIGN_HL_VB, 1, (void*)&RmPrevRace, rmChgPracticeScreen, NULL, (tfuiCallback)NULL, (tfuiCallback)NULL); GfuiAddSKey(rmScrHdle, GLUT_KEY_PAGE_UP, "Previous Results", (void*)&RmPrevRace, rmChgPracticeScreen, NULL); } GfuiButtonCreate(rmScrHdle, "Continue", GFUI_FONT_LARGE, 320, 40, 150, GFUI_ALIGN_HC_VB, 0, prevHdle, GfuiScreenReplace, NULL, (tfuiCallback)NULL, (tfuiCallback)NULL); if (i < totLaps) { RmNextRace.prevHdle = prevHdle; RmNextRace.info = info; RmNextRace.start = start + MAX_LINES; GfuiGrButtonCreate(rmScrHdle, "data/img/arrow-down.png", "data/img/arrow-down.png", "data/img/arrow-down.png", "data/img/arrow-down-pushed.png", 540, 40, GFUI_ALIGN_HL_VB, 1, (void*)&RmNextRace, rmChgPracticeScreen, NULL, (tfuiCallback)NULL, (tfuiCallback)NULL); GfuiAddSKey(rmScrHdle, GLUT_KEY_PAGE_DOWN, "Next Results", (void*)&RmNextRace, rmChgPracticeScreen, NULL); } GfuiAddKey(rmScrHdle, (unsigned char)27, "", prevHdle, GfuiScreenReplace, NULL); GfuiAddKey(rmScrHdle, (unsigned char)13, "", prevHdle, GfuiScreenReplace, NULL); GfuiAddSKey(rmScrHdle, GLUT_KEY_F12, "Take a Screen Shot", NULL, GfuiScreenShot, NULL); GfuiScreenActivate(rmScrHdle); }
void HmReadPrefs(int index) { const char *prm; const char *defaultSettings; const int BUFSIZE = 1024; char sstring[BUFSIZE]; int cmd; float tmp; tCtrlRef *ref; int i; int idx = index - 1; tControlCmd *cmdCtrl; HCtx[idx]->CmdControl = (tControlCmd *) calloc (nbCmdControl, sizeof (tControlCmd)); cmdCtrl = HCtx[idx]->CmdControl; memcpy(cmdCtrl, CmdControlRef, nbCmdControl * sizeof (tControlCmd)); snprintf(sstring, BUFSIZE, "%s%s", GetLocalDir(), HM_PREF_FILE); PrefHdle = GfParmReadFile(sstring, GFPARM_RMODE_REREAD | GFPARM_RMODE_CREAT); snprintf(sstring, BUFSIZE, "%s/%s/%d", HM_SECT_PREF, HM_LIST_DRV, index); prm = GfParmGetStr(PrefHdle, sstring, HM_ATT_TRANS, HM_VAL_AUTO); if (strcmp(prm, HM_VAL_AUTO) == 0) { HCtx[idx]->Transmission = 0; } else { HCtx[idx]->Transmission = 1; } /* Parameters Settings */ prm = GfParmGetStr(PrefHdle, sstring, HM_ATT_ABS, Yn[HCtx[idx]->ParamAbs]); if (strcmp(prm, Yn[0]) == 0) { HCtx[idx]->ParamAbs = 1; } else { HCtx[idx]->ParamAbs = 0; } prm = GfParmGetStr(PrefHdle, sstring, HM_ATT_ASR, Yn[HCtx[idx]->ParamAsr]); if (strcmp(prm, Yn[0]) == 0) { HCtx[idx]->ParamAsr = 1; } else { HCtx[idx]->ParamAsr = 0; } prm = GfParmGetStr(PrefHdle, HM_SECT_PREF, HM_ATT_CONTROL, controlList[2].parmName); prm = GfParmGetStr(PrefHdle, sstring, HM_ATT_CONTROL, prm); for (i = 0; i < nbControl; i++) { if (!strcmp(prm, controlList[i].parmName)) { break; } } if (i == nbControl) { i = 2; } if ((i == 0) && !joyPresent) { i = 2; } defaultSettings = controlList[i].settings; /* Command Settings */ for (cmd = 0; cmd < nbCmdControl; cmd++) { prm = GfctrlGetNameByRef(cmdCtrl[cmd].type, cmdCtrl[cmd].val); prm = GfParmGetStr(PrefHdle, defaultSettings, cmdCtrl[cmd].name, prm); prm = GfParmGetStr(PrefHdle, sstring, cmdCtrl[cmd].name, prm); if (!prm || (strlen(prm) == 0)) { cmdCtrl[cmd].type = GFCTRL_TYPE_NOT_AFFECTED; GfOut("%s -> NONE (-1)\n", cmdCtrl[cmd].name); continue; } ref = GfctrlGetRefByName(prm); cmdCtrl[cmd].type = ref->type; cmdCtrl[cmd].val = ref->index; GfOut("%s -> %s\n", cmdCtrl[cmd].name, prm); if (cmdCtrl[cmd].minName) { cmdCtrl[cmd].min = (float)GfParmGetNum(PrefHdle, defaultSettings, cmdCtrl[cmd].minName, (char*)NULL, (tdble)cmdCtrl[cmd].min); cmdCtrl[cmd].min = cmdCtrl[cmd].minVal = (float)GfParmGetNum(PrefHdle, sstring, cmdCtrl[cmd].minName, (char*)NULL, (tdble)cmdCtrl[cmd].min); } if (cmdCtrl[cmd].maxName) { cmdCtrl[cmd].max = (float)GfParmGetNum(PrefHdle, defaultSettings, cmdCtrl[cmd].maxName, (char*)NULL, (tdble)cmdCtrl[cmd].max); cmdCtrl[cmd].max = (float)GfParmGetNum(PrefHdle, sstring, cmdCtrl[cmd].maxName, (char*)NULL, (tdble)cmdCtrl[cmd].max); } if (cmdCtrl[cmd].sensName) { cmdCtrl[cmd].sens = 1.0f / (float)GfParmGetNum(PrefHdle, defaultSettings, cmdCtrl[cmd].sensName, (char*)NULL, 1.0 / (tdble)cmdCtrl[cmd].sens); cmdCtrl[cmd].sens = 1.0f / (float)GfParmGetNum(PrefHdle, sstring, cmdCtrl[cmd].sensName, (char*)NULL, 1.0 / (tdble)cmdCtrl[cmd].sens); } if (cmdCtrl[cmd].powName) { cmdCtrl[cmd].pow = (float)GfParmGetNum(PrefHdle, defaultSettings, cmdCtrl[cmd].powName, (char*)NULL, (tdble)cmdCtrl[cmd].pow); cmdCtrl[cmd].pow = (float)GfParmGetNum(PrefHdle, sstring, cmdCtrl[cmd].powName, (char*)NULL, (tdble)cmdCtrl[cmd].pow); } if (cmdCtrl[cmd].spdSensName) { cmdCtrl[cmd].spdSens = (float)GfParmGetNum(PrefHdle, defaultSettings, cmdCtrl[cmd].spdSensName, (char*)NULL, (tdble)cmdCtrl[cmd].spdSens); cmdCtrl[cmd].spdSens = (float)GfParmGetNum(PrefHdle, sstring, cmdCtrl[cmd].spdSensName, (char*)NULL, (tdble)cmdCtrl[cmd].spdSens); cmdCtrl[cmd].spdSens = cmdCtrl[cmd].spdSens / 100.0; } if (cmdCtrl[cmd].deadZoneName) { cmdCtrl[cmd].deadZone = (float)GfParmGetNum(PrefHdle, defaultSettings, cmdCtrl[cmd].deadZoneName, (char*)NULL, (tdble)cmdCtrl[cmd].deadZone); cmdCtrl[cmd].deadZone = (float)GfParmGetNum(PrefHdle, sstring, cmdCtrl[cmd].deadZoneName, (char*)NULL, (tdble)cmdCtrl[cmd].deadZone); } if (cmdCtrl[cmd].min > cmdCtrl[cmd].max) { tmp = cmdCtrl[cmd].min; cmdCtrl[cmd].min = cmdCtrl[cmd].max; cmdCtrl[cmd].max = tmp; } cmdCtrl[cmd].deadZone = (cmdCtrl[cmd].max - cmdCtrl[cmd].min) * cmdCtrl[cmd].deadZone; if (cmdCtrl[cmd].type == GFCTRL_TYPE_MOUSE_AXIS) { HCtx[idx]->MouseControlUsed = 1; } } prm = GfParmGetStr(PrefHdle, defaultSettings, HM_ATT_REL_BUT_NEUTRAL, Yn[HCtx[idx]->RelButNeutral]); prm = GfParmGetStr(PrefHdle, sstring, HM_ATT_REL_BUT_NEUTRAL, prm); if (strcmp(prm, Yn[0]) == 0) { HCtx[idx]->RelButNeutral = 1; } else { HCtx[idx]->RelButNeutral = 0; } prm = GfParmGetStr(PrefHdle, defaultSettings, HM_ATT_SEQSHFT_ALLOW_NEUTRAL, Yn[HCtx[idx]->SeqShftAllowNeutral]); prm = GfParmGetStr(PrefHdle, sstring, HM_ATT_SEQSHFT_ALLOW_NEUTRAL, prm); if (strcmp(prm, Yn[0]) == 0) { HCtx[idx]->SeqShftAllowNeutral = 1; } else { HCtx[idx]->SeqShftAllowNeutral = 0; } prm = GfParmGetStr(PrefHdle, sstring, HM_ATT_AUTOREVERSE, Yn[HCtx[idx]->AutoReverse]); if (strcmp(prm, Yn[0]) == 0) { HCtx[idx]->AutoReverse = 1; } else { HCtx[idx]->AutoReverse = 0; } }
/** Interactive track selection @param vs Pointer on a tRmTrackSelect structure (cast to void *) @warning The race manager's parameters are updated but not saved. @ingroup racemantools */ void RmTrackSelect(void *vs) { const char *defaultTrack; const char *defaultCategory; tFList *CatCur; tFList *TrList, *TrCur; int Xpos, Ypos, DX, DY; int curTrkIdx; const int BUFSIZE = 1024; char buf[BUFSIZE]; char path[BUFSIZE]; ts = (tRmTrackSelect*)vs; /* Get the list of categories directories */ CategoryList = GfDirGetList("tracks"); if (CategoryList == NULL) { GfTrace("RmTrackSelect: No track category available\n"); return; } CatCur = CategoryList; do { CatCur->dispName = RmGetCategoryName(CatCur->name); if (strlen(CatCur->dispName) == 0) { GfTrace("RmTrackSelect: No definition for track category %s\n", CatCur->name); return; } /* get the tracks in the category directory */ snprintf(buf, BUFSIZE, "tracks/%s", CatCur->name); TrList = GfDirGetList(buf); if (TrList == NULL) { GfTrace("RmTrackSelect: No track for category %s available\n", CatCur->name); return; } TrList = TrList->next; /* get the first one */ CatCur->userData = (void*)TrList; TrCur = TrList; do { TrCur->dispName = RmGetTrackName(CatCur->name, TrCur->name); if (strlen(TrCur->dispName) == 0) { GfTrace("RmTrackSelect: No definition for track %s\n", TrCur->name); return; } TrCur = TrCur->next; } while (TrCur != TrList); CatCur = CatCur->next; } while (CatCur != CategoryList); curTrkIdx = (int)GfParmGetNum(ts->param, RM_SECT_TRACKS, RE_ATTR_CUR_TRACK, NULL, 1); snprintf(path, BUFSIZE, "%s/%d", RM_SECT_TRACKS, curTrkIdx); defaultCategory = GfParmGetStr(ts->param, path, RM_ATTR_CATEGORY, CategoryList->name); /* XXX coherency check */ defaultTrack = GfParmGetStr(ts->param, path, RM_ATTR_NAME, ((tFList*)CategoryList->userData)->name); CatCur = CategoryList; do { if (strcmp(CatCur->name, defaultCategory) == 0) { CategoryList = CatCur; TrCur = (tFList*)(CatCur->userData); do { if (strcmp(TrCur->name, defaultTrack) == 0) { CatCur->userData = (void*)TrCur; break; } TrCur = TrCur->next; } while (TrCur != TrList); break; } CatCur = CatCur->next; } while (CatCur != CategoryList); scrHandle = GfuiScreenCreateEx((float*)NULL, NULL, rmtsActivate, NULL, (tfuiCallback)NULL, 1); GfuiScreenAddBgImg(scrHandle, "data/img/splash-qrtrk.png"); rmtsAddKeys(); GfuiTitleCreate(scrHandle, "Select Track", 0); GfuiGrButtonCreate(scrHandle, "data/img/arrow-left.png", "data/img/arrow-left.png", "data/img/arrow-left.png", "data/img/arrow-left-pushed.png", 80, 400, GFUI_ALIGN_HC_VB, 0, (void*)0, rmCatPrevNext, NULL, (tfuiCallback)NULL, (tfuiCallback)NULL); CatLabelId = GfuiLabelCreate(scrHandle, CategoryList->dispName, GFUI_FONT_LARGE_C, 320, 400, GFUI_ALIGN_HC_VB, 30); GfuiGrButtonCreate(scrHandle, "data/img/arrow-right.png", "data/img/arrow-right.png", "data/img/arrow-right.png", "data/img/arrow-right-pushed.png", 540, 400, GFUI_ALIGN_HC_VB, 0, (void*)1, rmCatPrevNext, NULL, (tfuiCallback)NULL, (tfuiCallback)NULL); GfuiGrButtonCreate(scrHandle, "data/img/arrow-left.png", "data/img/arrow-left.png", "data/img/arrow-left.png", "data/img/arrow-left-pushed.png", 80, 370, GFUI_ALIGN_HC_VB, 0, (void*)0, rmtsPrevNext, NULL, (tfuiCallback)NULL, (tfuiCallback)NULL); TrackLabelId = GfuiLabelCreate(scrHandle, ((tFList*)CategoryList->userData)->dispName, GFUI_FONT_LARGE_C, 320, 370, GFUI_ALIGN_HC_VB, 30); GfuiGrButtonCreate(scrHandle, "data/img/arrow-right.png", "data/img/arrow-right.png", "data/img/arrow-right.png", "data/img/arrow-right-pushed.png", 540, 370, GFUI_ALIGN_HC_VB, 0, (void*)1, rmtsPrevNext, NULL, (tfuiCallback)NULL, (tfuiCallback)NULL); MapId = GfuiStaticImageCreate(scrHandle, 320, 100, 260, 195, rmGetMapName(buf, BUFSIZE)); GfuiButtonCreate(scrHandle, "Accept", GFUI_FONT_LARGE, 210, 40, 150, GFUI_ALIGN_HC_VB, GFUI_MOUSE_UP, NULL, rmtsSelect, NULL, (tfuiCallback)NULL, (tfuiCallback)NULL); GfuiButtonCreate(scrHandle, "Back", GFUI_FONT_LARGE, 430, 40, 150, GFUI_ALIGN_HC_VB, GFUI_MOUSE_UP, ts->prevScreen, rmtsDeactivate, NULL, (tfuiCallback)NULL, (tfuiCallback)NULL); Xpos = 20; Ypos = 320; DX = 110; DY = 30; GfuiLabelCreate(scrHandle, "Description:", GFUI_FONT_MEDIUM, Xpos, Ypos, GFUI_ALIGN_HL_VB, 0); DescId = GfuiLabelCreate(scrHandle, "", GFUI_FONT_MEDIUM_C, Xpos + DX, Ypos, GFUI_ALIGN_HL_VB, 50); Ypos -= DY; GfuiLabelCreate(scrHandle, "Author:", GFUI_FONT_MEDIUM, Xpos, Ypos, GFUI_ALIGN_HL_VB, 0); AuthorId = GfuiLabelCreate(scrHandle, "", GFUI_FONT_MEDIUM_C, Xpos + DX, Ypos, GFUI_ALIGN_HL_VB, 20); Ypos -= DY; GfuiLabelCreate(scrHandle, "Length:", GFUI_FONT_MEDIUM, Xpos, Ypos, GFUI_ALIGN_HL_VB, 0); LengthId = GfuiLabelCreate(scrHandle, "", GFUI_FONT_MEDIUM_C, Xpos + DX, Ypos, GFUI_ALIGN_HL_VB, 20); Ypos -= DY; GfuiLabelCreate(scrHandle, "Width:", GFUI_FONT_MEDIUM, Xpos, Ypos, GFUI_ALIGN_HL_VB, 0); WidthId = GfuiLabelCreate(scrHandle, "", GFUI_FONT_MEDIUM_C, Xpos + DX, Ypos, GFUI_ALIGN_HL_VB, 20); Ypos -= DY; GfuiLabelCreate(scrHandle, "Pits:", GFUI_FONT_MEDIUM, Xpos, Ypos, GFUI_ALIGN_HL_VB, 0); PitsId = GfuiLabelCreate(scrHandle, "", GFUI_FONT_MEDIUM_C, Xpos + DX, Ypos, GFUI_ALIGN_HL_VB, 20); rmUpdateTrackInfo(); GfuiScreenActivate(scrHandle); }