You can subscribe to this list here.
| 2006 |
Jan
|
Feb
|
Mar
(1) |
Apr
(1) |
May
|
Jun
(1) |
Jul
|
Aug
(10) |
Sep
|
Oct
|
Nov
|
Dec
(3) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2007 |
Jan
(1) |
Feb
(2) |
Mar
(3) |
Apr
(2) |
May
(10) |
Jun
(2) |
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
(3) |
Dec
|
| 2008 |
Jan
(6) |
Feb
(4) |
Mar
(5) |
Apr
(2) |
May
(1) |
Jun
(1) |
Jul
(4) |
Aug
(6) |
Sep
(2) |
Oct
(9) |
Nov
(1) |
Dec
(4) |
| 2009 |
Jan
(9) |
Feb
(2) |
Mar
(2) |
Apr
(2) |
May
(6) |
Jun
(18) |
Jul
(33) |
Aug
(39) |
Sep
(33) |
Oct
(24) |
Nov
(23) |
Dec
(22) |
| 2010 |
Jan
(29) |
Feb
(32) |
Mar
(51) |
Apr
(17) |
May
(31) |
Jun
(21) |
Jul
(32) |
Aug
(28) |
Sep
(35) |
Oct
(27) |
Nov
(11) |
Dec
(13) |
| 2011 |
Jan
(14) |
Feb
(13) |
Mar
(27) |
Apr
(27) |
May
(28) |
Jun
(20) |
Jul
(43) |
Aug
(52) |
Sep
(66) |
Oct
(61) |
Nov
(11) |
Dec
(8) |
| 2012 |
Jan
(20) |
Feb
(30) |
Mar
(38) |
Apr
(21) |
May
(33) |
Jun
(21) |
Jul
(25) |
Aug
(9) |
Sep
(24) |
Oct
(42) |
Nov
(27) |
Dec
(41) |
| 2013 |
Jan
(20) |
Feb
(35) |
Mar
(156) |
Apr
(298) |
May
(258) |
Jun
(201) |
Jul
(105) |
Aug
(60) |
Sep
(193) |
Oct
(245) |
Nov
(280) |
Dec
(194) |
| 2014 |
Jan
(63) |
Feb
(202) |
Mar
(200) |
Apr
(23) |
May
(53) |
Jun
(105) |
Jul
(18) |
Aug
(26) |
Sep
(110) |
Oct
(187) |
Nov
(97) |
Dec
(74) |
| 2015 |
Jan
(45) |
Feb
(55) |
Mar
(116) |
Apr
(116) |
May
(193) |
Jun
(164) |
Jul
(50) |
Aug
(111) |
Sep
(98) |
Oct
(71) |
Nov
(103) |
Dec
(63) |
| 2016 |
Jan
(33) |
Feb
(101) |
Mar
(182) |
Apr
(139) |
May
(140) |
Jun
(103) |
Jul
(165) |
Aug
(286) |
Sep
(208) |
Oct
(127) |
Nov
(97) |
Dec
(54) |
| 2017 |
Jan
(64) |
Feb
(335) |
Mar
(202) |
Apr
(212) |
May
(139) |
Jun
(127) |
Jul
(294) |
Aug
(154) |
Sep
(170) |
Oct
(152) |
Nov
(156) |
Dec
(62) |
| 2018 |
Jan
(168) |
Feb
(237) |
Mar
(196) |
Apr
(174) |
May
(174) |
Jun
(161) |
Jul
(127) |
Aug
(88) |
Sep
(149) |
Oct
(66) |
Nov
(52) |
Dec
(135) |
| 2019 |
Jan
(146) |
Feb
(126) |
Mar
(104) |
Apr
(58) |
May
(60) |
Jun
(28) |
Jul
(197) |
Aug
(129) |
Sep
(141) |
Oct
(148) |
Nov
(63) |
Dec
(100) |
| 2020 |
Jan
(74) |
Feb
(37) |
Mar
(59) |
Apr
(154) |
May
(194) |
Jun
(133) |
Jul
(313) |
Aug
(197) |
Sep
(49) |
Oct
(162) |
Nov
(143) |
Dec
(57) |
| 2021 |
Jan
(120) |
Feb
(107) |
Mar
(314) |
Apr
(157) |
May
(524) |
Jun
(169) |
Jul
(72) |
Aug
(133) |
Sep
(135) |
Oct
(146) |
Nov
(198) |
Dec
(325) |
| 2022 |
Jan
(409) |
Feb
(249) |
Mar
(138) |
Apr
(95) |
May
(102) |
Jun
(221) |
Jul
(66) |
Aug
(120) |
Sep
(192) |
Oct
(131) |
Nov
(53) |
Dec
(171) |
| 2023 |
Jan
(357) |
Feb
(82) |
Mar
(168) |
Apr
(218) |
May
(196) |
Jun
(86) |
Jul
(115) |
Aug
(49) |
Sep
(190) |
Oct
(102) |
Nov
(45) |
Dec
(76) |
| 2024 |
Jan
(86) |
Feb
(50) |
Mar
(324) |
Apr
(209) |
May
(197) |
Jun
(232) |
Jul
(194) |
Aug
(247) |
Sep
(219) |
Oct
(266) |
Nov
(328) |
Dec
(304) |
| 2025 |
Jan
(191) |
Feb
(115) |
Mar
(137) |
Apr
(32) |
May
(126) |
Jun
(403) |
Jul
(213) |
Aug
(203) |
Sep
(148) |
Oct
(109) |
Nov
(191) |
Dec
(209) |
| 2026 |
Jan
(127) |
Feb
(123) |
Mar
(160) |
Apr
(141) |
May
(45) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
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.
|
|
From: <rel...@us...> - 2009-06-24 15:54:23
|
Revision: 275
http://modplug.svn.sourceforge.net/modplug/?rev=275&view=rev
Author: relabsoluness
Date: 2009-06-24 15:54:18 +0000 (Wed, 24 Jun 2009)
Log Message:
-----------
(Patch from Jojo)
. Playback: 4-Bit panning didn't disable surround sound (merge edit: now uses compatibility flag for IT/MPTM/XM).
Modified Paths:
--------------
trunk/OpenMPT/soundlib/Snd_fx.cpp
Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-06-23 19:53:05 UTC (rev 274)
+++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-06-24 15:54:18 UTC (rev 275)
@@ -2277,7 +2277,16 @@
// E7x: Set Tremolo WaveForm
case 0x70: pChn->nTremoloType = param & 0x07; break;
// E8x: Set 4-bit Panning
- case 0x80: if (!m_nTickCount) { pChn->nPan = (param << 4) + 8; pChn->dwFlags |= CHN_FASTVOLRAMP; } break;
+ //case 0x80: if (!m_nTickCount) { pChn->nPan = (param << 4) + 8; pChn->dwFlags |= CHN_FASTVOLRAMP; } break;
+ case 0x80: if (!m_nTickCount)
+ {
+ if( TypeIsIT_MPT_XM() == false || GetModFlag(MSF_COMPATIBLE_PLAY) )
+ {
+ if (!(m_dwSongFlags & SONG_SURROUNDPAN)) pChn->dwFlags &= ~CHN_SURROUND;
+ }
+ pChn->nPan = (param << 4) + 8; pChn->dwFlags |= CHN_FASTVOLRAMP;
+ }
+ break;
// E9x: Retrig
case 0x90: RetrigNote(nChn, param); break;
// EAx: Fine Volume Up
@@ -2352,7 +2361,16 @@
}
break;
// S8x: Set 4-bit Panning
- case 0x80: if (!m_nTickCount) { pChn->nPan = (param << 4) + 8; pChn->dwFlags |= CHN_FASTVOLRAMP; } break;
+ //case 0x80: if (!m_nTickCount) { pChn->nPan = (param << 4) + 8; pChn->dwFlags |= CHN_FASTVOLRAMP; } break;
+ case 0x80: if (!m_nTickCount)
+ {
+ if( TypeIsIT_MPT_XM() == false || GetModFlag(MSF_COMPATIBLE_PLAY) )
+ {
+ if (!(m_dwSongFlags & SONG_SURROUNDPAN)) pChn->dwFlags &= ~CHN_SURROUND;
+ }
+ pChn->nPan = (param << 4) + 8; pChn->dwFlags |= CHN_FASTVOLRAMP;
+ }
+ break;
// S9x: Set Surround
case 0x90: ExtendedChannelEffect(pChn, param & 0x0F); break;
// SAx: Set 64k Offset
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2009-06-23 19:53:13
|
Revision: 274
http://modplug.svn.sourceforge.net/modplug/?rev=274&view=rev
Author: relabsoluness
Date: 2009-06-23 19:53:05 +0000 (Tue, 23 Jun 2009)
Log Message:
-----------
1.17.02.54
Modified Paths:
--------------
branches/1.17.02.53x/mptrack/bin/mptrack.exe
branches/1.17.02.53x/packageTemplate/History.txt
Modified: branches/1.17.02.53x/mptrack/bin/mptrack.exe
===================================================================
(Binary files differ)
Modified: branches/1.17.02.53x/packageTemplate/History.txt
===================================================================
--- branches/1.17.02.53x/packageTemplate/History.txt 2009-06-23 19:38:41 UTC (rev 273)
+++ branches/1.17.02.53x/packageTemplate/History.txt 2009-06-23 19:53:05 UTC (rev 274)
@@ -8,7 +8,14 @@
?: other
(tx XYZ): thanks to XYZ for telling us about the bug
+v1.17.02.54 (June 2009, revision 274)
+-------------------------------------
+ . <re> Pattern tab: It's now possible to use the old note fade behaviour when playing notes (see setup->general). (rev. 267)
+ . <re> Pattern tab: Fixed wrong interpretations of "Old style pattern context menu"-option. (rev. 267)
+ . <re> Misc: Some internal fixes. (rev. 267)
+
+
v1.17.02.53 (May 2009, revision 259)
------------------------------------
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2009-06-23 19:38:50
|
Revision: 273
http://modplug.svn.sourceforge.net/modplug/?rev=273&view=rev
Author: relabsoluness
Date: 2009-06-23 19:38:41 +0000 (Tue, 23 Jun 2009)
Log Message:
-----------
(Patches from Jojo, merged somewhat modified)
+ General: Can now import GDM files.
/ Pattern tab: Improved echo paste undo.
. Misc: Document will now be set modified when changing rows per beat from main bar.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Mainbar.cpp
trunk/OpenMPT/mptrack/Modedit.cpp
trunk/OpenMPT/mptrack/mptrack.vcproj
trunk/OpenMPT/soundlib/Sndfile.cpp
trunk/OpenMPT/soundlib/Sndfile.h
Added Paths:
-----------
trunk/OpenMPT/soundlib/Load_gdm.cpp
Modified: trunk/OpenMPT/mptrack/Mainbar.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Mainbar.cpp 2009-06-17 18:44:27 UTC (rev 272)
+++ trunk/OpenMPT/mptrack/Mainbar.cpp 2009-06-23 19:38:41 UTC (rev 273)
@@ -487,6 +487,7 @@
if ((nCurrentSpeed < 0) || (nCurrentTempo < 0)) return;
if ((pMainFrm = CMainFrame::GetMainFrame()) != NULL)
{
+ CModDoc *pModDoc = pMainFrm->GetModPlaying();
CSoundFile *pSndFile = pMainFrm->GetSoundFilePlaying();
if (pSndFile)
{
@@ -524,12 +525,14 @@
if (nCurrentRowsPerBeat > 1)
{
pSndFile->m_nRowsPerBeat = nCurrentRowsPerBeat - 1;
+ pModDoc->SetModified(true);
}
} else
{
if (nCurrentRowsPerBeat < 64)
{
pSndFile->m_nRowsPerBeat = nCurrentRowsPerBeat + 1;
+ pModDoc->SetModified(true);
}
}
m_SpinRowsPerBeat.SetPos(0);
Modified: trunk/OpenMPT/mptrack/Modedit.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Modedit.cpp 2009-06-17 18:44:27 UTC (rev 272)
+++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-06-23 19:38:41 UTC (rev 273)
@@ -1833,6 +1833,7 @@
nPattern = m_SndFile.Order[oNextOrder];
if(m_SndFile.Patterns.IsValidIndex(nPattern) == false) goto PasteDone;
m = m_SndFile.Patterns[nPattern];
+ PrepareUndo(nPattern, 0,0, m_SndFile.m_nChannels, m_SndFile.PatternSize[nPattern]);
oCurrentOrder = oNextOrder;
}
}
Modified: trunk/OpenMPT/mptrack/mptrack.vcproj
===================================================================
--- trunk/OpenMPT/mptrack/mptrack.vcproj 2009-06-17 18:44:27 UTC (rev 272)
+++ trunk/OpenMPT/mptrack/mptrack.vcproj 2009-06-23 19:38:41 UTC (rev 273)
@@ -277,6 +277,9 @@
RelativePath="..\soundlib\Load_far.cpp">
</File>
<File
+ RelativePath="..\soundlib\Load_gdm.cpp">
+ </File>
+ <File
RelativePath="..\soundlib\Load_it.cpp">
</File>
<File
Added: trunk/OpenMPT/soundlib/Load_gdm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_gdm.cpp (rev 0)
+++ trunk/OpenMPT/soundlib/Load_gdm.cpp 2009-06-23 19:38:41 UTC (rev 273)
@@ -0,0 +1,532 @@
+/*
+ * This source code is public domain.
+ *
+ * Purpose: Load GDM (BWSB Soundsystem) modules
+ * Authors: Johannes Schultz
+ *
+ * This code is partly based on zilym's original code / specs (which are utterly wrong :P).
+ * Thanks to the MenTaLguY for gdm.txt and ajs for gdm2s3m and some hints.
+ *
+ * Hint 1: Most (all?) of the unsupported features were not supported in 2GDM / BWSB either.
+ * Hint 2: Files will be played like their original formats would be played in MPT, so no
+ * BWSB quirks including crashes and freezes are supported. :-P
+*/
+
+#include "stdafx.h"
+#include "sndfile.h"
+
+#pragma pack(1)
+
+typedef struct _GDMHEADER
+{
+ DWORD ID; // ID: 'GDM\xFE'
+ CHAR SongTitle[32]; // Music's title
+ CHAR SongMusician[32]; // Name of music's composer
+ CHAR DOSEOF[3]; // 13, 10, 26
+ DWORD ID2; // ID: 'GMFS'
+ BYTE FormMajorVer; // Format major version
+ BYTE FormMinorVer; // Format minor version
+ UINT16 TrackID; // Composing Tracker ID code (00 = 2GDM)
+ BYTE TrackMajorVer; // Tracker's major version
+ BYTE TrackMinorVer; // Tracker's minor version
+ BYTE PanMap[32]; // 0-Left to 15-Right, 255-N/U
+ BYTE MastVol; // Range: 0...64
+ BYTE Tempo; // Initial music tempo (6)
+ BYTE BPM; // Initial music BPM (125)
+ UINT16 FormOrigin; // Original format ID:
+ // 1-MOD, 2-MTM, 3-S3M, 4-669, 5-FAR, 6-ULT, 7-STM, 8-MED
+ // (versions of 2GDM prior to v1.15 won't set this correctly)
+
+ UINT32 OrdOffset;
+ BYTE NOO; // Number of orders in module - 1
+ UINT32 PatOffset;
+ BYTE NOP; // Number of patterns in module - 1
+ UINT32 SamHeadOffset;
+ UINT32 SamOffset;
+ BYTE NOS; // Number of samples in module - 1
+ UINT32 MTOffset; // Offset of song message
+ UINT32 MTLength;
+ UINT32 SSOffset; // Offset of scrolly script (huh?)
+ UINT16 SSLength;
+ UINT32 TGOffset; // Offset of text graphic (huh?)
+ UINT16 TGLength;
+} GDMHEADER, *PGDMHEADER;
+
+typedef struct _GDMSAMPLEHEADER
+{
+ CHAR SamName[32];
+ CHAR FileName[12];
+ BYTE EmsHandle; // useless
+ UINT32 Length;
+ UINT32 LoopBegin;
+ UINT32 LoopEnd;
+ BYTE Flags;
+ UINT16 C4Hertz;
+ BYTE Volume;
+ BYTE Pan;
+} GDMSAMPLEHEADER, *PGDMSAMPLEHEADER;
+
+BOOL CSoundFile::ReadGDM(const LPCBYTE lpStream, const DWORD dwMemLength)
+//-----------------------------------------------------------
+{
+ if ((!lpStream) || (dwMemLength < sizeof(GDMHEADER))) return FALSE;
+
+ const PGDMHEADER pHeader = (PGDMHEADER)lpStream;
+
+ // is it a valid GDM file?
+ if( (LittleEndian(pHeader->ID) != 0xFE4D4447) || //GDM\xFE
+ (pHeader->DOSEOF[0] != 13 || pHeader->DOSEOF[1] != 10 || pHeader->DOSEOF[2] != 26) || //CR+LF+EOF
+ (LittleEndian(pHeader->ID2) != 0x53464D47)) return FALSE; //GMFS
+
+ // song name
+ memset(m_szNames, 0, sizeof(m_szNames));
+ memcpy(m_szNames[0], pHeader->SongTitle, 32);
+ SetNullTerminator(m_szNames[0]);
+
+ // there are no other format versions...
+ if(pHeader->FormMajorVer != 1 || pHeader->FormMinorVer != 0)
+ {
+ ::MessageBox(0, TEXT("GDM file seems to be valid, but this format version is currently not supported."), TEXT("OpenMPT GDM import"), MB_ICONERROR);
+ return FALSE;
+ }
+
+ // todo: Is TrackID, TrackMajorVer, TrackMinorVer relevant? The only TrackID should be 0 - 2GDM.exe
+
+ // read channel pan map... 0...15 = channel panning, 16 = surround channel, 255 = channel does not exist
+ m_nChannels = 32;
+ for(int i = 0; i < 32; i++)
+ {
+ if(pHeader->PanMap[i] < 16)
+ {
+ ChnSettings[i].nPan = min((pHeader->PanMap[i] << 4) + 8, 256);
+ }
+ else if(pHeader->PanMap[i] == 16)
+ {
+ ChnSettings[i].nPan = 128;
+ ChnSettings[i].dwFlags |= CHN_SURROUND;
+ }
+ else if(pHeader->PanMap[i] == 0xff)
+ {
+ m_nChannels = i;
+ break;
+ }
+ }
+
+ m_nDefaultGlobalVolume = min(pHeader->MastVol << 2, 256);
+ m_nDefaultSpeed = pHeader->Tempo;
+ m_nDefaultTempo = pHeader->BPM;
+ m_nRestartPos = 0; // not supported in this format, so use the default value
+ m_nSamplePreAmp = 48; // dito
+ m_nVSTiVolume = 48; // dito
+
+ // 1-MOD, 2-MTM, 3-S3M, 4-669, 5-FAR, 6-ULT, 7-STM, 8-MED
+
+ switch(pHeader->FormOrigin)
+ {
+ case 1:
+ m_nType = MOD_TYPE_MOD;
+ break;
+ case 2:
+ m_nType = MOD_TYPE_MTM;
+ break;
+ case 3:
+ m_nType = MOD_TYPE_S3M;
+ break;
+ case 4:
+ m_nType = MOD_TYPE_669;
+ break;
+ case 5:
+ m_nType = MOD_TYPE_FAR;
+ break;
+ case 6:
+ m_nType = MOD_TYPE_ULT;
+ break;
+ case 7:
+ m_nType = MOD_TYPE_STM;
+ break;
+ case 8:
+ m_nType = MOD_TYPE_MED;
+ break;
+ default:
+ ::MessageBox(0, TEXT("GDM file seems to be valid, but the original format is currently not supported.\nThis should not happen."), TEXT("OpenMPT GDM import"), MB_ICONERROR);
+ return FALSE;
+ break;
+ }
+
+ // check if offsets are valid. we won't read the scrolly text or text graphics, but invalid pointers would probably indicate a broken file...
+ if( dwMemLength < pHeader->OrdOffset || dwMemLength - pHeader->OrdOffset < pHeader->NOO
+ || dwMemLength < pHeader->PatOffset
+ || dwMemLength < pHeader->SamHeadOffset || dwMemLength - pHeader->SamHeadOffset < (pHeader->NOS + 1) * sizeof(GDMSAMPLEHEADER)
+ || dwMemLength < pHeader->SamOffset
+ || dwMemLength < pHeader->MTOffset || dwMemLength - pHeader->MTOffset < pHeader->MTLength
+ || dwMemLength < pHeader->SSOffset || dwMemLength - pHeader->SSOffset < pHeader->SSLength
+ || dwMemLength < pHeader->TGOffset || dwMemLength - pHeader->TGOffset < pHeader->TGLength)
+ return FALSE;
+
+ // read orders
+ Order.ReadAsByte(lpStream + pHeader->OrdOffset, pHeader->NOO + 1, dwMemLength - pHeader->OrdOffset);
+
+ // read samples
+ m_nSamples = pHeader->NOS + 1;
+
+ DWORD iSampleOffset = pHeader->SamOffset;
+ int iLZWsamples = 0;
+
+ for(UINT iSmp = 1; iSmp <= m_nSamples; iSmp++)
+ {
+ const PGDMSAMPLEHEADER pSample = (PGDMSAMPLEHEADER)(lpStream + pHeader->SamHeadOffset + (iSmp - 1) * sizeof(GDMSAMPLEHEADER));
+
+ // sample header
+
+ memcpy(m_szNames[iSmp], pSample->SamName, 32);
+ SetNullTerminator(m_szNames[iSmp]);
+ memcpy(Ins[iSmp].name, pSample->FileName, 12);
+
+ Ins[iSmp].nC4Speed = pSample->C4Hertz;
+ Ins[iSmp].nGlobalVol = 256; // not supported in this format
+ Ins[iSmp].nLength = min(pSample->Length, MAX_SAMPLE_LENGTH); // in bytes
+ Ins[iSmp].nLoopStart = min(pSample->LoopBegin, Ins[iSmp].nLength); // in samples
+ Ins[iSmp].nLoopEnd = min(pSample->LoopEnd - 1, Ins[iSmp].nLength); // dito
+ FrequencyToTranspose(&Ins[iSmp]); // set transpose + finetune for mod files
+
+ if(pSample->Flags & 0x01) Ins[iSmp].uFlags |= CHN_LOOP; // loop sample
+
+ if(pSample->Flags & 0x04)
+ {
+ Ins[iSmp].nVolume = min(pSample->Volume << 2, 256); // 0...64, 255 = no default volume
+ }
+ else
+ {
+ Ins[iSmp].nVolume = 256; // default volume
+ }
+
+ if(pSample->Flags & 0x08) // default panning is used
+ {
+ Ins[iSmp].uFlags |= CHN_PANNING;
+ Ins[iSmp].nPan = (pSample->Pan > 15) ? 128 : min((pSample->Pan << 4) + 8, 256); // 0...15, 16 = surround (not supported), 255 = no default panning
+ }
+ else
+ {
+ Ins[iSmp].nPan = 128;
+ }
+
+ /* note: apparently (and according to zilym), 2GDM doesn't handle 16 bit or stereo samples properly.
+ so those flags are pretty much meaningless and we will ignore them... in fact, samples won't load as expected if we don't! */
+
+ UINT iSampleFormat;
+ if(pSample->Flags & 0x02) // 16 bit
+ {
+ if(pSample->Flags & 0x20) // stereo
+ {
+ iSampleFormat = RS_PCM16U; // should be RS_STPCM16U but that breaks the sample reader
+ }
+ else
+ {
+ iSampleFormat = RS_PCM16U;
+ }
+ }
+ else // 8 bit
+ {
+ if(pSample->Flags & 0x20) // stereo
+ {
+ iSampleFormat = RS_PCM8U; // should be RS_STPCM8U - dito
+ }
+ else
+ {
+ iSampleFormat = RS_PCM8U;
+ }
+ }
+
+ // according to zilym, LZW support has never been finished, so this is also practically useless.
+ if(pSample->Flags & 0x10)
+ iLZWsamples++;
+
+ // read sample data
+ ReadSample(&Ins[iSmp], iSampleFormat, reinterpret_cast<LPCSTR>(lpStream + iSampleOffset), dwMemLength - iSampleOffset);
+ iSampleOffset += min(pSample->Length, dwMemLength - iSampleOffset);
+
+ }
+
+ // read patterns
+ Patterns.ResizeArray(max(MAX_PATTERNS, pHeader->NOP + 1));
+
+ // position in file
+ DWORD iPatternsOffset = pHeader->PatOffset;
+
+ BOOL bS3MCommandSet = (GetBestSaveFormat() & (MOD_TYPE_S3M | MOD_TYPE_IT | MOD_TYPE_MPT));
+
+ for (PATTERNINDEX iPat = 0; iPat < pHeader->NOP + 1; iPat++)
+ {
+
+ if(iPatternsOffset + 2 > dwMemLength) break;
+ UINT16 iPatternLength = *(UINT16 *)(lpStream + iPatternsOffset); // pattern length including the two "length" bytes
+ if(iPatternLength > dwMemLength || iPatternsOffset > dwMemLength - iPatternLength) break;
+
+ if(Patterns.Insert(iPat, 64))
+ {
+ CString s;
+ s.Format(TEXT("Allocating patterns failed starting from pattern %u"), iPat);
+ MessageBox(NULL, s, TEXT("OpenMPT GDM import"), MB_ICONERROR);
+ break;
+ }
+
+ // position in THIS pattern
+ DWORD iPatternPos = iPatternsOffset + 2;
+
+ MODCOMMAND *p = Patterns[iPat];
+
+ for(UINT iRow = 0; iRow < 64; iRow++)
+ {
+ do // zero byte = next row
+ {
+ if(iPatternPos + 1 > dwMemLength) break;
+
+ BYTE bChannel = lpStream[iPatternPos++];
+
+ if(bChannel == 0) break; // next row, please!
+
+ UINT channel = bChannel & 0x1f;
+ if(channel >= m_nChannels) break; // better safe than sorry!
+
+ MODCOMMAND *m = &p[iRow * m_nChannels + channel];
+
+ if(bChannel & 0x20)
+ {
+ // note and sample follows
+ if(iPatternPos + 2 > dwMemLength) break;
+ BYTE bNote = lpStream[iPatternPos++];
+ BYTE bSample = lpStream[iPatternPos++];
+
+ bNote = (bNote & 0x7F) - 1; // this format doesn't have note cuts
+ if(bNote < 0xF0) bNote = (bNote & 0x0F) + 12 * (bNote >> 4) + 13;
+ if(bNote == 0xFF) bNote = 0;
+ m->note = bNote;
+ m->instr = bSample;
+
+ }
+
+ if(bChannel & 0x40)
+ {
+ // effect(s) follow
+
+ m->command = CMD_NONE;
+ m->volcmd = CMD_NONE;
+
+ do
+ {
+ if(iPatternPos + 2 > dwMemLength) break;
+ BYTE bEffect = lpStream[iPatternPos++];
+ BYTE bEffectData = lpStream[iPatternPos++];
+
+ BYTE command = bEffect & 0x1F, param = bEffectData;
+ BYTE volcommand = CMD_NONE, volparam = param;
+
+ switch(command)
+ {
+ case 0x01: command = CMD_PORTAMENTOUP; if(param >= 0xE0) param = 0xDF; break;
+ case 0x02: command = CMD_PORTAMENTODOWN; if(param >= 0xE0) param = 0xDF; break;
+ case 0x03: command = CMD_TONEPORTAMENTO; break;
+ case 0x04: command = CMD_VIBRATO; break;
+ case 0x05: command = CMD_TONEPORTAVOL; if (param & 0xF0) param &= 0xF0; break;
+ case 0x06: command = CMD_VIBRATOVOL; if (param & 0xF0) param &= 0xF0; break;
+ case 0x07: command = CMD_TREMOLO; break;
+ case 0x08: command = CMD_TREMOR; break;
+ case 0x09: command = CMD_OFFSET; break;
+ case 0x0A: command = CMD_VOLUMESLIDE; break;
+ case 0x0B: command = CMD_POSITIONJUMP; break;
+ case 0x0C:
+ if(bS3MCommandSet)
+ {
+ command = CMD_NONE;
+ volcommand = VOLCMD_VOLUME;
+ volparam = min(param, 64);
+ }
+ else
+ {
+ command = CMD_VOLUME;
+ param = min(param, 64);
+ }
+ break;
+ case 0x0D: command = CMD_PATTERNBREAK; break;
+ case 0x0E:
+ if(bS3MCommandSet)
+ {
+ command = CMD_S3MCMDEX;
+ // need to do some remapping
+ switch(param >> 4)
+ {
+ case 0x0:
+ // set filter
+ command = CMD_MODCMDEX;
+ break;
+ case 0x1:
+ // fine porta up
+ command = CMD_PORTAMENTOUP;
+ param = 0xF0 | (param & 0x0F);
+ break;
+ case 0x2:
+ // fine porta down
+ command = CMD_PORTAMENTODOWN;
+ param = 0xF0 | (param & 0x0F);
+ break;
+ case 0x3:
+ // glissando control
+ param = 0x10 | (param & 0x0F);
+ break;
+ case 0x4:
+ // vibrato waveform
+ param = 0x30 | (param & 0x0F);
+ break;
+ case 0x5:
+ // set finetune
+ param = 0x20 | (param & 0x0F);
+ break;
+ case 0x6:
+ // pattern loop
+ param = 0xB0 | (param & 0x0F);
+ break;
+ case 0x7:
+ // tremolo waveform
+ param = 0x40 | (param & 0x0F);
+ break;
+ case 0x8:
+ // extra fine porta up
+ command = CMD_PORTAMENTOUP;
+ param = 0xE0 | (param & 0x0F);
+ break;
+ case 0x9:
+ // extra fine porta down
+ command = CMD_PORTAMENTODOWN;
+ param = 0xE0 | (param & 0x0F);
+ break;
+ case 0xA:
+ // fine volume up
+ command = CMD_VOLUMESLIDE;
+ param = ((param & 0x0F) << 4) | 0x0F;
+ break;
+ case 0xB:
+ // fine volume down
+ command = CMD_VOLUMESLIDE;
+ param = 0xF0 | (param & 0x0F);
+ break;
+ case 0xC:
+ // note cut
+ break;
+ case 0xD:
+ // note delay
+ break;
+ case 0xE:
+ // pattern delay
+ break;
+ case 0xF:
+ command = CMD_MODCMDEX;
+ // invert loop / funk repeat
+ break;
+ }
+ }
+ else
+ {
+ command = CMD_MODCMDEX;
+ }
+ break;
+ case 0x0F: command = CMD_SPEED; break;
+ case 0x10: command = CMD_ARPEGGIO; break;
+ case 0x11: command = CMD_NONE /* set internal flag */; break;
+ case 0x12:
+ if((!bS3MCommandSet) && ((param & 0xF0) == 0))
+ {
+ // retrig in "mod style"
+ command = CMD_MODCMDEX;
+ param = 0x90 | (param & 0x0F);
+ }
+ else
+ {
+ // either "s3m style" is required or this format is like s3m anyway
+ command = CMD_RETRIG;
+ }
+ break;
+ case 0x13: command = CMD_GLOBALVOLUME; break;
+ case 0x14: command = CMD_FINEVIBRATO; break;
+ case 0x1E:
+ switch(param >> 4)
+ {
+ case 0x0:
+ switch(param & 0x0F)
+ {
+ case 0x0: command = CMD_S3MCMDEX; param = 0x90; break;
+ case 0x1: command = CMD_PANNING8; param = 0xA4; break;
+ case 0x2: command = CMD_NONE /* set normal loop - not implemented in 2GDM */; break;
+ case 0x3: command = CMD_NONE /* set bidi loop - dito */; break;
+ case 0x4: command = CMD_S3MCMDEX; param = 0x9E; break;
+ case 0x5: command = CMD_S3MCMDEX; param = 0x9F; break;
+ case 0x6: command = CMD_NONE /* monaural sample - dito */; break;
+ case 0x7: command = CMD_NONE /* stereo sample - dito */; break;
+ case 0x8: command = CMD_NONE /* stop sample on end - dito */; break;
+ case 0x9: command = CMD_NONE /* loop sample on end - dito */; break;
+ default: command = CMD_NONE; break;
+ }
+ break;
+ case 0x8:
+ command = (bS3MCommandSet) ? CMD_S3MCMDEX : CMD_MODCMDEX;
+ break;
+ case 0xD:
+ // adjust frequency (increment in hz) - not implemented in 2GDM
+ command = CMD_NONE;
+ break;
+ default: command = CMD_NONE; break;
+ }
+ break;
+ case 0x1F: command = CMD_TEMPO; break;
+ default: command = CMD_NONE; break;
+ }
+
+ if(command != CMD_NONE)
+ {
+ // move pannings to volume column - should never happen
+ if(m->command == CMD_S3MCMDEX && ((m->param >> 4) == 0x8) && volcommand == CMD_NONE)
+ {
+ volcommand = VOLCMD_PANNING;
+ volparam = ((param & 0x0F) << 2) + 2;
+ }
+
+ m->command = command;
+ m->param = param;
+ }
+ if(volcommand != CMD_NONE)
+ {
+ m->volcmd = volcommand;
+ m->vol = volparam;
+ }
+
+ if(!(bEffect & 0x20)) break; // no other effect follows
+ } while(1);
+
+ }
+
+ } while(1);
+ }
+
+ iPatternsOffset += iPatternLength;
+ }
+
+ // read song comments
+ if(pHeader->MTLength)
+ {
+ m_lpszSongComments = new char[pHeader->MTLength + 1];
+ if (m_lpszSongComments)
+ {
+ memset(m_lpszSongComments, 0, pHeader->MTLength + 1);
+ memcpy(m_lpszSongComments, lpStream + pHeader->MTOffset, pHeader->MTLength);
+ }
+ }
+
+ if(iLZWsamples)
+ {
+ TCHAR s[128];
+ wsprintf(s, TEXT("%d samples are LZW compressed. LZW compression is currently not supported.\nPlease send this file to the OpenMPT team."), iLZWsamples);
+ ::MessageBox(0, s, TEXT("OpenMPT GDM import"), MB_ICONWARNING);
+ }
+
+ return TRUE;
+
+}
Modified: trunk/OpenMPT/soundlib/Sndfile.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-06-17 18:44:27 UTC (rev 272)
+++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-06-23 19:38:41 UTC (rev 273)
@@ -593,6 +593,7 @@
#endif
#endif // MODPLUG_BASIC_SUPPORT
&& (!ReadMO3(lpStream, dwMemLength))
+ && (!ReadGDM(lpStream, dwMemLength))
&& (!ReadMod(lpStream, dwMemLength))) m_nType = MOD_TYPE_NONE;
#ifdef ZIPPED_MOD_SUPPORT
if ((!m_lpszSongComments) && (archive.GetComments(FALSE)))
Modified: trunk/OpenMPT/soundlib/Sndfile.h
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.h 2009-06-17 18:44:27 UTC (rev 272)
+++ trunk/OpenMPT/soundlib/Sndfile.h 2009-06-23 19:38:41 UTC (rev 273)
@@ -1068,6 +1068,7 @@
BOOL ReadJ2B(LPCBYTE lpStream, DWORD dwMemLength);
BOOL ReadUMX(LPCBYTE lpStream, DWORD dwMemLength);
BOOL ReadMO3(LPCBYTE lpStream, const DWORD dwMemLength);
+ BOOL ReadGDM(const LPCBYTE lpStream, const DWORD dwMemLength);
BOOL ReadMID(LPCBYTE lpStream, DWORD dwMemLength);
// Save Functions
#ifndef MODPLUG_NO_FILESAVE
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2009-06-17 18:45:13
|
Revision: 272
http://modplug.svn.sourceforge.net/modplug/?rev=272&view=rev
Author: relabsoluness
Date: 2009-06-17 18:44:27 +0000 (Wed, 17 Jun 2009)
Log Message:
-----------
? Misc: Fixed a merge bug from last commit.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/mptrack.rc
Modified: trunk/OpenMPT/mptrack/mptrack.rc
===================================================================
--- trunk/OpenMPT/mptrack/mptrack.rc 2009-06-17 17:50:41 UTC (rev 271)
+++ trunk/OpenMPT/mptrack/mptrack.rc 2009-06-17 18:44:27 UTC (rev 272)
@@ -146,7 +146,7 @@
MENUITEM "Cleanup S&ong", ID_CLEANUP_SONG
MENUITEM "Remove &All Instruments", ID_INSTRUMENTS_REMOVEALL
MENUITEM "Cleanup &Plugins", ID_CLEANUP_PLUGS
- MENUITEM "Co&mpo Cleanup", ID_CLEANUP_COMPO
+ MENUITEM "Co&mpo Cleanup", ID_CLEANUP_COMPO
END
MENUITEM SEPARATOR
MENUITEM "&Find\tCtrl+F", ID_EDIT_FIND
@@ -2051,7 +2051,6 @@
BOTTOMMARGIN, 104
END
- ID_CLEANUP_COMPO "Reset attributes to defaults (useful for creating sample packs)\Compo Cleanup"
IDD_CONTROL_INSTRUMENTS, DIALOG
BEGIN
RIGHTMARGIN, 522
@@ -2500,6 +2499,7 @@
ID_PATTERN_PLAYROW "Play current row\nPlay Row"
ID_IMPORT_MIDILIB "Defines the default MIDI library used when importing MIDI files"
ID_CLEANUP_REARRANGE "Rearrange all patterns so that they are sorted in the order list\nRearrange Patterns"
+ ID_CLEANUP_COMPO "Reset attributes to defaults (useful for creating sample packs)\nCompo Cleanup"
END
STRINGTABLE
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2009-06-17 17:51:19
|
Revision: 271
http://modplug.svn.sourceforge.net/modplug/?rev=271&view=rev
Author: relabsoluness
Date: 2009-06-17 17:50:41 +0000 (Wed, 17 Jun 2009)
Log Message:
-----------
(Patches from Jojo, merged somewhat modified with related refactoring)
. General tab: Document will now be set modified when moving or inserting plugins.
+ Pattern tab: Added description to high offset command in note properties dialog.
+ Pattern tab: Paste will now optionally continue on next pattern (echo paste).
+ Sample tab: Can now play sample from given position with Ctrl + left mouse button.
+ Misc: Compo cleanup
/ Misc: Updated project file.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/CommandSet.cpp
trunk/OpenMPT/mptrack/CommandSet.h
trunk/OpenMPT/mptrack/Ctrl_seq.cpp
trunk/OpenMPT/mptrack/MainFrm.cpp
trunk/OpenMPT/mptrack/Mainfrm.h
trunk/OpenMPT/mptrack/Moddoc.cpp
trunk/OpenMPT/mptrack/Moddoc.h
trunk/OpenMPT/mptrack/Modedit.cpp
trunk/OpenMPT/mptrack/Moptions.cpp
trunk/OpenMPT/mptrack/OrderToPatternTable.cpp
trunk/OpenMPT/mptrack/OrderToPatternTable.h
trunk/OpenMPT/mptrack/View_gen.cpp
trunk/OpenMPT/mptrack/View_pat.cpp
trunk/OpenMPT/mptrack/View_smp.cpp
trunk/OpenMPT/mptrack/View_smp.h
trunk/OpenMPT/mptrack/mptrack.rc
trunk/OpenMPT/mptrack/mptrack.vcproj
trunk/OpenMPT/mptrack/patternContainer.cpp
trunk/OpenMPT/mptrack/patternContainer.h
trunk/OpenMPT/mptrack/resource.h
trunk/OpenMPT/soundlib/Sndfile.h
trunk/OpenMPT/soundlib/modsmp_ctrl.cpp
trunk/OpenMPT/soundlib/modsmp_ctrl.h
Modified: trunk/OpenMPT/mptrack/CommandSet.cpp
===================================================================
--- trunk/OpenMPT/mptrack/CommandSet.cpp 2009-06-15 20:04:15 UTC (rev 270)
+++ trunk/OpenMPT/mptrack/CommandSet.cpp 2009-06-17 17:50:41 UTC (rev 271)
@@ -2304,6 +2304,11 @@
commands[kcChannelReset].isDummy = false;
commands[kcChannelReset].Message = "Reset channel";
+ commands[kcSwitchEchoPaste].UID = 1787;
+ commands[kcSwitchEchoPaste].Message = "Switch echo paste";
+ commands[kcSwitchEchoPaste].isHidden = false;
+ commands[kcSwitchEchoPaste].isDummy = false;
+
#ifdef _DEBUG
for (int i=0; i<kcNumCommands; i++) {
if (commands[i].UID != 0) { // ignore unset UIDs
Modified: trunk/OpenMPT/mptrack/CommandSet.h
===================================================================
--- trunk/OpenMPT/mptrack/CommandSet.h 2009-06-15 20:04:15 UTC (rev 270)
+++ trunk/OpenMPT/mptrack/CommandSet.h 2009-06-17 17:50:41 UTC (rev 271)
@@ -84,6 +84,7 @@
kcEditPaste,
kcEditMixPaste,
kcEditMixPasteITStyle,
+ kcSwitchEchoPaste,
kcEditSelectAll,
kcEditFind,
kcEditFindNext,
Modified: trunk/OpenMPT/mptrack/Ctrl_seq.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2009-06-15 20:04:15 UTC (rev 270)
+++ trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2009-06-17 17:50:41 UTC (rev 271)
@@ -247,6 +247,7 @@
END_CRITICAL();
}
m_pParent->SetCurrentPattern(n);
+ m_pModDoc->SetElapsedTime(static_cast<ORDERINDEX>(m_nScrollPos), 0);
}
}
UpdateInfoText();
Modified: trunk/OpenMPT/mptrack/MainFrm.cpp
===================================================================
--- trunk/OpenMPT/mptrack/MainFrm.cpp 2009-06-15 20:04:15 UTC (rev 270)
+++ trunk/OpenMPT/mptrack/MainFrm.cpp 2009-06-17 17:50:41 UTC (rev 271)
@@ -166,7 +166,7 @@
int CMainFrame::gnPlugWindowHeight = 332;
DWORD CMainFrame::gnPlugWindowLast = 0;
-uint32 CMainFrame::gnMsgBoxVisiblityFlags = ~0;
+uint32 CMainFrame::gnMsgBoxVisiblityFlags = uint32_max;
CRITICAL_SECTION CMainFrame::m_csAudio;
HANDLE CMainFrame::m_hPlayThread = NULL;
@@ -393,7 +393,7 @@
gnPlugWindowWidth = GetPrivateProfileInt("Display", "PlugSelectWindowWidth", 370, iniFile);
gnPlugWindowHeight = GetPrivateProfileInt("Display", "PlugSelectWindowHeight", 332, iniFile);
gnPlugWindowLast = GetPrivateProfileDWord("Display", "PlugSelectWindowLast", 0, iniFile);
- gnMsgBoxVisiblityFlags = GetPrivateProfileDWord("Display", "MsgBoxVisibilityFlags", ~0, iniFile);
+ gnMsgBoxVisiblityFlags = GetPrivateProfileDWord("Display", "MsgBoxVisibilityFlags", uint32_max, iniFile);
CHAR s[16];
for (int ncol=0; ncol<MAX_MODCOLORS; ncol++) {
Modified: trunk/OpenMPT/mptrack/Mainfrm.h
===================================================================
--- trunk/OpenMPT/mptrack/Mainfrm.h 2009-06-15 20:04:15 UTC (rev 270)
+++ trunk/OpenMPT/mptrack/Mainfrm.h 2009-06-17 17:50:41 UTC (rev 271)
@@ -207,6 +207,8 @@
#define PATTERN_SYNCMUTE 0x1000000
#define PATTERN_AUTODELAY 0x2000000
#define PATTERN_NOTEFADE 0x4000000
+#define PATTERN_ECHOPASTE 0x8000000
+#define PATTERN_POSITIONAWARETIMER 0x10000000
// Keyboard Setup
@@ -552,6 +554,7 @@
inline BOOL IsRendering() const { return (m_dwStatus & MODSTATUS_RENDERING); } //rewbs.VSTTimeInfo
DWORD GetElapsedTime() const { return m_dwElapsedTime; }
void ResetElapsedTime() { m_dwElapsedTime = 0; }
+ void SetElapsedTime(DWORD dwElapsedTime) { m_dwElapsedTime = dwElapsedTime; }
inline CModDoc *GetModPlaying() const { return (IsPlaying()||IsRendering()) ? m_pModPlaying : NULL; }
inline CSoundFile *GetSoundFilePlaying() const { return (IsPlaying()||IsRendering()) ? m_pSndFile : NULL; } //rewbs.VSTTimeInfo
BOOL InitRenderer(CSoundFile*); //rewbs.VSTTimeInfo
Modified: trunk/OpenMPT/mptrack/Moddoc.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-06-15 20:04:15 UTC (rev 270)
+++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-06-17 17:50:41 UTC (rev 271)
@@ -57,6 +57,7 @@
ON_COMMAND(ID_CLEANUP_PATTERNS, OnCleanupPatterns)
ON_COMMAND(ID_CLEANUP_SONG, OnCleanupSong)
ON_COMMAND(ID_CLEANUP_REARRANGE, OnRearrangePatterns)
+ ON_COMMAND(ID_CLEANUP_COMPO, OnCompoCleanup)
ON_COMMAND(ID_INSTRUMENTS_REMOVEALL,OnRemoveAllInstruments)
// -> CODE#0020
// -> DESC="rearrange sample list"
@@ -764,7 +765,7 @@
return IDCANCEL;
}
-UINT CModDoc::PlayNote(UINT note, UINT nins, UINT nsmp, BOOL bpause, LONG nVol, LONG loopstart, LONG loopend, int nCurrentChn) //rewbs.vstiLive: added current chan param
+UINT CModDoc::PlayNote(UINT note, UINT nins, UINT nsmp, BOOL bpause, LONG nVol, LONG loopstart, LONG loopend, int nCurrentChn, const uint32 nStartPos) //rewbs.vstiLive: added current chan param
//-----------------------------------------------------------------------------------------------------------
{
CMainFrame *pMainFrm = CMainFrame::GetMainFrame();
@@ -860,6 +861,16 @@
pChn->dwFlags &= ~CHN_EXTRALOUD;
}
+ // Handle custom start position
+ if(nStartPos != uint32_max && pChn->pInstrument)
+ {
+ pChn->nPos = nStartPos;
+ // If start position is after loop end, set loop end to sample end so that the sample starts
+ // playing.
+ if(pChn->nLoopEnd < nStartPos)
+ pChn->nLength = pChn->nLoopEnd = pChn->pInstrument->nLength;
+ }
+
/*
if (bpause) {
if ((loopstart + 16 < loopend) && (loopstart >= 0) && (loopend <= (LONG)pChn->nLength)) {
@@ -1882,7 +1893,15 @@
ShowLog("Pattern Rearrange", CMainFrame::GetMainFrame());
}
+void CModDoc::OnCompoCleanup()
+//------------------------------
+{
+ CompoCleanup();
+ UpdateAllViews(NULL, HINT_MODTYPE);
+}
+
+
void CModDoc::OnUpdateInstrumentOnly(CCmdUI *p)
//---------------------------------------------
{
@@ -1951,25 +1970,7 @@
void CModDoc::OnRemoveAllInstruments()
//------------------------------------
{
- if (!m_SndFile.m_nInstruments) return;
- if (CMainFrame::GetMainFrame()->MessageBox("This will remove all the instruments in the song,\n"
- "Do you want to continue?", "Warning", MB_YESNO | MB_ICONQUESTION) != IDYES) return;
- if (CMainFrame::GetMainFrame()->MessageBox("Do you want to convert all instruments to samples ?\n",
- NULL, MB_YESNO | MB_ICONQUESTION) == IDYES)
- {
- ConvertInstrumentsToSamples();
- }
- char removeSamples = -1;
- if (::MessageBox(NULL, "Remove samples associated with an instrument if they are unused?", "Removing instrument", MB_YESNO | MB_ICONQUESTION) == IDYES) {
- removeSamples = 1;
- }
-
- for (UINT i=1; i<=m_SndFile.m_nInstruments; i++) {
- m_SndFile.DestroyInstrument(i,removeSamples);
- }
- m_SndFile.m_nInstruments = 0;
- SetModified();
- UpdateAllViews(NULL, HINT_MODTYPE);
+ RemoveAllInstruments();
}
@@ -2651,6 +2652,11 @@
}
break;
case 0x60: if (gFXInfo[ndx].dwEffect == CMD_MODCMDEX) break;
+
+ case 0xA0:
+ wsprintf(s, "+ %u samples", 0x10000 * (param & 0x0F));
+ break;
+
case 0xB0:
if (gFXInfo[ndx].dwEffect == CMD_S3MCMDEX)
{
@@ -2949,8 +2955,11 @@
//end rewbs.vstCompliance
END_CRITICAL();
- pMainFrm->ResetElapsedTime();
- if (pModPlaying != this) {
+ // set playback timer in the status bar
+ SetElapsedTime(static_cast<ORDERINDEX>(nOrd), nRow, true);
+
+ if (pModPlaying != this)
+ {
pMainFrm->PlayMod(this, followSonghWnd, m_dwNotifyType|MPTNOTIFY_POSITION|MPTNOTIFY_VUMETERS); //rewbs.fix2977
}
}
@@ -2997,7 +3006,9 @@
//end rewbs.VSTCompliance
END_CRITICAL();
- pMainFrm->ResetElapsedTime();
+ // set playback timer in the status bar
+ SetElapsedTime(static_cast<ORDERINDEX>(nOrd), nRow, true);
+
if (pModPlaying != this) {
pMainFrm->PlayMod(this, followSonghWnd, m_dwNotifyType|MPTNOTIFY_POSITION|MPTNOTIFY_VUMETERS); //rewbs.fix2977
}
@@ -3049,7 +3060,8 @@
//rewbs.VSTCompliance
END_CRITICAL();
- pMainFrm->ResetElapsedTime();
+ // set playback timer in the status bar
+ SetElapsedTime(static_cast<ORDERINDEX>(nOrd), nRow, true);
if (pModPlaying != this) {
pMainFrm->PlayMod(this, followSonghWnd, m_dwNotifyType|MPTNOTIFY_POSITION|MPTNOTIFY_VUMETERS); //rewbs.fix2977
@@ -3262,3 +3274,22 @@
}
}
+
+// Sets playback timer to playback time at given position. If 'bReset' is true,
+// timer is reset if playback position timer is not enabled.
+void CModDoc::SetElapsedTime(ORDERINDEX nOrd, ROWINDEX nRow, bool bReset)
+//-----------------------------------------------------------------------
+{
+ CMainFrame *pMainFrm = CMainFrame::GetMainFrame();
+ if(pMainFrm == NULL)
+ return;
+
+ if(CMainFrame::m_dwPatternSetup & PATTERN_POSITIONAWARETIMER)
+ {
+ double dPatternPlaytime = max(0, m_SndFile.GetPlaybackTimeAt(nOrd, nRow));
+ pMainFrm->SetElapsedTime((DWORD) (dPatternPlaytime * 1000));
+ }
+ else if(bReset)
+ pMainFrm->ResetElapsedTime();
+}
+
Modified: trunk/OpenMPT/mptrack/Moddoc.h
===================================================================
--- trunk/OpenMPT/mptrack/Moddoc.h 2009-06-15 20:04:15 UTC (rev 270)
+++ trunk/OpenMPT/mptrack/Moddoc.h 2009-06-17 17:50:41 UTC (rev 271)
@@ -186,8 +186,11 @@
BOOL ConvertInstrumentsToSamples();;
BOOL RemoveUnusedSamples();
BOOL RemoveUnusedInstruments();
+ void RemoveAllInstruments(bool bConfirm = true);
BOOL RemoveUnusedPlugs();
+ UINT RemovePlugs(const bool (&keepMask)[MAX_MIXPLUGINS]);
BOOL RemoveUnusedPatterns(BOOL bRemove=TRUE);
+ BOOL CompoCleanup();
LONG InsertPattern(LONG nOrd=-1, UINT nRows=64);
LONG InsertSample(BOOL bLimit=FALSE);
LONG InsertInstrument(LONG lSample=0, LONG lDuplicate=0);
@@ -196,7 +199,7 @@
BOOL RemovePattern(UINT n);
BOOL RemoveSample(UINT n);
BOOL RemoveInstrument(UINT n);
- UINT PlayNote(UINT note, UINT nins, UINT nsmp, BOOL bpause, LONG nVol=-1, LONG loopstart=0, LONG loopend=0, int nCurrentChn=-1); //rewbs.vstiLive: added current chan param
+ UINT PlayNote(UINT note, UINT nins, UINT nsmp, BOOL bpause, LONG nVol=-1, LONG loopstart=0, LONG loopend=0, int nCurrentChn=-1, const uint32 nStartPos = uint32_max); //rewbs.vstiLive: added current chan param
BOOL NoteOff(UINT note, BOOL bFade=FALSE, UINT nins=-1, UINT nCurrentChn=-1); //rewbs.vstiLive: add params
// -> CODE#0020
@@ -255,6 +258,7 @@
void TogglePluginEditor(UINT m_nCurrentPlugin); //rewbs.patPlugNames
void RecordParamChange(int slot, long param);
void LearnMacro(int macro, long param);
+ void SetElapsedTime(ORDERINDEX nOrd, ROWINDEX nRow, bool bReset = false);
BOOL RemoveChannels(BOOL bChnMask[MAX_CHANNELS]);
@@ -325,6 +329,7 @@
afx_msg void OnCleanupPatterns();
afx_msg void OnCleanupSong();
afx_msg void OnRearrangePatterns();
+ afx_msg void OnCompoCleanup();
afx_msg void OnRemoveAllInstruments();
afx_msg void OnEstimateSongLength();
afx_msg void OnApproximateBPM();
Modified: trunk/OpenMPT/mptrack/Modedit.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Modedit.cpp 2009-06-15 20:04:15 UTC (rev 270)
+++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-06-17 17:50:41 UTC (rev 271)
@@ -809,13 +809,54 @@
return FALSE;
}
+
+UINT CModDoc::RemovePlugs(const bool (&keepMask)[MAX_MIXPLUGINS])
+//---------------------------------------------------------------
+{
+ //Remove all plugins whose keepMask[plugindex] is false.
+ UINT nRemoved=0;
+ for (PLUGINDEX nPlug=0; nPlug<MAX_MIXPLUGINS; nPlug++)
+ {
+ SNDMIXPLUGIN* pPlug = &m_SndFile.m_MixPlugins[nPlug];
+ if (keepMask[nPlug] || !pPlug)
+ {
+ Log("Keeping mixplug addess (%d): %X\n", nPlug, &(pPlug->pMixPlugin));
+ continue;
+ }
+
+ if (pPlug->pPluginData)
+ {
+ delete pPlug->pPluginData;
+ pPlug->pPluginData = NULL;
+ }
+ if (pPlug->pMixPlugin)
+ {
+ pPlug->pMixPlugin->Release();
+ pPlug->pMixPlugin=NULL;
+ }
+ if (pPlug->pMixState)
+ {
+ delete pPlug->pMixState;
+ }
+
+ memset(&(pPlug->Info), 0, sizeof(SNDMIXPLUGININFO));
+ Log("Zeroing range (%d) %X - %X\n", nPlug, &(pPlug->Info), &(pPlug->Info)+sizeof(SNDMIXPLUGININFO));
+ pPlug->nPluginDataSize=0;
+ pPlug->fDryRatio=0;
+ pPlug->defaultProgram=0;
+ nRemoved++;
+ }
+
+ return nRemoved;
+}
+
+
BOOL CModDoc::RemoveUnusedPlugs()
//-------------------------------
{
- BYTE usedmap[MAX_MIXPLUGINS];
- memset(usedmap, false, MAX_MIXPLUGINS);
+ bool usedmap[MAX_MIXPLUGINS];
+ memset(usedmap, false, sizeof(usedmap));
-
for (PLUGINDEX nPlug=0; nPlug < MAX_MIXPLUGINS; nPlug++) {
//Is the plugin assigned to a channel?
@@ -849,43 +890,49 @@
}
- //Remove unused plugins
- int nRemoved=0;
- for (int nPlug=0; nPlug<MAX_MIXPLUGINS; nPlug++) {
- SNDMIXPLUGIN* pPlug = &m_SndFile.m_MixPlugins[nPlug];
- if (usedmap[nPlug] || !pPlug) {
- Log("Keeping mixplug addess (%d): %X\n", nPlug, &(pPlug->pMixPlugin));
- continue;
- }
+ UINT nRemoved = RemovePlugs(usedmap);
- if (pPlug->pPluginData) {
- delete pPlug->pPluginData;
- pPlug->pPluginData = NULL;
+ if (nRemoved) {
+ SetModified();
+ }
+
+ return nRemoved;
+}
+
+
+void CModDoc::RemoveAllInstruments(bool bConfirm)
+//-----------------------------------------------
+{
+ if (!m_SndFile.m_nInstruments)
+ return;
+
+ char removeSamples = -1;
+ if(bConfirm)
+ {
+ if (CMainFrame::GetMainFrame()->MessageBox("This will remove all the instruments in the song,\n"
+ "Do you want to continue?", "Warning", MB_YESNO | MB_ICONQUESTION) != IDYES) return;
+ if (CMainFrame::GetMainFrame()->MessageBox("Do you want to convert all instruments to samples ?\n",
+ NULL, MB_YESNO | MB_ICONQUESTION) == IDYES)
+ {
+ ConvertInstrumentsToSamples();
}
- if (pPlug->pMixPlugin) {
- pPlug->pMixPlugin->Release();
- pPlug->pMixPlugin=NULL;
+
+ if (::MessageBox(NULL, "Remove samples associated with an instrument if they are unused?", "Removing instrument", MB_YESNO | MB_ICONQUESTION) == IDYES) {
+ removeSamples = 1;
}
- if (pPlug->pMixState) {
- delete pPlug->pMixState;
- }
-
- memset(&(pPlug->Info), 0, sizeof(SNDMIXPLUGININFO));
- Log("Zeroing range (%d) %X - %X\n", nPlug, &(pPlug->Info), &(pPlug->Info)+sizeof(SNDMIXPLUGININFO));
- pPlug->nPluginDataSize=0;
- pPlug->fDryRatio=0;
- pPlug->defaultProgram=0;
- nRemoved++;
-
}
- if (nRemoved) {
- SetModified();
+ for (UINT i=1; i<=m_SndFile.m_nInstruments; i++)
+ {
+ m_SndFile.DestroyInstrument(i,removeSamples);
}
- return nRemoved;
+ m_SndFile.m_nInstruments = 0;
+ SetModified();
+ UpdateAllViews(NULL, HINT_MODTYPE);
}
+
BOOL CModDoc::RemoveUnusedInstruments()
//-------------------------------------
{
@@ -931,7 +978,7 @@
}
EndWaitCursor();
if ((bReorg) && (m_SndFile.m_nInstruments > 1)
- && (::MessageBox(NULL, "Do you want to reorganize the remaining instruments ?", NULL, MB_YESNO | MB_ICONQUESTION) == IDYES))
+ && (::MessageBox(NULL, "Do you want to reorganize the remaining instruments?", "Instrument Cleanup", MB_YESNO | MB_ICONQUESTION) == IDYES))
{
BeginWaitCursor();
BEGIN_CRITICAL();
@@ -993,6 +1040,96 @@
}
+BOOL CModDoc::CompoCleanup()
+//--------------------------
+{
+ //jojo.compocleanup
+ if(::MessageBox(NULL, TEXT("WARNING: Compo cleanup will convert module to IT format, remove all patterns and reset song, sample and instrument attributes to default values. Continue?"), TEXT("Compo Cleanup"), MB_YESNO | MB_ICONWARNING) == IDNO)
+ return FALSE;
+
+ // Stop play.
+ CMainFrame::GetMainFrame()->StopMod(this);
+
+ BeginWaitCursor();
+ BEGIN_CRITICAL();
+
+ // convert to IT...
+ ChangeModType(MOD_TYPE_IT);
+
+ // clear order list
+ m_SndFile.Order.Init();
+ m_SndFile.Order[0] = 0;
+
+ // remove all patterns
+ m_SndFile.Patterns.Init();
+ m_SndFile.Patterns.Insert(0, 64);
+ m_SndFile.SetCurrentOrder(0);
+
+ // Global vars
+ m_SndFile.m_nDefaultTempo = 125;
+ m_SndFile.m_nDefaultSpeed = 6;
+ m_SndFile.m_nDefaultGlobalVolume = 256;
+ m_SndFile.m_nSamplePreAmp = 48;
+ m_SndFile.m_nVSTiVolume = 48;
+ m_SndFile.m_nRestartPos = 0;
+
+ // Set 4 default channels.
+ m_SndFile.ReArrangeChannels(vector<CHANNELINDEX>(4, MAX_BASECHANNELS));
+
+ //remove plugs
+ bool keepMask[MAX_MIXPLUGINS]; memset(keepMask, 0, sizeof(keepMask));
+ RemovePlugs(keepMask);
+
+ // instruments
+ if(m_SndFile.m_nInstruments && ::MessageBox(NULL, "Remove instruments?", "Compo Cleanup", MB_YESNO | MB_ICONQUESTION) == IDYES)
+ {
+ // remove instruments
+ RemoveAllInstruments(false);
+ }
+ else
+ {
+ // reset instruments
+ for(UINT i = 1; i <= m_SndFile.m_nInstruments; i++)
+ {
+ m_SndFile.Headers[i]->nFadeOut = 256;
+ m_SndFile.Headers[i]->nGlobalVol = 64;
+ m_SndFile.Headers[i]->nPan = 128;
+ m_SndFile.Headers[i]->dwFlags &= ~ENV_SETPANNING;
+ m_SndFile.Headers[i]->nMixPlug = 0;
+
+ m_SndFile.Headers[i]->nVolSwing = 0;
+ m_SndFile.Headers[i]->nPanSwing = 0;
+ m_SndFile.Headers[i]->nCutSwing = 0;
+ m_SndFile.Headers[i]->nResSwing = 0;
+
+ //might be a good idea to leave those enabled...
+ /*
+ m_SndFile.Headers[i]->dwFlags &= ~ENV_VOLUME;
+ m_SndFile.Headers[i]->dwFlags &= ~ENV_PANNING;
+ m_SndFile.Headers[i]->dwFlags &= ~ENV_PITCH;
+ m_SndFile.Headers[i]->dwFlags &= ~ENV_FILTER;
+ */
+ }
+ }
+
+ // reset samples
+ ctrlSmp::ResetSamples(m_SndFile, ctrlSmp::SmpResetCompo);
+
+ // Set modflags.
+ m_SndFile.SetModFlag(MSF_MIDICC_BUGEMULATION, false);
+ m_SndFile.SetModFlag(MSF_OLDVOLSWING, false);
+ m_SndFile.SetModFlag(MSF_COMPATIBLE_PLAY, true);
+
+ END_CRITICAL();
+ EndWaitCursor();
+
+ UpdateAllViews(NULL, HINT_MODGENERAL, this);
+
+ SetModified();
+ return TRUE;
+}
+
+
BOOL CModDoc::AdjustEndOfSample(UINT nSample)
//-------------------------------------------
{
@@ -1538,6 +1675,7 @@
MODCOMMAND *m = m_SndFile.Patterns[nPattern];
UINT nrow = dwBeginSel >> 16;
UINT ncol = (dwBeginSel & 0xFFFF) >> 3;
+ ORDERINDEX oCurrentOrder = m_SndFile.GetCurrentOrder(); //jojo.echopaste
UINT col;
BOOL bS3M = FALSE, bOk = FALSE;
UINT len = 0;
@@ -1683,6 +1821,22 @@
// Next row
m += m_SndFile.m_nChannels;
nrow++;
+
+ //jojo.echopaste
+ if(CMainFrame::m_dwPatternSetup & PATTERN_ECHOPASTE)
+ {
+ while(nrow >= m_SndFile.PatternSize[nPattern])
+ {
+ nrow = 0;
+ ORDERINDEX oNextOrder = m_SndFile.Order.GetNextOrderIgnoringSkips(oCurrentOrder);
+ if((oNextOrder <= 0) || (oNextOrder >= m_SndFile.Order.size())) goto PasteDone;
+ nPattern = m_SndFile.Order[oNextOrder];
+ if(m_SndFile.Patterns.IsValidIndex(nPattern) == false) goto PasteDone;
+ m = m_SndFile.Patterns[nPattern];
+ oCurrentOrder = oNextOrder;
+ }
+ }
+
}
PasteDone:
GlobalUnlock(hCpy);
Modified: trunk/OpenMPT/mptrack/Moptions.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Moptions.cpp 2009-06-15 20:04:15 UTC (rev 270)
+++ trunk/OpenMPT/mptrack/Moptions.cpp 2009-06-17 17:50:41 UTC (rev 271)
@@ -602,6 +602,8 @@
OPTGEN_SYNCMUTE,
OPTGEN_AUTODELAY,
OPTGEN_PATNOTEFADE,
+ OPTGEN_ECHOPASTE,
+ OPTGEN_POSITIONAWARETIMER,
OPTGEN_MAXOPTIONS
};
@@ -637,7 +639,9 @@
{"Old style pattern context menu", "Check this option to hide unavailable items in the pattern editor context menu. Uncheck to grey-out unavailable items instead."},
{"Maintain sample sync on mute", "Samples continue to be processed when channels are muted (like in IT2 and FT2)"},
{"Automatic delay commands", "Automatically insert appropriate note-delay commands when recording notes during live playback."},
- {"Note fade on key up", "Enable to fade/stop notes on key up in pattern tab." }
+ {"Note fade on key up", "Enable to fade/stop notes on key up in pattern tab." },
+ {"Echo paste mode", "Wrap pasted pattern data into next pattern. This is useful for creating echo channels."},
+ {"Position aware timer", "If enabled, timer will show the playback position time if possible instead of running timer."},
};
@@ -700,6 +704,8 @@
case OPTGEN_AUTODELAY: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_AUTODELAY); break;
case OPTGEN_PATNOTEFADE: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_NOTEFADE); break;
+ case OPTGEN_ECHOPASTE: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_ECHOPASTE); break;
+ case OPTGEN_POSITIONAWARETIMER: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_POSITIONAWARETIMER); break;
}
m_CheckList.SetCheck(i, (bCheck) ? TRUE : FALSE);
}
@@ -758,6 +764,8 @@
case OPTGEN_SYNCMUTE: mask = PATTERN_SYNCMUTE; break;
case OPTGEN_AUTODELAY: mask = PATTERN_AUTODELAY; break;
case OPTGEN_PATNOTEFADE: mask = PATTERN_NOTEFADE; break;
+ case OPTGEN_ECHOPASTE: mask = PATTERN_ECHOPASTE; break;
+ case OPTGEN_POSITIONAWARETIMER: mask = PATTERN_POSITIONAWARETIMER; break;
}
if (bCheck) CMainFrame::m_dwPatternSetup |= mask; else CMainFrame::m_dwPatternSetup &= ~mask;
Modified: trunk/OpenMPT/mptrack/OrderToPatternTable.cpp
===================================================================
--- trunk/OpenMPT/mptrack/OrderToPatternTable.cpp 2009-06-15 20:04:15 UTC (rev 270)
+++ trunk/OpenMPT/mptrack/OrderToPatternTable.cpp 2009-06-17 17:50:41 UTC (rev 271)
@@ -159,6 +159,18 @@
}
+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;}
Modified: trunk/OpenMPT/mptrack/OrderToPatternTable.h
===================================================================
--- trunk/OpenMPT/mptrack/OrderToPatternTable.h 2009-06-15 20:04:15 UTC (rev 270)
+++ trunk/OpenMPT/mptrack/OrderToPatternTable.h 2009-06-17 17:50:41 UTC (rev 271)
@@ -28,6 +28,9 @@
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);
Modified: trunk/OpenMPT/mptrack/View_gen.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_gen.cpp 2009-06-15 20:04:15 UTC (rev 270)
+++ trunk/OpenMPT/mptrack/View_gen.cpp 2009-06-17 17:50:41 UTC (rev 271)
@@ -1359,12 +1359,14 @@
// Update instruments
for (INSTRUMENTINDEX nIns=1; nIns<=pSndFile->m_nInstruments; nIns++) {
if (pSndFile->Headers[nIns] && (pSndFile->Headers[nIns]->nMixPlug == src+1)) {
- pSndFile->Headers[nIns]->nMixPlug = dest+1;
+ pSndFile->Headers[nIns]->nMixPlug = static_cast<BYTE>(dest+1);
}
}
END_CRITICAL();
+ pModDoc->SetModified();
+
return true;
}
@@ -1411,6 +1413,8 @@
m_CbnPlugin.SetCurSel(m_nCurrentPlugin);
OnPluginChanged();
+
+ pModDoc->SetModified();
}
}
Modified: trunk/OpenMPT/mptrack/View_pat.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_pat.cpp 2009-06-15 20:04:15 UTC (rev 270)
+++ trunk/OpenMPT/mptrack/View_pat.cpp 2009-06-17 17:50:41 UTC (rev 271)
@@ -3509,6 +3509,7 @@
case kcChangeLoopStatus: SendCtrlMessage(CTRLMSG_PAT_LOOP, -1); return wParam;
case kcNewPattern: SendCtrlMessage(CTRLMSG_PAT_NEWPATTERN); return wParam;
case kcSwitchToOrderList: OnSwitchToOrderList();
+ case kcSwitchEchoPaste: CMainFrame::m_dwPatternSetup ^= PATTERN_ECHOPASTE; return wParam;
}
//Ranges:
Modified: trunk/OpenMPT/mptrack/View_smp.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_smp.cpp 2009-06-15 20:04:15 UTC (rev 270)
+++ trunk/OpenMPT/mptrack/View_smp.cpp 2009-06-17 17:50:41 UTC (rev 271)
@@ -1363,6 +1363,12 @@
InvalidateSample();
pModDoc->SetModified();
}
+ else
+ {
+ // ctrl + click = play from cursor pos
+ if(CMainFrame::GetInputHandler()->CtrlPressed())
+ PlayNote(NOTE_MIDDLEC, ScreenToSample(point.x));
+ }
}
}
@@ -2031,8 +2037,8 @@
{
}
-void CViewSample::PlayNote(UINT note)
-//-----------------------------------------------------
+void CViewSample::PlayNote(UINT note, const uint32 nStartPos)
+//------------------------------------------------------------
{
CMainFrame *pMainFrm = CMainFrame::GetMainFrame();
CModDoc *pModDoc = GetDocument();
@@ -2049,11 +2055,17 @@
pModDoc->NoteOff(note, TRUE);
else
pModDoc->NoteOff(0, TRUE);
+
DWORD loopstart = m_dwBeginSel, loopend = m_dwEndSel;
if (loopend - loopstart < (UINT)(4 << m_nZoom))
loopend = loopstart = 0; // selection is too small -> no loop
- pModDoc->PlayNote(note, 0, m_nSample, FALSE, -1, loopstart, loopend);
+ if(nStartPos != uint32_max)
+ pModDoc->PlayNote(note, 0, m_nSample, FALSE, -1, loopstart, loopend, -1, nStartPos);
+ else
+ pModDoc->PlayNote(note, 0, m_nSample, FALSE, -1, loopstart, loopend);
+
+
m_dwStatus |= SMPSTATUS_KEYDOWN;
s[0] = 0;
if ((note) && (note <= NOTE_MAX)) wsprintf(s, "%s%d", szNoteNames[(note-1)%12], (note-1)/12);
Modified: trunk/OpenMPT/mptrack/View_smp.h
===================================================================
--- trunk/OpenMPT/mptrack/View_smp.h 2009-06-15 20:04:15 UTC (rev 270)
+++ trunk/OpenMPT/mptrack/View_smp.h 2009-06-17 17:50:41 UTC (rev 271)
@@ -32,7 +32,7 @@
BOOL SetZoom(UINT nZoom);
LONG SampleToScreen(LONG n) const;
DWORD ScreenToSample(LONG x) const;
- void PlayNote(UINT note); //rewbs.customKeys
+ void PlayNote(UINT note, const uint32 nStartPos = uint32_max); //rewbs.customKeys
void InvalidateSample();
void SetCurSel(DWORD nBegin, DWORD nEnd);
void ScrollToPosition(int x);
Modified: trunk/OpenMPT/mptrack/mptrack.rc
===================================================================
--- trunk/OpenMPT/mptrack/mptrack.rc 2009-06-15 20:04:15 UTC (rev 270)
+++ trunk/OpenMPT/mptrack/mptrack.rc 2009-06-17 17:50:41 UTC (rev 271)
@@ -146,6 +146,7 @@
MENUITEM "Cleanup S&ong", ID_CLEANUP_SONG
MENUITEM "Remove &All Instruments", ID_INSTRUMENTS_REMOVEALL
MENUITEM "Cleanup &Plugins", ID_CLEANUP_PLUGS
+ MENUITEM "Co&mpo Cleanup", ID_CLEANUP_COMPO
END
MENUITEM SEPARATOR
MENUITEM "&Find\tCtrl+F", ID_EDIT_FIND
@@ -2050,6 +2051,7 @@
BOTTOMMARGIN, 104
END
+ ID_CLEANUP_COMPO "Reset attributes to defaults (useful for creating sample packs)\Compo Cleanup"
IDD_CONTROL_INSTRUMENTS, DIALOG
BEGIN
RIGHTMARGIN, 522
Modified: trunk/OpenMPT/mptrack/mptrack.vcproj
===================================================================
--- trunk/OpenMPT/mptrack/mptrack.vcproj 2009-06-15 20:04:15 UTC (rev 270)
+++ trunk/OpenMPT/mptrack/mptrack.vcproj 2009-06-17 17:50:41 UTC (rev 271)
@@ -358,6 +358,9 @@
RelativePath=".\modedit.cpp">
</File>
<File
+ RelativePath="..\soundlib\modsmp_ctrl.cpp">
+ </File>
+ <File
RelativePath=".\Moptions.cpp">
</File>
<File
@@ -771,6 +774,9 @@
RelativePath=".\moddoc.h">
</File>
<File
+ RelativePath="..\soundlib\modsmp_ctrl.h">
+ </File>
+ <File
RelativePath=".\Moptions.h">
</File>
<File
Modified: trunk/OpenMPT/mptrack/patternContainer.cpp
===================================================================
--- trunk/OpenMPT/mptrack/patternContainer.cpp 2009-06-15 20:04:15 UTC (rev 270)
+++ trunk/OpenMPT/mptrack/patternContainer.cpp 2009-06-17 17:50:41 UTC (rev 271)
@@ -85,3 +85,16 @@
else if(Size() < MAX_PATTERNS) ResizeArray(MAX_PATTERNS);
}
+
+void CPatternContainer::Init()
+//----------------------------
+{
+ for(PATTERNINDEX i = 0; i < Size(); i++)
+ {
+ Remove(i);
+ }
+
+ ResizeArray(MAX_PATTERNS);
+}
+
+
Modified: trunk/OpenMPT/mptrack/patternContainer.h
===================================================================
--- trunk/OpenMPT/mptrack/patternContainer.h 2009-06-15 20:04:15 UTC (rev 270)
+++ trunk/OpenMPT/mptrack/patternContainer.h 2009-06-17 17:50:41 UTC (rev 271)
@@ -30,6 +30,9 @@
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));}
Modified: trunk/OpenMPT/mptrack/resource.h
===================================================================
--- trunk/OpenMPT/mptrack/resource.h 2009-06-15 20:04:15 UTC (rev 270)
+++ trunk/OpenMPT/mptrack/resource.h 2009-06-17 17:50:41 UTC (rev 271)
@@ -1056,7 +1056,7 @@
#define ID_NETLINK_MODARCHIVE 59214
#define ID_PATTERN_DUPLICATECHANNEL 59216
#define ID_EDIT_GOTO_MENU 59220
-
+#define ID_CLEANUP_COMPO 59221
#define ID_SAMPLE_DRAW 59224
#define ID_SAMPLE_ADDSILENCE 59225
// Next default values for new objects
Modified: trunk/OpenMPT/soundlib/Sndfile.h
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.h 2009-06-15 20:04:15 UTC (rev 270)
+++ trunk/OpenMPT/soundlib/Sndfile.h 2009-06-17 17:50:41 UTC (rev 271)
@@ -846,7 +846,7 @@
public: //Misc
void ChangeModTypeTo(const MODTYPE& newType);
- //Return value in seconds.
+ //Returns value in seconds. If given position won't be played at all, returns -1.
double GetPlaybackTimeAt(ORDERINDEX, ROWINDEX);
uint16 GetModFlags() const {return m_ModFlags;}
Modified: trunk/OpenMPT/soundlib/modsmp_ctrl.cpp
===================================================================
--- trunk/OpenMPT/soundlib/modsmp_ctrl.cpp 2009-06-15 20:04:15 UTC (rev 270)
+++ trunk/OpenMPT/soundlib/modsmp_ctrl.cpp 2009-06-17 17:50:41 UTC (rev 271)
@@ -149,4 +149,25 @@
}
+void ResetSamples(CSoundFile& rSndFile, ResetFlag resetflag)
+//----------------------------------------------------------
+{
+ const UINT nSamples = rSndFile.GetNumSamples();
+ for(UINT i = 1; i <= nSamples; i++)
+ {
+ if(resetflag == SmpResetCompo)
+ {
+ rSndFile.Ins[i].nPan = 128;
+ rSndFile.Ins[i].nGlobalVol = 64;
+ rSndFile.Ins[i].nVolume = 256;
+ rSndFile.Ins[i].nVibDepth = 0;
+ rSndFile.Ins[i].nVibRate = 0;
+ rSndFile.Ins[i].nVibSweep = 0;
+ rSndFile.Ins[i].nVibType = 0;
+ rSndFile.Ins[i].uFlags &= ~CHN_PANNING;
+ }
+ }
+}
+
+
} // namespace ctrlSmp
Modified: trunk/OpenMPT/soundlib/modsmp_ctrl.h
===================================================================
--- trunk/OpenMPT/soundlib/modsmp_ctrl.h 2009-06-15 20:04:15 UTC (rev 270)
+++ trunk/OpenMPT/soundlib/modsmp_ctrl.h 2009-06-17 17:50:41 UTC (rev 271)
@@ -12,6 +12,11 @@
typedef uintptr_t SmpLength;
+enum ResetFlag
+{
+ SmpResetCompo = 1
+};
+
// Insert silence to given location.
// Note: Is currently implemented only for inserting silence to the beginning and to the end of the sample.
// Return: Length of the new sample.
@@ -27,6 +32,9 @@
// allocation may be more than what this function returns.
inline SmpLength GetSampleCapacity(MODINSTRUMENT& smp) {return smp.GetSampleSizeInBytes();}
+// Resets samples.
+void ResetSamples(CSoundFile& rSndFile, ResetFlag resetflag);
+
}
#endif
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2009-06-15 20:34:09
|
Revision: 270
http://modplug.svn.sourceforge.net/modplug/?rev=270&view=rev
Author: relabsoluness
Date: 2009-06-15 20:04:15 +0000 (Mon, 15 Jun 2009)
Log Message:
-----------
(Patch from Jojo, merged slightly modified)
+ XM: Compatibility play-mode with a couple of related fixes.
+ XM: Detects compatibility mode automatically when loading XM-file.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/dlg_misc.cpp
trunk/OpenMPT/soundlib/Load_it.cpp
trunk/OpenMPT/soundlib/Load_xm.cpp
trunk/OpenMPT/soundlib/Snd_fx.cpp
trunk/OpenMPT/soundlib/Sndfile.cpp
trunk/OpenMPT/soundlib/Sndfile.h
trunk/OpenMPT/soundlib/Sndmix.cpp
Modified: trunk/OpenMPT/mptrack/dlg_misc.cpp
===================================================================
--- trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-06-14 21:48:05 UTC (rev 269)
+++ trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-06-15 20:04:15 UTC (rev 270)
@@ -280,7 +280,9 @@
p->SetWindowText("1. Enable more IT compatible playback.\n"
"2. Use old random variation behavior for instruments.\n"
"3. Enable plugin volume command bug emulation.");
- else if(XM) p->SetWindowText("1. Unused\n2. Unused\n3. Plugin volume command bug emulation");
+ else if(XM) p->SetWindowText("1. Enable more XM compatible playback.\n"
+ "2. Unused\n"
+ "3. Plugin volume command bug");
}
p = GetDlgItem(IDC_FLAGEDITTITLE);
if(p) p->ShowWindow(XMorITorMPT);
Modified: trunk/OpenMPT/soundlib/Load_it.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_it.cpp 2009-06-14 21:48:05 UTC (rev 269)
+++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-06-15 20:04:15 UTC (rev 270)
@@ -1490,7 +1490,7 @@
{
SetModFlag(MSF_MIDICC_BUGEMULATION, false);
SetModFlag(MSF_OLDVOLSWING, false);
- SetModFlag(MSF_IT_COMPATIBLE_PLAY, true);
+ SetModFlag(MSF_COMPATIBLE_PLAY, true);
}
}
return TRUE;
Modified: trunk/OpenMPT/soundlib/Load_xm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_xm.cpp 2009-06-14 21:48:05 UTC (rev 269)
+++ trunk/OpenMPT/soundlib/Load_xm.cpp 2009-06-15 20:04:15 UTC (rev 270)
@@ -95,6 +95,8 @@
BYTE samples_used[(MAX_SAMPLES+7)/8];
UINT unused_samples;
+ bool bMadeWithModPlug = false;
+
m_nChannels = 0;
if ((!lpStream) || (dwMemLength < 0x200)) return FALSE;
if (_strnicmp((LPCSTR)lpStream, "Extended Module", 15)) return FALSE;
@@ -554,6 +556,7 @@
}
dwMemPos += len;
}
+ bMadeWithModPlug = true;
}
// Read midi config: "MIDI"
if ((dwMemPos + 8 < dwMemLength) && (LittleEndian(*((DWORD *)(lpStream+dwMemPos))) == 0x4944494D))
@@ -566,6 +569,7 @@
m_dwSongFlags |= SONG_EMBEDMIDICFG;
dwMemPos += len; //rewbs.fix36946
}
+ bMadeWithModPlug = true;
}
// Read pattern names: "PNAM"
if ((dwMemPos + 8 < dwMemLength) && (LittleEndian(*((DWORD *)(lpStream+dwMemPos))) == 0x4d414e50))
@@ -582,6 +586,7 @@
}
dwMemPos += len;
}
+ bMadeWithModPlug = true;
}
// Read channel names: "CNAM"
if ((dwMemPos + 8 < dwMemLength) && (LittleEndian(*((DWORD *)(lpStream+dwMemPos))) == 0x4d414e43))
@@ -598,13 +603,18 @@
}
dwMemPos += len;
}
+ bMadeWithModPlug = true;
}
// Read mix plugins information
if (dwMemPos + 8 < dwMemLength)
{
dwMemPos += LoadMixPlugins(lpStream+dwMemPos, dwMemLength-dwMemPos);
+ bMadeWithModPlug = true;
}
+ if(bMadeWithModPlug == false)
+ SetModFlag(MSF_COMPATIBLE_PLAY, true);
+
// -> CODE#0027
// -> DESC="per-instrument volume ramping setup (refered as attack)"
Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-06-14 21:48:05 UTC (rev 269)
+++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-06-15 20:04:15 UTC (rev 270)
@@ -417,7 +417,7 @@
MODINSTRUMENT *psmp = &Ins[instr];
UINT note = pChn->nNewNote;
- if(note == 0 && TypeIsIT_MPT() && GetModFlag(MSF_IT_COMPATIBLE_PLAY)) return;
+ if(note == 0 && TypeIsIT_MPT() && GetModFlag(MSF_COMPATIBLE_PLAY)) return;
if ((penv) && (note) && (note <= 128))
{
@@ -498,7 +498,7 @@
if ((!bPorta) || (!(m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT))) || (m_dwSongFlags & SONG_ITCOMPATMODE)
|| (!pChn->nLength) || ((pChn->dwFlags & CHN_NOTEFADE) && (!pChn->nFadeOutVol))
//IT compatibility tentative fix: Reset envelopes when instrument changes.
- || (TypeIsIT_MPT() && GetModFlag(MSF_IT_COMPATIBLE_PLAY) && bInstrumentChanged))
+ || (TypeIsIT_MPT() && GetModFlag(MSF_COMPATIBLE_PLAY) && bInstrumentChanged))
{
pChn->dwFlags |= CHN_FASTVOLRAMP;
if ((m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT)) && (!bInstrumentChanged) && (penv) && (!(pChn->dwFlags & (CHN_KEYOFF|CHN_NOTEFADE))))
@@ -535,7 +535,7 @@
//IT compatibility tentative fix: Don't anymore change bidi loop direction when
//no sample nor instrument is changed.
- if(TypeIsIT_MPT() && GetModFlag(MSF_IT_COMPATIBLE_PLAY) && psmp == pChn->pInstrument && !bInstrumentChanged)
+ if(TypeIsIT_MPT() && GetModFlag(MSF_COMPATIBLE_PLAY) && psmp == pChn->pInstrument && !bInstrumentChanged)
pChn->dwFlags = (pChn->dwFlags & (0xFFFFFF00 | CHN_PINGPONGFLAG)) | (psmp->uFlags & 0xFF);
else
pChn->dwFlags = (pChn->dwFlags & 0xFFFFFF00) | (psmp->uFlags & 0xFF);
@@ -622,7 +622,7 @@
}
//IT compatibility tentative fix: Clear channel note memory.
- if(TypeIsIT_MPT() && GetModFlag(MSF_IT_COMPATIBLE_PLAY))
+ if(TypeIsIT_MPT() && GetModFlag(MSF_COMPATIBLE_PLAY))
{
pChn->nNote = 0;
pChn->nNewNote = 0;
@@ -1085,7 +1085,7 @@
nStartTick = param & 0x0F;
//IT compatibility 08. Handling of out-of-range delay command.
- if(nStartTick >= m_nMusicSpeed && GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT) && GetModFlag(MSF_IT_COMPATIBLE_PLAY))
+ if(nStartTick >= m_nMusicSpeed && GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT) && GetModFlag(MSF_COMPATIBLE_PLAY))
{
if(instr)
{
@@ -1137,7 +1137,7 @@
if ((!note) && (instr)) //Case: instrument with no note data.
{
//IT compatibility: Instrument with no note.
- if(GetType() & (MOD_TYPE_IT|MOD_TYPE_MPT) && GetModFlag(MSF_IT_COMPATIBLE_PLAY))
+ if(GetType() & (MOD_TYPE_IT|MOD_TYPE_MPT) && GetModFlag(MSF_COMPATIBLE_PLAY))
{
if(m_nInstruments)
{
@@ -1316,14 +1316,14 @@
break;
case VOLCMD_PORTAUP:
- if((GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) && GetModFlag(MSF_IT_COMPATIBLE_PLAY))
+ if((GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) && GetModFlag(MSF_COMPATIBLE_PLAY))
PortamentoUp(pChn, vol << 2, true);
else
PortamentoUp(pChn, vol << 2, false);
break;
case VOLCMD_PORTADOWN:
- if((GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) && GetModFlag(MSF_IT_COMPATIBLE_PLAY))
+ if((GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) && GetModFlag(MSF_COMPATIBLE_PLAY))
PortamentoDown(pChn, vol << 2, true);
else
PortamentoDown(pChn, vol << 2, false);
@@ -1533,7 +1533,25 @@
// Key Off
case CMD_KEYOFF:
- if (!m_nTickCount) KeyOff(nChn);
+ if(GetModFlag(MSF_COMPATIBLE_PLAY) && (m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2)))
+ {
+ // This is how it's supposed to sound...
+ if (m_nTickCount == param)
+ {
+ // XM: Key-Off + Sample == Note Cut
+ if ((!pChn->pHeader) || (!(pChn->pHeader->dwFlags & ENV_VOLUME)))
+ {
+ pChn->dwFlags |= CHN_FASTVOLRAMP;
+ pChn->nVolume = 0;
+ }
+ KeyOff(nChn);
+ }
+ }
+ else
+ {
+ // This is how it's NOT supposed to sound...
+ if (!m_nTickCount) KeyOff(nChn);
+ }
break;
// Extra-fine porta up/down
@@ -1576,16 +1594,21 @@
if (!m_nTickCount)
{
pChn->nVolEnvPosition = param;
- pChn->nPanEnvPosition = param;
- pChn->nPitchEnvPosition = param;
- if (pChn->pHeader)
+
+ if(!GetModFlag(MSF_COMPATIBLE_PLAY) || !(m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2)))
{
- INSTRUMENTHEADER *penv = pChn->pHeader;
- if ((pChn->dwFlags & CHN_PANENV) && (penv->nPanEnv) && (param > penv->PanPoints[penv->nPanEnv-1]))
+ pChn->nPanEnvPosition = param;
+ pChn->nPitchEnvPosition = param;
+ if (pChn->pHeader)
{
- pChn->dwFlags &= ~CHN_PANENV;
+ INSTRUMENTHEADER *penv = pChn->pHeader;
+ if ((pChn->dwFlags & CHN_PANENV) && (penv->nPanEnv) && (param > penv->PanPoints[penv->nPanEnv-1]))
+ {
+ pChn->dwFlags &= ~CHN_PANENV;
+ }
}
}
+
}
break;
@@ -1944,7 +1967,7 @@
pChn->dwFlags |= CHN_PORTAMENTO;
//IT compatibility 03
- if(!(m_dwSongFlags & SONG_ITCOMPATMODE) && (GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) && GetModFlag(MSF_IT_COMPATIBLE_PLAY))
+ if(!(m_dwSongFlags & SONG_ITCOMPATMODE) && (GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) && GetModFlag(MSF_COMPATIBLE_PLAY))
{
if(param == 0) param = pChn->nOldPortaUpDown;
pChn->nOldPortaUpDown = param;
@@ -3061,7 +3084,7 @@
pChn->nPatternLoopCount--;
if(!pChn->nPatternLoopCount)
{
- if(GetType() & (MOD_TYPE_IT|MOD_TYPE_MPT) && GetModFlag(MSF_IT_COMPATIBLE_PLAY))
+ if(GetType() & (MOD_TYPE_IT|MOD_TYPE_MPT) && GetModFlag(MSF_COMPATIBLE_PLAY))
pChn->nPatternLoop = m_nRow+1;
return -1;
@@ -3070,7 +3093,7 @@
{
MODCHANNEL *p = Chn;
- if(!(GetType() & (MOD_TYPE_IT|MOD_TYPE_MPT) && GetModFlag(MSF_IT_COMPATIBLE_PLAY)))
+ if(!(GetType() & (MOD_TYPE_IT|MOD_TYPE_MPT) && GetModFlag(MSF_COMPATIBLE_PLAY)))
{
for (UINT i=0; i<m_nChannels; i++, p++) if (p != pChn)
{
Modified: trunk/OpenMPT/soundlib/Sndfile.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-06-14 21:48:05 UTC (rev 269)
+++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-06-15 20:04:15 UTC (rev 270)
@@ -2917,22 +2917,15 @@
uint16 CSoundFile::GetModFlagMask(const MODTYPE oldtype, const MODTYPE newtype) const
//-----------------------------------------------------------------------------------
{
- if(oldtype == MOD_TYPE_IT)
- {
- if(newtype == MOD_TYPE_MPT) return 65535;
- if(newtype == MOD_TYPE_XM) return (1 << MSF_MIDICC_BUGEMULATION);
- return 0;
- }
+ const MODTYPE combined = oldtype | newtype;
- if(oldtype == MOD_TYPE_MPT)
- {
- if(newtype == MOD_TYPE_IT) return 65535;
- if(newtype == MOD_TYPE_XM) return (1 << MSF_MIDICC_BUGEMULATION);
- return 0;
- }
+ // XM <-> IT/MPT conversion.
+ if(combined == (MOD_TYPE_IT|MOD_TYPE_XM) || combined == (MOD_TYPE_MPT|MOD_TYPE_XM))
+ return (1 << MSF_COMPATIBLE_PLAY) + (1 << MSF_MIDICC_BUGEMULATION);
- if(oldtype == MOD_TYPE_XM && (newtype == MOD_TYPE_IT || newtype == MOD_TYPE_MPT))
- return (1 << MSF_MIDICC_BUGEMULATION);
+ // IT <-> MPT conversion.
+ if(combined == (MOD_TYPE_IT|MOD_TYPE_MPT))
+ return uint16_max;
return 0;
}
Modified: trunk/OpenMPT/soundlib/Sndfile.h
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.h 2009-06-14 21:48:05 UTC (rev 269)
+++ trunk/OpenMPT/soundlib/Sndfile.h 2009-06-15 20:04:15 UTC (rev 270)
@@ -828,7 +828,7 @@
//Note: These are bit indeces. MSF <-> Mod(Specific)Flag.
//If changing these, ChangeModTypeTo() might need modification.
-const BYTE MSF_IT_COMPATIBLE_PLAY = 0; //IT/MPT
+const BYTE MSF_COMPATIBLE_PLAY = 0; //IT/MPT/XM
const BYTE MSF_OLDVOLSWING = 1; //IT/MPT
const BYTE MSF_MIDICC_BUGEMULATION = 2; //IT/MPT/XM
Modified: trunk/OpenMPT/soundlib/Sndmix.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndmix.cpp 2009-06-14 21:48:05 UTC (rev 269)
+++ trunk/OpenMPT/soundlib/Sndmix.cpp 2009-06-15 20:04:15 UTC (rev 270)
@@ -1164,7 +1164,7 @@
else
{
//IT playback compatibility 01 & 02
- if(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT) && GetModFlag(MSF_IT_COMPATIBLE_PLAY))
+ if(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT) && GetModFlag(MSF_COMPATIBLE_PLAY))
{
if(pChn->nArpeggio >> 4 != 0 || (pChn->nArpeggio & 0x0F) != 0)
{
@@ -1276,7 +1276,7 @@
switch (pChn->nVibratoType & 0x03)
{
case 1:
- if(GetModFlag(MSF_IT_COMPATIBLE_PLAY) == true)
+ if(GetModFlag(MSF_COMPATIBLE_PLAY) == true)
vdelta = -ModRampDownTable[(vibpos+16) % 64];
else
vdelta = ModRampDownTable[vibpos];
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2009-06-14 21:49:09
|
Revision: 269
http://modplug.svn.sourceforge.net/modplug/?rev=269&view=rev
Author: relabsoluness
Date: 2009-06-14 21:48:05 +0000 (Sun, 14 Jun 2009)
Log Message:
-----------
(Patch from coda, merged somewhat modified with related refactoring)
+ Sample tab: Sample drawing.
+ Sample tab: Add silence to sample.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Modedit.cpp
trunk/OpenMPT/mptrack/Mptrack.cpp
trunk/OpenMPT/mptrack/View_smp.cpp
trunk/OpenMPT/mptrack/View_smp.h
trunk/OpenMPT/mptrack/dlg_misc.cpp
trunk/OpenMPT/mptrack/dlg_misc.h
trunk/OpenMPT/mptrack/mptrack.rc
trunk/OpenMPT/mptrack/res/smptoolb.bmp
trunk/OpenMPT/mptrack/resource.h
Added Paths:
-----------
trunk/OpenMPT/soundlib/modsmp_ctrl.cpp
trunk/OpenMPT/soundlib/modsmp_ctrl.h
Modified: trunk/OpenMPT/mptrack/Modedit.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Modedit.cpp 2009-06-12 17:32:08 UTC (rev 268)
+++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-06-14 21:48:05 UTC (rev 269)
@@ -7,6 +7,7 @@
#include "moddoc.h"
#include "dlg_misc.h"
#include "dlsbank.h"
+#include "modsmp_ctrl.h"
#pragma warning(disable:4244) //"conversion from 'type1' to 'type2', possible loss of data"
@@ -995,84 +996,13 @@
BOOL CModDoc::AdjustEndOfSample(UINT nSample)
//-------------------------------------------
{
- const MODINSTRUMENT *pins;
+ MODINSTRUMENT *pins;
if (nSample >= MAX_SAMPLES) return FALSE;
pins = &m_SndFile.Ins[nSample];
if ((!pins->nLength) || (!pins->pSample)) return FALSE;
- BEGIN_CRITICAL();
- UINT len = pins->nLength;
- if (pins->uFlags & CHN_16BIT)
- {
- signed short *p = (signed short *)pins->pSample;
- if (pins->uFlags & CHN_STEREO)
- {
- p[(len+3)*2] = p[(len+2)*2] = p[(len+1)*2] = p[(len)*2] = p[(len-1)*2];
- p[(len+3)*2+1] = p[(len+2)*2+1] = p[(len+1)*2+1] = p[(len)*2+1] = p[(len-1)*2+1];
- } else
- {
- p[len+4] = p[len+3] = p[len+2] = p[len+1] = p[len] = p[len-1];
- }
- if (((pins->uFlags & (CHN_LOOP|CHN_PINGPONGLOOP|CHN_STEREO)) == CHN_LOOP)
- && (pins->nLoopEnd == pins->nLength)
- && (pins->nLoopEnd > pins->nLoopStart) && (pins->nLength > 2))
- {
- p[len] = p[pins->nLoopStart];
- p[len+1] = p[pins->nLoopStart+1];
- p[len+2] = p[pins->nLoopStart+2];
- p[len+3] = p[pins->nLoopStart+3];
- p[len+4] = p[pins->nLoopStart+4];
- }
- } else
- {
- signed char *p = (signed char *)pins->pSample;
- if (pins->uFlags & CHN_STEREO)
- {
- p[(len+3)*2] = p[(len+2)*2] = p[(len+1)*2] = p[(len)*2] = p[(len-1)*2];
- p[(len+3)*2+1] = p[(len+2)*2+1] = p[(len+1)*2+1] = p[(len)*2+1] = p[(len-1)*2+1];
- } else
- {
- p[len+4] = p[len+3] = p[len+2] = p[len+1] = p[len] = p[len-1];
- }
- if (((pins->uFlags & (CHN_LOOP|CHN_PINGPONGLOOP|CHN_STEREO)) == CHN_LOOP)
- && (pins->nLoopEnd == pins->nLength)
- && (pins->nLoopEnd > pins->nLoopStart) && (pins->nLength > 2))
- {
- p[len] = p[pins->nLoopStart];
- p[len+1] = p[pins->nLoopStart+1];
- p[len+2] = p[pins->nLoopStart+2];
- p[len+3] = p[pins->nLoopStart+3];
- p[len+4] = p[pins->nLoopStart+4];
- }
- }
- // Update channels with new loop values
- {
- for (UINT i=0; i<MAX_CHANNELS; i++) if ((m_SndFile.Chn[i].pInstrument == pins) && (m_SndFile.Chn[i].nLength))
- {
- if ((pins->nLoopStart + 3 < pins->nLoopEnd) && (pins->nLoopEnd <= pins->nLength))
- {
- m_SndFile.Chn[i].nLoopStart = pins->nLoopStart;
- m_SndFile.Chn[i].nLoopEnd = pins->nLoopEnd;
- m_SndFile.Chn[i].nLength = pins->nLoopEnd;
- if (m_SndFile.Chn[i].nPos > m_SndFile.Chn[i].nLength)
- {
- m_SndFile.Chn[i].nPos = m_SndFile.Chn[i].nLoopStart;
- m_SndFile.Chn[i].dwFlags &= ~CHN_PINGPONGFLAG;
- }
- DWORD d = m_SndFile.Chn[i].dwFlags & ~(CHN_PINGPONGLOOP|CHN_LOOP);
- if (pins->uFlags & CHN_LOOP)
- {
- d |= CHN_LOOP;
- if (pins->uFlags & CHN_PINGPONGLOOP) d |= CHN_PINGPONGLOOP;
- }
- m_SndFile.Chn[i].dwFlags = d;
- } else
- if (!(pins->uFlags & CHN_LOOP))
- {
- m_SndFile.Chn[i].dwFlags &= ~(CHN_PINGPONGLOOP|CHN_LOOP);
- }
- }
- }
- END_CRITICAL();
+
+ ctrlSmp::AdjustEndOfSample(*pins, &m_SndFile);
+
return TRUE;
}
Modified: trunk/OpenMPT/mptrack/Mptrack.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Mptrack.cpp 2009-06-12 17:32:08 UTC (rev 268)
+++ trunk/OpenMPT/mptrack/Mptrack.cpp 2009-06-14 21:48:05 UTC (rev 269)
@@ -19,7 +19,7 @@
#include <shlwapi.h>
// rewbs.memLeak
-#define CRTDBG_MAP_ALLOC
+#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#include ".\mptrack.h"
@@ -1686,6 +1686,8 @@
"http://www.hermannseib.com/english/vsthost.htm|"
"Ian Luck for UNMO3|"
"http://www.un4seen.com/mo3.html|"
+ "coda for sample drawing code|"
+ "http://coda.s3m.us/|"
"Pel K. Txnder for the scrolling credits control :)|"
"http://tinyurl.com/4yze8|"
"The people at Modplug forums for crucial contribution|"
Modified: trunk/OpenMPT/mptrack/View_smp.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_smp.cpp 2009-06-12 17:32:08 UTC (rev 268)
+++ trunk/OpenMPT/mptrack/View_smp.cpp 2009-06-14 21:48:05 UTC (rev 269)
@@ -9,7 +9,13 @@
#include "channelManagerDlg.h"
#include "view_smp.h"
#include "midi.h"
+#include "dlg_misc.h"
+#include "modsmp_ctrl.h"
+#define new DEBUG_NEW
+
+
+
// Non-client toolbar
#define SMP_LEFTBAR_CY 29
#define SMP_LEFTBAR_CXSEP 14
@@ -31,6 +37,8 @@
ID_SAMPLE_ZOOMUP,
ID_SAMPLE_ZOOMDOWN,
ID_SEPARATOR,
+ ID_SAMPLE_DRAW,
+ ID_SAMPLE_ADDSILENCE,
};
@@ -75,6 +83,8 @@
ON_COMMAND(ID_SAMPLE_SETSUSTAINEND, OnSetSustainEnd)
ON_COMMAND(ID_SAMPLE_ZOOMUP, OnZoomUp)
ON_COMMAND(ID_SAMPLE_ZOOMDOWN, OnZoomDown)
+ ON_COMMAND(ID_SAMPLE_DRAW, OnDrawingToggle)
+ ON_COMMAND(ID_SAMPLE_ADDSILENCE, OnAddSilence)
ON_MESSAGE(WM_MOD_MIDIMSG, OnMidiMsg)
ON_MESSAGE(WM_MOD_KEYCOMMAND, OnCustomKeyMsg) //rewbs.customKeys
//}}AFX_MSG_MAP
@@ -103,6 +113,7 @@
//---------------------------------
{
m_dwBeginSel = m_dwEndSel = 0;
+ m_bDrawingEnabled = false; // sample drawing
ModifyStyleEx(0, WS_EX_ACCEPTFILES);
CModScrollView::OnInitialUpdate();
CMainFrame *pMainFrm = CMainFrame::GetMainFrame();
@@ -179,6 +190,7 @@
pModDoc->SetFollowWnd(m_hWnd, MPTNOTIFY_SAMPLE|nSmp);
if (nSmp == m_nSample) return FALSE;
m_dwBeginSel = m_dwEndSel = 0;
+ m_bDrawingEnabled = false; // sample drawing
CMainFrame *pMainFrm = CMainFrame::GetMainFrame();
if (pMainFrm) pMainFrm->SetInfoText("");
m_nSample = nSmp;
@@ -394,6 +406,13 @@
UpdateNcButtonState();
InvalidateSample();
}
+
+ // sample drawing
+ if(dwHintMask & HINT_SAMPLEINFO)
+ {
+ m_bDrawingEnabled = false;
+ UpdateNcButtonState();
+ }
}
#define YCVT(n, bits) (ymed - (((n) * yrange) >> (bits)))
@@ -987,6 +1006,8 @@
{
case ID_SAMPLE_ZOOMUP: nImage = 1; break;
case ID_SAMPLE_ZOOMDOWN: nImage = 2; break;
+ case ID_SAMPLE_DRAW: nImage = (dwStyle & NCBTNS_DISABLED) ? 18 : 16; break;
+ case ID_SAMPLE_ADDSILENCE: nImage = 17; break;
}
pDC->Draw3dRect(rect.left-1, rect.top-1, SMP_LEFTBAR_CXBTN+2, SMP_LEFTBAR_CYBTN+2, c3, c4);
pDC->Draw3dRect(rect.left, rect.top, SMP_LEFTBAR_CXBTN, SMP_LEFTBAR_CYBTN, c1, c2);
@@ -1061,6 +1082,15 @@
dwStyle |= NCBTNS_MOUSEOVER;
if (m_dwStatus & SMPSTATUS_NCLBTNDOWN) dwStyle |= NCBTNS_PUSHED;
}
+
+ switch(cLeftBarButtons[i])
+ {
+ case ID_SAMPLE_DRAW:
+ if(m_bDrawingEnabled) dwStyle |= NCBTNS_CHECKED;
+ if(pSndFile->Ins[m_nSample].GetNumChannels() > 1) dwStyle |= NCBTNS_DISABLED;
+ break;
+ }
+
if (dwStyle != m_NcButtonState[i])
{
m_NcButtonState[i] = dwStyle;
@@ -1163,6 +1193,41 @@
}
+template<class T, class uT>
+T CViewSample::GetSampleValueFromPoint(const CPoint& point)
+//------------------------------------------------------------
+{
+ STATIC_ASSERT(sizeof(T) == sizeof(uT) && sizeof(T) <= 2);
+ int value = (std::numeric_limits<T>::max)() - (std::numeric_limits<uT>::max)() * point.y / (m_rcClient.bottom - m_rcClient.top);
+ Limit(value, (std::numeric_limits<T>::min)(), (std::numeric_limits<T>::max)());
+ return static_cast<T>(value);
+}
+
+
+template<class T, class uT>
+void CViewSample::SetInitialDrawPoint(void* pSample, const CPoint& point)
+//-----------------------------------------------------------------------
+{
+ T* data = reinterpret_cast<T*>(pSample);
+ data[m_dwEndDrag] = GetSampleValueFromPoint<T, uT>(point);
+}
+
+
+template<class T, class uT>
+void CViewSample::SetSampleData(void* pSample, const CPoint& point, const DWORD old )
+//-----------------------------------------------------------------------------------
+{
+ T* data = reinterpret_cast<T*>(pSample);
+ const int oldvalue = data[old];
+ const int value = GetSampleValueFromPoint<T, uT>(point);
+ for(DWORD i=old; i != m_dwEndDrag; i += (m_dwEndDrag > old ? 1 : -1))
+ {
+ data[i] = static_cast<T>((float)oldvalue + (value - oldvalue) * ((float)i - old) / ((float)m_dwEndDrag - old));
+ }
+ data[m_dwEndDrag] = static_cast<T>(value);
+}
+
+
void CViewSample::OnMouseMove(UINT, CPoint point)
//-----------------------------------------------
{
@@ -1212,7 +1277,7 @@
if (m_dwStatus & SMPSTATUS_MOUSEDRAG)
{
BOOL bAgain = FALSE;
- DWORD len = pSndFile->Ins[m_nSample].nLength;
+ const DWORD len = pSndFile->Ins[m_nSample].nLength;
if (!len) return;
DWORD old = m_dwEndDrag;
if (m_nZoom)
@@ -1242,12 +1307,24 @@
point.x = m_rcClient.right;
}
}
- LONG l = ScreenToSample(point.x);
- if (l < 0) l = 0;
- m_dwEndDrag = l;
- if (m_dwEndDrag > len) m_dwEndDrag = len;
- if (old != m_dwEndDrag)
+ m_dwEndDrag = ScreenToSample(point.x);
+ if(m_bDrawingEnabled)
{
+ if(m_dwEndDrag < len)
+ {
+ if(pSndFile->Ins[m_nSample].GetElementarySampleSize() == 2)
+ SetSampleData<int16, uint16>(pSndFile->Ins[m_nSample].pSample, point, old);
+ else if(pSndFile->Ins[m_nSample].GetElementarySampleSize() == 1)
+ SetSampleData<int8, uint8>(pSndFile->Ins[m_nSample].pSample, point, old);
+
+ ctrlSmp::AdjustEndOfSample(pSndFile->Ins[m_nSample], pSndFile);
+
+ InvalidateSample();
+ pModDoc->SetModified();
+ }
+ }
+ else if (old != m_dwEndDrag)
+ {
SetCurSel(m_dwBeginDrag, m_dwEndDrag);
UpdateWindow();
}
@@ -1275,6 +1352,17 @@
if (m_dwBeginDrag >= len) m_dwBeginDrag = len-1;
m_dwEndDrag = m_dwBeginDrag;
if (oldsel) SetCurSel(m_dwBeginDrag, m_dwEndDrag);
+ // set initial point for sample drawing
+ if (m_bDrawingEnabled)
+ {
+ if(pSndFile->Ins[m_nSample].GetElementarySampleSize() == 2)
+ SetInitialDrawPoint<int16, uint16>(pSndFile->Ins[m_nSample].pSample, point);
+ else if(pSndFile->Ins[m_nSample].GetElementarySampleSize() == 1)
+ SetInitialDrawPoint<int8, uint8>(pSndFile->Ins[m_nSample].pSample, point);
+
+ InvalidateSample();
+ pModDoc->SetModified();
+ }
}
}
@@ -1299,7 +1387,7 @@
{
CSoundFile *pSndFile = pModDoc->GetSoundFile();
DWORD len = pSndFile->Ins[m_nSample].nLength;
- if (len) SetCurSel(0, len);
+ if (len && !m_bDrawingEnabled) SetCurSel(0, len);
}
}
@@ -2279,6 +2367,43 @@
}
+void CViewSample::OnDrawingToggle()
+//---------------------------------
+{
+ m_bDrawingEnabled = !m_bDrawingEnabled;
+ UpdateNcButtonState();
+}
+
+
+void CViewSample::OnAddSilence()
+//------------------------------
+{
+ CAddSilenceDlg dlg(this);
+ if (dlg.DoModal() != IDOK) return;
+
+ CModDoc *pModDoc = GetDocument();
+ if (!pModDoc) return;
+ CSoundFile *pSndFile = pModDoc->GetSoundFile();
+ if (!pSndFile) return;
+
+ const ctrlSmp::SmpLength nOldLength = pSndFile->Ins[m_nSample].nLength;
+
+ if( MAX_SAMPLE_LENGTH - nOldLength < dlg.m_nSamples )
+ {
+ CString str; str.Format(TEXT("Can't add silence because the new sample length would exceed maximum sample length %u."), MAX_SAMPLE_LENGTH);
+ AfxMessageBox(str, MB_ICONINFORMATION);
+ return;
+ }
+
+ ctrlSmp::InsertSilence(pSndFile->Ins[m_nSample], dlg.m_nSamples, (dlg.m_bAddAtEnd) ? pSndFile->Ins[m_nSample].nLength : 0, pSndFile);
+
+ if(nOldLength != pSndFile->Ins[m_nSample].nLength)
+ {
+ pModDoc->SetModified();
+ pModDoc->UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEINFO | HINT_SAMPLEDATA, NULL);
+ }
+}
+
LRESULT CViewSample::OnMidiMsg(WPARAM dwMidiDataParam, LPARAM)
//-------------------------------------------------------
{
Modified: trunk/OpenMPT/mptrack/View_smp.h
===================================================================
--- trunk/OpenMPT/mptrack/View_smp.h 2009-06-12 17:32:08 UTC (rev 268)
+++ trunk/OpenMPT/mptrack/View_smp.h 2009-06-14 21:48:05 UTC (rev 269)
@@ -5,7 +5,7 @@
#define SMPSTATUS_KEYDOWN 0x02
#define SMPSTATUS_NCLBTNDOWN 0x04
-#define SMP_LEFTBAR_BUTTONS 3
+#define SMP_LEFTBAR_BUTTONS 5
//======================================
class CViewSample: public CModScrollView
@@ -20,6 +20,7 @@
DWORD m_dwMenuParam;
DWORD m_NcButtonState[SMP_LEFTBAR_BUTTONS];
DWORD m_dwNotifyPos[MAX_CHANNELS];
+ bool m_bDrawingEnabled;
public:
CViewSample();
@@ -42,6 +43,18 @@
BOOL GetNcButtonRect(UINT nBtn, LPRECT lpRect);
void UpdateNcButtonState();
+ // Sets sample data on sample draw.
+ template<class T, class uT>
+ void SetSampleData(void* pSample, const CPoint& point, const DWORD old);
+
+ // Sets initial draw point on sample draw.
+ template<class T, class uT>
+ void SetInitialDrawPoint(void* pSample, const CPoint& point);
+
+ // Returns sample value corresponding given point in the sample view.
+ template<class T, class uT>
+ T GetSampleValueFromPoint(const CPoint& point);
+
public:
//{{AFX_VIRTUAL(CViewSample)
virtual void OnDraw(CDC *);
@@ -98,6 +111,8 @@
afx_msg void OnSetSustainEnd();
afx_msg void OnZoomUp();
afx_msg void OnZoomDown();
+ afx_msg void OnDrawingToggle();
+ afx_msg void OnAddSilence();
afx_msg LRESULT OnMidiMsg(WPARAM, LPARAM);
afx_msg LRESULT OnCustomKeyMsg(WPARAM, LPARAM); //rewbs.customKeys
//}}AFX_MSG
Modified: trunk/OpenMPT/mptrack/dlg_misc.cpp
===================================================================
--- trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-06-12 17:32:08 UTC (rev 268)
+++ trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-06-14 21:48:05 UTC (rev 269)
@@ -1543,6 +1543,33 @@
}
+// Add silence to a sample
+BOOL CAddSilenceDlg::OnInitDialog()
+//---------------------------------
+{
+ CDialog::OnInitDialog();
+ CSpinButtonCtrl *spin = (CSpinButtonCtrl *)GetDlgItem(IDC_SPIN1);
+ if (spin)
+ {
+ spin->SetRange(0, int16_max);
+ spin->SetPos(m_nSamples);
+ }
+ CButton *radio2 = (CButton *)GetDlgItem(IDC_RADIO2);
+ radio2->SetCheck(m_bAddAtEnd);
+ SetDlgItemInt(IDC_EDIT1, m_nSamples);
+ return TRUE;
+}
+
+
+void CAddSilenceDlg::OnOK()
+//-------------------------
+{
+ m_nSamples = GetDlgItemInt(IDC_EDIT1);
+ m_bAddAtEnd = (IsDlgButtonChecked(IDC_RADIO2) != 0);
+ CDialog::OnOK();
+}
+
+
////////////////////////////////////////////////////////////////////////////////
// Sound Bank Information
Modified: trunk/OpenMPT/mptrack/dlg_misc.h
===================================================================
--- trunk/OpenMPT/mptrack/dlg_misc.h 2009-06-12 17:32:08 UTC (rev 268)
+++ trunk/OpenMPT/mptrack/dlg_misc.h 2009-06-14 21:48:05 UTC (rev 269)
@@ -325,7 +325,22 @@
virtual void OnOK();
};
+//===========================
+class CAddSilenceDlg: public CDialog
+//===========================
+{
+public:
+ UINT m_nSamples;
+ bool m_bAddAtEnd;
+public:
+ CAddSilenceDlg(CWnd *parent, UINT nSamples=32):CDialog(IDD_ADDSILENCE, parent) { m_nSamples = nSamples; m_bAddAtEnd = true; }
+ virtual BOOL OnInitDialog();
+ virtual void OnOK();
+};
+
+
+
////////////////////////////////////////////////////////////////////////
// Sound Banks
Modified: trunk/OpenMPT/mptrack/mptrack.rc
===================================================================
--- trunk/OpenMPT/mptrack/mptrack.rc 2009-06-12 17:32:08 UTC (rev 268)
+++ trunk/OpenMPT/mptrack/mptrack.rc 2009-06-14 21:48:05 UTC (rev 269)
@@ -1929,6 +1929,26 @@
LTEXT "around current",IDC_STATIC,156,84,49,8
END
+IDD_ADDSILENCE DIALOGEX 0, 0, 175, 63
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "Insert Silence"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,118,7,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,118,25,50,14
+ GROUPBOX "",IDC_STATIC,7,3,106,55
+ EDITTEXT IDC_EDIT1,25,14,40,14,ES_AUTOHSCROLL | ES_NUMBER
+ CONTROL "",IDC_SPIN1,"msctls_updown32",UDS_SETBUDDYINT |
+ UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS |
+ UDS_NOTHOUSANDS,57,15,11,14
+ LTEXT "samples",IDC_STATIC,74,17,26,8
+ CONTROL "At beginning of sample",IDC_RADIO1,"Button",
+ BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,11,32,89,10
+ CONTROL "At end of sample",IDC_RADIO2,"Button",
+ BS_AUTORADIOBUTTON | WS_TABSTOP,11,46,70,10
+END
+
IDD_PATTERNRANDOMIZER_EFFECT DIALOGEX 0, 0, 235, 172
STYLE DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD
FONT 8, "MS Sans Serif", 0, 0, 0x0
@@ -2212,6 +2232,15 @@
RIGHTMARGIN, 229
BOTTOMMARGIN, 169
END
+
+ IDD_ADDSILENCE, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 168
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 56
+ END
+
END
#endif // APSTUDIO_INVOKED
Modified: trunk/OpenMPT/mptrack/res/smptoolb.bmp
===================================================================
(Binary files differ)
Modified: trunk/OpenMPT/mptrack/resource.h
===================================================================
--- trunk/OpenMPT/mptrack/resource.h 2009-06-12 17:32:08 UTC (rev 268)
+++ trunk/OpenMPT/mptrack/resource.h 2009-06-14 21:48:05 UTC (rev 269)
@@ -105,6 +105,7 @@
#define IDS_ERR_TUNING_SERIALISATION 514
#define IDD_MIDIPARAMCONTROL 515
#define IDD_MSGBOX_HIDABLE 516
+#define IDD_ADDSILENCE 517
#define IDC_BUTTON1 1001
#define IDC_BUTTON2 1002
#define IDC_BUTTON3 1003
@@ -1056,13 +1057,15 @@
#define ID_PATTERN_DUPLICATECHANNEL 59216
#define ID_EDIT_GOTO_MENU 59220
+#define ID_SAMPLE_DRAW 59224
+#define ID_SAMPLE_ADDSILENCE 59225
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_3D_CONTROLS 1
-#define _APS_NEXT_RESOURCE_VALUE 517
-#define _APS_NEXT_COMMAND_VALUE 59221
+#define _APS_NEXT_RESOURCE_VALUE 518
+#define _APS_NEXT_COMMAND_VALUE 59226
#define _APS_NEXT_CONTROL_VALUE 2343
#define _APS_NEXT_SYMED_VALUE 901
#endif
Added: trunk/OpenMPT/soundlib/modsmp_ctrl.cpp
===================================================================
--- trunk/OpenMPT/soundlib/modsmp_ctrl.cpp (rev 0)
+++ trunk/OpenMPT/soundlib/modsmp_ctrl.cpp 2009-06-14 21:48:05 UTC (rev 269)
@@ -0,0 +1,152 @@
+/*
+ * MODINSTRUMENT related functions.
+ */
+
+#include "stdafx.h"
+#include "modsmp_ctrl.h"
+#include "mptrack/MainFrm.h"
+
+#define new DEBUG_NEW
+
+namespace ctrlSmp
+{
+
+void ReplaceSample(MODINSTRUMENT& smp, const LPSTR pNewSample, const SmpLength nNewLength)
+//----------------------------------------------------------------------------------------
+{
+ LPSTR const pOldSmp = smp.pSample;
+ BEGIN_CRITICAL();
+ smp.pSample = pNewSample;
+ smp.nLength = nNewLength;
+ END_CRITICAL();
+ CSoundFile::FreeSample(pOldSmp);
+}
+
+
+SmpLength InsertSilence(MODINSTRUMENT& smp, const SmpLength nSilenceLength, const SmpLength nStartFrom, CSoundFile* pSndFile)
+//----------------------------------------------------------------------------------------------------------------------------
+{
+ if(nSilenceLength == 0 || nSilenceLength >= MAX_SAMPLE_LENGTH || smp.nLength > MAX_SAMPLE_LENGTH - nSilenceLength)
+ return smp.nLength;
+
+ const SmpLength nOldBytes = smp.GetSampleSizeInBytes();
+ const SmpLength nSilenceBytes = nSilenceLength * smp.GetElementarySampleSize() * smp.GetNumChannels();
+ const SmpLength nNewSmpBytes = nOldBytes + nSilenceBytes;
+ const SmpLength nNewLength = smp.nLength + nSilenceLength;
+
+ LPSTR pNewSmp = 0;
+ if( GetSampleCapacity(smp) >= nNewSmpBytes ) // If sample has room to expand.
+ {
+ AfxMessageBox("Not implemented: GetSampleCapacity(smp) >= nNewSmpBytes");
+ // Not implemented, GetSampleCapacity() currently always returns length based value
+ // even if there is unused space in the sample.
+ }
+ else // Have to allocate new sample.
+ {
+ pNewSmp = CSoundFile::AllocateSample(nNewSmpBytes);
+ if(pNewSmp == 0)
+ return smp.nLength; //Sample allocation failed.
+ if(nStartFrom == 0)
+ {
+ memset(pNewSmp, 0, nSilenceBytes);
+ memcpy(pNewSmp + nSilenceBytes, smp.pSample, nOldBytes);
+ }
+ else if(nStartFrom == smp.nLength)
+ {
+ memcpy(pNewSmp, smp.pSample, nOldBytes);
+ memset(pNewSmp + nOldBytes, 0, nSilenceBytes);
+ }
+ else
+ AfxMessageBox(TEXT("Unsupported start position in InsertSilence."));
+ }
+
+ ReplaceSample(smp, pNewSmp, nNewLength);
+ AdjustEndOfSample(smp, pSndFile);
+
+ return smp.nLength;
+}
+
+namespace // Unnamed namespace for local implementation functions.
+{
+
+template <class T>
+void AdjustEndOfSampleImpl(MODINSTRUMENT& smp)
+//--------------------------------------------
+{
+ MODINSTRUMENT* const pins = &smp;
+ const UINT len = pins->nLength;
+ T* p = reinterpret_cast<T*>(pins->pSample);
+ if (pins->uFlags & CHN_STEREO)
+ {
+ p[(len+3)*2] = p[(len+2)*2] = p[(len+1)*2] = p[(len)*2] = p[(len-1)*2];
+ p[(len+3)*2+1] = p[(len+2)*2+1] = p[(len+1)*2+1] = p[(len)*2+1] = p[(len-1)*2+1];
+ } else
+ {
+ p[len+4] = p[len+3] = p[len+2] = p[len+1] = p[len] = p[len-1];
+ }
+ if (((pins->uFlags & (CHN_LOOP|CHN_PINGPONGLOOP|CHN_STEREO)) == CHN_LOOP)
+ && (pins->nLoopEnd == pins->nLength)
+ && (pins->nLoopEnd > pins->nLoopStart) && (pins->nLength > 2))
+ {
+ p[len] = p[pins->nLoopStart];
+ p[len+1] = p[pins->nLoopStart+1];
+ p[len+2] = p[pins->nLoopStart+2];
+ p[len+3] = p[pins->nLoopStart+3];
+ p[len+4] = p[pins->nLoopStart+4];
+ }
+}
+
+} // unnamed namespace.
+
+
+bool AdjustEndOfSample(MODINSTRUMENT& smp, CSoundFile* pSndFile)
+//--------------------------------------------------------------
+{
+ MODINSTRUMENT* const pins = &smp;
+
+ if ((!pins->nLength) || (!pins->pSample))
+ return false;
+
+ BEGIN_CRITICAL();
+
+ if (pins->GetElementarySampleSize() == 2)
+ AdjustEndOfSampleImpl<int16>(*pins);
+ else if(pins->GetElementarySampleSize() == 1)
+ AdjustEndOfSampleImpl<int8>(*pins);
+
+ // Update channels with new loop values
+ if(pSndFile != 0)
+ {
+ CSoundFile& rSndFile = *pSndFile;
+ for (UINT i=0; i<MAX_CHANNELS; i++) if ((rSndFile.Chn[i].pInstrument == pins) && (rSndFile.Chn[i].nLength))
+ {
+ if ((pins->nLoopStart + 3 < pins->nLoopEnd) && (pins->nLoopEnd <= pins->nLength))
+ {
+ rSndFile.Chn[i].nLoopStart = pins->nLoopStart;
+ rSndFile.Chn[i].nLoopEnd = pins->nLoopEnd;
+ rSndFile.Chn[i].nLength = pins->nLoopEnd;
+ if (rSndFile.Chn[i].nPos > rSndFile.Chn[i].nLength)
+ {
+ rSndFile.Chn[i].nPos = rSndFile.Chn[i].nLoopStart;
+ rSndFile.Chn[i].dwFlags &= ~CHN_PINGPONGFLAG;
+ }
+ DWORD d = rSndFile.Chn[i].dwFlags & ~(CHN_PINGPONGLOOP|CHN_LOOP);
+ if (pins->uFlags & CHN_LOOP)
+ {
+ d |= CHN_LOOP;
+ if (pins->uFlags & CHN_PINGPONGLOOP) d |= CHN_PINGPONGLOOP;
+ }
+ rSndFile.Chn[i].dwFlags = d;
+ } else
+ if (!(pins->uFlags & CHN_LOOP))
+ {
+ rSndFile.Chn[i].dwFlags &= ~(CHN_PINGPONGLOOP|CHN_LOOP);
+ }
+ }
+ }
+ END_CRITICAL();
+ return true;
+}
+
+
+} // namespace ctrlSmp
Added: trunk/OpenMPT/soundlib/modsmp_ctrl.h
===================================================================
--- trunk/OpenMPT/soundlib/modsmp_ctrl.h (rev 0)
+++ trunk/OpenMPT/soundlib/modsmp_ctrl.h 2009-06-14 21:48:05 UTC (rev 269)
@@ -0,0 +1,32 @@
+/*
+ * MODINSTRUMENT related functions.
+ */
+
+#ifndef MODSMP_CTRL_H
+#define MODSMP_CTRL_H
+
+#include "Sndfile.h"
+
+namespace ctrlSmp
+{
+
+typedef uintptr_t SmpLength;
+
+// Insert silence to given location.
+// Note: Is currently implemented only for inserting silence to the beginning and to the end of the sample.
+// Return: Length of the new sample.
+SmpLength InsertSilence(MODINSTRUMENT& smp, const SmpLength nSilenceLength, const SmpLength nStartFrom, CSoundFile* pSndFile = 0);
+
+// Replaces sample in 'smp' with given sample and frees the old sample.
+void ReplaceSample(MODINSTRUMENT& smp, const LPSTR pNewSample, const SmpLength nNewLength);
+
+bool AdjustEndOfSample(MODINSTRUMENT& smp, CSoundFile* pSndFile = 0);
+
+// Returns the number of bytes allocated(at least) for sample data.
+// Note: Currently the return value is based on the sample length and the actual
+// allocation may be more than what this function returns.
+inline SmpLength GetSampleCapacity(MODINSTRUMENT& smp) {return smp.GetSampleSizeInBytes();}
+
+}
+
+#endif
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2009-06-12 17:32:32
|
Revision: 268
http://modplug.svn.sourceforge.net/modplug/?rev=268&view=rev
Author: relabsoluness
Date: 2009-06-12 17:32:08 +0000 (Fri, 12 Jun 2009)
Log Message:
-----------
? Added validations to song/instrument extension reading and refactored related code. (merged from rev. 267)
Modified Paths:
--------------
trunk/OpenMPT/mptrack/misc_util.h
trunk/OpenMPT/soundlib/Load_it.cpp
trunk/OpenMPT/soundlib/Load_xm.cpp
trunk/OpenMPT/soundlib/Sampleio.cpp
trunk/OpenMPT/soundlib/Sndfile.h
Modified: trunk/OpenMPT/mptrack/misc_util.h
===================================================================
--- trunk/OpenMPT/mptrack/misc_util.h 2009-06-12 16:25:54 UTC (rev 267)
+++ trunk/OpenMPT/mptrack/misc_util.h 2009-06-12 17:32:08 UTC (rev 268)
@@ -42,10 +42,34 @@
// Size of the array must be known at compile time.
template <size_t size>
inline void SetNullTerminator(char (&buffer)[size])
+//-------------------------------------------------
{
STATIC_ASSERT(size > 0);
buffer[size-1] = 0;
}
+// Limits 'val' to given range. If 'val' is less than 'lowerLimit', 'val' is set to value 'lowerLimit'.
+// Similarly if 'val' is greater than 'upperLimit', 'val' is set to value 'upperLimit'.
+// If 'lowerLimit' > 'upperLimit', 'val' won't be modified.
+template<class T, class C>
+inline void Limit(T& val, const C lowerLimit, const C upperLimit)
+//---------------------------------------------------------------
+{
+ if(lowerLimit > upperLimit) return;
+ if(val < lowerLimit) val = lowerLimit;
+ else if(val > upperLimit) val = upperLimit;
+}
+
+
+// Like Limit, but with upperlimit only.
+template<class T, class C>
+inline void LimitMax(T& val, const C upperLimit)
+//----------------------------------------------
+{
+ if(val > upperLimit)
+ val = upperLimit;
+}
+
+
#endif
Modified: trunk/OpenMPT/soundlib/Load_it.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_it.cpp 2009-06-12 16:25:54 UTC (rev 267)
+++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-06-12 17:32:08 UTC (rev 268)
@@ -847,8 +847,7 @@
// Extra info data
__int32 fcode = 0;
- __int16 fsize = 0;
- BYTE * ptr = (BYTE *)(lpStream + streamPos);
+ LPCBYTE ptr = lpStream + min(streamPos, dwMemLength);
if (streamPos <= dwMemLength - 4) {
fcode = (*((__int32 *)ptr));
@@ -863,7 +862,7 @@
i = 1;
// parse file
- while( ptr + 4 <= (BYTE *)(lpStream + dwMemLength) && i <= m_nInstruments ){
+ while( uintptr_t(ptr - lpStream) <= dwMemLength - 4 && i <= m_nInstruments ){
fcode = (*((__int32 *)ptr)); // read field code
@@ -876,16 +875,7 @@
default:
ptr += sizeof(__int32); // jump field code
- if(ptr + 2 > (BYTE *)(lpStream + dwMemLength)) return FALSE;
- fsize = (*((__int16 *)ptr)); // read field size
- ptr += sizeof(__int16); // jump field size
- BYTE * fadr = GetInstrumentHeaderFieldPointer(Headers[i], fcode, fsize);
- if(fadr && fcode != 'K[..') // copy field data in instrument's header
- {
- if(ptr + fsize > (BYTE *)(lpStream + dwMemLength)) return FALSE;
- memcpy(fadr,ptr,fsize); // (except for keyboard mapping)
- }
- ptr += fsize; // jump field
+ ReadExtendedInstrumentProperty(Headers[i], fcode, ptr, lpStream + dwMemLength);
break;
}
}
@@ -893,7 +883,7 @@
//HACK: if we fail on i <= m_nInstruments above, arrive here without having set fcode as appropriate,
// hence the code duplication.
- if (ptr + 4 <= (BYTE *)(lpStream + dwMemLength)) {
+ if ( (uintptr_t)(ptr - lpStream) <= dwMemLength - 4 ) {
fcode = (*((__int32 *)ptr));
}
@@ -1320,55 +1310,18 @@
ITSAMPLESTRUCT *pis = (ITSAMPLESTRUCT *)(lpStream+smppos[pifh->smpnum-1]);
dwMemPos = pis->samplepointer + lastSampleSize;
- // Get file pointer to match the first byte of extra settings informations __int16 size = 0;
- __int32 code = 0;
- __int16 size = 0;
- BYTE * ptr = NULL;
- if(dwMemPos < dwMemLength) {
- ptr = (BYTE *)(lpStream + dwMemPos);
- code = (*((__int32 *)ptr));;
+ // Load instrument and song extensions.
+ if(mptStartPos >= dwMemPos)
+ {
+ LPCBYTE ptr = LoadExtendedInstrumentProperties(lpStream + dwMemPos, lpStream + mptStartPos, &interpretModplugmade);
+ LoadExtendedSongProperties(GetType(), ptr, lpStream, mptStartPos, &interpretModplugmade);
}
-
- // Instrument extensions
- if( code == 'MPTX' ){
- interpretModplugmade = true;
- ptr += sizeof(__int32); // jump extension header code
- while( (DWORD)(ptr - lpStream) < mptStartPos ){ //Loop 'till beginning of end of file/mpt specific looking for inst. extensions
- code = (*((__int32 *)ptr)); // read field code
- if (code == 'MPTS') { //Reached song extensions, break out of this loop
- break;
- }
-
- ptr += sizeof(__int32); // jump field code
- size = (*((__int16 *)ptr)); // read field size
- ptr += sizeof(__int16); // jump field size
-
- for(UINT nins=1; nins<=m_nInstruments; nins++){
- if(Headers[nins]){
- // get field's adress in instrument's header
- BYTE * fadr = GetInstrumentHeaderFieldPointer(Headers[nins], code, size);
- // copy field data in instrument's header (except for keyboard mapping)
- if(fadr && code != 'K[..') memcpy(fadr,ptr,size);
- // jump field
- ptr += size;
- }
- }
- //end rewbs.instroVSTi
- }
- }
// -! NEW_FEATURE#0027
- // Song extensions
- if( code == 'MPTS' )
- {
- interpretModplugmade = true;
- LoadExtendedSongProperties(GetType(), ptr, lpStream, mptStartPos);
- }
+ // Reading Patterns
Patterns.ResizeArray(max(MAX_PATTERNS, npatterns));
-
- // Reading Patterns
for (UINT npat=0; npat<npatterns; npat++)
{
if ((!patpos[npat]) || ((DWORD)patpos[npat] >= dwMemLength - 4))
@@ -3691,47 +3644,124 @@
return;
}
+LPCBYTE CSoundFile::LoadExtendedInstrumentProperties(const LPCBYTE pStart,
+ const LPCBYTE pEnd,
+ bool* pInterpretMptMade)
+//---------------------------------------------------------------------------
+{
+ if( pStart == NULL || pEnd <= pStart || uintptr_t(pEnd - pStart) < 4)
+ return NULL;
-void CSoundFile::LoadExtendedSongProperties(const MODTYPE modtype, BYTE*& ptr, const LPCBYTE lpStream, const size_t searchlimit)
-//--------------------------------------------------
+ int32 code = 0;
+ int16 size = 0;
+ LPCBYTE ptr = pStart;
+
+ memcpy(&code, ptr, sizeof(code));
+
+ if(code != 'MPTX')
+ return NULL;
+
+ // Found MPTX, interpret the file MPT made.
+ if(pInterpretMptMade != NULL)
+ *pInterpretMptMade = true;
+
+ ptr += sizeof(int32); // jump extension header code
+ while( ptr < pEnd && uintptr_t(pEnd-ptr) >= 4) //Loop 'till beginning of end of file/mpt specific looking for inst. extensions
+ {
+ memcpy(&code, ptr, sizeof(code)); // read field code
+ if (code == 'MPTS') //Reached song extensions, break out of this loop
+ return ptr;
+
+ ptr += sizeof(code); // jump field code
+
+ if((uintptr_t)(pEnd - ptr) < 2)
+ return NULL;
+
+ memcpy(&size, ptr, sizeof(size)); // read field size
+ ptr += sizeof(size); // jump field size
+
+ if(IsValidSizeField(ptr, pEnd, size) == false)
+ return NULL;
+
+ for(UINT nins=1; nins<=m_nInstruments; nins++)
+ {
+ if(Headers[nins])
+ ReadInstrumentExtensionField(Headers[nins], ptr, code, size);
+ }
+ }
+
+ return NULL;
+}
+
+
+void CSoundFile::LoadExtendedSongProperties(const MODTYPE modtype,
+ LPCBYTE ptr,
+ const LPCBYTE lpStream,
+ const size_t searchlimit,
+ bool* pInterpretMptMade)
+//-------------------------------------------------------------------
{
+ if(searchlimit < 6 || ptr == NULL || ptr < lpStream || uintptr_t(ptr - lpStream) > searchlimit - 4)
+ return;
+
+ const LPCBYTE pEnd = lpStream + searchlimit;
+
int32 code = 0;
int16 size = 0;
- ptr += sizeof(int32); // jump extension header code
- while( (DWORD)((ptr + 6) - lpStream) <= searchlimit ) //Loop until given limit.
+
+ memcpy(&code, ptr, sizeof(code));
+
+ if(code != 'MPTS')
+ return;
+
+ // Found MPTS, interpret the file MPT made.
+ if(pInterpretMptMade != NULL)
+ *pInterpretMptMade = true;
+
+
+ // Case macros.
+ #define CASE(id, data) \
+ case id: fadr = reinterpret_cast<BYTE*>(&data); nMaxReadCount = min(size, sizeof(data)); break;
+ #define CASE_NOTXM(id, data) \
+ case id: if(modtype != MOD_TYPE_XM) {fadr = reinterpret_cast<BYTE*>(&data); nMaxReadCount = min(size, sizeof(data));} break;
+
+ ptr += sizeof(code); // jump extension header code
+ while( uintptr_t(ptr - lpStream) <= searchlimit-6 ) //Loop until given limit.
{
- code = (*((__int32 *)ptr)); // read field code
- ptr += sizeof(__int32); // jump field code
- size = (*((__int16 *)ptr)); // read field size
- if(size < 0) break;
- ptr += sizeof(__int16); // jump field size
+ code = (*((int32 *)ptr)); // read field code
+ ptr += sizeof(int32); // jump field code
+ size = (*((int16 *)ptr)); // read field size
+ ptr += sizeof(int16); // jump field size
+ if(IsValidSizeField(ptr, pEnd, size) == false)
+ break;
+
+ size_t nMaxReadCount = 0;
BYTE * fadr = NULL;
- switch (code) { // interpret field code
- case 'DT..': fadr = reinterpret_cast<BYTE*>(&m_nDefaultTempo); break;
- case 'RPB.': fadr = reinterpret_cast<BYTE*>(&m_nRowsPerBeat); break;
- case 'RPM.': fadr = reinterpret_cast<BYTE*>(&m_nRowsPerMeasure); break;
- case 'C...': if(modtype != MOD_TYPE_XM) fadr = reinterpret_cast<BYTE*>(&m_nChannels); break;
- case 'TM..': fadr = reinterpret_cast<BYTE*>(&m_nTempoMode); break;
- case 'PMM.': fadr = reinterpret_cast<BYTE*>(&m_nMixLevels); break;
- case 'CWV.': fadr = reinterpret_cast<BYTE*>(&m_dwCreatedWithVersion); break;
- case 'LSWV': fadr = reinterpret_cast<BYTE*>(&m_dwLastSavedWithVersion); break;
- case 'SPA.': fadr = reinterpret_cast<BYTE*>(&m_nSamplePreAmp); break;
- case 'VSTV': fadr = reinterpret_cast<BYTE*>(&m_nVSTiVolume); break;
- case 'DGV.': fadr = reinterpret_cast<BYTE*>(&m_nDefaultGlobalVolume); break;
- case 'RP..': if(modtype != MOD_TYPE_XM) fadr = reinterpret_cast<BYTE*>(&m_nRestartPos); break;
- case 'MSF.': fadr = reinterpret_cast<BYTE*>(&m_ModFlags); break;
- case 'MIMA':
- if(DWORD(ptr - lpStream + DWORD(size)) > searchlimit)
- MessageBox(NULL, "Error: Bad MIMA datasizefield", NULL, MB_ICONERROR);
- else
- GetMIDIMapper().Unserialize(ptr, size);
- break;
+
+ switch (code) // interpret field code
+ {
+ CASE('DT..', m_nDefaultTempo);
+ CASE('RPB.', m_nRowsPerBeat);
+ CASE('RPM.', m_nRowsPerMeasure);
+ CASE_NOTXM('C...', m_nChannels);
+ CASE('TM..', m_nTempoMode);
+ CASE('PMM.', m_nMixLevels);
+ CASE('CWV.', m_dwCreatedWithVersion);
+ CASE('LSWV', m_dwLastSavedWithVersion);
+ CASE('SPA.', m_nSamplePreAmp);
+ CASE('VSTV', m_nVSTiVolume);
+ CASE('DGV.', m_nDefaultGlobalVolume);
+ CASE_NOTXM('RP..', m_nRestartPos);
+ CASE('MSF.', m_ModFlags);
+ case 'MIMA': GetMIDIMapper().Unserialize(ptr, size); break;
case 'ChnS':
- if( ((ptr - lpStream) + DWORD(size) <= searchlimit) && (size <= 63*2) && (size % 2 == 0) )
+ if( (size <= 63*2) && (size % 2 == 0) )
{
const BYTE* pData = ptr;
- for(__int16 i = 0; i<size/2; i++, pData += 2) if(pData[0] != 0xFF)
+ STATIC_ASSERT(ARRAYELEMCOUNT(ChnSettings) >= 64);
+ const __int16 nLoopLimit = min(size/2, ARRAYELEMCOUNT(ChnSettings) - 64);
+ for(__int16 i = 0; i<nLoopLimit; i++, pData += 2) if(pData[0] != 0xFF)
{
ChnSettings[i+64].nVolume = pData[1];
ChnSettings[i+64].nPan = 128;
@@ -3745,11 +3775,30 @@
break;
}
- if (fadr != NULL && (ptr - lpStream) + DWORD(size) <= searchlimit) { // if field code recognized
- memcpy(fadr,ptr,size); // read field data
- }
+ if (fadr != NULL) // if field code recognized
+ memcpy(fadr,ptr,nMaxReadCount); // read field data
+
ptr += size; // jump field data
}
+
+ // Validate read values.
+ Limit(m_nDefaultTempo, GetModSpecifications().tempoMin, GetModSpecifications().tempoMax);
+ //m_nRowsPerBeat
+ //m_nRowsPerMeasure
+ LimitMax(m_nChannels, GetModSpecifications().channelsMax);
+ //m_nTempoMode
+ //m_nMixLevels
+ //m_dwCreatedWithVersion
+ //m_dwLastSavedWithVersion
+ //m_nSamplePreAmp
+ //m_nVSTiVolume
+ //m_nDefaultGlobalVolume);
+ //m_nRestartPos
+ //m_ModFlags
+
+
+ #undef CASE
+ #undef CASE_NOTXM
}
Modified: trunk/OpenMPT/soundlib/Load_xm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_xm.cpp 2009-06-12 16:25:54 UTC (rev 267)
+++ trunk/OpenMPT/soundlib/Load_xm.cpp 2009-06-12 17:32:08 UTC (rev 268)
@@ -611,54 +611,16 @@
// Leave if no extra instrument settings are available (end of file reached)
if(dwMemPos >= dwMemLength) return TRUE;
- // Get file pointer to match the first byte of extra settings informations
- BYTE * ptr = (BYTE *)(lpStream + dwMemPos);
+ bool bInterpretMptMade = false;
+ LPCBYTE ptr = lpStream + dwMemPos;
+ if(m_nInstruments)
+ ptr = LoadExtendedInstrumentProperties(ptr, lpStream+dwMemLength, &bInterpretMptMade);
- // Seek for supported extended settings header
- __int16 size = 0;
- __int32 code = (*((__int32 *)ptr));
+ LoadExtendedSongProperties(GetType(), ptr, lpStream, dwMemLength, &bInterpretMptMade);
- // Instrument extensions
- if( code == 'MPTX' && m_nInstruments ){
- ptr += sizeof(__int32); // jump extension header code
- while( (DWORD)(ptr - lpStream) < dwMemLength ){ //Loop 'till end of file looking for inst. extensions
+ if(bInterpretMptMade && m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 17, 2, 50))
+ SetModFlag(MSF_MIDICC_BUGEMULATION, true);
- code = (*((__int32 *)ptr)); // read field code
- if (code == 'MPTS') { //Reached song extensions, break out of this loop
- break;
- }
-
- ptr += sizeof(__int32); // jump field code
- size = (*((__int16 *)ptr)); // read field size
- ptr += sizeof(__int16); // jump field size
-
- for(UINT nins=1; nins<=m_nInstruments; nins++){
- if(Headers[nins]){
- // get field's adress in instrument's header
- BYTE * fadr = GetInstrumentHeaderFieldPointer(Headers[nins], code, size);
- // copy field data in instrument's header (except for keyboard mapping)
- if(fadr && code != 'K[..') memcpy(fadr,ptr,size);
- // jump field
- ptr += size;
- }
- }
- //end rewbs.instroVSTi
- }
- }
-// -! NEW_FEATURE#0027
-
- // Song extensions
- if( code == 'MPTS' )
- {
- LoadExtendedSongProperties(MOD_TYPE_XM, ptr, lpStream, dwMemLength);
- if(m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 17, 2, 50))
- SetModFlag(MSF_MIDICC_BUGEMULATION, true);
- }
-
-
-
-
-
return TRUE;
}
Modified: trunk/OpenMPT/soundlib/Sampleio.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sampleio.cpp 2009-06-12 16:25:54 UTC (rev 267)
+++ trunk/OpenMPT/soundlib/Sampleio.cpp 2009-06-12 17:32:08 UTC (rev 268)
@@ -1297,28 +1297,8 @@
// Leave if no extra instrument settings are available (end of file reached)
if(dwMemPos >= dwFileLength) return TRUE;
- // Compute current file pointer position
- BYTE * ptr = (BYTE *)(lpMemFile+dwMemPos);
+ ReadExtendedInstrumentProperties(penv, lpMemFile + dwMemPos, dwFileLength - dwMemPos);
- // Seek for supported extended settings header
- if( (*((__int32 *)ptr)) == 'MPTX' && penv ){
- __int16 size;
- __int32 code;
- ptr += sizeof(__int32); // jump extension header code
-
- while( (DWORD)(ptr - lpMemFile) < dwFileLength ){
- code = (*((__int32 *)ptr)); // read field code
- ptr += sizeof(__int32); // jump field code
- size = (*((__int16 *)ptr)); // read field size
- ptr += sizeof(__int16); // jump field size
-
- BYTE * fadr = GetInstrumentHeaderFieldPointer(penv, code, size);
- if(fadr && code != 'K[..') // copy field data in instrument's header
- memcpy(fadr,ptr,size); // (except for keyboard mapping)
- ptr += size; // jump field
- }
- }
-
// -! NEW_FEATURE#0027
return TRUE;
@@ -1827,28 +1807,8 @@
// Leave if no extra instrument settings are available (end of file reached)
if(dwMemPos >= dwFileLength) return TRUE;
- // Get file pointer to match the first byte of extra settings informations
- ptr = (BYTE *)(lpMemFile+dwMemPos);
+ ReadExtendedInstrumentProperties(penv, lpMemFile + dwMemPos, dwFileLength - dwMemPos);
- // Seek for supported extended settings header
- if( (*((__int32 *)ptr)) == 'MPTX' && penv ){
- __int16 size;
- __int32 code;
- ptr += sizeof(__int32); // jump extension header code
-
- while( (DWORD)(ptr - lpMemFile) < dwFileLength ){
- code = (*((__int32 *)ptr)); // read field code
- ptr += sizeof(__int32); // jump field code
- size = (*((__int16 *)ptr)); // read field size
- ptr += sizeof(__int16); // jump field size
-
- BYTE * fadr = GetInstrumentHeaderFieldPointer(penv, code, size);
- if(fadr && code != 'K[..') // copy field data in instrument's header
- memcpy(fadr,ptr,size); // (except for keyboard mapping)
- ptr += size; // jump field
- }
- }
-
// -! NEW_FEATURE#0027
return TRUE;
@@ -2043,6 +2003,73 @@
}
+
+bool IsValidSizeField(const LPCBYTE pData, const LPCBYTE pEnd, const int16 size)
+//------------------------------------------------------------------------------
+{
+ if(size < 0 || (uintptr_t)(pEnd - pData) < (uintptr_t)size)
+ return false;
+ else
+ return true;
+}
+
+
+void ReadInstrumentExtensionField(INSTRUMENTHEADER* penv, LPCBYTE& ptr, const int32 code, const int16 size)
+//------------------------------------------------------------------------------------------------------------
+{
+ // get field's address in instrument's header
+ BYTE* fadr = GetInstrumentHeaderFieldPointer(penv, code, size);
+
+ if(fadr && code != 'K[..') // copy field data in instrument's header
+ memcpy(fadr,ptr,size); // (except for keyboard mapping)
+ ptr += size; // jump field
+}
+
+
+void ReadExtendedInstrumentProperty(INSTRUMENTHEADER* penv, const int32 code, LPCBYTE& pData, const LPCBYTE pEnd)
+//---------------------------------------------------------------------------------------------------------------
+{
+ if(pEnd < pData || uintptr_t(pEnd - pData) < 2)
+ return;
+
+ int16 size;
+ memcpy(&size, pData, sizeof(size)); // read field size
+ pData += sizeof(size); // jump field size
+
+ if(IsValidSizeField(pData, pEnd, size) == false)
+ return;
+
+ ReadInstrumentExtensionField(penv, pData, code, size);
+}
+
+
+void ReadExtendedInstrumentProperties(INSTRUMENTHEADER* penv, const LPCBYTE pDataStart, const size_t nMemLength)
+//--------------------------------------------------------------------------------------------------------------
+{
+ if(penv == 0 || pDataStart == 0 || nMemLength < 4)
+ return;
+
+ LPCBYTE pData = pDataStart;
+ const LPCBYTE pEnd = pDataStart + nMemLength;
+
+ int32 code;
+ memcpy(&code, pData, sizeof(code));
+
+ // Seek for supported extended settings header
+ if( code == 'MPTX' )
+ {
+ pData += sizeof(code); // jump extension header code
+
+ while( (uintptr_t)(pData - pDataStart) <= nMemLength - 4)
+ {
+ memcpy(&code, pData, sizeof(code)); // read field code
+ pData += sizeof(code); // jump field code
+ ReadExtendedInstrumentProperty(penv, code, pData, pEnd);
+ }
+ }
+}
+
+
///////////////////////////////////////////////////////////////////////////////////////////////////
// 8SVX Samples
Modified: trunk/OpenMPT/soundlib/Sndfile.h
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.h 2009-06-12 16:25:54 UTC (rev 267)
+++ trunk/OpenMPT/soundlib/Sndfile.h 2009-06-12 17:32:08 UTC (rev 268)
@@ -1086,8 +1086,13 @@
void WriteInstrumentPropertyForAllInstruments(__int32 code, __int16 size, FILE* f, INSTRUMENTHEADER* instruments[], UINT nInstruments);
void SaveExtendedInstrumentProperties(INSTRUMENTHEADER *instruments[], UINT nInstruments, FILE* f);
void SaveExtendedSongProperties(FILE* f);
- void LoadExtendedSongProperties(const MODTYPE modtype, BYTE*& ptr, const BYTE* startpos, const size_t seachlimit);
+ void LoadExtendedSongProperties(const MODTYPE modtype, LPCBYTE ptr, const LPCBYTE startpos, const size_t seachlimit, bool* pInterpretMptMade = NULL);
+ // Reads extended instrument properties(XM/IT/MPTM).
+ // If no errors occur and song extension tag is found, returns pointer to the beginning
+ // of the tag, else returns NULL.
+ LPCBYTE LoadExtendedInstrumentProperties(const LPCBYTE pStart, const LPCBYTE pEnd, bool* pInterpretMptMade = NULL);
+
#endif // MODPLUG_NO_FILESAVE
// MOD Convert function
UINT GetBestSaveFormat() const;
@@ -1515,4 +1520,18 @@
#endif
+// Used in instrument/song extension reading to make sure the size field is valid.
+bool IsValidSizeField(const LPCBYTE pData, const LPCBYTE pEnd, const int16 size);
+
+// Read instrument property with 'code' and 'size' from 'ptr' to instrument 'penv'.
+// Note: (ptr, size) pair must be valid (e.g. can read 'size' bytes from 'ptr')
+void ReadInstrumentExtensionField(INSTRUMENTHEADER* penv, LPCBYTE& ptr, const int32 code, const int16 size);
+
+// Read instrument property with 'code' from 'pData' to instrument 'penv'.
+void ReadExtendedInstrumentProperty(INSTRUMENTHEADER* penv, const int32 code, LPCBYTE& pData, const LPCBYTE pEnd);
+
+// Read extended instrument properties from 'pDataStart' to instrument 'penv'.
+void ReadExtendedInstrumentProperties(INSTRUMENTHEADER* penv, const LPCBYTE pDataStart, const size_t nMemLength);
+
+
#endif
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2009-06-12 16:25:58
|
Revision: 267
http://modplug.svn.sourceforge.net/modplug/?rev=267&view=rev
Author: relabsoluness
Date: 2009-06-12 16:25:54 +0000 (Fri, 12 Jun 2009)
Log Message:
-----------
. XM/IT/MPTM: Fixed a bug in reading an extension. This broke the extension search after reading that entry, although the affected entry has been the last extension in the write order. (merged from rev. 263)
. Pattern tab: It's now possible to use the old note fade behaviour when playing notes in pattern tab(see setup->general). (merged from rev. 264)
. Pattern tab: Fixed wrong interpretations of "Old style pattern context menu"-option. (merged partly from rev. 262)
? Added validations to song/instrument extension reading and refactored related code.
Modified Paths:
--------------
branches/1.17.02.53x/mptrack/MainFrm.cpp
branches/1.17.02.53x/mptrack/Mainfrm.h
branches/1.17.02.53x/mptrack/Moptions.cpp
branches/1.17.02.53x/mptrack/View_pat.cpp
branches/1.17.02.53x/mptrack/misc_util.h
branches/1.17.02.53x/mptrack/version.h
branches/1.17.02.53x/soundlib/Load_it.cpp
branches/1.17.02.53x/soundlib/Load_xm.cpp
branches/1.17.02.53x/soundlib/Sampleio.cpp
branches/1.17.02.53x/soundlib/Sndfile.h
Modified: branches/1.17.02.53x/mptrack/MainFrm.cpp
===================================================================
--- branches/1.17.02.53x/mptrack/MainFrm.cpp 2009-06-09 19:59:04 UTC (rev 266)
+++ branches/1.17.02.53x/mptrack/MainFrm.cpp 2009-06-12 16:25:54 UTC (rev 267)
@@ -425,6 +425,9 @@
gnMidiPatternLen = GetPrivateProfileLong("MIDI Settings", "MidiImportPatLen", gnMidiPatternLen, iniFile);
m_dwPatternSetup = GetPrivateProfileDWord("Pattern Editor", "PatternSetup", m_dwPatternSetup, iniFile);
+ if(gcsPreviousVersion != "" && MptVersion::ToNum(gcsPreviousVersion) < MAKE_VERSION_NUMERIC(1,17,02,50))
+ m_dwPatternSetup |= PATTERN_NOTEFADE;
+
m_nRowSpacing = GetPrivateProfileDWord("Pattern Editor", "RowSpacing", 16, iniFile);
m_nRowSpacing2 = GetPrivateProfileDWord("Pattern Editor", "RowSpacing2", 4, iniFile);
gbLoopSong = GetPrivateProfileDWord("Pattern Editor", "LoopSong", true, iniFile);
@@ -541,6 +544,7 @@
RegQueryValueEx(key, "MidiSetup", NULL, &dwREG_DWORD, (LPBYTE)&m_dwMidiSetup, &dwDWORDSize);
RegQueryValueEx(key, "MidiDevice", NULL, &dwREG_DWORD, (LPBYTE)&m_nMidiDevice, &dwDWORDSize);
RegQueryValueEx(key, "PatternSetup", NULL, &dwREG_DWORD, (LPBYTE)&m_dwPatternSetup, &dwDWORDSize);
+ m_dwPatternSetup |= PATTERN_NOTEFADE; // Set flag to maintain old behaviour(was changed in 1.17.02.50).
RegQueryValueEx(key, "RowSpacing", NULL, &dwREG_DWORD, (LPBYTE)&m_nRowSpacing, &dwDWORDSize);
RegQueryValueEx(key, "RowSpacing2", NULL, &dwREG_DWORD, (LPBYTE)&m_nRowSpacing2, &dwDWORDSize);
RegQueryValueEx(key, "LoopSong", NULL, &dwREG_DWORD, (LPBYTE)&gbLoopSong, &dwDWORDSize);
Modified: branches/1.17.02.53x/mptrack/Mainfrm.h
===================================================================
--- branches/1.17.02.53x/mptrack/Mainfrm.h 2009-06-09 19:59:04 UTC (rev 266)
+++ branches/1.17.02.53x/mptrack/Mainfrm.h 2009-06-12 16:25:54 UTC (rev 267)
@@ -206,6 +206,7 @@
#define PATTERN_OLDCTXMENUSTYLE 0x800000
#define PATTERN_SYNCMUTE 0x1000000
#define PATTERN_AUTODELAY 0x2000000
+#define PATTERN_NOTEFADE 0x4000000
// Keyboard Setup
Modified: branches/1.17.02.53x/mptrack/Moptions.cpp
===================================================================
--- branches/1.17.02.53x/mptrack/Moptions.cpp 2009-06-09 19:59:04 UTC (rev 266)
+++ branches/1.17.02.53x/mptrack/Moptions.cpp 2009-06-12 16:25:54 UTC (rev 267)
@@ -601,6 +601,7 @@
OPTGEN_PATTERNCTXMENUSTYLE,
OPTGEN_SYNCMUTE,
OPTGEN_AUTODELAY,
+ OPTGEN_PATNOTEFADE,
OPTGEN_MAXOPTIONS
};
@@ -636,6 +637,7 @@
{"Old style pattern context menu", "Check this option to hide unavailable items in the pattern editor context menu. Uncheck to grey-out unavailable items instead."},
{"Maintain sample sync on mute", "Samples continue to be processed when channels are muted (like in IT2 and FT2)"},
{"Automatic delay commands", "Automatically insert appropriate note-delay commands when recording notes during live playback."},
+ {"Note fade on key up", "Enable to fade/stop notes on key up in pattern tab." }
};
@@ -697,6 +699,7 @@
case OPTGEN_SYNCMUTE: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_SYNCMUTE); break;
case OPTGEN_AUTODELAY: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_AUTODELAY); break;
+ case OPTGEN_PATNOTEFADE: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_NOTEFADE); break;
}
m_CheckList.SetCheck(i, (bCheck) ? TRUE : FALSE);
}
@@ -754,6 +757,7 @@
case OPTGEN_PATTERNCTXMENUSTYLE: mask = PATTERN_OLDCTXMENUSTYLE; break;
case OPTGEN_SYNCMUTE: mask = PATTERN_SYNCMUTE; break;
case OPTGEN_AUTODELAY: mask = PATTERN_AUTODELAY; break;
+ case OPTGEN_PATNOTEFADE: mask = PATTERN_NOTEFADE; break;
}
if (bCheck) CMainFrame::m_dwPatternSetup |= mask; else CMainFrame::m_dwPatternSetup &= ~mask;
Modified: branches/1.17.02.53x/mptrack/View_pat.cpp
===================================================================
--- branches/1.17.02.53x/mptrack/View_pat.cpp 2009-06-09 19:59:04 UTC (rev 266)
+++ branches/1.17.02.53x/mptrack/View_pat.cpp 2009-06-12 16:25:54 UTC (rev 267)
@@ -3787,8 +3787,12 @@
pModDoc->NoteOff(0, TRUE, ins, m_dwCursor & 0xFFFF);
}
else
- pModDoc->NoteOff(note, FALSE, ins, GetChanFromCursor(m_dwCursor));
- //pModDoc->NoteOff(note, TRUE, ins, (m_dwCursor & 0xFFFF) >> 3);
+ {
+ if(CMainFrame::m_dwPatternSetup & PATTERN_NOTEFADE)
+ pModDoc->NoteOff(note, TRUE, ins, GetChanFromCursor(m_dwCursor));
+ else
+ pModDoc->NoteOff(note, FALSE, ins, GetChanFromCursor(m_dwCursor));
+ }
}
//Enter note off in pattern?
@@ -4518,11 +4522,8 @@
bool CViewPattern::BuildMiscCtxMenu(HMENU hMenu, CInputHandler* ih)
//-----------------------------------------------------------------
{
- if (CMainFrame::m_dwPatternSetup & PATTERN_OLDCTXMENUSTYLE) return false;
-
AppendMenu(hMenu, MF_STRING, ID_SHOWTIMEATROW, "Show row play time\t" + ih->GetKeyTextFromCommand(kcTimeAtRow));
return true;
-
}
bool CViewPattern::BuildSelectionCtxMenu(HMENU hMenu, CInputHandler* ih)
@@ -4701,9 +4702,6 @@
bool CViewPattern::BuildChannelControlCtxMenu(HMENU hMenu)
//--------------------------------------------------------------------
{
- if (CMainFrame::m_dwPatternSetup&PATTERN_OLDCTXMENUSTYLE) return false;
- //Not doing the menuentries if opted to use old style menu style.
-
AppendMenu(hMenu, MF_SEPARATOR, 0, "");
AppendMenu(hMenu, MF_STRING, ID_PATTERN_DUPLICATECHANNEL, "Duplicate this channel");
Modified: branches/1.17.02.53x/mptrack/misc_util.h
===================================================================
--- branches/1.17.02.53x/mptrack/misc_util.h 2009-06-09 19:59:04 UTC (rev 266)
+++ branches/1.17.02.53x/mptrack/misc_util.h 2009-06-12 16:25:54 UTC (rev 267)
@@ -42,10 +42,34 @@
// Size of the array must be known at compile time.
template <size_t size>
inline void SetNullTerminator(char (&buffer)[size])
+//-------------------------------------------------
{
STATIC_ASSERT(size > 0);
buffer[size-1] = 0;
}
+// Limits 'val' to given range. If 'val' is less than 'lowerLimit', 'val' is set to value 'lowerLimit'.
+// Similarly if 'val' is greater than 'upperLimit', 'val' is set to value 'upperLimit'.
+// If 'lowerLimit' > 'upperLimit', 'val' won't be modified.
+template<class T, class C>
+inline void Limit(T& val, const C lowerLimit, const C upperLimit)
+//---------------------------------------------------------------
+{
+ if(lowerLimit > upperLimit) return;
+ if(val < lowerLimit) val = lowerLimit;
+ else if(val > upperLimit) val = upperLimit;
+}
+
+
+// Like Limit, but with upperlimit only.
+template<class T, class C>
+inline void LimitMax(T& val, const C upperLimit)
+//----------------------------------------------
+{
+ if(val > upperLimit)
+ val = upperLimit;
+}
+
+
#endif
Modified: branches/1.17.02.53x/mptrack/version.h
===================================================================
--- branches/1.17.02.53x/mptrack/version.h 2009-06-09 19:59:04 UTC (rev 266)
+++ branches/1.17.02.53x/mptrack/version.h 2009-06-12 16:25:54 UTC (rev 267)
@@ -15,7 +15,7 @@
#define VER_MAJORMAJOR 1
#define VER_MAJOR 17
#define VER_MINOR 02
-#define VER_MINORMINOR 53
+#define VER_MINORMINOR 54
//Creates version number from version parts that appears in version string.
//For example MAKE_VERSION_NUMERIC(1,17,02,28) gives version number of
Modified: branches/1.17.02.53x/soundlib/Load_it.cpp
===================================================================
--- branches/1.17.02.53x/soundlib/Load_it.cpp 2009-06-09 19:59:04 UTC (rev 266)
+++ branches/1.17.02.53x/soundlib/Load_it.cpp 2009-06-12 16:25:54 UTC (rev 267)
@@ -847,8 +847,7 @@
// Extra info data
__int32 fcode = 0;
- __int16 fsize = 0;
- BYTE * ptr = (BYTE *)(lpStream + streamPos);
+ LPCBYTE ptr = lpStream + min(streamPos, dwMemLength);
if (streamPos <= dwMemLength - 4) {
fcode = (*((__int32 *)ptr));
@@ -863,7 +862,7 @@
i = 1;
// parse file
- while( ptr + 4 <= (BYTE *)(lpStream + dwMemLength) && i <= m_nInstruments ){
+ while( uintptr_t(ptr - lpStream) <= dwMemLength - 4 && i <= m_nInstruments ){
fcode = (*((__int32 *)ptr)); // read field code
@@ -876,16 +875,7 @@
default:
ptr += sizeof(__int32); // jump field code
- if(ptr + 2 > (BYTE *)(lpStream + dwMemLength)) return FALSE;
- fsize = (*((__int16 *)ptr)); // read field size
- ptr += sizeof(__int16); // jump field size
- BYTE * fadr = GetInstrumentHeaderFieldPointer(Headers[i], fcode, fsize);
- if(fadr && fcode != 'K[..') // copy field data in instrument's header
- {
- if(ptr + fsize > (BYTE *)(lpStream + dwMemLength)) return FALSE;
- memcpy(fadr,ptr,fsize); // (except for keyboard mapping)
- }
- ptr += fsize; // jump field
+ ReadExtendedInstrumentProperty(Headers[i], fcode, ptr, lpStream + dwMemLength);
break;
}
}
@@ -893,7 +883,7 @@
//HACK: if we fail on i <= m_nInstruments above, arrive here without having set fcode as appropriate,
// hence the code duplication.
- if (ptr + 4 <= (BYTE *)(lpStream + dwMemLength)) {
+ if ( (uintptr_t)(ptr - lpStream) <= dwMemLength - 4 ) {
fcode = (*((__int32 *)ptr));
}
@@ -917,8 +907,8 @@
}
// -! NEW_FEATURE#0023
-BOOL CSoundFile::ReadIT(const BYTE *lpStream, const DWORD dwMemLength)
-//--------------------------------------------------------------
+BOOL CSoundFile::ReadIT(const LPCBYTE lpStream, const DWORD dwMemLength)
+//----------------------------------------------------------------------
{
ITFILEHEADER *pifh = (ITFILEHEADER *)lpStream;
@@ -1320,55 +1310,18 @@
ITSAMPLESTRUCT *pis = (ITSAMPLESTRUCT *)(lpStream+smppos[pifh->smpnum-1]);
dwMemPos = pis->samplepointer + lastSampleSize;
- // Get file pointer to match the first byte of extra settings informations __int16 size = 0;
- __int32 code = 0;
- __int16 size = 0;
- BYTE * ptr = NULL;
- if(dwMemPos < dwMemLength) {
- ptr = (BYTE *)(lpStream + dwMemPos);
- code = (*((__int32 *)ptr));;
+ // Load instrument and song extensions.
+ if(mptStartPos >= dwMemPos)
+ {
+ LPCBYTE ptr = LoadExtendedInstrumentProperties(lpStream + dwMemPos, lpStream + mptStartPos, &interpretModplugmade);
+ LoadExtendedSongProperties(GetType(), ptr, lpStream, mptStartPos, &interpretModplugmade);
}
-
- // Instrument extensions
- if( code == 'MPTX' ){
- interpretModplugmade = true;
- ptr += sizeof(__int32); // jump extension header code
- while( (DWORD)(ptr - lpStream) < mptStartPos ){ //Loop 'till beginning of end of file/mpt specific looking for inst. extensions
- code = (*((__int32 *)ptr)); // read field code
- if (code == 'MPTS') { //Reached song extensions, break out of this loop
- break;
- }
-
- ptr += sizeof(__int32); // jump field code
- size = (*((__int16 *)ptr)); // read field size
- ptr += sizeof(__int16); // jump field size
-
- for(UINT nins=1; nins<=m_nInstruments; nins++){
- if(Headers[nins]){
- // get field's adress in instrument's header
- BYTE * fadr = GetInstrumentHeaderFieldPointer(Headers[nins], code, size);
- // copy field data in instrument's header (except for keyboard mapping)
- if(fadr && code != 'K[..') memcpy(fadr,ptr,size);
- // jump field
- ptr += size;
- }
- }
- //end rewbs.instroVSTi
- }
- }
// -! NEW_FEATURE#0027
- // Song extensions
- if( code == 'MPTS' )
- {
- interpretModplugmade = true;
- LoadExtendedSongProperties(GetType(), ptr, lpStream, mptStartPos);
- }
+ // Reading Patterns
Patterns.ResizeArray(max(MAX_PATTERNS, npatterns));
-
- // Reading Patterns
for (UINT npat=0; npat<npatterns; npat++)
{
if ((!patpos[npat]) || ((DWORD)patpos[npat] >= dwMemLength - 4))
@@ -3674,53 +3627,143 @@
return;
}
+LPCBYTE CSoundFile::LoadExtendedInstrumentProperties(const LPCBYTE pStart,
+ const LPCBYTE pEnd,
+ bool* pInterpretMptMade)
+//---------------------------------------------------------------------------
+{
+ if( pStart == NULL || pEnd <= pStart || uintptr_t(pEnd - pStart) < 4)
+ return NULL;
-void CSoundFile::LoadExtendedSongProperties(const MODTYPE modtype, BYTE*& ptr, const BYTE* lpStream, const size_t searchlimit)
-//--------------------------------------------------
+ int32 code = 0;
+ int16 size = 0;
+ LPCBYTE ptr = pStart;
+
+ memcpy(&code, ptr, sizeof(code));
+
+ if(code != 'MPTX')
+ return NULL;
+
+ // Found MPTX, interpret the file MPT made.
+ if(pInterpretMptMade != NULL)
+ *pInterpretMptMade = true;
+
+ ptr += sizeof(int32); // jump extension header code
+ while( ptr < pEnd && uintptr_t(pEnd-ptr) >= 4) //Loop 'till beginning of end of file/mpt specific looking for inst. extensions
+ {
+ memcpy(&code, ptr, sizeof(code)); // read field code
+ if (code == 'MPTS') //Reached song extensions, break out of this loop
+ return ptr;
+
+ ptr += sizeof(code); // jump field code
+
+ if((uintptr_t)(pEnd - ptr) < 2)
+ return NULL;
+
+ memcpy(&size, ptr, sizeof(size)); // read field size
+ ptr += sizeof(size); // jump field size
+
+ if(IsValidSizeField(ptr, pEnd, size) == false)
+ return NULL;
+
+ for(UINT nins=1; nins<=m_nInstruments; nins++)
+ {
+ if(Headers[nins])
+ ReadInstrumentExtensionField(Headers[nins], ptr, code, size);
+ }
+ }
+
+ return NULL;
+}
+
+
+void CSoundFile::LoadExtendedSongProperties(const MODTYPE modtype,
+ LPCBYTE ptr,
+ const LPCBYTE lpStream,
+ const size_t searchlimit,
+ bool* pInterpretMptMade)
+//-------------------------------------------------------------------
{
+ if(searchlimit < 6 || ptr == NULL || ptr < lpStream || uintptr_t(ptr - lpStream) > searchlimit - 4)
+ return;
+
+ const LPCBYTE pEnd = lpStream + searchlimit;
+
int32 code = 0;
int16 size = 0;
- ptr += sizeof(int32); // jump extension header code
- while( (DWORD)(ptr + 6 - lpStream) <= searchlimit ) //Loop until given limit.
+
+ memcpy(&code, ptr, sizeof(code));
+
+ if(code != 'MPTS')
+ return;
+
+ // Found MPTS, interpret the file MPT made.
+ if(pInterpretMptMade != NULL)
+ *pInterpretMptMade = true;
+
+
+ // Case macros.
+ #define CASE(id, data) \
+ case id: fadr = reinterpret_cast<BYTE*>(&data); nMaxReadCount = min(size, sizeof(data)); break;
+ #define CASE_NOTXM(id, data) \
+ case id: if(modtype != MOD_TYPE_XM) {fadr = reinterpret_cast<BYTE*>(&data); nMaxReadCount = min(size, sizeof(data));} break;
+
+ ptr += sizeof(code); // jump extension header code
+ while( uintptr_t(ptr - lpStream) <= searchlimit-6 ) //Loop until given limit.
{
- code = (*((__int32 *)ptr)); // read field code
- ptr += sizeof(__int32); // jump field code
- size = (*((__int16 *)ptr)); // read field size
- if(size < 0) break;
- ptr += sizeof(__int16); // jump field size
+ code = (*((int32 *)ptr)); // read field code
+ ptr += sizeof(int32); // jump field code
+ size = (*((int16 *)ptr)); // read field size
+ ptr += sizeof(int16); // jump field size
+ if(IsValidSizeField(ptr, pEnd, size) == false)
+ break;
+
+ size_t nMaxReadCount = 0;
BYTE * fadr = NULL;
- switch (code) { // interpret field code
- case 'DT..': fadr = reinterpret_cast<BYTE*>(&m_nDefaultTempo); break;
- case 'RPB.': fadr = reinterpret_cast<BYTE*>(&m_nRowsPerBeat); break;
- case 'RPM.': fadr = reinterpret_cast<BYTE*>(&m_nRowsPerMeasure); break;
- case 'C...': if(modtype != MOD_TYPE_XM) fadr = reinterpret_cast<BYTE*>(&m_nChannels); break;
- case 'TM..': fadr = reinterpret_cast<BYTE*>(&m_nTempoMode); break;
- case 'PMM.': fadr = reinterpret_cast<BYTE*>(&m_nMixLevels); break;
- case 'CWV.': fadr = reinterpret_cast<BYTE*>(&m_dwCreatedWithVersion); break;
- case 'LSWV': fadr = reinterpret_cast<BYTE*>(&m_dwLastSavedWithVersion); break;
- case 'SPA.': fadr = reinterpret_cast<BYTE*>(&m_nSamplePreAmp); break;
- case 'VSTV': fadr = reinterpret_cast<BYTE*>(&m_nVSTiVolume); break;
- case 'DGV.': fadr = reinterpret_cast<BYTE*>(&m_nDefaultGlobalVolume); break;
- case 'RP..': if(modtype != MOD_TYPE_XM) fadr = reinterpret_cast<BYTE*>(&m_nRestartPos); break;
- case 'MSF.': fadr = reinterpret_cast<BYTE*>(&m_ModFlags); break;
- case 'MIMA':
- if(DWORD(ptr - lpStream + DWORD(size)) > searchlimit)
- MessageBox(NULL, "Error: Bad MIMA datasizefield", NULL, MB_ICONERROR);
- else
- {
- GetMIDIMapper().Unserialize(ptr, size);
- ptr += size;
- }
- break;
+ switch (code) // interpret field code
+ {
+ CASE('DT..', m_nDefaultTempo);
+ CASE('RPB.', m_nRowsPerBeat);
+ CASE('RPM.', m_nRowsPerMeasure);
+ CASE_NOTXM('C...', m_nChannels);
+ CASE('TM..', m_nTempoMode);
+ CASE('PMM.', m_nMixLevels);
+ CASE('CWV.', m_dwCreatedWithVersion);
+ CASE('LSWV', m_dwLastSavedWithVersion);
+ CASE('SPA.', m_nSamplePreAmp);
+ CASE('VSTV', m_nVSTiVolume);
+ CASE('DGV.', m_nDefaultGlobalVolume);
+ CASE_NOTXM('RP..', m_nRestartPos);
+ CASE('MSF.', m_ModFlags);
+ case 'MIMA': GetMIDIMapper().Unserialize(ptr, size); break;
}
- if (fadr != NULL && ptr - lpStream + DWORD(size) <= searchlimit) { // if field code recognized
- memcpy(fadr,ptr,size); // read field data
- }
+ if (fadr != NULL) // if field code recognized
+ memcpy(fadr,ptr,nMaxReadCount); // read field data
+
ptr += size; // jump field data
}
+
+ // Validate read values.
+ Limit(m_nDefaultTempo, GetModSpecifications().tempoMin, GetModSpecifications().tempoMax);
+ //m_nRowsPerBeat
+ //m_nRowsPerMeasure
+ LimitMax(m_nChannels, GetModSpecifications().channelsMax);
+ //m_nTempoMode
+ //m_nMixLevels
+ //m_dwCreatedWithVersion
+ //m_dwLastSavedWithVersion
+ //m_nSamplePreAmp
+ //m_nVSTiVolume
+ //m_nDefaultGlobalVolume);
+ //m_nRestartPos
+ //m_ModFlags
+
+
+ #undef CASE
+ #undef CASE_NOTXM
}
Modified: branches/1.17.02.53x/soundlib/Load_xm.cpp
===================================================================
--- branches/1.17.02.53x/soundlib/Load_xm.cpp 2009-06-09 19:59:04 UTC (rev 266)
+++ branches/1.17.02.53x/soundlib/Load_xm.cpp 2009-06-12 16:25:54 UTC (rev 267)
@@ -611,54 +611,16 @@
// Leave if no extra instrument settings are available (end of file reached)
if(dwMemPos >= dwMemLength) return TRUE;
- // Get file pointer to match the first byte of extra settings informations
- BYTE * ptr = (BYTE *)(lpStream + dwMemPos);
+ bool bInterpretMptMade = false;
+ LPCBYTE ptr = lpStream + dwMemPos;
+ if(m_nInstruments)
+ ptr = LoadExtendedInstrumentProperties(ptr, lpStream+dwMemLength, &bInterpretMptMade);
- // Seek for supported extended settings header
- __int16 size = 0;
- __int32 code = (*((__int32 *)ptr));
+ LoadExtendedSongProperties(GetType(), ptr, lpStream, dwMemLength, &bInterpretMptMade);
- // Instrument extensions
- if( code == 'MPTX' && m_nInstruments ){
- ptr += sizeof(__int32); // jump extension header code
- while( (DWORD)(ptr - lpStream) < dwMemLength ){ //Loop 'till end of file looking for inst. extensions
+ if(bInterpretMptMade && m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 17, 2, 50))
+ SetModFlag(MSF_MIDICC_BUGEMULATION, true);
- code = (*((__int32 *)ptr)); // read field code
- if (code == 'MPTS') { //Reached song extensions, break out of this loop
- break;
- }
-
- ptr += sizeof(__int32); // jump field code
- size = (*((__int16 *)ptr)); // read field size
- ptr += sizeof(__int16); // jump field size
-
- for(UINT nins=1; nins<=m_nInstruments; nins++){
- if(Headers[nins]){
- // get field's adress in instrument's header
- BYTE * fadr = GetInstrumentHeaderFieldPointer(Headers[nins], code, size);
- // copy field data in instrument's header (except for keyboard mapping)
- if(fadr && code != 'K[..') memcpy(fadr,ptr,size);
- // jump field
- ptr += size;
- }
- }
- //end rewbs.instroVSTi
- }
- }
-// -! NEW_FEATURE#0027
-
- // Song extensions
- if( code == 'MPTS' )
- {
- LoadExtendedSongProperties(MOD_TYPE_XM, ptr, lpStream, dwMemLength);
- if(m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 17, 2, 50))
- SetModFlag(MSF_MIDICC_BUGEMULATION, true);
- }
-
-
-
-
-
return TRUE;
}
Modified: branches/1.17.02.53x/soundlib/Sampleio.cpp
===================================================================
--- branches/1.17.02.53x/soundlib/Sampleio.cpp 2009-06-09 19:59:04 UTC (rev 266)
+++ branches/1.17.02.53x/soundlib/Sampleio.cpp 2009-06-12 16:25:54 UTC (rev 267)
@@ -1297,28 +1297,8 @@
// Leave if no extra instrument settings are available (end of file reached)
if(dwMemPos >= dwFileLength) return TRUE;
- // Compute current file pointer position
- BYTE * ptr = (BYTE *)(lpMemFile+dwMemPos);
+ ReadExtendedInstrumentProperties(penv, lpMemFile + dwMemPos, dwFileLength - dwMemPos);
- // Seek for supported extended settings header
- if( (*((__int32 *)ptr)) == 'MPTX' && penv ){
- __int16 size;
- __int32 code;
- ptr += sizeof(__int32); // jump extension header code
-
- while( (DWORD)(ptr - lpMemFile) < dwFileLength ){
- code = (*((__int32 *)ptr)); // read field code
- ptr += sizeof(__int32); // jump field code
- size = (*((__int16 *)ptr)); // read field size
- ptr += sizeof(__int16); // jump field size
-
- BYTE * fadr = GetInstrumentHeaderFieldPointer(penv, code, size);
- if(fadr && code != 'K[..') // copy field data in instrument's header
- memcpy(fadr,ptr,size); // (except for keyboard mapping)
- ptr += size; // jump field
- }
- }
-
// -! NEW_FEATURE#0027
return TRUE;
@@ -1827,28 +1807,8 @@
// Leave if no extra instrument settings are available (end of file reached)
if(dwMemPos >= dwFileLength) return TRUE;
- // Get file pointer to match the first byte of extra settings informations
- ptr = (BYTE *)(lpMemFile+dwMemPos);
+ ReadExtendedInstrumentProperties(penv, lpMemFile + dwMemPos, dwFileLength - dwMemPos);
- // Seek for supported extended settings header
- if( (*((__int32 *)ptr)) == 'MPTX' && penv ){
- __int16 size;
- __int32 code;
- ptr += sizeof(__int32); // jump extension header code
-
- while( (DWORD)(ptr - lpMemFile) < dwFileLength ){
- code = (*((__int32 *)ptr)); // read field code
- ptr += sizeof(__int32); // jump field code
- size = (*((__int16 *)ptr)); // read field size
- ptr += sizeof(__int16); // jump field size
-
- BYTE * fadr = GetInstrumentHeaderFieldPointer(penv, code, size);
- if(fadr && code != 'K[..') // copy field data in instrument's header
- memcpy(fadr,ptr,size); // (except for keyboard mapping)
- ptr += size; // jump field
- }
- }
-
// -! NEW_FEATURE#0027
return TRUE;
@@ -2043,6 +2003,73 @@
}
+
+bool IsValidSizeField(const LPCBYTE pData, const LPCBYTE pEnd, const int16 size)
+//------------------------------------------------------------------------------
+{
+ if(size < 0 || (uintptr_t)(pEnd - pData) < (uintptr_t)size)
+ return false;
+ else
+ return true;
+}
+
+
+void ReadInstrumentExtensionField(INSTRUMENTHEADER* penv, LPCBYTE& ptr, const int32 code, const int16 size)
+//------------------------------------------------------------------------------------------------------------
+{
+ // get field's address in instrument's header
+ BYTE* fadr = GetInstrumentHeaderFieldPointer(penv, code, size);
+
+ if(fadr && code != 'K[..') // copy field data in instrument's header
+ memcpy(fadr,ptr,size); // (except for keyboard mapping)
+ ptr += size; // jump field
+}
+
+
+void ReadExtendedInstrumentProperty(INSTRUMENTHEADER* penv, const int32 code, LPCBYTE& pData, const LPCBYTE pEnd)
+//---------------------------------------------------------------------------------------------------------------
+{
+ if(pEnd < pData || uintptr_t(pEnd - pData) < 2)
+ return;
+
+ int16 size;
+ memcpy(&size, pData, sizeof(size)); // read field size
+ pData += sizeof(size); // jump field size
+
+ if(IsValidSizeField(pData, pEnd, size) == false)
+ return;
+
+ ReadInstrumentExtensionField(penv, pData, code, size);
+}
+
+
+void ReadExtendedInstrumentProperties(INSTRUMENTHEADER* penv, const LPCBYTE pDataStart, const size_t nMemLength)
+//--------------------------------------------------------------------------------------------------------------
+{
+ if(penv == 0 || pDataStart == 0 || nMemLength < 4)
+ return;
+
+ LPCBYTE pData = pDataStart;
+ const LPCBYTE pEnd = pDataStart + nMemLength;
+
+ int32 code;
+ memcpy(&code, pData, sizeof(code));
+
+ // Seek for supported extended settings header
+ if( code == 'MPTX' )
+ {
+ pData += sizeof(code); // jump extension header code
+
+ while( (uintptr_t)(pData - pDataStart) <= nMemLength - 4)
+ {
+ memcpy(&code, pData, sizeof(code)); // read field code
+ pData += sizeof(code); // jump field code
+ ReadExtendedInstrumentProperty(penv, code, pData, pEnd);
+ }
+ }
+}
+
+
///////////////////////////////////////////////////////////////////////////////////////////////////
// 8SVX Samples
Modified: branches/1.17.02.53x/soundlib/Sndfile.h
===================================================================
--- branches/1.17.02.53x/soundlib/Sndfile.h 2009-06-09 19:59:04 UTC (rev 266)
+++ branches/1.17.02.53x/soundlib/Sndfile.h 2009-06-12 16:25:54 UTC (rev 267)
@@ -1086,8 +1086,13 @@
void WriteInstrumentPropertyForAllInstruments(__int32 code, __int16 size, FILE* f, INSTRUMENTHEADER* instruments[], UINT nInstruments);
void SaveExtendedInstrumentProperties(INSTRUMENTHEADER *instruments[], UINT nInstruments, FILE* f);
void SaveExtendedSongProperties(FILE* f);
- void LoadExtendedSongProperties(const MODTYPE modtype, BYTE*& ptr, const BYTE* startpos, const size_t seachlimit);
+ void LoadExtendedSongProperties(const MODTYPE modtype, LPCBYTE ptr, const LPCBYTE startpos, const size_t seachlimit, bool* pInterpretMptMade = NULL);
+ // Reads extended instrument properties(XM/IT/MPTM).
+ // If no errors occur and song extension tag is found, returns pointer to the beginning
+ // of the tag, else returns NULL.
+ LPCBYTE LoadExtendedInstrumentProperties(const LPCBYTE pStart, const LPCBYTE pEnd, bool* pInterpretMptMade = NULL);
+
#endif // MODPLUG_NO_FILESAVE
// MOD Convert function
UINT GetBestSaveFormat() const;
@@ -1515,4 +1520,18 @@
#endif
+// Used in instrument/song extension reading to make sure the size field is valid.
+bool IsValidSizeField(const LPCBYTE pData, const LPCBYTE pEnd, const int16 size);
+
+// Read instrument property with 'code' and 'size' from 'ptr' to instrument 'penv'.
+// Note: (ptr, size) pair must be valid (e.g. can read 'size' bytes from 'ptr')
+void ReadInstrumentExtensionField(INSTRUMENTHEADER* penv, LPCBYTE& ptr, const int32 code, const int16 size);
+
+// Read instrument property with 'code' from 'pData' to instrument 'penv'.
+void ReadExtendedInstrumentProperty(INSTRUMENTHEADER* penv, const int32 code, LPCBYTE& pData, const LPCBYTE pEnd);
+
+// Read extended instrument properties from 'pDataStart' to instrument 'penv'.
+void ReadExtendedInstrumentProperties(INSTRUMENTHEADER* penv, const LPCBYTE pDataStart, const size_t nMemLength);
+
+
#endif
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2009-06-09 19:59:10
|
Revision: 266
http://modplug.svn.sourceforge.net/modplug/?rev=266&view=rev
Author: relabsoluness
Date: 2009-06-09 19:59:04 +0000 (Tue, 09 Jun 2009)
Log Message:
-----------
Branch for 1.17.02.xx versions starting from 1.17.02.53.
Added Paths:
-----------
branches/1.17.02.53x/
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2009-06-08 21:23:56
|
Revision: 265
http://modplug.svn.sourceforge.net/modplug/?rev=265&view=rev
Author: relabsoluness
Date: 2009-06-08 21:22:25 +0000 (Mon, 08 Jun 2009)
Log Message:
-----------
. General tab: Fixes channel controls that got badly broken in rev. 263.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/View_gen.cpp
Modified: trunk/OpenMPT/mptrack/View_gen.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_gen.cpp 2009-06-08 19:25:03 UTC (rev 264)
+++ trunk/OpenMPT/mptrack/View_gen.cpp 2009-06-08 21:22:25 UTC (rev 265)
@@ -662,7 +662,7 @@
short int pos;
LockControls();
- const UINT nLoopLimit = pModDoc->GetSoundFile()->GetNumChannels() - nChn;
+ const UINT nLoopLimit = min(4, pModDoc->GetSoundFile()->GetNumChannels() - nChn);
for (UINT iCh=0; iCh<nLoopLimit; iCh++)
{
// Volume sliders
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2009-06-08 19:27:34
|
Revision: 264
http://modplug.svn.sourceforge.net/modplug/?rev=264&view=rev
Author: relabsoluness
Date: 2009-06-08 19:25:03 +0000 (Mon, 08 Jun 2009)
Log Message:
-----------
. Pattern tab: It's now possible to use the old note fade behaviour when playing notes in pattern tab(see setup->general).
Modified Paths:
--------------
trunk/OpenMPT/mptrack/MainFrm.cpp
trunk/OpenMPT/mptrack/Mainfrm.h
trunk/OpenMPT/mptrack/Moptions.cpp
trunk/OpenMPT/mptrack/View_pat.cpp
Modified: trunk/OpenMPT/mptrack/MainFrm.cpp
===================================================================
--- trunk/OpenMPT/mptrack/MainFrm.cpp 2009-06-06 19:11:18 UTC (rev 263)
+++ trunk/OpenMPT/mptrack/MainFrm.cpp 2009-06-08 19:25:03 UTC (rev 264)
@@ -425,6 +425,9 @@
gnMidiPatternLen = GetPrivateProfileLong("MIDI Settings", "MidiImportPatLen", gnMidiPatternLen, iniFile);
m_dwPatternSetup = GetPrivateProfileDWord("Pattern Editor", "PatternSetup", m_dwPatternSetup, iniFile);
+ if(gcsPreviousVersion != "" && MptVersion::ToNum(gcsPreviousVersion) < MAKE_VERSION_NUMERIC(1,17,02,50))
+ m_dwPatternSetup |= PATTERN_NOTEFADE;
+
m_nRowSpacing = GetPrivateProfileDWord("Pattern Editor", "RowSpacing", 16, iniFile);
m_nRowSpacing2 = GetPrivateProfileDWord("Pattern Editor", "RowSpacing2", 4, iniFile);
gbLoopSong = GetPrivateProfileDWord("Pattern Editor", "LoopSong", true, iniFile);
@@ -541,6 +544,7 @@
RegQueryValueEx(key, "MidiSetup", NULL, &dwREG_DWORD, (LPBYTE)&m_dwMidiSetup, &dwDWORDSize);
RegQueryValueEx(key, "MidiDevice", NULL, &dwREG_DWORD, (LPBYTE)&m_nMidiDevice, &dwDWORDSize);
RegQueryValueEx(key, "PatternSetup", NULL, &dwREG_DWORD, (LPBYTE)&m_dwPatternSetup, &dwDWORDSize);
+ m_dwPatternSetup |= PATTERN_NOTEFADE; // Set flag to maintain old behaviour(was changed in 1.17.02.50).
RegQueryValueEx(key, "RowSpacing", NULL, &dwREG_DWORD, (LPBYTE)&m_nRowSpacing, &dwDWORDSize);
RegQueryValueEx(key, "RowSpacing2", NULL, &dwREG_DWORD, (LPBYTE)&m_nRowSpacing2, &dwDWORDSize);
RegQueryValueEx(key, "LoopSong", NULL, &dwREG_DWORD, (LPBYTE)&gbLoopSong, &dwDWORDSize);
Modified: trunk/OpenMPT/mptrack/Mainfrm.h
===================================================================
--- trunk/OpenMPT/mptrack/Mainfrm.h 2009-06-06 19:11:18 UTC (rev 263)
+++ trunk/OpenMPT/mptrack/Mainfrm.h 2009-06-08 19:25:03 UTC (rev 264)
@@ -206,6 +206,7 @@
#define PATTERN_OLDCTXMENUSTYLE 0x800000
#define PATTERN_SYNCMUTE 0x1000000
#define PATTERN_AUTODELAY 0x2000000
+#define PATTERN_NOTEFADE 0x4000000
// Keyboard Setup
Modified: trunk/OpenMPT/mptrack/Moptions.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Moptions.cpp 2009-06-06 19:11:18 UTC (rev 263)
+++ trunk/OpenMPT/mptrack/Moptions.cpp 2009-06-08 19:25:03 UTC (rev 264)
@@ -601,6 +601,7 @@
OPTGEN_PATTERNCTXMENUSTYLE,
OPTGEN_SYNCMUTE,
OPTGEN_AUTODELAY,
+ OPTGEN_PATNOTEFADE,
OPTGEN_MAXOPTIONS
};
@@ -636,6 +637,7 @@
{"Old style pattern context menu", "Check this option to hide unavailable items in the pattern editor context menu. Uncheck to grey-out unavailable items instead."},
{"Maintain sample sync on mute", "Samples continue to be processed when channels are muted (like in IT2 and FT2)"},
{"Automatic delay commands", "Automatically insert appropriate note-delay commands when recording notes during live playback."},
+ {"Note fade on key up", "Enable to fade/stop notes on key up in pattern tab." }
};
@@ -697,6 +699,7 @@
case OPTGEN_SYNCMUTE: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_SYNCMUTE); break;
case OPTGEN_AUTODELAY: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_AUTODELAY); break;
+ case OPTGEN_PATNOTEFADE: bCheck = (CMainFrame::m_dwPatternSetup & PATTERN_NOTEFADE); break;
}
m_CheckList.SetCheck(i, (bCheck) ? TRUE : FALSE);
}
@@ -754,6 +757,7 @@
case OPTGEN_PATTERNCTXMENUSTYLE: mask = PATTERN_OLDCTXMENUSTYLE; break;
case OPTGEN_SYNCMUTE: mask = PATTERN_SYNCMUTE; break;
case OPTGEN_AUTODELAY: mask = PATTERN_AUTODELAY; break;
+ case OPTGEN_PATNOTEFADE: mask = PATTERN_NOTEFADE; break;
}
if (bCheck) CMainFrame::m_dwPatternSetup |= mask; else CMainFrame::m_dwPatternSetup &= ~mask;
Modified: trunk/OpenMPT/mptrack/View_pat.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_pat.cpp 2009-06-06 19:11:18 UTC (rev 263)
+++ trunk/OpenMPT/mptrack/View_pat.cpp 2009-06-08 19:25:03 UTC (rev 264)
@@ -3804,8 +3804,12 @@
pModDoc->NoteOff(0, TRUE, ins, m_dwCursor & 0xFFFF);
}
else
- pModDoc->NoteOff(note, FALSE, ins, GetChanFromCursor(m_dwCursor));
- //pModDoc->NoteOff(note, TRUE, ins, (m_dwCursor & 0xFFFF) >> 3);
+ {
+ if(CMainFrame::m_dwPatternSetup & PATTERN_NOTEFADE)
+ pModDoc->NoteOff(note, TRUE, ins, GetChanFromCursor(m_dwCursor));
+ else
+ pModDoc->NoteOff(note, FALSE, ins, GetChanFromCursor(m_dwCursor));
+ }
}
//Enter note off in pattern?
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2009-06-06 19:11:22
|
Revision: 263
http://modplug.svn.sourceforge.net/modplug/?rev=263&view=rev
Author: relabsoluness
Date: 2009-06-06 19:11:18 +0000 (Sat, 06 Jun 2009)
Log Message:
-----------
+ IT/MTPM: Channel settings(vol&pan) for channels after 64 will now be saved in the file.
. XM/IT/MPTM: Fixed a bug in reading an extension. This broke the extension search after reading that entry, although the affected entry has been the last extension in the write order.
? Minor tweaks.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/View_gen.cpp
trunk/OpenMPT/soundlib/Load_it.cpp
trunk/OpenMPT/soundlib/Sndfile.cpp
Modified: trunk/OpenMPT/mptrack/View_gen.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_gen.cpp 2009-06-06 18:49:52 UTC (rev 262)
+++ trunk/OpenMPT/mptrack/View_gen.cpp 2009-06-06 19:11:18 UTC (rev 263)
@@ -656,13 +656,14 @@
pModDoc = GetDocument();
nChn = m_nActiveTab * 4;
- if ((pModDoc) && (!IsLocked()) && (nChn < 64))
+ if ((pModDoc) && (!IsLocked()) && (nChn < MAX_BASECHANNELS))
{
BOOL bUpdate = FALSE;
short int pos;
LockControls();
- for (UINT iCh=0; iCh<4; iCh++)
+ const UINT nLoopLimit = pModDoc->GetSoundFile()->GetNumChannels() - nChn;
+ for (UINT iCh=0; iCh<nLoopLimit; iCh++)
{
// Volume sliders
pos = (short int)m_sbVolume[iCh].GetPos();
Modified: trunk/OpenMPT/soundlib/Load_it.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_it.cpp 2009-06-06 18:49:52 UTC (rev 262)
+++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-06-06 19:11:18 UTC (rev 263)
@@ -917,8 +917,8 @@
}
// -! NEW_FEATURE#0023
-BOOL CSoundFile::ReadIT(const BYTE *lpStream, const DWORD dwMemLength)
-//--------------------------------------------------------------
+BOOL CSoundFile::ReadIT(const LPCBYTE lpStream, const DWORD dwMemLength)
+//----------------------------------------------------------------------
{
ITFILEHEADER *pifh = (ITFILEHEADER *)lpStream;
@@ -3595,6 +3595,23 @@
fwrite(&size, 1, sizeof(__int16), f);
fwrite(&m_nChannels, 1, size, f);
+ if(TypeIsIT_MPT() && m_nChannels > 64) //IT header has room only for 64 channels. Save the
+ { //settings that do not fit to the header here as an extension.
+ code = 'ChnS';
+ fwrite(&code, 1, sizeof(__int32), f);
+ size = (m_nChannels - 64)*2;
+ fwrite(&size, 1, sizeof(__int16), f);
+ for(UINT ich = 64; ich < m_nChannels; ich++)
+ {
+ BYTE panvol[2];
+ panvol[0] = ChnSettings[ich].nPan >> 2;
+ if (ChnSettings[ich].dwFlags & CHN_SURROUND) panvol[0] = 100;
+ if (ChnSettings[ich].dwFlags & CHN_MUTE) panvol[0] |= 0x80;
+ panvol[1] = ChnSettings[ich].nVolume;
+ fwrite(&panvol, sizeof(panvol), 1, f);
+ }
+ }
+
code = 'TM..'; //write m_nTempoMode
fwrite(&code, 1, sizeof(__int32), f);
size = sizeof(m_nTempoMode);
@@ -3675,13 +3692,13 @@
}
-void CSoundFile::LoadExtendedSongProperties(const MODTYPE modtype, BYTE*& ptr, const BYTE* lpStream, const size_t searchlimit)
+void CSoundFile::LoadExtendedSongProperties(const MODTYPE modtype, BYTE*& ptr, const LPCBYTE lpStream, const size_t searchlimit)
//--------------------------------------------------
{
int32 code = 0;
int16 size = 0;
ptr += sizeof(int32); // jump extension header code
- while( (DWORD)(ptr + 6 - lpStream) <= searchlimit ) //Loop until given limit.
+ while( (DWORD)((ptr + 6) - lpStream) <= searchlimit ) //Loop until given limit.
{
code = (*((__int32 *)ptr)); // read field code
ptr += sizeof(__int32); // jump field code
@@ -3708,15 +3725,27 @@
if(DWORD(ptr - lpStream + DWORD(size)) > searchlimit)
MessageBox(NULL, "Error: Bad MIMA datasizefield", NULL, MB_ICONERROR);
else
+ GetMIDIMapper().Unserialize(ptr, size);
+ break;
+ case 'ChnS':
+ if( ((ptr - lpStream) + DWORD(size) <= searchlimit) && (size <= 63*2) && (size % 2 == 0) )
{
- GetMIDIMapper().Unserialize(ptr, size);
- ptr += size;
+ const BYTE* pData = ptr;
+ for(__int16 i = 0; i<size/2; i++, pData += 2) if(pData[0] != 0xFF)
+ {
+ ChnSettings[i+64].nVolume = pData[1];
+ ChnSettings[i+64].nPan = 128;
+ if (pData[0] & 0x80) ChnSettings[i+64].dwFlags |= CHN_MUTE;
+ const UINT n = pData[0] & 0x7F;
+ if (n <= 64) ChnSettings[i+64].nPan = n << 2;
+ if (n == 100) ChnSettings[i+64].dwFlags |= CHN_SURROUND;
+ }
}
break;
}
- if (fadr != NULL && ptr - lpStream + DWORD(size) <= searchlimit) { // if field code recognized
+ if (fadr != NULL && (ptr - lpStream) + DWORD(size) <= searchlimit) { // if field code recognized
memcpy(fadr,ptr,size); // read field data
}
ptr += size; // jump field data
Modified: trunk/OpenMPT/soundlib/Sndfile.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-06-06 18:49:52 UTC (rev 262)
+++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-06-06 19:11:18 UTC (rev 263)
@@ -136,6 +136,7 @@
[EXT] means external (not related) to INSTRUMENTHEADER content
C... [EXT] nChannels
+ChnS [EXT] IT/MPTM: Channel settings for channels 65-127 if needed (doesn't fit to IT header).
CS.. nCutSwing
CWV. [EXT] dwCreatedWithVersion
DCT. nDCT;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2009-06-06 18:49:54
|
Revision: 262
http://modplug.svn.sourceforge.net/modplug/?rev=262&view=rev
Author: relabsoluness
Date: 2009-06-06 18:49:52 +0000 (Sat, 06 Jun 2009)
Log Message:
-----------
Pattern tab:
+ Channel reset(stops note, sets initial chn settings). Available from channel header context menu and new key binding.
. Fixed wrong interpretations of "Old style pattern context menu"-option.
/ Channel control context menu will now be visible only in channel header context.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/CommandSet.cpp
trunk/OpenMPT/mptrack/CommandSet.h
trunk/OpenMPT/mptrack/KeyConfigDlg.cpp
trunk/OpenMPT/mptrack/View_pat.cpp
trunk/OpenMPT/mptrack/View_pat.h
trunk/OpenMPT/mptrack/resource.h
Modified: trunk/OpenMPT/mptrack/CommandSet.cpp
===================================================================
--- trunk/OpenMPT/mptrack/CommandSet.cpp 2009-06-06 18:40:29 UTC (rev 261)
+++ trunk/OpenMPT/mptrack/CommandSet.cpp 2009-06-06 18:49:52 UTC (rev 262)
@@ -2299,6 +2299,11 @@
commands[kcSampleSignUnsign].isHidden = false;
commands[kcSampleSignUnsign].isDummy = false;
+ commands[kcChannelReset].UID = 1786;
+ commands[kcChannelReset].isHidden = false;
+ commands[kcChannelReset].isDummy = false;
+ commands[kcChannelReset].Message = "Reset channel";
+
#ifdef _DEBUG
for (int i=0; i<kcNumCommands; i++) {
if (commands[i].UID != 0) { // ignore unset UIDs
Modified: trunk/OpenMPT/mptrack/CommandSet.h
===================================================================
--- trunk/OpenMPT/mptrack/CommandSet.h 2009-06-06 18:40:29 UTC (rev 261)
+++ trunk/OpenMPT/mptrack/CommandSet.h 2009-06-06 18:49:52 UTC (rev 262)
@@ -230,6 +230,7 @@
kcToggleChanMuteOnPatTransition,
kcUnmuteAllChnOnPatTransition,
kcSoloChnOnPatTransition,
+ kcChannelReset,
kcCopyAndLoseSelection,
kcTransposeUp,
kcTransposeDown,
Modified: trunk/OpenMPT/mptrack/KeyConfigDlg.cpp
===================================================================
--- trunk/OpenMPT/mptrack/KeyConfigDlg.cpp 2009-06-06 18:40:29 UTC (rev 261)
+++ trunk/OpenMPT/mptrack/KeyConfigDlg.cpp 2009-06-06 18:49:52 UTC (rev 262)
@@ -229,9 +229,9 @@
for (int c=kcClearRow; c<=kcInsertAllRows; c++)
newCat->commands.Add(c);
newCat->separators.Add(kcInsertAllRows); //--------------------------------------
- for (int c=kcChannelMute; c<=kcSoloChnOnPatTransition; c++)
+ for (int c=kcChannelMute; c<=kcChannelReset; c++)
newCat->commands.Add(c);
- newCat->separators.Add(kcSoloChnOnPatTransition); //--------------------------------------
+ newCat->separators.Add(kcChannelReset); //--------------------------------------
for (int c=kcTransposeUp; c<=kcTransposeOctDown; c++)
newCat->commands.Add(c);
newCat->separators.Add(kcTransposeOctDown); //--------------------------------------
Modified: trunk/OpenMPT/mptrack/View_pat.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_pat.cpp 2009-06-06 18:40:29 UTC (rev 261)
+++ trunk/OpenMPT/mptrack/View_pat.cpp 2009-06-06 18:49:52 UTC (rev 262)
@@ -66,6 +66,7 @@
ON_COMMAND(ID_EDIT_SPLITRECSELECT, OnSplitRecordSelect)
// -! NEW_FEATURE#0012
ON_COMMAND(ID_EDIT_UNDO, OnEditUndo)
+ ON_COMMAND(ID_PATTERN_CHNRESET, OnChannelReset)
ON_COMMAND(ID_PATTERN_MUTE, OnMuteFromClick) //rewbs.customKeys
ON_COMMAND(ID_PATTERN_SOLO, OnSoloFromClick) //rewbs.customKeys
ON_COMMAND(ID_PATTERN_TRANSITIONMUTE, OnTogglePendingMuteFromClick)
@@ -1218,8 +1219,8 @@
//------ Standard Menu ---------- :
else if ((pt.x >= m_szHeader.cx) && (pt.y > m_szHeader.cy)) {
- if (BuildSoloMuteCtxMenu(hMenu, ih, nChn, pSndFile))
- AppendMenu(hMenu, MF_SEPARATOR, 0, "");
+ /*if (BuildSoloMuteCtxMenu(hMenu, ih, nChn, pSndFile))
+ AppendMenu(hMenu, MF_SEPARATOR, 0, "");*/
if (BuildSelectionCtxMenu(hMenu, ih))
AppendMenu(hMenu, MF_SEPARATOR, 0, "");
if (BuildEditCtxMenu(hMenu, ih, pModDoc))
@@ -1376,8 +1377,23 @@
}
}
+void CViewPattern::OnChannelReset()
+//---------------------------------
+{
+ const CHANNELINDEX nChn = GetChanFromCursor(m_nMenuParam);
+ CModDoc *pModDoc = GetDocument();
+ CSoundFile* pSndFile;
+ if (pModDoc == 0 || (pSndFile = pModDoc->GetSoundFile()) == 0) return;
+ const bool bIsMuted = pModDoc->IsChannelMuted(nChn);
+ if(!bIsMuted) pModDoc->MuteChannel(nChn, true);
+ pSndFile->ResetChannelState(nChn, CHNRESET_TOTAL);
+ if(!bIsMuted) pModDoc->MuteChannel(nChn, false);
+}
+
+
void CViewPattern::OnMuteFromClick()
+//----------------------------------
{
OnMuteChannel(false);
}
@@ -3328,6 +3344,7 @@
case kcChannelUnmuteAll: OnUnmuteAll(); return wParam;
case kcToggleChanMuteOnPatTransition: TogglePendingMute(GetChanFromCursor(m_dwCursor)); return wParam;
case kcUnmuteAllChnOnPatTransition: OnPendingUnmuteAllChnFromClick(); return wParam;
+ case kcChannelReset: OnChannelReset(); return wParam;
case kcTimeAtRow: OnShowTimeAtRow(); return wParam;
case kcSoloChnOnPatTransition: PendingSoloChn(GetCurrentChannel()); return wParam;
case kcTransposeUp: OnTransposeUp(); return wParam;
@@ -4486,6 +4503,8 @@
AppendMenu(hMenu, MF_STRING, ID_PATTERN_TRANSITION_UNMUTEALL, "On transition: Unmute all\t" + ih->GetKeyTextFromCommand(kcUnmuteAllChnOnPatTransition));
AppendMenu(hMenu, MF_STRING, ID_PATTERN_TRANSITIONSOLO, "On transition: Solo\t" + ih->GetKeyTextFromCommand(kcSoloChnOnPatTransition));
+
+ AppendMenu(hMenu, MF_STRING, ID_PATTERN_CHNRESET, "Reset Channel\t" + ih->GetKeyTextFromCommand(kcChannelReset));
return true;
}
@@ -4518,11 +4537,8 @@
bool CViewPattern::BuildMiscCtxMenu(HMENU hMenu, CInputHandler* ih)
//-----------------------------------------------------------------
{
- if (CMainFrame::m_dwPatternSetup & PATTERN_OLDCTXMENUSTYLE) return false;
-
AppendMenu(hMenu, MF_STRING, ID_SHOWTIMEATROW, "Show row play time\t" + ih->GetKeyTextFromCommand(kcTimeAtRow));
return true;
-
}
bool CViewPattern::BuildSelectionCtxMenu(HMENU hMenu, CInputHandler* ih)
@@ -4701,9 +4717,6 @@
bool CViewPattern::BuildChannelControlCtxMenu(HMENU hMenu)
//--------------------------------------------------------------------
{
- if (CMainFrame::m_dwPatternSetup&PATTERN_OLDCTXMENUSTYLE) return false;
- //Not doing the menuentries if opted to use old style menu style.
-
AppendMenu(hMenu, MF_SEPARATOR, 0, "");
AppendMenu(hMenu, MF_STRING, ID_PATTERN_DUPLICATECHANNEL, "Duplicate this channel");
@@ -4729,11 +4742,8 @@
CArray<UINT, UINT> validChans;
DWORD greyed = (ListChansWhereColSelected(INST_COLUMN, validChans)>0)?FALSE:MF_GRAYED;
- if (CMainFrame::m_dwPatternSetup&PATTERN_OLDCTXMENUSTYLE && (!greyed)) {
- // Case: User has opted to use old style menu style.
- AppendMenu(hMenu, MF_STRING, ID_PATTERN_SETINSTRUMENT, "Change Instrument\t" + ih->GetKeyTextFromCommand(kcPatternSetInstrument));
- }
- else {
+ if (!greyed || !(CMainFrame::m_dwPatternSetup&PATTERN_OLDCTXMENUSTYLE))
+ {
// Create the new menu and add it to the existing menu.
HMENU instrumentChangeMenu = ::CreatePopupMenu();
AppendMenu(hMenu, MF_POPUP|greyed, (UINT)instrumentChangeMenu, "Change Instrument\t" + ih->GetKeyTextFromCommand(kcPatternSetInstrument));
@@ -4741,32 +4751,39 @@
if(pSndFile == NULL)
return false;
+ if(!greyed)
+ {
+ if (pSndFile->m_nInstruments)
+ {
+ for (UINT i=1; i<=pSndFile->m_nInstruments; i++)
+ {
+ if (pSndFile->Headers[i] == NULL)
+ continue;
- if (pSndFile->m_nInstruments) {
- for (UINT i=1; i<=pSndFile->m_nInstruments; i++) {
- if (pSndFile->Headers[i] == NULL) {
- continue;
- }
CString instString = pSndFile->GetPatternViewInstrumentName(i, true);
if(instString.GetLength() > 0) AppendMenu(instrumentChangeMenu, MF_STRING, ID_CHANGE_INSTRUMENT+i, pSndFile->GetPatternViewInstrumentName(i));
//Adding the entry to the list only if it has some name, since if the name is empty,
//it likely is some non-used instrument.
}
- } else {
+ }
+ else
+ {
CHAR s[256];
UINT nmax = pSndFile->m_nSamples;
while ((nmax > 1) && (pSndFile->Ins[nmax].pSample == NULL) && (!pSndFile->m_szNames[nmax][0])) nmax--;
- for (UINT i=1; i<=nmax; i++) if ((pSndFile->m_szNames[i][0]) || (pSndFile->Ins[i].pSample)) {
+ for (UINT i=1; i<=nmax; i++) if ((pSndFile->m_szNames[i][0]) || (pSndFile->Ins[i].pSample))
+ {
wsprintf(s, "%02d: %s", i, pSndFile->m_szNames[i]);
AppendMenu(instrumentChangeMenu, MF_STRING, ID_CHANGE_INSTRUMENT+i, s);
}
}
- //Add options to remove instrument from selection.
- AppendMenu(instrumentChangeMenu, MF_SEPARATOR, 0, 0);
- AppendMenu(instrumentChangeMenu, MF_STRING, ID_CHANGE_INSTRUMENT, "Remove instrument");
- AppendMenu(instrumentChangeMenu, MF_STRING, ID_CHANGE_INSTRUMENT+GetCurrentInstrument(), "Set to current instrument");
+ //Add options to remove instrument from selection.
+ AppendMenu(instrumentChangeMenu, MF_SEPARATOR, 0, 0);
+ AppendMenu(instrumentChangeMenu, MF_STRING, ID_CHANGE_INSTRUMENT, "Remove instrument");
+ AppendMenu(instrumentChangeMenu, MF_STRING, ID_CHANGE_INSTRUMENT+GetCurrentInstrument(), "Set to current instrument");
+ }
return true;
}
return false;
Modified: trunk/OpenMPT/mptrack/View_pat.h
===================================================================
--- trunk/OpenMPT/mptrack/View_pat.h 2009-06-06 18:40:29 UTC (rev 261)
+++ trunk/OpenMPT/mptrack/View_pat.h 2009-06-06 18:49:52 UTC (rev 262)
@@ -228,6 +228,7 @@
afx_msg void OnEditGoto();
afx_msg void OnEditFindNext();
afx_msg void OnEditUndo();
+ afx_msg void OnChannelReset();
afx_msg void OnMuteFromClick(); //rewbs.customKeys
afx_msg void OnSoloFromClick(); //rewbs.customKeys
afx_msg void OnTogglePendingMuteFromClick(); //rewbs.customKeys
Modified: trunk/OpenMPT/mptrack/resource.h
===================================================================
--- trunk/OpenMPT/mptrack/resource.h 2009-06-06 18:40:29 UTC (rev 261)
+++ trunk/OpenMPT/mptrack/resource.h 2009-06-06 18:49:52 UTC (rev 262)
@@ -961,6 +961,7 @@
#define ID_PATTERN_PLAYNOLOOP 32901
#define ID_PATTERN_OPEN_RANDOMIZER 32905
#define ID_PATTERN_INTERPOLATE_NOTE 32906
+#define ID_PATTERN_CHNRESET 32907
#define ID_PRESET_LOAD 32915
#define ID_PRESET_SAVE 32916
#define ID_PRESET_RANDOM 32917
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2009-06-06 18:40:37
|
Revision: 261
http://modplug.svn.sourceforge.net/modplug/?rev=261&view=rev
Author: relabsoluness
Date: 2009-06-06 18:40:29 +0000 (Sat, 06 Jun 2009)
Log Message:
-----------
/ VST: Changed host IDs and a couple of related return values. If compatibility problems occur, old IDs can be set with ini-settings.
? Misc: Modifications to remove some compiler warnings(in mptrack.cpp).
? Misc: Changed version to 1.17.03.01.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Mptrack.cpp
trunk/OpenMPT/mptrack/Mptrack.h
trunk/OpenMPT/mptrack/Vstplug.cpp
trunk/OpenMPT/mptrack/Vstplug.h
trunk/OpenMPT/mptrack/version.h
Modified: trunk/OpenMPT/mptrack/Mptrack.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Mptrack.cpp 2009-05-30 21:38:42 UTC (rev 260)
+++ trunk/OpenMPT/mptrack/Mptrack.cpp 2009-06-06 18:40:29 UTC (rev 261)
@@ -220,6 +220,7 @@
static void ShowChangesDialog()
//-----------------------------
{
+ /*
const char* const firstOpenMessage = "OpenMPT development build " MPT_VERSION_STR ".\n\n"
"Some notable changes since version 1.17.02.48:\n\n"
" [New] Name filter in plugin selection dialog.\n"
@@ -236,6 +237,7 @@
" For more detailed list of changes, see history.txt.";
CMainFrame::GetMainFrame()->MessageBox(firstOpenMessage, "OpenMPT v." MPT_VERSION_STR, MB_ICONINFORMATION);
+ */
}
@@ -1551,7 +1553,7 @@
if (t > 256)
m_bFirst = FALSE;
- dir = (t/256) % 2; //change dir every 256 t
+ dir = ((t/256) % 2 != 0); //change dir every 256 t
t = t%256;
if (!dir) t = (256-t);
@@ -2209,9 +2211,9 @@
UINT m = (m_Dib.bmiColors[i].rgbRed >> 2)
+ (m_Dib.bmiColors[i].rgbGreen >> 1)
+ (m_Dib.bmiColors[i].rgbBlue >> 2);
- m_Dib.bmiColors[i|0x80].rgbRed = (m + r)>>1;
- m_Dib.bmiColors[i|0x80].rgbGreen = (m + g)>>1;
- m_Dib.bmiColors[i|0x80].rgbBlue = (m + b)>>1;
+ m_Dib.bmiColors[i|0x80].rgbRed = static_cast<BYTE>((m + r)>>1);
+ m_Dib.bmiColors[i|0x80].rgbGreen = static_cast<BYTE>((m + g)>>1);
+ m_Dib.bmiColors[i|0x80].rgbBlue = static_cast<BYTE>((m + b)>>1);
}
}
@@ -2921,6 +2923,17 @@
m_pPluginManager = new CVstPluginManager;
if (!m_pPluginManager) return FALSE;
nPlugins = GetPrivateProfileInt("VST Plugins", "NumPlugins", 0, m_szConfigFileName);
+
+ #ifndef NO_VST
+ char buffer[64];
+ GetPrivateProfileString("VST Plugins", "HostProductString", CVstPluginManager::s_szHostProductString, buffer, ARRAYELEMCOUNT(buffer), m_szConfigFileName);
+ strcpy(CVstPluginManager::s_szHostProductString, buffer);
+ GetPrivateProfileString("VST Plugins", "HostVendorString", CVstPluginManager::s_szHostVendorString, buffer, ARRAYELEMCOUNT(buffer), m_szConfigFileName);
+ strcpy(CVstPluginManager::s_szHostVendorString, buffer);
+ CVstPluginManager::s_nHostVendorVersion = GetPrivateProfileInt("VST Plugins", "HostVendorVersion", CVstPluginManager::s_nHostVendorVersion, m_szConfigFileName);
+ #endif
+
+
CString nonFoundPlugs;
for (LONG iPlug=0; iPlug<nPlugins; iPlug++)
{
@@ -2962,6 +2975,14 @@
}
wsprintf(s, "%d", iPlug);
WritePrivateProfileString("VST Plugins", "NumPlugins", s, m_szConfigFileName);
+
+ #ifndef NO_VST
+ WritePrivateProfileString("VST Plugins", "HostProductString", CVstPluginManager::s_szHostProductString, m_szConfigFileName);
+ WritePrivateProfileString("VST Plugins", "HostVendorString", CVstPluginManager::s_szHostVendorString, m_szConfigFileName);
+ CMainFrame::WritePrivateProfileLong("VST Plugins", "HostVendorVersion", CVstPluginManager::s_nHostVendorVersion, m_szConfigFileName);
+ #endif
+
+
if (m_pPluginManager)
{
delete m_pPluginManager;
Modified: trunk/OpenMPT/mptrack/Mptrack.h
===================================================================
--- trunk/OpenMPT/mptrack/Mptrack.h 2009-05-30 21:38:42 UTC (rev 260)
+++ trunk/OpenMPT/mptrack/Mptrack.h 2009-06-06 18:40:29 UTC (rev 261)
@@ -344,7 +344,7 @@
MODPLUGFASTDIB m_Dib;
UINT m_nTextColor, m_nBkColor;
LPMODPLUGDIB m_pTextDib;
- BOOL m_nBlendOffset;
+ BYTE m_nBlendOffset;
BYTE m_n4BitPalette[16];
public:
@@ -359,7 +359,7 @@
void SetColor(UINT nIndex, COLORREF cr);
void SetAllColors(UINT nBaseIndex, UINT nColors, COLORREF *pcr);
void TextBlt(int x, int y, int cx, int cy, int srcx, int srcy, LPMODPLUGDIB lpdib=NULL);
- void SetBlendMode(UINT nBlendOfs) { m_nBlendOffset = nBlendOfs; }
+ void SetBlendMode(BYTE nBlendOfs) { m_nBlendOffset = nBlendOfs; }
void SetBlendColor(COLORREF cr);
};
Modified: trunk/OpenMPT/mptrack/Vstplug.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Vstplug.cpp 2009-05-30 21:38:42 UTC (rev 260)
+++ trunk/OpenMPT/mptrack/Vstplug.cpp 2009-06-06 18:40:29 UTC (rev 261)
@@ -13,9 +13,14 @@
#include "VstEditor.h" //rewbs.defaultPlugGUI
#include "defaultvsteditor.h" //rewbs.defaultPlugGUI
#include "midi.h"
+#include "version.h"
#ifndef NO_VST
+char CVstPluginManager::s_szHostProductString[64] = "OpenMPT";
+char CVstPluginManager::s_szHostVendorString[64] = "OpenMPT project";
+long CVstPluginManager::s_nHostVendorVersion = MptVersion::num;
+
//#define VST_LOG
//#define ENABLE_BUZZ
#define DMO_LOG
@@ -861,16 +866,19 @@
case audioMasterGetOutputSpeakerArrangement:
Log("VST plugin to host: Get Output Speaker Arrangement\n");
break;
- case audioMasterGetVendorString: // Prentending to be Steinberg for compat.
- strcpy((char*)ptr,"Steinberg");
-// strcpy((char*)ptr,"OpenMPT");
- return 0;
- case audioMasterGetVendorVersion: // Prentending to be Cubase VST 7. :)
- return 7000;
- case audioMasterGetProductString: // Prentending to be Cubase VST for compat.
- strcpy((char*)ptr,"Cubase VST");
-// strcpy((char*)ptr,"OpenMPT");
- return 0;
+ case audioMasterGetVendorString:
+ strcpy((char*)ptr, s_szHostVendorString);
+ //strcpy((char*)ptr,"Steinberg");
+ //return 0;
+ return true;
+ case audioMasterGetVendorVersion:
+ return s_nHostVendorVersion;
+ //return 7000;
+ case audioMasterGetProductString:
+ strcpy((char*)ptr, s_szHostProductString);
+ //strcpy((char*)ptr,"Cubase VST");
+ //return 0;
+ return true;
case audioMasterVendorSpecific:
return 0;
// void* in <ptr>, format not defined yet
Modified: trunk/OpenMPT/mptrack/Vstplug.h
===================================================================
--- trunk/OpenMPT/mptrack/Vstplug.h 2009-05-30 21:38:42 UTC (rev 260)
+++ trunk/OpenMPT/mptrack/Vstplug.h 2009-06-06 18:40:29 UTC (rev 261)
@@ -249,6 +249,12 @@
static long VSTCALLBACK MasterCallBack(AEffect *effect, long opcode, long index, long value, void *ptr, float opt);
static BOOL __cdecl CreateMixPluginProc(PSNDMIXPLUGIN, CSoundFile*);
VstTimeInfo timeInfo; //rewbs.VSTcompliance
+
+public:
+ static char s_szHostProductString[64];
+ static char s_szHostVendorString[64];
+ static long s_nHostVendorVersion;
+
#else // NO_VST
public:
PVSTPLUGINLIB AddPlugin(LPCSTR, BOOL =TRUE, const bool = false, CString* const = 0) {return 0;}
Modified: trunk/OpenMPT/mptrack/version.h
===================================================================
--- trunk/OpenMPT/mptrack/version.h 2009-05-30 21:38:42 UTC (rev 260)
+++ trunk/OpenMPT/mptrack/version.h 2009-06-06 18:40:29 UTC (rev 261)
@@ -14,8 +14,8 @@
//Version definitions. The only thing that needs to be changed when changing version number.
#define VER_MAJORMAJOR 1
#define VER_MAJOR 17
-#define VER_MINOR 02
-#define VER_MINORMINOR 53
+#define VER_MINOR 03
+#define VER_MINORMINOR 01
//Creates version number from version parts that appears in version string.
//For example MAKE_VERSION_NUMERIC(1,17,02,28) gives version number of
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2009-05-30 21:38:44
|
Revision: 260
http://modplug.svn.sourceforge.net/modplug/?rev=260&view=rev
Author: relabsoluness
Date: 2009-05-30 21:38:42 +0000 (Sat, 30 May 2009)
Log Message:
-----------
Tag for 1.17.02.53
Added Paths:
-----------
tags/1.17.02.53/
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2009-05-30 21:22:03
|
Revision: 259
http://modplug.svn.sourceforge.net/modplug/?rev=259&view=rev
Author: relabsoluness
Date: 2009-05-30 21:21:35 +0000 (Sat, 30 May 2009)
Log Message:
-----------
1.17.02.53
Modified Paths:
--------------
trunk/OpenMPT/mptrack/bin/mptrack.exe
trunk/OpenMPT/packageTemplate/History.txt
trunk/OpenMPT/packageTemplate/SoundTouch/README.html
trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb
Added Paths:
-----------
trunk/OpenMPT/mptrack/bin/OpenMPT_SoundTouch.dll
Added: trunk/OpenMPT/mptrack/bin/OpenMPT_SoundTouch.dll
===================================================================
(Binary files differ)
Property changes on: trunk/OpenMPT/mptrack/bin/OpenMPT_SoundTouch.dll
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Modified: trunk/OpenMPT/mptrack/bin/mptrack.exe
===================================================================
(Binary files differ)
Modified: trunk/OpenMPT/packageTemplate/History.txt
===================================================================
--- trunk/OpenMPT/packageTemplate/History.txt 2009-05-17 14:54:05 UTC (rev 258)
+++ trunk/OpenMPT/packageTemplate/History.txt 2009-05-30 21:21:35 UTC (rev 259)
@@ -8,15 +8,217 @@
?: other
(tx XYZ): thanks to XYZ for telling us about the bug
+
+v1.17.02.53 (May 2009, revision 259)
+------------------------------------
+
+General:
+ + <jojo> Can now import MO3 files using external library. (rev. 248)
+
+ . <jojo> Song Cleanup: Sample cleanup should no longer remove data after sustain loop end point. (rev. 248)
+ . <jojo> Misc: When adding channels from song properties, new channels are now initialized properly (bug 1814). (rev. 236)
+ . <jojo> BPM approximation showed wrong rows per beat in some cases (bug 2532) (rev. 231)
+ . <jojo> Disabled special handling of '&'-character when drawing texts to various components where the special handling should not take place. (http://lpchip.com/modplug/viewtopic.php?t=1962) (rev. 229)
+ . <re> File opening: Added a couple of return value checks to reduce the change of crash when opening lots of files (bug 2546) (rev. 239)
+
+ / <jojo> Menu: Goto dialog can now be opened from Edit-menu. (rev. 246)
+ / <re> Pattern cleanup: Clearing sequence after first '---' item is now optional. (rev. 239)
+ / <re> When passing MIDI to plug, documents will now be set modified since MIDI data may change parameters. (rev. 243)
+
+General tab:
+ / <jojo> General tab: VST volume slider is now disabled for S3M. (rev. 246)
+ / <jojo> General tab: Initial channel volume controls are now enabled only for IT and MPTM. (rev. 246)
+
+Pattern tab:
+ + <jojo> Added descriptions of SBx, S3x, S4x and S5x command parameters to note properties dialog. (rev. 251)
+ + <jojo> Descriptions to retrigger note command parameters in note properties dialog. (rev. 248)
+ + <jojo> Ability to start playback with incoming MIDI note (see setup->MIDI) (rev. 246)
+ + <jojo> Duplicate channel (see channel header context menu). (246)
+ + <re> MIDI controllers can now be used to input smooth MIDI macro commands to pattern (setup->MIDI). (rev. 240)
+
+ . <re> Undo should now work with chords. (rev. 244)
+ . <re> When playing with MIDI keyboard, plugins got a constant note velocity, not the actual velocity (bug 2754) (rev. 239)
+ . <re> Undo fixes (didn't properly handle playback positions/multichannel record, set redundant undo points)(rev 243)
+ . <re> Param record in plugs GUI wrote commands even when pattern record was off. (rev 243)
+ . <re> Fixed chord detection when row spacing was enabled. (rev 243)
+ . <re> Fix to displaying wrong pattern name when using more than 255 patterns (http://lpchip.com/modplug/viewtopic.php?t=2344) (rev. 212)
+ . <re> Accidental moving when selecting order in margins shouldn't happen anymore. (rev 225)
+ . <re> Fix to possible crash when using undo after pattern resize (bug introduced in rev. 168)
+
+ / <jojo> When applying "change instrument", won't add instrument number to note off/cut if the note doesn't have instrument already. (rev. 248)
+ / <re> Default orderlist margin value can now be controlled with "DefaultSequenceMargins" ini-settings under "Pattern Editor" context. (rev 225)
+ / <jojo & re> Sequence view: Sequence scrolling won't no longer be cut on first '---' item on IT/MPTM/XM. (rev. 237)
+ / <re> Pattern: The keyboard split 'feature' when entering chords is removed (bug 2790). (rev. 244)
+
+Sample tab:
+ + <jojo> Can now normalize sample selections. (rev. 254)
+ + <jojo> Can now optionally normalize all samples instead of just one (click normalize with shift down) (rev. 249)
+ + <jojo & re> Status bar now displays offset value at given sample point. (rev. 232)
+ + <jojo & re> Sample amplify now accepts negative values(inverts sample phase) (request 2219) (rev. 234)
+ + <jojo & re> Signed/unsigned sample conversion. (rev. 235)
+ + <re> Added button for phase invert to toolbar. (rev. 235)
+ + <jojo> Ability to save sample as raw. (rev. 236)
+
+ . <re> Fix to zoom-related crash when loading samples in sample tab. Occurs usually with lengthy samples. (rev. 211)
+ . <jojo> Playing sample selection didn't work properly in all cases (bug 1700). (rev. 231)
+ . <jojo> Setting loop points could affect playing of sample even if loop was disabled (bug 1874) (rev. 231)
+
+ / <jojo> Notes from MIDI should now be played like notes from keyboard. (rev. 246)
+ / <jojo> Play sample button now stops previous note even if mod is playing (bug 1366) (rev. 231)
+ / <jojo> Sustain loop will now be enabled when setting it to sample selection. (rev. 231)
+ / <jojo> Sample editing: If possible, use loop points as trim limits if there's no selection chosen. (rev. 230)
+ / <re> Time stretching is now implemented with SoundTouch library. (rev. 228)
+ / <re> Disabled pitchshifting/time stretching of 8-bit samples(didn't seem to work). (rev. 228)
+
+Instrument tab:
+ . <jojo> Envelope view: Middle line will now be drawn in panning and pitch/filter envelopes even if row guidelines are enabled. (rev. 254)
+
+ / <jojo> Instrument tab: Sample map can now map "No sample". (rev. 236)
+ / <re> Changed default instrument plug volume command handling from Dry/Wet to none. Also added ini-setting with which one can set the default value used for new instruments. Ini setting is "DefaultPlugVolumeHandling" in [Misc], possible values are 0,1,2. (rev. 238)
+
+MPTM:
+ . <re> Pattern cleanup: In some cases sequence wasn't cleaned properly for mptm. (rev. 239)
+ / <re> Changed pattern/order limit for MPTm from 65000 to 4000. (rev. 212)
+ Instrument tuning:
+ + <re> Added letter 'b' to drawable letters. (rev. 217)
+ . <re> Creating 'group geometric' was broken (perhaps since v. 1.17.02.49) (rev. 252)
+ . <re> Loading certain old tuning objects didn't work. (rev. 238)
+ / <re> Notes should now be drawn more clearly when using custom tunings. (rev. 217)
+
+IT:
+ . <jojo & re> Macro config should now be loaded correctly also when loading IT files not made with MPT. (rev. 257)
+ . <jojo & re> Playback fix to vibrato with ramp down waveform in IT compatibility play. (rev. 257)
+ . <re> When file was saved with compatibility export, the last order was not shown in Impulse Tracker. (rev. 257)
+
+XM:
+ . <jojo> Fix to handling a special case of Bxx and Dxx (bug 2769) (rev 241)
+
+S3M:
+ . <re> S3M saving: Sequence of length 241-255 should now be cut to length 240 instead of ~16. (rev. 239)
+ / <re> When loading S3M files which contain Zxx-effects, user is now asked how to process them. (bug 2166) (rev. 233)
+ / <re> S3M saving: Saved sequence is no longer cut on first '---' item. (rev. 239)
+
+MOD:
+ . <jojo & re> Fixes to MOD saving: it should now be possible to create ProTracker compatible MOD files with compatibility export. (rev. 256)
+
+Package template:
+ / <jojo> PackageTemplate: Update to DE_jojo-keymap
+
+Misc:
+ . <from libmodplug> Fix to faulty portamento handling on loading AMF.
+ . <various> Lots of smaller bug fixes.
+
+
+
+v1.17.02.52 (14 Apr 2008, revision 210)
+---------------------------------------
+ . <re> Shouldn't need winhttp anymore(at least now that updatecheck is disabled). Dependency caused problems in Win98.
+ . <re> Fix to faulty plug file existence check(introduced in 1.17.02.51)(http://lpchip.com/modplug/viewtopic.php?t=2255)
+ . <re> Sound card-options buffer length value validation.
+ . <re> In .51, muted channels were ignored completely in MIDI export. Now pattern effects are processed in muted channels.
+ . <re> IT style-playback fix
+
+
+v1.17.02.51 (29 Mar 2008, revision 208)
+---------------------------------------
+ . <re> Fix to crash when loading VST with long(>32) param name.
+ . <ma & re> Fix to possible memory corruption problem on handling VST with more than 30 outputs.
+ - VST with more than 32 outputs might still be handled poorly.
+ . <re> Fix to possible crash when browsing modules in treeview(http://lpchip.com/modplug/viewtopic.php?t=2222).
+ . <re> Fix to severe memory leak in the same section as above.
+ . <re> Fix to mptm not showing in tree view file browser.
+ . <re> Fix to MIDI drum export (http://lpchip.com/modplug/viewtopic.php?t=2024)
+ . <re> Fix to possible crash on MIDI export if exporting module with more than 64 channels.
+ / <re> MIDI export won't anymore export muted channels(http://lpchip.com/modplug/viewtopic.php?t=2017)
+ . <re> When converting MOD->S3M/IT/MPTM, finetune setting was ignored (http://lpchip.com/modplug/viewtopic.php?t=1706)
+ . <re> IT compatibility: Fix to not resetting envelopes on new instrument (http://lpchip.com/modplug/viewtopic.php?t=1869)
+ . <re> IT compatibility: Fix to bidi loop resetting (http://lpchip.com/modplug/viewtopic.php?t=788)
+ . <re> IT compatibility: Fix to note trigger after note cut(http://lpchip.com/modplug/viewtopic.php?t=2080)
+ . <re> Mixmode-tooltip in general tab was in some cases shown on unrelated controls (http://lpchip.com/modplug/viewtopic.php?t=2176)
+ . <re> Pitch/tempo lock was lost on first instrument when opening instrument tab for the first time. (http://lpchip.com/modplug/viewtopic.php?t=1823)
+ . <re> Verifying buffer length-setting read from INI-file to prevent the impression that it can be set < 10 (http://lpchip.com/modplug/viewtopic.php?t=992)
+ . <re> Pattern effectdata paste was broken for MOD (probably since .46) (http://lpchip.com/modplug/viewtopic.php?t=1938)
+ / <re> When loading plug information at startup, checking whether the plug files exist. (http://lpchip.com/modplug/viewtopic.php?t=1367)
+ . <re> Continuous pattern navigation fixes(http://lpchip.com/modplug/viewtopic.php?t=1960, http://lpchip.com/modplug/viewtopic.php?t=1959)
+ . <re> Keyboard split related fix (http://lpchip.com/modplug/viewtopic.php?t=1887)
+ . <re> Releasenode information should now be included when copying instrument envelopes (http://lpchip.com/modplug/viewtopic.php?t=1780)
+ . <ma> Potential memory corruption bug when loading VSTs
+
+ - <re> Removed buggy rearrange samples (http://lpchip.com/modplug/viewtopic.php?t=2148)
+ . <re> Fixed MIDI mapping not checking MIDI event, which could cause events like pitch bend to trigger some mapping item.
+ . <re> Extended song/instrument properties were not always loaded correctly for IT (bug introduced in 1.17.02.50)(http://lpchip.com/modplug/viewtopic.php?p=16335)
+ . <re> Fix for faulty tabs when switching between modtypes with and without instrumenttab. (http://lpchip.com/modplug/viewtopic.php?t=1614)
+ . <re> Fix for possible crash on save/load when using more than 64 channels with MPTM.
+ / <re> Modified flag is not set when sliding tempo/global volume slider for MOD file.
+ / <re> When setting instrument pan, checking whether instrument samples have set pan enabled and optionally disabling them.
+ + <re> Unmute all(on transition) shortcutkeys should now work in orderlist context.
+ / <re> Disabled Set Pan in sample tab for XM.
+ + <re> Half/double pattern rownumber buttons to pattern properties dialog.
+ / <re> Show prev/next pattern now shows pattern over +++ orderlist items.
+ + <re> Channel status in status bar now show channel volume info.
+ / <re> Disabled setting channel pan for MOD/XM in general view.
+
+
+v1.17.02.50 (26 Jan 2008, revision 198)
+---------------------------------------
+ / <re> MIDICC bug related compatibility improvement for loading old IT/MPTm files.
+ + <re> MIDI controller mapping to plug params.
+ + <re> Ability to take MIDI volume into account when playing notes.
+ + <re> Ability to pass MIDI to plug.
+ + <re> Ability to start/continue/stop play with certain MIDI messages (untested)
+ + <re> Ability to choose how volume commands behave for plugs.
+ . <re> Fixed sending wrong MIDI message in ::MidiCC.
+
+ + <re> Keyshortcuts for preset navigation jumps in VST editor.
+ . <re> Default VST editor preset field name validation in the menubar.
+
+ + <re> Added ability to edit various flags in song properties.
+ . <re> Fix for pattern duplicate for small patterns (http://lpchip.com/modplug/viewtopic.php?t=1747)
+ . <re> Fixed song properties-menu entry in mainframe(was grayed and didn't show keyshortcut)
+ . <re> Fixed crash with certain toolbar related ini-settings (http://lpchip.com/modplug/viewtopic.php?t=2033)
+ . <re> Further fixes to prevent unnotified overwriting of file.
+ / <re> .bak-files won't now be shown with "All modules" filter when loading modules.
+ . <re> Show row playtime didn't on certain cases work on first pattern row (http://lpchip.com/modplug/viewtopic.php?t=2044)
+ . <re> Fix to faulty play with certain instruments without notes in IT compatible playmode (http://lpchip.com/modplug/viewtopic.php?t=2080)
+ . <re> Pattern number box didn't open pattern properties when using MPTm. (http://lpchip.com/modplug/viewtopic.php?t=2073)
+ . <re> Fixed wrong MIDI CC names in macro editor.
+ ./ <re> Setting volume to 0(v00) in pattern didn't necessarily set volume to 0 when using volume random variation for instrument. All other random variation behaviors are changed as well; now the 'swing' is applied directly to channel values instead of using swing addition, and by default the swing effect is reset on new note. (http://lpchip.com/modplug/viewtopic.php?t=2074)
+
+ / <re> MPTm made with this version will be recognized as IT in earlier versions.
+ / <re> Various validity checks for read data in ITP loading.
+
+
+v1.17.02.49 (17 Nov 2007, revision 194)
+---------------------------------------
+ + <re> Improved VST preset navigation in VST window. Known problem: doesn't update if preset is changed from VSTs own preset navigation.
+ + <re> Improvements in IT compatibility playmode. When loading ITs, if file doesn't seem modplug made, then automatically setting IT compatibility playmode. The playmode setting can be toggled in song properties dialog, and the autodetection with an ini setting.
+ + <re> 'key binding not understood'-messages can be disabled with an ini setting.
+ . <re> Fixed wrong file version in IT compatibility save. (http://lpchip.com/modplug/viewtopic.php?t=1723)
+ . <re> Fixed possible unnotified overwriting of file occurring for example when dealing with a new file. (http://lpchip.com/modplug/viewtopic.php?t=1813)
+ . <re> Fixed broken note preview for certain type of instruments in instrument tab. (http://lpchip.com/modplug/viewtopic.php?t=1996)
+ . <re> Fixed possible crash on channel mode wav export when a channel has a long name. (http://lpchip.com/modplug/viewtopic.php?t=2005)
+ . <re> Fixed pattern position indicator jump when clicking VST-box in channel header. (http://lpchip.com/modplug/viewtopic.php?t=2014)
+ / <re> Custom tuning related
+ -file format changes
+ -changed interpretation of finesteps: now zero finesteps means that finesteps are equal to notesteps, previously zero finesteps disabled portamentos etc)
+ -Pitch slide between notes with portamentos is now specialised also for other tuning types than just geometric(changes behavior). Previously behavior was 'geometric' for all types.
+
+ . <rewbs> Fix pattern search, which could search for the wrong param. Also enable typing of desired param value rather than only selecting from listbox. (http://lpchip.com/modplug/viewtopic.php?t=1799)
+ . <rewbs> Delay-load winhttp.dll and don't die if it can't be found, e.g. on win98. (http://lpchip.com/modplug/viewtopic.php?t=1778)
+ . <rewbs> Fix a couple of pixels on D# in the pattern editor small font bitmap. (http://lpchip.com/modplug/viewtopic.php?t=1781)
+ + <rewbs> Add name filter to plugin selection dialog. Useful when you have hundreds of plugins.
+ + <Pelya> Allow Window key as a modifier in the keyboard configuration. Disables start menu pop-up when pressing the Win key if and only if it used in the active keyboard configuration.
+ + <Pelya> Disables NumLock/CapsLock/ScrollLock lamps on keyboard if and only if they are used in the active keyboard configuration. The lamps will blink anyway - can't help it until we start using DirectInput.
+
v1.17.02.48
- . <Relabs> Fix song cleanup issue (http://lpchip.com/modplug/viewtopic.php?t=1711)
- . <Relabs> Pitch/Tempo lock fix (broken in .46 and .47) (http://lpchip.com/modplug/viewtopic.php?t=1646)
- / <Relabs> Pattern manager channel reordering behviour changes / fixes. (http://lpchip.com/modplug/viewtopic.php?t=1148)
+ . <re> Fix song cleanup issue (http://lpchip.com/modplug/viewtopic.php?t=1711)
+ . <re> Pitch/Tempo lock fix (broken in .46 and .47) (http://lpchip.com/modplug/viewtopic.php?t=1646)
+ / <re> Pattern manager channel reordering behviour changes / fixes. (http://lpchip.com/modplug/viewtopic.php?t=1148)
. <pelya> Fix bad horizontal scrolling in pattern editor when positioning the cursor with the mouse. (http://lpchip.com/modplug/viewtopic.php?t=1650)
. <rewbs> Fix odd "play row" behaviour when using 1 tick-per-row (http://lpchip.com/modplug/viewtopic.php?t=1038).
. <rewbs> Fix pop due to ramping when song starts with a pattern command that sets a low global volume. (http://lpchip.com/modplug/viewtopic.php?t=523)
. <rewbs> Fix occasional colour issues with orderlist (http://lpchip.com/modplug/viewtopic.php?t=867)
- . <rewbs> Fix impossible horizontal scrolling in pattern editor when playing with follow song on
+ . <rewbs> Fix impossible horizontal scrolling in pattern editor when playing with follow song on
. <rewbs> Grey out "Trim" option in sample editor context menu if there's no selection. (http://lpchip.com/modplug/viewtopic.php?t=908)
v1.17.02.47
@@ -26,54 +228,54 @@
. <rewbs> Fix saturation on old modules (introduced in 1.17.02.46). Loading tracks with no saved mixlevel setting defaults to 'original'.
Starting new IT, MPTM, ITP or XM defaults to '117RC3'. Starting new MOD or S3M defaults to 'original'.
. <rewbs> Tree view FX list now starts with FX01 instead of FX00.
- / <Relabs> Pattern skipping behavior returned to that of .45
+ / <re> Pattern skipping behavior returned to that of .45
. <pelya & rewbs> internal: ifdefs for compilation on vs2005
- . <Relabs> internal: VS Edit&Continue fix (gone broken in 'RC3'branch)
- / <Relabs> Minor modifications(cleanup of channel state reset code, removed unused orderundo-vector.)
+ . <re> internal: VS Edit&Continue fix (gone broken in 'RC3'branch)
+ / <re> Minor modifications(cleanup of channel state reset code, removed unused orderundo-vector.)
v1.17.02.46
- + <Relabsoluness> Experimental MPTm format:
+ + <re> Experimental MPTm format:
--> Internally, it is still very close to the IT-based format.
--> Order&pattern limit increased to 65000; whole range not tested :) (Note that modeffects such as position jump doesn't cover the whole range unless the #-extension can be used(haven't tested))
- + <Relabsoluness> User definable tuning modes for instruments:
+ + <re> User definable tuning modes for instruments:
--> Only available for MPTm
--> Ratio value as well as note name for every key can be assigned invidually; gives rather free hands for experiments.
--> Every instrument can have it's own tuning
--> Tunings can be saved to file and loaded from file.
--> IMPORTANT: When using tunings, behavior of various modcommands such as portamento have been changed, and new behaviors are still to be decided.
- + <Relabsoluness> In song properties, option to increase playback compatibility with original Impulse Tracker behavior. Is in no way complete; currently affects only a couple of differences. Many differences are still there.
- + <Relabsoluness> Ability to load multiple mods/samples/instruments from corresponding load dialogs.
+ + <re> In song properties, option to increase playback compatibility with original Impulse Tracker behavior. Is in no way complete; currently affects only a couple of differences. Many differences are still there.
+ + <re> Ability to load multiple mods/samples/instruments from corresponding load dialogs.
--> Known issue: Intermittent failures.
- + <Relabsoluness> 32-bit float wav import
- . <Relabsoluness> 24/32-bit PCM wav sample import fixed
- + <Relabsoluness> Playback control additions: 'Solo on transition' & 'Mute on transition'. Available from pattern view context menu(right click).
- + <Relabsoluness> Envelope points can be scaled by a factor through context menu on envelopeview(right click)
- + <Relabsoluness> Calculator of playback time (measured from start) at the beginning of any row of any pattern (uses existing modlength calculator).
+ + <re> 32-bit float wav import
+ . <re> 24/32-bit PCM wav sample import fixed
+ + <re> Playback control additions: 'Solo on transition' & 'Mute on transition'. Available from pattern view context menu(right click).
+ + <re> Envelope points can be scaled by a factor through context menu on envelopeview(right click)
+ + <re> Calculator of playback time (measured from start) at the beginning of any row of any pattern (uses existing modlength calculator).
--> Known limitation: When the row is within pattern loop, doesn't give all possible times.
+ <rewbs> SCx now sends note-off to VSTis at tick x.
+ <rewbs> New mixmode (called 1.17RC3): bypass global preamp, force soft panning, provide explicit dB value for sample attenuation. WARNING: this mixmode is subject to change.
+ <rewbs> Check for updates on startup. To disable, set CheckForUpdates=0 in mptrack.ini.
. <rewbs> Plugin list window remembers its position/size even on cancel.
. <rewbs> Fix odd window position on very first startup (before mptrack.ini is created).
- . <Relabsoluness> When opening instruments, load dialog didn't remember its previous path.
- . <Relabsoluness> In general tab, it was possible to give longer modname than the fileformat could save.
- . <Relabsoluness> Instruments associates with VSTis no longer also need to be associated to a sample in order to play.
- . <Relabsoluness> Trash characters to empty ITP comments should no longer appear.
- . <Relabsoluness> Channel state should now be updated correctly when e.g. moving channels through channel manager.
- . <Relabsoluness> It should no longer be possible to remove all channels from channel manager.
- / <Relabsoluness> Channel states resetting when jumping between orders from orderlist.
+ . <re> When opening instruments, load dialog didn't remember its previous path.
+ . <re> In general tab, it was possible to give longer modname than the fileformat could save.
+ . <re> Instruments associates with VSTis no longer also need to be associated to a sample in order to play.
+ . <re> Trash characters to empty ITP comments should no longer appear.
+ . <re> Channel state should now be updated correctly when e.g. moving channels through channel manager.
+ . <re> It should no longer be possible to remove all channels from channel manager.
+ / <re> Channel states resetting when jumping between orders from orderlist.
--> NOTE: While this fixes a bug (behavior change) introduced in the tuning branch(?), it also changes quite prominent behavior so can annoy people - might need to be modified at some point.
- / <Relabsoluness> Added version number to the mainframe title.
- / <Relabsoluness> Changed the 'order message' at the bottom bar of the screen "Position x of y" to "Position x of y (x in hex of y in hex)".
- / <Relabsoluness> Lots of smaller (internal) changes.
+ / <re> Added version number to the mainframe title.
+ / <re> Changed the 'order message' at the bottom bar of the screen "Position x of y" to "Position x of y (x in hex of y in hex)".
+ / <re> Lots of smaller (internal) changes.
v1.17.02.45
- + <Relabsoluness & Alex> "Pitch to tempo lock" instrument setting: define the tempo at which your instrument loops correctly, and it will be pitched automatically to match the song's current tempo.
- + <Relabsoluness> Notification when attempting to modify pattern but pattern record is off.
- + <Relabsoluness> Orderlist margins: you can define how many slots to keep visible around the active pattern as the orderlist scrolls
- . <Relabsoluness> Fixes for various unexpected pattern loop state changes.
- . <Relabsoluness> Fixes to IT Style clear.
- . <Relabsoluness> Memory management fixes and misc other bug fixes.
+ + <re & Alex> "Pitch to tempo lock" instrument setting: define the tempo at which your instrument loops correctly, and it will be pitched automatically to match the song's current tempo.
+ + <re> Notification when attempting to modify pattern but pattern record is off.
+ + <re> Orderlist margins: you can define how many slots to keep visible around the active pattern as the orderlist scrolls
+ . <re> Fixes for various unexpected pattern loop state changes.
+ . <re> Fixes to IT Style clear.
+ . <re> Memory management fixes and misc other bug fixes.
. <rewbs> ITP loading fixed (I broke it in v1.17.02.44)
. <rewbs> Time estimation fixed for tracks with pattern break+XParam.
. <rewbs> "Last saved with" version number was not always saved correctly - fixed
@@ -91,14 +293,6 @@
. <rewbs> Added channel limit check when adding chans from the pattern editor.
. <rewbs> Fixed instant crash with SampleTank 2.1.
-. v1.17.02.43
- + <rewbs> You can now load up new plugins from anywhere, not just the General tab. Select "Plugin Manager..." from the view menu. This can also be assigned to a global hotkey.
- Limitation: currently plugins added to a song in this manner with always be put in the first empty slot. In a future version you'll be able to choose the slot directly from that window.
- + <rewbs> "Cleanup Plugins" to remove any plugs that are not associated to a channel and not used by an instrument and not used as an output for any used plugs.
- . <rewbs> Fixed channel limits. Should be able to correctly save IT pattern data with up to 127 chans. There's only space for 64 channel headers though (channel names etc..). XMs restricted to 64 chans.
- . <rewbs> Added channel limit check when adding chans from the pattern editor.
- . <rewbs> Fixed instant crash with SampleTank 2.1.
-
. v1.17.02.42
+ <rewbs> "Compatibility export" in file menu: save as 'plain' IT, without all of OpenMPT's crap. IT only for now (not XM).
. <rewbs> Set instrument in pattern editor should work when no note is specified (tx Torvus - http://lpchip.com/modplug/viewtopic.php?t=470)
@@ -115,14 +309,14 @@
. v 1.17.02.40
- + <Relabsoluness> Added indicator of currently playing pattern to orderlist.
- + <Relabsoluness> 'Loop pattern' and 'follow song' keys should now work when orderlist has focus.
+ + <re> Added indicator of currently playing pattern to orderlist.
+ + <re> 'Loop pattern' and 'follow song' keys should now work when orderlist has focus.
+ <rewbs> Removed registry dependencies. All settings will now be saved to ini file.
. <rewbs> Correcly update orderlist position when cycling through patterns
- . <Relabsoluness> Fixed orderlist GUI update on ctrl-transition when in patternloop mode
- . <Relabsoluness> Moving a channel should now correctly take into account record-channels and pending mutes
- . <Relabsoluness> Switching autodelay off in the options now works for note-offs as well.
- . <Relabsoluness> Some mod-effects like 'pattern jump' and 'break pattern' no longer conflict with pattern loop toggling.
+ . <re> Fixed orderlist GUI update on ctrl-transition when in patternloop mode
+ . <re> Moving a channel should now correctly take into account record-channels and pending mutes
+ . <re> Switching autodelay off in the options now works for note-offs as well.
+ . <re> Some mod-effects like 'pattern jump' and 'break pattern' no longer conflict with pattern loop toggling.
. <rewbs> Fixed bad capping of random cutoff variation (tx LPChip)
. <rewbs> Fixed crash on loading ITP with pattern names (tx Relabsoluness)
. <rewbs> Fixed incorrect version number in saved files (tx Relabsoluness)
@@ -131,12 +325,12 @@
. v 1.17.02.39
- + <Relabsoluness> Remove and insert channels directly from pattern editor via channel header context menu
- + <Relabsoluness> Toggle loop pattern playback mode with a shortcut key and a checkbox above the pattern editor
- + <Relabsoluness> The automatic note delays that are inserted when recording notes live are now optional
- . <Relabsoluness> Fixed auto note delays so they work with S3Ms too
- . <Relabsoluness> Fixes and improvements to displayed instrument name in pattern editor
- . <Relabsoluness> Fixes and improvements to instrument swap from context menu
+ + <re> Remove and insert channels directly from pattern editor via channel header context menu
+ + <re> Toggle loop pattern playback mode with a shortcut key and a checkbox above the pattern editor
+ + <re> The automatic note delays that are inserted when recording notes live are now optional
+ . <re> Fixed auto note delays so they work with S3Ms too
+ . <re> Fixes and improvements to displayed instrument name in pattern editor
+ . <re> Fixes and improvements to instrument swap from context menu
. <rewbs> Plugins should never cause song to be marked as modified if their GUI is not open (tx LPChip)
/ <rewbs> Version number in executable properties now correlates with real OpenMPT version number
/ <rewbs> Restored solo/mute in pattern editor main context menu.
@@ -173,17 +367,17 @@
(+ <rewbs> volume commands without notes now send volume MIDI CC to plugs, but as far as I've seen, no plugs seem to respond to it.)
. v 1.17.02.35
- + <rewbs & Relabsoluness> Note delay (SDx) is written automatically during "live tracking" if there are no effects already on the existing row.
+ + <rewbs & re> Note delay (SDx) is written automatically during "live tracking" if there are no effects already on the existing row.
+ <rewbs> Preliminary parameter value recording should work a bit now with follow song on. Attempts to set correct macro if it exists. Will only overwite \xx. Does not work with certain plugs that don't give idle time back to the host during mouse down (e.g. Albino, Vanguard...), still trying to understand this. Please play with this & give feedback, but don't expect miracles yet. :)
. <rewbs> Restored external 0-255 sample panning range with XM.
/ <rewbs> experimental: muting a channel with a VSTi playing should turn off the active note on that channel.
/ <rewbs> Midi pitch bend reset on each new note for that instrument's midi channel.
. v 1.17.02.34
- + <Relabsoluness> Added dynamic instrument list for Change Instrument item in pattern ctx menu.
+ + <re> Added dynamic instrument list for Change Instrument item in pattern ctx menu.
/ <rewbs> Disabled it for users who have opted for the old style context menu in general settings, + other minor change.
- + <Relabsoluness> Added "Clear selection" item in pattern ctx menu
- / <Relabsoluness> Can now set an instrument value for notes which previously had no attached instruments.
+ + <re> Added "Clear selection" item in pattern ctx menu
+ / <re> Can now set an instrument value for notes which previously had no attached instruments.
+ <rewbs> If you load a track with unrecognized plugins, you'll be prompted to search for the plugs on kvraudio.
. <rewbs> Fixed rare crash on playback if playing a song with missing plugins.
/ <rewbs> Minor code cleanups
@@ -703,4 +897,4 @@
Questions/comments/bug reports?
-------------------------------
-Visit http://modplug.sourceforge.net/forum.
\ No newline at end of file
+Visit http://modplug.sourceforge.net/forum.
Modified: trunk/OpenMPT/packageTemplate/SoundTouch/README.html
===================================================================
--- trunk/OpenMPT/packageTemplate/SoundTouch/README.html 2009-05-17 14:54:05 UTC (rev 258)
+++ trunk/OpenMPT/packageTemplate/SoundTouch/README.html 2009-05-30 21:21:35 UTC (rev 259)
@@ -14,10 +14,10 @@
SoundTouch readme providing documentation for the time stretching feature.<br>
SoundTouch WWW page: http://www.surina.net/soundtouch
</h5></font>
-<h1>SoundTouch audio processing library v1.3.1
+<h1>SoundTouch audio processing library v1.4.0
</h1>
<p class="normal">SoundTouch library Copyright (c) Olli
-Parviainen 2002-2006 </p>
+Parviainen 2002-2009 </p>
<hr>
<h2>3. About implementation & Usage tips</h2>
<h3>3.3. About algorithms</h3>
@@ -40,10 +40,10 @@
sound the default parameter set may result into a sub-optimal
result.</p>
<p>The time-stretch algorithm default
-parameter values are set by these #defines in file "TDStretch.h":</p>
+parameter values are set by these #defines in file "TDStretch.h":</p>
<blockquote>
- <pre>#define DEFAULT_SEQUENCE_MS 82
-#define DEFAULT_SEEKWINDOW_MS 28
+ <pre>#define DEFAULT_SEQUENCE_MS AUTOMATIC
+#define DEFAULT_SEEKWINDOW_MS AUTOMATIC
#define DEFAULT_OVERLAP_MS 12</pre>
</blockquote>
<p>These parameters affect to the time-stretch
@@ -55,13 +55,16 @@
the time-stretch algorithm. Larger values mean fewer sequences
are used in processing. In principle a larger value sounds better when
slowing down the tempo, but worse when increasing the tempo and vice
-versa.<br>
+versa. <br>
+ <br>
+ By default, this setting value is calculated automatically according to
+ tempo value.<br>
</li>
<li><strong>DEFAULT_SEEKWINDOW_MS</strong>: The seeking window
default length in milliseconds is for the algorithm that seeks the best
possible overlapping location. This determines from how
wide a sample "window" the algorithm can use to find an optimal mixing
-location when the sound sequences are to be linked back together.<br>
+location when the sound sequences are to be linked back together. <br>
<br>
The bigger this window setting is, the higher the possibility to find a
better mixing position becomes, but at the same time large values may
@@ -69,6 +72,9 @@
chosen at more uneven intervals. If there's a disturbing artifact that
sounds as if a constant frequency was drifting around, try reducing
this setting.<br>
+ <br>
+ By default, this setting value is calculated automatically according to
+ tempo value.<br>
</li>
<li><strong>DEFAULT_OVERLAP_MS</strong>: Overlap
length in milliseconds. When the sound sequences are mixed back
@@ -82,7 +88,7 @@
<p>Notice that these parameters can also be
set during execution time with functions "<strong>TDStretch::setParameters()</strong>"
and "<strong>SoundTouch::setSetting()</strong>".</p>
-<p>The table below summarizes how the
+<p>The table below summaries how the
parameters can be adjusted for different applications:</p>
<table border="1">
<tbody>
@@ -94,9 +100,7 @@
affects...</strong></td>
<td valign="top"><strong>Smaller value
affects...</strong></td>
- <td valign="top"><strong>Music</strong></td>
- <td valign="top"><strong>Speech</strong></td>
- <td valign="top"><strong>Effect in CPU burden</strong></td>
+ <td valign="top"><strong>Effect to CPU burden</strong></td>
</tr>
<tr>
<td valign="top">
@@ -110,9 +114,6 @@
<td valign="top">Smaller value might be better
for speeding up tempo. Reducing the value accelerates the "echoing"
artifact when slowing down the tempo </td>
- <td valign="top">Default value usually good</td>
- <td valign="top">A smaller value than default
-might be better</td>
<td valign="top">Increasing the parameter
value reduces computation burden</td>
</tr>
@@ -126,9 +127,6 @@
good mixing position, but may cause a "drifting" artifact</td>
<td valign="top">Smaller reduce possibility to
find a good mixing position, but reduce the "drifting" artifact.</td>
- <td valign="top">Default value usually good,
-unless a "drifting" artifact is disturbing.</td>
- <td valign="top">Default value usually good</td>
<td valign="top">Increasing the parameter
value increases computation burden</td>
</tr>
@@ -141,22 +139,124 @@
<td valign="top"> </td>
<td valign="top">If you reduce the "sequence
ms" setting, you might wish to try a smaller value.</td>
- <td valign="top"> </td>
- <td valign="top"> </td>
<td valign="top">Increasing the parameter
value increases computation burden</td>
</tr>
</tbody>
</table>
<hr>
-<h2 align="left">6. LICENSE </h2>
+<h2>5. Change History</h2>
+<h3>5.1. SoundTouch library Change History </h3>
+
+<p><strong>1.4.0:</strong></p>
+<ul>
+<li>Improved sound quality by automatic calculation of time stretch algorithm
+ processing parameters according to tempo setting</li>
+<li>Moved BPM detection routines from SoundStretch application into SoundTouch
+ library</li>
+<li>Bugfixes: Usage of uninitialied variables, GNU build scripts, compiler errors
+ due to 'const' keyword mismatch.</li>
+<li>Source code cleanup</li>
+
+</ul>
+
+<p><strong>v1.3.1:
+</strong></p>
+<ul>
+<li>Changed static class declaration to GCC 4.x compiler compatible syntax.</li>
+<li>Enabled MMX/SSE-optimized routines also for GCC compilers. Earlier
+the MMX/SSE-optimized routines were written in compiler-specific inline
+assembler, now these routines are migrated to use compiler intrinsic
+syntax which allows compiling the same MMX/SSE-optimized source code with
+both Visual C++ and GCC compilers. </li>
+<li>Set floating point as the default sample format and added switch to
+the GNU configure script for selecting the other sample format.</li>
+
+</ul>
+
+<p><strong>v1.3.0:
+</strong></p>
+<ul>
+ <li>Fixed tempo routine output duration inaccuracy due to rounding
+error </li>
+ <li>Implemented separate processing routines for integer and
+floating arithmetic to allow improvements to floating point routines
+(earlier used algorithms mostly optimized for integer arithmetic also
+for floating point samples) </li>
+ <li>Fixed a bug that distorts sound if sample rate changes during the
+sound stream </li>
+ <li>Fixed a memory leak that appeared in MMX/SSE/3DNow! optimized
+routines </li>
+ <li>Reduced redundant code pieces in MMX/SSE/3DNow! optimized
+routines vs. the standard C routines.</li>
+ <li>MMX routine incompatibility with new gcc compiler versions </li>
+ <li>Other miscellaneous bug fixes </li>
+</ul>
+<p><strong>v1.2.1: </strong></p>
+<ul>
+ <li>Added automake/autoconf scripts for GNU
+platforms (in courtesy of David Durham)</li>
+ <li>Fixed SCALE overflow bug in rate transposer
+routine.</li>
+ <li>Fixed 64bit address space bugs.</li>
+ <li>Created a 'soundtouch' namespace for
+SAMPLETYPE definitions.</li>
+</ul>
+<p><strong>v1.2.0: </strong></p>
+<ul>
+ <li>Added support for 32bit floating point sample
+data type with SSE/3DNow! optimizations for Win32 platform (SSE/3DNow! optimizations currently not supported in GCC environment)</li>
+ <li>Replaced 'make-gcc' script for GNU environment
+by master Makefile</li>
+ <li>Added time-stretch routine configurability to
+SoundTouch main class</li>
+ <li>Bugfixes</li>
+</ul>
+<p><strong>v1.1.1: </strong></p>
+<ul>
+ <li>Moved SoundTouch under lesser GPL license (LGPL). This allows using SoundTouch library in programs that aren't
+released under GPL license. </li>
+ <li>Changed MMX routine organiation so that MMX optimized routines are now implemented in classes that are derived from
+the basic classes having the standard non-mmx routines. </li>
+ <li>MMX routines to support gcc version 3. </li>
+ <li>Replaced windows makefiles by script using the .dsw files </li>
+</ul>
+<p><strong>v1.01: </strong></p>
+<ul>
+ <li>"mmx_gcc.cpp": Added "using namespace std" and
+removed "return 0" from a function with void return value to fix
+compiler errors when compiling the library in Solaris environment. </li>
+ <li>Moved file "FIFOSampleBuffer.h" to "include"
+directory to allow accessing the FIFOSampleBuffer class from external
+files. </li>
+</ul>
+<p><strong>v1.0: </strong></p>
+<ul>
+ <li>Initial release </li>
+</ul>
+<p> </p>
+<hr>
+<h2 >6. Acknowledgements </h2>
+<p >Kudos for these people who have submitted bugfixed since
+SoundTouch v1.3.1: </p>
+<ul>
+ <li>Arthur A</li>
+ <li>Richard Ash</li>
+ <li>Stanislav Brabec</li>
+ <li>Brian Cameron</li>
+ <li>Justin Frankel</li>
+ <li>Jason Garland</li>
+ <li>Takashi Iwai</li>
+</ul>
+<p >Moral greetings to all other contributors as well!</p>
+<hr>
+<h2 >7. LICENSE </h2>
<p>SoundTouch audio processing library<br>
Copyright (c) Olli Parviainen</p>
<p>This library is free software; you can
redistribute it and/or modify it under the terms of the GNU
-Lesser General Public License as published by the Free Software
-Foundation; either version 2.1 of the License, or (at your option)
-any later version.</p>
+Lesser General Public License vesrion 2.1 as published by the Free Software
+Foundation.</p>
<p>This library is distributed in the hope
that it will be useful, but WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A
Modified: trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb
===================================================================
--- trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb 2009-05-17 14:54:05 UTC (rev 258)
+++ trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb 2009-05-30 21:21:35 UTC (rev 259)
@@ -8,6 +8,8 @@
0:1346:2:79:1 //File/Open: Ctrl+O (KeyDown)
0:1348:2:87:1 //File/Close: Ctrl+W (KeyDown)
0:1349:2:83:1 //File/Save: Ctrl+S (KeyDown)
+0:1693:0:166:1 //Previous Document: (KeyDown)
+0:1694:0:167:1 //Next Document: (KeyDown)
0:1030:0:116:1 //Play song/Pause song: F5 (KeyDown)
0:1031:0:119:1 //Pause song: F8 (KeyDown)
0:1375:0:27:1 //Stop Song: ESC (KeyDown)
@@ -194,6 +196,7 @@
5:1229:0:55:1 //Set volume digit 7: 7 (KeyDown)
5:1229:0:103:1 //Set volume digit 7: 7 (ZEHNERTASTATUR) (KeyDown)
5:1230:0:56:1 //Set volume digit 8: 8 (KeyDown)
+5:1230:0:104:1 //Set volume digit 8: 8 (ZEHNERTASTATUR) (KeyDown)
5:1231:0:57:1 //Set volume digit 9: 9 (KeyDown)
5:1231:0:105:1 //Set volume digit 9: 9 (ZEHNERTASTATUR) (KeyDown)
5:1232:0:86:1 //Vol command - volume: V (KeyDown)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2009-05-17 14:54:15
|
Revision: 258
http://modplug.svn.sourceforge.net/modplug/?rev=258&view=rev
Author: relabsoluness
Date: 2009-05-17 14:54:05 +0000 (Sun, 17 May 2009)
Log Message:
-----------
. Pattern tab: Fix to possible crash when using undo after pattern resize (bug introduced in rev. 168).
./ Miscellaneous tweaks (typo fixes etc.).
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Modedit.cpp
trunk/OpenMPT/mptrack/Mptrack.cpp
trunk/OpenMPT/mptrack/dlg_misc.cpp
Modified: trunk/OpenMPT/mptrack/Modedit.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Modedit.cpp 2009-05-09 23:01:26 UTC (rev 257)
+++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-05-17 14:54:05 UTC (rev 258)
@@ -2093,10 +2093,11 @@
MODCOMMAND *newPattern = CSoundFile::AllocatePattern(nRows, m_SndFile.m_nChannels);
MODCOMMAND *oldPattern = m_SndFile.Patterns[nPattern];
if (!newPattern) return (UINT)-1;
+ const ROWINDEX nOldRowCount = m_SndFile.Patterns[nPattern].GetNumRows();
m_SndFile.Patterns[nPattern].SetData(newPattern, nRows);
if (oldPattern)
{
- memcpy(newPattern, oldPattern, m_SndFile.m_nChannels*m_SndFile.PatternSize[nPattern]*sizeof(MODCOMMAND));
+ memcpy(newPattern, oldPattern, m_SndFile.m_nChannels*nOldRowCount*sizeof(MODCOMMAND));
CSoundFile::FreePattern(oldPattern);
}
}
Modified: trunk/OpenMPT/mptrack/Mptrack.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Mptrack.cpp 2009-05-09 23:01:26 UTC (rev 257)
+++ trunk/OpenMPT/mptrack/Mptrack.cpp 2009-05-17 14:54:05 UTC (rev 258)
@@ -231,9 +231,9 @@
" [Mod] mptm files made with this version will be recognized as IT in 1.17.02.48.\n"
" [Mod] Automatic update check on startup is no longer available.\n"
" [Fix] Copy/Paste in pattern was partly broken when working with MOD format.\n"
- " [Fix] Fixed wrong version in IT files saved with compatibility save.\n"
+ " [Fix] Fixed wrong version in IT files saved with compatibility export.\n"
"\n"
- " For more detail, see history.txt.";
+ " For more detailed list of changes, see history.txt.";
CMainFrame::GetMainFrame()->MessageBox(firstOpenMessage, "OpenMPT v." MPT_VERSION_STR, MB_ICONINFORMATION);
}
@@ -1264,7 +1264,7 @@
// -> DESC="IT project files (.itp)"
"Impulse Tracker Projects (*.itp)|*.itp;*.itpz|"
// -! NEW_FEATURE#0023
- "Open MPT Modules (*.mptm)|*.mptm;*.mptmz|"
+ "OpenMPT Modules (*.mptm)|*.mptm;*.mptmz|"
"Other Modules (mtm,okt,mdl,669,far,...)|*.mtm;*.669;*.ult;*.wow;*.far;*.mdl;*.okt;*.dmf;*.ptm;*.med;*.ams;*.dbm;*.dsm;*.umx;*.amf;*.psm;*.mt2|"
"Wave Files (*.wav)|*.wav|"
"Midi Files (*.mid,*.rmi)|*.mid;*.rmi;*.smf|"
@@ -1651,7 +1651,7 @@
m_bmp.LoadBitmap(MAKEINTRESOURCE(IDB_MPTRACK));
wsprintf(s, "Build Date: %s", gszBuildDate);
SetDlgItemText(IDC_EDIT2, s);
- SetDlgItemText(IDC_EDIT3, CString("Open Modplug Tracker, version ") + MptVersion::str + " (development build)");
+ SetDlgItemText(IDC_EDIT3, CString("OpenMPT, version ") + MptVersion::str + " (development build)");
m_heContact.SetWindowText(
"Contact / Discussion:\r\n\
Modified: trunk/OpenMPT/mptrack/dlg_misc.cpp
===================================================================
--- trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-05-09 23:01:26 UTC (rev 257)
+++ trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-05-17 14:54:05 UTC (rev 258)
@@ -1967,7 +1967,7 @@
int param = m_pModDoc->MacroToPlugParam(&(m_MidiCfg.szMidiSFXExt[sfx*32]));
CVstPlugin *pVstPlugin;
char s[256];
- message.Format("These are the parameters that can be conrolled by macro SF%X:\n\n",sfx);
+ message.Format("These are the parameters that can be controlled by macro SF%X:\n\n",sfx);
for (UINT plug=0; plug<MAX_MIXPLUGINS; plug++)
{
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2009-05-09 23:01:43
|
Revision: 257
http://modplug.svn.sourceforge.net/modplug/?rev=257&view=rev
Author: relabsoluness
Date: 2009-05-09 23:01:26 +0000 (Sat, 09 May 2009)
Log Message:
-----------
. IT load: Macro config should now be loaded correctly also when loading IT files not made with MPT.
. IT compatibility export: tentative fix to hidden last sequence item when opened in IT.
. IT compatibility play: tentative fix to vibrato with ramp down waveform.
/ Misc: Minor changes to load functions.
/ Misc: Removed tremor effect description.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Moddoc.cpp
trunk/OpenMPT/soundlib/LOAD_AMF.CPP
trunk/OpenMPT/soundlib/Load_it.cpp
trunk/OpenMPT/soundlib/Load_mdl.cpp
trunk/OpenMPT/soundlib/Load_med.cpp
trunk/OpenMPT/soundlib/Load_mid.cpp
trunk/OpenMPT/soundlib/Load_mt2.cpp
trunk/OpenMPT/soundlib/Load_okt.cpp
trunk/OpenMPT/soundlib/Load_stm.cpp
trunk/OpenMPT/soundlib/Sampleio.cpp
trunk/OpenMPT/soundlib/Sndmix.cpp
Modified: trunk/OpenMPT/mptrack/Moddoc.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-05-02 20:42:19 UTC (rev 256)
+++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-05-09 23:01:26 UTC (rev 257)
@@ -2495,12 +2495,6 @@
wsprintf(s, "%dbpm", param);
break;
- case CMD_TREMOR:
- if(param)
- wsprintf(s, "ontime %d, offtime %d", param >> 4, param & 0x0F);
- else
- strcpy(s, "continue");
- break;
case CMD_RETRIG:
switch(param >> 4) {
Modified: trunk/OpenMPT/soundlib/LOAD_AMF.CPP
===================================================================
--- trunk/OpenMPT/soundlib/LOAD_AMF.CPP 2009-05-02 20:42:19 UTC (rev 256)
+++ trunk/OpenMPT/soundlib/LOAD_AMF.CPP 2009-05-09 23:01:26 UTC (rev 257)
@@ -174,7 +174,7 @@
DWORD dwMemPos;
if ((!lpStream) || (dwMemLength < 2048)) return FALSE;
- if ((!strncmp((LPCTSTR)lpStream, "ASYLUM Music Format V1.0", 25)) && (dwMemLength > 4096))
+ if ((!strncmp((LPCSTR)lpStream, "ASYLUM Music Format V1.0", 25)) && (dwMemLength > 4096))
{
UINT numorders, numpats, numsamples;
@@ -370,7 +370,7 @@
// Store tracks positions
BYTE **pTrackData = new BYTE *[realtrackcnt];
memset(pTrackData, 0, sizeof(pTrackData));
- for (UINT iTrack=0; iTrack<realtrackcnt; iTrack++) if (dwMemPos + 3 <= dwMemLength)
+ for (UINT iTrack=0; iTrack<realtrackcnt; iTrack++) if (dwMemPos <= dwMemLength-3)
{
UINT nTrkSize = LittleEndianW(*(USHORT *)(lpStream+dwMemPos));
nTrkSize += (UINT)lpStream[dwMemPos+2] << 16;
Modified: trunk/OpenMPT/soundlib/Load_it.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_it.cpp 2009-05-02 20:42:19 UTC (rev 256)
+++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-05-09 23:01:26 UTC (rev 257)
@@ -980,7 +980,7 @@
if (pifh->flags & 0x08) m_dwSongFlags |= SONG_LINEARSLIDES;
if (pifh->flags & 0x10) m_dwSongFlags |= SONG_ITOLDEFFECTS;
if (pifh->flags & 0x20) m_dwSongFlags |= SONG_ITCOMPATMODE;
- if (pifh->flags & 0x80) m_dwSongFlags |= SONG_EMBEDMIDICFG;
+ if ((pifh->flags & 0x80) || (pifh->special & 0x08)) m_dwSongFlags |= SONG_EMBEDMIDICFG;
if (pifh->flags & 0x1000) m_dwSongFlags |= SONG_EXFILTERRANGE;
memcpy(m_szNames[0], pifh->songname, 26);
m_szNames[0][26] = 0;
@@ -1241,7 +1241,7 @@
// Reading Samples
m_nSamples = pifh->smpnum;
if (m_nSamples >= MAX_SAMPLES) m_nSamples = MAX_SAMPLES-1;
- for (UINT nsmp=0; nsmp<pifh->smpnum; nsmp++) if ((smppos[nsmp]) && (smppos[nsmp] + sizeof(ITSAMPLESTRUCT) <= dwMemLength))
+ for (UINT nsmp=0; nsmp<pifh->smpnum; nsmp++) if ((smppos[nsmp]) && (smppos[nsmp] <= dwMemLength - sizeof(ITSAMPLESTRUCT)))
{
lastSampleSize = 0; //ensure lastsamplesize = 0 if last sample is empty, else we'll skip the MPTX stuff.
ITSAMPLESTRUCT *pis = (ITSAMPLESTRUCT *)(lpStream+smppos[nsmp]);
@@ -1761,7 +1761,6 @@
memset(&itss, 0, sizeof(itss));
memcpy(itss.filename, psmp->name, 12);
memcpy(itss.name, m_szNames[nsmp], 26);
- SetNullTerminator(itss.name);
itss.id = 0x53504D49;
itss.gvl = (BYTE)psmp->nGlobalVol;
@@ -2058,7 +2057,6 @@
memset(smpcount, 0, sizeof(smpcount));
memcpy(iti.filename, penv->filename, 12);
memcpy(iti.name, penv->name, 26);
- SetNullTerminator(iti.name);
iti.mbank = penv->wMidiBank;
iti.mpr = penv->nMidiProgram;
iti.mch = penv->nMidiChannel;
@@ -2376,7 +2374,6 @@
memset(&itss, 0, sizeof(itss));
memcpy(itss.filename, psmp->name, 12);
memcpy(itss.name, m_szNames[nsmp], 26);
- SetNullTerminator(itss.name);
itss.id = 0x53504D49;
itss.gvl = (BYTE)psmp->nGlobalVol;
if (m_nInstruments)
@@ -2545,6 +2542,10 @@
while (header.ordnum>0 && Order[header.ordnum-1]==0xFF) {
header.ordnum--;
}
+
+ if(header.ordnum + 1 < MAX_ORDERS)
+ header.ordnum++;
+
header.patnum = MAX_PATTERNS;
while ((header.patnum > 0) && (!Patterns[header.patnum-1])) {
header.patnum--;
Modified: trunk/OpenMPT/soundlib/Load_mdl.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_mdl.cpp 2009-05-02 20:42:19 UTC (rev 256)
+++ trunk/OpenMPT/soundlib/Load_mdl.cpp 2009-05-09 23:01:26 UTC (rev 257)
@@ -328,7 +328,6 @@
INSTRUMENTHEADER *penv = Headers[nins];
memset(penv, 0, sizeof(INSTRUMENTHEADER));
memcpy(penv->name, lpStream+dwPos+2, 32);
- SetNullTerminator(penv->name);
penv->nGlobalVol = 64;
penv->nPPC = 5*12;
SetDefaultInstrumentValues(penv);
@@ -458,7 +457,7 @@
{
DWORD dwLen = *((DWORD *)(lpStream+dwPos));
dwPos += 4;
- if ((dwPos+dwLen <= dwMemLength) && (dwLen > 4))
+ if ( (dwLen <= dwMemLength) && (dwPos <= dwMemLength - dwLen) && (dwLen > 4) )
{
flags = (pins->uFlags & CHN_16BIT) ? RS_MDL16 : RS_MDL8;
ReadSample(pins, flags, (LPSTR)(lpStream+dwPos), dwLen);
Modified: trunk/OpenMPT/soundlib/Load_med.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_med.cpp 2009-05-02 20:42:19 UTC (rev 256)
+++ trunk/OpenMPT/soundlib/Load_med.cpp 2009-05-09 23:01:26 UTC (rev 257)
@@ -521,7 +521,7 @@
dwBlockArr = BigEndian(pmmh->blockarr);
dwSmplArr = BigEndian(pmmh->smplarr);
dwExpData = BigEndian(pmmh->expdata);
- if ((dwExpData) && (dwExpData+sizeof(MMD0EXP) < dwMemLength))
+ if ((dwExpData) && (dwExpData < dwMemLength - sizeof(MMD0EXP)))
pmex = (MMD0EXP *)(lpStream+dwExpData);
else
pmex = NULL;
@@ -659,7 +659,7 @@
}
UINT pseq = 0;
- if ((playseqtable) && (playseqtable + nplayseq*4 < dwMemLength))
+ if ((playseqtable) && (playseqtable < dwMemLength) && (nplayseq*4 < dwMemLength - playseqtable))
{
pseq = BigEndian(((LPDWORD)(lpStream+playseqtable))[nplayseq]);
}
@@ -737,7 +737,7 @@
}
// Track Names
DWORD trackinfo_ofs = BigEndian(pmex->trackinfo_ofs);
- if ((trackinfo_ofs) && (trackinfo_ofs + m_nChannels * 4 < dwMemLength))
+ if ((trackinfo_ofs) && (trackinfo_ofs < dwMemLength) && (m_nChannels * 4 < dwMemLength - trackinfo_ofs))
{
DWORD *ptrktags = (DWORD *)(lpStream + trackinfo_ofs);
for (UINT i=0; i<m_nChannels; i++)
@@ -866,7 +866,7 @@
{
DWORD nameofs = BigEndian(pbi->blockname);
UINT namelen = BigEndian(pbi->blocknamelen);
- if ((nameofs < dwMemLength) && (nameofs+namelen < dwMemLength))
+ if ((nameofs < dwMemLength) && (namelen < dwMemLength - nameofs))
{
SetPatternName(iBlk, (LPCSTR)(lpStream+nameofs));
}
Modified: trunk/OpenMPT/soundlib/Load_mid.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_mid.cpp 2009-05-02 20:42:19 UTC (rev 256)
+++ trunk/OpenMPT/soundlib/Load_mid.cpp 2009-05-09 23:01:26 UTC (rev 257)
@@ -590,7 +590,7 @@
pmth = (MIDITRACKHEADER *)(lpStream+dwMemPos);
if (dwMemPos + 8 >= dwMemLength) break;
DWORD len = BigEndian(pmth->len);
- if ((pmth->id == 0x6B72544D) && (dwMemPos + 8 + len <= dwMemLength))
+ if ((pmth->id == 0x6B72544D) && (len <= dwMemLength - (dwMemPos + 8)))
{
#ifdef MIDI_DETAILED_LOG
Log(" track%d at offset %d len=%d ", itrk, dwMemPos+8, len);
Modified: trunk/OpenMPT/soundlib/Load_mt2.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_mt2.cpp 2009-05-02 20:42:19 UTC (rev 256)
+++ trunk/OpenMPT/soundlib/Load_mt2.cpp 2009-05-09 23:01:26 UTC (rev 257)
@@ -418,7 +418,7 @@
#ifdef MT2DEBUG
if (iIns <= pfh->wInstruments) Log(" Instrument #%d at offset %04X: %d bytes\n", iIns, dwMemPos, pmi->dwDataLen);
#endif
- if (((LONG)pmi->dwDataLen > 0) && (dwMemPos + pmi->dwDataLen + 40 <= dwMemLength))
+ if (((LONG)pmi->dwDataLen > 0) && (dwMemPos <= dwMemLength - 40) && (pmi->dwDataLen <= dwMemLength - (dwMemPos + 40)))
{
InstrMap[iIns-1] = pmi;
if (penv)
Modified: trunk/OpenMPT/soundlib/Load_okt.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_okt.cpp 2009-05-02 20:42:19 UTC (rev 256)
+++ trunk/OpenMPT/soundlib/Load_okt.cpp 2009-05-09 23:01:26 UTC (rev 257)
@@ -113,7 +113,7 @@
}
// PBOD
UINT npat = 0;
- while ((dwMemPos+10 < dwMemLength) && (*((DWORD *)(lpStream + dwMemPos)) == 0x444F4250))
+ while ((dwMemPos < dwMemLength-10) && (*((DWORD *)(lpStream + dwMemPos)) == 0x444F4250))
{
DWORD dwPos = dwMemPos + 10;
UINT rows = lpStream[dwMemPos+9];
@@ -189,7 +189,7 @@
}
// SBOD
UINT nsmp = 1;
- while ((dwMemPos+10 < dwMemLength) && (*((DWORD *)(lpStream + dwMemPos)) == 0x444F4253))
+ while ((dwMemPos < dwMemLength - 10) && (*((DWORD *)(lpStream + dwMemPos)) == 0x444F4253))
{
if (nsmp < MAX_SAMPLES) ReadSample(&Ins[nsmp], RS_PCM8S, (LPSTR)(lpStream+dwMemPos+8), dwMemLength-dwMemPos-8);
dwMemPos += BigEndian(*((DWORD *)(lpStream + dwMemPos + 4))) + 8;
Modified: trunk/OpenMPT/soundlib/Load_stm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_stm.cpp 2009-05-02 20:42:19 UTC (rev 256)
+++ trunk/OpenMPT/soundlib/Load_stm.cpp 2009-05-09 23:01:26 UTC (rev 257)
@@ -177,7 +177,7 @@
if (pIns->nLength)
{
UINT nPos = ((UINT)phdr->sample[nSmp-1].reserved) << 4;
- if ((nPos >= sizeof(STMHEADER)) && (nPos+pIns->nLength <= dwMemLength)) dwMemPos = nPos;
+ if ((nPos >= sizeof(STMHEADER)) && (nPos <= dwMemLength) && (pIns->nLength <= dwMemLength-nPos)) dwMemPos = nPos;
if (dwMemPos < dwMemLength)
{
dwMemPos += ReadSample(pIns, RS_PCM8S, (LPSTR)(lpStream+dwMemPos),dwMemLength-dwMemPos);
Modified: trunk/OpenMPT/soundlib/Sampleio.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sampleio.cpp 2009-05-02 20:42:19 UTC (rev 256)
+++ trunk/OpenMPT/soundlib/Sampleio.cpp 2009-05-09 23:01:26 UTC (rev 257)
@@ -566,7 +566,6 @@
if (xtrabytes >= 22)
{
memcpy(pins->name, pszTextEx, 22);
- SetNullTerminator(pins->name);
xtrabytes -= 22;
}
}
Modified: trunk/OpenMPT/soundlib/Sndmix.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndmix.cpp 2009-05-02 20:42:19 UTC (rev 256)
+++ trunk/OpenMPT/soundlib/Sndmix.cpp 2009-05-09 23:01:26 UTC (rev 257)
@@ -1276,7 +1276,10 @@
switch (pChn->nVibratoType & 0x03)
{
case 1:
- vdelta = ModRampDownTable[vibpos];
+ if(GetModFlag(MSF_IT_COMPATIBLE_PLAY) == true)
+ vdelta = -ModRampDownTable[(vibpos+16) % 64];
+ else
+ vdelta = ModRampDownTable[vibpos];
break;
case 2:
vdelta = ModSquareTable[vibpos];
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2009-05-02 20:42:23
|
Revision: 256
http://modplug.svn.sourceforge.net/modplug/?rev=256&view=rev
Author: relabsoluness
Date: 2009-05-02 20:42:19 +0000 (Sat, 02 May 2009)
Log Message:
-----------
. (patch from Jojo, merged somewhat modified) Fixes to MOD saving: it should now be possible to create ProTracker compatible MOD files with compatibility export.
+ Added a few hidable usage tips.
. Fix to parameter validation in ReadSample.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Ctrl_smp.cpp
trunk/OpenMPT/mptrack/MainFrm.cpp
trunk/OpenMPT/mptrack/Mainfrm.h
trunk/OpenMPT/mptrack/Moddoc.cpp
trunk/OpenMPT/mptrack/dlg_misc.cpp
trunk/OpenMPT/mptrack/dlg_misc.h
trunk/OpenMPT/mptrack/mptrack.rc
trunk/OpenMPT/mptrack/resource.h
trunk/OpenMPT/soundlib/Load_mod.cpp
trunk/OpenMPT/soundlib/Sndfile.cpp
trunk/OpenMPT/soundlib/Sndfile.h
Modified: trunk/OpenMPT/mptrack/Ctrl_smp.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2009-05-01 14:12:28 UTC (rev 255)
+++ trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2009-05-02 20:42:19 UTC (rev 256)
@@ -2242,9 +2242,10 @@
memset(&viewstate, 0, sizeof(viewstate));
SendViewMessage(VIEWMSG_SAVESTATE, (LPARAM)&viewstate);
if ((!m_pModDoc) || (!m_pSndFile) || (!m_pSndFile->Ins[m_nSample].pSample)) return;
- if( AfxMessageBox(TEXT(GetStrI18N("Apply signed/unsigned conversion(distortion)?\n\n"
- "Note: in many cases this increases volume level significantly.")), MB_YESNO|MB_ICONQUESTION) == IDNO )
- return;
+
+ if(m_pModDoc->IsNotePlaying(0, m_nSample, 0) == TRUE)
+ MsgBoxHidable(ConfirmSignUnsignWhenPlaying);
+
BeginWaitCursor();
pins = &m_pSndFile->Ins[m_nSample];
dwStart = viewstate.dwBeginSel;
Modified: trunk/OpenMPT/mptrack/MainFrm.cpp
===================================================================
--- trunk/OpenMPT/mptrack/MainFrm.cpp 2009-05-01 14:12:28 UTC (rev 255)
+++ trunk/OpenMPT/mptrack/MainFrm.cpp 2009-05-02 20:42:19 UTC (rev 256)
@@ -166,6 +166,8 @@
int CMainFrame::gnPlugWindowHeight = 332;
DWORD CMainFrame::gnPlugWindowLast = 0;
+uint32 CMainFrame::gnMsgBoxVisiblityFlags = ~0;
+
CRITICAL_SECTION CMainFrame::m_csAudio;
HANDLE CMainFrame::m_hPlayThread = NULL;
DWORD CMainFrame::m_dwPlayThreadId = 0;
@@ -391,6 +393,7 @@
gnPlugWindowWidth = GetPrivateProfileInt("Display", "PlugSelectWindowWidth", 370, iniFile);
gnPlugWindowHeight = GetPrivateProfileInt("Display", "PlugSelectWindowHeight", 332, iniFile);
gnPlugWindowLast = GetPrivateProfileDWord("Display", "PlugSelectWindowLast", 0, iniFile);
+ gnMsgBoxVisiblityFlags = GetPrivateProfileDWord("Display", "MsgBoxVisibilityFlags", ~0, iniFile);
CHAR s[16];
for (int ncol=0; ncol<MAX_MODCOLORS; ncol++) {
@@ -902,6 +905,7 @@
WritePrivateProfileLong("Display", "PlugSelectWindowWidth", gnPlugWindowWidth, iniFile);
WritePrivateProfileLong("Display", "PlugSelectWindowHeight", gnPlugWindowHeight, iniFile);
WritePrivateProfileLong("Display", "PlugSelectWindowLast", gnPlugWindowLast, iniFile);
+ WritePrivateProfileDWord("Display", "MsgBoxVisibilityFlags", gnMsgBoxVisiblityFlags, iniFile);
CHAR s[16];
for (int ncol=0; ncol<MAX_MODCOLORS; ncol++) {
Modified: trunk/OpenMPT/mptrack/Mainfrm.h
===================================================================
--- trunk/OpenMPT/mptrack/Mainfrm.h 2009-05-01 14:12:28 UTC (rev 255)
+++ trunk/OpenMPT/mptrack/Mainfrm.h 2009-05-02 20:42:19 UTC (rev 256)
@@ -425,6 +425,8 @@
static int gnPlugWindowHeight;
static DWORD gnPlugWindowLast;
+ static uint32 gnMsgBoxVisiblityFlags;
+
// Midi Input
public:
static HMIDIIN shMidiIn;
Modified: trunk/OpenMPT/mptrack/Moddoc.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-05-01 14:12:28 UTC (rev 255)
+++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-05-02 20:42:19 UTC (rev 256)
@@ -20,6 +20,12 @@
static char THIS_FILE[] = __FILE__;
#endif
+const TCHAR* const FileFilterMOD = TEXT("ProTracker Modules (*.mod)|*.mod||");
+const TCHAR* const FileFilterXM = TEXT("FastTracker Modules (*.xm)|*.xm||");
+const TCHAR* const FileFilterS3M = TEXT("ScreamTracker Modules (*.s3m)|*.s3m||");
+const TCHAR* const FileFilterIT = TEXT("Impulse Tracker Modules (*.it)|*.it||");
+const TCHAR* const FileFilterITP = TEXT("Impulse Tracker Projects (*.itp)|*.itp||");
+const TCHAR* const FileFilterMPT = TEXT("OpenMPT Modules (*.mptm)|*.mptm||");
/////////////////////////////////////////////////////////////////////////////
// CModDoc
@@ -487,18 +493,19 @@
switch(m_SndFile.GetType())
{
case MOD_TYPE_MOD:
+ MsgBoxHidable(ModCompatibilityExportTip);
lpszDefExt = "mod";
- lpszFilter = "ProTracker Modules (*.mod)|*.mod||";
+ lpszFilter = FileFilterMOD;
strcpy(fext, ".mod");
break;
case MOD_TYPE_S3M:
lpszDefExt = "s3m";
- lpszFilter = "ScreamTracker Modules (*.s3m)|*.s3m||";
+ lpszFilter = FileFilterS3M;
strcpy(fext, ".s3m");
break;
case MOD_TYPE_XM:
lpszDefExt = "xm";
- lpszFilter = "FastTracker Modules (*.xm)|*.xm||";
+ lpszFilter = FileFilterXM;
strcpy(fext, ".xm");
break;
case MOD_TYPE_IT:
@@ -509,19 +516,21 @@
// strcpy(fext, ".it");
if(m_SndFile.m_dwSongFlags & SONG_ITPROJECT){
lpszDefExt = "itp";
- lpszFilter = "Impulse Tracker Projects (*.itp)|*.itp||";
+ lpszFilter = FileFilterITP;
strcpy(fext, ".itp");
}
- else{
+ else
+ {
+ MsgBoxHidable(ItCompatibilityExportTip);
lpszDefExt = "it";
- lpszFilter = "Impulse Tracker Modules (*.it)|*.it||";
+ lpszFilter = FileFilterIT;
strcpy(fext, ".it");
}
// -! NEW_FEATURE#0023
break;
case MOD_TYPE_MPT:
lpszDefExt = "mptm";
- lpszFilter = "OpenMPT Modules (*.mptm)|*.mptm||";
+ lpszFilter = FileFilterMPT;
strcpy(fext, ".mptm");
break;
default:
@@ -1561,7 +1570,7 @@
//HACK: This is a quick fix. Needs to be better integrated into player and GUI.
void CModDoc::OnFileCompatibilitySave()
-//-------------------------------
+//-------------------------------------
{
CHAR path[_MAX_PATH]="", drive[_MAX_DRIVE]="";
CHAR s[_MAX_PATH], fname[_MAX_FNAME]="";
@@ -1571,21 +1580,34 @@
UINT type = m_SndFile.GetType();
if ((!pMainFrm) || (!m_SndFile.GetType())) return;
- switch (type) {
+ switch (type)
+ {
/*case MOD_TYPE_XM:
ext = "xm";
pattern = "Fast Tracker Files (*.xm)|*.xm||";
break;*/
+ case MOD_TYPE_MOD:
+ ext = MOD_STD_SPECS.fileExtension;
+ pattern = FileFilterMOD;
+ if( AfxMessageBox(GetStrI18N(TEXT(
+ "Compared to regular MOD save, compatibility export makes "
+ "small adjustments to the save file in order to make the file compatible with "
+ "ProTracker. Note that this feature is not complete and the "
+ "file is not guaranteed to be free of MPT-specific features.\n\n "
+ "Important: beginning of some samples may be adjusted in the process. Proceed?")), MB_ICONINFORMATION|MB_YESNO) != IDYES
+ )
+ return;
+ break;
case MOD_TYPE_IT:
- ext = "it";
- pattern = "Impulse Tracker Files (*.it)|*.it||";
+ ext = IT_STD_SPECS.fileExtension;
+ pattern = FileFilterIT;
+ ::MessageBox(NULL,"Warning: the exported file will not contain any of MPT's file-format hacks.", "Compatibility export warning.",MB_ICONINFORMATION | MB_OK);
break;
default:
- ::MessageBox(NULL,"Compatibility export is currently only available the IT format.", "Can't do compatibility export.",MB_ICONINFORMATION | MB_OK);
+ ::MessageBox(NULL,"Compatibility export is currently only available for MOD and IT modules.", "Can't do compatibility export.",MB_ICONINFORMATION | MB_OK);
return;
}
- ::MessageBox(NULL,"Warning: the exported file will not contain any of MPT's file-format hacks.", "Compatibility export warning.",MB_ICONINFORMATION | MB_OK);
_splitpath(GetPathName(), drive, path, fname, NULL);
strcpy(s, drive);
strcat(s, path);
@@ -1602,7 +1624,13 @@
if (dlg.DoModal() != IDOK){
return;
}
- switch (type) {
+ switch (type)
+ {
+ case MOD_TYPE_MOD:
+ m_SndFile.SaveMod(dlg.GetPathName(), 0, true);
+ SetModified(); // Compatibility save may adjust samples so set modified...
+ m_ShowSavedialog = true; // ...and force save dialog to appear when saving.
+ break;
case MOD_TYPE_XM:
m_SndFile.SaveCompatXM(dlg.GetPathName());
break;
Modified: trunk/OpenMPT/mptrack/dlg_misc.cpp
===================================================================
--- trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-05-01 14:12:28 UTC (rev 255)
+++ trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-05-02 20:42:19 UTC (rev 256)
@@ -2710,4 +2710,90 @@
CDialog::OnCancel();
}
+///////////////////////////////////////////////////////////////////////////////////////
+// Messagebox with 'don't show again'-option.
+//===================================
+class CMsgBoxHidable : public CDialog
+//===================================
+{
+public:
+ CMsgBoxHidable(LPCTSTR strMsg, bool checkStatus = true, CWnd* pParent = NULL);
+ enum { IDD = IDD_MSGBOX_HIDABLE };
+
+ int m_nCheckStatus;
+ LPCTSTR m_StrMsg;
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual BOOL OnInitDialog();
+};
+
+
+struct MsgBoxHidableMessage
+//=========================
+{
+ LPCTSTR strMsg;
+ uint32 nMask;
+ bool bDefaultDontShowAgainStatus; // true for don't show again, false for show again.
+};
+
+const MsgBoxHidableMessage HidableMessages[] =
+{
+ {TEXT("Tip: To create ProTracker compatible MOD-files, try compatibility export from File-menu."), 1, true},
+ {TEXT("Tip: To create IT-files without MPT-specific extensions included, try compatibility export from File-menu."), 1 << 1, true},
+ {TEXT("Press OK to apply signed/unsigned conversion\n (note: this often significantly increases volume level)"), 1 << 2, false}
+};
+
+STATIC_ASSERT(ARRAYELEMCOUNT(HidableMessages) == enMsgBoxHidableMessage_count);
+
+// Messagebox with 'don't show this again'-checkbox. Uses parameter 'enMsg'
+// to get the needed information from message array, and updates the variable that
+// controls the show/don't show-flags.
+void MsgBoxHidable(enMsgBoxHidableMessage enMsg)
+//----------------------------------------------
+{
+ // Check whether the message should be shown.
+ if((CMainFrame::gnMsgBoxVisiblityFlags & HidableMessages[enMsg].nMask) == 0)
+ return;
+
+ const LPCTSTR strMsg = HidableMessages[enMsg].strMsg;
+ const uint32 mask = HidableMessages[enMsg].nMask;
+ const bool defaulCheckStatus = HidableMessages[enMsg].bDefaultDontShowAgainStatus;
+
+ // Show dialog.
+ CMsgBoxHidable dlg(strMsg, defaulCheckStatus);
+ dlg.DoModal();
+
+ // Update visibility flags.
+ if(dlg.m_nCheckStatus == BST_CHECKED)
+ CMainFrame::gnMsgBoxVisiblityFlags &= ~mask;
+ else
+ CMainFrame::gnMsgBoxVisiblityFlags |= mask;
+}
+
+
+CMsgBoxHidable::CMsgBoxHidable(LPCTSTR strMsg, bool checkStatus, CWnd* pParent)
+ : CDialog(CMsgBoxHidable::IDD, pParent),
+ m_StrMsg(strMsg),
+ m_nCheckStatus((checkStatus) ? BST_CHECKED : BST_UNCHECKED)
+//----------------------------------------------------------------------------
+{}
+
+BOOL CMsgBoxHidable::OnInitDialog()
+//----------------------------------
+{
+ CDialog::OnInitDialog();
+ SetDlgItemText(IDC_MESSAGETEXT, m_StrMsg);
+ SetWindowText(AfxGetAppName());
+ return TRUE;
+}
+
+void CMsgBoxHidable::DoDataExchange(CDataExchange* pDX)
+//------------------------------------------------------
+{
+ CDialog::DoDataExchange(pDX);
+ DDX_Check(pDX, IDC_DONTSHOWAGAIN, m_nCheckStatus);
+}
+
+
+
Modified: trunk/OpenMPT/mptrack/dlg_misc.h
===================================================================
--- trunk/OpenMPT/mptrack/dlg_misc.h 2009-05-01 14:12:28 UTC (rev 255)
+++ trunk/OpenMPT/mptrack/dlg_misc.h 2009-05-02 20:42:19 UTC (rev 256)
@@ -493,4 +493,18 @@
};
+/////////////////////////////////////////////////////////////////////////
+// Messagebox with 'don't show again'-option.
+
+// Enums for message entries. See dlg_misc.cpp for the array of entries.
+enum enMsgBoxHidableMessage
+{
+ ModCompatibilityExportTip = 0,
+ ItCompatibilityExportTip = 1,
+ ConfirmSignUnsignWhenPlaying = 2,
+ enMsgBoxHidableMessage_count = 3
+};
+
+void MsgBoxHidable(enMsgBoxHidableMessage enMsg);
+
#endif
Modified: trunk/OpenMPT/mptrack/mptrack.rc
===================================================================
--- trunk/OpenMPT/mptrack/mptrack.rc 2009-05-01 14:12:28 UTC (rev 255)
+++ trunk/OpenMPT/mptrack/mptrack.rc 2009-05-02 20:42:19 UTC (rev 256)
@@ -2626,6 +2626,19 @@
// Dialog
//
+IDD_MSGBOX_HIDABLE DIALOGEX 0, 0, 186, 71
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+EXSTYLE WS_EX_TOOLWINDOW
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,149,50,30,14
+ PUSHBUTTON "Cancel",IDCANCEL,111,49,30,14,NOT WS_VISIBLE
+ CONTROL "Don't show this again.",IDC_DONTSHOWAGAIN,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,7,54,90,10
+ LTEXT "Static",IDC_MESSAGETEXT,7,7,172,40
+END
+
IDD_MIDIPARAMCONTROL DIALOGEX 0, 0, 392, 202
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
WS_SYSMENU
@@ -2837,6 +2850,14 @@
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
+ IDD_MSGBOX_HIDABLE, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 179
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 64
+ END
+
IDD_MIDIPARAMCONTROL, DIALOG
BEGIN
RIGHTMARGIN, 388
Modified: trunk/OpenMPT/mptrack/resource.h
===================================================================
--- trunk/OpenMPT/mptrack/resource.h 2009-05-01 14:12:28 UTC (rev 255)
+++ trunk/OpenMPT/mptrack/resource.h 2009-05-02 20:42:19 UTC (rev 256)
@@ -104,6 +104,7 @@
#define IDD_DIALOG3 513
#define IDS_ERR_TUNING_SERIALISATION 514
#define IDD_MIDIPARAMCONTROL 515
+#define IDD_MSGBOX_HIDABLE 516
#define IDC_BUTTON1 1001
#define IDC_BUTTON2 1002
#define IDC_BUTTON3 1003
@@ -825,6 +826,8 @@
#define IDC_EDIT_STRETCHPARAMS 2338
#define IDC_MIDI_MACRO_CONTROL 2339
#define IDC_MIDIPLAYPATTERNONMIDIIN 2340
+#define IDC_DONTSHOWAGAIN 2341
+#define IDC_MESSAGETEXT 2342
#define ID_FILE_NEWMOD 32771
#define ID_FILE_NEWXM 32772
#define ID_FILE_NEWS3M 32773
@@ -1057,9 +1060,9 @@
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_3D_CONTROLS 1
-#define _APS_NEXT_RESOURCE_VALUE 516
+#define _APS_NEXT_RESOURCE_VALUE 517
#define _APS_NEXT_COMMAND_VALUE 59221
-#define _APS_NEXT_CONTROL_VALUE 2341
+#define _APS_NEXT_CONTROL_VALUE 2343
#define _APS_NEXT_SYMED_VALUE 901
#endif
#endif
Modified: trunk/OpenMPT/soundlib/Load_mod.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_mod.cpp 2009-05-01 14:12:28 UTC (rev 255)
+++ trunk/OpenMPT/soundlib/Load_mod.cpp 2009-05-02 20:42:19 UTC (rev 256)
@@ -373,8 +373,8 @@
#ifndef MODPLUG_NO_FILESAVE
#pragma warning(disable:4100)
-BOOL CSoundFile::SaveMod(LPCSTR lpszFileName, UINT nPacking)
-//----------------------------------------------------------
+BOOL CSoundFile::SaveMod(LPCSTR lpszFileName, UINT nPacking, const bool bCompatibilityExport)
+//-------------------------------------------------------------------------------------------
{
BYTE insmap[32];
UINT inslen[32];
@@ -418,8 +418,11 @@
bTab[25] = pins->nVolume >> 2;
bTab[26] = pins->nLoopStart >> 9;
bTab[27] = pins->nLoopStart >> 1;
- bTab[28] = (pins->nLoopEnd - pins->nLoopStart) >> 9;
- bTab[29] = (pins->nLoopEnd - pins->nLoopStart) >> 1;
+ UINT replen = pins->nLoopEnd - pins->nLoopStart;
+ if(bCompatibilityExport && replen < 2) // ensure PT will load it properly
+ replen = 2;
+ bTab[28] = replen >> 9;
+ bTab[29] = replen >> 1;
fwrite(bTab, 30, 1, f);
}
// Writing number of patterns
@@ -501,6 +504,11 @@
for (UINT ismpd=1; ismpd<=31; ismpd++) if (inslen[ismpd])
{
MODINSTRUMENT *pins = &Ins[insmap[ismpd]];
+ if(bCompatibilityExport == true)
+ {
+ if(pins->nLength > 0) pins->pSample[0] = 0;
+ if(pins->nLength > 1) pins->pSample[1] = 0;
+ }
UINT flags = RS_PCM8S;
#ifndef NO_PACKING
if (!(pins->uFlags & (CHN_16BIT|CHN_STEREO)))
Modified: trunk/OpenMPT/soundlib/Sndfile.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-05-01 14:12:28 UTC (rev 255)
+++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-05-02 20:42:19 UTC (rev 256)
@@ -1899,12 +1899,13 @@
UINT CSoundFile::ReadSample(MODINSTRUMENT *pIns, UINT nFlags, LPCSTR lpMemFile, DWORD dwMemLength, const WORD format)
//-----------------------------------------------------------------------------------------------------------------------
{
+ if ((!pIns) || (pIns->nLength < 4) || (!lpMemFile)) return 0;
+
if(pIns->nLength > MAX_SAMPLE_LENGTH)
pIns->nLength = MAX_SAMPLE_LENGTH;
UINT len = 0, mem = pIns->nLength+6;
- if ((!pIns) || (pIns->nLength < 4) || (!lpMemFile)) return 0;
pIns->uFlags &= ~(CHN_16BIT|CHN_STEREO);
if (nFlags & RSF_16BIT)
{
Modified: trunk/OpenMPT/soundlib/Sndfile.h
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.h 2009-05-01 14:12:28 UTC (rev 255)
+++ trunk/OpenMPT/soundlib/Sndfile.h 2009-05-02 20:42:19 UTC (rev 256)
@@ -1074,7 +1074,7 @@
UINT WriteSample(FILE *f, MODINSTRUMENT *pins, UINT nFlags, UINT nMaxLen=0);
BOOL SaveXM(LPCSTR lpszFileName, UINT nPacking=0);
BOOL SaveS3M(LPCSTR lpszFileName, UINT nPacking=0);
- BOOL SaveMod(LPCSTR lpszFileName, UINT nPacking=0);
+ BOOL SaveMod(LPCSTR lpszFileName, UINT nPacking=0, const bool bCompatibilityExport = false);
BOOL SaveIT(LPCSTR lpszFileName, UINT nPacking=0);
BOOL SaveCompatIT(LPCSTR lpszFileName);
BOOL SaveCompatXM(LPCSTR lpszFileName);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2009-05-01 14:12:37
|
Revision: 255
http://modplug.svn.sourceforge.net/modplug/?rev=255&view=rev
Author: relabsoluness
Date: 2009-05-01 14:12:28 +0000 (Fri, 01 May 2009)
Log Message:
-----------
. Fix to faulty portamento handling on loading AMF (patch copied from libmodplug).
. Various string null termination and other validations to load functions.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/misc_util.h
trunk/OpenMPT/soundlib/Dlsbank.cpp
trunk/OpenMPT/soundlib/LOAD_AMF.CPP
trunk/OpenMPT/soundlib/Load_far.cpp
trunk/OpenMPT/soundlib/Load_it.cpp
trunk/OpenMPT/soundlib/Load_mdl.cpp
trunk/OpenMPT/soundlib/Load_med.cpp
trunk/OpenMPT/soundlib/Load_mt2.cpp
trunk/OpenMPT/soundlib/Load_ult.cpp
trunk/OpenMPT/soundlib/Sampleio.cpp
Modified: trunk/OpenMPT/mptrack/misc_util.h
===================================================================
--- trunk/OpenMPT/mptrack/misc_util.h 2009-04-04 20:15:12 UTC (rev 254)
+++ trunk/OpenMPT/mptrack/misc_util.h 2009-05-01 14:12:28 UTC (rev 255)
@@ -38,5 +38,14 @@
*/
}
+// Sets last character to null in given char array.
+// Size of the array must be known at compile time.
+template <size_t size>
+inline void SetNullTerminator(char (&buffer)[size])
+{
+ STATIC_ASSERT(size > 0);
+ buffer[size-1] = 0;
+}
+
#endif
Modified: trunk/OpenMPT/soundlib/Dlsbank.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Dlsbank.cpp 2009-04-04 20:15:12 UTC (rev 254)
+++ trunk/OpenMPT/soundlib/Dlsbank.cpp 2009-05-01 14:12:28 UTC (rev 255)
@@ -1592,7 +1592,7 @@
if (pSndFile->m_nType & MOD_TYPE_XM) psmp->uFlags |= CHN_PANNING;
}
}
- if (pins->szName[0]) memcpy(pSndFile->m_szNames[nSample], pins->szName, 32);
+ if (pins->szName[0]) memcpy(pSndFile->m_szNames[nSample], pins->szName, 31);
bOk = TRUE;
}
FreeWaveForm(pWaveForm);
@@ -1672,6 +1672,7 @@
} else
{
memcpy(penv->name, pins->szName, 32);
+ SetNullTerminator(penv->name);
}
int nTranspose = 0;
for (UINT iNoteMap=0; iNoteMap<NOTE_MAX; iNoteMap++)
Modified: trunk/OpenMPT/soundlib/LOAD_AMF.CPP
===================================================================
--- trunk/OpenMPT/soundlib/LOAD_AMF.CPP 2009-04-04 20:15:12 UTC (rev 254)
+++ trunk/OpenMPT/soundlib/LOAD_AMF.CPP 2009-05-01 14:12:28 UTC (rev 255)
@@ -109,8 +109,10 @@
else param = (param&0x0F)<<4;
break;
// 0x04: Porta Up/Down
- case 0x04: if (param & 0x80) { command = CMD_PORTAMENTOUP; param = -(signed char)param; }
- else { command = CMD_PORTAMENTODOWN; } break;
+ //case 0x04: if (param & 0x80) { command = CMD_PORTAMENTOUP; param = -(signed char)param; }
+ // else { command = CMD_PORTAMENTODOWN; } break;
+ case 0x04: if (param & 0x80) { command = CMD_PORTAMENTOUP; param = (-(signed char)param)&0x7F; }
+ else { command = CMD_PORTAMENTODOWN; } break;
// 0x06: Tone Portamento
case 0x06: command = CMD_TONEPORTAMENTO; break;
// 0x07: Tremor
@@ -268,7 +270,7 @@
|| (!pfh->numsamples) || (pfh->numsamples > MAX_SAMPLES)
|| (pfh->numchannels < 4) || (pfh->numchannels > 32))
return FALSE;
- memcpy(m_szNames[0], pfh->title, 32);
+ memcpy(m_szNames[0], pfh->title, 31);
dwMemPos = sizeof(AMFFILEHEADER);
m_nType = MOD_TYPE_AMF;
m_nChannels = pfh->numchannels;
@@ -330,7 +332,7 @@
AMFSAMPLE *psh = (AMFSAMPLE *)(lpStream + dwMemPos);
dwMemPos += sizeof(AMFSAMPLE);
- memcpy(m_szNames[iIns+1], psh->samplename, 32);
+ memcpy(m_szNames[iIns+1], psh->samplename, 31);
memcpy(pins->name, psh->filename, 13);
pins->nLength = LittleEndian(psh->length);
pins->nC4Speed = LittleEndianW(psh->c2spd);
Modified: trunk/OpenMPT/soundlib/Load_far.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_far.cpp 2009-04-04 20:15:12 UTC (rev 254)
+++ trunk/OpenMPT/soundlib/Load_far.cpp 2009-05-01 14:12:28 UTC (rev 255)
@@ -67,7 +67,7 @@
FARHEADER1 farHeader;
memcpy(&farHeader, lpStream, sizeof(FARHEADER1));
FARHEADER1 *pmh1 = &farHeader;
- FARHEADER2 *pmh2;
+ FARHEADER2 *pmh2 = 0;
DWORD dwMemPos = sizeof(FARHEADER1);
UINT headerlen;
BYTE samplemap[8];
@@ -87,7 +87,7 @@
m_nDefaultTempo = 80;
m_nDefaultGlobalVolume = 256;
- memcpy(m_szNames[0], pmh1->songname, 32);
+ memcpy(m_szNames[0], pmh1->songname, 31);
// Channel Setting
for (UINT nchpan=0; nchpan<16; nchpan++)
{
@@ -124,7 +124,7 @@
if (dwMemPos >= dwMemLength) return TRUE;
// byteswap pattern data.
- for(uint16 psfix = 256; psfix--;)
+ for(uint16 psfix = 0; psfix < 256; psfix++)
{
pmh2->patsiz[psfix] = LittleEndianW( pmh2->patsiz[psfix] ) ;
}
@@ -249,7 +249,7 @@
const FARSAMPLE *pfs = reinterpret_cast<const FARSAMPLE*>(lpStream + dwMemPos);
dwMemPos += sizeof(FARSAMPLE);
m_nSamples = ismp + 1;
- memcpy(m_szNames[ismp+1], pfs->samplename, 32);
+ memcpy(m_szNames[ismp+1], pfs->samplename, 31);
const DWORD length = LittleEndian( pfs->length );
pins->nLength = length;
pins->nLoopStart = LittleEndian(pfs->reppos) ;
Modified: trunk/OpenMPT/soundlib/Load_it.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_it.cpp 2009-04-04 20:15:12 UTC (rev 254)
+++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-05-01 14:12:28 UTC (rev 255)
@@ -600,6 +600,7 @@
// ChnSettings[i].szName
memcpy(&ChnSettings[i].szName[0],lpStream+streamPos,len);
+ SetNullTerminator(ChnSettings[i].szName);
streamPos += len;
}
@@ -647,6 +648,7 @@
for(i=0; i<m_nInstruments; i++){
ASSERT_CAN_READ(len);
memcpy(&m_szInstrumentPath[i][0],lpStream+streamPos,len);
+ SetNullTerminator(m_szInstrumentPath[i]);
streamPos += len;
}
@@ -1008,7 +1010,7 @@
if (m_nChannels < GetModSpecifications().channelsMin) m_nChannels = GetModSpecifications().channelsMin;
// Reading Song Message
- if ((pifh->special & 0x01) && (pifh->msglength) && (pifh->msgoffset + pifh->msglength < dwMemLength))
+ if ((pifh->special & 0x01) && (pifh->msglength) && (pifh->msglength <= dwMemLength) && (pifh->msgoffset < dwMemLength - pifh->msglength))
{
m_lpszSongComments = new char[pifh->msglength+1];
if (m_lpszSongComments)
@@ -1759,6 +1761,7 @@
memset(&itss, 0, sizeof(itss));
memcpy(itss.filename, psmp->name, 12);
memcpy(itss.name, m_szNames[nsmp], 26);
+ SetNullTerminator(itss.name);
itss.id = 0x53504D49;
itss.gvl = (BYTE)psmp->nGlobalVol;
@@ -2055,6 +2058,7 @@
memset(smpcount, 0, sizeof(smpcount));
memcpy(iti.filename, penv->filename, 12);
memcpy(iti.name, penv->name, 26);
+ SetNullTerminator(iti.name);
iti.mbank = penv->wMidiBank;
iti.mpr = penv->nMidiProgram;
iti.mch = penv->nMidiChannel;
@@ -2372,6 +2376,7 @@
memset(&itss, 0, sizeof(itss));
memcpy(itss.filename, psmp->name, 12);
memcpy(itss.name, m_szNames[nsmp], 26);
+ SetNullTerminator(itss.name);
itss.id = 0x53504D49;
itss.gvl = (BYTE)psmp->nGlobalVol;
if (m_nInstruments)
@@ -2681,6 +2686,7 @@
memset(smpcount, 0, sizeof(smpcount));
memcpy(iti.filename, penv->filename, 12);
memcpy(iti.name, penv->name, 26);
+ SetNullTerminator(iti.name);
iti.mbank = penv->wMidiBank;
iti.mpr = penv->nMidiProgram;
iti.mch = penv->nMidiChannel;
@@ -2988,6 +2994,7 @@
memset(&itss, 0, sizeof(itss));
memcpy(itss.filename, psmp->name, 12);
memcpy(itss.name, m_szNames[nsmp], 26);
+ SetNullTerminator(itss.name);
itss.id = 0x53504D49;
itss.gvl = (BYTE)psmp->nGlobalVol;
if (m_nInstruments)
Modified: trunk/OpenMPT/soundlib/Load_mdl.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_mdl.cpp 2009-04-04 20:15:12 UTC (rev 254)
+++ trunk/OpenMPT/soundlib/Load_mdl.cpp 2009-05-01 14:12:28 UTC (rev 255)
@@ -215,7 +215,7 @@
block = *((WORD *)(lpStream+dwMemPos));
blocklen = *((DWORD *)(lpStream+dwMemPos+2));
dwMemPos += 6;
- if (dwMemPos + blocklen > dwMemLength)
+ if (blocklen > dwMemLength - dwMemPos)
{
if (dwMemPos == 11) return FALSE;
break;
@@ -228,7 +228,7 @@
Log("infoblock: %d bytes\n", blocklen);
#endif
pmib = (MDLINFOBLOCK *)(lpStream+dwMemPos);
- memcpy(m_szNames[0], pmib->songname, 32);
+ memcpy(m_szNames[0], pmib->songname, 31);
norders = pmib->norders;
if (norders > MAX_ORDERS) norders = MAX_ORDERS;
m_nRestartPos = pmib->repeatpos;
@@ -328,6 +328,7 @@
INSTRUMENTHEADER *penv = Headers[nins];
memset(penv, 0, sizeof(INSTRUMENTHEADER));
memcpy(penv->name, lpStream+dwPos+2, 32);
+ SetNullTerminator(penv->name);
penv->nGlobalVol = 64;
penv->nPPC = 5*12;
SetDefaultInstrumentValues(penv);
@@ -411,7 +412,7 @@
if ((nins >= MAX_SAMPLES) || (!nins)) continue;
if (m_nSamples < nins) m_nSamples = nins;
MODINSTRUMENT *pins = &Ins[nins];
- memcpy(m_szNames[nins], lpStream+dwPos+1, 32);
+ memcpy(m_szNames[nins], lpStream+dwPos+1, 31);
memcpy(pins->name, lpStream+dwPos+33, 8);
const BYTE *p = lpStream+dwPos+41;
if (pmsh->version > 0)
Modified: trunk/OpenMPT/soundlib/Load_med.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_med.cpp 2009-04-04 20:15:12 UTC (rev 254)
+++ trunk/OpenMPT/soundlib/Load_med.cpp 2009-05-01 14:12:28 UTC (rev 255)
@@ -699,9 +699,11 @@
UINT annotxt = BigEndian(pmex->annotxt);
UINT annolen = BigEndian(pmex->annolen);
annolen = min(annolen, MED_MAX_COMMENT_LENGTH); //Thanks to Luigi Auriemma for pointing out an overflow risk
- if ((annotxt) && (annolen) && (annolen <= dwMemLength) && (annotxt <= dwMemLength - annolen) ) {
+ if ((annotxt) && (annolen) && (annolen <= dwMemLength) && (annotxt <= dwMemLength - annolen) )
+ {
m_lpszSongComments = new char[annolen+1];
- if (m_lpszSongComments) {
+ if (m_lpszSongComments)
+ {
memcpy(m_lpszSongComments, lpStream+annotxt, annolen);
m_lpszSongComments[annolen] = 0;
}
@@ -709,7 +711,7 @@
// Song Name
UINT songname = BigEndian(pmex->songname);
UINT songnamelen = BigEndian(pmex->songnamelen);
- if ((songname) && (songnamelen) && (songname+songnamelen <= dwMemLength))
+ if ((songname) && (songnamelen) && (songname <= dwMemLength) && (songnamelen <= dwMemLength-songname))
{
if (songnamelen > 31) songnamelen = 31;
memcpy(m_szNames[0], lpStream+songname, songnamelen);
@@ -722,14 +724,14 @@
UINT ientries = BigEndianW(pmex->i_ext_entries);
UINT ientrysz = BigEndianW(pmex->i_ext_entrsz);
- if ((iinfoptr) && (ientrysz < 256) && (iinfoptr + ientries*ientrysz < dwMemLength))
+ if ((iinfoptr) && (ientrysz < 256) && (ientries*ientrysz < dwMemLength) && (iinfoptr < dwMemLength - ientries*ientrysz))
{
LPCSTR psznames = (LPCSTR)(lpStream + iinfoptr);
UINT maxnamelen = ientrysz;
- if (maxnamelen > 32) maxnamelen = 32;
+ if (maxnamelen > 31) maxnamelen = 31;
for (UINT i=0; i<ientries; i++) if (i < m_nSamples)
{
- lstrcpyn(m_szNames[i+1], psznames + i*ientrysz, maxnamelen);
+ memcpy(m_szNames[i+1], psznames + i*ientrysz, maxnamelen);
}
}
}
@@ -742,7 +744,7 @@
{
DWORD trknameofs = 0, trknamelen = 0;
DWORD trktagofs = BigEndian(ptrktags[i]);
- if (trktagofs)
+ if (trktagofs && (trktagofs <= dwMemLength - 8) )
{
while (trktagofs+8 < dwMemLength)
{
@@ -757,9 +759,10 @@
trktagofs += 8;
}
if (trknamelen > MAX_CHANNELNAME) trknamelen = MAX_CHANNELNAME;
- if ((trknameofs) && (trknameofs + trknamelen < dwMemLength))
+ if ((trknameofs) && (trknameofs < dwMemLength - trknamelen))
{
- lstrcpyn(ChnSettings[i].szName, (LPCSTR)(lpStream+trknameofs), MAX_CHANNELNAME);
+ memcpy(ChnSettings[i].szName, (LPCSTR)(lpStream+trknameofs), MAX_CHANNELNAME);
+ SetNullTerminator(ChnSettings[i].szName);
}
}
}
Modified: trunk/OpenMPT/soundlib/Load_mt2.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_mt2.cpp 2009-04-04 20:15:12 UTC (rev 254)
+++ trunk/OpenMPT/soundlib/Load_mt2.cpp 2009-05-01 14:12:28 UTC (rev 255)
@@ -406,6 +406,7 @@
{
memset(penv, 0, sizeof(INSTRUMENTHEADER));
memcpy(penv->name, pmi->szName, 32);
+ SetNullTerminator(penv->name);
penv->nGlobalVol = 64;
penv->nPan = 128;
for (UINT i=0; i<NOTE_MAX; i++)
@@ -536,7 +537,7 @@
#endif
if (iSmp < MAX_SAMPLES)
{
- memcpy(m_szNames[iSmp], pms->szName, 32);
+ memcpy(m_szNames[iSmp], pms->szName, 31);
}
if (pms->dwDataLen > 0)
{
Modified: trunk/OpenMPT/soundlib/Load_ult.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_ult.cpp 2009-04-04 20:15:12 UTC (rev 254)
+++ trunk/OpenMPT/soundlib/Load_ult.cpp 2009-05-01 14:12:28 UTC (rev 255)
@@ -60,7 +60,7 @@
m_nType = MOD_TYPE_ULT;
m_nDefaultSpeed = 6;
m_nDefaultTempo = 125;
- memcpy(m_szNames[0], pmh->songtitle, 32);
+ memcpy(m_szNames[0], pmh->songtitle, 31);
// read songtext
dwMemPos = sizeof(ULTHEADER);
if ((pmh->reserved) && (dwMemPos + pmh->reserved * 32 < dwMemLength))
@@ -89,7 +89,7 @@
{
pus = (ULTSAMPLE *)(lpStream+dwMemPos);
MODINSTRUMENT *pins = &Ins[ins];
- memcpy(m_szNames[ins], pus->samplename, 32);
+ memcpy(m_szNames[ins], pus->samplename, 31);
memcpy(pins->name, pus->dosname, 12);
pins->nLoopStart = pus->loopstart;
pins->nLoopEnd = pus->loopend;
Modified: trunk/OpenMPT/soundlib/Sampleio.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sampleio.cpp 2009-04-04 20:15:12 UTC (rev 254)
+++ trunk/OpenMPT/soundlib/Sampleio.cpp 2009-05-01 14:12:28 UTC (rev 255)
@@ -524,7 +524,7 @@
if ((dwInfoList+d+8+len <= dwFileLength) && (len))
{
DWORD dwNameLen = len;
- if (dwNameLen > 32) dwNameLen = 32;
+ if (dwNameLen > 31) dwNameLen = 31;
memcpy(m_szNames[nSample], lpMemFile+dwInfoList+d+8, dwNameLen);
if (phdr->id_RIFF != 0x46464952)
{
@@ -560,12 +560,13 @@
LPSTR pszTextEx = (LPSTR)(pxh+1);
if (xtrabytes >= 32)
{
- memcpy(m_szNames[nSample], pszTextEx, 32);
+ memcpy(m_szNames[nSample], pszTextEx, 31);
pszTextEx += 32;
xtrabytes -= 32;
if (xtrabytes >= 22)
{
memcpy(pins->name, pszTextEx, 22);
+ SetNullTerminator(pins->name);
xtrabytes -= 22;
}
}
@@ -1875,6 +1876,7 @@
iti->id = 0x49504D49; // "IMPI"
memcpy(iti->filename, penv->filename, 12);
memcpy(iti->name, penv->name, 26);
+ SetNullTerminator(iti->name);
iti->mpr = penv->nMidiProgram;
iti->mch = penv->nMidiChannel;
iti->mbank = penv->wMidiBank; //rewbs.MidiBank
@@ -2125,7 +2127,7 @@
case IFFID_NAME:
{
UINT len = dwChunkLen;
- if (len > 32) len = 32;
+ if (len > 31) len = 31;
memset(m_szNames[nSample], 0, 32);
memcpy(m_szNames[nSample], pChunkData, len);
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2009-04-04 20:15:26
|
Revision: 254
http://modplug.svn.sourceforge.net/modplug/?rev=254&view=rev
Author: relabsoluness
Date: 2009-04-04 20:15:12 +0000 (Sat, 04 Apr 2009)
Log Message:
-----------
(Patches from Jojo, merged slightly modified)
+ Sample tab: Can now normalize sample selections.
. Envelope view: Middle line will now be drawn in panning and pitch/filter envelopes even if row guidelines are enabled.
/ PackageTemplate:: Update to DE_jojo-keymap
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Ctrl_smp.cpp
trunk/OpenMPT/mptrack/View_ins.cpp
trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb
Modified: trunk/OpenMPT/mptrack/Ctrl_smp.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2009-04-04 19:09:48 UTC (rev 253)
+++ trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2009-04-04 20:15:12 UTC (rev 254)
@@ -1037,7 +1037,9 @@
//Default case: Normalize current sample
UINT iMinSample = m_nSample, iMaxSample = m_nSample;
-
+ //If only one sample is selected, parts of it may be amplified
+ UINT iStart = 0, iEnd = 0;
+
//Shift -> Normalize all samples
if(CMainFrame::GetInputHandler()->ShiftPressed())
{
@@ -1045,6 +1047,13 @@
if(ans == IDNO) return;
iMinSample = 1;
iMaxSample = m_pSndFile->m_nSamples;
+ } else {
+ SAMPLEVIEWSTATE viewstate;
+ memset(&viewstate, 0, sizeof(viewstate));
+ SendViewMessage(VIEWMSG_SAVESTATE, (LPARAM)&viewstate);
+
+ iStart = viewstate.dwBeginSel;
+ iEnd = viewstate.dwEndSel;
}
@@ -1058,13 +1067,26 @@
BOOL bOk = FALSE;
MODINSTRUMENT *pins = &m_pSndFile->Ins[iSmp];
+ if(iMinSample != iMaxSample) {
+ //if more than one sample is selected, always amplify the whole sample.
+ iStart = 0;
+ iEnd = pins->nLength;
+ } else {
+ //one sample: correct the boundaries, if needed
+ if (iEnd > pins->nLength) iEnd = pins->nLength;
+ if (iStart > iEnd) iStart = iEnd;
+ if (iStart == iEnd) {
+ iStart = 0;
+ iEnd = pins->nLength;
+ }
+ }
+ if (pins->uFlags & CHN_STEREO) { iStart *= 2; iEnd *= 2; }
+
if (pins->uFlags & CHN_16BIT)
{
- UINT len = pins->nLength;
signed short *p = (signed short *)pins->pSample;
- if (pins->uFlags & CHN_STEREO) len *= 2;
int max = 1;
- for (UINT i=0; i<len; i++)
+ for (UINT i = iStart; i < iEnd; i++)
{
if (p[i] > max) max = p[i];
if (-p[i] > max) max = -p[i];
@@ -1072,7 +1094,7 @@
if (max < 32767)
{
max++;
- for (UINT j=0; j<len; j++)
+ for (UINT j = iStart; j < iEnd; j++)
{
int l = p[j];
p[j] = (l << 15) / max;
@@ -1081,11 +1103,9 @@
}
} else
{
- UINT len = pins->nLength;
signed char *p = (signed char *)pins->pSample;
- if (pins->uFlags & CHN_STEREO) len *= 2;
int max = 1;
- for (UINT i=0; i<len; i++)
+ for (UINT i = iStart; i < iEnd; i++)
{
if (p[i] > max) max = p[i];
if (-p[i] > max) max = -p[i];
@@ -1093,7 +1113,7 @@
if (max < 127)
{
max++;
- for (UINT j=0; j<len; j++)
+ for (UINT j = iStart; j < iEnd; j++)
{
int l = p[j];
p[j] = (l << 7) / max;
Modified: trunk/OpenMPT/mptrack/View_ins.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_ins.cpp 2009-04-04 19:09:48 UTC (rev 253)
+++ trunk/OpenMPT/mptrack/View_ins.cpp 2009-04-04 20:15:12 UTC (rev 254)
@@ -1268,15 +1268,15 @@
//hdc = pDC->m_hDC;
oldpen = m_dcMemMain.SelectObject(CMainFrame::penDarkGray);
m_dcMemMain.FillRect(&m_rcClient, CBrush::FromHandle(CMainFrame::brushBlack));
+ if (m_bGrid)
+ {
+ DrawGrid(&m_dcMemMain, pSndFile->m_nMusicSpeed);
+ }
if (m_nEnv != ENV_VOLUME)
{
m_dcMemMain.MoveTo(0, ymed);
m_dcMemMain.LineTo(m_rcClient.right, ymed);
}
- if (m_bGrid)
- {
- DrawGrid(&m_dcMemMain, pSndFile->m_nMusicSpeed);
- }
m_dcMemMain.SelectObject(CMainFrame::penDarkGray);
// Drawing Loop Start/End
if (EnvGetLoop())
Modified: trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb
===================================================================
--- trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb 2009-04-04 19:09:48 UTC (rev 253)
+++ trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb 2009-04-04 20:15:12 UTC (rev 254)
@@ -6,6 +6,7 @@
//----( Global Context (0) )------------
0:1347:2:78:1 //File/New: Ctrl+N (KeyDown)
0:1346:2:79:1 //File/Open: Ctrl+O (KeyDown)
+0:1348:2:87:1 //File/Close: Ctrl+W (KeyDown)
0:1349:2:83:1 //File/Save: Ctrl+S (KeyDown)
0:1030:0:116:1 //Play song/Pause song: F5 (KeyDown)
0:1031:0:119:1 //Pause song: F8 (KeyDown)
@@ -19,6 +20,7 @@
0:1361:2:67:1 //Copy: Ctrl+C (KeyDown)
0:1361:2:45:1 //Copy: Ctrl+EINFG (KeyDown)
0:1362:2:86:1 //Paste: Ctrl+V (KeyDown)
+0:1363:3:86:1 //Mix Paste: Shift+Ctrl+V (KeyDown)
0:1686:1:86:1 //Mix Paste (old IT Style): Shift+V (KeyDown)
0:1364:2:53:1 //SelectAll: Ctrl+5 (KeyDown)
0:1365:2:70:1 //Find: Ctrl+F (KeyDown)
@@ -62,6 +64,7 @@
2:1049:6:35:1 //Go to last row of last channel: Ctrl+Alt+ENDE (KeyDown)
2:1050:1:16:1 //Selection key: Shift+UMSCHALT (KeyDown)
2:1011:2:76:1 //Select channel / Select all: Ctrl+L (KeyDown)
+2:1663:0:145:1 //Toggle follow song: ROLLEN-FESTSTELL (KeyDown)
2:1003:0:13:1 //Quick copy: EINGABE (KeyDown)
2:1004:0:32:5 //Quick paste: LEER (KeyDown|KeyHold)
2:1001:2:32:1 //Enable recording: Ctrl+LEER (KeyDown)
@@ -79,10 +82,12 @@
2:1014:2:74:1 //Interpolate volume: Ctrl+J (KeyDown)
2:1015:2:75:1 //Interpolate effect: Ctrl+K (KeyDown)
2:1016:4:66:1 //Open effect visualizer: Alt+B (KeyDown)
+2:1766:2:71:1 //Go to row/channel/...: Ctrl+G (KeyDown)
2:1013:2:73:1 //Apply current instrument: Ctrl+I (KeyDown)
2:1660:4:69:5 //Grow selection: Alt+E (KeyDown|KeyHold)
2:1661:4:68:5 //Shrink selection: Alt+D (KeyDown|KeyHold)
2:1059:2:46:1 //Clear row and step: Ctrl+ENTF (KeyDown)
+2:1060:1:46:1 //Clear field and step: Shift+ENTF (KeyDown)
2:1665:0:46:1 //Clear field and step (IT Style): ENTF (KeyDown)
2:1061:0:8:5 //Delete rows: R\xDCCK (KeyDown|KeyHold)
2:1377:2:8:5 //Delete all rows: Ctrl+R\xDCCK (KeyDown|KeyHold)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2009-04-04 19:09:52
|
Revision: 253
http://modplug.svn.sourceforge.net/modplug/?rev=253&view=rev
Author: relabsoluness
Date: 2009-04-04 19:09:48 +0000 (Sat, 04 Apr 2009)
Log Message:
-----------
/ Small tweaks(ctrl_smp, setup dialog).
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Ctrl_smp.cpp
trunk/OpenMPT/mptrack/Mpdlgs.cpp
Modified: trunk/OpenMPT/mptrack/Ctrl_smp.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2009-03-30 22:41:07 UTC (rev 252)
+++ trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2009-04-04 19:09:48 UTC (rev 253)
@@ -1665,7 +1665,7 @@
default: wsprintf(str,"Unknown Error...");
break;
}
- ::MessageBox(NULL,str,"Error",MB_ICONERROR);
+ AfxMessageBox(str, MB_ICONERROR);
}
// Update sample view
@@ -1759,12 +1759,26 @@
MODINSTRUMENT *pins = &m_pSndFile->Ins[m_nSample];
if(!pins) return -1;
+ const uint32 nSampleRate = pins->GetSampleRate(m_pSndFile->GetType());
+
+ // SoundTouch(v1.4.0) documentation says that sample rates 8000-48000 are supported.
+ // Check whether sample rate is within that range, and if not,
+ // ask user whether to proceed.
+ if(nSampleRate < 8000 || nSampleRate > 48000)
+ {
+ CString str;
+ str.Format(TEXT(GetStrI18N("Current samplerate, %u Hz, is not in the supported samplerate range 8000 Hz - 48000 Hz. Continue?")), nSampleRate);
+ if(AfxMessageBox(str, MB_ICONQUESTION|MB_YESNO) != IDYES)
+ return -1;
+
+ }
+
// Stretching is implemented only for 16-bit samples. Return with
// error if trying to use wtih non 16-bit samples.
if(pins->GetElementarySampleSize() != 2)
return 4;
- // SoundTouch seems to crash with short samples. Don't know what
+ // SoundTouch(1.3.1) seems to crash with short samples. Don't know what
// the actual limit or whether it depends on sample rate,
// but simply set some semiarbitrary threshold here.
if(pins->nLength < 256)
@@ -1832,7 +1846,6 @@
// Initialize soundtouch object.
{
- const uint32 nSampleRate = pins->GetSampleRate(m_pSndFile->GetType());
if(nSampleRate < 300) // Too low samplerate crashes soundtouch.
{ // Limiting it to value 300(quite arbitrarily chosen).
delete pSoundTouch;
@@ -2209,6 +2222,9 @@
memset(&viewstate, 0, sizeof(viewstate));
SendViewMessage(VIEWMSG_SAVESTATE, (LPARAM)&viewstate);
if ((!m_pModDoc) || (!m_pSndFile) || (!m_pSndFile->Ins[m_nSample].pSample)) return;
+ if( AfxMessageBox(TEXT(GetStrI18N("Apply signed/unsigned conversion(distortion)?\n\n"
+ "Note: in many cases this increases volume level significantly.")), MB_YESNO|MB_ICONQUESTION) == IDNO )
+ return;
BeginWaitCursor();
pins = &m_pSndFile->Ins[m_nSample];
dwStart = viewstate.dwBeginSel;
Modified: trunk/OpenMPT/mptrack/Mpdlgs.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Mpdlgs.cpp 2009-03-30 22:41:07 UTC (rev 252)
+++ trunk/OpenMPT/mptrack/Mpdlgs.cpp 2009-04-04 19:09:48 UTC (rev 253)
@@ -283,7 +283,7 @@
else
{
m_PreAmpNoteShowed = true;
- MessageBox(str_preampChangeNote, _TEXT(""), MB_ICONINFORMATION);
+ AfxMessageBox(str_preampChangeNote, MB_ICONINFORMATION);
SetPreAmpSliderPosition();
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2009-03-30 22:41:23
|
Revision: 252
http://modplug.svn.sourceforge.net/modplug/?rev=252&view=rev
Author: relabsoluness
Date: 2009-03-30 22:41:07 +0000 (Mon, 30 Mar 2009)
Log Message:
-----------
Instrument tuning related changes:
. Creating 'group geometric' was broken.
/ Return-key won't now close the dialog.
/ Added index in front of note names.
/ groupsize and groupratio edits are now enabled with general types.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/TuningDialog.cpp
trunk/OpenMPT/mptrack/TuningDialog.h
trunk/OpenMPT/mptrack/tuningRatioMapWnd.cpp
trunk/OpenMPT/soundlib/tuningbase.cpp
Modified: trunk/OpenMPT/mptrack/TuningDialog.cpp
===================================================================
--- trunk/OpenMPT/mptrack/TuningDialog.cpp 2009-03-07 21:24:44 UTC (rev 251)
+++ trunk/OpenMPT/mptrack/TuningDialog.cpp 2009-03-30 22:41:07 UTC (rev 252)
@@ -273,8 +273,8 @@
}
else //case: m_pActiveTuning is of type general.
{
- m_EditSteps.EnableWindow(false);
- m_EditRatioPeriod.EnableWindow(false);
+ //m_EditSteps.EnableWindow(false);
+ //m_EditRatioPeriod.EnableWindow(false);
}
m_EditRatioPeriod.Invalidate();
@@ -1293,6 +1293,17 @@
}
+void CTuningDialog::OnOK()
+//------------------------
+{
+ // Prevent return-key from closing the window.
+ if(GetKeyState(VK_RETURN) <= -127)
+ return;
+ else
+ CDialog::OnOK();
+}
+
+
////////////////////////////////////////////////////////
//***************
//CTuningTreeCtrl
Modified: trunk/OpenMPT/mptrack/TuningDialog.h
===================================================================
--- trunk/OpenMPT/mptrack/TuningDialog.h 2009-03-07 21:24:44 UTC (rev 251)
+++ trunk/OpenMPT/mptrack/TuningDialog.h 2009-03-30 22:41:07 UTC (rev 252)
@@ -321,6 +321,7 @@
void DoErrorExit();
+ virtual void OnOK();
//Treectrl context menu functions.
public:
Modified: trunk/OpenMPT/mptrack/tuningRatioMapWnd.cpp
===================================================================
--- trunk/OpenMPT/mptrack/tuningRatioMapWnd.cpp 2009-03-07 21:24:44 UTC (rev 251)
+++ trunk/OpenMPT/mptrack/tuningRatioMapWnd.cpp 2009-03-30 22:41:07 UTC (rev 252)
@@ -64,9 +64,12 @@
const bool isValidNote = m_pTuning->IsValidNote(noteToDraw);
string temp;
- if(isValidNote) temp = m_pTuning->GetNoteName(noteToDraw);
+ if(isValidNote)
+ {
+ temp = "(" + Stringify(noteToDraw) + ") " + m_pTuning->GetNoteName(noteToDraw);
+ }
- if(isValidNote && temp.size() < sizeofS)
+ if(isValidNote && temp.size()+1 < sizeofS)
wsprintf(s, "%s", temp.c_str());
else
wsprintf(s, "%s", "...");
Modified: trunk/OpenMPT/soundlib/tuningbase.cpp
===================================================================
--- trunk/OpenMPT/soundlib/tuningbase.cpp 2009-03-07 21:24:44 UTC (rev 251)
+++ trunk/OpenMPT/soundlib/tuningbase.cpp 2009-03-30 22:41:07 UTC (rev 252)
@@ -431,7 +431,7 @@
return true;
if(m_TuningType == TT_GROUPGEOMETRIC)
- return CreateGroupGeometric(s, GetGroupRatio(), GetValidityRange().first);
+ return CreateGroupGeometric(s, GetGroupRatio(), 0);
if(m_TuningType == TT_GEOMETRIC)
return CreateGeometric(s, GetGroupRatio());
@@ -448,7 +448,7 @@
return true;
if(m_TuningType == TT_GROUPGEOMETRIC)
- return CreateGroupGeometric(GetGroupSize(), r, GetValidityRange().first);
+ return CreateGroupGeometric(GetGroupSize(), r, 0);
if(m_TuningType == TT_GEOMETRIC)
return CreateGeometric(GetGroupSize(), r);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|