void ReUpdatePracticeCurRes(tCarElt *car, bool bForceNew) { if (bForceNew) { static const char* pszTableHeader = "Lap \tTime \tBest \tTop spd \tMin spd \tDamages"; ReUI().setResultsTableHeader(pszTableHeader); char* t1 = GfTime2Str(car->_lastLapTime, 0, false, 3); char* t2 = GfTime2Str(car->_bestLapTime, 0, false, 3); char buf[128]; // Cancel hightlight on first line if (car->_laps == 2) ReUI().setResultsTableRow(0, ""); tReCarInfo *info = &(ReInfo->_reCarInfo[car->index]); static int nLastLapDamages = 0; if (car->_laps <= 2) nLastLapDamages = 0; snprintf(buf, sizeof(buf), "%.3d \t%-12s \t%-12s \t%5.1f \t%5.1f \t %.5d (%d)", car->_laps - 1, t1, t2, info->topSpd * 3.6, info->botSpd * 3.6, car->_dammage ? car->_dammage - nLastLapDamages : 0, car->_dammage); nLastLapDamages = car->_dammage; free(t1); free(t2); ReUI().addResultsTableRow(buf); } else { ReUpdateQualifCurRes(car); } }
void ReUpdateQualifCurRes(tCarElt *car) { int i; int nCars; int printed; int maxLines; void *carparam; char *carName; const char *race = ReInfo->_reRaceName; void *results = ReInfo->results; const int BUFSIZE = 1024; char buf[BUFSIZE], path[BUFSIZE]; ReResEraseScreen(); maxLines = ReResGetLines(); snprintf(buf, BUFSIZE, "%s on %s - Lap %d", car->_name, ReInfo->track->name, car->_laps); ReResScreenSetTitle(buf); snprintf(buf, BUFSIZE, "cars/%s/%s.xml", car->_carName, car->_carName); carparam = GfParmReadFile(buf, GFPARM_RMODE_STD); carName = GfParmGetName(carparam); printed = 0; snprintf(path, BUFSIZE, "%s/%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK); nCars = GfParmGetEltNb(results, path); nCars = MIN(nCars + 1, maxLines); for (i = 1; i < nCars; i++) { snprintf(path, BUFSIZE, "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, i); if (!printed) { if ((car->_bestLapTime != 0.0) && (car->_bestLapTime < GfParmGetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, 0))) { snprintf(buf, BUFSIZE, "%d - %s - %s (%s)", i, GfTime2Str(car->_bestLapTime, 0), car->_name, carName); ReResScreenSetText(buf, i - 1, 1); printed = 1; } } snprintf(buf, BUFSIZE, "%d - %s - %s (%s)", i + printed, GfTime2Str(GfParmGetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, 0), 0), GfParmGetStr(results, path, RE_ATTR_NAME, ""), GfParmGetStr(results, path, RE_ATTR_CAR, "")); ReResScreenSetText(buf, i - 1 + printed, 0); } if (!printed) { snprintf(buf, BUFSIZE, "%d - %s - %s (%s)", i, GfTime2Str(car->_bestLapTime, 0), car->_name, carName); ReResScreenSetText(buf, i - 1, 1); } GfParmReleaseHandle(carparam); ReInfo->_refreshDisplay = 1; }
/** * This function shows the pit menu and let the user fill in the amount * of fuel he wants and the number of damage he want to repair * * @param car The current car (pitcmd is modified on user decisions) * @param s The current situation (used to calculate the remaining time) * @param callback The function which is called after the user made a decision */ void RmPitMenuStart(tCarElt *car, tSituation *s, tfuiCallback callback) { char buf[128]; rmCar = car; rmCallback = callback; if (menuHandle) GfuiScreenRelease(menuHandle); GfLogInfo("Entering Pit menu\n"); // Create screen, load menu XML descriptor and create static controls. menuHandle = GfuiScreenCreate(NULL, NULL, NULL, NULL, NULL, 1); void *menuXMLDescHdle = GfuiMenuLoad("pitmenu.xml"); GfuiMenuCreateStaticControls(menuHandle, menuXMLDescHdle); // Create variable title label. int titleId = GfuiMenuCreateLabelControl(menuHandle, menuXMLDescHdle, "titlelabel"); snprintf(buf, sizeof(buf), "Pit Stop for %s", car->_name); GfuiLabelSetText(menuHandle, titleId, buf); // Create labels for remaining laps and remaining fuel. int remainLapsTimeId = GfuiMenuCreateLabelControl(menuHandle, menuXMLDescHdle, "remaininglapstimelabel"); if( s->_totTime > 0 && s->_totTime > s->currentTime ) // Timed part of the timed session { GfuiMenuCreateLabelControl(menuHandle, menuXMLDescHdle, "remainingtimelabel"); if( s->_extraLaps > 0) snprintf(buf, sizeof(buf), "%s + %d laps", GfTime2Str( s->_totTime - s->currentTime, NULL, true, 0 ), s->_extraLaps); else snprintf(buf, sizeof(buf), "%s", GfTime2Str( s->_totTime - s->currentTime, NULL, true, 0 ) ); } else { GfuiMenuCreateLabelControl(menuHandle, menuXMLDescHdle, "remaininglapslabel"); snprintf(buf, sizeof(buf), "%d", car->_remainingLaps); //Laps tot drive to win the race } GfuiLabelSetText(menuHandle, remainLapsTimeId, buf); int remainFuelId = GfuiMenuCreateLabelControl(menuHandle, menuXMLDescHdle, "remainingfuellabel"); snprintf(buf, sizeof(buf), "%.1f", car->_fuel); GfuiLabelSetText(menuHandle, remainFuelId, buf); // Create edit boxes for fuel and repair amounts. fuelId = GfuiMenuCreateEditControl(menuHandle, menuXMLDescHdle, "fuelamountedit", NULL, NULL, rmUpdtFuel); snprintf(buf, sizeof(buf), "%.1f", car->pitcmd.fuel); GfuiEditboxSetString(menuHandle, fuelId, buf); repairId = GfuiMenuCreateEditControl(menuHandle, menuXMLDescHdle, "repairamountedit", NULL, NULL, rmUpdtRepair); snprintf(buf, sizeof(buf), "%d", (int)car->pitcmd.repair); GfuiEditboxSetString(menuHandle, repairId, buf); // Create Repair and Stop&Go buttons. GfuiMenuCreateButtonControl(menuHandle, menuXMLDescHdle, "repairbutton", NULL, rmRepair); GfuiMenuCreateButtonControl(menuHandle, menuXMLDescHdle, "stopgobutton", NULL, rmStopAndGo); // Close menu XML descriptor. GfParmReleaseHandle(menuXMLDescHdle); // Register keyboard shortcuts. GfuiMenuDefaultKeysAdd(menuHandle); // Activate the created screen. GfuiScreenActivate(menuHandle); }
static void rmPracticeResults(void *prevHdle, tRmInfo *info, int start) { // Used across rmPracticeResults calls when multiple pages. static int NLastLapDamages = 0; void *results = info->results; const char *race = info->_reRaceName; int i; int y; static char buf[256]; static char path[1024]; char *str; int damages; // Create screen, load menu XML descriptor and create static controls. rmScrHdle = GfuiScreenCreate(); GfLogTrace("Entering Practice Results menu\n"); void *hmenu = GfuiMenuLoad("practiceresultsmenu.xml"); GfuiMenuCreateStaticControls(rmScrHdle, hmenu); // Create variable title labels. snprintf(buf, sizeof(buf), "%s at %s", race, info->track->name); const int titleId = GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "Title"); GfuiLabelSetText(rmScrHdle, titleId, buf); snprintf(path, sizeof(path), "%s/%s/%s", info->track->name, RE_SECT_RESULTS, race); snprintf(buf, sizeof(buf), "%s (%s)", GfParmGetStr(results, path, RM_ATTR_DRVNAME, NULL), GfParmGetStr(results, path, RM_ATTR_CAR, NULL)); const int subTitleId = GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "SubTitle"); GfuiLabelSetText(rmScrHdle, subTitleId, buf); // Get layout properties. const int nMaxLines = (int)GfuiMenuGetNumProperty(hmenu, "nMaxResultLines", 15); const int yTopLine = (int)GfuiMenuGetNumProperty(hmenu, "yTopLine", 400); const int yLineShift = (int)GfuiMenuGetNumProperty(hmenu, "yLineShift", 20); // Display the result table. y = yTopLine; snprintf(path, sizeof(path), "%s/%s/%s", info->track->name, RE_SECT_RESULTS, race); const int totLaps = (int)GfParmGetEltNb(results, path); // Reset last damage value if top of the table. if (start == 0) NLastLapDamages = 0; else { snprintf(path, sizeof(path), "%s/%s/%s/%d", info->track->name, RE_SECT_RESULTS, race, start - 1); NLastLapDamages = (int)(GfParmGetNum(results, path, RE_ATTR_DAMMAGES, NULL, 0)); } for (i = 0 + start; i < MIN(start + nMaxLines, totLaps); i++) { snprintf(path, sizeof(path), "%s/%s/%s/%d", info->track->name, RE_SECT_RESULTS, race, i + 1); /* Lap */ snprintf(buf, sizeof(buf), "%d", i+1); GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "LapNumber", true, // From template. buf, GFUI_TPL_X, y); /* Time */ str = GfTime2Str(GfParmGetNum(results, path, RE_ATTR_TIME, NULL, 0), " ", false, 3); GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "LapTime", true, // From template. str, GFUI_TPL_X, y); free(str); /* Best Lap Time */ str = GfTime2Str(GfParmGetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, 0), " ", false, 3); GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "BestTime", true, // From template. str, GFUI_TPL_X, y); free(str); /* Top Spd */ snprintf(buf, sizeof(buf), "%3.1f", (GfParmGetNum(results, path, RE_ATTR_TOP_SPEED, NULL, 0) * 3.6)); GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "TopSpeed", true, // From template. buf, GFUI_TPL_X, y); /* Min Spd */ snprintf(buf, sizeof(buf), "%3.1f", (GfParmGetNum(results, path, RE_ATTR_BOT_SPEED, NULL, 0) * 3.6)); GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "MinSpeed", true, // From template. buf, GFUI_TPL_X, y); /* Damages in current lap + (total so far) */ damages = (int)(GfParmGetNum(results, path, RE_ATTR_DAMMAGES, NULL, 0)); snprintf(buf, sizeof(buf), "%d (%d)", damages ? damages - NLastLapDamages : 0, damages); GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "Damages", true, // From template. buf, GFUI_TPL_X, y); NLastLapDamages = damages; y -= yLineShift; } if (start > 0) { RmPrevRace.prevHdle = prevHdle; RmPrevRace.info = info; RmPrevRace.start = start - nMaxLines; GfuiMenuCreateButtonControl(rmScrHdle, hmenu, "PreviousPageArrow", (void*)&RmPrevRace, rmChgPracticeScreen); GfuiAddKey(rmScrHdle, GFUIK_PAGEUP, "Previous Results", (void*)&RmPrevRace, rmChgPracticeScreen, NULL); } // Add "Continue" button GfuiMenuCreateButtonControl(rmScrHdle, hmenu, "ContinueButton", prevHdle, GfuiScreenReplace); //Create 'save' button in the bottom right //rmSaveButtonId = GfuiMenuCreateButtonControl(rmScrHdle, hmenu, "SaveButton", info, rmSaveRes); if (i < totLaps) { RmNextRace.prevHdle = prevHdle; RmNextRace.info = info; RmNextRace.start = start + nMaxLines; GfuiMenuCreateButtonControl(rmScrHdle, hmenu, "NextPageArrow", (void*)&RmNextRace, rmChgPracticeScreen); GfuiAddKey(rmScrHdle, GFUIK_PAGEDOWN, "Next Results", (void*)&RmNextRace, rmChgPracticeScreen, NULL); } GfuiAddKey(rmScrHdle, GFUIK_ESCAPE, "Continue", prevHdle, GfuiScreenReplace, NULL); GfuiAddKey(rmScrHdle, GFUIK_RETURN, "Continue", prevHdle, GfuiScreenReplace, NULL); GfuiAddKey(rmScrHdle, GFUIK_F12, "Take a Screen Shot", NULL, GfuiScreenShot, NULL); GfuiAddKey(rmScrHdle, GFUIK_F1, "Help", rmScrHdle, GfuiHelpScreen, NULL); GfuiScreenActivate(rmScrHdle); }
static void rmQualifResults(void *prevHdle, tRmInfo *info, const char* pszTitle, int start) { void *results = info->results; const char *race = info->_reRaceName; int i; static char buf[256]; static char path[512]; char *str; GfLogTrace("Entering %s Results menu\n", pszTitle); // Create screen, load menu XML descriptor and create static controls. rmScrHdle = GfuiScreenCreate(); void *hmenu = GfuiMenuLoad("qualifsresultsmenu.xml"); GfuiMenuCreateStaticControls(rmScrHdle, hmenu); // Create variable title label. const int titleId = GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "Title"); snprintf(buf, sizeof(buf), "%s at %s", race, info->track->name); GfuiLabelSetText(rmScrHdle, titleId, buf); // Get layout properties. const int nMaxLines = (int)GfuiMenuGetNumProperty(hmenu, "nMaxResultLines", 15); const int yTopLine = (int)GfuiMenuGetNumProperty(hmenu, "yTopLine", 400); const int yLineShift = (int)GfuiMenuGetNumProperty(hmenu, "yLineShift", 20); // Never used : remove ? //snprintf(path, sizeof(path), "%s/%s/%s/%s/%d", info->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, 1); //tdble refTime = GfParmGetNum(results, path, RE_ATTR_TIME, NULL, 0); //snprintf(path, sizeof(path), "%s/%s/%s", info->track->name, RE_SECT_RESULTS, race); //const int totLaps = (int)GfParmGetNum(results, path, RE_ATTR_LAPS, NULL, 0); snprintf(path, sizeof(path), "%s/%s/%s/%s", info->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK); const int nbCars = (int)GfParmGetEltNb(results, path); GfLogDebug("rmQualifResults: path=%s, file=%s\n", path, GfParmGetFileName(results)); GfLogDebug("rmQualifResults: start=%d, nbCars=%d, nMaxLines=%d\n", start, nbCars, nMaxLines); int y = yTopLine; for (i = start; i < MIN(start + nMaxLines, nbCars); i++) { snprintf(path, sizeof(path), "%s/%s/%s/%s/%d", info->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, i + 1); // Never used : remove ? //const int laps = (int)GfParmGetNum(results, path, RE_ATTR_LAPS, NULL, 0); //Rank snprintf(buf, sizeof(buf), "%d", i+1); GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "Rank", true, // From template. buf, GFUI_TPL_X, y); //Driver short name GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "DriverName", true, // From template. GfParmGetStr(results, path, RE_ATTR_SNAME, ""), GFUI_TPL_X, y); //Driver type const std::string strModName = GfParmGetStr(results, path, RE_ATTR_MODULE, ""); GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "DriverType", true, // From template. GfDriver::getType(strModName).c_str(), GFUI_TPL_X, y); //Car GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "CarModel", true, // From template. GfParmGetStr(results, path, RE_ATTR_CAR, ""), GFUI_TPL_X, y); //Best lap str = GfTime2Str(GfParmGetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, 0), 0, false, 3); GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "BestLapTime", true, // From template. str, GFUI_TPL_X, y); free(str); // Next line. y -= yLineShift; }//for i if (start > 0) { RmPrevRace.prevHdle = prevHdle; RmPrevRace.info = info; RmPrevRace.start = start - nMaxLines; RmPrevRace.title = pszTitle; GfuiMenuCreateButtonControl(rmScrHdle, hmenu, "PreviousPageArrow", (void*)&RmPrevRace, rmChgQualifScreen); GfuiAddKey(rmScrHdle, GFUIK_PAGEUP, "Previous Results", (void*)&RmPrevRace, rmChgQualifScreen, NULL); } // Add "Continue" button GfuiMenuCreateButtonControl(rmScrHdle, hmenu, "ContinueButton", prevHdle, GfuiScreenReplace); //Create 'save' button in the bottom right //rmSaveButtonId = GfuiMenuCreateButtonControl(rmScrHdle, hmenu, "savebutton", info, rmSaveRes); if (i < nbCars) { RmNextRace.prevHdle = prevHdle; RmNextRace.info = info; RmNextRace.start = start + nMaxLines; RmNextRace.title = pszTitle; GfuiMenuCreateButtonControl(rmScrHdle, hmenu, "NextPageArrow", (void*)&RmNextRace, rmChgQualifScreen); GfuiAddKey(rmScrHdle, GFUIK_PAGEDOWN, "Next Results", (void*)&RmNextRace, rmChgQualifScreen, NULL); } GfuiAddKey(rmScrHdle, GFUIK_ESCAPE, "Continue", prevHdle, GfuiScreenReplace, NULL); GfuiAddKey(rmScrHdle, GFUIK_RETURN, "Continue", prevHdle, GfuiScreenReplace, NULL); GfuiAddKey(rmScrHdle, GFUIK_F12, "Take a Screen Shot", NULL, GfuiScreenShot, NULL); GfuiAddKey(rmScrHdle, GFUIK_F1, "Help", rmScrHdle, GfuiHelpScreen, NULL); GfuiScreenActivate(rmScrHdle); }
static void rmRaceResults(void *prevHdle, tRmInfo *info, int start) { void *results = info->results; const char *race = info->_reRaceName; static char buf[256]; static char path[512]; char *str; GfLogTrace("Entering Race Results menu\n"); // Create screen, load menu XML descriptor and create static controls. rmScrHdle = GfuiScreenCreate(); void *hmenu = GfuiMenuLoad("raceresultsmenu.xml"); GfuiMenuCreateStaticControls(rmScrHdle, hmenu); // Create variable title label. snprintf(buf, sizeof(buf), "%s at %s", race, info->track->name); const int titleId = GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "Title"); GfuiLabelSetText(rmScrHdle, titleId, buf); // Get layout properties. const int nMaxLines = (int)GfuiMenuGetNumProperty(hmenu, "nMaxResultLines", 15); const int yTopLine = (int)GfuiMenuGetNumProperty(hmenu, "yTopLine", 400); const int yLineShift = (int)GfuiMenuGetNumProperty(hmenu, "yLineShift", 20); const GfuiColor cPlaceGain = GfuiColor::build(GfuiMenuGetStrProperty(hmenu, "colorGainedPlaces", "0x32CD32")); const float* acPlaceGain = cPlaceGain.toFloatRGBA(); const GfuiColor cPlaceLoss = GfuiColor::build(GfuiMenuGetStrProperty(hmenu, "colorLostPlaces", "0xF28500")); const float* acPlaceLoss = cPlaceLoss.toFloatRGBA(); // Never used : remove ? //Get total laps, winner time //snprintf(path, sizeof(path), "%s/%s/%s", info->track->name, RE_SECT_RESULTS, race); //int totLaps = (int)GfParmGetNum(results, path, RE_ATTR_LAPS, NULL, 0); //snprintf(path, sizeof(path), "%s/%s/%s/%s/%d", info->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, 1); //tdble refTime = GfParmGetNum(results, path, RE_ATTR_TIME, NULL, 0); //Get number of cars snprintf(path, sizeof(path), "%s/%s/%s/%s", info->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK); int nbCars = (int)GfParmGetEltNb(results, path); // Display the result table. int y = yTopLine; int i; for (i = start; i < MIN(start + nMaxLines, nbCars); i++) { snprintf(path, sizeof(path), "%s/%s/%s/%s/%d", info->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, i + 1); int laps = (int)GfParmGetNum(results, path, RE_ATTR_LAPS, NULL, 0);//Laps covered //Rank snprintf(buf, sizeof(buf), "%d", i+1); GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "Rank", true, // From template. buf, GFUI_TPL_X, y); //Advance (The num.attrib 'index' holds the starting position) int advance = (int)(GfParmGetNum(results, path, RE_ATTR_INDEX, NULL, 0)) - i; snprintf(buf, sizeof(buf), "%d", advance); const float *aColor = advance > 0 ? acPlaceGain : (advance < 0 ? acPlaceLoss : GFUI_TPL_COLOR); GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "Advance", true, // From template. buf, GFUI_TPL_X, y, GFUI_TPL_FONTID, GFUI_TPL_WIDTH, GFUI_TPL_ALIGN, GFUI_TPL_MAXLEN, aColor); //Driver short name GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "DriverName", true, // From template. GfParmGetStr(results, path, RE_ATTR_SNAME, ""), GFUI_TPL_X, y); //Driver type const std::string strModName = GfParmGetStr(results, path, RE_ATTR_MODULE, ""); GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "DriverType", true, // From template. GfDriver::getType(strModName).c_str(), GFUI_TPL_X, y); //Car GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "CarModel", true, // From template. GfParmGetStr(results, path, RE_ATTR_CAR, ""), GFUI_TPL_X, y); //Total Time str = GfTime2Str(GfParmGetNum(results, path, RE_ATTR_TIME, NULL, 0), 0, false, 3); GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "TotalTime", true, // From template. str, GFUI_TPL_X, y); free(str); //Best lap str = GfTime2Str(GfParmGetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, 0), 0, false, 3); GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "BestLapTime", true, // From template. str, GFUI_TPL_X, y); free(str); //Laps covered snprintf(buf, sizeof(buf), "%d", laps); GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "Laps", true, // From template. buf, GFUI_TPL_X, y); //Top speed snprintf(buf, sizeof(buf), "%3.1f", (GfParmGetNum(results, path, RE_ATTR_TOP_SPEED, NULL, 0) * 3.6)); GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "TopSpeed", true, // From template. buf, GFUI_TPL_X, y); //Damage snprintf(buf, sizeof(buf), "%d", (int)(GfParmGetNum(results, path, RE_ATTR_DAMMAGES, NULL, 0))); GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "Damages", true, // From template. buf, GFUI_TPL_X, y); //Pitstops snprintf(buf, sizeof(buf), "%d", (int)(GfParmGetNum(results, path, RE_ATTR_NB_PIT_STOPS, NULL, 0))); GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "Pits", true, // From template. buf, GFUI_TPL_X, y); y -= yLineShift; //Line feed }//for i //If it is not the first screen of the results, show a 'Prev' button if (start > 0) { RmPrevRace.prevHdle = prevHdle; RmPrevRace.info = info; RmPrevRace.start = start - nMaxLines; GfuiMenuCreateButtonControl(rmScrHdle, hmenu, "PreviousPageArrow", (void*)&RmPrevRace, rmChgRaceScreen); GfuiAddKey(rmScrHdle, GFUIK_PAGEUP, "Previous Results", (void*)&RmPrevRace, rmChgRaceScreen, NULL); }//if start // Add "Continue" button GfuiMenuCreateButtonControl(rmScrHdle, hmenu, "ContinueButton", prevHdle, GfuiScreenReplace); //Create 'save' button in the bottom right //rmSaveButtonId = GfuiMenuCreateButtonControl(rmScrHdle, hmenu, "SaveButton", info, rmSaveRes); //If we did not display all the results yet, let's show a 'Next' button if (i < nbCars) { RmNextRace.prevHdle = prevHdle; RmNextRace.info = info; RmNextRace.start = start + nMaxLines; GfuiMenuCreateButtonControl(rmScrHdle, hmenu, "NextPageArrow", (void*)&RmNextRace, rmChgRaceScreen); GfuiAddKey(rmScrHdle, GFUIK_PAGEDOWN, "Next Results", (void*)&RmNextRace, rmChgRaceScreen, NULL); }//if i //Link key handlers GfuiAddKey(rmScrHdle, GFUIK_ESCAPE, "Continue", prevHdle, GfuiScreenReplace, NULL); GfuiAddKey(rmScrHdle, GFUIK_RETURN, "Continue", prevHdle, GfuiScreenReplace, NULL); GfuiAddKey(rmScrHdle, GFUIK_F12, "Take a Screen Shot", NULL, GfuiScreenShot, NULL); GfuiAddKey(rmScrHdle, GFUIK_F1, "Help", rmScrHdle, GfuiHelpScreen, NULL); //Show! GfuiScreenActivate(rmScrHdle); }//rmRaceResults
void ReUpdateRaceCurRes() { static const char* pszTableHeader = "Rank \tTime \tDriver \tCar"; int ncars; int xx; void *carparam; char *carName; tCarElt *car; char *tmp_str; double time_left; ncars = ReInfo->s->_ncars; if (ncars > ReUI().getResultsTableRowCount()) ncars = ReUI().getResultsTableRowCount(); char pszTitle[128]; snprintf(pszTitle, sizeof(pszTitle), "%s at %s", ReInfo->_reRaceName, ReInfo->track->name); if (ReInfo->s->_totTime > ReInfo->s->currentTime) { time_left = ReInfo->s->_totTime - ReInfo->s->currentTime; snprintf( buf, sizeof(buf), "%d:%02d:%02d", (int)floor( time_left / 3600.0f ), (int)floor( time_left / 60.0f ) % 60, (int)floor( time_left ) % 60 ); } else { snprintf( buf, sizeof(buf), "%d laps", ReInfo->s->_totLaps ); } ReUI().setResultsTableTitles(pszTitle, buf); ReUI().setResultsTableHeader(pszTableHeader); for (xx = 0; xx < ncars; ++xx) { car = ReInfo->s->cars[ xx ]; snprintf(buf, sizeof(buf), "cars/models/%s/%s.xml", car->_carName, car->_carName); carparam = GfParmReadFile(buf, GFPARM_RMODE_STD); carName = strdup(GfParmGetName(carparam)); GfParmReleaseHandle(carparam); if (car->_state & RM_CAR_STATE_DNF) { snprintf(buf, sizeof(buf), "out %-20s %-20s", car->_name, carName); } else if (car->_timeBehindLeader == 0.0f) { if (xx != 0) snprintf(buf, sizeof(buf), " %2d \t --:--- \t%-25s \t%-20s", xx + 1, car->_name, carName); else snprintf(buf, sizeof(buf), " %2d \t%3d laps \t%-25s \t%-20s", xx + 1, car->_laps - 1, car->_name, carName); } else { if (xx == 0) { snprintf(buf, sizeof(buf), " %2d \t%3d laps \t%-25s \t%-20s", xx + 1, car->_laps - 1, car->_name, carName); } else { if (car->_lapsBehindLeader == 0) { tmp_str = GfTime2Str(car->_timeBehindLeader, " ", false, 3); snprintf(buf, sizeof(buf), " %2d \t%-12s\t%-25s \t%-20s", xx + 1, tmp_str, car->_name, carName); free(tmp_str); } else if (car->_lapsBehindLeader == 1) snprintf(buf, sizeof(buf), " %2d \t 1 lap \t%-25s \t%-20s", xx + 1, car->_name, carName); else snprintf(buf, sizeof(buf), " %2d \t %3d laps \t%-25s \t%-20s", xx + 1, car->_lapsBehindLeader, car->_name, carName); } } ReUI().setResultsTableRow(xx, buf); FREEZ(carName); } }
void ReUpdateQualifCurRes(tCarElt *car) { static const char* pszTableHeader = "Rank \tTime \tDriver \tCar"; int i; int xx; int nCars; int nCarsReal; int printed; int maxLines; void *carparam; char *carName; const char *race = ReInfo->_reRaceName; void *results = ReInfo->results; char *tmp_str; double time_left; if (ReInfo->s->_ncars == 1) { ReUI().eraseResultsTable(); maxLines = ReUI().getResultsTableRowCount(); snprintf(buf, sizeof(buf), "cars/models/%s/%s.xml", car->_carName, car->_carName); carparam = GfParmReadFile(buf, GFPARM_RMODE_STD); carName = GfParmGetName(carparam); char pszTitle[128]; snprintf(pszTitle, sizeof(pszTitle), "%s at %s", race, ReInfo->track->name); if (ReInfo->s->_raceType == RM_TYPE_PRACTICE || car->_laps < 1 || car->_laps > ReInfo->s->_totLaps) snprintf(buf, sizeof(buf), "%s (%s)", car->_name, carName); else snprintf(buf, sizeof(buf), "%s (%s) - Lap %d", car->_name, carName, car->_laps); ReUI().setResultsTableTitles(pszTitle, buf); ReUI().setResultsTableHeader(pszTableHeader); printed = 0; snprintf(path, sizeof(path), "%s/%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK); nCarsReal = GfParmGetEltNb(results, path); nCars = MIN(nCarsReal + 1, maxLines); // limit display to only those on 1st page for (i = 1; i < nCars; i++) { snprintf(path, sizeof(path), "%s/%s/%s/%s/%d", ReInfo->track->name, RE_SECT_RESULTS, race, RE_SECT_RANK, i); if (!printed && car->_bestLapTime != 0.0 && car->_bestLapTime < GfParmGetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, 0)) { tmp_str = GfTime2Str(car->_bestLapTime, " ", false, 3); snprintf(buf, sizeof(buf), " %2d \t%-12s \t%-25s \t%-20s", i, tmp_str, car->_name, carName); free(tmp_str); ReUI().setResultsTableRow(i - 1, buf, /*highlight=*/true); printed = 1; } tmp_str = GfTime2Str(GfParmGetNum(results, path, RE_ATTR_BEST_LAP_TIME, NULL, 0), " ", false, 3); snprintf(buf, sizeof(buf), " %2d \t%-12s \t%-25s \t%-20s", i + printed, tmp_str, GfParmGetStr(results, path, RE_ATTR_NAME, ""), GfParmGetStr(results, path, RE_ATTR_CAR, "")); free (tmp_str); ReUI().setResultsTableRow(i - 1 + printed, buf); } if (!printed) { tmp_str = GfTime2Str(car->_bestLapTime, " ", false, 3); snprintf(buf, sizeof(buf), " %2d \t%-12s \t%-25s \t%-20s", nCarsReal + 1, tmp_str, car->_name, carName); free(tmp_str); ReUI().setResultsTableRow(i - 1, buf, /*highlight=*/true); } GfParmReleaseHandle(carparam); } else { nCars = ReInfo->s->_ncars; if (nCars > ReUI().getResultsTableRowCount()) nCars = ReUI().getResultsTableRowCount(); char pszTitle[128]; snprintf(pszTitle, sizeof(pszTitle), "%s at %s", race, ReInfo->track->name); if (ReInfo->s->_totTime > ReInfo->s->currentTime) { time_left = ReInfo->s->_totTime - ReInfo->s->currentTime; snprintf( buf, sizeof(buf), "%d:%02d:%02d", (int)floor( time_left / 3600.0f ), (int)floor( time_left / 60.0f ) % 60, (int)floor( time_left ) % 60 ); } else { snprintf( buf, sizeof(buf), "%d laps", ReInfo->s->_totLaps ); } ReUI().setResultsTableTitles(pszTitle, buf); ReUI().setResultsTableHeader(pszTableHeader); for (xx = 0; xx < nCars; ++xx) { car = ReInfo->s->cars[ xx ]; snprintf(buf, sizeof(buf), "cars/models/%s/%s.xml", car->_carName, car->_carName); carparam = GfParmReadFile(buf, GFPARM_RMODE_STD); carName = strdup(GfParmGetName(carparam)); GfParmReleaseHandle(carparam); if (car->_state & RM_CAR_STATE_DNF) { snprintf(buf, sizeof(buf), "out \t \t%-25s \t%-20s", car->_name, carName); } else if (car->_bestLapTime <= 0.0f) { snprintf(buf, sizeof(buf), " %2d \t --:--- \t%-25s \t%-20s", xx + 1, car->_name, carName); } else { if (xx == 0) tmp_str = GfTime2Str(car->_bestLapTime, " ", false, 3); else tmp_str = GfTime2Str(car->_bestLapTime - ReInfo->s->cars[0]->_bestLapTime, "+", false, 3); snprintf(buf, sizeof(buf), " %2d \t%-12s \t%-25s \t%-20s", xx + 1, tmp_str, car->_name, carName); free(tmp_str); } ReUI().setResultsTableRow(xx, buf); FREEZ(carName); } } }
static void ReManage(tCarElt *car) { int i, pitok; tTrackSeg *sseg; tdble wseg; static float color[] = {0.0, 0.0, 1.0, 1.0}; tSituation *s = ReInfo->s; tReCarInfo *info = &(ReInfo->_reCarInfo[car->index]); if (car->_speed_x > car->_topSpeed) { car->_topSpeed = car->_speed_x; } // For practice and qualif. if (car->_speed_x > info->topSpd) { info->topSpd = car->_speed_x; } if (car->_speed_x < info->botSpd) { info->botSpd = car->_speed_x; } // Pitstop. if (car->_pit) { if (car->ctrl.raceCmd & RM_CMD_PIT_ASKED) { // Pit already occupied? if (car->_pit->pitCarIndex == TR_PIT_STATE_FREE) { sprintf(car->ctrl.msg[2], "Can Pit"); } else { sprintf(car->ctrl.msg[2], "Pit Occupied"); } memcpy(car->ctrl.msgColor, color, sizeof(car->ctrl.msgColor)); } if (car->_state & RM_CAR_STATE_PIT) { car->ctrl.raceCmd &= ~RM_CMD_PIT_ASKED; // clear the flag. if (car->_scheduledEventTime < s->currentTime) { car->_state &= ~RM_CAR_STATE_PIT; car->_pit->pitCarIndex = TR_PIT_STATE_FREE; sprintf(buf, "%s pit stop %.1fs", car->_name, info->totalPitTime); ReRaceMsgSet(buf, 5); } else { sprintf(car->ctrl.msg[2], "in pits %.1fs", s->currentTime - info->startPitTime); } } else if ((car->ctrl.raceCmd & RM_CMD_PIT_ASKED) && car->_pit->pitCarIndex == TR_PIT_STATE_FREE && (s->_maxDammage == 0 || car->_dammage <= s->_maxDammage)) { tdble lgFromStart = car->_trkPos.seg->lgfromstart; switch (car->_trkPos.seg->type) { case TR_STR: lgFromStart += car->_trkPos.toStart; break; default: lgFromStart += car->_trkPos.toStart * car->_trkPos.seg->radius; break; } if ((lgFromStart > car->_pit->lmin) && (lgFromStart < car->_pit->lmax)) { pitok = 0; int side; tdble toBorder; if (ReInfo->track->pits.side == TR_RGT) { side = TR_SIDE_RGT; toBorder = car->_trkPos.toRight; } else { side = TR_SIDE_LFT; toBorder = car->_trkPos.toLeft; } sseg = car->_trkPos.seg->side[side]; wseg = RtTrackGetWidth(sseg, car->_trkPos.toStart); if (sseg->side[side]) { sseg = sseg->side[side]; wseg += RtTrackGetWidth(sseg, car->_trkPos.toStart); } if (((toBorder + wseg) < (ReInfo->track->pits.width - car->_dimension_y / 2.0)) && (fabs(car->_speed_x) < 1.0) && (fabs(car->_speed_y) < 1.0)) { pitok = 1; } if (pitok) { car->_state |= RM_CAR_STATE_PIT; car->_nbPitStops++; for (i = 0; i < car->_pit->freeCarIndex; i++) { if (car->_pit->car[i] == car) { car->_pit->pitCarIndex = i; break; } } info->startPitTime = s->currentTime; sprintf(buf, "%s in pits", car->_name); ReRaceMsgSet(buf, 5); if (car->robot->rbPitCmd(car->robot->index, car, s) == ROB_PIT_MENU) { // the pit cmd is modified by menu. ReStop(); RmPitMenuStart(car, (void*)car, ReUpdtPitCmd); } else { ReUpdtPitTime(car); } } } } } /* Start Line Crossing */ if (info->prevTrkPos.seg != car->_trkPos.seg) { if ((info->prevTrkPos.seg->raceInfo & TR_LAST) && (car->_trkPos.seg->raceInfo & TR_START)) { if (info->lapFlag == 0) { if ((car->_state & RM_CAR_STATE_FINISH) == 0) { car->_laps++; car->_remainingLaps--; if (car->_laps > 1) { car->_lastLapTime = s->currentTime - info->sTime; car->_curTime += car->_lastLapTime; if (car->_bestLapTime != 0) { car->_deltaBestLapTime = car->_lastLapTime - car->_bestLapTime; } if ((car->_lastLapTime < car->_bestLapTime) || (car->_bestLapTime == 0)) { car->_bestLapTime = car->_lastLapTime; } if (car->_pos != 1) { car->_timeBehindLeader = car->_curTime - s->cars[0]->_curTime; car->_lapsBehindLeader = s->cars[0]->_laps - car->_laps; car->_timeBehindPrev = car->_curTime - s->cars[car->_pos - 2]->_curTime; s->cars[car->_pos - 2]->_timeBeforeNext = car->_timeBehindPrev; } else { car->_timeBehindLeader = 0; car->_lapsBehindLeader = 0; car->_timeBehindPrev = 0; } info->sTime = s->currentTime; switch (ReInfo->s->_raceType) { case RM_TYPE_PRACTICE: if (ReInfo->_displayMode == RM_DISP_MODE_NONE) { ReInfo->_refreshDisplay = 1; char *t1, *t2; t1 = GfTime2Str(car->_lastLapTime, 0); t2 = GfTime2Str(car->_bestLapTime, 0); sprintf(buf,"lap: %02d time: %s best: %s top spd: %.2f min spd: %.2f damage: %d", car->_laps - 1, t1, t2, info->topSpd * 3.6, info->botSpd * 3.6, car->_dammage); ReResScreenAddText(buf); free(t1); free(t2); } /* save the lap result */ ReSavePracticeLap(car); break; case RM_TYPE_QUALIF: if (ReInfo->_displayMode == RM_DISP_MODE_NONE) { ReUpdateQualifCurRes(car); } break; } } else { if ((ReInfo->_displayMode == RM_DISP_MODE_NONE) && (ReInfo->s->_raceType == RM_TYPE_QUALIF)) { ReUpdateQualifCurRes(car); } } info->topSpd = car->_speed_x; info->botSpd = car->_speed_x; if ((car->_remainingLaps < 0) || (s->_raceState == RM_RACE_FINISHING)) { car->_state |= RM_CAR_STATE_FINISH; s->_raceState = RM_RACE_FINISHING; if (ReInfo->s->_raceType == RM_TYPE_RACE) { if (car->_pos == 1) { sprintf(buf, "Winner %s", car->_name); ReRaceBigMsgSet(buf, 10); } else { const char *numSuffix = "th"; if (abs(12 - car->_pos) > 1) { /* leave suffix as 'th' for 11 to 13 */ switch (car->_pos % 10) { case 1: numSuffix = "st"; break; case 2: numSuffix = "nd"; break; case 3: numSuffix = "rd"; break; default: break; } } sprintf(buf, "%s Finished %d%s", car->_name, car->_pos, numSuffix); ReRaceMsgSet(buf, 5); } } } } else { /* prevent infinite looping of cars around track, allow one lap after finish for the first car */ for (i = 0; i < s->_ncars; i++) { s->cars[i]->_state |= RM_CAR_STATE_FINISH; } return; } } else { info->lapFlag--; } } if ((info->prevTrkPos.seg->raceInfo & TR_START) && (car->_trkPos.seg->raceInfo & TR_LAST)) { /* going backward through the start line */ info->lapFlag++; } } ReRaceRules(car); info->prevTrkPos = car->_trkPos; car->_curLapTime = s->currentTime - info->sTime; car->_distFromStartLine = car->_trkPos.seg->lgfromstart + (car->_trkPos.seg->type == TR_STR ? car->_trkPos.toStart : car->_trkPos.toStart * car->_trkPos.seg->radius); car->_distRaced = (car->_laps - 1) * ReInfo->track->length + car->_distFromStartLine; }
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); }
static void rmQualifResults(void *prevHdle, tRmInfo *info, int start) { void *results = info->results; const char *race = info->_reRaceName; int i; int x1, x2, x3; 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 nbCars; int offset; rmScrHdle = GfuiScreenCreate(); snprintf(buf, BUFSIZE, "Qualification 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"); 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, "Time", fgcolor, GFUI_FONT_MEDIUM_C, x3, y, GFUI_ALIGN_HR_VB, 0); y -= 20; 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); 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); 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_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, rmChgQualifScreen, NULL, (tfuiCallback)NULL, (tfuiCallback)NULL); GfuiAddSKey(rmScrHdle, GLUT_KEY_PAGE_UP, "Previous Results", (void*)&RmPrevRace, rmChgQualifScreen, NULL); } GfuiButtonCreate(rmScrHdle, "Continue", GFUI_FONT_LARGE, 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, rmChgQualifScreen, NULL, (tfuiCallback)NULL, (tfuiCallback)NULL); GfuiAddSKey(rmScrHdle, GLUT_KEY_PAGE_DOWN, "Next Results", (void*)&RmNextRace, rmChgQualifScreen, 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); }
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); }