Re #396 Converted the starting grid menu, enhanced customizability of Results-Only race menu (and fixed the displayed car name) + some more menu layout tweaks + Fixes #235 (human drivers named as 'human' in the starting grid menu)

git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@3616 30fe4595-0a0c-4342-8851-515496e4dcbd

Former-commit-id: 8ce0b7dee034b5172becc85880d58c8f228870f2
Former-commit-id: 7c2347c3377c4daf8565646ca4656b1be5371306
This commit is contained in:
pouillot 2011-05-28 13:13:57 +00:00
parent d1b3b189f1
commit a242f1d150
6 changed files with 147 additions and 141 deletions

View file

@ -313,7 +313,11 @@ ReStoreRaceResults(const char *race)
car = s->cars[0];
sprintf(path, "%s/%s/%s", ReInfo->track->name, RE_SECT_RESULTS, race);
GfParmSetStr(results, path, RM_ATTR_DRVNAME, car->_name);
GfParmSetStr(results, path, RE_ATTR_CAR, car->_carName);
sprintf(buf, "cars/%s/%s.xml", car->_carName, car->_carName);
carparam = GfParmReadFile(buf, GFPARM_RMODE_STD);
carName = GfParmGetName(carparam);
GfParmSetStr(results, path, RE_ATTR_CAR, carName);
GfParmReleaseHandle(carparam);
break;
}
/* Otherwise, fall through */

View file

@ -434,19 +434,26 @@ const GfDriverSkin& GfDriver::getSkin() const
return _skin;
}
std::string GfDriver::getType(const std::string& strModName)
{
std::string strType;
// Parse module name for last '_' char : assumed to be the separator between type
// and instance name for ubiquitous robots (ex: simplix)
const size_t nTruncPos = strModName.rfind('_');
if (nTruncPos == std::string::npos)
strType = strModName; // Copy.
else
strType = strModName.substr(0, nTruncPos); // Copy + truncate.
return strType;
}
const std::string& GfDriver::getType() const
{
if (_strType.empty())
{
// Parse module name for last '_' char : assumed to be the separator between type
// and instance name for ubiquitous robots (ex: simplix)
size_t nTruncPos = _strModName.rfind('_');
if (nTruncPos == std::string::npos)
_strType = _strModName; // Copy.
else
_strType = _strModName.substr(0, nTruncPos); // Copy + truncate.
}
_strType = getType(_strModName);
return _strType;
}

View file

@ -85,6 +85,9 @@ public:
void setCar(const GfCar* pCar);
void setSkin(const GfDriverSkin& skin);
//! Compute a driver type from a driver module name.
static std::string getType(const std::string& strModName);
//! Get the possible skins using the same search path as the graphics engine.
std::vector<GfDriverSkin> getPossibleSkins(const std::string& strAltCarId = "") const;

View file

