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-09-01 18:50:54
|
Revision: 351
http://modplug.svn.sourceforge.net/modplug/?rev=351&view=rev
Author: relabsoluness
Date: 2009-09-01 18:50:33 +0000 (Tue, 01 Sep 2009)
Log Message:
-----------
[Ref] Moved constants from Sndfile.h to a new file, renamed OrderToPatternTable files, added some utility functions, minor code cleanup.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/misc_util.h
trunk/OpenMPT/mptrack/mptrack.vcproj
trunk/OpenMPT/mptrack/mptrack_08.vcproj
trunk/OpenMPT/mptrack/typedefs.h
trunk/OpenMPT/soundlib/Sndfile.h
trunk/OpenMPT/soundlib/mod_specifications.h
trunk/OpenMPT/soundlib/pattern.h
trunk/OpenMPT/soundlib/patternContainer.h
Added Paths:
-----------
trunk/OpenMPT/soundlib/ModSequence.cpp
trunk/OpenMPT/soundlib/ModSequence.h
trunk/OpenMPT/soundlib/Snd_defs.h
Removed Paths:
-------------
trunk/OpenMPT/soundlib/OrderToPatternTable.cpp
trunk/OpenMPT/soundlib/OrderToPatternTable.h
Modified: trunk/OpenMPT/mptrack/misc_util.h
===================================================================
--- trunk/OpenMPT/mptrack/misc_util.h 2009-08-30 22:27:15 UTC (rev 350)
+++ trunk/OpenMPT/mptrack/misc_util.h 2009-09-01 18:50:33 UTC (rev 351)
@@ -81,4 +81,33 @@
LPCCH LoadResource(LPCTSTR lpName, LPCTSTR lpType, LPCCH& pData, size_t& nSize, HGLOBAL& hglob);
+namespace utilImpl
+{
+ template <bool bMemcpy>
+ struct ArrayCopyImpl {};
+
+ template <>
+ struct ArrayCopyImpl<true>
+ {
+ template <class T>
+ static void Do(T* pDst, const T* pSrc, const size_t n) {memcpy(pDst, pSrc, sizeof(T) * n);}
+ };
+
+ template <>
+ struct ArrayCopyImpl<false>
+ {
+ template <class T>
+ static void Do(T* pDst, const T* pSrc, const size_t n) {std::copy(pSrc, pSrc + n, pDst);}
+ };
+} // namespace utilImpl
+
+
+// Copies n elements from array pSrc to array pDst.
+// If the source and destination arrays overlap, behaviour is undefined.
+template <class T>
+void ArrayCopy(T* pDst, const T* pSrc, const size_t n)
+{
+ utilImpl::ArrayCopyImpl<std::tr1::has_trivial_assign<T>::value>::Do(pDst, pSrc, n);
+}
+
#endif
Modified: trunk/OpenMPT/mptrack/mptrack.vcproj
===================================================================
--- trunk/OpenMPT/mptrack/mptrack.vcproj 2009-08-30 22:27:15 UTC (rev 350)
+++ trunk/OpenMPT/mptrack/mptrack.vcproj 2009-09-01 18:50:33 UTC (rev 351)
@@ -367,6 +367,9 @@
RelativePath=".\Modedit.cpp">
</File>
<File
+ RelativePath="..\soundlib\ModSequence.cpp">
+ </File>
+ <File
RelativePath="..\soundlib\modsmp_ctrl.cpp">
</File>
<File
@@ -397,9 +400,6 @@
RelativePath=".\OpenGLEditor.cpp">
</File>
<File
- RelativePath="..\soundlib\OrderToPatternTable.cpp">
- </File>
- <File
RelativePath="..\soundlib\pattern.cpp">
</File>
<File
@@ -795,6 +795,9 @@
RelativePath=".\moddoc.h">
</File>
<File
+ RelativePath="..\soundlib\ModSequence.h">
+ </File>
+ <File
RelativePath="..\soundlib\modsmp_ctrl.h">
</File>
<File
@@ -819,12 +822,6 @@
RelativePath=".\OpenGLEditor.h">
</File>
<File
- RelativePath=".\order.h">
- </File>
- <File
- RelativePath="..\soundlib\OrderToPatternTable.h">
- </File>
- <File
RelativePath="..\soundlib\pattern.h">
</File>
<File
@@ -852,6 +849,9 @@
RelativePath=".\serialization_utils.h">
</File>
<File
+ RelativePath="..\soundlib\Snd_defs.h">
+ </File>
+ <File
RelativePath="..\Soundlib\snddev.h">
</File>
<File
Modified: trunk/OpenMPT/mptrack/mptrack_08.vcproj
===================================================================
--- trunk/OpenMPT/mptrack/mptrack_08.vcproj 2009-08-30 22:27:15 UTC (rev 350)
+++ trunk/OpenMPT/mptrack/mptrack_08.vcproj 2009-09-01 18:50:33 UTC (rev 351)
@@ -493,6 +493,10 @@
>
</File>
<File
+ RelativePath="..\soundlib\ModSequence.cpp"
+ >
+ </File>
+ <File
RelativePath="..\soundlib\modsmp_ctrl.cpp"
>
</File>
@@ -533,10 +537,6 @@
>
</File>
<File
- RelativePath="..\soundlib\OrderToPatternTable.cpp"
- >
- </File>
- <File
RelativePath="..\soundlib\pattern.cpp"
>
</File>
@@ -1051,6 +1051,10 @@
>
</File>
<File
+ RelativePath="..\soundlib\ModSequence.h"
+ >
+ </File>
+ <File
RelativePath="..\soundlib\modsmp_ctrl.h"
>
</File>
@@ -1083,14 +1087,6 @@
>
</File>
<File
- RelativePath=".\order.h"
- >
- </File>
- <File
- RelativePath="..\soundlib\OrderToPatternTable.h"
- >
- </File>
- <File
RelativePath="..\soundlib\pattern.h"
>
</File>
@@ -1127,6 +1123,10 @@
>
</File>
<File
+ RelativePath="..\soundlib\Snd_defs.h"
+ >
+ </File>
+ <File
RelativePath="..\Soundlib\snddev.h"
>
</File>
Modified: trunk/OpenMPT/mptrack/typedefs.h
===================================================================
--- trunk/OpenMPT/mptrack/typedefs.h 2009-08-30 22:27:15 UTC (rev 350)
+++ trunk/OpenMPT/mptrack/typedefs.h 2009-09-01 18:50:33 UTC (rev 351)
@@ -31,26 +31,26 @@
typedef float float32;
-typedef uint32 ROWINDEX;
- const ROWINDEX ROWINDEX_MAX = uint32_max;
-typedef uint16 CHANNELINDEX;
- const CHANNELINDEX CHANNELINDEX_MAX = uint16_max;
- const CHANNELINDEX CHANNELINDEX_INVALID = CHANNELINDEX_MAX;
-typedef uint16 ORDERINDEX;
- const ORDERINDEX ORDERINDEX_MAX = uint16_max;
- const ORDERINDEX ORDERINDEX_INVALID = ORDERINDEX_MAX;
-typedef uint16 PATTERNINDEX;
- const PATTERNINDEX PATTERNINDEX_MAX = uint16_max;
- const PATTERNINDEX PATTERNINDEX_INVALID = PATTERNINDEX_MAX;
-typedef uint8 PLUGINDEX;
-typedef uint16 TEMPO;
-typedef uint16 SAMPLEINDEX;
- const SAMPLEINDEX SAMPLEINDEX_MAX = uint16_max;
- const SAMPLEINDEX SAMPLEINDEX_INVALID = SAMPLEINDEX_MAX;
-typedef uint16 INSTRUMENTINDEX;
- const SAMPLEINDEX INSTRUMENTINDEX_MAX = uint16_max;
- const SAMPLEINDEX INSTRUMENTINDEX_INVALID = INSTRUMENTINDEX_MAX;
-typedef uint32 MODTYPE;
+#if !_HAS_TR1
+ namespace std
+ {
+ namespace tr1
+ {
+ template <class T> struct has_trivial_assign {static const bool value = false;};
+ #define SPECIALIZE_TRIVIAL_ASSIGN(type) template <> struct has_trivial_assign<type> {static const bool value = true;}
+ SPECIALIZE_TRIVIAL_ASSIGN(int8);
+ SPECIALIZE_TRIVIAL_ASSIGN(uint8);
+ SPECIALIZE_TRIVIAL_ASSIGN(int16);
+ SPECIALIZE_TRIVIAL_ASSIGN(uint16);
+ SPECIALIZE_TRIVIAL_ASSIGN(int32);
+ SPECIALIZE_TRIVIAL_ASSIGN(uint32);
+ SPECIALIZE_TRIVIAL_ASSIGN(int64);
+ SPECIALIZE_TRIVIAL_ASSIGN(uint64);
+ #undef SPECIALIZE_TRIVIAL_ASSIGN
+ };
+ };
+#endif
+
#endif
Copied: trunk/OpenMPT/soundlib/ModSequence.cpp (from rev 349, trunk/OpenMPT/soundlib/OrderToPatternTable.cpp)
===================================================================
--- trunk/OpenMPT/soundlib/ModSequence.cpp (rev 0)
+++ trunk/OpenMPT/soundlib/ModSequence.cpp 2009-09-01 18:50:33 UTC (rev 351)
@@ -0,0 +1,221 @@
+#include "stdafx.h"
+#include "sndfile.h"
+#include "ModSequence.h"
+#include "../mptrack/serialization_utils.h"
+
+#define str_SequenceTruncationNote (GetStrI18N((_TEXT("Module has sequence of length %u; it will be truncated to maximum supported length, %u."))))
+
+DWORD COrderToPatternTable::Deserialize(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 > ModSpecs::mptm.ordersMax)
+ s = ModSpecs::mptm.ordersMax;
+
+ resize(max(s, MAX_ORDERS));
+ 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();
+ }
+ if (GetCount() < MAX_ORDERS)
+ resize(MAX_ORDERS, 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());}
+
+
+void ReadModSequence(std::istream& iStrm, COrderToPatternTable& seq, const size_t)
+//--------------------------------------------------------------------------------
+{
+ uint16 size;
+ srlztn::Binaryread<uint16>(iStrm, size);
+ if(size > ModSpecs::mptm.ordersMax)
+ {
+ // Hack: Show message here if trying to load longer sequence than what is supported.
+ CString str; str.Format(str_SequenceTruncationNote, size, ModSpecs::mptm.ordersMax);
+ AfxMessageBox(str, MB_ICONWARNING);
+ size = ModSpecs::mptm.ordersMax;
+ }
+ seq.resize(max(size, MAX_ORDERS), seq.GetInvalidPatIndex());
+ if(size == 0)
+ { seq.Init(); return; }
+
+ for(size_t i = 0; i < size; i++)
+ {
+ uint16 temp;
+ srlztn::Binaryread<uint16>(iStrm, temp);
+ seq[i] = temp;
+ }
+}
+
+
+void WriteModSequence(std::ostream& oStrm, const COrderToPatternTable& seq)
+//-------------------------------------------------------------------------
+{
+ uint16 size = seq.GetCount();
+ srlztn::Binarywrite<uint16>(oStrm, size);
+ const COrderToPatternTable::const_iterator endIter = seq.end();
+ for(COrderToPatternTable::const_iterator citer = seq.begin(); citer != endIter; citer++)
+ {
+ const uint16 temp = static_cast<uint16>(*citer);
+ srlztn::Binarywrite<uint16>(oStrm, temp);
+ }
+}
+
Copied: trunk/OpenMPT/soundlib/ModSequence.h (from rev 349, trunk/OpenMPT/soundlib/OrderToPatternTable.h)
===================================================================
--- trunk/OpenMPT/soundlib/ModSequence.h (rev 0)
+++ trunk/OpenMPT/soundlib/ModSequence.h 2009-09-01 18:50:33 UTC (rev 351)
@@ -0,0 +1,68 @@
+#ifndef ORDERTOPATTERNTABLE_H
+#define ORDERTOPATTERNTABLE_H
+
+#include <vector>
+using std::vector;
+
+class CSoundFile;
+
+
+#pragma warning(disable:4244) //conversion from 'type1' to 'type2', possible loss of data.
+
+
+//==============================================
+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 Deserialize(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;
+
+private:
+ const CSoundFile& m_rSndFile;
+};
+
+#pragma warning(default:4244) //conversion from 'type1' to 'type2', possible loss of data.
+
+
+void ReadModSequence(std::istream& iStrm, COrderToPatternTable& seq, const size_t nSize = 0);
+void WriteModSequence(std::ostream& oStrm, const COrderToPatternTable& seq);
+
+#endif
+
Deleted: trunk/OpenMPT/soundlib/OrderToPatternTable.cpp
===================================================================
--- trunk/OpenMPT/soundlib/OrderToPatternTable.cpp 2009-08-30 22:27:15 UTC (rev 350)
+++ trunk/OpenMPT/soundlib/OrderToPatternTable.cpp 2009-09-01 18:50:33 UTC (rev 351)
@@ -1,221 +0,0 @@
-#include "stdafx.h"
-#include "sndfile.h"
-#include "ordertopatterntable.h"
-#include "../mptrack/serialization_utils.h"
-
-#define str_SequenceTruncationNote (GetStrI18N((_TEXT("Module has sequence of length %u; it will be truncated to maximum supported length, %u."))))
-
-DWORD COrderToPatternTable::Deserialize(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 > ModSpecs::mptm.ordersMax)
- s = ModSpecs::mptm.ordersMax;
-
- resize(max(s, MAX_ORDERS));
- 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();
- }
- if (GetCount() < MAX_ORDERS)
- resize(MAX_ORDERS, 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());}
-
-
-void ReadModSequence(std::istream& iStrm, COrderToPatternTable& seq, const size_t)
-//--------------------------------------------------------------------------------
-{
- uint16 size;
- srlztn::Binaryread<uint16>(iStrm, size);
- if(size > ModSpecs::mptm.ordersMax)
- {
- // Hack: Show message here if trying to load longer sequence than what is supported.
- CString str; str.Format(str_SequenceTruncationNote, size, ModSpecs::mptm.ordersMax);
- AfxMessageBox(str, MB_ICONWARNING);
- size = ModSpecs::mptm.ordersMax;
- }
- seq.resize(max(size, MAX_ORDERS), seq.GetInvalidPatIndex());
- if(size == 0)
- { seq.Init(); return; }
-
- for(size_t i = 0; i < size; i++)
- {
- uint16 temp;
- srlztn::Binaryread<uint16>(iStrm, temp);
- seq[i] = temp;
- }
-}
-
-
-void WriteModSequence(std::ostream& oStrm, const COrderToPatternTable& seq)
-//-------------------------------------------------------------------------
-{
- uint16 size = seq.GetCount();
- srlztn::Binarywrite<uint16>(oStrm, size);
- const COrderToPatternTable::const_iterator endIter = seq.end();
- for(COrderToPatternTable::const_iterator citer = seq.begin(); citer != endIter; citer++)
- {
- const uint16 temp = static_cast<uint16>(*citer);
- srlztn::Binarywrite<uint16>(oStrm, temp);
- }
-}
-
Deleted: trunk/OpenMPT/soundlib/OrderToPatternTable.h
===================================================================
--- trunk/OpenMPT/soundlib/OrderToPatternTable.h 2009-08-30 22:27:15 UTC (rev 350)
+++ trunk/OpenMPT/soundlib/OrderToPatternTable.h 2009-09-01 18:50:33 UTC (rev 351)
@@ -1,68 +0,0 @@
-#ifndef ORDERTOPATTERNTABLE_H
-#define ORDERTOPATTERNTABLE_H
-
-#include <vector>
-using std::vector;
-
-class CSoundFile;
-
-
-#pragma warning(disable:4244) //conversion from 'type1' to 'type2', possible loss of data.
-
-
-//==============================================
-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 Deserialize(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;
-
-private:
- const CSoundFile& m_rSndFile;
-};
-
-#pragma warning(default:4244) //conversion from 'type1' to 'type2', possible loss of data.
-
-
-void ReadModSequence(std::istream& iStrm, COrderToPatternTable& seq, const size_t nSize = 0);
-void WriteModSequence(std::ostream& oStrm, const COrderToPatternTable& seq);
-
-#endif
-
Added: trunk/OpenMPT/soundlib/Snd_defs.h
===================================================================
--- trunk/OpenMPT/soundlib/Snd_defs.h (rev 0)
+++ trunk/OpenMPT/soundlib/Snd_defs.h 2009-09-01 18:50:33 UTC (rev 351)
@@ -0,0 +1,367 @@
+/*
+ * OpenMPT
+ *
+ * Snd_defs.h
+ *
+ * Authors: Olivier Lapicque <oli...@jp...>
+ * OpenMPT devs
+*/
+
+#ifndef SND_DEF_H
+#define SND_DEF_H
+
+#ifndef LPCBYTE
+typedef const BYTE * LPCBYTE;
+#endif
+
+typedef uint32 ROWINDEX;
+ const ROWINDEX ROWINDEX_MAX = uint32_max;
+typedef uint16 CHANNELINDEX;
+ const CHANNELINDEX CHANNELINDEX_MAX = uint16_max;
+ const CHANNELINDEX CHANNELINDEX_INVALID = CHANNELINDEX_MAX;
+typedef uint16 ORDERINDEX;
+ const ORDERINDEX ORDERINDEX_MAX = uint16_max;
+ const ORDERINDEX ORDERINDEX_INVALID = ORDERINDEX_MAX;
+typedef uint16 PATTERNINDEX;
+ const PATTERNINDEX PATTERNINDEX_MAX = uint16_max;
+ const PATTERNINDEX PATTERNINDEX_INVALID = PATTERNINDEX_MAX;
+typedef uint8 PLUGINDEX;
+typedef uint16 TEMPO;
+typedef uint16 SAMPLEINDEX;
+ const SAMPLEINDEX SAMPLEINDEX_MAX = uint16_max;
+ const SAMPLEINDEX SAMPLEINDEX_INVALID = SAMPLEINDEX_MAX;
+typedef uint16 INSTRUMENTINDEX;
+ const SAMPLEINDEX INSTRUMENTINDEX_MAX = uint16_max;
+ const SAMPLEINDEX INSTRUMENTINDEX_INVALID = INSTRUMENTINDEX_MAX;
+typedef uint8 SEQUENCEINDEX;
+ const SEQUENCEINDEX SEQUENCEINDEX_MAX = uint8_max;
+ const SEQUENCEINDEX SEQUENCEINDEX_INVALID = SEQUENCEINDEX_MAX;
+typedef uint32 MODTYPE;
+
+#define MAX_PATTERN_ROWS 1024 // -> CODE#0008 -> DESC="#define to set pattern size" -! BEHAVIOUR_CHANGE#0008
+
+
+#define MOD_AMIGAC2 0x1AB
+// -> CODE#0006
+// -> DESC="misc quantity changes"
+#define MAX_SAMPLE_LENGTH 0x10000000 // 0x04000000 (64MB -> now 256MB).
+ // Note: Sample size in bytes can be more than 256 MB.
+// -! BEHAVIOUR_CHANGE#0006
+#define MAX_SAMPLE_RATE 100000
+#define MAX_ORDERS 256
+const SEQUENCEINDEX MAX_SEQUENCES = 10;
+#define MAX_PATTERNS 240
+#define MAX_SAMPLES 4000
+
+#define MAX_INSTRUMENTS 256 //200 // -> CODE#0006 -> DESC="misc quantity changes" // -! BEHAVIOUR_CHANGE#0006
+//#ifdef FASTSOUNDLIB
+//#define MAX_CHANNELS 80
+//#else
+// -> CODE#0006
+// -> DESC="misc quantity changes"
+#define MAX_CHANNELS 256 //200 // Note: This is the maximum number of sound channels,
+ // see MAX_BASECHANNELS for max pattern channels.
+// -! BEHAVIOUR_CHANGE#0006
+//#endif
+// -> CODE#0006
+// -> DESC="misc quantity changes"
+//#ifdef FASTSOUNDLIB
+//#define MAX_BASECHANNELS 64
+//#else
+#define MAX_BASECHANNELS 127 // Max pattern channels.
+//#endif
+// -! BEHAVIOUR_CHANGE#0006
+#define MAX_ENVPOINTS 32
+#define MIN_PERIOD 0x0020
+#define MAX_PERIOD 0xFFFF
+#define MAX_PATTERNNAME 32
+#define MAX_CHANNELNAME 20
+#define MAX_INFONAME 80
+#define MAX_EQ_BANDS 6
+
+#define MAX_MIXPLUGINS 100 //50 // -> CODE#0006 -> DESC="misc quantity changes" -! BEHAVIOUR_CHANGE#0006
+#define MAX_PLUGPRESETS 1000 //rewbs.plugPresets
+
+#define MOD_TYPE_NONE 0x00
+#define MOD_TYPE_MOD 0x01
+#define MOD_TYPE_S3M 0x02
+#define MOD_TYPE_XM 0x04
+#define MOD_TYPE_MED 0x08
+#define MOD_TYPE_MTM 0x10
+#define MOD_TYPE_IT 0x20
+#define MOD_TYPE_669 0x40
+#define MOD_TYPE_ULT 0x80
+#define MOD_TYPE_STM 0x100
+#define MOD_TYPE_FAR 0x200
+#define MOD_TYPE_WAV 0x400
+#define MOD_TYPE_AMF 0x800
+#define MOD_TYPE_AMS 0x1000
+#define MOD_TYPE_DSM 0x2000
+#define MOD_TYPE_MDL 0x4000
+#define MOD_TYPE_OKT 0x8000
+#define MOD_TYPE_MID 0x10000
+#define MOD_TYPE_DMF 0x20000
+#define MOD_TYPE_PTM 0x40000
+#define MOD_TYPE_DBM 0x80000
+#define MOD_TYPE_MT2 0x100000
+#define MOD_TYPE_AMF0 0x200000
+#define MOD_TYPE_PSM 0x400000
+#define MOD_TYPE_J2B 0x800000
+#define MOD_TYPE_MPT 0x1000000
+#define MOD_TYPE_UMX 0x80000000 // Fake type
+#define MAX_MODTYPE 24
+
+// For compatibility mode
+#define TRK_IMPULSETRACKER MOD_TYPE_IT | MOD_TYPE_MPT
+#define TRK_FASTTRACKER2 MOD_TYPE_XM
+#define TRK_SCREAMTRACKER MOD_TYPE_S3M
+#define TRK_PROTRACKER MOD_TYPE_MOD
+#define TRK_ALLTRACKERS TRK_IMPULSETRACKER | TRK_FASTTRACKER2 | TRK_SCREAMTRACKER | TRK_PROTRACKER
+
+
+
+// Channel flags:
+// Bits 0-7: Sample Flags
+#define CHN_16BIT 0x01
+#define CHN_LOOP 0x02
+#define CHN_PINGPONGLOOP 0x04
+#define CHN_SUSTAINLOOP 0x08
+#define CHN_PINGPONGSUSTAIN 0x10
+#define CHN_PANNING 0x20
+#define CHN_STEREO 0x40
+#define CHN_PINGPONGFLAG 0x80 //When flag is on, bidiloop is processed backwards?
+// Bits 8-31: Channel Flags
+#define CHN_MUTE 0x100
+#define CHN_KEYOFF 0x200
+#define CHN_NOTEFADE 0x400
+#define CHN_SURROUND 0x800
+#define CHN_NOIDO 0x1000
+#define CHN_HQSRC 0x2000
+#define CHN_FILTER 0x4000
+#define CHN_VOLUMERAMP 0x8000
+#define CHN_VIBRATO 0x10000
+#define CHN_TREMOLO 0x20000
+#define CHN_PANBRELLO 0x40000
+#define CHN_PORTAMENTO 0x80000
+#define CHN_GLISSANDO 0x100000
+#define CHN_VOLENV 0x200000
+#define CHN_PANENV 0x400000
+#define CHN_PITCHENV 0x800000
+#define CHN_FASTVOLRAMP 0x1000000
+#define CHN_EXTRALOUD 0x2000000
+#define CHN_REVERB 0x4000000
+#define CHN_NOREVERB 0x8000000
+#define CHN_SOLO 0x10000000 // -> CODE#0012 -> DESC="midi keyboard split" -! NEW_FEATURE#0012
+#define CHN_NOFX 0x20000000 // -> CODE#0015 -> DESC="channels management dlg" -! NEW_FEATURE#0015
+#define CHN_SYNCMUTE 0x40000000
+
+#define ENV_VOLUME 0x0001
+#define ENV_VOLSUSTAIN 0x0002
+#define ENV_VOLLOOP 0x0004
+#define ENV_PANNING 0x0008
+#define ENV_PANSUSTAIN 0x0010
+#define ENV_PANLOOP 0x0020
+#define ENV_PITCH 0x0040
+#define ENV_PITCHSUSTAIN 0x0080
+#define ENV_PITCHLOOP 0x0100
+#define ENV_SETPANNING 0x0200
+#define ENV_FILTER 0x0400
+#define ENV_VOLCARRY 0x0800
+#define ENV_PANCARRY 0x1000
+#define ENV_PITCHCARRY 0x2000
+#define ENV_MUTE 0x4000
+
+
+// Filter Modes
+#define FLTMODE_UNCHANGED 0xFF
+#define FLTMODE_LOWPASS 0
+#define FLTMODE_HIGHPASS 1
+#define FLTMODE_BANDPASS 2
+
+
+#define RSF_16BIT 0x04
+#define RSF_STEREO 0x08
+
+#define RS_PCM8S 0 // 8-bit signed
+#define RS_PCM8U 1 // 8-bit unsigned
+#define RS_PCM8D 2 // 8-bit delta values
+#define RS_ADPCM4 3 // 4-bit ADPCM-packed
+#define RS_PCM16D 4 // 16-bit delta values
+#define RS_PCM16S 5 // 16-bit signed
+#define RS_PCM16U 6 // 16-bit unsigned
+#define RS_PCM16M 7 // 16-bit motorola order
+#define RS_STPCM8S (RS_PCM8S|RSF_STEREO) // stereo 8-bit signed
+#define RS_STPCM8U (RS_PCM8U|RSF_STEREO) // stereo 8-bit unsigned
+#define RS_STPCM8D (RS_PCM8D|RSF_STEREO) // stereo 8-bit delta values
+#define RS_STPCM16S (RS_PCM16S|RSF_STEREO) // stereo 16-bit signed
+#define RS_STPCM16U (RS_PCM16U|RSF_STEREO) // stereo 16-bit unsigned
+#define RS_STPCM16D (RS_PCM16D|RSF_STEREO) // stereo 16-bit delta values
+#define RS_STPCM16M (RS_PCM16M|RSF_STEREO) // stereo 16-bit signed big endian
+// IT 2.14 compressed samples
+#define RS_IT2148 0x10
+#define RS_IT21416 0x14
+#define RS_IT2158 0x12
+#define RS_IT21516 0x16
+// AMS Packed Samples
+#define RS_AMS8 0x11
+#define RS_AMS16 0x15
+// DMF Huffman compression
+#define RS_DMF8 0x13
+#define RS_DMF16 0x17
+// MDL Huffman compression
+#define RS_MDL8 0x20
+#define RS_MDL16 0x24
+#define RS_PTM8DTO16 0x25
+// Stereo Interleaved Samples
+#define RS_STIPCM8S (RS_PCM8S|0x40|RSF_STEREO) // stereo 8-bit signed
+#define RS_STIPCM8U (RS_PCM8U|0x40|RSF_STEREO) // stereo 8-bit unsigned
+#define RS_STIPCM16S (RS_PCM16S|0x40|RSF_STEREO) // stereo 16-bit signed
+#define RS_STIPCM16U (RS_PCM16U|0x40|RSF_STEREO) // stereo 16-bit unsigned
+#define RS_STIPCM16M (RS_PCM16M|0x40|RSF_STEREO) // stereo 16-bit signed big endian
+// 24-bit signed
+#define RS_PCM24S (RS_PCM16S|0x80) // mono 24-bit signed
+#define RS_STIPCM24S (RS_PCM16S|0x80|RSF_STEREO) // stereo 24-bit signed
+// 32-bit
+#define RS_PCM32S (RS_PCM16S|0xC0) // mono 32-bit signed
+#define RS_STIPCM32S (RS_PCM16S|0xC0|RSF_STEREO) // stereo 32-bit signed
+
+
+
+// NNA types (New Note Action)
+#define NNA_NOTECUT 0
+#define NNA_CONTINUE 1
+#define NNA_NOTEOFF 2
+#define NNA_NOTEFADE 3
+
+// DCT types (Duplicate Check Types)
+#define DCT_NONE 0
+#define DCT_NOTE 1
+#define DCT_SAMPLE 2
+#define DCT_INSTRUMENT 3
+#define DCT_PLUGIN 4 //rewbs.VSTiNNA
+
+// DNA types (Duplicate Note Action)
+#define DNA_NOTECUT 0
+#define DNA_NOTEOFF 1
+#define DNA_NOTEFADE 2
+
+// Mixer Hardware-Dependent features
+#define SYSMIX_ENABLEMMX 0x01
+#define SYSMIX_SLOWCPU 0x02
+#define SYSMIX_FASTCPU 0x04
+#define SYSMIX_MMXEX 0x08
+#define SYSMIX_3DNOW 0x10
+#define SYSMIX_SSE 0x20
+
+// Module flags
+#define SONG_EMBEDMIDICFG 0x0001
+#define SONG_FASTVOLSLIDES 0x0002
+#define SONG_ITOLDEFFECTS 0x0004
+#define SONG_ITCOMPATMODE 0x0008
+#define SONG_LINEARSLIDES 0x0010
+#define SONG_PATTERNLOOP 0x0020
+#define SONG_STEP 0x0040
+#define SONG_PAUSED 0x0080
+#define SONG_FADINGSONG 0x0100
+#define SONG_ENDREACHED 0x0200
+#define SONG_GLOBALFADE 0x0400
+#define SONG_CPUVERYHIGH 0x0800
+#define SONG_FIRSTTICK 0x1000
+#define SONG_MPTFILTERMODE 0x2000
+#define SONG_SURROUNDPAN 0x4000
+#define SONG_EXFILTERRANGE 0x8000
+#define SONG_AMIGALIMITS 0x10000
+// -> CODE#0023
+// -> DESC="IT project files (.itp)"
+#define SONG_ITPROJECT 0x20000
+#define SONG_ITPEMBEDIH 0x40000
+// -! NEW_FEATURE#0023
+#define SONG_BREAKTOROW 0x80000
+#define SONG_POSJUMP 0x100000
+
+// Global Options (Renderer)
+#define SNDMIX_REVERSESTEREO 0x0001
+#define SNDMIX_NOISEREDUCTION 0x0002
+#define SNDMIX_AGC 0x0004
+#define SNDMIX_NORESAMPLING 0x0008
+// SNDMIX_NOLINEARSRCMODE is the default
+//#define SNDMIX_HQRESAMPLER 0x0010 //rewbs.resamplerConf: renamed SNDMIX_HQRESAMPLER to SNDMIX_SPLINESRCMODE
+#define SNDMIX_SPLINESRCMODE 0x0010
+#define SNDMIX_MEGABASS 0x0020
+#define SNDMIX_SURROUND 0x0040
+#define SNDMIX_REVERB 0x0080
+#define SNDMIX_EQ 0x0100
+#define SNDMIX_SOFTPANNING 0x0200
+//#define SNDMIX_ULTRAHQSRCMODE 0x0400 //rewbs.resamplerConf: renamed SNDMIX_ULTRAHQSRCMODE to SNDMIX_POLYPHASESRCMODE
+#define SNDMIX_POLYPHASESRCMODE 0x0400
+#define SNDMIX_FIRFILTERSRCMODE 0x0800 //rewbs: added SNDMIX_FIRFILTERSRCMODE
+
+//rewbs.resamplerConf: for stuff that applies to cubic spline, polyphase and FIR
+#define SNDMIX_HQRESAMPLER (SNDMIX_SPLINESRCMODE|SNDMIX_POLYPHASESRCMODE|SNDMIX_FIRFILTERSRCMODE)
+
+////rewbs.resamplerConf: for stuff that applies to polyphase and FIR
+#define SNDMIX_ULTRAHQSRCMODE (SNDMIX_POLYPHASESRCMODE|SNDMIX_FIRFILTERSRCMODE)
+
+// Misc Flags (can safely be turned on or off)
+#define SNDMIX_DIRECTTODISK 0x10000
+#define SNDMIX_ENABLEMMX 0x20000
+#define SNDMIX_NOBACKWARDJUMPS 0x40000
+#define SNDMIX_MAXDEFAULTPAN 0x80000 // Used by the MOD loader
+#define SNDMIX_MUTECHNMODE 0x100000 // Notes are not played on muted channels
+#define SNDMIX_EMULATE_MIX_BUGS 0x200000 // rewbs.emulateMixBugs
+
+#define MAX_GLOBAL_VOLUME 256
+
+// Resampling modes
+enum {
+ SRCMODE_NEAREST,
+ SRCMODE_LINEAR,
+ SRCMODE_SPLINE,
+ SRCMODE_POLYPHASE,
+ SRCMODE_FIRFILTER, //rewbs.resamplerConf
+ SRCMODE_DEFAULT,
+ NUM_SRC_MODES
+};
+
+enum {
+ ENV_RESET_ALL,
+ ENV_RESET_VOL,
+ ENV_RESET_PAN,
+ ENV_RESET_PITCH,
+ ENV_RELEASE_NODE_UNSET=0xFF,
+ NOT_YET_RELEASED=-1
+};
+
+enum {
+ CHANNEL_ONLY = 0,
+ INSTRUMENT_ONLY = 1,
+ PRIORITISE_INSTRUMENT = 2,
+ PRIORITISE_CHANNEL = 3,
+ EVEN_IF_MUTED = false,
+ RESPECT_MUTES = true,
+};
+
+//Plugin velocity handling options
+enum PLUGVELOCITYHANDLING
+{
+ PLUGIN_VELOCITYHANDLING_CHANNEL = 0,
+ PLUGIN_VELOCITYHANDLING_VOLUME
+};
+
+//Plugin volumecommand handling options
+enum PLUGVOLUMEHANDLING
+{
+ PLUGIN_VOLUMEHANDLING_MIDI = 0,
+ PLUGIN_VOLUMEHANDLING_DRYWET,
+ PLUGIN_VOLUMEHANDLING_IGNORE,
+};
+
+// filtermodes
+/*enum {
+ INST_FILTERMODE_DEFAULT=0,
+ INST_FILTERMODE_HIGHPASS,
+ INST_FILTERMODE_LOWPASS,
+ INST_NUMFILTERMODES
+};*/
+
+#endif
Modified: trunk/OpenMPT/soundlib/Sndfile.h
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.h 2009-08-30 22:27:15 UTC (rev 350)
+++ trunk/OpenMPT/soundlib/Sndfile.h 2009-09-01 18:50:33 UTC (rev 351)
@@ -7,364 +7,21 @@
* OpenMPT devs
*/
+#ifndef __SNDFILE_H
+#define __SNDFILE_H
+
#include "../mptrack/SoundFilePlayConfig.h"
#include "../mptrack/misc_util.h"
#include "mod_specifications.h"
#include <vector>
#include <bitset>
#include "midi.h"
+#include "Snd_defs.h"
class CTuningBase;
typedef CTuningBase CTuning;
-using std::bitset;
-#ifndef __SNDFILE_H
-#define __SNDFILE_H
-
-#ifndef LPCBYTE
-typedef const BYTE * LPCBYTE;
-#endif
-
-// -> CODE#0008
-// -> DESC="#define to set pattern size"
-#define MAX_PATTERN_ROWS 1024
-// -! BEHAVIOUR_CHANGE#0008
-
-#define MOD_AMIGAC2 0x1AB
-// -> CODE#0006
-// -> DESC="misc quantity changes"
-#define MAX_SAMPLE_LENGTH 0x10000000 // 0x04000000 (64MB -> now 256MB).
- // Note: Sample size in bytes can be more than 256 MB.
-// -! BEHAVIOUR_CHANGE#0006
-#define MAX_SAMPLE_RATE 100000
-#define MAX_ORDERS 256
-#define MAX_PATTERNS 240
-#define MAX_SAMPLES 4000
-// -> CODE#0006
-// -> DESC="misc quantity changes"
-#define MAX_INSTRUMENTS 256 //200
-// -! BEHAVIOUR_CHANGE#0006
-//#ifdef FASTSOUNDLIB
-//#define MAX_CHANNELS 80
-//#else
-// -> CODE#0006
-// -> DESC="misc quantity changes"
-#define MAX_CHANNELS 256 //200 //Note: This is the maximum number of sound channels,
- // see MAX_BASECHANNELS for max pattern channels.
-// -! BEHAVIOUR_CHANGE#0006
-//#endif
-// -> CODE#0006
-// -> DESC="misc quantity changes"
-//#ifdef FASTSOUNDLIB
-//#define MAX_BASECHANNELS 64
-//#else
-#define MAX_BASECHANNELS 127 //Max pattern channels.
-//#endif
-// -! BEHAVIOUR_CHANGE#0006
-#define MAX_ENVPOINTS 32
-#define MIN_PERIOD 0x0020
-#define MAX_PERIOD 0xFFFF
-#define MAX_PATTERNNAME 32
-#define MAX_CHANNELNAME 20
-#define MAX_INFONAME 80
-#define MAX_EQ_BANDS 6
-// -> CODE#0006
-// -> DESC="misc quantity changes"
-#define MAX_MIXPLUGINS 100 //50
-// -! BEHAVIOUR_CHANGE#0006
-#define MAX_PLUGPRESETS 1000 //rewbs.plugPresets
-
-#define MOD_TYPE_NONE 0x00
-#define MOD_TYPE_MOD 0x01
-#define MOD_TYPE_S3M 0x02
-#define MOD_TYPE_XM 0x04
-#define MOD_TYPE_MED 0x08
-#define MOD_TYPE_MTM 0x10
-#define MOD_TYPE_IT 0x20
-#define MOD_TYPE_669 0x40
-#define MOD_TYPE_ULT 0x80
-#define MOD_TYPE_STM 0x100
-#define MOD_TYPE_FAR 0x200
-#define MOD_TYPE_WAV 0x400
-#define MOD_TYPE_AMF 0x800
-#define MOD_TYPE_AMS 0x1000
-#define MOD_TYPE_DSM 0x2000
-#define MOD_TYPE_MDL 0x4000
-#define MOD_TYPE_OKT 0x8000
-#define MOD_TYPE_MID 0x10000
-#define MOD_TYPE_DMF 0x20000
-#define MOD_TYPE_PTM 0x40000
-#define MOD_TYPE_DBM 0x80000
-#define MOD_TYPE_MT2 0x100000
-#define MOD_TYPE_AMF0 0x200000
-#define MOD_TYPE_PSM 0x400000
-#define MOD_TYPE_J2B 0x800000
-#define MOD_TYPE_MPT 0x1000000
-#define MOD_TYPE_UMX 0x80000000 // Fake type
-#define MAX_MODTYPE 24
-
-// For compatibility mode
-#define TRK_IMPULSETRACKER MOD_TYPE_IT | MOD_TYPE_MPT
-#define TRK_FASTTRACKER2 MOD_TYPE_XM
-#define TRK_SCREAMTRACKER MOD_TYPE_S3M
-#define TRK_PROTRACKER MOD_TYPE_MOD
-#define TRK_ALLTRACKERS TRK_IMPULSETRACKER | TRK_FASTTRACKER2 | TRK_SCREAMTRACKER | TRK_PROTRACKER
-
-
-
-// Channel flags:
-// Bits 0-7: Sample Flags
-#define CHN_16BIT 0x01
-#define CHN_LOOP 0x02
-#define CHN_PINGPONGLOOP 0x04
-#define CHN_SUSTAINLOOP 0x08
-#define CHN_PINGPONGSUSTAIN 0x10
-#define CHN_PANNING 0x20
-#define CHN_STEREO 0x40
-#define CHN_PINGPONGFLAG 0x80 //When flag is on, bidiloop is processed backwards?
-// Bits 8-31: Channel Flags
-#define CHN_MUTE 0x100
-#define CHN_KEYOFF 0x200
-#define CHN_NOTEFADE 0x400
-#define CHN_SURROUND 0x800
-#define CHN_NOIDO 0x1000
-#define CHN_HQSRC 0x2000
-#define CHN_FILTER 0x4000
-#define CHN_VOLUMERAMP 0x8000
-#define CHN_VIBRATO 0x10000
-#define CHN_TREMOLO 0x20000
-#define CHN_PANBRELLO 0x40000
-#define CHN_PORTAMENTO 0x80000
-#define CHN_GLISSANDO 0x100000
-#define CHN_VOLENV 0x200000
-#define CHN_PANENV 0x400000
-#define CHN_PITCHENV 0x800000
-#define CHN_FASTVOLRAMP 0x1000000
-#define CHN_EXTRALOUD 0x2000000
-#define CHN_REVERB 0x4000000
-#define CHN_NOREVERB 0x8000000
-// -> CODE#0012
-// -> DESC="midi keyboard split"
-#define CHN_SOLO 0x10000000
-// -! NEW_FEATURE#0012
-
-// -> CODE#0015
-// -> DESC="channels management dlg"
-#define CHN_NOFX 0x20000000
-// -! NEW_FEATURE#0015
-
-#define CHN_SYNCMUTE 0x40000000
-
-#define ENV_VOLUME 0x0001
-#define ENV_VOLSUSTAIN 0x0002
-#define ENV_VOLLOOP 0x0004
-#define ENV_PANNING 0x0008
-#define ENV_PANSUSTAIN 0x0010
-#define ENV_PANLOOP 0x0020
-#define ENV_PITCH 0x0040
-#define ENV_PITCHSUSTAIN 0x0080
-#define ENV_PITCHLOOP 0x0100
-#define ENV_SETPANNING 0x0200
-#define ENV_FILTER 0x0400
-#define ENV_VOLCARRY 0x0800
-#define ENV_PANCARRY 0x1000
-#define ENV_PITCHCARRY 0x2000
-#define ENV_MUTE 0x4000
-
-
-// Filter Modes
-#define FLTMODE_UNCHANGED 0xFF
-#define FLTMODE_LOWPASS 0
-#define FLTMODE_HIGHPASS 1
-#define FLTMODE_BANDPASS 2
-
-
-#define RSF_16BIT 0x04
-#define RSF_STEREO 0x08
-
-#define RS_PCM8S 0 // 8-bit signed
-#define RS_PCM8U 1 // 8-bit unsigned
-#define RS_PCM8D 2 // 8-bit delta values
-#define RS_ADPCM4 3 // 4-bit ADPCM-packed
-#define RS_PCM16D 4 // 16-bit delta values
-#define RS_PCM16S 5 // 16-bit signed
-#define RS_PCM16U 6 // 16-bit unsigned
-#define RS_PCM16M 7 // 16-bit motorola order
-#define RS_STPCM8S (RS_PCM8S|RSF_STEREO) // stereo 8-bit signed
-#define RS_STPCM8U (RS_PCM8U|RSF_STEREO) // stereo 8-bit unsigned
-#define RS_STPCM8D (RS_PCM8D|RSF_STEREO) // stereo 8-bit delta values
-#define RS_STPCM16S (RS_PCM16S|RSF_STEREO) // stereo 16-bit signed
-#define RS_STPCM16U (RS_PCM16U|RSF_STEREO) // stereo 16-bit unsigned
-#define RS_STPCM16D (RS_PCM16D|RSF_STEREO) // stereo 16-bit delta values
-#define RS_STPCM16M (RS_PCM16M|RSF_STEREO) // stereo 16-bit signed big endian
-// IT 2.14 compressed samples
-#define RS_IT2148 0x10
-#define RS_IT21416 0x14
-#define RS_IT2158 0x12
-#define RS_IT21516 0x16
-// AMS Packed Samples
-#define RS_AMS8 0x11
-#define RS_AMS16 0x15
-// DMF Huffman compression
-#define RS_DMF8 0x13
-#define RS_DMF16 0x17
-// MDL Huffman compression
-#define RS_MDL8 0x20
-#define RS_MDL16 0x24
-#define RS_PTM8DTO16 0x25
-// Stereo Interleaved Samples
-#define RS_STIPCM8S (RS_PCM8S|0x40|RSF_STEREO) // stereo 8-bit signed
-#define RS_STIPCM8U (RS_PCM8U|0x40|RSF_STEREO) // stereo 8-bit unsigned
-#define RS_STIPCM16S (RS_PCM16S|0x40|RSF_STEREO) // stereo 16-bit signed
-#define RS_STIPCM16U (RS_PCM16U|0x40|RSF_STEREO) // stereo 16-bit unsigned
-#define RS_STIPCM16M (RS_PCM16M|0x40|RSF_STEREO) // stereo 16-bit signed big endian
-// 24-bit signed
-#define RS_PCM24S (RS_PCM16S|0x80) // mono 24-bit signed
-#define RS_STIPCM24S (RS_PCM16S|0x80|RSF_STEREO) // stereo 24-bit signed
-// 32-bit
-#define RS_PCM32S (RS_PCM16S|0xC0) // mono 32-bit signed
-#define RS_STIPCM32S (RS_PCM16S|0xC0|RSF_STEREO) // stereo 32-bit signed
-
-
-
-// NNA types (New Note Action)
-#define NNA_NOTECUT 0
-#define NNA_CONTINUE 1
-#define NNA_NOTEOFF 2
-#define NNA_NOTEFADE 3
-
-// DCT types (Duplicate Check Types)
-#define DCT_NONE 0
-#define DCT_NOTE 1
-#define DCT_SAMPLE 2
-#define DCT_INSTRUMENT 3
-#define DCT_PLUGIN 4 //rewbs.VSTiNNA
-
-// DNA types (Duplicate Note Action)
-#define DNA_NOTECUT 0
-#define DNA_NOTEOFF 1
-#define DNA_NOTEFADE 2
-
-// Mixer Hardware-Dependent features
-#define SYSMIX_ENABLEMMX 0x01
-#define SYSMIX_SLOWCPU 0x02
-#define SYSMIX_FASTCPU 0x04
-#define SYSMIX_MMXEX 0x08
-#define SYSMIX_3DNOW 0x10
-#define SYSMIX_SSE 0x20
-
-// Module flags
-#define SONG_EMBEDMIDICFG 0x0001
-#define SONG_FASTVOLSLIDES 0x0002
-#define SONG_ITOLDEFFECTS 0x0004
-#define SONG_ITCOMPATMODE 0x0008
-#define SONG_LINEARSLIDES 0x0010
-#define SONG_PATTERNLOOP 0x0020
-#define SONG_STEP 0x0040
-#define SONG_PAUSED 0x0080
-#define SONG_FADINGSONG 0x0100
-#define SONG_ENDREACHED 0x0200
-#define SONG_GLOBALFADE 0x0400
-#define SONG_CPUVERYHIGH 0x0800
-#define SONG_FIRSTTICK 0x1000
-#define SONG_MPTFILTERMODE 0x2000
-#define SONG_SURROUNDPAN 0x4000
-#define SONG_EXFILTERRANGE 0x8000
-#define SONG_AMIGALIMITS 0x10000
-// -> CODE#0023
-// -> DESC="IT project files (.itp)"
-#define SONG_ITPROJECT 0x20000
-#define SONG_ITPEMBEDIH 0x40000
-// -! NEW_FEATURE#0023
-#define SONG_BREAKTOROW 0x80000
-#define SONG_POSJUMP 0x100000
-
-// Global Options (Renderer)
-#define SNDMIX_REVERSESTEREO 0x0001
-#define SNDMIX_NOISEREDUCTION 0x0002
-#define SNDMIX_AGC 0x0004
-#define SNDMIX_NORESAMPLING 0x0008
-// SNDMIX_NOLINEARSRCMODE is the default
-//#define SNDMIX_HQRESAMPLER 0x0010 //rewbs.resamplerConf: renamed SNDMIX_HQRESAMPLER to SNDMIX_SPLINESRCMODE
-#define SNDMIX_SPLINESRCMODE 0x0010
-#define SNDMIX_MEGABASS 0x0020
-#define SNDMIX_SURROUND 0x0040
-#define SNDMIX_REVERB 0x0080
-#define SNDMIX_EQ 0x0100
-#define SNDMIX_SOFTPANNING 0x0200
-//#define SNDMIX_ULTRAHQSRCMODE 0x0400 //rewbs.resamplerConf: renamed SNDMIX_ULTRAHQSRCMODE to SNDMIX_POLYPHASESRCMODE
-#define SNDMIX_POLYPHASESRCMODE 0x0400
-#define SNDMIX_FIRFILTERSRCMODE 0x0800 //rewbs: added SNDMIX_FIRFILTERSRCMODE
-
-//rewbs.resamplerConf: for stuff that applies to cubic spline, polyphase and FIR
-#define SNDMIX_HQRESAMPLER (SNDMIX_SPLINESRCMODE|SNDMIX_POLYPHASESRCMODE|SNDMIX_FIRFILTERSRCMODE)
-
-////rewbs.resamplerConf: for stuff that applies to polyphase and FIR
-#define SNDMIX_ULTRAHQSRCMODE (SNDMIX_POLYPHASESRCMODE|SNDMIX_FIRFILTERSRCMODE)
-
-// Misc Flags (can safely be turned on or off)
-#define SNDMIX_DIRECTTODISK 0x10000
-#define SNDMIX_ENABLEMMX 0x20000
-#define SNDMIX_NOBACKWARDJUMPS 0x40000
-#define SNDMIX_MAXDEFAULTPAN 0x80000 // Used by the MOD loader
-#define SNDMIX_MUTECHNMODE 0x100000 // Notes are not played on muted channels
-#define SNDMIX_EMULATE_MIX_BUGS 0x200000 // rewbs.emulateMixBugs
-
-#define MAX_GLOBAL_VOLUME 256
-
-// Resampling modes
-enum {
- SRCMODE_NEAREST,
- SRCMODE_LINEAR,
- SRCMODE_SPLINE,
- SRCMODE_POLYPHASE,
- SRCMODE_FIRFILTER, //rewbs.resamplerConf
- SRCMODE_DEFAULT,
- NUM_SRC_MODES
-};
-
-enum {
- ENV_RESET_ALL,
- ENV_RESET_VOL,
- ENV_RESET_PAN,
- ENV_RESET_PITCH,
- ENV_RELEASE_NODE_UNSET=0xFF,
- NOT_YET_RELEASED=-1
-};
-
-enum {
- CHANNEL_ONLY = 0,
- INSTRUMENT_ONLY = 1,
- PRIORITISE_INSTRUMENT = 2,
- PRIORITISE_CHANNEL = 3,
- EVEN_IF_MUTED = false,
- RESPECT_MUTES = true,
-};
-
-//Plugin velocity handling options
-enum PLUGVELOCITYHANDLING
-{
- PLUGIN_VELOCITYHANDLING_CHANNEL = 0,
- PLUGIN_VELOCITYHANDLING_VOLUME
-};
-
-//Plugin volumecommand handling options
-enum PLUGVOLUMEHANDLING
-{
- PLUGIN_VOLUMEHANDLING_MIDI = 0,
- PLUGIN_VOLUMEHANDLING_DRYWET,
- PLUGIN_VOLUMEHANDLING_IGNORE,
-};
-
-// filtermodes
-/*enum {
- INST_FILTERMODE_DEFAULT=0,
- INST_FILTERMODE_HIGHPASS,
- INST_FILTERMODE_LOWPASS,
- INST_NUMFILTERMODES
-};*/
-
// Sample Struct
struct MODSAMPLE
{
@@ -774,12 +431,11 @@
#include "pattern.h"
#include "patternContainer.h"
-#include "ordertopatterntable.h"
+#include "ModSequence.h"
+#include "PlaybackEventer.h"
-#include "playbackEventer.h"
-
class CSoundFile;
//======================
@@ -1022,10 +678,7 @@
bool ReadSTM(LPCBYTE lpStream, DWORD dwMemLength);
bool ReadIT(LPCBYTE lpStream, const DWORD dwMemLength);
//bool ReadMPT(LPCBYTE lpStream, const DWORD dwMemLength);
-// -> CODE#0023
-// -> DESC="IT project files (.itp)"
- bool ReadITProject(LPCBYTE lpStream, const DWORD dwMemLength);
-// -! NEW_FEATURE#0023
+ bool ReadITProject(LPCBYTE lpStream, const DWORD dwMemLength); // -> CODE#0023 -> DESC="IT project files (.itp)" -! NEW_FEATURE#0023
bool Read669(LPCBYTE lpStream, DWORD dwMemLength);
bool ReadUlt(LPCBYTE lpStream, DWORD dwMemLength);
bool ReadWav(LPCBYTE lpStream, DWORD dwMemLength);
@@ -1055,10 +708,7 @@
bool SaveMod(LPCSTR lpszFileName, UINT nPacking=0, const bool bCompatibilityExport = false);
bool SaveIT(LPCSTR lpszFileName, UINT nPacking=0);
bool SaveCompatIT(LPCSTR lpszFileName);
-// -> CODE#0023
-// -> DESC="IT project files (.itp)"
- bool SaveITProject(LPCSTR lpszFileName);
-// -! NEW_FEATURE#0023
+ bool SaveITProject(LPCSTR lpszFileName); // -> CODE#0023 -> DESC="IT project files (.itp)" -! NEW_FEATURE#0023
UINT SaveMixPlugins(FILE *f=NULL, BOOL bUpdate=TRUE);
void WriteInstrumentPropertyForAllInstruments(__int32 code, __int16 size, FILE* f, MODINSTRUMENT* instruments[], UINT nInstruments);
void SaveExtendedInstrumentProperties(MODINSTRUMENT *instruments[], UINT nInstruments, FILE* f);
Modified: trunk/OpenMPT/soundlib/mod_specifications.h
===================================================================
--- trunk/OpenMPT/soundlib/mod_specifications.h 2009-08-30 22:27:15 UTC (rev 350)
+++ trunk/OpenMPT/soundlib/mod_specifications.h 2009-09-01 18:50:33 UTC (rev 351)
@@ -1,6 +1,7 @@
#ifndef MOD_SPECIFICATIONS_H
#define MOD_SPECIFICATIONS_H
+#include "Snd_defs.h"
#include "modcommand.h" //
#include "../mptrack/SoundFilePlayConfig.h" // mixlevel constants.
Modified: trunk/OpenMPT/soundlib/pattern.h
===================================================================
--- trunk/OpenMPT/soundlib/pattern.h 2009-08-30 22:27:15 UTC (rev 350)
+++ trunk/OpenMPT/soundlib/pattern.h 2009-09-01 18:50:33 UTC (rev 351)
@@ -3,6 +3,7 @@
#include <vector>
#include "modcommand.h"
+#include "Snd_defs.h"
using std::vector;
Modified: trunk/OpenMPT/soundlib/patternContainer.h
===================================================================
--- trunk/OpenMPT/soundlib/patternContainer.h 2009-08-30 22:27:15 UTC (rev 350)
+++ trunk/OpenMPT/soundlib/patternContainer.h 2009-09-01 18:50:33 UTC (rev 351)
@@ -2,6 +2,7 @@
#define PATTERNCONTAINER_H
#include "pattern.h"
+#include "Snd_defs.h"
class CSoundFile;
typedef CPattern MODPATTERN;
@@ -25,7 +26,7 @@
//BEGIN: INTERFACE METHODS
public:
- CPatternContainer(CSoundFile& sndFile) : m_rSndFile(sndFile) {m_Patterns.assign(240, MODPATTERN(*this));}
+ CPatternContainer(CSoundFile& sndFile) : m_rSndFile(sndFile) {m_Patterns.assign(MAX_PATTERNS, MODPATTERN(*this));}
// Clears existing patterns and resizes array to default size.
void Init();
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-08-30 22:27:26
|
Revision: 350
http://modplug.svn.sourceforge.net/modplug/?rev=350&view=rev
Author: saga-games
Date: 2009-08-30 22:27:15 +0000 (Sun, 30 Aug 2009)
Log Message:
-----------
[Fix] S3M Loader: Small modifications to pattern loader to load somewhat broken S3M files
[Fix] S3M Loader: Don't reset global volume to max if it is min for "new" modules
[Fix] S3M Loader: Smarter Zxx conversion
[Fix] S3M Saver: Was completely broken for a reason that's beyond my understanding :) (order size only has to be multiple of 2, not 16!)
[Imp] Mod Conversion: Convert 500/600 commands properly from MOD to any format, Adjust sustain loops for XM files, removed XM arpeggio conversion (it might be unwanted)
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Modedit.cpp
trunk/OpenMPT/soundlib/Load_s3m.cpp
Modified: trunk/OpenMPT/mptrack/Modedit.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-30 14:29:58 UTC (rev 349)
+++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-30 22:27:15 UTC (rev 350)
@@ -396,15 +396,22 @@
} // End if (oldTypeIsIT_MPT && newTypeIsS3M)
- ////////////////////////
- // Convert XM arpeggio
- if(m->command == CMD_ARPEGGIO && (newTypeIsXM || oldTypeIsXM))
+
+ ///////////////////////////////////////////////////
+ // Convert MOD to anything - adjust effect memory
+ if (oldTypeIsMOD)
{
- // swap notes
- m->param = ((m->param & 0x0F) << 4) | ((m->param & 0xF0) >> 4);
- }
+ switch(m->command)
+ {
+ case CMD_TONEPORTAVOL: // lacks memory -> 500 is the same as 300
+ if(m->param == 0x00) m->command = CMD_TONEPORTAMENTO;
+ break;
+ case CMD_VIBRATOVOL: // lacks memory -> 600 is the same as 400
+ if(m->param == 0x00) m->command = CMD_VIBRATO;
+ break;
+ }
+ } // End if (oldTypeIsMOD && newTypeIsXM)
-
/////////////////////////////////////////////////////////////////////////////////
// Convert anything to MOD - remove volume column, adjust retrig, effect memory
if (newTypeIsMOD)
@@ -664,26 +671,38 @@
CSoundFile::FrequencyToTranspose(&m_SndFile.Samples[i]);
if (!(m_SndFile.Samples[i].uFlags & CHN_PANNING)) m_SndFile.Samples[i].nPan = 128;
}
- BOOL bBrokenNoteMap = FALSE;
- for (UINT j=1; j<=m_SndFile.m_nInstruments; j++)
+ bool bBrokenNoteMap = false, bBrokenSustainLoop = false;
+ for (UINT j = 1; j <= m_SndFile.m_nInstruments; j++)
{
MODINSTRUMENT *pIns = m_SndFile.Instruments[j];
if (pIns)
{
- for (UINT k=0; k<NOTE_MAX; k++)
+ for (UINT k = 0; k < NOTE_MAX; k++)
{
if ((pIns->NoteMap[k]) && (pIns->NoteMap[k] != (BYTE)(k+1)))
{
- bBrokenNoteMap = TRUE;
+ bBrokenNoteMap = true;
break;
}
}
+ // Convert sustain loops to sustain "points"
+ if(pIns->VolEnv.nSustainStart != pIns->VolEnv.nSustainEnd)
+ {
+ pIns->VolEnv.nSustainEnd = pIns->VolEnv.nSustainStart;
+ bBrokenSustainLoop = true;
+ }
+ if(pIns->PanEnv.nSustainStart != pIns->PanEnv.nSustainEnd)
+ {
+ pIns->PanEnv.nSustainEnd = pIns->PanEnv.nSustainStart;
+ bBrokenSustainLoop = true;
+ }
pIns->dwFlags &= ~(ENV_SETPANNING|ENV_VOLCARRY|ENV_PANCARRY|ENV_PITCHCARRY|ENV_FILTER|ENV_PITCH);
pIns->nIFC &= 0x7F;
pIns->nIFR &= 0x7F;
}
}
if (bBrokenNoteMap) AddToLog("WARNING: Note Mapping will be lost when saving as XM.\n");
+ if (bBrokenSustainLoop) AddToLog("WARNING: Sustain loops were converted to sustain points.\n");
}
if(newTypeIsMOD)
Modified: trunk/OpenMPT/soundlib/Load_s3m.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_s3m.cpp 2009-08-30 14:29:58 UTC (rev 349)
+++ trunk/OpenMPT/soundlib/Load_s3m.cpp 2009-08-30 22:27:15 UTC (rev 350)
@@ -18,43 +18,6 @@
extern WORD S3MFineTuneTable[16];
-static void HandleZxx(uint8& nType, MODCOMMAND* const m)
-//-------------------------------------------------------------------
-{
- if(nType == 0)
- {
- CString str;
- str.Format(GetStrI18N("The S3M file contains Zxx effect. "
- "It can be processed in the following ways:\n"
- "Yes : Convert Zxx to S8x(set panning)-effects (PixPlay)\n"
- "No : Remove Zxx effects\n"
- "Cancel: Keep Zxx effects\n"
- "\nNote that options (yes) and (no) modify the loaded pattern data."
- ));
- const int nResult = ::AfxMessageBox(str, MB_YESNOCANCEL|MB_ICONINFORMATION);
-
- if(nResult == IDYES)
- nType = 2;
- else if(nResult == IDNO)
- nType = 3;
- else
- nType = 1;
- }
- if(nType != 1)
- {
- if(nType == 2)
- {
- m->command = CMD_S3MCMDEX;
- m->param = 0x80 + (m->param & 0xF);
- }
- else
- {
- m->command = 0;
- m->param = 0;
- }
- }
-}
-
//////////////////////////////////////////////////////
// ScreamTracker S3M file support
@@ -264,6 +227,7 @@
DWORD dwMemPos;
BYTE insflags[128], inspack[128];
S3MFILEHEADER psfh = *(S3MFILEHEADER *)lpStream;
+ bool bKeepMidiMacros = false;
psfh.reserved1 = LittleEndianW(psfh.reserved1);
psfh.ordnum = LittleEndianW(psfh.ordnum);
@@ -278,8 +242,26 @@
if (psfh.scrm != 0x4D524353) return false;
if((psfh.cwtv & 0xF000) == 0x5000) // OpenMPT Version number (Major.Minor)
+ {
m_dwLastSavedWithVersion = (psfh.cwtv & 0x0FFF) << 16;
+ bKeepMidiMacros = true; // simply load Zxx commands
+ }
+ if(psfh.cwtv == 0x1320 && psfh.special == 0 && (psfh.ordnum & 0x0F) == 0 && psfh.ultraclicks == 0 && (psfh.flags & ~0x50) == 0)
+ {
+ // MPT 1.16 and older versions of OpenMPT
+ m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 16, 00, 00);
+ bKeepMidiMacros = true; // simply load Zxx commands
+ }
+ if((psfh.cwtv & 0xF000) >= 0x2000)
+ {
+ // 2xyy - Orpheus, 3xyy - IT, 4xyy - Schism, 5xyy - OpenMPT
+ bKeepMidiMacros = true; // simply load Zxx commands
+ }
+
+ if(!bKeepMidiMacros) // Remove macros so they don't interfere with other tunes
+ memset(&m_MidiCfg, 0, sizeof(m_MidiCfg));
+
dwMemPos = 0x60;
m_nType = MOD_TYPE_S3M;
memset(m_szNames,0,sizeof(m_szNames));
@@ -292,7 +274,8 @@
m_nDefaultTempo = CLAMP(m_nDefaultTempo, 32, 255);
// Global Volume
m_nDefaultGlobalVolume = psfh.globalvol << 2;
- if ((!m_nDefaultGlobalVolume) || (m_nDefaultGlobalVolume > 256)) m_nDefaultGlobalVolume = 256;
+ if(!m_nDefaultGlobalVolume && psfh.cwtv < 0x1320) m_nDefaultGlobalVolume = 256; // not very reliable, but it fixes a few tunes
+ if(m_nDefaultGlobalVolume > 256) m_nDefaultGlobalVolume = 256;
m_nSamplePreAmp = psfh.mastervol & 0x7F; // Bit 8 = Stereo (we always use stereo)
// Channels
m_nChannels = 4;
@@ -386,8 +369,14 @@
//ASSERT(iLooplength == 0 || iLooplength > 4);
}
}
+
+ /* Try to find out if Zxx commands are supposed to be panning commands (PixPlay).
+ We won't convert if there are not enough Zxx commands, too "high" Zxx commands
+ or there are only "left" or "right" pannings (we assume that stereo should be somewhat balanced) */
+ bool bDoNotConvertZxx = false;
+ int iZxxCountRight = 0, iZxxCountLeft = 0;
+
// Reading patterns
- uint8 nZxxHandling = 0;
for (UINT iPat=0; iPat<patnum; iPat++)
{
UINT nInd = ((DWORD)ptr[nins+iPat]) << 4;
@@ -402,8 +391,9 @@
MODCOMMAND *p = Patterns[iPat];
UINT row = 0;
UINT j = 0;
- while (j < len)
+ while (row < 64) // this fixes ftp://us.aminet.net/pub/aminet/mods/8voic/s3m_hunt.lha (was: while (j < len))
{
+ if(j + nInd + 1 >= dwMemLength) break;
BYTE b = src[j++];
if (!b)
{
@@ -416,6 +406,7 @@
MODCOMMAND *m = &p[row*m_nChannels+chn];
if (b & 0x20)
{
+ if(j + nInd + 2 >= dwMemLength) break;
m->note = src[j++];
if (m->note < 0xF0) m->note = (m->note & 0x0F) + 12*(m->note >> 4) + 13;
else if (m->note == 0xFF) m->note = NOTE_NONE;
@@ -423,6 +414,7 @@
}
if (b & 0x40)
{
+ if(j + nInd + 1 >= dwMemLength) break;
UINT vol = src[j++];
if ((vol >= 128) && (vol <= 192))
{
@@ -437,12 +429,22 @@
}
if (b & 0x80)
{
+ if(j + nInd + 2 >= dwMemLength) break;
m->command = src[j++];
m->param = src[j++];
if (m->command) S3MConvert(m, FALSE);
if(m->command == CMD_MIDI)
{
- HandleZxx(nZxxHandling, m);
+ if(m->param > 0x0F)
+ {
+ // PixPlay has Z00 to Z0F panning, so we ignore this.
+ bDoNotConvertZxx = true;
+ }
+ else
+ {
+ if(m->param < 0x08) iZxxCountLeft++;
+ if(m->param > 0x08) iZxxCountRight++;
+ }
}
}
} else
@@ -451,10 +453,27 @@
if (b & 0x40) j++;
if (b & 0x80) j += 2;
}
- if (j >= len) break;
}
}
}
+
+ if((UINT)(iZxxCountLeft + iZxxCountRight) >= m_nChannels && !bDoNotConvertZxx && (iZxxCountLeft - iZxxCountRight > -(int)m_nChannels))
+ {
+ // there are enough Zxx commands, so let's assume this was made to be played with PixPlay
+ for(PATTERNINDEX nPat = 0; nPat < Patterns.Size(); nPat++) if(Patterns[nPat])
+ {
+ MODCOMMAND *m = Patterns[nPat];
+ for(UINT len = PatternSize[nPat] * m_nChannels; len; m++, len--)
+ {
+ if(m->command == CMD_MIDI)
+ {
+ m->command = CMD_S3MCMDEX;
+ m->param |= 0x80;
+ }
+ }
+ }
+ }
+
// Reading samples
for (UINT iRaw=1; iRaw<=insnum; iRaw++) if ((Samples[iRaw].nLength) && (insfile[iRaw]))
{
@@ -469,11 +488,6 @@
m_nMaxPeriod = 32767;
if (psfh.flags & 0x10) m_dwSongFlags |= SONG_AMIGALIMITS;
- if(nZxxHandling != 0 && nZxxHandling != 1 && GetpModDoc() != 0)
- {
- GetpModDoc()->SetModified();
- GetpModDoc()->SetShowSaveDialog(true);
- }
return true;
}
@@ -507,15 +521,14 @@
header[0x1B] = 0;
header[0x1C] = 0x1A;
header[0x1D] = 0x10;
- // Changes to 1.17.02.53:
- // -Try to save whole sequence instead of stopping on first empty order.
- // -With more than 0xF0 orders, limit sequence to 0xF0 instead of just masking with 0xF0.
- //TODO: Check whether the 0xF0 mask is correct.
- // (there are two bytes reserved from the header, so why 0xF0 mask?).
- //nbo = (GetNumPatterns() + 15) & 0xF0;
+
nbo = Order.GetLengthTailTrimmed();
- if(nbo > 0xF0) nbo = 0xF0;
- if (!nbo) nbo = 1;
+ if (nbo < 2)
+ nbo = 2;
+ else if (nbo & 1) // number of orders must be even
+ nbo++;
+ nbo = (nbo + 15) & 0xF0; // TODO why does it not work otherwise? nbo should be multiple of 2, not 16!
+ if(nbo > 0xF0) nbo = 0xF0; // sequence too long
header[0x20] = nbo & 0xFF;
header[0x21] = nbo >> 8;
nbi = m_nInstruments;
@@ -536,7 +549,7 @@
// Following: One nibble = Major version, one byte = Minor version (hex)
MptVersion::VersionNum vVersion = MptVersion::num;
header[0x28] = (BYTE)((vVersion >> 16) & 0xFF); // the "17" in OpenMPT 1.17
- header[0x29] = 0x50 | (BYTE)((vVersion >> 24) & 0x0F); // the "1" in OpenMPT 1.17 + OpenMPT Identifier 5 (works only for versions up to 15.99 :))
+ header[0x29] = 0x50 | (BYTE)((vVersion >> 24) & 0x0F); // the "1." in OpenMPT 1.17 + OpenMPT Identifier 5 (works only for versions up to 9.99 :))
header[0x2A] = 0x02; // Version = 1 => Signed samples
header[0x2B] = 0x00;
header[0x2C] = 'S';
@@ -548,7 +561,7 @@
header[0x32] = CLAMP(m_nDefaultTempo, 32, 255);
header[0x33] = CLAMP(m_nSamplePreAmp, 0x10, 0x7F) | 0x80; // Bit 8 = Stereo
header[0x34] = 0x10; // 16 Channels for UltraClick removal
- header[0x35] = 0xFC;
+ header[0x35] = 0xFC; // Write pan positions
for (i=0; i<32; i++)
{
if (i < m_nChannels)
@@ -562,7 +575,7 @@
memset(patptr, 0, sizeof(patptr));
memset(insptr, 0, sizeof(insptr));
UINT ofs0 = 0x60 + nbo;
- UINT ofs1 = ((0x60 + nbo + nbi*2 + nbp*2 + 15) & 0xFFF0) + 0x20;
+ UINT ofs1 = ((0x60 + nbo + nbi * 2 + nbp * 2 + 15) & 0xFFF0) + ((header[0x35] == 0xFC) ? 0x20 : 0);
UINT ofs = ofs1;
for (i=0; i<nbi; i++) insptr[i] = (WORD)((ofs + i*0x50) / 16);
for (i=0; i<nbp; i++) patptr[i] = (WORD)((ofs + nbi*0x50) / 16);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-08-30 14:30:04
|
Revision: 349
http://modplug.svn.sourceforge.net/modplug/?rev=349&view=rev
Author: saga-games
Date: 2009-08-30 14:29:58 +0000 (Sun, 30 Aug 2009)
Log Message:
-----------
[Fix] XM Compatibility: Compatible Arpeggio was done wrong
[Fix] XM Compatibility: More compatible "Note Off + Something"
[Fix] IT COmpatibility: Removed a "fix" again that was causing to completely destroy panbrello
[Imp] Comments tab: Only switch only to instrument list in XM modules if there are actually instruments
Modified Paths:
--------------
trunk/OpenMPT/mptrack/view_com.cpp
trunk/OpenMPT/soundlib/Snd_fx.cpp
trunk/OpenMPT/soundlib/Sndmix.cpp
Modified: trunk/OpenMPT/mptrack/view_com.cpp
===================================================================
--- trunk/OpenMPT/mptrack/view_com.cpp 2009-08-30 00:07:19 UTC (rev 348)
+++ trunk/OpenMPT/mptrack/view_com.cpp 2009-08-30 14:29:58 UTC (rev 349)
@@ -114,7 +114,7 @@
if(pModDoc)
{
pSndFile= pModDoc->GetSoundFile();
- if(pSndFile && (pSndFile->m_nType & MOD_TYPE_XM))
+ if(pSndFile && (pSndFile->m_nType & MOD_TYPE_XM) && pSndFile->m_nInstruments > 0)
{
m_nListId = IDC_LIST_INSTRUMENTS;
}
Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-08-30 00:07:19 UTC (rev 348)
+++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-08-30 14:29:58 UTC (rev 349)
@@ -1233,8 +1233,8 @@
note = instr = 0;
}
- // XM: Key-Off + Sample == Note Cut (BUT: Only if no instr number is present!)
- if ((note == NOTE_KEYOFF) && (!pChn->pModInstrument || !IsCompatibleMode(TRK_FASTTRACKER2)) && ((!pChn->pModInstrument) || (!(pChn->pModInstrument->dwFlags & ENV_VOLUME))))
+ // XM: Key-Off + Sample == Note Cut (BUT: Only if no instr number or volume effect is present!)
+ if ((note == NOTE_KEYOFF) && ((!instr && !vol && cmd != CMD_VOLUME) || !IsCompatibleMode(TRK_FASTTRACKER2)) && ((!pChn->pModInstrument) || (!(pChn->pModInstrument->dwFlags & ENV_VOLUME))))
{
pChn->dwFlags |= CHN_FASTVOLRAMP;
pChn->nVolume = 0;
Modified: trunk/OpenMPT/soundlib/Sndmix.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndmix.cpp 2009-08-30 00:07:19 UTC (rev 348)
+++ trunk/OpenMPT/soundlib/Sndmix.cpp 2009-08-30 14:29:58 UTC (rev 349)
@@ -951,8 +951,7 @@
pChn->nRealPan = pChn->nPan;
}
- if (pChn->nRealPan < 0) pChn->nRealPan = 0;
- if (pChn->nRealPan > 256) pChn->nRealPan = 256;
+ pChn->nRealPan = CLAMP(pChn->nRealPan, 0, 256);
pChn->nRampLength = 0;
//Aux variables
@@ -1231,7 +1230,7 @@
if (!(m_dwSongFlags & SONG_FIRSTTICK))
{
- arpPos = (m_nTickCount - m_nMusicSpeed) % 3;
+ arpPos = ((int)m_nTickCount - (int)m_nMusicSpeed) % 3;
if(arpPos < 0) arpPos += 3;
switch(arpPos)
{
@@ -1445,7 +1444,7 @@
pdelta += pChn->nRealPan;
pChn->nRealPan = CLAMP(pdelta, 0, 256);
- if(IsCompatibleMode(TRK_IMPULSETRACKER)) pChn->nPan = pChn->nRealPan;
+ //if(IsCompatibleMode(TRK_IMPULSETRACKER)) pChn->nPan = pChn->nRealPan; // TODO
}
int nPeriodFrac = 0;
// Instrument Auto-Vibrato
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-08-30 00:07:38
|
Revision: 348
http://modplug.svn.sourceforge.net/modplug/?rev=348&view=rev
Author: saga-games
Date: 2009-08-30 00:07:19 +0000 (Sun, 30 Aug 2009)
Log Message:
-----------
[Fix] Rearrange Samples: Also remap samples on instrument "keyboard" that were removed, so that f.e. instruments with VSTis won't have unwanted samples suddenly
[Fix] Order list: After inserting a single order, the list is now no more in multi-order mode.
[Imp] Order list: Enable multi-order mode also when using shift + cursor keys
[Ref] Some internal refactoring
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Ctrl_pat.h
trunk/OpenMPT/mptrack/Ctrl_seq.cpp
trunk/OpenMPT/mptrack/Modedit.cpp
trunk/OpenMPT/mptrack/tagging.cpp
Modified: trunk/OpenMPT/mptrack/Ctrl_pat.h
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_pat.h 2009-08-29 14:56:14 UTC (rev 347)
+++ trunk/OpenMPT/mptrack/Ctrl_pat.h 2009-08-30 00:07:19 UTC (rev 348)
@@ -44,6 +44,9 @@
void InvalidateSelection() const;
UINT GetCurrentPattern() const;
ORD_SELECTION GetCurSel(bool bIgnoreSelection) const;
+ // make the current selection the secondary selection (used for keyboard orderlist navigation)
+ inline void SetCurSelTo2ndSel()
+ {if(m_bShift && m_nScrollPos2nd == ORDERINDEX_INVALID) m_nScrollPos2nd = m_nScrollPos; else if(!m_bShift && m_nScrollPos2nd != ORDERINDEX_INVALID) m_nScrollPos2nd = ORDERINDEX_INVALID;};
bool SetCurSel(ORDERINDEX sel, bool bEdit = true, bool bShiftClick = false);
BOOL ProcessKeyDown(UINT nChar);
BOOL ProcessChar(UINT nChar);
@@ -71,7 +74,7 @@
// Returns the number of sequence items visible in the list.
BYTE GetLength();
- // Return true iff given order is in margins given that first shown order
+ // Return true if given order is in margins given that first shown order
// is 'startOrder'. Begin part of the whole sequence
// is not interpreted to be in margins regardless of the margin value.
bool IsOrderInMargins(int order, int startOrder);
Modified: trunk/OpenMPT/mptrack/Ctrl_seq.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2009-08-29 14:56:14 UTC (rev 347)
+++ trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2009-08-30 00:07:19 UTC (rev 348)
@@ -307,10 +307,10 @@
switch(nChar)
{
case VK_UP:
- case VK_LEFT: SetCurSel(m_nScrollPos - 1); break;
+ case VK_LEFT: SetCurSelTo2ndSel(); SetCurSel(m_nScrollPos - 1); break;
case VK_DOWN:
- case VK_RIGHT: SetCurSel(m_nScrollPos + 1); break;
- case VK_HOME: SetCurSel(0); break;
+ case VK_RIGHT: SetCurSelTo2ndSel(); SetCurSel(m_nScrollPos + 1); break;
+ case VK_HOME: SetCurSelTo2ndSel(); SetCurSel(0); break;
case VK_END:
if (m_pModDoc)
{
@@ -318,6 +318,7 @@
ORDERINDEX i = 0;
const int nSeqLength = pSndFile->Order.size();
for (i=0; i+1 < nSeqLength; i++) if (pSndFile->Order[i+1] == pSndFile->Order.GetInvalidPatIndex()) break;
+ SetCurSelTo2ndSel();
SetCurSel(i);
}
break;
@@ -928,7 +929,10 @@
pSndFile->Order[nInsertEnd + i + 1] = pSndFile->Order[nInsertEnd - nInsertCount + i];
}
m_nScrollPos = min(nInsertEnd + 1, pSndFile->Order.GetCount() - 1);
- m_nScrollPos2nd = min(m_nScrollPos + nInsertCount, pSndFile->Order.GetCount() - 1);
+ if(nInsertCount > 0)
+ m_nScrollPos2nd = min(m_nScrollPos + nInsertCount, pSndFile->Order.GetCount() - 1);
+ else
+ m_nScrollPos2nd = ORDERINDEX_INVALID;
InvalidateRect(NULL, FALSE);
m_pModDoc->SetModified();
m_pModDoc->UpdateAllViews(NULL, HINT_MODSEQUENCE, this);
Modified: trunk/OpenMPT/mptrack/Modedit.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-29 14:56:14 UTC (rev 347)
+++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-30 00:07:19 UTC (rev 348)
@@ -1060,7 +1060,7 @@
nSampleMap[i] = i;
// First, find out which sample slots are unused and create the new sample map
- for(UINT i = 1 ; i <= m_SndFile.m_nSamples; i++) {
+ for(SAMPLEINDEX i = 1 ; i <= m_SndFile.m_nSamples; i++) {
if(!m_SndFile.Samples[i].pSample)
{
// Move all following samples
@@ -1077,21 +1077,21 @@
BEGIN_CRITICAL();
// Now, move everything around
- for(UINT i = 1; i <= m_SndFile.m_nSamples; i++)
+ for(SAMPLEINDEX i = 1; i <= m_SndFile.m_nSamples; i++)
{
- if(nSampleMap[i] && nSampleMap[i] != i)
+ if(nSampleMap[i] != i)
{
// This gotta be moved
m_SndFile.MoveSample(i, nSampleMap[i]);
m_SndFile.Samples[i].pSample = nullptr;
strcpy(m_SndFile.m_szNames[nSampleMap[i]], m_SndFile.m_szNames[i]);
- m_SndFile.m_szNames[i][0] = '\0';
+ memset(m_SndFile.m_szNames[i], 0, sizeof(m_SndFile.m_szNames[i]));
// Also update instrument mapping (if module is in instrument mode)
- for(UINT iInstr = 1; iInstr <= m_SndFile.m_nInstruments; iInstr++){
+ for(INSTRUMENTINDEX iInstr = 1; iInstr <= m_SndFile.m_nInstruments; iInstr++){
if(m_SndFile.Instruments[iInstr]){
MODINSTRUMENT *p = m_SndFile.Instruments[iInstr];
- for(WORD iNote =0; iNote < 128; iNote++)
+ for(WORD iNote = 0; iNote < 128; iNote++)
if(p->Keyboard[iNote] == i) p->Keyboard[iNote] = nSampleMap[i];
}
}
@@ -1101,12 +1101,12 @@
// Go through the patterns and remap samples (if module is in sample mode)
if(!m_SndFile.m_nInstruments)
{
- for (UINT nPat=0; nPat < m_SndFile.Patterns.Size(); nPat++) if (m_SndFile.Patterns[nPat])
+ for (PATTERNINDEX nPat = 0; nPat < m_SndFile.Patterns.Size(); nPat++) if (m_SndFile.Patterns[nPat])
{
MODCOMMAND *m = m_SndFile.Patterns[nPat];
- for (UINT len = m_SndFile.PatternSize[nPat] * m_SndFile.m_nChannels; len; m++, len--)
+ for(UINT len = m_SndFile.PatternSize[nPat] * m_SndFile.m_nChannels; len; m++, len--)
{
- if(nSampleMap[m->instr]) m->instr = nSampleMap[m->instr];
+ if(m->instr <= m_SndFile.m_nSamples) m->instr = nSampleMap[m->instr];
}
}
}
@@ -1698,7 +1698,7 @@
}
if ((!m_SndFile.m_nInstruments) && ((m_SndFile.m_nSamples > 1) || (m_SndFile.Samples[1].pSample)))
{
- if (pDup) return -1;
+ if (pDup) return INSTRUMENTINDEX_INVALID;
UINT n = CMainFrame::GetMainFrame()->MessageBox("Convert existing samples to instruments first?", NULL, MB_YESNOCANCEL|MB_ICONQUESTION);
if (n == IDYES)
{
@@ -1713,7 +1713,7 @@
if (!p)
{
ErrorBox(IDS_ERR_OUTOFMEMORY, CMainFrame::GetMainFrame());
- return -1;
+ return INSTRUMENTINDEX_INVALID;
}
InitializeInstrument(p, smp);
m_SndFile.Instruments[smp] = p;
Modified: trunk/OpenMPT/mptrack/tagging.cpp
===================================================================
--- trunk/OpenMPT/mptrack/tagging.cpp 2009-08-29 14:56:14 UTC (rev 347)
+++ trunk/OpenMPT/mptrack/tagging.cpp 2009-08-30 00:07:19 UTC (rev 348)
@@ -1,5 +1,5 @@
/*
- * Purpose: File tagging (ID3v2, RIFF + more iIn the future)
+ * Purpose: File tagging (ID3v2, RIFF + more in the future)
* Authors: OpenMPT Devs
*/
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-08-29 14:56:28
|
Revision: 347
http://modplug.svn.sourceforge.net/modplug/?rev=347&view=rev
Author: saga-games
Date: 2009-08-29 14:56:14 +0000 (Sat, 29 Aug 2009)
Log Message:
-----------
[Fix] MP3 Tagging: Synchsafe integers were calculated wrong; Writing the comments field last so the chance of fucking up everything is lower (Winamp's tag reader seems to have some problems with my long comments, but they seem to be encoded correctly? :-S)
[Fix] XM Compatibility: Note Off with instrument number causes fadeout for samples that have no envelope.
[Imp] Comments tab: Default view mode is instruments instead of samples for XM files.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/tagging.cpp
trunk/OpenMPT/mptrack/view_com.cpp
trunk/OpenMPT/soundlib/Load_psm.cpp
trunk/OpenMPT/soundlib/Snd_fx.cpp
Modified: trunk/OpenMPT/mptrack/tagging.cpp
===================================================================
--- trunk/OpenMPT/mptrack/tagging.cpp 2009-08-29 00:40:26 UTC (rev 346)
+++ trunk/OpenMPT/mptrack/tagging.cpp 2009-08-29 14:56:14 UTC (rev 347)
@@ -1,5 +1,5 @@
/*
- * Purpose: File tagging (ID3v2, RIFF + more in the future)
+ * Purpose: File tagging (ID3v2, RIFF + more iIn the future)
* Authors: OpenMPT Devs
*/
@@ -23,15 +23,15 @@
// Convert Integer to Synchsafe Integer (see ID3v2.4 specs)
// Basically, it's a BigEndian integer, but the MSB of all bytes is 0.
// Thus, a 32-bit integer turns into a 28-bit integer.
-UINT32 CFileTagging::intToSynchsafe(UINT32 in)
+UINT32 CFileTagging::intToSynchsafe(UINT32 iIn)
{
- in = LittleEndian(in);
- UINT32 out = 0;
+ iIn = LittleEndian(iIn);
+ UINT32 iOut = 0, iSteps = 0;
do {
- out <<= 8;
- out |= (in & 0x7F);
- } while(in >>= 7);
- return BigEndian(out);
+ iOut |= (iIn & 0x7F) << iSteps;
+ iSteps += 8;
+ } while(iIn >>= 7);
+ return BigEndian(iOut);
}
// Write Tags
@@ -53,7 +53,7 @@
tHeader.flags = 0x00; // No flags
fwrite(&tHeader, 1, sizeof(tHeader), f);
- // Write TIT2 (Title), TCOM / TPE1 (Composer), TALB (Album), TCON (Genre), TYER (Date), WXXX (URL), COMM (Comment), TENC (Encoder)
+ // Write TIT2 (Title), TCOM / TPE1 (Composer), TALB (Album), TCON (Genre), TYER (Date), WXXX (URL), TENC (Encoder), COMM (Comment)
WriteID3v2Frame("TIT2", title, f);
WriteID3v2Frame("TPE1", artist, f);
WriteID3v2Frame("TCOM", artist, f);
@@ -61,8 +61,8 @@
WriteID3v2Frame("TCON", genre, f);
WriteID3v2Frame("TYER", year, f);
WriteID3v2Frame("WXXX", url, f);
+ WriteID3v2Frame("TENC", encoder, f);
WriteID3v2Frame("COMM", comments, f);
- WriteID3v2Frame("TENC", encoder, f);
// Write Padding
for(UINT i = 0; i < ID3v2_PADDING; i++)
Modified: trunk/OpenMPT/mptrack/view_com.cpp
===================================================================
--- trunk/OpenMPT/mptrack/view_com.cpp 2009-08-29 00:40:26 UTC (rev 346)
+++ trunk/OpenMPT/mptrack/view_com.cpp 2009-08-29 14:56:14 UTC (rev 347)
@@ -97,13 +97,30 @@
//----------------------------
{
m_nCurrentListId = 0;
- m_nListId = IDC_LIST_SAMPLES;
+ m_nListId = 0;//IDC_LIST_SAMPLES;
}
void CViewComments::OnInitialUpdate()
//-----------------------------------
{
+ if(m_nListId == 0)
+ {
+ m_nListId = IDC_LIST_SAMPLES;
+
+ // For XM, set the instrument list as the default list
+ CModDoc *pModDoc = GetDocument();
+ CSoundFile *pSndFile;
+ if(pModDoc)
+ {
+ pSndFile= pModDoc->GetSoundFile();
+ if(pSndFile && (pSndFile->m_nType & MOD_TYPE_XM))
+ {
+ m_nListId = IDC_LIST_INSTRUMENTS;
+ }
+ }
+ }
+
CChildFrame *pFrame = (CChildFrame *)GetParentFrame();
CRect rect;
Modified: trunk/OpenMPT/soundlib/Load_psm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-29 00:40:26 UTC (rev 346)
+++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-29 14:56:14 UTC (rev 347)
@@ -15,6 +15,7 @@
* - Sinaria - Seems to work (never played the game, so I can't really tell...)
*
* Effect conversion should be about right...
+ * If OpenMPT will ever support subtunes properly, the subtune crap should be rewritten completely.
*/
#include "stdafx.h"
Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-08-29 00:40:26 UTC (rev 346)
+++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-08-29 14:56:14 UTC (rev 347)
@@ -1233,8 +1233,8 @@
note = instr = 0;
}
- // XM: Key-Off + Sample == Note Cut
- if ((note == NOTE_KEYOFF) && ((!pChn->pModInstrument) || (!(pChn->pModInstrument->dwFlags & ENV_VOLUME))))
+ // XM: Key-Off + Sample == Note Cut (BUT: Only if no instr number is present!)
+ if ((note == NOTE_KEYOFF) && (!pChn->pModInstrument || !IsCompatibleMode(TRK_FASTTRACKER2)) && ((!pChn->pModInstrument) || (!(pChn->pModInstrument->dwFlags & ENV_VOLUME))))
{
pChn->dwFlags |= CHN_FASTVOLRAMP;
pChn->nVolume = 0;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-08-29 00:40:36
|
Revision: 346
http://modplug.svn.sourceforge.net/modplug/?rev=346&view=rev
Author: saga-games
Date: 2009-08-29 00:40:26 +0000 (Sat, 29 Aug 2009)
Log Message:
-----------
[Fix] IT Compatibility: Don't reset channel panning if panbrello ends (experimental)
[Imp] PSM Loader: I think it's finished... finally. Subsongs should work perfectly, a few other things have also been fixed / improved.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Moddoc.cpp
trunk/OpenMPT/soundlib/Load_psm.cpp
trunk/OpenMPT/soundlib/Sndfile.cpp
trunk/OpenMPT/soundlib/Sndmix.cpp
Modified: trunk/OpenMPT/mptrack/Moddoc.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-08-26 22:04:14 UTC (rev 345)
+++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-08-29 00:40:26 UTC (rev 346)
@@ -354,9 +354,9 @@
case MOD_TYPE_STM:
case MOD_TYPE_DSM:
case MOD_TYPE_AMF:
- case MOD_TYPE_PSM:
m_SndFile.ChangeModTypeTo(MOD_TYPE_S3M);
break;
+ case MOD_TYPE_PSM:
default:
m_SndFile.ChangeModTypeTo(MOD_TYPE_IT);
}
Modified: trunk/OpenMPT/soundlib/Load_psm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-26 22:04:14 UTC (rev 345)
+++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-29 00:40:26 UTC (rev 346)
@@ -8,12 +8,11 @@
*
* What's playing?
* - Epic Pinball - Perfect! (the old tunes in PSM16 format are not supported)
- * - Extreme Pinball - Default tempo / speed / restart position of subtunes is missing.
- * I'm using the last default values, restart position is still completely missing
+ * - Extreme Pinball - Perfect! (subtunes included!)
* - Jazz Jackrabbit - Perfect!
- * - One Must Fall! - Perfect! (I modelled the volume slide and portamento conversion after this, as I got the original MTM files)
+ * - One Must Fall! - Perfect! (it helped a lot to have the original MTM files...)
* - Silverball - Currently not supported (old PSM16 format)
- * - Sinaria - Seems to work more or less (never played the game, so I can't really tell...)
+ * - Sinaria - Seems to work (never played the game, so I can't really tell...)
*
* Effect conversion should be about right...
*/
@@ -77,6 +76,26 @@
};
#pragma pack()
+struct PSMSUBSONG // For internal use (pattern conversion)
+{
+ BYTE channelPanning[MAX_BASECHANNELS], channelVolume[MAX_BASECHANNELS];
+ bool channelSurround[MAX_BASECHANNELS];
+ BYTE defaultTempo, defaultSpeed;
+ CHAR songName[10];
+ ORDERINDEX startOrder, endOrder, restartPos;
+
+ PSMSUBSONG() {
+ memset(channelPanning, 128, sizeof(channelPanning));
+ memset(channelVolume, 64, sizeof(channelVolume));
+ memset(channelSurround, false, sizeof(channelSurround));
+ memset(songName, 0, sizeof(songName));
+ defaultTempo = 125;
+ defaultSpeed = 6;
+ startOrder = endOrder = restartPos = ORDERINDEX_INVALID;
+ }
+};
+
+// Portamento effect conversion (depending on format version)
inline BYTE convert_psm_porta(BYTE param, bool bNewFormat)
{
return ((bNewFormat) ? (param) : ((param < 4) ? (param | 0xF0) : (param >> 2)));
@@ -100,7 +119,8 @@
) return false;
// Yep, this seems to be a valid file.
- m_nType = MOD_TYPE_PSM;
+ m_nType = MOD_TYPE_IT;
+ SetModFlag(MSF_COMPATIBLE_PLAY, true);
m_nChannels = 0;
dwMemPos += 12;
@@ -110,15 +130,18 @@
m_nVSTiVolume = m_nSamplePreAmp = 48; // not supported in this format, so use a good default value
// pattern offset and identifier
- PATTERNINDEX numPatterns = 0;
- vector<DWORD> patternOffsets;
- vector<DWORD> patternIDs;
+ PATTERNINDEX numPatterns = 0; // used for setting up the orderlist - final pattern count
+ vector<DWORD> patternOffsets; // pattern offsets (sorted as they occour in the file)
+ vector<DWORD> patternIDs; // pattern IDs (sorted as they occour in the file)
+ vector<DWORD> orderOffsets; // combine the upper two vectors to get the offsets for each order item
patternOffsets.clear();
patternIDs.clear();
+ orderOffsets.clear();
Order.clear();
+ // subsong setup
+ vector<PSMSUBSONG> subsongs;
+ bool bSubsongPanningDiffers = false; // do we have subsongs with different panning positions?
- std::string sComment; // we will store some information about the tune here
-
while(dwMemPos + 8 < dwMemLength)
{
// Skip through the chunks
@@ -141,39 +164,37 @@
break;
case 0x444F4250: // "PBOD" - Pattern data of a single pattern
- if(chunkSize < 4 || chunkSize != LittleEndian(*(DWORD *)(lpStream + dwMemPos))) return false; // same value twice
+ if(chunkSize < 8 || chunkSize != LittleEndian(*(DWORD *)(lpStream + dwMemPos))) return false; // same value twice
- // Pattern ID (something like "P0 " or "P13 ") follows
+ // Pattern ID (something like "P0 " or "P13 ", or "PATT0 " in Sinaria) follows
if(memcmp(lpStream + dwMemPos + 4, "P", 1)) return false;
if(!memcmp(lpStream + dwMemPos + 4, "PATT", 4)) bNewFormat = true;
+ if(bNewFormat && chunkSize < 12) return false; // 4 additional bytes
+
char patternID[4];
memcpy(patternID, lpStream + dwMemPos + 5 + (bNewFormat ? 3 : 0), 3);
patternID[3] = 0;
+ patternIDs.push_back(atoi(patternID));
patternOffsets.push_back(dwMemPos + 8 + (bNewFormat ? 4 : 0));
- patternIDs.push_back(atoi(patternID));
- numPatterns++;
// Convert later as we have to know how many channels there are.
break;
- case 0x474E4F53: // "SONG" - Information about this file (channel count etc)
- // We will not check for the "song type", because it is not ALWAYS "MAINSONG " (Extreme Pinball seems to use other song types for the sub songs)
- // However, the last char always seems to be a space char.
+ case 0x474E4F53: // "SONG" - Subsong information (channel count etc)
{
if(chunkSize < sizeof(PSMSONGHEADER)) return false;
PSMSONGHEADER *pSong = (PSMSONGHEADER *)(lpStream + dwMemPos);
- if(pSong->compression != 0x01) return false;
- m_nChannels = max(m_nChannels, pSong->numChannels); // subsongs *might* have different channel count
+ if(pSong->compression != 0x01) return false; // no compression for PSM files
+ m_nChannels = CLAMP(pSong->numChannels, m_nChannels, MAX_BASECHANNELS); // subsongs *might* have different channel count
- CHAR cSongName[10];
- memcpy(cSongName, &pSong->songType, 9);
- cSongName[9] = 0;
- sComment += "\r\nSubsong: ";
- sComment += cSongName;
+ PSMSUBSONG subsong;
+ subsong.restartPos = (ORDERINDEX)Order.size(); // restart order "offset": current orderlist length
+ memcpy(subsong.songName, &pSong->songType, 9); // subsong name
+ subsong.songName[9] = 0;
DWORD dwChunkPos = dwMemPos + sizeof(PSMSONGHEADER);
- // Sub chunks
+ // "Sub sub chunks"
while(dwChunkPos + 8 < dwMemPos + chunkSize)
{
DWORD subChunkID = LittleEndian(*(DWORD *)(lpStream + dwChunkPos));
@@ -190,20 +211,11 @@
memcpy(cversion, lpStream + dwChunkPos, 6);
cversion[6] = 0;
int version = atoi(cversion);
- // Sinaria song dates
+ // Sinaria song dates (just to go sure...)
if(version == 800211 || version == 940902 || version == 940903 ||
version == 940906 || version == 940914 || version == 941213)
bNewFormat = true;
}
- #ifdef DEBUG
- CHAR cDate[7];
- memcpy(cDate, lpStream + dwChunkPos, 6);
- cDate[6] = 0;
- sComment += " - Build Date: ";
- sComment += cDate;
- if(bNewFormat) sComment += " (New Format)";
- else sComment += " (Old Format)";
- #endif
break;
case 0x484C504F: // "OPLH" - Order list, channel + module settings
@@ -215,6 +227,8 @@
// Now, the interesting part begins!
DWORD dwSettingsOffset = dwChunkPos + 2;
WORD nChunkCount = 0, nFirstOrderChunk = (WORD)-1;
+
+ // "Sub sub sub chunks" (grrrr, silly format)
while(dwSettingsOffset - dwChunkPos + 1 < subChunkSize)
{
switch(lpStream[dwSettingsOffset])
@@ -226,57 +240,62 @@
case 0x01: // Order list item
if(dwSettingsOffset - dwChunkPos + 5 > subChunkSize) return false;
// Pattern name follows - find pattern (this is the orderlist)
- for(PATTERNINDEX i = 0; i < patternIDs.size(); i++)
{
- char patternID[4];
+ char patternID[4]; // temporary
memcpy(patternID, lpStream + dwSettingsOffset + 2 + (bNewFormat ? 3 : 0), 3);
patternID[3] = 0;
DWORD nPattern = atoi(patternID);
- if(patternIDs[i] == nPattern)
+
+ // seek which pattern has this ID
+ for(uint32 i = 0; i < patternIDs.size(); i++)
{
- Order.push_back(i);
- break;
+ if(patternIDs[i] == nPattern)
+ {
+ // found the right pattern, copy offset + start / end positions.
+ if(subsong.startOrder == ORDERINDEX_INVALID)
+ subsong.startOrder = (ORDERINDEX)orderOffsets.size();
+ subsong.endOrder = (ORDERINDEX)orderOffsets.size();
+
+ // every pattern in the order will be unique, so store the pointer + pattern ID
+ orderOffsets.push_back(patternOffsets[i]);
+ Order.push_back(numPatterns);
+ numPatterns++;
+ break;
+ }
}
}
+ // decide whether this is the first order chunk or not (for finding out the correct restart position)
if(nFirstOrderChunk == (WORD)-1) nFirstOrderChunk = nChunkCount;
dwSettingsOffset += 5 + (bNewFormat ? 4 : 0);
break;
case 0x04: // Restart position
{
- // NOTE: This should not be global! (Extreme Pinball!!!)
WORD nRestartChunk = LittleEndian(*(WORD *)(lpStream + dwSettingsOffset + 1));
ORDERINDEX nRestartPosition = 0;
- if(nRestartChunk == 0) nRestartPosition = 0;
- else if(nRestartChunk >= nFirstOrderChunk) nRestartPosition = (ORDERINDEX)(nRestartChunk - nFirstOrderChunk);
- #ifdef DEBUG
- {
- char s[32];
- wsprintf(s, " - restart pos %d", nRestartPosition);
- sComment += s;
- }
- #endif
+ if(nRestartChunk >= nFirstOrderChunk) nRestartPosition = (ORDERINDEX)(nRestartChunk - nFirstOrderChunk);
+ subsong.restartPos += nRestartPosition;
+ m_nRestartPos = subsong.restartPos;
}
dwSettingsOffset += 3;
break;
case 0x07: // Default Speed
if(dwSettingsOffset - dwChunkPos + 2 > subChunkSize) break;
- // Same note as above!
- m_nDefaultSpeed = lpStream[dwSettingsOffset + 1];
+ m_nDefaultSpeed = subsong.defaultSpeed = lpStream[dwSettingsOffset + 1];
dwSettingsOffset += 2;
break;
case 0x08: // Default Tempo
if(dwSettingsOffset - dwChunkPos + 2 > subChunkSize) break;
- // Same note as above!
- m_nDefaultTempo = lpStream[dwSettingsOffset + 1];
+ m_nDefaultTempo = subsong.defaultTempo = lpStream[dwSettingsOffset + 1];
dwSettingsOffset += 2;
break;
case 0x0C: // Sample map table (???)
if(dwSettingsOffset - dwChunkPos + 7 > subChunkSize) break;
+ // Never seems to be different, so...
if (lpStream[dwSettingsOffset + 1] != 0x00 || lpStream[dwSettingsOffset + 2] != 0xFF ||
lpStream[dwSettingsOffset + 3] != 0x00 || lpStream[dwSettingsOffset + 4] != 0x00 ||
lpStream[dwSettingsOffset + 5] != 0x01 || lpStream[dwSettingsOffset + 6] != 0x00)
@@ -287,31 +306,44 @@
case 0x0D: // Channel panning table
if(dwSettingsOffset - dwChunkPos + 4 > subChunkSize) break;
+ if(lpStream[dwSettingsOffset + 1] < MAX_BASECHANNELS)
{
- CHANNELINDEX nChn = min(lpStream[dwSettingsOffset + 1], pSong->numChannels);
+ CHANNELINDEX nChn = lpStream[dwSettingsOffset + 1];
switch(lpStream[dwSettingsOffset + 3])
{
- case 0:
- ChnSettings[nChn].nPan = lpStream[dwSettingsOffset + 2] ^ 128;
+ case 0: // use panning
+ ChnSettings[nChn].nPan = subsong.channelPanning[nChn] = lpStream[dwSettingsOffset + 2] ^ 128;
+ ChnSettings[nChn].dwFlags &= ~CHN_SURROUND;
+ subsong.channelSurround[nChn] = false;
break;
- case 2:
- ChnSettings[nChn].nPan = 128;
+ case 2: // surround
+ ChnSettings[nChn].nPan = subsong.channelPanning[nChn] = 128;
ChnSettings[nChn].dwFlags |= CHN_SURROUND;
+ subsong.channelSurround[nChn] = true;
break;
- case 4:
- ChnSettings[nChn].nPan = 128;
+ case 4: // center
+ ChnSettings[nChn].nPan = subsong.channelPanning[nChn] = 128;
+ ChnSettings[nChn].dwFlags &= ~CHN_SURROUND;
+ subsong.channelSurround[nChn] = false;
break;
}
+ if(bSubsongPanningDiffers == false && subsongs.size() > 0)
+ {
+ if(subsongs.back().channelPanning[nChn] != subsong.channelPanning[nChn]
+ || subsongs.back().channelSurround[nChn] != subsong.channelSurround[nChn])
+ bSubsongPanningDiffers = true;
+ }
}
dwSettingsOffset += 4;
break;
- case 0x0E: // Channel volume table
+ case 0x0E: // Channel volume table (0...255)
if(dwSettingsOffset - dwChunkPos + 3 > subChunkSize) break;
- ChnSettings[min(lpStream[dwSettingsOffset + 1], pSong->numChannels)].nVolume = (lpStream[dwSettingsOffset + 2] >> 2) + 1;
+ if(lpStream[dwSettingsOffset + 1] < MAX_BASECHANNELS)
+ ChnSettings[lpStream[dwSettingsOffset + 1]].nVolume = subsong.channelVolume[lpStream[dwSettingsOffset + 1]] = (lpStream[dwSettingsOffset + 2] >> 2) + 1;
dwSettingsOffset += 3;
break;
@@ -320,12 +352,15 @@
CString s;
s.Format("Please report to the OpenMPT team: Unknown chunk %d found at position %d (in the OPLH chunk of this PSM file)", lpStream[dwSettingsOffset], dwSettingsOffset);
MessageBox(NULL, s, TEXT("OpenMPT PSM import"), MB_ICONERROR);
+ // anyway, in such cases, we have to quit as we don't know how big the chunk really is.
return false;
break;
}
nChunkCount++;
}
+ // separate subsongs by "---" patterns
+ orderOffsets.push_back(nullptr);
Order.push_back(Order.GetInvalidPatIndex());
}
break;
@@ -334,20 +369,26 @@
if(subChunkSize & 1) return false;
for(DWORD i = 0; i < subChunkSize; i += 2)
{
- if((i >> 1) >= m_nChannels) break;
+ CHANNELINDEX nChn = (CHANNELINDEX)(i >> 1);
+ if(nChn >= m_nChannels) break;
switch(lpStream[dwChunkPos + i])
{
- case 0:
- ChnSettings[i >> 1].nPan = lpStream[dwChunkPos + i + 1] ^ 128;
+ case 0: // use panning
+ ChnSettings[nChn].nPan = subsong.channelPanning[nChn] = lpStream[dwChunkPos + i + 1] ^ 128;
+ ChnSettings[nChn].dwFlags &= ~CHN_SURROUND;
+ subsong.channelSurround[nChn] = false;
break;
- case 2:
- ChnSettings[i >> 1].nPan = 128;
- ChnSettings[i >> 1].dwFlags |= CHN_SURROUND;
+ case 2: // surround
+ ChnSettings[nChn].nPan = subsong.channelPanning[nChn] = 128;
+ ChnSettings[nChn].dwFlags |= CHN_SURROUND;
+ subsong.channelSurround[nChn] = true;
break;
- case 4:
- ChnSettings[i >> 1].nPan = 128;
+ case 4: // center
+ ChnSettings[nChn].nPan = subsong.channelPanning[nChn] = 128;
+ ChnSettings[nChn].dwFlags &= ~CHN_SURROUND;
+ subsong.channelSurround[nChn] = false;
break;
}
}
@@ -368,6 +409,9 @@
dwChunkPos += subChunkSize;
}
+
+ // attach this subsong to the subsong list - finally, all "sub sub sub ..." chunks are parsed.
+ subsongs.push_back(subsong);
}
break;
@@ -375,6 +419,7 @@
case 0x504D5344: // DSMP - Samples
if(!bNewFormat)
{
+ // original header
if(chunkSize < sizeof(PSMOLDSAMPLEHEADER)) return false;
PSMOLDSAMPLEHEADER *pSample = (PSMOLDSAMPLEHEADER *)(lpStream + dwMemPos);
SAMPLEINDEX smp = (SAMPLEINDEX)(LittleEndianW(pSample->sampleNumber) + 1);
@@ -434,10 +479,14 @@
if(m_nChannels == 0)
return false;
+
// Now that we know the number of channels, we can go through all the patterns.
- for(PATTERNINDEX nPat = 0; nPat < numPatterns; nPat++)
+ // This is a bit stupid since we will even read duplicate patterns twice, but hey, we do this just once... so who cares?
+ PATTERNINDEX nPat = 0;
+ for(ORDERINDEX nOrd = 0; nOrd < Order.size(); nOrd++)
{
- DWORD dwPatternOffset = patternOffsets[nPat];
+ if(orderOffsets[nOrd] == nullptr) continue;
+ DWORD dwPatternOffset = orderOffsets[nOrd];
if(dwPatternOffset + 2 > dwMemLength) return false;
WORD patternSize = LittleEndianW(*(WORD *)(lpStream + dwPatternOffset));
dwPatternOffset += 2;
@@ -659,11 +708,7 @@
break;
default:
- #ifdef DEBUG
- ASSERT(false);
- #else
command = CMD_NONE;
- #endif
break;
}
@@ -679,17 +724,52 @@
row_data += m_nChannels;
dwPatternOffset += rowSize;
}
-
+ nPat++;
}
- if(!sComment.empty())
+ // write subsong "configuration" to patterns
+ for(uint32 i = 0; i < subsongs.size(); i++)
{
- m_lpszSongComments = new char[sComment.length() + 1];
- if (m_lpszSongComments)
+ PATTERNINDEX startPattern = Order[subsongs[i].startOrder], endPattern = Order[subsongs[i].endOrder];
+ if(startPattern == PATTERNINDEX_INVALID || endPattern == PATTERNINDEX_INVALID) continue; // what, invalid subtune?
+
+ // set the subsong name to all pattern names
+ for(PATTERNINDEX nPat = startPattern; nPat <= endPattern; nPat++)
{
- memset(m_lpszSongComments, 0, sComment.length() + 1);
- memcpy(m_lpszSongComments, sComment.c_str(), sComment.length());
+ SetPatternName(nPat, subsongs[i].songName);
}
+
+ // subsongs with different panning setup -> write to pattern (MUSIC_C.PSM)
+ if(bSubsongPanningDiffers)
+ {
+ for(CHANNELINDEX nChn = 0; nChn < m_nChannels; nChn++)
+ {
+ if(subsongs[i].channelSurround[nChn] == true)
+ TryWriteEffect(startPattern, 0, CMD_S3MCMDEX, 0x91, false, nChn, false, true);
+ else
+ TryWriteEffect(startPattern, 0, CMD_PANNING8, subsongs[i].channelPanning[nChn], false, nChn, false, true);
+ }
+ }
+ // write default tempo/speed to pattern
+ TryWriteEffect(startPattern, 0, CMD_SPEED, subsongs[i].defaultSpeed, false, CHANNELINDEX_INVALID, false, true);
+ TryWriteEffect(startPattern, 0, CMD_TEMPO, subsongs[i].defaultTempo, false, CHANNELINDEX_INVALID, false, true);
+
+ // don't write channel volume for now, as it's always set to 100% anyway
+
+ // there's a restart pos, so let's try to insert a Bxx command in the last pattern
+ if(subsongs[i].restartPos != ORDERINDEX_INVALID)
+ {
+ ROWINDEX lastRow = Patterns[endPattern].GetNumRows() - 1;
+ MODCOMMAND *row_data;
+ row_data = Patterns[endPattern];
+ for(uint32 nCell = 0; nCell < m_nChannels * Patterns[endPattern].GetNumRows(); nCell++)
+ {
+ if(row_data->command == CMD_PATTERNBREAK || row_data->command == CMD_POSITIONJUMP)
+ lastRow = nCell / m_nChannels;
+ row_data++;
+ }
+ TryWriteEffect(endPattern, lastRow, CMD_POSITIONJUMP, (BYTE)subsongs[i].restartPos, false, CHANNELINDEX_INVALID, false, true);
+ }
}
return true;
Modified: trunk/OpenMPT/soundlib/Sndfile.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-08-26 22:04:14 UTC (rev 345)
+++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-08-29 00:40:26 UTC (rev 346)
@@ -3119,7 +3119,7 @@
if(m_nType & MOD_TYPE_S3M && nParam > 0x80)
break;
- m->volcmd = VOLCMD_VOLUME;
+ m->volcmd = VOLCMD_PANNING;
m->command = nEffect;
if(m_nType & MOD_TYPE_S3M)
Modified: trunk/OpenMPT/soundlib/Sndmix.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndmix.cpp 2009-08-26 22:04:14 UTC (rev 345)
+++ trunk/OpenMPT/soundlib/Sndmix.cpp 2009-08-29 00:40:26 UTC (rev 346)
@@ -1445,6 +1445,7 @@
pdelta += pChn->nRealPan;
pChn->nRealPan = CLAMP(pdelta, 0, 256);
+ if(IsCompatibleMode(TRK_IMPULSETRACKER)) pChn->nPan = pChn->nRealPan;
}
int nPeriodFrac = 0;
// Instrument Auto-Vibrato
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-08-26 22:04:33
|
Revision: 345
http://modplug.svn.sourceforge.net/modplug/?rev=345&view=rev
Author: saga-games
Date: 2009-08-26 22:04:14 +0000 (Wed, 26 Aug 2009)
Log Message:
-----------
[Imp] IT Compatibility: More improvements to Vibrato, Tremolo and Panbrello. Using the tables from IT_TECH.TXT.
Modified Paths:
--------------
trunk/OpenMPT/soundlib/Snd_fx.cpp
trunk/OpenMPT/soundlib/Sndmix.cpp
trunk/OpenMPT/soundlib/Tables.cpp
Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-08-26 20:40:27 UTC (rev 344)
+++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-08-26 22:04:14 UTC (rev 345)
@@ -717,7 +717,7 @@
}
pChn->nPos = 0;
pChn->nPosLo = 0;
- if (pChn->nVibratoType < 4) pChn->nVibratoPos = ((m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT)) && (!(m_dwSongFlags & SONG_ITOLDEFFECTS))) ? 0x10 : 0;
+ if (pChn->nVibratoType < 4) pChn->nVibratoPos = ((!IsCompatibleMode(TRK_IMPULSETRACKER)) && (m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT)) && (!(m_dwSongFlags & SONG_ITOLDEFFECTS))) ? 0x10 : 0;
if(!IsCompatibleMode(TRK_IMPULSETRACKER) && pChn->nTremoloType < 4) pChn->nTremoloPos = 0;
}
if (pChn->nPos >= pChn->nLength) pChn->nPos = pChn->nLoopStart;
@@ -1859,6 +1859,7 @@
// IMF Commands
case CMD_NOTESLIDEUP:
NoteSlide(pChn, param, 1);
+ break;
case CMD_NOTESLIDEDOWN:
NoteSlide(pChn, param, -1);
break;
Modified: trunk/OpenMPT/soundlib/Sndmix.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndmix.cpp 2009-08-26 20:40:27 UTC (rev 344)
+++ trunk/OpenMPT/soundlib/Sndmix.cpp 2009-08-26 22:04:14 UTC (rev 345)
@@ -985,10 +985,10 @@
// Tremolo
if (pChn->dwFlags & CHN_TREMOLO)
{
- UINT trempos = pChn->nTremoloPos & 0x3F;
+ UINT trempos = pChn->nTremoloPos;
if (vol > 0 || IsCompatibleMode(TRK_IMPULSETRACKER))
{
- int tremattn = (m_nType & MOD_TYPE_XM) ? 5 : 6;
+ const int tremattn = (m_nType & MOD_TYPE_XM || IsCompatibleMode(TRK_IMPULSETRACKER)) ? 5 : 6;
switch (pChn->nTremoloType & 0x03)
{
case 1:
@@ -1000,7 +1000,7 @@
case 3:
//IT compatibility 19. Use random values
if(IsCompatibleMode(TRK_IMPULSETRACKER))
- vol += (((rand() & 0xFF) - 0x7F) * (int)pChn->nTremoloDepth) >> tremattn;
+ vol += (((rand() & 0x7F) - 0x40) * (int)pChn->nTremoloDepth) >> tremattn;
else
vol += (ModRandomTable[trempos] * (int)pChn->nTremoloDepth) >> tremattn;
break;
@@ -1010,7 +1010,10 @@
}
if ((m_nTickCount) || ((m_nType & (MOD_TYPE_STM|MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_MPT)) && (!(m_dwSongFlags & SONG_ITOLDEFFECTS))))
{
- pChn->nTremoloPos = (pChn->nTremoloPos + pChn->nTremoloSpeed) & 0x3F;
+ if(IsCompatibleMode(TRK_IMPULSETRACKER))
+ pChn->nTremoloPos = (pChn->nTremoloPos + 4 * pChn->nTremoloSpeed) & 0xFF;
+ else
+ pChn->nTremoloPos = (pChn->nTremoloPos + pChn->nTremoloSpeed) & 0x3F;
}
}
@@ -1340,20 +1343,20 @@
switch (pChn->nVibratoType & 0x03)
{
case 1:
- vdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITRampDownTable[(vibpos + 48) % 64] : ModRampDownTable[vibpos];
+ vdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITRampDownTable[vibpos] : ModRampDownTable[vibpos];
break;
case 2:
- vdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSquareTable[(vibpos + 48) % 64] : ModSquareTable[vibpos];
+ vdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSquareTable[vibpos] : ModSquareTable[vibpos];
break;
case 3:
//IT compatibility 19. Use random values
if(IsCompatibleMode(TRK_IMPULSETRACKER))
- vdelta = (rand() & 0xFF) - 0x7F;
+ vdelta = (rand() & 0x7F) - 0x40;
else
vdelta = ModRandomTable[vibpos];
break;
default:
- vdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSinusTable[(vibpos + 48) % 64] : ModSinusTable[vibpos];
+ vdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSinusTable[vibpos] : ModSinusTable[vibpos];
}
if(m_nType == MOD_TYPE_MPT && pChn->pModInstrument && pChn->pModInstrument->pTuning)
@@ -1369,7 +1372,22 @@
}
else //Original behavior
{
- UINT vdepth = ((!(m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT))) || (m_dwSongFlags & SONG_ITOLDEFFECTS)) ? 6 : 7;
+ UINT vdepth;
+ if(IsCompatibleMode(TRK_IMPULSETRACKER))
+ {
+ if(m_dwSongFlags & SONG_ITOLDEFFECTS)
+ {
+ vdepth = 5;
+ vdelta = -vdelta;
+ } else
+ {
+ vdepth = 6;
+ }
+ }
+ else
+ {
+ vdepth = ((!(m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT))) || (m_dwSongFlags & SONG_ITOLDEFFECTS)) ? 6 : 7;
+ }
vdelta = (vdelta * (int)pChn->nVibratoDepth) >> vdepth;
if ((m_dwSongFlags & SONG_LINEARSLIDES) && (m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT)))
{
@@ -1385,20 +1403,24 @@
if (l & 0x03) vdelta += _muldiv(period, FineLinearSlideUpTable[l & 0x03], 0x10000) - period;
}
}
- if(IsCompatibleMode(TRK_ALLTRACKERS))
- period -= vdelta;
- else
- period += vdelta;
+ period += vdelta;
}
if ((m_nTickCount) || ((m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT)) && (!(m_dwSongFlags & SONG_ITOLDEFFECTS))))
{
- pChn->nVibratoPos = (pChn->nVibratoPos + pChn->nVibratoSpeed) & 0x3F;
+ if(IsCompatibleMode(TRK_IMPULSETRACKER))
+ pChn->nVibratoPos = (vibpos + 4 * pChn->nVibratoSpeed) & 0xFF;
+ else
+ pChn->nVibratoPos = (vibpos + pChn->nVibratoSpeed) & 0x3F;
}
}
// Panbrello
if (pChn->dwFlags & CHN_PANBRELLO)
{
- UINT panpos = ((pChn->nPanbrelloPos+0x10) >> 2) & 0x3F;
+ UINT panpos;
+ if(IsCompatibleMode(TRK_IMPULSETRACKER))
+ panpos = pChn->nPanbrelloPos & 0xFF;
+ else
+ panpos = ((pChn->nPanbrelloPos + 0x10) >> 2) & 0x3F;
LONG pdelta;
switch (pChn->nPanbrelloType & 0x03)
{
@@ -1411,7 +1433,7 @@
case 3:
//IT compatibility 19. Use random values
if(IsCompatibleMode(TRK_IMPULSETRACKER))
- pdelta = (rand() & 0xFF) - 0x7F;
+ pdelta = (rand() & 0x7f) - 0x40;
else
pdelta = ModRandomTable[panpos];
break;
@@ -1419,7 +1441,7 @@
pdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSinusTable[panpos] : ModSinusTable[panpos];
}
pChn->nPanbrelloPos += pChn->nPanbrelloSpeed;
- pdelta = ((pdelta * (int)pChn->nPanbrelloDepth) + 2) >> (IsCompatibleMode(TRK_IMPULSETRACKER) ? 4 : 3);
+ pdelta = ((pdelta * (int)pChn->nPanbrelloDepth) + 2) >> 3;
pdelta += pChn->nRealPan;
pChn->nRealPan = CLAMP(pdelta, 0, 256);
Modified: trunk/OpenMPT/soundlib/Tables.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Tables.cpp 2009-08-26 20:40:27 UTC (rev 344)
+++ trunk/OpenMPT/soundlib/Tables.cpp 2009-08-26 22:04:14 UTC (rev 345)
@@ -154,33 +154,69 @@
42,-34,89,-4,-51,-72,21,-29,112,123,84,-101,-92,98,-54,-95
};
-// Impulse Tracker tables
+// Impulse Tracker tables (ITTECH.TXT)
// Sinus table
-short int ITSinusTable[64] =
+short int ITSinusTable[256] =
{
- 0,12,25,37,49,60,71,81,90,98,106,112,117,122,125,126,
- 127,126,125,122,117,112,106,98,90,81,71,60,49,37,25,12,
- 0,-12,-25,-37,-49,-60,-71,-81,-90,-98,-106,-112,-117,-122,-125,-126,
- -127,-126,-125,-122,-117,-112,-106,-98,-90,-81,-71,-60,-49,-37,-25,-12
+ 0, 2, 3, 5, 6, 8, 9, 11, 12, 14, 16, 17, 19, 20, 22, 23,
+ 24, 26, 27, 29, 30, 32, 33, 34, 36, 37, 38, 39, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59,
+ 59, 60, 60, 61, 61, 62, 62, 62, 63, 63, 63, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 63, 63, 63, 62, 62, 62, 61, 61, 60, 60,
+ 59, 59, 58, 57, 56, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46,
+ 45, 44, 43, 42, 41, 39, 38, 37, 36, 34, 33, 32, 30, 29, 27, 26,
+ 24, 23, 22, 20, 19, 17, 16, 14, 12, 11, 9, 8, 6, 5, 3, 2,
+ 0, -2, -3, -5, -6, -8, -9,-11,-12,-14,-16,-17,-19,-20,-22,-23,
+ -24,-26,-27,-29,-30,-32,-33,-34,-36,-37,-38,-39,-41,-42,-43,-44,
+ -45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-56,-57,-58,-59,
+ -59,-60,-60,-61,-61,-62,-62,-62,-63,-63,-63,-64,-64,-64,-64,-64,
+ -64,-64,-64,-64,-64,-64,-63,-63,-63,-62,-62,-62,-61,-61,-60,-60,
+ -59,-59,-58,-57,-56,-56,-55,-54,-53,-52,-51,-50,-49,-48,-47,-46,
+ -45,-44,-43,-42,-41,-39,-38,-37,-36,-34,-33,-32,-30,-29,-27,-26,
+ -24,-23,-22,-20,-19,-17,-16,-14,-12,-11, -9, -8, -6, -5, -3, -2,
};
// Triangle wave table (ramp down)
-short int ITRampDownTable[64] =
+short int ITRampDownTable[256] =
{
- 127,123,119,115,111,107,103,99,95,91,87,83,79,75,71,67,
- 63,59,55,51,47,43,39,35,31,27,23,19,15,11,7,3,
- 0,-4,-8,-12,-16,-20,-24,-28,-32,-36,-40,-44,-48,-52,-56,-60,
- -64,-68,-72,-76,-80,-84,-88,-92,-96,-100,-104,-108,-112,-116,-120,-124
+ 64, 63, 63, 62, 62, 61, 61, 60, 60, 59, 59, 58, 58, 57, 57, 56,
+ 56, 55, 55, 54, 54, 53, 53, 52, 52, 51, 51, 50, 50, 49, 49, 48,
+ 48, 47, 47, 46, 46, 45, 45, 44, 44, 43, 43, 42, 42, 41, 41, 40,
+ 40, 39, 39, 38, 38, 37, 37, 36, 36, 35, 35, 34, 34, 33, 33, 32,
+ 32, 31, 31, 30, 30, 29, 29, 28, 28, 27, 27, 26, 26, 25, 25, 24,
+ 24, 23, 23, 22, 22, 21, 21, 20, 20, 19, 19, 18, 18, 17, 17, 16,
+ 16, 15, 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8,
+ 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0,
+ 0, -1, -1, -2, -2, -3, -3, -4, -4, -5, -5, -6, -6, -7, -7, -8,
+ -8, -9, -9,-10,-10,-11,-11,-12,-12,-13,-13,-14,-14,-15,-15,-16,
+ -16,-17,-17,-18,-18,-19,-19,-20,-20,-21,-21,-22,-22,-23,-23,-24,
+ -24,-25,-25,-26,-26,-27,-27,-28,-28,-29,-29,-30,-30,-31,-31,-32,
+ -32,-33,-33,-34,-34,-35,-35,-36,-36,-37,-37,-38,-38,-39,-39,-40,
+ -40,-41,-41,-42,-42,-43,-43,-44,-44,-45,-45,-46,-46,-47,-47,-48,
+ -48,-49,-49,-50,-50,-51,-51,-52,-52,-53,-53,-54,-54,-55,-55,-56,
+ -56,-57,-57,-58,-58,-59,-59,-60,-60,-61,-61,-62,-62,-63,-63,-64,
};
// Square wave table
-short int ITSquareTable[64] =
+short int ITSquareTable[256] =
{
- 127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
- 127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
// volume fade tables for Retrig Note:
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2009-08-26 20:40:41
|
Revision: 344
http://modplug.svn.sourceforge.net/modplug/?rev=344&view=rev
Author: relabsoluness
Date: 2009-08-26 20:40:27 +0000 (Wed, 26 Aug 2009)
Log Message:
-----------
[New] MIDI mapping: Editing a plug param in its editor while holding shift key will now open MIDI mapping dialog.
[Fix] MIDI mapping: Some minor tweaks and fixes to the MIDI mapping dialog.
[Fix] Pattern tab: Fixed possible crash occurring if echo pattern in echo paste doesn't exist.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/MIDIMappingDialog.cpp
trunk/OpenMPT/mptrack/MIDIMappingDialog.h
trunk/OpenMPT/mptrack/Modedit.cpp
trunk/OpenMPT/mptrack/Mpt_midi.cpp
trunk/OpenMPT/mptrack/View_pat.cpp
trunk/OpenMPT/mptrack/Vstplug.cpp
trunk/OpenMPT/soundlib/midi.h
trunk/OpenMPT/soundlib/patternContainer.h
Modified: trunk/OpenMPT/mptrack/MIDIMappingDialog.cpp
===================================================================
--- trunk/OpenMPT/mptrack/MIDIMappingDialog.cpp 2009-08-25 20:14:24 UTC (rev 343)
+++ trunk/OpenMPT/mptrack/MIDIMappingDialog.cpp 2009-08-26 20:40:27 UTC (rev 344)
@@ -65,6 +65,7 @@
m_ChannelCBox.SetCurSel(1+GetFromMIDIMsg_Channel(dwMidiDataParam));
m_EventCBox.SetCurSel(0);
m_ControllerCBox.SetCurSel(GetFromMIDIMsg_DataByte1(dwMidiDataParam));
+ OnCbnSelchangeComboChannel();
OnCbnSelchangeComboEvent();
OnCbnSelchangeComboController();
UpdateString();
@@ -78,16 +79,6 @@
{
CDialog::OnInitDialog();
- if (m_rMIDIMapper.GetCount() > 0)
- m_Setting = m_rMIDIMapper.GetDirective(0);
-
- m_ChannelCBox.SetCurSel(m_Setting.GetChannel());
-
- CheckDlgButton(IDC_CHECKACTIVE, m_Setting.IsActive() ? BST_CHECKED : BST_UNCHECKED);
- CheckDlgButton(IDC_CHECKCAPTURE, m_Setting.GetCaptureMIDI() ? BST_CHECKED : BST_UNCHECKED);
- GetDlgItem(IDC_CHECK_PATRECORD)->ShowWindow((m_rSndFile.GetType() == MOD_TYPE_MPT) ? SW_SHOW : SW_HIDE);
- CheckDlgButton(IDC_CHECK_PATRECORD, m_Setting.GetAllowPatternEdit() ? BST_CHECKED : BST_UNCHECKED);
-
m_EventCBox.SetCurSel(0);
//Add controller names.
@@ -97,14 +88,13 @@
temp.Format("%3d %s", i, MidiCCNames[i]);
m_ControllerCBox.AddString(temp);
}
- m_ControllerCBox.SetCurSel(m_Setting.GetController());
//Add Pluginnames
AddPluginNamesToCombobox(m_PluginCBox, m_rSndFile.m_MixPlugins);
m_PluginCBox.SetCurSel(m_Setting.GetPlugIndex()-1);
//Add plugin parameter names
- AddPluginParameternamesToCombobox(m_PlugParamCBox, m_rSndFile.m_MixPlugins[0]);
+ AddPluginParameternamesToCombobox(m_PlugParamCBox, m_rSndFile.m_MixPlugins[(m_Setting.GetPlugIndex() <= MAX_MIXPLUGINS) ? m_Setting.GetPlugIndex() - 1 : 0]);
m_PlugParamCBox.SetCurSel(m_Setting.GetParamIndex());
//Add directives to list.
@@ -113,16 +103,26 @@
{
m_List.AddString(CreateListString(*iter));
}
- if(m_rMIDIMapper.GetCount() > 0)
+ if(m_rMIDIMapper.GetCount() > 0 && m_Setting.IsDefault())
{
m_List.SetCurSel(0);
OnLbnSelchangeList1();
- m_Setting = m_rMIDIMapper.GetDirective(0);
}
+ else
+ {
+ m_ChannelCBox.SetCurSel(m_Setting.GetChannel());
+ m_ControllerCBox.SetCurSel(m_Setting.GetController());
+ CheckDlgButton(IDC_CHECKACTIVE, m_Setting.IsActive() ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(IDC_CHECKCAPTURE, m_Setting.GetCaptureMIDI() ? BST_CHECKED : BST_UNCHECKED);
+ GetDlgItem(IDC_CHECK_PATRECORD)->ShowWindow((m_rSndFile.GetType() == MOD_TYPE_MPT) ? SW_SHOW : SW_HIDE);
+ CheckDlgButton(IDC_CHECK_PATRECORD, m_Setting.GetAllowPatternEdit() ? BST_CHECKED : BST_UNCHECKED);
+ }
UpdateString();
CMainFrame::GetMainFrame()->SetMidiRecordWnd(GetSafeHwnd());
+
+ CheckDlgButton(IDC_CHECK_MIDILEARN, BST_CHECKED);
return TRUE; // return TRUE unless you set the focus to a control
}
Modified: trunk/OpenMPT/mptrack/MIDIMappingDialog.h
===================================================================
--- trunk/OpenMPT/mptrack/MIDIMappingDialog.h 2009-08-25 20:14:24 UTC (rev 343)
+++ trunk/OpenMPT/mptrack/MIDIMappingDialog.h 2009-08-26 20:40:27 UTC (rev 344)
@@ -21,6 +21,8 @@
// Dialog Data
enum { IDD = IDD_MIDIPARAMCONTROL };
+ CMIDIMappingDirective m_Setting;
+
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
@@ -49,7 +51,7 @@
CSpinButtonCtrl m_SpinMoveMapping;
- CMIDIMappingDirective m_Setting;
+
public:
afx_msg void OnLbnSelchangeList1();
Modified: trunk/OpenMPT/mptrack/Modedit.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-25 20:14:24 UTC (rev 343)
+++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-26 20:40:27 UTC (rev 344)
@@ -2304,7 +2304,7 @@
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;
+ if(m_SndFile.Patterns.IsValidPat(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/Mpt_midi.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Mpt_midi.cpp 2009-08-25 20:14:24 UTC (rev 343)
+++ trunk/OpenMPT/mptrack/Mpt_midi.cpp 2009-08-26 20:40:27 UTC (rev 344)
@@ -165,6 +165,20 @@
//----------------------------------------------------------------------------
+CString CMIDIMappingDirective::ToString() const
+//---------------------------------------------
+{
+ CString str; str.Preallocate(20);
+ char flags[4] = "000";
+ if(m_Active) flags[0] = '1';
+ if(m_CaptureMIDI) flags[1] = '1';
+ if(m_AllowPatternEdit) flags[2] = '1';
+ str.Format("%s:%d:%x:%d:%d:%d", flags, (int)GetChannel(), (int)GetEvent(), (int)GetController(), (int)m_PluginIndex, m_Parameter);
+ str.Trim();
+ return str;
+}
+
+
size_t CMIDIMapper::GetSerializationSize() const
//---------------------------------------------
{
Modified: trunk/OpenMPT/mptrack/View_pat.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_pat.cpp 2009-08-25 20:14:24 UTC (rev 343)
+++ trunk/OpenMPT/mptrack/View_pat.cpp 2009-08-26 20:40:27 UTC (rev 344)
@@ -3018,7 +3018,7 @@
//--------------------------------------------------------------------------------
{
static MODCOMMAND m;
- if (rSf.Patterns.IsValidIndex(pos.nPat) && pos.nRow < rSf.Patterns[pos.nPat].GetNumRows() && pos.nChn < rSf.GetNumChannels())
+ if (rSf.Patterns.IsValidPat(pos.nPat) && pos.nRow < rSf.Patterns[pos.nPat].GetNumRows() && pos.nChn < rSf.GetNumChannels())
return rSf.Patterns[pos.nPat].GetpModCommand(pos.nRow, pos.nChn);
else
return &m;
@@ -5125,7 +5125,7 @@
const ROWINDEX iRowCandidate, const PATTERNINDEX iPatCandidate) const
//-------------------------------------------------------------------------------------------
{
- if(rSndFile.Patterns.IsValidIndex(iPatCandidate) && rSndFile.Patterns[iPatCandidate].IsValidRow(iRowCandidate))
+ if(rSndFile.Patterns.IsValidPat(iPatCandidate) && rSndFile.Patterns[iPatCandidate].IsValidRow(iRowCandidate))
{ // Case: Edit position candidates are valid -- use them.
iPat = iPatCandidate;
iRow = iRowCandidate;
Modified: trunk/OpenMPT/mptrack/Vstplug.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Vstplug.cpp 2009-08-25 20:14:24 UTC (rev 343)
+++ trunk/OpenMPT/mptrack/Vstplug.cpp 2009-08-26 20:40:27 UTC (rev 344)
@@ -14,6 +14,7 @@
#include "defaultvsteditor.h" //rewbs.defaultPlugGUI
#include "midi.h"
#include "version.h"
+#include "midimappingdialog.h"
#ifdef VST_USE_ALTERNATIVE_MAGIC //Pelya's plugin ID fix. Breaks fx presets, so let's avoid it for now.
#include "Unzip32.h" //For CRC calculation (to detect plugins with same UID)
#endif
@@ -677,6 +678,18 @@
pModDoc->RecordParamChange(pVstPlugin->GetSlot(), index);
}
+ if (CMainFrame::GetInputHandler()->ShiftPressed())
+ {
+ CMainFrame::GetInputHandler()->SetModifierMask(0); // Make sure that the dialog will open only once.
+ CAbstractVstEditor *pVstEditor = pVstPlugin->GetEditor();
+ const HWND oldMIDIRecondWnd = CMainFrame::GetMainFrame()->GetMidiRecordWnd();
+ CMIDIMappingDialog dlg(pVstEditor, *pModDoc->GetSoundFile());
+ dlg.m_Setting.SetParamIndex(index);
+ dlg.m_Setting.SetPlugIndex(pVstPlugin->GetSlot()+1);
+ dlg.DoModal();
+ CMainFrame::GetMainFrame()->SetMidiRecordWnd(oldMIDIRecondWnd);
+ }
+
// Learn macro
CAbstractVstEditor *pVstEditor = pVstPlugin->GetEditor();
if (pVstEditor) {
Modified: trunk/OpenMPT/soundlib/midi.h
===================================================================
--- trunk/OpenMPT/soundlib/midi.h 2009-08-25 20:14:24 UTC (rev 343)
+++ trunk/OpenMPT/soundlib/midi.h 2009-08-26 20:40:27 UTC (rev 344)
@@ -63,20 +63,12 @@
void SetParamIndex(const int i) {m_Parameter = i;}
uint32 GetParamIndex() const {return m_Parameter;}
- bool operator==(const CMIDIMappingDirective& d) {return memcmp(this, &d, sizeof(CMIDIMappingDirective)) == 0;}
+ bool IsDefault() const {return *this == CMIDIMappingDirective();}
- CString ToString() const
- {
- CString str; str.Preallocate(20);
- char flags[4] = "000";
- if(m_Active) flags[0] = '1';
- if(m_CaptureMIDI) flags[1] = '1';
- if(m_AllowPatternEdit) flags[2] = '1';
- str.Format("%s:%d:%x:%d:%d:%d", flags, (int)GetChannel(), (int)GetEvent(), (int)GetController(), (int)m_PluginIndex, m_Parameter);
- str.Trim();
- return str;
- }
+ bool operator==(const CMIDIMappingDirective& d) const {return memcmp(this, &d, sizeof(CMIDIMappingDirective)) == 0;}
+ CString ToString() const;
+
BYTE GetChnEvent() const {return m_ChnEvent;}
private:
Modified: trunk/OpenMPT/soundlib/patternContainer.h
===================================================================
--- trunk/OpenMPT/soundlib/patternContainer.h 2009-08-25 20:14:24 UTC (rev 343)
+++ trunk/OpenMPT/soundlib/patternContainer.h 2009-08-26 20:40:27 UTC (rev 344)
@@ -55,6 +55,9 @@
// Return true if pattern can be accessed with operator[](iPat), false otherwise.
bool IsValidIndex(const PATTERNINDEX iPat) const {return (iPat < Size());}
+
+ // Return true if IsValidIndex() is true and the corresponding pattern has allocated modcommand array, false otherwise.
+ bool IsValidPat(const PATTERNINDEX iPat) const {return IsValidIndex(iPat) && (*this)[iPat];}
void ResizeArray(const PATTERNINDEX newSize);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2009-08-25 20:14:34
|
Revision: 343
http://modplug.svn.sourceforge.net/modplug/?rev=343&view=rev
Author: relabsoluness
Date: 2009-08-25 20:14:24 +0000 (Tue, 25 Aug 2009)
Log Message:
-----------
[Fix] IT loader: Loading song and instrument extensions was broken (since rev. 340).
Modified Paths:
--------------
trunk/OpenMPT/soundlib/Load_it.cpp
Modified: trunk/OpenMPT/soundlib/Load_it.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_it.cpp 2009-08-25 01:18:21 UTC (rev 342)
+++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-08-25 20:14:24 UTC (rev 343)
@@ -1285,7 +1285,7 @@
}
// Load instrument and song extensions.
- if(mptStartPos >= dwMemPos && mptStartPos < dwMemLength)
+ if(mptStartPos >= dwMemPos)
{
LPCBYTE ptr = LoadExtendedInstrumentProperties(lpStream + dwMemPos, lpStream + mptStartPos, &interpretModplugmade);
LoadExtendedSongProperties(GetType(), ptr, lpStream, mptStartPos, &interpretModplugmade);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-08-25 01:18:28
|
Revision: 342
http://modplug.svn.sourceforge.net/modplug/?rev=342&view=rev
Author: saga-games
Date: 2009-08-25 01:18:21 +0000 (Tue, 25 Aug 2009)
Log Message:
-----------
[Fix] IT Compatibility: Don't reset Tremolo on new note, don't ignore tremolo if note volume is 0
[Fix] IT Compatibility: Fixed Tremolo, Vibrato and Panbrello tables
[Fix] IT Compatibility: Ignore S[345]x with x > 3
[Imp] XM Loader: detect a very old MPT version
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Moddoc.cpp
trunk/OpenMPT/soundlib/Load_psm.cpp
trunk/OpenMPT/soundlib/Load_xm.cpp
trunk/OpenMPT/soundlib/Snd_fx.cpp
trunk/OpenMPT/soundlib/Sndfile.cpp
trunk/OpenMPT/soundlib/Sndmix.cpp
trunk/OpenMPT/soundlib/Tables.cpp
Modified: trunk/OpenMPT/mptrack/Moddoc.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-08-24 20:57:36 UTC (rev 341)
+++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-08-25 01:18:21 UTC (rev 342)
@@ -2742,6 +2742,11 @@
case 0x30: // vibrato waveform
case 0x40: // tremolo waveform
case 0x50: // panbrello waveform
+ if(((param & 0x0F) > 0x03) && m_SndFile.IsCompatibleMode(TRK_IMPULSETRACKER))
+ {
+ strcpy(s, "ignore");
+ break;
+ }
switch(param & 0x0F)
{
case 0x00: case 0x04: case 0x08: case 0x0C: strcpy(s, "sine wave"); break;
Modified: trunk/OpenMPT/soundlib/Load_psm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-24 20:57:36 UTC (rev 341)
+++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-25 01:18:21 UTC (rev 342)
@@ -186,18 +186,10 @@
if(subChunkSize != 6) break;
{
- int version;
- for(DWORD i = 0; i < subChunkSize; i++)
- {
- if(lpStream[dwChunkPos + i] >= '0' && lpStream[dwChunkPos + i] <= '9')
- {
- version = (version * 10) + (lpStream[dwChunkPos + i] - '0');
- } else
- {
- version = 0;
- break;
- }
- }
+ CHAR cversion[7];
+ memcpy(cversion, lpStream + dwChunkPos, 6);
+ cversion[6] = 0;
+ int version = atoi(cversion);
// Sinaria song dates
if(version == 800211 || version == 940902 || version == 940903 ||
version == 940906 || version == 940914 || version == 941213)
Modified: trunk/OpenMPT/soundlib/Load_xm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_xm.cpp 2009-08-24 20:57:36 UTC (rev 341)
+++ trunk/OpenMPT/soundlib/Load_xm.cpp 2009-08-25 01:18:21 UTC (rev 342)
@@ -108,9 +108,6 @@
for(int i = 0; i < 20; i++)
if(lpStream[17 + i] == 0) bProbablyMadeWithModPlug = true;
- if (!memcmp((LPCSTR)lpStream + 0x26, "FastTracker v2.00 ", 20) && bProbablyMadeWithModPlug) bMadeWithModPlug = true;
- if (!memcmp((LPCSTR)lpStream + 0x26, "OpenMPT ", 8)) bMadeWithModPlug = true;
-
dwHdrSize = LittleEndian(*((DWORD *)(lpStream+60)));
norders = LittleEndianW(*((WORD *)(lpStream+64)));
if ((!norders) || (norders > MAX_ORDERS)) return false;
@@ -121,6 +118,23 @@
// if ((!channels) || (channels > 64)) return false;
if ((!channels) || (channels > MAX_BASECHANNELS)) return false;
// -! BEHAVIOUR_CHANGE#0006
+
+ if (!memcmp((LPCSTR)lpStream + 0x26, "FastTracker v2.00 ", 20) && bProbablyMadeWithModPlug) bMadeWithModPlug = true;
+ if (!memcmp((LPCSTR)lpStream + 0x26, "FastTracker v 2.00 ", 20))
+ {
+ bMadeWithModPlug = true;
+ m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 00, 00, 00);
+ }
+
+ if (!memcmp((LPCSTR)lpStream + 0x26, "OpenMPT ", 8))
+ {
+ //bMadeWithModPlug = true; // Don't set it - it's also used by compatibility export
+ CHAR sVersion[13];
+ memcpy(sVersion, lpStream + 0x26 + 8, 12);
+ sVersion[12] = 0;
+ m_dwLastSavedWithVersion = MptVersion::ToNum(sVersion);
+ }
+
m_nType = MOD_TYPE_XM;
m_nMinPeriod = 27;
m_nMaxPeriod = 54784;
@@ -637,7 +651,7 @@
if(bMadeWithModPlug)
{
SetModFlag(MSF_COMPATIBLE_PLAY, false);
- m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 16, 00, 00);
+ if(!m_dwLastSavedWithVersion) m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 16, 00, 00);
}
// -> CODE#0027
Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-08-24 20:57:36 UTC (rev 341)
+++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-08-25 01:18:21 UTC (rev 342)
@@ -718,7 +718,7 @@
pChn->nPos = 0;
pChn->nPosLo = 0;
if (pChn->nVibratoType < 4) pChn->nVibratoPos = ((m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT)) && (!(m_dwSongFlags & SONG_ITOLDEFFECTS))) ? 0x10 : 0;
- if (pChn->nTremoloType < 4) pChn->nTremoloPos = 0;
+ if(!IsCompatibleMode(TRK_IMPULSETRACKER) && pChn->nTremoloType < 4) pChn->nTremoloPos = 0;
}
if (pChn->nPos >= pChn->nLength) pChn->nPos = pChn->nLoopStart;
}
@@ -2541,11 +2541,11 @@
if (pChn->nPeriod) pChn->nPeriod = GetPeriodFromNote(pChn->nNote, pChn->nFineTune, pChn->nC5Speed);
break;
// S3x: Set Vibrato WaveForm
- case 0x30: pChn->nVibratoType = param & 0x07; break;
+ case 0x30: if(((param & 0x0F) < 0x04) || !IsCompatibleMode(TRK_IMPULSETRACKER)) pChn->nVibratoType = param & 0x07; break;
// S4x: Set Tremolo WaveForm
- case 0x40: pChn->nTremoloType = param & 0x07; break;
+ case 0x40: if(((param & 0x0F) < 0x04) || !IsCompatibleMode(TRK_IMPULSETRACKER)) pChn->nTremoloType = param & 0x07; break;
// S5x: Set Panbrello WaveForm
- case 0x50: pChn->nPanbrelloType = param & 0x07; break;
+ case 0x50: if(((param & 0x0F) < 0x04) || !IsCompatibleMode(TRK_IMPULSETRACKER)) pChn->nPanbrelloType = param & 0x07; break;
// S6x: Pattern Delay for x frames
case 0x60: m_nFrameDelay = param; break;
// S7x: Envelope Control
Modified: trunk/OpenMPT/soundlib/Sndfile.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-08-24 20:57:36 UTC (rev 341)
+++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-08-25 01:18:21 UTC (rev 342)
@@ -1190,6 +1190,7 @@
Chn[j].nCommand = 0;
Chn[j].nPatternLoopCount = 0;
Chn[j].nPatternLoop = 0;
+ Chn[j].nVibratoPos = Chn[j].nTremoloPos = Chn[j].nPanbrelloPos = 0;
//IT compatibility 15. Retrigger
if(IsCompatibleMode(TRK_IMPULSETRACKER))
{
@@ -1482,6 +1483,7 @@
Chn[i].nNewLeftVol = Chn[i].nNewRightVol = 0;
Chn[i].nLeftRamp = Chn[i].nRightRamp = 0;
Chn[i].nVolume = 256;
+ Chn[i].nVibratoPos = Chn[i].nTremoloPos = Chn[i].nPanbrelloPos = 0;
//-->Custom tuning related
Chn[i].m_ReCalculateFreqOnFirstTick = false;
Modified: trunk/OpenMPT/soundlib/Sndmix.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndmix.cpp 2009-08-24 20:57:36 UTC (rev 341)
+++ trunk/OpenMPT/soundlib/Sndmix.cpp 2009-08-25 01:18:21 UTC (rev 342)
@@ -68,6 +68,9 @@
extern short int ModRampDownTable[64];
extern short int ModSquareTable[64];
extern short int ModRandomTable[64];
+extern short int ITSinusTable[64];
+extern short int ITRampDownTable[64];
+extern short int ITSquareTable[64];
extern DWORD LinearSlideUpTable[256];
extern DWORD LinearSlideDownTable[256];
extern DWORD FineLinearSlideUpTable[16];
@@ -983,16 +986,16 @@
if (pChn->dwFlags & CHN_TREMOLO)
{
UINT trempos = pChn->nTremoloPos & 0x3F;
- if (vol > 0)
+ if (vol > 0 || IsCompatibleMode(TRK_IMPULSETRACKER))
{
int tremattn = (m_nType & MOD_TYPE_XM) ? 5 : 6;
switch (pChn->nTremoloType & 0x03)
{
case 1:
- vol += (ModRampDownTable[trempos] * (int)pChn->nTremoloDepth) >> tremattn;
+ vol += ((IsCompatibleMode(TRK_IMPULSETRACKER) ? ITRampDownTable[trempos] : ModRampDownTable[trempos]) * (int)pChn->nTremoloDepth) >> tremattn;
break;
case 2:
- vol += (ModSquareTable[trempos] * (int)pChn->nTremoloDepth) >> tremattn;
+ vol += ((IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSquareTable[trempos] : ModSquareTable[trempos]) * (int)pChn->nTremoloDepth) >> tremattn;
break;
case 3:
//IT compatibility 19. Use random values
@@ -1002,12 +1005,12 @@
vol += (ModRandomTable[trempos] * (int)pChn->nTremoloDepth) >> tremattn;
break;
default:
- vol += (ModSinusTable[trempos] * (int)pChn->nTremoloDepth) >> tremattn;
+ vol += ((IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSinusTable[trempos] : ModSinusTable[trempos]) * (int)pChn->nTremoloDepth) >> tremattn;
}
}
if ((m_nTickCount) || ((m_nType & (MOD_TYPE_STM|MOD_TYPE_S3M|MOD_TYPE_IT|MOD_TYPE_MPT)) && (!(m_dwSongFlags & SONG_ITOLDEFFECTS))))
{
- pChn->nTremoloPos = (trempos + pChn->nTremoloSpeed) & 0x3F;
+ pChn->nTremoloPos = (pChn->nTremoloPos + pChn->nTremoloSpeed) & 0x3F;
}
}
@@ -1337,13 +1340,10 @@
switch (pChn->nVibratoType & 0x03)
{
case 1:
- if(IsCompatibleMode(TRK_ALLTRACKERS))
- vdelta = -ModRampDownTable[(vibpos+16) % 64];
- else
- vdelta = ModRampDownTable[vibpos];
+ vdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITRampDownTable[(vibpos + 48) % 64] : ModRampDownTable[vibpos];
break;
case 2:
- vdelta = ModSquareTable[vibpos];
+ vdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSquareTable[(vibpos + 48) % 64] : ModSquareTable[vibpos];
break;
case 3:
//IT compatibility 19. Use random values
@@ -1353,7 +1353,7 @@
vdelta = ModRandomTable[vibpos];
break;
default:
- vdelta = ModSinusTable[vibpos];
+ vdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSinusTable[(vibpos + 48) % 64] : ModSinusTable[vibpos];
}
if(m_nType == MOD_TYPE_MPT && pChn->pModInstrument && pChn->pModInstrument->pTuning)
@@ -1385,11 +1385,14 @@
if (l & 0x03) vdelta += _muldiv(period, FineLinearSlideUpTable[l & 0x03], 0x10000) - period;
}
}
- period += vdelta;
+ if(IsCompatibleMode(TRK_ALLTRACKERS))
+ period -= vdelta;
+ else
+ period += vdelta;
}
if ((m_nTickCount) || ((m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT)) && (!(m_dwSongFlags & SONG_ITOLDEFFECTS))))
{
- pChn->nVibratoPos = (vibpos + pChn->nVibratoSpeed) & 0x3F;
+ pChn->nVibratoPos = (pChn->nVibratoPos + pChn->nVibratoSpeed) & 0x3F;
}
}
// Panbrello
@@ -1400,10 +1403,10 @@
switch (pChn->nPanbrelloType & 0x03)
{
case 1:
- pdelta = ModRampDownTable[panpos];
+ pdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITRampDownTable[panpos] : ModRampDownTable[panpos];
break;
case 2:
- pdelta = ModSquareTable[panpos];
+ pdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSquareTable[panpos] : ModSquareTable[panpos];
break;
case 3:
//IT compatibility 19. Use random values
@@ -1413,10 +1416,10 @@
pdelta = ModRandomTable[panpos];
break;
default:
- pdelta = ModSinusTable[panpos];
+ pdelta = IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSinusTable[panpos] : ModSinusTable[panpos];
}
pChn->nPanbrelloPos += pChn->nPanbrelloSpeed;
- pdelta = ((pdelta * (int)pChn->nPanbrelloDepth) + 2) >> 3;
+ pdelta = ((pdelta * (int)pChn->nPanbrelloDepth) + 2) >> (IsCompatibleMode(TRK_IMPULSETRACKER) ? 4 : 3);
pdelta += pChn->nRealPan;
pChn->nRealPan = CLAMP(pdelta, 0, 256);
Modified: trunk/OpenMPT/soundlib/Tables.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Tables.cpp 2009-08-24 20:57:36 UTC (rev 341)
+++ trunk/OpenMPT/soundlib/Tables.cpp 2009-08-25 01:18:21 UTC (rev 342)
@@ -154,7 +154,35 @@
42,-34,89,-4,-51,-72,21,-29,112,123,84,-101,-92,98,-54,-95
};
+// Impulse Tracker tables
+// Sinus table
+short int ITSinusTable[64] =
+{
+ 0,12,25,37,49,60,71,81,90,98,106,112,117,122,125,126,
+ 127,126,125,122,117,112,106,98,90,81,71,60,49,37,25,12,
+ 0,-12,-25,-37,-49,-60,-71,-81,-90,-98,-106,-112,-117,-122,-125,-126,
+ -127,-126,-125,-122,-117,-112,-106,-98,-90,-81,-71,-60,-49,-37,-25,-12
+};
+
+// Triangle wave table (ramp down)
+short int ITRampDownTable[64] =
+{
+ 127,123,119,115,111,107,103,99,95,91,87,83,79,75,71,67,
+ 63,59,55,51,47,43,39,35,31,27,23,19,15,11,7,3,
+ 0,-4,-8,-12,-16,-20,-24,-28,-32,-36,-40,-44,-48,-52,-56,-60,
+ -64,-68,-72,-76,-80,-84,-88,-92,-96,-100,-104,-108,-112,-116,-120,-124
+};
+
+// Square wave table
+short int ITSquareTable[64] =
+{
+ 127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
+ 127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+};
+
// volume fade tables for Retrig Note:
signed char retrigTable1[16] =
{ 0, 0, 0, 0, 0, 0, 10, 8, 0, 0, 0, 0, 0, 0, 24, 32 };
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-08-24 20:58:07
|
Revision: 341
http://modplug.svn.sourceforge.net/modplug/?rev=341&view=rev
Author: saga-games
Date: 2009-08-24 20:57:36 +0000 (Mon, 24 Aug 2009)
Log Message:
-----------
[Fix] MOD / XM Loading / Saving: More intelligent conversion of Speed / Tempo commands
[Fix] MOD Loading: Last pattern was not loading in .MODs that have no samples
[Ref] Made some CSoundFile functions private
Modified Paths:
--------------
trunk/OpenMPT/mptrack/typedefs.h
trunk/OpenMPT/soundlib/Load_mod.cpp
trunk/OpenMPT/soundlib/Load_psm.cpp
trunk/OpenMPT/soundlib/Sndfile.cpp
trunk/OpenMPT/soundlib/Sndfile.h
Modified: trunk/OpenMPT/mptrack/typedefs.h
===================================================================
--- trunk/OpenMPT/mptrack/typedefs.h 2009-08-24 11:43:54 UTC (rev 340)
+++ trunk/OpenMPT/mptrack/typedefs.h 2009-08-24 20:57:36 UTC (rev 341)
@@ -34,6 +34,8 @@
typedef uint32 ROWINDEX;
const ROWINDEX ROWINDEX_MAX = uint32_max;
typedef uint16 CHANNELINDEX;
+ const CHANNELINDEX CHANNELINDEX_MAX = uint16_max;
+ const CHANNELINDEX CHANNELINDEX_INVALID = CHANNELINDEX_MAX;
typedef uint16 ORDERINDEX;
const ORDERINDEX ORDERINDEX_MAX = uint16_max;
const ORDERINDEX ORDERINDEX_INVALID = ORDERINDEX_MAX;
Modified: trunk/OpenMPT/soundlib/Load_mod.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_mod.cpp 2009-08-24 11:43:54 UTC (rev 340)
+++ trunk/OpenMPT/soundlib/Load_mod.cpp 2009-08-24 20:57:36 UTC (rev 341)
@@ -41,7 +41,7 @@
case 0x0D: command = CMD_PATTERNBREAK; param = ((param >> 4) * 10) + (param & 0x0F); break;
case 0x0E: command = CMD_MODCMDEX; break;
case 0x0F: command = (param <= (UINT)((m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2)) ? 0x1F : 0x20)) ? CMD_SPEED : CMD_TEMPO;
- if ((param == 0xFF) && (m_nSamples == 15)) command = 0; break; //<rewbs> what the hell is this?! :) //<jojo> it's the "stop tune" command! :-P
+ if ((param == 0xFF) && (m_nSamples == 15) && (m_nType & MOD_TYPE_MOD)) command = 0; break; //<rewbs> what the hell is this?! :) //<jojo> it's the "stop tune" command! :-P
// Extension for XM extended effects
case 'G' - 55: command = CMD_GLOBALVOLUME; break; //16
case 'H' - 55: command = CMD_GLOBALVOLSLIDE; if (param & 0xF0) param &= 0xF0; break;
@@ -97,16 +97,24 @@
case CMD_TREMOLO: command = 0x07; break;
case CMD_PANNING8:
command = 0x08;
- if (bXM)
+ if(m_nType & MOD_TYPE_S3M)
{
- if (!(m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT)) && (m_nType != MOD_TYPE_XM) && (param <= 0x80))
+ if(param <= 0x80)
{
- param <<= 1;
- if (param > 255) param = 255;
+ param = min(param << 1, 0xFF);
}
- } else
- {
- if ((m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT)) || (m_nType == MOD_TYPE_XM)) param >>= 1;
+ else if(param == 0xA4)
+ {
+ if(bCompatibilityExport || !bXM)
+ {
+ command = param = 0;
+ }
+ else
+ {
+ command = 'X' - 55;
+ param = 91;
+ }
+ }
}
break;
case CMD_OFFSET: command = 0x09; break;
@@ -115,8 +123,8 @@
case CMD_VOLUME: command = 0x0C; break;
case CMD_PATTERNBREAK: command = 0x0D; param = ((param / 10) << 4) | (param % 10); break;
case CMD_MODCMDEX: command = 0x0E; break;
- case CMD_SPEED: command = 0x0F; if (param > 0x20) param = 0x20; break;
- case CMD_TEMPO: if (param >= 0x20) { command = 0x0F; break; }
+ case CMD_SPEED: command = 0x0F; param = min(param, (bXM) ? 0x1F : 0x20); break;
+ case CMD_TEMPO: command = 0x0F; param = max(param, (bXM) ? 0x20 : 0x21); break;
case CMD_GLOBALVOLUME: command = 'G' - 55; break;
case CMD_GLOBALVOLSLIDE: command = 'H' - 55; break;
case CMD_KEYOFF: command = 'K' - 55; break;
@@ -355,7 +363,7 @@
if (ipat < MAX_PATTERNS)
{
if(Patterns.Insert(ipat, 64)) break;
- if (dwMemPos + m_nChannels*256 >= dwMemLength) break;
+ if (dwMemPos + m_nChannels * 256 > dwMemLength) break;
MODCOMMAND *m = Patterns[ipat];
LPCBYTE p = lpStream + dwMemPos;
for (UINT j=m_nChannels*64; j; m++,p+=4,j--)
@@ -371,18 +379,21 @@
}
dwMemPos += m_nChannels*256;
}
- // Reading instruments
+
+ // Reading samples
DWORD dwErrCheck = 0;
- for (UINT ismp=1; ismp<=m_nSamples; ismp++) if (Samples[ismp].nLength)
+ for (UINT ismp = 1; ismp <= m_nSamples; ismp++) if (Samples[ismp].nLength)
{
- LPSTR p = (LPSTR)(lpStream+dwMemPos);
+ LPSTR p = (LPSTR)(lpStream + dwMemPos);
UINT flags = 0;
- if (dwMemPos + 5 >= dwMemLength) break;
- if (!_strnicmp(p, "ADPCM", 5))
+ if (dwMemPos + 5 <= dwMemLength)
{
- flags = 3;
- p += 5;
- dwMemPos += 5;
+ if (!_strnicmp(p, "ADPCM", 5))
+ {
+ flags = 3;
+ p += 5;
+ dwMemPos += 5;
+ }
}
DWORD dwSize = ReadSample(&Samples[ismp], flags, p, dwMemLength - dwMemPos);
if (dwSize)
@@ -394,7 +405,7 @@
#ifdef MODPLUG_TRACKER
return true;
#else
- return (dwErrCheck) ? TRUE : FALSE;
+ return (dwErrCheck) ? true : false;
#endif
}
Modified: trunk/OpenMPT/soundlib/Load_psm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-24 11:43:54 UTC (rev 340)
+++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-24 20:57:36 UTC (rev 341)
@@ -77,17 +77,9 @@
};
#pragma pack()
-BYTE convert_psm_porta(BYTE param, bool bNewFormat)
+inline BYTE convert_psm_porta(BYTE param, bool bNewFormat)
{
- if(bNewFormat)
- {
- return param;
- }
- else
- {
- if(param < 4) return param | 0xF0;
- else return (param >> 2);
- }
+ return ((bNewFormat) ? (param) : ((param < 4) ? (param | 0xF0) : (param >> 2)));
}
bool CSoundFile::ReadPSM(const LPCBYTE lpStream, const DWORD dwMemLength)
@@ -109,7 +101,6 @@
// Yep, this seems to be a valid file.
m_nType = MOD_TYPE_PSM;
- //m_dwSongFlags |= SONG_LINEARSLIDES; // TODO
m_nChannels = 0;
dwMemPos += 12;
@@ -207,6 +198,7 @@
break;
}
}
+ // Sinaria song dates
if(version == 800211 || version == 940902 || version == 940903 ||
version == 940906 || version == 940914 || version == 941213)
bNewFormat = true;
Modified: trunk/OpenMPT/soundlib/Sndfile.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-08-24 11:43:54 UTC (rev 340)
+++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-08-24 20:57:36 UTC (rev 341)
@@ -3040,3 +3040,152 @@
return *p;
}
+/* Try to write an (volume) effect in a given channel or any channel of a pattern in a specific row.
+ Usage: nPat - Pattern that should be modified
+ nRow - Row that should be modified
+ nEffect - (Volume) Effect that should be written
+ nParam - Effect that should be written
+ bIsVolumeEffect - Indicates whether the given effect is a volume effect or not
+ nChn - Channel that should be modified - use CHANNELINDEX_INVALID to allow all channels of the given row
+ bAllowMultipleEffects - If false, No effect will be written if an effect of the same type is already present in the channel(s)
+ bAllowNextRow - Indicates whether it is allowed to use the next row if there's no space for the effect
+ bRetry - For internal use only. Indicates whether an effect "rewrite" has already taken place (for recursive calls)
+*/
+bool CSoundFile::TryWriteEffect(PATTERNINDEX nPat, ROWINDEX nRow, BYTE nEffect, BYTE nParam, bool bIsVolumeEffect, CHANNELINDEX nChn, bool bAllowMultipleEffects, bool bAllowNextRow, bool bRetry)
+//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+{
+ // NOTE: Effect remapping is only implemented for a few basic effects.
+ CHANNELINDEX nScanChnMin = nChn, nScanChnMax = nChn;
+ MODCOMMAND *p = Patterns[nPat], *m;
+
+ // Scan all channels
+ if(nChn == CHANNELINDEX_INVALID)
+ {
+ nScanChnMin = 0;
+ nScanChnMax = m_nChannels - 1;
+ }
+
+ // Scan channel(s) for same effect type - if an effect of the same type is already present, exit.
+ if(bAllowMultipleEffects == false)
+ {
+ for(CHANNELINDEX i = nScanChnMin; i <= nScanChnMax; i++)
+ {
+ m = p + nRow * m_nChannels + i;
+ if(!bIsVolumeEffect && m->command == nEffect)
+ return true;
+ if(bIsVolumeEffect && m->volcmd == nEffect)
+ return true;
+ }
+ }
+
+ // Easy case: check if there's some space left to put the effect somewhere
+ for(CHANNELINDEX i = nScanChnMin; i <= nScanChnMax; i++)
+ {
+ m = p + nRow * m_nChannels + i;
+ if(!bIsVolumeEffect && m->command == CMD_NONE)
+ {
+ m->command = nEffect;
+ m->param = nParam;
+ return true;
+ }
+ if(bIsVolumeEffect && m->volcmd == VOLCMD_NONE)
+ {
+ m->volcmd = nEffect;
+ m->vol = nParam;
+ return true;
+ }
+ }
+
+ // Ok, apparently there's no space. If we haven't tried already, try to map it to the volume column or effect column instead.
+ if(bRetry == true) {
+ // Move some effects that also work in the volume column, so there's place for our new effect.
+ if(!bIsVolumeEffect)
+ {
+ for(CHANNELINDEX i = nScanChnMin; i <= nScanChnMax; i++)
+ {
+ m = p + nRow * m_nChannels + i;
+ switch(m->command)
+ {
+ case CMD_VOLUME:
+ m->volcmd = VOLCMD_VOLUME;
+ m->vol = m->param;
+ m->command = nEffect;
+ m->param = nParam;
+ return true;
+
+ case CMD_PANNING8:
+ if(m_nType & MOD_TYPE_S3M && nParam > 0x80)
+ break;
+
+ m->volcmd = VOLCMD_VOLUME;
+ m->command = nEffect;
+
+ if(m_nType & MOD_TYPE_S3M)
+ {
+ m->vol = m->param >> 1;
+ }
+ else
+ {
+ m->vol = (m->param >> 2) + 1;
+ }
+
+ m->param = nParam;
+ return true;
+ }
+ }
+ }
+
+ // Let's try it again by writing into the "other" effect column.
+ BYTE nNewEffect = CMD_NONE;
+ if(bIsVolumeEffect)
+ {
+ switch(nEffect)
+ {
+ case VOLCMD_PANNING:
+ nNewEffect = CMD_PANNING8;
+ if(m_nType & MOD_TYPE_S3M)
+ nParam <<= 1;
+ else
+ nParam = min(nParam << 2, 0xFF);
+ break;
+ case VOLCMD_VOLUME:
+ nNewEffect = CMD_VOLUME;
+ break;
+ }
+ } else
+ {
+ switch(nEffect)
+ {
+ case CMD_PANNING8:
+ nNewEffect = VOLCMD_PANNING;
+ if(m_nType & MOD_TYPE_S3M)
+ {
+ if(nParam <= 0x80)
+ nParam >>= 1;
+ else
+ nNewEffect = CMD_NONE;
+ }
+ else
+ {
+ nParam = (nParam >> 2) + 1;
+ }
+ break;
+ case CMD_VOLUME:
+ nNewEffect = CMD_VOLUME;
+ break;
+ }
+ }
+ if(nNewEffect != CMD_NONE)
+ {
+ if(TryWriteEffect(nPat, nRow, nNewEffect, nParam, !bIsVolumeEffect, nChn, bAllowMultipleEffects, bAllowNextRow, false) == true) return true;
+ }
+ }
+
+ // Try in the next row if possible (this may also happen if we already retried)
+ if(bAllowNextRow && (nRow + 1 < Patterns[nPat].GetNumRows()))
+ {
+ return TryWriteEffect(nPat, nRow + 1, nEffect, nParam, bIsVolumeEffect, nChn, bAllowMultipleEffects, bAllowNextRow, bRetry);
+ }
+
+ return false;
+}
Modified: trunk/OpenMPT/soundlib/Sndfile.h
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.h 2009-08-24 11:43:54 UTC (rev 340)
+++ trunk/OpenMPT/soundlib/Sndfile.h 2009-08-24 20:57:36 UTC (rev 341)
@@ -1148,7 +1148,15 @@
void CheckNNA(UINT nChn, UINT instr, int note, BOOL bForceCut);
void NoteChange(UINT nChn, int note, BOOL bPorta=FALSE, BOOL bResetEnv=TRUE, BOOL bManual=FALSE);
void InstrumentChange(MODCHANNEL *pChn, UINT instr, BOOL bPorta=FALSE,BOOL bUpdVol=TRUE,BOOL bResetEnv=TRUE);
+
// Channel Effects
+ void KeyOff(UINT nChn);
+ // Global Effects
+ void SetTempo(UINT param, bool setAsNonModcommand = false);
+ void SetSpeed(UINT param);
+
+private:
+ // Channel Effects
void PortamentoUp(MODCHANNEL *pChn, UINT param, const bool fineAsRegular = false);
void PortamentoDown(MODCHANNEL *pChn, UINT param, const bool fineAsRegular = false);
void MidiPortamento(MODCHANNEL *pChn, int param);
@@ -1170,7 +1178,6 @@
void RetrigNote(UINT nChn, UINT param, UINT offset=0); //rewbs.volOffset: added last param
void SampleOffset(UINT nChn, UINT param, bool bPorta); //rewbs.volOffset: moved offset code to own method
void NoteCut(UINT nChn, UINT nTick);
- void KeyOff(UINT nChn);
int PatternLoop(MODCHANNEL *, UINT param);
void ExtendedMODCommands(UINT nChn, UINT param);
void ExtendedS3MCommands(UINT nChn, UINT param);
@@ -1180,12 +1187,14 @@
void SetupChannelFilter(MODCHANNEL *pChn, BOOL bReset, int flt_modifier=256) const;
// Low-Level effect processing
void DoFreqSlide(MODCHANNEL *pChn, LONG nFreqSlide);
- // Global Effects
- void SetTempo(UINT param, bool setAsNonModcommand = false);
- void SetSpeed(UINT param);
void GlobalVolSlide(UINT param, UINT * nOldGlobalVolSlide);
DWORD IsSongFinished(UINT nOrder, UINT nRow) const;
BOOL IsValidBackwardJump(UINT nStartOrder, UINT nStartRow, UINT nJumpOrder, UINT nJumpRow) const;
+public:
+
+ // Write pattern effect functions
+ bool TryWriteEffect(PATTERNINDEX nPat, ROWINDEX nRow, BYTE nEffect, BYTE nParam, bool bIsVolumeEffect, CHANNELINDEX nChn = CHANNELINDEX_INVALID, bool bAllowMultipleEffects = true, bool bAllowNextRow = false, bool bRetry = true);
+
// Read/Write sample functions
char GetDeltaValue(char prev, UINT n) const { return (char)(prev + CompressionTable[n & 0x0F]); }
UINT PackSample(int &sample, int next);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-08-24 11:44:05
|
Revision: 340
http://modplug.svn.sourceforge.net/modplug/?rev=340&view=rev
Author: saga-games
Date: 2009-08-24 11:43:54 +0000 (Mon, 24 Aug 2009)
Log Message:
-----------
[Fix] IT Loader: Unset release env nodes for IT files made with IT 1.x, fix fadeout values
[Imp] PSM Loader: Several fixes for "new new" PSM format, channel panning, etc.
[Imp] S3M Loader: Don't write unnecessary invalid order items in the order table
[Imp] LHA Decoder: Several fixes (patch by kode54)
Modified Paths:
--------------
trunk/OpenMPT/soundlib/Load_it.cpp
trunk/OpenMPT/soundlib/Load_psm.cpp
trunk/OpenMPT/soundlib/Load_s3m.cpp
trunk/OpenMPT/unlha/EXTRACT.CPP
trunk/OpenMPT/unlha/HUF.CPP
trunk/OpenMPT/unlha/LHEXT.CPP
trunk/OpenMPT/unlha/SLIDE.CPP
trunk/OpenMPT/unlha/SLIDEHUF.H
trunk/OpenMPT/unlha/UNLHA32.H
trunk/OpenMPT/unlha/Unlha.cpp
Modified: trunk/OpenMPT/soundlib/Load_it.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_it.cpp 2009-08-23 21:07:17 UTC (rev 339)
+++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-08-24 11:43:54 UTC (rev 340)
@@ -230,7 +230,7 @@
const ITOLDINSTRUMENT *pis = (const ITOLDINSTRUMENT *)p;
memcpy(pIns->name, pis->name, 26);
memcpy(pIns->filename, pis->filename, 12);
- pIns->nFadeOut = pis->fadeout << 6;
+ pIns->nFadeOut = pis->fadeout << 7;
pIns->nGlobalVol = 64;
for (UINT j=0; j<NOTE_MAX; j++)
{
@@ -260,6 +260,10 @@
pIns->nNNA = pis->nna;
pIns->nDCT = pis->dnc;
pIns->nPan = 0x80;
+
+ pIns->VolEnv.nReleaseNode = ENV_RELEASE_NODE_UNSET;
+ pIns->PanEnv.nReleaseNode = ENV_RELEASE_NODE_UNSET;
+ pIns->PitchEnv.nReleaseNode = ENV_RELEASE_NODE_UNSET;
} else
{
const ITINSTRUMENT *pis = (const ITINSTRUMENT *)p;
@@ -276,7 +280,7 @@
}
if (pis->mbank<=128)
pIns->wMidiBank = pis->mbank;
- pIns->nFadeOut = pis->fadeout << 5;
+ pIns->nFadeOut = pis->fadeout << 5; // should be 6?
pIns->nGlobalVol = pis->gbv >> 1;
if (pIns->nGlobalVol > 64) pIns->nGlobalVol = 64;
for (UINT j=0; j<NOTE_MAX; j++)
@@ -1281,7 +1285,7 @@
}
// Load instrument and song extensions.
- if(mptStartPos >= dwMemPos)
+ if(mptStartPos >= dwMemPos && mptStartPos < dwMemLength)
{
LPCBYTE ptr = LoadExtendedInstrumentProperties(lpStream + dwMemPos, lpStream + mptStartPos, &interpretModplugmade);
LoadExtendedSongProperties(GetType(), ptr, lpStream, mptStartPos, &interpretModplugmade);
@@ -2001,7 +2005,7 @@
//if (pIns->nDCT<DCT_PLUGIN) iti.dct = pIns->nDCT; else iti.dct =0;
iti.dct = pIns->nDCT; //rewbs.instroVSTi: will other apps barf if they get an unknown DCT?
iti.dca = pIns->nDNA;
- iti.fadeout = pIns->nFadeOut >> 5;
+ iti.fadeout = pIns->nFadeOut >> 5; // should be 6?
iti.pps = pIns->nPPS;
iti.ppc = pIns->nPPC;
iti.gbv = (BYTE)(pIns->nGlobalVol << 1);
Modified: trunk/OpenMPT/soundlib/Load_psm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-23 21:07:17 UTC (rev 339)
+++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-24 11:43:54 UTC (rev 340)
@@ -38,7 +38,7 @@
};
-struct PSMSAMPLEHEADER // Regular sample header
+struct PSMOLDSAMPLEHEADER // Regular sample header
{
BYTE flags;
CHAR fileName[8]; // Filename of the original module (without extension)
@@ -49,14 +49,15 @@
DWORD sampleLength;
DWORD loopStart;
DWORD loopEnd; // FF FF FF FF = end of sample
- WORD unknown3;
+ BYTE unknown3;
+ BYTE defaulPan; // unused?
BYTE defaultVolume;
DWORD unknown4;
WORD C5Freq;
CHAR unknown5[21]; // 00 ... 00
};
-struct PSMSAMPLEHEADERSINARIA // Sinaria sample header
+struct PSMNEWSAMPLEHEADER // Sinaria sample header (and possibly other games)
{
BYTE flags;
CHAR fileName[8]; // Filename of the original module (without extension)
@@ -68,20 +69,25 @@
DWORD loopStart;
DWORD loopEnd;
WORD unknown3;
- BYTE unknown4;
+ BYTE defaultPan; // unused?
BYTE defaultVolume;
- DWORD unknown5;
+ DWORD unknown4;
WORD C5Freq;
- CHAR unknown6[16]; // 00 ... 00
+ CHAR unknown5[16]; // 00 ... 00
};
#pragma pack()
-BYTE convert_psm_effect(BYTE param, bool bIsSinaria)
+BYTE convert_psm_porta(BYTE param, bool bNewFormat)
{
- if(bIsSinaria)
+ if(bNewFormat)
+ {
return param;
+ }
else
- return (param >> 2);
+ {
+ if(param < 4) return param | 0xF0;
+ else return (param >> 2);
+ }
}
bool CSoundFile::ReadPSM(const LPCBYTE lpStream, const DWORD dwMemLength)
@@ -91,7 +97,7 @@
if( dwMemPos > dwMemLength || x > dwMemLength - dwMemPos ) return false;
DWORD dwMemPos = 0;
- bool bIsSinaria = false; // The game "Sinaria" uses a slightly modified PSM structure
+ bool bNewFormat = false; // The game "Sinaria" uses a slightly modified PSM structure
ASSERT_CAN_READ(12);
PSMHEADER shdr;
@@ -148,11 +154,11 @@
// Pattern ID (something like "P0 " or "P13 ") follows
if(memcmp(lpStream + dwMemPos + 4, "P", 1)) return false;
- if(!memcmp(lpStream + dwMemPos + 4, "PATT", 4)) bIsSinaria = true;
+ if(!memcmp(lpStream + dwMemPos + 4, "PATT", 4)) bNewFormat = true;
char patternID[4];
- memcpy(patternID, lpStream + dwMemPos + 5 + (bIsSinaria ? 3 : 0), 3);
+ memcpy(patternID, lpStream + dwMemPos + 5 + (bNewFormat ? 3 : 0), 3);
patternID[3] = 0;
- patternOffsets.push_back(dwMemPos + 8 + (bIsSinaria ? 4 : 0));
+ patternOffsets.push_back(dwMemPos + 8 + (bNewFormat ? 4 : 0));
patternIDs.push_back(atoi(patternID));
numPatterns++;
@@ -185,23 +191,46 @@
switch(subChunkID)
{
- case 0x45544144: // "DATE" - Song date (YYMMDD)
- if(subChunkSize < 6) break;
+ case 0x45544144: // "DATE" - Conversion date (YYMMDD)
+ if(subChunkSize != 6) break;
+ {
+ int version;
+ for(DWORD i = 0; i < subChunkSize; i++)
+ {
+ if(lpStream[dwChunkPos + i] >= '0' && lpStream[dwChunkPos + i] <= '9')
+ {
+ version = (version * 10) + (lpStream[dwChunkPos + i] - '0');
+ } else
+ {
+ version = 0;
+ break;
+ }
+ }
+ if(version == 800211 || version == 940902 || version == 940903 ||
+ version == 940906 || version == 940914 || version == 941213)
+ bNewFormat = true;
+ }
+ #ifdef DEBUG
CHAR cDate[7];
memcpy(cDate, lpStream + dwChunkPos, 6);
cDate[6] = 0;
- sComment += " - Date: ";
+ sComment += " - Build Date: ";
sComment += cDate;
+ if(bNewFormat) sComment += " (New Format)";
+ else sComment += " (Old Format)";
+ #endif
break;
case 0x484C504F: // "OPLH" - Order list, channel + module settings
{
if(subChunkSize < 9) return false;
- // First two bytes = "Memory alloc, roughly ordlen + 10, if too small, song freezes"
+ // First two bytes = Number of chunks that follow
+ //WORD nTotalChunks = LittleEndian(*(WORD *)(lpStream + dwChunkPos));
// Now, the interesting part begins!
DWORD dwSettingsOffset = dwChunkPos + 2;
+ WORD nChunkCount = 0, nFirstOrderChunk = (WORD)-1;
while(dwSettingsOffset - dwChunkPos + 1 < subChunkSize)
{
switch(lpStream[dwSettingsOffset])
@@ -216,7 +245,7 @@
for(PATTERNINDEX i = 0; i < patternIDs.size(); i++)
{
char patternID[4];
- memcpy(patternID, lpStream + dwSettingsOffset + 2 + (bIsSinaria ? 3 : 0), 3);
+ memcpy(patternID, lpStream + dwSettingsOffset + 2 + (bNewFormat ? 3 : 0), 3);
patternID[3] = 0;
DWORD nPattern = atoi(patternID);
if(patternIDs[i] == nPattern)
@@ -225,23 +254,25 @@
break;
}
}
- dwSettingsOffset += 5 + (bIsSinaria ? 4 : 0);
+ if(nFirstOrderChunk == (WORD)-1) nFirstOrderChunk = nChunkCount;
+ dwSettingsOffset += 5 + (bNewFormat ? 4 : 0);
break;
- case 0x04:
- /* It looks like the 2nd number of this chunk could be the restart position,
- where position = ((number < 15) ? 0 : (number - 15)) */
-
- //uint32 pos = lpStream[dwSettingsOffset + 1] | (lpStream[dwSettingsOffset + 2] << 8);
-
- // NOTE: This should not be global! (Extreme Pinball!!!)
- #ifdef DEBUG
+ case 0x04: // Restart position
{
- char s[32];
- wsprintf(s, " - restart %d", (lpStream[dwSettingsOffset + 1] < 15) ? 0 : lpStream[dwSettingsOffset + 1] - 15);
- sComment += s;
+ // NOTE: This should not be global! (Extreme Pinball!!!)
+ WORD nRestartChunk = LittleEndian(*(WORD *)(lpStream + dwSettingsOffset + 1));
+ ORDERINDEX nRestartPosition = 0;
+ if(nRestartChunk == 0) nRestartPosition = 0;
+ else if(nRestartChunk >= nFirstOrderChunk) nRestartPosition = (ORDERINDEX)(nRestartChunk - nFirstOrderChunk);
+ #ifdef DEBUG
+ {
+ char s[32];
+ wsprintf(s, " - restart pos %d", nRestartPosition);
+ sComment += s;
+ }
+ #endif
}
- #endif
dwSettingsOffset += 3;
break;
@@ -277,7 +308,7 @@
switch(lpStream[dwSettingsOffset + 3])
{
case 0:
- ChnSettings[nChn].nPan = lpStream[dwSettingsOffset + 2];
+ ChnSettings[nChn].nPan = lpStream[dwSettingsOffset + 2] ^ 128;
break;
case 2:
@@ -309,6 +340,7 @@
break;
}
+ nChunkCount++;
}
Order.push_back(Order.GetInvalidPatIndex());
}
@@ -322,7 +354,7 @@
switch(lpStream[dwChunkPos + i])
{
case 0:
- ChnSettings[i >> 1].nPan = lpStream[dwChunkPos + i + 1] - 128;
+ ChnSettings[i >> 1].nPan = lpStream[dwChunkPos + i + 1] ^ 128;
break;
case 2:
@@ -357,10 +389,10 @@
break;
case 0x504D5344: // DSMP - Samples
- if(!bIsSinaria)
+ if(!bNewFormat)
{
- if(chunkSize < sizeof(PSMSAMPLEHEADER)) return false;
- PSMSAMPLEHEADER *pSample = (PSMSAMPLEHEADER *)(lpStream + dwMemPos);
+ if(chunkSize < sizeof(PSMOLDSAMPLEHEADER)) return false;
+ PSMOLDSAMPLEHEADER *pSample = (PSMOLDSAMPLEHEADER *)(lpStream + dwMemPos);
SAMPLEINDEX smp = (SAMPLEINDEX)(LittleEndianW(pSample->sampleNumber) + 1);
m_nSamples = max(m_nSamples, smp);
memcpy(m_szNames[smp], pSample->sampleName, 31);
@@ -379,12 +411,12 @@
if(Samples[smp].nLoopEnd == 0xFFFFFF) Samples[smp].nLoopEnd = Samples[smp].nLength;
// Delta-encoded samples
- ReadSample(&Samples[smp], RS_PCM8D, (LPCSTR)(lpStream + dwMemPos + sizeof(PSMSAMPLEHEADER)), Samples[smp].nLength);
+ ReadSample(&Samples[smp], RS_PCM8D, (LPCSTR)(lpStream + dwMemPos + sizeof(PSMOLDSAMPLEHEADER)), Samples[smp].nLength);
} else
{
// Sinaria uses a slightly different sample header
- if(chunkSize < sizeof(PSMSAMPLEHEADERSINARIA)) return false;
- PSMSAMPLEHEADERSINARIA *pSample = (PSMSAMPLEHEADERSINARIA *)(lpStream + dwMemPos);
+ if(chunkSize < sizeof(PSMNEWSAMPLEHEADER)) return false;
+ PSMNEWSAMPLEHEADER *pSample = (PSMNEWSAMPLEHEADER *)(lpStream + dwMemPos);
SAMPLEINDEX smp = (SAMPLEINDEX)(LittleEndianW(pSample->sampleNumber) + 1);
m_nSamples = max(m_nSamples, smp);
memcpy(m_szNames[smp], pSample->sampleName, 31);
@@ -403,7 +435,7 @@
if(Samples[smp].nLoopEnd == 0xFFFFFF) Samples[smp].nLoopEnd = Samples[smp].nLength;
// Delta-encoded samples
- ReadSample(&Samples[smp], RS_PCM8D, (LPCSTR)(lpStream + dwMemPos + sizeof(PSMSAMPLEHEADERSINARIA)), Samples[smp].nLength);
+ ReadSample(&Samples[smp], RS_PCM8D, (LPCSTR)(lpStream + dwMemPos + sizeof(PSMNEWSAMPLEHEADER)), Samples[smp].nLength);
}
break;
@@ -419,24 +451,24 @@
if(m_nChannels == 0)
return false;
// Now that we know the number of channels, we can go through all the patterns.
- for(PATTERNINDEX i = 0; i < numPatterns; i++)
+ for(PATTERNINDEX nPat = 0; nPat < numPatterns; nPat++)
{
- DWORD dwPatternOffset = patternOffsets[i];
+ DWORD dwPatternOffset = patternOffsets[nPat];
if(dwPatternOffset + 2 > dwMemLength) return false;
WORD patternSize = LittleEndianW(*(WORD *)(lpStream + dwPatternOffset));
dwPatternOffset += 2;
- if(Patterns.Insert(i, patternSize))
+ if(Patterns.Insert(nPat, patternSize))
{
CString s;
- s.Format(TEXT("Allocating patterns failed starting from pattern %u"), i);
+ s.Format(TEXT("Allocating patterns failed starting from pattern %u"), nPat);
MessageBox(NULL, s, TEXT("OpenMPT PSM import"), MB_ICONERROR);
break;
}
// Read pattern.
MODCOMMAND *row_data;
- row_data = Patterns[i];
+ row_data = Patterns[nPat];
for(int nRow = 0; nRow < patternSize; nRow++)
{
@@ -458,15 +490,15 @@
if(dwRowOffset + 1 > dwMemLength) return false;
// Note present
BYTE bNote = lpStream[dwRowOffset];
- if(!bIsSinaria)
+ if(!bNewFormat)
{
if(bNote == 0xFF)
bNote = NOTE_NOTECUT;
else
- bNote = (bNote & 0x0F) + 12 * (bNote >> 4) + 13;
+ if(bNote < 129) bNote = (bNote & 0x0F) + 12 * (bNote >> 4) + 13;
} else
{
- bNote += 36;
+ if(bNote < 85) bNote += 36;
}
m->note = bNote;
dwRowOffset++;
@@ -500,41 +532,45 @@
// Volslides
case 0x01: // fine volslide up
command = CMD_VOLUMESLIDE;
- param = (param << 3) | 0x0F;
+ if (bNewFormat) param = (param << 4) | 0x0F;
+ else param = ((param & 0x1E) << 3) | 0x0F;
break;
case 0x02: // volslide up
command = CMD_VOLUMESLIDE;
- param = (param << 3);
+ if (bNewFormat) param = 0xF0 & (param << 4);
+ else param = 0xF0 & (param << 3);
break;
case 0x03: // fine volslide down
command = CMD_VOLUMESLIDE;
- param = 0xF0 | (param >> 1);
+ if (bNewFormat) param |= 0xF0;
+ else param = 0xF0 | (param >> 1);
break;
case 0x04: // volslide down
command = CMD_VOLUMESLIDE;
- param >>= 1;
+ if (bNewFormat) param &= 0x0F;
+ else param = (param >> 1) & 0x0F;
break;
// Portamento
case 0x0B: // fine portamento up
command = CMD_PORTAMENTOUP;
- param = 0xF0 | convert_psm_effect(param, bIsSinaria);
+ param = 0xF0 | convert_psm_porta(param, bNewFormat);
break;
case 0x0C: // portamento up
command = CMD_PORTAMENTOUP;
- param = convert_psm_effect(param, bIsSinaria);
+ param = convert_psm_porta(param, bNewFormat);
break;
case 0x0D: // fine portamento down
command = CMD_PORTAMENTODOWN;
- param = 0xF0 | convert_psm_effect(param, bIsSinaria);
+ param = 0xF0 | convert_psm_porta(param, bNewFormat);
break;
case 0x0E: // portamento down
command = CMD_PORTAMENTODOWN;
- param = convert_psm_effect(param, bIsSinaria);
+ param = convert_psm_porta(param, bNewFormat);
break;
case 0x0F: // tone portamento
command = CMD_TONEPORTAMENTO;
- param = convert_psm_effect(param, bIsSinaria);
+ if(!bNewFormat) param >>= 2;
break;
case 0x11: // glissando control
command = CMD_S3MCMDEX;
Modified: trunk/OpenMPT/soundlib/Load_s3m.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_s3m.cpp 2009-08-23 21:07:17 UTC (rev 339)
+++ trunk/OpenMPT/soundlib/Load_s3m.cpp 2009-08-24 11:43:54 UTC (rev 340)
@@ -513,10 +513,9 @@
//TODO: Check whether the 0xF0 mask is correct.
// (there are two bytes reserved from the header, so why 0xF0 mask?).
//nbo = (GetNumPatterns() + 15) & 0xF0;
- nbo = Order.GetLengthTailTrimmed() + 15;
+ nbo = Order.GetLengthTailTrimmed();
if(nbo > 0xF0) nbo = 0xF0;
- nbo = nbo & 0xF0;
- if (!nbo) nbo = 16;
+ if (!nbo) nbo = 1;
header[0x20] = nbo & 0xFF;
header[0x21] = nbo >> 8;
nbi = m_nInstruments;
Modified: trunk/OpenMPT/unlha/EXTRACT.CPP
===================================================================
--- trunk/OpenMPT/unlha/EXTRACT.CPP 2009-08-23 21:07:17 UTC (rev 339)
+++ trunk/OpenMPT/unlha/EXTRACT.CPP 2009-08-24 11:43:54 UTC (rev 340)
@@ -16,7 +16,7 @@
switch (method)
{
case 0:
- case 8:
+ case 10:
{
int len1 = m_dwOutputLen - (int)(outfp - m_lpOutputFile);
int len2 = m_dwStreamLen - infp;
@@ -30,14 +30,22 @@
crc = 0;
}
break;
- case 6: // -lzs-
+ case 8: // -lzs-
LzInterface.dicbit = 11;
decode(&LzInterface);
break;
case 1: // -lh1-
case 4: // -lh4-
- case 7: // -lz5-
+ case 9: // -lz5-
LzInterface.dicbit = 12;
+ decode(&LzInterface);
+ break;
+ case 6: // -lh6-
+ LzInterface.dicbit = 15;
+ decode(&LzInterface);
+ break;
+ case 7: // -lh7-
+ LzInterface.dicbit = 16;
default:
decode(&LzInterface);
}
Modified: trunk/OpenMPT/unlha/HUF.CPP
===================================================================
--- trunk/OpenMPT/unlha/HUF.CPP 2009-08-23 21:07:17 UTC (rev 339)
+++ trunk/OpenMPT/unlha/HUF.CPP 2009-08-24 11:43:54 UTC (rev 340)
@@ -4,7 +4,7 @@
#define NP (MAX_DICBIT + 1)
#define NT (USHRT_BIT + 3)
-#define PBIT 4 /* smallest integer such that (1 << PBIT) > NP */
+//#define PBIT 4 /* smallest integer such that (1 << PBIT) > NP */
#define TBIT 5 /* smallest integer such that (1 << TBIT) > NT */
#define NPT 0x80
@@ -16,8 +16,10 @@
t_freq[2 * NT - 1];
} HUFDATA;
-HUFDATA *gpHufData = NULL;
+//HUFDATA *gpHufData = NULL;
+#define gpHufData (*((HUFDATA **)&m_pHufData))
+
VOID CLhaArchive::InitHufTables()
{
gpHufData = (HUFDATA *)(m_pDecoderData + 4096);
@@ -104,7 +106,7 @@
blocksize = getbits(16);
read_pt_len(NT, TBIT, 3);
read_c_len();
- read_pt_len(NP, PBIT, -1);
+ read_pt_len(np, pbit, -1);
}
blocksize--;
j = gpHufData->c_table[bitbuf >> 4];
@@ -125,21 +127,28 @@
unsigned short j, mask;
j = gpHufData->pt_table[bitbuf >> (16 - 8)];
- if (j < NP) fillbuf(gpHufData->pt_len[j]);
+ if (j < np) fillbuf(gpHufData->pt_len[j]);
else {
fillbuf(8); mask = 1 << (16 - 1);
do {
j = (bitbuf & mask) ? right[j] : left[j];
mask >>= 1;
- } while (j >= NP);
+ } while (j >= np);
fillbuf(gpHufData->pt_len[j] - 8);
}
if (j != 0) j = (1 << (j - 1)) + getbits(j - 1);
return j;
}
-void CLhaArchive::decode_start_st1()
+void CLhaArchive::decode_start_st1(int dicbit)
{
+ switch (dicbit)
+ {
+ case 12:
+ case 13: pbit = 4; np = 14; break;
+ case 15: pbit = 5; np = 16; break;
+ case 16: pbit = 5; np = 17; break;
+ }
init_getbits();
blocksize = 0;
}
Modified: trunk/OpenMPT/unlha/LHEXT.CPP
===================================================================
--- trunk/OpenMPT/unlha/LHEXT.CPP 2009-08-23 21:07:17 UTC (rev 339)
+++ trunk/OpenMPT/unlha/LHEXT.CPP 2009-08-24 11:43:54 UTC (rev 340)
@@ -26,10 +26,10 @@
}
-const char *methods[10] =
+const char *methods[12] =
{
- "-lh0-", "-lh1-", "-lh2-", "-lh3-", "-lh4-",
- "-lh5-", "-lzs-", "-lz5-", "-lz4-", NULL
+ "-lh0-", "-lh1-", "-lh2-", "-lh3-", "-lh4-", "-lh5-",
+ "-lh6-", "-lh7-", "-lzs-", "-lz5-", "-lz4-", NULL
};
Modified: trunk/OpenMPT/unlha/SLIDE.CPP
===================================================================
--- trunk/OpenMPT/unlha/SLIDE.CPP 2009-08-23 21:07:17 UTC (rev 339)
+++ trunk/OpenMPT/unlha/SLIDE.CPP 2009-08-24 11:43:54 UTC (rev 340)
@@ -43,17 +43,19 @@
{
case 1: decode_start_dyn(); break;
case 2: decode_start_st0(); break;
- case 3: decode_start_st1(); break;
- case 4: decode_start_st1(); break;
- case 5: decode_start_lzs(); break;
- case 6: decode_start_lz5(text); break;
+ case 3: decode_start_st1(12); break;
+ case 4: decode_start_st1(13); break;
+ case 5: decode_start_st1(15); break;
+ case 6: decode_start_st1(16); break;
+ case 7: decode_start_lzs(); break;
+ case 8: decode_start_lz5(text); break;
default: decode_start_fix(); break;
}
#ifdef LHADEBUG
Log("Starting Decode (original size=%d)...\n", pinterface->original);
#endif
dicsiz1 = dicsiz - 1;
- offset = (pinterface->method == 6) ? 0x100 - 2 : 0x100 - 3;
+ offset = (pinterface->method == 8) ? 0x100 - 2 : 0x100 - 3;
count = 0;
loc = 0;
while (count < pinterface->original)
@@ -64,8 +66,10 @@
case 2: c = decode_c_st0(); break;
case 3: c = decode_c_st1(); break;
case 4: c = decode_c_st1(); break;
- case 5: c = decode_c_lzs(); break;
- case 6: c = decode_c_lz5(); break;
+ case 5: c = decode_c_st1(); break;
+ case 6: c = decode_c_st1(); break;
+ case 7: c = decode_c_lzs(); break;
+ case 8: c = decode_c_lz5(); break;
default: c = decode_c_dyn(); break;
}
if (c <= 255)
@@ -86,8 +90,10 @@
case 2: d = decode_p_st0(); break;
case 3: d = decode_p_st1(); break;
case 4: d = decode_p_st1(); break;
- case 5: d = decode_p_lzs(); break;
- case 6: d = decode_p_lz5(); break;
+ case 5: d = decode_p_st1(); break;
+ case 6: d = decode_p_st1(); break;
+ case 7: d = decode_p_lzs(); break;
+ case 8: d = decode_p_lz5(); break;
default: d = decode_p_st0(); break;
}
int j = c - offset;
Modified: trunk/OpenMPT/unlha/SLIDEHUF.H
===================================================================
--- trunk/OpenMPT/unlha/SLIDEHUF.H 2009-08-23 21:07:17 UTC (rev 339)
+++ trunk/OpenMPT/unlha/SLIDEHUF.H 2009-08-24 11:43:54 UTC (rev 340)
@@ -11,7 +11,7 @@
/* from slide.c */
-#define MAX_DICBIT 13
+#define MAX_DICBIT 16 // 13
#define MAX_DICSIZ (1 << MAX_DICBIT)
#define MATCHBIT 8 /* bits for MAXMATCH - THRESHOLD */
Modified: trunk/OpenMPT/unlha/UNLHA32.H
===================================================================
--- trunk/OpenMPT/unlha/UNLHA32.H 2009-08-23 21:07:17 UTC (rev 339)
+++ trunk/OpenMPT/unlha/UNLHA32.H 2009-08-24 11:43:54 UTC (rev 340)
@@ -72,9 +72,10 @@
unsigned short *freq;
unsigned char *buf;
unsigned short bufsiz, blocksize;
- unsigned int np;
+ unsigned int np, pbit;
+ void * m_pHufData;
int flag, flagcnt, matchpos, prev_char;
- unsigned short dicsiz, dicbit, maxmatch, loc;
+ unsigned int dicsiz, dicbit, maxmatch, loc;
unsigned short left[2 * NC - 1], right[2 * NC - 1];
protected:
@@ -113,7 +114,7 @@
protected:
// huf.cpp
VOID InitHufTables();
- void decode_start_st1();
+ void decode_start_st1(int dicbit);
void read_pt_len(short nn, short nbit, short i_special);
void read_c_len();
unsigned short decode_c_st1();
Modified: trunk/OpenMPT/unlha/Unlha.cpp
===================================================================
--- trunk/OpenMPT/unlha/Unlha.cpp 2009-08-23 21:07:17 UTC (rev 339)
+++ trunk/OpenMPT/unlha/Unlha.cpp 2009-08-24 11:43:54 UTC (rev 340)
@@ -69,6 +69,8 @@
m_lpOutputFile = 0;
m_dwOutputLen = 0;
m_pDecoderData = NULL;
+
+ gpHufData = NULL;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-08-23 22:13:59
|
Revision: 339
http://modplug.svn.sourceforge.net/modplug/?rev=339&view=rev
Author: saga-games
Date: 2009-08-23 21:07:17 +0000 (Sun, 23 Aug 2009)
Log Message:
-----------
[Fix] PSM Loading: Didn't work at all in the release build (only debug mode worked). Many more fixes to the loader code to also load PSMs from the game Sinaria. Furthermore, effect conversion seems to be about right now.
[Fix] XM Compatibility: Volume command Ux should not enable Vibrato at all, it only sets the vibrato speed
[Fix] XM Compatibility: Pxy effect was too deep
[Imp] XM Loading: Detect MPT-made XMs more reliably
[Imp] XM Loading: Make XMs with strange pattern header sizes load correctly (removed some code that was there to make really, really broken XMs load - would this work at all?)
[Imp] XM Saveing: Include version number in "made with" string.
Modified Paths:
--------------
trunk/OpenMPT/soundlib/Load_psm.cpp
trunk/OpenMPT/soundlib/Load_xm.cpp
trunk/OpenMPT/soundlib/Snd_fx.cpp
Modified: trunk/OpenMPT/soundlib/Load_psm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-22 22:47:59 UTC (rev 338)
+++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-23 21:07:17 UTC (rev 339)
@@ -3,17 +3,19 @@
* Authors: Johannes Schultz
*
* This is partly based on http://www.shikadi.net/moddingwiki/ProTracker_Studio_Module
- * and partly reverse-engineered.
+ * and partly reverse-engineered. Also thanks to the author of foo_dumb, the source code
+ * gave me a few clues. :)
*
* What's playing?
- * - Epic Pinball - Seems to be working perfectly with linear freq slides enabled
+ * - Epic Pinball - Perfect! (the old tunes in PSM16 format are not supported)
* - Extreme Pinball - Default tempo / speed / restart position of subtunes is missing.
* I'm using the last default values, restart position is still completely missing
- * - Jazz Jackrabbit - Hmm, I don't like some of the portas (BONUS.PSM - the guitar portamento is too "deep"), but apart from that it's great.
+ * - Jazz Jackrabbit - Perfect!
* - One Must Fall! - Perfect! (I modelled the volume slide and portamento conversion after this, as I got the original MTM files)
* - Silverball - Currently not supported (old PSM16 format)
+ * - Sinaria - Seems to work more or less (never played the game, so I can't really tell...)
*
- * Effect conversion should be about right, however I have my doubts wheter linear freq slides are used or not.
+ * Effect conversion should be about right...
*/
#include "stdafx.h"
@@ -36,44 +38,52 @@
};
-struct PSMSAMPLEHEADERTEST // apparently, this is wrong.
+struct PSMSAMPLEHEADER // Regular sample header
{
- CHAR sampleFormat[9];
+ BYTE flags;
+ CHAR fileName[8]; // Filename of the original module (without extension)
DWORD sampleID; // INS0...INS9 (only last digit of sample ID, i.e. sample 1 and sample 11 are equal)
CHAR sampleName[33];
CHAR unknown1[6]; // 00 00 00 00 00 FF
WORD sampleNumber;
+ DWORD sampleLength;
DWORD loopStart;
- CHAR loop; // 1 = loop
- CHAR unknown2[3]; // 00 00 00 00 00 FF
DWORD loopEnd; // FF FF FF FF = end of sample
WORD unknown3;
- CHAR defaultVolume;
+ BYTE defaultVolume;
DWORD unknown4;
WORD C5Freq;
- CHAR padding[21]; // 00 ... 00
+ CHAR unknown5[21]; // 00 ... 00
};
-struct PSMSAMPLEHEADER // Use this instead
+struct PSMSAMPLEHEADERSINARIA // Sinaria sample header
{
BYTE flags;
- CHAR fileName[8];
- DWORD sampleID; // INS0...INS9 (only last digit of sample ID, i.e. sample 1 and sample 11 are equal)
+ CHAR fileName[8]; // Filename of the original module (without extension)
+ CHAR sampleID[8]; // INS0...INS99999
CHAR sampleName[33];
CHAR unknown1[6]; // 00 00 00 00 00 FF
WORD sampleNumber;
DWORD sampleLength;
DWORD loopStart;
- DWORD loopEnd; // FF FF FF FF = end of sample
+ DWORD loopEnd;
WORD unknown3;
- CHAR defaultVolume;
- DWORD unknown4;
+ BYTE unknown4;
+ BYTE defaultVolume;
+ DWORD unknown5;
WORD C5Freq;
- CHAR unknown5[21]; // 00 ... 00
+ CHAR unknown6[16]; // 00 ... 00
};
-
#pragma pack()
+BYTE convert_psm_effect(BYTE param, bool bIsSinaria)
+{
+ if(bIsSinaria)
+ return param;
+ else
+ return (param >> 2);
+}
+
bool CSoundFile::ReadPSM(const LPCBYTE lpStream, const DWORD dwMemLength)
//-----------------------------------------------------------------------
{
@@ -81,6 +91,7 @@
if( dwMemPos > dwMemLength || x > dwMemLength - dwMemPos ) return false;
DWORD dwMemPos = 0;
+ bool bIsSinaria = false; // The game "Sinaria" uses a slightly modified PSM structure
ASSERT_CAN_READ(12);
PSMHEADER shdr;
@@ -92,7 +103,7 @@
// Yep, this seems to be a valid file.
m_nType = MOD_TYPE_PSM;
- m_dwSongFlags |= SONG_LINEARSLIDES; // Seems to be correct for Epic Pinball and Jazz Jackrabbit?
+ //m_dwSongFlags |= SONG_LINEARSLIDES; // TODO
m_nChannels = 0;
dwMemPos += 12;
@@ -137,10 +148,11 @@
// Pattern ID (something like "P0 " or "P13 ") follows
if(memcmp(lpStream + dwMemPos + 4, "P", 1)) return false;
+ if(!memcmp(lpStream + dwMemPos + 4, "PATT", 4)) bIsSinaria = true;
char patternID[4];
- memcpy(patternID, lpStream + dwMemPos + 5, 3);
+ memcpy(patternID, lpStream + dwMemPos + 5 + (bIsSinaria ? 3 : 0), 3);
patternID[3] = 0;
- patternOffsets.push_back(dwMemPos + 8);
+ patternOffsets.push_back(dwMemPos + 8 + (bIsSinaria ? 4 : 0));
patternIDs.push_back(atoi(patternID));
numPatterns++;
@@ -179,25 +191,22 @@
CHAR cDate[7];
memcpy(cDate, lpStream + dwChunkPos, 6);
cDate[6] = 0;
- sComment += "\r\nDate: ";
+ sComment += " - Date: ";
sComment += cDate;
break;
case 0x484C504F: // "OPLH" - Order list, channel + module settings
{
if(subChunkSize < 9) return false;
- // First byte = "Memory alloc, roughly ordlen + 10, if too small, song freezes"
- if(LittleEndian(*(DWORD *)(lpStream + dwChunkPos + 1)) != 0xFF000C00 // "Something"
- || LittleEndian(*(DWORD *)(lpStream + dwChunkPos + 5)) != 0x00010000) // "Something"
- return false;
+ // First two bytes = "Memory alloc, roughly ordlen + 10, if too small, song freezes"
// Now, the interesting part begins!
- DWORD dwSettingsOffset = dwChunkPos + 9;
+ DWORD dwSettingsOffset = dwChunkPos + 2;
while(dwSettingsOffset - dwChunkPos + 1 < subChunkSize)
{
switch(lpStream[dwSettingsOffset])
{
- case 0x00: // Seems to be the End item
+ case 0x00: // End
dwSettingsOffset += 1;
break;
@@ -207,7 +216,7 @@
for(PATTERNINDEX i = 0; i < patternIDs.size(); i++)
{
char patternID[4];
- memcpy(patternID, lpStream + dwSettingsOffset + 2, 3);
+ memcpy(patternID, lpStream + dwSettingsOffset + 2 + (bIsSinaria ? 3 : 0), 3);
patternID[3] = 0;
DWORD nPattern = atoi(patternID);
if(patternIDs[i] == nPattern)
@@ -216,25 +225,29 @@
break;
}
}
- dwSettingsOffset += 5;
+ dwSettingsOffset += 5 + (bIsSinaria ? 4 : 0);
break;
case 0x04:
/* It looks like the 2nd number of this chunk could be the restart position,
where position = ((number < 15) ? 0 : (number - 15)) */
+
+ //uint32 pos = lpStream[dwSettingsOffset + 1] | (lpStream[dwSettingsOffset + 2] << 8);
+
+ // NOTE: This should not be global! (Extreme Pinball!!!)
#ifdef DEBUG
{
char s[32];
wsprintf(s, " - restart %d", (lpStream[dwSettingsOffset + 1] < 15) ? 0 : lpStream[dwSettingsOffset + 1] - 15);
sComment += s;
- dwSettingsOffset += 3;
}
#endif
+ dwSettingsOffset += 3;
break;
case 0x07: // Default Speed
if(dwSettingsOffset - dwChunkPos + 2 > subChunkSize) break;
- // NOTE: This should not be global! (Extreme Pinball!!!)
+ // Same note as above!
m_nDefaultSpeed = lpStream[dwSettingsOffset + 1];
dwSettingsOffset += 2;
break;
@@ -246,19 +259,49 @@
dwSettingsOffset += 2;
break;
- case 0x0D: // This is a channel header
+ case 0x0C: // Sample map table (???)
+ if(dwSettingsOffset - dwChunkPos + 7 > subChunkSize) break;
+
+ if (lpStream[dwSettingsOffset + 1] != 0x00 || lpStream[dwSettingsOffset + 2] != 0xFF ||
+ lpStream[dwSettingsOffset + 3] != 0x00 || lpStream[dwSettingsOffset + 4] != 0x00 ||
+ lpStream[dwSettingsOffset + 5] != 0x01 || lpStream[dwSettingsOffset + 6] != 0x00)
+ return false;
+ dwSettingsOffset += 7;
+ break;
+
+ case 0x0D: // Channel panning table
if(dwSettingsOffset - dwChunkPos + 4 > subChunkSize) break;
- ChnSettings[min(lpStream[dwSettingsOffset + 1], pSong->numChannels)].nPan = lpStream[dwSettingsOffset + 2];
- // Last byte: "either 0, 2 or 4 (Some sort of priority?)"
+
+ {
+ CHANNELINDEX nChn = min(lpStream[dwSettingsOffset + 1], pSong->numChannels);
+ switch(lpStream[dwSettingsOffset + 3])
+ {
+ case 0:
+ ChnSettings[nChn].nPan = lpStream[dwSettingsOffset + 2];
+ break;
+
+ case 2:
+ ChnSettings[nChn].nPan = 128;
+ ChnSettings[nChn].dwFlags |= CHN_SURROUND;
+ break;
+
+ case 4:
+ ChnSettings[nChn].nPan = 128;
+ break;
+
+ }
+ }
dwSettingsOffset += 4;
break;
- case 0x0E: // Unknown - "0E <ChnID> FF"
+ case 0x0E: // Channel volume table
if(dwSettingsOffset - dwChunkPos + 3 > subChunkSize) break;
+ ChnSettings[min(lpStream[dwSettingsOffset + 1], pSong->numChannels)].nVolume = (lpStream[dwSettingsOffset + 2] >> 2) + 1;
+
dwSettingsOffset += 3;
break;
- default: // How the hell should this happen? I've listened through all existing (original) PSM files. :)
+ default: // How the hell should this happen? I've listened through almost all existing (original) PSM files. :)
CString s;
s.Format("Please report to the OpenMPT team: Unknown chunk %d found at position %d (in the OPLH chunk of this PSM file)", lpStream[dwSettingsOffset], dwSettingsOffset);
MessageBox(NULL, s, TEXT("OpenMPT PSM import"), MB_ICONERROR);
@@ -271,6 +314,29 @@
}
break;
+ case 0x4E415050: // PPAN - Channel panning table (used in Sinaria)
+ if(subChunkSize & 1) return false;
+ for(DWORD i = 0; i < subChunkSize; i += 2)
+ {
+ if((i >> 1) >= m_nChannels) break;
+ switch(lpStream[dwChunkPos + i])
+ {
+ case 0:
+ ChnSettings[i >> 1].nPan = lpStream[dwChunkPos + i + 1] - 128;
+ break;
+
+ case 2:
+ ChnSettings[i >> 1].nPan = 128;
+ ChnSettings[i >> 1].dwFlags |= CHN_SURROUND;
+ break;
+
+ case 4:
+ ChnSettings[i >> 1].nPan = 128;
+ break;
+ }
+ }
+ break;
+
case 0x54544150: // PATT - Pattern list
// We don't really need this.
break;
@@ -291,7 +357,7 @@
break;
case 0x504D5344: // DSMP - Samples
-
+ if(!bIsSinaria)
{
if(chunkSize < sizeof(PSMSAMPLEHEADER)) return false;
PSMSAMPLEHEADER *pSample = (PSMSAMPLEHEADER *)(lpStream + dwMemPos);
@@ -310,11 +376,34 @@
Samples[smp].nPan = 128;
Samples[smp].nVolume = (pSample->defaultVolume + 1) << 1;
Samples[smp].uFlags = (pSample->flags & 0x80) ? CHN_LOOP : 0;
- if(Samples[smp].nLoopStart > 0) Samples[smp].nLoopStart--;
if(Samples[smp].nLoopEnd == 0xFFFFFF) Samples[smp].nLoopEnd = Samples[smp].nLength;
// Delta-encoded samples
ReadSample(&Samples[smp], RS_PCM8D, (LPCSTR)(lpStream + dwMemPos + sizeof(PSMSAMPLEHEADER)), Samples[smp].nLength);
+ } else
+ {
+ // Sinaria uses a slightly different sample header
+ if(chunkSize < sizeof(PSMSAMPLEHEADERSINARIA)) return false;
+ PSMSAMPLEHEADERSINARIA *pSample = (PSMSAMPLEHEADERSINARIA *)(lpStream + dwMemPos);
+ SAMPLEINDEX smp = (SAMPLEINDEX)(LittleEndianW(pSample->sampleNumber) + 1);
+ m_nSamples = max(m_nSamples, smp);
+ memcpy(m_szNames[smp], pSample->sampleName, 31);
+ m_szNames[smp][31] = 0;
+ memcpy(Samples[smp].filename, pSample->fileName, 8);
+ Samples[smp].filename[8] = 0;
+
+ Samples[smp].nGlobalVol = 0x40;
+ Samples[smp].nC5Speed = LittleEndianW(pSample->C5Freq);
+ Samples[smp].nLength = LittleEndian(pSample->sampleLength);
+ Samples[smp].nLoopStart = LittleEndian(pSample->loopStart);
+ Samples[smp].nLoopEnd = LittleEndian(pSample->loopEnd);
+ Samples[smp].nPan = 128;
+ Samples[smp].nVolume = (pSample->defaultVolume + 1) << 1;
+ Samples[smp].uFlags = (pSample->flags & 0x80) ? CHN_LOOP : 0;
+ if(Samples[smp].nLoopEnd == 0xFFFFFF) Samples[smp].nLoopEnd = Samples[smp].nLength;
+
+ // Delta-encoded samples
+ ReadSample(&Samples[smp], RS_PCM8D, (LPCSTR)(lpStream + dwMemPos + sizeof(PSMSAMPLEHEADERSINARIA)), Samples[smp].nLength);
}
break;
@@ -369,10 +458,16 @@
if(dwRowOffset + 1 > dwMemLength) return false;
// Note present
BYTE bNote = lpStream[dwRowOffset];
- if(bNote == 0xFF)
- bNote = NOTE_NOTECUT;
- else
- bNote = (bNote & 0x0F) + 12 * (bNote >> 4) + 13;
+ if(!bIsSinaria)
+ {
+ if(bNote == 0xFF)
+ bNote = NOTE_NOTECUT;
+ else
+ bNote = (bNote & 0x0F) + 12 * (bNote >> 4) + 13;
+ } else
+ {
+ bNote += 36;
+ }
m->note = bNote;
dwRowOffset++;
}
@@ -423,23 +518,23 @@
// Portamento
case 0x0B: // fine portamento up
command = CMD_PORTAMENTOUP;
- param = 0xF0 | (param >> 1);
+ param = 0xF0 | convert_psm_effect(param, bIsSinaria);
break;
case 0x0C: // portamento up
command = CMD_PORTAMENTOUP;
- param >>= 1;
+ param = convert_psm_effect(param, bIsSinaria);
break;
case 0x0D: // fine portamento down
command = CMD_PORTAMENTODOWN;
- param = 0xF0 | (param >> 1);
+ param = 0xF0 | convert_psm_effect(param, bIsSinaria);
break;
case 0x0E: // portamento down
command = CMD_PORTAMENTODOWN;
- param >>= 1;
+ param = convert_psm_effect(param, bIsSinaria);
break;
case 0x0F: // tone portamento
command = CMD_TONEPORTAMENTO;
- param >>= 2;
+ param = convert_psm_effect(param, bIsSinaria);
break;
case 0x11: // glissando control
command = CMD_S3MCMDEX;
@@ -502,6 +597,7 @@
case 0x33: // position jump
command = CMD_POSITIONJUMP;
param >>= 1;
+ dwRowOffset += 1;
break;
case 0x34: // pattern break
command = CMD_PATTERNBREAK;
@@ -543,8 +639,11 @@
break;
default:
+ #ifdef DEBUG
ASSERT(false);
- //command = CMD_NONE;
+ #else
+ command = CMD_NONE;
+ #endif
break;
}
Modified: trunk/OpenMPT/soundlib/Load_xm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_xm.cpp 2009-08-22 22:47:59 UTC (rev 338)
+++ trunk/OpenMPT/soundlib/Load_xm.cpp 2009-08-23 21:07:17 UTC (rev 339)
@@ -109,7 +109,7 @@
if(lpStream[17 + i] == 0) bProbablyMadeWithModPlug = true;
if (!memcmp((LPCSTR)lpStream + 0x26, "FastTracker v2.00 ", 20) && bProbablyMadeWithModPlug) bMadeWithModPlug = true;
- if (!memcmp((LPCSTR)lpStream + 0x26, "Open ModPlug Tracker", 20)) bMadeWithModPlug = true;
+ if (!memcmp((LPCSTR)lpStream + 0x26, "OpenMPT ", 8)) bMadeWithModPlug = true;
dwHdrSize = LittleEndian(*((DWORD *)(lpStream+60)));
norders = LittleEndianW(*((WORD *)(lpStream+64)));
@@ -180,20 +180,20 @@
UINT ipatmap = pattern_map[ipat];
DWORD dwSize = 0;
WORD rows=64, packsize=0;
- dwSize = LittleEndian(*((DWORD *)(lpStream+dwMemPos)));
- while ((dwMemPos + dwSize >= dwMemLength) || (dwSize & 0xFFFFFF00))
+ dwSize = LittleEndian(*((DWORD *)(lpStream + dwMemPos)));
+ /*while ((dwMemPos + dwSize >= dwMemLength) || (dwSize & 0xFFFFFF00))
{
if (dwMemPos + 4 >= dwMemLength) break;
dwMemPos++;
dwSize = LittleEndian(*((DWORD *)(lpStream+dwMemPos)));
- }
- rows = LittleEndianW(*((WORD *)(lpStream+dwMemPos+5)));
+ }*/
+ rows = LittleEndianW(*((WORD *)(lpStream + dwMemPos + 5)));
// -> CODE#0008
// -> DESC="#define to set pattern size"
// if ((!rows) || (rows > 256)) rows = 64;
if ((!rows) || (rows > MAX_PATTERN_ROWS)) rows = 64;
// -> BEHAVIOUR_CHANGE#0008
- packsize = LittleEndianW(*((WORD *)(lpStream+dwMemPos+7)));
+ packsize = LittleEndianW(*((WORD *)(lpStream + dwMemPos + 7)));
if (dwMemPos + dwSize + 4 > dwMemLength) return true;
dwMemPos += dwSize;
if (dwMemPos + packsize > dwMemLength) return true;
@@ -694,9 +694,9 @@
fwrite("Extended Module: ", 17, 1, f);
fwrite(m_szNames[0], 20, 1, f);
s[0] = 0x1A;
- lstrcpy((LPSTR)&s[1], (nPacking) ? "MOD Plugin packed " : "Open ModPlug Tracker");
- s[21] = 0x04;
- s[22] = 0x01;
+ lstrcpy((LPSTR)&s[1], (nPacking) ? "MOD Plugin packed " : "OpenMPT " MPT_VERSION_STR " ");
+ s[21] = 0x04; // Version number
+ s[22] = 0x01; // XM Format v1.04
fwrite(&s[0], 23, 1, f);
// Writing song header
memset(&header, 0, sizeof(header));
Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-08-22 22:47:59 UTC (rev 338)
+++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-08-23 21:07:17 UTC (rev 339)
@@ -1420,7 +1420,10 @@
break;
case VOLCMD_VIBRATOSPEED:
- Vibrato(pChn, vol << 4);
+ if(IsCompatibleMode(TRK_FASTTRACKER2))
+ pChn->nVibratoSpeed = vol & 0x0F;
+ else
+ Vibrato(pChn, vol << 4);
break;
case VOLCMD_VIBRATODEPTH:
@@ -2386,6 +2389,8 @@
{
if (param & 0x0F) nPanSlide = -(int)((param & 0x0F) << 2);
else nPanSlide = (int)((param & 0xF0) >> 2);
+ if(IsCompatibleMode(TRK_FASTTRACKER2))
+ nPanSlide >>= 2;
}
}
if (nPanSlide)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-08-22 22:48:10
|
Revision: 338
http://modplug.svn.sourceforge.net/modplug/?rev=338&view=rev
Author: saga-games
Date: 2009-08-22 22:47:59 +0000 (Sat, 22 Aug 2009)
Log Message:
-----------
[Fix] Macro config: "Show All" FX display starts at 1 instead of 0, like all other FX enumerations
[Imp] PSM Loader: Several improvements; Near-perfect effect conversion.
[Imp] XM Loader: Detecting MPT-Made XM files more reliably
[Imp] Playback: If restart position is 0 and a subtune is played (i.e. a tune separated with a "---" pattern), OpenMPT will now try to jump back to the first order of this subtune instead.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/dlg_misc.cpp
trunk/OpenMPT/soundlib/Load_psm.cpp
trunk/OpenMPT/soundlib/Load_xm.cpp
trunk/OpenMPT/soundlib/Sndmix.cpp
Modified: trunk/OpenMPT/mptrack/dlg_misc.cpp
===================================================================
--- trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-08-22 10:21:22 UTC (rev 337)
+++ trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-08-22 22:47:59 UTC (rev 338)
@@ -2096,7 +2096,7 @@
{
pVstPlugin->GetParamName(param, s, 256);
paramName = s;
- line.Format("FX%d: %s\t Param %d (%x): %s\n", plug, plugName, param, param+80, paramName);
+ line.Format("FX%d: %s\t Param %d (%x): %s\n", plug + 1, plugName, param, param+80, paramName);
message += line;
}
}
Modified: trunk/OpenMPT/soundlib/Load_psm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-22 10:21:22 UTC (rev 337)
+++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-22 22:47:59 UTC (rev 338)
@@ -6,12 +6,14 @@
* and partly reverse-engineered.
*
* What's playing?
- * - Epic Pinball - Seems to be working perfectly, apart from some portas? (esp. Deep Sea, Shareware Info - Linear freq slides needed!?)
+ * - Epic Pinball - Seems to be working perfectly with linear freq slides enabled
* - Extreme Pinball - Default tempo / speed / restart position of subtunes is missing.
* I'm using the last default values, restart position is still completely missing
- * - Jazz Jackrabbit - Hmm, I don't like some of the portas, but apart from that it's great. (same problem as Epic Pinball)
+ * - Jazz Jackrabbit - Hmm, I don't like some of the portas (BONUS.PSM - the guitar portamento is too "deep"), but apart from that it's great.
* - One Must Fall! - Perfect! (I modelled the volume slide and portamento conversion after this, as I got the original MTM files)
* - Silverball - Currently not supported (old PSM16 format)
+ *
+ * Effect conversion should be about right, however I have my doubts wheter linear freq slides are used or not.
*/
#include "stdafx.h"
@@ -55,7 +57,7 @@
struct PSMSAMPLEHEADER // Use this instead
{
BYTE flags;
- CHAR sampleFormat[8];
+ CHAR fileName[8];
DWORD sampleID; // INS0...INS9 (only last digit of sample ID, i.e. sample 1 and sample 11 are equal)
CHAR sampleName[33];
CHAR unknown1[6]; // 00 00 00 00 00 FF
@@ -72,13 +74,6 @@
#pragma pack()
-BYTE convert_psm_param(BYTE param)
-{
- // special conversion of some PSM parameters. is this done correctly?
- return param >> 1;
- //return (param + 1) >> 1;
-}
-
bool CSoundFile::ReadPSM(const LPCBYTE lpStream, const DWORD dwMemLength)
//-----------------------------------------------------------------------
{
@@ -97,7 +92,7 @@
// Yep, this seems to be a valid file.
m_nType = MOD_TYPE_PSM;
- //m_dwSongFlags |= SONG_LINEARSLIDES; // TODO
+ m_dwSongFlags |= SONG_LINEARSLIDES; // Seems to be correct for Epic Pinball and Jazz Jackrabbit?
m_nChannels = 0;
dwMemPos += 12;
@@ -142,8 +137,11 @@
// Pattern ID (something like "P0 " or "P13 ") follows
if(memcmp(lpStream + dwMemPos + 4, "P", 1)) return false;
+ char patternID[4];
+ memcpy(patternID, lpStream + dwMemPos + 5, 3);
+ patternID[3] = 0;
patternOffsets.push_back(dwMemPos + 8);
- patternIDs.push_back(*(DWORD *)(lpStream + dwMemPos + 4));
+ patternIDs.push_back(atoi(patternID));
numPatterns++;
// Convert later as we have to know how many channels there are.
@@ -177,12 +175,12 @@
{
case 0x45544144: // "DATE" - Song date (YYMMDD)
if(subChunkSize < 6) break;
+
CHAR cDate[7];
memcpy(cDate, lpStream + dwChunkPos, 6);
cDate[6] = 0;
sComment += "\r\nDate: ";
sComment += cDate;
- // We don't care about the date.
break;
case 0x484C504F: // "OPLH" - Order list, channel + module settings
@@ -199,12 +197,20 @@
{
switch(lpStream[dwSettingsOffset])
{
+ case 0x00: // Seems to be the End item
+ dwSettingsOffset += 1;
+ break;
+
case 0x01: // Order list item
if(dwSettingsOffset - dwChunkPos + 5 > subChunkSize) return false;
// Pattern name follows - find pattern (this is the orderlist)
for(PATTERNINDEX i = 0; i < patternIDs.size(); i++)
{
- if(patternIDs[i] == *(DWORD *)(lpStream + dwSettingsOffset + 1))
+ char patternID[4];
+ memcpy(patternID, lpStream + dwSettingsOffset + 2, 3);
+ patternID[3] = 0;
+ DWORD nPattern = atoi(patternID);
+ if(patternIDs[i] == nPattern)
{
Order.push_back(i);
break;
@@ -213,9 +219,17 @@
dwSettingsOffset += 5;
break;
- case 0x04: // "end?" "04 03 00 00" in most cases (not Extreme Pinball - maybe restart positions are dumped here?)
- if(dwSettingsOffset - dwChunkPos + 4 > subChunkSize) return false;
- dwSettingsOffset += 4;
+ case 0x04:
+ /* It looks like the 2nd number of this chunk could be the restart position,
+ where position = ((number < 15) ? 0 : (number - 15)) */
+ #ifdef DEBUG
+ {
+ char s[32];
+ wsprintf(s, " - restart %d", (lpStream[dwSettingsOffset + 1] < 15) ? 0 : lpStream[dwSettingsOffset + 1] - 15);
+ sComment += s;
+ dwSettingsOffset += 3;
+ }
+ #endif
break;
case 0x07: // Default Speed
@@ -243,12 +257,8 @@
if(dwSettingsOffset - dwChunkPos + 3 > subChunkSize) break;
dwSettingsOffset += 3;
break;
-
- case 0x00: // "end?"
- dwSettingsOffset += 1;
- break;
- default: // How the hell should this happen? I've listened through all existing PSM files. :)
+ default: // How the hell should this happen? I've listened through all existing (original) PSM files. :)
CString s;
s.Format("Please report to the OpenMPT team: Unknown chunk %d found at position %d (in the OPLH chunk of this PSM file)", lpStream[dwSettingsOffset], dwSettingsOffset);
MessageBox(NULL, s, TEXT("OpenMPT PSM import"), MB_ICONERROR);
@@ -288,7 +298,9 @@
SAMPLEINDEX smp = (SAMPLEINDEX)(LittleEndianW(pSample->sampleNumber) + 1);
m_nSamples = max(m_nSamples, smp);
memcpy(m_szNames[smp], pSample->sampleName, 31);
- m_szNames[0][31] = 0;
+ m_szNames[smp][31] = 0;
+ memcpy(Samples[smp].filename, pSample->fileName, 8);
+ Samples[smp].filename[8] = 0;
Samples[smp].nGlobalVol = 0x40;
Samples[smp].nC5Speed = LittleEndianW(pSample->C5Freq);
@@ -317,7 +329,6 @@
if(m_nChannels == 0)
return false;
-
// Now that we know the number of channels, we can go through all the patterns.
for(PATTERNINDEX i = 0; i < numPatterns; i++)
{
@@ -350,7 +361,7 @@
if(dwRowOffset + 1 > dwMemLength) return false;
BYTE mask = lpStream[dwRowOffset];
// Point to the correct channel
- MODCOMMAND *m = row_data + min(m_nChannels, lpStream[dwRowOffset + 1]);
+ MODCOMMAND *m = row_data + min(m_nChannels - 1, lpStream[dwRowOffset + 1]);
dwRowOffset += 2;
if(mask & 0x80)
@@ -358,7 +369,10 @@
if(dwRowOffset + 1 > dwMemLength) return false;
// Note present
BYTE bNote = lpStream[dwRowOffset];
- bNote = (bNote & 0x0F) + 12 * (bNote >> 4) + 13;
+ if(bNote == 0xFF)
+ bNote = NOTE_NOTECUT;
+ else
+ bNote = (bNote & 0x0F) + 12 * (bNote >> 4) + 13;
m->note = bNote;
dwRowOffset++;
}
@@ -376,7 +390,7 @@
if(dwRowOffset + 1 > dwMemLength) return false;
// Volume present
m->volcmd = VOLCMD_VOLUME;
- m->vol = (min(lpStream[dwRowOffset], 127)) >> 1;
+ m->vol = (min(lpStream[dwRowOffset], 127) + 1) >> 1;
dwRowOffset++;
}
@@ -409,29 +423,29 @@
// Portamento
case 0x0B: // fine portamento up
command = CMD_PORTAMENTOUP;
- param = 0xF0 | convert_psm_param(param);
+ param = 0xF0 | (param >> 1);
break;
case 0x0C: // portamento up
command = CMD_PORTAMENTOUP;
- param = convert_psm_param(param);
+ param >>= 1;
break;
case 0x0D: // fine portamento down
command = CMD_PORTAMENTODOWN;
- param = 0xF0 | convert_psm_param(param);
+ param = 0xF0 | (param >> 1);
break;
case 0x0E: // portamento down
command = CMD_PORTAMENTODOWN;
- param = convert_psm_param(param);
+ param >>= 1;
break;
case 0x0F: // tone portamento
command = CMD_TONEPORTAMENTO;
- param = convert_psm_param(param);
+ param >>= 2;
break;
- case 0x10: // glissando control
+ case 0x11: // glissando control
command = CMD_S3MCMDEX;
param = 0x10 | (param & 0x01);
break;
- case 0x11: // tone portamento + volslide up
+ case 0x10: // tone portamento + volslide up
command = CMD_TONEPORTAVOL;
param = param & 0xF0;
break;
@@ -472,9 +486,8 @@
param = lpStream[dwRowOffset + 2];
dwRowOffset += 2;
break;
- case 0x2A: // set finetune
- command = CMD_S3MCMDEX;
- param = 0x40 | (param & 0x0F);
+ case 0x2A: // retrigger
+ command = CMD_RETRIG;
break;
case 0x2B: // note cut
command = CMD_S3MCMDEX;
@@ -488,9 +501,11 @@
// Position change
case 0x33: // position jump
command = CMD_POSITIONJUMP;
+ param >>= 1;
break;
case 0x34: // pattern break
command = CMD_PATTERNBREAK;
+ param >>= 1;
break;
case 0x35: // loop pattern
command = CMD_S3MCMDEX;
@@ -514,16 +529,22 @@
command = CMD_ARPEGGIO;
break;
case 0x48: // set finetune
- command = CMD_MODCMDEX;
- param = 0x50 | (param & 0x0F);
+ command = CMD_S3MCMDEX;
+ param = 0x20 | (param & 0x0F);
break;
case 0x49: // set balance
command = CMD_S3MCMDEX;
param = 0x80 | (param & 0x0F);
break;
+ case CMD_MODCMDEX:
+ // for some strange home-made tunes
+ command = CMD_S3MCMDEX;
+ break;
+
default:
- //ASSERT(false);
+ ASSERT(false);
+ //command = CMD_NONE;
break;
}
Modified: trunk/OpenMPT/soundlib/Load_xm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_xm.cpp 2009-08-22 10:21:22 UTC (rev 337)
+++ trunk/OpenMPT/soundlib/Load_xm.cpp 2009-08-22 22:47:59 UTC (rev 338)
@@ -95,14 +95,22 @@
BYTE samples_used[(MAX_SAMPLES+7)/8];
UINT unused_samples;
- bool bMadeWithModPlug = false;
+ bool bMadeWithModPlug = false, bProbablyMadeWithModPlug = false;
// set this here already because XMs compressed with BoobieSqueezer will exit the function early
SetModFlag(MSF_COMPATIBLE_PLAY, true);
m_nChannels = 0;
if ((!lpStream) || (dwMemLength < 0xAA)) return false; // the smallest XM I know is 174 Bytes
if (_strnicmp((LPCSTR)lpStream, "Extended Module", 15)) return false;
+
memcpy(m_szNames[0], lpStream + 17, 20);
+ // look for null-terminated song name - that's most likely a tune made with modplug
+ for(int i = 0; i < 20; i++)
+ if(lpStream[17 + i] == 0) bProbablyMadeWithModPlug = true;
+
+ if (!memcmp((LPCSTR)lpStream + 0x26, "FastTracker v2.00 ", 20) && bProbablyMadeWithModPlug) bMadeWithModPlug = true;
+ if (!memcmp((LPCSTR)lpStream + 0x26, "Open ModPlug Tracker", 20)) bMadeWithModPlug = true;
+
dwHdrSize = LittleEndian(*((DWORD *)(lpStream+60)));
norders = LittleEndianW(*((WORD *)(lpStream+64)));
if ((!norders) || (norders > MAX_ORDERS)) return false;
@@ -328,6 +336,7 @@
min(ihsize - sizeof(XMINSTRUMENTHEADER), sizeof(XMSAMPLEHEADER)));
xmsh.shsize = LittleEndian(xmsh.shsize);
+ if(xmsh.shsize == 0 && bProbablyMadeWithModPlug) bMadeWithModPlug = true;
for (int i = 0; i < 24; ++i) {
xmsh.venv[i] = LittleEndianW(xmsh.venv[i]);
Modified: trunk/OpenMPT/soundlib/Sndmix.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndmix.cpp 2009-08-22 10:21:22 UTC (rev 337)
+++ trunk/OpenMPT/soundlib/Sndmix.cpp 2009-08-22 22:47:59 UTC (rev 338)
@@ -645,6 +645,21 @@
if (!m_nRepeatCount) return FALSE;
+ ORDERINDEX nRestartPosOverride = m_nRestartPos;
+ if(!m_nRestartPos && m_nCurrentPattern <= Order.size())
+ {
+ // if we're in a subtune and there's no restart position, go to the first order of the subtune
+ for(ORDERINDEX iOrd = m_nCurrentPattern - 1; iOrd > 0; iOrd--)
+ {
+ if(Order[iOrd] == Order.GetInvalidPatIndex())
+ {
+ // Jump back to first order of this subtune
+ nRestartPosOverride = iOrd + 1;
+ break;
+ }
+ }
+ }
+
if(CMainFrame::GetMainFrame())
{
// If channel resetting is disabled, we will emulate a pattern break
@@ -652,7 +667,7 @@
m_dwSongFlags |= SONG_BREAKTOROW;
}
- if (!m_nRestartPos && !(m_dwSongFlags & SONG_BREAKTOROW))
+ if (!nRestartPosOverride && !(m_dwSongFlags & SONG_BREAKTOROW))
{
//rewbs.instroVSTi: stop all VSTi at end of song, if looping.
StopAllVsti();
@@ -690,7 +705,7 @@
//Handle Repeat position
if (m_nRepeatCount > 0) m_nRepeatCount--;
- m_nCurrentPattern = m_nRestartPos;
+ m_nCurrentPattern = nRestartPosOverride;
//m_nRow = 0;
m_dwSongFlags &= ~SONG_BREAKTOROW;
//If restart pos points to +++, move along
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-08-22 10:21:34
|
Revision: 337
http://modplug.svn.sourceforge.net/modplug/?rev=337&view=rev
Author: saga-games
Date: 2009-08-22 10:21:22 +0000 (Sat, 22 Aug 2009)
Log Message:
-----------
[Fix] A brand new PSM loader! Ditched the old and buggy loader as the new loader works way better, it can even handle modules from Extreme Pinball. Some finetuning is still mandatory, though.
[Fix] S3M Loading: Disable loop for files with very short loop at the beginning of the sample
Modified Paths:
--------------
trunk/OpenMPT/soundlib/Load_psm.cpp
trunk/OpenMPT/soundlib/Load_s3m.cpp
Modified: trunk/OpenMPT/soundlib/Load_psm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-20 20:43:52 UTC (rev 336)
+++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-22 10:21:22 UTC (rev 337)
@@ -1,841 +1,558 @@
/*
- * This source code is public domain.
+ * Purpose: Load new PSM (ProTracker Studio) modules
+ * Authors: Johannes Schultz
*
- * Authors: Olivier Lapicque <oli...@jp...>
-*/
+ * This is partly based on http://www.shikadi.net/moddingwiki/ProTracker_Studio_Module
+ * and partly reverse-engineered.
+ *
+ * What's playing?
+ * - Epic Pinball - Seems to be working perfectly, apart from some portas? (esp. Deep Sea, Shareware Info - Linear freq slides needed!?)
+ * - Extreme Pinball - Default tempo / speed / restart position of subtunes is missing.
+ * I'm using the last default values, restart position is still completely missing
+ * - Jazz Jackrabbit - Hmm, I don't like some of the portas, but apart from that it's great. (same problem as Epic Pinball)
+ * - One Must Fall! - Perfect! (I modelled the volume slide and portamento conversion after this, as I got the original MTM files)
+ * - Silverball - Currently not supported (old PSM16 format)
+ */
-
-///////////////////////////////////////////////////
-//
-// PSM module loader
-//
-///////////////////////////////////////////////////
#include "stdafx.h"
#include "sndfile.h"
-//#define PSM_LOG
-
-#define PSM_ID_NEW 0x204d5350 // "PSM "
-#define PSM_ID_OLD 0xfe4d5350 // "PSM\xFE"
-#define IFFID_FILE 0x454c4946
-#define IFFID_TITL 0x4c544954
-#define IFFID_SDFT 0x54464453
-#define IFFID_PBOD 0x444f4250
-#define IFFID_SONG 0x474e4f53
-#define IFFID_PATT 0x54544150
-#define IFFID_DSMP 0x504d5344
-#define IFFID_OPLH 0x484c504f
-
#pragma pack(1)
-typedef struct _PSMCHUNK
+struct PSMHEADER
{
- DWORD id;
- DWORD len;
- DWORD listid;
-} PSMCHUNK;
+ DWORD formatID; // "PSM " (new format)
+ DWORD fileSize; // Filesize - 12
+ DWORD fileInfoID; // "FILE" Start of file info
+};
-typedef struct _PSMSONGHDR
+struct PSMSONGHEADER
{
- CHAR songname[8]; // "MAINSONG"
- BYTE reserved1;
- BYTE reserved2;
- BYTE channels;
-} PSMSONGHDR;
+ CHAR songType[9]; // Mostly "MAINSONG " (But not in Extreme Pinball!)
+ BYTE compression; // 1 - uncompressed
+ BYTE numChannels; // Number of channels, usually 4
-typedef struct _PSMPATTERN
+};
+
+struct PSMSAMPLEHEADERTEST // apparently, this is wrong.
{
- DWORD size;
- DWORD name;
- WORD rows;
- WORD reserved1;
- BYTE data[4];
-} PSMPATTERN;
+ CHAR sampleFormat[9];
+ DWORD sampleID; // INS0...INS9 (only last digit of sample ID, i.e. sample 1 and sample 11 are equal)
+ CHAR sampleName[33];
+ CHAR unknown1[6]; // 00 00 00 00 00 FF
+ WORD sampleNumber;
+ DWORD loopStart;
+ CHAR loop; // 1 = loop
+ CHAR unknown2[3]; // 00 00 00 00 00 FF
+ DWORD loopEnd; // FF FF FF FF = end of sample
+ WORD unknown3;
+ CHAR defaultVolume;
+ DWORD unknown4;
+ WORD C5Freq;
+ CHAR padding[21]; // 00 ... 00
+};
-typedef struct _PSMSAMPLE
+struct PSMSAMPLEHEADER // Use this instead
{
BYTE flags;
- CHAR songname[8];
- DWORD smpid;
- CHAR samplename[34];
- DWORD reserved1;
- BYTE reserved2;
- BYTE insno;
- BYTE reserved3;
- DWORD length;
- DWORD loopstart;
- DWORD loopend;
- WORD reserved4;
- BYTE defvol;
- DWORD reserved5;
- DWORD samplerate;
- BYTE reserved6[19];
-} PSMSAMPLE;
+ CHAR sampleFormat[8];
+ DWORD sampleID; // INS0...INS9 (only last digit of sample ID, i.e. sample 1 and sample 11 are equal)
+ CHAR sampleName[33];
+ CHAR unknown1[6]; // 00 00 00 00 00 FF
+ WORD sampleNumber;
+ DWORD sampleLength;
+ DWORD loopStart;
+ DWORD loopEnd; // FF FF FF FF = end of sample
+ WORD unknown3;
+ CHAR defaultVolume;
+ DWORD unknown4;
+ WORD C5Freq;
+ CHAR unknown5[21]; // 00 ... 00
+};
#pragma pack()
+BYTE convert_psm_param(BYTE param)
+{
+ // special conversion of some PSM parameters. is this done correctly?
+ return param >> 1;
+ //return (param + 1) >> 1;
+}
-bool CSoundFile::ReadPSM(LPCBYTE lpStream, DWORD dwMemLength)
-//-----------------------------------------------------------
+bool CSoundFile::ReadPSM(const LPCBYTE lpStream, const DWORD dwMemLength)
+//-----------------------------------------------------------------------
{
- PSMCHUNK *pfh = (PSMCHUNK *)lpStream;
- DWORD dwMemPos, dwSongPos;
- DWORD smpnames[MAX_SAMPLES];
- DWORD patptrs[MAX_PATTERNS];
- BYTE samplemap[MAX_SAMPLES];
- UINT nPatterns;
+ #define ASSERT_CAN_READ(x) \
+ if( dwMemPos > dwMemLength || x > dwMemLength - dwMemPos ) return false;
- // Chunk0: "PSM ",filesize,"FILE"
- if (dwMemLength < 256) return false;
- if (pfh->id == PSM_ID_OLD)
- {
- #ifdef PSM_LOG
- Log("Old PSM format not supported\n");
- #endif
- return false;
- }
- if ((pfh->id != PSM_ID_NEW) || (pfh->len+12 > dwMemLength) || (pfh->listid != IFFID_FILE)) return false;
+ DWORD dwMemPos = 0;
+
+ ASSERT_CAN_READ(12);
+ PSMHEADER shdr;
+ memcpy(&shdr, lpStream, sizeof(PSMHEADER));
+ if(LittleEndian(shdr.formatID) != 0x204d5350 // "PSM "
+ || LittleEndian(shdr.fileSize) != dwMemLength - 12
+ || LittleEndian(shdr.fileInfoID) != 0x454C4946 // "FILE"
+ ) return false;
+
+ // Yep, this seems to be a valid file.
m_nType = MOD_TYPE_PSM;
- m_nChannels = 16;
- m_nSamples = 0;
- nPatterns = 0;
- dwMemPos = 12;
- dwSongPos = 0;
- for (UINT iChPan=0; iChPan<16; iChPan++)
+ //m_dwSongFlags |= SONG_LINEARSLIDES; // TODO
+ m_nChannels = 0;
+
+ dwMemPos += 12;
+
+ memset(m_szNames, 0, sizeof(m_szNames));
+
+ m_nVSTiVolume = m_nSamplePreAmp = 48; // not supported in this format, so use a good default value
+
+ // pattern offset and identifier
+ PATTERNINDEX numPatterns = 0;
+ vector<DWORD> patternOffsets;
+ vector<DWORD> patternIDs;
+ patternOffsets.clear();
+ patternIDs.clear();
+ Order.clear();
+
+ std::string sComment; // we will store some information about the tune here
+
+ while(dwMemPos + 8 < dwMemLength)
{
- UINT pan = (((iChPan & 3) == 1) || ((iChPan&3)==2)) ? 0xC0 : 0x40;
- ChnSettings[iChPan].nPan = pan;
- }
- while (dwMemPos+8 < dwMemLength)
- {
- PSMCHUNK *pchunk = (PSMCHUNK *)(lpStream+dwMemPos);
- if ((pchunk->len >= dwMemLength - 8) || (dwMemPos + pchunk->len + 8 > dwMemLength)) break;
+ // Skip through the chunks
+ ASSERT_CAN_READ(8);
+ DWORD chunkID = LittleEndian(*(DWORD *)(lpStream + dwMemPos));
+ DWORD chunkSize = LittleEndian(*(DWORD *)(lpStream + dwMemPos + 4));
dwMemPos += 8;
- PUCHAR pdata = (PUCHAR)(lpStream+dwMemPos);
- ULONG len = pchunk->len;
- if (len) switch(pchunk->id)
+
+ ASSERT_CAN_READ(chunkSize);
+
+ switch(chunkID)
{
- // "TITL": Song title
- case IFFID_TITL:
- if (!pdata[0]) { pdata++; len--; }
- memcpy(m_szNames[0], pdata, (len>31) ? 31 : len);
+ case 0x4C544954: // "TITL" - Song Title
+ memcpy(m_szNames[0], lpStream + dwMemPos, (chunkSize < 31) ? chunkSize : 31);
m_szNames[0][31] = 0;
break;
- // "PBOD": Pattern
- case IFFID_PBOD:
- if ((len >= 12) && (nPatterns < MAX_PATTERNS))
- {
- patptrs[nPatterns++] = dwMemPos-8;
- }
+
+ case 0x54464453: // "SDFT" - Format info (song data starts here)
+ if(chunkSize != 8 || memcmp(lpStream + dwMemPos, "MAINSONG", 8)) return false;
break;
- // "SONG": Song description
- case IFFID_SONG:
- if ((len >= sizeof(PSMSONGHDR)+8) && (!dwSongPos))
- {
- dwSongPos = dwMemPos - 8;
- }
+
+ case 0x444F4250: // "PBOD" - Pattern data of a single pattern
+ if(chunkSize < 4 || chunkSize != LittleEndian(*(DWORD *)(lpStream + dwMemPos))) return false; // same value twice
+
+ // Pattern ID (something like "P0 " or "P13 ") follows
+ if(memcmp(lpStream + dwMemPos + 4, "P", 1)) return false;
+ patternOffsets.push_back(dwMemPos + 8);
+ patternIDs.push_back(*(DWORD *)(lpStream + dwMemPos + 4));
+ numPatterns++;
+
+ // Convert later as we have to know how many channels there are.
break;
- // "DSMP": Sample Data
- case IFFID_DSMP:
- if ((len >= sizeof(PSMSAMPLE)) && (m_nSamples+1 < MAX_SAMPLES))
+
+ case 0x474E4F53: // "SONG" - Information about this file (channel count etc)
+ // We will not check for the "song type", because it is not ALWAYS "MAINSONG " (Extreme Pinball seems to use other song types for the sub songs)
+ // However, the last char always seems to be a space char.
{
- m_nSamples++;
- MODSAMPLE *pSmp = &Samples[m_nSamples];
- PSMSAMPLE *psmp = (PSMSAMPLE *)pdata;
- smpnames[m_nSamples] = psmp->smpid;
- memcpy(m_szNames[m_nSamples], psmp->samplename, 31);
- m_szNames[m_nSamples][31] = 0;
- samplemap[m_nSamples-1] = (BYTE)m_nSamples;
- // Init sample
- pSmp->nGlobalVol = 0x40;
- pSmp->nC5Speed = psmp->samplerate;
- pSmp->nLength = psmp->length;
- pSmp->nLoopStart = psmp->loopstart;
- pSmp->nLoopEnd = psmp->loopend;
- pSmp->nPan = 128;
- pSmp->nVolume = (psmp->defvol+1) * 2;
- pSmp->uFlags = (psmp->flags & 0x80) ? CHN_LOOP : 0;
- if (pSmp->nLoopStart > 0) pSmp->nLoopStart--;
- // Point to sample data
- pdata += 0x60;
- len -= 0x60;
- // Load sample data
- if ((pSmp->nLength > 3) && (len > 3))
+ if(chunkSize < sizeof(PSMSONGHEADER)) return false;
+ PSMSONGHEADER *pSong = (PSMSONGHEADER *)(lpStream + dwMemPos);
+ if(pSong->compression != 0x01) return false;
+ m_nChannels = max(m_nChannels, pSong->numChannels); // subsongs *might* have different channel count
+
+ CHAR cSongName[10];
+ memcpy(cSongName, &pSong->songType, 9);
+ cSongName[9] = 0;
+ sComment += "\r\nSubsong: ";
+ sComment += cSongName;
+
+ DWORD dwChunkPos = dwMemPos + sizeof(PSMSONGHEADER);
+
+ // Sub chunks
+ while(dwChunkPos + 8 < dwMemPos + chunkSize)
{
- ReadSample(pSmp, RS_PCM8D, (LPCSTR)pdata, len);
- } else
- {
- pSmp->nLength = 0;
- }
- }
- break;
- #if 0
- default:
- {
- CHAR s[8], s2[64];
- *(DWORD *)s = pchunk->id;
- s[4] = 0;
- wsprintf(s2, "%s: %4d bytes @ %4d\n", s, pchunk->len, dwMemPos);
- OutputDebugString(s2);
- }
- #endif
- }
- dwMemPos += pchunk->len;
- }
- // Step #1: convert song structure
- PSMSONGHDR *pSong = (PSMSONGHDR *)(lpStream+dwSongPos+8);
- if ((!dwSongPos) || (pSong->channels < 2) || (pSong->channels > 32)) return true;
- m_nChannels = pSong->channels;
- // Valid song header -> convert attached chunks
- {
- DWORD dwSongEnd = dwSongPos + 8 + *(DWORD *)(lpStream+dwSongPos+4);
- dwMemPos = dwSongPos + 8 + 11; // sizeof(PSMCHUNK)+sizeof(PSMSONGHDR)
- while (dwMemPos + 8 < dwSongEnd)
- {
- PSMCHUNK *pchunk = (PSMCHUNK *)(lpStream+dwMemPos);
- dwMemPos += 8;
- if ((pchunk->len > dwSongEnd) || (dwMemPos + pchunk->len > dwSongEnd)) break;
- PUCHAR pdata = (PUCHAR)(lpStream+dwMemPos);
- ULONG len = pchunk->len;
- switch(pchunk->id)
- {
- case IFFID_OPLH:
- if (len >= 0x20)
- {
- UINT pos = len - 3;
- while (pos > 5)
+ DWORD subChunkID = LittleEndian(*(DWORD *)(lpStream + dwChunkPos));
+ DWORD subChunkSize = LittleEndian(*(DWORD *)(lpStream + dwChunkPos + 4));
+ dwChunkPos += 8;
+
+ switch(subChunkID)
{
- BOOL bFound = FALSE;
- pos -= 5;
- DWORD dwName = *(DWORD *)(pdata+pos);
- for (UINT i=0; i<nPatterns; i++)
+ case 0x45544144: // "DATE" - Song date (YYMMDD)
+ if(subChunkSize < 6) break;
+ CHAR cDate[7];
+ memcpy(cDate, lpStream + dwChunkPos, 6);
+ cDate[6] = 0;
+ sComment += "\r\nDate: ";
+ sComment += cDate;
+ // We don't care about the date.
+ break;
+
+ case 0x484C504F: // "OPLH" - Order list, channel + module settings
{
- DWORD dwPatName = ((PSMPATTERN *)(lpStream+patptrs[i]+8))->name;
- if (dwName == dwPatName)
+ if(subChunkSize < 9) return false;
+ // First byte = "Memory alloc, roughly ordlen + 10, if too small, song freezes"
+ if(LittleEndian(*(DWORD *)(lpStream + dwChunkPos + 1)) != 0xFF000C00 // "Something"
+ || LittleEndian(*(DWORD *)(lpStream + dwChunkPos + 5)) != 0x00010000) // "Something"
+ return false;
+
+ // Now, the interesting part begins!
+ DWORD dwSettingsOffset = dwChunkPos + 9;
+ while(dwSettingsOffset - dwChunkPos + 1 < subChunkSize)
{
- bFound = TRUE;
- break;
+ switch(lpStream[dwSettingsOffset])
+ {
+ case 0x01: // Order list item
+ if(dwSettingsOffset - dwChunkPos + 5 > subChunkSize) return false;
+ // Pattern name follows - find pattern (this is the orderlist)
+ for(PATTERNINDEX i = 0; i < patternIDs.size(); i++)
+ {
+ if(patternIDs[i] == *(DWORD *)(lpStream + dwSettingsOffset + 1))
+ {
+ Order.push_back(i);
+ break;
+ }
+ }
+ dwSettingsOffset += 5;
+ break;
+
+ case 0x04: // "end?" "04 03 00 00" in most cases (not Extreme Pinball - maybe restart positions are dumped here?)
+ if(dwSettingsOffset - dwChunkPos + 4 > subChunkSize) return false;
+ dwSettingsOffset += 4;
+ break;
+
+ case 0x07: // Default Speed
+ if(dwSettingsOffset - dwChunkPos + 2 > subChunkSize) break;
+ // NOTE: This should not be global! (Extreme Pinball!!!)
+ m_nDefaultSpeed = lpStream[dwSettingsOffset + 1];
+ dwSettingsOffset += 2;
+ break;
+
+ case 0x08: // Default Tempo
+ if(dwSettingsOffset - dwChunkPos + 2 > subChunkSize) break;
+ // Same note as above!
+ m_nDefaultTempo = lpStream[dwSettingsOffset + 1];
+ dwSettingsOffset += 2;
+ break;
+
+ case 0x0D: // This is a channel header
+ if(dwSettingsOffset - dwChunkPos + 4 > subChunkSize) break;
+ ChnSettings[min(lpStream[dwSettingsOffset + 1], pSong->numChannels)].nPan = lpStream[dwSettingsOffset + 2];
+ // Last byte: "either 0, 2 or 4 (Some sort of priority?)"
+ dwSettingsOffset += 4;
+ break;
+
+ case 0x0E: // Unknown - "0E <ChnID> FF"
+ if(dwSettingsOffset - dwChunkPos + 3 > subChunkSize) break;
+ dwSettingsOffset += 3;
+ break;
+
+ case 0x00: // "end?"
+ dwSettingsOffset += 1;
+ break;
+
+ default: // How the hell should this happen? I've listened through all existing PSM files. :)
+ CString s;
+ s.Format("Please report to the OpenMPT team: Unknown chunk %d found at position %d (in the OPLH chunk of this PSM file)", lpStream[dwSettingsOffset], dwSettingsOffset);
+ MessageBox(NULL, s, TEXT("OpenMPT PSM import"), MB_ICONERROR);
+ return false;
+ break;
+
+ }
}
+ Order.push_back(Order.GetInvalidPatIndex());
}
- if ((!bFound) && (pdata[pos+1] > 0) && (pdata[pos+1] <= 0x10)
- && (pdata[pos+3] > 0x40) && (pdata[pos+3] < 0xC0))
- {
- m_nDefaultSpeed = pdata[pos+1];
- m_nDefaultTempo = pdata[pos+3];
- break;
- }
+ break;
+
+ case 0x54544150: // PATT - Pattern list
+ // We don't really need this.
+ break;
+
+ case 0x4D415344: // DSAM - Sample list
+ // We don't need this either.
+ break;
+
+ default:
+ break;
+
}
- UINT iOrd = 0;
- Order.resize(MAX_ORDERS, Order.GetInvalidPatIndex());
- while ((pos+5<len) && (iOrd < MAX_ORDERS))
- {
- DWORD dwName = *(DWORD *)(pdata+pos);
- for (UINT i=0; i<nPatterns; i++)
- {
- DWORD dwPatName = ((PSMPATTERN *)(lpStream+patptrs[i]+8))->name;
- if (dwName == dwPatName)
- {
- Order[iOrd++] = i;
- break;
- }
- }
- pos += 5;
- }
+
+ dwChunkPos += subChunkSize;
}
- break;
}
- dwMemPos += pchunk->len;
+
+ break;
+
+ case 0x504D5344: // DSMP - Samples
+
+ {
+ if(chunkSize < sizeof(PSMSAMPLEHEADER)) return false;
+ PSMSAMPLEHEADER *pSample = (PSMSAMPLEHEADER *)(lpStream + dwMemPos);
+ SAMPLEINDEX smp = (SAMPLEINDEX)(LittleEndianW(pSample->sampleNumber) + 1);
+ m_nSamples = max(m_nSamples, smp);
+ memcpy(m_szNames[smp], pSample->sampleName, 31);
+ m_szNames[0][31] = 0;
+
+ Samples[smp].nGlobalVol = 0x40;
+ Samples[smp].nC5Speed = LittleEndianW(pSample->C5Freq);
+ Samples[smp].nLength = LittleEndian(pSample->sampleLength);
+ Samples[smp].nLoopStart = LittleEndian(pSample->loopStart);
+ Samples[smp].nLoopEnd = LittleEndian(pSample->loopEnd);
+ Samples[smp].nPan = 128;
+ Samples[smp].nVolume = (pSample->defaultVolume + 1) << 1;
+ Samples[smp].uFlags = (pSample->flags & 0x80) ? CHN_LOOP : 0;
+ if(Samples[smp].nLoopStart > 0) Samples[smp].nLoopStart--;
+ if(Samples[smp].nLoopEnd == 0xFFFFFF) Samples[smp].nLoopEnd = Samples[smp].nLength;
+
+ // Delta-encoded samples
+ ReadSample(&Samples[smp], RS_PCM8D, (LPCSTR)(lpStream + dwMemPos + sizeof(PSMSAMPLEHEADER)), Samples[smp].nLength);
+ }
+
+ break;
+
+ default:
+ break;
+
}
+
+ dwMemPos += chunkSize;
}
- // Step #2: convert patterns
- for (UINT nPat=0; nPat<nPatterns; nPat++)
+ if(m_nChannels == 0)
+ return false;
+
+ // Now that we know the number of channels, we can go through all the patterns.
+ for(PATTERNINDEX i = 0; i < numPatterns; i++)
{
- PSMPATTERN *pPsmPat = (PSMPATTERN *)(lpStream+patptrs[nPat]+8);
- ULONG len = *(DWORD *)(lpStream+patptrs[nPat]+4) - 12;
- UINT nRows = pPsmPat->rows;
- if (len > pPsmPat->size) len = pPsmPat->size;
- if ((nRows < 64) || (nRows > 256)) nRows = 64;
- if(Patterns.Insert(nPat, nRows))
+ DWORD dwPatternOffset = patternOffsets[i];
+ if(dwPatternOffset + 2 > dwMemLength) return false;
+ WORD patternSize = LittleEndianW(*(WORD *)(lpStream + dwPatternOffset));
+ dwPatternOffset += 2;
+
+ if(Patterns.Insert(i, patternSize))
+ {
+ CString s;
+ s.Format(TEXT("Allocating patterns failed starting from pattern %u"), i);
+ MessageBox(NULL, s, TEXT("OpenMPT PSM import"), MB_ICONERROR);
break;
+ }
- MODCOMMAND *m = Patterns[nPat];
- BYTE *p = pPsmPat->data;
- UINT pos = 0;
- UINT row = 0;
- UINT oldch = 0;
- BOOL bNewRow = FALSE;
- #ifdef PSM_LOG
- Log("Pattern %d at offset 0x%04X\n", nPat, (DWORD)(p - (BYTE *)lpStream));
- #endif
- while ((row < nRows) && (pos+1 < len))
+ // Read pattern.
+ MODCOMMAND *row_data;
+ row_data = Patterns[i];
+
+ for(int nRow = 0; nRow < patternSize; nRow++)
{
- UINT flags = p[pos++];
- UINT ch = p[pos++];
+ if(dwPatternOffset + 2 > dwMemLength) return false;
+ WORD rowSize = LittleEndianW(*(WORD *)(lpStream + dwPatternOffset));
- #ifdef PSM_LOG
- //Log("flags+ch: %02X.%02X\n", flags, ch);
- #endif
- if (((flags & 0xf0) == 0x10) && (ch <= oldch) /*&& (!bNewRow)*/)
+ DWORD dwRowOffset = dwPatternOffset + 2;
+
+ while(dwRowOffset < dwPatternOffset + rowSize)
{
- if ((pos+1<len) && (!(p[pos] & 0x0f)) && (p[pos+1] < m_nChannels))
+ if(dwRowOffset + 1 > dwMemLength) return false;
+ BYTE mask = lpStream[dwRowOffset];
+ // Point to the correct channel
+ MODCOMMAND *m = row_data + min(m_nChannels, lpStream[dwRowOffset + 1]);
+ dwRowOffset += 2;
+
+ if(mask & 0x80)
{
- #ifdef PSM_LOG
- //if (!nPat) Log("Continuing on new row\n");
- #endif
- row++;
- m += m_nChannels;
- oldch = ch;
- continue;
+ if(dwRowOffset + 1 > dwMemLength) return false;
+ // Note present
+ BYTE bNote = lpStream[dwRowOffset];
+ bNote = (bNote & 0x0F) + 12 * (bNote >> 4) + 13;
+ m->note = bNote;
+ dwRowOffset++;
}
- }
- if ((pos >= len) || (row >= nRows)) break;
- if (!(flags & 0xf0))
- {
- #ifdef PSM_LOG
- //if (!nPat) Log("EOR(%d): %02X.%02X\n", row, p[pos], p[pos+1]);
- #endif
- row++;
- m += m_nChannels;
- bNewRow = TRUE;
- oldch = ch;
- continue;
- }
- bNewRow = FALSE;
- if (ch >= m_nChannels)
- {
- #ifdef PSM_LOG
- if (!nPat) Log("Invalid channel row=%d (0x%02X.0x%02X)\n", row, flags, ch);
- #endif
- ch = 0;
- }
- // Note + Instr
- if ((flags & 0x40) && (pos+1 < len))
- {
- UINT note = p[pos++];
- UINT nins = p[pos++];
- #ifdef PSM_LOG
- //if (!nPat) Log("note+ins: %02X.%02X\n", note, nins);
- if ((!nPat) && (nins >= m_nSamples)) Log("WARNING: invalid instrument number (%d)\n", nins);
- #endif
- if ((note) && (note < 0x80)) note = (note>>4)*12+(note&0x0f)+12+1;
- m[ch].instr = samplemap[nins];
- m[ch].note = note;
- }
- // Volume
- if ((flags & 0x20) && (pos < len))
- {
- m[ch].volcmd = VOLCMD_VOLUME;
- m[ch].vol = p[pos++] / 2;
- }
- // Effect
- if ((flags & 0x10) && (pos+1 < len))
- {
- UINT command = p[pos++];
- UINT param = p[pos++];
- // Convert effects
- switch(command)
+
+ if(mask & 0x40)
{
- // 01: fine volslide up
- case 0x01: command = CMD_VOLUMESLIDE; param |= 0x0f; break;
- // 04: fine volslide down
- case 0x04: command = CMD_VOLUMESLIDE; param>>=4; param |= 0xf0; break;
- // 0C: portamento up
- case 0x0C: command = CMD_PORTAMENTOUP; param = (param+1)/2; break;
- // 0E: portamento down
- case 0x0E: command = CMD_PORTAMENTODOWN; param = (param+1)/2; break;
- // 33: Position Jump
- case 0x33: command = CMD_POSITIONJUMP; break;
- // 34: Pattern break
- case 0x34: command = CMD_PATTERNBREAK; break;
- // 3D: speed
- case 0x3D: command = CMD_SPEED; break;
- // 3E: tempo
- case 0x3E: command = CMD_TEMPO; break;
- // Unknown
- default:
- #ifdef PSM_LOG
- Log("Unknown PSM effect pat=%d row=%d ch=%d: %02X.%02X\n", nPat, row, ch, command, param);
- #endif
- command = param = 0;
+ if(dwRowOffset + 1 > dwMemLength) return false;
+ // Instrument present
+ m->instr = lpStream[dwRowOffset] + 1;
+ dwRowOffset++;
}
- m[ch].command = (BYTE)command;
- m[ch].param = (BYTE)param;
- }
- oldch = ch;
- }
- #ifdef PSM_LOG
- if (pos < len)
- {
- Log("Pattern %d: %d/%d[%d] rows (%d bytes) -> %d bytes left\n", nPat, row, nRows, pPsmPat->rows, pPsmPat->size, len-pos);
- }
- #endif
- }
- // Done (finally!)
- return true;
-}
+ if(mask & 0x20)
+ {
+ if(dwRowOffset + 1 > dwMemLength) return false;
+ // Volume present
+ m->volcmd = VOLCMD_VOLUME;
+ m->vol = (min(lpStream[dwRowOffset], 127)) >> 1;
+ dwRowOffset++;
+ }
+ if(mask & 0x10)
+ {
+ // Effect present - convert
+ if(dwRowOffset + 2 > dwMemLength) return false;
+ BYTE command = lpStream[dwRowOffset], param = lpStream[dwRowOffset + 1];
-//////////////////////////////////////////////////////////////
-//
-// PSM Old Format
-//
+ switch(command)
+ {
+ // Volslides
+ case 0x01: // fine volslide up
+ command = CMD_VOLUMESLIDE;
+ param = (param << 3) | 0x0F;
+ break;
+ case 0x02: // volslide up
+ command = CMD_VOLUMESLIDE;
+ param = (param << 3);
+ break;
+ case 0x03: // fine volslide down
+ command = CMD_VOLUMESLIDE;
+ param = 0xF0 | (param >> 1);
+ break;
+ case 0x04: // volslide down
+ command = CMD_VOLUMESLIDE;
+ param >>= 1;
+ break;
-/*
+ // Portamento
+ case 0x0B: // fine portamento up
+ command = CMD_PORTAMENTOUP;
+ param = 0xF0 | convert_psm_param(param);
+ break;
+ case 0x0C: // portamento up
+ command = CMD_PORTAMENTOUP;
+ param = convert_psm_param(param);
+ break;
+ case 0x0D: // fine portamento down
+ command = CMD_PORTAMENTODOWN;
+ param = 0xF0 | convert_psm_param(param);
+ break;
+ case 0x0E: // portamento down
+ command = CMD_PORTAMENTODOWN;
+ param = convert_psm_param(param);
+ break;
+ case 0x0F: // tone portamento
+ command = CMD_TONEPORTAMENTO;
+ param = convert_psm_param(param);
+ break;
+ case 0x10: // glissando control
+ command = CMD_S3MCMDEX;
+ param = 0x10 | (param & 0x01);
+ break;
+ case 0x11: // tone portamento + volslide up
+ command = CMD_TONEPORTAVOL;
+ param = param & 0xF0;
+ break;
+ case 0x12: // tone portamento + volslide down
+ command = CMD_TONEPORTAVOL;
+ param = (param >> 4) & 0x0F;
+ break;
-CONST
- c_PSM_MaxOrder = $FF;
- c_PSM_MaxSample = $FF;
- c_PSM_MaxChannel = $0F;
+ // Vibrato
+ case 0x15: // vibrato
+ command = CMD_VIBRATO;
+ break;
+ case 0x16: // vibrato waveform
+ command = CMD_S3MCMDEX;
+ param = 0x30 | (param & 0x0F);
+ break;
+ case 0x17: // vibrato + volslide up
+ command = CMD_VIBRATOVOL;
+ param = 0xF0 | param;
+ break;
+ case 0x18: // vibrato + volslide down
+ command = CMD_VIBRATOVOL;
+ break;
- TYPE
- PPSM_Header = ^TPSM_Header;
- TPSM_Header = RECORD
- PSM_Sign : ARRAY[01..04] OF CHAR; { PSM + #254 }
- PSM_SongName : ARRAY[01..58] OF CHAR;
- PSM_Byte00 : BYTE;
- PSM_Byte1A : BYTE;
- PSM_Unknown00 : BYTE;
- PSM_Unknown01 : BYTE;
- PSM_Unknown02 : BYTE;
- PSM_Speed : BYTE;
- PSM_Tempo : BYTE;
- PSM_Unknown03 : BYTE;
- PSM_Unknown04 : WORD;
- PSM_OrderLength : WORD;
- PSM_PatternNumber : WORD;
- PSM_SampleNumber : WORD;
- PSM_ChannelNumber : WORD;
- PSM_ChannelUsed : WORD;
- PSM_OrderPosition : LONGINT;
- PSM_ChannelSettingPosition : LONGINT;
- PSM_PatternPosition : LONGINT;
- PSM_SamplePosition : LONGINT;
- { *** perhaps there are some more infos in a larger header,
- but i have not decoded it and so it apears here NOT }
- END;
+ // Tremolo
+ case 0x1F: // tremolo
+ command = CMD_TREMOLO;
+ break;
+ case 0x20: // tremolo waveform
+ command = CMD_S3MCMDEX;
+ param = 0x40 | (param & 0x0F);
+ break;
- PPSM_Sample = ^TPSM_Sample;
- TPSM_Sample = RECORD
- PSM_SampleFileName : ARRAY[01..12] OF CHAR;
- PSM_SampleByte00 : BYTE;
- PSM_SampleName : ARRAY[01..22] OF CHAR;
- PSM_SampleUnknown00 : ARRAY[01..02] OF BYTE;
- PSM_SamplePosition : LONGINT;
- PSM_SampleUnknown01 : ARRAY[01..04] OF BYTE;
- PSM_SampleNumber : BYTE;
- PSM_SampleFlags : WORD;
- PSM_SampleLength : LONGINT;
- PSM_SampleLoopBegin : LONGINT;
- PSM_SampleLoopEnd : LONGINT;
- PSM_Unknown03 : BYTE;
- PSM_SampleVolume : BYTE;
- PSM_SampleC5Speed : WORD;
- END;
+ // Sample commands
+ case 0x29: // 3-byte offset - we only support the middle byte.
+ if(dwRowOffset + 4 > dwMemLength) return false;
+ command = CMD_OFFSET;
+ param = lpStream[dwRowOffset + 2];
+ dwRowOffset += 2;
+ break;
+ case 0x2A: // set finetune
+ command = CMD_S3MCMDEX;
+ param = 0x40 | (param & 0x0F);
+ break;
+ case 0x2B: // note cut
+ command = CMD_S3MCMDEX;
+ param = 0xC0 | (param & 0x0F);
+ break;
+ case 0x2C: // note delay
+ command = CMD_S3MCMDEX;
+ param = 0xD0 | (param & 0x0F);
+ break;
- PPSM_SampleList = ^TPSM_SampleList;
- TPSM_SampleList = ARRAY[01..c_PSM_MaxSample] OF TPSM_Sample;
+ // Position change
+ case 0x33: // position jump
+ command = CMD_POSITIONJUMP;
+ break;
+ case 0x34: // pattern break
+ command = CMD_PATTERNBREAK;
+ break;
+ case 0x35: // loop pattern
+ command = CMD_S3MCMDEX;
+ param = 0xB0 | (param & 0x0F);
+ break;
+ case 0x36: // pattern delay
+ command = CMD_S3MCMDEX;
+ param = 0xE0 | (param & 0x0F);
+ break;
- PPSM_Order = ^TPSM_Order;
- TPSM_Order = ARRAY[00..c_PSM_MaxOrder] OF BYTE;
+ // speed change
+ case 0x3D: // set speed
+ command = CMD_SPEED;
+ break;
+ case 0x3E: // set tempo
+ command = CMD_TEMPO;
+ break;
- PPSM_ChannelSettings = ^TPSM_ChannelSettings;
- TPSM_ChannelSettings = ARRAY[00..c_PSM_MaxChannel] OF BYTE;
+ // misc commands
+ case 0x47: // arpeggio
+ command = CMD_ARPEGGIO;
+ break;
+ case 0x48: // set finetune
+ command = CMD_MODCMDEX;
+ param = 0x50 | (param & 0x0F);
+ break;
+ case 0x49: // set balance
+ command = CMD_S3MCMDEX;
+ param = 0x80 | (param & 0x0F);
+ break;
- CONST
- PSM_NotesInPattern : BYTE = $00;
- PSM_ChannelInPattern : BYTE = $00;
+ default:
+ //ASSERT(false);
+ break;
- CONST
- c_PSM_SetSpeed = 60;
+ }
- FUNCTION PSM_Size(FileName : STRING;FilePosition : LONGINT) : LONGINT;
- BEGIN
- END;
+ m->command = command;
+ m->param = param;
- PROCEDURE PSM_UnpackPattern(VAR Source,Destination;PatternLength : WORD);
- VAR
- Witz : ARRAY[00..04] OF WORD;
- I1,I2 : WORD;
- I3,I4 : WORD;
- TopicalByte : ^BYTE;
- Pattern : PUnpackedPattern;
- ChannelP : BYTE;
- NoteP : BYTE;
- InfoByte : BYTE;
- CodeByte : BYTE;
- InfoWord : WORD;
- Effect : BYTE;
- Opperand : BYTE;
- Panning : BYTE;
- Volume : BYTE;
- PrevInfo : BYTE;
- InfoIndex : BYTE;
- BEGIN
- Pattern := @Destination;
- TopicalByte := @Source;
- { *** Initialize patttern }
- FOR I2 := 0 TO c_Maximum_NoteIndex DO
- FOR I3 := 0 TO c_Maximum_ChannelIndex DO
- BEGIN
- Pattern^[I2,I3,c_Pattern_NoteIndex] := $FF;
- Pattern^[I2,I3,c_Pattern_SampleIndex] := $00;
- Pattern^[I2,I3,c_Pattern_VolumeIndex] := $FF;
- Pattern^[I2,I3,c_Pattern_PanningIndex] := $FF;
- Pattern^[I2,I3,c_Pattern_EffectIndex] := $00;
- Pattern^[I2,I3,c_Pattern_OpperandIndex] := $00;
- END;
- { *** Byte-pointer on first pattern-entry }
- ChannelP := $00;
- NoteP := $00;
- InfoByte := $00;
- PrevInfo := $00;
- InfoIndex := $02;
- { *** read notes in pattern }
- PSM_NotesInPattern := TopicalByte^; INC(TopicalByte); DEC(PatternLength); INC(InfoIndex);
- PSM_ChannelInPattern := TopicalByte^; INC(TopicalByte); DEC(PatternLength); INC(InfoIndex);
- { *** unpack pattern }
- WHILE (INTEGER(PatternLength) > 0) AND (NoteP < c_Maximum_NoteIndex) DO
- BEGIN
- { *** Read info-byte }
- InfoByte := TopicalByte^; INC(TopicalByte); DEC(PatternLength); INC(InfoIndex);
- IF InfoByte <> $00 THEN
- BEGIN
- ChannelP := InfoByte AND $0F;
- IF InfoByte AND 128 = 128 THEN { note and sample }
- BEGIN
- { *** read note }
- CodeByte := TopicalByte^; INC(TopicalByte); DEC(PatternLength);
- DEC(CodeByte);
- CodeByte := CodeByte MOD 12 * 16 + CodeByte DIV 12 + 2;
- Pattern^[NoteP,ChannelP,c_Pattern_NoteIndex] := CodeByte;
- { *** read sample }
- CodeByte := TopicalByte^; INC(TopicalByte); DEC(PatternLength);
- Pattern^[NoteP,ChannelP,c_Pattern_SampleIndex] := CodeByte;
- END;
- IF InfoByte AND 64 = 64 THEN { Volume }
- BEGIN
- CodeByte := TopicalByte^; INC(TopicalByte); DEC(PatternLength);
- Pattern^[NoteP,ChannelP,c_Pattern_VolumeIndex] := CodeByte;
- END;
- IF InfoByte AND 32 = 32 THEN { effect AND opperand }
- BEGIN
- Effect := TopicalByte^; INC(TopicalByte); DEC(PatternLength);
- Opperand := TopicalByte^; INC(TopicalByte); DEC(PatternLength);
- CASE Effect OF
- c_PSM_SetSpeed:
- BEGIN
- Effect := c_I_Set_Speed;
- END;
- ELSE
- BEGIN
- Effect := c_I_NoEffect;
- Opperand := $00;
- END;
- END;
- Pattern^[NoteP,ChannelP,c_Pattern_EffectIndex] := Effect;
- Pattern^[NoteP,ChannelP,c_Pattern_OpperandIndex] := Opperand;
- END;
- END ELSE INC(NoteP);
- END;
- END;
+ dwRowOffset += 2;
+ }
- PROCEDURE PSM_Load(FileName : STRING;FilePosition : LONGINT;VAR Module : PModule;VAR ErrorCode : WORD);
- { *** caution : Module has to be inited before!!!! }
- VAR
- Header : PPSM_Header;
- Sample : PPSM_SampleList;
- Order : PPSM_Order;
- ChannelSettings : PPSM_ChannelSettings;
- MultiPurposeBuffer : PByteArray;
- PatternBuffer : PUnpackedPattern;
- TopicalParaPointer : WORD;
+ }
- InFile : FILE;
- I1,I2 : WORD;
- I3,I4 : WORD;
- TempW : WORD;
- TempB : BYTE;
- TempP : PByteArray;
- TempI : INTEGER;
- { *** copy-vars for loop-extension }
- CopySource : LONGINT;
- CopyDestination : LONGINT;
- CopyLength : LONGINT;
- BEGIN
- { *** try to open file }
- ASSIGN(InFile,FileName);
-{$I-}
- RESET(InFile,1);
-{$I+}
- IF IORESULT <> $00 THEN
- BEGIN
- EXIT;
- END;
-{$I-}
- { *** seek start of module }
- IF FILESIZE(InFile) < FilePosition THEN
- BEGIN
- EXIT;
- END;
- SEEK(InFile,FilePosition);
- { *** look for enough memory for temporary variables }
- IF MEMAVAIL < SIZEOF(TPSM_Header) + SIZEOF(TPSM_SampleList) +
- SIZEOF(TPSM_Order) + SIZEOF(TPSM_ChannelSettings) +
- SIZEOF(TByteArray) + SIZEOF(TUnpackedPattern)
- THEN
- BEGIN
- EXIT;
- END;
- { *** init dynamic variables }
- NEW(Header);
- NEW(Sample);
- NEW(Order);
- NEW(ChannelSettings);
- NEW(MultiPurposeBuffer);
- NEW(PatternBuffer);
- { *** read header }
- BLOCKREAD(InFile,Header^,SIZEOF(TPSM_Header));
- { *** test if this is a DSM-file }
- IF NOT ((Header^.PSM_Sign[1] = 'P') AND (Header^.PSM_Sign[2] = 'S') AND
- (Header^.PSM_Sign[3] = 'M') AND (Header^.PSM_Sign[4] = #254)) THEN
- BEGIN
- ErrorCode := c_NoValidFileFormat;
- CLOSE(InFile);
- EXIT;
- END;
- { *** read order }
- SEEK(InFile,FilePosition + Header^.PSM_OrderPosition);
- BLOCKREAD(InFile,Order^,Header^.PSM_OrderLength);
- { *** read channelsettings }
- SEEK(InFile,FilePosition + Header^.PSM_ChannelSettingPosition);
- BLOCKREAD(InFile,ChannelSettings^,SIZEOF(TPSM_ChannelSettings));
- { *** read samplelist }
- SEEK(InFile,FilePosition + Header^.PSM_SamplePosition);
- BLOCKREAD(InFile,Sample^,Header^.PSM_SampleNumber * SIZEOF(TPSM_Sample));
- { *** copy header to intern NTMIK-structure }
- Module^.Module_Sign := 'MF';
- Module^.Module_FileFormatVersion := $0100;
- Module^.Module_SampleNumber := Header^.PSM_SampleNumber;
- Module^.Module_PatternNumber := Header^.PSM_PatternNumber;
- Module^.Module_OrderLength := Header^.PSM_OrderLength;
- Module^.Module_ChannelNumber := Header^.PSM_ChannelNumber+1;
- Module^.Module_Initial_GlobalVolume := 64;
- Module^.Module_Initial_MasterVolume := $C0;
- Module^.Module_Initial_Speed := Header^.PSM_Speed;
- Module^.Module_Initial_Tempo := Header^.PSM_Tempo;
-{ *** paragraph 01 start }
- Module^.Module_Flags := c_Module_Flags_ZeroVolume * BYTE(1) +
- c_Module_Flags_Stereo * BYTE(1) +
- c_Module_Flags_ForceAmigaLimits * BYTE(0) +
- c_Module_Flags_Panning * BYTE(1) +
- c_Module_Flags_Surround * BYTE(1) +
- c_Module_Flags_QualityMixing * BYTE(1) +
- c_Module_Flags_FastVolumeSlides * BYTE(0) +
- c_Module_Flags_SpecialCustomData * BYTE(0) +
- c_Module_Flags_SongName * BYTE(1);
- I1 := $01;
- WHILE (Header^.PSM_SongName[I1] > #00) AND (I1 < c_Module_SongNameLength) DO
- BEGIN
- Module^.Module_Name[I1] := Header^.PSM_SongName[I1];
- INC(I1);
- END;
- Module^.Module_Name[c_Module_SongNameLength] := #00;
- { *** Init channelsettings }
- FOR I1 := 0 TO c_Maximum_ChannelIndex DO
- BEGIN
- IF I1 < Header^.PSM_ChannelUsed THEN
- BEGIN
- { *** channel enabled }
- Module^.Module_ChannelSettingPointer^[I1].ChannelSettings_GlobalVolume := 64;
- Module^.Module_ChannelSettingPointer^[I1].ChannelSettings_Panning := (ChannelSettings^[I1]) * $08;
- Module^.Module_ChannelSettingPointer^[I1].ChannelSettings_Code := I1 + $10 * BYTE(ChannelSettings^[I1] > $08) +
- c_ChannelSettings_Code_ChannelEnabled * BYTE(1) +
- c_ChannelSettings_Code_ChannelDigital * BYTE(1);
- Module^.Module_ChannelSettingPointer^[I1].ChannelSettings_Controls :=
- c_ChannelSettings_Controls_EnhancedMode * BYTE(1) +
- c_ChannelSettings_Controls_SurroundMode * BYTE(0);
- END
- ELSE
- BEGIN
- { *** channel disabled }
- Module^.Module_ChannelSettingPointer^[I1].ChannelSettings_GlobalVolume := $00;
- Module^.Module_ChannelSettingPointer^[I1].ChannelSettings_Panning := $00;
- Module^.Module_ChannelSettingPointer^[I1].ChannelSettings_Code := $00;
- Module^.Module_ChannelSettingPointer^[I1].ChannelSettings_Controls := $00;
- END;
- END;
- { *** init and copy order }
- FILLCHAR(Module^.Module_OrderPointer^,c_Maximum_OrderIndex+1,$FF);
- MOVE(Order^,Module^.Module_OrderPointer^,Header^.PSM_OrderLength);
- { *** read pattern }
- SEEK(InFile,FilePosition + Header^.PSM_PatternPosition);
- NTMIK_LoaderPatternNumber := Header^.PSM_PatternNumber-1;
- FOR I1 := 0 TO Header^.PSM_PatternNumber-1 DO
- BEGIN
- NTMIK_LoadPatternProcedure;
- { *** read length }
- BLOCKREAD(InFile,TempW,2);
- { *** read pattern }
- BLOCKREAD(InFile,MultiPurposeBuffer^,TempW-2);
- { *** unpack pattern and set notes per channel to 64 }
- PSM_UnpackPattern(MultiPurposeBuffer^,PatternBuffer^,TempW);
- NTMIK_PackPattern(MultiPurposeBuffer^,PatternBuffer^,PSM_NotesInPattern);
- TempW := WORD(256) * MultiPurposeBuffer^[01] + MultiPurposeBuffer^[00];
- GETMEM(Module^.Module_PatternPointer^[I1],TempW);
- MOVE(MultiPurposeBuffer^,Module^.Module_PatternPointer^[I1]^,TempW);
- { *** next pattern }
- END;
- { *** read samples }
- NTMIK_LoaderSampleNumber := Header^.PSM_SampleNumber;
- FOR I1 := 1 TO Header^.PSM_SampleNumber DO
- BEGIN
- NTMIK_LoadSampleProcedure;
- { *** get index for sample }
- I3 := Sample^[I1].PSM_SampleNumber;
- { *** clip PSM-sample }
- IF Sample^[I1].PSM_SampleLoopEnd > Sample^[I1].PSM_SampleLength
- THEN Sample^[I1].PSM_SampleLoopEnd := Sample^[I1].PSM_SampleLength;
- { *** init intern sample }
- NEW(Module^.Module_SamplePointer^[I3]);
- FILLCHAR(Module^.Module_SamplePointer^[I3]^,SIZEOF(TSample),$00);
- FILLCHAR(Module^.Module_SamplePointer^[I3]^.Sample_SampleName,c_Sample_SampleNameLength,#32);
- FILLCHAR(Module^.Module_SamplePointer^[I3]^.Sample_FileName,c_Sample_FileNameLength,#32);
- { *** copy informations to intern sample }
- I2 := $01;
- WHILE (Sample^[I1].PSM_SampleName[I2] > #00) AND (I2 < c_Sample_SampleNameLength) DO
- BEGIN
- Module^.Module_SamplePointer^[I3]^.Sample_SampleName[I2] := Sample^[I1].PSM_SampleName[I2];
- INC(I2);
- END;
- Module^.Module_SamplePointer^[I3]^.Sample_Sign := 'DF';
- Module^.Module_SamplePointer^[I3]^.Sample_FileFormatVersion := $00100;
- Module^.Module_SamplePointer^[I3]^.Sample_Position := $00000000;
- Module^.Module_SamplePointer^[I3]^.Sample_Selector := $0000;
- Module^.Module_SamplePointer^[I3]^.Sample_Volume := Sample^[I1].PSM_SampleVolume;
- Module^.Module_SamplePointer^[I3]^.Sample_LoopCounter := $00;
- Module^.Module_SamplePointer^[I3]^.Sample_C5Speed := Sample^[I1].PSM_SampleC5Speed;
- Module^.Module_SamplePointer^[I3]^.Sample_Length := Sample^[I1].PSM_SampleLength;
- Module^.Module_SamplePointer^[I3]^.Sample_LoopBegin := Sample^[I1].PSM_SampleLoopBegin;
- Module^.Module_SamplePointer^[I3]^.Sample_LoopEnd := Sample^[I1].PSM_SampleLoopEnd;
- { *** now it's time for the flags }
- Module^.Module_SamplePointer^[I3]^.Sample_Flags :=
- c_Sample_Flags_DigitalSample * BYTE(1) +
- c_Sample_Flags_8BitSample * BYTE(1) +
- c_Sample_Flags_UnsignedSampleData * BYTE(1) +
- c_Sample_Flags_Packed * BYTE(0) +
- c_Sample_Flags_LoopCounter * BYTE(0) +
- c_Sample_Flags_SampleName * BYTE(1) +
- c_Sample_Flags_LoopActive *
- BYTE(Sample^[I1].PSM_SampleFlags AND (LONGINT(1) SHL 15) = (LONGINT(1) SHL 15));
- { *** alloc memory for sample-data }
- E_Getmem(Module^.Module_SamplePointer^[I3]^.Sample_Selector,
- Module^.Module_SamplePointer^[I3]^.Sample_Position,
- Module^.Module_SamplePointer^[I3]^.Sample_Length + c_LoopExtensionSize);
- { *** read out data }
- EPT(TempP).p_Selector := Module^.Module_SamplePointer^[I3]^.Sample_Selector;
- EPT(TempP).p_Offset := $0000;
- SEEK(InFile,Sample^[I1].PSM_SamplePosition);
- E_BLOCKREAD(InFile,TempP^,Module^.Module_SamplePointer^[I3]^.Sample_Length);
- { *** 'coz the samples are signed in a DSM-file -> PC-fy them }
- IF Module^.Module_SamplePointer^[I3]^.Sample_Length > 4 THEN
- BEGIN
- CopyLength := Module^.Module_SamplePointer^[I3]^.Sample_Length;
- { *** decode sample }
- ASM
- DB 066h; MOV CX,WORD PTR CopyLength
- { *** load sample selector }
- MOV ES,WORD PTR TempP[00002h]
- DB 066h; XOR SI,SI
- DB 066h; XOR DI,DI
- XOR AH,AH
- { *** conert all bytes }
- @@MainLoop:
- DB 026h; DB 067h; LODSB
- ADD AL,AH
- MOV AH,AL
- DB 067h; STOSB
- DB 066h; LOOP @@MainLoop
- END;
- { *** make samples unsigned }
- ASM
- DB 066h; MOV CX,WORD PTR CopyLength
- { *** load sample selector }
- MOV ES,WORD PTR TempP[00002h]
- DB 066h; XOR SI,SI
- DB 066h; XOR DI,DI
- { *** conert all bytes }
- @@MainLoop:
- DB 026h; DB 067h; LODSB
- SUB AL,080h
- DB 067h; STOSB
- DB 066h; LOOP @@MainLoop
- END;
- { *** Create Loop-Extension }
- IF Module^.Module_SamplePointer^[I3]^.Sample_Flags AND c_Sample_Flags_LoopActive = c_Sample_Flags_LoopActive THEN
- BEGIN
- CopySource := Module^.Module_SamplePointer^[I3]^.Sample_LoopBegin;
- CopyDestination := Module^.Module_SamplePointer^[I3]^.Sample_LoopEnd;
- CopyLength := CopyDestination - CopySource;
- ASM
- { *** load sample-selector }
- MOV ES,WORD PTR TempP[00002h]
- DB 066h; MOV DI,WORD PTR CopyDestination
- { *** calculate number of full sample-loops to copy }
- XOR DX,DX
- MOV AX,c_LoopExtensionSize
- MOV BX,WORD PTR CopyLength
- DIV BX
- OR AX,AX
- JE @@NoFullLoop
- { *** copy some full-loops (size=bx) }
- MOV CX,AX
- @@InnerLoop:
- PUSH CX
- DB 066h; MOV SI,WORD PTR CopySource
- MOV CX,BX
- DB 0F3h; DB 026h,067h,0A4h { REP MOVS BYTE PTR ES:[EDI],ES:[ESI] }
- POP CX
- LOOP @@InnerLoop
- @@NoFullLoop:
- { *** calculate number of rest-bytes to copy }
- DB 066h; MOV SI,WORD PTR CopySource
- MOV CX,DX
- DB 0F3h; DB 026h,067h,0A4h { REP MOVS BYTE PTR ES:[EDI],ES:[ESI] }
- END;
- END
- ELSE
- BEGIN
- CopyDestination := Module^.Module_SamplePointer^[I3]^.Sample_Length;
- ASM
- { *** load sample-selector }
- MOV ES,WORD PTR TempP[00002h]
- DB 066h; MOV DI,WORD PTR CopyDestination
- { *** clear extension }
- MOV CX,c_LoopExtensionSize
- MOV AL,080h
- DB 0F3h; DB 067h,0AAh { REP STOS BYTE PTR ES:[EDI] }
- END;
- END;
- END;
- { *** next sample }
- END;
- { *** init period-ranges }
- NTMIK_MaximumPeriod := $0000D600 SHR 1;
- NTMIK_MinimumPeriod := $0000D600 SHR 8;
- { *** close file }
- CLOSE(InFile);
- { *** dispose all dynamic variables }
- DISPOSE(Header);
- DISPOSE(Sample);
- DISPOSE(Order);
- DISPOSE(ChannelSettings);
- DISPOSE(MultiPurposeBuffer);
- DISPOSE(PatternBuffer);
- { *** set errorcode to noerror }
- ErrorCode := c_NoError;
- END;
+ row_data += m_nChannels;
+ dwPatternOffset += rowSize;
+ }
-*/
+ }
+ if(!sComment.empty())
+ {
+ m_lpszSongComments = new char[sComment.length() + 1];
+ if (m_lpszSongComments)
+ {
+ memset(m_lpszSongComments, 0, sComment.length() + 1);
+ memcpy(m_lpszSongComments, sComment.c_str(), sComment.length());
+ }
+ }
+
+ return true;
+
+ #undef ASSERT_CAN_READ
+}
Modified: trunk/OpenMPT/soundlib/Load_s3m.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_s3m.cpp 2009-08-20 20:43:52 UTC (rev 336)
+++ trunk/OpenMPT/soundlib/Load_s3m.cpp 2009-08-22 10:21:22 UTC (rev 337)
@@ -376,6 +376,10 @@
insfile[iSmp] = ((DWORD)LittleEndianW(*((LPWORD)(s+0x0E)))) << 4;
insfile[iSmp] += ((DWORD)(BYTE)s[0x0D]) << 20;
if (insfile[iSmp] > dwMemLength) insfile[iSmp] &= 0xFFFF;
+
+ if(Samples[iSmp].nLoopEnd <= 4)
+ Samples[iSmp].nLoopStart = Samples[iSmp].nLoopEnd = 0;
+
if ((Samples[iSmp].nLoopStart >= Samples[iSmp].nLoopEnd) || (Samples[iSmp].nLoopEnd - Samples[iSmp].nLoopStart < 1))
Samples[iSmp].nLoopStart = Samples[iSmp].nLoopEnd = 0;
Samples[iSmp].nPan = 0x80;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-08-20 20:44:03
|
Revision: 336
http://modplug.svn.sourceforge.net/modplug/?rev=336&view=rev
Author: saga-games
Date: 2009-08-20 20:43:52 +0000 (Thu, 20 Aug 2009)
Log Message:
-----------
[Ref] Dabbling with order limits (especially in the module loaders) so that...
[Fix] ...Inserting more than 128 orders in MOD format is not possible anymore.
[Fix] More order overflow checks
[Fix] Fixed checks when Instruments or Samples were created. Also added test checks for those numbers.
[Mod] Moved tagging.h into the appropriate "folder" of the project file.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Ctrl_ins.cpp
trunk/OpenMPT/mptrack/Ctrl_pat.cpp
trunk/OpenMPT/mptrack/Ctrl_seq.cpp
trunk/OpenMPT/mptrack/Ctrl_smp.cpp
trunk/OpenMPT/mptrack/Moddoc.cpp
trunk/OpenMPT/mptrack/Moddoc.h
trunk/OpenMPT/mptrack/Modedit.cpp
trunk/OpenMPT/mptrack/mptrack.vcproj
trunk/OpenMPT/mptrack/mptrack_08.vcproj
trunk/OpenMPT/mptrack/test/test.cpp
trunk/OpenMPT/mptrack/typedefs.h
trunk/OpenMPT/soundlib/LOAD_AMF.CPP
trunk/OpenMPT/soundlib/LOAD_DBM.CPP
trunk/OpenMPT/soundlib/LOAD_DMF.CPP
trunk/OpenMPT/soundlib/LOAD_DSM.CPP
trunk/OpenMPT/soundlib/Load_ams.cpp
trunk/OpenMPT/soundlib/Load_far.cpp
trunk/OpenMPT/soundlib/Load_imf.cpp
trunk/OpenMPT/soundlib/Load_mdl.cpp
trunk/OpenMPT/soundlib/Load_med.cpp
trunk/OpenMPT/soundlib/Load_mid.cpp
trunk/OpenMPT/soundlib/Load_mod.cpp
trunk/OpenMPT/soundlib/Load_mt2.cpp
trunk/OpenMPT/soundlib/Load_okt.cpp
trunk/OpenMPT/soundlib/Load_psm.cpp
trunk/OpenMPT/soundlib/Load_wav.cpp
trunk/OpenMPT/soundlib/Sndfile.cpp
Modified: trunk/OpenMPT/mptrack/Ctrl_ins.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -1503,7 +1503,7 @@
}
BOOL bFirst = (pSndFile->m_nInstruments) ? FALSE : TRUE;
LONG ins = m_pModDoc->InsertInstrument(0);
- if (ins > 0)
+ if (ins != INSTRUMENTINDEX_INVALID)
{
SetCurrentInstrument(ins);
m_pModDoc->UpdateAllViews(NULL, (ins << HINT_SHIFT_INS) | HINT_INSTRUMENT | HINT_INSNAMES | HINT_ENVELOPE);
@@ -1525,7 +1525,7 @@
{
BOOL bFirst = (pSndFile->m_nInstruments) ? FALSE : TRUE;
LONG ins = m_pModDoc->InsertInstrument(0, m_nInstrument);
- if (ins > 0)
+ if (ins != INSTRUMENTINDEX_INVALID)
{
SetCurrentInstrument(ins);
m_pModDoc->UpdateAllViews(NULL, (ins << HINT_SHIFT_INS) | HINT_INSTRUMENT | HINT_INSNAMES | HINT_ENVELOPE);
Modified: trunk/OpenMPT/mptrack/Ctrl_pat.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -877,6 +877,8 @@
ORD_SELECTION selection = m_OrderList.GetCurSel(false);
ORDERINDEX nInsertCount = selection.nOrdHi - selection.nOrdLo;
ORDERINDEX nInsertWhere = selection.nOrdLo + nInsertCount + 1;
+ if (nInsertWhere >= pSndFile->GetModSpecifications().ordersMax)
+ return;
bool bSuccess = false;
// has this pattern been duplicated already? (for multiselect)
vector<PATTERNINDEX> pReplaceIndex;
@@ -917,14 +919,15 @@
nNewPat = pReplaceIndex[nCurPat]; // take care of patterns that have been duplicated before
else
nNewPat= pSndFile->Order[selection.nOrdLo + i];
- pSndFile->Order[selection.nOrdLo + i + nInsertCount + 1] = nNewPat;
+ if (selection.nOrdLo + i + nInsertCount + 1 < pSndFile->Order.GetCount())
+ pSndFile->Order[selection.nOrdLo + i + nInsertCount + 1] = nNewPat;
}
}
if(bSuccess)
{
m_OrderList.InvalidateRect(NULL, FALSE);
m_OrderList.SetCurSel(nInsertWhere);
- SetCurrentPattern(pSndFile->Order[nInsertWhere]);
+ SetCurrentPattern(pSndFile->Order[min(nInsertWhere, pSndFile->Order.GetCount()-1)]);
m_pModDoc->SetModified();
m_pModDoc->UpdateAllViews(NULL, HINT_MODSEQUENCE|HINT_PATNAMES, this);
if(selection.nOrdHi != selection.nOrdLo) m_OrderList.m_nScrollPos2nd = nInsertWhere + nInsertCount;
Modified: trunk/OpenMPT/mptrack/Ctrl_seq.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -570,15 +570,12 @@
s[0] = 0;
if ((nOrder >= 0) && (rect.left + m_cxFont - 4 <= rcClient.right))
{
- if (nOrder == pSndFile->Order.GetInvalidPatIndex()) strcpy(s, "---"); //Print the 'dots'
- else
+ if (nIndex < pSndFile->Order.GetCount())
{
- if (nOrder < pSndFile->Patterns.Size()) wsprintf(s, "%d", nOrder);
- else
- {
- if(nOrder == pSndFile->Order.GetIgnoreIndex()) strcpy(s, "+++");
- else strcpy(s, "???");
- }
+ if (nOrder == pSndFile->Order.GetInvalidPatIndex()) strcpy(s, "---");
+ else if (nOrder == pSndFile->Order.GetIgnoreIndex()) strcpy(s, "+++");
+ else if (nOrder < pSndFile->Patterns.Size()) wsprintf(s, "%d", nOrder);
+ else strcpy(s, "???");
}
}
dc.SetTextColor((bHighLight) ? colorTextSel : colorText);
@@ -912,7 +909,7 @@
ORD_SELECTION selection = GetCurSel(false);
ORDERINDEX nInsertCount = selection.nOrdHi - selection.nOrdLo, nInsertEnd = selection.nOrdHi;
- for(int i = 0; i <= nInsertCount; i++)
+ for(ORDERINDEX i = 0; i <= nInsertCount; i++)
{
//Checking whether there is some pattern at the end of orderlist.
@@ -922,7 +919,7 @@
pSndFile->Order.push_back(pSndFile->Order.GetInvalidPatIndex());
}
- for (int i=pSndFile->Order.size() - 1; i>nInsertEnd; i--) pSndFile->Order[i] = pSndFile->Order[i - 1];
+ for(int j = pSndFile->Order.size() - 1; j > nInsertEnd; j--) pSndFile->Order[j] = pSndFile->Order[j - 1];
}
// now that there is enough space in the order list, overwrite the orders
for(ORDERINDEX i = 0; i <= nInsertCount; i++)
@@ -930,8 +927,8 @@
if(nInsertEnd + i + 1 < pSndFile->GetModSpecifications().ordersMax)
pSndFile->Order[nInsertEnd + i + 1] = pSndFile->Order[nInsertEnd - nInsertCount + i];
}
- m_nScrollPos = nInsertEnd + 1;
- m_nScrollPos2nd = m_nScrollPos + nInsertCount;
+ m_nScrollPos = min(nInsertEnd + 1, pSndFile->Order.GetCount() - 1);
+ m_nScrollPos2nd = min(m_nScrollPos + nInsertCount, pSndFile->Order.GetCount() - 1);
InvalidateRect(NULL, FALSE);
m_pModDoc->SetModified();
m_pModDoc->UpdateAllViews(NULL, HINT_MODSEQUENCE, this);
Modified: trunk/OpenMPT/mptrack/Ctrl_smp.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -884,7 +884,7 @@
//------------------------------
{
LONG smp = m_pModDoc->InsertSample(TRUE);
- if (smp > 0)
+ if (smp != SAMPLEINDEX_INVALID)
{
if(pSampleUndoBuffer) OnPitchShiftTimeStretchCancel();
Modified: trunk/OpenMPT/mptrack/Moddoc.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -1987,7 +1987,7 @@
//----------------------------
{
LONG smp = InsertSample();
- if (smp >= 0) ViewSample(smp);
+ if (smp != SAMPLEINDEX_INVALID) ViewSample(smp);
}
@@ -1995,7 +1995,7 @@
//--------------------------------
{
LONG ins = InsertInstrument();
- if (ins >= 0) ViewInstrument(ins);
+ if (ins != INSTRUMENTINDEX_INVALID) ViewInstrument(ins);
}
Modified: trunk/OpenMPT/mptrack/Moddoc.h
===================================================================
--- trunk/OpenMPT/mptrack/Moddoc.h 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/mptrack/Moddoc.h 2009-08-20 20:43:52 UTC (rev 336)
@@ -199,7 +199,7 @@
PATTERNINDEX InsertPattern(ORDERINDEX nOrd = -1, ROWINDEX nRows = 64);
SAMPLEINDEX InsertSample(bool bLimit = false);
- INSTRUMENTINDEX InsertInstrument(LONG lSample=0, LONG lDuplicate=0);
+ INSTRUMENTINDEX InsertInstrument(LONG lSample = 0, LONG lDuplicate = 0);
void InitializeInstrument(MODINSTRUMENT *pIns, UINT nsample=0);
bool RemoveOrder(ORDERINDEX n);
bool RemovePattern(PATTERNINDEX n);
Modified: trunk/OpenMPT/mptrack/Modedit.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -1661,10 +1661,10 @@
}
}
if (((bLimit) && (i >= 200) && (!m_SndFile.m_nInstruments))
- || (i >= MAX_SAMPLES))
+ || (i >= m_SndFile.GetModSpecifications().samplesMax))
{
ErrorBox(IDS_ERR_TOOMANYSMP, CMainFrame::GetMainFrame());
- return -1;
+ return SAMPLEINDEX_INVALID;
}
if (!m_SndFile.m_szNames[i][0]) strcpy(m_SndFile.m_szNames[i], "untitled");
MODSAMPLE *pSmp = &m_SndFile.Samples[i];
@@ -1690,7 +1690,8 @@
//-----------------------------------------------------------
{
MODINSTRUMENT *pDup = NULL;
- if ((m_SndFile.m_nType != MOD_TYPE_XM) && !(m_SndFile.m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT))) return -1;
+ INSTRUMENTINDEX nInstrumentMax = m_SndFile.GetModSpecifications().instrumentsMax - 1;
+ if ((m_SndFile.m_nType != MOD_TYPE_XM) && !(m_SndFile.m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT))) return INSTRUMENTINDEX_INVALID;
if ((lDuplicate > 0) && (lDuplicate <= (LONG)m_SndFile.m_nInstruments))
{
pDup = m_SndFile.Instruments[lDuplicate];
@@ -1702,7 +1703,7 @@
if (n == IDYES)
{
UINT nInstruments = m_SndFile.m_nSamples;
- if (nInstruments >= MAX_INSTRUMENTS) nInstruments = MAX_INSTRUMENTS-1;
+ if (nInstruments > nInstrumentMax) nInstruments = nInstrumentMax;
for (UINT smp=1; smp<=nInstruments; smp++)
{
m_SndFile.Samples[smp].uFlags &= ~CHN_MUTE;
@@ -1721,7 +1722,7 @@
}
m_SndFile.m_nInstruments = nInstruments;
} else
- if (n != IDNO) return -1;
+ if (n != IDNO) return INSTRUMENTINDEX_INVALID;
}
UINT newins = 0;
for (UINT i=1; i<=m_SndFile.m_nInstruments; i++)
@@ -1734,10 +1735,10 @@
}
if (!newins)
{
- if (m_SndFile.m_nInstruments >= MAX_INSTRUMENTS-1)
+ if (m_SndFile.m_nInstruments >= nInstrumentMax)
{
ErrorBox(IDS_ERR_TOOMANYINS, CMainFrame::GetMainFrame());
- return -1;
+ return INSTRUMENTINDEX_INVALID;
}
newins = ++m_SndFile.m_nInstruments;
}
@@ -1745,7 +1746,7 @@
if (pIns)
{
UINT newsmp = 0;
- if ((lSample > 0) && (lSample < MAX_SAMPLES))
+ if ((lSample > 0) && (lSample < m_SndFile.GetModSpecifications().samplesMax))
{
newsmp = lSample;
} else
@@ -1762,7 +1763,7 @@
if (!newsmp)
{
int inssmp = InsertSample();
- if (inssmp > 0) newsmp = inssmp;
+ if (inssmp != SAMPLEINDEX_INVALID) newsmp = inssmp;
}
}
BEGIN_CRITICAL();
@@ -1784,7 +1785,7 @@
} else
{
ErrorBox(IDS_ERR_OUTOFMEMORY, CMainFrame::GetMainFrame());
- return -1;
+ return INSTRUMENTINDEX_INVALID;
}
return newins;
}
Modified: trunk/OpenMPT/mptrack/mptrack.vcproj
===================================================================
--- trunk/OpenMPT/mptrack/mptrack.vcproj 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/mptrack/mptrack.vcproj 2009-08-20 20:43:52 UTC (rev 336)
@@ -481,9 +481,6 @@
RelativePath=".\tagging.cpp">
</File>
<File
- RelativePath=".\tagging.h">
- </File>
- <File
RelativePath=".\view_com.cpp">
</File>
<File
@@ -870,6 +867,9 @@
RelativePath=".\StdAfx.h">
</File>
<File
+ RelativePath=".\tagging.h">
+ </File>
+ <File
RelativePath=".\typedefs.h">
</File>
<File
Modified: trunk/OpenMPT/mptrack/mptrack_08.vcproj
===================================================================
--- trunk/OpenMPT/mptrack/mptrack_08.vcproj 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/mptrack/mptrack_08.vcproj 2009-08-20 20:43:52 UTC (rev 336)
@@ -645,10 +645,6 @@
>
</File>
<File
- RelativePath=".\tagging.h"
- >
- </File>
- <File
RelativePath=".\view_com.cpp"
>
</File>
@@ -1151,6 +1147,10 @@
>
</File>
<File
+ RelativePath=".\tagging.h"
+ >
+ </File>
+ <File
RelativePath=".\typedefs.h"
>
</File>
Modified: trunk/OpenMPT/mptrack/test/test.cpp
===================================================================
--- trunk/OpenMPT/mptrack/test/test.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/mptrack/test/test.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -163,6 +163,9 @@
VERIFY_EQUAL(ROWINDEX_MAX, (std::numeric_limits<ROWINDEX>::max)());
VERIFY_EQUAL(ORDERINDEX_MAX, (std::numeric_limits<ORDERINDEX>::max)());
+ VERIFY_EQUAL(PATTERNINDEX_MAX, (std::numeric_limits<PATTERNINDEX>::max)());
+ VERIFY_EQUAL(SAMPLEINDEX_MAX, (std::numeric_limits<SAMPLEINDEX>::max)());
+ VERIFY_EQUAL(INSTRUMENTINDEX_MAX, (std::numeric_limits<INSTRUMENTINDEX>::max)());
}
Modified: trunk/OpenMPT/mptrack/typedefs.h
===================================================================
--- trunk/OpenMPT/mptrack/typedefs.h 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/mptrack/typedefs.h 2009-08-20 20:43:52 UTC (rev 336)
@@ -43,7 +43,11 @@
typedef uint8 PLUGINDEX;
typedef uint16 TEMPO;
typedef uint16 SAMPLEINDEX;
+ const SAMPLEINDEX SAMPLEINDEX_MAX = uint16_max;
+ const SAMPLEINDEX SAMPLEINDEX_INVALID = SAMPLEINDEX_MAX;
typedef uint16 INSTRUMENTINDEX;
+ const SAMPLEINDEX INSTRUMENTINDEX_MAX = uint16_max;
+ const SAMPLEINDEX INSTRUMENTINDEX_INVALID = INSTRUMENTINDEX_MAX;
typedef uint32 MODTYPE;
Modified: trunk/OpenMPT/soundlib/LOAD_AMF.CPP
===================================================================
--- trunk/OpenMPT/soundlib/LOAD_AMF.CPP 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/soundlib/LOAD_AMF.CPP 2009-08-20 20:43:52 UTC (rev 336)
@@ -191,10 +191,7 @@
m_nSamples = 31;
m_nDefaultTempo = 125;
m_nDefaultSpeed = 6;
- for (UINT iOrd=0; iOrd<MAX_ORDERS; iOrd++)
- {
- Order[iOrd] = (iOrd < numorders) ? lpStream[dwMemPos+iOrd] : Order.GetInvalidPatIndex();
- }
+ Order.ReadAsByte(lpStream + dwMemPos, numorders, dwMemLength - dwMemPos);
dwMemPos = 294; // ???
for (UINT iSmp=0; iSmp<numsamples; iSmp++)
{
@@ -307,21 +304,18 @@
dwMemPos += 2;
}
// Setup sequence list
- for (UINT iOrd=0; iOrd<MAX_ORDERS; iOrd++)
+ Order.resize(pfh->numorders, Order.GetInvalidPatIndex());
+ for (UINT iOrd=0; iOrd < pfh->numorders; iOrd++)
{
- Order[iOrd] = Order.GetInvalidPatIndex();
- if (iOrd < pfh->numorders)
+ Order[iOrd] = iOrd;
+ Patterns[iOrd].Resize(64);
+ if (pfh->version >= 14)
{
- Order[iOrd] = iOrd;
- Patterns[iOrd].Resize(64);
- if (pfh->version >= 14)
- {
- Patterns[iOrd].Resize(LittleEndianW(*(USHORT *)(lpStream+dwMemPos)));
- dwMemPos += 2;
- }
- ptracks[iOrd] = (USHORT *)(lpStream+dwMemPos);
- dwMemPos += m_nChannels * sizeof(USHORT);
+ Patterns[iOrd].Resize(LittleEndianW(*(USHORT *)(lpStream+dwMemPos)));
+ dwMemPos += 2;
}
+ ptracks[iOrd] = (USHORT *)(lpStream+dwMemPos);
+ dwMemPos += m_nChannels * sizeof(USHORT);
}
if (dwMemPos + m_nSamples * (sizeof(AMFSAMPLE)+8) > dwMemLength) return true;
// Read Samples
Modified: trunk/OpenMPT/soundlib/LOAD_DBM.CPP
===================================================================
--- trunk/OpenMPT/soundlib/LOAD_DBM.CPP 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/soundlib/LOAD_DBM.CPP 2009-08-20 20:43:52 UTC (rev 336)
@@ -120,10 +120,11 @@
if (m_nChannels > 64) m_nChannels = 64;
memcpy(m_szNames[0], (pfh->songname[0]) ? pfh->songname : pfh->songname2, 32);
m_szNames[0][31] = 0;
+ Order.resize(nOrders, Order.GetInvalidPatIndex());
for (UINT iOrd=0; iOrd < nOrders; iOrd++)
{
- Order[iOrd] = lpStream[dwMemPos+iOrd*2+1];
- if (iOrd >= MAX_ORDERS-2) break;
+ if (iOrd >= MAX_ORDERS) break;
+ Order[iOrd] = (PATTERNINDEX)BigEndianW(*((WORD *)(lpStream + dwMemPos + iOrd * 2)));
}
dwMemPos += 2*nOrders;
while (dwMemPos + 10 < dwMemLength)
Modified: trunk/OpenMPT/soundlib/LOAD_DMF.CPP
===================================================================
--- trunk/OpenMPT/soundlib/LOAD_DMF.CPP 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/soundlib/LOAD_DMF.CPP 2009-08-20 20:43:52 UTC (rev 336)
@@ -145,8 +145,9 @@
{
UINT nseq = sequ->seqsize >> 1;
if (nseq >= MAX_ORDERS-1) nseq = MAX_ORDERS-1;
+ Order.resize(nseq, Order.GetInvalidPatIndex());
if (sequ->loopstart < nseq) m_nRestartPos = sequ->loopstart;
- for (UINT i=0; i<nseq; i++) Order[i] = (BYTE)sequ->sequ[i];
+ for (UINT i = 0; i < nseq; i++) Order[i] = (PATTERNINDEX)sequ->sequ[i];
}
dwMemPos += sequ->seqsize + 8;
break;
Modified: trunk/OpenMPT/soundlib/LOAD_DSM.CPP
===================================================================
--- trunk/OpenMPT/soundlib/LOAD_DSM.CPP 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/soundlib/LOAD_DSM.CPP 2009-08-20 20:43:52 UTC (rev 336)
@@ -110,10 +110,8 @@
m_nDefaultGlobalVolume = psong->globalvol << 2;
if ((!m_nDefaultGlobalVolume) || (m_nDefaultGlobalVolume > 256)) m_nDefaultGlobalVolume = 256;
m_nSamplePreAmp = psong->mastervol & 0x7F;
- for (UINT iOrd=0; iOrd<MAX_ORDERS; iOrd++)
- {
- Order[iOrd] = (BYTE)((iOrd < psong->numord) ? psong->orders[iOrd] : 0xFF);
- }
+ Order.ReadAsByte(psong->orders, psong->numord, sizeof(psong->orders));
+
for (UINT iPan=0; iPan<16; iPan++)
{
ChnSettings[iPan].nPan = 0x80;
Modified: trunk/OpenMPT/soundlib/Load_ams.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_ams.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/soundlib/Load_ams.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -103,8 +103,12 @@
for (UINT cNam=0; cNam<m_nChannels; cNam++)
{
if (dwMemPos + 32 >= dwMemLength) return true;
- tmp = lpStream[dwMemPos++];
- dwMemPos += tmp;
+ BYTE chnnamlen = lpStream[dwMemPos++];
+ if ((chnnamlen) && (chnnamlen < MAX_CHANNELNAME))
+ {
+ memcpy(ChnSettings[cNam].szName, lpStream + dwMemPos + 1, chnnamlen);
+ }
+ dwMemPos += chnnamlen;
}
// Read Pattern Names
m_lpszPatternNames = new char[pfh->patterns * 32];
@@ -132,10 +136,10 @@
dwMemPos += tmp;
}
// Read Order List
- for (UINT iOrd=0; iOrd<pfh->orders; iOrd++, dwMemPos += 2)
+ Order.resize(pfh->orders, Order.GetInvalidPatIndex());
+ for (UINT iOrd=0; iOrd < pfh->orders; iOrd++, dwMemPos += 2)
{
- UINT n = *((WORD *)(lpStream+dwMemPos));
- Order[iOrd] = n;
+ Order[iOrd] = (PATTERNINDEX)*((WORD *)(lpStream + dwMemPos));
}
// Read Patterns
for (UINT iPat=0; iPat<pfh->patterns; iPat++)
@@ -459,15 +463,12 @@
}
// Order List
{
- for (UINT i=0; i<MAX_ORDERS; i++)
+ if ((dwMemPos + 2 * psh->orders) >= dwMemLength) return TRUE;
+ Order.resize(psh->orders, Order.GetInvalidPatIndex());
+ for (UINT iOrd = 0; iOrd < psh->orders; iOrd++)
{
- Order[i] = Order.GetInvalidPatIndex();
- if (dwMemPos + 2 >= dwMemLength) return TRUE;
- if (i < psh->orders)
- {
- Order[i] = lpStream[dwMemPos];
- dwMemPos += 2;
- }
+ Order[iOrd] = (PATTERNINDEX)*((WORD *)(lpStream + dwMemPos));
+ dwMemPos += 2;
}
}
// Pattern Data
Modified: trunk/OpenMPT/soundlib/Load_far.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_far.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/soundlib/Load_far.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -114,10 +114,8 @@
pmh2 = &farHeader2;
dwMemPos += sizeof(FARHEADER2);
if (dwMemPos >= dwMemLength) return true;
- for (UINT iorder=0; iorder<MAX_ORDERS; iorder++)
- {
- Order[iorder] = (iorder <= pmh2->snglen) ? pmh2->orders[iorder] : Order.GetInvalidPatIndex();
- }
+
+ Order.ReadAsByte(pmh2->orders, pmh2->snglen, sizeof(pmh2->orders));
m_nRestartPos = pmh2->loopto;
// Reading Patterns
dwMemPos += headerlen - (869 + pmh1->stlen);
Modified: trunk/OpenMPT/soundlib/Load_imf.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_imf.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/soundlib/Load_imf.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -329,8 +329,9 @@
}
if(!m_nChannels) return false;
+ Order.resize(hdr.ordnum);
for (ORDERINDEX nOrd = 0; nOrd < hdr.ordnum; nOrd++)
- Order[nOrd] = ((hdr.orderlist[nOrd] == 0xff) ? Order.GetIgnoreIndex() : hdr.orderlist[nOrd]);
+ Order[nOrd] = ((hdr.orderlist[nOrd] == 0xff) ? Order.GetIgnoreIndex() : (PATTERNINDEX)hdr.orderlist[nOrd]);
// read patterns
for (PATTERNINDEX nPat = 0; nPat < hdr.patnum; nPat++)
Modified: trunk/OpenMPT/soundlib/Load_mdl.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_mdl.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/soundlib/Load_mdl.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -245,7 +245,7 @@
else
m_nChannels = i+1;
}
- for (j=0; j<norders; j++) Order[j] = pmib->seq[j];
+ Order.ReadAsByte(pmib->seq, norders, sizeof(pmib->seq));
break;
// ME: song message
case 0x454D:
Modified: trunk/OpenMPT/soundlib/Load_med.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_med.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/soundlib/Load_med.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -670,19 +670,20 @@
UINT n = BigEndianW(pmps->length);
if (pseq+n <= dwMemLength)
{
+ Order.resize(nOrders++);
for (UINT i=0; i<n; i++)
{
- UINT seqval = pmps->seq[i] >> 8;
+ WORD seqval = BigEndian(pmps->seq[i]);
if ((seqval < wNumBlocks) && (nOrders < MAX_ORDERS-1))
{
- Order[nOrders++] = seqval;
+ Order[nOrders++] = (ORDERINDEX)seqval;
}
}
}
}
}
playtransp = pmsh2->playtransp;
- while (nOrders < MAX_ORDERS) Order[nOrders++] = 0xFF;
+ while (nOrders < MAX_ORDERS) Order[nOrders++] = Order.GetInvalidPatIndex();
}
// Reading Expansion structure
if (pmex)
Modified: trunk/OpenMPT/soundlib/Load_mid.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_mid.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/soundlib/Load_mid.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -563,7 +563,7 @@
Log("%d tracks, tempo = %dus, division = %04X TickFactor=%d\n", tracks, nTempoUsec, ((UINT)division) & 0xFFFF, nTickMultiplier);
#endif
// Initializing
- Order.assign(Order.size(), Order.GetInvalidPatIndex());
+ Order.resize(MAX_ORDERS, Order.GetInvalidPatIndex());
memset(chnstate, 0, sizeof(chnstate));
memset(miditracks, 0, sizeof(miditracks));
memset(midichstate, 0, sizeof(midichstate));
Modified: trunk/OpenMPT/soundlib/Load_mod.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_mod.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/soundlib/Load_mod.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -291,7 +291,6 @@
pMagic = (PMODMAGIC)(lpStream+dwMemPos);
dwMemPos += sizeof(MODMAGIC);
if (m_nSamples == 15) dwMemPos -= 4;
- Order.assign(Order.size(), 0);
Order.ReadAsByte(pMagic->Orders, 128, 128);
UINT nbp, nbpbuggy, nbpbuggy2, norders;
@@ -315,7 +314,7 @@
}
if (i >= nbpbuggy2) nbpbuggy2 = i+1;
}
- for (UINT iend=norders; iend<MAX_ORDERS; iend++) Order[iend] = Order.GetInvalidPatIndex();
+ for (UINT iend = norders; iend < 0x80; iend++) Order[iend] = Order.GetInvalidPatIndex();
norders--;
m_nRestartPos = pMagic->nRestartPos;
if (m_nRestartPos >= 0x78) m_nRestartPos = 0;
Modified: trunk/OpenMPT/soundlib/Load_mt2.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_mt2.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/soundlib/Load_mt2.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -204,9 +204,10 @@
{
m_nDefaultTempo = 110250 / pfh->wSamplesPerTick;
}
- for (UINT iOrd=0; iOrd<MAX_ORDERS; iOrd++)
+ Order.resize(pfh->nOrders, Order.GetInvalidPatIndex());
+ for (UINT iOrd=0; iOrd < pfh->nOrders; iOrd++)
{
- Order[iOrd] = (BYTE)((iOrd < pfh->nOrders) ? pfh->Orders[iOrd] : 0xFF);
+ Order[iOrd] = (PATTERNINDEX)pfh->Orders[iOrd];
}
memcpy(m_szNames[0], pfh->szSongName, 32);
m_szNames[0][31] = 0;
Modified: trunk/OpenMPT/soundlib/Load_okt.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_okt.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/soundlib/Load_okt.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -107,6 +107,7 @@
{
UINT orderlen = norders;
if (orderlen >= MAX_ORDERS) orderlen = MAX_ORDERS-1;
+ Order.resize(orderlen);
for (UINT i=0; i<orderlen; i++) Order[i] = lpStream[dwMemPos+10+i];
for (UINT j=orderlen; j>1; j--) { if (Order[j-1]) break; Order[j-1] = 0xFF; }
dwMemPos += BigEndian(*((DWORD *)(lpStream + dwMemPos + 4))) + 8;
Modified: trunk/OpenMPT/soundlib/Load_psm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/soundlib/Load_psm.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -15,8 +15,8 @@
//#define PSM_LOG
-#define PSM_ID_NEW 0x204d5350
-#define PSM_ID_OLD 0xfe4d5350
+#define PSM_ID_NEW 0x204d5350 // "PSM "
+#define PSM_ID_OLD 0xfe4d5350 // "PSM\xFE"
#define IFFID_FILE 0x454c4946
#define IFFID_TITL 0x4c544954
#define IFFID_SDFT 0x54464453
@@ -226,6 +226,7 @@
}
}
UINT iOrd = 0;
+ Order.resize(MAX_ORDERS, Order.GetInvalidPatIndex());
while ((pos+5<len) && (iOrd < MAX_ORDERS))
{
DWORD dwName = *(DWORD *)(pdata+pos);
Modified: trunk/OpenMPT/soundlib/Load_wav.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_wav.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/soundlib/Load_wav.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -50,8 +50,8 @@
m_nDefaultSpeed = 8;
m_nDefaultTempo = 125;
m_dwSongFlags |= SONG_LINEARSLIDES; // For no resampling
+ Order.resize(MAX_ORDERS, Order.GetInvalidPatIndex());
Order[0] = 0;
- Order[1] = 0xFF;
bool fail = Patterns.Insert(0, 64);
fail = Patterns.Insert(1, 64);
if(fail) return true;
Modified: trunk/OpenMPT/soundlib/Sndfile.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-08-20 16:46:12 UTC (rev 335)
+++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-08-20 20:43:52 UTC (rev 336)
@@ -508,7 +508,8 @@
memset(ChnMix, 0, sizeof(ChnMix));
memset(Chn, 0, sizeof(Chn));
memset(Instruments, 0, sizeof(Instruments));
- Order.assign(MAX_ORDERS, Order.GetInvalidPatIndex());
+ //Order.assign(MAX_ORDERS, Order.GetInvalidPatIndex());
+ Order.resize(1, Order.GetInvalidPatIndex());
Patterns.ClearPatterns();
memset(m_szNames, 0, sizeof(m_szNames));
memset(m_MixPlugins, 0, sizeof(m_MixPlugins));
@@ -706,7 +707,7 @@
if ((m_nRestartPos >= Order.size()) || (Order[m_nRestartPos] >= Patterns.Size())) m_nRestartPos = 0;
// Load plugins only when m_pModDoc != 0. (can be == 0 for example when examining module samples in treeview.
- CString sNotFound;
+ string sNotFound;
bool bSearchIDs[MAX_MIXPLUGINS] = {false};
UINT iShowNotFound = 0;
@@ -757,7 +758,7 @@
sNotFound = "The following plugins have not been found:\n\n" + sNotFound + "\nDo you want to search for them on KVRAudio?"
"\nWARNING: A browser window / tab is opened for every plugin. If you do not want that, you can visit http://www.kvraudio.com/search.php";
}
- if (::MessageBox(0, sNotFound, "OpenMPT - Plugins missing", MB_YESNO | MB_DEFBUTTON2 | MB_ICONQUESTION) == IDYES)
+ if (::MessageBox(0, sNotFound.c_str(), "OpenMPT - Plugins missing", MB_YESNO | MB_DEFBUTTON2 | MB_ICONQUESTION) == IDYES)
for (UINT iPlug = 0; iPlug < MAX_MIXPLUGINS; iPlug++)
if (bSearchIDs[iPlug] == true)
{
@@ -774,6 +775,7 @@
if (m_nType)
{
SetModSpecsPointer(m_pModSpecs, m_nType);
+ Order.resize(GetModSpecifications().ordersMax, Order.GetInvalidPatIndex());
return TRUE;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2009-08-20 16:46:20
|
Revision: 335
http://modplug.svn.sourceforge.net/modplug/?rev=335&view=rev
Author: relabsoluness
Date: 2009-08-20 16:46:12 +0000 (Thu, 20 Aug 2009)
Log Message:
-----------
[New] MIDI: Can now record MIDI mapping changes to pattern.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/MIDIMappingDialog.cpp
trunk/OpenMPT/mptrack/MIDIMappingDialog.h
trunk/OpenMPT/mptrack/Mpt_midi.cpp
trunk/OpenMPT/mptrack/View_pat.cpp
trunk/OpenMPT/mptrack/View_pat.h
trunk/OpenMPT/mptrack/mptrack.rc
trunk/OpenMPT/mptrack/resource.h
trunk/OpenMPT/soundlib/midi.h
trunk/OpenMPT/soundlib/modcommand.h
Modified: trunk/OpenMPT/mptrack/MIDIMappingDialog.cpp
===================================================================
--- trunk/OpenMPT/mptrack/MIDIMappingDialog.cpp 2009-08-19 15:20:48 UTC (rev 334)
+++ trunk/OpenMPT/mptrack/MIDIMappingDialog.cpp 2009-08-20 16:46:12 UTC (rev 335)
@@ -52,6 +52,7 @@
ON_BN_CLICKED(IDC_BUTTON_REMOVE, OnBnClickedButtonRemove)
ON_MESSAGE(WM_MOD_MIDIMSG, OnMidiMsg)
ON_NOTIFY(UDN_DELTAPOS, IDC_SPINMOVEMAPPING, OnDeltaposSpinmovemapping)
+ ON_BN_CLICKED(IDC_CHECK_PATRECORD, OnBnClickedCheckPatRecord)
END_MESSAGE_MAP()
@@ -77,10 +78,15 @@
{
CDialog::OnInitDialog();
+ if (m_rMIDIMapper.GetCount() > 0)
+ m_Setting = m_rMIDIMapper.GetDirective(0);
+
m_ChannelCBox.SetCurSel(m_Setting.GetChannel());
- CheckDlgButton(IDC_CHECKACTIVE, m_Setting.IsActive() ? MF_CHECKED : MF_UNCHECKED);
- CheckDlgButton(IDC_CHECKCAPTURE, m_Setting.GetCaptureMIDI() ? MF_CHECKED : MF_UNCHECKED);
+ CheckDlgButton(IDC_CHECKACTIVE, m_Setting.IsActive() ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(IDC_CHECKCAPTURE, m_Setting.GetCaptureMIDI() ? BST_CHECKED : BST_UNCHECKED);
+ GetDlgItem(IDC_CHECK_PATRECORD)->ShowWindow((m_rSndFile.GetType() == MOD_TYPE_MPT) ? SW_SHOW : SW_HIDE);
+ CheckDlgButton(IDC_CHECK_PATRECORD, m_Setting.GetAllowPatternEdit() ? BST_CHECKED : BST_UNCHECKED);
m_EventCBox.SetCurSel(0);
@@ -168,6 +174,14 @@
}
+void CMIDIMappingDialog::OnBnClickedCheckPatRecord()
+//--------------------------------------------------
+{
+ m_Setting.SetAllowPatternEdit(IsDlgButtonChecked(IDC_CHECK_PATRECORD) == BST_CHECKED);
+ UpdateString();
+}
+
+
void CMIDIMappingDialog::UpdateString()
//-------------------------------------
{
Modified: trunk/OpenMPT/mptrack/MIDIMappingDialog.h
===================================================================
--- trunk/OpenMPT/mptrack/MIDIMappingDialog.h 2009-08-19 15:20:48 UTC (rev 334)
+++ trunk/OpenMPT/mptrack/MIDIMappingDialog.h 2009-08-20 16:46:12 UTC (rev 335)
@@ -65,4 +65,5 @@
afx_msg void OnBnClickedButtonRemove();
afx_msg LRESULT OnMidiMsg(WPARAM, LPARAM);
afx_msg void OnDeltaposSpinmovemapping(NMHDR *pNMHDR, LRESULT *pResult);
+ afx_msg void OnBnClickedCheckPatRecord();
};
Modified: trunk/OpenMPT/mptrack/Mpt_midi.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Mpt_midi.cpp 2009-08-19 15:20:48 UTC (rev 334)
+++ trunk/OpenMPT/mptrack/Mpt_midi.cpp 2009-08-20 16:46:12 UTC (rev 335)
@@ -192,7 +192,8 @@
uint8 temp8 = citer->IsActive(); //bit 0
if(citer->GetCaptureMIDI()) temp8 |= (1 << 1); //bit 1
//bits 2-4: Mapping type: 0 for plug param control.
- //bit 5: if(citer->GetAllowPatternEdit()) temp8 |= (1 << 4);
+ //bit 5:
+ if(citer->GetAllowPatternEdit()) temp8 |= (1 << 5);
//bits 6-7: Size: 5, 6, 8, 12
BYTE parambytes = 4;
@@ -238,7 +239,7 @@
CMIDIMappingDirective s;
s.SetActive((i8 & 1) != 0);
s.SetCaptureMIDI((i8 & (1 << 1)) != 0);
- s.SetAllowPatternEdit((i8 & (1 << 4)) != 0);
+ s.SetAllowPatternEdit((i8 & (1 << 5)) != 0);
memcpy(&i16, ptr, 2); ptr += 2; //Channel, event, MIDIbyte1.
memcpy(&i8, ptr, 1); ptr++; //Plugindex
const BYTE remainingbytes = psize - 4;
Modified: trunk/OpenMPT/mptrack/View_pat.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_pat.cpp 2009-08-19 15:20:48 UTC (rev 334)
+++ trunk/OpenMPT/mptrack/View_pat.cpp 2009-08-20 16:46:12 UTC (rev 335)
@@ -3001,6 +3001,30 @@
}
+ModCommandPos CViewPattern::GetEditPos(CSoundFile& rSf, const bool bLiveRecord) const
+//-----------------------------------------------------------------------------------
+{
+ ModCommandPos editpos;
+ if(bLiveRecord)
+ SetEditPos(rSf, editpos.nRow, editpos.nPat, rSf.m_nRow, rSf.m_nPattern);
+ else
+ {editpos.nPat = m_nPattern; editpos.nRow = m_nRow;}
+ editpos.nChn = GetChanFromCursor(m_dwCursor);
+ return editpos;
+}
+
+
+MODCOMMAND* CViewPattern::GetModCommand(CSoundFile& rSf, const ModCommandPos& pos)
+//--------------------------------------------------------------------------------
+{
+ static MODCOMMAND m;
+ if (rSf.Patterns.IsValidIndex(pos.nPat) && pos.nRow < rSf.Patterns[pos.nPat].GetNumRows() && pos.nChn < rSf.GetNumChannels())
+ return rSf.Patterns[pos.nPat].GetpModCommand(pos.nRow, pos.nChn);
+ else
+ return &m;
+}
+
+
LRESULT CViewPattern::OnMidiMsg(WPARAM dwMidiDataParam, LPARAM)
//--------------------------------------------------------
{
@@ -3043,10 +3067,25 @@
if ((event == 0x9) && !nVol) event = 0x8; //Convert event to note-off if req'd
- //Try finding MIDI mapping.
- BYTE mappedIndex = 0, paramValue = 0;
+ // Handle MIDI mapping.
+ uint8 mappedIndex = uint8_max, paramValue = uint8_max;
uint32 paramIndex = 0;
- if(pSndFile->GetMIDIMapper().OnMIDImsg(dwMidiData, mappedIndex, paramIndex, paramValue))
+ const bool bCaptured = pSndFile->GetMIDIMapper().OnMIDImsg(dwMidiData, mappedIndex, paramIndex, paramValue);
+
+ // Write parameter control commands if needed.
+ if (paramValue != uint8_max && IsEditingEnabled() && pSndFile->GetType() == MOD_TYPE_MPT)
+ {
+ // Note: There's no undo for these modifications.
+ const bool bLiveRecord = IsLiveRecord(*pModDoc, *pSndFile);
+ ModCommandPos editpos = GetEditPos(*pSndFile, bLiveRecord);
+ MODCOMMAND* p = GetModCommand(*pSndFile, editpos);
+ p->Set(NOTE_PCS, mappedIndex, static_cast<uint16>(paramIndex), static_cast<uint16>((paramValue * MODCOMMAND::maxColumnValue)/127));
+ if(bLiveRecord == false)
+ InvalidateRow(editpos.nRow);
+ pMainFrm->ThreadSafeSetModified(pModDoc);
+ }
+
+ if (bCaptured)
return 0;
switch(event)
@@ -3079,17 +3118,13 @@
}
// Checking whether to record MIDI controller change as MIDI macro change.
- if((CMainFrame::m_dwMidiSetup & MIDISETUP_MIDIMACROCONTROL) && IsEditingEnabled())
+ // Don't write this if command was already written by MIDI mapping.
+ if((paramValue == uint8_max || pSndFile->GetType() != MOD_TYPE_MPT) && IsEditingEnabled() && (CMainFrame::m_dwMidiSetup & MIDISETUP_MIDIMACROCONTROL))
{
- // Note: No undo for these modifications.
+ // Note: There's no undo for these modifications.
const bool bLiveRecord = IsLiveRecord(*pModDoc, *pSndFile);
- ROWINDEX nRow = m_nRow;
- PATTERNINDEX nPat = m_nPattern;
- if(bLiveRecord)
- SetEditPos(*pSndFile, nRow, nPat, pSndFile->m_nRow, pSndFile->m_nPattern);
-
- const CHANNELINDEX nChn = GetChanFromCursor(m_dwCursor);
- MODCOMMAND *p = pSndFile->Patterns[nPat].GetpModCommand(nRow, nChn);
+ ModCommandPos editpos = GetEditPos(*pSndFile, bLiveRecord);
+ MODCOMMAND* p = GetModCommand(*pSndFile, editpos);
if(p->command == 0 || p->command == CMD_SMOOTHMIDI || p->command == CMD_MIDI)
{ // Write command only if there's no existing command or already a midi macro command.
p->command = CMD_SMOOTHMIDI;
@@ -3098,7 +3133,7 @@
// Update GUI only if not recording live.
if(bLiveRecord == false)
- InvalidateRow(nRow);
+ InvalidateRow(editpos.nRow);
}
}
@@ -4941,20 +4976,15 @@
return chans.GetCount();
}
-UINT CViewPattern::GetRowFromCursor(DWORD cursor) {
-//-----------------------------------------------
- return cursor >> 16;
-}
+ROWINDEX CViewPattern::GetRowFromCursor(DWORD cursor) {return cursor >> 16;}
+//---------------------------------------------------
+
+CHANNELINDEX CViewPattern::GetChanFromCursor(DWORD cursor) {return static_cast<CHANNELINDEX>((cursor & 0xFFFF) >> 3);}
+//-------------------------------------------------------
-UINT CViewPattern::GetChanFromCursor(DWORD cursor) {
-//------------------------------------------------
- return (cursor & 0xFFFF) >> 3;
-}
+UINT CViewPattern::GetColTypeFromCursor(DWORD cursor) {return cursor & 0x07;}
+//---------------------------------------------------
-UINT CViewPattern::GetColTypeFromCursor(DWORD cursor) {
-//--------------------------------------------------
- return cursor & 0x07;
-}
bool CViewPattern::IsInterpolationPossible(UINT startRow, UINT endRow,
UINT chan, UINT colType, CSoundFile* pSndFile) {
Modified: trunk/OpenMPT/mptrack/View_pat.h
===================================================================
--- trunk/OpenMPT/mptrack/View_pat.h 2009-08-19 15:20:48 UTC (rev 334)
+++ trunk/OpenMPT/mptrack/View_pat.h 2009-08-20 16:46:12 UTC (rev 335)
@@ -55,7 +55,14 @@
};
const RowMask DefaultRowMask = {true, true, true, true, true};
+struct ModCommandPos
+{
+ PATTERNINDEX nPat;
+ ROWINDEX nRow;
+ CHANNELINDEX nChn;
+};
+
//////////////////////////////////////////////////////////////////
// Pattern editing class
@@ -323,9 +330,9 @@
UINT GetSelectionEndChan();
UINT ListChansWhereColSelected(UINT colType, CArray<UINT,UINT> &chans);
- UINT GetRowFromCursor(DWORD cursor);
- UINT GetChanFromCursor(DWORD cursor);
- UINT GetColTypeFromCursor(DWORD cursor);
+ static ROWINDEX GetRowFromCursor(DWORD cursor);
+ static CHANNELINDEX GetChanFromCursor(DWORD cursor);
+ static UINT GetColTypeFromCursor(DWORD cursor);
bool IsInterpolationPossible(UINT startRow, UINT endRow, UINT chan, UINT colType, CSoundFile* pSndFile);
void Interpolate(UINT type);
@@ -341,6 +348,13 @@
ROWINDEX& iRow, PATTERNINDEX& iPat,
const ROWINDEX iRowCandidate, const PATTERNINDEX iPatCandidate) const;
+ // Returns edit position.
+ ModCommandPos GetEditPos(CSoundFile& rSf, const bool bLiveRecord) const;
+
+ // Returns pointer to modcommand at given position. If the position is not valid, returns pointer
+ // to a dummy command.
+ MODCOMMAND* GetModCommand(CSoundFile& rSf, const ModCommandPos& pos);
+
bool IsEditingEnabled() const {return ((m_dwStatus&PATSTATUS_RECORD) != 0);}
//Like IsEditingEnabled(), but shows some notification when editing is not enabled.
Modified: trunk/OpenMPT/mptrack/mptrack.rc
===================================================================
--- trunk/OpenMPT/mptrack/mptrack.rc 2009-08-19 15:20:48 UTC (rev 334)
+++ trunk/OpenMPT/mptrack/mptrack.rc 2009-08-20 16:46:12 UTC (rev 335)
@@ -2248,7 +2248,7 @@
BEGIN
GROUPBOX "Current mapping",IDC_STATIC,5,5,325,105
CONTROL "Active",IDC_CHECKACTIVE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,20,42,10
- CONTROL "Capture",IDC_CHECKCAPTURE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,65,20,39,10
+ CONTROL "Capture",IDC_CHECKCAPTURE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,67,20,39,10
LTEXT "Channel",IDC_STATIC,15,35,27,8
COMBOBOX IDC_COMBO_CHANNEL,15,45,36,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Event",IDC_STATIC,61,35,20,8
@@ -2267,6 +2267,7 @@
CONTROL "",IDC_SPINMOVEMAPPING,"msctls_updown32",0x0,330,115,11,80
CONTROL "MIDI learn",IDC_CHECK_MIDILEARN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,335,30,47,11
DEFPUSHBUTTON "Close",IDOK,335,10,50,14
+ CONTROL "Pattern record",IDC_CHECK_PATRECORD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,114,20,63,10
END
IDD_TUNING DIALOGEX 0, 0, 512, 240
Modified: trunk/OpenMPT/mptrack/resource.h
===================================================================
--- trunk/OpenMPT/mptrack/resource.h 2009-08-19 15:20:48 UTC (rev 334)
+++ trunk/OpenMPT/mptrack/resource.h 2009-08-20 16:46:12 UTC (rev 335)
@@ -882,6 +882,7 @@
#define IDC_SPIN_ADDSILENCE 2382
#define IDC_RADIO_RESIZETO 2384
#define IDC_EDIT_MODLOADING_WARNINGS 2385
+#define IDC_CHECK_PATRECORD 2386
#define ID_FILE_NEWMOD 32771
#define ID_FILE_NEWXM 32772
#define ID_FILE_NEWS3M 32773
@@ -1123,7 +1124,7 @@
#define _APS_3D_CONTROLS 1
#define _APS_NEXT_RESOURCE_VALUE 521
#define _APS_NEXT_COMMAND_VALUE 59229
-#define _APS_NEXT_CONTROL_VALUE 2386
+#define _APS_NEXT_CONTROL_VALUE 2387
#define _APS_NEXT_SYMED_VALUE 901
#endif
#endif
Modified: trunk/OpenMPT/soundlib/midi.h
===================================================================
--- trunk/OpenMPT/soundlib/midi.h 2009-08-19 15:20:48 UTC (rev 334)
+++ trunk/OpenMPT/soundlib/midi.h 2009-08-20 16:46:12 UTC (rev 335)
@@ -68,10 +68,10 @@
CString ToString() const
{
CString str; str.Preallocate(20);
- char flags[3] = "00";
+ char flags[4] = "000";
if(m_Active) flags[0] = '1';
if(m_CaptureMIDI) flags[1] = '1';
- //if(m_AllowPatternEdit) flags[2] = '1';
+ if(m_AllowPatternEdit) flags[2] = '1';
str.Format("%s:%d:%x:%d:%d:%d", flags, (int)GetChannel(), (int)GetEvent(), (int)GetController(), (int)m_PluginIndex, m_Parameter);
str.Trim();
return str;
Modified: trunk/OpenMPT/soundlib/modcommand.h
===================================================================
--- trunk/OpenMPT/soundlib/modcommand.h 2009-08-19 15:20:48 UTC (rev 334)
+++ trunk/OpenMPT/soundlib/modcommand.h 2009-08-20 16:46:12 UTC (rev 335)
@@ -31,6 +31,8 @@
return !(*this == mc);
}
+ void Set(NOTE n, INSTR ins, uint16 volcol, uint16 effectcol) {note = n; instr = ins; SetValueVolCol(volcol); SetValueEffectCol(effectcol);}
+
uint16 GetValueVolCol() const {return GetValueVolCol(volcmd, vol);}
static uint16 GetValueVolCol(BYTE volcmd, BYTE vol) {return (volcmd << 8) + vol;}
void SetValueVolCol(const uint16 val) {volcmd = static_cast<BYTE>(val >> 8); vol = static_cast<BYTE>(val & 0xFF);}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-08-19 15:20:54
|
Revision: 334
http://modplug.svn.sourceforge.net/modplug/?rev=334&view=rev
Author: saga-games
Date: 2009-08-19 15:20:48 +0000 (Wed, 19 Aug 2009)
Log Message:
-----------
[New] (Partly from last commit): Envelope points can now be added by shift-clicking somewhere in the envelope editor. Middle mouse button click removes the nearest point.
[Fix] Mod Conversion: Used MAX_CHANNELS instead of MAX_BASECHANNELS (luckily, nothing could go wrong as there are more max. virtual channels than max. chanenls)
[Fix] Pattern editor: Inserting a new pattern won't resize it to 32 rows anymore if the current pattern has less than 32 rows.
[Mod] Note properties / Find&Replace: Show "Note Cut", "Note Fade", "Note Off" instead of "^^", "~~" and "==" for easier understanding. Maybe this should only happen in the note properties, though.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Ctrl_pat.cpp
trunk/OpenMPT/mptrack/Modedit.cpp
trunk/OpenMPT/mptrack/Mptrack.h
trunk/OpenMPT/mptrack/View_ins.cpp
trunk/OpenMPT/mptrack/View_ins.h
trunk/OpenMPT/mptrack/dlg_misc.cpp
Modified: trunk/OpenMPT/mptrack/Ctrl_pat.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2009-08-18 23:06:08 UTC (rev 333)
+++ trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2009-08-19 15:20:48 UTC (rev 334)
@@ -850,10 +850,10 @@
if ((pat < pSndFile->Patterns.Size()) && (pSndFile->Patterns[pat]) && (pSndFile->m_nType & (MOD_TYPE_XM|MOD_TYPE_IT|MOD_TYPE_MPT)))
{
rows = pSndFile->PatternSize[pat];
- if (rows < 32) rows = 32;
+ rows = CLAMP(rows, pSndFile->GetModSpecifications().patternRowsMin, pSndFile->GetModSpecifications().patternRowsMax);
}
PATTERNINDEX nNewPat = m_pModDoc->InsertPattern(nCurOrd + 1, rows);
- if ((nNewPat >= 0) && (nNewPat < pSndFile->Patterns.Size()))
+ if ((nNewPat != PATTERNINDEX_INVALID) && (nNewPat < pSndFile->Patterns.Size()))
{
m_OrderList.SetCurSel(nCurOrd + 1);
m_OrderList.InvalidateRect(NULL, FALSE);
@@ -889,11 +889,10 @@
if (nCurPat < pSndFile->Patterns.Size() && pReplaceIndex[nCurPat] == PATTERNINDEX_INVALID)
{
rows = pSndFile->PatternSize[nCurPat];
- if (rows < pSndFile->GetModSpecifications().patternRowsMin) rows = pSndFile->GetModSpecifications().patternRowsMin;
- if (rows > pSndFile->GetModSpecifications().patternRowsMax) rows = pSndFile->GetModSpecifications().patternRowsMax;
+ rows = CLAMP(rows, pSndFile->GetModSpecifications().patternRowsMin, pSndFile->GetModSpecifications().patternRowsMax);
PATTERNINDEX nNewPat = m_pModDoc->InsertPattern(nInsertWhere + i, rows);
- if ((nNewPat >= 0) && (nNewPat < pSndFile->Patterns.Size()) && (pSndFile->Patterns[nCurPat] != nullptr))
+ if ((nNewPat != PATTERNINDEX_INVALID) && (nNewPat < pSndFile->Patterns.Size()) && (pSndFile->Patterns[nCurPat] != nullptr))
{
MODCOMMAND *pSrc = pSndFile->Patterns[nCurPat];
MODCOMMAND *pDest = pSndFile->Patterns[nNewPat];
Modified: trunk/OpenMPT/mptrack/Modedit.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-18 23:06:08 UTC (rev 333)
+++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-19 15:20:48 UTC (rev 334)
@@ -159,13 +159,13 @@
/////////////////////////////
// Converting pattern data
- for (UINT nPat=0; nPat<m_SndFile.Patterns.Size(); nPat++) if (m_SndFile.Patterns[nPat])
+ for (UINT nPat = 0; nPat < m_SndFile.Patterns.Size(); nPat++) if (m_SndFile.Patterns[nPat])
{
MODCOMMAND *m = m_SndFile.Patterns[nPat];
// This is used for -> MOD/XM conversion
- BYTE cEffectMemory[MAX_CHANNELS][MAX_EFFECTS];
- memset(&cEffectMemory, 0, sizeof(BYTE) * MAX_CHANNELS * MAX_EFFECTS);
+ BYTE cEffectMemory[MAX_BASECHANNELS][MAX_EFFECTS];
+ memset(&cEffectMemory, 0, sizeof(BYTE) * MAX_BASECHANNELS * MAX_EFFECTS);
UINT nChannel = m_SndFile.m_nChannels - 1;
for (UINT len = m_SndFile.PatternSize[nPat] * m_SndFile.m_nChannels; len; m++, len--)
@@ -1613,7 +1613,7 @@
{
const int i = m_SndFile.Patterns.Insert(nRows);
if(i < 0)
- return -1;
+ return PATTERNINDEX_INVALID;
//Increasing orderlist size if given order is beyond current limit,
//or if the last order already has a pattern.
Modified: trunk/OpenMPT/mptrack/Mptrack.h
===================================================================
--- trunk/OpenMPT/mptrack/Mptrack.h 2009-08-18 23:06:08 UTC (rev 333)
+++ trunk/OpenMPT/mptrack/Mptrack.h 2009-08-19 15:20:48 UTC (rev 334)
@@ -405,7 +405,8 @@
extern const BYTE gEffectColors[MAX_EFFECTS];
extern const LPCSTR szNoteNames[12];
extern const LPCTSTR szDefaultNoteNames[NOTE_MAX];
-const LPCTSTR szSpecialNoteNames[NOTE_MAX_SPECIAL - NOTE_MIN_SPECIAL + 1] = {TEXT("PCs"), TEXT("PC"), TEXT("~~"), TEXT("^^"), TEXT("==")};
+//const LPCTSTR szSpecialNoteNames[NOTE_MAX_SPECIAL - NOTE_MIN_SPECIAL + 1] = {TEXT("PCs"), TEXT("PC"), TEXT("~~"), TEXT("^^"), TEXT("==")};
+const LPCTSTR szSpecialNoteNames[NOTE_MAX_SPECIAL - NOTE_MIN_SPECIAL + 1] = {TEXT("PCs"), TEXT("PC"), TEXT("Note Fade"), TEXT("Note Cut"), TEXT("Note Off")};
const LPCTSTR szSpecialNoteShortDesc[NOTE_MAX_SPECIAL - NOTE_MIN_SPECIAL + 1] = {TEXT("Param Control (Smooth)"), TEXT("Param Control"), TEXT("Note Fade"), TEXT("Note Cut"), TEXT("Note Off")};
// Make sure that special note arrays include string for every note.
Modified: trunk/OpenMPT/mptrack/View_ins.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_ins.cpp 2009-08-18 23:06:08 UTC (rev 333)
+++ trunk/OpenMPT/mptrack/View_ins.cpp 2009-08-19 15:20:48 UTC (rev 334)
@@ -62,6 +62,7 @@
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_RBUTTONDOWN()
+ ON_WM_MBUTTONDOWN()
ON_WM_NCLBUTTONDOWN()
ON_WM_NCLBUTTONUP()
ON_WM_NCLBUTTONDBLCLK()
@@ -1700,6 +1701,7 @@
}
else
{
+ // Shift-Click: Insert envelope point here
if(CMainFrame::GetMainFrame()->GetInputHandler()->ShiftPressed())
{
m_ptMenu = pt;
@@ -1756,7 +1758,18 @@
}
}
+void CViewInstrument::OnMButtonDown(UINT, CPoint pt)
+//--------------------------------------------------
+{
+ // Middle mouse button: Remove envelope point
+ if(EnvGetLastPoint() <= 1) return;
+ m_nDragItem = ScreenToPoint(pt.x, pt.y) + 1;
+ if(m_nDragItem == 0) return;
+ m_ptMenu = pt;
+ OnEnvRemovePoint();
+}
+
void CViewInstrument::OnPrevInstrument()
//--------------------------------------
{
Modified: trunk/OpenMPT/mptrack/View_ins.h
===================================================================
--- trunk/OpenMPT/mptrack/View_ins.h 2009-08-18 23:06:08 UTC (rev 333)
+++ trunk/OpenMPT/mptrack/View_ins.h 2009-08-19 15:20:48 UTC (rev 334)
@@ -111,6 +111,7 @@
afx_msg void OnLButtonDown(UINT, CPoint);
afx_msg void OnLButtonUp(UINT, CPoint);
afx_msg void OnRButtonDown(UINT, CPoint);
+ afx_msg void OnMButtonDown(UINT, CPoint);
afx_msg void OnNcMouseMove(UINT nHitTest, CPoint point);
afx_msg void OnNcLButtonDown(UINT, CPoint);
afx_msg void OnNcLButtonUp(UINT, CPoint);
Modified: trunk/OpenMPT/mptrack/dlg_misc.cpp
===================================================================
--- trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-08-18 23:06:08 UTC (rev 333)
+++ trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-08-19 15:20:48 UTC (rev 334)
@@ -916,9 +916,10 @@
combo->AddString(s);
}
combo->SetCurSel(nrows - specs.patternRowsMin);
- wsprintf(s, "Pattern #%d:\x0d\x0a %d rows (%dK)",
+ wsprintf(s, "Pattern #%d:\x0d\x0a %d row%s (%dK)",
m_nPattern,
pSndFile->PatternSize[m_nPattern],
+ (pSndFile->PatternSize[m_nPattern] == 1) ? "" : "s",
(pSndFile->PatternSize[m_nPattern] * pSndFile->m_nChannels * sizeof(MODCOMMAND))/1024);
SetDlgItemText(IDC_TEXT1, s);
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-08-18 23:06:19
|
Revision: 333
http://modplug.svn.sourceforge.net/modplug/?rev=333&view=rev
Author: saga-games
Date: 2009-08-18 23:06:08 +0000 (Tue, 18 Aug 2009)
Log Message:
-----------
[Fix] Pattern editor: Multiselect Pattern Duplicate shouldn't crash anymore if a non-existing pattern is being duplicated.
[Ref] Instrument editor code: Making use of the new INSTRUMENTENVELOPE sub-objects to reduce redundancy A LOT; Also using bool instead of BOOL.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Ctrl_pat.cpp
trunk/OpenMPT/mptrack/View_ins.cpp
trunk/OpenMPT/mptrack/View_ins.h
Modified: trunk/OpenMPT/mptrack/Ctrl_pat.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2009-08-18 20:38:41 UTC (rev 332)
+++ trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2009-08-18 23:06:08 UTC (rev 333)
@@ -873,13 +873,14 @@
if (m_pModDoc)
{
CSoundFile *pSndFile = m_pModDoc->GetSoundFile();
+
ORD_SELECTION selection = m_OrderList.GetCurSel(false);
ORDERINDEX nInsertCount = selection.nOrdHi - selection.nOrdLo;
ORDERINDEX nInsertWhere = selection.nOrdLo + nInsertCount + 1;
bool bSuccess = false;
// has this pattern been duplicated already? (for multiselect)
- PATTERNINDEX pReplaceIndex[MAX_PATTERNS]; // TODO I think this is a bit much...
- memset(&pReplaceIndex, PATTERNINDEX_INVALID, sizeof(PATTERNINDEX) * MAX_PATTERNS);
+ vector<PATTERNINDEX> pReplaceIndex;
+ pReplaceIndex.resize(pSndFile->Patterns.Size(), PATTERNINDEX_INVALID);
for(ORDERINDEX i = 0; i <= nInsertCount; i++)
{
@@ -887,13 +888,12 @@
ROWINDEX rows = 64;
if (nCurPat < pSndFile->Patterns.Size() && pReplaceIndex[nCurPat] == PATTERNINDEX_INVALID)
{
- if ((pSndFile->Patterns[nCurPat]) && (pSndFile->m_nType & (MOD_TYPE_XM|MOD_TYPE_IT|MOD_TYPE_MPT)))
- {
- rows = pSndFile->PatternSize[nCurPat];
- if (rows < pSndFile->GetModSpecifications().patternRowsMin) rows = pSndFile->GetModSpecifications().patternRowsMin;
- }
+ rows = pSndFile->PatternSize[nCurPat];
+ if (rows < pSndFile->GetModSpecifications().patternRowsMin) rows = pSndFile->GetModSpecifications().patternRowsMin;
+ if (rows > pSndFile->GetModSpecifications().patternRowsMax) rows = pSndFile->GetModSpecifications().patternRowsMax;
+
PATTERNINDEX nNewPat = m_pModDoc->InsertPattern(nInsertWhere + i, rows);
- if ((nNewPat >= 0) && (nNewPat < pSndFile->Patterns.Size()))
+ if ((nNewPat >= 0) && (nNewPat < pSndFile->Patterns.Size()) && (pSndFile->Patterns[nCurPat] != nullptr))
{
MODCOMMAND *pSrc = pSndFile->Patterns[nCurPat];
MODCOMMAND *pDest = pSndFile->Patterns[nNewPat];
Modified: trunk/OpenMPT/mptrack/View_ins.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_ins.cpp 2009-08-18 20:38:41 UTC (rev 332)
+++ trunk/OpenMPT/mptrack/View_ins.cpp 2009-08-18 23:06:08 UTC (rev 333)
@@ -268,10 +268,10 @@
}
-BOOL CViewInstrument::EnvSetValue(int nPoint, int nTick, int nValue)
+bool CViewInstrument::EnvSetValue(int nPoint, int nTick, int nValue)
//------------------------------------------------------------------
{
- BOOL bOk = FALSE;
+ bool bOk = false;
CModDoc *pModDoc = GetDocument();
if (pModDoc)
{
@@ -282,24 +282,14 @@
LPWORD pPoints = NULL;
LPBYTE pData = NULL;
UINT maxpoints = 0;
- switch(m_nEnv)
- {
- case ENV_VOLUME:
- maxpoints = pIns->VolEnv.nNodes;
- pPoints = pIns->VolEnv.Ticks;
- pData = pIns->VolEnv.Values;
- break;
- case ENV_PANNING:
- maxpoints = pIns->PanEnv.nNodes;
- pPoints = pIns->PanEnv.Ticks;
- pData = pIns->PanEnv.Values;
- break;
- case ENV_PITCH:
- maxpoints = pIns->PitchEnv.nNodes;
- pPoints = pIns->PitchEnv.Ticks;
- pData = pIns->PitchEnv.Values;
- break;
- }
+
+ INSTRUMENTENVELOPE *envelope = GetEnvelopePtr();
+ if(envelope == nullptr) return false;
+
+ maxpoints = envelope->nNodes;
+ pPoints = envelope->Ticks;
+ pData = envelope->Values;
+
if (!nPoint) nTick = 0;
if ((nPoint < (int)maxpoints) && (pPoints) && (pData))
{
@@ -313,7 +303,7 @@
if (nTick != pPoints[nPoint])
{
pPoints[nPoint] = (WORD)nTick;
- bOk = TRUE;
+ bOk = true;
}
}
if (nValue >= 0)
@@ -322,7 +312,7 @@
if (nValue != pData[nPoint])
{
pData[nPoint] = (BYTE)nValue;
- bOk = TRUE;
+ bOk = true;
}
}
}
@@ -335,28 +325,9 @@
UINT CViewInstrument::EnvGetNumPoints() const
//-------------------------------------------
{
- CModDoc *pModDoc = GetDocument();
- if (pModDoc)
- {
- CSoundFile *pSndFile = pModDoc->GetSoundFile();
- MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument];
- if (pIns)
- {
- switch(m_nEnv)
- {
- case ENV_VOLUME:
- if (pIns->VolEnv.nNodes) return pIns->VolEnv.nNodes;
- break;
- case ENV_PANNING:
- if (pIns->PanEnv.nNodes) return pIns->PanEnv.nNodes;
- break;
- case ENV_PITCH:
- if (pIns->PitchEnv.nNodes) return pIns->PitchEnv.nNodes;
- break;
- }
- }
- }
- return 0;
+ INSTRUMENTENVELOPE *envelope = GetEnvelopePtr();
+ if(envelope == nullptr) return 0;
+ return envelope->nNodes;
}
@@ -369,7 +340,7 @@
}
-BOOL CViewInstrument::EnvGetLoop() const
+bool CViewInstrument::EnvGetLoop() const
//--------------------------------------
{
CModDoc *pModDoc = GetDocument();
@@ -382,22 +353,22 @@
switch(m_nEnv)
{
case ENV_VOLUME:
- if (pIns->dwFlags & ENV_VOLLOOP) return TRUE;
+ if (pIns->dwFlags & ENV_VOLLOOP) return true;
break;
case ENV_PANNING:
- if (pIns->dwFlags & ENV_PANLOOP) return TRUE;
+ if (pIns->dwFlags & ENV_PANLOOP) return true;
break;
case ENV_PITCH:
- if (pIns->dwFlags & ENV_PITCHLOOP) return TRUE;
+ if (pIns->dwFlags & ENV_PITCHLOOP) return true;
break;
}
}
}
- return FALSE;
+ return false;
}
-BOOL CViewInstrument::EnvGetSustain() const
+bool CViewInstrument::EnvGetSustain() const
//-----------------------------------------
{
CModDoc *pModDoc = GetDocument();
@@ -410,22 +381,22 @@
switch(m_nEnv)
{
case ENV_VOLUME:
- if (pIns->dwFlags & ENV_VOLSUSTAIN) return TRUE;
+ if (pIns->dwFlags & ENV_VOLSUSTAIN) return true;
break;
case ENV_PANNING:
- if (pIns->dwFlags & ENV_PANSUSTAIN) return TRUE;
+ if (pIns->dwFlags & ENV_PANSUSTAIN) return true;
break;
case ENV_PITCH:
- if (pIns->dwFlags & ENV_PITCHSUSTAIN) return TRUE;
+ if (pIns->dwFlags & ENV_PITCHSUSTAIN) return true;
break;
}
}
}
- return FALSE;
+ return false;
}
-BOOL CViewInstrument::EnvGetCarry() const
+bool CViewInstrument::EnvGetCarry() const
//---------------------------------------
{
CModDoc *pModDoc = GetDocument();
@@ -438,110 +409,58 @@
switch(m_nEnv)
{
case ENV_VOLUME:
- if (pIns->dwFlags & ENV_VOLCARRY) return TRUE;
+ if (pIns->dwFlags & ENV_VOLCARRY) return true;
break;
case ENV_PANNING:
- if (pIns->dwFlags & ENV_PANCARRY) return TRUE;
+ if (pIns->dwFlags & ENV_PANCARRY) return true;
break;
case ENV_PITCH:
- if (pIns->dwFlags & ENV_PITCHCARRY) return TRUE;
+ if (pIns->dwFlags & ENV_PITCHCARRY) return true;
break;
}
}
}
- return FALSE;
+ return false;
}
UINT CViewInstrument::EnvGetLoopStart() const
//-------------------------------------------
{
- CModDoc *pModDoc = GetDocument();
- if (pModDoc)
- {
- CSoundFile *pSndFile = pModDoc->GetSoundFile();
- MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument];
- if (pIns)
- {
- switch(m_nEnv)
- {
- case ENV_VOLUME: return pIns->VolEnv.nLoopStart;
- case ENV_PANNING: return pIns->PanEnv.nLoopStart;
- case ENV_PITCH: return pIns->PitchEnv.nLoopStart;
- }
- }
- }
- return 0;
+ INSTRUMENTENVELOPE *envelope = GetEnvelopePtr();
+ if(envelope == nullptr) return 0;
+ return envelope->nLoopStart;
}
UINT CViewInstrument::EnvGetLoopEnd() const
//-----------------------------------------
{
- CModDoc *pModDoc = GetDocument();
- if (pModDoc)
- {
- CSoundFile *pSndFile = pModDoc->GetSoundFile();
- MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument];
- if (pIns)
- {
- switch(m_nEnv)
- {
- case ENV_VOLUME: return pIns->VolEnv.nLoopEnd;
- case ENV_PANNING: return pIns->PanEnv.nLoopEnd;
- case ENV_PITCH: return pIns->PitchEnv.nLoopEnd;
- }
- }
- }
- return 0;
+ INSTRUMENTENVELOPE *envelope = GetEnvelopePtr();
+ if(envelope == nullptr) return 0;
+ return envelope->nLoopEnd;
}
UINT CViewInstrument::EnvGetSustainStart() const
//----------------------------------------------
{
- CModDoc *pModDoc = GetDocument();
- if (pModDoc)
- {
- CSoundFile *pSndFile = pModDoc->GetSoundFile();
- MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument];
- if (pIns)
- {
- switch(m_nEnv)
- {
- case ENV_VOLUME: return pIns->VolEnv.nSustainStart;
- case ENV_PANNING: return pIns->PanEnv.nSustainStart;
- case ENV_PITCH: return pIns->PitchEnv.nSustainStart;
- }
- }
- }
- return 0;
+ INSTRUMENTENVELOPE *envelope = GetEnvelopePtr();
+ if(envelope == nullptr) return 0;
+ return envelope->nSustainStart;
}
UINT CViewInstrument::EnvGetSustainEnd() const
//--------------------------------------------
{
- CModDoc *pModDoc = GetDocument();
- if (pModDoc)
- {
- CSoundFile *pSndFile = pModDoc->GetSoundFile();
- MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument];
- if (pIns)
- {
- switch(m_nEnv)
- {
- case ENV_VOLUME: return pIns->VolEnv.nSustainEnd;
- case ENV_PANNING: return pIns->PanEnv.nSustainEnd;
- case ENV_PITCH: return pIns->PitchEnv.nSustainEnd;
- }
- }
- }
- return 0;
+ INSTRUMENTENVELOPE *envelope = GetEnvelopePtr();
+ if(envelope == nullptr) return 0;
+ return envelope->nSustainEnd;
}
-BOOL CViewInstrument::EnvGetVolEnv() const
+bool CViewInstrument::EnvGetVolEnv() const
//----------------------------------------
{
CModDoc *pModDoc = GetDocument();
@@ -549,13 +468,13 @@
{
CSoundFile *pSndFile = pModDoc->GetSoundFile();
MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument];
- if (pIns) return (pIns->dwFlags & ENV_VOLUME) ? TRUE : FALSE;
+ if (pIns) return (pIns->dwFlags & ENV_VOLUME) ? true : false;
}
- return FALSE;
+ return false;
}
-BOOL CViewInstrument::EnvGetPanEnv() const
+bool CViewInstrument::EnvGetPanEnv() const
//----------------------------------------
{
CModDoc *pModDoc = GetDocument();
@@ -563,13 +482,13 @@
{
CSoundFile *pSndFile = pModDoc->GetSoundFile();
MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument];
- if (pIns) return (pIns->dwFlags & ENV_PANNING) ? TRUE : FALSE;
+ if (pIns) return (pIns->dwFlags & ENV_PANNING) ? true : false;
}
- return FALSE;
+ return false;
}
-BOOL CViewInstrument::EnvGetPitchEnv() const
+bool CViewInstrument::EnvGetPitchEnv() const
//------------------------------------------
{
CModDoc *pModDoc = GetDocument();
@@ -577,13 +496,13 @@
{
CSoundFile *pSndFile = pModDoc->GetSoundFile();
MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument];
- if (pIns) return ((pIns->dwFlags & (ENV_PITCH|ENV_FILTER)) == ENV_PITCH) ? TRUE : FALSE;
+ if (pIns) return ((pIns->dwFlags & (ENV_PITCH|ENV_FILTER)) == ENV_PITCH) ? true : false;
}
- return FALSE;
+ return false;
}
-BOOL CViewInstrument::EnvGetFilterEnv() const
+bool CViewInstrument::EnvGetFilterEnv() const
//-------------------------------------------
{
CModDoc *pModDoc = GetDocument();
@@ -591,185 +510,95 @@
{
CSoundFile *pSndFile = pModDoc->GetSoundFile();
MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument];
- if (pIns) return ((pIns->dwFlags & (ENV_PITCH|ENV_FILTER)) == (ENV_PITCH|ENV_FILTER)) ? TRUE : FALSE;
+ if (pIns) return ((pIns->dwFlags & (ENV_PITCH|ENV_FILTER)) == (ENV_PITCH|ENV_FILTER)) ? true : false;
}
- return FALSE;
+ return false;
}
-BOOL CViewInstrument::EnvSetLoopStart(int nPoint)
+bool CViewInstrument::EnvSetLoopStart(int nPoint)
//-----------------------------------------------
{
- CModDoc *pModDoc = GetDocument();
- if ((pModDoc) && (nPoint >= 0) && (nPoint <= (int)EnvGetLastPoint()))
+ INSTRUMENTENVELOPE *envelope = GetEnvelopePtr();
+ if(envelope == nullptr) return false;
+ if(nPoint < 0 || nPoint > (int)EnvGetLastPoint()) return false;
+
+ if (nPoint != envelope->nLoopStart)
{
- CSoundFile *pSndFile = pModDoc->GetSoundFile();
- MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument];
- if (pIns)
- {
- switch(m_nEnv)
- {
- case ENV_VOLUME:
- if (nPoint != pIns->VolEnv.nLoopStart)
- {
- pIns->VolEnv.nLoopStart = (BYTE)nPoint;
- if (pIns->VolEnv.nLoopEnd < nPoint) pIns->VolEnv.nLoopEnd = (BYTE)nPoint;
- return TRUE;
- }
- break;
- case ENV_PANNING:
- if (nPoint != pIns->PanEnv.nLoopStart)
- {
- pIns->PanEnv.nLoopStart = (BYTE)nPoint;
- if (pIns->PanEnv.nLoopEnd < nPoint) pIns->PanEnv.nLoopEnd = (BYTE)nPoint;
- return TRUE;
- }
- break;
- case ENV_PITCH:
- if (nPoint != pIns->PitchEnv.nLoopStart)
- {
- pIns->PitchEnv.nLoopStart = (BYTE)nPoint;
- if (pIns->PitchEnv.nLoopEnd < nPoint) pIns->PitchEnv.nLoopEnd = (BYTE)nPoint;
- return TRUE;
- }
- break;
- }
- }
+ envelope->nLoopStart = (BYTE)nPoint;
+ if (envelope->nLoopEnd < nPoint) envelope->nLoopEnd = (BYTE)nPoint;
+ return true;
+ } else
+ {
+ return false;
}
- return FALSE;
}
-BOOL CViewInstrument::EnvSetLoopEnd(int nPoint)
+bool CViewInstrument::EnvSetLoopEnd(int nPoint)
//---------------------------------------------
{
- CModDoc *pModDoc = GetDocument();
- if ((pModDoc) && (nPoint >= 0) && (nPoint <= (int)EnvGetLastPoint()))
+ INSTRUMENTENVELOPE *envelope = GetEnvelopePtr();
+ if(envelope == nullptr) return false;
+ if(nPoint < 0 || nPoint > (int)EnvGetLastPoint()) return false;
+
+ if (nPoint != envelope->nLoopEnd)
{
- CSoundFile *pSndFile = pModDoc->GetSoundFile();
- MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument];
- if (pIns)
- {
- switch(m_nEnv)
- {
- case ENV_VOLUME:
- if (nPoint != pIns->VolEnv.nLoopEnd)
- {
- pIns->VolEnv.nLoopEnd = (BYTE)nPoint;
- if (pIns->VolEnv.nLoopStart > nPoint) pIns->VolEnv.nLoopStart = (BYTE)nPoint;
- return TRUE;
- }
- break;
- case ENV_PANNING:
- if (nPoint != pIns->PanEnv.nLoopEnd)
- {
- pIns->PanEnv.nLoopEnd = (BYTE)nPoint;
- if (pIns->PanEnv.nLoopStart > nPoint) pIns->PanEnv.nLoopStart = (BYTE)nPoint;
- return TRUE;
- }
- break;
- case ENV_PITCH:
- if (nPoint != pIns->PitchEnv.nLoopEnd)
- {
- pIns->PitchEnv.nLoopEnd = (BYTE)nPoint;
- if (pIns->PitchEnv.nLoopStart > nPoint) pIns->PitchEnv.nLoopStart = (BYTE)nPoint;
- return TRUE;
- }
- break;
- }
- }
+ envelope->nLoopEnd = (BYTE)nPoint;
+ if (envelope->nLoopStart > nPoint) envelope->nLoopStart = (BYTE)nPoint;
+ return true;
+ } else
+ {
+ return false;
}
- return FALSE;
}
-BOOL CViewInstrument::EnvSetSustainStart(int nPoint)
+bool CViewInstrument::EnvSetSustainStart(int nPoint)
//--------------------------------------------------
{
- CModDoc *pModDoc = GetDocument();
- if ((pModDoc) && (nPoint >= 0) && (nPoint <= (int)EnvGetLastPoint()))
+ INSTRUMENTENVELOPE *envelope = GetEnvelopePtr();
+ if(envelope == nullptr) return false;
+ if(nPoint < 0 || nPoint > (int)EnvGetLastPoint()) return false;
+
+ // We won't do any security checks here as GetEnvelopePtr() does that for us.
+ CSoundFile *pSndFile = GetDocument()->GetSoundFile();
+
+ if (nPoint != envelope->nSustainStart)
{
- CSoundFile *pSndFile = pModDoc->GetSoundFile();
- MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument];
- if (pIns)
- {
- switch(m_nEnv)
- {
- case ENV_VOLUME:
- if (nPoint != pIns->VolEnv.nSustainStart)
- {
- pIns->VolEnv.nSustainStart = (BYTE)nPoint;
- if ((pIns->VolEnv.nSustainEnd < nPoint) || (pSndFile->m_nType & MOD_TYPE_XM)) pIns->VolEnv.nSustainEnd = (BYTE)nPoint;
- return TRUE;
- }
- break;
- case ENV_PANNING:
- if (nPoint != pIns->PanEnv.nSustainStart)
- {
- pIns->PanEnv.nSustainStart = (BYTE)nPoint;
- if ((pIns->PanEnv.nSustainEnd < nPoint) || (pSndFile->m_nType & MOD_TYPE_XM)) pIns->PanEnv.nSustainEnd = (BYTE)nPoint;
- return TRUE;
- }
- break;
- case ENV_PITCH:
- if (nPoint != pIns->PitchEnv.nSustainStart)
- {
- pIns->PitchEnv.nSustainStart = (BYTE)nPoint;
- if ((pIns->PitchEnv.nSustainEnd < nPoint) || (pSndFile->m_nType & MOD_TYPE_XM)) pIns->PitchEnv.nSustainEnd = (BYTE)nPoint;
- return TRUE;
- }
- break;
- }
- }
+ envelope->nSustainStart = (BYTE)nPoint;
+ if ((envelope->nSustainEnd < nPoint) || (pSndFile->m_nType & MOD_TYPE_XM)) envelope->nSustainEnd = (BYTE)nPoint;
+ return true;
+ } else
+ {
+ return false;
}
- return FALSE;
}
-BOOL CViewInstrument::EnvSetSustainEnd(int nPoint)
+bool CViewInstrument::EnvSetSustainEnd(int nPoint)
//------------------------------------------------
{
- CModDoc *pModDoc = GetDocument();
- if ((pModDoc) && (nPoint >= 0) && (nPoint <= (int)EnvGetLastPoint()))
+ INSTRUMENTENVELOPE *envelope = GetEnvelopePtr();
+ if(envelope == nullptr) return false;
+ if(nPoint < 0 || nPoint > (int)EnvGetLastPoint()) return false;
+
+ // We won't do any security checks here as GetEnvelopePtr() does that for us.
+ CSoundFile *pSndFile = GetDocument()->GetSoundFile();
+
+ if (nPoint != envelope->nSustainEnd)
{
- CSoundFile *pSndFile = pModDoc->GetSoundFile();
- MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument];
- if (pIns)
- {
- switch(m_nEnv)
- {
- case ENV_VOLUME:
- if (nPoint != pIns->VolEnv.nSustainEnd)
- {
- pIns->VolEnv.nSustainEnd = (BYTE)nPoint;
- if ((pIns->VolEnv.nSustainStart > nPoint) || (pSndFile->m_nType & MOD_TYPE_XM)) pIns->VolEnv.nSustainStart = (BYTE)nPoint;
- return TRUE;
- }
- break;
- case ENV_PANNING:
- if (nPoint != pIns->PanEnv.nSustainEnd)
- {
- pIns->PanEnv.nSustainEnd = (BYTE)nPoint;
- if ((pIns->PanEnv.nSustainStart > nPoint) || (pSndFile->m_nType & MOD_TYPE_XM)) pIns->PanEnv.nSustainStart = (BYTE)nPoint;
- return TRUE;
- }
- break;
- case ENV_PITCH:
- if (nPoint != pIns->PitchEnv.nSustainEnd)
- {
- pIns->PitchEnv.nSustainEnd = (BYTE)nPoint;
- if ((pIns->PitchEnv.nSustainStart > nPoint) || (pSndFile->m_nType & MOD_TYPE_XM)) pIns->PitchEnv.nSustainStart = (BYTE)nPoint;
- return TRUE;
- }
- break;
- }
- }
+ envelope->nSustainEnd = (BYTE)nPoint;
+ if ((envelope->nSustainStart > nPoint) || (pSndFile->m_nType & MOD_TYPE_XM)) envelope->nSustainStart = (BYTE)nPoint;
+ return true;
+ } else
+ {
+ return false;
}
- return FALSE;
}
-BOOL CViewInstrument::EnvSetLoop(BOOL bLoop)
+bool CViewInstrument::EnvSetLoop(bool bLoop)
//------------------------------------------
{
CModDoc *pModDoc = GetDocument();
@@ -786,29 +615,29 @@
case ENV_PANNING: dwMask = ENV_PANLOOP; break;
case ENV_PITCH: dwMask = ENV_PITCHLOOP; break;
}
- if (!dwMask) return FALSE;
+ if (!dwMask) return false;
if (bLoop)
{
if (!(pIns->dwFlags & dwMask))
{
pIns->dwFlags |= dwMask;
- return TRUE;
+ return true;
}
} else
{
if (pIns->dwFlags & dwMask)
{
pIns->dwFlags &= ~dwMask;
- return TRUE;
+ return true;
}
}
}
}
- return FALSE;
+ return false;
}
-BOOL CViewInstrument::EnvSetSustain(BOOL bSustain)
+bool CViewInstrument::EnvSetSustain(bool bSustain)
//------------------------------------------------
{
CModDoc *pModDoc = GetDocument();
@@ -825,29 +654,29 @@
case ENV_PANNING: dwMask = ENV_PANSUSTAIN; break;
case ENV_PITCH: dwMask = ENV_PITCHSUSTAIN; break;
}
- if (!dwMask) return FALSE;
+ if (!dwMask) return false;
if (bSustain)
{
if (!(pIns->dwFlags & dwMask))
{
pIns->dwFlags |= dwMask;
- return TRUE;
+ return true;
}
} else
{
if (pIns->dwFlags & dwMask)
{
pIns->dwFlags &= ~dwMask;
- return TRUE;
+ return true;
}
}
}
}
- return FALSE;
+ return false;
}
-BOOL CViewInstrument::EnvSetCarry(BOOL bCarry)
+bool CViewInstrument::EnvSetCarry(bool bCarry)
//--------------------------------------------
{
CModDoc *pModDoc = GetDocument();
@@ -864,29 +693,29 @@
case ENV_PANNING: dwMask = ENV_PANCARRY; break;
case ENV_PITCH: dwMask = ENV_PITCHCARRY; break;
}
- if (!dwMask) return FALSE;
+ if (!dwMask) return false;
if (bCarry)
{
if (!(pIns->dwFlags & dwMask))
{
pIns->dwFlags |= dwMask;
- return TRUE;
+ return true;
}
} else
{
if (pIns->dwFlags & dwMask)
{
pIns->dwFlags &= ~dwMask;
- return TRUE;
+ return true;
}
}
}
}
- return FALSE;
+ return false;
}
-BOOL CViewInstrument::EnvSetVolEnv(BOOL bEnable)
+bool CViewInstrument::EnvSetVolEnv(bool bEnable)
//----------------------------------------------
{
CModDoc *pModDoc = GetDocument();
@@ -912,14 +741,14 @@
{
pIns->dwFlags &= ~ENV_VOLUME;
}
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
-BOOL CViewInstrument::EnvSetPanEnv(BOOL bEnable)
+bool CViewInstrument::EnvSetPanEnv(bool bEnable)
//----------------------------------------------
{
CModDoc *pModDoc = GetDocument();
@@ -945,14 +774,14 @@
{
pIns->dwFlags &= ~ENV_PANNING;
}
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
-BOOL CViewInstrument::EnvSetPitchEnv(BOOL bEnable)
+bool CViewInstrument::EnvSetPitchEnv(bool bEnable)
//------------------------------------------------
{
CModDoc *pModDoc = GetDocument();
@@ -979,14 +808,14 @@
{
pIns->dwFlags &= ~(ENV_PITCH|ENV_FILTER);
}
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
-BOOL CViewInstrument::EnvSetFilterEnv(BOOL bEnable)
+bool CViewInstrument::EnvSetFilterEnv(bool bEnable)
//-------------------------------------------------
{
CModDoc *pModDoc = GetDocument();
@@ -1012,10 +841,10 @@
{
pIns->dwFlags &= ~(ENV_PITCH|ENV_FILTER);
}
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
@@ -1351,72 +1180,27 @@
}
BYTE CViewInstrument::EnvGetReleaseNode()
-//--------------------------------------
+//---------------------------------------
{
- CModDoc *pModDoc = GetDocument();
- if (pModDoc) {
- CSoundFile *pSndFile = pModDoc->GetSoundFile();
- MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument];
- if (pIns) {
- switch(m_nEnv) {
- case ENV_VOLUME:
- return pIns->VolEnv.nReleaseNode;
- case ENV_PANNING:
- return pIns->PanEnv.nReleaseNode;
- case ENV_PITCH:
- return pIns->PitchEnv.nReleaseNode;
- default:
- return ENV_RELEASE_NODE_UNSET;
- }
- }
- }
- return ENV_RELEASE_NODE_UNSET;
+ INSTRUMENTENVELOPE *envelope = GetEnvelopePtr();
+ if(envelope == nullptr) return ENV_RELEASE_NODE_UNSET;
+ return envelope->nReleaseNode;
}
WORD CViewInstrument::EnvGetReleaseNodeValue()
-//--------------------------------------
+//--------------------------------------------
{
- CModDoc *pModDoc = GetDocument();
- if (pModDoc) {
- CSoundFile *pSndFile = pModDoc->GetSoundFile();
- MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument];
- if (pIns) {
- switch(m_nEnv) {
- case ENV_VOLUME:
- return pIns->VolEnv.Values[EnvGetReleaseNode()];
- case ENV_PANNING:
- return pIns->PanEnv.Values[EnvGetReleaseNode()];
- case ENV_PITCH:
- return pIns->PitchEnv.Values[EnvGetReleaseNode()];
- default:
- return 0;
- }
- }
- }
- return 0;
+ INSTRUMENTENVELOPE *envelope = GetEnvelopePtr();
+ if(envelope == nullptr) return 0;
+ return envelope->Values[EnvGetReleaseNode()];
}
WORD CViewInstrument::EnvGetReleaseNodeTick()
-//--------------------------------------
+//-------------------------------------------
{
- CModDoc *pModDoc = GetDocument();
- if (pModDoc) {
- CSoundFile *pSndFile = pModDoc->GetSoundFile();
- MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument];
- if (pIns) {
- switch(m_nEnv) {
- case ENV_VOLUME:
- return pIns->VolEnv.Ticks[EnvGetReleaseNode()];
- case ENV_PANNING:
- return pIns->PanEnv.Ticks[EnvGetReleaseNode()];
- case ENV_PITCH:
- return pIns->PitchEnv.Ticks[EnvGetReleaseNode()];
- default:
- return 0;
- }
- }
- }
- return 0;
+ INSTRUMENTENVELOPE *envelope = GetEnvelopePtr();
+ if(envelope == nullptr) return 0;
+ return envelope->Ticks[EnvGetReleaseNode()];
}
@@ -1914,6 +1698,14 @@
SetCapture();
m_dwStatus |= INSSTATUS_DRAGGING;
}
+ else
+ {
+ if(CMainFrame::GetMainFrame()->GetInputHandler()->ShiftPressed())
+ {
+ m_ptMenu = pt;
+ OnEnvInsertPoint();
+ }
+ }
}
}
@@ -2054,29 +1846,16 @@
{
CSoundFile *pSndFile = pModDoc->GetSoundFile();
MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument];
- switch(m_nEnv) {
- case ENV_VOLUME:
- if (pIns->VolEnv.nReleaseNode == node) {
- pIns->VolEnv.nReleaseNode = ENV_RELEASE_NODE_UNSET;
- } else {
- pIns->VolEnv.nReleaseNode = node;
- }
- break;
- case ENV_PANNING:
- if (pIns->PanEnv.nReleaseNode == node) {
- pIns->PanEnv.nReleaseNode = ENV_RELEASE_NODE_UNSET;
- } else {
- pIns->PanEnv.nReleaseNode = node;
- }
- break;
- case ENV_PITCH:
- if (pIns->PitchEnv.nReleaseNode == node) {
- pIns->PitchEnv.nReleaseNode = ENV_RELEASE_NODE_UNSET;
- } else {
- pIns->PitchEnv.nReleaseNode = node;
- }
- break;
+
+ INSTRUMENTENVELOPE *envelope = GetEnvelopePtr();
+ if(envelope == nullptr) return;
+
+ if (envelope->nReleaseNode == node) {
+ envelope->nReleaseNode = ENV_RELEASE_NODE_UNSET;
+ } else {
+ envelope->nReleaseNode = node;
}
+
pModDoc->SetModified();
InvalidateRect(NULL, FALSE);
}
@@ -2154,73 +1933,27 @@
MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument];
if (pIns)
{
- BOOL bOk = FALSE;
+ INSTRUMENTENVELOPE *envelope = GetEnvelopePtr();
+ if(envelope == nullptr || envelope->nNodes == 0) return;
+
UINT nPoint = m_nDragItem - 1;
- switch(m_nEnv)
+
+ envelope->nNodes--;
+ for (UINT i=nPoint; i<envelope->nNodes; i++)
{
- case ENV_VOLUME:
- if (pIns->VolEnv.nNodes > 1)
- {
- pIns->VolEnv.nNodes--;
- for (UINT i=nPoint; i<pIns->VolEnv.nNodes; i++)
- {
- pIns->VolEnv.Ticks[i] = pIns->VolEnv.Ticks[i+1];
- pIns->VolEnv.Values[i] = pIns->VolEnv.Values[i+1];
- }
- if (nPoint >= pIns->VolEnv.nNodes) nPoint = pIns->VolEnv.nNodes-1;
- if (pIns->VolEnv.nLoopStart > nPoint) pIns->VolEnv.nLoopStart--;
- if (pIns->VolEnv.nLoopEnd > nPoint) pIns->VolEnv.nLoopEnd--;
- if (pIns->VolEnv.nSustainStart > nPoint) pIns->VolEnv.nSustainStart--;
- if (pIns->VolEnv.nSustainEnd > nPoint) pIns->VolEnv.nSustainEnd--;
- if (pIns->VolEnv.nReleaseNode>nPoint && pIns->VolEnv.nReleaseNode!=ENV_RELEASE_NODE_UNSET) pIns->VolEnv.nReleaseNode--;
- pIns->VolEnv.Ticks[0] = 0;
- bOk = TRUE;
- }
- break;
- case ENV_PANNING:
- if (pIns->PanEnv.nNodes > 1)
- {
- pIns->PanEnv.nNodes--;
- for (UINT i=nPoint; i<pIns->PanEnv.nNodes; i++)
- {
- pIns->PanEnv.Ticks[i] = pIns->PanEnv.Ticks[i+1];
- pIns->PanEnv.Values[i] = pIns->PanEnv.Values[i+1];
- }
- if (nPoint >= pIns->PanEnv.nNodes) nPoint = pIns->PanEnv.nNodes-1;
- if (pIns->PanEnv.nLoopStart > nPoint) pIns->PanEnv.nLoopStart--;
- if (pIns->PanEnv.nLoopEnd > nPoint) pIns->PanEnv.nLoopEnd--;
- if (pIns->PanEnv.nSustainStart > nPoint) pIns->PanEnv.nSustainStart--;
- if (pIns->PanEnv.nSustainEnd > nPoint) pIns->PanEnv.nSustainEnd--;
- if (pIns->PanEnv.nReleaseNode>nPoint && pIns->PanEnv.nReleaseNode!=ENV_RELEASE_NODE_UNSET) pIns->PanEnv.nReleaseNode--;
- pIns->PanEnv.Ticks[0] = 0;
- bOk = TRUE;
- }
- break;
- case ENV_PITCH:
- if (pIns->PitchEnv.nNodes > 1)
- {
- pIns->PitchEnv.nNodes--;
- for (UINT i=nPoint; i<pIns->PitchEnv.nNodes; i++)
- {
- pIns->PitchEnv.Ticks[i] = pIns->PitchEnv.Ticks[i+1];
- pIns->PitchEnv.Values[i] = pIns->PitchEnv.Values[i+1];
- }
- if (nPoint >= pIns->PitchEnv.nNodes) nPoint = pIns->PitchEnv.nNodes-1;
- if (pIns->PitchEnv.nLoopStart > nPoint) pIns->PitchEnv.nLoopStart--;
- if (pIns->PitchEnv.nLoopEnd > nPoint) pIns->PitchEnv.nLoopEnd--;
- if (pIns->PitchEnv.nSustainStart > nPoint) pIns->PitchEnv.nSustainStart--;
- if (pIns->PitchEnv.nSustainEnd > nPoint) pIns->PitchEnv.nSustainEnd--;
- if (pIns->PitchEnv.nReleaseNode>nPoint && pIns->PitchEnv.nReleaseNode!=ENV_RELEASE_NODE_UNSET) pIns->PitchEnv.nReleaseNode--;
- pIns->PitchEnv.Ticks[0] = 0;
- bOk = TRUE;
- }
- break;
+ envelope->Ticks[i] = envelope->Ticks[i + 1];
+ envelope->Values[i] = envelope->Values[i + 1];
}
- if (bOk)
- {
- pModDoc->SetModified();
- pModDoc->UpdateAllViews(NULL, (m_nInstrument << HINT_SHIFT_INS) | HINT_ENVELOPE, NULL);
- }
+ if (nPoint >= envelope->nNodes) nPoint = envelope->nNodes-1;
+ if (envelope->nLoopStart > nPoint) envelope->nLoopStart--;
+ if (envelope->nLoopEnd > nPoint) envelope->nLoopEnd--;
+ if (envelope->nSustainStart > nPoint) envelope->nSustainStart--;
+ if (envelope->nSustainEnd > nPoint) envelope->nSustainEnd--;
+ if (envelope->nReleaseNode>nPoint && envelope->nReleaseNode!=ENV_RELEASE_NODE_UNSET) envelope->nReleaseNode--;
+ envelope->Ticks[0] = 0;
+
+ pModDoc->SetModified();
+ pModDoc->UpdateAllViews(NULL, (m_nInstrument << HINT_SHIFT_INS) | HINT_ENVELOPE, NULL);
}
}
}
@@ -2236,100 +1969,58 @@
MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument];
if (pIns)
{
- BOOL bOk = FALSE;
int nTick = ScreenToTick(m_ptMenu.x);
int nValue = ScreenToValue(m_ptMenu.y);
+ if(nTick < 0) return;
+
UINT maxpoints = (pSndFile->m_nType == MOD_TYPE_XM) ? 12 : 25;
//To check: Should there be MAX_ENVPOINTS?
- if (nValue < 0) nValue = 0;
- if (nValue > 64) nValue = 64;
- if (nTick >= 0) switch(m_nEnv)
+ nValue = CLAMP(nValue, 0, 64);
+
+ INSTRUMENTENVELOPE *envelope = GetEnvelopePtr();
+ if(envelope == nullptr) return;
+ BYTE cDefaultValue;
+
+ switch(m_nEnv)
{
- case ENV_VOLUME:
- if (pIns->VolEnv.nNodes < maxpoints)
+ case ENV_VOLUME:
+ cDefaultValue = 64;
+ break;
+ case ENV_PANNING:
+ cDefaultValue = 32;
+ break;
+ case ENV_PITCH:
+ cDefaultValue = (pIns->dwFlags & ENV_FILTER) ? 64 : 32;
+ break;
+ default:
+ return;
+ }
+
+ if (envelope->nNodes < maxpoints)
+ {
+ if (!envelope->nNodes)
{
- if (!pIns->VolEnv.nNodes)
- {
- pIns->VolEnv.Ticks[0] = 0;
- pIns->VolEnv.Values[0] = 64;
- pIns->VolEnv.nNodes = 1;
- }
- UINT i = 0;
- for (i=0; i<pIns->VolEnv.nNodes; i++) if (nTick <= pIns->VolEnv.Ticks[i]) break;
- for (UINT j=pIns->VolEnv.nNodes; j>i; j--)
- {
- pIns->VolEnv.Ticks[j] = pIns->VolEnv.Ticks[j-1];
- pIns->VolEnv.Values[j] = pIns->VolEnv.Values[j-1];
- }
- pIns->VolEnv.Ticks[i] = (WORD)nTick;
- pIns->VolEnv.Values[i] = (BYTE)nValue;
- pIns->VolEnv.nNodes++;
- if (pIns->VolEnv.nLoopStart >= i) pIns->VolEnv.nLoopStart++;
- if (pIns->VolEnv.nLoopEnd >= i) pIns->VolEnv.nLoopEnd++;
- if (pIns->VolEnv.nSustainStart >= i) pIns->VolEnv.nSustainStart++;
- if (pIns->VolEnv.nSustainEnd >= i) pIns->VolEnv.nSustainEnd++;
- if (pIns->VolEnv.nReleaseNode>=i && pIns->VolEnv.nReleaseNode!=ENV_RELEASE_NODE_UNSET) pIns->VolEnv.nReleaseNode++;
- bOk = TRUE;
+ envelope->Ticks[0] = 0;
+ envelope->Values[0] = cDefaultValue;
+ envelope->nNodes = 1;
}
- break;
- case ENV_PANNING:
- if (pIns->PanEnv.nNodes < maxpoints)
+ UINT i = 0;
+ for (i = 0; i < envelope->nNodes; i++) if (nTick <= envelope->Ticks[i]) break;
+ for (UINT j = envelope->nNodes; j > i; j--)
{
- if (!pIns->PanEnv.nNodes)
- {
- pIns->PanEnv.Ticks[0] = 0;
- pIns->PanEnv.Values[0] = 32;
- pIns->PanEnv.nNodes = 1;
- }
- UINT i = 0;
- for (i=0; i<pIns->PanEnv.nNodes; i++) if (nTick <= pIns->PanEnv.Ticks[i]) break;
- for (UINT j=pIns->PanEnv.nNodes; j>i; j--)
- {
- pIns->PanEnv.Ticks[j] = pIns->PanEnv.Ticks[j-1];
- pIns->PanEnv.Values[j] = pIns->PanEnv.Values[j-1];
- }
- pIns->PanEnv.Ticks[i] = (WORD)nTick;
- pIns->PanEnv.Values[i] =(BYTE)nValue;
- pIns->PanEnv.nNodes++;
- if (pIns->PanEnv.nLoopStart >= i) pIns->PanEnv.nLoopStart++;
- if (pIns->PanEnv.nLoopEnd >= i) pIns->PanEnv.nLoopEnd++;
- if (pIns->PanEnv.nSustainStart >= i) pIns->PanEnv.nSustainStart++;
- if (pIns->PanEnv.nSustainEnd >= i) pIns->PanEnv.nSustainEnd++;
- if (pIns->PanEnv.nReleaseNode>=i && pIns->PanEnv.nReleaseNode!=ENV_RELEASE_NODE_UNSET) pIns->PanEnv.nReleaseNode++;
- bOk = TRUE;
+ envelope->Ticks[j] = envelope->Ticks[j - 1];
+ envelope->Values[j] = envelope->Values[j - 1];
}
- break;
- case ENV_PITCH:
- if (pIns->PitchEnv.nNodes < maxpoints)
- {
- if (!pIns->PitchEnv.nNodes)
- {
- pIns->PitchEnv.Ticks[0] = 0;
- pIns->PitchEnv.Values[0] = 32;
- pIns->PitchEnv.nNodes = 1;
- }
- UINT i = 0;
- for (i=0; i<pIns->PitchEnv.nNodes; i++) if (nTick <= pIns->PitchEnv.Ticks[i]) break;
- for (UINT j=pIns->PitchEnv.nNodes; j>i; j--)
- {
- pIns->PitchEnv.Ticks[j] = pIns->PitchEnv.Ticks[j-1];
- pIns->PitchEnv.Values[j] = pIns->PitchEnv.Values[j-1];
- }
- pIns->PitchEnv.Ticks[i] = (WORD)nTick;
- pIns->PitchEnv.Values[i] = (BYTE)nValue;
- pIns->PitchEnv.nNodes++;
- if (pIns->PitchEnv.nLoopStart >= i) pIns->PitchEnv.nLoopStart++;
- if (pIns->PitchEnv.nLoopEnd >= i) pIns->PitchEnv.nLoopEnd++;
- if (pIns->PitchEnv.nSustainStart >= i) pIns->PitchEnv.nSustainStart++;
- if (pIns->PitchEnv.nSustainEnd >= i) pIns->PitchEnv.nSustainEnd++;
- if (pIns->PitchEnv.nReleaseNode>=i && pIns->PitchEnv.nReleaseNode!=ENV_RELEASE_NODE_UNSET) pIns->PitchEnv.nReleaseNode++;
- bOk = TRUE;
- }
- break;
- }
- if (bOk)
- {
+ envelope->Ticks[i] = (WORD)nTick;
+ envelope->Values[i] = (BYTE)nValue;
+ envelope->nNodes++;
+ if (envelope->nLoopStart >= i) envelope->nLoopStart++;
+ if (envelope->nLoopEnd >= i) envelope->nLoopEnd++;
+ if (envelope->nSustainStart >= i) envelope->nSustainStart++;
+ if (envelope->nSustainEnd >= i) envelope->nSustainEnd++;
+ if (envelope->nReleaseNode >= i && envelope->nReleaseNode != ENV_RELEASE_NODE_UNSET) envelope->nReleaseNode++;
+
pModDoc->SetModified();
pModDoc->UpdateAllViews(NULL, (m_nInstrument << HINT_SHIFT_INS) | HINT_ENVELOPE, NULL);
}
@@ -2719,3 +2410,34 @@
}
+
+INSTRUMENTENVELOPE *CViewInstrument::GetEnvelopePtr() const
+//---------------------------------------------------------
+{
+ // Get a pointer to the currently selected envelope.
+ // First do some standard checks...
+ CModDoc *pModDoc = GetDocument();
+ if(pModDoc == nullptr) return nullptr;
+ CSoundFile *pSndFile = pModDoc->GetSoundFile();
+ if(pSndFile == nullptr) return nullptr;
+ MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument];
+ if(pIns == nullptr) return nullptr;
+
+ // Now for the real thing.
+ INSTRUMENTENVELOPE *envelope = nullptr;
+
+ switch(m_nEnv)
+ {
+ case ENV_VOLUME:
+ envelope = &pIns->VolEnv;
+ break;
+ case ENV_PANNING:
+ envelope = &pIns->PanEnv;
+ break;
+ case ENV_PITCH:
+ envelope = &pIns->PitchEnv;
+ break;
+ }
+
+ return envelope;
+}
Modified: trunk/OpenMPT/mptrack/View_ins.h
===================================================================
--- trunk/OpenMPT/mptrack/View_ins.h 2009-08-18 20:38:41 UTC (rev 332)
+++ trunk/OpenMPT/mptrack/View_ins.h 2009-08-18 23:06:08 UTC (rev 333)
@@ -41,6 +41,7 @@
public:
void UpdateScrollSize();
BOOL SetCurrentInstrument(UINT nIns, UINT m_nEnv=0);
+ INSTRUMENTENVELOPE *GetEnvelopePtr() const;
UINT EnvGetTick(int nPoint) const;
UINT EnvGetValue(int nPoint) const;
UINT EnvGetLastPoint() const;
@@ -49,25 +50,25 @@
UINT EnvGetLoopEnd() const;
UINT EnvGetSustainStart() const;
UINT EnvGetSustainEnd() const;
- BOOL EnvGetLoop() const;
- BOOL EnvGetSustain() const;
- BOOL EnvGetCarry() const;
- BOOL EnvGetVolEnv() const;
- BOOL EnvGetPanEnv() const;
- BOOL EnvGetPitchEnv() const;
- BOOL EnvGetFilterEnv() const;
- BOOL EnvSetValue(int nPoint, int nTick=-1, int nValue=-1);
- BOOL EnvSetLoopStart(int nPoint);
- BOOL EnvSetLoopEnd(int nPoint);
- BOOL EnvSetSustainStart(int nPoint);
- BOOL EnvSetSustainEnd(int nPoint);
- BOOL EnvSetLoop(BOOL bLoop);
- BOOL EnvSetSustain(BOOL bSustain);
- BOOL EnvSetCarry(BOOL bCarry);
- BOOL EnvSetVolEnv(BOOL bEnable);
- BOOL EnvSetPanEnv(BOOL bEnable);
- BOOL EnvSetPitchEnv(BOOL bEnable);
- BOOL EnvSetFilterEnv(BOOL bEnable);
+ bool EnvGetLoop() const;
+ bool EnvGetSustain() const;
+ bool EnvGetCarry() const;
+ bool EnvGetVolEnv() const;
+ bool EnvGetPanEnv() const;
+ bool EnvGetPitchEnv() const;
+ bool EnvGetFilterEnv() const;
+ bool EnvSetValue(int nPoint, int nTick=-1, int nValue=-1);
+ bool EnvSetLoopStart(int nPoint);
+ bool EnvSetLoopEnd(int nPoint);
+ bool EnvSetSustainStart(int nPoint);
+ bool EnvSetSustainEnd(int nPoint);
+ bool EnvSetLoop(bool bLoop);
+ bool EnvSetSustain(bool bSustain);
+ bool EnvSetCarry(bool bCarry);
+ bool EnvSetVolEnv(bool bEnable);
+ bool EnvSetPanEnv(bool bEnable);
+ bool EnvSetPitchEnv(bool bEnable);
+ bool EnvSetFilterEnv(bool bEnable);
int TickToScreen(int nTick) const;
int PointToScreen(int nPoint) const;
int ScreenToTick(int x) const;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2009-08-18 20:38:58
|
Revision: 332
http://modplug.svn.sourceforge.net/modplug/?rev=332&view=rev
Author: relabsoluness
Date: 2009-08-18 20:38:41 +0000 (Tue, 18 Aug 2009)
Log Message:
-----------
[Mod] Default keybindings and tunings are now loaded from resources.
[Ref] Some related tweaks and renaming.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/CommandSet.cpp
trunk/OpenMPT/mptrack/CommandSet.h
trunk/OpenMPT/mptrack/Ctrl_ins.cpp
trunk/OpenMPT/mptrack/InputHandler.cpp
trunk/OpenMPT/mptrack/Stdafx.h
trunk/OpenMPT/mptrack/misc_util.cpp
trunk/OpenMPT/mptrack/misc_util.h
trunk/OpenMPT/mptrack/mptrack.rc
trunk/OpenMPT/mptrack/mptrack.vcproj
trunk/OpenMPT/mptrack/mptrack_08.vcproj
trunk/OpenMPT/mptrack/resource.h
trunk/OpenMPT/soundlib/Load_it.cpp
trunk/OpenMPT/soundlib/Sndfile.cpp
trunk/OpenMPT/soundlib/Sndfile.h
Added Paths:
-----------
trunk/OpenMPT/mptrack/res/built-inTunings.tc
trunk/OpenMPT/mptrack/res/defaultKeybindings.mkb
Removed Paths:
-------------
trunk/OpenMPT/mptrack/bin/tunings/
trunk/OpenMPT/packageTemplate/default.mkb
trunk/OpenMPT/packageTemplate/tunings/
Modified: trunk/OpenMPT/mptrack/CommandSet.cpp
===================================================================
--- trunk/OpenMPT/mptrack/CommandSet.cpp 2009-08-18 18:41:12 UTC (rev 331)
+++ trunk/OpenMPT/mptrack/CommandSet.cpp 2009-08-18 20:38:41 UTC (rev 332)
@@ -2,8 +2,10 @@
#include "stdafx.h"
#include ".\commandset.h"
+#include "resource.h"
#include <stdio.h>
#include <stdlib.h>
+#include <fstream>
#define ENABLE_LOGGING 0
@@ -3074,7 +3076,7 @@
if( (outStream = fopen( fileName, "w" )) == NULL )
{
- ::MessageBox(NULL, "Can't open file for writing.", "", MB_ICONEXCLAMATION|MB_OK);
+ AfxMessageBox(IDS_CANT_OPEN_FILE_FOR_WRITING, MB_ICONEXCLAMATION|MB_OK);
return false;
}
fprintf(outStream, "//-------- OpenMPT key binding definition file -------\n");
@@ -3111,10 +3113,9 @@
return true;
}
-bool CCommandSet::LoadFile(CString fileName)
+
+bool CCommandSet::LoadFile(std::istream& iStrm, LPCTSTR szFilename)
{
-
- FILE *inStream;
KeyCombination kc;
CommandID cmd=kcNumCommands;
char s[1024];
@@ -3124,17 +3125,8 @@
int l=0;
pTempCS = new CCommandSet();
-
-
- if( (inStream = fopen( fileName, "r" )) == NULL )
- {
- ::MessageBox(NULL, "Can't open file keyboard config file " + fileName + " for reading.", "", MB_ICONEXCLAMATION|MB_OK);
- delete pTempCS;
- return false;
- }
-
int errorCount=0;
- while(fgets(s,1024,inStream))
+ while(iStrm.getline(s, sizeof(s)))
{
//::MessageBox(NULL, s, "", MB_ICONEXCLAMATION|MB_OK);
curLine = s;
@@ -3189,7 +3181,7 @@
errorCount++;
CString err;
if (errorCount<10) {
- err.Format("Line %d in key binding file %s was not understood.", l, fileName);
+ err.Format("Line %d in key binding file %s was not understood.", l, szFilename);
if(s_bShowErrorOnUnknownKeybinding) ::MessageBox(NULL, err, "", MB_ICONEXCLAMATION|MB_OK);
Log(err);
} else if (errorCount==10) {
@@ -3214,6 +3206,19 @@
return true;
}
+bool CCommandSet::LoadFile(CString fileName)
+{
+ std::ifstream fin(fileName);
+ if (fin.fail())
+ {
+ CString strMsg;
+ AfxFormatString1(strMsg, IDS_CANT_OPEN_KEYBINDING_FILE, fileName);
+ AfxMessageBox(strMsg, MB_ICONEXCLAMATION|MB_OK);
+ return false;
+ }
+ else
+ return LoadFile(fin, fileName);
+}
//Could do better search algo but this is not perf critical.
Modified: trunk/OpenMPT/mptrack/CommandSet.h
===================================================================
--- trunk/OpenMPT/mptrack/CommandSet.h 2009-08-18 18:41:12 UTC (rev 331)
+++ trunk/OpenMPT/mptrack/CommandSet.h 2009-08-18 20:38:41 UTC (rev 332)
@@ -1101,6 +1101,7 @@
void GenKeyMap(KeyMap &km); // Generate a keymap from this command set
bool SaveFile(CString FileName, bool debug);
bool LoadFile(CString FileName);
+ bool LoadFile(std::istream& iStrm, LPCTSTR szFilename);
static DWORD GetKeymapLabel(InputTargetContext ctx, UINT mod, UINT code, KeyEventType ke);
Modified: trunk/OpenMPT/mptrack/Ctrl_ins.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2009-08-18 18:41:12 UTC (rev 331)
+++ trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2009-08-18 20:38:41 UTC (rev 332)
@@ -2553,11 +2553,11 @@
sel -= 1;
CTuningCollection* tc = 0;
- if(sel < CSoundFile::GetStandardTunings().GetNumTunings())
- tc = &CSoundFile::GetStandardTunings();
+ if(sel < CSoundFile::GetBuiltInTunings().GetNumTunings())
+ tc = &CSoundFile::GetBuiltInTunings();
else
{
- sel -= CSoundFile::GetStandardTunings().GetNumTunings();
+ sel -= CSoundFile::GetBuiltInTunings().GetNumTunings();
if(sel < CSoundFile::GetLocalTunings().GetNumTunings())
tc = &CSoundFile::GetLocalTunings();
else
@@ -2581,7 +2581,7 @@
//Case: Chosen tuning editor to be displayed.
//Creating vector for the CTuningDialog.
vector<CTuningCollection*> v;
- v.push_back(&m_pSndFile->GetStandardTunings());
+ v.push_back(&m_pSndFile->GetBuiltInTunings());
v.push_back(&m_pSndFile->GetLocalTunings());
v.push_back(&m_pSndFile->GetTuneSpecificTunings());
CTuningDialog td(this, v, pInstH->pTuning);
@@ -2618,9 +2618,9 @@
return;
}
- for(size_t i = 0; i < CSoundFile::GetStandardTunings().GetNumTunings(); i++)
+ for(size_t i = 0; i < CSoundFile::GetBuiltInTunings().GetNumTunings(); i++)
{
- if(pIns->pTuning == &CSoundFile::GetStandardTunings().GetTuning(i))
+ if(pIns->pTuning == &CSoundFile::GetBuiltInTunings().GetTuning(i))
{
m_ComboTuning.SetCurSel(i+1);
return;
@@ -2631,7 +2631,7 @@
{
if(pIns->pTuning == &CSoundFile::GetLocalTunings().GetTuning(i))
{
- m_ComboTuning.SetCurSel(i+CSoundFile::GetStandardTunings().GetNumTunings()+1);
+ m_ComboTuning.SetCurSel(i+CSoundFile::GetBuiltInTunings().GetNumTunings()+1);
return;
}
}
@@ -2640,7 +2640,7 @@
{
if(pIns->pTuning == &m_pSndFile->GetTuneSpecificTunings().GetTuning(i))
{
- m_ComboTuning.SetCurSel(i+CSoundFile::GetStandardTunings().GetNumTunings() + CSoundFile::GetLocalTunings().GetNumTunings()+1);
+ m_ComboTuning.SetCurSel(i+CSoundFile::GetBuiltInTunings().GetNumTunings() + CSoundFile::GetLocalTunings().GetNumTunings()+1);
return;
}
}
@@ -2792,9 +2792,9 @@
m_ComboTuning.DeleteString(0);
m_ComboTuning.AddString("OMPT IT behavior"); //<-> Instrument pTuning pointer == NULL
- for(size_t i = 0; i<CSoundFile::GetStandardTunings().GetNumTunings(); i++)
+ for(size_t i = 0; i<CSoundFile::GetBuiltInTunings().GetNumTunings(); i++)
{
- m_ComboTuning.AddString(CSoundFile::GetStandardTunings().GetTuning(i).GetName().c_str());
+ m_ComboTuning.AddString(CSoundFile::GetBuiltInTunings().GetTuning(i).GetName().c_str());
}
for(size_t i = 0; i<CSoundFile::GetLocalTunings().GetNumTunings(); i++)
{
Modified: trunk/OpenMPT/mptrack/InputHandler.cpp
===================================================================
--- trunk/OpenMPT/mptrack/InputHandler.cpp 2009-08-18 18:41:12 UTC (rev 331)
+++ trunk/OpenMPT/mptrack/InputHandler.cpp 2009-08-18 20:38:41 UTC (rev 332)
@@ -8,6 +8,8 @@
#include "mainfrm.h"
#include <direct.h>
#include ".\inputhandler.h"
+#include <strstream>
+#include <Shlwapi.h>
#define TRANSITIONBIT 0x8000
#define REPEATBIT 0x4000
@@ -21,17 +23,43 @@
activeCommandSet = new CCommandSet();
CCommandSet::s_bShowErrorOnUnknownKeybinding = (CMainFrame::GetMainFrame()->GetPrivateProfileLong("Misc", "ShowErrorOnUnknownKeybinding", 1, theApp.GetConfigFileName()) != 0);
- CString workingDir;
- char wd[255];
- _getdcwd(_getdrive(), wd, 255);
- workingDir = wd;
- if (!CMainFrame::m_szKbdFile[0]) {
- strcpy(CMainFrame::m_szKbdFile, workingDir + "\\default.mkb");
- }
- if (!(activeCommandSet->LoadFile(CMainFrame::m_szKbdFile))) {
- if (!(activeCommandSet->LoadFile(workingDir + "\\default.mkb"))) {
- AfxMessageBox("Warning! OpenMPT has not been able to locate a keymap file. Please locate one in the settings.\r\nUntil you do so, the keyboard will not work in OpenMPT.");
+ CString sDefaultPath = CMainFrame::m_csExecutableDirectoryPath + TEXT("Keybindings.mkb");
+ if (sDefaultPath.GetLength() > MAX_PATH - 1)
+ sDefaultPath = "";
+
+ const bool bNoExistingKbdFileSetting = (CMainFrame::m_szKbdFile[0] == 0);
+
+ // 1. Try to load keybindings from the path saved in the settings.
+ // 2. If the setting doesn't exist or the loading fails, try to load from default location.
+ // 3. If neither one of these worked, load default keybindings from resources.
+ // 4. If there were no keybinging setting already, create a keybinding file to default location
+ // and set it's path to settings.
+
+ if (bNoExistingKbdFileSetting || !(activeCommandSet->LoadFile(CMainFrame::m_szKbdFile)))
+ {
+ if (bNoExistingKbdFileSetting)
+ _tcscpy(CMainFrame::m_szKbdFile, sDefaultPath);
+ bool bSuccess = false;
+ if (PathFileExists(sDefaultPath) == TRUE)
+ bSuccess = activeCommandSet->LoadFile(sDefaultPath);
+ if (bSuccess == false)
+ {
+ // Load keybindings from resources.
+ Log("Loading keybindings from resources\n");
+ const char* pData = nullptr;
+ HGLOBAL hglob = nullptr;
+ size_t nSize = 0;
+ if (LoadResource(MAKEINTRESOURCE(IDR_DEFAULT_KEYBINDINGS), TEXT("KEYBINDINGS"), pData, nSize, hglob) != nullptr)
+ {
+ std::istrstream iStrm(pData, nSize);
+ bSuccess = activeCommandSet->LoadFile(iStrm, TEXT("\"executable resource\""));
+ FreeResource(hglob);
+ if (bSuccess && bNoExistingKbdFileSetting)
+ activeCommandSet->SaveFile(CMainFrame::m_szKbdFile, false);
+ }
}
+ if (bSuccess == false)
+ AfxMessageBox(IDS_UNABLE_TO_LOAD_KEYBINDINGS, MB_ICONERROR);
}
//Get Keymap
@@ -148,7 +176,7 @@
inp[0].type = inp[1].type = INPUT_KEYBOARD;
inp[0].ki.time = inp[1].ki.time = 0;
inp[0].ki.dwExtraInfo = inp[0].ki.dwExtraInfo = 0;
- inp[0].ki.wVk = inp[1].ki.wVk = nChar;
+ inp[0].ki.wVk = inp[1].ki.wVk = static_cast<WORD>(nChar);
inp[0].ki.wScan = inp[1].ki.wScan = 0;
inp[0].ki.dwFlags = KEYEVENTF_KEYUP;
inp[1].ki.dwFlags = 0;
@@ -339,12 +367,12 @@
bool CInputHandler::CtrlPressed(void)
{
- return (modifierMask & HOTKEYF_CONTROL);
+ return ((modifierMask & HOTKEYF_CONTROL) != 0);
}
bool CInputHandler::AltPressed(void)
{
- return (modifierMask & HOTKEYF_ALT);
+ return ((modifierMask & HOTKEYF_ALT) != 0);
}
void CInputHandler::Bypass(bool b)
Modified: trunk/OpenMPT/mptrack/Stdafx.h
===================================================================
--- trunk/OpenMPT/mptrack/Stdafx.h 2009-08-18 18:41:12 UTC (rev 331)
+++ trunk/OpenMPT/mptrack/Stdafx.h 2009-08-18 20:38:41 UTC (rev 332)
@@ -50,6 +50,10 @@
//#include <afxdhtml.h>
#pragma warning(default:4201)
+#include <string>
+#include <fstream>
+#include <strstream>
+
#ifndef OFN_FORCESHOWHIDDEN
#define OFN_FORCESHOWHIDDEN 0x10000000
#endif
Modified: trunk/OpenMPT/mptrack/misc_util.cpp
===================================================================
--- trunk/OpenMPT/mptrack/misc_util.cpp 2009-08-18 18:41:12 UTC (rev 331)
+++ trunk/OpenMPT/mptrack/misc_util.cpp 2009-08-18 20:38:41 UTC (rev 332)
@@ -1,3 +1,31 @@
#include "stdafx.h"
#include "misc_util.h"
+/*
+ * Loads resource.
+ * lpName and lpType: parameters passed to FindResource().
+ * pData: Pointer to loaded resource data, nullptr if load not successful.
+ * nSize: Size of the data in bytes, zero if load not succesfull.
+ * hglob: HGLOBAL returned by LoadResource-function.
+ * Return: pData.
+ */
+LPCCH LoadResource(LPCTSTR lpName, LPCTSTR lpType, LPCCH& pData, size_t& nSize, HGLOBAL& hglob)
+//---------------------------------------------------------------------------------------------
+{
+ pData = nullptr;
+ nSize = 0;
+ hglob = nullptr;
+ HINSTANCE hInstance = AfxGetInstanceHandle();
+ HRSRC hrsrc = FindResource(hInstance, lpName, lpType);
+ if (hrsrc != NULL)
+ {
+ hglob = LoadResource(hInstance, hrsrc);
+ if (hglob != NULL)
+ {
+ pData = reinterpret_cast<const char*>(LockResource(hglob));
+ nSize = SizeofResource(hInstance, hrsrc);
+ }
+ }
+ return pData;
+}
+
Modified: trunk/OpenMPT/mptrack/misc_util.h
===================================================================
--- trunk/OpenMPT/mptrack/misc_util.h 2009-08-18 18:41:12 UTC (rev 331)
+++ trunk/OpenMPT/mptrack/misc_util.h 2009-08-18 20:38:41 UTC (rev 332)
@@ -78,5 +78,7 @@
#define CLAMP(number, low, high) min(high, max(low, number))
#endif
+
+LPCCH LoadResource(LPCTSTR lpName, LPCTSTR lpType, LPCCH& pData, size_t& nSize, HGLOBAL& hglob);
#endif
Modified: trunk/OpenMPT/mptrack/mptrack.rc
===================================================================
--- trunk/OpenMPT/mptrack/mptrack.rc 2009-08-18 18:41:12 UTC (rev 331)
+++ trunk/OpenMPT/mptrack/mptrack.rc 2009-08-18 20:38:41 UTC (rev 332)
@@ -13,7 +13,7 @@
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
-// Deutsch (Deutschland) resources
+// German (Germany) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU)
#ifdef _WIN32
@@ -55,12 +55,12 @@
END
#endif // APSTUDIO_INVOKED
-#endif // Deutsch (Deutschland) resources
+#endif // German (Germany) resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
-// Englisch (USA) resources
+// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
@@ -2204,14 +2204,19 @@
IDS_UNSUPPORTED_TUNING_DnD
"For the time being Drag and Drop is only supported for tuning instances."
IDS_OPERATION_FAIL "Operation failed."
+ IDS_CANT_OPEN_KEYBINDING_FILE
+ "Can't open keybindings file %1 for reading. Default keybindings will be used."
+ IDS_UNABLE_TO_LOAD_KEYBINDINGS
+ "Loading keybindings failed. The keyboard won't work properly."
+ IDS_CANT_OPEN_FILE_FOR_WRITING "Can't open file for writing."
END
-#endif // Englisch (USA) resources
+#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
-// Englisch (GB) resources
+// English (U.K.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
#ifdef _WIN32
@@ -2565,11 +2570,25 @@
//
1 RT_MANIFEST "res\\rt_manif.bin"
-#endif // Englisch (GB) resources
+
/////////////////////////////////////////////////////////////////////////////
+//
+// KEYBINDINGS
+//
+IDR_DEFAULT_KEYBINDINGS KEYBINDINGS "res\\defaultKeybindings.mkb"
+/////////////////////////////////////////////////////////////////////////////
+//
+// TUNING
+//
+IDR_BUILTIN_TUNINGS TUNING "res\\built-inTunings.tc"
+#endif // English (U.K.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
Modified: trunk/OpenMPT/mptrack/mptrack.vcproj
===================================================================
--- trunk/OpenMPT/mptrack/mptrack.vcproj 2009-08-18 18:41:12 UTC (rev 331)
+++ trunk/OpenMPT/mptrack/mptrack.vcproj 2009-08-18 20:38:41 UTC (rev 332)
@@ -638,9 +638,15 @@
RelativePath="res\bitmap1.bmp">
</File>
<File
+ RelativePath=".\res\built-inTunings.tc">
+ </File>
+ <File
RelativePath=".\res\colors.bmp">
</File>
<File
+ RelativePath=".\res\defaultKeyBindings.mkb">
+ </File>
+ <File
RelativePath=".\res\dragging.cur">
</File>
<File
Modified: trunk/OpenMPT/mptrack/mptrack_08.vcproj
===================================================================
--- trunk/OpenMPT/mptrack/mptrack_08.vcproj 2009-08-18 18:41:12 UTC (rev 331)
+++ trunk/OpenMPT/mptrack/mptrack_08.vcproj 2009-08-18 20:38:41 UTC (rev 332)
@@ -1236,6 +1236,14 @@
</File>
</Filter>
<File
+ RelativePath=".\res\built-inTunings.tc"
+ >
+ </File>
+ <File
+ RelativePath=".\res\defaultKeybindings.mkb"
+ >
+ </File>
+ <File
RelativePath=".\mptrack.reg"
>
</File>
Added: trunk/OpenMPT/mptrack/res/built-inTunings.tc
===================================================================
(Binary files differ)
Property changes on: trunk/OpenMPT/mptrack/res/built-inTunings.tc
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: trunk/OpenMPT/mptrack/res/defaultKeybindings.mkb
===================================================================
--- trunk/OpenMPT/mptrack/res/defaultKeybindings.mkb (rev 0)
+++ trunk/OpenMPT/mptrack/res/defaultKeybindings.mkb 2009-08-18 20:38:41 UTC (rev 332)
@@ -0,0 +1,280 @@
+//-------- OpenMPT key binding definition file -------
+//-Format is: -
+//- Context:Command ID:Modifiers:Key:KeypressEventType //Comments -
+//----------------------------------------------------------------------
+
+//----( Global Context (0) )------------
+0:1347:2:78:1 //File/New: Ctrl+N (KeyDown)
+0:1346:2:79:1 //File/Open: Ctrl+O (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)
+0:1375:0:27:1 //Stop Song: ESC (KeyDown)
+0:1029:0:117:1 //Play song from start: F6 (KeyDown)
+0:1027:0:118:5 //Play pattern from start: F7 (KeyDown|KeyHold)
+0:1026:2:118:5 //Play pattern from cursor: Ctrl+F7 (KeyDown|KeyHold)
+0:1376:0:120:1 //Toggle Midi Record: F9 (KeyDown)
+0:1359:2:90:1 //Undo: Ctrl+Z (KeyDown)
+0:1360:2:88:1 //Cut: Ctrl+X (KeyDown)
+0:1361:2:67:1 //Copy: Ctrl+C (KeyDown)
+0:1361:2:45:1 //Copy: Ctrl+INSERT (KeyDown)
+0:1362:2:86:1 //Paste: Ctrl+V (KeyDown)
+0:1362:1:45:1 //Paste: Shift+INSERT (KeyDown)
+0:1364:2:53:1 //SelectAll: Ctrl+5 (KeyDown)
+0:1365:2:70:1 //Find: Ctrl+F (KeyDown)
+0:1366:0:114:1 //Find Next: F3 (KeyDown)
+0:1021:4:71:1 //View General: Alt+G (KeyDown)
+0:1022:4:80:1 //View Pattern: Alt+P (KeyDown)
+0:1023:4:83:1 //View Samples: Alt+S (KeyDown)
+0:1024:4:78:1 //View Instruments: Alt+N (KeyDown)
+0:1025:1:120:1 //View Comments: Shift+F9 (KeyDown)
+0:1368:2:113:1 //Toggle Tree View: Ctrl+F2 (KeyDown)
+0:1369:2:112:1 //View Options: Ctrl+F1 (KeyDown)
+0:1370:0:112:1 //Help (to do): F1 (KeyDown)
+0:1032:2:111:5 //Previous instrument: Ctrl+NUM DIVIDE (KeyDown|KeyHold)
+0:1032:2:38:5 //Previous instrument: Ctrl+UP (KeyDown|KeyHold)
+0:1033:2:106:5 //Next instrument: Ctrl+NUMMULT (KeyDown|KeyHold)
+0:1033:2:40:5 //Next instrument: Ctrl+DOWN (KeyDown|KeyHold)
+0:1036:0:111:1 //Previous octave: NUM DIVIDE (KeyDown)
+0:1037:0:106:1 //Next octave: NUMMULT (KeyDown)
+0:1034:2:37:5 //Previous order: Ctrl+LEFT (KeyDown|KeyHold)
+0:1035:2:39:5 //Next order: Ctrl+RIGHT (KeyDown|KeyHold)
+
+//----( General Context [bottom] (1) )------------
+
+//----( Pattern Context [bottom] (2) )------------
+2:1017:0:34:5 //Jump down by measure: PGDOWN (KeyDown|KeyHold)
+2:1018:0:33:5 //Jump up by measure: PGUP (KeyDown|KeyHold)
+2:1338:4:34:5 //Jump down by beat: Alt+PGDOWN (KeyDown|KeyHold)
+2:1339:4:33:5 //Jump up by beat: Alt+PGUP (KeyDown|KeyHold)
+2:1340:6:34:5 //Snap down to beat: Ctrl+Alt+PGDOWN (KeyDown|KeyHold)
+2:1341:6:33:5 //Snap up to beat: Ctrl+Alt+PGUP (KeyDown|KeyHold)
+2:1038:0:40:5 //Navigate down by 1 row: DOWN (KeyDown|KeyHold)
+2:1039:0:38:5 //Navigate up by 1 row: UP (KeyDown|KeyHold)
+2:1691:4:40:5 //Navigate down by spacing: Alt+DOWN (KeyDown|KeyHold)
+2:1692:4:38:5 //Navigate up by spacing: Alt+UP (KeyDown|KeyHold)
+2:1040:0:37:5 //Navigate left: LEFT (KeyDown|KeyHold)
+2:1041:0:39:5 //Navigate right: RIGHT (KeyDown|KeyHold)
+2:1042:0:9:5 //Navigate to next channel: TAB (KeyDown|KeyHold)
+2:1043:1:9:5 //Navigate to previous channel: Shift+TAB (KeyDown|KeyHold)
+2:1044:0:36:1 //Go to first channel: HOME (KeyDown)
+2:1045:2:36:1 //Go to first row: Ctrl+HOME (KeyDown)
+2:1046:6:36:1 //Go to first row of first channel: Ctrl+Alt+HOME (KeyDown)
+2:1047:0:35:1 //Go to last channel: END (KeyDown)
+2:1048:2:35:1 //Go to last row: Ctrl+END (KeyDown)
+2:1049:6:35:1 //Go to last row of last channel: Ctrl+Alt+END (KeyDown)
+2:1050:1:16:1 //Selection key: Shift (KeyDown)
+2:1051:2:17:1 //Copy select key: Ctrl (KeyDown)
+2:1011:2:76:1 //Select channel / Select all: Ctrl+L (KeyDown)
+2:1663:0:122:1 //Toggle follow song: F11 (KeyDown)
+2:1003:0:13:5 //Quick copy: ENTER (KeyDown|KeyHold)
+2:1004:0:32:5 //Quick paste: SPACE (KeyDown|KeyHold)
+2:1001:2:32:1 //Enable recording: Ctrl+SPACE (KeyDown)
+2:1002:2:13:5 //Play row: Ctrl+ENTER (KeyDown|KeyHold)
+2:1317:4:18:1 //Set row jump on note entry: Alt (KeyDown)
+2:1685:2:9:1 //Switch to order list: Ctrl+TAB (KeyDown)
+2:1662:6:80:1 //Toggle channel's plugin editor: Ctrl+Alt+P (KeyDown)
+2:1062:0:93:1 //Show note properties: Application (KeyDown)
+2:1005:0:121:5 //Mute current channel: F10 (KeyDown|KeyHold)
+2:1006:2:121:5 //Solo current channel: Ctrl+F10 (KeyDown|KeyHold)
+2:1007:2:81:5 //Transpose +1: Ctrl+Q (KeyDown|KeyHold)
+2:1008:2:65:5 //Transpose -1: Ctrl+A (KeyDown|KeyHold)
+2:1009:3:81:5 //Transpose +12: Shift+Ctrl+Q (KeyDown|KeyHold)
+2:1010:3:65:5 //Transpose -12: Shift+Ctrl+A (KeyDown|KeyHold)
+2:1012:2:77:1 //Amplify selection: Ctrl+M (KeyDown)
+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:1058:0:46:1 //Clear field: DELETE (KeyDown)
+2:1664:1:190:1 //Clear field (IT Style): Shift+. (KeyDown)
+2:1059:2:46:1 //Clear row and step: Ctrl+DELETE (KeyDown)
+2:1665:1:46:5 //Clear field and step (IT Style): Shift+DELETE (KeyDown|KeyHold)
+2:1061:0:8:5 //Delete rows: BACKSPACE (KeyDown|KeyHold)
+2:1377:2:8:5 //Delete all rows: Ctrl+BACKSPACE (KeyDown|KeyHold)
+2:1378:0:45:1 //Insert Row: INSERT (KeyDown)
+2:1379:2:45:1 //Insert All Rows: Ctrl+INSERT (KeyDown)
+2:1055:0:109:5 //Previous pattern: NUM SUB (KeyDown|KeyHold)
+2:1054:0:107:5 //Next pattern: NUM PLUS (KeyDown|KeyHold)
+
+//----( Pattern Context [bottom] - Note Col (3) )------------
+3:1064:0:81:1 //Base octave C: Q (KeyDown)
+3:1065:0:87:1 //Base octave C#: W (KeyDown)
+3:1066:0:69:1 //Base octave D: E (KeyDown)
+3:1067:0:82:1 //Base octave D#: R (KeyDown)
+3:1068:0:84:1 //Base octave E: T (KeyDown)
+3:1069:0:89:1 //Base octave F: Y (KeyDown)
+3:1070:0:85:1 //Base octave F#: U (KeyDown)
+3:1071:0:73:1 //Base octave G: I (KeyDown)
+3:1072:0:79:1 //Base octave G#: O (KeyDown)
+3:1073:0:80:1 //Base octave +1 A: P (KeyDown)
+3:1074:0:219:1 //Base octave +1 A#: [ (KeyDown)
+3:1075:0:221:1 //Base octave +1 B: ] (KeyDown)
+3:1076:0:65:1 //Base octave +1 C: A (KeyDown)
+3:1077:0:83:1 //Base octave +1 C#: S (KeyDown)
+3:1078:0:68:1 //Base octave +1 D: D (KeyDown)
+3:1079:0:70:1 //Base octave +1 D#: F (KeyDown)
+3:1080:0:71:1 //Base octave +1 E: G (KeyDown)
+3:1081:0:72:1 //Base octave +1 F: H (KeyDown)
+3:1082:0:74:1 //Base octave +1 F#: J (KeyDown)
+3:1083:0:75:1 //Base octave +1 G: K (KeyDown)
+3:1084:0:76:1 //Base octave +1 G#: L (KeyDown)
+3:1085:0:186:1 //Base octave +2 A: ; (KeyDown)
+3:1086:0:222:1 //Base octave +2 A#: # (KeyDown)
+3:1087:0:220:1 //Base octave +2 B: \ (KeyDown)
+3:1088:0:90:1 //Base octave +2 C: Z (KeyDown)
+3:1089:0:88:1 //Base octave +2 C#: X (KeyDown)
+3:1090:0:67:1 //Base octave +2 D: C (KeyDown)
+3:1091:0:86:1 //Base octave +2 D#: V (KeyDown)
+3:1092:0:66:1 //Base octave +2 E: B (KeyDown)
+3:1093:0:78:1 //Base octave +2 F: N (KeyDown)
+3:1094:0:77:1 //Base octave +2 F#: M (KeyDown)
+3:1095:0:188:1 //Base octave +2 G: , (KeyDown)
+3:1096:0:190:1 //Base octave +2 G#: . (KeyDown)
+3:1097:0:191:1 //Base octave +3 A: / (KeyDown)
+3:1212:0:48:1 //Set octave 0: 0 (KeyDown)
+3:1212:0:96:1 //Set octave 0: NUM 0 (KeyDown)
+3:1213:0:49:1 //Set octave 1: 1 (KeyDown)
+3:1213:0:97:1 //Set octave 1: NUM 1 (KeyDown)
+3:1214:0:50:1 //Set octave 2: 2 (KeyDown)
+3:1214:0:98:1 //Set octave 2: NUM 2 (KeyDown)
+3:1215:0:51:1 //Set octave 3: 3 (KeyDown)
+3:1215:0:99:1 //Set octave 3: NUM 3 (KeyDown)
+3:1216:0:52:1 //Set octave 4: 4 (KeyDown)
+3:1216:0:100:1 //Set octave 4: NUM 4 (KeyDown)
+3:1217:0:53:1 //Set octave 5: 5 (KeyDown)
+3:1217:0:101:1 //Set octave 5: NUM 5 (KeyDown)
+3:1218:0:54:1 //Set octave 6: 6 (KeyDown)
+3:1218:0:102:1 //Set octave 6: NUM 6 (KeyDown)
+3:1219:0:55:1 //Set octave 7: 7 (KeyDown)
+3:1219:0:103:1 //Set octave 7: NUM 7 (KeyDown)
+3:1220:0:56:1 //Set octave 8: 8 (KeyDown)
+3:1220:0:104:1 //Set octave 8: NUM 8 (KeyDown)
+3:1221:0:57:1 //Set octave 9: 9 (KeyDown)
+3:1221:0:105:1 //Set octave 9: NUM 9 (KeyDown)
+3:1316:1:16:1 //Chord Modifier: Shift (KeyDown)
+3:1200:0:192:1 //Note cut: ' (KeyDown)
+3:1201:0:187:1 //Note off: = (KeyDown)
+
+//----( Pattern Context [bottom] - Ins Col (4) )------------
+4:1202:0:96:1 //Set instrument digit 0: NUM 0 (KeyDown)
+4:1202:0:48:1 //Set instrument digit 0: 0 (KeyDown)
+4:1203:0:97:1 //Set instrument digit 1: NUM 1 (KeyDown)
+4:1203:0:49:1 //Set instrument digit 1: 1 (KeyDown)
+4:1204:0:98:1 //Set instrument digit 2: NUM 2 (KeyDown)
+4:1204:0:50:1 //Set instrument digit 2: 2 (KeyDown)
+4:1205:0:99:1 //Set instrument digit 3: NUM 3 (KeyDown)
+4:1205:0:51:1 //Set instrument digit 3: 3 (KeyDown)
+4:1206:0:100:1 //Set instrument digit 4: NUM 4 (KeyDown)
+4:1206:0:52:1 //Set instrument digit 4: 4 (KeyDown)
+4:1207:0:101:1 //Set instrument digit 5: NUM 5 (KeyDown)
+4:1207:0:53:1 //Set instrument digit 5: 5 (KeyDown)
+4:1208:0:102:1 //Set instrument digit 6: NUM 6 (KeyDown)
+4:1208:0:54:1 //Set instrument digit 6: 6 (KeyDown)
+4:1209:0:103:1 //Set instrument digit 7: NUM 7 (KeyDown)
+4:1209:0:55:1 //Set instrument digit 7: 7 (KeyDown)
+4:1210:0:56:1 //Set instrument digit 8: 8 (KeyDown)
+4:1211:0:105:1 //Set instrument digit 9: NUM 9 (KeyDown)
+4:1211:0:57:1 //Set instrument digit 9: 9 (KeyDown)
+
+//----( Pattern Context [bottom] - Vol Col (5) )------------
+5:1222:0:48:1 //Set volume digit 0: 0 (KeyDown)
+5:1222:0:96:1 //Set volume digit 0: NUM 0 (KeyDown)
+5:1223:0:49:1 //Set volume digit 1: 1 (KeyDown)
+5:1223:0:97:1 //Set volume digit 1: NUM 1 (KeyDown)
+5:1224:0:50:1 //Set volume digit 2: 2 (KeyDown)
+5:1224:0:98:1 //Set volume digit 2: NUM 2 (KeyDown)
+5:1225:0:51:1 //Set volume digit 3: 3 (KeyDown)
+5:1225:0:99:1 //Set volume digit 3: NUM 3 (KeyDown)
+5:1226:0:52:1 //Set volume digit 4: 4 (KeyDown)
+5:1226:0:100:1 //Set volume digit 4: NUM 4 (KeyDown)
+5:1227:0:53:1 //Set volume digit 5: 5 (KeyDown)
+5:1227:0:101:1 //Set volume digit 5: NUM 5 (KeyDown)
+5:1228:0:54:1 //Set volume digit 6: 6 (KeyDown)
+5:1228:0:102:1 //Set volume digit 6: NUM 6 (KeyDown)
+5:1229:0:55:1 //Set volume digit 7: 7 (KeyDown)
+5:1229:0:103:1 //Set volume digit 7: NUM 7 (KeyDown)
+5:1230:0:56:1 //Set volume digit 8: 8 (KeyDown)
+5:1231:0:57:1 //Set volume digit 9: 9 (KeyDown)
+5:1231:0:105:1 //Set volume digit 9: NUM 9 (KeyDown)
+5:1232:0:86:1 //Vol command - volume: V (KeyDown)
+5:1233:0:80:1 //Vol command - pan: P (KeyDown)
+5:1234:0:67:1 //Vol command - vol slide up: C (KeyDown)
+5:1235:0:68:1 //Vol command - vol slide down: D (KeyDown)
+5:1236:0:65:1 //Vol command - vol fine slide up: A (KeyDown)
+5:1237:0:66:1 //Vol command - vol fine slide down: B (KeyDown)
+5:1238:0:85:1 //Vol command - vibrato speed: U (KeyDown)
+5:1239:0:72:1 //Vol command - vibrato: H (KeyDown)
+5:1240:0:76:1 //Vol command - XM pan left: L (KeyDown)
+5:1241:0:82:1 //Vol command - XM pan right: R (KeyDown)
+5:1242:0:71:1 //Vol command - Portamento: G (KeyDown)
+5:1243:0:70:1 //Vol command - Portamento Up: F (KeyDown)
+5:1244:0:69:1 //Vol command - Portamento Down: E (KeyDown)
+5:1245:1:186:1 //Vol command - Velocity: Shift+; (KeyDown)
+5:1246:0:79:1 //Vol command - Offset: O (KeyDown)
+
+//----( Pattern Context [bottom] - FX Col (6) )------------
+6:1294:0:220:1 //FX midi macro slide: \ (KeyDown)
+6:1295:1:186:1 //FX pseudo-velocity (experimental): Shift+; (KeyDown)
+
+//----( Pattern Context [bottom] - Param Col (7) )------------
+7:1247:0:48:1 //FX Param digit 0: 0 (KeyDown)
+7:1247:0:96:1 //FX Param digit 0: NUM 0 (KeyDown)
+7:1248:0:49:1 //FX Param digit 1: 1 (KeyDown)
+7:1248:0:97:1 //FX Param digit 1: NUM 1 (KeyDown)
+7:1249:0:50:1 //FX Param digit 2: 2 (KeyDown)
+7:1249:0:98:1 //FX Param digit 2: NUM 2 (KeyDown)
+7:1250:0:51:1 //FX Param digit 3: 3 (KeyDown)
+7:1250:0:99:1 //FX Param digit 3: NUM 3 (KeyDown)
+7:1251:0:52:1 //FX Param digit 4: 4 (KeyDown)
+7:1251:0:100:1 //FX Param digit 4: NUM 4 (KeyDown)
+7:1252:0:53:1 //FX Param digit 5: 5 (KeyDown)
+7:1252:0:101:1 //FX Param digit 5: NUM 5 (KeyDown)
+7:1253:0:54:1 //FX Param digit 6: 6 (KeyDown)
+7:1253:0:102:1 //FX Param digit 6: NUM 6 (KeyDown)
+7:1254:0:55:1 //FX Param digit 7: 7 (KeyDown)
+7:1254:0:103:1 //FX Param digit 7: NUM 7 (KeyDown)
+7:1255:0:56:1 //FX Param digit 8: 8 (KeyDown)
+7:1255:0:104:1 //FX Param digit 8: NUM 8 (KeyDown)
+7:1256:0:57:1 //FX Param digit 9: 9 (KeyDown)
+7:1256:0:105:1 //FX Param digit 9: NUM 9 (KeyDown)
+7:1257:0:65:1 //FX Param digit A: A (KeyDown)
+7:1258:0:66:1 //FX Param digit B: B (KeyDown)
+7:1259:0:67:1 //FX Param digit C: C (KeyDown)
+7:1260:0:68:1 //FX Param digit D: D (KeyDown)
+7:1261:0:69:1 //FX Param digit E: E (KeyDown)
+7:1262:0:70:1 //FX Param digit F: F (KeyDown)
+
+//----( Sample Context [bottom] (8) )------------
+8:1380:2:84:1 //Trim sample around loop points: Ctrl+T (KeyDown)
+8:1383:0:8:1 //Silence sample selection: BACKSPACE (KeyDown)
+8:1385:3:65:1 //Amplify Sample: Shift+Ctrl+A (KeyDown)
+8:1381:3:82:1 //Reverse sample: Shift+Ctrl+R (KeyDown)
+8:1382:0:46:1 //Delete sample selection: DELETE (KeyDown)
+8:1386:0:107:1 //Zoom Out: NUM PLUS (KeyDown)
+8:1387:0:109:1 //Zoom In: NUM SUB (KeyDown)
+
+//----( Instrument Context [bottom] (9) )------------
+
+//----( Comments Context [bottom] (10) )------------
+
+//----( Unknown Context (11) )------------
+
+//----( Unknown Context (12) )------------
+
+//----( Plugin GUI Context (13) )------------
+
+//----( General Context [top] (14) )------------
+
+//----( Pattern Context [top] (15) )------------
+
+//----( Sample Context [top] (16) )------------
+
+//----( Instrument Context [top] (17) )------------
+
+//----( Comments Context [top] (18) )------------
+
+//----( Unknown Context (19) )------------
Modified: trunk/OpenMPT/mptrack/resource.h
===================================================================
--- trunk/OpenMPT/mptrack/resource.h 2009-08-18 18:41:12 UTC (rev 331)
+++ trunk/OpenMPT/mptrack/resource.h 2009-08-18 20:38:41 UTC (rev 332)
@@ -47,6 +47,9 @@
#define IDS_ERR_NO_TUNING_SELECTION 208
#define IDS_UNSUPPORTED_TUNING_DnD 209
#define IDS_OPERATION_FAIL 210
+#define IDS_CANT_OPEN_KEYBINDING_FILE 211
+#define IDS_UNABLE_TO_LOAD_KEYBINDINGS 212
+#define IDS_CANT_OPEN_FILE_FOR_WRITING 213
#define IDB_MAINBAR 300
#define IDB_IMAGELIST 301
#define IDB_PATTERNS 302
@@ -107,6 +110,8 @@
#define IDD_MSGBOX_HIDABLE 516
#define IDD_ADDSILENCE 517
#define IDD_MODLOADING_WARNINGS 518
+#define IDR_DEFAULT_KEYBINDINGS 519
+#define IDR_BUILTIN_TUNINGS 520
#define IDC_BUTTON1 1001
#define IDC_BUTTON2 1002
#define IDC_BUTTON3 1003
@@ -1116,7 +1121,7 @@
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_3D_CONTROLS 1
-#define _APS_NEXT_RESOURCE_VALUE 519
+#define _APS_NEXT_RESOURCE_VALUE 521
#define _APS_NEXT_COMMAND_VALUE 59229
#define _APS_NEXT_CONTROL_VALUE 2386
#define _APS_NEXT_SYMED_VALUE 901
Deleted: trunk/OpenMPT/packageTemplate/default.mkb
===================================================================
--- trunk/OpenMPT/packageTemplate/default.mkb 2009-08-18 18:41:12 UTC (rev 331)
+++ trunk/OpenMPT/packageTemplate/default.mkb 2009-08-18 20:38:41 UTC (rev 332)
@@ -1,280 +0,0 @@
-//-------- OpenMPT key binding definition file -------
-//-Format is: -
-//- Context:Command ID:Modifiers:Key:KeypressEventType //Comments -
-//----------------------------------------------------------------------
-
-//----( Global Context (0) )------------
-0:1347:2:78:1 //File/New: Ctrl+N (KeyDown)
-0:1346:2:79:1 //File/Open: Ctrl+O (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)
-0:1375:0:27:1 //Stop Song: ESC (KeyDown)
-0:1029:0:117:1 //Play song from start: F6 (KeyDown)
-0:1027:0:118:5 //Play pattern from start: F7 (KeyDown|KeyHold)
-0:1026:2:118:5 //Play pattern from cursor: Ctrl+F7 (KeyDown|KeyHold)
-0:1376:0:120:1 //Toggle Midi Record: F9 (KeyDown)
-0:1359:2:90:1 //Undo: Ctrl+Z (KeyDown)
-0:1360:2:88:1 //Cut: Ctrl+X (KeyDown)
-0:1361:2:67:1 //Copy: Ctrl+C (KeyDown)
-0:1361:2:45:1 //Copy: Ctrl+INSERT (KeyDown)
-0:1362:2:86:1 //Paste: Ctrl+V (KeyDown)
-0:1362:1:45:1 //Paste: Shift+INSERT (KeyDown)
-0:1364:2:53:1 //SelectAll: Ctrl+5 (KeyDown)
-0:1365:2:70:1 //Find: Ctrl+F (KeyDown)
-0:1366:0:114:1 //Find Next: F3 (KeyDown)
-0:1021:4:71:1 //View General: Alt+G (KeyDown)
-0:1022:4:80:1 //View Pattern: Alt+P (KeyDown)
-0:1023:4:83:1 //View Samples: Alt+S (KeyDown)
-0:1024:4:78:1 //View Instruments: Alt+N (KeyDown)
-0:1025:1:120:1 //View Comments: Shift+F9 (KeyDown)
-0:1368:2:113:1 //Toggle Tree View: Ctrl+F2 (KeyDown)
-0:1369:2:112:1 //View Options: Ctrl+F1 (KeyDown)
-0:1370:0:112:1 //Help (to do): F1 (KeyDown)
-0:1032:2:111:5 //Previous instrument: Ctrl+NUM DIVIDE (KeyDown|KeyHold)
-0:1032:2:38:5 //Previous instrument: Ctrl+UP (KeyDown|KeyHold)
-0:1033:2:106:5 //Next instrument: Ctrl+NUMMULT (KeyDown|KeyHold)
-0:1033:2:40:5 //Next instrument: Ctrl+DOWN (KeyDown|KeyHold)
-0:1036:0:111:1 //Previous octave: NUM DIVIDE (KeyDown)
-0:1037:0:106:1 //Next octave: NUMMULT (KeyDown)
-0:1034:2:37:5 //Previous order: Ctrl+LEFT (KeyDown|KeyHold)
-0:1035:2:39:5 //Next order: Ctrl+RIGHT (KeyDown|KeyHold)
-
-//----( General Context [bottom] (1) )------------
-
-//----( Pattern Context [bottom] (2) )------------
-2:1017:0:34:5 //Jump down by measure: PGDOWN (KeyDown|KeyHold)
-2:1018:0:33:5 //Jump up by measure: PGUP (KeyDown|KeyHold)
-2:1338:4:34:5 //Jump down by beat: Alt+PGDOWN (KeyDown|KeyHold)
-2:1339:4:33:5 //Jump up by beat: Alt+PGUP (KeyDown|KeyHold)
-2:1340:6:34:5 //Snap down to beat: Ctrl+Alt+PGDOWN (KeyDown|KeyHold)
-2:1341:6:33:5 //Snap up to beat: Ctrl+Alt+PGUP (KeyDown|KeyHold)
-2:1038:0:40:5 //Navigate down by 1 row: DOWN (KeyDown|KeyHold)
-2:1039:0:38:5 //Navigate up by 1 row: UP (KeyDown|KeyHold)
-2:1691:4:40:5 //Navigate down by spacing: Alt+DOWN (KeyDown|KeyHold)
-2:1692:4:38:5 //Navigate up by spacing: Alt+UP (KeyDown|KeyHold)
-2:1040:0:37:5 //Navigate left: LEFT (KeyDown|KeyHold)
-2:1041:0:39:5 //Navigate right: RIGHT (KeyDown|KeyHold)
-2:1042:0:9:5 //Navigate to next channel: TAB (KeyDown|KeyHold)
-2:1043:1:9:5 //Navigate to previous channel: Shift+TAB (KeyDown|KeyHold)
-2:1044:0:36:1 //Go to first channel: HOME (KeyDown)
-2:1045:2:36:1 //Go to first row: Ctrl+HOME (KeyDown)
-2:1046:6:36:1 //Go to first row of first channel: Ctrl+Alt+HOME (KeyDown)
-2:1047:0:35:1 //Go to last channel: END (KeyDown)
-2:1048:2:35:1 //Go to last row: Ctrl+END (KeyDown)
-2:1049:6:35:1 //Go to last row of last channel: Ctrl+Alt+END (KeyDown)
-2:1050:1:16:1 //Selection key: Shift (KeyDown)
-2:1051:2:17:1 //Copy select key: Ctrl (KeyDown)
-2:1011:2:76:1 //Select channel / Select all: Ctrl+L (KeyDown)
-2:1663:0:122:1 //Toggle follow song: F11 (KeyDown)
-2:1003:0:13:5 //Quick copy: ENTER (KeyDown|KeyHold)
-2:1004:0:32:5 //Quick paste: SPACE (KeyDown|KeyHold)
-2:1001:2:32:1 //Enable recording: Ctrl+SPACE (KeyDown)
-2:1002:2:13:5 //Play row: Ctrl+ENTER (KeyDown|KeyHold)
-2:1317:4:18:1 //Set row jump on note entry: Alt (KeyDown)
-2:1685:2:9:1 //Switch to order list: Ctrl+TAB (KeyDown)
-2:1662:6:80:1 //Toggle channel's plugin editor: Ctrl+Alt+P (KeyDown)
-2:1062:0:93:1 //Show note properties: Application (KeyDown)
-2:1005:0:121:5 //Mute current channel: F10 (KeyDown|KeyHold)
-2:1006:2:121:5 //Solo current channel: Ctrl+F10 (KeyDown|KeyHold)
-2:1007:2:81:5 //Transpose +1: Ctrl+Q (KeyDown|KeyHold)
-2:1008:2:65:5 //Transpose -1: Ctrl+A (KeyDown|KeyHold)
-2:1009:3:81:5 //Transpose +12: Shift+Ctrl+Q (KeyDown|KeyHold)
-2:1010:3:65:5 //Transpose -12: Shift+Ctrl+A (KeyDown|KeyHold)
-2:1012:2:77:1 //Amplify selection: Ctrl+M (KeyDown)
-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:1058:0:46:1 //Clear field: DELETE (KeyDown)
-2:1664:1:190:1 //Clear field (IT Style): Shift+. (KeyDown)
-2:1059:2:46:1 //Clear row and step: Ctrl+DELETE (KeyDown)
-2:1665:1:46:5 //Clear field and step (IT Style): Shift+DELETE (KeyDown|KeyHold)
-2:1061:0:8:5 //Delete rows: BACKSPACE (KeyDown|KeyHold)
-2:1377:2:8:5 //Delete all rows: Ctrl+BACKSPACE (KeyDown|KeyHold)
-2:1378:0:45:1 //Insert Row: INSERT (KeyDown)
-2:1379:2:45:1 //Insert All Rows: Ctrl+INSERT (KeyDown)
-2:1055:0:109:5 //Previous pattern: NUM SUB (KeyDown|KeyHold)
-2:1054:0:107:5 //Next pattern: NUM PLUS (KeyDown|KeyHold)
-
-//----( Pattern Context [bottom] - Note Col (3) )------------
-3:1064:0:81:1 //Base octave C: Q (KeyDown)
-3:1065:0:87:1 //Base octave C#: W (KeyDown)
-3:1066:0:69:1 //Base octave D: E (KeyDown)
-3:1067:0:82:1 //Base octave D#: R (KeyDown)
-3:1068:0:84:1 //Base octave E: T (KeyDown)
-3:1069:0:89:1 //Base octave F: Y (KeyDown)
-3:1070:0:85:1 //Base octave F#: U (KeyDown)
-3:1071:0:73:1 //Base octave G: I (KeyDown)
-3:1072:0:79:1 //Base octave G#: O (KeyDown)
-3:1073:0:80:1 //Base octave +1 A: P (KeyDown)
-3:1074:0:219:1 //Base octave +1 A#: [ (KeyDown)
-3:1075:0:221:1 //Base octave +1 B: ] (KeyDown)
-3:1076:0:65:1 //Base octave +1 C: A (KeyDown)
-3:1077:0:83:1 //Base octave +1 C#: S (KeyDown)
-3:1078:0:68:1 //Base octave +1 D: D (KeyDown)
-3:1079:0:70:1 //Base octave +1 D#: F (KeyDown)
-3:1080:0:71:1 //Base octave +1 E: G (KeyDown)
-3:1081:0:72:1 //Base octave +1 F: H (KeyDown)
-3:1082:0:74:1 //Base octave +1 F#: J (KeyDown)
-3:1083:0:75:1 //Base octave +1 G: K (KeyDown)
-3:1084:0:76:1 //Base octave +1 G#: L (KeyDown)
-3:1085:0:186:1 //Base octave +2 A: ; (KeyDown)
-3:1086:0:222:1 //Base octave +2 A#: # (KeyDown)
-3:1087:0:220:1 //Base octave +2 B: \ (KeyDown)
-3:1088:0:90:1 //Base octave +2 C: Z (KeyDown)
-3:1089:0:88:1 //Base octave +2 C#: X (KeyDown)
-3:1090:0:67:1 //Base octave +2 D: C (KeyDown)
-3:1091:0:86:1 //Base octave +2 D#: V (KeyDown)
-3:1092:0:66:1 //Base octave +2 E: B (KeyDown)
-3:1093:0:78:1 //Base octave +2 F: N (KeyDown)
-3:1094:0:77:1 //Base octave +2 F#: M (KeyDown)
-3:1095:0:188:1 //Base octave +2 G: , (KeyDown)
-3:1096:0:190:1 //Base octave +2 G#: . (KeyDown)
-3:1097:0:191:1 //Base octave +3 A: / (KeyDown)
-3:1212:0:48:1 //Set octave 0: 0 (KeyDown)
-3:1212:0:96:1 //Set octave 0: NUM 0 (KeyDown)
-3:1213:0:49:1 //Set octave 1: 1 (KeyDown)
-3:1213:0:97:1 //Set octave 1: NUM 1 (KeyDown)
-3:1214:0:50:1 //Set octave 2: 2 (KeyDown)
-3:1214:0:98:1 //Set octave 2: NUM 2 (KeyDown)
-3:1215:0:51:1 //Set octave 3: 3 (KeyDown)
-3:1215:0:99:1 //Set octave 3: NUM 3 (KeyDown)
-3:1216:0:52:1 //Set octave 4: 4 (KeyDown)
-3:1216:0:100:1 //Set octave 4: NUM 4 (KeyDown)
-3:1217:0:53:1 //Set octave 5: 5 (KeyDown)
-3:1217:0:101:1 //Set octave 5: NUM 5 (KeyDown)
-3:1218:0:54:1 //Set octave 6: 6 (KeyDown)
-3:1218:0:102:1 //Set octave 6: NUM 6 (KeyDown)
-3:1219:0:55:1 //Set octave 7: 7 (KeyDown)
-3:1219:0:103:1 //Set octave 7: NUM 7 (KeyDown)
-3:1220:0:56:1 //Set octave 8: 8 (KeyDown)
-3:1220:0:104:1 //Set octave 8: NUM 8 (KeyDown)
-3:1221:0:57:1 //Set octave 9: 9 (KeyDown)
-3:1221:0:105:1 //Set octave 9: NUM 9 (KeyDown)
-3:1316:1:16:1 //Chord Modifier: Shift (KeyDown)
-3:1200:0:192:1 //Note cut: ' (KeyDown)
-3:1201:0:187:1 //Note off: = (KeyDown)
-
-//----( Pattern Context [bottom] - Ins Col (4) )------------
-4:1202:0:96:1 //Set instrument digit 0: NUM 0 (KeyDown)
-4:1202:0:48:1 //Set instrument digit 0: 0 (KeyDown)
-4:1203:0:97:1 //Set instrument digit 1: NUM 1 (KeyDown)
-4:1203:0:49:1 //Set instrument digit 1: 1 (KeyDown)
-4:1204:0:98:1 //Set instrument digit 2: NUM 2 (KeyDown)
-4:1204:0:50:1 //Set instrument digit 2: 2 (KeyDown)
-4:1205:0:99:1 //Set instrument digit 3: NUM 3 (KeyDown)
-4:1205:0:51:1 //Set instrument digit 3: 3 (KeyDown)
-4:1206:0:100:1 //Set instrument digit 4: NUM 4 (KeyDown)
-4:1206:0:52:1 //Set instrument digit 4: 4 (KeyDown)
-4:1207:0:101:1 //Set instrument digit 5: NUM 5 (KeyDown)
-4:1207:0:53:1 //Set instrument digit 5: 5 (KeyDown)
-4:1208:0:102:1 //Set instrument digit 6: NUM 6 (KeyDown)
-4:1208:0:54:1 //Set instrument digit 6: 6 (KeyDown)
-4:1209:0:103:1 //Set instrument digit 7: NUM 7 (KeyDown)
-4:1209:0:55:1 //Set instrument digit 7: 7 (KeyDown)
-4:1210:0:56:1 //Set instrument digit 8: 8 (KeyDown)
-4:1211:0:105:1 //Set instrument digit 9: NUM 9 (KeyDown)
-4:1211:0:57:1 //Set instrument digit 9: 9 (KeyDown)
-
-//----( Pattern Context [bottom] - Vol Col (5) )------------
-5:1222:0:48:1 //Set volume digit 0: 0 (KeyDown)
-5:1222:0:96:1 //Set volume digit 0: NUM 0 (KeyDown)
-5:1223:0:49:1 //Set volume digit 1: 1 (KeyDown)
-5:1223:0:97:1 //Set volume digit 1: NUM 1 (KeyDown)
-5:1224:0:50:1 //Set volume digit 2: 2 (KeyDown)
-5:1224:0:98:1 //Set volume digit 2: NUM 2 (KeyDown)
-5:1225:0:51:1 //Set volume digit 3: 3 (KeyDown)
-5:1225:0:99:1 //Set volume digit 3: NUM 3 (KeyDown)
-5:1226:0:52:1 //Set volume digit 4: 4 (KeyDown)
-5:1226:0:100:1 //Set volume digit 4: NUM 4 (KeyDown)
-5:1227:0:53:1 //Set volume digit 5: 5 (KeyDown)
-5:1227:0:101:1 //Set volume digit 5: NUM 5 (KeyDown)
-5:1228:0:54:1 //Set volume digit 6: 6 (KeyDown)
-5:1228:0:102:1 //Set volume digit 6: NUM 6 (KeyDown)
-5:1229:0:55:1 //Set volume digit 7: 7 (KeyDown)
-5:1229:0:103:1 //Set volume digit 7: NUM 7 (KeyDown)
-5:1230:0:56:1 //Set volume digit 8: 8 (KeyDown)
-5:1231:0:57:1 //Set volume digit 9: 9 (KeyDown)
-5:1231:0:105:1 //Set volume digit 9: NUM 9 (KeyDown)
-5:1232:0:86:1 //Vol command - volume: V (KeyDown)
-5:1233:0:80:1 //Vol command - pan: P (KeyDown)
-5:1234:0:67:1 //Vol command - vol slide up: C (KeyDown)
-5:1235:0:68:1 //Vol command - vol slide down: D (KeyDown)
-5:1236:0:65:1 //Vol command - vol fine slide up: A (KeyDown)
-5:1237:0:66:1 //Vol command - vol fine slide down: B (KeyDown)
-5:1238:0:85:1 //Vol command - vibrato speed: U (KeyDown)
-5:1239:0:72:1 //Vol command - vibrato: H (KeyDown)
-5:1240:0:76:1 //Vol command - XM pan left: L (KeyDown)
-5:1241:0:82:1 //Vol command - XM pan right: R (KeyDown)
-5:1242:0:71:1 //Vol command - Portamento: G (KeyDown)
-5:1243:0:70:1 //Vol command - Portamento Up: F (KeyDown)
-5:1244:0:69:1 //Vol command - Portamento Down: E (KeyDown)
-5:1245:1:186:1 //Vol command - Velocity: Shift+; (KeyDown)
-5:1246:0:79:1 //Vol command - Offset: O (KeyDown)
-
-//----( Pattern Context [bottom] - FX Col (6) )------------
-6:1294:0:220:1 //FX midi macro slide: \ (KeyDown)
-6:1295:1:186:1 //FX pseudo-velocity (experimental): Shift+; (KeyDown)
-
-//----( Pattern Context [bottom] - Param Col (7) )------------
-7:1247:0:48:1 //FX Param digit 0: 0 (KeyDown)
-7:1247:0:96:1 //FX Param digit 0: NUM 0 (KeyDown)
-7:1248:0:49:1 //FX Param digit 1: 1 (KeyDown)
-7:1248:0:97:1 //FX Param digit 1: NUM 1 (KeyDown)
-7:1249:0:50:1 //FX Param digit 2: 2 (KeyDown)
-7:1249:0:98:1 //FX Param digit 2: NUM 2 (KeyDown)
-7:1250:0:51:1 //FX Param digit 3: 3 (KeyDown)
-7:1250:0:99:1 //FX Param digit 3: NUM 3 (KeyDown)
-7:1251:0:52:1 //FX Param digit 4: 4 (KeyDown)
-7:1251:0:100:1 //FX Param digit 4: NUM 4 (KeyDown)
-7:1252:0:53:1 //FX Param digit 5: 5 (KeyDown)
-7:1252:0:101:1 //FX Param digit 5: NUM 5 (KeyDown)
-7:1253:0:54:1 //FX Param digit 6: 6 (KeyDown)
-7:1253:0:102:1 //FX Param digit 6: NUM 6 (KeyDown)
-7:1254:0:55:1 //FX Param digit 7: 7 (KeyDown)
-7:1254:0:103:1 //FX Param digit 7: NUM 7 (KeyDown)
-7:1255:0:56:1 //FX Param digit 8: 8 (KeyDown)
-7:1255:0:104:1 //FX Param digit 8: NUM 8 (KeyDown)
-7:1256:0:57:1 //FX Param digit 9: 9 (KeyDown)
-7:1256:0:105:1 //FX Param digit 9: NUM 9 (KeyDown)
-7:1257:0:65:1 //FX Param digit A: A (KeyDown)
-7:1258:0:66:1 //FX Param digit B: B (KeyDown)
-7:1259:0:67:1 //FX Param digit C: C (KeyDown)
-7:1260:0:68:1 //FX Param digit D: D (KeyDown)
-7:1261:0:69:1 //FX Param digit E: E (KeyDown)
-7:1262:0:70:1 //FX Param digit F: F (KeyDown)
-
-//----( Sample Context [bottom] (8) )------------
-8:1380:2:84:1 //Trim sample around loop points: Ctrl+T (KeyDown)
-8:1383:0:8:1 //Silence sample selection: BACKSPACE (KeyDown)
-8:1385:3:65:1 //Amplify Sample: Shift+Ctrl+A (KeyDown)
-8:1381:3:82:1 //Reverse sample: Shift+Ctrl+R (KeyDown)
-8:1382:0:46:1 //Delete sample selection: DELETE (KeyDown)
-8:1386:0:107:1 //Zoom Out: NUM PLUS (KeyDown)
-8:1387:0:109:1 //Zoom In: NUM SUB (KeyDown)
-
-//----( Instrument Context [bottom] (9) )------------
-
-//----( Comments Context [bottom] (10) )------------
-
-//----( Unknown Context (11) )------------
-
-//----( Unknown Context (12) )------------
-
-//----( Plugin GUI Context (13) )------------
-
-//----( General Context [top] (14) )------------
-
-//----( Pattern Context [top] (15) )------------
-
-//----( Sample Context [top] (16) )------------
-
-//----( Instrument Context [top] (17) )------------
-
-//----( Comments Context [top] (18) )------------
-
-//----( Unknown Context (19) )------------
Modified: trunk/OpenMPT/soundlib/Load_it.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_it.cpp 2009-08-18 18:41:12 UTC (rev 331)
+++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-08-18 20:38:41 UTC (rev 332)
@@ -161,12 +161,12 @@
if(csf.Instruments[i]->pTuning)
continue;
- csf.Instruments[i]->pTuning = csf.GetStandardTunings().GetTuning(str);
+ csf.Instruments[i]->pTuning = csf.GetBuiltInTunings().GetTuning(str);
if(csf.Instruments[i]->pTuning)
continue;
- if(str == "TET12" && csf.GetStandardTunings().GetNumTunings() > 0)
- csf.Instruments[i]->pTuning = &csf.GetStandardTunings().GetTuning(0);
+ if(str == "TET12" && csf.GetBuiltInTunings().GetNumTunings() > 0)
+ csf.Instruments[i]->pTuning = &csf.GetBuiltInTunings().GetTuning(0);
if(csf.Instruments[i]->pTuning)
continue;
Modified: trunk/OpenMPT/soundlib/Sndfile.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-08-18 18:41:12 UTC (rev 331)
+++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-08-18 20:38:41 UTC (rev 332)
@@ -390,7 +390,7 @@
//////////////////////////////////////////////////////////
// CSoundFile
-CTuningCollection* CSoundFile::s_pTuningsSharedStandard(0);
+CTuningCollection* CSoundFile::s_pTuningsSharedBuiltIn(0);
CTuningCollection* CSoundFile::s_pTuningsSharedLocal(0);
uint8 CSoundFile::s_DefaultPlugVolumeHandling = PLUGIN_VOLUMEHANDLING_IGNORE;
@@ -2839,7 +2839,7 @@
//---------------------------------
{
delete s_pTuningsSharedLocal; s_pTuningsSharedLocal = 0;
- delete s_pTuningsSharedStandard; s_pTuningsSharedStandard = 0;
+ delete s_pTuningsSharedBuiltIn; s_pTuningsSharedBuiltIn = 0;
}
bool CSoundFile::SaveStaticTunings()
@@ -2862,42 +2862,45 @@
bool CSoundFile::LoadStaticTunings()
//-----------------------------------
{
- if(s_pTuningsSharedLocal || s_pTuningsSharedStandard) return true;
+ if(s_pTuningsSharedLocal || s_pTuningsSharedBuiltIn) return true;
//For now not allowing to reload tunings(one should be careful when reloading them
//since various parts may use addresses of the tuningobjects).
CTuning::MessageHandler = &SimpleMessageBox;
-
- s_pTuningsSharedStandard = new CTuningCollection("Standard tunings");
+
+ s_pTuningsSharedBuiltIn = new CTuningCollection;
s_pTuningsSharedLocal = new CTuningCollection("Local tunings");
- const string exeDir = CMainFrame::m_csExecutableDirectoryPath;
- const string baseDirectoryName = exeDir + "tunings\\";
- string filenameBase;
- string filename;
-
- s_pTuningsSharedStandard->SetSavefilePath(baseDirectoryName + string("standard\\std_tunings") + CTuningCollection::s_FileExtension);
- s_pTuningsSharedLocal->SetSavefilePath(baseDirectoryName + string("local_tunings") + CTuningCollection::s_FileExtension);
-
- s_pTuningsSharedStandard->Deserialize();
- s_pTuningsSharedLocal->Deserialize();
-
- //This condition should not be true.
- if(s_pTuningsSharedStandard->GetNumTunings() == 0)
+ // Load built-in tunings.
+ const char* pData = nullptr;
+ HGLOBAL hglob = nullptr;
+ size_t nSize = 0;
+ if (LoadResource(MAKEINTRESOURCE(IDR_BUILTIN_TUNINGS), TEXT("TUNING"), pData, nSize, hglob) != nullptr)
{
+ std::istrstream iStrm(pData, nSize);
+ s_pTuningsSharedBuiltIn->Deserialize(iStrm);
+ FreeResource(hglob);
+ }
+ if(s_pTuningsSharedBuiltIn->GetNumTunings() == 0)
+ {
+ ASSERT(false);
CTuningRTI* pT = new CTuningRTI;
//Note: Tuning collection class handles deleting.
pT->CreateGeometric(1,1);
- if(s_pTuningsSharedStandard->AddTuning(pT))
+ if(s_pTuningsSharedBuiltIn->AddTuning(pT))
delete pT;
}
+
+ // Load local tunings.
+ s_pTuningsSharedLocal->SetSavefilePath(std::string(CMainFrame::m_csExecutableDirectoryPath + "tunings\\local_tunings" + CTuningCollection::s_FileExtension.c_str()));
+ s_pTuningsSharedLocal->Deserialize();
- //Enabling adding/removing of tunings for standard collection
- //only for debug builds.
+ // Enabling adding/removing of tunings for standard collection
+ // only for debug builds.
#ifdef DEBUG
- s_pTuningsSharedStandard->SetConstStatus(CTuningCollection::EM_ALLOWALL);
+ s_pTuningsSharedBuiltIn->SetConstStatus(CTuningCollection::EM_ALLOWALL);
#else
- s_pTuningsSharedStandard->SetConstStatus(CTuningCollection::EM_CONST);
+ s_pTuningsSharedBuiltIn->SetConstStatus(CTuningCollection::EM_CONST);
#endif
MODINSTRUMENT::s_DefaultTuning = NULL;
Modified: trunk/OpenMPT/soundlib/Sndfile.h
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.h 2009-08-18 18:41:12 UTC (rev 331)
+++ trunk/OpenMPT/soundlib/Sndfile.h 2009-08-18 20:38:41 UTC (rev 332)
@@ -835,14 +835,14 @@
static bool LoadStaticTunings();
static bool SaveStaticTunings();
static void DeleteStaticdata();
- static CTuningCollection& GetStandardTunings() {return *s_pTuningsSharedStandard;}
+ static CTuningCollection& GetBuiltInTunings() {return *s_pTuningsSharedBuiltIn;}
static CTuningCollection& GetLocalTunings() {return *s_pTuningsSharedLocal;}
CTuningCollection& GetTuneSpecificTunings() {return *m_pTuningsTuneSpecific;}
std::string GetNoteName(const int16&, const int inst = -1) const;
private:
CTuningCollection* m_pTuningsTuneSpecific;
- static CTuningCollection* s_pTuningsSharedStandard;
+ static CTuningCollection* s_pTuningsSharedBuiltIn;
static CTuningCollection* s_pTuningsSharedLocal;
//<--Tuning
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-08-18 18:41:23
|
Revision: 331
http://modplug.svn.sourceforge.net/modplug/?rev=331&view=rev
Author: saga-games
Date: 2009-08-18 18:41:12 +0000 (Tue, 18 Aug 2009)
Log Message:
-----------
[New] Pattern editor: Multiple orders can be selected in the pattern sequence. At the moment, it is possible to insert, delete, duplicate and dragondrop multiple orders.
[Ref] Redesigned a few functions and stuff to make this new feature work; Replace UINT/DWORD/whatever by ORDERINDEX/PATTERNINDEX and BOOL by bool where appropriate
[Fix] Moving orders (when duplicating them) should be aware of the max. possible order now.
[Fix] 669 Loader: Small modification so corehop.669 can be loaded; Note: Loader is still buggy like hell
[Imp] Added tests for bitshifting version numbers
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Ctrl_pat.cpp
trunk/OpenMPT/mptrack/Ctrl_pat.h
trunk/OpenMPT/mptrack/Ctrl_seq.cpp
trunk/OpenMPT/mptrack/Moddoc.h
trunk/OpenMPT/mptrack/Modedit.cpp
trunk/OpenMPT/mptrack/View_tre.cpp
trunk/OpenMPT/mptrack/test/test.cpp
trunk/OpenMPT/mptrack/typedefs.h
trunk/OpenMPT/soundlib/Load_669.cpp
trunk/OpenMPT/soundlib/Sndmix.cpp
Modified: trunk/OpenMPT/mptrack/Ctrl_pat.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2009-08-16 22:47:01 UTC (rev 330)
+++ trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2009-08-18 18:41:12 UTC (rev 331)
@@ -408,7 +408,7 @@
case CTRLMSG_SETCURRENTORDER:
//Set orderlist selection and refresh GUI if change successful
- m_OrderList.SetCurSel(lParam, FALSE);
+ m_OrderList.SetCurSel((ORDERINDEX)lParam, FALSE);
break;
case CTRLMSG_FORCEREFRESH:
@@ -417,7 +417,7 @@
break;
case CTRLMSG_GETCURRENTORDER:
- return m_OrderList.GetCurSel();
+ return m_OrderList.GetCurSel(true).nOrdLo;
case CTRLMSG_SETCURRENTINSTRUMENT:
case CTRLMSG_PAT_SETINSTRUMENT:
@@ -472,11 +472,11 @@
break;
case CTRLMSG_PREVORDER:
- m_OrderList.SetCurSel(m_OrderList.GetCurSel()-1, TRUE);
+ m_OrderList.SetCurSel(m_OrderList.GetCurSel(true).nOrdLo - 1, TRUE);
break;
case CTRLMSG_NEXTORDER:
- m_OrderList.SetCurSel(m_OrderList.GetCurSel()+1, TRUE);
+ m_OrderList.SetCurSel(m_OrderList.GetCurSel(true).nOrdLo + 1, TRUE);
break;
//rewbs.customKeys
@@ -582,7 +582,7 @@
{
if (pSndFile)
{
- for (UINT i=0; i<pSndFile->Order.size(); i++)
+ for (ORDERINDEX i=0; i<pSndFile->Order.size(); i++)
{
if (pSndFile->Order[i] == (UINT)lParam)
{
@@ -599,7 +599,7 @@
if (pSndFile)
{
lParam &= 0x7FFF;
- m_OrderList.SetCurSel(lParam);
+ m_OrderList.SetCurSel((ORDERINDEX)lParam);
SetCurrentPattern(pSndFile->Order[lParam]);
}
}
@@ -652,7 +652,7 @@
void CCtrlPatterns::OnSequencePrev()
//----------------------------------
{
- m_OrderList.SetCurSel(m_OrderList.GetCurSel()-1);
+ m_OrderList.SetCurSel(m_OrderList.GetCurSel(true).nOrdLo - 1);
m_OrderList.SetFocus();
}
@@ -660,7 +660,7 @@
void CCtrlPatterns::OnSequenceNext()
//----------------------------------
{
- m_OrderList.SetCurSel(m_OrderList.GetCurSel()+1);
+ m_OrderList.SetCurSel(m_OrderList.GetCurSel(true).nOrdLo + 1);
m_OrderList.SetFocus();
}
@@ -844,18 +844,18 @@
if (m_pModDoc)
{
CSoundFile *pSndFile = m_pModDoc->GetSoundFile();
- UINT nCurOrd = m_OrderList.GetCurSel();
- UINT pat = pSndFile->Order[nCurOrd];
- UINT rows = 64;
+ ORDERINDEX nCurOrd = m_OrderList.GetCurSel(true).nOrdLo;
+ PATTERNINDEX pat = pSndFile->Order[nCurOrd];
+ ROWINDEX rows = 64;
if ((pat < pSndFile->Patterns.Size()) && (pSndFile->Patterns[pat]) && (pSndFile->m_nType & (MOD_TYPE_XM|MOD_TYPE_IT|MOD_TYPE_MPT)))
{
rows = pSndFile->PatternSize[pat];
if (rows < 32) rows = 32;
}
- LONG nNewPat = m_pModDoc->InsertPattern(nCurOrd+1, rows);
+ PATTERNINDEX nNewPat = m_pModDoc->InsertPattern(nCurOrd + 1, rows);
if ((nNewPat >= 0) && (nNewPat < pSndFile->Patterns.Size()))
{
- m_OrderList.SetCurSel(nCurOrd+1);
+ m_OrderList.SetCurSel(nCurOrd + 1);
m_OrderList.InvalidateRect(NULL, FALSE);
SetCurrentPattern(nNewPat);
m_pModDoc->SetModified();
@@ -869,35 +869,67 @@
void CCtrlPatterns::OnPatternDuplicate()
//--------------------------------------
{
+ // duplicates one or more patterns.
if (m_pModDoc)
{
CSoundFile *pSndFile = m_pModDoc->GetSoundFile();
- UINT nCurOrd = m_OrderList.GetCurSel();
- UINT nCurPat = pSndFile->Order[nCurOrd];
- UINT rows = 64;
- if (nCurPat < pSndFile->Patterns.Size())
+ ORD_SELECTION selection = m_OrderList.GetCurSel(false);
+ ORDERINDEX nInsertCount = selection.nOrdHi - selection.nOrdLo;
+ ORDERINDEX nInsertWhere = selection.nOrdLo + nInsertCount + 1;
+ bool bSuccess = false;
+ // has this pattern been duplicated already? (for multiselect)
+ PATTERNINDEX pReplaceIndex[MAX_PATTERNS]; // TODO I think this is a bit much...
+ memset(&pReplaceIndex, PATTERNINDEX_INVALID, sizeof(PATTERNINDEX) * MAX_PATTERNS);
+
+ for(ORDERINDEX i = 0; i <= nInsertCount; i++)
{
- if ((pSndFile->Patterns[nCurPat]) && (pSndFile->m_nType & (MOD_TYPE_XM|MOD_TYPE_IT|MOD_TYPE_MPT)))
+ PATTERNINDEX nCurPat = pSndFile->Order[selection.nOrdLo + i];
+ ROWINDEX rows = 64;
+ if (nCurPat < pSndFile->Patterns.Size() && pReplaceIndex[nCurPat] == PATTERNINDEX_INVALID)
{
- rows = pSndFile->PatternSize[nCurPat];
- if (rows < pSndFile->GetModSpecifications().patternRowsMin) rows = pSndFile->GetModSpecifications().patternRowsMin;
+ if ((pSndFile->Patterns[nCurPat]) && (pSndFile->m_nType & (MOD_TYPE_XM|MOD_TYPE_IT|MOD_TYPE_MPT)))
+ {
+ rows = pSndFile->PatternSize[nCurPat];
+ if (rows < pSndFile->GetModSpecifications().patternRowsMin) rows = pSndFile->GetModSpecifications().patternRowsMin;
+ }
+ PATTERNINDEX nNewPat = m_pModDoc->InsertPattern(nInsertWhere + i, rows);
+ if ((nNewPat >= 0) && (nNewPat < pSndFile->Patterns.Size()))
+ {
+ MODCOMMAND *pSrc = pSndFile->Patterns[nCurPat];
+ MODCOMMAND *pDest = pSndFile->Patterns[nNewPat];
+ UINT n = pSndFile->PatternSize[nCurPat];
+ if (pSndFile->PatternSize[nNewPat] < n) n = pSndFile->PatternSize[nNewPat];
+ n *= pSndFile->m_nChannels;
+ if (n) memcpy(pDest, pSrc, n * sizeof(MODCOMMAND));
+ bSuccess = true;
+ pReplaceIndex[nCurPat] = nNewPat; // mark as duplicated
+ }
+ else
+ {
+ break;
+ }
}
- LONG nNewPat = m_pModDoc->InsertPattern(nCurOrd+1, rows);
- if ((nNewPat >= 0) && (nNewPat < pSndFile->Patterns.Size()))
+ else
{
- MODCOMMAND *pSrc = pSndFile->Patterns[nCurPat];
- MODCOMMAND *pDest = pSndFile->Patterns[nNewPat];
- UINT n = pSndFile->PatternSize[nCurPat];
- if (pSndFile->PatternSize[nNewPat] < n) n = pSndFile->PatternSize[nNewPat];
- n *= pSndFile->m_nChannels;
- if (n) memcpy(pDest, pSrc, n * sizeof(MODCOMMAND));
- m_OrderList.SetCurSel(nCurOrd+1);
- m_OrderList.InvalidateRect(NULL, FALSE);
- SetCurrentPattern(nNewPat);
- m_pModDoc->SetModified();
- m_pModDoc->UpdateAllViews(NULL, HINT_MODSEQUENCE|HINT_PATNAMES, this);
+ // invalid pattern, or it has been duplicated before (multiselect)
+ for (int j = pSndFile->Order.size() - 1; j > selection.nOrdLo + i + nInsertCount + 1; j--) pSndFile->Order[j] = pSndFile->Order[j - 1];
+ PATTERNINDEX nNewPat;
+ if(nCurPat < pSndFile->Patterns.Size() && pReplaceIndex[nCurPat] != PATTERNINDEX_INVALID)
+ nNewPat = pReplaceIndex[nCurPat]; // take care of patterns that have been duplicated before
+ else
+ nNewPat= pSndFile->Order[selection.nOrdLo + i];
+ pSndFile->Order[selection.nOrdLo + i + nInsertCount + 1] = nNewPat;
}
}
+ if(bSuccess)
+ {
+ m_OrderList.InvalidateRect(NULL, FALSE);
+ m_OrderList.SetCurSel(nInsertWhere);
+ SetCurrentPattern(pSndFile->Order[nInsertWhere]);
+ m_pModDoc->SetModified();
+ m_pModDoc->UpdateAllViews(NULL, HINT_MODSEQUENCE|HINT_PATNAMES, this);
+ if(selection.nOrdHi != selection.nOrdLo) m_OrderList.m_nScrollPos2nd = nInsertWhere + nInsertCount;
+ }
}
SwitchToView();
}
Modified: trunk/OpenMPT/mptrack/Ctrl_pat.h
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_pat.h 2009-08-16 22:47:01 UTC (rev 330)
+++ trunk/OpenMPT/mptrack/Ctrl_pat.h 2009-08-18 18:41:12 UTC (rev 331)
@@ -5,6 +5,12 @@
class COrderList;
class CCtrlPatterns;
+struct ORD_SELECTION
+{
+ ORDERINDEX nOrdLo;
+ ORDERINDEX nOrdHi;
+};
+
//===========================
class COrderList: public CWnd
//===========================
@@ -13,14 +19,17 @@
protected:
HFONT m_hFont;
COLORREF colorText, colorTextSel;
- //m_nXScroll : The order at the beginning of shown orderlist?
- //m_nScrollPos: The same as order?
- int m_cxFont, m_cyFont, m_nXScroll, m_nScrollPos, m_nDropPos;
+ int m_cxFont, m_cyFont;
+ //m_nXScroll : The order at the beginning of shown orderlist
+ //m_nScrollPos: The same as order
+ //m_nScrollPos2nd: 2nd selection point if multiple orders are selected
+ // (not neccessarily the higher order - GetCurSel() is taking care of that.)
+ ORDERINDEX m_nXScroll, m_nScrollPos, m_nScrollPos2nd, m_nDropPos;
+ bool m_bScrolling, m_bDragging, m_bShift;
+ ORDERINDEX m_nDragOrder;
//To tell how many orders('orderboxes') to show at least
//on both sides of current order(when updating orderslist position).
BYTE m_nOrderlistMargins;
- UINT m_nDragOrder;
- BOOL m_bScrolling, m_bDragging, m_bShift;
CModDoc *m_pModDoc;
CCtrlPatterns *m_pParent;
@@ -33,9 +42,9 @@
public:
BOOL Init(const CRect&, CCtrlPatterns *pParent, CModDoc *, HFONT hFont);
void InvalidateSelection() const;
- int GetCurSel() const { return m_nScrollPos; }
UINT GetCurrentPattern() const;
- BOOL SetCurSel(int sel, BOOL bEdit=TRUE);
+ ORD_SELECTION GetCurSel(bool bIgnoreSelection) const;
+ bool SetCurSel(ORDERINDEX sel, bool bEdit = true, bool bShiftClick = false);
BOOL ProcessKeyDown(UINT nChar);
BOOL ProcessChar(UINT nChar);
BOOL UpdateScrollInfo();
Modified: trunk/OpenMPT/mptrack/Ctrl_seq.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2009-08-16 22:47:01 UTC (rev 330)
+++ trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2009-08-18 18:41:12 UTC (rev 331)
@@ -5,7 +5,6 @@
#include "globals.h"
#include "ctrl_pat.h"
#include "view_pat.h"
-#include ".\ctrl_pat.h"
//////////////////////////////////////////////////////////////
// CPatEdit
@@ -75,14 +74,15 @@
//----------------------
{
m_hFont = NULL;
- m_pParent = NULL;
+ m_pParent = nullptr;
m_cxFont = m_cyFont = 0;
- m_pModDoc = NULL;
+ m_pModDoc = nullptr;
m_nScrollPos = m_nXScroll = 0;
+ m_nScrollPos2nd = ORDERINDEX_INVALID;
m_nOrderlistMargins = s_nDefaultMargins;
- m_bScrolling = FALSE;
- m_bDragging = FALSE;
- m_bShift = FALSE;
+ m_bScrolling = false;
+ m_bDragging = false;
+ m_bShift = false;
}
@@ -159,11 +159,27 @@
void COrderList::InvalidateSelection() const
//------------------------------------------
{
+ ORDERINDEX nOrdLo = m_nScrollPos, nCount = 1;
+ static ORDERINDEX m_nScrollPos2Old = m_nScrollPos2nd;
+ if(m_nScrollPos2Old != ORDERINDEX_INVALID)
+ {
+ // there were multiple orders selected - remove them all
+ ORDERINDEX nOrdHi = m_nScrollPos;
+ if(m_nScrollPos2Old < m_nScrollPos)
+ {
+ nOrdLo = m_nScrollPos2Old;
+ } else
+ {
+ nOrdHi = m_nScrollPos2Old;
+ }
+ nCount = nOrdHi - nOrdLo + 1;
+ }
+ m_nScrollPos2Old = m_nScrollPos2nd;
CRect rcClient, rect;
GetClientRect(&rcClient);
- rect.left = rcClient.left + (m_nScrollPos - m_nXScroll) * m_cxFont;
+ rect.left = rcClient.left + (nOrdLo - m_nXScroll) * m_cxFont;
rect.top = rcClient.top;
- rect.right = rect.left + m_cxFont;
+ rect.right = rect.left + m_cxFont * nCount;
rect.bottom = rcClient.bottom;
if (rect.right > rcClient.right) rect.right = rcClient.right;
if (rect.left < rcClient.left) rect.left = rcClient.left;
@@ -186,34 +202,51 @@
}
-BOOL COrderList::SetCurSel(int sel, BOOL bEdit)
-//---------------------------------------------
+ORD_SELECTION COrderList::GetCurSel(bool bIgnoreSelection) const
+//--------------------------------------------------------------
{
+ // returns the currently selected order(s)
+ ORD_SELECTION result;
+ result.nOrdLo = result.nOrdHi = m_nScrollPos;
+ // bIgnoreSelection: true if only first selection marker is important.
+ if(!bIgnoreSelection && m_nScrollPos2nd != ORDERINDEX_INVALID) {
+ if(m_nScrollPos2nd < m_nScrollPos) // ord2 < ord1
+ result.nOrdLo = m_nScrollPos2nd;
+ else
+ result.nOrdHi = m_nScrollPos2nd;
+ }
+ return result;
+}
+
+bool COrderList::SetCurSel(ORDERINDEX sel, bool bEdit, bool bShiftClick)
+//----------------------------------------------------------------------
+{
CMainFrame *pMainFrm = CMainFrame::GetMainFrame();
CSoundFile *pSndFile = m_pModDoc->GetSoundFile();
+ ORDERINDEX *nOrder = (bShiftClick) ? &m_nScrollPos2nd : &m_nScrollPos;
- if ((sel < 0) || (sel >= int(pSndFile->Order.size())) || (!m_pParent) || (!pMainFrm)) return FALSE;
- if (sel == m_nScrollPos) return TRUE;
+ if ((sel < 0) || (sel >= int(pSndFile->Order.size())) || (!m_pParent) || (!pMainFrm)) return false;
+ if (sel == *nOrder) return true;
const BYTE nShownLength = GetLength();
InvalidateSelection();
- m_nScrollPos = sel;
+ *nOrder = sel;
if (!m_bScrolling)
{
const BYTE nMargins = GetMargins(GetMarginsMax(nShownLength));
- if ((m_nScrollPos < m_nXScroll + nMargins) || (!m_cxFont) || (!m_cyFont))
+ if ((*nOrder < m_nXScroll + nMargins) || (!m_cxFont) || (!m_cyFont))
{ // Must move first shown sequence item to left in order to show
// the new active order.
- m_nXScroll = max(0, m_nScrollPos - nMargins);
+ m_nXScroll = max(0, *nOrder - nMargins);
SetScrollPos(SB_HORZ, m_nXScroll);
InvalidateRect(NULL, FALSE);
} else
{
- int maxsel = nShownLength;
+ ORDERINDEX maxsel = nShownLength;
if (maxsel) maxsel--;
- if (m_nScrollPos - m_nXScroll >= maxsel - nMargins)
+ if (*nOrder - m_nXScroll >= maxsel - nMargins)
{ // Must move first shown sequence item to right in order to show
// the new active order.
- m_nXScroll = m_nScrollPos - (maxsel - nMargins);
+ m_nXScroll = *nOrder - (maxsel - nMargins);
SetScrollPos(SB_HORZ, m_nXScroll);
InvalidateRect(NULL, FALSE);
}
@@ -223,7 +256,7 @@
if ((m_pParent) && (m_pModDoc) && (bEdit))
{
UINT n = pSndFile->Order[m_nScrollPos];
- if ((n < pSndFile->Patterns.Size()) && (pSndFile->Patterns[n]))
+ if ((n < pSndFile->Patterns.Size()) && (pSndFile->Patterns[n]) && !bShiftClick)
{
BOOL bIsPlaying = (pMainFrm->GetModPlaying() == m_pModDoc);
if ((bIsPlaying) && (pSndFile->m_dwSongFlags & SONG_PATTERNLOOP))
@@ -251,7 +284,8 @@
}
}
UpdateInfoText();
- return TRUE;
+ if(m_nScrollPos == m_nScrollPos2nd) m_nScrollPos2nd = ORDERINDEX_INVALID;
+ return true;
}
@@ -273,15 +307,15 @@
switch(nChar)
{
case VK_UP:
- case VK_LEFT: SetCurSel(m_nScrollPos-1); break;
+ case VK_LEFT: SetCurSel(m_nScrollPos - 1); break;
case VK_DOWN:
- case VK_RIGHT: SetCurSel(m_nScrollPos+1); break;
+ case VK_RIGHT: SetCurSel(m_nScrollPos + 1); break;
case VK_HOME: SetCurSel(0); break;
case VK_END:
if (m_pModDoc)
{
CSoundFile *pSndFile = m_pModDoc->GetSoundFile();
- int i = 0;
+ ORDERINDEX i = 0;
const int nSeqLength = pSndFile->Order.size();
for (i=0; i+1 < nSeqLength; i++) if (pSndFile->Order[i+1] == pSndFile->Order.GetInvalidPatIndex()) break;
SetCurSel(i);
@@ -492,12 +526,14 @@
CSoundFile *pSndFile = m_pModDoc->GetSoundFile();
GetClientRect(&rcClient);
rect = rcClient;
- int nIndex = m_nXScroll;
+ ORDERINDEX nIndex = m_nXScroll;
+ ORD_SELECTION selection = GetCurSel(false);
+
//Scrolling the shown orders(the showns rectangles)?
while (rect.left < rcClient.right)
{
- BOOL bHighLight = ((bFocus) && (nIndex == m_nScrollPos)) ? TRUE : FALSE;
- int nOrder = ((nIndex >= 0) && (nIndex < int(pSndFile->Order.size()))) ? pSndFile->Order[nIndex] : -1;
+ bool bHighLight = ((bFocus) && (nIndex >= selection.nOrdLo && nIndex <= selection.nOrdHi)) ? true : false;
+ ORDERINDEX nOrder = ((nIndex >= 0) && (nIndex < int(pSndFile->Order.size()))) ? pSndFile->Order[nIndex] : -1;
if ((rect.right = rect.left + m_cxFont) > rcClient.right) rect.right = rcClient.right;
rect.right--;
if (bHighLight) {
@@ -586,10 +622,12 @@
if (ih->CtrlPressed())
{
+ // queue pattern
+ //m_nScrollPos2nd = ORDERINDEX_INVALID;
if (m_pModDoc)
{
CSoundFile *pSndFile = m_pModDoc->GetSoundFile();
- int nOrder = m_nXScroll + (pt.x - rect.left) / m_cxFont;
+ ORDERINDEX nOrder = m_nXScroll + (pt.x - rect.left) / m_cxFont;
if ((nOrder >= 0) && (nOrder < int(pSndFile->Order.size())))
{
if (pSndFile->m_nSeqOverride == static_cast<UINT>(nOrder)+1) {
@@ -602,12 +640,22 @@
}
} else
{
+ // mark pattern (+skip to)
const int oldXScroll = m_nXScroll;
- SetCurSel(m_nXScroll + (pt.x - rect.left) / m_cxFont);
- m_bDragging = IsOrderInMargins(m_nScrollPos, oldXScroll) ? FALSE : TRUE;
- if(m_bDragging == TRUE)
+
+ ORDERINDEX nOrder = m_nXScroll + (pt.x - rect.left) / m_cxFont;
+ ORD_SELECTION selection = GetCurSel(false);
+
+ // check if cursor is in selection - if it is, only react on MouseUp as the user might want to drag those orders
+ if(m_nScrollPos2nd == ORDERINDEX_INVALID || nOrder < selection.nOrdLo || nOrder > selection.nOrdHi)
{
- m_nDragOrder = GetCurSel();
+ m_nScrollPos2nd = ORDERINDEX_INVALID;
+ SetCurSel(nOrder, true, ih->ShiftPressed());
+ }
+ m_bDragging = IsOrderInMargins(m_nScrollPos, oldXScroll) ? false : true;
+ if(m_bDragging == true)
+ {
+ m_nDragOrder = GetCurSel(true).nOrdLo;
m_nDropPos = m_nDragOrder;
SetCapture();
}
@@ -622,25 +670,68 @@
void COrderList::OnLButtonUp(UINT nFlags, CPoint pt)
//--------------------------------------------------
{
+ CRect rect;
+ GetClientRect(&rect);
+
if (m_bDragging)
{
- CRect rect;
-
- m_bDragging = FALSE;
+ m_bDragging = false;
ReleaseCapture();
- GetClientRect(&rect);
if (rect.PtInRect(pt))
{
int n = m_nXScroll + (pt.x - rect.left) / m_cxFont;
if ((n >= 0) && (n == m_nDropPos) && (m_pModDoc))
{
- if (m_nDragOrder == (UINT)m_nDropPos) return;
- if (m_pModDoc->MoveOrder(m_nDragOrder, m_nDropPos, TRUE, m_bShift))
+ // drag multiple orders (not quite as easy...)
+ ORD_SELECTION selection = GetCurSel(false);
+ // move how many orders from where?
+ ORDERINDEX nMoveCount = (selection.nOrdHi - selection.nOrdLo), nMovePos = selection.nOrdLo;
+ // drop before or after the selection
+ bool bMoveBack = !(m_nDragOrder < (UINT)m_nDropPos);
+ // don't do anything if drop position is inside the selection
+ if(m_nDropPos >= selection.nOrdLo && m_nDropPos <= selection.nOrdHi) return;
+ // drag or order or multiple orders?
+ bool bMultiSelection = (selection.nOrdLo != selection.nOrdHi);
+
+ for(int i = 0; i <= nMoveCount; i++)
{
- SetCurSel(((m_nDragOrder < (UINT)m_nDropPos) && (!m_bShift)) ? m_nDropPos-1 : m_nDropPos);
- m_pModDoc->SetModified();
+ if(!m_pModDoc->MoveOrder(nMovePos, m_nDropPos, true, m_bShift)) return;
+ if((bMoveBack ^ m_bShift) == true && bMultiSelection)
+ {
+ nMovePos++;
+ m_nDropPos++;
+ }
+ if(bMoveBack && m_bShift && bMultiSelection) {
+ nMovePos += 2;
+ m_nDropPos++;
+ }
}
+ if(bMultiSelection)
+ {
+ // adjust selection
+ m_nScrollPos2nd = m_nDropPos - 1;
+ m_nDropPos -= nMoveCount + (bMoveBack ? 0 : 1);
+ SetCurSel((bMoveBack && (!m_bShift)) ? m_nDropPos - 1 : m_nDropPos);
+ } else
+ {
+ SetCurSel(((m_nDragOrder < (UINT)m_nDropPos) && (!m_bShift)) ? m_nDropPos - 1 : m_nDropPos);
+ }
+ m_pModDoc->SetModified();
}
+ else
+ {
+ ORDERINDEX nOrder = m_nXScroll + (pt.x - rect.left) / m_cxFont;
+ ORD_SELECTION selection = GetCurSel(false);
+
+ // this should actually have equal signs but that breaks multiselect: nOrder >= selection.nOrdLo && nOrder <= section.nOrdHi
+ if (pt.y < rect.bottom && m_nScrollPos2nd != ORDERINDEX_INVALID && nOrder > selection.nOrdLo && nOrder < selection.nOrdHi)
+ {
+ // Remove selection if we didn't drag anything but multiselect was active
+ m_nScrollPos2nd = ORDERINDEX_INVALID;
+ SetFocus();
+ SetCurSel(m_nXScroll + (pt.x - rect.left) / m_cxFont);
+ }
+ }
}
InvalidateRect(NULL, FALSE);
} else
@@ -658,11 +749,12 @@
CRect rect;
GetClientRect(&rect);
- int n = -1;
+ ORDERINDEX n = ORDERINDEX_INVALID;
if (rect.PtInRect(pt))
{
+ CSoundFile *pSndFile = m_pModDoc->GetSoundFile();
n = m_nXScroll + (pt.x - rect.left) / m_cxFont;
- if ((n < 0) || (n >= int(m_pModDoc->GetSoundFile()->Order.size()))) n = -1;
+ if (n >= int(pSndFile->Order.size()) || n >= pSndFile->GetModSpecifications().ordersMax) n = ORDERINDEX_INVALID;
}
if (n != (int)m_nDropPos)
{
@@ -673,7 +765,7 @@
SetCursor(CMainFrame::curDragging);
} else
{
- m_nDropPos = -1;
+ m_nDropPos = ORDERINDEX_INVALID;
SetCursor(CMainFrame::curNoDrop);
}
}
@@ -691,39 +783,59 @@
GetClientRect(&rect);
if (m_bDragging)
{
- m_nDropPos = -1;
+ m_nDropPos = ORDERINDEX_INVALID;
OnLButtonUp(nFlags, pt);
}
- if (pt.y < rect.bottom)
+ if (pt.y >= rect.bottom) return;
+
+ CSoundFile *pSndFile = m_pModDoc->GetSoundFile();
+
+ bool bMultiSelection = (m_nScrollPos2nd != ORDERINDEX_INVALID);
+
+ if(!bMultiSelection) SetCurSel(m_nXScroll + (pt.x - rect.left) / m_cxFont);
+ SetFocus();
+ HMENU hMenu = ::CreatePopupMenu();
+ if(!hMenu) return;
+
+ // check if at least one pattern in the current selection exists
+ bool bPatternExists = false;
+ ORD_SELECTION selection = GetCurSel(false);
+ for(ORDERINDEX nOrd = selection.nOrdLo; nOrd <= selection.nOrdHi; nOrd++)
{
- SetCurSel(m_nXScroll + (pt.x - rect.left) / m_cxFont);
- SetFocus();
- HMENU hMenu = ::CreatePopupMenu();
-
- UINT nCurrentPattern = GetCurrentPattern();
- bool patternExists = (nCurrentPattern < m_pModDoc->GetSoundFile()->Patterns.Size()
- && m_pModDoc->GetSoundFile()->Patterns[nCurrentPattern] != NULL);
- DWORD greyed = patternExists?FALSE:MF_GRAYED;
+ bPatternExists = ((pSndFile->Order[nOrd] < pSndFile->Patterns.Size())
+ && (pSndFile->Patterns[pSndFile->Order[nOrd]] != nullptr));
+ if(bPatternExists) break;
+ }
- if (hMenu)
+ DWORD greyed = bPatternExists ? 0 : MF_GRAYED;
+
+ if(bMultiSelection)
+ {
+ // several patterns are selected.
+ AppendMenu(hMenu, MF_STRING, ID_ORDERLIST_INSERT, "&Insert Patterns\tIns");
+ AppendMenu(hMenu, MF_STRING, ID_ORDERLIST_DELETE, "&Remove Patterns\tDel");
+ AppendMenu(hMenu, MF_SEPARATOR, NULL, "");
+ AppendMenu(hMenu, MF_STRING | greyed, ID_ORDERLIST_COPY, "&Duplicate Patterns");
+ }
+ else
+ {
+ // only one pattern is selected
+ AppendMenu(hMenu, MF_STRING, ID_ORDERLIST_INSERT, "&Insert Pattern\tIns");
+ AppendMenu(hMenu, MF_STRING, ID_ORDERLIST_DELETE, "&Remove Pattern\tDel");
+ AppendMenu(hMenu, MF_SEPARATOR, NULL, "");
+ AppendMenu(hMenu, MF_STRING, ID_ORDERLIST_NEW, "Create &New Pattern");
+ AppendMenu(hMenu, MF_STRING | greyed, ID_ORDERLIST_COPY, "&Duplicate Pattern");
+ AppendMenu(hMenu, MF_STRING | greyed, ID_PATTERNCOPY, "&Copy Pattern");
+ AppendMenu(hMenu, MF_STRING | greyed, ID_PATTERNPASTE, "P&aste Pattern");
+ if ((m_pModDoc) && (m_pModDoc->GetSoundFile()->m_nType & (MOD_TYPE_XM|MOD_TYPE_IT|MOD_TYPE_MPT)))
{
- AppendMenu(hMenu, MF_STRING, ID_ORDERLIST_INSERT, "&Insert Pattern\tIns");
- AppendMenu(hMenu, MF_STRING, ID_ORDERLIST_DELETE, "&Remove Pattern\tDel");
AppendMenu(hMenu, MF_SEPARATOR, NULL, "");
- AppendMenu(hMenu, MF_STRING, ID_ORDERLIST_NEW, "Create &New Pattern");
- AppendMenu(hMenu, MF_STRING|greyed, ID_ORDERLIST_COPY, "&Duplicate Pattern");
- AppendMenu(hMenu, MF_STRING|greyed, ID_PATTERNCOPY, "&Copy Pattern");
- AppendMenu(hMenu, MF_STRING|greyed, ID_PATTERNPASTE, "P&aste Pattern");
- if ((m_pModDoc) && (m_pModDoc->GetSoundFile()->m_nType & (MOD_TYPE_XM|MOD_TYPE_IT|MOD_TYPE_MPT)))
- {
- AppendMenu(hMenu, MF_SEPARATOR, NULL, "");
- AppendMenu(hMenu, MF_STRING|greyed, ID_PATTERN_PROPERTIES, "&Properties...");
- }
- ClientToScreen(&pt);
- ::TrackPopupMenu(hMenu, TPM_LEFTALIGN|TPM_RIGHTBUTTON, pt.x, pt.y, 0, m_hWnd, NULL);
- ::DestroyMenu(hMenu);
+ AppendMenu(hMenu, MF_STRING | greyed, ID_PATTERN_PROPERTIES, "&Properties...");
}
}
+ ClientToScreen(&pt);
+ ::TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, m_hWnd, NULL);
+ ::DestroyMenu(hMenu);
}
@@ -732,6 +844,8 @@
{
if ((m_pModDoc) && (m_pParent))
{
+ m_nScrollPos2nd = ORDERINDEX_INVALID;
+ SetFocus();
CSoundFile *pSndFile = m_pModDoc->GetSoundFile();
m_pParent->SetCurrentPattern(pSndFile->Order[m_nScrollPos]);
}
@@ -741,11 +855,11 @@
void COrderList::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar*)
//--------------------------------------------------------------
{
- UINT nNewPos = m_nXScroll;
+ ORDERINDEX nNewPos = m_nXScroll;
UINT smin, smax;
GetScrollRange(SB_HORZ, (LPINT)&smin, (LPINT)&smax);
- m_bScrolling = TRUE;
+ m_bScrolling = true;
switch(nSBCode)
{
case SB_LEFT: nNewPos = 0; break;
@@ -755,7 +869,7 @@
case SB_PAGERIGHT: if (nNewPos+4 < smax) nNewPos += 4; else nNewPos = smax; break;
case SB_THUMBTRACK:
case SB_THUMBPOSITION: nNewPos = nPos; if (nNewPos & 0xFFFF8000) nNewPos = smin; break;
- case SB_ENDSCROLL: m_bScrolling = FALSE; break;
+ case SB_ENDSCROLL: m_bScrolling = false; break;
}
if (nNewPos > smax) nNewPos = smax;
if (nNewPos != (UINT)m_nXScroll)
@@ -770,12 +884,13 @@
void COrderList::OnSize(UINT nType, int cx, int cy)
//-------------------------------------------------
{
- int smin, smax, nPos;
+ ORDERINDEX nPos;
+ int smin, smax;
CWnd::OnSize(nType, cx, cy);
UpdateScrollInfo();
GetScrollRange(SB_HORZ, &smin, &smax);
- nPos = (short int)GetScrollPos(SB_HORZ);
+ nPos = (ORDERINDEX)GetScrollPos(SB_HORZ);
if (nPos > smax) nPos = smax;
if (m_nXScroll != nPos)
{
@@ -789,17 +904,34 @@
void COrderList::OnInsertOrder()
//------------------------------
{
+ // insert the same order(s) after the currently selected order(s)
if (m_pModDoc)
{
CSoundFile *pSndFile = m_pModDoc->GetSoundFile();
- //Checking whether there is some pattern at the end of orderlist.
- if(pSndFile->Order[pSndFile->Order.size()-1] < pSndFile->Patterns.Size())
+ ORD_SELECTION selection = GetCurSel(false);
+ ORDERINDEX nInsertCount = selection.nOrdHi - selection.nOrdLo, nInsertEnd = selection.nOrdHi;
+
+ for(int i = 0; i <= nInsertCount; i++)
{
- if(pSndFile->Order.size() < pSndFile->GetModSpecifications().ordersMax)
- pSndFile->Order.push_back(pSndFile->Order.GetInvalidPatIndex());
+
+ //Checking whether there is some pattern at the end of orderlist.
+ if(pSndFile->Order[pSndFile->Order.size() - 1] < pSndFile->Patterns.Size())
+ {
+ if(pSndFile->Order.size() < pSndFile->GetModSpecifications().ordersMax)
+ pSndFile->Order.push_back(pSndFile->Order.GetInvalidPatIndex());
+ }
+
+ for (int i=pSndFile->Order.size() - 1; i>nInsertEnd; i--) pSndFile->Order[i] = pSndFile->Order[i - 1];
}
- for (int i=pSndFile->Order.size()-1; i>m_nScrollPos; i--) pSndFile->Order[i] = pSndFile->Order[i-1];
+ // now that there is enough space in the order list, overwrite the orders
+ for(ORDERINDEX i = 0; i <= nInsertCount; i++)
+ {
+ if(nInsertEnd + i + 1 < pSndFile->GetModSpecifications().ordersMax)
+ pSndFile->Order[nInsertEnd + i + 1] = pSndFile->Order[nInsertEnd - nInsertCount + i];
+ }
+ m_nScrollPos = nInsertEnd + 1;
+ m_nScrollPos2nd = m_nScrollPos + nInsertCount;
InvalidateRect(NULL, FALSE);
m_pModDoc->SetModified();
m_pModDoc->UpdateAllViews(NULL, HINT_MODSEQUENCE, this);
@@ -814,14 +946,22 @@
{
CSoundFile *pSndFile = m_pModDoc->GetSoundFile();
- m_pModDoc->RemoveOrder(m_nScrollPos);
+ ORD_SELECTION selection = GetCurSel(false);
+ // remove selection
+ m_nScrollPos2nd = ORDERINDEX_INVALID;
+
+ for(int i = 0; i <= (selection.nOrdHi - selection.nOrdLo); i++)
+ {
+ m_pModDoc->RemoveOrder(selection.nOrdLo);
+ }
InvalidateRect(NULL, FALSE);
m_pModDoc->UpdateAllViews(NULL, HINT_MODSEQUENCE, this);
- UINT nNewOrd = pSndFile->Order[m_nScrollPos];
- if ((nNewOrd < pSndFile->Patterns.Size()) && (pSndFile->Patterns[nNewOrd]) && (m_pParent))
+ SetCurSel(selection.nOrdLo);
+ PATTERNINDEX nNewPat = pSndFile->Order[selection.nOrdLo];
+ if ((nNewPat < pSndFile->Patterns.Size()) && (pSndFile->Patterns[nNewPat] != nullptr) && (m_pParent))
{
- m_pParent->SetCurrentPattern(nNewOrd);
+ m_pParent->SetCurrentPattern(nNewPat);
}
}
}
@@ -938,7 +1078,7 @@
InvalidateRect(NULL, FALSE);
m_pModDoc->SetModified();
m_pModDoc->UpdateAllViews(NULL, HINT_MODSEQUENCE, this);
- SetCurSel(posdest, TRUE);
+ SetCurSel(posdest, true);
}
return bCanDrop;
}
Modified: trunk/OpenMPT/mptrack/Moddoc.h
===================================================================
--- trunk/OpenMPT/mptrack/Moddoc.h 2009-08-16 22:47:01 UTC (rev 330)
+++ trunk/OpenMPT/mptrack/Moddoc.h 2009-08-18 18:41:12 UTC (rev 331)
@@ -197,14 +197,14 @@
void RearrangeSampleList();
BOOL CompoCleanup();
- LONG InsertPattern(ORDERINDEX nOrd = -1, ROWINDEX nRows = 64);
- LONG InsertSample(BOOL bLimit=FALSE);
- LONG InsertInstrument(LONG lSample=0, LONG lDuplicate=0);
+ PATTERNINDEX InsertPattern(ORDERINDEX nOrd = -1, ROWINDEX nRows = 64);
+ SAMPLEINDEX InsertSample(bool bLimit = false);
+ INSTRUMENTINDEX InsertInstrument(LONG lSample=0, LONG lDuplicate=0);
void InitializeInstrument(MODINSTRUMENT *pIns, UINT nsample=0);
- BOOL RemoveOrder(UINT n);
- BOOL RemovePattern(UINT n);
- BOOL RemoveSample(UINT n);
- BOOL RemoveInstrument(UINT n);
+ bool RemoveOrder(ORDERINDEX n);
+ bool RemovePattern(PATTERNINDEX n);
+ bool RemoveSample(SAMPLEINDEX n);
+ bool RemoveInstrument(INSTRUMENTINDEX n);
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
@@ -240,7 +240,7 @@
BOOL IsChildSample(UINT nIns, UINT nSmp) const;
UINT FindSampleParent(UINT nSmp) const;
UINT FindInstrumentChild(UINT nIns) const;
- BOOL MoveOrder(UINT nSourceNdx, UINT nDestNdx, BOOL bUpdate=TRUE, BOOL bCopy=FALSE);
+ bool MoveOrder(UINT nSourceNdx, UINT nDestNdx, bool bUpdate = true, bool bCopy = false);
BOOL ExpandPattern(PATTERNINDEX nPattern);
BOOL ShrinkPattern(PATTERNINDEX nPattern);
BOOL CopyPattern(PATTERNINDEX nPattern, DWORD dwBeginSel, DWORD dwEndSel);
Modified: trunk/OpenMPT/mptrack/Modedit.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-16 22:47:01 UTC (rev 330)
+++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-18 18:41:12 UTC (rev 331)
@@ -1046,6 +1046,81 @@
}
+
+
+void CModDoc::RearrangeSampleList()
+//---------------------------------
+{
+ if(m_SndFile.m_nSamples < 2)
+ return;
+
+ UINT nRemap = 0; // remap count
+ UINT nSampleMap[MAX_SAMPLES + 1]; // map old => new
+ for(UINT i = 0; i <= MAX_SAMPLES; i++)
+ nSampleMap[i] = i;
+
+ // First, find out which sample slots are unused and create the new sample map
+ for(UINT i = 1 ; i <= m_SndFile.m_nSamples; i++) {
+ if(!m_SndFile.Samples[i].pSample)
+ {
+ // Move all following samples
+ nRemap++;
+ nSampleMap[i] = 0;
+ for(UINT j = i + 1; j <= m_SndFile.m_nSamples; j++)
+ nSampleMap[j]--;
+ }
+ }
+
+ if(!nRemap)
+ return;
+
+ BEGIN_CRITICAL();
+
+ // Now, move everything around
+ for(UINT i = 1; i <= m_SndFile.m_nSamples; i++)
+ {
+ if(nSampleMap[i] && nSampleMap[i] != i)
+ {
+ // This gotta be moved
+ m_SndFile.MoveSample(i, nSampleMap[i]);
+ m_SndFile.Samples[i].pSample = nullptr;
+ strcpy(m_SndFile.m_szNames[nSampleMap[i]], m_SndFile.m_szNames[i]);
+ m_SndFile.m_szNames[i][0] = '\0';
+
+ // Also update instrument mapping (if module is in instrument mode)
+ for(UINT iInstr = 1; iInstr <= m_SndFile.m_nInstruments; iInstr++){
+ if(m_SndFile.Instruments[iInstr]){
+ MODINSTRUMENT *p = m_SndFile.Instruments[iInstr];
+ for(WORD iNote =0; iNote < 128; iNote++)
+ if(p->Keyboard[iNote] == i) p->Keyboard[iNote] = nSampleMap[i];
+ }
+ }
+ }
+ }
+
+ // Go through the patterns and remap samples (if module is in sample mode)
+ if(!m_SndFile.m_nInstruments)
+ {
+ for (UINT nPat=0; nPat < m_SndFile.Patterns.Size(); nPat++) if (m_SndFile.Patterns[nPat])
+ {
+ MODCOMMAND *m = m_SndFile.Patterns[nPat];
+ for (UINT len = m_SndFile.PatternSize[nPat] * m_SndFile.m_nChannels; len; m++, len--)
+ {
+ if(nSampleMap[m->instr]) m->instr = nSampleMap[m->instr];
+ }
+ }
+ }
+
+ m_SndFile.m_nSamples -= nRemap;
+
+ END_CRITICAL();
+
+ SetModified();
+ UpdateAllViews(NULL, HINT_MODTYPE);
+
+}
+
+
BOOL CModDoc::ConvertInstrumentsToSamples()
//-----------------------------------------
{
@@ -1533,8 +1608,8 @@
}
-LONG CModDoc::InsertPattern(ORDERINDEX nOrd, ROWINDEX nRows)
-//------------------------------------------------
+PATTERNINDEX CModDoc::InsertPattern(ORDERINDEX nOrd, ROWINDEX nRows)
+//------------------------------------------------------------------
{
const int i = m_SndFile.Patterns.Insert(nRows);
if(i < 0)
@@ -1573,8 +1648,8 @@
}
-LONG CModDoc::InsertSample(BOOL bLimit)
-//-------------------------------------
+SAMPLEINDEX CModDoc::InsertSample(bool bLimit)
+//--------------------------------------------
{
UINT i = 1;
for (i=1; i<=m_SndFile.m_nSamples; i++)
@@ -1611,7 +1686,7 @@
}
-LONG CModDoc::InsertInstrument(LONG lSample, LONG lDuplicate)
+INSTRUMENTINDEX CModDoc::InsertInstrument(LONG lSample, LONG lDuplicate)
//-----------------------------------------------------------
{
MODINSTRUMENT *pDup = NULL;
@@ -1733,44 +1808,44 @@
}
-BOOL CModDoc::RemoveOrder(UINT n)
+bool CModDoc::RemoveOrder(ORDERINDEX n)
//-------------------------------
{
if (n < m_SndFile.Order.size())
{
BEGIN_CRITICAL();
- for (UINT i=n; i<m_SndFile.Order.size()-1; i++)
+ for (ORDERINDEX i=n; i<m_SndFile.Order.size()-1; i++)
{
m_SndFile.Order[i] = m_SndFile.Order[i+1];
}
m_SndFile.Order[m_SndFile.Order.size()-1] = m_SndFile.Order.GetInvalidPatIndex();
END_CRITICAL();
SetModified();
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
-BOOL CModDoc::RemovePattern(UINT n)
+bool CModDoc::RemovePattern(PATTERNINDEX n)
//---------------------------------
{
if ((n < m_SndFile.Patterns.Size()) && (m_SndFile.Patterns[n]))
{
BEGIN_CRITICAL();
LPVOID p = m_SndFile.Patterns[n];
- m_SndFile.Patterns[n] = NULL;
+ m_SndFile.Patterns[n] = nullptr;
m_SndFile.SetPatternName(n, "");
CSoundFile::FreePattern(p);
END_CRITICAL();
SetModified();
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
-BOOL CModDoc::RemoveSample(UINT n)
+bool CModDoc::RemoveSample(SAMPLEINDEX n)
//--------------------------------
{
if ((n) && (n <= m_SndFile.m_nSamples))
@@ -1783,86 +1858,13 @@
&& (!m_SndFile.Samples[m_SndFile.m_nSamples].pSample)) m_SndFile.m_nSamples--;
END_CRITICAL();
SetModified();
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
-void CModDoc::RearrangeSampleList()
-//---------------------------------
-{
- if(m_SndFile.m_nSamples < 2)
- return;
-
- UINT nRemap = 0; // remap count
- UINT nSampleMap[MAX_SAMPLES + 1]; // map old => new
- for(UINT i = 0; i <= MAX_SAMPLES; i++)
- nSampleMap[i] = i;
-
- // First, find out which sample slots are unused and create the new sample map
- for(UINT i = 1 ; i <= m_SndFile.m_nSamples; i++) {
- if(!m_SndFile.Samples[i].pSample)
- {
- // Move all following samples
- nRemap++;
- nSampleMap[i] = 0;
- for(UINT j = i + 1; j <= m_SndFile.m_nSamples; j++)
- nSampleMap[j]--;
- }
- }
-
- if(!nRemap)
- return;
-
- BEGIN_CRITICAL();
-
- // Now, move everything around
- for(UINT i = 1; i <= m_SndFile.m_nSamples; i++)
- {
- if(nSampleMap[i] && nSampleMap[i] != i)
- {
- // This gotta be moved
- m_SndFile.MoveSample(i, nSampleMap[i]);
- m_SndFile.Samples[i].pSample = nullptr;
- strcpy(m_SndFile.m_szNames[nSampleMap[i]], m_SndFile.m_szNames[i]);
- m_SndFile.m_szNames[i][0] = '\0';
-
- // Also update instrument mapping (if module is in instrument mode)
- for(UINT iInstr = 1; iInstr <= m_SndFile.m_nInstruments; iInstr++){
- if(m_SndFile.Instruments[iInstr]){
- MODINSTRUMENT *p = m_SndFile.Instruments[iInstr];
- for(WORD iNote =0; iNote < 128; iNote++)
- if(p->Keyboard[iNote] == i) p->Keyboard[iNote] = nSampleMap[i];
- }
- }
- }
- }
-
- // Go through the patterns and remap samples (if module is in sample mode)
- if(!m_SndFile.m_nInstruments)
- {
- for (UINT nPat=0; nPat < m_SndFile.Patterns.Size(); nPat++) if (m_SndFile.Patterns[nPat])
- {
- MODCOMMAND *m = m_SndFile.Patterns[nPat];
- for (UINT len = m_SndFile.PatternSize[nPat] * m_SndFile.m_nChannels; len; m++, len--)
- {
- if(nSampleMap[m->instr]) m->instr = nSampleMap[m->instr];
- }
- }
- }
-
- m_SndFile.m_nSamples -= nRemap;
-
- END_CRITICAL();
-
- SetModified();
- UpdateAllViews(NULL, HINT_MODTYPE);
-
-}
-
-
-BOOL CModDoc::RemoveInstrument(UINT n)
+bool CModDoc::RemoveInstrument(INSTRUMENTINDEX n)
//------------------------------------
{
if ((n) && (n <= m_SndFile.m_nInstruments) && (m_SndFile.Instruments[n]))
@@ -1875,31 +1877,32 @@
if (!bIns) m_SndFile.m_nInstruments = 0;
END_CRITICAL();
SetModified();
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
-BOOL CModDoc::MoveOrder(UINT nSourceNdx, UINT nDestNdx, BOOL bUpdate, BOOL bCopy)
+bool CModDoc::MoveOrder(UINT nSourceNdx, UINT nDestNdx, bool bUpdate, bool bCopy)
//-------------------------------------------------------------------------------
{
- if ((nSourceNdx >= m_SndFile.Order.size()) || (nDestNdx >= m_SndFile.Order.size())) return FALSE;
- UINT n = m_SndFile.Order[nSourceNdx];
+ if ((nSourceNdx >= m_SndFile.Order.size()) || (nDestNdx >= m_SndFile.Order.size())) return false;
+ if (nDestNdx >= m_SndFile.GetModSpecifications().ordersMax) return false;
+ ORDERINDEX n = m_SndFile.Order[nSourceNdx];
// Delete source
if (!bCopy)
{
- for (UINT i=nSourceNdx; i<m_SndFile.Order.size()-1; i++) m_SndFile.Order[i] = m_SndFile.Order[i+1];
+ for (ORDERINDEX i = nSourceNdx; i < m_SndFile.Order.size() - 1; i++) m_SndFile.Order[i] = m_SndFile.Order[i+1];
if (nSourceNdx < nDestNdx) nDestNdx--;
}
// Insert at dest
- for (UINT j=m_SndFile.Order.size()-1; j>nDestNdx; j--) m_SndFile.Order[j] = m_SndFile.Order[j-1];
+ for (ORDERINDEX j = m_SndFile.Order.size() - 1; j > nDestNdx; j--) m_SndFile.Order[j] = m_SndFile.Order[j-1];
m_SndFile.Order[nDestNdx] = n;
if (bUpdate)
{
UpdateAllViews(NULL, HINT_MODSEQUENCE, NULL);
}
- return TRUE;
+ return true;
}
Modified: trunk/OpenMPT/mptrack/View_tre.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_tre.cpp 2009-08-16 22:47:01 UTC (rev 330)
+++ trunk/OpenMPT/mptrack/View_tre.cpp 2009-08-18 18:41:12 UTC (rev 331)
@@ -1870,7 +1870,7 @@
{
if (bDoDrop)
{
- if (dwItemDrag != dwItemDrop) pModDoc->MoveOrder(dwItemDrag, dwItemDrop, TRUE);
+ if (dwItemDrag != dwItemDrop) pModDoc->MoveOrder(dwItemDrag, dwItemDrop, true);
}
return TRUE;
}
Modified: trunk/OpenMPT/mptrack/test/test.cpp
===================================================================
--- trunk/OpenMPT/mptrack/test/test.cpp 2009-08-16 22:47:01 UTC (rev 330)
+++ trunk/OpenMPT/mptrack/test/test.cpp 2009-08-18 18:41:12 UTC (rev 331)
@@ -95,6 +95,9 @@
STATIC_ASSERT( MAKE_VERSION_NUMERIC(1,17,2,28) == 18285096 );
STATIC_ASSERT( MAKE_VERSION_NUMERIC(1,17,02,48) == 18285128 );
STATIC_ASSERT( MAKE_VERSION_NUMERIC(01,17,02,52) == 18285138 );
+ // Ensure that bit-shifting works (used in some mod loaders for example)
+ STATIC_ASSERT( MAKE_VERSION_NUMERIC(01,17,00,00) == 0x0117 << 16 );
+ STATIC_ASSERT( MAKE_VERSION_NUMERIC(01,17,03,00) >> 8 == 0x011703 );
}
//Verify that the version obtained from the executable file is the same as
Modified: trunk/OpenMPT/mptrack/typedefs.h
===================================================================
--- trunk/OpenMPT/mptrack/typedefs.h 2009-08-16 22:47:01 UTC (rev 330)
+++ trunk/OpenMPT/mptrack/typedefs.h 2009-08-18 18:41:12 UTC (rev 331)
@@ -36,7 +36,10 @@
typedef uint16 CHANNELINDEX;
typedef uint16 ORDERINDEX;
const ORDERINDEX ORDERINDEX_MAX = uint16_max;
+ const ORDERINDEX ORDERINDEX_INVALID = ORDERINDEX_MAX;
typedef uint16 PATTERNINDEX;
+ const PATTERNINDEX PATTERNINDEX_MAX = uint16_max;
+ const PATTERNINDEX PATTERNINDEX_INVALID = PATTERNINDEX_MAX;
typedef uint8 PLUGINDEX;
typedef uint16 TEMPO;
typedef uint16 SAMPLEINDEX;
Modified: trunk/OpenMPT/soundlib/Load_669.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_669.cpp 2009-08-16 22:47:01 UTC (rev 330)
+++ trunk/OpenMPT/soundlib/Load_669.cpp 2009-08-18 18:41:12 UTC (rev 331)
@@ -59,7 +59,7 @@
DWORD len = LittleEndian(*((DWORD *)(&psmp[ichk].length)));
dontfuckwithme += len;
}
- if (dontfuckwithme > dwMemLength) return false;
+ if (dontfuckwithme - 0x1F1 > dwMemLength) return false;
// That should be enough checking: this must be a 669 module.
m_nType = MOD_TYPE_669;
m_dwSongFlags |= SONG_LINEARSLIDES;
Modified: trunk/OpenMPT/soundlib/Sndmix.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndmix.cpp 2009-08-16 22:47:01 UTC (rev 330)
+++ trunk/OpenMPT/soundlib/Sndmix.cpp 2009-08-18 18:41:12 UTC (rev 331)
@@ -855,9 +855,7 @@
//if(!(pChn->dwFlags & CHN_MUTE)) //removed by rewbs: fix http://www.modplug.com/forum/viewtopic.php?t=3358
nchn32++;
}
- if(nchn32 < 1) nchn32 = 1;
- if(nchn32 > 31) nchn32 = 31;
-
+ nchn32 = CLAMP(nchn32, 1, 31);
DWORD mastervol;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-08-16 22:47:11
|
Revision: 330
http://modplug.svn.sourceforge.net/modplug/?rev=330&view=rev
Author: saga-games
Date: 2009-08-16 22:47:01 +0000 (Sun, 16 Aug 2009)
Log Message:
-----------
[Fix] Rearrange Samples: Empty samples were overwriting the mod title
[Fix] Mod Conversion: Resetting the effect memory array proplery (nope, this was note a char array :)
[Imp] IMF Loading: Remove the last disabled channels and a little bit of refactoring
[Ref] Some more usage of the *INDEX datatypes
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Childfrm.h
trunk/OpenMPT/mptrack/Moddoc.h
trunk/OpenMPT/mptrack/Modedit.cpp
trunk/OpenMPT/soundlib/Load_imf.cpp
Modified: trunk/OpenMPT/mptrack/Childfrm.h
===================================================================
--- trunk/OpenMPT/mptrack/Childfrm.h 2009-08-16 16:58:51 UTC (rev 329)
+++ trunk/OpenMPT/mptrack/Childfrm.h 2009-08-16 22:47:01 UTC (rev 330)
@@ -26,13 +26,13 @@
typedef struct PATTERNVIEWSTATE
{
DWORD cbStruct;
- UINT nPattern;
- UINT nRow;
+ PATTERNINDEX nPattern;
+ ROWINDEX nRow;
UINT nCursor;
DWORD dwBeginSel;
DWORD dwEndSel;
UINT nDetailLevel;
- UINT nOrder; //rewbs.playSongFromCursor
+ ORDERINDEX nOrder; //rewbs.playSongFromCursor
} PATTERNVIEWSTATE;
typedef struct SAMPLEVIEWSTATE
Modified: trunk/OpenMPT/mptrack/Moddoc.h
===================================================================
--- trunk/OpenMPT/mptrack/Moddoc.h 2009-08-16 16:58:51 UTC (rev 329)
+++ trunk/OpenMPT/mptrack/Moddoc.h 2009-08-16 22:47:01 UTC (rev 330)
@@ -197,7 +197,7 @@
void RearrangeSampleList();
BOOL CompoCleanup();
- LONG InsertPattern(LONG nOrd=-1, UINT nRows=64);
+ LONG InsertPattern(ORDERINDEX nOrd = -1, ROWINDEX nRows = 64);
LONG InsertSample(BOOL bLimit=FALSE);
LONG InsertInstrument(LONG lSample=0, LONG lDuplicate=0);
void InitializeInstrument(MODINSTRUMENT *pIns, UINT nsample=0);
Modified: trunk/OpenMPT/mptrack/Modedit.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-16 16:58:51 UTC (rev 329)
+++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-16 22:47:01 UTC (rev 330)
@@ -162,8 +162,12 @@
for (UINT nPat=0; nPat<m_SndFile.Patterns.Size(); nPat++) if (m_SndFile.Patterns[nPat])
{
MODCOMMAND *m = m_SndFile.Patterns[nPat];
- BYTE cEffectMemory[MAX_CHANNELS][MAX_EFFECTS] = {0}; // for -> MOD/XM conversion
+
+ // This is used for -> MOD/XM conversion
+ BYTE cEffectMemory[MAX_CHANNELS][MAX_EFFECTS];
+ memset(&cEffectMemory, 0, sizeof(BYTE) * MAX_CHANNELS * MAX_EFFECTS);
UINT nChannel = m_SndFile.m_nChannels - 1;
+
for (UINT len = m_SndFile.PatternSize[nPat] * m_SndFile.m_nChannels; len; m++, len--)
{
nChannel = (nChannel + 1) % m_SndFile.m_nChannels; // 0...Channels - 1
@@ -1529,7 +1533,7 @@
}
-LONG CModDoc::InsertPattern(LONG nOrd, UINT nRows)
+LONG CModDoc::InsertPattern(ORDERINDEX nOrd, ROWINDEX nRows)
//------------------------------------------------
{
const int i = m_SndFile.Patterns.Insert(nRows);
@@ -1816,16 +1820,15 @@
// Now, move everything around
for(UINT i = 1; i <= m_SndFile.m_nSamples; i++)
{
- if(nSampleMap[i] != i)
+ if(nSampleMap[i] && nSampleMap[i] != i)
{
// This gotta be moved
-
m_SndFile.MoveSample(i, nSampleMap[i]);
m_SndFile.Samples[i].pSample = nullptr;
strcpy(m_SndFile.m_szNames[nSampleMap[i]], m_SndFile.m_szNames[i]);
m_SndFile.m_szNames[i][0] = '\0';
- // Also update instrument mapping
+ // Also update instrument mapping (if module is in instrument mode)
for(UINT iInstr = 1; iInstr <= m_SndFile.m_nInstruments; iInstr++){
if(m_SndFile.Instruments[iInstr]){
MODINSTRUMENT *p = m_SndFile.Instruments[iInstr];
@@ -1839,12 +1842,12 @@
// Go through the patterns and remap samples (if module is in sample mode)
if(!m_SndFile.m_nInstruments)
{
- for (UINT nPat=0; nPat<m_SndFile.Patterns.Size(); nPat++) if (m_SndFile.Patterns[nPat])
+ for (UINT nPat=0; nPat < m_SndFile.Patterns.Size(); nPat++) if (m_SndFile.Patterns[nPat])
{
MODCOMMAND *m = m_SndFile.Patterns[nPat];
for (UINT len = m_SndFile.PatternSize[nPat] * m_SndFile.m_nChannels; len; m++, len--)
{
- m->instr = nSampleMap[m->instr];
+ if(nSampleMap[m->instr]) m->instr = nSampleMap[m->instr];
}
}
}
Modified: trunk/OpenMPT/soundlib/Load_imf.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_imf.cpp 2009-08-16 16:58:51 UTC (rev 329)
+++ trunk/OpenMPT/soundlib/Load_imf.cpp 2009-08-16 22:47:01 UTC (rev 330)
@@ -1,7 +1,7 @@
/*
* Purpose: Load IMF (Imago Orpheus) modules
* Authors: Storlek (Original author - http://schismtracker.org/)
- * Johannes Schultz (OpenMPT Port)
+ * Johannes Schultz (OpenMPT Port, tweaks)
*
* Thanks to Storlek for allowing me to use this code!
*/
@@ -232,7 +232,6 @@
static void load_imf_envelope(MODINSTRUMENT *ins, INSTRUMENTENVELOPE *env, IMFINSTRUMENT *imfins, int e)
{
- UINT n;
UINT min = 0; // minimum tick value for next node
int shift = (e == IMF_ENV_VOL) ? 0 : 2;
@@ -242,7 +241,7 @@
env->nSustainStart = env->nSustainEnd = imfins->env[e].sustain;
env->nReleaseNode = ENV_RELEASE_NODE_UNSET;
- for (n = 0; n < env->nNodes; n++) {
+ for (UINT n = 0; n < env->nNodes; n++) {
UINT16 nTick, nValue;
nTick = LittleEndianW(imfins->nodes[e][n].tick);
nValue = LittleEndianW(imfins->nodes[e][n].value) >> shift;
@@ -302,7 +301,7 @@
m_nSamples = 0; // Will be incremented later
m_nInstruments = 0;
- m_nChannels = 32;
+ m_nChannels = 0;
for (CHANNELINDEX nChn = 0; nChn < 32; nChn++) {
ChnSettings[nChn].nPan = hdr.channels[nChn].panning * 64 / 255;
ChnSettings[nChn].nPan *= 4;
@@ -313,9 +312,11 @@
// TODO: reverb/chorus?
switch (hdr.channels[nChn].status) {
case 0: // enabled; don't worry about it
+ m_nChannels = nChn + 1;
break;
case 1: // mute
ChnSettings[nChn].dwFlags |= CHN_MUTE;
+ m_nChannels = nChn + 1;
break;
case 2: // disabled
ChnSettings[nChn].dwFlags |= CHN_MUTE;
@@ -326,6 +327,7 @@
return false;
}
}
+ if(!m_nChannels) return false;
for (ORDERINDEX nOrd = 0; nOrd < hdr.ordnum; nOrd++)
Order[nOrd] = ((hdr.orderlist[nOrd] == 0xff) ? Order.GetIgnoreIndex() : hdr.orderlist[nOrd]);
@@ -360,7 +362,7 @@
dwMemPos += 1;
if (mask == 0) {
row++;
- row_data += 32;
+ row_data += m_nChannels;
continue;
}
@@ -449,7 +451,7 @@
// read instruments
for (INSTRUMENTINDEX nIns = 0; nIns < hdr.insnum; nIns++) {
IMFINSTRUMENT imfins;
- MODINSTRUMENT *ins;
+ MODINSTRUMENT *pIns;
ASSERT_CAN_READ(sizeof(IMFINSTRUMENT));
memset(&imfins, 0, sizeof(IMFINSTRUMENT));
memcpy(&imfins, lpStream + dwMemPos, sizeof(IMFINSTRUMENT));
@@ -465,42 +467,33 @@
return false;
}
- ins = new MODINSTRUMENT;
- if (!ins) continue;
- Instruments[nIns + 1] = ins;
- memset(ins, 0, sizeof(MODINSTRUMENT));
+ pIns = new MODINSTRUMENT;
+ if (!pIns) continue;
+ Instruments[nIns + 1] = pIns;
+ memset(pIns, 0, sizeof(MODINSTRUMENT));
+ pIns->nPPC = 5 * 12;
+ SetDefaultInstrumentValues(pIns);
- strncpy(ins->name, imfins.name, 25);
- ins->name[25] = 0;
+ strncpy(pIns->name, imfins.name, 31);
+ pIns->name[31] = 0;
if (imfins.smpnum) {
for (BYTE cNote = 0; cNote < 120; cNote++) {
- ins->NoteMap[cNote] = cNote + 1;
- ins->Keyboard[cNote] = firstsample + imfins.map[cNote];
+ pIns->NoteMap[cNote] = cNote + 1;
+ pIns->Keyboard[cNote] = firstsample + imfins.map[cNote];
}
}
- /* Fadeout:
- IT1 - 64
- IT2 - 256
- FT2 - 4095
- IMF - 4095
- MPT - god knows what, all the loaders are inconsistent
- Schism - 128 presented (!); 8192? internal
+ pIns->nFadeOut = imfins.fadeout;
+ pIns->nGlobalVol = 128;
- IMF and XM have the same range and modplug's XM loader doesn't do any bit shifting with it,
- so I'll do the same here for now. I suppose I should get this nonsense straightened
- out at some point, though. */
- ins->nFadeOut = imfins.fadeout;
- ins->nGlobalVol = 128;
+ load_imf_envelope(pIns, &pIns->VolEnv, &imfins, IMF_ENV_VOL);
+ load_imf_envelope(pIns, &pIns->PanEnv, &imfins, IMF_ENV_PAN);
+ load_imf_envelope(pIns, &pIns->PitchEnv, &imfins, IMF_ENV_FILTER);
- load_imf_envelope(ins, &ins->VolEnv, &imfins, IMF_ENV_VOL);
- load_imf_envelope(ins, &ins->PanEnv, &imfins, IMF_ENV_PAN);
- load_imf_envelope(ins, &ins->PitchEnv, &imfins, IMF_ENV_FILTER);
-
// hack to get === to stop notes (from modplug's xm loader)
- if (!(ins->dwFlags & ENV_VOLUME) && !ins->nFadeOut)
- ins->nFadeOut = 8192;
+ if (!(pIns->dwFlags & ENV_VOLUME) && !pIns->nFadeOut)
+ pIns->nFadeOut = 8192;
// read this instrument's samples
for (SAMPLEINDEX nSmp = 0; nSmp < imfins.smpnum; nSmp++) {
@@ -520,7 +513,7 @@
strncpy(pSample->filename, imfsmp.filename, 12);
pSample->filename[12] = 0;
- strcpy(m_szNames[nSmp + 1], pSample->filename);
+ strcpy(m_szNames[m_nSamples], pSample->filename);
blen = pSample->nLength = LittleEndian(imfsmp.length);
pSample->nLoopStart = LittleEndian(imfsmp.loop_start);
pSample->nLoopEnd = LittleEndian(imfsmp.loop_end);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-08-16 16:59:06
|
Revision: 329
http://modplug.svn.sourceforge.net/modplug/?rev=329&view=rev
Author: saga-games
Date: 2009-08-16 16:58:51 +0000 (Sun, 16 Aug 2009)
Log Message:
-----------
[Imp] Mod Conversion: Try to use fix commands that don't have cache (00 value) in XM (Arpeggio) and MOD format (Arpeggio and a few others) by using the previous value
[New] OpenMPT can now import IMF (Imago Orpheus) modules
[Ref] Minor modifications in the GDM and MO3 loaders
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Modedit.cpp
trunk/OpenMPT/mptrack/Mptrack.cpp
trunk/OpenMPT/soundlib/Load_gdm.cpp
trunk/OpenMPT/soundlib/Load_imf.cpp
trunk/OpenMPT/soundlib/Load_mo3.cpp
trunk/OpenMPT/soundlib/Sndfile.cpp
Modified: trunk/OpenMPT/mptrack/Modedit.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-16 11:55:06 UTC (rev 328)
+++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-16 16:58:51 UTC (rev 329)
@@ -162,8 +162,11 @@
for (UINT nPat=0; nPat<m_SndFile.Patterns.Size(); nPat++) if (m_SndFile.Patterns[nPat])
{
MODCOMMAND *m = m_SndFile.Patterns[nPat];
+ BYTE cEffectMemory[MAX_CHANNELS][MAX_EFFECTS] = {0}; // for -> MOD/XM conversion
+ UINT nChannel = m_SndFile.m_nChannels - 1;
for (UINT len = m_SndFile.PatternSize[nPat] * m_SndFile.m_nChannels; len; m++, len--)
{
+ nChannel = (nChannel + 1) % m_SndFile.m_nChannels; // 0...Channels - 1
//////////////////////////
// Convert 8-bit Panning
@@ -286,6 +289,13 @@
switch(m->command)
{
+ case CMD_ARPEGGIO:
+ // No effect memory in XM / MOD
+ if(m->param == 0)
+ m->param = cEffectMemory[nChannel][CMD_ARPEGGIO];
+ else
+ cEffectMemory[nChannel][CMD_ARPEGGIO] = m->param;
+ break;
case CMD_S3MCMDEX:
m->command = CMD_MODCMDEX;
switch(m->param & 0xF0)
@@ -391,8 +401,8 @@
}
- //////////////////////////////////////////////////////////////////
- // Convert anything to MOD - remove volume column, adjust retrig
+ /////////////////////////////////////////////////////////////////////////////////
+ // Convert anything to MOD - remove volume column, adjust retrig, effect memory
if (newTypeIsMOD)
{
if(m->command) switch(m->command)
@@ -401,6 +411,17 @@
m->command = CMD_MODCMDEX;
m->param = 0x90 | (m->param & 0x0F);
break;
+ case CMD_PORTAMENTOUP:
+ case CMD_PORTAMENTODOWN:
+ case CMD_TONEPORTAVOL:
+ case CMD_VIBRATOVOL:
+ case CMD_VOLUMESLIDE:
+ // ProTracker doesn't have effect memory for these commands, so let's try to fix them
+ if(m->param == 0)
+ m->param = cEffectMemory[nChannel][m->command];
+ else
+ cEffectMemory[nChannel][m->command] = m->param;
+ break;
}
else switch(m->volcmd)
Modified: trunk/OpenMPT/mptrack/Mptrack.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Mptrack.cpp 2009-08-16 11:55:06 UTC (rev 328)
+++ trunk/OpenMPT/mptrack/Mptrack.cpp 2009-08-16 16:58:51 UTC (rev 329)
@@ -1252,13 +1252,11 @@
OFN_HIDEREADONLY | OFN_ENABLESIZING | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_FORCESHOWHIDDEN | OFN_ALLOWMULTISELECT,
// -> CODE#0023
// -> DESC="IT project files (.itp)"
-// "All Modules|*.mod;*.nst;*.wow;*.s3m;*.stm;*.669;*.mtm;*.xm;*.it;*.ult;*.mdz;*.s3z;*.xmz;*.itz;mod.*;*.far;*.mdl;*.okt;*.dmf;*.ptm;*.mdr;*.med;*.ams;*.dbm;*.dsm;*.mid;*.rmi;*.smf;*.bak;*.umx;*.amf;*.psm;*.mt2|"
-// "All Modules|*.mod;*.nst;*.wow;*.s3m;*.stm;*.669;*.mtm;*.xm;*.it;*.ult;*.mdz;*.s3z;*.xmz;*.itz;mod.*;*.far;*.mdl;*.okt;*.dmf;*.ptm;*.mdr;*.med;*.ams;*.dbm;*.dsm;*.mid;*.rmi;*.smf;*.bak;*.umx;*.amf;*.psm;*.mt2;*.gdm|"
#ifndef NO_MO3_SUPPORT
- "All Modules|*.mod;*.nst;*.wow;*.s3m;*.stm;*.669;*.mtm;*.xm;*.it;*.itp;*.mptm;*.ult;*.mdz;*.s3z;*.xmz;*.itz;mod.*;*.far;*.mdl;*.okt;*.dmf;*.ptm;*.mdr;*.med;*.ams;*.dbm;*.dsm;*.mid;*.rmi;*.smf;*.umx;*.amf;*.psm;*.mt2;*.gdm;*.mo3|"
+ "All Modules|*.mod;*.nst;*.wow;*.s3m;*.stm;*.669;*.mtm;*.xm;*.it;*.itp;*.mptm;*.ult;*.mdz;*.s3z;*.xmz;*.itz;mod.*;*.far;*.mdl;*.okt;*.dmf;*.ptm;*.mdr;*.med;*.ams;*.dbm;*.dsm;*.mid;*.rmi;*.smf;*.umx;*.amf;*.psm;*.mt2;*.gdm;*.imf;*.mo3|"
"Compressed Modules (*.mdz;*.s3z;*.xmz;*.itz;*.mo3)|*.mdz;*.s3z;*.xmz;*.itz;*.mdr;*.zip;*.rar;*.lha;*.mo3|"
#else
- "All Modules|*.mod;*.nst;*.wow;*.s3m;*.stm;*.669;*.mtm;*.xm;*.it;*.itp;*.mptm;*.ult;*.mdz;*.s3z;*.xmz;*.itz;mod.*;*.far;*.mdl;*.okt;*.dmf;*.ptm;*.mdr;*.med;*.ams;*.dbm;*.dsm;*.mid;*.rmi;*.smf;*.umx;*.amf;*.psm;*.mt2;*.gdm|"
+ "All Modules|*.mod;*.nst;*.wow;*.s3m;*.stm;*.669;*.mtm;*.xm;*.it;*.itp;*.mptm;*.ult;*.mdz;*.s3z;*.xmz;*.itz;mod.*;*.far;*.mdl;*.okt;*.dmf;*.ptm;*.mdr;*.med;*.ams;*.dbm;*.dsm;*.mid;*.rmi;*.smf;*.umx;*.amf;*.psm;*.mt2;*.gdm;*.imf|"
"Compressed Modules (*.mdz;*.s3z;*.xmz;*.itz)|*.mdz;*.s3z;*.xmz;*.itz;*.mdr;*.zip;*.rar;*.lha|"
#endif
// -! NEW_FEATURE#0023
@@ -1271,7 +1269,7 @@
"Impulse Tracker Projects (*.itp)|*.itp;*.itpz|"
// -! NEW_FEATURE#0023
"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;*.gdm|"
+ "Other Modules (mtm,okt,mdl,669,far,...)|*.mtm;*.669;*.ult;*.wow;*.far;*.mdl;*.okt;*.dmf;*.ptm;*.med;*.ams;*.dbm;*.dsm;*.umx;*.amf;*.psm;*.mt2;*.gdm;*.imf|"
"Wave Files (*.wav)|*.wav|"
"Midi Files (*.mid,*.rmi)|*.mid;*.rmi;*.smf|"
"All Files (*.*)|*.*||",
Modified: trunk/OpenMPT/soundlib/Load_gdm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_gdm.cpp 2009-08-16 11:55:06 UTC (rev 328)
+++ trunk/OpenMPT/soundlib/Load_gdm.cpp 2009-08-16 16:58:51 UTC (rev 329)
@@ -66,6 +66,8 @@
BYTE Pan; // default pan
} GDMSAMPLEHEADER, *PGDMSAMPLEHEADER;
+#pragma pack()
+
bool CSoundFile::ReadGDM(const LPCBYTE lpStream, const DWORD dwMemLength)
//-----------------------------------------------------------
{
Modified: trunk/OpenMPT/soundlib/Load_imf.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_imf.cpp 2009-08-16 11:55:06 UTC (rev 328)
+++ trunk/OpenMPT/soundlib/Load_imf.cpp 2009-08-16 16:58:51 UTC (rev 329)
@@ -1,6 +1,6 @@
/*
* Purpose: Load IMF (Imago Orpheus) modules
- * Authors: Storlek (http://schismtracker.org/)
+ * Authors: Storlek (Original author - http://schismtracker.org/)
* Johannes Schultz (OpenMPT Port)
*
* Thanks to Storlek for allowing me to use this code!
@@ -12,7 +12,7 @@
#pragma pack(1)
struct IMFCHANNEL {
- char name[12]; // Channelname (ASCIIZ-String, max 11 chars)
+ char name[12]; // Channel name (ASCIIZ-String, max 11 chars)
BYTE chorus; // Default chorus
BYTE reverb; // Default reverb
BYTE panning; // Pan positions 00-FF
@@ -20,20 +20,20 @@
};
struct IMFHEADER {
- char title[32]; // Songname (ASCIIZ-String, max. 31 chars)
- UINT16 ordnum; // Number of orders saved
- UINT16 patnum; // Number of patterns saved
- UINT16 insnum; // Number of instruments saved
- UINT16 flags; // Module flags (&1 => linear)
+ char title[32]; // Songname (ASCIIZ-String, max. 31 chars)
+ UINT16 ordnum; // Number of orders saved
+ UINT16 patnum; // Number of patterns saved
+ UINT16 insnum; // Number of instruments saved
+ UINT16 flags; // Module flags (&1 => linear)
BYTE unused1[8];
- BYTE tempo; // Default tempo (Axx, 1..255)
- BYTE bpm; // Default beats per minute (BPM) (Txx, 32..255)
- BYTE master; // Default mastervolume (Vxx, 0..64)
- BYTE amp; // Amplification factor (mixing volume, 4..127)
+ BYTE tempo; // Default tempo (Axx, 1..255)
+ BYTE bpm; // Default beats per minute (BPM) (Txx, 32..255)
+ BYTE master; // Default mastervolume (Vxx, 0..64)
+ BYTE amp; // Amplification factor (mixing volume, 4..127)
BYTE unused2[8];
- char im10[4]; // 'IM10'
- struct IMFCHANNEL channels[32]; // Channel settings
- BYTE orderlist[256]; // Order list (0xff = +++; blank out anything beyond ordnum)
+ char im10[4]; // 'IM10'
+ IMFCHANNEL channels[32]; // Channel settings
+ BYTE orderlist[256]; // Order list (0xff = +++; blank out anything beyond ordnum)
};
enum {
@@ -60,22 +60,22 @@
char name[32]; // Inst. name (ASCIIZ-String, max. 31 chars)
BYTE map[120]; // Multisample settings
BYTE unused[8];
- struct IMFENVNODES nodes[3][16];
- struct IMFENVELOPE env[3];
+ IMFENVNODES nodes[3][16];
+ IMFENVELOPE env[3];
UINT16 fadeout; // Fadeout rate (0...0FFFH)
UINT16 smpnum; // Number of samples in instrument
char ii10[4]; // 'II10'
};
struct IMFSAMPLE {
- char filename[13]; // Sample filename (12345678.ABC) */
+ char filename[13]; // Sample filename (12345678.ABC) */
BYTE unused1[3];
UINT32 length; // Length
UINT32 loop_start; // Loop start
UINT32 loop_end; // Loop end
UINT32 C5Speed; // Samplerate
- BYTE volume; // Default volume (0..64)
- BYTE panning; // Default pan (00h = Left / 80h = Middle)
+ BYTE volume; // Default volume (0...64)
+ BYTE panning; // Default pan (0...255)
BYTE unused2[14];
BYTE flags; // Sample flags
BYTE unused3[5];
@@ -85,54 +85,53 @@
};
#pragma pack()
-
static BYTE imf_efftrans[] = {
CMD_NONE,
- CMD_SPEED, // 0x01 1xx Set Tempo
- CMD_TEMPO, // 0x02 2xx Set BPM
+ CMD_SPEED, // 0x01 1xx Set Tempo
+ CMD_TEMPO, // 0x02 2xx Set BPM
CMD_TONEPORTAMENTO, // 0x03 3xx Tone Portamento
- CMD_TONEPORTAVOL, // 0x04 4xy Tone Portamento + Volume Slide
- CMD_VIBRATO, // 0x05 5xy Vibrato
- CMD_VIBRATOVOL, // 0x06 6xy Vibrato + Volume Slide
- CMD_FINEVIBRATO, // 0x07 7xy Fine Vibrato
- CMD_TREMOLO, // 0x08 8xy Tremolo
- CMD_ARPEGGIO, // 0x09 9xy Arpeggio
- CMD_PANNING8, // 0x0A Axx Set Pan Position
- CMD_PANNINGSLIDE, // 0x0B Bxy Pan Slide
- CMD_VOLUME, // 0x0C Cxx Set Volume
- CMD_VOLUMESLIDE, // 0x0D Dxy Volume Slide
- CMD_VOLUMESLIDE, // 0x0E Exy Fine Volume Slide
- CMD_S3MCMDEX, // 0x0F Fxx Set Finetune
- CMD_NOTESLIDEUP, // 0x10 Gxy Note Slide Up
- CMD_NOTESLIDEDOWN, // 0x11 Hxy Note Slide Down
- CMD_PORTAMENTOUP, // 0x12 Ixx Slide Up
- CMD_PORTAMENTODOWN, // 0x13 Jxx Slide Down
- CMD_PORTAMENTOUP, // 0x14 Kxx Fine Slide Up
- CMD_PORTAMENTODOWN, // 0x15 Lxx Fine Slide Down
- CMD_MIDI, // 0x16 Mxx Set Filter Cutoff - XXX
- CMD_NONE, // 0x17 Nxy Filter Slide + Resonance - XXX
- CMD_OFFSET, // 0x18 Oxx Set Sample Offset
- CMD_NONE, // 0x19 Pxx Set Fine Sample Offset - XXX
- CMD_KEYOFF, // 0x1A Qxx Key Off
- CMD_RETRIG, // 0x1B Rxy Retrig
- CMD_TREMOR, // 0x1C Sxy Tremor
- CMD_POSITIONJUMP, // 0x1D Txx Position Jump
- CMD_PATTERNBREAK, // 0x1E Uxx Pattern Break
- CMD_GLOBALVOLUME, // 0x1F Vxx Set Mastervolume
- CMD_GLOBALVOLSLIDE, // 0x20 Wxy Mastervolume Slide
- CMD_S3MCMDEX, // 0x21 Xxx Extended Effect
- // X1x Set Filter
- // X3x Glissando
- // X5x Vibrato Waveform
- // X8x Tremolo Waveform
- // XAx Pattern Loop
- // XBx Pattern Delay
- // XCx Note Cut
- // XDx Note Delay
- // XEx Ignore Envelope
- // XFx Invert Loop
- CMD_NONE, // 0x22 Yxx Chorus - XXX
- CMD_NONE, // 0x23 Zxx Reverb - XXX
+ CMD_TONEPORTAVOL, // 0x04 4xy Tone Portamento + Volume Slide
+ CMD_VIBRATO, // 0x05 5xy Vibrato
+ CMD_VIBRATOVOL, // 0x06 6xy Vibrato + Volume Slide
+ CMD_FINEVIBRATO, // 0x07 7xy Fine Vibrato
+ CMD_TREMOLO, // 0x08 8xy Tremolo
+ CMD_ARPEGGIO, // 0x09 9xy Arpeggio
+ CMD_PANNING8, // 0x0A Axx Set Pan Position
+ CMD_PANNINGSLIDE, // 0x0B Bxy Pan Slide
+ CMD_VOLUME, // 0x0C Cxx Set Volume
+ CMD_VOLUMESLIDE, // 0x0D Dxy Volume Slide
+ CMD_VOLUMESLIDE, // 0x0E Exy Fine Volume Slide
+ CMD_S3MCMDEX, // 0x0F Fxx Set Finetune
+ CMD_NOTESLIDEUP, // 0x10 Gxy Note Slide Up
+ CMD_NOTESLIDEDOWN, // 0x11 Hxy Note Slide Down
+ CMD_PORTAMENTOUP, // 0x12 Ixx Slide Up
+ CMD_PORTAMENTODOWN, // 0x13 Jxx Slide Down
+ CMD_PORTAMENTOUP, // 0x14 Kxx Fine Slide Up
+ CMD_PORTAMENTODOWN, // 0x15 Lxx Fine Slide Down
+ CMD_MIDI, // 0x16 Mxx Set Filter Cutoff - XXX
+ CMD_NONE, // 0x17 Nxy Filter Slide + Resonance - XXX
+ CMD_OFFSET, // 0x18 Oxx Set Sample Offset
+ CMD_NONE, // 0x19 Pxx Set Fine Sample Offset - XXX
+ CMD_KEYOFF, // 0x1A Qxx Key Off
+ CMD_RETRIG, // 0x1B Rxy Retrig
+ CMD_TREMOR, // 0x1C Sxy Tremor
+ CMD_POSITIONJUMP, // 0x1D Txx Position Jump
+ CMD_PATTERNBREAK, // 0x1E Uxx Pattern Break
+ CMD_GLOBALVOLUME, // 0x1F Vxx Set Mastervolume
+ CMD_GLOBALVOLSLIDE, // 0x20 Wxy Mastervolume Slide
+ CMD_S3MCMDEX, // 0x21 Xxx Extended Effect
+ // X1x Set Filter
+ // X3x Glissando
+ // X5x Vibrato Waveform
+ // X8x Tremolo Waveform
+ // XAx Pattern Loop
+ // XBx Pattern Delay
+ // XCx Note Cut
+ // XDx Note Delay
+ // XEx Ignore Envelope
+ // XFx Invert Loop
+ CMD_NONE, // 0x22 Yxx Chorus - XXX
+ CMD_NONE, // 0x23 Zxx Reverb - XXX
};
static void import_imf_effect(MODCOMMAND *note)
@@ -225,115 +224,6 @@
}
}
-#ifdef _IMF_SUPPORT_FINISHED_
-
-static void load_imf_pattern(CSoundFile *csf, int pat, UINT32 ignore_channels, slurp_t *fp)
-{
- UINT16 length, nrows;
- BYTE mask, channel;
- int row, startpos;
- unsigned int lostfx = 0;
- MODCOMMAND *row_data, *note, junk_note;
-
- startpos = slurp_tell(fp);
-
- slurp_read(fp, &length, 2);
- length = LittleEndianW(length);
- slurp_read(fp, &nrows, 2);
- nrows = LittleEndianW(nrows);
-
- csf->Patterns.Insert(pat, nrows);
- //row_data = Patterns[pat] = csf_allocate_pattern(nrows, 64);
- //PatternSize[pat] = PatternAllocSize[pat] = nrows;
- row_data = csf->Patterns[pat];
-
- row = 0;
- while (row < nrows) {
- mask = slurp_getc(fp);
- if (mask == 0) {
- row++;
- row_data += MAX_CHANNELS;
- continue;
- }
-
- channel = mask & 0x1f;
-
- if (ignore_channels & (1 << channel)) {
- /* should do this better, i.e. not go through the whole process of deciding
- what to do with the effects since they're just being thrown out */
- //printf("disabled channel %d contains data\n", channel + 1);
- note = &junk_note;
- } else {
- note = row_data + channel;
- }
-
- if (mask & 0x20) {
- /* read note/instrument */
- note->note = slurp_getc(fp);
- note->instr = slurp_getc(fp);
- if (note->note == 160) {
- note->note = NOTE_KEYOFF; /* ??? */
- } else if (note->note == 255) {
- note->note = NOTE_NONE; /* ??? */
- } else {
- note->note = (note->note >> 4) * 12 + (note->note & 0xf) + 12 + 1;
- if (note->note > NOTE_MAX) {
- //printf("%d.%d.%d: funny note 0x%02x\n",
- // pat, row, channel, fp->data[fp->pos - 1]);
- note->note = NOTE_NONE;
- }
- }
- }
- if ((mask & 0xc0) == 0xc0) {
- BYTE e1c, e1d, e2c, e2d;
-
- /* read both effects and figure out what to do with them */
- e1c = slurp_getc(fp);
- e1d = slurp_getc(fp);
- e2c = slurp_getc(fp);
- e2d = slurp_getc(fp);
- if (e1c == 0xc) {
- note->vol = min(e1d, 0x40);
- note->volcmd = VOLCMD_VOLUME;
- note->command = e2c;
- note->param = e2d;
- } else if (e2c == 0xc) {
- note->vol = min(e2d, 0x40);
- note->volcmd = VOLCMD_VOLUME;
- note->command = e1c;
- note->param = e1d;
- } else if (e1c == 0xa) {
- note->vol = e1d * 64 / 255;
- note->volcmd = VOLCMD_PANNING;
- note->command = e2c;
- note->param = e2d;
- } else if (e2c == 0xa) {
- note->vol = e2d * 64 / 255;
- note->volcmd = VOLCMD_PANNING;
- note->command = e1c;
- note->param = e1d;
- } else {
- /* check if one of the effects is a 'global' effect
- -- if so, put it in some unused channel instead.
- otherwise pick the most important effect. */
- lostfx++;
- note->command = e2c;
- note->param = e2d;
- }
- } else if (mask & 0xc0) {
- /* there's one effect, just stick it in the effect column */
- note->command = slurp_getc(fp);
- note->param = slurp_getc(fp);
- }
- if (note->command)
- import_imf_effect(note);
- }
-
- /*if (lostfx)
- log_appendf(2, "Pattern %d: %d effect%s skipped!\n", pat, lostfx, lostfx == 1 ? "" : "s");*/
-}
-
-
static unsigned int envflags[3][3] = {
{ENV_VOLUME, ENV_VOLSUSTAIN, ENV_VOLLOOP},
{ENV_PANNING, ENV_PANSUSTAIN, ENV_PANLOOP},
@@ -342,21 +232,23 @@
static void load_imf_envelope(MODINSTRUMENT *ins, INSTRUMENTENVELOPE *env, IMFINSTRUMENT *imfins, int e)
{
- int n, t, v;
- int min = 0; // minimum tick value for next node
- int shift = (e == IMF_ENV_VOL ? 0 : 2);
+ UINT n;
+ UINT min = 0; // minimum tick value for next node
+ int shift = (e == IMF_ENV_VOL) ? 0 : 2;
env->nNodes = CLAMP(imfins->env[e].points, 2, 25);
env->nLoopStart = imfins->env[e].loop_start;
env->nLoopEnd = imfins->env[e].loop_end;
env->nSustainStart = env->nSustainEnd = imfins->env[e].sustain;
+ env->nReleaseNode = ENV_RELEASE_NODE_UNSET;
for (n = 0; n < env->nNodes; n++) {
- t = LittleEndianW(imfins->nodes[e][n].tick);
- v = LittleEndianW(imfins->nodes[e][n].value) >> shift;
- env->Ticks[n] = max(min, t);
- env->Values[n] = v = min(v, 64);
- min = t + 1;
+ UINT16 nTick, nValue;
+ nTick = LittleEndianW(imfins->nodes[e][n].tick);
+ nValue = LittleEndianW(imfins->nodes[e][n].value) >> shift;
+ env->Ticks[n] = (WORD)max(min, nTick);
+ env->Values[n] = (BYTE)min(nValue, 64);
+ min = nTick + 1;
}
// this would be less retarded if the envelopes all had their own flags...
if (imfins->env[e].flags & 1)
@@ -367,20 +259,22 @@
ins->dwFlags |= envflags[e][2];
}
-//int fmt_imf_load_song(CSoundFile *song, slurp_t *fp, UNUSED unsigned int lflags)
bool CSoundFile::ReadIMF(const LPCBYTE lpStream, const DWORD dwMemLength)
{
- DWORD dwMemPos;
+ #define ASSERT_CAN_READ(x) \
+ if( dwMemPos > dwMemLength || x > dwMemLength - dwMemPos ) return false;
+
+ DWORD dwMemPos = 0;
IMFHEADER hdr;
- int n, s;
MODSAMPLE *pSample = Samples + 1;
- int firstsample = 1; // first pSample for the current instrument
- UINT32 ignore_channels = 0; /* bit set for each channel that's completely disabled */
+ WORD firstsample = 1; // first pSample for the current instrument
+ UINT32 ignore_channels = 0; // bit set for each channel that's completely disabled
- //slurp_read(fp, &hdr, sizeof(hdr));
- if(sizeof(IMFHEADER) > dwMemLength) return false;
- memset(hdr, 0, sizeof(IMFHEADER));
- memcpy(hdr, lpStream, sizeof(IMFHEADER))
+ ASSERT_CAN_READ(sizeof(IMFHEADER));
+ memset(&hdr, 0, sizeof(IMFHEADER));
+ memcpy(&hdr, lpStream, sizeof(IMFHEADER));
+ dwMemPos = sizeof(IMFHEADER);
+
hdr.ordnum = LittleEndianW(hdr.ordnum);
hdr.patnum = LittleEndianW(hdr.patnum);
hdr.insnum = LittleEndianW(hdr.insnum);
@@ -390,56 +284,177 @@
return false;
ChangeModTypeTo(MOD_TYPE_IT);
+ SetModFlag(MSF_COMPATIBLE_PLAY, true);
// song name
memset(m_szNames, 0, sizeof(m_szNames));
- memcpy(m_szNames[0], hdr.title, 25);
- m_szNames[0][25] = 0;
+ memcpy(m_szNames[0], hdr.title, 31);
+ m_szNames[0][31] = 0;
SetNullTerminator(m_szNames[0]);
if (hdr.flags & 1)
m_dwSongFlags |= SONG_LINEARSLIDES;
- //m_dwSongFlags |= SONG_INSTRUMENTMODE;
m_nDefaultSpeed = hdr.tempo;
m_nDefaultTempo = hdr.bpm;
- m_nDefaultGlobalVolume = hdr.master << 1;
- m_nSamplePreAmp = hdr.amp;
+ m_nDefaultGlobalVolume = CLAMP(hdr.master, 0, 64) << 2;
+ m_nSamplePreAmp = CLAMP(hdr.amp, 4, 127);
+
+ m_nSamples = 0; // Will be incremented later
+ m_nInstruments = 0;
- for (n = 0; n < 32; n++) {
- Chn[n].nPan = hdr.channels[n].panning * 64 / 255;
- Chn[n].nPan *= 4; //mphack
- /* TODO: reverb/chorus??? */
- switch (hdr.channels[n].status) {
- case 0: /* enabled; don't worry about it */
+ m_nChannels = 32;
+ for (CHANNELINDEX nChn = 0; nChn < 32; nChn++) {
+ ChnSettings[nChn].nPan = hdr.channels[nChn].panning * 64 / 255;
+ ChnSettings[nChn].nPan *= 4;
+
+ memcpy(&ChnSettings[nChn].szName[0], hdr.channels[nChn].name, 12);
+ SetNullTerminator(ChnSettings[nChn].szName);
+
+ // TODO: reverb/chorus?
+ switch (hdr.channels[nChn].status) {
+ case 0: // enabled; don't worry about it
break;
- case 1: /* mute */
- Chn[n].dwFlags |= CHN_MUTE;
+ case 1: // mute
+ ChnSettings[nChn].dwFlags |= CHN_MUTE;
break;
- case 2: /* disabled */
- Chn[n].dwFlags |= CHN_MUTE;
- ignore_channels |= (1 << n);
+ case 2: // disabled
+ ChnSettings[nChn].dwFlags |= CHN_MUTE;
+ ignore_channels |= (1 << nChn);
break;
- default: /* uhhhh.... freak out */
+ default: // uhhhh.... freak out
//fprintf(stderr, "imf: channel %d has unknown status %d\n", n, hdr.channels[n].status);
return false;
}
}
- for (; n < MAX_CHANNELS; n++)
- Chn[n].dwFlags |= CHN_MUTE;
- for (n = 0; n < hdr.ordnum; n++)
- Order[n] = ((hdr.orderlist[n] == 0xff) ? Order.GetIgnoreIndex() : hdr.orderlist[n]);
+ for (ORDERINDEX nOrd = 0; nOrd < hdr.ordnum; nOrd++)
+ Order[nOrd] = ((hdr.orderlist[nOrd] == 0xff) ? Order.GetIgnoreIndex() : hdr.orderlist[nOrd]);
- for (n = 0; n < hdr.patnum; n++)
- load_imf_pattern(this, n, ignore_channels, fp);
-
- dwMemPos = sizeof(IMFHEADER);
+ // read patterns
+ for (PATTERNINDEX nPat = 0; nPat < hdr.patnum; nPat++)
+ {
+ UINT16 length, nrows;
+ BYTE mask, channel;
+ int row;
+ unsigned int lostfx = 0;
+ MODCOMMAND *row_data, *note, junk_note;
- for (n = 0; n < hdr.insnum; n++) {
- // read the ins header
- struct IMFINSTRUMENT imfins;
+ ASSERT_CAN_READ(4);
+ length = LittleEndianW(*((UINT16 *)(lpStream + dwMemPos)));
+ nrows = LittleEndianW(*((UINT16 *)(lpStream + dwMemPos + 2)));
+ dwMemPos += 4;
+
+ if(Patterns.Insert(nPat, nrows))
+ {
+ CString s;
+ s.Format(TEXT("Allocating patterns failed starting from pattern %u"), nPat);
+ MessageBox(NULL, s, TEXT("OpenMPT IMF import"), MB_ICONERROR);
+ break;
+ }
+ row_data = Patterns[nPat];
+
+ row = 0;
+ while (row < nrows) {
+ ASSERT_CAN_READ(1);
+ mask = *((BYTE *)(lpStream + dwMemPos));
+ dwMemPos += 1;
+ if (mask == 0) {
+ row++;
+ row_data += 32;
+ continue;
+ }
+
+ channel = mask & 0x1f;
+
+ if (ignore_channels & (1 << channel)) {
+ /* should do this better, i.e. not go through the whole process of deciding
+ what to do with the effects since they're just being thrown out */
+ //printf("disabled channel %d contains data\n", channel + 1);
+ note = &junk_note;
+ } else {
+ note = row_data + channel;
+ }
+
+ if (mask & 0x20) {
+ // read note/instrument
+ ASSERT_CAN_READ(2);
+ note->note = *((BYTE *)(lpStream + dwMemPos));
+ note->instr = *((BYTE *)(lpStream + dwMemPos + 1));
+ dwMemPos += 2;
+
+ if (note->note == 160) {
+ note->note = NOTE_KEYOFF; /* ??? */
+ } else if (note->note == 255) {
+ note->note = NOTE_NONE; /* ??? */
+ } else {
+ note->note = (note->note >> 4) * 12 + (note->note & 0xf) + 12 + 1;
+ if (note->note > NOTE_MAX) {
+ /*printf("%d.%d.%d: funny note 0x%02x\n",
+ nPat, row, channel, fp->data[fp->pos - 1]);*/
+ note->note = NOTE_NONE;
+ }
+ }
+ }
+ if ((mask & 0xc0) == 0xc0) {
+ BYTE e1c, e1d, e2c, e2d;
+
+ // read both effects and figure out what to do with them
+ ASSERT_CAN_READ(4);
+ e1c = *((BYTE *)(lpStream + dwMemPos));
+ e1d = *((BYTE *)(lpStream + dwMemPos + 1));
+ e2c = *((BYTE *)(lpStream + dwMemPos + 2));
+ e2d = *((BYTE *)(lpStream + dwMemPos + 3));
+ dwMemPos += 4;
+
+ if (e1c == 0xc) {
+ note->vol = min(e1d, 0x40);
+ note->volcmd = VOLCMD_VOLUME;
+ note->command = e2c;
+ note->param = e2d;
+ } else if (e2c == 0xc) {
+ note->vol = min(e2d, 0x40);
+ note->volcmd = VOLCMD_VOLUME;
+ note->command = e1c;
+ note->param = e1d;
+ } else if (e1c == 0xa) {
+ note->vol = e1d * 64 / 255;
+ note->volcmd = VOLCMD_PANNING;
+ note->command = e2c;
+ note->param = e2d;
+ } else if (e2c == 0xa) {
+ note->vol = e2d * 64 / 255;
+ note->volcmd = VOLCMD_PANNING;
+ note->command = e1c;
+ note->param = e1d;
+ } else {
+ /* check if one of the effects is a 'global' effect
+ -- if so, put it in some unused channel instead.
+ otherwise pick the most important effect. */
+ lostfx++;
+ note->command = e2c;
+ note->param = e2d;
+ }
+ } else if (mask & 0xc0) {
+ // there's one effect, just stick it in the effect column
+ ASSERT_CAN_READ(2);
+ note->command = *((BYTE *)(lpStream + dwMemPos));
+ note->param = *((BYTE *)(lpStream + dwMemPos + 1));
+ dwMemPos += 2;
+ }
+ if (note->command)
+ import_imf_effect(note);
+ }
+ }
+
+ // read instruments
+ for (INSTRUMENTINDEX nIns = 0; nIns < hdr.insnum; nIns++) {
+ IMFINSTRUMENT imfins;
MODINSTRUMENT *ins;
- slurp_read(fp, &imfins, sizeof(imfins));
+ ASSERT_CAN_READ(sizeof(IMFINSTRUMENT));
+ memset(&imfins, 0, sizeof(IMFINSTRUMENT));
+ memcpy(&imfins, lpStream + dwMemPos, sizeof(IMFINSTRUMENT));
+ dwMemPos += sizeof(IMFINSTRUMENT);
+ m_nInstruments++;
imfins.smpnum = LittleEndianW(imfins.smpnum);
imfins.fadeout = LittleEndianW(imfins.fadeout);
@@ -452,16 +467,16 @@
ins = new MODINSTRUMENT;
if (!ins) continue;
- Instruments[n + 1] = ins;
+ Instruments[nIns + 1] = ins;
memset(ins, 0, sizeof(MODINSTRUMENT));
strncpy(ins->name, imfins.name, 25);
ins->name[25] = 0;
if (imfins.smpnum) {
- for (s = 0; s < 120; s++) {
- ins->NoteMap[s] = s + 1;
- ins->Keyboard[s] = firstsample + imfins.map[s];
+ for (BYTE cNote = 0; cNote < 120; cNote++) {
+ ins->NoteMap[cNote] = cNote + 1;
+ ins->Keyboard[cNote] = firstsample + imfins.map[cNote];
}
}
@@ -487,13 +502,16 @@
if (!(ins->dwFlags & ENV_VOLUME) && !ins->nFadeOut)
ins->nFadeOut = 8192;
- for (s = 0; s < imfins.smpnum; s++) {
+ // read this instrument's samples
+ for (SAMPLEINDEX nSmp = 0; nSmp < imfins.smpnum; nSmp++) {
IMFSAMPLE imfsmp;
UINT32 blen;
- if(dwMemPos + sizeof(IMFSAMPLE) > dwMemLength) break;
- memset(imfsmp, 0, sizeof(IMFSAMPLE));
- memcpy(imfsmp, lpStream + dwMemPos, sizeof(IMFSAMPLE));
-
+ ASSERT_CAN_READ(sizeof(IMFSAMPLE));
+ memset(&imfsmp, 0, sizeof(IMFSAMPLE));
+ memcpy(&imfsmp, lpStream + dwMemPos, sizeof(IMFSAMPLE));
+ dwMemPos += sizeof(IMFSAMPLE);
+ m_nSamples++;
+
if (memcmp(imfsmp.is10, "IS10", 4) != 0) {
//printf("is10 says %02x %02x %02x %02x!\n",
// imfsmp.is10[0], imfsmp.is10[1], imfsmp.is10[2], imfsmp.is10[3]);
@@ -502,13 +520,14 @@
strncpy(pSample->filename, imfsmp.filename, 12);
pSample->filename[12] = 0;
- strcpy(m_szNames[s + 1], pSample->filename);
+ strcpy(m_szNames[nSmp + 1], pSample->filename);
blen = pSample->nLength = LittleEndian(imfsmp.length);
pSample->nLoopStart = LittleEndian(imfsmp.loop_start);
pSample->nLoopEnd = LittleEndian(imfsmp.loop_end);
pSample->nC5Speed = LittleEndian(imfsmp.C5Speed);
- pSample->nVolume = imfsmp.volume * 4; //mphack
- pSample->nPan = imfsmp.panning; //mphack (IT uses 0-64, IMF uses the full 0-255)
+ pSample->nVolume = imfsmp.volume * 4;
+ pSample->nGlobalVol = 256;
+ pSample->nPan = imfsmp.panning;
if (imfsmp.flags & 1)
pSample->uFlags |= CHN_LOOP;
if (imfsmp.flags & 2)
@@ -522,20 +541,17 @@
if (imfsmp.flags & 8)
pSample->uFlags |= CHN_PANNING;
- if (!blen) {
- /* leave it blank */
- /*} else if (lflags & LOAD_NOSAMPLES) {
- slurp_seek(fp, blen, SEEK_CUR);*/
- } else {
- ReadSample(pSample, (imfsmp.flags & 4) ? RS_PCM8U : RS_PCM16U, reinterpret_cast<LPCSTR>(lpStream + iSampleOffset), blen);
+ if(blen)
+ {
+ ASSERT_CAN_READ(blen);
+ ReadSample(pSample, (imfsmp.flags & 4) ? RS_PCM16S : RS_PCM8S, reinterpret_cast<LPCSTR>(lpStream + dwMemPos), blen);
}
+ dwMemPos += blen;
pSample++;
- dwMemPos += sizeof(IMFSAMPLE);
}
firstsample += imfins.smpnum;
}
return true;
-}
-#endif
\ No newline at end of file
+}
\ No newline at end of file
Modified: trunk/OpenMPT/soundlib/Load_mo3.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_mo3.cpp 2009-08-16 11:55:06 UTC (rev 328)
+++ trunk/OpenMPT/soundlib/Load_mo3.cpp 2009-08-16 16:58:51 UTC (rev 329)
@@ -23,11 +23,15 @@
//-----------------------------------------------------------
{
// no valid MO3 file (magic bytes: "MO3")
- if(dwMemLength < 3 || lpStream[0] != 'M' || lpStream[1] != 'O' || lpStream[2] != '3')
+ if(dwMemLength < 4 || lpStream[0] != 'M' || lpStream[1] != 'O' || lpStream[2] != '3')
return false;
#ifdef NO_MO3_SUPPORT
- UNREFERENCED_PARAMETER(dwMemLength);
+ /* As of August 2009, the format revision is 5; Versions > 31 are unlikely to exist in the next few years,
+ so we will just ignore those if there's no UNMO3 library to tell us if the file is valid or not
+ (avoid messagebox with .MOD files that have a song name starting with "MO3" */
+ if(lpStream[3] > 31) return false;
+
AfxMessageBox(GetStrI18N(__TEXT("The file appears to be a MO3 file, but this OpenMPT build does not support loading MO3 files.")));
return false;
#else
Modified: trunk/OpenMPT/soundlib/Sndfile.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-08-16 11:55:06 UTC (rev 328)
+++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-08-16 16:58:51 UTC (rev 329)
@@ -593,8 +593,9 @@
#endif // MODPLUG_TRACKER
#endif
#endif // MODPLUG_BASIC_SUPPORT
+ && (!ReadGDM(lpStream, dwMemLength))
+ && (!ReadIMF(lpStream, dwMemLength))
&& (!ReadMO3(lpStream, dwMemLength))
- && (!ReadGDM(lpStream, dwMemLength))
&& (!ReadMod(lpStream, dwMemLength))) m_nType = MOD_TYPE_NONE;
#ifdef ZIPPED_MOD_SUPPORT
if ((!m_lpszSongComments) && (archive.GetComments(FALSE)))
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2009-08-16 11:55:18
|
Revision: 328
http://modplug.svn.sourceforge.net/modplug/?rev=328&view=rev
Author: saga-games
Date: 2009-08-16 11:55:06 +0000 (Sun, 16 Aug 2009)
Log Message:
-----------
[Fix] VST Editor: Patches are now saved in the folder specified by the user in the "save as" dialog (not the working directory)
[Ref] Refactoring, part 3: The three envelopes are now sub-structs of MODINSTRUMENT to reduce redundancy. Based on the new structs, more parts of the code could be optimized.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/AbstractVstEditor.cpp
trunk/OpenMPT/mptrack/Modedit.cpp
trunk/OpenMPT/mptrack/ScaleEnvPointsDlg.cpp
trunk/OpenMPT/mptrack/View_ins.cpp
trunk/OpenMPT/soundlib/Dlsbank.cpp
trunk/OpenMPT/soundlib/LOAD_DBM.CPP
trunk/OpenMPT/soundlib/Load_ams.cpp
trunk/OpenMPT/soundlib/Load_imf.cpp
trunk/OpenMPT/soundlib/Load_it.cpp
trunk/OpenMPT/soundlib/Load_mdl.cpp
trunk/OpenMPT/soundlib/Load_mid.cpp
trunk/OpenMPT/soundlib/Load_mt2.cpp
trunk/OpenMPT/soundlib/Load_xm.cpp
trunk/OpenMPT/soundlib/Sampleio.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/AbstractVstEditor.cpp
===================================================================
--- trunk/OpenMPT/mptrack/AbstractVstEditor.cpp 2009-08-16 11:46:32 UTC (rev 327)
+++ trunk/OpenMPT/mptrack/AbstractVstEditor.cpp 2009-08-16 11:55:06 UTC (rev 328)
@@ -113,8 +113,8 @@
if (m_pVstPlugin)
{
CFileDialog dlg(TRUE, "fxp", NULL,
- OFN_HIDEREADONLY| OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST | OFN_ENABLESIZING | OFN_NOREADONLYRETURN,
- "VST Program (*.fxp)|*.fxp||", theApp.m_pMainWnd);
+ OFN_HIDEREADONLY| OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST | OFN_ENABLESIZING | OFN_NOREADONLYRETURN,
+ "VST Program (*.fxp)|*.fxp||", theApp.m_pMainWnd);
const LPCTSTR pszWdir = CMainFrame::GetWorkingDirectory(DIR_PLUGINPRESETS);
if(pszWdir[0])
dlg.m_ofn.lpstrInitialDir = pszWdir;
@@ -122,10 +122,11 @@
if (!(dlg.DoModal() == IDOK)) return;
- CMainFrame::SetWorkingDirectory(dlg.GetFileName(), DIR_PLUGINPRESETS, true);
+ CString sFile = dlg.GetPathName();
+ CMainFrame::SetWorkingDirectory(sFile, DIR_PLUGINPRESETS, true);
//TODO: exception handling to distinguish errors at this level.
- if (!(m_pVstPlugin->LoadProgram(dlg.GetFileName())))
+ if (!(m_pVstPlugin->LoadProgram(sFile)))
::AfxMessageBox("Error loading preset. Are you sure it is for this plugin?");
}
}
@@ -136,17 +137,18 @@
if (m_pVstPlugin)
{
CFileDialog dlg(FALSE, "fxp", NULL,
- OFN_HIDEREADONLY| OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST | OFN_ENABLESIZING | OFN_NOREADONLYRETURN,
- "VST Program (*.fxp)|*.fxp||", theApp.m_pMainWnd);
+ OFN_HIDEREADONLY| OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST | OFN_ENABLESIZING | OFN_NOREADONLYRETURN,
+ "VST Program (*.fxp)|*.fxp||", theApp.m_pMainWnd);
const LPCTSTR pszWdir = CMainFrame::GetWorkingDirectory(DIR_PLUGINPRESETS);
if(pszWdir[0])
dlg.m_ofn.lpstrInitialDir = pszWdir;
if (!(dlg.DoModal() == IDOK)) return;
- CMainFrame::SetWorkingDirectory(dlg.GetFileName(), DIR_PLUGINPRESETS, true);
+ CString sFile = dlg.GetPathName();
+ CMainFrame::SetWorkingDirectory(sFile, DIR_PLUGINPRESETS, true);
//TODO: exception handling
- if (!(m_pVstPlugin->SaveProgram(dlg.GetFileName())))
+ if (!(m_pVstPlugin->SaveProgram(sFile)))
::AfxMessageBox("Error saving preset.");
}
return;
Modified: trunk/OpenMPT/mptrack/Modedit.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-16 11:46:32 UTC (rev 327)
+++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-08-16 11:55:06 UTC (rev 328)
@@ -2323,45 +2323,45 @@
switch(nEnv)
{
case ENV_PANNING:
- pPoints = pIns->PanPoints;
- pValues = pIns->PanEnv;
- nPoints = pIns->nPanEnv;
+ pPoints = pIns->PanEnv.Ticks;
+ pValues = pIns->PanEnv.Values;
+ nPoints = pIns->PanEnv.nNodes;
bLoop = (pIns->dwFlags & ENV_PANLOOP) ? TRUE : FALSE;
bSus = (pIns->dwFlags & ENV_PANSUSTAIN) ? TRUE : FALSE;
bCarry = (pIns->dwFlags & ENV_PANCARRY) ? TRUE : FALSE;
- susBegin = pIns->nPanSustainBegin;
- susEnd = pIns->nPanSustainEnd;
- loopBegin = pIns->nPanLoopStart;
- loopEnd = pIns->nPanLoopEnd;
- releaseNode = pIns->nPanEnvReleaseNode;
+ susBegin = pIns->PanEnv.nSustainStart;
+ susEnd = pIns->PanEnv.nSustainEnd;
+ loopBegin = pIns->PanEnv.nLoopStart;
+ loopEnd = pIns->PanEnv.nLoopEnd;
+ releaseNode = pIns->PanEnv.nReleaseNode;
break;
case ENV_PITCH:
- pPoints = pIns->PitchPoints;
- pValues = pIns->PitchEnv;
- nPoints = pIns->nPitchEnv;
+ pPoints = pIns->PitchEnv.Ticks;
+ pValues = pIns->PitchEnv.Values;
+ nPoints = pIns->PitchEnv.nNodes;
bLoop = (pIns->dwFlags & ENV_PITCHLOOP) ? TRUE : FALSE;
bSus = (pIns->dwFlags & ENV_PITCHSUSTAIN) ? TRUE : FALSE;
bCarry = (pIns->dwFlags & ENV_PITCHCARRY) ? TRUE : FALSE;
- susBegin = pIns->nPitchSustainBegin;
- susEnd = pIns->nPitchSustainEnd;
- loopBegin = pIns->nPitchLoopStart;
- loopEnd = pIns->nPitchLoopEnd;
- releaseNode = pIns->nPitchEnvReleaseNode;
+ susBegin = pIns->PitchEnv.nSustainStart;
+ susEnd = pIns->PitchEnv.nSustainEnd;
+ loopBegin = pIns->PitchEnv.nLoopStart;
+ loopEnd = pIns->PitchEnv.nLoopEnd;
+ releaseNode = pIns->PitchEnv.nReleaseNode;
break;
default:
- pPoints = pIns->VolPoints;
- pValues = pIns->VolEnv;
- nPoints = pIns->nVolEnv;
+ pPoints = pIns->VolEnv.Ticks;
+ pValues = pIns->VolEnv.Values;
+ nPoints = pIns->VolEnv.nNodes;
bLoop = (pIns->dwFlags & ENV_VOLLOOP) ? TRUE : FALSE;
bSus = (pIns->dwFlags & ENV_VOLSUSTAIN) ? TRUE : FALSE;
bCarry = (pIns->dwFlags & ENV_VOLCARRY) ? TRUE : FALSE;
- susBegin = pIns->nVolSustainBegin;
- susEnd = pIns->nVolSustainEnd;
- loopBegin = pIns->nVolLoopStart;
- loopEnd = pIns->nVolLoopEnd;
- releaseNode = pIns->nVolEnvReleaseNode;
+ susBegin = pIns->VolEnv.nSustainStart;
+ susEnd = pIns->VolEnv.nSustainEnd;
+ loopBegin = pIns->VolEnv.nLoopStart;
+ loopEnd = pIns->VolEnv.nLoopEnd;
+ releaseNode = pIns->VolEnv.nReleaseNode;
break;
}
strcpy(s, pszEnvHdr);
@@ -2440,48 +2440,48 @@
switch(nEnv)
{
case ENV_PANNING:
- pPoints = pIns->PanPoints;
- pValues = pIns->PanEnv;
- pIns->nPanEnv = nPoints;
+ pPoints = pIns->PanEnv.Ticks;
+ pValues = pIns->PanEnv.Values;
+ pIns->PanEnv.nNodes = nPoints;
pIns->dwFlags &= ~(ENV_PANLOOP|ENV_PANSUSTAIN|ENV_PANCARRY);
if (bLoop) pIns->dwFlags |= ENV_PANLOOP;
if (bSus) pIns->dwFlags |= ENV_PANSUSTAIN;
if (bCarry) pIns->dwFlags |= ENV_PANCARRY;
- pIns->nPanSustainBegin = susBegin;
- pIns->nPanSustainEnd = susEnd;
- pIns->nPanLoopStart = loopBegin;
- pIns->nPanLoopEnd = loopEnd;
- pIns->nPanEnvReleaseNode = releaseNode;
+ pIns->PanEnv.nSustainStart = susBegin;
+ pIns->PanEnv.nSustainEnd = susEnd;
+ pIns->PanEnv.nLoopStart = loopBegin;
+ pIns->PanEnv.nLoopEnd = loopEnd;
+ pIns->PanEnv.nReleaseNode = releaseNode;
break;
case ENV_PITCH:
- pPoints = pIns->PitchPoints;
- pValues = pIns->PitchEnv;
- pIns->nPitchEnv = nPoints;
+ pPoints = pIns->PitchEnv.Ticks;
+ pValues = pIns->PitchEnv.Values;
+ pIns->PitchEnv.nNodes = nPoints;
pIns->dwFlags &= ~(ENV_PITCHLOOP|ENV_PITCHSUSTAIN|ENV_PITCHCARRY);
if (bLoop) pIns->dwFlags |= ENV_PITCHLOOP;
if (bSus) pIns->dwFlags |= ENV_PITCHSUSTAIN;
if (bCarry) pIns->dwFlags |= ENV_PITCHCARRY;
- pIns->nPitchSustainBegin = susBegin;
- pIns->nPitchSustainEnd = susEnd;
- pIns->nPitchLoopStart = loopBegin;
- pIns->nPitchLoopEnd = loopEnd;
- pIns->nPitchEnvReleaseNode = releaseNode;
+ pIns->PitchEnv.nSustainStart = susBegin;
+ pIns->PitchEnv.nSustainEnd = susEnd;
+ pIns->PitchEnv.nLoopStart = loopBegin;
+ pIns->PitchEnv.nLoopEnd = loopEnd;
+ pIns->PitchEnv.nReleaseNode = releaseNode;
break;
default:
- pPoints = pIns->VolPoints;
- pValues = pIns->VolEnv;
- pIns->nVolEnv = nPoints;
+ pPoints = pIns->VolEnv.Ticks;
+ pValues = pIns->VolEnv.Values;
+ pIns->VolEnv.nNodes = nPoints;
pIns->dwFlags &= ~(ENV_VOLLOOP|ENV_VOLSUSTAIN|ENV_VOLCARRY);
if (bLoop) pIns->dwFlags |= ENV_VOLLOOP;
if (bSus) pIns->dwFlags |= ENV_VOLSUSTAIN;
if (bCarry) pIns->dwFlags |= ENV_VOLCARRY;
- pIns->nVolSustainBegin = susBegin;
- pIns->nVolSustainEnd = susEnd;
- pIns->nVolLoopStart = loopBegin;
- pIns->nVolLoopEnd = loopEnd;
- pIns->nVolEnvReleaseNode = releaseNode;
+ pIns->VolEnv.nSustainStart = susBegin;
+ pIns->VolEnv.nSustainEnd = susEnd;
+ pIns->VolEnv.nLoopStart = loopBegin;
+ pIns->VolEnv.nLoopEnd = loopEnd;
+ pIns->VolEnv.nReleaseNode = releaseNode;
break;
}
int oldn = 0;
@@ -2510,15 +2510,15 @@
switch(nEnv)
{
case ENV_PANNING:
- pIns->nPanEnvReleaseNode = r;
+ pIns->PanEnv.nReleaseNode = r;
break;
case ENV_PITCH:
- pIns->nPitchEnvReleaseNode = r;
+ pIns->PitchEnv.nReleaseNode = r;
break;
default:
- pIns->nVolEnvReleaseNode = r;
+ pIns->VolEnv.nReleaseNode = r;
break;
}
}
Modified: trunk/OpenMPT/mptrack/ScaleEnvPointsDlg.cpp
===================================================================
--- trunk/OpenMPT/mptrack/ScaleEnvPointsDlg.cpp 2009-08-16 11:46:32 UTC (rev 327)
+++ trunk/OpenMPT/mptrack/ScaleEnvPointsDlg.cpp 2009-08-16 11:55:06 UTC (rev 328)
@@ -50,18 +50,18 @@
switch(m_Env)
{
case ENV_VOLUME:
- array = &m_pInstrument->VolPoints;
- arraySize = &m_pInstrument->nVolEnv;
+ array = &m_pInstrument->VolEnv.Ticks;
+ arraySize = &m_pInstrument->VolEnv.nNodes;
break;
case ENV_PANNING:
- array = &m_pInstrument->PanPoints;
- arraySize = &m_pInstrument->nPanEnv;
+ array = &m_pInstrument->PanEnv.Ticks;
+ arraySize = &m_pInstrument->PanEnv.nNodes;
break;
case ENV_PITCH:
- array = &m_pInstrument->PitchPoints;
- arraySize = &m_pInstrument->nPitchEnv;
+ array = &m_pInstrument->PitchEnv.Ticks;
+ arraySize = &m_pInstrument->PitchEnv.nNodes;
break;
}
Modified: trunk/OpenMPT/mptrack/View_ins.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_ins.cpp 2009-08-16 11:46:32 UTC (rev 327)
+++ trunk/OpenMPT/mptrack/View_ins.cpp 2009-08-16 11:55:06 UTC (rev 328)
@@ -225,13 +225,13 @@
switch(m_nEnv)
{
case ENV_VOLUME:
- if (nPoint < (int)pIns->nVolEnv) return pIns->VolPoints[nPoint];
+ if (nPoint < (int)pIns->VolEnv.nNodes) return pIns->VolEnv.Ticks[nPoint];
break;
case ENV_PANNING:
- if (nPoint < (int)pIns->nPanEnv) return pIns->PanPoints[nPoint];
+ if (nPoint < (int)pIns->PanEnv.nNodes) return pIns->PanEnv.Ticks[nPoint];
break;
case ENV_PITCH:
- if (nPoint < (int)pIns->nPitchEnv) return pIns->PitchPoints[nPoint];
+ if (nPoint < (int)pIns->PitchEnv.nNodes) return pIns->PitchEnv.Ticks[nPoint];
break;
}
}
@@ -253,13 +253,13 @@
switch(m_nEnv)
{
case ENV_VOLUME:
- if (nPoint < (int)pIns->nVolEnv) return pIns->VolEnv[nPoint];
+ if (nPoint < (int)pIns->VolEnv.nNodes) return pIns->VolEnv.Values[nPoint];
break;
case ENV_PANNING:
- if (nPoint < (int)pIns->nPanEnv) return pIns->PanEnv[nPoint];
+ if (nPoint < (int)pIns->PanEnv.nNodes) return pIns->PanEnv.Values[nPoint];
break;
case ENV_PITCH:
- if (nPoint < (int)pIns->nPitchEnv) return pIns->PitchEnv[nPoint];
+ if (nPoint < (int)pIns->PitchEnv.nNodes) return pIns->PitchEnv.Values[nPoint];
break;
}
}
@@ -285,19 +285,19 @@
switch(m_nEnv)
{
case ENV_VOLUME:
- maxpoints = pIns->nVolEnv;
- pPoints = pIns->VolPoints;
- pData = pIns->VolEnv;
+ maxpoints = pIns->VolEnv.nNodes;
+ pPoints = pIns->VolEnv.Ticks;
+ pData = pIns->VolEnv.Values;
break;
case ENV_PANNING:
- maxpoints = pIns->nPanEnv;
- pPoints = pIns->PanPoints;
- pData = pIns->PanEnv;
+ maxpoints = pIns->PanEnv.nNodes;
+ pPoints = pIns->PanEnv.Ticks;
+ pData = pIns->PanEnv.Values;
break;
case ENV_PITCH:
- maxpoints = pIns->nPitchEnv;
- pPoints = pIns->PitchPoints;
- pData = pIns->PitchEnv;
+ maxpoints = pIns->PitchEnv.nNodes;
+ pPoints = pIns->PitchEnv.Ticks;
+ pData = pIns->PitchEnv.Values;
break;
}
if (!nPoint) nTick = 0;
@@ -345,13 +345,13 @@
switch(m_nEnv)
{
case ENV_VOLUME:
- if (pIns->nVolEnv) return pIns->nVolEnv;
+ if (pIns->VolEnv.nNodes) return pIns->VolEnv.nNodes;
break;
case ENV_PANNING:
- if (pIns->nPanEnv) return pIns->nPanEnv;
+ if (pIns->PanEnv.nNodes) return pIns->PanEnv.nNodes;
break;
case ENV_PITCH:
- if (pIns->nPitchEnv) return pIns->nPitchEnv;
+ if (pIns->PitchEnv.nNodes) return pIns->PitchEnv.nNodes;
break;
}
}
@@ -465,9 +465,9 @@
{
switch(m_nEnv)
{
- case ENV_VOLUME: return pIns->nVolLoopStart;
- case ENV_PANNING: return pIns->nPanLoopStart;
- case ENV_PITCH: return pIns->nPitchLoopStart;
+ case ENV_VOLUME: return pIns->VolEnv.nLoopStart;
+ case ENV_PANNING: return pIns->PanEnv.nLoopStart;
+ case ENV_PITCH: return pIns->PitchEnv.nLoopStart;
}
}
}
@@ -487,9 +487,9 @@
{
switch(m_nEnv)
{
- case ENV_VOLUME: return pIns->nVolLoopEnd;
- case ENV_PANNING: return pIns->nPanLoopEnd;
- case ENV_PITCH: return pIns->nPitchLoopEnd;
+ case ENV_VOLUME: return pIns->VolEnv.nLoopEnd;
+ case ENV_PANNING: return pIns->PanEnv.nLoopEnd;
+ case ENV_PITCH: return pIns->PitchEnv.nLoopEnd;
}
}
}
@@ -509,9 +509,9 @@
{
switch(m_nEnv)
{
- case ENV_VOLUME: return pIns->nVolSustainBegin;
- case ENV_PANNING: return pIns->nPanSustainBegin;
- case ENV_PITCH: return pIns->nPitchSustainBegin;
+ case ENV_VOLUME: return pIns->VolEnv.nSustainStart;
+ case ENV_PANNING: return pIns->PanEnv.nSustainStart;
+ case ENV_PITCH: return pIns->PitchEnv.nSustainStart;
}
}
}
@@ -531,9 +531,9 @@
{
switch(m_nEnv)
{
- case ENV_VOLUME: return pIns->nVolSustainEnd;
- case ENV_PANNING: return pIns->nPanSustainEnd;
- case ENV_PITCH: return pIns->nPitchSustainEnd;
+ case ENV_VOLUME: return pIns->VolEnv.nSustainEnd;
+ case ENV_PANNING: return pIns->PanEnv.nSustainEnd;
+ case ENV_PITCH: return pIns->PitchEnv.nSustainEnd;
}
}
}
@@ -610,26 +610,26 @@
switch(m_nEnv)
{
case ENV_VOLUME:
- if (nPoint != pIns->nVolLoopStart)
+ if (nPoint != pIns->VolEnv.nLoopStart)
{
- pIns->nVolLoopStart = (BYTE)nPoint;
- if (pIns->nVolLoopEnd < nPoint) pIns->nVolLoopEnd = (BYTE)nPoint;
+ pIns->VolEnv.nLoopStart = (BYTE)nPoint;
+ if (pIns->VolEnv.nLoopEnd < nPoint) pIns->VolEnv.nLoopEnd = (BYTE)nPoint;
return TRUE;
}
break;
case ENV_PANNING:
- if (nPoint != pIns->nPanLoopStart)
+ if (nPoint != pIns->PanEnv.nLoopStart)
{
- pIns->nPanLoopStart = (BYTE)nPoint;
- if (pIns->nPanLoopEnd < nPoint) pIns->nPanLoopEnd = (BYTE)nPoint;
+ pIns->PanEnv.nLoopStart = (BYTE)nPoint;
+ if (pIns->PanEnv.nLoopEnd < nPoint) pIns->PanEnv.nLoopEnd = (BYTE)nPoint;
return TRUE;
}
break;
case ENV_PITCH:
- if (nPoint != pIns->nPitchLoopStart)
+ if (nPoint != pIns->PitchEnv.nLoopStart)
{
- pIns->nPitchLoopStart = (BYTE)nPoint;
- if (pIns->nPitchLoopEnd < nPoint) pIns->nPitchLoopEnd = (BYTE)nPoint;
+ pIns->PitchEnv.nLoopStart = (BYTE)nPoint;
+ if (pIns->PitchEnv.nLoopEnd < nPoint) pIns->PitchEnv.nLoopEnd = (BYTE)nPoint;
return TRUE;
}
break;
@@ -653,26 +653,26 @@
switch(m_nEnv)
{
case ENV_VOLUME:
- if (nPoint != pIns->nVolLoopEnd)
+ if (nPoint != pIns->VolEnv.nLoopEnd)
{
- pIns->nVolLoopEnd = (BYTE)nPoint;
- if (pIns->nVolLoopStart > nPoint) pIns->nVolLoopStart = (BYTE)nPoint;
+ pIns->VolEnv.nLoopEnd = (BYTE)nPoint;
+ if (pIns->VolEnv.nLoopStart > nPoint) pIns->VolEnv.nLoopStart = (BYTE)nPoint;
return TRUE;
}
break;
case ENV_PANNING:
- if (nPoint != pIns->nPanLoopEnd)
+ if (nPoint != pIns->PanEnv.nLoopEnd)
{
- pIns->nPanLoopEnd = (BYTE)nPoint;
- if (pIns->nPanLoopStart > nPoint) pIns->nPanLoopStart = (BYTE)nPoint;
+ pIns->PanEnv.nLoopEnd = (BYTE)nPoint;
+ if (pIns->PanEnv.nLoopStart > nPoint) pIns->PanEnv.nLoopStart = (BYTE)nPoint;
return TRUE;
}
break;
case ENV_PITCH:
- if (nPoint != pIns->nPitchLoopEnd)
+ if (nPoint != pIns->PitchEnv.nLoopEnd)
{
- pIns->nPitchLoopEnd = (BYTE)nPoint;
- if (pIns->nPitchLoopStart > nPoint) pIns->nPitchLoopStart = (BYTE)nPoint;
+ pIns->PitchEnv.nLoopEnd = (BYTE)nPoint;
+ if (pIns->PitchEnv.nLoopStart > nPoint) pIns->PitchEnv.nLoopStart = (BYTE)nPoint;
return TRUE;
}
break;
@@ -696,26 +696,26 @@
switch(m_nEnv)
{
case ENV_VOLUME:
- if (nPoint != pIns->nVolSustainBegin)
+ if (nPoint != pIns->VolEnv.nSustainStart)
{
- pIns->nVolSustainBegin = (BYTE)nPoint;
- if ((pIns->nVolSustainEnd < nPoint) || (pSndFile->m_nType & MOD_TYPE_XM)) pIns->nVolSustainEnd = (BYTE)nPoint;
+ pIns->VolEnv.nSustainStart = (BYTE)nPoint;
+ if ((pIns->VolEnv.nSustainEnd < nPoint) || (pSndFile->m_nType & MOD_TYPE_XM)) pIns->VolEnv.nSustainEnd = (BYTE)nPoint;
return TRUE;
}
break;
case ENV_PANNING:
- if (nPoint != pIns->nPanSustainBegin)
+ if (nPoint != pIns->PanEnv.nSustainStart)
{
- pIns->nPanSustainBegin = (BYTE)nPoint;
- if ((pIns->nPanSustainEnd < nPoint) || (pSndFile->m_nType & MOD_TYPE_XM)) pIns->nPanSustainEnd = (BYTE)nPoint;
+ pIns->PanEnv.nSustainStart = (BYTE)nPoint;
+ if ((pIns->PanEnv.nSustainEnd < nPoint) || (pSndFile->m_nType & MOD_TYPE_XM)) pIns->PanEnv.nSustainEnd = (BYTE)nPoint;
return TRUE;
}
break;
case ENV_PITCH:
- if (nPoint != pIns->nPitchSustainBegin)
+ if (nPoint != pIns->PitchEnv.nSustainStart)
{
- pIns->nPitchSustainBegin = (BYTE)nPoint;
- if ((pIns->nPitchSustainEnd < nPoint) || (pSndFile->m_nType & MOD_TYPE_XM)) pIns->nPitchSustainEnd = (BYTE)nPoint;
+ pIns->PitchEnv.nSustainStart = (BYTE)nPoint;
+ if ((pIns->PitchEnv.nSustainEnd < nPoint) || (pSndFile->m_nType & MOD_TYPE_XM)) pIns->PitchEnv.nSustainEnd = (BYTE)nPoint;
return TRUE;
}
break;
@@ -739,26 +739,26 @@
switch(m_nEnv)
{
case ENV_VOLUME:
- if (nPoint != pIns->nVolSustainEnd)
+ if (nPoint != pIns->VolEnv.nSustainEnd)
{
- pIns->nVolSustainEnd = (BYTE)nPoint;
- if ((pIns->nVolSustainBegin > nPoint) || (pSndFile->m_nType & MOD_TYPE_XM)) pIns->nVolSustainBegin = (BYTE)nPoint;
+ pIns->VolEnv.nSustainEnd = (BYTE)nPoint;
+ if ((pIns->VolEnv.nSustainStart > nPoint) || (pSndFile->m_nType & MOD_TYPE_XM)) pIns->VolEnv.nSustainStart = (BYTE)nPoint;
return TRUE;
}
break;
case ENV_PANNING:
- if (nPoint != pIns->nPanSustainEnd)
+ if (nPoint != pIns->PanEnv.nSustainEnd)
{
- pIns->nPanSustainEnd = (BYTE)nPoint;
- if ((pIns->nPanSustainBegin > nPoint) || (pSndFile->m_nType & MOD_TYPE_XM)) pIns->nPanSustainBegin = (BYTE)nPoint;
+ pIns->PanEnv.nSustainEnd = (BYTE)nPoint;
+ if ((pIns->PanEnv.nSustainStart > nPoint) || (pSndFile->m_nType & MOD_TYPE_XM)) pIns->PanEnv.nSustainStart = (BYTE)nPoint;
return TRUE;
}
break;
case ENV_PITCH:
- if (nPoint != pIns->nPitchSustainEnd)
+ if (nPoint != pIns->PitchEnv.nSustainEnd)
{
- pIns->nPitchSustainEnd = (BYTE)nPoint;
- if ((pIns->nPitchSustainBegin > nPoint) || (pSndFile->m_nType & MOD_TYPE_XM)) pIns->nPitchSustainBegin = (BYTE)nPoint;
+ pIns->PitchEnv.nSustainEnd = (BYTE)nPoint;
+ if ((pIns->PitchEnv.nSustainStart > nPoint) || (pSndFile->m_nType & MOD_TYPE_XM)) pIns->PitchEnv.nSustainStart = (BYTE)nPoint;
return TRUE;
}
break;
@@ -899,13 +899,13 @@
if (bEnable)
{
pIns->dwFlags |= ENV_VOLUME;
- if (!pIns->nVolEnv)
+ if (!pIns->VolEnv.nNodes)
{
- pIns->VolEnv[0] = 64;
- pIns->VolEnv[1] = 64;
- pIns->VolPoints[0] = 0;
- pIns->VolPoints[1] = 10;
- pIns->nVolEnv = 2;
+ pIns->VolEnv.Values[0] = 64;
+ pIns->VolEnv.Values[1] = 64;
+ pIns->VolEnv.Ticks[0] = 0;
+ pIns->VolEnv.Ticks[1] = 10;
+ pIns->VolEnv.nNodes = 2;
InvalidateRect(NULL, FALSE);
}
} else
@@ -932,13 +932,13 @@
if (bEnable)
{
pIns->dwFlags |= ENV_PANNING;
- if (!pIns->nPanEnv)
+ if (!pIns->PanEnv.nNodes)
{
- pIns->PanEnv[0] = 32;
- pIns->PanEnv[1] = 32;
- pIns->PanPoints[0] = 0;
- pIns->PanPoints[1] = 10;
- pIns->nPanEnv = 2;
+ pIns->PanEnv.Values[0] = 32;
+ pIns->PanEnv.Values[1] = 32;
+ pIns->PanEnv.Ticks[0] = 0;
+ pIns->PanEnv.Ticks[1] = 10;
+ pIns->PanEnv.nNodes = 2;
InvalidateRect(NULL, FALSE);
}
} else
@@ -966,13 +966,13 @@
{
pIns->dwFlags |= ENV_PITCH;
pIns->dwFlags &= ~ENV_FILTER;
- if (!pIns->nPitchEnv)
+ if (!pIns->PitchEnv.nNodes)
{
- pIns->PitchEnv[0] = 32;
- pIns->PitchEnv[1] = 32;
- pIns->PitchPoints[0] = 0;
- pIns->PitchPoints[1] = 10;
- pIns->nPitchEnv = 2;
+ pIns->PitchEnv.Values[0] = 32;
+ pIns->PitchEnv.Values[1] = 32;
+ pIns->PitchEnv.Ticks[0] = 0;
+ pIns->PitchEnv.Ticks[1] = 10;
+ pIns->PitchEnv.nNodes = 2;
InvalidateRect(NULL, FALSE);
}
} else
@@ -999,13 +999,13 @@
if ((bEnable) && (pSndFile->m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT)))
{
pIns->dwFlags |= (ENV_PITCH|ENV_FILTER);
- if (!pIns->nPitchEnv)
+ if (!pIns->PitchEnv.nNodes)
{
- pIns->PitchEnv[0] = 64;
- pIns->PitchEnv[1] = 64;
- pIns->PitchPoints[0] = 0;
- pIns->PitchPoints[1] = 10;
- pIns->nPitchEnv = 2;
+ pIns->PitchEnv.Values[0] = 64;
+ pIns->PitchEnv.Values[1] = 64;
+ pIns->PitchEnv.Ticks[0] = 0;
+ pIns->PitchEnv.Ticks[1] = 10;
+ pIns->PitchEnv.nNodes = 2;
InvalidateRect(NULL, FALSE);
}
} else
@@ -1360,11 +1360,11 @@
if (pIns) {
switch(m_nEnv) {
case ENV_VOLUME:
- return pIns->nVolEnvReleaseNode;
+ return pIns->VolEnv.nReleaseNode;
case ENV_PANNING:
- return pIns->nPanEnvReleaseNode;
+ return pIns->PanEnv.nReleaseNode;
case ENV_PITCH:
- return pIns->nPitchEnvReleaseNode;
+ return pIns->PitchEnv.nReleaseNode;
default:
return ENV_RELEASE_NODE_UNSET;
}
@@ -1383,11 +1383,11 @@
if (pIns) {
switch(m_nEnv) {
case ENV_VOLUME:
- return pIns->VolEnv[EnvGetReleaseNode()];
+ return pIns->VolEnv.Values[EnvGetReleaseNode()];
case ENV_PANNING:
- return pIns->PanEnv[EnvGetReleaseNode()];
+ return pIns->PanEnv.Values[EnvGetReleaseNode()];
case ENV_PITCH:
- return pIns->PitchEnv[EnvGetReleaseNode()];
+ return pIns->PitchEnv.Values[EnvGetReleaseNode()];
default:
return 0;
}
@@ -1406,11 +1406,11 @@
if (pIns) {
switch(m_nEnv) {
case ENV_VOLUME:
- return pIns->VolPoints[EnvGetReleaseNode()];
+ return pIns->VolEnv.Ticks[EnvGetReleaseNode()];
case ENV_PANNING:
- return pIns->PanPoints[EnvGetReleaseNode()];
+ return pIns->PanEnv.Ticks[EnvGetReleaseNode()];
case ENV_PITCH:
- return pIns->PitchPoints[EnvGetReleaseNode()];
+ return pIns->PitchEnv.Ticks[EnvGetReleaseNode()];
default:
return 0;
}
@@ -2056,24 +2056,24 @@
MODINSTRUMENT *pIns = pSndFile->Instruments[m_nInstrument];
switch(m_nEnv) {
case ENV_VOLUME:
- if (pIns->nVolEnvReleaseNode == node) {
- pIns->nVolEnvReleaseNode = ENV_RELEASE_NODE_UNSET;
+ if (pIns->VolEnv.nReleaseNode == node) {
+ pIns->VolEnv.nReleaseNode = ENV_RELEASE_NODE_UNSET;
} else {
- pIns->nVolEnvReleaseNode = node;
+ pIns->VolEnv.nReleaseNode = node;
}
break;
case ENV_PANNING:
- if (pIns->nPanEnvReleaseNode == node) {
- pIns->nPanEnvReleaseNode = ENV_RELEASE_NODE_UNSET;
+ if (pIns->PanEnv.nReleaseNode == node) {
+ pIns->PanEnv.nReleaseNode = ENV_RELEASE_NODE_UNSET;
} else {
- pIns->nPanEnvReleaseNode = node;
+ pIns->PanEnv.nReleaseNode = node;
}
break;
case ENV_PITCH:
- if (pIns->nPitchEnvReleaseNode == node) {
- pIns->nPitchEnvReleaseNode = ENV_RELEASE_NODE_UNSET;
+ if (pIns->PitchEnv.nReleaseNode == node) {
+ pIns->PitchEnv.nReleaseNode = ENV_RELEASE_NODE_UNSET;
} else {
- pIns->nPitchEnvReleaseNode = node;
+ pIns->PitchEnv.nReleaseNode = node;
}
break;
}
@@ -2159,59 +2159,59 @@
switch(m_nEnv)
{
case ENV_VOLUME:
- if (pIns->nVolEnv > 1)
+ if (pIns->VolEnv.nNodes > 1)
{
- pIns->nVolEnv--;
- for (UINT i=nPoint; i<pIns->nVolEnv; i++)
+ pIns->VolEnv.nNodes--;
+ for (UINT i=nPoint; i<pIns->VolEnv.nNodes; i++)
{
- pIns->VolPoints[i] = pIns->VolPoints[i+1];
- pIns->VolEnv[i] = pIns->VolEnv[i+1];
+ pIns->VolEnv.Ticks[i] = pIns->VolEnv.Ticks[i+1];
+ pIns->VolEnv.Values[i] = pIns->VolEnv.Values[i+1];
}
- if (nPoint >= pIns->nVolEnv) nPoint = pIns->nVolEnv-1;
- if (pIns->nVolLoopStart > nPoint) pIns->nVolLoopStart--;
- if (pIns->nVolLoopEnd > nPoint) pIns->nVolLoopEnd--;
- if (pIns->nVolSustainBegin > nPoint) pIns->nVolSustainBegin--;
- if (pIns->nVolSustainEnd > nPoint) pIns->nVolSustainEnd--;
- if (pIns->nVolEnvReleaseNode>nPoint && pIns->nVolEnvReleaseNode!=ENV_RELEASE_NODE_UNSET) pIns->nVolEnvReleaseNode--;
- pIns->VolPoints[0] = 0;
+ if (nPoint >= pIns->VolEnv.nNodes) nPoint = pIns->VolEnv.nNodes-1;
+ if (pIns->VolEnv.nLoopStart > nPoint) pIns->VolEnv.nLoopStart--;
+ if (pIns->VolEnv.nLoopEnd > nPoint) pIns->VolEnv.nLoopEnd--;
+ if (pIns->VolEnv.nSustainStart > nPoint) pIns->VolEnv.nSustainStart--;
+ if (pIns->VolEnv.nSustainEnd > nPoint) pIns->VolEnv.nSustainEnd--;
+ if (pIns->VolEnv.nReleaseNode>nPoint && pIns->VolEnv.nReleaseNode!=ENV_RELEASE_NODE_UNSET) pIns->VolEnv.nReleaseNode--;
+ pIns->VolEnv.Ticks[0] = 0;
bOk = TRUE;
}
break;
case ENV_PANNING:
- if (pIns->nPanEnv > 1)
+ if (pIns->PanEnv.nNodes > 1)
{
- pIns->nPanEnv--;
- for (UINT i=nPoint; i<pIns->nPanEnv; i++)
+ pIns->PanEnv.nNodes--;
+ for (UINT i=nPoint; i<pIns->PanEnv.nNodes; i++)
{
- pIns->PanPoints[i] = pIns->PanPoints[i+1];
- pIns->PanEnv[i] = pIns->PanEnv[i+1];
+ pIns->PanEnv.Ticks[i] = pIns->PanEnv.Ticks[i+1];
+ pIns->PanEnv.Values[i] = pIns->PanEnv.Values[i+1];
}
- if (nPoint >= pIns->nPanEnv) nPoint = pIns->nPanEnv-1;
- if (pIns->nPanLoopStart > nPoint) pIns->nPanLoopStart--;
- if (pIns->nPanLoopEnd > nPoint) pIns->nPanLoopEnd--;
- if (pIns->nPanSustainBegin > nPoint) pIns->nPanSustainBegin--;
- if (pIns->nPanSustainEnd > nPoint) pIns->nPanSustainEnd--;
- if (pIns->nPanEnvReleaseNode>nPoint && pIns->nPanEnvReleaseNode!=ENV_RELEASE_NODE_UNSET) pIns->nPanEnvReleaseNode--;
- pIns->PanPoints[0] = 0;
+ if (nPoint >= pIns->PanEnv.nNodes) nPoint = pIns->PanEnv.nNodes-1;
+ if (pIns->PanEnv.nLoopStart > nPoint) pIns->PanEnv.nLoopStart--;
+ if (pIns->PanEnv.nLoopEnd > nPoint) pIns->PanEnv.nLoopEnd--;
+ if (pIns->PanEnv.nSustainStart > nPoint) pIns->PanEnv.nSustainStart--;
+ if (pIns->PanEnv.nSustainEnd > nPoint) pIns->PanEnv.nSustainEnd--;
+ if (pIns->PanEnv.nReleaseNode>nPoint && pIns->PanEnv.nReleaseNode!=ENV_RELEASE_NODE_UNSET) pIns->PanEnv.nReleaseNode--;
+ pIns->PanEnv.Ticks[0] = 0;
bOk = TRUE;
}
break;
case ENV_PITCH:
- if (pIns->nPitchEnv > 1)
+ if (pIns->PitchEnv.nNodes > 1)
{
- pIns->nPitchEnv--;
- for (UINT i=nPoint; i<pIns->nPitchEnv; i++)
+ pIns->PitchEnv.nNodes--;
+ for (UINT i=nPoint; i<pIns->PitchEnv.nNodes; i++)
{
- pIns->PitchPoints[i] = pIns->PitchPoints[i+1];
- pIns->PitchEnv[i] = pIns->PitchEnv[i+1];
+ pIns->PitchEnv.Ticks[i] = pIns->PitchEnv.Ticks[i+1];
+ pIns->PitchEnv.Values[i] = pIns->PitchEnv.Values[i+1];
}
- if (nPoint >= pIns->nPitchEnv) nPoint = pIns->nPitchEnv-1;
- if (pIns->nPitchLoopStart > nPoint) pIns->nPitchLoopStart--;
- if (pIns->nPitchLoopEnd > nPoint) pIns->nPitchLoopEnd--;
- if (pIns->nPitchSustainBegin > nPoint) pIns->nPitchSustainBegin--;
- if (pIns->nPitchSustainEnd > nPoint) pIns->nPitchSustainEnd--;
- if (pIns->nPitchEnvReleaseNode>nPoint && pIns->nPitchEnvReleaseNode!=ENV_RELEASE_NODE_UNSET) pIns->nPitchEnvReleaseNode--;
- pIns->PitchPoints[0] = 0;
+ if (nPoint >= pIns->PitchEnv.nNodes) nPoint = pIns->PitchEnv.nNodes-1;
+ if (pIns->PitchEnv.nLoopStart > nPoint) pIns->PitchEnv.nLoopStart--;
+ if (pIns->PitchEnv.nLoopEnd > nPoint) pIns->PitchEnv.nLoopEnd--;
+ if (pIns->PitchEnv.nSustainStart > nPoint) pIns->PitchEnv.nSustainStart--;
+ if (pIns->PitchEnv.nSustainEnd > nPoint) pIns->PitchEnv.nSustainEnd--;
+ if (pIns->PitchEnv.nReleaseNode>nPoint && pIns->PitchEnv.nReleaseNode!=ENV_RELEASE_NODE_UNSET) pIns->PitchEnv.nReleaseNode--;
+ pIns->PitchEnv.Ticks[0] = 0;
bOk = TRUE;
}
break;
@@ -2247,83 +2247,83 @@
if (nTick >= 0) switch(m_nEnv)
{
case ENV_VOLUME:
- if (pIns->nVolEnv < maxpoints)
+ if (pIns->VolEnv.nNodes < maxpoints)
{
- if (!pIns->nVolEnv)
+ if (!pIns->VolEnv.nNodes)
{
- pIns->VolPoints[0] = 0;
- pIns->VolEnv[0] = 64;
- pIns->nVolEnv = 1;
+ pIns->VolEnv.Ticks[0] = 0;
+ pIns->VolEnv.Values[0] = 64;
+ pIns->VolEnv.nNodes = 1;
}
UINT i = 0;
- for (i=0; i<pIns->nVolEnv; i++) if (nTick <= pIns->VolPoints[i]) break;
- for (UINT j=pIns->nVolEnv; j>i; j--)
+ for (i=0; i<pIns->VolEnv.nNodes; i++) if (nTick <= pIns->VolEnv.Ticks[i]) break;
+ for (UINT j=pIns->VolEnv.nNodes; j>i; j--)
{
- pIns->VolPoints[j] = pIns->VolPoints[j-1];
- pIns->VolEnv[j] = pIns->VolEnv[j-1];
+ pIns->VolEnv.Ticks[j] = pIns->VolEnv.Ticks[j-1];
+ pIns->VolEnv.Values[j] = pIns->VolEnv.Values[j-1];
}
- pIns->VolPoints[i] = (WORD)nTick;
- pIns->VolEnv[i] = (BYTE)nValue;
- pIns->nVolEnv++;
- if (pIns->nVolLoopStart >= i) pIns->nVolLoopStart++;
- if (pIns->nVolLoopEnd >= i) pIns->nVolLoopEnd++;
- if (pIns->nVolSustainBegin >= i) pIns->nVolSustainBegin++;
- if (pIns->nVolSustainEnd >= i) pIns->nVolSustainEnd++;
- if (pIns->nVolEnvReleaseNode>=i && pIns->nVolEnvReleaseNode!=ENV_RELEASE_NODE_UNSET) pIns->nVolEnvReleaseNode++;
+ pIns->VolEnv.Ticks[i] = (WORD)nTick;
+ pIns->VolEnv.Values[i] = (BYTE)nValue;
+ pIns->VolEnv.nNodes++;
+ if (pIns->VolEnv.nLoopStart >= i) pIns->VolEnv.nLoopStart++;
+ if (pIns->VolEnv.nLoopEnd >= i) pIns->VolEnv.nLoopEnd++;
+ if (pIns->VolEnv.nSustainStart >= i) pIns->VolEnv.nSustainStart++;
+ if (pIns->VolEnv.nSustainEnd >= i) pIns->VolEnv.nSustainEnd++;
+ if (pIns->VolEnv.nReleaseNode>=i && pIns->VolEnv.nReleaseNode!=ENV_RELEASE_NODE_UNSET) pIns->VolEnv.nReleaseNode++;
bOk = TRUE;
}
break;
case ENV_PANNING:
- if (pIns->nPanEnv < maxpoints)
+ if (pIns->PanEnv.nNodes < maxpoints)
{
- if (!pIns->nPanEnv)
+ if (!pIns->PanEnv.nNodes)
{
- pIns->PanPoints[0] = 0;
- pIns->PanEnv[0] = 32;
- pIns->nPanEnv = 1;
+ pIns->PanEnv.Ticks[0] = 0;
+ pIns->PanEnv.Values[0] = 32;
+ pIns->PanEnv.nNodes = 1;
}
UINT i = 0;
- for (i=0; i<pIns->nPanEnv; i++) if (nTick <= pIns->PanPoints[i]) break;
- for (UINT j=pIns->nPanEnv; j>i; j--)
+ for (i=0; i<pIns->PanEnv.nNodes; i++) if (nTick <= pIns->PanEnv.Ticks[i]) break;
+ for (UINT j=pIns->PanEnv.nNodes; j>i; j--)
{
- pIns->PanPoints[j] = pIns->PanPoints[j-1];
- pIns->PanEnv[j] = pIns->PanEnv[j-1];
+ pIns->PanEnv.Ticks[j] = pIns->PanEnv.Ticks[j-1];
+ pIns->PanEnv.Values[j] = pIns->PanEnv.Values[j-1];
}
- pIns->PanPoints[i] = (WORD)nTick;
- pIns->PanEnv[i] =(BYTE)nValue;
- pIns->nPanEnv++;
- if (pIns->nPanLoopStart >= i) pIns->nPanLoopStart++;
- if (pIns->nPanLoopEnd >= i) pIns->nPanLoopEnd++;
- if (pIns->nPanSustainBegin >= i) pIns->nPanSustainBegin++;
- if (pIns->nPanSustainEnd >= i) pIns->nPanSustainEnd++;
- if (pIns->nPanEnvReleaseNode>=i && pIns->nPanEnvReleaseNode!=ENV_RELEASE_NODE_UNSET) pIns->nPanEnvReleaseNode++;
+ pIns->PanEnv.Ticks[i] = (WORD)nTick;
+ pIns->PanEnv.Values[i] =(BYTE)nValue;
+ pIns->PanEnv.nNodes++;
+ if (pIns->PanEnv.nLoopStart >= i) pIns->PanEnv.nLoopStart++;
+ if (pIns->PanEnv.nLoopEnd >= i) pIns->PanEnv.nLoopEnd++;
+ if (pIns->PanEnv.nSustainStart >= i) pIns->PanEnv.nSustainStart++;
+ if (pIns->PanEnv.nSustainEnd >= i) pIns->PanEnv.nSustainEnd++;
+ if (pIns->PanEnv.nReleaseNode>=i && pIns->PanEnv.nReleaseNode!=ENV_RELEASE_NODE_UNSET) pIns->PanEnv.nReleaseNode++;
bOk = TRUE;
}
break;
case ENV_PITCH:
- if (pIns->nPitchEnv < maxpoints)
+ if (pIns->PitchEnv.nNodes < maxpoints)
{
- if (!pIns->nPitchEnv)
+ if (!pIns->PitchEnv.nNodes)
{
- pIns->PitchPoints[0] = 0;
- pIns->PitchEnv[0] = 32;
- pIns->nPitchEnv = 1;
+ pIns->PitchEnv.Ticks[0] = 0;
+ pIns->PitchEnv.Values[0] = 32;
+ pIns->PitchEnv.nNodes = 1;
}
UINT i = 0;
- for (i=0; i<pIns->nPitchEnv; i++) if (nTick <= pIns->PitchPoints[i]) break;
- for (UINT j=pIns->nPitchEnv; j>i; j--)
+ for (i=0; i<pIns->PitchEnv.nNodes; i++) if (nTick <= pIns->PitchEnv.Ticks[i]) break;
+ for (UINT j=pIns->PitchEnv.nNodes; j>i; j--)
{
- pIns->PitchPoints[j] = pIns->PitchPoints[j-1];
- pIns->PitchEnv[j] = pIns->PitchEnv[j-1];
+ pIns->PitchEnv.Ticks[j] = pIns->PitchEnv.Ticks[j-1];
+ pIns->PitchEnv.Values[j] = pIns->PitchEnv.Values[j-1];
}
- pIns->PitchPoints[i] = (WORD)nTick;
- pIns->PitchEnv[i] = (BYTE)nValue;
- pIns->nPitchEnv++;
- if (pIns->nPitchLoopStart >= i) pIns->nPitchLoopStart++;
- if (pIns->nPitchLoopEnd >= i) pIns->nPitchLoopEnd++;
- if (pIns->nPitchSustainBegin >= i) pIns->nPitchSustainBegin++;
- if (pIns->nPitchSustainEnd >= i) pIns->nPitchSustainEnd++;
- if (pIns->nPitchEnvReleaseNode>=i && pIns->nPitchEnvReleaseNode!=ENV_RELEASE_NODE_UNSET) pIns->nPitchEnvReleaseNode++;
+ pIns->PitchEnv.Ticks[i] = (WORD)nTick;
+ pIns->PitchEnv.Values[i] = (BYTE)nValue;
+ pIns->PitchEnv.nNodes++;
+ if (pIns->PitchEnv.nLoopStart >= i) pIns->PitchEnv.nLoopStart++;
+ if (pIns->PitchEnv.nLoopEnd >= i) pIns->PitchEnv.nLoopEnd++;
+ if (pIns->PitchEnv.nSustainStart >= i) pIns->PitchEnv.nSustainStart++;
+ if (pIns->PitchEnv.nSustainEnd >= i) pIns->PitchEnv.nSustainEnd++;
+ if (pIns->PitchEnv.nReleaseNode>=i && pIns->PitchEnv.nReleaseNode!=ENV_RELEASE_NODE_UNSET) pIns->PitchEnv.nReleaseNode++;
bOk = TRUE;
}
break;
Modified: trunk/OpenMPT/soundlib/Dlsbank.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Dlsbank.cpp 2009-08-16 11:46:32 UTC (rev 327)
+++ trunk/OpenMPT/soundlib/Dlsbank.cpp 2009-08-16 11:55:06 UTC (rev 328)
@@ -1703,9 +1703,9 @@
pIns->nDNA = DNA_NOTEFADE;
pIns->nResampling = SRCMODE_DEFAULT;
pIns->nFilterMode = FLTMODE_UNCHANGED;
- pIns->nPanEnvReleaseNode=ENV_RELEASE_NODE_UNSET;
- pIns->nPitchEnvReleaseNode=ENV_RELEASE_NODE_UNSET;
- pIns->nVolEnvReleaseNode=ENV_RELEASE_NODE_UNSET;
+ pIns->PanEnv.nReleaseNode=ENV_RELEASE_NODE_UNSET;
+ pIns->PitchEnv.nReleaseNode=ENV_RELEASE_NODE_UNSET;
+ pIns->VolEnv.nReleaseNode=ENV_RELEASE_NODE_UNSET;
pSndFile->Instruments[nInstr] = pIns;
nSample = 1;
UINT nLoadedSmp = 0;
@@ -1776,17 +1776,17 @@
// Delay section
// -> DLS level 2
// Attack section
- pIns->VolPoints[nPoint] = 0;
+ pIns->VolEnv.Ticks[nPoint] = 0;
if (part->wVolAttack)
{
- pIns->VolEnv[nPoint] = (BYTE)(64/(part->wVolAttack/2+2)+8);// /-----
- pIns->VolPoints[nPoint+1] = part->wVolAttack; // |
+ pIns->VolEnv.Values[nPoint] = (BYTE)(64/(part->wVolAttack/2+2)+8);// /-----
+ pIns->VolEnv.Ticks[nPoint+1] = part->wVolAttack; // |
} else
{
- pIns->VolEnv[nPoint] = 64; // |-----
- pIns->VolPoints[nPoint+1] = 1; // |
+ pIns->VolEnv.Values[nPoint] = 64; // |-----
+ pIns->VolEnv.Ticks[nPoint+1] = 1; // |
}
- pIns->VolEnv[nPoint+1] = 64;
+ pIns->VolEnv.Values[nPoint+1] = 64;
nPoint += 2;
// Hold section
// -> DLS Level 2
@@ -1795,7 +1795,7 @@
{
if (part->nVolSustainLevel < 128)
{
- LONG lStartTime = pIns->VolPoints[nPoint-1];
+ LONG lStartTime = pIns->VolEnv.Ticks[nPoint-1];
LONG lSusLevel = - DLS32BitRelativeLinearToGain(part->nVolSustainLevel << 9) / 65536;
LONG lDecayTime = 1;
if (lSusLevel > 0)
@@ -1812,10 +1812,10 @@
if ((ltime > 1) && (ltime < lDecayTime))
{
ltime += lStartTime;
- if (ltime > pIns->VolPoints[nPoint-1])
+ if (ltime > pIns->VolEnv.Ticks[nPoint-1])
{
- pIns->VolPoints[nPoint] = (WORD)ltime;
- pIns->VolEnv[nPoint] = (BYTE)(lFactor / 2);
+ pIns->VolEnv.Ticks[nPoint] = (WORD)ltime;
+ pIns->VolEnv.Values[nPoint] = (BYTE)(lFactor / 2);
nPoint++;
}
}
@@ -1823,10 +1823,10 @@
}
}
- if (lStartTime + lDecayTime > (LONG)pIns->VolPoints[nPoint-1])
+ if (lStartTime + lDecayTime > (LONG)pIns->VolEnv.Ticks[nPoint-1])
{
- pIns->VolEnv[nPoint] = (BYTE)((part->nVolSustainLevel+1) / 2);
- pIns->VolPoints[nPoint] = (WORD)(lStartTime+lDecayTime);
+ pIns->VolEnv.Values[nPoint] = (BYTE)((part->nVolSustainLevel+1) / 2);
+ pIns->VolEnv.Ticks[nPoint] = (WORD)(lStartTime+lDecayTime);
nPoint++;
}
}
@@ -1834,17 +1834,17 @@
} else
{
pIns->dwFlags |= ENV_VOLSUSTAIN;
- pIns->VolPoints[nPoint] = (WORD)(pIns->VolPoints[nPoint-1]+1);
- pIns->VolEnv[nPoint] = pIns->VolEnv[nPoint-1];
+ pIns->VolEnv.Ticks[nPoint] = (WORD)(pIns->VolEnv.Ticks[nPoint-1]+1);
+ pIns->VolEnv.Values[nPoint] = pIns->VolEnv.Values[nPoint-1];
nPoint++;
}
- pIns->nVolSustainBegin = pIns->nVolSustainEnd = (BYTE)(nPoint - 1);
+ pIns->VolEnv.nSustainStart = pIns->VolEnv.nSustainEnd = (BYTE)(nPoint - 1);
// Release section
- if ((part->wVolRelease) && (pIns->VolEnv[nPoint-1] > 1))
+ if ((part->wVolRelease) && (pIns->VolEnv.Values[nPoint-1] > 1))
{
LONG lReleaseTime = part->wVolRelease;
- LONG lStartTime = pIns->VolPoints[nPoint-1];
- LONG lStartFactor = pIns->VolEnv[nPoint-1];
+ LONG lStartTime = pIns->VolEnv.Ticks[nPoint-1];
+ LONG lStartFactor = pIns->VolEnv.Values[nPoint-1];
LONG lSusLevel = - DLS32BitRelativeLinearToGain(lStartFactor << 10) / 65536;
LONG lDecayEndTime = (lReleaseTime * lSusLevel) / 960;
lReleaseTime -= lDecayEndTime;
@@ -1859,26 +1859,26 @@
if ((ltime > 1) && (ltime < lReleaseTime))
{
ltime += lStartTime;
- if (ltime > pIns->VolPoints[nPoint-1])
+ if (ltime > pIns->VolEnv.Ticks[nPoint-1])
{
- pIns->VolPoints[nPoint] = (WORD)ltime;
- pIns->VolEnv[nPoint] = (BYTE)lFactor;
+ pIns->VolEnv.Ticks[nPoint] = (WORD)ltime;
+ pIns->VolEnv.Values[nPoint] = (BYTE)lFactor;
nPoint++;
}
}
}
}
if (lReleaseTime < 1) lReleaseTime = 1;
- pIns->VolPoints[nPoint] = (WORD)(lStartTime + lReleaseTime);
- pIns->VolEnv[nPoint] = 0;
+ pIns->VolEnv.Ticks[nPoint] = (WORD)(lStartTime + lReleaseTime);
+ pIns->VolEnv.Values[nPoint] = 0;
nPoint++;
} else
{
- pIns->VolPoints[nPoint] = (BYTE)(pIns->VolPoints[nPoint-1] + 1);
- pIns->VolEnv[nPoint] = 0;
+ pIns->VolEnv.Ticks[nPoint] = (BYTE)(pIns->VolEnv.Ticks[nPoint-1] + 1);
+ pIns->VolEnv.Values[nPoint] = 0;
nPoint++;
}
- pIns->nVolEnv = (BYTE)nPoint;
+ pIns->VolEnv.nNodes = (BYTE)nPoint;
}
}
if (pDlsIns->ulBank & F_INSTRUMENT_DRUMS)
@@ -1888,15 +1888,15 @@
if (!(pIns->dwFlags & ENV_VOLUME))
{
pIns->dwFlags |= ENV_VOLUME;
- pIns->VolPoints[0] = 0;
- pIns->VolEnv[0] = 64;
- pIns->VolPoints[1] = 5;
- pIns->VolEnv[1] = 64;
- pIns->VolPoints[2] = 10;
- pIns->VolEnv[2] = 32;
- pIns->VolPoints[3] = 20; // 1 second max. for drums
- pIns->VolEnv[3] = 0;
- pIns->nVolEnv = 4;
+ pIns->VolEnv.Ticks[0] = 0;
+ pIns->VolEnv.Values[0] = 64;
+ pIns->VolEnv.Ticks[1] = 5;
+ pIns->VolEnv.Values[1] = 64;
+ pIns->VolEnv.Ticks[2] = 10;
+ pIns->VolEnv.Values[2] = 32;
+ pIns->VolEnv.Ticks[3] = 20; // 1 second max. for drums
+ pIns->VolEnv.Values[3] = 0;
+ pIns->VolEnv.nNodes = 4;
}
}
return TRUE;
Modified: trunk/OpenMPT/soundlib/LOAD_DBM.CPP
===================================================================
--- trunk/OpenMPT/soundlib/LOAD_DBM.CPP 2009-08-16 11:46:32 UTC (rev 327)
+++ trunk/OpenMPT/soundlib/LOAD_DBM.CPP 2009-08-16 11:55:06 UTC (rev 328)
@@ -219,15 +219,15 @@
if (peh->flags & 1) pIns->dwFlags |= ENV_VOLUME;
if (peh->flags & 2) pIns->dwFlags |= ENV_VOLSUSTAIN;
if (peh->flags & 4) pIns->dwFlags |= ENV_VOLLOOP;
- pIns->nVolEnv = peh->numpoints + 1;
- if (pIns->nVolEnv > MAX_ENVPOINTS) pIns->nVolEnv = MAX_ENVPOINTS;
- pIns->nVolLoopStart = peh->loopbegin;
- pIns->nVolLoopEnd = peh->loopend;
- pIns->nVolSustainBegin = pIns->nVolSustainEnd = peh->sustain1;
- for (UINT i=0; i<pIns->nVolEnv; i++)
+ pIns->VolEnv.nNodes = peh->numpoints + 1;
+ if (pIns->VolEnv.nNodes > MAX_ENVPOINTS) pIns->VolEnv.nNodes = MAX_ENVPOINTS;
+ pIns->VolEnv.nLoopStart = peh->loopbegin;
+ pIns->VolEnv.nLoopEnd = peh->loopend;
+ pIns->VolEnv.nSustainStart = pIns->VolEnv.nSustainEnd = peh->sustain1;
+ for (UINT i=0; i<pIns->VolEnv.nNodes; i++)
{
- pIns->VolPoints[i] = BigEndianW(peh->volenv[i*2]);
- pIns->VolEnv[i] = (BYTE)BigEndianW(peh->volenv[i*2+1]);
+ pIns->VolEnv.Ticks[i] = BigEndianW(peh->volenv[i*2]);
+ pIns->VolEnv.Values[i] = (BYTE)BigEndianW(peh->volenv[i*2+1]);
}
}
chunk_pos += sizeof(DBMENVELOPE);
Modified: trunk/OpenMPT/soundlib/Load_ams.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_ams.cpp 2009-08-16 11:46:32 UTC (rev 327)
+++ trunk/OpenMPT/soundlib/Load_ams.cpp 2009-08-16 11:55:06 UTC (rev 328)
@@ -381,15 +381,15 @@
// Volume Envelope
{
UINT pos = 0;
- pIns->nVolEnv = (volenv->points > 16) ? 16 : volenv->points;
- pIns->nVolSustainBegin = pIns->nVolSustainEnd = volenv->sustain;
- pIns->nVolLoopStart = volenv->loopbegin;
- pIns->nVolLoopEnd = volenv->loopend;
- for (UINT i=0; i<pIns->nVolEnv; i++)
+ pIns->VolEnv.nNodes = (volenv->points > 16) ? 16 : volenv->points;
+ pIns->VolEnv.nSustainStart = pIns->VolEnv.nSustainEnd = volenv->sustain;
+ pIns->VolEnv.nLoopStart = volenv->loopbegin;
+ pIns->VolEnv.nLoopEnd = volenv->loopend;
+ for (UINT i=0; i<pIns->VolEnv.nNodes; i++)
{
- pIns->VolEnv[i] = (BYTE)((volenv->info[i*3+2] & 0x7F) >> 1);
+ pIns->VolEnv.Values[i] = (BYTE)((volenv->info[i*3+2] & 0x7F) >> 1);
pos += volenv->info[i*3] + ((volenv->info[i*3+1] & 1) << 8);
- pIns->VolPoints[i] = (WORD)pos;
+ pIns->VolEnv.Ticks[i] = (WORD)pos;
}
}
pIns->nFadeOut = (((lpStream[dwMemPos+2] & 0x0F) << 8) | (lpStream[dwMemPos+1])) << 3;
Modified: trunk/OpenMPT/soundlib/Load_imf.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_imf.cpp 2009-08-16 11:46:32 UTC (rev 327)
+++ trunk/OpenMPT/soundlib/Load_imf.cpp 2009-08-16 11:55:06 UTC (rev 328)
@@ -389,6 +389,8 @@
if (memcmp(hdr.im10, "IM10", 4) != 0)
return false;
+ ChangeModTypeTo(MOD_TYPE_IT);
+
// song name
memset(m_szNames, 0, sizeof(m_szNames));
memcpy(m_szNames[0], hdr.title, 25);
@@ -402,7 +404,6 @@
m_nDefaultTempo = hdr.bpm;
m_nDefaultGlobalVolume = hdr.master << 1;
m_nSamplePreAmp = hdr.amp;
- m_nVSTiVolume = 48; // not supported
for (n = 0; n < 32; n++) {
Chn[n].nPan = hdr.channels[n].panning * 64 / 255;
@@ -489,7 +490,9 @@
for (s = 0; s < imfins.smpnum; s++) {
IMFSAMPLE imfsmp;
UINT32 blen;
- slurp_read(fp, &imfsmp, sizeof(imfsmp));
+ if(dwMemPos + sizeof(IMFSAMPLE) > dwMemLength) break;
+ memset(imfsmp, 0, sizeof(IMFSAMPLE));
+ memcpy(imfsmp, lpStream + dwMemPos, sizeof(IMFSAMPLE));
if (memcmp(imfsmp.is10, "IS10", 4) != 0) {
//printf("is10 says %02x %02x %02x %02x!\n",
@@ -528,6 +531,7 @@
}
pSample++;
+ dwMemPos += sizeof(IMFSAMPLE);
}
firstsample += imfins.smpnum;
}
Modified: trunk/OpenMPT/soundlib/Load_it.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_it.cpp 2009-08-16 11:46:32 UTC (rev 327)
+++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-08-16 11:55:06 UTC (rev 328)
@@ -243,19 +243,19 @@
if (pis->flags & 0x01) pIns->dwFlags |= ENV_VOLUME;
if (pis->flags & 0x02) pIns->dwFlags |= ENV_VOLLOOP;
if (pis->flags & 0x04) pIns->dwFlags |= ENV_VOLSUSTAIN;
- pIns->nVolLoopStart = pis->vls;
- pIns->nVolLoopEnd = pis->vle;
- pIns->nVolSustainBegin = pis->sls;
- pIns->nVolSustainEnd = pis->sle;
- pIns->nVolEnv = 25;
+ pIns->VolEnv.nLoopStart = pis->vls;
+ pIns->VolEnv.nLoopEnd = pis->vle;
+ pIns->VolEnv.nSustainStart = pis->sls;
+ pIns->VolEnv.nSustainEnd = pis->sle;
+ pIns->VolEnv.nNodes = 25;
for (UINT ev=0; ev<25; ev++)
{
- if ((pIns->VolPoints[ev] = pis->nodes[ev*2]) == 0xFF)
+ if ((pIns->VolEnv.Ticks[ev] = pis->nodes[ev*2]) == 0xFF)
{
- pIns->nVolEnv = ev;
+ pIns->VolEnv.nNodes = ev;
break;
}
- pIns->VolEnv[ev] = pis->nodes[ev*2+1];
+ pIns->VolEnv.Values[ev] = pis->nodes[ev*2+1];
}
pIns->nNNA = pis->nna;
pIns->nDCT = pis->dnc;
@@ -348,44 +348,44 @@
if (pis->volenv.flags & 2) pIns->dwFlags |= ENV_VOLLOOP;
if (pis->volenv.flags & 4) pIns->dwFlags |= ENV_VOLSUSTAIN;
if (pis->volenv.flags & 8) pIns->dwFlags |= ENV_VOLCARRY;
- pIns->nVolEnv = pis->volenv.num;
- if (pIns->nVolEnv > 25) pIns->nVolEnv = 25;
- pIns->nVolLoopStart = pis->volenv.lpb;
- pIns->nVolLoopEnd = pis->volenv.lpe;
- pIns->nVolSustainBegin = pis->volenv.slb;
- pIns->nVolSustainEnd = pis->volenv.sle;
+ pIns->VolEnv.nNodes = pis->volenv.num;
+ if (pIns->VolEnv.nNodes > 25) pIns->VolEnv.nNodes = 25;
+ pIns->VolEnv.nLoopStart = pis->volenv.lpb;
+ pIns->VolEnv.nLoopEnd = pis->volenv.lpe;
+ pIns->VolEnv.nSustainStart = pis->volenv.slb;
+ pIns->VolEnv.nSustainEnd = pis->volenv.sle;
// Panning Envelope
if (pis->panenv.flags & 1) pIns->dwFlags |= ENV_PANNING;
if (pis->panenv.flags & 2) pIns->dwFlags |= ENV_PANLOOP;
if (pis->panenv.flags & 4) pIns->dwFlags |= ENV_PANSUSTAIN;
if (pis->panenv.flags & 8) pIns->dwFlags |= ENV_PANCARRY;
- pIns->nPanEnv = pis->panenv.num;
- if (pIns->nPanEnv > 25) pIns->nPanEnv = 25;
- pIns->nPanLoopStart = pis->panenv.lpb;
- pIns->nPanLoopEnd = pis->panenv.lpe;
- pIns->nPanSustainBegin = pis->panenv.slb;
- pIns->nPanSustainEnd = pis->panenv.sle;
+ pIns->PanEnv.nNodes = pis->panenv.num;
+ if (pIns->PanEnv.nNodes > 25) pIns->PanEnv.nNodes = 25;
+ pIns->PanEnv.nLoopStart = pis->panenv.lpb;
+ pIns->PanEnv.nLoopEnd = pis->panenv.lpe;
+ pIns->PanEnv.nSustainStart = pis->panenv.slb;
+ pIns->PanEnv.nSustainEnd = pis->panenv.sle;
// Pitch Envelope
if (pis->pitchenv.flags & 1) pIns->dwFlags |= ENV_PITCH;
if (pis->pitchenv.flags & 2) pIns->dwFlags |= ENV_PITCHLOOP;
if (pis->pitchenv.flags & 4) pIns->dwFlags |= ENV_PITCHSUSTAIN;
if (pis->pitchenv.flags & 8) pIns->dwFlags |= ENV_PITCHCARRY;
if (pis->pitchenv.flags & 0x80) pIns->dwFlags |= ENV_FILTER;
- pIns->nPitchEnv = pis->pitchenv.num;
- if (pIns->nPitchEnv > 25) pIns->nPitchEnv = 25;
- pIns->nPitchLoopStart = pis->pitchenv.lpb;
- pIns->nPitchLoopEnd = pis->pitchenv.lpe;
- pIns->nPitchSustainBegin = pis->pitchenv.slb;
- pIns->nPitchSustainEnd = pis->pitchenv.sle;
+ pIns->PitchEnv.nNodes = pis->pitchenv.num;
+ if (pIns->PitchEnv.nNodes > 25) pIns->PitchEnv.nNodes = 25;
+ pIns->PitchEnv.nLoopStart = pis->pitchenv.lpb;
+ pIns->PitchEnv.nLoopEnd = pis->pitchenv.lpe;
+ pIns->PitchEnv.nSustainStart = pis->pitchenv.slb;
+ pIns->PitchEnv.nSustainEnd = pis->pitchenv.sle;
// Envelopes Data
for (UINT ev=0; ev<25; ev++)
{
- pIns->VolEnv[ev] = pis->volenv.data[ev*3];
- pIns->VolPoints[ev] = (pis->volenv.data[ev*3+2] << 8) | (pis->volenv.data[ev*3+1]);
- pIns->PanEnv[ev] = pis->panenv.data[ev*3] + 32;
- pIns->PanPoints[ev] = (pis->panenv.data[ev*3+2] << 8) | (pis->panenv.data[ev*3+1]);
- pIns->PitchEnv[ev] = pis->pitchenv.data[ev*3] + 32;
- pIns->PitchPoints[ev] = (pis->pitchenv.data[ev*3+2] << 8) | (pis->pitchenv.data[ev*3+1]);
+ pIns->VolEnv.Values[ev] = pis->volenv.data[ev*3];
+ pIns->VolEnv.Ticks[ev] = (pis->volenv.data[ev*3+2] << 8) | (pis->volenv.data[ev*3+1]);
+ pIns->PanEnv.Values[ev] = pis->panenv.data[ev*3] + 32;
+ pIns->PanEnv.Ticks[ev] = (pis->panenv.data[ev*3+2] << 8) | (pis->panenv.data[ev*3+1]);
+ pIns->PitchEnv.Values[ev] = pis->pitchenv.data[ev*3] + 32;
+ pIns->PitchEnv.Ticks[ev] = (pis->pitchenv.data[ev*3+2] << 8) | (pis->pitchenv.data[ev*3+1]);
}
pIns->nNNA = pis->nna;
pIns->nDCT = pis->dct;
@@ -403,8 +403,8 @@
if (pIns->nPan > 256) pIns->nPan = 128;
if (pis->dfp < 0x80) pIns->dwFlags |= ENV_SETPANNING;
}
- if ((pIns->nVolLoopStart >= 25) || (pIns->nVolLoopEnd >= 25)) pIns->dwFlags &= ~ENV_VOLLOOP;
- if ((pIns->nVolSustainBegin >= 25) || (pIns->nVolSustainEnd >= 25)) pIns->dwFlags &= ~ENV_VOLSUSTAIN;
+ if ((pIns->VolEnv.nLoopStart >= 25) || (pIns->VolEnv.nLoopEnd >= 25)) pIns->dwFlags &= ~ENV_VOLLOOP;
+ if ((pIns->VolEnv.nSustainStart >= 25) || (pIns->VolEnv.nSustainEnd >= 25)) pIns->dwFlags &= ~ENV_VOLSUSTAIN;
return returnVal; //return offset
}
@@ -2030,44 +2030,44 @@
if (pIns->dwFlags & ENV_VOLLOOP) iti.volenv.flags |= 0x02;
if (pIns->dwFlags & ENV_VOLSUSTAIN) iti.volenv.flags |= 0x04;
if (pIns->dwFlags & ENV_VOLCARRY) iti.volenv.flags |= 0x08;
- iti.volenv.num = (BYTE)pIns->nVolEnv;
- iti.volenv.lpb = (BYTE)pIns->nVolLoopStart;
- iti.volenv.lpe = (BYTE)pIns->nVolLoopEnd;
- iti.volenv.slb = pIns->nVolSustainBegin;
- iti.volenv.sle = pIns->nVolSustainEnd;
+ iti.volenv.num = (BYTE)pIns->VolEnv.nNodes;
+ iti.volenv.lpb = (BYTE)pIns->VolEnv.nLoopStart;
+ iti.volenv.lpe = (BYTE)pIns->VolEnv.nLoopEnd;
+ iti.volenv.slb = pIns->VolEnv.nSustainStart;
+ iti.volenv.sle = pIns->VolEnv.nSustainEnd;
// Writing Panning envelope
if (pIns->dwFlags & ENV_PANNING) iti.panenv.flags |= 0x01;
if (pIns->dwFlags & ENV_PANLOOP) iti.panenv.flags |= 0x02;
if (pIns->dwFlags & ENV_PANSUSTAIN) iti.panenv.flags |= 0x04;
if (pIns->dwFlags & ENV_PANCARRY) iti.panenv.flags |= 0x08;
- iti.panenv.num = (BYTE)pIns->nPanEnv;
- iti.panenv.lpb = (BYTE)pIns->nPanLoopStart;
- iti.panenv.lpe = (BYTE)pIns->nPanLoopEnd;
- iti.panenv.slb = pIns->nPanSustainBegin;
- iti.panenv.sle = pIns->nPanSustainEnd;
+ iti.panenv.num = (BYTE)pIns->PanEnv.nNodes;
+ iti.panenv.lpb = (BYTE)pIns->PanEnv.nLoopStart;
+ iti.panenv.lpe = (BYTE)pIns->PanEnv.nLoopEnd;
+ iti.panenv.slb = pIns->PanEnv.nSustainStart;
+ iti.panenv.sle = pIns->PanEnv.nSustainEnd;
// Writing Pitch Envelope
if (pIns->dwFlags & ENV_PITCH) iti.pitchenv.flags |= 0x01;
if (pIns->dwFlags & ENV_PITCHLOOP) iti.pitchenv.flags |= 0x02;
if (pIns->dwFlags & ENV_PITCHSUSTAIN) iti.pitchenv.flags |= 0x04;
if (pIns->dwFlags & ENV_PITCHCARRY) iti.pitchenv.flags |= 0x08;
if (pIns->dwFlags & ENV_FILTER) iti.pitchenv.flags |= 0x80;
- iti.pitchenv.num = (BYTE)pIns->nPitchEnv;
- iti.pitchenv.lpb = (BYTE)pIns->nPitchLoopStart;
- iti.pitchenv.lpe = (BYTE)pIns->nPitchLoopEnd;
- iti.pitchenv.slb = (BYTE)pIns->nPitchSustainBegin;
- iti.pitchenv.sle = (BYTE)pIns->nPitchSustainEnd;
+ iti.pitchenv.num = (BYTE)pIns->PitchEnv.nNodes;
+ iti.pitchenv.lpb = (BYTE)pIns->PitchEnv.nLoopStart;
+ iti.pitchenv.lpe = (BYTE)pIns->PitchEnv.nLoopEnd;
+ iti.pitchenv.slb = (BYTE)pIns->PitchEnv.nSustainStart;
+ iti.pitchenv.sle = (BYTE)pIns->PitchEnv.nSustainEnd;
// Writing Envelopes data
for (UINT ev=0; ev<25; ev++)
{
- iti.volenv.data[ev*3] = pIns->VolEnv[ev];
- iti.volenv.data[ev*3+1] = pIns->VolPoints[ev] & 0xFF;
- iti.volenv.data[ev*3+2] = pIns->VolPoints[ev] >> 8;
- iti.panenv.data[ev*3] = pIns->PanEnv[ev] - 32;
- iti.panenv.data[ev*3+1] = pIns->PanPoints[ev] & 0xFF;
- iti.panenv.data[ev*3+2] = pIns->PanPoints[ev] >> 8;
- iti.pitchenv.data[ev*3] = pIns->PitchEnv[ev] - 32;
- iti.pitchenv.data[ev*3+1] = pIns->PitchPoints[ev] & 0xFF;
- iti.pitchenv.data[ev*3+2] = pIns->PitchPoints[ev] >> 8;
+ iti.volenv.data[ev*3] = pIns->VolEnv.Values[ev];
+ iti.volenv.data[ev*3+1] = pIns->VolEnv.Ticks[ev] & 0xFF;
+ iti.volenv.data[ev*3+2] = pIns->VolEnv.Ticks[ev] >> 8;
+ iti.panenv.data[ev*3] = pIns->PanEnv.Values[ev] - 32;
+ iti.panenv.data[ev*3+1] = pIns->PanEnv.Ticks[ev] & 0xFF;
+ iti.panenv.data[ev*3+2] = pIns->PanEnv.Ticks[ev] >> 8;
+ iti.pitchenv.data[ev*3] = pIns->PitchEnv.Values[ev] - 32;
+ iti.pitchenv.data[ev*3+1] = pIns->PitchEnv.Ticks[ev] & 0xFF;
+ iti.pitchenv.data[ev*3+2] = pIns->PitchEnv.Ticks[ev] >> 8;
}
} else
// Save Empty Instrument
@@ -2675,44 +2675,44 @@
if (pIns->dwFlags & ENV_VOLLOOP) iti.volenv.flags |= 0x02;
if (pIns->dwFlags & ENV_VOLSUSTAIN) iti.volenv.flags |= 0x04;
if (pIns->dwFlags & ENV_VOLCARRY) iti.volenv.flags |= 0x08;
- iti.volenv.num = (BYTE)pIns->nVolEnv;
- iti.volenv.lpb = (BYTE)pIns->nVolLoopStart;
- iti.volenv.lpe = (BYTE)pIns->nVolLoopEnd;
- iti.volenv.slb = pIns->nVolSustainBegin;
- iti.volenv.sle = pIns->nVolSustainEnd;
+ iti.volenv.num = (BYTE)pIns->VolEnv.nNodes;
+ iti.volenv.lpb = (BYTE)pIns->VolEnv.nLoopStart;
+ iti.volenv.lpe = (BYTE)pIns->VolEnv.nLoopEnd;
+ iti.volenv.slb = pIns->VolEnv.nSustainStart;
+ iti.volenv.sle = pIns->VolEnv.nSustainEnd;
// Writing Panning envelope
if (pIns->dwFlags & ENV_PANNING) iti.panenv.flags |= 0x01;
if (pIns->dwFlags & ENV_PANLOOP) iti.panenv.flags |= 0x02;
if (pIns->dwFlags & ENV_PANSUSTAIN) iti.panenv.flags |= 0x04;
if (pIns->dwFlags & ENV_PANCARRY) iti.panenv.flags |= 0x08;
- iti.panenv.num = (BYTE)pIns->nPanEnv;
- iti.panenv.lpb = (BYTE)pIns->nPanLoopStart;
- iti.panenv.lpe = (BYTE)pIns->nPanLoopEnd;
- iti.panenv.slb = pIns->nPanSustainBegin;
- iti.panenv.sle = pIns->nPanSustainEnd;
+ iti.panenv.num = (BYTE)pIns->PanEnv.nNodes;
+ iti.panenv.lpb = (BYTE)pIns->PanEnv.nLoopStart;
+ iti.panenv.lpe = (BYTE)pIns->PanEnv.nLoopEnd;
+ iti.panenv.slb = pIns->PanEnv.nSustainStart;
+ iti.panenv.sle = pIns->PanEnv.nSustainEnd;
// Writing Pitch Envelope
if (pIns->dwFlags & ENV_PITCH) iti.pitchenv.flags |= 0x01;
if (pIns->dwFlags & ENV_PITCHLOOP) iti.pitchenv.flags |= 0x02;
if (pIns->dwFlags & ENV_PITCHSUSTAIN) iti.pitchenv.flags |= 0x04;
if (pIns->dwFlags & ENV_PITCHCARRY) iti.pitchenv.flags |= 0x08;
if (pIns->dwFlags & ENV_FILTER) iti.pitchenv.flags |= 0x80;
- iti.pitchenv.num = (BYTE)pIns->nPitchEnv;
- iti.pitchenv.lpb = (BYTE)pIns->nPitchLoopStart;
- iti.pitchenv.lpe = (BYTE)pIns->nPitchLoopEnd;
- iti.pitchenv.slb = (BYTE)pIns->nPitchSustainBegin;
- iti.pitchenv.sle = (BYTE)pIns->nPitchSustainEnd;
+ iti.pitchenv.num = (BYTE)pIns->PitchEnv.nNodes;
+ iti.pitchenv.lpb = (BYTE)pIns->PitchEnv.nLoopStart;
+ iti.pitchenv.lpe = (BYTE)pIns->PitchEnv.nLoopEnd;
+ iti.pitchenv.slb = (BYTE)pIns->PitchEnv.nSustainStart;
+ iti.pitchenv.sle = (BYTE)pIns->PitchEnv.nSustainEnd;
// Writing Envelopes data
for (UINT ev=0; ev<25; ev++)
{
- iti.volenv.data[ev*3] = pIns->VolEnv[ev];
- iti.volenv.data[ev*3+1] = pIns->VolPoints[ev] & 0xFF;
- iti.volenv.data[ev*3+2] = pIns->VolPoints[ev] >> 8;
- iti.panenv.data[ev*3] = pIns->PanEnv[ev] - 32;
- iti.panenv.data[ev*3+1] = pIns->PanPoints[ev] & 0xFF;
- iti.panenv.data[ev*3+2] = pIns->PanPoints[ev] >> 8;
- iti.pitchenv.data[ev*3] = pIns->PitchEnv[ev] - 32;
- iti.pitchenv.data[ev*3+1] = pIns->PitchPoints[ev] & 0xFF;
- iti.pitchenv.data[ev*3+2] = pIns->PitchPoints[ev] >> 8;
+ iti.volenv.data[ev*3] = pIns->VolEnv.Values[ev];
+ iti.volenv.data[ev*3+1] = pIns->VolEnv.Ticks[ev] & 0xFF;
+ iti.volenv.data[ev*3+2] = pIns->VolEnv.Ticks[ev] >> 8;
+ iti.panenv.data[ev*3] = pIns->PanEnv.Values[ev] - 32;
+ iti.panenv.data[ev*3+1] = pIns->PanEnv.Ticks[ev] & 0xFF;
+ iti.panenv.data[ev*3+2] = pIns->PanEnv.Ticks[ev] >> 8;
+ iti.pitchenv.data[ev*3] = pIns->PitchEnv.Values[ev] - 32;
+ iti.pitchenv.data[ev*3+1] = pIns->PitchEnv.Ticks[ev] & 0xFF;
+ iti.pitchenv.data[ev*3+2] = pIns->PitchEnv.Ticks[ev] >> 8;
}
} else
// Save Empty Instrument
@@ -3494,9 +3494,9 @@
WriteInstrumentPropertyForAllInstruments('CS..', sizeof(m_defaultInstrument.nCutSwing), f, instruments, nInstruments);
WriteInstrumentPropertyForAllInstruments('RS..', sizeof(m_defaultInstrument.nResSwing), f, instruments, nInstruments);
WriteInstrumentPropertyForAllInstruments('FM..', sizeof(m_defaultInstrument.nFilterMode), f, instruments, nInstruments);
- WriteInstrumentPropertyForAllInstruments('PERN', sizeof(m_defaultInstrument.nPitchEnvReleaseNode ), f, instruments, nInstruments);
- WriteInstrumentPropertyForAllInstruments('AERN', sizeof(m_defaultInstrument.nPanEnvReleaseNode), f, instruments, nInstruments);
- WriteInstrumentPropertyForAllInstruments('VERN', sizeof(m_defaultInstrument.nVolEnvReleaseNode), f, instruments, nInstruments);
+ WriteInstrumentPropertyForAllInstruments('PERN', sizeof(m_defaultInstrument.PitchEnv.nReleaseNode ), f, instruments, nInstruments);
+ WriteInstrumentPropertyForAllInstruments('AERN', sizeof(m_defaultInstrument.PanEnv.nReleaseNode), f, instruments, nInstruments);
+ WriteInstrumentPropertyForAllInstruments('VERN', sizeof(m_defaultInstrument.VolEnv.nReleaseNode), f, instruments, nInstruments);
WriteInstrumentPropertyForAllInstruments('PTTL', sizeof(m_defaultInstrument.wPitchToTempoLock), f, instruments, nInstruments);
WriteInstrumentPropertyForAllInstruments('PVEH', sizeof(m_defaultInstrument.nPluginVelocityHandling), f, instruments, nInstruments);
WriteInstrumentPropertyForAllInstruments('PVOH', sizeof(m_defaultInstrument.nPluginVolumeHandling), f, instruments, nInstruments);
Modified: trunk/OpenMPT/soundlib/Load_mdl.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_mdl.cpp 2009-08-16 11:46:32 UTC (rev 327)
+++ trunk/OpenMPT/soundlib/Load_mdl.cpp 2009-08-16 11:55:06 UTC (rev 328)
@@ -497,23 +497,23 @@
for (UINT nve=0; nve<nvolenv; nve++, pve+=33) if (pve[0]+1 == insvolenv[iIns])
{
WORD vtick = 1;
- pIns->nVolEnv = 15;
+ pIns->VolEnv.nNodes = 15;
for (UINT iv=0; iv<15; iv++)
{
if (iv) vtick += pve[iv*2+1];
- pIns->VolPoints[iv] = vtick;
- pIns->VolEnv[iv] = pve[iv*2+2];
+ pIns->VolEnv.Ticks[iv] = vtick;
+ pIns->VolEnv.Values[iv] = pve[iv*2+2];
if (!pve[iv*2+1])
{
- pIns->nVolEnv = iv+1;
+ pIns->VolEnv.nNodes = iv+1;
break;
}
}
- pIns->nVolSustainBegin = pIns->nVolSustainEnd = pve[31] & 0x0F;
+ pIns->VolEnv.nSustainStart = pIns->VolEnv.nSustainEnd = pve[31] & 0x0F;
if (pve[31] & 0x10) pIns->dwFlags |= ENV_VOLSUSTAIN;
if (pve[31] & 0x20) pIns->dwFlags |= ENV_VOLLOOP;
- pIns->nVolLoopStart = pve[32] & 0x0F;
- pIns->nVolLoopEnd = pve[32] >> 4;
+ pIns->VolEnv.nLoopStart = pve[32] & 0x0F;
+ pIns->VolEnv.nLoopEnd = pve[32] >> 4;
}
}
// Setup panning envelope
@@ -523,22 +523,22 @@
for (UINT npe=0; npe<npanenv; npe++, ppe+=33) if (ppe[0]+1 == inspanenv[iIns])
{
WORD vtick = 1;
- pIns->nPanEnv = 15;
+ pIns->PanEnv.nNodes = 15;
for (UINT iv=0; iv<15; iv++)
{
if (iv) vtick += ppe[iv*2+1];
- pIns->PanPoints[iv] = vtick;
- pIns->PanEnv[iv] = ppe[iv*2+2];
+ pIns->PanEnv.Ticks[iv] = vtick;
+ pIns->PanEnv.Values[iv] = ppe[iv*2+2];
if (!ppe[iv*2+1])
{
- pIns->nPanEnv = iv+1;
+ pIns->PanEnv.nNodes = iv+1;
break;
}
}
if (ppe[31] & 0x10) pIns->dwFlags |= ENV_PANSUSTAIN;
if (ppe[31] & 0x20) pIns->dwFlags |= ENV_PANLOOP;
- pIns->nPa...
[truncated message content] |
|
From: <rel...@us...> - 2009-08-16 11:46:45
|
Revision: 327
http://modplug.svn.sourceforge.net/modplug/?rev=327&view=rev
Author: relabsoluness
Date: 2009-08-16 11:46:32 +0000 (Sun, 16 Aug 2009)
Log Message:
-----------
[Fix] Sample tab: Fix to crash that occurred when resizing sample while it was playing.
[Fix] Instrument tab: Fix to crash that occurred when multiple windows had instrument tab of the same document open.
[Fix] Tuning: Default tuning file should now load correctly (broken in rev. 323).
[Ref] S3M load: Check parameters before reading.
[Ref] Internal: Changes to get rid of some compiler warnings and disabled some warnings (see Stdafx.h).
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Ctrl_ins.cpp
trunk/OpenMPT/mptrack/ScaleEnvPointsDlg.cpp
trunk/OpenMPT/mptrack/ScaleEnvPointsDlg.h
trunk/OpenMPT/mptrack/Stdafx.h
trunk/OpenMPT/mptrack/View_tre.cpp
trunk/OpenMPT/mptrack/serialization_utils.cpp
trunk/OpenMPT/soundlib/Load_s3m.cpp
trunk/OpenMPT/soundlib/modsmp_ctrl.cpp
trunk/OpenMPT/soundlib/modsmp_ctrl.h
Modified: trunk/OpenMPT/mptrack/Ctrl_ins.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2009-08-15 19:28:24 UTC (rev 326)
+++ trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2009-08-16 11:46:32 UTC (rev 327)
@@ -1295,7 +1295,7 @@
// -> DESC="IT project files (.itp)"
int n = strlen(lpszFileName);
if(n >= _MAX_PATH) n = _MAX_PATH-1;
- strncpy(&m_pSndFile->m_szInstrumentPath[m_nInstrument-1][0],lpszFileName,n);
+ strncpy(m_pSndFile->m_szInstrumentPath[m_nInstrument-1],lpszFileName,n);
m_pSndFile->m_szInstrumentPath[m_nInstrument-1][n] = '\0';
m_pSndFile->instrumentModified[m_nInstrument-1] = FALSE;
// -! NEW_FEATURE#0023
@@ -1643,7 +1643,7 @@
// -> DESC="IT project files (.itp)"
int n = strlen(dlg.GetPathName());
if(n > _MAX_PATH) n = _MAX_PATH;
- strncpy(&m_pSndFile->m_szInstrumentPath[m_nInstrument-1][0],dlg.GetPathName(),n);
+ strncpy(m_pSndFile->m_szInstrumentPath[m_nInstrument-1],dlg.GetPathName(),n);
m_pSndFile->instrumentModified[m_nInstrument-1] = FALSE;
// -! NEW_FEATURE#0023
@@ -2030,13 +2030,12 @@
if ((!IsLocked()) && pIns->nMixPlug != nPlug) {
m_pModDoc->SetModified();
pIns->nMixPlug = nPlug;
+ m_pModDoc->UpdateAllViews(NULL, HINT_MIXPLUGINS, this);
+ m_pModDoc->UpdateAllViews(NULL, (m_nInstrument << HINT_SHIFT_INS) | HINT_INSNAMES, this);
}
m_CbnPluginVelocityHandling.SetCurSel(pIns->nPluginVelocityHandling);
m_CbnPluginVolumeHandling.SetCurSel(pIns->nPluginVolumeHandling);
- m_pModDoc->UpdateAllViews(NULL, HINT_MIXPLUGINS, this);
- m_pModDoc->UpdateAllViews(NULL, (m_nInstrument << HINT_SHIFT_INS) | HINT_INSNAMES, this);
-
if (pIns->nMixPlug) //if we have not just set to no plugin
{
PSNDMIXPLUGIN pPlug = &(m_pSndFile->m_MixPlugins[pIns->nMixPlug-1]);
@@ -2653,7 +2652,6 @@
pIns->SetTuning(pIns->s_DefaultTuning);
END_CRITICAL();
m_pModDoc->SetModified();
- UpdateView((m_nInstrument << HINT_SHIFT_INS) | HINT_INSTRUMENT);
}
void CCtrlInstruments::OnEnChangeEditPitchtempolock()
Modified: trunk/OpenMPT/mptrack/ScaleEnvPointsDlg.cpp
===================================================================
--- trunk/OpenMPT/mptrack/ScaleEnvPointsDlg.cpp 2009-08-15 19:28:24 UTC (rev 326)
+++ trunk/OpenMPT/mptrack/ScaleEnvPointsDlg.cpp 2009-08-16 11:46:32 UTC (rev 327)
@@ -9,7 +9,7 @@
// CScaleEnvPointsDlg dialog
IMPLEMENT_DYNAMIC(CScaleEnvPointsDlg, CDialog)
-CScaleEnvPointsDlg::CScaleEnvPointsDlg(CWnd* pParent, MODINSTRUMENT* pInst, BYTE env)
+CScaleEnvPointsDlg::CScaleEnvPointsDlg(CWnd* pParent, MODINSTRUMENT* pInst, UINT env)
: CDialog(CScaleEnvPointsDlg::IDD, pParent),
m_pInstrument(pInst),
m_Env(env)
Modified: trunk/OpenMPT/mptrack/ScaleEnvPointsDlg.h
===================================================================
--- trunk/OpenMPT/mptrack/ScaleEnvPointsDlg.h 2009-08-15 19:28:24 UTC (rev 326)
+++ trunk/OpenMPT/mptrack/ScaleEnvPointsDlg.h 2009-08-16 11:46:32 UTC (rev 327)
@@ -11,7 +11,7 @@
DECLARE_DYNAMIC(CScaleEnvPointsDlg)
public:
- CScaleEnvPointsDlg(CWnd* pParent, MODINSTRUMENT* pInst, BYTE env); // standard constructor
+ CScaleEnvPointsDlg(CWnd* pParent, MODINSTRUMENT* pInst, UINT env); // standard constructor
virtual ~CScaleEnvPointsDlg();
// Dialog Data
@@ -24,7 +24,7 @@
private:
MODINSTRUMENT* m_pInstrument;
- BYTE m_Env; //To tell which envelope to process.
+ UINT m_Env; //To tell which envelope to process.
CEdit m_EditFactor;
protected:
virtual void OnOK();
Modified: trunk/OpenMPT/mptrack/Stdafx.h
===================================================================
--- trunk/OpenMPT/mptrack/Stdafx.h 2009-08-15 19:28:24 UTC (rev 326)
+++ trunk/OpenMPT/mptrack/Stdafx.h 2009-08-16 11:46:32 UTC (rev 327)
@@ -29,7 +29,7 @@
#define MMNODRV
#define MMNOMCI
-//#define _CRT_SECURE_NO_WARNINGS // Define to disable the "This function or variable may be unsafe" warnings.
+#define _CRT_SECURE_NO_WARNINGS // Define to disable the "This function or variable may be unsafe" warnings.
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT 1
Modified: trunk/OpenMPT/mptrack/View_tre.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_tre.cpp 2009-08-15 19:28:24 UTC (rev 326)
+++ trunk/OpenMPT/mptrack/View_tre.cpp 2009-08-16 11:46:32 UTC (rev 327)
@@ -2606,7 +2606,7 @@
dlg.m_ofn.nMaxFile = _MAX_PATH;
if(dlg.DoModal() == IDOK){
- strcpy(&pSndFile->m_szInstrumentPath[dwItem-1][0],pszFileNames);
+ strcpy(pSndFile->m_szInstrumentPath[dwItem-1], pszFileNames);
OnRefreshTree();
}
@@ -2642,7 +2642,7 @@
dlg.m_ofn.lpstrFile = pszFileNames;
dlg.m_ofn.nMaxFile = _MAX_PATH;
- if(dlg.DoModal() == IDOK) strcpy(&pSndFile->m_szInstrumentPath[dwItem-1][0],pszFileNames);
+ if(dlg.DoModal() == IDOK) strcpy(pSndFile->m_szInstrumentPath[dwItem-1], pszFileNames);
dlg.m_ofn.lpstrFile = NULL;
dlg.m_ofn.nMaxFile = 0;
Modified: trunk/OpenMPT/mptrack/serialization_utils.cpp
===================================================================
--- trunk/OpenMPT/mptrack/serialization_utils.cpp 2009-08-15 19:28:24 UTC (rev 326)
+++ trunk/OpenMPT/mptrack/serialization_utils.cpp 2009-08-16 11:46:32 UTC (rev 327)
@@ -696,7 +696,7 @@
}
if(Testbit(flagbyte, 3))
- iStrm.ignore(8);
+ iStrm.ignore(5);
// Read entrycount
ReadAdaptive1248(iStrm, tempU64);
Modified: trunk/OpenMPT/soundlib/Load_s3m.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_s3m.cpp 2009-08-15 19:28:24 UTC (rev 326)
+++ trunk/OpenMPT/soundlib/Load_s3m.cpp 2009-08-16 11:46:32 UTC (rev 327)
@@ -255,6 +255,8 @@
bool CSoundFile::ReadS3M(const BYTE *lpStream, DWORD dwMemLength)
//---------------------------------------------------------------
{
+ if ((!lpStream) || (dwMemLength <= sizeof(S3MFILEHEADER)+sizeof(S3MSAMPLESTRUCT)+64)) return false;
+
UINT insnum,patnum,nins,npat;
DWORD insfile[128];
WORD ptr[256];
@@ -273,7 +275,6 @@
psfh.scrm = LittleEndian(psfh.scrm);
psfh.special = LittleEndianW(psfh.special);
- if ((!lpStream) || (dwMemLength <= sizeof(S3MFILEHEADER)+sizeof(S3MSAMPLESTRUCT)+64)) return false;
if (psfh.scrm != 0x4D524353) return false;
if((psfh.cwtv & 0xF000) == 0x5000) // OpenMPT Version number (Major.Minor)
Modified: trunk/OpenMPT/soundlib/modsmp_ctrl.cpp
===================================================================
--- trunk/OpenMPT/soundlib/modsmp_ctrl.cpp 2009-08-15 19:28:24 UTC (rev 326)
+++ trunk/OpenMPT/soundlib/modsmp_ctrl.cpp 2009-08-16 11:46:32 UTC (rev 327)
@@ -11,15 +11,17 @@
namespace ctrlSmp
{
-void ReplaceSample(MODSAMPLE& smp, const LPSTR pNewSample, const SmpLength nNewLength)
-//----------------------------------------------------------------------------------------
+void ReplaceSample(MODSAMPLE& smp, const LPSTR pNewSample, const SmpLength nNewLength, CSoundFile* pSndFile)
+//----------------------------------------------------------------------------------------------------------
{
LPSTR const pOldSmp = smp.pSample;
BEGIN_CRITICAL();
+ if (pSndFile != nullptr)
+ ctrlChn::ReplaceSample(pSndFile->Chn, pOldSmp, pNewSample, nNewLength);
smp.pSample = pNewSample;
smp.nLength = nNewLength;
- END_CRITICAL();
- CSoundFile::FreeSample(pOldSmp);
+ CSoundFile::FreeSample(pOldSmp);
+ END_CRITICAL();
}
@@ -60,7 +62,7 @@
AfxMessageBox(TEXT("Unsupported start position in InsertSilence."));
}
- ReplaceSample(smp, pNewSmp, nNewLength);
+ ReplaceSample(smp, pNewSmp, nNewLength, pSndFile);
AdjustEndOfSample(smp, pSndFile);
return smp.nLength;
@@ -88,7 +90,7 @@
// Copy over old data and replace sample by the new one
memcpy(pNewSmp, smp.pSample, nNewSmpBytes);
- ReplaceSample(smp, pNewSmp, nNewLength);
+ ReplaceSample(smp, pNewSmp, nNewLength, pSndFile);
// Adjust loops
if(smp.nLoopStart > nNewLength)
@@ -340,3 +342,32 @@
} // namespace ctrlSmp
+
+
+
+namespace ctrlChn
+{
+
+void ReplaceSample( MODCHANNEL (&Chn)[MAX_CHANNELS],
+ LPCSTR pOldSample,
+ LPSTR pNewSample,
+ const ctrlSmp::SmpLength nNewLength,
+ DWORD orFlags /* = 0*/,
+ DWORD andFlags /* = MAXDWORD*/)
+{
+ for (CHANNELINDEX i = 0; i < MAX_CHANNELS; i++)
+ {
+ if (Chn[i].pSample == pOldSample)
+ {
+ Chn[i].pSample = pNewSample;
+ Chn[i].pCurrentSample = pNewSample;
+ if (Chn[i].nPos > nNewLength)
+ Chn[i].nPos = 0;
+ Chn[i].nLength = nNewLength;
+ Chn[i].dwFlags |= orFlags;
+ Chn[i].dwFlags &= andFlags;
+ }
+ }
+}
+
+} // namespace ctrlChn
Modified: trunk/OpenMPT/soundlib/modsmp_ctrl.h
===================================================================
--- trunk/OpenMPT/soundlib/modsmp_ctrl.h 2009-08-15 19:28:24 UTC (rev 326)
+++ trunk/OpenMPT/soundlib/modsmp_ctrl.h 2009-08-16 11:46:32 UTC (rev 327)
@@ -21,15 +21,16 @@
// 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(MODSAMPLE& smp, const SmpLength nSilenceLength, const SmpLength nStartFrom, CSoundFile* pSndFile = nullptr);
+SmpLength InsertSilence(MODSAMPLE& smp, const SmpLength nSilenceLength, const SmpLength nStartFrom, CSoundFile* pSndFile);
// Change sample size.
// Note: If resized sample is bigger, silence will be added to the sample's tail.
// Return: Length of the new sample.
-SmpLength ResizeSample(MODSAMPLE& smp, const SmpLength nNewLength, CSoundFile* pSndFile = nullptr);
+SmpLength ResizeSample(MODSAMPLE& smp, const SmpLength nNewLength, CSoundFile* pSndFile);
// Replaces sample in 'smp' with given sample and frees the old sample.
-void ReplaceSample(MODSAMPLE& smp, const LPSTR pNewSample, const SmpLength nNewLength);
+// If valid CSoundFile pointer is given, the sample will be replaced also from the sounds channels.
+void ReplaceSample(MODSAMPLE& smp, const LPSTR pNewSample, const SmpLength nNewLength, CSoundFile* pSndFile);
bool AdjustEndOfSample(MODSAMPLE& smp, CSoundFile* pSndFile = 0);
@@ -53,4 +54,17 @@
} // Namespace ctrlSmp
+namespace ctrlChn
+{
+
+// Replaces sample from sound channels by given sample.
+void ReplaceSample( MODCHANNEL (&Chn)[MAX_CHANNELS],
+ LPCSTR pOldSample,
+ LPSTR pNewSample,
+ const ctrlSmp::SmpLength nNewLength,
+ DWORD orFlags = 0,
+ DWORD andFlags = MAXDWORD);
+
+} // namespace ctrlChn
+
#endif
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|