Example #1
0
// Generic function for creating and activating the menu.
static void*
rmStopRaceMenu(const tButtonDesc aButtons[], int nButtons, int nCancelIndex)
{
    // Create screen, load menu XML descriptor and create static controls.
    void *hscreen = GfuiScreenCreate(NULL, NULL, NULL, NULL, NULL, 1);

    void *hmenu = GfuiMenuLoad("stopracemenu.xml");

    GfuiMenuCreateStaticControls(hscreen, hmenu);

    // Create buttons from menu properties and button template.
    const int xpos = (int)GfuiMenuGetNumProperty(hmenu, "xButton", 270);
    const int dy = (int)GfuiMenuGetNumProperty(hmenu, "buttonShift", 30);
	int ypos = (int)GfuiMenuGetNumProperty(hmenu, "yTopButton", 380);
	char pszPropName[64];
	const char* pszCancelTip = "";
    for (int nButInd = 0; nButInd < nButtons; nButInd++)
    {
		// Get text and tip from button role and menu properties.
		sprintf(pszPropName, "%s.text", aButtons[nButInd].role);
		const char* pszText = GfuiMenuGetStrProperty(hmenu, pszPropName, "");
		sprintf(pszPropName, "%s.tip", aButtons[nButInd].role);
		const char* pszTip = GfuiMenuGetStrProperty(hmenu, pszPropName, "");
		if (nButInd == nCancelIndex)
			pszCancelTip = pszTip;
		
		// Create the button from the template.
		GfuiMenuCreateTextButtonControl(hscreen, hmenu, "button",
										aButtons[nButInd].screen, GfuiScreenActivate, 0, 0, 0,
										true, // From template.
										pszText, pszTip, xpos, ypos);

		// Next button if not last.
		ypos -= dy;
    }

    // Register keyboard shortcuts.
    GfuiMenuDefaultKeysAdd(hscreen);
    GfuiAddKey(hscreen, GFUIK_ESCAPE, pszCancelTip,
			   aButtons[nCancelIndex].screen, GfuiScreenActivate, NULL);

    // Close menu XML descriptor.
    GfParmReleaseHandle(hmenu);
    
    // Activate the created screen.
    GfuiScreenActivate(hscreen);

    return hscreen;
}
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*
RmResScreenInit()
{
	if (rmResScreenHdle)
		GfuiScreenRelease(rmResScreenHdle);

	tRmInfo* reInfo = LmRaceEngine().inData();

    // Create screen, load menu XML descriptor and create static controls.
    rmResScreenHdle = GfuiScreenCreate(black, 0, rmResScreenActivate, 0, rmResScreenDeactivate, 0);
    void *hmenu = GfuiMenuLoad("raceblindscreen.xml");
    GfuiMenuCreateStaticControls(rmResScreenHdle, hmenu);

    // Create variable main title (race session) label.
    rmResTitleId = GfuiMenuCreateLabelControl(rmResScreenHdle, hmenu, "Title");

    // Create background image if any specified.
    const char* img = GfParmGetStr(reInfo->params, RM_SECT_HEADER, RM_ATTR_RUNIMG, 0);
    if (img)
		GfuiScreenAddBgImg(rmResScreenHdle, img);
    
    // Create variable subtitle (driver and race name, lap number) label.
    rmResSubTitleId = GfuiMenuCreateLabelControl(rmResScreenHdle, hmenu, "SubTitle");

    // Create table header label.
    rmResHeaderId = GfuiMenuCreateLabelControl(rmResScreenHdle, hmenu, "Header");

	// Get layout properties, except for nMaxResultRows (see below).
    const int yTopRow = (int)GfuiMenuGetNumProperty(hmenu, "yTopRow", 400);
    const int yRowShift = (int)GfuiMenuGetNumProperty(hmenu, "yRowShift", 20);

	// Allocate row info arrays, if not already done.
	if (!rmResRowLabelId)
	{
		// Load nMaxResultRows/colors only the first time (ignore any later change,
		// otherwize, we'd have to realloc the row info arrays).
		rmNMaxResRows = (int)GfuiMenuGetNumProperty(hmenu, "nMaxResultRows", 20);
		const GfuiColor cNormal =
			GfuiColor::build(GfuiMenuGetStrProperty(hmenu, "rowColorNormal", "0x0000FF"));
		const GfuiColor cHighlighted =
			GfuiColor::build(GfuiMenuGetStrProperty(hmenu, "rowColorHighlighted", "0x00FF00"));
		memcpy(rmColors[0], cNormal.toFloatRGBA(), sizeof(rmColors[0]));
		memcpy(rmColors[1], cHighlighted.toFloatRGBA(), sizeof(rmColors[1]));
	
		rmResRowLabelId = (int*)calloc(rmNMaxResRows, sizeof(int));
		rmResRowText = (char**)calloc(rmNMaxResRows, sizeof(char*));
		rmResRowColor = (float**)calloc(rmNMaxResRows, sizeof(float*));
	}

    // Create result rows (1 label for each).
    int	y = yTopRow;
    for (int i = 0; i < rmNMaxResRows; i++)
	{
		freez(rmResRowText[i]);
		rmResRowColor[i] = rmColors[0];
		rmResRowLabelId[i] =
			GfuiMenuCreateLabelControl(rmResScreenHdle, hmenu, "Row", true, // from template
									   "", GFUI_TPL_X, y, GFUI_TPL_FONTID, GFUI_TPL_WIDTH,
									   GFUI_TPL_ALIGN, GFUI_TPL_MAXLEN, rmResRowColor[i]);
		y -= yRowShift;
    }

    // Close menu XML descriptor.
    GfParmReleaseHandle(hmenu);
    
    // Register keyboard shortcuts.
    GfuiAddKey(rmResScreenHdle, GFUIK_F1, "Help", rmResScreenHdle, GfuiHelpScreen, NULL);
    GfuiAddKey(rmResScreenHdle, GFUIK_F12, "Screen shot", NULL, GfuiScreenShot, NULL);

    GfuiAddKey(rmResScreenHdle, GFUIK_ESCAPE, "Stop current race",
			   (void*)RE_STATE_RACE_STOP, rmApplyState, NULL);
    GfuiAddKey(rmResScreenHdle, 'q', GFUIM_ALT, "Quit game now, save nothing",
			   (void*)RE_STATE_EXIT, rmApplyState, NULL);

    // Initialize current result row.
    rmCurRowIndex = 0;

    return rmResScreenHdle;
}