@ -26,6 +26,7 @@
#include <portability.h>
#include <tgfclient.h>
#include <drivers.h>
#include "racescreens.h"
@ -68,20 +69,6 @@ rmChgPracticeScreen(void *vprc)
GfuiScreenRelease(prevScr);
}
void rmGetDriverType(const char* moduleName, char* driverType, size_t maxSize)
{
char* pos;
strncpy(driverType, moduleName, maxSize);
driverType[maxSize-1] = 0; // Ensure 0 termination
// Parse module name for last '_' char :
// assumed to be the separator between type and instance name for ubiquitous robots (ex: simplix)
pos = strrchr(driverType, '_');
if (pos)
*pos = 0;
}
static void
rmPracticeResults(void *prevHdle, tRmInfo *info, int start)
{
@ -106,7 +93,7 @@ rmPracticeResults(void *prevHdle, tRmInfo *info, int start)
GfuiMenuCreateStaticControls(rmScrHdle, hmenu);
// Create variable title labels.
snprintf(buf, sizeof(buf), "Practice Results on %s", info->track->name);
snprintf(buf, sizeof(buf), "Practice Results at %s", info->track->name);
const int titleId = GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "Title");
GfuiLabelSetText(rmScrHdle, titleId, buf);
@ -114,7 +101,7 @@ rmPracticeResults(void *prevHdle, tRmInfo *info, int start)
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, "PlayerTitle");
const int subTitleId = GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "SubTitle");
GfuiLabelSetText(rmScrHdle, subTitleId, buf);
// Get layout properties.
@ -140,13 +127,13 @@ rmPracticeResults(void *prevHdle, tRmInfo *info, int start)
buf, GFUI_TPL_X, y);
/* Time */
str = GfTime2Str(GfParmGetNum(results, path, RE_ATTR_TIME, NULL, 0), " ", false, 2);;
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, 2);;
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);
@ -232,7 +219,7 @@ rmRaceResults(void *prevHdle, tRmInfo *info, int start)
// Create variable title label.
sprintf(buf, "%s", info->track->name);
const int subTitleId = GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "RaceTitle");
const int subTitleId = GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "SubTitle");
GfuiLabelSetText(rmScrHdle, subTitleId, buf);
// Get layout properties.
@ -283,9 +270,9 @@ rmRaceResults(void *prevHdle, tRmInfo *info, int start)
GfParmGetStr(results, path, RE_ATTR_NAME, ""), GFUI_TPL_X, y);
//Driver type
rmGetDriverType(GfParmGetStr(results, path, RE_ATTR_MODULE, ""), buf, sizeof(buf));
const std::string strModName = GfParmGetStr(results, path, RE_ATTR_MODULE, "");
GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "DriverType", true, // From template.
buf, GFUI_TPL_X, y);
GfDriver::getType(strModName).c_str(), GFUI_TPL_X, y);
//Car
GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "CarModel", true, // From template.
@ -391,7 +378,7 @@ rmQualifResults(void *prevHdle, tRmInfo *info, int start)
// Create variable title label.
sprintf(buf, "%s", info->track->name);
const int subTitleId = GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "RaceTitle");
const int subTitleId = GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "SubTitle");
GfuiLabelSetText(rmScrHdle, subTitleId, buf);
// Get layout properties.
@ -423,9 +410,9 @@ rmQualifResults(void *prevHdle, tRmInfo *info, int start)
GfParmGetStr(results, path, RE_ATTR_NAME, ""), GFUI_TPL_X, y);
//Driver type
rmGetDriverType(GfParmGetStr(results, path, RE_ATTR_MODULE, ""), buf, sizeof(buf));
const std::string strModName = GfParmGetStr(results, path, RE_ATTR_MODULE, "");
GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "DriverType", true, // From template.
buf, GFUI_TPL_X, y);
GfDriver::getType(strModName).c_str(), GFUI_TPL_X, y);
//Car
GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "CarModel", true, // From template.
@ -512,8 +499,8 @@ RmShowStandings(void *prevHdle, tRmInfo *info, int start)
// Create variable title label.
//Set title
sprintf(buf, "%s Standings", info->_reRaceName);
const int subTitleId = GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "RaceTitle");
GfuiLabelSetText(rmScrHdle, subTitleId, buf);
const int titleId = GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "Title");
GfuiLabelSetText(rmScrHdle, titleId, buf);
// Get layout properties.
const int nMaxLines = (int)GfuiMenuGetNumProperty(hmenu, "nMaxResultLines", 15);
@ -536,9 +523,9 @@ RmShowStandings(void *prevHdle, tRmInfo *info, int start)
GfParmGetStr(results, path, RE_ATTR_NAME, ""), GFUI_TPL_X, y);
//Driver type
rmGetDriverType(GfParmGetStr(results, path, RE_ATTR_MODULE, ""), buf, sizeof(buf));
const std::string strModName = GfParmGetStr(results, path, RE_ATTR_MODULE, "");
GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "DriverType", true, // From template.
buf, GFUI_TPL_X, y);
GfDriver::getType(strModName).c_str(), GFUI_TPL_X, y);
//Car
GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "CarModel", true, // From template.

View file

