From 6ffced1d9006e619d7e90abd7a124b73c1970eee Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Thu, 29 Mar 2018 03:48:21 +0200 Subject: [PATCH] file access cross-platform compatibility fixes --- DynObj.cpp | 15 ++++++++++----- EU07.cpp | 4 ++-- Event.cpp | 3 +-- MdlMngr.cpp | 7 ++++--- PyInt.cpp | 2 +- Texture.cpp | 5 +---- World.cpp | 2 +- audio.cpp | 5 +---- material.cpp | 11 ++++------- stars.cpp | 2 +- utilities.cpp | 9 +++++++++ utilities.h | 5 +++++ 12 files changed, 40 insertions(+), 30 deletions(-) diff --git a/DynObj.cpp b/DynObj.cpp index da4436ce..c188cc77 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -1733,7 +1733,8 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424" ) { // Ustawienie początkowe pojazdu iDirection = (Reversed ? 0 : 1); // Ra: 0, jeśli ma być wstawiony jako obrócony tyłem - asBaseDir = "dynamic\\" + BaseDir + "\\"; // McZapkie-310302 + asBaseDir = szDynamicPath + BaseDir + "/"; // McZapkie-310302 + replace_slashes( asBaseDir ); asName = Name; std::string asAnimName = ""; // zmienna robocza do wyszukiwania osi i wózków // Ra: zmieniamy znaczenie obsady na jednoliterowe, żeby dosadzić kierownika @@ -1768,9 +1769,9 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424" if (!MoverParameters->LoadFIZ(asBaseDir)) { // jak wczytanie CHK się nie uda, to błąd if (ConversionError == 666) - ErrorLog( "Bad vehicle: failed do locate definition file \"" + BaseDir + "\\" + Type_Name + ".fiz" + "\"" ); + ErrorLog( "Bad vehicle: failed do locate definition file \"" + BaseDir + "/" + Type_Name + ".fiz" + "\"" ); else { - ErrorLog( "Bad vehicle: failed to load definition from file \"" + BaseDir + "\\" + Type_Name + ".fiz\" (error " + to_string( ConversionError ) + ")" ); + ErrorLog( "Bad vehicle: failed to load definition from file \"" + BaseDir + "/" + Type_Name + ".fiz\" (error " + to_string( ConversionError ) + ")" ); } return 0.0; // zerowa długość to brak pojazdu } @@ -1780,8 +1781,7 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424" (fVel > 0 ? 1 : -1) * Cab * (iDirection ? 1 : -1))) // jak jedzie lub obsadzony to gotowy do drogi { - Error("Parameters mismatch: dynamic object " + asName + " from\n" + BaseDir + "\\" + - Type_Name); + Error("Parameters mismatch: dynamic object " + asName + " from \"" + BaseDir + "/" + Type_Name + "\"" ); return 0.0; // zerowa długość to brak pojazdu } // ustawienie pozycji hamulca @@ -4173,11 +4173,16 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName, m_materialdata.multi_textures = 0; // czy jest wiele tekstur wymiennych? parser.getTokens(); parser >> asModel; + replace_slashes( asModel ); if( asModel[asModel.size() - 1] == '#' ) // Ra 2015-01: nie podoba mi siê to { // model wymaga wielu tekstur wymiennych m_materialdata.multi_textures = 1; asModel.erase( asModel.length() - 1 ); } + // name can contain leading slash, erase it to avoid creation of double slashes when the name is combined with current directory + if( asModel[ 0 ] == '/' ) { + asModel.erase( 0, 1 ); + } std::size_t i = asModel.find( ',' ); if ( i != std::string::npos ) { // Ra 2015-01: może szukać przecinka w nazwie modelu, a po przecinku była by liczba tekstur? diff --git a/EU07.cpp b/EU07.cpp index 980c9716..589c6017 100644 --- a/EU07.cpp +++ b/EU07.cpp @@ -436,8 +436,8 @@ int main(int argc, char *argv[]) #endif if( Global.iConvertModels < 0 ) { Global.iConvertModels = -Global.iConvertModels; - World.CreateE3D( "models\\" ); // rekurencyjne przeglądanie katalogów - World.CreateE3D( "dynamic\\", true ); + World.CreateE3D( szModelPath ); // rekurencyjne przeglądanie katalogów + World.CreateE3D( szDynamicPath, true ); } // po zrobieniu E3D odpalamy normalnie scenerię, by ją zobaczyć #ifdef _WIN32 Console::On(); // włączenie konsoli diff --git a/Event.cpp b/Event.cpp index 2752e213..45155d95 100644 --- a/Event.cpp +++ b/Event.cpp @@ -476,9 +476,8 @@ void TEvent::Load(cParser *parser, Math3D::vector3 const &org) } else if (token.substr(token.length() - 4, 4) == ".vmd") // na razie tu, może będzie inaczej { // animacja z pliku VMD -// TFileStream *fs = new TFileStream( "models\\" + AnsiString( token.c_str() ), fmOpenRead ); { - std::ifstream file( "models\\" + token, std::ios::binary | std::ios::ate ); file.unsetf( std::ios::skipws ); + std::ifstream file( szModelPath + token, std::ios::binary | std::ios::ate ); file.unsetf( std::ios::skipws ); auto size = file.tellg(); // ios::ate already positioned us at the end of the file file.seekg( 0, std::ios::beg ); // rewind the caret afterwards Params[ 7 ].asInt = size; diff --git a/MdlMngr.cpp b/MdlMngr.cpp index 7adff69a..3dea431c 100644 --- a/MdlMngr.cpp +++ b/MdlMngr.cpp @@ -81,12 +81,13 @@ TModelsManager::GetModel(std::string const &Name, bool const Dynamic) // - wczytanie modelu animowanego - Init() - sprawdzić std::string const buftp { Global.asCurrentTexturePath }; // zapamiętanie aktualnej ścieżki do tekstur, std::string filename { Name }; - if( Name.find( '/' ) != std::string::npos ) { + if( ( false == Dynamic ) + && ( Name.find( '/' ) != std::string::npos ) ) { // pobieranie tekstur z katalogu, w którym jest model + // when loading vehicles the path is set by the calling routine, so we can skip it here Global.asCurrentTexturePath += Name; - Global.asCurrentTexturePath.erase( Global.asCurrentTexturePath.rfind( "/" ) + 1 ); + Global.asCurrentTexturePath.erase( Global.asCurrentTexturePath.rfind( '/' ) + 1 ); } - erase_extension( filename ); filename = ToLower( filename ); diff --git a/PyInt.cpp b/PyInt.cpp index e426af9f..c4615c50 100644 --- a/PyInt.cpp +++ b/PyInt.cpp @@ -479,7 +479,7 @@ void TPythonScreens::update() void TPythonScreens::setLookupPath(std::string const &path) { _lookupPath = path; - std::replace(_lookupPath.begin(), _lookupPath.end(), '\\', '/'); + replace_slashes( _lookupPath ); } TPythonScreens::TPythonScreens() diff --git a/Texture.cpp b/Texture.cpp index f148dc8b..d077195b 100644 --- a/Texture.cpp +++ b/Texture.cpp @@ -761,10 +761,7 @@ texture_manager::create( std::string Filename, bool const Loadnow ) { } erase_extension( Filename ); - // change slashes to cross-platform - std::replace( - std::begin( Filename ), std::end( Filename ), - '\\', '/' ); + replace_slashes( Filename ); std::vector extensions { { ".dds" }, { ".tga" }, { ".bmp" }, { ".ext" } }; diff --git a/World.cpp b/World.cpp index 09b440b4..23b6793b 100644 --- a/World.cpp +++ b/World.cpp @@ -1955,7 +1955,7 @@ void TWorld::CreateE3D(std::string const &Path, bool Dynamic) // launch recursive search for sub-directories... if( filename == "." ) { continue; } if( filename == ".." ) { continue; } - CreateE3D( Path + filename + "\\", Dynamic ); + CreateE3D( Path + filename + "/", Dynamic ); } else { // process the file diff --git a/audio.cpp b/audio.cpp index e90a57ca..c9511e2e 100644 --- a/audio.cpp +++ b/audio.cpp @@ -133,10 +133,7 @@ buffer_manager::create( std::string const &Filename ) { auto filename { ToLower( Filename ) }; erase_extension( filename ); - // convert slashes - std::replace( - std::begin( filename ), std::end( filename ), - '\\', '/' ); + replace_slashes( filename ); audio::buffer_handle lookup { null_handle }; std::string filelookup; diff --git a/material.cpp b/material.cpp index b2fcb201..31b10d5c 100644 --- a/material.cpp +++ b/material.cpp @@ -17,8 +17,8 @@ http://mozilla.org/MPL/2.0/. // helper, returns potential path part from provided file name std::string path( std::string const &Filename ) { return ( - Filename.rfind( '\\' ) != std::string::npos ? - Filename.substr( 0, Filename.rfind( '\\' ) + 1 ) : + Filename.rfind( '/' ) != std::string::npos ? + Filename.substr( 0, Filename.rfind( '/' ) + 1 ) : "" ); } @@ -111,12 +111,9 @@ material_manager::create( std::string const &Filename, bool const Loadnow ) { filename.erase( filename.find( '|' ) ); // po | może być nazwa kolejnej tekstury erase_extension( filename ); - filename += ".mat"; + replace_slashes( filename ); - // change slashes to llinux-compatible - std::replace( - std::begin( filename ), std::end( filename ), - '\\', '/' ); + filename += ".mat"; // try to locate requested material in the databank auto const databanklookup = find_in_databank( filename ); diff --git a/stars.cpp b/stars.cpp index b7c9ef79..1f0b87ed 100644 --- a/stars.cpp +++ b/stars.cpp @@ -10,5 +10,5 @@ void cStars::init() { - m_stars = TModelsManager::GetModel( "models\\skydome_stars.t3d", false ); + m_stars = TModelsManager::GetModel( "skydome_stars.t3d", false ); } diff --git a/utilities.cpp b/utilities.cpp index 3f791750..8e3475ac 100644 --- a/utilities.cpp +++ b/utilities.cpp @@ -334,3 +334,12 @@ erase_extension( std::string &Filename ) { } return false; } + +// potentially replaces backward slashes in provided file path with unix-compatible forward slashes +void +replace_slashes( std::string &Filename ) { + + std::replace( + std::begin( Filename ), std::end( Filename ), + '\\', '/' ); +} diff --git a/utilities.h b/utilities.h index 6d182c7d..26918a8b 100644 --- a/utilities.h +++ b/utilities.h @@ -28,6 +28,7 @@ http://mozilla.org/MPL/2.0/. #define szSceneryPath "scenery/" #define szTexturePath "textures/" #define szModelPath "models/" +#define szDynamicPath "dynamic/" #define szSoundPath "sounds/" #define MAKE_ID4(a,b,c,d) (((std::uint32_t)(d)<<24)|((std::uint32_t)(c)<<16)|((std::uint32_t)(b)<<8)|(std::uint32_t)(a)) @@ -183,6 +184,10 @@ std::time_t last_modified( std::string const &Filename ); bool erase_extension( std::string &Filename ); +// potentially replaces backward slashes in provided file path with unix-compatible forward slashes +void +replace_slashes( std::string &Filename ); + template void SafeDelete( Type_ &Pointer ) { delete Pointer;