From: <rel...@us...> - 2010-03-21 21:29:51
|
Revision: 542 http://modplug.svn.sourceforge.net/modplug/?rev=542&view=rev Author: relabsoluness Date: 2010-03-21 21:29:43 +0000 (Sun, 21 Mar 2010) Log Message: ----------- [Fix] VST: Some VSTs that previously wouldn't load might now load fine. [Fix] Instrument tuning: Minor fixes to ratio window, made tuning collection loading more reliable, minor other changes. [Fix] Serialization code: Fixed a memory leak in write functions, added alternative way to read entries and minor other changes. [Mod] Mod specs: Reduced xmEx sample count to 4000. [Ref] Added CountOf-macro (a better alternative to ARRAYELEMCOUNT-macro). Modified Paths: -------------- trunk/OpenMPT/mptrack/Vstplug.cpp trunk/OpenMPT/mptrack/serialization_utils.cpp trunk/OpenMPT/mptrack/serialization_utils.h trunk/OpenMPT/mptrack/tuningRatioMapWnd.cpp trunk/OpenMPT/mptrack/typedefs.h trunk/OpenMPT/soundlib/mod_specifications.h trunk/OpenMPT/soundlib/tuning.cpp trunk/OpenMPT/soundlib/tuningCollection.cpp Modified: trunk/OpenMPT/mptrack/Vstplug.cpp =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.cpp 2010-03-21 17:25:13 UTC (rev 541) +++ trunk/OpenMPT/mptrack/Vstplug.cpp 2010-03-21 21:29:43 UTC (rev 542) @@ -708,7 +708,8 @@ // Returns the unique id of a plug that's currently loading // (not sure what this is actually for - we return *effect's UID, cos Herman Seib does something similar :) // Let's see what happens...) - case audioMasterCurrentId: return effect->uniqueID; + case audioMasterCurrentId: + return (effect != nullptr) ? effect->uniqueID : 0; // Call application idle routine (this will call effEditIdle for all open editors too) case audioMasterIdle: OnIdle(); Modified: trunk/OpenMPT/mptrack/serialization_utils.cpp =================================================================== --- trunk/OpenMPT/mptrack/serialization_utils.cpp 2010-03-21 17:25:13 UTC (rev 541) +++ trunk/OpenMPT/mptrack/serialization_utils.cpp 2010-03-21 21:29:43 UTC (rev 542) @@ -863,8 +863,11 @@ if (m_fpLogFunc) m_fpLogFunc(tstrWritingMap, uint32(m_posMapStart - m_posStart)); - if(GetFlag(RwfRwHasMap)) //Write map + if (GetFlag(RwfRwHasMap)) //Write map + { oStrm.write(m_MapStream.str(), m_MapStream.pcount()); + m_MapStream.freeze(false); + } const Postype posMapEnd = oStrm.tellp(); Modified: trunk/OpenMPT/mptrack/serialization_utils.h =================================================================== --- trunk/OpenMPT/mptrack/serialization_utils.h 2010-03-21 17:25:13 UTC (rev 541) +++ trunk/OpenMPT/mptrack/serialization_utils.h 2010-03-21 21:29:43 UTC (rev 542) @@ -127,6 +127,11 @@ EntryRead, EntryNotFound }; + enum IdMatchStatus + { + IdMatch, IdMismatch + }; + typedef std::vector<ReadEntry>::const_iterator ReadIterator; Ssb(InStream* pIstrm, OutStream* pOstrm); Ssb(IoStream& ioStrm); @@ -142,7 +147,7 @@ void BeginWrite(const void* pId, const size_t nIdSize, const uint64& nVersion); void BeginWrite(const LPCSTR pszId, const uint64& nVersion) {BeginWrite(pszId, strlen(pszId), nVersion);} - // Read header. + // Call this to begin reading: must be called before other read functions. void BeginRead(const void* pId, const size_t nLength, const uint64& nVersion); void BeginRead(const LPCSTR pszId, const uint64& nVersion) {return BeginRead(pszId, strlen(pszId), nVersion);} @@ -170,6 +175,18 @@ // After calling BeginRead(), this returns number of entries in the file. NumType GetNumEntries() const {return m_nReadEntrycount;} + // Returns read iterator to the beginning of entries. + // The behaviour of read iterators is undefined if map doesn't + // contain entry ids or data begin positions. + ReadIterator GetReadBegin(); + + // Returns read iterator to the end(one past last) of entries. + ReadIterator GetReadEnd(); + + // Compares given id with read entry id + IdMatchStatus CompareId(const ReadIterator& iter, LPCSTR pszId) {return CompareId(iter, pszId, strlen(pszId));} + IdMatchStatus CompareId(const ReadIterator& iter, const void* pId, const size_t nIdSize); + // When writing, returns the number of entries written. // When reading, returns the number of entries read not including unrecognized entries. NumType GetCounter() const {return m_nCounter;} @@ -187,6 +204,12 @@ template <class T, class FuncObj> ReadRv ReadItem(T& obj, const void* pId, const size_t nIdSize, FuncObj); + // Read item using read iterator. + template <class T> + ReadRv ReadItem(const ReadIterator& iter, T& obj) {return ReadItem(iter, obj, srlztn::ReadItem<T>);} + template <class T, class FuncObj> + ReadRv ReadItem(const ReadIterator& iter, T& obj, FuncObj func); + // Write item using default write implementation. template <class T> void WriteItem(const T& obj, const LPCSTR pszId) {WriteItem(obj, pszId, strlen(pszId), &srlztn::WriteItem<T>);} @@ -204,6 +227,9 @@ void SetFlag(Rwf flag, bool val) {m_Flags.set(flag, val);} bool GetFlag(Rwf flag) const {return m_Flags[flag];} + // Write given string to log if log func is defined. + void Log(LPCTSTR psz) {if (m_fpLogFunc) m_fpLogFunc(psz);} + SsbStatus m_Status; uint32 m_nFixedEntrySize; // Read/write: If > 0, data entries have given fixed size. fpLogFunc_t m_fpLogFunc; // Pointer to log function. @@ -319,6 +345,48 @@ } +template <class T, class FuncObj> +Ssb::ReadRv Ssb::ReadItem(const ReadIterator& iter, T& obj, FuncObj func) +//----------------------------------------------------------------------- +{ + m_pIstrm->clear(); + if (iter->rposStart != 0) + m_pIstrm->seekg(m_posStart + Postype(iter->rposStart)); + const Postype pos = m_pIstrm->tellg(); + func(*m_pIstrm, obj, iter->nSize); + return OnReadEntry(&(*iter), &m_Idarray[iter->nIdpos], iter->nIdLength, pos); +} + + +inline Ssb::IdMatchStatus Ssb::CompareId(const ReadIterator& iter, const void* pId, const size_t nIdSize) +//------------------------------------------------------------------------------------------------------- +{ + if (nIdSize == iter->nIdLength && memcmp(&m_Idarray[iter->nIdpos], pId, iter->nIdLength) == 0) + return IdMatch; + else + return IdMismatch; +} + + +inline Ssb::ReadIterator Ssb::GetReadBegin() +//------------------------------------------ +{ + ASSERT(GetFlag(RwfRMapHasId) && (GetFlag(RwfRMapHasStartpos) || GetFlag(RwfRMapHasSize) || m_nFixedEntrySize > 0)); + if (GetFlag(RwfRMapCached) == false) + CacheMap(); + return mapData.begin(); +} + + +inline Ssb::ReadIterator Ssb::GetReadEnd() +//---------------------------------------- +{ + if (GetFlag(RwfRMapCached) == false) + CacheMap(); + return mapData.end(); +} + + template<class T> inline void Binarywrite(OutStream& oStrm, const T& data) //------------------------------------------------------ @@ -364,19 +432,25 @@ inline void Binaryread(InStream& iStrm, T& data, const Offtype bytecount) //----------------------------------------------------------------------- { + #if _HAS_TR1 + static_assert(std::tr1::has_trivial_assign<T>::value == true, ""); + #endif memset(&data, 0, sizeof(data)); - iStrm.read(reinterpret_cast<char*>(&data), min(bytecount, sizeof(data))); + iStrm.read(reinterpret_cast<char*>(&data), (std::min)((size_t)bytecount, sizeof(data))); } template <class T> -inline void ReadItem(InStream& iStrm, T& data, const DataSize /*nSize*/) -//---------------------------------------------------------------------- +inline void ReadItem(InStream& iStrm, T& data, const DataSize nSize) +//------------------------------------------------------------------ { #if _HAS_TR1 - STATIC_ASSERT(std::tr1::has_trivial_assign<T>::value == true); + static_assert(std::tr1::has_trivial_assign<T>::value == true, ""); #endif - Binaryread(iStrm, data); + if (nSize == sizeof(T) || nSize == invalidDatasize) + Binaryread(iStrm, data); + else + Binaryread(iStrm, data, nSize); } // Read specialization for float. If data size is 8, read double and assign it to given float. Modified: trunk/OpenMPT/mptrack/tuningRatioMapWnd.cpp =================================================================== --- trunk/OpenMPT/mptrack/tuningRatioMapWnd.cpp 2010-03-21 17:25:13 UTC (rev 541) +++ trunk/OpenMPT/mptrack/tuningRatioMapWnd.cpp 2010-03-21 21:29:43 UTC (rev 542) @@ -49,8 +49,8 @@ const size_t sizeofS = sizeof(s) / sizeof(s[0]); CRect rect; - NOTEINDEXTYPE nNotes = (rcClient.bottom + m_cyFont - 1) / m_cyFont; - if(!m_nNote) m_nNote = m_nNoteCentre; + NOTEINDEXTYPE nNotes = static_cast<NOTEINDEXTYPE>((rcClient.bottom + m_cyFont - 1) / m_cyFont); + //if(!m_nNote) m_nNote = m_nNoteCentre; NOTEINDEXTYPE nPos = m_nNote - (nNotes/2); int ypaint = 0; @@ -132,11 +132,11 @@ CRect rcClient; GetClientRect(&rcClient); int nNotes = (rcClient.bottom + m_cyFont - 1) / m_cyFont; - const UINT n = (pt.y / m_cyFont) + m_nNote - (nNotes/2); - const NOTEINDEXTYPE note = n - m_nNoteCentre; + const int n = (pt.y / m_cyFont) + m_nNote - (nNotes/2); + const NOTEINDEXTYPE note = static_cast<NOTEINDEXTYPE>(n - m_nNoteCentre); if(m_pTuning->IsValidNote(note)) { - m_nNote = n; + m_nNote = static_cast<NOTEINDEXTYPE>(n); InvalidateRect(NULL, FALSE); if(m_pParent) m_pParent->UpdateRatioMapEdits(GetShownCentre()); Modified: trunk/OpenMPT/mptrack/typedefs.h =================================================================== --- trunk/OpenMPT/mptrack/typedefs.h 2010-03-21 17:25:13 UTC (rev 541) +++ trunk/OpenMPT/mptrack/typedefs.h 2010-03-21 21:29:43 UTC (rev 542) @@ -2,8 +2,16 @@ #define TYPEDEFS_H #define nullptr 0 -#define ARRAYELEMCOUNT(x) (sizeof(x)/sizeof(x[0])) +// CountOf macro computes the number of elements in a statically-allocated array. +#if _MSC_VER >= 1400 + #define CountOf(x) _countof(x) +#else + #define CountOf(x) (sizeof(x)/sizeof(x[0])) +#endif + +#define ARRAYELEMCOUNT(x) CountOf(x) + //Compile time assert. #define STATIC_ASSERT(expr) C_ASSERT(expr) #define static_assert(expr, msg) C_ASSERT(expr) Modified: trunk/OpenMPT/soundlib/mod_specifications.h =================================================================== --- trunk/OpenMPT/soundlib/mod_specifications.h 2010-03-21 17:25:13 UTC (rev 541) +++ trunk/OpenMPT/soundlib/mod_specifications.h 2010-03-21 21:29:43 UTC (rev 542) @@ -233,7 +233,7 @@ 0, //Max sample filename length 22, //Max instrument name length 0, //Max instrument filename length - 256 * 16, //SamplesMax (actually 16 per instrument) + 4000, //SamplesMax (actually 16 per instrument(256*16=4096), but limited to MAX_SAMPLES=4000) 256, //instrumentMax mixLevels_117RC3, //defaultMixLevels 200, //Max MIDI mapping directives Modified: trunk/OpenMPT/soundlib/tuning.cpp =================================================================== --- trunk/OpenMPT/soundlib/tuning.cpp 2010-03-21 17:25:13 UTC (rev 541) +++ trunk/OpenMPT/soundlib/tuning.cpp 2010-03-21 21:29:43 UTC (rev 542) @@ -381,7 +381,8 @@ ssb.ReadItem(pTuning->m_GroupRatio, "RTI3"); ssb.ReadItem(pTuning->m_SerHelperRatiotableSize, "RTI4"); - if ((ssb.m_Status & srlztn::SNT_FAILURE) == 0) + // If reader status is ok and m_StepMin is somewhat reasonable, process data. + if ((ssb.m_Status & srlztn::SNT_FAILURE) == 0 && pTuning->m_StepMin >= -300 && pTuning->m_StepMin <= 300) { EDITMASK temp = pTuning->GetEditMask(); pTuning->m_EditMask = EM_ALLOWALL; //Allowing all while processing data. @@ -500,6 +501,11 @@ //m_StepMin inStrm.read(reinterpret_cast<char*>(&pT->m_StepMin), sizeof(pT->m_StepMin)); + if (pT->m_StepMin < -200 || pT->m_StepMin > 200) + { + delete pT; + return nullptr; + } //m_GroupSize inStrm.read(reinterpret_cast<char*>(&pT->m_GroupSize), sizeof(pT->m_GroupSize)); Modified: trunk/OpenMPT/soundlib/tuningCollection.cpp =================================================================== --- trunk/OpenMPT/soundlib/tuningCollection.cpp 2010-03-21 17:25:13 UTC (rev 541) +++ trunk/OpenMPT/soundlib/tuningCollection.cpp 2010-03-21 21:29:43 UTC (rev 542) @@ -153,10 +153,19 @@ iStrm.seekg(startpos); srlztn::Ssb ssb(iStrm); ssb.BeginRead("TC", s_SerializationVersion); - ssb.ReadItem(m_Name, "0", 1, &ReadStr); - ssb.ReadItem(m_EditMask, "1"); - for(size_t i = 2; i < ssb.GetNumEntries(); i++) - ssb.ReadItem(*this, "2", 1, &ReadTuning); + + srlztn::Ssb::ReadIterator iter = ssb.GetReadBegin(); + const srlztn::Ssb::ReadIterator iterEnd = ssb.GetReadEnd(); + for(iter; iter != iterEnd; iter++) + { + if (ssb.CompareId(iter, "0") == srlztn::Ssb::IdMatch) + ssb.ReadItem(iter, m_Name, &ReadStr); + else if (ssb.CompareId(iter, "1") == srlztn::Ssb::IdMatch) + ssb.ReadItem(iter, m_EditMask); + else if (ssb.CompareId(iter, "2") == srlztn::Ssb::IdMatch) + ssb.ReadItem(iter, *this, &ReadTuning); + } + if(ssb.m_Status & srlztn::SNT_FAILURE) return true; else This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |