From: <sag...@us...> - 2013-11-17 00:41:07
|
Revision: 3249 http://sourceforge.net/p/modplug/code/3249 Author: saga-games Date: 2013-11-17 00:40:57 +0000 (Sun, 17 Nov 2013) Log Message: ----------- [Mod] Path names in ITP files are now unicode and, if possible, relative to the ITP file. Modified Paths: -------------- trunk/OpenMPT/common/mptPathString.cpp trunk/OpenMPT/common/mptPathString.h trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Mptrack.cpp trunk/OpenMPT/mptrack/Mptrack.h trunk/OpenMPT/soundlib/Load_itp.cpp trunk/OpenMPT/test/test.cpp Modified: trunk/OpenMPT/common/mptPathString.cpp =================================================================== --- trunk/OpenMPT/common/mptPathString.cpp 2013-11-16 23:10:41 UTC (rev 3248) +++ trunk/OpenMPT/common/mptPathString.cpp 2013-11-17 00:40:57 UTC (rev 3249) @@ -31,58 +31,119 @@ } PathString PathString::GetDrive() const +//------------------------------------- { PathString drive; SplitPath(&drive, nullptr, nullptr, nullptr); return drive; } PathString PathString::GetDir() const +//----------------------------------- { PathString dir; SplitPath(nullptr, &dir, nullptr, nullptr); return dir; } PathString PathString::GetPath() const +//------------------------------------ { PathString drive, dir; SplitPath(&drive, &dir, nullptr, nullptr); return drive + dir; } PathString PathString::GetFileName() const +//---------------------------------------- { PathString fname; SplitPath(nullptr, nullptr, &fname, nullptr); return fname; } PathString PathString::GetFileExt() const +//--------------------------------------- { PathString ext; SplitPath(nullptr, nullptr, nullptr, &ext); return ext; } PathString PathString::GetFullFileName() const +//-------------------------------------------- { PathString name, ext; SplitPath(nullptr, nullptr, &name, &ext); return name + ext; } + PathString PathString::ReplaceExt(const mpt::PathString &newExt) const +//-------------------------------------------------------------------- { return GetDrive() + GetDir() + GetFileName() + newExt; } + PathString PathString::SanitizeComponent() const +//---------------------------------------------- { PathString result = *this; SanitizeFilename(result); return result; } + +// Convert an absolute path to a path that's relative to OpenMPT's directory. +// Paths are relative to the executable path. +PathString PathString::AbsolutePathToRelative(const PathString &relativeTo) const +//------------------------------------------------------------------------------- +{ + mpt::PathString result = path; + if(path.empty()) + { + return result; + } + if(!_wcsnicmp(relativeTo.AsNative().c_str(), AsNative().c_str(), relativeTo.AsNative().length())) + { + // Path is OpenMPT's directory or a sub directory ("C:\OpenMPT\Somepath" => ".\Somepath") + result = MPT_PATHSTRING(".\\"); // ".\" + result += mpt::PathString::FromNative(AsNative().substr(relativeTo.AsNative().length())); + } else if(!_wcsnicmp(relativeTo.AsNative().c_str(), AsNative().c_str(), 2)) + { + // Path is on the same drive as OpenMPT ("C:\Somepath" => "\Somepath") + result = mpt::PathString::FromNative(AsNative().substr(2)); + } + return result; +} + + +// Convert a relative path to an absolute path. +// Paths are relative to the executable path. +PathString PathString::RelativePathToAbsolute(const PathString &relativeTo) const +//------------------------------------------------------------------------------- +{ + mpt::PathString result = path; + if(path.empty()) + { + return result; + } + if(AsNative().length() >= 2 && AsNative().substr(0, 1) == L"\\" && AsNative().substr(0, 2) != L"\\\\") + { + // Path is on the same drive as OpenMPT ("\Somepath\" => "C:\Somepath\"), but ignore network paths starting with "\\" + result = mpt::PathString::FromNative(relativeTo.AsNative().substr(0, 2)); + result += path; + } else if(AsNative().length() >= 2 && AsNative().substr(0, 2) == L".\\") + { + // Path is OpenMPT's directory or a sub directory (".\Somepath\" => "C:\OpenMPT\Somepath\") + result = relativeTo; // "C:\OpenMPT\" + result += mpt::PathString::FromNative(AsNative().substr(2)); + } + return result; +} + + #if defined(WIN32) #if defined(_MFC_VER) mpt::PathString PathString::TunnelOutofCString(const CString &path) +//----------------------------------------------------------------- { #ifdef UNICODE return mpt::PathString::FromWide(path.GetString()); @@ -103,7 +164,9 @@ #endif } + CString PathString::TunnelIntoCString(const mpt::PathString &path) +//---------------------------------------------------------------- { #ifdef UNICODE return path.ToWide().c_str(); Modified: trunk/OpenMPT/common/mptPathString.h =================================================================== --- trunk/OpenMPT/common/mptPathString.h 2013-11-16 23:10:41 UTC (rev 3248) +++ trunk/OpenMPT/common/mptPathString.h 2013-11-17 00:40:57 UTC (rev 3249) @@ -120,6 +120,10 @@ return false; } + // Relative / absolute paths conversion + mpt::PathString AbsolutePathToRelative(const mpt::PathString &relativeTo) const; + mpt::PathString RelativePathToAbsolute(const mpt::PathString &relativeTo) const; + #endif // MODPLUG_TRACKER public: Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2013-11-16 23:10:41 UTC (rev 3248) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2013-11-17 00:40:57 UTC (rev 3249) @@ -219,7 +219,7 @@ BeginWaitCursor(); #ifndef NO_FILEREADER_STD_ISTREAM - mpt::ifstream f(lpszPathName, std::ios_base::binary); + mpt::ifstream f(filename, std::ios_base::binary); m_SndFile.Create(FileReader(&f), CSoundFile::loadCompleteModule, this); #else { @@ -229,6 +229,9 @@ FileReader file = f.GetFile(); if(file.IsValid()) { + ASSERT(GetPathNameMpt() == mpt::PathString()); + SetPathName(filename, FALSE); // Path is not set yet, but ITP loader needs this for relative paths. + m_SndFile.Create(file, CSoundFile::loadCompleteModule, this); } } Modified: trunk/OpenMPT/mptrack/Mptrack.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.cpp 2013-11-16 23:10:41 UTC (rev 3248) +++ trunk/OpenMPT/mptrack/Mptrack.cpp 2013-11-17 00:40:57 UTC (rev 3249) @@ -2041,56 +2041,6 @@ } -// Convert an absolute path to a path that's relative to OpenMPT's directory. -// Paths are relative to the executable path. -mpt::PathString CTrackApp::AbsolutePathToRelative(const mpt::PathString &path) -//---------------------------------------------------------------------------- -{ - mpt::PathString result = path; - if(path.empty()) - { - return result; - } - mpt::PathString exePath = GetAppDirPath(); - if(!_wcsnicmp(exePath.AsNative().c_str(), path.AsNative().c_str(), exePath.AsNative().length())) - { - // Path is OpenMPT's directory or a sub directory ("C:\OpenMPT\Somepath" => ".\Somepath") - result = MPT_PATHSTRING(".\\"); // ".\" - result += mpt::PathString::FromNative(path.AsNative().substr(exePath.AsNative().length())); - } else if(!_wcsnicmp(exePath.AsNative().c_str(), path.AsNative().c_str(), 2)) - { - // Path is on the same drive as OpenMPT ("C:\Somepath" => "\Somepath") - result = mpt::PathString::FromNative(path.AsNative().substr(2)); - } - return result; -} - - -// Convert a relative path to an absolute path. -// Paths are relative to the executable path. -mpt::PathString CTrackApp::RelativePathToAbsolute(const mpt::PathString &path) -//---------------------------------------------------------------------------- -{ - mpt::PathString result = path; - if(path.empty()) - { - return result; - } - mpt::PathString exePath = GetAppDirPath(); - if(path.AsNative().length() >= 2 && path.AsNative().substr(0, 1) == L"\\" && path.AsNative().substr(0, 2) != L"\\\\") - { - // Path is on the same drive as OpenMPT ("\Somepath\" => "C:\Somepath\"), but ignore network paths starting with "\\" - result = mpt::PathString::FromNative(exePath.AsNative().substr(0, 2)); - result += path; - } else if(path.AsNative().length() >= 2 && path.AsNative().substr(0, 2) == L".\\") - { - // Path is OpenMPT's directory or a sub directory (".\Somepath\" => "C:\OpenMPT\Somepath\") - result = exePath; // "C:\OpenMPT\" - result += mpt::PathString::FromNative(path.AsNative().substr(2)); - } - return result; -} - void CTrackApp::RemoveMruItem(const int nItem) //-------------------------------------------- { Modified: trunk/OpenMPT/mptrack/Mptrack.h =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.h 2013-11-16 23:10:41 UTC (rev 3248) +++ trunk/OpenMPT/mptrack/Mptrack.h 2013-11-17 00:40:57 UTC (rev 3249) @@ -210,9 +210,6 @@ static VOID SetAsProject(BOOL n) { m_nProject = n; } // -! NEW_FEATURE#0023 -#if defined(ENABLE_TESTS) - static void SetAppDirPath(mpt::PathString exePath) {m_szExePath=exePath;} -#endif static mpt::PathString GetAppDirPath() {return m_szExePath;} // Returns '\'-ended executable directory path. static MODTYPE GetDefaultDocType() { return m_nDefaultDocType; } static void SetDefaultDocType(MODTYPE n) { m_nDefaultDocType = n; } @@ -271,8 +268,8 @@ void SetupPaths(bool overridePortable); // Relative / absolute paths conversion - mpt::PathString AbsolutePathToRelative(const mpt::PathString &path); - mpt::PathString RelativePathToAbsolute(const mpt::PathString &path); + mpt::PathString AbsolutePathToRelative(const mpt::PathString &path) { return path.AbsolutePathToRelative(GetAppDirPath()); } + mpt::PathString RelativePathToAbsolute(const mpt::PathString &path) { return path.RelativePathToAbsolute(GetAppDirPath()); } /// Removes item from MRU-list; most recent item has index zero. void RemoveMruItem(const int nItem); Modified: trunk/OpenMPT/soundlib/Load_itp.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_itp.cpp 2013-11-16 23:10:41 UTC (rev 3248) +++ trunk/OpenMPT/soundlib/Load_itp.cpp 2013-11-17 00:40:57 UTC (rev 3249) @@ -7,7 +7,8 @@ * with the IT format, but keeping the instrument files with big samples separate * from the pattern data, to keep the work files small and handy. * The current design of the format is quite flawed, though, so expect this to - * change in the (far?) future. + * change in the (far?) future. Most likely, the new MPTM format will contain + * optional functionality to link samples and instruments instead of embedding them. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ @@ -18,13 +19,21 @@ #include "../mptrack/mptrack.h" #include "../mptrack/TrackerSettings.h" #include "../mptrack/MemoryMappedFile.h" +#include "../mptrack/Moddoc.h" #endif #include "../common/version.h" #include "Loaders.h" #include "ITTools.h" +// Version changelog: +// v1.03: - Relative unicode instrument paths instead of absolute ANSI paths +// - Per-path variable string length +// - Embedded samples are IT-compressed +// (rev. 3249) +// v1.02: Explicitely updated format to use new instrument flags representation (rev. 483) +// v1.01: Added option to embed instrument headers -#define ITP_VERSION 0x00000102 // v1.02 +#define ITP_VERSION 0x00000103 // v1.03 #define ITP_FILE_ID 0x2E697470 // .itp ASCII @@ -63,7 +72,7 @@ if(!file.CanRead(12 + 4 + 24 + 4) || file.ReadUint32LE() != ITP_FILE_ID // Magic bytes || (version = file.ReadUint32LE()) > ITP_VERSION // Format version - || !ReadITPString(songName, file)) // Song name + || !ReadITPString(songName, file)) // Song name { return false; } else if(loadFlags == onlyVerifyHeader) @@ -129,12 +138,28 @@ } // Instruments' paths - size = file.ReadUint32LE(); // path string length + if(version <= 0x00000102) + { + size = file.ReadUint32LE(); // path string length + } for(INSTRUMENTINDEX ins = 0; ins < GetNumInstruments(); ins++) { + if(version > 0x00000102) + { + size = file.ReadUint32LE(); // path string length + } std::string path; file.ReadString<mpt::String::maybeNullTerminated>(path, size); - m_szInstrumentPath[ins] = mpt::PathString::FromLocale(path); + if(version <= 0x00000102) + { + path = mpt::To(mpt::CharsetUTF8, mpt::CharsetLocale, path); + } + m_szInstrumentPath[ins] = mpt::PathString::FromUTF8(path); + + if(GetpModDoc() != nullptr) + { + m_szInstrumentPath[ins] = m_szInstrumentPath[ins].RelativePathToAbsolute(GetpModDoc()->GetPathNameMpt()); + } } // Song Orders @@ -390,17 +415,14 @@ id = m_nInstruments; fwrite(&id, 1, sizeof(id), f); - // path name string length - id = _MAX_PATH; - fwrite(&id, 1, sizeof(id), f); - // instruments' path for(i = 0; i < m_nInstruments; i++) { - char path[_MAX_PATH]; - MemsetZero(path); - strncpy(path, m_szInstrumentPath[i].ToLocale().c_str(), _MAX_PATH); - fwrite(path, 1, _MAX_PATH, f); + const std::string path = m_szInstrumentPath[i].AbsolutePathToRelative(filename).ToUTF8(); + // path name string length + id = path.length(); + fwrite(&id, 1, sizeof(id), f); + fwrite(path.c_str(), 1, path.length(), f); } // Song Orders @@ -482,7 +504,7 @@ if(!sampleUsed[nsmp] && Samples[nsmp].pSample) { ITSample itss; - itss.ConvertToIT(Samples[nsmp], GetType(), false, false); + itss.ConvertToIT(Samples[nsmp], GetType(), true, true); mpt::String::Write<mpt::String::nullTerminated>(itss.name, m_szNames[nsmp]); Modified: trunk/OpenMPT/test/test.cpp =================================================================== --- trunk/OpenMPT/test/test.cpp 2013-11-16 23:10:41 UTC (rev 3248) +++ trunk/OpenMPT/test/test.cpp 2013-11-17 00:40:57 UTC (rev 3249) @@ -708,18 +708,15 @@ // Path conversions #ifdef MODPLUG_TRACKER - const mpt::PathString realExePath = theApp.GetAppDirPath(); const mpt::PathString exePath = MPT_PATHSTRING("C:\\OpenMPT\\"); - theApp.SetAppDirPath(exePath); - VERIFY_EQUAL(theApp.AbsolutePathToRelative(MPT_PATHSTRING("C:\\OpenMPT\\")), MPT_PATHSTRING(".\\")); - VERIFY_EQUAL(theApp.AbsolutePathToRelative(MPT_PATHSTRING("c:\\OpenMPT\\foo")), MPT_PATHSTRING(".\\foo")); - VERIFY_EQUAL(theApp.AbsolutePathToRelative(MPT_PATHSTRING("C:\\foo")), MPT_PATHSTRING("\\foo")); - VERIFY_EQUAL(theApp.RelativePathToAbsolute(MPT_PATHSTRING(".\\")), MPT_PATHSTRING("C:\\OpenMPT\\")); - VERIFY_EQUAL(theApp.RelativePathToAbsolute(MPT_PATHSTRING(".\\foo")), MPT_PATHSTRING("C:\\OpenMPT\\foo")); - VERIFY_EQUAL(theApp.RelativePathToAbsolute(MPT_PATHSTRING("\\foo")), MPT_PATHSTRING("C:\\foo")); - VERIFY_EQUAL(theApp.AbsolutePathToRelative(MPT_PATHSTRING("\\\\server\\path\\file")), MPT_PATHSTRING("\\\\server\\path\\file")); - VERIFY_EQUAL(theApp.RelativePathToAbsolute(MPT_PATHSTRING("\\\\server\\path\\file")), MPT_PATHSTRING("\\\\server\\path\\file")); - theApp.SetAppDirPath(realExePath); + VERIFY_EQUAL(MPT_PATHSTRING("C:\\OpenMPT\\").AbsolutePathToRelative(exePath), MPT_PATHSTRING(".\\")); + VERIFY_EQUAL(MPT_PATHSTRING("c:\\OpenMPT\\foo").AbsolutePathToRelative(exePath), MPT_PATHSTRING(".\\foo")); + VERIFY_EQUAL(MPT_PATHSTRING("C:\\foo").AbsolutePathToRelative(exePath), MPT_PATHSTRING("\\foo")); + VERIFY_EQUAL(MPT_PATHSTRING(".\\").RelativePathToAbsolute(exePath), MPT_PATHSTRING("C:\\OpenMPT\\")); + VERIFY_EQUAL(MPT_PATHSTRING(".\\foo").RelativePathToAbsolute(exePath), MPT_PATHSTRING("C:\\OpenMPT\\foo")); + VERIFY_EQUAL(MPT_PATHSTRING("\\foo").RelativePathToAbsolute(exePath), MPT_PATHSTRING("C:\\foo")); + VERIFY_EQUAL(MPT_PATHSTRING("\\\\server\\path\\file").AbsolutePathToRelative(exePath), MPT_PATHSTRING("\\\\server\\path\\file")); + VERIFY_EQUAL(MPT_PATHSTRING("\\\\server\\path\\file").RelativePathToAbsolute(exePath), MPT_PATHSTRING("\\\\server\\path\\file")); #endif } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |