diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/external_dependencies/openmpt-trunk/soundlib/patternContainer.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/external_dependencies/openmpt-trunk/soundlib/patternContainer.cpp')
-rw-r--r-- | Src/external_dependencies/openmpt-trunk/soundlib/patternContainer.cpp | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/Src/external_dependencies/openmpt-trunk/soundlib/patternContainer.cpp b/Src/external_dependencies/openmpt-trunk/soundlib/patternContainer.cpp new file mode 100644 index 00000000..ace4406d --- /dev/null +++ b/Src/external_dependencies/openmpt-trunk/soundlib/patternContainer.cpp @@ -0,0 +1,201 @@ +/* + * PatternContainer.cpp + * -------------------- + * Purpose: Container class for managing patterns. + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + + +#include "stdafx.h" +#include "patternContainer.h" +#include "Sndfile.h" +#include "mod_specifications.h" +#include "../common/serialization_utils.h" +#include "../common/version.h" + + +OPENMPT_NAMESPACE_BEGIN + + +void CPatternContainer::ClearPatterns() +{ + DestroyPatterns(); + m_Patterns.assign(m_Patterns.size(), CPattern(*this)); +} + + +void CPatternContainer::DestroyPatterns() +{ + m_Patterns.clear(); +} + + +PATTERNINDEX CPatternContainer::Duplicate(PATTERNINDEX from, bool respectQtyLimits) +{ + if(!IsValidPat(from)) + { + return PATTERNINDEX_INVALID; + } + + PATTERNINDEX newPatIndex = InsertAny(m_Patterns[from].GetNumRows(), respectQtyLimits); + + if(newPatIndex != PATTERNINDEX_INVALID) + { + m_Patterns[newPatIndex] = m_Patterns[from]; + } + return newPatIndex; +} + + +PATTERNINDEX CPatternContainer::InsertAny(const ROWINDEX rows, bool respectQtyLimits) +{ + PATTERNINDEX i = 0; + for(i = 0; i < m_Patterns.size(); i++) + if(!m_Patterns[i].IsValid()) break; + if(respectQtyLimits && i >= m_rSndFile.GetModSpecifications().patternsMax) + return PATTERNINDEX_INVALID; + if(!Insert(i, rows)) + return PATTERNINDEX_INVALID; + else return i; +} + + +bool CPatternContainer::Insert(const PATTERNINDEX index, const ROWINDEX rows) +{ + if(rows > MAX_PATTERN_ROWS || rows == 0 || index >= PATTERNINDEX_INVALID) + return false; + if(IsValidPat(index)) + return false; + + try + { + if(index >= m_Patterns.size()) + { + m_Patterns.resize(index + 1, CPattern(*this)); + } + m_Patterns[index].AllocatePattern(rows); + m_Patterns[index].RemoveSignature(); + m_Patterns[index].SetName(""); + } catch(mpt::out_of_memory e) + { + mpt::delete_out_of_memory(e); + return false; + } + return m_Patterns[index].IsValid(); +} + + +void CPatternContainer::Remove(const PATTERNINDEX ipat) +{ + if(ipat < m_Patterns.size()) m_Patterns[ipat].Deallocate(); +} + + +bool CPatternContainer::IsPatternEmpty(const PATTERNINDEX nPat) const +{ + if(!IsValidPat(nPat)) + return false; + + for(const auto &m : m_Patterns[nPat].m_ModCommands) + { + if(!m.IsEmpty()) + return false; + } + return true; +} + + +void CPatternContainer::ResizeArray(const PATTERNINDEX newSize) +{ + m_Patterns.resize(newSize, CPattern(*this)); +} + + +void CPatternContainer::OnModTypeChanged(const MODTYPE /*oldtype*/) +{ + const CModSpecifications specs = m_rSndFile.GetModSpecifications(); + //if(specs.patternsMax < Size()) + // ResizeArray(specs.patternsMax); + + // remove pattern time signatures + if(!specs.hasPatternSignatures) + { + for(PATTERNINDEX nPat = 0; nPat < m_Patterns.size(); nPat++) + { + m_Patterns[nPat].RemoveSignature(); + m_Patterns[nPat].RemoveTempoSwing(); + } + } +} + + +PATTERNINDEX CPatternContainer::GetNumPatterns() const +{ + for(PATTERNINDEX pat = Size(); pat > 0; pat--) + { + if(IsValidPat(pat - 1)) + { + return pat; + } + } + return 0; +} + + +PATTERNINDEX CPatternContainer::GetNumNamedPatterns() const +{ + if(Size() == 0) + { + return 0; + } + for(PATTERNINDEX nPat = Size(); nPat > 0; nPat--) + { + if(!m_Patterns[nPat - 1].GetName().empty()) + { + return nPat; + } + } + return 0; +} + + + +void WriteModPatterns(std::ostream& oStrm, const CPatternContainer& patc) +{ + srlztn::SsbWrite ssb(oStrm); + ssb.BeginWrite(FileIdPatterns, Version::Current().GetRawVersion()); + const PATTERNINDEX nPatterns = patc.Size(); + uint16 nCount = 0; + for(uint16 i = 0; i < nPatterns; i++) if (patc[i].IsValid()) + { + ssb.WriteItem(patc[i], srlztn::ID::FromInt<uint16>(i), &WriteModPattern); + nCount = i + 1; + } + ssb.WriteItem<uint16>(nCount, "num"); // Index of last pattern + 1. + ssb.FinishWrite(); +} + + +void ReadModPatterns(std::istream& iStrm, CPatternContainer& patc, const size_t) +{ + srlztn::SsbRead ssb(iStrm); + ssb.BeginRead(FileIdPatterns, Version::Current().GetRawVersion()); + if ((ssb.GetStatus() & srlztn::SNT_FAILURE) != 0) + return; + PATTERNINDEX nPatterns = patc.Size(); + uint16 nCount = uint16_max; + if (ssb.ReadItem(nCount, "num") != srlztn::SsbRead::EntryNotFound) + nPatterns = nCount; + LimitMax(nPatterns, ModSpecs::mptm.patternsMax); + if (nPatterns > patc.Size()) + patc.ResizeArray(nPatterns); + for(uint16 i = 0; i < nPatterns; i++) + { + ssb.ReadItem(patc[i], srlztn::ID::FromInt<uint16>(i), &ReadModPattern); + } +} + + +OPENMPT_NAMESPACE_END |