From: <rel...@us...> - 2009-06-24 19:40:35
|
Revision: 276 http://modplug.svn.sourceforge.net/modplug/?rev=276&view=rev Author: relabsoluness Date: 2009-06-24 19:39:33 +0000 (Wed, 24 Jun 2009) Log Message: ----------- [Ref] Moved pattern, playbackeventer and sequence files from mptrack to soundlib. (merged from devBranch_1_17_03) Modified Paths: -------------- trunk/OpenMPT/mptrack/mptrack.vcproj trunk/OpenMPT/soundlib/Sndfile.h Added Paths: ----------- trunk/OpenMPT/soundlib/OrderToPatternTable.cpp trunk/OpenMPT/soundlib/OrderToPatternTable.h trunk/OpenMPT/soundlib/PlaybackEventer.cpp trunk/OpenMPT/soundlib/PlaybackEventer.h trunk/OpenMPT/soundlib/pattern.cpp trunk/OpenMPT/soundlib/pattern.h trunk/OpenMPT/soundlib/patternContainer.cpp trunk/OpenMPT/soundlib/patternContainer.h Removed Paths: ------------- trunk/OpenMPT/mptrack/OrderToPatternTable.cpp trunk/OpenMPT/mptrack/OrderToPatternTable.h trunk/OpenMPT/mptrack/PlaybackEventer.cpp trunk/OpenMPT/mptrack/PlaybackEventer.h trunk/OpenMPT/mptrack/pattern.cpp trunk/OpenMPT/mptrack/pattern.h trunk/OpenMPT/mptrack/patternContainer.cpp trunk/OpenMPT/mptrack/patternContainer.h Deleted: trunk/OpenMPT/mptrack/OrderToPatternTable.cpp =================================================================== --- trunk/OpenMPT/mptrack/OrderToPatternTable.cpp 2009-06-24 15:54:18 UTC (rev 275) +++ trunk/OpenMPT/mptrack/OrderToPatternTable.cpp 2009-06-24 19:39:33 UTC (rev 276) @@ -1,228 +0,0 @@ -#include "stdafx.h" -#include "sndfile.h" -#include "ordertopatterntable.h" - -#define str_SequenceTruncationNote (GetStrI18N((_TEXT("Module has sequence of length %u; it will be truncated to maximum supported length, %u.")))) - -DWORD COrderToPatternTable::Unserialize(const BYTE* const src, const DWORD memLength) -//------------------------------------------------------------------------- -{ - if(memLength < 2 + 4) return 0; - uint16 version = 0; - uint32 s = 0; - DWORD memPos = 0; - memcpy(&version, src, sizeof(version)); - memPos += sizeof(version); - if(version != 0) return memPos; - memcpy(&s, src+memPos, sizeof(s)); - memPos += sizeof(s); - if(s > 65000) return true; - if(memLength < memPos+s*4) return memPos; - - const uint32 nOriginalSize = s; - if(s > MPTM_SPECS.ordersMax) - s = MPTM_SPECS.ordersMax; - - resize(s); - for(size_t i = 0; i<s; i++, memPos +=4 ) - { - uint32 temp; - memcpy(&temp, src+memPos, 4); - (*this)[i] = static_cast<PATTERNINDEX>(temp); - } - memPos += 4*(nOriginalSize - s); - return memPos; -} - - -size_t COrderToPatternTable::WriteToByteArray(BYTE* dest, const UINT numOfBytes, const UINT destSize) -//----------------------------------------------------------------------------- -{ - if(numOfBytes > destSize) return true; - if(size() < numOfBytes) resize(numOfBytes, 0xFF); - UINT i = 0; - for(i = 0; i<numOfBytes; i++) - { - dest[i] = static_cast<BYTE>((*this)[i]); - } - return i; //Returns the number of bytes written. -} - - -size_t COrderToPatternTable::WriteAsByte(FILE* f, const UINT count) -//--------------------------------------------------------------- -{ - if(size() < count) resize(count, GetInvalidPatIndex()); - - size_t i = 0; - - for(i = 0; i<count; i++) - { - const PATTERNINDEX pat = (*this)[i]; - BYTE temp = static_cast<BYTE>((*this)[i]); - - if(pat > 0xFD) - { - if(pat == GetInvalidPatIndex()) temp = 0xFF; - else temp = 0xFE; - } - fwrite(&temp, 1, 1, f); - } - return i; //Returns the number of bytes written. -} - -bool COrderToPatternTable::ReadAsByte(const BYTE* pFrom, const int howMany, const int memLength) -//------------------------------------------------------------------------- -{ - if(howMany < 0 || howMany > memLength) return true; - if(m_rSndFile.GetType() != MOD_TYPE_MPT && howMany > MAX_ORDERS) return true; - - if(size() < static_cast<size_t>(howMany)) - resize(howMany, GetInvalidPatIndex()); - - for(int i = 0; i<howMany; i++, pFrom++) - (*this)[i] = *pFrom; - return false; -} - - -bool COrderToPatternTable::NeedsExtraDatafield() const -//---------------------------------------------- -{ - if(m_rSndFile.GetType() == MOD_TYPE_MPT && m_rSndFile.Patterns.Size() > 0xFD) - return true; - else - return false; -} - - -void COrderToPatternTable::OnModTypeChanged(const MODTYPE oldtype) -//---------------------------------------------------------------- -{ - const CModSpecifications specs = m_rSndFile.GetModSpecifications(); - - //Resize orderlist if needed. Because old orderlist had MAX_ORDERS(256) elements, not making it - //smaller than that even if the modtype doesn't support that many orders. - if(specs.ordersMax < GetCount()) - { - resize(max(MAX_ORDERS, specs.ordersMax)); - for(ORDERINDEX i = GetCount(); i>specs.ordersMax; --i) (*this)[i-1] = GetInvalidPatIndex(); - } - - //Replace items used to denote end of song/skip order. - replace(begin(), end(), GetInvalidPatIndex(oldtype), GetInvalidPatIndex()); - replace(begin(), end(), GetIgnoreIndex(oldtype), GetIgnoreIndex()); -} - - -ORDERINDEX COrderToPatternTable::GetLengthTailTrimmed() const -//----------------------------------------------------------- -{ - ORDERINDEX nEnd = GetCount(); - if(nEnd == 0) return 0; - nEnd--; - const PATTERNINDEX iInvalid = GetInvalidPatIndex(); - while(nEnd > 0 && (*this)[nEnd] == iInvalid) - nEnd--; - return ((*this)[nEnd] == iInvalid) ? 0 : nEnd+1; -} - - -ORDERINDEX COrderToPatternTable::GetLengthFirstEmpty() const -//---------------------------------------------------------- -{ - const ORDERINDEX nLength = GetCount(); - ORDERINDEX nMax = 0; - while ((nMax < nLength) && ((*this)[nMax] != (*this).GetInvalidPatIndex())) nMax++; - return nMax; -} - - -ORDERINDEX COrderToPatternTable::GetNextOrderIgnoringSkips(const ORDERINDEX start) const -//------------------------------------------------------------------------------------- -{ - const ORDERINDEX count = GetCount(); - if(count == 0) return 0; - ORDERINDEX next = min(count-1, start+1); - while(next+1 < count && (*this)[next] == GetIgnoreIndex()) next++; - return next; -} - -ORDERINDEX COrderToPatternTable::GetPreviousOrderIgnoringSkips(const ORDERINDEX start) const -//------------------------------------------------------------------------------------- -{ - const ORDERINDEX count = GetCount(); - if(start == 0 || count == 0) return 0; - ORDERINDEX prev = min(start-1, count-1); - while(prev > 0 && (*this)[prev] == GetIgnoreIndex()) prev--; - return prev; -} - - -void COrderToPatternTable::Init() -//------------------------------- -{ - resize(MAX_ORDERS, GetInvalidPatIndex()); - for(ORDERINDEX i = 0; i < GetCount(); i++) - { - (*this)[i] = GetInvalidPatIndex(); - } -} - - - -PATTERNINDEX COrderToPatternTable::GetInvalidPatIndex(const MODTYPE type) {return type == MOD_TYPE_MPT ? 65535 : 0xFF;} -PATTERNINDEX COrderToPatternTable::GetIgnoreIndex(const MODTYPE type) {return type == MOD_TYPE_MPT ? 65534 : 0xFE;} - -PATTERNINDEX COrderToPatternTable::GetInvalidPatIndex() const {return GetInvalidPatIndex(m_rSndFile.GetType());} -PATTERNINDEX COrderToPatternTable::GetIgnoreIndex() const {return GetIgnoreIndex(m_rSndFile.GetType());} - - - - -//-------------------------------------------------- -//-------------------------------------------------- -//-------------------------------------------------- - -using namespace srlztn; - -void COrderSerialization::ProWrite(OUTSTREAM& ostrm) const -//-------------------------------------------------------- -{ - uint16 size = static_cast<uint16>(m_rOrders.size()); - ostrm.write(reinterpret_cast<const char*>(&size), 2); - const COrderToPatternTable::const_iterator endIter = m_rOrders.end(); - for(COrderToPatternTable::const_iterator citer = m_rOrders.begin(); citer != endIter; citer++) - { - const uint16 temp = static_cast<uint16>(*citer); - ostrm.write(reinterpret_cast<const char*>(&temp), 2); - } -} - - -void COrderSerialization::ProRead(INSTREAM& istrm, const uint64 /*datasize*/) -//--------------------------------------------------------------------------- -{ - uint16 size; - istrm.read(reinterpret_cast<char*>(&size), 2); - if(size > MPTM_SPECS.ordersMax) - { - // Hack: Show message here if trying to load longer sequence than what is supported. - CString str; str.Format(str_SequenceTruncationNote, size, MPTM_SPECS.ordersMax); - ::MessageBox(0, str, "", MB_ICONWARNING); - size = MPTM_SPECS.ordersMax; - } - m_rOrders.resize(size); - if(size == 0) {m_rOrders.assign(MAX_ORDERS, m_rOrders.GetInvalidPatIndex()); return;} - - const COrderToPatternTable::const_iterator endIter = m_rOrders.end(); - for(COrderToPatternTable::iterator iter = m_rOrders.begin(); iter != endIter; iter++) - { - uint16 temp; - istrm.read(reinterpret_cast<char*>(&temp), 2); - *iter = temp; - } -} - - - Deleted: trunk/OpenMPT/mptrack/OrderToPatternTable.h =================================================================== --- trunk/OpenMPT/mptrack/OrderToPatternTable.h 2009-06-24 15:54:18 UTC (rev 275) +++ trunk/OpenMPT/mptrack/OrderToPatternTable.h 2009-06-24 19:39:33 UTC (rev 276) @@ -1,77 +0,0 @@ -#ifndef ORDERTOPATTERNTABLE_H -#define ORDERTOPATTERNTABLE_H - -#include "serialization_utils.h" -#include <vector> -using std::vector; - -class CSoundFile; -class COrderToPatternTable; - -#pragma warning(disable:4244) //conversion from 'type1' to 'type2', possible loss of data - -class COrderSerialization : public srlztn::ABCSerializationStreamer -//========================================================= -{ -public: - COrderSerialization(COrderToPatternTable& ordertable) : m_rOrders(ordertable) {} - virtual void ProWrite(srlztn::OUTSTREAM& ostrm) const; - virtual void ProRead(srlztn::INSTREAM& istrm, const uint64 /*datasize*/); -private: - COrderToPatternTable& m_rOrders; -}; - -//============================================== -class COrderToPatternTable : public vector<PATTERNINDEX> -//============================================== -{ -public: - COrderToPatternTable(const CSoundFile& sndFile) : m_rSndFile(sndFile) {} - - // Initialize default sized sequence. - void Init(); - - bool ReadAsByte(const BYTE* pFrom, const int howMany, const int memLength); - - size_t WriteAsByte(FILE* f, const UINT count); - - size_t WriteToByteArray(BYTE* dest, const UINT numOfBytes, const UINT destSize); - - ORDERINDEX GetCount() const {return size();} - - //Deprecated function used for MPTm's created in 1.17.02.46 - 1.17.02.48. - DWORD Unserialize(const BYTE* const src, const DWORD memLength); - - //Returns true if the IT orderlist datafield is not sufficient to store orderlist information. - bool NeedsExtraDatafield() const; - - void OnModTypeChanged(const MODTYPE oldtype); - - // Returns length of sequence without counting trailing '---' items. - ORDERINDEX GetLengthTailTrimmed() const; - - // Returns length of sequence stopping counting on first '---' (or at the end of sequence). - ORDERINDEX GetLengthFirstEmpty() const; - - PATTERNINDEX GetInvalidPatIndex() const; //To correspond 0xFF - static PATTERNINDEX GetInvalidPatIndex(const MODTYPE type); - - PATTERNINDEX GetIgnoreIndex() const; //To correspond 0xFE - static PATTERNINDEX GetIgnoreIndex(const MODTYPE type); - - //Returns the previous/next order ignoring skip indeces(+++). - //If no previous/next order exists, return first/last order, and zero - //when orderlist is empty. - ORDERINDEX GetNextOrderIgnoringSkips(const ORDERINDEX start) const; - ORDERINDEX GetPreviousOrderIgnoringSkips(const ORDERINDEX start) const; - - COrderSerialization* NewReadWriteObject() {return new COrderSerialization(*this);} - -private: - const CSoundFile& m_rSndFile; -}; - -#pragma warning(default:4244) - -#endif - Deleted: trunk/OpenMPT/mptrack/PlaybackEventer.cpp =================================================================== --- trunk/OpenMPT/mptrack/PlaybackEventer.cpp 2009-06-24 15:54:18 UTC (rev 275) +++ trunk/OpenMPT/mptrack/PlaybackEventer.cpp 2009-06-24 19:39:33 UTC (rev 276) @@ -1,31 +0,0 @@ -#include "stdafx.h" -#include "PlaybackEventer.h" -#include "sndfile.h" - -CPlaybackEventer::~CPlaybackEventer() -//--------------------------------- -{ -} - -void CPlaybackEventer::PatternTranstionChnSolo(const CHANNELINDEX chnIndex) -//------------------------------------------------------------------------- -{ - if(chnIndex >= m_rSndFile.m_nChannels) - return; - - for(CHANNELINDEX i = 0; i<m_rSndFile.m_nChannels; i++) - { - m_rSndFile.m_bChannelMuteTogglePending[i] = (m_rSndFile.ChnSettings[i].dwFlags & CHN_MUTE) ? false : true; - } - m_rSndFile.m_bChannelMuteTogglePending[chnIndex] = (m_rSndFile.ChnSettings[chnIndex].dwFlags & CHN_MUTE) ? true : false; -} - - -void CPlaybackEventer::PatternTransitionChnUnmuteAll() -//---------------------------------------------------- -{ - for(CHANNELINDEX i = 0; i<m_rSndFile.m_nChannels; i++) - { - m_rSndFile.m_bChannelMuteTogglePending[i] = (m_rSndFile.ChnSettings[i].dwFlags & CHN_MUTE) ? true : false; - } -} \ No newline at end of file Deleted: trunk/OpenMPT/mptrack/PlaybackEventer.h =================================================================== --- trunk/OpenMPT/mptrack/PlaybackEventer.h 2009-06-24 15:54:18 UTC (rev 275) +++ trunk/OpenMPT/mptrack/PlaybackEventer.h 2009-06-24 19:39:33 UTC (rev 276) @@ -1,25 +0,0 @@ -#ifndef PLAYBACKEVENTER_H -#define PLAYBACKEVENTER_H - -#include "pattern.h" - -class CSoundFile; - -//==================== -class CPlaybackEventer -//==================== -{ -public: - CPlaybackEventer(CSoundFile& sndf) : m_rSndFile(sndf) {} - ~CPlaybackEventer(); - - //SetPatternEvent(const PATTERNINDEX pattern, const ROWINDEX row, const CHANNELINDEX column); - - void PatternTranstionChnSolo(const CHANNELINDEX chnIndex); - void PatternTransitionChnUnmuteAll(); - -private: - CSoundFile& m_rSndFile; -}; - -#endif Modified: trunk/OpenMPT/mptrack/mptrack.vcproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack.vcproj 2009-06-24 15:54:18 UTC (rev 275) +++ trunk/OpenMPT/mptrack/mptrack.vcproj 2009-06-24 19:39:33 UTC (rev 276) @@ -391,13 +391,13 @@ RelativePath=".\OpenGLEditor.cpp"> </File> <File - RelativePath=".\OrderToPatternTable.cpp"> + RelativePath="..\soundlib\OrderToPatternTable.cpp"> </File> <File - RelativePath=".\pattern.cpp"> + RelativePath="..\soundlib\pattern.cpp"> </File> <File - RelativePath=".\patternContainer.cpp"> + RelativePath="..\soundlib\patternContainer.cpp"> </File> <File RelativePath=".\PatternGotoDialog.cpp"> @@ -406,7 +406,7 @@ RelativePath=".\PerformanceCounter.cpp"> </File> <File - RelativePath=".\PlaybackEventer.cpp"> + RelativePath="..\soundlib\PlaybackEventer.cpp"> </File> <File RelativePath=".\PSRatioCalc.cpp"> @@ -804,13 +804,13 @@ RelativePath=".\order.h"> </File> <File - RelativePath=".\OrderToPatternTable.h"> + RelativePath="..\soundlib\OrderToPatternTable.h"> </File> <File - RelativePath=".\pattern.h"> + RelativePath="..\soundlib\pattern.h"> </File> <File - RelativePath=".\patternContainer.h"> + RelativePath="..\soundlib\patternContainer.h"> </File> <File RelativePath=".\PatternGotoDialog.h"> @@ -819,7 +819,7 @@ RelativePath=".\PerformanceCounter.h"> </File> <File - RelativePath=".\PlaybackEventer.h"> + RelativePath="..\soundlib\PlaybackEventer.h"> </File> <File RelativePath=".\PSRatioCalc.h"> Deleted: trunk/OpenMPT/mptrack/pattern.cpp =================================================================== --- trunk/OpenMPT/mptrack/pattern.cpp 2009-06-24 15:54:18 UTC (rev 275) +++ trunk/OpenMPT/mptrack/pattern.cpp 2009-06-24 19:39:33 UTC (rev 276) @@ -1,232 +0,0 @@ -#include "stdafx.h" -#include "pattern.h" -#include "patternContainer.h" -#include "mainfrm.h" -#include "moddoc.h" - - -CHANNELINDEX CPattern::GetNumChannels() const -//------------------------------------------- -{ - return m_rPatternContainer.GetSoundFile().GetNumChannels(); -} - -bool CPattern::Resize(const ROWINDEX newRowCount, const bool showDataLossWarning) -//------------------------------------------- -{ - if(m_ModCommands == NULL) - { - //For Mimicing old behavior of setting patternsize before even having the - //actual pattern allocated. - m_Rows = newRowCount; - return false; - } - - - CSoundFile& sndFile = m_rPatternContainer.GetSoundFile(); - const CModSpecifications& specs = sndFile.GetModSpecifications(); - if(sndFile.m_pModDoc == NULL) return true; - CModDoc& rModDoc = *sndFile.m_pModDoc; - if(newRowCount > specs.patternRowsMax || newRowCount < specs.patternRowsMin) - return true; - - if (newRowCount == m_Rows) return false; - rModDoc.BeginWaitCursor(); - BEGIN_CRITICAL(); - if (newRowCount > m_Rows) - { - MODCOMMAND *p = CSoundFile::AllocatePattern(newRowCount, sndFile.m_nChannels); - if (p) - { - memcpy(p, m_ModCommands, sndFile.m_nChannels*m_Rows*sizeof(MODCOMMAND)); - CSoundFile::FreePattern(m_ModCommands); - m_ModCommands = p; - m_Rows = newRowCount; - } - } else - { - BOOL bOk = TRUE; - MODCOMMAND *p = m_ModCommands; - UINT ndif = (m_Rows - newRowCount) * sndFile.m_nChannels; - UINT npos = newRowCount * sndFile.m_nChannels; - if(showDataLossWarning) - { - for (UINT i=0; i<ndif; i++) - { - if (*((DWORD *)(p+i+npos))) - { - bOk = FALSE; - break; - } - } - if (!bOk && showDataLossWarning) - { - END_CRITICAL(); - rModDoc.EndWaitCursor(); - if (CMainFrame::GetMainFrame()->MessageBox("Data at the end of the pattern will be lost.\nDo you want to continue", - "Shrink Pattern", MB_YESNO|MB_ICONQUESTION) == IDYES) bOk = TRUE; - rModDoc.BeginWaitCursor(); - BEGIN_CRITICAL(); - } - } - if (bOk) - { - MODCOMMAND *pnew = CSoundFile::AllocatePattern(newRowCount, sndFile.m_nChannels); - if (pnew) - { - memcpy(pnew, m_ModCommands, sndFile.m_nChannels*newRowCount*sizeof(MODCOMMAND)); - CSoundFile::FreePattern(m_ModCommands); - m_ModCommands = pnew; - m_Rows = newRowCount; - } - } - } - END_CRITICAL(); - rModDoc.EndWaitCursor(); - rModDoc.SetModified(); - return (newRowCount == m_Rows) ? false : true; -} - - -bool CPattern::ClearData() -//------------------------ -{ - BEGIN_CRITICAL(); - m_Rows = 0; - CSoundFile::FreePattern(m_ModCommands); - m_ModCommands = NULL; - END_CRITICAL(); - return false; -} - -bool CPattern::Expand() -//--------------------- -{ - MODCOMMAND *newPattern, *oldPattern; - UINT nRows, nChns; - - CSoundFile& sndFile = m_rPatternContainer.GetSoundFile(); - if(sndFile.m_pModDoc == NULL) return true; - - CModDoc& rModDoc = *sndFile.m_pModDoc; - - if ((!m_ModCommands) || (m_Rows > sndFile.GetModSpecifications().patternRowsMax / 2)) return true; - - rModDoc.BeginWaitCursor(); - nRows = m_Rows; - nChns = sndFile.m_nChannels; - newPattern = CSoundFile::AllocatePattern(nRows*2, nChns); - if (!newPattern) return true; - - const UINT nPattern = m_rPatternContainer.GetIndex(this); - rModDoc.PrepareUndo(nPattern, 0,0, nChns, nRows); - oldPattern = m_ModCommands; - for (UINT y=0; y<nRows; y++) - { - memcpy(newPattern+y*2*nChns, oldPattern+y*nChns, nChns*sizeof(MODCOMMAND)); - } - m_ModCommands = newPattern; - m_Rows = nRows * 2; - CSoundFile::FreePattern(oldPattern); oldPattern= NULL; - rModDoc.SetModified(); - rModDoc.UpdateAllViews(NULL, HINT_PATTERNDATA | (nPattern << HINT_SHIFT_PAT), NULL); - rModDoc.EndWaitCursor(); - return false; -} - -bool CPattern::Shrink() -//--------------------- -{ - UINT nRows, nChns; - - if (!m_ModCommands || m_Rows < 32) return true; - - CSoundFile& sndFile = m_rPatternContainer.GetSoundFile(); - if(sndFile.m_pModDoc == NULL) return true; - - CModDoc& rModDoc = *sndFile.m_pModDoc; - - rModDoc.BeginWaitCursor(); - nRows = m_Rows; - nChns = sndFile.m_nChannels; - const UINT nPattern = m_rPatternContainer.GetIndex(this); - rModDoc.PrepareUndo(nPattern, 0,0, nChns, nRows); - nRows /= 2; - for (UINT y=0; y<nRows; y++) - { - MODCOMMAND *psrc = sndFile.Patterns[nPattern] + (y * 2 * nChns); - MODCOMMAND *pdest = sndFile.Patterns[nPattern] + (y * nChns); - for (UINT x=0; x<nChns; x++) - { - pdest[x] = psrc[x]; - if ((!pdest[x].note) && (!pdest[x].instr)) - { - pdest[x].note = psrc[x+nChns].note; - pdest[x].instr = psrc[x+nChns].instr; - if (psrc[x+nChns].volcmd) - { - pdest[x].volcmd = psrc[x+nChns].volcmd; - pdest[x].vol = psrc[x+nChns].vol; - } - if (!pdest[x].command) - { - pdest[x].command = psrc[x+nChns].command; - pdest[x].param = psrc[x+nChns].param; - } - } - } - } - m_Rows = nRows; - rModDoc.SetModified(); - rModDoc.UpdateAllViews(NULL, HINT_PATTERNDATA | (nPattern << HINT_SHIFT_PAT), NULL); - rModDoc.EndWaitCursor(); - return false; -} - - - -bool CPattern::WriteITPdata(FILE* f) const -//---------------------------------------- -{ - for(ROWINDEX r = 0; r<GetNumRows(); r++) - { - for(CHANNELINDEX c = 0; c<GetNumChannels(); c++) - { - MODCOMMAND mc = GetModCommand(r,c); - fwrite(&mc, sizeof(MODCOMMAND), 1, f); - } - } - return false; -} - -bool CPattern::ReadITPdata(const BYTE* const lpStream, DWORD& streamPos, const DWORD datasize, const DWORD dwMemLength) -//----------------------------------------------------------------------------------------------- -{ - if(streamPos > dwMemLength || datasize >= dwMemLength - streamPos || datasize < sizeof(MODCOMMAND_ORIGINAL)) - return true; - - const DWORD startPos = streamPos; - ROWINDEX counter = 0; - while(streamPos - startPos + sizeof(MODCOMMAND_ORIGINAL) <= datasize) - { - MODCOMMAND_ORIGINAL temp; - memcpy(&temp, lpStream+streamPos, sizeof(MODCOMMAND_ORIGINAL)); - MODCOMMAND& mc = GetModCommand(counter); - mc.command = temp.command; - mc.instr = temp.instr; - mc.note = temp.note; - mc.param = temp.param; - mc.vol = temp.vol; - mc.volcmd = temp.volcmd; - streamPos += sizeof(MODCOMMAND_ORIGINAL); - counter++; - } - if(streamPos != startPos + datasize) - { - ASSERT(false); - return true; - } - else - return false; -} - Deleted: trunk/OpenMPT/mptrack/pattern.h =================================================================== --- trunk/OpenMPT/mptrack/pattern.h 2009-06-24 15:54:18 UTC (rev 275) +++ trunk/OpenMPT/mptrack/pattern.h 2009-06-24 19:39:33 UTC (rev 276) @@ -1,91 +0,0 @@ -#ifndef PATTERN_H -#define PATTERN_H - -#include <vector> -#include "modcommand.h" - -using std::vector; - -class CPatternContainer; - -typedef MODCOMMAND* PatternRow; - - -//============ -class CPattern -//============ -{ - friend class CPatternContainer; - -public: -//BEGIN: OPERATORS - //To mimic MODCOMMAND* - operator MODCOMMAND*() {return m_ModCommands;} - operator const MODCOMMAND*() const {return m_ModCommands;} - CPattern& operator=(MODCOMMAND* const p) {m_ModCommands = p; return *this;} - CPattern& operator=(const CPattern& pat) - { - m_ModCommands = pat.m_ModCommands; - m_Rows = pat.m_Rows; - return *this; - } -//END: OPERATORS - -//BEGIN: INTERFACE METHODS -public: - MODCOMMAND* GetpModCommand(const ROWINDEX r, const CHANNELINDEX c) {return &m_ModCommands[r*GetNumChannels()+c];} - const MODCOMMAND* GetpModCommand(const ROWINDEX r, const CHANNELINDEX c) const {return &m_ModCommands[r*GetNumChannels()+c];} - - ROWINDEX GetNumRows() const {return m_Rows;} - - // Return true if modcommand can be accessed from given row, false otherwise. - bool IsValidRow(const ROWINDEX iRow) const {return (iRow < GetNumRows());} - - // Return PatternRow object which has operator[] defined so that MODCOMMAND - // at (iRow, iChn) can be accessed with GetRow(iRow)[iChn]. - PatternRow GetRow(const ROWINDEX iRow) {return GetpModCommand(iRow, 0);} - - CHANNELINDEX GetNumChannels() const; - - bool Resize(const ROWINDEX newRowCount, const bool showDataLossWarning = true); - - bool ClearData(); - - bool SetData(MODCOMMAND* p, const ROWINDEX rows) {m_ModCommands = p; m_Rows = rows; return false;} - - bool Expand(); - - bool Shrink(); - - bool WriteITPdata(FILE* f) const; - bool ReadITPdata(const BYTE* const lpStream, DWORD& streamPos, const DWORD datasize, const DWORD dwMemLength); - //Parameters: - //1. Pointer to the beginning of the stream - //2. Tells where to start(lpStream+streamPos) and number of bytes read is added to it. - //3. How many bytes to read - //4. Length of the stream. - //Returns true on error. - -//END: INTERFACE METHODS - - CPattern(CPatternContainer& patCont) : m_ModCommands(0), m_Rows(64), m_rPatternContainer(patCont) {} - -private: - MODCOMMAND& GetModCommand(ROWINDEX i) {return m_ModCommands[i];} - //Returns modcommand from (floor[i/channelCount], i%channelCount) - - MODCOMMAND& GetModCommand(ROWINDEX r, CHANNELINDEX c) {return m_ModCommands[r*GetNumChannels()+c];} - const MODCOMMAND& GetModCommand(ROWINDEX r, CHANNELINDEX c) const {return m_ModCommands[r*GetNumChannels()+c];} - - -//BEGIN: DATA -private: - MODCOMMAND* m_ModCommands; - ROWINDEX m_Rows; - CPatternContainer& m_rPatternContainer; -//END: DATA -}; - - - -#endif Deleted: trunk/OpenMPT/mptrack/patternContainer.cpp =================================================================== --- trunk/OpenMPT/mptrack/patternContainer.cpp 2009-06-24 15:54:18 UTC (rev 275) +++ trunk/OpenMPT/mptrack/patternContainer.cpp 2009-06-24 19:39:33 UTC (rev 276) @@ -1,100 +0,0 @@ -#include "stdafx.h" -#include "patternContainer.h" -#include "sndfile.h" -#include "mainfrm.h" - -int CPatternContainer::Insert(const ROWINDEX rows) -//--------------------------------------------- -{ - PATTERNINDEX i = 0; - for(i = 0; i<m_Patterns.size(); i++) - if(!m_Patterns[i]) break; - if(Insert(i, rows)) - return -1; - else return i; - -} - - -bool CPatternContainer::Insert(const PATTERNINDEX index, const ROWINDEX rows) -//--------------------------------------------------------------- -{ - const CModSpecifications& specs = m_rSndFile.GetModSpecifications(); - if(index >= specs.patternsMax || index > m_Patterns.size() || rows > specs.patternRowsMax) - return true; - if(index < m_Patterns.size() && m_Patterns[index]) - return true; - - if(index == m_Patterns.size()) - { - if(index < specs.patternsMax) - m_Patterns.push_back(MODPATTERN(*this)); - else - { - ErrorBox(IDS_ERR_TOOMANYPAT, CMainFrame::GetMainFrame()); - return true; - } - } - - m_Patterns[index] = CSoundFile::AllocatePattern(rows, m_rSndFile.m_nChannels); - m_Patterns[index].m_Rows = rows; - - if(!m_Patterns[index]) return true; - - return false; -} - -bool CPatternContainer::Remove(const PATTERNINDEX ipat) -//---------------------------------------------- -{ - if(ipat >= m_Patterns.size()) - return true; - - return m_Patterns[ipat].ClearData(); -} - -PATTERNINDEX CPatternContainer::GetIndex(const MODPATTERN* const pPat) const -//------------------------------------------------------------------ -{ - const PATTERNINDEX endI = static_cast<PATTERNINDEX>(m_Patterns.size()); - for(PATTERNINDEX i = 0; i<endI; i++) - if(&m_Patterns[i] == pPat) return i; - - return endI; -} - - -void CPatternContainer::ResizeArray(const PATTERNINDEX newSize) -//------------------------------------------------------------- -{ - if(Size() <= newSize) - m_Patterns.resize(newSize, MODPATTERN(*this)); - else - { - for(PATTERNINDEX i = Size(); i > newSize; i--) Remove(i-1); - m_Patterns.resize(newSize, MODPATTERN(*this)); - } -} - - -void CPatternContainer::OnModTypeChanged(const MODTYPE /*oldtype*/) -//---------------------------------------------------------- -{ - const CModSpecifications specs = m_rSndFile.GetModSpecifications(); - if(specs.patternsMax < Size()) ResizeArray(max(MAX_PATTERNS, specs.patternsMax)); - else if(Size() < MAX_PATTERNS) ResizeArray(MAX_PATTERNS); -} - - -void CPatternContainer::Init() -//---------------------------- -{ - for(PATTERNINDEX i = 0; i < Size(); i++) - { - Remove(i); - } - - ResizeArray(MAX_PATTERNS); -} - - Deleted: trunk/OpenMPT/mptrack/patternContainer.h =================================================================== --- trunk/OpenMPT/mptrack/patternContainer.h 2009-06-24 15:54:18 UTC (rev 275) +++ trunk/OpenMPT/mptrack/patternContainer.h 2009-06-24 19:39:33 UTC (rev 276) @@ -1,77 +0,0 @@ -#ifdef __SNDFILE_H - -#ifndef PATTERNCONTAINER_H -#define PATTERNCONTAINER_H - -#include "pattern.h" -#include <limits> - -class CSoundFile; -typedef CPattern MODPATTERN; - -//===================== -class CPatternContainer -//===================== -{ -//BEGIN: TYPEDEFS -public: - typedef vector<MODPATTERN> PATTERNVECTOR; -//END: TYPEDEFS - - -//BEGIN: OPERATORS -public: - //To mimic old pattern == MODCOMMAND* behavior. - MODPATTERN& operator[](const int pat) {return m_Patterns[pat];} - const MODPATTERN& operator[](const int pat) const {return m_Patterns[pat];} -//END: OPERATORS - -//BEGIN: INTERFACE METHODS -public: - CPatternContainer(CSoundFile& sndFile) : m_rSndFile(sndFile) {m_Patterns.assign(MAX_PATTERNS, MODPATTERN(*this));} - - // Clears existing patterns and resizes array to default size. - void Init(); - - //Note: No memory handling here. - void ClearPatterns() {m_Patterns.assign(m_Patterns.size(), MODPATTERN(*this));} - - //Insert (default)pattern to given position. If pattern already exists at that position, - //ignoring request. - bool Insert(const PATTERNINDEX index, const ROWINDEX rows); - - //Insert pattern to position with the lowest index, and return that index, -1 - //on failure. - int Insert(const ROWINDEX rows); - - //Remove pattern from given position. Currently it actually makes the pattern - //'invisible' - the pattern data is cleared but the actual pattern object won't get removed. - bool Remove(const PATTERNINDEX index); - - PATTERNINDEX Size() const {return static_cast<PATTERNINDEX>(m_Patterns.size());} - - CSoundFile& GetSoundFile() {return m_rSndFile;} - - //Returns the index of given pattern, Size() if not found. - PATTERNINDEX GetIndex(const MODPATTERN* const pPat) const; - - // Return true if pattern can be accessed with operator[](iPat), false otherwise. - bool IsValidIndex(const PATTERNINDEX iPat) const {return (iPat < Size());} - - void ResizeArray(const PATTERNINDEX newSize); - - void OnModTypeChanged(const MODTYPE oldtype); - -//END: INTERFACE METHODS - - -//BEGIN: DATA MEMBERS -private: - PATTERNVECTOR m_Patterns; - CSoundFile& m_rSndFile; -//END: DATA MEMBERS - -}; - -#endif -#endif Copied: trunk/OpenMPT/soundlib/OrderToPatternTable.cpp (from rev 271, trunk/OpenMPT/mptrack/OrderToPatternTable.cpp) =================================================================== --- trunk/OpenMPT/soundlib/OrderToPatternTable.cpp (rev 0) +++ trunk/OpenMPT/soundlib/OrderToPatternTable.cpp 2009-06-24 19:39:33 UTC (rev 276) @@ -0,0 +1,228 @@ +#include "stdafx.h" +#include "sndfile.h" +#include "ordertopatterntable.h" + +#define str_SequenceTruncationNote (GetStrI18N((_TEXT("Module has sequence of length %u; it will be truncated to maximum supported length, %u.")))) + +DWORD COrderToPatternTable::Unserialize(const BYTE* const src, const DWORD memLength) +//------------------------------------------------------------------------- +{ + if(memLength < 2 + 4) return 0; + uint16 version = 0; + uint32 s = 0; + DWORD memPos = 0; + memcpy(&version, src, sizeof(version)); + memPos += sizeof(version); + if(version != 0) return memPos; + memcpy(&s, src+memPos, sizeof(s)); + memPos += sizeof(s); + if(s > 65000) return true; + if(memLength < memPos+s*4) return memPos; + + const uint32 nOriginalSize = s; + if(s > MPTM_SPECS.ordersMax) + s = MPTM_SPECS.ordersMax; + + resize(s); + for(size_t i = 0; i<s; i++, memPos +=4 ) + { + uint32 temp; + memcpy(&temp, src+memPos, 4); + (*this)[i] = static_cast<PATTERNINDEX>(temp); + } + memPos += 4*(nOriginalSize - s); + return memPos; +} + + +size_t COrderToPatternTable::WriteToByteArray(BYTE* dest, const UINT numOfBytes, const UINT destSize) +//----------------------------------------------------------------------------- +{ + if(numOfBytes > destSize) return true; + if(size() < numOfBytes) resize(numOfBytes, 0xFF); + UINT i = 0; + for(i = 0; i<numOfBytes; i++) + { + dest[i] = static_cast<BYTE>((*this)[i]); + } + return i; //Returns the number of bytes written. +} + + +size_t COrderToPatternTable::WriteAsByte(FILE* f, const UINT count) +//--------------------------------------------------------------- +{ + if(size() < count) resize(count, GetInvalidPatIndex()); + + size_t i = 0; + + for(i = 0; i<count; i++) + { + const PATTERNINDEX pat = (*this)[i]; + BYTE temp = static_cast<BYTE>((*this)[i]); + + if(pat > 0xFD) + { + if(pat == GetInvalidPatIndex()) temp = 0xFF; + else temp = 0xFE; + } + fwrite(&temp, 1, 1, f); + } + return i; //Returns the number of bytes written. +} + +bool COrderToPatternTable::ReadAsByte(const BYTE* pFrom, const int howMany, const int memLength) +//------------------------------------------------------------------------- +{ + if(howMany < 0 || howMany > memLength) return true; + if(m_rSndFile.GetType() != MOD_TYPE_MPT && howMany > MAX_ORDERS) return true; + + if(size() < static_cast<size_t>(howMany)) + resize(howMany, GetInvalidPatIndex()); + + for(int i = 0; i<howMany; i++, pFrom++) + (*this)[i] = *pFrom; + return false; +} + + +bool COrderToPatternTable::NeedsExtraDatafield() const +//---------------------------------------------- +{ + if(m_rSndFile.GetType() == MOD_TYPE_MPT && m_rSndFile.Patterns.Size() > 0xFD) + return true; + else + return false; +} + + +void COrderToPatternTable::OnModTypeChanged(const MODTYPE oldtype) +//---------------------------------------------------------------- +{ + const CModSpecifications specs = m_rSndFile.GetModSpecifications(); + + //Resize orderlist if needed. Because old orderlist had MAX_ORDERS(256) elements, not making it + //smaller than that even if the modtype doesn't support that many orders. + if(specs.ordersMax < GetCount()) + { + resize(max(MAX_ORDERS, specs.ordersMax)); + for(ORDERINDEX i = GetCount(); i>specs.ordersMax; --i) (*this)[i-1] = GetInvalidPatIndex(); + } + + //Replace items used to denote end of song/skip order. + replace(begin(), end(), GetInvalidPatIndex(oldtype), GetInvalidPatIndex()); + replace(begin(), end(), GetIgnoreIndex(oldtype), GetIgnoreIndex()); +} + + +ORDERINDEX COrderToPatternTable::GetLengthTailTrimmed() const +//----------------------------------------------------------- +{ + ORDERINDEX nEnd = GetCount(); + if(nEnd == 0) return 0; + nEnd--; + const PATTERNINDEX iInvalid = GetInvalidPatIndex(); + while(nEnd > 0 && (*this)[nEnd] == iInvalid) + nEnd--; + return ((*this)[nEnd] == iInvalid) ? 0 : nEnd+1; +} + + +ORDERINDEX COrderToPatternTable::GetLengthFirstEmpty() const +//---------------------------------------------------------- +{ + const ORDERINDEX nLength = GetCount(); + ORDERINDEX nMax = 0; + while ((nMax < nLength) && ((*this)[nMax] != (*this).GetInvalidPatIndex())) nMax++; + return nMax; +} + + +ORDERINDEX COrderToPatternTable::GetNextOrderIgnoringSkips(const ORDERINDEX start) const +//------------------------------------------------------------------------------------- +{ + const ORDERINDEX count = GetCount(); + if(count == 0) return 0; + ORDERINDEX next = min(count-1, start+1); + while(next+1 < count && (*this)[next] == GetIgnoreIndex()) next++; + return next; +} + +ORDERINDEX COrderToPatternTable::GetPreviousOrderIgnoringSkips(const ORDERINDEX start) const +//------------------------------------------------------------------------------------- +{ + const ORDERINDEX count = GetCount(); + if(start == 0 || count == 0) return 0; + ORDERINDEX prev = min(start-1, count-1); + while(prev > 0 && (*this)[prev] == GetIgnoreIndex()) prev--; + return prev; +} + + +void COrderToPatternTable::Init() +//------------------------------- +{ + resize(MAX_ORDERS, GetInvalidPatIndex()); + for(ORDERINDEX i = 0; i < GetCount(); i++) + { + (*this)[i] = GetInvalidPatIndex(); + } +} + + + +PATTERNINDEX COrderToPatternTable::GetInvalidPatIndex(const MODTYPE type) {return type == MOD_TYPE_MPT ? 65535 : 0xFF;} +PATTERNINDEX COrderToPatternTable::GetIgnoreIndex(const MODTYPE type) {return type == MOD_TYPE_MPT ? 65534 : 0xFE;} + +PATTERNINDEX COrderToPatternTable::GetInvalidPatIndex() const {return GetInvalidPatIndex(m_rSndFile.GetType());} +PATTERNINDEX COrderToPatternTable::GetIgnoreIndex() const {return GetIgnoreIndex(m_rSndFile.GetType());} + + + + +//-------------------------------------------------- +//-------------------------------------------------- +//-------------------------------------------------- + +using namespace srlztn; + +void COrderSerialization::ProWrite(OUTSTREAM& ostrm) const +//-------------------------------------------------------- +{ + uint16 size = static_cast<uint16>(m_rOrders.size()); + ostrm.write(reinterpret_cast<const char*>(&size), 2); + const COrderToPatternTable::const_iterator endIter = m_rOrders.end(); + for(COrderToPatternTable::const_iterator citer = m_rOrders.begin(); citer != endIter; citer++) + { + const uint16 temp = static_cast<uint16>(*citer); + ostrm.write(reinterpret_cast<const char*>(&temp), 2); + } +} + + +void COrderSerialization::ProRead(INSTREAM& istrm, const uint64 /*datasize*/) +//--------------------------------------------------------------------------- +{ + uint16 size; + istrm.read(reinterpret_cast<char*>(&size), 2); + if(size > MPTM_SPECS.ordersMax) + { + // Hack: Show message here if trying to load longer sequence than what is supported. + CString str; str.Format(str_SequenceTruncationNote, size, MPTM_SPECS.ordersMax); + ::MessageBox(0, str, "", MB_ICONWARNING); + size = MPTM_SPECS.ordersMax; + } + m_rOrders.resize(size); + if(size == 0) {m_rOrders.assign(MAX_ORDERS, m_rOrders.GetInvalidPatIndex()); return;} + + const COrderToPatternTable::const_iterator endIter = m_rOrders.end(); + for(COrderToPatternTable::iterator iter = m_rOrders.begin(); iter != endIter; iter++) + { + uint16 temp; + istrm.read(reinterpret_cast<char*>(&temp), 2); + *iter = temp; + } +} + + + Copied: trunk/OpenMPT/soundlib/OrderToPatternTable.h (from rev 271, trunk/OpenMPT/mptrack/OrderToPatternTable.h) =================================================================== --- trunk/OpenMPT/soundlib/OrderToPatternTable.h (rev 0) +++ trunk/OpenMPT/soundlib/OrderToPatternTable.h 2009-06-24 19:39:33 UTC (rev 276) @@ -0,0 +1,77 @@ +#ifndef ORDERTOPATTERNTABLE_H +#define ORDERTOPATTERNTABLE_H + +#include "../mptrack/serialization_utils.h" +#include <vector> +using std::vector; + +class CSoundFile; +class COrderToPatternTable; + +#pragma warning(disable:4244) //conversion from 'type1' to 'type2', possible loss of data + +class COrderSerialization : public srlztn::ABCSerializationStreamer +//========================================================= +{ +public: + COrderSerialization(COrderToPatternTable& ordertable) : m_rOrders(ordertable) {} + virtual void ProWrite(srlztn::OUTSTREAM& ostrm) const; + virtual void ProRead(srlztn::INSTREAM& istrm, const uint64 /*datasize*/); +private: + COrderToPatternTable& m_rOrders; +}; + +//============================================== +class COrderToPatternTable : public vector<PATTERNINDEX> +//============================================== +{ +public: + COrderToPatternTable(const CSoundFile& sndFile) : m_rSndFile(sndFile) {} + + // Initialize default sized sequence. + void Init(); + + bool ReadAsByte(const BYTE* pFrom, const int howMany, const int memLength); + + size_t WriteAsByte(FILE* f, const UINT count); + + size_t WriteToByteArray(BYTE* dest, const UINT numOfBytes, const UINT destSize); + + ORDERINDEX GetCount() const {return size();} + + //Deprecated function used for MPTm's created in 1.17.02.46 - 1.17.02.48. + DWORD Unserialize(const BYTE* const src, const DWORD memLength); + + //Returns true if the IT orderlist datafield is not sufficient to store orderlist information. + bool NeedsExtraDatafield() const; + + void OnModTypeChanged(const MODTYPE oldtype); + + // Returns length of sequence without counting trailing '---' items. + ORDERINDEX GetLengthTailTrimmed() const; + + // Returns length of sequence stopping counting on first '---' (or at the end of sequence). + ORDERINDEX GetLengthFirstEmpty() const; + + PATTERNINDEX GetInvalidPatIndex() const; //To correspond 0xFF + static PATTERNINDEX GetInvalidPatIndex(const MODTYPE type); + + PATTERNINDEX GetIgnoreIndex() const; //To correspond 0xFE + static PATTERNINDEX GetIgnoreIndex(const MODTYPE type); + + //Returns the previous/next order ignoring skip indeces(+++). + //If no previous/next order exists, return first/last order, and zero + //when orderlist is empty. + ORDERINDEX GetNextOrderIgnoringSkips(const ORDERINDEX start) const; + ORDERINDEX GetPreviousOrderIgnoringSkips(const ORDERINDEX start) const; + + COrderSerialization* NewReadWriteObject() {return new COrderSerialization(*this);} + +private: + const CSoundFile& m_rSndFile; +}; + +#pragma warning(default:4244) + +#endif + Copied: trunk/OpenMPT/soundlib/PlaybackEventer.cpp (from rev 217, trunk/OpenMPT/mptrack/PlaybackEventer.cpp) =================================================================== --- trunk/OpenMPT/soundlib/PlaybackEventer.cpp (rev 0) +++ trunk/OpenMPT/soundlib/PlaybackEventer.cpp 2009-06-24 19:39:33 UTC (rev 276) @@ -0,0 +1,31 @@ +#include "stdafx.h" +#include "PlaybackEventer.h" +#include "sndfile.h" + +CPlaybackEventer::~CPlaybackEventer() +//--------------------------------- +{ +} + +void CPlaybackEventer::PatternTranstionChnSolo(const CHANNELINDEX chnIndex) +//------------------------------------------------------------------------- +{ + if(chnIndex >= m_rSndFile.m_nChannels) + return; + + for(CHANNELINDEX i = 0; i<m_rSndFile.m_nChannels; i++) + { + m_rSndFile.m_bChannelMuteTogglePending[i] = (m_rSndFile.ChnSettings[i].dwFlags & CHN_MUTE) ? false : true; + } + m_rSndFile.m_bChannelMuteTogglePending[chnIndex] = (m_rSndFile.ChnSettings[chnIndex].dwFlags & CHN_MUTE) ? true : false; +} + + +void CPlaybackEventer::PatternTransitionChnUnmuteAll() +//---------------------------------------------------- +{ + for(CHANNELINDEX i = 0; i<m_rSndFile.m_nChannels; i++) + { + m_rSndFile.m_bChannelMuteTogglePending[i] = (m_rSndFile.ChnSettings[i].dwFlags & CHN_MUTE) ? true : false; + } +} \ No newline at end of file Copied: trunk/OpenMPT/soundlib/PlaybackEventer.h (from rev 217, trunk/OpenMPT/mptrack/PlaybackEventer.h) =================================================================== --- trunk/OpenMPT/soundlib/PlaybackEventer.h (rev 0) +++ trunk/OpenMPT/soundlib/PlaybackEventer.h 2009-06-24 19:39:33 UTC (rev 276) @@ -0,0 +1,25 @@ +#ifndef PLAYBACKEVENTER_H +#define PLAYBACKEVENTER_H + +#include "pattern.h" + +class CSoundFile; + +//==================== +class CPlaybackEventer +//==================== +{ +public: + CPlaybackEventer(CSoundFile& sndf) : m_rSndFile(sndf) {} + ~CPlaybackEventer(); + + //SetPatternEvent(const PATTERNINDEX pattern, const ROWINDEX row, const CHANNELINDEX column); + + void PatternTranstionChnSolo(const CHANNELINDEX chnIndex); + void PatternTransitionChnUnmuteAll(); + +private: + CSoundFile& m_rSndFile; +}; + +#endif Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2009-06-24 15:54:18 UTC (rev 275) +++ trunk/OpenMPT/soundlib/Sndfile.h 2009-06-24 19:39:33 UTC (rev 276) @@ -805,11 +805,11 @@ typedef VOID (__cdecl * LPSNDMIXHOOKPROC)(int *, unsigned long, unsigned long); // buffer, samples, channels -#include "../mptrack/pattern.h" -#include "../mptrack/patternContainer.h" -#include "../mptrack/ordertopatterntable.h" +#include "pattern.h" +#include "patternContainer.h" +#include "ordertopatterntable.h" -#include "../mptrack/playbackEventer.h" +#include "playbackEventer.h" Copied: trunk/OpenMPT/soundlib/pattern.cpp (from rev 217, trunk/OpenMPT/mptrack/pattern.cpp) =================================================================== --- trunk/OpenMPT/soundlib/pattern.cpp (rev 0) +++ trunk/OpenMPT/soundlib/pattern.cpp 2009-06-24 19:39:33 UTC (rev 276) @@ -0,0 +1,232 @@ +#include "stdafx.h" +#include "pattern.h" +#include "patternContainer.h" +#include "../mptrack/mainfrm.h" +#include "../mptrack/moddoc.h" + + +CHANNELINDEX CPattern::GetNumChannels() const +//------------------------------------------- +{ + return m_rPatternContainer.GetSoundFile().GetNumChannels(); +} + +bool CPattern::Resize(const ROWINDEX newRowCount, const bool showDataLossWarning) +//------------------------------------------- +{ + if(m_ModCommands == NULL) + { + //For Mimicing old behavior of setting patternsize before even having the + //actual pattern allocated. + m_Rows = newRowCount; + return false; + } + + + CSoundFile& sndFile = m_rPatternContainer.GetSoundFile(); + const CModSpecifications& specs = sndFile.GetModSpecifications(); + if(sndFile.m_pModDoc == NULL) return true; + CModDoc& rModDoc = *sndFile.m_pModDoc; + if(newRowCount > specs.patternRowsMax || newRowCount < specs.patternRowsMin) + return true; + + if (newRowCount == m_Rows) return false; + rModDoc.BeginWaitCursor(); + BEGIN_CRITICAL(); + if (newRowCount > m_Rows) + { + MODCOMMAND *p = CSoundFile::AllocatePattern(newRowCount, sndFile.m_nChannels); + if (p) + { + memcpy(p, m_ModCommands, sndFile.m_nChannels*m_Rows*sizeof(MODCOMMAND)); + CSoundFile::FreePattern(m_ModCommands); + m_ModCommands = p; + m_Rows = newRowCount; + } + } else + { + BOOL bOk = TRUE; + MODCOMMAND *p = m_ModCommands; + UINT ndif = (m_Rows - newRowCount) * sndFile.m_nChannels; + UINT npos = newRowCount * sndFile.m_nChannels; + if(showDataLossWarning) + { + for (UINT i=0; i<ndif; i++) + { + if (*((DWORD *)(p+i+npos))) + { + bOk = FALSE; + break; + } + } + if (!bOk && showDataLossWarning) + { + END_CRITICAL(); + rModDoc.EndWaitCursor(); + if (CMainFrame::GetMainFrame()->MessageBox("Data at the end of the pattern will be lost.\nDo you want to continue", + "Shrink Pattern", MB_YESNO|MB_ICONQUESTION) == IDYES) bOk = TRUE; + rModDoc.BeginWaitCursor(); + BEGIN_CRITICAL(); + } + } + if (bOk) + { + MODCOMMAND *pnew = CSoundFile::AllocatePattern(newRowCount, sndFile.m_nChannels); + if (pnew) + { + memcpy(pnew, m_ModCommands, sndFile.m_nChannels*newRowCount*sizeof(MODCOMMAND)); + CSoundFile::FreePattern(m_ModCommands); + m_ModCommands = pnew; + m_Rows = newRowCount; + } + } + } + END_CRITICAL(); + rModDoc.EndWaitCursor(); + rModDoc.SetModified(); + return (newRowCount == m_Rows) ? false : true; +} + + +bool CPattern::ClearData() +//------------------------ +{ + BEGIN_CRITICAL(); + m_Rows = 0; + CSoundFile::FreePattern(m_ModCommands); + m_ModCommands = NULL; + END_CRITICAL(); + return false; +} + +bool CPattern::Expand() +//--------------------- +{ + MODCOMMAND *newPattern, *oldPattern; + UINT nRows, nChns; + + CSoundFile& sndFile = m_rPatternContainer.GetSoundFile(); + if(sndFile.m_pModDoc == NULL) return true; + + CModDoc& rModDoc = *sndFile.m_pModDoc; + + if ((!m_ModCommands) || (m_Rows > sndFile.GetModSpecifications().patternRowsMax / 2)) return true; + + rModDoc.BeginWaitCursor(); + nRows = m_Rows; + nChns = sndFile.m_nChannels; + newPattern = CSoundFile::AllocatePattern(nRows*2, nChns); + if (!newPattern) return true; + + const UINT nPattern = m_rPatternContainer.GetIndex(this); + rModDoc.PrepareUndo(nPattern, 0,0, nChns, nRows); + oldPattern = m_ModCommands; + for (UINT y=0; y<nRows; y++) + { + memcpy(newPattern+y*2*nChns, oldPattern+y*nChns, nChns*sizeof(MODCOMMAND)); + } + m_ModCommands = newPattern; + m_Rows = nRows * 2; + CSoundFile::FreePattern(oldPattern); oldPattern= NULL; + rModDoc.SetModified(); + rModDoc.UpdateAllViews(NULL, HINT_PATTERNDATA | (nPattern << HINT_SHIFT_PAT), NULL); + rModDoc.EndWaitCursor(); + return false; +} + +bool CPattern::Shrink() +//--------------------- +{ + UINT nRows, nChns; + + if (!m_ModCommands || m_Rows < 32) return true; + + CSoundFile& sndFile = m_rPatternContainer.GetSoundFile(); + if(sndFile.m_pModDoc == NULL) return true; + + CModDoc& rModDoc = *sndFile.m_pModDoc; + + rModDoc.BeginWaitCursor(); + nRows = m_Rows; + nChns = sndFile.m_nChannels; + const UINT nPattern = m_rPatternContainer.GetIndex(this); + rModDoc.PrepareUndo(nPattern, 0,0, nChns, nRows); + nRows /= 2; + for (UINT y=0; y<nRows; y++) + { + MODCOMMAND *psrc = sndFile.Patterns[nPattern] + (y * 2 * nChns); + MODCOMMAND *pdest = sndFile.Patterns[nPattern] + (y * nChns); + for (UINT x=0; x<nChns; x++) + { + pdest[x] = psrc[x]; + if ((!pdest[x].note) && (!pdest[x].instr)) + { + pdest[x].note = psrc[x+nChns].note; + pdest[x].instr = psrc[x+nChns].instr; + if (psrc[x+nChns].volcmd) + { + pdest[x].volcmd = psrc[x+nChns].volcmd; + pdest[x].vol = psrc[x+nChns].vol; + } + if (!pdest[x].command) + { + pdest[x].command = psrc[x+nChns].command; + pdest[x].param = psrc[x+nChns].param; + } + } + } + } + m_Rows = nRows; + rModDoc.SetModified(); + rModDoc.UpdateAllViews(NULL, HINT_PATTERNDATA | (nPattern << HINT_SHIFT_PAT), NULL); + rModDoc.EndWaitCursor(); + return false; +} + + + +bool CPattern::WriteITPdata(FILE* f) const +//---------------------------------------- +{ + for(ROWINDEX r = 0; r<GetNumRows(); r++) + { + for(CHANNELINDEX c = 0; c<GetNumChannels(); c++) + { + MODCOMMAND mc = GetModCommand(r,c); + fwrite(&mc, sizeof(MODCOMMAND), 1, f); + } + } + return false; +} + +bool CPattern::ReadITPdata(const BYTE* const lpStream, DWORD& streamPos, const DWORD datasize, const DWORD dwMemLength) +//----------------------------------------------------------------------------------------------- +{ + if(streamPos > dwMemLength || datasize >= dwMemLength - streamPos || datasize < sizeof(MODCOMMAND_ORIGINAL)) + return true; + + const DWORD startPos = streamPos; + ROWINDEX counter = 0; + while(streamPos - startPos + sizeof(MODCOMMAND_ORIGINAL) <= datasize) + { + MODCOMMAND_ORIGINAL temp; + memcpy(&temp, lpStream+streamPos, sizeof(MODCOMMAND_ORIGINAL)); + MODCOMMAND& mc = GetModCommand(counter); + mc.command = temp.command; + mc.instr = temp.instr; + mc.note = temp.note; + mc.param = temp.param; + mc.vol = temp.vol; + mc.volcmd = temp.volcmd; + streamPos += sizeof(MODCOMMAND_ORIGINAL); + counter++; + } + if(streamPos != startPos + datasize) + { + ASSERT(false); + return true; + } + else + return false; +} + Copied: trunk/OpenMPT/soundlib/pattern.h (from rev 244, trunk/OpenMPT/mptrack/pattern.h) =================================================================== --- trunk/OpenMPT/soundlib/pattern.h (rev 0) +++ trunk/OpenMPT/soundlib/pattern.h 2009-06-24 19:39:33 UTC (rev 276) @@ -0,0 +1,91 @@ +#ifndef PATTERN_H +#define PATTERN_H + +#include <vector> +#include "modcommand.h" + +using std::vector; + +class CPatternContainer; + +typedef MODCOMMAND* PatternRow; + + +//============ +class CPattern +//============ +{ + friend class CPatternContainer; + +public: +//BEGIN: OPERATORS + //To mimic MODCOMMAND* + operator MODCOMMAND*() {return m_ModCommands;} + operator const MODCOMMAND*() const {return m_ModCommands;} + CPattern& operator=(MODCOMMAND* const p) {m_ModCommands = p; return *this;} + CPattern& operator=(const CPattern& pat) + { + m_ModCommands = pat.m_ModCommands; + m_Rows = pat.m_Rows; + return *this; + } +//END: OPERATORS + +//BEGIN: INTERFACE METHODS +public: + MODCOMMAND* GetpModCommand(const ROWINDEX r, const CHANNELINDEX c) {return &m_ModCommands[r*GetNumChannels()+c];} + const MODCOMMAND* GetpModCommand(const ROWINDEX r, const CHANNELINDEX c) const {return &m_ModCommands[r*GetNumChannels()+c];} + + ROWINDEX GetNumRows() const {return m_Rows;} + + // Return true if modcommand can be accessed from given row, false otherwise. + bool IsValidRow(const ROWINDEX iRow) const {return (iRow < GetNumRows());} + + // Return PatternRow object which has operator[] defined so that MODCOMMAND + // at (iRow, iChn) can be accessed with GetRow(iRow)[iChn]. + PatternRow GetRow(const ROWINDEX iRow) {return GetpModCommand(iRow, 0);} + + CHANNELINDEX GetNumChannels() const; + + bool Resize(const ROWINDEX newRowCount, const bool showDataLossWarning = true); + + bool ClearData(); + + bool SetData(MODCOMMAND* p, const ROWINDEX rows) {m_ModCommands = p; m_Rows = rows; return false;} + + bool Expand(); + + bool Shrink(); + + bool WriteITPdata(FILE* f) const; + bool ReadITPdata(const BYTE* const lpStream, DWORD& streamPos, const DWORD datasize, const DWORD dwMemLength); + //Parameters: + //1. Pointer to the beginning of the stream + //2. Tells where to start(lpStream+streamPos) and number of bytes read is added to it. + //3. How many bytes to read + //4. Length of the stream. + //Returns true on error. + +//END: INTERFACE METHODS + + CPattern(CPatternContainer& patCont) : m_ModCommands(0), m_Rows(64), m_rPatternContainer(patCont) {} + +private: + MODCOMMAND& GetModCommand(ROWINDEX i) {return m_ModCommands[i];} + //Returns modcommand from (floor[i/channelCount], i%channelCount) + + MODCOMMAND& GetModCommand(ROWINDEX r, CHANNELINDEX c) {return m_ModCommands[r*GetNumChannels()+c];} + const MODCOMMAND& GetModCommand(ROWINDEX r, CHANNELINDEX c) const {return m_ModCommands[r*GetNumChannels()+c];} + + +//BEGIN: DATA +private: + MODCOMMAND* m_ModCommands; + ROWINDEX m_Rows; + CPatternContainer& m_rPatternContainer; +//END: DATA +}; + + + +#endif Copied: trunk/OpenMPT/soundlib/patternContainer.cpp (from rev 271, trunk/OpenMPT/mptrack/patternContainer.cpp) =================================================================== --- trunk/OpenMPT/soundlib/patternContainer.cpp (rev 0) +++ trunk/OpenMPT/soundlib/patternContainer.cpp 2009-06-24 19:39:33 UTC (rev 276) @@ -0,0 +1,100 @@ +#include "stdafx.h" +#include "patternContainer.h" +#include "sndfile.h" +#include "../mptrack/mainfrm.h" + +int CPatternContainer::Insert(const ROWINDEX rows) +//--------------------------------------------- +{ + PATTERNINDEX i = 0; + for(i = 0; i<m_Patterns.size(); i++) + if(!m_Patterns[i]) break; + if(Insert(i, rows)) + return -1; + else return i; + +} + + +bool CPatternContainer::Insert(const PATTERNINDEX index, const ROWINDEX rows) +//--------------------------------------------------------------- +{ + const CModSpecifications& specs = m_rSndFile.GetModSpecifications(); + if(index >= specs.patternsMax || index > m_Patterns.size() || rows > specs.patternRowsMax) + return true; + if(index < m_Patterns.size() && m_Patterns[index]) + return true; + + if(index == m_Patterns.size()) + { + if(index < specs.patternsMax) + m_Patterns.push_back(MODPATTERN(*this)); + else + { + ErrorBox(IDS_ERR_TOOMANYPAT, CMainFrame::GetMainFrame()); + return true; + } + } + + m_Patterns[index] = CSoundFile::AllocatePattern(rows, m_rSndFile.m_nChannels); + m_Patterns[index].m_Rows = rows; + + if(!m_Patterns[index]) return true; + + return false; +} + +bool CPatternContainer::Remove(const PATTERNINDEX ipat) +//---------------------------------------------- +{ + if(ipat >= m_Patterns.size()) + return true; + + return m_Patterns[ipat].ClearData(); +} + +PATTERNINDEX CPatternContainer::GetIndex(const MODPATTERN* const pPat) const +//------------------------------------------------------------------ +{ + const PATTERNINDEX endI = static_cast<PATTERNINDEX>(m_Patterns.size()); + for(PATTERNINDEX i = 0; i<endI; i++) + if(&m_Patterns[i] == pPat) return i; + + return endI; +} + + +void CPatternContainer::ResizeArray(const PATTERNINDEX newSize) +//------------------------------------------------------------- +{ + if(Size() <= newSize) + m_Patterns.resize(newSize, MODPATTERN(*this)); + else + { + for(PATTERNINDEX i = Size(); i > newSize; i--) Remove(i-1); + m_Patterns.resize(newSize, MODPATTERN(*this)); + } +} + + +void CPatternContainer::OnModTypeChanged(const MODTYPE /*oldtype*/) +//---------------------------------------------------------- +{ + const CModSpecifications specs = m_rSndFile.GetModSpecifications(); + if(specs.patternsMax < Size()) ResizeArray(max(MAX_PATTERNS, specs.patternsMax)); + else if(Size() < MAX_PATTERNS) ResizeArray(MAX_PATTERNS); +} + + +void CPatternContainer::Init() +//---------------------------- +{ + for(PATTERNINDEX i = 0; i < Size(); i++) + { + Remove(i); + } + + ResizeArray(MAX_PATTERNS); +} + + Copied: trunk/OpenMPT/soundlib/patternContainer.h (from rev 271, trunk/OpenMPT/mptrack/patternContainer.h) =================================================================== --- trunk/OpenMPT/soundlib/patternContainer.h (rev 0) +++ trunk/OpenMPT/soundlib/patternContainer.h 2009-06-24 19:39:33 UTC (rev 276) @@ -0,0 +1,77 @@ +#ifdef __SNDFILE_H + +#ifndef PATTERNCONTAINER_H +#define PATTERNCONTAINER_H + +#include "pattern.h" +#include <limits> + +class CSoundFile; +typedef CPattern MODPATTERN; + +//===================== +class CPatternContainer +//===================== +{ +//BEGIN: TYPEDEFS +public: + typedef vector<MODPATTERN> PATTERNVECTOR; +//END: TYPEDEFS + + +//BEGIN: OPERATORS +public: + //To mimic old pattern == MODCOMMAND* behavior. + MODPATTERN& operator[](const int pat) {return m_Patterns[pat];} + const MODPATTERN& operator[](const int pat) const {return m_Patterns[pat];} +//END: OPERATORS + +//BEGIN: INTERFACE METHODS +public: + CPatternContainer(CSoundFile& sndFile) : m_rSndFile(sndFile) {m_Patterns.assign(MAX_PATTERNS, MODPATTERN(*this));} + + // Clears existing patterns and resizes array to default size. + void Init(); + + //Note: No memory handling here. + void ClearPatterns() {m_Patterns.assign(m_Patterns.size(), MODPATTERN(*this));} + + //Insert (default)pattern to given position. If pattern already exists at that position, + //ignoring request. + bool Insert(const PATTERNINDEX index, const ROWINDEX rows); + + //Insert pattern to position with the lowest index, and return that index, -1 + //on failure. + int Insert(const ROWINDEX rows); + + //Remove pattern from given position. Currently it actually makes the pattern + //'invisible' - the pattern data is cleared but the actual pattern object won't get removed. + bool Remove(const PATTERNINDEX index); + + PATTERNINDEX Size() const {return static_cast<PATTERNINDEX>(m_Patterns.size());} + + CSoundFile& GetSoundFile() {return m_rSndFile;} + + //Returns the index of given pattern, Size() if not found. + PATTERNINDEX GetIndex(const MODPATTERN* const pPat) const; + + // Return true if pattern can be accessed with operator[](iPat), false otherwise. + bool IsValidIndex(const PATTERNINDEX iPat) const {return (iPat < Size());} + + void ResizeArray(const PATTERNINDEX newSize); + + void OnModTypeChanged(const MODTYPE oldtype); + +//END: INTERFACE METHODS + + +//BEGIN: DATA MEMBERS +private: + PATTERNVECTOR m_Patterns; + CSoundFile& m_rSndFile; +//END: DATA MEMBERS + +}; + +#endif +#endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |