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);
	}
}
Exemple #2
0
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;
}
Exemple #10
0
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);
}
Exemple #11
0
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);
}
Exemple #12
0
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);
}