@ -466,11 +466,7 @@ RmHookInit()
/**************************************************************************
* Result only screen (blind mode)
*/
static const int NMaxResultLines = 21;
static float white[4] = {1.0, 1.0, 1.0, 1.0};
static float red[4] = {1.0, 0.0, 0.0, 1.0};
static float *rmColor[] = {white, red};
static float rmColors[2][4]; // Initialized at menu-load time (2 RGBA float color arrays).
static const char *aSessionTypeNames[3] = {"Practice", "Qualifications", "Race"};
@ -478,10 +474,10 @@ static void *rmResScreenHdle = 0;
static int rmResMainTitleId;
static int rmResTitleId;
static int* rmResMsgId = 0;
static int* rmResMsgId = 0; // Initialized at menu-load time.
static int* rmResMsgClr = 0;
static char** rmResMsg = 0;
static int* rmResMsgClr = 0; // Initialized at menu-load time.
static char** rmResMsg = 0; // Initialized at menu-load time.
static int rmCurLine;
@ -585,9 +581,15 @@ RmResScreenInit()
// Allocate line info arrays once and for all, if not already done.
if (!rmResMsgId)
{
// Load nMaxResultLines only the first time (ignore any later change,
// Load nMaxResultLines/colors only the first time (ignore any later change,
// otherwize, we'd have to realloc the line info arrays).
rmNMaxResLines = (int)GfuiMenuGetNumProperty(hmenu, "nMaxResultLines", 20);
const GfuiColor cNormal =
GfuiColor::build(GfuiMenuGetStrProperty(hmenu, "lineColorNormal", "0x0000FF"));
const GfuiColor cHighlighted =
GfuiColor::build(GfuiMenuGetStrProperty(hmenu, "lineColorHighlighted", "0x00FF00"));
memcpy(rmColors[0], cNormal.toFloatRGBA(), sizeof(rmColors[0]));
memcpy(rmColors[1], cHighlighted.toFloatRGBA(), sizeof(rmColors[0]));
rmResMsgId = (int*)calloc(rmNMaxResLines, sizeof(int));
rmResMsg = (char**)calloc(rmNMaxResLines, sizeof(char*));
@ -683,7 +685,7 @@ RmResScreenSetText(const char *text, int line, int clr)
rmResMsg[line] = strdup(text);
rmResMsgClr[line] = (clr >= 0 && clr < 2) ? clr : 0;
GfuiLabelSetText(rmResScreenHdle, rmResMsgId[line], rmResMsg[line]);
GfuiLabelSetColor(rmResScreenHdle, rmResMsgId[line], rmColor[rmResMsgClr[line]]);
GfuiLabelSetColor(rmResScreenHdle, rmResMsgId[line], rmColors[rmResMsgClr[line]]);
// The menu changed.
rmbResMenuChanged = true;

View file

@ -27,6 +27,7 @@
#include <tgfclient.h>
#include <robot.h>
#include <drivers.h> // GfDriver::getType
#include "legacymenu.h"
#include "racescreens.h"
@ -71,8 +72,6 @@ rmStartRaceHookInit(void)
}
// The menu itself ******************************************************
static const int NMaxLines = 20;
typedef struct
{
void *startScr;
@ -99,144 +98,148 @@ rmChgStartScreen(void *vpsrc)
void
rmDisplayStartRace(tRmInfo *info, void *startScr, void *abortScr, int start)
{
static char path[1024];
int nCars;
int i;
int y;
int x, dx;
int rows, curRow;
const char *img;
const char *name;
int robotIdx;
int extended;
void *robhdle;
void *carHdle;
const char *carName;
static char path[512];
static char buf[64];
void *params = info->params;
const char *race = info->_reRaceName;
const char *raceName = info->_reRaceName;
GfLogTrace("Entering Start Race menu\n");
// Create screen, load menu XML descriptor and create static controls.
rmScrHdle = GfuiScreenCreate();
void *menuXMLDescHdle = GfuiMenuLoad("startracemenu.xml");
GfuiMenuCreateStaticControls(rmScrHdle, menuXMLDescHdle);
void *hmenu = GfuiMenuLoad("startracemenu.xml");
GfuiMenuCreateStaticControls(rmScrHdle, hmenu);
// Create variable title label.
int titleId = GfuiMenuCreateLabelControl(rmScrHdle, menuXMLDescHdle, "titlelabel");
GfuiLabelSetText(rmScrHdle, titleId, race);
int titleId = GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "TitleLabel");
GfuiLabelSetText(rmScrHdle, titleId, raceName);
// Create background image if any.
img = GfParmGetStr(params, RM_SECT_HEADER, RM_ATTR_STARTIMG, 0);
if (img) {
const char* img = GfParmGetStr(params, RM_SECT_HEADER, RM_ATTR_STARTIMG, 0);
if (img)
GfuiScreenAddBgImg(rmScrHdle, img);
}
// Create starting grid labels if specified in race params.
if (!strcmp(GfParmGetStr(params, race, RM_ATTR_DISP_START_GRID, RM_VAL_YES), RM_VAL_YES)) {
if (!strcmp(GfParmGetStr(params, raceName, RM_ATTR_DISP_START_GRID, RM_VAL_YES), RM_VAL_YES))
{
// Create starting grid subtitle label.
GfuiMenuCreateLabelControl(rmScrHdle, menuXMLDescHdle, "subtitlelabel");
GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "SubTitleLabel");
// Get layout properties.
const int nMaxLines = (int)GfuiMenuGetNumProperty(hmenu, "nMaxLines", 15);
const int yTopLine = (int)GfuiMenuGetNumProperty(hmenu, "yTopLine", 400);
const int yLineShift = (int)GfuiMenuGetNumProperty(hmenu, "yLineShift", 20);
sprintf(path, "%s/%s", race, RM_SECT_STARTINGGRID);
rows = (int)GfParmGetNum(params, path, RM_ATTR_ROWS, (char*)NULL, 2);
// Create drivers info table.
dx = 0;
x = 40;
y = 400;
curRow = 0;
nCars = GfParmGetEltNb(params, RM_SECT_DRIVERS_RACING);
for (i = start; i < MIN(start + NMaxLines, nCars); i++)
// snprintf(path, sizeof(path), "%s/%s", raceName, RM_SECT_STARTINGGRID);
// const int rows = (int)GfParmGetNum(params, path, RM_ATTR_ROWS, (char*)NULL, 2);
const int nCars = GfParmGetEltNb(params, RM_SECT_DRIVERS_RACING);
int y = yTopLine;
int i = start;
for (; i < MIN(start + nMaxLines, nCars); i++)
{
/* Find starting driver's name */
sprintf(path, "%s/%d", RM_SECT_DRIVERS_RACING, i + 1);
name = GfParmGetStr(info->params, path, RM_ATTR_MODULE, "");
robotIdx = (int)GfParmGetNum(info->params, path, RM_ATTR_IDX, NULL, 0);
extended = GfParmGetNum(info->params, path, RM_ATTR_EXTENDED, NULL, 0);
carName = NULL;
robhdle = NULL;
if( extended )
{
sprintf(path, "%s/%s/%d/%d", RM_SECT_DRIVERINFO, name, extended, robotIdx);
carName = GfParmGetStr(info->params, path, RM_ATTR_CARNAME, NULL);
}
else
{
sprintf(path, "%sdrivers/%s/%s.xml", GfLocalDir(), name, name);
robhdle = GfParmReadFile(path, GFPARM_RMODE_STD);
if (!robhdle)
{
sprintf(path, "drivers/%s/%s.xml", name, name);
robhdle = GfParmReadFile(path, GFPARM_RMODE_STD);
}
snprintf(path, sizeof(path), "%s/%d", RM_SECT_DRIVERS_RACING, i + 1);
const char* modName = GfParmGetStr(info->params, path, RM_ATTR_MODULE, "");
const int robotIdx = (int)GfParmGetNum(info->params, path, RM_ATTR_IDX, NULL, 0);
const int extended = (int)GfParmGetNum(info->params, path, RM_ATTR_EXTENDED, NULL, 0);
void* robhdle = 0;
snprintf(path, sizeof(path), "%sdrivers/%s/%s.xml", GfLocalDir(), modName, modName);
robhdle = GfParmReadFile(path, GFPARM_RMODE_STD);
if (!robhdle)
{
snprintf(path, sizeof(path), "drivers/%s/%s.xml", modName, modName);
robhdle = GfParmReadFile(path, GFPARM_RMODE_STD);
}
if (robhdle)
{
sprintf(path, "%s/%s/%d", ROB_SECT_ROBOTS, ROB_LIST_INDEX, robotIdx);
name = GfParmGetStr(robhdle, path, ROB_ATTR_NAME, "<none>");
carName = GfParmGetStr(robhdle, path, ROB_ATTR_CAR, "");
}
}
if( carName )
const char* name = modName;
if (robhdle)
{
snprintf(path, sizeof(path), "%s/%s/%d", ROB_SECT_ROBOTS, ROB_LIST_INDEX, robotIdx);
name = GfParmGetStr(robhdle, path, ROB_ATTR_NAME, "<not found>");
}
const char* carName = 0;
if (extended)
{
snprintf(path, sizeof(path), "%s/%s/%d/%d", RM_SECT_DRIVERINFO, modName, extended, robotIdx);
carName = GfParmGetStr(info->params, path, RM_ATTR_CARNAME, "<not found>");
}
else if (robhdle)
{
carName = GfParmGetStr(robhdle, path, ROB_ATTR_CAR, "<not found>");
}
void* carHdle = 0;
if (carName)
{
sprintf(path, "cars/%s/%s.xml", carName, carName);
snprintf(path, sizeof(path), "cars/%s/%s.xml", carName, carName);
carHdle = GfParmReadFile(path, GFPARM_RMODE_STD);
carName = GfParmGetName(carHdle);
sprintf(path, "%d - %s - (%s)", i + 1, name, carName);
GfuiLabelCreate(rmScrHdle, path, GFUI_FONT_MEDIUM_C,
x + curRow * dx, y, GFUI_ALIGN_HL_VB, 0);
}
//Rank
snprintf(buf, sizeof(buf), "%d", i+1);
GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "Rank", true, // From template.
buf, GFUI_TPL_X, y);
//Driver name
GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "DriverName", true, // From template.
name, GFUI_TPL_X, y);
//Driver type
GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "DriverType", true, // From template.
GfDriver::getType(modName).c_str(), GFUI_TPL_X, y);
//Car model
GfuiMenuCreateLabelControl(rmScrHdle, hmenu, "CarModel", true, // From template.
carName ? carName : "<not found>", GFUI_TPL_X, y);
GfParmReleaseHandle(carHdle);
}
y -= yLineShift;
curRow = (curRow + 1) % rows;
y -= 15;
// Release robhdle only when no more need for read strings (like carname).
// Release params handles only when no more need for read strings (like carname).
if (carHdle)
GfParmReleaseHandle(carHdle);
if (robhdle)
GfParmReleaseHandle(robhdle);
}
if (start > 0) {
if (start > 0)
{
prevStartRace.startScr = startScr;
prevStartRace.abortScr = abortScr;
prevStartRace.info = info;
prevStartRace.start = start - NMaxLines;
prevStartRace.start = start - nMaxLines;
// Create Previous page button and associated keyboard shortcut if needed.
GfuiMenuCreateButtonControl(rmScrHdle, menuXMLDescHdle, "previouspagearrow",
(void*)&prevStartRace, rmChgStartScreen);
GfuiMenuCreateButtonControl(rmScrHdle, hmenu, "PreviousPageArrow",
(void*)&prevStartRace, rmChgStartScreen);
GfuiAddKey(rmScrHdle, GFUIK_PAGEUP, "Previous drivers",
(void*)&prevStartRace, rmChgStartScreen, NULL);
(void*)&prevStartRace, rmChgStartScreen, NULL);
}
if (i < nCars) {
if (i < nCars)
{
nextStartRace.startScr = startScr;
nextStartRace.abortScr = abortScr;
nextStartRace.info = info;
nextStartRace.start = start + NMaxLines;
nextStartRace.start = start + nMaxLines;
// Create Next page button and associated keyboard shortcut if needed.
GfuiMenuCreateButtonControl(rmScrHdle, menuXMLDescHdle, "nextpagearrow",
(void*)&nextStartRace, rmChgStartScreen);
GfuiMenuCreateButtonControl(rmScrHdle, hmenu, "NextPageArrow",
(void*)&nextStartRace, rmChgStartScreen);
GfuiAddKey(rmScrHdle, GFUIK_PAGEDOWN, "Next Drivers",
(void*)&nextStartRace, rmChgStartScreen, NULL);
(void*)&nextStartRace, rmChgStartScreen, NULL);
}
}
// Create Start and Abandon buttons.
GfuiMenuCreateButtonControl(rmScrHdle, menuXMLDescHdle, "startbutton", startScr, GfuiScreenReplace);
GfuiMenuCreateButtonControl(rmScrHdle, menuXMLDescHdle, "abandonbutton", abortScr, GfuiScreenReplace);
GfuiMenuCreateButtonControl(rmScrHdle, hmenu, "StartButton", startScr, GfuiScreenReplace);
GfuiMenuCreateButtonControl(rmScrHdle, hmenu, "AbandonButton", abortScr, GfuiScreenReplace);
// Close menu XML descriptor.
GfParmReleaseHandle(menuXMLDescHdle);
GfParmReleaseHandle(hmenu);
// Register keyboard shortcuts.
GfuiAddKey(rmScrHdle, GFUIK_RETURN, "Start", startScr, GfuiScreenReplace, NULL);