From e5e83f3921b2faf1ba354e70b42aba7477e1522a Mon Sep 17 00:00:00 2001 From: Xavier Del Campo Romero Date: Sat, 18 Jan 2025 09:35:46 +0100 Subject: [PATCH] Support reading trackdata from GfLocalDir() This would allow users to extract track data into GfLocalDir(), which is guaranteed to have write permissions, as opposed to GfDataDir(). --- src/libs/tgfdata/tracks.cpp | 31 ++++++---- src/libs/tgfdata/tracks.h | 2 + src/modules/graphic/osggraph/OsgMain.cpp | 10 ++- .../osggraph/Scenery/OsgBackground.cpp | 11 ++-- .../graphic/osggraph/Scenery/OsgPit.cpp | 14 +++-- .../graphic/osggraph/Scenery/OsgScenery.cpp | 61 ++++++++----------- .../graphic/osggraph/Scenery/OsgScenery.h | 8 +-- src/modules/graphic/ssggraph/grbackground.cpp | 13 ++-- src/modules/graphic/ssggraph/grmain.cpp | 7 ++- src/modules/graphic/ssggraph/grscene.cpp | 16 ++++- src/modules/graphic/ssggraph/grscene.h | 2 + src/modules/track/trackv1/track.cpp | 9 ++- .../racescreens/csnetworkingmenu.cpp | 44 +++++++------ .../legacymenu/racescreens/networkingmenu.cpp | 44 +++++++------ 14 files changed, 160 insertions(+), 112 deletions(-) diff --git a/src/libs/tgfdata/tracks.cpp b/src/libs/tgfdata/tracks.cpp index 03d3d7fa8..2327c7d1e 100644 --- a/src/libs/tgfdata/tracks.cpp +++ b/src/libs/tgfdata/tracks.cpp @@ -86,10 +86,8 @@ GfTracks::~GfTracks() _pPrivate = 0; } -GfTracks::GfTracks() +void GfTracks::list(const std::string &path) { - _pPrivate = new GfTracks::Private; - // Get the list of sub-dirs in the "tracks" folder (the track categories). tFList* lstCatFolders = GfDirGetList("tracks"); if (!lstCatFolders) @@ -113,7 +111,7 @@ GfTracks::GfTracks() continue; // Get the list of sub-dirs in the "tracks" folder (the track categories). - std::string strDirName("tracks/"); + std::string strDirName(path); strDirName += pszCatId; tFList* lstTrackFolders = GfDirGetList(strDirName.c_str()); if (!lstTrackFolders) @@ -143,7 +141,7 @@ GfTracks::GfTracks() continue; std::ostringstream ossFileName; - ossFileName << "tracks/" << pszCatId << '/' << pszTrackId + ossFileName << path << pszCatId << '/' << pszTrackId << '/' << pszTrackId << '.' << TRKEXT; const std::string strTrackFileName(ossFileName.str()); if (!GfFileExists(strTrackFileName.c_str())) @@ -155,13 +153,13 @@ GfTracks::GfTracks() // Get 1st level track info (those which don't need to open any file). ossFileName.str(""); - ossFileName << "tracks/" << pszCatId << '/' << pszTrackId + ossFileName << path << pszCatId << '/' << pszTrackId << '/' << pszTrackId << ".jpg"; std::string strPreviewFileName(ossFileName.str()); if (!GfFileExists(strPreviewFileName.c_str())) { ossFileName.str(""); - ossFileName << "tracks/" << pszCatId << '/' << pszTrackId + ossFileName << path << pszCatId << '/' << pszTrackId << '/' << pszTrackId << ".png"; strPreviewFileName = ossFileName.str(); } @@ -169,7 +167,7 @@ GfTracks::GfTracks() strPreviewFileName = "data/img/splash-trackselect.jpg"; ossFileName.str(""); - ossFileName << "tracks/" << pszCatId << '/' << pszTrackId << '/' << "outline.png"; + ossFileName << path << pszCatId << '/' << pszTrackId << '/' << "outline.png"; std::string strOutlineFileName(ossFileName.str()); if (!GfFileExists(strOutlineFileName.c_str())) strOutlineFileName = "data/img/notrackoutline.png"; @@ -201,6 +199,14 @@ GfTracks::GfTracks() print(false); // No verbose here, otherwise infinite recursion. } +GfTracks::GfTracks() +{ + _pPrivate = new GfTracks::Private; + + list(std::string(GfLocalDir()) + "tracks/"); + list(std::string(GfDataDir()) + "tracks/"); +} + ITrackLoader* GfTracks::getTrackLoader() const { return _pPrivate->piTrackLoader; @@ -226,7 +232,7 @@ const std::vector& GfTracks::getCategoryNames() const { std::ostringstream ossFileName; ossFileName << "data/tracks/" << *itCatId << '.' << TRKEXT; - void* hparmCat = GfParmReadFile(ossFileName.str(), GFPARM_RMODE_STD); + void* hparmCat = GfParmReadFileBoth(ossFileName.str(), GFPARM_RMODE_STD); const char* pszCatName; if (!hparmCat) { @@ -624,10 +630,13 @@ bool GfTrack::load() const std::ostringstream ossFileName; ossFileName << "tracks/" << _strCatId << '/' << _strId << '/' << (pTrack->graphic.model3d ? pTrack->graphic.model3d : "track.ac"); - if (!GfFileExists(ossFileName.str().c_str())) + std::string path = ossFileName.str(); + + if (!GfFileExists((GfLocalDir() + path).c_str()) + && !GfFileExists((GfDataDir() + path).c_str())) { GfLogWarning("Unusable track %s : could not find 3D model %s\n", - _strId.c_str(), ossFileName.str().c_str()); + _strId.c_str(), path.c_str()); return false; } diff --git a/src/libs/tgfdata/tracks.h b/src/libs/tgfdata/tracks.h index 51ba31e8a..10f94c20d 100644 --- a/src/libs/tgfdata/tracks.h +++ b/src/libs/tgfdata/tracks.h @@ -128,6 +128,8 @@ protected: GfTracks(); ~GfTracks(); + void list(const std::string &path); + protected: // The singleton itself. diff --git a/src/modules/graphic/osggraph/OsgMain.cpp b/src/modules/graphic/osggraph/OsgMain.cpp index 1722bc645..6f083799d 100644 --- a/src/modules/graphic/osggraph/OsgMain.cpp +++ b/src/modules/graphic/osggraph/OsgMain.cpp @@ -530,7 +530,11 @@ int initTrack(tTrack *track) // TODO: Find a solution to init the graphics first independent of objects. // Now, do the real track loading job. - grTrackHandle = GfParmReadFile(track->filename, GFPARM_RMODE_STD | GFPARM_RMODE_CREAT); + grTrackHandle = GfParmReadFileBoth(track->filename, GFPARM_RMODE_STD); + if (!grTrackHandle) { + GfLogError("GfParmReadFileBoth %s failed\n", track->filename); + return -1; + } //Options = new SDOptions; @@ -538,7 +542,9 @@ int initTrack(tTrack *track) render = new SDRender; //cam = new SDCamera; - scenery->LoadScene(track); + if (scenery->LoadScene(track)) + return -1; + render->Init(track); Clouds = track->local.clouds; diff --git a/src/modules/graphic/osggraph/Scenery/OsgBackground.cpp b/src/modules/graphic/osggraph/Scenery/OsgBackground.cpp index c05d36ebe..343fc7d01 100644 --- a/src/modules/graphic/osggraph/Scenery/OsgBackground.cpp +++ b/src/modules/graphic/osggraph/Scenery/OsgBackground.cpp @@ -44,13 +44,16 @@ void SDBackground::build(int X, int Y, int Z, const std::string& TrackPath) { osgDB::Registry::instance()->clearObjectCache(); - std::string LocalPath = GfDataDir(); + std::string DataPath = GfDataDir(), LocalPath = GfLocalDir(); osgDB::FilePathList pathList = osgDB::Registry::instance()->getDataFilePathList(); - pathList.push_front(LocalPath+"data/objects/"); - pathList.push_front(LocalPath+"data/textures/"); - pathList.push_front(TrackPath); + pathList.push_front(DataPath + "data/objects/"); + pathList.push_front(DataPath + "data/textures/"); + pathList.push_front(DataPath + TrackPath); + pathList.push_front(LocalPath + "data/objects/"); + pathList.push_front(LocalPath + "data/textures/"); + pathList.push_front(LocalPath + TrackPath); osgDB::Registry::instance()->setDataFilePathList(pathList); //osg::ref_ptr _background_transform = new osg::MatrixTransform; diff --git a/src/modules/graphic/osggraph/Scenery/OsgPit.cpp b/src/modules/graphic/osggraph/Scenery/OsgPit.cpp index 4c4309fde..e4d60d113 100644 --- a/src/modules/graphic/osggraph/Scenery/OsgPit.cpp +++ b/src/modules/graphic/osggraph/Scenery/OsgPit.cpp @@ -422,10 +422,16 @@ void SDPit::build(const tTrack *track) // load pit indicator if (bHasPitIndicator) { - loader.AddSearchPath(std::string("tracks/") + track->category + "/" + track->internalname); - loader.AddSearchPath("data/objects"); - loader.AddSearchPath("data/textures"); - loader.AddSearchPath("data/img"); + std::string localdir = GfLocalDir(), datadir = GfDataDir(); + loader.AddSearchPath(localdir + "tracks/" + track->category + "/" + track->internalname); + loader.AddSearchPath(localdir + "data/objects"); + loader.AddSearchPath(localdir + "data/textures"); + loader.AddSearchPath(localdir + "data/img"); + + loader.AddSearchPath(datadir + "tracks/" + track->category + "/" + track->internalname); + loader.AddSearchPath(datadir + "data/objects"); + loader.AddSearchPath(datadir + "data/textures"); + loader.AddSearchPath(datadir + "data/img"); std::string filename = pits->pitindicator == 1 ? "pit_indicator.ac" diff --git a/src/modules/graphic/osggraph/Scenery/OsgScenery.cpp b/src/modules/graphic/osggraph/Scenery/OsgScenery.cpp index 2cd14ca1b..580ae8f92 100644 --- a/src/modules/graphic/osggraph/Scenery/OsgScenery.cpp +++ b/src/modules/graphic/osggraph/Scenery/OsgScenery.cpp @@ -69,7 +69,7 @@ SDScenery::~SDScenery(void) } } -void SDScenery::LoadScene(const tTrack *track) +int SDScenery::LoadScene(const tTrack *track) { void *hndl = grTrackHandle; const char *acname; @@ -118,44 +118,37 @@ void SDScenery::LoadScene(const tTrack *track) GfLogError("No specified track 3D model file\n"); } - std::string PathTmp = GfDataDir(); - _bgsky = strcmp(GfParmGetStr(grHandle, GR_SCT_GRAPHIC, GR_ATT_DYNAMICSKYDOME, GR_ATT_DYNAMICSKYDOME_DISABLED), GR_ATT_DYNAMICSKYDOME_ENABLED) == 0; if (_bgsky) { - std::string strPath = PathTmp; - snprintf(buf, 256, "tracks/%s/%s/", SDTrack->category, SDTrack->internalname); - strPath += buf; - m_background->build(grWrldX, grWrldY, grWrldZ, strPath); + snprintf(buf, 256, "tracks/%s/%s/", track->category, track->internalname); + m_background->build(grWrldX, grWrldY, grWrldZ, buf); GfLogDebug("Background loaded\n"); } - std::string strPath = GfDataDir(); - snprintf(buf, 256, "tracks/%s/%s/", SDTrack->category, SDTrack->internalname); + snprintf(buf, 256, "tracks/%s/%s/", track->category, track->internalname); std::string ext = osgDB::getFileExtension(acname); if (ext == "acc") { GfLogDebug("Load 3D Model Scene ACC\n"); - strPath+=buf; - _strTexturePath = strPath; - strPath+=acname; - - LoadTrack(strPath); + if (!LoadTrack(buf, acname)) + { + GfLogError("LoadTrack %s%s failed\n", buf, acname); + return -1; + } } else { - strPath+=buf; - - std::string strTPath = GfDataDir(); + std::string localdir = GfLocalDir(), datadir = GfDataDir(); osgDB::FilePathList pathList = osgDB::Registry::instance()->getDataFilePathList(); - pathList.push_back(strPath); - GfLogDebug("Track Path : %s\n", pathList.back().c_str()); - pathList.push_back(strTPath+"data/objects/"); - GfLogDebug("Texture Path : %s\n", pathList.back().c_str()); - pathList.push_back(strTPath+"data/textures/"); - GfLogDebug("Texture Path : %s\n", pathList.back().c_str()); + pathList.push_back(localdir + buf); + pathList.push_back(localdir + "data/objects/"); + pathList.push_back(localdir + "data/textures/"); + pathList.push_back(datadir + buf); + pathList.push_back(datadir + "data/objects/"); + pathList.push_back(datadir + "data/textures/"); osgDB::Registry::instance()->setDataFilePathList(pathList); osg::ref_ptr pTrack = osgDB::readNodeFile(acname); @@ -184,6 +177,7 @@ void SDScenery::LoadScene(const tTrack *track) osgDB::Registry::instance()->setDataFilePathList( osgDB::FilePathList() ); osgDB::Registry::instance()->clearObjectCache(); + return 0; } void SDScenery::LoadSkyOptions() @@ -219,22 +213,19 @@ void SDScenery::ShutdownScene(void) _scenery = NULL; } -bool SDScenery::LoadTrack(std::string& strTrack) +bool SDScenery::LoadTrack(const std::string &dir, const std::string &file) { - std::string name; - GfLogDebug("Track Path : %s\n", strTrack.c_str()); + std::string localdir = GfLocalDir(); osgLoader loader; - GfLogDebug("Texture Path : %s\n", _strTexturePath.c_str()); - loader.AddSearchPath(_strTexturePath); + loader.AddSearchPath(dir); + loader.AddSearchPath(localdir + "data/textures/"); + loader.AddSearchPath("data/textures/"); - std::string strTPath = GfDataDir(); - strTPath += "data/textures/"; - GfLogDebug("Texture Path : %s\n", strTPath.c_str()); - loader.AddSearchPath(strTPath); + std::string path = dir + file; + osg::Node *pTrack; - osg::Node *pTrack = loader.Load3dFile(strTrack, false, "", name); - - if (pTrack) + if ((pTrack = loader.Load3dFile(GfLocalDir() + path)) + || (pTrack = loader.Load3dFile(path))) { pTrack->getOrCreateStateSet()->setRenderBinDetails(TRACKBIN,"RenderBin"); _scenery->addChild(pTrack); diff --git a/src/modules/graphic/osggraph/Scenery/OsgScenery.h b/src/modules/graphic/osggraph/Scenery/OsgScenery.h index a29d83a23..79c5a8fa8 100644 --- a/src/modules/graphic/osggraph/Scenery/OsgScenery.h +++ b/src/modules/graphic/osggraph/Scenery/OsgScenery.h @@ -104,8 +104,6 @@ private: osg::ref_ptr _scenery; - tTrack *SDTrack; - int _max_visibility; int _nb_cloudlayer; int _DynamicSkyDome; @@ -116,8 +114,6 @@ private: bool _speedWay; bool _speedWayLong; - std::string _strTexturePath; - static double grWrldX; static double grWrldY; static double grWrldZ; @@ -126,7 +122,7 @@ private: void LoadGraphicsOptions(); void LoadSkyOptions(); void CustomizePits(void); - bool LoadTrack(std::string& strTrack); + bool LoadTrack(const std::string &dir, const std::string &file); public: /* Constructor */ @@ -135,7 +131,7 @@ public: /* Destructor */ ~SDScenery(void); - void LoadScene(const tTrack *track); + int LoadScene(const tTrack *track); void ShutdownScene(void); void reposition(double X, double Y, double Z); void update_tracklights(double currentTime, double totTime, int raceType); diff --git a/src/modules/graphic/ssggraph/grbackground.cpp b/src/modules/graphic/ssggraph/grbackground.cpp index c3b251aa4..f4422e2e9 100644 --- a/src/modules/graphic/ssggraph/grbackground.cpp +++ b/src/modules/graphic/ssggraph/grbackground.cpp @@ -502,8 +502,11 @@ grLoadBackground() GfLogDebug("Loading background ...\n"); - snprintf(buf, sizeof(buf), "tracks/%s/%s;data/img;data/textures;.", - grTrack->category, grTrack->internalname); + std::string trackpath = grTrackPath(); + const char *track = trackpath.c_str(); + + snprintf(buf, sizeof(buf), "%s%s;%s;data/img;data/textures;.", + GfLocalDir(), track, track); grSetFilePath(buf); grGammaValue = 1.8; grMipMap = 0; @@ -894,11 +897,13 @@ void grLoadBackgroundSky(void) char buf2[256]; const char *bgsky; ssgEntity *desc2; + std::string trackpath = grTrackPath(); + const char *track = trackpath.c_str(); bgsky = "background-sky.ac"; - snprintf(buf2, sizeof(buf2), "tracks/%s/%s;data/textures;.", grTrack->category, grTrack->internalname); + snprintf(buf2, sizeof(buf2), "%s%s;%s;data/textures;.", GfLocalDir(), track, track); ssgTexturePath(buf2); - snprintf(buf2, sizeof(buf2), "tracks/%s/%s;data/objects", grTrack->category, grTrack->internalname); + snprintf(buf2, sizeof(buf2), "%s%s;%s;data/objects", GfLocalDir(), track, track); ssgModelPath(buf2); desc2 = grssgLoadAC3D(bgsky, NULL); diff --git a/src/modules/graphic/ssggraph/grmain.cpp b/src/modules/graphic/ssggraph/grmain.cpp index 848b3296d..fe6313680 100644 --- a/src/modules/graphic/ssggraph/grmain.cpp +++ b/src/modules/graphic/ssggraph/grmain.cpp @@ -952,7 +952,12 @@ initTrack(tTrack *track) grssgSetCurrentOptions(&options); // Now, do the real track loading job. - grTrackHandle = GfParmReadFile(track->filename, GFPARM_RMODE_STD | GFPARM_RMODE_CREAT); + grTrackHandle = GfParmReadFileBoth(track->filename, GFPARM_RMODE_STD); + if (!grTrackHandle) { + GfLogError("GfParmReadFileBoth %s failed\n", track->filename); + return -1; + } + if (grNbActiveScreens > 0) return grLoadScene(track); diff --git a/src/modules/graphic/ssggraph/grscene.cpp b/src/modules/graphic/ssggraph/grscene.cpp index cb2f3da3f..a44441c35 100644 --- a/src/modules/graphic/ssggraph/grscene.cpp +++ b/src/modules/graphic/ssggraph/grscene.cpp @@ -77,6 +77,16 @@ ssgBranch *CarlightAnchor = NULL; ssgBranch *TrackLightAnchor = NULL; ssgBranch *ThePits = NULL; +std::string +grTrackPath() +{ + std::string trackpath = "tracks/"; + trackpath += grTrack->category; + trackpath += "/"; + trackpath += grTrack->internalname; + + return trackpath; +} // Must have (Question: What for ?) int preScene(ssgEntity *e) @@ -227,9 +237,11 @@ grLoadScene(tTrack *track) if ( grSkyDomeDistance > 0 ) grLoadBackgroundSky(); - snprintf(buf, sizeof(buf), "tracks/%s/%s;data/textures;data/img;.", grTrack->category, grTrack->internalname); + std::string trackpath = grTrackPath(); + const char *tr = trackpath.c_str(); + snprintf(buf, sizeof(buf), "%s%s;%s;data/textures;data/img;.", GfLocalDir(), tr, tr); ssgTexturePath(buf); - snprintf(buf, sizeof(buf), "tracks/%s/%s", grTrack->category, grTrack->internalname); + snprintf(buf, sizeof(buf), "%s%s;%s", GfLocalDir(), tr, tr); ssgModelPath(buf); desc = grssgLoadAC3D(acname, NULL); diff --git a/src/modules/graphic/ssggraph/grscene.h b/src/modules/graphic/ssggraph/grscene.h index 8b5b4732a..6f198e3d9 100644 --- a/src/modules/graphic/ssggraph/grscene.h +++ b/src/modules/graphic/ssggraph/grscene.h @@ -27,6 +27,7 @@ #include //tTrack #include // tSituation #include "grmultitexstate.h" +#include namespace ssggraph { @@ -67,6 +68,7 @@ extern void grShutdownScene(void); extern void grCustomizePits(void); extern void grLoadPitsIndicator(tdble x,tdble y, tdble z, char *buf, int Pitind); extern void grDrawBackground(class cGrCamera *, class cGrBackgroundCam *bgCam); +std::string grTrackPath(); //TODO: Question: What is this??? kilo // Possible answer: Some try to lower GPU load by filtering the scene ? JP diff --git a/src/modules/track/trackv1/track.cpp b/src/modules/track/trackv1/track.cpp index c2bc7ef9c..c14df5e9f 100644 --- a/src/modules/track/trackv1/track.cpp +++ b/src/modules/track/trackv1/track.cpp @@ -46,12 +46,15 @@ tTrack * TrackBuildv1(const char *trackfile) { TrackShutdown(); + void *h = GfParmReadFileBoth (trackfile, GFPARM_RMODE_STD); + + if (!h) + return nullptr; theTrack = (tTrack*)calloc(1, sizeof(tTrack)); theCamList = (tRoadCam*)NULL; - theTrack->params = TrackHandle = - GfParmReadFile (trackfile, GFPARM_RMODE_STD | GFPARM_RMODE_CREAT | GFPARM_RMODE_PRIVATE); + theTrack->params = TrackHandle = h; theTrack->filename = strdup(trackfile); @@ -86,7 +89,7 @@ TrackBuildEx(const char *trackfile) theTrack = (tTrack*)calloc(1, sizeof(tTrack)); theCamList = (tRoadCam*)NULL; - theTrack->params = TrackHandle = GfParmReadFile (trackfile, GFPARM_RMODE_STD | GFPARM_RMODE_CREAT | GFPARM_RMODE_PRIVATE); + theTrack->params = TrackHandle = GfParmReadFileBoth (trackfile, GFPARM_RMODE_STD); theTrack->filename = strdup(trackfile); diff --git a/src/modules/userinterface/legacymenu/racescreens/csnetworkingmenu.cpp b/src/modules/userinterface/legacymenu/racescreens/csnetworkingmenu.cpp index d7b0ae692..906b9f705 100644 --- a/src/modules/userinterface/legacymenu/racescreens/csnetworkingmenu.cpp +++ b/src/modules/userinterface/legacymenu/racescreens/csnetworkingmenu.cpp @@ -172,7 +172,7 @@ GetTrackName(const char *category, const char *trackName) std::string name; sprintf(buf, "tracks/%s/%s/%s.%s", category, trackName, trackName, TRKEXT); - trackHandle = GfParmReadFile(buf, GFPARM_RMODE_STD); + trackHandle = GfParmReadFileBoth(buf, GFPARM_RMODE_STD); if (trackHandle) { name = GfParmGetStr(trackHandle, TRK_SECT_HDR, TRK_ATT_NAME, trackName); @@ -195,37 +195,41 @@ GetTrackName(const char *category, const char *trackName) static std::string GetTrackPreviewFileName(const char *pszCategory, const char *pszTrack) { - char buf[256]; + static const char *extensions[] = {"jpg", "png"}; - // Try JPEG first. - snprintf(buf, sizeof(buf), "tracks/%s/%s/%s.jpg", pszCategory, pszTrack, pszTrack); - buf[255] = 0; /* snprinf manual is not clear about that ... */ - - // Then PNG if not found. - if (!GfFileExists(buf)) + for (size_t i = 0; i < sizeof extensions / sizeof *extensions; i++) { - snprintf(buf, sizeof(buf), "tracks/%s/%s/%s.png", pszCategory, pszTrack, pszTrack); - buf[255] = 0; /* snprinf manual is not clear about that ... */ + const char *ext = extensions[i]; + std::string dirs[] = {GfLocalDir(), GfDataDir()}; + + for (size_t i = 0; i < sizeof dirs / sizeof *dirs; i++) + { + std::string path = dirs[i] + "tracks/" + pszCategory + + "/" + pszTrack + "/" + pszTrack + "." + ext; + + if (GfFileExists(path.c_str())) + return path; + } } - // Then fallback. - if (!GfFileExists(buf)) - strncpy(buf, "data/img/splash-networkrace.jpg", sizeof(buf)); - - return std::string(buf); + return "data/img/splash-networkrace.jpg"; } static std::string GetTrackOutlineFileName(const char *pszCategory,const char *pszTrack) { - char buf[256]; + std::string dirs[] = {GfLocalDir(), GfDataDir()}; - snprintf(buf, sizeof(buf), "tracks/%s/%s/outline.png", pszCategory, pszTrack); + for (size_t i = 0; i < sizeof dirs / sizeof *dirs; i++) + { + std::string path = dirs[i] + "tracks/" + pszCategory + "/" + pszTrack + + "/outline.png"; - if (!GfFileExists(buf)) - strncpy(buf, "data/img/transparent.png", sizeof(buf)); + if (GfFileExists(path.c_str())) + return path; + } - return std::string(buf); + return "data/img/transparent.png"; } // Called by both server and client diff --git a/src/modules/userinterface/legacymenu/racescreens/networkingmenu.cpp b/src/modules/userinterface/legacymenu/racescreens/networkingmenu.cpp index e9079bf16..298646a9b 100644 --- a/src/modules/userinterface/legacymenu/racescreens/networkingmenu.cpp +++ b/src/modules/userinterface/legacymenu/racescreens/networkingmenu.cpp @@ -169,7 +169,7 @@ GetTrackName(const char *category, const char *trackName) std::string name; sprintf(buf, "tracks/%s/%s/%s.%s", category, trackName, trackName, TRKEXT); - trackHandle = GfParmReadFile(buf, GFPARM_RMODE_STD); + trackHandle = GfParmReadFileBoth(buf, GFPARM_RMODE_STD); if (trackHandle) { name = GfParmGetStr(trackHandle, TRK_SECT_HDR, TRK_ATT_NAME, trackName); @@ -192,37 +192,41 @@ GetTrackName(const char *category, const char *trackName) static std::string GetTrackPreviewFileName(const char *pszCategory, const char *pszTrack) { - char buf[256]; + static const char *extensions[] = {"jpg", "png"}; - // Try JPEG first. - snprintf(buf, sizeof(buf), "tracks/%s/%s/%s.jpg", pszCategory, pszTrack, pszTrack); - buf[255] = 0; /* snprinf manual is not clear about that ... */ + for (size_t i = 0; i < sizeof extensions / sizeof *extensions; i++) + { + const char *ext = extensions[i]; + std::string dirs[] = {GfLocalDir(), GfDataDir()}; - // Then PNG if not found. - if (!GfFileExists(buf)) - { - snprintf(buf, sizeof(buf), "tracks/%s/%s/%s.png", pszCategory, pszTrack, pszTrack); - buf[255] = 0; /* snprinf manual is not clear about that ... */ - } + for (size_t i = 0; i < sizeof dirs / sizeof *dirs; i++) + { + std::string path = dirs[i] + "tracks/" + pszCategory + + "/" + pszTrack + "/" + pszTrack + "." + ext; - // Then fallback. - if (!GfFileExists(buf)) - strncpy(buf, "data/img/splash-networkrace.jpg", sizeof(buf)); + if (GfFileExists(path.c_str())) + return path; + } + } - return std::string(buf); + return "data/img/splash-networkrace.jpg"; } static std::string GetTrackOutlineFileName(const char *pszCategory,const char *pszTrack) { - char buf[256]; + std::string dirs[] = {GfLocalDir(), GfDataDir()}; - snprintf(buf, sizeof(buf), "tracks/%s/%s/outline.png", pszCategory, pszTrack); + for (size_t i = 0; i < sizeof dirs / sizeof *dirs; i++) + { + std::string path = dirs[i] + "tracks/" + pszCategory + "/" + pszTrack + + "/outline.png"; - if (!GfFileExists(buf)) - strncpy(buf, "data/img/transparent.png", sizeof(buf)); + if (GfFileExists(path.c_str())) + return path; + } - return std::string(buf); + return "data/img/transparent.png"; } static void