forked from speed-dreams/speed-dreams-code
Re #99 Driver select menu : Category filter follow the last human driver car choice, even after changing car + display user friendly category names (except in the picked driver infos)
git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@3135 30fe4595-0a0c-4342-8851-515496e4dcbd Former-commit-id: 27a3670f44b8d876d2d997b875b7a2db0ae7c7a0 Former-commit-id: 4d1cea6c2caa3f469f1a5e96859e55cca9a8b09d
This commit is contained in:
parent
d0f622abd0
commit
f4fa156640
8 changed files with 288 additions and 175 deletions
|
@ -97,7 +97,7 @@ bool HostSettingsMenu::Init(void* pMenu)
|
||||||
CreateStaticControls();
|
CreateStaticControls();
|
||||||
|
|
||||||
int carCatId = CreateComboboxControl("carcatcombobox",NULL,CarControlCB);
|
int carCatId = CreateComboboxControl("carcatcombobox",NULL,CarControlCB);
|
||||||
const std::vector<std::string> vecCategories = CarInfo::self()->GetCategoryNames();
|
const std::vector<std::string>& vecCategories = CarInfo::self()->GetCategoryNames();
|
||||||
|
|
||||||
int CatIndex = 0;
|
int CatIndex = 0;
|
||||||
for (unsigned int i=0;i<vecCategories.size();i++)
|
for (unsigned int i=0;i<vecCategories.size();i++)
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
|
|
||||||
void RmCarSelectMenu::onActivateCB(void *pCarSelectMenu)
|
void RmCarSelectMenu::onActivateCB(void *pCarSelectMenu)
|
||||||
{
|
{
|
||||||
//GfLogDebug("RmCarSelectMenu::onActivateCB\n");
|
GfLogTrace("Entering Car Select menu\n");
|
||||||
|
|
||||||
// Get the RmCarSelectMenu instance.
|
// Get the RmCarSelectMenu instance.
|
||||||
RmCarSelectMenu* pMenu = static_cast<RmCarSelectMenu*>(pCarSelectMenu);
|
RmCarSelectMenu* pMenu = static_cast<RmCarSelectMenu*>(pCarSelectMenu);
|
||||||
|
@ -42,11 +42,8 @@ void RmCarSelectMenu::onActivateCB(void *pCarSelectMenu)
|
||||||
// (use the 1st one from the 1st category if none).
|
// (use the 1st one from the 1st category if none).
|
||||||
CarData* pCurCar = CarInfo::self()->GetCarData(pMenu->getDriver()->carName);
|
CarData* pCurCar = CarInfo::self()->GetCarData(pMenu->getDriver()->carName);
|
||||||
if (!pCurCar)
|
if (!pCurCar)
|
||||||
pCurCar = &CarInfo::self()->GetCarsInCategory(CarInfo::self()->GetCategoryNames()[0])[0];
|
pCurCar = CarInfo::self()->GetCarsInCategory(CarInfo::self()->GetCategoryNames()[0])[0];
|
||||||
|
|
||||||
// Store current car params handle.
|
|
||||||
pMenu->setSelectedCarParamsHandle(pMenu->getDriver()->carParmHdle);
|
|
||||||
|
|
||||||
// Get currently selected skin name for the current driver.
|
// Get currently selected skin name for the current driver.
|
||||||
const char* pszCurSkinName =
|
const char* pszCurSkinName =
|
||||||
pMenu->getDriver()->skinName ? pMenu->getDriver()->skinName : rmdStdSkinName;
|
pMenu->getDriver()->skinName ? pMenu->getDriver()->skinName : rmdStdSkinName;
|
||||||
|
@ -54,8 +51,8 @@ void RmCarSelectMenu::onActivateCB(void *pCarSelectMenu)
|
||||||
// Initialize the GUI contents.
|
// Initialize the GUI contents.
|
||||||
GfuiLabelSetText(pMenu->GetMenuHandle(), pMenu->GetDynamicControlId("drivernamelabel"),
|
GfuiLabelSetText(pMenu->GetMenuHandle(), pMenu->GetDynamicControlId("drivernamelabel"),
|
||||||
pMenu->getDriver()->name);
|
pMenu->getDriver()->name);
|
||||||
pMenu->resetCarCategoryComboBox(pCurCar->strCategoryName);
|
pMenu->resetCarCategoryComboBox(pCurCar->strCategoryRealName);
|
||||||
pMenu->resetCarModelComboBox(pCurCar->strCategoryName, pCurCar->strRealName);
|
pMenu->resetCarModelComboBox(pCurCar->strCategoryRealName, pCurCar->strRealName);
|
||||||
pMenu->resetCarDataSheet(pCurCar->strName);
|
pMenu->resetCarDataSheet(pCurCar->strName);
|
||||||
pMenu->resetCarSkinComboBox(pCurCar->strRealName, pszCurSkinName);
|
pMenu->resetCarSkinComboBox(pCurCar->strRealName, pszCurSkinName);
|
||||||
pMenu->resetCarPreviewImage(pszCurSkinName);
|
pMenu->resetCarPreviewImage(pszCurSkinName);
|
||||||
|
@ -146,21 +143,33 @@ void RmCarSelectMenu::onAcceptCB(void *pCarSelectMenu)
|
||||||
}
|
}
|
||||||
pMenu->getDriver()->skinTargets = pMenu->getSelectedCarSkinTargets();
|
pMenu->getDriver()->skinTargets = pMenu->getSelectedCarSkinTargets();
|
||||||
|
|
||||||
// Save car choice into the driver structure (only human drivers can change it).
|
// Save car choice into the driver structure if any change
|
||||||
|
// (only human drivers can change it).
|
||||||
if (pMenu->getDriver()->isHuman)
|
if (pMenu->getDriver()->isHuman)
|
||||||
{
|
{
|
||||||
|
const CarData* pNewCar = pMenu->getSelectedCarModel();
|
||||||
|
|
||||||
// Car name.
|
// Car name.
|
||||||
const char* pszOldCarName = pMenu->getDriver()->carName;
|
const char* pszOldCarName = pMenu->getDriver()->carName;
|
||||||
const char* pszNewCarName = pMenu->getSelectedCarModel()->strName.c_str();
|
const char* pszNewCarName = pNewCar->strName.c_str();
|
||||||
if (pszNewCarName && (!pszOldCarName || strcmp(pszOldCarName, pszNewCarName)))
|
if (pszNewCarName && (!pszOldCarName || strcmp(pszOldCarName, pszNewCarName)))
|
||||||
{
|
{
|
||||||
if (pszOldCarName)
|
if (pMenu->getDriver()->carName)
|
||||||
free(pMenu->getDriver()->carName);
|
free(pMenu->getDriver()->carName);
|
||||||
pMenu->getDriver()->carName = strdup(pszNewCarName);
|
pMenu->getDriver()->carName = strdup(pszNewCarName);
|
||||||
}
|
|
||||||
|
|
||||||
// Car XML file.
|
// Car real name.
|
||||||
pMenu->getDriver()->carParmHdle = pMenu->getSelectedCarParamsHandle();
|
if (pMenu->getDriver()->carRealName)
|
||||||
|
free(pMenu->getDriver()->carRealName);
|
||||||
|
const char* pszNewCarRealName = pNewCar->strRealName.c_str();
|
||||||
|
pMenu->getDriver()->carRealName = strdup(pszNewCarRealName);
|
||||||
|
|
||||||
|
// Car category.
|
||||||
|
if (pMenu->getDriver()->carCategory)
|
||||||
|
free(pMenu->getDriver()->carCategory);
|
||||||
|
const char* pszNewCarCatName = pNewCar->strCategoryName.c_str();
|
||||||
|
pMenu->getDriver()->carCategory = strdup(pszNewCarCatName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Back to previous screen.
|
// Back to previous screen.
|
||||||
|
@ -177,11 +186,11 @@ void RmCarSelectMenu::onCancelCB(void *pCarSelectMenu)
|
||||||
}
|
}
|
||||||
|
|
||||||
RmCarSelectMenu::RmCarSelectMenu()
|
RmCarSelectMenu::RmCarSelectMenu()
|
||||||
: GfuiMenuScreen("carselectmenu.xml"), _nCurSkinIndex(0), _pDriver(0), _hCarParams(0)
|
: GfuiMenuScreen("carselectmenu.xml"), _nCurSkinIndex(0), _pDriver(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void RmCarSelectMenu::resetCarCategoryComboBox(const std::string& strSelectedCategoryName)
|
void RmCarSelectMenu::resetCarCategoryComboBox(const std::string& strSelectedCategoryRealName)
|
||||||
{
|
{
|
||||||
const int nCategoryComboId = GetDynamicControlId("categorycombo");
|
const int nCategoryComboId = GetDynamicControlId("categorycombo");
|
||||||
|
|
||||||
|
@ -189,15 +198,15 @@ void RmCarSelectMenu::resetCarCategoryComboBox(const std::string& strSelectedCat
|
||||||
GfuiEnable(GetMenuHandle(), nCategoryComboId, getDriver()->isHuman ? GFUI_ENABLE : GFUI_DISABLE);
|
GfuiEnable(GetMenuHandle(), nCategoryComboId, getDriver()->isHuman ? GFUI_ENABLE : GFUI_DISABLE);
|
||||||
|
|
||||||
// Retrieve the available car categories.
|
// Retrieve the available car categories.
|
||||||
const std::vector<std::string> vecCatNames = CarInfo::self()->GetCategoryNames();
|
const std::vector<std::string>& vecCatRealNames = CarInfo::self()->GetCategoryRealNames();
|
||||||
|
|
||||||
// Load the combo-box from their names (and determine the requested category index).
|
// Load the combo-box from their names (and determine the requested category index).
|
||||||
unsigned nCurrentCategoryIndex = 0;
|
unsigned nCurrentCategoryIndex = 0;
|
||||||
GfuiComboboxClear(GetMenuHandle(), nCategoryComboId);
|
GfuiComboboxClear(GetMenuHandle(), nCategoryComboId);
|
||||||
for (unsigned nCatIndex = 0; nCatIndex < vecCatNames.size(); nCatIndex++)
|
for (unsigned nCatIndex = 0; nCatIndex < vecCatRealNames.size(); nCatIndex++)
|
||||||
{
|
{
|
||||||
GfuiComboboxAddText(GetMenuHandle(), nCategoryComboId, vecCatNames[nCatIndex].c_str());
|
GfuiComboboxAddText(GetMenuHandle(), nCategoryComboId, vecCatRealNames[nCatIndex].c_str());
|
||||||
if (!strSelectedCategoryName.empty() && vecCatNames[nCatIndex] == strSelectedCategoryName)
|
if (!strSelectedCategoryRealName.empty() && vecCatRealNames[nCatIndex] == strSelectedCategoryRealName)
|
||||||
nCurrentCategoryIndex = nCatIndex;
|
nCurrentCategoryIndex = nCatIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,10 +214,10 @@ void RmCarSelectMenu::resetCarCategoryComboBox(const std::string& strSelectedCat
|
||||||
GfuiComboboxSetSelectedIndex(GetMenuHandle(), nCategoryComboId, nCurrentCategoryIndex);
|
GfuiComboboxSetSelectedIndex(GetMenuHandle(), nCategoryComboId, nCurrentCategoryIndex);
|
||||||
|
|
||||||
//GfLogDebug("resetCarCategoryComboBox(%s) : cur=%d\n",
|
//GfLogDebug("resetCarCategoryComboBox(%s) : cur=%d\n",
|
||||||
// strSelectedCategoryName.c_str(), nCurrentCategoryIndex);
|
// strSelectedCategoryRealName.c_str(), nCurrentCategoryIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RmCarSelectMenu::resetCarModelComboBox(const std::string& strCategoryName,
|
void RmCarSelectMenu::resetCarModelComboBox(const std::string& strCategoryRealName,
|
||||||
const std::string& strSelectedCarRealName)
|
const std::string& strSelectedCarRealName)
|
||||||
{
|
{
|
||||||
const int nModelComboId = GetDynamicControlId("modelcombo");
|
const int nModelComboId = GetDynamicControlId("modelcombo");
|
||||||
|
@ -217,8 +226,8 @@ void RmCarSelectMenu::resetCarModelComboBox(const std::string& strCategoryName,
|
||||||
GfuiEnable(GetMenuHandle(), nModelComboId, getDriver()->isHuman ? GFUI_ENABLE : GFUI_DISABLE);
|
GfuiEnable(GetMenuHandle(), nModelComboId, getDriver()->isHuman ? GFUI_ENABLE : GFUI_DISABLE);
|
||||||
|
|
||||||
// Retrieve car models in the selected category.
|
// Retrieve car models in the selected category.
|
||||||
const std::vector<CarData> vecCarsInCat =
|
const std::vector<CarData*> vecCarsInCat =
|
||||||
CarInfo::self()->GetCarsInCategory(strCategoryName);
|
CarInfo::self()->GetCarsInCategoryRealName(strCategoryRealName);
|
||||||
|
|
||||||
// Load the combo-box from their real names (and determine the selected model index).
|
// Load the combo-box from their real names (and determine the selected model index).
|
||||||
unsigned nCurrentCarIndexInCategory = 0;
|
unsigned nCurrentCarIndexInCategory = 0;
|
||||||
|
@ -226,9 +235,9 @@ void RmCarSelectMenu::resetCarModelComboBox(const std::string& strCategoryName,
|
||||||
for (unsigned nCarIndex = 0; nCarIndex < vecCarsInCat.size(); nCarIndex++)
|
for (unsigned nCarIndex = 0; nCarIndex < vecCarsInCat.size(); nCarIndex++)
|
||||||
{
|
{
|
||||||
GfuiComboboxAddText(GetMenuHandle(), nModelComboId,
|
GfuiComboboxAddText(GetMenuHandle(), nModelComboId,
|
||||||
vecCarsInCat[nCarIndex].strRealName.c_str());
|
vecCarsInCat[nCarIndex]->strRealName.c_str());
|
||||||
if (!strSelectedCarRealName.empty()
|
if (!strSelectedCarRealName.empty()
|
||||||
&& vecCarsInCat[nCarIndex].strRealName == strSelectedCarRealName)
|
&& vecCarsInCat[nCarIndex]->strRealName == strSelectedCarRealName)
|
||||||
nCurrentCarIndexInCategory = nCarIndex;
|
nCurrentCarIndexInCategory = nCarIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,7 +245,7 @@ void RmCarSelectMenu::resetCarModelComboBox(const std::string& strCategoryName,
|
||||||
GfuiComboboxSetSelectedIndex(GetMenuHandle(), nModelComboId, nCurrentCarIndexInCategory);
|
GfuiComboboxSetSelectedIndex(GetMenuHandle(), nModelComboId, nCurrentCarIndexInCategory);
|
||||||
|
|
||||||
//GfLogDebug("resetCarModelComboBox(cat=%s, selCar=%s) : cur=%d (nCarsInCat=%d)\n",
|
//GfLogDebug("resetCarModelComboBox(cat=%s, selCar=%s) : cur=%d (nCarsInCat=%d)\n",
|
||||||
// strCategoryName.c_str(), strSelectedCarRealName.c_str(),
|
// strCategoryRealName.c_str(), strSelectedCarRealName.c_str(),
|
||||||
// nCurrentCarIndexInCategory, vecCarsInCat.size());
|
// nCurrentCarIndexInCategory, vecCarsInCat.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,12 +255,9 @@ void RmCarSelectMenu::resetCarDataSheet(const std::string& strSelectedCarName)
|
||||||
|
|
||||||
// Open new car params.
|
// Open new car params.
|
||||||
std::ostringstream ossCarXMLFileName;
|
std::ostringstream ossCarXMLFileName;
|
||||||
ossCarXMLFileName << "cars/" << strSelectedCarName << '/' << strSelectedCarName << ".xml";
|
ossCarXMLFileName << "cars/" << strSelectedCarName << '/' << strSelectedCarName << PARAMEXT;
|
||||||
void* newHdle = GfParmReadFile(ossCarXMLFileName.str().c_str(), GFPARM_RMODE_STD);
|
void* newHdle = GfParmReadFile(ossCarXMLFileName.str().c_str(), GFPARM_RMODE_STD);
|
||||||
|
|
||||||
// Store new car params handle.
|
|
||||||
setSelectedCarParamsHandle(newHdle);
|
|
||||||
|
|
||||||
// Update GUI.
|
// Update GUI.
|
||||||
std::ostringstream ossSpecValue;
|
std::ostringstream ossSpecValue;
|
||||||
std::ostringstream ossSpecPath;
|
std::ostringstream ossSpecPath;
|
||||||
|
@ -346,8 +352,6 @@ void RmCarSelectMenu::resetCarPreviewImage(const std::string& strSelectedSkinNam
|
||||||
|
|
||||||
void RmCarSelectMenu::RunMenu(trmdDrvElt* pDriver)
|
void RmCarSelectMenu::RunMenu(trmdDrvElt* pDriver)
|
||||||
{
|
{
|
||||||
//GfLogDebug("RmCarSelectMenu::RunMenu\n");
|
|
||||||
|
|
||||||
// Initialize if not already done.
|
// Initialize if not already done.
|
||||||
if (!GetMenuHandle())
|
if (!GetMenuHandle())
|
||||||
Initialize();
|
Initialize();
|
||||||
|
@ -361,10 +365,6 @@ void RmCarSelectMenu::RunMenu(trmdDrvElt* pDriver)
|
||||||
|
|
||||||
bool RmCarSelectMenu::Initialize()
|
bool RmCarSelectMenu::Initialize()
|
||||||
{
|
{
|
||||||
//GfLogDebug("RmCarSelectMenu::Initialize\n");
|
|
||||||
|
|
||||||
CarInfo::self()->print();
|
|
||||||
|
|
||||||
// Create the menu and all its controls.
|
// Create the menu and all its controls.
|
||||||
CreateMenuEx(NULL, this, onActivateCB, NULL, (tfuiCallback)NULL, 1);
|
CreateMenuEx(NULL, this, onActivateCB, NULL, (tfuiCallback)NULL, 1);
|
||||||
|
|
||||||
|
@ -415,24 +415,4 @@ trmdDrvElt* RmCarSelectMenu::getDriver()
|
||||||
void RmCarSelectMenu::setDriver(trmdDrvElt* pDriver)
|
void RmCarSelectMenu::setDriver(trmdDrvElt* pDriver)
|
||||||
{
|
{
|
||||||
_pDriver = pDriver;
|
_pDriver = pDriver;
|
||||||
_hCarParams = 0; // No newly selected car for the moment.
|
|
||||||
}
|
|
||||||
|
|
||||||
void RmCarSelectMenu::setSelectedCarParamsHandle(void* hdle)
|
|
||||||
{
|
|
||||||
if (!hdle)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Close old car params if not null and not the current driver's one
|
|
||||||
// (and if it really changes).
|
|
||||||
if (_hCarParams && _hCarParams != _pDriver->carParmHdle && _hCarParams != hdle)
|
|
||||||
GfParmReleaseHandle(_hCarParams);
|
|
||||||
|
|
||||||
// Store the new one.
|
|
||||||
_hCarParams = hdle;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* RmCarSelectMenu::getSelectedCarParamsHandle() const
|
|
||||||
{
|
|
||||||
return _hCarParams;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,9 +56,6 @@ protected:
|
||||||
const char* getSelectedCarSkin() const;
|
const char* getSelectedCarSkin() const;
|
||||||
int getSelectedCarSkinTargets() const;
|
int getSelectedCarSkinTargets() const;
|
||||||
|
|
||||||
void setSelectedCarParamsHandle(void* hdle);
|
|
||||||
void* getSelectedCarParamsHandle() const;
|
|
||||||
|
|
||||||
// Control callback functions (have to be static, as used as tgfclient controls callbacks).
|
// Control callback functions (have to be static, as used as tgfclient controls callbacks).
|
||||||
static void onActivateCB(void *pCarSelectMenu);
|
static void onActivateCB(void *pCarSelectMenu);
|
||||||
static void onChangeCategory(tComboBoxInfo *pInfo);
|
static void onChangeCategory(tComboBoxInfo *pInfo);
|
||||||
|
@ -74,7 +71,7 @@ private:
|
||||||
struct rmdDrvElt* _pDriver;
|
struct rmdDrvElt* _pDriver;
|
||||||
|
|
||||||
// Currently selected car params handle.
|
// Currently selected car params handle.
|
||||||
void* _hCarParams;
|
//void* _hCarParams;
|
||||||
|
|
||||||
// Skin names and targets + associated skinned livery preview files
|
// Skin names and targets + associated skinned livery preview files
|
||||||
std::vector<std::string> _vecSkinNames;
|
std::vector<std::string> _vecSkinNames;
|
||||||
|
|
|
@ -43,15 +43,14 @@ static const char* pszSkinIntFileSuffix = "-int";
|
||||||
static const char* pszLogoFileName = "logo"; // Warning: Must be consistent with grscene.cpp
|
static const char* pszLogoFileName = "logo"; // Warning: Must be consistent with grscene.cpp
|
||||||
static const char* pszWheel3DFileName = "wheel3d"; // Warning: Must be consistent with wheel<i>.ac/acc
|
static const char* pszWheel3DFileName = "wheel3d"; // Warning: Must be consistent with wheel<i>.ac/acc
|
||||||
|
|
||||||
static const char* apszExcludedSkinNamePrefixes[] = { "rpm", "speed", "int" };
|
static const char* apszExcludedSkinNamePrefixes[] = { "rpm", "speed", "int", "0", "1", "2", "3" };
|
||||||
static const int nExcludedSkinNamePrefixes = sizeof(apszExcludedSkinNamePrefixes) / sizeof(char*);
|
static const int nExcludedSkinNamePrefixes = sizeof(apszExcludedSkinNamePrefixes) / sizeof(char*);
|
||||||
|
|
||||||
|
|
||||||
int rmdDriverMatchesFilters(const trmdDrvElt *drv, const char* carCat, const char* drvTyp,
|
int rmdDriverMatchesFilters(const trmdDrvElt *drv, const char* carCat, const char* drvTyp,
|
||||||
const char* anyCarCat, const char* anyDrvTyp)
|
const char* anyCarCat, const char* anyDrvTyp)
|
||||||
{
|
{
|
||||||
return (!strcmp(carCat, anyCarCat)
|
return (!strcmp(carCat, anyCarCat) || !strcmp(carCat, drv->carCategory))
|
||||||
|| !strcmp(GfParmGetStr(drv->carParmHdle, SECT_CAR, PRM_CATEGORY, ""), carCat))
|
|
||||||
&& (!strcmp(drvTyp, anyDrvTyp)
|
&& (!strcmp(drvTyp, anyDrvTyp)
|
||||||
|| strstr(drv->moduleName, drvTyp) == drv->moduleName);
|
|| strstr(drv->moduleName, drvTyp) == drv->moduleName);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include <tgf.h>
|
#include <tgf.h>
|
||||||
|
#include <carinfo.h>
|
||||||
|
|
||||||
|
|
||||||
// Driver description
|
// Driver description
|
||||||
|
@ -39,10 +40,11 @@ typedef struct rmdDrvElt
|
||||||
char *name; // Driver name
|
char *name; // Driver name
|
||||||
int isSelected; // Selected for race ?
|
int isSelected; // Selected for race ?
|
||||||
int isHuman; // Human driver ?
|
int isHuman; // Human driver ?
|
||||||
char *carName; // Car (folder) name
|
char *carName; // Car XML file / folder name
|
||||||
|
char *carRealName; // Car user-friendly name
|
||||||
|
char *carCategory; // Car category XML file / folder name
|
||||||
int skinTargets; // Skin targets bit-field (see car.h for possible values)
|
int skinTargets; // Skin targets bit-field (see car.h for possible values)
|
||||||
char *skinName; // Skin name (or 0 if standard skin)
|
char *skinName; // Skin name (or 0 if standard skin)
|
||||||
void *carParmHdle; // Handle to the car XML params file
|
|
||||||
GF_TAILQ_ENTRY(struct rmdDrvElt) link;
|
GF_TAILQ_ENTRY(struct rmdDrvElt) link;
|
||||||
} trmdDrvElt;
|
} trmdDrvElt;
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,8 @@ static int NbMaxSelectedDrivers;
|
||||||
|
|
||||||
// Car categories
|
// Car categories
|
||||||
static const char* AnyCarCategory = "--- All ---";
|
static const char* AnyCarCategory = "--- All ---";
|
||||||
static std::vector<std::string> VecCarCategories;
|
static std::vector<std::string> VecCarCategories; // Category folder/file names
|
||||||
|
static std::vector<std::string> VecCarCategoryNames; // Category real/displayed names
|
||||||
static size_t CurCarCategoryIndex = 0;
|
static size_t CurCarCategoryIndex = 0;
|
||||||
|
|
||||||
// Driver types
|
// Driver types
|
||||||
|
@ -100,6 +101,8 @@ static size_t CurSkinIndex = 0;
|
||||||
GF_TAILQ_HEAD(DriverListHead, trmdDrvElt);
|
GF_TAILQ_HEAD(DriverListHead, trmdDrvElt);
|
||||||
static tDriverListHead DriverList;
|
static tDriverListHead DriverList;
|
||||||
|
|
||||||
|
trmdDrvElt *PPickedDriver;
|
||||||
|
|
||||||
// Local functions.
|
// Local functions.
|
||||||
static void rmdsCleanup(void);
|
static void rmdsCleanup(void);
|
||||||
static void rmdsFilterDriverScrollList(const char* carCat, const char* driverType);
|
static void rmdsFilterDriverScrollList(const char* carCat, const char* driverType);
|
||||||
|
@ -112,37 +115,90 @@ static void rmdsClickOnDriver(void * /* dummy */);
|
||||||
static void
|
static void
|
||||||
rmdsActivate(void * /* notused */)
|
rmdsActivate(void * /* notused */)
|
||||||
{
|
{
|
||||||
|
GfLogTrace("Entering Driver Select menu\n");
|
||||||
|
|
||||||
std::vector<std::string> vecSkinNames;
|
std::vector<std::string> vecSkinNames;
|
||||||
std::map<std::string, std::string> mapSkinPreviewFiles; // Key = skin name.
|
std::map<std::string, std::string> mapSkinPreviewFiles; // Key = skin name.
|
||||||
std::map<std::string, int> mapSkinTargets; // Key = skin name.
|
std::map<std::string, int> mapSkinTargets; // Key = skin name.
|
||||||
|
|
||||||
// Update competitors skinning data (in case things changed since the menu was last open ;
|
// Update competitors skinning data (in case things changed since the menu was last open ;
|
||||||
// ex: the user added a 3D wheel skinned texture in its user settings)
|
// ex: the user added a 3D wheel skinned texture in its user settings)
|
||||||
trmdDrvElt *curDrv;
|
trmdDrvElt *driver;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
const char* name;
|
const char* name;
|
||||||
while ((name = GfuiScrollListGetElement(ScrHandle, CompetitorsScrollListId,
|
while ((name = GfuiScrollListGetElement(ScrHandle, CompetitorsScrollListId,
|
||||||
index, (void**)&curDrv)))
|
index, (void**)&driver)))
|
||||||
{
|
{
|
||||||
// Get really available (now) skins, skin targets and preview files for the driver's car.
|
// Get really available (now) skins, skin targets and preview files for the driver's car.
|
||||||
rmdGetCarSkinsInSearchPath(curDrv, 0, vecSkinNames, mapSkinTargets, mapSkinPreviewFiles);
|
rmdGetCarSkinsInSearchPath(driver, 0, vecSkinNames, mapSkinTargets, mapSkinPreviewFiles);
|
||||||
|
|
||||||
// Update skin targets for the choosen skin (targets might have changed).
|
// Update skin targets for the choosen skin (targets might have changed).
|
||||||
curDrv->skinTargets = 0;
|
driver->skinTargets = 0;
|
||||||
if (curDrv->skinName)
|
if (driver->skinName)
|
||||||
{
|
{
|
||||||
std::map<std::string, int>::const_iterator itSkinTargets =
|
std::map<std::string, int>::const_iterator itSkinTargets =
|
||||||
mapSkinTargets.find(curDrv->skinName);
|
mapSkinTargets.find(driver->skinName);
|
||||||
if (itSkinTargets != mapSkinTargets.end())
|
if (itSkinTargets != mapSkinTargets.end())
|
||||||
curDrv->skinTargets = itSkinTargets->second;
|
driver->skinTargets = itSkinTargets->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next competitor.
|
// Next competitor.
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update selected driver displayed info
|
// Select the current driver in the relevant scroll-list
|
||||||
rmdsClickOnDriver(NULL);
|
if (PPickedDriver)
|
||||||
|
{
|
||||||
|
const char* name;
|
||||||
|
int curDrvIndex = -1;
|
||||||
|
index = 0;
|
||||||
|
while ((name = GfuiScrollListGetElement(ScrHandle, CompetitorsScrollListId,
|
||||||
|
index, (void**)&driver)))
|
||||||
|
{
|
||||||
|
if (driver == PPickedDriver)
|
||||||
|
{
|
||||||
|
curDrvIndex = index;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
if (curDrvIndex >= 0)
|
||||||
|
{
|
||||||
|
GfuiScrollListSetSelectedElement(ScrHandle, CompetitorsScrollListId, curDrvIndex);
|
||||||
|
//GfLogDebug("Selecting competitor #%d '%s'\n", curDrvIndex, name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
curDrvIndex = -1;
|
||||||
|
index = 0;
|
||||||
|
while ((name = GfuiScrollListGetElement(ScrHandle, CandidatesScrollListId,
|
||||||
|
index, (void**)&driver)))
|
||||||
|
{
|
||||||
|
if (driver == PPickedDriver)
|
||||||
|
{
|
||||||
|
curDrvIndex =index;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
if (curDrvIndex >= 0)
|
||||||
|
{
|
||||||
|
GfuiScrollListSetSelectedElement(ScrHandle, CandidatesScrollListId, curDrvIndex);
|
||||||
|
//GfLogDebug("Selecting candidate #%d '%s'\n", curDrvIndex, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update car category filter criteria : use the one of the current driver if any.
|
||||||
|
const char* curDrvCarCat = PPickedDriver ? PPickedDriver->carCategory : AnyCarCategory;
|
||||||
|
CurCarCategoryIndex =
|
||||||
|
(std::find(VecCarCategories.begin(), VecCarCategories.end(), curDrvCarCat)
|
||||||
|
- VecCarCategories.begin() + VecCarCategories.size()) % VecCarCategories.size();
|
||||||
|
//GfLogDebug("Car cat filter : %p '%s' %d\n", PPickedDriver, curDrvCarCat, CurCarCategoryIndex);
|
||||||
|
rmdsFilterDriverScrollList(curDrvCarCat, VecDriverTypes[CurDriverTypeIndex].c_str());
|
||||||
|
GfuiLabelSetText(ScrHandle, DriverTypeEditId, VecDriverTypes[CurDriverTypeIndex].c_str());
|
||||||
|
GfuiLabelSetText(ScrHandle, CarCategoryEditId, VecCarCategoryNames[CurCarCategoryIndex].c_str());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Screen de-activation call-back.
|
// Screen de-activation call-back.
|
||||||
|
@ -162,7 +218,7 @@ rmdsChangeCarCategory(void *vp)
|
||||||
CurCarCategoryIndex =
|
CurCarCategoryIndex =
|
||||||
(CurCarCategoryIndex + VecCarCategories.size() + (int)(long)vp) % VecCarCategories.size();
|
(CurCarCategoryIndex + VecCarCategories.size() + (int)(long)vp) % VecCarCategories.size();
|
||||||
|
|
||||||
GfuiLabelSetText(ScrHandle, CarCategoryEditId, VecCarCategories[CurCarCategoryIndex].c_str());
|
GfuiLabelSetText(ScrHandle, CarCategoryEditId, VecCarCategoryNames[CurCarCategoryIndex].c_str());
|
||||||
|
|
||||||
rmdsFilterDriverScrollList(VecCarCategories[CurCarCategoryIndex].c_str(),
|
rmdsFilterDriverScrollList(VecCarCategories[CurCarCategoryIndex].c_str(),
|
||||||
VecDriverTypes[CurDriverTypeIndex].c_str());
|
VecDriverTypes[CurDriverTypeIndex].c_str());
|
||||||
|
@ -201,7 +257,7 @@ rmdsChangeSkin(void *vp)
|
||||||
|
|
||||||
// Load associated preview image (or "no preview" panel if none available).
|
// Load associated preview image (or "no preview" panel if none available).
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (!stat(MapCurDriverSkinPreviewFiles[pszCurSkinName].c_str(), &st))
|
if (GfFileExists(MapCurDriverSkinPreviewFiles[pszCurSkinName].c_str()))
|
||||||
GfuiStaticImageSet(ScrHandle, CarImageId,
|
GfuiStaticImageSet(ScrHandle, CarImageId,
|
||||||
MapCurDriverSkinPreviewFiles[pszCurSkinName].c_str(),
|
MapCurDriverSkinPreviewFiles[pszCurSkinName].c_str(),
|
||||||
/* index= */ 0, /* canDeform= */false);
|
/* index= */ 0, /* canDeform= */false);
|
||||||
|
@ -306,14 +362,10 @@ rmdsPreviousMenu(void *screen)
|
||||||
static void
|
static void
|
||||||
rmdsCarSelectMenu(void *pPreviousMenu)
|
rmdsCarSelectMenu(void *pPreviousMenu)
|
||||||
{
|
{
|
||||||
//GfLogDebug("rmdsCarSelectMenu\n");
|
if (PPickedDriver)
|
||||||
|
|
||||||
trmdDrvElt *pDriver = rmdsGetHighlightedDriver();
|
|
||||||
|
|
||||||
if (pDriver)
|
|
||||||
{
|
{
|
||||||
CarSelectMenu.SetPreviousMenuHandle(pPreviousMenu);
|
CarSelectMenu.SetPreviousMenuHandle(pPreviousMenu);
|
||||||
CarSelectMenu.RunMenu(pDriver);
|
CarSelectMenu.RunMenu(PPickedDriver);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,8 +378,7 @@ rmdsMoveDriver(void *vd)
|
||||||
static void
|
static void
|
||||||
rmdsClickOnDriver(void * /* dummy */)
|
rmdsClickOnDriver(void * /* dummy */)
|
||||||
{
|
{
|
||||||
static const unsigned maxBufSize = 64;
|
char buf[64];
|
||||||
char buf[maxBufSize];
|
|
||||||
const char *name;
|
const char *name;
|
||||||
trmdDrvElt *curDrv;
|
trmdDrvElt *curDrv;
|
||||||
|
|
||||||
|
@ -361,11 +412,14 @@ rmdsClickOnDriver(void * /* dummy */)
|
||||||
// Update selected driver (if any) displayed infos.
|
// Update selected driver (if any) displayed infos.
|
||||||
if (name)
|
if (name)
|
||||||
{
|
{
|
||||||
rmdGetDriverType(curDrv->moduleName, buf, maxBufSize);
|
// The selected driver is the new picked one.
|
||||||
|
PPickedDriver = curDrv;
|
||||||
|
|
||||||
|
// Update picked driver info.
|
||||||
|
rmdGetDriverType(curDrv->moduleName, buf, sizeof(buf));
|
||||||
GfuiLabelSetText(ScrHandle, PickedDriverTypeLabelId, buf);
|
GfuiLabelSetText(ScrHandle, PickedDriverTypeLabelId, buf);
|
||||||
GfuiLabelSetText(ScrHandle, PickedDriverCarLabelId, GfParmGetName(curDrv->carParmHdle));
|
GfuiLabelSetText(ScrHandle, PickedDriverCarLabelId, curDrv->carRealName);
|
||||||
GfuiLabelSetText(ScrHandle, PickedDriverCarCategoryLabelId,
|
GfuiLabelSetText(ScrHandle, PickedDriverCarCategoryLabelId, curDrv->carCategory);
|
||||||
GfParmGetStr(curDrv->carParmHdle, SECT_CAR, PRM_CATEGORY, ""));
|
|
||||||
|
|
||||||
// Get really available skins, skin targets and preview files for the driver's car.
|
// Get really available skins, skin targets and preview files for the driver's car.
|
||||||
rmdGetCarSkinsInSearchPath(curDrv, 0, VecCurDriverSkinNames,
|
rmdGetCarSkinsInSearchPath(curDrv, 0, VecCurDriverSkinNames,
|
||||||
|
@ -551,15 +605,15 @@ RmDriversSelect(void *vs)
|
||||||
trmdDrvElt *curDrv;
|
trmdDrvElt *curDrv;
|
||||||
int nDrivers, robotIdx;
|
int nDrivers, robotIdx;
|
||||||
void *robhdle;
|
void *robhdle;
|
||||||
struct stat st;
|
|
||||||
const char *carName;
|
const char *carName;
|
||||||
|
const char *carRealName;
|
||||||
|
const char *carCat;
|
||||||
int extended;
|
int extended;
|
||||||
void *carhdle;
|
void *carhdle;
|
||||||
|
void *cathdle;
|
||||||
int human;
|
int human;
|
||||||
const char* initCarCat;
|
const char* initCarCat;
|
||||||
|
|
||||||
//GfLogDebug("RmDriversSelect\n");
|
|
||||||
|
|
||||||
// Initialize drivers selection
|
// Initialize drivers selection
|
||||||
MenuData = (tRmDriverSelect*)vs;
|
MenuData = (tRmDriverSelect*)vs;
|
||||||
|
|
||||||
|
@ -605,6 +659,7 @@ RmDriversSelect(void *vs)
|
||||||
GF_TAILQ_INIT(&DriverList);
|
GF_TAILQ_INIT(&DriverList);
|
||||||
|
|
||||||
VecCarCategories.push_back(AnyCarCategory);
|
VecCarCategories.push_back(AnyCarCategory);
|
||||||
|
VecCarCategoryNames.push_back(AnyCarCategory);
|
||||||
VecDriverTypes.push_back(AnyDriverType);
|
VecDriverTypes.push_back(AnyDriverType);
|
||||||
|
|
||||||
list = 0;
|
list = 0;
|
||||||
|
@ -637,41 +692,54 @@ RmDriversSelect(void *vs)
|
||||||
carName = GfParmGetStr(robhdle, path, ROB_ATTR_CAR, "");
|
carName = GfParmGetStr(robhdle, path, ROB_ATTR_CAR, "");
|
||||||
human = strcmp(GfParmGetStr(robhdle, path, ROB_ATTR_TYPE, ROB_VAL_ROBOT), ROB_VAL_ROBOT);
|
human = strcmp(GfParmGetStr(robhdle, path, ROB_ATTR_TYPE, ROB_VAL_ROBOT), ROB_VAL_ROBOT);
|
||||||
sprintf(path, "cars/%s/%s.xml", carName, carName);
|
sprintf(path, "cars/%s/%s.xml", carName, carName);
|
||||||
if (!stat(path, &st)) {
|
carhdle = GfParmReadFile(path, GFPARM_RMODE_STD);
|
||||||
carhdle = GfParmReadFile(path, GFPARM_RMODE_STD);
|
if (carhdle) {
|
||||||
if (carhdle) {
|
carCat = GfParmGetStr(carhdle, SECT_CAR, PRM_CATEGORY, "");
|
||||||
curDrv = (trmdDrvElt*)calloc(1, sizeof(trmdDrvElt));
|
carRealName = GfParmGetName(carhdle);
|
||||||
curDrv->interfaceIndex = curmod->modInfo[i].index;
|
|
||||||
curDrv->moduleName = strdup(modName);
|
curDrv = (trmdDrvElt*)calloc(1, sizeof(trmdDrvElt));
|
||||||
curDrv->carName = strdup(carName); // Default one if not specified in race file.
|
curDrv->interfaceIndex = curmod->modInfo[i].index;
|
||||||
curDrv->skinName = 0; // Set later if needed from race params.
|
curDrv->moduleName = strdup(modName);
|
||||||
curDrv->skinTargets = 0; // Set later if needed from race params.
|
curDrv->carName = strdup(carName); // Default one if not specified in race file.
|
||||||
curDrv->name = strdup(curmod->modInfo[i].name);
|
curDrv->carRealName = strdup(carRealName); // For the default car.
|
||||||
curDrv->carParmHdle = carhdle;
|
curDrv->carCategory = strdup(carCat); // For the default car.
|
||||||
//GfLogDebug("Candidate %s : %s on %s\n", modName, curDrv->name, carName);
|
curDrv->skinName = 0; // Set later if needed from race params.
|
||||||
const char* carCat = GfParmGetStr(carhdle, SECT_CAR, PRM_CATEGORY, "");
|
curDrv->skinTargets = 0; // Set later if needed from race params.
|
||||||
if (std::find(VecCarCategories.begin(), VecCarCategories.end(), carCat) == VecCarCategories.end()) {
|
curDrv->name = strdup(curmod->modInfo[i].name);
|
||||||
VecCarCategories.push_back(carCat);
|
//GfLogDebug("Candidate %s : %s on %s\n", modName, curDrv->name, carName);
|
||||||
}
|
if (std::find(VecCarCategories.begin(), VecCarCategories.end(), carCat) == VecCarCategories.end()) {
|
||||||
rmdGetDriverType(modName, drvType, drvTypeMaxSize);
|
VecCarCategories.push_back(carCat);
|
||||||
if (std::find(VecDriverTypes.begin(), VecDriverTypes.end(), drvType) == VecDriverTypes.end()) {
|
sprintf(path, "categories/%s.xml", carCat);
|
||||||
VecDriverTypes.push_back(drvType);
|
cathdle = GfParmReadFile(path, GFPARM_RMODE_STD);
|
||||||
}
|
if (cathdle) {
|
||||||
|
carCat = GfParmGetName(cathdle);
|
||||||
curDrv->isHuman = human ? 1 : 0;
|
|
||||||
if (human) {
|
|
||||||
GF_TAILQ_INSERT_HEAD(&DriverList, curDrv, link);
|
|
||||||
} else {
|
} else {
|
||||||
GF_TAILQ_INSERT_TAIL(&DriverList, curDrv, link);
|
GfLogWarning("Car %s category file %s not %s for '%s' (%s #%d)\n",
|
||||||
|
carName, path, GfFileExists(path) ? "readable" : "found",
|
||||||
|
curmod->modInfo[i].name, modName, i);
|
||||||
}
|
}
|
||||||
NbTotDrivers++;
|
VecCarCategoryNames.push_back(carCat);
|
||||||
} else {
|
if (cathdle)
|
||||||
GfLogWarning("Ignoring '%s' (%s #%d) because '%s' is not readable\n",
|
GfParmReleaseHandle(cathdle);
|
||||||
curmod->modInfo[i].name, modName, i, path);
|
|
||||||
}
|
}
|
||||||
|
GfParmReleaseHandle(carhdle);
|
||||||
|
|
||||||
|
rmdGetDriverType(modName, drvType, drvTypeMaxSize);
|
||||||
|
if (std::find(VecDriverTypes.begin(), VecDriverTypes.end(), drvType) == VecDriverTypes.end()) {
|
||||||
|
VecDriverTypes.push_back(drvType);
|
||||||
|
}
|
||||||
|
|
||||||
|
curDrv->isHuman = human ? 1 : 0;
|
||||||
|
if (human) {
|
||||||
|
GF_TAILQ_INSERT_HEAD(&DriverList, curDrv, link);
|
||||||
|
} else {
|
||||||
|
GF_TAILQ_INSERT_TAIL(&DriverList, curDrv, link);
|
||||||
|
}
|
||||||
|
NbTotDrivers++;
|
||||||
} else {
|
} else {
|
||||||
GfLogWarning("Ignoring '%s' (%s #%d) because '%s' was not found\n",
|
GfLogWarning("Ignoring '%s' (%s #%d) because '%s' file not %s\n",
|
||||||
curmod->modInfo[i].name, modName, i, path);
|
curmod->modInfo[i].name, modName, i, path,
|
||||||
|
GfFileExists(path) ? "readable" : "found");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -693,7 +761,7 @@ RmDriversSelect(void *vs)
|
||||||
(int)GfParmGetNum(MenuData->param, RM_SECT_DRIVERS, RM_ATTR_MAXNUM, NULL, 0);
|
(int)GfParmGetNum(MenuData->param, RM_SECT_DRIVERS, RM_ATTR_MAXNUM, NULL, 0);
|
||||||
nDrivers = GfParmGetEltNb(MenuData->param, RM_SECT_DRIVERS);
|
nDrivers = GfParmGetEltNb(MenuData->param, RM_SECT_DRIVERS);
|
||||||
//GfLogDebug("Competitors : n=%d (max=%d)\n", nDrivers, NbMaxSelectedDrivers);
|
//GfLogDebug("Competitors : n=%d (max=%d)\n", nDrivers, NbMaxSelectedDrivers);
|
||||||
initCarCat = 0;
|
PPickedDriver = 0;
|
||||||
index = 1;
|
index = 1;
|
||||||
for (i = 1; i < nDrivers+1; i++) {
|
for (i = 1; i < nDrivers+1; i++) {
|
||||||
// Get driver infos from the the starting grid in the race params file
|
// Get driver infos from the the starting grid in the race params file
|
||||||
|
@ -723,10 +791,10 @@ RmDriversSelect(void *vs)
|
||||||
GfuiScrollListInsertElement(ScrHandle, CompetitorsScrollListId,
|
GfuiScrollListInsertElement(ScrHandle, CompetitorsScrollListId,
|
||||||
curDrv->name, index, (void*)curDrv);
|
curDrv->name, index, (void*)curDrv);
|
||||||
|
|
||||||
// Try and determine the initial car category for the filtering combo-box
|
// Initialize the picked driver
|
||||||
// (the car category of the last human driver, or else of the last driver).
|
// (the last human driver, or else of the last driver).
|
||||||
if (!initCarCat || curDrv->isHuman)
|
if (!PPickedDriver || curDrv->isHuman)
|
||||||
initCarCat = GfParmGetStr(curDrv->carParmHdle, SECT_CAR, PRM_CATEGORY, "");
|
PPickedDriver = curDrv;
|
||||||
|
|
||||||
// Get the chosen car for the race if any specified (human only).
|
// Get the chosen car for the race if any specified (human only).
|
||||||
if (curDrv->isHuman && extended)
|
if (curDrv->isHuman && extended)
|
||||||
|
@ -735,16 +803,21 @@ RmDriversSelect(void *vs)
|
||||||
sprintf(path, "%s/%s/%d/%d", RM_SECT_DRIVERINFO, moduleName, extended, robotIdx);
|
sprintf(path, "%s/%s/%d/%d", RM_SECT_DRIVERINFO, moduleName, extended, robotIdx);
|
||||||
carName = GfParmGetStr(MenuData->param, path, RM_ATTR_CARNAME, 0);
|
carName = GfParmGetStr(MenuData->param, path, RM_ATTR_CARNAME, 0);
|
||||||
sprintf(path, "cars/%s/%s.xml", carName, carName);
|
sprintf(path, "cars/%s/%s.xml", carName, carName);
|
||||||
if (!stat(path, &st)) {
|
if (GfFileExists(path)) {
|
||||||
carhdle = GfParmReadFile(path, GFPARM_RMODE_STD);
|
carhdle = GfParmReadFile(path, GFPARM_RMODE_STD);
|
||||||
if (carhdle) {
|
if (carhdle) {
|
||||||
//GfLogDebug(" Car XML OK : %s\n", path);
|
|
||||||
if (curDrv->carParmHdle)
|
|
||||||
GfParmReleaseHandle(curDrv->carParmHdle);
|
|
||||||
curDrv->carParmHdle = carhdle;
|
|
||||||
if (curDrv->carName)
|
if (curDrv->carName)
|
||||||
free(curDrv->carName);
|
free(curDrv->carName);
|
||||||
curDrv->carName = strdup(carName);
|
curDrv->carName = strdup(carName);
|
||||||
|
carCat = GfParmGetStr(carhdle, SECT_CAR, PRM_CATEGORY, "");
|
||||||
|
if (curDrv->carCategory)
|
||||||
|
free(curDrv->carCategory);
|
||||||
|
curDrv->carCategory = strdup(carCat);
|
||||||
|
carRealName = GfParmGetName(carhdle);
|
||||||
|
if (curDrv->carRealName)
|
||||||
|
free(curDrv->carRealName);
|
||||||
|
curDrv->carRealName = strdup(carRealName);
|
||||||
|
GfParmReleaseHandle(carhdle);
|
||||||
} else {
|
} else {
|
||||||
GfLogError("Falling back to default car '%s' "
|
GfLogError("Falling back to default car '%s' "
|
||||||
"for %s because '%s' is not readable\n",
|
"for %s because '%s' is not readable\n",
|
||||||
|
@ -771,15 +844,10 @@ RmDriversSelect(void *vs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize Candidates scroll-list filter criteria and fill-in the scroll-list.
|
// Initialize driver type filter criteria to "all types".
|
||||||
CurDriverTypeIndex = 0;
|
CurDriverTypeIndex =
|
||||||
if (!initCarCat)
|
(std::find(VecDriverTypes.begin(), VecDriverTypes.end(), AnyDriverType)
|
||||||
initCarCat = AnyCarCategory;
|
- VecDriverTypes.begin() + VecDriverTypes.size()) % VecDriverTypes.size();
|
||||||
CurCarCategoryIndex = std::find(VecCarCategories.begin(), VecCarCategories.end(), initCarCat) - VecCarCategories.begin();
|
|
||||||
CurCarCategoryIndex = CurCarCategoryIndex % VecCarCategories.size();
|
|
||||||
rmdsFilterDriverScrollList(initCarCat, AnyDriverType);
|
|
||||||
GfuiLabelSetText(ScrHandle, DriverTypeEditId, AnyDriverType);
|
|
||||||
GfuiLabelSetText(ScrHandle, CarCategoryEditId, initCarCat);
|
|
||||||
|
|
||||||
// Picked Driver Info
|
// Picked Driver Info
|
||||||
PickedDriverTypeLabelId = CreateLabelControl(ScrHandle,menuDescHdle,"pickeddrivertypelabel");
|
PickedDriverTypeLabelId = CreateLabelControl(ScrHandle,menuDescHdle,"pickeddrivertypelabel");
|
||||||
|
@ -808,6 +876,7 @@ rmdsCleanup(void)
|
||||||
trmdDrvElt *curDrv;
|
trmdDrvElt *curDrv;
|
||||||
|
|
||||||
VecCarCategories.clear();
|
VecCarCategories.clear();
|
||||||
|
VecCarCategoryNames.clear();
|
||||||
VecDriverTypes.clear();
|
VecDriverTypes.clear();
|
||||||
VecCurDriverSkinNames.clear();
|
VecCurDriverSkinNames.clear();
|
||||||
MapCurDriverSkinPreviewFiles.clear();
|
MapCurDriverSkinPreviewFiles.clear();
|
||||||
|
@ -817,9 +886,10 @@ rmdsCleanup(void)
|
||||||
free(curDrv->name);
|
free(curDrv->name);
|
||||||
free(curDrv->moduleName);
|
free(curDrv->moduleName);
|
||||||
free(curDrv->carName);
|
free(curDrv->carName);
|
||||||
|
free(curDrv->carRealName);
|
||||||
|
free(curDrv->carCategory);
|
||||||
if (curDrv->skinName)
|
if (curDrv->skinName)
|
||||||
free(curDrv->skinName);
|
free(curDrv->skinName);
|
||||||
GfParmReleaseHandle(curDrv->carParmHdle);
|
|
||||||
free(curDrv);
|
free(curDrv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include "carinfo.h"
|
#include "carinfo.h"
|
||||||
|
|
||||||
|
@ -31,8 +31,11 @@ struct PrivateData
|
||||||
// Map for quick access to CarData by name
|
// Map for quick access to CarData by name
|
||||||
std::map<std::string, int> mapCarNameIndices;
|
std::map<std::string, int> mapCarNameIndices;
|
||||||
|
|
||||||
// Set of category names.
|
// Vector of category names.
|
||||||
std::set<std::string> setCategoryNames;
|
std::vector<std::string> vecCategoryNames;
|
||||||
|
|
||||||
|
// Vector of category real names.
|
||||||
|
std::vector<std::string> vecCategoryRealNames;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,12 +58,14 @@ CarInfo::CarInfo()
|
||||||
tFList *curFile;
|
tFList *curFile;
|
||||||
void *carParmHdle;
|
void *carParmHdle;
|
||||||
|
|
||||||
// Load the category list from the "cars" folder contents.
|
// Load the car list from the "cars" folder contents.
|
||||||
curFile = files = GfDirGetList("cars");
|
curFile = files = GfDirGetList("cars");
|
||||||
if (curFile)
|
if (curFile)
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
//GfLogDebug("Examining car %s\n", curFile->name);
|
||||||
|
|
||||||
// Ignore "." and ".." folders.
|
// Ignore "." and ".." folders.
|
||||||
if (curFile->name[0] == '.')
|
if (curFile->name[0] == '.')
|
||||||
continue;
|
continue;
|
||||||
|
@ -77,7 +82,7 @@ CarInfo::CarInfo()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read car info and store it in the CarData structure.
|
// Read car info and store it in the CarData structure (category real name = later).
|
||||||
CarData carData;
|
CarData carData;
|
||||||
carData.strName = pszCarName;
|
carData.strName = pszCarName;
|
||||||
carData.strCategoryName = GfParmGetStr(carParmHdle, "Car", "category", "");
|
carData.strCategoryName = GfParmGetStr(carParmHdle, "Car", "category", "");
|
||||||
|
@ -87,7 +92,10 @@ CarInfo::CarInfo()
|
||||||
// Update the CarInfo singleton.
|
// Update the CarInfo singleton.
|
||||||
m_priv->vecCars.push_back(carData);
|
m_priv->vecCars.push_back(carData);
|
||||||
m_priv->mapCarNameIndices[pszCarName] = m_priv->vecCars.size() - 1;
|
m_priv->mapCarNameIndices[pszCarName] = m_priv->vecCars.size() - 1;
|
||||||
m_priv->setCategoryNames.insert(carData.strCategoryName);
|
if (std::find(m_priv->vecCategoryNames.begin(),
|
||||||
|
m_priv->vecCategoryNames.end(), carData.strCategoryName)
|
||||||
|
== m_priv->vecCategoryNames.end())
|
||||||
|
m_priv->vecCategoryNames.push_back(carData.strCategoryName);
|
||||||
|
|
||||||
// Close the XML file of the car.
|
// Close the XML file of the car.
|
||||||
GfParmReleaseHandle(carParmHdle);
|
GfParmReleaseHandle(carParmHdle);
|
||||||
|
@ -96,6 +104,24 @@ CarInfo::CarInfo()
|
||||||
}
|
}
|
||||||
|
|
||||||
GfDirFreeList(files, NULL, true, true);
|
GfDirFreeList(files, NULL, true, true);
|
||||||
|
|
||||||
|
// Sort car categories.
|
||||||
|
std::sort(m_priv->vecCategoryNames.begin(), m_priv->vecCategoryNames.end());
|
||||||
|
|
||||||
|
// Set car category real name (only here because m_priv->vecCategoryNames
|
||||||
|
// has to be completed before we can GetCategoryRealNames().
|
||||||
|
const std::vector<std::string> vecCatRealNames = GetCategoryRealNames();
|
||||||
|
std::vector<std::string>::const_iterator iterCatName;
|
||||||
|
for (int nCatIndex = 0; nCatIndex < m_priv->vecCategoryNames.size(); nCatIndex++)
|
||||||
|
{
|
||||||
|
std::vector<CarData*> vecCarsInCat =
|
||||||
|
GetCarsInCategory(m_priv->vecCategoryNames[nCatIndex]);
|
||||||
|
std::vector<CarData*>::iterator iterCar;
|
||||||
|
for (iterCar = vecCarsInCat.begin(); iterCar != vecCarsInCat.end(); iterCar++)
|
||||||
|
(*iterCar)->strCategoryRealName = vecCatRealNames[nCatIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
print();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CarInfo::GetCarRealName(const std::string& strCarName) const
|
std::string CarInfo::GetCarRealName(const std::string& strCarName) const
|
||||||
|
@ -124,28 +150,63 @@ std::vector<std::string> CarInfo::GetCarNamesInCategory(const std::string& strCa
|
||||||
return vecCarNames;
|
return vecCarNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<CarData> CarInfo::GetCarsInCategory(const std::string& strCatName) const
|
std::vector<CarData*> CarInfo::GetCarsInCategory(const std::string& strCatName) const
|
||||||
{
|
{
|
||||||
std::vector<CarData> vecCarsInCat;
|
std::vector<CarData*> vecCarsInCat;
|
||||||
|
|
||||||
std::vector<CarData>::const_iterator iterCar;
|
std::vector<CarData>::iterator iterCar;
|
||||||
for (iterCar = m_priv->vecCars.begin(); iterCar != m_priv->vecCars.end(); iterCar++)
|
for (iterCar = m_priv->vecCars.begin(); iterCar != m_priv->vecCars.end(); iterCar++)
|
||||||
if (strCatName == "All" || iterCar->strCategoryName == strCatName)
|
if (strCatName == "All" || iterCar->strCategoryName == strCatName)
|
||||||
vecCarsInCat.push_back(*iterCar);
|
vecCarsInCat.push_back(&(*iterCar));
|
||||||
|
|
||||||
return vecCarsInCat;
|
return vecCarsInCat;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> CarInfo::GetCategoryNames() const
|
std::vector<CarData*> CarInfo::GetCarsInCategoryRealName(const std::string& strCatRealName) const
|
||||||
{
|
{
|
||||||
std::vector<std::string> vecCatNames;
|
std::vector<CarData*> vecCarsInCat;
|
||||||
|
|
||||||
std::set<std::string>::const_iterator iterCat;
|
std::vector<CarData>::iterator iterCar;
|
||||||
for (iterCat = m_priv->setCategoryNames.begin();
|
for (iterCar = m_priv->vecCars.begin(); iterCar != m_priv->vecCars.end(); iterCar++)
|
||||||
iterCat != m_priv->setCategoryNames.end(); iterCat++)
|
if (strCatRealName == "All" || iterCar->strCategoryRealName == strCatRealName)
|
||||||
vecCatNames.push_back(*iterCat);
|
vecCarsInCat.push_back(&(*iterCar));
|
||||||
|
|
||||||
return vecCatNames;
|
return vecCarsInCat;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string>& CarInfo::GetCategoryNames() const
|
||||||
|
{
|
||||||
|
return m_priv->vecCategoryNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string>& CarInfo::GetCategoryRealNames() const
|
||||||
|
{
|
||||||
|
if (m_priv->vecCategoryRealNames.empty())
|
||||||
|
{
|
||||||
|
std::vector<std::string>::const_iterator iterCatName;
|
||||||
|
for (iterCatName = m_priv->vecCategoryNames.begin();
|
||||||
|
iterCatName != m_priv->vecCategoryNames.end(); iterCatName++)
|
||||||
|
{
|
||||||
|
std::ostringstream ossCatFileName;
|
||||||
|
ossCatFileName << "categories/" << *iterCatName << PARAMEXT;
|
||||||
|
const std::string strCatFileName = ossCatFileName.str();
|
||||||
|
void* hCat = GfParmReadFile(strCatFileName.c_str(), GFPARM_RMODE_STD);
|
||||||
|
if (hCat)
|
||||||
|
{
|
||||||
|
m_priv->vecCategoryRealNames.push_back(GfParmGetName(hCat));
|
||||||
|
GfParmReleaseHandle(hCat);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_priv->vecCategoryRealNames.push_back(*iterCatName); // Fall-back.
|
||||||
|
GfLogWarning("Car category file %s not %s\n",
|
||||||
|
strCatFileName.c_str(),
|
||||||
|
GfFileExists(strCatFileName.c_str()) ? "readable" : "found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_priv->vecCategoryRealNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> CarInfo::GetCarRealNamesInCategory(const std::string& strCatName) const
|
std::vector<std::string> CarInfo::GetCarRealNamesInCategory(const std::string& strCatName) const
|
||||||
|
@ -182,19 +243,20 @@ CarData* CarInfo::GetCarData(const std::string& strCarName) const
|
||||||
|
|
||||||
void CarInfo::print() const
|
void CarInfo::print() const
|
||||||
{
|
{
|
||||||
GfLogDebug("CarInfo : %d cars, %d categories\n",
|
GfLogDebug("Found %d cars in %d categories\n",
|
||||||
m_priv->vecCars.size(), m_priv->setCategoryNames.size());
|
m_priv->vecCars.size(), m_priv->vecCategoryNames.size());
|
||||||
std::set<std::string>::const_iterator iterCat;
|
std::vector<std::string>::const_iterator iterCat;
|
||||||
for (iterCat = m_priv->setCategoryNames.begin();
|
for (int nCatIndex = 0; nCatIndex < m_priv->vecCategoryNames.size(); nCatIndex++)
|
||||||
iterCat != m_priv->setCategoryNames.end(); iterCat++)
|
|
||||||
{
|
{
|
||||||
GfLogDebug(" %s category :\n", iterCat->c_str());
|
GfLogDebug(" %s (%s) :\n", m_priv->vecCategoryRealNames[nCatIndex].c_str(),
|
||||||
const std::vector<CarData> vecCarsInCat = GetCarsInCategory(iterCat->c_str());
|
m_priv->vecCategoryNames[nCatIndex].c_str());
|
||||||
std::vector<CarData>::const_iterator iterCar;
|
const std::vector<CarData*> vecCarsInCat =
|
||||||
|
GetCarsInCategory(m_priv->vecCategoryNames[nCatIndex]);
|
||||||
|
std::vector<CarData*>::const_iterator iterCar;
|
||||||
for (iterCar = vecCarsInCat.begin(); iterCar != vecCarsInCat.end(); iterCar++)
|
for (iterCar = vecCarsInCat.begin(); iterCar != vecCarsInCat.end(); iterCar++)
|
||||||
{
|
{
|
||||||
GfLogDebug(" %s (%s) : %s\n", iterCar->strRealName.c_str(),
|
GfLogDebug(" %s (%s) : %s\n", (*iterCar)->strRealName.c_str(),
|
||||||
iterCar->strName.c_str(), iterCar->strXMLPath.c_str());
|
(*iterCar)->strName.c_str(), (*iterCar)->strXMLPath.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ public:
|
||||||
std::string strName; // XML file / folder name (ex: "sc-boxer-96")
|
std::string strName; // XML file / folder name (ex: "sc-boxer-96")
|
||||||
std::string strRealName; // User friendly name (ex: "SC Boxer 96").
|
std::string strRealName; // User friendly name (ex: "SC Boxer 96").
|
||||||
std::string strCategoryName; // Category name (ex: "LS-GT1").
|
std::string strCategoryName; // Category name (ex: "LS-GT1").
|
||||||
|
std::string strCategoryRealName; // Category name (ex: "Long Day Series GT1").
|
||||||
std::string strXMLPath; // Path-name of the car XML file.
|
std::string strXMLPath; // Path-name of the car XML file.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -42,13 +43,15 @@ public:
|
||||||
// Accessor to the unique instance of the singleton.
|
// Accessor to the unique instance of the singleton.
|
||||||
static CarInfo* self();
|
static CarInfo* self();
|
||||||
|
|
||||||
std::vector<std::string> GetCategoryNames() const;
|
const std::vector<std::string>& GetCategoryNames() const;
|
||||||
|
const std::vector<std::string>& GetCategoryRealNames() const;
|
||||||
|
|
||||||
CarData* GetCarData(const std::string& strCarName) const;
|
CarData* GetCarData(const std::string& strCarName) const;
|
||||||
std::string GetCarRealName(const std::string& strCarName) const;
|
std::string GetCarRealName(const std::string& strCarName) const;
|
||||||
CarData* GetCarDataFromRealName(const std::string& strCarRealName) const;
|
CarData* GetCarDataFromRealName(const std::string& strCarRealName) const;
|
||||||
|
|
||||||
std::vector<CarData> GetCarsInCategory(const std::string& strCatName = "All") const;
|
std::vector<CarData*> GetCarsInCategory(const std::string& strCatName = "All") const;
|
||||||
|
std::vector<CarData*> GetCarsInCategoryRealName(const std::string& strCatRealName = "All") const;
|
||||||
std::vector<std::string> GetCarNamesInCategory(const std::string& strCatName = "All") const;
|
std::vector<std::string> GetCarNamesInCategory(const std::string& strCatName = "All") const;
|
||||||
std::vector<std::string> GetCarRealNamesInCategory(const std::string& strCatName = "All") const;
|
std::vector<std::string> GetCarRealNamesInCategory(const std::string& strCatName = "All") const;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue